summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriroul <iroul@iroul-VirtualBox.(none)>2014-04-04 07:35:14 -0700
committeriroul <iroul@iroul-VirtualBox.(none)>2014-04-04 07:35:14 -0700
commitafd34f2893a06a3aecf17e8e83b1df6ed2ae91a2 (patch)
tree851102abc55d91a1b76e63e9e89f9a7733da95b5
parentc4b028ad53f7b362a864de24828d7cc39ff67b0a (diff)
downloadfqterm-afd34f2893a06a3aecf17e8e83b1df6ed2ae91a2.tar.xz
move to my github.
-rw-r--r--CMakeLists.txt95
-rw-r--r--CMakeLists.txt.freebsd114
-rw-r--r--CMakeLists.txt.linux158
-rw-r--r--CMakeLists.txt.macos132
-rw-r--r--CMakeLists.txt.win3297
-rw-r--r--FQTermNSIS.nsi195
-rw-r--r--INSTALL.txt161
-rw-r--r--LICENSE39
-rw-r--r--README.txt3
-rw-r--r--VersionInfo12
-rw-r--r--cmake/FindALSA.cmake46
-rw-r--r--cmake/FindOSS.cmake41
-rw-r--r--cmake/VersionControl.cmake82
-rw-r--r--doc/DocsYouNeed.txt6
-rw-r--r--doc/fqtermscript.txt1
-rw-r--r--res/credits52
-rw-r--r--res/cursor/end.xpm38
-rw-r--r--res/cursor/enter.xpm38
-rw-r--r--res/cursor/exit.xpm38
-rw-r--r--res/cursor/hand.xpm38
-rw-r--r--res/cursor/home.xpm38
-rw-r--r--res/cursor/mac_16x16/end.xpm22
-rw-r--r--res/cursor/mac_16x16/enter.xpm22
-rw-r--r--res/cursor/mac_16x16/exit.xpm22
-rw-r--r--res/cursor/mac_16x16/hand.xpm22
-rw-r--r--res/cursor/mac_16x16/home.xpm22
-rw-r--r--res/cursor/mac_16x16/next.xpm22
-rw-r--r--res/cursor/mac_16x16/pagedown.xpm22
-rw-r--r--res/cursor/mac_16x16/pageup.xpm22
-rw-r--r--res/cursor/mac_16x16/prev.xpm22
-rw-r--r--res/cursor/next.xpm38
-rw-r--r--res/cursor/pagedown.xpm38
-rw-r--r--res/cursor/pageup.xpm38
-rw-r--r--res/cursor/prev.xpm38
-rw-r--r--res/default_font.conf24
-rw-r--r--res/dict/common_zh_CN.ts618
-rw-r--r--res/dict/fqterm_zh_CN.ts666
-rw-r--r--res/dict/protocol_zh_CN.ts157
-rw-r--r--res/dict/ui_zh_CN.ts1706
-rw-r--r--res/fqterm.desktop13
-rw-r--r--res/fqterm.icnsbin0 -> 54565 bytes
-rw-r--r--res/fqterm.sh30
-rw-r--r--res/pic/ViewerButtons/adjustsize.pngbin0 -> 1929 bytes
-rw-r--r--res/pic/ViewerButtons/button-cancel.pngbin0 -> 1767 bytes
-rw-r--r--res/pic/ViewerButtons/button-delete.pngbin0 -> 1492 bytes
-rw-r--r--res/pic/ViewerButtons/button-recover.pngbin0 -> 1938 bytes
-rw-r--r--res/pic/ViewerButtons/clear-state-gray.pngbin0 -> 1564 bytes
-rw-r--r--res/pic/ViewerButtons/clear-state.pngbin0 -> 1762 bytes
-rw-r--r--res/pic/ViewerButtons/document-save-as.pngbin0 -> 1205 bytes
-rw-r--r--res/pic/ViewerButtons/edit-clear.pngbin0 -> 1729 bytes
-rw-r--r--res/pic/ViewerButtons/edit-delete.pngbin0 -> 1224 bytes
-rw-r--r--res/pic/ViewerButtons/edit-shuffle.pngbin0 -> 1331 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-info.pngbin0 -> 2812 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-like-16x16.pngbin0 -> 940 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-like-gray.pngbin0 -> 1373 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-like.pngbin0 -> 1607 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-new-16x16.pngbin0 -> 1172 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-new-gray.pngbin0 -> 1942 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-new.pngbin0 -> 2239 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-recover-16x16.pngbin0 -> 887 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-recover-gray.pngbin0 -> 1909 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-recover.pngbin0 -> 2377 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-title-16x16.pngbin0 -> 988 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-title.pngbin0 -> 1644 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-trash-16x16.pngbin0 -> 1058 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-trash-gray.pngbin0 -> 1332 bytes
-rw-r--r--res/pic/ViewerButtons/emblem-trash.pngbin0 -> 1570 bytes
-rw-r--r--res/pic/ViewerButtons/next.pngbin0 -> 1310 bytes
-rw-r--r--res/pic/ViewerButtons/object-rotate-left.pngbin0 -> 924 bytes
-rw-r--r--res/pic/ViewerButtons/object-rotate-right.pngbin0 -> 943 bytes
-rw-r--r--res/pic/ViewerButtons/open.pngbin0 -> 2073 bytes
-rw-r--r--res/pic/ViewerButtons/play_gif.pngbin0 -> 900 bytes
-rw-r--r--res/pic/ViewerButtons/prev.pngbin0 -> 1080 bytes
-rw-r--r--res/pic/ViewerButtons/previous.pngbin0 -> 837 bytes
-rw-r--r--res/pic/ViewerButtons/save-state-gray.pngbin0 -> 1567 bytes
-rw-r--r--res/pic/ViewerButtons/save-state.pngbin0 -> 2053 bytes
-rw-r--r--res/pic/ViewerButtons/trash-empty.pngbin0 -> 1121 bytes
-rw-r--r--res/pic/ViewerButtons/trash-full.pngbin0 -> 1695 bytes
-rw-r--r--res/pic/ViewerButtons/trash-state-gray.pngbin0 -> 956 bytes
-rw-r--r--res/pic/ViewerButtons/trash-state.pngbin0 -> 1715 bytes
-rw-r--r--res/pic/ViewerButtons/view-fullscreen.pngbin0 -> 687 bytes
-rw-r--r--res/pic/ViewerButtons/window-close.pngbin0 -> 1045 bytes
-rw-r--r--res/pic/ViewerButtons/zoom-fit-best.pngbin0 -> 1356 bytes
-rw-r--r--res/pic/ViewerButtons/zoom-in.pngbin0 -> 1281 bytes
-rw-r--r--res/pic/ViewerButtons/zoom-original.pngbin0 -> 1264 bytes
-rw-r--r--res/pic/ViewerButtons/zoom-out.pngbin0 -> 1233 bytes
-rw-r--r--res/pic/ViewerButtons/zoomin.pngbin0 -> 1696 bytes
-rw-r--r--res/pic/ViewerButtons/zoomout.pngbin0 -> 1662 bytes
-rw-r--r--res/pic/address_book.pngbin0 -> 4087 bytes
-rw-r--r--res/pic/ansi_color.pngbin0 -> 1918 bytes
-rw-r--r--res/pic/anti_idle.pngbin0 -> 2076 bytes
-rw-r--r--res/pic/auto_reconnect.pngbin0 -> 1205 bytes
-rw-r--r--res/pic/auto_reply.pngbin0 -> 2666 bytes
-rw-r--r--res/pic/beep.pngbin0 -> 2262 bytes
-rw-r--r--res/pic/change_fonts.pngbin0 -> 1582 bytes
-rw-r--r--res/pic/connect.pngbin0 -> 1965 bytes
-rw-r--r--res/pic/copy.pngbin0 -> 1338 bytes
-rw-r--r--res/pic/copy_with_color.pngbin0 -> 2053 bytes
-rw-r--r--res/pic/disconnect.pngbin0 -> 1944 bytes
-rw-r--r--res/pic/english_font.pngbin0 -> 3124 bytes
-rw-r--r--res/pic/fqterm.pngbin0 -> 10178 bytes
-rw-r--r--res/pic/fqterm_128x128.icobin0 -> 67646 bytes
-rw-r--r--res/pic/fqterm_128x128.pngbin0 -> 14912 bytes
-rw-r--r--res/pic/fqterm_16x16.icobin0 -> 1150 bytes
-rw-r--r--res/pic/fqterm_16x16.pngbin0 -> 1713 bytes
-rw-r--r--res/pic/fqterm_256x256.icobin0 -> 270398 bytes
-rw-r--r--res/pic/fqterm_256x256.pngbin0 -> 42415 bytes
-rw-r--r--res/pic/fqterm_32x32.icobin0 -> 4286 bytes
-rw-r--r--res/pic/fqterm_32x32.pngbin0 -> 1975 bytes
-rw-r--r--res/pic/fqterm_48x48.icobin0 -> 9662 bytes
-rw-r--r--res/pic/fqterm_48x48.pngbin0 -> 10178 bytes
-rw-r--r--res/pic/fqterm_64x64.icobin0 -> 16958 bytes
-rw-r--r--res/pic/fqterm_64x64.pngbin0 -> 5283 bytes
-rw-r--r--res/pic/fqterm_tray.pngbin0 -> 1713 bytes
-rw-r--r--res/pic/get_article_fulltext.pngbin0 -> 1909 bytes
-rw-r--r--res/pic/image_viewer.pngbin0 -> 3350 bytes
-rw-r--r--res/pic/messagebox_critical.pngbin0 -> 1473 bytes
-rw-r--r--res/pic/messagebox_info.pngbin0 -> 1397 bytes
-rw-r--r--res/pic/messagebox_warning.pngbin0 -> 1356 bytes
-rw-r--r--res/pic/mouse.pngbin0 -> 2152 bytes
-rw-r--r--res/pic/other_font.pngbin0 -> 3231 bytes
-rw-r--r--res/pic/paste.pngbin0 -> 1647 bytes
-rw-r--r--res/pic/popwidget.pngbin0 -> 4633 bytes
-rw-r--r--res/pic/preferences.pngbin0 -> 1881 bytes
-rw-r--r--res/pic/quick_login.pngbin0 -> 1138 bytes
-rw-r--r--res/pic/rectangle_selection.pngbin0 -> 2306 bytes
-rw-r--r--res/pic/refresh.pngbin0 -> 1914 bytes
-rw-r--r--res/pic/save_setting.pngbin0 -> 1894 bytes
-rw-r--r--res/pic/setup_shortcuts.pngbin0 -> 1333 bytes
-rw-r--r--res/pic/shadow.pngbin0 -> 1818 bytes
-rw-r--r--res/pic/tabpad.pngbin0 -> 620 bytes
-rw-r--r--res/pic/toggle_ansi_color.pngbin0 -> 1475 bytes
-rw-r--r--res/pic/view_messages.pngbin0 -> 2374 bytes
-rw-r--r--res/schema/Linux.schema27
-rw-r--r--res/schema/Softness.schema27
-rw-r--r--res/schema/VIM.schema27
-rw-r--r--res/schema/XTerm.schema27
-rw-r--r--res/schema/default.schema27
-rw-r--r--res/script/README112
-rw-r--r--res/script/buildindex.js132
-rw-r--r--res/script/continuous.py19
-rw-r--r--res/script/download.js19
-rw-r--r--res/script/download.py253
-rw-r--r--res/script/downloadelite.js207
-rw-r--r--res/script/downloadelite_smth.js255
-rw-r--r--res/script/post.js17
-rw-r--r--res/script/post.py21
-rw-r--r--res/script/postfile.py48
-rw-r--r--res/script/search.js22
-rw-r--r--res/script/sendmsg.py33
-rw-r--r--res/script/system.js48
-rw-r--r--res/script/system.py103
-rw-r--r--res/script/test.js4
-rw-r--r--res/script/tools.py65
-rw-r--r--res/script/utils.js46
-rw-r--r--res/script/weiboshare.js51
-rw-r--r--res/skin/dpstyle/ReadMe.txt5
-rw-r--r--res/skin/dpstyle/dpstyle.qss203
-rw-r--r--res/skin/dpstyle/image/checkbox_checked.pngbin0 -> 263 bytes
-rw-r--r--res/skin/dpstyle/image/checkbox_checked_hover.pngbin0 -> 266 bytes
-rw-r--r--res/skin/dpstyle/image/checkbox_checked_pressed.pngbin0 -> 425 bytes
-rw-r--r--res/skin/dpstyle/image/checkbox_unchecked.pngbin0 -> 159 bytes
-rw-r--r--res/skin/dpstyle/image/checkbox_unchecked_hover.pngbin0 -> 159 bytes
-rw-r--r--res/skin/dpstyle/image/checkbox_unchecked_pressed.pngbin0 -> 320 bytes
-rw-r--r--res/skin/dpstyle/image/down_arrow.pngbin0 -> 175 bytes
-rw-r--r--res/skin/dpstyle/image/down_arrow_disabled.pngbin0 -> 174 bytes
-rw-r--r--res/skin/dpstyle/image/frame.pngbin0 -> 253 bytes
-rw-r--r--res/skin/dpstyle/image/pagefold.pngbin0 -> 1545 bytes
-rw-r--r--res/skin/dpstyle/image/pushbutton.pngbin0 -> 533 bytes
-rw-r--r--res/skin/dpstyle/image/pushbutton_hover.pngbin0 -> 525 bytes
-rw-r--r--res/skin/dpstyle/image/pushbutton_pressed.pngbin0 -> 513 bytes
-rw-r--r--res/skin/dpstyle/image/radiobutton_checked.pngbin0 -> 355 bytes
-rw-r--r--res/skin/dpstyle/image/radiobutton_checked_hover.pngbin0 -> 532 bytes
-rw-r--r--res/skin/dpstyle/image/radiobutton_checked_pressed.pngbin0 -> 599 bytes
-rw-r--r--res/skin/dpstyle/image/radiobutton_unchecked.pngbin0 -> 240 bytes
-rw-r--r--res/skin/dpstyle/image/radiobutton_unchecked_hover.pngbin0 -> 492 bytes
-rw-r--r--res/skin/dpstyle/image/radiobutton_unchecked_pressed.pngbin0 -> 556 bytes
-rw-r--r--res/skin/dpstyle/image/sizegrip.pngbin0 -> 129 bytes
-rw-r--r--res/skin/dpstyle/image/spindown.pngbin0 -> 276 bytes
-rw-r--r--res/skin/dpstyle/image/spindown_hover.pngbin0 -> 268 bytes
-rw-r--r--res/skin/dpstyle/image/spindown_off.pngbin0 -> 249 bytes
-rw-r--r--res/skin/dpstyle/image/spindown_pressed.pngbin0 -> 264 bytes
-rw-r--r--res/skin/dpstyle/image/spinup.pngbin0 -> 283 bytes
-rw-r--r--res/skin/dpstyle/image/spinup_hover.pngbin0 -> 277 bytes
-rw-r--r--res/skin/dpstyle/image/spinup_off.pngbin0 -> 274 bytes
-rw-r--r--res/skin/dpstyle/image/spinup_pressed.pngbin0 -> 277 bytes
-rw-r--r--res/skin/dpstyle/image/up_arrow.pngbin0 -> 197 bytes
-rw-r--r--res/skin/dpstyle/image/up_arrow_disabled.pngbin0 -> 172 bytes
-rw-r--r--res/unite/exit24
-rw-r--r--res/unite/help24
-rw-r--r--res/unite/script-doc199
-rw-r--r--res/unite/shortcut-doc10
-rw-r--r--res/unite/ssh-unix-doc17
-rw-r--r--res/unite/welcome24
-rw-r--r--res/userconf/README.txt5
-rw-r--r--res/userconf/address.cfg.orig156
-rw-r--r--res/userconf/fqterm.cfg.orig58
-rw-r--r--res/userconf/language.cfg.orig4
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/common/CMakeLists.txt36
-rw-r--r--src/common/common.cpp53
-rw-r--r--src/common/common.h64
-rw-r--r--src/common/fqterm.h350
-rw-r--r--src/common/fqterm_config.cpp181
-rw-r--r--src/common/fqterm_config.h61
-rw-r--r--src/common/fqterm_exif_extractor.cpp647
-rw-r--r--src/common/fqterm_exif_extractor.h126
-rw-r--r--src/common/fqterm_filedialog.cpp157
-rw-r--r--src/common/fqterm_filedialog.h49
-rw-r--r--src/common/fqterm_font.cpp261
-rw-r--r--src/common/fqterm_font.h34
-rw-r--r--src/common/fqterm_param.cpp274
-rw-r--r--src/common/fqterm_param.h221
-rw-r--r--src/common/fqterm_path.cpp601
-rw-r--r--src/common/fqterm_path.h46
-rw-r--r--src/common/fqterm_shortcuthelper.cpp298
-rw-r--r--src/common/fqterm_shortcuthelper.h175
-rw-r--r--src/common/fqterm_sound.cpp733
-rw-r--r--src/common/fqterm_sound.h79
-rw-r--r--src/common/fqterm_trace.cpp328
-rw-r--r--src/common/fqterm_trace.h331
-rw-r--r--src/fqterm/3rdparty/dotnetstyle.cpp1274
-rw-r--r--src/fqterm/3rdparty/dotnetstyle.h77
-rw-r--r--src/fqterm/3rdparty/qxtglobal.h207
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut.cpp193
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut.h58
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp262
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_p.h63
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_win.cpp214
-rw-r--r--src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp115
-rw-r--r--src/fqterm/3rdparty/uaocodec.cpp15761
-rw-r--r--src/fqterm/3rdparty/uaocodec.h69
-rw-r--r--src/fqterm/CMakeLists.txt83
-rw-r--r--src/fqterm/fqterm.rcbin0 -> 330 bytes
-rw-r--r--src/fqterm/fqterm_app.cpp38
-rw-r--r--src/fqterm/fqterm_app.h41
-rw-r--r--src/fqterm/fqterm_autoupdate.cpp178
-rw-r--r--src/fqterm/fqterm_autoupdate.h61
-rw-r--r--src/fqterm/fqterm_frame.cpp2162
-rw-r--r--src/fqterm/fqterm_frame.h326
-rw-r--r--src/fqterm/fqterm_python.cpp826
-rw-r--r--src/fqterm/fqterm_python.h51
-rw-r--r--src/fqterm/fqterm_screen.cpp1868
-rw-r--r--src/fqterm/fqterm_screen.h281
-rw-r--r--src/fqterm/fqterm_scriptengine.cpp488
-rw-r--r--src/fqterm/fqterm_scriptengine.h147
-rw-r--r--src/fqterm/fqterm_window.cpp2531
-rw-r--r--src/fqterm/fqterm_window.h345
-rw-r--r--src/fqterm/fqterm_wndmgr.cpp381
-rw-r--r--src/fqterm/fqterm_wndmgr.h115
-rw-r--r--src/fqterm/main.cpp135
-rw-r--r--src/protocol/CMakeLists.txt65
-rw-r--r--src/protocol/fqterm_socket.cpp672
-rw-r--r--src/protocol/fqterm_socket.h196
-rw-r--r--src/protocol/fqterm_ssh_socket.cpp352
-rw-r--r--src/protocol/fqterm_ssh_socket.h131
-rw-r--r--src/protocol/internal/crc32.cpp84
-rw-r--r--src/protocol/internal/crc32.h37
-rw-r--r--src/protocol/internal/fqterm_serialization.h54
-rw-r--r--src/protocol/internal/fqterm_ssh1_packet.cpp148
-rw-r--r--src/protocol/internal/fqterm_ssh1_packet.h40
-rw-r--r--src/protocol/internal/fqterm_ssh2_kex.cpp394
-rw-r--r--src/protocol/internal/fqterm_ssh2_kex.h105
-rw-r--r--src/protocol/internal/fqterm_ssh2_packet.cpp267
-rw-r--r--src/protocol/internal/fqterm_ssh2_packet.h51
-rw-r--r--src/protocol/internal/fqterm_ssh_auth.cpp223
-rw-r--r--src/protocol/internal/fqterm_ssh_auth.h112
-rw-r--r--src/protocol/internal/fqterm_ssh_buffer.cpp302
-rw-r--r--src/protocol/internal/fqterm_ssh_buffer.h83
-rw-r--r--src/protocol/internal/fqterm_ssh_channel.cpp439
-rw-r--r--src/protocol/internal/fqterm_ssh_channel.h130
-rw-r--r--src/protocol/internal/fqterm_ssh_cipher.h58
-rw-r--r--src/protocol/internal/fqterm_ssh_const.h146
-rw-r--r--src/protocol/internal/fqterm_ssh_des.cpp180
-rw-r--r--src/protocol/internal/fqterm_ssh_des.h74
-rw-r--r--src/protocol/internal/fqterm_ssh_hash.h47
-rw-r--r--src/protocol/internal/fqterm_ssh_kex.cpp210
-rw-r--r--src/protocol/internal/fqterm_ssh_kex.h100
-rw-r--r--src/protocol/internal/fqterm_ssh_mac.cpp53
-rw-r--r--src/protocol/internal/fqterm_ssh_mac.h54
-rw-r--r--src/protocol/internal/fqterm_ssh_md5.cpp36
-rw-r--r--src/protocol/internal/fqterm_ssh_md5.h50
-rw-r--r--src/protocol/internal/fqterm_ssh_packet.cpp242
-rw-r--r--src/protocol/internal/fqterm_ssh_packet.h148
-rw-r--r--src/protocol/internal/fqterm_ssh_pubkey.h37
-rw-r--r--src/protocol/internal/fqterm_ssh_rsa.cpp67
-rw-r--r--src/protocol/internal/fqterm_ssh_rsa.h41
-rw-r--r--src/protocol/internal/fqterm_ssh_types.h43
-rw-r--r--src/terminal/CMakeLists.txt46
-rw-r--r--src/terminal/fqterm_buffer.cpp998
-rw-r--r--src/terminal/fqterm_buffer.h297
-rw-r--r--src/terminal/fqterm_session.cpp1648
-rw-r--r--src/terminal/fqterm_session.h344
-rw-r--r--src/terminal/fqterm_text_line.cpp541
-rw-r--r--src/terminal/fqterm_text_line.h159
-rw-r--r--src/terminal/internal/fqterm_decode.cpp1279
-rw-r--r--src/terminal/internal/fqterm_decode.h194
-rw-r--r--src/terminal/internal/fqterm_telnet.cpp1041
-rw-r--r--src/terminal/internal/fqterm_telnet.h195
-rw-r--r--src/terminal/internal/fqterm_zmodem.cpp3056
-rw-r--r--src/terminal/internal/fqterm_zmodem.h623
-rw-r--r--src/ui/CMakeLists.txt122
-rw-r--r--src/ui/aboutdialog.cpp71
-rw-r--r--src/ui/aboutdialog.h39
-rw-r--r--src/ui/aboutdialog.ui175
-rw-r--r--src/ui/addrdialog.cpp396
-rw-r--r--src/ui/addrdialog.h87
-rw-r--r--src/ui/addrdialog.ui1211
-rw-r--r--src/ui/articledialog.cpp105
-rw-r--r--src/ui/articledialog.h52
-rw-r--r--src/ui/articledialog.ui132
-rw-r--r--src/ui/defineescape.cpp51
-rw-r--r--src/ui/defineescape.h44
-rw-r--r--src/ui/defineescape.ui68
-rw-r--r--src/ui/fqterm_canvas.cpp537
-rw-r--r--src/ui/fqterm_canvas.h105
-rw-r--r--src/ui/fqterm_time_label.cpp50
-rw-r--r--src/ui/fqterm_time_label.h44
-rw-r--r--src/ui/fqterm_tool_button.cpp41
-rw-r--r--src/ui/fqterm_tool_button.h46
-rw-r--r--src/ui/imageviewer.cpp1749
-rw-r--r--src/ui/imageviewer.h336
-rw-r--r--src/ui/iplookup.cpp56
-rw-r--r--src/ui/iplookup.h43
-rw-r--r--src/ui/iplookup.ui76
-rw-r--r--src/ui/keydialog.cpp285
-rw-r--r--src/ui/keydialog.h63
-rw-r--r--src/ui/keydialog.ui665
-rw-r--r--src/ui/msgdialog.cpp43
-rw-r--r--src/ui/msgdialog.h35
-rw-r--r--src/ui/msgdialog.ui86
-rw-r--r--src/ui/osdmessage.cpp210
-rw-r--r--src/ui/osdmessage.h69
-rw-r--r--src/ui/overlayWidget.cpp84
-rw-r--r--src/ui/overlayWidget.h51
-rw-r--r--src/ui/pictureflow.cpp1201
-rw-r--r--src/ui/pictureflow.h198
-rw-r--r--src/ui/popupMessage.cpp316
-rw-r--r--src/ui/popupMessage.h116
-rw-r--r--src/ui/popwidget.cpp177
-rw-r--r--src/ui/popwidget.h70
-rw-r--r--src/ui/prefdialog.cpp332
-rw-r--r--src/ui/prefdialog.h66
-rw-r--r--src/ui/prefdialog.ui644
-rw-r--r--src/ui/progressBar.cpp100
-rw-r--r--src/ui/progressBar.h71
-rw-r--r--src/ui/quickdialog.cpp258
-rw-r--r--src/ui/quickdialog.h73
-rw-r--r--src/ui/quickdialog.ui211
-rw-r--r--src/ui/schemadialog.cpp323
-rw-r--r--src/ui/schemadialog.h80
-rw-r--r--src/ui/schemadialog.ui539
-rw-r--r--src/ui/shortcutdialog.cpp176
-rw-r--r--src/ui/shortcutdialog.h61
-rw-r--r--src/ui/sitemanager.cpp412
-rw-r--r--src/ui/sitemanager.h104
-rw-r--r--src/ui/sitemanager.ui593
-rw-r--r--src/ui/soundconf.cpp178
-rw-r--r--src/ui/soundconf.h57
-rw-r--r--src/ui/soundconf.ui162
-rw-r--r--src/ui/sshlogin.ui75
-rw-r--r--src/ui/sshlogindialog.cpp80
-rw-r--r--src/ui/sshlogindialog.h45
-rw-r--r--src/ui/statusBar.cpp530
-rw-r--r--src/ui/statusBar.h148
-rw-r--r--src/ui/zmodemdialog.cpp73
-rw-r--r--src/ui/zmodemdialog.h51
-rw-r--r--src/ui/zmodemdialog.ui105
-rw-r--r--src/unite/CMakeLists.txt46
-rw-r--r--src/unite/fqterm_mini_server.cpp71
-rw-r--r--src/unite/fqterm_mini_server.h69
-rw-r--r--src/unite/internal/article.cpp19
-rw-r--r--src/unite/internal/article.h28
-rw-r--r--src/unite/internal/board.cpp19
-rw-r--r--src/unite/internal/board.h28
-rw-r--r--src/unite/internal/session.cpp138
-rw-r--r--src/unite/internal/session.h77
-rw-r--r--src/unite/internal/state.cpp676
-rw-r--r--src/unite/internal/state.h219
-rw-r--r--src/unite/internal/statebuilder.cpp32
-rw-r--r--src/unite/internal/statebuilder.h16
-rw-r--r--src/unite/internal/unite.h35
-rw-r--r--src/unite/internal/user.cpp19
-rw-r--r--src/unite/internal/user.h35
-rw-r--r--src/utilities/CMakeLists.txt33
-rw-r--r--src/utilities/fqterm_convert.cpp3485
-rw-r--r--src/utilities/fqterm_convert.h44
-rw-r--r--src/utilities/fqterm_http.cpp264
-rw-r--r--src/utilities/fqterm_http.h83
-rw-r--r--src/utilities/fqterm_ip_location.cpp265
-rw-r--r--src/utilities/fqterm_ip_location.h73
-rw-r--r--src/utilities/fqwcwidth.cpp468
-rw-r--r--src/utilities/fqwcwidth.h60
393 files changed, 77809 insertions, 12 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..6098e8e
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,95 @@
+project(fqterm)
+
+set(FQTERM_VERSION "0.9.8")
+
+cmake_minimum_required( VERSION 2.4.2 FATAL_ERROR )
+
+if(COMMAND cmake_policy)
+ cmake_policy(SET CMP0003 NEW)
+endif(COMMAND cmake_policy)
+
+set(CMAKE_MODULE_PATH
+ ${CMAKE_SOURCE_DIR}/cmake
+)
+
+IF(NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE "MinsizeRel")
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+set(CMAKE_COLOR_MAKEFILE ON)
+
+include(${CMAKE_MODULE_PATH}/VersionControl.cmake)
+vcs_get_revision(MCGSVN_WC_REVISION)
+
+find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork QtScript QtXml REQUIRED)
+IF(APPLE)
+ELSE(APPLE)
+include(${QT_USE_FILE})
+ENDIF(APPLE)
+
+qt4_add_translation(fqterm_qm_files
+ ${CMAKE_SOURCE_DIR}/res/dict/fqterm_zh_CN.ts
+ ${CMAKE_SOURCE_DIR}/res/dict/ui_zh_CN.ts
+ ${CMAKE_SOURCE_DIR}/res/dict/protocol_zh_CN.ts
+ ${CMAKE_SOURCE_DIR}/res/dict/common_zh_CN.ts
+)
+
+add_custom_target(fqterm_qm_target
+ DEPENDS ${fqterm_qm_files}
+)
+FIND_PACKAGE(PythonLibs)
+if (PYTHONLIBS_FOUND)
+ SET(PYTHON_LIB ${PYTHON_LIBRARIES})
+ INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
+ ADD_DEFINITIONS(-DFOUND_PYTHON)
+else (PYTHONLIBS_FOUND)
+ SET(PYTHON_LIB)
+endif (PYTHONLIBS_FOUND)
+
+IF(WIN32)
+ FILE(READ ${QT_LIBRARY_DIR}/QtCore.prl FQ_CORE_QT_CONFIG)
+ELSE(WIN32)
+ IF(APPLE)
+ FILE(READ ${QT_LIBRARY_DIR}/QtCore.framework/QtCore.prl FQ_CORE_QT_CONFIG)
+ ELSE(APPLE)
+ FILE(READ ${QT_LIBRARY_DIR}/libQtCore.prl FQ_CORE_QT_CONFIG)
+ ENDIF(APPLE)
+ENDIF(WIN32)
+
+IF(NOT FQ_CORE_QT_CONFIG MATCHES "static")
+ SET(FQTERM_USE_STATIC_QT false)
+ELSE(NOT FQ_CORE_QT_CONFIG MATCHES "static")
+ SET(FQTERM_USE_STATIC_QT true)
+ENDIF(NOT FQ_CORE_QT_CONFIG MATCHES "static")
+
+SET(SUB_CMAKELIST "UNKNOWN")
+
+IF(WIN32)
+ SET(SUB_CMAKELIST "CMakeLists.txt.win32")
+ELSE(WIN32)
+ IF(APPLE)
+ SET(SUB_CMAKELIST "CMakeLists.txt.macos")
+ ELSE(APPLE)
+ IF(UNIX)
+ IF(CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD")
+ SET(SUB_CMAKELIST "CMakeLists.txt.linux")
+ ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD")
+ IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ SET(SUB_CMAKELIST "CMakeLists.txt.freebsd")
+ ENDIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD")
+ ENDIF(UNIX)
+ ENDIF(APPLE)
+ENDIF(WIN32)
+
+IF(CMAKE_SYSTEM_NAME MATCHES "GNU")
+ SET(SUB_CMAKELIST "CMakeLists.txt.linux")
+ENDIF(CMAKE_SYSTEM_NAME MATCHES "GNU")
+
+IF(SUB_CMAKELIST MATCHES "UNKNOWN")
+ MESSAGE(FATAL_ERROR "Unsupported system type detected!")
+ELSE(SUB_CMAKELIST MATCHES "UNKNOWN")
+ INCLUDE("${SUB_CMAKELIST}")
+ENDIF(SUB_CMAKELIST MATCHES "UNKNOWN")
+
+
diff --git a/CMakeLists.txt.freebsd b/CMakeLists.txt.freebsd
new file mode 100644
index 0000000..08ca9ac
--- /dev/null
+++ b/CMakeLists.txt.freebsd
@@ -0,0 +1,114 @@
+find_package(OpenSSL REQUIRED)
+find_package(OSS)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+ADD_DEFINITIONS(-Wall)
+ADD_DEFINITIONS(-DQT_SHARED)
+ADD_DEFINITIONS(-D_OS_FREEBSD_)
+ADD_DEFINITIONS(-DFQTERM_VERSION_STRING="\\"${FQTERM_VERSION}\\"")
+ADD_DEFINITIONS(-DFQTERM_SVN_REVISION="\\"${MCGSVN_WC_REVISION}\\"")
+IF(OSS_FOUND)
+ ADD_DEFINITIONS(-DAUDIO_OSS)
+ SET(AUDIO_INCLUDE_DIR "${OSS_INCLUDE_DIR}")
+ELSE(OSS_FOUND)
+ SET(AUDIO_INCLUDE_DIR)
+ENDIF(OSS_FOUND)
+
+add_subdirectory(src)
+
+ADD_EXECUTABLE(fqterm.bin
+ src/fqterm/main.cpp
+)
+
+include_directories(
+ ${AUDIO_INCLUDE_DIR}
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/common
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/protocol
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/terminal
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ui
+ ${AUDIO_INCLUDE_DIR}
+)
+
+link_directories(
+ ${QT_PLUGINS_DIR}/codecs
+ ${QT_PLUGINS_DIR}/imageformats
+)
+
+target_link_libraries(fqterm.bin
+ fqterm_main
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_utilities
+ fqterm_ui
+ fqterm_common
+ fqterm_unite
+ ${QT_QTNETWORK_LIBRARIES}
+ ${QT_QTSCRIPT_LIBRARIES}
+ ${QT_LIBRARIES}
+ ${QT_QTXML_LIBRARIES}
+ ${OPENSSL_LIBRARIES}
+ ${PYTHON_LIB}
+)
+
+add_dependencies(fqterm.bin
+ fqterm_main
+ fqterm_common
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_ui
+ fqterm_utilities
+ fqterm_qm_target
+)
+
+add_custom_target(love
+COMMAND FQTERM_RESOURCE=${CMAKE_SOURCE_DIR}/res ${CMAKE_BINARY_DIR}/fqterm.bin
+DEPENDS ${CMAKE_BINARY_DIR}/fqterm.bin
+)
+
+INSTALL(
+ FILES ${CMAKE_BINARY_DIR}/fqterm.bin
+ DESTINATION bin/
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+INSTALL(
+ FILES ${CMAKE_SOURCE_DIR}/res/fqterm.sh
+ DESTINATION bin/
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ RENAME fqterm
+)
+
+INSTALL(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/res/
+ DESTINATION share/FQTerm/
+ DIRECTORY_PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ FILE_PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+ PATTERN "*.svn*" EXCLUDE
+ PATTERN "*.ts.orig*" EXCLUDE
+)
+
+INSTALL(
+ FILES ${fqterm_qm_files}
+ DESTINATION share/FQTerm/dict/
+ PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+)
diff --git a/CMakeLists.txt.linux b/CMakeLists.txt.linux
new file mode 100644
index 0000000..60a53a7
--- /dev/null
+++ b/CMakeLists.txt.linux
@@ -0,0 +1,158 @@
+find_package(OpenSSL REQUIRED)
+find_package(ALSA)
+find_package(OSS)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+if (FQTERM_USE_STATIC_QT)
+ ADD_DEFINITIONS(-DFQTERM_USE_STATIC_QT)
+endif(FQTERM_USE_STATIC_QT)
+
+if (ALSA_FOUND)
+ ADD_DEFINITIONS(-DAUDIO_ALSA)
+ SET(AUDIO_INCLUDE_DIR "${ALSA_INCLUDE_DIR}")
+ SET(AUDIO_LIBRARY "${ALSA_LIBRARY}")
+else (ALSA_FOUND)
+ if (OSS_FOUND)
+ ADD_DEFINITIONS(-DAUDIO_OSS)
+ SET(AUDIO_INCLUDE_DIR "${OSS_INCLUDE_DIR}")
+ SET(AUDIO_LIBRARY)
+ endif (OSS_FOUND)
+endif(ALSA_FOUND)
+
+ADD_DEFINITIONS(-Wall)
+ADD_DEFINITIONS(-D_OS_LINUX_)
+ADD_DEFINITIONS(-D "FQTERM_VERSION_STRING=\\\"${FQTERM_VERSION}\\\"")
+ADD_DEFINITIONS(-D "FQTERM_SVN_REVISION=\\\"${MCGSVN_WC_REVISION}\\\"")
+
+add_subdirectory(src)
+
+ADD_EXECUTABLE(fqterm.bin
+ src/fqterm/main.cpp
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/common
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/protocol
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/terminal
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/unite
+ ${AUDIO_INCLUDE_DIR}
+)
+
+link_directories(
+ ${QT_PLUGINS_DIR}/codecs
+ ${QT_PLUGINS_DIR}/imageformats
+)
+
+if (FQTERM_USE_STATIC_QT)
+ set(FQ_QT_STATIC_PLUGINS
+ ${QT_PLUGINS_DIR}/imageformats/libqgif.a
+ ${QT_PLUGINS_DIR}/imageformats/libqjpeg.a
+ ${QT_PLUGINS_DIR}/imageformats/libqmng.a
+ ${QT_PLUGINS_DIR}/codecs/libqcncodecs.a
+ ${QT_PLUGINS_DIR}/codecs/libqjpcodecs.a
+ ${QT_PLUGINS_DIR}/codecs/libqkrcodecs.a
+ ${QT_PLUGINS_DIR}/codecs/libqtwcodecs.a
+ jpeg
+ )
+endif(FQTERM_USE_STATIC_QT)
+
+target_link_libraries(fqterm.bin
+ fqterm_main
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_utilities
+ fqterm_ui
+ fqterm_common
+ fqterm_unite
+ ${QT_QTNETWORK_LIBRARIES}
+ ${QT_QTXML_LIBRARIES}
+ ${QT_QTSCRIPT_LIBRARIES}
+ ${FQ_QT_STATIC_PLUGINS}
+ ${QT_LIBRARIES}
+ ${OPENSSL_LIBRARIES}
+ ${AUDIO_LIBRARY}
+ ${PYTHON_LIB}
+ crypto
+ X11
+)
+
+add_dependencies(fqterm.bin
+ fqterm_main
+ fqterm_common
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_ui
+ fqterm_utilities
+ fqterm_qm_target
+)
+
+add_custom_target(love
+COMMAND FQTERM_RESOURCE=${CMAKE_SOURCE_DIR}/res ${CMAKE_BINARY_DIR}/fqterm.bin
+DEPENDS ${CMAKE_BINARY_DIR}/fqterm.bin
+)
+
+INSTALL(
+ FILES ${CMAKE_BINARY_DIR}/fqterm.bin
+ DESTINATION bin/
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+INSTALL(
+ FILES ${CMAKE_SOURCE_DIR}/res/fqterm.sh
+ DESTINATION bin/
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ RENAME fqterm
+)
+
+INSTALL(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/res/
+ DESTINATION share/FQTerm/
+ DIRECTORY_PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ FILE_PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+ PATTERN "*.svn*" EXCLUDE
+ PATTERN "fqterm.desktop" EXCLUDE
+)
+
+INSTALL(
+ FILES ${fqterm_qm_files}
+ DESTINATION share/FQTerm/dict/
+ PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+)
+
+INSTALL(
+ FILES res/fqterm.desktop
+ DESTINATION share/applications
+)
+
+SET(CPACK_PACKAGE_CONTACT FireLakeWalker@gmail.com)
+SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE)
+SET(CPACK_SYSTEM_NAME Linux-i386)
+SET(CPACK_PACKAGE_VERSION ${FQTERM_VERSION})
+SET(CPACK_DEBIAN_PACKAGE_VERSION ${FQTERM_VERSION}+i386)
+SET(CPACK_DEBIAN_PACKAGE_SECTION Network)
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "This package is generated by FQTerm team, to get a formal version, please visit http://packages.debian.org/sid/main/fqterm.")
+
+SET(CPACK_GENERATOR DEB)
+INCLUDE(CPack)
+# vim:ft=cmake:
diff --git a/CMakeLists.txt.macos b/CMakeLists.txt.macos
new file mode 100644
index 0000000..459c0ad
--- /dev/null
+++ b/CMakeLists.txt.macos
@@ -0,0 +1,132 @@
+find_package(OpenSSL REQUIRED)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+ADD_DEFINITIONS(-Wall)
+ADD_DEFINITIONS(-DFQTERM_VERSION_STRING="\\"${FQTERM_VERSION}\\"")
+ADD_DEFINITIONS(-DFQTERM_SVN_REVISION="\\"${MCGSVN_WC_REVISION}\\"")
+
+if(FQTERM_USE_STATIC_QT)
+ ADD_DEFINITIONS(-DFQTERM_USE_STATIC_QT)
+endif(FQTERM_USE_STATIC_QT)
+
+add_subdirectory(src)
+
+find_library(APPKIT_LIBRARY AppKit)
+
+FIND_LIBRARY(CARBON_LIBRARY Carbon)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/common
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/protocol
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/terminal
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/unite
+)
+
+link_directories(
+ ${QT_PLUGINS_DIR}/codecs
+ ${QT_PLUGINS_DIR}/imageformats
+)
+
+set(MACOSX_BUNDLE_INFO_STRING "FQTerm for you")
+set(MACOSX_BUNDLE_ICON_FILE "fqterm")
+set(MACOSX_BUNDLE_GUI_IDENTIFIER "FQTerm")
+set(MACOSX_BUNDLE_LONG_VERSION_STRING "FQTerm ${FQTERM_VERSION}")
+set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${FQTERM_VERSION}")
+set(MACOSX_BUNDLE_BUNDLE_NAME "FQTerm")
+set(MACOSX_BUNDLE_BUNDLE_VERSION "1.0")
+set(MACOSX_BUNDLE_COPYRIGHT "2008, fqterm@gmail.com, FireLakeWalker@gmail.com")
+
+ADD_EXECUTABLE(fqterm
+ MACOSX_BUNDLE
+ src/fqterm/main.cpp
+)
+
+set(FQ_QT_PLUGINS
+ qcncodecs qjpcodecs qkrcodecs qtwcodecs
+ qjpeg qgif qmng)
+
+if(FQTERM_USE_STATIC_QT)
+ set(FQ_QT_STATIC_PLUGINS
+ ${FQ_QT_PLUGINS})
+endif(FQTERM_USE_STATIC_QT)
+
+target_link_libraries(fqterm
+ ${QT_LIBRARIES}
+ ${QT_QTCORE_LIBRARY}
+ ${QT_QTGUI_LIBRARY}
+ ${QT_QTNETWORK_LIBRARY}
+ ${QT_QTSCRIPT_LIBRARY}
+ ${APPKIT_LIBRARY}
+ ${CARBON_LIBRARY}
+ ${FQ_QT_STATIC_PLUGINS}
+ ${PYTHON_LIB}
+ ${ZLIB_LIBRARIES}
+ ${QT_QTXML_LIBRARIES}
+ ssl
+ crypto
+ fqterm_common
+ fqterm_protocol
+ fqterm_terminal
+ fqterm_utilities
+ fqterm_ui
+ fqterm_main
+ fqterm_unite
+)
+
+add_dependencies(fqterm
+ fqterm_main
+ fqterm_common
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_ui
+ fqterm_utilities
+ fqterm_unite
+ fqterm_qm_target
+)
+
+add_custom_target(love
+COMMAND FQTERM_RESOURCE=${CMAKE_SOURCE_DIR}/res ${CMAKE_BINARY_DIR}/fqterm.app/Contents/MacOS/fqterm
+DEPENDS ${CMAKE_BINARY_DIR}/fqterm.app/Contents/MacOS/fqterm
+)
+
+INSTALL(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/res/
+ DESTINATION ${CMAKE_BINARY_DIR}/fqterm.app/Contents/Resources/
+ DIRECTORY_PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ FILE_PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+ PATTERN "*.svn*" EXCLUDE
+)
+
+INSTALL(
+ FILES ${fqterm_qm_files}
+ DESTINATION ${CMAKE_BINARY_DIR}/fqterm.app/Contents/Resources/dict/
+ PERMISSIONS
+ OWNER_WRITE OWNER_READ
+ GROUP_READ
+ WORLD_READ
+)
+
+
+add_custom_target(package
+COMMAND make install
+COMMAND rm -f ${CMAKE_BINARY_DIR}/fqterm.dmg
+COMMAND hdiutil create -verbose -srcfolder ${CMAKE_BINARY_DIR}/fqterm.app ${CMAKE_BINARY_DIR}/fqterm.dmg
+DEPENDS ${CMAKE_BINARY_DIR}/fqterm.app
+)
+
+set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
+
+include(DeployQt4)
+INSTALL_QT4_EXECUTABLE(fqterm.app "${FQ_QT_PLUGINS}" "" "")
diff --git a/CMakeLists.txt.win32 b/CMakeLists.txt.win32
new file mode 100644
index 0000000..f9ff97e
--- /dev/null
+++ b/CMakeLists.txt.win32
@@ -0,0 +1,97 @@
+set(OPENSSL_INCLUDE_DIR
+"C:/openssl/include"
+)
+
+set(OPENSSL_LIBRARIES
+"C:/openssl/lib/libeay32.lib"
+"C:/openssl/lib/ssleay32.lib"
+)
+
+set(NETWORK_LIBRARIES
+"ws2_32.lib"
+)
+
+SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/Zi /Od /MD")
+
+ADD_DEFINITIONS(/D USE_DOTNET_STYLE)
+ADD_DEFINITIONS(/D _CRT_SECURE_NO_DEPRECATE)
+ADD_DEFINITIONS(/D FQTERM_VERSION_STRING="\\"${FQTERM_VERSION}\\"")
+ADD_DEFINITIONS(/D FQTERM_SVN_REVISION="\\"${MCGSVN_WC_REVISION}\\"")
+
+if(FQTERM_USE_STATIC_QT)
+ ADD_DEFINITIONS(/D FQTERM_USE_STATIC_QT)
+ REMOVE_DEFINITIONS(-DQT_DLL)
+endif(FQTERM_USE_STATIC_QT)
+
+add_subdirectory(src)
+
+set(fqterm_RCS
+ fqterm.rc
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/common
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/protocol
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/terminal
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/unite
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/unite
+)
+
+link_directories(
+ ${QT_PLUGINS_DIR}/codecs
+ ${QT_PLUGINS_DIR}/imageformats
+)
+
+ADD_EXECUTABLE(fqterm
+ src/fqterm/main.cpp
+)
+
+if(FQTERM_USE_STATIC_QT)
+ set(FQ_QT_STATIC_PLUGINS
+ qcncodecs qjpcodecs qkrcodecs qtwcodecs
+ qjpeg qgif qmng
+ )
+ set(SOUND_LIBRARIES
+ "winmm.lib"
+ )
+
+ set(IME_LIBRARIES
+ "Imm32.lib"
+ )
+endif(FQTERM_USE_STATIC_QT)
+
+target_link_libraries(fqterm
+ fqterm_main
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_utilities
+ fqterm_ui
+ fqterm_common
+ fqterm_unite
+ ${QT_LIBRARIES}
+ ${QT_QTNETWORK_LIBRARIES}
+ ${QT_QTSCRIPT_LIBRARIES}
+ ${QT_QTXML_LIBRARIES}
+ ${OPENSSL_LIBRARIES}
+ ${FQ_QT_STATIC_PLUGINS}
+ ${PYTHON_LIB}
+ ${SOUND_LIBRARIES}
+ ${NETWORK_LIBRARIES}
+ ${IME_LIBRARIES}
+)
+
+add_dependencies(fqterm
+ fqterm_main
+ fqterm_common
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_ui
+ fqterm_unite
+ fqterm_utilities
+ fqterm_unite
+)
diff --git a/FQTermNSIS.nsi b/FQTermNSIS.nsi
new file mode 100644
index 0000000..e2304d9
--- /dev/null
+++ b/FQTermNSIS.nsi
@@ -0,0 +1,195 @@
+;--------------------------------
+!define FQTERMDIR E:\fqterm
+
+;--------------------------------
+
+Name "FQTerm Installer"
+Caption "FQTerm Installer"
+OutFile "FQTerm_Installer.exe"
+
+SetDateSave on
+SetDatablockOptimize on
+CRCCheck on
+SilentInstall normal
+BGGradient 000000 800000 FFFFFF
+InstallColors FF8080 000030
+XPStyle on
+
+InstallDir "$PROGRAMFILES\FQTerm"
+InstallDirRegKey HKLM "Software\FQTerm" "Install_Dir"
+
+
+RequestExecutionLevel admin
+
+;--------------------------------
+
+PageEx license
+ LicenseText "FQTerm, a modern terminal emulator."
+ LicenseData ${FQTERMDIR}\LICENSE
+PageExEnd
+
+
+Page directory
+Page components
+Page instfiles
+
+UninstPage uninstConfirm
+UninstPage instfiles
+
+;--------------------------------
+
+;!ifndef NOINSTTYPES
+; InstType "Full"
+; InstType "Base"
+;!endif
+
+AutoCloseWindow false
+ShowInstDetails show
+
+;--------------------------------
+
+Section "" ; empty string makes it hidden, so would starting with -
+
+ ; write reg info
+ WriteRegStr HKLM SOFTWARE\FQTerm "Install_Dir" "$INSTDIR"
+
+ ; write uninstall strings
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FQTerm" "DisplayName" "FQTerm (remove only)"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FQTerm" "UninstallString" '"$INSTDIR\bt-uninst.exe"'
+
+ SetOutPath $INSTDIR
+ CreateDirectory "$INSTDIR"
+ CreateDirectory "$INSTDIR\cursor"
+ CreateDirectory "$INSTDIR\cursor\mac_16x16"
+ CreateDirectory "$INSTDIR\dict"
+ CreateDirectory "$INSTDIR\pic"
+ CreateDirectory "$INSTDIR\pic\ViewerButtons"
+ CreateDirectory "$INSTDIR\userconf"
+ CreateDirectory "$INSTDIR\script"
+ CreateDirectory "$INSTDIR\unite"
+ CreateDirectory "$INSTDIR\schema"
+ CreateDirectory "$APPDATA\FQTerm"
+ CreateDirectory "$APPDATA\FQTerm\schema"
+ CreateDirectory "$APPDATA\FQTerm\pool"
+ CreateDirectory "$APPDATA\FQTerm\pool\shadow-cache"
+ CreateDirectory "$APPDATA\FQTerm\zmodem"
+ WriteUninstaller "bt-uninst.exe"
+
+SectionEnd
+
+
+
+Section "CreateShortCut"
+
+ Call CSC
+
+SectionEnd
+
+
+Section "-CopyFiles"
+
+; SetOutPath $INSTDIR\FQTerm
+ SetOutPath "$INSTDIR"
+ File "${FQTERMDIR}\build\release\fqterm.exe"
+ File "${FQTERMDIR}\build\release\libeay32.dll"
+ File "${FQTERMDIR}\build\release\msvcr*.dll"
+ File "${FQTERMDIR}\build\release\msvcp*.dll"
+; File "${FQTERMDIR}\build\release\msvcm*.dll"
+ File "${FQTERMDIR}\build\release\python*.dll"
+; File "${FQTERMDIR}\build\release\Microsoft.*.CRT.manifest"
+ File "${FQTERMDIR}\build\release\QQWry.Dat"
+ SetOutPath "$INSTDIR\dict"
+ File "${FQTERMDIR}\build\*.qm"
+ SetOutPath "$INSTDIR"
+ File "${FQTERMDIR}\res\credits"
+ File "${FQTERMDIR}\res\default_font.conf"
+ SetOutPath "$INSTDIR\cursor"
+ File "${FQTERMDIR}\res\cursor\*.*"
+ SetOutPath "$INSTDIR\cursor\mac_16x16"
+ File "${FQTERMDIR}\res\cursor\mac_16x16\*.*"
+ SetOutPath "$INSTDIR\pic"
+ File "${FQTERMDIR}\res\pic\*.*"
+ SetOutPath "$INSTDIR\pic\ViewerButtons"
+ File "${FQTERMDIR}\res\pic\ViewerButtons\*.*"
+ SetOutPath "$INSTDIR\schema"
+ File "${FQTERMDIR}\res\schema\*.*"
+ SetOutPath "$APPDATA\FQTerm\schema"
+ File "${FQTERMDIR}\res\schema\*.*"
+ SetOutPath "$INSTDIR\userconf"
+ File "${FQTERMDIR}\res\userconf\*.*"
+
+ SetOutPath "$INSTDIR\script"
+ File "${FQTERMDIR}\res\script\*.*"
+
+ SetOutPath "$INSTDIR\unite"
+ File "${FQTERMDIR}\res\unite\*.*"
+
+SectionEnd
+
+
+;--------------------------------
+
+Function "CSC"
+
+ SetOutPath $INSTDIR ; for working directory
+ CreateDirectory "$SMPROGRAMS\FQTerm"
+ CreateShortCut "$SMPROGRAMS\FQTerm\Uninstall FQTerm.lnk" "$INSTDIR\bt-uninst.exe"
+ CreateShortCut "$SMPROGRAMS\FQTerm\FQTerm.lnk" "$INSTDIR\fqterm.exe" "" "$INSTDIR\pic\fqterm_32x32.ico"
+ CreateShortCut "$DESKTOP\FQTerm.lnk" "$INSTDIR\fqterm.exe" "" "$INSTDIR\pic\fqterm_256x256.ico"
+ CreateShortCut "$QUICKLAUNCH\FQTerm.lnk" "$INSTDIR\fqterm.exe" "" "$INSTDIR\pic\fqterm_32x32.ico"
+
+FunctionEnd
+
+
+;--------------------------------
+
+; Uninstaller
+
+UninstallText "This will uninstall FQTerm. Hit next to continue."
+;UninstallIcon "${NSISDIR}\Contrib\Graphics\Icons\nsis1-uninstall.ico"
+
+Section "Uninstall"
+
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FQTerm"
+ DeleteRegKey HKLM "SOFTWARE\FQTerm"
+
+ MessageBox MB_YESNO|MB_ICONQUESTION "Would you like to remove the directory $APPDATA\FQTERM?" IDNO NoDelete
+ Delete "$APPDATA\FQTerm\pool\shadow-cache\*.*"
+ RMDir "$APPDATA\FQTerm\pool\shadow-cache"
+ Delete "$APPDATA\FQTerm\pool\*.*"
+ RMDir "$APPDATA\FQTerm\pool"
+ Delete "$APPDATA\FQTerm\zmodem\*.*"
+ RMDir "$APPDATA\FQTerm\zmodem"
+ Delete "$APPDATA\schema\*.*"
+ RMDir "$APPDATA\schema"
+
+ Delete "$APPDATA\FQTERM\*.*"
+ RMDir "$APPDATA\FQTERM" ; skipped if no
+ NoDelete:
+
+ Delete "$INSTDIR\*.*"
+ Delete "$INSTDIR\cursor\*.*"
+ Delete "$INSTDIR\cursor\mac_16x16\*.*"
+ Delete "$INSTDIR\dict\*.*"
+ Delete "$INSTDIR\pic\*.*"
+ Delete "$INSTDIR\pic\ViewerButtons\*.*"
+ Delete "$INSTDIR\userconf\*.*"
+ Delete "$INSTDIR\schema\*.*"
+
+ RMDir "$INSTDIR\schema"
+ RMDir "$INSTDIR\cursor\mac_16x16"
+ RMDir "$INSTDIR\cursor"
+ RMDir "$INSTDIR\dict"
+ RMDir "$INSTDIR\pic\ViewerButtons"
+ RMDir "$INSTDIR\pic"
+ RMDir "$INSTDIR\userconf"
+ RMDir "$INSTDIR"
+ Delete "$SMPROGRAMS\FQTerm\*.lnk"
+ RMDir "$SMPROGRAMS\FQTerm"
+ Delete "$DESKTOP\FQTerm.lnk"
+ Delete "$QUICKLAUNCH\FQTerm.lnk"
+ IfFileExists "$INSTDIR" 0 NoErrorMsg
+ MessageBox MB_OK "Note: $INSTDIR could not be removed!" IDOK 0 ; skipped if file doesn't exist
+ NoErrorMsg:
+
+SectionEnd
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 0000000..1539e46
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,161 @@
+For convenience, we will call the root directory of fqterm source code
+as $FQTERM in this document.
+
+--------------------------------------------------------
+[ How to build FQTerm under Linux using GCC]
+
+First make sure that the latest version of Qt4 library and OpenSSL
+library are installed. Next please install CMake, which is a very
+powerful cross-platform build system. Then follow the instructions
+below to setup the development environment.
+
+1. Create "build" directory.
+
+ Create directory $FQTERM/build.
+
+2. Generate the project file and build FQTerm.
+
+ In the console run commands below:
+
+ $ cd $FQTERM/build # change current postion to the build direcotry
+ $ cmake ../ # generate necessary Makefiles
+ $ make # build the program
+ $ make love # invoke this command if you are eager to run
+ # fqterm before installing it.
+ $ make install # install fqterm.
+ $ fqterm # run fqterm just installed.
+
+3. Enable IP location detection feature.
+
+ If you want to enable the IP location detection feature, please
+ download the IP location database file "QQWry.dat" and put a copy of
+ it under "$HOME/.fqterm" or "$PREFIX/share/FQTerm". You can get
+ "QQWry.dat" from this project's home page or from other websites.
+
+
+--------------------------------------------------------
+[ How to build FQTerm under MacOS X using GCC or Xcode ]
+
+First make sure that the latest version of Qt4 are installed properly.
+Next please install CMake, which is a very powerful cross-platform
+build system. Then follow the instructions below to setup the
+development environment.
+
+1. Create "build" directory.
+
+ Create directory $FQTERM/build.
+
+2. Generate the project file and build FQTerm.
+
+ In the console run commands below:
+
+ $ cd $FQTERM/build # change current postion to the build direcotry
+ $ cmake ../ # generate necessary Makefiles
+ $ make # build the program
+ $ make love # invoke this command if you are eager to run
+ # fqterm before installing it.
+ $ make diskimage # create fqterm.dmg for distribution.
+ $ make install # get a complete MacOS X application bundle
+ # in $FQTERM/build/fqterm.app
+ $ open ./fqterm.app # run fqterm just installed.
+
+ Or if you want to use Xcode to build FQTerm other than GNU make,
+ please run command below instead:
+
+ $ cmake -G "Xcode" ../
+
+ and then use Xcode to open the generated project file.
+
+3. Enable IP location detection feature.
+
+ If you want to enable the IP location detection feature, please
+ download the IP location database file "QQWry.dat" and put a copy of
+ it under "$HOME/.fqterm" or "$PREFIX/share/FQTerm". You can get
+ "QQWry.dat" from this project's home page or from other websites.
+
+4. Known issues.
+
+ You may get an error when running "$ make diskimage" as below:
+
+ $ make diskimage
+ ...
+ hdiutil: create failed - error 49168
+ ...
+
+ [zz http://lists.apple.com/archives/Carbon-dev/2007/Aug/msg00357.html]
+ It seemed one of the reasons listed below could contribute to this problem:
+
+ 1) Some of the files you're trying to archive are being used
+ exclusively by another process. A couple of people figured that
+ their Anti-Virus software (e.g. Norton AV) was to blame.
+
+ 2) Disk space is low, and the hdiutil tool cannot perform its
+ internal caching.
+
+ 3) A file system error which is not detected by Disk Utility
+ prevents proper accessing some crucial files. Repairing the disk
+ using "Disk Warrior" did help.
+
+ 4) Files which were put into the trash can but were not deleted yet
+ cause problems when tried to being put into the disk image.
+
+----------------------------------------------------------
+[ How to build FQTerm under Win32 using MS Visual Studio ]
+
+MS Visual Studio Express 2005 is recommended, but other version of
+Visual Studio can also be used. First make sure that the latest
+version of OpenSSL with default configurations and Qt4 are also
+installed properly. Next please install CMake, which is a very
+powerful cross-platform build system. Then follow the instructions
+below to setup the development environment.
+
+1. Set environment variables.
+
+ Make sure the environment variable QTDIR is set to the directory
+ where Qt4 is installed.
+
+2. Specify OpenSSL path. And prepare python lib.
+
+ First open the file $FQTERM/CMakeLists.txt.win32 with a text
+ editor, and then change the two macros, OPENSSL_INCLUDE_DIR and
+ OPENSSL_LIBRARIES, based on where OpenSSL is installed.
+
+ You MUST have debug version of python lib(pythonxx_d.lib) when
+ build debug version.
+
+3. Create "build" directory.
+
+ Create directory %FQTERM%\build.
+
+4. Generate project files.
+
+ In the console run the command below to generate Visual Studio
+ project files.
+
+ $ cd %FQTERM%\build
+ $ cmake -G "Visual Studio 9 2008" ..\
+
+ This command will generate ".sln" and ".vcproject" files for Visual
+ Studio 8. Then you can use Visual Studio to open the .sln file.
+
+ For other versions of Visual Studio, please see the help
+ message of CMake by running "cmake --help".
+
+5. Start coding/buiding/debuging as usual using Visual Studio.
+
+6. Enable IP location detection feature.
+
+ If you want to enable the IP location detection feature, please
+ download the IP location database file "QQWry.dat" and put a copy of
+ it under "$FQTERM/build/debug" and "$FQTERM/build/release". You can
+ get "QQWry.dat" from this project's home page or from other
+ websites.
+
+7. Generate FQTerm Installer (Windows)
+
+ If you wish to install FQTerm to your system, please install NSIS and
+ compile FQTermNSIS.nsi. This will require some files in the right
+ position. Please check FQTermNSIS.nsi and see the section Section
+ "-CopyFiles".
+
+
diff --git a/LICENSE b/LICENSE
index 22fbe5d..edad89f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,12 +1,12 @@
-GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
+ 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
+ Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@@ -56,7 +56,7 @@ 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
+ GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@@ -255,7 +255,7 @@ 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
+ 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
@@ -277,9 +277,9 @@ 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
+ END OF TERMS AND CONDITIONS
- How to Apply These Terms to Your New Programs
+ 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
@@ -290,8 +290,8 @@ 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.
- {description}
- Copyright (C) {year} {fullname}
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
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
@@ -329,11 +329,26 @@ 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.
- {signature of Ty Coon}, 1 April 1989
+ <signature of Ty Coon>, 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. \ No newline at end of file
+Public License instead of this License.
+
+
+* In addition, as a special exception, the copyright holders give
+* permission to link the code of portions of this program with the
+* OpenSSL library under certain conditions as described in each
+* individual source file, and distribute linked combinations
+* including the two.
+* You must obey the GNU General Public License in all respects
+* for all of the code used other than OpenSSL. If you modify
+* file(s) with this exception, you may extend this exception to your
+* version of the file(s), but you are not obligated to do so. If you
+* do not wish to do so, delete this exception statement from your
+* version. If you delete this exception statement from all source
+* files in the program, then also delete it here.
+
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..d348be2
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,3 @@
+FQTerm is a cross-platform terminal emulator program which supports
+telnet/ssh1/ssh2 protocols and can process ANSI control sequences. It
+can be used to login BBS sites or *NIX hosts.
diff --git a/VersionInfo b/VersionInfo
new file mode 100644
index 0000000..77ef8a1
--- /dev/null
+++ b/VersionInfo
@@ -0,0 +1,12 @@
+[Mac]
+verison=0.9.3
+[Linux]
+version=0.9.3
+[Win]
+version=0.9.3
+[FQMac]
+verison=0.9.8
+[FQLinux]
+version=0.9.8
+[FQWin]
+version=0.9.8
diff --git a/cmake/FindALSA.cmake b/cmake/FindALSA.cmake
new file mode 100644
index 0000000..28bd408
--- /dev/null
+++ b/cmake/FindALSA.cmake
@@ -0,0 +1,46 @@
+#
+# Find ALSA for linux platforms
+# by etnlegend@newsmth
+
+IF ( ALSA_INCLUDE_DIR )
+ SET ( ALSA_FIND_QUIETLY TRUE )
+ENDIF ( ALSA_INCLUDE_DIR )
+
+SET ( ALSA_HDR_NAME "alsa/asoundlib.h" )
+
+FIND_PATH ( ALSA_INCLUDE_DIR "${ALSA_HDR_NAME}"
+ "/usr/local/include" "/usr/include"
+)
+
+SET ( ALSA_LIB_NAME "asound" )
+
+FIND_LIBRARY ( ALSA_LIBRARY
+ NAMES "${ALSA_LIB_NAME}"
+ PATHS "/usr/local/lib" "/usr/lib"
+)
+
+IF ( ALSA_INCLUDE_DIR AND ALSA_LIBRARY )
+ SET ( ALSA_FOUND TRUE )
+ SET ( ALSA_LIBRARIES "${ALSA_LIBRARY}" )
+ELSE ( ALSA_INCLUDE_DIR AND ALSA_LIBRARY )
+ SET ( ALSA_FOUND FALSE )
+ SET ( ALSA_LIBRARIES )
+ENDIF ( ALSA_INCLUDE_DIR AND ALSA_LIBRARY )
+
+IF ( ALSA_FOUND )
+ IF ( NOT ALSA_FIND_QUIETLY )
+ MESSAGE ( STATUS "Found ALSA: ${ALSA_LIBRARY} ${ALSA_INCLUDE_DIR}/${ALSA_HDR_NAME}" )
+ ENDIF ( NOT ALSA_FIND_QUIETLY )
+ELSE ( ALSA_FOUND )
+ IF ( ALSA_FIND_REQUIRED )
+ MESSAGE ( FATAL_ERROR "FAILED to found ALSA - REQUIRED" )
+ ELSE ( ALSA_FIND_REQUIRED )
+ MESSAGE ( STATUS "Disabled ALSA" )
+ ENDIF ( ALSA_FIND_REQUIRED )
+ENDIF ( ALSA_FOUND )
+
+MARK_AS_ADVANCED (
+ ALSA_LIBRARY
+ ALSA_INCLUDE_DIR
+)
+
diff --git a/cmake/FindOSS.cmake b/cmake/FindOSS.cmake
new file mode 100644
index 0000000..51bb102
--- /dev/null
+++ b/cmake/FindOSS.cmake
@@ -0,0 +1,41 @@
+#
+# Find OSS include header for Unix platforms.
+# used by FQTerm to detect the availability of OSS.
+
+IF(UNIX)
+ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ SET(OSS_HDR_NAME "linux/soundcard.h")
+ ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ SET(OSS_HDR_NAME "sys/soundcard.h")
+ ELSE(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ SET(OSS_HDR_NAME "machine/soundcard.h")
+ ENDIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ENDIF(UNIX)
+
+FIND_PATH(OSS_INCLUDE_DIR "${OSS_HDR_NAME}"
+ "/usr/include" "/usr/local/include"
+)
+
+IF(OSS_INCLUDE_DIR)
+ SET(OSS_FOUND TRUE)
+ELSE(OSS_INCLUDE_DIR)
+ SET(OSS_FOUND)
+ENDIF(OSS_INCLUDE_DIR)
+
+IF(OSS_FOUND)
+ MESSAGE(STATUS "Found OSS Audio")
+ELSE(OSS_FOUND)
+ IF(OSS_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "FAILED to found Audio - REQUIRED")
+ ELSE(OSS_FIND_REQUIRED)
+ MESSAGE(STATUS "Audio Disabled")
+ ENDIF(OSS_FIND_REQUIRED)
+ENDIF(OSS_FOUND)
+
+MARK_AS_ADVANCED (
+ OSS_FOUND
+ OSS_INCLUDE_DIR
+)
+
diff --git a/cmake/VersionControl.cmake b/cmake/VersionControl.cmake
new file mode 100644
index 0000000..aa7f4ff
--- /dev/null
+++ b/cmake/VersionControl.cmake
@@ -0,0 +1,82 @@
+# -*- cmake -*-
+#
+# Utility macros for getting info from the version control system.
+# Originally taken from http://emeraldviewer.googlecode.com (GPLv2)
+
+set (PROJECT_SOURCE_DIR .)
+
+FIND_PACKAGE(Subversion)
+
+if (WIN32 AND NOT Subversion_FOUND)
+ # The official subversion client is not available, so fall back to
+ # tortoise if it is installed.
+ find_program(TORTOISE_WCREV_EXECUTABLE
+ NAMES SubWCRev.exe
+ PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\TortoiseSVN;Directory]/bin"
+ )
+
+ if (NOT TORTOISE_WCREV_EXECUTABLE)
+ message(INFO "TortoiseSVN was not found.")
+ endif (NOT TORTOISE_WCREV_EXECUTABLE)
+endif (WIN32 AND NOT Subversion_FOUND)
+
+# Use this macro on all platforms to set _output_variable to the current SVN
+# revision.
+macro(vcs_get_revision _output_variable)
+ if (Subversion_FOUND)
+ # The included Subversion macros performs operations that require auth,
+ # which breaks when building under fakeroot. Replacing with a custom
+ # command. --Ambroff
+ # Subversion_WC_INFO(${PROJECT_SOURCE_DIR} _Indra)
+ # set(${_output_variable} ${_Indra_WC_LAST_CHANGED_REV})
+
+ execute_process(
+ COMMAND ${Subversion_SVN_EXECUTABLE} info ../
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_VARIABLE _svn_info_output
+ ERROR_VARIABLE _svn_info_error
+ RESULT_VARIABLE _svn_info_result
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+
+ if (NOT ${_svn_info_result} EQUAL 0)
+ message(STATUS "svn info failed: ${_svn_info_error}")
+ set(${_output_variable} 0)
+ else (NOT ${_svn_info_result} EQUAL 0)
+ string(REGEX REPLACE
+ "(.*)?Last Changed Rev: ([0-9]+).*$"
+ "\\2"
+ ${_output_variable}
+ ${_svn_info_output})
+ endif (NOT ${_svn_info_result} EQUAL 0)
+ else (Subversion_FOUND)
+ if (WIN32 AND TORTOISE_WCREV_EXECUTABLE)
+ # try to find TortoisSVN if we are on windows.
+ execute_process(
+ COMMAND ${TORTOISE_WCREV_EXECUTABLE} ../
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_VARIABLE _tortoise_rev_info
+ ERROR_VARIABLE _tortoise_rev_info_error
+ RESULT_VARIABLE _tortoise_rev_info_result
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+
+ if (NOT ${_tortoise_rev_info_result} EQUAL 0)
+ message(STATUS "Command '${_tortoise_rev_info_error} ${PROJECT_SOURCE_DIR}' failed: ${_tortoise_rev_info_error}")
+ set(${_output_variable} 0)
+ else (NOT ${_tortoise_rev_info_result} EQUAL 0)
+ string(REGEX REPLACE
+ "(.*\n)?Last committed at revision ([0-9]+).*$"
+ "\\2"
+ ${_output_variable} "${_tortoise_rev_info}")
+ endif (NOT ${_tortoise_rev_info_result} EQUAL 0)
+ else (WIN32 AND TORTOISE_WCREV_EXECUTABLE)
+ # Ruh-roh... we can't get the revision, so set it to '0'
+ message(STATUS
+ "No subversion client is installed. Setting build number to 0.")
+ set(${_output_variable} 0)
+ endif (WIN32 AND TORTOISE_WCREV_EXECUTABLE)
+ endif (Subversion_FOUND)
+endmacro(vcs_get_revision)
diff --git a/doc/DocsYouNeed.txt b/doc/DocsYouNeed.txt
new file mode 100644
index 0000000..509ecd4
--- /dev/null
+++ b/doc/DocsYouNeed.txt
@@ -0,0 +1,6 @@
+RFC854
+RFC_lists
+Unicode Terminals
+Unicode and UTF-8 on the text console
+VTTest_VT100_VT220_XTerm test utility
+vttest.tar.gz \ No newline at end of file
diff --git a/doc/fqtermscript.txt b/doc/fqtermscript.txt
new file mode 100644
index 0000000..57a1a3e
--- /dev/null
+++ b/doc/fqtermscript.txt
@@ -0,0 +1 @@
+please wait... \ No newline at end of file
diff --git a/res/credits b/res/credits
new file mode 100644
index 0000000..196d121
--- /dev/null
+++ b/res/credits
@@ -0,0 +1,52 @@
+Authors of fqterm:
+ curvelet@newsmth.net
+ devilphoenix@newsmth.net
+ edyfox
+ jokhva
+ ecore.cn
+ lidaobing
+ if you have any problems please contact fqterm@gmail.com.
+
+kingson xiaokiangwang@yahoo.com.cn
+fiasco yinshouyi@peoplemail.com.cn
+hooey hephooey@hotmail.com
+ authors of qterm
+
+smartfish
+ smartfish@263.net
+ coder for miniTerm
+
+kafa
+ kafa@263.net
+ coder for miniTerm
+
+Merlion
+ vonjian@yahoo.com
+ making cursor
+
+hwang
+ hwangxw@fm365.com
+ URL detection
+
+Nimrod
+ Nimrod.bbs@smth.org
+ copy article dialog
+
+Luba
+ Luba.bbs@bbs.cs.nthu.edu.tw
+ traditional chinese translation for 0.2.0
+
+cppgx
+ cppgx.bbs@smth.org
+ qtermconfig
+ maintainer of qterm-qst
+
+cyb
+ cyber@thuee.org
+ iplocation
+
+others(patch/suggestion/bug report)
+ Dominator, nukq, ihw, ghostdiy, gpliu,
+ acura, filix, MetalSlugX, hiei, fullow,
+ Chicyu, careless, qiyu, hrothgar, minux.ma,
+ boltomli, oahong, sly.thu, cnyegle, leimiaos, javaboy@newsmth
diff --git a/res/cursor/end.xpm b/res/cursor/end.xpm
new file mode 100644
index 0000000..5105ec7
--- /dev/null
+++ b/res/cursor/end.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *end[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"........#############...........",
+"........#aaa#aaa#aa##...........",
+"........#a###a#a#a#a#...........",
+"........#aaa#a#a#a#a#...........",
+"........#a###a#a#a#a#...........",
+"........#aaa#a#a#aa##...........",
+"........#############...........",
+"................................",
+".....###################........",
+"......#aaaaaaaaaaaaaaa#.........",
+".......#aaaaaaaaaaaaa#..........",
+"........#aaaaaaaaaaa#...........",
+".........#aaaaaaaaa#............",
+"..........#aaaaaaa#.............",
+"...........#aaaaa#..............",
+"............#aaa#...............",
+".............#a#................",
+"......#################.........",
+"......#aaaaaaaaaaaaaaa#.........",
+"......#aaaaaaaaaaaaaaa#.........",
+"......#################.........",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................"};
diff --git a/res/cursor/enter.xpm b/res/cursor/enter.xpm
new file mode 100644
index 0000000..3df959b
--- /dev/null
+++ b/res/cursor/enter.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *enter[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"...#####################........",
+"...#aaa#aaa#aaa#aaa#aaa#........",
+"...#a###a#a##a##a###a#a#........",
+"...#aaa#a#a##a##aaa#aa##........",
+"...#a###a#a##a##a###a#a#........",
+"...#aaa#a#a##a##aaa#a#a#........",
+"...#####################.####...",
+".........................#aa#...",
+".........................#aa#...",
+".......#.................#aa#...",
+"......##.................#aa#...",
+".....#a#.................#aa#...",
+"....#aa###################aa#...",
+"...#aaaaaaaaaaaaaaaaaaaaaaaa#...",
+"...#aaaaaaaaaaaaaaaaaaaaaaaa#...",
+"....#aa######################...",
+".....#a#........................",
+"......##........................",
+".......#........................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................"};
diff --git a/res/cursor/exit.xpm b/res/cursor/exit.xpm
new file mode 100644
index 0000000..674c248
--- /dev/null
+++ b/res/cursor/exit.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *exit[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"................................",
+".........##.....................",
+"........#a#.....................",
+".......#aa#.....................",
+"......#aaa##################....",
+".....#aaaaaaaaaaaaaaaaaaaaa#....",
+"....#aaaaaa###############a#....",
+"...#aaaaaaa#aaa#a#a#a#aaa#a#....",
+"..#aaaaaaaa#a###a#a#a##a##a#....",
+".#aaaaaaaaa#a####a##a##a##a#....",
+"#aaaaaaaaaa#aaa##a##a##a##a#....",
+".#aaaaaaaaa#a####a##a##a##a#....",
+"..#aaaaaaaa#a###a#a#a##a##a#....",
+"...#aaaaaaa#aaa#a#a#a##a##a#....",
+"....#aaaaaa###############a#....",
+".....#aaaaaaaaaaaaaaaaaaaaa#....",
+"......#aaa##################....",
+".......#aa#.....................",
+"........#a#.....................",
+".........##.....................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................"};
diff --git a/res/cursor/hand.xpm b/res/cursor/hand.xpm
new file mode 100644
index 0000000..2a13828
--- /dev/null
+++ b/res/cursor/hand.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *hand[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+".............##.................",
+"............#aa#................",
+"............#aa#................",
+"............#aa#................",
+"............#aa#................",
+"............#aa###..............",
+"............#aa#aa###...........",
+"............#aa#aa#aa##.........",
+"............#aa#aa#aa#a#........",
+"........###.#aa#aa#aa#aa#.......",
+"........#aa##aaaaaaaa#aa#.......",
+"........#aaa#aaaaaaaaaaa#.......",
+".........#aa#aaaaaaaaaaa#.......",
+"..........#a#aaaaaaaaaaa#.......",
+"..........#aaaaaaaaaaaaa#.......",
+"...........#aaaaaaaaaaaa#.......",
+"...........#aaaaaaaaaaa#........",
+"............#aaaaaaaaaa#........",
+"............#aaaaaaaaaa#........",
+".............#aaaaaaaa#.........",
+".............#aaaaaaaa#.........",
+".............##########.........",
+"................................",
+"................................",
+"................................",
+"................................"};
diff --git a/res/cursor/home.xpm b/res/cursor/home.xpm
new file mode 100644
index 0000000..5e74c99
--- /dev/null
+++ b/res/cursor/home.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *home[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"................................",
+"................................",
+"......#################.........",
+"......#aaaaaaaaaaaaaaa#.........",
+"......#aaaaaaaaaaaaaaa#.........",
+"......#################.........",
+".............#a#................",
+"............#aaa#...............",
+"...........#aaaaa#..............",
+"..........#aaaaaaa#.............",
+".........#aaaaaaaaa#............",
+"........#aaaaaaaaaaa#...........",
+".......#aaaaaaaaaaaaa#..........",
+"......#aaaaaaaaaaaaaaa#.........",
+"......#################.........",
+"................................",
+"......#################.........",
+"......#a#a##a##a#a#aaa#.........",
+"......#a#a#a#a#aaa#a###.........",
+"......#aaa#a#a#a#a#aaa#.........",
+"......#a#a#a#a#a#a#a###.........",
+"......#a#a##a##a#a#aaa#.........",
+"......#################.........",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................"};
diff --git a/res/cursor/mac_16x16/end.xpm b/res/cursor/mac_16x16/end.xpm
new file mode 100644
index 0000000..9f7e3d7
--- /dev/null
+++ b/res/cursor/mac_16x16/end.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *end[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+"................",
+"..############..",
+"..#aaaaaaaaaa#..",
+"...#aaaaaaaa#...",
+"....#aaaaaa#....",
+".....#aaaa#.....",
+"......#aa#......",
+".......##.......",
+"..############..",
+"..#aaaaaaaaaa#..",
+"..############..",
+"................",
+"................",
+"................"};
diff --git a/res/cursor/mac_16x16/enter.xpm b/res/cursor/mac_16x16/enter.xpm
new file mode 100644
index 0000000..9f33487
--- /dev/null
+++ b/res/cursor/mac_16x16/enter.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *enter[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+"................",
+"................",
+"............###.",
+"............#a#.",
+"....#.......#a#.",
+"...##.......#a#.",
+"..#a#########a#.",
+".#aaaaaaaaaaaa#.",
+"..#a###########.",
+"...##...........",
+"....#...........",
+"................",
+"................",
+"................"};
diff --git a/res/cursor/mac_16x16/exit.xpm b/res/cursor/mac_16x16/exit.xpm
new file mode 100644
index 0000000..f0e69e1
--- /dev/null
+++ b/res/cursor/mac_16x16/exit.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *exit[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+"................",
+"......#.........",
+".....##.........",
+"....#a#.........",
+"...#aa#########.",
+"..#aaa..aaaaaa#.",
+".#aaaaaaaaaaaa#.",
+"..#aaaaaaaaaaa#.",
+"...#aa#########.",
+"....#a#.........",
+".....##.........",
+"......#.........",
+"................",
+"................"};
diff --git a/res/cursor/mac_16x16/hand.xpm b/res/cursor/mac_16x16/hand.xpm
new file mode 100644
index 0000000..258795e
--- /dev/null
+++ b/res/cursor/mac_16x16/hand.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *hand[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"......#.........",
+".....#a#........",
+".....#a#........",
+".....#a###......",
+".....#a#a###....",
+".....#a#a#a###..",
+".##..#a#a#a#.###",
+".#a###aaaaaa.#a#",
+".#aaa#aaaaaa..a#",
+"..#aaaaaaaaaaa##",
+"...#a.aaaaaaaa#.",
+"...##aaaaaaaa##.",
+"....##aaaaaaa#..",
+".....#aaaaaaa#..",
+".....#########..",
+"................"};
diff --git a/res/cursor/mac_16x16/home.xpm b/res/cursor/mac_16x16/home.xpm
new file mode 100644
index 0000000..feae51c
--- /dev/null
+++ b/res/cursor/mac_16x16/home.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *home[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+"................",
+"..############..",
+"..#aaaaaaaaaa#..",
+"..############..",
+".......##.......",
+"......#aa#......",
+".....#aaa.#.....",
+"....#aaaaaa#....",
+"...#aaaaaaaa#...",
+"..#aaaaaaaaaa#..",
+"..############..",
+"................",
+"................",
+"................"};
diff --git a/res/cursor/mac_16x16/next.xpm b/res/cursor/mac_16x16/next.xpm
new file mode 100644
index 0000000..43f11dd
--- /dev/null
+++ b/res/cursor/mac_16x16/next.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *next[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+".....#####......",
+".....#aaa#......",
+".....#aaa#......",
+".....#aaa#......",
+".#####aaa#####..",
+".#aaaaaaaaaaa#..",
+"..#aaaaaaaaa#...",
+"...#aaaaaaa#....",
+"....#aaaaa#.....",
+".....#aaa#......",
+"......#a#.......",
+".......#........",
+"................",
+"................"};
diff --git a/res/cursor/mac_16x16/pagedown.xpm b/res/cursor/mac_16x16/pagedown.xpm
new file mode 100644
index 0000000..063b4bc
--- /dev/null
+++ b/res/cursor/mac_16x16/pagedown.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *pagedown[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+"..###########...",
+"...#aaaaaaa#....",
+"....#aaaaa#.....",
+".....#aaa#......",
+"......#a#.......",
+".......#........",
+"..###########...",
+"...#aaaaaaa#....",
+"....#aaaaa#.....",
+".....#aaa#......",
+"......#a#.......",
+".......#........",
+"................",
+"................"};
diff --git a/res/cursor/mac_16x16/pageup.xpm b/res/cursor/mac_16x16/pageup.xpm
new file mode 100644
index 0000000..ce0570c
--- /dev/null
+++ b/res/cursor/mac_16x16/pageup.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *pageup[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+".......#........",
+"......#a#.......",
+".....#aaa#......",
+"....#aaaaa#.....",
+"...#aaaaaaa#....",
+"..#aaaaaaaaa#...",
+".#############..",
+"......#a#.......",
+".....#aaa#......",
+"....#aaaaa#.....",
+"...#aaaaaaa#....",
+"..#aaaaaaaaa#...",
+".#############..",
+"................"};
diff --git a/res/cursor/mac_16x16/prev.xpm b/res/cursor/mac_16x16/prev.xpm
new file mode 100644
index 0000000..8524545
--- /dev/null
+++ b/res/cursor/mac_16x16/prev.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char *prev[]={
+"16 16 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................",
+"................",
+".......#........",
+"......#a#.......",
+".....#aaa#......",
+"....#aaaaa#.....",
+"...#aaaaaaa#....",
+"..#aaaaaaaaa#...",
+".#.aaaaaaaaaa#..",
+".#####aaa#####..",
+".....#aaa#......",
+".....#aaa#......",
+".....#aaa#......",
+".....#####......",
+"................",
+"................"};
diff --git a/res/cursor/next.xpm b/res/cursor/next.xpm
new file mode 100644
index 0000000..1592168
--- /dev/null
+++ b/res/cursor/next.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *next[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+".......#################........",
+".......#aaa#aaa#a#a#aaa#........",
+".......#a#a#a###a#a##a##........",
+".......#a#a#aaa##a###a##........",
+".......#a#a#a###a#a##a##........",
+".......#a#a#aaa#a#a##a##........",
+".......#################........",
+"................................",
+"............#######.............",
+"............#aaaaa#.............",
+"............#aaaaa#.............",
+"............#aaaaa#.............",
+"........#####aaaaa#####.........",
+"........#aaaaaaaaaaaaa#.........",
+".........#aaaaaaaaaaa#..........",
+"..........#aaaaaaaaa#...........",
+"...........#aaaaaaa#............",
+"............#aaaaa#.............",
+".............#aaa#..............",
+"..............#a#...............",
+"...............#................",
+"................................",
+"................................"};
diff --git a/res/cursor/pagedown.xpm b/res/cursor/pagedown.xpm
new file mode 100644
index 0000000..b2cee38
--- /dev/null
+++ b/res/cursor/pagedown.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *pagedown[]={
+"32 32 3 1",
+"a c None",
+". c #000000",
+"# c #ffffff",
+"................................",
+"##...#...##.###.##...#..#.#.###.",
+"#.#.#.#.#...#...#.#.#.#.#.#.#.#.",
+"##..###.#...###.#.#.#.#.#.#.#.#.",
+"#...#.#.#.#.#...#.#.#.#.###.#.#.",
+"#...#.#..##.###.##...#..#.#.#.#.",
+"................................",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+"aaaaaaa.................aaaaaaaa",
+"aaaaaaa.###############.aaaaaaaa",
+"aaaaaaaa.#############.aaaaaaaaa",
+"aaaaaaaaa.###########.aaaaaaaaaa",
+"aaaaaaaaaa.#########.aaaaaaaaaaa",
+"aaaaaaaaaaa.#######.aaaaaaaaaaaa",
+"aaaaaaaaaaaa.#####.aaaaaaaaaaaaa",
+"aaaaaaaaaaaaa.###.aaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaa.#.aaaaaaaaaaaaaaa",
+"aaaaaaa.................aaaaaaaa",
+"aaaaaaa.###############.aaaaaaaa",
+"aaaaaaaa.#############.aaaaaaaaa",
+"aaaaaaaaa.###########.aaaaaaaaaa",
+"aaaaaaaaaa.#########.aaaaaaaaaaa",
+"aaaaaaaaaaa.#######.aaaaaaaaaaaa",
+"aaaaaaaaaaaa.#####.aaaaaaaaaaaaa",
+"aaaaaaaaaaaaa.###.aaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaa.#.aaaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
diff --git a/res/cursor/pageup.xpm b/res/cursor/pageup.xpm
new file mode 100644
index 0000000..6b1e579
--- /dev/null
+++ b/res/cursor/pageup.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *pageup[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"................................",
+"................................",
+"................................",
+"...............#................",
+"..............#a#...............",
+".............#aaa#..............",
+"............#aaaaa#.............",
+"...........#aaaaaaa#............",
+"..........#aaaaaaaaa#...........",
+".........#aaaaaaaaaaa#..........",
+"........#aaaaaaaaaaaaa#.........",
+".......#aaaaaaaaaaaaaaa#........",
+".......#################........",
+"..............#a#...............",
+".............#aaa#..............",
+"............#aaaaa#.............",
+"...........#aaaaaaa#............",
+"..........#aaaaaaaaa#...........",
+".........#aaaaaaaaaaa#..........",
+"........#aaaaaaaaaaaaa#.........",
+".......#aaaaaaaaaaaaaaa#........",
+".......#################........",
+"................................",
+"...#########################....",
+"...#aa###a###aa#aaa#a#a#aa##....",
+"...#a#a#a#a#a###a###a#a#a#a#....",
+"...#aa##aaa#a###aaa#a#a#aa##....",
+"...#a###a#a#a#a#a###a#a#a###....",
+"...#a###a#a##aa#aaa##a##a###....",
+"...#########################....",
+"................................"};
diff --git a/res/cursor/prev.xpm b/res/cursor/prev.xpm
new file mode 100644
index 0000000..340afdf
--- /dev/null
+++ b/res/cursor/prev.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char *prev[]={
+"32 32 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"................................",
+"..............#.................",
+".............#a#................",
+"............#aaa#...............",
+"...........#aaaaa#..............",
+"..........#aaaaaaa#.............",
+".........#aaaaaaaaa#............",
+"........#aaaaaaaaaaa#...........",
+".......#aaaaaaaaaaaaa#..........",
+".......#####aaaaa#####..........",
+"...........#aaaaa#..............",
+"...........#aaaaa#..............",
+"...........#aaaaa#..............",
+"...........#######..............",
+"................................",
+"......#################.........",
+"......#aa##aa##aaa#a#a#.........",
+"......#a#a#a#a#a###a#a#.........",
+"......#aa##aa##aaa#a#a#.........",
+"......#a###a#a#a###aaa#.........",
+"......#a###a#a#aaa##a##.........",
+"......#################.........",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................",
+"................................"};
diff --git a/res/default_font.conf b/res/default_font.conf
new file mode 100644
index 0000000..c10d20b
--- /dev/null
+++ b/res/default_font.conf
@@ -0,0 +1,24 @@
+[Apple]
+Default=en_US:Monaco, Andale Mono, Courier, Courier New, Lucida Sans Typewriter
+Monaco=zh_CN:åŽæ–‡ç»†é»‘, åŽæ–‡é»‘体, Hei
+Andale Mono=zh_CN:åŽæ–‡ç»†é»‘, åŽæ–‡é»‘体, Hei
+Courier=zh_CN:åŽæ–‡å®‹ä½“, 宋体, åŽæ–‡æ¥·ä½“, Kai, åŽæ–‡ä»¿å®‹
+Courier New=zh_CN:åŽæ–‡å®‹ä½“, 宋体, åŽæ–‡æ¥·ä½“, Kai, åŽæ–‡ä»¿å®‹
+Lucida Sans Typewriter=zh_CN:åŽæ–‡ç»†é»‘, åŽæ–‡é»‘体, Hei
+
+[Linux]
+Default=en_US:Courier, Andale Mono, Bitstream Vera Sans Mono, Courier New, Cursor, Monospace
+Courier=zh_CN:新宋体, åŽæ–‡å®‹ä½“, 宋体, åŽæ–‡æ¥·ä½“, AR PL ZenKai Uni, åŽæ–‡ä»¿å®‹, AR PL ShanHeiSun Uni
+Andale Mono=zh_CN: åŽæ–‡ç»†é»‘, åŽæ–‡é»‘体, 黑体, WenQuanYi Zen Hei, AR PL ShanHeiSun Uni
+Bitstream Vera Sans Mono=zh_CN: åŽæ–‡ç»†é»‘, åŽæ–‡é»‘体, 黑体, WenQuanYi Zen Hei, AR PL ShanHeiSun Uni
+Courier New=zh_CN:新宋体, åŽæ–‡å®‹ä½“, 宋体, åŽæ–‡æ¥·ä½“, AR PL ZenKai Uni, åŽæ–‡ä»¿å®‹, AR PL ShanHeiSun Uni
+Cursor=zh_CN: åŽæ–‡ç»†é»‘, åŽæ–‡é»‘体, 黑体, WenQuanYi Zen Hei, AR PL ShanHeiSun Uni
+Monospace=zh_CN:åŽæ–‡ç»†é»‘, åŽæ–‡é»‘体, 黑体, WenQuanYi Zen Hei, AR PL ShanHeiSun Uni
+
+[Windows]
+Default=en_US:新宋体, Bitstream Vera Sans Mono, 宋体, 楷体, Courier, Courier New, Lucida Sans Typewriter
+Courier=zh_CN:新宋体, 宋体, åŽæ–‡å®‹ä½“, åŽæ–‡æ¥·ä½“, Kai, åŽæ–‡ä»¿å®‹
+Courier New=zh_CN:新宋体, 宋体, åŽæ–‡å®‹ä½“, åŽæ–‡æ¥·ä½“, Kai, åŽæ–‡ä»¿å®‹
+Bitstream Vera Sans Mono=zh_CN:微软雅黑, 黑体, 幼圆
+Lucida Sans Typewriter=zh_CN:微软雅黑, 黑体, 幼圆
+
diff --git a/res/dict/common_zh_CN.ts b/res/dict/common_zh_CN.ts
new file mode 100644
index 0000000..0f10a77
--- /dev/null
+++ b/res/dict/common_zh_CN.ts
@@ -0,0 +1,618 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh_CN" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>FQTerm::FQTermFileDialog</name>
+ <message>
+ <source>Save As...</source>
+ <translation>å¦å­˜ä¸º...</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermShortcutHelper</name>
+ <message>
+ <source>Connect Host</source>
+ <translation>连接主机</translation>
+ </message>
+ <message>
+ <source>Disconnect Host</source>
+ <translation>断开连接</translation>
+ </message>
+ <message>
+ <source>F2</source>
+ <translation>F2</translation>
+ </message>
+ <message>
+ <source>Address Book</source>
+ <translation>地å€ç°¿</translation>
+ </message>
+ <message>
+ <source>F3</source>
+ <translation>F3</translation>
+ </message>
+ <message>
+ <source>Quick Login</source>
+ <translation>快速连接</translation>
+ </message>
+ <message>
+ <source>Ctrl+C</source>
+ <translation>Ctrl+C</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>å¤åˆ¶</translation>
+ </message>
+ <message>
+ <source>Ctrl+V</source>
+ <translation>Ctrl+V</translation>
+ </message>
+ <message>
+ <source>Paste</source>
+ <translation>粘贴</translation>
+ </message>
+ <message>
+ <source>Ctrl+Ins</source>
+ <translation>Ctrl+Ins</translation>
+ </message>
+ <message>
+ <source>Shift+Insert</source>
+ <translation>Shift+Insert</translation>
+ </message>
+ <message>
+ <source>Copy With Color</source>
+ <translation>彩色å¤åˆ¶</translation>
+ </message>
+ <message>
+ <source>Rectangle Selection</source>
+ <translation>矩形选择</translation>
+ </message>
+ <message>
+ <source>Paste With Word Wrap</source>
+ <translation>自动折行粘贴</translation>
+ </message>
+ <message>
+ <source>Set English Font</source>
+ <translation>设置英文字体</translation>
+ </message>
+ <message>
+ <source>Color Setting</source>
+ <translation>颜色设置</translation>
+ </message>
+ <message>
+ <source>Refresh Screen</source>
+ <translation>刷新å±å¹•</translation>
+ </message>
+ <message>
+ <source>Toggle Ansi Color</source>
+ <translation>开关ANSI色彩</translation>
+ </message>
+ <message>
+ <source>Set UI Font</source>
+ <translation>设置UI字体</translation>
+ </message>
+ <message>
+ <source>F6</source>
+ <translation>F6</translation>
+ </message>
+ <message>
+ <source>Toggle Full Screen</source>
+ <translation>å…¨å±/æ¢å¤</translation>
+ </message>
+ <message>
+ <source>F12</source>
+ <translation>F12</translation>
+ </message>
+ <message>
+ <source>Toggle Boss Color</source>
+ <translation>è€æ¿é”®/æ¢å¤</translation>
+ </message>
+ <message>
+ <source>Toggle Switch Bar</source>
+ <translation>开关Switch Bar</translation>
+ </message>
+ <message>
+ <source>Current Session Setting</source>
+ <translation>当å‰ç«™ç‚¹è®¾ç½®</translation>
+ </message>
+ <message>
+ <source>Ctrl+Alt+G</source>
+ <translation>Ctrl+Alt+G</translation>
+ </message>
+ <message>
+ <source>Google selected words</source>
+ <translation>Google选中文本</translation>
+ </message>
+ <message>
+ <source>Ctrl+Alt+E</source>
+ <translation>Ctrl+Alt+E</translation>
+ </message>
+ <message>
+ <source>Invoke external editor</source>
+ <translation>调用外部编辑器 </translation>
+ </message>
+ <message>
+ <source>Default Setting</source>
+ <translation>缺çœè®¾ç½®</translation>
+ </message>
+ <message>
+ <source>Preference</source>
+ <translation>å好</translation>
+ </message>
+ <message>
+ <source>Edit Schema</source>
+ <translation>编辑调色æ¿</translation>
+ </message>
+ <message>
+ <source>Shorcut Setting</source>
+ <translation>å¿«æ·é”®è®¾ç½®</translation>
+ </message>
+ <message>
+ <source>F9</source>
+ <translation>F9</translation>
+ </message>
+ <message>
+ <source>Copy Article</source>
+ <translation>å¤åˆ¶æ–‡ç« </translation>
+ </message>
+ <message>
+ <source>Toggle Anti Idle</source>
+ <translation>开关防å‘呆</translation>
+ </message>
+ <message>
+ <source>Toggle Auto Reply</source>
+ <translation>开关自动回å¤</translation>
+ </message>
+ <message>
+ <source>F10</source>
+ <translation>F10</translation>
+ </message>
+ <message>
+ <source>View Messages</source>
+ <translation>æµè§ˆä¿¡æ¯</translation>
+ </message>
+ <message>
+ <source>IP Lookup</source>
+ <translation>IP查询</translation>
+ </message>
+ <message>
+ <source>Toggle Beep</source>
+ <translation>开关蜂鸣</translation>
+ </message>
+ <message>
+ <source>Toggle Mouse Support</source>
+ <translation>开关鼠标支æŒ</translation>
+ </message>
+ <message>
+ <source>Image Viewer</source>
+ <translation>图åƒæµè§ˆå™¨</translation>
+ </message>
+ <message>
+ <source>F7</source>
+ <translation>F7</translation>
+ </message>
+ <message>
+ <source>Run Script</source>
+ <translation>执行脚本</translation>
+ </message>
+ <message>
+ <source>F8</source>
+ <translation>F8</translation>
+ </message>
+ <message>
+ <source>Stop Script</source>
+ <translation>åœæ­¢è„šæœ¬</translation>
+ </message>
+ <message>
+ <source>Ctrl+F1</source>
+ <translation>Ctrl+F1</translation>
+ </message>
+ <message>
+ <source>Run Python Script</source>
+ <translation>执行Python脚本</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>关于</translation>
+ </message>
+ <message>
+ <source>Homepage</source>
+ <translation>主页</translation>
+ </message>
+ <message>
+ <source>&amp;Connect</source>
+ <translation>连接(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Disconnect</source>
+ <translation>断开连接(&amp;D)</translation>
+ </message>
+ <message>
+ <source>&amp;Address book</source>
+ <translation>地å€ç°¿(&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Quick login</source>
+ <translation>快速连接(&amp;Q)</translation>
+ </message>
+ <message>
+ <source>&amp;Exit</source>
+ <translation>退出(&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>å¤åˆ¶(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Paste</source>
+ <translation>粘贴(&amp;P)</translation>
+ </message>
+ <message>
+ <source>C&amp;opy with color</source>
+ <translation>彩色å¤åˆ¶(&amp;o)</translation>
+ </message>
+ <message>
+ <source>&amp;Rectangle select</source>
+ <translation>矩形选择(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Auto copy &amp;select</source>
+ <translation>自动å¤åˆ¶(&amp;s)</translation>
+ </message>
+ <message>
+ <source>P&amp;aste with wordwrap</source>
+ <translation>自动æ¢è¡Œç²˜è´´(&amp;a)</translation>
+ </message>
+ <message>
+ <source>&amp;Google It</source>
+ <translation type="obsolete">Google一下(&amp;G)</translation>
+ </message>
+ <message>
+ <source>E&amp;xternal Editor</source>
+ <translation>外部编辑器(&amp;x)</translation>
+ </message>
+ <message>
+ <source>&amp;Fast Post</source>
+ <translation>快速å‘æ–‡(&amp;F)</translation>
+ </message>
+ <message>
+ <source>&amp;None</source>
+ <translation>&amp;None</translation>
+ </message>
+ <message>
+ <source>&amp;ESC ESC [</source>
+ <translation>&amp;ESC ESC [</translation>
+ </message>
+ <message>
+ <source>Ctrl+&amp;U [</source>
+ <translation type="obsolete">Ctrl+&amp;U [</translation>
+ </message>
+ <message>
+ <source>&amp;Custom...</source>
+ <translation>自定义(&amp;C)...</translation>
+ </message>
+ <message>
+ <source>&amp;Non-English Font</source>
+ <translation type="obsolete">éžè‹±è¯­å­—体(&amp;N)</translation>
+ </message>
+ <message>
+ <source>&amp;English Font</source>
+ <translation>英语字体(&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Color Setting</source>
+ <translation>颜色设置(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Use ANSI Color</source>
+ <translation>使用ANSI颜色(&amp;U)</translation>
+ </message>
+ <message>
+ <source>&amp;Refresh</source>
+ <translation>刷新(&amp;R)</translation>
+ </message>
+ <message>
+ <source>U&amp;I font</source>
+ <translation>ç•Œé¢å­—体(&amp;I)</translation>
+ </message>
+ <message>
+ <source>Fullscree&amp;n</source>
+ <translation>å…¨å±(&amp;n)</translation>
+ </message>
+ <message>
+ <source>B&amp;oss Color</source>
+ <translation>ä¿æŠ¤è‰²(&amp;C)</translation>
+ </message>
+ <message>
+ <source>S&amp;witch Bar</source>
+ <translation>任务æ (&amp;w)</translation>
+ </message>
+ <message>
+ <source>&amp;Hide</source>
+ <translation>éšè—(&amp;H)</translation>
+ </message>
+ <message>
+ <source>&amp;Left</source>
+ <translation>左侧(&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;Right</source>
+ <translation>å³ä¾§(&amp;R)</translation>
+ </message>
+ <message>
+ <source>&amp;Setting for current session</source>
+ <translation>当å‰è¿žæŽ¥å±žæ€§(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Default setting</source>
+ <translation>缺çœè®¾ç½®(&amp;D)</translation>
+ </message>
+ <message>
+ <source>&amp;Preferences...</source>
+ <translation>å好(&amp;P)...</translation>
+ </message>
+ <message>
+ <source>Short&amp;cut Setting</source>
+ <translation>å¿«æ·é”®è®¾ç½®(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Edit Schema</source>
+ <translation>编辑图标(&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Copy article</source>
+ <translation>全文下载(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Anti &amp;idle</source>
+ <translation>防å‘呆(&amp;i)</translation>
+ </message>
+ <message>
+ <source>Auto &amp;reply</source>
+ <translation>自动回å¤(&amp;r)</translation>
+ </message>
+ <message>
+ <source>&amp;View messages</source>
+ <translation>查看å³æ—¶æ¶ˆæ¯(&amp;V)</translation>
+ </message>
+ <message>
+ <source>&amp;Beep</source>
+ <translation>蜂鸣(&amp;B) </translation>
+ </message>
+ <message>
+ <source>&amp;Mouse support</source>
+ <translation>鼠标支æŒ(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Ima&amp;ge viewer</source>
+ <translation>图åƒé¢„览器(&amp;g)</translation>
+ </message>
+ <message>
+ <source>I&amp;P Lookup</source>
+ <translation>查询IP(&amp;P)</translation>
+ </message>
+ <message>
+ <source>&amp;Run...</source>
+ <translation>è¿è¡Œ(&amp;R)...</translation>
+ </message>
+ <message>
+ <source>&amp;Stop</source>
+ <translation>åœæ­¢(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Run &amp;Python...</source>
+ <translation>执行Python脚本(&amp;P)...</translation>
+ </message>
+ <message>
+ <source>&amp;Cascade</source>
+ <translation>层å (&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Tile</source>
+ <translation>平铺(&amp;T)</translation>
+ </message>
+ <message>
+ <source>About &amp;FQTerm</source>
+ <translation>关于 FQTerm(&amp;F)</translation>
+ </message>
+ <message>
+ <source>FQTerm&apos;s &amp;Homepage</source>
+ <translation>主页(&amp;H)</translation>
+ </message>
+ <message>
+ <source>Reconnect When Disconnected By Host</source>
+ <translation>当主机断开时自动é‡è¿ž</translation>
+ </message>
+ <message>
+ <source>Cascade Windows</source>
+ <translation>层å çª—å£</translation>
+ </message>
+ <message>
+ <source>Tils Windows</source>
+ <translation>平铺窗å£</translation>
+ </message>
+ <message>
+ <source>Auto Copy Selection</source>
+ <translation>自动å¤åˆ¶é€‰æ‹©åŒºåŸŸ</translation>
+ </message>
+ <message>
+ <source>Set Other Font</source>
+ <translation>设置中文字体</translation>
+ </message>
+ <message>
+ <source>Alt+`</source>
+ <translation>Alt+`</translation>
+ </message>
+ <message>
+ <source>Share selected text and highlighted URL to weibo</source>
+ <translation>分享选中文本(至微åš)</translation>
+ </message>
+ <message>
+ <source>Ctrl+Alt+F</source>
+ <translation>Ctrl+Alt+F</translation>
+ </message>
+ <message>
+ <source>Fast post from clipboard</source>
+ <translation>快速å‘帖(自剪贴æ¿)</translation>
+ </message>
+ <message>
+ <source>Shift+F1</source>
+ <translation>Shift+F1</translation>
+ </message>
+ <message>
+ <source>Exit FQTerm</source>
+ <translation>退出FQTerm</translation>
+ </message>
+ <message>
+ <source>Set Color Ctrl to None</source>
+ <translation>将颜色控制字符串设为空</translation>
+ </message>
+ <message>
+ <source>Set Color Ctrl to **[</source>
+ <translation>将颜色控制字符串设为 **[</translation>
+ </message>
+ <message>
+ <source>Set Color Ctrl to ^u[</source>
+ <translation>将颜色控制字符串设为 ^u[</translation>
+ </message>
+ <message>
+ <source>Set Color Ctrl to old custom</source>
+ <translation>将颜色控制字符串设为自定义字符串</translation>
+ </message>
+ <message>
+ <source>Set Color Ctrl to custom</source>
+ <translation>将颜色控制字符串设为自定义字符串</translation>
+ </message>
+ <message>
+ <source>Toggle Auto Reconnect</source>
+ <translation>开关自动é‡è¿ž</translation>
+ </message>
+ <message>
+ <source>Set Scrollbar to Left</source>
+ <translation>滚动æ¡å·¦ä¾§æ˜¾ç¤º</translation>
+ </message>
+ <message>
+ <source>Set Scrollbar to Right</source>
+ <translation>滚动æ¡å³ä¾§æ˜¾ç¤º</translation>
+ </message>
+ <message>
+ <source>Set Scrollbar Hidden</source>
+ <translation>éšè—滚动æ¡</translation>
+ </message>
+ <message>
+ <source>Use Google</source>
+ <translation>使用Google</translation>
+ </message>
+ <message>
+ <source>Use Baidu</source>
+ <translation>使用Baidu</translation>
+ </message>
+ <message>
+ <source>Use Bing</source>
+ <translation>使用Bing</translation>
+ </message>
+ <message>
+ <source>Use Yahoo!</source>
+ <translation>使用Yahoo!</translation>
+ </message>
+ <message>
+ <source>Use Customized SE</source>
+ <translation>使用自定义æœç´¢å¼•æ“Ž</translation>
+ </message>
+ <message>
+ <source>Choose UI Language: English</source>
+ <translation>Choose UI Language: English</translation>
+ </message>
+ <message>
+ <source>Save Current Session Setting</source>
+ <translation>ä¿å­˜å½“å‰ç«™ç‚¹è®¾ç½®</translation>
+ </message>
+ <message>
+ <source>Ctrl</source>
+ <translation>Ctrl</translation>
+ </message>
+ <message>
+ <source>Alt</source>
+ <translation>Alt</translation>
+ </message>
+ <message>
+ <source>+Right</source>
+ <translation>+Right</translation>
+ </message>
+ <message>
+ <source>Next Window</source>
+ <translation>下一窗å£</translation>
+ </message>
+ <message>
+ <source>+Left</source>
+ <translation>+Left</translation>
+ </message>
+ <message>
+ <source>Prev Window</source>
+ <translation>å‰ä¸€çª—å£</translation>
+ </message>
+ <message>
+ <source>Ctrl+Alt+Q</source>
+ <translation>Ctrl+Alt+Q</translation>
+ </message>
+ <message>
+ <source>Show FQTerm</source>
+ <translation>显示FQTerm</translation>
+ </message>
+ <message>
+ <source>O&amp;ther Font</source>
+ <translation>中文字体(&amp;t)</translation>
+ </message>
+ <message>
+ <source>&amp;Search It</source>
+ <translation>æœç´¢æ–‡æœ¬(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Sha&amp;re It</source>
+ <translation>分享信æ¯(&amp;r)</translation>
+ </message>
+ <message>
+ <source>Ctrl+&amp;U[</source>
+ <translation>Ctrl+&amp;U[</translation>
+ </message>
+ <message>
+ <source>&amp;English</source>
+ <translation>英语(&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Google</source>
+ <translation>&amp;Google</translation>
+ </message>
+ <message>
+ <source>&amp;Baidu</source>
+ <translation>&amp;Baidu</translation>
+ </message>
+ <message>
+ <source>&amp;Bing</source>
+ <translation>&amp;Bing</translation>
+ </message>
+ <message>
+ <source>&amp;Yahoo!</source>
+ <translation>&amp;Yahoo!</translation>
+ </message>
+ <message>
+ <source>&amp;Custom</source>
+ <translation>自定义(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Save Settin&amp;g</source>
+ <translation>ä¿å­˜è®¾ç½®(&amp;g)</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>&amp;English</source>
+ <translation>英语(&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Non-English</source>
+ <translation>éžè‹±è¯­(&amp;N)</translation>
+ </message>
+</context>
+</TS>
diff --git a/res/dict/fqterm_zh_CN.ts b/res/dict/fqterm_zh_CN.ts
new file mode 100644
index 0000000..8c1f614
--- /dev/null
+++ b/res/dict/fqterm_zh_CN.ts
@@ -0,0 +1,666 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>FQTerm::FQTermAutoUpdater</name>
+ <message>
+ <source>FQTerm Update Notifier</source>
+ <translation>FQTerm å‡çº§é€šçŸ¥</translation>
+ </message>
+ <message>
+ <source>FQTerm update available.
+Press OK to visit our download list,
+Discard for a next-time-startup inform,
+Ignore for no more notification.</source>
+ <translation type="obsolete">FQTerm 新版本å¯ç”¨
+&quot;确认&quot;访问下载列表
+“å–消&quot;等待下次å¯åŠ¨æ示
+&quot;忽略&quot;忽略本次更新.</translation>
+ </message>
+ <message>
+ <source>FQTerm update available.
+Press OK to visit our download list,
+Discard for a future prompt,
+Ignore for no more notification.</source>
+ <translation>FQTerm 新版本å¯ç”¨
+&quot;确认&quot;访问下载列表
+“å–消&quot;å°†æ¥æ示
+&quot;忽略&quot;忽略本次更新.</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermExternalEditor</name>
+ <message>
+ <source>OK</source>
+ <translation>确认</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermFrame</name>
+ <message>
+ <source>Cascade</source>
+ <translation type="obsolete">层å </translation>
+ </message>
+ <message>
+ <source>FQTerm will keep running in the system tray.
+To terminate the program, choose exit in the tray menu.</source>
+ <translation>FQTermå·²ç»æœ€å°åŒ–至系统托盘.</translation>
+ </message>
+ <message>
+ <source>Tile</source>
+ <translation type="obsolete">平铺</translation>
+ </message>
+ <message>
+ <source>Main Window</source>
+ <translation>主窗å£</translation>
+ </message>
+ <message>
+ <source>Quick Login</source>
+ <translation>快速连接</translation>
+ </message>
+ <message>
+ <source>This will take effect after restart,
+please close all windows and restart.</source>
+ <translation type="obsolete">您的设置将在é‡æ–°å¯åŠ¨ç¨‹åºåŽç”Ÿæ•ˆ,
+请关闭所有窗å£åŽé‡å¯ç¨‹åº.</translation>
+ </message>
+ <message>
+ <source>Disconnect</source>
+ <translation type="obsolete">断开连接</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>文件(&amp;F)</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>编辑(&amp;E)</translation>
+ </message>
+ <message>
+ <source>Control sequence in clipboar&amp;d</source>
+ <translation>剪贴æ¿ä¸­çš„控制åºåˆ—(&amp;d)</translation>
+ </message>
+ <message>
+ <source>Clipboard &amp;encoding</source>
+ <translation type="obsolete">剪贴æ¿ç¼–ç (&amp;e)</translation>
+ </message>
+ <message>
+ <source>&amp;GBK</source>
+ <translation type="obsolete">&amp;GBK</translation>
+ </message>
+ <message>
+ <source>&amp;Big5</source>
+ <translation type="obsolete">&amp;Big5</translation>
+ </message>
+ <message>
+ <source>&amp;View</source>
+ <translation>视图(&amp;V)</translation>
+ </message>
+ <message>
+ <source>&amp;Font</source>
+ <translation>字体(&amp;F)</translation>
+ </message>
+ <message>
+ <source>&amp;Color</source>
+ <translation type="obsolete">颜色(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Language</source>
+ <translation>语言(&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;English</source>
+ <translation type="obsolete">&amp;English</translation>
+ </message>
+ <message>
+ <source>&amp;Simplified Chinese</source>
+ <translation type="obsolete">简体中文(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Traditional Chinese</source>
+ <translation type="obsolete">ç¹é«”中文(&amp;T)</translation>
+ </message>
+ <message>
+ <source>&amp;Themes</source>
+ <translation>主题(&amp;T)</translation>
+ </message>
+ <message>
+ <source>&amp;ScrollBar</source>
+ <translation>滚动æ¡(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Option</source>
+ <translation>选项(&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Special</source>
+ <translation>特殊(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Scrip&amp;t</source>
+ <translation>脚本(&amp;t)</translation>
+ </message>
+ <message>
+ <source>&amp;Windows</source>
+ <translation>窗å£(&amp;W)</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>帮助(&amp;H)</translation>
+ </message>
+ <message>
+ <source>Key Setup</source>
+ <translation>自定义按键组åˆ</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>显示</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>éšè—</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>关于</translation>
+ </message>
+ <message>
+ <source>Exit</source>
+ <translation>退出</translation>
+ </message>
+ <message>
+ <source>Sorry, image viewer is not supported currently.</source>
+ <translation type="obsolete">对ä¸èµ·,图åƒé¢„览器ä»å¤„于开å‘中.</translation>
+ </message>
+ <message>
+ <source>FQTerm&apos;s &amp;Homepage</source>
+ <translation type="obsolete">主页(&amp;H)</translation>
+ </message>
+ <message>
+ <source>FQTerm</source>
+ <translation>FQTerm</translation>
+ </message>
+ <message>
+ <source>Alt</source>
+ <translation>Alt</translation>
+ </message>
+ <message>
+ <source>Alt+Right</source>
+ <translation type="obsolete">Alt+Right</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Alt+Left</translation>
+ </message>
+ <message>
+ <source>Ctrl+Alt</source>
+ <translation>Ctrl+Alt</translation>
+ </message>
+ <message>
+ <source>F2</source>
+ <translation type="obsolete">F2</translation>
+ </message>
+ <message>
+ <source>F3</source>
+ <translation type="obsolete">F3</translation>
+ </message>
+ <message>
+ <source>Ctrl+Insert</source>
+ <translation type="obsolete">Ctrl+Insert</translation>
+ </message>
+ <message>
+ <source>Shift+Insert</source>
+ <translation type="obsolete">Shift+Insert</translation>
+ </message>
+ <message>
+ <source>F5</source>
+ <translation type="obsolete">F5</translation>
+ </message>
+ <message>
+ <source>F6</source>
+ <translation type="obsolete">F6</translation>
+ </message>
+ <message>
+ <source>F12</source>
+ <translation type="obsolete">F12</translation>
+ </message>
+ <message>
+ <source>F9</source>
+ <translation type="obsolete">F9</translation>
+ </message>
+ <message>
+ <source>F10</source>
+ <translation type="obsolete">F10</translation>
+ </message>
+ <message>
+ <source>F7</source>
+ <translation type="obsolete">F7</translation>
+ </message>
+ <message>
+ <source>F8</source>
+ <translation type="obsolete">F8</translation>
+ </message>
+ <message>
+ <source>F1</source>
+ <translation type="obsolete">F1</translation>
+ </message>
+ <message>
+ <source>Ctrl</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Ctrl+Meta</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Set Terminal Fonts</source>
+ <translation>设置终端字体</translation>
+ </message>
+ <message>
+ <source> Font</source>
+ <translation type="obsolete">字体</translation>
+ </message>
+ <message>
+ <source>Searc&amp;h Engine</source>
+ <translation>æœç´¢å¼•æ“Ž(&amp;h)</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermScreen</name>
+ <message>
+ <source>Shift+PageUp</source>
+ <translation>Shift+PageUp</translation>
+ </message>
+ <message>
+ <source>Shift+PageDown</source>
+ <translation>Shift+PageDown</translation>
+ </message>
+ <message>
+ <source>Shift+Up</source>
+ <translation>Shift+Up</translation>
+ </message>
+ <message>
+ <source>Shift+Down</source>
+ <translation>Shift+Down</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermScriptEngine</name>
+ <message>
+ <source>FQTerm</source>
+ <translation>FQTerm</translation>
+ </message>
+ <message>
+ <source>Unable to open the script file
+</source>
+ <translation>无法打开脚本文件</translation>
+ </message>
+ <message>
+ <source>uncaught exception at line </source>
+ <translation>未æ•èŽ·çš„异常,所在行数:</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermWindow</name>
+ <message>
+ <source>Not Connected</source>
+ <translation type="obsolete">未连接</translation>
+ </message>
+ <message>
+ <source>Preview image</source>
+ <translation>预览图片</translation>
+ </message>
+ <message>
+ <source>Save As...</source>
+ <translation>ä¿å­˜ä¸º...</translation>
+ </message>
+ <message>
+ <source>Open link</source>
+ <translation>打开链接</translation>
+ </message>
+ <message>
+ <source>Copy link address</source>
+ <translation>å¤åˆ¶é“¾æŽ¥åœ°å€</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>å¤åˆ¶</translation>
+ </message>
+ <message>
+ <source>Paste</source>
+ <translation>粘贴</translation>
+ </message>
+ <message>
+ <source>Copy Article</source>
+ <translation>全文下载</translation>
+ </message>
+ <message>
+ <source>Font</source>
+ <translation>字体</translation>
+ </message>
+ <message>
+ <source>Setting</source>
+ <translation>设置</translation>
+ </message>
+ <message>
+ <source>Color</source>
+ <translation>颜色</translation>
+ </message>
+ <message>
+ <source>Open URL</source>
+ <translation type="obsolete">打开URL</translation>
+ </message>
+ <message>
+ <source>resolving host name</source>
+ <translation type="obsolete">解æžä¸»æœºå称</translation>
+ </message>
+ <message>
+ <source>host found</source>
+ <translation type="obsolete">找到主机</translation>
+ </message>
+ <message>
+ <source>host not found</source>
+ <translation type="obsolete">主机未找到</translation>
+ </message>
+ <message>
+ <source>connecting...</source>
+ <translation type="obsolete">连接中...</translation>
+ </message>
+ <message>
+ <source>connected</source>
+ <translation type="obsolete">已连接</translation>
+ </message>
+ <message>
+ <source>connected to proxy</source>
+ <translation type="obsolete">已连接至代ç†</translation>
+ </message>
+ <message>
+ <source>proxy authentation</source>
+ <translation type="obsolete">代ç†æƒé™</translation>
+ </message>
+ <message>
+ <source>proxy failed</source>
+ <translation type="obsolete">代ç†å¤±è´¥</translation>
+ </message>
+ <message>
+ <source>connection refused</source>
+ <translation type="obsolete">连接被拒ç»</translation>
+ </message>
+ <message>
+ <source>error when reading from server</source>
+ <translation type="obsolete">读å–æœåŠ¡å™¨æ•°æ®å¤±è´¥</translation>
+ </message>
+ <message>
+ <source>connection closed</source>
+ <translation type="obsolete">连接已关闭</translation>
+ </message>
+ <message>
+ <source>connection close finished</source>
+ <translation type="obsolete">完æˆå…³é—­è¿žæŽ¥</translation>
+ </message>
+ <message>
+ <source>connect to host via proxy</source>
+ <translation type="obsolete">通过代ç†è¿žæŽ¥ä¸»æœº</translation>
+ </message>
+ <message>
+ <source>error in gethostbyname</source>
+ <translation type="obsolete">gethostbyname错误</translation>
+ </message>
+ <message>
+ <source>error in startup winsock</source>
+ <translation type="obsolete">winsockå¯åŠ¨é”™è¯¯</translation>
+ </message>
+ <message>
+ <source>error in connection</source>
+ <translation type="obsolete">连接错误</translation>
+ </message>
+ <message>
+ <source>error in proxy</source>
+ <translation type="obsolete">代ç†é”™è¯¯</translation>
+ </message>
+ <message>
+ <source>time out!</source>
+ <translation type="obsolete">超时!</translation>
+ </message>
+ <message>
+ <source>time out after trying %1 times</source>
+ <translation type="obsolete">超时,å·²é‡è¯•:%1次</translation>
+ </message>
+ <message>
+ <source>canceled by remote peer %1</source>
+ <translation type="obsolete">已被%1å–消</translation>
+ </message>
+ <message>
+ <source>unhandled header %1 at state %2</source>
+ <translation type="obsolete">未处ç†çš„头部%1,状æ€%2</translation>
+ </message>
+ <message>
+ <source>msg from remote peer: %1</source>
+ <translation type="obsolete">ä¿¡æ¯:%1</translation>
+ </message>
+ <message>
+ <source>data errors %1</source>
+ <translation type="obsolete">æ•°æ®é”™è¯¯%1</translation>
+ </message>
+ <message>
+ <source>falied to write file</source>
+ <translation type="obsolete">写文件失败</translation>
+ </message>
+ <message>
+ <source>skipping file %1</source>
+ <translation type="obsolete">跳过文件%1</translation>
+ </message>
+ <message>
+ <source>Ctrl+Insert</source>
+ <translation>Ctrl+Insert</translation>
+ </message>
+ <message>
+ <source>Shift+Insert</source>
+ <translation>Shift+Insert</translation>
+ </message>
+ <message>
+ <source>F9</source>
+ <translation type="obsolete">F9</translation>
+ </message>
+ <message>
+ <source>FQTerm</source>
+ <translation>FQTerm</translation>
+ </message>
+ <message>
+ <source>Connected,Do you still want to exit?</source>
+ <translation type="obsolete">已连接, 确认退出?</translation>
+ </message>
+ <message>
+ <source>UserCancel</source>
+ <translation type="obsolete">用户å–消</translation>
+ </message>
+ <message>
+ <source>Session error</source>
+ <translation>Session 错误</translation>
+ </message>
+ <message>
+ <source>Not connected</source>
+ <translation>未连接</translation>
+ </message>
+ <message>
+ <source>Ctrl+C</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Ctrl+V</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source> Font</source>
+ <translation>字体</translation>
+ </message>
+ <message>
+ <source>Still connected, do you really want to exit?</source>
+ <translation>已连接, 确认退出?</translation>
+ </message>
+ <message>
+ <source>Time out!</source>
+ <translation>超时!</translation>
+ </message>
+ <message>
+ <source>Time out after trying %1 times</source>
+ <translation>超时,å·²é‡è¯•:%1次</translation>
+ </message>
+ <message>
+ <source>Canceled by remote peer %1</source>
+ <translation>已被%1å–消</translation>
+ </message>
+ <message>
+ <source>Unhandled header %1 at state %2</source>
+ <translation>未处ç†çš„头部%1,状æ€%2</translation>
+ </message>
+ <message>
+ <source>Msg from remote peer: %1</source>
+ <translation>ä¿¡æ¯:%1</translation>
+ </message>
+ <message>
+ <source>Data errors %1</source>
+ <translation>æ•°æ®é”™è¯¯%1</translation>
+ </message>
+ <message>
+ <source>Falied to write file</source>
+ <translation>写文件失败</translation>
+ </message>
+ <message>
+ <source>Skipping file %1</source>
+ <translation>跳过文件%1</translation>
+ </message>
+ <message>
+ <source>Resolving host name</source>
+ <translation>解æžä¸»æœºå称</translation>
+ </message>
+ <message>
+ <source>Host found</source>
+ <translation>找到主机</translation>
+ </message>
+ <message>
+ <source>Host not found</source>
+ <translation>主机未找到</translation>
+ </message>
+ <message>
+ <source>Connecting...</source>
+ <translation>连接中...</translation>
+ </message>
+ <message>
+ <source>Connected</source>
+ <translation>已连接</translation>
+ </message>
+ <message>
+ <source>Connected to proxy</source>
+ <translation>已连接至代ç†</translation>
+ </message>
+ <message>
+ <source>Proxy authentation</source>
+ <translation>代ç†æƒé™</translation>
+ </message>
+ <message>
+ <source>Proxy failed</source>
+ <translation>代ç†å¤±è´¥</translation>
+ </message>
+ <message>
+ <source>Connection refused</source>
+ <translation>连接被拒ç»</translation>
+ </message>
+ <message>
+ <source>Error when reading from server</source>
+ <translation>读å–æœåŠ¡å™¨æ•°æ®å¤±è´¥</translation>
+ </message>
+ <message>
+ <source>Connection closed</source>
+ <translation>连接已关闭</translation>
+ </message>
+ <message>
+ <source>Connection close finished</source>
+ <translation>完æˆå…³é—­è¿žæŽ¥</translation>
+ </message>
+ <message>
+ <source>Connect to host via proxy</source>
+ <translation>通过代ç†è¿žæŽ¥ä¸»æœº</translation>
+ </message>
+ <message>
+ <source>Error in gethostbyname</source>
+ <translation>gethostbyname错误</translation>
+ </message>
+ <message>
+ <source>Error in startup winsock</source>
+ <translation>winsockå¯åŠ¨é”™è¯¯</translation>
+ </message>
+ <message>
+ <source>Error in connection</source>
+ <translation>连接错误</translation>
+ </message>
+ <message>
+ <source>Error in proxy</source>
+ <translation>代ç†é”™è¯¯</translation>
+ </message>
+ <message>
+ <source>User Cancel</source>
+ <translation>用户å–消</translation>
+ </message>
+ <message>
+ <source>URL Dialog</source>
+ <translation>打开URL</translation>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation>打开URL(&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>å–消(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Waiting header...</source>
+ <translation>获å–文件头...</translation>
+ </message>
+ <message>
+ <source>Open Selected As Url</source>
+ <translation>将选中文字作为URL打开</translation>
+ </message>
+ <message>
+ <source>Google Selected Text!</source>
+ <translation type="obsolete">Google选中文字!</translation>
+ </message>
+ <message>
+ <source>Font Selector</source>
+ <translation>字体选择</translation>
+ </message>
+ <message>
+ <source>IP database file does NOT exist</source>
+ <translation>IPæ•°æ®åº“文件ä¸å­˜åœ¨</translation>
+ </message>
+ <message>
+ <source>Invalid IP</source>
+ <translation>éžæ³•IP</translation>
+ </message>
+ <message>
+ <source>Share Selected Text and URL!</source>
+ <translation>分享选中文本åŠé“¾æŽ¥!</translation>
+ </message>
+ <message>
+ <source>Search Selected Text!</source>
+ <translation>æœç´¢é€‰ä¸­æ–‡æœ¬!</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermWndMgr</name>
+ <message>
+ <source>FQTerm</source>
+ <translation>FQTerm</translation>
+ </message>
+ <message>
+ <source>Still connected, do you really want to exit?</source>
+ <translation>已连接, 确认退出?</translation>
+ </message>
+</context>
+</TS>
diff --git a/res/dict/protocol_zh_CN.ts b/res/dict/protocol_zh_CN.ts
new file mode 100644
index 0000000..f205ada
--- /dev/null
+++ b/res/dict/protocol_zh_CN.ts
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>FQTerm::FQTermSSH1Channel</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_channel.cpp" line="88"/>
+ <source>Server refused pty allocation!</source>
+ <translation>æœåŠ¡å™¨æ‹’ç»pty分é…!</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSH1Kex</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_kex.cpp" line="72"/>
+ <source>Kex exchange failed!</source>
+ <translation>Kex交æ¢å¤±è´¥!</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_kex.cpp" line="91"/>
+ <source>startKex: First packet is not public key</source>
+ <translation>startKex: 第一个包éžå…¬é’¥</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSH1PacketReceiver</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh1_packet.cpp" line="95"/>
+ <source>parseData: The packet is too big</source>
+ <translation>解æžæ•°æ®: 包过大</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh1_packet.cpp" line="132"/>
+ <source>parseData: bad CRC32</source>
+ <translation>解æžæ•°æ®: bad CRC32</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSH1PasswdAuth</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="62"/>
+ <source>UserCancel</source>
+ <translation>用户å–消</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="85"/>
+ <source>Strange response from server</source>
+ <translation>未识别的æœåŠ¡å™¨å“应</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="93"/>
+ <source>User canceled</source>
+ <translation>用户å–消</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSH2Channel</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_channel.cpp" line="240"/>
+ <source>Server refuces to open a channel.</source>
+ <translation>æœåŠ¡å™¨æ‹’ç»å¼€å¯é€šé“.</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_channel.cpp" line="245"/>
+ <source>Server error when opening a channel.</source>
+ <translation>å¼€å¯é€šé“æ—¶æœåŠ¡é”™è¯¯.</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_channel.cpp" line="288"/>
+ <source>Server refused pty allocation!</source>
+ <translation>æœåŠ¡å™¨æ‹’ç»pty分é…!</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_channel.cpp" line="363"/>
+ <source>Channel closed by the server.</source>
+ <translation>æœåŠ¡å™¨å…³é—­é€šé“.</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_channel.cpp" line="424"/>
+ <source>Can&apos;t open a shell.</source>
+ <translation>无法开å¯shell.</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_channel.cpp" line="427"/>
+ <source>Unsupported packet.</source>
+ <translation>ä¸æ”¯æŒçš„包格å¼.</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSH2Kex</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh2_kex.cpp" line="120"/>
+ <source>Key exchange failed!</source>
+ <translation>Key交æ¢å¤±è´¥!</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh2_kex.cpp" line="139"/>
+ <source>startKex: First packet is not SSH_MSG_KEXINIT</source>
+ <translation>startKex: 第一个包éžSSH_MSG_KEXINIT</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh2_kex.cpp" line="210"/>
+ <source>Expect a SSH_MSG_KEXDH_REPLY packet</source>
+ <translation>期望得到SSH_MSG_KEXDH_REPLY</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh2_kex.cpp" line="298"/>
+ <source>Expect a SSH_MSG_NEWKEYS packet</source>
+ <translation>期望得到SSH_MSG_NEWKEYS</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSH2PacketReceiver</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh2_packet.cpp" line="188"/>
+ <source>parseData: packet too big</source>
+ <translation>解æžæ•°æ®: 包过大</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSH2PasswdAuth</name>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="166"/>
+ <source>Authentication failed!</source>
+ <translation>身份验è¯å¤±è´¥!</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="169"/>
+ <source>Unexpected packet</source>
+ <translation>未期望的包</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="177"/>
+ <source>Expect a SSH2_MSG_SERVICE_ACCEPT packet</source>
+ <translation>期望得到 SSH_2_MSG_SERVICE_ACCEPT</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="184"/>
+ <source>Error when sending username and password.</source>
+ <translation>å‘é€ç”¨æˆ·å密ç é”™è¯¯.</translation>
+ </message>
+ <message>
+ <location filename="../../src/protocol/internal/fqterm_ssh_auth.cpp" line="207"/>
+ <source>UserCancel</source>
+ <translation>用户å–消</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermSSHSocket</name>
+ <message>
+ <location filename="../../src/protocol/fqterm_ssh_socket.cpp" line="222"/>
+ <source>Unknown SSH version. Check if you set the right server and port.</source>
+ <translation>未知的SSH版本. 检查æœåŠ¡å™¨åŠç«¯å£è®¾ç½®.</translation>
+ </message>
+</context>
+</TS>
diff --git a/res/dict/ui_zh_CN.ts b/res/dict/ui_zh_CN.ts
new file mode 100644
index 0000000..d6ff29b
--- /dev/null
+++ b/res/dict/ui_zh_CN.ts
@@ -0,0 +1,1706 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>@default</name>
+ <message>
+ <source>No sound file</source>
+ <translation type="obsolete">未å‘现声音文件</translation>
+ </message>
+ <message>
+ <source>You have to select a file to test the sound</source>
+ <translation type="obsolete">必须选择一个声音文件</translation>
+ </message>
+ <message>
+ <source>&amp;Ok</source>
+ <translation type="obsolete">确定(&amp;O)</translation>
+ </message>
+ <message>
+ <source>No player</source>
+ <translation type="obsolete">未å‘现播放器</translation>
+ </message>
+ <message>
+ <source>You have to specify an external player</source>
+ <translation type="obsolete">必须指定一个外部播放器</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermCanvas</name>
+ <message>
+ <source>zoom 1:1</source>
+ <translation>缩放为 1:1</translation>
+ </message>
+ <message>
+ <source>fit window</source>
+ <translation type="obsolete">适应窗å£</translation>
+ </message>
+ <message>
+ <source>zoom in</source>
+ <translation>放大</translation>
+ </message>
+ <message>
+ <source>zoom out</source>
+ <translation>缩å°</translation>
+ </message>
+ <message>
+ <source>fullscreen</source>
+ <translation>å…¨å±</translation>
+ </message>
+ <message>
+ <source>rotate CW 90</source>
+ <translation>顺时针旋转90度</translation>
+ </message>
+ <message>
+ <source>rotate CCW 90</source>
+ <translation>逆时针旋转90度</translation>
+ </message>
+ <message>
+ <source>save as</source>
+ <translation>å¦å­˜ä¸º</translation>
+ </message>
+ <message>
+ <source>copy to</source>
+ <translation>å¤åˆ¶åˆ°</translation>
+ </message>
+ <message>
+ <source>silent copy</source>
+ <translation>ä¿å­˜</translation>
+ </message>
+ <message>
+ <source>delete</source>
+ <translation>删除</translation>
+ </message>
+ <message>
+ <source>exit</source>
+ <translation>退出</translation>
+ </message>
+ <message>
+ <source>Ctrl+Z</source>
+ <translation>Ctrl+Z</translation>
+ </message>
+ <message>
+ <source>adjust size</source>
+ <translation>调整尺寸</translation>
+ </message>
+ <message>
+ <source>Ctrl+X</source>
+ <translation>Ctrl+X</translation>
+ </message>
+ <message>
+ <source>Ctrl+=</source>
+ <translation>Ctrl+=</translation>
+ </message>
+ <message>
+ <source>Ctrl+-</source>
+ <translation>Ctrl+-</translation>
+ </message>
+ <message>
+ <source>Ctrl+F</source>
+ <translation>Ctrl+F</translation>
+ </message>
+ <message>
+ <source>Ctrl+]</source>
+ <translation>Ctrl+]</translation>
+ </message>
+ <message>
+ <source>Ctrl+[</source>
+ <translation>Ctrl+[</translation>
+ </message>
+ <message>
+ <source>Ctrl+S</source>
+ <translation>Ctrl+S</translation>
+ </message>
+ <message>
+ <source>Ctrl+C</source>
+ <translation>Ctrl+C</translation>
+ </message>
+ <message>
+ <source>Shift+S</source>
+ <translation>Shift+S</translation>
+ </message>
+ <message>
+ <source>Ctrl+D</source>
+ <translation>Ctrl+D</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Open Dir</source>
+ <translation>打开文件夹</translation>
+ </message>
+ <message>
+ <source>show Fit</source>
+ <translation>适åˆçª—å£</translation>
+ </message>
+ <message>
+ <source>show MaxFit</source>
+ <translation>适åˆçª—å£(拉伸)</translation>
+ </message>
+ <message>
+ <source>show Origin</source>
+ <translation>原始大å°</translation>
+ </message>
+ <message>
+ <source>show Stretch</source>
+ <translation>拉伸</translation>
+ </message>
+ <message>
+ <source>Adjust Mode</source>
+ <translation>调整模å¼</translation>
+ </message>
+ <message>
+ <source>No Preview Available</source>
+ <translation>没有预览</translation>
+ </message>
+ <message>
+ <source>Failed to save file</source>
+ <translation>ä¿å­˜æ–‡ä»¶å¤±è´¥</translation>
+ </message>
+ <message>
+ <source>Cant save file, maybe format not supported</source>
+ <translation>无法ä¿å­˜æ–‡ä»¶ï¼Œå¯èƒ½ä¸ºä¸æ”¯æŒçš„类型</translation>
+ </message>
+ <message>
+ <source>play gif</source>
+ <translation>播放gif</translation>
+ </message>
+ <message>
+ <source>Ctrl+/</source>
+ <translation>Ctrl+/</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermImage</name>
+ <message>
+ <source>Hide &amp;Browser</source>
+ <translation type="obsolete">éšè—æµè§ˆå™¨(&amp;B)</translation>
+ </message>
+ <message>
+ <source>Show &amp;Browser</source>
+ <translation type="obsolete">显示æµè§ˆå™¨(&amp;B)</translation>
+ </message>
+ <message>
+ <source>Hide &amp;List</source>
+ <translation type="obsolete">éšè—列表(&amp;L)</translation>
+ </message>
+ <message>
+ <source>Show &amp;List</source>
+ <translation type="obsolete">显示列表(&amp;L)</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermImageFlow</name>
+ <message>
+ <source>Close</source>
+ <translation>关闭</translation>
+ </message>
+ <message>
+ <source>Trash All</source>
+ <translation>全部删除</translation>
+ </message>
+ <message>
+ <source>Like </source>
+ <translation>Like </translation>
+ </message>
+ <message>
+ <source>New </source>
+ <translation>新建</translation>
+ </message>
+ <message>
+ <source>Trash </source>
+ <translation>Trash </translation>
+ </message>
+ <message>
+ <source>Recover </source>
+ <translation>æ¢å¤</translation>
+ </message>
+ <message>
+ <source>Title </source>
+ <translation>题目</translation>
+ </message>
+ <message>
+ <source>Save your likes under</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Recover</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>删除</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermImageOrigin</name>
+ <message>
+ <source>FQTerm Image Viewer</source>
+ <translation>FQTerm 图åƒæµè§ˆå™¨</translation>
+ </message>
+ <message>
+ <source>Sort by name</source>
+ <translation>æ ¹æ®æ–‡ä»¶å排åº</translation>
+ </message>
+ <message>
+ <source>Sort by time</source>
+ <translation>æ ¹æ®åˆ›å»ºæ—¶é—´æŽ’åº</translation>
+ </message>
+ <message>
+ <source>Sort by size</source>
+ <translation>æ ¹æ®æ–‡ä»¶å¤§å°æŽ’åº</translation>
+ </message>
+ <message>
+ <source>Sort by type</source>
+ <translation>æ ¹æ®æ–‡ä»¶ç±»åž‹æŽ’åº</translation>
+ </message>
+ <message>
+ <source>Previous</source>
+ <translation>上一个</translation>
+ </message>
+ <message>
+ <source>Next</source>
+ <translation>下一个</translation>
+ </message>
+ <message>
+ <source>Comment : </source>
+ <translation>评论:</translation>
+ </message>
+ <message>
+ <source>Model</source>
+ <translation>åž‹å·</translation>
+ </message>
+ <message>
+ <source>ExposureTime</source>
+ <translation>æ›å…‰æ—¶é—´</translation>
+ </message>
+ <message>
+ <source>FNumber</source>
+ <translation>F值</translation>
+ </message>
+ <message>
+ <source>ISO</source>
+ <translation>ISO</translation>
+ </message>
+ <message>
+ <source>FocalLength</source>
+ <translation>焦è·</translation>
+ </message>
+ <message>
+ <source>MeteringMode</source>
+ <translation>测è·æ¨¡å¼</translation>
+ </message>
+ <message>
+ <source>ExposureBias</source>
+ <translation>æ›å…‰è¡¥å¿</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::FQTermShortcutDialog</name>
+ <message>
+ <source>Shortcut Setting</source>
+ <translation>å¿«æ·é”®è®¾ç½®</translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation>æè¿°</translation>
+ </message>
+ <message>
+ <source>Shortcut</source>
+ <translation>å¿«æ·é”®</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>缺çœ</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>确定</translation>
+ </message>
+ <message>
+ <source>Apply</source>
+ <translation>应用</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+ <message>
+ <source>Reset All</source>
+ <translation>é‡ç½®</translation>
+ </message>
+ <message>
+ <source>Press key/combines on Shortcut column.
+Note Del is reserved for clear shortcut setting.</source>
+ <translation>在快æ·é”®åˆ—按相应的自定义快æ·é”®
+按Delå¯ä»¥åˆ é™¤å¿«æ·é”®.</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::ImageFlow</name>
+ <message>
+ <source>Tagged as </source>
+ <translation>Tagged as </translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::ImageViewerDirModel</name>
+ <message>
+ <source>Image Preview</source>
+ <translation>图åƒé¢„览</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::ProgressBar</name>
+ <message>
+ <source>Done</source>
+ <translation>完æˆ</translation>
+ </message>
+ <message>
+ <source>Aborted</source>
+ <translation>中断</translation>
+ </message>
+ <message>
+ <source>Aborting...</source>
+ <translation>正在中断...</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::StatusBar</name>
+ <message>
+ <source>Abort all background-operations</source>
+ <translation>å–消所有åŽå°æ“作</translation>
+ </message>
+ <message>
+ <source>Show progress detail</source>
+ <translation>细节</translation>
+ </message>
+ <message>
+ <source>Multiple background-tasks running</source>
+ <translation>多任务åŽå°è¿è¡Œä¸­</translation>
+ </message>
+ <message>
+ <source>Aborting all jobs...</source>
+ <translation>å–消所有任务...</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::addrDialog</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="obsolete">å–消</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation type="obsolete">确定</translation>
+ </message>
+ <message>
+ <source>Setting</source>
+ <translation type="obsolete">设置</translation>
+ </message>
+ <message>
+ <source>AddressBook</source>
+ <translation type="obsolete">地å€ç°¿</translation>
+ </message>
+ <message>
+ <source>Font Selector</source>
+ <translation>选择文字</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::quickDialog</name>
+ <message>
+ <source>Add To AddressBook</source>
+ <translation>加入地å€ç°¿</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::siteDialog</name>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>The site configuration has been changed.
+To save, press Yes.
+To discard, press No.
+To continue editing, press Cancel</source>
+ <translation>站点设置已改å˜.
+点击Yesä¿å­˜è®¾ç½®
+点击Noä¿ç•™åŽŸè®¾ç½®
+继续编辑,点击Cancel</translation>
+ </message>
+ <message>
+ <source>Are you sure to DELETE this site?</source>
+ <translation>确认删除�</translation>
+ </message>
+</context>
+<context>
+ <name>FQTerm::soundConf</name>
+ <message>
+ <source>No such output driver</source>
+ <translation type="obsolete">没有驱动</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation type="obsolete">确认(&amp;O)</translation>
+ </message>
+ <message>
+ <source>No sound file</source>
+ <translation>未å‘现声音文件</translation>
+ </message>
+ <message>
+ <source>You have to select a file to test the sound</source>
+ <translation>必须选择一个声音文件</translation>
+ </message>
+ <message>
+ <source>&amp;Ok</source>
+ <translation>确定(&amp;O)</translation>
+ </message>
+ <message>
+ <source>No player</source>
+ <translation>未å‘现播放器</translation>
+ </message>
+ <message>
+ <source>You have to specify an external player</source>
+ <translation>必须指定一个外部播放器</translation>
+ </message>
+</context>
+<context>
+ <name>FQTermImage</name>
+ <message>
+ <source>Form1</source>
+ <translation type="obsolete">窗体1</translation>
+ </message>
+ <message>
+ <source>&amp;Previous</source>
+ <translation type="obsolete">上一个(&amp;P)</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation type="obsolete">Alt+P</translation>
+ </message>
+ <message>
+ <source>&amp;Browser</source>
+ <translation type="obsolete">æµè§ˆå™¨(&amp;B)</translation>
+ </message>
+ <message>
+ <source>Alt+B</source>
+ <translation type="obsolete">Alt+B</translation>
+ </message>
+ <message>
+ <source>&amp;Next</source>
+ <translation type="obsolete">下一个(&amp;N)</translation>
+ </message>
+ <message>
+ <source>Alt+N</source>
+ <translation type="obsolete">Alt+N</translation>
+ </message>
+ <message>
+ <source>ImageViewer</source>
+ <translation type="obsolete">图åƒé¢„览器</translation>
+ </message>
+ <message>
+ <source>&amp;List</source>
+ <translation type="obsolete">列表(&amp;L)</translation>
+ </message>
+</context>
+<context>
+ <name>IPLookupDialog</name>
+ <message>
+ <source>IP Lookup</source>
+ <translation>查询IP</translation>
+ </message>
+ <message>
+ <source>IP Address</source>
+ <translation>IP地å€</translation>
+ </message>
+ <message>
+ <source>Physical Address</source>
+ <translation>实际地å€</translation>
+ </message>
+ <message>
+ <source>Lookup</source>
+ <translation>查询</translation>
+ </message>
+ <message>
+ <source>Finished</source>
+ <translation>完æˆ</translation>
+ </message>
+ <message>
+ <source>IP database file does NOT exist</source>
+ <translation>IPæ•°æ®åº“文件ä¸å­˜åœ¨</translation>
+ </message>
+ <message>
+ <source>Invalid IP</source>
+ <translation>éžæ³•IP</translation>
+ </message>
+</context>
+<context>
+ <name>SSHLogin</name>
+ <message>
+ <source>Login</source>
+ <translation>登录</translation>
+ </message>
+ <message>
+ <source>Please enter your username and password</source>
+ <translation>请输入你的用户å和密ç </translation>
+ </message>
+ <message>
+ <source>UserName:</source>
+ <translation>用户å:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>密ç :</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>确认</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+</context>
+<context>
+ <name>aboutDialog</name>
+ <message>
+ <source>About FQTerm</source>
+ <translation>关于</translation>
+ </message>
+ <message>
+ <source>FQTerm 0.5.0 (QT 4.1 based)</source>
+ <translation type="obsolete">FQTerm (基于QT4.1)</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>关于</translation>
+ </message>
+ <message>
+ <source>FQTerm 2007</source>
+ <translation type="obsolete">FQTerm 2007</translation>
+ </message>
+ <message>
+ <source>Authors</source>
+ <translation>作者</translation>
+ </message>
+ <message>
+ <source>Credits</source>
+ <translation>致谢</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>关闭</translation>
+ </message>
+ <message>
+ <source>FQTerm</source>
+ <translation>FQTerm</translation>
+ </message>
+ <message>
+ <source>FQTerm
+
+http://code.google.com/p/fqterm</source>
+ <translation type="obsolete">FQTerm
+
+http://code.google.com/p/fqterm</translation>
+ </message>
+ <message>
+ <source>fqterm@gmail.com
+
+devilphoenix@newsmth</source>
+ <translation>fqterm@gmail.com
+
+devilphoenix@newsmth</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;SimSun&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="obsolete">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;SimSun&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;FQTerm&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://code.google.com/p/fqterm&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://code.google.com/p/fqterm&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;FQTerm&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://code.google.com/p/fqterm&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://code.google.com/p/fqterm&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;SimSun&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;SimSun&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>addrDialog</name>
+ <message>
+ <source>AddressBook</source>
+ <translation type="obsolete">地å€ç°¿</translation>
+ </message>
+ <message>
+ <source>Apply</source>
+ <translation type="obsolete">应用</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="obsolete">添加</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="obsolete">关闭</translation>
+ </message>
+ <message>
+ <source>Connect</source>
+ <translation type="obsolete">连接</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation type="obsolete">删除</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>通用属性</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>地å€</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>类型</translation>
+ </message>
+ <message>
+ <source>Auto Login</source>
+ <translation type="obsolete">自动登录</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>å称</translation>
+ </message>
+ <message>
+ <source>BBS</source>
+ <translation>BBS</translation>
+ </message>
+ <message>
+ <source>*NIX</source>
+ <translation>*NIX</translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation>端å£</translation>
+ </message>
+ <message>
+ <source>Prelogin</source>
+ <translation>登录å‰</translation>
+ </message>
+ <message>
+ <source>User</source>
+ <translation>用户å</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>密ç </translation>
+ </message>
+ <message>
+ <source>Postlogin</source>
+ <translation>登录åŽ</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>显示</translation>
+ </message>
+ <message>
+ <source>ANSI Color</source>
+ <translation>ANSI 颜色</translation>
+ </message>
+ <message>
+ <source>Always Hightlight</source>
+ <translation>总是高亮</translation>
+ </message>
+ <message>
+ <source>Auto Select Font Size When Resize Window</source>
+ <translation type="obsolete">窗体å˜åŒ–时自动调整字体大å°</translation>
+ </message>
+ <message>
+ <source>BBS Encoding</source>
+ <translation>BBS ç¼–ç </translation>
+ </message>
+ <message>
+ <source>GBK</source>
+ <translation>GBK</translation>
+ </message>
+ <message>
+ <source>BIG5</source>
+ <translation>BIG5</translation>
+ </message>
+ <message>
+ <source>Display Code</source>
+ <translation type="obsolete">显示编ç </translation>
+ </message>
+ <message>
+ <source>Font</source>
+ <translation>字体</translation>
+ </message>
+ <message>
+ <source>Text Color</source>
+ <translation>文字颜色</translation>
+ </message>
+ <message>
+ <source>Background</source>
+ <translation>背景</translation>
+ </message>
+ <message>
+ <source>Schema</source>
+ <translation type="obsolete">图表</translation>
+ </message>
+ <message>
+ <source>TextLabel3</source>
+ <translation>文本标签3</translation>
+ </message>
+ <message>
+ <source>Terminal</source>
+ <translation>终端</translation>
+ </message>
+ <message>
+ <source>Columns</source>
+ <translation>列</translation>
+ </message>
+ <message>
+ <source>Term Type</source>
+ <translation>终端类型</translation>
+ </message>
+ <message>
+ <source>Cursor Type</source>
+ <translation>光标类型</translation>
+ </message>
+ <message>
+ <source>Rows</source>
+ <translation>行</translation>
+ </message>
+ <message>
+ <source>Block</source>
+ <translation>å—状</translation>
+ </message>
+ <message>
+ <source>Underline</source>
+ <translation>下划线</translation>
+ </message>
+ <message>
+ <source>I Type</source>
+ <translation>Iå½¢</translation>
+ </message>
+ <message>
+ <source>Scroll Lines</source>
+ <translation>滚动</translation>
+ </message>
+ <message>
+ <source>Escape string (i.e. *[ )</source>
+ <translation>ESC字符串(如*[)</translation>
+ </message>
+ <message>
+ <source>Key Type</source>
+ <translation>按键类型</translation>
+ </message>
+ <message>
+ <source>VT100</source>
+ <translation>VT100</translation>
+ </message>
+ <message>
+ <source>XTERM</source>
+ <translation>XTERM</translation>
+ </message>
+ <message>
+ <source>Connection</source>
+ <translation type="obsolete">连接</translation>
+ </message>
+ <message>
+ <source>Protocol</source>
+ <translation>åè®®</translation>
+ </message>
+ <message>
+ <source>Telnet</source>
+ <translation>Telnet</translation>
+ </message>
+ <message>
+ <source>SSH1</source>
+ <translation>SSH1</translation>
+ </message>
+ <message>
+ <source>SSH2</source>
+ <translation>SSH2</translation>
+ </message>
+ <message>
+ <source>Proxy</source>
+ <translation>代ç†</translation>
+ </message>
+ <message>
+ <source>Authentation</source>
+ <translation>认è¯</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>æ— </translation>
+ </message>
+ <message>
+ <source>Wingate</source>
+ <translation>Wingate</translation>
+ </message>
+ <message>
+ <source>SOCKS4</source>
+ <translation>SOCKS4</translation>
+ </message>
+ <message>
+ <source>SOCKS5</source>
+ <translation>SOCKS5</translation>
+ </message>
+ <message>
+ <source>HTTP</source>
+ <translation>HTTP</translation>
+ </message>
+ <message>
+ <source>Misc</source>
+ <translation>其它</translation>
+ </message>
+ <message>
+ <source>Load Control Script</source>
+ <translation>装载控制脚本</translation>
+ </message>
+ <message>
+ <source>When disconnected, close window automatically</source>
+ <translation>当连接断开时,自动关闭窗å£</translation>
+ </message>
+ <message>
+ <source>Autoreply Message</source>
+ <translation>自动回å¤æ¶ˆæ¯</translation>
+ </message>
+ <message>
+ <source>Max Idle Time</source>
+ <translation>最大å‘呆时间</translation>
+ </message>
+ <message>
+ <source>Anti-idle String</source>
+ <translation>防å‘呆字符串</translation>
+ </message>
+ <message>
+ <source>For Maximum</source>
+ <translation>最大</translation>
+ </message>
+ <message>
+ <source>Times (-1 means infinite)</source>
+ <translation>次数(-1为无穷)</translation>
+ </message>
+ <message>
+ <source>When disconnected, reconnect every</source>
+ <translation>自动é‡è¿žé—´éš”</translation>
+ </message>
+ <message>
+ <source>Browse...</source>
+ <translation>æµè§ˆ...</translation>
+ </message>
+ <message>
+ <source>Key to reply message</source>
+ <translation>回å¤æ¶ˆæ¯æŒ‰é”®</translation>
+ </message>
+ <message>
+ <source>s</source>
+ <translation>s</translation>
+ </message>
+ <message>
+ <source>Mouse</source>
+ <translation>é¼ æ ‡</translation>
+ </message>
+ <message>
+ <source>Menu Type</source>
+ <translation>èœå•ç±»åž‹</translation>
+ </message>
+ <message>
+ <source>Menu Label</source>
+ <translation type="obsolete">èœå•æ ‡ç­¾</translation>
+ </message>
+ <message>
+ <source>Reverse</source>
+ <translation>å转</translation>
+ </message>
+ <message>
+ <source>Color...</source>
+ <translation>颜色...</translation>
+ </message>
+ <message>
+ <source>Custom Color</source>
+ <translation>自定义颜色</translation>
+ </message>
+ <message>
+ <source>Site Setting</source>
+ <translation>站点设置</translation>
+ </message>
+ <message>
+ <source>Telnet Auto Login</source>
+ <translation>Telnet自动登录</translation>
+ </message>
+ <message>
+ <source>SSH Auto Login</source>
+ <translation>SSH自动登录</translation>
+ </message>
+ <message>
+ <source>Menu Color</source>
+ <translation>èœå•é¢œè‰²</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation type="obsolete">确认(&amp;O)</translation>
+ </message>
+ <message>
+ <source>Apply (&amp;Temporarily)</source>
+ <translation>应用 (临时&amp;T)</translation>
+ </message>
+ <message>
+ <source>&amp;Apply (Save)</source>
+ <translation>应用 (ä¿å­˜&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>å–消(&amp;C)</translation>
+ </message>
+ <message>
+ <source>UTF8</source>
+ <translation>UTF8</translation>
+ </message>
+ <message>
+ <source>Font ratio</source>
+ <translation type="obsolete">中英文比例</translation>
+ </message>
+ <message>
+ <source>Adjust Font Size When Resize</source>
+ <translation type="obsolete">自动调节字体</translation>
+ </message>
+ <message>
+ <source>Char W/H ratio</source>
+ <translation type="obsolete">字符高宽比(å½±å“é—´è·)</translation>
+ </message>
+ <message>
+ <source>Keyboard</source>
+ <translation>键盘</translation>
+ </message>
+ <message>
+ <source>BackSpace Setting</source>
+ <translation>退格键设定</translation>
+ </message>
+ <message>
+ <source>Send backspace as ^H</source>
+ <translation>退格键为^H</translation>
+ </message>
+ <message>
+ <source>Send backspace as ^? (127)</source>
+ <translation>退格键为^?(127)</translation>
+ </message>
+ <message>
+ <source>Anti-idle</source>
+ <translation>防å‘呆</translation>
+ </message>
+ <message>
+ <source>Enable Zmodem</source>
+ <translation>使用Zmodem</translation>
+ </message>
+ <message>
+ <source>Enable Buzz</source>
+ <translation>使用振动</translation>
+ </message>
+ <message>
+ <source>Enable Beep</source>
+ <translation>使用蜂鸣</translation>
+ </message>
+ <message>
+ <source>Enable Mouse Support</source>
+ <translation>打开鼠标支æŒ</translation>
+ </message>
+ <message>
+ <source>Align Mode</source>
+ <translation>对é½æ¨¡å¼</translation>
+ </message>
+ <message>
+ <source>Line Spacing</source>
+ <translation>行间è·</translation>
+ </message>
+ <message>
+ <source>Char Spacing</source>
+ <translation>å­—é—´è·</translation>
+ </message>
+ <message>
+ <source>Align Mid</source>
+ <translation>中线对é½</translation>
+ </message>
+ <message>
+ <source>Align Bottom</source>
+ <translation>底部对é½</translation>
+ </message>
+ <message>
+ <source>Align Top</source>
+ <translation>顶端对é½</translation>
+ </message>
+ <message>
+ <source>BIG5-HKSCS</source>
+ <translation>BIG5-HKSCS</translation>
+ </message>
+ <message>
+ <source>BIG5-UAO</source>
+ <translation>BIG5-UAO</translation>
+ </message>
+ <message>
+ <source>Keep Font; Adjust Row/Column.</source>
+ <translation>ä¿æŒå­—体大å°,调整行列.</translation>
+ </message>
+ <message>
+ <source>Keep Row/Column; Adjust Font.</source>
+ <translation>ä¿æŒè¡Œåˆ—,调整字体大å°.</translation>
+ </message>
+ <message>
+ <source>Keep Font; Keep Row/Column.</source>
+ <translation>ä¿æŒå­—体大å°åŠè¡Œåˆ—.</translation>
+ </message>
+</context>
+<context>
+ <name>articleDialog</name>
+ <message>
+ <source>Article Viewer</source>
+ <translation>文章æµè§ˆå™¨</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>关闭</translation>
+ </message>
+ <message>
+ <source>Select All</source>
+ <translation>全选</translation>
+ </message>
+ <message>
+ <source>Save...</source>
+ <translation>ä¿å­˜...</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation>å¤åˆ¶</translation>
+ </message>
+</context>
+<context>
+ <name>dlgDefineEscape</name>
+ <message>
+ <source>Define Escape</source>
+ <translation>定义逃逸</translation>
+ </message>
+ <message>
+ <source>Escape String *[</source>
+ <translation>逃逸串 *[</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>确定</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+</context>
+<context>
+ <name>keyDialog</name>
+ <message>
+ <source>Key Setup</source>
+ <translation>按键设置</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>添加</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>删除</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>æ›´æ–°</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>关闭</translation>
+ </message>
+ <message>
+ <source>Define</source>
+ <translation>定义</translation>
+ </message>
+ <message>
+ <source>Script</source>
+ <translation>脚本</translation>
+ </message>
+ <message>
+ <source>Program</source>
+ <translation>程åº</translation>
+ </message>
+ <message>
+ <source>Enter</source>
+ <translation>回车</translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation>æ–¹å‘é”®[å³]</translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation>æ–¹å‘é”®[å·¦]</translation>
+ </message>
+ <message>
+ <source>Down</source>
+ <translation>æ–¹å‘é”®[下]</translation>
+ </message>
+ <message>
+ <source>General Keys</source>
+ <translation>通用按键</translation>
+ </message>
+ <message>
+ <source>Up</source>
+ <translation>æ–¹å‘é”®[上]</translation>
+ </message>
+ <message>
+ <source>Browse...</source>
+ <translation>æµè§ˆ...</translation>
+ </message>
+ <message>
+ <source>Key</source>
+ <translation>按键</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>å称</translation>
+ </message>
+ <message>
+ <source>Short Cut</source>
+ <translation>å¿«æ·é”®</translation>
+ </message>
+</context>
+<context>
+ <name>msgDialog</name>
+ <message>
+ <source>Messages Viewer</source>
+ <translation>消æ¯æŸ¥çœ‹å™¨</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>确认</translation>
+ </message>
+</context>
+<context>
+ <name>prefDialog</name>
+ <message>
+ <source>Preference</source>
+ <translation>å好</translation>
+ </message>
+ <message>
+ <source>Alternative Mouse Wheel Control</source>
+ <translation>其它滚动控制</translation>
+ </message>
+ <message>
+ <source>Save Message To File</source>
+ <translation>将消æ¯å‚¨å­˜è‡³æ–‡ä»¶</translation>
+ </message>
+ <message>
+ <source>Warn When Exit Connected</source>
+ <translation>当连接时试图退出则å‘出警告</translation>
+ </message>
+ <message>
+ <source>Detect URL When Mouse Move</source>
+ <translation>鼠标移动时检测URL</translation>
+ </message>
+ <message>
+ <source>Blink Tab When Receive Message</source>
+ <translation>收到消æ¯æ—¶é—ªçƒ</translation>
+ </message>
+ <message>
+ <source>Paste word-wrap at</source>
+ <translation type="obsolete">自动回行粘贴</translation>
+ </message>
+ <message>
+ <source>Sound When Receive Messages</source>
+ <translation>收到消æ¯æ—¶å‘声</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>æ— </translation>
+ </message>
+ <message>
+ <source>Beep</source>
+ <translation>蜂鸣</translation>
+ </message>
+ <message>
+ <source>Sound File</source>
+ <translation>声音文件</translation>
+ </message>
+ <message>
+ <source>Configure</source>
+ <translation>设置</translation>
+ </message>
+ <message>
+ <source>Enable Smart Word-Wrap</source>
+ <translation>智能自动回行</translation>
+ </message>
+ <message>
+ <source>Clear ZModem and HTTP directory when exit</source>
+ <translation type="obsolete">退出时清ç†ZModemå’ŒHTTP目录</translation>
+ </message>
+ <message>
+ <source>Show as tray when close</source>
+ <translation type="obsolete">关闭至系统托盘</translation>
+ </message>
+ <message>
+ <source>Zmodem directory</source>
+ <translation type="obsolete">Zmodem目录</translation>
+ </message>
+ <message>
+ <source>HTTP directory</source>
+ <translation type="obsolete">HTTP目录</translation>
+ </message>
+ <message>
+ <source>HTTP Browser</source>
+ <translation>HTTPæµè§ˆå™¨</translation>
+ </message>
+ <message>
+ <source>Image Viewer</source>
+ <translation>图åƒé¢„览器</translation>
+ </message>
+ <message>
+ <source>Browse</source>
+ <translation>æµè§ˆ</translation>
+ </message>
+ <message>
+ <source>Choose</source>
+ <translation>选择</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>确定</translation>
+ </message>
+ <message>
+ <source>Input Method</source>
+ <translation>输入法</translation>
+ </message>
+ <message>
+ <source>GBK</source>
+ <translation>GBK</translation>
+ </message>
+ <message>
+ <source>BIG5</source>
+ <translation>BIG5</translation>
+ </message>
+ <message>
+ <source>Paste Word-Wrap At</source>
+ <translation>自动回行粘贴</translation>
+ </message>
+ <message>
+ <source>Show As Tray When Close</source>
+ <translation>关闭至系统托盘</translation>
+ </message>
+ <message>
+ <source>Clear ZModem And HTTP Directory When Exit</source>
+ <translation>退出时清ç†ZModemå’ŒHTTP目录</translation>
+ </message>
+ <message>
+ <source>Zmodem Directory</source>
+ <translation>Zmodem目录</translation>
+ </message>
+ <message>
+ <source>HTTP Directory</source>
+ <translation>HTTP目录</translation>
+ </message>
+ <message>
+ <source>StyleSheet File</source>
+ <translation>StyleSheet文件</translation>
+ </message>
+ <message>
+ <source>Reply when ENQ received</source>
+ <translation>收到ENQ时回å¤</translation>
+ </message>
+ <message>
+ <source>Display Offset</source>
+ <translation>显示(横å‘)å移é‡</translation>
+ </message>
+ <message>
+ <source>Editor &amp; Args</source>
+ <translation>编辑器åŠè¿è¡Œå‚æ•°</translation>
+ </message>
+ <message>
+ <source>AntiAlias</source>
+ <translation>å别å</translation>
+ </message>
+ <message>
+ <source>Vertical Display</source>
+ <translation>垂直显示</translation>
+ </message>
+ <message>
+ <source>Top</source>
+ <translation>居顶</translation>
+ </message>
+ <message>
+ <source>Middle</source>
+ <translation>居中</translation>
+ </message>
+ <message>
+ <source>Bottom</source>
+ <translation>居底</translation>
+ </message>
+ <message>
+ <source>ASCII Art Enhance Mode</source>
+ <translation>ASCII色å—æ— ç¼æ¨¡å¼</translation>
+ </message>
+</context>
+<context>
+ <name>quickDialog</name>
+ <message>
+ <source>Quick Login</source>
+ <translation>快速连接</translation>
+ </message>
+ <message>
+ <source>History</source>
+ <translation type="obsolete">历å²</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation type="obsolete">地å€</translation>
+ </message>
+ <message>
+ <source>Connect</source>
+ <translation>连接</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>关闭</translation>
+ </message>
+ <message>
+ <source>Advanced</source>
+ <translation>高级</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>删除</translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation>端å£</translation>
+ </message>
+ <message>
+ <source>Protocol</source>
+ <translation>åè®®</translation>
+ </message>
+ <message>
+ <source>Telnet</source>
+ <translation>Telnet</translation>
+ </message>
+ <message>
+ <source>SSH1</source>
+ <translation>SSH1</translation>
+ </message>
+ <message>
+ <source>SSH2</source>
+ <translation>SSH2</translation>
+ </message>
+ <message>
+ <source>Host Name</source>
+ <translation>主机å</translation>
+ </message>
+ <message>
+ <source>23</source>
+ <translation>23</translation>
+ </message>
+</context>
+<context>
+ <name>schemaDialog</name>
+ <message>
+ <source>Schema Editor</source>
+ <translation>图标编辑器</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>标题</translation>
+ </message>
+ <message>
+ <source>8-15</source>
+ <translation>8-15</translation>
+ </message>
+ <message>
+ <source>0-7</source>
+ <translation>0-7</translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation>ä¿å­˜</translation>
+ </message>
+ <message>
+ <source>Remove </source>
+ <translation>移除</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>确定</translation>
+ </message>
+ <message>
+ <source>Background</source>
+ <translation>背景</translation>
+ </message>
+ <message>
+ <source>Fade to</source>
+ <translation type="obsolete">æ·¡å…¥</translation>
+ </message>
+ <message>
+ <source>Min</source>
+ <translation>最å°</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>æ— </translation>
+ </message>
+ <message>
+ <source>Choose</source>
+ <translation>选择</translation>
+ </message>
+ <message>
+ <source>Max</source>
+ <translation>最大</translation>
+ </message>
+ <message>
+ <source>Tile</source>
+ <translation>平铺</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation>中心</translation>
+ </message>
+ <message>
+ <source>Scale</source>
+ <translation>比例</translation>
+ </message>
+ <message>
+ <source>Image</source>
+ <translation>图åƒ</translation>
+ </message>
+ <message>
+ <source>Transparent</source>
+ <translation type="obsolete">é€æ˜Ž</translation>
+ </message>
+ <message>
+ <source>Render</source>
+ <translation>渲染</translation>
+ </message>
+ <message>
+ <source>Coverage</source>
+ <translation>覆盖范围</translation>
+ </message>
+ <message>
+ <source>Whole</source>
+ <translation>整体</translation>
+ </message>
+ <message>
+ <source>Padding</source>
+ <translation>平直</translation>
+ </message>
+ <message>
+ <source>Note:
+ Alpha will only apply on background
+ If Coverage is set to Padding
+ Alpha will take no effect
+</source>
+ <translation>请注æ„:
+ Alpha仅应用于背景色
+ 若“覆盖范围â€è¢«è®¾ç½®ä¸ºâ€œå¹³ç›´â€
+ Alphaå°†ä¸ä¼šç”Ÿæ•ˆ
+</translation>
+ </message>
+ <message>
+ <source>Alpha</source>
+ <translation>åŠé€æ˜Ž</translation>
+ </message>
+</context>
+<context>
+ <name>siteManager</name>
+ <message>
+ <source>Address Book</source>
+ <translation>地å€ç°¿</translation>
+ </message>
+ <message>
+ <source>&amp;Up</source>
+ <translation>上移(&amp;U)</translation>
+ </message>
+ <message>
+ <source>&amp;Down</source>
+ <translation>下移(&amp;D)</translation>
+ </message>
+ <message>
+ <source>Site Name</source>
+ <translation>站点å称</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>地å€</translation>
+ </message>
+ <message>
+ <source>Protocol</source>
+ <translation>åè®®</translation>
+ </message>
+ <message>
+ <source>Telnet</source>
+ <translation>Telnet</translation>
+ </message>
+ <message>
+ <source>SSH1</source>
+ <translation>SSH1</translation>
+ </message>
+ <message>
+ <source>SSH2</source>
+ <translation>SSH2</translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation>端å£</translation>
+ </message>
+ <message>
+ <source>Host Type</source>
+ <translation>主机类型</translation>
+ </message>
+ <message>
+ <source>BBS</source>
+ <translation>BBS</translation>
+ </message>
+ <message>
+ <source>*NIX</source>
+ <translation>*NIX</translation>
+ </message>
+ <message>
+ <source>Use Proxy</source>
+ <translation>使用代ç†</translation>
+ </message>
+ <message>
+ <source>Setting...</source>
+ <translation>设置...</translation>
+ </message>
+ <message>
+ <source>Auto Login</source>
+ <translation>自动登录</translation>
+ </message>
+ <message>
+ <source>Font Preview</source>
+ <translation>字体预览</translation>
+ </message>
+ <message>
+ <source>Font Previewer</source>
+ <translation>字体预览</translation>
+ </message>
+ <message>
+ <source>&amp;Reset</source>
+ <translation>é‡ç½®(&amp;R)</translation>
+ </message>
+ <message>
+ <source>A&amp;dvance</source>
+ <translation>高级(&amp;d)</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>新建(&amp;N)</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>删除(&amp;D)</translation>
+ </message>
+ <message>
+ <source>C&amp;onnect</source>
+ <translation>连接(&amp;o)</translation>
+ </message>
+ <message>
+ <source>&amp;Apply</source>
+ <translation type="obsolete">应用(&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Close</source>
+ <translation>关闭(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Save</source>
+ <translation>ä¿å­˜(&amp;S)</translation>
+ </message>
+</context>
+<context>
+ <name>soundConf</name>
+ <message>
+ <source>Configure</source>
+ <translation>设置</translation>
+ </message>
+ <message>
+ <source>Sound File:</source>
+ <translation>声音文件:</translation>
+ </message>
+ <message>
+ <source>Select...</source>
+ <translation>选择...</translation>
+ </message>
+ <message>
+ <source>External Program:</source>
+ <translation>外部程åº:</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>确认</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+ <message>
+ <source>Play With:</source>
+ <translation>使用播放器:</translation>
+ </message>
+ <message>
+ <source>Test</source>
+ <translation>测试</translation>
+ </message>
+ <message>
+ <source>External</source>
+ <translation>外部</translation>
+ </message>
+ <message>
+ <source>Internal</source>
+ <translation>内部</translation>
+ </message>
+</context>
+<context>
+ <name>zmodemDialog</name>
+ <message>
+ <source>Zmodem Status</source>
+ <translation>Zmodem状æ€</translation>
+ </message>
+ <message>
+ <source>textLabel1</source>
+ <translation>文本标签1</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>å–消</translation>
+ </message>
+ <message>
+ <source>textLabel2</source>
+ <translation>文本标签2</translation>
+ </message>
+</context>
+</TS>
diff --git a/res/fqterm.desktop b/res/fqterm.desktop
new file mode 100644
index 0000000..0ffad86
--- /dev/null
+++ b/res/fqterm.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Type=Application
+Categories=Application;Qt;Network;
+Icon=/usr/local/share/FQTerm/pic/fqterm_256x256.png
+Name=FQTerm
+Exec=fqterm -caption "%c" %i %u
+GenericName=BBS Client
+GenericName[zh_CN]=BBS 客户端程åº
+GenericName[zh_TW]=BBS 客戶端程å¼
+Comment=BBS client based on Qt library in linux
+Terminal=false
diff --git a/res/fqterm.icns b/res/fqterm.icns
new file mode 100644
index 0000000..e2dc1fe
--- /dev/null
+++ b/res/fqterm.icns
Binary files differ
diff --git a/res/fqterm.sh b/res/fqterm.sh
new file mode 100644
index 0000000..d9e1d2c
--- /dev/null
+++ b/res/fqterm.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+this_name="$0"
+
+current_directory=`/bin/pwd`
+
+cd `dirname "$this_name"`
+base_name=`basename "$this_name"`
+bin_directory=`/bin/pwd`
+
+# get the real file name in case it's a symbolic link.
+while [ -h "$this_name" ]; do
+ this_name=`/bin/ls -l "$base_name" | sed -e 's/^.* -> //' `
+ cd `dirname "$this_name"`
+ base_name=`basename "$this_name"`
+ bin_directory=`/bin/pwd`
+done
+
+# setup environment variables and then run the real executable.
+if [ -x "$base_name".bin ]; then
+ cd "$current_directory"
+ export FQTERM_PREFIX=`dirname "$bin_directory"`
+ export FQTERM_RESOURCE="$FQTERM_PREFIX/share/FQTerm"
+ "$bin_directory/$base_name.bin" "$@"
+ exit $?
+else
+ cd "$current_directory"
+ echo "Error, cannot find $base_name."
+ exit 2
+fi
diff --git a/res/pic/ViewerButtons/adjustsize.png b/res/pic/ViewerButtons/adjustsize.png
new file mode 100644
index 0000000..c4d884c
--- /dev/null
+++ b/res/pic/ViewerButtons/adjustsize.png
Binary files differ
diff --git a/res/pic/ViewerButtons/button-cancel.png b/res/pic/ViewerButtons/button-cancel.png
new file mode 100644
index 0000000..7566a10
--- /dev/null
+++ b/res/pic/ViewerButtons/button-cancel.png
Binary files differ
diff --git a/res/pic/ViewerButtons/button-delete.png b/res/pic/ViewerButtons/button-delete.png
new file mode 100644
index 0000000..3ce2c12
--- /dev/null
+++ b/res/pic/ViewerButtons/button-delete.png
Binary files differ
diff --git a/res/pic/ViewerButtons/button-recover.png b/res/pic/ViewerButtons/button-recover.png
new file mode 100644
index 0000000..753e94a
--- /dev/null
+++ b/res/pic/ViewerButtons/button-recover.png
Binary files differ
diff --git a/res/pic/ViewerButtons/clear-state-gray.png b/res/pic/ViewerButtons/clear-state-gray.png
new file mode 100644
index 0000000..ec13fed
--- /dev/null
+++ b/res/pic/ViewerButtons/clear-state-gray.png
Binary files differ
diff --git a/res/pic/ViewerButtons/clear-state.png b/res/pic/ViewerButtons/clear-state.png
new file mode 100644
index 0000000..6854f0d
--- /dev/null
+++ b/res/pic/ViewerButtons/clear-state.png
Binary files differ
diff --git a/res/pic/ViewerButtons/document-save-as.png b/res/pic/ViewerButtons/document-save-as.png
new file mode 100644
index 0000000..97bad5d
--- /dev/null
+++ b/res/pic/ViewerButtons/document-save-as.png
Binary files differ
diff --git a/res/pic/ViewerButtons/edit-clear.png b/res/pic/ViewerButtons/edit-clear.png
new file mode 100644
index 0000000..7345c44
--- /dev/null
+++ b/res/pic/ViewerButtons/edit-clear.png
Binary files differ
diff --git a/res/pic/ViewerButtons/edit-delete.png b/res/pic/ViewerButtons/edit-delete.png
new file mode 100644
index 0000000..ff5b897
--- /dev/null
+++ b/res/pic/ViewerButtons/edit-delete.png
Binary files differ
diff --git a/res/pic/ViewerButtons/edit-shuffle.png b/res/pic/ViewerButtons/edit-shuffle.png
new file mode 100644
index 0000000..885fa48
--- /dev/null
+++ b/res/pic/ViewerButtons/edit-shuffle.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-info.png b/res/pic/ViewerButtons/emblem-info.png
new file mode 100644
index 0000000..d46bd4e
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-info.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-like-16x16.png b/res/pic/ViewerButtons/emblem-like-16x16.png
new file mode 100644
index 0000000..c1dee22
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-like-16x16.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-like-gray.png b/res/pic/ViewerButtons/emblem-like-gray.png
new file mode 100644
index 0000000..c398b59
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-like-gray.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-like.png b/res/pic/ViewerButtons/emblem-like.png
new file mode 100644
index 0000000..5bfa49c
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-like.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-new-16x16.png b/res/pic/ViewerButtons/emblem-new-16x16.png
new file mode 100644
index 0000000..34af64f
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-new-16x16.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-new-gray.png b/res/pic/ViewerButtons/emblem-new-gray.png
new file mode 100644
index 0000000..6439530
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-new-gray.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-new.png b/res/pic/ViewerButtons/emblem-new.png
new file mode 100644
index 0000000..0ac11c7
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-new.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-recover-16x16.png b/res/pic/ViewerButtons/emblem-recover-16x16.png
new file mode 100644
index 0000000..bc52bb8
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-recover-16x16.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-recover-gray.png b/res/pic/ViewerButtons/emblem-recover-gray.png
new file mode 100644
index 0000000..e9a4eb0
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-recover-gray.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-recover.png b/res/pic/ViewerButtons/emblem-recover.png
new file mode 100644
index 0000000..70070cb
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-recover.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-title-16x16.png b/res/pic/ViewerButtons/emblem-title-16x16.png
new file mode 100644
index 0000000..d40626b
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-title-16x16.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-title.png b/res/pic/ViewerButtons/emblem-title.png
new file mode 100644
index 0000000..f187cd8
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-title.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-trash-16x16.png b/res/pic/ViewerButtons/emblem-trash-16x16.png
new file mode 100644
index 0000000..a07a57d
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-trash-16x16.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-trash-gray.png b/res/pic/ViewerButtons/emblem-trash-gray.png
new file mode 100644
index 0000000..baf8e93
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-trash-gray.png
Binary files differ
diff --git a/res/pic/ViewerButtons/emblem-trash.png b/res/pic/ViewerButtons/emblem-trash.png
new file mode 100644
index 0000000..4d2e963
--- /dev/null
+++ b/res/pic/ViewerButtons/emblem-trash.png
Binary files differ
diff --git a/res/pic/ViewerButtons/next.png b/res/pic/ViewerButtons/next.png
new file mode 100644
index 0000000..a585cab
--- /dev/null
+++ b/res/pic/ViewerButtons/next.png
Binary files differ
diff --git a/res/pic/ViewerButtons/object-rotate-left.png b/res/pic/ViewerButtons/object-rotate-left.png
new file mode 100644
index 0000000..29aa9ab
--- /dev/null
+++ b/res/pic/ViewerButtons/object-rotate-left.png
Binary files differ
diff --git a/res/pic/ViewerButtons/object-rotate-right.png b/res/pic/ViewerButtons/object-rotate-right.png
new file mode 100644
index 0000000..dea855a
--- /dev/null
+++ b/res/pic/ViewerButtons/object-rotate-right.png
Binary files differ
diff --git a/res/pic/ViewerButtons/open.png b/res/pic/ViewerButtons/open.png
new file mode 100644
index 0000000..45fa288
--- /dev/null
+++ b/res/pic/ViewerButtons/open.png
Binary files differ
diff --git a/res/pic/ViewerButtons/play_gif.png b/res/pic/ViewerButtons/play_gif.png
new file mode 100644
index 0000000..70daa33
--- /dev/null
+++ b/res/pic/ViewerButtons/play_gif.png
Binary files differ
diff --git a/res/pic/ViewerButtons/prev.png b/res/pic/ViewerButtons/prev.png
new file mode 100644
index 0000000..612fb34
--- /dev/null
+++ b/res/pic/ViewerButtons/prev.png
Binary files differ
diff --git a/res/pic/ViewerButtons/previous.png b/res/pic/ViewerButtons/previous.png
new file mode 100644
index 0000000..c2295b5
--- /dev/null
+++ b/res/pic/ViewerButtons/previous.png
Binary files differ
diff --git a/res/pic/ViewerButtons/save-state-gray.png b/res/pic/ViewerButtons/save-state-gray.png
new file mode 100644
index 0000000..6567093
--- /dev/null
+++ b/res/pic/ViewerButtons/save-state-gray.png
Binary files differ
diff --git a/res/pic/ViewerButtons/save-state.png b/res/pic/ViewerButtons/save-state.png
new file mode 100644
index 0000000..1feb0dd
--- /dev/null
+++ b/res/pic/ViewerButtons/save-state.png
Binary files differ
diff --git a/res/pic/ViewerButtons/trash-empty.png b/res/pic/ViewerButtons/trash-empty.png
new file mode 100644
index 0000000..264114c
--- /dev/null
+++ b/res/pic/ViewerButtons/trash-empty.png
Binary files differ
diff --git a/res/pic/ViewerButtons/trash-full.png b/res/pic/ViewerButtons/trash-full.png
new file mode 100644
index 0000000..ae18f5f
--- /dev/null
+++ b/res/pic/ViewerButtons/trash-full.png
Binary files differ
diff --git a/res/pic/ViewerButtons/trash-state-gray.png b/res/pic/ViewerButtons/trash-state-gray.png
new file mode 100644
index 0000000..137483d
--- /dev/null
+++ b/res/pic/ViewerButtons/trash-state-gray.png
Binary files differ
diff --git a/res/pic/ViewerButtons/trash-state.png b/res/pic/ViewerButtons/trash-state.png
new file mode 100644
index 0000000..57d3437
--- /dev/null
+++ b/res/pic/ViewerButtons/trash-state.png
Binary files differ
diff --git a/res/pic/ViewerButtons/view-fullscreen.png b/res/pic/ViewerButtons/view-fullscreen.png
new file mode 100644
index 0000000..6845e04
--- /dev/null
+++ b/res/pic/ViewerButtons/view-fullscreen.png
Binary files differ
diff --git a/res/pic/ViewerButtons/window-close.png b/res/pic/ViewerButtons/window-close.png
new file mode 100644
index 0000000..bf8104f
--- /dev/null
+++ b/res/pic/ViewerButtons/window-close.png
Binary files differ
diff --git a/res/pic/ViewerButtons/zoom-fit-best.png b/res/pic/ViewerButtons/zoom-fit-best.png
new file mode 100644
index 0000000..02de8c9
--- /dev/null
+++ b/res/pic/ViewerButtons/zoom-fit-best.png
Binary files differ
diff --git a/res/pic/ViewerButtons/zoom-in.png b/res/pic/ViewerButtons/zoom-in.png
new file mode 100644
index 0000000..54937bd
--- /dev/null
+++ b/res/pic/ViewerButtons/zoom-in.png
Binary files differ
diff --git a/res/pic/ViewerButtons/zoom-original.png b/res/pic/ViewerButtons/zoom-original.png
new file mode 100644
index 0000000..3b79370
--- /dev/null
+++ b/res/pic/ViewerButtons/zoom-original.png
Binary files differ
diff --git a/res/pic/ViewerButtons/zoom-out.png b/res/pic/ViewerButtons/zoom-out.png
new file mode 100644
index 0000000..7543ac4
--- /dev/null
+++ b/res/pic/ViewerButtons/zoom-out.png
Binary files differ
diff --git a/res/pic/ViewerButtons/zoomin.png b/res/pic/ViewerButtons/zoomin.png
new file mode 100644
index 0000000..d46f5af
--- /dev/null
+++ b/res/pic/ViewerButtons/zoomin.png
Binary files differ
diff --git a/res/pic/ViewerButtons/zoomout.png b/res/pic/ViewerButtons/zoomout.png
new file mode 100644
index 0000000..4632656
--- /dev/null
+++ b/res/pic/ViewerButtons/zoomout.png
Binary files differ
diff --git a/res/pic/address_book.png b/res/pic/address_book.png
new file mode 100644
index 0000000..34aac8a
--- /dev/null
+++ b/res/pic/address_book.png
Binary files differ
diff --git a/res/pic/ansi_color.png b/res/pic/ansi_color.png
new file mode 100644
index 0000000..18cbe59
--- /dev/null
+++ b/res/pic/ansi_color.png
Binary files differ
diff --git a/res/pic/anti_idle.png b/res/pic/anti_idle.png
new file mode 100644
index 0000000..a2ed8af
--- /dev/null
+++ b/res/pic/anti_idle.png
Binary files differ
diff --git a/res/pic/auto_reconnect.png b/res/pic/auto_reconnect.png
new file mode 100644
index 0000000..7f73973
--- /dev/null
+++ b/res/pic/auto_reconnect.png
Binary files differ
diff --git a/res/pic/auto_reply.png b/res/pic/auto_reply.png
new file mode 100644
index 0000000..f9c6f24
--- /dev/null
+++ b/res/pic/auto_reply.png
Binary files differ
diff --git a/res/pic/beep.png b/res/pic/beep.png
new file mode 100644
index 0000000..15faf6a
--- /dev/null
+++ b/res/pic/beep.png
Binary files differ
diff --git a/res/pic/change_fonts.png b/res/pic/change_fonts.png
new file mode 100644
index 0000000..c360d0b
--- /dev/null
+++ b/res/pic/change_fonts.png
Binary files differ
diff --git a/res/pic/connect.png b/res/pic/connect.png
new file mode 100644
index 0000000..5fefb93
--- /dev/null
+++ b/res/pic/connect.png
Binary files differ
diff --git a/res/pic/copy.png b/res/pic/copy.png
new file mode 100644
index 0000000..951b521
--- /dev/null
+++ b/res/pic/copy.png
Binary files differ
diff --git a/res/pic/copy_with_color.png b/res/pic/copy_with_color.png
new file mode 100644
index 0000000..52ac2cd
--- /dev/null
+++ b/res/pic/copy_with_color.png
Binary files differ
diff --git a/res/pic/disconnect.png b/res/pic/disconnect.png
new file mode 100644
index 0000000..b8d6085
--- /dev/null
+++ b/res/pic/disconnect.png
Binary files differ
diff --git a/res/pic/english_font.png b/res/pic/english_font.png
new file mode 100644
index 0000000..5553c63
--- /dev/null
+++ b/res/pic/english_font.png
Binary files differ
diff --git a/res/pic/fqterm.png b/res/pic/fqterm.png
new file mode 100644
index 0000000..aab3dfc
--- /dev/null
+++ b/res/pic/fqterm.png
Binary files differ
diff --git a/res/pic/fqterm_128x128.ico b/res/pic/fqterm_128x128.ico
new file mode 100644
index 0000000..3f25061
--- /dev/null
+++ b/res/pic/fqterm_128x128.ico
Binary files differ
diff --git a/res/pic/fqterm_128x128.png b/res/pic/fqterm_128x128.png
new file mode 100644
index 0000000..6e3d7be
--- /dev/null
+++ b/res/pic/fqterm_128x128.png
Binary files differ
diff --git a/res/pic/fqterm_16x16.ico b/res/pic/fqterm_16x16.ico
new file mode 100644
index 0000000..b0a5900
--- /dev/null
+++ b/res/pic/fqterm_16x16.ico
Binary files differ
diff --git a/res/pic/fqterm_16x16.png b/res/pic/fqterm_16x16.png
new file mode 100644
index 0000000..c30e17c
--- /dev/null
+++ b/res/pic/fqterm_16x16.png
Binary files differ
diff --git a/res/pic/fqterm_256x256.ico b/res/pic/fqterm_256x256.ico
new file mode 100644
index 0000000..ec1cbac
--- /dev/null
+++ b/res/pic/fqterm_256x256.ico
Binary files differ
diff --git a/res/pic/fqterm_256x256.png b/res/pic/fqterm_256x256.png
new file mode 100644
index 0000000..2d637b9
--- /dev/null
+++ b/res/pic/fqterm_256x256.png
Binary files differ
diff --git a/res/pic/fqterm_32x32.ico b/res/pic/fqterm_32x32.ico
new file mode 100644
index 0000000..7c8a251
--- /dev/null
+++ b/res/pic/fqterm_32x32.ico
Binary files differ
diff --git a/res/pic/fqterm_32x32.png b/res/pic/fqterm_32x32.png
new file mode 100644
index 0000000..7512cda
--- /dev/null
+++ b/res/pic/fqterm_32x32.png
Binary files differ
diff --git a/res/pic/fqterm_48x48.ico b/res/pic/fqterm_48x48.ico
new file mode 100644
index 0000000..b092999
--- /dev/null
+++ b/res/pic/fqterm_48x48.ico
Binary files differ
diff --git a/res/pic/fqterm_48x48.png b/res/pic/fqterm_48x48.png
new file mode 100644
index 0000000..aab3dfc
--- /dev/null
+++ b/res/pic/fqterm_48x48.png
Binary files differ
diff --git a/res/pic/fqterm_64x64.ico b/res/pic/fqterm_64x64.ico
new file mode 100644
index 0000000..64c9904
--- /dev/null
+++ b/res/pic/fqterm_64x64.ico
Binary files differ
diff --git a/res/pic/fqterm_64x64.png b/res/pic/fqterm_64x64.png
new file mode 100644
index 0000000..4d90164
--- /dev/null
+++ b/res/pic/fqterm_64x64.png
Binary files differ
diff --git a/res/pic/fqterm_tray.png b/res/pic/fqterm_tray.png
new file mode 100644
index 0000000..c30e17c
--- /dev/null
+++ b/res/pic/fqterm_tray.png
Binary files differ
diff --git a/res/pic/get_article_fulltext.png b/res/pic/get_article_fulltext.png
new file mode 100644
index 0000000..8e299a4
--- /dev/null
+++ b/res/pic/get_article_fulltext.png
Binary files differ
diff --git a/res/pic/image_viewer.png b/res/pic/image_viewer.png
new file mode 100644
index 0000000..32eb2ca
--- /dev/null
+++ b/res/pic/image_viewer.png
Binary files differ
diff --git a/res/pic/messagebox_critical.png b/res/pic/messagebox_critical.png
new file mode 100644
index 0000000..da1e944
--- /dev/null
+++ b/res/pic/messagebox_critical.png
Binary files differ
diff --git a/res/pic/messagebox_info.png b/res/pic/messagebox_info.png
new file mode 100644
index 0000000..eb37d9a
--- /dev/null
+++ b/res/pic/messagebox_info.png
Binary files differ
diff --git a/res/pic/messagebox_warning.png b/res/pic/messagebox_warning.png
new file mode 100644
index 0000000..82d3fc7
--- /dev/null
+++ b/res/pic/messagebox_warning.png
Binary files differ
diff --git a/res/pic/mouse.png b/res/pic/mouse.png
new file mode 100644
index 0000000..91ae19a
--- /dev/null
+++ b/res/pic/mouse.png
Binary files differ
diff --git a/res/pic/other_font.png b/res/pic/other_font.png
new file mode 100644
index 0000000..60edbfb
--- /dev/null
+++ b/res/pic/other_font.png
Binary files differ
diff --git a/res/pic/paste.png b/res/pic/paste.png
new file mode 100644
index 0000000..e84e2b7
--- /dev/null
+++ b/res/pic/paste.png
Binary files differ
diff --git a/res/pic/popwidget.png b/res/pic/popwidget.png
new file mode 100644
index 0000000..b44002c
--- /dev/null
+++ b/res/pic/popwidget.png
Binary files differ
diff --git a/res/pic/preferences.png b/res/pic/preferences.png
new file mode 100644
index 0000000..78115ee
--- /dev/null
+++ b/res/pic/preferences.png
Binary files differ
diff --git a/res/pic/quick_login.png b/res/pic/quick_login.png
new file mode 100644
index 0000000..8a4bed6
--- /dev/null
+++ b/res/pic/quick_login.png
Binary files differ
diff --git a/res/pic/rectangle_selection.png b/res/pic/rectangle_selection.png
new file mode 100644
index 0000000..5356741
--- /dev/null
+++ b/res/pic/rectangle_selection.png
Binary files differ
diff --git a/res/pic/refresh.png b/res/pic/refresh.png
new file mode 100644
index 0000000..f4a4873
--- /dev/null
+++ b/res/pic/refresh.png
Binary files differ
diff --git a/res/pic/save_setting.png b/res/pic/save_setting.png
new file mode 100644
index 0000000..46eac82
--- /dev/null
+++ b/res/pic/save_setting.png
Binary files differ
diff --git a/res/pic/setup_shortcuts.png b/res/pic/setup_shortcuts.png
new file mode 100644
index 0000000..b1b86f8
--- /dev/null
+++ b/res/pic/setup_shortcuts.png
Binary files differ
diff --git a/res/pic/shadow.png b/res/pic/shadow.png
new file mode 100644
index 0000000..b54f504
--- /dev/null
+++ b/res/pic/shadow.png
Binary files differ
diff --git a/res/pic/tabpad.png b/res/pic/tabpad.png
new file mode 100644
index 0000000..071acd8
--- /dev/null
+++ b/res/pic/tabpad.png
Binary files differ
diff --git a/res/pic/toggle_ansi_color.png b/res/pic/toggle_ansi_color.png
new file mode 100644
index 0000000..af3cbfa
--- /dev/null
+++ b/res/pic/toggle_ansi_color.png
Binary files differ
diff --git a/res/pic/view_messages.png b/res/pic/view_messages.png
new file mode 100644
index 0000000..588e5c8
--- /dev/null
+++ b/res/pic/view_messages.png
Binary files differ
diff --git a/res/schema/Linux.schema b/res/schema/Linux.schema
new file mode 100644
index 0000000..f338197
--- /dev/null
+++ b/res/schema/Linux.schema
@@ -0,0 +1,27 @@
+[schema]
+title=Linux
+
+[image]
+name=
+type=0
+fade=#000000
+alpha=0
+
+[color]
+color0=#000000
+color1=#b21818
+color2=#18b218
+color3=#b26818
+color4=#1818b2
+color5=#b218b2
+color6=#18b2b2
+color7=#b2b2b2
+color8=#686868
+color9=#ff5454
+color10=#54ff54
+color11=#ffff54
+color12=#5454ff
+color13=#ff54ff
+color14=#54ffff
+color15=#f9f9f9
+
diff --git a/res/schema/Softness.schema b/res/schema/Softness.schema
new file mode 100644
index 0000000..ef33972
--- /dev/null
+++ b/res/schema/Softness.schema
@@ -0,0 +1,27 @@
+[schema]
+title=Softness
+
+[image]
+name=
+type=0
+fade=#000000
+alpha=0.0
+
+[color]
+color0=#141414
+color1=#783c3c
+color2=#3c783c
+color3=#78783c
+color4=#3c3c78
+color5=#783c3c
+color6=#3c7878
+color7=#c0c0c0
+color8=#808080
+color9=#c86464
+color10=#64c864
+color11=#c8c864
+color12=#6464c8
+color13=#c864c8
+color14=#64c8c8
+color15=#e5e5e5
+
diff --git a/res/schema/VIM.schema b/res/schema/VIM.schema
new file mode 100644
index 0000000..ed4e3fa
--- /dev/null
+++ b/res/schema/VIM.schema
@@ -0,0 +1,27 @@
+[schema]
+title=VIM
+
+[image]
+name=
+type=0
+fade=#000000
+alpha=0
+
+[color]
+color0=#000000
+color1=#c00000
+color2=#008000
+color3=#808000
+color4=#0000c0
+color5=#c000c0
+color6=#008080
+color7=#c0c0c0
+color8=#808080
+color9=#ff6060
+color10=#00ff00
+color11=#ffff00
+color12=#8080ff
+color13=#ff40ff
+color14=#00ffff
+color15=#ffffff
+
diff --git a/res/schema/XTerm.schema b/res/schema/XTerm.schema
new file mode 100644
index 0000000..0c0a191
--- /dev/null
+++ b/res/schema/XTerm.schema
@@ -0,0 +1,27 @@
+[schema]
+title=XTerm
+
+[image]
+name=
+type=0
+fade=#000000
+alpha=0
+
+[color]
+color0=#000000
+color1=#cd0000
+color2=#00cd00
+color3=#cdcd00
+color4=#0000cd
+color5=#cd00cd
+color6=#00cdcd
+color7=#e5e5e5
+color8=#4d4d4d
+color9=#ff0000
+color10=#00ff00
+color11=#ffff00
+color12=#0000ff
+color13=#ff00ff
+color14=#00ffff
+color15=#ffffff
+
diff --git a/res/schema/default.schema b/res/schema/default.schema
new file mode 100644
index 0000000..a5a120e
--- /dev/null
+++ b/res/schema/default.schema
@@ -0,0 +1,27 @@
+[schema]
+title=default
+
+[image]
+name=
+type=0
+fade=#000000
+alpha=0
+
+[color]
+color0=#000000
+color1=#800000
+color2=#008000
+color3=#808000
+color4=#000080
+color5=#800080
+color6=#008080
+color7=#808080
+color8=#a0a0a4
+color9=#ff0000
+color10=#00ff00
+color11=#ffff00
+color12=#0000ff
+color13=#ff00ff
+color14=#00ffff
+color15=#ffffff
+
diff --git a/res/script/README b/res/script/README
new file mode 100644
index 0000000..c7dacbc
--- /dev/null
+++ b/res/script/README
@@ -0,0 +1,112 @@
+
+I've contacted one of the authors of CTerm, and got his permisson to use these scripts with FQTerm.
+Other scripts were directly drawn from qterm0.4.1.
+
+Any file to be written to or read from should be in the format of UTF-8.
+
+Usage:
+
+sessionID=long(sys.argv[0])
+
+formatError(sessionID)
+get the traceback info
+return string
+
+getArticle(sessionID, interval)
+copy current article
+return (string, success)
+
+
+copyArticle(sessionID)
+copy current article (obsolete)
+return string
+
+getText(sessionID, line)
+get text at line
+return string
+
+
+getAttrText(sessionID, line)
+get attr text at line
+return string
+
+sendString(sessionID, str)
+send string to server
+return number of bytes written
+
+
+sendParsedString(sessionID, str)
+send string with escape
+return number of bytes written
+
+caretX(sessionID)
+caret x
+return int
+
+caretY(sessionID)
+caret y
+return int
+
+
+columns(sessionID)
+screen width
+return int
+
+
+rows(sessionID)
+screen height
+return int
+
+
+isConnected(sessionID)
+connected to server or not
+return int
+
+disconnect(sessionID)
+disconnect from server
+
+
+reconnect(sessionID)
+reconnect
+
+
+getBBSCodec(sessionID)
+get the bbs encoding, GBK or Big5
+return string
+
+getAddress(sessionID)
+get the bbs address
+return string
+
+getPort(sessionID)
+get the bbs port number
+return int
+
+getProtocol(sessionID)
+get the bbs protocol, 0/1/2 TELNET/SSH1/SSH2
+return int
+
+getReplyKey(sessionID)
+get the key to reply messages
+return string (wtf...?)
+
+
+getURL(sessionID)
+get the url string under mouse (not sure if works)
+return string
+
+
+previewImage(sessionID, url)
+preview the image link
+
+
+fromUTF8(str, codec)
+decode from utf8 to string in specified codec
+return string
+
+
+toUTF8(str, codec)
+decode from string in specified codec to utf8
+return string
+
+
diff --git a/res/script/buildindex.js b/res/script/buildindex.js
new file mode 100644
index 0000000..d5235d4
--- /dev/null
+++ b/res/script/buildindex.js
@@ -0,0 +1,132 @@
+fqterm.import("utils.js");
+//NOTE: 1. this file should be in utf8
+//first enter the folder, then start script.
+var timeout = 2000;
+var path = "c:\\fix-elite\\"; //DO NOT miss last slash
+var base_path = path;
+
+var make_html_header = function(num)
+{
+ num = parseInt(num);
+ var result = '<html><head>\n'+
+ '<meta http-equiv="Content-Language" content="zh-cn">\n'+
+ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n'+
+ '<title>FQTerm Article Downloader</title>\n'+
+ '</head>\n'+
+ '<body>\n'+
+ '<p><b><h1>FQTerm Article Downloader</h1></b></p>\n'+
+ '<p><p align=center><a href=' + (num - 1) + '.html>Prevoius</a>\n'+
+ '<a href=index.html>Index</a>\n'+
+ '<a href=' + (num + 1) + '.html>Next</a></p align=center></p>'+
+ '<hr><p></p>\n';
+ return result;
+}
+
+var make_html_ender = function(num)
+{
+ num = parseInt(num);
+ var result = '<hr><p></p>\n'+
+ '<p><p align=center><a href=' + (num - 1) + '.html>Prevoius</a>\n'+
+ '<a href=index.html>Index</a>\n'+
+ '<a href=' + (num + 1) + '.html>Next</a></p align=center></p>\n'+
+ '<p><b>FQTerm --- BBS client based on Qt library</b><p>\n'+
+ '<p><a href=http://code.google.com/p/fqterm>\n'+
+ 'http://code.google.com/p/fqterm</a><p>\n'+
+ '</body>\n'+
+ '</html>\n';
+ return result;
+}
+
+var make_index_header = function() {
+ var result = '<html><head>\n' +
+ '<meta http-equiv="Content-Language" content="zh-cn">\n' +
+ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n' +
+ '<title>FQTerm Article Downloader</title>\n' +
+ '</head>\n' +
+ '<p><b><h1>FQTerm Article Downloader</h1></b></p>\n' +
+ '<p><p align=center>\n' +
+ '<a href=\"../index.html\">Up</a>\n' +
+ '</p align=center</p>\n' +
+ '<hr><p></p>\n\n';
+ return result;
+}
+
+var make_index_ender = function() {
+ var result = '<hr><p></p>\n' +
+ '<p><p align=center>\n' +
+ '<a href=\"../index.html\">Up</a>\n' +
+ '</p align=center</p>\n' +
+ '<p><b>FQTerm --- BBS client based on Qt library</b><p>\n' +
+ '<p><a href=http://code.google.com/p/fqterm>\n' +
+ 'http://code.google.com/p/fqterm</a><p>\n' +
+ '</body>\n' +
+ '</html>\n';
+ return result;
+}
+
+var get_list_num = function(str_line) {
+ // get the number
+ try{
+ var re = /[0-9]+/;
+ var num = re.exec(str_line);
+ return num[0];
+ } catch(err) {
+ return "";
+ }
+}
+
+var get_list_categary = function(str_line) {
+ try{
+ var re = /\[[^0-9]{2}\]/; //utf8!
+ var cat = re.exec(str_line);
+ return cat[0];
+ } catch(err) {
+ return "";
+ }
+}
+
+var get_list_title = function(str_line) {
+ try{
+ var re = /\[[^0-9]{2}\]/; //utf8!
+ var cat = re.exec(str_line);
+ var i = str_line.search(re);
+ return str_line.substr(i + cat[0].length);
+ } catch(err) {
+ return "";
+ }
+}
+
+
+var build_index = function() {
+ fqterm.makePath(path);
+ var h = make_index_header();
+ fqterm.writeFile(path + 'index.html', h);
+ while (true) {
+ var line = fqterm.caretY();
+ var str_line = fqterm.getText(line);
+ var article_num = get_list_num(str_line);
+ var article_category = get_list_categary(str_line);
+ var article_title = get_list_title(str_line);
+ if (article_category == '[文件]') {
+ var a = '<p><a href=' + article_num + '.html>[文件] ' + article_title + '</a></p>\n';
+ fqterm.appendFile(path + "index.html", a);
+ } else if (article_category == '[目录]') {
+ var a = '<p><a href=' + article_num + '/index.html>[目录] ' + article_title + '</a></p>\n';
+ fqterm.appendFile(path + "index.html", a);
+ } else {
+ break;
+ }
+ fqterm.sendString('j');
+ sleep(timeout);
+ var str_next = fqterm.getText(fqterm.caretY());
+ article_num_next = get_list_num(str_next);
+ if (article_num_next == "" || parseInt(article_num_next) <= parseInt(article_num)) {
+ break;
+ }
+ }
+ var e = make_index_ender();
+ fqterm.appendFile(path + 'index.html', e);
+ fqterm.sendString('q');
+}
+
+build_index();
diff --git a/res/script/continuous.py b/res/script/continuous.py
new file mode 100644
index 0000000..4240f3a
--- /dev/null
+++ b/res/script/continuous.py
@@ -0,0 +1,19 @@
+# This is demo script to continuousely download 4 articles
+import fqterm
+import sys, time
+
+# f=open("/home/dp2/test.txt","w")
+f = open("c:\\test.txt", "w")
+
+lp=long(sys.argv[0])
+
+for i in range(4):
+ fqterm.sendString(lp,"r")
+ time.sleep(1)
+ f.write(fqterm.getArticle(lp, 100)[0])
+ time.sleep(1)
+ fqterm.sendString(lp,"q")
+ time.sleep(1)
+ fqterm.sendString(lp,"j")
+ time.sleep(1)
+f.close()
diff --git a/res/script/download.js b/res/script/download.js
new file mode 100644
index 0000000..1a27fa4
--- /dev/null
+++ b/res/script/download.js
@@ -0,0 +1,19 @@
+fqterm.import("utils.js");
+
+var n = 4;
+var timeout = 1000;
+var filename = "c:\\test.txt";
+fqterm.writeFile(filename, "")
+
+while(n--)
+{
+ fqterm.sendString("r");
+ sleep(timeout);
+ var article = fqterm.copyArticle();
+ fqterm.appendFile(filename, article)
+ fqterm.sendString("q");
+ sleep(timeout);
+ fqterm.sendString("j");
+ sleep(timeout);
+}
+
diff --git a/res/script/download.py b/res/script/download.py
new file mode 100644
index 0000000..d274cc5
--- /dev/null
+++ b/res/script/download.py
@@ -0,0 +1,253 @@
+# coding=UTF-8
+"""
+download the directory
+
+ 13/09/04 kingson
+ * add this changelog
+
+Notes:
+ 1. make sure the path is empty, otherwise mkdir complain and stoped
+ 2. the time for sleep() varies dependent on sites
+ 3. tested for FireBird BBS only
+Bugs:
+ 1.
+TODO:
+ 1. add some GUI for control, e.g. stop, pause, resume, inside script
+ 2. make it robust
+"""
+
+import fqterm
+import sys,os,string,time,re
+
+# the pointer to fqtermWindow object
+lp=long(sys.argv[0])
+
+wait_time = 2.0
+
+def txt2html(txt):
+ txt=string.replace(txt,"\n","\n<br>")
+ return string.replace(txt," ","&nbsp;")
+
+def upper_dir(path):
+ if(sys.platform=="win32"): # '\' for win32
+ i=path.rfind("\\",0,-1)
+ else:
+ i=path.rfind("/",0,-1) # '/' for *nix
+ return path[:i+1]
+
+def lower_dir(path, subdir):
+ if(sys.platform=="win32"): # '\' for win32
+ return path+subdir+"\\"
+ else:
+ return path+subdir+"/" # '/' for *nix
+
+def write_html_header(hfile, num):
+ hfile.write("""<html><head>
+ <meta http-equiv="Content-Language" content="zh-cn">
+ <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
+ <title>FQTerm Article Downloader</title>
+ </head>""")
+ hfile.write("<body>")
+ hfile.write("<p><b><h1>FQTerm Article Downloader</h1></b></p>")
+ txt="""<p><p align=center><a href=%d.html>Prevoius</a>
+ <a href=index.html>Index</a>
+ <a href=%d.html>Next</a></p align=center></p>""" % (num-1,num+1)
+ hfile.write(txt)
+ hfile.write("<hr><p></p>\n")
+
+def write_html_ender(hfile,num):
+ hfile.write("<hr><p></p>")
+ txt="""<p><p align=center><a href=%d.html>Prevoius</a>
+ <a href=index.html>Index</a>
+ <a href=%d.html>Next</a></p align=center></p>""" % (num-1,num+1)
+ hfile.write(txt)
+ hfile.write("<p><b>FQTerm --- BBS client based on Qt library</b><p>")
+ hfile.write("""<p><a href=http://code.google.com/p/fqterm>
+ http://code.google.com/p/fqterm</a><p>""")
+ hfile.write("</body>")
+ hfile.write("</html>")
+
+def write_index_header(hfile):
+ hfile.write("""<html><head>
+ <meta http-equiv="Content-Language" content="zh-cn">
+ <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
+ <title>FQTerm Article Downloader</title>
+ </head>""")
+ hfile.write("<p><b><h1>FQTerm Article Downloader</h1></b></p>")
+ hfile.write("""<p><p align=center>
+ <a href=\"../index.html\">Up</a>
+ </p align=center</p>""")
+ hfile.write("<hr><p></p>\n")
+
+def write_index_ender(hfile):
+ hfile.write("<hr><p></p>")
+ hfile.write("""<p><p align=center>
+ <a href=\"../index.html\">Up</a>
+ </p align=center</p>""")
+ hfile.write("<p><b>FQTerm --- BBS client based on Qt library</b><p>")
+ hfile.write("""<p><a href=http://code.google.com/p/fqterm>
+ http://code.google.com/p/fqterm</a><p>""")
+ hfile.write("</body>")
+ hfile.write("</html>")
+
+def get_list_num(str_line):
+ # get the number
+ matchobj = re.search("[0-9]+",str_line)
+ if(matchobj==None):
+ # wrong format
+ return None
+ else:
+ return str_line[matchobj.start():matchobj.end()]
+
+def get_list_categary(str_line):
+ # get the categary
+ matchobj = re.search("\[[^0-9]{6}\]",str_line)
+ if(matchobj==None):
+ # wrong format
+ return None
+ else:
+ return str_line[matchobj.start():matchobj.end()]
+
+def get_list_title(str_line):
+ matchobj = re.search("\[[^0-9]{6}\]",str_line)
+ if(matchobj==None):
+ # wrong format
+ return None
+ else:
+ # get the title
+ return str_line[matchobj.end()+1:]
+
+def down_folder():
+ global path
+ first_num = -1
+ while(1):
+ line=fqterm.caretY(lp)
+ str_line=fqterm.getText(lp,line)
+
+ article_num = get_list_num(str_line)
+ if (first_num == -1):
+ first_num = article_num
+ if(article_num==None):
+ print "Wrong format list"
+ # end the index.html
+ f=open(path+"index.html","a+")
+ write_index_ender(f)
+ f.close()
+ # wrong formated list, leave out
+ print "leave %s" % path
+ fqterm.sendString(lp,'q')
+ path=upper_dir(path)
+ time.sleep(wait_time)
+ return
+
+ article_categary = get_list_categary(str_line)
+ article_title = get_list_title(str_line)
+
+ # download if its file
+ if article_categary == '[文件]':
+ # log in index.html
+ f=open(path+"index.html","a+")
+ f.write("<p><a href="+article_num+".html>")
+ f.write("[文件] "+article_title+"</a></p>\n")
+ f.close()
+ # downlaod and save article
+ f=open(path+article_num+".html","w")
+ fqterm.sendString(lp,'r')
+ time.sleep(wait_time)
+ write_html_header(f,int(article_num))
+ f.write(txt2html(fqterm.getArticle(lp, 100)[0]))
+ f.write("\n")
+ write_html_ender(f,int(article_num))
+ f.close()
+ time.sleep(wait_time)
+ fqterm.sendString(lp,"q")
+ time.sleep(wait_time)
+ # recursive callback if its directory
+ elif article_categary == '[目录]':
+ # log in index.html
+ f=open(path+"index.html","a+")
+ f.write("<p><a href="+article_num+"/index.html>")
+ f.write("[目录] "+article_title+"</a></p>\n")
+ f.close()
+ # make dir and enter
+ path=lower_dir(path,article_num)
+ os.mkdir(path)
+ print "enter %s" % path
+ # create index.html and write the header
+ f=open(path+"index.html","w")
+ write_index_header(f)
+ f.close()
+ # recursive call
+ fqterm.sendString(lp,'r')
+ time.sleep(wait_time)
+ # increase delay when condition not met
+ down_folder()
+ else:
+ print "Unrecognized Categary"
+ # end the index.html
+ f=open(path+"index.html","a+")
+ write_index_ender(f)
+ f.close()
+ # wrong formated list, leave out
+ print "leave %s" % path
+ fqterm.sendString(lp,'q')
+ path=upper_dir(path)
+ time.sleep(wait_time)
+ return
+ str_next=fqterm.getText(lp,line+1)
+ # move cursor down and get the num
+ fqterm.sendString(lp,'j')
+ time.sleep(wait_time)
+ str_next=fqterm.getText(lp,fqterm.caretY(lp))
+ article_num_next = get_list_num(str_next)
+ if(article_num_next==None):
+ print "Wrong format list"
+ # end the index.html
+ f=open(path+"index.html","a+")
+ write_index_ender(f)
+ f.close()
+ # wrong formated list, leave out
+ print "leave %s" % path
+ fqterm.sendString(lp,'q')
+ path=upper_dir(path)
+ time.sleep(wait_time)
+ return
+ # exit current dir when the number of the next one equals or small then last
+ # this may cause problem when the server is extra slow
+ if(int(article_num_next) <= int(article_num)):
+ #print "leaving, because cur: %s < pre: %s" % (article_num_next , article_num)
+ if(path!=path_dir):
+ # end the index.html
+ f=open(path+"index.html","a+")
+ write_index_ender(f)
+ f.close()
+ # leave out
+ print "leave %s" % path
+ fqterm.sendString(lp,'q')
+ path=upper_dir(path)
+ time.sleep(wait_time)
+ return
+
+# NOTE: make sure path ended with '/'(*nix) or '\\'(windowz)
+#path_dir=path="e:\\temp\\test\\"
+path_dir=path="/home/dp2/temp/test/"
+
+# try to save all to home dir
+# path_dir=path=os.environ['HOME']+"/.fqterm/downloads/"+time.ctime()+"/"
+os.makedirs(path)
+
+# enter
+fqterm.sendString(lp,'x')
+time.sleep(wait_time)
+# create index.html and write the header
+f=open(path+"index.html","w")
+write_index_header(f)
+f.close()
+down_folder()
+# end the index.html
+f=open(path+"index.html","a+")
+write_index_ender(f)
+f.close()
+# exit
+fqterm.sendString(lp,'q')
+
diff --git a/res/script/downloadelite.js b/res/script/downloadelite.js
new file mode 100644
index 0000000..b835d6b
--- /dev/null
+++ b/res/script/downloadelite.js
@@ -0,0 +1,207 @@
+fqterm.import("utils.js");
+//NOTE: 1. this file should be in utf8
+// 2. if you cannot enter "BMS", this script may fail.
+//first enter the folder, then start script.
+var timeout = 2000;
+var path = "c:\\elite\\"; //DO NOT miss last slash
+var base_path = path;
+var newlinere;
+if (fqterm.platform() == "Win") {
+ newlinere = /%0D%0A/g;
+} else if (fqterm.platform() == "Mac"){
+ newlinere = /%0D/g;
+} else {
+ newlinere = /%0A/g;
+}
+newlinere = /\r\n|\n|\r/mg;
+//var path = /home/dp2/elite/
+var download = function(filename) {
+ fqterm.sendString("r");
+ sleep(timeout);
+ var article = fqterm.copyArticle();
+ fqterm.sendString("q");
+ sleep(timeout);
+ return article;
+}
+
+var make_html_header = function(num)
+{
+ num = parseInt(num);
+ var result = '<html><head>\n'+
+ '<meta http-equiv="Content-Language" content="zh-cn">\n'+
+ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n'+
+ '<title>FQTerm Article Downloader</title>\n'+
+ '</head>\n'+
+ '<body>\n'+
+ '<p><b><h1>FQTerm Article Downloader</h1></b></p>\n'+
+ '<p><p align=center><a href=' + (num - 1) + '.html>Prevoius</a>\n'+
+ '<a href=index.html>Index</a>\n'+
+ '<a href=' + (num + 1) + '.html>Next</a></p align=center></p>'+
+ '<hr><p></p>\n';
+ return result;
+}
+
+var make_html_ender = function(num)
+{
+ num = parseInt(num);
+ var result = '<hr><p></p>\n'+
+ '<p><p align=center><a href=' + (num - 1) + '.html>Prevoius</a>\n'+
+ '<a href=index.html>Index</a>\n'+
+ '<a href=' + (num + 1) + '.html>Next</a></p align=center></p>\n'+
+ '<p><b>FQTerm --- BBS client based on Qt library</b><p>\n'+
+ '<p><a href=http://code.google.com/p/fqterm>\n'+
+ 'http://code.google.com/p/fqterm</a><p>\n'+
+ '</body>\n'+
+ '</html>\n';
+ return result;
+}
+
+var make_index_header = function() {
+ var result = '<html><head>\n' +
+ '<meta http-equiv="Content-Language" content="zh-cn">\n' +
+ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n' +
+ '<title>FQTerm Article Downloader</title>\n' +
+ '</head>\n' +
+ '<p><b><h1>FQTerm Article Downloader</h1></b></p>\n' +
+ '<p><p align=center>\n' +
+ '<a href=\"../index.html\">Up</a>\n' +
+ '</p align=center</p>\n' +
+ '<hr><p></p>\n\n';
+ return result;
+}
+
+var make_index_ender = function() {
+ var result = '<hr><p></p>\n' +
+ '<p><p align=center>\n' +
+ '<a href=\"../index.html\">Up</a>\n' +
+ '</p align=center</p>\n' +
+ '<p><b>FQTerm --- BBS client based on Qt library</b><p>\n' +
+ '<p><a href=http://code.google.com/p/fqterm>\n' +
+ 'http://code.google.com/p/fqterm</a><p>\n' +
+ '</body>\n' +
+ '</html>\n';
+ return result;
+}
+
+var get_list_num = function(str_line) {
+ // get the number
+ try{
+ var re = /[0-9]+/;
+ var num = re.exec(str_line);
+ return num[0];
+ } catch(err) {
+ return "";
+ }
+}
+
+var get_list_categary = function(str_line) {
+ try{
+ var re = /\[[^0-9]{2}\]/; //utf8!
+ var cat = re.exec(str_line);
+ return cat[0];
+ } catch(err) {
+ return "";
+ }
+}
+
+var get_list_title = function(str_line) {
+ try{
+ var re = /\[[^0-9]{2}\]/; //utf8!
+ var cat = re.exec(str_line);
+ var i = str_line.search(re);
+ return str_line.substr(i + cat[0].length);
+ } catch(err) {
+ return "";
+ }
+}
+
+var txt2html = function(txt) {
+ var result = escape(txt);
+ var re_nlchar;
+ var newline;
+ if(result.indexOf('%0D%0A') > -1){
+ re_nlchar = /%0D%0A/g ;
+ newline = "%0D%0A";
+ }else if(result.indexOf('%0A') > -1) {
+ re_nlchar = /%0A/g ;
+ newline = "%0A";
+ }else if(result.indexOf('%0D') > -1){
+ re_nlchar = /%0D/g ;
+ newline = "%0A";
+ }
+ result = result.replace(re_nlchar, newline + '<br />');
+ result = result.replace(/%20/g, '&nbsp;');
+ return unescape(result);
+}
+
+var upper_dir = function(path) {
+ var spliter;
+ if (fqterm.platform() == "Win") {
+ spliter = '\\';
+ } else {
+ spliter = '/';
+ }
+ if (path.lastIndexOf(spliter) == path.length - 1) {
+ path = path.substr(0, path.length - 1);
+ }
+ var i = path.lastIndexOf(spliter);
+
+ return path.substr(0, i + 1);
+}
+
+var lower_dir = function(path, subdir) {
+ var spliter;
+ if (fqterm.platform() == "Win") {
+ spliter = '\\';
+ } else {
+ spliter = '/';
+ }
+ if (path.lastIndexOf(spliter) != path.length - 1) {
+ path += spliter;
+ }
+ return path + subdir + spliter;
+}
+
+
+var down_folder = function() {
+ fqterm.makePath(path);
+ var h = make_index_header();
+ fqterm.writeFile(path + 'index.html', h);
+ while (true) {
+ var line = fqterm.caretY();
+ var str_line = fqterm.getText(line);
+ var article_num = get_list_num(str_line);
+ var article_category = get_list_categary(str_line);
+ var article_title = get_list_title(str_line);
+ if (article_category == '[文件]') {
+ var a = '<p><a href=' + article_num + '.html>[文件] ' + article_title + '</a></p>\n';
+ fqterm.appendFile(path + "index.html", a);
+ var content = make_html_header(article_num) + txt2html(download()) + '\n' + make_html_ender(article_num);
+ fqterm.writeFile(path + article_num + ".html", content);
+ } else if (article_category == '[目录]') {
+ var a = '<p><a href=' + article_num + '/index.html>[目录] ' + article_title + '</a></p>\n';
+ fqterm.appendFile(path + "index.html", a);
+ path = lower_dir(path, article_num);
+ fqterm.sendString('r');
+ sleep(timeout);
+ down_folder();
+ } else {
+ break;
+ }
+ fqterm.sendString('j');
+ sleep(timeout);
+ var str_next = fqterm.getText(fqterm.caretY());
+ article_num_next = get_list_num(str_next);
+ if (article_num_next == "" || parseInt(article_num_next) <= parseInt(article_num)) {
+ break;
+ }
+ }
+ var e = make_index_ender();
+ fqterm.appendFile(path + 'index.html', e);
+ fqterm.sendString('q');
+ path = upper_dir(path);
+ sleep(timeout);
+}
+//fqterm.sendString('x');
+//sleep(timeout);
+down_folder();
diff --git a/res/script/downloadelite_smth.js b/res/script/downloadelite_smth.js
new file mode 100644
index 0000000..42a9d2f
--- /dev/null
+++ b/res/script/downloadelite_smth.js
@@ -0,0 +1,255 @@
+fqterm.import("utils.js");
+//NOTE: 1. this file should be in utf8
+// 2. if you cannot enter "BMS", this script may fail.
+//first enter the folder, then start script.
+var timeout = 6000;
+var path = "c:\\elite-sex\\"; //DO NOT miss last slash
+var base_path = path;
+
+newlinere = /\r\n|\n|\r/mg;
+//var path = /home/dp2/elite/
+
+var lastline = function() {
+ return fqterm.getText(fqterm.rows() - 1);
+}
+
+var firstline = function() {
+ return fqterm.getText(0);
+}
+
+var currentline = function(){
+ return fqterm.getText(fqterm.caretY());
+}
+
+var download = function(filename) {
+
+ var last_line = lastline();
+ fqterm.sendString("r");
+ var n = 10;
+ while(n--) {
+ sleep(timeout / 10);
+ if (lastline() != last_line) break;
+ }
+ var article = fqterm.copyArticle();
+
+ last_line = lastline();
+ fqterm.sendString("q");
+ n = 10;
+ while(n--) {
+ sleep(timeout / 10);
+ var c = lastline();
+ if (c != last_line) {
+ break;
+ }
+ }
+ return article;
+}
+
+var make_html_header = function(num)
+{
+ num = parseInt(num);
+ var result = '<html><head>\n'+
+ '<meta http-equiv="Content-Language" content="zh-cn">\n'+
+ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n'+
+ '<title>FQTerm Article Downloader</title>\n'+
+ '</head>\n'+
+ '<body>\n'+
+ '<p><b><h1>FQTerm Article Downloader</h1></b></p>\n'+
+ '<p><p align=center><a href=' + (num - 1) + '.html>Prevoius</a>\n'+
+ '<a href=index.html>Index</a>\n'+
+ '<a href=' + (num + 1) + '.html>Next</a></p align=center></p>'+
+ '<hr><p></p>\n';
+ return result;
+}
+
+var make_html_ender = function(num)
+{
+ num = parseInt(num);
+ var result = '<hr><p></p>\n'+
+ '<p><p align=center><a href=' + (num - 1) + '.html>Prevoius</a>\n'+
+ '<a href=index.html>Index</a>\n'+
+ '<a href=' + (num + 1) + '.html>Next</a></p align=center></p>\n'+
+ '<p><b>FQTerm --- BBS client based on Qt library</b><p>\n'+
+ '<p><a href=http://code.google.com/p/fqterm>\n'+
+ 'http://code.google.com/p/fqterm</a><p>\n'+
+ '</body>\n'+
+ '</html>\n';
+ return result;
+}
+
+var make_index_header = function() {
+ var result = '<html><head>\n' +
+ '<meta http-equiv="Content-Language" content="zh-cn">\n' +
+ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n' +
+ '<title>FQTerm Article Downloader</title>\n' +
+ '</head>\n' +
+ '<p><b><h1>FQTerm Article Downloader</h1></b></p>\n' +
+ '<p><p align=center>\n' +
+ '<a href=\"../index.html\">Up</a>\n' +
+ '</p align=center</p>\n' +
+ '<hr><p></p>\n\n';
+ return result;
+}
+
+var make_index_ender = function() {
+ var result = '<hr><p></p>\n' +
+ '<p><p align=center>\n' +
+ '<a href=\"../index.html\">Up</a>\n' +
+ '</p align=center</p>\n' +
+ '<p><b>FQTerm --- BBS client based on Qt library</b><p>\n' +
+ '<p><a href=http://code.google.com/p/fqterm>\n' +
+ 'http://code.google.com/p/fqterm</a><p>\n' +
+ '</body>\n' +
+ '</html>\n';
+ return result;
+}
+
+var get_list_num = function(str_line) {
+ // get the number
+ try{
+ var re = /[0-9]+/;
+ var num = re.exec(str_line);
+ return num[0];
+ } catch(err) {
+ return "";
+ }
+}
+
+var get_list_categary = function(str_line) {
+ try{
+ var re = /\[[^0-9]{2}\]/; //utf8!
+ var cat = re.exec(str_line);
+ return cat[0];
+ } catch(err) {
+ return "";
+ }
+}
+
+var get_list_title = function(str_line) {
+ try{
+ var re = /\[[^0-9]{2}\]/; //utf8!
+ var cat = re.exec(str_line);
+ var i = str_line.search(re);
+ return str_line.substr(i + cat[0].length);
+ } catch(err) {
+ return "";
+ }
+}
+
+var txt2html = function(txt) {
+ var result = escape(txt);
+ var re_nlchar;
+ var newline;
+ if(result.indexOf('%0D%0A') > -1){
+ re_nlchar = /%0D%0A/g ;
+ newline = "%0D%0A";
+ }else if(result.indexOf('%0A') > -1) {
+ re_nlchar = /%0A/g ;
+ newline = "%0A";
+ }else if(result.indexOf('%0D') > -1){
+ re_nlchar = /%0D/g ;
+ newline = "%0A";
+ }
+ result = result.replace(re_nlchar, newline + '<br />');
+ result = result.replace(/%20/g, '&nbsp;');
+ return unescape(result);
+}
+
+var upper_dir = function(path) {
+ var spliter;
+ if (fqterm.platform() == "Win") {
+ spliter = '\\';
+ } else {
+ spliter = '/';
+ }
+ if (path.lastIndexOf(spliter) == path.length - 1) {
+ path = path.substr(0, path.length - 1);
+ }
+ var i = path.lastIndexOf(spliter);
+
+ return path.substr(0, i + 1);
+}
+
+var lower_dir = function(path, subdir) {
+ var spliter;
+ if (fqterm.platform() == "Win") {
+ spliter = '\\';
+ } else {
+ spliter = '/';
+ }
+ if (path.lastIndexOf(spliter) != path.length - 1) {
+ path += spliter;
+ }
+ return path + subdir + spliter;
+}
+
+
+var down_folder = function() {
+ var single = true;
+ if (fqterm.caretY() > 0 && get_list_num(fqterm.getText(fqterm.caretY() - 1)) != "") {
+ single = false;
+ } else if (fqterm.caretY() < fqterm.rows() - 1 && get_list_num(fqterm.getText(fqterm.caretY() + 1)) != "") {
+ single = false;
+ }
+
+ fqterm.makePath(path);
+ var h = make_index_header();
+ fqterm.writeFile(path + 'index.html', h);
+ while (true) {
+ var line = fqterm.caretY();
+ var str_line = fqterm.getText(line);
+ var article_num = get_list_num(str_line);
+ var article_category = get_list_categary(str_line);
+ var article_title = get_list_title(str_line);
+ if (article_category == '[文件]') {
+ var a = '<p><a href=' + article_num + '.html>[文件] ' + article_title + '</a></p>\n';
+ fqterm.appendFile(path + "index.html", a);
+ var content = make_html_header(article_num) + txt2html(download()) + '\n' + make_html_ender(article_num);
+ fqterm.writeFile(path + article_num + ".html", content);
+ } else if (article_category == '[目录]') {
+ var a = '<p><a href=' + article_num + '/index.html>[目录] ' + article_title + '</a></p>\n';
+ fqterm.appendFile(path + "index.html", a);
+ path = lower_dir(path, article_num);
+ var first_line = firstline();
+ fqterm.sendString('r');
+ var n = 10;
+ while(n--) {
+ sleep(timeout / 10);
+ if (firstline() != first_line) break;
+ }
+ down_folder();
+ } else if (article_category == '[错误]') {
+ } else {
+ break;
+ }
+ //fqterm.msgBox(single);
+ if (single) break;
+ var cur_line = currentline();
+ fqterm.sendString('j');
+ var n = 10;
+ while(n--) {
+ sleep(timeout / 10);
+ if (currentline() != cur_line) break;
+ }
+ var str_next = fqterm.getText(fqterm.caretY());
+ article_num_next = get_list_num(str_next);
+ if (article_num_next == "" || parseInt(article_num_next) <= parseInt(article_num)) {
+ break;
+ }
+ }
+ var e = make_index_ender();
+ fqterm.appendFile(path + 'index.html', e);
+ path = upper_dir(path);
+
+
+ var first_line = firstline();
+ fqterm.sendString('q');
+ var n = 10;
+ while(n--) {
+ sleep(timeout / 10);
+ if (firstline() != first_line) break;
+ }
+}
+//fqterm.sendString('x');
+//sleep(timeout);
+down_folder();
diff --git a/res/script/post.js b/res/script/post.js
new file mode 100644
index 0000000..2de0f56
--- /dev/null
+++ b/res/script/post.js
@@ -0,0 +1,17 @@
+fqterm.import("utils.js");
+var path = "c:\\temp\\"; //DO NOT miss last slash here.
+var timeout = 500;
+var filelist = fqterm.readFolder(path);
+for (var i = 0; i < filelist.length; ++i)
+{
+ var filename = filelist[i];
+ var content = fqterm.readFile(path + filename);
+ fqterm.sendParsedString("^p");
+ sleep(timeout);
+ fqterm.sendString(filename);
+ fqterm.sendString("\n\n");
+ sleep(timeout);
+ fqterm.sendString(content);
+ fqterm.sendParsedString("^W\n");
+ sleep(timeout);
+} \ No newline at end of file
diff --git a/res/script/post.py b/res/script/post.py
new file mode 100644
index 0000000..27348f2
--- /dev/null
+++ b/res/script/post.py
@@ -0,0 +1,21 @@
+# coding=UTF-8
+# è¿žç»­å‘æ–‡
+
+import fqterm
+import sys, string, random
+
+sessionID=long(sys.argv[0])
+#print "sessionID is %s"%ID
+
+random.seed()
+for j in range(13):
+ i=random.random()*100000
+ print i
+ title='%fåªé’è›™%f张嘴'%(i,i)
+ content='%fåªçœ¼ç›%fæ¡è…¿'%(2*i,4*i)
+ #data=['^p', title, '\n', '\n', content, '^w','\n']
+ fqterm.sendParsedString(sessionID, r'^p%s\n\n%s^w\n'%(title, content) )
+ #for item in data:
+ # SendParsedString(ID, item)
+ # if dataEvents.has_key(ID):
+ # dataEvents[ID].wait()
diff --git a/res/script/postfile.py b/res/script/postfile.py
new file mode 100644
index 0000000..7de8244
--- /dev/null
+++ b/res/script/postfile.py
@@ -0,0 +1,48 @@
+# coding=UTF-8
+
+# 从硬盘文件连续å‘æ–‡
+# for fqterm: we need to add some status check.
+
+import fqterm
+import tools
+import sys, string, random, glob, os, time
+
+ID=long(sys.argv[0])
+#print "sessionID is %s"%ID
+
+random.seed()
+os.chdir(r'/home/dp2/') #主目录
+filenames = glob.glob(r'*.txt') #过滤æ¡ä»¶
+#filenames.extend( )
+for n in filenames:
+ print n
+ if len(n)>=5 and n[0:5]=='album': #特例
+ continue
+ #if n[-4:len(n)]!='.txt':
+ # continue
+ f=file(n, 'r')
+ title=f.readline()
+ title=title.strip()
+ while title and title.strip()=='':
+ title=f.readline()
+ title=title.strip()
+ if not title:
+ continue
+ content=f.read()
+
+ if not title or not content:
+ continue
+
+ data=['\x10', title, '\n', '\n', content, '\x17']
+
+ for item in data:
+ fqterm.sendString(ID, item)
+ print item
+ #if dataEvents.has_key(ID):
+ #dataEvents[ID].wait()
+ fqterm.sendString(ID, '\n')
+ #WaitFor(ID, SST_LIST)
+
+ interval=random.random()*7+3
+ #print interval
+ time.sleep(interval)
diff --git a/res/script/search.js b/res/script/search.js
new file mode 100644
index 0000000..a5be08b
--- /dev/null
+++ b/res/script/search.js
@@ -0,0 +1,22 @@
+fqterm.searchSelected = function(engine) {
+
+ var text = encodeURIComponent(String(fqterm.getSelect(false)));
+ var url = "about:blank";
+ engine = engine.toLowerCase();
+ if (engine == "google") {
+ searchUrl = "http://www.google.com/search?client=fqterm&rls=en&q=" + text + "&sourceid=fqterm";
+ } else if (engine == "baidu") {
+ searchUrl = "http://www.baidu.com/s?ie=utf-8&wd=" + text;
+ } else if (engine == "bing") {
+ searchUrl = "http://www.bing.com/search?q=" + text;
+ } else if (engine == "yahoo") {
+ searchUrl = "http://search.yahoo.com/search?ei=UTF-8&p=" + text;
+ } else if (engine == "custom") {
+ fqterm.msgBox("Modify search.js to customize search engine...");
+ return false;
+ }else {
+ return false;
+ }
+ fqterm.openUrl(searchUrl);
+ return true;
+}
diff --git a/res/script/sendmsg.py b/res/script/sendmsg.py
new file mode 100644
index 0000000..4d9ef2f
--- /dev/null
+++ b/res/script/sendmsg.py
@@ -0,0 +1,33 @@
+# send current article to one assigned email address
+# 1. need CJK codec
+import smtplib
+from email.Header import Header
+from email.Message import Message
+import fqterm,sys,string
+
+lp=long(sys.argv[0])
+article=fqterm.getArticle(lp, 100)[0]
+
+from_addr = "mime@email.com"
+to_addr="yours@email.com"
+
+subject = article.split("\n")
+subject = subject[1]
+subject = subject[7:]
+
+mess = Message()
+h = Header(subject,'GB2312')
+mess['Subject']=h
+
+msg = ("Content-Type: text/plain; charset= GB2312\r\n"
+ "From: %s\r\nTo: %s\r\n%s\r\n\r\n"
+ % (from_addr,to_addr, mess.as_string()))
+msg = msg + article
+
+smtp_host = "smtp.email.com"
+server = smtplib.SMTP(smtp_host)
+server.set_debuglevel(1)
+#maybe your smtp need auth
+#server.login(usr,pwd)
+server.sendmail(from_addr,to_addr,msg)
+server.quit()
diff --git a/res/script/system.js b/res/script/system.js
new file mode 100644
index 0000000..a49df9e
--- /dev/null
+++ b/res/script/system.js
@@ -0,0 +1,48 @@
+fqterm.import("utils.js");
+fqterm.mouseEvent = function(type, states, x, y, delta) {
+ if (type == fqterm.MOUSEEVENT.MOUSE_PRESS &&
+ states & fqterm.BUTTONSTATE.LEFT_BUTTON &&
+ states & fqterm.BUTTONSTATE.CTRL) {
+ fqterm.msgBox(fqterm.getFullTextAt(y, x, 1));
+ }
+ return false;
+}
+
+fqterm.detectMenu = function() {
+ fqterm.setMenuRect(1, 3, 20);
+ return false;
+}
+
+fqterm.antiIdle = function() {
+ //fqterm.msgBox("antiIdle");
+ return false;
+}
+
+
+fqterm.onBell = function() {
+ //fqterm.msgBox("onBell");
+}
+
+fqterm.autoReply = function() {
+ //fqterm.msgBox("autoReply");
+ return false;
+}
+
+
+fqterm.dataEvent = function() {
+ //fqterm.msgBox("data event");
+}
+
+fqterm.keyEvent = function(type, states, key) {
+// if (type == fqterm.KEYEVENT.KEY_PRESS &&
+// states & fqterm.BUTTONSTATE.CTRL && key) {
+// fqterm.msgBox(key);
+// }
+}
+
+
+var timeEvent = function() {
+ //fqterm.msgBox("haha");
+}
+var id = fqterm.setInterval(1000, timeEvent);
+//fqterm.clearInterval(id); \ No newline at end of file
diff --git a/res/script/system.py b/res/script/system.py
new file mode 100644
index 0000000..5305995
--- /dev/null
+++ b/res/script/system.py
@@ -0,0 +1,103 @@
+# coding=UTF-8
+"""
+This information is used to track the changes following this format
+ dd/mm/yy Author
+ * changes
+ * ...
+
+ 10/09/04 kingson
+ * merge code for ytht.net preview by cppgx
+ 08/09/04 kingson
+ * add this changelog information
+"""
+import fqterm, string
+import re, urllib
+
+"""
+get url from ytht
+"""
+
+def previewYTHT(lp):
+ URL=fqterm.getURL(lp)
+ if(URL=='' or URL==None):
+ return
+ if re.search('http://ytht.net/Ytht.Net' \
+ '(\S+)/con\?B=(\d+)&F=M\.(\d+)\.A', URL) != None:
+ # ytht artical URL
+ print 'Analizing ytht artical URL'
+ f_con = urllib.urlopen(URL)
+ con = f_con.read()
+ f_con.close()
+ m_con = re.search('src=\"http://162.105.31.(\d+)(/|:(\d+)/)' \
+ 'Ytht.Net/boards/(\d+)/M\.(\d+)\.A\+\d+\"', con)
+ if m_con != None:
+ URL1 = con[(m_con.start() + 5):(m_con.end() - 1)]
+ print 'URL1 = %s' % URL1
+ f_con1 = urllib.urlopen(URL1)
+ con1_lines = f_con1.readlines()
+ f_con1.close()
+ x = range(0, len(con1_lines))
+ for i in x:
+ m_con1 = re.search('<a href=\'http://162.105.31.(\d+)' \
+ '(/|:(\d+)/)Ytht.Net/attach/bbscon/(\S+)\?B=(\d+)&amp;' \
+ 'F=M\.(\d+)\.A&amp;attachpos=(\d+)&amp;attachname=/(\S+)\'', \
+ con1_lines[i])
+ if m_con1 != None:
+ URL2 = con1_lines[i][(m_con1.start() + 9): \
+ (m_con1.end() - 1)].replace('&amp;', '&')
+ print 'URL2 = %s' % URL2
+ fqterm.previewImage(lp, URL2)
+
+"""
+this is called when beep received
+"""
+def onBell(lp):
+ pass
+
+"""
+this is called when ready to autoreply
+"""
+def autoReply(lp):
+ reply = "I am the auto replier, please wait..."
+ reply_key = fqterm.getReplyKey(lp)
+ if(reply_key==''):
+ fqterm.sendParsedString(lp,"^Z")
+ else:
+ fqterm.sendParsedString(lp,reply_key)
+ fqterm.sendString(lp,reply)
+ fqterm.sendParsedString(lp,"^M")
+
+"""
+this is called when no activity after certain seconds,
+which is set in AddressBook dialog
+"""
+def antiIdle(lp):
+ fqterm.sendParsedString(lp,"^@")
+ print "antiIdle"
+
+"""
+whenever there is a mouse event
+type 0-press 1-release 2-move 3-double click 4-wheel
+state 0x01-left 0x02-right 0x04-middle 0x08-alt 0x10-control 0x20-shift
+cx/cy cursor position x/y in character
+"""
+def mouseEvent(lp, type, state, x, y, delta):
+ # left click + control to preview image
+ if type==0 and state==0x11:
+ previewYTHT(lp)
+
+"""
+whenever there is a key event
+type 0-press 1-release
+state 0x08-alt 0x10-control 0x20-shift
+key refer to Qt/Doc
+"""
+def keyEvent(lp, type, state, key):
+ pass
+
+"""
+whenever there is data from server after decoding
+and displaying
+"""
+def dataEvent(lp):
+ pass
diff --git a/res/script/test.js b/res/script/test.js
new file mode 100644
index 0000000..3018d8c
--- /dev/null
+++ b/res/script/test.js
@@ -0,0 +1,4 @@
+//fqterm.msgBox(fqterm.getAddress())
+//if (!fqterm.isConnected()) fqterm.reconnect()
+//fqterm.previewImage("http://img1.kaixin001.com.cn/i2/kaixinlogo.gif")
+fqterm.msgBox(fqterm.copyArticle());
diff --git a/res/script/tools.py b/res/script/tools.py
new file mode 100644
index 0000000..65320a0
--- /dev/null
+++ b/res/script/tools.py
@@ -0,0 +1,65 @@
+# coding=UTF-8
+# various tools
+
+# Left Arrow <--
+def sendLeft(fqterm,lp):
+ fqterm.sendParsedString(lp,"^[[C")
+# Left Arrow -->
+def sendRight(fqterm,lp):
+ fqterm.sendParsedString(lp,"^[[D")
+# Up Arrow
+def sendUp(fqterm,lp):
+ fqterm.sendParsedString(lp,"^[[A")
+# Down Arrow
+def sendDown(fqterm,lp):
+ fqterm.sendParsedString(lp,"^[[B")
+# Page Up
+def sendPageUp(fqterm,lp):
+ fqterm.sendParsedString(lp,"^[[5")
+# Page Down
+def sendPageDown(fqterm,lp):
+ fqterm.sendParsedString(lp,"^[[6")
+# Enter
+def sendDown(fqterm,lp):
+ fqterm.sendParsedString(lp,"^M")
+
+# Page State
+# Firebird BBS only
+def getPageState(fqterm,lp):
+ pageState="unknown"
+ lastline=fqterm.getText(lp,fqterm.rows(lp)-1)
+ if(lastline.find("阅读文章")!=-1 or
+ lastline.find("阅读精åŽåŒº")!=-1 or
+ lastline.find("下é¢è¿˜æœ‰")!=-1 or
+ lastline.find("回信")!=-1):
+ pageState="reading"
+ elif(lastline.find("时间")!=-1 and
+ lastline.find("使用者")!=-1):
+ pageState="list"
+
+ return pageState
+
+# analyze article list
+# return a dictionary
+# {"num":xxx,"sign":"","id":"","date":"","title":""}
+def getListInfo(text):
+ lst=text.split()
+ info["num"]=long(lst[0])
+ info["sign"]=lst[1]
+ info["id"]=lst[2]
+ info["date"]=lst[3]+lst[4]
+ info["title"]=lst[5]
+ return info
+
+# get the current user ID
+# only for FireBird BBS
+def getCurrentID(fqterm,lp):
+ text = fqterm.getText(lp,fqterm.rows(lp)-1)
+ if(text.find("使用者")==-1):
+ return
+ lst = string.split(text,"]")
+ text = lst[2]
+ lst = string.split(text,"[")
+ return lst[1]
+
+
diff --git a/res/script/utils.js b/res/script/utils.js
new file mode 100644
index 0000000..c13202c
--- /dev/null
+++ b/res/script/utils.js
@@ -0,0 +1,46 @@
+//script function names:
+//antiIdle() called on antiIdle, if this function exists, the embedded antiIdle procedure will not be called. (use fqterm.isAntiIdle() to get info.)
+//onBell() called on bell received. if this callback exists, the autoReply procedure will not be started. (use fqterm.isAutoReply() to get info.)
+//autoReply() (deprecated) called on autoReply, if this callback exists, the embedded autoReply procedure will not be called
+//dataEvent() called when contents in buffer changed. (after onBell, you will definitely receive one)
+//keyEvent(type(key event type), states (OR flags), key (key code)) called when keyevent received.
+//mouseEvent(type(mouse event type), states (OR flags), x, y, delta(for wheel)) called when mouseevent received. x, y are in term coordinates. If this callback exists, the embedded mouse/wheel support will be disabled (click to read article/enter menu), selecting/right click menu will still be there.
+//detectMenu() set menu rect here and return true to override the embedded menu selection rect. (call fqterm.setMenuRect()). and the mouse click on article, menu, ... will not take effect. you need to implement them in your mouse event.
+
+
+sleep = function(ms) {
+ var originInterval = fqterm.getUIEventInterval();
+ fqterm.setUIEventInterval(1);
+ var start = new Date().getTime();
+ while(true) {
+ if(new Date().getTime() - start > ms) break;
+ }
+ fqterm.setUIEventInterval(originInterval);
+}
+
+
+//script key event type
+fqterm.KEYEVENT = {
+ UNKNOWN : -1,
+ KEY_PRESS : 0
+}
+
+//script mouse event type
+fqterm.MOUSEEVENT = {
+ UNKNOWN : -1,
+ MOUSE_PRESS : 0,
+ MOUSE_RELEASE : 1,
+ MOUSE_MOVE : 2,
+ MOUSE_DBCLICK : 3,
+ WHEEL : 4
+}
+
+//script button state & key modifier
+fqterm.BUTTONSTATE = {
+ LEFT_BUTTON : 0x01,
+ RIGHT_BUTTON : 0x02,
+ MID_BUTTON : 0x04,
+ ALT : 0x08,
+ CTRL : 0x10,
+ SHIFT : 0x20
+}
diff --git a/res/script/weiboshare.js b/res/script/weiboshare.js
new file mode 100644
index 0000000..1ca9f92
--- /dev/null
+++ b/res/script/weiboshare.js
@@ -0,0 +1,51 @@
+
+var text = String(fqterm.getSelect(false));
+var url = String(fqterm.getURL());
+
+/*
+var sharejs = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n' +
+ '<html xmlns="http://www.w3.org/1999/xhtml">\n' +
+ '<head>\n' +
+ '<meta http-equiv="Content-type" content="text/html;charset=UTF-8">\n' +
+ '</head>\n' +
+ '<body onload="simulateclick()">\n' +
+ "<script type=\"text/javascript\" charset=\"utf-8\">\n(function(){\nvar _w = 142 , _h = 32;" +
+ "var param = {\nurl:location.href,\n" +
+ "type:'4',\n" +
+ "count:'0', \n" +
+ "appkey:'',\n" +
+ "title:'%1',\n" +
+ "pic:'%2',\n" +
+ "ralateUid:'2868108420',\n" +
+ "language:'zh_cn', \n" +
+ "rnd:new Date().valueOf()\n}\n" +
+ "var temp = [];\nfor( var p in param ){\ntemp.push(p + '=' + encodeURIComponent( param[p] || '' ) )\n}\n" +
+ "document.write('<iframe allowTransparency=\"true\" frameborder=\"0\" scrolling=\"no\" src=\"http://hits.sinajs.cn/A1/weiboshare.html?' + temp.join('&') + '\"" +
+ " width=\"'+ _w+'\" height=\"'+_h+'\"></iframe>')\n})()\n";
+ sharejs = sharejs + " </script>\n </body>\n </html>\n";
+ fqterm.writeFile("tmp.html", sharejs);
+*/
+
+var picUrl = "";
+
+var pattern = new RegExp('.+\\.(png|jpg|gif|bmp)$', 'i');
+if (pattern.test(url)) {
+ picUrl = url;
+} else {
+ text = text + ' ' + url;
+}
+
+shareurl = 'http://v.t.sina.com.cn/share/share.php?title=' + encodeURIComponent(removeSpecial(text));
+shareurl= shareurl + '&pic=' + encodeURIComponent(picUrl);
+shareurl= shareurl + '&ralateUid=2868108420&url=' + encodeURIComponent("D:\Test\test.html");
+
+
+fqterm.openUrl(shareurl);
+function removeSpecial(str) {
+ var res = str.replace(/"/g, '\\\"');
+ res = res.replace(/'/g, '\\\'');
+ res = res.replace(/\\/g, '\\\\');
+ res = res.replace(/\n/g, ' ');
+ res = res.replace(/\r/g, '');
+ return res;
+}
diff --git a/res/skin/dpstyle/ReadMe.txt b/res/skin/dpstyle/ReadMe.txt
new file mode 100644
index 0000000..bc3e2ed
--- /dev/null
+++ b/res/skin/dpstyle/ReadMe.txt
@@ -0,0 +1,5 @@
+dp"Ëæ±ã"×öµÄstyle sheet
+»ù±¾°üÀ¨ÁËËùÓеĿɶ¨ÖÆÔªËØ
+ÇëÏȽ«.qssÎļþÖеĸ÷´¦image·¾¶¸ÄΪ±¾»úÉϵÄ·¾¶
+È»ºóÔÚÆ«ºÃÖÐÑ¡Ôñ.qssÎļþ
+Èç¹û½«Æ«ºÃÖÐqssÎļþÒ»ÏîÁô¿Õ£¬Ôò²»»áʹÓÃsytlesheet£¬Ò²²»»áÕ¼ÓÃÈκÎ×ÊÔ´¡£
diff --git a/res/skin/dpstyle/dpstyle.qss b/res/skin/dpstyle/dpstyle.qss
new file mode 100644
index 0000000..b3ad554
--- /dev/null
+++ b/res/skin/dpstyle/dpstyle.qss
@@ -0,0 +1,203 @@
+QMenuBar {
+spacing: 10px;
+background-color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop : 0.0 white, stop : 0.5 gray, stop : 1 black);
+border : 1px outset;
+}
+QMenuBar::item {
+color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+background: transparent;
+}
+
+QMenuBar::item:selected {
+border-radius: 3px;
+border: 2px outset gray;
+color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 gray, stop: 0.1 black,stop: 0.2 gray, stop: 0.3 white, stop: 0.4 gray, stop: 0.5 black, stop: 0.6 gray,stop: 0.7 white, stop: 0.8 gray, stop: 0.9 black, stop: 1.0 gray);
+background : rgba(200, 200, 200, 150);}
+
+QMenuBar::item:pressed {
+border-radius: 3px;
+border: 2px inset gray;
+color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 gray, stop: 0.1 black,stop: 0.2 gray, stop: 0.3 white, stop: 0.4 gray, stop: 0.5 black, stop: 0.6 gray,stop: 0.7 white, stop: 0.8 gray, stop: 0.9 black, stop: 1.0 gray);
+background : rgba(100, 100, 100, 150);}
+
+ QMenu {
+ background-color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+
+ }
+
+ QMenu::item {
+ padding: 2px 25px 2px 20px;
+ border: 1px solid transparent; /* reserve space for selection border */
+ background : rgba(200,200,200,100);
+ color : rgb(40,40,40);
+ }
+
+ QMenu::item:disabled {
+ padding: 2px 25px 2px 20px;
+ border: 1px solid transparent; /* reserve space for selection border */
+ background : rgba(200,200,200,100);
+ color : rgb(200,200,200);
+ }
+
+ QMenu::item:selected {
+ color : rgb(200,200,200);
+ border-radius: 2px;
+ border: 1px outset gray;
+ background: rgba(100, 100, 100, 150);
+ }
+
+ QMenu::icon:checked {
+ border: 1px inset gray;
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ bottom: 1px;
+ left: 1px;
+ }
+
+ QMenu::separator {
+ height: 2px;
+ background: rgb(40,40,40);
+ margin-left: 10px;
+ margin-right: 5px;
+ }
+
+ QMenu::indicator {
+ width: 13px;
+ height: 13px;
+ }
+
+ QMenu::indicator:non-exclusive:unchecked {
+ image: url(C:/Users/Iroul/Desktop/images/checkbox_unchecked.png);
+ }
+
+ QMenu::indicator:non-exclusive:unchecked:selected {
+ image: url(C:/Users/Iroul/Desktop/images/checkbox_unchecked_hover.png);
+ }
+
+ QMenu::indicator:non-exclusive:checked {
+ image: url(C:/Users/Iroul/Desktop/images/checkbox_checked.png);
+ }
+
+ QMenu::indicator:non-exclusive:checked:selected {
+ image: url(C:/Users/Iroul/Desktop/images/checkbox_checked_hover.png);
+ }
+
+ /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */
+ QMenu::indicator:exclusive:unchecked {
+ image: url(C:/Users/Iroul/Desktop/images/radiobutton_unchecked.png);
+ }
+
+ QMenu::indicator:exclusive:unchecked:selected {
+ image: url(C:/Users/Iroul/Desktop/images/radiobutton_unchecked_hover.png);
+ }
+
+ QMenu::indicator:exclusive:checked {
+ image: url(C:/Users/Iroul/Desktop/images/radiobutton_checked.png);
+ }
+
+ QMenu::indicator:exclusive:checked:selected {
+ image: url(C:/Users/Iroul/Desktop/images/radiobutton_checked_hover.png);
+ }
+QToolBar {
+background-color : gray;
+border : 1px inset;
+}
+
+QToolBar:first {
+background-color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop : 0.0 white,stop : 1 gray);
+border : 1px inset;
+}
+QToolBar:middle {
+background-color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop : 0.0 gray,stop : 1 gray);
+border : 1px inset;
+}
+QToolBar:last {
+background-color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop : 0.0 gray,stop : 1 black);
+border : 1px inset;
+}
+
+QToolBar:only-one {
+background-color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop : 0.0 white,stop : 1 black);
+border : 1px inset;
+}
+QToolBar QToolButton {
+background : transparent;
+border : 2px outset transparent;
+border-radius : 3px;
+margin : 2px;
+}
+QToolBar QToolButton:hover {
+background-color : rgba(200,200,200,150);
+border : 2px outset gray;
+border-radius : 3px;
+}
+QToolBar QToolButton:pressed {
+background-color : rgba(200,200,200,150);
+border : 2px inset gray;
+border-radius : 3px;
+}
+QToolBar QToolButton:checked {
+background-color : rgba(200,200,200,150);
+border : 2px inset gray;
+border-radius : 3px;
+}
+ QTabWidget::pane { /* The tab widget frame */
+ border-top: 2px solid #C2C7CB;
+ background : blue;
+ border-color: #9B9B9B;
+ border-bottom-color: #C2C7CB; /* same as pane color */
+ }
+
+ QTabWidget::tab-bar {
+ background : blue;
+ left: 5px; /* move to the right by 5px */
+ }
+
+ QTabWidget {
+ background : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+ }
+ QTabBar {
+ background : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+ }
+ /* Style the tab using the tab sub-control. Note that
+ it reads QTabBar _not_ QTabWidget */
+ QTabBar::tab {
+ border: 2px solid #C4C4C3;
+ border-bottom-color: #C2C7CB; /* same as the pane color */
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ min-width: 8ex;
+ padding: 2px;
+ }
+
+ QTabBar::tab:hover {
+ color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 gray, stop: 0.1 black,stop: 0.2 gray, stop: 0.3 white, stop: 0.4 gray, stop: 0.5 black, stop: 0.6 gray,stop: 0.7 white, stop: 0.8 gray, stop: 0.9 black, stop: 1.0 gray);
+ background : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+ border-color: #9B9B9B;
+ border-bottom-color: #C2C7CB; /* same as pane color */
+ }
+
+ QTabBar::tab:selected {
+ color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 gray, stop: 0.1 black,stop: 0.2 gray, stop: 0.3 white, stop: 0.4 gray, stop: 0.5 black, stop: 0.6 gray,stop: 0.7 white, stop: 0.8 gray, stop: 0.9 black, stop: 1.0 gray);
+ background : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+ border-color: #9B9B9B;
+ border-bottom-color: #C2C7CB; /* same as pane color */
+ }
+
+ QTabBar::tab:!selected {
+ margin-top: 2px; /* make non-selected tabs look smaller */
+ background : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 gray, stop: 0.1 black,stop: 0.2 gray, stop: 0.3 white, stop: 0.4 gray, stop: 0.5 black, stop: 0.6 gray,stop: 0.7 white, stop: 0.8 gray, stop: 0.9 black, stop: 1.0 gray);
+ color : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+
+ }
+ QStatusBar {
+ background : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+ }
+
+QWidget#taskbar {
+ background : transparent;
+}
+#tasklayout {
+ background : qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.0 black,stop: 0.1 gray, stop: 0.2 white, stop: 0.3 gray, stop: 0.4 black, stop: 0.5 gray,stop: 0.6 white, stop: 0.7 gray, stop: 0.8 black, stop: 0.9 gray, stop: 1.0 white);
+} \ No newline at end of file
diff --git a/res/skin/dpstyle/image/checkbox_checked.png b/res/skin/dpstyle/image/checkbox_checked.png
new file mode 100644
index 0000000..cbf06f6
--- /dev/null
+++ b/res/skin/dpstyle/image/checkbox_checked.png
Binary files differ
diff --git a/res/skin/dpstyle/image/checkbox_checked_hover.png b/res/skin/dpstyle/image/checkbox_checked_hover.png
new file mode 100644
index 0000000..fb4d4d3
--- /dev/null
+++ b/res/skin/dpstyle/image/checkbox_checked_hover.png
Binary files differ
diff --git a/res/skin/dpstyle/image/checkbox_checked_pressed.png b/res/skin/dpstyle/image/checkbox_checked_pressed.png
new file mode 100644
index 0000000..852fcc0
--- /dev/null
+++ b/res/skin/dpstyle/image/checkbox_checked_pressed.png
Binary files differ
diff --git a/res/skin/dpstyle/image/checkbox_unchecked.png b/res/skin/dpstyle/image/checkbox_unchecked.png
new file mode 100644
index 0000000..5f54655
--- /dev/null
+++ b/res/skin/dpstyle/image/checkbox_unchecked.png
Binary files differ
diff --git a/res/skin/dpstyle/image/checkbox_unchecked_hover.png b/res/skin/dpstyle/image/checkbox_unchecked_hover.png
new file mode 100644
index 0000000..6873644
--- /dev/null
+++ b/res/skin/dpstyle/image/checkbox_unchecked_hover.png
Binary files differ
diff --git a/res/skin/dpstyle/image/checkbox_unchecked_pressed.png b/res/skin/dpstyle/image/checkbox_unchecked_pressed.png
new file mode 100644
index 0000000..6a768c4
--- /dev/null
+++ b/res/skin/dpstyle/image/checkbox_unchecked_pressed.png
Binary files differ
diff --git a/res/skin/dpstyle/image/down_arrow.png b/res/skin/dpstyle/image/down_arrow.png
new file mode 100644
index 0000000..85004ae
--- /dev/null
+++ b/res/skin/dpstyle/image/down_arrow.png
Binary files differ
diff --git a/res/skin/dpstyle/image/down_arrow_disabled.png b/res/skin/dpstyle/image/down_arrow_disabled.png
new file mode 100644
index 0000000..d9eefed
--- /dev/null
+++ b/res/skin/dpstyle/image/down_arrow_disabled.png
Binary files differ
diff --git a/res/skin/dpstyle/image/frame.png b/res/skin/dpstyle/image/frame.png
new file mode 100644
index 0000000..05a6005
--- /dev/null
+++ b/res/skin/dpstyle/image/frame.png
Binary files differ
diff --git a/res/skin/dpstyle/image/pagefold.png b/res/skin/dpstyle/image/pagefold.png
new file mode 100644
index 0000000..69be8f2
--- /dev/null
+++ b/res/skin/dpstyle/image/pagefold.png
Binary files differ
diff --git a/res/skin/dpstyle/image/pushbutton.png b/res/skin/dpstyle/image/pushbutton.png
new file mode 100644
index 0000000..c7529ba
--- /dev/null
+++ b/res/skin/dpstyle/image/pushbutton.png
Binary files differ
diff --git a/res/skin/dpstyle/image/pushbutton_hover.png b/res/skin/dpstyle/image/pushbutton_hover.png
new file mode 100644
index 0000000..af0ef9d
--- /dev/null
+++ b/res/skin/dpstyle/image/pushbutton_hover.png
Binary files differ
diff --git a/res/skin/dpstyle/image/pushbutton_pressed.png b/res/skin/dpstyle/image/pushbutton_pressed.png
new file mode 100644
index 0000000..f7381f7
--- /dev/null
+++ b/res/skin/dpstyle/image/pushbutton_pressed.png
Binary files differ
diff --git a/res/skin/dpstyle/image/radiobutton_checked.png b/res/skin/dpstyle/image/radiobutton_checked.png
new file mode 100644
index 0000000..8ab9157
--- /dev/null
+++ b/res/skin/dpstyle/image/radiobutton_checked.png
Binary files differ
diff --git a/res/skin/dpstyle/image/radiobutton_checked_hover.png b/res/skin/dpstyle/image/radiobutton_checked_hover.png
new file mode 100644
index 0000000..d68cb00
--- /dev/null
+++ b/res/skin/dpstyle/image/radiobutton_checked_hover.png
Binary files differ
diff --git a/res/skin/dpstyle/image/radiobutton_checked_pressed.png b/res/skin/dpstyle/image/radiobutton_checked_pressed.png
new file mode 100644
index 0000000..e3cd5a5
--- /dev/null
+++ b/res/skin/dpstyle/image/radiobutton_checked_pressed.png
Binary files differ
diff --git a/res/skin/dpstyle/image/radiobutton_unchecked.png b/res/skin/dpstyle/image/radiobutton_unchecked.png
new file mode 100644
index 0000000..321a9a1
--- /dev/null
+++ b/res/skin/dpstyle/image/radiobutton_unchecked.png
Binary files differ
diff --git a/res/skin/dpstyle/image/radiobutton_unchecked_hover.png b/res/skin/dpstyle/image/radiobutton_unchecked_hover.png
new file mode 100644
index 0000000..666a3b0
--- /dev/null
+++ b/res/skin/dpstyle/image/radiobutton_unchecked_hover.png
Binary files differ
diff --git a/res/skin/dpstyle/image/radiobutton_unchecked_pressed.png b/res/skin/dpstyle/image/radiobutton_unchecked_pressed.png
new file mode 100644
index 0000000..c4b0567
--- /dev/null
+++ b/res/skin/dpstyle/image/radiobutton_unchecked_pressed.png
Binary files differ
diff --git a/res/skin/dpstyle/image/sizegrip.png b/res/skin/dpstyle/image/sizegrip.png
new file mode 100644
index 0000000..350583a
--- /dev/null
+++ b/res/skin/dpstyle/image/sizegrip.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spindown.png b/res/skin/dpstyle/image/spindown.png
new file mode 100644
index 0000000..7ff3c64
--- /dev/null
+++ b/res/skin/dpstyle/image/spindown.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spindown_hover.png b/res/skin/dpstyle/image/spindown_hover.png
new file mode 100644
index 0000000..1486c4d
--- /dev/null
+++ b/res/skin/dpstyle/image/spindown_hover.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spindown_off.png b/res/skin/dpstyle/image/spindown_off.png
new file mode 100644
index 0000000..a90ab3f
--- /dev/null
+++ b/res/skin/dpstyle/image/spindown_off.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spindown_pressed.png b/res/skin/dpstyle/image/spindown_pressed.png
new file mode 100644
index 0000000..f6271cb
--- /dev/null
+++ b/res/skin/dpstyle/image/spindown_pressed.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spinup.png b/res/skin/dpstyle/image/spinup.png
new file mode 100644
index 0000000..1069dd0
--- /dev/null
+++ b/res/skin/dpstyle/image/spinup.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spinup_hover.png b/res/skin/dpstyle/image/spinup_hover.png
new file mode 100644
index 0000000..884c8d7
--- /dev/null
+++ b/res/skin/dpstyle/image/spinup_hover.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spinup_off.png b/res/skin/dpstyle/image/spinup_off.png
new file mode 100644
index 0000000..02dad1f
--- /dev/null
+++ b/res/skin/dpstyle/image/spinup_off.png
Binary files differ
diff --git a/res/skin/dpstyle/image/spinup_pressed.png b/res/skin/dpstyle/image/spinup_pressed.png
new file mode 100644
index 0000000..b1843e2
--- /dev/null
+++ b/res/skin/dpstyle/image/spinup_pressed.png
Binary files differ
diff --git a/res/skin/dpstyle/image/up_arrow.png b/res/skin/dpstyle/image/up_arrow.png
new file mode 100644
index 0000000..e7f7ddb
--- /dev/null
+++ b/res/skin/dpstyle/image/up_arrow.png
Binary files differ
diff --git a/res/skin/dpstyle/image/up_arrow_disabled.png b/res/skin/dpstyle/image/up_arrow_disabled.png
new file mode 100644
index 0000000..4d2c277
--- /dev/null
+++ b/res/skin/dpstyle/image/up_arrow_disabled.png
Binary files differ
diff --git a/res/unite/exit b/res/unite/exit
new file mode 100644
index 0000000..b6852af
--- /dev/null
+++ b/res/unite/exit
@@ -0,0 +1,24 @@
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ â•”â•[*]â•â•â• Message â•â•â•â•â•â•â•— 
+ â•‘ â•‘ 
+ ║ [1] 返回FQ BBS ║ 
+ ║ [2] 离开本BBS站 ║ 
+ â•‘ â•‘ 
+ â•‘________________________________â•‘ 
+ â•‘ â•‘ 
+ â•‘   å–消(C) â–ƒ â•‘ 
+ ║ ▃▃▃▃▃▃ ║ 
+ â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• 
+ 
+ 
+ 
+ 
+ 
+ 
+  \ No newline at end of file
diff --git a/res/unite/help b/res/unite/help
new file mode 100644
index 0000000..3b0aa0c
--- /dev/null
+++ b/res/unite/help
@@ -0,0 +1,24 @@
+帮助 FQTerm BBS  
+  
+ ┌─ ╱╲╱╲ Let's fq~ ───────────────────────┠
+ ╱╲︳ │ │───────────────────────────────┤ 
+ │ │ ╱╱ ̄╲  │ 
+ ╲ ╲|/╱ ̄ ̄  code.google.com/p/fqterm  │ 
+ │  ̄ ̄·  │ 
+ ├─────────────────────────────────────┤ 
+ └────────────────────────────────[FQ TEAM]┘ 
+ 
+ S) 脚本文档 
+ T) å¿«æ·é”® 
+ U) 连接Unix主机 F
+ X) 退出 是 Q .
+   ╱╲╱╲ 一 · 
+  ╱╲︳ │ │ 也 心 ç§ ∵ 
+  │ │ ╱╱ ̄╲ 生 是 情 :· 
+  ╲ ╲|/╱ ̄ ̄ 活 一 .∵: 
+   ̄ ̄· æ–¹ ç§ .∴· 
+  ` . å¼ .·∴` 
+   ∵: .. ..:∵.:·` 
+  `·∴ .:∴:∴‥`` 
+  
+      \ No newline at end of file
diff --git a/res/unite/script-doc b/res/unite/script-doc
new file mode 100644
index 0000000..b23f26f
--- /dev/null
+++ b/res/unite/script-doc
@@ -0,0 +1,199 @@
+
+FQTerm支æŒjavascriptå’ŒPython脚本
+
+javascriptè¿è¡Œæ–¹å¼æ˜¯åœ¨è„šæœ¬èœå•ä¸­é€‰æ‹©è¿è¡Œè„šæœ¬
+
+而Python则需è¦é€‰æ‹©è¿è¡ŒPython脚本
+
+如果你的èœå•ä¸­æ²¡æœ‰"è¿è¡ŒPython脚本",说明编译时未将Python支æŒç¼–译进FQTerm,请与作者或者打包者è”ç³»
+
+*编译fqterm时,若è¦æ”¯æŒPython,请在环境å˜é‡ä¸­åŒ…å«python2*.lib的路径
+
+现在fqterm对脚本回调的支æŒä»ç„¶å¤„于试验阶段,所以没有记载在这里。
+
+
+以下是jsçš„api列表,你基本å¯ä»¥åœ¨js中åƒè°ƒç”¨æ™®é€šçš„javascript function一样调用这些函数
+
+QString类型的返回值将被转å˜ä¸ºå­—符串,而QList类型则会被转å˜ä¸ºä¸€ä¸ªåˆ—表
+
+如果需è¦sleep,则需è¦fqterm.import(utils.js)。sleep是忙等,å‚数为ms。
+
+调用方å¼ï¼šåœ¨js脚本中,fqterm.function()å³å¯
+
+ //importå¦ä¸€ä¸ªè„šæœ¬ï¼Œå¦‚果是相对路径,则先在脚本当å‰è·¯å¾„æœç´¢
+ //然åŽåœ¨script目录下æœç´¢
+ bool import(const QString& filename);
+
+ //timer
+ int setInterval(int ms, const QScriptValue& func);
+ void clearInterval(int id);
+
+ //ui functions.
+ void msgBox(const QString& msg);
+
+ //bbs ui functions
+ int caretX();
+ int caretY();
+
+ QString getText(int row);
+ QString getTextAt(int row, int column, int len);
+ //当column是一个字的åŽåŠéƒ¨åˆ†æ—¶ï¼Œç”¨full的这个版本å¯ä»¥å¾—到这个字
+ QString getFullTextAt(int row, int column, int len);
+ QString getAttrText(int row);
+ QString getAttrTextAt(int row, int column, int len);
+ QString getFullAttrTextAt(int row, int column, int len);
+
+ void sendString(const QString& str);
+ void sendParsedString(const QString& str);
+
+ int columns();
+ int rows();
+
+ bool isConnected();
+ void disconnect();
+ void reconnect();
+
+ QString getBBSCodec();
+ QString getAddress();
+ int getPort();
+ int getProtocol();
+
+ QString getReplyKey();
+
+ QString getURL();
+ QString getIP();
+ void previewImage(const QString& url);
+ QString copyArticle();
+ void openUrl(const QString & url);
+ QString getSelect(bool color_copy);
+ QList<int> mapToChar(int screenX, int screenY);
+ //next 2 functions are map screen to char for x, y.
+ int charX(int screenX);
+ int charY(int screenY);
+ //mouse position is given in screen coordinate.
+ int mouseX();
+ int mouseY();
+
+ //auxiliary functions.
+ //should be move to some other class.
+ //qt script provides so poor extensions to js.
+ void writeFile(const QString& filename, const QString& str);
+ void appendFile(const QString& filename, const QString& str);
+ QString readFile(const QString& filename);
+ QStringList readFolder(const QString& path);
+ QString platform();
+ bool makePath(const QString& path);
+ QString newLine();
+
+
+以下是Pythonçš„API列表,具体用法还请å‚考script目录下的脚本示例
+
+需è¦æ³¨æ„的是
+
+1.需è¦import fqterm,æ‰èƒ½ä½¿ç”¨fqtermçš„API
+2.long(sys.argv[0])是当å‰çª—å£çš„标记
+
+sessionID=long(sys.argv[0])
+
+formatError(sessionID)
+get the traceback info
+return string
+
+getArticle(sessionID, interval)
+copy current article
+return (string, success)
+
+
+copyArticle(sessionID)
+copy current article (obsolete)
+return string
+
+getText(sessionID, line)
+get text at line
+return string
+
+
+getAttrText(sessionID, line)
+get attr text at line
+return string
+
+sendString(sessionID, str)
+send string to server
+return number of bytes written
+
+
+sendParsedString(sessionID, str)
+send string with escape
+return number of bytes written
+
+caretX(sessionID)
+caret x
+return int
+
+caretY(sessionID)
+caret y
+return int
+
+
+columns(sessionID)
+screen width
+return int
+
+
+rows(sessionID)
+screen height
+return int
+
+
+isConnected(sessionID)
+connected to server or not
+return int
+
+disconnect(sessionID)
+disconnect from server
+
+
+reconnect(sessionID)
+reconnect
+
+
+getBBSCodec(sessionID)
+get the bbs encoding, GBK or Big5
+return string
+
+getAddress(sessionID)
+get the bbs address
+return string
+
+getPort(sessionID)
+get the bbs port number
+return int
+
+getProtocol(sessionID)
+get the bbs protocol, 0/1/2 TELNET/SSH1/SSH2
+return int
+
+getReplyKey(sessionID)
+get the key to reply messages
+return string (wtf...?)
+
+
+getURL(sessionID)
+get the url string under mouse (not sure if works)
+return string
+
+
+previewImage(sessionID, url)
+preview the image link
+
+
+fromUTF8(str, codec)
+decode from utf8 to string in specified codec
+return string
+
+
+toUTF8(str, codec)
+decode from string in specified codec to utf8
+return string
+
+
diff --git a/res/unite/shortcut-doc b/res/unite/shortcut-doc
new file mode 100644
index 0000000..6a08262
--- /dev/null
+++ b/res/unite/shortcut-doc
@@ -0,0 +1,10 @@
+FQTerm支æŒä¸¤ç§å¿«æ·é”®è®¾ç½®
+
+1.系统快æ·é”®ï¼Œè¯·é€‰æ‹©Option-->Shortcut Settingèœå•é¡¹ï¼Œç„¶åŽé€‰ä¸­å¯¹åº”功能的快æ·é”®ä¸€åˆ—,按下你需è¦çš„å¿«æ·é”®ã€‚注æ„Del键是ä¿ç•™çš„,用以清空快æ·é”®ã€‚
+
+
+2.自定义快æ·é”®ï¼Œå¯ä»¥é€šè¿‡ç‚¹å‡»å·¥å…·æ ä¸Šçš„键盘图标æ¥è®¾ç½®ã€‚这里需è¦æ‰‹å·¥è¾“入快æ·é”®ä»£ç (如Ctrl+Alt+C),并且在按键æ ä¸­è¾“入相应的按键åºåˆ—。需è¦æ³¨æ„的一点是,Enter用Return代替,å³ä½¿ç”¨Ctrl+Return,ä¸èƒ½ä½¿ç”¨Ctrl+Enter。
+
+注æ„Ctrl用^表示,比如Ctrl-P就是^P,回车是^M,方å‘键请用下é¢çš„æ示按钮输入。
+
+F1至F12çš„åºåˆ—是^[[11~ ^[[12~ ^[[13~ ^[[14~ ^[[15~ ^[[17~ ^[[18~ ^[[19~ ^[[20~ ^[[21~ ^[[23~ ^[[24~ \ No newline at end of file
diff --git a/res/unite/ssh-unix-doc b/res/unite/ssh-unix-doc
new file mode 100644
index 0000000..7d5d6fa
--- /dev/null
+++ b/res/unite/ssh-unix-doc
@@ -0,0 +1,17 @@
+1.在站点设置-->其他选项å¡ä¸­å…³é—­å“铃。窗å£æŒ¯åŠ¨ä¼šè‡ªåŠ¨è¢«å…³é—­ã€‚
+
+2.在站点设置-->其他选项å¡ä¸­å…³é—­é˜²å‘呆,å¦åˆ™ä¼šæœ‰é˜²å‘呆字符串被å‘é€è‡³æœåŠ¡å™¨ã€‚
+
+3.在站点设置-->属性选项å¡ä¸­è®¾ç½®æ­£ç¡®çš„ç¼–ç è®¾ç½®ï¼Œè¿™å’Œä½ çš„*nix主机设置有关,我们现在支æŒUTF8ç¼–ç ã€‚
+
+4.使用UTF8时我们无法使用debug模å¼ï¼Œå¦åˆ™è¿™ä¼šå¯¼è‡´ä¸€äº›è¾¹ç•Œæ£€æŸ¥é—®é¢˜å’Œcrash,在以åŽçš„版本中,我们会试图解决这个问题。
+
+5.在站点设置-->键盘中将退格键设置为"^?"。
+
+6.在选项-->å好中关闭ENQ。
+
+7.在站点设置-->其他选项å¡å…³é—­zmodem下载。
+
+8.在站点设置-->终端选项å¡ä¸­å°†ç»ˆç«¯ç±»åž‹è®¾ç½®ä¸ºvt102或xterm。
+
+9.现在我们支æŒç»ˆç«¯çª—å£è¡Œåˆ—æ•°çš„å˜åŒ–,但是终端窗å£çš„大å°é™å®šä¸º640x480。
diff --git a/res/unite/welcome b/res/unite/welcome
new file mode 100644
index 0000000..e8cf95e
--- /dev/null
+++ b/res/unite/welcome
@@ -0,0 +1,24 @@
+ä¸»é€‰å• FQTerm BBS  
+  
+ ┌─ ╱╲╱╲ Let's fq~~ ───────────────────────┠
+ ╱╲︳ │ │───────────────────────────────┤ 
+ │ │ ╱╱ ̄╲  │ 
+ ╲ ╲|/╱ ̄ ̄  code.google.com/p/fqterm  │ 
+ │  ̄ ̄·  │ 
+ ├─────────────────────────────────────┤ 
+ └────────────────────────────────[FQ TEAM]┘ 
+ 
+ H) 帮助文档 
+ X) 退出 
+ F 
+  是 Q . 
+   ╱╲╱╲ 一 · 
+  ╱╲︳ │ │ 也 心 ç§ ∵ 
+  │ │ ╱╱ ̄╲ 生 是 情 :· 
+  ╲ ╲|/╱ ̄ ̄ 活 一 .∵: 
+   ̄ ̄· æ–¹ ç§ .∴· 
+  ` . å¼ .·∴` 
+   ∵: .. ..:∵.:·` 
+  `·∴ .:∴:∴‥`` 
+  
+      \ No newline at end of file
diff --git a/res/userconf/README.txt b/res/userconf/README.txt
new file mode 100644
index 0000000..9f88660
--- /dev/null
+++ b/res/userconf/README.txt
@@ -0,0 +1,5 @@
+Don't modify files in this directory. They are backup files for user configurable data.
+
+If you do want to change settings, please go to:
+*nix: $HOME/.fqterm/
+win32: $HOME/Application Data/FQTerm/ \ No newline at end of file
diff --git a/res/userconf/address.cfg.orig b/res/userconf/address.cfg.orig
new file mode 100644
index 0000000..a842800
--- /dev/null
+++ b/res/userconf/address.cfg.orig
@@ -0,0 +1,156 @@
+[bbs 0]
+addr=bbs.newsmth.org
+alwayshighlight=0
+ansicolor=1
+antiidlestring=^@
+autoclosewin=0
+autocopy=1
+autofont=1
+autologin=0
+autoreply=(FQTerm) Sorry, I am not around
+bautoreply=1
+bbscode=0
+bgcolor=#000000
+colorcopy=0
+column=80
+cursor=1
+displaycode=0
+escape=^[^[[
+fgcolor=#c6c3c6
+hosttype=0
+interval=2
+keytype=0
+loadscript=0
+maxidle=120
+menucolor=#004184
+menutype=2
+name=NEWSMTH
+password=
+port=23
+postlogin=
+prelogin=
+protocol=0
+proxyaddr=
+proxyauth=0
+proxypassword=
+proxyport=0
+proxytype=0
+proxyuser=
+reconnect=0
+rectselect=0
+replykey=
+retrytimes=-1
+row=24
+schemafile=
+scriptfile=
+scroll=240
+sshpassword=
+sshuser=
+termtype=vt102
+user=
+
+[bbs 1]
+addr=newsmth.net
+alwayshighlight=0
+ansicolor=1
+antiidlestring=^@
+autoclosewin=0
+autocopy=1
+autofont=1
+autologin=0
+autoreply=(FQTerm) Sorry, I am not around
+bautoreply=1
+bbscode=0
+bgcolor=#000000
+colorcopy=0
+column=80
+cursor=1
+displaycode=0
+escape=^[^[[
+fgcolor=#c6c3c6
+hosttype=0
+interval=2
+keytype=0
+loadscript=0
+maxidle=120
+menucolor=#004184
+menutype=2
+name=ssh_NEWSMTH
+password=
+port=22
+postlogin=
+prelogin=
+protocol=1
+proxyaddr=
+proxyauth=0
+proxypassword=
+proxyport=0
+proxytype=0
+proxyuser=
+reconnect=0
+rectselect=0
+replykey=
+retrytimes=-1
+row=24
+schemafile=
+scriptfile=
+scroll=240
+sshpassword=
+sshuser=
+termtype=vt102
+user=
+
+[bbs 2]
+addr=mitbbs.com
+alwayshighlight=0
+ansicolor=1
+antiidlestring=^@
+autoclosewin=0
+autocopy=1
+autofont=1
+autologin=0
+autoreply=(FQTerm) Sorry, I am not around
+bautoreply=1
+bbscode=0
+bgcolor=#000000
+colorcopy=0
+column=80
+cursor=1
+displaycode=0
+escape=^[^[[
+fgcolor=#c6c3c6
+hosttype=0
+interval=2
+keytype=0
+loadscript=0
+maxidle=120
+menucolor=#004084
+menutype=2
+name=Unknown Space
+password=
+port=23
+postlogin=
+prelogin=
+protocol=0
+proxyaddr=
+proxyauth=0
+proxypassword=
+proxyport=0
+proxytype=0
+proxyuser=
+reconnect=0
+rectselect=0
+replykey=
+retrytimes=-1
+row=24
+schemafile=
+scriptfile=
+scroll=240
+sshpassword=
+sshuser=
+termtype=vt102
+user=
+
+[bbs list]
+num=3
+
diff --git a/res/userconf/fqterm.cfg.orig b/res/userconf/fqterm.cfg.orig
new file mode 100644
index 0000000..a82c376
--- /dev/null
+++ b/res/userconf/fqterm.cfg.orig
@@ -0,0 +1,58 @@
+[global]
+articledialog=700 224 645 584
+bbsbar=0 2 2 1 21
+clipcodec=0
+fullscreen=0
+keybar=1 2 1 0 0
+language=zh_CN
+mainbar=1 2 0 1 0
+max=1
+msgdialog=629 325 474 212
+pixelsize=16
+pointsize=12
+quick default index=0
+quickdefaultindex=3
+subwindowmax=1
+subwindowsize=1280 652
+switchbar=1
+theme=0
+toolbarstate=000000ff00000000fd00000000000005000000029800000004000000040000000800000008fc00000001000000020000000300000018004d00610069006e00200054006f006f006c0042006100720100000000000000460000000000000000000000140043007500730074006f006d0020004b0065007901000000460000006200000000000000000000001c0062006200730020006f007000650072006100740069006f006e007301000000a8000004580000000000000000
+version=000309
+vscrollpos=2
+
+[key]
+key0=0^Ptest^M^Mhehe^M^X^M^M
+key1=0^[[Cr^Morz!^W^M
+name0=post
+name1=orz
+num=1
+shortcut0=
+shortcut1=Ctrl+Alt+R
+
+[preference]
+antialias=1
+beep=1
+blinktab=1
+clearpool=0
+http=
+image=
+logmsg=1
+smartww=1
+url=1
+vsetting=1
+warn=1
+wheel=1
+wordwrap=72
+xim=0
+
+[quick 0]
+addr=newsmth.net
+port=23
+
+[quick 1]
+addr=newsmth.net
+port=22
+
+[quick list]
+num=2
+
diff --git a/res/userconf/language.cfg.orig b/res/userconf/language.cfg.orig
new file mode 100644
index 0000000..a7fa5cc
--- /dev/null
+++ b/res/userconf/language.cfg.orig
@@ -0,0 +1,4 @@
+[Name]
+zh_CN=简体中文(&C)
+zh_TW=ç¹é«”中文(&T)
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..e8aedb4
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_subdirectory(common)
+
+add_subdirectory(protocol)
+
+add_subdirectory(ui)
+
+add_subdirectory(terminal)
+
+add_subdirectory(utilities)
+
+add_subdirectory(unite)
+
+add_subdirectory(fqterm)
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
new file mode 100644
index 0000000..d3f0c09
--- /dev/null
+++ b/src/common/CMakeLists.txt
@@ -0,0 +1,36 @@
+set(fqterm_common_SRCS
+ common.h
+ common.cpp
+ fqterm.h
+ fqterm_trace.h
+ fqterm_trace.cpp
+ fqterm_config.h
+ fqterm_config.cpp
+ fqterm_sound.h
+ fqterm_sound.cpp
+ fqterm_param.h
+ fqterm_param.cpp
+ fqterm_path.h
+ fqterm_path.cpp
+ fqterm_font.h
+ fqterm_font.cpp
+ fqterm_exif_extractor.h
+ fqterm_exif_extractor.cpp
+ fqterm_filedialog.h
+ fqterm_filedialog.cpp
+ fqterm_shortcuthelper.h
+ fqterm_shortcuthelper.cpp
+)
+
+qt4_automoc(${fqterm_common_SRCS})
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_common
+ ${fqterm_common_SRCS}
+)
diff --git a/src/common/common.cpp b/src/common/common.cpp
new file mode 100644
index 0000000..ec08bef
--- /dev/null
+++ b/src/common/common.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+
+#include <QString>
+#include <QProcess>
+#include <QStringList>
+#include "common.h"
+
+namespace FQTerm {
+
+void runProgram(const QString &cmd, const QString& arg, bool bg) {
+ if (bg) {
+ QProcess::startDetached(cmd, QStringList(arg));
+ } else {
+ QProcess::execute(cmd, QStringList(arg));
+ }
+
+ return;
+ /*
+#if defined(WIN32)
+ QString strCmd = "\"\"" + cmd + "\" \"" + arg + "\"\"";
+#else
+ QString strCmd = "'" + cmd + "' '" + arg + "'";
+#endif
+#if !defined(WIN32)
+ if (bg) {
+ strCmd += " &";
+ }
+#endif
+ system(strCmd.toLocal8Bit());
+ */
+}
+
+} // namespace FQTerm
diff --git a/src/common/common.h b/src/common/common.h
new file mode 100644
index 0000000..5720ddc
--- /dev/null
+++ b/src/common/common.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_COMMON_H
+#define FQTERM_COMMON_H
+
+#if defined(WIN32)
+#define OS_NEW_LINE "\r\n"
+#elif defined(__APPLE__)
+#define OS_NEW_LINE "\r"
+#else
+#define OS_NEW_LINE "\n"
+#endif
+
+class QString;
+
+namespace FQTerm {
+
+enum Directions {
+ kHome = 0,
+ kEnd = 1,
+ kPageUp = 2,
+ kPageDown = 3,
+ kUp = 4,
+ kDown = 5,
+ kLeft = 6,
+ kRight = 7
+};
+
+const char * const kDirections[] = {
+ // 4
+ "\x1b[1~", // 0 HOME
+ "\x1b[4~", // 1 END
+ "\x1b[5~", // 2 PAGE UP
+ "\x1b[6~", // 3 PAGE DOWN
+ // 3
+ "\x1b[A", // 4 UP
+ "\x1b[B", // 5 DOWN
+ "\x1b[D", // 6 LEFT
+ "\x1b[C" // 7 RIGHT
+};
+
+void runProgram(const QString &cmd, const QString& arg = "", bool bg = true);
+
+} // namespace FQTerm
+
+#endif // FQTERM_COMMON_H
diff --git a/src/common/fqterm.h b/src/common/fqterm.h
new file mode 100644
index 0000000..515cedc
--- /dev/null
+++ b/src/common/fqterm.h
@@ -0,0 +1,350 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_GLOBAL_H
+#define FQTERM_GLOBAL_H
+
+#ifndef BUFSIZE
+#define BUFSIZE (1024)
+#endif
+
+#include <QTextCodec>
+#include <QString>
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+#if defined(WIN32) && (_MSC_VER >= 1400)
+ //Using vc2005 or +
+#define fq_strdup _strdup
+#else
+#define fq_strdup strdup
+#endif
+
+#ifdef FOUND_PYTHON
+//#define HAVE_PYTHON
+#endif //FOUND_PYTHON
+
+#define USE_GLOBAL_HOTKEY
+
+//code convert
+enum EncodingID {FQTERM_ENCODING_GBK = 0, FQTERM_ENCODING_BIG5 = 1,
+ FQTERM_ENCODING_UTF8 = 2, FQTERM_ENCODING_HKSCS = 3,
+ FQTERM_ENCODING_UAO = 4};
+
+#if QT_VERSION >= 0X040700
+#define GBK_CODECS_NAME "GB18030"
+#else
+#define GBK_CODECS_NAME "GBK"
+#endif
+
+#define G2U(s) ( QTextCodec::codecForName(GBK_CODECS_NAME)->toUnicode(s) )
+#define U2G(s) ( QTextCodec::codecForName(GBK_CODECS_NAME)->fromUnicode(s) )
+#define B2U(s) ( QTextCodec::codecForName("Big5")->toUnicode(s) )
+#define U2B(s) ( QTextCodec::codecForName("Big5")->fromUnicode(s) )
+#define H2U(s) ( QTextCodec::codecForName("Big5-HKSCS")->toUnicode(s) )
+#define U2H(s) ( QTextCodec::codecForName("Big5-HKSCS")->fromUnicode(s) )
+#define U2U8(s) ( s.toUtf8() )
+#define U82U(s) ( QString::fromUtf8(s) )
+#define A2U(s) (QTextCodec::codecForName("UAO")->toUnicode(s) )
+#define U2A(s) ( QTextCodec::codecForName("UAO")->fromUnicode(s) )
+
+inline QByteArray unicode2encoding(const QString &text, int encoding) {
+ switch(encoding)
+ {
+ case FQTERM_ENCODING_GBK:
+ return(U2G(text));
+ case FQTERM_ENCODING_BIG5:
+ return(U2B(text));
+ case FQTERM_ENCODING_UTF8:
+ return(U2U8(text));
+ case FQTERM_ENCODING_HKSCS:
+ return (U2H(text));
+ case FQTERM_ENCODING_UAO:
+ return (U2A(text));
+ }
+
+ return "";
+}
+
+inline QString encoding2unicode(const QByteArray &text, int encoding) {
+ switch(encoding)
+ {
+ case FQTERM_ENCODING_GBK:
+ return(G2U(text));
+ case FQTERM_ENCODING_BIG5:
+ return(B2U(text));
+ case FQTERM_ENCODING_UTF8:
+ return(U82U(text));
+ case FQTERM_ENCODING_HKSCS:
+ return (H2U(text));
+ case FQTERM_ENCODING_UAO:
+ return (A2U(text));
+ }
+
+ return "";
+}
+
+#define FQTERM_CTRL(c) ((c)&0x1f)
+
+// every character has a 16-bit description
+// low 8 for colors
+// hight 8 for attributes
+#define COLORMASK 0x00ff
+#define ATTRMASK 0xff00
+
+// color 8-bit
+// bit 0-2 foreground
+// 0 black
+// 1 red
+// 2 green
+// 3 yellow
+// 4 blue
+// 5 magenta
+// 6 cyan
+// 7 white
+// bit 3 highlight foreground
+// 0 no
+// 1 highlight
+// bit 4-6 background
+// 0 black
+// 1 red
+// 2 green
+// 3 yellow
+// 4 blue
+// 5 magenta
+// 6 cyan
+// 7 white
+// bit 7 highlight background (unused)
+// 0 no
+// 1 highlight
+
+#define FGMASK 0x0f
+#define BGMASK 0xf0
+#define FG_HIGHLIGHT_MASK 0x08
+#define BG_HIGHLIGHT_MASK 0x80
+
+//set color
+#define SETFG(c) ( (c) & FGMASK )
+#define SETBG(c) ( ( (c) << 4 ) & BGMASK )
+#define SET_FG_HIGHLIGHT(c) ( ( (c) << 3 ) & FG_HIGHLIGHT_MASK )
+#define SET_BG_HIGHLIGHT(c) ( ( (c) << 7 ) & BG_HIGHLIGHT_MASK )
+
+//get color
+#define GETFG(c) ( (c) & FGMASK )
+#define GETBG(c) ( ( (c) & BGMASK ) >> 4 )
+
+#define GET_FG_HIGHLIGHT(c) ( ( (c) & FG_HIGHLIGHT_MASK ) >> 3 )
+#define GET_BG_HIGHLIGHT(c) ( ( (c) & BG_HIGHLIGHT_MASK ) >> 7 )
+
+//#define GET_INVERSE_COLOR(c) ( SETFG( (7 - (c & 0x7)) | (c & 0x08) ) | SETBG(15-GETBG(c)) )
+#define GET_INVERSE_COLOR(c) ( SETFG(15-GETFG(c)) | SETBG(15-GETBG(c)) )
+
+// mask for attr
+#define BRIGHTMASK 0x01
+#define DIMMASK 0x02
+#define UNDERLINEMASK 0x08
+#define BLINKMASK 0x10
+#define RAPIDBLINKMASK 0x20
+#define REVERSEMASK 0x40
+#define INVISIBLEMASK 0x80
+
+//set attributes
+#define SETBRIGHT(a) ( (a) | BRIGHTMASK )
+#define SETDIM(a) ( (a) | DIMMASK )
+#define SETUNDERLINE(a) ( (a) | UNDERLINEMASK )
+#define SETBLINK(a) ( (a) | BLINKMASK )
+#define SETRAPIDBLINK(a) ( (a) | RAPIDBLINKMASK )
+#define SETREVERSE(a) ( (a) | REVERSEMASK )
+#define SETINVISIBLE(a) ( (a) | INVISIBLEMASK )
+
+//get attributes
+#define GETBRIGHT(a) ( (a) & BRIGHTMASK )
+#define GETDIM(a) ( (a) & DIMMASK )
+#define GETUNDERLINE(a) ( (a) & UNDERLINEMASK )
+#define GETBLINK(a) ( (a) & BLINKMASK )
+#define GETRAPIDBLINK(a) ( (a) & RAPIDBLINKMASK )
+#define GETREVERSE(a) ( (a) & REVERSEMASK )
+#define GETINVISIBLE(a) ( (a) & INVISIBLEMASK )
+
+//default color
+#define NO_COLOR ( SETFG(7) | SETBG(0) )
+//default attribute
+#define NO_ATTR 0x04
+
+// other definations
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define DAE_FINISH 10001
+#define DAE_TIMEOUT 10002
+
+#define PYE_ERROR 10003
+#define PYE_FINISH 10004
+
+// some keys
+#define CHAR_NUL 0x00 // ^@
+#define CHAR_ENQ 0x05 // ^E
+#define CHAR_BELL 0x07 // ^G
+#define CHAR_BS 0x08 // ^H
+#define CHAR_TAB 0x09 // ^I
+#define CHAR_LF 0x0a // ^J
+#define CHAR_VT 0x0b // ^K
+#define CHAR_FF 0x0c // ^L
+#define CHAR_CR 0x0d // ^M
+#define CHAR_SO 0x0e // ^N
+#define CHAR_SI 0x0f // ^O
+#define CHAR_CAN 0x18 // ^X
+#define CHAR_ESC 0x1b // ^[
+#define CHAR_DEL 0x7f // DEL
+
+#define CHAR_NORMAL -1
+
+const char ANSWERBACK_MESSAGE[] = "This is fqterm.";
+
+// telnet state
+#define TSRESOLVING 30
+#define TSHOSTFOUND 31
+#define TSHOSTNOTFOUND 32
+#define TSCONNECTING 33
+#define TSHOSTCONNECTED 34
+#define TSPROXYCONNECTED 35
+#define TSPROXYAUTH 36
+#define TSPROXYFAIL 38
+#define TSREFUSED 39
+#define TSREADERROR 40
+#define TSCLOSED 41
+#define TSCLOSEFINISH 42
+#define TSCONNECTVIAPROXY 43
+#define TSEGETHOSTBYNAME 44
+#define TSEINIWINSOCK 45
+#define TSERROR 46
+#define TSPROXYERROR 47
+#define TSWRITED 48
+
+// zmodem types
+#define RcvByteCount 0 /* value is # bytes received */
+#define SndByteCount 1 /* value is # bytes sent */
+#define RcvTimeout 2 /* receiver did not respond, aborting */
+#define SndTimeout 3 /* value is # of consecutive send timeouts */
+#define RmtCancel 4 /* remote end has cancelled */
+#define ProtocolErr 5 /* protocol error has occurred, val=hdr */
+#define RemoteMessage 6 /* message from remote end */
+#define DataErr 7 /* data error, val=error count */
+#define FileErr 8 /* error writing file, val=errno */
+#define FileBegin 9 /* file transfer begins, str=name */
+#define FileEnd 10 /* file transfer ends, str=name */
+#define FileSkip 11 /* file being skipped, str=name */
+
+
+// proxy type
+#define NOPROXY 0
+#define WINGATE 1
+#define SOCKS4 2
+#define SOCKS5 3
+#define HTTP 4
+
+// UI ID
+#define ID_FILE_CONNECT 0x00
+#define ID_FILE_DISCONNECT 0x01
+#define ID_FILE_ADDRESS 0x02
+#define ID_FILE_QUICK 0x03
+#define ID_FILE_EXIT 0x04
+
+#define ID_EDIT_COPY 0x10
+#define ID_EDIT_PASTE 0x11
+#define ID_EDIT_COLOR 0x12
+#define ID_EDIT_RECT 0x13
+#define ID_EDIT_AUTO 0x14
+#define ID_EDIT_WW 0x15
+
+#define ID_EDIT_ESC_NO 0x17
+#define ID_EDIT_ESC_ESC 0x18
+#define ID_EDIT_ESC_U 0x19
+#define ID_EDIT_ESC_CUS 0x1a
+
+#define ID_EDIT_CODEC_GBK 0x1b
+#define ID_EDIT_CODEC_BIG5 0x1c
+
+
+#define ID_VIEW_FONT 0x20
+#define ID_VIEW_COLOR 0x21
+#define ID_VIEW_REFRESH 0x22
+#define ID_VIEW_LANG 0x23
+#define ID_VIEW_FULL 0x24
+#define ID_VIEW_BOSS 0x25
+#define ID_VIEW_SCROLL_HIDE 0x26
+#define ID_VIEW_SCROLL_LEFT 0x27
+#define ID_VIEW_SCROLL_RIGHT 0x28
+#define ID_VIEW_SWITCH 0x29
+#define ID_VIEW_STATUS 0x3a
+
+#define ID_OPTION_CURRENT 0x30
+#define ID_OPTION_DEFAULT 0x31
+#define ID_OPTION_PREF 0x32
+
+#define ID_SPEC_ANTI 0x40
+#define ID_SPEC_AUTO 0x41
+#define ID_SPEC_MESSAGE 0x42
+#define ID_SPEC_BEEP 0x43
+#define ID_SPEC_MOUSE 0x44
+#define ID_SPEC_ARTICLE 0x45
+
+#define ID_SCRIPT_RUN 0x50
+#define ID_SCRIPT_STOP 0x51
+
+#define ID_HELP_ABOUT 0x60
+#define ID_HELP_HOMEPAGE 0x61
+
+//for open last addr
+#define LAST_ADDRESS_INDEX -321
+
+//script function names:
+#define SFN_ANTI_IDLE "antiIdle"
+#define SFN_ON_BELL "onBell"
+#define SFN_AUTO_REPLY "autoReply"
+#define SFN_DATA_EVENT "dataEvent"
+#define SFN_KEY_EVENT "keyEvent"
+#define SFN_MOUSE_EVENT "mouseEvent"
+#define SFN_DETECT_MENU "detectMenu"
+
+//script key event type
+#define SKET_KEY_PRESS 0
+
+//script mouse event type
+#define SMET_UNKOWN -1
+#define SMET_MOUSE_PRESS 0
+#define SMET_MOUSE_RELEASE 1
+#define SMET_MOUSE_MOVE 2
+#define SMET_MOUSE_DBCLICK 3
+#define SMET_WHEEL 4
+
+//script button state & key modifier
+#define SBS_LEFT_BUTTON 0x01
+#define SBS_RIGHT_BUTTON 0x02
+#define SBS_MID_BUTTON 0x04
+#define SBS_ALT 0x08
+#define SBS_CTRL 0x10
+#define SBS_SHIFT 0x20
+
+} // namespace FQTerm
+
+#endif // FQTERM_GLOBAL_H
diff --git a/src/common/fqterm_config.cpp b/src/common/fqterm_config.cpp
new file mode 100644
index 0000000..19e0db4
--- /dev/null
+++ b/src/common/fqterm_config.cpp
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QTextStream>
+#include <QFile>
+#include <QString>
+#include <QTextCodec>
+
+#include "fqterm_trace.h"
+#include "fqterm_config.h"
+
+namespace FQTerm {
+
+FQTermConfig::FQTermConfig(const QString &szFileName) {
+ load(szFileName);
+}
+
+FQTermConfig::~FQTermConfig(){
+
+}
+
+bool FQTermConfig::save(const QString &szFileName) {
+ QFile file(szFileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ FQ_TRACE("config", 0) << "Failed to open the file for writing: "
+ << szFileName;
+ return false;
+ }
+
+ QTextStream os;
+ os.setDevice(&file);
+ saveToStream(os);
+ // os.unsetDevice();
+ file.close();
+
+
+ return true;
+}
+
+bool FQTermConfig::loadFromStream(QTextStream &is) {
+ QString strLine, strSection;
+
+ data.clear();
+
+ is.setCodec(QTextCodec::codecForName("UTF-8"));
+
+ while (!is.atEnd()) {
+ strLine = is.readLine().trimmed();
+ if (strLine.isEmpty() || strLine[0] == '#') {
+ continue;
+ }
+
+ if (strLine.left(1) == "[" && strLine.right(1) == "]") {
+ strSection = strLine.mid(1, strLine.length() - 2);
+ addSection(strSection);
+ } else {
+ QString strValue = strLine.section('=', 1).trimmed();
+ setItemValue(strSection, strLine.section('=', 0, 0).trimmed(),
+ strValue.isNull() ? QString(""): strValue);
+ }
+ }
+ return true;
+}
+
+bool FQTermConfig::saveToStream(QTextStream &os) {
+ QString strLine, strSection;
+ Section::iterator iStr;
+
+ os.setCodec(QTextCodec::codecForName("UTF-8"));
+
+ for (StrSecMap::iterator iSec = data.begin(); iSec != data.end(); ++iSec) {
+ os << '[' << iSec.key() << "]\n";
+ for (iStr = iSec.value().begin(); iStr != iSec.value().end(); ++iStr) {
+ os << iStr.key() << '=' << iStr.value() << '\n';
+ }
+ os << '\n';
+ }
+ return true;
+}
+
+
+bool FQTermConfig::addSection(const QString &szSection) {
+ if (hasSection(szSection)) {
+ return false;
+ }
+ Section sec;
+ data[szSection] = sec;
+ return true;
+}
+
+bool FQTermConfig::hasSection(const QString &szSection) const
+{
+ return data.find(szSection) != data.end();
+}
+
+bool FQTermConfig::setItemValue(const QString &szSection, const QString
+ &szItemName, const QString &szItemValue) {
+ if (!hasSection(szSection))
+ if (!addSection(szSection)) {
+ return false;
+ }
+
+ data[szSection][szItemName] = szItemValue;
+ return true;
+}
+
+QString FQTermConfig::getItemValue(const QString &szSection,
+ const QString &szItemName) const {
+ if (hasSection(szSection))
+ if (data[szSection].find(szItemName) != data[szSection].end())
+ if (!data[szSection][szItemName].isEmpty()) {
+ return data[szSection][szItemName];
+ }
+ return "";
+}
+
+bool FQTermConfig::renameSection(const QString &szSection, const QString
+ &szNewName) {
+ if (hasSection(szNewName) || !hasSection(szSection)) {
+ return false;
+ }
+
+ if (!addSection(szNewName)) {
+ return false;
+ }
+ data[szNewName] = data[szSection];
+
+ return deleteSection(szSection);
+}
+
+bool FQTermConfig::deleteSection(const QString &szSection) {
+ if (hasSection(szSection)) {
+ data.remove(szSection);
+ return true;
+ }
+ return false;
+}
+
+bool FQTermConfig::deleteItem(const QString &szSection, const QString
+ &szItemName) {
+ if (hasSection(szSection))
+ if (data[szSection].find(szItemName) != data[szSection].end()) {
+ data[szSection].remove(szItemName);
+ return true;
+ }
+ return false;
+}
+
+bool FQTermConfig::load(const QString &filename) {
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ FQ_TRACE("config", 0) << "Failed to open the file for reading "
+ << filename;
+ return false;
+ }
+ QTextStream is;
+ is.setDevice(&file);
+ loadFromStream(is);
+ //is.unsetDevice();
+ file.close();
+ return true;
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_config.h b/src/common/fqterm_config.h
new file mode 100644
index 0000000..2f88602
--- /dev/null
+++ b/src/common/fqterm_config.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_CFG_H
+#define FQTERM_CFG_H
+
+#include <QTextStream>
+#include <QMap>
+#include <QObject>
+
+namespace FQTerm {
+typedef QMap<QString, QString> Section;
+typedef QMap<QString, Section> StrSecMap;
+
+class FQTermConfig {
+ private:
+ StrSecMap data;
+ bool loadFromStream(QTextStream &);
+ bool saveToStream(QTextStream &);
+
+ bool addSection(const QString &sectionName);
+ public:
+ FQTermConfig(const QString &fileName);
+ ~FQTermConfig();
+
+ bool load(const QString &filename);
+ bool save(const QString &fileName);
+
+ bool setItemValue(const QString &sectionName, const QString &itemName,
+ const QString &itemValue);
+
+ QString getItemValue(const QString &sectionName,
+ const QString &itemName) const;
+
+ bool deleteItem(const QString &sectionName, const QString &itemName);
+ bool deleteSection(const QString &sectionName);
+
+ bool renameSection(const QString &sectionName, const QString &newName);
+ bool hasSection(const QString &sectionName) const;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_CFG_H
diff --git a/src/common/fqterm_exif_extractor.cpp b/src/common/fqterm_exif_extractor.cpp
new file mode 100644
index 0000000..05d318e
--- /dev/null
+++ b/src/common/fqterm_exif_extractor.cpp
@@ -0,0 +1,647 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_exif_extractor.h"
+
+namespace FQTerm {
+
+const ExifExtractor::uint16 ExifExtractor::IFD0Tag[16] = {0x010e, 0x010f, 0x0110, 0x0112, 0x011a,
+ 0x011b, 0x0128, 0x0131, 0x0132, 0x013e,
+ 0x013f, 0x0211, 0x0213, 0x0214, 0x8298, 0x8769
+};
+
+const char ExifExtractor::IFD0TagName[16][30] = { "ImageDescription", "Make", "Model", "Orientation",
+ "XResolution", "YResolution", "ResolutionUnit", "Software",
+ "DateTime", "WhitePoint", "PrimaryChromaticities", "YCbCrCoefficients",
+ "YCbCrPositioning", "ReferenceBlackWhite", "Copyright", "ExifOffset"
+};
+
+const ExifExtractor::uint16 ExifExtractor::SubIFDTag[38] = {0x829a,0x829d,0x8822,0x8827,0x9000,0x9003,0x9004,0x9101,0x9102,0x9201,0x9202,0x9203,0x9204,
+ 0x9205,0x9206,0x9207,0x9208,0x9209,0x920a,0x927c,0x9286,0x9290,0x9291,0x9292,0xa000,0xa001,
+ 0xa002,0xa003,0xa004,0xa005,0xa20e,0xa20f,0xa210,0xa215,0xa217,0xa300,0xa301,0xa302};
+
+const char ExifExtractor::SubIFDTagName[38][30] = {"ExposureTime","FNumber","ExposureProgram","ISOSpeedRatings","ExifVersion","DateTimeOriginal","DateTimeDigitized",
+ "ComponentsConfiguration","CompressedBitsPerPixel","ShutterSpeedValue","ApertureValue","BrightnessValue","ExposureBiasValue",
+ "MaxApertureValue","SubjectDistance","MeteringMode","LightSource","Flash","FocalLength","MakerNote","UserComment","SubsecTime",
+ "SubsecTimeOriginal","SubsecTimeDigitized","FlashPixVersion","ColorSpace","ExifImageWidth","ExifImageHeight","RelatedSoundFile",
+ "ExifInteroperabilityOffset","FocalPlaneXResolution","FocalPlaneYResolution","FocalPlaneResolutionUnit","ExposureIndex",
+ "SensingMethod","FileSource","SceneType","CFAPattern"};
+
+const char ExifExtractor::exifHeaderStandard[6] = {'E', 'x', 'i', 'f', '\0', '\0'};
+
+ExifExtractor::ExifExtractor()
+{
+ exifFile_ = NULL;
+ reset();
+}
+
+ExifExtractor::~ExifExtractor()
+{
+ reset();
+}
+
+std::string ExifExtractor::extractExifInfo(std::string fileName) {
+ return extractExifInfo(fopen(fileName.c_str(), "rb"));
+}
+
+std::string ExifExtractor::extractExifInfo(FILE* file) {
+ reset();
+ exifFile_ = file;
+ if (!exifFile_ || !isReadable() || !checkEndian()) {
+ return exifInformation_;
+ }
+ if (!readIFD0())
+ return exifInformation_;
+ readSubIFD();
+ postRead();
+ std::map<std::string, std::string>::iterator ii;
+ for (ii = exifKeyValuePairs_.begin();
+ ii != exifKeyValuePairs_.end();
+ ++ii) {
+ if ((*ii).first == "UserComment") {
+ continue;
+ }
+ exifInformation_ += (*ii).first + " : " + (*ii).second + "\n";
+ }
+ fclose(exifFile_);
+ exifFile_ = NULL;
+ return exifInformation_;
+}
+std::string ExifExtractor::info() {
+ return exifInformation_;
+}
+
+std::string ExifExtractor::operator[]( const std::string& key ) {
+ std::map<std::string, std::string>::iterator ii;
+ if ((ii = exifKeyValuePairs_.find(key)) != exifKeyValuePairs_.end()) {
+ return (*ii).second;
+ }
+ return "";
+}
+
+void ExifExtractor::postRead() {
+ std::map<std::string, std::string>::iterator ii;
+ if ((ii = exifKeyValuePairs_.find("Orientation")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "1st row - 1st col : top - left side"; break;
+ case '2': (*ii).second = "1st row - 1st col : top - right side"; break;
+ case '3': (*ii).second = "1st row - 1st col : bottom - right side"; break;
+ case '4': (*ii).second = "1st row - 1st col : bottom - left side"; break;
+ case '5': (*ii).second = "1st row - 1st col : left side - top"; break;
+ case '6': (*ii).second = "1st row - 1st col : right side - top"; break;
+ case '7': (*ii).second = "1st row - 1st col : right side - bottom"; break;
+ case '8': (*ii).second = "1st row - 1st col : left side - bottom"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ResolutionUnit")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "no-unit"; break;
+ case '2': (*ii).second = "inch"; break;
+ case '3': (*ii).second = "centimeter"; break;
+ default: (*ii).second = "inch"; break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("DateTime")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ for (size_t i = 0; i < (*ii).second.length() && i < 11; ++i) {
+ if ((*ii).second[i] == ':'){
+ (*ii).second[i] = '.';
+ }
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("DateTimeOriginal")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ for (size_t i = 0; i < (*ii).second.length() && i < 11; ++i) {
+ if ((*ii).second[i] == ':'){
+ (*ii).second[i] = '.';
+ }
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("DateTimeDigitized")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ for (size_t i = 0; i < (*ii).second.length() && i < 11; ++i) {
+ if ((*ii).second[i] == ':'){
+ (*ii).second[i] = '.';
+ }
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("YCbCrPositioning")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "The center of pixel array"; break;
+ case '2': (*ii).second = "The datum point"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("MeteringMode")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ uint16 value = 123;
+ sscanf((*ii).second.c_str(), "%hu", &value);
+ switch(value) {
+ case 0: (*ii).second = "Unknown"; break;
+ case 1: (*ii).second = "Average"; break;
+ case 2: (*ii).second = "CenterWeightedAverage"; break;
+ case 3: (*ii).second = "Spot"; break;
+ case 4: (*ii).second = "Multi-spot"; break;
+ case 5: (*ii).second = "Pattern"; break;
+ case '6': (*ii).second = "Partial"; break;
+ case 255: (*ii).second = "Other"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("LightSource")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ uint16 value = 123;
+ sscanf((*ii).second.c_str(), "%hu", &value);
+ switch(value) {
+ case 0: (*ii).second = "unknown"; break;
+ case 1: (*ii).second = "daylight"; break;
+ case 2: (*ii).second = "fluorescent"; break;
+ case 3: (*ii).second = "tungsten"; break;
+ case 10: (*ii).second = "flash"; break;
+ case 17: (*ii).second = "standard light A"; break;
+ case 18: (*ii).second = "standard light B"; break;
+ case 19: (*ii).second = "standard light C"; break;
+ case 20: (*ii).second = "D55"; break;
+ case 21: (*ii).second = "D65"; break;
+ case 22: (*ii).second = "D75"; break;
+ case 255: (*ii).second = "other"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("Flash")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ uint16 value = 123;
+ sscanf((*ii).second.c_str(), "%hu", &value);
+ value &= 0x07;
+ switch(value) {
+ case 0: (*ii).second = "Flash did not fire"; break;
+ case 1: (*ii).second = "Flash fired"; break;
+ case 5: (*ii).second = "Flash fired but strobe return light not detected"; break;
+ case 7: (*ii).second = "Flash fired and strobe return light detected"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ColorSpace")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "sRGB color space"; break;
+ case '6': (*ii).second = "Uncalibrated"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("FocalPlaneResolutionUnit")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '1': (*ii).second = "no-unit"; break;
+ case '2': (*ii).second = "inch"; break;
+ case '3': (*ii).second = "centimeter"; break;
+ default: exifKeyValuePairs_.erase(ii); break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("SensingMethod")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ switch((*ii).second[0]) {
+ case '2': (*ii).second = "1 chip color area sensor"; break;
+ default: (*ii).second = "other"; break;
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ExifVersion")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ (*ii).second = 'V' + (*ii).second.substr(0, 2) + '.' + (*ii).second.substr(2);
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ComponentsConfiguration")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ static const char CCName[7][10] = {"", "[Y]", "[Cb]", "[Cr]", "[Red]", "[Green]", "[Blue]"};
+ std::string cc;
+ for(int i = 0; i < 4; ++i) {
+ int index = (*ii).second[i];
+ if (index < 0 || index >= 7) {
+ index = 0;
+ }
+ cc += CCName[index];
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("ExifVersion")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ (*ii).second = 'V' + (*ii).second.substr(0, 2) + '.' + (*ii).second.substr(2);
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("MakerNote")) != exifKeyValuePairs_.end()) {
+ exifKeyValuePairs_.erase(ii);
+ }
+ if ((ii = exifKeyValuePairs_.find("CFAPattern")) != exifKeyValuePairs_.end()) {
+ exifKeyValuePairs_.erase(ii);
+ }
+ if ((ii = exifKeyValuePairs_.find("UserComment")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() < 8) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ //Leave it to higher level which can deal with encoding.
+ //"\0x41\0x53\0x43\0x49\0x49\0x00\0x00\0x00"//ASCII
+ //"\0x4a\0x49\0x53\0x00\0x00\0x00\0x00\0x00"//JIS
+ //"\0x55\0x4e\0x49\0x43\0x4f\0x44\0x45\0x00"//Unicode
+ //"\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00"//Undefined
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("FlashPixVersion")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 4) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ (*ii).second = 'V' + (*ii).second.substr(0, 2) + '.' + (*ii).second.substr(2);
+ }
+ }
+ //FileSource
+ if ((ii = exifKeyValuePairs_.find("FileSource")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ if ((*ii).second[0] == '\003') {
+ (*ii).second = "Digital still camera";
+ } else {
+ exifKeyValuePairs_.erase(ii);
+ }
+ }
+ }
+ if ((ii = exifKeyValuePairs_.find("SceneType")) != exifKeyValuePairs_.end()) {
+ if ((*ii).second.length() != 1) {
+ exifKeyValuePairs_.erase(ii);
+ } else {
+ if ((*ii).second[0] == '\001') {
+ (*ii).second = "Directly photographed";
+ } else {
+ exifKeyValuePairs_.erase(ii);
+ }
+ }
+ }
+
+}
+
+std::string ExifExtractor::readInfo() {
+ uint32 count;
+ uint32 offset;
+ uint16 shortValue;
+ uint32 longValue;
+ uint32 urationalp;
+ uint32 urationalc;
+ uint32 urationalgcd;
+ int32 rationalp;
+ int32 rationalc;
+ int32 rationalgcd;
+ int32 sign;
+ DATATYPE dataType;
+ char* buffer;
+ std::string ret = "";
+
+ if (!read(&shortValue, 2,1) || shortValue == 0 || shortValue > MAXGUARD) {
+ return ret;
+ }
+ dataType = (DATATYPE)shortValue;
+
+ if (!read(&count, 4,1)) {
+ return ret;
+ }
+
+ switch(dataType) {
+ case UNDEFINED:
+ buffer = new char[count + 1];
+
+ if (count < 4) {
+ if (!read(buffer, 1, count)) {
+ return ret;
+ }
+ } else {
+ if (!read(&offset, 4, 1)) {
+ return ret;
+ }
+ seek(12 + offset, SEEK_SET);
+ memset(buffer, 0, count + 1);
+ read(buffer, 1, count);
+ }
+ ret = std::string(buffer, count);
+ delete []buffer;
+ break;
+ case ASCIISTRING:
+ if (!read(&offset, 4, 1)) {
+ break;
+ }
+ seek(12 + offset, SEEK_SET);
+ buffer = new char[count + 1];
+ memset(buffer, 0, count + 1);
+ read(buffer, 1, count);
+ ret = buffer;
+ delete []buffer;
+ break;
+ case UNSIGNEDINT16:
+ if (!read(&shortValue, 2, 1)) {
+ break;
+ }
+ buffer = new char[256];
+ sprintf(buffer, "%hu", shortValue);
+ ret = buffer;
+ delete []buffer;
+ break;
+ case UNSIGNEDINT32:
+ if (!read(&longValue, 4, 1)) {
+ break;
+ }
+ buffer = new char[256];
+ sprintf(buffer, "%u", longValue);
+ ret = buffer;
+ delete []buffer;
+
+ break;
+ case UNSIGNEDRATIONAL:
+ if (!read(&offset, 4, 1)) {
+ break;
+ }
+ seek(12 + offset, SEEK_SET);
+ if (!read(&urationalc, 4, 1)) {
+ break;
+ }
+ if (!read(&urationalp, 4, 1)) {
+ break;
+ }
+ urationalgcd = gcd(urationalp, urationalc);
+ if (urationalgcd == 0) urationalgcd = 1;
+ buffer = new char[256];
+ sprintf(buffer, "%u/%u", urationalc / urationalgcd, urationalp / urationalgcd);
+ ret = buffer;
+ delete []buffer;
+ break;
+ case RATIONAL:
+ if (!read(&offset, 4, 1)) {
+ break;
+ }
+ sign = 1;
+ seek(12 + offset, SEEK_SET);
+ if (!read(&rationalc, 4, 1)) {
+ break;
+ }
+ if (rationalc < 0) {
+ sign *= -1;
+ rationalc = -rationalc;
+ }
+ if (!read(&rationalp, 4, 1)) {
+ break;
+ }
+ if (rationalp < 0) {
+ sign *= -1;
+ rationalp = -rationalp;
+ }
+ rationalgcd = gcd(rationalp, rationalc);
+ if (rationalgcd == 0) rationalgcd = 1;
+ buffer = new char[256];
+ sprintf(buffer, "%d/%d", sign * rationalc / rationalgcd, rationalp / rationalgcd);
+ ret = buffer;
+ delete []buffer;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+bool ExifExtractor::analyzeIFD0TagInfo() {
+ bool res = true;
+ uint16 tag;
+ if (!read(&tag, 2, 1))
+ res = false;
+ int index;
+ for (index = 0; index < 16; ++index) {
+ if (IFD0Tag[index] == tag) {
+ break;
+ }
+ }
+ if (index == 16) {
+ res = false;
+ }
+ long pos = ftell(exifFile_) + 10;
+
+ if (res) {
+ std::string info = readInfo();
+ if (info != "")
+ exifKeyValuePairs_[IFD0TagName[index]] = info;
+ }
+
+ seek(pos, SEEK_SET);
+ return res;
+}
+
+bool ExifExtractor::analyzeSubIFDTagInfo() {
+ bool res = true;
+ uint16 tag;
+ if (!read(&tag, 2, 1))
+ res = false;
+ int index;
+ for (index = 0; index < 38; ++index) {
+ if (SubIFDTag[index] == tag) {
+ break;
+ }
+ }
+ if (index == 38) {
+ res = false;
+ }
+ long pos = ftell(exifFile_) + 10;
+
+ if (res) {
+ std::string info = readInfo();
+ if (info != "")
+ exifKeyValuePairs_[SubIFDTagName[index]] = info;
+ }
+
+ seek(pos, SEEK_SET);
+ return res;
+}
+
+bool ExifExtractor::readIFD0() {
+ seek(16, SEEK_SET);
+ if (!read(&ifdOffset_, 4, 1)) {
+ return false;
+ }
+ seek(ifdOffset_ + 12, SEEK_SET);
+ uint16 entryCount = 0;
+ if (!read(&entryCount, 2, 1)) {
+ return false;
+ }
+ int app1Entry = entryCount;
+ while (app1Entry >= 0) {
+ analyzeIFD0TagInfo();
+ app1Entry--;
+ }
+ return true;
+}
+
+bool ExifExtractor::readSubIFD() {
+ std::map<std::string, std::string>::iterator ii;
+ if ((ii = exifKeyValuePairs_.find("ExifOffset")) == exifKeyValuePairs_.end()) {
+ return false;
+ }
+ uint32 exifOffset = 0;
+ sscanf((*ii).second.c_str(), "%u", &exifOffset);
+ seek(12 + exifOffset, SEEK_SET);
+
+ uint16 entryCount = 0;
+ if (!read(&entryCount, 2, 1)) {
+ return false;
+ }
+ int app1Entry = entryCount;
+ while (app1Entry >= 0) {
+ analyzeSubIFDTagInfo();
+ app1Entry--;
+ }
+ return true;
+}
+
+bool ExifExtractor::isReadable() {
+ rewind();
+ unsigned char soi[2];
+ if (!read(soi, 2, 1))
+ return false;
+ if (soi[0] != 0xFF || soi[1] != 0xD8) {
+ return false;
+ }
+ unsigned char app1[2];
+ if (!read(app1, 2, 1))
+ return false;
+ if (app1[0] != 0xFF || app1[1] != 0xE1) {
+ return false;
+ }
+ seek(2, SEEK_CUR);
+ char exifHeader[6];
+ if (!read(exifHeader, 1, 6)) {
+ return false;
+ }
+ for (int i = 0; i < 6; ++i) {
+ if (exifHeader[i] != exifHeaderStandard[i])
+ return false;
+ }
+ return true;
+}
+
+bool ExifExtractor::checkEndian() {
+ toggle_ = false;
+ seek(12, SEEK_SET);
+ uint16 endian = 0;
+ if (!read(&endian, 2, 1)) {
+ return false;
+ }
+ if (endian == 0x4949) {
+ //II
+ toggle_ = false;
+ }
+ else if (endian == 0x4d4d) {
+ //MM
+ toggle_ = true;
+ }
+ return true;
+}
+
+void ExifExtractor::toggleEndian( void* buf, size_t s ) {
+ char* buffer = (char*)buf;
+ if (!toggle_) {
+ return;
+ }
+ for (size_t i = 0; i < s / 2; ++i) {
+ char tmp;
+ tmp = buffer[i];
+ buffer[i] = buffer[s - i - 1];
+ buffer[s - i - 1] = tmp;
+ }
+}
+
+void ExifExtractor::reset() {
+ toggle_ = false;
+ exifKeyValuePairs_.clear();
+ if (exifFile_) {
+ fclose(exifFile_);
+ exifFile_ = NULL;
+ }
+ ifdOffset_ = 0;
+ exifInformation_.clear();
+}
+
+bool ExifExtractor::read( void* buffer, size_t elementSize, size_t count ) {
+ for (size_t i = 0; i < count; ++i) {
+ if (fread((char*)buffer + i * elementSize, elementSize, 1, exifFile_) != 1)
+ return false;
+ toggleEndian((char*)buffer + i * elementSize, elementSize);
+ }
+ return true;
+}
+
+void ExifExtractor::seek( long offset, int origin ) {
+ fseek(exifFile_, offset, origin);
+}
+
+void ExifExtractor::rewind() {
+ ::rewind(exifFile_);
+}
+} //namespace FQTerm
diff --git a/src/common/fqterm_exif_extractor.h b/src/common/fqterm_exif_extractor.h
new file mode 100644
index 0000000..7f05798
--- /dev/null
+++ b/src/common/fqterm_exif_extractor.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_EXIF_EXTRACTOR
+#define FQTERM_EXIF_EXTRACTOR
+
+//#include <QtGlobal>
+
+#include "fqterm_trace.h"
+
+#include <iostream>
+#include <vector>
+#include <stdio.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <map>
+#include <string>
+//using namespace std;
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdint>
+#endif
+
+namespace FQTerm {
+
+class ExifExtractor
+{
+public:
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ typedef std::uint32_t uint32;
+ typedef std::uint16_t uint16;
+ typedef std::int32_t int32;
+ typedef std::int16_t int16;
+#elif defined(QT_VERSION)
+ typedef quint32 uint32;
+ typedef quint16 uint16;
+ typedef qint32 int32;
+ typedef qint16 int16;
+#else
+ typedef unsigned int uint32;
+ typedef unsigned short int uint16;
+ typedef short int int16;
+ typedef int int32;
+#endif
+
+ enum DATATYPE {ZEORGARD = 0, UNSIGNEDCHAR = 1, ASCIISTRING = 2, UNSIGNEDINT16 = 3, UNSIGNEDINT32 = 4,
+ UNSIGNEDRATIONAL = 5, SIGNEDCHAR = 6, UNDEFINED = 7, SIGNEDSHORT = 8, SIGNEDLONG = 9, RATIONAL = 10,
+ SIGNEDFLOAT = 11, DOUBLEFLOAT = 12, MAXGUARD = 13};
+
+
+ ExifExtractor();
+ ~ExifExtractor();
+ std::string extractExifInfo(std::string fileName);
+ std::string extractExifInfo(FILE* file);
+
+ std::string info();
+
+ std::string operator[](const std::string& key);
+
+private:
+ void postRead();
+
+ std::string readInfo();
+ bool analyzeIFD0TagInfo();
+
+ bool analyzeSubIFDTagInfo();
+
+ bool readIFD0();
+ bool readSubIFD();
+ bool isReadable();
+ bool checkEndian();
+ void toggleEndian(void* buf, size_t s);
+
+ void reset();
+
+ bool read(void* buffer, size_t elementSize, size_t count);
+
+ void seek(long offset, int origin);
+
+ void rewind();
+
+ template<class T>
+ T gcd(T a, T b) {
+ if (a == 0 || b == 0)
+ return a + b;
+ return gcd(b, a % b);
+ }
+
+
+ bool toggle_;
+ std::map<std::string, std::string> exifKeyValuePairs_;
+ FILE* exifFile_;
+ uint32 ifdOffset_;
+ uint32 subIfdOffset_;
+
+ static const uint16 IFD0Tag[16];
+ static const char IFD0TagName[16][30];
+ static const uint16 SubIFDTag[38];
+ static const char SubIFDTagName[38][30];
+ static const char exifHeaderStandard[6];
+
+ std::string exifInformation_;
+};
+
+
+
+} //namespace FQTerm
+
+#endif
diff --git a/src/common/fqterm_filedialog.cpp b/src/common/fqterm_filedialog.cpp
new file mode 100644
index 0000000..958fff9
--- /dev/null
+++ b/src/common/fqterm_filedialog.cpp
@@ -0,0 +1,157 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_filedialog.h"
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+
+/*
+ * Constructs a articleDialog as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+namespace FQTerm {
+
+FQTermFileDialog::FQTermFileDialog(FQTermConfig *config, QWidget *parent, Qt::WFlags fl)
+ : QFileDialog(parent, fl) {
+
+ configDir = getPath(USER_CONFIG) + "/";
+ userConfig = configDir + "fqterm.cfg";
+ strSection = "previous";
+ strSave = "save";
+ strOpen = "open";
+ config_ = config;
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+FQTermFileDialog::~FQTermFileDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+
+QString FQTermFileDialog::getSaveName(const QString &fileToSave, const QString &hints, QWidget *widget) {
+ QString saveFile;
+ QString strPrevSave, saveName;
+ QFileDialog fileDialog(widget);
+
+ if (config_->load(userConfig)) {
+ strPrevSave = config_->getItemValue(strSection, strSave);
+ }
+
+ QString strTmp(fileToSave);
+#if !defined(Q_OS_WIN32) || !defined(_OS_WIN32_)
+ if (strTmp.toLocal8Bit().contains("/")) {
+ strTmp.replace(QString("/"), QString("_"));
+ }
+#endif
+
+ if (strPrevSave.isEmpty()) {
+ saveFile = configDir + strTmp;
+ } else {
+ saveFile = strPrevSave + "/" + strTmp;
+ }
+
+ QString realHints = (hints.isEmpty() ? "*" : hints);
+ saveName = fileDialog.getSaveFileName(widget,
+ tr("Save As..."),
+ saveFile, realHints);
+
+ QFileInfo fi(saveName);
+
+ if (!saveName.isEmpty()) {
+ config_->setItemValue(strSection, strSave, fi.absolutePath());
+ config_->save(userConfig);
+ }
+
+ return saveName;
+}
+
+QString FQTermFileDialog::getOpenName(const QString &title, const QString &hints, QWidget *widget) {
+ QString strPrevOpen;
+ QString openName;
+ QFileDialog fileDialog(widget);
+
+ strPrevOpen = (config_->load(userConfig) ? config_->getItemValue(strSection, strOpen) : "./");
+
+ QString realHints = (hints.isEmpty() ? "*" : hints);
+ QString realTitle = (title.isEmpty() ? "Choose a file to open" : title);
+ openName = fileDialog.getOpenFileName(widget, realTitle, strPrevOpen, realHints);
+
+ if (!openName.isEmpty()) {
+ config_->setItemValue(strSection, strOpen, QFileInfo(openName).absolutePath());
+ config_->save(userConfig);
+ }
+
+ return openName;
+}
+
+QStringList FQTermFileDialog::getOpenNames(const QString &title, const QString &hints, QWidget *widget) {
+ QString openDir, strPrevOpen;
+ QStringList openNames;
+ QFileDialog fileDialog(widget);
+
+ strPrevOpen = (config_->load(userConfig) ? config_->getItemValue(strSection, strOpen) : "./");
+
+ QString realHints = (hints.isEmpty() ? "*" : hints);
+ QString realTitle = (title.isEmpty() ? "Choose files to open" : title);
+ openNames = fileDialog.getOpenFileNames(widget, realTitle, strPrevOpen, realHints);
+
+ if (!openNames.isEmpty() && !openNames.at(0).isEmpty()) {
+ openDir = QFileInfo(openNames.at(0)).absolutePath();
+ config_->setItemValue(strSection, strOpen, openDir);
+ config_->save(userConfig);
+ }
+
+ return openNames;
+}
+
+QString FQTermFileDialog::getExistingDirectory(const QString &title, const QString &hints, QWidget *widget) {
+
+ QString strPrevOpen;
+ QFileDialog fileDialog(widget);
+
+ if (hints.isEmpty()) {
+ strPrevOpen = (config_->load(userConfig) ? config_->getItemValue(strSection, strOpen) : "./");
+ } else {
+ strPrevOpen = hints;
+ }
+
+ QString realTitle = (title.isEmpty() ? "Open a directory" : title);
+ QString dir = fileDialog.getExistingDirectory(widget,
+ realTitle,
+ strPrevOpen,
+ QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
+
+ if (!dir.isEmpty()) {
+ config_->setItemValue(strSection, strOpen, QFileInfo(dir).absolutePath());
+ config_->save(userConfig);
+ }
+
+ return dir;
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_filedialog.h b/src/common/fqterm_filedialog.h
new file mode 100644
index 0000000..5248ffd
--- /dev/null
+++ b/src/common/fqterm_filedialog.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FILEDIALOG_H
+#define FQTERM_FILEDIALOG_H
+
+#include <QFileDialog>
+#include <QMessageBox>
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class FQTermFileDialog: public QFileDialog {
+public:
+ FQTermFileDialog(FQTermConfig *config, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~FQTermFileDialog();
+
+ QString getSaveName(const QString &filename, const QString &hints, QWidget *widget = 0);
+ QString getOpenName(const QString &title, const QString &hints, QWidget *widget = 0);
+ QStringList getOpenNames(const QString &title, const QString &hints, QWidget *widget = 0);
+ QString getExistingDirectory(const QString &title, const QString &hints, QWidget *widget = 0);
+
+private:
+ QString strSection, strSave, strOpen;
+ FQTermConfig *config_;
+ QString configDir, userConfig;
+};
+
+} // name space FQTerm
+
+#endif // FQTERM_FILEEDIALOG_H
diff --git a/src/common/fqterm_font.cpp b/src/common/fqterm_font.cpp
new file mode 100644
index 0000000..f2dcfbd
--- /dev/null
+++ b/src/common/fqterm_font.cpp
@@ -0,0 +1,261 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <list>
+#include <set>
+#include <utility>
+#include <map>
+
+#include <QFontDatabase>
+#include <QFontInfo>
+#include <QFile>
+#include <QTextStream>
+#include <QTextCodec>
+#include <QLocale>
+
+#include "fqterm_trace.h"
+#include "fqterm_font.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+
+using namespace std;
+
+namespace FQTerm {
+
+namespace Font {
+
+enum Language{US_ENGLISH = 0,
+ SIMPLIFIED_CHINESE,
+ LANGUAGE_COUNT };
+
+QString getLanguageName(Language lang) {
+ switch (lang){
+ case US_ENGLISH:
+ return "en_US";
+ case SIMPLIFIED_CHINESE:
+ return "zh_CN";
+ default:
+ return "C";
+ }
+}
+
+Language getLanguageByName(QString langName) {
+ if (langName == "zh_CN") {
+ return SIMPLIFIED_CHINESE;
+ }
+ if (langName == "en_US") {
+ return US_ENGLISH;
+ }
+ return LANGUAGE_COUNT;
+}
+
+} // namespace Language
+
+typedef set<Font::Language> LanguageSet;
+typedef map<QString, pair<QString, LanguageSet> > FontLanguagesList;
+
+typedef map<QString, map<Font::Language, QStringList> > FontSets;
+
+// This function will be called only once.
+static const FontSets &getPreferedFontSets() {
+ static FontSets font_sets;
+ const QString &res_path = getPath(RESOURCE);
+
+ QString filename = res_path + "default_font.conf";
+
+ if (!QFile::exists(filename)) {
+ filename = res_path + "/dict/" + "default_font.conf";
+ }
+
+
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ FQ_TRACE("font", 0) << "Failed to open the default font configurations file:"
+ << filename;
+ return font_sets;
+ }
+
+ QTextStream is;
+ is.setDevice(&file);
+ is.setCodec(QTextCodec::codecForName("UTF-8"));
+
+#if defined(WIN32)
+ QString expected_section = "Windows";
+#elif defined(__APPLE__)
+ QString expected_section = "Apple";
+#else
+ QString expected_section = "Linux";
+#endif
+
+ QString line;
+
+ QString current_section;
+ while (!is.atEnd()) {
+ line = is.readLine().trimmed();
+ if (line.isEmpty() || line[0] == '#') {
+ continue;
+ }
+
+ if (line.left(1) == "[" && line.right(1) == "]") {
+ current_section = line.mid(1, line.length() - 2);
+ continue;
+ }
+
+ if (current_section == expected_section) {
+ QString en_font = line.section('=', 0, 0).trimmed().toLower();
+ QString fonts_for_lang = line.section('=', 1).trimmed();
+
+ map<Font::Language, QStringList> &font_set = font_sets[en_font];
+
+ QString lang = fonts_for_lang.section(":", 0, 0).trimmed();
+ QString fonts = fonts_for_lang.section(":", 1).trimmed();
+
+ QStringList font_list = fonts.split(",", QString::SkipEmptyParts);
+
+ for (int i = 0; i < font_list.size(); ++i) {
+ font_list[i] = font_list[i].trimmed();
+ }
+
+ font_set[Font::getLanguageByName(lang)] = font_list;
+ }
+ }
+
+ return font_sets;
+}
+
+#if 0
+//Not used
+static int outputAllSystemFonts(const QStringList &fonts) {
+ if (isAllowedCategory("font", 9)) {
+ for (int i = 0; i < fonts.size(); ++i) {
+ FQ_TRACE("font", 9) << "Found a font: "
+ << (QFontInfo(QFont(fonts.at(i))).fixedPitch() ?
+ "fixed-pitch " : "variable-pitch ")
+ << fonts.at(i);
+ }
+ }
+ return 0;
+}
+#endif
+
+static QStringList &getSystemFontFamilies() {
+ static QStringList list = QFontDatabase().families();
+ // static int tmp = outputAllSystemFonts(list);
+
+ return list;
+}
+
+static FontSets &getUserConfigFontSets() {
+ static FontSets font_sets = getPreferedFontSets();
+ return font_sets;
+}
+
+static QString getEnglishFontFamily() {
+ static const QStringList &families = getSystemFontFamilies();
+ static const FontSets &font_sets = getUserConfigFontSets();
+ static QString en_font_name;
+
+ if (!en_font_name.isEmpty()) {
+ return en_font_name;
+ }
+
+ FontSets::const_iterator it = font_sets.find("default");
+ if (it != font_sets.end()) {
+ map<Font::Language, QStringList>::const_iterator itt
+ = it->second.find(Font::US_ENGLISH);
+ if (itt != it->second.end()) {
+ for (int i = 0; i < itt->second.size(); ++i) {
+ const QString &font = itt->second[i];
+ if (families.contains(font)) {
+ en_font_name = font;
+ break;
+ }
+ }
+ }
+ }
+
+ return en_font_name;
+}
+
+
+static QString getFontFamilyForLang(Font::Language lang) {
+ static const QStringList &families = getSystemFontFamilies();
+ static const FontSets &font_sets = getUserConfigFontSets();
+
+ const QString en_font_name = getEnglishFontFamily();
+
+ if (lang == Font::US_ENGLISH) {
+ return en_font_name;
+ }
+
+ FontSets::const_iterator it = font_sets.find(en_font_name.toLower());
+ if (it != font_sets.end()) {
+ map<Font::Language, QStringList>::const_iterator itt
+ = it->second.find(lang);
+ if (itt != it->second.end()) {
+ for (int i = 0; i < itt->second.size(); ++i) {
+ const QString &font = itt->second[i];
+ if (families.contains(font)) {
+ return font;
+ } else {
+ FQ_TRACE("font", 5) << "Font " << font << " for "
+ << en_font_name << " not found.";
+ }
+ }
+ }
+ } else {
+ FQ_TRACE("font", 3) << "NO fontset for " << en_font_name << " found.";
+ }
+
+ return en_font_name;
+}
+
+QString getDefaultFontFamilyForLanguage(bool isEnglish) {
+ Font::Language lang = isEnglish ? Font::US_ENGLISH : Font::SIMPLIFIED_CHINESE;
+
+ static map<Font::Language, QString> langs_fonts_list;
+
+ map<Font::Language, QString>::iterator it = langs_fonts_list.find(lang);
+ if (it == langs_fonts_list.end()) {
+ langs_fonts_list.insert(
+ make_pair(lang, getFontFamilyForLang(lang)));
+ it = langs_fonts_list.find(lang);
+
+ FQ_TRACE("font", 3) << "Defaut font for "
+ << Font::getLanguageName(lang)
+ << " is: "
+ << it->second
+ << " (" << it->second.size() << ")";
+ }
+
+ return it->second;
+}
+
+#if 0
+//Not used.
+static Font::Language getCurrentSystemLanguage() {
+ if (QLocale::system().language() == QLocale::Chinese) {
+ return Font::SIMPLIFIED_CHINESE;
+ }
+
+ return Font::US_ENGLISH;
+}
+#endif
+} // namespace FQTerm
diff --git a/src/common/fqterm_font.h b/src/common/fqterm_font.h
new file mode 100644
index 0000000..7d28ffb
--- /dev/null
+++ b/src/common/fqterm_font.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FONT_H
+#define FQTERM_FONT_H
+
+#include <QString>
+
+#include "fqterm_param.h"
+
+namespace FQTerm {
+
+QString getDefaultFontFamilyForLanguage(bool isEnglish);
+
+} // namespace FQTerm
+
+#endif // FQTERM_FONT_H
diff --git a/src/common/fqterm_param.cpp b/src/common/fqterm_param.cpp
new file mode 100644
index 0000000..9490bdd
--- /dev/null
+++ b/src/common/fqterm_param.cpp
@@ -0,0 +1,274 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_param.h"
+#include "fqterm_font.h"
+
+namespace FQTerm {
+
+FQTermParam::FQTermParam() {
+ name_ = "NEW SMTH";
+ hostAddress_ = "newsmth.net";
+ port_ = 23;
+ hostType_ = 0; // 0--BBS 1--*NIX
+ isAutoLogin_ = false;
+ preLoginCommand_ = "";
+ userName_ = "";
+ password_ = "";
+ postLoginCommand_ = "";
+ // Display
+ serverEncodingID_ = 0;
+ isFontAutoFit_ = 1;
+ isAlwaysHighlight_ = 0;
+ isAnsiColor_ = 1;
+
+ englishFontName_ = getDefaultFontFamilyForLanguage(true);
+ englishFontSize_ = 14;
+ otherFontName_ = getDefaultFontFamilyForLanguage(false);
+ otherFontSize_ = 14;
+ alignMode_ = 0;
+ charSpacing_ = 0;
+ lineSpacing_ = 0;
+ //charRatio_ = 0;
+
+ backgroundColor_ = QColor(0, 0, 0);
+ foregroundColor_ = QColor(198, 195, 198);
+ schemaFileName_ = "";
+ // Terminal
+ virtualTermType_ = "vt102";
+ keyboardType_ = 0;
+ backspaceType_ = 0;
+ numColumns_ = 80;
+ numRows_ = 24;
+ numScrollLines_ = 240;
+ cursorType_ = 1; // 0--Block 1--Underline 2--I Type
+ escapeString_ = "^[^[[";
+ // Connection
+ proxyType_ = 0; // 0--None 1--Wingate 2--SOCKS4 3--SOCKS5 4--HTTP
+ proxyHostName_ = "";
+ proxyPort_ = 0;
+ isAuthentation_ = false;
+ proxyUserName_ = "";
+ proxyPassword_ = "";
+ protocolType_ = 0; // 0--Telnet 1--SSH1 2--SSH2
+ sshUserName_ = "";
+ sshPassword_ = "";
+ // Misc
+ maxIdleSeconds_ = 120;
+ replyKeyCombination_ = "^Z";
+ antiIdleMessage_ = "^@";
+ isAntiIdle_ = true;
+ isAutoReply_ = false;
+ autoReplyMessage_ = "(FQTerm) Sorry, I am not around";
+ isAutoReconnect_ = false;
+ reconnectInterval_ = 3;
+ retryTimes_ = 0;
+ isAutoCloseWin_ = false;
+ isAutoLoadScript_ = false;
+ enableZmodem_ = true;
+ autoLoadedScriptFileName_ = "";
+ isBeep_ = true;
+ isBuzz_ = false;
+
+ // Mouse
+ isSupportMouse_ = true;
+ // Mouse
+ menuType_ = 2;
+ menuColor_ = QColor(0, 65, 132);
+
+ isColorCopy_ = false;
+ isRectSelect_ = false;
+ isAutoCopy_ = true;
+ isAutoWrap_ = false;
+}
+
+FQTermParam::FQTermParam(const FQTermParam &param) {
+ copy(param);
+}
+
+FQTermParam::~FQTermParam(){}
+
+FQTermParam &FQTermParam::operator = (const FQTermParam &param) {
+ if (this == &param)
+ return *this;
+ copy(param);
+ return *this;
+}
+
+void FQTermParam::copy(const FQTermParam& param) {
+ name_ = param.name_;
+ hostAddress_ = param.hostAddress_;
+ port_ = param.port_;
+ hostType_ = param.hostType_; // 0--BBS 1--*NIX
+ isAutoLogin_ = param.isAutoLogin_;
+ preLoginCommand_ = param.preLoginCommand_;
+ userName_ = param.userName_;
+ password_ = param.password_;
+ postLoginCommand_ = param.postLoginCommand_;
+ // Display
+ serverEncodingID_ = param.serverEncodingID_;
+ isFontAutoFit_ = param.isFontAutoFit_;
+ isAlwaysHighlight_ = param.isAlwaysHighlight_;
+ isAnsiColor_ = param.isAnsiColor_;
+ englishFontName_ = param.englishFontName_;
+ englishFontSize_ = param.englishFontSize_;
+ otherFontName_ = param.otherFontName_;
+ otherFontSize_ = param.otherFontSize_;
+ alignMode_ = param.alignMode_;
+ charSpacing_ = param.charSpacing_;
+ lineSpacing_ = param.lineSpacing_;
+ //charRatio_ = param.charRatio_;
+ backgroundColor_ = param.backgroundColor_;
+ foregroundColor_ = param.foregroundColor_;
+ schemaFileName_ = param.schemaFileName_;
+ // Terminal
+ virtualTermType_ = param.virtualTermType_;
+ keyboardType_ = param.keyboardType_;
+ backspaceType_ = param.backspaceType_;
+ numColumns_ = param.numColumns_;
+ numRows_ = param.numRows_;
+ numScrollLines_ = param.numScrollLines_;
+ cursorType_ = param.cursorType_; // 0--Block 1--Underline 2--I Type
+ escapeString_ = param.escapeString_; // 0--ESC ESC 1--Ctrl+u
+ // Connection
+ proxyType_ = param.proxyType_;
+ // 0--None 1--Wingate 2--SOCKS4 3--SOCKS5 4--HTTP
+ proxyHostName_ = param.proxyHostName_;
+ proxyPort_ = param.proxyPort_;
+ isAuthentation_ = param.isAuthentation_;
+ proxyUserName_ = param.proxyUserName_;
+ proxyPassword_ = param.proxyPassword_;
+ protocolType_ = param.protocolType_; // 0--Telnet 1--SSH1 2--SSH2
+ sshUserName_ = param.sshUserName_;
+ sshPassword_ = param.sshPassword_;
+ // Misc
+ maxIdleSeconds_ = param.maxIdleSeconds_;
+ replyKeyCombination_ = param.replyKeyCombination_;
+ antiIdleMessage_ = param.antiIdleMessage_;
+ isAntiIdle_ = param.isAntiIdle_;
+ isAutoReply_ = param.isAutoReply_;
+ autoReplyMessage_ = param.autoReplyMessage_;
+ isAutoReconnect_ = param.isAutoReconnect_;
+ reconnectInterval_ = param.reconnectInterval_;
+ retryTimes_ = param.retryTimes_;
+ isAutoCloseWin_ = param.isAutoCloseWin_;
+ isAutoLoadScript_ = param.isAutoLoadScript_;
+ enableZmodem_ = param.enableZmodem_;
+ autoLoadedScriptFileName_ = param.autoLoadedScriptFileName_;
+ isBeep_ = param.isBeep_;
+ isBuzz_ = param.isBuzz_;
+
+ isSupportMouse_ = param.isSupportMouse_;
+ // Mouse
+ menuType_ = param.menuType_;
+ menuColor_ = param.menuColor_;
+
+ isColorCopy_ = param.isColorCopy_;
+ isRectSelect_ = param.isRectSelect_;
+ isAutoCopy_ = param.isAutoCopy_;
+ isAutoWrap_ = param.isAutoWrap_;
+}
+
+bool FQTermParam::operator==(const FQTermParam& param)
+{
+ if (name_ != param.name_) return false;
+ if (hostAddress_ != param.hostAddress_) return false;
+ if (port_ != param.port_) return false;
+ if (hostType_ != param.hostType_) return false;
+ if (isAutoLogin_ != param.isAutoLogin_) return false;
+ if (preLoginCommand_ != param.preLoginCommand_) return false;
+ if (userName_ != param.userName_) return false;
+ if (password_ != param.password_) return false;
+ if (postLoginCommand_ != param.postLoginCommand_) return false;
+ if (serverEncodingID_ != param.serverEncodingID_) return false;
+ if (isFontAutoFit_ != param.isFontAutoFit_) return false;
+ if (isAlwaysHighlight_ != param.isAlwaysHighlight_) return false;
+ if (isAnsiColor_ != param.isAnsiColor_) return false;
+ if (englishFontName_ != param.englishFontName_) return false;
+ if (englishFontSize_ != param.englishFontSize_) return false;
+ if (otherFontName_ != param.otherFontName_) return false;
+ if (otherFontSize_ != param.otherFontSize_) return false;
+ if (alignMode_ != param.alignMode_) return false;
+ if (charSpacing_ != param.charSpacing_) return false;
+ if (lineSpacing_ != param.lineSpacing_) return false;
+ if (backgroundColor_ != param.backgroundColor_) return false;
+ if (foregroundColor_ != param.foregroundColor_) return false;
+ if (schemaFileName_ != param.schemaFileName_) return false;
+ if (virtualTermType_ != param.virtualTermType_) return false;
+ if (keyboardType_ != param.keyboardType_) return false;
+ if (backspaceType_ != param.backspaceType_) return false;
+ if (numColumns_ != param.numColumns_) return false;
+ if (numRows_ != param.numRows_) return false;
+ if (numScrollLines_ != param.numScrollLines_) return false;
+ if (cursorType_ != param.cursorType_) return false;
+ if (escapeString_ != param.escapeString_) return false;
+ if (proxyType_ != param.proxyType_) return false;
+ if (proxyHostName_ != param.proxyHostName_) return false;
+ if (proxyPort_ != param.proxyPort_) return false;
+ if (isAuthentation_ != param.isAuthentation_) return false;
+ if (proxyUserName_ != param.proxyUserName_) return false;
+ if (proxyPassword_ != param.proxyPassword_) return false;
+ if (protocolType_ != param.protocolType_) return false;
+ if (sshUserName_ != param.sshUserName_) return false;
+ if (sshPassword_ != param.sshPassword_) return false;
+ if (maxIdleSeconds_ != param.maxIdleSeconds_) return false;
+ if (replyKeyCombination_ != param.replyKeyCombination_) return false;
+ if (antiIdleMessage_ != param.antiIdleMessage_) return false;
+ if (isAntiIdle_ != param.isAntiIdle_) return false;
+ if (isAutoReply_ != param.isAutoReply_) return false;
+ if (autoReplyMessage_ != param.autoReplyMessage_) return false;
+ if (isAutoReconnect_ != param.isAutoReconnect_) return false;
+ if (reconnectInterval_ != param.reconnectInterval_) return false;
+ if (retryTimes_ != param.retryTimes_) return false;
+ if (isAutoCloseWin_ != param.isAutoCloseWin_) return false;
+ if (isAutoLoadScript_ != param.isAutoLoadScript_) return false;
+ if (enableZmodem_ != param.enableZmodem_) return false;
+ if (isBuzz_ != param.isBuzz_) return false;
+ if (isBeep_ != param.isBeep_) return false;
+ if (isSupportMouse_ != param.isSupportMouse_) return false;
+ if (autoLoadedScriptFileName_ != param.autoLoadedScriptFileName_) return false;
+ if (menuType_ != param.menuType_) return false;
+ if (isColorCopy_ != param.isColorCopy_) return false;
+ if (isRectSelect_ != param.isRectSelect_) return false;
+ if (isAutoCopy_ != param.isAutoCopy_) return false;
+ if (isAutoWrap_ != param.isAutoWrap_) return false;
+ return true;
+}
+
+QString FQTermParam::getLanguageName(bool isEnglish, bool translate /* = true */)
+{
+ if (isEnglish) {
+ return QString(translate ? QObject::tr("&English") : "English");
+ }
+ return QString(translate ? QObject::tr("&Non-English") : "Non-English");
+}
+
+const FQTermParam& FQTermParam::getFQBBSParam() {
+ static bool inited = false;
+ static FQTermParam param;
+ if (!inited) {
+ param.name_ = "FQTermHelp";
+ param.hostAddress_ = "127.0.0.1";
+ param.port_ = 35172;
+ param.serverEncodingID_ = 2;
+ }
+ return param;
+}
+} // namespace FQTerm
diff --git a/src/common/fqterm_param.h b/src/common/fqterm_param.h
new file mode 100644
index 0000000..ef44f59
--- /dev/null
+++ b/src/common/fqterm_param.h
@@ -0,0 +1,221 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PARAM_H
+#define FQTERM_PARAM_H
+
+#include <QString>
+#include <QColor>
+
+namespace FQTerm {
+
+
+//The FQTerm Pref also contains global settings.
+//TODO: move all global settings into FQTermPref.
+struct FQTermPref {
+ static FQTermPref* getInstance()
+ {
+ //Though Singleton, I didn't define a ctor and make it private
+ //Why?
+ //I'm lazy.
+ static FQTermPref* pThis = new FQTermPref();
+ return pThis;
+ }
+ int displayOffset_;
+ int vsetting_;
+ int imeEncodingID_; // 0--GBK 1--BIG5
+ int widthToWrapWord_;
+ // bool bSmartWW;
+ bool isWheelSupported_;
+ bool openWarnOnClose_;
+ bool openTabBlinking_;
+ bool replyENQ_;
+ // bool bLogMsg;
+ QString httpBrowser_;
+ int openBeep_;
+ QString beepSoundFileName_;
+ int beepMethodID_;
+ QString beepPlayerName_;
+ bool openUrlCheck_;
+ // bool bAutoCopy;
+ bool openAntiAlias_;
+ bool openMinimizeToTray_;
+ bool needClearZmodemPoolOnClose_;
+ bool useStyleSheet_;
+ QString styleSheetFile_;
+ QString zmodemDir_;
+ QString poolDir_;
+ QString imageViewerName_;
+ QString externalEditor_;
+ QString externalEditorArg_;
+ QString searchEngine_;
+ //global settings
+ bool isBossColor_;
+ bool isAnsciiEnhance_;
+ QString escapeString_;
+ int termScrollBarPosition_; // 0--hide 1--LEFT 2--RIGHT
+ bool runServer_;
+};
+
+
+class FQTermParam {
+ public:
+ FQTermParam();
+ FQTermParam(const FQTermParam &);
+ ~FQTermParam();
+
+ FQTermParam &operator = (const FQTermParam &);
+
+ bool operator==(const FQTermParam &);
+
+ static const FQTermParam& getFQBBSParam();
+ static QString getLanguageName(bool isEnglish, bool translate = true);
+ // General
+ // Name
+ QString name_;
+ // Address
+ QString hostAddress_;
+ // Port
+ quint16 port_;
+ // Host Type
+ int hostType_; // 0--BBS 1--*NIX
+ // Auto Login
+ bool isAutoLogin_;
+ // Pre Login
+ QString preLoginCommand_;
+ // User Name
+ QString userName_;
+ // Password
+ QString password_;
+ // Post Login
+ QString postLoginCommand_;
+
+ // Display
+ // {FQTERM_ENCODING_GBK = 0, FQTERM_ENCODING_BIG5 = 1, FQTERM_ENCODING_UTF8 = 2, FQTERM_ENCODING_HKSCS = 3, FQTERM_ENCODING_UAO = 4};
+ int serverEncodingID_;
+
+ // 0 - keep column/row, adjust font
+ // 1 - keep font, adjust column/row
+ // 2 - keep column/row/font
+ int isFontAutoFit_;
+ // Always Highlight
+ bool isAlwaysHighlight_;
+ // ANSI Color
+ bool isAnsiColor_;
+ // Font Name
+ QString englishFontName_;
+ QString otherFontName_;
+ // Font Size
+ int englishFontSize_;
+ int otherFontSize_;
+
+ int alignMode_; //how to align english char/chinese char in vertical direction 0 -- vcenter, 1 -- bottom 2 -- top
+ int charSpacing_; //additional char spacing for English char.
+ int lineSpacing_; //additional line spacing
+ //int charRatio_; //height of english char / width of english char
+ // Background Color
+ QColor backgroundColor_;
+ // Foreground Color
+ QColor foregroundColor_;
+ // Schema File
+ QString schemaFileName_;
+
+ // Terminal
+ // Terminal Type
+ QString virtualTermType_;
+ // Key Type
+ int keyboardType_; // 0--BBS 1--XTERM 2--VT100
+ // Columns & Rows
+ int numColumns_, numRows_;
+ // Scroll Lines
+ int numScrollLines_;
+ // Curor Type
+ int cursorType_; // 0--Block 1--Underline 2--I Type
+ // the esacpe string
+ QString escapeString_;
+
+ //Keyboard
+ int backspaceType_; //0--^H 1--^?(127)
+
+
+ // Connection
+ // Proxy Type
+ int proxyType_; // 0--None 1--Wingate 2--SOCKS4 3--SOCKS5 4--HTTP
+ // Address
+ QString proxyHostName_;
+ // Port
+ quint16 proxyPort_;
+ // Authentation
+ bool isAuthentation_;
+ // User Name
+ QString proxyUserName_;
+ // Password
+ QString proxyPassword_;
+ // Protocol
+ int protocolType_; // 0--Telnet 1--SSH1 2--SSH2 3--Local
+ // User Name
+ QString sshUserName_;
+ // Password
+ QString sshPassword_;
+ // Misc
+ // Max Idle Time %s
+ int maxIdleSeconds_;
+ QString replyKeyCombination_;
+ // Send When Idle
+ QString antiIdleMessage_;
+ bool isAntiIdle_;
+ // wether autoreply
+ bool isAutoReply_;
+ // Auto Reply Messages
+ QString autoReplyMessage_;
+ // Reconnect When Disconnected By Host
+ bool isAutoReconnect_;
+ // Reconnect Interval (s)
+ int reconnectInterval_;
+ // Retry times
+ int retryTimes_; // -1 -- infinite
+ // Close Window When Disconnected By Host
+ bool isAutoCloseWin_;
+
+ bool isBeep_;
+ bool isBuzz_;
+
+ // Mouse
+ bool isSupportMouse_;
+ int menuType_; // 0--underline 1--reverse 2--color
+ QColor menuColor_;
+ // Script
+ bool isAutoLoadScript_;
+ QString autoLoadedScriptFileName_;
+ // Zmodem
+ bool enableZmodem_;
+
+ bool isColorCopy_;
+ bool isRectSelect_;
+ bool isAutoCopy_;
+ bool isAutoWrap_;
+
+ private:
+ void copy(const FQTermParam& parm);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_PARAM_H
diff --git a/src/common/fqterm_path.cpp b/src/common/fqterm_path.cpp
new file mode 100644
index 0000000..88ee385
--- /dev/null
+++ b/src/common/fqterm_path.cpp
@@ -0,0 +1,601 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifdef WIN32
+#include <windows.h>
+#include <shlobj.h>
+#endif // WIN32
+
+#include <QApplication>
+#include <QFile>
+#include <QDir>
+#include <QFont>
+
+#include "fqterm_config.h"
+#include "fqterm_trace.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_font.h"
+
+namespace FQTerm {
+
+static QString getUserDataDir();
+static QString getInstallPrefix();
+static QString getResourceDir(const QString &prefix);
+
+const QString &getPath(PathCategory category) {
+ static QString null_dir = "";
+ static QString user_config = getUserDataDir();
+ static QString prefix = getInstallPrefix();
+ static QString resource = getResourceDir(prefix);
+
+ switch (category) {
+ case RESOURCE:
+ return resource;
+ break;
+ case USER_CONFIG:
+ return user_config;
+ break;
+ }
+ return null_dir;
+}
+
+void clearDir(const QString &path) {
+ QDir dir(path);
+ if (dir.exists()) {
+ const QFileInfoList list = dir.entryInfoList();
+ //QFileInfoListIterator it( *list );
+ //QFileInfo *fi;
+ foreach(QFileInfo fi, list) {
+ if (fi.isFile()) {
+ dir.remove(fi.fileName());
+ }
+ }
+ }
+}
+
+bool checkPath(const QString &path) {
+ QDir dir(path);
+ if (!dir.exists()) {
+ if (!dir.mkpath(path)) {
+ FQ_TRACE("path", 0) << "Failed to create directory " << path;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool checkFile(const QString &src, const QString &dst) {
+ if (QFile(dst).exists()) {
+ return true;
+ }
+
+ if (!QFile::copy(src, dst)) {
+ FQ_TRACE("path", 0) << "Failed to copy a file from " << src
+ << " to " << dst;
+ return false;
+ }
+
+ FQ_TRACE("path", 5) << "A file copied from " << src
+ << " to " << dst;
+
+ if (!QFile::setPermissions(dst, QFile::ReadOwner | QFile::WriteOwner)) {
+ FQ_TRACE("path", 0) << "Failed to change access attributs of "<< dst
+ << " to make only the owner have rights to "
+ << "read/write it.";
+ return false;
+ }
+
+ return true;
+}
+
+bool iniSettings() {
+ if (!checkPath(getPath(USER_CONFIG))) {
+ return false;
+ }
+
+ if (!checkFile(getPath(RESOURCE) + "userconf/fqterm.cfg.orig",
+ getPath(USER_CONFIG) + "fqterm.cfg")) {
+ return false;
+ }
+
+ if (!checkFile(getPath(RESOURCE) + "userconf/address.cfg.orig",
+ getPath(USER_CONFIG) + "address.cfg")) {
+ return false;
+ }
+
+ if (!checkFile(getPath(RESOURCE) + "userconf/language.cfg.orig",
+ getPath(USER_CONFIG) + "language.cfg")) {
+ return false;
+ }
+
+ //Copy schema files
+ if (checkPath(getPath(USER_CONFIG) + "schema")) {
+ checkFile(getPath(RESOURCE) + "schema/default.schema",
+ getPath(USER_CONFIG) + "schema/default.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/Linux.schema",
+ getPath(USER_CONFIG) + "schema/Linux.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/Softness.schema",
+ getPath(USER_CONFIG) + "schema/Softness.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/VIM.schema",
+ getPath(USER_CONFIG) + "schema/VIM.schema");
+
+ checkFile(getPath(RESOURCE) + "schema/XTerm.schema",
+ getPath(USER_CONFIG) + "schema/XTerm.schema");
+ }
+
+
+ //read settings from fqterm.cfg
+ FQTermConfig *conf = new FQTermConfig(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ //set font
+ QString family = (conf->getItemValue("global", "font"));
+
+ QString pointsize = conf->getItemValue("global", "pointsize");
+ QString pixelsize = conf->getItemValue("global", "pixelsize");
+ if (!family.isEmpty()) {
+ QFont font(family);
+ if (pointsize.toInt() > 0) {
+ font.setPointSize(pointsize.toInt());
+ }
+ if (pixelsize.toInt() > 0) {
+ font.setPixelSize(pixelsize.toInt());
+ }
+ QString openAntiAlias_ = conf->getItemValue("global", "antialias");
+ if (openAntiAlias_ != "0") {
+ font.setStyleStrategy(QFont::PreferAntialias);
+ }
+ qApp->setFont(font);
+ }
+
+ // zmodem and pool directory
+ QString pathZmodem = conf->getItemValue("preference", "zmodem");
+ if (pathZmodem.isEmpty()) {
+ pathZmodem = getPath(USER_CONFIG) + "zmodem";
+ }
+
+ if (!checkPath(pathZmodem)) {
+ return false;
+ }
+
+ QString pathPool = conf->getItemValue("preference", "pool");
+
+ if (pathPool.isEmpty()) {
+ pathPool = getPath(USER_CONFIG) + "pool/";
+ }
+
+ if (pathPool.right(1) != "/") {
+ pathPool.append('/');
+ }
+
+ QString pathCache = pathPool + "shadow-cache/";
+
+ if (!checkPath(pathPool) || !checkPath(pathCache)) {
+ return false;
+ }
+
+ delete conf;
+ return true;
+}
+
+void checkHelpExists(FQTermConfig* pConf) {
+ QString strTmp = pConf->getItemValue("bbs list", "num");
+ int bbsCount = strTmp.toInt();
+
+ QString strSection;
+
+ for (int i = 0; i < bbsCount; i++) {
+ strSection.sprintf("bbs %d", i);
+ strTmp = pConf->getItemValue(strSection, "name");
+ if (strTmp == "FQTermHelp")
+ return;
+ }
+ pConf->setItemValue("bbs list", "num", QString("%1").arg(bbsCount + 1));
+ saveAddress(pConf, bbsCount, FQTermParam::getFQBBSParam());
+ pConf->save(getPath(USER_CONFIG) + "address.cfg");
+}
+
+void loadNameList(FQTermConfig *pConf, QStringList &listName) {
+ QString strTmp = pConf->getItemValue("bbs list", "num");
+
+ QString strSection;
+
+ for (int i = 0; i < strTmp.toInt(); i++) {
+ strSection.sprintf("bbs %d", i);
+ listName.append(pConf->getItemValue(strSection, "name"));
+ }
+}
+
+bool loadAddress(FQTermConfig *pConf, int n, FQTermParam &param) {
+ QString strTmp, strSection;
+ if (n < 0) {
+ strSection = "default";
+ } else {
+ strSection.sprintf("bbs %d", n);
+ }
+
+ if (!pConf->hasSection(strSection))
+ return false;
+
+ // check if larger than existence
+ strTmp = pConf->getItemValue("bbs list", "num");
+ if (n >= strTmp.toInt()) {
+ return false;
+ }
+ param.name_ = pConf->getItemValue(strSection, "name");
+ param.hostAddress_ = pConf->getItemValue(strSection, "addr");
+ strTmp = pConf->getItemValue(strSection, "port");
+ param.port_ = strTmp.toUShort();
+ strTmp = pConf->getItemValue(strSection, "hosttype");
+ param.hostType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "autologin");
+ param.isAutoLogin_ = (strTmp != "0");
+ param.preLoginCommand_ = pConf->getItemValue(strSection, "prelogin");
+ param.userName_ = pConf->getItemValue(strSection, "user");
+ param.password_ = pConf->getItemValue(strSection, "password");
+ param.postLoginCommand_ = pConf->getItemValue(strSection, "postlogin");
+
+ strTmp = pConf->getItemValue(strSection, "bbscode");
+ param.serverEncodingID_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "autofont");
+ if (strTmp == "0") {
+ param.isFontAutoFit_ = 0;
+ } else if (strTmp == "2") {
+ param.isFontAutoFit_ = 2;
+ } else {
+ param.isFontAutoFit_ = 1;
+ }
+ strTmp = pConf->getItemValue(strSection, "alwayshighlight");
+ param.isAlwaysHighlight_ = (strTmp != "0");
+ strTmp = pConf->getItemValue(strSection, "ansicolor");
+ param.isAnsiColor_ = (strTmp != "0");
+ QString language;
+ QString font_name;
+ QString font_size;
+ language = FQTermParam::getLanguageName(true, false);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ font_size = pConf->getItemValue(strSection, language + "fontsize");
+ if (!font_name.isEmpty()) {
+ param.englishFontName_ = font_name;
+ }
+ if (!font_size.isEmpty()) {
+ param.englishFontSize_ = font_size.toInt();
+ }
+ //FIXME: Should be removed in next release!!!!! (Since 0.9.7)
+ if (font_name.isEmpty()) {
+ language = FQTermParam::getLanguageName(true);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ if (!font_name.isEmpty()) {
+ param.englishFontName_ = font_name;
+ }
+ }
+
+ language = FQTermParam::getLanguageName(false, false);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ font_size = pConf->getItemValue(strSection, language + "fontsize");
+ if (!font_name.isEmpty()) {
+ param.otherFontName_ = font_name;
+ }
+ if (!font_size.isEmpty()) {
+ param.otherFontSize_ = font_size.toInt();
+ }
+
+ //FIXME: Should be removed in next release!!!!!
+ if (font_name.isEmpty()) {
+ language = FQTermParam::getLanguageName(false);
+ font_name = pConf->getItemValue(strSection, language + "fontname");
+ if (!font_name.isEmpty()) {
+ param.englishFontName_ = font_name;
+ }
+ }
+
+ param.foregroundColor_.setNamedColor(pConf->getItemValue(strSection, "fgcolor"));
+ param.backgroundColor_.setNamedColor(pConf->getItemValue(strSection, "bgcolor"));
+ param.schemaFileName_ = pConf->getItemValue(strSection, "schemafile");
+
+ param.virtualTermType_ = pConf->getItemValue(strSection, "termtype");
+ strTmp = pConf->getItemValue(strSection, "keytype");
+ param.keyboardType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "backspacetype");
+ param.backspaceType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "column");
+ param.numColumns_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "row");
+ param.numRows_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "scroll");
+ param.numScrollLines_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "cursor");
+ param.cursorType_ = strTmp.toInt();
+ param.escapeString_ = pConf->getItemValue(strSection, "escape");
+
+ strTmp = pConf->getItemValue(strSection, "proxytype");
+ param.proxyType_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "proxyauth");
+ param.isAuthentation_ = (strTmp != "0");
+ param.proxyHostName_ = pConf->getItemValue(strSection, "proxyaddr");
+ strTmp = pConf->getItemValue(strSection, "proxyport");
+ param.proxyPort_ = strTmp.toInt();
+ param.proxyUserName_ = pConf->getItemValue(strSection, "proxyuser");
+ param.proxyPassword_ = pConf->getItemValue(strSection, "proxypassword");
+ strTmp = pConf->getItemValue(strSection, "protocol");
+ param.protocolType_ = strTmp.toInt();
+ param.sshUserName_ = pConf->getItemValue(strSection, "sshuser");
+ param.sshPassword_ = pConf->getItemValue(strSection, "sshpassword");
+
+ strTmp = pConf->getItemValue(strSection, "maxidle");
+ param.maxIdleSeconds_ = strTmp.toInt();
+ param.replyKeyCombination_ = pConf->getItemValue(strSection, "replykey");
+ if (param.replyKeyCombination_.isNull()) {
+ Q_ASSERT(false);
+ }
+
+ param.antiIdleMessage_ = pConf->getItemValue(strSection, "antiidlestring");
+ strTmp = pConf->getItemValue(strSection, "isantiidle");
+ param.isAntiIdle_ = (strTmp != "0");
+ param.autoReplyMessage_ = pConf->getItemValue(strSection, "autoreply");
+ strTmp = pConf->getItemValue(strSection, "bautoreply");
+ param.isAutoReply_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "reconnect");
+ param.isAutoReconnect_ = (strTmp != "0");
+ strTmp = pConf->getItemValue(strSection, "interval");
+ param.reconnectInterval_ = strTmp.toInt();
+ strTmp = pConf->getItemValue(strSection, "retrytimes");
+ param.retryTimes_ = strTmp.toInt();
+
+ strTmp = pConf->getItemValue(strSection, "autoclosewin");
+ param.isAutoCloseWin_ = (strTmp == "1");
+
+ strTmp = pConf->getItemValue(strSection, "alignmode");
+ param.alignMode_ = strTmp.toInt();
+
+
+ strTmp = pConf->getItemValue(strSection, "charspacing");
+ param.charSpacing_ = strTmp.toInt();
+
+ strTmp = pConf->getItemValue(strSection, "linespacing");
+ param.lineSpacing_ = strTmp.toInt();
+
+ strTmp = pConf->getItemValue(strSection, "loadscript");
+ param.isAutoLoadScript_ = (strTmp != "0");
+ param.autoLoadedScriptFileName_ = pConf->getItemValue(strSection, "scriptfile");
+
+ strTmp = pConf->getItemValue(strSection, "enablezmodem");
+ param.enableZmodem_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "isbeep");
+ param.isBeep_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "isbuzz");
+ param.isBuzz_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "ismouse");
+ param.isSupportMouse_ = (strTmp != "0");
+
+ strTmp = pConf->getItemValue(strSection, "menutype");
+ param.menuType_ = strTmp.toInt();
+ param.menuColor_.setNamedColor(pConf->getItemValue(strSection, "menucolor"));
+
+ param.isColorCopy_ = (pConf->getItemValue(strSection, "colorcopy") != "0");
+ param.isAutoCopy_ = (pConf->getItemValue(strSection, "autocopy") != "0");
+ param.isRectSelect_ = (pConf->getItemValue(strSection, "rectselect") != "0");
+ param.isAutoWrap_ = (pConf->getItemValue(strSection, "autowrap" ) == "1");
+
+ return true;
+}
+
+void saveAddress(FQTermConfig *pConf, int n, const FQTermParam &param) {
+ QString strTmp, strSection;
+ if (n < 0) {
+ strSection = "default";
+ } else {
+ strSection.sprintf("bbs %d", n);
+ }
+
+ pConf->setItemValue(strSection, "name", param.name_);
+ pConf->setItemValue(strSection, "addr", param.hostAddress_);
+ strTmp.setNum(param.port_);
+ pConf->setItemValue(strSection, "port", strTmp);
+ strTmp.setNum(param.hostType_);
+ pConf->setItemValue(strSection, "hosttype", strTmp);
+ pConf->setItemValue(strSection, "autologin", param.isAutoLogin_ ? "1" : "0");
+ pConf->setItemValue(strSection, "prelogin", param.preLoginCommand_);
+ pConf->setItemValue(strSection, "user", param.userName_);
+ pConf->setItemValue(strSection, "password", param.password_);
+ pConf->setItemValue(strSection, "postlogin", param.postLoginCommand_);
+
+ strTmp.setNum(param.serverEncodingID_);
+ pConf->setItemValue(strSection, "bbscode", strTmp);
+ pConf->setItemValue(strSection, "autofont", strTmp.setNum(param.isFontAutoFit_));
+ pConf->setItemValue(strSection, "alwayshighlight", param.isAlwaysHighlight_ ?
+ "1" : "0");
+ pConf->setItemValue(strSection, "ansicolor", param.isAnsiColor_ ? "1" : "0");
+
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(true, false) + "fontname", param.englishFontName_);
+ strTmp.setNum(param.englishFontSize_);
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(true, false) + "fontsize", strTmp);
+
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(false, false) + "fontname", param.otherFontName_);
+ strTmp.setNum(param.otherFontSize_);
+ pConf->setItemValue(strSection, FQTermParam::getLanguageName(false, false) + "fontsize", strTmp);
+
+ pConf->setItemValue(strSection, "alignmode", strTmp.setNum(param.alignMode_));
+ pConf->setItemValue(strSection, "charspacing", strTmp.setNum(param.charSpacing_));
+ pConf->setItemValue(strSection, "linespacing", strTmp.setNum(param.lineSpacing_));
+
+ pConf->setItemValue(strSection, "bgcolor", param.backgroundColor_.name());
+ pConf->setItemValue(strSection, "fgcolor", param.foregroundColor_.name());
+
+ pConf->setItemValue(strSection, "schemafile", param.schemaFileName_);
+
+ pConf->setItemValue(strSection, "termtype", param.virtualTermType_);
+ strTmp.setNum(param.keyboardType_);
+ pConf->setItemValue(strSection, "keytype", strTmp);
+ strTmp.setNum(param.backspaceType_);
+ pConf->setItemValue(strSection, "backspacetype", strTmp);
+ strTmp.setNum(param.numColumns_);
+ pConf->setItemValue(strSection, "column", strTmp);
+ strTmp.setNum(param.numRows_);
+ pConf->setItemValue(strSection, "row", strTmp);
+ strTmp.setNum(param.numScrollLines_);
+ pConf->setItemValue(strSection, "scroll", strTmp);
+ strTmp.setNum(param.cursorType_);
+ pConf->setItemValue(strSection, "cursor", strTmp);
+ pConf->setItemValue(strSection, "escape", param.escapeString_);
+
+ strTmp.setNum(param.proxyType_);
+ pConf->setItemValue(strSection, "proxytype", strTmp);
+ pConf->setItemValue(strSection, "proxyauth", param.isAuthentation_ ? "1" : "0");
+ pConf->setItemValue(strSection, "proxyaddr", param.proxyHostName_);
+ strTmp.setNum(param.proxyPort_);
+ pConf->setItemValue(strSection, "proxyport", strTmp);
+ pConf->setItemValue(strSection, "proxyuser", param.proxyUserName_);
+ pConf->setItemValue(strSection, "proxypassword", param.proxyPassword_);
+ strTmp.setNum(param.protocolType_);
+ pConf->setItemValue(strSection, "protocol", strTmp);
+ pConf->setItemValue(strSection, "sshuser", param.sshUserName_);
+ pConf->setItemValue(strSection, "sshpassword", param.sshPassword_);
+
+ strTmp.setNum(param.maxIdleSeconds_);
+ pConf->setItemValue(strSection, "maxidle", strTmp);
+ pConf->setItemValue(strSection, "replykey", param.replyKeyCombination_);
+ pConf->setItemValue(strSection, "antiidlestring", param.antiIdleMessage_);
+ pConf->setItemValue(strSection, "isantiidle", param.isAntiIdle_?"1" : "0");
+ pConf->setItemValue(strSection, "bautoreply", param.isAutoReply_ ? "1" : "0");
+ pConf->setItemValue(strSection, "autoreply", param.autoReplyMessage_);
+ pConf->setItemValue(strSection, "reconnect", param.isAutoReconnect_? "1" : "0");
+ strTmp.setNum(param.reconnectInterval_);
+ pConf->setItemValue(strSection, "interval", strTmp);
+ strTmp.setNum(param.retryTimes_);
+ pConf->setItemValue(strSection, "retrytimes", strTmp);
+ pConf->setItemValue(strSection, "autoclosewin", param.isAutoCloseWin_? "1" : "0");
+
+ pConf->setItemValue(strSection, "loadscript", param.isAutoLoadScript_ ? "1" : "0");
+ pConf->setItemValue(strSection, "scriptfile", param.autoLoadedScriptFileName_);
+
+ pConf->setItemValue(strSection, "enablezmodem", param.enableZmodem_? "1" : "0");
+
+ pConf->setItemValue(strSection, "isbeep", param.isBeep_? "1" : "0");
+ pConf->setItemValue(strSection, "isbuzz", param.isBuzz_? "1" : "0");
+ pConf->setItemValue(strSection, "ismouse", param.isSupportMouse_? "1" : "0");
+
+ strTmp.setNum(param.menuType_);
+ pConf->setItemValue(strSection, "menutype", strTmp);
+ pConf->setItemValue(strSection, "menucolor", param.menuColor_.name());
+
+ pConf->setItemValue(strSection, "colorcopy", param.isColorCopy_? "1" : "0");
+ pConf->setItemValue(strSection, "autocopy", param.isAutoCopy_? "1" : "0");
+ pConf->setItemValue(strSection, "rectselect", param.isRectSelect_? "1" : "0");
+ pConf->setItemValue(strSection, "autowrap", param.isAutoWrap_?"1":"0");
+
+}
+
+static QString getResourceDir(const QString &prefix) {
+ QString res;
+
+ std::string fqterm_resource;
+
+ char *p = NULL;
+ if ((p = getenv("FQTERM_RESOURCE")) != NULL)
+ fqterm_resource = p;
+
+ if (fqterm_resource.size() == 0) {
+#if defined(WIN32)
+ res = prefix;
+#elif defined(__APPLE__)
+ res = prefix + "../Resources/";
+#else
+ res = prefix + "share/FQTerm/";
+#endif
+ } else {
+ res = QString::fromLocal8Bit(fqterm_resource.c_str());
+ }
+
+ if (res[res.size() - 1] != '/')
+ res += '/';
+
+ return res;
+}
+
+static QString getInstallPrefix() {
+ QString res;
+
+ std::string fqterm_prefix;
+
+ char *p = NULL;
+ if ((p = getenv("FQTERM_PREFIX")) != NULL)
+ fqterm_prefix = p;
+
+ if (fqterm_prefix.size() == 0) {
+ res = QCoreApplication::applicationDirPath() + "/";
+ } else {
+ res = QString::fromLocal8Bit(fqterm_prefix.c_str());
+ }
+
+ if (res[res.size() - 1] != '/')
+ res += '/';
+
+ return res;
+}
+
+static QString getUserDataDir() {
+ char *evnDataDir = NULL;
+ if ((evnDataDir = getenv("FQTERM_DATADIR")) != NULL) {
+ std::string fqterm_data = evnDataDir;
+ if (fqterm_data[fqterm_data.size() - 1] != '/'
+#ifdef WIN32
+ || fqterm_data[fqterm_data.size() - 1] != '\\'
+#endif
+ )
+ fqterm_data += '/';
+ if (fqterm_data.length() != 0) {
+ return QString::fromLocal8Bit(fqterm_data.c_str());
+ }
+ }
+
+#ifdef WIN32
+ char buffer[MAX_PATH];
+ SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, buffer);
+ std::string dir(buffer);
+
+ if (dir[dir.size() - 1] != '\\') {
+ dir += '\\';
+ }
+ return QString::fromLocal8Bit(dir.c_str()) + "FQTerm/";
+#else
+ char *p = NULL;
+
+ std::string home;
+ if ((p = getenv("HOME")) != NULL)
+ home = p;
+ if (home.size() == 0)
+ home = "/root/";
+
+ if (home[home.size() - 1] != '/')
+ home += '/';
+
+ return QString::fromLocal8Bit(home.c_str()) + ".fqterm/";
+#endif
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_path.h b/src/common/fqterm_path.h
new file mode 100644
index 0000000..08611be
--- /dev/null
+++ b/src/common/fqterm_path.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PATH_H
+#define FQTERM_PATH_H
+
+class QString;
+class QStringList;
+
+class FQTermConfig;
+class FQTermParam;
+
+namespace FQTerm {
+
+enum PathCategory {RESOURCE, USER_CONFIG};
+
+const QString &getPath(PathCategory category);
+
+bool iniSettings();
+
+void checkHelpExists(FQTermConfig*);
+void loadNameList(FQTermConfig *, QStringList &);
+bool loadAddress(FQTermConfig *, int, FQTermParam &);
+void saveAddress(FQTermConfig *, int, const FQTermParam &);
+
+void clearDir(const QString &path);
+} // namespace FQTerm
+
+#endif // FQTERM_PATH_H
diff --git a/src/common/fqterm_shortcuthelper.cpp b/src/common/fqterm_shortcuthelper.cpp
new file mode 100644
index 0000000..8c18643
--- /dev/null
+++ b/src/common/fqterm_shortcuthelper.cpp
@@ -0,0 +1,298 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+#include "fqterm_shortcuthelper.h"
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+
+#include <QWidget>
+#include <QAction>
+#include <QPixmap>
+namespace FQTerm
+{
+
+FQTermShortcutHelper::FQTermShortcutHelper(FQTermConfig* config, QWidget* actionParent) :
+ config_(config),
+ actionParent_(actionParent)
+{
+ initShortcutDescriptionTable();
+}
+
+QString FQTermShortcutHelper::getShortcutText(int shortcut)
+{
+ if (!config_)
+ return "";
+ QString result = getShortcutConfig(shortcut);
+ if (result == "")
+ result = getShortcutDefaultText(shortcut);
+ else if (result == "Undefined")
+ result = "";
+ return result;
+}
+
+void FQTermShortcutHelper::initShortcutDescriptionTable()
+{
+ initShortcutDescriptionTableEntry(CONNECT, "connect", tr(""), tr("Connect Host"), "connect");
+ initShortcutDescriptionTableEntry(CASCADEWINDOWS, "cascadewindows", tr(""), tr("Cascade Windows"));
+ initShortcutDescriptionTableEntry(TILEWINDOWS, "tilewindows", tr(""), tr("Tils Windows"));
+ initShortcutDescriptionTableEntry(DISCONNECT, "disconnect", tr(""), tr("Disconnect Host"), "disconnect");
+ initShortcutDescriptionTableEntry(ADDRESSBOOK, "addressbook", tr("F2"), tr("Address Book"), "address_book");
+ initShortcutDescriptionTableEntry(QUICKLOGIN, "quicklogin", tr("F3"), tr("Quick Login"), "quick_login");
+#if defined(__APPLE__)
+ initShortcutDescriptionTableEntry(COPY, "copy", tr("Ctrl+C"), tr("Copy"), "copy");
+ initShortcutDescriptionTableEntry(PASTE, "paste", tr("Ctrl+V"), tr("Paste"), "paste");
+#else
+ initShortcutDescriptionTableEntry(COPY, "copy", tr("Ctrl+Ins"), tr("Copy"), "copy");
+ initShortcutDescriptionTableEntry(PASTE, "paste", tr("Shift+Insert"), tr("Paste"), "paste");
+#endif
+ initShortcutDescriptionTableEntry(COPYWITHCOLOR, "copywithcolor", tr(""), tr("Copy With Color"), "copy_with_color");
+ getAction(COPYWITHCOLOR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(RECTANGLESELECTION, "rectangleselection", tr(""), tr("Rectangle Selection"), "rectangle_selection");
+ getAction(RECTANGLESELECTION)->setCheckable(true);
+ initShortcutDescriptionTableEntry(AUTOCOPYSELECTION, "autocopyselection", tr(""), tr("Auto Copy Selection"));
+ getAction(AUTOCOPYSELECTION)->setCheckable(true);
+ initShortcutDescriptionTableEntry(PASTEWORDWRAP, "pastewordwrap", tr(""), tr("Paste With Word Wrap"));
+ getAction(PASTEWORDWRAP)->setCheckable(true);
+ initShortcutDescriptionTableEntry(ENGLISHFONT, "englishfont", tr(""), tr("Set English Font"));
+ initShortcutDescriptionTableEntry(OTHERFONT, "nonenglishfont", tr(""), tr("Set Other Font"));
+ initShortcutDescriptionTableEntry(COLORSETTING, "colorsetting", tr(""), tr("Color Setting"), "ansi_color");
+ initShortcutDescriptionTableEntry(REFRESHSCREEN, "refreshscreen", tr(""), tr("Refresh Screen"), "refresh");
+ initShortcutDescriptionTableEntry(ANSICOLOR, "ansicolor", tr(""), tr("Toggle Ansi Color"), "toggle_ansi_color");
+ getAction(ANSICOLOR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(UIFONT, "uifont", tr(""), tr("Set UI Font"));
+ initShortcutDescriptionTableEntry(FULLSCREEN, "fullscreen", tr("F6"), tr("Toggle Full Screen"));
+ getAction(FULLSCREEN)->setCheckable(true);
+ initShortcutDescriptionTableEntry(BOSSCOLOR, "bosscolor", tr("F12"), tr("Toggle Boss Color"));
+ getAction(BOSSCOLOR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SWITCHBAR, "switchbar", tr(""), tr("Toggle Switch Bar"));
+ getAction(SWITCHBAR)->setCheckable(true);
+ initShortcutDescriptionTableEntry(CURRENTSETTING, "currentsetting", tr(""), tr("Current Session Setting"), "preferences");
+ initShortcutDescriptionTableEntry(SEARCHIT, "googleit", tr("Ctrl+Alt+G"), tr("Google selected words"));
+ initShortcutDescriptionTableEntry(WEIBOSHARE, "shareit", tr("Alt+`"), tr("Share selected text and highlighted URL to weibo"));
+ initShortcutDescriptionTableEntry(EXTERNALEDITOR, "externaleditor", tr("Ctrl+Alt+E"), tr("Invoke external editor"));
+ initShortcutDescriptionTableEntry(FASTPOST, "fastpost", tr("Ctrl+Alt+F"), tr("Fast post from clipboard"));
+ initShortcutDescriptionTableEntry(DEFAULTSETTING, "defaultsetting", tr(""), tr("Default Setting"));
+ initShortcutDescriptionTableEntry(PREFERENCE, "preference", tr(""), tr("Preference"), "preferences");
+ initShortcutDescriptionTableEntry(EDITSCHEMA, "schema", tr(""), tr("Edit Schema"));
+ initShortcutDescriptionTableEntry(SHORTCUTSETTING, "shortcut", tr(""), tr("Shorcut Setting"));
+ initShortcutDescriptionTableEntry(COPYARTICLE, "copyarticle", tr("F9"), tr("Copy Article"), "get_article_fulltext");
+ initShortcutDescriptionTableEntry(ANTIIDLE, "antiidle", tr(""), tr("Toggle Anti Idle"), "anti_idle");
+ getAction(ANTIIDLE)->setCheckable(true);
+ initShortcutDescriptionTableEntry(AUTOREPLY, "autoreply", tr(""), tr("Toggle Auto Reply"), "auto_reply");
+ getAction(AUTOREPLY)->setCheckable(true);
+ initShortcutDescriptionTableEntry(VIEWMESSAGE, "viewmessage", tr("F10"), tr("View Messages"), "view_messages");
+ initShortcutDescriptionTableEntry(IPLOOKUP, "iplookup", tr(""), tr("IP Lookup"));
+ initShortcutDescriptionTableEntry(BEEP, "beep", tr(""), tr("Toggle Beep"), "beep");
+ getAction(BEEP)->setCheckable(true);
+ initShortcutDescriptionTableEntry(MOUSESUPPORT, "mousesupport", tr(""), tr("Toggle Mouse Support"), "mouse");
+ getAction(MOUSESUPPORT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(IMAGEVIEWER, "imageviewer", tr(""), tr("Image Viewer"), "image_viewer");
+ initShortcutDescriptionTableEntry(RUNSCRIPT, "runscript", tr("F7"), tr("Run Script"));
+ initShortcutDescriptionTableEntry(STOPSCRIPT, "stop", tr("F8"), tr("Stop Script"));
+#ifdef HAVE_PYTHON
+ initShortcutDescriptionTableEntry(RUNPYTHONSCRIPT, "runpythonscript", tr("Ctrl+F1"), tr("Run Python Script"));
+#endif //HAVE_PYTHON
+ initShortcutDescriptionTableEntry(ABOUT, "about", tr("Shift+F1"), tr("About"));
+ initShortcutDescriptionTableEntry(HOMEPAGE, "homepage", tr(""), tr("Homepage"));
+ initShortcutDescriptionTableEntry(EXIT, "exit", tr(""), tr("Exit FQTerm"));
+ initShortcutDescriptionTableEntry(COLORCTL_NO, "colorctlno", tr(""), tr("Set Color Ctrl to None"));
+ getAction(COLORCTL_NO)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_SMTH, "colorctlsmth", tr(""), tr("Set Color Ctrl to **["));
+ getAction(COLORCTL_SMTH)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_PTT, "colorctlptt", tr(""), tr("Set Color Ctrl to ^u["));
+ getAction(COLORCTL_PTT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_OLD_CUSTOM, "colorctloldcustom", tr(""), tr("Set Color Ctrl to old custom"));
+ getAction(COLORCTL_OLD_CUSTOM)->setCheckable(true);
+ initShortcutDescriptionTableEntry(COLORCTL_CUSTOM, "colorctlcustom", tr(""), tr("Set Color Ctrl to custom"));
+ getAction(COLORCTL_CUSTOM)->setCheckable(false);
+ initShortcutDescriptionTableEntry(AUTORECONNECT, "autoreconnect", tr(""), tr("Toggle Auto Reconnect"), "auto_reconnect");
+ getAction(AUTORECONNECT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SCROLLBAR_LEFT, "scrollbarleft", tr(""), tr("Set Scrollbar to Left"));
+ getAction(SCROLLBAR_LEFT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SCROLLBAR_RIGHT, "scrollbarright", tr(""), tr("Set Scrollbar to Right"));
+ getAction(SCROLLBAR_RIGHT)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SCROLLBAR_HIDDEN, "scrollbarhidden", tr(""), tr("Set Scrollbar Hidden"));
+ getAction(SCROLLBAR_HIDDEN)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_GOOGLE, "searchgoogle", tr(""), tr("Use Google"));
+ getAction(SEARCH_GOOGLE)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_BAIDU, "searchbaidu", tr(""), tr("Use Baidu"));
+ getAction(SEARCH_BAIDU)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_BING, "searchbing", tr(""), tr("Use Bing"));
+ getAction(SEARCH_BING)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_YAHOO, "searchyahoo", tr(""), tr("Use Yahoo!"));
+ getAction(SEARCH_YAHOO)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SEARCH_CUSTOM, "searchcustom", tr(""), tr("Use Customized SE"));
+ getAction(SEARCH_CUSTOM)->setCheckable(true);
+ initShortcutDescriptionTableEntry(LANGUAGE_ENGLISH, "languageenglish", tr(""), tr("Choose UI Language: English"));
+ getAction(LANGUAGE_ENGLISH)->setCheckable(true);
+ initShortcutDescriptionTableEntry(SAVESETTING, "savesetting", tr(""), tr("Save Current Session Setting"), "save_setting");
+
+#if defined(__APPLE__)
+ QString opt(tr("Ctrl"));
+#else
+ QString opt(tr("Alt"));
+#endif
+
+ initShortcutDescriptionTableEntry(NEXTWINDOW, "nextwindow", opt + tr("+Right"), tr("Next Window"));
+ initShortcutDescriptionTableEntry(PREVWINDOW, "prevwindow", opt + tr("+Left"), tr("Prev Window"));
+
+ initShortcutDescriptionTableEntry(GLOBAL_SHOW_FQTERM, "showfqterm", tr("Ctrl+Alt+Q"), tr("Show FQTerm"));
+ //index, key, default shortcut, descritption
+
+ retranslateActions();
+}
+
+void FQTermShortcutHelper::retranslateAction(int shortcut, const QString& text)
+{
+ if (getAction(shortcut))
+ getAction(shortcut)->setText(text);
+}
+
+void FQTermShortcutHelper::retranslateActions() {
+ retranslateAction(CONNECT, tr("&Connect"));
+ retranslateAction(DISCONNECT, tr("&Disconnect"));
+ retranslateAction(ADDRESSBOOK, tr("&Address book"));
+ retranslateAction(QUICKLOGIN, tr("&Quick login"));
+ retranslateAction(COPY, tr("&Copy"));
+ retranslateAction(PASTE, tr("&Paste"));
+ retranslateAction(COPYWITHCOLOR, tr("C&opy with color"));
+ retranslateAction(RECTANGLESELECTION, tr("&Rectangle select"));
+ retranslateAction(AUTOCOPYSELECTION, tr("Auto copy &select"));
+ retranslateAction(PASTEWORDWRAP, tr("P&aste with wordwrap"));
+ retranslateAction(ENGLISHFONT, tr("&English Font"));
+ retranslateAction(OTHERFONT, tr("O&ther Font"));
+ retranslateAction(COLORSETTING, tr("&Color Setting"));
+ retranslateAction(ANSICOLOR, tr("&Use ANSI Color"));
+ retranslateAction(REFRESHSCREEN, tr("&Refresh"));
+ retranslateAction(UIFONT, tr("U&I font"));
+ retranslateAction(FULLSCREEN, tr("Fullscree&n"));
+ retranslateAction(BOSSCOLOR, tr("B&oss Color"));
+ retranslateAction(SWITCHBAR, tr("S&witch Bar"));
+ retranslateAction(SEARCHIT, tr("&Search It"));
+ retranslateAction(WEIBOSHARE, tr("Sha&re It"));
+ retranslateAction(EXTERNALEDITOR, tr("E&xternal Editor"));
+ retranslateAction(FASTPOST, tr("&Fast Post"));
+ retranslateAction(CURRENTSETTING, tr("&Setting for current session"));
+ retranslateAction(DEFAULTSETTING, tr("&Default setting"));
+ retranslateAction(PREFERENCE, tr("&Preferences..."));
+ retranslateAction(SHORTCUTSETTING, tr("Short&cut Setting"));
+ retranslateAction(EDITSCHEMA, tr("&Edit Schema"));
+ retranslateAction(COPYARTICLE, tr("&Copy article"));
+ retranslateAction(ANTIIDLE, tr("Anti &idle"));
+ retranslateAction(AUTOREPLY, tr("Auto &reply"));
+ retranslateAction(VIEWMESSAGE, tr("&View messages"));
+ retranslateAction(IPLOOKUP, tr("I&P Lookup"));
+ retranslateAction(BEEP, tr("&Beep"));
+ retranslateAction(MOUSESUPPORT, tr("&Mouse support"));
+ retranslateAction(IMAGEVIEWER, tr("Ima&ge viewer"));
+ retranslateAction(RUNSCRIPT, tr("&Run..."));
+ retranslateAction(STOPSCRIPT, tr("&Stop"));
+ retranslateAction(RUNPYTHONSCRIPT, tr("Run &Python..."));
+ retranslateAction(ABOUT, tr("About &FQTerm"));
+ retranslateAction(HOMEPAGE, tr("FQTerm's &Homepage"));
+ retranslateAction(CASCADEWINDOWS, tr("&Cascade"));
+ retranslateAction(TILEWINDOWS, tr("&Tile"));
+ retranslateAction(EXIT, tr("&Exit"));
+ retranslateAction(COLORCTL_NO, tr("&None"));
+ retranslateAction(COLORCTL_SMTH, tr("&ESC ESC ["));
+ retranslateAction(COLORCTL_PTT, tr("Ctrl+&U["));
+ retranslateAction(COLORCTL_CUSTOM, tr("&Custom..."));
+ retranslateAction(AUTORECONNECT, tr("Reconnect When Disconnected By Host"));
+ retranslateAction(NEXTWINDOW, tr("Next Window"));
+ retranslateAction(PREVWINDOW, tr("Prev Window"));
+ retranslateAction(LANGUAGE_ENGLISH, tr("&English"));
+ retranslateAction(SCROLLBAR_HIDDEN, tr("&Hide"));
+ retranslateAction(SCROLLBAR_RIGHT, tr("&Right"));
+ retranslateAction(SCROLLBAR_LEFT, tr("&Left"));
+ retranslateAction(SEARCH_GOOGLE, tr("&Google"));
+ retranslateAction(SEARCH_BAIDU, tr("&Baidu"));
+ retranslateAction(SEARCH_BING, tr("&Bing"));
+ retranslateAction(SEARCH_YAHOO, tr("&Yahoo!"));
+ retranslateAction(SEARCH_CUSTOM, tr("&Custom"));
+ retranslateAction(SAVESETTING, tr("Save Settin&g"));
+}
+
+
+void FQTermShortcutHelper::resetAllShortcutText()
+{
+ for (int i = FQTERM_APPLICATION_SHORTCUT_START + 1; i < FQTERM_APPLICATION_SHORTCUT_END; ++i)
+ {
+ resetShortcutText(i);
+ }
+}
+
+void FQTermShortcutHelper::resetShortcutText(int shortcut)
+{
+ if (!config_)
+ return;
+ setShortcutText(shortcut, getShortcutDefaultText(shortcut));
+}
+
+void FQTermShortcutHelper::setShortcutText(int shortcut, const QString& text)
+{
+ if (!config_)
+ return;
+ QString val = text.trimmed();
+ if (val == "")
+ val = "Undefined";
+ setShortcutConfig(shortcut, val);
+ if (getAction(shortcut))
+ getAction(shortcut)->setShortcut(val);
+}
+
+FQTermShortcutHelper::~FQTermShortcutHelper()
+{
+}
+
+QString FQTermShortcutHelper::getShortcutConfig(int shortcut)
+{
+ return config_->getItemValue(getShortcutSection(), getShortcutKey(shortcut));
+}
+
+void FQTermShortcutHelper::setShortcutConfig(int shortcut, const QString& text)
+{
+ config_->setItemValue(getShortcutSection(), getShortcutKey(shortcut), text);
+}
+
+void FQTermShortcutHelper::initShortcutDescriptionTableEntry(int index, const QString& key, const QString& defaultshortcuttext, const QString& description, const QString& actionSkin) {
+ shortcutDescriptionTable_[index] = ShortcutDescriptionEntry(key, defaultshortcuttext, description);
+ shortcutDescriptionTable_[index].action_ = new QAction(actionParent_);
+ if (actionParent_) {
+ actionParent_->addAction(shortcutDescriptionTable_[index].action_);
+ }
+ shortcutDescriptionTable_[index].action_->setShortcut(getShortcutText(index));
+ if (actionSkin != QString::null)
+ shortcutDescriptionTable_[index].action_->setIcon(QPixmap(getPath(RESOURCE) + "pic/" + actionSkin + ".png"));
+}
+
+
+FQTermShortcutHelper::ShortcutDescriptionEntry::ShortcutDescriptionEntry(const QString& key /*= QString("")*/,
+ const QString& defaultshortcuttext /*= QString("")*/,
+ const QString& description /*= QString("")*/) :
+ key_(key),
+ defaultshortcuttext_(defaultshortcuttext),
+ description_(description),
+ action_(NULL) {}
+
+FQTermShortcutHelper::ShortcutDescriptionEntry::~ShortcutDescriptionEntry() {
+ delete action_;
+}
+}//namespace FQTerm
+
+#include "fqterm_shortcuthelper.moc" \ No newline at end of file
diff --git a/src/common/fqterm_shortcuthelper.h b/src/common/fqterm_shortcuthelper.h
new file mode 100644
index 0000000..7e77df7
--- /dev/null
+++ b/src/common/fqterm_shortcuthelper.h
@@ -0,0 +1,175 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef __FQTERM_SHORTCUTHELPER__
+#define __FQTERM_SHORTCUTHELPER__
+
+#include "fqterm.h"
+#include <QObject>
+#include <QString>
+#include <QMap>
+
+class QWidget;
+class QAction;
+namespace FQTerm
+{
+class FQTermConfig;
+
+
+#define FQTERM_ADDACTION(WIDGET, NAME, RECEIVER, FUNCTION) \
+ do{ \
+ QAction *action = getAction((FQTermShortcutHelper::NAME));\
+ QObject::disconnect(action, SIGNAL(triggered()), (RECEIVER), SLOT(FUNCTION())); \
+ FQ_VERIFY(connect(action, SIGNAL(triggered()), (RECEIVER), SLOT(FUNCTION()))); \
+ (WIDGET)->addAction(action);\
+ } while(0)
+
+
+
+class FQTermShortcutHelper : public QObject
+{
+ Q_OBJECT;
+public:
+ enum FQTERM_SHORTCUT
+ {
+ FQTERM_APPLICATION_SHORTCUT_START = 0,
+ CONNECT,
+ DISCONNECT,
+ ADDRESSBOOK, //F2
+ QUICKLOGIN, //F3
+ COPY, //Ctrl+Ins under lin & win, Ctrl+C under mac
+ PASTE, //Shift+Insert under lin & win, Ctrl+V under mac
+ COPYWITHCOLOR,
+ RECTANGLESELECTION,
+ AUTOCOPYSELECTION,
+ PASTEWORDWRAP,
+ ENGLISHFONT,
+ OTHERFONT,
+ COLORSETTING,
+ ANSICOLOR,
+ REFRESHSCREEN, //F5
+ UIFONT,
+ FULLSCREEN, //F6
+ BOSSCOLOR, //F12
+ SWITCHBAR,
+ SEARCHIT, //Ctrl+Alt+G
+ WEIBOSHARE,
+ EXTERNALEDITOR, //Ctrl+Alt+E
+ FASTPOST, //Ctrl+Alt+F
+ CURRENTSETTING,
+ DEFAULTSETTING,
+ SAVESETTING,
+ PREFERENCE,
+ SHORTCUTSETTING,
+ EDITSCHEMA,
+ COPYARTICLE, //F9
+ ANTIIDLE,
+ AUTOREPLY,
+ VIEWMESSAGE, //F10
+ IPLOOKUP,
+ BEEP,
+ MOUSESUPPORT,
+ IMAGEVIEWER,
+ RUNSCRIPT, //F7
+ STOPSCRIPT, //F8
+ RUNPYTHONSCRIPT, //Ctrl+F1
+ ABOUT, //F1
+ HOMEPAGE,
+ CASCADEWINDOWS,
+ TILEWINDOWS,
+ EXIT,
+ COLORCTL_NO,
+ COLORCTL_SMTH,
+ COLORCTL_PTT,
+ COLORCTL_OLD_CUSTOM,
+ COLORCTL_CUSTOM,
+ AUTORECONNECT,
+ SCROLLBAR_LEFT,
+ SCROLLBAR_RIGHT,
+ SCROLLBAR_HIDDEN,
+ SEARCH_GOOGLE,
+ SEARCH_BAIDU,
+ SEARCH_BING,
+ SEARCH_YAHOO,
+ SEARCH_CUSTOM,
+ LANGUAGE_ENGLISH,
+ NEXTWINDOW,
+ PREVWINDOW,
+ GLOBAL_SHOW_FQTERM,
+ FQTERM_APPLICATION_SHORTCUT_END,
+ };
+
+
+public:
+ FQTermShortcutHelper(FQTermConfig* config, QWidget* actionParent);
+ ~FQTermShortcutHelper();
+
+private:
+ struct ShortcutDescriptionEntry
+ {
+ ShortcutDescriptionEntry(const QString& key = QString(""), const QString& defaultshortcuttext = QString(""), const QString& description = QString(""));
+ ~ShortcutDescriptionEntry();
+ QString key_;
+ QString defaultshortcuttext_;
+ QString description_;
+ QAction* action_;
+ };
+ void initShortcutDescriptionTable();
+ FQTermConfig* config_;
+ QWidget* actionParent_;
+ QMap<int, ShortcutDescriptionEntry> shortcutDescriptionTable_;
+ void initShortcutDescriptionTableEntry(int index, const QString& key, const QString& defaultshortcuttext, const QString& description, const QString& actionSkin = QString::null);
+
+public:
+
+ QString getShortcutText(int shortcut) ;
+ QString getShortcutDescription(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].description_;
+ }
+ QString getShortcutDefaultText(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].defaultshortcuttext_;
+ }
+ void setShortcutText(int shortcut, const QString& text);
+ void resetShortcutText(int shortcut);
+ void resetAllShortcutText();
+
+ QAction* getAction(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].action_;
+ }
+ void retranslateActions();
+private:
+ //These functions are used to save shortcut
+ QString getShortcutSection() {
+ return QString("shortcutsettings");
+ }
+ QString getShortcutKey(int shortcut) {
+ return shortcutDescriptionTable_[shortcut].key_;
+ }
+
+ QString getShortcutConfig(int shortcut);
+ void setShortcutConfig(int shortcut, const QString& text);
+ void retranslateAction(int shortcut, const QString& text);
+};
+
+
+}//namespace FQTerm
+
+
+#endif
diff --git a/src/common/fqterm_sound.cpp b/src/common/fqterm_sound.cpp
new file mode 100644
index 0000000..96bcc83
--- /dev/null
+++ b/src/common/fqterm_sound.cpp
@@ -0,0 +1,733 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QSound>
+#include <QFile>
+#include <QMessageBox>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*******************************************************/
+/********** OSS code is from OpenSound System **********/
+/*******************************************************/
+#ifdef AUDIO_OSS
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#if defined(_OS_FREEBSD_) || defined(_OS_LINUX_)
+#include <sys/soundcard.h>
+#define FQ_AUDIO_DEV "/dev/dsp"
+#else
+#include <machine/soundcard.h>
+#define FQ_AUDIO_DEV "/dev/audio"
+#endif
+
+#define WAVE_FORMAT_PCM 0x0001
+#define WAVE_FORMAT_ADPCM 0x0002
+#define WAVE_FORMAT_ALAW 0x0006
+#define WAVE_FORMAT_MULAW 0x0007
+#define WAVE_FORMAT_IMA_ADPCM 0x0011
+
+#ifndef AFMT_S32_LE
+#define AFMT_S32_LE 0x00001000 /* Little endian signed 32-bit */
+#endif
+
+typedef struct {
+ int coeff1, coeff2;
+} adpcm_coeff;
+
+#endif /* AUDIO_OSS */
+
+/* 2008.07.06, ecore.cn@gmail.com, alsa sound for FQTerm ... */
+#ifdef AUDIO_ALSA
+#include <alsa/asoundlib.h>
+#include <stdint.h>
+typedef struct tag_FQ_WAVE_FILE_HEADER {
+ uint32_t rid; /* RIFF ID */
+ uint32_t rsz; /* RIFF SIZE */
+ uint32_t wid; /* WAVE ID */
+}
+FQWFH;
+
+typedef struct tag_FQ_WAVE_FORMAT_HEADER {
+ uint32_t fid; /* FORMAT ID */
+ uint32_t fsz; /* FORMAT SIZE */
+ uint16_t aid; /* AUDIO ID */
+ uint16_t ach; /* AUDIO CHANNELS */
+ uint32_t asr; /* AUDIO SAMPLE RATE */
+ uint32_t abr; /* AUDIO BYTE RATE */
+ uint16_t aba; /* AUDIO BLOCK ALIGNMENT */
+ uint16_t abps; /* AUDIO BITS PER SAMPLE */
+}
+FQWMH;
+
+typedef struct tag_FQ_WAVE_DATA_HEADER {
+ uint32_t did; /* DATA ID */
+ uint32_t dsz; /* DATA SIZE */
+}
+FQWDH;
+
+#endif /* AUDIO_ALSA */
+
+#include "common.h"
+#include "fqterm_sound.h"
+
+namespace FQTerm {
+
+FQTermSound::FQTermSound(const QString &filename, QObject *parent,
+ const char *name)
+ : QThread(parent), soundFile_(filename) {
+ connect(this, SIGNAL(finished()), SLOT(deleteInstance()));
+ connect(this, SIGNAL(terminated()), SLOT(deleteInstance()));
+}
+
+FQTermSound::~FQTermSound() {
+}
+
+void FQTermSound::deleteInstance() {
+ FQ_TRACE("sound", 3) << "sound instance [" << (void*)this << "] is to be deleted!";
+ delete this;
+}
+
+void FQTermSound::run() {
+ if (QFile::exists(soundFile_)) {
+#if !defined(AUDIO_OSS) && !defined(AUDIO_ALSA)
+ QSound::play(soundFile_);
+#else
+ this->play();
+#endif
+ }
+}
+
+void FQTermExternalSound::setPlayer(const QString &playername) {
+ playerName_ = playername;
+}
+
+void FQTermExternalSound::play() {
+ if (QFile::exists(soundFile_)) {
+ runProgram(playerName_, soundFile_, false);
+ }
+}
+
+/*******************************************************/
+/********** OSS code is from OpenSound System **********/
+/*******************************************************/
+#ifdef AUDIO_OSS
+static int le_int (unsigned char *p, int l) {
+
+ int i, val;
+ val = 0;
+
+ for (i = l - 1; i >= 0; i--) {
+ val = (val << 8) | p[i];
+ }
+
+ return val;
+}
+
+static int setupDevice(int audiofd, int channels, int bits, int speed) {
+
+ int tmp;
+
+ tmp = bits;
+ if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &tmp) == -1) {
+ return 0;
+ }
+
+ if (tmp != bits) {
+ return 0;
+ }
+
+ tmp = channels;
+ if (ioctl(audiofd, SNDCTL_DSP_CHANNELS, &tmp) == -1) {
+ return 0;
+ }
+
+ if (tmp != channels) {
+ return 0;
+ }
+
+ tmp = speed;
+ if (ioctl(audiofd, SNDCTL_DSP_SPEED, &tmp) == -1) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static void dumpData(int audiofd, int soundfd, int filesize) {
+
+ int bsize, l;
+ unsigned char buf[1024];
+ bsize = sizeof(buf);
+
+ while (filesize) {
+
+ l = bsize;
+
+ if (l > filesize) {
+ l = filesize;
+ }
+
+ if ((l = read(soundfd, buf, l)) <= 0) {
+ return;
+ }
+
+ if (write(audiofd, buf, l) == -1) {
+ return;
+ }
+
+ filesize -= l;
+ }
+}
+
+static void dumpData24 (int audiofd, int soundfd, int filesize) {
+
+ int bsize, i, l;
+ unsigned char buf[1024];
+ int outbuf[1024], outlen=0;
+ int sample_s32;
+ bsize = sizeof(buf);
+
+ filesize -= filesize % 3;
+
+ while(filesize >= 3) {
+
+ l = bsize - bsize % 3;
+ if (l > filesize) {
+ l = filesize;
+ }
+
+ if(l < 3) {
+ break;
+ }
+
+ if ((l = read(soundfd, buf, l)) <= 0) {
+ return;
+ }
+
+ outlen=0;
+
+ for(i=0; i<l; i+= 3) {
+
+ unsigned int *u32 = (unsigned int *)&sample_s32; /* Alias */
+
+ /* Read the litle endian input samples */
+ *u32 = (buf[i] << 8) | (buf[i+1] << 16) | (buf[i+2]<<24);
+ outbuf[outlen++]=sample_s32;
+
+ }
+
+ if (write(audiofd, outbuf, outlen*sizeof(int)) == -1) {
+ return;
+ }
+
+ filesize -= l;
+ }
+}
+
+static void playAdpcmWave(int audiofd, int soundfd, unsigned char *hdr, int l) {
+
+ int i, n, dataleft, x;
+
+ adpcm_coeff coeff[32];
+ static int AdaptionTable[] = { 230, 230, 230, 230, 307, 409, 512, 614,
+ 768, 614, 512, 409, 307, 230, 230, 230
+ };
+
+ unsigned char buf[4096];
+
+ int channels = 1;
+ int bits = 8;
+ int speed = 11025;
+ int p = 12, max, outp;
+ int nBlockAlign, wSamplesPerBlock, wNumCoeff;
+ int fmt = -1;
+ int nib;
+
+ unsigned char outbuf[64 * 1024];
+
+ while (p < l - 16 && memcmp(&hdr[p], "data", 4) != 0) {
+
+ n = le_int(&hdr[p + 4], 4);
+ if (memcmp(&hdr[p], "fmt ", 4) == 0) {
+
+ fmt = le_int(&hdr[p + 8], 2);
+ channels = le_int(&hdr[p + 10], 2);
+ speed = le_int(&hdr[p + 12], 4);
+ nBlockAlign = le_int(&hdr[p + 20], 2);
+ bits = AFMT_S16_LE;
+ wSamplesPerBlock = le_int(&hdr[p + 26], 2);
+ wNumCoeff = le_int(&hdr[p + 28], 2);
+
+ x = p + 30;
+
+ for (i = 0; i < wNumCoeff; i++) {
+
+ coeff[i].coeff1 = (short)le_int(&hdr[x], 2);
+ x += 2;
+ coeff[i].coeff2 = (short)le_int(&hdr[x], 2);
+ x += 2;
+ }
+ }
+
+ p += n + 8;
+ }
+
+ if (p < l - 16 && memcmp(&hdr[p], "data", 4) == 0) {
+
+ dataleft = n = le_int(&hdr[p + 4], 4);
+ p += 8;
+
+ if (lseek(soundfd, p, SEEK_SET) == -1) {
+ return;
+ }
+
+ if (fmt != WAVE_FORMAT_ADPCM) {
+ return;
+ }
+
+ if (!setupDevice(audiofd, channels, bits, speed)) {
+ return;
+ }
+
+#define OUT_SAMPLE(s) { \
+ if (s>32767)s=32767;else if(s<-32768)s=-32768; \
+ outbuf[outp++] = (unsigned char)(s & 0xff); \
+ outbuf[outp++] = (unsigned char)((s>>8) & 0xff); \
+ n+=2; \
+ if (outp>=max){write(audiofd, outbuf, outp);outp=0;}\
+ }
+
+#define GETNIBBLE \
+ ((nib==0) ? \
+ (buf[x + nib++] >> 4) & 0x0f : \
+ buf[x++ + --nib] & 0x0f \
+ )
+
+ max = 1024;
+ outp = 0;
+
+ while (dataleft > nBlockAlign &&
+ read(soundfd, buf, nBlockAlign) == nBlockAlign) {
+
+ int predictor[2], delta[2], samp1[2], samp2[2];
+ int x = 0;
+ dataleft -= nBlockAlign;
+
+ nib = 0;
+ n = 0;
+
+ for (i = 0; i < channels; i++) {
+ predictor[i] = buf[x];
+ x++;
+ }
+
+ for (i = 0; i < channels; i++) {
+ delta[i] = (short)le_int(&buf[x], 2);
+ x += 2;
+ }
+
+ for (i = 0; i < channels; i++) {
+ samp1[i] = (short)le_int(&buf[x], 2);
+ x += 2;
+ OUT_SAMPLE(samp1[i]);
+ }
+
+ for (i = 0; i < channels; i++) {
+ samp2[i] = (short)le_int(&buf[x], 2);
+ x += 2;
+ OUT_SAMPLE(samp2[i]);
+ }
+
+ while (n < (wSamplesPerBlock * 2 * channels)) {
+
+ for (i = 0; i < channels; i++) {
+
+ int pred, new_pred, error_delta, i_delta;
+
+ pred = ((samp1[i] * coeff[predictor[i]].coeff1)
+ + (samp2[i] * coeff[predictor[i]].coeff2)) / 256;
+ i_delta = error_delta = GETNIBBLE;
+
+ if (i_delta & 0x08) {
+ i_delta -= 0x10; /* Convert to signed */
+ }
+
+ new_pred = pred + (delta[i] * i_delta);
+ OUT_SAMPLE(new_pred);
+
+ delta[i] = delta[i] * AdaptionTable[error_delta] / 256;
+ if (delta[i] < 16) {
+ delta[i] = 16;
+ }
+
+ samp2[i] = samp1[i];
+ samp1[i] = new_pred;
+ }
+ }
+ }
+ }
+
+ if (outp > 0) {
+ write (audiofd, outbuf, outp /*(outp+3) & ~3 */ );
+ }
+}
+
+static void playWave(int audiofd, int soundfd, unsigned char *hdr, int l) {
+
+ int filelen;
+ int n;
+ int channels = 1;
+ int bits = 8;
+ int file_bits = 8;
+ int speed = 11025;
+ int p = 12;
+ int fmt = -1;
+
+ filelen = le_int(&hdr[4], 4);
+
+ while(p < l - 16 && memcmp(&hdr[p], "data", 4) != 0) {
+
+ n = le_int(&hdr[p + 4], 4);
+
+ if (memcmp(&hdr[p], "fmt ", 4) == 0) {
+
+ fmt = le_int(&hdr[p + 8], 2);
+ channels = le_int(&hdr[p + 10], 2);
+ speed = le_int(&hdr[p + 12], 4);
+ bits = le_int(&hdr[p + 22], 2);
+
+ if (fmt == WAVE_FORMAT_ADPCM) {
+ playAdpcmWave(audiofd, soundfd, hdr, l);
+ return;
+ }
+
+ p += n + 8;
+ } else {
+ break;
+ }
+ }
+
+ if (p < l - 16 && memcmp(&hdr[p], "data", 4) == 0) {
+
+ n = le_int(&hdr[p + 4], 4);
+ p += 8;
+
+ if (lseek(soundfd, p, SEEK_SET) == -1) {
+ return;
+ }
+
+ if (fmt != WAVE_FORMAT_PCM) {
+ switch (fmt) {
+ case WAVE_FORMAT_ALAW:
+ bits = AFMT_A_LAW;
+ break;
+ case WAVE_FORMAT_MULAW:
+ bits = AFMT_MU_LAW;
+ break;
+ case WAVE_FORMAT_IMA_ADPCM:
+ bits = AFMT_IMA_ADPCM;
+ break;
+ default:
+ return;
+ }
+ }
+
+ file_bits = bits;
+
+ if (bits == 32) {
+ bits = AFMT_S32_LE;
+ } else if (bits == 24) {
+ bits = AFMT_S32_LE;
+ }
+
+ if (!setupDevice(audiofd, channels, bits, speed)) {
+ return;
+ }
+
+ if (file_bits != 24) {
+ dumpData (audiofd, soundfd, n);
+ } else {
+ dumpData24 (audiofd, soundfd, n);
+ }
+ }
+}
+#endif /* AUDIO_OSS */
+
+void FQTermSystemSound::play() {
+
+#ifdef AUDIO_OSS
+ int audio_fd = -1;
+ if ((audio_fd = open(FQ_AUDIO_DEV, O_WRONLY, 0)) == -1) {
+ FQ_TRACE("sound", 0) << "Error opening device: " << FQ_AUDIO_DEV;
+ return;
+ }
+
+ int sound_fd = -1;
+ QFile soundFile(soundFile_);
+
+ if (soundFile.open(QFile::ReadOnly)) {
+ sound_fd = soundFile.handle();
+ } else {
+ FQ_TRACE("sound", 0) << "Error opening file: " << soundFile_;
+ close(audio_fd);
+ return;
+ }
+
+ int l;
+ unsigned char sound_buf[1024];
+
+ if ((l = read(sound_fd, sound_buf, sizeof(sound_buf))) == -1) {
+ FQ_TRACE("sound", 0) << "Error reading file into buffer." << soundFile_;
+ soundFile.close();
+ close(audio_fd);
+ return;
+ }
+
+ if (l == 0) {
+ FQ_TRACE("sound", 0) << "Empty file: " << soundFile_;
+ soundFile.close();
+ close(audio_fd);
+ return;
+ }
+
+ lseek(sound_fd, 0, SEEK_SET); /* Start from the beginning */
+
+ if (l > 16 &&
+ memcmp(&sound_buf[0], "RIFF", 4) == 0 && memcmp(&sound_buf[8], "WAVE", 4) == 0) {
+
+ playWave(audio_fd, sound_fd, sound_buf, l);
+ } else {
+ FQ_TRACE("sound", 0) << "We play WAVE files only: " << soundFile_;
+ }
+
+ soundFile.close();
+ close(audio_fd);
+
+#undef OUTSAMPLE
+#undef GETNIBBLE
+#endif /* AUDIO_OSS */
+
+/* 2008.07.06, ecore.cn@gmail.com, alsa sound for FQTerm ... */
+#ifdef AUDIO_ALSA
+ FILE *fp;
+ FQWFH wfh;
+ FQWMH wmh;
+ FQWDH wdh;
+ int endian, sz, len, count, ret;
+ unsigned int val;
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+ snd_pcm_format_t format;
+ snd_pcm_uframes_t csz, vsz;
+ void *data;
+
+#define WAVE_UINT16(_x) (endian? ( \
+ (((_x) & 0x00FF) << 8) | \
+ (((_x) & 0xFF00) >> 8)): \
+ (_x))
+
+#define WAVE_UINT32(_x) (endian? ( \
+ (((_x) & 0x000000FF) << 24) | \
+ (((_x) & 0x0000FF00) << 8) | \
+ (((_x) & 0x00FF0000) >> 8) | \
+ (((_x) & 0xFF000000) >> 24)): \
+ (_x))
+
+ do {
+ if ((fp = fopen(this->soundFile_.toLocal8Bit(), "r")) == NULL) {
+ continue;
+ }
+
+ if (fread(&wfh, sizeof(FQWFH), 1, fp) != 1) {
+ continue;
+ }
+
+ switch (wfh.rid) {
+ case 0x52494646:
+ endian = 1; /* Big-Endian */
+ break;
+ case 0x46464952:
+ endian = 0; /* Small-Endian */
+ break;
+ default:
+ continue;
+ }
+
+ if (WAVE_UINT32(wfh.wid) != 0x45564157) { /* "WAVE" */
+ continue;
+ }
+
+ if (fread(&wmh, sizeof(FQWMH), 1, fp) != 1) {
+ continue;
+ }
+
+ if (WAVE_UINT32(wmh.fid) != 0x20746d66) { /* "FMT " */
+ continue;
+ }
+
+ if (WAVE_UINT32(wmh.fsz) != 16 || WAVE_UINT16(wmh.aid) != 1) { /* PCM */
+ continue;
+ }
+
+ if (fread(&wdh, sizeof(FQWDH), 1, fp) != 1) {
+ continue;
+ }
+
+ if (WAVE_UINT32(wdh.did) != 0x61746164) { /* "DATA" */
+ continue;
+ }
+
+ if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) {
+ continue;
+ }
+
+ snd_pcm_hw_params_alloca(&hwparams);
+ snd_pcm_sw_params_alloca(&swparams);
+
+ if (snd_pcm_hw_params_any(handle, hwparams) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_hw_params_set_access(handle, hwparams,
+ SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
+ continue;
+ }
+
+ switch(WAVE_UINT16(wmh.abps)) {
+ case 8:
+ format = SND_PCM_FORMAT_U8;
+ break;
+ case 16:
+ format = SND_PCM_FORMAT_S16_LE;
+ break;
+ case 24:
+ switch (WAVE_UINT16(wmh.aba) / WAVE_UINT16(wmh.ach)) {
+ case 3:
+ format = SND_PCM_FORMAT_S24_3LE;
+ break;
+ case 4:
+ format = SND_PCM_FORMAT_S24_LE;
+ break;
+ default:
+ continue;
+ }
+
+ break;
+ case 32:
+ format = SND_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ continue;
+ }
+
+ if (snd_pcm_hw_params_set_format(handle, hwparams, format) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_hw_params_set_channels(handle, hwparams,
+ WAVE_UINT16(wmh.ach)) < 0) {
+ continue;
+ }
+
+ val = WAVE_UINT32(wmh.asr);
+
+ if (snd_pcm_hw_params_set_rate_near(handle, hwparams, &val, NULL) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_hw_params(handle, hwparams) < 0) {
+ continue;
+ }
+
+ snd_pcm_hw_params_get_period_size(hwparams, &csz, NULL);
+ snd_pcm_hw_params_get_buffer_size(hwparams, &vsz);
+
+ if (csz == vsz) {
+ continue;
+ }
+
+ snd_pcm_sw_params_current(handle, swparams);
+
+ if (snd_pcm_sw_params_set_avail_min(handle, swparams, csz) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_sw_params_set_start_threshold(handle, swparams, vsz) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_sw_params_set_stop_threshold(handle, swparams, vsz) < 0) {
+ continue;
+ }
+
+ if (snd_pcm_sw_params(handle, swparams) < 0) {
+ continue;
+ }
+
+ sz = csz * snd_pcm_format_physical_width(format)
+ * WAVE_UINT16(wmh.ach) / 8;
+
+ if ((data = malloc(sz)) == NULL) {
+ continue;
+ }
+
+ len = WAVE_UINT32(wdh.dsz);
+
+ while (len > 0) {
+ count = (len < sz)? len: sz;
+
+ ret = fread(data, 1, count, fp);
+
+ len -= ret;
+
+ if (ret != count) {
+ continue;
+ }
+
+ count = ret * csz / sz;
+
+ ret = snd_pcm_writei(handle, data, count);
+
+ if (ret == -EAGAIN || (ret >= 0 && ret < count)) {
+ snd_pcm_wait(handle, 200);
+ }
+ }
+
+ free(data);
+
+ snd_pcm_drain(handle);
+ snd_pcm_close(handle);
+
+ fclose(fp);
+ }
+ while (0);
+
+#undef WAVE_UINT16
+#undef WAVE_UINT32
+#endif /* AUDIO_ALSA */
+}
+
+} // namespace FQTerm
+
+#include "fqterm_sound.moc"
diff --git a/src/common/fqterm_sound.h b/src/common/fqterm_sound.h
new file mode 100644
index 0000000..ab18645
--- /dev/null
+++ b/src/common/fqterm_sound.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SOUND_H
+#define FQTERM_SOUND_H
+
+#include <QObject>
+#include <QString>
+#include <QThread>
+
+#include "fqterm.h"
+
+namespace FQTerm {
+// By using QThread, we avoid blocking the main app.
+// FIXME: However, whichever play method we use (ext|int),
+// there are some WAVE files we can't play...
+
+class FQTermSound: public QThread {
+ Q_OBJECT;
+
+ public:
+ FQTermSound(const QString &filename, QObject *parent = 0,
+ const char *name = 0);
+
+ ~FQTermSound();
+
+ public slots:
+ void deleteInstance();
+
+ protected:
+ QString soundFile_;
+ virtual void play() = 0;
+ void run();
+};
+
+class FQTermSystemSound: public FQTermSound {
+ public:
+ FQTermSystemSound(const QString &filename, QObject *parent = 0,
+ const char *name = 0)
+ : FQTermSound(filename, parent, name) {
+ }
+
+ protected:
+ void play();
+};
+
+class FQTermExternalSound: public FQTermSound {
+ public:
+ FQTermExternalSound(const QString &playername, const QString &filename,
+ QObject *parent = 0, const char *name = 0)
+ : FQTermSound(filename, parent, name), playerName_(playername) {
+ }
+
+ protected:
+ QString playerName_;
+ void play();
+ void setPlayer(const QString &playername);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SOUND_H
diff --git a/src/common/fqterm_trace.cpp b/src/common/fqterm_trace.cpp
new file mode 100644
index 0000000..867b7ad
--- /dev/null
+++ b/src/common/fqterm_trace.cpp
@@ -0,0 +1,328 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <string>
+
+#ifdef WIN32
+#include <hash_set>
+#else
+#include <set>
+#endif
+
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+int *getDefaultMaxTraceLevel() {
+ static int max_trace_level = 10;
+ return &max_trace_level;
+}
+
+int getMaxTraceLevel() {
+ return *getDefaultMaxTraceLevel();
+}
+
+void setMaxTraceLevel(int max_trace_level) {
+ *getDefaultMaxTraceLevel() = max_trace_level;
+ FQ_TRACE("info", 0) << "The upper bound of maximum trace level is "
+ << FQTERM_MAX_TRACE_LEVEL;
+ FQ_TRACE("info", 0) << "The maximum trace level is set to "
+ << max_trace_level;
+}
+
+#ifdef WIN32
+typedef stdext::hash_set<std::string> CategorySet;
+#else
+typedef std::set<std::string> CategorySet;
+#endif
+
+CategorySet *getAllowedCategories() {
+ static CategorySet *allowed_categories
+ = new CategorySet;
+ return allowed_categories;
+}
+
+int isAllowedCategory(const char *category, int trace_level) {
+ if (trace_level <= 0) return true;
+
+ const CategorySet &categories = *getAllowedCategories();
+ if (categories.empty()
+ || categories.find(category) != categories.end()) {
+ return true;
+ }
+ return false;
+}
+
+void addAllowedCategory(const char *category) {
+ CategorySet &categories = *getAllowedCategories();
+
+ categories.insert(category);
+
+ FQ_TRACE("info", 0) << "Allow category: " << category;
+}
+
+// Event name from event type id (updated to Qt4.3.0).
+static const char *kEventName[] = {
+ "QEvent::None", // 0
+ "QEvent::Timer", // 1
+ "QEvent::MouseButtonPress", // 2
+ "QEvent::MouseButtonRelease", // 3
+ "QEvent::MouseButtonDblClick", // 4
+ "QEvent::MouseMove", // 5
+ "QEvent::KeyPress", // 6
+ "QEvent::KeyRelease", // 7
+ "QEvent::FocusIn", // 8
+ "QEvent::FocusOut", // 9
+ "QEvent::Enter", // 10
+ "QEvent::Leave", // 11
+ "QEvent::Paint", // 12
+ "QEvent::Move", // 13
+ "QEvent::Resize", // 14
+ "None", // 15
+ "None", // 16
+ "QEvent::Show", // 17
+ "QEvent::Hide", // 18
+ "QEvent::Close", // 19
+ "None", // 20
+ "QEvent::ParentChange", // 21
+ "None", // 22
+ "None", // 23
+ "QEvent::WindowActivate", // 24
+ "QEvent::WindowDeactivate", // 25
+ "QEvent::ShowToParent", // 26
+ "QEvent::HideToParent", // 27
+ "None", // 28
+ "None", // 29
+ "None", // 30
+ "QEvent::Wheel", // 31
+ "None", // 32
+ "QEvent::WindowTitleChange", // 33
+ "QEvent::WindowIconChange", // 34
+ "QEvent::ApplicationWindowIconChange", // 35
+ "QEvent::ApplicationFontChange", // 36
+ "QEvent::ApplicationLayoutDirectionChange", // 37
+ "QEvent::ApplicationPaletteChange", // 38
+ "QEvent::PaletteChange", // 39
+ "QEvent::Clipboard", // 40
+ "None", // 41
+ "None", // 42
+ "QEvent::MetaCall", // 43
+ "None", // 44
+ "None", // 45
+ "None", // 46
+ "None", // 47
+ "None", // 48
+ "None", // 49
+ "QEvent::SockAct", // 50
+ "QEvent::ShortcutOverride", // 51
+ "QEvent::DeferredDelete", // 52
+ "None", // 53
+ "None", // 54
+ "None", // 55
+ "None", // 56
+ "None", // 57
+ "None", // 58
+ "None", // 59
+ "QEvent::DragEnter", // 60
+ "QEvent::DragMove", // 61
+ "QEvent::DragLeave", // 62
+ "QEvent::Drop", // 63
+ "None", // 64
+ "None", // 65
+ "None", // 66
+ "None", // 67
+ "QEvent::ChildAdded", // 68
+ "QEvent::ChildPolished", // 69
+ "None", // 70
+ "QEvent::ChildRemoved", // 71
+ "None", // 72
+ "None", // 73
+ "QEvent::PolishRequest", // 74
+ "QEvent::Polish", // 75
+ "QEvent::LayoutRequest", // 76
+ "QEvent::UpdateRequest", // 77
+ "QEvent::UpdateLater", // 78
+ "None", // 79
+ "None", // 80
+ "None", // 81
+ "QEvent::ContextMenu", // 82
+ "QEvent::InputMethod", // 83
+ "None", // 84
+ "None", // 85
+ "QEvent::AccessibilityPrepare", // 86
+ "QEvent::TabletMove", // 87
+ "QEvent::LocaleChange", // 88
+ "QEvent::LanguageChange", // 89
+ "QEvent::LayoutDirectionChange", // 90
+ "None", // 91
+ "QEvent::TabletPress", // 92
+ "QEvent::TabletRelease", // 93
+ "None", // 94
+ "None", // 95
+ "QEvent::IconDrag", // 96
+ "QEvent::FontChange", // 97
+ "QEvent::EnabledChange", // 98
+ "QEvent::ActivationChange", // 99
+ "QEvent::StyleChange", // 100
+ "QEvent::IconTextChange", // 101
+ "QEvent::ModifiedChange", // 102
+ "QEvent::WindowBlocked", // 103
+ "QEvent::WindowUnblocked", // 104
+ "QEvent::WindowStateChange", // 105
+ "None", // 106
+ "None", // 107
+ "None", // 108
+ "QEvent::MouseTrackingChange", // 109
+ "QEvent::ToolTip", // 110
+ "QEvent::WhatsThis", // 111
+ "QEvent::StatusTip", // 112
+ "QEvent::ActionChanged", // 113
+ "QEvent::ActionAdded", // 114
+ "QEvent::ActionRemoved", // 115
+ "QEvent::FileOpen", // 116
+ "QEvent::Shortcut", // 117
+ "QEvent::WhatsThisClicked", // 118
+ "QEvent::AccessibilityHelp", // 119
+ "QEvent::ToolBarChange", // 120
+ "QEvent::ApplicationActivate", // 121
+ "QEvent::ApplicationDeactivate", // 122
+ "QEvent::QueryWhatsThis", // 123
+ "QEvent::EnterWhatsThisMode", // 124
+ "QEvent::LeaveWhatsThisMode", // 125
+ "QEvent::ZOrderChange", // 126
+ "QEvent::HoverEnter", // 127
+ "QEvent::HoverLeave", // 128
+ "QEvent::HoverMove", // 129
+ "QEvent::AccessibilityDescription", // 130
+ "QEvent::ParentAboutToChange", // 131
+ "QEvent::WinEventAct", // 132
+ "None", // 133
+ "None", // 134
+ "None", // 135
+ "None", // 136
+ "None", // 137
+ "None", // 138
+ "None", // 139
+ "None", // 140
+ "None", // 141
+ "None", // 142
+ "None", // 143
+ "None", // 144
+ "None", // 145
+ "None", // 146
+ "None", // 147
+ "None", // 148
+ "None", // 149
+ "QEvent::EnterEditFocus", // 150
+ "QEvent::LeaveEditFocus", // 151
+ "None", // 152
+ "QEvent::MenubarUpdated", // 153
+ "None", // 154
+ "QEvent::GraphicsSceneMouseMove", // 155
+ "QEvent::GraphicsSceneMousePress", // 156
+ "QEvent::GraphicsSceneMouseRelease", // 157
+ "QEvent::GraphicsSceneMouseDoubleClick", // 158
+ "QEvent::GraphicsSceneContextMenu", // 159
+ "QEvent::GraphicsSceneHoverEnter", // 160
+ "QEvent::GraphicsSceneHoverMove", // 161
+ "QEvent::GraphicsSceneHoverLeave", // 162
+ "QEvent::GraphicsSceneHelp", // 163
+ "QEvent::GraphicsSceneDragEnter", // 164
+ "QEvent::GraphicsSceneDragMove", // 165
+ "QEvent::GraphicsSceneDragLeave", // 166
+ "QEvent::GraphicsSceneDrop", // 167
+ "QEvent::GraphicsSceneWheel", // 168
+ "QEvent::KeyboardLayoutChange", // 169
+ "QEvent::DynamicPropertyChange", // 170
+ "QEvent::TabletEnterProximity", // 171
+ "QEvent::TabletLeaveProximity", // 172
+ // "QEvent::User", // 1000
+ // "QEvent::MaxUser", // 65535
+};
+
+const char *getEventName(unsigned int type) {
+ if (type > 1000) {
+ return "User defined event";
+ }
+
+ if (type > 172) {
+ return "None";
+ }
+
+ return kEventName[type];
+}
+
+} // namespace FQTerm
+
+#ifdef WIN32
+/*
+ * Number of micro-seconds between the beginning of the Windows epoch
+ * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
+ *
+ * This assumes all Win32 compilers have 64-bit support.
+ */
+
+#include <Windows.h>
+
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__WATCOMC__)
+ #define DELTA_EPOCH_IN_USEC 11644473600000000Ui64
+#else
+ #define DELTA_EPOCH_IN_USEC 11644473600000000ULL
+#endif
+
+static unsigned long long filetime_to_unix_epoch (const FILETIME *ft)
+{
+ unsigned long long res = (unsigned long long) ft->dwHighDateTime << 32;
+
+ res |= ft->dwLowDateTime;
+ res /= 10; /* from 100 nano-sec periods to usec */
+ res -= DELTA_EPOCH_IN_USEC; /* from Win epoch to Unix epoch */
+ return (res);
+}
+
+int gettimeofday (struct timeval *tv, int unused)
+{
+ FILETIME ft;
+ unsigned long long tim;
+
+ GetSystemTimeAsFileTime (&ft);
+ tim = filetime_to_unix_epoch (&ft);
+ tv->tv_sec = (long) (tim / 1000000L);
+ tv->tv_usec = (long) (tim % 1000000L);
+ return (0);
+}
+#else
+
+#include <sys/time.h>
+#include <time.h>
+
+#endif
+
+namespace FQTerm {
+
+long long getTraceTime() {
+ struct timeval t;
+ gettimeofday(&t, 0);
+ long long sec = t.tv_sec;
+ long long usec = t.tv_usec;
+ return sec * 1000 + usec/1000;
+}
+
+} // namespace FQTerm
diff --git a/src/common/fqterm_trace.h b/src/common/fqterm_trace.h
new file mode 100644
index 0000000..287a8a8
--- /dev/null
+++ b/src/common/fqterm_trace.h
@@ -0,0 +1,331 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TRACE_H
+#define FQTERM_TRACE_H
+
+#include <cassert>
+#ifndef WIN32
+#include <unistd.h>
+#endif // WIN32
+
+#include <QtDebug>
+#include <QFileInfo>
+
+namespace FQTerm {
+
+// define NO_FQTERM_TRACE to avoid all trace output.
+// #define NO_FQTERM_TRACE
+
+// define NO_FQTERM_TRACE_FILE_LINE_NUM to avoid file line number in trace
+// output.
+
+// define NO_FQTERM_TRACE_FUNCTION_NAME to avoid function name in trace output.
+// define integer FQTERM_MAX_TRACE_LEVEL to determine the maximize outputed
+// trace level.
+//#define NO_FQTERM_TRACE
+#if defined(NDEBUG)
+#define FQTERM_MAX_TRACE_LEVEL 1
+#endif
+
+#ifndef FQTERM_MAX_TRACE_LEVEL
+#define FQTERM_MAX_TRACE_LEVEL 20
+#endif // FQTERM_MAX_TRACE_LEVEL
+
+int getMaxTraceLevel();
+
+void setMaxTraceLevel(int max_trace_level);
+
+long long getTraceTime();
+
+int isAllowedCategory(const char *category, int trace_level);
+
+void addAllowedCategory(const char *category);
+
+static void soft_break() {
+#if defined(WIN32)
+ __asm int 03h;
+#else
+ pause();
+#endif
+}
+
+template<int trace_level>
+class FQTermTrace {
+ public:
+ FQTermTrace(const char *category, const char *file_name, int line_num, const char *func_name)
+ : category_(category),
+ is_dummy_(!isAllowedCategory(category, trace_level)),
+ trace_output_((trace_level <= FQTERM_MAX_TRACE_LEVEL
+ && trace_level <= getMaxTraceLevel())
+ ? new QDebug(qDebug().nospace())
+ : NULL),
+ dump_string_(false) {
+
+ if (is_dummy_) return;
+
+#ifdef NO_FQTERM_TRACE_FILE_LINE_NUM
+#ifdef NO_FQTERM_TRACE_FUNCTION_NAME
+ return;
+#endif // NO_FQTERM_TRACE_FUNCTION_NAME
+#endif // NO_FQTERM_TRACE_FILE_LINE_NUM
+
+ (*this) << "[" << category_ << " " << trace_level << " ";
+
+#ifndef NO_FQTERM_TRACE_FILE_LINE_NUM
+ (*this) << QFileInfo(file_name).fileName().toAscii().constData()
+ << ": " << line_num;
+#endif // NO_FQTERM_TRACE_FILE_LINE_NUM
+
+#ifndef NO_FQTERM_TRACE_FUNCTION_NAME
+#ifndef NO_FQTERM_TRACE_FILE_LINE_NUM
+ (*this) << ", ";
+#endif // NO_FQTERM_TRACE_FILE_LINE_NUM
+ (*this) << func_name;
+#endif // NO_FQTERM_TRACE_FUNCTION_NAME
+
+ (*this) << "] ";
+ }
+
+ ~FQTermTrace() {
+ if (is_dummy_) return;
+
+ if (trace_level <= FQTERM_MAX_TRACE_LEVEL && trace_level <= getMaxTraceLevel()) {
+ delete trace_output_;
+
+ if (trace_level < 0) {
+ soft_break();
+ assert(false);
+ qFatal("Fatal error occured!\n");
+ }
+ }
+ }
+
+ template<class T>
+ FQTermTrace &operator << (const T &t) {
+ if (is_dummy_) return *this;
+
+ if (trace_level <= FQTERM_MAX_TRACE_LEVEL && trace_level <= getMaxTraceLevel()) {
+ *trace_output_ << t;
+ }
+ return *this;
+ }
+
+ FQTermTrace &operator << (const std::string &t) {
+ return output_raw_string(t);
+ }
+
+ FQTermTrace &operator << (const char *t) {
+ return output_raw_string(t);
+ }
+
+ FQTermTrace &operator << (void (*setter)(FQTermTrace<trace_level> &)) {
+ (*setter)(*this);
+ return *this;
+ }
+
+ private:
+ FQTermTrace &output_raw_string(const std::string &t) {
+ if (is_dummy_) return *this;
+
+ if (trace_level <= FQTERM_MAX_TRACE_LEVEL && trace_level <= getMaxTraceLevel()) {
+ if (!dump_string_) {
+ for (std::string::size_type i = 0; i < t.size(); ++i) {
+ *trace_output_ << t[i];
+ }
+ } else {
+ for (std::string::size_type i = 0; i < t.size(); ++i) {
+ unsigned char a = t[i];
+ unsigned char b = a / 0x10;
+ unsigned char c = a % 0x10;
+ char h = (char) (b < 10 ? '0' + b : 'A' + b - 10);
+ char l = (char) (c < 10 ? '0' + c : 'A' + c - 10);
+
+ *trace_output_ << h << l << ' ';
+ }
+ }
+ }
+ return *this;
+ }
+
+ private:
+ const char *category_;
+ bool is_dummy_;
+ QDebug *trace_output_;
+
+ public:
+ bool dump_string_; // whether we print string in hex mode.
+
+};
+
+template<int trace_level>
+class FQTermDummyTrace {
+ public:
+ template<class T>
+ FQTermDummyTrace &operator << (const T &) {
+ return *this;
+ }
+
+ FQTermDummyTrace &operator << (void (*setter)(FQTermTrace<trace_level> &)) {
+ return *this;
+ }
+};
+
+template<int trace_level>
+void dumpHexString(FQTermTrace<trace_level> &tracer) {
+ tracer.dump_string_ = true;
+}
+
+template<int trace_level>
+void dumpNormalString(FQTermTrace<trace_level> &tracer) {
+ tracer.dump_string_ = false;
+}
+
+template<int trace_level>
+class FQTermScopeTrace {
+ public:
+ FQTermScopeTrace(const char *category, const char *file_name, int line_num,
+ const char *func_name, const char *scope_name)
+ : category_(category),
+ is_dummy_(!isAllowedCategory(category, trace_level)),
+ file_name_(file_name),
+ line_num_(line_num),
+ func_name_(func_name),
+ scope_name_(scope_name) {
+ if (is_dummy_) return;
+ FQTermTrace<trace_level>(category_, file_name_, line_num_, func_name_)
+ << "Entering " << scope_name_;
+ }
+
+ ~FQTermScopeTrace() {
+ if (is_dummy_) return;
+ FQTermTrace<trace_level>(category_, file_name_, line_num_, func_name_)
+ << "Leaving " << scope_name_;
+ }
+
+ private:
+ const char *category_;
+ bool is_dummy_;
+
+ const char *file_name_;
+ const int line_num_;
+ const char *func_name_;
+ const char *scope_name_;
+};
+
+template<int trace_level>
+class FQTermTimerTrace {
+ public:
+ FQTermTimerTrace(const char *category, const char *file_name, int line_num,
+ const char *func_name, const char *msg)
+ : category_(category),
+ is_dummy_(!isAllowedCategory(category, trace_level)),
+ file_name_(file_name),
+ line_num_(line_num),
+ func_name_(func_name),
+ msg_(msg),
+ start_time(is_dummy_? 0: getTraceTime()) {
+ }
+
+ ~FQTermTimerTrace() {
+ if (is_dummy_) return;
+
+ long long total_time = getTraceTime() - start_time;
+
+ long long num_sec = total_time / 1000;
+ long long num_ms = total_time % 1000;
+
+ FQTermTrace<trace_level>(category_, file_name_, line_num_, func_name_)
+ << msg_ << num_sec << "s" << num_ms << "ms";
+ }
+
+ private:
+ const char *category_;
+ bool is_dummy_;
+
+ const char *file_name_;
+ const int line_num_;
+ const char *func_name_;
+ const char *msg_;
+
+ long long start_time; // in millisecond.
+};
+
+// Some macros work in both debug & release version.
+#define FQ_FATAL(file, line, func) \
+ do {FQTerm::soft_break(); qFatal("%s", (QString(file) + ": %1 " + QString(func)).arg(line).toUtf8().constData());} while(false)
+
+#define FQ_VERIFY(expr) do { \
+ if(!(expr)) { \
+ FQ_FATAL(__FILE__, __LINE__, __FUNCTION__); \
+ } \
+ } while(false)
+
+
+
+#ifdef NO_FQTERM_TRACE
+
+#define FQ_TRACE(category, trace_level) FQTermDummyTrace<trace_level>()
+#define FQ_SCOPE_TRACE(category, trace_level, scope_name) do {} while (false)
+#define FQ_FUNC_TRACE(category, trace_level) do {} while(false)
+
+#define FQ_ASSERT(expr) do {} while(false)
+
+#define FQ_SCOPE_TIMER(category, trace_level, msg) do {} while(false)
+#define FQ_FUNC_TIMER(category, trace_level) do {} while(false)
+
+
+#else // NO_FQTERM_TRACE
+
+#define FQ_TRACE(category, trace_level) \
+ FQTermTrace<trace_level>(category, __FILE__, __LINE__, __FUNCTION__)
+
+#define FQ_SCOPE_TRACE_PRIVATE(file, line, func, category, trace_level, scope_name) \
+ FQTermScopeTrace<trace_level> file##line##func(category, file, line, func, scope_name);
+
+#define FQ_SCOPE_TRACE(category, trace_level, scope_name) \
+ FQ_SCOPE_TRACE_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, scope_name)
+
+#define FQ_FUNC_TRACE(category, trace_level) \
+ FQ_SCOPE_TRACE_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, "function")
+
+
+#define FQ_ASSERT(expr) \
+ do {if(!(expr)) {FQ_TRACE("assert", -1) << "assertion failed." << #expr;}} while(false)
+
+
+#define FQ_SCOPE_TIMER_PRIVATE(file, line, func, category, trace_level, msg) \
+ FQTermTimerTrace<trace_level> file##line##func(category, file, line, func, msg);
+
+#define FQ_SCOPE_TIMER(category, trace_level, msg) \
+ FQ_SCOPE_TIMER_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, msg)
+
+#define FQ_FUNC_TIMER(category, trace_level) \
+ FQ_SCOPE_TIMER_PRIVATE(__FILE__, __LINE__, __FUNCTION__, category, trace_level, "The function runs for ")
+
+
+#endif // NO_FQTERM_TRACE
+
+
+const char *getEventName(unsigned int type);
+
+} // namespace FQTerm
+
+#endif // FQTERM_TRACE_H
diff --git a/src/fqterm/3rdparty/dotnetstyle.cpp b/src/fqterm/3rdparty/dotnetstyle.cpp
new file mode 100644
index 0000000..d016ff2
--- /dev/null
+++ b/src/fqterm/3rdparty/dotnetstyle.cpp
@@ -0,0 +1,1274 @@
+/****************************************************************************
+**
+** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the DotNetStyle project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifdef USE_DOTNET_STYLE
+#include "dotnetstyle.h"
+#include <QStyleOption>
+#include <QPainter>
+#include <QMainWindow>
+#include <QDockWidget>
+#include <QDialogButtonBox>
+#include <QToolBar>
+#include <QDialog>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QLibrary>
+#include <QStatusBar>
+#include <QApplication>
+#include <qt_windows.h>
+
+typedef bool (WINAPI *PtrIsAppThemed)();
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+
+static PtrIsAppThemed pIsAppThemed = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsSepHeight = 9; // separator item height
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 2; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsRightBorder = 15; // right border on windows
+
+class DotNetStylePrivate
+{
+public:
+ DotNetStylePrivate()
+ {
+ QLibrary themeLib("uxtheme");
+ themeLib.load();
+ if (themeLib.isLoaded()) { //resolve uxtheme functions
+ pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
+ pGetCurrentThemeName = (PtrGetCurrentThemeName)themeLib.resolve("GetCurrentThemeName");
+ }
+ }
+ ~DotNetStylePrivate()
+ {}
+
+ enum InternalPalette {
+ Blue,
+ Silver,
+ Olive,
+ System,
+ Classic
+ };
+
+ void init();
+ QColor gradientDarkColor(const QStyleOption *option) const;
+ QColor gradientLightColor(const QStyleOption *option) const;
+ QColor highlightOutlineColor(const QStyleOption *option, bool act) const;
+ QColor shadowColor(const QStyleOption *option) const;
+ QBrush highlightBrush(const QStyleOption *option, bool act) const;
+ QBrush highlightMenuCheckBrush(const QStyleOption *option, bool act) const;
+ QLinearGradient toolbarGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion) const;
+ QLinearGradient menuGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion) const;
+ void updatePalette();
+
+ QColor menuSeparatorColor;
+ QColor menuBackgroundColor;
+ QColor menuFrameColor;
+ InternalPalette internalPalette; //internal color theme
+ DotNetStyle::ColorTheme theme; //external color theme
+ QPalette currentPal; //used to detect system palette changes
+ };
+
+
+
+inline QColor DotNetStylePrivate::gradientDarkColor(const QStyleOption *option) const {
+ QColor color = option->palette.background().color();
+ switch (internalPalette) {
+ case Olive:
+ color = QColor(217, 217, 167);
+ break;
+ case Blue:
+ color = QColor(158, 190, 245);
+ break;
+ case Silver:
+ color = QColor(216, 216, 229);
+ break;
+ default:
+ break;
+ }
+ return color;
+}
+
+inline QColor DotNetStylePrivate::gradientLightColor(const QStyleOption *option) const {
+ QColor color = option->palette.background().color().lighter(106);
+ switch (internalPalette) {
+ case Olive:
+ color = QColor(241, 240, 227);
+ break;
+ case Blue:
+ color = QColor(196, 217, 249);
+ break;
+ case Silver:
+ color = QColor(242, 242, 247);
+ break;
+ case Classic:
+ color = option->palette.light().color().lighter(106);
+ default:
+ break;
+ }
+ return color;
+}
+
+inline QColor DotNetStylePrivate::shadowColor(const QStyleOption *option) const {
+ QColor color;
+ switch (internalPalette) {
+ case Blue:
+ color = QColor(59, 97, 156);
+ break;
+ case Silver:
+ color = QColor(124, 124, 148);
+ break;
+ case Olive:
+ color = QColor(96, 128, 88);
+ break;
+ case Classic:
+ color = option->palette.background().color();
+ break;
+ default:
+ color = option->palette.dark().color();
+ break;
+ }
+ return color;
+}
+
+inline QColor DotNetStylePrivate::highlightOutlineColor(const QStyleOption *option, bool act = false) const {
+ QColor color;
+ switch (internalPalette) {
+ case Blue:
+ color = QColor(0, 0, 128);
+ break;
+ case Silver:
+ color = QColor(75, 75, 111);
+ break;
+ case Olive:
+ color = QColor(63, 93, 56);
+ break;
+ default:
+ if (act)
+ return option->palette.highlight().color().darker(110);
+ else
+ return option->palette.highlight().color().lighter(110);
+ break;
+ }
+ return color;
+}
+
+QBrush DotNetStylePrivate::highlightBrush(const QStyleOption *option, bool act) const {
+ QBrush brush;
+ QColor highlight;
+ switch (internalPalette) {
+ case Silver:
+ case Olive:
+ case Blue:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ brush = QColor(255, 238, 194);
+ } else {
+ QLinearGradient gradient(option->rect.topLeft(), option->rect.bottomLeft());
+ if (act) {
+ gradient.setColorAt(0, QColor(254, 149, 82));
+ gradient.setColorAt(1, QColor(255, 211, 142));
+ } else {
+ gradient.setColorAt(0, QColor(255, 252, 200));
+ gradient.setColorAt(1, QColor(255, 208, 145));
+ }
+ brush = gradient;
+ }
+ break;
+ default:
+ highlight = option->palette.highlight().color().lighter(120);
+ if (act)
+ highlight.setHsv(highlight.hue(), 70, 220);
+ else
+ highlight.setHsv(highlight.hue(), 40, 230);
+ brush = QBrush(highlight);
+ break;
+ }
+ return brush;
+}
+
+QBrush DotNetStylePrivate::highlightMenuCheckBrush(const QStyleOption *option, bool act) const {
+ QBrush brush;
+ QColor highlight;
+
+ switch (internalPalette) {
+ case Silver:
+ case Olive:
+ case Blue:
+ if (act)
+ brush = QColor(254, 128, 62);
+ else
+ brush = QColor(255, 192, 111);
+ break;
+ default:
+ highlight = option->palette.highlight().color().lighter(120);
+ if (act)
+ highlight.setHsv(highlight.hue(), 120, 180);
+ else {
+ highlight.setHsv(highlight.hue(), 30, 230);
+ }
+ highlight.setAlpha(170);
+ brush = highlight;
+ break;
+ }
+ return brush;
+}
+
+QLinearGradient DotNetStylePrivate::toolbarGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientation= Qt::Vertical) const {
+ QLinearGradient gradient(rect.topLeft(), orientation == Qt::Vertical ? rect.topRight() : rect.bottomLeft());
+ QColor start, stop;
+ switch (internalPalette)
+ {
+ case Blue:
+ start = QColor(220, 235, 254);
+ stop = QColor(129, 169, 226);
+ gradient.setColorAt(0.3, start);
+ break;
+ case Silver:
+ start = QColor(242, 242, 249);
+ stop = QColor(153, 151, 181);
+ gradient.setColorAt(0.3, start);
+ break;
+ case Olive:
+ start = QColor(241, 245, 217);
+ stop = QColor(183, 198, 145);
+ gradient.setColorAt(0.0, start);
+ break;
+ default:
+ start = option->palette.light().color();
+ if (internalPalette == Classic)
+ start = start.lighter(130);
+ start.setAlpha(180);
+ stop = option->palette.button().color();
+ stop.setHsv(stop.hue(), qMin(stop.saturation()*2, 255), (stop.value()*2)/3);
+ stop.setAlpha(128);
+ if (internalPalette == Classic)
+ stop.setAlpha(0);
+ gradient.setColorAt(0.3, start);
+ break;
+ }
+ gradient.setColorAt(1, stop);
+ return gradient;
+}
+
+
+QLinearGradient DotNetStylePrivate::menuGradient(const QStyleOption *option, QRect rect, Qt::Orientation orientaion = Qt::Horizontal) const {
+
+ QColor start, stop;
+ QLinearGradient grad;
+ if (orientaion == Qt::Vertical) {
+ grad.setStart(rect.left(), rect.top());
+ grad.setFinalStop(rect.left(), rect.bottom());
+ } else {
+ grad.setStart(QPoint(rect.left(), 0));
+ grad.setFinalStop(QPoint(rect.left() + 24, 0));
+ }
+ switch (internalPalette)
+ {
+ case Blue:
+ start = QColor(220, 235, 254);
+ stop = QColor(129, 169, 226);
+ grad.setColorAt(0.3, start);
+ break;
+ case Olive:
+ start = QColor(246, 248, 224);
+ stop = QColor(186, 201, 148);
+ grad.setColorAt(0.0, start);
+ break;
+ case Silver:
+ start = QColor(215, 215, 226);
+ stop = QColor(138, 137, 166);
+ grad.setColorAt(0.4, start);
+ break;
+ default:
+ start = option->palette.brush(QPalette::Active, QPalette::Base).color();
+ stop = gradientDarkColor(option);
+ stop.setHsv(stop.hue(), qMin((int)(stop.saturation()*1.2), 255), (5*stop.value()/7));
+ if (internalPalette == Classic)
+ stop.setAlpha(120);
+ grad.setColorAt(0, start);
+ break;
+ }
+ grad.setColorAt(1, stop);
+ return grad;
+}
+
+
+
+/*!
+ \class DotNetStyle qtdotnetstyle.h
+ \brief The DotNetStyle class provides an alternative, modern look for Qt applications on Windows.
+
+ The GUI look is very similar to the style introduced in
+ Visual Studio 2005, Office 2003 as well as in .NET Windows
+ Forms (when the RenderMode is set to "Professional"
+ instead of "System"). It gives applications a modern
+ gradient appearance for tool bars and menus while
+ retaining the native look and feel for other widgets.
+
+ The style supports different color themes, which may be specified in
+ the constructor. The default is \c Standard color theme.
+
+ This is the textedit example running with the Standard style:
+ \img dotnetstyle.png
+
+ This is the textedit example running with the Office style:
+ \img dotnetstyle2.png
+
+ \sa QStyle, QWindowsVistaStyle, QWindowsXPStyle
+*/
+
+
+/*!
+ \enum DotNetStyle::ColorTheme
+
+ This enum describes the different color schemes supported by the style.
+
+ \value Standard Use gradients based on the operating system palette.
+ \value Office Use Microsoft Office 2003 style gradients.
+*/
+
+/*!
+ Constructs a DotNetStyle object which uses the default color
+ theme (\c Office).
+*/
+DotNetStyle::DotNetStyle()
+: QWindowsVistaStyle(), d(new DotNetStylePrivate())
+{
+ d->theme = Office;
+}
+
+
+/*!
+ Constructs a DotNetStyle object which uses the color theme \a
+ colortheme.
+*/
+DotNetStyle::DotNetStyle(ColorTheme colortheme)
+ : QWindowsVistaStyle(), d(new DotNetStylePrivate())
+{
+ d->theme = colortheme;
+}
+
+
+/*!
+ Destroys the DotNetStyle object.
+*/
+DotNetStyle::~DotNetStyle()
+{
+ delete d;
+}
+
+
+/*!
+ \reimp
+ */
+void DotNetStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QColor gradientDark = d->gradientDarkColor(option);
+ QColor gradientLight = d->gradientLightColor(option);
+ QColor shadow = d->shadowColor(option);
+
+ QRect rect = option->rect;
+ switch (element) {
+ case PE_IndicatorDockWidgetResizeHandle:
+ break;
+ case PE_PanelLineEdit:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) {
+ QRect rect = option->rect.adjusted(2, 1, -2, -2);
+ painter->save();
+ bool active = option->state & State_Active &&
+ ((option->state & State_MouseOver)
+ || (option->state & State_HasFocus));
+ QBrush editBrush = option->palette.brush(QPalette::Base);
+ painter->setPen(QPen(editBrush.color()));
+ painter->fillRect(rect, editBrush);
+
+ QRect re = option->rect ;
+ if (active) {
+ painter->setPen(d->highlightOutlineColor(option));
+ painter->drawRect(rect);
+ }
+ painter->restore();
+ } else {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawPrimitive(element, option, painter, widget);
+ else
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ }
+ case PE_PanelButtonTool:
+ {
+ QStyleOption opt2 = *option;
+ if (widget)
+ if(QDockWidget *dw = qobject_cast<QDockWidget *>(widget->parentWidget())) {
+ if (!dw->isFloating())
+ opt2.palette.setBrush(QPalette::Button, Qt::transparent);
+ }
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawPrimitive(element, &opt2, painter, widget);
+ else
+ QWindowsXPStyle::drawPrimitive(element, &opt2, painter, widget);
+ }
+ break;
+ case PE_FrameMenu:
+ {
+ QPen pen = painter->pen();
+ QBrush brush = painter->brush();
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar*>(option))
+ {
+ Qt::Orientation orientation =(toolbar->toolBarArea == Qt::RightToolBarArea ||
+ toolbar->toolBarArea == Qt::LeftToolBarArea) ?
+ Qt::Vertical : Qt::Horizontal;
+ painter->setBrush(d->toolbarGradient(toolbar, toolbar->rect, orientation));
+ } else {
+ painter->setBrush(d->menuBackgroundColor);
+ }
+ painter->setPen(d->menuFrameColor);
+ painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ painter->setPen(pen);
+ painter->setBrush(brush);
+ }
+ break;
+ case PE_Widget:
+ if (const QMainWindow *mw = qobject_cast<const QMainWindow *>(widget)) {
+ if (d->currentPal != qApp->palette()) //workaround for style polish on theme color change
+ {
+ d->currentPal = qApp->palette();
+ d->updatePalette();
+ }
+ painter->save();
+ QPoint begin = widget->geometry().topRight();
+ QPoint end = widget->geometry().topLeft() + QPoint(0, widget->geometry().height()/2);
+ begin = widget->mapFromGlobal(begin);
+ end = widget->mapFromGlobal(end);
+ QLinearGradient menubargradient(begin, end);
+ menubargradient.setColorAt(0, gradientLight);
+ if (d->internalPalette == DotNetStylePrivate::System)
+ menubargradient.setColorAt(0.3, gradientDark);
+ else
+ menubargradient.setColorAt(0.8, gradientDark);
+ menubargradient.setColorAt(1, gradientDark);
+ QRect windowRect = option->rect;
+ if (QStatusBar *statusBar = mw->findChild<QStatusBar*>()) {
+ windowRect.adjust(0, 0, 0, -statusBar->height());
+ painter->setPen(option->palette.background().color().lighter(106));
+ painter->drawLine(windowRect.bottomLeft() + QPoint(0, 1),
+ windowRect.bottomRight() + QPoint(0, 1));
+ }
+ painter->fillRect(windowRect, menubargradient);
+ painter->restore();
+ }
+ break;
+ case PE_IndicatorToolBarSeparator:
+ {
+ QRect rect = option->rect;
+ shadow.setAlpha(180);
+ painter->setPen(shadow);
+ const int margin = 3;
+ if (option->state & State_Horizontal) {
+ const int offset = rect.width()/2;
+ painter->drawLine(rect.bottomLeft().x() + offset,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset,
+ rect.topLeft().y() + margin);
+ painter->setPen(QPen(option->palette.background().color().light(110)));
+ painter->drawLine(rect.bottomLeft().x() + offset + 1,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset + 1,
+ rect.topLeft().y() + margin);
+ } else { //Draw vertical separator
+ const int offset = rect.height()/2;
+ painter->setPen(QPen(option->palette.background().color().dark(110)));
+ painter->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset);
+ painter->setPen(QPen(option->palette.background().color().light(110)));
+ painter->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset + 1,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset + 1);
+ }
+ }
+ break;
+ case PE_IndicatorToolBarHandle:
+ painter->save();
+ {
+ QColor gripColor = shadow;
+ if (d->internalPalette != DotNetStylePrivate::System)
+ gripColor = shadow.darker(120);
+ if (option->state & State_Horizontal) {
+ for (int i = rect.height()/5; i <= 4*(rect.height()/5) ; i+=4) {
+ int y = rect.topLeft().y() + i + 1;
+ int x1 = rect.topLeft().x() + 3;
+ painter->fillRect(x1 + 1, y, 2, 2, Qt::white);
+ painter->fillRect(x1, y - 1, 2, 2, gripColor);
+ }
+ }
+ else { //vertical toolbar
+ for (int i = rect.width()/5; i <= 4*(rect.width()/5) ; i+=4) {
+ int x = rect.topLeft().x() + i + 1;
+ int y1 = rect.topLeft().y() + 3;
+ painter->fillRect(x , y1 + 1, 2, 2, Qt::white);
+ painter->fillRect(x - 1, y1, 2, 2, gripColor);
+ }
+ }
+ }
+ painter->restore();
+ break;
+ case PE_PanelMenuBar:
+ break;
+ default:
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawPrimitive(element, option, painter, widget);
+ else
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+
+ QColor gradientDark = d->gradientDarkColor(option);
+ QColor gradientLight = d->gradientLightColor(option);
+ QColor shadow = d->shadowColor(option);
+ QRect rect = option->rect;
+
+ switch (element) {
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ painter->save();
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ int x, y, w, h;
+ QStyleOptionMenuItem mbiCopy = *menuitem;
+ painter->fillRect(rect, d->menuBackgroundColor);
+ painter->fillRect(QRect(0, rect.top(), 25, rect.bottom()), d->menuGradient(option, rect));
+ menuitem->rect.getRect(&x, &y, &w, &h);
+
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+ ? menuitem->checked : false;
+ bool act = menuitem->state & State_Selected;
+
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = qMax(menuitem->maxIconWidth, 20);
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+ int yoff = y-1 + h / 2;
+ painter->setPen(d->menuSeparatorColor);
+ painter->drawLine(x + 32, yoff, x + w + 6, yoff);
+ painter->restore();
+ return;
+ }
+
+ QRect vCheckRect = visualRect(option->direction, menuitem->rect,
+ QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
+ vCheckRect.adjust(2, 0, 0, 0);
+
+ if (act) {
+ painter->setPen(d->highlightOutlineColor(option));
+ painter->setBrush(d->highlightBrush(option, false));
+ painter->drawRect(option->rect.adjusted(0, 0, -2, -2));
+ }
+
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ painter->setPen(menuitem->palette.text().color());
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checked) {
+ painter->save();
+ painter->setPen(d->highlightOutlineColor(option, act));
+ painter->setBrush(d->highlightMenuCheckBrush(option, act));
+ painter->drawRect(vCheckRect.adjusted(-1, 1, 0, -3));
+ painter->restore();
+
+ QStyleOptionMenuItem newMi = *menuitem;
+ newMi.state = State_None;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+ newMi.rect = visualRect(option->direction, menuitem->rect,
+ QRect(menuitem->rect.x() + windowsItemFrame, menuitem->rect.y() + windowsItemFrame,
+ checkcol - 2 * windowsItemFrame, menuitem->rect.height() - 2*windowsItemFrame));
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, painter, widget);
+ }
+ painter->setPen(menuitem->palette.buttonText().color());
+
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ painter->setPen(discol);
+ }
+
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos + 5, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+
+ if (!s.isEmpty()) { // draw text
+ painter->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ if (dis && !act) {
+ painter->setPen(discol);
+ }
+ painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ painter->setFont(font);
+ if (dis && !act) {
+ painter->setPen(discol);
+ }
+ painter->drawText(vTextRect, text_flags, s.left(t));
+ painter->restore();
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (h - 2 * windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ drawPrimitive(arrow, &newMI, painter, widget);
+ }
+ }
+ painter->restore();
+ break;
+#endif // QT_NO_MENU
+
+ case CE_MenuEmptyArea:
+ {
+ painter->fillRect(option->rect, option->palette.base());
+ QLinearGradient grad(QPoint(rect.left() , 0), QPoint(rect.left() + 23, 0));
+ grad.setColorAt(0, gradientLight.light(110));
+ grad.setColorAt(1, gradientDark);
+ painter->fillRect(QRect(0, rect.top() + 2, 23, rect.bottom() - 3), grad);
+ }
+ break;
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ QRect rect(QPoint(0, 0), widget->window()->size());
+ {
+ if (widget->window())
+ drawPrimitive(PE_Widget, option, painter, widget);
+ }
+ if (option->state & (QStyle::State_Sunken | QStyle::State_Selected))
+ {
+ QColor highlight = shadow;
+ painter->setPen(d->menuFrameColor);
+ if (option->state & QStyle::State_Sunken) {
+
+ if (d->internalPalette == DotNetStylePrivate::System)
+ painter->setBrush(Qt::white);
+ else
+ painter->setBrush(d->menuGradient(option, option->rect, Qt::Vertical));
+
+ painter->drawRect(option->rect.adjusted(0, 2, -1, 0));
+ //draw shadow behind:
+ QColor shade = Qt::black;
+ shade.setAlpha(50);
+ painter->setBrush(shade);
+ painter->setPen(Qt::transparent);
+ QRect shadowRect(option->rect.topRight() + QPoint(0, 4), option->rect.bottomRight() + QPoint(1,0));
+ painter->drawRect(shadowRect);
+ }
+ else {
+ painter->setPen(d->highlightOutlineColor(option));
+ painter->setBrush(d->highlightBrush(option, false));
+ painter->drawRect(option->rect.adjusted(0, 2, -2, -2));
+ }
+ }
+ QStyleOptionMenuItem mbiCopy = *mbi;
+ QPalette pal = mbi->palette;
+ pal.setBrush(QPalette::All, QPalette::ButtonText, mbi->palette.text());
+ mbiCopy.palette = pal;
+ QCommonStyle::drawControl(element, &mbiCopy, painter, widget);
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ if (widget->window())
+ drawPrimitive(PE_Widget, option, painter, widget);
+ break;
+ case CE_DockWidgetTitle:
+ if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
+ painter->save();
+ if (d->internalPalette == DotNetStylePrivate::System) {
+ painter->setBrush(option->palette.dark().color().light(130));
+ painter->setPen(option->palette.dark().color());
+ } else if (d->internalPalette == DotNetStylePrivate::Classic) {
+ painter->setBrush(option->palette.background().color().dark(108));
+ painter->setPen(option->palette.dark().color());
+ } else {
+ painter->setBrush(d->toolbarGradient(option, option->rect, Qt::Horizontal));
+ QColor color = d->gradientDarkColor(option).darker(120);
+ painter->setPen(color);
+ }
+ painter->drawRect(rect.adjusted(0, 2, -1, -3));
+
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ QRect titleRect = option->rect.adjusted(6, 2, 0, 0);
+ int buttonMargin = 4;
+ int mw = pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+ if (dwOpt->closable) {
+ QPixmap pm = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).pixmap(10, 10);
+ titleRect.adjust(0, 0, -pm.size().width() - mw - buttonMargin, 0);
+ }
+ if (dwOpt->floatable) {
+ QPixmap pm = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).pixmap(10, 10);
+ titleRect.adjust(0, 0, -pm.size().width() - mw - buttonMargin, 0);
+ }
+ titleRect = visualRect(option->direction, option->rect, titleRect);
+
+ if (!dwOpt->title.isEmpty()) {
+ QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+ drawItemText(painter, titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+ painter->restore();
+ }
+ break;
+ }
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar*>(option)) {
+ painter->save();
+ rect.adjust(1, 0, 0, 0);
+
+ if (const QToolBar *tb = qobject_cast<const QToolBar *>(widget)) {
+ if (option->direction == Qt::LeftToRight)
+ rect.setRight(tb->childrenRect().right() + 2);
+ else
+ rect.setLeft(tb->childrenRect().left() - 2);
+ }
+ Qt::Orientation gradientOrientation =(toolbar->toolBarArea == Qt::RightToolBarArea ||
+ toolbar->toolBarArea == Qt::LeftToolBarArea) ? Qt::Vertical : Qt::Horizontal;
+ QLinearGradient gradient = d->toolbarGradient(toolbar, rect, gradientOrientation);
+ painter->setBrush(gradient);
+ painter->setPen(Qt::NoPen);
+
+ bool roundEdges = true;
+ if (widget && widget->parentWidget()) {
+ if (const QToolBar *tb = qobject_cast<const QToolBar *>(widget)) {
+ if (!(tb->childrenRect().width() + 32 < widget->parentWidget()->geometry().width())) {
+ roundEdges = false;
+ rect.adjust(-1, 0, 0, 0);
+ }
+ }
+ }
+ if (roundEdges) {
+ rect = rect.adjusted(1, 1, -1, 0);
+ QRegion region = rect;
+ region -= QRect(rect.left(), rect.bottom(), 2, 1);
+ region -= QRect(rect.right() - 1, rect.bottom(), 2, 1);
+ region -= QRect(rect.left(), rect.bottom() - 1, 1, 1);
+ region -= QRect(rect.right(), rect.bottom() - 1, 1, 1);
+ region -= QRect(rect.left(), rect.top(), 2, 1);
+ region -= QRect(rect.right() - 1, rect.top(), 2, 1);
+ region -= QRect(rect.left(), rect.top() + 1, 1, 1);
+ region -= QRect(rect.right(), rect.top() + 1, 1, 1);
+ painter->setClipRegion(region);
+
+ painter->fillRect(rect, gradient);
+
+ painter->setPen(QPen(shadow, 0));
+ painter->drawLine(rect.bottomLeft() + QPoint(3,0), rect.bottomRight() - QPoint(2,0));
+ painter->drawPoint(rect.bottomRight() - QPoint(1, 1));
+ QColor alphashadow = shadow;
+ alphashadow.setAlpha(128);
+ painter->setPen(QPen(alphashadow, 0));
+ painter->drawLine(rect.topRight() + QPoint(0, 2), rect.bottomRight() - QPoint(0, 2));
+ } else {
+ painter->fillRect(rect, gradient);
+ }
+ painter->restore();
+ }
+ break;
+ default:
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawControl(element, option, painter, widget);
+ else
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ switch (control) {
+ case CC_ComboBox:
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ QColor highlightedOutlineColor = d->highlightOutlineColor(option);
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+ {
+ bool active = cmb->state & State_Active &&
+ ((cmb->state & State_MouseOver)
+ || (cmb->state & State_On)
+ || (cmb->state & State_HasFocus));
+ QRect editRect = QWindowsStyle::subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget).adjusted(0, 0, 3, 1);
+ QRect rect = option->rect.adjusted(1, 1, -3, -2);
+ editRect.setLeft(rect.left());
+
+ if (cmb->subControls & SC_ComboBoxEditField) {
+ painter->save();
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ painter->setPen(QPen(editBrush.color()));
+ painter->drawRect(rect);
+ painter->fillRect(editRect, editBrush);
+
+ if (active) {
+ QColor highlight = highlightedOutlineColor;
+ painter->setPen(highlight);
+ painter->drawRect(rect);
+ }
+ painter->restore();
+ }
+
+ if (cmb->subControls & SC_ComboBoxArrow) {
+ State flags = State_None;
+
+ QRect ar = QWindowsStyle::subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget).adjusted(1, 0, -1, 0);
+ if (active) {
+ painter->save();
+ painter->fillRect(ar, d->highlightBrush(option, cmb->state & State_Sunken));
+ painter->setPen(highlightedOutlineColor);
+ painter->drawLine(ar.topLeft(), ar.bottomLeft());
+ painter->restore();
+ }
+ ar.adjust(5, 5, -2, -2);
+ if (option->state & State_Enabled)
+ flags |= State_Enabled;
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = ar;
+ arrowOpt.palette = cmb->palette;
+ arrowOpt.state = flags;
+ QWindowsStyle::drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
+ }
+ }
+ } else {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawComplexControl(control, option, painter, widget);
+ else
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ }
+ break;
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option))
+ {
+ QRect button;
+ button = subControlRect(control, toolbutton, SC_ToolButton, widget);
+ if ((widget && qobject_cast<QToolBar*>(widget->parentWidget())) &&
+ ((toolbutton->state & State_MouseOver && toolbutton->state & State_Enabled)
+ || toolbutton->state & State_On)) {
+ QLinearGradient menubargradient2(button.topLeft(), button.bottomLeft());
+
+ bool act = (toolbutton->state & State_Sunken) || (toolbutton->state & State_On);
+ painter->setPen(d->highlightOutlineColor(option, act));
+ painter->setBrush(d->highlightBrush(option, act));
+ painter->drawRect(button.adjusted(0, 0, -2, -1));
+
+ QStyleOptionComplex comp;
+ comp.init(widget);
+ comp.rect = button;
+ QStyleOptionToolButton label = *toolbutton;
+ int fw = pixelMetric(PM_DefaultFrameWidth, option, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ label.features &= ~QStyleOptionToolButton::Arrow;
+ drawControl(CE_ToolButtonLabel, &label, painter, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ QStyleOption tool = *toolbutton;
+ tool.rect = QWindowsStyle::subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
+ painter->setPen(d->highlightOutlineColor(option, act));
+ painter->setBrush(d->highlightBrush(option, toolbutton->activeSubControls & SC_ToolButtonMenu));
+ painter->drawRect(tool.rect.adjusted(-2, 0, -1, -1));
+ tool.rect.adjust(2, 3, -2, -2);
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+ }
+ } else
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawComplexControl(control, option, painter, widget);
+ else
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ }
+ break;
+
+ default:
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::drawComplexControl(control, option, painter, widget);
+ else
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+QSize DotNetStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ QSize newSize;
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ newSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget);
+ else
+ newSize = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+
+ switch (type) {
+ case CT_LineEdit:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) {
+ newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ newSize += QSize(0, 2);
+ }
+ break;
+ case CT_ComboBox:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget())) {
+ newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ newSize += QSize(0, 2);
+ }
+ break;
+ case CT_MenuBarItem:
+ newSize += QSize(0, 1);
+ break;
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
+ newSize.setHeight(2);
+ } else {
+ newSize.rwidth() += 10;
+ //ensure menu items have uniform height
+ if (newSize.height() < 22)
+ newSize.setHeight(22);
+ }
+ }
+ break;
+ case CT_Menu:
+ //work around for a menu frame issue (same as xp style)
+ newSize = size;
+ newSize -= QSize(1,2);
+ break;
+ default:
+ break;
+ }
+ return newSize;
+}
+
+/*!
+ \reimp
+ */
+QRect DotNetStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ QRect rect;
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ rect = QWindowsVistaStyle::subElementRect(element, option, widget);
+ else
+ rect = QWindowsXPStyle::subElementRect(element, option, widget);
+ if (element == SE_DockWidgetCloseButton || element == SE_DockWidgetFloatButton)
+ rect.translate(0, 1);
+ return rect;
+}
+
+/*!
+ \reimp
+ */
+QRect DotNetStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect;
+ if (control == CC_ComboBox && widget && qobject_cast<QToolBar*>(widget->parentWidget()))
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ else if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ rect = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
+ else
+ rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget);
+
+ return rect;
+}
+
+/*!
+ \reimp
+ */
+QStyle::SubControl DotNetStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget) const
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return QWindowsVistaStyle::hitTestComplexControl(control, option, pos, widget);
+ else
+ return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget);
+}
+
+/*!
+ \reimp
+ */
+int DotNetStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ int retval = 0;
+
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ retval = QWindowsVistaStyle::pixelMetric(metric, option, widget);
+ else
+ retval = QWindowsXPStyle::pixelMetric(metric, option, widget);
+
+ switch (metric) {
+ case PM_ToolBarItemSpacing:
+ retval = 2;
+ break;
+ case PM_ToolBarIconSize:
+ retval = 16;
+ break;
+ case PM_MenuHMargin:
+ retval = 1;
+ break;
+ case PM_MenuVMargin:
+ retval = 1;
+ break;
+ case PM_MenuBarPanelWidth:
+ retval = 0;
+ break;
+ case PM_MenuPanelWidth:
+ retval = 1;
+ break;
+ case PM_DockWidgetTitleBarButtonMargin:
+ retval = 6;
+ break;
+ case PM_DefaultFrameWidth:
+ case PM_SpinBoxFrameWidth:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget()))
+ retval = 2;
+ break;
+ case PM_ButtonShiftVertical:
+ case PM_ButtonShiftHorizontal:
+ if (widget && qobject_cast<QToolBar*>(widget->parentWidget()))
+ retval = 0;
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+/*!
+ \reimp
+ */
+QPalette DotNetStyle::standardPalette() const
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return QWindowsVistaStyle::standardPalette();
+ else
+ return QWindowsXPStyle::standardPalette();
+}
+
+
+void DotNetStylePrivate::updatePalette()
+{
+ //Detect color palette
+ const int maxlength = 256;
+ WCHAR themeFileName[maxlength];
+ WCHAR themeColor[maxlength];
+ internalPalette = Classic;
+ if (pIsAppThemed && pIsAppThemed() && pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
+ QString name = QString::fromUtf16((ushort *)themeFileName);
+ QString color = QString::fromUtf16((ushort *)themeColor);
+ if (theme == DotNetStyle::Standard) {
+ if (name.endsWith("Luna.msstyles")) {
+ if (color == "Metallic")
+ internalPalette = Silver;
+ else
+ internalPalette = System;
+ }
+ } else { //Office style
+ if (name.endsWith("Luna.msstyles")) {
+ if (color == "HomeStead")
+ internalPalette = Olive;
+ else if (color == "Metallic")
+ internalPalette = Silver;
+ else
+ internalPalette = Blue;
+ } else if (name.endsWith("Aero.msstyles")) {
+ internalPalette = Blue;
+ }
+ }
+ }
+
+ switch (internalPalette) {
+ case Blue:
+ menuSeparatorColor = QColor(106, 140, 203);
+ menuBackgroundColor = QColor(246, 246, 246);
+ menuFrameColor = QColor(0, 45, 150);
+ break;
+ case Silver:
+ menuSeparatorColor = QColor(110, 109, 143);
+ menuBackgroundColor = QColor(254, 250, 255);
+ menuFrameColor = QColor(124, 124, 148);
+ break;
+ case Olive:
+ menuSeparatorColor = QColor(96, 128, 88);
+ menuBackgroundColor = QColor(244, 244, 238);
+ menuFrameColor = QColor(117, 141, 94);
+ break;
+ default:
+ menuFrameColor = currentPal.dark().color().lighter(108);
+ menuSeparatorColor = currentPal.background().color().darker(110);
+ menuBackgroundColor = currentPal.light().color();
+ menuBackgroundColor.setHsv(
+ menuBackgroundColor.hue(),
+ 3 * menuBackgroundColor.saturation()/8 ,
+ 250);
+ break;
+ }
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::polish(QApplication *app)
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::polish(app);
+ else
+ QWindowsXPStyle::polish(app);
+ d->currentPal = app->palette();
+ d->updatePalette();
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::unpolish(QApplication *app)
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::unpolish(app);
+ else
+ QWindowsXPStyle::unpolish(app);
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::polish(QWidget *widget)
+{
+ if (qobject_cast<QMainWindow *>(widget))
+ widget->setAttribute(Qt::WA_StyledBackground);
+ else if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else if (qobject_cast<QComboBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::polish(widget);
+ else
+ QWindowsXPStyle::polish(widget);
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::unpolish(QWidget *widget)
+{
+ if (qobject_cast<QMainWindow *>(widget))
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ else if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else if (qobject_cast<QComboBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::unpolish(widget);
+ else
+ QWindowsXPStyle::unpolish(widget);
+}
+
+/*!
+ \reimp
+ */
+void DotNetStyle::polish(QPalette &pal)
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ QWindowsVistaStyle::polish(pal);
+ else
+ QWindowsXPStyle::polish(pal);
+}
+
+/*!
+ \reimp
+ */
+QPixmap DotNetStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return QWindowsVistaStyle::standardPixmap(standardPixmap, opt, widget);
+ else
+ return QWindowsXPStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+/*!
+ \reimp
+*/
+int DotNetStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret = 0;
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ ret = QWindowsVistaStyle::styleHint(hint, option, widget, returnData);
+ else
+ ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
+ return ret;
+}
+
+#endif //USE_DOTNET_STYLE
diff --git a/src/fqterm/3rdparty/dotnetstyle.h b/src/fqterm/3rdparty/dotnetstyle.h
new file mode 100644
index 0000000..16326b6
--- /dev/null
+++ b/src/fqterm/3rdparty/dotnetstyle.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the DotNetStyle project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+
+#ifndef QTDOTNETSTYLE_H
+#define QTDOTNETSTYLE_H
+#ifdef USE_DOTNET_STYLE
+#include <QtGui/QWindowsVistastyle.h>
+
+class QLinearGradient;
+class QBrush;
+
+class DotNetStylePrivate;
+class DotNetStyle : public QWindowsVistaStyle
+{
+public:
+ enum ColorTheme {
+ Standard,
+ Office
+ };
+ DotNetStyle();
+
+ DotNetStyle(ColorTheme palette);
+
+ ~DotNetStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QPalette &pal);
+ void polish(QApplication *app);
+ void unpolish(QApplication *app);
+ QPalette standardPalette() const;
+ DotNetStylePrivate *d;
+};
+#endif //USE_DOTNET_STYLE
+#endif
diff --git a/src/fqterm/3rdparty/qxtglobal.h b/src/fqterm/3rdparty/qxtglobal.h
new file mode 100644
index 0000000..575372d
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobal.h
@@ -0,0 +1,207 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtCore module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+
+#ifndef QXTGLOBAL_H
+#define QXTGLOBAL_H
+
+#include <QtGlobal>
+
+#define QXT_VERSION 0x000600
+#define QXT_VERSION_STR "0.6.0"
+
+//--------------------------global macros------------------------------
+
+#ifndef QXT_NO_MACROS
+
+#endif // QXT_NO_MACROS
+
+//--------------------------export macros------------------------------
+
+#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_CORE)
+# define QXT_CORE_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_CORE_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_CORE_EXPORT
+#endif // BUILD_QXT_CORE
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_GUI)
+# define QXT_GUI_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_GUI_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_GUI_EXPORT
+#endif // BUILD_QXT_GUI
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_NETWORK)
+# define QXT_NETWORK_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_NETWORK_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_NETWORK_EXPORT
+#endif // BUILD_QXT_NETWORK
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_SQL)
+# define QXT_SQL_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_SQL_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_SQL_EXPORT
+#endif // BUILD_QXT_SQL
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_WEB)
+# define QXT_WEB_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_WEB_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_WEB_EXPORT
+#endif // BUILD_QXT_WEB
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_BERKELEY)
+# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_BERKELEY_EXPORT
+#endif // BUILD_QXT_BERKELEY
+
+#if !defined(QXT_STATIC)
+# if defined(BUILD_QXT_ZEROCONF)
+# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT
+# else
+# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QXT_ZEROCONF_EXPORT
+#endif // QXT_ZEROCONF_EXPORT
+
+#if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB || defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF
+# define BUILD_QXT
+#endif
+
+QXT_CORE_EXPORT const char* qxtVersion();
+
+#ifndef QT_BEGIN_NAMESPACE
+#define QT_BEGIN_NAMESPACE
+#endif
+
+#ifndef QT_END_NAMESPACE
+#define QT_END_NAMESPACE
+#endif
+
+#ifndef QT_FORWARD_DECLARE_CLASS
+#define QT_FORWARD_DECLARE_CLASS(Class) class Class;
+#endif
+
+/****************************************************************************
+** This file is derived from code bearing the following notice:
+** The sole author of this file, Adam Higerd, has explicitly disclaimed all
+** copyright interest and protection for the content within. This file has
+** been placed in the public domain according to United States copyright
+** statute and case law. In jurisdictions where this public domain dedication
+** is not legally recognized, anyone who receives a copy of this file is
+** permitted to use, modify, duplicate, and redistribute this file, in whole
+** or in part, with no restrictions or conditions. In these jurisdictions,
+** this file shall be copyright (C) 2006-2008 by Adam Higerd.
+****************************************************************************/
+
+#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;
+#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
+#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
+#define QXT_D(PUB) PUB##Private& d = qxt_d()
+#define QXT_P(PUB) PUB& p = qxt_p()
+
+template <typename PUB>
+class QxtPrivate
+{
+public:
+ virtual ~QxtPrivate()
+ {}
+ inline void QXT_setPublic(PUB* pub)
+ {
+ qxt_p_ptr = pub;
+ }
+
+protected:
+ inline PUB& qxt_p()
+ {
+ return *qxt_p_ptr;
+ }
+ inline const PUB& qxt_p() const
+ {
+ return *qxt_p_ptr;
+ }
+
+private:
+ PUB* qxt_p_ptr;
+};
+
+template <typename PUB, typename PVT>
+class QxtPrivateInterface
+{
+ friend class QxtPrivate<PUB>;
+public:
+ QxtPrivateInterface()
+ {
+ pvt = new PVT;
+ }
+ ~QxtPrivateInterface()
+ {
+ delete pvt;
+ }
+
+ inline void setPublic(PUB* pub)
+ {
+ pvt->QXT_setPublic(pub);
+ }
+ inline PVT& operator()()
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+ inline const PVT& operator()() const
+ {
+ return *static_cast<PVT*>(pvt);
+ }
+private:
+ QxtPrivateInterface(const QxtPrivateInterface&) { }
+ QxtPrivateInterface& operator=(const QxtPrivateInterface&) { }
+ QxtPrivate<PUB>* pvt;
+};
+
+#endif // QXT_GLOBAL
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut.cpp b/src/fqterm/3rdparty/qxtglobalshortcut.cpp
new file mode 100644
index 0000000..0d8f557
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include "qxtglobalshortcut.h"
+#include "qxtglobalshortcut_p.h"
+#include <QAbstractEventDispatcher>
+#include <QtDebug>
+
+bool QxtGlobalShortcutPrivate::error = false;
+int QxtGlobalShortcutPrivate::ref = 0;
+QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0;
+QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts;
+
+QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier)
+{
+ if (!ref++)
+ prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
+}
+
+QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
+{
+ if (!--ref)
+ QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter);
+}
+
+bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
+{
+ Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
+ key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]);
+ mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods);
+ const quint32 nativeKey = nativeKeycode(key);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = registerShortcut(nativeKey, nativeMods);
+ shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();
+ return res;
+}
+
+bool QxtGlobalShortcutPrivate::unsetShortcut()
+{
+ const quint32 nativeKey = nativeKeycode(key);
+ const quint32 nativeMods = nativeModifiers(mods);
+ const bool res = unregisterShortcut(nativeKey, nativeMods);
+ shortcuts.remove(qMakePair(nativeKey, nativeMods));
+ if (!res)
+ qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();
+ key = Qt::Key(0);
+ mods = Qt::KeyboardModifiers(0);
+ return res;
+}
+
+void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
+ if (shortcut && shortcut->isEnabled())
+ emit shortcut->activated();
+}
+
+/*!
+ \class QxtGlobalShortcut
+ \inmodule QxtGui
+ \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey".
+
+ A global shortcut triggers even if the application is not active. This
+ makes it easy to implement applications that react to certain shortcuts
+ still if some other application is active or if the application is for
+ example minimized to the system tray.
+
+ Example usage:
+ \code
+ QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
+ connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
+ shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
+ \endcode
+
+ \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication.
+ */
+
+/*!
+ \fn QxtGlobalShortcut::activated()
+
+ This signal is emitted when the user types the shortcut's key sequence.
+
+ \sa shortcut
+ */
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+}
+
+/*!
+ Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
+ */
+QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
+ : QObject(parent)
+{
+ QXT_INIT_PRIVATE(QxtGlobalShortcut);
+ setShortcut(shortcut);
+}
+
+/*!
+ Destructs the QxtGlobalShortcut.
+ */
+QxtGlobalShortcut::~QxtGlobalShortcut()
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+}
+
+/*!
+ \property QxtGlobalShortcut::shortcut
+ \brief the shortcut key sequence
+
+ \bold {Note:} Notice that corresponding key press and release events are not
+ delivered for registered global shortcuts even if they are disabled.
+ Also, comma separated key sequences are not supported.
+ Only the first part is used:
+
+ \code
+ qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
+ Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
+ \endcode
+ */
+QKeySequence QxtGlobalShortcut::shortcut() const
+{
+ return QKeySequence(qxt_d().key | qxt_d().mods);
+}
+
+bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
+{
+ if (qxt_d().key != 0)
+ qxt_d().unsetShortcut();
+ return qxt_d().setShortcut(shortcut);
+}
+
+/*!
+ \property QxtGlobalShortcut::enabled
+ \brief whether the shortcut is enabled
+
+ A disabled shortcut does not get activated.
+
+ The default value is \c true.
+
+ \sa setDisabled()
+ */
+bool QxtGlobalShortcut::isEnabled() const
+{
+ return qxt_d().enabled;
+}
+
+void QxtGlobalShortcut::setEnabled(bool enabled)
+{
+ qxt_d().enabled = enabled;
+}
+
+/*!
+ Sets the shortcut \a disabled.
+
+ \sa enabled
+ */
+void QxtGlobalShortcut::setDisabled(bool disabled)
+{
+ qxt_d().enabled = !disabled;
+}
+
+#include "qxtglobalshortcut.moc" \ No newline at end of file
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut.h b/src/fqterm/3rdparty/qxtglobalshortcut.h
new file mode 100644
index 0000000..8a352b8
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_H
+#define QXTGLOBALSHORTCUT_H
+
+#include "qxtglobal.h"
+#include <QObject>
+#include <QKeySequence>
+class QxtGlobalShortcutPrivate;
+
+class QxtGlobalShortcut : public QObject
+{
+ Q_OBJECT
+ QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
+
+public:
+ explicit QxtGlobalShortcut(QObject* parent = 0);
+ explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
+ virtual ~QxtGlobalShortcut();
+
+ QKeySequence shortcut() const;
+ bool setShortcut(const QKeySequence& shortcut);
+
+ bool isEnabled() const;
+
+public Q_SLOTS:
+ void setEnabled(bool enabled = true);
+ void setDisabled(bool disabled = true);
+
+Q_SIGNALS:
+ void activated();
+};
+
+#endif // QXTGLOBALSHORTCUT_H
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp b/src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp
new file mode 100644
index 0000000..7bfbf00
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_mac.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include <Carbon/Carbon.h>
+#include "qxtglobalshortcut_p.h"
+#include <QMap>
+#include <QHash>
+#include <QtDebug>
+#include <QApplication>
+
+typedef QPair<uint, uint> Identifier;
+static QMap<quint32, EventHotKeyRef> keyRefs;
+static QHash<Identifier, quint32> keyIDs;
+static quint32 hotKeySerial = 0;
+static bool qxt_mac_handler_installed = false;
+
+OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
+{
+ // pass event to the app event filter
+ Q_UNUSED(data);
+ qApp->macEventFilter(nextHandler, event);
+ return noErr;
+}
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+//bool QxtGlobalShortcutPrivate::macEventFilter(EventHandlerCallRef caller, EventRef event)
+{
+ EventRef event = (EventRef) message;
+ if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
+ {
+ EventHotKeyID keyID;
+ GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
+ Identifier id = keyIDs.key(keyID.id);
+ activateShortcut(id.second, id.first);
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= shiftKeyBit;
+ if (modifiers & Qt::ControlModifier)
+ native |= cmdKey;
+ if (modifiers & Qt::AltModifier)
+ native |= optionKey;
+ if (modifiers & Qt::MetaModifier)
+ native |= controlKey;
+ if (modifiers & Qt::KeypadModifier)
+ native |= kEventKeyModifierNumLockMask;
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ UTF16Char ch;
+ // Constants found in NSEvent.h from AppKit.framework
+ switch (key)
+ {
+ case Qt::Key_Return:
+ return kVK_Return;
+ case Qt::Key_Enter:
+ return kVK_ANSI_KeypadEnter;
+ case Qt::Key_Tab:
+ return kVK_Tab;
+ case Qt::Key_Space:
+ return kVK_Space;
+ case Qt::Key_Backspace:
+ return kVK_Delete;
+ case Qt::Key_Control:
+ return kVK_Command;
+ case Qt::Key_Shift:
+ return kVK_Shift;
+ case Qt::Key_CapsLock:
+ return kVK_CapsLock;
+ case Qt::Key_Option:
+ return kVK_Option;
+ case Qt::Key_Meta:
+ return kVK_Control;
+ case Qt::Key_F17:
+ return kVK_F17;
+ case Qt::Key_VolumeUp:
+ return kVK_VolumeUp;
+ case Qt::Key_VolumeDown:
+ return kVK_VolumeDown;
+ case Qt::Key_F18:
+ return kVK_F18;
+ case Qt::Key_F19:
+ return kVK_F19;
+ case Qt::Key_F20:
+ return kVK_F20;
+ case Qt::Key_F5:
+ return kVK_F5;
+ case Qt::Key_F6:
+ return kVK_F6;
+ case Qt::Key_F7:
+ return kVK_F7;
+ case Qt::Key_F3:
+ return kVK_F3;
+ case Qt::Key_F8:
+ return kVK_F8;
+ case Qt::Key_F9:
+ return kVK_F9;
+ case Qt::Key_F11:
+ return kVK_F11;
+ case Qt::Key_F13:
+ return kVK_F13;
+ case Qt::Key_F16:
+ return kVK_F16;
+ case Qt::Key_F14:
+ return kVK_F14;
+ case Qt::Key_F10:
+ return kVK_F10;
+ case Qt::Key_F12:
+ return kVK_F12;
+ case Qt::Key_F15:
+ return kVK_F15;
+ case Qt::Key_Help:
+ return kVK_Help;
+ case Qt::Key_Home:
+ return kVK_Home;
+ case Qt::Key_PageUp:
+ return kVK_PageUp;
+ case Qt::Key_Delete:
+ return kVK_ForwardDelete;
+ case Qt::Key_F4:
+ return kVK_F4;
+ case Qt::Key_End:
+ return kVK_End;
+ case Qt::Key_F2:
+ return kVK_F2;
+ case Qt::Key_PageDown:
+ return kVK_PageDown;
+ case Qt::Key_F1:
+ return kVK_F1;
+ case Qt::Key_Left:
+ return kVK_LeftArrow;
+ case Qt::Key_Right:
+ return kVK_RightArrow;
+ case Qt::Key_Down:
+ return kVK_DownArrow;
+ case Qt::Key_Up:
+ return kVK_UpArrow;
+ default:
+ ;
+ }
+
+ if (key == Qt::Key_Escape) ch = 27;
+ else if (key == Qt::Key_Return) ch = 13;
+ else if (key == Qt::Key_Enter) ch = 3;
+ else if (key == Qt::Key_Tab) ch = 9;
+ else ch = key;
+
+ CFDataRef currentLayoutData;
+ TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+
+ if (currentKeyboard == NULL)
+ return 0;
+
+ currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
+ CFRelease(currentKeyboard);
+ if (currentLayoutData == NULL)
+ return 0;
+
+ UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
+ UCKeyboardTypeHeader* table = header->keyboardTypeList;
+
+ uint8_t *data = (uint8_t*)header;
+ // God, would a little documentation for this shit kill you...
+ for (quint32 i=0; i < header->keyboardTypeCount; i++)
+ {
+ UCKeyStateRecordsIndex* stateRec = 0;
+ if (table[i].keyStateRecordsIndexOffset != 0)
+ {
+ stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
+ if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
+ }
+
+ UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
+ if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
+
+ for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
+ {
+ UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
+ for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
+ {
+ if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
+ {
+ long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
+ if (stateRec && idx < stateRec->keyStateRecordCount)
+ {
+ UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
+ if (rec->stateZeroCharData == ch) return k;
+ }
+ }
+ else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
+ {
+ if (keyToChar[k] == ch) return k;
+ }
+ } // for k
+ } // for j
+ } // for i
+
+ return 0;
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ if (!qxt_mac_handler_installed)
+ {
+ EventTypeSpec t;
+ t.eventClass = kEventClassKeyboard;
+ t.eventKind = kEventHotKeyPressed;
+ InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
+ }
+
+ EventHotKeyID keyID;
+ keyID.signature = 'cute';
+ keyID.id = ++hotKeySerial;
+
+ EventHotKeyRef ref = 0;
+ bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
+ if (rv)
+ {
+ keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
+ keyRefs.insert(keyID.id, ref);
+ }
+ qDebug() << ref;
+ return rv;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ Identifier id(nativeMods, nativeKey);
+ if (!keyIDs.contains(id)) return false;
+
+ EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
+ keyIDs.remove(id);
+ return !UnregisterEventHotKey(ref);
+}
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_p.h b/src/fqterm/3rdparty/qxtglobalshortcut_p.h
new file mode 100644
index 0000000..4570396
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#ifndef QXTGLOBALSHORTCUT_P_H
+#define QXTGLOBALSHORTCUT_P_H
+
+#include "qxtglobalshortcut.h"
+#include <QAbstractEventDispatcher>
+#include <QKeySequence>
+#include <QHash>
+
+class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut>
+{
+public:
+ QXT_DECLARE_PUBLIC(QxtGlobalShortcut)
+ QxtGlobalShortcutPrivate();
+ ~QxtGlobalShortcutPrivate();
+
+ bool enabled;
+ Qt::Key key;
+ Qt::KeyboardModifiers mods;
+
+ bool setShortcut(const QKeySequence& shortcut);
+ bool unsetShortcut();
+
+ static bool error;
+ static int ref;
+ static QAbstractEventDispatcher::EventFilter prevEventFilter;
+ static bool eventFilter(void* message);
+
+private:
+ static quint32 nativeKeycode(Qt::Key keycode);
+ static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
+
+ static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
+ static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
+ static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
+
+ static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
+};
+
+#endif // QXTGLOBALSHORTCUT_P_H
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_win.cpp b/src/fqterm/3rdparty/qxtglobalshortcut_win.cpp
new file mode 100644
index 0000000..4099989
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_win.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <qt_windows.h>
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ MSG* msg = static_cast<MSG*>(message);
+ if (msg->message == WM_HOTKEY)
+ {
+ const quint32 keycode = HIWORD(msg->lParam);
+ const quint32 modifiers = LOWORD(msg->lParam);
+ activateShortcut(keycode, modifiers);
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= MOD_SHIFT;
+ if (modifiers & Qt::ControlModifier)
+ native |= MOD_CONTROL;
+ if (modifiers & Qt::AltModifier)
+ native |= MOD_ALT;
+ if (modifiers & Qt::MetaModifier)
+ native |= MOD_WIN;
+ // TODO: resolve these?
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ switch (key)
+ {
+ case Qt::Key_Escape:
+ return VK_ESCAPE;
+ case Qt::Key_Tab:
+ case Qt::Key_Backtab:
+ return VK_TAB;
+ case Qt::Key_Backspace:
+ return VK_BACK;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ return VK_RETURN;
+ case Qt::Key_Insert:
+ return VK_INSERT;
+ case Qt::Key_Delete:
+ return VK_DELETE;
+ case Qt::Key_Pause:
+ return VK_PAUSE;
+ case Qt::Key_Print:
+ return VK_PRINT;
+ case Qt::Key_Clear:
+ return VK_CLEAR;
+ case Qt::Key_Home:
+ return VK_HOME;
+ case Qt::Key_End:
+ return VK_END;
+ case Qt::Key_Left:
+ return VK_LEFT;
+ case Qt::Key_Up:
+ return VK_UP;
+ case Qt::Key_Right:
+ return VK_RIGHT;
+ case Qt::Key_Down:
+ return VK_DOWN;
+ case Qt::Key_PageUp:
+ return VK_PRIOR;
+ case Qt::Key_PageDown:
+ return VK_NEXT;
+ case Qt::Key_F1:
+ return VK_F1;
+ case Qt::Key_F2:
+ return VK_F2;
+ case Qt::Key_F3:
+ return VK_F3;
+ case Qt::Key_F4:
+ return VK_F4;
+ case Qt::Key_F5:
+ return VK_F5;
+ case Qt::Key_F6:
+ return VK_F6;
+ case Qt::Key_F7:
+ return VK_F7;
+ case Qt::Key_F8:
+ return VK_F8;
+ case Qt::Key_F9:
+ return VK_F9;
+ case Qt::Key_F10:
+ return VK_F10;
+ case Qt::Key_F11:
+ return VK_F11;
+ case Qt::Key_F12:
+ return VK_F12;
+ case Qt::Key_F13:
+ return VK_F13;
+ case Qt::Key_F14:
+ return VK_F14;
+ case Qt::Key_F15:
+ return VK_F15;
+ case Qt::Key_F16:
+ return VK_F16;
+ case Qt::Key_F17:
+ return VK_F17;
+ case Qt::Key_F18:
+ return VK_F18;
+ case Qt::Key_F19:
+ return VK_F19;
+ case Qt::Key_F20:
+ return VK_F20;
+ case Qt::Key_F21:
+ return VK_F21;
+ case Qt::Key_F22:
+ return VK_F22;
+ case Qt::Key_F23:
+ return VK_F23;
+ case Qt::Key_F24:
+ return VK_F24;
+ case Qt::Key_Space:
+ return VK_SPACE;
+ case Qt::Key_Asterisk:
+ return VK_MULTIPLY;
+ case Qt::Key_Plus:
+ return VK_ADD;
+ case Qt::Key_Comma:
+ return VK_SEPARATOR;
+ case Qt::Key_Minus:
+ return VK_SUBTRACT;
+ case Qt::Key_Slash:
+ return VK_DIVIDE;
+
+ // numbers
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ return key;
+
+ // letters
+ case Qt::Key_A:
+ case Qt::Key_B:
+ case Qt::Key_C:
+ case Qt::Key_D:
+ case Qt::Key_E:
+ case Qt::Key_F:
+ case Qt::Key_G:
+ case Qt::Key_H:
+ case Qt::Key_I:
+ case Qt::Key_J:
+ case Qt::Key_K:
+ case Qt::Key_L:
+ case Qt::Key_M:
+ case Qt::Key_N:
+ case Qt::Key_O:
+ case Qt::Key_P:
+ case Qt::Key_Q:
+ case Qt::Key_R:
+ case Qt::Key_S:
+ case Qt::Key_T:
+ case Qt::Key_U:
+ case Qt::Key_V:
+ case Qt::Key_W:
+ case Qt::Key_X:
+ case Qt::Key_Y:
+ case Qt::Key_Z:
+ return key;
+
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey);
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ return UnregisterHotKey(0, nativeMods ^ nativeKey);
+}
diff --git a/src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp b/src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp
new file mode 100644
index 0000000..2b2e6b7
--- /dev/null
+++ b/src/fqterm/3rdparty/qxtglobalshortcut_x11.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+ **
+ ** Copyright (C) Qxt Foundation. Some rights reserved.
+ **
+ ** This file is part of the QxtGui module of the Qxt library.
+ **
+ ** This library is free software; you can redistribute it and/or modify it
+ ** under the terms of the Common Public License, version 1.0, as published
+ ** by IBM, and/or under the terms of the GNU Lesser General Public License,
+ ** version 2.1, as published by the Free Software Foundation.
+ **
+ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+ ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+ ** FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ** You should have received a copy of the CPL and the LGPL along with this
+ ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
+ ** included with the source distribution for more information.
+ ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
+ **
+ ** <http://libqxt.org> <foundation@libqxt.org>
+ **
+ ****************************************************************************/
+#include "qxtglobalshortcut_p.h"
+#include <QX11Info>
+#include <X11/Xlib.h>
+
+static int (*original_x_errhandler)(Display* display, XErrorEvent* event);
+
+static int qxt_x_errhandler(Display* display, XErrorEvent *event)
+{
+ Q_UNUSED(display);
+ switch (event->error_code)
+ {
+ case BadAccess:
+ case BadValue:
+ case BadWindow:
+ if (event->request_code == 33 /* X_GrabKey */ ||
+ event->request_code == 34 /* X_UngrabKey */)
+ {
+ QxtGlobalShortcutPrivate::error = true;
+ //TODO:
+ //char errstr[256];
+ //XGetErrorText(dpy, err->error_code, errstr, 256);
+ }
+ default:
+ return 0;
+ }
+}
+
+bool QxtGlobalShortcutPrivate::eventFilter(void* message)
+{
+ XEvent* event = static_cast<XEvent*>(message);
+ if (event->type == KeyPress)
+ {
+ XKeyEvent* key = (XKeyEvent*) event;
+ activateShortcut(key->keycode,
+ // Mod1Mask == Alt, Mod4Mask == Meta
+ key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
+ }
+ return false;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
+{
+ // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
+ quint32 native = 0;
+ if (modifiers & Qt::ShiftModifier)
+ native |= ShiftMask;
+ if (modifiers & Qt::ControlModifier)
+ native |= ControlMask;
+ if (modifiers & Qt::AltModifier)
+ native |= Mod1Mask;
+ // TODO: resolve these?
+ //if (modifiers & Qt::MetaModifier)
+ //if (modifiers & Qt::KeypadModifier)
+ //if (modifiers & Qt::GroupSwitchModifier)
+ return native;
+}
+
+quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
+{
+ Display* display = QX11Info::display();
+ return XKeysymToKeycode(display, XStringToKeysym(QKeySequence(key).toString().toLatin1().data()));
+}
+
+bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ Bool owner = True;
+ int pointer = GrabModeAsync;
+ int keyboard = GrabModeAsync;
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XGrabKey(display, nativeKey, nativeMods, window, owner, pointer, keyboard);
+ XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner, pointer, keyboard); // allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
+
+bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
+{
+ Display* display = QX11Info::display();
+ Window window = QX11Info::appRootWindow();
+ error = false;
+ original_x_errhandler = XSetErrorHandler(qxt_x_errhandler);
+ XUngrabKey(display, nativeKey, nativeMods, window);
+ XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); // allow numlock
+ XSync(display, False);
+ XSetErrorHandler(original_x_errhandler);
+ return !error;
+}
diff --git a/src/fqterm/3rdparty/uaocodec.cpp b/src/fqterm/3rdparty/uaocodec.cpp
new file mode 100644
index 0000000..2e70b78
--- /dev/null
+++ b/src/fqterm/3rdparty/uaocodec.cpp
@@ -0,0 +1,15761 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "uaocodec.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TEXTCODEC
+
+#define InRange(c, lower, upper) (((c) >= (lower)) && ((c) <= (upper)))
+#define IsLatin(c) ((c) < 0x80)
+#define IsFirstByte(c) (InRange((c), 0x81, 0xFE))
+#define IsSecondByteRange1(c) (InRange((c), 0x40, 0x7E))
+#define IsSecondByteRange2(c) (InRange((c), 0xA1, 0xFE))
+#define IsSecondByte(c) (IsSecondByteRange1(c) || IsSecondByteRange2(c))
+
+#define QValidChar(u) ((u) ? QChar((ushort)(u)) : QChar(QChar::ReplacementCharacter))
+
+
+int UAOCodec::_mibEnum()
+{
+ return 0;
+}
+
+QByteArray UAOCodec::_name()
+{
+ return "UAO";
+}
+
+/*
+ * ucs4 to big5hkscs convert routing
+ */
+
+typedef struct {
+ ushort index; /* index into big table */
+ ushort used; /* bitmask of used entries */
+} Summary16;
+
+static const ushort big5_to_ucs[] =
+{
+19991, 20002, 20012, 20053, 20066, 20106, 20144, 20203, 20205, 20220,
+20252, 20362, 20479, 20546, 20560, 20600, 20696, 20702, 20724, 20758,
+20810, 20817, 20836, 20842, 20869, 20880, 20893, 20902, 20904, 20905,
+20935, 20950, 20955, 20972, 20988, 21003, 21012, 21013, 21024, 21035,
+21049, 21071, 21105, 21136, 21138, 21140, 21148, 21167, 21173, 21200,
+21248, 21255, 21284, 21318, 21343, 21395, 21424, 21469, 21539, 21584,
+21585, 21642, 21661, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 21667, 21684, 21712,
+21795, 21823, 21836, 21843, 21853, 21868, 21918, 21929, 21996, 22005,
+22051, 22096, 22140, 22154, 22164, 22176, 22191, 22232, 22272, 22361,
+22373, 22399, 22405, 22409, 22433, 22444, 22452, 22464, 22472, 22483,
+22511, 22596, 22636, 22674, 22682, 22706, 22712, 22757, 22779, 22786,
+22795, 22800, 22808, 22811, 29836, 29837, 29849, 29851, 29860, 29876,
+29881, 29896, 29900, 29904, 29907, 30018, 30037, 30062, 30093, 30110,
+30172, 30252, 30287, 30289, 30323, 30324, 30373, 30425, 30478, 30479,
+30552, 30578, 30583, 30584, 30586, 30587, 30616, 30639, 30654, 30659,
+30661, 30667, 30685, 30694, 30708, 30750, 30781, 30786, 30788, 30795,
+30801, 21782, 22775, 38964, 33883, 28948, 33398, 35158, 40236, 40206,
+36527, 24674, 26214, 34510, 25785, 37772, 22107, 28485, 35532, 29001,
+24012, 34633, 39464, 31658, 36107, 39255, 23597, 32331, 38938, 20518,
+25458, 40568, 30783, 40633, 40634, 36046, 35715, 61305, 33931, 37284,
+31331, 25776, 24061, 24214, 32865, 26965, 31466, 28710, 26812, 31095,
+28060, 36841, 31074, 22178, 34687, 21093, 31108, 28300, 37271, 31622,
+38956, 26717, 20397, 34222, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 31725, 34635,
+20534, 26893, 27542, 24910, 20855, 30495, 20516, 32622, 30452, 27097,
+24803, 25334, 21599, 38788, 22092, 20677, 22040, 34398, 22834, 22875,
+22877, 22883, 22892, 22939, 22999, 23019, 23066, 23210, 23248, 23281,
+23350, 23497, 23539, 23571, 23580, 23582, 23635, 23705, 23708, 23738,
+23739, 23745, 23797, 23802, 23829, 23832, 23870, 23891, 23900, 23917,
+23923, 23924, 23948, 23952, 23993, 24016, 24019, 24135, 24164, 24271,
+24272, 24298, 24304, 24329, 24332, 24337, 24353, 24372, 24385, 24389,
+24401, 24412, 24422, 24451, 24560, 24650, 24672, 24715, 24742, 24798,
+24849, 24864, 24865, 24892, 24893, 24984, 25015, 25076, 25107, 25117,
+25118, 25143, 24186, 27664, 21454, 20267, 20302, 21556, 22257, 22766,
+22841, 22918, 23596, 20915, 20914, 28798, 35265, 35282, 36125, 36710,
+20122, 26469, 20177, 20004, 21327, 23626, 20872, 24213, 25269, 19996,
+20105, 29366, 31868, 32416, 21351, 36711, 37048, 38271, 38376, 20384,
+20387, 20822, 21017, 21170, 21364, 22850, 24069, 26594, 27769, 20026,
+32419, 32418, 32426, 32427, 32421, 32422, 32417, 32989, 33486, 35745,
+35746, 35747, 36126, 36127, 20891, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 36712,
+38377, 38886, 39029, 39118, 39134, 20457, 20204, 20261, 20010, 20262,
+20179, 20923, 21018, 21093, 21592, 23089, 23385, 23777, 23707, 23704,
+24072, 24211, 24452, 25375, 26102, 26187, 20070, 27902, 27971, 20044,
+29421, 29384, 20137, 30757, 31210, 32442, 32433, 32441, 32431, 32445,
+32432, 32423, 32429, 32435, 32440, 32439, 32961, 33033, 21005, 35760,
+35750, 35752, 35751, 35754, 35759, 35757, 35755, 23682, 36130, 36129,
+36713, 36715, 38025, 38024, 38026, 38027, 38378, 38453, 38485, 38473,
+39269, 39532, 39592, 20266, 20255, 20390, 20391, 21153, 21160, 21306,
+21442, 21713, 38382, 34900, 22269, 22362, 22441, 25191, 22815, 23044,
+22919, 19987, 23558, 23625, 23781, 23703, 24102, 24080, 24352, 24378,
+20174, 24469, 20932, 24581, 25195, 25346, 25194, 25249, 25379, 36133,
+21551, 26011, 26025, 26172, 21206, 24323, 26465, 26541, 26432, 27682,
+20937, 27973, 28170, 27882, 27814, 20928, 29301, 29424, 29616, 20135,
+27605, 24322, 20247, 32458, 32479, 32461, 32459, 32460, 32454, 32453,
+32452, 32456, 32449, 32450, 38069, 20064, 33626, 33550, 33682, 24196,
+33483, 22788, 26415, 34926, 35269, 35268, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+35775, 35766, 35776, 35767, 35768, 35774, 35772, 35769, 36137, 36131,
+36143, 36135, 36138, 36139, 36717, 36719, 36825, 36830, 36851, 38039,
+38035, 38031, 38034, 38381, 38472, 38470, 38452, 39030, 39031, 40060,
+40479, 21348, 40614, 22791, 20263, 20254, 20975, 21056, 21019, 21171,
+21195, 20007, 21333, 21727, 21796, 20052, 22260, 23591, 22330, 25253,
+22490, 22774, 23090, 23547, 23706, 24103, 24079, 21397, 21417, 24694,
+38391, 24812, 24699, 24700, 25315, 25381, 25442, 25196, 26531, 26635,
+26632, 38054, 27531, 22771, 27695, 27689, 28044, 20945, 28270, 28065,
+27748, 27979, 27985, 28067, 26080, 29369, 33487, 30011, 30153, 21457,
+30423, 30746, 31174, 31383, 31508, 31499, 32478, 32467, 32466, 32477,
+19997, 32476, 32473, 32474, 32470, 32475, 32899, 32958, 32960, 21326,
+33713, 33484, 34394, 35270, 35780, 35789, 35777, 35778, 35791, 35781,
+35784, 35787, 35785, 35786, 35779, 36142, 36148, 36144, 36155, 36146,
+36153, 36154, 36149, 20080, 36140, 36152, 36151, 36722, 36724, 36726,
+36827, 37038, 20065, 38046, 38062, 38041, 38048, 38055, 38045, 38052,
+38051, 38389, 38384, 24320, 38386, 38388, 38387, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 38431, 38454, 38451, 38887, 39033, 39034, 39035, 39274, 39277,
+39272, 39278, 39276, 20911, 39533, 20081, 20538, 20256, 20165, 20542,
+20260, 20588, 38130, 21183, 31215, 27719, 21527, 21596, 21595, 22253,
+22278, 28034, 22359, 22366, 22488, 33556, 22885, 22920, 29233, 24574,
+24582, 24698, 25439, 25250, 25443, 26500, 26198, 26197, 26104, 20250,
+19994, 26497, 26472, 26722, 26539, 23681, 27807, 28781, 28287, 28369,
+27815, 28902, 28860, 28800, 28949, 29239, 29422, 29502, 29682, 24403,
+30415, 30544, 30529, 38606, 30860, 33410, 31509, 31908, 32463, 32482,
+32465, 32485, 32486, 20041, 32673, 22307, 32928, 33050, 32959, 33041,
+33636, 33479, 21494, 33716, 34398, 34383, 21495, 34568, 34476, 34917,
+35013, 35815, 35813, 35814, 35797, 35799, 35800, 35801, 35811, 35802,
+35805, 35803, 35809, 35810, 35808, 35807, 36156, 36164, 36158, 36159,
+36160, 36161, 36162, 36165, 36739, 36733, 36732, 36734, 20892, 36816,
+36798, 36829, 36807, 37049, 38068, 38067, 38073, 38072, 38078, 38080,
+38085, 38057, 38082, 38083, 38089, 38091, 38044, 38093, 38079, 38086,
+38392, 38504, 38589, 30005, 39044, 39037, 39039, 39036, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 39041, 39042, 39282, 39284, 39281, 39280, 39536, 39534,
+39535, 40480, 20389, 20392, 21294, 21388, 23581, 21589, 21497, 21949,
+21863, 21716, 22242, 22270, 23576, 22443, 22545, 23551, 26790, 22842,
+22849, 22954, 23454, 23517, 23545, 23649, 23853, 23702, 24065, 24124,
+24443, 24577, 24815, 24696, 24813, 24808, 25602, 25524, 25530, 30021,
+33635, 26538, 28378, 28173, 27721, 28385, 28382, 28176, 28072, 28063,
+27818, 28180, 28183, 28068, 33639, 23572, 33638, 29425, 29712, 29595,
+30111, 30113, 30127, 30186, 23613, 30417, 30805, 31087, 31096, 31181,
+31216, 27964, 31389, 31546, 31581, 32509, 32510, 32508, 32496, 32491,
+32511, 32039, 32512, 32434, 32494, 32504, 32501, 32438, 32500, 32490,
+32513, 32502, 32602, 38395, 33669, 30422, 33642, 33485, 34432, 35829,
+35821, 35820, 35748, 35819, 35823, 35828, 35824, 35826, 35825, 35827,
+35822, 23486, 36168, 36170, 36213, 36214, 36741, 36740, 36731, 36828,
+36874, 36882, 38128, 38134, 38108, 38125, 38114, 38124, 38120, 38133,
+38115, 38402, 38394, 38397, 38401, 38400, 38469, 39047, 39046, 39122,
+39290, 39292, 39285, 39287, 39539, 32942, 39600, 40483, 40482, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 20964, 40784, 20159, 20202, 20215, 20396, 20393,
+20461, 21095, 21016, 21073, 21053, 21385, 21792, 22068, 21719, 22040,
+21943, 21880, 21501, 22687, 22367, 22368, 22549, 23092, 23157, 22953,
+23047, 23046, 23485, 23457, 20889, 23618, 23956, 24092, 24223, 21416,
+24217, 21422, 24191, 24377, 24198, 34385, 24551, 24578, 24751, 24814,
+24868, 24579, 25370, 25169, 25438, 25320, 25376, 25242, 25528, 25599,
+25932, 25968, 26242, 26165, 26679, 26729, 26530, 26631, 27004, 26728,
+20048, 26526, 27431, 27527, 27572, 27974, 27900, 27905, 27975, 28291,
+28070, 28071, 27988, 28909, 22870, 33721, 30126, 30353, 30385, 30424,
+30830, 30721, 31377, 31351, 32532, 32451, 32428, 32516, 32517, 32521,
+32534, 32536, 32447, 32526, 32531, 32525, 32514, 32520, 32519, 39554,
+32610, 33014, 32932, 33714, 33643, 33931, 34430, 34583, 21355, 35850,
+35845, 35848, 35846, 35806, 35831, 35832, 35838, 35839, 35844, 35843,
+35841, 35770, 35812, 35847, 35837, 35840, 31446, 36180, 36175, 36171,
+36145, 36134, 36172, 36132, 21334, 36176, 36136, 36179, 36341, 36745,
+36742, 36749, 36744, 36743, 36718, 36750, 36747, 36746, 36866, 36801,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 37051, 37073, 37011, 38156, 38161, 38144,
+38138, 38096, 38148, 38109, 38160, 38153, 38155, 38049, 38146, 38398,
+38405, 24041, 39049, 39052, 20859, 39295, 39297, 39548, 39547, 39543,
+39542, 39549, 39550, 39545, 39544, 39607, 38393, 40063, 40065, 40489,
+40486, 40632, 40831, 20454, 20647, 20394, 24130, 21058, 21544, 21725,
+22003, 22438, 22363, 22859, 34949, 23398, 23548, 23466, 20973, 24811,
+25044, 24518, 25112, 25317, 25377, 25374, 25454, 25523, 25321, 25441,
+25285, 25373, 21382, 26195, 26196, 26137, 26726, 27178, 26641, 26925,
+26725, 26426, 26721, 28096, 27987, 27901, 27978, 27811, 28582, 28177,
+28861, 28903, 28783, 28907, 28950, 29420, 29585, 29935, 30232, 21346,
+30610, 30742, 30875, 31215, 39062, 31267, 31397, 31491, 31579, 32546,
+32547, 33830, 32538, 21439, 32543, 32540, 32537, 32457, 33147, 20852,
+33329, 33633, 33831, 33436, 34434, 33828, 35044, 20146, 35278, 35867,
+35866, 35855, 35763, 35851, 35853, 35856, 35864, 35834, 35858, 35859,
+35773, 35861, 35865, 35852, 35862, 36182, 36752, 36753, 36755, 36751,
+21150, 36873, 36831, 36797, 36951, 37050, 38189, 38191, 38192, 38169,
+38065, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 38050, 38177, 24405, 38126, 38181,
+38182, 38175, 38178, 38193, 38414, 38543, 38505, 38745, 33148, 39050,
+39048, 39057, 39060, 22836, 39059, 39056, 39302, 39279, 39300, 39301,
+39559, 39560, 39558, 39608, 39612, 40077, 40501, 40490, 40495, 40493,
+40499, 40857, 40863, 20248, 20607, 20648, 21169, 21659, 21523, 21387,
+22489, 23156, 23252, 23351, 23604, 23654, 23679, 23896, 24110, 24357,
+24212, 24691, 25103, 20987, 25380, 25319, 25311, 25601, 25947, 27609,
+26279, 26723, 26816, 26727, 26633, 27183, 27539, 27617, 27870, 28392,
+27982, 28059, 28389, 28073, 28493, 33829, 28799, 28891, 28905, 22681,
+29406, 33719, 29615, 29815, 30184, 30103, 30699, 30970, 30710, 31699,
+31914, 38214, 31937, 32553, 32489, 32554, 32533, 32551, 32503, 32541,
+24635, 32437, 32555, 32420, 32549, 32358, 32550, 22768, 32874, 32852,
+32824, 33043, 32966, 33080, 33037, 20020, 20030, 33392, 34103, 34015,
+20111, 34684, 34632, 20149, 35099, 35274, 35868, 35876, 35878, 35762,
+35854, 35875, 35874, 35466, 35879, 36186, 36187, 36141, 36185, 36235,
+36758, 36759, 27586, 36757, 33286, 36824, 36808, 37213, 38208, 38209,
+38170, 38190, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 38194, 38149, 38180, 38202,
+38201, 38203, 38206, 38199, 38420, 38421, 38417, 38385, 38544, 38582,
+34429, 38889, 39063, 39123, 39563, 39567, 40092, 40091, 40084, 40081,
+40511, 40509, 28857, 25995, 19995, 22108, 22329, 22418, 23158, 25041,
+25193, 25527, 25200, 25781, 25670, 25822, 25783, 26029, 27103, 26588,
+27099, 26592, 27428, 24402, 27553, 27899, 28182, 28388, 28174, 28293,
+27983, 28908, 28952, 29367, 29454, 29934, 30112, 30545, 30784, 31036,
+31313, 31229, 31388, 31373, 31659, 31783, 31658, 31697, 31616, 31918,
+32455, 32558, 32469, 32557, 32483, 32559, 32728, 32844, 32834, 33040,
+33169, 26087, 33832, 34013, 33632, 34546, 34633, 35280, 35294, 35871,
+35880, 35884, 35882, 36184, 36434, 36857, 36344, 36527, 36716, 36761,
+36841, 21307, 37233, 38225, 38145, 38056, 38221, 38215, 38224, 38226,
+38217, 38422, 38383, 38423, 38425, 26434, 21452, 38607, 40481, 39069,
+39068, 39064, 39066, 39067, 39311, 39306, 39304, 39569, 39617, 40104,
+40100, 40107, 40103, 40515, 40517, 40516, 22404, 22364, 23456, 24222,
+24208, 24809, 24576, 25042, 25314, 26103, 27249, 26911, 27016, 27257,
+28487, 28625, 27813, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 28626, 27896, 28865,
+29261, 29322, 20861, 29549, 29626, 29756, 30068, 30250, 30861, 31095,
+31283, 31614, 33575, 32462, 32499, 32472, 32599, 32564, 33211, 33402,
+34222, 33647, 34433, 34631, 35014, 34948, 35889, 35782, 35885, 35890,
+35749, 35887, 36192, 36190, 36343, 36762, 36735, 36766, 36793, 38236,
+38237, 38238, 38142, 38231, 38232, 38230, 38233, 38197, 38210, 38143,
+37694, 20851, 38471, 38590, 38654, 38892, 38901, 31867, 39072, 39125,
+39314, 39313, 39579, 39575, 40120, 40115, 40109, 40119, 40529, 40521,
+40522, 40524, 40527, 20029, 40628, 21149, 21657, 22052, 20005, 23453,
+24748, 24527, 25318, 25600, 32999, 27015, 28572, 28491, 28809, 29649,
+30719, 30778, 30718, 30782, 31398, 31454, 31609, 31726, 36779, 32548,
+32487, 32578, 33002, 33328, 34108, 34106, 33446, 33529, 34164, 34461,
+35124, 35273, 35302, 35758, 35793, 35893, 36194, 36193, 36280, 37322,
+38047, 38105, 38152, 38416, 39128, 39286, 39269, 39582, 33150, 39578,
+40131, 40133, 20826, 40835, 40836, 20458, 21995, 21869, 22179, 23646,
+24807, 24913, 25668, 25658, 26003, 27185, 26639, 26818, 27516, 28866,
+29306, 38262, 29838, 30302, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 32544, 32493,
+20848, 34259, 34510, 35272, 35892, 25252, 35465, 36163, 36364, 36291,
+36347, 36720, 36777, 38256, 38253, 38081, 38107, 38094, 38255, 38220,
+21709, 39038, 39074, 39144, 39537, 39584, 34022, 39585, 39621, 40141,
+40143, 33722, 40548, 40542, 40839, 40840, 21870, 20456, 20645, 21587,
+23402, 24005, 23782, 24367, 25674, 26435, 27426, 28393, 29473, 21472,
+30270, 30307, 31548, 31809, 32843, 33039, 34989, 34924, 35835, 36174,
+36189, 36399, 36396, 36756, 37094, 38136, 37492, 38657, 38801, 32366,
+39076, 39556, 39553, 40150, 40098, 40148, 40151, 40551, 40485, 40761,
+40841, 40842, 40858, 24651, 25371, 25605, 29906, 31363, 32552, 33250,
+33821, 34506, 21464, 36902, 36923, 38259, 38084, 38757, 26174, 39181,
+24778, 39551, 39564, 39635, 39633, 40157, 40158, 40156, 40502, 22065,
+22365, 25597, 30251, 30315, 32641, 34453, 35753, 35863, 35894, 33395,
+36195, 37247, 38643, 28789, 38701, 39078, 39588, 39699, 39751, 40078,
+40560, 40557, 30839, 30416, 40140, 40844, 40843, 21381, 27012, 28286,
+31729, 31657, 34542, 35266, 36433, 34885, 38053, 39045, 39307, 39627,
+40649, 28390, 30633, 38218, 38831, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 39540,
+39589, 32518, 35872, 36495, 37245, 38075, 37550, 38179, 40132, 40072,
+40681, 20991, 40550, 39562, 40563, 40510, 38074, 20162, 34381, 27538,
+22439, 22395, 25099, 20451, 21037, 21389, 21593, 21370, 32424, 33543,
+38023, 38022, 21591, 24362, 31059, 32446, 37071, 38028, 21072, 21286,
+22261, 22445, 23045, 23741, 23811, 28062, 28172, 28867, 30502, 32448,
+32464, 33003, 38030, 38032, 38037, 38029, 38379, 22955, 23899, 24701,
+26720, 26536, 27817, 27976, 30066, 30743, 32471, 33757, 35271, 35765,
+35790, 35794, 36150, 36147, 36730, 36725, 36728, 36911, 37075, 37124,
+38059, 38060, 38043, 38063, 38061, 38058, 38390, 38503, 39032, 39275,
+40697, 20251, 20603, 20325, 21794, 22450, 24047, 24493, 28828, 33557,
+29426, 29614, 32488, 32480, 32481, 32671, 33645, 34545, 35795, 35798,
+35817, 35796, 35804, 36241, 36738, 36737, 37036, 38090, 38088, 38064,
+38066, 38070, 38157, 38092, 38077, 38076, 39043, 39040, 20971, 40702,
+20606, 21787, 23901, 24123, 24747, 24749, 24580, 25132, 25111, 25247,
+25248, 25532, 26724, 26473, 33637, 27986, 27812, 28829, 30386, 30720,
+32507, 32498, 32495, 32506, 33715, 35275, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+35830, 36167, 38129, 38098, 38097, 38101, 38111, 38123, 38127, 38122,
+38135, 38102, 38117, 39121, 21055, 21154, 21715, 21586, 23810, 23780,
+24209, 24870, 25378, 26912, 27637, 39053, 28061, 28514, 28064, 28375,
+29711, 29825, 30231, 32515, 32535, 32524, 32527, 32529, 33628, 33932,
+33553, 33473, 35833, 35836, 35842, 36181, 37112, 38162, 38103, 38141,
+38163, 38154, 38116, 38150, 38151, 38164, 38406, 38403, 38739, 39055,
+39293, 39541, 39552, 40066, 40488, 21714, 21717, 21721, 23250, 23748,
+24639, 27546, 27981, 28904, 29443, 29423, 30876, 31405, 32279, 32539,
+33927, 33640, 33929, 33630, 33720, 33431, 34547, 35816, 35857, 35860,
+35869, 37072, 38185, 38188, 38166, 38167, 38140, 38171, 38165, 38174,
+38036, 38415, 38408, 38409, 38410, 38412, 38413, 40498, 40497, 21724,
+24113, 24697, 25672, 58305, 27894, 29461, 29971, 30213, 30187, 30807,
+31654, 31578, 31976, 32545, 32807, 33631, 33718, 34544, 35042, 35279,
+35873, 35788, 35877, 36292, 38200, 38196, 38113, 38198, 38418, 39271,
+40082, 40085, 40504, 40505, 40506, 40832, 24636, 25669, 25784, 27898,
+30102, 32523, 32873, 33641, 34789, 34414, 35764, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 35881, 36188, 36157, 36760, 37021, 38227, 38112, 38204, 38223,
+34021, 38890, 39273, 39568, 39570, 39571, 38411, 40105, 40096, 40520,
+40513, 40518, 21411, 21590, 22406, 27104, 26638, 27655, 27895, 28486,
+31074, 32562, 32563, 32628, 33315, 34511, 34431, 35043, 35281, 35311,
+35886, 38235, 38239, 38250, 38214, 38121, 38891, 39073, 39312, 39618,
+40117, 40118, 40123, 40113, 40526, 40491, 40700, 21950, 25732, 26634,
+26533, 26636, 32561, 32845, 33551, 33480, 34162, 34548, 34686, 38132,
+38246, 38248, 38241, 38243, 38212, 38251, 38119, 38244, 38137, 38426,
+39071, 39316, 39546, 39581, 39583, 39576, 40535, 40538, 40540, 40838,
+40837, 20649, 23743, 30152, 25786, 27017, 28384, 30779, 31901, 32425,
+32556, 34105, 36166, 38257, 38396, 39129, 39586, 39574, 39580, 40101,
+40142, 40144, 40547, 40536, 40574, 20865, 23048, 28757, 25874, 30271,
+31656, 31860, 33339, 35276, 36345, 36318, 36729, 38228, 38252, 39587,
+39557, 40149, 40099, 40102, 40552, 40503, 40859, 26686, 26916, 34016,
+38624, 36723, 40159, 40095, 40553, 40556, 40554, 40555, 40519, 28751,
+31766, 35888, 39628, 31550, 31900, 32565, 33044, 36479, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 38247, 40090, 36273, 36508, 37246, 35891, 39070, 39079,
+39591, 40492, 25094, 38404, 40097, 40514, 31160, 25300, 36299, 29648,
+23467, 25296, 27585, 20943, 31108, 21525, 28508, 34972, 37095, 20857,
+25144, 25243, 25383, 25531, 25566, 25594, 25745, 25792, 25825, 25846,
+25861, 25909, 25934, 25963, 25992, 26073, 26142, 26171, 26175, 26180,
+26199, 26217, 26227, 26243, 26300, 26303, 26305, 26357, 26362, 26363,
+26382, 26390, 26423, 26468, 26470, 26534, 26535, 26537, 26619, 26621,
+26624, 26625, 26629, 26654, 26698, 26706, 26709, 26713, 26765, 26809,
+26831, 20616, 38184, 40087, 26914, 26918, 220, 58591, 58592, 252,
+58594, 58595, 220, 252, 26934, 26977, 33477, 33482, 33496, 33560,
+33562, 33571, 33606, 33627, 33634, 33644, 33646, 33692, 33695, 33717,
+33724, 33783, 33834, 33864, 33884, 33890, 33924, 33928, 34012, 34019,
+34104, 34138, 34199, 34219, 34241, 34323, 34326, 8715, 34581, 34672,
+34685, 34699, 34728, 34759, 34768, 34823, 34830, 34855, 34990, 8712,
+34997, 35007, 35045, 35061, 35100, 35101, 35191, 35303, 35383, 35500,
+35546, 35675, 35697, 35883, 35898, 35964, 35982, 36014, 36114, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 36169, 36173, 36209, 36360, 36410, 36464, 36505,
+36528, 36529, 36549, 36550, 36558, 36579, 36620, 36721, 36727, 36775,
+36847, 36878, 36921, 36965, 37001, 37086, 37141, 37334, 37339, 37342,
+37345, 37349, 37366, 37372, 37417, 37420, 65287, 37465, 37495, 37613,
+37690, 58701, 58702, 29227, 20866, 20886, 20023, 20843, 20799, 58709,
+58710, 26409, 27706, 21378, 30098, 32896, 34916, 19974, 58718, 58719,
+58720, 11927, 21241, 21269, 8225, 58725, 13316, 58727, 58728, 58729,
+58730, 58731, 20981, 58733, 23662, 58735, 22231, 20128, 20907, 11904,
+27079, 58741, 9550, 9688, 9689, 9794, 9654, 9668, 8597, 8252,
+ 182, 8704, 8616, 8596, 8962, 58755, 58756, 20124, 24746, 22311,
+22258, 21307, 22769, 36920, 38560, 26628, 21942, 39365, 35585, 20870,
+32257, 24540, 27431, 27572, 26716, 22885, 31311, 20206, 20385, 30011,
+28784, 20250, 24724, 28023, 32117, 22730, 25040, 25313, 27579, 35226,
+23398, 27005, 21917, 28167, 58794, 24059, 38501, 21223, 23515, 28450,
+38306, 27475, 35251, 27671, 24112, 25135, 29344, 34384, 26087, 24613,
+25312, 25369, 34394, 23777, 25375, 29421, 37111, 38911, 26241, 21220,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 35641, 21306, 39366, 21234, 58824, 24452,
+33550, 24693, 25522, 28179, 32076, 34509, 36605, 32153, 40335, 25731,
+30476, 20537, 21091, 38522, 22287, 26908, 27177, 38997, 39443, 21427,
+21577, 23087, 35492, 24195, 28207, 37489, 21495, 22269, 40658, 31296,
+30741, 28168, 25998, 27507, 21092, 38609, 21442, 26719, 24808, 36059,
+27531, 27503, 20816, 36766, 28287, 23455, 20889, 33294, 25448, 37320,
+23551, 21454, 34886, 24467, 28171, 29539, 32294, 31899, 20966, 23558,
+31216, 28169, 28988, 22888, 26465, 29366, 20055, 27972, 21104, 30067,
+32260, 22732, 23330, 35698, 37304, 35302, 22065, 23517, 23613, 22259,
+31883, 37204, 31298, 38543, 39620, 26530, 25968, 25454, 28716, 22768,
+25993, 38745, 31363, 25666, 32118, 23554, 27973, 25126, 36341, 37549,
+28508, 36983, 36984, 32330, 31109, 30094, 22766, 20105, 33624, 25436,
+25407, 24035, 31379, 35013, 20711, 23652, 32207, 39442, 22679, 24974,
+34101, 36104, 33235, 23646, 32154, 22549, 23550, 24111, 28382, 28381,
+25246, 27810, 28655, 21336, 22022, 22243, 26029, 24382, 36933, 26172,
+37619, 24193, 24500, 32884, 25074, 22618, 36883, 37444, 28857, 36578,
+20253, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 38651, 28783, 24403, 20826, 30423,
+31282, 38360, 24499, 27602, 29420, 35501, 23626, 38627, 24336, 24745,
+33075, 25309, 24259, 22770, 26757, 21338, 34180, 40614, 32283, 30330,
+39658, 25244, 27996, 27996, 25935, 25975, 20398, 25173, 20175, 36794,
+22793, 27497, 33303, 31807, 21253, 23453, 25265, 27873, 32990, 30770,
+35914, 39165, 22696, 27598, 28288, 33032, 40665, 35379, 34220, 36493,
+19982, 35465, 25671, 27096, 35617, 26332, 26469, 38972, 20081, 35239,
+31452, 38534, 26053, 20001, 29471, 32209, 28057, 22593, 31036, 21169,
+25147, 38666, 40802, 26278, 27508, 24651, 32244, 37676, 28809, 21172,
+27004, 37682, 28286, 24357, 20096, 26365, 22985, 23437, 23947, 27179,
+26907, 21936, 31874, 36796, 27018, 21682, 40235, 38635, 26905, 25539,
+39364, 20967, 26626, 36795, 20685, 23776, 26627, 20970, 21250, 30834,
+30033, 30048, 22138, 37618, 22592, 26622, 20451, 26466, 31870, 21249,
+20452, 20453, 20969, 21498, 21720, 22222, 22310, 22327, 22328, 22408,
+22451, 22442, 22448, 22486, 22640, 22713, 22743, 23670, 23740, 23749,
+23742, 23926, 24342, 24634, 25525, 26433, 26467, 26529, 26810, 26917,
+26920, 27258, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 26915, 26913, 27006, 27009,
+27101, 27182, 27250, 27423, 27615, 28181, 29077, 29927, 29938, 29936,
+29937, 29944, 29957, 30057, 30314, 30836, 31437, 31439, 31445, 31443,
+31457, 31472, 31490, 31763, 31767, 31888, 31917, 31936, 31960, 32155,
+32261, 32359, 32387, 32400, 33188, 33373, 33826, 34009, 34352, 34475,
+34543, 34992, 35011, 35012, 35076, 59183, 36542, 36552, 36684, 36791,
+36826, 36903, 36950, 37685, 37691, 37817, 38282, 38294, 38777, 38790,
+38800, 39082, 39830, 39831, 39860, 39887, 39889, 39890, 39922, 39921,
+39984, 40007, 40026, 40176, 40262, 40292, 40363, 20036, 21583, 25368,
+39857, 40041, 40263, 40293, 39983, 40639, 20916, 21610, 26528, 39822,
+37032, 20914, 13869, 25285, 21189, 26545, 21709, 24658, 21441, 28913,
+22531, 21855, 37390, 30528, 29756, 29002, 28377, 21472, 29486, 35023,
+30861, 32675, 32171, 36394, 37979, 25452, 24487, 23557, 32827, 23791,
+14776, 29009, 36045, 38894, 22642, 23139, 32632, 23895, 24943, 27032,
+32137, 31918, 32179, 28545, 23290, 22715, 29269, 30286, 36653, 37561,
+40286, 40623, 32583, 40388, 36120, 20915, 34412, 21668, 21414, 21030,
+26422, 20001, 21364, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24313, 21177, 21647,
+24312, 22956, 24625, 29248, 33047, 30267, 24333, 26187, 26280, 24932,
+25423, 28895, 27940, 31911, 31945, 21465, 25933, 22338, 29647, 32966,
+13649, 27445, 30849, 21452, 29483, 29482, 29641, 30026, 23033, 29124,
+29966, 32220, 39393, 35241, 28662, 14935, 25834, 15341, 27809, 28284,
+30055, 22633, 22633, 20996, 59338, 24967, 25658, 33263, 59342, 20917,
+20945, 27769, 22815, 36857, 39153, 25911, 33033, 34996, 14890, 36525,
+32663, 39440, 32037, 27336, 20876, 21031, 59360, 33050, 21408, 21410,
+27738, 27703, 33304, 21894, 24315, 20937, 30897, 37474, 21357, 20931,
+59374, 33905, 35207, 38765, 35728, 38563, 24316, 38583, 20814, 39952,
+26160, 37461, 30728, 37701, 37491, 37737, 59390, 59391, 59392, 59393,
+37343, 37338, 30804, 30822, 30856, 30902, 30919, 30930, 30935, 8491,
+ 8651, 30948, 30958, 30960, 30961, 30965, 31026, 31027, 31030, 31064,
+12307, 31065, 31089, 31102, 31107, 31110, 31111, 31121, 31129, 31135,
+31141, 31202, 31217, 31220, 31274, 31290, 31301, 31333, 31420, 31426,
+31433, 31451, 31465, 31486, 31500, 31527, 31529, 31554, 31555, 31573,
+31599, 31666, 27102, 27129, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 37238, 33114,
+33527, 21579, 33074, 32957, 33816, 37214, 37232, 37260, 33096, 59459,
+17462, 33113, 32927, 59463, 21833, 21537, 21722, 21554, 21945, 21652,
+59470, 30802, 30789, 30796, 59474, 33981, 33820, 33476, 59478, 33915,
+35629, 59481, 22347, 59483, 59484, 22341, 34766, 22112, 21994, 22139,
+32956, 59491, 30904, 27148, 21708, 31696, 31724, 31738, 31765, 31771,
+31797, 31812, 31853, 31886, 31928, 31939, 31974, 31981, 31987, 31989,
+31993, 59511, 31996, 32139, 32151, 32164, 32168, 32205, 32208, 32211,
+32229, 32253, 27154, 27170, 27184, 27190, 27237, 59527, 59528, 59529,
+59530, 59531, 59532, 59533, 59534, 27251, 27256, 59537, 59538, 27260,
+27305, 27306, 9450, 9312, 9313, 9314, 9315, 9316, 9317, 9318,
+ 9319, 9320, 9321, 9322, 9323, 9324, 9325, 9326, 9327, 9328,
+ 9329, 9330, 9331, 37700, 37805, 37830, 37861, 37914, 37921, 37950,
+37953, 37971, 37978, 38042, 38071, 38104, 38110, 38131, 38147, 38158,
+38159, 38168, 38173, 38186, 38187, 38207, 38213, 38222, 38242, 38245,
+38249, 38258, 38279, 38297, 38304, 38322, 38502, 38557, 38575, 38578,
+38707, 38715, 38733, 38735, 38737, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 38741,
+38756, 38763, 38769, 38802, 38834, 38898, 38973, 38996, 39077, 39107,
+39130, 39150, 39197, 39200, 39267, 39296, 39303, 39309, 39315, 39317,
+39356, 39368, 39410, 39606, 39641, 39646, 39695, 39753, 39794, 39811,
+39839, 39867, 39907, 39925, 39936, 39940, 39963, 9398, 9399, 9400,
+ 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410,
+ 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420,
+ 9421, 9422, 9423, 9424, 9425, 9426, 9427, 9428, 9429, 9430,
+ 9431, 9432, 9433, 9434, 9435, 9436, 9437, 9438, 9439, 9440,
+ 9441, 9442, 9443, 9444, 9445, 9446, 9447, 9448, 9449, 174,
+ 8482, 59697, 59698, 40054, 10102, 10103, 10104, 10105, 10106, 10107,
+10108, 10109, 10110, 10111, 40069, 40070, 40071, 40075, 40080, 40094,
+40110, 40112, 40114, 40116, 40122, 40124, 40125, 40134, 40135, 40138,
+40139, 40147, 40152, 40153, 40162, 40171, 40172, 40234, 40264, 40272,
+40314, 40390, 40523, 40533, 40539, 40561, 40618, 40637, 40644, 40674,
+40682, 40712, 40715, 40717, 40737, 40772, 40785, 40861, 64014, 64015,
+64017, 64019, 64020, 64024, 64031, 64032, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+64033, 64035, 64036, 64039, 64040, 64041, 19972, 20015, 20097, 20103,
+20131, 20151, 20156, 20216, 20264, 20265, 20279, 20290, 20293, 20299,
+20338, 20386, 20400, 20413, 20424, 20428, 20464, 20466, 20473, 20483,
+20488, 20532, 20539, 20568, 20582, 20609, 20624, 20668, 20688, 20703,
+20705, 20732, 20749, 20779, 20832, 20910, 20920, 20946, 20962, 20997,
+21044, 21052, 21081, 21096, 21113, 21156, 21196, 21287, 21314, 21341,
+21373, 21374, 21445, 21456, 21458, 21502, 21613, 21637, 21651, 21662,
+21689, 21731, 21743, 21773, 21784, 21797, 21800, 21803, 21831, 21881,
+21904, 21940, 21953, 21975, 21976, 22011, 20404, 22049, 8707, 22098,
+59852, 9787, 59854, 59855, 22109, 9332, 9333, 9334, 9335, 9336,
+ 9337, 9338, 9339, 9340, 9341, 9342, 9343, 9344, 9345, 9346,
+ 9347, 9348, 9349, 9350, 9351, 22113, 22153, 22155, 22174, 22177,
+22193, 22201, 22207, 22230, 22255, 22293, 22301, 22322, 22333, 22335,
+22339, 8660, 22398, 22410, 22413, 22416, 22428, 22459, 22462, 22468,
+22494, 22526, 22546, 22562, 22599, 22620, 22623, 22643, 22695, 22698,
+22704, 22709, 22710, 22731, 22736, 22752, 22789, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 22801, 22921, 22932, 22938, 22943, 22960, 22968, 22980, 23023,
+23024, 23032, 23042, 23051, 23053, 23058, 23073, 23076, 23079, 23082,
+23083, 23084, 23101, 23109, 23124, 23129, 23137, 23144, 23147, 23150,
+23153, 23161, 23166, 23169, 23170, 23174, 23176, 23185, 23193, 23200,
+23201, 23211, 23235, 23246, 23247, 23251, 23268, 23280, 23294, 23309,
+23313, 23317, 23327, 23339, 23361, 23364, 23366, 23370, 23375, 23400,
+23412, 23414, 23420, 23426, 23440, 9372, 9373, 9374, 9375, 9376,
+ 9377, 9378, 9379, 9380, 9381, 9382, 9383, 9384, 9385, 9386,
+ 9387, 9388, 9389, 9390, 9391, 9392, 9393, 9394, 9395, 9396,
+ 9397, 60009, 12850, 12849, 27307, 23446, 9352, 9353, 9354, 9355,
+ 9356, 9357, 9358, 9359, 9360, 9361, 9362, 9363, 9364, 9365,
+ 9366, 9367, 9368, 9369, 9370, 9371, 23509, 23511, 23587, 23685,
+23710, 23746, 23824, 23852, 23855, 23880, 23894, 23920, 23931, 23941,
+23972, 23979, 23990, 24001, 24023, 24073, 24136, 24210, 24253, 24334,
+24434, 24497, 24514, 24539, 24543, 24611, 24702, 24791, 24839, 24844,
+24857, 24866, 24912, 24928, 24961, 24981, 25017, 25024, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 25039, 25043, 25050, 25232, 25393, 8835, 25399, 25465,
+25483, 25537, 25570, 25574, 25595, 25598, 25607, 25650, 25656, 25659,
+25690, 25713, 25724, 25741, 25775, 25780, 25782, 25821, 25829, 25866,
+25873, 25887, 25951, 25965, 25990, 26037, 26046, 26065, 26068, 26083,
+26111, 26136, 26147, 26211, 26219, 26237, 26245, 26258, 26266, 26276,
+26285, 26291, 26294, 26317, 26318, 26370, 26380, 26393, 26436, 26475,
+26511, 26532, 26559, 26582, 26583, 8834, 26637, 26640, 26651, 26678,
+26695, 26710, 26756, 26760, 26813, 26819, 26821, 26882, 26883, 26889,
+26904, 26947, 26950, 26980, 26983, 26994, 27013, 27039, 27042, 27089,
+27093, 27094, 39457, 39462, 39471, 27329, 22975, 27105, 27139, 27162,
+27164, 27180, 27181, 27187, 27203, 27205, 27212, 27219, 27223, 27235,
+27252, 27266, 27274, 27279, 27289, 27303, 27313, 27317, 27326, 27337,
+27348, 27352, 27382, 27479, 27514, 27612, 27676, 27697, 27736, 27758,
+27765, 27775, 27823, 27851, 27871, 27903, 27906, 27909, 27910, 27942,
+27991, 27995, 28017, 28033, 28047, 28069, 28081, 28158, 28162, 28164,
+28175, 28184, 28202, 28240, 28249, 28314, 28341, 28344, 28379, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 28410, 28420, 28427, 28428, 28438, 28439, 28468,
+28477, 28502, 28537, 28554, 28573, 28575, 28603, 28606, 28627, 28633,
+28664, 28675, 28747, 28749, 28752, 28756, 28764, 28775, 28791, 28793,
+28811, 28815, 28832, 28835, 28837, 28838, 28839, 28868, 28876, 28880,
+28886, 618, 603, 230, 652, 593, 596, 650, 605, 601,
+ 602, 604, 609, 7747, 7753, 330, 7739, 629, 240, 643,
+ 658, 679, 676, 227, 60294, 60295, 623, 632, 647, 60299,
+ 199, 339, 594, 65351, 715, 719, 65345, 65346, 65348, 65349,
+65350, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360,
+65362, 65363, 65364, 65365, 65366, 65367, 65370, 28917, 12832, 12833,
+12834, 12835, 12836, 12837, 12838, 12839, 12840, 12841, 28926, 28933,
+28957, 28969, 28971, 28972, 28979, 28981, 28987, 28990, 28992, 29007,
+29035, 29045, 29047, 29052, 29054, 29068, 29070, 29073, 29078, 29090,
+29091, 29101, 29108, 29111, 29114, 29137, 29149, 29163, 29184, 29193,
+29198, 29199, 29206, 29207, 29220, 23204, 29230, 8838, 29271, 29276,
+29332, 29444, 29456, 29505, 29556, 29580, 29583, 29592, 29596, 29598,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 29607, 29610, 29653, 29665, 29666, 29668,
+29670, 29679, 29683, 8839, 29689, 29691, 29698, 29713, 29714, 29716,
+29717, 29719, 29721, 29724, 29726, 29727, 29751, 29752, 29753, 29763,
+29765, 29767, 29768, 29769, 29779, 29782, 29797, 29803, 29804, 29812,
+29818, 29826, 21378, 24191, 20008, 24186, 20886, 23424, 21353, 11911,
+60436, 21251, 9746, 33401, 17553, 11916, 11914, 20022, 60444, 21274,
+60446, 60447, 11925, 60449, 60450, 9492, 20058, 36790, 24308, 20872,
+20101, 60457, 20031, 60459, 60460, 20059, 21430, 36710, 32415, 35744,
+36125, 40479, 38376, 38021, 38429, 25164, 27701, 20155, 24516, 28780,
+11950, 21475, 27362, 39483, 39484, 39512, 39516, 39523, 9742, 8594,
+ 8592, 8593, 8595, 8680, 8678, 8679, 8681, 8680, 8678, 8679,
+ 8681, 9758, 9756, 9755, 9759, 12310, 12311, 9675, 10005, 10003,
+22267, 9789, 22813, 26189, 29221, 10025, 10017, 9786, 9785, 60515,
+60516, 60517, 60518, 60519, 23672, 9836, 9834, 23249, 23479, 23804,
+60526, 9993, 9986, 60529, 60530, 60531, 60532, 23765, 26478, 29793,
+29853, 32595, 34195, 10063, 60540, 60541, 23928, 24379, 60544, 9473,
+ 9475, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 60547, 60548, 60549, 60550, 60551,
+60552, 60553, 60554, 60555, 60556, 60557, 60558, 60559, 60560, 60561,
+39602, 39648, 39700, 39732, 39737, 39744, 39760, 39807, 9788, 32149,
+ 9729, 38708, 9730, 60575, 60576, 60577, 9992, 60579, 60580, 60581,
+60582, 60583, 60584, 60585, 8507, 8481, 26343, 28247, 60590, 29015,
+31178, 8470, 33132, 35577, 38998, 60597, 60598, 9760, 60600, 9828,
+ 9824, 9831, 9827, 9826, 9830, 9825, 9829, 60609, 60610, 27364,
+ 8478, 13250, 13272, 13217, 60616, 13221, 60618, 60619, 60620, 60621,
+60622, 9745, 39809, 39819, 39821, 39901, 39913, 39917, 39924, 39967,
+39968, 39974, 40019, 40029, 40059, 40204, 40214, 8626, 27397, 36073,
+36082, 36099, 36113, 36124, 36218, 36265, 36288, 36353, 36366, 36422,
+36456, 36465, 36478, 36480, 36534, 36537, 36540, 36547, 36580, 36589,
+36594, 36656, 36673, 36682, 36773, 36787, 36792, 36810, 36815, 36872,
+36915, 36919, 36964, 36972, 37289, 37302, 37316, 37370, 37384, 37395,
+37409, 37416, 37419, 37429, 37436, 37441, 37464, 37469, 37471, 37483,
+37486, 37505, 37508, 37513, 37519, 37553, 37562, 37567, 37588, 37595,
+37603, 37605, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 37611, 37612, 37620, 37622,
+37629, 37635, 37639, 37680, 37681, 37696, 37698, 37699, 37727, 37730,
+37734, 37736, 37747, 37748, 37752, 37757, 37761, 37764, 37766, 37767,
+37776, 37788, 37792, 37816, 37819, 37821, 37823, 37835, 37843, 37851,
+37856, 37872, 37873, 37875, 37876, 37889, 37892, 37896, 37911, 37915,
+37917, 37924, 37925, 37926, 37933, 37954, 37955, 37965, 37972, 37976,
+37989, 37991, 37996, 38009, 38011, 38264, 38277, 38310, 38314, 38486,
+38523, 38565, 38644, 38683, 38710, 38720, 38721, 38743, 38791, 38793,
+38811, 38833, 38845, 38848, 38850, 38866, 38880, 38932, 38933, 38947,
+38963, 39016, 39095, 39097, 39111, 39114, 39136, 39137, 39148, 39157,
+40225, 40244, 40249, 40265, 40270, 40301, 8759, 40302, 40316, 40323,
+40339, 40357, 8748, 40381, 27521, 27569, 40015, 40592, 40384, 60817,
+60818, 9775, 9776, 9783, 9779, 9780, 9781, 9778, 9782, 9777,
+40393, 40404, 40444, 40458, 40460, 40462, 40472, 40571, 40581, 40610,
+40620, 40625, 40641, 40646, 40647, 40689, 40696, 40743, 39182, 39193,
+39196, 39223, 39261, 39266, 39323, 39332, 39338, 39352, 39392, 39398,
+39413, 39455, 32254, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 32263, 32347, 32357,
+32364, 32567, 32576, 32577, 32585, 32594, 32655, 32659, 32692, 32733,
+32743, 32762, 32770, 32776, 32814, 32815, 32828, 32935, 33036, 33066,
+33076, 33090, 33110, 33156, 33189, 33252, 33364, 33381, 33403, 33415,
+33471, 33506, 33518, 33528, 33532, 33535, 33547, 33565, 33597, 33623,
+33681, 33708, 33741, 33773, 33797, 33812, 33814, 33825, 33838, 33854,
+33866, 33875, 33877, 33880, 33892, 33906, 33919, 33920, 33938, 33939,
+33942, 33955, 33982, 34014, 34017, 34018, 34020, 34040, 34051, 34053,
+34064, 34099, 8208, 34114, 34124, 34130, 34143, 34159, 34160, 34163,
+34262, 34272, 34286, 34300, 34317, 34319, 34324, 34344, 34370, 34373,
+34418, 34972, 23405, 33079, 60958, 39224, 21874, 21867, 60962, 13774,
+21873, 21946, 22001, 13778, 22000, 22021, 22050, 22061, 22083, 22046,
+22162, 31949, 21530, 21523, 21655, 26353, 30004, 21581, 22180, 22175,
+25811, 25390, 25592, 25886, 20088, 27626, 27698, 27709, 27746, 27826,
+28152, 28201, 28278, 28290, 28294, 28347, 28383, 28386, 28433, 28452,
+28532, 28561, 28597, 28659, 28661, 28859, 28864, 28943, 8706, 29013,
+29043, 29050, 61016, 21027, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 61018, 13393,
+61020, 36812, 61022, 61023, 192, 200, 204, 210, 217, 193,
+ 205, 211, 218, 257, 275, 299, 333, 363, 470, 196,
+ 203, 207, 214, 220, 198, 199, 209, 195, 213, 225,
+ 233, 237, 243, 250, 472, 228, 235, 239, 246, 252,
+ 230, 231, 241, 227, 245, 462, 283, 464, 466, 468,
+ 474, 197, 201, 29064, 216, 208, 7922, 222, 223, 170,
+ 161, 224, 232, 236, 242, 249, 476, 229, 29080, 29143,
+ 248, 240, 7923, 254, 255, 186, 191, 226, 234, 238,
+ 244, 251, 29173, 194, 202, 206, 212, 219, 184, 164,
+61110, 402, 12288, 65292, 12289, 12290, 65294, 8231, 65307, 65306,
+65311, 65281, 65072, 8230, 8229, 65104, 65105, 65106, 183, 65108,
+65109, 65110, 65111, 65372, 8211, 65073, 8212, 65075, 9588, 65076,
+65103, 65288, 65289, 65077, 65078, 65371, 65373, 65079, 65080, 12308,
+12309, 65081, 65082, 12304, 12305, 65083, 65084, 12298, 12299, 65085,
+65086, 12296, 12297, 65087, 65088, 12300, 12301, 65089, 65090, 12302,
+12303, 65091, 65092, 65113, 65114, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 65115,
+65116, 65117, 65118, 8216, 8217, 8220, 8221, 12317, 12318, 8245,
+ 8242, 65283, 65286, 65290, 8251, 167, 12291, 9675, 9679, 9651,
+ 9650, 9678, 9734, 9733, 9671, 9670, 9633, 9632, 9661, 9660,
+12963, 8453, 175, 65507, 65343, 717, 65097, 65098, 65101, 65102,
+65099, 65100, 65119, 65120, 65121, 65291, 65293, 215, 247, 177,
+ 8730, 65308, 65310, 65309, 8806, 8807, 8800, 8734, 8786, 8801,
+65122, 65123, 65124, 65125, 65126, 65374, 8745, 8746, 8869, 8736,
+ 8735, 8895, 13266, 13265, 8747, 8750, 8757, 8756, 9792, 9794,
+ 8853, 8857, 8593, 8595, 8592, 8594, 8598, 8599, 8601, 8600,
+ 8741, 8739, 65295, 65340, 8725, 65128, 65284, 65509, 12306, 65504,
+65505, 65285, 65312, 8451, 8457, 65129, 65130, 65131, 13269, 13212,
+13213, 13214, 13262, 13217, 13198, 13199, 13252, 176, 20825, 20827,
+20830, 20829, 20833, 20835, 21991, 29929, 31950, 9601, 9602, 9603,
+ 9604, 9605, 9606, 9607, 9608, 9615, 9614, 9613, 9612, 9611,
+ 9610, 9609, 9532, 9524, 9516, 9508, 9500, 9620, 9472, 9474,
+ 9621, 9484, 9488, 9492, 9496, 9581, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 9582, 9584, 9583, 9552, 9566, 9578, 9569, 9698, 9699, 9701,
+ 9700, 9585, 9586, 9587, 65296, 65297, 65298, 65299, 65300, 65301,
+65302, 65303, 65304, 65305, 8544, 8545, 8546, 8547, 8548, 8549,
+ 8550, 8551, 8552, 8553, 12321, 12322, 12323, 12324, 12325, 12326,
+12327, 12328, 12329, 21313, 21316, 21317, 65313, 65314, 65315, 65316,
+65317, 65318, 65319, 65320, 65321, 65322, 65323, 65324, 65325, 65326,
+65327, 65328, 65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336,
+65337, 65338, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352,
+65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360, 65361, 65362,
+65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370, 913, 914,
+ 915, 916, 917, 918, 919, 920, 921, 922, 923, 924,
+ 925, 926, 927, 928, 929, 931, 932, 933, 934, 935,
+ 936, 937, 945, 946, 947, 948, 949, 950, 951, 952,
+ 953, 954, 955, 956, 957, 958, 959, 960, 961, 963,
+ 964, 965, 966, 967, 968, 969, 12549, 12550, 12551, 12552,
+12553, 12554, 12555, 12556, 12557, 12558, 12559, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 12560, 12561, 12562, 12563, 12564, 12565, 12566, 12567, 12568,
+12569, 12570, 12571, 12572, 12573, 12574, 12575, 12576, 12577, 12578,
+12579, 12580, 12581, 12582, 12583, 12584, 12585, 729, 713, 714,
+ 711, 715, 9216, 9217, 9218, 9219, 9220, 9221, 9222, 9223,
+ 9224, 9225, 9226, 9227, 9228, 9229, 9230, 9231, 9232, 9233,
+ 9234, 9235, 9236, 9237, 9238, 9239, 9240, 9241, 9242, 9243,
+ 9244, 9245, 9246, 9247, 9249, 8364, 63561, 63562, 63563, 63564,
+63565, 63566, 63567, 63568, 63569, 63570, 63571, 63572, 63573, 63574,
+63575, 63576, 63577, 63578, 63579, 63580, 63581, 63582, 63583, 63584,
+63585, 63586, 63587, 63588, 63589, 19968, 20057, 19969, 19971, 20035,
+20061, 20102, 20108, 20154, 20799, 20837, 20843, 20960, 20992, 20993,
+21147, 21269, 21313, 21340, 21448, 19977, 19979, 19976, 19978, 20011,
+20024, 20961, 20037, 20040, 20063, 20062, 20110, 20129, 20800, 20995,
+21242, 21315, 21449, 21475, 22303, 22763, 22805, 22823, 22899, 23376,
+23377, 23379, 23544, 23567, 23586, 23608, 23665, 24029, 24037, 24049,
+24050, 24051, 24062, 24178, 24318, 24331, 24339, 25165, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 19985, 19984, 19981, 20013, 20016, 20025, 20043, 23609,
+20104, 20113, 20117, 20114, 20116, 20130, 20161, 20160, 20163, 20166,
+20167, 20173, 20170, 20171, 20164, 20803, 20801, 20839, 20845, 20846,
+20844, 20887, 20982, 20998, 20999, 21000, 21243, 21246, 21247, 21270,
+21305, 21320, 21319, 21317, 21342, 21380, 21451, 21450, 21453, 22764,
+22825, 22827, 22826, 22829, 23380, 23569, 23588, 23610, 23663, 24052,
+24187, 24319, 24340, 24341, 24515, 25096, 25142, 25163, 25166, 25903,
+25991, 26007, 26020, 26041, 26085, 26352, 26376, 26408, 27424, 27490,
+27513, 27595, 27604, 27611, 27663, 27700, 28779, 29226, 29238, 29243,
+29255, 29273, 29275, 29356, 29579, 19993, 19990, 19989, 19988, 19992,
+20027, 20045, 20047, 20046, 20197, 20184, 20180, 20181, 20182, 20183,
+20195, 20196, 20185, 20190, 20805, 20804, 20873, 20874, 20908, 20985,
+20986, 20984, 21002, 21152, 21151, 21253, 21254, 21271, 21277, 20191,
+21322, 21321, 21345, 21344, 21359, 21358, 21435, 21487, 21476, 21491,
+21484, 21486, 21481, 21480, 21500, 21496, 21493, 21483, 21478, 21482,
+21490, 21489, 21488, 21477, 21485, 21499, 22235, 22234, 22806, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 22830, 22833, 22900, 22902, 23381, 23427, 23612,
+24040, 24039, 24038, 24066, 24067, 24179, 24188, 24321, 24344, 24343,
+24517, 25098, 25171, 25172, 25170, 25169, 26021, 26086, 26414, 26412,
+26410, 26411, 26413, 27491, 27597, 27665, 27664, 27704, 27713, 27712,
+27710, 29359, 29572, 29577, 29916, 29926, 29976, 29983, 29992, 29993,
+30000, 30001, 30002, 30003, 30091, 30333, 30382, 30399, 30446, 30683,
+30690, 30707, 31034, 31166, 31348, 31435, 19998, 19999, 20050, 20051,
+20073, 20121, 20132, 20134, 20133, 20223, 20233, 20249, 20234, 20245,
+20237, 20240, 20241, 20239, 20210, 20214, 20219, 20208, 20211, 20221,
+20225, 20235, 20809, 20807, 20806, 20808, 20840, 20849, 20877, 20912,
+21015, 21009, 21010, 21006, 21014, 21155, 21256, 21281, 21280, 21360,
+21361, 21513, 21519, 21516, 21514, 21520, 21505, 21515, 21508, 21521,
+21517, 21512, 21507, 21518, 21510, 21522, 22240, 22238, 22237, 22323,
+22320, 22312, 22317, 22316, 22319, 22313, 22809, 22810, 22839, 22840,
+22916, 22904, 22915, 22909, 22905, 22914, 22913, 23383, 23384, 23431,
+23432, 23429, 23433, 23546, 23574, 23673, 24030, 24070, 24182, 24180,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 24335, 24347, 24537, 24534, 25102, 25100,
+25101, 25104, 25187, 25179, 25176, 25910, 26089, 26088, 26092, 26093,
+26354, 26355, 26377, 26429, 26420, 26417, 26421, 27425, 27492, 27515,
+27670, 27741, 27735, 27737, 27743, 27744, 27728, 27733, 27745, 27739,
+27725, 27726, 28784, 29279, 29277, 30334, 31481, 31859, 31992, 32566,
+32650, 32701, 32769, 32771, 32780, 32786, 32819, 32895, 32905, 32907,
+32908, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394,
+33406, 34411, 34880, 34892, 34915, 35199, 38433, 20018, 20136, 20301,
+20303, 20295, 20311, 20318, 20276, 20315, 20309, 20272, 20304, 20305,
+20285, 20282, 20280, 20291, 20308, 20284, 20294, 20323, 20316, 20320,
+20271, 20302, 20278, 20313, 20317, 20296, 20314, 20812, 20811, 20813,
+20853, 20918, 20919, 21029, 21028, 21033, 21034, 21032, 21163, 21161,
+21162, 21164, 21283, 21363, 21365, 21533, 21549, 21534, 21566, 21542,
+21582, 21543, 21574, 21571, 21555, 21576, 21570, 21531, 21545, 21578,
+21561, 21563, 21560, 21550, 21557, 21558, 21536, 21564, 21568, 21553,
+21547, 21535, 21548, 22250, 22256, 22244, 22251, 22346, 22353, 22336,
+22349, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 22343, 22350, 22334, 22352, 22351,
+22331, 22767, 22846, 22941, 22930, 22952, 22942, 22947, 22937, 22934,
+22925, 22948, 22931, 22922, 22949, 23389, 23388, 23386, 23387, 23436,
+23435, 23439, 23596, 23616, 23617, 23615, 23614, 23696, 23697, 23700,
+23692, 24043, 24076, 24207, 24199, 24202, 24311, 24324, 24351, 24420,
+24418, 24439, 24441, 24536, 24524, 24535, 24525, 24561, 24555, 24568,
+24554, 25106, 25105, 25220, 25239, 25238, 25216, 25206, 25225, 25197,
+25226, 25212, 25214, 25209, 25203, 25234, 25199, 25240, 25198, 25237,
+25235, 25233, 25222, 25913, 25915, 25912, 26097, 26356, 26463, 26446,
+26447, 26448, 26449, 26460, 26454, 26462, 26441, 26438, 26464, 26451,
+26455, 27493, 27599, 27714, 27742, 27801, 27777, 27784, 27785, 27781,
+27803, 27754, 27770, 27792, 27760, 27788, 27752, 27798, 27794, 27773,
+27779, 27762, 27774, 27764, 27782, 27766, 27789, 27796, 27800, 27778,
+28790, 28796, 28797, 28792, 29282, 29281, 29280, 29380, 29378, 29590,
+29996, 29995, 30007, 30008, 30338, 30447, 30691, 31169, 31168, 31167,
+31350, 31995, 32597, 32918, 32915, 32925, 32920, 32923, 32922, 32946,
+33391, 33426, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33419, 33421, 35211, 35282,
+35328, 35895, 35910, 35925, 35997, 36196, 36208, 36275, 36523, 36554,
+36763, 36784, 36802, 36806, 36805, 36804, 24033, 37009, 37026, 37034,
+37030, 37027, 37193, 37318, 37324, 38450, 38446, 38449, 38442, 38444,
+20006, 20054, 20083, 20107, 20123, 20126, 20139, 20140, 20335, 20381,
+20365, 20339, 20351, 20332, 20379, 20363, 20358, 20355, 20336, 20341,
+20360, 20329, 20347, 20374, 20350, 20367, 20369, 20346, 20820, 20818,
+20821, 20841, 20855, 20854, 20856, 20925, 20989, 21051, 21048, 21047,
+21050, 21040, 21038, 21046, 21057, 21182, 21179, 21330, 21332, 21331,
+21329, 21350, 21367, 21368, 21369, 21462, 21460, 21463, 21619, 21621,
+21654, 21624, 21653, 21632, 21627, 21623, 21636, 21650, 21638, 21628,
+21648, 21617, 21622, 21644, 21658, 21602, 21608, 21643, 21629, 21646,
+22266, 22403, 22391, 22378, 22377, 22369, 22374, 22372, 22396, 22812,
+22857, 22855, 22856, 22852, 22868, 22974, 22971, 22996, 22969, 22958,
+22993, 22982, 22992, 22989, 22987, 22995, 22986, 22959, 22963, 22994,
+22981, 23391, 23396, 23395, 23447, 23450, 23448, 23452, 23449, 23451,
+23578, 23624, 23621, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 23622, 23735, 23713,
+23736, 23721, 23723, 23729, 23731, 24088, 24090, 24086, 24085, 24091,
+24081, 24184, 24218, 24215, 24220, 24213, 24214, 24310, 24358, 24359,
+24361, 24448, 24449, 24447, 24444, 24541, 24544, 24573, 24565, 24575,
+24591, 24596, 24623, 24629, 24598, 24618, 24597, 24609, 24615, 24617,
+24619, 24603, 25110, 25109, 25151, 25150, 25152, 25215, 25289, 25292,
+25284, 25279, 25282, 25273, 25298, 25307, 25259, 25299, 25300, 25291,
+25288, 25256, 25277, 25276, 25296, 25305, 25287, 25293, 25269, 25306,
+25265, 25304, 25302, 25303, 25286, 25260, 25294, 25918, 26023, 26044,
+26106, 26132, 26131, 26124, 26118, 26114, 26126, 26112, 26127, 26133,
+26122, 26119, 26381, 26379, 26477, 26507, 26517, 26481, 26524, 26483,
+26487, 26503, 26525, 26519, 26479, 26480, 26495, 26505, 26494, 26512,
+26485, 26522, 26515, 26492, 26474, 26482, 27427, 27494, 27495, 27519,
+27667, 27675, 27875, 27880, 27891, 27825, 27852, 27877, 27827, 27837,
+27838, 27836, 27874, 27819, 27861, 27859, 27832, 27844, 27833, 27841,
+27822, 27863, 27845, 27889, 27839, 27835, 27873, 27867, 27850, 27820,
+27887, 27868, 27862, 27872, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28821, 28814,
+28818, 28810, 28825, 29228, 29229, 29240, 29256, 29287, 29289, 29376,
+29390, 29401, 29399, 29392, 29609, 29608, 29599, 29611, 29605, 30013,
+30109, 30105, 30106, 30340, 30402, 30450, 30452, 30693, 30717, 31038,
+31040, 31041, 31177, 31176, 31354, 31353, 31482, 31998, 32596, 32652,
+32651, 32773, 32954, 32933, 32930, 32945, 32929, 32939, 32937, 32948,
+32938, 32943, 33253, 33278, 33293, 33459, 33437, 33433, 33453, 33469,
+33439, 33465, 33457, 33452, 33445, 33455, 33464, 33443, 33456, 33470,
+33463, 34382, 34417, 21021, 34920, 36555, 36814, 36820, 36817, 37045,
+37048, 37041, 37046, 37319, 37329, 38263, 38272, 38428, 38464, 38463,
+38459, 38468, 38466, 38585, 38632, 38738, 38750, 20127, 20141, 20142,
+20449, 20405, 20399, 20415, 20448, 20433, 20431, 20445, 20419, 20406,
+20440, 20447, 20426, 20439, 20398, 20432, 20420, 20418, 20442, 20430,
+20446, 20407, 20823, 20882, 20881, 20896, 21070, 21059, 21066, 21069,
+21068, 21067, 21063, 21191, 21193, 21187, 21185, 21261, 21335, 21371,
+21402, 21467, 21676, 21696, 21672, 21710, 21705, 21688, 21670, 21683,
+21703, 21698, 21693, 21674, 21697, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 21700,
+21704, 21679, 21675, 21681, 21691, 21673, 21671, 21695, 22271, 22402,
+22411, 22432, 22435, 22434, 22478, 22446, 22419, 22869, 22865, 22863,
+22862, 22864, 23004, 23000, 23039, 23011, 23016, 23043, 23013, 23018,
+23002, 23014, 23041, 23035, 23401, 23459, 23462, 23460, 23458, 23461,
+23553, 23630, 23631, 23629, 23627, 23769, 23762, 24055, 24093, 24101,
+24095, 24189, 24224, 24230, 24314, 24328, 24365, 24421, 24456, 24453,
+24458, 24459, 24455, 24460, 24457, 24594, 24605, 24608, 24613, 24590,
+24616, 24653, 24688, 24680, 24674, 24646, 24643, 24684, 24683, 24682,
+24676, 25153, 25308, 25366, 25353, 25340, 25325, 25345, 25326, 25341,
+25351, 25329, 25335, 25327, 25324, 25342, 25332, 25361, 25346, 25919,
+25925, 26027, 26045, 26082, 26149, 26157, 26144, 26151, 26159, 26143,
+26152, 26161, 26148, 26359, 26623, 26579, 26609, 26580, 26576, 26604,
+26550, 26543, 26613, 26601, 26607, 26564, 26577, 26548, 26586, 26597,
+26552, 26575, 26590, 26611, 26544, 26585, 26594, 26589, 26578, 27498,
+27523, 27526, 27573, 27602, 27607, 27679, 27849, 27915, 27954, 27946,
+27969, 27941, 27916, 27953, 27934, 27927, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+27963, 27965, 27966, 27958, 27931, 27893, 27961, 27943, 27960, 27945,
+27950, 27957, 27918, 27947, 28843, 28858, 28851, 28844, 28847, 28845,
+28856, 28846, 28836, 29232, 29298, 29295, 29300, 29417, 29408, 29409,
+29623, 29642, 29627, 29618, 29645, 29632, 29619, 29978, 29997, 30031,
+30028, 30030, 30027, 30123, 30116, 30117, 30114, 30115, 30328, 30342,
+30343, 30344, 30408, 30406, 30403, 30405, 30465, 30457, 30456, 30473,
+30475, 30462, 30460, 30471, 30684, 30722, 30740, 30732, 30733, 31046,
+31049, 31048, 31047, 31161, 31162, 31185, 31186, 31179, 31359, 31361,
+31487, 31485, 31869, 32002, 32005, 32000, 32009, 32007, 32004, 32006,
+32568, 32654, 32703, 32772, 32784, 32781, 32785, 32822, 32982, 32997,
+32986, 32963, 32964, 32972, 32993, 32987, 32974, 32990, 32996, 32989,
+33268, 33314, 33511, 33539, 33541, 33507, 33499, 33510, 33540, 33509,
+33538, 33545, 33490, 33495, 33521, 33537, 33500, 33492, 33489, 33502,
+33491, 33503, 33519, 33542, 34384, 34425, 34427, 34426, 34893, 34923,
+35201, 35284, 35336, 35330, 35331, 35998, 36000, 36212, 36211, 36276,
+36557, 36556, 36848, 36838, 36834, 36842, 36837, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 36845, 36843, 36836, 36840, 37066, 37070, 37057, 37059, 37195,
+37194, 37325, 38274, 38480, 38475, 38476, 38477, 38754, 38761, 38859,
+38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 20056, 20147,
+20492, 20493, 20515, 20463, 20518, 20517, 20472, 20521, 20502, 20486,
+20540, 20511, 20506, 20498, 20497, 20474, 20480, 20500, 20520, 20465,
+20513, 20491, 20505, 20504, 20467, 20462, 20525, 20522, 20478, 20523,
+20489, 20860, 20900, 20901, 20898, 20941, 20940, 20934, 20939, 21078,
+21084, 21076, 21083, 21085, 21290, 21375, 21407, 21405, 21471, 21736,
+21776, 21761, 21815, 21756, 21733, 21746, 21766, 21754, 21780, 21737,
+21741, 21729, 21769, 21742, 21738, 21734, 21799, 21767, 21757, 21775,
+22275, 22276, 22466, 22484, 22475, 22467, 22537, 22799, 22871, 22872,
+22874, 23057, 23064, 23068, 23071, 23067, 23059, 23020, 23072, 23075,
+23081, 23077, 23052, 23049, 23403, 23640, 23472, 23475, 23478, 23476,
+23470, 23477, 23481, 23480, 23556, 23633, 23637, 23632, 23789, 23805,
+23803, 23786, 23784, 23792, 23798, 23809, 23796, 24046, 24109, 24107,
+24235, 24237, 24231, 24369, 24466, 24465, 24464, 24665, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 24675, 24677, 24656, 24661, 24685, 24681, 24687, 24708,
+24735, 24730, 24717, 24724, 24716, 24709, 24726, 25159, 25331, 25352,
+25343, 25422, 25406, 25391, 25429, 25410, 25414, 25423, 25417, 25402,
+25424, 25405, 25386, 25387, 25384, 25421, 25420, 25928, 25929, 26009,
+26049, 26053, 26178, 26185, 26191, 26179, 26194, 26188, 26181, 26177,
+26360, 26388, 26389, 26391, 26657, 26680, 26696, 26694, 26707, 26681,
+26690, 26708, 26665, 26803, 26647, 26700, 26705, 26685, 26612, 26704,
+26688, 26684, 26691, 26666, 26693, 26643, 26648, 26689, 27530, 27529,
+27575, 27683, 27687, 27688, 27686, 27684, 27888, 28010, 28053, 28040,
+28039, 28006, 28024, 28023, 27993, 28051, 28012, 28041, 28014, 27994,
+28020, 28009, 28044, 28042, 28025, 28037, 28005, 28052, 28874, 28888,
+28900, 28889, 28872, 28879, 29241, 29305, 29436, 29433, 29437, 29432,
+29431, 29574, 29677, 29705, 29678, 29664, 29674, 29662, 30036, 30045,
+30044, 30042, 30041, 30142, 30149, 30151, 30130, 30131, 30141, 30140,
+30137, 30146, 30136, 30347, 30384, 30410, 30413, 30414, 30505, 30495,
+30496, 30504, 30697, 30768, 30759, 30776, 30749, 30772, 30775, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30757, 30765, 30752, 30751, 30770, 31061, 31056,
+31072, 31071, 31062, 31070, 31069, 31063, 31066, 31204, 31203, 31207,
+31199, 31206, 31209, 31192, 31364, 31368, 31449, 31494, 31505, 31881,
+32033, 32023, 32011, 32010, 32032, 32034, 32020, 32016, 32021, 32026,
+32028, 32013, 32025, 32027, 32570, 32607, 32660, 32709, 32705, 32774,
+32792, 32789, 32793, 32791, 32829, 32831, 33009, 33026, 33008, 33029,
+33005, 33012, 33030, 33016, 33011, 33032, 33021, 33034, 33020, 33007,
+33261, 33260, 33280, 33296, 33322, 33323, 33320, 33324, 33467, 33579,
+33618, 33620, 33610, 33592, 33616, 33609, 33589, 33588, 33615, 33586,
+33593, 33590, 33559, 33600, 33585, 33576, 33603, 34388, 34442, 34474,
+34451, 34468, 34473, 34444, 34467, 34460, 34928, 34935, 34945, 34946,
+34941, 34937, 35352, 35344, 35342, 35340, 35349, 35338, 35351, 35347,
+35350, 35343, 35345, 35912, 35962, 35961, 36001, 36002, 36215, 36524,
+36562, 36564, 36559, 36785, 36865, 36870, 36855, 36864, 36858, 36852,
+36867, 36861, 36869, 36856, 37013, 37089, 37085, 37090, 37202, 37197,
+37196, 37336, 37341, 37335, 37340, 37337, 38275, 38498, 38499, 38497,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 38491, 38493, 38500, 38488, 38494, 38587,
+39138, 39340, 39592, 39640, 39717, 39730, 39740, 20094, 20602, 20605,
+20572, 20551, 20547, 20556, 20570, 20553, 20581, 20598, 20558, 20565,
+20597, 20596, 20599, 20559, 20495, 20591, 20589, 20828, 20885, 20976,
+21098, 21103, 21202, 21209, 21208, 21205, 21264, 21263, 21273, 21311,
+21312, 21310, 21443, 26364, 21830, 21866, 21862, 21828, 21854, 21857,
+21827, 21834, 21809, 21846, 21839, 21845, 21807, 21860, 21816, 21806,
+21852, 21804, 21859, 21811, 21825, 21847, 22280, 22283, 22281, 22495,
+22533, 22538, 22534, 22496, 22500, 22522, 22530, 22581, 22519, 22521,
+22816, 22882, 23094, 23105, 23113, 23142, 23146, 23104, 23100, 23138,
+23130, 23110, 23114, 23408, 23495, 23493, 23492, 23490, 23487, 23494,
+23561, 23560, 23559, 23648, 23644, 23645, 23815, 23814, 23822, 23835,
+23830, 23842, 23825, 23849, 23828, 23833, 23844, 23847, 23831, 24034,
+24120, 24118, 24115, 24119, 24247, 24248, 24246, 24245, 24254, 24373,
+24375, 24407, 24428, 24425, 24427, 24471, 24473, 24478, 24472, 24481,
+24480, 24476, 24703, 24739, 24713, 24736, 24744, 24779, 24756, 24806,
+24765, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 24773, 24763, 24757, 24796, 24764,
+24792, 24789, 24774, 24799, 24760, 24794, 24775, 25114, 25115, 25160,
+25504, 25511, 25458, 25494, 25506, 25509, 25463, 25447, 25496, 25514,
+25457, 25513, 25481, 25475, 25499, 25451, 25512, 25476, 25480, 25497,
+25505, 25516, 25490, 25487, 25472, 25467, 25449, 25448, 25466, 25949,
+25942, 25937, 25945, 25943, 21855, 25935, 25944, 25941, 25940, 26012,
+26011, 26028, 26063, 26059, 26060, 26062, 26205, 26202, 26212, 26216,
+26214, 26206, 26361, 21207, 26395, 26753, 26799, 26786, 26771, 26805,
+26751, 26742, 26801, 26791, 26775, 26800, 26755, 26820, 26797, 26758,
+26757, 26772, 26781, 26792, 26783, 26785, 26754, 27442, 27578, 27627,
+27628, 27691, 28046, 28092, 28147, 28121, 28082, 28129, 28108, 28132,
+28155, 28154, 28165, 28103, 28107, 28079, 28113, 28078, 28126, 28153,
+28088, 28151, 28149, 28101, 28114, 28186, 28085, 28122, 28139, 28120,
+28138, 28145, 28142, 28136, 28102, 28100, 28074, 28140, 28095, 28134,
+28921, 28937, 28938, 28925, 28911, 29245, 29309, 29313, 29468, 29467,
+29462, 29459, 29465, 29575, 29701, 29706, 29699, 29702, 29694, 29709,
+29920, 29942, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29943, 29980, 29986, 30053,
+30054, 30050, 30064, 30095, 30164, 30165, 30133, 30154, 30157, 30350,
+30420, 30418, 30427, 30519, 30526, 30524, 30518, 30520, 30522, 30827,
+30787, 30798, 31077, 31080, 31085, 31227, 31378, 31381, 31520, 31528,
+31515, 31532, 31526, 31513, 31518, 31534, 31890, 31895, 31893, 32070,
+32067, 32113, 32046, 32057, 32060, 32064, 32048, 32051, 32068, 32047,
+32066, 32050, 32049, 32573, 32670, 32666, 32716, 32718, 32722, 32796,
+32842, 32838, 33071, 33046, 33059, 33067, 33065, 33072, 33060, 33282,
+33333, 33335, 33334, 33337, 33678, 33694, 33688, 33656, 33698, 33686,
+33725, 33707, 33682, 33674, 33683, 33673, 33696, 33655, 33659, 33660,
+33670, 33703, 34389, 24426, 34503, 34496, 34486, 34500, 34485, 34502,
+34507, 34481, 34479, 34505, 34899, 34974, 34952, 34987, 34962, 34966,
+34957, 34955, 35219, 35215, 35370, 35357, 35363, 35365, 35377, 35373,
+35359, 35355, 35362, 35913, 35930, 36009, 36012, 36011, 36008, 36010,
+36007, 36199, 36198, 36286, 36282, 36571, 36575, 36889, 36877, 36890,
+36887, 36899, 36895, 36893, 36880, 36885, 36894, 36896, 36879, 36898,
+36886, 36891, 36884, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 37096, 37101, 37117,
+37207, 37326, 37365, 37350, 37347, 37351, 37357, 37353, 38281, 38506,
+38517, 38515, 38520, 38512, 38516, 38518, 38519, 38508, 38592, 38634,
+38633, 31456, 31455, 38914, 38915, 39770, 40165, 40565, 40575, 40613,
+40635, 20642, 20621, 20613, 20633, 20625, 20608, 20630, 20632, 20634,
+26368, 20977, 21106, 21108, 21109, 21097, 21214, 21213, 21211, 21338,
+21413, 21883, 21888, 21927, 21884, 21898, 21917, 21912, 21890, 21916,
+21930, 21908, 21895, 21899, 21891, 21939, 21934, 21919, 21822, 21938,
+21914, 21947, 21932, 21937, 21886, 21897, 21931, 21913, 22285, 22575,
+22570, 22580, 22564, 22576, 22577, 22561, 22557, 22560, 22777, 22778,
+22880, 23159, 23194, 23167, 23186, 23195, 23207, 23411, 23409, 23506,
+23500, 23507, 23504, 23562, 23563, 23601, 23884, 23888, 23860, 23879,
+24061, 24133, 24125, 24128, 24131, 24190, 24266, 24257, 24258, 24260,
+24380, 24429, 24489, 24490, 24488, 24785, 24801, 24754, 24758, 24800,
+24860, 24867, 24826, 24853, 24816, 24827, 24820, 24936, 24817, 24846,
+24822, 24841, 24832, 24850, 25119, 25161, 25507, 25484, 25551, 25536,
+25577, 25545, 25542, 25549, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 25554, 25571,
+25552, 25569, 25558, 25581, 25582, 25462, 25588, 25578, 25563, 25682,
+25562, 25593, 25950, 25958, 25954, 25955, 26001, 26000, 26031, 26222,
+26224, 26228, 26230, 26223, 26257, 26234, 26238, 26231, 26366, 26367,
+26399, 26397, 26874, 26837, 26848, 26840, 26839, 26885, 26847, 26869,
+26862, 26855, 26873, 26834, 26866, 26851, 26827, 26829, 26893, 26898,
+26894, 26825, 26842, 26990, 26875, 27454, 27450, 27453, 27544, 27542,
+27580, 27631, 27694, 27695, 27692, 28207, 28216, 28244, 28193, 28210,
+28263, 28234, 28192, 28197, 28195, 28187, 28251, 28248, 28196, 28246,
+28270, 28205, 28198, 28271, 28212, 28237, 28218, 28204, 28227, 28189,
+28222, 28363, 28297, 28185, 28238, 28259, 28228, 28274, 28265, 28255,
+28953, 28954, 28966, 28976, 28961, 28982, 29038, 28956, 29260, 29316,
+29312, 29494, 29477, 29492, 29481, 29754, 29738, 29747, 29730, 29733,
+29749, 29750, 29748, 29743, 29723, 29734, 29736, 29989, 29990, 30059,
+30058, 30178, 30171, 30179, 30169, 30168, 30174, 30176, 30331, 30332,
+30358, 30355, 30388, 30428, 30543, 30701, 30813, 30828, 30831, 31245,
+31240, 31243, 31237, 31232, 31384, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 31383,
+31382, 31461, 31459, 31561, 31574, 31558, 31568, 31570, 31572, 31565,
+31563, 31567, 31569, 31903, 31909, 32094, 32080, 32104, 32085, 32043,
+32110, 32114, 32097, 32102, 32098, 32112, 32115, 21892, 32724, 32725,
+32779, 32850, 32901, 33109, 33108, 33099, 33105, 33102, 33081, 33094,
+33086, 33100, 33107, 33140, 33298, 33308, 33769, 33795, 33784, 33805,
+33760, 33733, 33803, 33729, 33775, 33777, 33780, 33879, 33802, 33776,
+33804, 33740, 33789, 33778, 33738, 33848, 33806, 33796, 33756, 33799,
+33748, 33759, 34395, 34527, 34521, 34541, 34516, 34523, 34532, 34512,
+34526, 34903, 35009, 35010, 34993, 35203, 35222, 35387, 35424, 35413,
+35422, 35388, 35393, 35412, 35419, 35408, 35398, 35380, 35386, 35382,
+35414, 35937, 35970, 36015, 36028, 36019, 36029, 36033, 36027, 36032,
+36020, 36023, 36022, 36031, 36024, 36234, 36229, 36225, 36302, 36317,
+36299, 36314, 36305, 36300, 36315, 36294, 36603, 36600, 36604, 36764,
+36910, 36917, 36913, 36920, 36914, 36918, 37122, 37109, 37129, 37118,
+37219, 37221, 37327, 37396, 37397, 37411, 37385, 37406, 37389, 37392,
+37383, 37393, 38292, 38287, 38283, 38289, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+38291, 38290, 38286, 38538, 38542, 38539, 38525, 38533, 38534, 38541,
+38514, 38532, 38593, 38597, 38596, 38598, 38599, 38639, 38642, 38860,
+38917, 38918, 38920, 39143, 39146, 39151, 39145, 39154, 39149, 39342,
+39341, 40643, 40653, 40657, 20098, 20653, 20661, 20658, 20659, 20677,
+20670, 20652, 20663, 20667, 20655, 20679, 21119, 21111, 21117, 21215,
+21222, 21220, 21218, 21219, 21295, 21983, 21992, 21971, 21990, 21966,
+21980, 21959, 21969, 21987, 21988, 21999, 21978, 21985, 21957, 21958,
+21989, 21961, 22290, 22291, 22622, 22609, 22616, 22615, 22618, 22612,
+22635, 22604, 22637, 22602, 22626, 22610, 22603, 22887, 23233, 23241,
+23244, 23230, 23229, 23228, 23219, 23234, 23218, 23913, 23919, 24140,
+24185, 24265, 24264, 24338, 24409, 24492, 24494, 24858, 24847, 24904,
+24863, 24819, 24859, 24825, 24833, 24840, 24910, 24908, 24900, 24909,
+24894, 24884, 24871, 24845, 24838, 24887, 25121, 25122, 25619, 25662,
+25630, 25642, 25645, 25661, 25644, 25615, 25628, 25620, 25613, 25654,
+25622, 25623, 25606, 25964, 26015, 26032, 26263, 26249, 26247, 26248,
+26262, 26244, 26264, 26253, 26371, 27028, 26989, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 26970, 26999, 26976, 26964, 26997, 26928, 27010, 26954, 26984,
+26987, 26974, 26963, 27001, 27014, 26973, 26979, 26971, 27463, 27506,
+27584, 27583, 27603, 27645, 28322, 28335, 28371, 28342, 28354, 28304,
+28317, 28359, 28357, 28325, 28312, 28348, 28346, 28331, 28369, 28310,
+28316, 28356, 28372, 28330, 28327, 28340, 29006, 29017, 29033, 29028,
+29001, 29031, 29020, 29036, 29030, 29004, 29029, 29022, 28998, 29032,
+29014, 29242, 29266, 29495, 29509, 29503, 29502, 29807, 29786, 29781,
+29791, 29790, 29761, 29759, 29785, 29787, 29788, 30070, 30072, 30208,
+30192, 30209, 30194, 30193, 30202, 30207, 30196, 30195, 30430, 30431,
+30555, 30571, 30566, 30558, 30563, 30585, 30570, 30572, 30556, 30565,
+30568, 30562, 30702, 30862, 30896, 30871, 30872, 30860, 30857, 30844,
+30865, 30867, 30847, 31098, 31103, 31105, 33836, 31165, 31260, 31258,
+31264, 31252, 31263, 31262, 31391, 31392, 31607, 31680, 31584, 31598,
+31591, 31921, 31923, 31925, 32147, 32121, 32145, 32129, 32143, 32091,
+32622, 32617, 32618, 32626, 32681, 32680, 32676, 32854, 32856, 32902,
+32900, 33137, 33136, 33144, 33125, 33134, 33139, 33131, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 33145, 33146, 33126, 33285, 33351, 33922, 33911, 33853,
+33841, 33909, 33894, 33899, 33865, 33900, 33883, 33852, 33845, 33889,
+33891, 33897, 33901, 33862, 34398, 34396, 34399, 34553, 34579, 34568,
+34567, 34560, 34558, 34555, 34562, 34563, 34566, 34570, 34905, 35039,
+35028, 35033, 35036, 35032, 35037, 35041, 35018, 35029, 35026, 35228,
+35299, 35435, 35442, 35443, 35430, 35433, 35440, 35463, 35452, 35427,
+35488, 35441, 35461, 35437, 35426, 35438, 35436, 35449, 35451, 35390,
+35432, 35938, 35978, 35977, 36042, 36039, 36040, 36036, 36018, 36035,
+36034, 36037, 36321, 36319, 36328, 36335, 36339, 36346, 36330, 36324,
+36326, 36530, 36611, 36617, 36606, 36618, 36767, 36786, 36939, 36938,
+36947, 36930, 36948, 36924, 36949, 36944, 36935, 36943, 36942, 36941,
+36945, 36926, 36929, 37138, 37143, 37228, 37226, 37225, 37321, 37431,
+37463, 37432, 37437, 37440, 37438, 37467, 37451, 37476, 37457, 37428,
+37449, 37453, 37445, 37433, 37439, 37466, 38296, 38552, 38548, 38549,
+38605, 38603, 38601, 38602, 38647, 38651, 38649, 38646, 38742, 38772,
+38774, 38928, 38929, 38931, 38922, 38930, 38924, 39164, 39156, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 39165, 39166, 39347, 39345, 39348, 39649, 40169,
+40578, 40718, 40723, 40736, 20711, 20718, 20709, 20694, 20717, 20698,
+20693, 20687, 20689, 20721, 20686, 20713, 20834, 20979, 21123, 21122,
+21297, 21421, 22014, 22016, 22043, 22039, 22013, 22036, 22022, 22025,
+22029, 22030, 22007, 22038, 22047, 22024, 22032, 22006, 22296, 22294,
+22645, 22654, 22659, 22675, 22666, 22649, 22661, 22653, 22781, 22821,
+22818, 22820, 22890, 22889, 23265, 23270, 23273, 23255, 23254, 23256,
+23267, 23413, 23518, 23527, 23521, 23525, 23526, 23528, 23522, 23524,
+23519, 23565, 23650, 23940, 23943, 24155, 24163, 24149, 24151, 24148,
+24275, 24278, 24330, 24390, 24432, 24505, 24903, 24895, 24907, 24951,
+24930, 24931, 24927, 24922, 24920, 24949, 25130, 25735, 25688, 25684,
+25764, 25720, 25695, 25722, 25681, 25703, 25652, 25709, 25723, 25970,
+26017, 26071, 26070, 26274, 26280, 26269, 27036, 27048, 27029, 27073,
+27054, 27091, 27083, 27035, 27063, 27067, 27051, 27060, 27088, 27085,
+27053, 27084, 27046, 27075, 27043, 27465, 27468, 27699, 28467, 28436,
+28414, 28435, 28404, 28457, 28478, 28448, 28460, 28431, 28418, 28450,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28415, 28399, 28422, 28465, 28472, 28466,
+28451, 28437, 28459, 28463, 28552, 28458, 28396, 28417, 28402, 28364,
+28407, 29076, 29081, 29053, 29066, 29060, 29074, 29246, 29330, 29334,
+29508, 29520, 29796, 29795, 29802, 29808, 29805, 29956, 30097, 30247,
+30221, 30219, 30217, 30227, 30433, 30435, 30596, 30589, 30591, 30561,
+30913, 30879, 30887, 30899, 30889, 30883, 31118, 31119, 31117, 31278,
+31281, 31402, 31401, 31469, 31471, 31649, 31637, 31627, 31605, 31639,
+31645, 31636, 31631, 31672, 31623, 31620, 31929, 31933, 31934, 32187,
+32176, 32156, 32189, 32190, 32160, 32202, 32180, 32178, 32177, 32186,
+32162, 32191, 32181, 32184, 32173, 32210, 32199, 32172, 32624, 32736,
+32737, 32735, 32862, 32858, 32903, 33104, 33152, 33167, 33160, 33162,
+33151, 33154, 33255, 33274, 33287, 33300, 33310, 33355, 33993, 33983,
+33990, 33988, 33945, 33950, 33970, 33948, 33995, 33976, 33984, 34003,
+33936, 33980, 34001, 33994, 34623, 34588, 34619, 34594, 34597, 34612,
+34584, 34645, 34615, 34601, 35059, 35074, 35060, 35065, 35064, 35069,
+35048, 35098, 35055, 35494, 35468, 35486, 35491, 35469, 35489, 35475,
+35492, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 35498, 35493, 35496, 35480, 35473,
+35482, 35495, 35946, 35981, 35980, 36051, 36049, 36050, 36203, 36249,
+36245, 36348, 36628, 36626, 36629, 36627, 36771, 36960, 36952, 36956,
+36963, 36953, 36958, 36962, 36957, 36955, 37145, 37144, 37150, 37237,
+37240, 37239, 37236, 37496, 37504, 37509, 37528, 37526, 37499, 37523,
+37532, 37544, 37500, 37521, 38305, 38312, 38313, 38307, 38309, 38308,
+38553, 38556, 38555, 38604, 38610, 38656, 38780, 38789, 38902, 38935,
+38936, 39087, 39089, 39171, 39173, 39180, 39177, 39361, 39599, 39600,
+39654, 39745, 39746, 40180, 40182, 40179, 40636, 40763, 40778, 20740,
+20736, 20731, 20725, 20729, 20738, 20744, 20745, 20741, 20956, 21127,
+21128, 21129, 21133, 21130, 21232, 21426, 22062, 22075, 22073, 22066,
+22079, 22068, 22057, 22099, 22094, 22103, 22132, 22070, 22063, 22064,
+22656, 22687, 22686, 22707, 22684, 22702, 22697, 22694, 22893, 23305,
+23291, 23307, 23285, 23308, 23304, 23534, 23532, 23529, 23531, 23652,
+23653, 23965, 23956, 24162, 24159, 24161, 24290, 24282, 24287, 24285,
+24291, 24288, 24392, 24433, 24503, 24501, 24950, 24935, 24942, 24925,
+24917, 24962, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24956, 24944, 24939, 24958,
+24999, 24976, 25003, 24974, 25004, 24986, 24996, 24980, 25006, 25134,
+25705, 25711, 25721, 25758, 25778, 25736, 25744, 25776, 25765, 25747,
+25749, 25769, 25746, 25774, 25773, 25771, 25754, 25772, 25753, 25762,
+25779, 25973, 25975, 25976, 26286, 26283, 26292, 26289, 27171, 27167,
+27112, 27137, 27166, 27161, 27133, 27169, 27155, 27146, 27123, 27138,
+27141, 27117, 27153, 27472, 27470, 27556, 27589, 27590, 28479, 28540,
+28548, 28497, 28518, 28500, 28550, 28525, 28507, 28536, 28526, 28558,
+28538, 28528, 28516, 28567, 28504, 28373, 28527, 28512, 28511, 29087,
+29100, 29105, 29096, 29270, 29339, 29518, 29527, 29801, 29835, 29827,
+29822, 29824, 30079, 30240, 30249, 30239, 30244, 30246, 30241, 30242,
+30362, 30394, 30436, 30606, 30599, 30604, 30609, 30603, 30923, 30917,
+30906, 30922, 30910, 30933, 30908, 30928, 31295, 31292, 31296, 31293,
+31287, 31291, 31407, 31406, 31661, 31665, 31684, 31668, 31686, 31687,
+31681, 31648, 31692, 31946, 32224, 32244, 32239, 32251, 32216, 32236,
+32221, 32232, 32227, 32218, 32222, 32233, 32158, 32217, 32242, 32249,
+32629, 32631, 32687, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 32745, 32806, 33179,
+33180, 33181, 33184, 33178, 33176, 34071, 34109, 34074, 34030, 34092,
+34093, 34067, 34065, 34083, 34081, 34068, 34028, 34085, 34047, 34054,
+34690, 34676, 34678, 34656, 34662, 34680, 34664, 34649, 34647, 34636,
+34643, 34907, 34909, 35088, 35079, 35090, 35091, 35093, 35082, 35516,
+35538, 35527, 35524, 35477, 35531, 35576, 35506, 35529, 35522, 35519,
+35504, 35542, 35533, 35510, 35513, 35547, 35916, 35918, 35948, 36064,
+36062, 36070, 36068, 36076, 36077, 36066, 36067, 36060, 36074, 36065,
+36205, 36255, 36259, 36395, 36368, 36381, 36386, 36367, 36393, 36383,
+36385, 36382, 36538, 36637, 36635, 36639, 36649, 36646, 36650, 36636,
+36638, 36645, 36969, 36974, 36968, 36973, 36983, 37168, 37165, 37159,
+37169, 37255, 37257, 37259, 37251, 37573, 37563, 37559, 37610, 37548,
+37604, 37569, 37555, 37564, 37586, 37575, 37616, 37554, 38317, 38321,
+38660, 38662, 38663, 38665, 38752, 38797, 38795, 38799, 38945, 38955,
+38940, 39091, 39178, 39187, 39186, 39192, 39389, 39376, 39391, 39387,
+39377, 39381, 39378, 39385, 39607, 39662, 39663, 39719, 39749, 39748,
+39799, 39791, 40198, 40201, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 40195, 40617,
+40638, 40654, 22696, 40786, 20754, 20760, 20756, 20752, 20757, 20864,
+20906, 20957, 21137, 21139, 21235, 22105, 22123, 22137, 22121, 22116,
+22136, 22122, 22120, 22117, 22129, 22127, 22124, 22114, 22134, 22721,
+22718, 22727, 22725, 22894, 23325, 23348, 23416, 23536, 23566, 24394,
+25010, 24977, 25001, 24970, 25037, 25014, 25022, 25034, 25032, 25136,
+25797, 25793, 25803, 25787, 25788, 25818, 25796, 25799, 25794, 25805,
+25791, 25810, 25812, 25790, 25972, 26310, 26313, 26297, 26308, 26311,
+26296, 27197, 27192, 27194, 27225, 27243, 27224, 27193, 27204, 27234,
+27233, 27211, 27207, 27189, 27231, 27208, 27481, 27511, 27653, 28610,
+28593, 28577, 28611, 28580, 28609, 28583, 28595, 28608, 28601, 28598,
+28582, 28576, 28596, 29118, 29129, 29136, 29138, 29128, 29141, 29113,
+29134, 29145, 29148, 29123, 29124, 29544, 29852, 29859, 29848, 29855,
+29854, 29922, 29964, 29965, 30260, 30264, 30266, 30439, 30437, 30624,
+30622, 30623, 30629, 30952, 30938, 30956, 30951, 31142, 31309, 31310,
+31302, 31308, 31307, 31418, 31705, 31761, 31689, 31716, 31707, 31713,
+31721, 31718, 31957, 31958, 32266, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32273,
+32264, 32283, 32291, 32286, 32285, 32265, 32272, 32633, 32690, 32752,
+32753, 32750, 32808, 33203, 33193, 33192, 33275, 33288, 33368, 33369,
+34122, 34137, 34120, 34152, 34153, 34115, 34121, 34157, 34154, 34142,
+34691, 34719, 34718, 34722, 34701, 34913, 35114, 35122, 35109, 35115,
+35105, 35242, 35238, 35558, 35578, 35563, 35569, 35584, 35548, 35559,
+35566, 35582, 35585, 35586, 35575, 35565, 35571, 35574, 35580, 35947,
+35949, 35987, 36084, 36420, 36401, 36404, 36418, 36409, 36405, 36667,
+36655, 36664, 36659, 36776, 36774, 36981, 36980, 36984, 36978, 36988,
+36986, 37172, 37266, 37664, 37686, 37624, 37683, 37679, 37666, 37628,
+37675, 37636, 37658, 37648, 37670, 37665, 37653, 37678, 37657, 38331,
+38567, 38568, 38570, 38613, 38670, 38673, 38678, 38669, 38675, 38671,
+38747, 38748, 38758, 38808, 38960, 38968, 38971, 38967, 38957, 38969,
+38948, 39184, 39208, 39198, 39195, 39201, 39194, 39405, 39394, 39409,
+39608, 39612, 39675, 39661, 39720, 39825, 40213, 40227, 40230, 40232,
+40210, 40219, 40664, 40660, 40845, 40860, 20778, 20767, 20769, 20786,
+21237, 22158, 22144, 22160, 22149, 22151, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+22159, 22741, 22739, 22737, 22734, 23344, 23338, 23332, 23418, 23607,
+23656, 23996, 23994, 23997, 23992, 24171, 24396, 24509, 25033, 25026,
+25031, 25062, 25035, 25138, 25140, 25806, 25802, 25816, 25824, 25840,
+25830, 25836, 25841, 25826, 25837, 25986, 25987, 26329, 26326, 27264,
+27284, 27268, 27298, 27292, 27355, 27299, 27262, 27287, 27280, 27296,
+27484, 27566, 27610, 27656, 28632, 28657, 28639, 28640, 28635, 28644,
+28651, 28655, 28544, 28652, 28641, 28649, 28629, 28654, 28656, 29159,
+29151, 29166, 29158, 29157, 29165, 29164, 29172, 29152, 29237, 29254,
+29552, 29554, 29865, 29872, 29862, 29864, 30278, 30274, 30284, 30442,
+30643, 30634, 30640, 30636, 30631, 30637, 30703, 30967, 30970, 30964,
+30959, 30977, 31143, 31146, 31319, 31423, 31751, 31757, 31742, 31735,
+31756, 31712, 31968, 31964, 31966, 31970, 31967, 31961, 31965, 32302,
+32318, 32326, 32311, 32306, 32323, 32299, 32317, 32305, 32325, 32321,
+32308, 32313, 32328, 32309, 32319, 32303, 32580, 32755, 32764, 32881,
+32882, 32880, 32879, 32883, 33222, 33219, 33210, 33218, 33216, 33215,
+33213, 33225, 33214, 33256, 33289, 33393, 34218, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 34180, 34174, 34204, 34193, 34196, 34223, 34203, 34183, 34216,
+34186, 34407, 34752, 34769, 34739, 34770, 34758, 34731, 34747, 34746,
+34760, 34763, 35131, 35126, 35140, 35128, 35133, 35244, 35598, 35607,
+35609, 35611, 35594, 35616, 35613, 35588, 35600, 35905, 35903, 35955,
+36090, 36093, 36092, 36088, 36091, 36264, 36425, 36427, 36424, 36426,
+36676, 36670, 36674, 36677, 36671, 36991, 36989, 36996, 36993, 36994,
+36992, 37177, 37283, 37278, 37276, 37709, 37762, 37672, 37749, 37706,
+37733, 37707, 37656, 37758, 37740, 37723, 37744, 37722, 37716, 38346,
+38347, 38348, 38344, 38342, 38577, 38584, 38614, 38684, 38686, 38816,
+38867, 38982, 39094, 39221, 39425, 39423, 39854, 39851, 39850, 39853,
+40251, 40255, 40587, 40655, 40670, 40668, 40669, 40667, 40766, 40779,
+21474, 22165, 22190, 22745, 22744, 23352, 24413, 25059, 25139, 25844,
+25842, 25854, 25862, 25850, 25851, 25847, 26039, 26332, 26406, 27315,
+27308, 27331, 27323, 27320, 27330, 27310, 27311, 27487, 27512, 27567,
+28681, 28683, 28670, 28678, 28666, 28689, 28687, 29179, 29180, 29182,
+29176, 29559, 29557, 29863, 29887, 29973, 30294, 30296, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 30290, 30653, 30655, 30651, 30652, 30990, 31150, 31329,
+31330, 31328, 31428, 31429, 31787, 31783, 31786, 31774, 31779, 31777,
+31975, 32340, 32341, 32350, 32346, 32353, 32338, 32345, 32584, 32761,
+32763, 32887, 32886, 33229, 33231, 33290, 34255, 34217, 34253, 34256,
+34249, 34224, 34234, 34233, 34214, 34799, 34796, 34802, 34784, 35206,
+35250, 35316, 35624, 35641, 35628, 35627, 35920, 36101, 36441, 36451,
+36454, 36452, 36447, 36437, 36544, 36681, 36685, 36999, 36995, 37000,
+37291, 37292, 37328, 37780, 37770, 37782, 37794, 37811, 37806, 37804,
+37808, 37784, 37786, 37783, 38356, 38358, 38352, 38357, 38626, 38620,
+38617, 38619, 38622, 38692, 38819, 38822, 38829, 38905, 38989, 38991,
+38988, 38990, 38995, 39098, 39230, 39231, 39229, 39214, 39333, 39438,
+39617, 39683, 39686, 39759, 39758, 39757, 39882, 39881, 39933, 39880,
+39872, 40273, 40285, 40288, 40672, 40725, 40748, 20787, 22181, 22750,
+22751, 22754, 23541, 40848, 24300, 25074, 25079, 25078, 25077, 25856,
+25871, 26336, 26333, 27365, 27357, 27354, 27347, 28699, 28703, 28712,
+28698, 28701, 28693, 28696, 29190, 29197, 29272, 29346, 29560, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 29562, 29885, 29898, 29923, 30087, 30086, 30303,
+30305, 30663, 31001, 31153, 31339, 31337, 31806, 31807, 31800, 31805,
+31799, 31808, 32363, 32365, 32377, 32361, 32362, 32645, 32371, 32694,
+32697, 32696, 33240, 34281, 34269, 34282, 34261, 34276, 34277, 34295,
+34811, 34821, 34829, 34809, 34814, 35168, 35167, 35158, 35166, 35649,
+35676, 35672, 35657, 35674, 35662, 35663, 35654, 35673, 36104, 36106,
+36476, 36466, 36487, 36470, 36460, 36474, 36468, 36692, 36686, 36781,
+37002, 37003, 37297, 37294, 37857, 37841, 37855, 37827, 37832, 37852,
+37853, 37846, 37858, 37837, 37848, 37860, 37847, 37864, 38364, 38580,
+38627, 38698, 38695, 38753, 38876, 38907, 39006, 39000, 39003, 39100,
+39237, 39241, 39446, 39449, 39693, 39912, 39911, 39894, 39899, 40329,
+40289, 40306, 40298, 40300, 40594, 40599, 40595, 40628, 21240, 22184,
+22199, 22198, 22196, 22204, 22756, 23360, 23363, 23421, 23542, 24009,
+25080, 25082, 25880, 25876, 25881, 26342, 26407, 27372, 28734, 28720,
+28722, 29200, 29563, 29903, 30306, 30309, 31014, 31018, 31020, 31019,
+31431, 31478, 31820, 31811, 31821, 31983, 31984, 36782, 32381, 32380,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 32386, 32588, 32768, 33242, 33382, 34299,
+34297, 34321, 34298, 34310, 34315, 34311, 34314, 34836, 34837, 35172,
+35258, 35320, 35696, 35692, 35686, 35695, 35679, 35691, 36111, 36109,
+36489, 36481, 36485, 36482, 37300, 37323, 37912, 37891, 37885, 38369,
+38704, 39108, 39250, 39249, 39336, 39467, 39472, 39479, 39477, 39955,
+39949, 40569, 40629, 40680, 40751, 40799, 40803, 40801, 20791, 20792,
+22209, 22208, 22210, 22804, 23660, 24013, 25084, 25086, 25885, 25884,
+26005, 26345, 27387, 27396, 27386, 27570, 28748, 29211, 29351, 29910,
+29908, 30313, 30675, 31824, 32399, 32396, 32700, 34327, 34349, 34330,
+34851, 34850, 34849, 34847, 35178, 35180, 35261, 35700, 35703, 35709,
+36115, 36490, 36493, 36491, 36703, 36783, 37306, 37934, 37939, 37941,
+37946, 37944, 37938, 37931, 38370, 38712, 38713, 38706, 38911, 39015,
+39013, 39255, 39493, 39491, 39488, 39486, 39631, 39764, 39761, 39981,
+39973, 40367, 40372, 40386, 40376, 40605, 40687, 40729, 40796, 40806,
+40807, 20796, 20795, 22216, 22218, 22217, 23423, 24020, 24018, 24398,
+25087, 25892, 27402, 27489, 28753, 28760, 29568, 29924, 30090, 30318,
+30316, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 31155, 31840, 31839, 32894, 32893,
+33247, 35186, 35183, 35324, 35712, 36118, 36119, 36497, 36499, 36705,
+37192, 37956, 37969, 37970, 38717, 38718, 38851, 38849, 39019, 39253,
+39509, 39501, 39634, 39706, 40009, 39985, 39998, 39995, 40403, 40407,
+40756, 40812, 40810, 40852, 22220, 24022, 25088, 25891, 25899, 25898,
+26348, 27408, 29914, 31434, 31844, 31843, 31845, 32403, 32406, 32404,
+33250, 34360, 34367, 34865, 35722, 37008, 37007, 37987, 37984, 37988,
+38760, 39023, 39260, 39514, 39515, 39511, 39635, 39636, 39633, 40020,
+40023, 40022, 40421, 40607, 40692, 22225, 22761, 25900, 28766, 30321,
+30322, 30679, 32592, 32648, 34870, 34873, 34914, 35731, 35730, 35734,
+33399, 36123, 37312, 37994, 38722, 38728, 38724, 38854, 39024, 39519,
+39714, 39768, 40031, 40441, 40442, 40572, 40573, 40711, 40823, 40818,
+24307, 27414, 28771, 31852, 31854, 34875, 35264, 36513, 37313, 38002,
+38000, 39025, 39262, 39638, 39715, 40652, 28772, 30682, 35738, 38007,
+38857, 39522, 39525, 32412, 35740, 36522, 37317, 38013, 38014, 38012,
+40055, 40056, 40695, 35924, 38015, 40474, 29224, 39530, 39729, 40475,
+40478, 31858, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 9312, 9313, 9314, 9315,
+ 9316, 9317, 9318, 9319, 9320, 9321, 9332, 9333, 9334, 9335,
+ 9336, 9337, 9338, 9339, 9340, 9341, 8560, 8561, 8562, 8563,
+ 8564, 8565, 8566, 8567, 8568, 8569, 20022, 20031, 20101, 20128,
+20866, 20886, 20907, 21241, 21304, 21353, 21430, 22794, 23424, 24027,
+24186, 24191, 24308, 24400, 24417, 25908, 26080, 30098, 30326, 36789,
+38582, 168, 710, 12541, 12542, 12445, 12446, 12291, 20189, 12293,
+12294, 12295, 12540, 65339, 65341, 10045, 12353, 12354, 12355, 12356,
+12357, 12358, 12359, 12360, 12361, 12362, 12363, 12364, 12365, 12366,
+12367, 12368, 12369, 12370, 12371, 12372, 12373, 12374, 12375, 12376,
+12377, 12378, 12379, 12380, 12381, 12382, 12383, 12384, 12385, 12386,
+12387, 12388, 12389, 12390, 12391, 12392, 12393, 12394, 12395, 12396,
+12397, 12398, 12399, 12400, 12401, 12402, 12403, 12404, 12405, 12406,
+12407, 12408, 12409, 12410, 12411, 12412, 12413, 12414, 12415, 12416,
+12417, 12418, 12419, 12420, 12421, 12422, 12423, 12424, 12425, 12426,
+12427, 12428, 12429, 12430, 12431, 12432, 12433, 12434, 12435, 12449,
+12450, 12451, 12452, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12453, 12454, 12455,
+12456, 12457, 12458, 12459, 12460, 12461, 12462, 12463, 12464, 12465,
+12466, 12467, 12468, 12469, 12470, 12471, 12472, 12473, 12474, 12475,
+12476, 12477, 12478, 12479, 12480, 12481, 12482, 12483, 12484, 12485,
+12486, 12487, 12488, 12489, 12490, 12491, 12492, 12493, 12494, 12495,
+12496, 12497, 12498, 12499, 12500, 12501, 12502, 12503, 12504, 12505,
+12506, 12507, 12508, 12509, 12510, 12511, 12512, 12513, 12514, 12515,
+12516, 12517, 12518, 12519, 12520, 12521, 12522, 12523, 12524, 12525,
+12526, 12527, 12528, 12529, 12530, 12531, 12532, 12533, 12534, 1040,
+ 1041, 1042, 1043, 1044, 1045, 1025, 1046, 1047, 1048, 1049,
+ 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059,
+ 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069,
+ 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1105, 1078,
+ 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088,
+ 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098,
+ 1099, 1100, 1101, 1102, 1103, 8679, 8632, 8633, 12751, 63462,
+20058, 63464, 20994, 17553, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 40880, 20872,
+40881, 63470, 63471, 63472, 63473, 63474, 63475, 63476, 63477, 63478,
+63479, 63480, 63481, 63482, 12443, 12444, 12436, 12535, 12536, 12537,
+12538, 12539, 65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384,
+65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392, 65393, 65394,
+65395, 65396, 65506, 65508, 65287, 65282, 12849, 8470, 8481, 65397,
+65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407,
+65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417,
+65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427,
+65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437,
+65438, 65439, 20034, 20060, 20981, 21274, 21378, 19975, 19980, 20039,
+20109, 22231, 64012, 23662, 24435, 19983, 20871, 19982, 20014, 20115,
+20162, 20169, 20168, 20888, 21244, 21356, 21433, 22304, 22787, 22828,
+23568, 24063, 26081, 27571, 27596, 27668, 29247, 20017, 20028, 20200,
+20188, 20201, 20193, 20189, 20186, 21004, 21276, 21324, 22306, 22307,
+22807, 22831, 23425, 23428, 23570, 23611, 23668, 23667, 24068, 24192,
+24194, 24521, 25097, 25168, 27669, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 27702,
+27715, 27711, 27707, 29358, 29360, 29578, 31160, 32906, 38430, 20238,
+20248, 20268, 20213, 20244, 20209, 20224, 20215, 20232, 20253, 20226,
+20229, 20258, 20243, 20228, 20212, 20242, 20913, 21011, 21001, 21008,
+21158, 21282, 21279, 21325, 21386, 21511, 22241, 22239, 22318, 22314,
+22324, 22844, 22912, 22908, 22917, 22907, 22910, 22903, 22911, 23382,
+23573, 23589, 23676, 23674, 23675, 23678, 24031, 24181, 24196, 24322,
+24346, 24436, 24533, 24532, 24527, 25180, 25182, 25188, 25185, 25190,
+25186, 25177, 25184, 25178, 25189, 26095, 26094, 26430, 26425, 26424,
+26427, 26426, 26431, 26428, 26419, 27672, 27718, 27730, 27740, 27727,
+27722, 27732, 27723, 27724, 28785, 29278, 29364, 29365, 29582, 29994,
+30335, 31349, 32593, 33400, 33404, 33408, 33405, 33407, 34381, 35198,
+37017, 37015, 37016, 37019, 37012, 38434, 38436, 38432, 38435, 20310,
+20283, 20322, 20297, 20307, 20324, 20286, 20327, 20306, 20319, 20289,
+20312, 20269, 20275, 20287, 20321, 20879, 20921, 21020, 21022, 21025,
+21165, 21166, 21257, 21347, 21362, 21390, 21391, 21552, 21559, 21546,
+21588, 21573, 21529, 21532, 21541, 21528, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+21565, 21583, 21569, 21544, 21540, 21575, 22254, 22247, 22245, 22337,
+22341, 22348, 22345, 22347, 22354, 22790, 22848, 22950, 22936, 22944,
+22935, 22926, 22946, 22928, 22927, 22951, 22945, 23438, 23442, 23592,
+23594, 23693, 23695, 23688, 23691, 23689, 23698, 23690, 23686, 23699,
+23701, 24032, 24074, 24078, 24203, 24201, 24204, 24200, 24205, 24325,
+24349, 24440, 24438, 24530, 24529, 24528, 24557, 24552, 24558, 24563,
+24545, 24548, 24547, 24570, 24559, 24567, 24571, 24576, 24564, 25146,
+25219, 25228, 25230, 25231, 25236, 25223, 25201, 25211, 25210, 25200,
+25217, 25224, 25207, 25213, 25202, 25204, 25911, 26096, 26100, 26099,
+26098, 26101, 26437, 26439, 26457, 26453, 26444, 26440, 26461, 26445,
+26458, 26443, 27600, 27673, 27674, 27768, 27751, 27755, 27780, 27787,
+27791, 27761, 27759, 27753, 27802, 27757, 27783, 27797, 27804, 27750,
+27763, 27749, 27771, 27790, 28788, 28794, 29283, 29375, 29373, 29379,
+29382, 29377, 29370, 29381, 29589, 29591, 29587, 29588, 29586, 30010,
+30009, 30100, 30101, 30337, 31037, 32820, 32917, 32921, 32912, 32914,
+32924, 33424, 33423, 33413, 33422, 33425, 33427, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33418, 33411, 33412, 35960, 36809, 36799, 37023, 37025, 37029,
+37022, 37031, 37024, 38448, 38440, 38447, 38445, 20019, 20376, 20348,
+20357, 20349, 20352, 20359, 20342, 20340, 20361, 20356, 20343, 20300,
+20375, 20330, 20378, 20345, 20353, 20344, 20368, 20380, 20372, 20382,
+20370, 20354, 20373, 20331, 20334, 20894, 20924, 20926, 21045, 21042,
+21043, 21062, 21041, 21180, 21258, 21259, 21308, 21394, 21396, 21639,
+21631, 21633, 21649, 21634, 21640, 21611, 21626, 21630, 21605, 21612,
+21620, 21606, 21645, 21615, 21601, 21600, 21656, 21603, 21607, 21604,
+22263, 22265, 22383, 22386, 22381, 22379, 22385, 22384, 22390, 22400,
+22389, 22395, 22387, 22388, 22370, 22376, 22397, 22796, 22853, 22965,
+22970, 22991, 22990, 22962, 22988, 22977, 22966, 22972, 22979, 22998,
+22961, 22973, 22976, 22984, 22964, 22983, 23394, 23397, 23443, 23445,
+23620, 23623, 23726, 23716, 23712, 23733, 23727, 23720, 23724, 23711,
+23715, 23725, 23714, 23722, 23719, 23709, 23717, 23734, 23728, 23718,
+24087, 24084, 24089, 24360, 24354, 24355, 24356, 24404, 24450, 24446,
+24445, 24542, 24549, 24621, 24614, 24601, 24626, 24587, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 24628, 24586, 24599, 24627, 24602, 24606, 24620, 24610,
+24589, 24592, 24622, 24595, 24593, 24588, 24585, 24604, 25108, 25149,
+25261, 25268, 25297, 25278, 25258, 25270, 25290, 25262, 25267, 25263,
+25275, 25257, 25264, 25272, 25917, 26024, 26043, 26121, 26108, 26116,
+26130, 26120, 26107, 26115, 26123, 26125, 26117, 26109, 26129, 26128,
+26358, 26378, 26501, 26476, 26510, 26514, 26486, 26491, 26520, 26502,
+26500, 26484, 26509, 26508, 26490, 26527, 26513, 26521, 26499, 26493,
+26497, 26488, 26489, 26516, 27429, 27520, 27518, 27614, 27677, 27795,
+27884, 27883, 27886, 27865, 27830, 27860, 27821, 27879, 27831, 27856,
+27842, 27834, 27843, 27846, 27885, 27890, 27858, 27869, 27828, 27786,
+27805, 27776, 27870, 27840, 27952, 27853, 27847, 27824, 27897, 27855,
+27881, 27857, 28820, 28824, 28805, 28819, 28806, 28804, 28817, 28822,
+28802, 28826, 28803, 29290, 29398, 29387, 29400, 29385, 29404, 29394,
+29396, 29402, 29388, 29393, 29604, 29601, 29613, 29606, 29602, 29600,
+29612, 29597, 29917, 29928, 30015, 30016, 30014, 30092, 30104, 30383,
+30451, 30449, 30448, 30453, 30712, 30716, 30713, 30715, 30714, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30711, 31042, 31039, 31173, 31352, 31355, 31483,
+31861, 31997, 32821, 32911, 32942, 32931, 32952, 32949, 32941, 33312,
+33440, 33472, 33451, 33434, 33432, 33435, 33461, 33447, 33454, 33468,
+33438, 33466, 33460, 33448, 33441, 33449, 33474, 33444, 33475, 33462,
+33442, 34416, 34415, 34413, 34414, 35926, 36818, 36811, 36819, 36813,
+36822, 36821, 36823, 37042, 37044, 37039, 37043, 37040, 38457, 38461,
+38460, 38458, 38467, 20429, 20421, 20435, 20402, 20425, 20427, 20417,
+20436, 20444, 20441, 20411, 20403, 20443, 20423, 20438, 20410, 20416,
+20409, 20460, 21060, 21065, 21184, 21186, 21309, 21372, 21399, 21398,
+21401, 21400, 21690, 21665, 21677, 21669, 21711, 21699, 33549, 21687,
+21678, 21718, 21686, 21701, 21702, 21664, 21616, 21692, 21666, 21694,
+21618, 21726, 21680, 22453, 22430, 22431, 22436, 22412, 22423, 22429,
+22427, 22420, 22424, 22415, 22425, 22437, 22426, 22421, 22772, 22797,
+22867, 23009, 23006, 23022, 23040, 23025, 23005, 23034, 23037, 23036,
+23030, 23012, 23026, 23031, 23003, 23017, 23027, 23029, 23008, 23038,
+23028, 23021, 23464, 23628, 23760, 23768, 23756, 23767, 23755, 23771,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 23774, 23770, 23753, 23751, 23754, 23766,
+23763, 23764, 23759, 23752, 23750, 23758, 23775, 23800, 24057, 24097,
+24098, 24099, 24096, 24100, 24240, 24228, 24226, 24219, 24227, 24229,
+24327, 24366, 24406, 24454, 24631, 24633, 24660, 24690, 24670, 24645,
+24659, 24647, 24649, 24667, 24652, 24640, 24642, 24671, 24612, 24644,
+24664, 24678, 24686, 25154, 25155, 25295, 25357, 25355, 25333, 25358,
+25347, 25323, 25337, 25359, 25356, 25336, 25334, 25344, 25363, 25364,
+25338, 25365, 25339, 25328, 25921, 25923, 26026, 26047, 26166, 26145,
+26162, 26165, 26140, 26150, 26146, 26163, 26155, 26170, 26141, 26164,
+26169, 26158, 26383, 26384, 26561, 26610, 26568, 26554, 26588, 26555,
+26616, 26584, 26560, 26551, 26565, 26603, 26596, 26591, 26549, 26573,
+26547, 26615, 26614, 26606, 26595, 26562, 26553, 26574, 26599, 26608,
+26546, 26620, 26566, 26605, 26572, 26542, 26598, 26587, 26618, 26569,
+26570, 26563, 26602, 26571, 27432, 27522, 27524, 27574, 27606, 27608,
+27616, 27680, 27681, 27944, 27956, 27949, 27935, 27964, 27967, 27922,
+27914, 27866, 27955, 27908, 27929, 27962, 27930, 27921, 27904, 27933,
+27970, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 27905, 27928, 27959, 27907, 27919,
+27968, 27911, 27936, 27948, 27912, 27938, 27913, 27920, 28855, 28831,
+28862, 28849, 28848, 28833, 28852, 28853, 28841, 29249, 29257, 29258,
+29292, 29296, 29299, 29294, 29386, 29412, 29416, 29419, 29407, 29418,
+29414, 29411, 29573, 29644, 29634, 29640, 29637, 29625, 29622, 29621,
+29620, 29675, 29631, 29639, 29630, 29635, 29638, 29624, 29643, 29932,
+29934, 29998, 30023, 30024, 30119, 30122, 30329, 30404, 30472, 30467,
+30468, 30469, 30474, 30455, 30459, 30458, 30695, 30696, 30726, 30737,
+30738, 30725, 30736, 30735, 30734, 30729, 30723, 30739, 31050, 31052,
+31051, 31045, 31044, 31189, 31181, 31183, 31190, 31182, 31360, 31358,
+31441, 31488, 31489, 31866, 31864, 31865, 31871, 31872, 31873, 32003,
+32008, 32001, 32600, 32657, 32653, 32702, 32775, 32782, 32783, 32788,
+32823, 32984, 32967, 32992, 32977, 32968, 32962, 32976, 32965, 32995,
+32985, 32988, 32970, 32981, 32969, 32975, 32983, 32998, 32973, 33279,
+33313, 33428, 33497, 33534, 33529, 33543, 33512, 33536, 33493, 33594,
+33515, 33494, 33524, 33516, 33505, 33522, 33525, 33548, 33531, 33526,
+33520, 33514, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33508, 33504, 33530, 33523,
+33517, 34423, 34420, 34428, 34419, 34881, 34894, 34919, 34922, 34921,
+35283, 35332, 35335, 36210, 36835, 36833, 36846, 36832, 37105, 37053,
+37055, 37077, 37061, 37054, 37063, 37067, 37064, 37332, 37331, 38484,
+38479, 38481, 38483, 38474, 38478, 20510, 20485, 20487, 20499, 20514,
+20528, 20507, 20469, 20468, 20531, 20535, 20524, 20470, 20471, 20503,
+20508, 20512, 20519, 20533, 20527, 20529, 20494, 20826, 20884, 20883,
+20938, 20932, 20933, 20936, 20942, 21089, 21082, 21074, 21086, 21087,
+21077, 21090, 21197, 21262, 21406, 21798, 21730, 21783, 21778, 21735,
+21747, 21732, 21786, 21759, 21764, 21768, 21739, 21777, 21765, 21745,
+21770, 21755, 21751, 21752, 21728, 21774, 21763, 21771, 22273, 22274,
+22476, 22578, 22485, 22482, 22458, 22470, 22461, 22460, 22456, 22454,
+22463, 22471, 22480, 22457, 22465, 22798, 22858, 23065, 23062, 23085,
+23086, 23061, 23055, 23063, 23050, 23070, 23091, 23404, 23463, 23469,
+23468, 23555, 23638, 23636, 23788, 23807, 23790, 23793, 23799, 23808,
+23801, 24105, 24104, 24232, 24238, 24234, 24236, 24371, 24368, 24423,
+24669, 24666, 24679, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24641, 24738, 24712,
+24704, 24722, 24705, 24733, 24707, 24725, 24731, 24727, 24711, 24732,
+24718, 25113, 25158, 25330, 25360, 25430, 25388, 25412, 25413, 25398,
+25411, 25572, 25401, 25419, 25418, 25404, 25385, 25409, 25396, 25432,
+25428, 25433, 25389, 25415, 25395, 25434, 25425, 25400, 25431, 25408,
+25416, 25930, 25926, 26054, 26051, 26052, 26050, 26186, 26207, 26183,
+26193, 26386, 26387, 26655, 26650, 26697, 26674, 26675, 26683, 26699,
+26703, 26646, 26673, 26652, 26677, 26667, 26669, 26671, 26702, 26692,
+26676, 26653, 26642, 26644, 26662, 26664, 26670, 26701, 26682, 26661,
+26656, 27436, 27439, 27437, 27441, 27444, 27501, 32898, 27528, 27622,
+27620, 27624, 27619, 27618, 27623, 27685, 28026, 28003, 28004, 28022,
+27917, 28001, 28050, 27992, 28002, 28013, 28015, 28049, 28045, 28143,
+28031, 28038, 27998, 28007, 28000, 28055, 28016, 28028, 27999, 28034,
+28056, 27951, 28008, 28043, 28030, 28032, 28036, 27926, 28035, 28027,
+28029, 28021, 28048, 28892, 28883, 28881, 28893, 28875, 32569, 28898,
+28887, 28882, 28894, 28896, 28884, 28877, 28869, 28870, 28871, 28890,
+28878, 28897, 29250, 29304, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 29303, 29302,
+29440, 29434, 29428, 29438, 29430, 29427, 29435, 29441, 29651, 29657,
+29669, 29654, 29628, 29671, 29667, 29673, 29660, 29650, 29659, 29652,
+29661, 29658, 29655, 29656, 29672, 29918, 29919, 29940, 29941, 29985,
+30043, 30047, 30128, 30145, 30139, 30148, 30144, 30143, 30134, 30138,
+30346, 30409, 30493, 30491, 30480, 30483, 30482, 30499, 30481, 30485,
+30489, 30490, 30498, 30503, 30755, 30764, 30754, 30773, 30767, 30760,
+30766, 30763, 30753, 30761, 30771, 30762, 30769, 31060, 31067, 31055,
+31068, 31059, 31058, 31057, 31211, 31212, 31200, 31214, 31213, 31210,
+31196, 31198, 31197, 31366, 31369, 31365, 31371, 31372, 31370, 31367,
+31448, 31504, 31492, 31507, 31493, 31503, 31496, 31498, 31502, 31497,
+31506, 31876, 31889, 31882, 31884, 31880, 31885, 31877, 32030, 32029,
+32017, 32014, 32024, 32022, 32019, 32031, 32018, 32015, 32012, 32604,
+32609, 32606, 32608, 32605, 32603, 32662, 32658, 32707, 32706, 32704,
+32790, 32830, 32825, 33018, 33010, 33017, 33013, 33025, 33019, 33024,
+33281, 33327, 33317, 33587, 33581, 33604, 33561, 33617, 33573, 33622,
+33599, 33601, 33574, 33564, 33570, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 33602,
+33614, 33563, 33578, 33544, 33596, 33613, 33558, 33572, 33568, 33591,
+33583, 33577, 33607, 33605, 33612, 33619, 33566, 33580, 33611, 33575,
+33608, 34387, 34386, 34466, 34472, 34454, 34445, 34449, 34462, 34439,
+34455, 34438, 34443, 34458, 34437, 34469, 34457, 34465, 34471, 34453,
+34456, 34446, 34461, 34448, 34452, 34883, 34884, 34925, 34933, 34934,
+34930, 34944, 34929, 34943, 34927, 34947, 34942, 34932, 34940, 35346,
+35911, 35927, 35963, 36004, 36003, 36214, 36216, 36277, 36279, 36278,
+36561, 36563, 36862, 36853, 36866, 36863, 36859, 36868, 36860, 36854,
+37078, 37088, 37081, 37082, 37091, 37087, 37093, 37080, 37083, 37079,
+37084, 37092, 37200, 37198, 37199, 37333, 37346, 37338, 38492, 38495,
+38588, 39139, 39647, 39727, 20095, 20592, 20586, 20577, 20574, 20576,
+20563, 20555, 20573, 20594, 20552, 20557, 20545, 20571, 20554, 20578,
+20501, 20549, 20575, 20585, 20587, 20579, 20580, 20550, 20544, 20590,
+20595, 20567, 20561, 20944, 21099, 21101, 21100, 21102, 21206, 21203,
+21293, 21404, 21877, 21878, 21820, 21837, 21840, 21812, 21802, 21841,
+21858, 21814, 21813, 21808, 21842, 21829, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+21772, 21810, 21861, 21838, 21817, 21832, 21805, 21819, 21824, 21835,
+22282, 22279, 22523, 22548, 22498, 22518, 22492, 22516, 22528, 22509,
+22525, 22536, 22520, 22539, 22515, 22479, 22535, 22510, 22499, 22514,
+22501, 22508, 22497, 22542, 22524, 22544, 22503, 22529, 22540, 22513,
+22505, 22512, 22541, 22532, 22876, 23136, 23128, 23125, 23143, 23134,
+23096, 23093, 23149, 23120, 23135, 23141, 23148, 23123, 23140, 23127,
+23107, 23133, 23122, 23108, 23131, 23112, 23182, 23102, 23117, 23097,
+23116, 23152, 23145, 23111, 23121, 23126, 23106, 23132, 23410, 23406,
+23489, 23488, 23641, 23838, 23819, 23837, 23834, 23840, 23820, 23848,
+23821, 23846, 23845, 23823, 23856, 23826, 23843, 23839, 23854, 24126,
+24116, 24241, 24244, 24249, 24242, 24243, 24374, 24376, 24475, 24470,
+24479, 24714, 24720, 24710, 24766, 24752, 24762, 24787, 24788, 24783,
+24804, 24793, 24797, 24776, 24753, 24795, 24759, 24778, 24767, 24771,
+24781, 24768, 25394, 25445, 25482, 25474, 25469, 25533, 25502, 25517,
+25501, 25495, 25515, 25486, 25455, 25479, 25488, 25454, 25519, 25461,
+25500, 25453, 25518, 25468, 25508, 25403, 25503, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 25464, 25477, 25473, 25489, 25485, 25456, 25939, 26061, 26213,
+26209, 26203, 26201, 26204, 26210, 26392, 26745, 26759, 26768, 26780,
+26733, 26734, 26798, 26795, 26966, 26735, 26787, 26796, 26793, 26741,
+26740, 26802, 26767, 26743, 26770, 26748, 26731, 26738, 26794, 26752,
+26737, 26750, 26779, 26774, 26763, 26784, 26761, 26788, 26744, 26747,
+26769, 26764, 26762, 26749, 27446, 27443, 27447, 27448, 27537, 27535,
+27533, 27534, 27532, 27690, 28096, 28075, 28084, 28083, 28276, 28076,
+28137, 28130, 28087, 28150, 28116, 28160, 28104, 28128, 28127, 28118,
+28094, 28133, 28124, 28125, 28123, 28148, 28106, 28093, 28141, 28144,
+28090, 28117, 28098, 28111, 28105, 28112, 28146, 28115, 28157, 28119,
+28109, 28131, 28091, 28922, 28941, 28919, 28951, 28916, 28940, 28912,
+28932, 28915, 28944, 28924, 28927, 28934, 28947, 28928, 28920, 28918,
+28939, 28930, 28942, 29310, 29307, 29308, 29311, 29469, 29463, 29447,
+29457, 29464, 29450, 29448, 29439, 29455, 29470, 29576, 29686, 29688,
+29685, 29700, 29697, 29693, 29703, 29696, 29690, 29692, 29695, 29708,
+29707, 29684, 29704, 30052, 30051, 30158, 30162, 30159, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 30155, 30156, 30161, 30160, 30351, 30345, 30419, 30521,
+30511, 30509, 30513, 30514, 30516, 30515, 30525, 30501, 30523, 30517,
+30792, 30802, 30793, 30797, 30794, 30796, 30758, 30789, 30800, 31076,
+31079, 31081, 31082, 31075, 31083, 31073, 31163, 31226, 31224, 31222,
+31223, 31375, 31380, 31376, 31541, 31559, 31540, 31525, 31536, 31522,
+31524, 31539, 31512, 31530, 31517, 31537, 31531, 31533, 31535, 31538,
+31544, 31514, 31523, 31892, 31896, 31894, 31907, 32053, 32061, 32056,
+32054, 32058, 32069, 32044, 32041, 32065, 32071, 32062, 32063, 32074,
+32059, 32040, 32611, 32661, 32668, 32669, 32667, 32714, 32715, 32717,
+32720, 32721, 32711, 32719, 32713, 32799, 32798, 32795, 32839, 32835,
+32840, 33048, 33061, 33049, 33051, 33069, 33055, 33068, 33054, 33057,
+33045, 33063, 33053, 33058, 33297, 33336, 33331, 33338, 33332, 33330,
+33396, 33680, 33699, 33704, 33677, 33658, 33651, 33700, 33652, 33679,
+33665, 33685, 33689, 33653, 33684, 33705, 33661, 33667, 33676, 33693,
+33691, 33706, 33675, 33662, 33701, 33711, 33672, 33687, 33712, 33663,
+33702, 33671, 33710, 33654, 33690, 34393, 34390, 34495, 34487, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 34498, 34497, 34501, 34490, 34480, 34504, 34489,
+34483, 34488, 34508, 34484, 34491, 34492, 34499, 34493, 34494, 34898,
+34953, 34965, 34984, 34978, 34986, 34970, 34961, 34977, 34975, 34968,
+34983, 34969, 34971, 34967, 34980, 34988, 34956, 34963, 34958, 35202,
+35286, 35289, 35285, 35376, 35367, 35372, 35358, 35897, 35899, 35932,
+35933, 35965, 36005, 36221, 36219, 36217, 36284, 36290, 36281, 36287,
+36289, 36568, 36574, 36573, 36572, 36567, 36576, 36577, 36900, 36875,
+36881, 36892, 36876, 36897, 37103, 37098, 37104, 37108, 37106, 37107,
+37076, 37099, 37100, 37097, 37206, 37208, 37210, 37203, 37205, 37356,
+37364, 37361, 37363, 37368, 37348, 37369, 37354, 37355, 37367, 37352,
+37358, 38266, 38278, 38280, 38524, 38509, 38507, 38513, 38511, 38591,
+38762, 38916, 39141, 39319, 20635, 20629, 20628, 20638, 20619, 20643,
+20611, 20620, 20622, 20637, 20584, 20636, 20626, 20610, 20615, 20831,
+20948, 21266, 21265, 21412, 21415, 21905, 21928, 21925, 21933, 21879,
+22085, 21922, 21907, 21896, 21903, 21941, 21889, 21923, 21906, 21924,
+21885, 21900, 21926, 21887, 21909, 21921, 21902, 22284, 22569, 22583,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 22553, 22558, 22567, 22563, 22568, 22517,
+22600, 22565, 22556, 22555, 22579, 22591, 22582, 22574, 22585, 22584,
+22573, 22572, 22587, 22881, 23215, 23188, 23199, 23162, 23202, 23198,
+23160, 23206, 23164, 23205, 23212, 23189, 23214, 23095, 23172, 23178,
+23191, 23171, 23179, 23209, 23163, 23165, 23180, 23196, 23183, 23187,
+23197, 23530, 23501, 23499, 23508, 23505, 23498, 23502, 23564, 23600,
+23863, 23875, 23915, 23873, 23883, 23871, 23861, 23889, 23886, 23893,
+23859, 23866, 23890, 23869, 23857, 23897, 23874, 23865, 23881, 23864,
+23868, 23858, 23862, 23872, 23877, 24132, 24129, 24408, 24486, 24485,
+24491, 24777, 24761, 24780, 24802, 24782, 24772, 24852, 24818, 24842,
+24854, 24837, 24821, 24851, 24824, 24828, 24830, 24769, 24835, 24856,
+24861, 24848, 24831, 24836, 24843, 25162, 25492, 25521, 25520, 25550,
+25573, 25576, 25583, 25539, 25757, 25587, 25546, 25568, 25590, 25557,
+25586, 25589, 25697, 25567, 25534, 25565, 25564, 25540, 25560, 25555,
+25538, 25543, 25548, 25547, 25544, 25584, 25559, 25561, 25906, 25959,
+25962, 25956, 25948, 25960, 25957, 25996, 26013, 26014, 26030, 26064,
+26066, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 26236, 26220, 26235, 26240, 26225,
+26233, 26218, 26226, 26369, 26892, 26835, 26884, 26844, 26922, 26860,
+26858, 26865, 26895, 26838, 26871, 26859, 26852, 26870, 26899, 26896,
+26867, 26849, 26887, 26828, 26888, 26992, 26804, 26897, 26863, 26822,
+26900, 26872, 26832, 26877, 26876, 26856, 26891, 26890, 26903, 26830,
+26824, 26845, 26846, 26854, 26868, 26833, 26886, 26836, 26857, 26901,
+26917, 26823, 27449, 27451, 27455, 27452, 27540, 27543, 27545, 27541,
+27581, 27632, 27634, 27635, 27696, 28156, 28230, 28231, 28191, 28233,
+28296, 28220, 28221, 28229, 28258, 28203, 28223, 28225, 28253, 28275,
+28188, 28211, 28235, 28224, 28241, 28219, 28163, 28206, 28254, 28264,
+28252, 28257, 28209, 28200, 28256, 28273, 28267, 28217, 28194, 28208,
+28243, 28261, 28199, 28280, 28260, 28279, 28245, 28281, 28242, 28262,
+28213, 28214, 28250, 28960, 28958, 28975, 28923, 28974, 28977, 28963,
+28965, 28962, 28978, 28959, 28968, 28986, 28955, 29259, 29274, 29320,
+29321, 29318, 29317, 29323, 29458, 29451, 29488, 29474, 29489, 29491,
+29479, 29490, 29485, 29478, 29475, 29493, 29452, 29742, 29740, 29744,
+29739, 29718, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29722, 29729, 29741, 29745,
+29732, 29731, 29725, 29737, 29728, 29746, 29947, 29999, 30063, 30060,
+30183, 30170, 30177, 30182, 30173, 30175, 30180, 30167, 30357, 30354,
+30426, 30534, 30535, 30532, 30541, 30533, 30538, 30542, 30539, 30540,
+30686, 30700, 30816, 30820, 30821, 30812, 30829, 30833, 30826, 30830,
+30832, 30825, 30824, 30814, 30818, 31092, 31091, 31090, 31088, 31234,
+31242, 31235, 31244, 31236, 31385, 31462, 31460, 31562, 31547, 31556,
+31560, 31564, 31566, 31552, 31576, 31557, 31906, 31902, 31912, 31905,
+32088, 32111, 32099, 32083, 32086, 32103, 32106, 32079, 32109, 32092,
+32107, 32082, 32084, 32105, 32081, 32095, 32078, 32574, 32575, 32613,
+32614, 32674, 32672, 32673, 32727, 32849, 32847, 32848, 33022, 32980,
+33091, 33098, 33106, 33103, 33095, 33085, 33101, 33082, 33254, 33262,
+33271, 33272, 33273, 33284, 33340, 33341, 33343, 33397, 33595, 33743,
+33785, 33827, 33728, 33768, 33810, 33767, 33764, 33788, 33782, 33808,
+33734, 33736, 33771, 33763, 33727, 33793, 33757, 33765, 33752, 33791,
+33761, 33739, 33742, 33750, 33781, 33737, 33801, 33807, 33758, 33809,
+33798, 33730, 33779, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33749, 33786, 33735,
+33745, 33770, 33811, 33731, 33772, 33774, 33732, 33787, 33751, 33762,
+33819, 33755, 33790, 34520, 34530, 34534, 34515, 34531, 34522, 34538,
+34525, 34539, 34524, 34540, 34537, 34519, 34536, 34513, 34888, 34902,
+34901, 35002, 35031, 35001, 35000, 35008, 35006, 34998, 35004, 34999,
+35005, 34994, 35073, 35017, 35221, 35224, 35223, 35293, 35290, 35291,
+35406, 35405, 35385, 35417, 35392, 35415, 35416, 35396, 35397, 35410,
+35400, 35409, 35402, 35404, 35407, 35935, 35969, 35968, 36026, 36030,
+36016, 36025, 36021, 36228, 36224, 36233, 36312, 36307, 36301, 36295,
+36310, 36316, 36303, 36309, 36313, 36296, 36311, 36293, 36591, 36599,
+36602, 36601, 36582, 36590, 36581, 36597, 36583, 36584, 36598, 36587,
+36593, 36588, 36596, 36585, 36909, 36916, 36911, 37126, 37164, 37124,
+37119, 37116, 37128, 37113, 37115, 37121, 37120, 37127, 37125, 37123,
+37217, 37220, 37215, 37218, 37216, 37377, 37386, 37413, 37379, 37402,
+37414, 37391, 37388, 37376, 37394, 37375, 37373, 37382, 37380, 37415,
+37378, 37404, 37412, 37401, 37399, 37381, 37398, 38267, 38285, 38284,
+38288, 38535, 38526, 38536, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 38537, 38531,
+38528, 38594, 38600, 38595, 38641, 38640, 38764, 38768, 38766, 38919,
+39081, 39147, 40166, 40697, 20099, 20100, 20150, 20669, 20671, 20678,
+20654, 20676, 20682, 20660, 20680, 20674, 20656, 20673, 20666, 20657,
+20683, 20681, 20662, 20664, 20951, 21114, 21112, 21115, 21116, 21955,
+21979, 21964, 21968, 21963, 21962, 21981, 21952, 21972, 21956, 21993,
+21951, 21970, 21901, 21967, 21973, 21986, 21974, 21960, 22002, 21965,
+21977, 21954, 22292, 22611, 22632, 22628, 22607, 22605, 22601, 22639,
+22613, 22606, 22621, 22617, 22629, 22619, 22589, 22627, 22641, 22780,
+23239, 23236, 23243, 23226, 23224, 23217, 23221, 23216, 23231, 23240,
+23227, 23238, 23223, 23232, 23242, 23220, 23222, 23245, 23225, 23184,
+23510, 23512, 23513, 23583, 23603, 23921, 23907, 23882, 23909, 23922,
+23916, 23902, 23912, 23911, 23906, 24048, 24143, 24142, 24138, 24141,
+24139, 24261, 24268, 24262, 24267, 24263, 24384, 24495, 24493, 24823,
+24905, 24906, 24875, 24901, 24886, 24882, 24878, 24902, 24879, 24911,
+24873, 24896, 25120, 37224, 25123, 25125, 25124, 25541, 25585, 25579,
+25616, 25618, 25609, 25632, 25636, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 25651,
+25667, 25631, 25621, 25624, 25657, 25655, 25634, 25635, 25612, 25638,
+25648, 25640, 25665, 25653, 25647, 25610, 25626, 25664, 25637, 25639,
+25611, 25575, 25627, 25646, 25633, 25614, 25967, 26002, 26067, 26246,
+26252, 26261, 26256, 26251, 26250, 26265, 26260, 26232, 26400, 26982,
+26975, 26936, 26958, 26978, 26993, 26943, 26949, 26986, 26937, 26946,
+26967, 26969, 27002, 26952, 26953, 26933, 26988, 26931, 26941, 26981,
+26864, 27000, 26932, 26985, 26944, 26991, 26948, 26998, 26968, 26945,
+26996, 26956, 26939, 26955, 26935, 26972, 26959, 26961, 26930, 26962,
+26927, 27003, 26940, 27462, 27461, 27459, 27458, 27464, 27457, 27547,
+64013, 27643, 27644, 27641, 27639, 27640, 28315, 28374, 28360, 28303,
+28352, 28319, 28307, 28308, 28320, 28337, 28345, 28358, 28370, 28349,
+28353, 28318, 28361, 28343, 28336, 28365, 28326, 28367, 28338, 28350,
+28355, 28380, 28376, 28313, 28306, 28302, 28301, 28324, 28321, 28351,
+28339, 28368, 28362, 28311, 28334, 28323, 28999, 29012, 29010, 29027,
+29024, 28993, 29021, 29026, 29042, 29048, 29034, 29025, 28994, 29016,
+28995, 29003, 29040, 29023, 29008, 29011, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+28996, 29005, 29018, 29263, 29325, 29324, 29329, 29328, 29326, 29500,
+29506, 29499, 29498, 29504, 29514, 29513, 29764, 29770, 29771, 29778,
+29777, 29783, 29760, 29775, 29776, 29774, 29762, 29766, 29773, 29780,
+29921, 29951, 29950, 29949, 29981, 30073, 30071, 27011, 30191, 30223,
+30211, 30199, 30206, 30204, 30201, 30200, 30224, 30203, 30198, 30189,
+30197, 30205, 30361, 30389, 30429, 30549, 30559, 30560, 30546, 30550,
+30554, 30569, 30567, 30548, 30553, 30573, 30688, 30855, 30874, 30868,
+30863, 30852, 30869, 30853, 30854, 30881, 30851, 30841, 30873, 30848,
+30870, 30843, 31100, 31106, 31101, 31097, 31249, 31256, 31257, 31250,
+31255, 31253, 31266, 31251, 31259, 31248, 31395, 31394, 31390, 31467,
+31590, 31588, 31597, 31604, 31593, 31602, 31589, 31603, 31601, 31600,
+31585, 31608, 31606, 31587, 31922, 31924, 31919, 32136, 32134, 32128,
+32141, 32127, 32133, 32122, 32142, 32123, 32131, 32124, 32140, 32148,
+32132, 32125, 32146, 32621, 32619, 32615, 32616, 32620, 32678, 32677,
+32679, 32731, 32732, 32801, 33124, 33120, 33143, 33116, 33129, 33115,
+33122, 33138, 26401, 33118, 33142, 33127, 33135, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33092, 33121, 33309, 33353, 33348, 33344, 33346, 33349, 34033,
+33855, 33878, 33910, 33913, 33935, 33933, 33893, 33873, 33856, 33926,
+33895, 33840, 33869, 33917, 33882, 33881, 33908, 33907, 33885, 34055,
+33886, 33847, 33850, 33844, 33914, 33859, 33912, 33842, 33861, 33833,
+33753, 33867, 33839, 33858, 33837, 33887, 33904, 33849, 33870, 33868,
+33874, 33903, 33989, 33934, 33851, 33863, 33846, 33843, 33896, 33918,
+33860, 33835, 33888, 33876, 33902, 33872, 34571, 34564, 34551, 34572,
+34554, 34518, 34549, 34637, 34552, 34574, 34569, 34561, 34550, 34573,
+34565, 35030, 35019, 35021, 35022, 35038, 35035, 35034, 35020, 35024,
+35205, 35227, 35295, 35301, 35300, 35297, 35296, 35298, 35292, 35302,
+35446, 35462, 35455, 35425, 35391, 35447, 35458, 35460, 35445, 35459,
+35457, 35444, 35450, 35900, 35915, 35914, 35941, 35940, 35942, 35974,
+35972, 35973, 36044, 36200, 36201, 36241, 36236, 36238, 36239, 36237,
+36243, 36244, 36240, 36242, 36336, 36320, 36332, 36337, 36334, 36304,
+36329, 36323, 36322, 36327, 36338, 36331, 36340, 36614, 36607, 36609,
+36608, 36613, 36615, 36616, 36610, 36619, 36946, 36927, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 36932, 36937, 36925, 37136, 37133, 37135, 37137, 37142,
+37140, 37131, 37134, 37230, 37231, 37448, 37458, 37424, 37434, 37478,
+37427, 37477, 37470, 37507, 37422, 37450, 37446, 37485, 37484, 37455,
+37472, 37479, 37487, 37430, 37473, 37488, 37425, 37460, 37475, 37456,
+37490, 37454, 37459, 37452, 37462, 37426, 38303, 38300, 38302, 38299,
+38546, 38547, 38545, 38551, 38606, 38650, 38653, 38648, 38645, 38771,
+38775, 38776, 38770, 38927, 38925, 38926, 39084, 39158, 39161, 39343,
+39346, 39344, 39349, 39597, 39595, 39771, 40170, 40173, 40167, 40576,
+40701, 20710, 20692, 20695, 20712, 20723, 20699, 20714, 20701, 20708,
+20691, 20716, 20720, 20719, 20707, 20704, 20952, 21120, 21121, 21225,
+21227, 21296, 21420, 22055, 22037, 22028, 22034, 22012, 22031, 22044,
+22017, 22035, 22018, 22010, 22045, 22020, 22015, 22009, 22665, 22652,
+22672, 22680, 22662, 22657, 22655, 22644, 22667, 22650, 22663, 22673,
+22670, 22646, 22658, 22664, 22651, 22676, 22671, 22782, 22891, 23260,
+23278, 23269, 23253, 23274, 23258, 23277, 23275, 23283, 23266, 23264,
+23259, 23276, 23262, 23261, 23257, 23272, 23263, 23415, 23520, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 23523, 23651, 23938, 23936, 23933, 23942, 23930,
+23937, 23927, 23946, 23945, 23944, 23934, 23932, 23949, 23929, 23935,
+24152, 24153, 24147, 24280, 24273, 24279, 24270, 24284, 24277, 24281,
+24274, 24276, 24388, 24387, 24431, 24502, 24876, 24872, 24897, 24926,
+24945, 24947, 24914, 24915, 24946, 24940, 24960, 24948, 24916, 24954,
+24923, 24933, 24891, 24938, 24929, 24918, 25129, 25127, 25131, 25643,
+25677, 25691, 25693, 25716, 25718, 25714, 25715, 25725, 25717, 25702,
+25766, 25678, 25730, 25694, 25692, 25675, 25683, 25696, 25680, 25727,
+25663, 25708, 25707, 25689, 25701, 25719, 25971, 26016, 26273, 26272,
+26271, 26373, 26372, 26402, 27057, 27062, 27081, 27040, 27086, 27030,
+27056, 27052, 27068, 27025, 27033, 27022, 27047, 27021, 27049, 27070,
+27055, 27071, 27076, 27069, 27044, 27092, 27065, 27082, 27034, 27087,
+27059, 27027, 27050, 27041, 27038, 27097, 27031, 27024, 27074, 27061,
+27045, 27078, 27466, 27469, 27467, 27550, 27551, 27552, 27587, 27588,
+27646, 28366, 28405, 28401, 28419, 28453, 28408, 28471, 28411, 28462,
+28425, 28494, 28441, 28442, 28455, 28440, 28475, 28434, 28397, 28426,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28470, 28531, 28409, 28398, 28461, 28480,
+28464, 28476, 28469, 28395, 28423, 28430, 28483, 28421, 28413, 28406,
+28473, 28444, 28412, 28474, 28447, 28429, 28446, 28424, 28449, 29063,
+29072, 29065, 29056, 29061, 29058, 29071, 29051, 29062, 29057, 29079,
+29252, 29267, 29335, 29333, 29331, 29507, 29517, 29521, 29516, 29794,
+29811, 29809, 29813, 29810, 29799, 29806, 29952, 29954, 29955, 30077,
+30096, 30230, 30216, 30220, 30229, 30225, 30218, 30228, 30392, 30593,
+30588, 30597, 30594, 30574, 30592, 30575, 30590, 30595, 30898, 30890,
+30900, 30893, 30888, 30846, 30891, 30878, 30885, 30880, 30892, 30882,
+30884, 31128, 31114, 31115, 31126, 31125, 31124, 31123, 31127, 31112,
+31122, 31120, 31275, 31306, 31280, 31279, 31272, 31270, 31400, 31403,
+31404, 31470, 31624, 31644, 31626, 31633, 31632, 31638, 31629, 31628,
+31643, 31630, 31621, 31640, 21124, 31641, 31652, 31618, 31931, 31935,
+31932, 31930, 32167, 32183, 32194, 32163, 32170, 32193, 32192, 32197,
+32157, 32206, 32196, 32198, 32203, 32204, 32175, 32185, 32150, 32188,
+32159, 32166, 32174, 32169, 32161, 32201, 32627, 32738, 32739, 32741,
+32734, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 32804, 32861, 32860, 33161, 33158,
+33155, 33159, 33165, 33164, 33163, 33301, 33943, 33956, 33953, 33951,
+33978, 33998, 33986, 33964, 33966, 33963, 33977, 33972, 33985, 33997,
+33962, 33946, 33969, 34000, 33949, 33959, 33979, 33954, 33940, 33991,
+33996, 33947, 33961, 33967, 33960, 34006, 33944, 33974, 33999, 33952,
+34007, 34004, 34002, 34011, 33968, 33937, 34401, 34611, 34595, 34600,
+34667, 34624, 34606, 34590, 34593, 34585, 34587, 34627, 34604, 34625,
+34622, 34630, 34592, 34610, 34602, 34605, 34620, 34578, 34618, 34609,
+34613, 34626, 34598, 34599, 34616, 34596, 34586, 34608, 34577, 35063,
+35047, 35057, 35058, 35066, 35070, 35054, 35068, 35062, 35067, 35056,
+35052, 35051, 35229, 35233, 35231, 35230, 35305, 35307, 35304, 35499,
+35481, 35467, 35474, 35471, 35478, 35901, 35944, 35945, 36053, 36047,
+36055, 36246, 36361, 36354, 36351, 36365, 36349, 36362, 36355, 36359,
+36358, 36357, 36350, 36352, 36356, 36624, 36625, 36622, 36621, 37155,
+37148, 37152, 37154, 37151, 37149, 37146, 37156, 37153, 37147, 37242,
+37234, 37241, 37235, 37541, 37540, 37494, 37531, 37498, 37536, 37524,
+37546, 37517, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 37542, 37530, 37547, 37497,
+37527, 37503, 37539, 37614, 37518, 37506, 37525, 37538, 37501, 37512,
+37537, 37514, 37510, 37516, 37529, 37543, 37502, 37511, 37545, 37533,
+37515, 37421, 38558, 38561, 38655, 38744, 38781, 38778, 38782, 38787,
+38784, 38786, 38779, 38788, 38785, 38783, 38862, 38861, 38934, 39085,
+39086, 39170, 39168, 39175, 39325, 39324, 39363, 39353, 39355, 39354,
+39362, 39357, 39367, 39601, 39651, 39655, 39742, 39743, 39776, 39777,
+39775, 40177, 40178, 40181, 40615, 20735, 20739, 20784, 20728, 20742,
+20743, 20726, 20734, 20747, 20748, 20733, 20746, 21131, 21132, 21233,
+21231, 22088, 22082, 22092, 22069, 22081, 22090, 22089, 22086, 22104,
+22106, 22080, 22067, 22077, 22060, 22078, 22072, 22058, 22074, 22298,
+22699, 22685, 22705, 22688, 22691, 22703, 22700, 22693, 22689, 22783,
+23295, 23284, 23293, 23287, 23286, 23299, 23288, 23298, 23289, 23297,
+23303, 23301, 23311, 23655, 23961, 23959, 23967, 23954, 23970, 23955,
+23957, 23968, 23964, 23969, 23962, 23966, 24169, 24157, 24160, 24156,
+32243, 24283, 24286, 24289, 24393, 24498, 24971, 24963, 24953, 25009,
+25008, 24994, 24969, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24987, 24979, 25007,
+25005, 24991, 24978, 25002, 24993, 24973, 24934, 25011, 25133, 25710,
+25712, 25750, 25760, 25733, 25751, 25756, 25743, 25739, 25738, 25740,
+25763, 25759, 25704, 25777, 25752, 25974, 25978, 25977, 25979, 26034,
+26035, 26293, 26288, 26281, 26290, 26295, 26282, 26287, 27136, 27142,
+27159, 27109, 27128, 27157, 27121, 27108, 27168, 27135, 27116, 27106,
+27163, 27165, 27134, 27175, 27122, 27118, 27156, 27127, 27111, 27200,
+27144, 27110, 27131, 27149, 27132, 27115, 27145, 27140, 27160, 27173,
+27151, 27126, 27174, 27143, 27124, 27158, 27473, 27557, 27555, 27554,
+27558, 27649, 27648, 27647, 27650, 28481, 28454, 28542, 28551, 28614,
+28562, 28557, 28553, 28556, 28514, 28495, 28549, 28506, 28566, 28534,
+28524, 28546, 28501, 28530, 28498, 28496, 28503, 28564, 28563, 28509,
+28416, 28513, 28523, 28541, 28519, 28560, 28499, 28555, 28521, 28543,
+28565, 28515, 28535, 28522, 28539, 29106, 29103, 29083, 29104, 29088,
+29082, 29097, 29109, 29085, 29093, 29086, 29092, 29089, 29098, 29084,
+29095, 29107, 29336, 29338, 29528, 29522, 29534, 29535, 29536, 29533,
+29531, 29537, 29530, 29529, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 29538, 29831,
+29833, 29834, 29830, 29825, 29821, 29829, 29832, 29820, 29817, 29960,
+29959, 30078, 30245, 30238, 30233, 30237, 30236, 30243, 30234, 30248,
+30235, 30364, 30365, 30366, 30363, 30605, 30607, 30601, 30600, 30925,
+30907, 30927, 30924, 30929, 30926, 30932, 30920, 30915, 30916, 30921,
+31130, 31137, 31136, 31132, 31138, 31131, 27510, 31289, 31410, 31412,
+31411, 31671, 31691, 31678, 31660, 31694, 31663, 31673, 31690, 31669,
+31941, 31944, 31948, 31947, 32247, 32219, 32234, 32231, 32215, 32225,
+32259, 32250, 32230, 32246, 32241, 32240, 32238, 32223, 32630, 32684,
+32688, 32685, 32749, 32747, 32746, 32748, 32742, 32744, 32868, 32871,
+33187, 33183, 33182, 33173, 33186, 33177, 33175, 33302, 33359, 33363,
+33362, 33360, 33358, 33361, 34084, 34107, 34063, 34048, 34089, 34062,
+34057, 34061, 34079, 34058, 34087, 34076, 34043, 34091, 34042, 34056,
+34060, 34036, 34090, 34034, 34069, 34039, 34027, 34035, 34044, 34066,
+34026, 34025, 34070, 34046, 34088, 34077, 34094, 34050, 34045, 34078,
+34038, 34097, 34086, 34023, 34024, 34032, 34031, 34041, 34072, 34080,
+34096, 34059, 34073, 34095, 34402, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 34646,
+34659, 34660, 34679, 34785, 34675, 34648, 34644, 34651, 34642, 34657,
+34650, 34641, 34654, 34669, 34666, 34640, 34638, 34655, 34653, 34671,
+34668, 34682, 34670, 34652, 34661, 34639, 34683, 34677, 34658, 34663,
+34665, 34906, 35077, 35084, 35092, 35083, 35095, 35096, 35097, 35078,
+35094, 35089, 35086, 35081, 35234, 35236, 35235, 35309, 35312, 35308,
+35535, 35526, 35512, 35539, 35537, 35540, 35541, 35515, 35543, 35518,
+35520, 35525, 35544, 35523, 35514, 35517, 35545, 35902, 35917, 35983,
+36069, 36063, 36057, 36072, 36058, 36061, 36071, 36256, 36252, 36257,
+36251, 36384, 36387, 36389, 36388, 36398, 36373, 36379, 36374, 36369,
+36377, 36390, 36391, 36372, 36370, 36376, 36371, 36380, 36375, 36378,
+36652, 36644, 36632, 36634, 36640, 36643, 36630, 36631, 36979, 36976,
+36975, 36967, 36971, 37167, 37163, 37161, 37162, 37170, 37158, 37166,
+37253, 37254, 37258, 37249, 37250, 37252, 37248, 37584, 37571, 37572,
+37568, 37593, 37558, 37583, 37617, 37599, 37592, 37609, 37591, 37597,
+37580, 37615, 37570, 37608, 37578, 37576, 37582, 37606, 37581, 37589,
+37577, 37600, 37598, 37607, 37585, 37587, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+37557, 37601, 37574, 37556, 38268, 38316, 38315, 38318, 38320, 38564,
+38562, 38611, 38661, 38664, 38658, 38746, 38794, 38798, 38792, 38864,
+38863, 38942, 38941, 38950, 38953, 38952, 38944, 38939, 38951, 39090,
+39176, 39162, 39185, 39188, 39190, 39191, 39189, 39388, 39373, 39375,
+39379, 39380, 39374, 39369, 39382, 39384, 39371, 39383, 39372, 39603,
+39660, 39659, 39667, 39666, 39665, 39750, 39747, 39783, 39796, 39793,
+39782, 39798, 39797, 39792, 39784, 39780, 39788, 40188, 40186, 40189,
+40191, 40183, 40199, 40192, 40185, 40187, 40200, 40197, 40196, 40579,
+40659, 40719, 40720, 20764, 20755, 20759, 20762, 20753, 20958, 21300,
+21473, 22128, 22112, 22126, 22131, 22118, 22115, 22125, 22130, 22110,
+22135, 22300, 22299, 22728, 22717, 22729, 22719, 22714, 22722, 22716,
+22726, 23319, 23321, 23323, 23329, 23316, 23315, 23312, 23318, 23336,
+23322, 23328, 23326, 23535, 23980, 23985, 23977, 23975, 23989, 23984,
+23982, 23978, 23976, 23986, 23981, 23983, 23988, 24167, 24168, 24166,
+24175, 24297, 24295, 24294, 24296, 24293, 24395, 24508, 24989, 25000,
+24982, 25029, 25012, 25030, 25025, 25036, 25018, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 25023, 25016, 24972, 25815, 25814, 25808, 25807, 25801, 25789,
+25737, 25795, 25819, 25843, 25817, 25907, 25983, 25980, 26018, 26312,
+26302, 26304, 26314, 26315, 26319, 26301, 26299, 26298, 26316, 26403,
+27188, 27238, 27209, 27239, 27186, 27240, 27198, 27229, 27245, 27254,
+27227, 27217, 27176, 27226, 27195, 27199, 27201, 27242, 27236, 27216,
+27215, 27220, 27247, 27241, 27232, 27196, 27230, 27222, 27221, 27213,
+27214, 27206, 27477, 27476, 27478, 27559, 27562, 27563, 27592, 27591,
+27652, 27651, 27654, 28589, 28619, 28579, 28615, 28604, 28622, 28616,
+28510, 28612, 28605, 28574, 28618, 28584, 28676, 28581, 28590, 28602,
+28588, 28586, 28623, 28607, 28600, 28578, 28617, 28587, 28621, 28591,
+28594, 28592, 29125, 29122, 29119, 29112, 29142, 29120, 29121, 29131,
+29140, 29130, 29127, 29135, 29117, 29144, 29116, 29126, 29146, 29147,
+29341, 29342, 29545, 29542, 29543, 29548, 29541, 29547, 29546, 29823,
+29850, 29856, 29844, 29842, 29845, 29857, 29963, 30080, 30255, 30253,
+30257, 30269, 30259, 30268, 30261, 30258, 30256, 30395, 30438, 30618,
+30621, 30625, 30620, 30619, 30626, 30627, 30613, 30617, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 30615, 30941, 30953, 30949, 30954, 30942, 30947, 30939,
+30945, 30946, 30957, 30943, 30944, 31140, 31300, 31304, 31303, 31414,
+31416, 31413, 31409, 31415, 31710, 31715, 31719, 31709, 31701, 31717,
+31706, 31720, 31737, 31700, 31722, 31714, 31708, 31723, 31704, 31711,
+31954, 31956, 31959, 31952, 31953, 32274, 32289, 32279, 32268, 32287,
+32288, 32275, 32270, 32284, 32277, 32282, 32290, 32267, 32271, 32278,
+32269, 32276, 32293, 32292, 32579, 32635, 32636, 32634, 32689, 32751,
+32810, 32809, 32876, 33201, 33190, 33198, 33209, 33205, 33195, 33200,
+33196, 33204, 33202, 33207, 33191, 33266, 33365, 33366, 33367, 34134,
+34117, 34155, 34125, 34131, 34145, 34136, 34112, 34118, 34148, 34113,
+34146, 34116, 34129, 34119, 34147, 34110, 34139, 34161, 34126, 34158,
+34165, 34133, 34151, 34144, 34188, 34150, 34141, 34132, 34149, 34156,
+34403, 34405, 34404, 34715, 34703, 34711, 34707, 34706, 34696, 34689,
+34710, 34712, 34681, 34695, 34723, 34693, 34704, 34705, 34717, 34692,
+34708, 34716, 34714, 34697, 35102, 35110, 35120, 35117, 35118, 35111,
+35121, 35106, 35113, 35107, 35119, 35116, 35103, 35313, 35552, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 35554, 35570, 35572, 35573, 35549, 35604, 35556,
+35551, 35568, 35528, 35550, 35553, 35560, 35583, 35567, 35579, 35985,
+35986, 35984, 36085, 36078, 36081, 36080, 36083, 36204, 36206, 36261,
+36263, 36403, 36414, 36408, 36416, 36421, 36406, 36412, 36413, 36417,
+36400, 36415, 36541, 36662, 36654, 36661, 36658, 36665, 36663, 36660,
+36982, 36985, 36987, 36998, 37114, 37171, 37173, 37174, 37267, 37264,
+37265, 37261, 37263, 37671, 37662, 37640, 37663, 37638, 37647, 37754,
+37688, 37692, 37659, 37667, 37650, 37633, 37702, 37677, 37646, 37645,
+37579, 37661, 37626, 37669, 37651, 37625, 37623, 37684, 37634, 37668,
+37631, 37673, 37689, 37685, 37674, 37652, 37644, 37643, 37630, 37641,
+37632, 37627, 37654, 38332, 38349, 38334, 38329, 38330, 38326, 38335,
+38325, 38333, 38569, 38612, 38667, 38674, 38672, 38809, 38807, 38804,
+38896, 38904, 38965, 38959, 38962, 39204, 39199, 39207, 39209, 39326,
+39406, 39404, 39397, 39396, 39408, 39395, 39402, 39401, 39399, 39609,
+39615, 39604, 39611, 39670, 39674, 39673, 39671, 39731, 39808, 39813,
+39815, 39804, 39806, 39803, 39810, 39827, 39826, 39824, 39802, 39829,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 39805, 39816, 40229, 40215, 40224, 40222,
+40212, 40233, 40221, 40216, 40226, 40208, 40217, 40223, 40584, 40582,
+40583, 40622, 40621, 40661, 40662, 40698, 40722, 40765, 20774, 20773,
+20770, 20772, 20768, 20777, 21236, 22163, 22156, 22157, 22150, 22148,
+22147, 22142, 22146, 22143, 22145, 22742, 22740, 22735, 22738, 23341,
+23333, 23346, 23331, 23340, 23335, 23334, 23343, 23342, 23419, 23537,
+23538, 23991, 24172, 24170, 24510, 24507, 25027, 25013, 25020, 25063,
+25056, 25061, 25060, 25064, 25054, 25839, 25833, 25827, 25835, 25828,
+25832, 25985, 25984, 26038, 26074, 26322, 27277, 27286, 27265, 27301,
+27273, 27295, 27291, 27297, 27294, 27271, 27283, 27278, 27285, 27267,
+27304, 27300, 27281, 27263, 27302, 27290, 27269, 27276, 27282, 27483,
+27565, 27657, 28620, 28585, 28660, 28628, 28643, 28636, 28653, 28647,
+28646, 28638, 28658, 28637, 28642, 28648, 29153, 29169, 29160, 29170,
+29156, 29168, 29154, 29555, 29550, 29551, 29847, 29874, 29867, 29840,
+29866, 29869, 29873, 29861, 29871, 29968, 29969, 29970, 29967, 30084,
+30275, 30280, 30281, 30279, 30372, 30441, 30645, 30635, 30642, 30647,
+30646, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 30644, 30641, 30632, 30704, 30963,
+30973, 30978, 30971, 30972, 30962, 30981, 30969, 30974, 30980, 31147,
+31144, 31324, 31323, 31318, 31320, 31316, 31322, 31422, 31424, 31425,
+31749, 31759, 31730, 31744, 31743, 31739, 31758, 31732, 31755, 31731,
+31746, 31753, 31747, 31745, 31736, 31741, 31750, 31728, 31729, 31760,
+31754, 31976, 32301, 32316, 32322, 32307, 38984, 32312, 32298, 32329,
+32320, 32327, 32297, 32332, 32304, 32315, 32310, 32324, 32314, 32581,
+32639, 32638, 32637, 32756, 32754, 32812, 33211, 33220, 33228, 33226,
+33221, 33223, 33212, 33257, 33371, 33370, 33372, 34179, 34176, 34191,
+34215, 34197, 34208, 34187, 34211, 34171, 34212, 34202, 34206, 34167,
+34172, 34185, 34209, 34170, 34168, 34135, 34190, 34198, 34182, 34189,
+34201, 34205, 34177, 34210, 34178, 34184, 34181, 34169, 34166, 34200,
+34192, 34207, 34408, 34750, 34730, 34733, 34757, 34736, 34732, 34745,
+34741, 34748, 34734, 34761, 34755, 34754, 34764, 34743, 34735, 34756,
+34762, 34740, 34742, 34751, 34744, 34749, 34782, 34738, 35125, 35123,
+35132, 35134, 35137, 35154, 35127, 35138, 35245, 35247, 35246, 35314,
+35315, 35614, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 35608, 35606, 35601, 35589,
+35595, 35618, 35599, 35602, 35605, 35591, 35597, 35592, 35590, 35612,
+35603, 35610, 35919, 35952, 35954, 35953, 35951, 35989, 35988, 36089,
+36207, 36430, 36429, 36435, 36432, 36428, 36423, 36675, 36672, 36997,
+36990, 37176, 37274, 37282, 37275, 37273, 37279, 37281, 37277, 37280,
+37793, 37763, 37807, 37732, 37718, 37703, 37756, 37720, 37724, 37750,
+37705, 37712, 37713, 37728, 37741, 37775, 37708, 37738, 37753, 37719,
+37717, 37714, 37711, 37745, 37751, 37755, 37729, 37726, 37731, 37735,
+37760, 37710, 37721, 38343, 38336, 38345, 38339, 38341, 38327, 38574,
+38576, 38572, 38688, 38687, 38680, 38685, 38681, 38810, 38817, 38812,
+38814, 38813, 38869, 38868, 38897, 38977, 38980, 38986, 38985, 38981,
+38979, 39205, 39211, 39212, 39210, 39219, 39218, 39215, 39213, 39217,
+39216, 39320, 39331, 39329, 39426, 39418, 39412, 39415, 39417, 39416,
+39414, 39419, 39421, 39422, 39420, 39427, 39614, 39678, 39677, 39681,
+39676, 39752, 39834, 39848, 39838, 39835, 39846, 39841, 39845, 39844,
+39814, 39842, 39840, 39855, 40243, 40257, 40295, 40246, 40238, 40239,
+40241, 40248, 40240, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 40261, 40258, 40259,
+40254, 40247, 40256, 40253, 32757, 40237, 40586, 40585, 40589, 40624,
+40648, 40666, 40699, 40703, 40740, 40739, 40738, 40788, 40864, 20785,
+20781, 20782, 22168, 22172, 22167, 22170, 22173, 22169, 22896, 23356,
+23657, 23658, 24000, 24173, 24174, 25048, 25055, 25069, 25070, 25073,
+25066, 25072, 25067, 25046, 25065, 25855, 25860, 25853, 25848, 25857,
+25859, 25852, 26004, 26075, 26330, 26331, 26328, 27333, 27321, 27325,
+27361, 27334, 27322, 27318, 27319, 27335, 27316, 27309, 27486, 27593,
+27659, 28679, 28684, 28685, 28673, 28677, 28692, 28686, 28671, 28672,
+28667, 28710, 28668, 28663, 28682, 29185, 29183, 29177, 29187, 29181,
+29558, 29880, 29888, 29877, 29889, 29886, 29878, 29883, 29890, 29972,
+29971, 30300, 30308, 30297, 30288, 30291, 30295, 30298, 30374, 30397,
+30444, 30658, 30650, 30975, 30988, 30995, 30996, 30985, 30992, 30994,
+30993, 31149, 31148, 31327, 31772, 31785, 31769, 31776, 31775, 31789,
+31773, 31782, 31784, 31778, 31781, 31792, 32348, 32336, 32342, 32355,
+32344, 32354, 32351, 32337, 32352, 32343, 32339, 32693, 32691, 32759,
+32760, 32885, 33233, 33234, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33232, 33375,
+33374, 34228, 34246, 34240, 34243, 34242, 34227, 34229, 34237, 34247,
+34244, 34239, 34251, 34254, 34248, 34245, 34225, 34230, 34258, 34340,
+34232, 34231, 34238, 34409, 34791, 34790, 34786, 34779, 34795, 34794,
+34789, 34783, 34803, 34788, 34772, 34780, 34771, 34797, 34776, 34787,
+34724, 34775, 34777, 34817, 34804, 34792, 34781, 35155, 35147, 35151,
+35148, 35142, 35152, 35153, 35145, 35626, 35623, 35619, 35635, 35632,
+35637, 35655, 35631, 35644, 35646, 35633, 35621, 35639, 35622, 35638,
+35630, 35620, 35643, 35645, 35642, 35906, 35957, 35993, 35992, 35991,
+36094, 36100, 36098, 36096, 36444, 36450, 36448, 36439, 36438, 36446,
+36453, 36455, 36443, 36442, 36449, 36445, 36457, 36436, 36678, 36679,
+36680, 36683, 37160, 37178, 37179, 37182, 37288, 37285, 37287, 37295,
+37290, 37813, 37772, 37778, 37815, 37787, 37789, 37769, 37799, 37774,
+37802, 37790, 37798, 37781, 37768, 37785, 37791, 37773, 37809, 37777,
+37810, 37796, 37800, 37812, 37795, 37797, 38354, 38355, 38353, 38579,
+38615, 38618, 24002, 38623, 38616, 38621, 38691, 38690, 38693, 38828,
+38830, 38824, 38827, 38820, 38826, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 38818,
+38821, 38871, 38873, 38870, 38872, 38906, 38992, 38993, 38994, 39096,
+39233, 39228, 39226, 39439, 39435, 39433, 39437, 39428, 39441, 39434,
+39429, 39431, 39430, 39616, 39644, 39688, 39684, 39685, 39721, 39733,
+39754, 39756, 39755, 39879, 39878, 39875, 39871, 39873, 39861, 39864,
+39891, 39862, 39876, 39865, 39869, 40284, 40275, 40271, 40266, 40283,
+40267, 40281, 40278, 40268, 40279, 40274, 40276, 40287, 40280, 40282,
+40590, 40588, 40671, 40705, 40704, 40726, 40741, 40747, 40746, 40745,
+40744, 40780, 40789, 20788, 20789, 21142, 21239, 21428, 22187, 22189,
+22182, 22183, 22186, 22188, 22746, 22749, 22747, 22802, 23357, 23358,
+23359, 24003, 24176, 24511, 25083, 25863, 25872, 25869, 25865, 25868,
+25870, 25988, 26078, 26077, 26334, 27367, 27360, 27340, 27345, 27353,
+27339, 27359, 27356, 27344, 27371, 27343, 27341, 27358, 27488, 27568,
+27660, 28697, 28711, 28704, 28694, 28715, 28705, 28706, 28707, 28713,
+28695, 28708, 28700, 28714, 29196, 29194, 29191, 29186, 29189, 29349,
+29350, 29348, 29347, 29345, 29899, 29893, 29879, 29891, 29974, 30304,
+30665, 30666, 30660, 30705, 31005, 31003, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+31009, 31004, 30999, 31006, 31152, 31335, 31336, 31795, 31804, 31801,
+31788, 31803, 31980, 31978, 32374, 32373, 32376, 32368, 32375, 32367,
+32378, 32370, 32372, 32360, 32587, 32586, 32643, 32646, 32695, 32765,
+32766, 32888, 33239, 33237, 33380, 33377, 33379, 34283, 34289, 34285,
+34265, 34273, 34280, 34266, 34263, 34284, 34290, 34296, 34264, 34271,
+34275, 34268, 34257, 34288, 34278, 34287, 34270, 34274, 34816, 34810,
+34819, 34806, 34807, 34825, 34828, 34827, 34822, 34812, 34824, 34815,
+34826, 34818, 35170, 35162, 35163, 35159, 35169, 35164, 35160, 35165,
+35161, 35208, 35255, 35254, 35318, 35664, 35656, 35658, 35648, 35667,
+35670, 35668, 35659, 35669, 35665, 35650, 35666, 35671, 35907, 35959,
+35958, 35994, 36102, 36103, 36105, 36268, 36266, 36269, 36267, 36461,
+36472, 36467, 36458, 36463, 36475, 36546, 36690, 36689, 36687, 36688,
+36691, 36788, 37184, 37183, 37296, 37293, 37854, 37831, 37839, 37826,
+37850, 37840, 37881, 37868, 37836, 37849, 37801, 37862, 37834, 37844,
+37870, 37859, 37845, 37828, 37838, 37824, 37842, 37863, 38269, 38362,
+38363, 38625, 38697, 38699, 38700, 38696, 38694, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 38835, 38839, 38838, 38877, 38878, 38879, 39004, 39001, 39005,
+38999, 39103, 39101, 39099, 39102, 39240, 39239, 39235, 39334, 39335,
+39450, 39445, 39461, 39453, 39460, 39451, 39458, 39456, 39463, 39459,
+39454, 39452, 39444, 39618, 39691, 39690, 39694, 39692, 39735, 39914,
+39915, 39904, 39902, 39908, 39910, 39906, 39920, 39892, 39895, 39916,
+39900, 39897, 39909, 39893, 39905, 39898, 40311, 40321, 40330, 40324,
+40328, 40305, 40320, 40312, 40326, 40331, 40332, 40317, 40299, 40308,
+40309, 40304, 40297, 40325, 40307, 40315, 40322, 40303, 40313, 40319,
+40327, 40296, 40596, 40593, 40640, 40700, 40749, 40768, 40769, 40781,
+40790, 40791, 40792, 21303, 22194, 22197, 22195, 22755, 23365, 24006,
+24007, 24302, 24303, 24512, 24513, 25081, 25879, 25878, 25877, 25875,
+26079, 26344, 26339, 26340, 27379, 27376, 27370, 27368, 27385, 27377,
+27374, 27375, 28732, 28725, 28719, 28727, 28724, 28721, 28738, 28728,
+28735, 28730, 28729, 28736, 28731, 28723, 28737, 29203, 29204, 29352,
+29565, 29564, 29882, 30379, 30378, 30398, 30445, 30668, 30670, 30671,
+30669, 30706, 31013, 31011, 31015, 31016, 31012, 31017, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 31154, 31342, 31340, 31341, 31479, 31817, 31816, 31818,
+31815, 31813, 31982, 32379, 32382, 32385, 32384, 32698, 32767, 32889,
+33243, 33241, 33291, 33384, 33385, 34338, 34303, 34305, 34302, 34331,
+34304, 34294, 34308, 34313, 34309, 34316, 34301, 34841, 34832, 34833,
+34839, 34835, 34838, 35171, 35174, 35257, 35319, 35680, 35690, 35677,
+35688, 35683, 35685, 35687, 35693, 36270, 36486, 36488, 36484, 36697,
+36694, 36695, 36693, 36696, 36698, 37005, 37187, 37185, 37303, 37301,
+37298, 37299, 37899, 37907, 37883, 37920, 37903, 37908, 37886, 37909,
+37904, 37928, 37913, 37901, 37877, 37888, 37879, 37895, 37902, 37910,
+37906, 37882, 37897, 37880, 37898, 37887, 37884, 37900, 37878, 37905,
+37894, 38366, 38368, 38367, 38702, 38703, 38841, 38843, 38909, 38910,
+39008, 39010, 39011, 39007, 39105, 39106, 39248, 39246, 39257, 39244,
+39243, 39251, 39474, 39476, 39473, 39468, 39466, 39478, 39465, 39470,
+39480, 39469, 39623, 39626, 39622, 39696, 39698, 39697, 39947, 39944,
+39927, 39941, 39954, 39928, 40000, 39943, 39950, 39942, 39959, 39956,
+39945, 40351, 40345, 40356, 40349, 40338, 40344, 40336, 40347, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 40352, 40340, 40348, 40362, 40343, 40353, 40346,
+40354, 40360, 40350, 40355, 40383, 40361, 40342, 40358, 40359, 40601,
+40603, 40602, 40677, 40676, 40679, 40678, 40752, 40750, 40795, 40800,
+40798, 40797, 40793, 40849, 20794, 20793, 21144, 21143, 22211, 22205,
+22206, 23368, 23367, 24011, 24015, 24305, 25085, 25883, 27394, 27388,
+27395, 27384, 27392, 28739, 28740, 28746, 28744, 28745, 28741, 28742,
+29213, 29210, 29209, 29566, 29975, 30314, 30672, 31021, 31025, 31023,
+31828, 31827, 31986, 32394, 32391, 32392, 32395, 32390, 32397, 32589,
+32699, 32816, 33245, 34328, 34346, 34342, 34335, 34339, 34332, 34329,
+34343, 34350, 34337, 34336, 34345, 34334, 34341, 34857, 34845, 34843,
+34848, 34852, 34844, 34859, 34890, 35181, 35177, 35182, 35179, 35322,
+35705, 35704, 35653, 35706, 35707, 36112, 36116, 36271, 36494, 36492,
+36702, 36699, 36701, 37190, 37188, 37189, 37305, 37951, 37947, 37942,
+37929, 37949, 37948, 37936, 37945, 37930, 37943, 37932, 37952, 37937,
+38373, 38372, 38371, 38709, 38714, 38847, 38881, 39012, 39113, 39110,
+39104, 39256, 39254, 39481, 39485, 39494, 39492, 39490, 39489, 39482,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 39487, 39629, 39701, 39703, 39704, 39702,
+39738, 39762, 39979, 39965, 39964, 39980, 39971, 39976, 39977, 39972,
+39969, 40375, 40374, 40380, 40385, 40391, 40394, 40399, 40382, 40389,
+40387, 40379, 40373, 40398, 40377, 40378, 40364, 40392, 40369, 40365,
+40396, 40371, 40397, 40370, 40570, 40604, 40683, 40686, 40685, 40731,
+40728, 40730, 40753, 40782, 40805, 40804, 40850, 20153, 22214, 22213,
+22219, 22897, 23371, 23372, 24021, 24017, 24306, 25889, 25888, 25894,
+25890, 27403, 27400, 27401, 27661, 28757, 28758, 28759, 28754, 29214,
+29215, 29353, 29567, 29912, 29909, 29913, 29911, 30317, 30381, 31029,
+31156, 31344, 31345, 31831, 31836, 31833, 31835, 31834, 31988, 31985,
+32401, 32591, 32647, 33246, 33387, 34356, 34357, 34355, 34348, 34354,
+34358, 34860, 34856, 34854, 34858, 34853, 35185, 35263, 35262, 35323,
+35710, 35716, 35714, 35718, 35717, 35711, 36117, 36501, 36500, 36506,
+36498, 36496, 36502, 36503, 36704, 36706, 37191, 37964, 37968, 37962,
+37963, 37967, 37959, 37957, 37960, 37961, 37958, 38719, 38883, 39018,
+39017, 39115, 39252, 39259, 39502, 39507, 39508, 39500, 39503, 39496,
+39498, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 39497, 39506, 39504, 39632, 39705,
+39723, 39739, 39766, 39765, 40006, 40008, 39999, 40004, 39993, 39987,
+40001, 39996, 39991, 39988, 39986, 39997, 39990, 40411, 40402, 40414,
+40410, 40395, 40400, 40412, 40401, 40415, 40425, 40409, 40408, 40406,
+40437, 40405, 40413, 40630, 40688, 40757, 40755, 40754, 40770, 40811,
+40853, 40866, 20797, 21145, 22760, 22759, 22898, 23373, 24024, 34863,
+24399, 25089, 25091, 25092, 25897, 25893, 26006, 26347, 27409, 27410,
+27407, 27594, 28763, 28762, 29218, 29570, 29569, 29571, 30320, 30676,
+31847, 31846, 32405, 33388, 34362, 34368, 34361, 34364, 34353, 34363,
+34366, 34864, 34866, 34862, 34867, 35190, 35188, 35187, 35326, 35724,
+35726, 35723, 35720, 35909, 36121, 36504, 36708, 36707, 37308, 37986,
+37973, 37981, 37975, 37982, 38852, 38853, 38912, 39510, 39513, 39710,
+39711, 39712, 40018, 40024, 40016, 40010, 40013, 40011, 40021, 40025,
+40012, 40014, 40443, 40439, 40431, 40419, 40427, 40440, 40420, 40438,
+40417, 40430, 40422, 40434, 40432, 40418, 40428, 40436, 40435, 40424,
+40429, 40642, 40656, 40690, 40691, 40710, 40732, 40760, 40759, 40758,
+40771, 40783, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 40817, 40816, 40814, 40815,
+22227, 22221, 23374, 23661, 25901, 26349, 26350, 27411, 28767, 28769,
+28765, 28768, 29219, 29915, 29925, 30677, 31032, 31159, 31158, 31850,
+32407, 32649, 33389, 34371, 34872, 34871, 34869, 34891, 35732, 35733,
+36510, 36511, 36512, 36509, 37310, 37309, 37314, 37995, 37992, 37993,
+38629, 38726, 38723, 38727, 38855, 38885, 39518, 39637, 39769, 40035,
+40039, 40038, 40034, 40030, 40032, 40450, 40446, 40455, 40451, 40454,
+40453, 40448, 40449, 40457, 40447, 40445, 40452, 40608, 40734, 40774,
+40820, 40821, 40822, 22228, 25902, 26040, 27416, 27417, 27415, 27418,
+28770, 29222, 29354, 30680, 30681, 31033, 31849, 31851, 31990, 32410,
+32408, 32411, 32409, 33248, 33249, 34374, 34375, 34376, 35193, 35194,
+35196, 35195, 35327, 35736, 35737, 36517, 36516, 36515, 37998, 37997,
+37999, 38001, 38003, 38729, 39026, 39263, 40040, 40046, 40045, 40459,
+40461, 40464, 40463, 40466, 40465, 40609, 40693, 40713, 40775, 40824,
+40827, 40826, 40825, 22302, 28774, 31855, 34876, 36274, 36518, 37315,
+38004, 38008, 38006, 38005, 39520, 40052, 40051, 40049, 40053, 40468,
+40467, 40694, 40714, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 40868, 28776, 28773,
+31991, 34410, 34878, 34877, 34879, 35742, 35996, 36521, 36553, 38731,
+39027, 39028, 39116, 39265, 39339, 39524, 39526, 39527, 39716, 40469,
+40471, 40776, 25095, 27422, 29223, 34380, 36520, 38018, 38016, 38017,
+39529, 39528, 39726, 40473, 29225, 34379, 35743, 38019, 40057, 40631,
+30325, 39531, 40058, 40477, 28777, 28778, 40612, 40830, 40777, 40856,
+30849, 37561, 35023, 22715, 24658, 31911, 23290, 9556, 9574, 9559,
+ 9568, 9580, 9571, 9562, 9577, 9565, 9554, 9572, 9557, 9566,
+ 9578, 9569, 9560, 9575, 9563, 9555, 9573, 9558, 9567, 9579,
+ 9570, 9561, 9576, 9564, 9553, 9552, 9581, 9582, 9584, 9583,
+ 9619, 57344, 57345, 57346, 57347, 57348, 57349, 57350, 57351, 57352,
+57353, 57354, 57355, 57356, 57357, 57358, 57359, 57360, 57361, 57362,
+57363, 57364, 57365, 57366, 57367, 57368, 57369, 57370, 57371, 57372,
+57373, 57374, 57375, 57376, 57377, 57378, 57379, 29234, 29244, 29286,
+29314, 29327, 29343, 29357, 29361, 29368, 29374, 29389, 29403, 29476,
+29487, 29496, 29497, 29629, 29646, 29681, 29814, 29858, 29953, 29977,
+29987, 30012, 30020, 30025, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 30029, 30061,
+30082, 30083, 30089, 30124, 30166, 30185, 30272, 30285, 30292, 30312,
+30336, 30339, 30352, 30391, 30393, 30477, 30494, 30531, 30744, 30748,
+30777, 30780, 30791, 30806, 30842, 30901, 30905, 30918, 30937, 30983,
+31024, 31028, 31035, 31104, 31133, 31171, 31201, 31238, 31246, 31299,
+31312, 31427, 31442, 31458, 31463, 31480, 31542, 31586, 31596, 31610,
+31611, 31642, 31646, 31647, 31650, 31655, 31734, 31762, 31764, 31823,
+31830, 31832, 31915, 31994, 32072, 32075, 32119, 32212, 32213, 32214,
+32228, 32333, 32349, 32383, 32393, 32398, 32402, 32468, 32497, 32530,
+32560, 32625, 32642, 32686, 32710, 32800, 32802, 32805, 32817, 32863,
+32872, 32940, 32951, 20890, 21526, 21524, 13535, 19581, 25283, 57508,
+57509, 57510, 21707, 57512, 21948, 32950, 20903, 57516, 57517, 57518,
+21779, 33318, 57521, 21790, 21982, 25529, 26776, 57526, 21762, 21865,
+30132, 25596, 40580, 37418, 57533, 57534, 57535, 35015, 24734, 22053,
+28997, 23282, 57541, 21135, 22095, 30611, 34694, 36397, 33206, 13822,
+29174, 57550, 34820, 37765, 57553, 57554, 30310, 57556, 40050, 57558,
+25294, 57560, 40598, 18825, 31955, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 36570,
+40619, 25831, 57567, 33450, 26471, 28018, 30982, 31172, 32590, 34798,
+57575, 33726, 34351, 35237, 17935, 57580, 39112, 39232, 39245, 39436,
+39639, 40600, 40742, 57588, 20227, 57590, 20281, 20274, 20395, 20566,
+57595, 20526, 20646, 20697, 20750, 20717, 20737, 20980, 21023, 21088,
+21079, 21146, 21201, 21216, 21217, 20947, 20959, 30022, 20990, 21298,
+21292, 21299, 21419, 21418, 40846, 21609, 21660, 21466, 27338, 21875,
+57625, 13782, 57627, 22033, 22093, 57630, 22100, 13811, 57633, 22342,
+22394, 22375, 22586, 22502, 22493, 22592, 57641, 22566, 22748, 22967,
+23001, 23584, 57647, 23761, 23785, 23878, 23950, 57652, 24053, 24075,
+24082, 24110, 24158, 57658, 24397, 31357, 23491, 31419, 57663, 57664,
+24484, 24506, 24508, 57668, 24695, 24740, 24755, 24829, 24880, 57674,
+24988, 24921, 24957, 24924, 25471, 25058, 28885, 25145, 25192, 25221,
+25218, 25254, 25301, 25444, 25397, 25744, 14940, 26184, 26215, 26398,
+26627, 26540, 26617, 26806, 26924, 26881, 26880, 26826, 26995, 27008,
+26942, 57706, 27058, 27072, 27018, 27130, 27113, 27314, 27218, 27293,
+27421, 27474, 27642, 15569, 27854, 28239, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+28089, 28484, 57723, 28634, 28801, 31180, 28980, 15820, 29046, 57730,
+57731, 29205, 29264, 29319, 29484, 29362, 29410, 29442, 29512, 29480,
+29519, 29553, 25989, 57744, 29789, 29800, 29982, 30035, 30074, 30369,
+30412, 30500, 30507, 16485, 30803, 30931, 30936, 40318, 30895, 57760,
+24898, 31145, 39994, 31188, 57765, 31277, 31294, 31305, 31453, 31450,
+30147, 30215, 30210, 57774, 30311, 30319, 22048, 35431, 40727, 31519,
+31634, 31651, 31695, 57784, 31740, 31810, 31825, 31837, 31856, 31870,
+31878, 31875, 31916, 31943, 31938, 57796, 31962, 57798, 32077, 32090,
+32245, 32295, 32366, 40597, 21107, 32797, 32866, 32867, 32870, 32859,
+32934, 33027, 40577, 33224, 57815, 36768, 33270, 33306, 57819, 34673,
+34729, 34700, 40606, 34753, 40476, 57826, 34774, 34805, 34831, 34840,
+34861, 34882, 34885, 39989, 34926, 34986, 34976, 25245, 35139, 35149,
+29042, 34910, 57843, 33533, 17591, 33488, 33669, 40194, 40809, 33824,
+57851, 34010, 33965, 17659, 34123, 57856, 34306, 34320, 25553, 35209,
+35210, 35220, 40005, 35260, 35454, 35401, 35596, 35651, 35713, 35660,
+57871, 36013, 36075, 36087, 36108, 36226, 36262, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 36308, 36392, 36431, 36471, 36469, 36519, 36633, 57885, 36700,
+40260, 37060, 37201, 57890, 37212, 37209, 37223, 37244, 37262, 37307,
+40616, 36950, 36940, 37374, 37474, 37566, 37739, 37742, 37818, 37927,
+38295, 38311, 57909, 38456, 57911, 38531, 38550, 38529, 38589, 38659,
+38689, 38705, 38751, 38815, 38836, 38840, 38842, 38846, 38856, 40639,
+38943, 38958, 40869, 38983, 38987, 39014, 39020, 39092, 40794, 39132,
+39142, 39234, 39225, 39227, 40787, 39242, 40773, 19326, 39386, 31432,
+39610, 39613, 40706, 39722, 57951, 39725, 39650, 39682, 39679, 19463,
+39689, 19460, 19515, 39823, 39837, 39856, 39948, 39957, 39946, 39935,
+39982, 33000, 33001, 33004, 33038, 27705, 20074, 38465, 22770, 31074,
+26658, 57978, 57979, 33031, 22487, 17642, 25653, 34100, 16607, 57986,
+26906, 39938, 30129, 33747, 29041, 27147, 57993, 27258, 39668, 57996,
+57997, 30649, 25904, 28054, 22071, 26405, 27179, 32093, 36961, 20120,
+31910, 31545, 58009, 22901, 14023, 28799, 58013, 28299, 58015, 58016,
+38749, 37584, 22356, 58020, 16089, 58022, 58023, 24985, 29792, 28991,
+31022, 23190, 37704, 26254, 20477, 37697, 13908, 23925, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28702, 25979, 28813, 24269, 58039, 24743, 31408, 24419,
+58043, 29687, 58045, 29800, 30132, 58048, 39785, 189, 8531, 8532,
+ 188, 190, 8533, 8534, 8535, 8536, 8537, 8538, 34450, 34464,
+34477, 34482, 34725, 34737, 8539, 8540, 8541, 8542, 34778, 34895,
+34912, 34951, 34959, 34960, 35046, 35071, 35072, 35108, 35143, 35156,
+35173, 35200, 35217, 35356, 35369, 35371, 35384, 35389, 8978, 35472,
+35476, 35484, 35497, 35503, 35508, 35562, 35615, 8240, 35647, 35661,
+35678, 35682, 35689, 35739, 35921, 35995, 35999, 36052, 36054, 33042,
+33073, 33078, 33119, 33133, 33149, 33171, 33194, 33208, 33217, 33321,
+33325, 33326, 33342, 33378, 33386, 33416
+};
+
+static const uchar ucs_to_big5[][2] =
+{
+ {'\x00','\x00'},{'\x00','\x01'},{'\x00','\x02'},{'\x00','\x03'},{'\x00','\x04'},
+ {'\x00','\x05'},{'\x00','\x06'},{'\x00','\x07'},{'\x00','\x08'},{'\x00','\x09'},
+ {'\x00','\x0a'},{'\x00','\x0b'},{'\x00','\x0c'},{'\x00','\x0d'},{'\x00','\x0e'},
+ {'\x00','\x0f'},{'\x00','\x10'},{'\x00','\x11'},{'\x00','\x12'},{'\x00','\x13'},
+ {'\x00','\x14'},{'\x00','\x15'},{'\x00','\x16'},{'\x00','\x17'},{'\x00','\x18'},
+ {'\x00','\x19'},{'\x00','\x1a'},{'\x00','\x1b'},{'\x00','\x1c'},{'\x00','\x1d'},
+ {'\x00','\x1e'},{'\x00','\x1f'},{'\x00','\x20'},{'\x00','\x21'},{'\x00','\x22'},
+ {'\x00','\x23'},{'\x00','\x24'},{'\x00','\x25'},{'\x00','\x26'},{'\x00','\x27'},
+ {'\x00','\x28'},{'\x00','\x29'},{'\x00','\x2a'},{'\x00','\x2b'},{'\x00','\x2c'},
+ {'\x00','\x2d'},{'\x00','\x2e'},{'\x00','\x2f'},{'\x00','\x30'},{'\x00','\x31'},
+ {'\x00','\x32'},{'\x00','\x33'},{'\x00','\x34'},{'\x00','\x35'},{'\x00','\x36'},
+ {'\x00','\x37'},{'\x00','\x38'},{'\x00','\x39'},{'\x00','\x3a'},{'\x00','\x3b'},
+ {'\x00','\x3c'},{'\x00','\x3d'},{'\x00','\x3e'},{'\x00','\x3f'},{'\x00','\x40'},
+ {'\x00','\x41'},{'\x00','\x42'},{'\x00','\x43'},{'\x00','\x44'},{'\x00','\x45'},
+ {'\x00','\x46'},{'\x00','\x47'},{'\x00','\x48'},{'\x00','\x49'},{'\x00','\x4a'},
+ {'\x00','\x4b'},{'\x00','\x4c'},{'\x00','\x4d'},{'\x00','\x4e'},{'\x00','\x4f'},
+ {'\x00','\x50'},{'\x00','\x51'},{'\x00','\x52'},{'\x00','\x53'},{'\x00','\x54'},
+ {'\x00','\x55'},{'\x00','\x56'},{'\x00','\x57'},{'\x00','\x58'},{'\x00','\x59'},
+ {'\x00','\x5a'},{'\x00','\x5b'},{'\x00','\x5c'},{'\x00','\x5d'},{'\x00','\x5e'},
+ {'\x00','\x5f'},{'\x00','\x60'},{'\x00','\x61'},{'\x00','\x62'},{'\x00','\x63'},
+ {'\x00','\x64'},{'\x00','\x65'},{'\x00','\x66'},{'\x00','\x67'},{'\x00','\x68'},
+ {'\x00','\x69'},{'\x00','\x6a'},{'\x00','\x6b'},{'\x00','\x6c'},{'\x00','\x6d'},
+ {'\x00','\x6e'},{'\x00','\x6f'},{'\x00','\x70'},{'\x00','\x71'},{'\x00','\x72'},
+ {'\x00','\x73'},{'\x00','\x74'},{'\x00','\x75'},{'\x00','\x76'},{'\x00','\x77'},
+ {'\x00','\x78'},{'\x00','\x79'},{'\x00','\x7a'},{'\x00','\x7b'},{'\x00','\x7c'},
+ {'\x00','\x7d'},{'\x00','\x7e'},{'\x00','\x7f'},{'\x00','\x80'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa0','\xdf'},{'\xa2','\x46'},{'\xa2','\x47'},{'\xa0','\xfc'},
+ {'\xa2','\x44'},{'\x7c','\x20'},{'\xa1','\xb1'},{'\xc6','\xd8'},{'\x63','\x20'},
+ {'\xa0','\xde'},{'\x00','\x00'},{'\x00','\x00'},{'\x2d','\x20'},{'\x97','\xfb'},
+ {'\xa1','\xc2'},{'\xa2','\x58'},{'\xa1','\xd3'},{'\x32','\x20'},{'\x33','\x20'},
+ {'\xa1','\xac'},{'\xa3','\x67'},{'\x91','\xf8'},{'\xa1','\x50'},{'\xa0','\xfb'},
+ {'\x31','\x20'},{'\xa0','\xee'},{'\x00','\x00'},{'\xfe','\xb3'},{'\xfe','\xb0'},
+ {'\xfe','\xb4'},{'\xa0','\xef'},{'\xa0','\xa7'},{'\xa0','\xac'},{'\xa0','\xf6'},
+ {'\xa0','\xbe'},{'\xa0','\xb6'},{'\xa0','\xd6'},{'\xa0','\xbb'},{'\xa0','\xbc'},
+ {'\xa0','\xa8'},{'\xa0','\xd7'},{'\xa0','\xf7'},{'\xa0','\xb7'},{'\xa0','\xa9'},
+ {'\xa0','\xad'},{'\xa0','\xf8'},{'\xa0','\xb8'},{'\xa0','\xda'},{'\xa0','\xbd'},
+ {'\xa0','\xaa'},{'\xa0','\xae'},{'\xa0','\xf9'},{'\xa0','\xbf'},{'\xa0','\xb9'},
+ {'\xa1','\xd1'},{'\xa0','\xd9'},{'\xa0','\xab'},{'\xa0','\xaf'},{'\xa0','\xfa'},
+ {'\xa0','\xba'},{'\x59','\x20'},{'\xa0','\xdc'},{'\xa0','\xdd'},{'\xa0','\xe0'},
+ {'\xa0','\xc0'},{'\xa0','\xf0'},{'\xa0','\xce'},{'\xa0','\xc6'},{'\xa0','\xe6'},
+ {'\xa0','\xcb'},{'\xa0','\xcc'},{'\xa0','\xe1'},{'\xa0','\xc1'},{'\xa0','\xf1'},
+ {'\xa0','\xc7'},{'\xa0','\xe2'},{'\xa0','\xc2'},{'\xa0','\xf2'},{'\xa0','\xc8'},
+ {'\xa0','\xea'},{'\xa0','\xcd'},{'\xa0','\xe3'},{'\xa0','\xc3'},{'\xa0','\xf3'},
+ {'\xa0','\xcf'},{'\xa0','\xc9'},{'\xa1','\xd2'},{'\xa0','\xe9'},{'\xa0','\xe4'},
+ {'\xa0','\xc4'},{'\xa0','\xf4'},{'\xa0','\xca'},{'\x79','\x20'},{'\xa0','\xec'},
+ {'\xa0','\xed'},{'\x00','\x00'},{'\xa0','\xb0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa0','\xb1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xd1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xb2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9b','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xb3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe5'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xb4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xfe'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xd0'},{'\x00','\x00'},{'\xa0','\xd2'},
+ {'\x00','\x00'},{'\xa0','\xd3'},{'\x00','\x00'},{'\xa0','\xd4'},{'\x00','\x00'},
+ {'\xa0','\xb5'},{'\x00','\x00'},{'\xa0','\xc5'},{'\x00','\x00'},{'\xa0','\xd5'},
+ {'\x00','\x00'},{'\xa0','\xe5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xcb'},{'\x9b','\xe6'},
+ {'\x00','\x00'},{'\x9b','\xcc'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9b','\xcf'},{'\x9b','\xd0'},{'\x9b','\xc8'},{'\x9b','\xd1'},
+ {'\x9b','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xc7'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe1'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xe2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9b','\xcd'},{'\x00','\x00'},{'\x9b','\xca'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xda'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9b','\xdc'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xdb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xd9'},{'\xa3','\xbe'},{'\x00','\x00'},{'\xa3','\xbc'},{'\xa3','\xbd'},
+ {'\xa3','\xbf'},{'\x00','\x00'},{'\xa1','\xc5'},{'\x00','\x00'},{'\x9b','\xe9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\xbb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\x44'},{'\xa3','\x45'},
+ {'\xa3','\x46'},{'\xa3','\x47'},{'\xa3','\x48'},{'\xa3','\x49'},{'\xa3','\x4a'},
+ {'\xa3','\x4b'},{'\xa3','\x4c'},{'\xa3','\x4d'},{'\xa3','\x4e'},{'\xa3','\x4f'},
+ {'\xa3','\x50'},{'\xa3','\x51'},{'\xa3','\x52'},{'\xa3','\x53'},{'\xa3','\x54'},
+ {'\x00','\x00'},{'\xa3','\x55'},{'\xa3','\x56'},{'\xa3','\x57'},{'\xa3','\x58'},
+ {'\xa3','\x59'},{'\xa3','\x5a'},{'\xa3','\x5b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa3','\x5c'},{'\xa3','\x5d'},{'\xa3','\x5e'},{'\xa3','\x5f'},{'\xa3','\x60'},
+ {'\xa3','\x61'},{'\xa3','\x62'},{'\xa3','\x63'},{'\xa3','\x64'},{'\xa3','\x65'},
+ {'\xa3','\x66'},{'\xa3','\x67'},{'\xa3','\x68'},{'\xa3','\x69'},{'\xa3','\x6a'},
+ {'\xa3','\x6b'},{'\xa3','\x6c'},{'\x00','\x00'},{'\xa3','\x6d'},{'\xa3','\x6e'},
+ {'\xa3','\x6f'},{'\xa3','\x70'},{'\xa3','\x71'},{'\xa3','\x72'},{'\xa3','\x73'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc7','\xf9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc7','\xf3'},{'\xc7','\xf4'},{'\xc7','\xf5'},{'\xc7','\xf6'},{'\xc7','\xf7'},
+ {'\xc7','\xf8'},{'\xc7','\xfa'},{'\xc7','\xfb'},{'\xc7','\xfc'},{'\xc7','\xfd'},
+ {'\xc7','\xfe'},{'\xc8','\x40'},{'\xc8','\x41'},{'\xc8','\x42'},{'\xc8','\x43'},
+ {'\xc8','\x44'},{'\xc8','\x45'},{'\xc8','\x46'},{'\xc8','\x47'},{'\xc8','\x48'},
+ {'\xc8','\x49'},{'\xc8','\x4a'},{'\xc8','\x4b'},{'\xc8','\x4c'},{'\xc8','\x4d'},
+ {'\xc8','\x4e'},{'\xc8','\x4f'},{'\xc8','\x50'},{'\xc8','\x51'},{'\xc8','\x52'},
+ {'\xc8','\x53'},{'\xc8','\x54'},{'\xc8','\x55'},{'\xc8','\x56'},{'\xc8','\x57'},
+ {'\xc8','\x58'},{'\xc8','\x59'},{'\xc8','\x5a'},{'\xc8','\x5c'},{'\xc8','\x5d'},
+ {'\xc8','\x5e'},{'\xc8','\x5f'},{'\xc8','\x60'},{'\xc8','\x61'},{'\xc8','\x62'},
+ {'\xc8','\x63'},{'\xc8','\x64'},{'\xc8','\x65'},{'\xc8','\x66'},{'\xc8','\x67'},
+ {'\xc8','\x68'},{'\xc8','\x69'},{'\xc8','\x6a'},{'\xc8','\x6b'},{'\xc8','\x6c'},
+ {'\xc8','\x6d'},{'\xc8','\x6e'},{'\xc8','\x6f'},{'\xc8','\x70'},{'\xc8','\x71'},
+ {'\xc8','\x72'},{'\xc8','\x73'},{'\xc8','\x74'},{'\xc8','\x75'},{'\x00','\x00'},
+ {'\xc8','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9b','\xd4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xdb'},{'\xa0','\xeb'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9f','\xec'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\x56'},{'\xa1','\x58'},{'\xa2','\x77'},{'\xa1','\xfc'},
+ {'\x00','\x00'},{'\xa1','\xa5'},{'\xa1','\xa6'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xa7'},{'\xa1','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xcf'},
+ {'\x91','\xde'},{'\xa1','\x45'},{'\x00','\x00'},{'\xa3','\xbb'},{'\xa1','\x4c'},
+ {'\xa1','\x4b'},{'\xa1','\x45'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfe','\xe2'},{'\x00','\x00'},{'\xa1','\xac'},{'\xa1','\xb2'},{'\x00','\x00'},
+ {'\xa1','\xab'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xb0'},{'\x91','\xf7'},{'\x00','\x00'},{'\xa1','\xc3'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\xe1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa2','\x4a'},{'\x00','\x00'},{'\xa1','\xc1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x4b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xe2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\xc9'},{'\x97','\xfc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x96','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xc8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfe','\xb1'},{'\xfe','\xb2'},{'\xfe','\xb5'},{'\xfe','\xb6'},
+ {'\xfe','\xb7'},{'\xfe','\xb8'},{'\xfe','\xb9'},{'\xfe','\xba'},{'\xfe','\xc1'},
+ {'\xfe','\xc2'},{'\xfe','\xc3'},{'\xfe','\xc4'},{'\x00','\x00'},{'\xa2','\xb9'},
+ {'\xa2','\xba'},{'\xa2','\xbb'},{'\xa2','\xbc'},{'\xa2','\xbd'},{'\xa2','\xbe'},
+ {'\xa2','\xbf'},{'\xa2','\xc0'},{'\xa2','\xc1'},{'\xa2','\xc2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xb5'},{'\xc6','\xb6'},{'\xc6','\xb7'},{'\xc6','\xb8'},{'\xc6','\xb9'},
+ {'\xc6','\xba'},{'\xc6','\xbb'},{'\xc6','\xbc'},{'\xc6','\xbd'},{'\xc6','\xbe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf6'},{'\xa1','\xf4'},{'\xa1','\xf7'},
+ {'\xa1','\xf5'},{'\x91','\xfb'},{'\x91','\xf6'},{'\xa1','\xf8'},{'\xa1','\xf9'},
+ {'\xa1','\xfb'},{'\xa1','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x91','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\xfd'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc8','\x77'},{'\xc8','\x78'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x96','\x53'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x99','\x65'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x4a'},{'\xc8','\x76'},
+ {'\x9d','\x49'},{'\x9d','\x4c'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf9'},
+ {'\x00','\x00'},{'\xa0','\x79'},{'\x98','\xf9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xbe'},{'\x91','\x6b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x91','\x5f'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\x53'},
+ {'\x00','\x00'},{'\xa3','\x55'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa2','\x41'},{'\xa2','\x42'},{'\x00','\x00'},{'\xa2','\x58'},{'\x00','\x00'},
+ {'\xa1','\xd4'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xdb'},
+ {'\xa1','\xe8'},{'\xa1','\xe7'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xfd'},
+ {'\x00','\x00'},{'\xa1','\xfc'},{'\x00','\x00'},{'\xa3','\x4e'},{'\xa2','\xe4'},
+ {'\xa1','\xe4'},{'\xa1','\xe5'},{'\xa1','\xec'},{'\x9f','\x4c'},{'\x00','\x00'},
+ {'\xa1','\xed'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xef'},{'\xa1','\xee'},{'\xa1','\x47'},{'\x9f','\x46'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xdc'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xda'},{'\xa1','\xdd'},{'\x00','\x00'},{'\xa1','\xdd'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xd8'},{'\xa1','\xd9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\xe0'},
+ {'\x9a','\xa6'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\x72'},{'\x9c','\xaa'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xe6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xe9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x91','\xfc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\x5b'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\xd9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa3','\xc0'},{'\xa3','\xc1'},{'\xa3','\xc2'},{'\xa3','\xc3'},
+ {'\xa3','\xc4'},{'\xa3','\xc5'},{'\xa3','\xc6'},{'\xa3','\xc7'},{'\xa3','\xc8'},
+ {'\xa3','\xc9'},{'\xa3','\xca'},{'\xa3','\xcb'},{'\xa3','\xcc'},{'\xa3','\xcd'},
+ {'\xa3','\xce'},{'\xa3','\xcf'},{'\xa3','\xd0'},{'\xa3','\xd1'},{'\xa3','\xd2'},
+ {'\xa3','\xd3'},{'\xa3','\xd4'},{'\xa3','\xd5'},{'\xa3','\xd6'},{'\xa3','\xd7'},
+ {'\xa3','\xd8'},{'\xa3','\xd9'},{'\xa3','\xda'},{'\xa3','\xdb'},{'\xa3','\xdc'},
+ {'\xa3','\xdd'},{'\xa3','\xde'},{'\xa3','\xdf'},{'\x00','\x00'},{'\xa3','\xe0'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xa1'},{'\xc6','\xa2'},{'\xc6','\xa3'},
+ {'\xc6','\xa4'},{'\xc6','\xa5'},{'\xc6','\xa6'},{'\xc6','\xa7'},{'\xc6','\xa8'},
+ {'\xc6','\xa9'},{'\xc6','\xaa'},{'\x97','\x4b'},{'\x97','\x4c'},{'\x97','\x4d'},
+ {'\x97','\x4e'},{'\x97','\x4f'},{'\x97','\x50'},{'\x97','\x51'},{'\x97','\x52'},
+ {'\x97','\x53'},{'\x97','\x54'},{'\xc6','\xab'},{'\xc6','\xac'},{'\xc6','\xad'},
+ {'\xc6','\xae'},{'\xc6','\xaf'},{'\xc6','\xb0'},{'\xc6','\xb1'},{'\xc6','\xb2'},
+ {'\xc6','\xb3'},{'\xc6','\xb4'},{'\x99','\x4b'},{'\x99','\x4c'},{'\x99','\x4d'},
+ {'\x99','\x4e'},{'\x99','\x4f'},{'\x99','\x50'},{'\x99','\x51'},{'\x99','\x52'},
+ {'\x99','\x53'},{'\x99','\x54'},{'\x9a','\x41'},{'\x9a','\x42'},{'\x9a','\x43'},
+ {'\x9a','\x44'},{'\x9a','\x45'},{'\x9a','\x46'},{'\x9a','\x47'},{'\x9a','\x48'},
+ {'\x9a','\x49'},{'\x9a','\x4a'},{'\x9a','\x4b'},{'\x9a','\x4c'},{'\x9a','\x4d'},
+ {'\x9a','\x4e'},{'\x9a','\x4f'},{'\x9a','\x50'},{'\x9a','\x51'},{'\x9a','\x52'},
+ {'\x9a','\x53'},{'\x9a','\x54'},{'\x99','\xe1'},{'\x99','\xe2'},{'\x99','\xe3'},
+ {'\x99','\xe4'},{'\x99','\xe5'},{'\x99','\xe6'},{'\x99','\xe7'},{'\x99','\xe8'},
+ {'\x99','\xe9'},{'\x99','\xea'},{'\x99','\xeb'},{'\x99','\xec'},{'\x99','\xed'},
+ {'\x99','\xee'},{'\x99','\xef'},{'\x99','\xf0'},{'\x99','\xf1'},{'\x99','\xf2'},
+ {'\x99','\xf3'},{'\x99','\xf4'},{'\x99','\xf5'},{'\x99','\xf6'},{'\x99','\xf7'},
+ {'\x99','\xf8'},{'\x99','\xf9'},{'\x99','\xfa'},{'\x97','\xc7'},{'\x97','\xc8'},
+ {'\x97','\xc9'},{'\x97','\xca'},{'\x97','\xcb'},{'\x97','\xcc'},{'\x97','\xcd'},
+ {'\x97','\xce'},{'\x97','\xcf'},{'\x97','\xd0'},{'\x97','\xd1'},{'\x97','\xd2'},
+ {'\x97','\xd3'},{'\x97','\xd4'},{'\x97','\xd5'},{'\x97','\xd6'},{'\x97','\xd7'},
+ {'\x97','\xd8'},{'\x97','\xd9'},{'\x97','\xda'},{'\x97','\xdb'},{'\x97','\xdc'},
+ {'\x97','\xdd'},{'\x97','\xde'},{'\x97','\xdf'},{'\x97','\xe0'},{'\x97','\xe1'},
+ {'\x97','\xe2'},{'\x97','\xe3'},{'\x97','\xe4'},{'\x97','\xe5'},{'\x97','\xe6'},
+ {'\x97','\xe7'},{'\x97','\xe8'},{'\x97','\xe9'},{'\x97','\xea'},{'\x97','\xeb'},
+ {'\x97','\xec'},{'\x97','\xed'},{'\x97','\xee'},{'\x97','\xef'},{'\x97','\xf0'},
+ {'\x97','\xf1'},{'\x97','\xf2'},{'\x97','\xf3'},{'\x97','\xf4'},{'\x97','\xf5'},
+ {'\x97','\xf6'},{'\x97','\xf7'},{'\x97','\xf8'},{'\x97','\xf9'},{'\x97','\xfa'},
+ {'\x97','\x40'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x77'},{'\x9d','\x7d'},{'\xa2','\x78'},
+ {'\x9d','\x7e'},{'\xa1','\x4c'},{'\xa1','\x4c'},{'\xa1','\x4a'},{'\xa1','\x4a'},
+ {'\xa1','\x4b'},{'\xa1','\x4b'},{'\xa1','\x55'},{'\xa1','\x55'},{'\xa2','\x7a'},
+ {'\xa2','\x7a'},{'\xa2','\x7a'},{'\xa2','\x7a'},{'\xa2','\x7b'},{'\xa2','\x7b'},
+ {'\xa2','\x7b'},{'\xa2','\x7b'},{'\xa2','\x7c'},{'\xa2','\x7c'},{'\xa2','\x7c'},
+ {'\xa2','\x7c'},{'\xa2','\x7d'},{'\xa2','\x7d'},{'\xa2','\x7d'},{'\xa2','\x7d'},
+ {'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},
+ {'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x75'},{'\xa2','\x74'},{'\xa2','\x74'},
+ {'\xa2','\x74'},{'\xa2','\x74'},{'\xa2','\x74'},{'\xa2','\x74'},{'\xa2','\x74'},
+ {'\xa2','\x74'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},
+ {'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x73'},{'\xa2','\x72'},
+ {'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x72'},
+ {'\xa2','\x72'},{'\xa2','\x72'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},
+ {'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},
+ {'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},
+ {'\xa2','\x71'},{'\xa2','\x71'},{'\xa2','\x71'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x91','\xf0'},{'\x00','\x00'},{'\xf9','\xf9'},{'\xf9','\xf8'},{'\xf9','\xe6'},
+ {'\xf9','\xef'},{'\xf9','\xdd'},{'\xf9','\xe8'},{'\xf9','\xf1'},{'\xf9','\xdf'},
+ {'\xf9','\xec'},{'\xf9','\xf5'},{'\xf9','\xe3'},{'\xf9','\xee'},{'\xf9','\xf7'},
+ {'\xf9','\xe5'},{'\xf9','\xe9'},{'\xf9','\xf2'},{'\xf9','\xe0'},{'\xf9','\xeb'},
+ {'\xf9','\xf4'},{'\xf9','\xe2'},{'\xf9','\xe7'},{'\xf9','\xf0'},{'\xf9','\xde'},
+ {'\xf9','\xed'},{'\xf9','\xf6'},{'\xf9','\xe4'},{'\xf9','\xea'},{'\xf9','\xf3'},
+ {'\xf9','\xe1'},{'\xa2','\x7e'},{'\xa2','\xa1'},{'\xa2','\xa3'},{'\xa2','\xa2'},
+ {'\xa2','\xac'},{'\xa2','\xad'},{'\xa2','\xae'},{'\xa1','\x5a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa2','\x62'},{'\xa2','\x63'},{'\xa2','\x64'},{'\xa2','\x65'},
+ {'\xa2','\x66'},{'\xa2','\x67'},{'\xa2','\x68'},{'\xa2','\x69'},{'\xa2','\x70'},
+ {'\xa2','\x6f'},{'\xa2','\x6e'},{'\xa2','\x6d'},{'\xa2','\x6c'},{'\xa2','\x6b'},
+ {'\xa2','\x6a'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf9','\xfe'},
+ {'\xa2','\x76'},{'\xa2','\x79'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xbd'},{'\xa1','\xbc'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xb6'},{'\xa1','\xb5'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xbf'},{'\xa1','\xbe'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf5'},{'\x00','\x00'},
+ {'\xa1','\xbb'},{'\xa1','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa1','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xb7'},{'\xa1','\xb4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xf1'},{'\x91','\xf2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\xa8'},{'\xa2','\xa9'},
+ {'\xa2','\xab'},{'\xa2','\xaa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xba'},
+ {'\x9d','\xbc'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xb9'},{'\xa1','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x40'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\xed'},{'\x9c','\xd1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\x4f'},{'\x9d','\x4e'},{'\x00','\x00'},{'\x9d','\x4d'},{'\x9d','\x50'},
+ {'\x9d','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9f','\x55'},{'\x9f','\x56'},{'\x9f','\x5d'},{'\x9f','\x5b'},{'\x9f','\x58'},
+ {'\x9f','\x59'},{'\x9f','\x5a'},{'\x9f','\x5c'},{'\x9f','\x57'},{'\x00','\x00'},
+ {'\x9d','\x5e'},{'\x9d','\x5d'},{'\x98','\xfc'},{'\x9d','\xb8'},{'\x9d','\x57'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xf0'},{'\xa1','\xf2'},{'\xa1','\xf1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xd8'},
+ {'\x9d','\xdd'},{'\x9d','\xdb'},{'\x9d','\xda'},{'\x9d','\xd7'},{'\x9d','\xde'},
+ {'\x9d','\xdc'},{'\x9d','\xd9'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x66'},
+ {'\x00','\x00'},{'\x9d','\x65'},{'\xa2','\xea'},{'\x00','\x00'},{'\xa1','\xad'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\x6c'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xc0'},{'\x9d','\x6b'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x55'},{'\x00','\x00'},
+ {'\x9d','\x54'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x5c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xe6'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\x77'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x98','\x41'},{'\x98','\x42'},{'\x98','\x43'},
+ {'\x98','\x44'},{'\x98','\x45'},{'\x98','\x46'},{'\x98','\x47'},{'\x98','\x48'},
+ {'\x98','\x49'},{'\x98','\x4a'},{'\xc6','\xa1'},{'\xc6','\xa2'},{'\xc6','\xa3'},
+ {'\xc6','\xa4'},{'\xc6','\xa5'},{'\xc6','\xa6'},{'\xc6','\xa7'},{'\xc6','\xa8'},
+ {'\xc6','\xa9'},{'\xc6','\xaa'},{'\x98','\x41'},{'\x98','\x42'},{'\x98','\x43'},
+ {'\x98','\x44'},{'\x98','\x45'},{'\x98','\x46'},{'\x98','\x47'},{'\x98','\x48'},
+ {'\x98','\x49'},{'\x98','\x4a'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\xed'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9c','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\xd5'},
+ {'\x00','\x00'},{'\x9c','\xd4'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9c','\xdb'},{'\x00','\x00'},{'\x91','\xdb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x91','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9c','\xf7'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xbf'},
+ {'\xc6','\xc0'},{'\x00','\x00'},{'\xc6','\xc1'},{'\x00','\x00'},{'\xc6','\xc2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xc3'},
+ {'\xc6','\xc4'},{'\xc6','\xc5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc6','\xc6'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xc7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xc8'},{'\x00','\x00'},{'\xc6','\xc9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc6','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc6','\xcb'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xcc'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xcd'},{'\xc6','\xce'},
+ {'\xc6','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd0'},
+ {'\xc6','\xd1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc6','\xd4'},{'\xc6','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd6'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa1','\x40'},{'\xa1','\x42'},
+ {'\xa1','\x43'},{'\xa1','\xb2'},{'\x00','\x00'},{'\xc6','\xe0'},{'\xc6','\xe1'},
+ {'\xc6','\xe2'},{'\xa1','\x71'},{'\xa1','\x72'},{'\xa1','\x6d'},{'\xa1','\x6e'},
+ {'\xa1','\x75'},{'\xa1','\x76'},{'\xa1','\x79'},{'\xa1','\x7a'},{'\xa1','\x69'},
+ {'\xa1','\x6a'},{'\xa2','\x45'},{'\x96','\x5d'},{'\xa1','\x65'},{'\xa1','\x66'},
+ {'\x9d','\x51'},{'\x9d','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xe3'},{'\xa1','\xa9'},{'\xa1','\xaa'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa2','\xc3'},{'\xa2','\xc4'},{'\xa2','\xc5'},{'\xa2','\xc6'},
+ {'\xa2','\xc7'},{'\xa2','\xc8'},{'\xa2','\xc9'},{'\xa2','\xca'},{'\xa2','\xcb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\xcc'},
+ {'\xa2','\xcd'},{'\xa2','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xe7'},{'\xc6','\xe8'},
+ {'\xc6','\xe9'},{'\xc6','\xea'},{'\xc6','\xeb'},{'\xc6','\xec'},{'\xc6','\xed'},
+ {'\xc6','\xee'},{'\xc6','\xef'},{'\xc6','\xf0'},{'\xc6','\xf1'},{'\xc6','\xf2'},
+ {'\xc6','\xf3'},{'\xc6','\xf4'},{'\xc6','\xf5'},{'\xc6','\xf6'},{'\xc6','\xf7'},
+ {'\xc6','\xf8'},{'\xc6','\xf9'},{'\xc6','\xfa'},{'\xc6','\xfb'},{'\xc6','\xfc'},
+ {'\xc6','\xfd'},{'\xc6','\xfe'},{'\xc7','\x40'},{'\xc7','\x41'},{'\xc7','\x42'},
+ {'\xc7','\x43'},{'\xc7','\x44'},{'\xc7','\x45'},{'\xc7','\x46'},{'\xc7','\x47'},
+ {'\xc7','\x48'},{'\xc7','\x49'},{'\xc7','\x4a'},{'\xc7','\x4b'},{'\xc7','\x4c'},
+ {'\xc7','\x4d'},{'\xc7','\x4e'},{'\xc7','\x4f'},{'\xc7','\x50'},{'\xc7','\x51'},
+ {'\xc7','\x52'},{'\xc7','\x53'},{'\xc7','\x54'},{'\xc7','\x55'},{'\xc7','\x56'},
+ {'\xc7','\x57'},{'\xc7','\x58'},{'\xc7','\x59'},{'\xc7','\x5a'},{'\xc7','\x5b'},
+ {'\xc7','\x5c'},{'\xc7','\x5d'},{'\xc7','\x5e'},{'\xc7','\x5f'},{'\xc7','\x60'},
+ {'\xc7','\x61'},{'\xc7','\x62'},{'\xc7','\x63'},{'\xc7','\x64'},{'\xc7','\x65'},
+ {'\xc7','\x66'},{'\xc7','\x67'},{'\xc7','\x68'},{'\xc7','\x69'},{'\xc7','\x6a'},
+ {'\xc7','\x6b'},{'\xc7','\x6c'},{'\xc7','\x6d'},{'\xc7','\x6e'},{'\xc7','\x6f'},
+ {'\xc7','\x70'},{'\xc7','\x71'},{'\xc7','\x72'},{'\xc7','\x73'},{'\xc7','\x74'},
+ {'\xc7','\x75'},{'\xc7','\x76'},{'\xc7','\x77'},{'\xc7','\x78'},{'\xc7','\x79'},
+ {'\xc7','\x7a'},{'\xc8','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc8','\xb1'},{'\xc8','\xb2'},
+ {'\xc6','\xdc'},{'\xc6','\xdd'},{'\x00','\x00'},{'\x00','\x00'},{'\xc7','\x7b'},
+ {'\xc7','\x7c'},{'\xc7','\x7d'},{'\xc7','\x7e'},{'\xc7','\xa1'},{'\xc7','\xa2'},
+ {'\xc7','\xa3'},{'\xc7','\xa4'},{'\xc7','\xa5'},{'\xc7','\xa6'},{'\xc7','\xa7'},
+ {'\xc7','\xa8'},{'\xc7','\xa9'},{'\xc7','\xaa'},{'\xc7','\xab'},{'\xc7','\xac'},
+ {'\xc7','\xad'},{'\xc7','\xae'},{'\xc7','\xaf'},{'\xc7','\xb0'},{'\xc7','\xb1'},
+ {'\xc7','\xb2'},{'\xc7','\xb3'},{'\xc7','\xb4'},{'\xc7','\xb5'},{'\xc7','\xb6'},
+ {'\xc7','\xb7'},{'\xc7','\xb8'},{'\xc7','\xb9'},{'\xc7','\xba'},{'\xc7','\xbb'},
+ {'\xc7','\xbc'},{'\xc7','\xbd'},{'\xc7','\xbe'},{'\xc7','\xbf'},{'\xc7','\xc0'},
+ {'\xc7','\xc1'},{'\xc7','\xc2'},{'\xc7','\xc3'},{'\xc7','\xc4'},{'\xc7','\xc5'},
+ {'\xc7','\xc6'},{'\xc7','\xc7'},{'\xc7','\xc8'},{'\xc7','\xc9'},{'\xc7','\xca'},
+ {'\xc7','\xcb'},{'\xc7','\xcc'},{'\xc7','\xcd'},{'\xc7','\xce'},{'\xc7','\xcf'},
+ {'\xc7','\xd0'},{'\xc7','\xd1'},{'\xc7','\xd2'},{'\xc7','\xd3'},{'\xc7','\xd4'},
+ {'\xc7','\xd5'},{'\xc7','\xd6'},{'\xc7','\xd7'},{'\xc7','\xd8'},{'\xc7','\xd9'},
+ {'\xc7','\xda'},{'\xc7','\xdb'},{'\xc7','\xdc'},{'\xc7','\xdd'},{'\xc7','\xde'},
+ {'\xc7','\xdf'},{'\xc7','\xe0'},{'\xc7','\xe1'},{'\xc7','\xe2'},{'\xc7','\xe3'},
+ {'\xc7','\xe4'},{'\xc7','\xe5'},{'\xc7','\xe6'},{'\xc7','\xe7'},{'\xc7','\xe8'},
+ {'\xc7','\xe9'},{'\xc7','\xea'},{'\xc7','\xeb'},{'\xc7','\xec'},{'\xc7','\xed'},
+ {'\xc7','\xee'},{'\xc7','\xef'},{'\xc7','\xf0'},{'\xc7','\xf1'},{'\xc7','\xf2'},
+ {'\xc8','\xb4'},{'\xc8','\xb5'},{'\xc8','\xb6'},{'\xc8','\xb7'},{'\xc8','\xb8'},
+ {'\xc6','\xe3'},{'\xc6','\xda'},{'\xc6','\xdb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa3','\x74'},
+ {'\xa3','\x75'},{'\xa3','\x76'},{'\xa3','\x77'},{'\xa3','\x78'},{'\xa3','\x79'},
+ {'\xa3','\x7a'},{'\xa3','\x7b'},{'\xa3','\x7c'},{'\xa3','\x7d'},{'\xa3','\x7e'},
+ {'\xa3','\xa1'},{'\xa3','\xa2'},{'\xa3','\xa3'},{'\xa3','\xa4'},{'\xa3','\xa5'},
+ {'\xa3','\xa6'},{'\xa3','\xa7'},{'\xa3','\xa8'},{'\xa3','\xa9'},{'\xa3','\xaa'},
+ {'\xa3','\xab'},{'\xa3','\xac'},{'\xa3','\xad'},{'\xa3','\xae'},{'\xa3','\xaf'},
+ {'\xa3','\xb0'},{'\xa3','\xb1'},{'\xa3','\xb2'},{'\xa3','\xb3'},{'\xa3','\xb4'},
+ {'\xa3','\xb5'},{'\xa3','\xb6'},{'\xa3','\xb7'},{'\xa3','\xb8'},{'\xa3','\xb9'},
+ {'\xa3','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa4','\x40'},{'\xa4','\x47'},{'\xa4','\x54'},{'\xa5','\x7c'},{'\xa4','\x57'},
+ {'\xa4','\xa4'},{'\xa4','\x55'},{'\xa5','\xd2'},{'\xa4','\x41'},{'\xa4','\xfe'},
+ {'\xa4','\x42'},{'\xa4','\xd1'},{'\xa6','\x61'},{'\xa4','\x48'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc8','\x79'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9c','\x41'},{'\x9c','\x42'},{'\x9c','\x43'},
+ {'\x9c','\x44'},{'\x9c','\x45'},{'\x9c','\x46'},{'\x9c','\x47'},{'\x9c','\x48'},
+ {'\x9c','\x49'},{'\x9c','\x4a'},{'\xa4','\xeb'},{'\xa4','\xf5'},{'\xa4','\xf4'},
+ {'\xa4','\xec'},{'\xaa','\xf7'},{'\xa4','\x67'},{'\xa4','\xe9'},{'\x99','\xfd'},
+ {'\x99','\xfc'},{'\xaa','\xc0'},{'\xa6','\x57'},{'\xaf','\x53'},{'\xb0','\x5d'},
+ {'\xaf','\xac'},{'\xb3','\xd2'},{'\xa5','\x4e'},{'\xa9','\x49'},{'\xbe','\xc7'},
+ {'\xba','\xca'},{'\xa5','\xf8'},{'\xb8','\xea'},{'\xa8','\xf3'},{'\xb2','\xbd'},
+ {'\xa5','\xf0'},{'\xa6','\xdb'},{'\xa6','\xdc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x40'},{'\xa4','\x47'},
+ {'\xa4','\x54'},{'\xa5','\x7c'},{'\xa4','\xad'},{'\xa4','\xbb'},{'\xa4','\x43'},
+ {'\xa4','\x4b'},{'\xa4','\x45'},{'\xa4','\x51'},{'\xa4','\xeb'},{'\xa4','\xf5'},
+ {'\xa4','\xf4'},{'\xa4','\xec'},{'\xaa','\xf7'},{'\xa4','\x67'},{'\xa4','\xe9'},
+ {'\xae','\xe8'},{'\xa6','\xb3'},{'\xaa','\xc0'},{'\xa6','\x57'},{'\xaf','\x53'},
+ {'\xb0','\x5d'},{'\xaf','\xac'},{'\xb3','\xd2'},{'\xaf','\xb5'},{'\xa8','\x6b'},
+ {'\xa4','\x6b'},{'\xbe','\x41'},{'\xc0','\x75'},{'\xa6','\x4c'},{'\xaa','\x60'},
+ {'\xb6','\xb5'},{'\xa5','\xf0'},{'\xbc','\x67'},{'\xa1','\xc0'},{'\xa4','\x57'},
+ {'\xa4','\xa4'},{'\xa4','\x55'},{'\xa5','\xaa'},{'\xa5','\x6b'},{'\xc2','\xe5'},
+ {'\xa9','\x76'},{'\xbe','\xc7'},{'\xba','\xca'},{'\xa5','\xf8'},{'\xb8','\xea'},
+ {'\xa8','\xf3'},{'\xa9','\x5d'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x48','\x67'},
+ {'\x00','\x00'},{'\x65','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x64','\x61'},{'\x41','\x55'},{'\x00','\x00'},{'\x6f','\x56'},{'\x70','\x63'},
+ {'\x64','\x6d'},{'\x00','\x00'},{'\x00','\x00'},{'\x49','\x55'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x70','\x41'},
+ {'\x6e','\x41'},{'\x00','\x00'},{'\x6d','\x41'},{'\x6b','\x41'},{'\x4b','\x42'},
+ {'\x4d','\x42'},{'\x47','\x42'},{'\x00','\x00'},{'\x00','\x00'},{'\x70','\x46'},
+ {'\x6e','\x46'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x55'},{'\xa2','\x56'},
+ {'\x48','\x7a'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x66','\x6d'},
+ {'\x6e','\x6d'},{'\x00','\x00'},{'\xa2','\x50'},{'\xa2','\x51'},{'\xa2','\x52'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x54'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9d','\xe7'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x50','\x61'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x70','\x73'},{'\x6e','\x73'},{'\x00','\x00'},
+ {'\x6d','\x73'},{'\x70','\x56'},{'\x6e','\x56'},{'\x00','\x00'},{'\x6d','\x56'},
+ {'\x6b','\x56'},{'\x4d','\x56'},{'\x70','\x57'},{'\x6e','\x57'},{'\x00','\x00'},
+ {'\x6d','\x57'},{'\x6b','\x57'},{'\x4d','\x57'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9d','\xe3'},{'\x42','\x71'},{'\xa2','\x57'},{'\x63','\x64'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x64','\x42'},{'\x47','\x79'},{'\x68','\x61'},{'\x48','\x50'},
+ {'\x69','\x6e'},{'\x4b','\x4b'},{'\xa2','\x53'},{'\x6b','\x74'},{'\x6c','\x6d'},
+ {'\xa1','\xeb'},{'\xa1','\xea'},{'\x6c','\x78'},{'\x6d','\x62'},{'\xa2','\x4f'},
+ {'\x00','\x00'},{'\x50','\x48'},{'\x9d','\xe4'},{'\x00','\x00'},{'\x50','\x52'},
+ {'\x73','\x72'},{'\x53','\x76'},{'\x57','\x62'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x91','\xe0'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\xa2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\x44'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x95','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x48'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x4c'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfb','\xdf'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfb','\xe5'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfb','\x6f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x95','\x42'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x7d'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x67'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x95','\x5e'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x95','\xde'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x95','\xc7'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\x61'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x95','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfc','\x7c'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x71'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\xc2'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x4d'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x96','\xad'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\xd3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfd','\x5e'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x4a'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfd','\x67'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\xb0'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\x7d'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfd','\xe3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfd','\xf1'},{'\x00','\x00'},{'\x00','\x00'},{'\xfd','\xef'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfd','\xf2'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfb','\x45'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x40'},{'\xa4','\x42'},
+ {'\x00','\x00'},{'\xa4','\x43'},{'\x98','\xa7'},{'\x00','\x00'},{'\x91','\xd7'},
+ {'\xc9','\x45'},{'\xa4','\x56'},{'\xa4','\x54'},{'\xa4','\x57'},{'\xa4','\x55'},
+ {'\xc9','\x46'},{'\xa4','\xa3'},{'\xc9','\x4f'},{'\xc9','\x4d'},{'\xa4','\xa2'},
+ {'\xa4','\xa1'},{'\x00','\x00'},{'\x83','\xfd'},{'\xa5','\x42'},{'\xa5','\x41'},
+ {'\xa5','\x40'},{'\x81','\x40'},{'\xa5','\x43'},{'\xa4','\xfe'},{'\x85','\xd2'},
+ {'\x8a','\xbd'},{'\x83','\x5b'},{'\x85','\x46'},{'\xa5','\xe0'},{'\xa5','\xe1'},
+ {'\x00','\x00'},{'\x93','\xe5'},{'\x81','\x41'},{'\x00','\x00'},{'\x83','\x55'},
+ {'\x8b','\xf2'},{'\xa8','\xc3'},{'\x84','\xca'},{'\x9c','\xc9'},{'\x00','\x00'},
+ {'\x83','\xaa'},{'\xa4','\x58'},{'\x81','\x42'},{'\xa4','\xa4'},{'\xc9','\x50'},
+ {'\x98','\xa8'},{'\xa4','\xa5'},{'\xc9','\x63'},{'\xa6','\xea'},{'\xcb','\xb1'},
+ {'\x8a','\x5a'},{'\x00','\x00'},{'\xc6','\xbf'},{'\x91','\xcc'},{'\xa4','\x59'},
+ {'\xa4','\xa6'},{'\x83','\x6f'},{'\xa5','\x44'},{'\xc9','\x64'},{'\x8b','\xed'},
+ {'\x8a','\x5b'},{'\xc6','\xc0'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\x40'},
+ {'\xa4','\x44'},{'\x94','\xf2'},{'\xa4','\x5b'},{'\x00','\x00'},{'\xc9','\x47'},
+ {'\xa4','\x5c'},{'\x85','\xf3'},{'\x00','\x00'},{'\xa4','\xa7'},{'\x83','\xbf'},
+ {'\xa5','\x45'},{'\xa5','\x47'},{'\xa5','\x46'},{'\x87','\xe4'},{'\x00','\x00'},
+ {'\xa5','\xe2'},{'\xa5','\xe3'},{'\x84','\xce'},{'\x81','\x43'},{'\xa8','\xc4'},
+ {'\x92','\xe9'},{'\xad','\xbc'},{'\xa4','\x41'},{'\x9c','\xdf'},{'\x9c','\xe8'},
+ {'\xc9','\x41'},{'\xa4','\x45'},{'\xa4','\x5e'},{'\xa4','\x5d'},{'\x84','\x74'},
+ {'\x85','\x70'},{'\x81','\x44'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x83','\xbc'},{'\x00','\x00'},{'\x00','\x00'},{'\xa5','\xe4'},{'\xfe','\x41'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x85','\x67'},{'\x85','\xaf'},{'\x00','\x00'},{'\xa8','\xc5'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x61'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb0','\xae'},
+ {'\xd4','\x4b'},{'\x93','\xfa'},{'\x98','\xa9'},{'\xb6','\xc3'},{'\xdc','\xb1'},
+ {'\xdc','\xb2'},{'\xc6','\xc1'},{'\xa4','\x46'},{'\x98','\xaa'},{'\xa4','\xa9'},
+ {'\x83','\x5c'},{'\x81','\x45'},{'\xa8','\xc6'},{'\xa4','\x47'},{'\xc9','\x48'},
+ {'\xa4','\x5f'},{'\x8a','\x5f'},{'\x00','\x00'},{'\xa4','\xaa'},{'\xa4','\xac'},
+ {'\xc9','\x51'},{'\xa4','\xad'},{'\xa4','\xab'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfe','\x62'},{'\xa5','\xe5'},{'\x83','\x52'},{'\xa8','\xc7'},{'\x92','\x40'},
+ {'\x00','\x00'},{'\xa8','\xc8'},{'\xab','\x45'},{'\xc6','\xc2'},{'\xa4','\x60'},
+ {'\xa4','\xae'},{'\x98','\xab'},{'\xa5','\xe6'},{'\xa5','\xe8'},{'\xa5','\xe7'},
+ {'\x84','\x64'},{'\xa6','\xeb'},{'\x83','\xc2'},{'\x00','\x00'},{'\xa8','\xc9'},
+ {'\xa8','\xca'},{'\xab','\x46'},{'\xab','\x47'},{'\x00','\x00'},{'\x81','\x46'},
+ {'\x00','\x00'},{'\x89','\x5d'},{'\xad','\xbd'},{'\x00','\x00'},{'\x8a','\x62'},
+ {'\xdc','\xb3'},{'\x98','\xac'},{'\x00','\x00'},{'\xf6','\xd6'},{'\xa4','\x48'},
+ {'\x9c','\xf4'},{'\x98','\xad'},{'\x00','\x00'},{'\x00','\x00'},{'\x87','\xa3'},
+ {'\xa4','\xb0'},{'\xa4','\xaf'},{'\xc9','\x52'},{'\xa4','\xb1'},{'\xa4','\xb7'},
+ {'\x85','\xb2'},{'\xa4','\xb2'},{'\xa4','\xb3'},{'\xc9','\x54'},{'\xc9','\x53'},
+ {'\xa4','\xb5'},{'\xa4','\xb6'},{'\x00','\x00'},{'\xa4','\xb4'},{'\x84','\x47'},
+ {'\x93','\xc2'},{'\x00','\x00'},{'\x83','\x54'},{'\x00','\x00'},{'\x83','\xac'},
+ {'\xa5','\x4a'},{'\xa5','\x4b'},{'\xa5','\x4c'},{'\xa5','\x4d'},{'\xa5','\x49'},
+ {'\xa5','\x50'},{'\xc9','\x6a'},{'\x00','\x00'},{'\xc9','\x66'},{'\xc9','\x69'},
+ {'\xa5','\x51'},{'\xa5','\x61'},{'\x00','\x00'},{'\xc9','\x68'},{'\x00','\x00'},
+ {'\xa5','\x4e'},{'\xa5','\x4f'},{'\xa5','\x48'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc9','\x65'},{'\xc9','\x67'},{'\x87','\xa4'},{'\x81','\x47'},{'\x83','\xa8'},
+ {'\x81','\x48'},{'\x92','\x54'},{'\x00','\x00'},{'\xa5','\xf5'},{'\xc9','\xb0'},
+ {'\xa5','\xf2'},{'\xa5','\xf6'},{'\xc9','\xba'},{'\xc9','\xae'},{'\xa5','\xf3'},
+ {'\xc9','\xb2'},{'\x98','\xae'},{'\x00','\x00'},{'\x00','\x00'},{'\xa5','\xf4'},
+ {'\x81','\x49'},{'\xa5','\xf7'},{'\x00','\x00'},{'\xa5','\xe9'},{'\xc9','\xb1'},
+ {'\xa5','\xf8'},{'\xc9','\xb5'},{'\xfb','\xba'},{'\xc9','\xb9'},{'\xc9','\xb6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc9','\xb3'},{'\xa5','\xea'},{'\xa5','\xec'},
+ {'\xa5','\xf9'},{'\x00','\x00'},{'\xa5','\xee'},{'\xc9','\xab'},{'\xa5','\xf1'},
+ {'\xa5','\xef'},{'\xa5','\xf0'},{'\xc9','\xbb'},{'\xc9','\xb8'},{'\xc9','\xaf'},
+ {'\xa5','\xed'},{'\x00','\x00'},{'\x84','\x67'},{'\xc9','\xac'},{'\xa5','\xeb'},
+ {'\x85','\xd1'},{'\x8d','\xfd'},{'\x81','\x4a'},{'\xc9','\xb4'},{'\x84','\xc4'},
+ {'\x83','\xec'},{'\x85','\xb1'},{'\x00','\x00'},{'\xc9','\xb7'},{'\x00','\x00'},
+ {'\x85','\xb4'},{'\x83','\xa9'},{'\x83','\xab'},{'\x84','\xc3'},{'\x98','\xaf'},
+ {'\x98','\xb0'},{'\x83','\xeb'},{'\x83','\x43'},{'\xc9','\xad'},{'\xca','\x66'},
+ {'\x00','\x00'},{'\xa7','\x42'},{'\xa6','\xf4'},{'\x00','\x00'},{'\xfb','\xbd'},
+ {'\xca','\x67'},{'\xa6','\xf1'},{'\x00','\x00'},{'\xa7','\x44'},{'\x98','\xb1'},
+ {'\xa6','\xf9'},{'\xfb','\xbc'},{'\xa6','\xf8'},{'\xca','\x5b'},{'\xa6','\xfc'},
+ {'\xa6','\xf7'},{'\xca','\x60'},{'\xca','\x68'},{'\x00','\x00'},{'\xca','\x64'},
+ {'\x98','\xb2'},{'\xa6','\xfa'},{'\x00','\x00'},{'\x98','\xb3'},{'\xa6','\xfd'},
+ {'\xa6','\xee'},{'\xa7','\x47'},{'\xca','\x5d'},{'\x00','\x00'},{'\x98','\xb4'},
+ {'\xcb','\xbd'},{'\xa6','\xec'},{'\xa7','\x43'},{'\xa6','\xed'},{'\xa6','\xf5'},
+ {'\xa6','\xf6'},{'\xca','\x62'},{'\xca','\x5e'},{'\xa6','\xfb'},{'\xa6','\xf3'},
+ {'\xca','\x5a'},{'\xa6','\xef'},{'\xca','\x65'},{'\xa7','\x45'},{'\xa7','\x48'},
+ {'\xa6','\xf2'},{'\xa7','\x40'},{'\xa7','\x46'},{'\xa6','\xf0'},{'\xca','\x63'},
+ {'\xa7','\x41'},{'\xca','\x69'},{'\xca','\x5c'},{'\xa6','\xfe'},{'\xca','\x5f'},
+ {'\x8e','\x40'},{'\x00','\x00'},{'\xca','\x61'},{'\x00','\x00'},{'\xa8','\xd8'},
+ {'\xcb','\xbf'},{'\xcb','\xcb'},{'\xa8','\xd0'},{'\x00','\x00'},{'\xcb','\xcc'},
+ {'\xa8','\xcb'},{'\xa8','\xd5'},{'\x00','\x00'},{'\x98','\xb5'},{'\xa8','\xce'},
+ {'\xcb','\xb9'},{'\xa8','\xd6'},{'\xcb','\xb8'},{'\xcb','\xbc'},{'\xcb','\xc3'},
+ {'\xcb','\xc1'},{'\xa8','\xde'},{'\xa8','\xd9'},{'\xcb','\xb3'},{'\xcb','\xb5'},
+ {'\xa8','\xdb'},{'\xa8','\xcf'},{'\xcb','\xb6'},{'\xcb','\xc2'},{'\xcb','\xc9'},
+ {'\xa8','\xd4'},{'\xcb','\xbb'},{'\xcb','\xb4'},{'\xa8','\xd3'},{'\xcb','\xb7'},
+ {'\xa8','\xd7'},{'\xcb','\xba'},{'\x81','\x4b'},{'\xa8','\xd2'},{'\x00','\x00'},
+ {'\xa8','\xcd'},{'\x00','\x00'},{'\xa8','\xdc'},{'\xcb','\xc4'},{'\xa8','\xdd'},
+ {'\xcb','\xc8'},{'\x00','\x00'},{'\xcb','\xc6'},{'\xcb','\xca'},{'\xa8','\xda'},
+ {'\xcb','\xbe'},{'\xcb','\xb2'},{'\x00','\x00'},{'\xcb','\xc0'},{'\xa8','\xd1'},
+ {'\xcb','\xc5'},{'\xa8','\xcc'},{'\xcb','\xc7'},{'\x00','\x00'},{'\x83','\x65'},
+ {'\x92','\x55'},{'\x98','\xb6'},{'\x83','\x66'},{'\x00','\x00'},{'\x86','\xab'},
+ {'\x83','\xed'},{'\x83','\xee'},{'\x86','\xac'},{'\x87','\xa7'},{'\x88','\xca'},
+ {'\xfb','\xbe'},{'\x87','\xa6'},{'\x82','\x7d'},{'\xab','\x56'},{'\xab','\x4a'},
+ {'\x98','\xb7'},{'\x00','\x00'},{'\xcd','\xe0'},{'\xcd','\xe8'},{'\x98','\xf7'},
+ {'\xab','\x49'},{'\xab','\x51'},{'\xab','\x5d'},{'\x00','\x00'},{'\xcd','\xee'},
+ {'\xcd','\xec'},{'\xcd','\xe7'},{'\x00','\x00'},{'\x98','\xb8'},{'\x00','\x00'},
+ {'\xab','\x4b'},{'\xcd','\xed'},{'\xcd','\xe3'},{'\xab','\x59'},{'\xab','\x50'},
+ {'\xab','\x58'},{'\xcd','\xde'},{'\x00','\x00'},{'\xcd','\xea'},{'\x98','\xb9'},
+ {'\xcd','\xe1'},{'\xab','\x54'},{'\xcd','\xe2'},{'\x98','\xba'},{'\xcd','\xdd'},
+ {'\xab','\x5b'},{'\xab','\x4e'},{'\xab','\x57'},{'\xab','\x4d'},{'\x00','\x00'},
+ {'\xcd','\xdf'},{'\xcd','\xe4'},{'\x00','\x00'},{'\xcd','\xeb'},{'\xab','\x55'},
+ {'\xab','\x52'},{'\xcd','\xe6'},{'\xab','\x5a'},{'\xcd','\xe9'},{'\xcd','\xe5'},
+ {'\xab','\x4f'},{'\xab','\x5c'},{'\xab','\x53'},{'\xab','\x4c'},{'\xab','\x48'},
+ {'\x00','\x00'},{'\x8d','\xb9'},{'\x94','\x5f'},{'\x94','\x60'},{'\x88','\xc8'},
+ {'\x00','\x00'},{'\x8c','\xc8'},{'\x83','\xa7'},{'\x8c','\x6c'},{'\x00','\x00'},
+ {'\xcd','\xef'},{'\x87','\xa8'},{'\xad','\xd7'},{'\xad','\xc1'},{'\x98','\xbb'},
+ {'\xad','\xd1'},{'\x98','\xbc'},{'\xad','\xd6'},{'\xd0','\xd0'},{'\xd0','\xcf'},
+ {'\xd0','\xd4'},{'\xd0','\xd5'},{'\xad','\xc4'},{'\x98','\xbd'},{'\xad','\xcd'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfe','\x7b'},{'\xad','\xda'},{'\x81','\x4c'},
+ {'\xad','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\xbe'},{'\x00','\x00'},
+ {'\xd0','\xc9'},{'\xad','\xc7'},{'\xd0','\xca'},{'\x98','\xbf'},{'\xad','\xdc'},
+ {'\x00','\x00'},{'\xad','\xd3'},{'\xad','\xbe'},{'\xad','\xbf'},{'\xd0','\xdd'},
+ {'\xb0','\xbf'},{'\x00','\x00'},{'\xad','\xcc'},{'\xad','\xcb'},{'\xd0','\xcb'},
+ {'\xad','\xcf'},{'\xd4','\x5b'},{'\xad','\xc6'},{'\xd0','\xd6'},{'\xad','\xd5'},
+ {'\xad','\xd4'},{'\xad','\xca'},{'\xd0','\xce'},{'\xd0','\xd7'},{'\x00','\x00'},
+ {'\xd0','\xc8'},{'\xad','\xc9'},{'\xd0','\xd8'},{'\xad','\xd2'},{'\xd0','\xcc'},
+ {'\xad','\xc0'},{'\x82','\xa9'},{'\xad','\xc3'},{'\xad','\xc2'},{'\xd0','\xd9'},
+ {'\xad','\xd0'},{'\xad','\xc5'},{'\xad','\xd9'},{'\xad','\xdb'},{'\xd0','\xd3'},
+ {'\xad','\xd8'},{'\xfb','\xc1'},{'\xd0','\xdb'},{'\xd0','\xcd'},{'\xd0','\xdc'},
+ {'\x00','\x00'},{'\xd0','\xd1'},{'\x98','\xc0'},{'\xd0','\xda'},{'\x82','\xa3'},
+ {'\xd0','\xd2'},{'\x00','\x00'},{'\x92','\xb2'},{'\x85','\xb0'},{'\x98','\xc1'},
+ {'\xad','\xc8'},{'\x00','\x00'},{'\x85','\xb3'},{'\x00','\x00'},{'\xd4','\x63'},
+ {'\xd4','\x57'},{'\x81','\x4d'},{'\xb0','\xb3'},{'\x00','\x00'},{'\xd4','\x5c'},
+ {'\xd4','\x62'},{'\xb0','\xb2'},{'\xd4','\x55'},{'\xb0','\xb6'},{'\xd4','\x59'},
+ {'\xd4','\x52'},{'\xb0','\xb4'},{'\xd4','\x56'},{'\xb0','\xb9'},{'\xb0','\xbe'},
+ {'\x81','\x4e'},{'\xd4','\x67'},{'\x00','\x00'},{'\xd4','\x51'},{'\x00','\x00'},
+ {'\xb0','\xba'},{'\xfb','\xbf'},{'\xd4','\x66'},{'\x98','\xc2'},{'\x00','\x00'},
+ {'\xb0','\xb5'},{'\xd4','\x58'},{'\xb0','\xb1'},{'\xd4','\x53'},{'\xd4','\x4f'},
+ {'\xd4','\x5d'},{'\xd4','\x50'},{'\xd4','\x4e'},{'\xd4','\x5a'},{'\xd4','\x60'},
+ {'\xd4','\x61'},{'\xb0','\xb7'},{'\x98','\xc3'},{'\x00','\x00'},{'\xd8','\x5b'},
+ {'\xd4','\x5e'},{'\xd4','\x4d'},{'\xd4','\x5f'},{'\x85','\xb5'},{'\xb0','\xc1'},
+ {'\xd4','\x64'},{'\xb0','\xc0'},{'\xd4','\x4c'},{'\x00','\x00'},{'\xd4','\x54'},
+ {'\xd4','\x65'},{'\xb0','\xbc'},{'\xb0','\xbb'},{'\xb0','\xb8'},{'\xb0','\xbd'},
+ {'\x81','\x4f'},{'\x00','\x00'},{'\xb0','\xaf'},{'\x8d','\xfe'},{'\x00','\x00'},
+ {'\xb0','\xb0'},{'\x8e','\x65'},{'\x89','\xc8'},{'\xb3','\xc8'},{'\x98','\xc4'},
+ {'\xd8','\x5e'},{'\xd8','\x57'},{'\x00','\x00'},{'\xb3','\xc5'},{'\x00','\x00'},
+ {'\xd8','\x5f'},{'\x90','\xf0'},{'\x00','\x00'},{'\x00','\x00'},{'\xd8','\x55'},
+ {'\xd8','\x58'},{'\xb3','\xc4'},{'\xd8','\x59'},{'\x00','\x00'},{'\x98','\xc5'},
+ {'\xb3','\xc7'},{'\xd8','\x5d'},{'\x00','\x00'},{'\xd8','\x53'},{'\xd8','\x52'},
+ {'\xb3','\xc9'},{'\x00','\x00'},{'\xb3','\xca'},{'\xb3','\xc6'},{'\xb3','\xcb'},
+ {'\xd8','\x51'},{'\xd8','\x5c'},{'\xd8','\x5a'},{'\xd8','\x54'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb3','\xc3'},{'\xd8','\x56'},{'\x00','\x00'},
+ {'\x8c','\xc9'},{'\xfb','\xc2'},{'\x88','\xc9'},{'\x89','\xc9'},{'\x8f','\xfb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb6','\xca'},{'\xb6','\xc4'},{'\xdc','\xb7'},
+ {'\xb6','\xcd'},{'\xdc','\xbd'},{'\xdc','\xc0'},{'\xb6','\xc6'},{'\xb6','\xc7'},
+ {'\xdc','\xba'},{'\xb6','\xc5'},{'\xdc','\xc3'},{'\xb6','\xcb'},{'\xdc','\xc4'},
+ {'\x00','\x00'},{'\xdc','\xbf'},{'\xb6','\xcc'},{'\x98','\xc6'},{'\xdc','\xb4'},
+ {'\xb6','\xc9'},{'\xdc','\xb5'},{'\x00','\x00'},{'\xdc','\xbe'},{'\xdc','\xbc'},
+ {'\x00','\x00'},{'\xdc','\xb8'},{'\xb6','\xc8'},{'\xdc','\xb6'},{'\xb6','\xce'},
+ {'\xdc','\xbb'},{'\xdc','\xc2'},{'\xdc','\xb9'},{'\xdc','\xc1'},{'\x00','\x00'},
+ {'\x94','\x4f'},{'\xb9','\xb6'},{'\xb9','\xb3'},{'\x98','\xc7'},{'\xb9','\xb4'},
+ {'\x00','\x00'},{'\xe0','\xf9'},{'\xe0','\xf1'},{'\xb9','\xb2'},{'\xb9','\xaf'},
+ {'\xe0','\xf2'},{'\x81','\x50'},{'\xfb','\xc3'},{'\xb9','\xb1'},{'\xe0','\xf5'},
+ {'\x00','\x00'},{'\xe0','\xf7'},{'\x81','\x51'},{'\x98','\xc8'},{'\xe0','\xfe'},
+ {'\x98','\xc9'},{'\x00','\x00'},{'\xe0','\xfd'},{'\xe0','\xf8'},{'\xb9','\xae'},
+ {'\xe0','\xf0'},{'\xb9','\xac'},{'\xe0','\xf3'},{'\xb9','\xb7'},{'\xe0','\xf6'},
+ {'\x00','\x00'},{'\xe0','\xfa'},{'\xb9','\xb0'},{'\xb9','\xad'},{'\xe0','\xfc'},
+ {'\xe0','\xfb'},{'\xb9','\xb5'},{'\x00','\x00'},{'\xe0','\xf4'},{'\x81','\x52'},
+ {'\xbb','\xf8'},{'\xe4','\xec'},{'\x00','\x00'},{'\xe4','\xe9'},{'\xbb','\xf9'},
+ {'\x00','\x00'},{'\xbb','\xf7'},{'\x98','\xca'},{'\xe4','\xf0'},{'\xe4','\xed'},
+ {'\xe4','\xe6'},{'\xbb','\xf6'},{'\xfb','\xc6'},{'\xbb','\xfa'},{'\xe4','\xe7'},
+ {'\xbb','\xf5'},{'\xbb','\xfd'},{'\xe4','\xea'},{'\xe4','\xeb'},{'\xbb','\xfb'},
+ {'\xbb','\xfc'},{'\xe4','\xf1'},{'\xe4','\xee'},{'\xe4','\xef'},{'\x98','\xcb'},
+ {'\xfb','\xc4'},{'\x00','\x00'},{'\xbe','\xaa'},{'\xe8','\xf8'},{'\xbe','\xa7'},
+ {'\xe8','\xf5'},{'\xbe','\xa9'},{'\xbe','\xab'},{'\x81','\x53'},{'\xe8','\xf6'},
+ {'\xbe','\xa8'},{'\x00','\x00'},{'\xe8','\xf7'},{'\x00','\x00'},{'\xe8','\xf4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\x76'},{'\xec','\xbd'},{'\xc0','\x77'},
+ {'\xec','\xbb'},{'\x00','\x00'},{'\xec','\xbc'},{'\xec','\xba'},{'\xec','\xb9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\xbe'},{'\xc0','\x75'},{'\x98','\xcc'},
+ {'\x00','\x00'},{'\xef','\xb8'},{'\xef','\xb9'},{'\x00','\x00'},{'\xe4','\xe8'},
+ {'\xef','\xb7'},{'\xc0','\x78'},{'\xc3','\x5f'},{'\xf1','\xeb'},{'\xf1','\xec'},
+ {'\x00','\x00'},{'\xc4','\xd7'},{'\xc4','\xd8'},{'\xf5','\xc1'},{'\xf5','\xc0'},
+ {'\xc5','\x6c'},{'\xc5','\x6b'},{'\xf7','\xd0'},{'\x00','\x00'},{'\xa4','\x49'},
+ {'\xa4','\x61'},{'\xa4','\xb9'},{'\x00','\x00'},{'\xa4','\xb8'},{'\xa5','\x53'},
+ {'\xa5','\x52'},{'\xa5','\xfc'},{'\xa5','\xfb'},{'\xa5','\xfd'},{'\xa5','\xfa'},
+ {'\x81','\x54'},{'\xa7','\x4a'},{'\xa7','\x49'},{'\xa7','\x4b'},{'\x95','\xfc'},
+ {'\x00','\x00'},{'\x92','\xd1'},{'\x81','\x55'},{'\xa8','\xe0'},{'\x00','\x00'},
+ {'\xa8','\xdf'},{'\xa8','\xe1'},{'\x83','\x67'},{'\xab','\x5e'},{'\x00','\x00'},
+ {'\xa2','\x59'},{'\xd0','\xde'},{'\xa2','\x5a'},{'\xb0','\xc2'},{'\xa2','\x5c'},
+ {'\xa2','\x5b'},{'\xd8','\x60'},{'\x98','\xcd'},{'\xa2','\x5d'},{'\xb9','\xb8'},
+ {'\xa2','\x5e'},{'\x81','\x56'},{'\xa4','\x4a'},{'\x00','\x00'},{'\xa4','\xba'},
+ {'\xa5','\xfe'},{'\xa8','\xe2'},{'\x81','\x57'},{'\xa4','\x4b'},{'\xa4','\xbd'},
+ {'\xa4','\xbb'},{'\xa4','\xbc'},{'\x00','\x00'},{'\x8c','\xa3'},{'\xa6','\x40'},
+ {'\x00','\x00'},{'\x8b','\xd7'},{'\x89','\x55'},{'\xa7','\x4c'},{'\xa8','\xe4'},
+ {'\xa8','\xe3'},{'\xa8','\xe5'},{'\x90','\xbc'},{'\x00','\x00'},{'\x88','\xb5'},
+ {'\xad','\xdd'},{'\x8b','\xa6'},{'\x00','\x00'},{'\x00','\x00'},{'\xbe','\xac'},
+ {'\x90','\x54'},{'\xc6','\xc3'},{'\x00','\x00'},{'\x00','\x00'},{'\x81','\x58'},
+ {'\x92','\x4c'},{'\xc9','\x4e'},{'\x83','\x58'},{'\xa5','\x54'},{'\xa5','\x55'},
+ {'\x00','\x00'},{'\x95','\xe4'},{'\xa6','\x41'},{'\x00','\x00'},{'\xca','\x6a'},
+ {'\x81','\x59'},{'\xab','\x60'},{'\xab','\x5f'},{'\xd0','\xe0'},{'\xd0','\xdf'},
+ {'\xb0','\xc3'},{'\xc6','\xc4'},{'\xa4','\xbe'},{'\xc9','\x55'},{'\x87','\xc0'},
+ {'\xfb','\x41'},{'\x83','\x7e'},{'\x86','\x61'},{'\x81','\x5a'},{'\xcb','\xcd'},
+ {'\x00','\x00'},{'\xab','\x61'},{'\x00','\x00'},{'\xad','\xe0'},{'\x00','\x00'},
+ {'\xad','\xde'},{'\xad','\xdf'},{'\x81','\x5b'},{'\xfb','\x4e'},{'\x81','\x5c'},
+ {'\x81','\x5d'},{'\xbe','\xad'},{'\xc6','\xc5'},{'\xa5','\x56'},{'\x00','\x00'},
+ {'\x98','\xce'},{'\x85','\xad'},{'\xa6','\x42'},{'\xc9','\xbc'},{'\x83','\x4c'},
+ {'\x83','\x4b'},{'\x94','\xfb'},{'\x95','\xd5'},{'\xa7','\x4d'},{'\xa7','\x4e'},
+ {'\x98','\xcf'},{'\xca','\x6b'},{'\x00','\x00'},{'\x83','\xad'},{'\xcb','\xce'},
+ {'\xa8','\xe6'},{'\xcb','\xcf'},{'\x00','\x00'},{'\x84','\x60'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x95','\xf3'},{'\xd0','\xe2'},{'\xd0','\xe3'},{'\xad','\xe3'},
+ {'\x81','\x5e'},{'\xd0','\xe4'},{'\x84','\x5b'},{'\xd0','\xe1'},{'\xad','\xe4'},
+ {'\xad','\xe2'},{'\xad','\xe1'},{'\xd0','\xe5'},{'\x90','\xb6'},{'\xd4','\x68'},
+ {'\x84','\xee'},{'\x98','\xd0'},{'\xfb','\xcf'},{'\xd8','\x61'},{'\x00','\x00'},
+ {'\x81','\x5f'},{'\xdc','\xc5'},{'\xe1','\x40'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x81','\x60'},{'\xbb','\xfe'},{'\xbe','\xae'},{'\xe8','\xf9'},{'\xfb','\xd0'},
+ {'\xa4','\x4c'},{'\xa4','\x5a'},{'\x98','\xd1'},{'\x00','\x00'},{'\x87','\xa1'},
+ {'\x00','\x00'},{'\x92','\xe1'},{'\x94','\x4c'},{'\x00','\x00'},{'\x94','\x61'},
+ {'\x94','\x52'},{'\x8e','\x63'},{'\x81','\x61'},{'\x88','\xd7'},{'\x00','\x00'},
+ {'\x84','\xc5'},{'\xb0','\xc4'},{'\xb3','\xcd'},{'\x00','\x00'},{'\xb9','\xb9'},
+ {'\xfb','\xc7'},{'\xc9','\x42'},{'\xa4','\xbf'},{'\x00','\x00'},{'\xa5','\x59'},
+ {'\xa5','\x57'},{'\xa5','\x58'},{'\x89','\xdb'},{'\x81','\x62'},{'\xa8','\xe7'},
+ {'\xfb','\xd2'},{'\x8d','\xad'},{'\xa4','\x4d'},{'\xa4','\x4e'},{'\xc8','\x7d'},
+ {'\xa4','\x62'},{'\x95','\xcf'},{'\x98','\xd2'},{'\xa4','\xc0'},{'\xa4','\xc1'},
+ {'\xa4','\xc2'},{'\xc9','\xbe'},{'\xa5','\x5a'},{'\x81','\x63'},{'\xc9','\x6b'},
+ {'\x83','\xd2'},{'\xa6','\x46'},{'\x00','\x00'},{'\xc9','\xbf'},{'\xa6','\x44'},
+ {'\xa6','\x45'},{'\xc9','\xbd'},{'\x81','\x64'},{'\x81','\x65'},{'\xa6','\x47'},
+ {'\xa6','\x43'},{'\x87','\xaa'},{'\x83','\x68'},{'\x83','\xae'},{'\x84','\xc7'},
+ {'\xca','\x6c'},{'\xaa','\xec'},{'\xca','\x6d'},{'\xfb','\xc8'},{'\x81','\x66'},
+ {'\xca','\x6e'},{'\x00','\x00'},{'\xa0','\x7e'},{'\xa7','\x50'},{'\xa7','\x4f'},
+ {'\x95','\x7b'},{'\x95','\xe5'},{'\xa7','\x53'},{'\xa7','\x51'},{'\xa7','\x52'},
+ {'\x81','\x67'},{'\x00','\x00'},{'\x8d','\xba'},{'\xa8','\xed'},{'\x00','\x00'},
+ {'\xa8','\xec'},{'\xcb','\xd4'},{'\xcb','\xd1'},{'\xcb','\xd2'},{'\x98','\xd3'},
+ {'\xcb','\xd0'},{'\xa8','\xee'},{'\xa8','\xea'},{'\xa8','\xe9'},{'\x81','\x68'},
+ {'\xa8','\xeb'},{'\xa8','\xe8'},{'\x98','\xd4'},{'\x87','\xac'},{'\x00','\x00'},
+ {'\x8e','\xaf'},{'\x84','\xc6'},{'\xa8','\xef'},{'\x88','\xcc'},{'\xab','\x63'},
+ {'\xcd','\xf0'},{'\x00','\x00'},{'\xcb','\xd3'},{'\xab','\x68'},{'\x00','\x00'},
+ {'\xcd','\xf1'},{'\xab','\x64'},{'\xab','\x67'},{'\xab','\x66'},{'\xab','\x65'},
+ {'\xab','\x62'},{'\x81','\x69'},{'\x8d','\xc8'},{'\x87','\xab'},{'\xd0','\xe8'},
+ {'\x00','\x00'},{'\xad','\xe7'},{'\xd0','\xeb'},{'\xad','\xe5'},{'\xfb','\xca'},
+ {'\x00','\x00'},{'\x98','\xd5'},{'\xd0','\xe7'},{'\xad','\xe8'},{'\xad','\xe6'},
+ {'\xad','\xe9'},{'\xd0','\xe9'},{'\xd0','\xea'},{'\xfb','\xc9'},{'\xd0','\xe6'},
+ {'\xd0','\xec'},{'\x92','\xb3'},{'\x92','\xc9'},{'\x82','\x76'},{'\x00','\x00'},
+ {'\x87','\xa9'},{'\x98','\xd6'},{'\xb3','\xd1'},{'\xb0','\xc5'},{'\xd4','\x69'},
+ {'\xd4','\x6b'},{'\xd4','\x6a'},{'\xd4','\x6c'},{'\xb0','\xc6'},{'\x92','\xeb'},
+ {'\x81','\x6a'},{'\xb3','\xce'},{'\xfc','\xf5'},{'\xb3','\xcf'},{'\xb3','\xd0'},
+ {'\x00','\x00'},{'\xb6','\xd0'},{'\xdc','\xc7'},{'\x98','\xd7'},{'\xdc','\xc6'},
+ {'\xdc','\xc8'},{'\xdc','\xc9'},{'\xb6','\xd1'},{'\x00','\x00'},{'\xb6','\xcf'},
+ {'\xe1','\x41'},{'\xe1','\x42'},{'\xb9','\xbb'},{'\xb9','\xba'},{'\xe3','\x5a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbc','\x40'},{'\xbc','\x41'},{'\xbc','\x42'},
+ {'\xbc','\x44'},{'\xe4','\xf2'},{'\xe4','\xf3'},{'\xbc','\x43'},{'\x00','\x00'},
+ {'\xfb','\x69'},{'\x81','\x6b'},{'\xbe','\xaf'},{'\x81','\x6c'},{'\xbe','\xb0'},
+ {'\x81','\x6d'},{'\x00','\x00'},{'\xf1','\xed'},{'\xf5','\xc3'},{'\xf5','\xc2'},
+ {'\xf7','\xd1'},{'\xfb','\xcb'},{'\xa4','\x4f'},{'\x81','\x6e'},{'\x8b','\xef'},
+ {'\x89','\x74'},{'\xa5','\x5c'},{'\xa5','\x5b'},{'\x83','\xef'},{'\x8e','\xb0'},
+ {'\xa6','\x48'},{'\x98','\xd8'},{'\x00','\x00'},{'\xc9','\xc0'},{'\x00','\x00'},
+ {'\x83','\xf0'},{'\xa7','\x55'},{'\xa7','\x56'},{'\xa7','\x54'},{'\xa7','\x57'},
+ {'\xca','\x6f'},{'\xca','\x70'},{'\x81','\x6f'},{'\x00','\x00'},{'\x89','\xca'},
+ {'\x83','\x69'},{'\x84','\xc8'},{'\x93','\xf5'},{'\x81','\x70'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x95','\xa2'},{'\x00','\x00'},{'\xa8','\xf1'},
+ {'\xcb','\xd5'},{'\x00','\x00'},{'\xa8','\xf0'},{'\x85','\xb7'},{'\xcd','\xf2'},
+ {'\xab','\x6c'},{'\xcd','\xf3'},{'\xab','\x6b'},{'\x00','\x00'},{'\x95','\x44'},
+ {'\x00','\x00'},{'\xab','\x69'},{'\x00','\x00'},{'\xab','\x6a'},{'\x00','\x00'},
+ {'\x84','\xc9'},{'\x98','\xd9'},{'\xd0','\xed'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x81','\x71'},{'\xfb','\xcc'},{'\xb0','\xc7'},{'\xd4','\x6e'},{'\x00','\x00'},
+ {'\xb0','\xca'},{'\xd4','\x6d'},{'\xb1','\xe5'},{'\xb0','\xc9'},{'\xb0','\xc8'},
+ {'\x00','\x00'},{'\xb3','\xd4'},{'\x00','\x00'},{'\xb3','\xd3'},{'\xb3','\xd2'},
+ {'\xb6','\xd2'},{'\xfb','\xcd'},{'\xfb','\xce'},{'\xb6','\xd5'},{'\xb6','\xd6'},
+ {'\xb6','\xd4'},{'\x00','\x00'},{'\xb6','\xd3'},{'\x92','\x68'},{'\x00','\x00'},
+ {'\xe1','\x43'},{'\x00','\x00'},{'\xe1','\x44'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe4','\xf5'},{'\xbc','\x45'},{'\xe4','\xf4'},{'\x92','\xa4'},
+ {'\xbe','\xb1'},{'\xec','\xbf'},{'\xc0','\x79'},{'\x00','\x00'},{'\xf1','\xee'},
+ {'\xc4','\x55'},{'\xc6','\xc6'},{'\xa4','\x63'},{'\xa4','\xc3'},{'\xc9','\x56'},
+ {'\x00','\x00'},{'\xa4','\xc4'},{'\xa4','\xc5'},{'\x81','\x72'},{'\x94','\x5e'},
+ {'\x94','\x53'},{'\x9c','\xd0'},{'\x00','\x00'},{'\xa5','\x5d'},{'\xa5','\x5e'},
+ {'\x81','\x73'},{'\xa6','\x49'},{'\xca','\x71'},{'\xcb','\xd6'},{'\xcb','\xd7'},
+ {'\x00','\x00'},{'\xab','\x6d'},{'\xd0','\xee'},{'\xb0','\xcc'},{'\xb0','\xcb'},
+ {'\xd8','\x63'},{'\xd8','\x62'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x50'},
+ {'\xa4','\xc6'},{'\xa5','\x5f'},{'\x00','\x00'},{'\xb0','\xcd'},{'\xc9','\x43'},
+ {'\x00','\x00'},{'\xc9','\x6c'},{'\xa5','\x60'},{'\x00','\x00'},{'\xc9','\xc2'},
+ {'\xa6','\x4b'},{'\xa6','\x4a'},{'\xc9','\xc1'},{'\xa7','\x58'},{'\x81','\x74'},
+ {'\x00','\x00'},{'\x8d','\xc9'},{'\x98','\xda'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xad','\xea'},{'\x00','\x00'},{'\xfb','\xd4'},{'\xd4','\x6f'},{'\x86','\xad'},
+ {'\xb6','\xd7'},{'\xe1','\x45'},{'\xb9','\xbc'},{'\xfb','\xd3'},{'\xfb','\xd5'},
+ {'\xe8','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\xf3','\xfd'},{'\xc6','\xc7'},
+ {'\xa4','\xc7'},{'\x83','\xf1'},{'\x8b','\x4b'},{'\xcb','\xd8'},{'\xcd','\xf4'},
+ {'\xb0','\xd0'},{'\xb0','\xce'},{'\xb0','\xcf'},{'\xa4','\x51'},{'\x98','\xdb'},
+ {'\xa4','\x64'},{'\xa2','\xcd'},{'\xa4','\xca'},{'\x81','\x75'},{'\xa4','\xc9'},
+ {'\xa4','\xc8'},{'\xa5','\x63'},{'\xa5','\x62'},{'\x00','\x00'},{'\xc9','\x6d'},
+ {'\xc9','\xc3'},{'\x85','\x4f'},{'\x83','\x56'},{'\x00','\x00'},{'\xa8','\xf5'},
+ {'\xa8','\xf2'},{'\xa8','\xf4'},{'\xa8','\xf3'},{'\x84','\xcb'},{'\x88','\x6f'},
+ {'\xab','\x6e'},{'\x93','\x6d'},{'\x00','\x00'},{'\xb3','\xd5'},{'\x00','\x00'},
+ {'\xa4','\x52'},{'\x98','\xdc'},{'\xa4','\xcb'},{'\x81','\x76'},{'\xa5','\x65'},
+ {'\xa5','\x64'},{'\x89','\x41'},{'\xca','\x72'},{'\x84','\xc0'},{'\x00','\x00'},
+ {'\xa8','\xf6'},{'\x83','\x60'},{'\x00','\x00'},{'\xc6','\xc8'},{'\x00','\x00'},
+ {'\x88','\x55'},{'\xc9','\x57'},{'\x95','\xf2'},{'\xa5','\x67'},{'\xa5','\x66'},
+ {'\xa6','\x4c'},{'\xa6','\x4d'},{'\xca','\x73'},{'\xa7','\x59'},{'\x83','\x6a'},
+ {'\xa7','\x5a'},{'\x00','\x00'},{'\xa8','\xf7'},{'\xa8','\xf8'},{'\xa8','\xf9'},
+ {'\x8d','\xbd'},{'\xab','\x6f'},{'\xcd','\xf5'},{'\x98','\xdd'},{'\x98','\xde'},
+ {'\xad','\xeb'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\x44'},{'\x00','\x00'},
+ {'\xa4','\xcc'},{'\x8d','\x6d'},{'\x88','\xe5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x87','\xad'},{'\xc9','\xc4'},{'\x89','\xcd'},{'\x86','\xae'},{'\x8d','\xbb'},
+ {'\xca','\x74'},{'\xca','\x75'},{'\x00','\x00'},{'\x00','\x00'},{'\xcb','\xd9'},
+ {'\x81','\x77'},{'\xcb','\xda'},{'\x84','\xda'},{'\xcd','\xf7'},{'\xcd','\xf6'},
+ {'\xcd','\xf9'},{'\xcd','\xf8'},{'\xab','\x70'},{'\x00','\x00'},{'\xd4','\x70'},
+ {'\xad','\xed'},{'\xd0','\xef'},{'\xad','\xec'},{'\x95','\xe8'},{'\x00','\x00'},
+ {'\x95','\xe9'},{'\x8f','\xb6'},{'\xd8','\x64'},{'\xb3','\xd6'},{'\x95','\x7a'},
+ {'\xd8','\x65'},{'\x87','\xc5'},{'\x84','\xdb'},{'\xfb','\xd7'},{'\xfb','\xd6'},
+ {'\xe1','\x46'},{'\xb9','\xbd'},{'\x87','\xc7'},{'\x00','\x00'},{'\x81','\x78'},
+ {'\x00','\x00'},{'\xbc','\x46'},{'\x92','\xba'},{'\xf1','\xef'},{'\x00','\x00'},
+ {'\xc6','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\x58'},{'\x00','\x00'},
+ {'\xa5','\x68'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x89','\x4f'},
+ {'\x00','\x00'},{'\x95','\x48'},{'\x83','\xf2'},{'\xb0','\xd1'},{'\x00','\x00'},
+ {'\x98','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\xa4','\x53'},{'\xa4','\x65'},
+ {'\xa4','\xce'},{'\xa4','\xcd'},{'\x8b','\x5a'},{'\xa4','\xcf'},{'\x83','\x42'},
+ {'\x00','\x00'},{'\x98','\xe0'},{'\x84','\xfa'},{'\x98','\xe1'},{'\x00','\x00'},
+ {'\xa8','\xfb'},{'\x00','\x00'},{'\xa8','\xfa'},{'\xa8','\xfc'},{'\x8d','\x40'},
+ {'\x95','\xb3'},{'\xfb','\xdb'},{'\xab','\x71'},{'\x00','\x00'},{'\x81','\x79'},
+ {'\x00','\x00'},{'\xad','\xee'},{'\x8c','\xd4'},{'\xe8','\xfb'},{'\xc2','\x4f'},
+ {'\xa4','\x66'},{'\xa5','\x6a'},{'\xa5','\x79'},{'\xa5','\x74'},{'\x00','\x00'},
+ {'\xa5','\x6f'},{'\xa5','\x6e'},{'\xa5','\x75'},{'\xa5','\x73'},{'\xa5','\x6c'},
+ {'\xa5','\x7a'},{'\xa5','\x6d'},{'\xa5','\x69'},{'\xa5','\x78'},{'\xa5','\x77'},
+ {'\xa5','\x76'},{'\xa5','\x6b'},{'\x00','\x00'},{'\xa5','\x72'},{'\x85','\xfc'},
+ {'\x86','\x41'},{'\xa5','\x71'},{'\x86','\xb1'},{'\x94','\x62'},{'\xa5','\x7b'},
+ {'\xa5','\x70'},{'\x87','\xb4'},{'\x98','\xe2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa6','\x53'},{'\x00','\x00'},{'\xa6','\x59'},{'\xa6','\x55'},{'\x00','\x00'},
+ {'\xa6','\x5b'},{'\xc9','\xc5'},{'\xa6','\x58'},{'\xa6','\x4e'},{'\xa6','\x51'},
+ {'\xa6','\x54'},{'\xa6','\x50'},{'\xa6','\x57'},{'\xa6','\x5a'},{'\xa6','\x4f'},
+ {'\xa6','\x52'},{'\xa6','\x56'},{'\xa6','\x5c'},{'\x89','\xcc'},{'\xfb','\x43'},
+ {'\x90','\xb8'},{'\xfb','\x42'},{'\x85','\xba'},{'\xca','\x7e'},{'\xca','\x7b'},
+ {'\xa0','\x55'},{'\xa7','\x67'},{'\xca','\x7c'},{'\xa7','\x5b'},{'\xa7','\x5d'},
+ {'\xa7','\x75'},{'\xa7','\x70'},{'\x96','\xb2'},{'\x00','\x00'},{'\x81','\x7a'},
+ {'\xca','\xa5'},{'\xca','\x7d'},{'\xa7','\x5f'},{'\xa7','\x61'},{'\xca','\xa4'},
+ {'\xa7','\x68'},{'\xca','\x78'},{'\xa7','\x74'},{'\xa7','\x76'},{'\xa7','\x5c'},
+ {'\xa7','\x6d'},{'\x84','\x51'},{'\xca','\x76'},{'\xa7','\x73'},{'\x96','\xb4'},
+ {'\xa7','\x64'},{'\x83','\x45'},{'\xa7','\x6e'},{'\xa7','\x6f'},{'\xca','\x77'},
+ {'\xa7','\x6c'},{'\xa7','\x6a'},{'\x00','\x00'},{'\xa7','\x6b'},{'\xa7','\x71'},
+ {'\xca','\xa1'},{'\xa7','\x5e'},{'\x00','\x00'},{'\xa7','\x72'},{'\xca','\xa3'},
+ {'\xa7','\x66'},{'\xa7','\x63'},{'\x00','\x00'},{'\xca','\x7a'},{'\xa7','\x62'},
+ {'\xca','\xa6'},{'\xa7','\x65'},{'\x92','\xbb'},{'\xa7','\x69'},{'\x96','\xa4'},
+ {'\x00','\x00'},{'\xa0','\x5a'},{'\xa7','\x60'},{'\xca','\xa2'},{'\x81','\x7b'},
+ {'\x81','\x7c'},{'\x8e','\xb2'},{'\x8c','\xca'},{'\xca','\x79'},{'\x86','\xb0'},
+ {'\x8f','\xb7'},{'\x8d','\xc2'},{'\x83','\xb0'},{'\x8d','\xbc'},{'\x00','\x00'},
+ {'\x85','\xbc'},{'\x85','\xbb'},{'\x00','\x00'},{'\x00','\x00'},{'\x82','\xaf'},
+ {'\xcb','\xeb'},{'\xcb','\xea'},{'\xa9','\x4f'},{'\xcb','\xed'},{'\xcb','\xef'},
+ {'\xcb','\xe4'},{'\xcb','\xe7'},{'\xcb','\xee'},{'\xa9','\x50'},{'\xfb','\xd9'},
+ {'\x94','\xfc'},{'\xcb','\xe1'},{'\xcb','\xe5'},{'\x98','\xe3'},{'\x00','\x00'},
+ {'\xcb','\xe9'},{'\xce','\x49'},{'\xa9','\x4b'},{'\xce','\x4d'},{'\xa8','\xfd'},
+ {'\xcb','\xe6'},{'\xa8','\xfe'},{'\xa9','\x4c'},{'\xa9','\x45'},{'\xa9','\x41'},
+ {'\x00','\x00'},{'\xcb','\xe2'},{'\xa9','\x44'},{'\xa9','\x49'},{'\xa9','\x52'},
+ {'\xcb','\xe3'},{'\xcb','\xdc'},{'\xa9','\x43'},{'\xcb','\xdd'},{'\xcb','\xdf'},
+ {'\x00','\x00'},{'\xa9','\x46'},{'\x98','\xe4'},{'\xa9','\x48'},{'\xcb','\xdb'},
+ {'\xcb','\xe0'},{'\x00','\x00'},{'\x81','\x7d'},{'\xa9','\x51'},{'\xa9','\x4d'},
+ {'\xcb','\xe8'},{'\xa9','\x53'},{'\x95','\xa3'},{'\xa9','\x4a'},{'\xcb','\xde'},
+ {'\xa9','\x47'},{'\x98','\xe5'},{'\x96','\xb6'},{'\xa9','\x42'},{'\xa9','\x40'},
+ {'\xa0','\x57'},{'\xcb','\xec'},{'\x8b','\xf0'},{'\xa9','\x4e'},{'\x89','\xcb'},
+ {'\xfb','\xda'},{'\x81','\x7e'},{'\x98','\xe6'},{'\x00','\x00'},{'\xce','\x48'},
+ {'\xcd','\xfb'},{'\xce','\x4b'},{'\x81','\xa1'},{'\x95','\x79'},{'\xcd','\xfd'},
+ {'\xab','\x78'},{'\xab','\xa8'},{'\xab','\x74'},{'\xab','\xa7'},{'\xab','\x7d'},
+ {'\xab','\xa4'},{'\xab','\x72'},{'\xcd','\xfc'},{'\xce','\x43'},{'\xab','\xa3'},
+ {'\xce','\x4f'},{'\xab','\xa5'},{'\x94','\x46'},{'\xab','\x79'},{'\x81','\xa2'},
+ {'\x00','\x00'},{'\xce','\x45'},{'\xce','\x42'},{'\xab','\x77'},{'\x98','\xe7'},
+ {'\xcd','\xfa'},{'\xab','\xa6'},{'\xce','\x4a'},{'\xab','\x7c'},{'\xce','\x4c'},
+ {'\xab','\xa9'},{'\xab','\x73'},{'\xab','\x7e'},{'\xab','\x7b'},{'\xce','\x40'},
+ {'\xab','\xa1'},{'\xce','\x46'},{'\xce','\x47'},{'\xab','\x7a'},{'\xab','\xa2'},
+ {'\xab','\x76'},{'\x00','\x00'},{'\xfb','\x4a'},{'\x96','\xcf'},{'\x8c','\xb7'},
+ {'\xab','\x75'},{'\xcd','\xfe'},{'\x81','\xa3'},{'\x83','\xf3'},{'\x8e','\xe2'},
+ {'\x8e','\xb1'},{'\x86','\xb4'},{'\x8e','\xe3'},{'\xce','\x44'},{'\x87','\xb0'},
+ {'\x94','\x63'},{'\x8e','\xe4'},{'\x96','\xb3'},{'\x00','\x00'},{'\x8f','\x4f'},
+ {'\x88','\xce'},{'\xce','\x4e'},{'\x84','\xcc'},{'\xd1','\x44'},{'\xad','\xfb'},
+ {'\xd0','\xf1'},{'\x98','\xe8'},{'\xd0','\xf6'},{'\xad','\xf4'},{'\xae','\x40'},
+ {'\xd0','\xf4'},{'\xad','\xef'},{'\xad','\xf9'},{'\xad','\xfe'},{'\xd0','\xfb'},
+ {'\x00','\x00'},{'\xad','\xfa'},{'\xad','\xfd'},{'\x98','\xe9'},{'\x00','\x00'},
+ {'\xd0','\xfe'},{'\xad','\xf5'},{'\xd0','\xf5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\x42'},{'\xd1','\x43'},{'\x00','\x00'},{'\xad','\xf7'},
+ {'\xd1','\x41'},{'\xad','\xf3'},{'\xae','\x43'},{'\x00','\x00'},{'\xd0','\xf8'},
+ {'\x00','\x00'},{'\xad','\xf1'},{'\xfb','\x5a'},{'\xd1','\x46'},{'\xd0','\xf9'},
+ {'\xd0','\xfd'},{'\xad','\xf6'},{'\xae','\x42'},{'\xd0','\xfa'},{'\xad','\xfc'},
+ {'\xd1','\x40'},{'\xd1','\x47'},{'\xd4','\xa1'},{'\x98','\xea'},{'\xd1','\x45'},
+ {'\xae','\x44'},{'\xad','\xf0'},{'\xd0','\xfc'},{'\xd0','\xf3'},{'\xfb','\x52'},
+ {'\xad','\xf8'},{'\x00','\x00'},{'\x82','\x40'},{'\xd0','\xf2'},{'\x98','\xeb'},
+ {'\x00','\x00'},{'\xd0','\xf7'},{'\x8e','\x66'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfb','\x55'},{'\x00','\x00'},{'\x87','\xae'},{'\x00','\x00'},{'\x8e','\x41'},
+ {'\x81','\xa4'},{'\x84','\xcd'},{'\x98','\xec'},{'\xd0','\xf0'},{'\xae','\x41'},
+ {'\x98','\xed'},{'\x00','\x00'},{'\xd4','\x77'},{'\x98','\xee'},{'\xb0','\xe4'},
+ {'\xd4','\xa7'},{'\xb0','\xe2'},{'\xb0','\xdf'},{'\xd4','\x7c'},{'\xb0','\xdb'},
+ {'\xd4','\xa2'},{'\xb0','\xe6'},{'\xd4','\x76'},{'\xd4','\x7b'},{'\xd4','\x7a'},
+ {'\xad','\xf2'},{'\xb0','\xe1'},{'\xd4','\xa5'},{'\x00','\x00'},{'\xd4','\xa8'},
+ {'\xd4','\x73'},{'\x00','\x00'},{'\xb3','\xe8'},{'\x81','\xa5'},{'\xd4','\xa9'},
+ {'\xb0','\xe7'},{'\x00','\x00'},{'\xb0','\xd9'},{'\xb0','\xd6'},{'\xd4','\x7e'},
+ {'\xb0','\xd3'},{'\x98','\xef'},{'\xd4','\xa6'},{'\x96','\xb1'},{'\xb0','\xda'},
+ {'\xd4','\xaa'},{'\x81','\xa6'},{'\xd4','\x74'},{'\xd4','\xa4'},{'\xb0','\xdd'},
+ {'\xd4','\x75'},{'\xd4','\x78'},{'\xd4','\x7d'},{'\x81','\xa7'},{'\x00','\x00'},
+ {'\xb0','\xde'},{'\xb0','\xdc'},{'\xb0','\xe8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb0','\xe3'},{'\x81','\xa8'},{'\xb0','\xd7'},
+ {'\xb1','\xd2'},{'\x00','\x00'},{'\xb0','\xd8'},{'\xd4','\x79'},{'\xb0','\xe5'},
+ {'\xb0','\xe0'},{'\xd4','\xa3'},{'\xb0','\xd5'},{'\x86','\xb3'},{'\x00','\x00'},
+ {'\xfb','\x5b'},{'\xb0','\xd4'},{'\xa0','\x46'},{'\x81','\xa9'},{'\x8c','\x6e'},
+ {'\x8c','\xc7'},{'\x00','\x00'},{'\x00','\x00'},{'\xa0','\x49'},{'\xa0','\x45'},
+ {'\xfb','\xdd'},{'\x00','\x00'},{'\xd4','\x71'},{'\xd4','\x72'},{'\xd8','\x6a'},
+ {'\x87','\xb3'},{'\x98','\xf0'},{'\x00','\x00'},{'\xb3','\xd7'},{'\xb3','\xda'},
+ {'\xd8','\x75'},{'\xb3','\xee'},{'\xd8','\x78'},{'\xb3','\xd8'},{'\xd8','\x71'},
+ {'\xb3','\xde'},{'\xb3','\xe4'},{'\xb5','\xbd'},{'\x00','\x00'},{'\x95','\xed'},
+ {'\xb3','\xe2'},{'\xd8','\x6e'},{'\xb3','\xef'},{'\xb3','\xdb'},{'\xb3','\xe3'},
+ {'\xd8','\x76'},{'\xdc','\xd7'},{'\xd8','\x7b'},{'\xd8','\x6f'},{'\x98','\xf1'},
+ {'\xd8','\x66'},{'\xd8','\x73'},{'\xd8','\x6d'},{'\xb3','\xe1'},{'\xd8','\x79'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb3','\xdd'},{'\xb3','\xf1'},{'\xb3','\xea'},
+ {'\x00','\x00'},{'\xb3','\xdf'},{'\xb3','\xdc'},{'\x81','\xaa'},{'\xb3','\xe7'},
+ {'\x00','\x00'},{'\xd8','\x7a'},{'\xd8','\x6c'},{'\xd8','\x72'},{'\xd8','\x74'},
+ {'\xd8','\x68'},{'\xd8','\x77'},{'\xb3','\xd9'},{'\xd8','\x67'},{'\x81','\xab'},
+ {'\xb3','\xe0'},{'\xb3','\xf0'},{'\xb3','\xec'},{'\xd8','\x69'},{'\xb3','\xe6'},
+ {'\x00','\x00'},{'\x94','\x42'},{'\xb3','\xed'},{'\xb3','\xe9'},{'\xb3','\xe5'},
+ {'\x98','\xf2'},{'\xd8','\x70'},{'\x92','\x49'},{'\x87','\xb2'},{'\x00','\x00'},
+ {'\x96','\xb5'},{'\xa0','\x4a'},{'\xb3','\xeb'},{'\xfb','\x4c'},{'\x86','\xb2'},
+ {'\x8f','\xd9'},{'\xdc','\xd5'},{'\xdc','\xd1'},{'\x98','\xf3'},{'\xdc','\xe0'},
+ {'\xdc','\xca'},{'\xdc','\xd3'},{'\xb6','\xe5'},{'\xb6','\xe6'},{'\xb6','\xde'},
+ {'\xdc','\xdc'},{'\xb6','\xe8'},{'\xdc','\xcf'},{'\xdc','\xce'},{'\xdc','\xcc'},
+ {'\xdc','\xde'},{'\xb6','\xdc'},{'\xdc','\xd8'},{'\xdc','\xcd'},{'\xb6','\xdf'},
+ {'\xdc','\xd6'},{'\xb6','\xda'},{'\xdc','\xd2'},{'\xdc','\xd9'},{'\xdc','\xdb'},
+ {'\x98','\xf4'},{'\x98','\xf5'},{'\xdc','\xdf'},{'\xb6','\xe3'},{'\xdc','\xcb'},
+ {'\xb6','\xdd'},{'\xdc','\xd0'},{'\xfb','\x56'},{'\xb6','\xd8'},{'\x00','\x00'},
+ {'\xb6','\xe4'},{'\xdc','\xda'},{'\xb6','\xe0'},{'\xb6','\xe1'},{'\xb6','\xe7'},
+ {'\xb6','\xdb'},{'\xa2','\x5f'},{'\xb6','\xd9'},{'\xdc','\xd4'},{'\x96','\xc9'},
+ {'\x8c','\x6d'},{'\x81','\xac'},{'\x00','\x00'},{'\x00','\x00'},{'\xb6','\xe2'},
+ {'\xa0','\x4d'},{'\xa0','\x4b'},{'\xdc','\xdd'},{'\x88','\xcf'},{'\x00','\x00'},
+ {'\x81','\xad'},{'\xb9','\xcd'},{'\xb9','\xc8'},{'\x00','\x00'},{'\xe1','\x55'},
+ {'\xe1','\x51'},{'\x98','\xf6'},{'\xe1','\x4b'},{'\xb9','\xc2'},{'\xb9','\xbe'},
+ {'\xe1','\x54'},{'\xb9','\xbf'},{'\xe1','\x4e'},{'\xe1','\x50'},{'\x00','\x00'},
+ {'\xe1','\x53'},{'\xa0','\x4e'},{'\xb9','\xc4'},{'\x00','\x00'},{'\xb9','\xcb'},
+ {'\xb9','\xc5'},{'\x00','\x00'},{'\x00','\x00'},{'\xe1','\x49'},{'\xb9','\xc6'},
+ {'\xb9','\xc7'},{'\xe1','\x4c'},{'\xb9','\xcc'},{'\xfb','\xe1'},{'\xe1','\x4a'},
+ {'\xe1','\x4f'},{'\xb9','\xc3'},{'\xe1','\x48'},{'\xb9','\xc9'},{'\xb9','\xc1'},
+ {'\x82','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\xb9','\xc0'},{'\xe1','\x4d'},
+ {'\xe1','\x52'},{'\xa0','\x52'},{'\xb9','\xca'},{'\xfc','\xd9'},{'\x98','\xf8'},
+ {'\xa0','\x4f'},{'\x81','\xae'},{'\x8b','\xf1'},{'\xfb','\x65'},{'\x00','\x00'},
+ {'\xe1','\x47'},{'\x00','\x00'},{'\xbc','\x4d'},{'\xe5','\x47'},{'\x00','\x00'},
+ {'\xe5','\x44'},{'\xa0','\x50'},{'\xbc','\x47'},{'\xbc','\x53'},{'\xbc','\x54'},
+ {'\x8d','\x51'},{'\xbc','\x4a'},{'\xe5','\x42'},{'\xbc','\x4c'},{'\xe4','\xf9'},
+ {'\xbc','\x52'},{'\xfe','\x5d'},{'\xe5','\x46'},{'\xbc','\x49'},{'\xe5','\x48'},
+ {'\xbc','\x48'},{'\x00','\x00'},{'\xe5','\x43'},{'\xe5','\x45'},{'\xbc','\x4b'},
+ {'\xe5','\x41'},{'\xe4','\xfa'},{'\xe4','\xf7'},{'\xa0','\x51'},{'\x00','\x00'},
+ {'\xd8','\x6b'},{'\xe4','\xfd'},{'\x00','\x00'},{'\xe4','\xf6'},{'\xe4','\xfc'},
+ {'\xe4','\xfb'},{'\x00','\x00'},{'\xe4','\xf8'},{'\xfb','\xe2'},{'\xbc','\x4f'},
+ {'\xfb','\x6a'},{'\x81','\xaf'},{'\x00','\x00'},{'\x98','\xfa'},{'\xbc','\x4e'},
+ {'\xfb','\xe4'},{'\x00','\x00'},{'\x00','\x00'},{'\xbc','\x50'},{'\xe4','\xfe'},
+ {'\xbe','\xb2'},{'\xe5','\x40'},{'\x82','\x4f'},{'\x8a','\xbe'},{'\x99','\x40'},
+ {'\xe9','\x45'},{'\x00','\x00'},{'\xe8','\xfd'},{'\x99','\x55'},{'\xbe','\xbe'},
+ {'\xe9','\x42'},{'\xbe','\xb6'},{'\xbe','\xba'},{'\xe9','\x41'},{'\x00','\x00'},
+ {'\xbe','\xb9'},{'\xbe','\xb5'},{'\xbe','\xb8'},{'\xbe','\xb3'},{'\xbe','\xbd'},
+ {'\xe9','\x43'},{'\xe8','\xfe'},{'\xbe','\xbc'},{'\xe8','\xfc'},{'\xbe','\xbb'},
+ {'\xe9','\x44'},{'\xe9','\x40'},{'\xbc','\x51'},{'\x00','\x00'},{'\xbe','\xbf'},
+ {'\xe9','\x46'},{'\xbe','\xb7'},{'\xbe','\xb4'},{'\x94','\x57'},{'\x96','\xca'},
+ {'\x81','\xb0'},{'\x00','\x00'},{'\xec','\xc6'},{'\xec','\xc8'},{'\xc0','\x7b'},
+ {'\xec','\xc9'},{'\xec','\xc7'},{'\xec','\xc5'},{'\xec','\xc4'},{'\xc0','\x7d'},
+ {'\xec','\xc3'},{'\xc0','\x7e'},{'\x00','\x00'},{'\x99','\x56'},{'\x81','\xb1'},
+ {'\x99','\x57'},{'\xec','\xc1'},{'\xec','\xc2'},{'\xc0','\x7a'},{'\xc0','\xa1'},
+ {'\xc0','\x7c'},{'\x00','\x00'},{'\xa0','\x53'},{'\xec','\xc0'},{'\x81','\xb2'},
+ {'\xc2','\x50'},{'\x00','\x00'},{'\xef','\xbc'},{'\xef','\xba'},{'\xef','\xbf'},
+ {'\xef','\xbd'},{'\x00','\x00'},{'\xef','\xbb'},{'\xef','\xbe'},{'\x99','\x58'},
+ {'\xa0','\x5c'},{'\x81','\xb3'},{'\x99','\x59'},{'\x82','\x74'},{'\x8c','\x6f'},
+ {'\xa0','\x5b'},{'\xc3','\x60'},{'\xf1','\xf2'},{'\xf1','\xf3'},{'\xc4','\x56'},
+ {'\x00','\x00'},{'\xf1','\xf4'},{'\xf1','\xf0'},{'\xf1','\xf5'},{'\xf1','\xf1'},
+ {'\xc2','\x51'},{'\x81','\xb4'},{'\x00','\x00'},{'\x99','\x5a'},{'\xf3','\xfe'},
+ {'\xf4','\x41'},{'\xc4','\x59'},{'\xf4','\x40'},{'\xc4','\x58'},{'\xc4','\x57'},
+ {'\x00','\x00'},{'\x99','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x5a'},
+ {'\xf5','\xc5'},{'\xf5','\xc6'},{'\x99','\x5c'},{'\xc4','\xda'},{'\xc4','\xd9'},
+ {'\xc4','\xdb'},{'\xf5','\xc4'},{'\x00','\x00'},{'\xf6','\xd8'},{'\xf6','\xd7'},
+ {'\x00','\x00'},{'\xc5','\x6d'},{'\xc5','\x6f'},{'\xc5','\x6e'},{'\xf6','\xd9'},
+ {'\xc5','\xc8'},{'\xf8','\xa6'},{'\x94','\x64'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc5','\xf1'},{'\x00','\x00'},{'\xf8','\xa5'},{'\xf8','\xee'},{'\x00','\x00'},
+ {'\x99','\x5d'},{'\xc9','\x49'},{'\x81','\xb5'},{'\x00','\x00'},{'\xa5','\x7d'},
+ {'\xa5','\x7c'},{'\x00','\x00'},{'\xa6','\x5f'},{'\xa6','\x5e'},{'\xc9','\xc7'},
+ {'\xa6','\x5d'},{'\xc9','\xc6'},{'\x86','\xb5'},{'\x93','\x6f'},{'\xa7','\x79'},
+ {'\xca','\xa9'},{'\x00','\x00'},{'\xca','\xa8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa7','\x77'},{'\xa7','\x7a'},{'\x00','\x00'},{'\x85','\xbd'},{'\xca','\xa7'},
+ {'\x99','\x5e'},{'\xa7','\x78'},{'\x83','\x46'},{'\x92','\x43'},{'\x92','\xf6'},
+ {'\x84','\xcf'},{'\x8d','\xca'},{'\x00','\x00'},{'\xcb','\xf0'},{'\x00','\x00'},
+ {'\xcb','\xf1'},{'\xa9','\x54'},{'\x9d','\x56'},{'\x00','\x00'},{'\x83','\xf6'},
+ {'\x86','\xb6'},{'\xab','\xaa'},{'\x81','\xb6'},{'\xd1','\x48'},{'\xd1','\x49'},
+ {'\xae','\x45'},{'\xae','\x46'},{'\x00','\x00'},{'\x85','\xbe'},{'\xd4','\xac'},
+ {'\xb0','\xe9'},{'\xb0','\xeb'},{'\xd4','\xab'},{'\xb0','\xea'},{'\xd8','\x7c'},
+ {'\xb3','\xf2'},{'\x00','\x00'},{'\x92','\xb5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb6','\xe9'},{'\xb6','\xea'},{'\xdc','\xe1'},{'\x99','\x5f'},{'\xb9','\xcf'},
+ {'\x00','\x00'},{'\xb9','\xce'},{'\x00','\x00'},{'\xe5','\x49'},{'\xe9','\x48'},
+ {'\xe9','\x47'},{'\x99','\x60'},{'\xf9','\x6b'},{'\xa4','\x67'},{'\xc9','\x59'},
+ {'\x00','\x00'},{'\xc9','\x6e'},{'\xc9','\x6f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x94','\x65'},{'\x92','\x42'},{'\xa6','\x62'},{'\xa6','\x66'},{'\xc9','\xc9'},
+ {'\x00','\x00'},{'\xa6','\x64'},{'\xa6','\x63'},{'\xc9','\xc8'},{'\xa6','\x65'},
+ {'\xa6','\x61'},{'\x00','\x00'},{'\x99','\x61'},{'\xa6','\x60'},{'\xc9','\xca'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x94','\x66'},{'\x94','\x67'},{'\x8a','\xbf'},
+ {'\x84','\xd1'},{'\xa7','\xa6'},{'\x00','\x00'},{'\x99','\x62'},{'\xa7','\xa3'},
+ {'\x99','\x63'},{'\xa7','\x7d'},{'\xca','\xaa'},{'\x95','\xb5'},{'\x99','\x64'},
+ {'\x00','\x00'},{'\xca','\xab'},{'\xfb','\xe7'},{'\xa7','\xa1'},{'\x00','\x00'},
+ {'\xca','\xad'},{'\xa7','\x7b'},{'\xca','\xae'},{'\xca','\xac'},{'\xa7','\x7e'},
+ {'\xa7','\xa2'},{'\xa7','\xa5'},{'\xa7','\xa4'},{'\xa7','\x7c'},{'\xca','\xaf'},
+ {'\x00','\x00'},{'\xfe','\x6f'},{'\x00','\x00'},{'\x00','\x00'},{'\x85','\xc0'},
+ {'\x00','\x00'},{'\x81','\xb7'},{'\x83','\xf7'},{'\x88','\xd1'},{'\x8b','\x6f'},
+ {'\x8d','\x52'},{'\x85','\xc1'},{'\x87','\xb6'},{'\x87','\xb7'},{'\xa9','\x59'},
+ {'\xcb','\xfe'},{'\x00','\x00'},{'\xa9','\x5b'},{'\x81','\xb8'},{'\xa9','\x5a'},
+ {'\xfb','\xe9'},{'\xcc','\x40'},{'\xa9','\x58'},{'\xa9','\x57'},{'\xcb','\xf5'},
+ {'\x00','\x00'},{'\xcb','\xf4'},{'\x00','\x00'},{'\xcb','\xf2'},{'\xcb','\xf7'},
+ {'\xcb','\xf6'},{'\xcb','\xf3'},{'\xcb','\xfc'},{'\xcb','\xfd'},{'\xcb','\xfa'},
+ {'\xcb','\xf8'},{'\xa9','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\xfb','\xe8'},
+ {'\xcb','\xfb'},{'\xa9','\x5c'},{'\xcc','\x41'},{'\x99','\x66'},{'\x81','\xb9'},
+ {'\xcb','\xf9'},{'\x00','\x00'},{'\xab','\xab'},{'\xa9','\x55'},{'\x8b','\x6e'},
+ {'\x81','\xba'},{'\x8f','\xb8'},{'\x00','\x00'},{'\x94','\x68'},{'\x81','\xbb'},
+ {'\x99','\x67'},{'\xab','\xac'},{'\xce','\x54'},{'\x99','\x68'},{'\x00','\x00'},
+ {'\xce','\x5a'},{'\x99','\x69'},{'\x00','\x00'},{'\x8a','\xc0'},{'\xab','\xb2'},
+ {'\xce','\x58'},{'\xce','\x5e'},{'\x00','\x00'},{'\xce','\x55'},{'\xce','\x59'},
+ {'\xce','\x5b'},{'\xce','\x5d'},{'\xce','\x57'},{'\x99','\x6a'},{'\xce','\x56'},
+ {'\xce','\x51'},{'\xce','\x52'},{'\xab','\xad'},{'\x81','\xbc'},{'\xab','\xaf'},
+ {'\xab','\xae'},{'\xce','\x53'},{'\xce','\x5c'},{'\x88','\xd0'},{'\x8d','\xb6'},
+ {'\x00','\x00'},{'\x83','\xf8'},{'\x94','\x6a'},{'\x86','\xb8'},{'\x81','\xbd'},
+ {'\x8d','\xcb'},{'\xab','\xb1'},{'\x00','\x00'},{'\x94','\x6b'},{'\x00','\x00'},
+ {'\x8e','\x42'},{'\x94','\x69'},{'\x81','\xbe'},{'\xce','\x50'},{'\xd1','\x53'},
+ {'\x00','\x00'},{'\xd1','\x52'},{'\xd1','\x57'},{'\xd1','\x4e'},{'\x99','\x6b'},
+ {'\xd1','\x51'},{'\xd1','\x50'},{'\x99','\x6c'},{'\xd1','\x54'},{'\x81','\xbf'},
+ {'\xd1','\x58'},{'\xae','\x47'},{'\xae','\x4a'},{'\x99','\x6d'},{'\x00','\x00'},
+ {'\xd1','\x4f'},{'\xd1','\x55'},{'\x81','\xc0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xae','\x49'},{'\xd1','\x4a'},{'\x00','\x00'},{'\xab','\xb0'},{'\xd4','\xba'},
+ {'\xd1','\x56'},{'\x00','\x00'},{'\xd1','\x4d'},{'\x81','\xc1'},{'\xae','\x48'},
+ {'\xd1','\x4c'},{'\x94','\x6c'},{'\xfe','\x49'},{'\x85','\xc2'},{'\x89','\xce'},
+ {'\x84','\xd3'},{'\x00','\x00'},{'\xd4','\xb1'},{'\xfb','\xec'},{'\x99','\x6e'},
+ {'\xb0','\xec'},{'\xb0','\xf0'},{'\xd4','\xc1'},{'\xd4','\xaf'},{'\xd4','\xbd'},
+ {'\xb0','\xf1'},{'\xd4','\xbf'},{'\xfb','\xeb'},{'\xd4','\xc5'},{'\x00','\x00'},
+ {'\xd4','\xc9'},{'\x00','\x00'},{'\x00','\x00'},{'\xd4','\xc0'},{'\xd4','\xb4'},
+ {'\xd4','\xbc'},{'\x81','\xc2'},{'\xd4','\xca'},{'\xd4','\xc8'},{'\xd4','\xbe'},
+ {'\xd4','\xb9'},{'\xd4','\xb2'},{'\xd8','\xa6'},{'\xd4','\xb0'},{'\xb0','\xf5'},
+ {'\xd4','\xb7'},{'\xb0','\xf6'},{'\xb0','\xf2'},{'\xd4','\xad'},{'\xd4','\xc3'},
+ {'\xd4','\xb5'},{'\x99','\x6f'},{'\x00','\x00'},{'\xd4','\xb3'},{'\xd4','\xc6'},
+ {'\xb0','\xf3'},{'\x95','\x4a'},{'\xd4','\xcc'},{'\xb0','\xed'},{'\xb0','\xef'},
+ {'\xd4','\xbb'},{'\xd4','\xb6'},{'\xae','\x4b'},{'\xb0','\xee'},{'\xd4','\xb8'},
+ {'\xd4','\xc7'},{'\xd4','\xcb'},{'\xd4','\xc2'},{'\x00','\x00'},{'\xd4','\xc4'},
+ {'\x86','\xb9'},{'\x99','\x70'},{'\x00','\x00'},{'\xd4','\xae'},{'\x87','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xd8','\xa1'},{'\x00','\x00'},
+ {'\xd8','\xaa'},{'\xd8','\xa9'},{'\xb3','\xfa'},{'\xd8','\xa2'},{'\x00','\x00'},
+ {'\xb3','\xfb'},{'\xb3','\xf9'},{'\x99','\x71'},{'\xd8','\xa4'},{'\xb3','\xf6'},
+ {'\xd8','\xa8'},{'\xfb','\xef'},{'\xd8','\xa3'},{'\xd8','\xa5'},{'\xd8','\x7d'},
+ {'\xb3','\xf4'},{'\x00','\x00'},{'\xd8','\xb2'},{'\xd8','\xb1'},{'\xd8','\xae'},
+ {'\xb3','\xf3'},{'\xb3','\xf7'},{'\xb3','\xf8'},{'\xd1','\x4b'},{'\xd8','\xab'},
+ {'\xb3','\xf5'},{'\xb0','\xf4'},{'\xd8','\xad'},{'\xd8','\x7e'},{'\xd8','\xb0'},
+ {'\xd8','\xaf'},{'\xfb','\xea'},{'\xd8','\xb3'},{'\x00','\x00'},{'\xdc','\xef'},
+ {'\x00','\x00'},{'\xd8','\xac'},{'\x94','\x59'},{'\x93','\xe9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x81','\xc3'},{'\x00','\x00'},{'\x00','\x00'},{'\x99','\x72'},
+ {'\xd8','\xa7'},{'\xdc','\xe7'},{'\xb6','\xf4'},{'\xb6','\xf7'},{'\xb6','\xf2'},
+ {'\xdc','\xe6'},{'\xdc','\xea'},{'\xdc','\xe5'},{'\x00','\x00'},{'\xb6','\xec'},
+ {'\xb6','\xf6'},{'\xdc','\xe2'},{'\xb6','\xf0'},{'\xdc','\xe9'},{'\x00','\x00'},
+ {'\xb6','\xee'},{'\xb6','\xed'},{'\xdc','\xec'},{'\xb6','\xef'},{'\xdc','\xee'},
+ {'\x99','\x73'},{'\xdc','\xeb'},{'\xb6','\xeb'},{'\x99','\x74'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb6','\xf5'},{'\xdc','\xf0'},{'\xdc','\xe4'},{'\xdc','\xed'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xdc','\xe3'},{'\x95','\xcd'},{'\x00','\x00'},
+ {'\xb6','\xf1'},{'\x81','\xc4'},{'\xb6','\xf3'},{'\x00','\x00'},{'\xdc','\xe8'},
+ {'\x94','\x6d'},{'\xdc','\xf1'},{'\x95','\x62'},{'\x99','\x75'},{'\xe1','\x5d'},
+ {'\xb9','\xd0'},{'\xe1','\x63'},{'\x00','\x00'},{'\x00','\x00'},{'\xb9','\xd5'},
+ {'\xe1','\x5f'},{'\xe1','\x66'},{'\xe1','\x57'},{'\xb9','\xd7'},{'\xb9','\xd1'},
+ {'\xe1','\x5c'},{'\xbc','\x55'},{'\xe1','\x5b'},{'\xe1','\x64'},{'\xb9','\xd2'},
+ {'\x00','\x00'},{'\xb9','\xd6'},{'\xe1','\x5a'},{'\xe1','\x60'},{'\xe1','\x65'},
+ {'\xe1','\x56'},{'\xb9','\xd4'},{'\xe1','\x5e'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe1','\x62'},{'\xe1','\x68'},{'\xe1','\x58'},{'\xe1','\x61'},{'\x81','\xc5'},
+ {'\xb9','\xd3'},{'\xe1','\x67'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\x5e'},
+ {'\xe1','\x59'},{'\x89','\xf5'},{'\x81','\xc6'},{'\x00','\x00'},{'\xbc','\x59'},
+ {'\xe5','\x4b'},{'\xbc','\x57'},{'\xbc','\x56'},{'\xe5','\x4d'},{'\xe5','\x52'},
+ {'\x00','\x00'},{'\xe5','\x4e'},{'\x00','\x00'},{'\xe5','\x51'},{'\xbc','\x5c'},
+ {'\x99','\x76'},{'\xbe','\xa5'},{'\xbc','\x5b'},{'\x99','\x77'},{'\xe5','\x4a'},
+ {'\xe5','\x50'},{'\x00','\x00'},{'\xbc','\x5a'},{'\xe5','\x4f'},{'\x99','\x78'},
+ {'\xe5','\x4c'},{'\x81','\xc7'},{'\xbc','\x58'},{'\x00','\x00'},{'\x99','\x79'},
+ {'\x99','\x7a'},{'\x00','\x00'},{'\x81','\xc8'},{'\x94','\x6e'},{'\xe9','\x4d'},
+ {'\xf9','\xd9'},{'\xe9','\x4f'},{'\xe9','\x4a'},{'\xbe','\xc1'},{'\xe9','\x4c'},
+ {'\x00','\x00'},{'\xbe','\xc0'},{'\xe9','\x4e'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xbe','\xc3'},{'\xe9','\x50'},{'\xbe','\xc2'},{'\xe9','\x49'},{'\xe9','\x4b'},
+ {'\x92','\x5c'},{'\x99','\x7b'},{'\x92','\xee'},{'\x00','\x00'},{'\xc0','\xa5'},
+ {'\xec','\xcc'},{'\x99','\x7c'},{'\xc0','\xa4'},{'\xec','\xcd'},{'\xc0','\xa3'},
+ {'\xec','\xcb'},{'\xc0','\xa2'},{'\xec','\xca'},{'\x94','\x6f'},{'\xc2','\x53'},
+ {'\xc2','\x52'},{'\xf1','\xf6'},{'\xf1','\xf8'},{'\xfb','\xf0'},{'\xf1','\xf7'},
+ {'\xc3','\x61'},{'\xc3','\x62'},{'\x99','\x7d'},{'\x00','\x00'},{'\xc3','\x63'},
+ {'\xf4','\x42'},{'\xc4','\x5b'},{'\x81','\xc9'},{'\x00','\x00'},{'\xf7','\xd3'},
+ {'\xf7','\xd2'},{'\xc5','\xf2'},{'\x00','\x00'},{'\xa4','\x68'},{'\xa4','\xd0'},
+ {'\x00','\x00'},{'\x83','\x47'},{'\xa7','\xa7'},{'\x8a','\x52'},{'\x92','\x45'},
+ {'\x93','\xb3'},{'\x84','\xea'},{'\xce','\x5f'},{'\x00','\x00'},{'\x84','\xd4'},
+ {'\x82','\x41'},{'\x00','\x00'},{'\xb3','\xfc'},{'\xb3','\xfd'},{'\x81','\xca'},
+ {'\xdc','\xf2'},{'\xb9','\xd8'},{'\xe1','\x69'},{'\xe5','\x53'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x81','\xcb'},{'\xc9','\x5a'},{'\x84','\x7a'},{'\x99','\x7e'},
+ {'\xca','\xb0'},{'\x84','\xc2'},{'\x00','\x00'},{'\x93','\xc4'},{'\xc6','\xca'},
+ {'\x81','\xcc'},{'\xcc','\x42'},{'\xce','\x60'},{'\xd1','\x59'},{'\xae','\x4c'},
+ {'\x81','\xcd'},{'\x99','\xa1'},{'\xf1','\xf9'},{'\x00','\x00'},{'\xc4','\xdc'},
+ {'\xa4','\x69'},{'\xa5','\x7e'},{'\xc9','\x70'},{'\x81','\xce'},{'\xa6','\x67'},
+ {'\xa6','\x68'},{'\x81','\xcf'},{'\xa9','\x5d'},{'\x9d','\x58'},{'\x00','\x00'},
+ {'\x83','\xfa'},{'\xb0','\xf7'},{'\x00','\x00'},{'\xb9','\xda'},{'\x00','\x00'},
+ {'\xb9','\xdb'},{'\xb9','\xd9'},{'\x00','\x00'},{'\xa4','\x6a'},{'\x00','\x00'},
+ {'\xa4','\xd1'},{'\xa4','\xd3'},{'\xa4','\xd2'},{'\xc9','\x5b'},{'\xa4','\xd4'},
+ {'\xa5','\xa1'},{'\xc9','\x71'},{'\x00','\x00'},{'\xa5','\xa2'},{'\x82','\xb5'},
+ {'\x00','\x00'},{'\x89','\xb3'},{'\x00','\x00'},{'\x00','\x00'},{'\xa6','\x69'},
+ {'\xa6','\x6a'},{'\x83','\x48'},{'\x86','\xbc'},{'\x00','\x00'},{'\xc9','\xcb'},
+ {'\x00','\x00'},{'\xa7','\xa8'},{'\x00','\x00'},{'\xca','\xb1'},{'\x86','\xbd'},
+ {'\x83','\x6b'},{'\x00','\x00'},{'\xa9','\x61'},{'\xcc','\x43'},{'\x00','\x00'},
+ {'\xa9','\x5f'},{'\xa9','\x60'},{'\xa9','\x5e'},{'\xd1','\x5a'},{'\x88','\xd2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xab','\xb6'},{'\xab','\xb5'},{'\xab','\xb7'},
+ {'\xab','\xb4'},{'\x00','\x00'},{'\xce','\x61'},{'\xa9','\x62'},{'\xab','\xb3'},
+ {'\x87','\xf2'},{'\xae','\x4d'},{'\xae','\x4e'},{'\x00','\x00'},{'\xae','\x4f'},
+ {'\x82','\xb6'},{'\xd4','\xcd'},{'\x82','\xb7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\xfe'},{'\xd8','\xb4'},{'\xb0','\xf8'},{'\x82','\xb8'},{'\x00','\x00'},
+ {'\x85','\xc4'},{'\x00','\x00'},{'\xb6','\xf8'},{'\x92','\xe6'},{'\xb9','\xdd'},
+ {'\xb9','\xdc'},{'\xe1','\x6a'},{'\x82','\xb9'},{'\xbc','\x5d'},{'\xbe','\xc4'},
+ {'\x00','\x00'},{'\xef','\xc0'},{'\xf6','\xda'},{'\xf7','\xd4'},{'\xa4','\x6b'},
+ {'\xa5','\xa3'},{'\xfe','\x66'},{'\xa5','\xa4'},{'\xc9','\xd1'},{'\xa6','\x6c'},
+ {'\xa6','\x6f'},{'\x00','\x00'},{'\xc9','\xcf'},{'\xc9','\xcd'},{'\xa6','\x6e'},
+ {'\xc9','\xd0'},{'\xc9','\xd2'},{'\xc9','\xcc'},{'\xa6','\x71'},{'\xa6','\x70'},
+ {'\xa6','\x6d'},{'\xa6','\x6b'},{'\xc9','\xce'},{'\x83','\x49'},{'\x83','\xfc'},
+ {'\x85','\xc5'},{'\x99','\xa2'},{'\xa7','\xb3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xa7','\xb0'},{'\xca','\xb6'},{'\xca','\xb9'},{'\xca','\xb8'},{'\x00','\x00'},
+ {'\xa7','\xaa'},{'\xa7','\xb2'},{'\x99','\xa3'},{'\x00','\x00'},{'\xa7','\xaf'},
+ {'\xca','\xb5'},{'\xca','\xb3'},{'\xa7','\xae'},{'\x99','\xa4'},{'\x82','\xba'},
+ {'\x00','\x00'},{'\xa7','\xa9'},{'\xa7','\xac'},{'\x99','\xa5'},{'\xca','\xb4'},
+ {'\xca','\xbb'},{'\xca','\xb7'},{'\xa7','\xad'},{'\xa7','\xb1'},{'\xa7','\xb4'},
+ {'\xca','\xb2'},{'\xca','\xba'},{'\xa7','\xab'},{'\x87','\xbb'},{'\x86','\xbe'},
+ {'\x8d','\xdb'},{'\x95','\xa5'},{'\x00','\x00'},{'\xa9','\x67'},{'\xa9','\x6f'},
+ {'\x99','\xa6'},{'\xcc','\x4f'},{'\xcc','\x48'},{'\xa9','\x70'},{'\xcc','\x53'},
+ {'\xcc','\x44'},{'\xcc','\x4b'},{'\xfb','\xf1'},{'\x99','\xa7'},{'\xa9','\x66'},
+ {'\xcc','\x45'},{'\xa9','\x64'},{'\xcc','\x4c'},{'\xcc','\x50'},{'\xa9','\x63'},
+ {'\x9b','\x40'},{'\xcc','\x51'},{'\xcc','\x4a'},{'\x00','\x00'},{'\xcc','\x4d'},
+ {'\x99','\xa8'},{'\xa9','\x72'},{'\xa9','\x69'},{'\xcc','\x54'},{'\xcc','\x52'},
+ {'\x93','\xfc'},{'\xa9','\x6e'},{'\xa9','\x6c'},{'\xcc','\x49'},{'\xa9','\x6b'},
+ {'\xcc','\x47'},{'\xcc','\x46'},{'\xa9','\x6a'},{'\xa9','\x68'},{'\xa9','\x71'},
+ {'\xa9','\x6d'},{'\xa9','\x65'},{'\x00','\x00'},{'\xcc','\x4e'},{'\x82','\xbb'},
+ {'\xab','\xb9'},{'\xfb','\xf2'},{'\xab','\xc0'},{'\xce','\x6f'},{'\xab','\xb8'},
+ {'\xce','\x67'},{'\xce','\x63'},{'\x00','\x00'},{'\xce','\x73'},{'\xce','\x62'},
+ {'\x00','\x00'},{'\xab','\xbb'},{'\xce','\x6c'},{'\xab','\xbe'},{'\xab','\xc1'},
+ {'\x00','\x00'},{'\xab','\xbc'},{'\xce','\x70'},{'\xab','\xbf'},{'\x82','\xbc'},
+ {'\xae','\x56'},{'\xce','\x76'},{'\xce','\x64'},{'\x99','\xa9'},{'\x99','\xaa'},
+ {'\xce','\x66'},{'\xce','\x6d'},{'\xce','\x71'},{'\xce','\x75'},{'\xce','\x72'},
+ {'\xce','\x6b'},{'\xce','\x6e'},{'\x99','\xab'},{'\x95','\xc0'},{'\xce','\x68'},
+ {'\xab','\xc3'},{'\xce','\x6a'},{'\xce','\x69'},{'\xce','\x74'},{'\xab','\xba'},
+ {'\xce','\x65'},{'\xab','\xc2'},{'\x99','\xac'},{'\xab','\xbd'},{'\x83','\xfb'},
+ {'\x8d','\xcc'},{'\x87','\xbd'},{'\x87','\xbc'},{'\x90','\x55'},{'\xae','\x5c'},
+ {'\xd1','\x62'},{'\x99','\xad'},{'\xae','\x5b'},{'\x99','\xae'},{'\x00','\x00'},
+ {'\xd1','\x60'},{'\x00','\x00'},{'\xae','\x50'},{'\x99','\xaf'},{'\xae','\x55'},
+ {'\x00','\x00'},{'\xd1','\x5f'},{'\xd1','\x5c'},{'\xd1','\x61'},{'\xae','\x51'},
+ {'\xd1','\x5b'},{'\x82','\xbd'},{'\xae','\x54'},{'\xae','\x52'},{'\x00','\x00'},
+ {'\xd1','\x63'},{'\xae','\x53'},{'\xae','\x57'},{'\x99','\xb0'},{'\x00','\x00'},
+ {'\xae','\x58'},{'\x99','\xb1'},{'\xae','\x5a'},{'\x00','\x00'},{'\x99','\xb2'},
+ {'\x00','\x00'},{'\xae','\x59'},{'\x99','\xb3'},{'\x99','\xb4'},{'\x99','\xb5'},
+ {'\xd1','\x5d'},{'\xd1','\x5e'},{'\x92','\xbc'},{'\x00','\x00'},{'\x83','\xb1'},
+ {'\x84','\xd5'},{'\xd1','\x64'},{'\x87','\xb9'},{'\xd4','\xd4'},{'\xb0','\xf9'},
+ {'\xd8','\xc2'},{'\xd4','\xd3'},{'\xd4','\xe6'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb1','\x40'},{'\x99','\xb6'},{'\xd4','\xe4'},{'\x00','\x00'},{'\xb0','\xfe'},
+ {'\xb0','\xfa'},{'\xd4','\xed'},{'\xd4','\xdd'},{'\xd4','\xe0'},{'\x99','\xb7'},
+ {'\xb1','\x43'},{'\xd4','\xea'},{'\xd4','\xe2'},{'\xb0','\xfb'},{'\xb1','\x44'},
+ {'\x00','\x00'},{'\xd4','\xe7'},{'\xd4','\xe5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd4','\xd6'},{'\xd4','\xeb'},{'\xd4','\xdf'},{'\xd4','\xda'},{'\x99','\xb8'},
+ {'\xd4','\xd0'},{'\xd4','\xec'},{'\xd4','\xdc'},{'\xd4','\xcf'},{'\x99','\xb9'},
+ {'\xb1','\x42'},{'\xd4','\xe1'},{'\xd4','\xee'},{'\xd4','\xde'},{'\xd4','\xd2'},
+ {'\xd4','\xd7'},{'\xd4','\xce'},{'\x99','\xba'},{'\xb1','\x41'},{'\x95','\x63'},
+ {'\xd4','\xdb'},{'\xd4','\xd8'},{'\xb0','\xfc'},{'\xd4','\xd1'},{'\x99','\xbb'},
+ {'\xd4','\xe9'},{'\xb0','\xfd'},{'\x99','\xbc'},{'\xd4','\xd9'},{'\xd4','\xd5'},
+ {'\x99','\xbd'},{'\x00','\x00'},{'\xd4','\xe8'},{'\x99','\xbe'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x89','\xcf'},{'\x87','\xba'},{'\x8a','\xc1'},{'\xb4','\x40'},
+ {'\xd8','\xbb'},{'\x99','\xbf'},{'\xd8','\xb8'},{'\xd8','\xc9'},{'\xd8','\xbd'},
+ {'\xd8','\xca'},{'\x99','\xc0'},{'\xb4','\x42'},{'\x00','\x00'},{'\x99','\xc1'},
+ {'\x99','\xc2'},{'\xd8','\xc6'},{'\xd8','\xc3'},{'\x00','\x00'},{'\x99','\xc3'},
+ {'\x00','\x00'},{'\x99','\xc4'},{'\x00','\x00'},{'\xd8','\xc4'},{'\xd8','\xc7'},
+ {'\xd8','\xcb'},{'\x00','\x00'},{'\xd4','\xe3'},{'\xd8','\xcd'},{'\xdd','\x47'},
+ {'\x99','\xc5'},{'\xb4','\x43'},{'\xd8','\xce'},{'\xd8','\xb6'},{'\xd8','\xc0'},
+ {'\xfe','\x78'},{'\xd8','\xc5'},{'\x00','\x00'},{'\x99','\xc6'},{'\xb4','\x41'},
+ {'\xb4','\x44'},{'\xd8','\xcc'},{'\xd8','\xcf'},{'\xd8','\xba'},{'\xd8','\xb7'},
+ {'\x99','\xc7'},{'\x99','\xc8'},{'\xd8','\xb9'},{'\x00','\x00'},{'\x9c','\x70'},
+ {'\xd8','\xbe'},{'\xd8','\xbc'},{'\xb4','\x45'},{'\x00','\x00'},{'\xd8','\xc8'},
+ {'\x82','\xbe'},{'\x99','\xc9'},{'\xd8','\xbf'},{'\x00','\x00'},{'\xd8','\xc1'},
+ {'\xd8','\xb5'},{'\xdc','\xfa'},{'\xdc','\xf8'},{'\xb7','\x42'},{'\xb7','\x40'},
+ {'\xdd','\x43'},{'\xdc','\xf9'},{'\xdd','\x44'},{'\xdd','\x40'},{'\xdc','\xf7'},
+ {'\xdd','\x46'},{'\xdc','\xf6'},{'\xdc','\xfd'},{'\xb6','\xfe'},{'\xb6','\xfd'},
+ {'\xb6','\xfc'},{'\xdc','\xfb'},{'\xdd','\x41'},{'\xb6','\xf9'},{'\xb7','\x41'},
+ {'\x99','\xca'},{'\xdc','\xf4'},{'\x00','\x00'},{'\xdc','\xfe'},{'\xdc','\xf3'},
+ {'\xdc','\xfc'},{'\xb6','\xfa'},{'\xdd','\x42'},{'\xdc','\xf5'},{'\xb6','\xfb'},
+ {'\xdd','\x45'},{'\x99','\xcb'},{'\x99','\xcc'},{'\x82','\xbf'},{'\x9d','\x67'},
+ {'\x8e','\xe5'},{'\x99','\xcd'},{'\x89','\xd0'},{'\xe1','\x6e'},{'\xb9','\xe2'},
+ {'\xb9','\xe1'},{'\xb9','\xe3'},{'\xe1','\x7a'},{'\xe1','\x70'},{'\xe1','\x76'},
+ {'\xe1','\x6b'},{'\xe1','\x79'},{'\xe1','\x78'},{'\xe1','\x7c'},{'\xe1','\x75'},
+ {'\xb9','\xde'},{'\xe1','\x74'},{'\xb9','\xe4'},{'\x99','\xce'},{'\xe1','\x6d'},
+ {'\xb9','\xdf'},{'\x00','\x00'},{'\xe1','\x7b'},{'\xb9','\xe0'},{'\xe1','\x6f'},
+ {'\xe1','\x72'},{'\xe1','\x77'},{'\xe1','\x71'},{'\xe1','\x6c'},{'\x00','\x00'},
+ {'\x99','\xcf'},{'\x82','\xc0'},{'\xfb','\x67'},{'\xe1','\x73'},{'\xe5','\x55'},
+ {'\xbc','\x61'},{'\xe5','\x58'},{'\xe5','\x57'},{'\xe5','\x5a'},{'\xe5','\x5c'},
+ {'\xf9','\xdc'},{'\xbc','\x5f'},{'\x00','\x00'},{'\xe5','\x56'},{'\x99','\xd0'},
+ {'\xe5','\x54'},{'\x00','\x00'},{'\xe5','\x5d'},{'\xe5','\x5b'},{'\xe5','\x59'},
+ {'\x00','\x00'},{'\xe5','\x5f'},{'\x00','\x00'},{'\xe5','\x5e'},{'\xbc','\x63'},
+ {'\xbc','\x5e'},{'\x00','\x00'},{'\xbc','\x60'},{'\xbc','\x62'},{'\x99','\xd1'},
+ {'\x00','\x00'},{'\xe5','\x60'},{'\xe9','\x57'},{'\x99','\xd2'},{'\x00','\x00'},
+ {'\xe9','\x56'},{'\xe9','\x55'},{'\x99','\xd3'},{'\xe9','\x58'},{'\xe9','\x51'},
+ {'\x00','\x00'},{'\xe9','\x52'},{'\xe9','\x5a'},{'\xe9','\x53'},{'\x00','\x00'},
+ {'\xbe','\xc5'},{'\xe9','\x5c'},{'\x99','\xd4'},{'\xe9','\x5b'},{'\xe9','\x54'},
+ {'\x92','\xef'},{'\xec','\xd1'},{'\xc0','\xa8'},{'\xec','\xcf'},{'\xec','\xd4'},
+ {'\xec','\xd3'},{'\xe9','\x59'},{'\x00','\x00'},{'\xc0','\xa7'},{'\x99','\xd5'},
+ {'\xec','\xd2'},{'\xec','\xce'},{'\xec','\xd6'},{'\xec','\xd5'},{'\xc0','\xa6'},
+ {'\x00','\x00'},{'\xec','\xd0'},{'\x00','\x00'},{'\xbe','\xc6'},{'\x00','\x00'},
+ {'\x82','\xc1'},{'\x89','\xd1'},{'\xc2','\x54'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xef','\xc1'},{'\xf1','\xfa'},{'\xf1','\xfb'},{'\xf1','\xfc'},
+ {'\xc4','\x5c'},{'\x99','\xd6'},{'\x00','\x00'},{'\xc4','\x5d'},{'\x99','\xd7'},
+ {'\xf4','\x43'},{'\x99','\xd8'},{'\xf5','\xc8'},{'\xf5','\xc7'},{'\x00','\x00'},
+ {'\x99','\xd9'},{'\xf6','\xdb'},{'\xf6','\xdc'},{'\xf7','\xd5'},{'\xf8','\xa7'},
+ {'\x99','\xda'},{'\xa4','\x6c'},{'\xa4','\x6d'},{'\x00','\x00'},{'\xa4','\x6e'},
+ {'\xa4','\xd5'},{'\xa5','\xa5'},{'\xc9','\xd3'},{'\xa6','\x72'},{'\xa6','\x73'},
+ {'\x83','\xb2'},{'\xa7','\xb7'},{'\xa7','\xb8'},{'\xa7','\xb6'},{'\xa7','\xb5'},
+ {'\x00','\x00'},{'\xa9','\x73'},{'\x00','\x00'},{'\x00','\x00'},{'\xcc','\x55'},
+ {'\xa9','\x75'},{'\xa9','\x74'},{'\xcc','\x56'},{'\x88','\xd4'},{'\x00','\x00'},
+ {'\x99','\xdb'},{'\xab','\xc4'},{'\x8c','\xcb'},{'\xae','\x5d'},{'\xd1','\x65'},
+ {'\xa0','\x41'},{'\xd4','\xf0'},{'\x00','\x00'},{'\xb1','\x45'},{'\xb4','\x47'},
+ {'\xd4','\xef'},{'\xb4','\x46'},{'\x99','\xdc'},{'\xb9','\xe5'},{'\x99','\xdd'},
+ {'\xe1','\x7d'},{'\xbe','\xc7'},{'\x00','\x00'},{'\xc0','\xa9'},{'\xec','\xd7'},
+ {'\x99','\xde'},{'\xc4','\x5e'},{'\x00','\x00'},{'\xc5','\x70'},{'\xc6','\xcb'},
+ {'\xc9','\x72'},{'\x99','\xdf'},{'\xa5','\xa6'},{'\xc9','\x73'},{'\xa6','\x76'},
+ {'\x00','\x00'},{'\xa6','\x74'},{'\xa6','\x75'},{'\xa6','\x77'},{'\x00','\x00'},
+ {'\xa7','\xba'},{'\xa7','\xb9'},{'\x93','\xfd'},{'\xca','\xbc'},{'\xa7','\xbb'},
+ {'\x99','\xe0'},{'\x00','\x00'},{'\xca','\xbd'},{'\xcc','\x57'},{'\x00','\x00'},
+ {'\xcc','\x58'},{'\x9a','\x40'},{'\xa9','\x76'},{'\xa9','\x78'},{'\xa9','\x7a'},
+ {'\xa9','\x77'},{'\xa9','\x7b'},{'\xa9','\x79'},{'\x8b','\xf3'},{'\x86','\xbf'},
+ {'\x92','\xd4'},{'\x8b','\x70'},{'\x87','\xbf'},{'\xab','\xc8'},{'\xab','\xc5'},
+ {'\xab','\xc7'},{'\xab','\xc9'},{'\xab','\xc6'},{'\xd1','\x66'},{'\xce','\x77'},
+ {'\x00','\x00'},{'\x88','\xd6'},{'\x90','\xb3'},{'\xd1','\x68'},{'\xd1','\x67'},
+ {'\xae','\x63'},{'\x00','\x00'},{'\xae','\x5f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xae','\x60'},{'\xae','\x62'},{'\xae','\x64'},{'\xae','\x61'},{'\x9d','\x68'},
+ {'\xae','\x66'},{'\xae','\x65'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x87','\xbe'},{'\x87','\x59'},{'\xb1','\x4a'},{'\xd4','\xf2'},{'\xd4','\xf1'},
+ {'\xb1','\x49'},{'\xfc','\x43'},{'\xb1','\x48'},{'\xb1','\x47'},{'\xb1','\x4b'},
+ {'\xb1','\x46'},{'\x00','\x00'},{'\x82','\xc2'},{'\xd8','\xd5'},{'\xd8','\xd2'},
+ {'\xb4','\x49'},{'\xd8','\xd1'},{'\xd8','\xd6'},{'\x00','\x00'},{'\xb4','\x4b'},
+ {'\xd8','\xd4'},{'\xb4','\x48'},{'\xb4','\x4a'},{'\xd8','\xd3'},{'\x9a','\x55'},
+ {'\xdd','\x48'},{'\x9a','\x56'},{'\xdd','\x49'},{'\xdd','\x4a'},{'\x00','\x00'},
+ {'\x92','\x69'},{'\x00','\x00'},{'\x86','\xc0'},{'\xb9','\xe6'},{'\xb9','\xee'},
+ {'\xe1','\x7e'},{'\xb9','\xe8'},{'\xb9','\xec'},{'\xe1','\xa1'},{'\xb9','\xed'},
+ {'\xb9','\xe9'},{'\xb9','\xea'},{'\xb9','\xe7'},{'\xb9','\xeb'},{'\xbc','\x66'},
+ {'\xd8','\xd0'},{'\xbc','\x67'},{'\xbc','\x65'},{'\x00','\x00'},{'\xbc','\x64'},
+ {'\xe9','\x5d'},{'\xbe','\xc8'},{'\xec','\xd8'},{'\xec','\xd9'},{'\x82','\xc3'},
+ {'\x00','\x00'},{'\xc3','\x64'},{'\xc4','\x5f'},{'\x00','\x00'},{'\xa4','\x6f'},
+ {'\x86','\xc1'},{'\xa6','\x78'},{'\x84','\xd6'},{'\x88','\xd5'},{'\x00','\x00'},
+ {'\x93','\x66'},{'\x86','\xba'},{'\x00','\x00'},{'\xab','\xca'},{'\x93','\x47'},
+ {'\xd1','\x69'},{'\xae','\x67'},{'\x95','\x5b'},{'\x92','\xe2'},{'\xb1','\x4e'},
+ {'\xb1','\x4d'},{'\xb1','\x4c'},{'\xb4','\x4c'},{'\xb4','\x4d'},{'\xd8','\xd7'},
+ {'\xb9','\xef'},{'\xbe','\xc9'},{'\xa4','\x70'},{'\xc9','\x5c'},{'\xa4','\xd6'},
+ {'\xc9','\x74'},{'\x82','\xc4'},{'\x86','\xe0'},{'\xc9','\xd4'},{'\xa6','\x79'},
+ {'\x00','\x00'},{'\x86','\xb7'},{'\x00','\x00'},{'\xa9','\x7c'},{'\x00','\x00'},
+ {'\x82','\xc5'},{'\x86','\xaf'},{'\x82','\xc6'},{'\xdd','\x4b'},{'\xfb','\xf3'},
+ {'\x00','\x00'},{'\xa4','\x71'},{'\x9a','\x57'},{'\xa4','\xd7'},{'\xc9','\xd5'},
+ {'\x00','\x00'},{'\x84','\xd0'},{'\xca','\xbe'},{'\x00','\x00'},{'\xca','\xbf'},
+ {'\x00','\x00'},{'\xa7','\xbc'},{'\x82','\x59'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd8','\xd8'},{'\xb4','\x4e'},{'\x00','\x00'},{'\xdd','\x4c'},{'\x89','\xd2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xaa'},{'\xa4','\x72'},{'\xa4','\xa8'},
+ {'\xa4','\xd8'},{'\xc9','\x75'},{'\xa5','\xa7'},{'\x86','\xe9'},{'\xa7','\xc0'},
+ {'\xa7','\xbf'},{'\xa7','\xbd'},{'\xa7','\xbe'},{'\x87','\xc1'},{'\x00','\x00'},
+ {'\xcc','\x59'},{'\xa9','\x7e'},{'\xa9','\xa1'},{'\xcc','\x5a'},{'\xa9','\x7d'},
+ {'\x84','\x40'},{'\x83','\x57'},{'\xab','\xce'},{'\xce','\x78'},{'\xab','\xcd'},
+ {'\xab','\xcb'},{'\xab','\xcc'},{'\xae','\x6a'},{'\xae','\x68'},{'\x00','\x00'},
+ {'\x82','\xc7'},{'\xd1','\x6b'},{'\xae','\x69'},{'\xd1','\x6a'},{'\x00','\x00'},
+ {'\xae','\x5e'},{'\xd4','\xf3'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\x50'},
+ {'\xb1','\x51'},{'\x8c','\x70'},{'\x00','\x00'},{'\xb1','\x4f'},{'\x86','\xc2'},
+ {'\xb9','\xf0'},{'\xe1','\xa2'},{'\xbc','\x68'},{'\xbc','\x69'},{'\x89','\xd3'},
+ {'\xe5','\x61'},{'\xc0','\xab'},{'\xef','\xc2'},{'\xef','\xc3'},{'\x00','\x00'},
+ {'\xc4','\xdd'},{'\xf8','\xa8'},{'\xc9','\x4b'},{'\xa4','\xd9'},{'\x00','\x00'},
+ {'\xa4','\x73'},{'\x00','\x00'},{'\xc9','\x77'},{'\xc9','\x76'},{'\x00','\x00'},
+ {'\x94','\x70'},{'\x00','\x00'},{'\x9d','\x64'},{'\xa6','\x7a'},{'\xc9','\xd7'},
+ {'\xc9','\xd8'},{'\xc9','\xd6'},{'\x00','\x00'},{'\xc9','\xd9'},{'\x89','\xd4'},
+ {'\x00','\x00'},{'\x85','\xd7'},{'\x83','\xdb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9a','\x58'},{'\xca','\xc7'},{'\x00','\x00'},{'\xca','\xc2'},{'\xca','\xc4'},
+ {'\xca','\xc6'},{'\xca','\xc3'},{'\xa7','\xc4'},{'\xca','\xc0'},{'\x00','\x00'},
+ {'\xca','\xc1'},{'\xa7','\xc1'},{'\xa7','\xc2'},{'\xca','\xc5'},{'\xca','\xc8'},
+ {'\xa7','\xc3'},{'\xca','\xc9'},{'\x86','\xc4'},{'\x84','\x42'},{'\x83','\xb5'},
+ {'\x82','\xc8'},{'\x84','\xd7'},{'\x83','\xb4'},{'\x82','\xc9'},{'\xcc','\x68'},
+ {'\x9a','\x59'},{'\xcc','\x62'},{'\xcc','\x5d'},{'\xa9','\xa3'},{'\xcc','\x65'},
+ {'\xcc','\x63'},{'\xcc','\x5c'},{'\xcc','\x69'},{'\xcc','\x6c'},{'\xcc','\x67'},
+ {'\xcc','\x60'},{'\xa9','\xa5'},{'\xcc','\x66'},{'\xa9','\xa6'},{'\xcc','\x61'},
+ {'\xcc','\x64'},{'\xcc','\x5b'},{'\xcc','\x5f'},{'\xcc','\x6b'},{'\xa9','\xa7'},
+ {'\x00','\x00'},{'\xa9','\xa8'},{'\x00','\x00'},{'\xcc','\x5e'},{'\xcc','\x6a'},
+ {'\xa9','\xa2'},{'\xa9','\xa4'},{'\x00','\x00'},{'\x82','\xca'},{'\x82','\xcb'},
+ {'\x94','\x71'},{'\x8d','\xcd'},{'\x94','\x73'},{'\x8f','\xfc'},{'\x00','\x00'},
+ {'\x82','\xcc'},{'\x9a','\x5a'},{'\x00','\x00'},{'\x8e','\xe6'},{'\x94','\x72'},
+ {'\xce','\xab'},{'\xce','\xa4'},{'\xce','\xaa'},{'\xce','\xa3'},{'\xce','\xa5'},
+ {'\xce','\x7d'},{'\xce','\x7b'},{'\x00','\x00'},{'\xce','\xac'},{'\xce','\xa9'},
+ {'\xce','\x79'},{'\xfb','\xf5'},{'\xab','\xd0'},{'\xce','\xa7'},{'\xce','\xa8'},
+ {'\x9d','\x71'},{'\xce','\xa6'},{'\xce','\x7c'},{'\xce','\x7a'},{'\xab','\xcf'},
+ {'\xce','\xa2'},{'\xce','\x7e'},{'\x00','\x00'},{'\x00','\x00'},{'\xce','\xa1'},
+ {'\xce','\xad'},{'\x94','\x50'},{'\x83','\xb3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8e','\xb4'},{'\x84','\x41'},{'\x8c','\xcd'},{'\x00','\x00'},{'\xae','\x6f'},
+ {'\xfb','\xf6'},{'\xae','\x6e'},{'\x00','\x00'},{'\xd1','\x6c'},{'\xae','\x6b'},
+ {'\xd1','\x6e'},{'\x95','\x5d'},{'\xae','\x70'},{'\xd1','\x6f'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xae','\x73'},{'\x82','\xcd'},{'\xae','\x71'},{'\xd1','\x70'},
+ {'\xce','\xae'},{'\xd1','\x72'},{'\x82','\xce'},{'\xae','\x6d'},{'\x9d','\x69'},
+ {'\xae','\x6c'},{'\x00','\x00'},{'\xd1','\x6d'},{'\xd1','\x71'},{'\xae','\x72'},
+ {'\x8e','\xb3'},{'\x8d','\xce'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\x53'},
+ {'\xb1','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xd4','\xf5'},
+ {'\xd4','\xf9'},{'\xd4','\xfb'},{'\xb1','\x54'},{'\xd4','\xfe'},{'\x9a','\x5b'},
+ {'\xb1','\x58'},{'\xd5','\x41'},{'\x00','\x00'},{'\xb1','\x5a'},{'\x82','\xcf'},
+ {'\xb1','\x56'},{'\xb1','\x5e'},{'\x82','\xd0'},{'\xb1','\x5b'},{'\xd4','\xf7'},
+ {'\xb1','\x55'},{'\x00','\x00'},{'\xd4','\xf6'},{'\xd4','\xf4'},{'\xd5','\x43'},
+ {'\xd4','\xf8'},{'\x00','\x00'},{'\xb1','\x57'},{'\xd5','\x42'},{'\xb1','\x5c'},
+ {'\xd4','\xfd'},{'\xd4','\xfc'},{'\xb1','\x5d'},{'\xd4','\xfa'},{'\xb1','\x59'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9a','\x5c'},{'\x86','\xc3'},{'\xd5','\x44'},
+ {'\x9a','\x5d'},{'\xd5','\x40'},{'\xd8','\xe7'},{'\xd8','\xee'},{'\xd8','\xe3'},
+ {'\xb4','\x51'},{'\xd8','\xdf'},{'\xd8','\xef'},{'\xd8','\xd9'},{'\xd8','\xec'},
+ {'\xd8','\xea'},{'\xd8','\xe4'},{'\x00','\x00'},{'\xd8','\xed'},{'\xd8','\xe6'},
+ {'\x82','\xd1'},{'\xd8','\xde'},{'\xd8','\xf0'},{'\xd8','\xdc'},{'\xd8','\xe9'},
+ {'\xd8','\xda'},{'\x00','\x00'},{'\xd8','\xf1'},{'\xfb','\xf7'},{'\xb4','\x52'},
+ {'\x9a','\x5e'},{'\xd8','\xeb'},{'\xdd','\x4f'},{'\xd8','\xdd'},{'\xb4','\x4f'},
+ {'\x00','\x00'},{'\xd8','\xe1'},{'\x00','\x00'},{'\xb4','\x50'},{'\xd8','\xe0'},
+ {'\xd8','\xe5'},{'\x82','\xd2'},{'\x00','\x00'},{'\xd8','\xe2'},{'\x9a','\x5f'},
+ {'\x95','\x65'},{'\x89','\xd5'},{'\xd8','\xe8'},{'\x00','\x00'},{'\x8d','\xdc'},
+ {'\x82','\xd3'},{'\x8e','\x67'},{'\xdd','\x53'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xdd','\x56'},{'\xdd','\x4e'},{'\x00','\x00'},{'\xdd','\x50'},
+ {'\x00','\x00'},{'\xdd','\x55'},{'\xdd','\x54'},{'\xb7','\x43'},{'\x00','\x00'},
+ {'\xd8','\xdb'},{'\xdd','\x52'},{'\x82','\xd4'},{'\x00','\x00'},{'\xb7','\x44'},
+ {'\x9a','\x60'},{'\xdd','\x4d'},{'\xdd','\x51'},{'\x82','\xd5'},{'\x82','\xd6'},
+ {'\xfe','\x7e'},{'\x94','\x74'},{'\xe1','\xa9'},{'\x9d','\x7a'},{'\xe1','\xb0'},
+ {'\xe1','\xa7'},{'\x9a','\x61'},{'\xe1','\xae'},{'\xe1','\xa5'},{'\xe1','\xad'},
+ {'\xe1','\xb1'},{'\xe1','\xa4'},{'\xe1','\xa8'},{'\xe1','\xa3'},{'\x00','\x00'},
+ {'\xb9','\xf1'},{'\x9a','\x62'},{'\xe1','\xa6'},{'\xb9','\xf2'},{'\xe1','\xac'},
+ {'\xe1','\xab'},{'\xe1','\xaa'},{'\x93','\xfe'},{'\x82','\xd7'},{'\xe1','\xaf'},
+ {'\xfb','\xf8'},{'\x00','\x00'},{'\x82','\xd8'},{'\x00','\x00'},{'\xe5','\x65'},
+ {'\xe5','\x67'},{'\xbc','\x6b'},{'\xe5','\x68'},{'\x00','\x00'},{'\xe5','\x63'},
+ {'\x00','\x00'},{'\xe5','\x62'},{'\xe5','\x6c'},{'\x00','\x00'},{'\xe5','\x6a'},
+ {'\xbc','\x6a'},{'\xe5','\x6d'},{'\xe5','\x64'},{'\xe5','\x69'},{'\xe5','\x6b'},
+ {'\xe5','\x66'},{'\x00','\x00'},{'\x9a','\x63'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe9','\x61'},{'\xe9','\x66'},{'\xe9','\x60'},{'\xe9','\x65'},{'\x9a','\x64'},
+ {'\xe9','\x5e'},{'\xe9','\x68'},{'\xe9','\x64'},{'\xe9','\x69'},{'\xe9','\x63'},
+ {'\xe9','\x5f'},{'\xe9','\x67'},{'\x00','\x00'},{'\xe9','\x6a'},{'\xe9','\x62'},
+ {'\x9a','\x65'},{'\xec','\xda'},{'\xc0','\xaf'},{'\x82','\xd9'},{'\xc0','\xad'},
+ {'\x00','\x00'},{'\xc0','\xac'},{'\xc0','\xae'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xef','\xc4'},{'\x9a','\x66'},{'\xf1','\x72'},{'\xf1','\xfd'},{'\x00','\x00'},
+ {'\x8c','\xcc'},{'\xf4','\x44'},{'\xf4','\x45'},{'\x00','\x00'},{'\xc4','\x60'},
+ {'\x00','\x00'},{'\xf5','\xc9'},{'\x82','\x53'},{'\xc4','\xde'},{'\x00','\x00'},
+ {'\xf5','\xca'},{'\x82','\xda'},{'\xf6','\xde'},{'\xc5','\x72'},{'\x82','\xdb'},
+ {'\xc5','\x71'},{'\xf6','\xdd'},{'\xc5','\xc9'},{'\x9a','\x67'},{'\xf7','\xd6'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xcc'},{'\x00','\x00'},{'\xa4','\x74'},
+ {'\xa6','\x7b'},{'\xc9','\xda'},{'\xca','\xca'},{'\xa8','\xb5'},{'\xb1','\x5f'},
+ {'\x93','\x57'},{'\x00','\x00'},{'\xa4','\x75'},{'\xa5','\xaa'},{'\xa5','\xa9'},
+ {'\xa5','\xa8'},{'\x88','\xb2'},{'\x00','\x00'},{'\xa7','\xc5'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xae','\x74'},{'\x8e','\x43'},{'\xdd','\x57'},{'\xa4','\x76'},
+ {'\xa4','\x77'},{'\xa4','\x78'},{'\xa4','\xda'},{'\xfb','\xfa'},{'\x00','\x00'},
+ {'\xab','\xd1'},{'\x00','\x00'},{'\xce','\xaf'},{'\x00','\x00'},{'\x92','\x66'},
+ {'\x00','\x00'},{'\xb4','\x53'},{'\xa4','\x79'},{'\xc9','\x5d'},{'\x00','\x00'},
+ {'\x86','\xc5'},{'\xa5','\xab'},{'\xa5','\xac'},{'\xc9','\x78'},{'\x83','\x6c'},
+ {'\xa6','\x7c'},{'\x00','\x00'},{'\x83','\xb6'},{'\x9a','\x68'},{'\xca','\xcb'},
+ {'\xfb','\xfb'},{'\xa7','\xc6'},{'\x00','\x00'},{'\xca','\xcc'},{'\x84','\xd9'},
+ {'\x84','\x44'},{'\xa9','\xae'},{'\xfb','\xfc'},{'\x00','\x00'},{'\xcc','\x6e'},
+ {'\xa9','\xac'},{'\xa9','\xab'},{'\xcc','\x6d'},{'\xa9','\xa9'},{'\xcc','\x6f'},
+ {'\xa9','\xaa'},{'\xa9','\xad'},{'\x87','\xc3'},{'\xab','\xd2'},{'\x00','\x00'},
+ {'\xab','\xd4'},{'\xce','\xb3'},{'\xce','\xb0'},{'\xce','\xb1'},{'\xce','\xb2'},
+ {'\xce','\xb4'},{'\xab','\xd3'},{'\x84','\x43'},{'\x84','\xd8'},{'\xd1','\x74'},
+ {'\xd1','\x73'},{'\x00','\x00'},{'\xae','\x76'},{'\x00','\x00'},{'\xae','\x75'},
+ {'\x89','\xd6'},{'\x93','\x67'},{'\x92','\x6f'},{'\x8f','\x50'},{'\x00','\x00'},
+ {'\xb1','\x62'},{'\xd5','\x46'},{'\x00','\x00'},{'\xb1','\x61'},{'\xb1','\x63'},
+ {'\xb1','\x60'},{'\x00','\x00'},{'\x00','\x00'},{'\x8e','\x68'},{'\x86','\xc6'},
+ {'\xb4','\x55'},{'\xd5','\x45'},{'\x00','\x00'},{'\xb4','\x56'},{'\xd8','\xf3'},
+ {'\x88','\xcb'},{'\xb4','\x57'},{'\xd8','\xf2'},{'\xb4','\x54'},{'\x00','\x00'},
+ {'\x82','\xdc'},{'\x9a','\x69'},{'\x00','\x00'},{'\xdd','\x5a'},{'\xdd','\x5c'},
+ {'\xb7','\x45'},{'\xdd','\x5b'},{'\xdd','\x59'},{'\xdd','\x58'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe1','\xb4'},{'\xb9','\xf7'},{'\xb9','\xf5'},
+ {'\x00','\x00'},{'\xb9','\xf6'},{'\xe1','\xb2'},{'\xe1','\xb3'},{'\x00','\x00'},
+ {'\xb9','\xf3'},{'\xe5','\x71'},{'\xe5','\x6f'},{'\xfb','\xfe'},{'\xbc','\x6d'},
+ {'\xe5','\x70'},{'\xbc','\x6e'},{'\xbc','\x6c'},{'\xb9','\xf4'},{'\x82','\xdd'},
+ {'\x00','\x00'},{'\xe9','\x6d'},{'\xe9','\x6b'},{'\xe9','\x6c'},{'\xe5','\x6e'},
+ {'\xec','\xdc'},{'\xc0','\xb0'},{'\xec','\xdb'},{'\xef','\xc5'},{'\xef','\xc6'},
+ {'\xe9','\x6e'},{'\xf1','\xfe'},{'\x00','\x00'},{'\xa4','\x7a'},{'\xa5','\xad'},
+ {'\xa6','\x7e'},{'\xc9','\xdb'},{'\xa6','\x7d'},{'\x00','\x00'},{'\xa9','\xaf'},
+ {'\xb7','\x46'},{'\xc6','\xcd'},{'\xa4','\xdb'},{'\xa5','\xae'},{'\xab','\xd5'},
+ {'\xb4','\x58'},{'\xc6','\xce'},{'\xc9','\x79'},{'\x93','\x75'},{'\xc9','\x7a'},
+ {'\x92','\xbe'},{'\xc9','\xdc'},{'\x00','\x00'},{'\x87','\xca'},{'\xa7','\xc8'},
+ {'\xca','\xd0'},{'\xca','\xce'},{'\xa7','\xc9'},{'\xca','\xcd'},{'\xca','\xcf'},
+ {'\xca','\xd1'},{'\x00','\x00'},{'\xa7','\xc7'},{'\x8b','\x72'},{'\x8e','\xb5'},
+ {'\x9a','\x6a'},{'\x83','\xb7'},{'\x89','\xd8'},{'\xa9','\xb3'},{'\xa9','\xb4'},
+ {'\xa9','\xb1'},{'\x00','\x00'},{'\x87','\xc6'},{'\xa9','\xb0'},{'\xce','\xb8'},
+ {'\xa9','\xb2'},{'\x00','\x00'},{'\x8b','\x71'},{'\x87','\xc4'},{'\xab','\xd6'},
+ {'\x00','\x00'},{'\xce','\xb7'},{'\xce','\xb9'},{'\xce','\xb6'},{'\xce','\xba'},
+ {'\xab','\xd7'},{'\xae','\x79'},{'\xd1','\x75'},{'\x00','\x00'},{'\xd1','\x77'},
+ {'\xae','\x77'},{'\xd1','\x78'},{'\xae','\x78'},{'\xd1','\x76'},{'\x00','\x00'},
+ {'\xce','\xb5'},{'\xd5','\x47'},{'\xd5','\x4a'},{'\xd5','\x4b'},{'\xd5','\x48'},
+ {'\xb1','\x67'},{'\xb1','\x66'},{'\xb1','\x64'},{'\xb1','\x65'},{'\xd5','\x49'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\x6b'},{'\xb1','\x68'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb4','\x5a'},{'\xb4','\x5b'},{'\x93','\xb2'},
+ {'\xb4','\x5c'},{'\xdd','\x5d'},{'\xdd','\x5f'},{'\xdd','\x61'},{'\xb7','\x48'},
+ {'\xb7','\x47'},{'\xb4','\x59'},{'\xdd','\x60'},{'\xdd','\x5e'},{'\xfe','\xa4'},
+ {'\xe1','\xb8'},{'\x82','\xde'},{'\x82','\xdf'},{'\xe1','\xb6'},{'\xe1','\xbc'},
+ {'\xb9','\xf8'},{'\xe1','\xbd'},{'\xe1','\xba'},{'\xb9','\xf9'},{'\xe1','\xb7'},
+ {'\xe1','\xb5'},{'\xe1','\xbb'},{'\xbc','\x70'},{'\xe5','\x73'},{'\xe1','\xb9'},
+ {'\xbc','\x72'},{'\xe5','\x74'},{'\xbc','\x71'},{'\xbc','\x74'},{'\xe5','\x75'},
+ {'\xbc','\x6f'},{'\xbc','\x73'},{'\x00','\x00'},{'\xe9','\x73'},{'\xe9','\x71'},
+ {'\xe9','\x70'},{'\xe9','\x72'},{'\xe9','\x6f'},{'\x82','\xe0'},{'\x00','\x00'},
+ {'\xc3','\x66'},{'\x00','\x00'},{'\xf4','\x46'},{'\xf4','\x47'},{'\x82','\xe1'},
+ {'\xf5','\xcb'},{'\xf6','\xdf'},{'\xc6','\x55'},{'\xc6','\xcf'},{'\x00','\x00'},
+ {'\xa9','\xb5'},{'\xa7','\xca'},{'\x95','\xa4'},{'\x95','\xa1'},{'\xab','\xd8'},
+ {'\x95','\xee'},{'\x95','\xfa'},{'\x00','\x00'},{'\xa4','\x7b'},{'\xa4','\xdc'},
+ {'\x85','\x7b'},{'\xa5','\xaf'},{'\xc9','\xdd'},{'\x84','\x56'},{'\xa7','\xcb'},
+ {'\xca','\xd2'},{'\x00','\x00'},{'\xce','\xbb'},{'\xab','\xd9'},{'\x82','\xe2'},
+ {'\xb9','\xfa'},{'\xa4','\x7c'},{'\x82','\xe3'},{'\x95','\xaa'},{'\x9a','\x6c'},
+ {'\xa6','\xa1'},{'\x93','\xae'},{'\x82','\xe4'},{'\xb7','\x49'},{'\xa4','\x7d'},
+ {'\xa4','\xdd'},{'\xa4','\xde'},{'\x94','\x75'},{'\xa5','\xb1'},{'\xa5','\xb0'},
+ {'\x00','\x00'},{'\xc9','\xde'},{'\xa6','\xa2'},{'\x00','\x00'},{'\xca','\xd3'},
+ {'\x00','\x00'},{'\xa7','\xcc'},{'\x84','\x45'},{'\x82','\xe5'},{'\xcc','\x71'},
+ {'\xcc','\x72'},{'\xcc','\x73'},{'\x93','\xf9'},{'\xa9','\xb6'},{'\xa9','\xb7'},
+ {'\xcc','\x70'},{'\xa9','\xb8'},{'\x8d','\xc3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xab','\xda'},{'\xce','\xbc'},{'\x8c','\xce'},{'\xd1','\x7a'},{'\xae','\x7a'},
+ {'\x00','\x00'},{'\xd1','\x79'},{'\x82','\xe6'},{'\xb1','\x69'},{'\xd5','\x4c'},
+ {'\xb1','\x6a'},{'\xd5','\x4d'},{'\x87','\xc9'},{'\x84','\x46'},{'\x9d','\x7b'},
+ {'\xb4','\x5d'},{'\x00','\x00'},{'\x93','\x71'},{'\x00','\x00'},{'\xdd','\x62'},
+ {'\x82','\xe7'},{'\x00','\x00'},{'\xe1','\xbf'},{'\xe1','\xbe'},{'\x82','\xe8'},
+ {'\xb9','\xfb'},{'\x00','\x00'},{'\xbc','\x75'},{'\xe5','\x76'},{'\xbe','\xca'},
+ {'\xe9','\x74'},{'\xc0','\xb1'},{'\xfc','\x41'},{'\xc5','\x73'},{'\xf7','\xd8'},
+ {'\xc6','\xd0'},{'\x82','\xe9'},{'\x8a','\xd0'},{'\x85','\xe5'},{'\xcc','\x74'},
+ {'\x89','\xa3'},{'\xce','\xbd'},{'\xb1','\x6b'},{'\xd8','\xf4'},{'\xb7','\x4a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x82','\xea'},{'\xc2','\x55'},{'\xc2','\x55'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\xd1'},{'\xa7','\xce'},{'\xfe','\xa8'},
+ {'\xa7','\xcd'},{'\xab','\xdb'},{'\x82','\xeb'},{'\xd1','\x7b'},{'\x00','\x00'},
+ {'\xb1','\x6d'},{'\xb3','\x43'},{'\xb1','\x6e'},{'\xb1','\x6c'},{'\xb4','\x5e'},
+ {'\x00','\x00'},{'\xe1','\xc0'},{'\xb9','\xfc'},{'\xbc','\x76'},{'\x9a','\x6d'},
+ {'\xc9','\x4c'},{'\xc9','\xdf'},{'\x00','\x00'},{'\xca','\xd5'},{'\xa7','\xcf'},
+ {'\xca','\xd4'},{'\xa7','\xd0'},{'\x00','\x00'},{'\x86','\xc7'},{'\xa9','\xbc'},
+ {'\xcc','\x77'},{'\xcc','\x76'},{'\xa9','\xbb'},{'\xa9','\xb9'},{'\xa9','\xba'},
+ {'\xcc','\x75'},{'\x82','\xec'},{'\x92','\xa6'},{'\xab','\xdd'},{'\xce','\xbe'},
+ {'\xab','\xe0'},{'\xab','\xdc'},{'\xab','\xe2'},{'\xab','\xde'},{'\xab','\xdf'},
+ {'\xab','\xe1'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xae','\x7d'},
+ {'\xae','\x7c'},{'\xae','\x7b'},{'\x92','\xdc'},{'\x00','\x00'},{'\x84','\x48'},
+ {'\xd5','\x4f'},{'\xb1','\x6f'},{'\xb1','\x72'},{'\xb1','\x70'},{'\x00','\x00'},
+ {'\xd5','\x4e'},{'\xb1','\x75'},{'\x00','\x00'},{'\xb1','\x71'},{'\xd5','\x50'},
+ {'\xb1','\x74'},{'\xb1','\x73'},{'\x00','\x00'},{'\x00','\x00'},{'\xfc','\x47'},
+ {'\xd8','\xf6'},{'\xd8','\xf5'},{'\x95','\x5a'},{'\xb4','\x61'},{'\xb4','\x5f'},
+ {'\xb4','\x60'},{'\xd8','\xf7'},{'\xb7','\x4b'},{'\xdd','\x64'},{'\xb7','\x4c'},
+ {'\xdd','\x63'},{'\x00','\x00'},{'\x9a','\x6e'},{'\xe5','\x77'},{'\x93','\xa8'},
+ {'\x93','\x76'},{'\xbc','\x78'},{'\xe1','\xc1'},{'\xbc','\x77'},{'\x00','\x00'},
+ {'\xb9','\xfd'},{'\xfc','\x48'},{'\xec','\xde'},{'\xe9','\x75'},{'\xc0','\xb2'},
+ {'\xec','\xdd'},{'\xf2','\x40'},{'\xf4','\x48'},{'\xf4','\x49'},{'\x9a','\x6f'},
+ {'\xa4','\xdf'},{'\x9c','\xf5'},{'\xa5','\xb2'},{'\x88','\xda'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc9','\x7b'},{'\x00','\x00'},{'\x00','\x00'},{'\xa7','\xd2'},
+ {'\xa7','\xd4'},{'\x00','\x00'},{'\xc9','\xe2'},{'\xca','\xd8'},{'\xca','\xd7'},
+ {'\xca','\xd6'},{'\x00','\x00'},{'\xc9','\xe1'},{'\xc9','\xe0'},{'\xa6','\xa4'},
+ {'\xa7','\xd3'},{'\xa7','\xd1'},{'\xa6','\xa3'},{'\x00','\x00'},{'\x9a','\x70'},
+ {'\x92','\x4e'},{'\xa9','\xbd'},{'\xcc','\x78'},{'\x9a','\x71'},{'\xa9','\xbe'},
+ {'\xca','\xdd'},{'\x00','\x00'},{'\xca','\xdf'},{'\xca','\xde'},{'\xcc','\x79'},
+ {'\x00','\x00'},{'\x87','\xcc'},{'\xca','\xda'},{'\x00','\x00'},{'\xa7','\xd8'},
+ {'\xa7','\xd6'},{'\x00','\x00'},{'\xca','\xd9'},{'\xca','\xdb'},{'\xca','\xe1'},
+ {'\x82','\xed'},{'\xa7','\xd5'},{'\x00','\x00'},{'\xca','\xdc'},{'\xca','\xe5'},
+ {'\xa9','\xc0'},{'\x00','\x00'},{'\xca','\xe2'},{'\xa7','\xd7'},{'\x00','\x00'},
+ {'\xca','\xe0'},{'\xca','\xe3'},{'\x00','\x00'},{'\xa9','\xbf'},{'\x85','\xc7'},
+ {'\xa9','\xc1'},{'\xca','\xe4'},{'\x86','\xc8'},{'\x87','\xcd'},{'\x87','\xd1'},
+ {'\x8e','\x6b'},{'\x84','\x4a'},{'\x85','\xc8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xcc','\xaf'},{'\xcc','\xa2'},{'\xcc','\x7e'},{'\xcc','\xae'},{'\xcc','\xa9'},
+ {'\xab','\xe7'},{'\xa9','\xc2'},{'\xcc','\xaa'},{'\xcc','\xad'},{'\xab','\xe3'},
+ {'\xcc','\xac'},{'\xa9','\xc3'},{'\xa9','\xc8'},{'\xa9','\xc6'},{'\xcc','\xa3'},
+ {'\x00','\x00'},{'\xcc','\x7c'},{'\xcc','\xa5'},{'\xa9','\xcd'},{'\xcc','\xb0'},
+ {'\xab','\xe4'},{'\xcc','\xa6'},{'\x00','\x00'},{'\xab','\xe5'},{'\xa9','\xc9'},
+ {'\xcc','\xa8'},{'\x9a','\x72'},{'\xce','\xcd'},{'\xab','\xe6'},{'\xcc','\x7b'},
+ {'\xa9','\xca'},{'\xab','\xe8'},{'\xa9','\xcb'},{'\xa9','\xc7'},{'\xa9','\xcc'},
+ {'\xcc','\xa7'},{'\xcc','\x7a'},{'\xcc','\xab'},{'\xa9','\xc4'},{'\x00','\x00'},
+ {'\x95','\xa6'},{'\xcc','\x7d'},{'\xcc','\xa4'},{'\xcc','\xa1'},{'\xa9','\xc5'},
+ {'\x00','\x00'},{'\xce','\xbf'},{'\x00','\x00'},{'\xce','\xc0'},{'\x94','\x76'},
+ {'\x8a','\x4b'},{'\x8f','\x74'},{'\x00','\x00'},{'\x00','\x00'},{'\x8e','\xe7'},
+ {'\xce','\xca'},{'\xd1','\xa1'},{'\xce','\xcb'},{'\xab','\xee'},{'\xce','\xce'},
+ {'\xce','\xc4'},{'\xab','\xed'},{'\xce','\xc6'},{'\x00','\x00'},{'\xce','\xc7'},
+ {'\x82','\xee'},{'\x8c','\xf6'},{'\xce','\xc9'},{'\xab','\xe9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xae','\xa3'},{'\x00','\x00'},{'\xf9','\xda'},{'\xce','\xc5'},
+ {'\xce','\xc1'},{'\xae','\xa4'},{'\x00','\x00'},{'\x00','\x00'},{'\xce','\xcf'},
+ {'\xae','\x7e'},{'\xd1','\x7d'},{'\xce','\xc8'},{'\x00','\x00'},{'\xd1','\x7c'},
+ {'\xce','\xc3'},{'\xce','\xcc'},{'\x82','\xef'},{'\x00','\x00'},{'\xab','\xec'},
+ {'\xae','\xa1'},{'\xab','\xf2'},{'\xae','\xa2'},{'\xce','\xd0'},{'\xd1','\x7e'},
+ {'\xab','\xeb'},{'\xae','\xa6'},{'\xab','\xf1'},{'\xab','\xf0'},{'\xab','\xef'},
+ {'\xae','\xa5'},{'\xce','\xd1'},{'\xae','\xa7'},{'\xab','\xea'},{'\x00','\x00'},
+ {'\xce','\xc2'},{'\x89','\xd9'},{'\x00','\x00'},{'\x92','\xa8'},{'\x84','\xdc'},
+ {'\xfc','\x4b'},{'\x86','\xca'},{'\x8f','\x51'},{'\x85','\xc9'},{'\x84','\xdf'},
+ {'\x84','\xe0'},{'\x8d','\xdd'},{'\x9a','\x73'},{'\xb1','\x76'},{'\xd1','\xa4'},
+ {'\xd1','\xa6'},{'\x00','\x00'},{'\xd1','\xa8'},{'\xae','\xa8'},{'\xae','\xae'},
+ {'\xd5','\x53'},{'\xd1','\xac'},{'\xd1','\xa3'},{'\xb1','\x78'},{'\xd5','\x51'},
+ {'\x82','\xf0'},{'\xae','\xad'},{'\xae','\xab'},{'\xd1','\xae'},{'\x00','\x00'},
+ {'\xd5','\x52'},{'\x00','\x00'},{'\xd1','\xa5'},{'\x00','\x00'},{'\xae','\xac'},
+ {'\xd1','\xa9'},{'\xae','\xaf'},{'\xd1','\xab'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xae','\xaa'},{'\xd1','\xaa'},{'\xd1','\xad'},{'\xd1','\xa7'},{'\xfb','\x64'},
+ {'\xae','\xa9'},{'\xb1','\x79'},{'\x00','\x00'},{'\xd1','\xa2'},{'\xb1','\x77'},
+ {'\xfc','\x4c'},{'\x00','\x00'},{'\x82','\xf1'},{'\xfe','\xa6'},{'\xb1','\x7a'},
+ {'\x93','\xaf'},{'\x92','\x41'},{'\x8e','\x69'},{'\x8b','\xf4'},{'\x8e','\x6a'},
+ {'\x00','\x00'},{'\x87','\xce'},{'\xd5','\x55'},{'\xd5','\x5e'},{'\xb4','\x64'},
+ {'\xfc','\x4d'},{'\xb1','\x7c'},{'\xb1','\xa3'},{'\xb4','\x65'},{'\xd5','\x60'},
+ {'\xb1','\xaa'},{'\xd8','\xf9'},{'\xd5','\x56'},{'\xb1','\xa2'},{'\xb1','\xa5'},
+ {'\xb1','\x7e'},{'\xd5','\x54'},{'\xd5','\x62'},{'\xd5','\x65'},{'\xd9','\x49'},
+ {'\x00','\x00'},{'\xd5','\x63'},{'\xd8','\xfd'},{'\xb1','\xa1'},{'\xb1','\xa8'},
+ {'\xb1','\xac'},{'\xd5','\x5d'},{'\xd8','\xf8'},{'\xd5','\x61'},{'\xb1','\x7b'},
+ {'\xd8','\xfa'},{'\xd5','\x64'},{'\xd8','\xfc'},{'\xd5','\x59'},{'\x00','\x00'},
+ {'\xb4','\x62'},{'\x00','\x00'},{'\xd5','\x57'},{'\xd5','\x58'},{'\xb1','\xa7'},
+ {'\x00','\x00'},{'\x9a','\x74'},{'\xb1','\xa6'},{'\xd5','\x5b'},{'\xb1','\xab'},
+ {'\xd5','\x5f'},{'\xb1','\xa4'},{'\xd5','\x5c'},{'\x82','\xf2'},{'\xb1','\xa9'},
+ {'\xb4','\x66'},{'\xb4','\x63'},{'\xd8','\xfb'},{'\x82','\xad'},{'\xd5','\x5a'},
+ {'\x00','\x00'},{'\xb1','\x7d'},{'\x8c','\x71'},{'\x86','\xcc'},{'\x8b','\x73'},
+ {'\x00','\x00'},{'\x88','\xd8'},{'\x84','\xde'},{'\x86','\xcb'},{'\x87','\xcf'},
+ {'\x86','\xc9'},{'\xb4','\x6b'},{'\xb4','\x6f'},{'\xd9','\x40'},{'\xb7','\x51'},
+ {'\xb4','\x6d'},{'\xd9','\x44'},{'\xb4','\x71'},{'\xdd','\x65'},{'\xd9','\x46'},
+ {'\xb7','\x53'},{'\xb4','\x69'},{'\xb4','\x6c'},{'\xd9','\x47'},{'\xfc','\x4e'},
+ {'\xd9','\x48'},{'\xd9','\x4e'},{'\xb4','\x73'},{'\xb7','\x54'},{'\x00','\x00'},
+ {'\xd9','\x4a'},{'\xd9','\x4f'},{'\xd9','\x43'},{'\xb7','\x5e'},{'\x9a','\x75'},
+ {'\xb7','\x55'},{'\xb4','\x72'},{'\xd9','\x41'},{'\xd9','\x50'},{'\x9a','\x76'},
+ {'\xb7','\x5d'},{'\xb4','\x70'},{'\xb7','\x4e'},{'\xd9','\x4d'},{'\x82','\xf3'},
+ {'\xb4','\x74'},{'\xd9','\x45'},{'\xd8','\xfe'},{'\xb4','\x6a'},{'\xd9','\x42'},
+ {'\x00','\x00'},{'\xd9','\x4b'},{'\x9a','\x77'},{'\xb7','\x4d'},{'\xb7','\x52'},
+ {'\xb4','\x67'},{'\xd9','\x4c'},{'\x00','\x00'},{'\xb7','\x50'},{'\x82','\xf4'},
+ {'\x82','\xf5'},{'\x9a','\x78'},{'\xb4','\x68'},{'\x87','\xd0'},{'\x00','\x00'},
+ {'\x8e','\xb6'},{'\xb7','\x5c'},{'\xe1','\xc3'},{'\xdd','\x70'},{'\x00','\x00'},
+ {'\xdd','\x68'},{'\xe1','\xc2'},{'\x00','\x00'},{'\xdd','\x6c'},{'\xdd','\x6e'},
+ {'\xfc','\x4f'},{'\x00','\x00'},{'\xdd','\x6b'},{'\x00','\x00'},{'\xb7','\x5b'},
+ {'\x00','\x00'},{'\xdd','\x6a'},{'\xb7','\x5f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe1','\xd2'},{'\x82','\xf6'},{'\x82','\xf7'},{'\xb7','\x5a'},
+ {'\xba','\x40'},{'\xdd','\x71'},{'\xe1','\xc4'},{'\xfc','\xc9'},{'\x00','\x00'},
+ {'\xb7','\x58'},{'\xdd','\x69'},{'\xdd','\x6d'},{'\xb9','\xfe'},{'\xb7','\x4f'},
+ {'\xdd','\x66'},{'\xdd','\x67'},{'\xba','\x41'},{'\xb7','\x57'},{'\xb7','\x59'},
+ {'\xb7','\x56'},{'\xdd','\x6f'},{'\x9a','\x79'},{'\x8c','\x72'},{'\xe1','\xc8'},
+ {'\xe1','\xc9'},{'\xe1','\xce'},{'\xbc','\x7d'},{'\xe1','\xd5'},{'\x00','\x00'},
+ {'\xba','\x47'},{'\xfc','\x52'},{'\xba','\x46'},{'\xe1','\xd0'},{'\xfc','\x54'},
+ {'\xbc','\x7c'},{'\xe1','\xc5'},{'\xba','\x45'},{'\x9a','\x7a'},{'\xe1','\xd4'},
+ {'\xba','\x43'},{'\xba','\x44'},{'\x95','\xad'},{'\xe1','\xd1'},{'\xe5','\xaa'},
+ {'\xbc','\x7a'},{'\xb4','\x6e'},{'\x00','\x00'},{'\xe1','\xd3'},{'\xbc','\xa3'},
+ {'\xe1','\xcb'},{'\x00','\x00'},{'\xbc','\x7b'},{'\x95','\x66'},{'\xbc','\xa2'},
+ {'\xe1','\xc6'},{'\xe1','\xca'},{'\xe1','\xc7'},{'\xe1','\xcd'},{'\xba','\x48'},
+ {'\xbc','\x79'},{'\xba','\x42'},{'\x00','\x00'},{'\xe5','\x7a'},{'\xe1','\xcf'},
+ {'\x00','\x00'},{'\xbc','\xa1'},{'\xfc','\x53'},{'\xbc','\xa4'},{'\x00','\x00'},
+ {'\xe1','\xcc'},{'\x9a','\x7b'},{'\xbc','\x7e'},{'\xe5','\x79'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x95','\xd1'},{'\x00','\x00'},{'\xe5','\x7e'},
+ {'\xbe','\xce'},{'\xe5','\x78'},{'\xe9','\xa3'},{'\xe5','\xa9'},{'\xbc','\xa8'},
+ {'\x00','\x00'},{'\xbc','\xa6'},{'\xbe','\xcc'},{'\xe5','\xa6'},{'\xe5','\xa2'},
+ {'\xbc','\xac'},{'\x9a','\x7c'},{'\xe9','\x78'},{'\x00','\x00'},{'\x82','\xf8'},
+ {'\xfe','\x74'},{'\xbc','\xaa'},{'\xe5','\xa1'},{'\xfc','\x51'},{'\xe9','\x76'},
+ {'\x00','\x00'},{'\xe5','\xa5'},{'\x00','\x00'},{'\xe5','\xa8'},{'\xe5','\x7d'},
+ {'\x00','\x00'},{'\xbc','\xab'},{'\x00','\x00'},{'\x00','\x00'},{'\xbc','\xa5'},
+ {'\xe9','\x77'},{'\xbe','\xcd'},{'\xe5','\xa7'},{'\xbc','\xa7'},{'\xbc','\xa9'},
+ {'\xe5','\xa4'},{'\xbc','\xad'},{'\xe5','\xa3'},{'\xe5','\x7c'},{'\xe5','\x7b'},
+ {'\xbe','\xcb'},{'\xe5','\xab'},{'\xe9','\x7a'},{'\xec','\xe0'},{'\xbe','\xd0'},
+ {'\x82','\xf9'},{'\xe9','\xa2'},{'\x9a','\x7d'},{'\xe9','\x7e'},{'\x00','\x00'},
+ {'\xec','\xe1'},{'\x00','\x00'},{'\xbe','\xd1'},{'\xe9','\xa1'},{'\x9a','\x7e'},
+ {'\xe9','\x7c'},{'\xc0','\xb4'},{'\xec','\xdf'},{'\x00','\x00'},{'\xe9','\x79'},
+ {'\xe9','\x7b'},{'\xc0','\xb5'},{'\xbe','\xd3'},{'\xc0','\xb3'},{'\xbe','\xd2'},
+ {'\xc0','\xb7'},{'\xe9','\x7d'},{'\xbe','\xcf'},{'\x00','\x00'},{'\x9a','\xa1'},
+ {'\x92','\x5d'},{'\x8a','\xc2'},{'\x8b','\x75'},{'\x9a','\xa2'},{'\x88','\xd9'},
+ {'\x00','\x00'},{'\xef','\xcf'},{'\x00','\x00'},{'\xef','\xc7'},{'\x00','\x00'},
+ {'\x9a','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xec','\xe7'},
+ {'\xef','\xc8'},{'\xec','\xe3'},{'\x00','\x00'},{'\xfc','\x56'},{'\xc2','\x56'},
+ {'\xec','\xe5'},{'\xec','\xe4'},{'\xc0','\xb6'},{'\xec','\xe2'},{'\xec','\xe6'},
+ {'\xef','\xd0'},{'\xef','\xcc'},{'\xef','\xce'},{'\x00','\x00'},{'\xef','\xc9'},
+ {'\xef','\xca'},{'\x00','\x00'},{'\xef','\xcd'},{'\xef','\xcb'},{'\xc3','\x67'},
+ {'\x00','\x00'},{'\x82','\xfa'},{'\xc3','\x6a'},{'\xc3','\x69'},{'\xc3','\x68'},
+ {'\xc4','\x61'},{'\xf4','\x4a'},{'\xc4','\x62'},{'\xf2','\x41'},{'\xc4','\xdf'},
+ {'\xf5','\xcc'},{'\xc4','\xe0'},{'\xc5','\x74'},{'\xc5','\xca'},{'\xf7','\xd9'},
+ {'\x00','\x00'},{'\xf7','\xda'},{'\xf7','\xdb'},{'\x00','\x00'},{'\x90','\xab'},
+ {'\xf9','\xba'},{'\xa4','\xe0'},{'\xc9','\x7c'},{'\xa5','\xb3'},{'\x8d','\xb8'},
+ {'\xa6','\xa6'},{'\xa6','\xa7'},{'\xa6','\xa5'},{'\x89','\xda'},{'\xa6','\xa8'},
+ {'\xa7','\xda'},{'\xa7','\xd9'},{'\x82','\xfb'},{'\xcc','\xb1'},{'\xa9','\xcf'},
+ {'\xa9','\xce'},{'\x8e','\x6d'},{'\x88','\xdb'},{'\xd1','\xaf'},{'\xb1','\xad'},
+ {'\xb1','\xae'},{'\x00','\x00'},{'\x82','\xfc'},{'\x82','\xfd'},{'\xb4','\x75'},
+ {'\xdd','\x72'},{'\xb7','\x60'},{'\xb7','\x61'},{'\xdd','\x74'},{'\xdd','\x76'},
+ {'\xdd','\x75'},{'\x93','\x49'},{'\xe1','\xd7'},{'\x00','\x00'},{'\xe1','\xd6'},
+ {'\xba','\x49'},{'\xe1','\xd8'},{'\x8e','\x6c'},{'\xe5','\xac'},{'\xbc','\xae'},
+ {'\x92','\x70'},{'\xbe','\xd4'},{'\x00','\x00'},{'\xc0','\xb8'},{'\xc2','\x57'},
+ {'\xc0','\xb9'},{'\x00','\x00'},{'\xa4','\xe1'},{'\x82','\xfe'},{'\x90','\xbd'},
+ {'\xfc','\x58'},{'\xca','\xe6'},{'\x93','\xec'},{'\x00','\x00'},{'\xcc','\xb2'},
+ {'\xa9','\xd1'},{'\xa9','\xd0'},{'\xa9','\xd2'},{'\xab','\xf3'},{'\xce','\xd2'},
+ {'\xce','\xd3'},{'\x00','\x00'},{'\x00','\x00'},{'\xd1','\xb0'},{'\xae','\xb0'},
+ {'\xb1','\xaf'},{'\xb4','\x76'},{'\xd9','\x51'},{'\xa4','\xe2'},{'\x9c','\xf2'},
+ {'\xa4','\x7e'},{'\xa4','\xe3'},{'\x00','\x00'},{'\xc9','\x7d'},{'\xa5','\xb7'},
+ {'\xa5','\xb6'},{'\xa5','\xb4'},{'\xa5','\xb5'},{'\x93','\xc1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa6','\xab'},{'\xc9','\xe9'},{'\xc9','\xeb'},{'\xa6','\xaa'},
+ {'\xc9','\xe3'},{'\x00','\x00'},{'\xc9','\xe4'},{'\x00','\x00'},{'\xc9','\xea'},
+ {'\xc9','\xe6'},{'\xc9','\xe8'},{'\xa6','\xa9'},{'\xc9','\xe5'},{'\xc9','\xec'},
+ {'\xc9','\xe7'},{'\x83','\xf9'},{'\xfc','\x59'},{'\x8a','\xc3'},{'\x84','\x4d'},
+ {'\x84','\x4b'},{'\x84','\xe4'},{'\xa7','\xe1'},{'\xa7','\xea'},{'\xa7','\xe8'},
+ {'\xca','\xf0'},{'\xca','\xed'},{'\xca','\xf5'},{'\xa7','\xe6'},{'\xca','\xf6'},
+ {'\x00','\x00'},{'\xa7','\xdf'},{'\xca','\xf3'},{'\x00','\x00'},{'\xa7','\xe5'},
+ {'\xca','\xef'},{'\xca','\xee'},{'\xa7','\xe3'},{'\xca','\xf4'},{'\xa7','\xe4'},
+ {'\xa9','\xd3'},{'\xa7','\xde'},{'\xca','\xf1'},{'\xfc','\x5b'},{'\xca','\xe7'},
+ {'\xa7','\xdb'},{'\xfc','\x5a'},{'\xa7','\xee'},{'\xca','\xec'},{'\xca','\xf2'},
+ {'\xa7','\xe0'},{'\xa7','\xe2'},{'\x00','\x00'},{'\xca','\xe8'},{'\x00','\x00'},
+ {'\xca','\xe9'},{'\xca','\xea'},{'\x9a','\xa4'},{'\xa7','\xed'},{'\xa7','\xe7'},
+ {'\xa7','\xec'},{'\xca','\xeb'},{'\xa7','\xeb'},{'\xa7','\xdd'},{'\xa7','\xdc'},
+ {'\xa7','\xe9'},{'\x00','\x00'},{'\x87','\xd7'},{'\x90','\xbe'},{'\x93','\xbb'},
+ {'\xfd','\x57'},{'\x93','\x6a'},{'\x8e','\x6e'},{'\x8e','\x6f'},{'\x84','\x4e'},
+ {'\x85','\xcb'},{'\x00','\x00'},{'\x8c','\xa8'},{'\x84','\xd2'},{'\xfc','\x5c'},
+ {'\x00','\x00'},{'\xa9','\xe1'},{'\xcc','\xbe'},{'\xcc','\xb7'},{'\xa9','\xdc'},
+ {'\xa9','\xef'},{'\xcc','\xb3'},{'\xcc','\xba'},{'\xcc','\xbc'},{'\xcc','\xbf'},
+ {'\xa9','\xea'},{'\x00','\x00'},{'\xcc','\xbb'},{'\xcc','\xb4'},{'\xa9','\xe8'},
+ {'\xcc','\xb8'},{'\x00','\x00'},{'\xcc','\xc0'},{'\xa9','\xd9'},{'\x00','\x00'},
+ {'\xcc','\xbd'},{'\xa9','\xe3'},{'\xa9','\xe2'},{'\xcc','\xb6'},{'\xa9','\xd7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa9','\xd8'},{'\xfb','\x46'},{'\xa9','\xd6'},
+ {'\x88','\xe3'},{'\xa9','\xee'},{'\xa9','\xe6'},{'\xa9','\xe0'},{'\xa9','\xd4'},
+ {'\xcc','\xb9'},{'\xa9','\xdf'},{'\xa9','\xd5'},{'\xa9','\xe7'},{'\xa9','\xf0'},
+ {'\xce','\xd4'},{'\xa9','\xe4'},{'\xcc','\xb5'},{'\xa9','\xda'},{'\xa9','\xdd'},
+ {'\xa9','\xde'},{'\xfc','\x5d'},{'\xa9','\xec'},{'\xa9','\xed'},{'\xa9','\xeb'},
+ {'\xa9','\xe5'},{'\xa9','\xe9'},{'\xa9','\xdb'},{'\xab','\xf4'},{'\x93','\xb1'},
+ {'\x00','\x00'},{'\x89','\xde'},{'\x92','\x75'},{'\x92','\x5e'},{'\x8b','\x76'},
+ {'\x84','\xe1'},{'\x00','\x00'},{'\x88','\xdc'},{'\x8b','\xf6'},{'\x89','\xdd'},
+ {'\x87','\xd5'},{'\x88','\xe1'},{'\x00','\x00'},{'\xce','\xda'},{'\xac','\x41'},
+ {'\xab','\xf8'},{'\xab','\xfa'},{'\xac','\x40'},{'\xce','\xe6'},{'\xab','\xfd'},
+ {'\xd1','\xb1'},{'\xae','\xb1'},{'\xac','\x43'},{'\xce','\xd7'},{'\xce','\xdf'},
+ {'\xab','\xfe'},{'\xce','\xde'},{'\xce','\xdb'},{'\xce','\xe3'},{'\xce','\xe5'},
+ {'\xab','\xf7'},{'\xab','\xfb'},{'\xac','\x42'},{'\xae','\xb3'},{'\xce','\xe0'},
+ {'\xab','\xf9'},{'\xac','\x45'},{'\xce','\xd9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xab','\xfc'},{'\xae','\xb2'},{'\xab','\xf6'},{'\x00','\x00'},
+ {'\xce','\xd6'},{'\xce','\xdd'},{'\xce','\xd5'},{'\xce','\xd8'},{'\xce','\xdc'},
+ {'\xd1','\xb2'},{'\xac','\x44'},{'\x00','\x00'},{'\xce','\xe1'},{'\xce','\xe2'},
+ {'\xce','\xe4'},{'\xab','\xf5'},{'\x00','\x00'},{'\x94','\xf4'},{'\x92','\x76'},
+ {'\x87','\xd2'},{'\x8c','\xf7'},{'\x00','\x00'},{'\x88','\xe4'},{'\x88','\xde'},
+ {'\x83','\xb9'},{'\x87','\xd6'},{'\x88','\xdd'},{'\x8e','\xb7'},{'\x84','\x4f'},
+ {'\x89','\xdc'},{'\x84','\xe2'},{'\x00','\x00'},{'\x90','\xbf'},{'\xae','\xc1'},
+ {'\xd1','\xbe'},{'\xae','\xbf'},{'\xae','\xc0'},{'\xd1','\xb4'},{'\xd1','\xc4'},
+ {'\xa0','\x5e'},{'\xae','\xb6'},{'\x00','\x00'},{'\x9a','\xa5'},{'\xd5','\x66'},
+ {'\xd1','\xc6'},{'\xd1','\xc0'},{'\xfc','\x5f'},{'\xd1','\xb7'},{'\x9a','\xa7'},
+ {'\xd1','\xc9'},{'\xd1','\xba'},{'\xae','\xbc'},{'\xd5','\x7d'},{'\xd1','\xbd'},
+ {'\xae','\xbe'},{'\xae','\xb5'},{'\x93','\x56'},{'\xd1','\xcb'},{'\xd1','\xbf'},
+ {'\xae','\xb8'},{'\xd1','\xb8'},{'\xd1','\xb5'},{'\xd1','\xb6'},{'\xae','\xb9'},
+ {'\xd1','\xc5'},{'\xd1','\xcc'},{'\xae','\xbb'},{'\xd1','\xbc'},{'\xd1','\xbb'},
+ {'\xae','\xc3'},{'\xae','\xc2'},{'\xae','\xb4'},{'\xae','\xba'},{'\xae','\xbd'},
+ {'\xd1','\xc8'},{'\x00','\x00'},{'\x00','\x00'},{'\xd1','\xc2'},{'\xae','\xb7'},
+ {'\xd1','\xb3'},{'\xd1','\xca'},{'\xd1','\xc1'},{'\xd1','\xc3'},{'\xd1','\xc7'},
+ {'\x00','\x00'},{'\x93','\x55'},{'\x00','\x00'},{'\x87','\xd4'},{'\x85','\xca'},
+ {'\x00','\x00'},{'\x88','\xe2'},{'\x84','\xe3'},{'\x85','\xcc'},{'\xfc','\x5e'},
+ {'\xd5','\x67'},{'\x00','\x00'},{'\xb1','\xb7'},{'\xb1','\xcb'},{'\xb1','\xca'},
+ {'\x00','\x00'},{'\xb1','\xbf'},{'\x95','\x59'},{'\xd5','\x79'},{'\xd5','\x75'},
+ {'\xd5','\x72'},{'\xd5','\xa6'},{'\xb1','\xba'},{'\xb1','\xb2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd5','\x77'},{'\xb4','\xa8'},{'\xb1','\xb6'},{'\xd5','\xa1'},
+ {'\x9a','\xa8'},{'\xb1','\xcc'},{'\xb1','\xc9'},{'\xd5','\x7b'},{'\xd5','\x6a'},
+ {'\x00','\x00'},{'\xfc','\x55'},{'\xb1','\xc8'},{'\xd5','\xa3'},{'\xd5','\x69'},
+ {'\xb1','\xbd'},{'\xb1','\xc1'},{'\xd5','\xa2'},{'\x00','\x00'},{'\xd5','\x73'},
+ {'\xb1','\xc2'},{'\xb1','\xbc'},{'\xd5','\x68'},{'\x9a','\xa9'},{'\xb4','\x78'},
+ {'\xd5','\xa5'},{'\xd5','\x71'},{'\xb1','\xc7'},{'\xd5','\x74'},{'\xd5','\xa4'},
+ {'\xb1','\xc6'},{'\x00','\x00'},{'\xd9','\x52'},{'\x00','\x00'},{'\xb1','\xb3'},
+ {'\xd5','\x6f'},{'\xb1','\xb8'},{'\xb1','\xc3'},{'\x00','\x00'},{'\xb1','\xbe'},
+ {'\xd5','\x78'},{'\xd5','\x6e'},{'\xd5','\x6c'},{'\xd5','\x7e'},{'\xb1','\xb0'},
+ {'\xb1','\xc4'},{'\xb1','\xb4'},{'\xb4','\x77'},{'\xd5','\x7c'},{'\xb1','\xb5'},
+ {'\x00','\x00'},{'\xb1','\xb1'},{'\xb1','\xc0'},{'\xb1','\xbb'},{'\xb1','\xb9'},
+ {'\xd5','\x70'},{'\xb1','\xc5'},{'\xd5','\x6d'},{'\xd5','\x7a'},{'\xd5','\x76'},
+ {'\xd9','\x54'},{'\xd9','\x53'},{'\x92','\xa9'},{'\x88','\xe0'},{'\x86','\xce'},
+ {'\x94','\x77'},{'\x00','\x00'},{'\x8a','\xc4'},{'\x87','\xd8'},{'\xfb','\x57'},
+ {'\x86','\xcf'},{'\x90','\xc0'},{'\x8e','\x70'},{'\xd5','\x6b'},{'\xd9','\x64'},
+ {'\x00','\x00'},{'\xb4','\x7a'},{'\x9a','\xaa'},{'\xd9','\x6a'},{'\xd9','\x59'},
+ {'\xd9','\x67'},{'\xdd','\x77'},{'\xb4','\x7d'},{'\xd9','\x6b'},{'\xd9','\x6e'},
+ {'\xb4','\x7c'},{'\xd9','\x5c'},{'\xd9','\x6d'},{'\xd9','\x6c'},{'\xb4','\x7e'},
+ {'\xd9','\x55'},{'\xb4','\x79'},{'\xb4','\xa3'},{'\xfd','\x6c'},{'\xb4','\xa1'},
+ {'\xd9','\x69'},{'\x00','\x00'},{'\xd9','\x5f'},{'\xb4','\xa5'},{'\xd9','\x70'},
+ {'\xd9','\x68'},{'\xd9','\x71'},{'\xb4','\xad'},{'\xb4','\xab'},{'\xd9','\x66'},
+ {'\xd9','\x65'},{'\x90','\xc1'},{'\xd9','\x63'},{'\xd9','\x5d'},{'\xb4','\xa4'},
+ {'\x9a','\xab'},{'\xb4','\xa2'},{'\xd1','\xb9'},{'\xd9','\x56'},{'\x9a','\xac'},
+ {'\xdd','\xb7'},{'\xd9','\x57'},{'\xb4','\x7b'},{'\xb4','\xaa'},{'\xdd','\x79'},
+ {'\x00','\x00'},{'\xb4','\xa6'},{'\xb4','\xa7'},{'\xd9','\x58'},{'\xd9','\x6f'},
+ {'\xdd','\x78'},{'\xd9','\x60'},{'\xd9','\x5b'},{'\xb4','\xa9'},{'\xd9','\x61'},
+ {'\xd9','\x5e'},{'\x00','\x00'},{'\xa0','\x5f'},{'\xb4','\xae'},{'\x90','\xc2'},
+ {'\x9a','\xad'},{'\xfb','\x5d'},{'\x8d','\x53'},{'\x9a','\xae'},{'\x87','\xd9'},
+ {'\x8b','\xf7'},{'\x89','\xdf'},{'\x86','\xcd'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8c','\xf8'},{'\xb7','\x70'},{'\x9a','\xaf'},{'\x00','\x00'},{'\xdd','\x7c'},
+ {'\xdd','\xb1'},{'\xdd','\xb6'},{'\xdd','\xaa'},{'\xb7','\x6c'},{'\xdd','\xbb'},
+ {'\xb7','\x69'},{'\xdd','\x7a'},{'\x00','\x00'},{'\xdd','\x7b'},{'\xb7','\x62'},
+ {'\xb7','\x6b'},{'\xdd','\xa4'},{'\xb7','\x6e'},{'\xb7','\x6f'},{'\xdd','\xa5'},
+ {'\x00','\x00'},{'\xdd','\xb2'},{'\xdd','\xb8'},{'\xb7','\x6a'},{'\x00','\x00'},
+ {'\xb7','\x64'},{'\xdd','\xa3'},{'\xdd','\x7d'},{'\xdd','\xba'},{'\xdd','\xa8'},
+ {'\xdd','\xa9'},{'\xdd','\x7e'},{'\xdd','\xb4'},{'\xdd','\xab'},{'\xdd','\xb5'},
+ {'\xdd','\xad'},{'\x00','\x00'},{'\xb7','\x65'},{'\xe1','\xd9'},{'\xb7','\x68'},
+ {'\xb7','\x66'},{'\xdd','\xb9'},{'\xdd','\xb0'},{'\xdd','\xac'},{'\x00','\x00'},
+ {'\x9a','\xb0'},{'\xdd','\xa1'},{'\xba','\x53'},{'\xdd','\xaf'},{'\xb7','\x6d'},
+ {'\xdd','\xa7'},{'\x9a','\xb1'},{'\xdd','\xa6'},{'\x8c','\x74'},{'\x9a','\xb2'},
+ {'\x00','\x00'},{'\xb7','\x67'},{'\xb7','\x63'},{'\xe1','\xee'},{'\xdd','\xb3'},
+ {'\xdd','\xae'},{'\x93','\x45'},{'\xdd','\xa2'},{'\x8c','\x73'},{'\x8f','\x75'},
+ {'\x8a','\xc7'},{'\x93','\xda'},{'\x8f','\x52'},{'\x00','\x00'},{'\x8c','\xcf'},
+ {'\xe1','\xe9'},{'\x00','\x00'},{'\xe1','\xda'},{'\xe1','\xe5'},{'\x00','\x00'},
+ {'\xe1','\xec'},{'\xba','\x51'},{'\xb4','\xac'},{'\xe1','\xea'},{'\xba','\x4c'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xba','\x4b'},{'\xe1','\xf1'},
+ {'\x9a','\xb3'},{'\xe1','\xdb'},{'\xe1','\xe8'},{'\xe1','\xdc'},{'\xe1','\xe7'},
+ {'\xba','\x4f'},{'\xe1','\xeb'},{'\xd9','\x62'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe1','\xf2'},{'\xe1','\xe3'},{'\xba','\x52'},{'\xe5','\xba'},
+ {'\xbc','\xaf'},{'\x00','\x00'},{'\xe1','\xf0'},{'\xe1','\xef'},{'\xba','\x54'},
+ {'\xe5','\xad'},{'\xbc','\xb0'},{'\xe5','\xae'},{'\x9a','\xb4'},{'\xe1','\xdf'},
+ {'\xe1','\xe0'},{'\xe1','\xdd'},{'\xe1','\xe2'},{'\xe1','\xde'},{'\xe1','\xf3'},
+ {'\xba','\x4e'},{'\xbc','\xb1'},{'\xba','\x50'},{'\xba','\x55'},{'\x9a','\xb5'},
+ {'\xe1','\xe1'},{'\x00','\x00'},{'\xe1','\xed'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe1','\xe6'},{'\x92','\xb0'},{'\x8f','\xda'},{'\xe5','\xb1'},{'\x00','\x00'},
+ {'\xba','\x4a'},{'\xbc','\xb4'},{'\xe9','\xaa'},{'\xe5','\xb6'},{'\xe5','\xb5'},
+ {'\xe5','\xb7'},{'\x9a','\xb6'},{'\x00','\x00'},{'\xe5','\xb4'},{'\xbc','\xb5'},
+ {'\x90','\xc3'},{'\xbc','\xbb'},{'\xbc','\xb8'},{'\x00','\x00'},{'\xbc','\xb9'},
+ {'\xe5','\xaf'},{'\xe5','\xb2'},{'\xe5','\xbc'},{'\xbc','\xc1'},{'\xbc','\xbf'},
+ {'\x00','\x00'},{'\xe5','\xb3'},{'\xd9','\x5a'},{'\xbc','\xb2'},{'\xe5','\xb9'},
+ {'\xe5','\xb0'},{'\x00','\x00'},{'\xbc','\xc2'},{'\xe5','\xb8'},{'\xba','\x4d'},
+ {'\xbc','\xb7'},{'\xe1','\xe4'},{'\x00','\x00'},{'\x00','\x00'},{'\xbc','\xba'},
+ {'\x00','\x00'},{'\xbc','\xbe'},{'\xbc','\xc0'},{'\xbc','\xbd'},{'\xbc','\xbc'},
+ {'\x9a','\xb7'},{'\xbc','\xb6'},{'\xe5','\xbb'},{'\xbc','\xb3'},{'\xbc','\xc3'},
+ {'\x9a','\xb8'},{'\x8a','\xc6'},{'\x9a','\xb9'},{'\x8a','\xc9'},{'\x8f','\x76'},
+ {'\x82','\x4d'},{'\x8f','\xfe'},{'\xbe','\xd8'},{'\xbe','\xd9'},{'\xe9','\xa9'},
+ {'\xbe','\xe2'},{'\xbe','\xdf'},{'\x90','\xc4'},{'\xbe','\xd6'},{'\xbe','\xdd'},
+ {'\xe9','\xab'},{'\xbe','\xdb'},{'\xbe','\xd5'},{'\x00','\x00'},{'\xbe','\xdc'},
+ {'\x00','\x00'},{'\xe9','\xa8'},{'\xc0','\xbb'},{'\xbe','\xd7'},{'\x00','\x00'},
+ {'\xbe','\xde'},{'\xc0','\xba'},{'\xe9','\xa7'},{'\xe9','\xa6'},{'\x00','\x00'},
+ {'\xbe','\xe0'},{'\xa0','\x5d'},{'\xbe','\xe1'},{'\x00','\x00'},{'\xe9','\xa5'},
+ {'\xe9','\xa4'},{'\xc0','\xbc'},{'\xe9','\xae'},{'\xbe','\xda'},{'\xe9','\xac'},
+ {'\x00','\x00'},{'\x9a','\xba'},{'\x8a','\xc8'},{'\x00','\x00'},{'\xc0','\xbd'},
+ {'\x90','\xc5'},{'\xc0','\xc2'},{'\xec','\xea'},{'\xec','\xec'},{'\x9a','\xbb'},
+ {'\xc0','\xbf'},{'\xfb','\xa3'},{'\xec','\xed'},{'\xec','\xe9'},{'\x95','\xc8'},
+ {'\xec','\xeb'},{'\xc0','\xc0'},{'\xc0','\xc3'},{'\x00','\x00'},{'\xec','\xe8'},
+ {'\xc0','\xbe'},{'\xc0','\xc1'},{'\xc2','\x59'},{'\xe9','\xad'},{'\xc2','\x58'},
+ {'\x00','\x00'},{'\x90','\xc6'},{'\xc2','\x5e'},{'\xef','\xd4'},{'\x00','\x00'},
+ {'\xc2','\x5c'},{'\xc2','\x5d'},{'\xef','\xd7'},{'\xef','\xd3'},{'\xc2','\x5a'},
+ {'\xef','\xd1'},{'\xc3','\x6b'},{'\xef','\xd5'},{'\x00','\x00'},{'\xef','\xd6'},
+ {'\xef','\xd2'},{'\x90','\xc7'},{'\xc2','\x5b'},{'\xf2','\x42'},{'\x00','\x00'},
+ {'\xf2','\x45'},{'\x9a','\xbc'},{'\x00','\x00'},{'\xf2','\x46'},{'\xf2','\x44'},
+ {'\xf2','\x47'},{'\xc3','\x6c'},{'\xf2','\x43'},{'\x9a','\xbd'},{'\x90','\x57'},
+ {'\xf4','\x4e'},{'\xc4','\x64'},{'\xf4','\x4d'},{'\xf4','\x4c'},{'\xf4','\x4b'},
+ {'\xc4','\x63'},{'\xc4','\x65'},{'\x00','\x00'},{'\xf5','\xcd'},{'\xc4','\xe2'},
+ {'\xc4','\xe1'},{'\xa0','\x60'},{'\x9a','\xbe'},{'\xf6','\xe1'},{'\xf6','\xe0'},
+ {'\xf6','\xe3'},{'\xc5','\xcb'},{'\xc5','\x75'},{'\xf7','\xdd'},{'\xf6','\xe2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xdc'},{'\xc5','\xcd'},{'\xc5','\xcc'},
+ {'\xc5','\xf3'},{'\xf8','\xa9'},{'\xf8','\xef'},{'\xa4','\xe4'},{'\xfe','\x5b'},
+ {'\x00','\x00'},{'\xd9','\x72'},{'\xe9','\xaf'},{'\xc6','\xd2'},{'\x90','\xc8'},
+ {'\xa6','\xac'},{'\xca','\xf7'},{'\xa7','\xf1'},{'\xa7','\xef'},{'\x00','\x00'},
+ {'\xa7','\xf0'},{'\x00','\x00'},{'\xcc','\xc1'},{'\xa9','\xf1'},{'\xac','\x46'},
+ {'\x00','\x00'},{'\xce','\xe7'},{'\x00','\x00'},{'\xce','\xe8'},{'\x00','\x00'},
+ {'\xac','\x47'},{'\xd1','\xce'},{'\x00','\x00'},{'\xae','\xc4'},{'\xae','\xc5'},
+ {'\xd1','\xcd'},{'\x00','\x00'},{'\x87','\xda'},{'\x95','\xb4'},{'\x90','\xc9'},
+ {'\xb1','\xd3'},{'\x00','\x00'},{'\xb1','\xcf'},{'\x00','\x00'},{'\xd5','\xa7'},
+ {'\xb1','\xd6'},{'\xb1','\xd5'},{'\xb1','\xce'},{'\xb1','\xd1'},{'\xb1','\xd4'},
+ {'\xb1','\xd0'},{'\x00','\x00'},{'\x89','\xe0'},{'\xd9','\x76'},{'\xb1','\xcd'},
+ {'\xb4','\xaf'},{'\x9a','\xbf'},{'\x00','\x00'},{'\x00','\x00'},{'\xb4','\xb1'},
+ {'\xb4','\xb2'},{'\xd9','\x75'},{'\xd9','\x78'},{'\xb4','\xb0'},{'\xd9','\x73'},
+ {'\xd9','\x77'},{'\x00','\x00'},{'\xd9','\x74'},{'\x90','\xca'},{'\xb7','\x71'},
+ {'\x9a','\xc0'},{'\x00','\x00'},{'\xdd','\xbc'},{'\x87','\xdb'},{'\x00','\x00'},
+ {'\xba','\x56'},{'\xe1','\xf4'},{'\xbe','\xe3'},{'\xbc','\xc4'},{'\xe5','\xbd'},
+ {'\xbc','\xc5'},{'\xbc','\xc6'},{'\xe5','\xbf'},{'\xe5','\xbe'},{'\xe5','\xc0'},
+ {'\xe9','\xb1'},{'\x00','\x00'},{'\x00','\x00'},{'\xe9','\xb0'},{'\xec','\xef'},
+ {'\xec','\xee'},{'\xc0','\xc4'},{'\xc0','\xc5'},{'\xf2','\x48'},{'\xfc','\xb7'},
+ {'\x9a','\xc1'},{'\xa4','\xe5'},{'\x90','\xcb'},{'\x93','\x42'},{'\x00','\x00'},
+ {'\x8a','\xbc'},{'\xd9','\x79'},{'\x00','\x00'},{'\x92','\xc7'},{'\x00','\x00'},
+ {'\xb4','\xb4'},{'\xb4','\xb3'},{'\xdd','\xbd'},{'\x8c','\x75'},{'\xef','\xd8'},
+ {'\xc4','\xe3'},{'\xf7','\xde'},{'\xa4','\xe6'},{'\x00','\x00'},{'\xae','\xc6'},
+ {'\x00','\x00'},{'\xb1','\xd8'},{'\xb1','\xd7'},{'\xd9','\x7a'},{'\xd9','\x7b'},
+ {'\xb7','\x72'},{'\xe1','\xf5'},{'\xba','\x57'},{'\xe9','\xb2'},{'\x00','\x00'},
+ {'\xa4','\xe7'},{'\xa5','\xb8'},{'\x00','\x00'},{'\xa9','\xf2'},{'\xcc','\xc2'},
+ {'\x84','\x53'},{'\xce','\xe9'},{'\xac','\x48'},{'\xb1','\xd9'},{'\x8a','\xca'},
+ {'\xd9','\x7c'},{'\xb4','\xb5'},{'\xb7','\x73'},{'\x00','\x00'},{'\xe5','\xc1'},
+ {'\xe5','\xc2'},{'\x00','\x00'},{'\x9a','\xc2'},{'\xec','\xf0'},{'\xc2','\x5f'},
+ {'\xf8','\xf0'},{'\xa4','\xe8'},{'\x00','\x00'},{'\xcc','\xc3'},{'\xa9','\xf3'},
+ {'\xac','\x49'},{'\x9a','\xc3'},{'\xce','\xea'},{'\x00','\x00'},{'\xae','\xc7'},
+ {'\xd1','\xd2'},{'\xd1','\xd0'},{'\xd1','\xd1'},{'\xae','\xc8'},{'\xd1','\xcf'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\xdb'},
+ {'\xb1','\xdc'},{'\xd5','\xa8'},{'\xb1','\xdd'},{'\xb1','\xda'},{'\xd9','\x7d'},
+ {'\x9a','\xc4'},{'\xd9','\x7e'},{'\xdd','\xbe'},{'\x9a','\xc5'},{'\x00','\x00'},
+ {'\xba','\x59'},{'\xba','\x58'},{'\x00','\x00'},{'\x90','\xcc'},{'\xec','\xf1'},
+ {'\xef','\xd9'},{'\x00','\x00'},{'\xf2','\x4a'},{'\xf2','\x49'},{'\xf4','\x4f'},
+ {'\xc6','\xd3'},{'\xc9','\x5e'},{'\xac','\x4a'},{'\x9a','\xc6'},{'\x00','\x00'},
+ {'\xa4','\xe9'},{'\xa5','\xb9'},{'\x8a','\xf6'},{'\xa6','\xae'},{'\xa6','\xad'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa6','\xaf'},{'\xa6','\xb0'},{'\xc9','\xee'},
+ {'\xc9','\xed'},{'\xca','\xf8'},{'\xa7','\xf2'},{'\xca','\xfb'},{'\xca','\xfa'},
+ {'\xca','\xf9'},{'\xca','\xfc'},{'\x83','\xba'},{'\x8b','\x77'},{'\x85','\xd0'},
+ {'\x00','\x00'},{'\xa9','\xf4'},{'\xcc','\xc9'},{'\xcc','\xc5'},{'\xcc','\xce'},
+ {'\x00','\x00'},{'\x9a','\xc7'},{'\xa9','\xfb'},{'\x00','\x00'},{'\xa9','\xf9'},
+ {'\xcc','\xca'},{'\xcc','\xc6'},{'\xcc','\xcd'},{'\xa9','\xf8'},{'\xaa','\x40'},
+ {'\xcc','\xc8'},{'\xcc','\xc4'},{'\xa9','\xfe'},{'\xcc','\xcb'},{'\xa9','\xf7'},
+ {'\xcc','\xcc'},{'\xa9','\xfa'},{'\xa9','\xfc'},{'\xcc','\xd0'},{'\xcc','\xcf'},
+ {'\xcc','\xc7'},{'\xa9','\xf6'},{'\xa9','\xf5'},{'\xa9','\xfd'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9a','\xc8'},{'\x88','\xe8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xce','\xef'},{'\xce','\xf5'},{'\x90','\xcd'},{'\xac','\x50'},{'\xac','\x4d'},
+ {'\xce','\xec'},{'\xce','\xf1'},{'\x9a','\xc9'},{'\xac','\x53'},{'\xac','\x4b'},
+ {'\xce','\xf0'},{'\xac','\x4e'},{'\xac','\x51'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xce','\xf3'},{'\x00','\x00'},{'\xac','\x4c'},{'\xce','\xf8'},{'\xac','\x4f'},
+ {'\x95','\xfe'},{'\xac','\x52'},{'\xce','\xed'},{'\xce','\xf2'},{'\xce','\xf6'},
+ {'\xce','\xee'},{'\xce','\xeb'},{'\x00','\x00'},{'\x00','\x00'},{'\xce','\xf7'},
+ {'\xce','\xf4'},{'\x90','\xce'},{'\x84','\x54'},{'\x00','\x00'},{'\x8d','\x46'},
+ {'\x90','\xcf'},{'\x00','\x00'},{'\xae','\xd0'},{'\xae','\xc9'},{'\xae','\xcc'},
+ {'\x90','\xd0'},{'\xae','\xcf'},{'\x00','\x00'},{'\xd1','\xd5'},{'\xfc','\x62'},
+ {'\xae','\xca'},{'\xd1','\xd3'},{'\x83','\xbb'},{'\xae','\xce'},{'\x9d','\x59'},
+ {'\x00','\x00'},{'\xae','\xcb'},{'\x00','\x00'},{'\xd1','\xd6'},{'\xae','\xcd'},
+ {'\x88','\xe6'},{'\x88','\xe7'},{'\x85','\xcf'},{'\x85','\xce'},{'\x90','\xd1'},
+ {'\x00','\x00'},{'\xd5','\xac'},{'\xb1','\xdf'},{'\xd5','\xab'},{'\xd5','\xad'},
+ {'\xb1','\xde'},{'\xb1','\xe3'},{'\xd1','\xd4'},{'\x00','\x00'},{'\xd5','\xaa'},
+ {'\xd5','\xae'},{'\x9a','\xca'},{'\xb1','\xe0'},{'\xd5','\xa9'},{'\xb1','\xe2'},
+ {'\xfc','\x63'},{'\xb1','\xe1'},{'\x90','\xd2'},{'\xd9','\xa7'},{'\x9a','\xcb'},
+ {'\xd9','\xa2'},{'\x00','\x00'},{'\xb4','\xb6'},{'\xb4','\xba'},{'\xb4','\xb7'},
+ {'\xd9','\xa5'},{'\xd9','\xa8'},{'\x90','\xd3'},{'\xb4','\xb8'},{'\x00','\x00'},
+ {'\xb4','\xb9'},{'\xb4','\xbe'},{'\xdd','\xc7'},{'\xd9','\xa6'},{'\xb4','\xbc'},
+ {'\xd9','\xa3'},{'\xd9','\xa1'},{'\x9a','\xcc'},{'\xb4','\xbd'},{'\x00','\x00'},
+ {'\xd9','\xa4'},{'\x92','\x7d'},{'\x87','\xdc'},{'\x90','\xd4'},{'\xb7','\x79'},
+ {'\x9a','\xcd'},{'\xdd','\xbf'},{'\xb7','\x76'},{'\xb7','\x77'},{'\xb7','\x75'},
+ {'\xdd','\xc4'},{'\xdd','\xc3'},{'\xdd','\xc0'},{'\xb7','\x7b'},{'\xfe','\x7a'},
+ {'\x00','\x00'},{'\xdd','\xc2'},{'\xb4','\xbb'},{'\x9a','\xce'},{'\x00','\x00'},
+ {'\xdd','\xc6'},{'\xdd','\xc1'},{'\xb7','\x78'},{'\xb7','\x74'},{'\xb7','\x7a'},
+ {'\xdd','\xc5'},{'\x9a','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\xba','\x5c'},
+ {'\x00','\x00'},{'\xe1','\xf8'},{'\xe1','\xf7'},{'\xe1','\xf6'},{'\xba','\x5a'},
+ {'\x00','\x00'},{'\x9a','\xd0'},{'\x00','\x00'},{'\x93','\xef'},{'\x89','\xe2'},
+ {'\xba','\x5b'},{'\xe5','\xc5'},{'\xe5','\xc8'},{'\xbc','\xc8'},{'\x00','\x00'},
+ {'\x9a','\xd1'},{'\xbc','\xc7'},{'\xe5','\xc9'},{'\xe5','\xc4'},{'\xbc','\xca'},
+ {'\xe5','\xc6'},{'\x9a','\xd2'},{'\xbc','\xc9'},{'\xe5','\xc3'},{'\x9a','\xd3'},
+ {'\xe5','\xc7'},{'\xbe','\xe9'},{'\xbe','\xe6'},{'\xe9','\xbb'},{'\xe9','\xba'},
+ {'\x90','\xd5'},{'\xe9','\xb9'},{'\xe9','\xb4'},{'\x90','\xd6'},{'\xe9','\xb5'},
+ {'\x90','\xd7'},{'\x00','\x00'},{'\x00','\x00'},{'\xbe','\xe7'},{'\x00','\x00'},
+ {'\xbe','\xe4'},{'\xbe','\xe8'},{'\xe9','\xb3'},{'\xbe','\xe5'},{'\xe9','\xb6'},
+ {'\xe9','\xb7'},{'\xe9','\xbc'},{'\x9a','\xd4'},{'\x9a','\xd5'},{'\xe9','\xb8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\xf2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc0','\xc7'},{'\x00','\x00'},{'\xef','\xdc'},{'\xc0','\xc6'},
+ {'\xef','\xda'},{'\xef','\xdb'},{'\xc2','\x60'},{'\xc3','\x6e'},{'\xf2','\x4b'},
+ {'\x00','\x00'},{'\xc3','\x6d'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x51'},
+ {'\xf4','\x52'},{'\x00','\x00'},{'\xc4','\x66'},{'\x9d','\xca'},{'\xf4','\x50'},
+ {'\xc4','\xe4'},{'\x00','\x00'},{'\xf7','\xdf'},{'\xc5','\xce'},{'\xf8','\xaa'},
+ {'\xf8','\xab'},{'\x00','\x00'},{'\xa4','\xea'},{'\xa0','\x58'},{'\xa6','\xb1'},
+ {'\xa6','\xb2'},{'\xa7','\xf3'},{'\x90','\xd8'},{'\xcc','\xd1'},{'\xac','\x54'},
+ {'\xae','\xd1'},{'\xb1','\xe4'},{'\x90','\xd9'},{'\x90','\xda'},{'\xb0','\xd2'},
+ {'\x93','\xfb'},{'\xb4','\xbf'},{'\xb4','\xc0'},{'\xb3','\xcc'},{'\xd9','\xa9'},
+ {'\x9a','\xd6'},{'\xb7','\x7c'},{'\xe1','\xfa'},{'\xe1','\xf9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa4','\xeb'},{'\xa6','\xb3'},{'\xcc','\xd2'},{'\xaa','\x42'},
+ {'\x9a','\xd7'},{'\xaa','\x41'},{'\x90','\xdb'},{'\xce','\xf9'},{'\xce','\xfa'},
+ {'\x00','\x00'},{'\xd1','\xd7'},{'\xd1','\xd8'},{'\xae','\xd2'},{'\xae','\xd3'},
+ {'\x90','\xdc'},{'\xae','\xd4'},{'\xd5','\xaf'},{'\x9a','\xd8'},{'\x00','\x00'},
+ {'\xb1','\xe6'},{'\x00','\x00'},{'\xb4','\xc2'},{'\xfc','\x64'},{'\xb4','\xc1'},
+ {'\xdd','\xc8'},{'\xdf','\x7a'},{'\xe1','\xfb'},{'\xe9','\xbd'},{'\x00','\x00'},
+ {'\xfe','\x5e'},{'\xc2','\x61'},{'\xc4','\x67'},{'\xa4','\xec'},{'\x91','\xd1'},
+ {'\xa5','\xbc'},{'\xa5','\xbd'},{'\xa5','\xbb'},{'\xa5','\xbe'},{'\xa5','\xba'},
+ {'\x84','\x7b'},{'\x00','\x00'},{'\xa6','\xb6'},{'\x00','\x00'},{'\xc9','\xf6'},
+ {'\xa6','\xb5'},{'\xa6','\xb7'},{'\x95','\x7c'},{'\x90','\xdd'},{'\xc9','\xf1'},
+ {'\xc9','\xf0'},{'\xc9','\xf3'},{'\xc9','\xf2'},{'\xc9','\xf5'},{'\xa6','\xb4'},
+ {'\xc9','\xef'},{'\xc9','\xf4'},{'\x84','\x59'},{'\x94','\x78'},{'\x8b','\x59'},
+ {'\x8c','\xd0'},{'\x9a','\xd9'},{'\xca','\xfd'},{'\xa7','\xfd'},{'\xca','\xfe'},
+ {'\xcb','\x43'},{'\xa7','\xfc'},{'\x00','\x00'},{'\xcb','\x47'},{'\xcb','\x42'},
+ {'\xcb','\x45'},{'\xa7','\xf5'},{'\xa7','\xf6'},{'\xa7','\xf7'},{'\xa7','\xf8'},
+ {'\x00','\x00'},{'\xa8','\x40'},{'\x00','\x00'},{'\xcb','\x41'},{'\xa7','\xfa'},
+ {'\xa8','\x41'},{'\x00','\x00'},{'\xcb','\x40'},{'\xcb','\x46'},{'\x00','\x00'},
+ {'\xa7','\xf9'},{'\xcb','\x44'},{'\xa7','\xfb'},{'\xa7','\xf4'},{'\xa7','\xfe'},
+ {'\x84','\x57'},{'\x94','\x5c'},{'\x94','\x79'},{'\x90','\xde'},{'\x83','\x53'},
+ {'\x90','\xdf'},{'\xfb','\xa6'},{'\x85','\xd4'},{'\x8e','\x72'},{'\xaa','\x57'},
+ {'\x9a','\xda'},{'\xcc','\xd4'},{'\xaa','\x43'},{'\x9d','\x72'},{'\xaa','\x4d'},
+ {'\xaa','\x4e'},{'\xaa','\x46'},{'\xaa','\x58'},{'\xaa','\x48'},{'\xcc','\xdc'},
+ {'\xaa','\x53'},{'\xcc','\xd7'},{'\xaa','\x49'},{'\xcc','\xe6'},{'\xcc','\xe7'},
+ {'\xcc','\xdf'},{'\xcc','\xd8'},{'\xaa','\x56'},{'\xcc','\xe4'},{'\xaa','\x51'},
+ {'\xaa','\x4f'},{'\x00','\x00'},{'\xcc','\xe5'},{'\x00','\x00'},{'\xcc','\xe3'},
+ {'\xcc','\xdb'},{'\xcc','\xd3'},{'\xcc','\xda'},{'\xaa','\x4a'},{'\x00','\x00'},
+ {'\xaa','\x50'},{'\x00','\x00'},{'\xaa','\x44'},{'\xcc','\xde'},{'\xcc','\xdd'},
+ {'\xcc','\xd5'},{'\x9a','\xdb'},{'\xaa','\x52'},{'\xcc','\xe1'},{'\xcc','\xd6'},
+ {'\xaa','\x55'},{'\xcc','\xe8'},{'\xaa','\x45'},{'\x00','\x00'},{'\xaa','\x4c'},
+ {'\xcc','\xd9'},{'\xcc','\xe2'},{'\xaa','\x54'},{'\x00','\x00'},{'\xaa','\x47'},
+ {'\xaa','\x4b'},{'\x87','\xe5'},{'\xcc','\xe0'},{'\x94','\xfd'},{'\x94','\x7a'},
+ {'\x87','\xe0'},{'\x84','\xe5'},{'\x9a','\xdc'},{'\x8f','\xdc'},{'\x90','\xe0'},
+ {'\x90','\xe1'},{'\x8d','\xdf'},{'\x90','\xe2'},{'\x86','\xd2'},{'\x85','\xd6'},
+ {'\xfc','\x66'},{'\x84','\x58'},{'\xcf','\x5b'},{'\xac','\x5c'},{'\xac','\x69'},
+ {'\x95','\x45'},{'\xcf','\x56'},{'\xcf','\x4c'},{'\xac','\x62'},{'\xcf','\x4a'},
+ {'\xac','\x5b'},{'\xcf','\x45'},{'\xac','\x65'},{'\xcf','\x52'},{'\xce','\xfe'},
+ {'\xcf','\x41'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\xdd'},
+ {'\xcf','\x44'},{'\xce','\xfb'},{'\xcf','\x51'},{'\xcf','\x61'},{'\xac','\x60'},
+ {'\xcf','\x46'},{'\xcf','\x58'},{'\x00','\x00'},{'\xce','\xfd'},{'\xcf','\x5f'},
+ {'\xcf','\x60'},{'\xcf','\x63'},{'\xcf','\x5a'},{'\xcf','\x4b'},{'\xcf','\x53'},
+ {'\xac','\x66'},{'\xac','\x59'},{'\xac','\x61'},{'\xac','\x6d'},{'\xac','\x56'},
+ {'\xac','\x58'},{'\x00','\x00'},{'\x9a','\xde'},{'\x9a','\xdf'},{'\xcf','\x43'},
+ {'\xac','\x6a'},{'\xac','\x63'},{'\xcf','\x5d'},{'\xcf','\x40'},{'\xac','\x6c'},
+ {'\xac','\x67'},{'\xcf','\x49'},{'\x8a','\xce'},{'\x00','\x00'},{'\xac','\x6b'},
+ {'\xcf','\x50'},{'\xcf','\x48'},{'\xac','\x64'},{'\xcf','\x5c'},{'\xcf','\x54'},
+ {'\x00','\x00'},{'\xac','\x5e'},{'\xcf','\x62'},{'\xcf','\x47'},{'\xac','\x5a'},
+ {'\xcf','\x59'},{'\xcf','\x4f'},{'\xac','\x5f'},{'\xcf','\x55'},{'\xac','\x57'},
+ {'\xce','\xfc'},{'\xac','\x68'},{'\xae','\xe3'},{'\xac','\x5d'},{'\xcf','\x4e'},
+ {'\xcf','\x4d'},{'\xcf','\x42'},{'\xfc','\x67'},{'\xcf','\x5e'},{'\x90','\xe3'},
+ {'\xcf','\x57'},{'\x90','\xe4'},{'\x94','\x5a'},{'\xac','\x55'},{'\x90','\xe5'},
+ {'\x90','\xe6'},{'\x94','\x4d'},{'\x94','\x51'},{'\x92','\x48'},{'\x90','\xe7'},
+ {'\x00','\x00'},{'\x87','\xe1'},{'\x84','\xe7'},{'\x89','\xe6'},{'\x8f','\xdb'},
+ {'\x84','\xe6'},{'\x8f','\xdd'},{'\x9a','\xe1'},{'\x8f','\xba'},{'\x8c','\x77'},
+ {'\x9a','\xe2'},{'\x88','\xeb'},{'\xd1','\xec'},{'\xae','\xea'},{'\xd1','\xed'},
+ {'\x00','\x00'},{'\xd1','\xe1'},{'\xae','\xdf'},{'\xae','\xeb'},{'\x00','\x00'},
+ {'\xd1','\xda'},{'\x9a','\xe3'},{'\xd1','\xe3'},{'\xd1','\xeb'},{'\x90','\xe8'},
+ {'\xd1','\xd9'},{'\xd1','\xf4'},{'\xae','\xd5'},{'\xfe','\x45'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\xf3'},{'\xd1','\xee'},{'\x00','\x00'},{'\xd1','\xef'},
+ {'\xae','\xdd'},{'\xae','\xe8'},{'\xd1','\xe5'},{'\x00','\x00'},{'\xd1','\xe6'},
+ {'\xd1','\xf0'},{'\xd1','\xe7'},{'\x00','\x00'},{'\xd1','\xe2'},{'\xd1','\xdc'},
+ {'\xd1','\xdd'},{'\xd1','\xea'},{'\xd1','\xe4'},{'\x9a','\xe4'},{'\x87','\xde'},
+ {'\xae','\xd6'},{'\xae','\xda'},{'\xd1','\xf2'},{'\xd1','\xde'},{'\xae','\xe6'},
+ {'\xae','\xe2'},{'\x90','\x6a'},{'\x00','\x00'},{'\xae','\xe5'},{'\xae','\xec'},
+ {'\xae','\xdb'},{'\xae','\xe7'},{'\xd1','\xe9'},{'\xae','\xe9'},{'\xae','\xd8'},
+ {'\x9a','\xe5'},{'\xae','\xd7'},{'\xd1','\xdb'},{'\x90','\xe9'},{'\xd1','\xdf'},
+ {'\xae','\xe0'},{'\xd1','\xf1'},{'\xd1','\xe8'},{'\xd1','\xe0'},{'\xae','\xe4'},
+ {'\xae','\xe1'},{'\x90','\xea'},{'\xae','\xd9'},{'\xae','\xdc'},{'\x90','\xeb'},
+ {'\x9a','\xe6'},{'\x00','\x00'},{'\x00','\x00'},{'\x90','\xec'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x92','\x51'},{'\x82','\x7c'},{'\x00','\x00'},{'\x92','\xcc'},
+ {'\x8d','\xde'},{'\x88','\xef'},{'\x85','\xd5'},{'\x89','\xe3'},{'\x8e','\x71'},
+ {'\x88','\xed'},{'\x88','\xe9'},{'\x89','\xe5'},{'\x87','\xe3'},{'\x87','\xdf'},
+ {'\x00','\x00'},{'\xd5','\xc4'},{'\x00','\x00'},{'\xd5','\xb4'},{'\xd5','\xb5'},
+ {'\xd5','\xb9'},{'\x00','\x00'},{'\xd5','\xc8'},{'\xd5','\xc5'},{'\x00','\x00'},
+ {'\xd5','\xbe'},{'\xd5','\xbd'},{'\xb1','\xed'},{'\xd5','\xc1'},{'\xd5','\xd0'},
+ {'\xd5','\xb0'},{'\x00','\x00'},{'\xd5','\xd1'},{'\xd5','\xc3'},{'\xd5','\xd5'},
+ {'\xd5','\xc9'},{'\xb1','\xec'},{'\xd5','\xc7'},{'\xb1','\xe7'},{'\xb1','\xfc'},
+ {'\xb1','\xf2'},{'\x9a','\xe7'},{'\xb1','\xf6'},{'\xb1','\xf5'},{'\xd5','\xb1'},
+ {'\x9a','\xe8'},{'\xd5','\xce'},{'\xd5','\xd4'},{'\xd5','\xcc'},{'\xd5','\xd3'},
+ {'\x90','\xed'},{'\x00','\x00'},{'\xd5','\xc0'},{'\xd5','\xb2'},{'\xd5','\xd2'},
+ {'\xd5','\xc2'},{'\xb1','\xea'},{'\xb1','\xf7'},{'\x00','\x00'},{'\xd5','\xcb'},
+ {'\xb1','\xf0'},{'\xfb','\x58'},{'\x00','\x00'},{'\x00','\x00'},{'\xd5','\xca'},
+ {'\xd5','\xb3'},{'\xb1','\xf8'},{'\x00','\x00'},{'\xb1','\xfa'},{'\xd5','\xcd'},
+ {'\xb1','\xfb'},{'\xb1','\xe9'},{'\xd5','\xba'},{'\xd5','\xcf'},{'\x00','\x00'},
+ {'\x86','\xbb'},{'\xb1','\xef'},{'\xb1','\xf9'},{'\xd5','\xbc'},{'\xd5','\xc6'},
+ {'\xd5','\xb7'},{'\xd5','\xbb'},{'\xb1','\xf4'},{'\xd5','\xb6'},{'\xb1','\xe8'},
+ {'\xb1','\xf1'},{'\xb1','\xee'},{'\xd5','\xbf'},{'\xae','\xde'},{'\xd9','\xc0'},
+ {'\xb1','\xeb'},{'\xfc','\x68'},{'\x00','\x00'},{'\x00','\x00'},{'\x90','\xee'},
+ {'\x94','\x7b'},{'\x00','\x00'},{'\x82','\x6f'},{'\x9a','\xe9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x89','\xe4'},{'\x00','\x00'},{'\x8c','\x78'},{'\x9a','\xea'},
+ {'\xb1','\xf3'},{'\x9a','\xeb'},{'\xd9','\xc3'},{'\xd9','\xd9'},{'\xd9','\xce'},
+ {'\xb4','\xd6'},{'\xfc','\x6c'},{'\xb4','\xd1'},{'\xd9','\xbd'},{'\xb4','\xd2'},
+ {'\xd9','\xcd'},{'\x90','\xef'},{'\xd9','\xc6'},{'\xd9','\xd3'},{'\xb4','\xce'},
+ {'\xd9','\xab'},{'\xd9','\xd5'},{'\xb4','\xc4'},{'\xd9','\xb3'},{'\xb4','\xc7'},
+ {'\xb4','\xc6'},{'\x00','\x00'},{'\xb4','\xd7'},{'\x00','\x00'},{'\xd9','\xad'},
+ {'\xd9','\xcf'},{'\xd9','\xd0'},{'\xb4','\xc9'},{'\xb4','\xc5'},{'\xd9','\xbb'},
+ {'\x00','\x00'},{'\xb4','\xd0'},{'\xd9','\xb6'},{'\x00','\x00'},{'\xd9','\xd1'},
+ {'\xb4','\xcc'},{'\xd9','\xc9'},{'\xd9','\xd6'},{'\xd9','\xb0'},{'\xd9','\xb5'},
+ {'\xd9','\xaf'},{'\x00','\x00'},{'\xb4','\xcb'},{'\xd9','\xc2'},{'\xdd','\xde'},
+ {'\xd9','\xb1'},{'\xb4','\xcf'},{'\xd9','\xba'},{'\xd9','\xd2'},{'\xb4','\xca'},
+ {'\xd9','\xb7'},{'\xd9','\xb4'},{'\xd9','\xc5'},{'\xb4','\xcd'},{'\xb4','\xc3'},
+ {'\xb4','\xd9'},{'\xd9','\xc8'},{'\xd9','\xc7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xfc','\x6b'},{'\xfc','\x6a'},{'\x9a','\xec'},{'\x9a','\xed'},{'\xd9','\xac'},
+ {'\xb4','\xc8'},{'\xd9','\xd4'},{'\xd9','\xbc'},{'\xd9','\xbe'},{'\x9a','\xee'},
+ {'\xd9','\xcb'},{'\xd9','\xca'},{'\xd9','\xaa'},{'\xb4','\xd3'},{'\xb4','\xd5'},
+ {'\xd9','\xb2'},{'\xd9','\xb9'},{'\xd9','\xc1'},{'\xb4','\xd4'},{'\xd9','\xb8'},
+ {'\xd9','\xc4'},{'\xd9','\xd7'},{'\x00','\x00'},{'\xd9','\xcc'},{'\x9a','\xef'},
+ {'\x94','\x49'},{'\xfe','\x4f'},{'\x94','\x41'},{'\x92','\xb6'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8b','\x79'},{'\x8e','\xb8'},{'\x94','\xa2'},{'\x90','\xf3'},
+ {'\x94','\xa1'},{'\x90','\x6b'},{'\xd9','\xd8'},{'\x90','\xf4'},{'\x00','\x00'},
+ {'\x94','\x7d'},{'\x00','\x00'},{'\xd9','\xae'},{'\x00','\x00'},{'\xfc','\x69'},
+ {'\x88','\xec'},{'\x00','\x00'},{'\xdd','\xf2'},{'\xb7','\xa6'},{'\x00','\x00'},
+ {'\xdd','\xf0'},{'\xdd','\xdb'},{'\xdd','\xe0'},{'\xdd','\xd9'},{'\x90','\xfd'},
+ {'\xdd','\xec'},{'\xdd','\xcb'},{'\xdd','\xd2'},{'\x00','\x00'},{'\xdd','\xea'},
+ {'\xdd','\xf4'},{'\xdd','\xdc'},{'\xfc','\x6f'},{'\xdd','\xcf'},{'\xdd','\xe2'},
+ {'\xdd','\xe7'},{'\xdd','\xd3'},{'\x9a','\xf0'},{'\xdd','\xe4'},{'\xdd','\xd0'},
+ {'\x9a','\xf1'},{'\x00','\x00'},{'\xdd','\xd7'},{'\xdd','\xd8'},{'\xb7','\xa8'},
+ {'\xdd','\xeb'},{'\xdd','\xe9'},{'\x00','\x00'},{'\xdd','\xcc'},{'\xdd','\xee'},
+ {'\x00','\x00'},{'\xdd','\xef'},{'\xdd','\xf1'},{'\xb7','\xac'},{'\xb7','\xa4'},
+ {'\x82','\x6c'},{'\xd5','\xb8'},{'\xdd','\xd4'},{'\xdd','\xe6'},{'\xdd','\xd5'},
+ {'\xb7','\xa1'},{'\xb7','\xb1'},{'\xdd','\xed'},{'\xb7','\xaf'},{'\xb7','\xab'},
+ {'\xdd','\xca'},{'\xb7','\xa3'},{'\x90','\xfe'},{'\xdd','\xcd'},{'\xb7','\xb0'},
+ {'\x9a','\xf2'},{'\xdd','\xdd'},{'\xdd','\xc9'},{'\x9a','\xf3'},{'\xb7','\xa9'},
+ {'\xdd','\xe1'},{'\xdd','\xd1'},{'\xb7','\xaa'},{'\xdd','\xda'},{'\xb7','\x7e'},
+ {'\xb4','\xd8'},{'\xdd','\xe3'},{'\xd9','\xbf'},{'\xdd','\xce'},{'\x9a','\xf4'},
+ {'\xfc','\x6d'},{'\xdd','\xe8'},{'\xb7','\xa5'},{'\xdd','\xe5'},{'\xb7','\xa2'},
+ {'\xdd','\xdf'},{'\xb7','\xad'},{'\xdd','\xd6'},{'\xdd','\xf3'},{'\x87','\xe2'},
+ {'\x92','\x62'},{'\x94','\xa3'},{'\x00','\x00'},{'\xfc','\x6e'},{'\x94','\xa4'},
+ {'\xb7','\xa7'},{'\xde','\xc6'},{'\x8d','\x6e'},{'\x9a','\xf5'},{'\xb7','\xae'},
+ {'\x8b','\xf9'},{'\x8b','\x7a'},{'\x90','\x40'},{'\x94','\x45'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe2','\x4a'},{'\xe2','\x48'},{'\x00','\x00'},{'\xe2','\x5e'},
+ {'\xe2','\x46'},{'\x00','\x00'},{'\xe2','\x58'},{'\xb7','\x7d'},{'\xba','\x5f'},
+ {'\xe2','\x42'},{'\xe2','\x5d'},{'\x95','\x67'},{'\xe2','\x47'},{'\xe2','\x55'},
+ {'\xba','\x64'},{'\xba','\x5d'},{'\x00','\x00'},{'\xe2','\x5b'},{'\x9a','\xf6'},
+ {'\xe2','\x40'},{'\xe2','\x5a'},{'\x9a','\xf7'},{'\xba','\x6f'},{'\xe2','\x51'},
+ {'\xe2','\x61'},{'\xba','\x6d'},{'\xe2','\x49'},{'\xba','\x5e'},{'\xe2','\x4b'},
+ {'\xe2','\x59'},{'\xba','\x67'},{'\xe2','\x44'},{'\xba','\x6b'},{'\xba','\x61'},
+ {'\xe2','\x4d'},{'\xe2','\x43'},{'\xe1','\xfc'},{'\xfc','\x71'},{'\xe2','\x57'},
+ {'\xba','\x68'},{'\xe2','\x60'},{'\xe1','\xfd'},{'\xba','\x65'},{'\x00','\x00'},
+ {'\xe2','\x53'},{'\x00','\x00'},{'\xba','\x66'},{'\xe2','\x45'},{'\xe2','\x50'},
+ {'\xe2','\x4c'},{'\xe2','\x4e'},{'\xfc','\x72'},{'\xba','\x60'},{'\xe2','\x5f'},
+ {'\xba','\x6e'},{'\xe2','\x4f'},{'\x00','\x00'},{'\xe2','\x62'},{'\x91','\xee'},
+ {'\x00','\x00'},{'\xe1','\xfe'},{'\xe2','\x54'},{'\xba','\x63'},{'\xba','\x6c'},
+ {'\xba','\x6a'},{'\xe2','\x41'},{'\xe2','\x56'},{'\xba','\x69'},{'\x9a','\xf8'},
+ {'\x00','\x00'},{'\xba','\x62'},{'\xe2','\x52'},{'\x9a','\xf9'},{'\x9a','\xfa'},
+ {'\x00','\x00'},{'\x93','\xdb'},{'\xe2','\x5c'},{'\x00','\x00'},{'\x8a','\xcd'},
+ {'\x00','\x00'},{'\x94','\xa5'},{'\x96','\x7d'},{'\x8a','\xcb'},{'\x8f','\xb9'},
+ {'\x9b','\x41'},{'\xe5','\xd5'},{'\x00','\x00'},{'\xe5','\xd1'},{'\xe5','\xcd'},
+ {'\xe5','\xe1'},{'\xe5','\xde'},{'\xbc','\xcd'},{'\xfc','\x75'},{'\x00','\x00'},
+ {'\xe5','\xe5'},{'\xe5','\xd4'},{'\xbc','\xd8'},{'\xe5','\xdb'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe5','\xd0'},{'\xe5','\xda'},{'\xbc','\xd5'},{'\xe5','\xee'},
+ {'\x00','\x00'},{'\xe5','\xeb'},{'\xe5','\xdd'},{'\xe5','\xce'},{'\x96','\x7e'},
+ {'\xfc','\x74'},{'\xe5','\xe2'},{'\xe5','\xe4'},{'\xbc','\xd1'},{'\xe5','\xd8'},
+ {'\xe5','\xd3'},{'\xe5','\xca'},{'\xbc','\xce'},{'\xbc','\xd6'},{'\x9b','\x42'},
+ {'\xe5','\xe7'},{'\xbc','\xd7'},{'\xe5','\xcb'},{'\xe5','\xed'},{'\xe5','\xe0'},
+ {'\xe5','\xe6'},{'\xbc','\xd4'},{'\xfe','\x54'},{'\x96','\xce'},{'\xe5','\xe3'},
+ {'\x00','\x00'},{'\xe5','\xea'},{'\x00','\x00'},{'\xbc','\xd9'},{'\x96','\xeb'},
+ {'\xbc','\xd3'},{'\xe5','\xdc'},{'\xe5','\xcf'},{'\xe5','\xef'},{'\xe5','\xcc'},
+ {'\xe5','\xe8'},{'\xbc','\xd0'},{'\x9b','\x43'},{'\xe5','\xd6'},{'\x9b','\x44'},
+ {'\xe5','\xd7'},{'\xbc','\xcf'},{'\xbc','\xcc'},{'\xe5','\xd2'},{'\xbc','\xd2'},
+ {'\x96','\xec'},{'\xbc','\xcb'},{'\x00','\x00'},{'\xe5','\xe9'},{'\xe5','\xec'},
+ {'\xe5','\xd9'},{'\xe9','\xca'},{'\x92','\xb7'},{'\x88','\xea'},{'\x94','\x40'},
+ {'\x9b','\x45'},{'\x9b','\x46'},{'\x94','\xa6'},{'\x89','\xe7'},{'\x96','\xed'},
+ {'\x8c','\x76'},{'\xe9','\xc2'},{'\x9b','\x47'},{'\xe9','\xbe'},{'\xbe','\xf6'},
+ {'\x96','\xee'},{'\x00','\x00'},{'\xbe','\xeb'},{'\xbe','\xf0'},{'\xbe','\xec'},
+ {'\xe9','\xcc'},{'\xe9','\xd7'},{'\xbe','\xea'},{'\xe9','\xc4'},{'\xe9','\xcd'},
+ {'\xe5','\xdf'},{'\xe9','\xce'},{'\x00','\x00'},{'\x9b','\x48'},{'\xbe','\xf1'},
+ {'\x9b','\x49'},{'\xe9','\xdd'},{'\xbe','\xf5'},{'\xbe','\xf8'},{'\xe9','\xc0'},
+ {'\x00','\x00'},{'\xbe','\xf4'},{'\x9b','\x4a'},{'\xe9','\xdb'},{'\xe9','\xdc'},
+ {'\xe9','\xd2'},{'\xe9','\xd1'},{'\xe9','\xc9'},{'\xfc','\x77'},{'\x9b','\x4b'},
+ {'\xe9','\xd3'},{'\xe9','\xda'},{'\xe9','\xd9'},{'\x9b','\x4c'},{'\xbe','\xef'},
+ {'\xbe','\xed'},{'\xe9','\xcb'},{'\xe9','\xc8'},{'\x00','\x00'},{'\xe9','\xc5'},
+ {'\xe9','\xd8'},{'\xbe','\xf7'},{'\xe9','\xd6'},{'\xbe','\xf3'},{'\xbe','\xf2'},
+ {'\x9b','\x4d'},{'\xe9','\xd0'},{'\x96','\xef'},{'\xe9','\xbf'},{'\xe9','\xc1'},
+ {'\xe9','\xc3'},{'\xe9','\xd5'},{'\xe9','\xcf'},{'\xbe','\xee'},{'\x00','\x00'},
+ {'\xe9','\xc6'},{'\x00','\x00'},{'\xe9','\xd4'},{'\x00','\x00'},{'\x8b','\x78'},
+ {'\x94','\xa7'},{'\x96','\xf8'},{'\x9b','\x4e'},{'\x00','\x00'},{'\xe9','\xc7'},
+ {'\x00','\x00'},{'\x96','\xf9'},{'\x8b','\x7b'},{'\x94','\x7e'},{'\x00','\x00'},
+ {'\x96','\xfc'},{'\x00','\x00'},{'\xc0','\xcf'},{'\xed','\x45'},{'\xc0','\xc8'},
+ {'\xec','\xf5'},{'\x9b','\x4f'},{'\xed','\x41'},{'\xc0','\xca'},{'\xed','\x48'},
+ {'\x00','\x00'},{'\xec','\xfc'},{'\x00','\x00'},{'\xec','\xf7'},{'\x9b','\x50'},
+ {'\x00','\x00'},{'\xed','\x49'},{'\xec','\xf3'},{'\xec','\xfe'},{'\x9b','\x51'},
+ {'\xc0','\xd1'},{'\xed','\x44'},{'\xed','\x4a'},{'\xec','\xfd'},{'\xc0','\xc9'},
+ {'\xed','\x40'},{'\xec','\xf4'},{'\xc0','\xd0'},{'\x00','\x00'},{'\x9b','\x52'},
+ {'\xed','\x47'},{'\xec','\xf9'},{'\xc0','\xcc'},{'\xfc','\x78'},{'\xec','\xfb'},
+ {'\xec','\xf8'},{'\xc0','\xd2'},{'\xec','\xfa'},{'\xc0','\xcb'},{'\xc0','\xce'},
+ {'\xed','\x43'},{'\xec','\xf6'},{'\xed','\x46'},{'\x9b','\x53'},{'\xed','\x42'},
+ {'\x96','\xfd'},{'\x96','\xfe'},{'\x99','\xfe'},{'\xc2','\x63'},{'\xef','\xe7'},
+ {'\xc2','\x68'},{'\xc2','\x69'},{'\x00','\x00'},{'\x9b','\x54'},{'\xfc','\x76'},
+ {'\xc2','\x62'},{'\xef','\xe6'},{'\x9b','\x55'},{'\xef','\xe3'},{'\xef','\xe4'},
+ {'\xc2','\x66'},{'\xef','\xde'},{'\xef','\xe2'},{'\xc2','\x65'},{'\x00','\x00'},
+ {'\xef','\xdf'},{'\x9b','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\x9a','\xfe'},
+ {'\xc2','\x67'},{'\xc2','\x64'},{'\x00','\x00'},{'\xef','\xdd'},{'\xef','\xe1'},
+ {'\xef','\xe5'},{'\x95','\xe3'},{'\x9b','\x57'},{'\xfb','\xdc'},{'\xf2','\x51'},
+ {'\xf2','\x4e'},{'\xf2','\x57'},{'\x00','\x00'},{'\xf2','\x56'},{'\xf2','\x54'},
+ {'\xf2','\x4f'},{'\x00','\x00'},{'\xc3','\x72'},{'\x9b','\x58'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\x59'},{'\xf2','\x50'},{'\xc3','\x71'},
+ {'\xc0','\xcd'},{'\xf2','\x53'},{'\xc3','\x70'},{'\xf2','\x58'},{'\xf2','\x52'},
+ {'\xf2','\x4d'},{'\xef','\xe0'},{'\x9c','\xf9'},{'\x00','\x00'},{'\x9d','\xe1'},
+ {'\xc3','\x6f'},{'\x00','\x00'},{'\xf2','\x4c'},{'\xf4','\x56'},{'\x00','\x00'},
+ {'\xf4','\x55'},{'\xf2','\x55'},{'\xc4','\x68'},{'\x00','\x00'},{'\xf4','\x59'},
+ {'\xf4','\x5a'},{'\xf4','\x54'},{'\xf4','\x58'},{'\x00','\x00'},{'\xf4','\x53'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9b','\x5a'},{'\x00','\x00'},{'\xf5','\xd1'},
+ {'\xf4','\x57'},{'\xc4','\xe7'},{'\xc4','\xe5'},{'\xf5','\xcf'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf5','\xd2'},{'\x00','\x00'},{'\xf5','\xce'},
+ {'\xf5','\xd0'},{'\xc4','\xe6'},{'\x9d','\xfe'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf6','\xe5'},{'\xf6','\xe6'},{'\xc5','\x76'},{'\xf6','\xe4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xe2'},{'\xc5','\xcf'},{'\xf7','\xe0'},
+ {'\xf7','\xe1'},{'\xf8','\xac'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\x56'},
+ {'\xf8','\xf3'},{'\xf8','\xf1'},{'\xf8','\xf2'},{'\xf8','\xf4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfc','\x79'},{'\xf9','\xbb'},{'\x94','\xa8'},{'\xa4','\xed'},
+ {'\xa6','\xb8'},{'\x8c','\xd1'},{'\xaa','\x59'},{'\x8a','\xcf'},{'\xcc','\xe9'},
+ {'\x00','\x00'},{'\x87','\xe6'},{'\xcf','\x64'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\xf5'},{'\xd1','\xf7'},{'\x00','\x00'},{'\xd1','\xf6'},
+ {'\x00','\x00'},{'\xd1','\xf8'},{'\xb1','\xfd'},{'\xd5','\xd7'},{'\xd1','\xf9'},
+ {'\x95','\xb9'},{'\xd5','\xd6'},{'\xd5','\xd8'},{'\xd5','\xd9'},{'\xd9','\xda'},
+ {'\xb4','\xdb'},{'\xd9','\xdb'},{'\xd9','\xdd'},{'\xb4','\xdc'},{'\xb4','\xda'},
+ {'\xd9','\xdc'},{'\x00','\x00'},{'\xdd','\xfa'},{'\xdd','\xf8'},{'\xdd','\xf7'},
+ {'\x00','\x00'},{'\xdd','\xf6'},{'\xdd','\xf5'},{'\xb7','\xb2'},{'\xdd','\xf9'},
+ {'\xba','\x70'},{'\xe2','\x63'},{'\xe2','\x65'},{'\xba','\x71'},{'\xe2','\x64'},
+ {'\xbc','\xdb'},{'\x00','\x00'},{'\xbc','\xda'},{'\xe5','\xf0'},{'\xfc','\x7a'},
+ {'\x92','\x6c'},{'\xe9','\xdf'},{'\xe9','\xde'},{'\xe9','\xe0'},{'\x9b','\x5b'},
+ {'\x00','\x00'},{'\xbe','\xf9'},{'\x00','\x00'},{'\xed','\x4b'},{'\xc0','\xd3'},
+ {'\x00','\x00'},{'\xef','\xe8'},{'\xc2','\x6a'},{'\xf2','\x59'},{'\xc5','\x77'},
+ {'\xa4','\xee'},{'\xa5','\xbf'},{'\xa6','\xb9'},{'\xa8','\x42'},{'\xaa','\x5a'},
+ {'\xaa','\x5b'},{'\x00','\x00'},{'\x93','\xc5'},{'\xac','\x6e'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd1','\xfa'},{'\x00','\x00'},{'\x92','\xd0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb7','\xb3'},{'\x92','\xc8'},{'\x93','\xf0'},{'\x00','\x00'},
+ {'\xe6','\xd1'},{'\xbe','\xfa'},{'\xc2','\x6b'},{'\xa4','\xef'},{'\x9b','\x5c'},
+ {'\xa6','\xba'},{'\x8c','\x79'},{'\x00','\x00'},{'\xcc','\xeb'},{'\xaa','\x5c'},
+ {'\xcc','\xea'},{'\x9f','\x4e'},{'\xcf','\x65'},{'\xac','\x6f'},{'\xcf','\x66'},
+ {'\x00','\x00'},{'\xac','\x70'},{'\x87','\xe7'},{'\xd1','\xfc'},{'\xae','\xee'},
+ {'\xae','\xed'},{'\x92','\xcf'},{'\xd5','\xde'},{'\xd5','\xdc'},{'\xd5','\xdd'},
+ {'\xd5','\xdb'},{'\x00','\x00'},{'\xd5','\xda'},{'\x8d','\xb5'},{'\x89','\xe8'},
+ {'\xd9','\xde'},{'\xd9','\xe1'},{'\xb4','\xde'},{'\xd9','\xdf'},{'\xb4','\xdd'},
+ {'\xd9','\xe0'},{'\x8e','\xe8'},{'\xdd','\xfb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe2','\x66'},{'\xe2','\x67'},{'\xe2','\x68'},{'\x8a','\xd1'},{'\xe5','\xf3'},
+ {'\xe5','\xf2'},{'\xbc','\xdc'},{'\xe5','\xf1'},{'\xe5','\xf4'},{'\xe9','\xe1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe9','\xe2'},{'\xe9','\xe3'},{'\x00','\x00'},
+ {'\xed','\x4c'},{'\xc0','\xd4'},{'\xc2','\x6c'},{'\xf2','\x5a'},{'\x9f','\x4f'},
+ {'\xc4','\xe8'},{'\xc9','\x5f'},{'\x87','\xe8'},{'\xac','\x71'},{'\xcf','\x67'},
+ {'\xae','\xef'},{'\x00','\x00'},{'\x00','\x00'},{'\xb1','\xfe'},{'\x92','\x5f'},
+ {'\xb4','\xdf'},{'\xd9','\xe2'},{'\x00','\x00'},{'\xb7','\xb5'},{'\xb7','\xb4'},
+ {'\x90','\xb5'},{'\x8a','\x75'},{'\xe2','\x69'},{'\xe2','\x6a'},{'\xbc','\xdd'},
+ {'\xbc','\xde'},{'\xe9','\xe5'},{'\xe9','\xe4'},{'\xef','\xe9'},{'\xf7','\xe3'},
+ {'\xa4','\xf0'},{'\xc9','\x60'},{'\xa5','\xc0'},{'\x93','\xd1'},{'\xa8','\x43'},
+ {'\xcb','\x48'},{'\x00','\x00'},{'\xac','\x72'},{'\xb7','\xb6'},{'\xa4','\xf1'},
+ {'\x84','\x65'},{'\xcf','\x68'},{'\xac','\x73'},{'\xcf','\x69'},{'\x89','\xe1'},
+ {'\xc0','\xd5'},{'\xa4','\xf2'},{'\x9b','\x5d'},{'\x00','\x00'},{'\xcc','\xec'},
+ {'\x94','\xa9'},{'\xcf','\x6a'},{'\x89','\xe9'},{'\xd2','\x42'},{'\xd2','\x41'},
+ {'\xd1','\xfe'},{'\x00','\x00'},{'\xd1','\xfd'},{'\xd2','\x43'},{'\xd2','\x40'},
+ {'\x00','\x00'},{'\xa0','\x62'},{'\xb2','\x40'},{'\xb2','\x41'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb4','\xe0'},{'\xd9','\xe3'},{'\x00','\x00'},{'\xd9','\xe4'},
+ {'\xd9','\xe5'},{'\x00','\x00'},{'\x8e','\xb9'},{'\x00','\x00'},{'\xde','\x41'},
+ {'\xde','\x42'},{'\xde','\x40'},{'\xfc','\x7b'},{'\xdd','\xfd'},{'\xdd','\xfe'},
+ {'\xb7','\xb7'},{'\xe2','\x6b'},{'\xe5','\xf7'},{'\xe5','\xf6'},{'\xe5','\xf5'},
+ {'\xe5','\xf8'},{'\xe9','\xe7'},{'\xe9','\xe6'},{'\xbe','\xfb'},{'\xe9','\xe8'},
+ {'\x8f','\xbb'},{'\xc0','\xd6'},{'\xed','\x4d'},{'\x00','\x00'},{'\xef','\xea'},
+ {'\xf2','\x5b'},{'\xf6','\xe7'},{'\x00','\x00'},{'\xa4','\xf3'},{'\xa5','\xc2'},
+ {'\xa5','\xc1'},{'\x00','\x00'},{'\xaa','\x5d'},{'\xc9','\x61'},{'\xc9','\x7e'},
+ {'\xa6','\xbb'},{'\x92','\x6e'},{'\xc9','\xf7'},{'\xcb','\x49'},{'\xcb','\x4a'},
+ {'\xaa','\x5e'},{'\x9b','\x5e'},{'\xcc','\xed'},{'\x00','\x00'},{'\xac','\x74'},
+ {'\xcf','\x6b'},{'\xcf','\x6c'},{'\x84','\x5a'},{'\xae','\xf0'},{'\xae','\xf4'},
+ {'\xd2','\x44'},{'\xae','\xf3'},{'\xae','\xf1'},{'\xae','\xf2'},{'\x84','\xec'},
+ {'\xd5','\xdf'},{'\xb2','\x42'},{'\xb4','\xe3'},{'\x00','\x00'},{'\xb4','\xe1'},
+ {'\xb4','\xe2'},{'\xd9','\xe6'},{'\x9b','\x5f'},{'\xa0','\x63'},{'\xba','\x72'},
+ {'\xa4','\xf4'},{'\x9c','\xf3'},{'\xc9','\xa1'},{'\x95','\xeb'},{'\xa5','\xc3'},
+ {'\xfe','\x40'},{'\x91','\xd2'},{'\xc9','\xa4'},{'\x00','\x00'},{'\xa0','\x64'},
+ {'\xa5','\xc6'},{'\xc9','\xa3'},{'\xa5','\xc5'},{'\xa5','\xc4'},{'\xa8','\x44'},
+ {'\xc9','\xa2'},{'\x00','\x00'},{'\x00','\x00'},{'\xc9','\xf8'},{'\x85','\xb9'},
+ {'\x00','\x00'},{'\x86','\xd5'},{'\xc9','\xfc'},{'\xc9','\xfe'},{'\xca','\x40'},
+ {'\xa6','\xc5'},{'\xa6','\xc6'},{'\xc9','\xfb'},{'\xa6','\xc1'},{'\x00','\x00'},
+ {'\xc9','\xf9'},{'\x00','\x00'},{'\xc9','\xfd'},{'\xa6','\xc2'},{'\x00','\x00'},
+ {'\xa6','\xbd'},{'\x9b','\x60'},{'\xa6','\xbe'},{'\x95','\xea'},{'\xa6','\xc4'},
+ {'\xc9','\xfa'},{'\xa6','\xbc'},{'\xa8','\x45'},{'\xa6','\xbf'},{'\xa6','\xc0'},
+ {'\xa6','\xc3'},{'\xa0','\x65'},{'\x00','\x00'},{'\x84','\xf1'},{'\xcb','\x5b'},
+ {'\xcb','\x59'},{'\xcb','\x4c'},{'\xa8','\x51'},{'\xcb','\x53'},{'\xa8','\x4c'},
+ {'\xcb','\x4d'},{'\x00','\x00'},{'\xcb','\x55'},{'\x9b','\x61'},{'\xcb','\x52'},
+ {'\xa8','\x4f'},{'\xcb','\x51'},{'\xa8','\x56'},{'\xcb','\x5a'},{'\xa8','\x58'},
+ {'\x9b','\x62'},{'\xa8','\x5a'},{'\x00','\x00'},{'\xcb','\x4b'},{'\x83','\x6e'},
+ {'\xa8','\x4d'},{'\xcb','\x5c'},{'\x00','\x00'},{'\xa8','\x54'},{'\xa8','\x57'},
+ {'\x9b','\x63'},{'\xcd','\x45'},{'\xa8','\x47'},{'\xa8','\x5e'},{'\xa8','\x55'},
+ {'\xcb','\x4e'},{'\xa8','\x4a'},{'\xa8','\x59'},{'\xcb','\x56'},{'\xa8','\x48'},
+ {'\xa8','\x49'},{'\xcd','\x43'},{'\xcb','\x4f'},{'\xa8','\x50'},{'\xa8','\x5b'},
+ {'\xcb','\x5d'},{'\xcb','\x50'},{'\xa8','\x4e'},{'\x00','\x00'},{'\xa8','\x53'},
+ {'\xcc','\xee'},{'\xa8','\x5c'},{'\xcb','\x57'},{'\xa8','\x52'},{'\x00','\x00'},
+ {'\xa8','\x5d'},{'\xa8','\x46'},{'\xcb','\x54'},{'\xa8','\x4b'},{'\xcb','\x58'},
+ {'\xcd','\x44'},{'\x00','\x00'},{'\x85','\xd8'},{'\x00','\x00'},{'\x95','\xca'},
+ {'\x93','\x6b'},{'\x88','\xf4'},{'\x8e','\x75'},{'\x8b','\x7e'},{'\x84','\x5f'},
+ {'\x85','\xdc'},{'\x00','\x00'},{'\x8d','\xe0'},{'\x86','\xdb'},{'\xaa','\x6a'},
+ {'\xaa','\x7a'},{'\xcc','\xf5'},{'\xaa','\x71'},{'\x9b','\x64'},{'\xcd','\x4b'},
+ {'\xaa','\x62'},{'\xa0','\x66'},{'\xaa','\x65'},{'\xcd','\x42'},{'\x00','\x00'},
+ {'\xcc','\xf3'},{'\xcc','\xf7'},{'\xaa','\x6d'},{'\xaa','\x6f'},{'\xcc','\xfa'},
+ {'\xaa','\x76'},{'\xaa','\x68'},{'\xaa','\x66'},{'\xaa','\x67'},{'\xaa','\x75'},
+ {'\xcd','\x47'},{'\xaa','\x70'},{'\xcc','\xf9'},{'\xcc','\xfb'},{'\xaa','\x6e'},
+ {'\xaa','\x73'},{'\xcc','\xfc'},{'\xcd','\x4a'},{'\x00','\x00'},{'\xac','\x75'},
+ {'\xaa','\x79'},{'\x9b','\x65'},{'\xaa','\x63'},{'\xcd','\x49'},{'\xfc','\x7d'},
+ {'\xcd','\x4d'},{'\xcc','\xf8'},{'\xcd','\x4f'},{'\xcd','\x40'},{'\xaa','\x6c'},
+ {'\xcc','\xf4'},{'\xaa','\x6b'},{'\xaa','\x7d'},{'\xaa','\x72'},{'\x00','\x00'},
+ {'\xcc','\xf2'},{'\xcf','\x75'},{'\xaa','\x78'},{'\xaa','\x7c'},{'\xcd','\x41'},
+ {'\xcd','\x46'},{'\x9b','\x66'},{'\xaa','\x7e'},{'\xaa','\x77'},{'\xaa','\x69'},
+ {'\xaa','\x5f'},{'\x00','\x00'},{'\xaa','\x64'},{'\x00','\x00'},{'\xcc','\xf6'},
+ {'\xaa','\x60'},{'\xcd','\x4e'},{'\x84','\x5e'},{'\xcc','\xf0'},{'\xcc','\xef'},
+ {'\xcc','\xfd'},{'\xcc','\xf1'},{'\xaa','\x7b'},{'\xae','\xf5'},{'\xaa','\x74'},
+ {'\xcc','\xfe'},{'\xaa','\x61'},{'\x00','\x00'},{'\xac','\xa6'},{'\x8f','\x54'},
+ {'\x8f','\xbc'},{'\x8b','\xa2'},{'\xcd','\x4c'},{'\x8f','\x77'},{'\x8a','\xd2'},
+ {'\x87','\xea'},{'\x88','\xf2'},{'\x83','\xbd'},{'\x9b','\x67'},{'\xcf','\x7c'},
+ {'\xcf','\xa1'},{'\x9b','\x68'},{'\xcf','\xa4'},{'\xcf','\x77'},{'\x9b','\x69'},
+ {'\x9b','\x6a'},{'\xcf','\xa7'},{'\xcf','\xaa'},{'\xcf','\xac'},{'\xcf','\x74'},
+ {'\xac','\x76'},{'\xac','\x7b'},{'\xd2','\x49'},{'\xac','\xad'},{'\xcf','\xa5'},
+ {'\xcf','\xad'},{'\xcf','\x7b'},{'\xcf','\x73'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd2','\x64'},{'\xac','\x7e'},{'\xcf','\xa2'},{'\xcf','\x78'},
+ {'\xcf','\x7a'},{'\xac','\xa5'},{'\x00','\x00'},{'\xcf','\x7d'},{'\xac','\x7d'},
+ {'\xcf','\x70'},{'\xcf','\xa8'},{'\x00','\x00'},{'\xcf','\xab'},{'\x00','\x00'},
+ {'\x95','\xb0'},{'\xac','\x7a'},{'\x9b','\x6b'},{'\xac','\xa8'},{'\xcf','\x6d'},
+ {'\xac','\xaa'},{'\xac','\x78'},{'\xac','\xae'},{'\xcf','\xa9'},{'\xcf','\x6f'},
+ {'\xac','\xab'},{'\xd2','\x5e'},{'\xcd','\x48'},{'\xac','\x7c'},{'\xac','\x77'},
+ {'\xcf','\x76'},{'\xcf','\x6e'},{'\xac','\xac'},{'\xac','\xa4'},{'\xcf','\xa3'},
+ {'\xac','\xa9'},{'\xac','\xa7'},{'\xcf','\x79'},{'\xac','\xa1'},{'\xcf','\x71'},
+ {'\xac','\xa2'},{'\xac','\xa3'},{'\xcf','\x72'},{'\xcf','\xa6'},{'\xac','\x79'},
+ {'\xcf','\x7e'},{'\x83','\xbe'},{'\x92','\xea'},{'\x93','\x48'},{'\x87','\xe9'},
+ {'\x87','\xec'},{'\x8d','\xe1'},{'\x00','\x00'},{'\x88','\xf3'},{'\x84','\xf2'},
+ {'\x00','\x00'},{'\x8e','\xe9'},{'\x89','\xec'},{'\x8a','\xd7'},{'\x00','\x00'},
+ {'\x84','\xf3'},{'\x8e','\x74'},{'\x88','\xf1'},{'\x87','\xf0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x9b','\x6c'},{'\xd2','\x4c'},{'\xae','\xfd'},{'\xaf','\x43'},
+ {'\x9b','\x6d'},{'\x93','\xbd'},{'\x00','\x00'},{'\xd2','\x55'},{'\xd2','\x5b'},
+ {'\xd2','\x57'},{'\xd2','\x4a'},{'\xd2','\x4d'},{'\xd2','\x46'},{'\xd2','\x47'},
+ {'\xaf','\x4a'},{'\xae','\xfa'},{'\xd2','\x56'},{'\xd2','\x5f'},{'\xaf','\x45'},
+ {'\xae','\xf6'},{'\x00','\x00'},{'\xaf','\x40'},{'\xd2','\x4e'},{'\xaf','\x42'},
+ {'\xd2','\x4f'},{'\xd2','\x59'},{'\x9b','\x6e'},{'\xfb','\xa7'},{'\x00','\x00'},
+ {'\xaf','\x44'},{'\xd2','\x68'},{'\xd2','\x48'},{'\xae','\xfc'},{'\xae','\xfb'},
+ {'\xaf','\x48'},{'\xd2','\x45'},{'\xd2','\x66'},{'\xd2','\x5a'},{'\xd2','\x67'},
+ {'\xd2','\x61'},{'\xd2','\x53'},{'\xd2','\x62'},{'\x9b','\x6f'},{'\xd2','\x5c'},
+ {'\xd2','\x65'},{'\xd2','\x63'},{'\xaf','\x49'},{'\xd2','\x54'},{'\xae','\xf9'},
+ {'\xae','\xf8'},{'\xaf','\x41'},{'\xaf','\x47'},{'\xd2','\x60'},{'\xaf','\x46'},
+ {'\xd2','\x51'},{'\xb2','\x43'},{'\x9b','\x70'},{'\xd2','\x69'},{'\xd2','\x50'},
+ {'\xd2','\x4b'},{'\xae','\xfe'},{'\xaf','\x4b'},{'\xae','\xf7'},{'\xfe','\x5c'},
+ {'\xd2','\x58'},{'\xd2','\x5d'},{'\x93','\xe8'},{'\x00','\x00'},{'\x89','\xed'},
+ {'\x82','\x71'},{'\x8e','\xbb'},{'\x8d','\xcf'},{'\x86','\xda'},{'\x8e','\xbd'},
+ {'\x84','\xf0'},{'\x00','\x00'},{'\x84','\xf4'},{'\x86','\xde'},{'\x9b','\x71'},
+ {'\x87','\xee'},{'\x87','\xef'},{'\x86','\xd9'},{'\x89','\xef'},{'\xb2','\x65'},
+ {'\xd5','\xe1'},{'\xd5','\xe5'},{'\x00','\x00'},{'\xb2','\x52'},{'\xb2','\x50'},
+ {'\x00','\x00'},{'\x9b','\x72'},{'\xb2','\x47'},{'\xd5','\xe3'},{'\xd5','\xe2'},
+ {'\xb2','\x5b'},{'\x00','\x00'},{'\xd5','\xe8'},{'\xb2','\x55'},{'\xfc','\xa1'},
+ {'\xd5','\xfa'},{'\xd6','\x47'},{'\xb2','\x44'},{'\xd5','\xf7'},{'\xd5','\xf0'},
+ {'\xb2','\x67'},{'\xd5','\xe0'},{'\x00','\x00'},{'\xd5','\xfc'},{'\x00','\x00'},
+ {'\xb2','\x64'},{'\xb2','\x58'},{'\xb2','\x63'},{'\xb2','\x4e'},{'\xd5','\xec'},
+ {'\xd5','\xfe'},{'\xd5','\xf6'},{'\xb2','\x4f'},{'\xb2','\x49'},{'\xd6','\x45'},
+ {'\x00','\x00'},{'\xd5','\xfd'},{'\xd6','\x40'},{'\xb2','\x51'},{'\xb2','\x59'},
+ {'\xd6','\x42'},{'\xd5','\xea'},{'\xd5','\xfb'},{'\xd5','\xef'},{'\xd6','\x44'},
+ {'\xb2','\x5e'},{'\xb2','\x46'},{'\xb2','\x5c'},{'\xd5','\xf4'},{'\xd5','\xf2'},
+ {'\xd5','\xf3'},{'\xb2','\x53'},{'\xd5','\xee'},{'\xd5','\xed'},{'\xb2','\x48'},
+ {'\xd5','\xe7'},{'\xd6','\x46'},{'\xb2','\x4a'},{'\xd5','\xf1'},{'\xb2','\x68'},
+ {'\x00','\x00'},{'\xb2','\x62'},{'\xd5','\xe6'},{'\xb2','\x5f'},{'\xb2','\x5d'},
+ {'\xb2','\x66'},{'\xd5','\xf8'},{'\xb2','\x61'},{'\xd2','\x52'},{'\xd5','\xf9'},
+ {'\xb2','\x60'},{'\xd6','\x41'},{'\xb2','\x45'},{'\xd5','\xf5'},{'\xb2','\x57'},
+ {'\xd5','\xe9'},{'\xb2','\x56'},{'\xa0','\x67'},{'\xb2','\x54'},{'\xb2','\x4c'},
+ {'\xb2','\x4b'},{'\xd9','\xe7'},{'\xd6','\x43'},{'\x9b','\x73'},{'\x00','\x00'},
+ {'\xd5','\xeb'},{'\x00','\x00'},{'\x9b','\x74'},{'\xd9','\xfc'},{'\x9b','\x75'},
+ {'\xb2','\x4d'},{'\x00','\x00'},{'\x92','\x64'},{'\x92','\xc6'},{'\x92','\xe4'},
+ {'\x84','\x5d'},{'\x92','\xdd'},{'\x8d','\xd0'},{'\x86','\xd4'},{'\x8a','\xd5'},
+ {'\x9b','\x76'},{'\x86','\xd8'},{'\x88','\xf6'},{'\x00','\x00'},{'\x92','\xaa'},
+ {'\x86','\xdc'},{'\x94','\xaa'},{'\x8a','\xd3'},{'\x86','\xdd'},{'\x9b','\x77'},
+ {'\xb5','\x41'},{'\xb2','\x5a'},{'\xb4','\xee'},{'\xd9','\xf6'},{'\xb4','\xfc'},
+ {'\x00','\x00'},{'\xd9','\xea'},{'\xb4','\xeb'},{'\xb4','\xe7'},{'\xda','\x49'},
+ {'\xb4','\xed'},{'\xb4','\xf1'},{'\xb4','\xec'},{'\xb4','\xf5'},{'\xda','\x4d'},
+ {'\xda','\x44'},{'\xa0','\x68'},{'\x9b','\x78'},{'\xd9','\xf1'},{'\xb4','\xfa'},
+ {'\xb4','\xf4'},{'\xd9','\xfd'},{'\xb4','\xe4'},{'\xda','\x4a'},{'\xda','\x43'},
+ {'\xb4','\xe8'},{'\xd9','\xf7'},{'\xb4','\xf7'},{'\xda','\x55'},{'\xda','\x56'},
+ {'\x00','\x00'},{'\xb4','\xe5'},{'\xda','\x48'},{'\xb4','\xf9'},{'\xd9','\xfb'},
+ {'\xd9','\xed'},{'\xd9','\xee'},{'\xb4','\xfd'},{'\xd9','\xf2'},{'\xd9','\xf9'},
+ {'\xd9','\xf3'},{'\x00','\x00'},{'\xb4','\xfb'},{'\xb5','\x44'},{'\xd9','\xef'},
+ {'\xd9','\xe8'},{'\xd9','\xe9'},{'\x00','\x00'},{'\xd9','\xeb'},{'\xb4','\xea'},
+ {'\xd9','\xf8'},{'\x00','\x00'},{'\xb4','\xf8'},{'\xb5','\x42'},{'\xfc','\x7e'},
+ {'\x9b','\x79'},{'\xd9','\xfa'},{'\xda','\x53'},{'\xda','\x4b'},{'\xb4','\xe6'},
+ {'\xda','\x51'},{'\xb4','\xf2'},{'\x9d','\xcb'},{'\xb4','\xf0'},{'\x9b','\x7a'},
+ {'\xda','\x57'},{'\xb4','\xef'},{'\xda','\x41'},{'\xd9','\xf4'},{'\xd9','\xfe'},
+ {'\xb5','\x47'},{'\xda','\x45'},{'\xda','\x42'},{'\xd9','\xf0'},{'\xb5','\x43'},
+ {'\xda','\x4f'},{'\xda','\x4c'},{'\xda','\x54'},{'\xb4','\xe9'},{'\xda','\x40'},
+ {'\xb5','\x46'},{'\x00','\x00'},{'\xda','\x47'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb4','\xf3'},{'\xb4','\xf6'},{'\x00','\x00'},{'\xda','\x46'},{'\xb5','\x45'},
+ {'\xd9','\xf5'},{'\xd5','\xe4'},{'\x00','\x00'},{'\xa0','\x69'},{'\xda','\x50'},
+ {'\xda','\x4e'},{'\xda','\x52'},{'\x00','\x00'},{'\x00','\x00'},{'\x95','\xcb'},
+ {'\x00','\x00'},{'\x8d','\x6f'},{'\x85','\xda'},{'\x93','\xd2'},{'\x00','\x00'},
+ {'\xa0','\x6a'},{'\x87','\xed'},{'\x00','\x00'},{'\x8a','\xd6'},{'\xa0','\x6b'},
+ {'\x00','\x00'},{'\xd9','\xec'},{'\xb5','\x40'},{'\x00','\x00'},{'\xfe','\x6a'},
+ {'\x82','\x78'},{'\xde','\x61'},{'\xde','\x60'},{'\xde','\x46'},{'\xb7','\xbd'},
+ {'\x00','\x00'},{'\xde','\x5f'},{'\xde','\x49'},{'\xde','\x4a'},{'\x00','\x00'},
+ {'\xb7','\xc7'},{'\xde','\x68'},{'\xb7','\xc2'},{'\xde','\x5e'},{'\x9b','\x7b'},
+ {'\xde','\x43'},{'\xb7','\xc8'},{'\xb7','\xbe'},{'\xde','\x52'},{'\xde','\x48'},
+ {'\xde','\x4b'},{'\xde','\x63'},{'\xb7','\xb8'},{'\xde','\x6a'},{'\xde','\x62'},
+ {'\xb7','\xc1'},{'\xde','\x57'},{'\xb7','\xcc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb7','\xcb'},{'\xb7','\xc5'},{'\x00','\x00'},{'\x00','\x00'},{'\xde','\x69'},
+ {'\xb7','\xb9'},{'\xde','\x55'},{'\xde','\x4c'},{'\xde','\x59'},{'\xde','\x65'},
+ {'\xb7','\xcd'},{'\x9b','\x7c'},{'\xb7','\xbb'},{'\xde','\x54'},{'\x9b','\x7d'},
+ {'\xde','\x4d'},{'\xb7','\xc4'},{'\xa0','\x6c'},{'\xb7','\xc3'},{'\xde','\x50'},
+ {'\xde','\x5a'},{'\xde','\x64'},{'\xde','\x47'},{'\xde','\x51'},{'\xb7','\xbc'},
+ {'\xde','\x5b'},{'\xb7','\xc9'},{'\xb7','\xc0'},{'\xde','\x4e'},{'\xb7','\xbf'},
+ {'\xde','\x45'},{'\xde','\x53'},{'\xde','\x67'},{'\xb4','\xfe'},{'\xba','\xb0'},
+ {'\xde','\x56'},{'\xe2','\x6c'},{'\xde','\x58'},{'\xde','\x66'},{'\xb7','\xc6'},
+ {'\xde','\x4f'},{'\xb7','\xba'},{'\xb7','\xca'},{'\xbc','\xf0'},{'\xde','\x44'},
+ {'\x8e','\xbe'},{'\xde','\x5d'},{'\x95','\x50'},{'\x86','\xd3'},{'\x9b','\x7e'},
+ {'\xde','\x5c'},{'\x93','\x69'},{'\x86','\xd7'},{'\xa0','\x6d'},{'\x90','\x41'},
+ {'\x86','\xd6'},{'\xa0','\x6e'},{'\x00','\x00'},{'\x8a','\xd4'},{'\x89','\xee'},
+ {'\x8d','\x7b'},{'\x00','\x00'},{'\x89','\xeb'},{'\x8c','\xd2'},{'\x00','\x00'},
+ {'\xe2','\xaa'},{'\xba','\xad'},{'\xe2','\x7d'},{'\xe2','\xa4'},{'\xba','\xa2'},
+ {'\x00','\x00'},{'\xe2','\x6e'},{'\xba','\xaf'},{'\x00','\x00'},{'\xba','\x77'},
+ {'\xe2','\x6d'},{'\xe2','\xb0'},{'\xba','\xb1'},{'\xe2','\x71'},{'\xe2','\xa3'},
+ {'\x9b','\xa1'},{'\xe2','\x73'},{'\xe2','\xb3'},{'\xe2','\xaf'},{'\xba','\x75'},
+ {'\xba','\xa1'},{'\xe6','\x53'},{'\xba','\xae'},{'\xba','\x7d'},{'\xe2','\x6f'},
+ {'\x9b','\xa2'},{'\xe2','\xae'},{'\xba','\xa3'},{'\xe2','\xab'},{'\xe2','\xb8'},
+ {'\xe2','\x75'},{'\xe2','\x7e'},{'\x9b','\xa3'},{'\x9b','\xa4'},{'\xe2','\xb6'},
+ {'\xe2','\xac'},{'\xba','\x7c'},{'\x00','\x00'},{'\xa0','\x6f'},{'\xe2','\x7c'},
+ {'\xba','\x76'},{'\xba','\x74'},{'\xba','\xa8'},{'\x9b','\xa5'},{'\x9b','\xa6'},
+ {'\xe2','\x7a'},{'\xe2','\x77'},{'\xe2','\x78'},{'\x00','\x00'},{'\xe2','\xb2'},
+ {'\x00','\x00'},{'\xe2','\xb7'},{'\xe2','\xb5'},{'\xba','\x7a'},{'\xe2','\xb9'},
+ {'\xba','\x7e'},{'\xba','\xa7'},{'\xa0','\x70'},{'\xe2','\x70'},{'\xe5','\xfa'},
+ {'\xe2','\x79'},{'\x00','\x00'},{'\xba','\x78'},{'\xba','\xac'},{'\xba','\xa9'},
+ {'\xba','\x7b'},{'\xe2','\xa5'},{'\xe2','\x74'},{'\xba','\xaa'},{'\xe2','\xa7'},
+ {'\xba','\xa4'},{'\xba','\xa6'},{'\xba','\x73'},{'\x9b','\xa7'},{'\xe2','\xa9'},
+ {'\xe2','\xa1'},{'\xe2','\x72'},{'\xba','\xa5'},{'\xe2','\xb1'},{'\xe2','\xb4'},
+ {'\xe2','\x7b'},{'\xe2','\xa8'},{'\x9b','\xa8'},{'\xba','\x79'},{'\xbc','\xdf'},
+ {'\xe2','\xa6'},{'\xe5','\xf9'},{'\x00','\x00'},{'\xe2','\xad'},{'\xfc','\xa2'},
+ {'\x82','\x50'},{'\x8f','\xbd'},{'\x8b','\x7c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8b','\xfb'},{'\x00','\x00'},{'\x89','\xf0'},{'\xe2','\x76'},
+ {'\xe6','\x44'},{'\xe6','\x4e'},{'\xbc','\xe2'},{'\xe6','\x4d'},{'\xe6','\x59'},
+ {'\xbc','\xe4'},{'\xe6','\x4b'},{'\x9b','\xa9'},{'\xe6','\x4f'},{'\xbc','\xef'},
+ {'\x00','\x00'},{'\xe6','\x46'},{'\xbc','\xe7'},{'\x90','\xb9'},{'\xe6','\x52'},
+ {'\xe9','\xf0'},{'\xbc','\xf3'},{'\xbc','\xf2'},{'\xe6','\x54'},{'\xe6','\x43'},
+ {'\xe6','\x5e'},{'\xbc','\xed'},{'\x00','\x00'},{'\xbc','\xe3'},{'\xe6','\x57'},
+ {'\x00','\x00'},{'\xe6','\x5b'},{'\xe6','\x60'},{'\xe6','\x55'},{'\xe6','\x49'},
+ {'\xbc','\xe6'},{'\xbc','\xe9'},{'\xbc','\xf1'},{'\xbc','\xec'},{'\x00','\x00'},
+ {'\xe6','\x4c'},{'\xe2','\xa2'},{'\xa0','\x71'},{'\x00','\x00'},{'\xe6','\x48'},
+ {'\xe6','\x5f'},{'\xbc','\xe8'},{'\x9b','\xaa'},{'\xbc','\xeb'},{'\xe6','\x61'},
+ {'\xbc','\xe0'},{'\xe6','\x56'},{'\xe5','\xfb'},{'\xe6','\x5c'},{'\xc0','\xdf'},
+ {'\x95','\x6b'},{'\xe6','\x4a'},{'\x00','\x00'},{'\xbc','\xe1'},{'\xe6','\x45'},
+ {'\xbc','\xe5'},{'\xe5','\xfc'},{'\xba','\xab'},{'\xe6','\x41'},{'\x9b','\xab'},
+ {'\xe6','\x5a'},{'\xe6','\x42'},{'\xe6','\x40'},{'\xbc','\xea'},{'\x00','\x00'},
+ {'\xe6','\x58'},{'\xa0','\x72'},{'\xe5','\xfe'},{'\xe6','\x51'},{'\xe6','\x50'},
+ {'\xe6','\x5d'},{'\xe6','\x47'},{'\xbc','\xee'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x8b','\xfa'},{'\x9b','\xac'},{'\xe9','\xf3'},
+ {'\x9b','\xad'},{'\xbf','\x49'},{'\xbe','\xfe'},{'\xea','\x40'},{'\xe9','\xeb'},
+ {'\xbf','\x41'},{'\xe9','\xf7'},{'\xbf','\x48'},{'\xbf','\x43'},{'\xe9','\xf5'},
+ {'\xed','\x4f'},{'\xe9','\xfb'},{'\xea','\x42'},{'\xe9','\xfa'},{'\xe9','\xe9'},
+ {'\xe9','\xf8'},{'\xea','\x44'},{'\xea','\x46'},{'\xbe','\xfd'},{'\xea','\x45'},
+ {'\xbf','\x44'},{'\xbf','\x4a'},{'\xa0','\x73'},{'\xbf','\x47'},{'\x00','\x00'},
+ {'\xe9','\xfe'},{'\xbf','\x46'},{'\xe9','\xf9'},{'\x9b','\xae'},{'\xe9','\xed'},
+ {'\xe9','\xf2'},{'\x9b','\xaf'},{'\xe9','\xfd'},{'\xbf','\x45'},{'\xbf','\x42'},
+ {'\xbe','\xfc'},{'\xbf','\x40'},{'\xe9','\xf1'},{'\x00','\x00'},{'\xe5','\xfd'},
+ {'\xe9','\xec'},{'\xe9','\xef'},{'\xea','\x41'},{'\xe9','\xf4'},{'\xe9','\xea'},
+ {'\xed','\x4e'},{'\xea','\x43'},{'\xe9','\xee'},{'\xe9','\xfc'},{'\x00','\x00'},
+ {'\x8b','\x7d'},{'\x8b','\xa1'},{'\x9b','\xb0'},{'\xed','\x51'},{'\xc0','\xe3'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xd7'},{'\x9b','\xb1'},{'\xfc','\xa4'},
+ {'\xc0','\xdb'},{'\xed','\x53'},{'\xed','\x59'},{'\xed','\x57'},{'\xc0','\xd9'},
+ {'\xc0','\xda'},{'\xc0','\xe1'},{'\xed','\x5a'},{'\xed','\x52'},{'\xc0','\xdc'},
+ {'\x00','\x00'},{'\xed','\x56'},{'\xed','\x55'},{'\xed','\x5b'},{'\xc0','\xe2'},
+ {'\x00','\x00'},{'\xc0','\xdd'},{'\xc0','\xe0'},{'\xed','\x54'},{'\xc0','\xe4'},
+ {'\xc0','\xde'},{'\xc0','\xe5'},{'\xc0','\xd8'},{'\xed','\x58'},{'\xa0','\x74'},
+ {'\xed','\x50'},{'\xa0','\x75'},{'\x95','\xc6'},{'\xef','\xf7'},{'\x9b','\xb2'},
+ {'\x00','\x00'},{'\xc2','\x71'},{'\xef','\xf4'},{'\xef','\xf6'},{'\x00','\x00'},
+ {'\xc2','\x6f'},{'\xef','\xf2'},{'\xef','\xf3'},{'\xef','\xee'},{'\x00','\x00'},
+ {'\x9b','\xb3'},{'\xe9','\xf6'},{'\xef','\xef'},{'\xc2','\x70'},{'\xef','\xeb'},
+ {'\x00','\x00'},{'\xc2','\x6d'},{'\xef','\xf8'},{'\xc2','\x6e'},{'\xef','\xec'},
+ {'\xef','\xed'},{'\xef','\xf1'},{'\xc2','\x73'},{'\x00','\x00'},{'\xc2','\x72'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xef','\xf0'},{'\xc3','\x78'},{'\xf2','\x5f'},
+ {'\xf2','\x65'},{'\xc3','\x79'},{'\xf2','\x5c'},{'\xc3','\x76'},{'\xc3','\x73'},
+ {'\xf2','\x67'},{'\xc3','\x77'},{'\xfe','\xa1'},{'\xc3','\x74'},{'\xf2','\x5e'},
+ {'\xf2','\x61'},{'\xf2','\x62'},{'\xf2','\x63'},{'\xf2','\x66'},{'\x00','\x00'},
+ {'\xef','\xf5'},{'\xf2','\x5d'},{'\xc3','\x75'},{'\xf2','\x64'},{'\xf2','\x68'},
+ {'\xf2','\x60'},{'\x93','\x40'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x5d'},
+ {'\xc4','\x6a'},{'\xf4','\x60'},{'\xc4','\x6b'},{'\xf4','\x68'},{'\xf4','\x5f'},
+ {'\xf4','\x5c'},{'\x00','\x00'},{'\xf4','\x5e'},{'\xf4','\x62'},{'\xf4','\x65'},
+ {'\xf4','\x64'},{'\xf4','\x67'},{'\xf4','\x5b'},{'\x00','\x00'},{'\xc4','\x69'},
+ {'\xf4','\x63'},{'\xf4','\x66'},{'\xf4','\x69'},{'\xf4','\x61'},{'\xf5','\xd3'},
+ {'\xf5','\xd4'},{'\xf5','\xd8'},{'\xf5','\xd9'},{'\x00','\x00'},{'\xf5','\xd6'},
+ {'\xf5','\xd7'},{'\xf5','\xd5'},{'\x9b','\xb4'},{'\xc4','\xe9'},{'\x9b','\xb5'},
+ {'\x00','\x00'},{'\x90','\x76'},{'\x9b','\xb6'},{'\xc5','\x78'},{'\xf6','\xeb'},
+ {'\x00','\x00'},{'\x9b','\xb7'},{'\xf6','\xe8'},{'\xf6','\xe9'},{'\xf6','\xea'},
+ {'\xc5','\x79'},{'\x00','\x00'},{'\xf7','\xe5'},{'\xf7','\xe4'},{'\x9b','\xb8'},
+ {'\xf8','\xaf'},{'\xc5','\xf4'},{'\xf8','\xad'},{'\xf8','\xb0'},{'\xf8','\xae'},
+ {'\xf8','\xf5'},{'\xc6','\x57'},{'\xc6','\x65'},{'\xf9','\xa3'},{'\xf9','\x6c'},
+ {'\x9b','\xb9'},{'\xf9','\xa2'},{'\xf9','\xd0'},{'\xf9','\xd1'},{'\xa4','\xf5'},
+ {'\x9c','\xf6'},{'\x85','\xd9'},{'\x00','\x00'},{'\x88','\xf9'},{'\xa6','\xc7'},
+ {'\xca','\x41'},{'\x00','\x00'},{'\x00','\x00'},{'\xcb','\x5e'},{'\x8d','\x5f'},
+ {'\xa8','\x5f'},{'\x9b','\xba'},{'\xa8','\x62'},{'\x9b','\xbb'},{'\xcb','\x5f'},
+ {'\x00','\x00'},{'\xa8','\x60'},{'\xa8','\x61'},{'\x83','\x4d'},{'\x89','\xf2'},
+ {'\x85','\xdf'},{'\xfc','\xa5'},{'\xcd','\x58'},{'\xcd','\x5a'},{'\xcd','\x55'},
+ {'\xcd','\x52'},{'\xcd','\x54'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\xf4'},
+ {'\xaa','\xa4'},{'\x9b','\xbc'},{'\x00','\x00'},{'\xfe','\xa3'},{'\xaa','\xa2'},
+ {'\x9b','\xbd'},{'\x00','\x00'},{'\xcd','\x56'},{'\xaa','\xa3'},{'\xcd','\x53'},
+ {'\xcd','\x50'},{'\xaa','\xa1'},{'\xcd','\x57'},{'\x00','\x00'},{'\xcd','\x51'},
+ {'\xaa','\xa5'},{'\xcd','\x59'},{'\x00','\x00'},{'\x8e','\x45'},{'\x8e','\x76'},
+ {'\x00','\x00'},{'\xcf','\xaf'},{'\x9b','\xbe'},{'\xcf','\xb3'},{'\x00','\x00'},
+ {'\x9b','\xbf'},{'\xac','\xb7'},{'\x9b','\xc0'},{'\x9b','\xc1'},{'\x9b','\xc2'},
+ {'\x00','\x00'},{'\xcf','\xb6'},{'\x00','\x00'},{'\xac','\xaf'},{'\xac','\xb2'},
+ {'\xac','\xb4'},{'\xac','\xb6'},{'\xac','\xb3'},{'\xcf','\xb2'},{'\xcf','\xb1'},
+ {'\x00','\x00'},{'\xac','\xb1'},{'\xcf','\xb4'},{'\xcf','\xb5'},{'\x00','\x00'},
+ {'\xcf','\xae'},{'\xac','\xb5'},{'\x8a','\xbb'},{'\xac','\xb0'},{'\xa0','\x76'},
+ {'\x85','\xde'},{'\x88','\xf7'},{'\xcf','\xb0'},{'\x00','\x00'},{'\xa0','\x77'},
+ {'\x8b','\xa3'},{'\x8c','\x7a'},{'\x8d','\xd1'},{'\x9b','\xc3'},{'\xd2','\x77'},
+ {'\xd2','\x78'},{'\xd2','\x79'},{'\xaf','\x50'},{'\x00','\x00'},{'\xaf','\x4c'},
+ {'\xd2','\x6e'},{'\x9b','\xc4'},{'\xd2','\x76'},{'\xd2','\x7b'},{'\xaf','\x51'},
+ {'\x9b','\xc5'},{'\xd2','\x6c'},{'\xd2','\x72'},{'\xd2','\x6b'},{'\xd2','\x75'},
+ {'\xfc','\x57'},{'\x9b','\xc6'},{'\xd2','\x71'},{'\xaf','\x4d'},{'\xaf','\x4f'},
+ {'\xd2','\x7a'},{'\x89','\xf3'},{'\xd2','\x6a'},{'\xd2','\x6d'},{'\xd2','\x73'},
+ {'\x95','\xaf'},{'\xd2','\x74'},{'\xd2','\x7c'},{'\xd2','\x70'},{'\x00','\x00'},
+ {'\xaf','\x4e'},{'\x00','\x00'},{'\x85','\xdd'},{'\x88','\xf8'},{'\x8e','\xea'},
+ {'\x89','\xf4'},{'\x00','\x00'},{'\x88','\xfa'},{'\x8a','\xd8'},{'\x87','\xf1'},
+ {'\x00','\x00'},{'\xb2','\x6d'},{'\xd6','\x4e'},{'\x95','\x49'},{'\x00','\x00'},
+ {'\xd6','\x50'},{'\xd6','\x4c'},{'\x9c','\x40'},{'\xd6','\x58'},{'\xd6','\x4a'},
+ {'\xd6','\x57'},{'\xb2','\x69'},{'\xd6','\x48'},{'\xda','\x5b'},{'\xd6','\x52'},
+ {'\xb2','\x6c'},{'\x9c','\x4b'},{'\xd6','\x53'},{'\xd6','\x56'},{'\x00','\x00'},
+ {'\xd6','\x5a'},{'\x00','\x00'},{'\xd6','\x4f'},{'\x9c','\x4c'},{'\xd6','\x54'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb2','\x6a'},{'\xb2','\x6b'},{'\xd6','\x59'},
+ {'\xd6','\x4d'},{'\xd6','\x49'},{'\xd6','\x5b'},{'\xa0','\x78'},{'\xd6','\x51'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd6','\x55'},{'\x82','\x44'},{'\x85','\xe0'},
+ {'\x88','\xfb'},{'\xd6','\x4b'},{'\x8a','\xd9'},{'\xb5','\x48'},{'\xb5','\x49'},
+ {'\xda','\x65'},{'\xb5','\x4f'},{'\x9c','\x4d'},{'\xda','\x59'},{'\xda','\x62'},
+ {'\xda','\x58'},{'\xb5','\x4c'},{'\xda','\x60'},{'\xda','\x5e'},{'\x00','\x00'},
+ {'\xda','\x5f'},{'\xb5','\x4a'},{'\x00','\x00'},{'\xda','\x63'},{'\x9c','\x4e'},
+ {'\x00','\x00'},{'\x9c','\x4f'},{'\x9c','\x50'},{'\x00','\x00'},{'\xda','\x5c'},
+ {'\xda','\x5a'},{'\xb5','\x4b'},{'\xda','\x5d'},{'\xda','\x61'},{'\x9c','\x51'},
+ {'\xfc','\xa7'},{'\x9c','\x52'},{'\xb5','\x4d'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xda','\x64'},{'\x9c','\x53'},{'\x92','\xe5'},{'\x00','\x00'},
+ {'\x9c','\x54'},{'\xfe','\x76'},{'\x9c','\x55'},{'\xde','\x70'},{'\xde','\x77'},
+ {'\xde','\x79'},{'\xde','\xa1'},{'\xfb','\x66'},{'\xb7','\xda'},{'\xde','\x6b'},
+ {'\x00','\x00'},{'\xb7','\xd2'},{'\x95','\x4f'},{'\xde','\x7a'},{'\xb7','\xd7'},
+ {'\xde','\xa2'},{'\xb7','\xce'},{'\x9c','\x56'},{'\xde','\x7d'},{'\x95','\x5f'},
+ {'\xde','\x6d'},{'\xde','\x7e'},{'\xde','\x6c'},{'\xa0','\x7a'},{'\xb7','\xdc'},
+ {'\x9d','\xcd'},{'\xde','\x78'},{'\xb7','\xcf'},{'\xde','\xa3'},{'\x00','\x00'},
+ {'\xb7','\xd4'},{'\xde','\x71'},{'\xb7','\xd9'},{'\xde','\x7c'},{'\xde','\x6f'},
+ {'\xde','\x76'},{'\xde','\x72'},{'\xde','\x6e'},{'\xb7','\xd1'},{'\xb7','\xd8'},
+ {'\xb7','\xd6'},{'\xb7','\xd3'},{'\xb7','\xdb'},{'\xb7','\xd0'},{'\xde','\x75'},
+ {'\x9c','\x57'},{'\xb7','\xd5'},{'\x00','\x00'},{'\xb5','\x4e'},{'\x00','\x00'},
+ {'\xde','\x7b'},{'\xfe','\x53'},{'\xde','\x73'},{'\xa0','\x7b'},{'\x00','\x00'},
+ {'\x9c','\x58'},{'\xfc','\xa9'},{'\x9c','\x59'},{'\xde','\x74'},{'\x00','\x00'},
+ {'\xa0','\x7c'},{'\xe2','\xc1'},{'\x9c','\x5a'},{'\xba','\xb4'},{'\x9c','\x5b'},
+ {'\x00','\x00'},{'\xe2','\xbd'},{'\xe2','\xc3'},{'\xe2','\xbf'},{'\x00','\x00'},
+ {'\xba','\xb6'},{'\xe2','\xbe'},{'\xe2','\xc2'},{'\xe2','\xba'},{'\xa0','\xd8'},
+ {'\xe2','\xbc'},{'\xba','\xb5'},{'\x00','\x00'},{'\x9c','\x5c'},{'\x00','\x00'},
+ {'\x9c','\x5d'},{'\xe2','\xc0'},{'\xe2','\xbb'},{'\x9c','\x5e'},{'\xba','\xb7'},
+ {'\x00','\x00'},{'\xba','\xb2'},{'\x94','\xab'},{'\x9c','\x5f'},{'\xe2','\xc4'},
+ {'\xa0','\xe7'},{'\xba','\xb3'},{'\xe6','\x67'},{'\xe6','\x64'},{'\xe6','\x70'},
+ {'\xe6','\x6a'},{'\xe6','\x6c'},{'\xbc','\xf4'},{'\xe6','\x66'},{'\xe6','\x6e'},
+ {'\x9c','\x60'},{'\x9c','\x61'},{'\xe6','\x6d'},{'\xe6','\x6b'},{'\x00','\x00'},
+ {'\xe6','\x71'},{'\xbc','\xf7'},{'\xe6','\x68'},{'\xe6','\x6f'},{'\x00','\x00'},
+ {'\xbc','\xf5'},{'\x9c','\x62'},{'\x00','\x00'},{'\xe6','\x63'},{'\xe6','\x65'},
+ {'\xbc','\xf6'},{'\xe6','\x62'},{'\xe6','\x72'},{'\x9c','\x63'},{'\xe6','\x69'},
+ {'\x00','\x00'},{'\x9c','\x64'},{'\xea','\x4a'},{'\xbf','\x51'},{'\x9c','\x65'},
+ {'\x00','\x00'},{'\xea','\x55'},{'\xea','\x53'},{'\xbf','\x4b'},{'\xea','\x49'},
+ {'\xea','\x4c'},{'\xea','\x4d'},{'\xea','\x48'},{'\xbf','\x55'},{'\xbf','\x56'},
+ {'\xea','\x47'},{'\xea','\x56'},{'\xea','\x51'},{'\xbf','\x4f'},{'\xbf','\x4c'},
+ {'\xea','\x50'},{'\xea','\x4e'},{'\x00','\x00'},{'\x00','\x00'},{'\xbf','\x52'},
+ {'\xea','\x52'},{'\xbf','\x4d'},{'\x9c','\x66'},{'\xbf','\x4e'},{'\x00','\x00'},
+ {'\xea','\x4f'},{'\xbf','\x50'},{'\xea','\x4b'},{'\xa0','\xe8'},{'\xea','\x54'},
+ {'\xbf','\x53'},{'\xea','\x57'},{'\xea','\x58'},{'\xbf','\x54'},{'\x9c','\x67'},
+ {'\x00','\x00'},{'\xc0','\xe7'},{'\xc0','\xee'},{'\xed','\x5c'},{'\xed','\x62'},
+ {'\x00','\x00'},{'\xed','\x60'},{'\xc0','\xea'},{'\xc0','\xe9'},{'\xc0','\xe6'},
+ {'\xed','\x5e'},{'\x00','\x00'},{'\x00','\x00'},{'\x9c','\x68'},{'\xc0','\xec'},
+ {'\xc0','\xeb'},{'\xc0','\xe8'},{'\x00','\x00'},{'\xed','\x61'},{'\xed','\x5d'},
+ {'\xed','\x5f'},{'\x00','\x00'},{'\xc0','\xed'},{'\xa0','\xf5'},{'\xfb','\x70'},
+ {'\x00','\x00'},{'\xc2','\x77'},{'\xef','\xfb'},{'\x00','\x00'},{'\xc2','\x74'},
+ {'\xc2','\x75'},{'\xef','\xfd'},{'\xc2','\x76'},{'\xef','\xfa'},{'\x9c','\x69'},
+ {'\xef','\xf9'},{'\xf2','\x6c'},{'\xef','\xfc'},{'\x00','\x00'},{'\xf2','\x6d'},
+ {'\xc3','\x7a'},{'\xf2','\x6b'},{'\x00','\x00'},{'\x9c','\x6a'},{'\xf2','\x6a'},
+ {'\x00','\x00'},{'\xf2','\x69'},{'\xc3','\x7b'},{'\x9c','\x6b'},{'\x9c','\x6c'},
+ {'\xc4','\x6c'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x6a'},{'\xf4','\x6b'},
+ {'\xfc','\xac'},{'\x9c','\x6d'},{'\x9c','\x6e'},{'\x00','\x00'},{'\xf5','\xdc'},
+ {'\xf5','\xdb'},{'\xc4','\xea'},{'\x00','\x00'},{'\xf5','\xda'},{'\xf6','\xec'},
+ {'\xf6','\xed'},{'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xe6'},{'\xf8','\xb1'},
+ {'\x9c','\x6f'},{'\x9d','\x5a'},{'\xf8','\xf6'},{'\xf9','\xbc'},{'\xc6','\x79'},
+ {'\xf9','\xc6'},{'\xa4','\xf6'},{'\x91','\xc9'},{'\xaa','\xa6'},{'\xaa','\xa7'},
+ {'\x9c','\x71'},{'\x00','\x00'},{'\xac','\xb8'},{'\x85','\xc6'},{'\xfa','\x64'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xef'},{'\xa4','\xf7'},{'\x85','\xe1'},
+ {'\xaa','\xa8'},{'\xaf','\x52'},{'\xb7','\xdd'},{'\xa4','\xf8'},{'\xfa','\x65'},
+ {'\xb2','\x6e'},{'\xba','\xb8'},{'\xc9','\x62'},{'\x95','\xa7'},{'\xcf','\xb7'},
+ {'\xd2','\x7d'},{'\x00','\x00'},{'\xe2','\xc5'},{'\x00','\x00'},{'\xc0','\xf0'},
+ {'\xa4','\xf9'},{'\xaa','\xa9'},{'\xcf','\xb8'},{'\xcf','\xb9'},{'\xda','\x66'},
+ {'\xb5','\x50'},{'\x8b','\xa4'},{'\x00','\x00'},{'\xde','\xa4'},{'\xfc','\xad'},
+ {'\x00','\x00'},{'\xb7','\xde'},{'\xe2','\xc6'},{'\x00','\x00'},{'\x95','\x6e'},
+ {'\xbc','\xf8'},{'\x9c','\x73'},{'\xc3','\x7c'},{'\xa4','\xfa'},{'\xda','\x67'},
+ {'\xa4','\xfb'},{'\x9c','\x74'},{'\xa6','\xc9'},{'\xca','\x42'},{'\xa6','\xc8'},
+ {'\xa8','\x65'},{'\xa8','\x64'},{'\xa8','\x63'},{'\xcb','\x60'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfa','\x66'},{'\xaa','\xaa'},{'\x00','\x00'},{'\xaa','\xab'},
+ {'\xcd','\x5b'},{'\x00','\x00'},{'\xcf','\xba'},{'\x00','\x00'},{'\xcf','\xbd'},
+ {'\xac','\xba'},{'\xcf','\xbb'},{'\x00','\x00'},{'\xac','\xb9'},{'\xcf','\xbc'},
+ {'\xac','\xbb'},{'\x84','\x61'},{'\xd2','\xa2'},{'\xd2','\xa1'},{'\xd2','\x7e'},
+ {'\xaf','\x53'},{'\x8c','\x7b'},{'\xd6','\x5d'},{'\xd6','\x5e'},{'\xb2','\x6f'},
+ {'\xd6','\x5c'},{'\xd6','\x5f'},{'\xb5','\x52'},{'\xb2','\x70'},{'\xfa','\x67'},
+ {'\x00','\x00'},{'\xb5','\x51'},{'\xda','\x6b'},{'\xda','\x6a'},{'\xfc','\xae'},
+ {'\xda','\x68'},{'\xda','\x69'},{'\x8b','\xa5'},{'\xda','\x6c'},{'\xde','\xa6'},
+ {'\xde','\xa5'},{'\xde','\xa9'},{'\xfa','\x68'},{'\xde','\xa8'},{'\xde','\xa7'},
+ {'\xba','\xb9'},{'\xe2','\xc9'},{'\x9c','\x75'},{'\xe2','\xc8'},{'\xba','\xba'},
+ {'\xe2','\xc7'},{'\xe6','\x73'},{'\x00','\x00'},{'\xe6','\x74'},{'\xbc','\xf9'},
+ {'\x00','\x00'},{'\xea','\x59'},{'\xea','\x5a'},{'\xfa','\x69'},{'\x92','\x71'},
+ {'\xf2','\x72'},{'\xc3','\x7d'},{'\xf2','\x71'},{'\xf2','\x70'},{'\xf2','\x6e'},
+ {'\xf2','\x6f'},{'\xc4','\xeb'},{'\xf4','\x6c'},{'\xf6','\xee'},{'\xf8','\xf7'},
+ {'\x00','\x00'},{'\xa4','\xfc'},{'\xfa','\x6a'},{'\xc9','\xa5'},{'\xa5','\xc7'},
+ {'\xc9','\xa6'},{'\xfa','\x6b'},{'\xfc','\xb0'},{'\x00','\x00'},{'\xca','\x43'},
+ {'\xca','\x44'},{'\x83','\x5d'},{'\x8a','\xda'},{'\xfa','\x6c'},{'\x84','\xf6'},
+ {'\xcb','\x66'},{'\x00','\x00'},{'\x00','\x00'},{'\xcb','\x62'},{'\xfa','\x6d'},
+ {'\xcb','\x61'},{'\xaa','\xac'},{'\xcb','\x65'},{'\xa8','\x67'},{'\xcb','\x63'},
+ {'\xa8','\x66'},{'\xcb','\x67'},{'\xcb','\x64'},{'\x00','\x00'},{'\x83','\xc1'},
+ {'\xcd','\x5f'},{'\xcf','\xbe'},{'\xcd','\x5d'},{'\xcd','\x64'},{'\xfa','\x6e'},
+ {'\xaa','\xad'},{'\x00','\x00'},{'\xaa','\xb0'},{'\xcd','\x65'},{'\xcd','\x61'},
+ {'\x00','\x00'},{'\xcd','\x62'},{'\x00','\x00'},{'\xcd','\x5c'},{'\xaa','\xaf'},
+ {'\xcd','\x5e'},{'\xaa','\xae'},{'\xcd','\x63'},{'\xfa','\x6f'},{'\xcd','\x60'},
+ {'\x00','\x00'},{'\x89','\xf6'},{'\xcf','\xc2'},{'\xac','\xbd'},{'\xac','\xbe'},
+ {'\xfc','\xb1'},{'\xcf','\xc5'},{'\xcf','\xbf'},{'\x00','\x00'},{'\xcf','\xc4'},
+ {'\x00','\x00'},{'\xcf','\xc0'},{'\xac','\xbc'},{'\xcf','\xc3'},{'\xcf','\xc1'},
+ {'\x88','\xfc'},{'\x83','\xc0'},{'\x85','\xe2'},{'\x8e','\xec'},{'\x84','\x62'},
+ {'\x86','\xe2'},{'\x8e','\x47'},{'\xd2','\xa8'},{'\xd2','\xa5'},{'\x00','\x00'},
+ {'\xd2','\xa7'},{'\xaf','\x58'},{'\xaf','\x57'},{'\xaf','\x55'},{'\xd2','\xa4'},
+ {'\xd2','\xa9'},{'\xaf','\x54'},{'\xaf','\x56'},{'\xd2','\xa6'},{'\xd6','\x67'},
+ {'\xd2','\xa3'},{'\xd2','\xaa'},{'\xfc','\xb2'},{'\x8e','\xeb'},{'\x9c','\x76'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd6','\x62'},{'\xd6','\x66'},{'\x00','\x00'},
+ {'\xd6','\x65'},{'\xda','\x6e'},{'\xda','\x79'},{'\x00','\x00'},{'\x8a','\xdb'},
+ {'\xd6','\x68'},{'\x9c','\x77'},{'\xd6','\x63'},{'\xda','\x6d'},{'\xb2','\x74'},
+ {'\x00','\x00'},{'\x8f','\x55'},{'\xb2','\x73'},{'\xd6','\x61'},{'\xd6','\x64'},
+ {'\xb2','\x75'},{'\x00','\x00'},{'\xb2','\x72'},{'\xb2','\x71'},{'\xd6','\x60'},
+ {'\xd6','\x69'},{'\x93','\xe6'},{'\x00','\x00'},{'\x8c','\xd3'},{'\xda','\x70'},
+ {'\xda','\x77'},{'\xfa','\x70'},{'\xb5','\x54'},{'\xda','\x76'},{'\xda','\x73'},
+ {'\xfc','\xb4'},{'\xb5','\x56'},{'\x95','\xbd'},{'\x95','\xbc'},{'\xfc','\xaf'},
+ {'\xda','\x75'},{'\x95','\x52'},{'\xfa','\x71'},{'\xda','\x6f'},{'\xda','\x71'},
+ {'\xda','\x74'},{'\xda','\x72'},{'\xb5','\x55'},{'\xda','\x78'},{'\xb5','\x53'},
+ {'\xb7','\xdf'},{'\xfa','\x72'},{'\xfa','\x73'},{'\xde','\xad'},{'\xde','\xac'},
+ {'\xde','\xaa'},{'\x00','\x00'},{'\xb7','\xe2'},{'\xb7','\xe1'},{'\xde','\xae'},
+ {'\x9c','\x78'},{'\xde','\xab'},{'\xe2','\xca'},{'\xba','\xbb'},{'\xb7','\xe0'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xfc','\xb3'},{'\xde','\xb0'},{'\xde','\xaf'},
+ {'\x00','\x00'},{'\xe2','\xcd'},{'\xe2','\xcb'},{'\xbc','\xfa'},{'\xfc','\xb5'},
+ {'\xba','\xbc'},{'\xe2','\xcc'},{'\xe6','\x76'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbc','\xfb'},{'\xe6','\x75'},{'\xe6','\x7e'},
+ {'\xe6','\x7d'},{'\xe6','\x7b'},{'\x00','\x00'},{'\xe6','\x7a'},{'\xe6','\x77'},
+ {'\xe6','\x78'},{'\xe6','\x79'},{'\xe6','\x7c'},{'\xe6','\xa1'},{'\x92','\xde'},
+ {'\x00','\x00'},{'\xea','\x5f'},{'\xea','\x5c'},{'\xea','\x5d'},{'\xbf','\x57'},
+ {'\xea','\x5b'},{'\xea','\x61'},{'\xea','\x60'},{'\xea','\x5e'},{'\x8b','\xa7'},
+ {'\xed','\x64'},{'\xed','\x65'},{'\xc0','\xf1'},{'\xfc','\xb6'},{'\xc0','\xf2'},
+ {'\xed','\x63'},{'\x9c','\x79'},{'\xc2','\x79'},{'\xef','\xfe'},{'\xc2','\x78'},
+ {'\xc3','\x7e'},{'\x00','\x00'},{'\xc3','\xa1'},{'\xc4','\x6d'},{'\xf4','\x6e'},
+ {'\xf4','\x6d'},{'\xf5','\xdd'},{'\xf6','\xef'},{'\xc5','\x7a'},{'\xf7','\xe8'},
+ {'\xf7','\xe7'},{'\xf7','\xe9'},{'\xa5','\xc8'},{'\xcf','\xc6'},{'\xaf','\x59'},
+ {'\xb2','\x76'},{'\xd6','\x6a'},{'\xa5','\xc9'},{'\xc9','\xa7'},{'\xa4','\xfd'},
+ {'\x9c','\x7a'},{'\x00','\x00'},{'\xca','\x45'},{'\x9c','\x7b'},{'\x00','\x00'},
+ {'\x88','\xfd'},{'\xcb','\x6c'},{'\xcb','\x6a'},{'\xcb','\x6b'},{'\xcb','\x68'},
+ {'\xa8','\x68'},{'\xcb','\x69'},{'\x9c','\x7c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x86','\xe4'},{'\x9c','\x7d'},{'\xcd','\x6d'},{'\x9c','\x7e'},{'\xaa','\xb3'},
+ {'\xcd','\x6b'},{'\xcd','\x67'},{'\xcd','\x6a'},{'\x00','\x00'},{'\xcd','\x66'},
+ {'\xaa','\xb5'},{'\xcd','\x69'},{'\x9c','\xa1'},{'\xaa','\xb2'},{'\xaa','\xb1'},
+ {'\x9c','\xa2'},{'\xaa','\xb4'},{'\xcd','\x6c'},{'\xcd','\x68'},{'\x8e','\x48'},
+ {'\x89','\xf8'},{'\x84','\x63'},{'\x00','\x00'},{'\xac','\xc2'},{'\xac','\xc5'},
+ {'\xcf','\xce'},{'\xcf','\xcd'},{'\xcf','\xcc'},{'\xac','\xbf'},{'\xcf','\xd5'},
+ {'\xcf','\xcb'},{'\x8b','\xa8'},{'\xac','\xc1'},{'\xd2','\xaf'},{'\xfa','\x74'},
+ {'\xcf','\xd2'},{'\xcf','\xd0'},{'\xac','\xc4'},{'\x00','\x00'},{'\xcf','\xc8'},
+ {'\xcf','\xd3'},{'\x00','\x00'},{'\xcf','\xca'},{'\xcf','\xd4'},{'\xcf','\xd1'},
+ {'\xcf','\xc9'},{'\x95','\xbe'},{'\xac','\xc0'},{'\xcf','\xd6'},{'\xcf','\xc7'},
+ {'\xac','\xc3'},{'\xfa','\x75'},{'\x95','\xb6'},{'\x90','\xb2'},{'\x8b','\xfd'},
+ {'\xd2','\xb4'},{'\xd2','\xab'},{'\xd2','\xb6'},{'\x9c','\xa3'},{'\xd2','\xae'},
+ {'\xd2','\xb9'},{'\xd2','\xba'},{'\xd2','\xac'},{'\xd2','\xb8'},{'\xd2','\xb5'},
+ {'\xd2','\xb3'},{'\xd2','\xb7'},{'\xaf','\x5f'},{'\x00','\x00'},{'\xaf','\x5d'},
+ {'\x9c','\xa4'},{'\x9c','\xa5'},{'\xd2','\xb1'},{'\x9c','\xa6'},{'\xd2','\xad'},
+ {'\x9c','\xa7'},{'\xd2','\xb0'},{'\xd2','\xbb'},{'\xd2','\xb2'},{'\xaf','\x5e'},
+ {'\xcf','\xcf'},{'\x00','\x00'},{'\xaf','\x5a'},{'\xaf','\x5c'},{'\x9c','\xa8'},
+ {'\x00','\x00'},{'\xfa','\x76'},{'\x85','\xe4'},{'\x9c','\xa9'},{'\xd6','\x78'},
+ {'\xd6','\x6d'},{'\xd6','\x6b'},{'\xfe','\xaa'},{'\xd6','\x6c'},{'\x9c','\xab'},
+ {'\xd6','\x73'},{'\x9c','\xac'},{'\xd6','\x74'},{'\xd6','\x70'},{'\xb2','\x7b'},
+ {'\xd6','\x75'},{'\xd6','\x72'},{'\xd6','\x6f'},{'\x9c','\xad'},{'\xb2','\x79'},
+ {'\xd6','\x6e'},{'\xb2','\x77'},{'\xb2','\x7a'},{'\xd6','\x71'},{'\xd6','\x79'},
+ {'\xaf','\x5b'},{'\xb2','\x78'},{'\xd6','\x77'},{'\xd6','\x76'},{'\xb2','\x7c'},
+ {'\x00','\x00'},{'\x8e','\xbf'},{'\x86','\xe3'},{'\x9c','\xae'},{'\x9c','\xaf'},
+ {'\x00','\x00'},{'\x9c','\xb0'},{'\x9c','\xb1'},{'\xda','\x7e'},{'\x9c','\xb2'},
+ {'\x00','\x00'},{'\x9c','\xb3'},{'\xda','\xa1'},{'\xb5','\x60'},{'\x9c','\xb4'},
+ {'\xda','\xa7'},{'\x9c','\xb5'},{'\x9c','\xb6'},{'\xda','\xa9'},{'\xda','\xa2'},
+ {'\xb5','\x5a'},{'\xda','\xa6'},{'\xda','\xa5'},{'\xb5','\x5b'},{'\xb5','\x61'},
+ {'\x00','\x00'},{'\xb5','\x62'},{'\xda','\xa8'},{'\xb5','\x58'},{'\xda','\x7d'},
+ {'\xda','\x7b'},{'\xda','\xa3'},{'\xda','\x7a'},{'\xb5','\x5f'},{'\xda','\x7c'},
+ {'\xda','\xa4'},{'\xda','\xaa'},{'\xb5','\x59'},{'\xb5','\x5e'},{'\xb5','\x5c'},
+ {'\xb5','\x5d'},{'\x9c','\xb7'},{'\x9c','\xb8'},{'\x9c','\xb9'},{'\xb5','\x57'},
+ {'\x00','\x00'},{'\x8b','\xa9'},{'\x00','\x00'},{'\x00','\x00'},{'\xb7','\xe9'},
+ {'\xde','\xb7'},{'\xb7','\xe8'},{'\xde','\xbb'},{'\x9c','\xba'},{'\xde','\xb1'},
+ {'\x9c','\xbb'},{'\xde','\xbc'},{'\x9c','\xbc'},{'\x9c','\xbd'},{'\x9c','\xbe'},
+ {'\xde','\xb2'},{'\xde','\xb3'},{'\x00','\x00'},{'\xde','\xbd'},{'\xde','\xba'},
+ {'\xde','\xb8'},{'\xde','\xb9'},{'\xde','\xb5'},{'\xde','\xb4'},{'\x9c','\xbf'},
+ {'\xde','\xbe'},{'\xb7','\xe5'},{'\x9c','\xc0'},{'\xde','\xb6'},{'\x00','\x00'},
+ {'\xb7','\xea'},{'\xb7','\xe4'},{'\xb7','\xeb'},{'\xb7','\xec'},{'\xfc','\xb9'},
+ {'\xb7','\xe7'},{'\xb7','\xe6'},{'\xfe','\x75'},{'\x9d','\x73'},{'\xe2','\xce'},
+ {'\xba','\xbe'},{'\xba','\xbd'},{'\x9c','\xc1'},{'\x00','\x00'},{'\xe2','\xd3'},
+ {'\xfe','\xac'},{'\xbc','\xfc'},{'\xba','\xbf'},{'\x9c','\xc2'},{'\x9c','\xc3'},
+ {'\xba','\xc1'},{'\xe2','\xd4'},{'\xb7','\xe3'},{'\xba','\xc0'},{'\xe2','\xd0'},
+ {'\xe2','\xd2'},{'\xe2','\xcf'},{'\x9c','\xc4'},{'\xe2','\xd1'},{'\xfa','\x77'},
+ {'\x89','\xf9'},{'\x00','\x00'},{'\xe6','\xab'},{'\x9c','\xc5'},{'\x00','\x00'},
+ {'\xe6','\xaa'},{'\xe6','\xa7'},{'\xbd','\x40'},{'\xea','\x62'},{'\xbd','\x41'},
+ {'\xe6','\xa6'},{'\x9c','\xc6'},{'\xbc','\xfe'},{'\x00','\x00'},{'\xe6','\xa8'},
+ {'\xe6','\xa5'},{'\xe6','\xa2'},{'\xe6','\xa9'},{'\xe6','\xa3'},{'\xe6','\xa4'},
+ {'\xbc','\xfd'},{'\x81','\xd0'},{'\x81','\xd1'},{'\x8c','\x7d'},{'\x00','\x00'},
+ {'\xed','\x69'},{'\x00','\x00'},{'\xea','\x66'},{'\x00','\x00'},{'\xea','\x65'},
+ {'\xea','\x67'},{'\x00','\x00'},{'\xed','\x66'},{'\xbf','\x5a'},{'\x81','\xd2'},
+ {'\xea','\x63'},{'\x81','\xd3'},{'\xbf','\x58'},{'\x9d','\x74'},{'\xbf','\x5c'},
+ {'\xbf','\x5b'},{'\xea','\x64'},{'\xea','\x68'},{'\xfa','\x78'},{'\xbf','\x59'},
+ {'\x81','\xd4'},{'\xed','\x6d'},{'\xc0','\xf5'},{'\xc2','\x7a'},{'\xc0','\xf6'},
+ {'\xc0','\xf3'},{'\xed','\x6a'},{'\xed','\x68'},{'\x00','\x00'},{'\xed','\x6b'},
+ {'\x00','\x00'},{'\xed','\x6e'},{'\xc0','\xf4'},{'\xed','\x6c'},{'\xed','\x67'},
+ {'\x00','\x00'},{'\x81','\xd5'},{'\xf0','\x42'},{'\xf0','\x45'},{'\xf2','\x75'},
+ {'\xf0','\x40'},{'\x81','\xd6'},{'\xf4','\x6f'},{'\xf0','\x46'},{'\x00','\x00'},
+ {'\xc3','\xa2'},{'\xf0','\x44'},{'\xc2','\x7b'},{'\xf0','\x41'},{'\xf0','\x43'},
+ {'\xf0','\x47'},{'\xf2','\x76'},{'\x00','\x00'},{'\xf2','\x74'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x81','\xd7'},{'\x00','\x00'},{'\xc3','\xa3'},{'\xf2','\x73'},
+ {'\x81','\xd8'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x6e'},{'\x81','\xd9'},
+ {'\x00','\x00'},{'\x8c','\xf9'},{'\x81','\xda'},{'\xc4','\xed'},{'\xf6','\xf1'},
+ {'\xc4','\xec'},{'\xf6','\xf3'},{'\xf6','\xf0'},{'\xf6','\xf2'},{'\xc5','\xd0'},
+ {'\xf8','\xb2'},{'\xa5','\xca'},{'\xcd','\x6e'},{'\xd2','\xbc'},{'\xd2','\xbd'},
+ {'\xb2','\x7d'},{'\xde','\xbf'},{'\xbf','\x5d'},{'\xc3','\xa4'},{'\xc5','\x7b'},
+ {'\xf8','\xb3'},{'\xa5','\xcb'},{'\x94','\xac'},{'\xcd','\x6f'},{'\xa2','\x60'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xcf','\xd7'},{'\x00','\x00'},{'\xcf','\xd8'},
+ {'\x88','\xfe'},{'\x94','\xae'},{'\x94','\xaf'},{'\x94','\xad'},{'\x00','\x00'},
+ {'\xd2','\xbe'},{'\xd2','\xbf'},{'\xb2','\x7e'},{'\xb2','\xa1'},{'\x94','\xb0'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xda','\xab'},{'\x00','\x00'},{'\xde','\xc2'},
+ {'\xde','\xc1'},{'\xde','\xc0'},{'\xe2','\xd5'},{'\xfa','\x79'},{'\xe2','\xd6'},
+ {'\xe2','\xd7'},{'\xba','\xc2'},{'\x94','\xb1'},{'\x00','\x00'},{'\xe6','\xad'},
+ {'\xe6','\xac'},{'\x00','\x00'},{'\x00','\x00'},{'\xea','\x69'},{'\xbf','\x5e'},
+ {'\xbf','\x5f'},{'\x95','\xc2'},{'\xed','\x72'},{'\xed','\x6f'},{'\xed','\x70'},
+ {'\xed','\x71'},{'\xf0','\x49'},{'\xf0','\x48'},{'\xc2','\x7c'},{'\xf2','\x77'},
+ {'\xf5','\xde'},{'\xa5','\xcc'},{'\xfa','\x7a'},{'\xac','\xc6'},{'\x00','\x00'},
+ {'\xb2','\xa2'},{'\xde','\xc3'},{'\xfc','\xbb'},{'\xa5','\xcd'},{'\x00','\x00'},
+ {'\xd2','\xc0'},{'\xb2','\xa3'},{'\xfa','\x7b'},{'\x00','\x00'},{'\xb5','\x63'},
+ {'\xb5','\x64'},{'\x00','\x00'},{'\xa5','\xce'},{'\xa5','\xcf'},{'\xca','\x46'},
+ {'\xa8','\x6a'},{'\xa8','\x69'},{'\xac','\xc7'},{'\xcf','\xd9'},{'\xda','\xac'},
+ {'\xa5','\xd0'},{'\xa5','\xd1'},{'\xa5','\xd2'},{'\xa5','\xd3'},{'\xa0','\x59'},
+ {'\x86','\x7a'},{'\x00','\x00'},{'\xa8','\x6b'},{'\xa8','\x6c'},{'\xcb','\x6e'},
+ {'\xcb','\x6d'},{'\x84','\xf8'},{'\xfa','\x7c'},{'\xaa','\xb6'},{'\xcd','\x72'},
+ {'\xcd','\x70'},{'\xcd','\x71'},{'\x00','\x00'},{'\x81','\xdb'},{'\x00','\x00'},
+ {'\xfa','\x7d'},{'\x86','\xd0'},{'\xfb','\xd1'},{'\xcf','\xda'},{'\xcf','\xdb'},
+ {'\xfa','\x7e'},{'\x95','\xbf'},{'\xac','\xcb'},{'\xac','\xc9'},{'\xfa','\xa1'},
+ {'\xac','\xca'},{'\xac','\xc8'},{'\x00','\x00'},{'\x94','\x55'},{'\x00','\x00'},
+ {'\xfc','\xbc'},{'\xaf','\x60'},{'\x81','\xdc'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xaf','\x64'},{'\xaf','\x63'},{'\xd2','\xc1'},{'\xaf','\x62'},
+ {'\xaf','\x61'},{'\x00','\x00'},{'\xd2','\xc2'},{'\x94','\x56'},{'\x00','\x00'},
+ {'\xb2','\xa6'},{'\xd6','\x7b'},{'\xd6','\x7a'},{'\xb2','\xa4'},{'\xb2','\xa5'},
+ {'\x95','\xcc'},{'\x00','\x00'},{'\x94','\xb2'},{'\xb5','\x66'},{'\xb5','\x65'},
+ {'\xda','\xae'},{'\xfa','\xa2'},{'\x81','\xdd'},{'\xda','\xad'},{'\xb2','\xa7'},
+ {'\x00','\x00'},{'\x8d','\xe2'},{'\x92','\xec'},{'\x8b','\xaa'},{'\x00','\x00'},
+ {'\xb7','\xed'},{'\xde','\xc5'},{'\xb7','\xee'},{'\xde','\xc4'},{'\xfc','\xbd'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe2','\xd8'},{'\xe6','\xae'},{'\xbd','\x42'},
+ {'\xea','\x6a'},{'\x00','\x00'},{'\xfa','\xa3'},{'\xfa','\xa4'},{'\xed','\x73'},
+ {'\x00','\x00'},{'\xc3','\xa6'},{'\xc3','\xa5'},{'\x00','\x00'},{'\xfa','\xa5'},
+ {'\xc5','\x7c'},{'\xa5','\xd4'},{'\xcd','\x73'},{'\x81','\xde'},{'\x93','\x51'},
+ {'\xb2','\xa8'},{'\xe2','\xd9'},{'\xba','\xc3'},{'\xc6','\xd4'},{'\x00','\x00'},
+ {'\xcb','\x6f'},{'\xcb','\x70'},{'\x8f','\x78'},{'\x89','\xfb'},{'\xcd','\x74'},
+ {'\xaa','\xb8'},{'\xaa','\xb9'},{'\x00','\x00'},{'\x00','\x00'},{'\xaa','\xb7'},
+ {'\x81','\xdf'},{'\x86','\xe5'},{'\x8a','\xdd'},{'\x86','\xe6'},{'\xac','\xcf'},
+ {'\xac','\xd0'},{'\xac','\xcd'},{'\xac','\xce'},{'\x00','\x00'},{'\xcf','\xdc'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xcf','\xdd'},{'\xac','\xcc'},{'\xfa','\xa6'},
+ {'\x00','\x00'},{'\x87','\xf4'},{'\x86','\xe7'},{'\xd2','\xc3'},{'\xfe','\x51'},
+ {'\xaf','\x68'},{'\xaf','\x69'},{'\xfb','\x5c'},{'\xb2','\xab'},{'\xd2','\xc9'},
+ {'\x00','\x00'},{'\xaf','\x6e'},{'\xaf','\x6c'},{'\xd2','\xca'},{'\xd2','\xc5'},
+ {'\xaf','\x6b'},{'\xaf','\x6a'},{'\xaf','\x65'},{'\xd2','\xc8'},{'\xd2','\xc7'},
+ {'\xd2','\xc4'},{'\xaf','\x6d'},{'\xfc','\xd3'},{'\xd2','\xc6'},{'\xaf','\x66'},
+ {'\x00','\x00'},{'\xaf','\x67'},{'\x8f','\xfd'},{'\x84','\xf9'},{'\xb2','\xac'},
+ {'\xd6','\xa1'},{'\xd6','\xa2'},{'\xb2','\xad'},{'\xd6','\x7c'},{'\xd6','\x7e'},
+ {'\xd6','\xa4'},{'\xd6','\xa3'},{'\xd6','\x7d'},{'\x00','\x00'},{'\xb2','\xa9'},
+ {'\xb2','\xaa'},{'\xfa','\xa7'},{'\xda','\xb6'},{'\xb5','\x6b'},{'\xb5','\x6a'},
+ {'\xda','\xb0'},{'\xb5','\x68'},{'\x81','\xe0'},{'\xda','\xb3'},{'\xb5','\x6c'},
+ {'\xda','\xb4'},{'\xb5','\x6d'},{'\xda','\xb1'},{'\xb5','\x67'},{'\xb5','\x69'},
+ {'\xda','\xb5'},{'\x00','\x00'},{'\xda','\xb2'},{'\xda','\xaf'},{'\x89','\xfa'},
+ {'\xfa','\xa8'},{'\x86','\xe8'},{'\x8f','\x58'},{'\x00','\x00'},{'\xde','\xd2'},
+ {'\x00','\x00'},{'\xde','\xc7'},{'\xb7','\xf0'},{'\xb7','\xf3'},{'\xb7','\xf2'},
+ {'\xb7','\xf7'},{'\xb7','\xf6'},{'\xde','\xd3'},{'\xde','\xd1'},{'\xde','\xca'},
+ {'\xde','\xce'},{'\xde','\xcd'},{'\xb7','\xf4'},{'\xde','\xd0'},{'\xde','\xcc'},
+ {'\xde','\xd4'},{'\xde','\xcb'},{'\xb7','\xf5'},{'\xb7','\xef'},{'\xb7','\xf1'},
+ {'\xfc','\xd5'},{'\xde','\xc9'},{'\x00','\x00'},{'\x8f','\x57'},{'\x00','\x00'},
+ {'\xfc','\xd4'},{'\xe2','\xdb'},{'\xba','\xc7'},{'\xe2','\xdf'},{'\xba','\xc6'},
+ {'\xe2','\xdc'},{'\xba','\xc5'},{'\x00','\x00'},{'\xde','\xc8'},{'\xde','\xcf'},
+ {'\xe2','\xde'},{'\x00','\x00'},{'\xba','\xc8'},{'\xe2','\xe0'},{'\xe2','\xdd'},
+ {'\xe2','\xda'},{'\x8e','\xc1'},{'\x89','\x40'},{'\xe6','\xb1'},{'\xe6','\xb5'},
+ {'\xe6','\xb7'},{'\xe6','\xb3'},{'\xe6','\xb2'},{'\xe6','\xb0'},{'\xbd','\x45'},
+ {'\xbd','\x43'},{'\xbd','\x48'},{'\xbd','\x49'},{'\xe6','\xb4'},{'\xbd','\x46'},
+ {'\xe6','\xaf'},{'\xbd','\x47'},{'\xba','\xc4'},{'\xe6','\xb6'},{'\xbd','\x44'},
+ {'\x8b','\xab'},{'\x8d','\x54'},{'\x81','\xe1'},{'\xea','\x6c'},{'\x00','\x00'},
+ {'\xea','\x6b'},{'\xea','\x73'},{'\xea','\x6d'},{'\xea','\x72'},{'\xea','\x6f'},
+ {'\xbf','\x60'},{'\xea','\x71'},{'\x00','\x00'},{'\x00','\x00'},{'\xbf','\x61'},
+ {'\x00','\x00'},{'\xbf','\x62'},{'\x95','\xa9'},{'\xea','\x70'},{'\xea','\x6e'},
+ {'\x8c','\xd5'},{'\x90','\x58'},{'\xfa','\xa9'},{'\x00','\x00'},{'\xc0','\xf8'},
+ {'\xed','\x74'},{'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xf7'},{'\xed','\x77'},
+ {'\xed','\x75'},{'\xed','\x76'},{'\x00','\x00'},{'\x00','\x00'},{'\xc0','\xf9'},
+ {'\xfa','\xaa'},{'\x95','\x6f'},{'\x81','\xe2'},{'\xf0','\x4d'},{'\x81','\xe3'},
+ {'\xc2','\xa1'},{'\xf0','\x4e'},{'\xfa','\xab'},{'\x00','\x00'},{'\xc2','\x7d'},
+ {'\xf0','\x4f'},{'\xc2','\x7e'},{'\xf0','\x4c'},{'\xf0','\x50'},{'\x00','\x00'},
+ {'\xf0','\x4a'},{'\x00','\x00'},{'\x8c','\x7e'},{'\xc3','\xa7'},{'\xf2','\x78'},
+ {'\xc3','\xa8'},{'\xc4','\x6f'},{'\x8c','\xd6'},{'\xf0','\x4b'},{'\xc4','\x70'},
+ {'\xfb','\x76'},{'\xfc','\xd7'},{'\xfa','\xac'},{'\xc4','\xee'},{'\xf5','\xdf'},
+ {'\x8d','\x55'},{'\xc5','\x7e'},{'\xf6','\xf4'},{'\xc5','\x7d'},{'\xfc','\xd8'},
+ {'\xf7','\xea'},{'\xc5','\xf5'},{'\xc5','\xf6'},{'\x81','\xe4'},{'\x81','\xe5'},
+ {'\xf9','\xcc'},{'\xc6','\xd5'},{'\x00','\x00'},{'\xac','\xd1'},{'\xcf','\xde'},
+ {'\x93','\xb9'},{'\xb5','\x6e'},{'\xb5','\x6f'},{'\xa5','\xd5'},{'\xa6','\xca'},
+ {'\xca','\x47'},{'\xfa','\xad'},{'\xcb','\x71'},{'\xa8','\x6d'},{'\xfa','\xae'},
+ {'\xaa','\xba'},{'\x00','\x00'},{'\xac','\xd2'},{'\xac','\xd3'},{'\xac','\xd4'},
+ {'\xd6','\xa6'},{'\xd2','\xcb'},{'\xaf','\x6f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb2','\xae'},{'\xd6','\xa5'},{'\xfa','\xaf'},{'\x87','\xf5'},{'\xda','\xb8'},
+ {'\xb5','\x71'},{'\x00','\x00'},{'\xda','\xb7'},{'\xb5','\x70'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xde','\xd5'},{'\xbd','\x4a'},{'\xe6','\xbb'},{'\xe6','\xb8'},
+ {'\xe6','\xb9'},{'\xe6','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\xfc','\xbe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xed','\x78'},{'\x81','\xe6'},{'\xf0','\x51'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\x71'},{'\xf4','\x70'},
+ {'\x00','\x00'},{'\xf6','\xf5'},{'\xa5','\xd6'},{'\xcd','\x75'},{'\xaf','\x70'},
+ {'\x87','\xf6'},{'\x8e','\x77'},{'\x00','\x00'},{'\xb5','\x72'},{'\xde','\xd6'},
+ {'\x00','\x00'},{'\xfa','\xb0'},{'\xe2','\xe1'},{'\xfa','\xb1'},{'\xbd','\x4b'},
+ {'\xea','\x74'},{'\x00','\x00'},{'\xf0','\x52'},{'\xf4','\x72'},{'\xa5','\xd7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xaa','\xbb'},{'\xac','\xd7'},{'\xcf','\xdf'},
+ {'\xac','\xd8'},{'\xac','\xd6'},{'\x00','\x00'},{'\xac','\xd5'},{'\xd2','\xcc'},
+ {'\xaf','\x71'},{'\x00','\x00'},{'\xfc','\xbf'},{'\xaf','\x72'},{'\xaf','\x73'},
+ {'\x85','\xe6'},{'\x8d','\x69'},{'\x86','\xea'},{'\xb2','\xb0'},{'\xd6','\xa7'},
+ {'\xb2','\xaf'},{'\x00','\x00'},{'\x87','\x49'},{'\x84','\xfb'},{'\x87','\xf7'},
+ {'\x81','\xe7'},{'\xda','\xb9'},{'\xb2','\xb1'},{'\xb5','\x73'},{'\xde','\xd7'},
+ {'\xb7','\xf8'},{'\xb7','\xf9'},{'\x00','\x00'},{'\xba','\xc9'},{'\x00','\x00'},
+ {'\xba','\xca'},{'\xbd','\x4c'},{'\xbf','\x64'},{'\xea','\x75'},{'\xbf','\x63'},
+ {'\x00','\x00'},{'\xed','\x79'},{'\xc0','\xfa'},{'\x00','\x00'},{'\xf0','\x53'},
+ {'\xf4','\x73'},{'\xa5','\xd8'},{'\xa8','\x6e'},{'\xcd','\x78'},{'\xcd','\x77'},
+ {'\xaa','\xbc'},{'\xcd','\x76'},{'\xaa','\xbd'},{'\xcd','\x79'},{'\x00','\x00'},
+ {'\xcf','\xe5'},{'\xac','\xdb'},{'\xac','\xda'},{'\xcf','\xe7'},{'\xcf','\xe6'},
+ {'\xac','\xdf'},{'\x00','\x00'},{'\xac','\xde'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xac','\xd9'},{'\x00','\x00'},{'\xcf','\xe1'},{'\xcf','\xe2'},{'\xcf','\xe3'},
+ {'\x00','\x00'},{'\xac','\xe0'},{'\xcf','\xe0'},{'\xac','\xdc'},{'\xcf','\xe4'},
+ {'\xac','\xdd'},{'\x92','\xb1'},{'\xfa','\xb2'},{'\x81','\xe8'},{'\x81','\xe9'},
+ {'\xd2','\xcf'},{'\xd2','\xd3'},{'\xd2','\xd1'},{'\xd2','\xd0'},{'\x00','\x00'},
+ {'\xd2','\xd4'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xd2','\xd5'},
+ {'\xd2','\xd6'},{'\xd2','\xce'},{'\x00','\x00'},{'\xd2','\xcd'},{'\xfa','\xb3'},
+ {'\xaf','\x75'},{'\xaf','\x76'},{'\x00','\x00'},{'\xd2','\xd7'},{'\xd2','\xd2'},
+ {'\xfc','\xc0'},{'\xd6','\xb0'},{'\x8d','\xd2'},{'\xd2','\xd8'},{'\xaf','\x77'},
+ {'\xaf','\x74'},{'\x00','\x00'},{'\xfc','\xc1'},{'\x00','\x00'},{'\xd6','\xaa'},
+ {'\x00','\x00'},{'\xd6','\xa9'},{'\x00','\x00'},{'\xd6','\xab'},{'\xd6','\xac'},
+ {'\xd6','\xae'},{'\xd6','\xad'},{'\xd6','\xb2'},{'\xb2','\xb5'},{'\xb2','\xb2'},
+ {'\xb2','\xb6'},{'\xd6','\xa8'},{'\xb2','\xb7'},{'\xd6','\xb1'},{'\xb2','\xb4'},
+ {'\xd6','\xaf'},{'\xb2','\xb3'},{'\x00','\x00'},{'\x95','\x4d'},{'\x85','\xe8'},
+ {'\x00','\x00'},{'\xfa','\xb4'},{'\xda','\xbc'},{'\xda','\xbe'},{'\xda','\xba'},
+ {'\xda','\xbb'},{'\x00','\x00'},{'\x00','\x00'},{'\xda','\xbf'},{'\xda','\xc1'},
+ {'\xda','\xc2'},{'\xda','\xbd'},{'\xda','\xc0'},{'\xb5','\x74'},{'\x85','\xe7'},
+ {'\x8a','\xde'},{'\xde','\xdb'},{'\x00','\x00'},{'\xde','\xe0'},{'\xde','\xd8'},
+ {'\xde','\xdc'},{'\x00','\x00'},{'\x81','\xea'},{'\xde','\xe1'},{'\xde','\xdd'},
+ {'\xb7','\xfa'},{'\xb8','\x43'},{'\x00','\x00'},{'\xb7','\xfd'},{'\xde','\xd9'},
+ {'\xde','\xda'},{'\xba','\xce'},{'\xb8','\x46'},{'\xb7','\xfe'},{'\x00','\x00'},
+ {'\xb8','\x44'},{'\xb7','\xfc'},{'\xde','\xdf'},{'\xb8','\x45'},{'\xde','\xde'},
+ {'\xb8','\x41'},{'\xb7','\xfb'},{'\xb8','\x42'},{'\xde','\xe2'},{'\xe2','\xe6'},
+ {'\xe2','\xe8'},{'\x00','\x00'},{'\x00','\x00'},{'\x81','\xeb'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x81','\xec'},{'\x81','\xed'},
+ {'\xb8','\x40'},{'\x81','\xee'},{'\x81','\xef'},{'\xe2','\xe3'},{'\xba','\xcc'},
+ {'\xe2','\xe9'},{'\xba','\xcd'},{'\xe2','\xe7'},{'\xe2','\xe2'},{'\xe2','\xe5'},
+ {'\xe2','\xea'},{'\xba','\xcb'},{'\xe2','\xe4'},{'\x00','\x00'},{'\xbd','\x4e'},
+ {'\xe6','\xbf'},{'\xe6','\xbe'},{'\x00','\x00'},{'\xbd','\x51'},{'\xbd','\x4f'},
+ {'\xe6','\xbc'},{'\xbd','\x4d'},{'\xe6','\xbd'},{'\x00','\x00'},{'\xbd','\x50'},
+ {'\x89','\x42'},{'\xfb','\x6b'},{'\x00','\x00'},{'\xea','\x7d'},{'\x00','\x00'},
+ {'\xea','\xa1'},{'\x81','\xf0'},{'\xea','\x7e'},{'\xea','\x76'},{'\xea','\x7a'},
+ {'\xea','\x79'},{'\xea','\x77'},{'\xbf','\x66'},{'\xbf','\x67'},{'\xbf','\x65'},
+ {'\xea','\x78'},{'\xea','\x7b'},{'\xea','\x7c'},{'\x00','\x00'},{'\xbf','\x68'},
+ {'\x00','\x00'},{'\xc1','\x40'},{'\xed','\xa3'},{'\x8d','\x7c'},{'\xc0','\xfc'},
+ {'\xed','\x7b'},{'\xc0','\xfe'},{'\xc1','\x41'},{'\x00','\x00'},{'\x81','\xf1'},
+ {'\xc0','\xfd'},{'\xed','\xa2'},{'\xed','\x7c'},{'\xc0','\xfb'},{'\xed','\xa1'},
+ {'\xed','\x7a'},{'\xed','\x7e'},{'\xed','\x7d'},{'\x00','\x00'},{'\xfe','\x5a'},
+ {'\xf0','\x55'},{'\xc2','\xa4'},{'\xc2','\xa5'},{'\xc2','\xa2'},{'\x81','\xf2'},
+ {'\xc2','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x54'},{'\x81','\xf3'},
+ {'\xf2','\x7b'},{'\x81','\xf4'},{'\x00','\x00'},{'\xc3','\xa9'},{'\x00','\x00'},
+ {'\xf2','\x79'},{'\xf2','\x7a'},{'\x81','\xf5'},{'\xf4','\x74'},{'\xf4','\x77'},
+ {'\xf4','\x75'},{'\xf4','\x76'},{'\xf5','\xe0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc4','\xef'},{'\xf7','\xeb'},{'\xf8','\xb4'},{'\x00','\x00'},{'\xc5','\xf7'},
+ {'\xf8','\xf8'},{'\xf8','\xf9'},{'\xc6','\x66'},{'\xa5','\xd9'},{'\xac','\xe1'},
+ {'\x81','\xf6'},{'\xda','\xc3'},{'\x00','\x00'},{'\xde','\xe3'},{'\x00','\x00'},
+ {'\xa5','\xda'},{'\xa8','\x6f'},{'\x00','\x00'},{'\xaa','\xbe'},{'\x81','\xf7'},
+ {'\xcf','\xe8'},{'\xcf','\xe9'},{'\xaf','\x78'},{'\x00','\x00'},{'\x89','\xfc'},
+ {'\xda','\xc4'},{'\xb5','\x75'},{'\xb8','\x47'},{'\xc1','\x42'},{'\xed','\xa4'},
+ {'\xf2','\x7c'},{'\xf4','\x78'},{'\xa5','\xdb'},{'\x81','\xf8'},{'\x00','\x00'},
+ {'\x89','\xfe'},{'\xcd','\xa1'},{'\xcd','\x7a'},{'\xcd','\x7c'},{'\xcd','\x7e'},
+ {'\xcd','\x7d'},{'\xcd','\x7b'},{'\xaa','\xbf'},{'\x8c','\x41'},{'\x8b','\xfe'},
+ {'\x8e','\x78'},{'\x87','\xf9'},{'\xac','\xe2'},{'\xcf','\xf2'},{'\x00','\x00'},
+ {'\xcf','\xed'},{'\xcf','\xea'},{'\x00','\x00'},{'\x96','\x41'},{'\xcf','\xf1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xac','\xe4'},{'\xac','\xe5'},{'\xcf','\xf0'},
+ {'\xcf','\xef'},{'\xcf','\xee'},{'\xcf','\xeb'},{'\xcf','\xec'},{'\xcf','\xf3'},
+ {'\xac','\xe3'},{'\x92','\xc5'},{'\x89','\x43'},{'\x8d','\xe3'},{'\xfa','\xb5'},
+ {'\x00','\x00'},{'\x84','\xfc'},{'\x00','\x00'},{'\xfa','\xb6'},{'\xaf','\x7c'},
+ {'\x81','\xf9'},{'\xaf','\xa4'},{'\xaf','\xa3'},{'\xd2','\xe1'},{'\xd2','\xdb'},
+ {'\xd2','\xd9'},{'\x00','\x00'},{'\xaf','\xa1'},{'\xd6','\xb9'},{'\xaf','\x7a'},
+ {'\xd2','\xde'},{'\xd2','\xe2'},{'\xd2','\xe4'},{'\xd2','\xe0'},{'\xd2','\xda'},
+ {'\xaf','\xa2'},{'\xd2','\xdf'},{'\xd2','\xdd'},{'\xaf','\x79'},{'\xd2','\xe5'},
+ {'\xaf','\xa5'},{'\xd2','\xe3'},{'\xaf','\x7d'},{'\xd2','\xdc'},{'\x00','\x00'},
+ {'\xaf','\x7e'},{'\xaf','\x7b'},{'\xfa','\xb7'},{'\x8c','\x40'},{'\x90','\x42'},
+ {'\xfa','\xb8'},{'\x81','\xfa'},{'\x8c','\x42'},{'\x82','\x5f'},{'\x8a','\xdf'},
+ {'\x00','\x00'},{'\x81','\xfb'},{'\xb2','\xb9'},{'\x81','\xfc'},{'\xd6','\xba'},
+ {'\x00','\x00'},{'\xfa','\xb9'},{'\xd6','\xb3'},{'\xd6','\xb5'},{'\xd6','\xb7'},
+ {'\x81','\xfd'},{'\xd6','\xb8'},{'\xd6','\xb6'},{'\xb2','\xba'},{'\x00','\x00'},
+ {'\xd6','\xbb'},{'\x81','\xfe'},{'\xd6','\xb4'},{'\xfc','\xc3'},{'\x96','\x4b'},
+ {'\x86','\xeb'},{'\xfa','\xba'},{'\x8f','\x59'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xda','\xc8'},{'\xb5','\x76'},{'\xda','\xd0'},
+ {'\x00','\x00'},{'\xda','\xc5'},{'\x00','\x00'},{'\xda','\xd1'},{'\x00','\x00'},
+ {'\xda','\xc6'},{'\xda','\xc7'},{'\x96','\x4c'},{'\x00','\x00'},{'\xda','\xcf'},
+ {'\xda','\xce'},{'\xda','\xcb'},{'\xb2','\xb8'},{'\xb5','\x77'},{'\xda','\xc9'},
+ {'\xda','\xcc'},{'\xb5','\x78'},{'\xda','\xcd'},{'\xda','\xca'},{'\x94','\x54'},
+ {'\x00','\x00'},{'\x94','\xb4'},{'\x00','\x00'},{'\x00','\x00'},{'\x8d','\x68'},
+ {'\x00','\x00'},{'\xde','\xee'},{'\xfa','\xbb'},{'\xde','\xf2'},{'\xb8','\x4e'},
+ {'\x00','\x00'},{'\xe2','\xf0'},{'\xb8','\x51'},{'\xde','\xf0'},{'\xf9','\xd6'},
+ {'\x00','\x00'},{'\xde','\xed'},{'\xde','\xe8'},{'\xde','\xea'},{'\xde','\xeb'},
+ {'\xde','\xe4'},{'\x96','\x4d'},{'\xb8','\x4d'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb8','\x4c'},{'\x8b','\xac'},{'\xb8','\x48'},{'\xde','\xe7'},{'\x00','\x00'},
+ {'\xb8','\x4f'},{'\x00','\x00'},{'\xb8','\x50'},{'\xde','\xe6'},{'\xde','\xe9'},
+ {'\xde','\xf1'},{'\xb8','\x4a'},{'\xb8','\x4b'},{'\xde','\xef'},{'\xde','\xe5'},
+ {'\x89','\x44'},{'\x8e','\xed'},{'\x00','\x00'},{'\xe2','\xf2'},{'\xba','\xd0'},
+ {'\xe2','\xf4'},{'\xde','\xec'},{'\xe2','\xf6'},{'\xba','\xd4'},{'\xe2','\xf7'},
+ {'\xe2','\xf3'},{'\x00','\x00'},{'\xba','\xd1'},{'\xe2','\xef'},{'\xba','\xd3'},
+ {'\xe2','\xec'},{'\xe2','\xf1'},{'\xe2','\xf5'},{'\xe2','\xee'},{'\x00','\x00'},
+ {'\xfc','\xc7'},{'\xb8','\x49'},{'\x95','\xf0'},{'\xe2','\xeb'},{'\xba','\xd2'},
+ {'\xe2','\xed'},{'\xfa','\xbc'},{'\x96','\x4e'},{'\x00','\x00'},{'\x96','\xcd'},
+ {'\xfa','\xbd'},{'\xbd','\x54'},{'\xe6','\xc1'},{'\xbd','\x58'},{'\x00','\x00'},
+ {'\xbd','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\xba','\xcf'},{'\x00','\x00'},
+ {'\xe6','\xc8'},{'\xe6','\xc9'},{'\xbd','\x53'},{'\xfa','\xbe'},{'\x96','\x4f'},
+ {'\xe6','\xc7'},{'\xe6','\xca'},{'\xbd','\x55'},{'\xbd','\x52'},{'\xe6','\xc3'},
+ {'\xe6','\xc0'},{'\xe6','\xc5'},{'\xe6','\xc2'},{'\xbd','\x59'},{'\xe6','\xc4'},
+ {'\x96','\x50'},{'\xfc','\xc4'},{'\xe6','\xc6'},{'\xbd','\x57'},{'\x00','\x00'},
+ {'\x96','\x51'},{'\xfc','\xc5'},{'\xfa','\xbf'},{'\xbf','\x6a'},{'\xea','\xa8'},
+ {'\x00','\x00'},{'\xea','\xa2'},{'\xea','\xa6'},{'\xea','\xac'},{'\xea','\xad'},
+ {'\xea','\xa9'},{'\xea','\xaa'},{'\xea','\xa7'},{'\x96','\x54'},{'\xea','\xa4'},
+ {'\x00','\x00'},{'\xbf','\x6c'},{'\xbf','\x69'},{'\xea','\xa3'},{'\xea','\xa5'},
+ {'\x00','\x00'},{'\xbf','\x6b'},{'\xea','\xab'},{'\x96','\x55'},{'\xc1','\x46'},
+ {'\x96','\x56'},{'\x96','\x57'},{'\xed','\xaa'},{'\xed','\xa5'},{'\xc1','\x45'},
+ {'\x96','\x58'},{'\x00','\x00'},{'\xc1','\x43'},{'\x00','\x00'},{'\xed','\xac'},
+ {'\xc1','\x44'},{'\xed','\xa8'},{'\xed','\xa9'},{'\xed','\xa6'},{'\xed','\xad'},
+ {'\xf0','\x56'},{'\x00','\x00'},{'\xc1','\x47'},{'\xed','\xa7'},{'\x00','\x00'},
+ {'\xed','\xae'},{'\xed','\xab'},{'\xfb','\xa8'},{'\xfa','\xc0'},{'\x00','\x00'},
+ {'\xf0','\x5a'},{'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x57'},{'\x00','\x00'},
+ {'\xc2','\xa6'},{'\x00','\x00'},{'\xf0','\x5b'},{'\xf0','\x5d'},{'\xf0','\x5c'},
+ {'\xf0','\x58'},{'\xf0','\x59'},{'\x00','\x00'},{'\x00','\x00'},{'\xf2','\xa3'},
+ {'\x00','\x00'},{'\xc3','\xaa'},{'\x00','\x00'},{'\xf2','\x7e'},{'\xf2','\xa2'},
+ {'\xf2','\x7d'},{'\xf2','\xa4'},{'\x00','\x00'},{'\x00','\x00'},{'\xf2','\xa1'},
+ {'\x00','\x00'},{'\xf4','\x7a'},{'\xf4','\x7d'},{'\xf4','\x79'},{'\xc4','\x71'},
+ {'\xf4','\x7b'},{'\xf4','\x7c'},{'\xf4','\x7e'},{'\xc4','\x72'},{'\xc4','\x74'},
+ {'\xc4','\x73'},{'\xf5','\xe1'},{'\xfe','\x77'},{'\xf5','\xe3'},{'\xfa','\xc1'},
+ {'\xf5','\xe2'},{'\x96','\x59'},{'\x96','\x5a'},{'\xfa','\xc2'},{'\xf6','\xf6'},
+ {'\x96','\x5b'},{'\x00','\x00'},{'\xf8','\xb5'},{'\xf8','\xfa'},{'\xa5','\xdc'},
+ {'\xfa','\xc3'},{'\x8a','\xe0'},{'\xcb','\x72'},{'\xaa','\xc0'},{'\xcd','\xa3'},
+ {'\xaa','\xc1'},{'\xaa','\xc2'},{'\xcd','\xa2'},{'\x00','\x00'},{'\xcf','\xf8'},
+ {'\xcf','\xf7'},{'\xac','\xe6'},{'\xac','\xe9'},{'\xac','\xe8'},{'\xac','\xe7'},
+ {'\xcf','\xf4'},{'\xcf','\xf6'},{'\xcf','\xf5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd2','\xe8'},{'\xaf','\xa7'},{'\xd2','\xec'},{'\xd2','\xeb'},{'\xd2','\xea'},
+ {'\xd2','\xe6'},{'\xaf','\xa6'},{'\xaf','\xaa'},{'\xaf','\xad'},{'\x96','\x5c'},
+ {'\x96','\x5e'},{'\xaf','\xae'},{'\xd2','\xe7'},{'\xd2','\xe9'},{'\xaf','\xac'},
+ {'\xaf','\xab'},{'\xaf','\xa9'},{'\xaf','\xa8'},{'\xd6','\xc2'},{'\x8f','\xbe'},
+ {'\xd6','\xc0'},{'\xd6','\xbc'},{'\xb2','\xbb'},{'\x00','\x00'},{'\xd6','\xbd'},
+ {'\xb2','\xbc'},{'\xd6','\xbe'},{'\xd6','\xbf'},{'\xd6','\xc1'},{'\x00','\x00'},
+ {'\xb2','\xbd'},{'\x00','\x00'},{'\x86','\xec'},{'\xda','\xd5'},{'\x96','\x5f'},
+ {'\xda','\xd4'},{'\xda','\xd3'},{'\xda','\xd2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x82','\x70'},{'\x86','\xed'},{'\xde','\xf6'},{'\xb8','\x52'},{'\x00','\x00'},
+ {'\xde','\xf3'},{'\xde','\xf5'},{'\x96','\x60'},{'\xb8','\x53'},{'\xfa','\xc4'},
+ {'\xb8','\x54'},{'\xde','\xf4'},{'\x96','\x61'},{'\x82','\x77'},{'\x93','\x50'},
+ {'\x96','\x62'},{'\x96','\x63'},{'\xe3','\x41'},{'\x00','\x00'},{'\xe2','\xf9'},
+ {'\xe2','\xfa'},{'\x00','\x00'},{'\xba','\xd7'},{'\xba','\xd5'},{'\xba','\xd6'},
+ {'\xe3','\x43'},{'\x96','\x64'},{'\xe3','\x42'},{'\xe2','\xfe'},{'\xe2','\xfd'},
+ {'\xe2','\xfc'},{'\xe2','\xfb'},{'\xe3','\x40'},{'\xe2','\xf8'},{'\x96','\x65'},
+ {'\xe6','\xcb'},{'\xe6','\xd0'},{'\xe6','\xce'},{'\xfa','\xc5'},{'\x00','\x00'},
+ {'\x96','\x66'},{'\xe6','\xcd'},{'\xe6','\xcc'},{'\xe6','\xcf'},{'\x00','\x00'},
+ {'\xea','\xae'},{'\x96','\x67'},{'\xbf','\x6d'},{'\xc1','\x48'},{'\xed','\xb0'},
+ {'\xfc','\xca'},{'\xc1','\x49'},{'\xed','\xaf'},{'\xf0','\x5f'},{'\xf0','\x5e'},
+ {'\xc2','\xa7'},{'\x00','\x00'},{'\xf2','\xa5'},{'\xc3','\xab'},{'\xf4','\xa1'},
+ {'\xc5','\xa1'},{'\xf6','\xf7'},{'\x00','\x00'},{'\xf8','\xb7'},{'\xf8','\xb6'},
+ {'\xc9','\xa8'},{'\xac','\xea'},{'\xac','\xeb'},{'\xd6','\xc3'},{'\x00','\x00'},
+ {'\xb8','\x56'},{'\xa5','\xdd'},{'\xa8','\x72'},{'\xa8','\x71'},{'\xa8','\x70'},
+ {'\x00','\x00'},{'\xfa','\xc6'},{'\xfb','\xa9'},{'\xcd','\xa4'},{'\x84','\xfd'},
+ {'\x00','\x00'},{'\xaa','\xc4'},{'\xaa','\xc3'},{'\x9d','\xce'},{'\xac','\xee'},
+ {'\xfc','\xa6'},{'\xcf','\xfa'},{'\xcf','\xfd'},{'\xcf','\xfb'},{'\x00','\x00'},
+ {'\xac','\xec'},{'\xac','\xed'},{'\x00','\x00'},{'\xfc','\xcc'},{'\xcf','\xf9'},
+ {'\xcf','\xfc'},{'\x00','\x00'},{'\xaf','\xb5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd2','\xf3'},{'\xd2','\xf5'},{'\xd2','\xf4'},{'\xaf','\xb2'},
+ {'\xd2','\xef'},{'\xfa','\xc7'},{'\x96','\x68'},{'\xaf','\xb0'},{'\xaf','\xaf'},
+ {'\x00','\x00'},{'\xaf','\xb3'},{'\xaf','\xb1'},{'\x00','\x00'},{'\xaf','\xb4'},
+ {'\xd2','\xf2'},{'\xd2','\xed'},{'\xd2','\xee'},{'\xd2','\xf1'},{'\xd2','\xf0'},
+ {'\x85','\xb8'},{'\x86','\xef'},{'\x96','\x69'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x96','\x6a'},{'\x00','\x00'},{'\xd6','\xc6'},{'\xd6','\xc7'},{'\xd6','\xc5'},
+ {'\x00','\x00'},{'\xd6','\xc4'},{'\xb2','\xbe'},{'\x00','\x00'},{'\x8a','\xe2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb5','\x7d'},{'\x00','\x00'},{'\xda','\xd6'},
+ {'\xda','\xd8'},{'\xda','\xda'},{'\xb5','\x7c'},{'\xfa','\xc8'},{'\x00','\x00'},
+ {'\xb5','\x7a'},{'\x00','\x00'},{'\xda','\xd7'},{'\xb5','\x7b'},{'\xda','\xd9'},
+ {'\xb5','\x79'},{'\xfa','\xc9'},{'\x00','\x00'},{'\xdf','\x41'},{'\xde','\xf7'},
+ {'\xde','\xfa'},{'\xde','\xfe'},{'\xb8','\x5a'},{'\xde','\xfc'},{'\x00','\x00'},
+ {'\xde','\xfb'},{'\xde','\xf8'},{'\xde','\xf9'},{'\xb8','\x58'},{'\xdf','\x40'},
+ {'\xb8','\x57'},{'\x00','\x00'},{'\xb8','\x5c'},{'\xb8','\x5b'},{'\xb8','\x59'},
+ {'\x00','\x00'},{'\xde','\xfd'},{'\x89','\x47'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe3','\x49'},{'\x00','\x00'},{'\xe3','\x48'},{'\x00','\x00'},{'\x96','\x6b'},
+ {'\xe3','\x44'},{'\x00','\x00'},{'\xfc','\xce'},{'\xba','\xd8'},{'\xe3','\x47'},
+ {'\xe3','\x46'},{'\xba','\xd9'},{'\x93','\xa6'},{'\x8b','\xae'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbd','\x5e'},{'\x00','\x00'},{'\xe6','\xd2'},
+ {'\x96','\x6c'},{'\xbd','\x5f'},{'\xbd','\x5b'},{'\xbd','\x5d'},{'\xfc','\xcf'},
+ {'\xbd','\x5a'},{'\xbd','\x5c'},{'\x00','\x00'},{'\x92','\xf9'},{'\xfa','\xca'},
+ {'\xea','\xaf'},{'\x96','\x6d'},{'\xbf','\x70'},{'\xea','\xb1'},{'\xea','\xb0'},
+ {'\xfc','\xd0'},{'\xe3','\x45'},{'\xbf','\x72'},{'\xbf','\x71'},{'\xbf','\x6e'},
+ {'\xbf','\x6f'},{'\x92','\x53'},{'\xfa','\xcb'},{'\x8a','\xe1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xed','\xb5'},{'\x00','\x00'},{'\xed','\xb3'},{'\xc1','\x4a'},
+ {'\xed','\xb4'},{'\x00','\x00'},{'\xed','\xb6'},{'\xed','\xb2'},{'\xed','\xb1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x60'},{'\xc2','\xaa'},{'\xc2','\xa8'},
+ {'\xc2','\xa9'},{'\x82','\x67'},{'\x00','\x00'},{'\x96','\x6e'},{'\x00','\x00'},
+ {'\xf2','\xa6'},{'\xf2','\xa7'},{'\xc3','\xad'},{'\x00','\x00'},{'\xc3','\xac'},
+ {'\xf4','\xa3'},{'\xf4','\xa4'},{'\xf4','\xa2'},{'\x00','\x00'},{'\xf6','\xf8'},
+ {'\xf6','\xf9'},{'\x00','\x00'},{'\x00','\x00'},{'\xa5','\xde'},{'\xca','\x48'},
+ {'\xa8','\x73'},{'\x87','\xfb'},{'\xcd','\xa5'},{'\xaa','\xc6'},{'\xaa','\xc5'},
+ {'\xcd','\xa6'},{'\x00','\x00'},{'\xfc','\x42'},{'\xd0','\x40'},{'\xac','\xef'},
+ {'\xcf','\xfe'},{'\xac','\xf0'},{'\x00','\x00'},{'\x8c','\xfa'},{'\xaf','\xb6'},
+ {'\xd2','\xf8'},{'\xd2','\xf6'},{'\xd2','\xfc'},{'\xaf','\xb7'},{'\xd2','\xf7'},
+ {'\xd2','\xfb'},{'\xd2','\xf9'},{'\xd2','\xfa'},{'\x8a','\xe4'},{'\x00','\x00'},
+ {'\xd6','\xc8'},{'\xd6','\xca'},{'\x87','\xfa'},{'\xb2','\xbf'},{'\x93','\x58'},
+ {'\xd6','\xc9'},{'\xb2','\xc0'},{'\xb5','\xa2'},{'\xb5','\xa1'},{'\xb5','\x7e'},
+ {'\xda','\xdb'},{'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xe3'},{'\x86','\xf1'},
+ {'\xdf','\x44'},{'\xb8','\x5d'},{'\xb8','\x5e'},{'\x00','\x00'},{'\xdf','\x43'},
+ {'\xdf','\x42'},{'\x00','\x00'},{'\x89','\x48'},{'\x8c','\x43'},{'\x00','\x00'},
+ {'\xe3','\x4a'},{'\xba','\xdb'},{'\xba','\xda'},{'\xe3','\x4b'},{'\xe3','\x4c'},
+ {'\x8e','\xee'},{'\xbd','\x61'},{'\xbd','\x60'},{'\xfe','\xa7'},{'\xea','\xb5'},
+ {'\xe6','\xd3'},{'\xe6','\xd5'},{'\xe6','\xd4'},{'\xea','\xb4'},{'\xea','\xb2'},
+ {'\xea','\xb6'},{'\xea','\xb3'},{'\x00','\x00'},{'\xbf','\x73'},{'\xfc','\x44'},
+ {'\x96','\x6f'},{'\x00','\x00'},{'\xed','\xb7'},{'\xc1','\x4b'},{'\xed','\xb8'},
+ {'\xed','\xb9'},{'\x96','\x70'},{'\xfa','\xcc'},{'\xc2','\xab'},{'\xc2','\xac'},
+ {'\x00','\x00'},{'\xc4','\x75'},{'\xfd','\xe5'},{'\x96','\x71'},{'\xc5','\xd1'},
+ {'\xa5','\xdf'},{'\x00','\x00'},{'\x94','\xb5'},{'\x00','\x00'},{'\x94','\xb6'},
+ {'\x00','\x00'},{'\xd0','\x41'},{'\xfa','\xcd'},{'\x94','\xb8'},{'\x00','\x00'},
+ {'\x94','\xb7'},{'\x88','\x67'},{'\x00','\x00'},{'\xd2','\xfd'},{'\xaf','\xb8'},
+ {'\xfc','\xd2'},{'\x96','\x72'},{'\x93','\xe2'},{'\xfc','\xd1'},{'\x8c','\x44'},
+ {'\xb3','\xba'},{'\xb3','\xb9'},{'\x94','\xb9'},{'\xfa','\xce'},{'\xb5','\xa4'},
+ {'\xda','\xdd'},{'\xb5','\xa3'},{'\xda','\xdc'},{'\xfa','\xcf'},{'\x00','\x00'},
+ {'\x96','\x73'},{'\x82','\x6d'},{'\xdf','\x45'},{'\x00','\x00'},{'\xba','\xdc'},
+ {'\xe3','\x4d'},{'\xba','\xdd'},{'\x94','\xba'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x76'},{'\xf4','\xa5'},
+ {'\xfa','\xd0'},{'\xa6','\xcb'},{'\xaa','\xc7'},{'\xcd','\xa7'},{'\x00','\x00'},
+ {'\xac','\xf2'},{'\x96','\x74'},{'\xac','\xf1'},{'\xd0','\x42'},{'\xd0','\x43'},
+ {'\x94','\xbb'},{'\x89','\x49'},{'\xd3','\x40'},{'\xd3','\x42'},{'\xaf','\xb9'},
+ {'\x00','\x00'},{'\xd3','\x44'},{'\xd3','\x47'},{'\xd3','\x45'},{'\x85','\x41'},
+ {'\x96','\x75'},{'\x00','\x00'},{'\xd3','\x46'},{'\xd3','\x43'},{'\xd2','\xfe'},
+ {'\xaf','\xba'},{'\xd3','\x48'},{'\xd3','\x41'},{'\x85','\x40'},{'\x85','\xec'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd6','\xd3'},{'\xb2','\xc6'},{'\xd6','\xdc'},
+ {'\xb2','\xc3'},{'\x00','\x00'},{'\xd6','\xd5'},{'\xb2','\xc7'},{'\xfc','\xdc'},
+ {'\xb2','\xc1'},{'\x00','\x00'},{'\xd6','\xd0'},{'\xd6','\xdd'},{'\xd6','\xd1'},
+ {'\xd6','\xce'},{'\xb2','\xc5'},{'\x96','\x76'},{'\xb2','\xc2'},{'\x96','\x77'},
+ {'\xd6','\xd4'},{'\xd6','\xd7'},{'\xb2','\xc4'},{'\xd6','\xd8'},{'\xb2','\xc8'},
+ {'\xd6','\xd9'},{'\xd6','\xcf'},{'\xd6','\xd6'},{'\xd6','\xda'},{'\xd6','\xd2'},
+ {'\xd6','\xcd'},{'\xd6','\xcb'},{'\xfa','\xd1'},{'\x00','\x00'},{'\xd6','\xdb'},
+ {'\xfe','\x64'},{'\x86','\xf2'},{'\xda','\xdf'},{'\x8c','\xd7'},{'\x00','\x00'},
+ {'\x90','\x7a'},{'\x00','\x00'},{'\xda','\xe4'},{'\x00','\x00'},{'\x96','\x78'},
+ {'\x96','\x79'},{'\xda','\xe0'},{'\xda','\xe6'},{'\xb5','\xa7'},{'\xd6','\xcc'},
+ {'\xda','\xe1'},{'\xb5','\xa5'},{'\xda','\xde'},{'\xb5','\xac'},{'\xda','\xe2'},
+ {'\xb5','\xab'},{'\xda','\xe3'},{'\xb5','\xad'},{'\xb5','\xa8'},{'\xb5','\xae'},
+ {'\xb5','\xa9'},{'\x00','\x00'},{'\xb5','\xaa'},{'\x96','\x7a'},{'\xb5','\xa6'},
+ {'\x00','\x00'},{'\xda','\xe5'},{'\x00','\x00'},{'\x8f','\x5b'},{'\x89','\x4a'},
+ {'\x00','\x00'},{'\x86','\xf3'},{'\x00','\x00'},{'\x00','\x00'},{'\xb8','\x61'},
+ {'\xdf','\x50'},{'\xfa','\xd2'},{'\xdf','\x53'},{'\xdf','\x47'},{'\xdf','\x4c'},
+ {'\xdf','\x46'},{'\xb8','\x63'},{'\x00','\x00'},{'\xdf','\x4a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xfa','\xd3'},{'\xdf','\x48'},{'\xb8','\x62'},{'\x96','\x7b'},
+ {'\xdf','\x4f'},{'\xdf','\x4e'},{'\xdf','\x4b'},{'\xdf','\x4d'},{'\xdf','\x49'},
+ {'\xba','\xe1'},{'\xdf','\x52'},{'\xb8','\x5f'},{'\xdf','\x51'},{'\x8c','\x45'},
+ {'\xfa','\xd4'},{'\xfa','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x8b','\xaf'},
+ {'\x00','\x00'},{'\x8a','\xe9'},{'\x00','\x00'},{'\xe3','\x5d'},{'\x00','\x00'},
+ {'\xba','\xe8'},{'\xe3','\x58'},{'\x82','\x7a'},{'\xba','\xe7'},{'\xe3','\x4e'},
+ {'\x00','\x00'},{'\xe3','\x50'},{'\xba','\xe0'},{'\xe3','\x55'},{'\xe3','\x54'},
+ {'\xe3','\x57'},{'\xba','\xe5'},{'\xe3','\x52'},{'\xe3','\x51'},{'\xfc','\xdd'},
+ {'\x00','\x00'},{'\xba','\xe4'},{'\xba','\xdf'},{'\xe3','\x53'},{'\xba','\xe2'},
+ {'\xe3','\x59'},{'\xe3','\x5b'},{'\xfa','\xd6'},{'\xe3','\x56'},{'\xe3','\x4f'},
+ {'\xba','\xe3'},{'\xfa','\xd7'},{'\xfa','\xd8'},{'\xbd','\x69'},{'\xba','\xde'},
+ {'\xfa','\xd9'},{'\xfc','\xde'},{'\xe3','\x5c'},{'\x00','\x00'},{'\x8f','\x5a'},
+ {'\xfa','\xda'},{'\x90','\x59'},{'\x8d','\x71'},{'\x8a','\xe7'},{'\x8a','\xe5'},
+ {'\xe6','\xd9'},{'\xbd','\x62'},{'\x00','\x00'},{'\xe6','\xdb'},{'\x00','\x00'},
+ {'\xbd','\x63'},{'\x96','\x7c'},{'\x00','\x00'},{'\xbd','\x65'},{'\xe6','\xde'},
+ {'\x00','\x00'},{'\xe6','\xd6'},{'\xba','\xe6'},{'\xe6','\xdc'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xe6','\xd8'},{'\x00','\x00'},
+ {'\xb8','\x60'},{'\xbd','\x68'},{'\x00','\x00'},{'\x00','\x00'},{'\xbd','\x64'},
+ {'\x00','\x00'},{'\xbd','\x66'},{'\xbd','\x67'},{'\x00','\x00'},{'\xbf','\x76'},
+ {'\xe6','\xdd'},{'\xe6','\xd7'},{'\xbd','\x6a'},{'\x00','\x00'},{'\xe6','\xda'},
+ {'\xfc','\xdf'},{'\x96','\xd0'},{'\x8a','\xe8'},{'\x00','\x00'},{'\x8a','\x40'},
+ {'\xea','\xc0'},{'\xea','\xbb'},{'\x00','\x00'},{'\x00','\x00'},{'\xea','\xc5'},
+ {'\xbf','\x74'},{'\xea','\xbd'},{'\xbf','\x78'},{'\xea','\xc3'},{'\xea','\xba'},
+ {'\xea','\xb7'},{'\xea','\xc6'},{'\xc1','\x51'},{'\xbf','\x79'},{'\xea','\xc2'},
+ {'\xea','\xb8'},{'\xbf','\x77'},{'\xea','\xbc'},{'\xbf','\x7b'},{'\xea','\xb9'},
+ {'\xea','\xbe'},{'\xbf','\x7a'},{'\xea','\xc1'},{'\xea','\xc4'},{'\x96','\xd1'},
+ {'\x82','\xa1'},{'\x8c','\x46'},{'\x00','\x00'},{'\xed','\xcb'},{'\xed','\xcc'},
+ {'\xed','\xbc'},{'\xed','\xc3'},{'\xed','\xc1'},{'\x00','\x00'},{'\xfa','\xdb'},
+ {'\xc1','\x4f'},{'\xed','\xc8'},{'\xea','\xbf'},{'\x96','\xd2'},{'\xed','\xbf'},
+ {'\xfc','\xe1'},{'\xed','\xc9'},{'\xc1','\x4e'},{'\xed','\xbe'},{'\xed','\xbd'},
+ {'\xed','\xc7'},{'\xed','\xc4'},{'\xed','\xc6'},{'\x00','\x00'},{'\xed','\xba'},
+ {'\xed','\xca'},{'\xc1','\x4c'},{'\x00','\x00'},{'\xed','\xc5'},{'\xed','\xce'},
+ {'\xed','\xc2'},{'\xc1','\x50'},{'\xc1','\x4d'},{'\xed','\xc0'},{'\xed','\xbb'},
+ {'\xed','\xcd'},{'\xbf','\x75'},{'\xfa','\xdc'},{'\x94','\xbc'},{'\xfa','\xdd'},
+ {'\x96','\xd3'},{'\x90','\x77'},{'\x94','\xbd'},{'\x00','\x00'},{'\xf0','\x63'},
+ {'\x00','\x00'},{'\x96','\xd4'},{'\xf0','\x61'},{'\xf0','\x67'},{'\xc2','\xb0'},
+ {'\xf0','\x65'},{'\xf0','\x64'},{'\xc2','\xb2'},{'\xf0','\x6a'},{'\xc2','\xb1'},
+ {'\x00','\x00'},{'\xf0','\x6b'},{'\xf0','\x68'},{'\xc2','\xae'},{'\xf0','\x69'},
+ {'\xf0','\x62'},{'\xc2','\xaf'},{'\xc2','\xad'},{'\xf2','\xab'},{'\xf0','\x66'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf0','\x6c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf2','\xa8'},{'\x00','\x00'},{'\x96','\xd5'},{'\x00','\x00'},{'\xc3','\xb2'},
+ {'\xc3','\xb0'},{'\xf2','\xaa'},{'\x00','\x00'},{'\xf2','\xac'},{'\xf2','\xa9'},
+ {'\xc3','\xb1'},{'\xc3','\xae'},{'\xc3','\xaf'},{'\xc3','\xb3'},{'\x8c','\xd8'},
+ {'\xfc','\xe2'},{'\xc4','\x78'},{'\x96','\xd6'},{'\xf4','\xaa'},{'\x00','\x00'},
+ {'\xf4','\xa9'},{'\xf4','\xa7'},{'\xf4','\xa6'},{'\xf4','\xa8'},{'\x00','\x00'},
+ {'\xc4','\x77'},{'\xc4','\x79'},{'\x00','\x00'},{'\xfa','\xde'},{'\xc4','\xf0'},
+ {'\xfc','\xe3'},{'\x00','\x00'},{'\xf5','\xe5'},{'\xf5','\xe4'},{'\x00','\x00'},
+ {'\xfa','\xdf'},{'\xf6','\xfa'},{'\xfa','\xe0'},{'\xf6','\xfc'},{'\xf6','\xfe'},
+ {'\xf6','\xfd'},{'\xf6','\xfb'},{'\xfc','\xe4'},{'\x00','\x00'},{'\xc5','\xa3'},
+ {'\xc5','\xa2'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\xd3'},{'\xc5','\xd2'},
+ {'\xc5','\xd4'},{'\xf7','\xed'},{'\xf7','\xec'},{'\x00','\x00'},{'\xf8','\xfb'},
+ {'\xf8','\xb8'},{'\xf8','\xfc'},{'\xc6','\x58'},{'\x96','\xd7'},{'\xc6','\x59'},
+ {'\xf9','\x6d'},{'\xfc','\xe5'},{'\x00','\x00'},{'\xc6','\x7e'},{'\xa6','\xcc'},
+ {'\x90','\x5a'},{'\xcd','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\xd0','\x45'},
+ {'\xd0','\x46'},{'\xd0','\x44'},{'\x8b','\xdd'},{'\x83','\x5e'},{'\xac','\xf3'},
+ {'\xfc','\xe6'},{'\xd0','\x47'},{'\xd0','\x48'},{'\xd0','\x49'},{'\x94','\x43'},
+ {'\xfc','\xe8'},{'\xd3','\x49'},{'\xd3','\x4f'},{'\xfc','\xe7'},{'\x00','\x00'},
+ {'\xd3','\x4d'},{'\xaf','\xbb'},{'\xd3','\x4b'},{'\x92','\xf7'},{'\xd3','\x4c'},
+ {'\xd3','\x4e'},{'\x96','\xd8'},{'\x00','\x00'},{'\x94','\xbe'},{'\xd3','\x4a'},
+ {'\xb2','\xc9'},{'\x00','\x00'},{'\xd6','\xde'},{'\xb2','\xcb'},{'\xd6','\xe0'},
+ {'\xb2','\xca'},{'\xd6','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\x92','\xe0'},
+ {'\x90','\x7b'},{'\x90','\x43'},{'\xda','\xe8'},{'\xb5','\xaf'},{'\x00','\x00'},
+ {'\xda','\xea'},{'\xda','\xe7'},{'\xd6','\xe1'},{'\x85','\xed'},{'\xb5','\xb0'},
+ {'\xfe','\x63'},{'\xf9','\xdb'},{'\xda','\xe9'},{'\x00','\x00'},{'\x8a','\x41'},
+ {'\xfa','\xe1'},{'\xfc','\xe9'},{'\x94','\xbf'},{'\x8a','\xea'},{'\xdf','\x56'},
+ {'\x00','\x00'},{'\xb8','\x64'},{'\xdf','\x54'},{'\xb8','\x65'},{'\xdf','\x55'},
+ {'\xb8','\x66'},{'\x00','\x00'},{'\x00','\x00'},{'\x96','\xd9'},{'\xba','\xe9'},
+ {'\xe3','\x61'},{'\xe3','\x5e'},{'\xe3','\x60'},{'\xba','\xea'},{'\xba','\xeb'},
+ {'\xe3','\x5f'},{'\x94','\xc0'},{'\x8a','\x43'},{'\xfc','\xeb'},{'\x96','\xda'},
+ {'\x00','\x00'},{'\xe6','\xdf'},{'\x00','\x00'},{'\xfc','\xea'},{'\xe6','\xe0'},
+ {'\x95','\xb2'},{'\xbd','\x6b'},{'\xe6','\xe2'},{'\xe6','\xe1'},{'\xa0','\x54'},
+ {'\xa2','\x61'},{'\x00','\x00'},{'\xea','\xca'},{'\xea','\xcb'},{'\xea','\xc7'},
+ {'\xfb','\x7e'},{'\xea','\xc8'},{'\xbf','\x7c'},{'\xbf','\x7d'},{'\xea','\xc9'},
+ {'\x94','\xc1'},{'\xc1','\x57'},{'\xfc','\xed'},{'\x00','\x00'},{'\xc1','\x53'},
+ {'\xc1','\x58'},{'\xc1','\x54'},{'\xc1','\x56'},{'\xc1','\x52'},{'\x00','\x00'},
+ {'\xc1','\x55'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x96','\xdb'},
+ {'\xc2','\xb3'},{'\xed','\xcf'},{'\x00','\x00'},{'\xf2','\xae'},{'\x00','\x00'},
+ {'\xf2','\xad'},{'\x96','\xdc'},{'\xf4','\xab'},{'\xc4','\x7a'},{'\xc4','\x7b'},
+ {'\xf7','\x41'},{'\xf5','\xe6'},{'\x96','\xdd'},{'\xf7','\x40'},{'\x96','\xde'},
+ {'\xf8','\xfd'},{'\xf9','\xa4'},{'\xa6','\xcd'},{'\x96','\xdf'},{'\xfa','\xe2'},
+ {'\xa8','\x74'},{'\x96','\xe1'},{'\xcd','\xa9'},{'\xaa','\xc8'},{'\x00','\x00'},
+ {'\xac','\xf6'},{'\xd0','\x4c'},{'\xac','\xf4'},{'\xd0','\x4a'},{'\xac','\xf9'},
+ {'\xac','\xf5'},{'\xac','\xfa'},{'\xac','\xf8'},{'\xd0','\x4b'},{'\xac','\xf7'},
+ {'\xaf','\xbf'},{'\xaf','\xbe'},{'\xd3','\x5a'},{'\xaf','\xc7'},{'\xd3','\x53'},
+ {'\xd3','\x59'},{'\xaf','\xc3'},{'\xd3','\x52'},{'\xd3','\x58'},{'\xd3','\x56'},
+ {'\xaf','\xc2'},{'\xaf','\xc4'},{'\xd3','\x55'},{'\xaf','\xbd'},{'\xd3','\x54'},
+ {'\xaf','\xc8'},{'\xaf','\xc5'},{'\xaf','\xc9'},{'\xaf','\xc6'},{'\xd3','\x51'},
+ {'\xd3','\x50'},{'\xd3','\x57'},{'\xaf','\xc0'},{'\xaf','\xbc'},{'\xaf','\xc1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x95','\xe2'},{'\x00','\x00'},{'\x86','\xfa'},
+ {'\xd6','\xf0'},{'\xd6','\xe9'},{'\x00','\x00'},{'\xb5','\xb5'},{'\xd6','\xe8'},
+ {'\x00','\x00'},{'\xb2','\xcf'},{'\xb2','\xd6'},{'\xb2','\xd3'},{'\xb2','\xd9'},
+ {'\xb2','\xd8'},{'\xb2','\xd4'},{'\x00','\x00'},{'\xd6','\xe2'},{'\xd6','\xe5'},
+ {'\x00','\x00'},{'\xd6','\xe4'},{'\xb2','\xd0'},{'\xd6','\xe6'},{'\xd6','\xef'},
+ {'\xb2','\xd1'},{'\xd6','\xe3'},{'\xd6','\xec'},{'\xd6','\xed'},{'\xb2','\xd2'},
+ {'\xd6','\xea'},{'\xb2','\xd7'},{'\xb2','\xcd'},{'\xb2','\xd5'},{'\xd6','\xe7'},
+ {'\xb2','\xcc'},{'\xd6','\xeb'},{'\xfa','\xe3'},{'\x00','\x00'},{'\xd6','\xee'},
+ {'\xfa','\xe4'},{'\x92','\xab'},{'\xfc','\xef'},{'\xda','\xfb'},{'\xda','\xf2'},
+ {'\xb5','\xb2'},{'\xda','\xf9'},{'\xda','\xf6'},{'\xda','\xee'},{'\xda','\xf7'},
+ {'\xb5','\xb4'},{'\xda','\xef'},{'\x00','\x00'},{'\xda','\xeb'},{'\x00','\x00'},
+ {'\xfc','\xf0'},{'\xb8','\x6c'},{'\xda','\xf4'},{'\xfe','\x60'},{'\xb5','\xb1'},
+ {'\xda','\xfa'},{'\x00','\x00'},{'\xb5','\xb8'},{'\xb5','\xba'},{'\xda','\xed'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb5','\xb9'},{'\xda','\xf0'},{'\xb5','\xb3'},
+ {'\xda','\xf8'},{'\xda','\xf1'},{'\xda','\xf5'},{'\x00','\x00'},{'\xda','\xf3'},
+ {'\xb5','\xb6'},{'\xda','\xec'},{'\xb5','\xbb'},{'\xb2','\xce'},{'\xb5','\xb7'},
+ {'\xb5','\xbc'},{'\x00','\x00'},{'\x92','\x5b'},{'\x93','\x46'},{'\xfa','\xe5'},
+ {'\x00','\x00'},{'\xb8','\x68'},{'\xdf','\x5d'},{'\xdf','\x5f'},{'\xdf','\x61'},
+ {'\xdf','\x65'},{'\x00','\x00'},{'\xdf','\x5b'},{'\xdf','\x59'},{'\xb8','\x6a'},
+ {'\x00','\x00'},{'\xdf','\x60'},{'\xdf','\x64'},{'\xdf','\x5c'},{'\xdf','\x58'},
+ {'\x00','\x00'},{'\xdf','\x57'},{'\x95','\x68'},{'\x00','\x00'},{'\x96','\xe2'},
+ {'\xdf','\x62'},{'\xdf','\x5a'},{'\xdf','\x5e'},{'\xb8','\x6b'},{'\x00','\x00'},
+ {'\xb8','\x69'},{'\xdf','\x66'},{'\xb8','\x67'},{'\xdf','\x63'},{'\x9d','\xb9'},
+ {'\xe3','\x72'},{'\x96','\xe3'},{'\x00','\x00'},{'\x92','\xae'},{'\x93','\x64'},
+ {'\x94','\xc2'},{'\xba','\xee'},{'\xe3','\x6a'},{'\xbd','\x78'},{'\xe3','\x74'},
+ {'\xba','\xf1'},{'\xe3','\x78'},{'\xba','\xf7'},{'\xe3','\x65'},{'\x96','\xe4'},
+ {'\x00','\x00'},{'\xe3','\x75'},{'\xe3','\x62'},{'\x96','\xe5'},{'\xe3','\x77'},
+ {'\xe3','\x66'},{'\x95','\x56'},{'\xba','\xfe'},{'\xba','\xfb'},{'\xe3','\x76'},
+ {'\xe3','\x70'},{'\xba','\xed'},{'\xba','\xf5'},{'\xba','\xf4'},{'\x95','\x6a'},
+ {'\xba','\xf3'},{'\xba','\xf9'},{'\x00','\x00'},{'\xe3','\x63'},{'\xba','\xfa'},
+ {'\xe3','\x71'},{'\xba','\xf6'},{'\xba','\xec'},{'\xe3','\x73'},{'\xba','\xef'},
+ {'\xba','\xf0'},{'\xba','\xf8'},{'\xe3','\x68'},{'\xe3','\x67'},{'\xe3','\x64'},
+ {'\x00','\x00'},{'\xe3','\x6c'},{'\xe3','\x69'},{'\xe3','\x6d'},{'\xba','\xfd'},
+ {'\x00','\x00'},{'\xe3','\x79'},{'\xba','\xf2'},{'\xe3','\x6e'},{'\xe3','\x6f'},
+ {'\x96','\xe6'},{'\xe3','\x6b'},{'\x93','\x5c'},{'\x96','\xe7'},{'\x93','\xe7'},
+ {'\xba','\xfc'},{'\x96','\xe8'},{'\xfa','\xe6'},{'\xfa','\xe7'},{'\xfa','\xe8'},
+ {'\xe6','\xe7'},{'\xbd','\x70'},{'\xbd','\x79'},{'\xbd','\x75'},{'\xe6','\xe4'},
+ {'\x95','\xc3'},{'\xbd','\x72'},{'\xbd','\x76'},{'\xe6','\xf0'},{'\xbd','\x6c'},
+ {'\xe6','\xe8'},{'\x00','\x00'},{'\xbd','\x74'},{'\xfa','\xe9'},{'\x96','\xe9'},
+ {'\xe6','\xeb'},{'\xe6','\xe6'},{'\xbd','\x73'},{'\xbd','\x77'},{'\xe6','\xe5'},
+ {'\x00','\x00'},{'\xbd','\x71'},{'\x00','\x00'},{'\xe6','\xef'},{'\xbd','\x6e'},
+ {'\xe6','\xee'},{'\xe6','\xed'},{'\xbd','\x7a'},{'\xe5','\x72'},{'\xbd','\x6d'},
+ {'\xfc','\xf1'},{'\xe6','\xec'},{'\xe6','\xe3'},{'\x00','\x00'},{'\xbd','\x7b'},
+ {'\xe6','\xea'},{'\xbd','\x6f'},{'\x00','\x00'},{'\x96','\xea'},{'\x9f','\x7e'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x92','\x4d'},{'\x00','\x00'},{'\xe6','\xe9'},
+ {'\x92','\xed'},{'\x94','\xc3'},{'\x00','\x00'},{'\x9f','\xa1'},{'\xbf','\xa2'},
+ {'\xbf','\xa7'},{'\xbf','\x7e'},{'\xea','\xd8'},{'\xea','\xcf'},{'\xea','\xdb'},
+ {'\xea','\xd3'},{'\xea','\xd9'},{'\xbf','\xa8'},{'\xbf','\xa1'},{'\xea','\xcc'},
+ {'\xea','\xd2'},{'\xea','\xdc'},{'\xea','\xd5'},{'\xea','\xda'},{'\xea','\xce'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xea','\xd6'},{'\xbf','\xa3'},{'\xea','\xd4'},
+ {'\xbf','\xa6'},{'\xbf','\xa5'},{'\xea','\xd0'},{'\xea','\xd1'},{'\xea','\xcd'},
+ {'\xea','\xd7'},{'\xbf','\xa4'},{'\xea','\xde'},{'\xea','\xdd'},{'\x92','\xdf'},
+ {'\xfc','\xf2'},{'\x00','\x00'},{'\xed','\xda'},{'\xed','\xd6'},{'\xc1','\x5f'},
+ {'\x00','\x00'},{'\xed','\xd0'},{'\xc1','\x59'},{'\xc1','\x69'},{'\xed','\xdc'},
+ {'\xc1','\x61'},{'\xc1','\x5d'},{'\xed','\xd3'},{'\xc1','\x64'},{'\xc1','\x67'},
+ {'\xed','\xde'},{'\xc1','\x5c'},{'\xed','\xd5'},{'\xc1','\x65'},{'\xed','\xe0'},
+ {'\xed','\xdd'},{'\xed','\xd1'},{'\xc1','\x60'},{'\xc1','\x5a'},{'\xc1','\x68'},
+ {'\xed','\xd8'},{'\xc1','\x63'},{'\xed','\xd2'},{'\xc1','\x5e'},{'\xed','\xdf'},
+ {'\xc1','\x62'},{'\xc1','\x5b'},{'\xed','\xd9'},{'\xc1','\x66'},{'\xed','\xd7'},
+ {'\x93','\x4f'},{'\x82','\x5a'},{'\xed','\xdb'},{'\xfa','\xea'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xf0','\x6e'},{'\xf0','\x74'},{'\xc2','\xb9'},{'\xf0','\x77'},
+ {'\xc2','\xb4'},{'\xc2','\xb5'},{'\xf0','\x6f'},{'\xf0','\x76'},{'\xf0','\x71'},
+ {'\xc2','\xba'},{'\xc2','\xb7'},{'\x9f','\xa2'},{'\xf0','\x6d'},{'\xfa','\xeb'},
+ {'\xc2','\xb6'},{'\xf0','\x73'},{'\xf0','\x75'},{'\xc2','\xb8'},{'\xf0','\x72'},
+ {'\xf0','\x70'},{'\x00','\x00'},{'\x9f','\xa3'},{'\x8a','\x50'},{'\x94','\xc4'},
+ {'\xf2','\xb8'},{'\xc3','\xb7'},{'\xc3','\xb8'},{'\xc3','\xb4'},{'\x9f','\xa4'},
+ {'\xc3','\xb5'},{'\x8c','\xe8'},{'\xf2','\xb4'},{'\xf2','\xb2'},{'\x00','\x00'},
+ {'\xf2','\xb6'},{'\xc3','\xba'},{'\xf2','\xb7'},{'\xf2','\xb0'},{'\xf2','\xaf'},
+ {'\xf2','\xb3'},{'\xf2','\xb1'},{'\xc3','\xb6'},{'\xf2','\xb5'},{'\xf4','\xac'},
+ {'\xc4','\x7e'},{'\xc4','\x7d'},{'\xf4','\xad'},{'\xfa','\xec'},{'\xf4','\xaf'},
+ {'\xf4','\xae'},{'\xc4','\xa1'},{'\x94','\xc5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf5','\xeb'},{'\xf5','\xe8'},{'\xf5','\xe9'},{'\xfa','\xed'},{'\xf5','\xe7'},
+ {'\xf5','\xea'},{'\xc4','\xf2'},{'\xf5','\xec'},{'\xfa','\xee'},{'\xc4','\xf1'},
+ {'\x94','\xc6'},{'\xf7','\x42'},{'\xfa','\xef'},{'\xc5','\xd5'},{'\xc5','\xd7'},
+ {'\xf7','\xee'},{'\xc5','\xd6'},{'\xf8','\xb9'},{'\xf9','\x40'},{'\xf9','\x42'},
+ {'\xf8','\xfe'},{'\xf9','\x41'},{'\xc6','\x6c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9c','\xeb'},{'\x83','\x5f'},{'\x83','\x76'},{'\x83','\x71'},{'\x83','\x70'},
+ {'\x8a','\x4e'},{'\x83','\x74'},{'\x83','\x75'},{'\x83','\xcb'},{'\x8d','\xbe'},
+ {'\x90','\x44'},{'\x83','\x72'},{'\x83','\x73'},{'\x87','\xfe'},{'\x83','\xcc'},
+ {'\x00','\x00'},{'\x83','\xc8'},{'\x83','\xca'},{'\x83','\xc6'},{'\x86','\xfc'},
+ {'\x83','\xcd'},{'\x00','\x00'},{'\x8a','\x4c'},{'\x87','\x41'},{'\x83','\xcf'},
+ {'\x83','\xce'},{'\x83','\xc7'},{'\x83','\xc5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x83','\xc9'},{'\x8d','\xc5'},{'\x88','\x45'},{'\x8d','\xd3'},{'\x84','\x71'},
+ {'\x84','\x72'},{'\x87','\xfd'},{'\x84','\x6f'},{'\x84','\x6e'},{'\x84','\x6d'},
+ {'\x8a','\xeb'},{'\x84','\x70'},{'\x89','\x53'},{'\x84','\x68'},{'\x84','\x6b'},
+ {'\x84','\x6c'},{'\x84','\x6a'},{'\x8b','\xb1'},{'\x85','\xee'},{'\x8d','\xd4'},
+ {'\x85','\xf0'},{'\x85','\x44'},{'\x85','\x43'},{'\xfa','\xf0'},{'\x8a','\xed'},
+ {'\x85','\x4a'},{'\x8d','\xe4'},{'\x8b','\xb3'},{'\x85','\x48'},{'\x85','\x49'},
+ {'\x85','\x4b'},{'\x85','\x47'},{'\x85','\x45'},{'\x85','\x42'},{'\x84','\x69'},
+ {'\x8e','\x4a'},{'\x8e','\x4b'},{'\x85','\xef'},{'\x8a','\xef'},{'\x00','\x00'},
+ {'\x85','\xf1'},{'\x85','\xf2'},{'\x8c','\x49'},{'\x8e','\x49'},{'\x8a','\x45'},
+ {'\x87','\x43'},{'\x86','\xf8'},{'\x00','\x00'},{'\x8c','\xa2'},{'\x86','\xfd'},
+ {'\x8e','\x7b'},{'\x86','\xf7'},{'\xfa','\xf1'},{'\x8e','\x7a'},{'\x8b','\xb2'},
+ {'\x87','\x42'},{'\x87','\x40'},{'\x87','\x45'},{'\x8a','\x49'},{'\x86','\xfe'},
+ {'\x00','\x00'},{'\x8e','\x7c'},{'\x8e','\x79'},{'\x86','\xf6'},{'\x86','\xf4'},
+ {'\x86','\xf5'},{'\x86','\xf9'},{'\x86','\xfb'},{'\x87','\x44'},{'\x88','\x49'},
+ {'\x8e','\xc2'},{'\x88','\x40'},{'\x88','\x41'},{'\x8d','\xa3'},{'\x88','\x4b'},
+ {'\x88','\x4a'},{'\x88','\x42'},{'\x00','\x00'},{'\x8f','\x79'},{'\x8e','\xc4'},
+ {'\x88','\x48'},{'\x88','\x46'},{'\x8e','\xc5'},{'\x00','\x00'},{'\x8e','\xc6'},
+ {'\xfa','\xf2'},{'\x88','\x47'},{'\x87','\xfc'},{'\x8a','\x47'},{'\x88','\x43'},
+ {'\x8e','\xc3'},{'\x88','\x44'},{'\x89','\x52'},{'\x89','\x4e'},{'\x8e','\xf0'},
+ {'\x89','\x51'},{'\x8a','\x4a'},{'\x00','\x00'},{'\x89','\x50'},{'\x8c','\xa1'},
+ {'\x8f','\x5d'},{'\x89','\x4b'},{'\x89','\x4c'},{'\x8c','\x48'},{'\x8a','\x4f'},
+ {'\x8a','\x51'},{'\x8a','\x48'},{'\x8c','\xfb'},{'\x8a','\x44'},{'\x8a','\x46'},
+ {'\x8a','\x4d'},{'\x90','\x45'},{'\x8a','\xee'},{'\x8a','\xec'},{'\x8a','\xf0'},
+ {'\xfa','\xf3'},{'\x8f','\xde'},{'\x8f','\xbf'},{'\x8f','\xc0'},{'\x8b','\xb5'},
+ {'\x90','\x7c'},{'\xa6','\xce'},{'\x9f','\xa5'},{'\xac','\xfb'},{'\xd2','\x6f'},
+ {'\xaf','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\xb2','\xda'},{'\xda','\xfc'},
+ {'\xda','\xfd'},{'\x9f','\xa6'},{'\x9f','\xa7'},{'\x8c','\x4a'},{'\xea','\xdf'},
+ {'\xc1','\x6a'},{'\xed','\xe1'},{'\x00','\x00'},{'\x95','\x74'},{'\xc2','\xbb'},
+ {'\x9f','\xa8'},{'\xf2','\xba'},{'\xf2','\xb9'},{'\xc4','\xa2'},{'\xf5','\xed'},
+ {'\xfb','\xaa'},{'\xf7','\x43'},{'\xc5','\xf8'},{'\xca','\x49'},{'\x9f','\xa9'},
+ {'\x9d','\x75'},{'\xaa','\xc9'},{'\xa8','\x75'},{'\x00','\x00'},{'\x8b','\xb4'},
+ {'\xd0','\x4d'},{'\x00','\x00'},{'\x87','\x46'},{'\xd3','\x60'},{'\xd3','\x5b'},
+ {'\xd3','\x5f'},{'\xd3','\x5d'},{'\xaf','\xcb'},{'\xd3','\x5e'},{'\xd3','\x5c'},
+ {'\x88','\x4d'},{'\xd6','\xf1'},{'\x00','\x00'},{'\xda','\xfe'},{'\xdb','\x40'},
+ {'\xdf','\x69'},{'\xdf','\x6a'},{'\xb8','\x6e'},{'\xb8','\x6f'},{'\xdf','\x68'},
+ {'\xdf','\x6b'},{'\xdf','\x67'},{'\xb8','\x6d'},{'\x00','\x00'},{'\xbb','\x40'},
+ {'\xfa','\xf4'},{'\xb8','\x70'},{'\xe3','\x7a'},{'\x8f','\xc1'},{'\xbd','\x7c'},
+ {'\xe6','\xf1'},{'\xbd','\x7d'},{'\x95','\x64'},{'\xbf','\xa9'},{'\xea','\xe2'},
+ {'\xea','\xe0'},{'\xea','\xe1'},{'\xed','\xe4'},{'\xed','\xe3'},{'\xed','\xe2'},
+ {'\x00','\x00'},{'\x8d','\x56'},{'\xfa','\xf5'},{'\xf2','\xbb'},{'\x00','\x00'},
+ {'\xc3','\xb9'},{'\xf2','\xbc'},{'\xf7','\x44'},{'\xc5','\xf9'},{'\xf8','\xba'},
+ {'\xa6','\xcf'},{'\xaa','\xcb'},{'\xaa','\xca'},{'\xd0','\x4f'},{'\xac','\xfc'},
+ {'\x9f','\xaa'},{'\x00','\x00'},{'\xd0','\x4e'},{'\xd3','\x62'},{'\x9f','\xab'},
+ {'\xaf','\xcc'},{'\xd6','\xf2'},{'\xd3','\x61'},{'\x95','\xe0'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb2','\xdc'},{'\xd6','\xf5'},{'\xd6','\xf3'},{'\xd6','\xf4'},
+ {'\xb2','\xdb'},{'\x8e','\x4c'},{'\xdb','\x42'},{'\xdb','\x43'},{'\xdb','\x41'},
+ {'\x95','\x55'},{'\xb8','\x73'},{'\xdf','\x6d'},{'\xdf','\x6c'},{'\xdf','\x6e'},
+ {'\xb8','\x72'},{'\xb8','\x71'},{'\x00','\x00'},{'\x00','\x00'},{'\xe6','\xf2'},
+ {'\xe6','\xf4'},{'\xfa','\xf6'},{'\xbd','\x7e'},{'\xe6','\xf3'},{'\xea','\xe3'},
+ {'\xbf','\xaa'},{'\xf0','\x79'},{'\x9f','\xac'},{'\xf0','\x78'},{'\xc3','\xbb'},
+ {'\xf2','\xbd'},{'\xc3','\xbd'},{'\xc3','\xbc'},{'\xf4','\xb0'},{'\xf5','\xee'},
+ {'\xc4','\xf3'},{'\xa6','\xd0'},{'\xd0','\x50'},{'\xac','\xfd'},{'\xd3','\x65'},
+ {'\xaf','\xce'},{'\xd3','\x64'},{'\xd3','\x63'},{'\x00','\x00'},{'\xaf','\xcd'},
+ {'\xfa','\xf7'},{'\xd6','\xfb'},{'\x00','\x00'},{'\xd6','\xfd'},{'\xd6','\xf6'},
+ {'\xd6','\xf7'},{'\xb2','\xdd'},{'\xd6','\xf8'},{'\xb2','\xde'},{'\xd6','\xfc'},
+ {'\xd6','\xf9'},{'\xd6','\xfa'},{'\xb2','\xdf'},{'\x00','\x00'},{'\xb5','\xbe'},
+ {'\xb5','\xbf'},{'\x00','\x00'},{'\xdb','\x44'},{'\x8a','\xf1'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xdf','\x6f'},{'\xdf','\x70'},{'\x9f','\xad'},{'\xe3','\x7e'},
+ {'\xbb','\x43'},{'\xbb','\x41'},{'\xbb','\x42'},{'\xe3','\x7b'},{'\xe3','\x7c'},
+ {'\x00','\x00'},{'\xe3','\x7d'},{'\xe6','\xf9'},{'\x9f','\xae'},{'\xe6','\xfa'},
+ {'\xbd','\xa1'},{'\xe6','\xf7'},{'\xe6','\xf6'},{'\xe6','\xf8'},{'\xe6','\xf5'},
+ {'\xbf','\xad'},{'\xea','\xe4'},{'\xbf','\xab'},{'\xbf','\xac'},{'\xed','\xe6'},
+ {'\xc1','\x6b'},{'\xed','\xe5'},{'\xef','\xa8'},{'\x00','\x00'},{'\xf0','\x7a'},
+ {'\xf0','\x7b'},{'\xc2','\xbc'},{'\x9f','\xaf'},{'\xc2','\xbd'},{'\xc1','\x6c'},
+ {'\xf2','\xbe'},{'\xf2','\xbf'},{'\xf4','\xb1'},{'\xc4','\xa3'},{'\xa6','\xd1'},
+ {'\x9f','\xb0'},{'\xa6','\xd2'},{'\xac','\xfe'},{'\xaa','\xcc'},{'\xaf','\xcf'},
+ {'\xd0','\x51'},{'\x9f','\xb1'},{'\x00','\x00'},{'\x00','\x00'},{'\xb5','\xc0'},
+ {'\xa6','\xd3'},{'\xad','\x41'},{'\xd0','\x52'},{'\xd0','\x53'},{'\xad','\x40'},
+ {'\xad','\x42'},{'\xa6','\xd4'},{'\x00','\x00'},{'\xd0','\x54'},{'\xaf','\xd1'},
+ {'\xd3','\x66'},{'\xaf','\xd3'},{'\xaf','\xd0'},{'\xaf','\xd2'},{'\x00','\x00'},
+ {'\xd7','\x41'},{'\xb2','\xe0'},{'\xfc','\xf6'},{'\xd7','\x40'},{'\xd6','\xfe'},
+ {'\xfa','\xf8'},{'\xdf','\x71'},{'\xfa','\xf9'},{'\x00','\x00'},{'\xe3','\xa1'},
+ {'\xfa','\xfa'},{'\xbd','\xa2'},{'\x8f','\x5e'},{'\xbf','\xae'},{'\xea','\xe6'},
+ {'\xea','\xe5'},{'\x00','\x00'},{'\xed','\xe7'},{'\x00','\x00'},{'\x9f','\xb2'},
+ {'\x9f','\xb3'},{'\xf5','\xef'},{'\xfa','\xfb'},{'\x00','\x00'},{'\xa6','\xd5'},
+ {'\xcb','\x73'},{'\xcd','\xaa'},{'\xad','\x43'},{'\xd0','\x55'},{'\x8a','\x55'},
+ {'\xd3','\x68'},{'\x00','\x00'},{'\x95','\x5c'},{'\x9f','\xb4'},{'\xaf','\xd4'},
+ {'\xd3','\x67'},{'\xaf','\xd5'},{'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xf3'},
+ {'\xd7','\x43'},{'\x00','\x00'},{'\x00','\x00'},{'\xb2','\xe2'},{'\xd7','\x42'},
+ {'\xd7','\x44'},{'\x00','\x00'},{'\xb2','\xe1'},{'\x8c','\xd9'},{'\x8a','\xf2'},
+ {'\x8f','\xdf'},{'\x00','\x00'},{'\xdb','\x46'},{'\xdb','\x47'},{'\xdb','\x45'},
+ {'\xb5','\xc1'},{'\x00','\x00'},{'\x8a','\x54'},{'\x00','\x00'},{'\xb8','\x74'},
+ {'\x00','\x00'},{'\xb8','\x75'},{'\x00','\x00'},{'\xbb','\x45'},{'\xfc','\xfa'},
+ {'\xe3','\xa3'},{'\xe3','\xa2'},{'\xbb','\x44'},{'\xfa','\xfc'},{'\x00','\x00'},
+ {'\x82','\x6b'},{'\xfc','\xf7'},{'\xfc','\xf8'},{'\xe6','\xfb'},{'\x00','\x00'},
+ {'\xfc','\xf9'},{'\xe6','\xfc'},{'\xfa','\xfd'},{'\x8f','\x7a'},{'\x8a','\x53'},
+ {'\x00','\x00'},{'\xea','\xe7'},{'\x00','\x00'},{'\x00','\x00'},{'\xc1','\x70'},
+ {'\xc1','\x6f'},{'\xc1','\x6d'},{'\xc1','\x6e'},{'\xc1','\x71'},{'\x93','\x77'},
+ {'\xf0','\x7c'},{'\xc2','\xbf'},{'\xc2','\xbe'},{'\xf2','\xc0'},{'\xf4','\xb2'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\xa5'},{'\xc5','\xa4'},
+ {'\xa6','\xd6'},{'\x91','\xd5'},{'\x00','\x00'},{'\xd1','\xfb'},{'\x85','\x4c'},
+ {'\xb8','\x77'},{'\xb5','\xc2'},{'\xb8','\x76'},{'\xbb','\x46'},{'\x00','\x00'},
+ {'\xa6','\xd7'},{'\xc9','\xa9'},{'\xa6','\xd8'},{'\xa6','\xd9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xcd','\xab'},{'\xcb','\x76'},{'\x00','\x00'},{'\xcb','\x77'},
+ {'\xa8','\x77'},{'\x00','\x00'},{'\xcb','\x74'},{'\xa8','\x76'},{'\x00','\x00'},
+ {'\xa8','\x79'},{'\xcb','\x75'},{'\xa8','\x7b'},{'\xa8','\x7a'},{'\xcb','\x78'},
+ {'\xa8','\x78'},{'\x00','\x00'},{'\x96','\xaf'},{'\x85','\xf6'},{'\xaa','\xd1'},
+ {'\xaa','\xcf'},{'\xcd','\xad'},{'\x88','\x4f'},{'\xaa','\xce'},{'\xfc','\xfb'},
+ {'\x9f','\xb5'},{'\x00','\x00'},{'\xaa','\xd3'},{'\xaa','\xd5'},{'\xaa','\xd2'},
+ {'\xfa','\xfe'},{'\xcd','\xb0'},{'\xcd','\xac'},{'\xaa','\xd6'},{'\x00','\x00'},
+ {'\xaa','\xd0'},{'\xa8','\x7c'},{'\x00','\x00'},{'\xaa','\xd4'},{'\xcd','\xaf'},
+ {'\xfb','\x4d'},{'\xfb','\x40'},{'\xcd','\xae'},{'\x00','\x00'},{'\xaa','\xcd'},
+ {'\x00','\x00'},{'\x96','\xcb'},{'\x96','\xa6'},{'\x85','\x4d'},{'\x85','\xf8'},
+ {'\x85','\x4e'},{'\x83','\xd0'},{'\xd0','\x5b'},{'\xad','\x47'},{'\xad','\x48'},
+ {'\xd0','\x5d'},{'\x8a','\x57'},{'\xd0','\x57'},{'\xd0','\x5a'},{'\xd0','\x63'},
+ {'\xd0','\x61'},{'\x00','\x00'},{'\xad','\x49'},{'\xd0','\x67'},{'\xad','\x4c'},
+ {'\xd0','\x64'},{'\xd0','\x5c'},{'\xd0','\x59'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xdb','\x49'},{'\xd0','\x62'},{'\xad','\x44'},{'\xd0','\x65'},{'\xd0','\x56'},
+ {'\xd0','\x5f'},{'\xad','\x46'},{'\xad','\x4b'},{'\xd0','\x60'},{'\xad','\x4f'},
+ {'\xad','\x4d'},{'\x00','\x00'},{'\xd0','\x58'},{'\xad','\x4a'},{'\x00','\x00'},
+ {'\xd0','\x5e'},{'\xad','\x4e'},{'\xad','\x45'},{'\xd0','\x66'},{'\x8b','\xf8'},
+ {'\xfd','\xfb'},{'\xfd','\xfc'},{'\x8c','\x4b'},{'\x8d','\xd5'},{'\xfd','\xfd'},
+ {'\xaf','\xda'},{'\x00','\x00'},{'\xaf','\xe3'},{'\xaf','\xd8'},{'\xaf','\xd6'},
+ {'\xd3','\x6a'},{'\xaf','\xde'},{'\xaf','\xdb'},{'\xd3','\x6c'},{'\x88','\x4e'},
+ {'\x00','\x00'},{'\xaf','\xdd'},{'\xd3','\x6b'},{'\xd3','\x69'},{'\xd3','\x6e'},
+ {'\xaf','\xe2'},{'\xaf','\xe0'},{'\xdb','\x48'},{'\x00','\x00'},{'\xd3','\x6f'},
+ {'\xd3','\x6d'},{'\xaf','\xd7'},{'\xfc','\xfc'},{'\x00','\x00'},{'\xaf','\xd9'},
+ {'\xaf','\xdc'},{'\xfe','\x48'},{'\xaf','\xdf'},{'\x83','\xd1'},{'\xaf','\xe1'},
+ {'\x00','\x00'},{'\x9f','\xb6'},{'\x8a','\x59'},{'\xfd','\xfe'},{'\x8c','\xda'},
+ {'\x8a','\xf4'},{'\x85','\xf9'},{'\xfe','\xee'},{'\x8a','\x56'},{'\x90','\x7d'},
+ {'\xd7','\x4e'},{'\xb2','\xe4'},{'\x95','\xa8'},{'\xd7','\x45'},{'\xd7','\x47'},
+ {'\x85','\xf7'},{'\xd7','\x48'},{'\x00','\x00'},{'\xd7','\x50'},{'\xd7','\x4c'},
+ {'\xd7','\x4a'},{'\x00','\x00'},{'\xd7','\x4d'},{'\xd7','\x51'},{'\xb2','\xe5'},
+ {'\xb2','\xe9'},{'\xd7','\x46'},{'\x00','\x00'},{'\xd7','\x4f'},{'\x00','\x00'},
+ {'\xb2','\xe7'},{'\x9f','\xb7'},{'\xb2','\xe6'},{'\xd7','\x4b'},{'\xd7','\x49'},
+ {'\x00','\x00'},{'\xb2','\xe3'},{'\xb2','\xe8'},{'\xfe','\xef'},{'\x96','\xa5'},
+ {'\x93','\xb0'},{'\x9f','\xb8'},{'\x00','\x00'},{'\xfe','\xf0'},{'\xa0','\x42'},
+ {'\x8a','\x58'},{'\xb5','\xc8'},{'\xdb','\x51'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xdb','\x4f'},{'\xb5','\xca'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x9f','\xb9'},{'\xdb','\x4a'},{'\xdf','\xa1'},{'\x00','\x00'},{'\xb5','\xc9'},
+ {'\xdb','\x4e'},{'\x96','\xab'},{'\x00','\x00'},{'\xdb','\x4b'},{'\xb5','\xc5'},
+ {'\xb5','\xcb'},{'\xdb','\x50'},{'\xb5','\xc7'},{'\xdb','\x4d'},{'\xbb','\x47'},
+ {'\xb5','\xc6'},{'\xdb','\x4c'},{'\xb5','\xcc'},{'\xb5','\xc4'},{'\xb5','\xc3'},
+ {'\x9f','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\x96','\xae'},{'\x96','\xa2'},
+ {'\xdf','\x77'},{'\xdf','\x75'},{'\x00','\x00'},{'\xdf','\x7b'},{'\xfe','\xf1'},
+ {'\xdf','\x73'},{'\xdf','\xa2'},{'\xdf','\x78'},{'\x00','\x00'},{'\xdf','\x72'},
+ {'\xb8','\x7b'},{'\xb8','\xa3'},{'\xdf','\x7d'},{'\x00','\x00'},{'\xdf','\x76'},
+ {'\x00','\x00'},{'\xb8','\x7e'},{'\x9d','\xd0'},{'\xfe','\xf2'},{'\xb8','\x7c'},
+ {'\xdf','\x7e'},{'\xb8','\x79'},{'\xb8','\x78'},{'\xdf','\x79'},{'\xb8','\x7d'},
+ {'\xb5','\xcd'},{'\x00','\x00'},{'\xdf','\x7c'},{'\xdf','\x74'},{'\xb8','\x7a'},
+ {'\xb8','\xa1'},{'\xb8','\xa2'},{'\x89','\x54'},{'\x89','\xae'},{'\xfe','\xf3'},
+ {'\x8c','\x65'},{'\xbb','\x4c'},{'\xbb','\x48'},{'\x00','\x00'},{'\xbb','\x4d'},
+ {'\xe3','\xa6'},{'\x9f','\xbb'},{'\x00','\x00'},{'\xe3','\xa5'},{'\xe3','\xa7'},
+ {'\xbb','\x4a'},{'\xe3','\xa4'},{'\xbb','\x4b'},{'\xe3','\xaa'},{'\xe3','\xa9'},
+ {'\xe3','\xa8'},{'\x00','\x00'},{'\xbb','\x49'},{'\x00','\x00'},{'\x8a','\xf5'},
+ {'\x00','\x00'},{'\xfe','\xf4'},{'\x00','\x00'},{'\xe7','\x41'},{'\x00','\x00'},
+ {'\xe7','\x44'},{'\xbd','\xa8'},{'\xe7','\x43'},{'\xbd','\xa7'},{'\xbd','\xa3'},
+ {'\xbd','\xa4'},{'\xbd','\xa5'},{'\xe7','\x40'},{'\xe6','\xfe'},{'\xbd','\xa6'},
+ {'\x00','\x00'},{'\xe7','\x42'},{'\xe6','\xfd'},{'\x94','\xc7'},{'\x9f','\xbc'},
+ {'\xea','\xe9'},{'\xea','\xf3'},{'\xbf','\xb1'},{'\xbf','\xb0'},{'\xfe','\xf5'},
+ {'\xea','\xed'},{'\xea','\xef'},{'\x00','\x00'},{'\xea','\xea'},{'\x00','\x00'},
+ {'\xea','\xee'},{'\xea','\xe8'},{'\xea','\xf1'},{'\xbf','\xaf'},{'\xea','\xf0'},
+ {'\xea','\xec'},{'\xfb','\x6e'},{'\xea','\xf2'},{'\xfe','\xf6'},{'\xea','\xeb'},
+ {'\xc1','\x74'},{'\xed','\xe8'},{'\xed','\xee'},{'\xc1','\x78'},{'\xc1','\x7a'},
+ {'\xc1','\x77'},{'\xc1','\x76'},{'\xfe','\xf7'},{'\xc1','\x75'},{'\xc1','\x73'},
+ {'\xed','\xe9'},{'\xed','\xec'},{'\xc1','\x72'},{'\xed','\xed'},{'\xfc','\xfe'},
+ {'\xc1','\x79'},{'\xed','\xeb'},{'\x00','\x00'},{'\xed','\xea'},{'\xc2','\xc0'},
+ {'\x00','\x00'},{'\xc2','\xc1'},{'\xf0','\xa1'},{'\xf0','\x7d'},{'\xf0','\x7e'},
+ {'\x93','\x62'},{'\x00','\x00'},{'\xf2','\xc2'},{'\x00','\x00'},{'\xf2','\xc1'},
+ {'\xc3','\xbe'},{'\xf4','\xb4'},{'\xc4','\xa4'},{'\xf4','\xb3'},{'\x00','\x00'},
+ {'\xf5','\xf0'},{'\xf7','\x45'},{'\xc5','\xa6'},{'\xf9','\x43'},{'\xf9','\x44'},
+ {'\xc5','\xd8'},{'\xa6','\xda'},{'\x9f','\xbd'},{'\xaa','\xd7'},{'\xdb','\x52'},
+ {'\xbb','\x4e'},{'\xc1','\x7b'},{'\xed','\xef'},{'\xa6','\xdb'},{'\x00','\x00'},
+ {'\xaf','\xe5'},{'\xaf','\xe4'},{'\xdb','\x53'},{'\x95','\xd3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xea','\xf4'},{'\xa6','\xdc'},{'\xad','\x50'},{'\x00','\x00'},
+ {'\xfd','\x42'},{'\xdb','\x54'},{'\xdb','\x55'},{'\xdb','\x56'},{'\xbb','\x4f'},
+ {'\xbf','\xb2'},{'\xa6','\xdd'},{'\x00','\x00'},{'\xaa','\xd8'},{'\xd0','\x68'},
+ {'\xaf','\xe6'},{'\xd3','\x70'},{'\xb2','\xea'},{'\x00','\x00'},{'\xdb','\x57'},
+ {'\xb8','\xa4'},{'\x8a','\x77'},{'\xbb','\x50'},{'\xbf','\xb3'},{'\xc1','\x7c'},
+ {'\xc2','\xc2'},{'\xf4','\xb5'},{'\xa6','\xde'},{'\xaa','\xd9'},{'\x92','\xd6'},
+ {'\x00','\x00'},{'\xaf','\xe7'},{'\xd7','\x52'},{'\xb5','\xce'},{'\x00','\x00'},
+ {'\xbb','\x51'},{'\xe3','\xab'},{'\xe7','\x45'},{'\x93','\xc6'},{'\x95','\xec'},
+ {'\x00','\x00'},{'\xfd','\x43'},{'\xa6','\xdf'},{'\xb5','\xcf'},{'\xdf','\xa3'},
+ {'\xbb','\x52'},{'\xa6','\xe0'},{'\xcd','\xb1'},{'\xd0','\x69'},{'\xad','\x51'},
+ {'\x8f','\xc2'},{'\x00','\x00'},{'\xd3','\x72'},{'\xfb','\x53'},{'\x00','\x00'},
+ {'\xaf','\xea'},{'\xfe','\xf8'},{'\xaf','\xe8'},{'\xaf','\xe9'},{'\xaf','\xeb'},
+ {'\xfe','\xf9'},{'\xfe','\xfa'},{'\xd3','\x71'},{'\x8c','\x4c'},{'\x89','\x56'},
+ {'\xd7','\x57'},{'\xd7','\x54'},{'\xd7','\x56'},{'\xb2','\xeb'},{'\xb2','\xed'},
+ {'\xb2','\xec'},{'\xd7','\x53'},{'\xb2','\xee'},{'\xd7','\x55'},{'\x90','\x5b'},
+ {'\xdb','\x58'},{'\xdb','\x59'},{'\xfe','\xfb'},{'\xdb','\x5a'},{'\xdf','\xa6'},
+ {'\x00','\x00'},{'\xdf','\xa7'},{'\x00','\x00'},{'\xdf','\xa5'},{'\xdf','\xa8'},
+ {'\x00','\x00'},{'\xb8','\xa5'},{'\x00','\x00'},{'\xdf','\xa4'},{'\x00','\x00'},
+ {'\xbb','\x53'},{'\x00','\x00'},{'\x00','\x00'},{'\xe7','\x4a'},{'\xe7','\x46'},
+ {'\xe7','\x49'},{'\xe7','\x4b'},{'\xe7','\x48'},{'\xe7','\x47'},{'\x9f','\xbe'},
+ {'\xea','\xf5'},{'\xea','\xf6'},{'\xea','\xf7'},{'\xbf','\xb4'},{'\xbf','\xb5'},
+ {'\xed','\xf1'},{'\xed','\xf0'},{'\xed','\xf2'},{'\x94','\xc8'},{'\xf0','\xa3'},
+ {'\xf0','\xa2'},{'\x00','\x00'},{'\xf2','\xc4'},{'\xfe','\xfc'},{'\xf2','\xc5'},
+ {'\xf2','\xc3'},{'\x9f','\xbf'},{'\xc4','\xa5'},{'\x00','\x00'},{'\xf4','\xb6'},
+ {'\xf4','\xb7'},{'\xfe','\xfd'},{'\xf7','\x46'},{'\xf7','\xef'},{'\xf8','\xbb'},
+ {'\xa6','\xe1'},{'\xa8','\x7d'},{'\x8a','\x5c'},{'\xc1','\x7d'},{'\xa6','\xe2'},
+ {'\x8d','\x5b'},{'\xd7','\x58'},{'\xdb','\x5b'},{'\x82','\x45'},{'\xc6','\x41'},
+ {'\xca','\x4a'},{'\x9c','\xd2'},{'\x8b','\xb7'},{'\x9f','\xc0'},{'\xca','\x4b'},
+ {'\xca','\x4d'},{'\xa6','\xe3'},{'\xca','\x4e'},{'\xca','\x4c'},{'\x00','\x00'},
+ {'\x85','\xeb'},{'\xcb','\xa2'},{'\xcb','\xa3'},{'\xcb','\x7b'},{'\x00','\x00'},
+ {'\x9f','\xc1'},{'\xfe','\xfe'},{'\x00','\x00'},{'\xcb','\xa1'},{'\xa8','\xa1'},
+ {'\x00','\x00'},{'\xa8','\xa2'},{'\xcb','\x7c'},{'\xcb','\x7a'},{'\xcb','\x79'},
+ {'\xcb','\x7d'},{'\xa8','\x7e'},{'\xcb','\x7e'},{'\xd0','\x6a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8e','\xf6'},{'\xcd','\xb6'},{'\xaa','\xdc'},{'\xcd','\xb5'},
+ {'\xcd','\xb7'},{'\x89','\x59'},{'\xaa','\xdb'},{'\xcd','\xbc'},{'\xaa','\xdf'},
+ {'\xcd','\xb2'},{'\xcd','\xc0'},{'\xcd','\xc6'},{'\xaa','\xe6'},{'\xcd','\xc3'},
+ {'\xaa','\xe3'},{'\x8c','\x4f'},{'\xcd','\xb9'},{'\xcd','\xbf'},{'\xcd','\xc1'},
+ {'\xfb','\xa5'},{'\xcd','\xb4'},{'\xaa','\xe2'},{'\xaa','\xdd'},{'\xcd','\xba'},
+ {'\xaa','\xe4'},{'\xaa','\xe7'},{'\xaa','\xe1'},{'\x00','\x00'},{'\xaa','\xda'},
+ {'\xcd','\xbe'},{'\xcd','\xb8'},{'\xcd','\xc5'},{'\xaa','\xe9'},{'\xaa','\xe5'},
+ {'\xaa','\xe0'},{'\xcd','\xbd'},{'\xaf','\xec'},{'\xcd','\xbb'},{'\xaa','\xde'},
+ {'\xaa','\xe8'},{'\x9f','\xc2'},{'\xcd','\xb3'},{'\x8e','\xca'},{'\xcd','\xc2'},
+ {'\xcd','\xc4'},{'\x96','\xbe'},{'\x91','\x40'},{'\x00','\x00'},{'\x85','\xfb'},
+ {'\x8f','\xe1'},{'\x00','\x00'},{'\x91','\x41'},{'\x84','\x79'},{'\x85','\x51'},
+ {'\x87','\x4b'},{'\x83','\x78'},{'\x84','\xf7'},{'\xfd','\x5f'},{'\xad','\x62'},
+ {'\xad','\x5c'},{'\xad','\x64'},{'\xad','\x61'},{'\xd0','\x71'},{'\xd0','\x74'},
+ {'\xad','\x5d'},{'\x91','\x42'},{'\xd0','\x6b'},{'\x00','\x00'},{'\xad','\x56'},
+ {'\xad','\x60'},{'\x00','\x00'},{'\xad','\x63'},{'\xad','\x65'},{'\xd0','\xa2'},
+ {'\xd0','\x77'},{'\x9f','\xc3'},{'\xad','\x55'},{'\xd0','\xa1'},{'\xad','\x59'},
+ {'\xad','\x57'},{'\xad','\x52'},{'\xd0','\x6f'},{'\x00','\x00'},{'\xd0','\x7e'},
+ {'\xd0','\x73'},{'\xd0','\x76'},{'\xd0','\xa5'},{'\x9f','\xc4'},{'\xad','\x66'},
+ {'\xd0','\x7d'},{'\xad','\x5e'},{'\xd0','\x78'},{'\xd0','\xa4'},{'\xd0','\x75'},
+ {'\xd0','\x79'},{'\xd0','\x7c'},{'\x96','\xa3'},{'\x9f','\xc5'},{'\xd0','\x6d'},
+ {'\xd0','\xa3'},{'\xd0','\x7b'},{'\x9f','\xc6'},{'\xfd','\x5d'},{'\xd0','\x6c'},
+ {'\x9f','\xc7'},{'\xd0','\x70'},{'\xad','\x5f'},{'\xad','\x5a'},{'\xad','\x53'},
+ {'\xad','\x58'},{'\xad','\x54'},{'\xad','\x67'},{'\xd0','\x6e'},{'\xd3','\xa5'},
+ {'\xad','\x5b'},{'\x00','\x00'},{'\x9f','\xc8'},{'\xd0','\x7a'},{'\xce','\x41'},
+ {'\x92','\xa7'},{'\x8f','\xe0'},{'\x00','\x00'},{'\x8e','\xc9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x85','\xc3'},{'\x8e','\x46'},{'\xd3','\xa8'},{'\xaf','\xfa'},
+ {'\x91','\x43'},{'\xd3','\x76'},{'\x91','\x44'},{'\xd3','\xa3'},{'\xd3','\x7d'},
+ {'\x9f','\xc9'},{'\xd3','\xb2'},{'\x00','\x00'},{'\xd3','\xaa'},{'\x00','\x00'},
+ {'\xd3','\x7e'},{'\x91','\x45'},{'\xd3','\xa9'},{'\xd3','\x78'},{'\xd3','\x7c'},
+ {'\xd3','\xb5'},{'\xaf','\xfd'},{'\xd3','\xad'},{'\xd3','\xa4'},{'\xaf','\xed'},
+ {'\xd3','\xb3'},{'\xd3','\x74'},{'\x00','\x00'},{'\xd3','\xac'},{'\x00','\x00'},
+ {'\xaf','\xfc'},{'\xaf','\xf7'},{'\xd3','\x73'},{'\xaf','\xf5'},{'\xaf','\xf4'},
+ {'\xaf','\xf9'},{'\xd3','\xab'},{'\xaf','\xf1'},{'\xaf','\xf8'},{'\xd0','\x72'},
+ {'\xdb','\x5c'},{'\xd3','\xa6'},{'\x9f','\xca'},{'\x00','\x00'},{'\xd3','\x7a'},
+ {'\xaf','\xfb'},{'\xd3','\x7b'},{'\xd3','\xa1'},{'\xaf','\xfe'},{'\xd3','\x75'},
+ {'\xd3','\xaf'},{'\x91','\x46'},{'\xd3','\xae'},{'\xd3','\xb6'},{'\xaf','\xf3'},
+ {'\xaf','\xf0'},{'\xd3','\xb4'},{'\xd3','\xb0'},{'\xd3','\xa7'},{'\xd3','\xa2'},
+ {'\xaf','\xf6'},{'\xaf','\xf2'},{'\xd3','\x77'},{'\xaf','\xee'},{'\xd3','\xb1'},
+ {'\xaf','\xef'},{'\x00','\x00'},{'\xd3','\x79'},{'\x9f','\xcb'},{'\x93','\x54'},
+ {'\x00','\x00'},{'\x84','\x75'},{'\x91','\x47'},{'\x8e','\xc7'},{'\x00','\x00'},
+ {'\x8e','\xf4'},{'\x8f','\x5f'},{'\x8a','\xf9'},{'\x89','\x57'},{'\x91','\x48'},
+ {'\x86','\xd1'},{'\x85','\xfa'},{'\x8e','\x73'},{'\x86','\xe1'},{'\x86','\xdf'},
+ {'\x8e','\xf2'},{'\x8f','\x7b'},{'\x87','\x4a'},{'\x88','\x51'},{'\x91','\x49'},
+ {'\x8e','\x4d'},{'\x91','\x4a'},{'\x8b','\xb9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd7','\x5e'},{'\xd7','\x60'},{'\xd7','\x65'},{'\xd7','\x79'},
+ {'\xb2','\xfc'},{'\xb2','\xf2'},{'\x00','\x00'},{'\xd7','\x5d'},{'\xb2','\xfd'},
+ {'\xb2','\xfe'},{'\xd7','\x68'},{'\xd7','\x6f'},{'\xd7','\x75'},{'\x00','\x00'},
+ {'\xd7','\x62'},{'\x00','\x00'},{'\xd7','\x69'},{'\x00','\x00'},{'\x87','\x48'},
+ {'\xb3','\x40'},{'\xd7','\x77'},{'\xd7','\x72'},{'\xb2','\xfa'},{'\xb2','\xf8'},
+ {'\xd7','\x6e'},{'\xd7','\x6a'},{'\xd7','\x5c'},{'\xb2','\xef'},{'\xd7','\x61'},
+ {'\xd7','\x59'},{'\x9f','\xcc'},{'\xb2','\xf7'},{'\xb2','\xf9'},{'\xd7','\x66'},
+ {'\xd7','\x63'},{'\xb2','\xf4'},{'\xd7','\x73'},{'\xb2','\xf1'},{'\xd7','\x64'},
+ {'\xd7','\x7a'},{'\xd7','\x6c'},{'\x91','\x4b'},{'\xd7','\x6b'},{'\xb2','\xf0'},
+ {'\x91','\x4c'},{'\xb2','\xfb'},{'\x00','\x00'},{'\xb2','\xf3'},{'\xd7','\x5a'},
+ {'\xd7','\x5f'},{'\xd7','\x70'},{'\xd7','\x76'},{'\xb3','\x41'},{'\xd7','\x5b'},
+ {'\xd7','\x67'},{'\xd7','\x6d'},{'\xb2','\xf6'},{'\x9f','\xcd'},{'\x00','\x00'},
+ {'\xd7','\x78'},{'\xd7','\x71'},{'\xd7','\x74'},{'\x85','\x50'},{'\x88','\x50'},
+ {'\x8e','\x7d'},{'\x85','\xfd'},{'\x91','\x4d'},{'\x8f','\x60'},{'\x89','\xf7'},
+ {'\x8e','\xf5'},{'\x87','\xf3'},{'\x8c','\xc2'},{'\x00','\x00'},{'\x91','\x4e'},
+ {'\xb2','\xf5'},{'\xfb','\xad'},{'\xdb','\x6c'},{'\xdb','\x60'},{'\xb5','\xd7'},
+ {'\xdb','\x7d'},{'\xdb','\xa7'},{'\xdb','\xaa'},{'\xb5','\xd5'},{'\xdb','\x68'},
+ {'\xdb','\xa3'},{'\xdb','\x69'},{'\xdb','\x77'},{'\xb5','\xe2'},{'\xdb','\x73'},
+ {'\xb5','\xdf'},{'\x9f','\xce'},{'\xdb','\x74'},{'\xdb','\x5d'},{'\x00','\x00'},
+ {'\xdb','\xa4'},{'\x00','\x00'},{'\xfe','\x52'},{'\xb5','\xe8'},{'\xdb','\xa1'},
+ {'\xdb','\x75'},{'\xdb','\xac'},{'\xdb','\x70'},{'\xdf','\xc8'},{'\x00','\x00'},
+ {'\xdb','\xaf'},{'\xb5','\xe6'},{'\xdb','\x6e'},{'\xdb','\x7a'},{'\xb5','\xe9'},
+ {'\xb5','\xd4'},{'\xdb','\x72'},{'\xdb','\xad'},{'\xdb','\x6b'},{'\xdb','\x64'},
+ {'\xdb','\x6f'},{'\x00','\x00'},{'\xdb','\x63'},{'\xdb','\x61'},{'\xb5','\xd0'},
+ {'\xdb','\xa5'},{'\xdb','\x6a'},{'\xdb','\xa8'},{'\x9f','\xcf'},{'\xdb','\xa9'},
+ {'\xb5','\xd8'},{'\xb5','\xdd'},{'\xb5','\xd9'},{'\xb5','\xe1'},{'\xdb','\x7e'},
+ {'\xb5','\xda'},{'\xdb','\x76'},{'\xdb','\x66'},{'\x91','\x4f'},{'\xb5','\xd2'},
+ {'\xdb','\x5e'},{'\xdb','\xa2'},{'\xdb','\xab'},{'\xdb','\x65'},{'\xb5','\xe0'},
+ {'\xdb','\xb0'},{'\xdb','\x71'},{'\x00','\x00'},{'\xdb','\x6d'},{'\x00','\x00'},
+ {'\xb5','\xd1'},{'\xb5','\xe5'},{'\x9f','\xd0'},{'\xdb','\x7c'},{'\xb5','\xe7'},
+ {'\x00','\x00'},{'\xdb','\x78'},{'\xb5','\xdc'},{'\xb5','\xd6'},{'\xb5','\xde'},
+ {'\xb5','\xd3'},{'\xb5','\xe4'},{'\xdb','\x79'},{'\xdb','\x67'},{'\xdb','\x7b'},
+ {'\xdb','\x62'},{'\xdb','\xa6'},{'\x9f','\xd1'},{'\x00','\x00'},{'\x9f','\xd2'},
+ {'\x00','\x00'},{'\x96','\xa7'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xae'},
+ {'\x96','\xbd'},{'\x8c','\xfd'},{'\x00','\x00'},{'\x00','\x00'},{'\xfd','\x63'},
+ {'\x9f','\xd3'},{'\x94','\xc9'},{'\xdb','\x5f'},{'\x89','\x5b'},{'\x89','\xf1'},
+ {'\x89','\x4d'},{'\x89','\x58'},{'\x8a','\xf7'},{'\xdf','\xc7'},{'\x91','\x50'},
+ {'\xdf','\xdd'},{'\xb8','\x55'},{'\xdf','\xcc'},{'\x9f','\xd4'},{'\xdf','\xca'},
+ {'\xdf','\xb5'},{'\xb8','\xa9'},{'\xdf','\xc5'},{'\xdf','\xd9'},{'\xdf','\xc1'},
+ {'\xb8','\xb1'},{'\xdf','\xd8'},{'\xdf','\xbf'},{'\xb5','\xe3'},{'\xdf','\xcf'},
+ {'\xdf','\xc0'},{'\xdf','\xd6'},{'\xb8','\xb0'},{'\xb8','\xa8'},{'\x9f','\xd5'},
+ {'\xdf','\xaa'},{'\xdf','\xb2'},{'\x00','\x00'},{'\xdf','\xcb'},{'\xdf','\xc3'},
+ {'\xdf','\xdc'},{'\xdf','\xc6'},{'\xb8','\xb6'},{'\xdf','\xd7'},{'\x91','\x51'},
+ {'\xb8','\xad'},{'\x9f','\xd6'},{'\xdf','\xc9'},{'\xdf','\xd1'},{'\xdf','\xb6'},
+ {'\xdf','\xd0'},{'\x00','\x00'},{'\xdf','\xe1'},{'\xdf','\xb1'},{'\xdf','\xd2'},
+ {'\x9f','\xd7'},{'\xdf','\xdf'},{'\x9f','\xd8'},{'\xdf','\xab'},{'\xb5','\xdb'},
+ {'\x9f','\xd9'},{'\xdf','\xb9'},{'\xdf','\xb8'},{'\xb8','\xaf'},{'\x91','\x52'},
+ {'\xdf','\xbc'},{'\xdf','\xbe'},{'\xdf','\xcd'},{'\xdf','\xde'},{'\xb8','\xb2'},
+ {'\x91','\x53'},{'\xb8','\xb3'},{'\x9f','\xda'},{'\xdf','\xb0'},{'\xb8','\xab'},
+ {'\xdf','\xb4'},{'\xdf','\xda'},{'\xb8','\xb4'},{'\x00','\x00'},{'\xb8','\xac'},
+ {'\xb8','\xae'},{'\xb8','\xb5'},{'\xdf','\xe0'},{'\xdf','\xd3'},{'\xdf','\xce'},
+ {'\x95','\xf5'},{'\x9f','\xdb'},{'\xdf','\xbb'},{'\xdf','\xba'},{'\xb8','\xaa'},
+ {'\xdf','\xac'},{'\xb8','\xa7'},{'\xdf','\xc4'},{'\xdf','\xad'},{'\xdf','\xc2'},
+ {'\x96','\xc0'},{'\x00','\x00'},{'\xdf','\xb7'},{'\xdf','\xdb'},{'\x9f','\xdc'},
+ {'\x9f','\xdd'},{'\x00','\x00'},{'\xb8','\xa6'},{'\x00','\x00'},{'\x91','\x54'},
+ {'\x00','\x00'},{'\xdf','\xb3'},{'\x8e','\xf1'},{'\x91','\x55'},{'\x8e','\xf3'},
+ {'\x00','\x00'},{'\x88','\x52'},{'\x8e','\xc8'},{'\xdf','\xaf'},{'\xdf','\xd5'},
+ {'\xdf','\xae'},{'\xbb','\x60'},{'\xe3','\xd3'},{'\x9f','\xde'},{'\x9f','\xdf'},
+ {'\xe3','\xc2'},{'\x00','\x00'},{'\x9f','\xe0'},{'\xe3','\xac'},{'\xe3','\xca'},
+ {'\xbb','\x58'},{'\xe3','\xbb'},{'\xe3','\xc5'},{'\xbb','\x5b'},{'\xe3','\xbe'},
+ {'\xbb','\x59'},{'\xe3','\xaf'},{'\xe3','\xcd'},{'\xe3','\xae'},{'\xe3','\xc1'},
+ {'\x9f','\xe1'},{'\xe3','\xad'},{'\x00','\x00'},{'\x00','\x00'},{'\xe3','\xbf'},
+ {'\xe3','\xc8'},{'\xe3','\xc6'},{'\xe3','\xba'},{'\xe3','\xb5'},{'\xe3','\xb3'},
+ {'\xfd','\x66'},{'\xe3','\xb4'},{'\xe3','\xc7'},{'\xe3','\xd2'},{'\xe3','\xbc'},
+ {'\xbb','\x5a'},{'\x00','\x00'},{'\xe3','\xb7'},{'\x00','\x00'},{'\xe3','\xcb'},
+ {'\x00','\x00'},{'\xbb','\x5d'},{'\xe3','\xb6'},{'\xe3','\xb0'},{'\xe3','\xc0'},
+ {'\xbb','\x61'},{'\x96','\xbc'},{'\x9f','\xe2'},{'\xbb','\x55'},{'\xbb','\x5e'},
+ {'\xe3','\xb8'},{'\xe3','\xb2'},{'\x00','\x00'},{'\xbb','\x57'},{'\xdf','\xd4'},
+ {'\xbb','\x56'},{'\xe3','\xc3'},{'\x00','\x00'},{'\xbb','\x54'},{'\xbb','\x63'},
+ {'\xbb','\x5c'},{'\xe3','\xc4'},{'\xe3','\xb9'},{'\xe3','\xb1'},{'\xe3','\xcc'},
+ {'\xe3','\xbd'},{'\xbb','\x62'},{'\xe3','\xd0'},{'\xbb','\x5f'},{'\xe3','\xcf'},
+ {'\x00','\x00'},{'\xe3','\xc9'},{'\xe3','\xce'},{'\x00','\x00'},{'\x94','\xca'},
+ {'\xfd','\x65'},{'\xe3','\xd1'},{'\x91','\x56'},{'\x8a','\xf8'},{'\x9f','\xe3'},
+ {'\x8a','\x5e'},{'\x90','\x6c'},{'\x9f','\xe4'},{'\x9f','\xe5'},{'\x91','\x57'},
+ {'\x9f','\xe6'},{'\x8f','\xaa'},{'\x8c','\xbd'},{'\xe7','\x73'},{'\xe7','\x74'},
+ {'\xe7','\x67'},{'\xe7','\x66'},{'\xe7','\x62'},{'\xbd','\xb4'},{'\x00','\x00'},
+ {'\xbd','\xac'},{'\xe7','\x76'},{'\xe7','\x75'},{'\xdf','\xa9'},{'\xe7','\x5f'},
+ {'\xe7','\x63'},{'\xe7','\x5d'},{'\x00','\x00'},{'\xe7','\x70'},{'\xe7','\x61'},
+ {'\x9f','\xe7'},{'\xe7','\x77'},{'\xe7','\x5a'},{'\xe7','\x58'},{'\xe7','\x64'},
+ {'\xe7','\x6e'},{'\xe7','\x69'},{'\xbd','\xb6'},{'\xe7','\x4f'},{'\x00','\x00'},
+ {'\xe7','\x6d'},{'\x9f','\xe8'},{'\x00','\x00'},{'\x9f','\xe9'},{'\xbd','\xb7'},
+ {'\xdf','\xbd'},{'\xe7','\x5b'},{'\xe7','\x52'},{'\xe7','\x55'},{'\xe7','\x7b'},
+ {'\xe7','\x5c'},{'\xe7','\x53'},{'\xe7','\x51'},{'\xe7','\x4e'},{'\x9f','\xea'},
+ {'\xbd','\xb0'},{'\xe7','\x65'},{'\xbd','\xaf'},{'\xbd','\xb3'},{'\xe7','\x60'},
+ {'\xe7','\x68'},{'\xbd','\xa9'},{'\xe7','\x78'},{'\xe7','\x7c'},{'\xbd','\xab'},
+ {'\x00','\x00'},{'\xe7','\x57'},{'\xe7','\x6b'},{'\xe7','\x6f'},{'\xe7','\x54'},
+ {'\xe7','\x79'},{'\xbd','\xb2'},{'\x00','\x00'},{'\xbd','\xb1'},{'\xe7','\x4c'},
+ {'\xbd','\xb5'},{'\xe7','\x72'},{'\xe7','\x56'},{'\xe7','\x6a'},{'\xe7','\x50'},
+ {'\xe7','\x5e'},{'\xe7','\x59'},{'\xbd','\xad'},{'\xbd','\xae'},{'\xe7','\x6c'},
+ {'\xe7','\x7d'},{'\xe7','\x7a'},{'\xe7','\x71'},{'\x00','\x00'},{'\x9f','\xeb'},
+ {'\xfe','\x4c'},{'\x93','\x60'},{'\x00','\x00'},{'\x8a','\x5d'},{'\x91','\x58'},
+ {'\x90','\x46'},{'\x8c','\x4e'},{'\xe7','\x4d'},{'\x8c','\x4d'},{'\xbd','\xaa'},
+ {'\xeb','\x49'},{'\x00','\x00'},{'\xeb','\x40'},{'\xeb','\x43'},{'\x9f','\xed'},
+ {'\xbf','\xbb'},{'\xeb','\x45'},{'\xea','\xf9'},{'\xeb','\x41'},{'\xeb','\x47'},
+ {'\xbf','\xb8'},{'\xbf','\xbc'},{'\xbf','\xb6'},{'\xfd','\x68'},{'\x9f','\xee'},
+ {'\xea','\xfb'},{'\xeb','\x4c'},{'\x00','\x00'},{'\x00','\x00'},{'\xeb','\x46'},
+ {'\x9f','\xef'},{'\xea','\xfc'},{'\xeb','\x55'},{'\xeb','\x4f'},{'\xea','\xf8'},
+ {'\xee','\x46'},{'\xea','\xfe'},{'\xbf','\xb7'},{'\x91','\x59'},{'\xeb','\x4a'},
+ {'\x00','\x00'},{'\xeb','\x54'},{'\xbf','\xbf'},{'\x9f','\xf0'},{'\xeb','\x51'},
+ {'\xea','\xfd'},{'\xeb','\x44'},{'\xeb','\x48'},{'\xeb','\x42'},{'\xeb','\x56'},
+ {'\xeb','\x53'},{'\xeb','\x50'},{'\xbf','\xb9'},{'\xbf','\xba'},{'\xbf','\xbe'},
+ {'\xea','\xfa'},{'\xeb','\x57'},{'\xbf','\xbd'},{'\xeb','\x4d'},{'\x9f','\xf1'},
+ {'\x9f','\xf2'},{'\xeb','\x4b'},{'\x8f','\xe2'},{'\x9f','\xf3'},{'\x8c','\x51'},
+ {'\xeb','\x4e'},{'\xee','\x53'},{'\xee','\x40'},{'\xee','\x45'},{'\xee','\x52'},
+ {'\xee','\x44'},{'\xed','\xfb'},{'\xee','\x41'},{'\x00','\x00'},{'\xc1','\xa2'},
+ {'\x00','\x00'},{'\xed','\xf4'},{'\xee','\x4d'},{'\xee','\x4f'},{'\xed','\xf3'},
+ {'\xc1','\xa1'},{'\xee','\x51'},{'\xee','\x49'},{'\xc1','\xa8'},{'\xee','\x50'},
+ {'\xee','\x42'},{'\xc1','\xaa'},{'\xed','\xf9'},{'\xeb','\x52'},{'\xee','\x4a'},
+ {'\xee','\x47'},{'\xed','\xf5'},{'\xee','\x55'},{'\xc1','\xa4'},{'\x00','\x00'},
+ {'\x9d','\x76'},{'\xc1','\xa5'},{'\xed','\xf7'},{'\xee','\x48'},{'\x91','\x5a'},
+ {'\xee','\x54'},{'\xee','\x4b'},{'\xed','\xfd'},{'\xc1','\xa7'},{'\xc1','\xa3'},
+ {'\xee','\x4c'},{'\xed','\xfe'},{'\xee','\x56'},{'\xed','\xf8'},{'\xee','\x43'},
+ {'\xee','\x4e'},{'\xed','\xfa'},{'\xed','\xfc'},{'\x00','\x00'},{'\xc2','\xcb'},
+ {'\xed','\xf6'},{'\xc1','\xa9'},{'\xc2','\xc4'},{'\xc1','\x7e'},{'\x91','\x5b'},
+ {'\x93','\xd6'},{'\x00','\x00'},{'\x82','\x7e'},{'\xc1','\xa6'},{'\xc2','\xc8'},
+ {'\xf0','\xb3'},{'\x00','\x00'},{'\xf0','\xa9'},{'\xf0','\xa4'},{'\xf0','\xaa'},
+ {'\xf0','\xb4'},{'\xf0','\xb8'},{'\xf0','\xb7'},{'\xc2','\xca'},{'\xc2','\xc9'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf0','\xab'},{'\xf0','\xb9'},{'\xf0','\xae'},
+ {'\xf0','\xa6'},{'\x91','\x5c'},{'\xf0','\xa8'},{'\xf0','\xa7'},{'\xf0','\xad'},
+ {'\xf0','\xb2'},{'\xf0','\xa5'},{'\xf0','\xac'},{'\xf0','\xb1'},{'\xc2','\xc7'},
+ {'\x00','\x00'},{'\xf0','\xaf'},{'\x00','\x00'},{'\xc2','\xc5'},{'\xf0','\xb0'},
+ {'\xc2','\xc3'},{'\xc2','\xc6'},{'\xf2','\xd5'},{'\xf0','\xb5'},{'\x8c','\xa4'},
+ {'\x00','\x00'},{'\xc3','\xc2'},{'\x9f','\xf4'},{'\xf2','\xcd'},{'\xf2','\xd1'},
+ {'\xf2','\xc9'},{'\xf2','\xcc'},{'\x00','\x00'},{'\xf2','\xd4'},{'\xc3','\xc0'},
+ {'\xf2','\xd9'},{'\xf2','\xd2'},{'\x9f','\xf5'},{'\xf2','\xca'},{'\xf2','\xda'},
+ {'\xf2','\xd3'},{'\xc3','\xc3'},{'\xc3','\xc4'},{'\xf2','\xd7'},{'\x00','\x00'},
+ {'\xf2','\xcb'},{'\xc3','\xbf'},{'\xc3','\xc1'},{'\xf2','\xc6'},{'\xf2','\xce'},
+ {'\xf2','\xc8'},{'\x9f','\xf6'},{'\xf2','\xd8'},{'\xf2','\xd6'},{'\xf2','\xc7'},
+ {'\xf2','\xcf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf4','\xbe'},
+ {'\xc3','\xc5'},{'\xf2','\xd0'},{'\xc4','\xa7'},{'\xc4','\xa9'},{'\xc4','\xa6'},
+ {'\x9f','\xf7'},{'\xf4','\xc3'},{'\xf4','\xbb'},{'\xf4','\xb9'},{'\xf4','\xbd'},
+ {'\xf4','\xba'},{'\xfd','\x6a'},{'\x00','\x00'},{'\xf4','\xbf'},{'\xf4','\xc1'},
+ {'\xc4','\xaa'},{'\xc4','\xac'},{'\x00','\x00'},{'\xf4','\xc0'},{'\xc4','\xad'},
+ {'\xc4','\xab'},{'\xf4','\xc2'},{'\x9f','\xf8'},{'\x00','\x00'},{'\x9f','\xf9'},
+ {'\xfd','\x6b'},{'\xc4','\xa8'},{'\x00','\x00'},{'\x91','\x5d'},{'\x9f','\xfa'},
+ {'\x00','\x00'},{'\x91','\x5e'},{'\xc4','\xf4'},{'\xf5','\xf1'},{'\xf5','\xf7'},
+ {'\xc4','\xf6'},{'\xf4','\xbc'},{'\xf5','\xf6'},{'\x00','\x00'},{'\xf5','\xfd'},
+ {'\xf5','\xf4'},{'\xf5','\xfb'},{'\xf5','\xfa'},{'\xf4','\xb8'},{'\xf5','\xf5'},
+ {'\xf0','\xb6'},{'\xf5','\xfe'},{'\xf5','\xf3'},{'\xf5','\xf8'},{'\x9f','\xfb'},
+ {'\xf5','\xfc'},{'\xf5','\xf2'},{'\x00','\x00'},{'\xf7','\x4a'},{'\xc4','\xf5'},
+ {'\xf5','\xf9'},{'\xfb','\xae'},{'\x94','\xcb'},{'\xf7','\xf4'},{'\xf7','\x4b'},
+ {'\xf7','\x49'},{'\xf7','\x47'},{'\xf7','\x48'},{'\xf7','\x4c'},{'\x00','\x00'},
+ {'\xc5','\xd9'},{'\xf7','\xf2'},{'\xf7','\xf0'},{'\xf7','\xf5'},{'\xf7','\xf3'},
+ {'\x00','\x00'},{'\xf7','\xf6'},{'\xc5','\xda'},{'\xf7','\xf1'},{'\x00','\x00'},
+ {'\x9f','\xfc'},{'\xf8','\xbc'},{'\x00','\x00'},{'\x9f','\xfd'},{'\xf9','\x45'},
+ {'\xf9','\x46'},{'\xf9','\x47'},{'\x00','\x00'},{'\x00','\x00'},{'\xf9','\xc7'},
+ {'\xf9','\xbd'},{'\xca','\x4f'},{'\xaa','\xea'},{'\x86','\x40'},{'\xad','\x68'},
+ {'\x87','\xcb'},{'\xd3','\xb8'},{'\xd3','\xb7'},{'\xb0','\x40'},{'\xb3','\x42'},
+ {'\xd7','\x7c'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\x7b'},{'\x85','\x52'},
+ {'\xb5','\xea'},{'\xb8','\xb8'},{'\x00','\x00'},{'\xb8','\xb7'},{'\xb8','\xb9'},
+ {'\x00','\x00'},{'\xe3','\xd4'},{'\xe7','\x7e'},{'\xeb','\x58'},{'\xeb','\x5a'},
+ {'\xeb','\x59'},{'\x00','\x00'},{'\xc1','\xab'},{'\xee','\x57'},{'\xf0','\xba'},
+ {'\xf9','\xa5'},{'\xa6','\xe4'},{'\x95','\x78'},{'\xcd','\xc9'},{'\xcd','\xca'},
+ {'\xcd','\xc8'},{'\xcd','\xc7'},{'\xaa','\xeb'},{'\x9f','\xfe'},{'\xd0','\xa9'},
+ {'\xd0','\xa7'},{'\x00','\x00'},{'\x00','\x00'},{'\xd0','\xa6'},{'\x00','\x00'},
+ {'\xad','\x69'},{'\xad','\x6b'},{'\xad','\x6a'},{'\xd0','\xa8'},{'\x8a','\xaf'},
+ {'\x88','\x53'},{'\x8f','\xc4'},{'\x87','\x4c'},{'\x8b','\xba'},{'\x89','\x5a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd3','\xc4'},{'\xd3','\xc1'},{'\xd3','\xbf'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb0','\x41'},{'\xd3','\xc2'},{'\xb0','\x46'},
+ {'\xd3','\xbc'},{'\xd3','\xcb'},{'\x00','\x00'},{'\xd3','\xcd'},{'\xd3','\xbd'},
+ {'\xfe','\xbb'},{'\xb0','\x43'},{'\xd3','\xce'},{'\xd3','\xc9'},{'\xd3','\xbb'},
+ {'\xd3','\xc0'},{'\xd3','\xca'},{'\xd3','\xc6'},{'\xd3','\xc3'},{'\x00','\x00'},
+ {'\xb0','\x48'},{'\xd3','\xcc'},{'\xd3','\xbe'},{'\x00','\x00'},{'\xfe','\xbc'},
+ {'\xd3','\xc7'},{'\xd3','\xb9'},{'\xb0','\x47'},{'\xb0','\x44'},{'\xd3','\xc5'},
+ {'\x00','\x00'},{'\xd3','\xc8'},{'\xd3','\xba'},{'\xb0','\x45'},{'\xb0','\x42'},
+ {'\x94','\xcc'},{'\x86','\x43'},{'\xfe','\xbd'},{'\x00','\x00'},{'\xb3','\x4c'},
+ {'\xd7','\xa5'},{'\xb3','\x4b'},{'\xfe','\xbe'},{'\xd7','\xa8'},{'\xd7','\xab'},
+ {'\xb3','\x48'},{'\xb3','\x46'},{'\xd7','\x7e'},{'\xd7','\xa9'},{'\xd7','\xa7'},
+ {'\xd7','\xa4'},{'\xd7','\xac'},{'\xd7','\xad'},{'\xd7','\xaf'},{'\xd7','\xb0'},
+ {'\xd7','\x7d'},{'\xb3','\x45'},{'\xd7','\xa2'},{'\xd7','\xa1'},{'\xd7','\xae'},
+ {'\xb3','\x47'},{'\xd7','\xa3'},{'\xb3','\x49'},{'\xb3','\x44'},{'\xd7','\xa6'},
+ {'\xb3','\x4d'},{'\x8c','\xfe'},{'\xb3','\x4a'},{'\xd7','\xaa'},{'\x92','\xac'},
+ {'\x82','\x4c'},{'\x8f','\xc3'},{'\xb5','\xf1'},{'\xdb','\xbf'},{'\x00','\x00'},
+ {'\xdb','\xb4'},{'\xb5','\xee'},{'\x00','\x00'},{'\xdf','\xe7'},{'\xdb','\xbd'},
+ {'\xdb','\xb1'},{'\xb5','\xec'},{'\xdb','\xb6'},{'\xb5','\xef'},{'\xdb','\xba'},
+ {'\xdb','\xb8'},{'\xb5','\xf2'},{'\xb5','\xeb'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xdb','\xb2'},{'\xdb','\xb5'},{'\xb5','\xf0'},{'\x00','\x00'},{'\xdb','\xb3'},
+ {'\x00','\x00'},{'\xdb','\xbe'},{'\xdb','\xbc'},{'\xdb','\xb7'},{'\xdb','\xb9'},
+ {'\xdb','\xbb'},{'\xb5','\xed'},{'\x8d','\x72'},{'\x94','\xcd'},{'\x8f','\x61'},
+ {'\x8e','\x4e'},{'\x8a','\xfa'},{'\x8e','\xf7'},{'\x8f','\xe3'},{'\xdf','\xe8'},
+ {'\xdf','\xee'},{'\xdf','\xe4'},{'\xdf','\xea'},{'\xb8','\xba'},{'\xdf','\xe6'},
+ {'\xb8','\xc0'},{'\x00','\x00'},{'\x00','\x00'},{'\xb8','\xbf'},{'\x00','\x00'},
+ {'\xb8','\xbe'},{'\xdf','\xed'},{'\xb8','\xc1'},{'\xb8','\xc2'},{'\xdf','\xe3'},
+ {'\xdf','\xf0'},{'\xb8','\xc3'},{'\xb8','\xbd'},{'\xb8','\xbc'},{'\xdf','\xec'},
+ {'\xb8','\xc4'},{'\xdf','\xe2'},{'\xdf','\xe5'},{'\xdf','\xef'},{'\xdf','\xeb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xe3','\xf4'},{'\xe3','\xe9'},{'\xb8','\xbb'},
+ {'\x00','\x00'},{'\x91','\x60'},{'\x00','\x00'},{'\x88','\x54'},{'\xbb','\x6a'},
+ {'\xe3','\xdd'},{'\xe3','\xf2'},{'\xe3','\xde'},{'\xbb','\x65'},{'\x00','\x00'},
+ {'\xe3','\xdb'},{'\x00','\x00'},{'\xe3','\xe4'},{'\xe3','\xdc'},{'\xbb','\x67'},
+ {'\xe3','\xd6'},{'\xe3','\xf1'},{'\xbb','\x68'},{'\xe3','\xee'},{'\xe3','\xef'},
+ {'\xe3','\xd7'},{'\xbb','\x6d'},{'\xe3','\xe6'},{'\x00','\x00'},{'\xe3','\xe0'},
+ {'\xe3','\xe7'},{'\xe3','\xda'},{'\x00','\x00'},{'\xe3','\xf3'},{'\xe3','\xeb'},
+ {'\xe3','\xe5'},{'\xe3','\xd5'},{'\xbb','\x69'},{'\xe3','\xec'},{'\x00','\x00'},
+ {'\xbb','\x6c'},{'\xe3','\xf0'},{'\x00','\x00'},{'\xe3','\xea'},{'\xbb','\x66'},
+ {'\xe3','\xe8'},{'\x00','\x00'},{'\xe3','\xe2'},{'\xbb','\x64'},{'\xe3','\xd9'},
+ {'\xe3','\xe1'},{'\xe3','\xed'},{'\xe3','\xdf'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe3','\xe3'},{'\x8b','\xbb'},{'\x8a','\x61'},{'\x8a','\xfb'},{'\x00','\x00'},
+ {'\x82','\xa2'},{'\xbd','\xc1'},{'\xdf','\xe9'},{'\xe7','\xb2'},{'\xe7','\xbb'},
+ {'\xe7','\xb1'},{'\xe7','\xad'},{'\xe7','\xaa'},{'\xbd','\xc2'},{'\xe7','\xa8'},
+ {'\xbb','\x6b'},{'\xe7','\xa1'},{'\xbd','\xc0'},{'\xe7','\xa7'},{'\xbd','\xbf'},
+ {'\xe7','\xac'},{'\xe7','\xa9'},{'\xe7','\xb9'},{'\xe7','\xb4'},{'\xe7','\xae'},
+ {'\xe7','\xb3'},{'\xbd','\xbb'},{'\xe7','\xab'},{'\xe7','\xbe'},{'\xe7','\xa2'},
+ {'\xe7','\xa3'},{'\xe7','\xba'},{'\xbd','\xbc'},{'\xe7','\xbf'},{'\xbd','\xbe'},
+ {'\xe7','\xc0'},{'\xe7','\xb0'},{'\xe3','\xd8'},{'\xe7','\xb6'},{'\xe7','\xaf'},
+ {'\xe7','\xb8'},{'\xe7','\xb5'},{'\x91','\x61'},{'\xfd','\x45'},{'\x00','\x00'},
+ {'\xe7','\xa6'},{'\xbd','\xb9'},{'\xe7','\xbd'},{'\xbd','\xba'},{'\xe7','\xa4'},
+ {'\xbd','\xbd'},{'\xeb','\x64'},{'\xe7','\xb7'},{'\xe7','\xbc'},{'\x8a','\x60'},
+ {'\x91','\x62'},{'\x8f','\xe4'},{'\x82','\x75'},{'\x00','\x00'},{'\xeb','\x61'},
+ {'\xbd','\xb8'},{'\xbf','\xc0'},{'\xeb','\x6b'},{'\xeb','\x67'},{'\xfb','\x6c'},
+ {'\xeb','\x65'},{'\xeb','\x60'},{'\xeb','\x6f'},{'\x00','\x00'},{'\x91','\x63'},
+ {'\xfd','\x47'},{'\xbf','\xc4'},{'\x00','\x00'},{'\xeb','\x5c'},{'\xeb','\x68'},
+ {'\xeb','\x69'},{'\xeb','\x5f'},{'\xeb','\x5e'},{'\xeb','\x6c'},{'\x00','\x00'},
+ {'\xeb','\x62'},{'\xeb','\x5d'},{'\xeb','\x63'},{'\x00','\x00'},{'\xeb','\x6e'},
+ {'\xeb','\x5b'},{'\xeb','\x6d'},{'\xeb','\x6a'},{'\xbf','\xc2'},{'\xbf','\xc1'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xbf','\xc3'},{'\xeb','\x66'},{'\xf0','\xcb'},
+ {'\xfe','\xbf'},{'\x00','\x00'},{'\x00','\x00'},{'\x91','\x64'},{'\xfd','\x46'},
+ {'\xee','\x59'},{'\xc1','\xb1'},{'\xee','\x5d'},{'\xee','\x5a'},{'\xee','\x61'},
+ {'\xee','\x67'},{'\xee','\x5c'},{'\xfe','\xc0'},{'\xee','\x70'},{'\xc1','\xae'},
+ {'\xee','\x6a'},{'\xee','\x5f'},{'\xee','\x6b'},{'\xee','\x66'},{'\xee','\x6d'},
+ {'\xee','\x5e'},{'\xc1','\xb3'},{'\xc1','\xb2'},{'\xee','\x60'},{'\xee','\x6e'},
+ {'\xee','\x58'},{'\xee','\x6c'},{'\xc1','\xac'},{'\xfd','\x49'},{'\xee','\x64'},
+ {'\xee','\x63'},{'\xee','\x68'},{'\xee','\x5b'},{'\xc1','\xb0'},{'\x91','\x65'},
+ {'\xc1','\xb4'},{'\xee','\x62'},{'\xee','\x69'},{'\xc1','\xb5'},{'\xee','\x65'},
+ {'\x00','\x00'},{'\x96','\xc7'},{'\x00','\x00'},{'\x91','\x66'},{'\xc1','\xad'},
+ {'\xc1','\xaf'},{'\xf0','\xc7'},{'\xf0','\xc5'},{'\x00','\x00'},{'\xfd','\x4c'},
+ {'\xf0','\xcc'},{'\xf0','\xc9'},{'\xf0','\xcd'},{'\xfe','\xc5'},{'\xf0','\xbe'},
+ {'\xf0','\xc6'},{'\xf0','\xd1'},{'\xee','\x6f'},{'\xf0','\xc2'},{'\xc2','\xcf'},
+ {'\xe7','\xa5'},{'\xf0','\xbd'},{'\xf0','\xca'},{'\xf0','\xc4'},{'\xf0','\xc1'},
+ {'\xf0','\xbc'},{'\xf0','\xbb'},{'\xf0','\xd0'},{'\x00','\x00'},{'\xf0','\xc0'},
+ {'\xf0','\xbf'},{'\xc2','\xcd'},{'\xf0','\xc8'},{'\xfb','\xab'},{'\xc2','\xcc'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc2','\xce'},{'\xf0','\xc3'},{'\xf0','\xcf'},
+ {'\xfd','\x4d'},{'\xf2','\xde'},{'\xf2','\xdf'},{'\x00','\x00'},{'\xc3','\xc9'},
+ {'\xf2','\xdc'},{'\xc3','\xc6'},{'\xf2','\xe4'},{'\x00','\x00'},{'\xc3','\xca'},
+ {'\xf2','\xe6'},{'\xf2','\xdb'},{'\xf0','\xce'},{'\xf2','\xe8'},{'\xf2','\xdd'},
+ {'\xfb','\x72'},{'\xc3','\xc7'},{'\xf2','\xe3'},{'\x91','\x67'},{'\xf2','\xe5'},
+ {'\xf2','\xe0'},{'\xf2','\xe7'},{'\xf2','\xe2'},{'\xf2','\xe1'},{'\xc3','\xc8'},
+ {'\x91','\x68'},{'\xfd','\x4e'},{'\xf4','\xc5'},{'\xf4','\xc6'},{'\x00','\x00'},
+ {'\xf4','\xc8'},{'\xc4','\xae'},{'\xc4','\xaf'},{'\xf4','\xc9'},{'\xf4','\xc7'},
+ {'\xfd','\x4f'},{'\xf4','\xc4'},{'\x00','\x00'},{'\xf6','\x42'},{'\xf6','\x45'},
+ {'\xf6','\x41'},{'\x00','\x00'},{'\xc4','\xfa'},{'\xf6','\x43'},{'\xc4','\xf9'},
+ {'\xc4','\xf8'},{'\xc4','\xf7'},{'\xf6','\x44'},{'\xf7','\x51'},{'\xf7','\x4f'},
+ {'\x91','\x69'},{'\xf7','\x4e'},{'\xf6','\x40'},{'\xf7','\x50'},{'\xf6','\x46'},
+ {'\xf7','\x4d'},{'\xfd','\x50'},{'\xf7','\xf9'},{'\xf7','\xd7'},{'\xf7','\xf7'},
+ {'\xc5','\xdb'},{'\xf7','\xf8'},{'\xf7','\xfa'},{'\x00','\x00'},{'\xf8','\xbf'},
+ {'\xc5','\xfa'},{'\xf8','\xbe'},{'\xf8','\xbd'},{'\xc5','\xfb'},{'\x00','\x00'},
+ {'\xc6','\x5a'},{'\xf9','\x6e'},{'\xf9','\xa7'},{'\xf9','\xa6'},{'\xf9','\xa8'},
+ {'\xa6','\xe5'},{'\xd0','\xaa'},{'\xfd','\x51'},{'\xd3','\xcf'},{'\xd3','\xd0'},
+ {'\x8d','\x75'},{'\x92','\xdb'},{'\x00','\x00'},{'\xdb','\xc0'},{'\x00','\x00'},
+ {'\xf6','\x47'},{'\xf8','\xc0'},{'\xa6','\xe6'},{'\xad','\x6c'},{'\xd0','\xab'},
+ {'\xfe','\xc6'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xb1'},{'\xb3','\x4e'},
+ {'\x83','\xf5'},{'\xdb','\xc2'},{'\xdb','\xc1'},{'\xb5','\xf3'},{'\x00','\x00'},
+ {'\xb8','\xc5'},{'\xe7','\xc1'},{'\xbd','\xc3'},{'\x00','\x00'},{'\xbd','\xc4'},
+ {'\xfd','\x5b'},{'\x00','\x00'},{'\xfe','\xc7'},{'\xbf','\xc5'},{'\xc5','\xfc'},
+ {'\xa6','\xe7'},{'\x91','\xd6'},{'\x86','\x44'},{'\x00','\x00'},{'\xd0','\xac'},
+ {'\xaa','\xed'},{'\xd0','\xae'},{'\xd0','\xad'},{'\xad','\x6d'},{'\x8c','\xdc'},
+ {'\xd3','\xd1'},{'\x84','\x7c'},{'\xd3','\xd8'},{'\xb0','\x49'},{'\xd3','\xd6'},
+ {'\xd3','\xd4'},{'\x00','\x00'},{'\xd3','\xdb'},{'\xd3','\xd2'},{'\xd3','\xd3'},
+ {'\xb0','\x4a'},{'\x00','\x00'},{'\xb0','\x4e'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd3','\xdc'},{'\xb0','\x4d'},{'\xd3','\xda'},{'\xd3','\xd7'},{'\xd3','\xd5'},
+ {'\xb0','\x4b'},{'\xb0','\x4c'},{'\xd3','\xd9'},{'\x8b','\xbd'},{'\x88','\xd3'},
+ {'\x00','\x00'},{'\xfe','\xc8'},{'\xb3','\x50'},{'\xd7','\xb2'},{'\x00','\x00'},
+ {'\xb3','\x55'},{'\xd7','\xc2'},{'\xb3','\x54'},{'\xd7','\xc4'},{'\xfe','\xc9'},
+ {'\xfe','\xca'},{'\xd7','\xb8'},{'\xb3','\x52'},{'\xd7','\xc3'},{'\x00','\x00'},
+ {'\xd7','\xb3'},{'\xb3','\x53'},{'\xd7','\xbf'},{'\xd7','\xbb'},{'\xd7','\xbd'},
+ {'\xd7','\xb7'},{'\xd7','\xbe'},{'\x90','\xba'},{'\x00','\x00'},{'\xb3','\x4f'},
+ {'\xd7','\xba'},{'\xfd','\x56'},{'\xd7','\xb9'},{'\xd7','\xb5'},{'\x00','\x00'},
+ {'\xd7','\xc0'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xbc'},{'\xd7','\xb4'},
+ {'\x00','\x00'},{'\xd7','\xb6'},{'\xb3','\x51'},{'\xd7','\xc1'},{'\x8c','\xdb'},
+ {'\x91','\x6a'},{'\x00','\x00'},{'\x94','\xce'},{'\xb5','\xf6'},{'\xdb','\xcd'},
+ {'\x00','\x00'},{'\x95','\xdd'},{'\x91','\x6c'},{'\xdb','\xc9'},{'\xdb','\xcb'},
+ {'\xdb','\xc6'},{'\xdb','\xc5'},{'\xdb','\xc3'},{'\x00','\x00'},{'\xdb','\xca'},
+ {'\xdb','\xcc'},{'\xdb','\xc8'},{'\x91','\x6d'},{'\xdb','\xc7'},{'\xb5','\xf4'},
+ {'\xb5','\xf5'},{'\x94','\xcf'},{'\x94','\xd0'},{'\x86','\x45'},{'\x8b','\xbc'},
+ {'\xfb','\x63'},{'\x00','\x00'},{'\xdb','\xcf'},{'\xb8','\xcd'},{'\xdf','\xf2'},
+ {'\xdf','\xf8'},{'\xdf','\xf3'},{'\xdf','\xf4'},{'\xf9','\xd8'},{'\xdf','\xf9'},
+ {'\x00','\x00'},{'\xb8','\xcf'},{'\x00','\x00'},{'\xb8','\xc7'},{'\xb8','\xce'},
+ {'\xdf','\xf1'},{'\xdb','\xc4'},{'\xb8','\xca'},{'\xb8','\xc8'},{'\xdf','\xf7'},
+ {'\xdf','\xf6'},{'\xb8','\xc9'},{'\xb8','\xcb'},{'\xdf','\xf5'},{'\xb8','\xc6'},
+ {'\x00','\x00'},{'\xb8','\xcc'},{'\x8f','\x62'},{'\x8f','\xc5'},{'\x89','\x5c'},
+ {'\x91','\x6e'},{'\xfe','\xcb'},{'\xe3','\xf6'},{'\xbb','\x74'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe4','\x42'},{'\xe4','\x41'},{'\x00','\x00'},{'\xe3','\xfb'},
+ {'\xbb','\x76'},{'\xe4','\x40'},{'\xe3','\xf7'},{'\xe3','\xf8'},{'\xbb','\x6e'},
+ {'\xbb','\x70'},{'\x91','\x6f'},{'\xe3','\xfd'},{'\xe3','\xf5'},{'\xbb','\x72'},
+ {'\xbb','\x71'},{'\xe3','\xf9'},{'\xe3','\xfe'},{'\xe3','\xfc'},{'\xbb','\x73'},
+ {'\xe3','\xfa'},{'\xfe','\xcc'},{'\xfe','\xcd'},{'\xdb','\xce'},{'\xbb','\x6f'},
+ {'\x00','\x00'},{'\x94','\xd1'},{'\xe7','\xc2'},{'\xe7','\xc9'},{'\xbd','\xc6'},
+ {'\x00','\x00'},{'\xe7','\xcd'},{'\xbd','\xca'},{'\xe7','\xc5'},{'\xe7','\xc3'},
+ {'\x00','\x00'},{'\xe7','\xcc'},{'\x00','\x00'},{'\xbd','\xc5'},{'\xe7','\xcb'},
+ {'\xbd','\xc7'},{'\xbd','\xc8'},{'\xe7','\xc4'},{'\xbd','\xc9'},{'\xe7','\xca'},
+ {'\xe7','\xc6'},{'\xe7','\xc7'},{'\xe7','\xc8'},{'\xbb','\x75'},{'\x8a','\x63'},
+ {'\x91','\x70'},{'\x91','\x71'},{'\xeb','\x70'},{'\xeb','\x7c'},{'\x00','\x00'},
+ {'\xbf','\xca'},{'\xeb','\x77'},{'\xeb','\x79'},{'\xfe','\xce'},{'\xbf','\xc8'},
+ {'\xeb','\x71'},{'\xeb','\x75'},{'\x00','\x00'},{'\xeb','\x78'},{'\xbf','\xc6'},
+ {'\xbf','\xc9'},{'\xeb','\x7b'},{'\xeb','\x73'},{'\xeb','\x74'},{'\xeb','\x7a'},
+ {'\xeb','\x72'},{'\xeb','\x76'},{'\xbf','\xc7'},{'\xee','\x72'},{'\x8c','\x53'},
+ {'\xee','\x71'},{'\xc1','\xb7'},{'\xee','\x77'},{'\xc1','\xb9'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc1','\xb6'},{'\xee','\x73'},{'\xc1','\xba'},{'\xee','\x74'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xee','\x75'},{'\xee','\x78'},{'\xfd','\x58'},
+ {'\xc1','\xb8'},{'\x00','\x00'},{'\xf0','\xd6'},{'\xfe','\xcf'},{'\x00','\x00'},
+ {'\xf0','\xd9'},{'\x00','\x00'},{'\xf0','\xd3'},{'\xf0','\xd5'},{'\xfd','\x59'},
+ {'\x00','\x00'},{'\xf0','\xd4'},{'\xf0','\xd7'},{'\xf0','\xd8'},{'\xee','\x76'},
+ {'\xf0','\xd2'},{'\xfe','\xd0'},{'\x00','\x00'},{'\xc3','\xcd'},{'\xf2','\xec'},
+ {'\xf2','\xef'},{'\xf2','\xf1'},{'\xf2','\xea'},{'\xf2','\xeb'},{'\xf2','\xee'},
+ {'\xf2','\xf0'},{'\xc3','\xce'},{'\xc3','\xcc'},{'\xc3','\xcb'},{'\xf2','\xed'},
+ {'\xf2','\xe9'},{'\xf4','\xca'},{'\xc4','\xb0'},{'\xfe','\xd1'},{'\xf4','\xcb'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf6','\x49'},{'\xc4','\xfb'},{'\xf6','\x4b'},
+ {'\xc4','\xfc'},{'\xf6','\x48'},{'\xf6','\x4a'},{'\xc5','\xa8'},{'\x00','\x00'},
+ {'\xf7','\x52'},{'\xc5','\xa7'},{'\xf7','\xfd'},{'\xf7','\xfc'},{'\x00','\x00'},
+ {'\xf7','\xfb'},{'\x91','\x72'},{'\x00','\x00'},{'\xf9','\x48'},{'\xf9','\x49'},
+ {'\xf9','\x4b'},{'\xf9','\x4a'},{'\x00','\x00'},{'\xca','\x50'},{'\xa6','\xe8'},
+ {'\xfe','\xd2'},{'\xad','\x6e'},{'\xd7','\xc5'},{'\xb5','\xf7'},{'\x00','\x00'},
+ {'\xdf','\xfa'},{'\xc2','\xd0'},{'\x95','\xf6'},{'\xf2','\xf2'},{'\xfd','\x6d'},
+ {'\xfd','\x6e'},{'\xa8','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\x57'},{'\x00','\x00'},{'\xfe','\xd3'},{'\x00','\x00'},{'\xb3','\x56'},
+ {'\xfd','\x6f'},{'\xdb','\xd0'},{'\xb5','\xf8'},{'\xdb','\xd2'},{'\xdb','\xd1'},
+ {'\x00','\x00'},{'\x92','\x60'},{'\xdf','\xfb'},{'\xb8','\xd0'},{'\xe4','\x43'},
+ {'\xe4','\x46'},{'\xe4','\x45'},{'\x00','\x00'},{'\xe4','\x44'},{'\xe7','\xce'},
+ {'\xe7','\xd0'},{'\xe7','\xcf'},{'\xfb','\xaf'},{'\xbf','\xcc'},{'\x93','\xe1'},
+ {'\x00','\x00'},{'\x95','\xc5'},{'\xbf','\xcb'},{'\x00','\x00'},{'\xc1','\xbb'},
+ {'\xee','\x79'},{'\xee','\x7b'},{'\xee','\x7a'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc2','\xd1'},{'\x92','\x6d'},{'\x00','\x00'},{'\x00','\x00'},{'\xf2','\xf4'},
+ {'\xf2','\xf3'},{'\x00','\x00'},{'\xf4','\xcc'},{'\xc4','\xb1'},{'\x00','\x00'},
+ {'\xfd','\x71'},{'\xc4','\xfd'},{'\xf7','\x54'},{'\xf7','\x53'},{'\xc6','\x5b'},
+ {'\x83','\x4e'},{'\x8d','\x73'},{'\x00','\x00'},{'\x84','\x7e'},{'\x84','\x7d'},
+ {'\x85','\x53'},{'\x8d','\xe6'},{'\x8c','\xa6'},{'\x8c','\x54'},{'\x8a','\x64'},
+ {'\x8e','\x7e'},{'\x90','\x5c'},{'\x00','\x00'},{'\x89','\x5e'},{'\x8f','\x63'},
+ {'\x8a','\xfc'},{'\x8f','\xc6'},{'\xa8','\xa4'},{'\xd0','\xaf'},{'\xad','\x6f'},
+ {'\xd7','\xc8'},{'\xd7','\xc6'},{'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xc7'},
+ {'\xdb','\xd4'},{'\xdb','\xd5'},{'\xe0','\x43'},{'\xdb','\xd3'},{'\x8a','\xfd'},
+ {'\xdf','\xfc'},{'\xe0','\x41'},{'\xe0','\x40'},{'\xe0','\x42'},{'\xb8','\xd1'},
+ {'\xdf','\xfe'},{'\xdf','\xfd'},{'\xe0','\x44'},{'\x91','\x73'},{'\xe4','\x49'},
+ {'\xe4','\x47'},{'\x00','\x00'},{'\xe4','\x48'},{'\xe7','\xd3'},{'\xe7','\xd1'},
+ {'\x00','\x00'},{'\x8f','\xc7'},{'\xe7','\xd2'},{'\xeb','\x7d'},{'\xee','\x7c'},
+ {'\xee','\x7d'},{'\xc2','\xd2'},{'\x00','\x00'},{'\xf2','\xf5'},{'\xf4','\xcd'},
+ {'\xc4','\xb2'},{'\x00','\x00'},{'\xf6','\x4c'},{'\xf7','\x55'},{'\xc5','\xa9'},
+ {'\x00','\x00'},{'\xf7','\xfe'},{'\xf9','\x4c'},{'\xa8','\xa5'},{'\x00','\x00'},
+ {'\xad','\x71'},{'\xad','\x72'},{'\xd0','\xb0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xd0','\xb1'},{'\xad','\x70'},{'\x00','\x00'},{'\xb0','\x54'},{'\x00','\x00'},
+ {'\xb0','\x52'},{'\x00','\x00'},{'\xb0','\x51'},{'\xb0','\x58'},{'\xb0','\x50'},
+ {'\xb0','\x59'},{'\xd3','\xdd'},{'\xb0','\x56'},{'\x00','\x00'},{'\xb0','\x53'},
+ {'\xb0','\x57'},{'\xb0','\x55'},{'\xb0','\x4f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\x5f'},{'\xfe','\xd4'},{'\xb3','\x59'},{'\xd7','\xcc'},{'\xb3','\x5e'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb3','\x60'},{'\xb3','\x5a'},{'\x00','\x00'},
+ {'\xb3','\x5b'},{'\x00','\x00'},{'\xd7','\xca'},{'\x00','\x00'},{'\xfe','\xd5'},
+ {'\xb3','\x58'},{'\xfe','\xd6'},{'\xd7','\xcb'},{'\xb3','\x5d'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd7','\xc9'},{'\xb3','\x5c'},{'\x00','\x00'},{'\x93','\xd5'},
+ {'\xb6','\x44'},{'\x00','\x00'},{'\xb6','\x46'},{'\x91','\x74'},{'\xfe','\xd7'},
+ {'\xdb','\xd8'},{'\xb6','\x45'},{'\xb5','\xf9'},{'\xb5','\xfd'},{'\xfe','\xd8'},
+ {'\xb8','\xe4'},{'\xe0','\x49'},{'\xdb','\xda'},{'\xb5','\xfe'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xdb','\xdd'},{'\xdb','\xde'},{'\xb6','\x43'},{'\x00','\x00'},
+ {'\xdb','\xe0'},{'\xfd','\x73'},{'\xdb','\xe2'},{'\x00','\x00'},{'\xdb','\xe3'},
+ {'\xdb','\xd7'},{'\xdb','\xd6'},{'\xdb','\xe4'},{'\xb6','\x42'},{'\xdb','\xe1'},
+ {'\xdb','\xdf'},{'\x00','\x00'},{'\xb6','\x40'},{'\xb5','\xfb'},{'\xb6','\x47'},
+ {'\xdb','\xdb'},{'\xdb','\xdc'},{'\xdb','\xd9'},{'\x00','\x00'},{'\xb6','\x41'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb5','\xfc'},{'\x00','\x00'},{'\xb5','\xfa'},
+ {'\xe0','\x48'},{'\xb8','\xdf'},{'\xb8','\xda'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb8','\xd5'},{'\xfc','\xda'},{'\xb8','\xe5'},{'\xb8','\xd6'},{'\x00','\x00'},
+ {'\xb8','\xd2'},{'\xb8','\xe1'},{'\xb8','\xde'},{'\xb8','\xe0'},{'\x00','\x00'},
+ {'\xb8','\xd7'},{'\xb8','\xdc'},{'\xb8','\xd3'},{'\xb8','\xd4'},{'\xe0','\x50'},
+ {'\xe0','\x4d'},{'\xe0','\x45'},{'\xe0','\x4a'},{'\x00','\x00'},{'\xb8','\xe2'},
+ {'\xe0','\x51'},{'\xb8','\xe3'},{'\xb8','\xd9'},{'\x00','\x00'},{'\xfd','\x72'},
+ {'\xe0','\x47'},{'\x00','\x00'},{'\xe0','\x4f'},{'\xe0','\x4b'},{'\xe0','\x4e'},
+ {'\xe0','\x4c'},{'\xb8','\xdd'},{'\xe0','\x46'},{'\xb8','\xd8'},{'\x00','\x00'},
+ {'\x8c','\xa9'},{'\x8a','\x6c'},{'\xe4','\x4c'},{'\xbb','\x78'},{'\xbb','\x7b'},
+ {'\x00','\x00'},{'\xe4','\x4e'},{'\xfe','\xda'},{'\xbb','\xa5'},{'\xe4','\x4d'},
+ {'\xbb','\x7d'},{'\xfe','\xdb'},{'\xbd','\xcf'},{'\xe4','\x4f'},{'\x00','\x00'},
+ {'\xbb','\xa4'},{'\xe4','\x4b'},{'\xbb','\xa6'},{'\x00','\x00'},{'\xfe','\xdc'},
+ {'\x00','\x00'},{'\xbb','\x79'},{'\x00','\x00'},{'\xb8','\xdb'},{'\xbb','\x7c'},
+ {'\x00','\x00'},{'\xbb','\x7a'},{'\xbb','\x7e'},{'\xbb','\xa2'},{'\xbb','\x77'},
+ {'\xbb','\xa7'},{'\xbb','\xa3'},{'\xfe','\xdd'},{'\xbb','\xa1'},{'\xe4','\x4a'},
+ {'\x91','\x75'},{'\x93','\xab'},{'\x00','\x00'},{'\xfe','\xde'},{'\xbd','\xd6'},
+ {'\x00','\x00'},{'\xbd','\xd2'},{'\x00','\x00'},{'\xfe','\xdf'},{'\x00','\x00'},
+ {'\xbd','\xd9'},{'\x00','\x00'},{'\xe7','\xd6'},{'\xbd','\xda'},{'\xe7','\xe2'},
+ {'\xe7','\xdb'},{'\xbd','\xcb'},{'\xe7','\xe3'},{'\xe7','\xdd'},{'\xbd','\xd5'},
+ {'\xe7','\xde'},{'\x00','\x00'},{'\xbd','\xd4'},{'\xe7','\xe1'},{'\xbd','\xce'},
+ {'\xe7','\xdf'},{'\xe7','\xd5'},{'\xbd','\xcd'},{'\xeb','\xaa'},{'\xbd','\xd3'},
+ {'\x00','\x00'},{'\xbd','\xd0'},{'\x82','\x51'},{'\xbd','\xd8'},{'\x00','\x00'},
+ {'\xe7','\xd4'},{'\x00','\x00'},{'\xe7','\xd8'},{'\xbd','\xcc'},{'\xe7','\xd7'},
+ {'\xe7','\xd9'},{'\xe7','\xda'},{'\xbd','\xd7'},{'\xe7','\xdc'},{'\xe7','\xe0'},
+ {'\xe7','\xe4'},{'\x91','\x76'},{'\xbd','\xdb'},{'\xbf','\xd2'},{'\xeb','\xa5'},
+ {'\xeb','\xab'},{'\xeb','\xa8'},{'\xeb','\x7e'},{'\xeb','\xac'},{'\xeb','\xa1'},
+ {'\x00','\x00'},{'\xeb','\xa7'},{'\x00','\x00'},{'\xbf','\xcd'},{'\xbf','\xd3'},
+ {'\xeb','\xad'},{'\x00','\x00'},{'\xfe','\xe0'},{'\xbf','\xcf'},{'\x00','\x00'},
+ {'\xbf','\xd9'},{'\xbf','\xd4'},{'\xeb','\xaf'},{'\xeb','\xa9'},{'\xbf','\xd0'},
+ {'\xeb','\xa2'},{'\xbf','\xda'},{'\xeb','\xa3'},{'\xeb','\xa4'},{'\xbf','\xdb'},
+ {'\xbf','\xd8'},{'\xbd','\xd1'},{'\x9d','\xd1'},{'\xbf','\xce'},{'\xeb','\xb0'},
+ {'\xbf','\xdc'},{'\x00','\x00'},{'\xbf','\xd5'},{'\xeb','\xae'},{'\xbf','\xd1'},
+ {'\xbf','\xd6'},{'\xbf','\xd7'},{'\x00','\x00'},{'\xc1','\xc3'},{'\xee','\xa4'},
+ {'\xee','\xad'},{'\xee','\xaa'},{'\xee','\xac'},{'\x00','\x00'},{'\xc1','\xc0'},
+ {'\xee','\xa5'},{'\xfd','\x74'},{'\xee','\xab'},{'\xc1','\xbc'},{'\xee','\xa7'},
+ {'\xc1','\xc4'},{'\xee','\xa3'},{'\xee','\xa8'},{'\xee','\xaf'},{'\xeb','\xa6'},
+ {'\xee','\xa9'},{'\xee','\xa2'},{'\xc1','\xbd'},{'\xee','\xa1'},{'\xc1','\xbe'},
+ {'\xee','\xb0'},{'\xc1','\xbf'},{'\xee','\xae'},{'\xc1','\xc2'},{'\xee','\x7e'},
+ {'\xfe','\xe1'},{'\xc1','\xc1'},{'\x93','\xdc'},{'\xee','\xa6'},{'\xf0','\xdc'},
+ {'\xf0','\xea'},{'\xf0','\xe5'},{'\xf0','\xe7'},{'\xf0','\xdb'},{'\xc2','\xd3'},
+ {'\x00','\x00'},{'\xf0','\xda'},{'\xc2','\xd6'},{'\xc2','\xd5'},{'\x96','\xc1'},
+ {'\xf0','\xe9'},{'\xf0','\xe1'},{'\xf0','\xde'},{'\xf0','\xe4'},{'\x00','\x00'},
+ {'\xf0','\xdd'},{'\x00','\x00'},{'\xf0','\xdf'},{'\xf0','\xe8'},{'\xf0','\xe6'},
+ {'\x00','\x00'},{'\xc2','\xd4'},{'\xf0','\xed'},{'\xf0','\xeb'},{'\xf0','\xe2'},
+ {'\xf0','\xec'},{'\xf0','\xe3'},{'\xfe','\xe3'},{'\xf2','\xf9'},{'\xc3','\xcf'},
+ {'\xf3','\x41'},{'\xfd','\x75'},{'\x00','\x00'},{'\xf6','\x4f'},{'\xc3','\xd6'},
+ {'\xf0','\xe0'},{'\xf2','\xf7'},{'\xc3','\xd2'},{'\xf2','\xf8'},{'\xf2','\xfd'},
+ {'\xfd','\x77'},{'\xfe','\xe4'},{'\xc3','\xd4'},{'\xc3','\xd5'},{'\xf2','\xf6'},
+ {'\xf3','\x40'},{'\xf3','\x42'},{'\xf2','\xfa'},{'\xf2','\xfc'},{'\xf2','\xfe'},
+ {'\xf2','\xfb'},{'\xf3','\x43'},{'\xc3','\xd1'},{'\xc3','\xd7'},{'\xc3','\xd3'},
+ {'\x91','\x77'},{'\xc3','\xd0'},{'\xf4','\xd0'},{'\xfe','\xe5'},{'\xc4','\xb7'},
+ {'\xf4','\xce'},{'\x00','\x00'},{'\xfe','\xe6'},{'\xf4','\xd2'},{'\x00','\x00'},
+ {'\xf4','\xd3'},{'\xc4','\xb5'},{'\xf4','\xd4'},{'\xf4','\xd1'},{'\xfe','\xe7'},
+ {'\xf4','\xcf'},{'\xc4','\xb8'},{'\xc4','\xb4'},{'\xf4','\xd5'},{'\x00','\x00'},
+ {'\xc4','\xb6'},{'\xc4','\xb3'},{'\x91','\x78'},{'\x92','\xf0'},{'\x00','\x00'},
+ {'\xc4','\xfe'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\x40'},{'\xf6','\x4e'},
+ {'\xf6','\x4d'},{'\xf6','\x50'},{'\xf6','\x51'},{'\x00','\x00'},{'\xc5','\x41'},
+ {'\xf7','\x56'},{'\xf7','\x5b'},{'\xc5','\xaa'},{'\xfd','\x76'},{'\xf7','\x58'},
+ {'\x82','\x63'},{'\xf7','\x57'},{'\xf7','\x5a'},{'\xf7','\x59'},{'\x00','\x00'},
+ {'\xf8','\x43'},{'\x00','\x00'},{'\xc5','\xdc'},{'\xf8','\x42'},{'\xf8','\x40'},
+ {'\x00','\x00'},{'\xf8','\x41'},{'\x00','\x00'},{'\x95','\xf8'},{'\x00','\x00'},
+ {'\xc5','\xfe'},{'\xc5','\xfd'},{'\xf8','\xc1'},{'\xf8','\xc2'},{'\xc6','\x40'},
+ {'\x00','\x00'},{'\xf9','\x4d'},{'\xf9','\x4e'},{'\xc6','\x67'},{'\xfe','\xe8'},
+ {'\xc6','\x6d'},{'\x00','\x00'},{'\xf9','\xa9'},{'\xf9','\xc8'},{'\x9c','\xec'},
+ {'\x83','\x79'},{'\x83','\x7a'},{'\x83','\x7b'},{'\x87','\x50'},{'\x8b','\xc2'},
+ {'\x83','\xd4'},{'\x83','\xd6'},{'\x83','\xd5'},{'\x8d','\x58'},{'\x83','\xd7'},
+ {'\x83','\xda'},{'\x00','\x00'},{'\x83','\xd9'},{'\x8c','\x56'},{'\x83','\xd8'},
+ {'\x83','\xd3'},{'\x00','\x00'},{'\x8a','\x68'},{'\x89','\x62'},{'\x8f','\x7e'},
+ {'\x8d','\xe7'},{'\x84','\xa2'},{'\x84','\xa4'},{'\x84','\xa5'},{'\x84','\xa8'},
+ {'\x88','\x62'},{'\x00','\x00'},{'\x84','\xa7'},{'\x89','\x6a'},{'\x84','\xa6'},
+ {'\x84','\xa1'},{'\x84','\xa3'},{'\x85','\x56'},{'\x85','\x57'},{'\x85','\x5e'},
+ {'\x85','\x54'},{'\x85','\x59'},{'\x8b','\xbf'},{'\x00','\x00'},{'\x85','\x5a'},
+ {'\x85','\x5c'},{'\x85','\x5d'},{'\x85','\x5b'},{'\x8f','\x65'},{'\x85','\x55'},
+ {'\x8d','\xe8'},{'\x85','\x58'},{'\x00','\x00'},{'\x8c','\x57'},{'\x8d','\xe9'},
+ {'\x8e','\x4f'},{'\x8e','\x52'},{'\x86','\x49'},{'\x8e','\x50'},{'\x86','\x4a'},
+ {'\x86','\x4b'},{'\x86','\x4c'},{'\x86','\x4e'},{'\x86','\x50'},{'\x8e','\x53'},
+ {'\x86','\x4f'},{'\x88','\x5a'},{'\x86','\x54'},{'\x86','\x53'},{'\x86','\x51'},
+ {'\x86','\x52'},{'\x86','\x4d'},{'\x88','\x63'},{'\x86','\x47'},{'\x86','\x48'},
+ {'\x86','\x46'},{'\x8e','\xf8'},{'\x8e','\x51'},{'\x00','\x00'},{'\x87','\x51'},
+ {'\x87','\x4f'},{'\x87','\x4e'},{'\x87','\x58'},{'\x87','\x52'},{'\x87','\x54'},
+ {'\x87','\x56'},{'\x87','\x55'},{'\x87','\x57'},{'\x87','\x53'},{'\x87','\x4d'},
+ {'\x8e','\xa1'},{'\x88','\x5b'},{'\x88','\x5c'},{'\x8e','\xcb'},{'\x89','\x67'},
+ {'\x8c','\xdd'},{'\x8e','\xcc'},{'\x88','\x65'},{'\x88','\x5d'},{'\x88','\x5e'},
+ {'\x88','\x66'},{'\x88','\x61'},{'\x8e','\xcd'},{'\x88','\x60'},{'\x88','\x5f'},
+ {'\x88','\x57'},{'\x88','\x59'},{'\x88','\x64'},{'\x88','\x58'},{'\x00','\x00'},
+ {'\x88','\x56'},{'\x89','\x63'},{'\x89','\x6d'},{'\x89','\x64'},{'\x8a','\x69'},
+ {'\x89','\x61'},{'\x89','\x65'},{'\x8e','\xf9'},{'\x89','\x68'},{'\x89','\x69'},
+ {'\x8e','\xfa'},{'\x89','\x6b'},{'\x89','\x6e'},{'\x8d','\x59'},{'\x89','\x66'},
+ {'\x89','\x6c'},{'\x89','\x60'},{'\x89','\x5f'},{'\x8a','\x65'},{'\x8e','\xfb'},
+ {'\x00','\x00'},{'\x8a','\xfe'},{'\x8d','\xa4'},{'\x8f','\x64'},{'\x8a','\x6b'},
+ {'\x8a','\x6a'},{'\x8a','\x66'},{'\x8f','\x66'},{'\x8a','\x67'},{'\x8a','\x6d'},
+ {'\x8b','\x40'},{'\x8f','\xa1'},{'\x8b','\x42'},{'\x91','\x79'},{'\x8b','\x41'},
+ {'\x8b','\xc0'},{'\x8f','\xc8'},{'\x8b','\xc3'},{'\x90','\x78'},{'\x8b','\xbe'},
+ {'\x8b','\xc1'},{'\x90','\xa6'},{'\x8c','\xa7'},{'\x8c','\x58'},{'\x8d','\x5a'},
+ {'\xa8','\xa6'},{'\x00','\x00'},{'\xd7','\xcd'},{'\x91','\x7a'},{'\xd7','\xce'},
+ {'\xe0','\x52'},{'\xe4','\x50'},{'\xe7','\xe5'},{'\xc1','\xc6'},{'\x00','\x00'},
+ {'\xc1','\xc5'},{'\xf0','\xee'},{'\xf3','\x44'},{'\x00','\x00'},{'\xf8','\x44'},
+ {'\xa8','\xa7'},{'\xd3','\xde'},{'\xb0','\x5a'},{'\xb3','\x61'},{'\xe0','\x54'},
+ {'\xe0','\x53'},{'\xbd','\xdc'},{'\xe7','\xe6'},{'\xbd','\xdd'},{'\xee','\xb1'},
+ {'\xc2','\xd7'},{'\xfe','\xe9'},{'\x00','\x00'},{'\x00','\x00'},{'\xc6','\x76'},
+ {'\xa8','\xa8'},{'\xcd','\xcb'},{'\xd3','\xdf'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\x62'},{'\x00','\x00'},{'\xd7','\xcf'},{'\xd7','\xd0'},{'\x00','\x00'},
+ {'\xdb','\xe5'},{'\x00','\x00'},{'\xb6','\x48'},{'\xb8','\xe6'},{'\x00','\x00'},
+ {'\xe0','\x56'},{'\xe0','\x55'},{'\xe0','\x57'},{'\x00','\x00'},{'\xe4','\x51'},
+ {'\xe4','\x52'},{'\xbb','\xa8'},{'\xbf','\xdd'},{'\xbd','\xde'},{'\xbf','\xde'},
+ {'\x00','\x00'},{'\xee','\xb5'},{'\xee','\xb2'},{'\xee','\xb4'},{'\xee','\xb3'},
+ {'\xc1','\xc7'},{'\x00','\x00'},{'\xf0','\xef'},{'\xf3','\x46'},{'\xf3','\x45'},
+ {'\xcb','\xa4'},{'\xb0','\x5c'},{'\xb0','\x5b'},{'\xd3','\xe0'},{'\x91','\x7b'},
+ {'\xd7','\xd1'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xe7'},{'\xdb','\xe6'},
+ {'\xb6','\x49'},{'\x00','\x00'},{'\xe0','\x59'},{'\xe0','\x5a'},{'\xe0','\x58'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xb8','\xe8'},{'\xb8','\xe7'},{'\x00','\x00'},
+ {'\xbb','\xaa'},{'\xbb','\xa9'},{'\x91','\x7c'},{'\xe7','\xe7'},{'\xeb','\xb3'},
+ {'\xeb','\xb1'},{'\xeb','\xb2'},{'\xbf','\xdf'},{'\xee','\xb7'},{'\xee','\xb6'},
+ {'\x00','\x00'},{'\xf0','\xf2'},{'\xf0','\xf1'},{'\xf0','\xf0'},{'\xf3','\x47'},
+ {'\xfe','\xea'},{'\xf9','\xaa'},{'\xa8','\xa9'},{'\xad','\x73'},{'\xfe','\xeb'},
+ {'\xad','\x74'},{'\xb0','\x5d'},{'\xb0','\x5e'},{'\xd3','\xe2'},{'\xd3','\xe1'},
+ {'\xd7','\xd2'},{'\x00','\x00'},{'\xb3','\x68'},{'\xb3','\x66'},{'\xb3','\x63'},
+ {'\xb3','\x67'},{'\xb3','\x65'},{'\xb3','\x64'},{'\xfd','\x79'},{'\x91','\x7d'},
+ {'\xb6','\x4a'},{'\xdb','\xea'},{'\x00','\x00'},{'\xb8','\xed'},{'\xb6','\x4c'},
+ {'\xb6','\x51'},{'\xdb','\xec'},{'\xb6','\x53'},{'\xb6','\x52'},{'\xb6','\x55'},
+ {'\xdb','\xeb'},{'\xdb','\xe8'},{'\xb6','\x4f'},{'\xb6','\x4b'},{'\xb6','\x4d'},
+ {'\xdb','\xe9'},{'\xb6','\x54'},{'\xb6','\x50'},{'\xb6','\x4e'},{'\xb8','\xef'},
+ {'\xb8','\xee'},{'\xb8','\xec'},{'\xb8','\xf0'},{'\x00','\x00'},{'\xb8','\xea'},
+ {'\xb8','\xeb'},{'\x00','\x00'},{'\xb8','\xe9'},{'\x00','\x00'},{'\xe0','\x5b'},
+ {'\x95','\x60'},{'\x82','\x62'},{'\xe4','\x54'},{'\x00','\x00'},{'\xbb','\xac'},
+ {'\xbb','\xad'},{'\xbb','\xab'},{'\xfe','\xec'},{'\xe4','\x53'},{'\xfe','\xed'},
+ {'\xe4','\x55'},{'\x00','\x00'},{'\xe7','\xea'},{'\xe7','\xec'},{'\x92','\xce'},
+ {'\xbd','\xe7'},{'\xe7','\xed'},{'\xbd','\xe0'},{'\xe7','\xe9'},{'\xbd','\xdf'},
+ {'\xbd','\xe9'},{'\xbd','\xe5'},{'\xbd','\xe6'},{'\xbd','\xe2'},{'\xe7','\xe8'},
+ {'\xbd','\xe1'},{'\xe7','\xee'},{'\xe7','\xeb'},{'\x9e','\x40'},{'\xbd','\xe8'},
+ {'\xfd','\x7a'},{'\xbd','\xe3'},{'\xbd','\xe4'},{'\xeb','\xb5'},{'\x00','\x00'},
+ {'\xeb','\xb7'},{'\xeb','\xb6'},{'\x9e','\x41'},{'\xeb','\xb8'},{'\xbf','\xe0'},
+ {'\xeb','\xb4'},{'\x00','\x00'},{'\xfd','\x7b'},{'\xc1','\xcb'},{'\xee','\xb8'},
+ {'\xc1','\xc8'},{'\xc1','\xcc'},{'\xc1','\xca'},{'\xc1','\xc9'},{'\xf0','\xf3'},
+ {'\x00','\x00'},{'\xf0','\xf6'},{'\x00','\x00'},{'\xf0','\xf5'},{'\x9e','\x42'},
+ {'\xf0','\xf4'},{'\xc2','\xd8'},{'\xf3','\x48'},{'\xf3','\x49'},{'\xc3','\xd8'},
+ {'\xf3','\x4a'},{'\xc3','\xd9'},{'\x82','\x57'},{'\xfd','\x7c'},{'\xc4','\xba'},
+ {'\x00','\x00'},{'\xc4','\xb9'},{'\xf6','\x52'},{'\x9e','\x43'},{'\x91','\x7e'},
+ {'\xc5','\x42'},{'\xf6','\x53'},{'\xf7','\x5c'},{'\xc5','\xab'},{'\xc5','\xac'},
+ {'\x95','\x76'},{'\xf8','\x45'},{'\x00','\x00'},{'\xc6','\x42'},{'\x9e','\x44'},
+ {'\x83','\x50'},{'\x83','\x7c'},{'\x83','\x7d'},{'\x00','\x00'},{'\x83','\xdd'},
+ {'\x83','\xdc'},{'\x84','\xaa'},{'\x88','\x6e'},{'\x84','\x50'},{'\x88','\x6c'},
+ {'\x84','\xac'},{'\x88','\x71'},{'\x84','\xa9'},{'\x84','\xad'},{'\x84','\xae'},
+ {'\x85','\x68'},{'\x8a','\x70'},{'\x85','\x5f'},{'\x84','\xab'},{'\x85','\x61'},
+ {'\x88','\x6b'},{'\x85','\x63'},{'\x8d','\xeb'},{'\x85','\x60'},{'\x85','\x66'},
+ {'\x8d','\xea'},{'\x85','\x6a'},{'\x85','\x69'},{'\x85','\x64'},{'\x85','\x65'},
+ {'\x85','\x62'},{'\x86','\x55'},{'\x8f','\xa3'},{'\x86','\x57'},{'\x86','\x58'},
+ {'\x86','\x59'},{'\x86','\x5a'},{'\x86','\x5b'},{'\x8c','\xaa'},{'\x86','\x56'},
+ {'\x86','\x5c'},{'\x90','\x47'},{'\x8e','\xa2'},{'\x87','\x5a'},{'\x91','\xa1'},
+ {'\x87','\x5b'},{'\x88','\x6a'},{'\x88','\x6d'},{'\x91','\xa2'},{'\x8c','\xde'},
+ {'\x88','\x69'},{'\x88','\x70'},{'\x00','\x00'},{'\x00','\x00'},{'\x88','\x72'},
+ {'\x88','\x68'},{'\x8e','\xce'},{'\x89','\x6f'},{'\x00','\x00'},{'\x8b','\x43'},
+ {'\x8a','\x71'},{'\x8a','\x6e'},{'\x8a','\x6f'},{'\x8f','\xa2'},{'\x8c','\xdf'},
+ {'\x8b','\xc5'},{'\x00','\x00'},{'\x8b','\xc4'},{'\x8c','\x5a'},{'\x8c','\x59'},
+ {'\x8d','\x5c'},{'\xa8','\xaa'},{'\x00','\x00'},{'\xb3','\x6a'},{'\xb3','\x69'},
+ {'\xe0','\x5c'},{'\xe0','\x5d'},{'\x00','\x00'},{'\xbb','\xae'},{'\xeb','\xb9'},
+ {'\xbd','\xea'},{'\xeb','\xba'},{'\xee','\xb9'},{'\xa8','\xab'},{'\x91','\xa3'},
+ {'\xd0','\xb2'},{'\xad','\x76'},{'\xad','\x75'},{'\x87','\x5c'},{'\xd3','\xe3'},
+ {'\xb0','\x5f'},{'\xd3','\xe4'},{'\xd7','\xd5'},{'\x9e','\x45'},{'\xd7','\xd4'},
+ {'\x00','\x00'},{'\xd7','\xd3'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xee'},
+ {'\xb6','\x58'},{'\xfd','\x7d'},{'\x00','\x00'},{'\xdb','\xed'},{'\xb6','\x57'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xdb','\xef'},{'\xb6','\x56'},
+ {'\x8a','\x72'},{'\xe0','\x5f'},{'\xe0','\x62'},{'\xe0','\x60'},{'\xe0','\x61'},
+ {'\xe0','\x65'},{'\xe0','\x5e'},{'\xe0','\x66'},{'\xe0','\x63'},{'\xe0','\x64'},
+ {'\xbb','\xb0'},{'\xe4','\x56'},{'\x00','\x00'},{'\x00','\x00'},{'\xbb','\xaf'},
+ {'\x00','\x00'},{'\xe7','\xf2'},{'\xe7','\xf0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xbd','\xeb'},{'\xe7','\xef'},{'\xe7','\xf1'},{'\x00','\x00'},{'\xbd','\xec'},
+ {'\x00','\x00'},{'\xeb','\xbb'},{'\xfd','\x7e'},{'\xeb','\xbc'},{'\xc1','\xcd'},
+ {'\x9e','\x46'},{'\xf3','\x4c'},{'\xf3','\x4e'},{'\xf3','\x4b'},{'\xf3','\x4d'},
+ {'\xf4','\xd6'},{'\xf6','\x54'},{'\x00','\x00'},{'\x90','\xa3'},{'\xf9','\x6f'},
+ {'\xa8','\xac'},{'\xad','\x77'},{'\xd3','\xe5'},{'\xd3','\xe7'},{'\xd3','\xe6'},
+ {'\x8c','\x5b'},{'\xd7','\xd8'},{'\xb3','\x6c'},{'\x00','\x00'},{'\xd7','\xd6'},
+ {'\x00','\x00'},{'\xb3','\x6b'},{'\xd7','\xd9'},{'\x9e','\x47'},{'\xd7','\xda'},
+ {'\xd7','\xd7'},{'\x8c','\xac'},{'\x8f','\x67'},{'\xdb','\xfb'},{'\xb6','\x60'},
+ {'\xdb','\xf3'},{'\xdb','\xf9'},{'\x00','\x00'},{'\x00','\x00'},{'\xb6','\x5b'},
+ {'\xb6','\x5e'},{'\xdb','\xf2'},{'\xb6','\x59'},{'\xdb','\xf6'},{'\xe0','\x6c'},
+ {'\xb6','\x5d'},{'\x00','\x00'},{'\xdb','\xf1'},{'\xfd','\xa1'},{'\xdb','\xf7'},
+ {'\xdb','\xf4'},{'\xdb','\xfa'},{'\xdb','\xf0'},{'\xdb','\xf8'},{'\xb6','\x5c'},
+ {'\xb6','\x5f'},{'\xdb','\xf5'},{'\xb6','\x5a'},{'\x90','\x5e'},{'\xb8','\xf2'},
+ {'\xe0','\x68'},{'\xb8','\xf1'},{'\xe0','\x6f'},{'\xe0','\x6e'},{'\xb8','\xf8'},
+ {'\x00','\x00'},{'\xb8','\xf9'},{'\xe0','\x70'},{'\xb8','\xf3'},{'\xe0','\x6d'},
+ {'\xb8','\xf7'},{'\xe0','\x72'},{'\xe0','\x69'},{'\x00','\x00'},{'\xe0','\x6b'},
+ {'\xb8','\xf4'},{'\xe0','\x67'},{'\xe0','\x6a'},{'\xe0','\x71'},{'\xb8','\xf5'},
+ {'\xe0','\x73'},{'\x88','\x73'},{'\x00','\x00'},{'\x8b','\xc6'},{'\x8b','\x46'},
+ {'\x90','\x5d'},{'\xb8','\xf6'},{'\x8c','\xad'},{'\xbb','\xb1'},{'\xe4','\x5b'},
+ {'\xe4','\x61'},{'\xe4','\x59'},{'\xe4','\x62'},{'\x9e','\x48'},{'\xe4','\x58'},
+ {'\xe4','\x5d'},{'\xe4','\x63'},{'\xe4','\x60'},{'\xe4','\x5f'},{'\xe4','\x5e'},
+ {'\x91','\xa4'},{'\xe4','\x57'},{'\xe4','\x5c'},{'\x00','\x00'},{'\x8c','\xab'},
+ {'\xe4','\x5a'},{'\x9e','\x49'},{'\xbd','\xf1'},{'\xbd','\xee'},{'\xe7','\xfb'},
+ {'\xe8','\x41'},{'\xe8','\x43'},{'\xe8','\x40'},{'\xe7','\xf8'},{'\xe7','\xfa'},
+ {'\xe8','\x45'},{'\xe8','\x42'},{'\xe7','\xfc'},{'\xe8','\x46'},{'\xe7','\xf9'},
+ {'\xe8','\x44'},{'\xbd','\xef'},{'\xbd','\xf5'},{'\xbd','\xf3'},{'\xe7','\xf3'},
+ {'\xbd','\xf4'},{'\xbd','\xf0'},{'\xe7','\xf4'},{'\xe7','\xf6'},{'\xe7','\xf5'},
+ {'\xe7','\xfd'},{'\xe7','\xfe'},{'\xfd','\xa2'},{'\xbd','\xf2'},{'\x95','\x57'},
+ {'\xbd','\xed'},{'\x8c','\xe1'},{'\xfb','\x6d'},{'\xe7','\xf7'},{'\x8c','\xe0'},
+ {'\xeb','\xc6'},{'\xbf','\xe2'},{'\x00','\x00'},{'\xeb','\xbd'},{'\xbf','\xe3'},
+ {'\xbf','\xe6'},{'\xeb','\xc2'},{'\x00','\x00'},{'\xeb','\xbf'},{'\xbf','\xe5'},
+ {'\x91','\xa5'},{'\x00','\x00'},{'\xeb','\xc3'},{'\xeb','\xc4'},{'\xeb','\xbe'},
+ {'\xeb','\xc7'},{'\xeb','\xc0'},{'\xeb','\xc5'},{'\xbf','\xe4'},{'\x00','\x00'},
+ {'\xbf','\xe1'},{'\xeb','\xc1'},{'\x9e','\x4a'},{'\xee','\xbf'},{'\xc1','\xd0'},
+ {'\xc1','\xce'},{'\xc1','\xd1'},{'\xc1','\xcf'},{'\xee','\xbe'},{'\xee','\xbb'},
+ {'\xee','\xba'},{'\xfd','\xa3'},{'\xee','\xbd'},{'\x8d','\x74'},{'\x8b','\x44'},
+ {'\xee','\xbc'},{'\xf1','\x45'},{'\xc2','\xde'},{'\xf0','\xfb'},{'\xf0','\xfa'},
+ {'\x00','\x00'},{'\xc2','\xd9'},{'\xf1','\x41'},{'\xf1','\x40'},{'\xf0','\xf7'},
+ {'\xf1','\x43'},{'\xf0','\xfc'},{'\xc2','\xdd'},{'\xf0','\xf9'},{'\xf1','\x42'},
+ {'\xf0','\xf8'},{'\xc2','\xda'},{'\xc2','\xdc'},{'\xf0','\xfd'},{'\xc2','\xdb'},
+ {'\xf0','\xfe'},{'\x9e','\x4b'},{'\xf1','\x44'},{'\xf3','\x52'},{'\x00','\x00'},
+ {'\xc3','\xde'},{'\xf3','\x4f'},{'\x00','\x00'},{'\xf3','\x53'},{'\x91','\xa6'},
+ {'\x9e','\x4c'},{'\xc3','\xdb'},{'\xf3','\x51'},{'\xc3','\xe0'},{'\xfd','\xa5'},
+ {'\xc3','\xdd'},{'\xfd','\xa4'},{'\xf3','\x50'},{'\x00','\x00'},{'\xc3','\xdf'},
+ {'\xf3','\x54'},{'\xc3','\xda'},{'\x00','\x00'},{'\x9e','\x4d'},{'\x90','\x7e'},
+ {'\x9e','\x4e'},{'\xc4','\xbc'},{'\xc4','\xbe'},{'\x00','\x00'},{'\xf4','\xd9'},
+ {'\xc4','\xbd'},{'\xf4','\xd7'},{'\xc3','\xdc'},{'\xf4','\xd8'},{'\xc4','\xbb'},
+ {'\xc5','\x43'},{'\xc5','\x45'},{'\xf6','\x56'},{'\xc5','\x44'},{'\xf6','\x55'},
+ {'\x8d','\xa5'},{'\xf7','\x61'},{'\xc5','\xad'},{'\xf7','\x60'},{'\xc5','\xae'},
+ {'\xf7','\x5e'},{'\xf7','\x5d'},{'\xf7','\x62'},{'\xf7','\x63'},{'\xf8','\x46'},
+ {'\x91','\xa7'},{'\xf7','\x5f'},{'\x00','\x00'},{'\x90','\xa4'},{'\xf8','\xc6'},
+ {'\xf8','\xc3'},{'\xf8','\xc4'},{'\xf8','\xc5'},{'\xc6','\x5c'},{'\x00','\x00'},
+ {'\xf9','\x51'},{'\xf9','\x50'},{'\xf9','\x4f'},{'\xf9','\x70'},{'\xfd','\xa6'},
+ {'\xf9','\xbe'},{'\xf9','\xab'},{'\xc6','\x6e'},{'\xa8','\xad'},{'\xb0','\x60'},
+ {'\x95','\xdf'},{'\x00','\x00'},{'\x82','\x49'},{'\x91','\xa8'},{'\x91','\xa9'},
+ {'\xb8','\xfa'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x4f'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x50'},{'\xbd','\xf6'},{'\x00','\x00'},
+ {'\x9e','\x51'},{'\xeb','\xc8'},{'\x94','\xd3'},{'\x00','\x00'},{'\xc2','\xdf'},
+ {'\x00','\x00'},{'\xf3','\x55'},{'\x9e','\x52'},{'\x00','\x00'},{'\x91','\xaa'},
+ {'\x91','\xab'},{'\x00','\x00'},{'\x94','\xd4'},{'\xf9','\xac'},{'\xa8','\xae'},
+ {'\xaa','\xee'},{'\xad','\x79'},{'\xad','\x78'},{'\x91','\xac'},{'\xb0','\x63'},
+ {'\x00','\x00'},{'\xd3','\xe8'},{'\xb0','\x61'},{'\xd3','\xe9'},{'\xb0','\x62'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xd7','\xdf'},{'\xd7','\xdb'},{'\x00','\x00'},
+ {'\xfb','\xa1'},{'\xb3','\x6d'},{'\xd7','\xde'},{'\xd7','\xdd'},{'\xd7','\xdc'},
+ {'\xb3','\x6e'},{'\xd7','\xe0'},{'\xd7','\xe1'},{'\x93','\x7d'},{'\x91','\xad'},
+ {'\x9e','\x53'},{'\xdc','\x43'},{'\xdc','\x41'},{'\xdc','\x45'},{'\xdc','\x46'},
+ {'\xdc','\x4c'},{'\x00','\x00'},{'\xdc','\x48'},{'\xdc','\x4a'},{'\x9e','\x54'},
+ {'\xdc','\x42'},{'\xdb','\xfc'},{'\x00','\x00'},{'\xdc','\x49'},{'\x9e','\x55'},
+ {'\x00','\x00'},{'\xdc','\x4b'},{'\xdc','\x44'},{'\xdc','\x47'},{'\xdb','\xfd'},
+ {'\xb6','\x62'},{'\xdc','\x40'},{'\xdb','\xfe'},{'\xb6','\x61'},{'\xb6','\x63'},
+ {'\x92','\xad'},{'\xb8','\xfd'},{'\xe0','\x75'},{'\xe0','\x77'},{'\xe0','\x76'},
+ {'\xe0','\x7b'},{'\xb8','\xfb'},{'\x00','\x00'},{'\xe0','\x78'},{'\xe0','\x74'},
+ {'\xe0','\x79'},{'\xe0','\x7a'},{'\xb8','\xfc'},{'\xb8','\xfe'},{'\xe0','\x7c'},
+ {'\x91','\xae'},{'\xe4','\x67'},{'\xe4','\x66'},{'\x00','\x00'},{'\xe4','\x64'},
+ {'\xe4','\x65'},{'\xbb','\xb3'},{'\xbb','\xb5'},{'\xbb','\xb2'},{'\xbb','\xb4'},
+ {'\xe8','\x4d'},{'\xe8','\x4e'},{'\xe8','\x49'},{'\xfd','\xa7'},{'\xe8','\x4a'},
+ {'\xbd','\xf8'},{'\xbd','\xfd'},{'\xbd','\xf7'},{'\xbd','\xfe'},{'\xbd','\xf9'},
+ {'\xe8','\x4b'},{'\x00','\x00'},{'\x00','\x00'},{'\xe8','\x4c'},{'\xe8','\x48'},
+ {'\xbe','\x40'},{'\xbd','\xfb'},{'\x00','\x00'},{'\x00','\x00'},{'\xbd','\xfa'},
+ {'\xbd','\xfc'},{'\x00','\x00'},{'\xe8','\x47'},{'\x95','\x70'},{'\xeb','\xca'},
+ {'\xbf','\xe8'},{'\x9e','\x56'},{'\x00','\x00'},{'\xeb','\xcc'},{'\xbf','\xea'},
+ {'\xeb','\xcf'},{'\xeb','\xcb'},{'\xeb','\xc9'},{'\xeb','\xce'},{'\xbf','\xe9'},
+ {'\xeb','\xcd'},{'\x00','\x00'},{'\xbf','\xe7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc1','\xd3'},{'\xc1','\xd6'},{'\xee','\xc1'},{'\x9e','\x57'},{'\xc1','\xd4'},
+ {'\xee','\xc0'},{'\xc1','\xd2'},{'\xc1','\xd5'},{'\xf1','\x46'},{'\xf1','\x47'},
+ {'\xf1','\x48'},{'\xc2','\xe0'},{'\x9e','\x58'},{'\xf1','\x49'},{'\x94','\xd5'},
+ {'\xc2','\xe1'},{'\xc3','\xe2'},{'\xf3','\x58'},{'\xf3','\x59'},{'\xf3','\x57'},
+ {'\xf3','\x56'},{'\xf3','\x5a'},{'\xc3','\xe1'},{'\xf4','\xdd'},{'\xf4','\xdb'},
+ {'\xf4','\xdc'},{'\xf4','\xde'},{'\xf4','\xda'},{'\xf4','\xdf'},{'\xf6','\x58'},
+ {'\xfd','\xa9'},{'\xf6','\x59'},{'\xf6','\x57'},{'\xc5','\x46'},{'\xf7','\x64'},
+ {'\xc5','\xaf'},{'\xf7','\x65'},{'\xf8','\x48'},{'\xf8','\x47'},{'\x00','\x00'},
+ {'\x83','\x51'},{'\x83','\x61'},{'\x83','\xa1'},{'\x83','\xde'},{'\x00','\x00'},
+ {'\x83','\xdf'},{'\x8b','\x48'},{'\x84','\xaf'},{'\x88','\x79'},{'\x84','\xb0'},
+ {'\x8c','\xae'},{'\x91','\xaf'},{'\x85','\x6b'},{'\x90','\x6e'},{'\x85','\x6c'},
+ {'\x8d','\xed'},{'\x85','\x6d'},{'\x91','\xb0'},{'\x8d','\xee'},{'\x90','\x5f'},
+ {'\x8d','\xec'},{'\x87','\x60'},{'\x86','\x5f'},{'\x86','\x5e'},{'\x86','\x60'},
+ {'\x8b','\xc8'},{'\x00','\x00'},{'\x8e','\x56'},{'\x8e','\x55'},{'\x86','\x5d'},
+ {'\x87','\x5f'},{'\x87','\x5e'},{'\x88','\x75'},{'\x88','\x78'},{'\x88','\x77'},
+ {'\x88','\x74'},{'\x88','\x7c'},{'\x88','\x7b'},{'\x00','\x00'},{'\x88','\x76'},
+ {'\x88','\x7a'},{'\x89','\x73'},{'\x89','\x70'},{'\x89','\x71'},{'\x00','\x00'},
+ {'\x89','\x72'},{'\x8c','\xe2'},{'\x8a','\x76'},{'\x8a','\x73'},{'\x8a','\x74'},
+ {'\x8f','\xa4'},{'\x8b','\x49'},{'\x8b','\xc7'},{'\xa8','\xaf'},{'\xb6','\x64'},
+ {'\x00','\x00'},{'\x8b','\xc9'},{'\xb9','\x40'},{'\xfd','\x41'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xbb','\xb6'},{'\x00','\x00'},{'\x9e','\x59'},{'\xbf','\xec'},
+ {'\x91','\xb1'},{'\xbf','\xeb'},{'\x8c','\xaf'},{'\x00','\x00'},{'\x8c','\x47'},
+ {'\x00','\x00'},{'\xc3','\xe3'},{'\xc4','\x7c'},{'\xc5','\x47'},{'\xa8','\xb0'},
+ {'\xb0','\x64'},{'\xb9','\x41'},{'\x9e','\x5a'},{'\xf3','\x5b'},{'\xc6','\xd6'},
+ {'\x9c','\xe0'},{'\x94','\xd6'},{'\x9e','\x5b'},{'\x8b','\xca'},{'\x93','\xc3'},
+ {'\x94','\x4e'},{'\x94','\x44'},{'\x89','\x77'},{'\x86','\x63'},{'\xcb','\xa6'},
+ {'\x00','\x00'},{'\x88','\x7e'},{'\xa8','\xb1'},{'\x00','\x00'},{'\xa8','\xb4'},
+ {'\xa8','\xb3'},{'\xa8','\xb2'},{'\x86','\x65'},{'\x8a','\x79'},{'\xcb','\xa5'},
+ {'\x9e','\x5c'},{'\xcd','\xcd'},{'\xa0','\xa4'},{'\xcd','\xcf'},{'\xaa','\xef'},
+ {'\x9e','\x5d'},{'\x86','\x62'},{'\xaa','\xf1'},{'\xcd','\xcc'},{'\xcd','\xce'},
+ {'\xaa','\xf0'},{'\xcd','\xd1'},{'\xcd','\xd0'},{'\xcd','\xd2'},{'\x8a','\x78'},
+ {'\x84','\xb1'},{'\x94','\xd7'},{'\x85','\x6e'},{'\x87','\x61'},{'\x86','\x64'},
+ {'\x84','\xb2'},{'\x89','\x76'},{'\xd0','\xb6'},{'\xd0','\xb4'},{'\xad','\x7c'},
+ {'\xd0','\xb3'},{'\xad','\xa3'},{'\xad','\x7e'},{'\xad','\x7b'},{'\x00','\x00'},
+ {'\xad','\xa4'},{'\x8b','\x4a'},{'\xad','\x7d'},{'\xad','\xa2'},{'\x00','\x00'},
+ {'\xad','\xa1'},{'\xd0','\xb5'},{'\x91','\xb2'},{'\xad','\x7a'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x84','\xb3'},{'\xb0','\x6a'},{'\xd3','\xeb'},{'\xd3','\xf1'},
+ {'\xb0','\x67'},{'\xb0','\x6e'},{'\x95','\xd9'},{'\xb0','\x69'},{'\xd3','\xee'},
+ {'\xd3','\xf0'},{'\xb0','\x6c'},{'\xd3','\xea'},{'\xd3','\xed'},{'\xb0','\x68'},
+ {'\xb0','\x65'},{'\xd3','\xec'},{'\xb0','\x6b'},{'\xd3','\xef'},{'\xb0','\x6d'},
+ {'\xb0','\x66'},{'\x00','\x00'},{'\x9e','\x5e'},{'\x89','\x75'},{'\x87','\x62'},
+ {'\xd7','\xe3'},{'\xd7','\xe6'},{'\xb3','\x70'},{'\x91','\xb3'},{'\xb3','\x7a'},
+ {'\xb3','\x76'},{'\xd7','\xe4'},{'\x87','\x63'},{'\x93','\x7a'},{'\xb3','\x7e'},
+ {'\xb3','\x77'},{'\xb3','\x7c'},{'\xb3','\x72'},{'\x00','\x00'},{'\xb3','\x6f'},
+ {'\xb3','\x71'},{'\xb3','\x7d'},{'\xd7','\xe5'},{'\xb3','\x75'},{'\xb3','\x78'},
+ {'\xb3','\x74'},{'\xb3','\x79'},{'\xd7','\xe7'},{'\xb3','\x7b'},{'\xb3','\x73'},
+ {'\xd7','\xe2'},{'\x00','\x00'},{'\x8d','\x41'},{'\x94','\xd8'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xdc','\x4d'},
+ {'\xb6','\x65'},{'\xdc','\x4f'},{'\x00','\x00'},{'\xb6','\x67'},{'\xb6','\x69'},
+ {'\x9e','\x5f'},{'\xdc','\x4e'},{'\xb6','\x66'},{'\xb6','\x6a'},{'\x9e','\x60'},
+ {'\xb6','\x68'},{'\x91','\xb4'},{'\x00','\x00'},{'\x8d','\x42'},{'\xb9','\x47'},
+ {'\xe0','\xa3'},{'\xb9','\x4f'},{'\xe0','\x7e'},{'\x00','\x00'},{'\xb9','\x50'},
+ {'\xb9','\x45'},{'\x00','\x00'},{'\xe0','\xa1'},{'\x93','\x72'},{'\x00','\x00'},
+ {'\xb9','\x4a'},{'\x00','\x00'},{'\xe0','\xa2'},{'\xb9','\x43'},{'\xb9','\x42'},
+ {'\xfd','\xb6'},{'\xb9','\x4d'},{'\xb9','\x4c'},{'\xb9','\x4b'},{'\xb9','\x49'},
+ {'\xb9','\x4e'},{'\xe0','\x7d'},{'\xb9','\x44'},{'\xb9','\x46'},{'\xb9','\x48'},
+ {'\xfd','\xb5'},{'\x89','\x78'},{'\xbb','\xb8'},{'\xbb','\xbb'},{'\x00','\x00'},
+ {'\xbb','\xbf'},{'\xbb','\xb9'},{'\xbb','\xbe'},{'\xbb','\xbc'},{'\x00','\x00'},
+ {'\xbb','\xb7'},{'\xfe','\x61'},{'\xbb','\xbd'},{'\xbb','\xba'},{'\x9e','\x61'},
+ {'\x91','\xb5'},{'\x00','\x00'},{'\xe8','\x52'},{'\xbe','\x43'},{'\xbe','\x41'},
+ {'\x00','\x00'},{'\xe8','\x53'},{'\x9e','\x62'},{'\xbe','\x44'},{'\xbe','\x42'},
+ {'\xe8','\x51'},{'\xe8','\x50'},{'\x00','\x00'},{'\xbf','\xf0'},{'\xe8','\x4f'},
+ {'\xbf','\xee'},{'\xbf','\xed'},{'\xeb','\xd0'},{'\xbe','\x45'},{'\xbf','\xef'},
+ {'\xeb','\xd1'},{'\xbf','\xf2'},{'\xeb','\xd2'},{'\xbf','\xf1'},{'\xc1','\xd8'},
+ {'\xee','\xc3'},{'\xc1','\xd7'},{'\xc1','\xdc'},{'\xc1','\xda'},{'\xc1','\xdb'},
+ {'\xc2','\xe3'},{'\xc1','\xd9'},{'\xee','\xc2'},{'\xeb','\xd3'},{'\xc2','\xe2'},
+ {'\xc2','\xe4'},{'\x91','\xb6'},{'\xc3','\xe4'},{'\xc3','\xe5'},{'\x00','\x00'},
+ {'\xf4','\xe0'},{'\x00','\x00'},{'\xc5','\xde'},{'\xc5','\xdd'},{'\xa8','\xb6'},
+ {'\x00','\x00'},{'\x88','\xa3'},{'\xca','\x55'},{'\xb0','\x6f'},{'\x00','\x00'},
+ {'\xca','\x52'},{'\xca','\x53'},{'\xca','\x51'},{'\x00','\x00'},{'\xca','\x54'},
+ {'\x00','\x00'},{'\x8f','\xa5'},{'\xcb','\xaa'},{'\xcb','\xa7'},{'\xcb','\xac'},
+ {'\xcb','\xa8'},{'\xa8','\xb7'},{'\xa8','\xba'},{'\x00','\x00'},{'\xcb','\xa9'},
+ {'\xa8','\xb9'},{'\xcb','\xab'},{'\x95','\x40'},{'\x00','\x00'},{'\xa8','\xb8'},
+ {'\x00','\x00'},{'\x8e','\x57'},{'\x00','\x00'},{'\x85','\x6f'},{'\xcd','\xd5'},
+ {'\xcd','\xd7'},{'\xaa','\xf4'},{'\xcd','\xd3'},{'\xcd','\xd6'},{'\xcd','\xd4'},
+ {'\xaa','\xf2'},{'\xaa','\xf5'},{'\x00','\x00'},{'\xaa','\xf3'},{'\x86','\x66'},
+ {'\x89','\x79'},{'\x88','\xa1'},{'\x00','\x00'},{'\xd0','\xb8'},{'\xd0','\xbc'},
+ {'\xd0','\xb9'},{'\x00','\x00'},{'\xad','\xa7'},{'\x00','\x00'},{'\xad','\xa8'},
+ {'\xfd','\xab'},{'\xd0','\xbb'},{'\x00','\x00'},{'\xd0','\xbd'},{'\xd0','\xbf'},
+ {'\x00','\x00'},{'\xad','\xa5'},{'\xd0','\xbe'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xad','\xa6'},{'\x8d','\xc6'},{'\x8e','\xfc'},{'\x88','\xa2'},{'\x00','\x00'},
+ {'\x8d','\xf0'},{'\xd7','\xee'},{'\xd0','\xba'},{'\xd3','\xf2'},{'\xd3','\xfb'},
+ {'\xd3','\xf9'},{'\xd3','\xf4'},{'\xd3','\xf5'},{'\xd3','\xfa'},{'\xd3','\xfc'},
+ {'\xb0','\x71'},{'\x91','\xb7'},{'\xd3','\xf7'},{'\xd3','\xf3'},{'\xb0','\x70'},
+ {'\xb0','\x72'},{'\xd3','\xf6'},{'\xd3','\xfd'},{'\xd3','\xf8'},{'\x8c','\xe3'},
+ {'\x90','\xbb'},{'\xb3','\xa1'},{'\xd7','\xf1'},{'\xd7','\xe9'},{'\xd7','\xef'},
+ {'\xd7','\xf0'},{'\xb3','\xa2'},{'\x00','\x00'},{'\xd7','\xe8'},{'\xd7','\xea'},
+ {'\xd0','\xb7'},{'\xd7','\xec'},{'\xd7','\xed'},{'\xd7','\xeb'},{'\xb6','\x6c'},
+ {'\x00','\x00'},{'\x92','\x7b'},{'\x8e','\xcf'},{'\xdc','\x56'},{'\xeb','\xd4'},
+ {'\xdc','\x57'},{'\xdc','\x54'},{'\xb3','\xa3'},{'\xb6','\x6e'},{'\xdc','\x53'},
+ {'\xdc','\x59'},{'\xdc','\x58'},{'\xb6','\x6b'},{'\xdc','\x5c'},{'\xdc','\x52'},
+ {'\xdc','\x5b'},{'\xdc','\x50'},{'\xdc','\x5a'},{'\xdc','\x55'},{'\xb6','\x6d'},
+ {'\x00','\x00'},{'\xe0','\xaa'},{'\x00','\x00'},{'\xe0','\xa5'},{'\xe0','\xab'},
+ {'\xe0','\xa6'},{'\xe0','\xa4'},{'\xe0','\xa7'},{'\xb9','\x51'},{'\x00','\x00'},
+ {'\xe0','\xa9'},{'\x91','\xb8'},{'\xe0','\xa8'},{'\xb9','\x52'},{'\xbb','\xc1'},
+ {'\xbb','\xc0'},{'\xe4','\x6e'},{'\xe4','\x71'},{'\xe4','\x69'},{'\xe4','\x6d'},
+ {'\xbb','\xc2'},{'\xe4','\x6c'},{'\xe4','\x6a'},{'\xe4','\x70'},{'\xe4','\x6b'},
+ {'\xe4','\x68'},{'\xe4','\x6f'},{'\x00','\x00'},{'\xe8','\x59'},{'\xbe','\x48'},
+ {'\xf1','\x4a'},{'\xe8','\x56'},{'\xe8','\x57'},{'\xe8','\x55'},{'\xdc','\x51'},
+ {'\xbe','\x47'},{'\xe8','\x5a'},{'\xe8','\x54'},{'\xbe','\x46'},{'\xbe','\x49'},
+ {'\xe8','\x58'},{'\xeb','\xd5'},{'\xbf','\xf3'},{'\xeb','\xd6'},{'\xeb','\xd7'},
+ {'\x00','\x00'},{'\xee','\xc4'},{'\xc1','\xdd'},{'\xf1','\x4b'},{'\xf1','\x4c'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xf1','\x4d'},{'\xf3','\x5d'},{'\xf3','\x5c'},
+ {'\xf4','\xe2'},{'\x00','\x00'},{'\xf4','\xe1'},{'\xf6','\x5b'},{'\xf6','\x5c'},
+ {'\xf6','\x5a'},{'\xf7','\x66'},{'\xc5','\xb0'},{'\xa8','\xbb'},{'\xad','\xaa'},
+ {'\xad','\xa9'},{'\xb0','\x75'},{'\xb0','\x74'},{'\xd4','\x40'},{'\xd4','\x41'},
+ {'\xd3','\xfe'},{'\xfd','\xac'},{'\xb0','\x73'},{'\xd7','\xf5'},{'\x92','\xf8'},
+ {'\xd7','\xf6'},{'\xd7','\xf2'},{'\xb3','\xa4'},{'\xd7','\xf3'},{'\xfd','\xaf'},
+ {'\xd7','\xf4'},{'\x00','\x00'},{'\xfd','\xae'},{'\x8a','\x7a'},{'\x96','\xa8'},
+ {'\xdc','\x5f'},{'\xdc','\x61'},{'\xdc','\x5d'},{'\xdc','\x60'},{'\xb6','\x6f'},
+ {'\xdc','\x5e'},{'\xb6','\x70'},{'\x00','\x00'},{'\xfd','\xb0'},{'\xdd','\x73'},
+ {'\xb9','\x55'},{'\xb9','\x54'},{'\x00','\x00'},{'\xb9','\x53'},{'\x00','\x00'},
+ {'\xe0','\xac'},{'\xe0','\xad'},{'\x96','\xa9'},{'\x8b','\x4c'},{'\xe4','\x73'},
+ {'\xe4','\x75'},{'\xbb','\xc6'},{'\xbb','\xc3'},{'\x96','\xa1'},{'\xbb','\xc5'},
+ {'\xbb','\xc4'},{'\xe4','\x74'},{'\xe4','\x72'},{'\x00','\x00'},{'\xfd','\xb1'},
+ {'\x8d','\xa6'},{'\x90','\xa5'},{'\x8d','\x5d'},{'\xe8','\x61'},{'\xe8','\x5e'},
+ {'\xe8','\x5f'},{'\xbe','\x4d'},{'\xe8','\x60'},{'\xe8','\x5b'},{'\xe8','\x5c'},
+ {'\xbe','\x4a'},{'\x00','\x00'},{'\xbe','\x4b'},{'\xe8','\x5d'},{'\xbe','\x4c'},
+ {'\x96','\xaa'},{'\xeb','\xdb'},{'\xfd','\xb2'},{'\xeb','\xdc'},{'\xeb','\xd9'},
+ {'\xeb','\xda'},{'\xbf','\xf4'},{'\xeb','\xd8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x82','\x79'},{'\x00','\x00'},{'\xee','\xc8'},{'\xee','\xc5'},
+ {'\xee','\xc7'},{'\xc1','\xe0'},{'\xee','\xcb'},{'\xc1','\xdf'},{'\xee','\xc9'},
+ {'\xee','\xcc'},{'\xee','\xca'},{'\xee','\xc6'},{'\xc1','\xde'},{'\x82','\x66'},
+ {'\xf1','\x4f'},{'\x00','\x00'},{'\xf1','\x50'},{'\xf1','\x4e'},{'\x9e','\x63'},
+ {'\xf1','\x52'},{'\xc2','\xe5'},{'\xc2','\xe6'},{'\xf3','\x5f'},{'\xc3','\xe7'},
+ {'\xf1','\x51'},{'\xf3','\x5e'},{'\xc3','\xe6'},{'\xf4','\xe5'},{'\xf4','\xe6'},
+ {'\xc4','\xbf'},{'\xf4','\xe4'},{'\x9e','\x64'},{'\xf4','\xe3'},{'\x92','\xf1'},
+ {'\xf6','\x5d'},{'\xc5','\x48'},{'\xfd','\xb3'},{'\xf8','\x49'},{'\xf8','\xc8'},
+ {'\xf8','\xc7'},{'\x00','\x00'},{'\xc6','\x43'},{'\xc6','\x5d'},{'\xf8','\xc9'},
+ {'\xf9','\x71'},{'\x9e','\x65'},{'\xc6','\x6f'},{'\xa8','\xbc'},{'\xaa','\xf6'},
+ {'\x92','\xd8'},{'\xb9','\x56'},{'\x8c','\x5c'},{'\xc4','\xc0'},{'\xa8','\xbd'},
+ {'\xad','\xab'},{'\xb3','\xa5'},{'\xb6','\x71'},{'\xc2','\xe7'},{'\xaa','\xf7'},
+ {'\x00','\x00'},{'\xd0','\xc1'},{'\xd0','\xc0'},{'\xd4','\x42'},{'\x91','\xb9'},
+ {'\xb0','\x78'},{'\xb0','\x76'},{'\xb0','\x7a'},{'\xd4','\x44'},{'\x91','\xba'},
+ {'\xb0','\x79'},{'\xb0','\x77'},{'\x91','\xbb'},{'\x96','\x49'},{'\x00','\x00'},
+ {'\x91','\xbc'},{'\xd4','\x43'},{'\xb3','\xa8'},{'\xd7','\xfc'},{'\x91','\xbd'},
+ {'\xb3','\xa7'},{'\xb3','\xa9'},{'\xd8','\x42'},{'\xb3','\xab'},{'\xd7','\xfe'},
+ {'\xd8','\x40'},{'\xd7','\xf7'},{'\xb3','\xaa'},{'\xd8','\x43'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xd7','\xf9'},{'\x00','\x00'},{'\xd7','\xfa'},{'\xd7','\xf8'},
+ {'\xb3','\xa6'},{'\x91','\xbe'},{'\xd8','\x41'},{'\xd7','\xfb'},{'\xd7','\xfd'},
+ {'\x9e','\x66'},{'\x00','\x00'},{'\x91','\xbf'},{'\xdc','\x6d'},{'\xfd','\xb7'},
+ {'\xdc','\x6c'},{'\xdc','\x6a'},{'\xdc','\x62'},{'\xdc','\x71'},{'\xdc','\x65'},
+ {'\xdc','\x6f'},{'\xdc','\x76'},{'\xdc','\x6e'},{'\xb6','\x79'},{'\x9e','\x67'},
+ {'\xb6','\x75'},{'\xdc','\x63'},{'\x00','\x00'},{'\xdc','\x69'},{'\xb6','\x77'},
+ {'\x95','\x4c'},{'\xdc','\x68'},{'\xb6','\x78'},{'\xb6','\x7a'},{'\xdc','\x6b'},
+ {'\x9e','\x68'},{'\xb6','\x72'},{'\xb6','\x73'},{'\xdc','\x77'},{'\xdc','\x75'},
+ {'\x00','\x00'},{'\xdc','\x74'},{'\xdc','\x66'},{'\x00','\x00'},{'\xdc','\x72'},
+ {'\x00','\x00'},{'\xb6','\x76'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x69'},
+ {'\x00','\x00'},{'\xb6','\x74'},{'\xdc','\x73'},{'\xdc','\x64'},{'\xdc','\x67'},
+ {'\xdc','\x70'},{'\x9e','\x6a'},{'\x91','\xc0'},{'\xfb','\x5f'},{'\x9e','\x6b'},
+ {'\x91','\xc1'},{'\xe4','\xba'},{'\xe0','\xb7'},{'\x00','\x00'},{'\xe0','\xb0'},
+ {'\xe0','\xc3'},{'\xe0','\xcc'},{'\xe0','\xb3'},{'\xb9','\x61'},{'\x9e','\x6c'},
+ {'\xe0','\xc0'},{'\xb9','\x57'},{'\xb9','\x59'},{'\xb9','\x65'},{'\xe0','\xb1'},
+ {'\x00','\x00'},{'\x9e','\x6d'},{'\xb9','\x5a'},{'\xb9','\x5c'},{'\xb9','\x66'},
+ {'\xb9','\x5b'},{'\x9e','\x6e'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\x7b'},
+ {'\xb9','\x64'},{'\xe0','\xb9'},{'\x00','\x00'},{'\xe0','\xae'},{'\xb9','\x62'},
+ {'\xe0','\xb8'},{'\xb9','\x5e'},{'\xe0','\xca'},{'\xb9','\x63'},{'\xe0','\xc8'},
+ {'\xe0','\xbc'},{'\xe0','\xc6'},{'\xb9','\x60'},{'\xe0','\xaf'},{'\xe0','\xc9'},
+ {'\xe0','\xc4'},{'\x96','\x40'},{'\xe0','\xcb'},{'\xb9','\x58'},{'\x9e','\x6f'},
+ {'\x91','\xc3'},{'\xb9','\x67'},{'\xb9','\x5d'},{'\x00','\x00'},{'\x9e','\x70'},
+ {'\xe0','\xb5'},{'\x9e','\x71'},{'\xe0','\xbd'},{'\xe0','\xc1'},{'\x95','\xf1'},
+ {'\xe0','\xc5'},{'\xb9','\x5f'},{'\xe0','\xb4'},{'\xe0','\xb2'},{'\xe0','\xbe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x72'},{'\xe0','\xbb'},
+ {'\xe0','\xba'},{'\x9e','\x73'},{'\xe0','\xbf'},{'\xe0','\xc2'},{'\x92','\xc0'},
+ {'\xe0','\xc7'},{'\x96','\x43'},{'\x8c','\xe5'},{'\x00','\x00'},{'\xe4','\x78'},
+ {'\x91','\xc4'},{'\xbb','\xc7'},{'\xe4','\xa4'},{'\xe4','\x7a'},{'\xbb','\xcc'},
+ {'\xbb','\xd0'},{'\xe4','\xad'},{'\xe4','\xb5'},{'\xe4','\xa6'},{'\xbb','\xc8'},
+ {'\x9e','\x74'},{'\xe4','\xaa'},{'\xe0','\xb6'},{'\x9e','\x75'},{'\xbb','\xc9'},
+ {'\xe4','\xb1'},{'\xe4','\xb6'},{'\xe4','\xae'},{'\x9e','\x76'},{'\xe4','\xb0'},
+ {'\xe4','\xb9'},{'\xe4','\xb2'},{'\xe4','\x7e'},{'\xe4','\xa9'},{'\x9e','\x77'},
+ {'\x00','\x00'},{'\xbb','\xd1'},{'\x00','\x00'},{'\xbb','\xcd'},{'\xe4','\x7c'},
+ {'\xe4','\xab'},{'\xbb','\xcb'},{'\xe4','\xa5'},{'\xbb','\xca'},{'\xe4','\xb3'},
+ {'\xe4','\xa2'},{'\xe4','\x79'},{'\xbb','\xce'},{'\xe4','\xb8'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe4','\x7b'},{'\xe4','\xaf'},{'\xe4','\xac'},{'\xe4','\xa7'},
+ {'\xe4','\x77'},{'\xe4','\x76'},{'\xe4','\xa1'},{'\xe4','\xb4'},{'\xbb','\xcf'},
+ {'\xe4','\xb7'},{'\xe4','\x7d'},{'\xe4','\xa3'},{'\xbe','\x52'},{'\x93','\x4b'},
+ {'\x8d','\xa8'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\x78'},{'\xbe','\x5a'},
+ {'\xbe','\x55'},{'\xe8','\xa4'},{'\xe8','\xa1'},{'\xe8','\x67'},{'\xbe','\x50'},
+ {'\x00','\x00'},{'\xf9','\xd7'},{'\x9e','\x79'},{'\xbe','\x4f'},{'\xbe','\x56'},
+ {'\x00','\x00'},{'\xfd','\xb9'},{'\x9e','\x7a'},{'\xe8','\x65'},{'\xbe','\x54'},
+ {'\xe8','\x71'},{'\xe8','\x63'},{'\xe8','\x64'},{'\xbe','\x4e'},{'\xe8','\xa3'},
+ {'\xbe','\x58'},{'\xe8','\x74'},{'\xe8','\x79'},{'\xe8','\x73'},{'\xeb','\xee'},
+ {'\xe8','\x6f'},{'\xe8','\x77'},{'\xe8','\x75'},{'\xe8','\x68'},{'\xe8','\x62'},
+ {'\xe8','\x7d'},{'\xbe','\x57'},{'\xe8','\x7e'},{'\x9e','\x7b'},{'\xe8','\x78'},
+ {'\x00','\x00'},{'\xe8','\x6d'},{'\xe8','\x6b'},{'\xe8','\x66'},{'\x00','\x00'},
+ {'\x9e','\x7c'},{'\x00','\x00'},{'\xe8','\x6e'},{'\xe8','\x7b'},{'\xe8','\x6a'},
+ {'\xe8','\x7a'},{'\xe8','\xa2'},{'\x00','\x00'},{'\x9e','\x7d'},{'\xbe','\x53'},
+ {'\x9e','\x7e'},{'\xe8','\x76'},{'\xe8','\x7c'},{'\xe8','\x72'},{'\xe8','\x6c'},
+ {'\xbe','\x51'},{'\x9e','\xa1'},{'\x9e','\xa2'},{'\x91','\xc5'},{'\xe4','\xa8'},
+ {'\xe8','\x70'},{'\xbe','\x59'},{'\xe8','\x69'},{'\x94','\x58'},{'\x93','\x74'},
+ {'\x9e','\xa3'},{'\x00','\x00'},{'\x9e','\xa4'},{'\xeb','\xf4'},{'\xbf','\xf7'},
+ {'\xeb','\xf3'},{'\xeb','\xf0'},{'\xec','\x44'},{'\xbf','\xfb'},{'\x9e','\xa5'},
+ {'\xec','\x41'},{'\xeb','\xf8'},{'\xec','\x43'},{'\xeb','\xe9'},{'\xeb','\xf6'},
+ {'\x9e','\xa6'},{'\xbf','\xfd'},{'\x00','\x00'},{'\xeb','\xe1'},{'\x9e','\xa7'},
+ {'\xeb','\xdf'},{'\xec','\x42'},{'\x00','\x00'},{'\xec','\x40'},{'\xeb','\xfe'},
+ {'\xeb','\xed'},{'\xeb','\xec'},{'\xeb','\xe2'},{'\xc0','\x40'},{'\x00','\x00'},
+ {'\xeb','\xe8'},{'\xeb','\xf2'},{'\xeb','\xfd'},{'\xc0','\x43'},{'\xec','\x45'},
+ {'\x00','\x00'},{'\xc1','\xe8'},{'\xc0','\x45'},{'\xbf','\xfe'},{'\xeb','\xe6'},
+ {'\x00','\x00'},{'\xeb','\xef'},{'\xeb','\xde'},{'\xeb','\xe0'},{'\xbf','\xf5'},
+ {'\xc0','\x42'},{'\xbf','\xfa'},{'\xeb','\xe7'},{'\xeb','\xf7'},{'\xeb','\xf1'},
+ {'\xc0','\x41'},{'\xeb','\xdd'},{'\xc1','\xe3'},{'\xeb','\xf9'},{'\xeb','\xfc'},
+ {'\xbf','\xfc'},{'\x93','\xf3'},{'\xeb','\xeb'},{'\xc0','\x44'},{'\xbf','\xf9'},
+ {'\x9e','\xa8'},{'\x9e','\xa9'},{'\x93','\xf7'},{'\xbf','\xf8'},{'\xeb','\xf5'},
+ {'\xeb','\xfb'},{'\xbf','\xf6'},{'\x00','\x00'},{'\xeb','\xe4'},{'\xeb','\xfa'},
+ {'\x91','\xc6'},{'\x94','\xdb'},{'\xeb','\xe5'},{'\x00','\x00'},{'\x8b','\xd6'},
+ {'\x00','\x00'},{'\x9e','\xaa'},{'\xfe','\x7c'},{'\x9e','\xab'},{'\x9e','\xac'},
+ {'\x97','\x55'},{'\x96','\x42'},{'\xeb','\xea'},{'\xee','\xd2'},{'\xfe','\x79'},
+ {'\xee','\xd7'},{'\xc1','\xe5'},{'\xc1','\xe7'},{'\xee','\xdd'},{'\xc1','\xe1'},
+ {'\xee','\xec'},{'\xee','\xe3'},{'\xee','\xd8'},{'\xee','\xd9'},{'\xee','\xe2'},
+ {'\x00','\x00'},{'\xc1','\xee'},{'\xee','\xe1'},{'\xee','\xd1'},{'\xee','\xe0'},
+ {'\xee','\xd4'},{'\xee','\xed'},{'\xc1','\xed'},{'\xc1','\xeb'},{'\xee','\xd5'},
+ {'\x00','\x00'},{'\xee','\xe8'},{'\x9e','\xad'},{'\xee','\xda'},{'\xee','\xe7'},
+ {'\x9e','\xae'},{'\xee','\xe9'},{'\xee','\xd0'},{'\xc1','\xe6'},{'\x9e','\xaf'},
+ {'\xee','\xea'},{'\x9e','\xb0'},{'\x96','\x44'},{'\xee','\xde'},{'\xfd','\xba'},
+ {'\xc1','\xea'},{'\xee','\xdb'},{'\xfd','\xbb'},{'\x00','\x00'},{'\xc1','\xec'},
+ {'\xee','\xe4'},{'\x00','\x00'},{'\x9e','\xb1'},{'\x9e','\xb2'},{'\xc1','\xe4'},
+ {'\xee','\xd6'},{'\xee','\xe5'},{'\x9e','\xb3'},{'\xee','\xdf'},{'\xeb','\xe3'},
+ {'\xee','\xe6'},{'\xee','\xd3'},{'\x9e','\xb4'},{'\xc1','\xe9'},{'\x00','\x00'},
+ {'\xee','\xeb'},{'\x9e','\xb5'},{'\xc1','\xe2'},{'\xee','\xce'},{'\x9e','\xb6'},
+ {'\xfb','\x73'},{'\x9e','\xb7'},{'\x9e','\xb8'},{'\xf1','\x60'},{'\xf1','\x59'},
+ {'\xc2','\xe9'},{'\x00','\x00'},{'\xf1','\x54'},{'\xf1','\x63'},{'\xf1','\x5b'},
+ {'\xee','\xdc'},{'\x9e','\xb9'},{'\xf1','\x65'},{'\xf1','\x55'},{'\x00','\x00'},
+ {'\xc2','\xe8'},{'\xf1','\x5f'},{'\xc2','\xea'},{'\xc2','\xf2'},{'\xc2','\xf0'},
+ {'\xf1','\x61'},{'\xc2','\xf1'},{'\xf1','\x57'},{'\x9e','\xba'},{'\xf1','\x58'},
+ {'\xf1','\x5d'},{'\xf1','\x62'},{'\x9e','\xbb'},{'\xee','\xcd'},{'\xc2','\xeb'},
+ {'\xf1','\x6a'},{'\xf1','\x67'},{'\xf1','\x6b'},{'\xf1','\x5e'},{'\xf1','\x5a'},
+ {'\xf1','\x68'},{'\xf3','\x6a'},{'\xf1','\x5c'},{'\x00','\x00'},{'\xc2','\xee'},
+ {'\x97','\x56'},{'\xc2','\xed'},{'\xee','\xcf'},{'\xc2','\xef'},{'\xf1','\x64'},
+ {'\xf1','\x66'},{'\xc2','\xec'},{'\xf1','\x69'},{'\xf1','\x53'},{'\x00','\x00'},
+ {'\xf1','\x56'},{'\x9e','\xbc'},{'\x94','\xdc'},{'\xfd','\xbc'},{'\x9e','\xbd'},
+ {'\x00','\x00'},{'\x9e','\xbe'},{'\x00','\x00'},{'\x9e','\xbf'},{'\xf3','\x73'},
+ {'\x00','\x00'},{'\xf3','\x63'},{'\xc3','\xeb'},{'\xf3','\x71'},{'\x00','\x00'},
+ {'\x97','\x57'},{'\xf3','\x61'},{'\xc3','\xec'},{'\x00','\x00'},{'\xf3','\x6c'},
+ {'\x9e','\xc0'},{'\xf3','\x68'},{'\xc3','\xf1'},{'\xf3','\x72'},{'\xf3','\x62'},
+ {'\xf3','\x65'},{'\xc3','\xe9'},{'\xf3','\x74'},{'\x9e','\xc1'},{'\xf3','\x6d'},
+ {'\xf3','\x70'},{'\xc3','\xef'},{'\xc3','\xf4'},{'\xc3','\xf2'},{'\xf3','\x69'},
+ {'\xf3','\x64'},{'\x9e','\xc2'},{'\xc3','\xed'},{'\xc3','\xee'},{'\xf3','\x60'},
+ {'\xc3','\xea'},{'\x9e','\xc3'},{'\xc3','\xe8'},{'\xc3','\xf0'},{'\xf3','\x6f'},
+ {'\xc3','\xf3'},{'\x97','\x58'},{'\xf3','\x6b'},{'\xf3','\x75'},{'\xc3','\xf5'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xf3','\x67'},{'\x00','\x00'},
+ {'\xf3','\x6e'},{'\x00','\x00'},{'\x9e','\xc4'},{'\x9e','\xc5'},{'\x00','\x00'},
+ {'\x9e','\xc6'},{'\x9e','\xc7'},{'\xf4','\xf3'},{'\xf5','\x42'},{'\xf4','\xf5'},
+ {'\xf4','\xfc'},{'\xf3','\x66'},{'\xf4','\xfa'},{'\xf4','\xe9'},{'\xf5','\x40'},
+ {'\xc4','\xc3'},{'\xf4','\xed'},{'\xf4','\xfe'},{'\xf4','\xf4'},{'\x9e','\xc8'},
+ {'\x00','\x00'},{'\xc4','\xc2'},{'\x9e','\xc9'},{'\x00','\x00'},{'\xf5','\x44'},
+ {'\xf4','\xf6'},{'\x9e','\xca'},{'\xf4','\xfb'},{'\xf4','\xfd'},{'\xf4','\xe7'},
+ {'\xf5','\x41'},{'\xf4','\xf2'},{'\xf4','\xf7'},{'\xf4','\xeb'},{'\xf4','\xef'},
+ {'\xf5','\x43'},{'\xf4','\xf9'},{'\xf4','\xe8'},{'\xf4','\xec'},{'\xf4','\xee'},
+ {'\xf4','\xf8'},{'\x9e','\xcb'},{'\xc4','\xc1'},{'\xf4','\xf1'},{'\x97','\x59'},
+ {'\x9e','\xcc'},{'\x00','\x00'},{'\x9e','\xcd'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf4','\xea'},{'\x97','\x5a'},{'\x00','\x00'},{'\x00','\x00'},{'\x9e','\xce'},
+ {'\x9e','\xcf'},{'\x9e','\xd0'},{'\xfd','\xbd'},{'\xf4','\xf0'},{'\xf6','\x61'},
+ {'\xf6','\x66'},{'\xc5','\x4f'},{'\xf6','\x68'},{'\x9e','\xd1'},{'\xc5','\x49'},
+ {'\x00','\x00'},{'\xf6','\x64'},{'\xf6','\x6a'},{'\xc5','\x4e'},{'\xc5','\x4a'},
+ {'\x00','\x00'},{'\xc5','\x4b'},{'\xf6','\x60'},{'\xf6','\x67'},{'\xc5','\x4d'},
+ {'\xf6','\x65'},{'\xc5','\x4c'},{'\xf6','\x5f'},{'\xf6','\x63'},{'\xf6','\x62'},
+ {'\x97','\x5b'},{'\xf6','\x5e'},{'\xf6','\x69'},{'\x97','\x5c'},{'\x9e','\xd2'},
+ {'\x9e','\xd3'},{'\xc5','\xb1'},{'\xf7','\x6d'},{'\xf7','\x70'},{'\xf7','\x6c'},
+ {'\xf7','\x6e'},{'\xf7','\x6f'},{'\xf7','\x69'},{'\xf7','\x6a'},{'\xf7','\x67'},
+ {'\x9e','\xd4'},{'\x00','\x00'},{'\xf7','\x6b'},{'\xf7','\x68'},{'\xc5','\xb2'},
+ {'\xc5','\xb3'},{'\x97','\x5d'},{'\x9e','\xd5'},{'\xf8','\x4b'},{'\x00','\x00'},
+ {'\xf8','\x4d'},{'\x9e','\xd6'},{'\x00','\x00'},{'\x97','\x5e'},{'\x95','\x58'},
+ {'\x00','\x00'},{'\xf8','\x4c'},{'\xf8','\x4e'},{'\x00','\x00'},{'\xc5','\xe0'},
+ {'\x00','\x00'},{'\xf8','\x4a'},{'\xc5','\xdf'},{'\xc5','\xe1'},{'\x9e','\xd7'},
+ {'\x00','\x00'},{'\x9e','\xd8'},{'\xf8','\xcb'},{'\xf8','\xcc'},{'\xc6','\x44'},
+ {'\xf8','\xca'},{'\x9e','\xd9'},{'\xf9','\x53'},{'\xf9','\x52'},{'\xf9','\x54'},
+ {'\xc6','\x5f'},{'\xf9','\x55'},{'\xc6','\x5e'},{'\xf9','\x56'},{'\xf9','\x72'},
+ {'\xf9','\x75'},{'\xf9','\x74'},{'\xc6','\x68'},{'\xf9','\x73'},{'\x9e','\xda'},
+ {'\x00','\x00'},{'\x9e','\xdb'},{'\xc6','\x72'},{'\xc6','\x70'},{'\xc6','\x71'},
+ {'\xc6','\x77'},{'\xf9','\xc0'},{'\xf9','\xc1'},{'\xf9','\xbf'},{'\xf9','\xc9'},
+ {'\x00','\x00'},{'\x9c','\xf0'},{'\x8d','\xc1'},{'\x8d','\xc0'},{'\x83','\xe1'},
+ {'\x83','\xe0'},{'\x83','\xe2'},{'\x83','\xe3'},{'\x8d','\xc7'},{'\x8d','\xd9'},
+ {'\x8d','\xd6'},{'\x84','\xb6'},{'\x8d','\xd7'},{'\x00','\x00'},{'\x84','\xb7'},
+ {'\x84','\xb5'},{'\x8f','\x46'},{'\x8d','\xd8'},{'\x00','\x00'},{'\x84','\xb4'},
+ {'\x00','\x00'},{'\x85','\x73'},{'\x97','\x5f'},{'\x8d','\xf4'},{'\x86','\x73'},
+ {'\x85','\x76'},{'\x85','\x71'},{'\x8c','\x5d'},{'\x85','\x74'},{'\x88','\xae'},
+ {'\x89','\xa1'},{'\x85','\x78'},{'\x85','\x77'},{'\x8d','\x76'},{'\x84','\xe8'},
+ {'\x85','\x75'},{'\x8b','\x4f'},{'\x86','\x6e'},{'\x8d','\xf7'},{'\x8d','\xf2'},
+ {'\x8d','\xf3'},{'\x8d','\xf6'},{'\x85','\x72'},{'\x8d','\xf5'},{'\x8e','\x5a'},
+ {'\x89','\x7e'},{'\x8e','\x5b'},{'\x86','\x68'},{'\x86','\x67'},{'\x84','\x73'},
+ {'\x8e','\x5c'},{'\x97','\x60'},{'\x86','\x6a'},{'\x86','\x69'},{'\x8d','\xb2'},
+ {'\x8d','\xa7'},{'\x8e','\x60'},{'\x8e','\x5f'},{'\x86','\x6b'},{'\x86','\x75'},
+ {'\x86','\x6c'},{'\x8c','\xb2'},{'\x86','\x6f'},{'\x86','\x70'},{'\x8d','\x44'},
+ {'\x86','\x6d'},{'\x86','\x76'},{'\x00','\x00'},{'\x8e','\x59'},{'\x86','\x71'},
+ {'\x8e','\x58'},{'\x86','\x72'},{'\x8e','\x5e'},{'\x86','\x74'},{'\x8c','\xb4'},
+ {'\x00','\x00'},{'\x88','\xa8'},{'\x8e','\xa5'},{'\x8e','\xa4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8e','\xa6'},{'\x8e','\xac'},{'\x8e','\xd1'},{'\x97','\x61'},
+ {'\x8c','\x5e'},{'\x00','\x00'},{'\x8c','\xb3'},{'\x87','\x66'},{'\x88','\xaa'},
+ {'\x97','\x62'},{'\x8e','\xa7'},{'\x8f','\xa7'},{'\x8f','\x6a'},{'\x87','\x68'},
+ {'\x87','\x6c'},{'\x8e','\xd5'},{'\x8e','\xad'},{'\x00','\x00'},{'\x8f','\xec'},
+ {'\x87','\x6a'},{'\x8f','\xcd'},{'\x8e','\xaa'},{'\x8e','\xa8'},{'\x87','\x69'},
+ {'\x87','\x67'},{'\x89','\xa4'},{'\x8e','\xa9'},{'\x87','\x64'},{'\x8e','\xa3'},
+ {'\x85','\xb6'},{'\x97','\x63'},{'\x8f','\xe5'},{'\x87','\x6b'},{'\x87','\x65'},
+ {'\x8e','\xab'},{'\x8c','\xe4'},{'\x8f','\xee'},{'\x88','\xa7'},{'\x00','\x00'},
+ {'\x8f','\x42'},{'\x8e','\xd2'},{'\x8b','\xce'},{'\x8b','\xd5'},{'\x88','\xa6'},
+ {'\x8b','\x4e'},{'\x88','\xaf'},{'\x97','\x64'},{'\x88','\xa9'},{'\x8a','\xa2'},
+ {'\x8e','\xd6'},{'\x8e','\xd7'},{'\x8c','\x5f'},{'\x88','\xac'},{'\x8e','\xd4'},
+ {'\x88','\xad'},{'\x88','\xa4'},{'\x8e','\x5d'},{'\x97','\x65'},{'\x97','\x66'},
+ {'\x88','\xab'},{'\x88','\xa5'},{'\x8e','\xd0'},{'\x8e','\xd3'},{'\x8e','\xd8'},
+ {'\x8f','\x44'},{'\x8f','\x40'},{'\x8f','\x41'},{'\x97','\x67'},{'\x89','\x7d'},
+ {'\x8a','\x7d'},{'\x8f','\x43'},{'\x00','\x00'},{'\x97','\x68'},{'\x8f','\x45'},
+ {'\x89','\xa7'},{'\x00','\x00'},{'\x89','\xa2'},{'\x89','\xa8'},{'\x8d','\xa9'},
+ {'\x8a','\xa3'},{'\x89','\xa5'},{'\x89','\xa6'},{'\x00','\x00'},{'\x90','\xf1'},
+ {'\x8e','\xfd'},{'\x97','\x69'},{'\x97','\x6a'},{'\x8e','\xfe'},{'\x89','\x7a'},
+ {'\x8a','\x7e'},{'\x89','\x7b'},{'\x89','\x7c'},{'\x89','\xa9'},{'\x8a','\xa1'},
+ {'\x00','\x00'},{'\x8f','\x69'},{'\x8b','\xd3'},{'\x8f','\x6b'},{'\x8a','\xa8'},
+ {'\x8f','\x68'},{'\x8a','\xa5'},{'\x8a','\xa4'},{'\x8a','\xa6'},{'\x8f','\xa8'},
+ {'\x00','\x00'},{'\x8a','\xa7'},{'\x97','\x6b'},{'\x8a','\x7b'},{'\x8a','\x7c'},
+ {'\x8b','\xd4'},{'\x00','\x00'},{'\x8f','\xea'},{'\x97','\x6c'},{'\x8a','\x42'},
+ {'\x8b','\x51'},{'\x00','\x00'},{'\x8b','\x54'},{'\x8d','\x7d'},{'\x00','\x00'},
+ {'\x8c','\xb6'},{'\x8b','\x50'},{'\x97','\x6d'},{'\x8f','\xa9'},{'\x8b','\x52'},
+ {'\x8b','\x4d'},{'\x8b','\x53'},{'\x8f','\xa6'},{'\x90','\x60'},{'\x00','\x00'},
+ {'\x8b','\xd1'},{'\x8b','\xcf'},{'\x8b','\xd0'},{'\x8b','\xd2'},{'\x00','\x00'},
+ {'\x8f','\xc9'},{'\x8b','\xcb'},{'\x8b','\xcc'},{'\x8b','\xcd'},{'\x8f','\xca'},
+ {'\x00','\x00'},{'\x8f','\xe8'},{'\x97','\x6e'},{'\x8f','\xe9'},{'\x8f','\xed'},
+ {'\x97','\x6f'},{'\x8f','\xe6'},{'\x90','\xa1'},{'\x8f','\xe7'},{'\x97','\x70'},
+ {'\x8f','\xcb'},{'\x8f','\xeb'},{'\x90','\x61'},{'\x8c','\xb1'},{'\x00','\x00'},
+ {'\x8c','\xb5'},{'\x8c','\xb0'},{'\x90','\x48'},{'\x97','\x71'},{'\x8d','\x43'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x8c','\x7c'},{'\xaa','\xf8'},{'\x9e','\xdc'},
+ {'\x00','\x00'},{'\xd8','\x44'},{'\xdc','\x78'},{'\xe8','\xa5'},{'\xf3','\x76'},
+ {'\x00','\x00'},{'\x83','\x63'},{'\xaa','\xf9'},{'\x00','\x00'},{'\xad','\xac'},
+ {'\xb0','\x7b'},{'\x00','\x00'},{'\x9e','\xdd'},{'\xd8','\x45'},{'\x97','\x72'},
+ {'\xd8','\x46'},{'\xb3','\xac'},{'\x94','\xdd'},{'\xb6','\x7d'},{'\xdc','\x7a'},
+ {'\xdc','\x79'},{'\xb6','\xa3'},{'\xb6','\x7c'},{'\xdc','\x7b'},{'\xb6','\x7e'},
+ {'\xb6','\xa2'},{'\xb6','\xa1'},{'\xb6','\x7b'},{'\x00','\x00'},{'\x94','\xde'},
+ {'\xfd','\xbe'},{'\xb9','\x68'},{'\x97','\x73'},{'\x00','\x00'},{'\xe0','\xd0'},
+ {'\xe0','\xce'},{'\x00','\x00'},{'\xe0','\xcf'},{'\xe0','\xcd'},{'\x97','\x74'},
+ {'\xbb','\xd2'},{'\x92','\x6b'},{'\xbb','\xd5'},{'\xbb','\xd7'},{'\xbb','\xd6'},
+ {'\x9e','\xde'},{'\xfd','\xbf'},{'\xbb','\xd3'},{'\xbb','\xd4'},{'\x9e','\xdf'},
+ {'\xe8','\xa7'},{'\xe8','\xa6'},{'\xbe','\x5b'},{'\xe8','\xa8'},{'\x00','\x00'},
+ {'\xe8','\xa9'},{'\xbe','\x5c'},{'\x97','\x75'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xec','\x4d'},{'\xec','\x4b'},{'\xee','\xf3'},{'\x00','\x00'},{'\xec','\x49'},
+ {'\xec','\x4a'},{'\xc0','\x46'},{'\xec','\x46'},{'\xec','\x4e'},{'\xec','\x48'},
+ {'\xec','\x4c'},{'\xee','\xef'},{'\x00','\x00'},{'\x00','\x00'},{'\xee','\xf1'},
+ {'\x00','\x00'},{'\xee','\xf2'},{'\xc1','\xf3'},{'\xee','\xee'},{'\xc1','\xf2'},
+ {'\xee','\xf0'},{'\xc1','\xef'},{'\xc1','\xf0'},{'\xc1','\xf1'},{'\xec','\x47'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc2','\xf5'},{'\xf1','\x6e'},{'\xf1','\x6c'},
+ {'\xf1','\x6d'},{'\xc2','\xf3'},{'\xc2','\xf6'},{'\xc2','\xf4'},{'\x00','\x00'},
+ {'\x93','\xa7'},{'\x00','\x00'},{'\xf3','\x77'},{'\xf3','\x78'},{'\xc3','\xf6'},
+ {'\x00','\x00'},{'\xf5','\x45'},{'\xf5','\x47'},{'\xf5','\x46'},{'\xc4','\xc4'},
+ {'\xc5','\x50'},{'\xf6','\x6d'},{'\xf6','\x6c'},{'\xf6','\x6b'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x83','\x64'},{'\x83','\xa2'},{'\x83','\xe4'},{'\x8d','\xda'},
+ {'\x00','\x00'},{'\x84','\xb8'},{'\x83','\xf4'},{'\x8b','\x56'},{'\x85','\x7a'},
+ {'\x8a','\xac'},{'\x85','\x7c'},{'\x85','\x7e'},{'\x85','\x7d'},{'\x85','\x79'},
+ {'\x8d','\xf8'},{'\x84','\xdd'},{'\x86','\x77'},{'\x88','\xc1'},{'\x87','\x6e'},
+ {'\x87','\x47'},{'\x90','\x49'},{'\x87','\x6f'},{'\x88','\xb0'},{'\x00','\x00'},
+ {'\x87','\x71'},{'\x87','\x70'},{'\x87','\x6d'},{'\x8e','\xda'},{'\x90','\xac'},
+ {'\x88','\xb1'},{'\x8e','\xd9'},{'\x00','\x00'},{'\x8f','\x48'},{'\x8f','\x49'},
+ {'\x8f','\x4a'},{'\x8f','\xb0'},{'\x8f','\x4b'},{'\x8f','\x4c'},{'\x89','\xaa'},
+ {'\x8f','\x47'},{'\x8c','\x60'},{'\x8a','\xab'},{'\x8f','\x6c'},{'\x00','\x00'},
+ {'\x8a','\xa9'},{'\x8a','\xaa'},{'\x8b','\x55'},{'\x8b','\x57'},{'\x00','\x00'},
+ {'\x8b','\x58'},{'\x8f','\xef'},{'\x00','\x00'},{'\xaa','\xfa'},{'\x9c','\xf1'},
+ {'\xc9','\xaa'},{'\x85','\xa1'},{'\xca','\x58'},{'\xa6','\xe9'},{'\xca','\x56'},
+ {'\xca','\x59'},{'\xca','\x57'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xcb','\xae'},{'\x00','\x00'},{'\xa8','\xc1'},{'\x00','\x00'},{'\xa8','\xc2'},
+ {'\xcb','\xb0'},{'\xa8','\xbf'},{'\xcb','\xaf'},{'\xcb','\xad'},{'\xa8','\xc0'},
+ {'\xa8','\xbe'},{'\x85','\xa3'},{'\x84','\xbb'},{'\x83','\xe5'},{'\x85','\xa2'},
+ {'\x00','\x00'},{'\xfd','\xc1'},{'\xcd','\xd8'},{'\xcd','\xdb'},{'\xaa','\xfd'},
+ {'\xcd','\xda'},{'\xcd','\xd9'},{'\x00','\x00'},{'\xaa','\xfc'},{'\xaa','\xfb'},
+ {'\xfe','\x42'},{'\xab','\x40'},{'\xcd','\xdc'},{'\xaa','\xfe'},{'\x87','\x72'},
+ {'\x84','\xba'},{'\x8b','\xd8'},{'\x84','\xb9'},{'\x83','\xe7'},{'\xd0','\xc6'},
+ {'\xad','\xae'},{'\xad','\xaf'},{'\xad','\xb0'},{'\xd0','\xc7'},{'\xd0','\xc3'},
+ {'\xad','\xad'},{'\xd0','\xc4'},{'\x00','\x00'},{'\xd0','\xc5'},{'\xd0','\xc2'},
+ {'\x83','\xe6'},{'\x9e','\xe0'},{'\x00','\x00'},{'\xb0','\xa4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xb0','\xa1'},{'\xd4','\x45'},{'\xb0','\xa2'},{'\xb0','\xa5'},
+ {'\xd4','\x46'},{'\x00','\x00'},{'\xb0','\x7e'},{'\xb0','\x7c'},{'\xb0','\x7d'},
+ {'\xb0','\xa3'},{'\x92','\x67'},{'\x97','\x76'},{'\x8d','\xf9'},{'\x86','\x78'},
+ {'\x89','\xac'},{'\xb3','\xad'},{'\xd8','\x49'},{'\xb3','\xb5'},{'\xd8','\x48'},
+ {'\x00','\x00'},{'\xd8','\x4b'},{'\xb3','\xb1'},{'\xd8','\x4a'},{'\xb6','\xab'},
+ {'\xb3','\xaf'},{'\xb3','\xb2'},{'\xb3','\xae'},{'\xb3','\xb3'},{'\xb3','\xb4'},
+ {'\xb3','\xb0'},{'\x00','\x00'},{'\x92','\xb4'},{'\x9e','\xe1'},{'\xd8','\x47'},
+ {'\xb6','\xa7'},{'\xdc','\x7d'},{'\x00','\x00'},{'\xdc','\xa3'},{'\xfd','\xc5'},
+ {'\x00','\x00'},{'\xdc','\xa2'},{'\xb6','\xac'},{'\xb6','\xa8'},{'\xb6','\xa9'},
+ {'\xdc','\x7c'},{'\xdc','\x7e'},{'\xdc','\xa1'},{'\xb6','\xa4'},{'\xb6','\xa6'},
+ {'\x00','\x00'},{'\xb6','\xaa'},{'\xb6','\xa5'},{'\x92','\xfa'},{'\x8a','\xad'},
+ {'\xe0','\xd3'},{'\xe0','\xd1'},{'\xe0','\xd2'},{'\xb9','\x6a'},{'\xb9','\x6b'},
+ {'\xfd','\xc4'},{'\xe0','\xd4'},{'\xb9','\x69'},{'\xbb','\xd8'},{'\x00','\x00'},
+ {'\xbb','\xda'},{'\xbb','\xd9'},{'\x97','\x77'},{'\xe4','\xbb'},{'\x00','\x00'},
+ {'\x92','\x47'},{'\xe4','\xbc'},{'\xe8','\xab'},{'\x95','\xf9'},{'\xe8','\xaa'},
+ {'\x9e','\xe2'},{'\x00','\x00'},{'\xc0','\x47'},{'\xc0','\x48'},{'\xec','\x4f'},
+ {'\xc0','\x49'},{'\x00','\x00'},{'\xee','\xf6'},{'\x00','\x00'},{'\xee','\xf4'},
+ {'\x97','\x78'},{'\xee','\xf5'},{'\xc1','\xf4'},{'\x97','\x79'},{'\xf1','\x6f'},
+ {'\xc3','\xf7'},{'\x00','\x00'},{'\xc6','\xd7'},{'\x95','\xfb'},{'\xc1','\xf5'},
+ {'\xab','\x41'},{'\x00','\x00'},{'\xb0','\xa6'},{'\xd4','\x47'},{'\x86','\x79'},
+ {'\x8b','\xd9'},{'\xd8','\x4c'},{'\xb3','\xb6'},{'\xb6','\xad'},{'\xdc','\xa4'},
+ {'\xdc','\xa6'},{'\xb6','\xaf'},{'\xb6','\xae'},{'\xb6','\xb0'},{'\xb6','\xb1'},
+ {'\xdc','\xa5'},{'\xb9','\x6e'},{'\xb9','\x6f'},{'\xb9','\x6d'},{'\xbb','\xdb'},
+ {'\xb9','\x6c'},{'\xe0','\xd5'},{'\x8b','\x5b'},{'\x00','\x00'},{'\x92','\xca'},
+ {'\xbb','\xdc'},{'\xe8','\xac'},{'\xec','\x50'},{'\xc0','\x4a'},{'\xc1','\xf6'},
+ {'\xf1','\x70'},{'\xf1','\x74'},{'\xc2','\xf9'},{'\xf1','\x71'},{'\xc2','\xfa'},
+ {'\xc2','\xf8'},{'\xf1','\x75'},{'\xc2','\xfb'},{'\xf1','\x73'},{'\x90','\x6d'},
+ {'\xf3','\x79'},{'\xc2','\xf7'},{'\xc3','\xf8'},{'\x00','\x00'},{'\xf8','\xcd'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xab','\x42'},{'\xb3','\xb8'},{'\xb3','\xb7'},
+ {'\x94','\x48'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb6','\xb2'},
+ {'\xdc','\xa8'},{'\xdc','\xa7'},{'\xb6','\xb3'},{'\x8d','\x5e'},{'\x9e','\xe3'},
+ {'\xe0','\xd9'},{'\xb9','\x73'},{'\xb9','\x70'},{'\xe0','\xd8'},{'\xb9','\x72'},
+ {'\xe0','\xd6'},{'\xb9','\x71'},{'\x00','\x00'},{'\xe0','\xd7'},{'\x8b','\xda'},
+ {'\xe4','\xbd'},{'\xbb','\xdd'},{'\x8c','\xe6'},{'\xe8','\xaf'},{'\xfd','\xc7'},
+ {'\xbe','\x5d'},{'\xe8','\xad'},{'\xbe','\x5e'},{'\xbe','\x5f'},{'\xe8','\xae'},
+ {'\xbe','\x60'},{'\x93','\xed'},{'\xec','\x51'},{'\x00','\x00'},{'\xc0','\x4e'},
+ {'\xc0','\x4b'},{'\xc0','\x50'},{'\xec','\x53'},{'\xc0','\x4c'},{'\xec','\x52'},
+ {'\xc0','\x4f'},{'\x00','\x00'},{'\x00','\x00'},{'\xc0','\x4d'},{'\x00','\x00'},
+ {'\xee','\xf9'},{'\xee','\xfb'},{'\x00','\x00'},{'\x9e','\xe4'},{'\xc1','\xf7'},
+ {'\xee','\xfa'},{'\xc1','\xf8'},{'\xee','\xf8'},{'\xee','\xf7'},{'\xfd','\xc8'},
+ {'\xf1','\x77'},{'\xf1','\x76'},{'\xc2','\xfc'},{'\xf1','\x78'},{'\xf3','\x7e'},
+ {'\xc3','\xfa'},{'\xf3','\x7d'},{'\xf3','\x7a'},{'\xc3','\xf9'},{'\xf3','\x7b'},
+ {'\xf3','\x7c'},{'\x8d','\x60'},{'\xf5','\x48'},{'\xf5','\x49'},{'\xc4','\xc5'},
+ {'\xfd','\xc9'},{'\xc5','\x53'},{'\x97','\x7a'},{'\x9d','\xbb'},{'\xf6','\x6e'},
+ {'\x9e','\xe5'},{'\x00','\x00'},{'\xc5','\x51'},{'\xc5','\x52'},{'\xf6','\x6f'},
+ {'\x97','\x7b'},{'\x00','\x00'},{'\xc5','\xb4'},{'\xc5','\xb5'},{'\xf7','\x71'},
+ {'\x9e','\xe6'},{'\x9e','\xe7'},{'\xc6','\x45'},{'\xf8','\xcf'},{'\xc6','\x47'},
+ {'\x00','\x00'},{'\xf8','\xce'},{'\xf8','\xd0'},{'\xc6','\x46'},{'\xf9','\x57'},
+ {'\x00','\x00'},{'\xf9','\xad'},{'\x00','\x00'},{'\x97','\x7c'},{'\x00','\x00'},
+ {'\x97','\x7d'},{'\x00','\x00'},{'\x97','\x7e'},{'\xab','\x43'},{'\x8e','\xdb'},
+ {'\x00','\x00'},{'\x97','\xa1'},{'\xb9','\x74'},{'\x9e','\xe8'},{'\xe4','\xbe'},
+ {'\x93','\x43'},{'\xe8','\xb0'},{'\xc0','\x51'},{'\xc0','\x52'},{'\xfe','\x6d'},
+ {'\xab','\x44'},{'\xfd','\xca'},{'\xbe','\x61'},{'\xc3','\xfb'},{'\xad','\xb1'},
+ {'\x00','\x00'},{'\x97','\xa2'},{'\x8d','\x45'},{'\xc0','\x53'},{'\x00','\x00'},
+ {'\xc5','\xe2'},{'\xad','\xb2'},{'\xd8','\x4d'},{'\x97','\xa3'},{'\xdc','\xa9'},
+ {'\x95','\xf7'},{'\xdc','\xab'},{'\x00','\x00'},{'\xdc','\xaa'},{'\x97','\xa4'},
+ {'\xe0','\xdd'},{'\xe0','\xda'},{'\xb9','\x75'},{'\x00','\x00'},{'\xb9','\x76'},
+ {'\xe0','\xdb'},{'\xe0','\xdc'},{'\x94','\xdf'},{'\xe4','\xc0'},{'\xe4','\xc5'},
+ {'\xbb','\xde'},{'\xe4','\xbf'},{'\xe4','\xc1'},{'\xe4','\xc8'},{'\xe4','\xc3'},
+ {'\xe4','\xc7'},{'\xe4','\xc4'},{'\xe4','\xc2'},{'\xe4','\xc6'},{'\xbb','\xdf'},
+ {'\x94','\xe0'},{'\x9e','\xe9'},{'\xe8','\xb3'},{'\x9e','\xea'},{'\xe8','\xb1'},
+ {'\xbe','\x63'},{'\x00','\x00'},{'\xbe','\x62'},{'\xe8','\xb2'},{'\xbe','\x64'},
+ {'\x94','\xe1'},{'\x8c','\xe7'},{'\x97','\xa5'},{'\x00','\x00'},{'\xec','\x56'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\x55'},{'\xc0','\x54'},{'\xec','\x54'},
+ {'\xee','\xfc'},{'\x9e','\xeb'},{'\xee','\xfe'},{'\xef','\x41'},{'\xef','\x40'},
+ {'\xfd','\xcb'},{'\xc1','\xf9'},{'\xee','\xfd'},{'\xf1','\xa1'},{'\xc2','\xfd'},
+ {'\xf1','\x7d'},{'\xf1','\xa2'},{'\xc2','\xfe'},{'\x00','\x00'},{'\xf1','\x7b'},
+ {'\x00','\x00'},{'\xf1','\x7e'},{'\xf1','\x7c'},{'\xf1','\x79'},{'\xc3','\x40'},
+ {'\xf1','\x7a'},{'\x8d','\x7e'},{'\x00','\x00'},{'\x9e','\xec'},{'\x97','\xa6'},
+ {'\xf3','\xa1'},{'\xfd','\xcc'},{'\x00','\x00'},{'\xf3','\xa3'},{'\xf3','\xa2'},
+ {'\xfd','\xcd'},{'\xf5','\x4a'},{'\xfd','\xce'},{'\xf5','\x4b'},{'\x00','\x00'},
+ {'\x9e','\xed'},{'\xfd','\xcf'},{'\xf6','\x70'},{'\x9e','\xee'},{'\xc5','\xb7'},
+ {'\x9e','\xef'},{'\xc5','\xb6'},{'\xf8','\x4f'},{'\xf8','\x50'},{'\xc6','\x48'},
+ {'\xf8','\xd1'},{'\xfd','\xd0'},{'\xc6','\x69'},{'\x00','\x00'},{'\xad','\xb3'},
+ {'\xb6','\xb4'},{'\xe4','\xca'},{'\xe4','\xc9'},{'\xe8','\xb5'},{'\xe8','\xb4'},
+ {'\x00','\x00'},{'\x9e','\xf0'},{'\xc1','\xfa'},{'\xef','\x43'},{'\xef','\x42'},
+ {'\xf1','\xa5'},{'\xf1','\xa3'},{'\xf1','\xa6'},{'\xf1','\xa4'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xc3','\xfc'},{'\xf3','\xa4'},{'\xf3','\xa5'},{'\xf3','\xa6'},
+ {'\x9e','\xf1'},{'\xf6','\x71'},{'\x00','\x00'},{'\xf7','\x72'},{'\x00','\x00'},
+ {'\xf8','\xd2'},{'\x83','\xa3'},{'\x85','\xa4'},{'\x00','\x00'},{'\x8a','\xb0'},
+ {'\x8f','\xab'},{'\x8f','\xce'},{'\x8b','\xdb'},{'\xad','\xb4'},{'\x95','\x61'},
+ {'\x00','\x00'},{'\xec','\x57'},{'\xef','\x44'},{'\x97','\xa7'},{'\xad','\xb5'},
+ {'\x00','\x00'},{'\x8b','\xdc'},{'\xbb','\xe0'},{'\x00','\x00'},{'\xec','\x58'},
+ {'\xc3','\x41'},{'\xf1','\xa7'},{'\xc3','\xfd'},{'\x00','\x00'},{'\xf5','\x4c'},
+ {'\xf5','\x4d'},{'\xc5','\x54'},{'\xf8','\x51'},{'\xad','\xb6'},{'\xb3','\xbb'},
+ {'\xb3','\xbc'},{'\xd8','\x4e'},{'\xb6','\xb5'},{'\xb6','\xb6'},{'\xdc','\xac'},
+ {'\xb6','\xb7'},{'\x00','\x00'},{'\xb9','\x7a'},{'\x00','\x00'},{'\xb9','\x7c'},
+ {'\xe0','\xdf'},{'\xe0','\xe0'},{'\xe0','\xde'},{'\xb9','\x77'},{'\xb9','\x78'},
+ {'\xb9','\x7b'},{'\xb9','\x79'},{'\x9e','\xf2'},{'\x9e','\xf3'},{'\xe4','\xcb'},
+ {'\xbb','\xe1'},{'\xbb','\xe2'},{'\x00','\x00'},{'\x82','\x5b'},{'\xe8','\xbc'},
+ {'\xbe','\x67'},{'\xe8','\xb7'},{'\xe8','\xb6'},{'\xfd','\xd2'},{'\xe8','\xbb'},
+ {'\xbe','\x65'},{'\x00','\x00'},{'\x9e','\xf4'},{'\xc0','\x5b'},{'\x00','\x00'},
+ {'\xe8','\xb8'},{'\xe8','\xbd'},{'\xe8','\xba'},{'\xe8','\xb9'},{'\x00','\x00'},
+ {'\xbe','\x66'},{'\x82','\x7b'},{'\xc0','\x59'},{'\xfd','\xd3'},{'\xec','\x5a'},
+ {'\xc0','\x55'},{'\x00','\x00'},{'\xec','\x5b'},{'\x9e','\xf5'},{'\x82','\x42'},
+ {'\xec','\x59'},{'\x00','\x00'},{'\xc0','\x58'},{'\xc0','\x56'},{'\xc0','\x5a'},
+ {'\x00','\x00'},{'\xc0','\x57'},{'\x93','\xdf'},{'\x97','\xa8'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xef','\x45'},{'\x00','\x00'},{'\xef','\x4a'},
+ {'\xef','\x46'},{'\xef','\x49'},{'\xc1','\xfb'},{'\xfd','\xd5'},{'\xed','\xd4'},
+ {'\xef','\x48'},{'\xef','\x47'},{'\xfd','\xd6'},{'\xc3','\x44'},{'\xc3','\x42'},
+ {'\xc3','\x45'},{'\xc3','\x43'},{'\xf1','\xa8'},{'\xf1','\xa9'},{'\xf1','\xaa'},
+ {'\xc3','\x46'},{'\x97','\xa9'},{'\x92','\xb8'},{'\x9d','\xd2'},{'\xf3','\xaa'},
+ {'\xc4','\x40'},{'\xf3','\xa8'},{'\x00','\x00'},{'\xc4','\x41'},{'\xf3','\xa7'},
+ {'\xf3','\xa9'},{'\xc3','\xfe'},{'\xf5','\x51'},{'\xf5','\x4e'},{'\x00','\x00'},
+ {'\xf5','\x4f'},{'\xf5','\x50'},{'\xf6','\x72'},{'\xc5','\x56'},{'\xfd','\xd7'},
+ {'\xc5','\x55'},{'\x9e','\xf6'},{'\xf7','\x74'},{'\xf7','\x73'},{'\xc5','\xb8'},
+ {'\xfd','\xd8'},{'\x00','\x00'},{'\x00','\x00'},{'\xc5','\xe3'},{'\xc6','\x49'},
+ {'\xc6','\x60'},{'\xf9','\x58'},{'\xf9','\xae'},{'\xf9','\xaf'},{'\x83','\xa4'},
+ {'\x84','\xbc'},{'\x84','\xbd'},{'\x8d','\xfa'},{'\x85','\xa5'},{'\x85','\xa6'},
+ {'\x85','\xa7'},{'\x86','\x7e'},{'\x86','\x7c'},{'\x8c','\xb8'},{'\x86','\x7d'},
+ {'\x8e','\x62'},{'\x86','\xa1'},{'\x86','\xa2'},{'\x8e','\x61'},{'\x86','\x7b'},
+ {'\x8d','\x77'},{'\x87','\x74'},{'\x87','\x73'},{'\x89','\xb0'},{'\x88','\xb3'},
+ {'\x89','\xaf'},{'\x00','\x00'},{'\x88','\xb4'},{'\x8e','\xba'},{'\x00','\x00'},
+ {'\x8e','\xdc'},{'\x89','\xb5'},{'\x89','\xb1'},{'\x00','\x00'},{'\x89','\xb4'},
+ {'\x89','\xb2'},{'\x00','\x00'},{'\x89','\x46'},{'\x8a','\xb1'},{'\x8b','\x5f'},
+ {'\x00','\x00'},{'\x8b','\x60'},{'\x8b','\x61'},{'\x8b','\x5e'},{'\x8b','\x5d'},
+ {'\x90','\xa7'},{'\x8f','\xf0'},{'\x8b','\xde'},{'\x8f','\xcf'},{'\x8c','\xb9'},
+ {'\x00','\x00'},{'\x8c','\xe9'},{'\x97','\xaa'},{'\x8d','\x61'},{'\x90','\xa8'},
+ {'\xad','\xb7'},{'\xdc','\xad'},{'\x94','\xe2'},{'\x00','\x00'},{'\xe0','\xe1'},
+ {'\xe4','\xcc'},{'\xe4','\xcd'},{'\xbb','\xe3'},{'\x00','\x00'},{'\xbb','\xe4'},
+ {'\xe8','\xbe'},{'\xbe','\x68'},{'\xfd','\xd9'},{'\x00','\x00'},{'\xc1','\xfc'},
+ {'\x9e','\xf7'},{'\xf1','\xab'},{'\x9e','\xf8'},{'\xc3','\x47'},{'\xf3','\xad'},
+ {'\xc4','\x42'},{'\xf3','\xac'},{'\xf3','\xae'},{'\xf3','\xab'},{'\xf6','\x75'},
+ {'\xf5','\x52'},{'\xf5','\x53'},{'\x97','\xab'},{'\xc4','\xc6'},{'\x00','\x00'},
+ {'\xf6','\x74'},{'\x9e','\xf9'},{'\xfb','\xb2'},{'\xf6','\x73'},{'\x9e','\xfa'},
+ {'\xf7','\x75'},{'\xf9','\xb0'},{'\x00','\x00'},{'\x83','\xa5'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8e','\xae'},{'\x87','\x75'},{'\x8a','\xb2'},{'\x00','\x00'},
+ {'\x8b','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\x8c','\x61'},{'\x90','\x4a'},
+ {'\x97','\xac'},{'\xad','\xb8'},{'\xfd','\xdb'},{'\x00','\x00'},{'\x83','\xa6'},
+ {'\xad','\xb9'},{'\x9e','\xfb'},{'\x9e','\xfc'},{'\xb0','\xa7'},{'\xd4','\x48'},
+ {'\x00','\x00'},{'\xd8','\x4f'},{'\xfd','\xdc'},{'\xb6','\xb8'},{'\x8c','\xba'},
+ {'\xb6','\xbb'},{'\xb6','\xb9'},{'\xdc','\xae'},{'\x9e','\xfd'},{'\xb6','\xbd'},
+ {'\x97','\xad'},{'\xb6','\xba'},{'\x00','\x00'},{'\x95','\xda'},{'\xb6','\xbc'},
+ {'\x00','\x00'},{'\xb9','\x7e'},{'\x9e','\xfe'},{'\xe0','\xe2'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xe0','\xe3'},{'\xe8','\xc0'},{'\x00','\x00'},{'\xb9','\x7d'},
+ {'\xb9','\xa1'},{'\xb9','\xa2'},{'\x00','\x00'},{'\xe4','\xcf'},{'\x00','\x00'},
+ {'\xe4','\xce'},{'\xbb','\xe5'},{'\x00','\x00'},{'\xbb','\xe6'},{'\x00','\x00'},
+ {'\xe4','\xd0'},{'\xe8','\xbf'},{'\xbb','\xe8'},{'\xbe','\x69'},{'\x00','\x00'},
+ {'\xbb','\xe7'},{'\x8d','\x47'},{'\x9f','\x70'},{'\x00','\x00'},{'\xc0','\x5c'},
+ {'\xe8','\xc1'},{'\xbe','\x6b'},{'\xbe','\x6a'},{'\xe8','\xc2'},{'\xe8','\xc5'},
+ {'\xe8','\xc3'},{'\xe8','\xc4'},{'\xbe','\x6c'},{'\x9f','\x71'},{'\xc0','\x61'},
+ {'\xc0','\x5f'},{'\x9f','\x72'},{'\x97','\xae'},{'\xc0','\x5e'},{'\xec','\x5d'},
+ {'\x97','\xaf'},{'\xc0','\x60'},{'\x00','\x00'},{'\x00','\x00'},{'\xec','\x5c'},
+ {'\xef','\x4b'},{'\x00','\x00'},{'\xec','\x5e'},{'\xc0','\x5d'},{'\xec','\x5f'},
+ {'\xef','\x4e'},{'\xef','\x4c'},{'\xef','\x4d'},{'\xef','\x52'},{'\xc3','\x4b'},
+ {'\xef','\x51'},{'\xef','\x54'},{'\xef','\x53'},{'\xef','\x50'},{'\xef','\x4f'},
+ {'\x00','\x00'},{'\xc1','\xfd'},{'\x00','\x00'},{'\x9f','\x73'},{'\xa0','\x44'},
+ {'\xfd','\xde'},{'\xf1','\xae'},{'\xfd','\xdf'},{'\xf1','\xad'},{'\xc3','\x4a'},
+ {'\xc3','\x48'},{'\xc3','\x49'},{'\xfb','\xb3'},{'\xf1','\xac'},{'\xfd','\xdd'},
+ {'\xf3','\xb1'},{'\x00','\x00'},{'\xc4','\x43'},{'\x00','\x00'},{'\xf3','\xb0'},
+ {'\xf3','\xaf'},{'\xc4','\x44'},{'\xfd','\xe1'},{'\xf5','\x58'},{'\xf5','\x57'},
+ {'\xfb','\xb4'},{'\xf5','\x55'},{'\x00','\x00'},{'\xf5','\x54'},{'\xc4','\xc8'},
+ {'\xc4','\xc7'},{'\xf5','\x59'},{'\xf7','\x76'},{'\xc5','\xb9'},{'\xf6','\x77'},
+ {'\xc5','\x57'},{'\xf6','\x76'},{'\xf5','\x56'},{'\x00','\x00'},{'\xf7','\x77'},
+ {'\xc5','\xe4'},{'\x9f','\x74'},{'\xc6','\x61'},{'\xf9','\x59'},{'\x00','\x00'},
+ {'\xf9','\xb1'},{'\x9f','\x75'},{'\x97','\xb0'},{'\x00','\x00'},{'\x83','\xe8'},
+ {'\x00','\x00'},{'\x8f','\x6d'},{'\x85','\xaa'},{'\x8f','\xac'},{'\x85','\xa8'},
+ {'\x8d','\xfb'},{'\x85','\xac'},{'\x85','\xa9'},{'\x85','\xab'},{'\x89','\xb7'},
+ {'\x86','\xa6'},{'\x86','\xa5'},{'\x86','\xa3'},{'\x00','\x00'},{'\x86','\xa4'},
+ {'\x87','\x78'},{'\x8c','\x62'},{'\x87','\x79'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x87','\x76'},{'\x00','\x00'},{'\x87','\x77'},{'\x8e','\xdd'},{'\x00','\x00'},
+ {'\x88','\xb6'},{'\x97','\xb1'},{'\x88','\xb7'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x89','\xb8'},{'\x89','\xb9'},{'\x89','\xb6'},{'\x97','\xb2'},{'\x8b','\x64'},
+ {'\x00','\x00'},{'\x8b','\x63'},{'\x8d','\x78'},{'\x00','\x00'},{'\x97','\xb3'},
+ {'\x00','\x00'},{'\x8b','\x62'},{'\x8f','\xd0'},{'\x8b','\xe1'},{'\x8b','\xe0'},
+ {'\x97','\xb4'},{'\x8f','\xf1'},{'\x97','\xb5'},{'\xad','\xba'},{'\xd8','\x50'},
+ {'\xef','\x55'},{'\xad','\xbb'},{'\x00','\x00'},{'\x9f','\x76'},{'\xe4','\xd2'},
+ {'\xe4','\xd1'},{'\xec','\x60'},{'\x00','\x00'},{'\x00','\x00'},{'\xef','\x57'},
+ {'\x00','\x00'},{'\xef','\x56'},{'\x9f','\x77'},{'\xc3','\x4c'},{'\xf3','\xb2'},
+ {'\xf3','\xb3'},{'\xc4','\xc9'},{'\x00','\x00'},{'\x9f','\x78'},{'\xf9','\xb2'},
+ {'\xb0','\xa8'},{'\xb6','\xbf'},{'\xb6','\xbe'},{'\xe0','\xe4'},{'\xe0','\xe6'},
+ {'\xb9','\xa4'},{'\xe0','\xe5'},{'\xb9','\xa3'},{'\xb9','\xa5'},{'\xe0','\xe7'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x9f','\x79'},{'\xe4','\xd4'},{'\xe4','\xd6'},
+ {'\xe4','\xd5'},{'\x97','\xb6'},{'\xe4','\xd8'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xbb','\xe9'},{'\xe4','\xd7'},{'\xe4','\xd3'},{'\x94','\x4b'},
+ {'\x92','\x4a'},{'\x92','\xa3'},{'\xe4','\xd9'},{'\x97','\xb7'},{'\xe8','\xcc'},
+ {'\x00','\x00'},{'\xe8','\xcf'},{'\xe8','\xd1'},{'\xe8','\xc7'},{'\xe8','\xcb'},
+ {'\xe8','\xc8'},{'\xbe','\x6e'},{'\xbe','\x71'},{'\xbe','\x73'},{'\xe8','\xc9'},
+ {'\xe8','\xca'},{'\xbe','\x72'},{'\xe8','\xcd'},{'\xe8','\xd0'},{'\xe8','\xce'},
+ {'\xbe','\x74'},{'\xfd','\xe4'},{'\xbe','\x70'},{'\xe8','\xc6'},{'\xbe','\x6d'},
+ {'\x00','\x00'},{'\xbe','\x6f'},{'\x9f','\x7a'},{'\x95','\xc4'},{'\xc0','\x63'},
+ {'\xec','\x66'},{'\xec','\x64'},{'\xec','\x63'},{'\x9f','\x7b'},{'\xec','\x69'},
+ {'\x00','\x00'},{'\xec','\x68'},{'\xec','\x67'},{'\x00','\x00'},{'\xec','\x62'},
+ {'\xc0','\x62'},{'\xec','\x61'},{'\x00','\x00'},{'\xec','\x65'},{'\xc0','\x64'},
+ {'\x97','\xb8'},{'\x00','\x00'},{'\xef','\x5a'},{'\x9f','\x7c'},{'\xef','\x5e'},
+ {'\xef','\x5b'},{'\xef','\x5d'},{'\xef','\x5c'},{'\xef','\x59'},{'\xef','\x5f'},
+ {'\xef','\x62'},{'\xef','\x60'},{'\xef','\x61'},{'\xc2','\x40'},{'\x00','\x00'},
+ {'\xc1','\xfe'},{'\xef','\x58'},{'\xef','\x63'},{'\xf1','\xb3'},{'\xf1','\xb6'},
+ {'\xf1','\xb8'},{'\xf1','\xb7'},{'\x00','\x00'},{'\xf1','\xb1'},{'\xf1','\xb5'},
+ {'\xf1','\xb0'},{'\xfb','\xb5'},{'\xf1','\xb2'},{'\xc3','\x4d'},{'\xf1','\xaf'},
+ {'\x95','\xe1'},{'\xf1','\xb4'},{'\x93','\x5d'},{'\x92','\xb9'},{'\xf3','\xc0'},
+ {'\xf3','\xb5'},{'\xc4','\x45'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x46'},
+ {'\xf3','\xb4'},{'\xf3','\xb9'},{'\xf3','\xbf'},{'\xf3','\xb7'},{'\xf3','\xbe'},
+ {'\x9f','\x7d'},{'\xf3','\xbb'},{'\x9a','\xfb'},{'\xf3','\xba'},{'\xf3','\xbd'},
+ {'\xf3','\xb8'},{'\xf3','\xb6'},{'\x9a','\xfc'},{'\xf3','\xbc'},{'\x82','\x55'},
+ {'\xf5','\x60'},{'\xf5','\x5e'},{'\xc4','\xca'},{'\xf5','\x5d'},{'\xf5','\x63'},
+ {'\xf5','\x61'},{'\x9a','\xfd'},{'\xc4','\xcb'},{'\xf5','\x5c'},{'\xf5','\x5a'},
+ {'\x00','\x00'},{'\xf5','\x5b'},{'\xc4','\xcd'},{'\xf5','\x5f'},{'\xc4','\xcc'},
+ {'\xf5','\x62'},{'\xf6','\x78'},{'\xf6','\x7e'},{'\x9c','\xfa'},{'\x9c','\xfb'},
+ {'\xf6','\x79'},{'\xc5','\x5b'},{'\xf6','\xa1'},{'\xc5','\x5a'},{'\xf6','\x7d'},
+ {'\xf6','\x7c'},{'\xc5','\x59'},{'\xf6','\x7b'},{'\xc5','\x58'},{'\xf6','\x7a'},
+ {'\x00','\x00'},{'\xf7','\x7d'},{'\xf7','\xa1'},{'\xf7','\x7e'},{'\x00','\x00'},
+ {'\xf7','\x7b'},{'\xc5','\xbb'},{'\xf7','\x78'},{'\xf7','\x7c'},{'\xf7','\xa3'},
+ {'\x00','\x00'},{'\xf7','\xa2'},{'\xf7','\x79'},{'\xf7','\x7a'},{'\xc5','\xba'},
+ {'\xf8','\x52'},{'\xc5','\xe7'},{'\x9c','\xfc'},{'\xf8','\x53'},{'\xc5','\xe5'},
+ {'\xc5','\xe6'},{'\x9c','\xfd'},{'\x00','\x00'},{'\xf8','\xd3'},{'\xc6','\x4a'},
+ {'\xf9','\x76'},{'\x00','\x00'},{'\xc6','\x6a'},{'\x9c','\xfe'},{'\xf9','\xb3'},
+ {'\xc6','\x6b'},{'\xf9','\xb4'},{'\xf9','\xb5'},{'\xf9','\xc3'},{'\xf9','\xc2'},
+ {'\xc6','\x7a'},{'\xf9','\xcd'},{'\x83','\xe9'},{'\x85','\xae'},{'\x86','\xa8'},
+ {'\x86','\xa9'},{'\x86','\xa7'},{'\x8c','\xbb'},{'\x00','\x00'},{'\x87','\x7a'},
+ {'\x8d','\xa1'},{'\x8e','\xde'},{'\x88','\xbb'},{'\x88','\xba'},{'\x88','\xbf'},
+ {'\x88','\xbe'},{'\x8f','\xf2'},{'\x88','\xb9'},{'\x88','\xb8'},{'\x88','\xbc'},
+ {'\x88','\xbd'},{'\x8d','\x49'},{'\x8e','\xdf'},{'\x8c','\xeb'},{'\x88','\x4c'},
+ {'\x00','\x00'},{'\x8c','\xea'},{'\x90','\x63'},{'\x89','\xbc'},{'\x89','\xba'},
+ {'\x89','\xbb'},{'\x00','\x00'},{'\x8d','\xaf'},{'\x8a','\xb3'},{'\x8d','\x4a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xb4'},{'\x8f','\xad'},{'\x8b','\x65'},
+ {'\x8f','\xae'},{'\x8f','\xaf'},{'\x00','\x00'},{'\x00','\x00'},{'\x90','\x4c'},
+ {'\x8b','\xe3'},{'\x8f','\xf5'},{'\x00','\x00'},{'\x8c','\x66'},{'\x8b','\xe2'},
+ {'\x90','\x4d'},{'\x8f','\xf3'},{'\x8c','\x64'},{'\x8f','\xf4'},{'\x8c','\xbc'},
+ {'\x8c','\xbe'},{'\x90','\x4b'},{'\x90','\x62'},{'\x8d','\x62'},{'\x8d','\xa2'},
+ {'\x00','\x00'},{'\x90','\xa9'},{'\xb0','\xa9'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe0','\xe9'},{'\x00','\x00'},{'\xe0','\xe8'},{'\x00','\x00'},{'\xbb','\xea'},
+ {'\xbb','\xeb'},{'\xe4','\xda'},{'\x9d','\xb0'},{'\xe8','\xd2'},{'\xec','\x6c'},
+ {'\x00','\x00'},{'\x97','\xb9'},{'\xbe','\x75'},{'\xc0','\x65'},{'\xec','\x6a'},
+ {'\xfd','\xe6'},{'\xec','\x6d'},{'\xc0','\x66'},{'\xfd','\xe7'},{'\xef','\x64'},
+ {'\xec','\x6b'},{'\xf1','\xb9'},{'\xc3','\x4e'},{'\xf3','\xc1'},{'\x00','\x00'},
+ {'\x92','\xfb'},{'\x8c','\xbf'},{'\xf5','\x66'},{'\xf5','\x64'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xf5','\x65'},{'\x8d','\x79'},{'\x90','\x79'},{'\xf6','\xa2'},
+ {'\x00','\x00'},{'\xc5','\x5c'},{'\xf7','\xa4'},{'\xc5','\xea'},{'\xc5','\xbc'},
+ {'\xc5','\xe8'},{'\xc5','\xe9'},{'\xf8','\xd4'},{'\xc6','\x62'},{'\xfb','\xb6'},
+ {'\xb0','\xaa'},{'\x97','\xba'},{'\x00','\x00'},{'\x00','\x00'},{'\xf1','\xba'},
+ {'\x00','\x00'},{'\x97','\xbb'},{'\xd4','\x49'},{'\x9d','\xb1'},{'\xb9','\xa6'},
+ {'\xfd','\xec'},{'\xe4','\xdb'},{'\x00','\x00'},{'\x00','\x00'},{'\xbb','\xec'},
+ {'\xe4','\xdc'},{'\x00','\x00'},{'\x00','\x00'},{'\x93','\xba'},{'\xe8','\xd4'},
+ {'\xe8','\xd3'},{'\xc0','\x68'},{'\xbe','\x76'},{'\xbe','\x77'},{'\x00','\x00'},
+ {'\xe8','\xd7'},{'\xe8','\xd6'},{'\xe8','\xd5'},{'\xfe','\x57'},{'\x00','\x00'},
+ {'\xec','\x6e'},{'\xec','\x71'},{'\x00','\x00'},{'\xec','\x70'},{'\xec','\x6f'},
+ {'\xc0','\x67'},{'\xef','\x68'},{'\xef','\x66'},{'\xef','\x65'},{'\xfd','\xee'},
+ {'\x00','\x00'},{'\xef','\x67'},{'\xfd','\xed'},{'\xc3','\x4f'},{'\xf1','\xbc'},
+ {'\xf1','\xbd'},{'\xc3','\x50'},{'\x00','\x00'},{'\xf1','\xbb'},{'\xfd','\xf0'},
+ {'\xf3','\xc3'},{'\xf3','\xc2'},{'\xf3','\xc5'},{'\xc4','\x47'},{'\xf3','\xc4'},
+ {'\x97','\xbc'},{'\xf5','\x67'},{'\xf5','\x69'},{'\xf5','\x68'},{'\x8d','\x63'},
+ {'\x9d','\xb2'},{'\xf6','\xa3'},{'\xf6','\xa6'},{'\xf6','\xa4'},{'\xf6','\xa5'},
+ {'\xf7','\xa5'},{'\xc5','\xbd'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf8','\x54'},{'\xf8','\x55'},{'\xf8','\x56'},{'\x00','\x00'},{'\xc6','\x4b'},
+ {'\xc6','\x63'},{'\xf9','\xb6'},{'\xb0','\xab'},{'\x00','\x00'},{'\xbe','\x78'},
+ {'\xc0','\x69'},{'\xf1','\xbe'},{'\xfd','\xe9'},{'\xf7','\xa6'},{'\x00','\x00'},
+ {'\xfd','\xeb'},{'\xf9','\xc4'},{'\xd4','\x4a'},{'\x00','\x00'},{'\xc6','\x7b'},
+ {'\xb0','\xac'},{'\xec','\x72'},{'\x9d','\xb3'},{'\xf1','\xbf'},{'\x00','\x00'},
+ {'\xf3','\xc6'},{'\x00','\x00'},{'\x9d','\xb4'},{'\xf6','\xa7'},{'\xf7','\xa7'},
+ {'\xb0','\xad'},{'\x00','\x00'},{'\xe4','\xdd'},{'\xe4','\xde'},{'\x9d','\xb5'},
+ {'\xbb','\xed'},{'\xbb','\xee'},{'\xe8','\xd9'},{'\xbe','\x7a'},{'\xbe','\x79'},
+ {'\xe8','\xd8'},{'\x8d','\x64'},{'\xef','\x69'},{'\x97','\xbd'},{'\xf1','\xc0'},
+ {'\xf1','\xc2'},{'\xf1','\xc1'},{'\xc3','\x53'},{'\xc3','\x52'},{'\xc3','\x51'},
+ {'\x9d','\xb6'},{'\xc5','\x5e'},{'\xf6','\xa8'},{'\x00','\x00'},{'\xc5','\x5d'},
+ {'\xf7','\xa9'},{'\xf7','\xa8'},{'\x00','\x00'},{'\xc6','\x4c'},{'\xf8','\xd5'},
+ {'\xb3','\xbd'},{'\xe0','\xea'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe4','\xe1'},{'\xe4','\xdf'},{'\xe4','\xe0'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xe8','\xe2'},{'\x00','\x00'},{'\xe8','\xdd'},{'\xe8','\xda'},{'\xe8','\xe1'},
+ {'\xfe','\xaf'},{'\x00','\x00'},{'\x00','\x00'},{'\xe8','\xe3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xbe','\x7c'},{'\xe8','\xe0'},{'\xe8','\xdc'},{'\x97','\xbe'},
+ {'\x00','\x00'},{'\xe8','\xdb'},{'\xe8','\xdf'},{'\xe8','\xde'},{'\xbe','\x7b'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xec','\x7d'},{'\xec','\x78'},{'\xec','\x76'},
+ {'\xec','\xa1'},{'\xec','\x77'},{'\x9d','\xb7'},{'\xec','\x73'},{'\x9d','\xee'},
+ {'\xec','\x79'},{'\x97','\xbf'},{'\x00','\x00'},{'\xec','\x74'},{'\xef','\x72'},
+ {'\xec','\x75'},{'\xec','\xa2'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xef'},
+ {'\x00','\x00'},{'\x9d','\xf0'},{'\x94','\xfe'},{'\xfd','\xf3'},{'\xec','\x7c'},
+ {'\xc0','\x6a'},{'\xec','\x7b'},{'\xec','\x7a'},{'\x00','\x00'},{'\xec','\x7e'},
+ {'\x94','\xe3'},{'\x94','\xe4'},{'\x00','\x00'},{'\x00','\x00'},{'\xef','\x6a'},
+ {'\xef','\x6d'},{'\x00','\x00'},{'\xfd','\xf4'},{'\xef','\x6c'},{'\x97','\xc0'},
+ {'\xef','\x74'},{'\xef','\x6f'},{'\xef','\x73'},{'\x00','\x00'},{'\xef','\x71'},
+ {'\xef','\x70'},{'\xef','\x6e'},{'\x00','\x00'},{'\xef','\x6b'},{'\x00','\x00'},
+ {'\xc2','\x43'},{'\xc2','\x42'},{'\x00','\x00'},{'\xc2','\x44'},{'\xc2','\x41'},
+ {'\xef','\x75'},{'\xfd','\xf5'},{'\x94','\xf5'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x94','\xe5'},{'\xf1','\xc8'},{'\xf1','\xcb'},{'\x00','\x00'},{'\xf1','\xc9'},
+ {'\xf1','\xcd'},{'\x00','\x00'},{'\x97','\xc1'},{'\x00','\x00'},{'\xf1','\xce'},
+ {'\x00','\x00'},{'\xf1','\xc6'},{'\xc3','\x58'},{'\xf1','\xc7'},{'\x00','\x00'},
+ {'\xf1','\xc5'},{'\xf1','\xcc'},{'\x00','\x00'},{'\xf1','\xc4'},{'\xf1','\xc3'},
+ {'\xc3','\x57'},{'\xc3','\x55'},{'\xc3','\x54'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x94','\xe6'},{'\x00','\x00'},{'\x94','\xe7'},
+ {'\x94','\xe8'},{'\xf1','\xca'},{'\xf3','\xcf'},{'\xf3','\xd5'},{'\xc4','\x4a'},
+ {'\xf3','\xd0'},{'\x00','\x00'},{'\xf3','\xd3'},{'\xf3','\xd7'},{'\xc4','\x4b'},
+ {'\xf3','\xd2'},{'\x9d','\xf1'},{'\xf3','\xca'},{'\x00','\x00'},{'\xf3','\xc9'},
+ {'\xf3','\xd6'},{'\xf3','\xcd'},{'\x97','\xc2'},{'\xf3','\xcb'},{'\xf3','\xd4'},
+ {'\xf3','\xcc'},{'\xc4','\x49'},{'\xc4','\x48'},{'\x9d','\xf2'},{'\xf3','\xc7'},
+ {'\xf3','\xc8'},{'\xf3','\xd1'},{'\x9d','\xf3'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf3','\xce'},{'\x94','\xea'},{'\x94','\xe9'},{'\x00','\x00'},{'\x9d','\xf4'},
+ {'\x97','\xc3'},{'\x00','\x00'},{'\xf5','\x6c'},{'\xf5','\x6f'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xc3','\x56'},{'\x00','\x00'},
+ {'\xfd','\xf9'},{'\x97','\xc4'},{'\x00','\x00'},{'\xfe','\x50'},{'\x00','\x00'},
+ {'\x97','\xc5'},{'\xf5','\x6d'},{'\xf5','\x73'},{'\xf5','\x71'},{'\xf5','\x6b'},
+ {'\xf5','\x76'},{'\xfd','\xf8'},{'\xf5','\x6a'},{'\xfd','\xf6'},{'\xc4','\xcf'},
+ {'\xf5','\x72'},{'\x00','\x00'},{'\x95','\xfd'},{'\x00','\x00'},{'\xf5','\x6e'},
+ {'\xc4','\xce'},{'\xf5','\x75'},{'\xfd','\xf7'},{'\x00','\x00'},{'\xf5','\x74'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x97','\xc6'},{'\xf6','\xab'},
+ {'\xf6','\xaa'},{'\x00','\x00'},{'\x9d','\xf5'},{'\x9d','\xf6'},{'\xf6','\xb1'},
+ {'\x00','\x00'},{'\xf6','\xad'},{'\xf6','\xb0'},{'\xc5','\x60'},{'\x9d','\xf7'},
+ {'\x00','\x00'},{'\xf6','\xae'},{'\xf6','\xaf'},{'\x00','\x00'},{'\xf6','\xa9'},
+ {'\xf6','\xac'},{'\xc5','\x5f'},{'\xfd','\xfa'},{'\x94','\xf9'},{'\x94','\xeb'},
+ {'\xc5','\xbf'},{'\xf7','\xb4'},{'\xf7','\xaf'},{'\xf7','\xb3'},{'\xfd','\x53'},
+ {'\xf7','\xb6'},{'\xf7','\xb2'},{'\x00','\x00'},{'\xf7','\xae'},{'\xfc','\xcb'},
+ {'\xc5','\xc1'},{'\xf7','\xb1'},{'\xf7','\xb5'},{'\xc5','\xc0'},{'\xf7','\xac'},
+ {'\xf5','\x70'},{'\xf7','\xb0'},{'\x00','\x00'},{'\x00','\x00'},{'\xf7','\xad'},
+ {'\xfd','\x70'},{'\xf7','\xaa'},{'\x94','\xec'},{'\xf7','\xab'},{'\xc5','\xbe'},
+ {'\xf8','\x5a'},{'\xf8','\x5c'},{'\xf8','\x5f'},{'\xf8','\x5b'},{'\xf8','\x60'},
+ {'\x9f','\x50'},{'\xf8','\x59'},{'\x00','\x00'},{'\xf8','\x57'},{'\x9d','\xf8'},
+ {'\xc5','\xeb'},{'\xf8','\x5d'},{'\xc5','\xed'},{'\xc5','\xec'},{'\xf8','\x58'},
+ {'\xf8','\x5e'},{'\x94','\xed'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xf9'},
+ {'\xf8','\xda'},{'\xc6','\x4d'},{'\xf8','\xdb'},{'\x00','\x00'},{'\xf8','\xd9'},
+ {'\xf8','\xd6'},{'\x00','\x00'},{'\x00','\x00'},{'\xf8','\xd8'},{'\xf8','\xd7'},
+ {'\xf9','\x5a'},{'\x94','\xf6'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf9','\x5c'},{'\xf9','\x5b'},{'\x00','\x00'},{'\x00','\x00'},{'\xf9','\x79'},
+ {'\xfb','\x78'},{'\xf9','\x78'},{'\xf9','\x77'},{'\xf9','\x7a'},{'\x98','\x40'},
+ {'\xc6','\x73'},{'\xc6','\x74'},{'\xf9','\xca'},{'\xf9','\xce'},{'\x9d','\xfa'},
+ {'\x84','\xbe'},{'\x00','\x00'},{'\x00','\x00'},{'\x88','\xc2'},{'\x00','\x00'},
+ {'\x88','\xc3'},{'\x8e','\xe0'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\x4b'},
+ {'\x98','\x4c'},{'\x98','\x4d'},{'\x8d','\xab'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x98','\x4e'},{'\x00','\x00'},{'\x89','\xbf'},{'\x8d','\x65'},{'\x00','\x00'},
+ {'\x98','\x4f'},{'\x8a','\xb8'},{'\x8f','\x6e'},{'\x00','\x00'},{'\x8a','\xb7'},
+ {'\x8f','\x6f'},{'\x00','\x00'},{'\x90','\xf2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x90','\xa2'},{'\x8a','\xb6'},{'\x8a','\xb5'},{'\x00','\x00'},{'\x98','\x50'},
+ {'\x90','\x70'},{'\x8f','\xb2'},{'\x90','\xad'},{'\x8c','\xed'},{'\x90','\x65'},
+ {'\x8b','\x68'},{'\x90','\x4e'},{'\x90','\x66'},{'\x8b','\x6a'},{'\x8b','\x67'},
+ {'\x8f','\xb1'},{'\x00','\x00'},{'\x8b','\x69'},{'\x00','\x00'},{'\x8b','\xe6'},
+ {'\x98','\x51'},{'\x00','\x00'},{'\x98','\x52'},{'\x8f','\xd5'},{'\x98','\x53'},
+ {'\x8b','\xe5'},{'\x98','\x54'},{'\x8f','\xd2'},{'\x8f','\xd3'},{'\x8b','\xe7'},
+ {'\x8b','\xe4'},{'\x00','\x00'},{'\x98','\x55'},{'\x8f','\xd4'},{'\x98','\x56'},
+ {'\x98','\x57'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8c','\x67'},{'\x8d','\xaa'},{'\x8c','\x68'},{'\x98','\x58'},
+ {'\x98','\x59'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\x5a'},{'\x98','\x5b'},
+ {'\x8d','\x6a'},{'\x8c','\xc0'},{'\x90','\x4f'},{'\x8c','\xc1'},{'\x90','\x50'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x98','\x5c'},{'\x8c','\xee'},{'\x90','\x64'},
+ {'\x8c','\xec'},{'\x8c','\xef'},{'\x98','\x5d'},{'\x98','\x5e'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x8d','\x4f'},{'\x8d','\x4d'},{'\x8d','\x4e'},{'\x90','\x6f'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x98','\x5f'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xb3','\xbe'},{'\xdc','\xaf'},{'\xe0','\xed'},{'\x00','\x00'},{'\xb9','\xa7'},
+ {'\xe0','\xeb'},{'\x98','\x60'},{'\x98','\x61'},{'\xe0','\xec'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x94','\xee'},{'\xe4','\xe2'},{'\xe4','\xe3'},{'\xbb','\xf1'},
+ {'\xbb','\xef'},{'\xe4','\xe4'},{'\xbb','\xf0'},{'\xe8','\xe8'},{'\x00','\x00'},
+ {'\xe8','\xeb'},{'\xe8','\xe5'},{'\xe8','\xec'},{'\xe8','\xe4'},{'\xe8','\xe6'},
+ {'\x00','\x00'},{'\xe8','\xe7'},{'\xe8','\xea'},{'\x00','\x00'},{'\xfd','\x61'},
+ {'\xbe','\xa1'},{'\xe8','\xef'},{'\xe8','\xee'},{'\xbe','\x7d'},{'\xe8','\xe9'},
+ {'\xe8','\xed'},{'\xbe','\x7e'},{'\x00','\x00'},{'\x00','\x00'},{'\x9d','\xfb'},
+ {'\x00','\x00'},{'\x82','\x48'},{'\x00','\x00'},{'\xec','\xac'},{'\x00','\x00'},
+ {'\xc0','\x6f'},{'\x00','\x00'},{'\xec','\xa7'},{'\xc0','\x6b'},{'\x9d','\xfc'},
+ {'\xec','\xa4'},{'\xec','\xaa'},{'\xec','\xad'},{'\x00','\x00'},{'\xc0','\x70'},
+ {'\x00','\x00'},{'\xec','\xa9'},{'\xec','\xa6'},{'\xec','\xae'},{'\xec','\xa5'},
+ {'\x9f','\x40'},{'\xec','\xab'},{'\xc0','\x6c'},{'\x00','\x00'},{'\xec','\xa3'},
+ {'\xc0','\x6d'},{'\x00','\x00'},{'\xc0','\x6e'},{'\xec','\xa8'},{'\x98','\x62'},
+ {'\x94','\x47'},{'\x82','\x47'},{'\xef','\xa9'},{'\xef','\x7a'},{'\xef','\x7b'},
+ {'\xef','\x7e'},{'\xef','\x7c'},{'\x00','\x00'},{'\xef','\x76'},{'\x9f','\x41'},
+ {'\x00','\x00'},{'\xef','\x79'},{'\xef','\xa5'},{'\xef','\x7d'},{'\x9f','\x42'},
+ {'\x00','\x00'},{'\xc2','\x45'},{'\x00','\x00'},{'\xef','\xa7'},{'\xef','\xa4'},
+ {'\xc2','\x46'},{'\xef','\xa6'},{'\xef','\x77'},{'\xef','\xa2'},{'\xef','\xa3'},
+ {'\xfd','\xaa'},{'\xef','\xa1'},{'\x94','\xef'},{'\x94','\xf7'},{'\x98','\x63'},
+ {'\x9f','\x43'},{'\xf1','\xd2'},{'\xf1','\xd4'},{'\xf1','\xd7'},{'\x00','\x00'},
+ {'\x9f','\x44'},{'\xf1','\xd1'},{'\x98','\x64'},{'\xc3','\x59'},{'\xf1','\xd9'},
+ {'\xf1','\xd0'},{'\xf1','\xda'},{'\x00','\x00'},{'\xf1','\xd6'},{'\xf1','\xd8'},
+ {'\xf1','\xdc'},{'\xf1','\xd5'},{'\xf1','\xdd'},{'\xf1','\xd3'},{'\xf1','\xcf'},
+ {'\xc3','\x5a'},{'\x95','\x72'},{'\xf1','\xdb'},{'\xc3','\x5b'},{'\xc4','\x4d'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x94','\xf0'},{'\x94','\xf8'},{'\x00','\x00'},
+ {'\xef','\x78'},{'\xf3','\xf1'},{'\xf3','\xe8'},{'\xc4','\x4f'},{'\xf3','\xe4'},
+ {'\xc4','\x50'},{'\x9f','\x45'},{'\x9f','\x47'},{'\xf3','\xed'},{'\xf3','\xe7'},
+ {'\xf3','\xdd'},{'\xc4','\x4e'},{'\xf3','\xea'},{'\xf3','\xe5'},{'\xf3','\xe6'},
+ {'\x00','\x00'},{'\xf3','\xd8'},{'\xf3','\xdf'},{'\xf3','\xee'},{'\x98','\x65'},
+ {'\xf3','\xeb'},{'\x9f','\x48'},{'\xf3','\xe3'},{'\xfc','\xc6'},{'\xf3','\xef'},
+ {'\xf3','\xde'},{'\xf3','\xd9'},{'\xf3','\xec'},{'\x9f','\x49'},{'\xf3','\xdb'},
+ {'\xf3','\xe9'},{'\xf3','\xe0'},{'\xf3','\xf0'},{'\xf3','\xdc'},{'\xc4','\x4c'},
+ {'\xf3','\xda'},{'\xf3','\xe1'},{'\xf3','\xe2'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x92','\xaf'},{'\xf5','\x7d'},{'\x00','\x00'},{'\xf5','\x7b'},{'\x9f','\x4a'},
+ {'\xf5','\xa2'},{'\x00','\x00'},{'\xf5','\xae'},{'\xf5','\xa5'},{'\xf5','\x7c'},
+ {'\xf5','\x78'},{'\xf5','\xa7'},{'\xf5','\x7e'},{'\xf5','\xa3'},{'\xf5','\x7a'},
+ {'\xf5','\xaa'},{'\xf5','\x77'},{'\xf5','\xa1'},{'\xf5','\xa6'},{'\xf5','\xa8'},
+ {'\xf5','\xab'},{'\xf5','\x79'},{'\x9f','\x4b'},{'\xf5','\xaf'},{'\xf5','\xb0'},
+ {'\xf5','\xa9'},{'\xf5','\xad'},{'\xf5','\xa4'},{'\x94','\xf1'},{'\xf6','\xc1'},
+ {'\xf6','\xc4'},{'\x00','\x00'},{'\xc5','\x61'},{'\x00','\x00'},{'\xf6','\xc3'},
+ {'\xf6','\xc8'},{'\xf6','\xc6'},{'\xc5','\x62'},{'\xf6','\xbd'},{'\xf6','\xb3'},
+ {'\xf6','\xb2'},{'\xc5','\x64'},{'\xf6','\xbf'},{'\xf6','\xc0'},{'\xf6','\xbc'},
+ {'\xf6','\xb4'},{'\x9f','\x4d'},{'\xf6','\xb9'},{'\xf5','\xac'},{'\x9f','\x52'},
+ {'\xf6','\xb5'},{'\xc5','\x63'},{'\xf6','\xbb'},{'\x95','\x75'},{'\xf6','\xba'},
+ {'\x98','\x66'},{'\xf6','\xb6'},{'\xf6','\xc2'},{'\x9f','\x5e'},{'\xf6','\xb7'},
+ {'\xf7','\xbb'},{'\xf6','\xc5'},{'\xf6','\xc7'},{'\xf6','\xbe'},{'\xf6','\xb8'},
+ {'\xf7','\xbc'},{'\xf7','\xbe'},{'\xf7','\xb8'},{'\xc5','\xc2'},{'\x9f','\x5f'},
+ {'\xf7','\xc5'},{'\xf7','\xc3'},{'\xc5','\xc3'},{'\xf7','\xc2'},{'\xf7','\xc1'},
+ {'\xf7','\xba'},{'\xf7','\xb7'},{'\xf7','\xbd'},{'\xf7','\xc6'},{'\xf7','\xb9'},
+ {'\xf7','\xbf'},{'\x00','\x00'},{'\xf8','\x69'},{'\xf8','\x6e'},{'\xf8','\x64'},
+ {'\xf8','\x67'},{'\xc5','\xee'},{'\xf8','\x6b'},{'\x00','\x00'},{'\xf8','\x72'},
+ {'\xf7','\xc0'},{'\x00','\x00'},{'\xf8','\x65'},{'\xf8','\x6f'},{'\xf8','\x73'},
+ {'\xf8','\x6a'},{'\xf8','\x63'},{'\xf8','\x6d'},{'\x00','\x00'},{'\xf8','\x6c'},
+ {'\xf8','\x71'},{'\xf8','\x70'},{'\xf7','\xc4'},{'\xf8','\x68'},{'\xf8','\x62'},
+ {'\xf8','\x66'},{'\xc6','\x4e'},{'\xc6','\x4f'},{'\xf8','\x61'},{'\x9f','\x60'},
+ {'\xf8','\xe6'},{'\xf8','\xdd'},{'\xf8','\xe5'},{'\xf8','\xe2'},{'\xf8','\xe3'},
+ {'\xf8','\xdc'},{'\xf8','\xdf'},{'\xf8','\xe7'},{'\xf8','\xe1'},{'\xf8','\xe0'},
+ {'\xf8','\xde'},{'\x00','\x00'},{'\xf8','\xe4'},{'\x9f','\x61'},{'\xf9','\x5d'},
+ {'\x9f','\x62'},{'\xf9','\x5e'},{'\x9f','\x63'},{'\xf9','\x60'},{'\xf9','\x5f'},
+ {'\xf9','\x62'},{'\xf9','\x61'},{'\xf9','\x7c'},{'\xf9','\x7b'},{'\xf9','\xb7'},
+ {'\x00','\x00'},{'\xf9','\xb8'},{'\x9f','\x64'},{'\xf9','\xc5'},{'\xc6','\x78'},
+ {'\xc6','\x7c'},{'\xfd','\x4a'},{'\xf9','\xcf'},{'\xc6','\x7d'},{'\x84','\xbf'},
+ {'\x86','\xaa'},{'\x8b','\x5c'},{'\x87','\x7e'},{'\x87','\x7d'},{'\x00','\x00'},
+ {'\x8c','\xf1'},{'\x88','\xc5'},{'\x00','\x00'},{'\x8e','\xe1'},{'\x88','\xc4'},
+ {'\x89','\xc1'},{'\x8f','\xd7'},{'\x90','\xaa'},{'\x89','\xc3'},{'\x00','\x00'},
+ {'\x89','\xc2'},{'\x00','\x00'},{'\x8f','\x4e'},{'\x8f','\x4d'},{'\x89','\xc4'},
+ {'\x00','\x00'},{'\x89','\xc0'},{'\x8d','\x50'},{'\x90','\x68'},{'\x8f','\x70'},
+ {'\x8f','\x71'},{'\x8f','\x72'},{'\x00','\x00'},{'\x00','\x00'},{'\x8a','\xba'},
+ {'\x8d','\xb1'},{'\x8a','\xb9'},{'\x00','\x00'},{'\x8f','\xb4'},{'\x90','\xae'},
+ {'\x8b','\x6b'},{'\x8b','\x6d'},{'\x8b','\x6c'},{'\x8f','\xb5'},{'\x90','\x75'},
+ {'\x8f','\xb3'},{'\x8b','\xe9'},{'\x8b','\xea'},{'\x98','\x67'},{'\x8b','\xeb'},
+ {'\x00','\x00'},{'\x8f','\xd6'},{'\x8b','\xec'},{'\x00','\x00'},{'\x8b','\xe8'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x98','\x68'},{'\x00','\x00'},
+ {'\x8f','\xf6'},{'\x90','\x52'},{'\x00','\x00'},{'\x8f','\xf7'},{'\x98','\x69'},
+ {'\x8f','\xf8'},{'\x00','\x00'},{'\x8c','\xc4'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x90','\x51'},{'\x8c','\xc3'},{'\x00','\x00'},
+ {'\x8d','\xae'},{'\x8c','\xf0'},{'\x90','\x67'},{'\x90','\x71'},{'\x90','\x73'},
+ {'\x90','\x74'},{'\x90','\x72'},{'\x8d','\x67'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8d','\x66'},{'\x98','\x6a'},{'\x00','\x00'},{'\x8d','\xb0'},{'\x00','\x00'},
+ {'\xb3','\xbf'},{'\x00','\x00'},{'\x00','\x00'},{'\x82','\x5e'},{'\xc4','\xd0'},
+ {'\xf6','\xc9'},{'\x9f','\x65'},{'\xc6','\x50'},{'\xc6','\x51'},{'\x90','\x53'},
+ {'\xb3','\xc0'},{'\xe0','\xee'},{'\xfc','\xfd'},{'\xb9','\xa8'},{'\xe8','\xf0'},
+ {'\xfb','\x5e'},{'\x9f','\x66'},{'\xec','\xb0'},{'\xec','\xb1'},{'\xec','\xaf'},
+ {'\xef','\xab'},{'\xef','\xaa'},{'\xc2','\x47'},{'\xf1','\xdf'},{'\xef','\xac'},
+ {'\xf1','\xde'},{'\x00','\x00'},{'\x9f','\x51'},{'\xf3','\xf3'},{'\xc4','\x51'},
+ {'\xc4','\x53'},{'\xf3','\xf2'},{'\xfc','\xf4'},{'\xfb','\x7c'},{'\xc4','\x52'},
+ {'\xfb','\xb7'},{'\xf5','\xb1'},{'\xf5','\xb3'},{'\xf5','\xb2'},{'\xf6','\xca'},
+ {'\xc5','\x65'},{'\xfd','\x48'},{'\xc5','\xef'},{'\xf8','\xe8'},{'\xf9','\x63'},
+ {'\x9f','\x67'},{'\x00','\x00'},{'\xf9','\xd2'},{'\xb3','\xc1'},{'\x84','\xc1'},
+ {'\xe4','\xe5'},{'\xfd','\xb4'},{'\xbe','\xa2'},{'\x98','\x6b'},{'\xfb','\xa2'},
+ {'\x9f','\x68'},{'\xec','\xb3'},{'\xec','\xb2'},{'\x95','\x73'},{'\xef','\xad'},
+ {'\x9f','\x69'},{'\x00','\x00'},{'\x00','\x00'},{'\xc4','\x54'},{'\xc4','\xd1'},
+ {'\xf7','\xc7'},{'\xf9','\xcb'},{'\x88','\xc6'},{'\x82','\x60'},{'\x82','\x61'},
+ {'\xb3','\xc2'},{'\xbb','\xf2'},{'\x98','\x6c'},{'\xbe','\xa3'},{'\x94','\xfa'},
+ {'\xf3','\xf4'},{'\x9f','\x6a'},{'\xf8','\x74'},{'\xb6','\xc0'},{'\x98','\x6d'},
+ {'\x00','\x00'},{'\x9f','\x6b'},{'\x9f','\x6c'},{'\xef','\xae'},{'\x8d','\x7a'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc6','\x64'},{'\xb6','\xc1'},{'\xbe','\xa4'},
+ {'\xc2','\x48'},{'\xf8','\x75'},{'\xb6','\xc2'},{'\x92','\xc3'},{'\xe8','\xf1'},
+ {'\xc0','\x72'},{'\xec','\xb4'},{'\xec','\xb5'},{'\x00','\x00'},{'\xc0','\x71'},
+ {'\x93','\xd4'},{'\xef','\xaf'},{'\xc2','\x4c'},{'\xc2','\x4a'},{'\xc2','\x4b'},
+ {'\xc2','\x49'},{'\xf1','\xe0'},{'\xc3','\x5c'},{'\x00','\x00'},{'\x98','\x6e'},
+ {'\x00','\x00'},{'\xf5','\xb5'},{'\xf5','\xb4'},{'\xf5','\xb7'},{'\xf5','\xb6'},
+ {'\xc4','\xd2'},{'\x8d','\xac'},{'\x98','\x6f'},{'\xf6','\xcb'},{'\x00','\x00'},
+ {'\xf6','\xcd'},{'\xf6','\xcc'},{'\xc5','\x66'},{'\xf7','\xc8'},{'\x9f','\x6d'},
+ {'\xf8','\x76'},{'\xf8','\x77'},{'\xc5','\xf0'},{'\xf9','\x64'},{'\xf9','\x7d'},
+ {'\xc6','\x75'},{'\x9f','\x6e'},{'\xdc','\xb0'},{'\xec','\xb6'},{'\xef','\xb0'},
+ {'\xf3','\xf5'},{'\xe0','\xef'},{'\x8e','\x64'},{'\xef','\xb1'},{'\xf1','\xe2'},
+ {'\xf1','\xe1'},{'\xfd','\xe8'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf8','\x78'},{'\xc6','\x52'},{'\x98','\x70'},{'\xf9','\x65'},{'\xf9','\x7e'},
+ {'\x98','\x71'},{'\x00','\x00'},{'\x98','\x72'},{'\xb9','\xa9'},{'\xe8','\xf2'},
+ {'\xe8','\xf3'},{'\x00','\x00'},{'\xec','\xb7'},{'\xb9','\xaa'},{'\x00','\x00'},
+ {'\xc3','\x5d'},{'\xf1','\xe3'},{'\xfc','\xdb'},{'\xf6','\xcf'},{'\xc5','\x67'},
+ {'\xf6','\xd0'},{'\xf6','\xce'},{'\xf8','\x79'},{'\x00','\x00'},{'\xf8','\xe9'},
+ {'\x00','\x00'},{'\xb9','\xab'},{'\x98','\x73'},{'\xef','\xb4'},{'\xef','\xb3'},
+ {'\xef','\xb2'},{'\xf1','\xe4'},{'\xfb','\xb8'},{'\x9f','\x6f'},{'\xf1','\xe8'},
+ {'\xf1','\xe7'},{'\xf1','\xe6'},{'\xf1','\xe5'},{'\xc3','\x5e'},{'\xf3','\xf6'},
+ {'\xf5','\xb9'},{'\xc4','\xd3'},{'\xf5','\xb8'},{'\xf6','\xd1'},{'\xf7','\xcb'},
+ {'\xf7','\xca'},{'\xc5','\xc4'},{'\xf7','\xc9'},{'\xf8','\x7c'},{'\xf8','\x7b'},
+ {'\xf8','\x7a'},{'\x8c','\xf2'},{'\x00','\x00'},{'\xbb','\xf3'},{'\x00','\x00'},
+ {'\xec','\xb8'},{'\xc2','\x4d'},{'\x00','\x00'},{'\xf3','\xf7'},{'\xf3','\xf8'},
+ {'\xf7','\xcc'},{'\xf8','\x7d'},{'\x98','\x74'},{'\xfd','\xe2'},{'\xf8','\xea'},
+ {'\xf9','\x66'},{'\xf9','\xb9'},{'\xf9','\xd4'},{'\xbb','\xf4'},{'\xc2','\x4e'},
+ {'\xf1','\xe9'},{'\xf3','\xf9'},{'\xf6','\xd2'},{'\xf8','\x7e'},{'\x87','\xa2'},
+ {'\x98','\x75'},{'\xbe','\xa6'},{'\xfd','\xe0'},{'\xef','\xb5'},{'\xf1','\xea'},
+ {'\xf3','\xfa'},{'\xf3','\xfb'},{'\xf3','\xfc'},{'\xf5','\xbe'},{'\xfd','\xda'},
+ {'\xf5','\xba'},{'\xc5','\x68'},{'\xf5','\xbd'},{'\xf5','\xbc'},{'\xc4','\xd4'},
+ {'\xf5','\xbb'},{'\xc4','\xd6'},{'\x93','\xee'},{'\xc4','\xd5'},{'\xf6','\xd4'},
+ {'\xf6','\xd3'},{'\xc5','\x69'},{'\xc5','\x6a'},{'\x00','\x00'},{'\xfd','\x62'},
+ {'\xc5','\xc6'},{'\xf7','\xcd'},{'\xc5','\xc5'},{'\x00','\x00'},{'\xf8','\xa3'},
+ {'\xf8','\xa4'},{'\xf8','\xa2'},{'\xf8','\xa1'},{'\xc6','\x54'},{'\x00','\x00'},
+ {'\xf8','\xeb'},{'\xf8','\xec'},{'\xf8','\xed'},{'\xc6','\x53'},{'\xf9','\x67'},
+ {'\xf9','\x6a'},{'\xf9','\x69'},{'\xf9','\x68'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xf9','\xd3'},{'\x88','\xc7'},{'\x8f','\x73'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x8c','\x6a'},{'\x8c','\x6b'},{'\x8f','\xfa'},{'\x8f','\xf9'},{'\x8c','\xc5'},
+ {'\x8c','\xc6'},{'\x8c','\xf3'},{'\x8c','\xf4'},{'\x8d','\x6c'},{'\x8d','\x6b'},
+ {'\xc0','\x73'},{'\xfb','\xd8'},{'\x00','\x00'},{'\xc3','\x65'},{'\xf5','\xbf'},
+ {'\xf6','\xd5'},{'\x00','\x00'},{'\xc5','\xc7'},{'\xf7','\xce'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xf9','\xd5'},{'\x89','\xc5'},{'\x8c','\xf5'},{'\x90','\x69'},
+ {'\xc0','\x74'},{'\x98','\x76'},{'\x00','\x00'},{'\x89','\xc6'},{'\xef','\xb6'},
+ {'\x00','\x00'},{'\xf7','\xcf'},{'\x00','\x00'},{'\xf9','\xa1'},{'\xfd','\xd4'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\xc8','\xa1'},{'\xc8','\xa3'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xfa','\x40'},
+ {'\xfa','\x41'},{'\xfa','\x42'},{'\xfa','\x43'},{'\xfa','\x44'},{'\xfa','\x45'},
+ {'\xfa','\x46'},{'\xfa','\x47'},{'\xfa','\x48'},{'\xfa','\x49'},{'\xfa','\x4a'},
+ {'\xfa','\x4b'},{'\xfa','\x4c'},{'\xfa','\x4d'},{'\xfa','\x4e'},{'\xfa','\x4f'},
+ {'\xfa','\x50'},{'\xfa','\x51'},{'\xfa','\x52'},{'\xfa','\x53'},{'\xfa','\x54'},
+ {'\xfa','\x55'},{'\xfa','\x56'},{'\xfa','\x57'},{'\xfa','\x58'},{'\xfa','\x59'},
+ {'\xfa','\x5a'},{'\xfa','\x5b'},{'\xfa','\x5c'},{'\xfa','\x5d'},{'\xfa','\x5e'},
+ {'\xfa','\x5f'},{'\xfa','\x60'},{'\xfa','\x61'},{'\xfa','\x62'},{'\xfa','\x63'},
+ {'\xfa','\x64'},{'\xfa','\x65'},{'\xfa','\x66'},{'\xfa','\x67'},{'\xfa','\x68'},
+ {'\xfa','\x69'},{'\xfa','\x6a'},{'\xfa','\x6b'},{'\xfa','\x6c'},{'\xfa','\x6d'},
+ {'\xfa','\x6e'},{'\xfa','\x6f'},{'\xfa','\x70'},{'\xfa','\x71'},{'\xfa','\x72'},
+ {'\xfa','\x73'},{'\xfa','\x74'},{'\xfa','\x75'},{'\xfa','\x76'},{'\xfa','\x77'},
+ {'\xfa','\x78'},{'\xfa','\x79'},{'\xfa','\x7a'},{'\xfa','\x7b'},{'\xfa','\x7c'},
+ {'\xfa','\x7d'},{'\xfa','\x7e'},{'\xfa','\xa1'},{'\xfa','\xa2'},{'\xfa','\xa3'},
+ {'\xfa','\xa4'},{'\xfa','\xa5'},{'\xfa','\xa6'},{'\xfa','\xa7'},{'\xfa','\xa8'},
+ {'\xfa','\xa9'},{'\xfa','\xaa'},{'\xfa','\xab'},{'\xfa','\xac'},{'\xfa','\xad'},
+ {'\xfa','\xae'},{'\xfa','\xaf'},{'\xfa','\xb0'},{'\xfa','\xb1'},{'\xfa','\xb2'},
+ {'\xfa','\xb3'},{'\xfa','\xb4'},{'\xfa','\xb5'},{'\xfa','\xb6'},{'\xfa','\xb7'},
+ {'\xfa','\xb8'},{'\xfa','\xb9'},{'\xfa','\xba'},{'\xfa','\xbb'},{'\xfa','\xbc'},
+ {'\xfa','\xbd'},{'\xfa','\xbe'},{'\xfa','\xbf'},{'\xfa','\xc0'},{'\xfa','\xc1'},
+ {'\xfa','\xc2'},{'\xfa','\xc3'},{'\xfa','\xc4'},{'\xfa','\xc5'},{'\xfa','\xc6'},
+ {'\xfa','\xc7'},{'\xfa','\xc8'},{'\xfa','\xc9'},{'\xfa','\xca'},{'\xfa','\xcb'},
+ {'\xfa','\xcc'},{'\xfa','\xcd'},{'\xfa','\xce'},{'\xfa','\xcf'},{'\xfa','\xd0'},
+ {'\xfa','\xd1'},{'\xfa','\xd2'},{'\xfa','\xd3'},{'\xfa','\xd4'},{'\xfa','\xd5'},
+ {'\xfa','\xd6'},{'\xfa','\xd7'},{'\xfa','\xd8'},{'\xfa','\xd9'},{'\xfa','\xda'},
+ {'\xfa','\xdb'},{'\xfa','\xdc'},{'\xfa','\xdd'},{'\xfa','\xde'},{'\xfa','\xdf'},
+ {'\xfa','\xe0'},{'\xfa','\xe1'},{'\xfa','\xe2'},{'\xfa','\xe3'},{'\xfa','\xe4'},
+ {'\xfa','\xe5'},{'\xfa','\xe6'},{'\xfa','\xe7'},{'\xfa','\xe8'},{'\xfa','\xe9'},
+ {'\xfa','\xea'},{'\xfa','\xeb'},{'\xfa','\xec'},{'\xfa','\xed'},{'\xfa','\xee'},
+ {'\xfa','\xef'},{'\xfa','\xf0'},{'\xfa','\xf1'},{'\xfa','\xf2'},{'\xfa','\xf3'},
+ {'\xfa','\xf4'},{'\xfa','\xf5'},{'\xfa','\xf6'},{'\xfa','\xf7'},{'\xfa','\xf8'},
+ {'\xfa','\xf9'},{'\xfa','\xfa'},{'\xfa','\xfb'},{'\xfa','\xfc'},{'\xfa','\xfd'},
+ {'\xfa','\xfe'},{'\xfb','\x40'},{'\xfb','\x41'},{'\xfb','\x42'},{'\xfb','\x43'},
+ {'\xfb','\x44'},{'\xfb','\x45'},{'\xfb','\x46'},{'\xfb','\x47'},{'\xfb','\x48'},
+ {'\xfb','\x49'},{'\xfb','\x4a'},{'\xfb','\x4b'},{'\xfb','\x4c'},{'\xfb','\x4d'},
+ {'\xfb','\x4e'},{'\xfb','\x4f'},{'\xfb','\x50'},{'\xfb','\x51'},{'\xfb','\x52'},
+ {'\xfb','\x53'},{'\xfb','\x54'},{'\xfb','\x55'},{'\xfb','\x56'},{'\xfb','\x57'},
+ {'\xfb','\x58'},{'\xfb','\x59'},{'\xfb','\x5a'},{'\xfb','\x5b'},{'\xfb','\x5c'},
+ {'\xfb','\x5d'},{'\xfb','\x5e'},{'\xfb','\x5f'},{'\xfb','\x60'},{'\xfb','\x61'},
+ {'\xfb','\x62'},{'\xfb','\x63'},{'\xfb','\x64'},{'\xfb','\x65'},{'\xfb','\x66'},
+ {'\xfb','\x67'},{'\xfb','\x68'},{'\xfb','\x69'},{'\xfb','\x6a'},{'\xfb','\x6b'},
+ {'\xfb','\x6c'},{'\xfb','\x6d'},{'\xfb','\x6e'},{'\xfb','\x6f'},{'\xfb','\x70'},
+ {'\xfb','\x71'},{'\xfb','\x72'},{'\xfb','\x73'},{'\xfb','\x74'},{'\xfb','\x75'},
+ {'\xfb','\x76'},{'\xfb','\x77'},{'\xfb','\x78'},{'\xfb','\x79'},{'\xfb','\x7a'},
+ {'\xfb','\x7b'},{'\xfb','\x7c'},{'\xfb','\x7d'},{'\xfb','\x7e'},{'\xfb','\xa1'},
+ {'\xfb','\xa2'},{'\xfb','\xa3'},{'\xfb','\xa4'},{'\xfb','\xa5'},{'\xfb','\xa6'},
+ {'\xfb','\xa7'},{'\xfb','\xa8'},{'\xfb','\xa9'},{'\xfb','\xaa'},{'\xfb','\xab'},
+ {'\xfb','\xac'},{'\xfb','\xad'},{'\xfb','\xae'},{'\xfb','\xaf'},{'\xfb','\xb0'},
+ {'\xfb','\xb1'},{'\xfb','\xb2'},{'\xfb','\xb3'},{'\xfb','\xb4'},{'\xfb','\xb5'},
+ {'\xfb','\xb6'},{'\xfb','\xb7'},{'\xfb','\xb8'},{'\xfb','\xb9'},{'\xfb','\xba'},
+ {'\xfb','\xbb'},{'\xfb','\xbc'},{'\xfb','\xbd'},{'\xfb','\xbe'},{'\xfb','\xbf'},
+ {'\xfb','\xc0'},{'\xfb','\xc1'},{'\xfb','\xc2'},{'\xfb','\xc3'},{'\xfb','\xc4'},
+ {'\xfb','\xc5'},{'\xfb','\xc6'},{'\xfb','\xc7'},{'\xfb','\xc8'},{'\xfb','\xc9'},
+ {'\xfb','\xca'},{'\xfb','\xcb'},{'\xfb','\xcc'},{'\xfb','\xcd'},{'\xfb','\xce'},
+ {'\xfb','\xcf'},{'\xfb','\xd0'},{'\xfb','\xd1'},{'\xfb','\xd2'},{'\xfb','\xd3'},
+ {'\xfb','\xd4'},{'\xfb','\xd5'},{'\xfb','\xd6'},{'\xfb','\xd7'},{'\xfb','\xd8'},
+ {'\xfb','\xd9'},{'\xfb','\xda'},{'\xfb','\xdb'},{'\xfb','\xdc'},{'\xfb','\xdd'},
+ {'\xfb','\xde'},{'\xfb','\xdf'},{'\xfb','\xe0'},{'\xfb','\xe1'},{'\xfb','\xe2'},
+ {'\xfb','\xe3'},{'\xfb','\xe4'},{'\xfb','\xe5'},{'\xfb','\xe6'},{'\xfb','\xe7'},
+ {'\xfb','\xe8'},{'\xfb','\xe9'},{'\xfb','\xea'},{'\xfb','\xeb'},{'\xfb','\xec'},
+ {'\xfb','\xed'},{'\xfb','\xee'},{'\xfb','\xef'},{'\xfb','\xf0'},{'\xfb','\xf1'},
+ {'\xfb','\xf2'},{'\xfb','\xf3'},{'\xfb','\xf4'},{'\xfb','\xf5'},{'\xfb','\xf6'},
+ {'\xfb','\xf7'},{'\xfb','\xf8'},{'\xfb','\xf9'},{'\xfb','\xfa'},{'\xfb','\xfb'},
+ {'\xfb','\xfc'},{'\xfb','\xfd'},{'\xfb','\xfe'},{'\xfc','\x40'},{'\xfc','\x41'},
+ {'\xfc','\x42'},{'\xfc','\x43'},{'\xfc','\x44'},{'\xfc','\x45'},{'\xfc','\x46'},
+ {'\xfc','\x47'},{'\xfc','\x48'},{'\xfc','\x49'},{'\xfc','\x4a'},{'\xfc','\x4b'},
+ {'\xfc','\x4c'},{'\xfc','\x4d'},{'\xfc','\x4e'},{'\xfc','\x4f'},{'\xfc','\x50'},
+ {'\xfc','\x51'},{'\xfc','\x52'},{'\xfc','\x53'},{'\xfc','\x54'},{'\xfc','\x55'},
+ {'\xfc','\x56'},{'\xfc','\x57'},{'\xfc','\x58'},{'\xfc','\x59'},{'\xfc','\x5a'},
+ {'\xfc','\x5b'},{'\xfc','\x5c'},{'\xfc','\x5d'},{'\xfc','\x5e'},{'\xfc','\x5f'},
+ {'\xfc','\x60'},{'\xfc','\x61'},{'\xfc','\x62'},{'\xfc','\x63'},{'\xfc','\x64'},
+ {'\xfc','\x65'},{'\xfc','\x66'},{'\xfc','\x67'},{'\xfc','\x68'},{'\xfc','\x69'},
+ {'\xfc','\x6a'},{'\xfc','\x6b'},{'\xfc','\x6c'},{'\xfc','\x6d'},{'\xfc','\x6e'},
+ {'\xfc','\x6f'},{'\xfc','\x70'},{'\xfc','\x71'},{'\xfc','\x72'},{'\xfc','\x73'},
+ {'\xfc','\x74'},{'\xfc','\x75'},{'\xfc','\x76'},{'\xfc','\x77'},{'\xfc','\x78'},
+ {'\xfc','\x79'},{'\xfc','\x7a'},{'\xfc','\x7b'},{'\xfc','\x7c'},{'\xfc','\x7d'},
+ {'\xfc','\x7e'},{'\xfc','\xa1'},{'\xfc','\xa2'},{'\xfc','\xa3'},{'\xfc','\xa4'},
+ {'\xfc','\xa5'},{'\xfc','\xa6'},{'\xfc','\xa7'},{'\xfc','\xa8'},{'\xfc','\xa9'},
+ {'\xfc','\xaa'},{'\xfc','\xab'},{'\xfc','\xac'},{'\xfc','\xad'},{'\xfc','\xae'},
+ {'\xfc','\xaf'},{'\xfc','\xb0'},{'\xfc','\xb1'},{'\xfc','\xb2'},{'\xfc','\xb3'},
+ {'\xfc','\xb4'},{'\xfc','\xb5'},{'\xfc','\xb6'},{'\xfc','\xb7'},{'\xfc','\xb8'},
+ {'\xfc','\xb9'},{'\xfc','\xba'},{'\xfc','\xbb'},{'\xfc','\xbc'},{'\xfc','\xbd'},
+ {'\xfc','\xbe'},{'\xfc','\xbf'},{'\xfc','\xc0'},{'\xfc','\xc1'},{'\xfc','\xc2'},
+ {'\xfc','\xc3'},{'\xfc','\xc4'},{'\xfc','\xc5'},{'\xfc','\xc6'},{'\xfc','\xc7'},
+ {'\xfc','\xc8'},{'\xfc','\xc9'},{'\xfc','\xca'},{'\xfc','\xcb'},{'\xfc','\xcc'},
+ {'\xfc','\xcd'},{'\xfc','\xce'},{'\xfc','\xcf'},{'\xfc','\xd0'},{'\xfc','\xd1'},
+ {'\xfc','\xd2'},{'\xfc','\xd3'},{'\xfc','\xd4'},{'\xfc','\xd5'},{'\xfc','\xd6'},
+ {'\xfc','\xd7'},{'\xfc','\xd8'},{'\xfc','\xd9'},{'\xfc','\xda'},{'\xfc','\xdb'},
+ {'\xfc','\xdc'},{'\xfc','\xdd'},{'\xfc','\xde'},{'\xfc','\xdf'},{'\xfc','\xe0'},
+ {'\xfc','\xe1'},{'\xfc','\xe2'},{'\xfc','\xe3'},{'\xfc','\xe4'},{'\xfc','\xe5'},
+ {'\xfc','\xe6'},{'\xfc','\xe7'},{'\xfc','\xe8'},{'\xfc','\xe9'},{'\xfc','\xea'},
+ {'\xfc','\xeb'},{'\xfc','\xec'},{'\xfc','\xed'},{'\xfc','\xee'},{'\xfc','\xef'},
+ {'\xfc','\xf0'},{'\xfc','\xf1'},{'\xfc','\xf2'},{'\xfc','\xf3'},{'\xfc','\xf4'},
+ {'\xfc','\xf5'},{'\xfc','\xf6'},{'\xfc','\xf7'},{'\xfc','\xf8'},{'\xfc','\xf9'},
+ {'\xfc','\xfa'},{'\xfc','\xfb'},{'\xfc','\xfc'},{'\xfc','\xfd'},{'\xfc','\xfe'},
+ {'\xfd','\x40'},{'\xfd','\x41'},{'\xfd','\x42'},{'\xfd','\x43'},{'\xfd','\x44'},
+ {'\xfd','\x45'},{'\xfd','\x46'},{'\xfd','\x47'},{'\xfd','\x48'},{'\xfd','\x49'},
+ {'\xfd','\x4a'},{'\xfd','\x4b'},{'\xfd','\x4c'},{'\xfd','\x4d'},{'\xfd','\x4e'},
+ {'\xfd','\x4f'},{'\xfd','\x50'},{'\xfd','\x51'},{'\xfd','\x52'},{'\xfd','\x53'},
+ {'\xfd','\x54'},{'\xfd','\x55'},{'\xfd','\x56'},{'\xfd','\x57'},{'\xfd','\x58'},
+ {'\xfd','\x59'},{'\xfd','\x5a'},{'\xfd','\x5b'},{'\xfd','\x5c'},{'\xfd','\x5d'},
+ {'\xfd','\x5e'},{'\xfd','\x5f'},{'\xfd','\x60'},{'\xfd','\x61'},{'\xfd','\x62'},
+ {'\xfd','\x63'},{'\xfd','\x64'},{'\xfd','\x65'},{'\xfd','\x66'},{'\xfd','\x67'},
+ {'\xfd','\x68'},{'\xfd','\x69'},{'\xfd','\x6a'},{'\xfd','\x6b'},{'\xfd','\x6c'},
+ {'\xfd','\x6d'},{'\xfd','\x6e'},{'\xfd','\x6f'},{'\xfd','\x70'},{'\xfd','\x71'},
+ {'\xfd','\x72'},{'\xfd','\x73'},{'\xfd','\x74'},{'\xfd','\x75'},{'\xfd','\x76'},
+ {'\xfd','\x77'},{'\xfd','\x78'},{'\xfd','\x79'},{'\xfd','\x7a'},{'\xfd','\x7b'},
+ {'\xfd','\x7c'},{'\xfd','\x7d'},{'\xfd','\x7e'},{'\xfd','\xa1'},{'\xfd','\xa2'},
+ {'\xfd','\xa3'},{'\xfd','\xa4'},{'\xfd','\xa5'},{'\xfd','\xa6'},{'\xfd','\xa7'},
+ {'\xfd','\xa8'},{'\xfd','\xa9'},{'\xfd','\xaa'},{'\xfd','\xab'},{'\xfd','\xac'},
+ {'\xfd','\xad'},{'\xfd','\xae'},{'\xfd','\xaf'},{'\xfd','\xb0'},{'\xfd','\xb1'},
+ {'\xfd','\xb2'},{'\xfd','\xb3'},{'\xfd','\xb4'},{'\xfd','\xb5'},{'\xfd','\xb6'},
+ {'\xfd','\xb7'},{'\xfd','\xb8'},{'\xfd','\xb9'},{'\xfd','\xba'},{'\xfd','\xbb'},
+ {'\xfd','\xbc'},{'\xfd','\xbd'},{'\xfd','\xbe'},{'\xfd','\xbf'},{'\xfd','\xc0'},
+ {'\xfd','\xc1'},{'\xfd','\xc2'},{'\xfd','\xc3'},{'\xfd','\xc4'},{'\xfd','\xc5'},
+ {'\xfd','\xc6'},{'\xfd','\xc7'},{'\xfd','\xc8'},{'\xfd','\xc9'},{'\xfd','\xca'},
+ {'\xfd','\xcb'},{'\xfd','\xcc'},{'\xfd','\xcd'},{'\xfd','\xce'},{'\xfd','\xcf'},
+ {'\xfd','\xd0'},{'\xfd','\xd1'},{'\xfd','\xd2'},{'\xfd','\xd3'},{'\xfd','\xd4'},
+ {'\xfd','\xd5'},{'\xfd','\xd6'},{'\xfd','\xd7'},{'\xfd','\xd8'},{'\xfd','\xd9'},
+ {'\xfd','\xda'},{'\xfd','\xdb'},{'\xfd','\xdc'},{'\xfd','\xdd'},{'\xfd','\xde'},
+ {'\xfd','\xdf'},{'\xfd','\xe0'},{'\xfd','\xe1'},{'\xfd','\xe2'},{'\xfd','\xe3'},
+ {'\xfd','\xe4'},{'\xfd','\xe5'},{'\xfd','\xe6'},{'\xfd','\xe7'},{'\xfd','\xe8'},
+ {'\xfd','\xe9'},{'\xfd','\xea'},{'\xfd','\xeb'},{'\xfd','\xec'},{'\xfd','\xed'},
+ {'\xfd','\xee'},{'\xfd','\xef'},{'\xfd','\xf0'},{'\xfd','\xf1'},{'\xfd','\xf2'},
+ {'\xfd','\xf3'},{'\xfd','\xf4'},{'\xfd','\xf5'},{'\xfd','\xf6'},{'\xfd','\xf7'},
+ {'\xfd','\xf8'},{'\xfd','\xf9'},{'\xfd','\xfa'},{'\xfd','\xfb'},{'\xfd','\xfc'},
+ {'\xfd','\xfd'},{'\xfd','\xfe'},{'\xfe','\x40'},{'\xfe','\x41'},{'\xfe','\x42'},
+ {'\xfe','\x43'},{'\xfe','\x44'},{'\xfe','\x45'},{'\xfe','\x46'},{'\xfe','\x47'},
+ {'\xfe','\x48'},{'\xfe','\x49'},{'\xfe','\x4a'},{'\xfe','\x4b'},{'\xfe','\x4c'},
+ {'\xfe','\x4d'},{'\xfe','\x4e'},{'\xfe','\x4f'},{'\xfe','\x50'},{'\xfe','\x51'},
+ {'\xfe','\x52'},{'\xfe','\x53'},{'\xfe','\x54'},{'\xfe','\x55'},{'\xfe','\x56'},
+ {'\xfe','\x57'},{'\xfe','\x58'},{'\xfe','\x59'},{'\xfe','\x5a'},{'\xfe','\x5b'},
+ {'\xfe','\x5c'},{'\xfe','\x5d'},{'\xfe','\x5e'},{'\xfe','\x5f'},{'\xfe','\x60'},
+ {'\xfe','\x61'},{'\xfe','\x62'},{'\xfe','\x63'},{'\xfe','\x64'},{'\xfe','\x65'},
+ {'\xfe','\x66'},{'\xfe','\x67'},{'\xfe','\x68'},{'\xfe','\x69'},{'\xfe','\x6a'},
+ {'\xfe','\x6b'},{'\xfe','\x6c'},{'\xfe','\x6d'},{'\xfe','\x6e'},{'\xfe','\x6f'},
+ {'\xfe','\x70'},{'\xfe','\x71'},{'\xfe','\x72'},{'\xfe','\x73'},{'\xfe','\x74'},
+ {'\xfe','\x75'},{'\xfe','\x76'},{'\xfe','\x77'},{'\xfe','\x78'},{'\xfe','\x79'},
+ {'\xfe','\x7a'},{'\xfe','\x7b'},{'\xfe','\x7c'},{'\xfe','\x7d'},{'\xfe','\x7e'},
+ {'\xfe','\xa1'},{'\xfe','\xa2'},{'\xfe','\xa3'},{'\xfe','\xa4'},{'\xfe','\xa5'},
+ {'\xfe','\xa6'},{'\xfe','\xa7'},{'\xfe','\xa8'},{'\xfe','\xa9'},{'\xfe','\xaa'},
+ {'\xfe','\xab'},{'\xfe','\xac'},{'\xfe','\xad'},{'\xfe','\xae'},{'\xfe','\xaf'},
+ {'\xfe','\xb0'},{'\xfe','\xb1'},{'\xfe','\xb2'},{'\xfe','\xb3'},{'\xfe','\xb4'},
+ {'\xfe','\xb5'},{'\xfe','\xb6'},{'\xfe','\xb7'},{'\xfe','\xb8'},{'\xfe','\xb9'},
+ {'\xfe','\xba'},{'\xfe','\xbb'},{'\xfe','\xbc'},{'\xfe','\xbd'},{'\xfe','\xbe'},
+ {'\xfe','\xbf'},{'\xfe','\xc0'},{'\xfe','\xc1'},{'\xfe','\xc2'},{'\xfe','\xc3'},
+ {'\xfe','\xc4'},{'\xfe','\xc5'},{'\xfe','\xc6'},{'\xfe','\xc7'},{'\xfe','\xc8'},
+ {'\xfe','\xc9'},{'\xfe','\xca'},{'\xfe','\xcb'},{'\xfe','\xcc'},{'\xfe','\xcd'},
+ {'\xfe','\xce'},{'\xfe','\xcf'},{'\xfe','\xd0'},{'\xfe','\xd1'},{'\xfe','\xd2'},
+ {'\xfe','\xd3'},{'\xfe','\xd4'},{'\xfe','\xd5'},{'\xfe','\xd6'},{'\xfe','\xd7'},
+ {'\xfe','\xd8'},{'\xfe','\xd9'},{'\xfe','\xda'},{'\xfe','\xdb'},{'\xfe','\xdc'},
+ {'\xfe','\xdd'},{'\xfe','\xde'},{'\xfe','\xdf'},{'\xfe','\xe0'},{'\xfe','\xe1'},
+ {'\xfe','\xe2'},{'\xfe','\xe3'},{'\xfe','\xe4'},{'\xfe','\xe5'},{'\xfe','\xe6'},
+ {'\xfe','\xe7'},{'\xfe','\xe8'},{'\xfe','\xe9'},{'\xfe','\xea'},{'\xfe','\xeb'},
+ {'\xfe','\xec'},{'\xfe','\xed'},{'\xfe','\xee'},{'\xfe','\xef'},{'\xfe','\xf0'},
+ {'\xfe','\xf1'},{'\xfe','\xf2'},{'\xfe','\xf3'},{'\xfe','\xf4'},{'\xfe','\xf5'},
+ {'\xfe','\xf6'},{'\xfe','\xf7'},{'\xfe','\xf8'},{'\xfe','\xf9'},{'\xfe','\xfa'},
+ {'\xfe','\xfb'},{'\xfe','\xfc'},{'\xfe','\xfd'},{'\xfe','\xfe'},{'\x8e','\x40'},
+ {'\x8e','\x41'},{'\x8e','\x42'},{'\x8e','\x43'},{'\x8e','\x44'},{'\x8e','\x45'},
+ {'\x8e','\x46'},{'\x8e','\x47'},{'\x8e','\x48'},{'\x8e','\x49'},{'\x8e','\x4a'},
+ {'\x8e','\x4b'},{'\x8e','\x4c'},{'\x8e','\x4d'},{'\x8e','\x4e'},{'\x8e','\x4f'},
+ {'\x8e','\x50'},{'\x8e','\x51'},{'\x8e','\x52'},{'\x8e','\x53'},{'\x8e','\x54'},
+ {'\x8e','\x55'},{'\x8e','\x56'},{'\x8e','\x57'},{'\x8e','\x58'},{'\x8e','\x59'},
+ {'\x8e','\x5a'},{'\x8e','\x5b'},{'\x8e','\x5c'},{'\x8e','\x5d'},{'\x8e','\x5e'},
+ {'\x8e','\x5f'},{'\x8e','\x60'},{'\x8e','\x61'},{'\x8e','\x62'},{'\x8e','\x63'},
+ {'\x8e','\x64'},{'\x8e','\x65'},{'\x8e','\x66'},{'\x8e','\x67'},{'\x8e','\x68'},
+ {'\x8e','\x69'},{'\x8e','\x6a'},{'\x8e','\x6b'},{'\x8e','\x6c'},{'\x8e','\x6d'},
+ {'\x8e','\x6e'},{'\x8e','\x6f'},{'\x8e','\x70'},{'\x8e','\x71'},{'\x8e','\x72'},
+ {'\x8e','\x73'},{'\x8e','\x74'},{'\x8e','\x75'},{'\x8e','\x76'},{'\x8e','\x77'},
+ {'\x8e','\x78'},{'\x8e','\x79'},{'\x8e','\x7a'},{'\x8e','\x7b'},{'\x8e','\x7c'},
+ {'\x8e','\x7d'},{'\x8e','\x7e'},{'\x8e','\xa1'},{'\x8e','\xa2'},{'\x8e','\xa3'},
+ {'\x8e','\xa4'},{'\x8e','\xa5'},{'\x8e','\xa6'},{'\x8e','\xa7'},{'\x8e','\xa8'},
+ {'\x8e','\xa9'},{'\x8e','\xaa'},{'\x8e','\xab'},{'\x8e','\xac'},{'\x8e','\xad'},
+ {'\x8e','\xae'},{'\x8e','\xaf'},{'\x8e','\xb0'},{'\x8e','\xb1'},{'\x8e','\xb2'},
+ {'\x8e','\xb3'},{'\x8e','\xb4'},{'\x8e','\xb5'},{'\x8e','\xb6'},{'\x8e','\xb7'},
+ {'\x8e','\xb8'},{'\x8e','\xb9'},{'\x8e','\xba'},{'\x8e','\xbb'},{'\x8e','\xbc'},
+ {'\x8e','\xbd'},{'\x8e','\xbe'},{'\x8e','\xbf'},{'\x8e','\xc0'},{'\x8e','\xc1'},
+ {'\x8e','\xc2'},{'\x8e','\xc3'},{'\x8e','\xc4'},{'\x8e','\xc5'},{'\x8e','\xc6'},
+ {'\x8e','\xc7'},{'\x8e','\xc8'},{'\x8e','\xc9'},{'\x8e','\xca'},{'\x8e','\xcb'},
+ {'\x8e','\xcc'},{'\x8e','\xcd'},{'\x8e','\xce'},{'\x8e','\xcf'},{'\x8e','\xd0'},
+ {'\x8e','\xd1'},{'\x8e','\xd2'},{'\x8e','\xd3'},{'\x8e','\xd4'},{'\x8e','\xd5'},
+ {'\x8e','\xd6'},{'\x8e','\xd7'},{'\x8e','\xd8'},{'\x8e','\xd9'},{'\x8e','\xda'},
+ {'\x8e','\xdb'},{'\x8e','\xdc'},{'\x8e','\xdd'},{'\x8e','\xde'},{'\x8e','\xdf'},
+ {'\x8e','\xe0'},{'\x8e','\xe1'},{'\x8e','\xe2'},{'\x8e','\xe3'},{'\x8e','\xe4'},
+ {'\x8e','\xe5'},{'\x8e','\xe6'},{'\x8e','\xe7'},{'\x8e','\xe8'},{'\x8e','\xe9'},
+ {'\x8e','\xea'},{'\x8e','\xeb'},{'\x8e','\xec'},{'\x8e','\xed'},{'\x8e','\xee'},
+ {'\x8e','\xef'},{'\x8e','\xf0'},{'\x8e','\xf1'},{'\x8e','\xf2'},{'\x8e','\xf3'},
+ {'\x8e','\xf4'},{'\x8e','\xf5'},{'\x8e','\xf6'},{'\x8e','\xf7'},{'\x8e','\xf8'},
+ {'\x8e','\xf9'},{'\x8e','\xfa'},{'\x8e','\xfb'},{'\x8e','\xfc'},{'\x8e','\xfd'},
+ {'\x8e','\xfe'},{'\x8f','\x40'},{'\x8f','\x41'},{'\x8f','\x42'},{'\x8f','\x43'},
+ {'\x8f','\x44'},{'\x8f','\x45'},{'\x8f','\x46'},{'\x8f','\x47'},{'\x8f','\x48'},
+ {'\x8f','\x49'},{'\x8f','\x4a'},{'\x8f','\x4b'},{'\x8f','\x4c'},{'\x8f','\x4d'},
+ {'\x8f','\x4e'},{'\x8f','\x4f'},{'\x8f','\x50'},{'\x8f','\x51'},{'\x8f','\x52'},
+ {'\x8f','\x53'},{'\x8f','\x54'},{'\x8f','\x55'},{'\x8f','\x56'},{'\x8f','\x57'},
+ {'\x8f','\x58'},{'\x8f','\x59'},{'\x8f','\x5a'},{'\x8f','\x5b'},{'\x8f','\x5c'},
+ {'\x8f','\x5d'},{'\x8f','\x5e'},{'\x8f','\x5f'},{'\x8f','\x60'},{'\x8f','\x61'},
+ {'\x8f','\x62'},{'\x8f','\x63'},{'\x8f','\x64'},{'\x8f','\x65'},{'\x8f','\x66'},
+ {'\x8f','\x67'},{'\x8f','\x68'},{'\x8f','\x69'},{'\x8f','\x6a'},{'\x8f','\x6b'},
+ {'\x8f','\x6c'},{'\x8f','\x6d'},{'\x8f','\x6e'},{'\x8f','\x6f'},{'\x8f','\x70'},
+ {'\x8f','\x71'},{'\x8f','\x72'},{'\x8f','\x73'},{'\x8f','\x74'},{'\x8f','\x75'},
+ {'\x8f','\x76'},{'\x8f','\x77'},{'\x8f','\x78'},{'\x8f','\x79'},{'\x8f','\x7a'},
+ {'\x8f','\x7b'},{'\x8f','\x7c'},{'\x8f','\x7d'},{'\x8f','\x7e'},{'\x8f','\xa1'},
+ {'\x8f','\xa2'},{'\x8f','\xa3'},{'\x8f','\xa4'},{'\x8f','\xa5'},{'\x8f','\xa6'},
+ {'\x8f','\xa7'},{'\x8f','\xa8'},{'\x8f','\xa9'},{'\x8f','\xaa'},{'\x8f','\xab'},
+ {'\x8f','\xac'},{'\x8f','\xad'},{'\x8f','\xae'},{'\x8f','\xaf'},{'\x8f','\xb0'},
+ {'\x8f','\xb1'},{'\x8f','\xb2'},{'\x8f','\xb3'},{'\x8f','\xb4'},{'\x8f','\xb5'},
+ {'\x8f','\xb6'},{'\x8f','\xb7'},{'\x8f','\xb8'},{'\x8f','\xb9'},{'\x8f','\xba'},
+ {'\x8f','\xbb'},{'\x8f','\xbc'},{'\x8f','\xbd'},{'\x8f','\xbe'},{'\x8f','\xbf'},
+ {'\x8f','\xc0'},{'\x8f','\xc1'},{'\x8f','\xc2'},{'\x8f','\xc3'},{'\x8f','\xc4'},
+ {'\x8f','\xc5'},{'\x8f','\xc6'},{'\x8f','\xc7'},{'\x8f','\xc8'},{'\x8f','\xc9'},
+ {'\x8f','\xca'},{'\x8f','\xcb'},{'\x8f','\xcc'},{'\x8f','\xcd'},{'\x8f','\xce'},
+ {'\x8f','\xcf'},{'\x8f','\xd0'},{'\x8f','\xd1'},{'\x8f','\xd2'},{'\x8f','\xd3'},
+ {'\x8f','\xd4'},{'\x8f','\xd5'},{'\x8f','\xd6'},{'\x8f','\xd7'},{'\x8f','\xd8'},
+ {'\x8f','\xd9'},{'\x8f','\xda'},{'\x8f','\xdb'},{'\x8f','\xdc'},{'\x8f','\xdd'},
+ {'\x8f','\xde'},{'\x8f','\xdf'},{'\x8f','\xe0'},{'\x8f','\xe1'},{'\x8f','\xe2'},
+ {'\x8f','\xe3'},{'\x8f','\xe4'},{'\x8f','\xe5'},{'\x8f','\xe6'},{'\x8f','\xe7'},
+ {'\x8f','\xe8'},{'\x8f','\xe9'},{'\x8f','\xea'},{'\x8f','\xeb'},{'\x8f','\xec'},
+ {'\x8f','\xed'},{'\x8f','\xee'},{'\x8f','\xef'},{'\x8f','\xf0'},{'\x8f','\xf1'},
+ {'\x8f','\xf2'},{'\x8f','\xf3'},{'\x8f','\xf4'},{'\x8f','\xf5'},{'\x8f','\xf6'},
+ {'\x8f','\xf7'},{'\x8f','\xf8'},{'\x8f','\xf9'},{'\x8f','\xfa'},{'\x8f','\xfb'},
+ {'\x8f','\xfc'},{'\x8f','\xfd'},{'\x8f','\xfe'},{'\x90','\x40'},{'\x90','\x41'},
+ {'\x90','\x42'},{'\x90','\x43'},{'\x90','\x44'},{'\x90','\x45'},{'\x90','\x46'},
+ {'\x90','\x47'},{'\x90','\x48'},{'\x90','\x49'},{'\x90','\x4a'},{'\x90','\x4b'},
+ {'\x90','\x4c'},{'\x90','\x4d'},{'\x90','\x4e'},{'\x90','\x4f'},{'\x90','\x50'},
+ {'\x90','\x51'},{'\x90','\x52'},{'\x90','\x53'},{'\x90','\x54'},{'\x90','\x55'},
+ {'\x90','\x56'},{'\x90','\x57'},{'\x90','\x58'},{'\x90','\x59'},{'\x90','\x5a'},
+ {'\x90','\x5b'},{'\x90','\x5c'},{'\x90','\x5d'},{'\x90','\x5e'},{'\x90','\x5f'},
+ {'\x90','\x60'},{'\x90','\x61'},{'\x90','\x62'},{'\x90','\x63'},{'\x90','\x64'},
+ {'\x90','\x65'},{'\x90','\x66'},{'\x90','\x67'},{'\x90','\x68'},{'\x90','\x69'},
+ {'\x90','\x6a'},{'\x90','\x6b'},{'\x90','\x6c'},{'\x90','\x6d'},{'\x90','\x6e'},
+ {'\x90','\x6f'},{'\x90','\x70'},{'\x90','\x71'},{'\x90','\x72'},{'\x90','\x73'},
+ {'\x90','\x74'},{'\x90','\x75'},{'\x90','\x76'},{'\x90','\x77'},{'\x90','\x78'},
+ {'\x90','\x79'},{'\x90','\x7a'},{'\x90','\x7b'},{'\x90','\x7c'},{'\x90','\x7d'},
+ {'\x90','\x7e'},{'\x90','\xa1'},{'\x90','\xa2'},{'\x90','\xa3'},{'\x90','\xa4'},
+ {'\x90','\xa5'},{'\x90','\xa6'},{'\x90','\xa7'},{'\x90','\xa8'},{'\x90','\xa9'},
+ {'\x90','\xaa'},{'\x90','\xab'},{'\x90','\xac'},{'\x90','\xad'},{'\x90','\xae'},
+ {'\x90','\xaf'},{'\x90','\xb0'},{'\x90','\xb1'},{'\x90','\xb2'},{'\x90','\xb3'},
+ {'\x90','\xb4'},{'\x90','\xb5'},{'\x90','\xb6'},{'\x90','\xb7'},{'\x90','\xb8'},
+ {'\x90','\xb9'},{'\x90','\xba'},{'\x90','\xbb'},{'\x90','\xbc'},{'\x90','\xbd'},
+ {'\x90','\xbe'},{'\x90','\xbf'},{'\x90','\xc0'},{'\x90','\xc1'},{'\x90','\xc2'},
+ {'\x90','\xc3'},{'\x90','\xc4'},{'\x90','\xc5'},{'\x90','\xc6'},{'\x90','\xc7'},
+ {'\x90','\xc8'},{'\x90','\xc9'},{'\x90','\xca'},{'\x90','\xcb'},{'\x90','\xcc'},
+ {'\x90','\xcd'},{'\x90','\xce'},{'\x90','\xcf'},{'\x90','\xd0'},{'\x90','\xd1'},
+ {'\x90','\xd2'},{'\x90','\xd3'},{'\x90','\xd4'},{'\x90','\xd5'},{'\x90','\xd6'},
+ {'\x90','\xd7'},{'\x90','\xd8'},{'\x90','\xd9'},{'\x90','\xda'},{'\x90','\xdb'},
+ {'\x90','\xdc'},{'\x90','\xdd'},{'\x90','\xde'},{'\x90','\xdf'},{'\x90','\xe0'},
+ {'\x90','\xe1'},{'\x90','\xe2'},{'\x90','\xe3'},{'\x90','\xe4'},{'\x90','\xe5'},
+ {'\x90','\xe6'},{'\x90','\xe7'},{'\x90','\xe8'},{'\x90','\xe9'},{'\x90','\xea'},
+ {'\x90','\xeb'},{'\x90','\xec'},{'\x90','\xed'},{'\x90','\xee'},{'\x90','\xef'},
+ {'\x90','\xf0'},{'\x90','\xf1'},{'\x90','\xf2'},{'\x90','\xf3'},{'\x90','\xf4'},
+ {'\x90','\xf5'},{'\x90','\xf6'},{'\x90','\xf7'},{'\x90','\xf8'},{'\x90','\xf9'},
+ {'\x90','\xfa'},{'\x90','\xfb'},{'\x90','\xfc'},{'\x90','\xfd'},{'\x90','\xfe'},
+ {'\x91','\x40'},{'\x91','\x41'},{'\x91','\x42'},{'\x91','\x43'},{'\x91','\x44'},
+ {'\x91','\x45'},{'\x91','\x46'},{'\x91','\x47'},{'\x91','\x48'},{'\x91','\x49'},
+ {'\x91','\x4a'},{'\x91','\x4b'},{'\x91','\x4c'},{'\x91','\x4d'},{'\x91','\x4e'},
+ {'\x91','\x4f'},{'\x91','\x50'},{'\x91','\x51'},{'\x91','\x52'},{'\x91','\x53'},
+ {'\x91','\x54'},{'\x91','\x55'},{'\x91','\x56'},{'\x91','\x57'},{'\x91','\x58'},
+ {'\x91','\x59'},{'\x91','\x5a'},{'\x91','\x5b'},{'\x91','\x5c'},{'\x91','\x5d'},
+ {'\x91','\x5e'},{'\x91','\x5f'},{'\x91','\x60'},{'\x91','\x61'},{'\x91','\x62'},
+ {'\x91','\x63'},{'\x91','\x64'},{'\x91','\x65'},{'\x91','\x66'},{'\x91','\x67'},
+ {'\x91','\x68'},{'\x91','\x69'},{'\x91','\x6a'},{'\x91','\x6b'},{'\x91','\x6c'},
+ {'\x91','\x6d'},{'\x91','\x6e'},{'\x91','\x6f'},{'\x91','\x70'},{'\x91','\x71'},
+ {'\x91','\x72'},{'\x91','\x73'},{'\x91','\x74'},{'\x91','\x75'},{'\x91','\x76'},
+ {'\x91','\x77'},{'\x91','\x78'},{'\x91','\x79'},{'\x91','\x7a'},{'\x91','\x7b'},
+ {'\x91','\x7c'},{'\x91','\x7d'},{'\x91','\x7e'},{'\x91','\xa1'},{'\x91','\xa2'},
+ {'\x91','\xa3'},{'\x91','\xa4'},{'\x91','\xa5'},{'\x91','\xa6'},{'\x91','\xa7'},
+ {'\x91','\xa8'},{'\x91','\xa9'},{'\x91','\xaa'},{'\x91','\xab'},{'\x91','\xac'},
+ {'\x91','\xad'},{'\x91','\xae'},{'\x91','\xaf'},{'\x91','\xb0'},{'\x91','\xb1'},
+ {'\x91','\xb2'},{'\x91','\xb3'},{'\x91','\xb4'},{'\x91','\xb5'},{'\x91','\xb6'},
+ {'\x91','\xb7'},{'\x91','\xb8'},{'\x91','\xb9'},{'\x91','\xba'},{'\x91','\xbb'},
+ {'\x91','\xbc'},{'\x91','\xbd'},{'\x91','\xbe'},{'\x91','\xbf'},{'\x91','\xc0'},
+ {'\x91','\xc1'},{'\x91','\xc2'},{'\x91','\xc3'},{'\x91','\xc4'},{'\x91','\xc5'},
+ {'\x91','\xc6'},{'\x91','\xc7'},{'\x91','\xc8'},{'\x91','\xc9'},{'\x91','\xca'},
+ {'\x91','\xcb'},{'\x91','\xcc'},{'\x91','\xcd'},{'\x91','\xce'},{'\x91','\xcf'},
+ {'\x91','\xd0'},{'\x91','\xd1'},{'\x91','\xd2'},{'\x91','\xd3'},{'\x91','\xd4'},
+ {'\x91','\xd5'},{'\x91','\xd6'},{'\x91','\xd7'},{'\x91','\xd8'},{'\x91','\xd9'},
+ {'\x91','\xda'},{'\x91','\xdb'},{'\x91','\xdc'},{'\x91','\xdd'},{'\x91','\xde'},
+ {'\x91','\xdf'},{'\x91','\xe0'},{'\x91','\xe1'},{'\x91','\xe2'},{'\x91','\xe3'},
+ {'\x91','\xe4'},{'\x91','\xe5'},{'\x91','\xe6'},{'\x91','\xe7'},{'\x91','\xe8'},
+ {'\x91','\xe9'},{'\x91','\xea'},{'\x91','\xeb'},{'\x91','\xec'},{'\x91','\xed'},
+ {'\x91','\xee'},{'\x91','\xef'},{'\x91','\xf0'},{'\x91','\xf1'},{'\x91','\xf2'},
+ {'\x91','\xf3'},{'\x91','\xf4'},{'\x91','\xf5'},{'\x91','\xf6'},{'\x91','\xf7'},
+ {'\x91','\xf8'},{'\x91','\xf9'},{'\x91','\xfa'},{'\x91','\xfb'},{'\x91','\xfc'},
+ {'\x91','\xfd'},{'\x91','\xfe'},{'\x92','\x40'},{'\x92','\x41'},{'\x92','\x42'},
+ {'\x92','\x43'},{'\x92','\x44'},{'\x92','\x45'},{'\x92','\x46'},{'\x92','\x47'},
+ {'\x92','\x48'},{'\x92','\x49'},{'\x92','\x4a'},{'\x92','\x4b'},{'\x92','\x4c'},
+ {'\x92','\x4d'},{'\x92','\x4e'},{'\x92','\x4f'},{'\x92','\x50'},{'\x92','\x51'},
+ {'\x92','\x52'},{'\x92','\x53'},{'\x92','\x54'},{'\x92','\x55'},{'\x92','\x56'},
+ {'\x92','\x57'},{'\x92','\x58'},{'\x92','\x59'},{'\x92','\x5a'},{'\x92','\x5b'},
+ {'\x92','\x5c'},{'\x92','\x5d'},{'\x92','\x5e'},{'\x92','\x5f'},{'\x92','\x60'},
+ {'\x92','\x61'},{'\x92','\x62'},{'\x92','\x63'},{'\x92','\x64'},{'\x92','\x65'},
+ {'\x92','\x66'},{'\x92','\x67'},{'\x92','\x68'},{'\x92','\x69'},{'\x92','\x6a'},
+ {'\x92','\x6b'},{'\x92','\x6c'},{'\x92','\x6d'},{'\x92','\x6e'},{'\x92','\x6f'},
+ {'\x92','\x70'},{'\x92','\x71'},{'\x92','\x72'},{'\x92','\x73'},{'\x92','\x74'},
+ {'\x92','\x75'},{'\x92','\x76'},{'\x92','\x77'},{'\x92','\x78'},{'\x92','\x79'},
+ {'\x92','\x7a'},{'\x92','\x7b'},{'\x92','\x7c'},{'\x92','\x7d'},{'\x92','\x7e'},
+ {'\x92','\xa1'},{'\x92','\xa2'},{'\x92','\xa3'},{'\x92','\xa4'},{'\x92','\xa5'},
+ {'\x92','\xa6'},{'\x92','\xa7'},{'\x92','\xa8'},{'\x92','\xa9'},{'\x92','\xaa'},
+ {'\x92','\xab'},{'\x92','\xac'},{'\x92','\xad'},{'\x92','\xae'},{'\x92','\xaf'},
+ {'\x92','\xb0'},{'\x92','\xb1'},{'\x92','\xb2'},{'\x92','\xb3'},{'\x92','\xb4'},
+ {'\x92','\xb5'},{'\x92','\xb6'},{'\x92','\xb7'},{'\x92','\xb8'},{'\x92','\xb9'},
+ {'\x92','\xba'},{'\x92','\xbb'},{'\x92','\xbc'},{'\x92','\xbd'},{'\x92','\xbe'},
+ {'\x92','\xbf'},{'\x92','\xc0'},{'\x92','\xc1'},{'\x92','\xc2'},{'\x92','\xc3'},
+ {'\x92','\xc4'},{'\x92','\xc5'},{'\x92','\xc6'},{'\x92','\xc7'},{'\x92','\xc8'},
+ {'\x92','\xc9'},{'\x92','\xca'},{'\x92','\xcb'},{'\x92','\xcc'},{'\x92','\xcd'},
+ {'\x92','\xce'},{'\x92','\xcf'},{'\x92','\xd0'},{'\x92','\xd1'},{'\x92','\xd2'},
+ {'\x92','\xd3'},{'\x92','\xd4'},{'\x92','\xd5'},{'\x92','\xd6'},{'\x92','\xd7'},
+ {'\x92','\xd8'},{'\x92','\xd9'},{'\x92','\xda'},{'\x92','\xdb'},{'\x92','\xdc'},
+ {'\x92','\xdd'},{'\x92','\xde'},{'\x92','\xdf'},{'\x92','\xe0'},{'\x92','\xe1'},
+ {'\x92','\xe2'},{'\x92','\xe3'},{'\x92','\xe4'},{'\x92','\xe5'},{'\x92','\xe6'},
+ {'\x92','\xe7'},{'\x92','\xe8'},{'\x92','\xe9'},{'\x92','\xea'},{'\x92','\xeb'},
+ {'\x92','\xec'},{'\x92','\xed'},{'\x92','\xee'},{'\x92','\xef'},{'\x92','\xf0'},
+ {'\x92','\xf1'},{'\x92','\xf2'},{'\x92','\xf3'},{'\x92','\xf4'},{'\x92','\xf5'},
+ {'\x92','\xf6'},{'\x92','\xf7'},{'\x92','\xf8'},{'\x92','\xf9'},{'\x92','\xfa'},
+ {'\x92','\xfb'},{'\x92','\xfc'},{'\x92','\xfd'},{'\x92','\xfe'},{'\x93','\x40'},
+ {'\x93','\x41'},{'\x93','\x42'},{'\x93','\x43'},{'\x93','\x44'},{'\x93','\x45'},
+ {'\x93','\x46'},{'\x93','\x47'},{'\x93','\x48'},{'\x93','\x49'},{'\x93','\x4a'},
+ {'\x93','\x4b'},{'\x93','\x4c'},{'\x93','\x4d'},{'\x93','\x4e'},{'\x93','\x4f'},
+ {'\x93','\x50'},{'\x93','\x51'},{'\x93','\x52'},{'\x93','\x53'},{'\x93','\x54'},
+ {'\x93','\x55'},{'\x93','\x56'},{'\x93','\x57'},{'\x93','\x58'},{'\x93','\x59'},
+ {'\x93','\x5a'},{'\x93','\x5b'},{'\x93','\x5c'},{'\x93','\x5d'},{'\x93','\x5e'},
+ {'\x93','\x5f'},{'\x93','\x60'},{'\x93','\x61'},{'\x93','\x62'},{'\x93','\x63'},
+ {'\x93','\x64'},{'\x93','\x65'},{'\x93','\x66'},{'\x93','\x67'},{'\x93','\x68'},
+ {'\x93','\x69'},{'\x93','\x6a'},{'\x93','\x6b'},{'\x93','\x6c'},{'\x93','\x6d'},
+ {'\x93','\x6e'},{'\x93','\x6f'},{'\x93','\x70'},{'\x93','\x71'},{'\x93','\x72'},
+ {'\x93','\x73'},{'\x93','\x74'},{'\x93','\x75'},{'\x93','\x76'},{'\x93','\x77'},
+ {'\x93','\x78'},{'\x93','\x79'},{'\x93','\x7a'},{'\x93','\x7b'},{'\x93','\x7c'},
+ {'\x93','\x7d'},{'\x93','\x7e'},{'\x93','\xa1'},{'\x93','\xa2'},{'\x93','\xa3'},
+ {'\x93','\xa4'},{'\x93','\xa5'},{'\x93','\xa6'},{'\x93','\xa7'},{'\x93','\xa8'},
+ {'\x93','\xa9'},{'\x93','\xaa'},{'\x93','\xab'},{'\x93','\xac'},{'\x93','\xad'},
+ {'\x93','\xae'},{'\x93','\xaf'},{'\x93','\xb0'},{'\x93','\xb1'},{'\x93','\xb2'},
+ {'\x93','\xb3'},{'\x93','\xb4'},{'\x93','\xb5'},{'\x93','\xb6'},{'\x93','\xb7'},
+ {'\x93','\xb8'},{'\x93','\xb9'},{'\x93','\xba'},{'\x93','\xbb'},{'\x93','\xbc'},
+ {'\x93','\xbd'},{'\x93','\xbe'},{'\x93','\xbf'},{'\x93','\xc0'},{'\x93','\xc1'},
+ {'\x93','\xc2'},{'\x93','\xc3'},{'\x93','\xc4'},{'\x93','\xc5'},{'\x93','\xc6'},
+ {'\x93','\xc7'},{'\x93','\xc8'},{'\x93','\xc9'},{'\x93','\xca'},{'\x93','\xcb'},
+ {'\x93','\xcc'},{'\x93','\xcd'},{'\x93','\xce'},{'\x93','\xcf'},{'\x93','\xd0'},
+ {'\x93','\xd1'},{'\x93','\xd2'},{'\x93','\xd3'},{'\x93','\xd4'},{'\x93','\xd5'},
+ {'\x93','\xd6'},{'\x93','\xd7'},{'\x93','\xd8'},{'\x93','\xd9'},{'\x93','\xda'},
+ {'\x93','\xdb'},{'\x93','\xdc'},{'\x93','\xdd'},{'\x93','\xde'},{'\x93','\xdf'},
+ {'\x93','\xe0'},{'\x93','\xe1'},{'\x93','\xe2'},{'\x93','\xe3'},{'\x93','\xe4'},
+ {'\x93','\xe5'},{'\x93','\xe6'},{'\x93','\xe7'},{'\x93','\xe8'},{'\x93','\xe9'},
+ {'\x93','\xea'},{'\x93','\xeb'},{'\x93','\xec'},{'\x93','\xed'},{'\x93','\xee'},
+ {'\x93','\xef'},{'\x93','\xf0'},{'\x93','\xf1'},{'\x93','\xf2'},{'\x93','\xf3'},
+ {'\x93','\xf4'},{'\x93','\xf5'},{'\x93','\xf6'},{'\x93','\xf7'},{'\x93','\xf8'},
+ {'\x93','\xf9'},{'\x93','\xfa'},{'\x93','\xfb'},{'\x93','\xfc'},{'\x93','\xfd'},
+ {'\x93','\xfe'},{'\x94','\x40'},{'\x94','\x41'},{'\x94','\x42'},{'\x94','\x43'},
+ {'\x94','\x44'},{'\x94','\x45'},{'\x94','\x46'},{'\x94','\x47'},{'\x94','\x48'},
+ {'\x94','\x49'},{'\x94','\x4a'},{'\x94','\x4b'},{'\x94','\x4c'},{'\x94','\x4d'},
+ {'\x94','\x4e'},{'\x94','\x4f'},{'\x94','\x50'},{'\x94','\x51'},{'\x94','\x52'},
+ {'\x94','\x53'},{'\x94','\x54'},{'\x94','\x55'},{'\x94','\x56'},{'\x94','\x57'},
+ {'\x94','\x58'},{'\x94','\x59'},{'\x94','\x5a'},{'\x94','\x5b'},{'\x94','\x5c'},
+ {'\x94','\x5d'},{'\x94','\x5e'},{'\x94','\x5f'},{'\x94','\x60'},{'\x94','\x61'},
+ {'\x94','\x62'},{'\x94','\x63'},{'\x94','\x64'},{'\x94','\x65'},{'\x94','\x66'},
+ {'\x94','\x67'},{'\x94','\x68'},{'\x94','\x69'},{'\x94','\x6a'},{'\x94','\x6b'},
+ {'\x94','\x6c'},{'\x94','\x6d'},{'\x94','\x6e'},{'\x94','\x6f'},{'\x94','\x70'},
+ {'\x94','\x71'},{'\x94','\x72'},{'\x94','\x73'},{'\x94','\x74'},{'\x94','\x75'},
+ {'\x94','\x76'},{'\x94','\x77'},{'\x94','\x78'},{'\x94','\x79'},{'\x94','\x7a'},
+ {'\x94','\x7b'},{'\x94','\x7c'},{'\x94','\x7d'},{'\x94','\x7e'},{'\x94','\xa1'},
+ {'\x94','\xa2'},{'\x94','\xa3'},{'\x94','\xa4'},{'\x94','\xa5'},{'\x94','\xa6'},
+ {'\x94','\xa7'},{'\x94','\xa8'},{'\x94','\xa9'},{'\x94','\xaa'},{'\x94','\xab'},
+ {'\x94','\xac'},{'\x94','\xad'},{'\x94','\xae'},{'\x94','\xaf'},{'\x94','\xb0'},
+ {'\x94','\xb1'},{'\x94','\xb2'},{'\x94','\xb3'},{'\x94','\xb4'},{'\x94','\xb5'},
+ {'\x94','\xb6'},{'\x94','\xb7'},{'\x94','\xb8'},{'\x94','\xb9'},{'\x94','\xba'},
+ {'\x94','\xbb'},{'\x94','\xbc'},{'\x94','\xbd'},{'\x94','\xbe'},{'\x94','\xbf'},
+ {'\x94','\xc0'},{'\x94','\xc1'},{'\x94','\xc2'},{'\x94','\xc3'},{'\x94','\xc4'},
+ {'\x94','\xc5'},{'\x94','\xc6'},{'\x94','\xc7'},{'\x94','\xc8'},{'\x94','\xc9'},
+ {'\x94','\xca'},{'\x94','\xcb'},{'\x94','\xcc'},{'\x94','\xcd'},{'\x94','\xce'},
+ {'\x94','\xcf'},{'\x94','\xd0'},{'\x94','\xd1'},{'\x94','\xd2'},{'\x94','\xd3'},
+ {'\x94','\xd4'},{'\x94','\xd5'},{'\x94','\xd6'},{'\x94','\xd7'},{'\x94','\xd8'},
+ {'\x94','\xd9'},{'\x94','\xda'},{'\x94','\xdb'},{'\x94','\xdc'},{'\x94','\xdd'},
+ {'\x94','\xde'},{'\x94','\xdf'},{'\x94','\xe0'},{'\x94','\xe1'},{'\x94','\xe2'},
+ {'\x94','\xe3'},{'\x94','\xe4'},{'\x94','\xe5'},{'\x94','\xe6'},{'\x94','\xe7'},
+ {'\x94','\xe8'},{'\x94','\xe9'},{'\x94','\xea'},{'\x94','\xeb'},{'\x94','\xec'},
+ {'\x94','\xed'},{'\x94','\xee'},{'\x94','\xef'},{'\x94','\xf0'},{'\x94','\xf1'},
+ {'\x94','\xf2'},{'\x94','\xf3'},{'\x94','\xf4'},{'\x94','\xf5'},{'\x94','\xf6'},
+ {'\x94','\xf7'},{'\x94','\xf8'},{'\x94','\xf9'},{'\x94','\xfa'},{'\x94','\xfb'},
+ {'\x94','\xfc'},{'\x94','\xfd'},{'\x94','\xfe'},{'\x95','\x40'},{'\x95','\x41'},
+ {'\x95','\x42'},{'\x95','\x43'},{'\x95','\x44'},{'\x95','\x45'},{'\x95','\x46'},
+ {'\x95','\x47'},{'\x95','\x48'},{'\x95','\x49'},{'\x95','\x4a'},{'\x95','\x4b'},
+ {'\x95','\x4c'},{'\x95','\x4d'},{'\x95','\x4e'},{'\x95','\x4f'},{'\x95','\x50'},
+ {'\x95','\x51'},{'\x95','\x52'},{'\x95','\x53'},{'\x95','\x54'},{'\x95','\x55'},
+ {'\x95','\x56'},{'\x95','\x57'},{'\x95','\x58'},{'\x95','\x59'},{'\x95','\x5a'},
+ {'\x95','\x5b'},{'\x95','\x5c'},{'\x95','\x5d'},{'\x95','\x5e'},{'\x95','\x5f'},
+ {'\x95','\x60'},{'\x95','\x61'},{'\x95','\x62'},{'\x95','\x63'},{'\x95','\x64'},
+ {'\x95','\x65'},{'\x95','\x66'},{'\x95','\x67'},{'\x95','\x68'},{'\x95','\x69'},
+ {'\x95','\x6a'},{'\x95','\x6b'},{'\x95','\x6c'},{'\x95','\x6d'},{'\x95','\x6e'},
+ {'\x95','\x6f'},{'\x95','\x70'},{'\x95','\x71'},{'\x95','\x72'},{'\x95','\x73'},
+ {'\x95','\x74'},{'\x95','\x75'},{'\x95','\x76'},{'\x95','\x77'},{'\x95','\x78'},
+ {'\x95','\x79'},{'\x95','\x7a'},{'\x95','\x7b'},{'\x95','\x7c'},{'\x95','\x7d'},
+ {'\x95','\x7e'},{'\x95','\xa1'},{'\x95','\xa2'},{'\x95','\xa3'},{'\x95','\xa4'},
+ {'\x95','\xa5'},{'\x95','\xa6'},{'\x95','\xa7'},{'\x95','\xa8'},{'\x95','\xa9'},
+ {'\x95','\xaa'},{'\x95','\xab'},{'\x95','\xac'},{'\x95','\xad'},{'\x95','\xae'},
+ {'\x95','\xaf'},{'\x95','\xb0'},{'\x95','\xb1'},{'\x95','\xb2'},{'\x95','\xb3'},
+ {'\x95','\xb4'},{'\x95','\xb5'},{'\x95','\xb6'},{'\x95','\xb7'},{'\x95','\xb8'},
+ {'\x95','\xb9'},{'\x95','\xba'},{'\x95','\xbb'},{'\x95','\xbc'},{'\x95','\xbd'},
+ {'\x95','\xbe'},{'\x95','\xbf'},{'\x95','\xc0'},{'\x95','\xc1'},{'\x95','\xc2'},
+ {'\x95','\xc3'},{'\x95','\xc4'},{'\x95','\xc5'},{'\x95','\xc6'},{'\x95','\xc7'},
+ {'\x95','\xc8'},{'\x95','\xc9'},{'\x95','\xca'},{'\x95','\xcb'},{'\x95','\xcc'},
+ {'\x95','\xcd'},{'\x95','\xce'},{'\x95','\xcf'},{'\x95','\xd0'},{'\x95','\xd1'},
+ {'\x95','\xd2'},{'\x95','\xd3'},{'\x95','\xd4'},{'\x95','\xd5'},{'\x95','\xd6'},
+ {'\x95','\xd7'},{'\x95','\xd8'},{'\x95','\xd9'},{'\x95','\xda'},{'\x95','\xdb'},
+ {'\x95','\xdc'},{'\x95','\xdd'},{'\x95','\xde'},{'\x95','\xdf'},{'\x95','\xe0'},
+ {'\x95','\xe1'},{'\x95','\xe2'},{'\x95','\xe3'},{'\x95','\xe4'},{'\x95','\xe5'},
+ {'\x95','\xe6'},{'\x95','\xe7'},{'\x95','\xe8'},{'\x95','\xe9'},{'\x95','\xea'},
+ {'\x95','\xeb'},{'\x95','\xec'},{'\x95','\xed'},{'\x95','\xee'},{'\x95','\xef'},
+ {'\x95','\xf0'},{'\x95','\xf1'},{'\x95','\xf2'},{'\x95','\xf3'},{'\x95','\xf4'},
+ {'\x95','\xf5'},{'\x95','\xf6'},{'\x95','\xf7'},{'\x95','\xf8'},{'\x95','\xf9'},
+ {'\x95','\xfa'},{'\x95','\xfb'},{'\x95','\xfc'},{'\x95','\xfd'},{'\x95','\xfe'},
+ {'\x96','\x40'},{'\x96','\x41'},{'\x96','\x42'},{'\x96','\x43'},{'\x96','\x44'},
+ {'\x96','\x45'},{'\x96','\x46'},{'\x96','\x47'},{'\x96','\x48'},{'\x96','\x49'},
+ {'\x96','\x4a'},{'\x96','\x4b'},{'\x96','\x4c'},{'\x96','\x4d'},{'\x96','\x4e'},
+ {'\x96','\x4f'},{'\x96','\x50'},{'\x96','\x51'},{'\x96','\x52'},{'\x96','\x53'},
+ {'\x96','\x54'},{'\x96','\x55'},{'\x96','\x56'},{'\x96','\x57'},{'\x96','\x58'},
+ {'\x96','\x59'},{'\x96','\x5a'},{'\x96','\x5b'},{'\x96','\x5c'},{'\x96','\x5d'},
+ {'\x96','\x5e'},{'\x96','\x5f'},{'\x96','\x60'},{'\x96','\x61'},{'\x96','\x62'},
+ {'\x96','\x63'},{'\x96','\x64'},{'\x96','\x65'},{'\x96','\x66'},{'\x96','\x67'},
+ {'\x96','\x68'},{'\x96','\x69'},{'\x96','\x6a'},{'\x96','\x6b'},{'\x96','\x6c'},
+ {'\x96','\x6d'},{'\x96','\x6e'},{'\x96','\x6f'},{'\x96','\x70'},{'\x96','\x71'},
+ {'\x96','\x72'},{'\x96','\x73'},{'\x96','\x74'},{'\x96','\x75'},{'\x96','\x76'},
+ {'\x96','\x77'},{'\x96','\x78'},{'\x96','\x79'},{'\x96','\x7a'},{'\x96','\x7b'},
+ {'\x96','\x7c'},{'\x96','\x7d'},{'\x96','\x7e'},{'\x96','\xa1'},{'\x96','\xa2'},
+ {'\x96','\xa3'},{'\x96','\xa4'},{'\x96','\xa5'},{'\x96','\xa6'},{'\x96','\xa7'},
+ {'\x96','\xa8'},{'\x96','\xa9'},{'\x96','\xaa'},{'\x96','\xab'},{'\x96','\xac'},
+ {'\x96','\xad'},{'\x96','\xae'},{'\x96','\xaf'},{'\x96','\xb0'},{'\x96','\xb1'},
+ {'\x96','\xb2'},{'\x96','\xb3'},{'\x96','\xb4'},{'\x96','\xb5'},{'\x96','\xb6'},
+ {'\x96','\xb7'},{'\x96','\xb8'},{'\x96','\xb9'},{'\x96','\xba'},{'\x96','\xbb'},
+ {'\x96','\xbc'},{'\x96','\xbd'},{'\x96','\xbe'},{'\x96','\xbf'},{'\x96','\xc0'},
+ {'\x96','\xc1'},{'\x96','\xc2'},{'\x96','\xc3'},{'\x96','\xc4'},{'\x96','\xc5'},
+ {'\x96','\xc6'},{'\x96','\xc7'},{'\x96','\xc8'},{'\x96','\xc9'},{'\x96','\xca'},
+ {'\x96','\xcb'},{'\x96','\xcc'},{'\x96','\xcd'},{'\x96','\xce'},{'\x96','\xcf'},
+ {'\x96','\xd0'},{'\x96','\xd1'},{'\x96','\xd2'},{'\x96','\xd3'},{'\x96','\xd4'},
+ {'\x96','\xd5'},{'\x96','\xd6'},{'\x96','\xd7'},{'\x96','\xd8'},{'\x96','\xd9'},
+ {'\x96','\xda'},{'\x96','\xdb'},{'\x96','\xdc'},{'\x96','\xdd'},{'\x96','\xde'},
+ {'\x96','\xdf'},{'\x96','\xe0'},{'\x96','\xe1'},{'\x96','\xe2'},{'\x96','\xe3'},
+ {'\x96','\xe4'},{'\x96','\xe5'},{'\x96','\xe6'},{'\x96','\xe7'},{'\x96','\xe8'},
+ {'\x96','\xe9'},{'\x96','\xea'},{'\x96','\xeb'},{'\x96','\xec'},{'\x96','\xed'},
+ {'\x96','\xee'},{'\x96','\xef'},{'\x96','\xf0'},{'\x96','\xf1'},{'\x96','\xf2'},
+ {'\x96','\xf3'},{'\x96','\xf4'},{'\x96','\xf5'},{'\x96','\xf6'},{'\x96','\xf7'},
+ {'\x96','\xf8'},{'\x96','\xf9'},{'\x96','\xfa'},{'\x96','\xfb'},{'\x96','\xfc'},
+ {'\x96','\xfd'},{'\x96','\xfe'},{'\x97','\x40'},{'\x97','\x41'},{'\x97','\x42'},
+ {'\x97','\x43'},{'\x97','\x44'},{'\x97','\x45'},{'\x97','\x46'},{'\x97','\x47'},
+ {'\x97','\x48'},{'\x97','\x49'},{'\x97','\x4a'},{'\x97','\x4b'},{'\x97','\x4c'},
+ {'\x97','\x4d'},{'\x97','\x4e'},{'\x97','\x4f'},{'\x97','\x50'},{'\x97','\x51'},
+ {'\x97','\x52'},{'\x97','\x53'},{'\x97','\x54'},{'\x97','\x55'},{'\x97','\x56'},
+ {'\x97','\x57'},{'\x97','\x58'},{'\x97','\x59'},{'\x97','\x5a'},{'\x97','\x5b'},
+ {'\x97','\x5c'},{'\x97','\x5d'},{'\x97','\x5e'},{'\x97','\x5f'},{'\x97','\x60'},
+ {'\x97','\x61'},{'\x97','\x62'},{'\x97','\x63'},{'\x97','\x64'},{'\x97','\x65'},
+ {'\x97','\x66'},{'\x97','\x67'},{'\x97','\x68'},{'\x97','\x69'},{'\x97','\x6a'},
+ {'\x97','\x6b'},{'\x97','\x6c'},{'\x97','\x6d'},{'\x97','\x6e'},{'\x97','\x6f'},
+ {'\x97','\x70'},{'\x97','\x71'},{'\x97','\x72'},{'\x97','\x73'},{'\x97','\x74'},
+ {'\x97','\x75'},{'\x97','\x76'},{'\x97','\x77'},{'\x97','\x78'},{'\x97','\x79'},
+ {'\x97','\x7a'},{'\x97','\x7b'},{'\x97','\x7c'},{'\x97','\x7d'},{'\x97','\x7e'},
+ {'\x97','\xa1'},{'\x97','\xa2'},{'\x97','\xa3'},{'\x97','\xa4'},{'\x97','\xa5'},
+ {'\x97','\xa6'},{'\x97','\xa7'},{'\x97','\xa8'},{'\x97','\xa9'},{'\x97','\xaa'},
+ {'\x97','\xab'},{'\x97','\xac'},{'\x97','\xad'},{'\x97','\xae'},{'\x97','\xaf'},
+ {'\x97','\xb0'},{'\x97','\xb1'},{'\x97','\xb2'},{'\x97','\xb3'},{'\x97','\xb4'},
+ {'\x97','\xb5'},{'\x97','\xb6'},{'\x97','\xb7'},{'\x97','\xb8'},{'\x97','\xb9'},
+ {'\x97','\xba'},{'\x97','\xbb'},{'\x97','\xbc'},{'\x97','\xbd'},{'\x97','\xbe'},
+ {'\x97','\xbf'},{'\x97','\xc0'},{'\x97','\xc1'},{'\x97','\xc2'},{'\x97','\xc3'},
+ {'\x97','\xc4'},{'\x97','\xc5'},{'\x97','\xc6'},{'\x97','\xc7'},{'\x97','\xc8'},
+ {'\x97','\xc9'},{'\x97','\xca'},{'\x97','\xcb'},{'\x97','\xcc'},{'\x97','\xcd'},
+ {'\x97','\xce'},{'\x97','\xcf'},{'\x97','\xd0'},{'\x97','\xd1'},{'\x97','\xd2'},
+ {'\x97','\xd3'},{'\x97','\xd4'},{'\x97','\xd5'},{'\x97','\xd6'},{'\x97','\xd7'},
+ {'\x97','\xd8'},{'\x97','\xd9'},{'\x97','\xda'},{'\x97','\xdb'},{'\x97','\xdc'},
+ {'\x97','\xdd'},{'\x97','\xde'},{'\x97','\xdf'},{'\x97','\xe0'},{'\x97','\xe1'},
+ {'\x97','\xe2'},{'\x97','\xe3'},{'\x97','\xe4'},{'\x97','\xe5'},{'\x97','\xe6'},
+ {'\x97','\xe7'},{'\x97','\xe8'},{'\x97','\xe9'},{'\x97','\xea'},{'\x97','\xeb'},
+ {'\x97','\xec'},{'\x97','\xed'},{'\x97','\xee'},{'\x97','\xef'},{'\x97','\xf0'},
+ {'\x97','\xf1'},{'\x97','\xf2'},{'\x97','\xf3'},{'\x97','\xf4'},{'\x97','\xf5'},
+ {'\x97','\xf6'},{'\x97','\xf7'},{'\x97','\xf8'},{'\x97','\xf9'},{'\x97','\xfa'},
+ {'\x97','\xfb'},{'\x97','\xfc'},{'\x97','\xfd'},{'\x97','\xfe'},{'\x98','\x40'},
+ {'\x98','\x41'},{'\x98','\x42'},{'\x98','\x43'},{'\x98','\x44'},{'\x98','\x45'},
+ {'\x98','\x46'},{'\x98','\x47'},{'\x98','\x48'},{'\x98','\x49'},{'\x98','\x4a'},
+ {'\x98','\x4b'},{'\x98','\x4c'},{'\x98','\x4d'},{'\x98','\x4e'},{'\x98','\x4f'},
+ {'\x98','\x50'},{'\x98','\x51'},{'\x98','\x52'},{'\x98','\x53'},{'\x98','\x54'},
+ {'\x98','\x55'},{'\x98','\x56'},{'\x98','\x57'},{'\x98','\x58'},{'\x98','\x59'},
+ {'\x98','\x5a'},{'\x98','\x5b'},{'\x98','\x5c'},{'\x98','\x5d'},{'\x98','\x5e'},
+ {'\x98','\x5f'},{'\x98','\x60'},{'\x98','\x61'},{'\x98','\x62'},{'\x98','\x63'},
+ {'\x98','\x64'},{'\x98','\x65'},{'\x98','\x66'},{'\x98','\x67'},{'\x98','\x68'},
+ {'\x98','\x69'},{'\x98','\x6a'},{'\x98','\x6b'},{'\x98','\x6c'},{'\x98','\x6d'},
+ {'\x98','\x6e'},{'\x98','\x6f'},{'\x98','\x70'},{'\x98','\x71'},{'\x98','\x72'},
+ {'\x98','\x73'},{'\x98','\x74'},{'\x98','\x75'},{'\x98','\x76'},{'\x98','\x77'},
+ {'\x98','\x78'},{'\x98','\x79'},{'\x98','\x7a'},{'\x98','\x7b'},{'\x98','\x7c'},
+ {'\x98','\x7d'},{'\x98','\x7e'},{'\x98','\xa1'},{'\x98','\xa2'},{'\x98','\xa3'},
+ {'\x98','\xa4'},{'\x98','\xa5'},{'\x98','\xa6'},{'\x98','\xa7'},{'\x98','\xa8'},
+ {'\x98','\xa9'},{'\x98','\xaa'},{'\x98','\xab'},{'\x98','\xac'},{'\x98','\xad'},
+ {'\x98','\xae'},{'\x98','\xaf'},{'\x98','\xb0'},{'\x98','\xb1'},{'\x98','\xb2'},
+ {'\x98','\xb3'},{'\x98','\xb4'},{'\x98','\xb5'},{'\x98','\xb6'},{'\x98','\xb7'},
+ {'\x98','\xb8'},{'\x98','\xb9'},{'\x98','\xba'},{'\x98','\xbb'},{'\x98','\xbc'},
+ {'\x98','\xbd'},{'\x98','\xbe'},{'\x98','\xbf'},{'\x98','\xc0'},{'\x98','\xc1'},
+ {'\x98','\xc2'},{'\x98','\xc3'},{'\x98','\xc4'},{'\x98','\xc5'},{'\x98','\xc6'},
+ {'\x98','\xc7'},{'\x98','\xc8'},{'\x98','\xc9'},{'\x98','\xca'},{'\x98','\xcb'},
+ {'\x98','\xcc'},{'\x98','\xcd'},{'\x98','\xce'},{'\x98','\xcf'},{'\x98','\xd0'},
+ {'\x98','\xd1'},{'\x98','\xd2'},{'\x98','\xd3'},{'\x98','\xd4'},{'\x98','\xd5'},
+ {'\x98','\xd6'},{'\x98','\xd7'},{'\x98','\xd8'},{'\x98','\xd9'},{'\x98','\xda'},
+ {'\x98','\xdb'},{'\x98','\xdc'},{'\x98','\xdd'},{'\x98','\xde'},{'\x98','\xdf'},
+ {'\x98','\xe0'},{'\x98','\xe1'},{'\x98','\xe2'},{'\x98','\xe3'},{'\x98','\xe4'},
+ {'\x98','\xe5'},{'\x98','\xe6'},{'\x98','\xe7'},{'\x98','\xe8'},{'\x98','\xe9'},
+ {'\x98','\xea'},{'\x98','\xeb'},{'\x98','\xec'},{'\x98','\xed'},{'\x98','\xee'},
+ {'\x98','\xef'},{'\x98','\xf0'},{'\x98','\xf1'},{'\x98','\xf2'},{'\x98','\xf3'},
+ {'\x98','\xf4'},{'\x98','\xf5'},{'\x98','\xf6'},{'\x98','\xf7'},{'\x98','\xf8'},
+ {'\x98','\xf9'},{'\x98','\xfa'},{'\x98','\xfb'},{'\x98','\xfc'},{'\x98','\xfd'},
+ {'\x98','\xfe'},{'\x99','\x40'},{'\x99','\x41'},{'\x99','\x42'},{'\x99','\x43'},
+ {'\x99','\x44'},{'\x99','\x45'},{'\x99','\x46'},{'\x99','\x47'},{'\x99','\x48'},
+ {'\x99','\x49'},{'\x99','\x4a'},{'\x99','\x4b'},{'\x99','\x4c'},{'\x99','\x4d'},
+ {'\x99','\x4e'},{'\x99','\x4f'},{'\x99','\x50'},{'\x99','\x51'},{'\x99','\x52'},
+ {'\x99','\x53'},{'\x99','\x54'},{'\x99','\x55'},{'\x99','\x56'},{'\x99','\x57'},
+ {'\x99','\x58'},{'\x99','\x59'},{'\x99','\x5a'},{'\x99','\x5b'},{'\x99','\x5c'},
+ {'\x99','\x5d'},{'\x99','\x5e'},{'\x99','\x5f'},{'\x99','\x60'},{'\x99','\x61'},
+ {'\x99','\x62'},{'\x99','\x63'},{'\x99','\x64'},{'\x99','\x65'},{'\x99','\x66'},
+ {'\x99','\x67'},{'\x99','\x68'},{'\x99','\x69'},{'\x99','\x6a'},{'\x99','\x6b'},
+ {'\x99','\x6c'},{'\x99','\x6d'},{'\x99','\x6e'},{'\x99','\x6f'},{'\x99','\x70'},
+ {'\x99','\x71'},{'\x99','\x72'},{'\x99','\x73'},{'\x99','\x74'},{'\x99','\x75'},
+ {'\x99','\x76'},{'\x99','\x77'},{'\x99','\x78'},{'\x99','\x79'},{'\x99','\x7a'},
+ {'\x99','\x7b'},{'\x99','\x7c'},{'\x99','\x7d'},{'\x99','\x7e'},{'\x99','\xa1'},
+ {'\x99','\xa2'},{'\x99','\xa3'},{'\x99','\xa4'},{'\x99','\xa5'},{'\x99','\xa6'},
+ {'\x99','\xa7'},{'\x99','\xa8'},{'\x99','\xa9'},{'\x99','\xaa'},{'\x99','\xab'},
+ {'\x99','\xac'},{'\x99','\xad'},{'\x99','\xae'},{'\x99','\xaf'},{'\x99','\xb0'},
+ {'\x99','\xb1'},{'\x99','\xb2'},{'\x99','\xb3'},{'\x99','\xb4'},{'\x99','\xb5'},
+ {'\x99','\xb6'},{'\x99','\xb7'},{'\x99','\xb8'},{'\x99','\xb9'},{'\x99','\xba'},
+ {'\x99','\xbb'},{'\x99','\xbc'},{'\x99','\xbd'},{'\x99','\xbe'},{'\x99','\xbf'},
+ {'\x99','\xc0'},{'\x99','\xc1'},{'\x99','\xc2'},{'\x99','\xc3'},{'\x99','\xc4'},
+ {'\x99','\xc5'},{'\x99','\xc6'},{'\x99','\xc7'},{'\x99','\xc8'},{'\x99','\xc9'},
+ {'\x99','\xca'},{'\x99','\xcb'},{'\x99','\xcc'},{'\x99','\xcd'},{'\x99','\xce'},
+ {'\x99','\xcf'},{'\x99','\xd0'},{'\x99','\xd1'},{'\x99','\xd2'},{'\x99','\xd3'},
+ {'\x99','\xd4'},{'\x99','\xd5'},{'\x99','\xd6'},{'\x99','\xd7'},{'\x99','\xd8'},
+ {'\x99','\xd9'},{'\x99','\xda'},{'\x99','\xdb'},{'\x99','\xdc'},{'\x99','\xdd'},
+ {'\x99','\xde'},{'\x99','\xdf'},{'\x99','\xe0'},{'\x99','\xe1'},{'\x99','\xe2'},
+ {'\x99','\xe3'},{'\x99','\xe4'},{'\x99','\xe5'},{'\x99','\xe6'},{'\x99','\xe7'},
+ {'\x99','\xe8'},{'\x99','\xe9'},{'\x99','\xea'},{'\x99','\xeb'},{'\x99','\xec'},
+ {'\x99','\xed'},{'\x99','\xee'},{'\x99','\xef'},{'\x99','\xf0'},{'\x99','\xf1'},
+ {'\x99','\xf2'},{'\x99','\xf3'},{'\x99','\xf4'},{'\x99','\xf5'},{'\x99','\xf6'},
+ {'\x99','\xf7'},{'\x99','\xf8'},{'\x99','\xf9'},{'\x99','\xfa'},{'\x99','\xfb'},
+ {'\x99','\xfc'},{'\x99','\xfd'},{'\x99','\xfe'},{'\x9a','\x40'},{'\x9a','\x41'},
+ {'\x9a','\x42'},{'\x9a','\x43'},{'\x9a','\x44'},{'\x9a','\x45'},{'\x9a','\x46'},
+ {'\x9a','\x47'},{'\x9a','\x48'},{'\x9a','\x49'},{'\x9a','\x4a'},{'\x9a','\x4b'},
+ {'\x9a','\x4c'},{'\x9a','\x4d'},{'\x9a','\x4e'},{'\x9a','\x4f'},{'\x9a','\x50'},
+ {'\x9a','\x51'},{'\x9a','\x52'},{'\x9a','\x53'},{'\x9a','\x54'},{'\x9a','\x55'},
+ {'\x9a','\x56'},{'\x9a','\x57'},{'\x9a','\x58'},{'\x9a','\x59'},{'\x9a','\x5a'},
+ {'\x9a','\x5b'},{'\x9a','\x5c'},{'\x9a','\x5d'},{'\x9a','\x5e'},{'\x9a','\x5f'},
+ {'\x9a','\x60'},{'\x9a','\x61'},{'\x9a','\x62'},{'\x9a','\x63'},{'\x9a','\x64'},
+ {'\x9a','\x65'},{'\x9a','\x66'},{'\x9a','\x67'},{'\x9a','\x68'},{'\x9a','\x69'},
+ {'\x9a','\x6a'},{'\x9a','\x6b'},{'\x9a','\x6c'},{'\x9a','\x6d'},{'\x9a','\x6e'},
+ {'\x9a','\x6f'},{'\x9a','\x70'},{'\x9a','\x71'},{'\x9a','\x72'},{'\x9a','\x73'},
+ {'\x9a','\x74'},{'\x9a','\x75'},{'\x9a','\x76'},{'\x9a','\x77'},{'\x9a','\x78'},
+ {'\x9a','\x79'},{'\x9a','\x7a'},{'\x9a','\x7b'},{'\x9a','\x7c'},{'\x9a','\x7d'},
+ {'\x9a','\x7e'},{'\x9a','\xa1'},{'\x9a','\xa2'},{'\x9a','\xa3'},{'\x9a','\xa4'},
+ {'\x9a','\xa5'},{'\x9a','\xa6'},{'\x9a','\xa7'},{'\x9a','\xa8'},{'\x9a','\xa9'},
+ {'\x9a','\xaa'},{'\x9a','\xab'},{'\x9a','\xac'},{'\x9a','\xad'},{'\x9a','\xae'},
+ {'\x9a','\xaf'},{'\x9a','\xb0'},{'\x9a','\xb1'},{'\x9a','\xb2'},{'\x9a','\xb3'},
+ {'\x9a','\xb4'},{'\x9a','\xb5'},{'\x9a','\xb6'},{'\x9a','\xb7'},{'\x9a','\xb8'},
+ {'\x9a','\xb9'},{'\x9a','\xba'},{'\x9a','\xbb'},{'\x9a','\xbc'},{'\x9a','\xbd'},
+ {'\x9a','\xbe'},{'\x9a','\xbf'},{'\x9a','\xc0'},{'\x9a','\xc1'},{'\x9a','\xc2'},
+ {'\x9a','\xc3'},{'\x9a','\xc4'},{'\x9a','\xc5'},{'\x9a','\xc6'},{'\x9a','\xc7'},
+ {'\x9a','\xc8'},{'\x9a','\xc9'},{'\x9a','\xca'},{'\x9a','\xcb'},{'\x9a','\xcc'},
+ {'\x9a','\xcd'},{'\x9a','\xce'},{'\x9a','\xcf'},{'\x9a','\xd0'},{'\x9a','\xd1'},
+ {'\x9a','\xd2'},{'\x9a','\xd3'},{'\x9a','\xd4'},{'\x9a','\xd5'},{'\x9a','\xd6'},
+ {'\x9a','\xd7'},{'\x9a','\xd8'},{'\x9a','\xd9'},{'\x9a','\xda'},{'\x9a','\xdb'},
+ {'\x9a','\xdc'},{'\x9a','\xdd'},{'\x9a','\xde'},{'\x9a','\xdf'},{'\x9a','\xe0'},
+ {'\x9a','\xe1'},{'\x9a','\xe2'},{'\x9a','\xe3'},{'\x9a','\xe4'},{'\x9a','\xe5'},
+ {'\x9a','\xe6'},{'\x9a','\xe7'},{'\x9a','\xe8'},{'\x9a','\xe9'},{'\x9a','\xea'},
+ {'\x9a','\xeb'},{'\x9a','\xec'},{'\x9a','\xed'},{'\x9a','\xee'},{'\x9a','\xef'},
+ {'\x9a','\xf0'},{'\x9a','\xf1'},{'\x9a','\xf2'},{'\x9a','\xf3'},{'\x9a','\xf4'},
+ {'\x9a','\xf5'},{'\x9a','\xf6'},{'\x9a','\xf7'},{'\x9a','\xf8'},{'\x9a','\xf9'},
+ {'\x9a','\xfa'},{'\x9a','\xfb'},{'\x9a','\xfc'},{'\x9a','\xfd'},{'\x9a','\xfe'},
+ {'\x9b','\x40'},{'\x9b','\x41'},{'\x9b','\x42'},{'\x9b','\x43'},{'\x9b','\x44'},
+ {'\x9b','\x45'},{'\x9b','\x46'},{'\x9b','\x47'},{'\x9b','\x48'},{'\x9b','\x49'},
+ {'\x9b','\x4a'},{'\x9b','\x4b'},{'\x9b','\x4c'},{'\x9b','\x4d'},{'\x9b','\x4e'},
+ {'\x9b','\x4f'},{'\x9b','\x50'},{'\x9b','\x51'},{'\x9b','\x52'},{'\x9b','\x53'},
+ {'\x9b','\x54'},{'\x9b','\x55'},{'\x9b','\x56'},{'\x9b','\x57'},{'\x9b','\x58'},
+ {'\x9b','\x59'},{'\x9b','\x5a'},{'\x9b','\x5b'},{'\x9b','\x5c'},{'\x9b','\x5d'},
+ {'\x9b','\x5e'},{'\x9b','\x5f'},{'\x9b','\x60'},{'\x9b','\x61'},{'\x9b','\x62'},
+ {'\x9b','\x63'},{'\x9b','\x64'},{'\x9b','\x65'},{'\x9b','\x66'},{'\x9b','\x67'},
+ {'\x9b','\x68'},{'\x9b','\x69'},{'\x9b','\x6a'},{'\x9b','\x6b'},{'\x9b','\x6c'},
+ {'\x9b','\x6d'},{'\x9b','\x6e'},{'\x9b','\x6f'},{'\x9b','\x70'},{'\x9b','\x71'},
+ {'\x9b','\x72'},{'\x9b','\x73'},{'\x9b','\x74'},{'\x9b','\x75'},{'\x9b','\x76'},
+ {'\x9b','\x77'},{'\x9b','\x78'},{'\x9b','\x79'},{'\x9b','\x7a'},{'\x9b','\x7b'},
+ {'\x9b','\x7c'},{'\x9b','\x7d'},{'\x9b','\x7e'},{'\x9b','\xa1'},{'\x9b','\xa2'},
+ {'\x9b','\xa3'},{'\x9b','\xa4'},{'\x9b','\xa5'},{'\x9b','\xa6'},{'\x9b','\xa7'},
+ {'\x9b','\xa8'},{'\x9b','\xa9'},{'\x9b','\xaa'},{'\x9b','\xab'},{'\x9b','\xac'},
+ {'\x9b','\xad'},{'\x9b','\xae'},{'\x9b','\xaf'},{'\x9b','\xb0'},{'\x9b','\xb1'},
+ {'\x9b','\xb2'},{'\x9b','\xb3'},{'\x9b','\xb4'},{'\x9b','\xb5'},{'\x9b','\xb6'},
+ {'\x9b','\xb7'},{'\x9b','\xb8'},{'\x9b','\xb9'},{'\x9b','\xba'},{'\x9b','\xbb'},
+ {'\x9b','\xbc'},{'\x9b','\xbd'},{'\x9b','\xbe'},{'\x9b','\xbf'},{'\x9b','\xc0'},
+ {'\x9b','\xc1'},{'\x9b','\xc2'},{'\x9b','\xc3'},{'\x9b','\xc4'},{'\x9b','\xc5'},
+ {'\x9b','\xc6'},{'\x9b','\xc7'},{'\x9b','\xc8'},{'\x9b','\xc9'},{'\x9b','\xca'},
+ {'\x9b','\xcb'},{'\x9b','\xcc'},{'\x9b','\xcd'},{'\x9b','\xce'},{'\x9b','\xcf'},
+ {'\x9b','\xd0'},{'\x9b','\xd1'},{'\x9b','\xd2'},{'\x9b','\xd3'},{'\x9b','\xd4'},
+ {'\x9b','\xd5'},{'\x9b','\xd6'},{'\x9b','\xd7'},{'\x9b','\xd8'},{'\x9b','\xd9'},
+ {'\x9b','\xda'},{'\x9b','\xdb'},{'\x9b','\xdc'},{'\x9b','\xdd'},{'\x9b','\xde'},
+ {'\x9b','\xdf'},{'\x9b','\xe0'},{'\x9b','\xe1'},{'\x9b','\xe2'},{'\x9b','\xe3'},
+ {'\x9b','\xe4'},{'\x9b','\xe5'},{'\x9b','\xe6'},{'\x9b','\xe7'},{'\x9b','\xe8'},
+ {'\x9b','\xe9'},{'\x9b','\xea'},{'\x9b','\xeb'},{'\x9b','\xec'},{'\x9b','\xed'},
+ {'\x9b','\xee'},{'\x9b','\xef'},{'\x9b','\xf0'},{'\x9b','\xf1'},{'\x9b','\xf2'},
+ {'\x9b','\xf3'},{'\x9b','\xf4'},{'\x9b','\xf5'},{'\x9b','\xf6'},{'\x9b','\xf7'},
+ {'\x9b','\xf8'},{'\x9b','\xf9'},{'\x9b','\xfa'},{'\x9b','\xfb'},{'\x9b','\xfc'},
+ {'\x9b','\xfd'},{'\x9b','\xfe'},{'\x9c','\x40'},{'\x9c','\x41'},{'\x9c','\x42'},
+ {'\x9c','\x43'},{'\x9c','\x44'},{'\x9c','\x45'},{'\x9c','\x46'},{'\x9c','\x47'},
+ {'\x9c','\x48'},{'\x9c','\x49'},{'\x9c','\x4a'},{'\x9c','\x4b'},{'\x9c','\x4c'},
+ {'\x9c','\x4d'},{'\x9c','\x4e'},{'\x9c','\x4f'},{'\x9c','\x50'},{'\x9c','\x51'},
+ {'\x9c','\x52'},{'\x9c','\x53'},{'\x9c','\x54'},{'\x9c','\x55'},{'\x9c','\x56'},
+ {'\x9c','\x57'},{'\x9c','\x58'},{'\x9c','\x59'},{'\x9c','\x5a'},{'\x9c','\x5b'},
+ {'\x9c','\x5c'},{'\x9c','\x5d'},{'\x9c','\x5e'},{'\x9c','\x5f'},{'\x9c','\x60'},
+ {'\x9c','\x61'},{'\x9c','\x62'},{'\x9c','\x63'},{'\x9c','\x64'},{'\x9c','\x65'},
+ {'\x9c','\x66'},{'\x9c','\x67'},{'\x9c','\x68'},{'\x9c','\x69'},{'\x9c','\x6a'},
+ {'\x9c','\x6b'},{'\x9c','\x6c'},{'\x9c','\x6d'},{'\x9c','\x6e'},{'\x9c','\x6f'},
+ {'\x9c','\x70'},{'\x9c','\x71'},{'\x9c','\x72'},{'\x9c','\x73'},{'\x9c','\x74'},
+ {'\x9c','\x75'},{'\x9c','\x76'},{'\x9c','\x77'},{'\x9c','\x78'},{'\x9c','\x79'},
+ {'\x9c','\x7a'},{'\x9c','\x7b'},{'\x9c','\x7c'},{'\x9c','\x7d'},{'\x9c','\x7e'},
+ {'\x9c','\xa1'},{'\x9c','\xa2'},{'\x9c','\xa3'},{'\x9c','\xa4'},{'\x9c','\xa5'},
+ {'\x9c','\xa6'},{'\x9c','\xa7'},{'\x9c','\xa8'},{'\x9c','\xa9'},{'\x9c','\xaa'},
+ {'\x9c','\xab'},{'\x9c','\xac'},{'\x9c','\xad'},{'\x9c','\xae'},{'\x9c','\xaf'},
+ {'\x9c','\xb0'},{'\x9c','\xb1'},{'\x9c','\xb2'},{'\x9c','\xb3'},{'\x9c','\xb4'},
+ {'\x9c','\xb5'},{'\x9c','\xb6'},{'\x9c','\xb7'},{'\x9c','\xb8'},{'\x9c','\xb9'},
+ {'\x9c','\xba'},{'\x9c','\xbb'},{'\x9c','\xbc'},{'\x9c','\xbd'},{'\x9c','\xbe'},
+ {'\x9c','\xbf'},{'\x9c','\xc0'},{'\x9c','\xc1'},{'\x9c','\xc2'},{'\x9c','\xc3'},
+ {'\x9c','\xc4'},{'\x9c','\xc5'},{'\x9c','\xc6'},{'\x9c','\xc7'},{'\x9c','\xc8'},
+ {'\x9c','\xc9'},{'\x9c','\xca'},{'\x9c','\xcb'},{'\x9c','\xcc'},{'\x9c','\xcd'},
+ {'\x9c','\xce'},{'\x9c','\xcf'},{'\x9c','\xd0'},{'\x9c','\xd1'},{'\x9c','\xd2'},
+ {'\x9c','\xd3'},{'\x9c','\xd4'},{'\x9c','\xd5'},{'\x9c','\xd6'},{'\x9c','\xd7'},
+ {'\x9c','\xd8'},{'\x9c','\xd9'},{'\x9c','\xda'},{'\x9c','\xdb'},{'\x9c','\xdc'},
+ {'\x9c','\xdd'},{'\x9c','\xde'},{'\x9c','\xdf'},{'\x9c','\xe0'},{'\x9c','\xe1'},
+ {'\x9c','\xe2'},{'\x9c','\xe3'},{'\x9c','\xe4'},{'\x9c','\xe5'},{'\x9c','\xe6'},
+ {'\x9c','\xe7'},{'\x9c','\xe8'},{'\x9c','\xe9'},{'\x9c','\xea'},{'\x9c','\xeb'},
+ {'\x9c','\xec'},{'\x9c','\xed'},{'\x9c','\xee'},{'\x9c','\xef'},{'\x9c','\xf0'},
+ {'\x9c','\xf1'},{'\x9c','\xf2'},{'\x9c','\xf3'},{'\x9c','\xf4'},{'\x9c','\xf5'},
+ {'\x9c','\xf6'},{'\x9c','\xf7'},{'\x9c','\xf8'},{'\x9c','\xf9'},{'\x9c','\xfa'},
+ {'\x9c','\xfb'},{'\x9c','\xfc'},{'\x9c','\xfd'},{'\x9c','\xfe'},{'\x9d','\x40'},
+ {'\x9d','\x41'},{'\x9d','\x42'},{'\x9d','\x43'},{'\x9d','\x44'},{'\x9d','\x45'},
+ {'\x9d','\x46'},{'\x9d','\x47'},{'\x9d','\x48'},{'\x9d','\x49'},{'\x9d','\x4a'},
+ {'\x9d','\x4b'},{'\x9d','\x4c'},{'\x9d','\x4d'},{'\x9d','\x4e'},{'\x9d','\x4f'},
+ {'\x9d','\x50'},{'\x9d','\x51'},{'\x9d','\x52'},{'\x9d','\x53'},{'\x9d','\x54'},
+ {'\x9d','\x55'},{'\x9d','\x56'},{'\x9d','\x57'},{'\x9d','\x58'},{'\x9d','\x59'},
+ {'\x9d','\x5a'},{'\x9d','\x5b'},{'\x9d','\x5c'},{'\x9d','\x5d'},{'\x9d','\x5e'},
+ {'\x9d','\x5f'},{'\x9d','\x60'},{'\x9d','\x61'},{'\x9d','\x62'},{'\x9d','\x63'},
+ {'\x9d','\x64'},{'\x9d','\x65'},{'\x9d','\x66'},{'\x9d','\x67'},{'\x9d','\x68'},
+ {'\x9d','\x69'},{'\x9d','\x6a'},{'\x9d','\x6b'},{'\x9d','\x6c'},{'\x9d','\x6d'},
+ {'\x9d','\x6e'},{'\x9d','\x6f'},{'\x9d','\x70'},{'\x9d','\x71'},{'\x9d','\x72'},
+ {'\x9d','\x73'},{'\x9d','\x74'},{'\x9d','\x75'},{'\x9d','\x76'},{'\x9d','\x77'},
+ {'\x9d','\x78'},{'\x9d','\x79'},{'\x9d','\x7a'},{'\x9d','\x7b'},{'\x9d','\x7c'},
+ {'\x9d','\x7d'},{'\x9d','\x7e'},{'\x9d','\xa1'},{'\x9d','\xa2'},{'\x9d','\xa3'},
+ {'\x9d','\xa4'},{'\x9d','\xa5'},{'\x9d','\xa6'},{'\x9d','\xa7'},{'\x9d','\xa8'},
+ {'\x9d','\xa9'},{'\x9d','\xaa'},{'\x9d','\xab'},{'\x9d','\xac'},{'\x9d','\xad'},
+ {'\x9d','\xae'},{'\x9d','\xaf'},{'\x9d','\xb0'},{'\x9d','\xb1'},{'\x9d','\xb2'},
+ {'\x9d','\xb3'},{'\x9d','\xb4'},{'\x9d','\xb5'},{'\x9d','\xb6'},{'\x9d','\xb7'},
+ {'\x9d','\xb8'},{'\x9d','\xb9'},{'\x9d','\xba'},{'\x9d','\xbb'},{'\x9d','\xbc'},
+ {'\x9d','\xbd'},{'\x9d','\xbe'},{'\x9d','\xbf'},{'\x9d','\xc0'},{'\x9d','\xc1'},
+ {'\x9d','\xc2'},{'\x9d','\xc3'},{'\x9d','\xc4'},{'\x9d','\xc5'},{'\x9d','\xc6'},
+ {'\x9d','\xc7'},{'\x9d','\xc8'},{'\x9d','\xc9'},{'\x9d','\xca'},{'\x9d','\xcb'},
+ {'\x9d','\xcc'},{'\x9d','\xcd'},{'\x9d','\xce'},{'\x9d','\xcf'},{'\x9d','\xd0'},
+ {'\x9d','\xd1'},{'\x9d','\xd2'},{'\x9d','\xd3'},{'\x9d','\xd4'},{'\x9d','\xd5'},
+ {'\x9d','\xd6'},{'\x9d','\xd7'},{'\x9d','\xd8'},{'\x9d','\xd9'},{'\x9d','\xda'},
+ {'\x9d','\xdb'},{'\x9d','\xdc'},{'\x9d','\xdd'},{'\x9d','\xde'},{'\x9d','\xdf'},
+ {'\x9d','\xe0'},{'\x9d','\xe1'},{'\x9d','\xe2'},{'\x9d','\xe3'},{'\x9d','\xe4'},
+ {'\x9d','\xe5'},{'\x9d','\xe6'},{'\x9d','\xe7'},{'\x9d','\xe8'},{'\x9d','\xe9'},
+ {'\x9d','\xea'},{'\x9d','\xeb'},{'\x9d','\xec'},{'\x9d','\xed'},{'\x9d','\xee'},
+ {'\x9d','\xef'},{'\x9d','\xf0'},{'\x9d','\xf1'},{'\x9d','\xf2'},{'\x9d','\xf3'},
+ {'\x9d','\xf4'},{'\x9d','\xf5'},{'\x9d','\xf6'},{'\x9d','\xf7'},{'\x9d','\xf8'},
+ {'\x9d','\xf9'},{'\x9d','\xfa'},{'\x9d','\xfb'},{'\x9d','\xfc'},{'\x9d','\xfd'},
+ {'\x9d','\xfe'},{'\x9e','\x40'},{'\x9e','\x41'},{'\x9e','\x42'},{'\x9e','\x43'},
+ {'\x9e','\x44'},{'\x9e','\x45'},{'\x9e','\x46'},{'\x9e','\x47'},{'\x9e','\x48'},
+ {'\x9e','\x49'},{'\x9e','\x4a'},{'\x9e','\x4b'},{'\x9e','\x4c'},{'\x9e','\x4d'},
+ {'\x9e','\x4e'},{'\x9e','\x4f'},{'\x9e','\x50'},{'\x9e','\x51'},{'\x9e','\x52'},
+ {'\x9e','\x53'},{'\x9e','\x54'},{'\x9e','\x55'},{'\x9e','\x56'},{'\x9e','\x57'},
+ {'\x9e','\x58'},{'\x9e','\x59'},{'\x9e','\x5a'},{'\x9e','\x5b'},{'\x9e','\x5c'},
+ {'\x9e','\x5d'},{'\x9e','\x5e'},{'\x9e','\x5f'},{'\x9e','\x60'},{'\x9e','\x61'},
+ {'\x9e','\x62'},{'\x9e','\x63'},{'\x9e','\x64'},{'\x9e','\x65'},{'\x9e','\x66'},
+ {'\x9e','\x67'},{'\x9e','\x68'},{'\x9e','\x69'},{'\x9e','\x6a'},{'\x9e','\x6b'},
+ {'\x9e','\x6c'},{'\x9e','\x6d'},{'\x9e','\x6e'},{'\x9e','\x6f'},{'\x9e','\x70'},
+ {'\x9e','\x71'},{'\x9e','\x72'},{'\x9e','\x73'},{'\x9e','\x74'},{'\x9e','\x75'},
+ {'\x9e','\x76'},{'\x9e','\x77'},{'\x9e','\x78'},{'\x9e','\x79'},{'\x9e','\x7a'},
+ {'\x9e','\x7b'},{'\x9e','\x7c'},{'\x9e','\x7d'},{'\x9e','\x7e'},{'\x9e','\xa1'},
+ {'\x9e','\xa2'},{'\x9e','\xa3'},{'\x9e','\xa4'},{'\x9e','\xa5'},{'\x9e','\xa6'},
+ {'\x9e','\xa7'},{'\x9e','\xa8'},{'\x9e','\xa9'},{'\x9e','\xaa'},{'\x9e','\xab'},
+ {'\x9e','\xac'},{'\x9e','\xad'},{'\x9e','\xae'},{'\x9e','\xaf'},{'\x9e','\xb0'},
+ {'\x9e','\xb1'},{'\x9e','\xb2'},{'\x9e','\xb3'},{'\x9e','\xb4'},{'\x9e','\xb5'},
+ {'\x9e','\xb6'},{'\x9e','\xb7'},{'\x9e','\xb8'},{'\x9e','\xb9'},{'\x9e','\xba'},
+ {'\x9e','\xbb'},{'\x9e','\xbc'},{'\x9e','\xbd'},{'\x9e','\xbe'},{'\x9e','\xbf'},
+ {'\x9e','\xc0'},{'\x9e','\xc1'},{'\x9e','\xc2'},{'\x9e','\xc3'},{'\x9e','\xc4'},
+ {'\x9e','\xc5'},{'\x9e','\xc6'},{'\x9e','\xc7'},{'\x9e','\xc8'},{'\x9e','\xc9'},
+ {'\x9e','\xca'},{'\x9e','\xcb'},{'\x9e','\xcc'},{'\x9e','\xcd'},{'\x9e','\xce'},
+ {'\x9e','\xcf'},{'\x9e','\xd0'},{'\x9e','\xd1'},{'\x9e','\xd2'},{'\x9e','\xd3'},
+ {'\x9e','\xd4'},{'\x9e','\xd5'},{'\x9e','\xd6'},{'\x9e','\xd7'},{'\x9e','\xd8'},
+ {'\x9e','\xd9'},{'\x9e','\xda'},{'\x9e','\xdb'},{'\x9e','\xdc'},{'\x9e','\xdd'},
+ {'\x9e','\xde'},{'\x9e','\xdf'},{'\x9e','\xe0'},{'\x9e','\xe1'},{'\x9e','\xe2'},
+ {'\x9e','\xe3'},{'\x9e','\xe4'},{'\x9e','\xe5'},{'\x9e','\xe6'},{'\x9e','\xe7'},
+ {'\x9e','\xe8'},{'\x9e','\xe9'},{'\x9e','\xea'},{'\x9e','\xeb'},{'\x9e','\xec'},
+ {'\x9e','\xed'},{'\x9e','\xee'},{'\x9e','\xef'},{'\x9e','\xf0'},{'\x9e','\xf1'},
+ {'\x9e','\xf2'},{'\x9e','\xf3'},{'\x9e','\xf4'},{'\x9e','\xf5'},{'\x9e','\xf6'},
+ {'\x9e','\xf7'},{'\x9e','\xf8'},{'\x9e','\xf9'},{'\x9e','\xfa'},{'\x9e','\xfb'},
+ {'\x9e','\xfc'},{'\x9e','\xfd'},{'\x9e','\xfe'},{'\x9f','\x40'},{'\x9f','\x41'},
+ {'\x9f','\x42'},{'\x9f','\x43'},{'\x9f','\x44'},{'\x9f','\x45'},{'\x9f','\x46'},
+ {'\x9f','\x47'},{'\x9f','\x48'},{'\x9f','\x49'},{'\x9f','\x4a'},{'\x9f','\x4b'},
+ {'\x9f','\x4c'},{'\x9f','\x4d'},{'\x9f','\x4e'},{'\x9f','\x4f'},{'\x9f','\x50'},
+ {'\x9f','\x51'},{'\x9f','\x52'},{'\x9f','\x53'},{'\x9f','\x54'},{'\x9f','\x55'},
+ {'\x9f','\x56'},{'\x9f','\x57'},{'\x9f','\x58'},{'\x9f','\x59'},{'\x9f','\x5a'},
+ {'\x9f','\x5b'},{'\x9f','\x5c'},{'\x9f','\x5d'},{'\x9f','\x5e'},{'\x9f','\x5f'},
+ {'\x9f','\x60'},{'\x9f','\x61'},{'\x9f','\x62'},{'\x9f','\x63'},{'\x9f','\x64'},
+ {'\x9f','\x65'},{'\x9f','\x66'},{'\x9f','\x67'},{'\x9f','\x68'},{'\x9f','\x69'},
+ {'\x9f','\x6a'},{'\x9f','\x6b'},{'\x9f','\x6c'},{'\x9f','\x6d'},{'\x9f','\x6e'},
+ {'\x9f','\x6f'},{'\x9f','\x70'},{'\x9f','\x71'},{'\x9f','\x72'},{'\x9f','\x73'},
+ {'\x9f','\x74'},{'\x9f','\x75'},{'\x9f','\x76'},{'\x9f','\x77'},{'\x9f','\x78'},
+ {'\x9f','\x79'},{'\x9f','\x7a'},{'\x9f','\x7b'},{'\x9f','\x7c'},{'\x9f','\x7d'},
+ {'\x9f','\x7e'},{'\x9f','\xa1'},{'\x9f','\xa2'},{'\x9f','\xa3'},{'\x9f','\xa4'},
+ {'\x9f','\xa5'},{'\x9f','\xa6'},{'\x9f','\xa7'},{'\x9f','\xa8'},{'\x9f','\xa9'},
+ {'\x9f','\xaa'},{'\x9f','\xab'},{'\x9f','\xac'},{'\x9f','\xad'},{'\x9f','\xae'},
+ {'\x9f','\xaf'},{'\x9f','\xb0'},{'\x9f','\xb1'},{'\x9f','\xb2'},{'\x9f','\xb3'},
+ {'\x9f','\xb4'},{'\x9f','\xb5'},{'\x9f','\xb6'},{'\x9f','\xb7'},{'\x9f','\xb8'},
+ {'\x9f','\xb9'},{'\x9f','\xba'},{'\x9f','\xbb'},{'\x9f','\xbc'},{'\x9f','\xbd'},
+ {'\x9f','\xbe'},{'\x9f','\xbf'},{'\x9f','\xc0'},{'\x9f','\xc1'},{'\x9f','\xc2'},
+ {'\x9f','\xc3'},{'\x9f','\xc4'},{'\x9f','\xc5'},{'\x9f','\xc6'},{'\x9f','\xc7'},
+ {'\x9f','\xc8'},{'\x9f','\xc9'},{'\x9f','\xca'},{'\x9f','\xcb'},{'\x9f','\xcc'},
+ {'\x9f','\xcd'},{'\x9f','\xce'},{'\x9f','\xcf'},{'\x9f','\xd0'},{'\x9f','\xd1'},
+ {'\x9f','\xd2'},{'\x9f','\xd3'},{'\x9f','\xd4'},{'\x9f','\xd5'},{'\x9f','\xd6'},
+ {'\x9f','\xd7'},{'\x9f','\xd8'},{'\x9f','\xd9'},{'\x9f','\xda'},{'\x9f','\xdb'},
+ {'\x9f','\xdc'},{'\x9f','\xdd'},{'\x9f','\xde'},{'\x9f','\xdf'},{'\x9f','\xe0'},
+ {'\x9f','\xe1'},{'\x9f','\xe2'},{'\x9f','\xe3'},{'\x9f','\xe4'},{'\x9f','\xe5'},
+ {'\x9f','\xe6'},{'\x9f','\xe7'},{'\x9f','\xe8'},{'\x9f','\xe9'},{'\x9f','\xea'},
+ {'\x9f','\xeb'},{'\x9f','\xec'},{'\x9f','\xed'},{'\x9f','\xee'},{'\x9f','\xef'},
+ {'\x9f','\xf0'},{'\x9f','\xf1'},{'\x9f','\xf2'},{'\x9f','\xf3'},{'\x9f','\xf4'},
+ {'\x9f','\xf5'},{'\x9f','\xf6'},{'\x9f','\xf7'},{'\x9f','\xf8'},{'\x9f','\xf9'},
+ {'\x9f','\xfa'},{'\x9f','\xfb'},{'\x9f','\xfc'},{'\x9f','\xfd'},{'\x9f','\xfe'},
+ {'\xa0','\x40'},{'\xa0','\x41'},{'\xa0','\x42'},{'\xa0','\x43'},{'\xa0','\x44'},
+ {'\xa0','\x45'},{'\xa0','\x46'},{'\xa0','\x47'},{'\xa0','\x48'},{'\xa0','\x49'},
+ {'\xa0','\x4a'},{'\xa0','\x4b'},{'\xa0','\x4c'},{'\xa0','\x4d'},{'\xa0','\x4e'},
+ {'\xa0','\x4f'},{'\xa0','\x50'},{'\xa0','\x51'},{'\xa0','\x52'},{'\xa0','\x53'},
+ {'\xa0','\x54'},{'\xa0','\x55'},{'\xa0','\x56'},{'\xa0','\x57'},{'\xa0','\x58'},
+ {'\xa0','\x59'},{'\xa0','\x5a'},{'\xa0','\x5b'},{'\xa0','\x5c'},{'\xa0','\x5d'},
+ {'\xa0','\x5e'},{'\xa0','\x5f'},{'\xa0','\x60'},{'\xa0','\x61'},{'\xa0','\x62'},
+ {'\xa0','\x63'},{'\xa0','\x64'},{'\xa0','\x65'},{'\xa0','\x66'},{'\xa0','\x67'},
+ {'\xa0','\x68'},{'\xa0','\x69'},{'\xa0','\x6a'},{'\xa0','\x6b'},{'\xa0','\x6c'},
+ {'\xa0','\x6d'},{'\xa0','\x6e'},{'\xa0','\x6f'},{'\xa0','\x70'},{'\xa0','\x71'},
+ {'\xa0','\x72'},{'\xa0','\x73'},{'\xa0','\x74'},{'\xa0','\x75'},{'\xa0','\x76'},
+ {'\xa0','\x77'},{'\xa0','\x78'},{'\xa0','\x79'},{'\xa0','\x7a'},{'\xa0','\x7b'},
+ {'\xa0','\x7c'},{'\xa0','\x7d'},{'\xa0','\x7e'},{'\xa0','\xa1'},{'\xa0','\xa2'},
+ {'\xa0','\xa3'},{'\xa0','\xa4'},{'\xa0','\xa5'},{'\xa0','\xa6'},{'\xa0','\xa7'},
+ {'\xa0','\xa8'},{'\xa0','\xa9'},{'\xa0','\xaa'},{'\xa0','\xab'},{'\xa0','\xac'},
+ {'\xa0','\xad'},{'\xa0','\xae'},{'\xa0','\xaf'},{'\xa0','\xb0'},{'\xa0','\xb1'},
+ {'\xa0','\xb2'},{'\xa0','\xb3'},{'\xa0','\xb4'},{'\xa0','\xb5'},{'\xa0','\xb6'},
+ {'\xa0','\xb7'},{'\xa0','\xb8'},{'\xa0','\xb9'},{'\xa0','\xba'},{'\xa0','\xbb'},
+ {'\xa0','\xbc'},{'\xa0','\xbd'},{'\xa0','\xbe'},{'\xa0','\xbf'},{'\xa0','\xc0'},
+ {'\xa0','\xc1'},{'\xa0','\xc2'},{'\xa0','\xc3'},{'\xa0','\xc4'},{'\xa0','\xc5'},
+ {'\xa0','\xc6'},{'\xa0','\xc7'},{'\xa0','\xc8'},{'\xa0','\xc9'},{'\xa0','\xca'},
+ {'\xa0','\xcb'},{'\xa0','\xcc'},{'\xa0','\xcd'},{'\xa0','\xce'},{'\xa0','\xcf'},
+ {'\xa0','\xd0'},{'\xa0','\xd1'},{'\xa0','\xd2'},{'\xa0','\xd3'},{'\xa0','\xd4'},
+ {'\xa0','\xd5'},{'\xa0','\xd6'},{'\xa0','\xd7'},{'\xa0','\xd8'},{'\xa0','\xd9'},
+ {'\xa0','\xda'},{'\xa0','\xdb'},{'\xa0','\xdc'},{'\xa0','\xdd'},{'\xa0','\xde'},
+ {'\xa0','\xdf'},{'\xa0','\xe0'},{'\xa0','\xe1'},{'\xa0','\xe2'},{'\xa0','\xe3'},
+ {'\xa0','\xe4'},{'\xa0','\xe5'},{'\xa0','\xe6'},{'\xa0','\xe7'},{'\xa0','\xe8'},
+ {'\xa0','\xe9'},{'\xa0','\xea'},{'\xa0','\xeb'},{'\xa0','\xec'},{'\xa0','\xed'},
+ {'\xa0','\xee'},{'\xa0','\xef'},{'\xa0','\xf0'},{'\xa0','\xf1'},{'\xa0','\xf2'},
+ {'\xa0','\xf3'},{'\xa0','\xf4'},{'\xa0','\xf5'},{'\xa0','\xf6'},{'\xa0','\xf7'},
+ {'\xa0','\xf8'},{'\xa0','\xf9'},{'\xa0','\xfa'},{'\xa0','\xfb'},{'\xa0','\xfc'},
+ {'\xa0','\xfd'},{'\xa0','\xfe'},{'\x81','\x40'},{'\x81','\x41'},{'\x81','\x42'},
+ {'\x81','\x43'},{'\x81','\x44'},{'\x81','\x45'},{'\x81','\x46'},{'\x81','\x47'},
+ {'\x81','\x48'},{'\x81','\x49'},{'\x81','\x4a'},{'\x81','\x4b'},{'\x81','\x4c'},
+ {'\x81','\x4d'},{'\x81','\x4e'},{'\x81','\x4f'},{'\x81','\x50'},{'\x81','\x51'},
+ {'\x81','\x52'},{'\x81','\x53'},{'\x81','\x54'},{'\x81','\x55'},{'\x81','\x56'},
+ {'\x81','\x57'},{'\x81','\x58'},{'\x81','\x59'},{'\x81','\x5a'},{'\x81','\x5b'},
+ {'\x81','\x5c'},{'\x81','\x5d'},{'\x81','\x5e'},{'\x81','\x5f'},{'\x81','\x60'},
+ {'\x81','\x61'},{'\x81','\x62'},{'\x81','\x63'},{'\x81','\x64'},{'\x81','\x65'},
+ {'\x81','\x66'},{'\x81','\x67'},{'\x81','\x68'},{'\x81','\x69'},{'\x81','\x6a'},
+ {'\x81','\x6b'},{'\x81','\x6c'},{'\x81','\x6d'},{'\x81','\x6e'},{'\x81','\x6f'},
+ {'\x81','\x70'},{'\x81','\x71'},{'\x81','\x72'},{'\x81','\x73'},{'\x81','\x74'},
+ {'\x81','\x75'},{'\x81','\x76'},{'\x81','\x77'},{'\x81','\x78'},{'\x81','\x79'},
+ {'\x81','\x7a'},{'\x81','\x7b'},{'\x81','\x7c'},{'\x81','\x7d'},{'\x81','\x7e'},
+ {'\x81','\xa1'},{'\x81','\xa2'},{'\x81','\xa3'},{'\x81','\xa4'},{'\x81','\xa5'},
+ {'\x81','\xa6'},{'\x81','\xa7'},{'\x81','\xa8'},{'\x81','\xa9'},{'\x81','\xaa'},
+ {'\x81','\xab'},{'\x81','\xac'},{'\x81','\xad'},{'\x81','\xae'},{'\x81','\xaf'},
+ {'\x81','\xb0'},{'\x81','\xb1'},{'\x81','\xb2'},{'\x81','\xb3'},{'\x81','\xb4'},
+ {'\x81','\xb5'},{'\x81','\xb6'},{'\x81','\xb7'},{'\x81','\xb8'},{'\x81','\xb9'},
+ {'\x81','\xba'},{'\x81','\xbb'},{'\x81','\xbc'},{'\x81','\xbd'},{'\x81','\xbe'},
+ {'\x81','\xbf'},{'\x81','\xc0'},{'\x81','\xc1'},{'\x81','\xc2'},{'\x81','\xc3'},
+ {'\x81','\xc4'},{'\x81','\xc5'},{'\x81','\xc6'},{'\x81','\xc7'},{'\x81','\xc8'},
+ {'\x81','\xc9'},{'\x81','\xca'},{'\x81','\xcb'},{'\x81','\xcc'},{'\x81','\xcd'},
+ {'\x81','\xce'},{'\x81','\xcf'},{'\x81','\xd0'},{'\x81','\xd1'},{'\x81','\xd2'},
+ {'\x81','\xd3'},{'\x81','\xd4'},{'\x81','\xd5'},{'\x81','\xd6'},{'\x81','\xd7'},
+ {'\x81','\xd8'},{'\x81','\xd9'},{'\x81','\xda'},{'\x81','\xdb'},{'\x81','\xdc'},
+ {'\x81','\xdd'},{'\x81','\xde'},{'\x81','\xdf'},{'\x81','\xe0'},{'\x81','\xe1'},
+ {'\x81','\xe2'},{'\x81','\xe3'},{'\x81','\xe4'},{'\x81','\xe5'},{'\x81','\xe6'},
+ {'\x81','\xe7'},{'\x81','\xe8'},{'\x81','\xe9'},{'\x81','\xea'},{'\x81','\xeb'},
+ {'\x81','\xec'},{'\x81','\xed'},{'\x81','\xee'},{'\x81','\xef'},{'\x81','\xf0'},
+ {'\x81','\xf1'},{'\x81','\xf2'},{'\x81','\xf3'},{'\x81','\xf4'},{'\x81','\xf5'},
+ {'\x81','\xf6'},{'\x81','\xf7'},{'\x81','\xf8'},{'\x81','\xf9'},{'\x81','\xfa'},
+ {'\x81','\xfb'},{'\x81','\xfc'},{'\x81','\xfd'},{'\x81','\xfe'},{'\x82','\x40'},
+ {'\x82','\x41'},{'\x82','\x42'},{'\x82','\x43'},{'\x82','\x44'},{'\x82','\x45'},
+ {'\x82','\x46'},{'\x82','\x47'},{'\x82','\x48'},{'\x82','\x49'},{'\x82','\x4a'},
+ {'\x82','\x4b'},{'\x82','\x4c'},{'\x82','\x4d'},{'\x82','\x4e'},{'\x82','\x4f'},
+ {'\x82','\x50'},{'\x82','\x51'},{'\x82','\x52'},{'\x82','\x53'},{'\x82','\x54'},
+ {'\x82','\x55'},{'\x82','\x56'},{'\x82','\x57'},{'\x82','\x58'},{'\x82','\x59'},
+ {'\x82','\x5a'},{'\x82','\x5b'},{'\x82','\x5c'},{'\x82','\x5d'},{'\x82','\x5e'},
+ {'\x82','\x5f'},{'\x82','\x60'},{'\x82','\x61'},{'\x82','\x62'},{'\x82','\x63'},
+ {'\x82','\x64'},{'\x82','\x65'},{'\x82','\x66'},{'\x82','\x67'},{'\x82','\x68'},
+ {'\x82','\x69'},{'\x82','\x6a'},{'\x82','\x6b'},{'\x82','\x6c'},{'\x82','\x6d'},
+ {'\x82','\x6e'},{'\x82','\x6f'},{'\x82','\x70'},{'\x82','\x71'},{'\x82','\x72'},
+ {'\x82','\x73'},{'\x82','\x74'},{'\x82','\x75'},{'\x82','\x76'},{'\x82','\x77'},
+ {'\x82','\x78'},{'\x82','\x79'},{'\x82','\x7a'},{'\x82','\x7b'},{'\x82','\x7c'},
+ {'\x82','\x7d'},{'\x82','\x7e'},{'\x82','\xa1'},{'\x82','\xa2'},{'\x82','\xa3'},
+ {'\x82','\xa4'},{'\x82','\xa5'},{'\x82','\xa6'},{'\x82','\xa7'},{'\x82','\xa8'},
+ {'\x82','\xa9'},{'\x82','\xaa'},{'\x82','\xab'},{'\x82','\xac'},{'\x82','\xad'},
+ {'\x82','\xae'},{'\x82','\xaf'},{'\x82','\xb0'},{'\x82','\xb1'},{'\x82','\xb2'},
+ {'\x82','\xb3'},{'\x82','\xb4'},{'\x82','\xb5'},{'\x82','\xb6'},{'\x82','\xb7'},
+ {'\x82','\xb8'},{'\x82','\xb9'},{'\x82','\xba'},{'\x82','\xbb'},{'\x82','\xbc'},
+ {'\x82','\xbd'},{'\x82','\xbe'},{'\x82','\xbf'},{'\x82','\xc0'},{'\x82','\xc1'},
+ {'\x82','\xc2'},{'\x82','\xc3'},{'\x82','\xc4'},{'\x82','\xc5'},{'\x82','\xc6'},
+ {'\x82','\xc7'},{'\x82','\xc8'},{'\x82','\xc9'},{'\x82','\xca'},{'\x82','\xcb'},
+ {'\x82','\xcc'},{'\x82','\xcd'},{'\x82','\xce'},{'\x82','\xcf'},{'\x82','\xd0'},
+ {'\x82','\xd1'},{'\x82','\xd2'},{'\x82','\xd3'},{'\x82','\xd4'},{'\x82','\xd5'},
+ {'\x82','\xd6'},{'\x82','\xd7'},{'\x82','\xd8'},{'\x82','\xd9'},{'\x82','\xda'},
+ {'\x82','\xdb'},{'\x82','\xdc'},{'\x82','\xdd'},{'\x82','\xde'},{'\x82','\xdf'},
+ {'\x82','\xe0'},{'\x82','\xe1'},{'\x82','\xe2'},{'\x82','\xe3'},{'\x82','\xe4'},
+ {'\x82','\xe5'},{'\x82','\xe6'},{'\x82','\xe7'},{'\x82','\xe8'},{'\x82','\xe9'},
+ {'\x82','\xea'},{'\x82','\xeb'},{'\x82','\xec'},{'\x82','\xed'},{'\x82','\xee'},
+ {'\x82','\xef'},{'\x82','\xf0'},{'\x82','\xf1'},{'\x82','\xf2'},{'\x82','\xf3'},
+ {'\x82','\xf4'},{'\x82','\xf5'},{'\x82','\xf6'},{'\x82','\xf7'},{'\x82','\xf8'},
+ {'\x82','\xf9'},{'\x82','\xfa'},{'\x82','\xfb'},{'\x82','\xfc'},{'\x82','\xfd'},
+ {'\x82','\xfe'},{'\x83','\x40'},{'\x83','\x41'},{'\x83','\x42'},{'\x83','\x43'},
+ {'\x83','\x44'},{'\x83','\x45'},{'\x83','\x46'},{'\x83','\x47'},{'\x83','\x48'},
+ {'\x83','\x49'},{'\x83','\x4a'},{'\x83','\x4b'},{'\x83','\x4c'},{'\x83','\x4d'},
+ {'\x83','\x4e'},{'\x83','\x4f'},{'\x83','\x50'},{'\x83','\x51'},{'\x83','\x52'},
+ {'\x83','\x53'},{'\x83','\x54'},{'\x83','\x55'},{'\x83','\x56'},{'\x83','\x57'},
+ {'\x83','\x58'},{'\x83','\x59'},{'\x83','\x5a'},{'\x83','\x5b'},{'\x83','\x5c'},
+ {'\x83','\x5d'},{'\x83','\x5e'},{'\x83','\x5f'},{'\x83','\x60'},{'\x83','\x61'},
+ {'\x83','\x62'},{'\x83','\x63'},{'\x83','\x64'},{'\x83','\x65'},{'\x83','\x66'},
+ {'\x83','\x67'},{'\x83','\x68'},{'\x83','\x69'},{'\x83','\x6a'},{'\x83','\x6b'},
+ {'\x83','\x6c'},{'\x83','\x6d'},{'\x83','\x6e'},{'\x83','\x6f'},{'\x83','\x70'},
+ {'\x83','\x71'},{'\x83','\x72'},{'\x83','\x73'},{'\x83','\x74'},{'\x83','\x75'},
+ {'\x83','\x76'},{'\x83','\x77'},{'\x83','\x78'},{'\x83','\x79'},{'\x83','\x7a'},
+ {'\x83','\x7b'},{'\x83','\x7c'},{'\x83','\x7d'},{'\x83','\x7e'},{'\x83','\xa1'},
+ {'\x83','\xa2'},{'\x83','\xa3'},{'\x83','\xa4'},{'\x83','\xa5'},{'\x83','\xa6'},
+ {'\x83','\xa7'},{'\x83','\xa8'},{'\x83','\xa9'},{'\x83','\xaa'},{'\x83','\xab'},
+ {'\x83','\xac'},{'\x83','\xad'},{'\x83','\xae'},{'\x83','\xaf'},{'\x83','\xb0'},
+ {'\x83','\xb1'},{'\x83','\xb2'},{'\x83','\xb3'},{'\x83','\xb4'},{'\x83','\xb5'},
+ {'\x83','\xb6'},{'\x83','\xb7'},{'\x83','\xb8'},{'\x83','\xb9'},{'\x83','\xba'},
+ {'\x83','\xbb'},{'\x83','\xbc'},{'\x83','\xbd'},{'\x83','\xbe'},{'\x83','\xbf'},
+ {'\x83','\xc0'},{'\x83','\xc1'},{'\x83','\xc2'},{'\x83','\xc3'},{'\x83','\xc4'},
+ {'\x83','\xc5'},{'\x83','\xc6'},{'\x83','\xc7'},{'\x83','\xc8'},{'\x83','\xc9'},
+ {'\x83','\xca'},{'\x83','\xcb'},{'\x83','\xcc'},{'\x83','\xcd'},{'\x83','\xce'},
+ {'\x83','\xcf'},{'\x83','\xd0'},{'\x83','\xd1'},{'\x83','\xd2'},{'\x83','\xd3'},
+ {'\x83','\xd4'},{'\x83','\xd5'},{'\x83','\xd6'},{'\x83','\xd7'},{'\x83','\xd8'},
+ {'\x83','\xd9'},{'\x83','\xda'},{'\x83','\xdb'},{'\x83','\xdc'},{'\x83','\xdd'},
+ {'\x83','\xde'},{'\x83','\xdf'},{'\x83','\xe0'},{'\x83','\xe1'},{'\x83','\xe2'},
+ {'\x83','\xe3'},{'\x83','\xe4'},{'\x83','\xe5'},{'\x83','\xe6'},{'\x83','\xe7'},
+ {'\x83','\xe8'},{'\x83','\xe9'},{'\x83','\xea'},{'\x83','\xeb'},{'\x83','\xec'},
+ {'\x83','\xed'},{'\x83','\xee'},{'\x83','\xef'},{'\x83','\xf0'},{'\x83','\xf1'},
+ {'\x83','\xf2'},{'\x83','\xf3'},{'\x83','\xf4'},{'\x83','\xf5'},{'\x83','\xf6'},
+ {'\x83','\xf7'},{'\x83','\xf8'},{'\x83','\xf9'},{'\x83','\xfa'},{'\x83','\xfb'},
+ {'\x83','\xfc'},{'\x83','\xfd'},{'\x83','\xfe'},{'\x84','\x40'},{'\x84','\x41'},
+ {'\x84','\x42'},{'\x84','\x43'},{'\x84','\x44'},{'\x84','\x45'},{'\x84','\x46'},
+ {'\x84','\x47'},{'\x84','\x48'},{'\x84','\x49'},{'\x84','\x4a'},{'\x84','\x4b'},
+ {'\x84','\x4c'},{'\x84','\x4d'},{'\x84','\x4e'},{'\x84','\x4f'},{'\x84','\x50'},
+ {'\x84','\x51'},{'\x84','\x52'},{'\x84','\x53'},{'\x84','\x54'},{'\x84','\x55'},
+ {'\x84','\x56'},{'\x84','\x57'},{'\x84','\x58'},{'\x84','\x59'},{'\x84','\x5a'},
+ {'\x84','\x5b'},{'\x84','\x5c'},{'\x84','\x5d'},{'\x84','\x5e'},{'\x84','\x5f'},
+ {'\x84','\x60'},{'\x84','\x61'},{'\x84','\x62'},{'\x84','\x63'},{'\x84','\x64'},
+ {'\x84','\x65'},{'\x84','\x66'},{'\x84','\x67'},{'\x84','\x68'},{'\x84','\x69'},
+ {'\x84','\x6a'},{'\x84','\x6b'},{'\x84','\x6c'},{'\x84','\x6d'},{'\x84','\x6e'},
+ {'\x84','\x6f'},{'\x84','\x70'},{'\x84','\x71'},{'\x84','\x72'},{'\x84','\x73'},
+ {'\x84','\x74'},{'\x84','\x75'},{'\x84','\x76'},{'\x84','\x77'},{'\x84','\x78'},
+ {'\x84','\x79'},{'\x84','\x7a'},{'\x84','\x7b'},{'\x84','\x7c'},{'\x84','\x7d'},
+ {'\x84','\x7e'},{'\x84','\xa1'},{'\x84','\xa2'},{'\x84','\xa3'},{'\x84','\xa4'},
+ {'\x84','\xa5'},{'\x84','\xa6'},{'\x84','\xa7'},{'\x84','\xa8'},{'\x84','\xa9'},
+ {'\x84','\xaa'},{'\x84','\xab'},{'\x84','\xac'},{'\x84','\xad'},{'\x84','\xae'},
+ {'\x84','\xaf'},{'\x84','\xb0'},{'\x84','\xb1'},{'\x84','\xb2'},{'\x84','\xb3'},
+ {'\x84','\xb4'},{'\x84','\xb5'},{'\x84','\xb6'},{'\x84','\xb7'},{'\x84','\xb8'},
+ {'\x84','\xb9'},{'\x84','\xba'},{'\x84','\xbb'},{'\x84','\xbc'},{'\x84','\xbd'},
+ {'\x84','\xbe'},{'\x84','\xbf'},{'\x84','\xc0'},{'\x84','\xc1'},{'\x84','\xc2'},
+ {'\x84','\xc3'},{'\x84','\xc4'},{'\x84','\xc5'},{'\x84','\xc6'},{'\x84','\xc7'},
+ {'\x84','\xc8'},{'\x84','\xc9'},{'\x84','\xca'},{'\x84','\xcb'},{'\x84','\xcc'},
+ {'\x84','\xcd'},{'\x84','\xce'},{'\x84','\xcf'},{'\x84','\xd0'},{'\x84','\xd1'},
+ {'\x84','\xd2'},{'\x84','\xd3'},{'\x84','\xd4'},{'\x84','\xd5'},{'\x84','\xd6'},
+ {'\x84','\xd7'},{'\x84','\xd8'},{'\x84','\xd9'},{'\x84','\xda'},{'\x84','\xdb'},
+ {'\x84','\xdc'},{'\x84','\xdd'},{'\x84','\xde'},{'\x84','\xdf'},{'\x84','\xe0'},
+ {'\x84','\xe1'},{'\x84','\xe2'},{'\x84','\xe3'},{'\x84','\xe4'},{'\x84','\xe5'},
+ {'\x84','\xe6'},{'\x84','\xe7'},{'\x84','\xe8'},{'\x84','\xe9'},{'\x84','\xea'},
+ {'\x84','\xeb'},{'\x84','\xec'},{'\x84','\xed'},{'\x84','\xee'},{'\x84','\xef'},
+ {'\x84','\xf0'},{'\x84','\xf1'},{'\x84','\xf2'},{'\x84','\xf3'},{'\x84','\xf4'},
+ {'\x84','\xf5'},{'\x84','\xf6'},{'\x84','\xf7'},{'\x84','\xf8'},{'\x84','\xf9'},
+ {'\x84','\xfa'},{'\x84','\xfb'},{'\x84','\xfc'},{'\x84','\xfd'},{'\x84','\xfe'},
+ {'\x85','\x40'},{'\x85','\x41'},{'\x85','\x42'},{'\x85','\x43'},{'\x85','\x44'},
+ {'\x85','\x45'},{'\x85','\x46'},{'\x85','\x47'},{'\x85','\x48'},{'\x85','\x49'},
+ {'\x85','\x4a'},{'\x85','\x4b'},{'\x85','\x4c'},{'\x85','\x4d'},{'\x85','\x4e'},
+ {'\x85','\x4f'},{'\x85','\x50'},{'\x85','\x51'},{'\x85','\x52'},{'\x85','\x53'},
+ {'\x85','\x54'},{'\x85','\x55'},{'\x85','\x56'},{'\x85','\x57'},{'\x85','\x58'},
+ {'\x85','\x59'},{'\x85','\x5a'},{'\x85','\x5b'},{'\x85','\x5c'},{'\x85','\x5d'},
+ {'\x85','\x5e'},{'\x85','\x5f'},{'\x85','\x60'},{'\x85','\x61'},{'\x85','\x62'},
+ {'\x85','\x63'},{'\x85','\x64'},{'\x85','\x65'},{'\x85','\x66'},{'\x85','\x67'},
+ {'\x85','\x68'},{'\x85','\x69'},{'\x85','\x6a'},{'\x85','\x6b'},{'\x85','\x6c'},
+ {'\x85','\x6d'},{'\x85','\x6e'},{'\x85','\x6f'},{'\x85','\x70'},{'\x85','\x71'},
+ {'\x85','\x72'},{'\x85','\x73'},{'\x85','\x74'},{'\x85','\x75'},{'\x85','\x76'},
+ {'\x85','\x77'},{'\x85','\x78'},{'\x85','\x79'},{'\x85','\x7a'},{'\x85','\x7b'},
+ {'\x85','\x7c'},{'\x85','\x7d'},{'\x85','\x7e'},{'\x85','\xa1'},{'\x85','\xa2'},
+ {'\x85','\xa3'},{'\x85','\xa4'},{'\x85','\xa5'},{'\x85','\xa6'},{'\x85','\xa7'},
+ {'\x85','\xa8'},{'\x85','\xa9'},{'\x85','\xaa'},{'\x85','\xab'},{'\x85','\xac'},
+ {'\x85','\xad'},{'\x85','\xae'},{'\x85','\xaf'},{'\x85','\xb0'},{'\x85','\xb1'},
+ {'\x85','\xb2'},{'\x85','\xb3'},{'\x85','\xb4'},{'\x85','\xb5'},{'\x85','\xb6'},
+ {'\x85','\xb7'},{'\x85','\xb8'},{'\x85','\xb9'},{'\x85','\xba'},{'\x85','\xbb'},
+ {'\x85','\xbc'},{'\x85','\xbd'},{'\x85','\xbe'},{'\x85','\xbf'},{'\x85','\xc0'},
+ {'\x85','\xc1'},{'\x85','\xc2'},{'\x85','\xc3'},{'\x85','\xc4'},{'\x85','\xc5'},
+ {'\x85','\xc6'},{'\x85','\xc7'},{'\x85','\xc8'},{'\x85','\xc9'},{'\x85','\xca'},
+ {'\x85','\xcb'},{'\x85','\xcc'},{'\x85','\xcd'},{'\x85','\xce'},{'\x85','\xcf'},
+ {'\x85','\xd0'},{'\x85','\xd1'},{'\x85','\xd2'},{'\x85','\xd3'},{'\x85','\xd4'},
+ {'\x85','\xd5'},{'\x85','\xd6'},{'\x85','\xd7'},{'\x85','\xd8'},{'\x85','\xd9'},
+ {'\x85','\xda'},{'\x85','\xdb'},{'\x85','\xdc'},{'\x85','\xdd'},{'\x85','\xde'},
+ {'\x85','\xdf'},{'\x85','\xe0'},{'\x85','\xe1'},{'\x85','\xe2'},{'\x85','\xe3'},
+ {'\x85','\xe4'},{'\x85','\xe5'},{'\x85','\xe6'},{'\x85','\xe7'},{'\x85','\xe8'},
+ {'\x85','\xe9'},{'\x85','\xea'},{'\x85','\xeb'},{'\x85','\xec'},{'\x85','\xed'},
+ {'\x85','\xee'},{'\x85','\xef'},{'\x85','\xf0'},{'\x85','\xf1'},{'\x85','\xf2'},
+ {'\x85','\xf3'},{'\x85','\xf4'},{'\x85','\xf5'},{'\x85','\xf6'},{'\x85','\xf7'},
+ {'\x85','\xf8'},{'\x85','\xf9'},{'\x85','\xfa'},{'\x85','\xfb'},{'\x85','\xfc'},
+ {'\x85','\xfd'},{'\x85','\xfe'},{'\x86','\x40'},{'\x86','\x41'},{'\x86','\x42'},
+ {'\x86','\x43'},{'\x86','\x44'},{'\x86','\x45'},{'\x86','\x46'},{'\x86','\x47'},
+ {'\x86','\x48'},{'\x86','\x49'},{'\x86','\x4a'},{'\x86','\x4b'},{'\x86','\x4c'},
+ {'\x86','\x4d'},{'\x86','\x4e'},{'\x86','\x4f'},{'\x86','\x50'},{'\x86','\x51'},
+ {'\x86','\x52'},{'\x86','\x53'},{'\x86','\x54'},{'\x86','\x55'},{'\x86','\x56'},
+ {'\x86','\x57'},{'\x86','\x58'},{'\x86','\x59'},{'\x86','\x5a'},{'\x86','\x5b'},
+ {'\x86','\x5c'},{'\x86','\x5d'},{'\x86','\x5e'},{'\x86','\x5f'},{'\x86','\x60'},
+ {'\x86','\x61'},{'\x86','\x62'},{'\x86','\x63'},{'\x86','\x64'},{'\x86','\x65'},
+ {'\x86','\x66'},{'\x86','\x67'},{'\x86','\x68'},{'\x86','\x69'},{'\x86','\x6a'},
+ {'\x86','\x6b'},{'\x86','\x6c'},{'\x86','\x6d'},{'\x86','\x6e'},{'\x86','\x6f'},
+ {'\x86','\x70'},{'\x86','\x71'},{'\x86','\x72'},{'\x86','\x73'},{'\x86','\x74'},
+ {'\x86','\x75'},{'\x86','\x76'},{'\x86','\x77'},{'\x86','\x78'},{'\x86','\x79'},
+ {'\x86','\x7a'},{'\x86','\x7b'},{'\x86','\x7c'},{'\x86','\x7d'},{'\x86','\x7e'},
+ {'\x86','\xa1'},{'\x86','\xa2'},{'\x86','\xa3'},{'\x86','\xa4'},{'\x86','\xa5'},
+ {'\x86','\xa6'},{'\x86','\xa7'},{'\x86','\xa8'},{'\x86','\xa9'},{'\x86','\xaa'},
+ {'\x86','\xab'},{'\x86','\xac'},{'\x86','\xad'},{'\x86','\xae'},{'\x86','\xaf'},
+ {'\x86','\xb0'},{'\x86','\xb1'},{'\x86','\xb2'},{'\x86','\xb3'},{'\x86','\xb4'},
+ {'\x86','\xb5'},{'\x86','\xb6'},{'\x86','\xb7'},{'\x86','\xb8'},{'\x86','\xb9'},
+ {'\x86','\xba'},{'\x86','\xbb'},{'\x86','\xbc'},{'\x86','\xbd'},{'\x86','\xbe'},
+ {'\x86','\xbf'},{'\x86','\xc0'},{'\x86','\xc1'},{'\x86','\xc2'},{'\x86','\xc3'},
+ {'\x86','\xc4'},{'\x86','\xc5'},{'\x86','\xc6'},{'\x86','\xc7'},{'\x86','\xc8'},
+ {'\x86','\xc9'},{'\x86','\xca'},{'\x86','\xcb'},{'\x86','\xcc'},{'\x86','\xcd'},
+ {'\x86','\xce'},{'\x86','\xcf'},{'\x86','\xd0'},{'\x86','\xd1'},{'\x86','\xd2'},
+ {'\x86','\xd3'},{'\x86','\xd4'},{'\x86','\xd5'},{'\x86','\xd6'},{'\x86','\xd7'},
+ {'\x86','\xd8'},{'\x86','\xd9'},{'\x86','\xda'},{'\x86','\xdb'},{'\x86','\xdc'},
+ {'\x86','\xdd'},{'\x86','\xde'},{'\x86','\xdf'},{'\x86','\xe0'},{'\x86','\xe1'},
+ {'\x86','\xe2'},{'\x86','\xe3'},{'\x86','\xe4'},{'\x86','\xe5'},{'\x86','\xe6'},
+ {'\x86','\xe7'},{'\x86','\xe8'},{'\x86','\xe9'},{'\x86','\xea'},{'\x86','\xeb'},
+ {'\x86','\xec'},{'\x86','\xed'},{'\x86','\xee'},{'\x86','\xef'},{'\x86','\xf0'},
+ {'\x86','\xf1'},{'\x86','\xf2'},{'\x86','\xf3'},{'\x86','\xf4'},{'\x86','\xf5'},
+ {'\x86','\xf6'},{'\x86','\xf7'},{'\x86','\xf8'},{'\x86','\xf9'},{'\x86','\xfa'},
+ {'\x86','\xfb'},{'\x86','\xfc'},{'\x86','\xfd'},{'\x86','\xfe'},{'\x87','\x40'},
+ {'\x87','\x41'},{'\x87','\x42'},{'\x87','\x43'},{'\x87','\x44'},{'\x87','\x45'},
+ {'\x87','\x46'},{'\x87','\x47'},{'\x87','\x48'},{'\x87','\x49'},{'\x87','\x4a'},
+ {'\x87','\x4b'},{'\x87','\x4c'},{'\x87','\x4d'},{'\x87','\x4e'},{'\x87','\x4f'},
+ {'\x87','\x50'},{'\x87','\x51'},{'\x87','\x52'},{'\x87','\x53'},{'\x87','\x54'},
+ {'\x87','\x55'},{'\x87','\x56'},{'\x87','\x57'},{'\x87','\x58'},{'\x87','\x59'},
+ {'\x87','\x5a'},{'\x87','\x5b'},{'\x87','\x5c'},{'\x87','\x5d'},{'\x87','\x5e'},
+ {'\x87','\x5f'},{'\x87','\x60'},{'\x87','\x61'},{'\x87','\x62'},{'\x87','\x63'},
+ {'\x87','\x64'},{'\x87','\x65'},{'\x87','\x66'},{'\x87','\x67'},{'\x87','\x68'},
+ {'\x87','\x69'},{'\x87','\x6a'},{'\x87','\x6b'},{'\x87','\x6c'},{'\x87','\x6d'},
+ {'\x87','\x6e'},{'\x87','\x6f'},{'\x87','\x70'},{'\x87','\x71'},{'\x87','\x72'},
+ {'\x87','\x73'},{'\x87','\x74'},{'\x87','\x75'},{'\x87','\x76'},{'\x87','\x77'},
+ {'\x87','\x78'},{'\x87','\x79'},{'\x87','\x7a'},{'\x87','\x7b'},{'\x87','\x7c'},
+ {'\x87','\x7d'},{'\x87','\x7e'},{'\x87','\xa1'},{'\x87','\xa2'},{'\x87','\xa3'},
+ {'\x87','\xa4'},{'\x87','\xa5'},{'\x87','\xa6'},{'\x87','\xa7'},{'\x87','\xa8'},
+ {'\x87','\xa9'},{'\x87','\xaa'},{'\x87','\xab'},{'\x87','\xac'},{'\x87','\xad'},
+ {'\x87','\xae'},{'\x87','\xaf'},{'\x87','\xb0'},{'\x87','\xb1'},{'\x87','\xb2'},
+ {'\x87','\xb3'},{'\x87','\xb4'},{'\x87','\xb5'},{'\x87','\xb6'},{'\x87','\xb7'},
+ {'\x87','\xb8'},{'\x87','\xb9'},{'\x87','\xba'},{'\x87','\xbb'},{'\x87','\xbc'},
+ {'\x87','\xbd'},{'\x87','\xbe'},{'\x87','\xbf'},{'\x87','\xc0'},{'\x87','\xc1'},
+ {'\x87','\xc2'},{'\x87','\xc3'},{'\x87','\xc4'},{'\x87','\xc5'},{'\x87','\xc6'},
+ {'\x87','\xc7'},{'\x87','\xc8'},{'\x87','\xc9'},{'\x87','\xca'},{'\x87','\xcb'},
+ {'\x87','\xcc'},{'\x87','\xcd'},{'\x87','\xce'},{'\x87','\xcf'},{'\x87','\xd0'},
+ {'\x87','\xd1'},{'\x87','\xd2'},{'\x87','\xd3'},{'\x87','\xd4'},{'\x87','\xd5'},
+ {'\x87','\xd6'},{'\x87','\xd7'},{'\x87','\xd8'},{'\x87','\xd9'},{'\x87','\xda'},
+ {'\x87','\xdb'},{'\x87','\xdc'},{'\x87','\xdd'},{'\x87','\xde'},{'\x87','\xdf'},
+ {'\x87','\xe0'},{'\x87','\xe1'},{'\x87','\xe2'},{'\x87','\xe3'},{'\x87','\xe4'},
+ {'\x87','\xe5'},{'\x87','\xe6'},{'\x87','\xe7'},{'\x87','\xe8'},{'\x87','\xe9'},
+ {'\x87','\xea'},{'\x87','\xeb'},{'\x87','\xec'},{'\x87','\xed'},{'\x87','\xee'},
+ {'\x87','\xef'},{'\x87','\xf0'},{'\x87','\xf1'},{'\x87','\xf2'},{'\x87','\xf3'},
+ {'\x87','\xf4'},{'\x87','\xf5'},{'\x87','\xf6'},{'\x87','\xf7'},{'\x87','\xf8'},
+ {'\x87','\xf9'},{'\x87','\xfa'},{'\x87','\xfb'},{'\x87','\xfc'},{'\x87','\xfd'},
+ {'\x87','\xfe'},{'\x88','\x40'},{'\x88','\x41'},{'\x88','\x42'},{'\x88','\x43'},
+ {'\x88','\x44'},{'\x88','\x45'},{'\x88','\x46'},{'\x88','\x47'},{'\x88','\x48'},
+ {'\x88','\x49'},{'\x88','\x4a'},{'\x88','\x4b'},{'\x88','\x4c'},{'\x88','\x4d'},
+ {'\x88','\x4e'},{'\x88','\x4f'},{'\x88','\x50'},{'\x88','\x51'},{'\x88','\x52'},
+ {'\x88','\x53'},{'\x88','\x54'},{'\x88','\x55'},{'\x88','\x56'},{'\x88','\x57'},
+ {'\x88','\x58'},{'\x88','\x59'},{'\x88','\x5a'},{'\x88','\x5b'},{'\x88','\x5c'},
+ {'\x88','\x5d'},{'\x88','\x5e'},{'\x88','\x5f'},{'\x88','\x60'},{'\x88','\x61'},
+ {'\x88','\x62'},{'\x88','\x63'},{'\x88','\x64'},{'\x88','\x65'},{'\x88','\x66'},
+ {'\x88','\x67'},{'\x88','\x68'},{'\x88','\x69'},{'\x88','\x6a'},{'\x88','\x6b'},
+ {'\x88','\x6c'},{'\x88','\x6d'},{'\x88','\x6e'},{'\x88','\x6f'},{'\x88','\x70'},
+ {'\x88','\x71'},{'\x88','\x72'},{'\x88','\x73'},{'\x88','\x74'},{'\x88','\x75'},
+ {'\x88','\x76'},{'\x88','\x77'},{'\x88','\x78'},{'\x88','\x79'},{'\x88','\x7a'},
+ {'\x88','\x7b'},{'\x88','\x7c'},{'\x88','\x7d'},{'\x88','\x7e'},{'\x88','\xa1'},
+ {'\x88','\xa2'},{'\x88','\xa3'},{'\x88','\xa4'},{'\x88','\xa5'},{'\x88','\xa6'},
+ {'\x88','\xa7'},{'\x88','\xa8'},{'\x88','\xa9'},{'\x88','\xaa'},{'\x88','\xab'},
+ {'\x88','\xac'},{'\x88','\xad'},{'\x88','\xae'},{'\x88','\xaf'},{'\x88','\xb0'},
+ {'\x88','\xb1'},{'\x88','\xb2'},{'\x88','\xb3'},{'\x88','\xb4'},{'\x88','\xb5'},
+ {'\x88','\xb6'},{'\x88','\xb7'},{'\x88','\xb8'},{'\x88','\xb9'},{'\x88','\xba'},
+ {'\x88','\xbb'},{'\x88','\xbc'},{'\x88','\xbd'},{'\x88','\xbe'},{'\x88','\xbf'},
+ {'\x88','\xc0'},{'\x88','\xc1'},{'\x88','\xc2'},{'\x88','\xc3'},{'\x88','\xc4'},
+ {'\x88','\xc5'},{'\x88','\xc6'},{'\x88','\xc7'},{'\x88','\xc8'},{'\x88','\xc9'},
+ {'\x88','\xca'},{'\x88','\xcb'},{'\x88','\xcc'},{'\x88','\xcd'},{'\x88','\xce'},
+ {'\x88','\xcf'},{'\x88','\xd0'},{'\x88','\xd1'},{'\x88','\xd2'},{'\x88','\xd3'},
+ {'\x88','\xd4'},{'\x88','\xd5'},{'\x88','\xd6'},{'\x88','\xd7'},{'\x88','\xd8'},
+ {'\x88','\xd9'},{'\x88','\xda'},{'\x88','\xdb'},{'\x88','\xdc'},{'\x88','\xdd'},
+ {'\x88','\xde'},{'\x88','\xdf'},{'\x88','\xe0'},{'\x88','\xe1'},{'\x88','\xe2'},
+ {'\x88','\xe3'},{'\x88','\xe4'},{'\x88','\xe5'},{'\x88','\xe6'},{'\x88','\xe7'},
+ {'\x88','\xe8'},{'\x88','\xe9'},{'\x88','\xea'},{'\x88','\xeb'},{'\x88','\xec'},
+ {'\x88','\xed'},{'\x88','\xee'},{'\x88','\xef'},{'\x88','\xf0'},{'\x88','\xf1'},
+ {'\x88','\xf2'},{'\x88','\xf3'},{'\x88','\xf4'},{'\x88','\xf5'},{'\x88','\xf6'},
+ {'\x88','\xf7'},{'\x88','\xf8'},{'\x88','\xf9'},{'\x88','\xfa'},{'\x88','\xfb'},
+ {'\x88','\xfc'},{'\x88','\xfd'},{'\x88','\xfe'},{'\x89','\x40'},{'\x89','\x41'},
+ {'\x89','\x42'},{'\x89','\x43'},{'\x89','\x44'},{'\x89','\x45'},{'\x89','\x46'},
+ {'\x89','\x47'},{'\x89','\x48'},{'\x89','\x49'},{'\x89','\x4a'},{'\x89','\x4b'},
+ {'\x89','\x4c'},{'\x89','\x4d'},{'\x89','\x4e'},{'\x89','\x4f'},{'\x89','\x50'},
+ {'\x89','\x51'},{'\x89','\x52'},{'\x89','\x53'},{'\x89','\x54'},{'\x89','\x55'},
+ {'\x89','\x56'},{'\x89','\x57'},{'\x89','\x58'},{'\x89','\x59'},{'\x89','\x5a'},
+ {'\x89','\x5b'},{'\x89','\x5c'},{'\x89','\x5d'},{'\x89','\x5e'},{'\x89','\x5f'},
+ {'\x89','\x60'},{'\x89','\x61'},{'\x89','\x62'},{'\x89','\x63'},{'\x89','\x64'},
+ {'\x89','\x65'},{'\x89','\x66'},{'\x89','\x67'},{'\x89','\x68'},{'\x89','\x69'},
+ {'\x89','\x6a'},{'\x89','\x6b'},{'\x89','\x6c'},{'\x89','\x6d'},{'\x89','\x6e'},
+ {'\x89','\x6f'},{'\x89','\x70'},{'\x89','\x71'},{'\x89','\x72'},{'\x89','\x73'},
+ {'\x89','\x74'},{'\x89','\x75'},{'\x89','\x76'},{'\x89','\x77'},{'\x89','\x78'},
+ {'\x89','\x79'},{'\x89','\x7a'},{'\x89','\x7b'},{'\x89','\x7c'},{'\x89','\x7d'},
+ {'\x89','\x7e'},{'\x89','\xa1'},{'\x89','\xa2'},{'\x89','\xa3'},{'\x89','\xa4'},
+ {'\x89','\xa5'},{'\x89','\xa6'},{'\x89','\xa7'},{'\x89','\xa8'},{'\x89','\xa9'},
+ {'\x89','\xaa'},{'\x89','\xab'},{'\x89','\xac'},{'\x89','\xad'},{'\x89','\xae'},
+ {'\x89','\xaf'},{'\x89','\xb0'},{'\x89','\xb1'},{'\x89','\xb2'},{'\x89','\xb3'},
+ {'\x89','\xb4'},{'\x89','\xb5'},{'\x89','\xb6'},{'\x89','\xb7'},{'\x89','\xb8'},
+ {'\x89','\xb9'},{'\x89','\xba'},{'\x89','\xbb'},{'\x89','\xbc'},{'\x89','\xbd'},
+ {'\x89','\xbe'},{'\x89','\xbf'},{'\x89','\xc0'},{'\x89','\xc1'},{'\x89','\xc2'},
+ {'\x89','\xc3'},{'\x89','\xc4'},{'\x89','\xc5'},{'\x89','\xc6'},{'\x89','\xc7'},
+ {'\x89','\xc8'},{'\x89','\xc9'},{'\x89','\xca'},{'\x89','\xcb'},{'\x89','\xcc'},
+ {'\x89','\xcd'},{'\x89','\xce'},{'\x89','\xcf'},{'\x89','\xd0'},{'\x89','\xd1'},
+ {'\x89','\xd2'},{'\x89','\xd3'},{'\x89','\xd4'},{'\x89','\xd5'},{'\x89','\xd6'},
+ {'\x89','\xd7'},{'\x89','\xd8'},{'\x89','\xd9'},{'\x89','\xda'},{'\x89','\xdb'},
+ {'\x89','\xdc'},{'\x89','\xdd'},{'\x89','\xde'},{'\x89','\xdf'},{'\x89','\xe0'},
+ {'\x89','\xe1'},{'\x89','\xe2'},{'\x89','\xe3'},{'\x89','\xe4'},{'\x89','\xe5'},
+ {'\x89','\xe6'},{'\x89','\xe7'},{'\x89','\xe8'},{'\x89','\xe9'},{'\x89','\xea'},
+ {'\x89','\xeb'},{'\x89','\xec'},{'\x89','\xed'},{'\x89','\xee'},{'\x89','\xef'},
+ {'\x89','\xf0'},{'\x89','\xf1'},{'\x89','\xf2'},{'\x89','\xf3'},{'\x89','\xf4'},
+ {'\x89','\xf5'},{'\x89','\xf6'},{'\x89','\xf7'},{'\x89','\xf8'},{'\x89','\xf9'},
+ {'\x89','\xfa'},{'\x89','\xfb'},{'\x89','\xfc'},{'\x89','\xfd'},{'\x89','\xfe'},
+ {'\x8a','\x40'},{'\x8a','\x41'},{'\x8a','\x42'},{'\x8a','\x43'},{'\x8a','\x44'},
+ {'\x8a','\x45'},{'\x8a','\x46'},{'\x8a','\x47'},{'\x8a','\x48'},{'\x8a','\x49'},
+ {'\x8a','\x4a'},{'\x8a','\x4b'},{'\x8a','\x4c'},{'\x8a','\x4d'},{'\x8a','\x4e'},
+ {'\x8a','\x4f'},{'\x8a','\x50'},{'\x8a','\x51'},{'\x8a','\x52'},{'\x8a','\x53'},
+ {'\x8a','\x54'},{'\x8a','\x55'},{'\x8a','\x56'},{'\x8a','\x57'},{'\x8a','\x58'},
+ {'\x8a','\x59'},{'\x8a','\x5a'},{'\x8a','\x5b'},{'\x8a','\x5c'},{'\x8a','\x5d'},
+ {'\x8a','\x5e'},{'\x8a','\x5f'},{'\x8a','\x60'},{'\x8a','\x61'},{'\x8a','\x62'},
+ {'\x8a','\x63'},{'\x8a','\x64'},{'\x8a','\x65'},{'\x8a','\x66'},{'\x8a','\x67'},
+ {'\x8a','\x68'},{'\x8a','\x69'},{'\x8a','\x6a'},{'\x8a','\x6b'},{'\x8a','\x6c'},
+ {'\x8a','\x6d'},{'\x8a','\x6e'},{'\x8a','\x6f'},{'\x8a','\x70'},{'\x8a','\x71'},
+ {'\x8a','\x72'},{'\x8a','\x73'},{'\x8a','\x74'},{'\x8a','\x75'},{'\x8a','\x76'},
+ {'\x8a','\x77'},{'\x8a','\x78'},{'\x8a','\x79'},{'\x8a','\x7a'},{'\x8a','\x7b'},
+ {'\x8a','\x7c'},{'\x8a','\x7d'},{'\x8a','\x7e'},{'\x8a','\xa1'},{'\x8a','\xa2'},
+ {'\x8a','\xa3'},{'\x8a','\xa4'},{'\x8a','\xa5'},{'\x8a','\xa6'},{'\x8a','\xa7'},
+ {'\x8a','\xa8'},{'\x8a','\xa9'},{'\x8a','\xaa'},{'\x8a','\xab'},{'\x8a','\xac'},
+ {'\x8a','\xad'},{'\x8a','\xae'},{'\x8a','\xaf'},{'\x8a','\xb0'},{'\x8a','\xb1'},
+ {'\x8a','\xb2'},{'\x8a','\xb3'},{'\x8a','\xb4'},{'\x8a','\xb5'},{'\x8a','\xb6'},
+ {'\x8a','\xb7'},{'\x8a','\xb8'},{'\x8a','\xb9'},{'\x8a','\xba'},{'\x8a','\xbb'},
+ {'\x8a','\xbc'},{'\x8a','\xbd'},{'\x8a','\xbe'},{'\x8a','\xbf'},{'\x8a','\xc0'},
+ {'\x8a','\xc1'},{'\x8a','\xc2'},{'\x8a','\xc3'},{'\x8a','\xc4'},{'\x8a','\xc5'},
+ {'\x8a','\xc6'},{'\x8a','\xc7'},{'\x8a','\xc8'},{'\x8a','\xc9'},{'\x8a','\xca'},
+ {'\x8a','\xcb'},{'\x8a','\xcc'},{'\x8a','\xcd'},{'\x8a','\xce'},{'\x8a','\xcf'},
+ {'\x8a','\xd0'},{'\x8a','\xd1'},{'\x8a','\xd2'},{'\x8a','\xd3'},{'\x8a','\xd4'},
+ {'\x8a','\xd5'},{'\x8a','\xd6'},{'\x8a','\xd7'},{'\x8a','\xd8'},{'\x8a','\xd9'},
+ {'\x8a','\xda'},{'\x8a','\xdb'},{'\x8a','\xdc'},{'\x8a','\xdd'},{'\x8a','\xde'},
+ {'\x8a','\xdf'},{'\x8a','\xe0'},{'\x8a','\xe1'},{'\x8a','\xe2'},{'\x8a','\xe3'},
+ {'\x8a','\xe4'},{'\x8a','\xe5'},{'\x8a','\xe6'},{'\x8a','\xe7'},{'\x8a','\xe8'},
+ {'\x8a','\xe9'},{'\x8a','\xea'},{'\x8a','\xeb'},{'\x8a','\xec'},{'\x8a','\xed'},
+ {'\x8a','\xee'},{'\x8a','\xef'},{'\x8a','\xf0'},{'\x8a','\xf1'},{'\x8a','\xf2'},
+ {'\x8a','\xf3'},{'\x8a','\xf4'},{'\x8a','\xf5'},{'\x8a','\xf6'},{'\x8a','\xf7'},
+ {'\x8a','\xf8'},{'\x8a','\xf9'},{'\x8a','\xfa'},{'\x8a','\xfb'},{'\x8a','\xfc'},
+ {'\x8a','\xfd'},{'\x8a','\xfe'},{'\x8b','\x40'},{'\x8b','\x41'},{'\x8b','\x42'},
+ {'\x8b','\x43'},{'\x8b','\x44'},{'\x8b','\x45'},{'\x8b','\x46'},{'\x8b','\x47'},
+ {'\x8b','\x48'},{'\x8b','\x49'},{'\x8b','\x4a'},{'\x8b','\x4b'},{'\x8b','\x4c'},
+ {'\x8b','\x4d'},{'\x8b','\x4e'},{'\x8b','\x4f'},{'\x8b','\x50'},{'\x8b','\x51'},
+ {'\x8b','\x52'},{'\x8b','\x53'},{'\x8b','\x54'},{'\x8b','\x55'},{'\x8b','\x56'},
+ {'\x8b','\x57'},{'\x8b','\x58'},{'\x8b','\x59'},{'\x8b','\x5a'},{'\x8b','\x5b'},
+ {'\x8b','\x5c'},{'\x8b','\x5d'},{'\x8b','\x5e'},{'\x8b','\x5f'},{'\x8b','\x60'},
+ {'\x8b','\x61'},{'\x8b','\x62'},{'\x8b','\x63'},{'\x8b','\x64'},{'\x8b','\x65'},
+ {'\x8b','\x66'},{'\x8b','\x67'},{'\x8b','\x68'},{'\x8b','\x69'},{'\x8b','\x6a'},
+ {'\x8b','\x6b'},{'\x8b','\x6c'},{'\x8b','\x6d'},{'\x8b','\x6e'},{'\x8b','\x6f'},
+ {'\x8b','\x70'},{'\x8b','\x71'},{'\x8b','\x72'},{'\x8b','\x73'},{'\x8b','\x74'},
+ {'\x8b','\x75'},{'\x8b','\x76'},{'\x8b','\x77'},{'\x8b','\x78'},{'\x8b','\x79'},
+ {'\x8b','\x7a'},{'\x8b','\x7b'},{'\x8b','\x7c'},{'\x8b','\x7d'},{'\x8b','\x7e'},
+ {'\x8b','\xa1'},{'\x8b','\xa2'},{'\x8b','\xa3'},{'\x8b','\xa4'},{'\x8b','\xa5'},
+ {'\x8b','\xa6'},{'\x8b','\xa7'},{'\x8b','\xa8'},{'\x8b','\xa9'},{'\x8b','\xaa'},
+ {'\x8b','\xab'},{'\x8b','\xac'},{'\x8b','\xad'},{'\x8b','\xae'},{'\x8b','\xaf'},
+ {'\x8b','\xb0'},{'\x8b','\xb1'},{'\x8b','\xb2'},{'\x8b','\xb3'},{'\x8b','\xb4'},
+ {'\x8b','\xb5'},{'\x8b','\xb6'},{'\x8b','\xb7'},{'\x8b','\xb8'},{'\x8b','\xb9'},
+ {'\x8b','\xba'},{'\x8b','\xbb'},{'\x8b','\xbc'},{'\x8b','\xbd'},{'\x8b','\xbe'},
+ {'\x8b','\xbf'},{'\x8b','\xc0'},{'\x8b','\xc1'},{'\x8b','\xc2'},{'\x8b','\xc3'},
+ {'\x8b','\xc4'},{'\x8b','\xc5'},{'\x8b','\xc6'},{'\x8b','\xc7'},{'\x8b','\xc8'},
+ {'\x8b','\xc9'},{'\x8b','\xca'},{'\x8b','\xcb'},{'\x8b','\xcc'},{'\x8b','\xcd'},
+ {'\x8b','\xce'},{'\x8b','\xcf'},{'\x8b','\xd0'},{'\x8b','\xd1'},{'\x8b','\xd2'},
+ {'\x8b','\xd3'},{'\x8b','\xd4'},{'\x8b','\xd5'},{'\x8b','\xd6'},{'\x8b','\xd7'},
+ {'\x8b','\xd8'},{'\x8b','\xd9'},{'\x8b','\xda'},{'\x8b','\xdb'},{'\x8b','\xdc'},
+ {'\x8b','\xdd'},{'\x8b','\xde'},{'\x8b','\xdf'},{'\x8b','\xe0'},{'\x8b','\xe1'},
+ {'\x8b','\xe2'},{'\x8b','\xe3'},{'\x8b','\xe4'},{'\x8b','\xe5'},{'\x8b','\xe6'},
+ {'\x8b','\xe7'},{'\x8b','\xe8'},{'\x8b','\xe9'},{'\x8b','\xea'},{'\x8b','\xeb'},
+ {'\x8b','\xec'},{'\x8b','\xed'},{'\x8b','\xee'},{'\x8b','\xef'},{'\x8b','\xf0'},
+ {'\x8b','\xf1'},{'\x8b','\xf2'},{'\x8b','\xf3'},{'\x8b','\xf4'},{'\x8b','\xf5'},
+ {'\x8b','\xf6'},{'\x8b','\xf7'},{'\x8b','\xf8'},{'\x8b','\xf9'},{'\x8b','\xfa'},
+ {'\x8b','\xfb'},{'\x8b','\xfc'},{'\x8b','\xfd'},{'\x8b','\xfe'},{'\x8c','\x40'},
+ {'\x8c','\x41'},{'\x8c','\x42'},{'\x8c','\x43'},{'\x8c','\x44'},{'\x8c','\x45'},
+ {'\x8c','\x46'},{'\x8c','\x47'},{'\x8c','\x48'},{'\x8c','\x49'},{'\x8c','\x4a'},
+ {'\x8c','\x4b'},{'\x8c','\x4c'},{'\x8c','\x4d'},{'\x8c','\x4e'},{'\x8c','\x4f'},
+ {'\x8c','\x50'},{'\x8c','\x51'},{'\x8c','\x52'},{'\x8c','\x53'},{'\x8c','\x54'},
+ {'\x8c','\x55'},{'\x8c','\x56'},{'\x8c','\x57'},{'\x8c','\x58'},{'\x8c','\x59'},
+ {'\x8c','\x5a'},{'\x8c','\x5b'},{'\x8c','\x5c'},{'\x8c','\x5d'},{'\x8c','\x5e'},
+ {'\x8c','\x5f'},{'\x8c','\x60'},{'\x8c','\x61'},{'\x8c','\x62'},{'\x8c','\x63'},
+ {'\x8c','\x64'},{'\x8c','\x65'},{'\x8c','\x66'},{'\x8c','\x67'},{'\x8c','\x68'},
+ {'\x8c','\x69'},{'\x8c','\x6a'},{'\x8c','\x6b'},{'\x8c','\x6c'},{'\x8c','\x6d'},
+ {'\x8c','\x6e'},{'\x8c','\x6f'},{'\x8c','\x70'},{'\x8c','\x71'},{'\x8c','\x72'},
+ {'\x8c','\x73'},{'\x8c','\x74'},{'\x8c','\x75'},{'\x8c','\x76'},{'\x8c','\x77'},
+ {'\x8c','\x78'},{'\x8c','\x79'},{'\x8c','\x7a'},{'\x8c','\x7b'},{'\x8c','\x7c'},
+ {'\x8c','\x7d'},{'\x8c','\x7e'},{'\x8c','\xa1'},{'\x8c','\xa2'},{'\x8c','\xa3'},
+ {'\x8c','\xa4'},{'\x8c','\xa5'},{'\x8c','\xa6'},{'\x8c','\xa7'},{'\x8c','\xa8'},
+ {'\x8c','\xa9'},{'\x8c','\xaa'},{'\x8c','\xab'},{'\x8c','\xac'},{'\x8c','\xad'},
+ {'\x8c','\xae'},{'\x8c','\xaf'},{'\x8c','\xb0'},{'\x8c','\xb1'},{'\x8c','\xb2'},
+ {'\x8c','\xb3'},{'\x8c','\xb4'},{'\x8c','\xb5'},{'\x8c','\xb6'},{'\x8c','\xb7'},
+ {'\x8c','\xb8'},{'\x8c','\xb9'},{'\x8c','\xba'},{'\x8c','\xbb'},{'\x8c','\xbc'},
+ {'\x8c','\xbd'},{'\x8c','\xbe'},{'\x8c','\xbf'},{'\x8c','\xc0'},{'\x8c','\xc1'},
+ {'\x8c','\xc2'},{'\x8c','\xc3'},{'\x8c','\xc4'},{'\x8c','\xc5'},{'\x8c','\xc6'},
+ {'\x8c','\xc7'},{'\x8c','\xc8'},{'\x8c','\xc9'},{'\x8c','\xca'},{'\x8c','\xcb'},
+ {'\x8c','\xcc'},{'\x8c','\xcd'},{'\x8c','\xce'},{'\x8c','\xcf'},{'\x8c','\xd0'},
+ {'\x8c','\xd1'},{'\x8c','\xd2'},{'\x8c','\xd3'},{'\x8c','\xd4'},{'\x8c','\xd5'},
+ {'\x8c','\xd6'},{'\x8c','\xd7'},{'\x8c','\xd8'},{'\x8c','\xd9'},{'\x8c','\xda'},
+ {'\x8c','\xdb'},{'\x8c','\xdc'},{'\x8c','\xdd'},{'\x8c','\xde'},{'\x8c','\xdf'},
+ {'\x8c','\xe0'},{'\x8c','\xe1'},{'\x8c','\xe2'},{'\x8c','\xe3'},{'\x8c','\xe4'},
+ {'\x8c','\xe5'},{'\x8c','\xe6'},{'\x8c','\xe7'},{'\x8c','\xe8'},{'\x8c','\xe9'},
+ {'\x8c','\xea'},{'\x8c','\xeb'},{'\x8c','\xec'},{'\x8c','\xed'},{'\x8c','\xee'},
+ {'\x8c','\xef'},{'\x8c','\xf0'},{'\x8c','\xf1'},{'\x8c','\xf2'},{'\x8c','\xf3'},
+ {'\x8c','\xf4'},{'\x8c','\xf5'},{'\x8c','\xf6'},{'\x8c','\xf7'},{'\x8c','\xf8'},
+ {'\x8c','\xf9'},{'\x8c','\xfa'},{'\x8c','\xfb'},{'\x8c','\xfc'},{'\x8c','\xfd'},
+ {'\x8c','\xfe'},{'\x8d','\x40'},{'\x8d','\x41'},{'\x8d','\x42'},{'\x8d','\x43'},
+ {'\x8d','\x44'},{'\x8d','\x45'},{'\x8d','\x46'},{'\x8d','\x47'},{'\x8d','\x48'},
+ {'\x8d','\x49'},{'\x8d','\x4a'},{'\x8d','\x4b'},{'\x8d','\x4c'},{'\x8d','\x4d'},
+ {'\x8d','\x4e'},{'\x8d','\x4f'},{'\x8d','\x50'},{'\x8d','\x51'},{'\x8d','\x52'},
+ {'\x8d','\x53'},{'\x8d','\x54'},{'\x8d','\x55'},{'\x8d','\x56'},{'\x8d','\x57'},
+ {'\x8d','\x58'},{'\x8d','\x59'},{'\x8d','\x5a'},{'\x8d','\x5b'},{'\x8d','\x5c'},
+ {'\x8d','\x5d'},{'\x8d','\x5e'},{'\x8d','\x5f'},{'\x8d','\x60'},{'\x8d','\x61'},
+ {'\x8d','\x62'},{'\x8d','\x63'},{'\x8d','\x64'},{'\x8d','\x65'},{'\x8d','\x66'},
+ {'\x8d','\x67'},{'\x8d','\x68'},{'\x8d','\x69'},{'\x8d','\x6a'},{'\x8d','\x6b'},
+ {'\x8d','\x6c'},{'\x8d','\x6d'},{'\x8d','\x6e'},{'\x8d','\x6f'},{'\x8d','\x70'},
+ {'\x8d','\x71'},{'\x8d','\x72'},{'\x8d','\x73'},{'\x8d','\x74'},{'\x8d','\x75'},
+ {'\x8d','\x76'},{'\x8d','\x77'},{'\x8d','\x78'},{'\x8d','\x79'},{'\x8d','\x7a'},
+ {'\x8d','\x7b'},{'\x8d','\x7c'},{'\x8d','\x7d'},{'\x8d','\x7e'},{'\x8d','\xa1'},
+ {'\x8d','\xa2'},{'\x8d','\xa3'},{'\x8d','\xa4'},{'\x8d','\xa5'},{'\x8d','\xa6'},
+ {'\x8d','\xa7'},{'\x8d','\xa8'},{'\x8d','\xa9'},{'\x8d','\xaa'},{'\x8d','\xab'},
+ {'\x8d','\xac'},{'\x8d','\xad'},{'\x8d','\xae'},{'\x8d','\xaf'},{'\x8d','\xb0'},
+ {'\x8d','\xb1'},{'\x8d','\xb2'},{'\x8d','\xb3'},{'\x8d','\xb4'},{'\x8d','\xb5'},
+ {'\x8d','\xb6'},{'\x8d','\xb7'},{'\x8d','\xb8'},{'\x8d','\xb9'},{'\x8d','\xba'},
+ {'\x8d','\xbb'},{'\x8d','\xbc'},{'\x8d','\xbd'},{'\x8d','\xbe'},{'\x8d','\xbf'},
+ {'\x8d','\xc0'},{'\x8d','\xc1'},{'\x8d','\xc2'},{'\x8d','\xc3'},{'\x8d','\xc4'},
+ {'\x8d','\xc5'},{'\x8d','\xc6'},{'\x8d','\xc7'},{'\x8d','\xc8'},{'\x8d','\xc9'},
+ {'\x8d','\xca'},{'\x8d','\xcb'},{'\x8d','\xcc'},{'\x8d','\xcd'},{'\x8d','\xce'},
+ {'\x8d','\xcf'},{'\x8d','\xd0'},{'\x8d','\xd1'},{'\x8d','\xd2'},{'\x8d','\xd3'},
+ {'\x8d','\xd4'},{'\x8d','\xd5'},{'\x8d','\xd6'},{'\x8d','\xd7'},{'\x8d','\xd8'},
+ {'\x8d','\xd9'},{'\x8d','\xda'},{'\x8d','\xdb'},{'\x8d','\xdc'},{'\x8d','\xdd'},
+ {'\x8d','\xde'},{'\x8d','\xdf'},{'\x8d','\xe0'},{'\x8d','\xe1'},{'\x8d','\xe2'},
+ {'\x8d','\xe3'},{'\x8d','\xe4'},{'\x8d','\xe5'},{'\x8d','\xe6'},{'\x8d','\xe7'},
+ {'\x8d','\xe8'},{'\x8d','\xe9'},{'\x8d','\xea'},{'\x8d','\xeb'},{'\x8d','\xec'},
+ {'\x8d','\xed'},{'\x8d','\xee'},{'\x8d','\xef'},{'\x8d','\xf0'},{'\x8d','\xf1'},
+ {'\x8d','\xf2'},{'\x8d','\xf3'},{'\x8d','\xf4'},{'\x8d','\xf5'},{'\x8d','\xf6'},
+ {'\x8d','\xf7'},{'\x8d','\xf8'},{'\x8d','\xf9'},{'\x8d','\xfa'},{'\x8d','\xfb'},
+ {'\x8d','\xfc'},{'\x8d','\xfd'},{'\x8d','\xfe'},{'\xc6','\xa1'},{'\xc6','\xa2'},
+ {'\xc6','\xa3'},{'\xc6','\xa4'},{'\xc6','\xa5'},{'\xc6','\xa6'},{'\xc6','\xa7'},
+ {'\xc6','\xa8'},{'\xc6','\xa9'},{'\xc6','\xaa'},{'\xc6','\xab'},{'\xc6','\xac'},
+ {'\xc6','\xad'},{'\xc6','\xae'},{'\xc6','\xaf'},{'\xc6','\xb0'},{'\xc6','\xb1'},
+ {'\xc6','\xb2'},{'\xc6','\xb3'},{'\xc6','\xb4'},{'\xc6','\xb5'},{'\xc6','\xb6'},
+ {'\xc6','\xb7'},{'\xc6','\xb8'},{'\xc6','\xb9'},{'\xc6','\xba'},{'\xc6','\xbb'},
+ {'\xc6','\xbc'},{'\xc6','\xbd'},{'\xc6','\xbe'},{'\xc6','\xbf'},{'\xc6','\xc0'},
+ {'\xc6','\xc1'},{'\xc6','\xc2'},{'\xc6','\xc3'},{'\xc6','\xc4'},{'\xc6','\xc5'},
+ {'\xc6','\xc6'},{'\xc6','\xc7'},{'\xc6','\xc8'},{'\xc6','\xc9'},{'\xc6','\xca'},
+ {'\xc6','\xcb'},{'\xc6','\xcc'},{'\xc6','\xcd'},{'\xc6','\xce'},{'\xc6','\xcf'},
+ {'\xc6','\xd0'},{'\xc6','\xd1'},{'\xc6','\xd2'},{'\xc6','\xd3'},{'\xc6','\xd4'},
+ {'\xc6','\xd5'},{'\xc6','\xd6'},{'\xc6','\xd7'},{'\xc6','\xd8'},{'\xc6','\xd9'},
+ {'\xc6','\xda'},{'\xc6','\xdb'},{'\xc6','\xdc'},{'\xc6','\xdd'},{'\xc6','\xde'},
+ {'\xc6','\xdf'},{'\xc6','\xe0'},{'\xc6','\xe1'},{'\xc6','\xe2'},{'\xc6','\xe3'},
+ {'\xc6','\xe4'},{'\xc6','\xe5'},{'\xc6','\xe6'},{'\xc6','\xe7'},{'\xc6','\xe8'},
+ {'\xc6','\xe9'},{'\xc6','\xea'},{'\xc6','\xeb'},{'\xc6','\xec'},{'\xc6','\xed'},
+ {'\xc6','\xee'},{'\xc6','\xef'},{'\xc6','\xf0'},{'\xc6','\xf1'},{'\xc6','\xf2'},
+ {'\xc6','\xf3'},{'\xc6','\xf4'},{'\xc6','\xf5'},{'\xc6','\xf6'},{'\xc6','\xf7'},
+ {'\xc6','\xf8'},{'\xc6','\xf9'},{'\xc6','\xfa'},{'\xc6','\xfb'},{'\xc6','\xfc'},
+ {'\xc6','\xfd'},{'\xc6','\xfe'},{'\xc7','\x40'},{'\xc7','\x41'},{'\xc7','\x42'},
+ {'\xc7','\x43'},{'\xc7','\x44'},{'\xc7','\x45'},{'\xc7','\x46'},{'\xc7','\x47'},
+ {'\xc7','\x48'},{'\xc7','\x49'},{'\xc7','\x4a'},{'\xc7','\x4b'},{'\xc7','\x4c'},
+ {'\xc7','\x4d'},{'\xc7','\x4e'},{'\xc7','\x4f'},{'\xc7','\x50'},{'\xc7','\x51'},
+ {'\xc7','\x52'},{'\xc7','\x53'},{'\xc7','\x54'},{'\xc7','\x55'},{'\xc7','\x56'},
+ {'\xc7','\x57'},{'\xc7','\x58'},{'\xc7','\x59'},{'\xc7','\x5a'},{'\xc7','\x5b'},
+ {'\xc7','\x5c'},{'\xc7','\x5d'},{'\xc7','\x5e'},{'\xc7','\x5f'},{'\xc7','\x60'},
+ {'\xc7','\x61'},{'\xc7','\x62'},{'\xc7','\x63'},{'\xc7','\x64'},{'\xc7','\x65'},
+ {'\xc7','\x66'},{'\xc7','\x67'},{'\xc7','\x68'},{'\xc7','\x69'},{'\xc7','\x6a'},
+ {'\xc7','\x6b'},{'\xc7','\x6c'},{'\xc7','\x6d'},{'\xc7','\x6e'},{'\xc7','\x6f'},
+ {'\xc7','\x70'},{'\xc7','\x71'},{'\xc7','\x72'},{'\xc7','\x73'},{'\xc7','\x74'},
+ {'\xc7','\x75'},{'\xc7','\x76'},{'\xc7','\x77'},{'\xc7','\x78'},{'\xc7','\x79'},
+ {'\xc7','\x7a'},{'\xc7','\x7b'},{'\xc7','\x7c'},{'\xc7','\x7d'},{'\xc7','\x7e'},
+ {'\xc7','\xa1'},{'\xc7','\xa2'},{'\xc7','\xa3'},{'\xc7','\xa4'},{'\xc7','\xa5'},
+ {'\xc7','\xa6'},{'\xc7','\xa7'},{'\xc7','\xa8'},{'\xc7','\xa9'},{'\xc7','\xaa'},
+ {'\xc7','\xab'},{'\xc7','\xac'},{'\xc7','\xad'},{'\xc7','\xae'},{'\xc7','\xaf'},
+ {'\xc7','\xb0'},{'\xc7','\xb1'},{'\xc7','\xb2'},{'\xc7','\xb3'},{'\xc7','\xb4'},
+ {'\xc7','\xb5'},{'\xc7','\xb6'},{'\xc7','\xb7'},{'\xc7','\xb8'},{'\xc7','\xb9'},
+ {'\xc7','\xba'},{'\xc7','\xbb'},{'\xc7','\xbc'},{'\xc7','\xbd'},{'\xc7','\xbe'},
+ {'\xc7','\xbf'},{'\xc7','\xc0'},{'\xc7','\xc1'},{'\xc7','\xc2'},{'\xc7','\xc3'},
+ {'\xc7','\xc4'},{'\xc7','\xc5'},{'\xc7','\xc6'},{'\xc7','\xc7'},{'\xc7','\xc8'},
+ {'\xc7','\xc9'},{'\xc7','\xca'},{'\xc7','\xcb'},{'\xc7','\xcc'},{'\xc7','\xcd'},
+ {'\xc7','\xce'},{'\xc7','\xcf'},{'\xc7','\xd0'},{'\xc7','\xd1'},{'\xc7','\xd2'},
+ {'\xc7','\xd3'},{'\xc7','\xd4'},{'\xc7','\xd5'},{'\xc7','\xd6'},{'\xc7','\xd7'},
+ {'\xc7','\xd8'},{'\xc7','\xd9'},{'\xc7','\xda'},{'\xc7','\xdb'},{'\xc7','\xdc'},
+ {'\xc7','\xdd'},{'\xc7','\xde'},{'\xc7','\xdf'},{'\xc7','\xe0'},{'\xc7','\xe1'},
+ {'\xc7','\xe2'},{'\xc7','\xe3'},{'\xc7','\xe4'},{'\xc7','\xe5'},{'\xc7','\xe6'},
+ {'\xc7','\xe7'},{'\xc7','\xe8'},{'\xc7','\xe9'},{'\xc7','\xea'},{'\xc7','\xeb'},
+ {'\xc7','\xec'},{'\xc7','\xed'},{'\xc7','\xee'},{'\xc7','\xef'},{'\xc7','\xf0'},
+ {'\xc7','\xf1'},{'\xc7','\xf2'},{'\xc7','\xf3'},{'\xc7','\xf4'},{'\xc7','\xf5'},
+ {'\xc7','\xf6'},{'\xc7','\xf7'},{'\xc7','\xf8'},{'\xc7','\xf9'},{'\xc7','\xfa'},
+ {'\xc7','\xfb'},{'\xc7','\xfc'},{'\xc7','\xfd'},{'\xc7','\xfe'},{'\xc8','\x40'},
+ {'\xc8','\x41'},{'\xc8','\x42'},{'\xc8','\x43'},{'\xc8','\x44'},{'\xc8','\x45'},
+ {'\xc8','\x46'},{'\xc8','\x47'},{'\xc8','\x48'},{'\xc8','\x49'},{'\xc8','\x4a'},
+ {'\xc8','\x4b'},{'\xc8','\x4c'},{'\xc8','\x4d'},{'\xc8','\x4e'},{'\xc8','\x4f'},
+ {'\xc8','\x50'},{'\xc8','\x51'},{'\xc8','\x52'},{'\xc8','\x53'},{'\xc8','\x54'},
+ {'\xc8','\x55'},{'\xc8','\x56'},{'\xc8','\x57'},{'\xc8','\x58'},{'\xc8','\x59'},
+ {'\xc8','\x5a'},{'\xc8','\x5b'},{'\xc8','\x5c'},{'\xc8','\x5d'},{'\xc8','\x5e'},
+ {'\xc8','\x5f'},{'\xc8','\x60'},{'\xc8','\x61'},{'\xc8','\x62'},{'\xc8','\x63'},
+ {'\xc8','\x64'},{'\xc8','\x65'},{'\xc8','\x66'},{'\xc8','\x67'},{'\xc8','\x68'},
+ {'\xc8','\x69'},{'\xc8','\x6a'},{'\xc8','\x6b'},{'\xc8','\x6c'},{'\xc8','\x6d'},
+ {'\xc8','\x6e'},{'\xc8','\x6f'},{'\xc8','\x70'},{'\xc8','\x71'},{'\xc8','\x72'},
+ {'\xc8','\x73'},{'\xc8','\x74'},{'\xc8','\x75'},{'\xc8','\x76'},{'\xc8','\x77'},
+ {'\xc8','\x78'},{'\xc8','\x79'},{'\xc8','\x7a'},{'\xc8','\x7b'},{'\xc8','\x7c'},
+ {'\xc8','\x7d'},{'\xc8','\x7e'},{'\xc8','\xa1'},{'\xc8','\xa2'},{'\xc8','\xa3'},
+ {'\xc8','\xa4'},{'\xc8','\xa5'},{'\xc8','\xa6'},{'\xc8','\xa7'},{'\xc8','\xa8'},
+ {'\xc8','\xa9'},{'\xc8','\xaa'},{'\xc8','\xab'},{'\xc8','\xac'},{'\xc8','\xad'},
+ {'\xc8','\xae'},{'\xc8','\xaf'},{'\xc8','\xb0'},{'\xc8','\xb1'},{'\xc8','\xb2'},
+ {'\xc8','\xb3'},{'\xc8','\xb4'},{'\xc8','\xb5'},{'\xc8','\xb6'},{'\xc8','\xb7'},
+ {'\xc8','\xb8'},{'\xc8','\xb9'},{'\xc8','\xba'},{'\xc8','\xbb'},{'\xc8','\xbc'},
+ {'\xc8','\xbd'},{'\xc8','\xbe'},{'\xc8','\xbf'},{'\xc8','\xc0'},{'\xc8','\xc1'},
+ {'\xc8','\xc2'},{'\xc8','\xc3'},{'\xc8','\xc4'},{'\xc8','\xc5'},{'\xc8','\xc6'},
+ {'\xc8','\xc7'},{'\xc8','\xc8'},{'\xc8','\xc9'},{'\xc8','\xca'},{'\xc8','\xcb'},
+ {'\xc8','\xcc'},{'\xc8','\xcd'},{'\xc8','\xce'},{'\xc8','\xcf'},{'\xc8','\xd0'},
+ {'\xc8','\xd1'},{'\xc8','\xd2'},{'\xc8','\xd3'},{'\xc8','\xd4'},{'\xc8','\xd5'},
+ {'\xc8','\xd6'},{'\xc8','\xd7'},{'\xc8','\xd8'},{'\xc8','\xd9'},{'\xc8','\xda'},
+ {'\xc8','\xdb'},{'\xc8','\xdc'},{'\xc8','\xdd'},{'\xc8','\xde'},{'\xc8','\xdf'},
+ {'\xc8','\xe0'},{'\xc8','\xe1'},{'\xc8','\xe2'},{'\xc8','\xe3'},{'\xc8','\xe4'},
+ {'\xc8','\xe5'},{'\xc8','\xe6'},{'\xc8','\xe7'},{'\xc8','\xe8'},{'\xc8','\xe9'},
+ {'\xc8','\xea'},{'\xc8','\xeb'},{'\xc8','\xec'},{'\xc8','\xed'},{'\xc8','\xee'},
+ {'\xc8','\xef'},{'\xc8','\xf0'},{'\xc8','\xf1'},{'\xc8','\xf2'},{'\xc8','\xf3'},
+ {'\xc8','\xf4'},{'\xc8','\xf5'},{'\xc8','\xf6'},{'\xc8','\xf7'},{'\xc8','\xf8'},
+ {'\xc8','\xf9'},{'\xc8','\xfa'},{'\xc8','\xfb'},{'\xc8','\xfc'},{'\xc8','\xfd'},
+ {'\xc8','\xfe'},{'\xa3','\xe2'},{'\xa3','\xe3'},{'\xa3','\xe4'},{'\xa3','\xe5'},
+ {'\xa3','\xe6'},{'\xa3','\xe7'},{'\xa3','\xe8'},{'\xa3','\xe9'},{'\xa3','\xea'},
+ {'\xa3','\xeb'},{'\xa3','\xec'},{'\xa3','\xed'},{'\xa3','\xee'},{'\xa3','\xef'},
+ {'\xa3','\xf0'},{'\xa3','\xf1'},{'\xa3','\xf2'},{'\xa3','\xf3'},{'\xa3','\xf4'},
+ {'\xa3','\xf5'},{'\xa3','\xf6'},{'\xa3','\xf7'},{'\xa3','\xf8'},{'\xa3','\xf9'},
+ {'\xa3','\xfa'},{'\xa3','\xfb'},{'\xa3','\xfc'},{'\xa3','\xfd'},{'\xa3','\xfe'},
+ {'\xc6','\xde'},{'\xc6','\xdf'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\xff'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xb0','\x5a'},
+ {'\xa7','\xf3'},{'\xa8','\xae'},{'\xb8','\xeb'},{'\xb7','\xc6'},{'\xa6','\xea'},
+ {'\xa5','\x79'},{'\xc0','\x74'},{'\xc0','\x74'},{'\xab','\xb4'},{'\xaa','\xf7'},
+ {'\xb3','\xe2'},{'\xa9','\x60'},{'\xc3','\x69'},{'\xc4','\xee'},{'\xc3','\xb9'},
+ {'\xc5','\xda'},{'\xc1','\xb3'},{'\xbb','\x72'},{'\xc5','\xde'},{'\xbc','\xd6'},
+ {'\xac','\xa5'},{'\xaf','\x4f'},{'\xaf','\x5f'},{'\xb8','\xa8'},{'\xb9','\x54'},
+ {'\xc0','\x64'},{'\xb6','\xc3'},{'\xa7','\x5a'},{'\xc4','\xe6'},{'\xc4','\xea'},
+ {'\xc4','\xf5'},{'\xc6','\x7d'},{'\xb4','\x50'},{'\xc0','\xdd'},{'\xc2','\xc5'},
+ {'\xc4','\xb0'},{'\xa9','\xd4'},{'\xc3','\xbe'},{'\xc4','\xfa'},{'\xb4','\x59'},
+ {'\xae','\xd4'},{'\xae','\xf6'},{'\xaf','\x54'},{'\xad','\xa6'},{'\xa8','\xd3'},
+ {'\xa7','\x4e'},{'\xb3','\xd2'},{'\xbe','\xdb'},{'\xc3','\x72'},{'\xc4','\x6c'},
+ {'\xbf','\x63'},{'\xa6','\xd1'},{'\xc4','\xaa'},{'\xb8','\xb8'},{'\xb8','\xf4'},
+ {'\xc5','\x53'},{'\xbe','\x7c'},{'\xc6','\x4f'},{'\xb8','\x4c'},{'\xb8','\x53'},
+ {'\xba','\xf1'},{'\xdb','\x77'},{'\xbf','\xfd'},{'\xb3','\xc0'},{'\xbd','\xd7'},
+ {'\xc3','\x62'},{'\xa7','\xcb'},{'\xc5','\xa2'},{'\xc5','\xa4'},{'\xa8','\x63'},
+ {'\xbd','\x55'},{'\xb8','\xef'},{'\xb9','\x70'},{'\xc2','\x53'},{'\xb9','\xf0'},
+ {'\xbc','\xd3'},{'\xb2','\x5c'},{'\xba','\x7c'},{'\xb2','\xd6'},{'\xc1','\x5c'},
+ {'\xad','\xae'},{'\xb0','\xc7'},{'\xa6','\xd8'},{'\xbb','\xfe'},{'\xad','\xe2'},
+ {'\xb8','\x57'},{'\xba','\xf0'},{'\xb5','\xd9'},{'\xb3','\xae'},{'\xc5','\xaa'},
+ {'\xce','\xd4'},{'\xbc','\xd6'},{'\xbf','\xd5'},{'\xa4','\xa6'},{'\xb9','\xe7'},
+ {'\xab','\xe3'},{'\xb2','\x76'},{'\xb2','\xa7'},{'\xa5','\x5f'},{'\xed','\xa8'},
+ {'\xab','\x4b'},{'\xb4','\x5f'},{'\xa4','\xa3'},{'\xaa','\x63'},{'\xbc','\xc6'},
+ {'\xaf','\xc1'},{'\xb0','\xd1'},{'\xb6','\xeb'},{'\xac','\xd9'},{'\xb8','\xad'},
+ {'\xbb','\xa1'},{'\xb1','\xfe'},{'\xa8','\xb0'},{'\xa8','\x48'},{'\xac','\x42'},
+ {'\xad','\x59'},{'\xb1','\xb0'},{'\xb2','\xa4'},{'\xab','\x47'},{'\xa8','\xe2'},
+ {'\x84','\x5b'},{'\xb1','\xe7'},{'\xc2','\xb3'},{'\xa8','\x7d'},{'\xbd','\xcc'},
+ {'\xb6','\x71'},{'\xc0','\x79'},{'\xa7','\x66'},{'\xa4','\x6b'},{'\xc3','\x66'},
+ {'\xae','\xc8'},{'\xc2','\x6f'},{'\xc4','\x72'},{'\xbe','\x5b'},{'\xc6','\x7a'},
+ {'\xc4','\x52'},{'\xbe','\xa4'},{'\xa4','\x4f'},{'\xbe','\xe4'},{'\xbe','\xfa'},
+ {'\xf7','\x65'},{'\xa6','\x7e'},{'\xbc','\xa6'},{'\xc5','\xca'},{'\xbc','\xbf'},
+ {'\xba','\xa7'},{'\xb7','\xd2'},{'\xe6','\xa3'},{'\x9d','\xce'},{'\xbd','\x6d'},
+ {'\xc1','\x70'},{'\xbd','\xfb'},{'\xbd','\xac'},{'\xb3','\x73'},{'\xc1','\xe5'},
+ {'\xa6','\x43'},{'\xa6','\x48'},{'\xab','\x7c'},{'\xaf','\x50'},{'\xb5','\xf5'},
+ {'\xbb','\xa1'},{'\xb7','\x47'},{'\xa9','\xc0'},{'\xb1','\xc9'},{'\xc0','\xd4'},
+ {'\xc3','\xae'},{'\xc2','\x79'},{'\xa5','\x4f'},{'\xcb','\xf1'},{'\xb9','\xe7'},
+ {'\xc0','\xad'},{'\xcc','\xb0'},{'\xac','\xc2'},{'\xbc','\xfc'},{'\xb2','\xdc'},
+ {'\xb2','\xe2'},{'\xb9','\x61'},{'\xb9','\x73'},{'\xc6','\x46'},{'\xbb','\xe2'},
+ {'\xa8','\xd2'},{'\xc2','\xa7'},{'\xc4','\xbf'},{'\xc1','\xf5'},{'\xb4','\x63'},
+ {'\xa4','\x46'},{'\xb9','\xb1'},{'\xbc','\x64'},{'\xa7','\xbf'},{'\xae','\xc6'},
+ {'\xbc','\xd6'},{'\xbf','\x52'},{'\xc0','\xf8'},{'\xe7','\x64'},{'\xbf','\xf1'},
+ {'\xc0','\x73'},{'\xb7','\x77'},{'\xa8','\xbf'},{'\xbc','\x42'},{'\xcc','\xd8'},
+ {'\xac','\x68'},{'\xac','\x79'},{'\xb7','\xc8'},{'\xaf','\x5b'},{'\xaf','\x64'},
+ {'\xb2','\xb8'},{'\xaf','\xc3'},{'\xc3','\xfe'},{'\xa4','\xbb'},{'\xbc','\xae'},
+ {'\xb3','\xb0'},{'\xad','\xdb'},{'\xb1','\x5b'},{'\xb2','\x5f'},{'\xbd','\xfc'},
+ {'\xab','\xdf'},{'\xb7','\x58'},{'\xae','\xdf'},{'\xb2','\x76'},{'\xb6','\xa9'},
+ {'\xa7','\x51'},{'\xa6','\x4f'},{'\xbc','\x69'},{'\xa9','\xf6'},{'\xa7','\xf5'},
+ {'\xb1','\xf9'},{'\xaa','\x64'},{'\xb2','\x7a'},{'\xb5','\x67'},{'\xbf','\xa9'},
+ {'\xf9','\xd8'},{'\xb8','\xcc'},{'\xa8','\xbd'},{'\xc2','\xf7'},{'\xb0','\xce'},
+ {'\xb7','\xc4'},{'\xa7','\x5b'},{'\xbf','\x4d'},{'\xbf','\x5a'},{'\xc4','\xa9'},
+ {'\x95','\xf9'},{'\xc5','\xec'},{'\xc5','\xef'},{'\xaa','\x4c'},{'\xb2','\x4f'},
+ {'\xc1','\x7b'},{'\xa5','\xdf'},{'\xb2','\xc1'},{'\xb2','\xc9'},{'\xaa','\xac'},
+ {'\xaa','\xa5'},{'\xc3','\xd1'},{'\xa4','\xb0'},{'\xaf','\xf9'},{'\xa8','\xeb'},
+ {'\xa4','\xc1'},{'\xab','\xd7'},{'\xa9','\xdd'},{'\xbf','\x7d'},{'\xa6','\x76'},
+ {'\xac','\x7d'},{'\xbc','\xc9'},{'\xbf','\xe7'},{'\xa6','\xe6'},{'\xad','\xb0'},
+ {'\xa8','\xa3'},{'\xb9','\xf8'},{'\xc9','\x4a'},{'\xdd','\xfc'},{'\x98','\x77'},
+ {'\x98','\x78'},{'\xb6','\xef'},{'\x98','\x79'},{'\xb4','\xb8'},{'\x98','\x7a'},
+ {'\x98','\x7b'},{'\xe8','\xf9'},{'\x95','\xbd'},{'\xaf','\x71'},{'\x98','\x7c'},
+ {'\xaf','\xab'},{'\xb2','\xbb'},{'\xba','\xd6'},{'\xb9','\x74'},{'\xba','\xeb'},
+ {'\xa6','\xd0'},{'\x98','\x7d'},{'\x98','\x7e'},{'\x98','\xa1'},{'\xbd','\xd1'},
+ {'\x98','\xa2'},{'\x98','\xa3'},{'\xb6','\x68'},{'\xb3','\xa3'},{'\x98','\xa4'},
+ {'\x98','\xa5'},{'\x98','\xa6'},{'\xb6','\xba'},{'\xb9','\x7d'},{'\xc0','\x5d'},
+ {'\xc5','\x62'},{'\x00','\x00'},{'\x00','\x00'},{'\xab','\x56'},{'\xb9','\xac'},
+ {'\xa7','\x4b'},{'\xab','\x6a'},{'\xb6','\xd4'},{'\xa8','\xf5'},{'\xb3','\xdc'},
+ {'\xb9','\xc4'},{'\xbe','\xb9'},{'\x94','\x59'},{'\xbe','\xa5'},{'\xbc','\x68'},
+ {'\xc9','\x4b'},{'\xae','\xac'},{'\xb4','\x6e'},{'\xbc','\xa8'},{'\xc3','\x67'},
+ {'\xb1','\xd3'},{'\xac','\x4a'},{'\xb4','\xbb'},{'\xb1','\xf6'},{'\xae','\xfc'},
+ {'\xb2','\x5a'},{'\xba','\x7e'},{'\xb5','\x4e'},{'\x9c','\x70'},{'\xb5','\x5a'},
+ {'\xb8','\x4f'},{'\xaa','\xc0'},{'\xac','\xe7'},{'\xac','\xe8'},{'\xaf','\xa7'},
+ {'\xaf','\xaa'},{'\xaf','\xac'},{'\xba','\xd7'},{'\xba','\xd5'},{'\xbd','\x5c'},
+ {'\xac','\xf0'},{'\xb8','\x60'},{'\xbd','\x6d'},{'\xbf','\xa7'},{'\xc1','\x63'},
+ {'\xb8','\x70'},{'\xaa','\xcc'},{'\xaf','\xe4'},{'\x9c','\xd2'},{'\x9c','\xd2'},
+ {'\xb5','\xdb'},{'\xbd','\xc5'},{'\xb5','\xf8'},{'\xbf','\xd6'},{'\xc2','\xd4'},
+ {'\xbb','\xab'},{'\xc3','\xd8'},{'\x9c','\xe0'},{'\xb6','\x68'},{'\xc3','\xf8'},
+ {'\xc5','\x54'},{'\xc0','\x57'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\x4a'},{'\xa1','\x57'},{'\x00','\x00'},
+ {'\xa1','\x59'},{'\xa1','\x5b'},{'\xa1','\x5f'},{'\xa1','\x60'},{'\xa1','\x63'},
+ {'\xa1','\x64'},{'\xa1','\x67'},{'\xa1','\x68'},{'\xa1','\x6b'},{'\xa1','\x6c'},
+ {'\xa1','\x6f'},{'\xa1','\x70'},{'\xa1','\x73'},{'\xa1','\x74'},{'\xa1','\x77'},
+ {'\xa1','\x78'},{'\xa1','\x7b'},{'\xa1','\x7c'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa1','\xc6'},{'\xa1','\xc7'},{'\xa1','\xca'},
+ {'\xa1','\xcb'},{'\xa1','\xc8'},{'\xa1','\xc9'},{'\xa1','\x5c'},{'\xa1','\x4d'},
+ {'\xa1','\x4e'},{'\xa1','\x4f'},{'\x00','\x00'},{'\xa1','\x51'},{'\xa1','\x52'},
+ {'\xa1','\x53'},{'\xa1','\x54'},{'\x00','\x00'},{'\xa1','\x7d'},{'\xa1','\x7e'},
+ {'\xa1','\xa1'},{'\xa1','\xa2'},{'\xa1','\xa3'},{'\xa1','\xa4'},{'\xa1','\xcc'},
+ {'\xa1','\xcd'},{'\xa1','\xce'},{'\xa1','\xde'},{'\xa1','\xdf'},{'\xa1','\xe0'},
+ {'\xa1','\xe1'},{'\xa1','\xe2'},{'\x00','\x00'},{'\xa2','\x42'},{'\xa2','\x4c'},
+ {'\xa2','\x4d'},{'\xa2','\x4e'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\xa1','\x49'},{'\xc8','\xd0'},{'\xa1','\xad'},{'\xa2','\x43'},
+ {'\xa2','\x48'},{'\xa1','\xae'},{'\x91','\xc2'},{'\xa1','\x5d'},{'\xa1','\x5e'},
+ {'\xa1','\xaf'},{'\xa1','\xcf'},{'\xa1','\x41'},{'\xa1','\xd0'},{'\xa1','\x44'},
+ {'\xa1','\xfe'},{'\xa2','\xaf'},{'\xa2','\xb0'},{'\xa2','\xb1'},{'\xa2','\xb2'},
+ {'\xa2','\xb3'},{'\xa2','\xb4'},{'\xa2','\xb5'},{'\xa2','\xb6'},{'\xa2','\xb7'},
+ {'\xa2','\xb8'},{'\xa1','\x47'},{'\xa1','\x46'},{'\xa1','\xd5'},{'\xa1','\xd7'},
+ {'\xa1','\xd6'},{'\xa1','\x48'},{'\xa2','\x49'},{'\xa2','\xcf'},{'\xa2','\xd0'},
+ {'\xa2','\xd1'},{'\xa2','\xd2'},{'\xa2','\xd3'},{'\xa2','\xd4'},{'\xa2','\xd5'},
+ {'\xa2','\xd6'},{'\xa2','\xd7'},{'\xa2','\xd8'},{'\xa2','\xd9'},{'\xa2','\xda'},
+ {'\xa2','\xdb'},{'\xa2','\xdc'},{'\xa2','\xdd'},{'\xa2','\xde'},{'\xa2','\xdf'},
+ {'\xa2','\xe0'},{'\xa2','\xe1'},{'\xa2','\xe2'},{'\xa2','\xe3'},{'\xa2','\xe4'},
+ {'\xa2','\xe5'},{'\xa2','\xe6'},{'\xa2','\xe7'},{'\xa2','\xe8'},{'\xc6','\xe4'},
+ {'\xa2','\x40'},{'\xc6','\xe5'},{'\x5e','\x20'},{'\xa1','\xc4'},{'\xa1','\xab'},
+ {'\xa2','\xe9'},{'\xa2','\xea'},{'\xa2','\xeb'},{'\xa2','\xec'},{'\xa2','\xed'},
+ {'\xa2','\xee'},{'\xa2','\xef'},{'\xa2','\xf0'},{'\xa2','\xf1'},{'\xa2','\xf2'},
+ {'\xa2','\xf3'},{'\xa2','\xf4'},{'\xa2','\xf5'},{'\xa2','\xf6'},{'\xa2','\xf7'},
+ {'\xa2','\xf8'},{'\xa2','\xf9'},{'\xa2','\xfa'},{'\xa2','\xfb'},{'\xa2','\xfc'},
+ {'\xa2','\xfd'},{'\xa2','\xfe'},{'\xa3','\x40'},{'\xa3','\x41'},{'\xa3','\x42'},
+ {'\xa3','\x43'},{'\xa1','\x61'},{'\xa1','\x55'},{'\xa1','\x62'},{'\xa1','\xe3'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xc8','\xb9'},{'\xc8','\xba'},{'\xc8','\xbb'},
+ {'\xc8','\xbc'},{'\xc8','\xbd'},{'\xc8','\xbe'},{'\xc8','\xbf'},{'\xc8','\xc0'},
+ {'\xc8','\xc1'},{'\xc8','\xc2'},{'\xc8','\xc3'},{'\xc8','\xc4'},{'\xc8','\xc5'},
+ {'\xc8','\xc6'},{'\xc8','\xc7'},{'\xc8','\xc8'},{'\xc8','\xc9'},{'\xc8','\xca'},
+ {'\xc8','\xcb'},{'\xc8','\xcc'},{'\xc8','\xd4'},{'\xc8','\xd5'},{'\xc8','\xd6'},
+ {'\xc8','\xd7'},{'\xc8','\xd8'},{'\xc8','\xd9'},{'\xc8','\xda'},{'\xc8','\xdb'},
+ {'\xc8','\xdc'},{'\xc8','\xdd'},{'\xc8','\xde'},{'\xc8','\xdf'},{'\xc8','\xe0'},
+ {'\xc8','\xe1'},{'\xc8','\xe2'},{'\xc8','\xe3'},{'\xc8','\xe4'},{'\xc8','\xe5'},
+ {'\xc8','\xe6'},{'\xc8','\xe7'},{'\xc8','\xe8'},{'\xc8','\xe9'},{'\xc8','\xea'},
+ {'\xc8','\xeb'},{'\xc8','\xec'},{'\xc8','\xed'},{'\xc8','\xee'},{'\xc8','\xef'},
+ {'\xc8','\xf0'},{'\xc8','\xf1'},{'\xc8','\xf2'},{'\xc8','\xf3'},{'\xc8','\xf4'},
+ {'\xc8','\xf5'},{'\xc8','\xf6'},{'\xc8','\xf7'},{'\xc8','\xf8'},{'\xc8','\xf9'},
+ {'\xc8','\xfa'},{'\xc8','\xfb'},{'\xc8','\xfc'},{'\xc8','\xfd'},{'\xc8','\xfe'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x46'},
+ {'\xa2','\x47'},{'\xc8','\xcd'},{'\xa1','\xc3'},{'\xc8','\xce'},{'\xa2','\x44'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\xa2','\x78'},{'\xa1','\xf6'},{'\xa1','\xf4'},
+ {'\xa1','\xf7'},{'\xa1','\xf5'},{'\xa1','\xbd'},{'\xa1','\xb3'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},{'\x00','\x00'},
+ {'\x00','\x00'}
+};
+
+static int qt_Big5ToUnicode(const uchar *s, uint *pwc)
+{
+ uchar c1 = s[0];
+ int idx;
+ ushort wc = 0xfffd;
+
+ if ((c1 >= 0x81 && c1 <= 0xfe)) {
+ uchar c2 = s[1];
+
+ if (c2 < 0x40 || c2 > 0xfe
+ || (idx = ((c1 - 0x81) * 191) + (c2 - 0x40),
+ (wc = big5_to_ucs[idx]) == 0))
+ return 0;
+ else {
+ *pwc = (uint) wc;
+ return 2;
+ }
+
+ } else if (c1 < 0x80) {
+ *pwc = (uint) c1;
+ return 1;
+ }
+ return 0;
+}
+
+static int qt_UnicodeToBig5(uint wc, uchar *r)
+{
+ const Summary16 *summary = NULL;
+ const uchar * c;
+ if (wc < 0x80) {
+ r[0] = (uchar) wc;
+ return 1;
+ }
+ else {
+ if (wc >= 0 && wc <= 65535){
+ c = ucs_to_big5[wc];
+ if (c [0] == '\0')
+ return 0;
+ if (c [1] != 0) {
+ r[0] = c[0];
+ r[1] = c[1];
+ return 2;
+ } else { // (c [1] == 0)
+ r[0] = c[0];
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+QString UAOCodec::convertToUnicode(const char* chars, int len, ConverterState *state) const
+{
+ QChar replacement = QChar::ReplacementCharacter;
+ uchar buf[2] = {0};
+ int nbuf = 0;
+ if (state) {
+ if (state->flags & ConvertInvalidToNull)
+ replacement = QChar::Null;
+ nbuf = state->remainingChars;
+ buf[0] = state->state_data[0];
+ buf[1] = state->state_data[1];
+ }
+ int invalid = 0;
+
+ //qDebug("UAOCodec::toUnicode(const char* chars = \"%s\", int len = %d)", chars, len);
+ QString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if (IsLatin(ch)) {
+ // ASCII
+ result += QLatin1Char(ch);
+ } else if (IsFirstByte(ch)) {
+ // Big5-ETen
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += replacement;
+ ++invalid;
+ }
+ break;
+ case 1:
+ if (IsSecondByte(ch)) {
+ // Big5-ETen
+ uint u;
+ buf[1] = ch;
+ if (qt_Big5ToUnicode(buf, &u) == 2)
+ result += QValidChar(u);
+ else {
+ // Error
+ result += replacement;
+ ++invalid;
+ }
+ } else {
+ // Error
+ result += replacement;
+ ++invalid;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ if (state) {
+ state->remainingChars = nbuf;
+ state->state_data[0] = buf[0];
+ state->state_data[1] = buf[1];
+ state->invalidChars += invalid;
+ }
+ return result;
+}
+
+QByteArray UAOCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *state) const
+{
+ char replacement = '?';
+ if (state) {
+ if (state->flags & ConvertInvalidToNull)
+ replacement = 0;
+ }
+
+ int invalid = 0;
+
+ int rlen = 2*len + 1;
+ QByteArray rstr;
+ rstr.resize(rlen);
+
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<len; i++) {
+ ushort ch = uc[i].unicode();
+ uchar c[2];
+ if (ch < 0x80) {
+ // ASCII
+ *cursor++ = ch;
+ } else if (qt_UnicodeToBig5(ch, c) == 2 && c[0] >= 0xa1 && c[0] <= 0xf9) {
+ *cursor++ = c[0];
+ *cursor++ = c[1];
+ } else {
+ *cursor++ = replacement;
+ ++invalid;
+ }
+ }
+ rstr.resize(cursor - (uchar*)rstr.constData());
+
+ if (state) {
+ state->invalidChars += invalid;
+ }
+ return rstr;
+}
+
+QList<QByteArray> UAOCodec::_aliases()
+{
+ QList<QByteArray> aliases;
+ aliases += "Unicode-at-on";
+ return aliases;
+}
+
+/* ====================================================================== */
+#endif // QT_NO_TEXTCODEC
+
+QT_END_NAMESPACE
diff --git a/src/fqterm/3rdparty/uaocodec.h b/src/fqterm/3rdparty/uaocodec.h
new file mode 100644
index 0000000..9984250
--- /dev/null
+++ b/src/fqterm/3rdparty/uaocodec.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Most of the code here was originally written by UAO project (http://uao.cpatch.org/)
+// Ported to Qt by hooey <hephooey@gmail.com> (from uao-051123-src.tar.gz)
+
+#ifndef UAOCODEC_H
+#define UAOCODEC_H
+
+#include <QtCore/qtextcodec.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class UAOCodec : public QTextCodec {
+public:
+ static QByteArray _name();
+ static QList<QByteArray> _aliases();
+ static int _mibEnum();
+
+ QByteArray name() const { return _name(); }
+ QList<QByteArray> aliases() const { return _aliases(); }
+ int mibEnum() const { return _mibEnum(); }
+
+ QString convertToUnicode(const char *, int, ConverterState *) const;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // UAOCODEC_H
diff --git a/src/fqterm/CMakeLists.txt b/src/fqterm/CMakeLists.txt
new file mode 100644
index 0000000..a93cdaf
--- /dev/null
+++ b/src/fqterm/CMakeLists.txt
@@ -0,0 +1,83 @@
+set(fqterm_SRCS
+ fqterm_app.h
+ fqterm_autoupdate.h
+ fqterm_frame.h
+ fqterm_screen.h
+ fqterm_window.h
+ fqterm_wndmgr.h
+ fqterm_autoupdate.cpp
+ fqterm_app.cpp
+ fqterm_frame.cpp
+ fqterm_screen.cpp
+ fqterm_window.cpp
+ fqterm_wndmgr.cpp
+ fqterm_python.h
+ fqterm_python.cpp
+ fqterm_scriptengine.h
+ fqterm_scriptengine.cpp
+)
+
+
+IF(WIN32)
+ set(global_shortcut_impl_SRCS 3rdparty/qxtglobalshortcut_win.cpp)
+ELSE(WIN32)
+ IF(APPLE)
+ set(global_shortcut_impl_SRCS 3rdparty/qxtglobalshortcut_mac.cpp)
+ ELSE(APPLE)
+ set(global_shortcut_impl_SRCS 3rdparty/qxtglobalshortcut_x11.cpp)
+ ENDIF(APPLE)
+ENDIF(WIN32)
+
+
+
+set(3rdparty_SRCS
+ 3rdparty/dotnetstyle.cpp
+ 3rdparty/dotnetstyle.h
+ 3rdparty/qxtglobalshortcut.cpp
+ 3rdparty/qxtglobalshortcut.h
+ 3rdparty/qxtglobalshortcut_p.h
+ 3rdparty/qxtglobal.h
+ 3rdparty/uaocodec.h
+ 3rdparty/uaocodec.cpp
+ ${global_shortcut_impl_SRCS}
+)
+
+qt4_automoc(${fqterm_SRCS}
+ ${3rdparty_SRCS}
+)
+
+qt4_create_translation(fqterm_qm_file
+ ${fqterm_SRCS}
+ ${CMAKE_SOURCE_DIR}/res/dict/fqterm_zh_CN.ts
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${QT_QTSCRIPT_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_SOURCE_DIR}/../protocol
+ ${CMAKE_CURRENT_SOURCE_DIR}/../terminal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/../unite
+ ${CMAKE_CURRENT_SOURCE_DIR}/../ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty
+ ${CMAKE_CURRENT_BINARY_DIR}/../ui
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_main
+ ${fqterm_SRCS}
+ ${3rdparty_SRCS}
+)
+
+add_dependencies(fqterm_main
+ fqterm_common
+ fqterm_terminal
+ fqterm_protocol
+ fqterm_ui
+ fqterm_utilities
+ fqterm_unite
+)
diff --git a/src/fqterm/fqterm.rc b/src/fqterm/fqterm.rc
new file mode 100644
index 0000000..88394ab
--- /dev/null
+++ b/src/fqterm/fqterm.rc
Binary files differ
diff --git a/src/fqterm/fqterm_app.cpp b/src/fqterm/fqterm_app.cpp
new file mode 100644
index 0000000..393355a
--- /dev/null
+++ b/src/fqterm/fqterm_app.cpp
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_app.h"
+
+namespace FQTerm {
+
+FQTermApplication::FQTermApplication( int & argc, char ** argv ) : QApplication(argc, argv)
+{
+
+}
+
+void FQTermApplication::commitData( QSessionManager & manager )
+{
+ emit saveData();
+}
+
+
+} //namespace FQTerm
+
+#include "fqterm_app.moc" \ No newline at end of file
diff --git a/src/fqterm/fqterm_app.h b/src/fqterm/fqterm_app.h
new file mode 100644
index 0000000..ee0778a
--- /dev/null
+++ b/src/fqterm/fqterm_app.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_APP
+#define FQTERM_APP
+#include <QApplication>
+#include <QObject>
+namespace FQTerm {
+
+class FQTermApplication : public QApplication {
+ Q_OBJECT;
+public:
+ FQTermApplication(int & argc, char ** argv);
+protected:
+ virtual void commitData(QSessionManager & manager);
+signals:
+ void saveData();
+protected slots:
+ void mainWindowDestroyed(QObject* obj) {quit();}
+};
+
+} //namespace FQTerm
+
+#endif \ No newline at end of file
diff --git a/src/fqterm/fqterm_autoupdate.cpp b/src/fqterm/fqterm_autoupdate.cpp
new file mode 100644
index 0000000..0f49c38
--- /dev/null
+++ b/src/fqterm/fqterm_autoupdate.cpp
@@ -0,0 +1,178 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_autoupdate.h"
+#include "fqterm_config.h"
+#include "fqterm_trace.h"
+#include "fqterm_param.h"
+
+#include <QDesktopServices>
+#include <QFile>
+#include <QHttp>
+#include <QMessageBox>
+#include <QString>
+#include <QUrl>
+
+namespace FQTerm {
+
+////////////////////////////////////////////////
+static int versionCompare(QString lhs, QString rhs) {
+ //0 -- lhs == rhs, -1 -- lhs > rhs, 1 -- lhs < rhs
+
+ int versionEnd = lhs.indexOf('-');
+ if (versionEnd != -1) {
+ lhs = lhs.mid(0, versionEnd);
+ }
+ versionEnd = rhs.indexOf('-');
+ if (versionEnd != -1) {
+ rhs = rhs.mid(0, versionEnd);
+ }
+ QStringList lhsList = lhs.split(".");
+ QStringList rhsList = rhs.split(".");
+ if (lhsList.size() != 3 || rhsList.size() != 3) {
+ return 0; //something is wrong
+ }
+ for (int i = 0; i < 3; ++i) {
+ if (lhsList[i].toInt() < rhsList[i].toInt()) {
+ return 1;
+ }
+ else if (lhsList[i].toInt() > rhsList[i].toInt()) {
+ return -1;
+ }
+ }
+ return 0;
+}
+///////////////////////////////////////////////
+
+void FQTermAutoUpdater::checkUpdate() {
+ QString fileName = FQTermPref::getInstance()->poolDir_ + "VersionInfo";
+ if (QFile::exists(fileName)) {
+ QFile::remove(fileName);
+ }
+ versionInfoFile_ = new QFile(fileName, this);
+ if (!versionInfoFile_->open(QIODevice::WriteOnly)) {
+ delete versionInfoFile_;
+ return;
+ }
+ FQ_VERIFY(connect(updateChecker_, SIGNAL(requestFinished(int, bool)),
+ this, SLOT(checkRequestFinished(int, bool))));
+ FQ_VERIFY(connect(updateChecker_, SIGNAL(done(bool)),
+ this, SLOT(httpDone(bool))));
+
+ const QString versionInfoURL = "http://fqterm.googlecode.com/svn/trunk/VersionInfo";
+ QUrl url(versionInfoURL);
+ QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
+ updateChecker_->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port());
+ if (!url.userName().isEmpty())
+ updateChecker_->setUser(url.userName(), url.password());
+ checkRequestId_ = updateChecker_->get(url.path(), versionInfoFile_);
+}
+
+QString FQTermAutoUpdater::getNewestVersion() {
+#if defined(WIN32)
+ const QString platform = "FQWin";
+#elif defined(__unix__) && !defined(__APPLE__)
+ const QString platform = "FQLinux";
+#else
+ const QString platform = "FQMac";
+#endif
+ FQTermConfig versionInfo(FQTermPref::getInstance()->poolDir_ + "VersionInfo");
+ QString ver = versionInfo.getItemValue(platform, "version");
+ if (ver.isEmpty()) {
+ return FQTERM_VERSION_STRING;
+ }
+ return ver;
+}
+
+void FQTermAutoUpdater::promptUpdate() {
+ const QString updateURL = "http://code.google.com/p/fqterm/downloads/list";
+ QMessageBox msgBox(QMessageBox::Information, tr("FQTerm Update Notifier"),
+ tr("FQTerm update available.\nPress OK to visit our download list,\nDiscard for a future prompt,\nIgnore for no more notification."),
+ QMessageBox::Ok | QMessageBox::Discard | QMessageBox::Ignore);
+ switch (msgBox.exec()) {
+ case QMessageBox::Ok:
+ QDesktopServices::openUrl(updateURL);
+ break;
+ case QMessageBox::Discard:
+ break;
+ case QMessageBox::Ignore:
+ config_->setItemValue("global", "newestversion", getNewestVersion());
+ config_->setItemValue("global", "updateprompt", "0");
+ break;
+ }
+}
+
+void FQTermAutoUpdater::checkRequestFinished(int requestId, bool error){
+
+ if (checkDone_ || requestId != checkRequestId_) {
+ return;
+ }
+ if (!error) {
+ checkDone_ = true;
+ }
+}
+
+void FQTermAutoUpdater::httpDone(bool err) {
+ if (!err) {
+ versionInfoFile_->flush();
+ if (checkDone_) {
+ QString newestVersionRecorded = config_->getItemValue("global", "newestversion");
+ if (newestVersionRecorded.isEmpty()) {
+ newestVersionRecorded = FQTERM_VERSION_STRING;
+ config_->setItemValue("global", "newestversion", newestVersionRecorded);
+ }
+ QString newestVersionReleased = getNewestVersion();
+
+ QString updatePrompt = config_->getItemValue("global", "updateprompt");
+ if (updatePrompt == "0") {
+ //if newest version > recorded version, still prompt.
+ if (versionCompare(newestVersionRecorded, newestVersionReleased) > 0) {
+ config_->setItemValue("global", "updateprompt", "1");
+ promptUpdate();
+ }
+ }
+ else {
+ config_->setItemValue("global", "updateprompt", "1");
+ //if newest version > version in use, prompt.
+ if (versionCompare(FQTERM_VERSION_STRING, newestVersionReleased) > 0) {
+ promptUpdate();
+ }
+ }
+ }
+ }
+ deleteLater();
+}
+
+FQTermAutoUpdater::FQTermAutoUpdater(QObject* parent, FQTermConfig* config)
+: QObject(parent),
+ config_(config),
+ versionInfoFile_(0),
+ checkDone_(false) {
+ updateChecker_ = new QHttp(this);
+}
+
+FQTermAutoUpdater::~FQTermAutoUpdater()
+{
+
+}
+
+} //FQTerm namespace
+
+#include "fqterm_autoupdate.moc"
diff --git a/src/fqterm/fqterm_autoupdate.h b/src/fqterm/fqterm_autoupdate.h
new file mode 100644
index 0000000..0ad8aaf
--- /dev/null
+++ b/src/fqterm/fqterm_autoupdate.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_AUTO_UPDATE_H
+#define FQTERM_AUTO_UPDATE_H
+
+#include <QObject>
+
+class QHttp;
+class QFile;
+class QString;
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class FQTermAutoUpdater : public QObject{
+
+ Q_OBJECT;
+
+public:
+ FQTermAutoUpdater(QObject* parent, FQTermConfig* config);
+ ~FQTermAutoUpdater();
+
+ void checkUpdate();
+
+protected slots:
+ void checkRequestFinished(int requestId, bool error);
+ void httpDone(bool err);
+
+private:
+ QString getNewestVersion();
+ void promptUpdate();
+
+ FQTermConfig* config_;
+ QHttp * updateChecker_;
+ QFile * versionInfoFile_;
+ int checkRequestId_;
+ bool checkDone_;
+};
+
+} //namespace FQTerm
+
+#endif
diff --git a/src/fqterm/fqterm_frame.cpp b/src/fqterm/fqterm_frame.cpp
new file mode 100644
index 0000000..b50eff9
--- /dev/null
+++ b/src/fqterm/fqterm_frame.cpp
@@ -0,0 +1,2162 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#if !defined(WIN32)
+#include <unistd.h>
+#endif
+
+#if defined(__linux__) || defined(__GLIBC__)
+#include <QLocale>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <QDesktopServices>
+#include <QDir>
+#include <QFontComboBox>
+#include <QFontDialog>
+#include <QInputDialog>
+#include <QKeySequence>
+#include <QList>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QSignalMapper>
+#include <QStatusBar>
+#include <QStyleFactory>
+#include <QTime>
+#include <QDate>
+#include <QSizePolicy>
+#include <QTimer>
+#include <QToolBar>
+#include <QTranslator>
+#include <QWindowStateChangeEvent>
+
+#include "aboutdialog.h"
+#include "addrdialog.h"
+#include "common.h"
+#include "keydialog.h"
+#include "prefdialog.h"
+#include "fqterm.h"
+
+#include "fqterm_path.h"
+#include "fqterm_autoupdate.h"
+#include "fqterm_config.h"
+#include "fqterm_frame.h"
+#include "fqterm_param.h"
+#include "fqterm_session.h"
+#include "fqterm_screen.h"
+#include "fqterm_time_label.h"
+#include "fqterm_tool_button.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#include "imageviewer.h"
+#include "quickdialog.h"
+#include "statusBar.h"
+#include "sitemanager.h"
+#include "fqterm_shortcuthelper.h"
+#include "fqterm_mini_server.h"
+#include "shortcutdialog.h"
+#include "schemadialog.h"
+#include "fqterm_ip_location.h"
+#include "iplookup.h"
+#include "defineescape.h"
+#include "uaocodec.h"
+
+#ifdef USE_DOTNET_STYLE
+#include "dotnetstyle.h"
+#endif //USE_DOTNET_STYLE
+
+#ifdef USE_GLOBAL_HOTKEY
+#include "qxtglobalshortcut.h"
+#endif //USE_GLOBAL_HOTKEY
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#include "fqterm_python.h"
+#endif //HAVE_PYTHON
+
+namespace FQTerm {
+
+
+const QString FQTermFrame::qmPrefix[FQTermFrame::translatedModule] =
+{"fqterm_", "ui_", "protocol_", "common_"};
+const QString FQTermFrame::qmPostfix = ".qm";
+
+//constructor
+FQTermFrame::FQTermFrame()
+ : QMainWindow(0),
+ tray_(0),
+ trayMenu_(0),
+#ifdef HAVE_PYTHON
+ pythonHelper_(0),
+#endif
+#ifdef USE_GLOBAL_HOTKEY
+ globalHotkey_(0),
+#endif //USE_GLOBAL_HOTKEY
+ shortcutHelper_(0)
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+
+/*#ifndef __APPLE__
+ setWindowFlags(Qt::CustomizeWindowHint);
+#endif*/
+ uaoCodec_ = new UAOCodec;
+
+ config_ = new FQTermConfig(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ initTranslator();
+ shortcutHelper_ = new FQTermShortcutHelper(config_, this);
+
+#ifdef IMAGE_USE_PICFLOW
+ imageViewer_ = new FQTermImageFlow(config_, NULL, Qt::Window);
+#else
+ imageViewer_ = new FQTermImageOrigin(config_, NULL, Qt::Window);
+#endif
+
+
+ //create the window manager to deal with the window-tab-icon pairs
+ windowManager_ = new FQTermWndMgr(this);
+ setCentralWidget(windowManager_);
+
+ //set menubar
+ addMainMenu();
+ FQ_VERIFY(connect(this, SIGNAL(changeLanguage()),
+ this, SLOT(recreateMenu())));
+
+ //initialize all settings
+ //This should be done before add main tool, since some status of tool will depend on setting
+ iniSetting();
+ FQTermConfig* conf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ checkHelpExists(conf);
+ delete conf;
+ //setup toolbar
+ addMainTool();
+
+ // add the custom defined key
+ // and load toolbar position
+ updateKeyToolBar();
+ loadToolBarPosition();
+ enableMenuToolBar(false);
+
+ // FIXME: !!!create a horizonal layout to hold the tabbar,the reason
+ //of why not put the tabbar directly on the status bar is when no
+ //tab in the tabbar,the statusbar display a horizonal line,ugly.
+ //perhaps there is some function in statusbar to solve this.
+ QWidget *hb = new QWidget(statusBar());
+ hb->setObjectName("taskbar");
+ QHBoxLayout *hbLayout = new QHBoxLayout(hb);
+ hbLayout->setMargin(0);
+ hbLayout->setObjectName("tasklayout");
+ statusBar()->addWidget(hb);
+ //create a tabbar in the hbox
+ hbLayout->addWidget(windowManager_->tabBar());
+
+ windowMapper_ = new QSignalMapper(this);
+ FQ_VERIFY(connect(windowMapper_, SIGNAL(mapped(int)),
+ windowManager_, SLOT(activateTheWindow(int))));
+ initAdditionalActions();
+
+ //create a progress bar to notify the download process
+ statusBar_ = new FQTerm::StatusBar(statusBar(), "mainStatusBar");
+ statusBar()->addWidget(statusBar_, 0);
+
+ installEventFilter(this);
+
+ QDate lastCheckDate = QDate::fromString(config_->getItemValue("global", "lastcheckupdate"));
+ QDate currentDate = QDate::currentDate();
+ if (!lastCheckDate.isValid() || lastCheckDate.daysTo(currentDate) >= 31) {
+ FQTermAutoUpdater* autoUpdater =
+ new FQTermAutoUpdater(this, config_);
+ autoUpdater->checkUpdate();
+ config_->setItemValue("global", "lastcheckupdate", currentDate.toString());
+ }
+
+ serverThread_ = new FQTermMiniServerThread();
+ if (FQTermPref::getInstance()->runServer_)
+ serverThread_->start();
+#ifdef HAVE_PYTHON
+ pythonHelper_ = new FQTermPythonHelper;
+#endif
+#ifdef USE_GLOBAL_HOTKEY
+ globalHotkey_ = new QxtGlobalShortcut(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM)->shortcut(), this);
+ FQ_VERIFY(connect(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM), SIGNAL(changed()),
+ this, SLOT(globalHotkeyChanged())));
+ FQ_VERIFY(connect(globalHotkey_, SIGNAL(activated()),
+ this, SLOT(globalHotkeyTriggered())));
+#endif //USE_GLOBAL_HOTKEY
+}
+
+//destructor
+FQTermFrame::~FQTermFrame() {
+#ifdef USE_GLOBAL_HOTKEY
+ delete globalHotkey_;
+#endif //USE_GLOBAL_HOTKEY
+#ifdef HAVE_PYTHON
+ delete pythonHelper_;
+#endif //HAVE_PYTHON
+ clearTranslator();
+ delete imageViewer_;
+ delete shortcutHelper_;
+ delete config_;
+ delete uaoCodec_;
+ delete windowManager_;
+ FQTermIPLocation::Destroy();
+ serverThread_->quit();
+ serverThread_->wait(1000);
+ delete serverThread_;
+
+}
+
+//initialize setting from fqterm.cfg
+void FQTermFrame::iniSetting() {
+ QString strTmp;
+
+ strTmp = config_->getItemValue("global", "fullscreen");
+ if (strTmp == "1") {
+ getAction(FQTermShortcutHelper::FULLSCREEN)->setChecked(true);
+ showFullScreen();
+ } else {
+ //window size
+ strTmp = config_->getItemValue("global", "max");
+ if (strTmp == "1") {
+ showMaximized();
+ } else {
+ QString size = config_->getItemValue("global", "size");
+ if (size != "") {
+ int x, y, cx, cy;
+ sscanf(size.toLatin1(), "%d %d %d %d", &x, &y, &cx, &cy);
+ resize(QSize(cx, cy));
+ move(QPoint(x, y));
+ }
+ }
+ }
+
+ theme_ = config_->getItemValue("global", "theme");
+ QStyle *style;
+#ifdef USE_DOTNET_STYLE
+ //javaboy@newsmth.org
+ if (theme_ == "Office")
+ style = new DotNetStyle(DotNetStyle::Office);
+ else
+#endif //USE_DOTNET_STYLE
+ style = QStyleFactory::create(theme_);
+ if (style) {
+ qApp->setStyle(style);
+ }
+
+ //language
+ updateLanguageMenu();
+
+ //TODO:
+ getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true);
+ FQTermPref::getInstance()->escapeString_ = config_->getItemValue("global", "escstr");
+ if (FQTermPref::getInstance()->escapeString_ == "") {
+ getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+ } else if (FQTermPref::getInstance()->escapeString_ == "^[^[[") {
+ getAction(FQTermShortcutHelper::COLORCTL_SMTH)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+ } else if (FQTermPref::getInstance()->escapeString_ == "^u[") {
+ getAction(FQTermShortcutHelper::COLORCTL_PTT)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+ } else {
+ QAction *pAction = getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM);
+ QString transStrEsc;
+ transEscapeStr(transStrEsc, FQTermPref::getInstance()->escapeString_);
+ pAction->setText(transStrEsc);
+ pAction->setVisible(true);
+ pAction->setChecked(true);
+ }
+
+ strTmp = config_->getItemValue("global", "vscrollpos");
+ if (strTmp == "0") {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 0;
+ getAction(FQTermShortcutHelper::SCROLLBAR_HIDDEN)->setChecked(true);
+ } else if (strTmp == "1") {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 1;
+ getAction(FQTermShortcutHelper::SCROLLBAR_LEFT)->setChecked(true);
+ } else {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 2;
+ getAction(FQTermShortcutHelper::SCROLLBAR_RIGHT)->setChecked(true);
+ }
+ strTmp = config_->getItemValue("global", "switchbar");
+ isTabBarShown_ = (strTmp != "0");
+ getAction(FQTermShortcutHelper::SWITCHBAR)->setChecked(isTabBarShown_);
+ if (isTabBarShown_) {
+ statusBar()->show();
+ } else {
+ statusBar()->hide();
+ }
+
+ //read sub-window setting.
+ strTmp = config_->getItemValue("global", "subwindowmax");
+ windowManager_->setSubWindowMax((strTmp != "0"));
+
+
+ strTmp = config_->getItemValue("global", "subwindowsize");
+ if (strTmp != "") {
+ //FIXME: In case of sub window size not saved properly.
+ int w, h;
+ sscanf(strTmp.toLatin1(), "%d %d", &w, &h);
+ windowManager_->setSubWindowSize(QSize(w, h));
+ } else {
+ //Magic Number. Initialize Window Size to Avoid Errors.
+ windowManager_->setSubWindowSize(QSize(640, 480));
+ }
+
+ FQTermPref::getInstance()->isBossColor_ = false;
+
+ loadPref();
+
+ setUseDock(FQTermPref::getInstance()->openMinimizeToTray_);
+
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ loadStyleSheetFromFile(FQTermPref::getInstance()->styleSheetFile_);
+ }
+
+ strTmp = config_->getItemValue("global", "runserver");
+ FQTermPref::getInstance()->runServer_ = (strTmp != "0");
+}
+
+void FQTermFrame::loadPref() {
+ QString strTmp;
+
+ strTmp = config_->getItemValue("preference", "displayoffset");
+ FQTermPref::getInstance()->displayOffset_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "vsetting");
+ FQTermPref::getInstance()->vsetting_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "xim");
+ FQTermPref::getInstance()->imeEncodingID_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "wordwrap");
+ FQTermPref::getInstance()->widthToWrapWord_ = strTmp.toInt();
+ // strTmp = conf->getItemValue("preference", "smartww");
+ // m_pref.bSmartWW = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "wheel");
+ FQTermPref::getInstance()->isWheelSupported_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "url");
+ FQTermPref::getInstance()->openUrlCheck_ = (strTmp != "0");
+ // strTmp = conf->getItemValue("preference", "logmsg");
+ // m_pref.bLogMsg = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "blinktab");
+ FQTermPref::getInstance()->openTabBlinking_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "warn");
+ FQTermPref::getInstance()->openWarnOnClose_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "beep");
+ FQTermPref::getInstance()->openBeep_ = strTmp.toInt();
+ FQTermPref::getInstance()->beepSoundFileName_ = config_->getItemValue("preference", "wavefile");
+ strTmp = config_->getItemValue("preference", "http");
+ FQTermPref::getInstance()->httpBrowser_ = strTmp;
+ // m_pref.strHttp = strTmp;
+ strTmp = config_->getItemValue("preference", "antialias");
+ FQTermPref::getInstance()->openAntiAlias_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "enq");
+ FQTermPref::getInstance()->replyENQ_ = (strTmp != "0");
+ strTmp = config_->getItemValue("preference", "tray");
+ if (strTmp.isEmpty()) {
+#if defined(__APPLE__) || defined(__linux__) || defined(__GLIBC__)
+ FQTermPref::getInstance()->openMinimizeToTray_ = false;
+#else
+ FQTermPref::getInstance()->openMinimizeToTray_ = true;
+#endif
+ } else {
+ FQTermPref::getInstance()->openMinimizeToTray_ = (strTmp != "0");
+ }
+ strTmp = config_->getItemValue("preference", "playmethod");
+ FQTermPref::getInstance()->beepMethodID_ = strTmp.toInt();
+ strTmp = config_->getItemValue("preference", "externalplayer");
+ FQTermPref::getInstance()->beepPlayerName_ = strTmp;
+
+ strTmp = config_->getItemValue("preference", "clearpool");
+ FQTermPref::getInstance()->needClearZmodemPoolOnClose_ = (strTmp == "1");
+ strTmp = config_->getItemValue("preference", "pool");
+ FQTermPref::getInstance()->poolDir_ = strTmp.isEmpty() ?
+ getPath(USER_CONFIG) + "pool/": strTmp;
+ if (FQTermPref::getInstance()->poolDir_.right(1) != "/") {
+ FQTermPref::getInstance()->poolDir_.append('/');
+ }
+ strTmp = config_->getItemValue("preference", "zmodem");
+ FQTermPref::getInstance()->zmodemDir_ = strTmp.isEmpty() ?
+ getPath(USER_CONFIG) + "zmodem/": strTmp;
+ if (FQTermPref::getInstance()->zmodemDir_.right(1) != "/") {
+ FQTermPref::getInstance()->zmodemDir_.append('/');
+ }
+ strTmp = config_->getItemValue("preference", "image");
+ FQTermPref::getInstance()->imageViewerName_ = strTmp;
+ strTmp = config_->getItemValue("preference", "qssfile");
+ FQTermPref::getInstance()->styleSheetFile_ = strTmp;
+ FQTermPref::getInstance()->useStyleSheet_ = !strTmp.isEmpty();
+
+ strTmp = config_->getItemValue("preference", "editor");
+ FQTermPref::getInstance()->externalEditor_ = strTmp;
+
+ //FIXME: duplicated strings.
+ strTmp = config_->getItemValue("preference", "searchengine");
+ if (strTmp == "google") {
+ getAction(FQTermShortcutHelper::SEARCH_GOOGLE)->setChecked(true);
+ } else if (strTmp == "baidu") {
+ getAction(FQTermShortcutHelper::SEARCH_BAIDU)->setChecked(true);
+ } else if (strTmp == "bing") {
+ getAction(FQTermShortcutHelper::SEARCH_BING)->setChecked(true);
+ } else if (strTmp == "yahoo") {
+ getAction(FQTermShortcutHelper::SEARCH_YAHOO)->setChecked(true);
+ } else if (strTmp == "custom") {
+ getAction(FQTermShortcutHelper::SEARCH_CUSTOM)->setChecked(true);
+ } else {
+ getAction(FQTermShortcutHelper::SEARCH_GOOGLE)->setChecked(true);
+ strTmp = "google";
+ }
+ FQTermPref::getInstance()->searchEngine_ = strTmp;
+
+ strTmp = config_->getItemValue("preference", "editorarg");
+ FQTermPref::getInstance()->externalEditorArg_ = strTmp;
+
+ strTmp = config_->getItemValue("preference", "asciienhance");
+ FQTermPref::getInstance()->isAnsciiEnhance_ = (strTmp == "1");
+}
+
+//save current setting to fqterm.cfg
+void FQTermFrame::saveSetting() {
+ QString strTmp;
+ //save font
+ config_->setItemValue("global", "font", qApp->font().family());
+ strTmp.setNum(QFontInfo(qApp->font()).pointSize());
+ config_->setItemValue("global", "pointsize", strTmp);
+ strTmp.setNum(QFontInfo(qApp->font()).pixelSize());
+ config_->setItemValue("global", "pixelsize", strTmp);
+
+ //save window position and size
+ if (isMaximized()) {
+ config_->setItemValue("global", "max", "1");
+ } else {
+ strTmp = QString("%1 %2 %3 %4").arg(x()).arg(y()).arg(width()).arg(height());
+ // cstrTmp.sprintf("%d %d %d %d",x(),y(),width(),height());
+ config_->setItemValue("global", "size", strTmp);
+ config_->setItemValue("global", "max", "0");
+ }
+
+ if (windowState() & Qt::WindowFullScreen) {
+ config_->setItemValue("global", "fullscreen", "1");
+ } else {
+ config_->setItemValue("global", "fullscreen", "0");
+ }
+
+ // cstrTmp.setNum(theme);
+ config_->setItemValue("global", "theme", theme_);
+
+ config_->setItemValue("global", "escstr", FQTermPref::getInstance()->escapeString_);
+
+ strTmp.setNum(FQTermPref::getInstance()->termScrollBarPosition_);
+ config_->setItemValue("global", "vscrollpos", strTmp);
+
+ config_->setItemValue("global", "switchbar", isTabBarShown_ ? "1" : "0");
+
+ //save subwindow setting
+ config_->setItemValue("global", "subwindowmax", windowManager_->getSubWindowMax() ? "1" : "0");
+ int w = windowManager_->getSubWindowSize().width();
+ int h = windowManager_->getSubWindowSize().height();
+
+ strTmp = QString("%1 %2").arg(w).arg(h);
+ config_->setItemValue("global", "subwindowsize", strTmp);
+
+ //Save toolbarstate.
+ QByteArray state = saveState().toHex();
+ strTmp = QString(state);
+ config_->setItemValue("global", "toolbarstate", strTmp);
+
+ config_->setItemValue("global", "runserver", FQTermPref::getInstance()->runServer_ ? "1" : "0");
+
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void FQTermFrame::initAdditionalActions()
+{
+
+#if defined(__APPLE__)
+ QString opt(tr("Ctrl"));
+#else
+ QString opt(tr("Alt"));
+#endif
+
+ for (int i = 1; i <= 10; ++i) {
+ QAction *idAction = new QAction(this);
+ QString shortcut(opt);
+ shortcut += "+" + QString("").setNum(i % 10);
+ idAction->setShortcut(shortcut);
+ connect(idAction, SIGNAL(triggered()), windowMapper_, SLOT(map()));
+ windowMapper_->setMapping(idAction, i - 1);
+ addAction(idAction);
+ }
+
+ FQTERM_ADDACTION(windowManager_, NEXTWINDOW, windowManager_, activateNextWindow);
+ FQTERM_ADDACTION(windowManager_, PREVWINDOW, windowManager_, activatePrevWindow);
+
+}
+
+//addressbook
+void FQTermFrame::addressBook() {
+ siteDialog siteManager(this, false);
+ if (siteManager.exec() == 1) {
+ newWindow(siteManager.currentParameter(), siteManager.currentSiteIndex());
+ }
+}
+
+//quicklogin
+void FQTermFrame::quickLogin() {
+ quickDialog quick(config_, this);
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+
+ loadAddress(pConf, -1, quick.param_);
+ delete pConf;
+
+ if (quick.exec() == 1) {
+ newWindow(quick.param_);
+ }
+}
+
+void FQTermFrame::exitFQTerm() {
+ if (!clearUp()) return;
+ deleteLater();
+}
+
+void FQTermFrame::newWindow(const FQTermParam &param, int index) {
+ QIcon *icon = new QIcon(QPixmap(getPath(RESOURCE) + "pic/tabpad.png"));
+ FQTermWindow* window = windowManager_->newWindow(param, config_, icon, index);
+
+ updateFontCombo();
+ FQ_VERIFY(connect(window->getScreen(), SIGNAL(termFontChange(bool,QFont)), this, SLOT(termFontChange(bool,QFont))));
+
+ window->connectHost();
+}
+
+
+void FQTermFrame::aboutFQTerm() {
+ aboutDialog about(this);
+ about.exec();
+}
+
+//slot Help->Homepage
+void FQTermFrame::homepage() {
+ const QString &httpBrowser = FQTermPref::getInstance()->httpBrowser_;
+ const QString homeUrl = "http://code.google.com/p/fqterm";
+
+ if (httpBrowser.isNull() || httpBrowser.isEmpty()) {
+ QDesktopServices::openUrl(homeUrl);
+ } else {
+ runProgram(httpBrowser, homeUrl);
+ }
+}
+
+//slot Windows menu aboutToShow
+void FQTermFrame::windowsMenuAboutToShow() {
+ menuWindows_->clear();
+ FQTERM_ADDACTION(menuWindows_, CASCADEWINDOWS, windowManager_, cascade);
+ FQTERM_ADDACTION(menuWindows_, TILEWINDOWS, windowManager_, tile);
+ if (windowManager_->count() == 0) {
+ getAction(FQTermShortcutHelper::CASCADEWINDOWS)->setEnabled(false);
+ getAction(FQTermShortcutHelper::TILEWINDOWS)->setEnabled(false);
+ }
+ menuWindows_->addSeparator();
+
+#ifdef Q_OS_MACX
+ // used to dock the program
+ if (isHidden()) {
+ menuWindows_->addAction(tr("Main Window"), this, SLOT(trayShow()));
+ }
+#endif
+
+ for (int i = 0; i < int(windowManager_->count()); ++i) {
+ QAction *idAction = menuWindows_->addAction(windowManager_->subWindowList().at(i)->windowTitle());
+ idAction->setCheckable(true);
+ idAction->setChecked(windowManager_->activeWindow() == windowManager_->nthWindow(i));
+ connect(idAction, SIGNAL(triggered()), windowMapper_, SLOT(map()));
+ windowMapper_->setMapping(idAction, i);
+ }
+}
+
+void FQTermFrame::reloadConfig() {
+ config_->load(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void FQTermFrame::popupConnectMenu() {
+ menuConnect_->clear();
+ menuConnect_->addAction(tr("Quick Login"), this, SLOT(quickLogin()));
+ menuConnect_->addSeparator();
+
+ FQTermConfig conf(getPath(USER_CONFIG) + "address.cfg");
+
+ QStringList listName;
+ loadNameList(&conf, listName);
+
+ for (int i = 0; i < listName.count(); i++) {
+ QAction *idAction = menuConnect_->addAction(listName[i], this, SLOT
+ (connectMenuActivated()));
+ idAction->setData(i);
+ if (i < 10) {
+#ifdef __APPLE__
+ QString shortCut(tr("Ctrl+Meta"));
+#else
+ QString shortCut(tr("Ctrl+Alt"));
+#endif
+ shortCut += "+" + QString("").setNum((i + 1)% 10);
+ idAction->setShortcut(shortCut);
+ }
+ }
+
+ int lastIndex = config_->getItemValue("global", "lastaddrindex").toInt();
+ if (lastIndex < 0 || lastIndex >= listName.count())
+ lastIndex = 0;
+ if (listName.count() > 0)
+ {
+ menuConnect_->addSeparator();
+ QAction *idAction = menuConnect_->addAction(listName[lastIndex], this, SLOT
+ (connectMenuActivated()));
+ idAction->setData(LAST_ADDRESS_INDEX);
+#ifdef __APPLE__
+ QString shortCut(tr("Ctrl+Meta"));
+#else
+ QString shortCut(tr("Ctrl+Alt"));
+#endif
+ shortCut += "+" + QString("-");
+ idAction->setShortcut(shortCut);
+
+ }
+}
+
+void FQTermFrame::connectMenuActivated() {
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ int id = static_cast < QAction * > (sender())->data().toInt();
+ if (id == LAST_ADDRESS_INDEX)
+ {
+ id = config_->getItemValue("global", "lastaddrindex").toInt();
+ }
+
+ FQTermParam param;
+
+ // FIXME: don't know the relation with id and param setted by setItemParameter
+ if (loadAddress(pConf, id, param)) {
+ newWindow(param, id);
+ }
+ delete pConf;
+}
+
+
+bool FQTermFrame::eventFilter(QObject *o, QEvent *e) {
+ return false;
+}
+
+void FQTermFrame::closeEvent(QCloseEvent *clse) {
+ if (FQTermPref::getInstance()->openMinimizeToTray_ &&
+ windowManager_->count() > 0) {
+ trayHide();
+ clse->ignore();
+ return ;
+ }
+ if (!clearUp())
+ {
+ clse->ignore();
+ return;
+ }
+
+ clse->accept();
+
+ deleteLater();
+}
+
+void FQTermFrame::langEnglish() {
+ installTranslator("en_US");
+}
+
+void FQTermFrame::connectIt() {
+ if (windowManager_->activeWindow() == NULL) {
+ FQTermParam param;
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+
+ loadAddress(pConf, -1, param);
+ delete pConf;
+ newWindow(param);
+ } else if (!windowManager_->activeWindow()->isConnected()) {
+ windowManager_->activeWindow()->getSession()->reconnect();
+ }
+}
+
+void FQTermFrame::disconnect() {
+ FQTermWindow* aw = windowManager_->activeWindow();
+ if (aw) {
+ aw->disconnect();
+ }
+}
+
+void FQTermFrame::copy() {
+ windowManager_->activeWindow()->copy();
+}
+
+void FQTermFrame::paste() {
+ windowManager_->activeWindow()->paste();
+}
+
+void FQTermFrame::searchIt()
+{
+ windowManager_->activeWindow()->searchIt();
+}
+
+void FQTermFrame::shareIt()
+{
+ windowManager_->activeWindow()->shareIt();
+}
+
+void FQTermFrame::externalEditor() {
+ windowManager_->activeWindow()->externalEditor();
+}
+
+void FQTermFrame::fastPost() {
+ windowManager_->activeWindow()->fastPost();
+}
+
+void FQTermFrame::copyRect() {
+ windowManager_->activeWindow()->getSession()->param().isRectSelect_
+ = !windowManager_->activeWindow()->getSession()->param().isRectSelect_;
+
+ getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isRectSelect_);
+}
+
+void FQTermFrame::copyColor() {
+ windowManager_->activeWindow()->getSession()->param().isColorCopy_
+ = !windowManager_->activeWindow()->getSession()->param().isColorCopy_;
+
+ getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isColorCopy_);
+}
+
+void FQTermFrame::copyArticle() {
+ windowManager_->activeWindow()->copyArticle();
+}
+
+void FQTermFrame::autoCopy() {
+ windowManager_->activeWindow()->getSession()->param().isAutoCopy_
+ = !windowManager_->activeWindow()->getSession()->param().isAutoCopy_;
+
+ getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isAutoCopy_);
+}
+
+void FQTermFrame::wordWrap() {
+ windowManager_->activeWindow()->getSession()->param().isAutoWrap_
+ = !windowManager_->activeWindow()->getSession()->param().isAutoWrap_;
+
+ getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isAutoWrap_);
+}
+
+void FQTermFrame::noEsc() {
+ FQTermPref::getInstance()->escapeString_ = "";
+ getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+}
+
+void FQTermFrame::escEsc() {
+ FQTermPref::getInstance()->escapeString_ = "^[^[[";
+ getAction(FQTermShortcutHelper::COLORCTL_SMTH)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+}
+
+void FQTermFrame::uEsc() {
+ FQTermPref::getInstance()->escapeString_ = "^u[";
+ getAction(FQTermShortcutHelper::COLORCTL_PTT)->setChecked(true);
+ getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false);
+}
+
+void FQTermFrame::oldCustomEsc() {
+}
+
+void FQTermFrame::customEsc() {
+ QString strEsc(FQTermPref::getInstance()->escapeString_);
+ DefineEscapeDialog defineEscapeDialog_(strEsc, this);
+ if (defineEscapeDialog_.exec() == 1)
+ {
+ FQTermPref::getInstance()->escapeString_ = strEsc;
+ QAction *pAction = getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM);
+ if (strEsc != QString("") && strEsc != QString("^[^[[") && strEsc != QString("^u["))
+ {
+ QString transStrEsc;
+ transEscapeStr(transStrEsc, strEsc);
+ pAction->setText(transStrEsc);
+ pAction->setVisible(true);
+ pAction->setChecked(true);
+ }
+ else
+ {
+ pAction->setVisible(false);
+ }
+ }
+}
+
+bool FQTermFrame::isDelimiterExistedBefore(const QString& str,
+ const std::vector<QString>& existingDelimiters) {
+ for (std::vector<QString>::const_iterator cit = existingDelimiters.begin();
+ cit != existingDelimiters.end();
+ ++cit)
+ {
+ if (str.right(cit->length()) == *cit)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+int FQTermFrame::isDelimiterExistedAfter(const QString& str,
+ const std::vector<QString>& existingDelimiters) {
+ for (std::vector<QString>::const_iterator cit = existingDelimiters.begin();
+ cit != existingDelimiters.end();
+ ++cit)
+ {
+ if (str.left(cit->length()) == *cit)
+ {
+ return cit->length();
+ }
+ }
+ return 0;
+}
+
+bool FQTermFrame::uppercaseCharFollowingCtrl(QString& str,
+ int& i,
+ const QString& after) {
+ if (after == QString("Ctrl") &&
+ str[i] > 'a' - 1 &&
+ str[i] < 'z' - 1)
+ {
+ str[i] = str[i].toUpper();
+ ++i;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void FQTermFrame::replaceEscapeString(QString& str,
+ const QString& before,
+ const QString& after,
+ const QString& delimiter,
+ const std::vector<QString> *existingDelimiters /* = NULL */) {
+ bool preMatched = false;
+ int i = 0;
+ while (i < str.length())
+ {
+ bool matched = true;
+ for (int j = 0; j < before.length(); ++j)
+ {
+ if (str[i + j] != before[j])
+ {
+ matched = false;
+ break;
+ }
+ }// end of for
+ if (matched)
+ {
+ if (i == 0)
+ {
+ // the matched string is the head of the string
+ str = after + delimiter + str.right(str.length() - before.length());
+ i = after.length() + delimiter.length();
+ bool changed = uppercaseCharFollowingCtrl(str, i, after);
+ preMatched = !changed;
+ }
+ else if (i == str.length() - before.length())
+ {
+ // the matched string is the tail of the string
+ if (existingDelimiters != NULL &&
+ isDelimiterExistedBefore(str.left(i), *existingDelimiters))
+ {
+ preMatched = true;
+ }
+
+ if (preMatched)
+ {
+ str = str.left(i) + after;
+ }
+ else
+ {
+ str = str.left(i) + delimiter + after;
+ }
+ break;
+ }
+ else
+ {
+ // the matched string is at the middle of the string
+ if (existingDelimiters != NULL &&
+ isDelimiterExistedBefore(str.left(i), *existingDelimiters))
+ {
+ preMatched = true;
+ }
+
+ if (preMatched)
+ {
+ str = str.left(i) + after + delimiter + str.right(str.length() - i - before.length());
+ i += after.length() + delimiter.length();
+ }
+ else
+ {
+ str = str.left(i) + delimiter + after + delimiter + str.right(str.length() - i - before.length());
+ i += after.length() + 2 * delimiter.length();
+ }
+ bool changed = uppercaseCharFollowingCtrl(str, i, after);
+ preMatched = !changed;
+ }
+ if (preMatched)
+ {
+ int len;
+ if (existingDelimiters != NULL &&
+ (len = isDelimiterExistedAfter(str.right(str.length() - i), *existingDelimiters)) != 0)
+ {
+ str = str.left(i) + str.right(str.length() - i - len);
+ }
+ }
+ }
+ else
+ {
+ preMatched = false;
+ ++i;
+ }
+ }// end of while
+}
+
+void FQTermFrame::transEscapeStr(QString& target, const QString& source) {
+ const QChar cSpecial(17);
+ target = source;
+ replaceEscapeString(target, QString("^["), QString("ESC"), QString(cSpecial));
+ std::vector<QString> existingDelimiters;
+ existingDelimiters.push_back(QString(cSpecial));
+ replaceEscapeString(target, QString("^"), QString("Ctrl"), QString("+"), &existingDelimiters);
+ target.replace(cSpecial, QChar(' '));
+}
+
+void FQTermFrame::setColor() {
+ windowManager_->activeWindow()->setColor();
+}
+
+void FQTermFrame::refreshScreen() {
+ windowManager_->activeWindow()->forcedRepaintScreen();
+}
+
+void FQTermFrame::uiFont() {
+ bool ok;
+ QFont font = QFontDialog::getFont(&ok, qApp->font());
+
+ if (FQTermPref::getInstance()->openAntiAlias_) {
+ font.setStyleStrategy(QFont::PreferAntialias);
+ }
+
+ if (ok == true) {
+ qApp->setFont(font);
+ //refresh style sheet
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ refreshStyleSheet();
+ }
+ imageViewer_->adjustItemSize();
+ }
+}
+
+void FQTermFrame::fullscreen() {
+
+
+ if (!(windowState() & Qt::WindowFullScreen)) {
+ menuBar()->hide();
+ toolBarMdiTools_->hide();
+ toolBarMdiConnectTools_->hide();
+ toolBarSetupKeys_->hide();
+ toolBarFonts_->hide();
+ hideScroll();
+ showSwitchBar();
+ showFullScreen();
+ } else {
+ menuBar()->show();
+ toolBarMdiTools_->show();
+ toolBarMdiConnectTools_->show();
+ toolBarSetupKeys_->show();
+ toolBarFonts_->show();
+ emit updateScroll();
+ showSwitchBar();
+ showNormal();
+ }
+
+}
+
+void FQTermFrame::bosscolor() {
+ FQTermPref::getInstance()->isBossColor_ = !FQTermPref::getInstance()->isBossColor_;
+ emit bossColor();
+ getAction(FQTermShortcutHelper::BOSSCOLOR)->setChecked(FQTermPref::getInstance()->isBossColor_);
+}
+
+
+void FQTermFrame::toggleServer(bool on) {
+ FQTermPref::getInstance()->runServer_ = on;
+ if (on) {
+ serverThread_->start();
+ } else {
+ serverThread_->quit();
+ serverThread_->wait(1000);
+ }
+}
+
+void FQTermFrame::themesMenuAboutToShow() {
+ QVector<QChar> vectorShortcutKeys;
+ menuThemes_->clear();
+ QStringList styles = QStyleFactory::keys();
+ for (QStringList::ConstIterator it = styles.begin();
+ it != styles.end(); it++) {
+ QString strTheme = *it;
+ for (int i = 0; i < strTheme.length(); ++i)
+ {
+ if (vectorShortcutKeys.indexOf(strTheme.at(i)) == -1)
+ {
+ vectorShortcutKeys.append(strTheme.at(i));
+ strTheme.insert(i, QChar('&'));
+ break;
+ }
+ }
+ insertThemeItem(strTheme);
+ }
+#ifdef USE_DOTNET_STYLE
+ insertThemeItem("Office"); //javaboy@newsmth.org
+#endif //USE_DOTNET_STYLE
+}
+
+void FQTermFrame::themesMenuActivated() {
+ theme_ = ((QAction*)QObject::sender())->text().remove(QChar('&'));
+ QStyle *style;
+#ifdef USE_DOTNET_STYLE
+ //javaboy@newsmth.org
+ if (theme_ == "Office")
+ style = new DotNetStyle(DotNetStyle::Office);
+ else
+#endif //USE_DOTNET_STYLE
+ style = QStyleFactory::create(theme_);
+ if (style) {
+ qApp->setStyle(style);
+ }
+}
+
+
+
+void FQTermFrame::hideScroll() {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 0;
+ emit updateScroll();
+}
+
+void FQTermFrame::leftScroll() {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 1;
+ emit updateScroll();
+}
+
+void FQTermFrame::rightScroll() {
+ FQTermPref::getInstance()->termScrollBarPosition_ = 2;
+ emit updateScroll();
+}
+
+void FQTermFrame::setSE(const QString& se) {
+ FQTermPref::getInstance()->searchEngine_ = se;
+ config_->setItemValue("preference", "searchengine", se);
+}
+
+void FQTermFrame::setSEGoogle() {
+ setSE("google");
+}
+void FQTermFrame::setSEBaidu(){
+ setSE("baidu");
+}
+void FQTermFrame::setSEYahoo() {
+ setSE("yahoo");
+}
+void FQTermFrame::setSEBing() {
+ setSE("bing");
+}
+void FQTermFrame::setSECustom(){
+ setSE("custom");
+}
+
+void FQTermFrame::showSwitchBar() {
+ isTabBarShown_ = !isTabBarShown_;
+ getAction(FQTermShortcutHelper::SWITCHBAR)->setChecked(isTabBarShown_);
+
+ if (isTabBarShown_) {
+ statusBar()->show();
+ } else {
+ statusBar()->hide();
+ }
+}
+
+void FQTermFrame::setting() {
+ windowManager_->activeWindow()->setting();
+ updateMenuToolBar();
+}
+
+void FQTermFrame::saveSessionSetting() {
+ windowManager_->activeWindow()->saveSetting(false);
+}
+
+void FQTermFrame::defaultSetting() {
+ FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ FQTermParam tmpParam;
+
+ if (pConf->hasSection("default")) {
+ loadAddress(pConf, -1, tmpParam);
+ }
+
+ addrDialog set(this, tmpParam, addrDialog::SAVE);
+
+ if (set.exec() == 2) {
+ saveAddress(pConf, -1, set.param());
+ pConf->save(getPath(USER_CONFIG) + "address.cfg");
+ }
+
+ delete pConf;
+}
+
+void FQTermFrame::preference() {
+ prefDialog pref(config_, this);
+ bool styleSheetUsed = FQTermPref::getInstance()->useStyleSheet_;
+
+ if (pref.exec() == 1) {
+ //TODO: refactor
+ loadPref();
+ setUseDock(FQTermPref::getInstance()->openMinimizeToTray_);
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ loadStyleSheetFromFile(FQTermPref::getInstance()->styleSheetFile_);
+ }
+ else if (styleSheetUsed) {
+ clearStyleSheet();
+ }
+ }
+ emit fontAntiAliasing(FQTermPref::getInstance()->openAntiAlias_);
+}
+
+void FQTermFrame::shortcutSetting() {
+ int act = windowManager_->activeWindowIndex();
+ FQTermShortcutDialog fsd(shortcutHelper_, this);
+ fsd.exec();
+ windowManager_->activateTheWindow(act);
+}
+
+void FQTermFrame::keySetup() {
+ keyDialog keyDlg(config_, this);
+ if (keyDlg.exec() == 1) {
+ updateKeyToolBar();
+ }
+}
+
+
+void FQTermFrame::ipLookup() {
+ IPLookupDialog ipLookupDialog_(this);
+ ipLookupDialog_.exec();
+}
+
+void FQTermFrame::antiIdle() {
+ windowManager_->activeWindow()->toggleAntiIdle();
+ getAction(FQTermShortcutHelper::ANTIIDLE)->setChecked(
+ windowManager_->activeWindow()->getSession()->isAntiIdle());
+}
+
+void FQTermFrame::autoReply() {
+ windowManager_->activeWindow()->toggleAutoReply();
+ getAction(FQTermShortcutHelper::AUTOREPLY)->setChecked(
+ windowManager_->activeWindow()->getSession()->isAutoReply());
+}
+
+void FQTermFrame::viewMessages() {
+ windowManager_->activeWindow()->viewMessages();
+}
+
+void FQTermFrame::enableMouse() {
+ windowManager_->activeWindow()->getSession()->param().isSupportMouse_
+ = !windowManager_->activeWindow()->getSession()->param().isSupportMouse_;
+ getAction(FQTermShortcutHelper::MOUSESUPPORT)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isSupportMouse_);
+}
+
+void FQTermFrame::viewImages(QString filename, bool raiseViewer) {
+ if (filename.isEmpty()) {
+ filename = FQTermPref::getInstance()->poolDir_;
+ }
+
+ if (raiseViewer) {
+ imageViewer_->scrollTo(filename);
+ if (imageViewer_->isHidden()) {
+ imageViewer_->resize(size() * 3 / 4 + QSize(1,1));
+ imageViewer_->show();
+ }
+ clearFocus();
+ imageViewer_->raise();
+ imageViewer_->activateWindow();
+ } else {
+ imageViewer_->updateImage(filename);
+ }
+}
+
+void FQTermFrame::viewImages() {
+ viewImages(FQTermPref::getInstance()->poolDir_, true);
+}
+
+void FQTermFrame::beep() {
+ windowManager_->activeWindow()->getSession()->param().isBeep_ =
+ !windowManager_->activeWindow()->getSession()->param().isBeep_;
+ getAction(FQTermShortcutHelper::BEEP)->setChecked(windowManager_->activeWindow()->getSession()->param().isBeep_);
+}
+
+void FQTermFrame::reconnect() {
+ FQTermWindow * qtw = windowManager_->activeWindow();
+ if (qtw){
+ qtw->toggleAutoReconnect();
+ }
+}
+
+
+void FQTermFrame::delayedRunScript() {
+ windowManager_->activeWindow()->runScript();
+}
+
+
+void FQTermFrame::runScript() {
+ QTimer::singleShot(1, this, SLOT(delayedRunScript()));
+}
+
+void FQTermFrame::stopScript() {
+ windowManager_->activeWindow()->stopScript();
+}
+
+
+void FQTermFrame::runPyScript() {
+#ifdef HAVE_PYTHON
+ windowManager_->activeWindow()->runPythonScript();
+#endif //HAVE_PYTHON
+}
+
+bool FQTermFrame::event(QEvent *e) {
+
+ static bool shown = false;
+ if (e->type() == QEvent::WindowStateChange) {
+ if ((((QWindowStateChangeEvent*)(e))->oldState() & Qt::WindowMinimized)
+ && !(windowState() & Qt::WindowMinimized)) {
+ shown = true;
+ }
+ if (!(windowState() & Qt::WindowMinimized))
+ {
+ config_->setItemValue("global", "max", (windowState() & Qt::WindowMaximized) ? "1" : "0");
+ config_->setItemValue("global", "fullscreen", (windowState() & Qt::WindowFullScreen) ? "1" : "0");
+ }
+ }
+ if (e->type() == QEvent::Paint && shown) {
+ shown = false;
+ qApp->setActiveWindow(NULL);
+ qApp->setActiveWindow(this);
+ }
+
+ bool res = this->QMainWindow::event(e);
+
+ if (e->type() == QEvent::HoverMove
+ || e->type() == QEvent::MouseMove
+ || e->type() == QEvent::Move) {
+ if (res) {
+ FQ_TRACE("frameEvent", 10) << "Accept event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ } else {
+ FQ_TRACE("frameEvent", 10) << "Ignore event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ }
+ } else {
+ if (res) {
+ FQ_TRACE("frameEvent", 9) << "Accept event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ } else {
+ FQ_TRACE("frameEvent", 9) << "Ignore event: " << e->type()
+ << " " << getEventName(e->type()) << ".";
+ }
+ }
+
+ return res;
+}
+
+void FQTermFrame::keyClicked(int id) {
+ if (windowManager_->activeWindow() == NULL) {
+ return ;
+ }
+
+ QString strItem = QString("key%1").arg(id);
+ QString strTmp = config_->getItemValue("key", strItem);
+
+ if (strTmp[0] == '0') { // key
+ windowManager_->activeWindow()->externInput(strTmp.mid(1));
+ } else if (strTmp[0] == '1') { // script
+ QString scriptFile = strTmp.mid(1).trimmed();
+#ifdef HAVE_PYTHON
+ if (scriptFile.endsWith(".py", Qt::CaseInsensitive))
+ windowManager_->activeWindow()->runPythonScriptFile(scriptFile);
+ else
+#endif
+ windowManager_->activeWindow()->runScript(scriptFile.toAscii());
+ } else if (strTmp[0] == '2') { // program
+ runProgram(strTmp.mid(1));
+ }
+}
+
+void FQTermFrame::addMainTool() {
+ // the main toolbar
+ toolBarMdiTools_ = addToolBar("Main ToolBar");
+ toolBarMdiTools_->setObjectName("Main ToolBar");
+
+ connectButton_ = new QToolButton(toolBarMdiTools_);
+ connectButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/connect.png"));
+
+ toolBarMdiTools_->addWidget(connectButton_);
+ menuConnect_ = new QMenu(this);
+ //FIXME: autoupdate menu
+ FQ_VERIFY(connect(menuConnect_, SIGNAL(aboutToShow()),
+ this, SLOT(popupConnectMenu())));
+ connectButton_->setMenu(menuConnect_);
+ connectButton_->setPopupMode(QToolButton::InstantPopup);
+
+ toolBarMdiTools_->addAction(getAction(FQTermShortcutHelper::QUICKLOGIN));
+
+ serverButton_ = new QToolButton(toolBarMdiTools_);
+ serverButton_->setCheckable(true);
+ serverButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/fqterm_32x32.png"));
+ serverButton_->setChecked(FQTermPref::getInstance()->runServer_);
+ FQ_VERIFY(connect(serverButton_, SIGNAL(toggled(bool)), this, SLOT(toggleServer(bool))));
+ toolBarMdiTools_->addWidget(serverButton_);
+ // custom define
+ toolBarSetupKeys_ = addToolBar("Custom Key");
+ toolBarSetupKeys_->setObjectName("Custom Key");
+
+ // the toolbar
+ toolBarMdiConnectTools_ = addToolBar("BBS operations");
+ toolBarMdiConnectTools_->setObjectName("BBS operations");
+ FQTERM_ADDACTION(toolBarMdiConnectTools_, DISCONNECT, this, disconnect);
+ getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(false);
+ toolBarMdiConnectTools_->addSeparator();
+
+ //Font Tool Bar
+ toolBarFonts_ = addToolBar("Font ToolBar");
+ toolBarFonts_->setObjectName("Font ToolBar");
+
+
+
+ // Edit (5)
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPY));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::PASTE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPYWITHCOLOR));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::RECTANGLESELECTION));
+ toolBarMdiConnectTools_->addSeparator();
+
+ //Font
+ fontButton_ = new QToolButton(toolBarFonts_);
+ QAction* dummyAction = new QAction(QPixmap(getPath(RESOURCE) + "pic/change_fonts.png"),
+ tr("Set Terminal Fonts"), fontButton_);
+ fontButton_->setDefaultAction(dummyAction);
+ toolBarFonts_->addWidget(fontButton_);
+ fontButton_->setMenu(menuFont_);
+ fontButton_->setPopupMode(QToolButton::InstantPopup);
+
+ toolBarFonts_->addSeparator();
+ englishFontCombo_ = new QFontComboBox(toolBarFonts_);
+ otherFontCombo_ = new QFontComboBox(toolBarFonts_);
+ QLabel *englishFontLabel = new QLabel(toolBarFonts_);
+ englishFontLabel->setPixmap(QPixmap(getPath(RESOURCE) + "pic/english_font.png"));
+ toolBarFonts_->addWidget(englishFontLabel);
+ toolBarFonts_->addWidget(englishFontCombo_);
+ toolBarFonts_->addSeparator();
+ QLabel *otherFontLabel = new QLabel(toolBarFonts_);
+ otherFontLabel->setPixmap(QPixmap(getPath(RESOURCE) + "pic/other_font.png"));
+ toolBarFonts_->addWidget(otherFontLabel);
+ toolBarFonts_->addWidget(otherFontCombo_);
+ FQ_VERIFY(connect(englishFontCombo_, SIGNAL(currentFontChanged(const QFont&)),
+ this, SLOT(comboFontChanged(const QFont&))));
+ FQ_VERIFY(connect(otherFontCombo_, SIGNAL(currentFontChanged(const QFont&)),
+ this, SLOT(comboFontChanged(const QFont&))));
+
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COLORSETTING));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::ANSICOLOR));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::REFRESHSCREEN));
+ toolBarMdiConnectTools_->addSeparator();
+
+ // Option
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::CURRENTSETTING));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::SAVESETTING));
+ toolBarMdiConnectTools_->addSeparator();
+
+ // Spec (5)
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPYARTICLE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::ANTIIDLE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::AUTOREPLY));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::VIEWMESSAGE));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::IMAGEVIEWER));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::MOUSESUPPORT));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::BEEP));
+ toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::AUTORECONNECT));
+
+ //call popupConnectMenu() to enable the shortcuts
+ popupConnectMenu();
+
+
+}
+
+
+QAction* FQTermFrame::getAction(int shortcut) {
+ if (!shortcutHelper_)
+ return NULL;
+ return shortcutHelper_->getAction(shortcut);
+}
+
+
+
+void FQTermFrame::addMainMenu() {
+ menuMain_ = menuBar();
+
+ //File Menu
+ menuFile_ = menuMain_->addMenu(tr("&File"));
+
+ FQTERM_ADDACTION(menuFile_, CONNECT, this, connectIt);
+ FQTERM_ADDACTION(menuFile_, DISCONNECT, this, disconnect);
+ menuFile_->addSeparator();
+ FQTERM_ADDACTION(menuFile_, ADDRESSBOOK, this, addressBook);
+ FQTERM_ADDACTION(menuFile_, QUICKLOGIN, this, quickLogin);
+ menuFile_->addSeparator();
+ FQTERM_ADDACTION(menuFile_, EXIT, this, exitFQTerm);
+ getAction(FQTermShortcutHelper::EXIT)->setMenuRole(QAction::QuitRole);
+
+ //Edit Menu
+ QMenu *edit = menuMain_->addMenu(tr("&Edit"));
+
+ FQTERM_ADDACTION(edit, COPY, this, copy);
+ FQTERM_ADDACTION(edit, PASTE, this, paste);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, COPYWITHCOLOR, this, copyColor);
+ FQTERM_ADDACTION(edit, RECTANGLESELECTION, this, copyRect);
+ FQTERM_ADDACTION(edit, AUTOCOPYSELECTION, this, autoCopy);
+ FQTERM_ADDACTION(edit, PASTEWORDWRAP, this, wordWrap);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, SEARCHIT, this, searchIt);
+ FQTERM_ADDACTION(edit, WEIBOSHARE, this, shareIt);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, EXTERNALEDITOR, this, externalEditor);
+ edit->addSeparator();
+ FQTERM_ADDACTION(edit, FASTPOST, this, fastPost);
+ edit->addSeparator();
+
+ QMenu *escapeMenu = edit->addMenu(tr("Control sequence in clipboar&d"));
+ escapeGroup = new QActionGroup(this);
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_NO,this, noEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_NO));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_SMTH,this, escEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_SMTH));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_PTT,this, uEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_PTT));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_OLD_CUSTOM,this, oldCustomEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM));
+ FQTERM_ADDACTION(escapeMenu, COLORCTL_CUSTOM,this, customEsc);
+ escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_CUSTOM));
+
+ //View menu
+ QMenu *view = menuMain_->addMenu(tr("&View"));
+
+ menuFont_ = view->addMenu(tr("&Font"));
+ menuFont_->setIcon(QPixmap(getPath(RESOURCE) + "pic/change_fonts.png"));
+ view->addMenu(menuFont_);
+ FQTERM_ADDACTION(menuFont_, OTHERFONT, this, setFont);
+ getAction(FQTermShortcutHelper::OTHERFONT)->setData(0);
+ FQTERM_ADDACTION(menuFont_, ENGLISHFONT, this, setFont);
+ getAction(FQTermShortcutHelper::ENGLISHFONT)->setData(1);
+ FQTERM_ADDACTION(view, COLORSETTING, this, setColor);
+ FQTERM_ADDACTION(view, ANSICOLOR, this, toggleAnsiColor);
+ FQTERM_ADDACTION(view, REFRESHSCREEN, this, refreshScreen);
+ view->addSeparator();
+
+ //language menu
+ languageGroup = new QActionGroup(view);
+ languageGroup->setExclusive(true);
+ if (installerList_.isEmpty()) {
+ FQ_TRACE("frame", 0)
+ << "No language menu because of lack of translation files";
+ } else {
+ menuLanguage_ = view->addMenu(tr("&Language"));
+ FQTERM_ADDACTION(menuLanguage_, LANGUAGE_ENGLISH, this, langEnglish);
+ languageGroup->addAction(getAction(FQTermShortcutHelper::LANGUAGE_ENGLISH));
+
+ foreach(TranslatorInstaller* installer, installerList_) {
+ QAction* action = menuLanguage_->addAction(
+ installer->languageName(), installer, SLOT(installTranslator()));
+ action->setCheckable(true);
+ languageGroup->addAction(action);
+ }
+
+ }
+
+ FQTERM_ADDACTION(view, UIFONT, this, uiFont);
+
+ menuThemes_ = view->addMenu(tr("&Themes"));
+ FQ_VERIFY(connect(menuThemes_, SIGNAL(aboutToShow()), this, SLOT(themesMenuAboutToShow())));
+
+ FQTERM_ADDACTION(view, FULLSCREEN, this, fullscreen);
+ FQTERM_ADDACTION(view, BOSSCOLOR, this, bosscolor);
+
+ view->addSeparator();
+
+ QMenu *scrollMenu = view->addMenu(tr("&ScrollBar"));
+ scrollGroup = new QActionGroup(this);
+ FQTERM_ADDACTION(scrollMenu, SCROLLBAR_HIDDEN,this, hideScroll);
+ scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_HIDDEN));
+ FQTERM_ADDACTION(scrollMenu, SCROLLBAR_RIGHT,this, rightScroll);
+ scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_RIGHT));
+ FQTERM_ADDACTION(scrollMenu, SCROLLBAR_LEFT,this, leftScroll);
+ scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_LEFT));
+
+ FQTERM_ADDACTION(view, SWITCHBAR, this, showSwitchBar);
+ // Option Menu
+ QMenu *option = menuMain_->addMenu(tr("&Option"));
+
+ FQTERM_ADDACTION(option, CURRENTSETTING, this, setting);
+ FQTERM_ADDACTION(option, SAVESETTING, this, saveSessionSetting);
+ option->addSeparator();
+ FQTERM_ADDACTION(option, DEFAULTSETTING, this, defaultSetting);
+#ifdef Q_OS_MAC
+ FQTERM_ADDACTION(menuFile_, PREFERENCE, this, preference);
+#else
+ FQTERM_ADDACTION(option, PREFERENCE, this, preference);
+#endif
+ getAction(FQTermShortcutHelper::PREFERENCE)->setMenuRole(QAction::PreferencesRole);
+ FQTERM_ADDACTION(option, SHORTCUTSETTING, this, shortcutSetting);
+ option->addSeparator();
+ FQTERM_ADDACTION(option, EDITSCHEMA, this, editSchema);
+ option->addSeparator();
+
+ QMenu *searchEngineMenu = option->addMenu(tr("Searc&h Engine"));
+ searchEngineGroup = new QActionGroup(this);
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_GOOGLE,this, setSEGoogle);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_GOOGLE));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_BAIDU,this, setSEBaidu);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_BAIDU));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_BING,this, setSEBing);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_BING));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_YAHOO,this, setSEYahoo);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_YAHOO));
+ FQTERM_ADDACTION(searchEngineMenu, SEARCH_CUSTOM,this, setSECustom);
+ searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_CUSTOM));
+
+ // Special
+ QMenu *spec = menuMain_->addMenu(tr("&Special"));
+ FQTERM_ADDACTION(spec, COPYARTICLE, this, copyArticle);
+ FQTERM_ADDACTION(spec, ANTIIDLE, this, antiIdle);
+ FQTERM_ADDACTION(spec, AUTOREPLY, this, autoReply);
+ FQTERM_ADDACTION(spec, VIEWMESSAGE, this, viewMessages);
+ FQTERM_ADDACTION(spec, BEEP, this, beep);
+ FQTERM_ADDACTION(spec, MOUSESUPPORT, this, enableMouse);
+ FQTERM_ADDACTION(spec, IMAGEVIEWER, this, viewImages);
+ FQTERM_ADDACTION(spec, IPLOOKUP, this, ipLookup);
+
+ //Script
+ QMenu *script = menuMain_->addMenu(tr("Scrip&t"));
+ FQTERM_ADDACTION(script, RUNSCRIPT, this, runScript);
+ FQTERM_ADDACTION(script, STOPSCRIPT, this, stopScript);
+#ifdef HAVE_PYTHON
+ script->addSeparator();
+ FQTERM_ADDACTION(script, RUNPYTHONSCRIPT, this, runPyScript);
+#endif //HAVE_PYTHON
+
+ //Window menu
+ menuWindows_ = menuMain_->addMenu(tr("&Windows"));
+ FQ_VERIFY(connect(menuWindows_, SIGNAL(aboutToShow()),this, SLOT(windowsMenuAboutToShow())));
+ menuMain_->addSeparator();
+
+ //Help menu
+ QMenu *help = menuMain_->addMenu(tr("&Help"));
+ FQTERM_ADDACTION(help, ABOUT, this, aboutFQTerm);
+ getAction(FQTermShortcutHelper::ABOUT)->setMenuRole(QAction::AboutRole);
+ FQTERM_ADDACTION(help, HOMEPAGE, this, homepage);
+}
+
+void FQTermFrame::updateMenuToolBar() {
+ FQTermWindow *window = windowManager_->activeWindow();
+
+ if (window == NULL) {
+ return ;
+ }
+
+ // update menu
+ getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(window->isConnected());
+ getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setChecked(window->getSession()->param().isColorCopy_);
+ getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setChecked(window->getSession()->param().isRectSelect_);
+ getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setChecked(window->getSession()->param().isAutoCopy_);
+ getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setChecked(window->getSession()->param().isAutoWrap_);
+ getAction(FQTermShortcutHelper::FULLSCREEN)->setChecked(windowState() & Qt::WindowFullScreen);
+ getAction(FQTermShortcutHelper::ANSICOLOR)->setChecked(window->getSession()->param().isAnsiColor_);
+ getAction(FQTermShortcutHelper::ANTIIDLE)->setChecked(window->getSession()->isAntiIdle());
+ getAction(FQTermShortcutHelper::AUTOREPLY)->setChecked(window->getSession()->isAutoReply());
+ getAction(FQTermShortcutHelper::BEEP)->setChecked(window->getSession()->param().isBeep_);
+ getAction(FQTermShortcutHelper::MOUSESUPPORT)->setChecked(window->getSession()->param().isSupportMouse_);
+ getAction(FQTermShortcutHelper::AUTORECONNECT)->setChecked(window->getSession()->param().isAutoReconnect_);
+
+ updateFontCombo();
+}
+
+void FQTermFrame::updateFontCombo() {
+ FQTermWindow *window = windowManager_->activeWindow();
+
+ if (window == NULL) {
+ return ;
+ }
+ englishFontCombo_->blockSignals(true);
+ otherFontCombo_->blockSignals(true);
+ englishFontCombo_->setCurrentFont(window->getScreen()->termFont(true));
+ otherFontCombo_->setCurrentFont(window->getScreen()->termFont(false));
+ englishFontCombo_->blockSignals(false);
+ otherFontCombo_->blockSignals(false);
+}
+
+void FQTermFrame::termFontChange(bool isEnglish, QFont font) {
+ updateFontCombo();
+}
+
+void FQTermFrame::comboFontChanged(const QFont & font) {
+
+ FQTermWindow *window = windowManager_->activeWindow();
+
+ if (window == NULL) {
+ return ;
+ }
+
+ window->getScreen()->blockSignals(true);
+
+ bool isEnglish = (sender() == (QObject*)englishFontCombo_);
+
+ QString& fontName = isEnglish?
+ window->getSession()->param().englishFontName_:window->getSession()->param().otherFontName_;
+ int& fontSize = isEnglish?
+ window->getSession()->param().englishFontSize_:window->getSession()->param().otherFontSize_;
+ QFontComboBox* combo = isEnglish ? englishFontCombo_ : otherFontCombo_;
+
+ QFont f(combo->currentFont().family(), window->getScreen()->termFont(true).pointSize());
+
+ window->getScreen()->setTermFont(isEnglish, f);
+
+ fontName = f.family();
+ fontSize = f.pointSize();
+
+ window->getScreen()->blockSignals(false);
+
+ window->forcedRepaintScreen();
+}
+
+void FQTermFrame::enableMenuToolBar(bool enable) {
+ getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::COPY)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::PASTE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::ANSICOLOR)->setEnabled(enable);
+
+ fontButton_->setEnabled(enable);
+ englishFontCombo_->setEnabled(enable);
+ otherFontCombo_->setEnabled(enable);
+ menuFont_->setEnabled(enable);
+
+ getAction(FQTermShortcutHelper::COLORSETTING)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::REFRESHSCREEN)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::CURRENTSETTING)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::SAVESETTING)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::COPYARTICLE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::ANTIIDLE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::AUTOREPLY)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::VIEWMESSAGE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::BEEP)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::MOUSESUPPORT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::RUNSCRIPT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::STOPSCRIPT)->setEnabled(enable);
+#ifdef HAVE_PYTHON
+ getAction(FQTermShortcutHelper::RUNPYTHONSCRIPT)->setEnabled(enable);
+#endif
+ getAction(FQTermShortcutHelper::SEARCHIT)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::WEIBOSHARE)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::EXTERNALEDITOR)->setEnabled(enable);
+ getAction(FQTermShortcutHelper::FASTPOST)->setEnabled(enable);
+}
+
+void FQTermFrame::updateKeyToolBar() {
+ toolBarSetupKeys_->clear();
+ toolBarSetupKeys_->addAction(QPixmap(getPath(RESOURCE) + "pic/setup_shortcuts.png"),
+ tr("Key Setup"), this, SLOT(keySetup()));
+
+ QString strItem, strTmp;
+ strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+
+ for (int i = 0; i < num; i++) {
+ strItem = QString("name%1").arg(i);
+ strTmp = config_->getItemValue("key", strItem);
+ FQTermToolButton *button =
+ new FQTermToolButton(toolBarSetupKeys_, i, strTmp);
+ button->setText(strTmp);
+ strItem = QString("key%1").arg(i);
+ strTmp = (config_->getItemValue("key", strItem));
+ //TODO: add tool tip here
+ // QToolTip::add( button, strTmp.mid(1) );
+ // button->addToolTip(strTmp.mid(1));
+
+ strTmp = config_->getItemValue("key", QString("shortcut%1").arg(i));
+ if (!strTmp.isEmpty()) {
+ QAction *act = new QAction(button);
+ act->setShortcut(strTmp);
+ button->addAction(act);
+ FQ_VERIFY(connect(act, SIGNAL(triggered()), button, SLOT(slotClicked())));
+ }
+
+ FQ_VERIFY(connect(button, SIGNAL(buttonClicked(int)),
+ this, SLOT(keyClicked(int))));
+ toolBarSetupKeys_->addWidget(button);
+ }
+
+
+
+}
+
+
+void FQTermFrame::popupFocusIn(FQTermWindow*) {
+ // bring to font
+ if (isHidden()) {
+ show();
+ }
+ if (isMinimized()) {
+ if (isMaximized()) {
+ showMaximized();
+ } else {
+ showNormal();
+ }
+ }
+ raise();
+ activateWindow();
+}
+
+void FQTermFrame::insertThemeItem(const QString& themeitem) {
+ QAction *idAction;
+
+ idAction = menuThemes_->addAction(themeitem,
+ this, SLOT(themesMenuActivated()));
+ idAction->setCheckable(true);
+ idAction->setChecked(themeitem == theme_);
+}
+
+void FQTermFrame::setUseDock(bool use) {
+ if (use == false) {
+ if (tray_) {
+ tray_->hide();
+ delete tray_;
+ tray_ = 0;
+ //delete menuTray_;
+ //menuTray_ = 0;
+ }
+ return ;
+ }
+
+ if (tray_ || !QSystemTrayIcon::isSystemTrayAvailable()) {
+ return ;
+ }
+
+ trayMenu_ = new QMenu;
+ FQ_VERIFY(connect(trayMenu_, SIGNAL(aboutToShow()), SLOT(buildTrayMenu())));
+
+ tray_ = new QSystemTrayIcon(this);
+ tray_->setIcon(QPixmap(getPath(RESOURCE) + "pic/fqterm_tray.png"));
+ tray_->setContextMenu(trayMenu_);
+ FQ_VERIFY(connect(tray_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+ SLOT(trayActived(QSystemTrayIcon::ActivationReason))));
+ tray_->show();
+}
+
+void FQTermFrame::buildTrayMenu() {
+ if (!trayMenu_) {
+ return ;
+ }
+ trayMenu_->clear();
+
+ if (isHidden()) {
+ trayMenu_->addAction(tr("Show"), this, SLOT(trayShow()));
+ } else {
+ trayMenu_->addAction(tr("Hide"), this, SLOT(trayHide()));
+ }
+ trayMenu_->addSeparator();
+ trayMenu_->addAction(tr("About"), this, SLOT(aboutFQTerm()));
+ trayMenu_->addAction(tr("Exit"), this, SLOT(exitFQTerm()));
+}
+
+void FQTermFrame::trayActived(QSystemTrayIcon::ActivationReason reason) {
+ if (reason == QSystemTrayIcon::Context) {
+ return ;
+ }
+ if (!isVisible()) {
+ trayShow();
+ } else {
+ trayHide();
+ }
+}
+
+void FQTermFrame::trayShow() {
+ show();
+ // bring to font
+ if (isHidden()) {
+ show();
+ }
+ if (isMinimized()) {
+ if (isMaximized()) {
+ showMaximized();
+ } else {
+#ifdef Q_OS_MACX
+ showMaximized();
+#else
+ showNormal();
+#endif
+ }
+ }
+ raise();
+ activateWindow();
+ FQTermWindow* window = windowManager_->activeWindow();
+ if (window) {
+ window->forcedRepaintScreen();
+ if (!window->isMaximized()) {
+ windowManager_->refreshAllExcept(window);
+ }
+ }
+}
+
+void FQTermFrame::trayHide() {
+ static bool showTip = true;
+ QString str = config_->getItemValue("global", "traytipshown");
+ if (str == "1") {
+ showTip = false;
+ }
+ hide();
+ if (showTip && tray_) {
+ tray_->showMessage(tr("FQTerm"),
+ tr("FQTerm will keep running in the system tray.\n"
+ "To terminate the program, "
+ "choose exit in the tray menu."));
+ showTip = false;
+ config_->setItemValue("global", "traytipshown", "1");
+ }
+}
+
+void FQTermFrame::buzz(FQTermWindow* window) {
+ if (windowManager_->activeWindow() == window)
+ return;
+ int xp = x();
+ int yp = y();
+ QTime t;
+
+ t.start();
+ for (int i = 32; i > 0;) {
+ if (t.elapsed() >= 1) {
+ int delta = i >> 2;
+ int dir = i &3;
+ int dx = ((dir == 1) || (dir == 2)) ? delta : -delta;
+ int dy = (dir < 2) ? delta : -delta;
+ move(xp + dx, yp + dy);
+ t.restart();
+ i--;
+ }
+ }
+ move(xp, yp);
+}
+
+
+//--------------------------
+//recreate the main menu
+//--------------------------
+void
+FQTermFrame::recreateMenu() {
+
+ if (shortcutHelper_) {
+ shortcutHelper_->retranslateActions();
+ }
+ menuBar()->clear();
+ delete escapeGroup;
+ delete languageGroup;
+ addMainMenu();
+ updateLanguageMenu();
+
+ QString strTmp = QString(saveState().toHex());
+ config_->setItemValue("global", "toolbarstate", strTmp);
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ delete toolBarMdiTools_;
+ delete toolBarSetupKeys_;
+ delete toolBarMdiConnectTools_;
+ delete toolBarFonts_;
+ delete menuConnect_;
+ addMainTool();
+ updateKeyToolBar();
+ loadToolBarPosition();
+ if (!windowManager_->activeWindow()) {
+ enableMenuToolBar(false);
+ } else {
+ enableMenuToolBar(true);
+ updateMenuToolBar();
+ }
+ if (FQTermPref::getInstance()->useStyleSheet_) {
+ refreshStyleSheet();
+ }
+}
+
+void FQTermFrame::installTranslator(const QString& lang) {
+ config_->setItemValue("global", "language", lang);
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+
+ for (int i = 0; i < translatedModule; ++i) {
+ if (translator[i] != 0) {
+ qApp->removeTranslator(translator[i]);
+ delete translator[i];
+ translator[i] = 0;
+ }
+ }
+
+ if (lang != "en_US" && !lang.isEmpty()) {
+ for (int i = 0; i < translatedModule; ++i) {
+ QString dict =
+ getPath(RESOURCE) + "dict/" + qmPrefix[i] + lang + qmPostfix;
+ translator[i] = new QTranslator(0);
+ translator[i]->load(dict);
+ qApp->installTranslator(translator[i]);
+ }
+ }
+
+ emit changeLanguage();
+}
+
+void FQTermFrame::initTranslator() {
+ QString dict_path = getPath(RESOURCE) + "dict/";
+ QDir dictDir(dict_path);
+ QStringList langList;
+
+ for (int i = 0; i < translatedModule; ++i) {
+ translator[i] = 0;
+ QStringList filter;
+ filter << qmPrefix[i] + "*" + qmPostfix;
+ dictDir.setNameFilters(filter);
+ QFileInfoList list = dictDir.entryInfoList();
+
+ FQ_TRACE("translator", 3) << "Found " << list.size()
+ << " " << qmPostfix
+ << " file(s) under path "
+ << dict_path;
+
+ foreach(QFileInfo info, list){
+ QString language = info.fileName();
+ language = language.mid(
+ qmPrefix[i].length(),
+ language.length() - qmPrefix[i].length() - qmPostfix.length());
+
+ FQ_TRACE("translator", 3) << "Check file " << info.fileName();
+
+ if (!langList.contains(language)) {
+ langList << language;
+ installerList_.append(new TranslatorInstaller(language, this));
+ FQ_TRACE("translator", 3) << "Found translations for " << language;
+ } else {
+ FQ_TRACE("translator", 3) << "Language " << language
+ << " is already registered.";
+ }
+ }
+ }
+
+ if (installerList_.empty()) {
+ FQ_TRACE("translator", 0) << "No translations found.";
+ }
+
+ QString lang = config_->getItemValue("global", "language");
+ if (!langList.contains(lang)) {
+ lang = QLocale::system().name();
+ }
+#if defined(__linux__) || defined(__GLIBC__)
+ if (QLocale::system().language() == QLocale::English)
+ lang = QLocale::system().name();
+#endif
+ installTranslator(lang);
+}
+
+
+void FQTermFrame::clearTranslator() {
+ foreach(TranslatorInstaller* installer, installerList_){
+ delete installer;
+ }
+}
+
+void FQTermFrame::updateLanguageMenu() {
+ QString strTmp = config_->getItemValue("global", "language");
+ int i = 0;
+ foreach(TranslatorInstaller* installer, installerList_){
+ if (installer->languageFormalName() == strTmp) {
+ languageGroup->actions().at(i + 1)->setChecked(true);
+ break;
+ }
+ ++i;
+ }
+ if (!installerList_.isEmpty() &&
+ (strTmp == "en_US" || i == installerList_.size())) {
+ languageGroup->actions().at(0)->setChecked(true);
+ }
+}
+
+void FQTermFrame::setFont() {
+ bool isEnglish = (QAction*)(sender()) == getAction(FQTermShortcutHelper::ENGLISHFONT);
+ windowManager_->activeWindow()->setFont(isEnglish);
+}
+
+void FQTermFrame::refreshStyleSheet()
+{
+ qApp->setStyleSheet(qApp->styleSheet());
+}
+void FQTermFrame::loadStyleSheetFromFile( const QString qssFile )
+{
+ QFile file(qssFile);
+ file.open(QIODevice::ReadOnly);
+ QString qss = file.readAll();
+ qApp->setStyleSheet(qss);
+ file.close();
+}
+
+void FQTermFrame::clearStyleSheet() {
+ qApp->setStyleSheet("");
+}
+
+void FQTermFrame::loadToolBarPosition()
+{
+ //load toolbar setting
+ QString strTmp = config_->getItemValue("global", "toolbarstate");
+ if (!strTmp.isEmpty())
+ {
+ restoreState(QByteArray::fromHex(strTmp.toAscii()));
+ } else {
+ addToolBar(Qt::TopToolBarArea, toolBarMdiConnectTools_);
+ insertToolBar(toolBarMdiConnectTools_,toolBarSetupKeys_);
+ insertToolBar(toolBarSetupKeys_, toolBarMdiTools_);
+ insertToolBar(toolBarMdiTools_, toolBarFonts_);
+ }
+}
+
+void FQTermFrame::toggleAnsiColor() {
+ windowManager_->activeWindow()->getSession()->param().isAnsiColor_
+ = !windowManager_->activeWindow()->getSession()->param().isAnsiColor_;
+ getAction(FQTermShortcutHelper::ANSICOLOR)->setChecked(
+ windowManager_->activeWindow()->getSession()->param().isAnsiColor_);
+ refreshScreen();
+}
+
+bool FQTermFrame::clearUp() {
+ if (!windowManager_->closeAllWindow())
+ return false;
+
+ saveSetting();
+ // clear zmodem and pool if needed
+ if (FQTermPref::getInstance()->needClearZmodemPoolOnClose_) {
+ clearDir(FQTermPref::getInstance()->zmodemDir_);
+ clearDir(FQTermPref::getInstance()->poolDir_);
+ clearDir(FQTermPref::getInstance()->poolDir_ + "shadow-cache/");
+ }
+
+ setUseDock(false);
+
+ return true;
+}
+
+void FQTermFrame::editSchema() {
+
+ schemaDialog schema(this);
+ FQ_VERIFY(connect(&schema, SIGNAL(schemaEdited()),
+ this, SLOT(schemaUpdated())));
+ schema.exec();
+}
+
+void FQTermFrame::schemaUpdated() {
+ for (int i = 0; i < windowManager_->count(); ++i) {
+ windowManager_->nthWindow(i)->getScreen()->setSchema();
+ windowManager_->nthWindow(i)->forcedRepaintScreen();
+ }
+}
+
+
+void FQTermFrame::globalHotkeyTriggered() {
+ if (isActiveWindow() && !isMinimized() && isVisible())
+ {
+ showMinimized();
+ return;
+ }
+ show();
+ if (config_->getItemValue("global", "fullscreen") == "1")
+ showFullScreen();
+ else if (config_->getItemValue("global", "max") == "1")
+ showMaximized();
+ else
+ showNormal();
+ raise();
+ activateWindow();
+}
+
+void FQTermFrame::globalHotkeyChanged()
+{
+#ifdef USE_GLOBAL_HOTKEY
+ globalHotkey_->setShortcut(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM)->shortcut());
+#endif //USE_GLOBAL_HOTKEY
+}
+
+
+
+TranslatorInstaller::TranslatorInstaller(const QString& language,
+ FQTermFrame* frame)
+ : language_(language),
+ frame_(frame) {
+ FQTermConfig conf(getPath(USER_CONFIG) + "language.cfg");
+
+ languageName_ = conf.getItemValue("Name", language_);
+ if (languageName_.isEmpty()){
+ languageName_ = QLocale::languageToString(QLocale(language_).language());
+ if (languageName_ == "C") {
+ languageName_ = "Unknown Language";
+ }
+ }
+}
+
+QString TranslatorInstaller::languageName() {
+ return languageName_;
+}
+
+void TranslatorInstaller::installTranslator() {
+ frame_->installTranslator(language_);
+}
+
+QString TranslatorInstaller::languageFormalName() {
+ return language_;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_frame.moc"
diff --git a/src/fqterm/fqterm_frame.h b/src/fqterm/fqterm_frame.h
new file mode 100644
index 0000000..8adaf49
--- /dev/null
+++ b/src/fqterm/fqterm_frame.h
@@ -0,0 +1,326 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FRAME_H
+#define FQTERM_FRAME_H
+
+#include <QMainWindow>
+#include <QSystemTrayIcon>
+#include <QMenuBar>
+
+#include <vector>
+
+class QWidget;
+class QLineEdit;
+class QToolButton;
+class QMdiArea;
+class QSignalMapper;
+class QTabBar;
+class QFontDialog;
+class QActionGroup;
+class QString;
+class QFontComboBox;
+class UAOCodec;
+
+#ifdef USE_GLOBAL_HOTKEY
+class QxtGlobalShortcut;
+#endif //USE_GLOBAL_HOTKEY
+
+namespace FQTerm {
+
+class IPLookupDialog;
+class DefineEscapeDialog;
+class FQTermImage;
+class FQTermParam;
+class FQTermConfig;
+class FQTermWndMgr;
+class FQTermWindow;
+class StatusBar;
+class FQTermTimeLabel;
+class TranslatorInstaller;
+class FQTermMiniServerThread;
+class FQTermShortcutHelper;
+
+#ifdef HAVE_PYTHON
+class FQTermPythonHelper;
+#endif //HAVE_PYTHON
+
+class FQTermFrame: public QMainWindow {
+ Q_OBJECT;
+ public:
+ FQTermFrame();
+ ~FQTermFrame();
+
+ void updateMenuToolBar();
+ void enableMenuToolBar(bool);
+
+ void popupFocusIn(FQTermWindow*);
+
+ void viewImages(QString filename, bool raiseViewer);
+ void buzz(FQTermWindow* window = NULL);
+ void installTranslator(const QString& lang);
+ FQTermConfig * config() const { return config_; }
+
+ static const int translatedModule = 4;
+ static const QString qmPrefix[translatedModule];
+ static const QString qmPostfix;
+
+ signals:
+ void bossColor();
+ void updateScroll();
+ void changeLanguage();
+ void fontAntiAliasing(bool);
+
+ protected slots:
+
+ bool event(QEvent *event);
+
+ void viewImages();
+ bool clearUp();
+
+ // Menu
+ void recreateMenu();
+ void addressBook();
+ void quickLogin();
+ void exitFQTerm();
+
+ void aboutFQTerm();
+ void langEnglish();
+ void defaultSetting();
+ void preference();
+ void shortcutSetting();
+ void runScript();
+ void delayedRunScript(); // to avoid activate recursion guard
+ void stopScript();
+ void runPyScript();
+ void homepage();
+
+ void toggleAnsiColor();
+
+ // Toolbar
+ void keyClicked(int);
+
+ void connectIt();
+ void disconnect();
+ void copy();
+ void paste();
+ void searchIt();
+ void shareIt();
+ void externalEditor();
+ void fastPost();
+ void copyRect();
+ void copyColor();
+ void copyArticle();
+ void autoCopy();
+ void wordWrap();
+ void noEsc();
+ void escEsc();
+ void uEsc();
+ void oldCustomEsc();
+ void customEsc();
+ void hideScroll();
+ void leftScroll();
+ void rightScroll();
+ void setSEGoogle();
+ void setSEBaidu();
+ void setSEYahoo();
+ void setSEBing();
+ void setSECustom();
+ void showSwitchBar();
+ void setFont();
+ void setColor();
+ void refreshScreen();
+ void fullscreen();
+ void bosscolor();
+ void toggleServer(bool on);
+ void uiFont();
+ void antiIdle();
+ void autoReply();
+ void setting();
+ void saveSessionSetting();
+ void viewMessages();
+ void enableMouse();
+ void beep();
+ void reconnect();
+ void keySetup();
+ void ipLookup();
+ void termFontChange(bool isEnglish, QFont font);
+ void comboFontChanged(const QFont & font);
+
+ void themesMenuAboutToShow();
+ void themesMenuActivated();
+ void windowsMenuAboutToShow();
+ void connectMenuActivated();
+ void popupConnectMenu();
+ void trayActived(QSystemTrayIcon::ActivationReason);
+
+ //void trayClicked(const QPoint &, int);
+ //void trayDoubleClicked();
+ void trayHide();
+ void trayShow();
+ void buildTrayMenu();
+
+ void reloadConfig();
+
+ void saveSetting();
+ void schemaUpdated();
+ void editSchema();
+ private:
+
+ FQTermWndMgr *windowManager_;
+ // image viewer
+ FQTermImage *imageViewer_;
+
+ FQTermTimeLabel *labelTime_;
+
+ QString theme_;
+
+ QActionGroup *escapeGroup;
+ QActionGroup *languageGroup;
+ QActionGroup *scrollGroup;
+ QActionGroup *searchEngineGroup;
+ QMenu *menuWindows_;
+ QMenu *menuThemes_;
+ QMenu *menuFont_;
+ QMenu *menuFile_;
+ QMenu *menuLanguage_;
+ QMenu *menuConnect_;
+ QSignalMapper* windowMapper_;
+
+ FQTerm::StatusBar *statusBar_;
+
+ QToolButton *serverButton_;
+ QToolButton *connectButton_;
+ QToolButton *fontButton_;
+ QFontComboBox *englishFontCombo_;
+ QFontComboBox *otherFontCombo_;
+
+ QMenuBar *menuMain_;
+ QToolBar *toolBarMdiConnectTools_;
+ QToolBar *toolBarMdiTools_;
+ QToolBar *toolBarSetupKeys_;
+ QToolBar *toolBarFonts_;
+
+ bool isTabBarShown_;
+
+ QSystemTrayIcon *tray_;
+
+ QMenu *trayMenu_;
+
+ QTranslator * translator[translatedModule];
+ QList<TranslatorInstaller*> installerList_;
+
+ FQTermConfig * config_;
+ FQTermShortcutHelper * shortcutHelper_;
+ QAction* getAction(int shortcut);
+ FQTermMiniServerThread* serverThread_;
+
+ UAOCodec* uaoCodec_;
+
+private:
+ void newWindow(const FQTermParam &param, int index = -1);
+
+ void closeEvent(QCloseEvent*);
+ void selectStyleMenu(int, int);
+ void iniSetting();
+ void loadPref();
+
+ void addMainMenu();
+ void addMainTool();
+
+ void setSE(const QString& se);
+
+ void updateKeyToolBar();
+ void updateFontCombo();
+
+ void loadToolBarPosition();
+
+ bool eventFilter(QObject *, QEvent*);
+
+ void insertThemeItem(const QString&);
+ void setUseDock(bool);
+
+ void initAdditionalActions();
+
+ void initTranslator();
+ void clearTranslator();
+ void connector();
+ void updateLanguageMenu();
+
+ void loadStyleSheetFromFile(const QString qssFile);
+ void refreshStyleSheet();
+ void clearStyleSheet();
+
+ bool isDelimiterExistedBefore(const QString& str,
+ const std::vector<QString>& existingDelimiters);
+ int isDelimiterExistedAfter(const QString& str,
+ const std::vector<QString>& existingDelimiters);
+ bool uppercaseCharFollowingCtrl(QString& str,
+ int& i,
+ const QString& after);
+ void replaceEscapeString(QString& str,
+ const QString& before,
+ const QString& after,
+ const QString& delimiter,
+ const std::vector<QString> *existingDelimiters = NULL);
+ void transEscapeStr(QString& target, const QString& source);
+
+#ifdef HAVE_PYTHON
+public:
+ FQTermPythonHelper* getPythonHelper() {
+ return pythonHelper_;
+ }
+
+ //protected slots:
+private:
+ FQTermPythonHelper* pythonHelper_;
+#endif //HAVE_PYTHON
+
+#ifdef USE_GLOBAL_HOTKEY
+ QxtGlobalShortcut* globalHotkey_;
+#endif //USE_GLOBAL_HOTKEY
+private slots:
+ void globalHotkeyTriggered();
+ void globalHotkeyChanged();
+};
+
+class TranslatorInstaller : public QObject
+{
+ Q_OBJECT;
+
+public:
+ TranslatorInstaller(const QString& language, FQTermFrame* frame);
+
+ QString languageName();
+ QString languageFormalName();
+public slots:
+ void installTranslator();
+
+protected:
+ QString language_;
+ FQTermFrame* frame_;
+
+ QString languageName_;
+};
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_FRAME_H
diff --git a/src/fqterm/fqterm_python.cpp b/src/fqterm/fqterm_python.cpp
new file mode 100644
index 0000000..68b9385
--- /dev/null
+++ b/src/fqterm/fqterm_python.cpp
@@ -0,0 +1,826 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+
+
+#include <QCustomEvent>
+#include <QTextStream>
+#include <QApplication>
+#include <QDir>
+#include <QFile>
+#include <QByteArray>
+#include <QMutex>
+#include <QThread>
+#include "fqterm.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif
+class SleeperThread : public QThread
+{
+public:
+ static void msleep(unsigned long msecs)
+ {
+ QThread::msleep(msecs);
+ }
+};
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_PYTHON
+
+#include "fqterm_window.h"
+#include "fqterm_buffer.h"
+#include "fqterm_text_line.h"
+#include "fqterm_param.h"
+#include "fqterm_session.h"
+#include "fqterm_python.h"
+#include "fqterm_path.h"
+#include "common.h"
+namespace FQTerm {
+
+/* **************************************************************************
+ *
+ * Pythons Embedding
+ *
+ * ***************************************************************************/
+
+QString getException() {
+ PyObject *pType = NULL, *pValue = NULL, *pTb = NULL, *pName, *pTraceback;
+
+ PyErr_Fetch(&pType, &pValue, &pTb);
+
+ pName = PyString_FromString("traceback");
+ pTraceback = PyImport_Import(pName);
+ Py_DECREF(pName);
+
+ if (pTraceback == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("format_exception");
+ PyObject *pRes = PyObject_CallMethodObjArgs(pTraceback, pName, pType, pValue,
+ pTb, NULL);
+ Py_DECREF(pName);
+
+ Py_DECREF(pTraceback);
+
+ Py_XDECREF(pType);
+ Py_XDECREF(pValue);
+ Py_XDECREF(pTb);
+
+ if (pRes == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("string");
+ PyObject *pString = PyImport_Import(pName);
+ Py_DECREF(pName);
+
+ if (pString == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("join");
+ PyObject *pErr = PyObject_CallMethodObjArgs(pString, pName, pRes, NULL);
+ Py_DECREF(pName);
+
+ Py_DECREF(pString);
+ Py_DECREF(pRes);
+
+ if (pErr == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ QString str(PyString_AsString(pErr));
+ Py_DECREF(pErr);
+
+ return str;
+}
+
+QString getErrOutputFile(FQTermWindow *lp) {
+ // file name
+ QString str2;
+ str2.setNum(long(lp));
+ str2 += ".err";
+ // path
+ return getPath(USER_CONFIG) + str2;
+}
+
+// copy current artcle for back compatible use only
+// for new coder please use getArticle
+static PyObject *fqterm_copyArticle(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ FQTermWindow *termWindow_ = (FQTermWindow*)lp;
+
+ QStringList strList;
+ QString strArticle;
+ QReadWriteLock& bufferLock = termWindow_->getSession()->getBufferLock();
+ QReadLocker locker(&bufferLock);
+ while (1) {
+ // check it there is duplicated string
+ // it starts from the end in the range of one screen height
+ // so this is a non-greedy match
+ QString strTemp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(0)->getAllPlainText(strTemp);
+ strTemp = strTemp.trimmed();
+ int i = 0;
+ int start = 0;
+ for (QStringList::Iterator it = strList.end();
+ it != strList.begin() && i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; // not exceeeding the last screen
+ --it, i++) {
+ if (*it != strTemp) {
+ continue;
+ }
+ QStringList::Iterator it2 = it;
+ bool dup = true;
+ // match more to see if its duplicated
+ for (int j = 0; j <= i; j++, it2++) {
+ QString str1;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(j)->getAllPlainText(str1);
+ if (*it2 != str1.trimmed()) {
+ dup = false;
+ break;
+ }
+ }
+ if (dup) {
+ // set the start point
+ start = i + 1;
+ break;
+ }
+ }
+ // add new lines
+ for (i = start; i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; i++) {
+ QString tmp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(i)->getAllPlainText(tmp);
+ strList += tmp.trimmed();
+ }
+
+ // the end of article
+ QString testEnd;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(termWindow_->getSession()->getBuffer()->getNumRows() - 1)->getAllPlainText(testEnd);
+ if (testEnd.indexOf("%") == -1) {
+ break;
+ }
+ // continue
+ termWindow_->writeString_ts(" ");
+
+ // TODO: fixme
+ if (!termWindow_->getSession()->getWaitCondition().wait(&bufferLock, 10000)) {
+ // // timeout
+ break;
+ }
+ }
+#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
+ strArticle = strList.join("\r\n");
+#else
+ strArticle = strList.join("\n");
+#endif
+
+ PyObject *py_text = PyString_FromString(strArticle.toUtf8());
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+static PyObject *fqterm_getArticle(PyObject *, PyObject *args) {
+ long lp;
+ int timeout;
+ int succeed = 1;
+
+ if (!PyArg_ParseTuple(args, "li", &lp, &timeout)) {
+ return NULL;
+ }
+ FQTermWindow *termWindow_ = (FQTermWindow*)lp;
+
+ QStringList strList;
+ QString strArticle;
+ QReadWriteLock& bufferLock = termWindow_->getSession()->getBufferLock();
+ while (!bufferLock.tryLockForRead()) {}
+ while (1) {
+ // check it there is duplicated string
+ // it starts from the end in the range of one screen height
+ // so this is a non-greedy match
+ QString strTemp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(0)->getAllPlainText(strTemp);
+ strTemp = strTemp.trimmed();
+
+ int i = 0;
+ int start = 0;
+ for (QStringList::Iterator it = strList.end();
+ it != strList.begin() && i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; // not exceeeding the last screen
+ --it, i++) {
+ if (it == strList.end() || *it != strTemp) {
+ continue;
+ }
+ QStringList::Iterator it2 = it;
+ bool dup = true;
+ // match more to see if its duplicated
+ for (int j = 0; j <= i && it2 != strList.end(); j++, it2++) {
+ QString str1;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(j)->getAllPlainText(str1);
+ if (*it2 != str1.trimmed()) {
+ dup = false;
+ break;
+ }
+ }
+ if (dup) {
+ // set the start point
+ start = i + 1;
+ break;
+ }
+ }
+ // add new lines
+ for (i = start; i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; i++) {
+ QString tmp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(i)->getAllPlainText(tmp);
+ strList += tmp.trimmed();
+ }
+
+ // the end of article
+ QString testEnd;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(termWindow_->getSession()->getBuffer()->getNumRows() - 1)->getAllPlainText(testEnd);
+ if (testEnd.indexOf("%") == -1) {
+ break;
+ }
+ // continue
+ termWindow_->writeString_ts(" ");
+
+ // TODO: fixme
+ if (!termWindow_->getSession()->getWaitCondition().wait(&bufferLock, timeout)) { // timeout
+ succeed = 0;
+ break;
+ }
+ }
+ bufferLock.unlock();
+ if (succeed)
+ strArticle = strList.join(OS_NEW_LINE);
+
+ PyObject *py_res = Py_BuildValue("si", (const char*)strArticle.toUtf8().data(),
+ succeed);
+
+ Py_INCREF(py_res);
+
+ return py_res;
+
+}
+
+static PyObject *fqterm_formatError(PyObject *, PyObject *args) {
+ long lp;
+
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ QString strErr;
+ QString filename = getErrOutputFile((FQTermWindow*)lp);
+
+ QDir d;
+ if (d.exists(filename)) {
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ QTextStream is(&file);
+ while (!is.atEnd()) {
+ strErr += is.readLine(); // line of text excluding '\n'
+ strErr += '\n';
+ }
+ file.close();
+ d.remove(filename);
+ }
+
+ if (!strErr.isEmpty()) {
+ ((FQTermWindow*)lp)->getPythonErrorMessage() = strErr;
+ // TODO: fixme
+ //qApp->postEvent((FQTermWindow*)lp, new QCustomEvent(PYE_ERROR));
+ } else {
+ // TODO: fixme
+ //qApp->postEvent((FQTermWindow*)lp, new QCustomEvent(PYE_FINISH));
+ }
+
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// caret x
+static PyObject *fqterm_caretX(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+ int x = ((FQTermWindow*)lp)->getSession()->getBuffer()->getCaretColumn();
+ PyObject *py_x = Py_BuildValue("i", x);
+ Py_INCREF(py_x);
+ return py_x;
+}
+
+// caret y
+static PyObject *fqterm_caretY(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+ int y = ((FQTermWindow*)lp)->getSession()->getBuffer()->getCaretRow();
+ PyObject *py_y = Py_BuildValue("i", y);
+ Py_INCREF(py_y);
+ return py_y;
+
+}
+
+// columns
+static PyObject *fqterm_columns(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ int numColumns = ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumColumns();
+ PyObject *py_columns = Py_BuildValue("i", numColumns);
+
+ Py_INCREF(py_columns);
+ return py_columns;
+
+}
+
+// rows
+static PyObject *fqterm_rows(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ int rows = ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows();
+ PyObject *py_rows = Py_BuildValue("i", rows);
+
+ Py_INCREF(py_rows);
+ return py_rows;
+}
+
+// sned string to server
+static PyObject *fqterm_sendString(PyObject *, PyObject *args) {
+ char *pstr;
+ long lp;
+
+ if (!PyArg_ParseTuple(args, "ls", &lp, &pstr)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->writeRawString_ts(U82U(pstr));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// input should be utf8.
+// same as above except parsing string first "\n" "^p" etc
+static PyObject *fqterm_sendParsedString(PyObject *, PyObject *args) {
+ char *pstr;
+ long lp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "ls", &lp, &pstr)) {
+ return NULL;
+ }
+ len = strlen(pstr);
+
+ ((FQTermWindow*)lp)->writeString_ts(U82U(pstr));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// get text at line
+static PyObject *fqterm_getText(PyObject *, PyObject *args) {
+ long lp;
+ int numRows;
+ if (!PyArg_ParseTuple(args, "li", &lp, &numRows)) {
+ return NULL;
+ }
+ QString str;
+ if (numRows < ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows())
+ ((FQTermWindow*)lp)->getSession()->getBuffer()->getTextLineInTerm(numRows)->getAllPlainText(str);
+
+ PyObject *py_text = PyString_FromString(U2U8(str));
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+// get text with attributes
+static PyObject *fqterm_getAttrText(PyObject *, PyObject *args) {
+ long lp;
+ int numRows;
+ if (!PyArg_ParseTuple(args, "li", &lp, &numRows)) {
+ return NULL;
+ }
+
+ QString str;
+ if (numRows < ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows())
+ ((FQTermWindow*)lp)->getSession()->getBuffer()->getTextLineInTerm(numRows)->getAllAnsiText(str);
+
+ PyObject *py_text = PyString_FromString(U2U8(str));
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+// is host connected
+static PyObject *fqterm_isConnected(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ bool connected = ((FQTermWindow*)lp)->isConnected();
+ PyObject *py_connected = Py_BuildValue("i", connected ? 1 : 0);
+
+ Py_INCREF(py_connected);
+ return py_connected;
+}
+
+// disconnect from host
+static PyObject *fqterm_disconnect(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->disconnect();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// reconnect to host
+static PyObject *fqterm_reconnect(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->getSession()->reconnect();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// bbs encoding 0-GBK 1-BIG5
+//FIXME: UTF8 and HKSCS
+static PyObject *fqterm_getBBSCodec(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_codec = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().serverEncodingID_ == 0 ? "GBK" : "Big5");
+ Py_INCREF(py_codec);
+
+ return py_codec;
+}
+
+// host address
+static PyObject *fqterm_getAddress(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_addr = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().hostAddress_.toLocal8Bit());
+ Py_INCREF(py_addr);
+ return py_addr;
+}
+
+// host port number
+static PyObject *fqterm_getPort(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_port = Py_BuildValue("i", ((FQTermWindow*)lp)->getSession()->param().port_);
+ Py_INCREF(py_port);
+ return py_port;
+}
+
+// connection protocol 0-telnet 1-SSH1 2-SSH2
+static PyObject *fqterm_getProtocol(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_port = Py_BuildValue("i", ((FQTermWindow*)lp)
+ ->getSession()->param().protocolType_);
+ Py_INCREF(py_port);
+ return py_port;
+}
+
+// key to reply msg
+static PyObject *fqterm_getReplyKey(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_key = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().replyKeyCombination_.toLocal8Bit());
+ Py_INCREF(py_key);
+ return py_key;
+}
+
+// url under mouse
+static PyObject *fqterm_getURL(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_url = PyString_FromString(((FQTermWindow*)lp)->getSession()->getUrl().toUtf8().constData());
+ Py_INCREF(py_url);
+ return py_url;
+}
+
+// preview image link
+static PyObject *fqterm_previewImage(PyObject *, PyObject *args) {
+ long lp;
+ char *url;
+ if (!PyArg_ParseTuple(args, "ls", &lp, &url)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->getHttpHelper(url, true);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+// convert string from UTF8 to specified encoding
+static PyObject *fqterm_fromUTF8(PyObject *, PyObject *args) {
+ char *str, *enc;
+ if (!PyArg_ParseTuple(args, "ss", &str, &enc)) {
+ return NULL;
+ }
+ QTextCodec *encodec = QTextCodec::codecForName(enc);
+ QTextCodec *utf8 = QTextCodec::codecForName("utf8");
+
+ PyObject *py_str = PyString_FromString(encodec->fromUnicode(utf8->toUnicode
+ (str)));
+ Py_INCREF(py_str);
+ return py_str;
+}
+
+// convert string from specified encoding to UTF8
+static PyObject *fqterm_toUTF8(PyObject *, PyObject *args) {
+ char *str, *enc;
+ if (!PyArg_ParseTuple(args, "ss", &str, &enc)) {
+ return NULL;
+ }
+ QTextCodec *encodec = QTextCodec::codecForName(enc);
+ QTextCodec *utf8 = QTextCodec::codecForName("utf8");
+
+ PyObject *py_str = PyString_FromString(utf8->fromUnicode(encodec->toUnicode
+ (str)));
+ Py_INCREF(py_str);
+ return py_str;
+}
+
+static PyObject *fqterm_wait(PyObject *, PyObject *args) {
+ long t;
+ if (!PyArg_ParseTuple(args, "l", &t)) {
+ return NULL;
+ }
+ SleeperThread::msleep(t);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyMethodDef fqterm_methods[] = {
+ {
+ "formatError", (PyCFunction)fqterm_formatError, METH_VARARGS,
+ "get the traceback info"
+ }
+
+ ,
+
+ {
+ "getArticle", (PyCFunction)fqterm_getArticle, METH_VARARGS,
+ "copy current article"
+ }
+
+ ,
+
+ {
+ "copyArticle", (PyCFunction)fqterm_copyArticle, METH_VARARGS,
+ "copy current article (obsolete)"
+ }
+
+ ,
+
+ {
+ "getText", (PyCFunction)fqterm_getText, METH_VARARGS, "get text at line#"
+ }
+
+ ,
+
+ {
+ "getAttrText", (PyCFunction)fqterm_getAttrText, METH_VARARGS,
+ "get attr text at line#"
+ }
+
+ ,
+
+ {
+ "sendString", (PyCFunction)fqterm_sendString, METH_VARARGS,
+ "send string to server"
+ }
+
+ ,
+
+ {
+ "sendParsedString", (PyCFunction)fqterm_sendParsedString, METH_VARARGS,
+ "send string with escape"
+ }
+
+ ,
+
+ {
+ "caretX", (PyCFunction)fqterm_caretX, METH_VARARGS, "caret x"
+ }
+
+ ,
+
+ {
+ "caretY", (PyCFunction)fqterm_caretY, METH_VARARGS, "caret y"
+ }
+
+ ,
+
+ {
+ "columns", (PyCFunction)fqterm_columns, METH_VARARGS, "screen width"
+ }
+
+ ,
+
+ {
+ "rows", (PyCFunction)fqterm_rows, METH_VARARGS, "screen height"
+ }
+
+ ,
+
+ {
+ "isConnected", (PyCFunction)fqterm_isConnected, METH_VARARGS,
+ "connected to server or not"
+ }
+
+ ,
+
+ {
+ "disconnect", (PyCFunction)fqterm_disconnect, METH_VARARGS,
+ "disconnect from server"
+ }
+
+ ,
+
+ {
+ "reconnect", (PyCFunction)fqterm_reconnect, METH_VARARGS, "reconnect"
+ }
+
+ ,
+
+ {
+ "getBBSCodec", (PyCFunction)fqterm_getBBSCodec, METH_VARARGS,
+ "get the bbs encoding, GBK or Big5"
+ }
+
+ ,
+
+ {
+ "getAddress", (PyCFunction)fqterm_getAddress, METH_VARARGS,
+ "get the bbs address"
+ }
+
+ ,
+
+ {
+ "getPort", (PyCFunction)fqterm_getPort, METH_VARARGS, "get the bbs port number"
+ }
+
+ ,
+
+ {
+ "getProtocol", (PyCFunction)fqterm_getProtocol, METH_VARARGS,
+ "get the bbs protocol, 0/1/2 TELNET/SSH1/SSH2"
+ }
+
+ ,
+
+ {
+ "getReplyKey", (PyCFunction)fqterm_getReplyKey, METH_VARARGS,
+ "get the key to reply messages"
+ }
+
+ ,
+
+ {
+ "getURL", (PyCFunction)fqterm_getURL, METH_VARARGS,
+ "get the url string under mouse"
+ }
+
+ ,
+
+ {
+ "previewImage", (PyCFunction)fqterm_previewImage, METH_VARARGS,
+ "preview the image link"
+ }
+
+ ,
+
+ {
+ "fromUTF8", (PyCFunction)fqterm_fromUTF8, METH_VARARGS,
+ "decode from utf8 to string in specified codec"
+ }
+
+ ,
+
+ {
+ "toUTF8", (PyCFunction)fqterm_toUTF8, METH_VARARGS,
+ "decode from string in specified codec to utf8"
+ }
+
+ ,
+
+ {
+ "wait", (PyCFunction)fqterm_wait, METH_VARARGS,
+ "wait for x ms"
+ }
+
+ ,
+
+ {
+ NULL, (PyCFunction)NULL, 0, NULL
+ }
+};
+
+
+
+FQTermPythonHelper::FQTermPythonHelper()
+ : mainThreadState_(NULL) {
+
+ // initialize Python
+ Py_Initialize();
+ // initialize thread support
+ PyEval_InitThreads();
+ // save a pointer to the main PyThreadState object
+ mainThreadState_ = PyThreadState_Get();
+ // add path
+ PyRun_SimpleString("import sys\n");
+ QString pathCmd;
+ pathCmd = "sys.path.insert(0,'";
+ pathCmd += getPath(RESOURCE)+"script')";
+ PyRun_SimpleString(fq_strdup(pathCmd.toUtf8().data()));
+
+ Py_InitModule4("fqterm", fqterm_methods,
+ NULL,(PyObject*)NULL,PYTHON_API_VERSION);
+ // release the lock
+ PyEval_ReleaseLock();
+}
+
+FQTermPythonHelper::~FQTermPythonHelper() {
+ // shut down the interpreter
+ PyInterpreterState * mainInterpreterState = mainThreadState_->interp;
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+ PyEval_AcquireLock();
+ Py_Finalize();
+}
+
+} // namespace FQTerm
+
+#endif //HAVE_PYTHON \ No newline at end of file
diff --git a/src/fqterm/fqterm_python.h b/src/fqterm/fqterm_python.h
new file mode 100644
index 0000000..bad6b04
--- /dev/null
+++ b/src/fqterm/fqterm_python.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PYTHON_H
+#define FQTERM_PYTHON_H
+
+#ifdef HAVE_PYTHON
+#include "fqterm.h"
+
+namespace FQTerm {
+
+class FQTermWindow;
+extern QString getException();
+extern QString getErrOutputFile(FQTermWindow*);
+extern PyMethodDef fqterm_methods[];
+
+class FQTermPythonHelper
+{
+public:
+ FQTermPythonHelper();
+ ~FQTermPythonHelper();
+ PyThreadState* getPyThreadState() {
+ return mainThreadState_;
+ }
+private:
+ PyThreadState * mainThreadState_;
+};
+
+} // namespace FQTerm
+
+#endif // HAVE_PYTHON
+
+#endif // FQTERM_PYTHON_H
+
diff --git a/src/fqterm/fqterm_screen.cpp b/src/fqterm/fqterm_screen.cpp
new file mode 100644
index 0000000..339e666
--- /dev/null
+++ b/src/fqterm/fqterm_screen.cpp
@@ -0,0 +1,1868 @@
+/****************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <QApplication>
+#include <QPainter>
+#include <QScrollBar>
+#include <QShortcut>
+#include <QTextCharFormat>
+#include <QTimer>
+#include <QWheelEvent>
+#include <QKeySequence>
+#include <QRegion>
+#include <QPolygon>
+
+#include "fqterm_buffer.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#include "fqterm_frame.h"
+#include "fqterm_param.h"
+#include "fqterm_screen.h"
+#include "fqterm_session.h"
+#include "fqterm_text_line.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+namespace FQTerm {
+/* ------------------------------------------------------------------------ */
+/* */
+/* Constructor/Destructor */
+/* */
+/* ------------------------------------------------------------------------ */
+
+FQTermScreen::FQTermScreen(QWidget *parent, FQTermSession *session)
+ : QWidget(parent),
+ scrollBarWidth_(15),
+ termBuffer_(session->getBuffer()),
+ cnLetterSpacing_(0.0),
+ spLetterSpacing_(0.0),
+ enLetterSpacing_(0.0),
+ cnFixedPitch_(false),
+ enFixedPitch_(false),
+ hasBackground_(false),
+ backgroundRenderOption_(0),
+ backgroundCoverage_(0),
+ backgroundAlpha_(0),
+ backgroundUseAlpha_(false) {
+ termWindow_ = (FQTermWindow*)parent;
+ session_ = session;
+ param_ = &session->param();
+ paintState_ = System;
+ isCursorShown_ = true;
+ is_light_background_mode_ = false;
+
+ setFocusPolicy(Qt::ClickFocus);
+ setAttribute(Qt::WA_InputMethodEnabled, true);
+ setMouseTracking(true);
+
+ setSchema();
+
+ initFontMetrics();
+
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(bufferSizeChanged()),
+ this, SLOT(bufferSizeChanged())));
+
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(termSizeChanged(int, int)),
+ this, SLOT(termSizeChanged(int, int))));
+
+ blinkTimer_ = new QTimer(this);
+ FQ_VERIFY(connect(blinkTimer_, SIGNAL(timeout()), this, SLOT(blinkEvent())));
+
+ cursorTimer_ = new QTimer(this);
+ FQ_VERIFY(connect(cursorTimer_, SIGNAL(timeout()),
+ this, SLOT(cursorEvent())));
+
+ // the scrollbar
+ scrollBar_ = new QScrollBar(this);
+ scrollBar_->setCursor(Qt::ArrowCursor);
+ bufferStart_ = 0;
+ bufferEnd_ = termBuffer_->getNumRows() - 1;
+ areLinesBlink_ = new bool[bufferEnd_ - bufferStart_ + 1];
+ scrollBar_->setRange(0, 0);
+ scrollBar_->setSingleStep(1);
+ scrollBar_->setPageStep(termBuffer_->getNumRows());
+ scrollBar_->setValue(0);
+ updateScrollBar();
+ FQ_VERIFY(connect(scrollBar_, SIGNAL(valueChanged(int)),
+ this, SLOT(scrollChanged(int))));
+
+ gotoPrevPage_ = new QShortcut(QKeySequence(tr("Shift+PageUp")),
+ this, SLOT(prevPage()));
+ gotoNextPage_ = new QShortcut(QKeySequence(tr("Shift+PageDown")),
+ this, SLOT(nextPage()));
+ gotoPrevLine_ = new QShortcut(QKeySequence(tr("Shift+Up")),
+ this, SLOT(prevLine()));
+ gotoNextLine_ = new QShortcut(QKeySequence(tr("Shift+Down")),
+ this, SLOT(nextLine()));
+
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+
+ // init variable
+ isBlinkScreen_ = false;
+ isBlinkCursor_ = true;
+
+
+ preedit_line_ = new PreeditLine(this, colors_);
+
+ tmp_im_query_ = new QString();
+}
+
+FQTermScreen::~FQTermScreen() {
+ delete [] areLinesBlink_;
+ delete blinkTimer_;
+ delete cursorTimer_;
+ //delete m_pCanvas;
+ //delete m_inputContent;
+
+ delete preedit_line_;
+
+ delete tmp_im_query_;
+}
+
+bool FQTermScreen::event(QEvent *e) {
+ switch(e->type()) {
+ case QEvent::KeyPress:
+ {
+ // forward all key press events to parant (FQTermWindow).
+ return false;
+ }
+ }
+ return this->QWidget::event(e);
+}
+
+// focus event received
+void FQTermScreen::focusInEvent(QFocusEvent*) {
+
+ gotoPrevPage_->setEnabled(true);
+ gotoNextPage_->setEnabled(true);
+ gotoPrevLine_->setEnabled(true);
+ gotoNextLine_->setEnabled(true);
+
+}
+
+// focus out
+void FQTermScreen::focusOutEvent(QFocusEvent*) {
+ gotoPrevPage_->setEnabled(false);
+ gotoNextPage_->setEnabled(false);
+ gotoPrevLine_->setEnabled(false);
+ gotoNextLine_->setEnabled(false);
+}
+
+void FQTermScreen::resizeEvent(QResizeEvent*) {
+ syncBufferAndScreen();
+}
+
+void FQTermScreen::syncBufferAndScreen() {
+ updateScrollBar();
+ updateBackgroundPixmap();
+
+ if (param_->isFontAutoFit_ == 1) {
+ updateFont();
+ } else if (param_->isFontAutoFit_ == 0) { //adjust column/row
+ int cx = clientRectangle_.width() / charWidth_;
+ int cy = clientRectangle_.height() / charHeight_;
+ if (param_->hostType_ == 0) {
+ if (cx < 80) cx = 80;
+ if (cy < 24) cy = 24;
+ } else {
+ if (cx < 10) cx = 10;
+ if (cy < 10) cy = 10;
+ }
+ session_->setTermSize(cx, cy);
+ //session_->writeStr("\0x5f");
+ } else {
+ session_->setTermSize(param_->numColumns_, param_->numRows_);
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Mouse */
+/* */
+/* ------------------------------------------------------------------------ */
+void FQTermScreen::enterEvent(QEvent *e) {
+ QApplication::sendEvent(termWindow_, e);
+}
+
+void FQTermScreen::leaveEvent(QEvent *e) {
+ QApplication::sendEvent(termWindow_, e);
+}
+
+void FQTermScreen::mousePressEvent(QMouseEvent *me) {
+
+ termWindow_->mousePressEvent(me);
+ setFocus();
+}
+
+void FQTermScreen::mouseMoveEvent(QMouseEvent *me) {
+#ifdef Q_OS_MACX
+ termWindow_->mouseMoveEvent(me);
+#else
+ termWindow_->mouseMoveEvent(me);
+ //QApplication::sendEvent(m_pWindow, me);
+#endif
+}
+
+void FQTermScreen::mouseReleaseEvent(QMouseEvent *me) {
+ termWindow_->mouseReleaseEvent(me);
+ //QApplication::sendEvent(m_pWindow, me);
+}
+
+void FQTermScreen::wheelEvent(QWheelEvent *we) {
+ if (FQTermPref::getInstance()->isWheelSupported_) {
+ QApplication::sendEvent(termWindow_, we);
+ } else {
+ QApplication::sendEvent(scrollBar_, we);
+ }
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Font */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermScreen::initFontMetrics() {
+ //issue 98
+ if (param_->isFontAutoFit_ == 1) {
+ englishFont_ = new QFont(param_->englishFontName_);
+ nonEnglishFont_ = new QFont(param_->otherFontName_);
+
+ updateFont();
+ } else {
+ englishFont_ = new QFont(param_->englishFontName_, qMax(8, param_->englishFontSize_));
+ nonEnglishFont_ = new QFont(param_->otherFontName_, qMax(8, param_->otherFontSize_));
+
+ setFontMetrics();
+ }
+
+ englishFont_->setWeight(QFont::Normal);;
+ nonEnglishFont_->setWeight(QFont::Normal);
+
+ // m_pFont->setStyleHint(QFont::System,
+ // m_pWindow->m_pFrame->m_pref.bAA ?
+ // QFont::PreferAntialias : QFont::NoAntialias);
+ updateFixedPitchInfo();
+}
+
+void FQTermScreen::updateFont() {
+ int nPixelSize;
+ int nIniSize =
+ qMax(8, qMin(clientRectangle_.height() / termBuffer_->getNumRows(),
+ clientRectangle_.width() *2 / termBuffer_->getNumColumns()));
+ //FIXME: WTF????
+ for (nPixelSize = nIniSize - 3; nPixelSize <= nIniSize + 3; nPixelSize++) {
+ englishFont_->setPixelSize(nPixelSize);
+ nonEnglishFont_->setPixelSize(nPixelSize);
+
+ setFontMetrics();
+ if ((termBuffer_->getNumRows() *charHeight_) > clientRectangle_.height() ||
+ (termBuffer_->getNumColumns() *charWidth_) > clientRectangle_.width()) {
+ while (nPixelSize > 5) {
+ nPixelSize--;
+ englishFont_->setPixelSize(nPixelSize);
+ nonEnglishFont_->setPixelSize(nPixelSize);
+
+ setFontMetrics();
+ //changed by dp to get larger font...
+ if ((termBuffer_->getNumRows()*charHeight_) <= clientRectangle_.height()
+ && (termBuffer_->getNumColumns() *charWidth_) <=
+ clientRectangle_.width()) {
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ englishFont_->setWeight(QFont::Normal);
+ nonEnglishFont_->setWeight(QFont::Normal);
+ setFontAntiAliasing(FQTermPref::getInstance()->openAntiAlias_);
+}
+
+void FQTermScreen::setFontMetrics() {
+
+ QFontMetrics nonEnglishFM(*nonEnglishFont_);
+ QFontMetrics englishFM(*englishFont_);
+
+ // FIXME: find a typical character for the current language.
+ int cn = nonEnglishFM.width(QChar(0x4e2D));
+ int en = englishFM.width('W');
+
+ int pix_size = nonEnglishFont_->pixelSize();
+ while (cn % 2 && pix_size > 10) {
+ nonEnglishFont_->setPixelSize(--pix_size);
+ nonEnglishFM = QFontMetrics(*nonEnglishFont_);
+ cn = nonEnglishFM.width(QChar(0x4e2D));
+ }
+
+ pix_size = englishFont_->pixelSize();
+ while (2 * en > cn + 1 && pix_size > 5) {
+ --pix_size;
+ englishFont_->setPixelSize(pix_size);
+ englishFM = QFontMetrics(*englishFont_);
+ en = englishFM.width('W');
+/*
+#ifndef __APPLE__
+ //FIXME: correctly draw chars with left/right bearing.
+ if ( - englishFM.leftBearing('W') - englishFM.rightBearing('W') > 0) {
+ en += - englishFM.leftBearing('W') - englishFM.rightBearing('W');
+ }
+#endif
+*/
+ }
+
+ charWidth_ = qMax(float(cn) / 2 , float(en));
+
+ charHeight_ = qMax(englishFM.height(), nonEnglishFM.height());
+ charHeight_ += param_->lineSpacing_;
+ //charWidth_ = ceil(qMax(charWidth_, charHeight_ * param_->charRatio_ / 100));
+ charWidth_ += param_->charSpacing_;
+
+ cnLetterSpacing_ = qMax(charWidth_ * 2 - cn, 0.0);
+ enLetterSpacing_ = qMax(charWidth_ - en, 0.0);
+
+ spLetterSpacing_ = qMax(charWidth_ - englishFM.width(' '), 0.0);
+
+ fontAscent_ = qMax(englishFM.ascent(), nonEnglishFM.ascent());
+ fontDescent_ = qMax(englishFM.descent(), nonEnglishFM.descent());
+
+ FQ_TRACE("font", 4) << "\nNon-English font:"
+ << "\nheight: " << nonEnglishFM.height()
+ << "\nascent: " << nonEnglishFM.ascent()
+ << "\ndescent: " << nonEnglishFM.descent();
+
+
+ FQ_TRACE("font", 4) << "\nEnglish font:"
+ << "\nheight: " << englishFM.height()
+ << "\nascent: " << englishFM.ascent()
+ << "\ndescent: " << englishFM.descent();
+
+ updateFixedPitchInfo();
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Colors */
+/* */
+/* ------------------------------------------------------------------------ */
+void FQTermScreen::setSchema() {
+ // the default color table
+ colors_[0] = Qt::black;
+ colors_[1] = Qt::darkRed;
+ colors_[2] = Qt::darkGreen;
+ colors_[3] = Qt::darkYellow;
+ colors_[4] = Qt::darkBlue;
+ colors_[5] = Qt::darkMagenta;
+ colors_[6] = Qt::darkCyan;
+ colors_[7] = Qt::darkGray;
+ colors_[8] = Qt::gray;
+ colors_[9] = Qt::red;
+ colors_[10] = Qt::green;
+ colors_[11] = Qt::yellow;
+ colors_[12] = Qt::blue;
+ colors_[13] = Qt::magenta;
+ colors_[14] = Qt::cyan;
+ colors_[15] = Qt::white;
+
+
+ hasBackground_ = false;
+ // if we have schema defined
+ if (QFile::exists(param_->schemaFileName_)) {
+ FQTermConfig *pConf = new FQTermConfig(param_->schemaFileName_);
+ for (int i = 0; i < 16; ++i) {
+ colors_[i].setNamedColor(pConf->getItemValue("color", QString("color%1").arg(i)));
+ }
+ originBackgroundPixmap_ = QPixmap(pConf->getItemValue("image", "name"));
+ //0 -- none 1 -- image
+ hasBackground_ = pConf->getItemValue("background", "type").toInt() ? 1 : 0;
+ backgroundRenderOption_ = pConf->getItemValue("image", "render").toInt();
+ backgroundCoverage_ = pConf->getItemValue("image", "cover").toInt();
+ backgroundUseAlpha_ = pConf->getItemValue("image", "usealpha").toInt();
+ backgroundAlpha_ = pConf->getItemValue("image", "alpha").toInt();
+
+ delete pConf;
+ }
+
+ // override schema using user defined Fg/Bg color
+ colors_[0] = param_->backgroundColor_;
+ colors_[7] = param_->foregroundColor_;
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Scrollbar */
+/* */
+/* ------------------------------------------------------------------------*/
+void FQTermScreen::prevPage() {
+ scrollLine(-termBuffer_->getNumRows());
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::nextPage() {
+ scrollLine(termBuffer_->getNumRows());
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::prevLine() {
+ scrollLine(-1);
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::nextLine() {
+ scrollLine(1);
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::scrollLine(int delta) {
+ bufferStart_ += delta;
+
+ if (bufferStart_ < 0) {
+ bufferStart_ = 0;
+ return ;
+ }
+ if (bufferStart_ > termBuffer_->getNumLines() - termBuffer_->getNumRows()) {
+ bufferStart_ = termBuffer_->getNumLines() - termBuffer_->getNumRows();
+ return ;
+ }
+
+ scrollBar_->setValue(bufferStart_);
+ bufferEnd_ = bufferStart_ + termBuffer_->getNumRows() - 1;
+
+ // notify session
+ session_->setScreenStart(bufferStart_);
+
+ for (int i = bufferStart_; i <= bufferEnd_; i++) {
+ session_->setLineAllChanged(i);
+ }
+}
+
+void FQTermScreen::scrollChanged(int value) {
+ if (bufferStart_ == value) {
+ return ;
+ }
+
+ if (value < 0) {
+ value = 0;
+ }
+ if (value > termBuffer_->getNumLines() - termBuffer_->getNumRows()) {
+ value = termBuffer_->getNumLines() - termBuffer_->getNumRows();
+ }
+
+ bufferStart_ = value;
+ bufferEnd_ = value + termBuffer_->getNumRows() - 1;
+
+ // notify session
+ session_->setScreenStart(bufferStart_);
+
+ for (int i = bufferStart_; i <= bufferEnd_; i++) {
+ //termBuffer_->at(i)->setChanged(-1, -1);
+ session_->setLineAllChanged(i);
+ }
+
+ setPaintState(NewData);
+ update();
+}
+
+void FQTermScreen::updateScrollBar() {
+ int numLeftPixels = 0; // ß¾
+ int numUpPixels = 0; // ϱ߾
+
+ switch (FQTermPref::getInstance()->termScrollBarPosition_) {
+ case 0:
+ scrollBar_->hide();
+ clientRectangle_ = QRect(numLeftPixels, numUpPixels,
+ rect().width() - numLeftPixels,
+ rect().height() - numUpPixels);
+ break;
+ case 1:
+ // LEFT
+ scrollBar_->setGeometry(0, 0, scrollBarWidth_, rect().height());
+ scrollBar_->show();
+ clientRectangle_ = QRect(scrollBarWidth_ + numLeftPixels, numUpPixels,
+ rect().width() - scrollBarWidth_ - numLeftPixels,
+ rect().height() - numUpPixels);
+ break;
+ case 2:
+ // RIGHT
+ scrollBar_->setGeometry(rect().width() - scrollBarWidth_, 0,
+ scrollBarWidth_, rect().height());
+ scrollBar_->show();
+ clientRectangle_ = QRect(numLeftPixels, numUpPixels,
+ rect().width() - scrollBarWidth_ - numLeftPixels,
+ rect().height() - numUpPixels);
+ break;
+ }
+ setPaintState(Repaint);
+ update();
+}
+
+void FQTermScreen::bufferSizeChanged() {
+ FQ_VERIFY(disconnect(scrollBar_, SIGNAL(valueChanged(int)),
+ this, SLOT(scrollChanged(int))));
+ scrollBar_->setRange(0, termBuffer_->getNumLines() - termBuffer_->getNumRows());
+ scrollBar_->setSingleStep(1);
+ scrollBar_->setPageStep(termBuffer_->getNumRows());
+
+ // FIXME: should not always move scroll bar to the bottom when
+ // buffer size is changed.
+ scrollBar_->setValue(termBuffer_->getNumLines() - termBuffer_->getNumRows());
+
+ bufferStart_ = scrollBar_->value();
+ bufferEnd_ = scrollBar_->value() + termBuffer_->getNumRows() - 1;
+
+ // notify session
+ session_->setScreenStart(bufferStart_);
+
+ FQ_VERIFY(connect(scrollBar_, SIGNAL(valueChanged(int)),
+ this, SLOT(scrollChanged(int))));
+
+ delete [] areLinesBlink_;
+ areLinesBlink_ = new bool[bufferEnd_ - bufferStart_ + 1];
+
+ scrollLine(0);
+}
+
+void FQTermScreen::termSizeChanged(int column, int row) {
+ FQ_TRACE("term", 3) << "The term size is changed to " << column << "x" << row;
+ syncBufferAndScreen();
+ bufferSizeChanged();
+ this->setPaintState(Repaint);
+ this->repaint();
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Display */
+/* */
+/* ------------------------------------------------------------------------ */
+
+//set pixmap background
+
+void FQTermScreen::updateBackgroundPixmap() {
+ if (!hasBackground_)
+ return;
+
+ switch (backgroundRenderOption_) {
+ case 0:
+ //tile
+ {
+ backgroundPixmap_ = QPixmap(clientRectangle_.size());
+ QPainter painter(&backgroundPixmap_);
+ painter.drawTiledPixmap(backgroundPixmap_.rect(), originBackgroundPixmap_);
+ }
+ break;
+ case 1:
+ //center
+ {
+ backgroundPixmap_ = QPixmap(clientRectangle_.size());
+ backgroundPixmap_.fill(colors_[0]);
+ QPainter painter(&backgroundPixmap_);
+ int x = (backgroundPixmap_.size() - originBackgroundPixmap_.size()).width() / 2;
+ int y = (backgroundPixmap_.size() - originBackgroundPixmap_.size()).height() / 2;
+ painter.drawPixmap(x, y, originBackgroundPixmap_);
+ }
+ break;
+ case 2:
+ //stretch
+ backgroundPixmap_ = originBackgroundPixmap_.scaled(clientRectangle_.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ break;
+ }
+ /*
+ hasBackground_ = false;
+ backgroundPixmap_ = pixmap;
+ backgroundPixmapType_ = nType;
+ QPalette palette;
+
+ switch (nType) {
+ case 0:
+ // none
+ palette.setColor(backgroundRole(), colors_[0]);
+ setPalette(palette);
+ break;
+ case 1:
+ //{ // transparent{}
+ break;
+ case 2:
+ // tile
+ if (!pixmap.isNull())
+ palette.setBrush(backgroundRole(), QBrush(pixmap));
+ setPalette(palette);
+ // updateBackgroundPixmap( pixmap );
+ hasBackground_ = true;
+ break;
+ //}
+ case 3:
+ // center
+ if (!pixmap.isNull()) {
+ QPixmap pxmBg = QPixmap(size());
+ QPainter painter(&pxmBg);
+ pxmBg.fill(colors_[0]);
+ painter.drawPixmap((size().width() - pixmap.width()) / 2,
+ (size().height() - pixmap.height()) / 2,
+ pixmap.width(), pixmap.height(), pixmap);
+ palette.setBrush(backgroundRole(), QBrush(pxmBg));
+ setPalette(palette);
+ // updateBackgroundPixmap(pxmBg);
+ hasBackground_ = true;
+ break;
+ }
+ case 4:
+ // stretch
+ if (!pixmap.isNull()) {
+ float sx = (float)size().width() / pixmap.width();
+ float sy = (float)size().height() / pixmap.height();
+ QMatrix matrix;
+ matrix.scale(sx, sy);
+ palette.setBrush(backgroundRole(), QBrush(pixmap.transformed(matrix)));
+ setPalette(palette);
+ // updateBackgroundPixmap(pixmap.transformed( matrix ));
+ hasBackground_ = true;
+ break;
+ }
+ default:
+ palette.setColor(backgroundRole(), colors_[0]);
+ setPalette(palette);
+ // setBackgroundColor( m_color[0] );
+
+ }
+ */
+}
+
+void FQTermScreen::cursorEvent() {
+ if (isBlinkCursor_) {
+ setPaintState(Cursor);
+ isCursorShown_ = !isCursorShown_;
+ update();
+ }
+}
+
+void FQTermScreen::blinkEvent() {
+ if (hasBlinkText_) {
+ isBlinkScreen_ = !isBlinkScreen_;
+ setPaintState(Blink);
+ update();
+ }
+}
+
+void FQTermScreen::paintEvent(QPaintEvent *pe) {
+ FQ_TRACE("screen", 8) << "paintEvent " << pe->rect().x() << "," << pe->rect().y() << " "
+ << pe->rect().width() << "x" << pe->rect().height();
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing, FQTermPref::getInstance()->openAntiAlias_);
+ painter.setRenderHint(QPainter::TextAntialiasing, FQTermPref::getInstance()->openAntiAlias_);
+ if (paintState_ == System) {
+ repaintScreen(pe, painter);
+ return;
+ }
+
+ if (testPaintState(Repaint)) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "repaint";
+ repaintScreen(pe, painter);
+ clearPaintState(Repaint);
+ }
+
+ if (testPaintState(NewData)) {
+ if (termBuffer_->isLightBackgroundMode() != is_light_background_mode_) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "new data repaint";
+ is_light_background_mode_ = termBuffer_->isLightBackgroundMode();
+ if (is_light_background_mode_) {
+ colors_[0] = param_->foregroundColor_;
+ colors_[7] = param_->backgroundColor_;
+ } else {
+ colors_[0] = param_->backgroundColor_;
+ colors_[7] = param_->foregroundColor_;
+ }
+ repaintScreen(pe, painter);
+ } else {
+ FQ_TRACE("screen", 8) << "paintEvent " << "new data refresh";
+ refreshScreen(painter);
+ }
+
+ clearPaintState(NewData);
+ }
+
+ if (testPaintState(Blink)) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "blink";
+ blinkScreen(painter);
+ clearPaintState(Blink);
+ }
+
+ if (testPaintState(Cursor)) {
+ FQ_TRACE("screen", 8) << "paintEvent " << "cursor";
+ updateCursor(painter);
+ clearPaintState(Cursor);
+ }
+
+ if (testPaintState(Widget)) {
+ updateWidgetRect(painter);
+ clearPaintState(Widget);
+ }
+}
+
+void FQTermScreen::blinkScreen(QPainter &painter) {
+ painter.setBackground(QBrush(colors_[0]));
+
+ for (int index = bufferStart_; index <= bufferEnd_; index++) {
+ if (areLinesBlink_[index - bufferStart_]) {
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(index);
+ uint linelength = pTextLine->getWidth();
+ const unsigned char *attr = pTextLine->getAttributes();
+ for (uint i = 0; i < linelength; ++i) {
+ if (GETBLINK(attr[i])) {
+ int startx = i;
+ while (i < linelength && GETBLINK(attr[i])) {
+ ++i;
+ }
+ drawLine(painter, index, startx, i, false);
+ }
+ }
+ }
+ }
+}
+
+void FQTermScreen::updateCursor(QPainter &painter) {
+ if (termBuffer_->getCaretColumn() >= termBuffer_->getNumColumns()) {
+ // we only allow the cursor located beyond the terminal screen temporarily.
+ // just ignore this.
+ return;
+ }
+
+ bool isCursorShown = isCursorShown_;
+ if (FQTermPref::getInstance()->isBossColor_) {
+ isCursorShown = true;
+ }
+
+ if (termBuffer_->getCaretLine() <= bufferEnd_
+ && termBuffer_->getCaretLine() >= bufferStart_) {
+
+ if (!isCursorShown) {
+ const FQTermTextLine *pTextLine
+ = termBuffer_->getTextLineInBuffer(termBuffer_->getCaretLine());
+ if ((int)pTextLine->getWidth() > termBuffer_->getCaretColumn()) {
+ int startx = pTextLine->getCellBegin(termBuffer_->getCaretColumn());
+ int endx = pTextLine->getCellEnd(termBuffer_->getCaretColumn() + 1);
+ if ((int)pTextLine->getWidth() > endx) {
+ endx = pTextLine->getCellEnd(endx + 1);
+ }
+ drawLine(painter, termBuffer_->getCaretLine(), startx, endx,
+ termBuffer_->getCaretLine());
+ } else {
+ //painter.fillRect(mapToRect(termBuffer_->getCaretColumn(), termBuffer_->getCaretLine(), 1, 1),colors_[0]);
+ drawBackground(painter, mapToRect(termBuffer_->getCaretColumn(),termBuffer_->getCaretLine(), 1, 1), 0);
+ }
+ return;
+ }
+
+ QPoint pt = mapToPixel(QPoint(termBuffer_->getCaretColumn(),
+ termBuffer_->getCaretLine()));
+ switch (param_->cursorType_) {
+ case 0:
+ // block
+ {
+ int x = termBuffer_->getCaretColumn();
+ int y = termBuffer_->getCaretLine();
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(y);
+ if ((int)pTextLine->getWidth() > x) {
+
+ int startx = pTextLine->getCellBegin(x);
+ int endx = pTextLine->getCellEnd(x + 1);
+
+ drawLine(painter, termBuffer_->getCaretLine(), startx, endx,
+ termBuffer_->getCaretLine());
+
+ QRect rect = mapToRect(startx, termBuffer_->getCaretLine(), 1, 1);
+ rect.translate(0, 0);
+ painter.fillRect(rect, colors_[7]);
+ } else {
+ QRect rect = mapToRect(termBuffer_->getCaretColumn(),
+ termBuffer_->getCaretLine(), 1, 1);
+ rect.translate(0, 0);
+ painter.fillRect(rect,
+ colors_[7]);
+ }
+ }
+ break;
+ case 1:
+ // underline
+ painter.fillRect(pt.x(), pt.y() + 9 * charHeight_ / 10, charWidth_,
+ charHeight_ / 10, colors_[7]);
+ break;
+ case 2:
+ // I type
+ painter.fillRect(pt.x(), pt.y() + 1, charWidth_ / 5, charHeight_ - 1,
+ colors_[7]);
+ break;
+ default:
+ painter.fillRect(pt.x(), pt.y()+1,
+ charWidth_, charHeight_ - 1, colors_[7]);
+ }
+ }
+}
+
+
+// refresh the screen when
+// 1. received new contents form server
+// 2. scrolled by user
+void FQTermScreen::refreshScreen(QPainter &painter) {
+ FQ_FUNC_TIMER("screen_paint", 5);
+
+ if (cursorTimer_->isActive()) {
+ cursorTimer_->stop();
+ }
+
+ if (blinkTimer_->isActive()) {
+ blinkTimer_->stop();
+ }
+
+ hasBlinkText_ = false;
+ isCursorShown_ = true;
+
+ for (int index = bufferStart_; index <= bufferEnd_; index++) {
+
+ FQ_VERIFY(index < termBuffer_->getNumLines());
+
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(index);
+
+ if (pTextLine->hasBlink()) {
+ hasBlinkText_ = true;
+ areLinesBlink_[index - bufferStart_] = true;
+ } else {
+ areLinesBlink_[index - bufferStart_] = false;
+ }
+
+ unsigned int startx, endx;
+ if (!pTextLine->getDirtyCells(startx, endx)) {
+ continue;
+ }
+
+ /*
+ Finally get around this for pku & ytht, don't know why some weird things
+ happened when only erase and draw the changed part.
+ */
+ startx = pTextLine->getCellBegin(startx);
+
+ int len = -1;
+ if ((int)endx != -1) {
+ len = endx - startx;
+ } else {
+ len = pTextLine->getMaxCellCount() - startx;
+ }
+
+ QRect rect = mapToRect(startx, index, len, 1);
+
+ //painter.fillRect(rect ,QBrush(colors_[0]));
+ drawBackground(painter, rect, 0);
+
+ drawLine(painter, index, startx, endx);
+
+ session_->clearLineChanged(index);
+ }
+
+ updateMicroFocus();
+ if (termWindow_->isConnected()) {
+ updateCursor(painter);
+ }
+
+
+ if (termWindow_->isConnected()) {
+ cursorTimer_->start(1000);
+ }
+
+ if (hasBlinkText_) {
+ blinkTimer_->start(1000);
+ }
+}
+
+void FQTermScreen::repaintScreen(QPaintEvent *pe, QPainter &painter) {
+ FQ_FUNC_TIMER("screen_paint", 5);
+
+ //painter.setBackground(QBrush(colors_[0]));
+
+ FQ_TRACE("screen", 5) << "Client area: " << pe->rect().width()
+ << "x" << pe->rect().height();
+
+ QRect rect = pe->rect().intersect(clientRectangle_);
+ //painter.eraseRect(rect);
+ drawBackground(painter, rect, 0);
+ QPoint tlPoint = mapToChar(QPoint(rect.left(), rect.top()));
+
+ QPoint brPoint = mapToChar(QPoint(rect.right(), rect.bottom()));
+
+ for (int y = tlPoint.y(); y <= brPoint.y(); y++) {
+ drawLine(painter, y);
+ }
+ if (termWindow_->getUrlStartPoint() != termWindow_->getUrlEndPoint()) {
+ drawUnderLine(painter, termWindow_->getUrlStartPoint(), termWindow_->getUrlEndPoint());
+ }
+
+
+}
+
+/////////////////////////////////////////////////
+//TODO: change to a more powerful function
+FQTermScreen::TextRenderingType FQTermScreen::charRenderingType(const QChar& c) {
+ if (c == ' ') return HalfAndSpace;
+ if (c.unicode() > 0x7f && c.unicode() <= 0x2dff) {
+ return FullAndAlign;
+ } else if (c.unicode() > 0x2dff) {
+ if (cnFixedPitch_)
+ return FullNotAlign;
+ else
+ return FullAndAlign;
+ }
+ return HalfAndAlign;
+}
+
+static bool isColorBlock(const QChar& c) {
+ if (!FQTermPref::getInstance()->isAnsciiEnhance_) return false;
+ return ((c.unicode() >= 0x2581 && c.unicode() <= 0x258f) ||
+ (c.unicode() >= 0x25e2 && c.unicode() <= 0x25e5));
+}
+
+/////////////////////////////////////////////////
+// draw a line with the specialAtter if given.
+// modified by hooey to draw part of the line.
+void FQTermScreen::drawLine(QPainter &painter, int index, int startx, int endx,
+ bool complete) {
+ FQ_ASSERT(index < termBuffer_->getNumLines());
+
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(index);
+ const unsigned char *color = pTextLine->getColors();
+ const unsigned char *attr = pTextLine->getAttributes();
+
+ uint linelength = pTextLine->getWidth();
+ bool isSessionSelected = session_->isSelectedMenu(index);
+ bool isTransparent = isSessionSelected && param_->menuType_ == 2;
+
+ menuRect_ = QRect();
+ QString cstrText;
+
+ if (startx < 0) {
+ startx = 0;
+ }
+
+ if (endx > (long)linelength || endx < 0) {
+ endx = linelength;
+ }
+
+ if (complete == true && isSessionSelected) {
+ menuRect_ = drawMenuSelect(painter, index);
+ startx = 0;
+ endx = linelength;
+ }
+
+ startx = pTextLine->getCellBegin(startx);
+ endx = pTextLine->getCellEnd(endx);
+
+ bool isMonoSpace = true;
+ if (!cnFixedPitch_
+ || !enFixedPitch_) {
+ isMonoSpace = false;
+ }
+
+
+
+ for (unsigned i = startx; (long)i < endx;) {
+ startx = i;
+ unsigned char tempcp = color[i];
+ unsigned char tempea = attr[i];
+ unsigned cell_begin = pTextLine->getCellBegin(startx);
+ unsigned cell_end = pTextLine->getCellEnd(cell_begin + 1);
+ TextRenderingType temprt;
+ cstrText.clear();
+ pTextLine->getPlainText(cell_begin, cell_end, cstrText);
+ temprt = charRenderingType(cstrText[0]);
+ bool color_block = isColorBlock(cstrText[0]);
+
+ bool bSelected = termBuffer_->isSelected(
+ QPoint(i, index), param_->isRectSelect_);
+
+ // get str of the same attribute
+ while ((long)i < endx && tempcp == color[i] && tempea == attr[i] &&
+ bSelected == termBuffer_->isSelected(
+ QPoint(i, index), param_->isRectSelect_)) {
+ unsigned cellBegin = pTextLine->getCellBegin(i);
+ unsigned cellEnd = pTextLine->getCellEnd(cellBegin + 1);
+ cstrText.clear();
+ pTextLine->getPlainText(cellBegin, cellEnd, cstrText);
+ if (temprt != charRenderingType(cstrText[0])) {
+ break;
+ }
+ bool colorBlock = isColorBlock(cstrText[0]);
+ if (cell_end != cellEnd && colorBlock || color_block && !colorBlock) {
+ break;
+ }
+ ++i;
+ }
+
+ cell_end = pTextLine->getCellEnd(i);
+ cstrText.clear();
+ pTextLine->getPlainText(cell_begin, cell_end, cstrText);
+
+ unsigned j = i;
+ if (j > 0 && pTextLine->getCellBegin(j) == pTextLine->getCellBegin(j - 1)
+ && *(pTextLine->getColors() + j) != *(pTextLine->getColors() + j - 1)) {
+ j++;
+ }
+ for (; j < cell_end; ++j) {
+ cstrText.append((QChar)URC);
+ }
+
+ int text_width = cell_end - cell_begin;
+
+ bool draw_half_begin_char = false;
+
+ if (startx > 0 && pTextLine->getCellBegin(startx) == pTextLine->getCellBegin(startx - 1)
+ && *(pTextLine->getColors() + startx) != *(pTextLine->getColors() + startx - 1)) {
+//#if defined(WIN32)
+ draw_half_begin_char = true;
+//#else
+// startx++;
+//#endif
+ }
+
+ painter.setFont((temprt == HalfAndAlign || temprt == HalfAndSpace)?*englishFont_:*nonEnglishFont_);
+ if (isMonoSpace && temprt != FullAndAlign) {
+ QFont& font = (temprt == HalfAndAlign || temprt == HalfAndSpace)?*englishFont_:*nonEnglishFont_;
+ if (temprt == HalfAndAlign) {
+ font.setLetterSpacing(QFont::AbsoluteSpacing, enLetterSpacing_);
+ } else if (temprt == HalfAndSpace) {
+ font.setLetterSpacing(QFont::AbsoluteSpacing, spLetterSpacing_);
+ } else {
+ font.setLetterSpacing(QFont::AbsoluteSpacing, cnLetterSpacing_);
+ }
+ painter.setFont(font);
+ if (draw_half_begin_char) {
+ text_width--;
+ draw_half_begin_char = false;
+ }
+ drawStr(painter, cstrText, startx, index, text_width,
+ tempcp, tempea, isTransparent, bSelected);
+ font.setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ } else if (temprt == FullNotAlign) {
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, cnLetterSpacing_);
+ painter.setFont(*nonEnglishFont_);
+ if (draw_half_begin_char) {
+ text_width--;
+ draw_half_begin_char = false;
+ }
+ drawStr(painter, cstrText, startx, index, text_width,
+ tempcp, tempea, isTransparent, bSelected);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ } else if (temprt == HalfAndSpace) {
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, spLetterSpacing_);
+ painter.setFont(*englishFont_);
+ if (draw_half_begin_char) {
+ text_width--;
+ draw_half_begin_char = false;
+ }
+ drawStr(painter, cstrText, startx, index, text_width,
+ tempcp, tempea, isTransparent, bSelected);
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ }else {
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, enLetterSpacing_);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, cnLetterSpacing_);
+ if (temprt == HalfAndAlign)
+ painter.setFont(*englishFont_);
+ else if (temprt == FullAndAlign)
+ painter.setFont(*nonEnglishFont_);
+ // Draw Characters one by one to fix the variable-width font
+ // display problem.
+ int offset = 0;
+ for (uint j = 0; (long)j < cstrText.length(); ++j) {
+ // TODO_UTF16: wrong character width here.
+ if (temprt == HalfAndAlign) {
+ drawStr(painter, (QString)cstrText.at(j),
+ startx + offset, index, 1,
+ tempcp, tempea,
+ isTransparent, bSelected);
+ offset++;
+ } else if (temprt == FullAndAlign){
+
+
+ int w = 2;
+ if (draw_half_begin_char) {
+ w--;
+ }
+ drawStr(painter, (QString)cstrText.at(j),
+ startx + offset, index, w,
+ tempcp, tempea,
+ isTransparent, bSelected);
+ if (draw_half_begin_char) {
+ draw_half_begin_char = false;
+ offset--;
+ }
+ offset += 2;
+
+ }
+ }
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ englishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ }
+ }
+}
+//
+// draw functions
+void FQTermScreen::drawStr(QPainter &painter, const QString &str,
+ int x, int y, int length,
+ unsigned char color, unsigned char attr,
+ bool transparent, bool selected) {
+ unsigned char cp = color;
+ unsigned char ea = attr;
+
+ // test bold mask or always highlighted
+ if (GETBRIGHT(ea) || param_->isAlwaysHighlight_) {
+ cp |= SET_FG_HIGHLIGHT(1);
+ }
+
+ // use 8-15 color
+ // test dim mask
+ if (GETDIM(ea)) {
+ }
+
+ // test underline mask
+ if (GETUNDERLINE(ea)) {
+ QFont font = painter.font();
+ font.setUnderline(true);
+ painter.setFont(font);
+ } else {
+ QFont font = painter.font();
+ font.setUnderline(false);
+ painter.setFont(font);
+ }
+ // test blink mask
+ if (GETBLINK(ea)){}
+ // test rapidblink mask
+ if (GETRAPIDBLINK(ea)){}
+ // test reverse mask
+ if (GETREVERSE(ea)) {
+ cp = GET_INVERSE_COLOR(cp);
+ }
+
+ if (selected) {
+ cp = GET_INVERSE_COLOR(cp);
+ }
+
+ // test invisible mask
+ if (GETINVISIBLE(ea)) {
+ }
+
+
+
+ int pen_color_index = GETFG(cp);
+ if (!param_->isAnsiColor_) {
+ if (GETBG(cp) != 0) {
+ pen_color_index = 0;
+ } else {
+ pen_color_index = 7;
+ }
+ }
+ painter.setPen(colors_[pen_color_index]);
+
+ int brush_color_index = GETBG(cp);
+ if (!param_->isAnsiColor_) {
+ if (GETBG(cp) != 0) {
+ brush_color_index = 7;
+ } else {
+ brush_color_index = 0;
+ }
+ }
+
+
+ QBrush brush(colors_[brush_color_index]);
+
+ // black on white without attr
+ if (FQTermPref::getInstance()->isBossColor_) {
+ painter.setPen(Qt::black);
+ brush = QBrush(Qt::white);
+ }
+
+ QPoint pt = mapToPixel(QPoint(x, y));
+ QRect rcErase = mapToRect(x, y, length, 1);
+
+ if (!menuRect_.intersects(rcErase)){
+ if (x == 0) {
+ rcErase.setLeft(rcErase.left() - 1);
+ }
+ //painter.fillRect(rcErase, brush);
+ drawBackground(painter, rcErase, brush_color_index);
+ if (x == 0) {
+ rcErase.setLeft(rcErase.left() + 1);
+ }
+ } else {
+ QRect rcKeep = menuRect_.intersected(rcErase);
+ rcKeep.setY(rcErase.y());
+ rcKeep.setHeight(rcErase.height());
+ if (rcErase.left() < rcKeep.left()) {
+ QPoint point = rcKeep.bottomLeft();
+ point.setX(point.x() + 1);
+ point.setY(point.y() + 1);
+ painter.fillRect(QRect(rcErase.topLeft(), point),
+ brush);
+ }
+ if (rcKeep.right() < rcErase.right()) {
+ QPoint point = rcErase.bottomRight();
+ point.setX(point.x() + 1);
+ point.setY(point.y() + 1);
+
+ painter.fillRect(QRect(rcKeep.topRight(), point),
+ brush);
+ }
+ }
+
+ if (!(isBlinkScreen_ && GETBLINK(attr))) {
+ FQ_TRACE("draw_text", 10) << "draw text: " << str;
+
+ QFontMetrics qm = painter.fontMetrics();
+ int font_height = qm.height();
+ int expected_font_height = rcErase.height();
+ int height_gap = expected_font_height - font_height;
+ int offset = (height_gap + 1)/2;
+ int ascent = qm.ascent() + offset;
+
+//#if defined(WIN32)
+ int verticalAlign = Qt::AlignVCenter;
+ switch(param_->alignMode_) {
+ case 0:
+ verticalAlign = Qt::AlignVCenter;
+ break;
+ case 1:
+ verticalAlign = Qt::AlignBottom;
+ break;
+ case 2:
+ verticalAlign = Qt::AlignTop;
+ break;
+ }
+ if (length > 2 || !isColorBlock(str[0])) {
+ painter.drawText(rcErase, Qt::AlignRight | verticalAlign, str);
+ } else {
+ //here length == 1 or == 2, isColorBlock == true, ensured in drawLine.
+ //when length == 1, we are drawing the second half of the block,
+ //otherwise the whole block.
+ //(c.unicode() >= 0x2581 && c.unicode() <= 0x258f)
+ //7 rectangles from shorter to taller (1/8 - 7/8 on the bottom)
+ //1 rectangle full
+ //7 rectangles from thicker to thinner (7/8 - 1/8 on the left)
+ //(c.unicode() >= 0x25e2 && c.unicode() <= 0x25e5)
+ //4 triangles bottom-right, bottom-left, top-left, top-right
+ QPolygon bound = rcErase;
+ QPolygon toDraw;
+ QRect rcFull = mapToRect(x, y, 2, 1);
+ rcFull.setBottom(rcFull.bottom() + 1);
+ rcFull.setRight(rcFull.right() + 1);
+ int unic = str[0].unicode();
+ if (unic >= 0x2581 && unic <= 0x2588) {
+ toDraw = QRect(rcFull.left(), rcFull.top() - rcFull.height() * (unic - 0x2581 + 1 - 8) / 8, rcFull.width(), rcFull.height() * (unic - 0x2581 + 1) / 8);
+ } else if (unic > 0x2588 && unic <= 0x258f) {
+ toDraw = QRect(rcFull.left(), rcFull.top(), rcFull.width() * (8 - unic + 0x2589 - 1) / 8, rcFull.height());
+ } else { //triangles
+ QVector<QPoint> points;
+ points.push_back(rcFull.topLeft());
+ points.push_back(rcFull.topRight());
+ points.push_back(rcFull.bottomRight());
+ points.push_back(rcFull.bottomLeft());
+ points.remove(unic - 0x25e2);
+ toDraw = points;
+ }
+ QBrush oldBrush = painter.brush();
+ painter.setBrush(colors_[pen_color_index]);
+ QPen oldPen = painter.pen();
+ painter.setPen(Qt::transparent);
+ painter.drawConvexPolygon(toDraw.intersected(bound));
+ painter.setBrush(oldBrush);
+ painter.setPen(oldPen);
+ }
+//#else
+// painter.drawText(pt.x(), pt.y() + ascent, str);
+//#endif
+ }
+}
+
+
+void FQTermScreen::eraseRect(QPainter &, int, int, int, int, short){
+ FQ_VERIFY(false);
+}
+
+void FQTermScreen::bossColor() {
+ if (FQTermPref::getInstance()->isBossColor_) {
+ colors_[0] = Qt::white;
+ colors_[7] = Qt::black;
+ QPalette palette;
+ palette.setColor(backgroundRole(), Qt::white);
+ setPalette(palette);
+
+ } else {
+ colors_[0] = param_->backgroundColor_;
+ colors_[7] = param_->foregroundColor_;
+ }
+
+
+ setPaintState(Repaint);
+ update();
+}
+
+QRect FQTermScreen::drawMenuSelect(QPainter &painter, int index) {
+ QRect rcSelect, rcMenu, rcInter;
+ // FIXME: what is this for
+/*
+ if (termBuffer_->isSelected(index)) {
+ bool is_rect_sel = param_->isRectSelect_;
+ rcSelect = mapToRect(termBuffer_->getSelectRect(index, is_rect_sel));
+ if (FQTermPref::getInstance()->isBossColor_) {
+ painter.fillRect(rcSelect, QBrush(colors_[0]));
+ } else {
+ painter.fillRect(rcSelect, QBrush(colors_[7]));
+ }
+ }
+*/
+ if (session_->isSelectedMenu(index)) {
+ rcMenu = mapToRect(session_->getMenuRect());
+ // m_pBand->setGeometry(rcMenu);
+ // m_pBand->show();
+ switch (param_->menuType_) {
+ case 0:
+ // underline
+ painter.fillRect(rcMenu.x(), rcMenu.y() + 10 * charHeight_ / 11,
+ rcMenu.width(), charHeight_ / 11, colors_[7]);
+ break;
+ case 2:
+ painter.fillRect(rcMenu, QBrush(FQTermPref::getInstance()->isBossColor_?colors_[0]:param_->menuColor_));
+ break;
+ }
+ }
+ return rcMenu;
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Auxilluary */
+/* */
+/* ------------------------------------------------------------------------ */
+
+QSize FQTermScreen::getScreenSize() const
+{
+ return QSize(termBuffer_->getNumColumns() * charWidth_, termBuffer_->getNumRows() * charHeight_);
+}
+
+QPoint FQTermScreen::mapToPixel(const QPoint &point) {
+ int dx = (getScreenSize().width() - clientRectangle_.width()) * FQTermPref::getInstance()->displayOffset_ / 100;
+ int dy = getVerticalSetting();
+ QPoint pt = clientRectangle_.topLeft();
+ pt.setX(pt.x() - dx);
+ pt.setY(pt.y() - dy);
+ QPoint pxlPoint;
+
+ pxlPoint.setX(point.x() *charWidth_ + pt.x());
+ pxlPoint.setY((point.y() - bufferStart_) *charHeight_ + pt.y());
+
+ return pxlPoint;
+}
+// mapToChar: get a position in the window and return the
+// corresponding char position
+QPoint FQTermScreen::mapToChar(const QPoint &point) {
+ int dx = (getScreenSize().width() - clientRectangle_.width()) * FQTermPref::getInstance()->displayOffset_ / 100;
+ int dy = getVerticalSetting();
+ QPoint pt = clientRectangle_.topLeft();
+ pt.setX(pt.x() - dx);
+ pt.setY(pt.y() - dy);
+ QPoint chPoint;
+ chPoint.setX(qMin(qMax(0, int((point.x() - pt.x()) / charWidth_)),
+ termBuffer_->getNumColumns() - 1));
+ chPoint.setY(qMin(qMax(0, int((point.y() - pt.y()) / charHeight_) + bufferStart_),
+ bufferEnd_));
+
+ //FIXME add bound check
+ return chPoint;
+}
+
+QRect FQTermScreen::mapToRect(int x, int y, int width, int height) {
+ QPoint pt = mapToPixel(QPoint(x, y));
+
+ if (width == -1) {
+ // to the end
+ return QRect(pt.x(), pt.y(), getScreenSize().width(), charHeight_ *height);
+ } else {
+ return QRect(pt.x(), pt.y(), width *charWidth_, charHeight_ *height);
+ }
+}
+
+QRect FQTermScreen::mapToRect(const QRect &rect) {
+ return mapToRect(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+// from KImageEffect::fade
+QImage &FQTermScreen::fade(QImage &img, float val, const QColor &color) {
+ if (img.width() == 0 || img.height() == 0) {
+ return img;
+ }
+
+ // We don't handle bitmaps
+ if (img.depth() == 1) {
+ return img;
+ }
+
+ unsigned char tbl[256];
+ for (int i = 0; i < 256; i++) {
+ tbl[i] = (int)(val *i + 0.5);
+ }
+
+ int red = color.red();
+ int green = color.green();
+ int blue = color.blue();
+
+ QRgb col;
+ int r, g, b, cr, cg, cb;
+
+ if (img.depth() <= 8) {
+ // pseudo color
+ for (int i = 0; i < img.numColors(); i++) {
+ col = img.color(i);
+ cr = qRed(col);
+ cg = qGreen(col);
+ cb = qBlue(col);
+ if (cr > red) {
+ r = cr - tbl[cr - red];
+ } else {
+ r = cr + tbl[red - cr];
+ }
+ if (cg > green) {
+ g = cg - tbl[cg - green];
+ } else {
+ g = cg + tbl[green - cg];
+ }
+ if (cb > blue) {
+ b = cb - tbl[cb - blue];
+ } else {
+ b = cb + tbl[blue - cb];
+ }
+ img.setColor(i, qRgba(r, g, b, qAlpha(col)));
+ }
+ } else {
+ // truecolor
+ for (int y = 0; y < img.height(); y++) {
+ QRgb *data = (QRgb*)img.scanLine(y);
+ for (int x = 0; x < img.width(); x++) {
+ col = *data;
+ cr = qRed(col);
+ cg = qGreen(col);
+ cb = qBlue(col);
+ if (cr > red) {
+ r = cr - tbl[cr - red];
+ } else {
+ r = cr + tbl[red - cr];
+ }
+ if (cg > green) {
+ g = cg - tbl[cg - green];
+ } else {
+ g = cg + tbl[green - cg];
+ }
+ if (cb > blue) {
+ b = cb - tbl[cb - blue];
+ } else {
+ b = cb + tbl[blue - cb];
+ }
+ *data++ = qRgba(r, g, b, qAlpha(col));
+ }
+ }
+ }
+
+ return img;
+}
+
+void FQTermScreen::inputMethodEvent(QInputMethodEvent *e) {
+ FQ_TRACE("ime", 5) << "Preedit: " << e->preeditString();
+ FQ_TRACE("ime", 5) << "Commit: " << e->commitString();
+
+ FQ_TRACE("ime", 8) << "Replace: " << e->replacementStart()
+ << ", " << e->replacementLength();
+
+ if (e->preeditString().size() > 0) {
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ preedit_line_->setPreeditText(e, nonEnglishFont_);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ QPoint pt = mapToPixel(QPoint(termBuffer_->getCaretColumn(),
+ termBuffer_->getCaretLine()));
+ preedit_line_->move(pt);
+ preedit_line_->show();
+ preedit_line_->update();
+ } else {
+ preedit_line_->hide();
+ }
+
+ if (e->commitString().size() > 0) {
+ emit inputEvent(e->commitString());
+ }
+}
+
+QVariant FQTermScreen::inputMethodQuery(Qt::InputMethodQuery property) const {
+ FQ_TRACE("ime", 5) << "Query: " << property;
+
+ int row = termBuffer_->getCaretRow();
+ int col = termBuffer_->getCaretColumn();
+
+ switch (property) {
+ case Qt::ImMicroFocus:
+ // Here we must use (column + 1, row + 1) as the result,
+ // otherwise MS Pinyin or GPY won't work well.
+ return QVariant(
+ QRect((termBuffer_->getCaretColumn()) * charWidth_
+ + (preedit_line_->isVisible() ?
+ preedit_line_->getCaretOffset() : 0),
+ (termBuffer_->getCaretRow()) * charHeight_,
+ charWidth_, charHeight_));
+ case Qt::ImFont:
+ {
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ QVariant var(*nonEnglishFont_);
+ nonEnglishFont_->setLetterSpacing(QFont::AbsoluteSpacing, 0.0);
+ return var;
+ }
+ case Qt::ImCurrentSelection:
+ return QVariant(QString());
+ case Qt::ImCursorPosition:
+ case Qt::ImSurroundingText:
+ {
+ tmp_im_query_->clear();
+ const FQTermTextLine *line = termBuffer_->getTextLineInTerm(row);
+ line->getPlainText(0, line->getCellEnd(col), *tmp_im_query_);
+
+ // TODO_UTF16: here only BMP is considered.
+ if (Qt::ImCursorPosition) {
+ return QVariant(tmp_im_query_->size());
+ } else {
+ tmp_im_query_->clear();
+ line->getPlainText(0, line->getWidth(), *tmp_im_query_);
+ return QVariant(QString(*tmp_im_query_));
+ }
+ }
+ break;
+ default:
+ return QVariant();
+ }
+}
+
+void FQTermScreen::updateFixedPitchInfo() {
+ QFont cnFont(*nonEnglishFont_);
+ QFont enFont(*englishFont_);
+ int cnPixelSize = nonEnglishFont_->pixelSize() <= 5 ? 12 : nonEnglishFont_->pixelSize();
+ int enPixelSize = englishFont_->pixelSize() <= 5 ? 12 : englishFont_->pixelSize();
+ cnFont.setPixelSize(cnPixelSize);
+ enFont.setPixelSize(enPixelSize);
+ QString cnTestString = QString::fromUtf8("\xe5\x9c\xb0\xe6\x96\xb9\xe6\x94\xbf\xe5\xba\x9c");
+ cnFixedPitch_ = (QFontMetrics(cnFont).width(cnTestString) ==
+ cnTestString.length() * QFontMetrics(cnFont).width(cnTestString.at(0)));
+ QString enTestString = QString::fromUtf8("www.newsmth.net");
+ enFixedPitch_ = QFontInfo(enFont).fixedPitch() &&
+ (QFontMetrics(enFont).width(enTestString) == enTestString.length() * QFontMetrics(enFont).width(enTestString.at(0)));
+
+ FQ_TRACE("font", 10) << "\nenglish: " << enFixedPitch_
+ << "\n chinese: " << cnFixedPitch_;
+
+}
+
+void FQTermScreen::setTermFont(bool isEnglish, const QFont& font)
+{
+ QFont *&pFont = isEnglish?englishFont_:nonEnglishFont_;
+ delete pFont;
+ if (param_->isFontAutoFit_ == 1) {
+ pFont = new QFont(font.family());
+ pFont->setKerning(false);
+ } else {
+ pFont = new QFont(font);
+ pFont->setKerning(false);
+ setFontMetrics();
+ }
+ updateFixedPitchInfo();
+ emit termFontChange(isEnglish, font);
+}
+
+QFont FQTermScreen::termFont(bool isEnglish) {
+ return isEnglish?(*englishFont_):(*nonEnglishFont_);
+}
+
+void FQTermScreen::drawUnderLine(QPainter &painter, const QPoint& startPoint, const QPoint& endPoint) {
+ if (startPoint.y() == endPoint.y()) {
+ drawSingleUnderLine(painter, startPoint, endPoint);
+ } else {
+ drawSingleUnderLine(painter, startPoint, QPoint(termBuffer_->getNumColumns(), startPoint.y()));
+ drawSingleUnderLine(painter, QPoint(0, endPoint.y()), endPoint);
+ for (int i = startPoint.y() + 1; i < endPoint.y(); ++i) {
+ drawSingleUnderLine(painter, QPoint(0, i), QPoint(termBuffer_->getNumColumns(), i));
+ }
+ }
+}
+
+void FQTermScreen::drawSingleUnderLine(QPainter &painter, const QPoint& startPoint, const QPoint& endPoint) {
+ FQ_VERIFY(startPoint.y() == endPoint.y());
+ QPoint realStart = mapToPixel(startPoint);
+ QPoint realEnd = mapToPixel(endPoint);
+ painter.fillRect(realStart.x(), realStart.y() + 10 * charHeight_ / 11,
+ realEnd.x() - realStart.x(), charHeight_ / 11, FQTermPref::getInstance()->isBossColor_?colors_[0]:param_->menuColor_);
+}
+
+void FQTermScreen::setFontAntiAliasing( bool on /*= true*/ ) {
+ englishFont_->setStyleStrategy(on?QFont::PreferAntialias:QFont::NoAntialias);
+ nonEnglishFont_->setStyleStrategy(on?QFont::PreferAntialias:QFont::NoAntialias);
+}
+
+void FQTermScreen::widgetHideAt(const QRect& rect){
+ widgetRect_ = rect;
+ setPaintState(Widget);
+ update();
+}
+
+void FQTermScreen::updateWidgetRect(QPainter& painter) {
+
+
+
+ QRect rect = widgetRect_.intersect(clientRectangle_);
+ if (rect.isEmpty())
+ return;
+ drawBackground(painter, rect, 0);
+
+ QPoint tlPoint = mapToChar(QPoint(rect.left(), rect.top()));
+
+ QPoint brPoint = mapToChar(QPoint(rect.right(), rect.bottom()));
+
+ for (int y = tlPoint.y(); y <= brPoint.y(); y++) {
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInBuffer(y);
+ int startx = qMin(tlPoint.x(),int(pTextLine->getWidth()));
+ int endx = qMin(brPoint.x(), int(pTextLine->getWidth()));
+ startx = pTextLine->getCellBegin(startx);
+ endx = pTextLine->getCellEnd(endx);
+ drawLine(painter, y, startx, endx);
+ }
+ widgetRect_ = QRect();
+}
+
+void FQTermScreen::drawBackgroundPixmap(QPainter& painter, const QRect& rect) {
+ if (!hasBackground_ ||
+ FQTermPref::getInstance()->isBossColor_ ||
+ backgroundPixmap_.isNull()) {
+ return;
+ }
+ if (backgroundCoverage_ == 1) { //Only padding, we do not draw screen background.
+ QRegion clip = rect;
+ QRect screenRect = mapToRect(0, termBuffer_->getNumLines() - termBuffer_->getNumRows(), termBuffer_->getNumColumns(), termBuffer_->getNumRows());
+ clip -= screenRect;
+ QVector<QRect> rects = clip.rects();
+ foreach(QRect r, rects) {
+ painter.drawPixmap(r, backgroundPixmap_, r);
+ }
+ return;
+ }
+ painter.drawPixmap(rect, backgroundPixmap_, rect);
+}
+
+int FQTermScreen::getVerticalSetting() const {
+ int dy = -1;
+ switch (FQTermPref::getInstance()->vsetting_)
+ {
+ case 0:
+ {
+ // Top
+ dy = 0;
+ break;
+ }
+ case 1:
+ {
+ // Middle
+ dy = (getScreenSize().height() - clientRectangle_.height()) / 2;
+ break;
+ }
+ case 2:
+ {
+ // Bottom
+ dy = (getScreenSize().height() - clientRectangle_.height());
+ break;
+ }
+ default:
+ {
+ // The logic should never get here
+ break;
+ }
+ }
+ return dy;
+}
+
+void FQTermScreen::drawBackground(QPainter& painter, const QRect& rect, int colorIndex) {
+
+ if (FQTermPref::getInstance()->isBossColor_) {
+ painter.fillRect(rect, Qt::white);
+ return;
+ }
+ if (hasBackground_ && !backgroundPixmap_.isNull()) {
+ if (colorIndex == 0 || (backgroundCoverage_ != 1 && backgroundUseAlpha_))
+ drawBackgroundPixmap(painter, rect);
+ if (backgroundCoverage_ == 1) { //Background only padding, we draw screen background.
+ QRegion clip = rect;
+ QRect screenRect = mapToRect(0, termBuffer_->getNumLines() - termBuffer_->getNumRows(), termBuffer_->getNumColumns(), termBuffer_->getNumRows());
+ clip &= screenRect;
+ QVector<QRect> rects = clip.rects();
+ foreach(QRect r, rects) {
+ painter.fillRect(r, colors_[colorIndex]);
+ }
+ } else {
+ if (backgroundUseAlpha_)
+ painter.setOpacity(double(backgroundAlpha_) / 100);
+ if (colorIndex != 0 || backgroundUseAlpha_)
+ painter.fillRect(rect, colors_[colorIndex]);
+ painter.setOpacity(1.0);
+ }
+ return;
+ }
+ painter.fillRect(rect, colors_[colorIndex]);
+}
+PreeditLine::PreeditLine(QWidget *parent,const QColor *colors)
+ : QWidget(parent),
+ pixmap_(new QPixmap()),
+ colors_(colors) {
+ //setFocusPolicy(Qt::NoFocus);
+ hide();
+}
+
+PreeditLine::~PreeditLine() {
+ delete pixmap_;
+}
+
+void PreeditLine::setPreeditText(QInputMethodEvent *e, const QFont *font) {
+ QString text = e->preeditString();
+
+ const QColor &white_color = colors_[7];
+ const QColor &black_color = colors_[0];
+
+ // MS Pinyin will add a white space '\u3000' in the end. Remove it.
+ text = text.trimmed();
+
+ QFontMetrics fm(*font);
+ QRect textRect = fm.boundingRect(text);
+
+ int width = textRect.width();
+ int height = textRect.height();
+
+ delete pixmap_;
+ pixmap_ = new QPixmap(width, height + 1); // add one pixel to shadow
+ // the original cursor on
+ // screen.
+ this->resize(width, height + 1);
+
+ QPainter painter(pixmap_);
+ painter.fillRect(textRect, QBrush(black_color));
+
+ painter.setFont(*font);
+ painter.setBackgroundMode(Qt::OpaqueMode);
+
+ // Parse attributes of the input method event.
+ for (int i = 0; i < e->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = e->attributes().at(i);
+ switch(a.type) {
+ case QInputMethodEvent::Cursor:
+ FQ_TRACE("ime", 10) << "Cursor: " << a.start << ", " << a.length;
+ {
+ painter.setPen(white_color);
+
+ int caret_begin = fm.boundingRect(text.left(a.start)).right();
+
+ painter.drawLine(caret_begin, 0, caret_begin, height);
+ painter.drawLine(caret_begin + 1, 0, caret_begin + 1, height);
+
+ caret_offset_ = caret_begin;
+ }
+ break;
+ case QInputMethodEvent::TextFormat:
+ {
+ if (a.start + a.length > text.size()) {
+ // index over flow. ignore it.
+ break;
+ }
+
+ const QString &sub_text = text.mid(a.start, a.length);
+
+ int x = fm.boundingRect(text.left(a.start)).width();
+
+ QTextCharFormat f =
+ qvariant_cast<QTextFormat>(a.value).toCharFormat();
+
+ // Hack here.
+ // If the background() is of style Qt::SolidPattern,
+ // we consider this segment of text is highlighted.
+ // Otherwise it's normal preedit text.
+ if (f.background().style() == Qt::SolidPattern) {
+ QBrush bg(white_color);
+ bg.setStyle(Qt::SolidPattern);
+
+ painter.setBackground(bg);
+ painter.setPen(black_color);
+ } else {
+ QBrush bg(black_color);
+ bg.setStyle(Qt::SolidPattern);
+
+ painter.setBackground(bg);
+ painter.setPen(white_color);
+ }
+
+ // Draw the text;
+ painter.drawText(x, fm.ascent(), sub_text);
+
+ FQ_TRACE("ime", 10) << "Sub-text: " << sub_text;
+ FQ_TRACE("ime", 10) << "Format: " << a.start << ", " << a.length;
+ FQ_TRACE("ime", 10) << "Background: " << f.background();
+ FQ_TRACE("ime", 10) << "Pen: " << f.textOutline();
+ }
+ break;
+ case QInputMethodEvent::Language:
+ FQ_TRACE("ime", 10) << "Language: " << a.start << ", " << a.length;
+ break;
+ case QInputMethodEvent::Ruby:
+ FQ_TRACE("ime", 10) << "Ruby: " << a.start << ", " << a.length;
+ break;
+ }
+ }
+
+ // Draw a line under the preedit text.
+ QPen pen(white_color);
+ pen.setStyle(Qt::DashLine);
+ painter.setPen(pen);
+ painter.drawLine(0, height - 1, width, height - 1);
+}
+
+void PreeditLine::paintEvent(QPaintEvent *e) {
+ QWidget::paintEvent(e);
+ QPainter p(this);
+ p.drawPixmap(QPointF(0, 0), *pixmap_, e->rect());
+}
+
+} // namespace FQTerm
+
+#include "fqterm_screen.moc"
diff --git a/src/fqterm/fqterm_screen.h b/src/fqterm/fqterm_screen.h
new file mode 100644
index 0000000..5c65142
--- /dev/null
+++ b/src/fqterm/fqterm_screen.h
@@ -0,0 +1,281 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SCREEN_H
+#define FQTERM_SCREEN_H
+
+#include <QWidget>
+#include <QVector>
+#include <QList>
+#include "fqterm_param.h"
+#include "fqterm_convert.h"
+
+class QTextCodec;
+class QColor;
+class QPainter;
+class QInputMethodEvent;
+class QPixmap;
+class QScrollBar;
+class QShortcut;
+
+namespace FQTerm {
+
+class FQTermWindow;
+class FQTermBuffer;
+class FQTermSession;
+class FQTermParam;
+
+class PreeditLine: public QWidget {
+public:
+ PreeditLine(QWidget *parent,const QColor *colors);
+ ~PreeditLine();
+
+ void setPreeditText(QInputMethodEvent *e, const QFont *font);
+
+ void paintEvent(QPaintEvent * event);
+
+ int getCaretOffset() const {return caret_offset_;}
+
+private:
+ QPixmap *pixmap_;
+ int caret_offset_;
+
+ const QColor *colors_;
+};
+
+class FQTermScreen: public QWidget {
+ Q_OBJECT;
+ public:
+
+ enum PaintState {
+ System = 0, Repaint = 1, NewData = 2, Blink = 4, Cursor = 8, Widget = 16
+ };
+ enum MouseState {
+ Enter, Press, Move, Release, Leave
+ };
+
+ FQTermScreen(QWidget *parent, FQTermSession *session);
+ ~FQTermScreen();
+
+ void setSchema();
+ void setTermFont(bool isEnglish, const QFont& font);
+
+ QFont termFont(bool isEnglish);
+
+
+ void setPaintState(PaintState ps) {
+ paintState_ |= ps;
+ }
+
+ void clearPaintState(PaintState ps) {
+ paintState_ &= ~ps;
+ }
+
+ bool testPaintState(PaintState ps) {
+ return paintState_ & ps;
+ }
+
+
+ /*void clearPaintState() {
+ paintState_ = None;
+ }*/
+ // Buffer cell coordinate to screen pixel.
+ int getBufferStart() {return bufferStart_;}
+ QPoint mapToPixel(const QPoint &);
+
+ // Screen pixel coordinate to buffer cell coordinate.
+ QPoint mapToChar(const QPoint &);
+
+ // Buffer cell coordinate to screen pixel.
+ QRect mapToRect(int x, int y, int width, int height);
+ QRect mapToRect(const QRect &);
+ private:
+ int paintState_;
+ void updateWidgetRect(QPainter& painter);
+ void refreshScreen(QPainter &painter);
+ void blinkScreen(QPainter &painter);
+ void updateCursor(QPainter &painter);
+ void repaintScreen(QPaintEvent *pe, QPainter &painter);
+ void syncBufferAndScreen();
+ void updateBackgroundPixmap();
+ void drawBackground(QPainter& painter, const QRect& rect, int colorIndex);
+ void drawBackgroundPixmap(QPainter& painter, const QRect& rect);
+ int getVerticalSetting() const;
+
+ signals:
+ // 0 - enter 1 - press 2 - move 3 - release 4 - leave
+ void mouseAction(int, QMouseEvent*);
+ void inputEvent(const QString&);
+ void termFontChange(bool isEnglish, QFont font);
+
+ public slots:
+ void bufferSizeChanged();
+ void termSizeChanged(int column, int row);
+ void bossColor();
+ void updateScrollBar();
+ void setFontAntiAliasing(bool on = true);
+ void widgetHideAt(const QRect& rect);
+
+
+ protected:
+ void initFontMetrics();
+
+ bool event(QEvent *e);
+
+ void resizeEvent(QResizeEvent*);
+ void focusInEvent(QFocusEvent*);
+ void focusOutEvent(QFocusEvent*);
+
+ void paintEvent(QPaintEvent*);
+
+ // mouse
+ void enterEvent(QEvent*);
+ void leaveEvent(QEvent*);
+ void mousePressEvent(QMouseEvent*);
+ void mouseMoveEvent(QMouseEvent*);
+ void mouseReleaseEvent(QMouseEvent*);
+ void wheelEvent(QWheelEvent*);
+
+ // display
+ void eraseRect(QPainter &, int, int, int, int, short);
+ void drawStr(QPainter &painter, const QString &str,
+ int x, int y, int length,
+ unsigned char color, unsigned char attr,
+ bool transparent, bool selected = false);
+ void drawLine(QPainter &, int index, int startx = -1, int endx = -1,
+ bool complete = true);
+ void drawCaret(QPainter &, bool);
+ QRect drawMenuSelect(QPainter &, int);
+ void drawUnderLine(QPainter &, const QPoint& startPoint, const QPoint& endPoint);
+
+ // auxiluary
+ int getPosX(int xChar) {
+ return xChar *charWidth_;
+ }
+ int getPosY(int yLine) {
+ return yLine *charHeight_;
+ }
+
+ //screen size, in pixel.
+ QSize getScreenSize() const;
+
+
+
+ void updateFont();
+ void setFontMetrics();
+
+ QImage &fade(QImage &, float, const QColor &);
+
+ void inputMethodEvent(QInputMethodEvent *e);
+ QVariant inputMethodQuery(Qt::InputMethodQuery property)const;
+
+
+ protected slots:
+ void blinkEvent();
+ void cursorEvent();
+ void scrollChanged(int);
+ void prevPage();
+ void nextPage();
+ void prevLine();
+ void nextLine();
+ void scrollLine(int);
+ protected:
+ void drawSingleUnderLine(QPainter &, const QPoint& startPoint, const QPoint& endPoint);
+
+ QRect clientRectangle_; // the display area
+ QRect menuRect_;
+ QRect widgetRect_; //we need to redraw this rect since a widget just disappeared.
+
+ int scrollBarWidth_;
+
+ QScrollBar *scrollBar_;
+
+ QTimer *blinkTimer_;
+ QTimer *cursorTimer_;
+
+ bool isBlinkScreen_;
+ bool isBlinkCursor_;
+ bool hasBlinkText_;
+
+ FQTermWindow *termWindow_;
+ FQTermSession *session_;
+ const FQTermBuffer *termBuffer_;
+ FQTermParam *param_;
+
+ bool is_light_background_mode_;
+
+ QColor colors_[16];
+ QFont *englishFont_;
+ QFont *nonEnglishFont_;
+
+ double fontAscent_, fontDescent_;
+ double charWidth_, charHeight_;
+ double cnLetterSpacing_;
+ double enLetterSpacing_;
+ double spLetterSpacing_;
+
+ void updateFixedPitchInfo();
+ bool cnFixedPitch_;
+ bool enFixedPitch_;
+ int lineSpacing_; // for future
+
+ bool *areLinesBlink_;
+ bool isCursorShown_;
+
+ // background
+ bool hasBackground_;
+ QPixmap backgroundPixmap_;
+ QPixmap originBackgroundPixmap_;
+ //0 -- tile 1 -- center 2 -- stretch
+ int backgroundRenderOption_;
+ //0 -- Whole screen, 1 -- Only padding
+ int backgroundCoverage_;
+ bool backgroundUseAlpha_;
+ int backgroundAlpha_;
+
+
+ // the range of the buffer's lines to be displayed
+ int bufferStart_;
+ int bufferEnd_;
+
+ QShortcut *gotoPrevPage_;
+ QShortcut *gotoNextPage_;
+ QShortcut *gotoPrevLine_;
+ QShortcut *gotoNextLine_;
+
+ FQTermConvert encodingConverter_;
+
+ PreeditLine *preedit_line_;
+
+ QString *tmp_im_query_;
+
+ //TODO: change to bit field
+ enum TextRenderingType{
+ HalfAndAlign, FullAndAlign, FullNotAlign, HalfAndSpace
+ };
+ TextRenderingType charRenderingType(const QChar& c);
+
+ friend class FQTermWindow;
+ // for test only
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SCREEN_H
diff --git a/src/fqterm/fqterm_scriptengine.cpp b/src/fqterm/fqterm_scriptengine.cpp
new file mode 100644
index 0000000..efab413
--- /dev/null
+++ b/src/fqterm/fqterm_scriptengine.cpp
@@ -0,0 +1,488 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+
+
+#include "fqterm_scriptengine.h"
+#include "fqterm_window.h"
+#include "fqterm_screen.h"
+#include "fqterm_session.h"
+#include "fqterm_buffer.h"
+#include "common.h"
+#include "fqterm_path.h"
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif
+
+#include <QString>
+#include <QDir>
+#include <QMessageBox>
+#include <QTime>
+#include <QTimer>
+#include <QFile>
+#include <QPoint>
+#include <QCursor>
+#include <QFileInfo>
+#include <QScriptContext>
+#include <QScriptContextInfo>
+namespace FQTerm {
+
+
+template <typename Tp>
+QScriptValue qScriptValueFromQObject(QScriptEngine *engine, Tp &qobject) {
+ return engine->newQObject(qobject);
+}
+
+template <typename Tp>
+void qScriptValueToQObject(const QScriptValue &value, Tp &qobject) {
+ qobject = qobject_cast<Tp>(value.toQObject());
+}
+
+template <typename Tp>
+int qScriptRegisterQObjectMetaType(
+ QScriptEngine *engine, const QScriptValue &prototype = QScriptValue()
+ ) {
+ return qScriptRegisterMetaType<Tp>(engine, qScriptValueFromQObject,
+ qScriptValueToQObject, prototype);
+}
+
+
+FQTermScriptEngine::FQTermScriptEngine(FQTermWindow* parent)
+: QObject(parent),
+ window_(parent),
+ engine_(NULL),
+ articleCopyThread_(NULL),
+ timerIDCount_(0) {
+ FQ_VERIFY(window_);
+ session_ = window_->getSession();
+ buffer_ = window_->getSession()->getBuffer();
+ screen_ = window_->getScreen();
+ articleCopyThread_ = new ArticleCopyThread(*session_, session_->getWaitCondition(), session_->getBufferLock());
+ FQ_VERIFY(connect(articleCopyThread_, SIGNAL(articleCopied(int, const QString)),
+ this, SLOT(articleCopied(int, const QString))));
+ engine_ = new QScriptEngine();
+ engine_->globalObject().setProperty(
+ "fq_session", engine_->newQObject(session_));
+ engine_->globalObject().setProperty(
+ "fq_window", engine_->newQObject(window_));
+ engine_->globalObject().setProperty(
+ "fq_buffer", engine_->newQObject(buffer_));
+ engine_->globalObject().setProperty(
+ "fq_screen", engine_->newQObject(screen_));
+ engine_->globalObject().setProperty(
+ "fqterm", engine_->newQObject(this));
+}
+
+FQTermScriptEngine::~FQTermScriptEngine() {
+ engine_->abortEvaluation();
+ delete engine_;
+}
+
+void FQTermScriptEngine::runScript( const QString& filename ) {
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ FQ_TRACE("script", 0) << "Unable to open the script file: " << filename;
+ QMessageBox::warning(window_, tr("FQTerm"),
+ tr("Unable to open the script file\n") + filename,
+ QMessageBox::Close);
+ return;
+ }
+
+ QString script = QString::fromUtf8(file.readAll());
+ QFileInfo fileInfo(filename);
+ QScriptValue result = engine_->evaluate(script, fileInfo.absoluteFilePath());
+ if (engine_->hasUncaughtException()) {
+ int line = engine_->uncaughtExceptionLineNumber();
+ FQ_TRACE("script", 0) << "uncaught exception at line " << line
+ << ":" << result.toString();
+ QMessageBox::warning(window_, tr("FQTerm"),
+ tr("uncaught exception at line ") + QString::number(line)
+ + ":\n" + result.toString(),
+ QMessageBox::Close);
+ }
+}
+
+void FQTermScriptEngine::stopScript() {
+ //all loops should be stopped here.
+ articleCopied_ = true;
+ engine_->abortEvaluation();
+}
+
+void FQTermScriptEngine::msgBox( const QString& msg ) {
+ QMessageBox::warning(window_, tr("FQTerm"),
+ msg,
+ QMessageBox::Close);
+}
+
+int FQTermScriptEngine::caretX() {
+ return buffer_->getCaretColumn();
+}
+
+int FQTermScriptEngine::caretY() {
+ return buffer_->getCaretRow();
+}
+
+int FQTermScriptEngine::columns() {
+ return buffer_->getNumColumns();
+}
+
+int FQTermScriptEngine::rows() {
+ return buffer_->getNumRows();
+}
+
+void FQTermScriptEngine::sendString(const QString& str) {
+ window_->writeRawString(str);
+}
+
+void FQTermScriptEngine::sendParsedString( const QString& str ){
+ window_->externInput(str);
+}
+
+QString FQTermScriptEngine::getText(int row) {
+ QString str;
+ if (row < rows())
+ buffer_->getTextLineInTerm(row)->getAllPlainText(str);
+ return str;
+}
+
+QString FQTermScriptEngine::getAttrText(int row) {
+ QString str;
+ if (row < rows())
+ buffer_->getTextLineInTerm(row)->getAllAnsiText(str);
+ return str;
+}
+
+bool FQTermScriptEngine::isConnected() {
+ return window_->isConnected();
+}
+
+void FQTermScriptEngine::disconnect() {
+ window_->disconnect();
+}
+
+void FQTermScriptEngine::reconnect() {
+ session_->reconnect();
+}
+
+//FIXME: UTF8 and HKSCS
+QString FQTermScriptEngine::getBBSCodec() {
+ return session_->param().serverEncodingID_ == 0 ? "GBK" : "Big5";
+}
+
+QString FQTermScriptEngine::getAddress() {
+ return session_->param().hostAddress_;
+}
+
+int FQTermScriptEngine::getPort() {
+ return session_->param().port_;
+}
+// connection protocol 0-telnet 1-SSH1 2-SSH2
+int FQTermScriptEngine::getProtocol() {
+ return session_->param().protocolType_;
+}
+
+QString FQTermScriptEngine::getReplyKey() {
+ return session_->param().replyKeyCombination_;
+}
+
+QString FQTermScriptEngine::getURL() {
+ return session_->getUrl();
+}
+
+QString FQTermScriptEngine::getIP() {
+ return session_->getIP();
+}
+
+void FQTermScriptEngine::previewImage(const QString& url) {
+ window_->getHttpHelper(url, true);
+}
+
+void FQTermScriptEngine::sleep(int ms) {
+ int originInterval = engine_->processEventsInterval();
+ engine_->setProcessEventsInterval(1);
+ QString busy_wait = "var start = new Date().getTime();\n"
+ "while(true) {if(new Date().getTime() - start > " + QString("%1").arg(ms) + ") break;}\n";
+ engine_->evaluate(busy_wait);
+ engine_->setProcessEventsInterval(originInterval);
+}
+
+//TODO: flags
+void FQTermScriptEngine::articleCopied(int state, const QString content) {
+ if (state == DAE_FINISH) {
+ articleCopied_ = true;
+ articleText_ = content;
+ } else /*if (state == DAE_TIMEOUT)*/ {
+ articleCopied_ = true;
+ articleText_ = "";
+ }
+}
+
+QString FQTermScriptEngine::copyArticle() {
+ articleCopied_ = false;
+ articleText_ = "";
+ articleCopyThread_->wait();
+ articleCopyThread_->start();
+ while(!articleCopied_) {
+ sleep(200);
+ }
+ return articleText_;
+}
+
+void FQTermScriptEngine::finalizeScript() {
+ engine_->setProcessEventsInterval(-1);
+ stopScript();
+ setParent(NULL);
+ //TODO: safe?
+ deleteLater();
+}
+
+void FQTermScriptEngine::writeFile( const QString& filename, const QString& str ) {
+ QFile file(filename);
+ file.open(QIODevice::WriteOnly);
+ file.write(U2U8(str));
+ file.close();
+}
+
+QString FQTermScriptEngine::readFile( const QString& filename ) {
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ QString str = U82U(file.readAll());
+ file.close();
+ return str;
+}
+
+void FQTermScriptEngine::appendFile( const QString& filename, const QString& str ) {
+ QFile file(filename);
+ file.open(QIODevice::WriteOnly | QIODevice::Append);
+ file.write(U2U8(str));
+ file.close();
+}
+
+QStringList FQTermScriptEngine::readFolder( const QString& path ) {
+ return QDir(path).entryList(QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot | QDir::Readable);
+}
+
+QString FQTermScriptEngine::platform() {
+#if defined(WIN32)
+ return "Win";
+#elif defined(__unix__) && !defined(__APPLE__)
+ return "Linux";
+#else
+ return "Mac";
+#endif
+}
+
+bool FQTermScriptEngine::makePath( const QString& path ){
+ return QDir().mkpath(path);
+}
+
+QString FQTermScriptEngine::newLine() {
+ return OS_NEW_LINE;
+}
+
+void FQTermScriptEngine::openUrl(const QString & url) {
+ window_->openUrlImpl(url);
+}
+
+QString FQTermScriptEngine::getSelect(bool color_copy) {
+ return buffer_->getTextSelected(
+ session_->param().isRectSelect_,
+ color_copy,
+ window_->parseString((const char*)session_->param().escapeString_.toLatin1()));
+}
+
+QList<int> FQTermScriptEngine::mapToChar(int screenX, int screenY) {
+ QPoint charP(screen_->mapToChar(QPoint(screenX, screenY)));
+ QList<int> result;
+ result << charP.x() << charP.y() - screen_->getBufferStart();
+ return result;
+}
+
+int FQTermScriptEngine::charX(int screen_x) {
+ return screen_->mapToChar(QPoint(screen_x, 0)).x();
+}
+
+int FQTermScriptEngine::charY(int screen_y) {
+ return screen_->mapToChar(QPoint(0, screen_y)).y() - screen_->getBufferStart();
+}
+
+QString FQTermScriptEngine::getTextAt( int row, int column, int len ) {
+ if (column < 0 || column >= columns() ||
+ row < 0 || row >= rows())
+ return "";
+ if (column + len > columns() || len < 0) {
+ len = columns() - column;
+ }
+ QString result;
+ buffer_->getTextLineInTerm(row)->getPlainText(column, column + len, result);
+ return result;
+}
+
+QString FQTermScriptEngine::getAttrTextAt( int row, int column, int len ) {
+ if (column < 0 || column >= columns() ||
+ row < 0 || row >= rows())
+ return "";
+ if (column + len > columns() || len < 0) {
+ len = columns() - column;
+ }
+ QString result;
+ buffer_->getTextLineInTerm(row)->getAnsiText(column, column + len, result);
+ return result;
+}
+
+QString FQTermScriptEngine::getFullTextAt(int row, int column, int len) {
+ return getTextAt(row, buffer_->getTextLineInTerm(row)->getCellBegin(column), len);
+}
+
+QString FQTermScriptEngine::getFullAttrText(int row, int column, int len) {
+ return getAttrTextAt(row, buffer_->getTextLineInTerm(row)->getCellBegin(column), len);
+}
+
+int FQTermScriptEngine::mouseSX() {
+ return screen_->mapFromGlobal(QCursor::pos()).x();
+}
+
+int FQTermScriptEngine::mouseSY() {
+ return screen_->mapFromGlobal(QCursor::pos()).y();
+}
+
+int FQTermScriptEngine::screenX( int char_x ){
+ return screen_->mapToPixel(QPoint(char_x, 0)).x();
+}
+
+int FQTermScriptEngine::screenY( int char_y ){
+ return screen_->mapToPixel(QPoint(0, char_y + screen_->getBufferStart())).y();
+}
+
+bool FQTermScriptEngine::scriptCallback( const QString& func, const QScriptValueList& args ) {
+ QScriptValue f = engine_->globalObject().property("fqterm").property(func);
+ if (f.isFunction()) {
+ QScriptValue res = f.call(QScriptValue(), args);
+ if (!engine_->hasUncaughtException() && res.isBool()) {
+ return res.toBool();
+ } else {
+ return false;
+ }
+ }
+ return false;
+}
+
+bool FQTermScriptEngine::importFile( const QString& filename ) {
+ QFileInfo fileInfo(filename);
+ if (!fileInfo.isAbsolute()) {
+ //first search current running path.
+ if (engine_->currentContext() && engine_->currentContext()->parentContext()) {
+ QString runningFile = QScriptContextInfo(engine_->currentContext()->parentContext()).fileName();
+ if (!runningFile.isEmpty()) {
+ QFileInfo current(runningFile);
+ fileInfo = QFileInfo(current.absolutePath() + '/' + filename);
+ }
+ }
+ //then look in script folder.
+ if (!fileInfo.exists()) {
+ fileInfo = QFileInfo(getPath(RESOURCE) + "script/" + filename);
+ }
+ }
+ if (!fileInfo.exists()) {
+ return false;
+ }
+ fileInfo.makeAbsolute();
+ runScript(fileInfo.absoluteFilePath());
+ return true;
+}
+
+int FQTermScriptEngine::setInterval(int ms, const QScriptValue& func) {
+ return createTimer(ms, func, false);
+}
+
+
+void FQTermScriptEngine::clearInterval(int id) {
+ destroyTimer(id);
+}
+
+void FQTermScriptEngine::serverRedraw() {
+ sendParsedString("^L");
+}
+
+void FQTermScriptEngine::clientRedraw() {
+ window_->refreshScreen();
+}
+
+void FQTermScriptEngine::setMenuRect(int row, int column, int len) {
+ if (column < 0 || column >= columns() ||
+ row < 0 || row >= rows())
+ return ;
+ if (column + len > columns() || len < 0) {
+ len = columns() - column;
+ }
+ row += screen_->getBufferStart();
+ session_->setMenuRect(row, column, len);
+}
+
+int FQTermScriptEngine::setTimeout(int ms, const QScriptValue& func) {
+ return createTimer(ms, func, true);
+}
+
+void FQTermScriptEngine::clearTimeout(int id) {
+ destroyTimer(id);
+}
+
+int FQTermScriptEngine::createTimer(int ms, const QScriptValue& func, bool singleShot) {
+ QTimer* timer = new QTimer(this);
+ timer->setInterval(ms);
+ timer->setSingleShot(singleShot);
+ int id = timerIDCount_++;
+ if (timerTable_.find(id) != timerTable_.end()) {
+ //actually impossible!
+ destroyTimer(id);
+ }
+ timerTable_[id] = timer;
+ bool res = qScriptConnect(timer, SIGNAL(timeout()), QScriptValue(), func);
+ timer->start();
+ return id;
+}
+
+void FQTermScriptEngine::destroyTimer(int id) {
+ if (timerTable_.find(id) != timerTable_.end()) {
+ timerTable_[id]->stop();
+ delete timerTable_[id];
+ timerTable_.erase(id);
+ }
+}
+
+int FQTermScriptEngine::getUIEventInterval() {
+ return engine_->processEventsInterval();
+}
+
+void FQTermScriptEngine::setUIEventInterval(int ms) {
+ engine_->setProcessEventsInterval(ms);
+}
+
+bool FQTermScriptEngine::isAntiIdle() {
+ return session_->isAntiIdle();
+}
+
+bool FQTermScriptEngine::isAutoReply() {
+ return session_->isAutoReply();
+}
+} // namespace FQTerm
+
+#include "fqterm_scriptengine.moc" \ No newline at end of file
diff --git a/src/fqterm/fqterm_scriptengine.h b/src/fqterm/fqterm_scriptengine.h
new file mode 100644
index 0000000..70ca5cd
--- /dev/null
+++ b/src/fqterm/fqterm_scriptengine.h
@@ -0,0 +1,147 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_SCRIPTENGINE_H
+#define FQTERM_SCRIPTENGINE_H
+
+#include "fqterm.h"
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QScriptEngine>
+#include <QScriptValue>
+#include <QList>
+#include <map>
+class QString;
+class QTimer;
+namespace FQTerm {
+class FQTermWindow;
+class FQTermSession;
+class FQTermScreen;
+class FQTermBuffer;
+class ArticleCopyThread;
+class FQTermScriptEngine : public QObject {
+ Q_OBJECT;
+public:
+ FQTermScriptEngine(FQTermWindow* parent);
+ ~FQTermScriptEngine();
+ QScriptEngine* getQtEngine() {return engine_;}
+ void runScript(const QString& filename);
+ void stopScript();
+ void finalizeScript();
+
+public:
+ bool scriptCallback(const QString& func, const QScriptValueList& args);
+public slots: //script apis
+ //ui functions.
+ void msgBox(const QString& msg);
+
+ //bbs ui functions
+ int caretX();
+ int caretY();
+ QString getText(int row);
+ QString getTextAt(int row, int column, int len);
+ //if we get from a column that contains the second part
+ //of a character with width == 2, we could still get it.
+ QString getFullTextAt(int row, int column, int len);
+ QString getAttrText(int row);
+ QString getAttrTextAt(int row, int column, int len);
+ QString getFullAttrText(int row, int column, int len);
+ void sendString(const QString& str);
+ void sendParsedString(const QString& str);
+ void serverRedraw();
+ void clientRedraw();
+ int columns();
+ int rows();
+ bool isConnected();
+ void disconnect();
+ void reconnect();
+ QString getBBSCodec();
+ QString getAddress();
+ int getPort();
+ int getProtocol();
+ QString getReplyKey();
+ QString getURL();
+ QString getIP();
+ void previewImage(const QString& url);
+ void sleep(int ms);
+ QString copyArticle();
+ void openUrl(const QString & url);
+ QString getSelect(bool color_copy);
+ QList<int> mapToChar(int screenX, int screenY);
+ //next 2 functions are map screen to char for x, y.
+ int charX(int screen_x);
+ int charY(int screen_y);
+ int screenX(int char_x);
+ int screenY(int char_y);
+ //mouse position is given in screen coordinate.
+ int mouseX() {return charX(mouseSX());}
+ int mouseY() {return charY(mouseSY());}
+
+ int mouseSX();
+ int mouseSY();
+
+ void setMenuRect(int row, int col, int len);
+
+ bool importFile(const QString& filename);
+
+ bool isAntiIdle();
+ bool isAutoReply();
+ //auxiliary functions.
+ //should be move to some other class.
+ //qt script provides so poor extensions to js.
+ void writeFile(const QString& filename, const QString& str);
+ void appendFile(const QString& filename, const QString& str);
+ QString readFile(const QString& filename);
+ QStringList readFolder(const QString& path);
+ QString platform();
+ bool makePath(const QString& path);
+ QString newLine();
+
+ //Timer
+ int setInterval(int ms, const QScriptValue& func);
+ void clearInterval(int id);
+ int setTimeout(int ms, const QScriptValue& func);
+ void clearTimeout(int id);
+
+ int getUIEventInterval();
+ void setUIEventInterval(int ms);
+private:
+ int createTimer(int ms, const QScriptValue& func, bool singleShot);
+ void destroyTimer(int id);
+
+private slots:
+ void articleCopied(int state, const QString content);
+private:
+ QScriptEngine* engine_;
+ FQTermWindow* window_;
+ FQTermSession* session_;
+ FQTermScreen* screen_;
+ FQTermBuffer* buffer_;
+ ArticleCopyThread* articleCopyThread_;
+ bool articleCopied_;
+ QString articleText_;
+ std::map<int, QTimer*> timerTable_;
+ int timerIDCount_;
+};
+
+
+}//namespace FQTerm
+#endif //FQTERM_SCRIPTENGINE_H \ No newline at end of file
diff --git a/src/fqterm/fqterm_window.cpp b/src/fqterm/fqterm_window.cpp
new file mode 100644
index 0000000..bb2c867
--- /dev/null
+++ b/src/fqterm/fqterm_window.cpp
@@ -0,0 +1,2531 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <QClipboard>
+#include <QDesktopServices>
+#include <QDialog>
+#include <QFileDialog>
+#include <QFontDialog>
+#include <QFontMetrics>
+#include <QInputDialog>
+#include <QImageReader>
+#include <QMenu>
+#include <QMessageBox>
+#include <QStatusBar>
+#include <QTextEdit>
+#include <QTimer>
+#include <QUrl>
+#include <QtScript/QScriptValue>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QTemporaryFile>
+#include <QRegExp>
+#include <QNetworkProxy>
+#include "addrdialog.h"
+#include "articledialog.h"
+#include "msgdialog.h"
+#include "osdmessage.h"
+#include "popwidget.h"
+#include "progressBar.h"
+#include "common.h"
+#include "fqterm_buffer.h"
+#include "fqterm_canvas.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#include "fqterm_filedialog.h"
+#include "fqterm_frame.h"
+#include "fqterm_http.h"
+#include "fqterm_ip_location.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_screen.h"
+#include "fqterm_session.h"
+#include "fqterm_sound.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#include "imageviewer.h"
+#include "sshlogindialog.h"
+#include "statusBar.h"
+#include "zmodemdialog.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#include "fqterm_python.h"
+#endif //HAVE_PYTHON
+#include "fqterm_scriptengine.h"
+
+
+namespace FQTerm {
+
+char FQTermWindow::directions_[][5] = {
+ // 4
+ "\x1b[1~", // 0 HOME
+ "\x1b[4~", // 1 END
+ "\x1b[5~", // 2 PAGE UP
+ "\x1b[6~", // 3 PAGE DOWN
+ // 3
+ "\x1b[A", // 4 UP
+ "\x1b[B", // 5 DOWN
+ "\x1b[D", // 6 LEFT
+ "\x1b[C" // 7 RIGHT
+};
+
+class FAQ: public QObject {
+ Q_OBJECT;
+ public slots:
+ FAQ() {a = 100;}
+
+ int get() {return a;}
+
+ private:
+ int a;
+};
+
+
+//constructor
+FQTermWindow::FQTermWindow(FQTermConfig *config, FQTermFrame *frame, FQTermParam param,
+ int addressIndex, QWidget *parent,
+ const char *name, Qt::WFlags wflags)
+ : QMainWindow(parent, wflags),
+ frame_(frame),
+ isSelecting_(false),
+ addressIndex_(addressIndex),
+ sound_(NULL),
+ isMouseClicked_(false),
+ blinkStatus_(true),
+ isUrlUnderLined_(false),
+#ifdef HAVE_PYTHON
+ // the system wide script
+ pythonScriptLoaded_(false),
+ // python thread module
+ pModule(NULL),
+ pDict(NULL),
+#endif
+ script_engine_(NULL),
+ externalEditor_(NULL) {
+ // isMouseX11_ = false;
+ session_ = new FQTermSession(config, param);
+ screen_ = new FQTermScreen(this, session_);
+
+ config_ = config;
+ zmodemDialog_ = new zmodemDialog(this);
+
+ externalEditor_ = new FQTermExternalEditor(this);
+
+ pageViewMessage_ = new PageViewMessage(this);
+ tabBlinkTimer_ = new QTimer;
+
+ setWindowIcon(QIcon("noicon"));
+ setWindowTitle(param.name_);
+ setMouseTracking(true);
+ setFocusProxy(screen_);
+ setCentralWidget(screen_);
+ addMenu();
+ setStatusBar(NULL);
+
+
+ FQ_VERIFY(connect(pageViewMessage_, SIGNAL(hideAt(const QRect&)),
+ screen_, SLOT(widgetHideAt(const QRect&))));
+
+ FQ_VERIFY(connect(frame_, SIGNAL(bossColor()),
+ screen_, SLOT(bossColor())));
+
+ FQ_VERIFY(connect(frame_, SIGNAL(fontAntiAliasing(bool)),
+ screen_, SLOT(setFontAntiAliasing(bool))));
+
+ FQ_VERIFY(connect(frame_, SIGNAL(changeLanguage()),
+ this, SLOT(recreateMenu())));
+ FQ_VERIFY(connect(frame_, SIGNAL(bossColor()),
+ screen_, SLOT(bossColor())));
+ FQ_VERIFY(connect(frame_, SIGNAL(updateScroll()),
+ screen_, SLOT(updateScrollBar())));
+
+ FQ_VERIFY(connect(screen_, SIGNAL(inputEvent(const QString&)),
+ session_, SLOT(handleInput(const QString&))));
+
+ FQ_VERIFY(connect(session_, SIGNAL(zmodemStateChanged(int, int, const char*)),
+ this, SLOT(ZmodemState(int, int, const char *))));
+ FQ_VERIFY(connect(zmodemDialog_, SIGNAL(canceled()),
+ session_, SLOT(cancelZmodem())));
+ FQ_VERIFY(connect(session_, SIGNAL(connectionClosed()),
+ this, SLOT(connectionClosed())));
+ FQ_VERIFY(connect(session_, SIGNAL(startAlert()), this, SLOT(startBlink())));
+ FQ_VERIFY(connect(session_, SIGNAL(stopAlert()), this, SLOT(stopBlink())));
+ // FQ_VERIFY(connect(session_->decoder_, SIGNAL(mouseMode(bool)),
+ // this, SLOT(setMouseMode(bool))));
+ FQ_VERIFY(connect(session_, SIGNAL(articleCopied(int, const QString)),
+ this, SLOT(articleCopied(int, const QString))));
+ FQ_VERIFY(connect(session_, SIGNAL(requestUserPwd(QString*, QString*, bool*)),
+ this, SLOT(requestUserPwd(QString *, QString *, bool *))));
+ //connect telnet signal to slots
+ // QVERIFY(connect(session_->telnet_, SIGNAL(readyRead(int)),
+ // this, SLOT(readReady(int))));
+ FQ_VERIFY(connect(session_, SIGNAL(sessionUpdated()),
+ this, SLOT(sessionUpdated())));
+ FQ_VERIFY(connect(session_, SIGNAL(bellReceived()), this, SLOT(beep())));
+ FQ_VERIFY(connect(session_, SIGNAL(onTitleSet(const QString&)), this, SLOT(onTitleSet(const QString&))));
+
+ FQ_VERIFY(connect(session_, SIGNAL(messageAutoReplied()),
+ this, SLOT(messageAutoReplied())));
+ FQ_VERIFY(connect(session_, SIGNAL(telnetStateChanged(int)),
+ this, SLOT(TelnetState(int))));
+ FQ_VERIFY(connect(session_, SIGNAL(errorMessage(QString)),
+ this, SLOT(showSessionErrorMessage(QString))));
+
+ FQ_VERIFY(connect(tabBlinkTimer_, SIGNAL(timeout()), this, SLOT(blinkTab())));
+
+ FQ_VERIFY(connect(externalEditor_, SIGNAL(done(const QString&)), this, SLOT(externalEditorDone(const QString&))));
+
+ FQ_VERIFY(connect(this, SIGNAL(writeStringSignal(const QString&)), this, SLOT(writeString(const QString&)), Qt::QueuedConnection));
+ FQ_VERIFY(connect(this, SIGNAL(writeRawStringSignal(const QString&)), this, SLOT(writeRawString(const QString&)), Qt::QueuedConnection));
+
+#if defined(WIN32)
+ popWindow_ = new popWidget(this, frame_);
+#else
+ popWindow_ = new popWidget(this);
+#endif
+
+ const QString &resource_dir = getPath(RESOURCE);
+
+ cursors_[FQTermSession::kHome] = QCursor(
+ QPixmap(resource_dir + "cursor/home.xpm"));
+ cursors_[FQTermSession::kEnd] = QCursor(
+ QPixmap(resource_dir + "cursor/end.xpm"));
+ cursors_[FQTermSession::kPageUp] = QCursor(
+ QPixmap(resource_dir + "cursor/pageup.xpm"));
+ cursors_[FQTermSession::kPageDown] = QCursor(
+ QPixmap(resource_dir + "cursor/pagedown.xpm"));
+ cursors_[FQTermSession::kUp] = QCursor(
+ QPixmap(resource_dir + "cursor/prev.xpm"));
+ cursors_[FQTermSession::kDown] = QCursor(
+ QPixmap(resource_dir + "cursor/next.xpm"));
+ cursors_[FQTermSession::kLeft] = QCursor(
+ QPixmap(resource_dir + "cursor/exit.xpm"), 0, 10);
+ cursors_[FQTermSession::kRight] = QCursor(
+ QPixmap(resource_dir + "cursor/hand.xpm"));
+ cursors_[FQTermSession::kNormal] = Qt::ArrowCursor;
+
+ script_engine_ = new FQTermScriptEngine(this);
+ if (session_->param().isAutoLoadScript_
+ && !session_->param().autoLoadedScriptFileName_.isEmpty()) {
+ const QString &filename = session_->param().autoLoadedScriptFileName_;
+#ifdef HAVE_PYTHON
+ if (filename.trimmed().endsWith(".py", Qt::CaseInsensitive)){
+ initPython(filename);
+ } else {
+ initPython("");
+#endif
+ runScript(filename);
+#ifdef HAVE_PYTHON
+ }
+ } else {
+ initPython("");
+#endif //HAVE_PYTHON
+ }
+ session_->setScriptListener(this);
+}
+
+FQTermWindow::~FQTermWindow() {
+#ifdef HAVE_PYTHON
+ finalizePython();
+#endif //HAVE_PYTHON
+ script_engine_->finalizeScript();
+ // delete telnet_;
+ delete session_;
+ delete popWindow_;
+ delete tabBlinkTimer_;
+ delete menu_;
+ delete urlMenu_;
+ delete screen_;
+ delete pageViewMessage_;
+ //delete script_engine_;
+}
+
+void FQTermWindow::addMenu() {
+ urlMenu_ = new QMenu(screen_);
+ urlMenu_->addAction(tr("Preview image"), this, SLOT(previewLink()));
+ urlMenu_->addAction(tr("Open link"), this, SLOT(openLink()));
+ urlMenu_->addAction(tr("Save As..."), this, SLOT(saveLink()));
+ urlMenu_->addAction(tr("Copy link address"), this, SLOT(copyLink()));
+ urlMenu_->addSeparator();
+ urlMenu_->addAction(tr("Share Selected Text and URL!"), this, SLOT(shareIt()));
+ const QString &resource_dir = getPath(RESOURCE);
+
+ menu_ = new QMenu(screen_);
+#if defined(__APPLE__)
+ // Please note that on MacOSX Qt::CTRL corresponds to Command key (apple key),
+ // while Qt::Meta corresponds to Ctrl key.
+ QKeySequence copy_shortcut(tr("Ctrl+C"));
+ QKeySequence paste_shortcut(tr("Ctrl+V"));
+#else
+ QKeySequence copy_shortcut(tr("Ctrl+Insert"));
+ QKeySequence paste_shortcut(tr("Shift+Insert"));
+#endif
+ menu_->addAction(QPixmap(resource_dir + "pic/copy.png"), tr("Copy"),
+ this, SLOT(copy()), copy_shortcut);
+ menu_->addAction(QPixmap(resource_dir + "pic/paste.png"), tr("Paste"),
+ this, SLOT(paste()), paste_shortcut);
+
+ menu_->addAction(QPixmap(resource_dir+"pic/get_article_fulltext.png"), tr("Copy Article"),
+ this, SLOT(copyArticle()));
+ menu_->addSeparator();
+
+ QMenu *fontMenu = new QMenu(menu_);
+ fontMenu->setTitle(tr("Font"));
+ fontMenu->setIcon(QPixmap(resource_dir + "pic/change_fonts.png"));
+ for (int i = 0; i < 2; ++i) {
+ QAction *act = fontMenu->addAction(
+ FQTermParam::getLanguageName(bool(i)) + tr(" Font"),
+ this, SLOT(setFont()));
+ act->setData(i);
+ }
+ menu_->addMenu(fontMenu);
+
+ menu_->addAction(QPixmap(resource_dir + "pic/ansi_color.png"), tr("Color"),
+ this, SLOT(setColor()));
+ menu_->addSeparator();
+ menu_->addAction(QPixmap(resource_dir + "pic/preferences.png"), tr("Setting"),
+ this, SLOT(setting()));
+ menu_->addSeparator();
+ menu_->addAction(tr("Open Selected As Url"), this, SLOT(openAsUrl()));
+ menu_->addAction(tr("Search Selected Text!"), this, SLOT(searchIt()));
+ menu_->addAction(tr("Share Selected Text and URL!"), this, SLOT(shareIt()));
+}
+
+void FQTermWindow::recreateMenu() {
+ delete urlMenu_;
+ delete menu_;
+ addMenu();
+}
+
+//close event received
+void FQTermWindow::closeEvent(QCloseEvent *clse) {
+ bool toClose = true;
+ if (isConnected() && FQTermPref::getInstance()->openWarnOnClose_) {
+ QMessageBox mb(tr("FQTerm"),
+ tr("Still connected, do you really want to exit?"),
+ QMessageBox::Warning, QMessageBox::Yes|QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (mb.exec() != QMessageBox::Yes) {
+ toClose = false;
+ }
+ }
+ if (toClose) {
+ session_->close();
+ } else {
+ clse->ignore();
+ return;
+ }
+ //We no longer save setting on close from r1036.
+ //saveSetting();
+}
+
+void FQTermWindow::blinkTab() {
+ emit blinkTheTab(this, blinkStatus_);
+ blinkStatus_ = !blinkStatus_;
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Mouse & Key */
+/* */
+/* ------------------------------------------------------------------------ */
+void FQTermWindow::enterEvent(QEvent*){}
+
+void FQTermWindow::leaveEvent(QEvent*) {
+ // TODO: code below doesn't work
+ // QPoint temp(0, 0);
+ // session_->setSelect(temp, temp, session_->isRectangleCopy_);
+ // QApplication::postEvent(screen_, new QPaintEvent(QRect(0, 0, 0, 0));
+ // &paintEvent);
+}
+
+void FQTermWindow::changeEvent(QEvent *e) {
+ if (e->type() == QEvent::WindowStateChange) {
+ QWindowStateChangeEvent *event = (QWindowStateChangeEvent*)(e);
+ Qt::WindowStates oldState = event->oldState();
+ if (!isMaximized()) {
+ emit refreshOthers(this);
+ }
+ if ( (oldState & Qt::WindowMinimized && !isMinimized()) ||
+ (!(oldState & Qt::WindowActive) && isActiveWindow())) {
+ forcedRepaintScreen();
+ }
+ if (oldState & Qt::WindowMaximized || isMaximized()) {
+ emit resizeSignal(this);
+ }
+ }
+}
+
+void FQTermWindow::resizeEvent(QResizeEvent *qResizeEvent)
+{
+ emit resizeSignal(this);
+}
+
+bool FQTermWindow::event(QEvent *qevent) {
+ bool res = false;
+ QKeyEvent *keyEvent;
+ switch(qevent->type()) {
+#ifdef __linux__
+ case QEvent::ShortcutOverride:
+ keyEvent = (QKeyEvent *)(qevent);
+ if(keyEvent->key() == Qt::Key_W &&
+ keyEvent->modifiers() == Qt::ControlModifier) {
+ keyEvent->accept();
+ res = true;
+ }
+ break;
+#endif
+ case QEvent::KeyPress:
+ keyEvent = (QKeyEvent *)(qevent);
+ if (keyEvent->key() == Qt::Key_Tab ||
+ keyEvent->key() == Qt::Key_Backtab) {
+ // Key_Tab and Key_Backtab are special, if we don't process them here,
+ // the default behavoir is to move focus. see QWidget::event.
+ keyPressEvent(keyEvent);
+ keyEvent->accept();
+ res = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ res = res || QMainWindow::event(qevent);
+
+ if (qevent->type() == QEvent::HoverMove
+ || qevent->type() == QEvent::MouseMove
+ || qevent->type() == QEvent::Move) {
+ if (res) {
+ FQ_TRACE("wndEvent", 10) << "Accept event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ } else {
+ FQ_TRACE("wndEvent", 10) << "Ignore event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ }
+ } else {
+ if (res) {
+ FQ_TRACE("wndEvent", 9) << "Accept event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ } else {
+ FQ_TRACE("wndEvent", 9) << "Ignore event: " << qevent->type()
+ << " " << getEventName(qevent->type()) << ".";
+ }
+ }
+ return res;
+}
+
+void FQTermWindow::mouseDoubleClickEvent(QMouseEvent *mouseevent) {
+ if (scriptMouseEvent(mouseevent))
+ return;
+}
+
+void FQTermWindow::mousePressEvent(QMouseEvent *mouseevent) {
+ if (scriptMouseEvent(mouseevent))
+ return;
+ // stop the tab blinking
+ stopBlink();
+
+ // Left Button for selecting
+ if (mouseevent->button() & Qt::LeftButton && !(mouseevent->modifiers())) {
+ startSelecting(mouseevent->pos());
+ }
+
+ // Right Button
+ if ((mouseevent->button() & Qt::RightButton)) {
+ if (mouseevent->modifiers() & Qt::ControlModifier) {
+ // on Url
+ if (!session_->getUrl().isEmpty()) {
+ previewLink();
+ }
+ return ;
+ }
+
+#ifdef __APPLE__
+ bool additional_modifier = (mouseevent->modifiers() & !Qt::MetaModifier);
+#else
+ bool additional_modifier = mouseevent->modifiers();
+#endif
+
+ if (!(additional_modifier)) {
+ // on Url
+ if (!session_->getUrl().isEmpty()) {
+ urlMenu_->popup(mouseevent->globalPos());
+ } else {
+ menu_->popup(mouseevent->globalPos());
+ }
+ return ;
+ }
+ }
+ // Middle Button for paste
+ if (mouseevent->button() &Qt::MidButton && !(mouseevent->modifiers())) {
+ if (isConnected())
+ // on Url
+ if (!session_->getUrl().isEmpty()) {
+ previewLink();
+ } else {
+ pasteHelper(false);
+ }
+ return ;
+ }
+
+ // If it is a click, there should be a press event and a release event.
+ isMouseClicked_ = true;
+
+ // xterm mouse event
+ //session_->sendMouseState(0, me->button(), me->state(), me->pos());
+}
+
+
+void FQTermWindow::mouseMoveEvent(QMouseEvent *mouseevent) {
+ bool mouseEventConsumed = scriptMouseEvent(mouseevent);
+ QPoint position = mouseevent->pos();
+ if (!mouseEventConsumed)
+ {
+
+ // selecting by leftbutton
+ if ((mouseevent->buttons() &Qt::LeftButton) && isSelecting_) {
+ onSelecting(position);
+ }
+ }
+ if (!(session_->param().isSupportMouse_ && isConnected())) {
+ return;
+ }
+
+ setCursorPosition(position);
+ setCursorType(position);
+
+
+ if (!mouseEventConsumed)
+ {
+ if (!isUrlUnderLined_ && session_->urlStartPoint() != session_->urlEndPoint()) {
+ isUrlUnderLined_ = true;
+ urlStartPoint_ = session_->urlStartPoint();
+ urlEndPoint_ = session_->urlEndPoint();
+ clientRect_ = QRect(QPoint(0, urlStartPoint_.y()), QSize(session_->getBuffer()->getNumColumns(), urlEndPoint_.y() - urlStartPoint_.y() + 1));
+ repaintScreen();
+
+ } else if (isUrlUnderLined_ && (session_->urlStartPoint() != urlStartPoint_ || session_->urlEndPoint() != urlEndPoint_)) {
+ clientRect_ = QRect(QPoint(0, urlStartPoint_.y()), QSize(session_->getBuffer()->getNumColumns(), urlEndPoint_.y() - urlStartPoint_.y() + 1));
+ urlStartPoint_ = QPoint();
+ urlEndPoint_ = QPoint();
+ repaintScreen();
+ isUrlUnderLined_ = false;
+
+ }
+ }
+}
+
+static bool isSupportedImage(const QString &name) {
+ static QList<QByteArray> image_formats =
+ QImageReader::supportedImageFormats();
+
+ return image_formats.contains(name.section(".", -1).toLower().toUtf8());
+}
+
+void FQTermWindow::mouseReleaseEvent(QMouseEvent *mouseevent) {
+ if (scriptMouseEvent(mouseevent))
+ return;
+ if (!isMouseClicked_) {
+ return ;
+ }
+ isMouseClicked_ = false;
+ // other than Left Button ignored
+ if (!(mouseevent->button() & Qt::LeftButton) ||
+ (mouseevent->modifiers() & Qt::KeyboardModifierMask)) {
+ // no local mouse event
+ //session_->sendMouseState(3, me->button(), me->state(), me->pos());
+ return ;
+ }
+
+ // Left Button for selecting
+ QPoint currentMouseCell = screen_->mapToChar(mouseevent->pos());
+ if (currentMouseCell != lastMouseCell_ && isSelecting_) {
+ finishSelecting(mouseevent->pos());
+ return ;
+ }
+ isSelecting_ = false;
+
+ if (!session_->param().isSupportMouse_ || !isConnected()) {
+ return ;
+ }
+
+ // url
+ QString url = session_->getUrl();
+ if (!url.isEmpty()) {
+ if (isSupportedImage(url)) {
+ previewLink();
+ } else {
+ openUrl(url);
+ }
+ return ;
+ }
+
+ processLClick(currentMouseCell);
+}
+
+void FQTermWindow::wheelEvent(QWheelEvent *wheelevent) {
+ if (scriptWheelEvent(wheelevent)) return;
+ int j = wheelevent->delta() > 0 ? 4 : 5;
+ if (!(wheelevent->modifiers())) {
+ if (FQTermPref::getInstance()->isWheelSupported_ && isConnected()) {
+ session_->writeStr(directions_[j]);
+ }
+ return ;
+ }
+ //session_->sendMouseState(j, Qt::NoButton, we->state(), we->pos());
+}
+
+//keyboard input event
+void FQTermWindow::keyPressEvent(QKeyEvent *keyevent) {
+ if (keyevent->isAutoRepeat() && !session_->getBuffer()->isAutoRepeatMode()) {
+ FQ_TRACE("sendkey", 5)
+ << "The terminal is set to not allow repeated key events.";
+ keyevent->accept();
+ return;
+ }
+ if (scriptKeyEvent(keyevent))
+ return;
+
+ keyevent->accept();
+
+ if (!isConnected()) {
+ if (keyevent->key() == Qt::Key_Return || keyevent->key() == Qt::Key_Enter) {
+ session_->reconnect();
+ }
+ return ;
+ }
+
+ // stop the tab blinking
+ stopBlink();
+ if (!session_->readyForInput()) {
+ return;
+ }
+ // message replying
+ session_->leaveIdle();
+
+ Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers();
+ int key = keyevent->key();
+ sendKey(key, modifier, keyevent->text());
+}
+/*
+void FQTermWindow::focusInEvent (QFocusEvent *event) {
+ QMainWindow::focusInEvent(event);
+ screen_->setFocus(Qt::OtherFocusReason);
+}
+*/
+
+//connect slot
+void FQTermWindow::connectHost() {
+ pageViewMessage_->display(tr("Not connected"), screen_->mapToPixel(QPoint(1, 1)));
+ session_->setProxy(session_->param().proxyType_,
+ session_->param().isAuthentation_,
+ session_->param().proxyHostName_,
+ session_->param().proxyPort_,
+ session_->param().proxyUserName_,
+ session_->param().proxyPassword_);
+ session_->connectHost(session_->param().hostAddress_, session_->param().port_);
+ config_->setItemValue("global", "lastaddrindex", QString("%1").arg(addressIndex_));
+}
+
+bool FQTermWindow::isConnected() {
+ return session_->isConnected();
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Telnet State */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermWindow::sessionUpdated() {
+ refreshScreen();
+ //send a mouse move event to make mouse-related change
+ QMouseEvent* me = new QMouseEvent(
+ QEvent::MouseMove, mapFromGlobal(QCursor::pos()),
+ QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QApplication::postEvent(this, me);
+}
+
+void FQTermWindow::requestUserPwd(QString *user, QString *pwd, bool *isOK) {
+ SSHLoginDialog login(user, pwd, this);
+ *isOK = (login.exec() == QDialog::Accepted);
+}
+
+void FQTermWindow::ZmodemState(int type, int value, const char *status) {
+ QString strMsg;
+ //to be completed
+ switch (type) {
+ case RcvByteCount:
+ case SndByteCount:
+ zmodemDialog_->setProgress(value);
+ return;
+ case RcvTimeout:
+ /* receiver did not respond, aborting */
+ strMsg = QString(tr("Time out!"));
+ break;
+ case SndTimeout:
+ /* value is # of consecutive send timeouts */
+ strMsg = QString(tr("Time out after trying %1 times")).arg(value);
+ break;
+ case RmtCancel:
+ /* remote end has cancelled */
+ strMsg = QString(tr("Canceled by remote peer %1")).arg(status);
+ break;
+ case ProtocolErr:
+ /* protocol error has occurred, val=hdr */
+ strMsg = QString(
+ tr("Unhandled header %1 at state %2")).arg(value).arg(status);
+ break;
+ case RemoteMessage:
+ /* message from remote end */
+ strMsg = QString(tr("Msg from remote peer: %1")).arg(status);
+ break;
+ case DataErr:
+ /* data error, val=error count */
+ strMsg = QString(tr("Data errors %1")).arg(value);
+ break;
+ case FileErr:
+ /* error writing file, val=errno */
+ strMsg = QString(tr("Falied to write file"));
+ break;
+ case FileBegin:
+ /* file transfer begins, str=name */
+ FQ_TRACE("window", 1) << "Starting file " << status;
+ zmodemDialog_->setFileInfo(session_->bbs2unicode(status), value);
+ zmodemDialog_->setProgress(0);
+ zmodemDialog_->clearErrorLog();
+ zmodemDialog_->show();
+ zmodemDialog_->setModal(true);
+ return;
+ case FileEnd:
+ /* file transfer ends, str=name */
+ zmodemDialog_->hide();
+ return;
+ case FileSkip:
+ /* file being skipped, str=name */
+ strMsg = QString(tr("Skipping file %1")).arg(status);
+ break;
+ }
+ zmodemDialog_->addErrorLog(strMsg);
+}
+
+// telnet state slot
+void FQTermWindow::TelnetState(int state) {
+ switch (state) {
+ case TSRESOLVING:
+ pageViewMessage_->display(tr("Resolving host name"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSHOSTFOUND:
+ pageViewMessage_->display(tr("Host found"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSHOSTNOTFOUND:
+ pageViewMessage_->display(tr("Host not found"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSCONNECTING:
+ pageViewMessage_->display(tr("Connecting..."), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSHOSTCONNECTED:
+ pageViewMessage_->display(tr("Connected"), screen_->mapToPixel(QPoint(1, 1)));
+ frame_->updateMenuToolBar();
+ break;
+ case TSPROXYCONNECTED:
+ pageViewMessage_->display(tr("Connected to proxy"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSPROXYAUTH:
+ pageViewMessage_->display(tr("Proxy authentation"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSPROXYFAIL:
+ pageViewMessage_->display(tr("Proxy failed"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSREFUSED:
+ pageViewMessage_->display(tr("Connection refused"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSREADERROR:
+ pageViewMessage_->display(tr("Error when reading from server"), screen_->mapToPixel(QPoint(1, 1)),
+ PageViewMessage::Error);
+ break;
+ case TSCLOSED:
+ pageViewMessage_->display(tr("Connection closed"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSCLOSEFINISH:
+ pageViewMessage_->display(tr("Connection close finished"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSCONNECTVIAPROXY:
+ pageViewMessage_->display(tr("Connect to host via proxy"), screen_->mapToPixel(QPoint(1, 1)));
+ break;
+ case TSEGETHOSTBYNAME:
+ pageViewMessage_->display(
+ tr("Error in gethostbyname"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSEINIWINSOCK:
+ pageViewMessage_->display(
+ tr("Error in startup winsock"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSERROR:
+ pageViewMessage_->display(
+ tr("Error in connection"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSPROXYERROR:
+ pageViewMessage_->display(tr("Error in proxy"), screen_->mapToPixel(QPoint(1, 1)), PageViewMessage::Error);
+ break;
+ case TSWRITED:
+ break;
+ }
+}
+
+void FQTermWindow::showSessionErrorMessage(QString reason) {
+ if (reason == tr("User Cancel")) {
+ return;
+ }
+ QMessageBox::critical(this, tr("Session error"), reason);
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* UI Slots */
+/* */
+/* ------------------------------------------------------------------------ */
+
+
+void FQTermWindow::copy() {
+ QClipboard *clipboard = QApplication::clipboard();
+
+ QString selected_text = session_->getBuffer()->getTextSelected(
+ session_->param().isRectSelect_,
+ session_->param().isColorCopy_,
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+
+ QByteArray cstrText = session_->unicode2bbs(selected_text);
+
+ // TODO_UTF16: avoid this replacement.
+ if (!FQTermPref::getInstance()->escapeString_.isEmpty()) {
+ cstrText.replace(
+ parseString((const char*)session_->param().escapeString_.toLatin1()),
+ parseString(FQTermPref::getInstance()->escapeString_.toLatin1()));
+ }
+ selected_text = session_->bbs2unicode(cstrText);
+
+ // TODO_UTF16: there are three modes: Clipboard, Selection, FindBuffer.
+ clipboard->setText(selected_text, QClipboard::Clipboard);
+ clipboard->setText(selected_text, QClipboard::Selection);
+}
+
+void FQTermWindow::paste() {
+ pasteHelper(true);
+}
+
+void FQTermWindow::writePasting(const QString& content)
+{
+ QByteArray cstrText = session_->unicode2bbs(content);
+
+ // TODO_UTF16: avoid this replacement.
+ if (!FQTermPref::getInstance()->escapeString_.isEmpty()) {
+ cstrText.replace(
+ parseString(FQTermPref::getInstance()->escapeString_.toLatin1()),
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+ }
+
+ if (session_->param().isAutoWrap_) {
+ // convert to unicode for word wrap
+ QString strText;
+ strText = session_->bbs2unicode(cstrText);
+ // insert '\n' as needed
+ for (uint i = 0; (long)i < strText.length(); i++) {
+ uint j = i;
+ uint k = 0, l = 0;
+ while ((long)j < strText.length() && strText.at(j) != QChar('\n')) {
+ if (FQTermPref::getInstance()->widthToWrapWord_ - (l - k) >= 0
+ && FQTermPref::getInstance()->widthToWrapWord_ - (l - k) < 2) {
+ strText.insert(j, QChar('\n'));
+ k = l;
+ j++;
+ break;
+ }
+ // double byte or not
+ if (strText.at(j).row() == '\0') {
+ l++;
+ } else {
+ l += 2;
+ }
+ j++;
+ }
+ i = j;
+ }
+
+ cstrText = session_->unicode2bbs(strText);
+ }
+
+ session_->write(cstrText, cstrText.length());
+}
+
+void FQTermWindow::pasteHelper(bool clip) {
+ if (!isConnected()) {
+ return ;
+ }
+
+ // TODO_UTF16: there are three modes: Clipboard, Selection, FindBuffer.
+ QClipboard *clipboard = QApplication::clipboard();
+
+ // TODO_UTF16: what's the termFrame_->clipboardEncodingID_?
+ /*
+ if (termFrame_->clipboardEncodingID_ == 0) {
+ if (clip) {
+ cstrText = U2G(clipboard->text(QClipboard::Clipboard));
+ }
+ else {
+ cstrText = U2G(clipboard->text(QClipboard::Selection));
+ }
+
+ if (session_->param().serverEncodingID_ == 1) {
+ char *str = encodingConverter_.G2B(cstrText, cstrText.length());
+ cstrText = str;
+ delete [] str;
+ }
+ } else {
+ if (clip) {
+ cstrText = U2B(clipboard->text(QClipboard::Clipboard));
+ } else {
+ cstrText = U2B(clipboard->text(QClipboard::Selection));
+ }
+
+ if (session_->param().serverEncodingID_ == 0) {
+ char *str = encodingConverter_.B2G(cstrText, cstrText.length());
+ cstrText = str;
+ delete [] str;
+ }
+ }
+ */
+
+ QString clipStr;
+
+ if (clip) {
+ clipStr = clipboard->text(QClipboard::Clipboard);
+ } else {
+ clipStr = clipboard->text(QClipboard::Selection);
+ }
+
+ writePasting(clipStr);
+}
+
+void FQTermWindow::openAsUrl() {
+ QString selected_text = session_->getBuffer()->getTextSelected(
+ session_->param().isRectSelect_,
+ session_->param().isColorCopy_,
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+ openUrl(selected_text);
+}
+
+void FQTermWindow::searchIt()
+{
+ script_engine_->runScript(getPath(RESOURCE) + "script/search.js");
+ QScriptValueList qvl;
+ qvl << FQTermPref::getInstance()->searchEngine_;
+ if (!script_engine_->scriptCallback("searchSelected", qvl)) {
+ //fall back to google.
+ QString selected_text = session_->getBuffer()->getTextSelected(
+ session_->param().isRectSelect_,
+ session_->param().isColorCopy_,
+ parseString((const char*)session_->param().escapeString_.toLatin1()));
+ QString searchUrl = "http://www.google.com/search?client=fqterm&rls=en&q=" + selected_text + "&sourceid=fqterm";
+ QByteArray url = QUrl(searchUrl).toEncoded();
+ openUrlImpl(url);
+ }
+}
+
+void FQTermWindow::shareIt()
+{
+ script_engine_->runScript(getPath(RESOURCE) + "script/weiboshare.js");
+}
+
+void FQTermWindow::fastPost()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ QString clipStr = clipboard->text(QClipboard::Clipboard);
+ QString lineEnd("\n");
+ QString postTitle = clipStr.left(clipStr.indexOf(lineEnd));
+
+ sendParsedString("^p");
+ writeRawString(postTitle);
+ writeRawString(QString("\n\n"));
+ writePasting(clipStr);
+ sendParsedString("^W\n");
+}
+
+
+void FQTermWindow::externalEditor() {
+ externalEditor_->start();
+}
+
+
+void FQTermWindow::externalEditorDone(const QString& str) {
+ QByteArray rawStr = session_->unicode2bbs_smart(str);
+ session_->write(rawStr, rawStr.length());
+}
+
+
+void FQTermWindow::copyArticle() {
+ if (!isConnected()) {
+ return ;
+ }
+
+ session_->copyArticle();
+}
+
+void FQTermWindow::setColor() {
+ addrDialog set(this, session_->param());
+
+ set.setCurrentTabIndex(addrDialog::Display);
+ int res = set.exec();
+ if (res != 0) {
+ updateSetting(set.param());
+ if (res == 2)
+ saveSetting(false);
+ }
+
+}
+
+void FQTermWindow::disconnect() {
+ session_->close();
+
+ connectionClosed();
+}
+
+void FQTermWindow::showIP(bool show) {
+ pageViewMessage_->hide();
+ if (!show) {
+ return;
+ }
+ QString country, city;
+ QString url = session_->getIP();
+ FQTermIPLocation *ipLocation = FQTermIPLocation::getInstance();
+
+ QRect screenRect = screen_->rect();
+ QPoint messagePos;
+ QRect globalIPRectangle = QRect(screen_->mapToRect(ipRectangle_));
+ QFontMetrics fm(qApp->font());
+ int charHeight = fm.height();
+
+ int midLine = (screenRect.top() + screenRect.bottom()) / 2;
+ int ipMidLine = (globalIPRectangle.top() + globalIPRectangle.bottom()) / 2;
+ if (ipMidLine < midLine) {
+ // "There is Plenty of Room at the Bottom." -- Feyman, 1959
+ messagePos.setY(globalIPRectangle.bottom() + 0.618 * charHeight);
+ } else {
+ messagePos.setY(globalIPRectangle.top()
+ - 0.618 * charHeight
+ - pageViewMessage_->size().height());
+ }
+
+ QString displayText;
+ if (ipLocation == NULL) {
+ displayText = tr("IP database file does NOT exist");
+ } else if (!ipLocation->getLocation(url, country, city)) {
+ displayText = tr("Invalid IP");
+ } else {
+ displayText = country + " " + city;
+ }
+
+ QRect messageSize(pageViewMessage_->displayCheck(displayText,
+ PageViewMessage::Info));
+ PageViewMessage::Alignment ali;
+ if (messageSize.width() + globalIPRectangle.left() >= screenRect.right()) {
+ //"But There is No Room at the Right" -- Curvelet, 2007
+ messagePos.setX(globalIPRectangle.right());
+ ali = PageViewMessage::TopRight;
+ } else {
+ messagePos.setX(globalIPRectangle.left());
+ ali = PageViewMessage::TopLeft;
+ }
+
+ pageViewMessage_->display(
+ displayText,
+ PageViewMessage::Info,
+ 0, messagePos, ali);
+}
+
+void FQTermWindow::runScript() {
+ // get the previous dir
+ QStringList fileList;
+ FQTermFileDialog fileDialog(config_);
+
+ fileList = fileDialog.getOpenNames("Choose a Javascript file", "JavaScript File (*.js)");
+
+ if (!fileList.isEmpty() && fileList.count() == 1) {
+ runScript(fileList.at(0));
+ }
+}
+
+void FQTermWindow::stopScript() {
+ script_engine_->stopScript();
+}
+
+void FQTermWindow::viewMessages() {
+ msgDialog msg(this);
+
+ QByteArray dlgSize =
+// frame_->config()->getItemValue("global", "msgdialog").toLatin1();
+ config_->getItemValue("global", "msgdialog").toLatin1();
+ const char *dsize = dlgSize.constData();
+ if (!dlgSize.isEmpty()) {
+ int x, y, cx, cy;
+ sscanf(dsize, "%d %d %d %d", &x, &y, &cx, &cy);
+ msg.resize(QSize(cx, cy));
+ msg.move(QPoint(x, y));
+ } else {
+ msg.resize(QSize(300, 500));
+ msg.move(QPoint(20,20));
+ }
+
+ msg.setMessageText(allMessages_);
+ msg.exec();
+
+ QString strSize = QString("%1 %2 %3 %4").arg(msg.x()).arg(msg.y()).arg
+ (msg.width()).arg(msg.height());
+// frame_->config()->setItemValue("global", "msgdialog", strSize);
+ config_->setItemValue("global", "msgdialog", strSize);
+}
+
+void FQTermWindow::setting() {
+ addrDialog set(this, session_->param());
+ int res = set.exec();
+ if (res != 0) {
+ updateSetting(set.param());
+ if (res == 2)
+ saveSetting(false);
+ }
+}
+
+void FQTermWindow::toggleAntiIdle() {
+ session_->setAntiIdle(!session_->isAntiIdle());
+}
+
+void FQTermWindow::toggleAutoReply() {
+ session_->setAutoReply(!session_->isAutoReply());
+}
+
+void FQTermWindow::toggleAutoReconnect() {
+ session_->setAutoReconnect(!session_->param().isAutoReconnect_);
+}
+
+void FQTermWindow::connectionClosed() {
+ stopBlink();
+
+ pageViewMessage_->display(tr("Connection closed"), screen_->mapToPixel(QPoint(1, 1)));
+
+ frame_->updateMenuToolBar();
+
+ setCursor(cursors_[FQTermSession::kNormal]);
+
+ refreshScreen();
+
+ if (!getSession()->param().isAutoReconnect_ && getSession()->param().isAutoCloseWin_) {
+ emit(connectionClosed(this));
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Events */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermWindow::articleCopied(int e, const QString content) {
+ if (e == DAE_FINISH) {
+// articleDialog article(frame_->config(), this);
+ articleDialog article(config_, this);
+
+ // Fix focus-losing bug.
+ // dsize should be a pointer to a non-temprary object.
+ QByteArray dlgSize =
+// frame_->config()->getItemValue("global", "articledialog").toLatin1();
+ config_->getItemValue("global", "articledialog").toLatin1();
+
+ const char *dsize = dlgSize.constData();
+
+ if (!dlgSize.isEmpty()) {
+ int x, y, cx, cy;
+ sscanf(dsize, "%d %d %d %d", &x, &y, &cx, &cy);
+ article.resize(QSize(cx, cy));
+ article.move(QPoint(x, y));
+ } else {
+ article.resize(QSize(300, 500));
+ article.move(20,20);
+ }
+ article.articleText_ = content;
+
+ article.ui_.textBrowser->setPlainText(article.articleText_);
+ article.exec();
+ QString strSize = QString("%1 %2 %3 %4").arg(article.x()).arg(article.y())
+ .arg(article.width()).arg(article.height());
+// frame_->config()->setItemValue("global", "articledialog", strSize);
+ config_->setItemValue("global", "articledialog", strSize);
+ } else if (e == DAE_TIMEOUT) {
+ QMessageBox::warning(this, "timeout", "download article timeout, aborted");
+#ifdef HAVE_PYTHON
+ } else if (e == PYE_ERROR) {
+ QMessageBox::warning(this, "Python script error", pythonErrorMessage_);
+ } else if (e == PYE_FINISH) {
+ QMessageBox::information(this, "Python script finished",
+ "Python script file executed successfully");
+#endif //HAVE_PYTHON
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Aux Func */
+/* */
+/* ------------------------------------------------------------------------ */
+
+QByteArray FQTermWindow::parseString(const QByteArray &cstr, int *len) {
+ QByteArray parsed = "";
+
+ if (len != 0) {
+ *len = 0;
+ }
+
+ for (uint i = 0; (long)i < cstr.length(); i++) {
+ if (cstr.at(i) == '^') {
+ i++;
+ if ((long)i < cstr.length()) {
+ parsed += FQTERM_CTRL(cstr.at(i));
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else if (cstr.at(i) == '\\') {
+ i++;
+ if ((long)i < cstr.length()) {
+ if (cstr.at(i) == 'n') {
+ parsed += CHAR_CR;
+ } else if (cstr.at(i) == 'r') {
+ parsed += CHAR_LF;
+ } else if (cstr.at(i) == 't') {
+ parsed += CHAR_TAB;
+ }
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else {
+ parsed += cstr.at(i);
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ }
+
+ return parsed;
+}
+
+void FQTermWindow::messageAutoReplied() {
+ pageViewMessage_->display("You have messages", PageViewMessage::Info, 0);
+}
+
+void FQTermWindow::saveSetting(bool ask /* = true*/) {
+ if (addressIndex_ == -1) {
+ return ;
+ }
+
+ //save these options silently
+ FQTermConfig pConf(getPath(USER_CONFIG) + "address.cfg");
+ FQTermParam param;
+ loadAddress(&pConf, addressIndex_, param);
+ param.isAutoCopy_ = session_->param().isAutoCopy_;
+ param.isAutoWrap_ = session_->param().isAutoWrap_;
+ param.isRectSelect_ = session_->param().isRectSelect_;
+ param.isColorCopy_ = session_->param().isColorCopy_;
+ saveAddress(&pConf, addressIndex_, param);
+ pConf.save(getPath(USER_CONFIG) + "address.cfg");
+
+ if (param == session_->param()) {
+ return;
+ }
+
+ QMessageBox mb("FQTerm", "Setting changed do you want to save it?",
+ QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (!ask || mb.exec() == QMessageBox::Yes) {
+ saveAddress(&pConf, addressIndex_, session_->param());
+ pConf.save(getPath(USER_CONFIG) + "address.cfg");
+ }
+}
+
+int FQTermWindow::externInput(const QByteArray &cstrText) {
+ QByteArray cstrParsed = parseString(cstrText);
+ return session_->write(cstrParsed, cstrParsed.length());
+}
+
+int FQTermWindow::externInput(const QString &cstrText) {
+ return externInput(session_->unicode2bbs_smart(cstrText));
+}
+
+int FQTermWindow::writeRawString(const QString& str) {
+ QByteArray rawStr = session_->unicode2bbs_smart(str);
+ return session_->write(rawStr, rawStr.length());
+}
+
+void FQTermWindow::sendParsedString(const char *str) {
+ int length;
+ QByteArray cstr = parseString(str, &length);
+ session_->write(cstr, length);
+}
+
+
+bool FQTermWindow::postQtScriptCallback(const QString& func, const QScriptValueList & args) {
+ return script_engine_->scriptCallback(func, args);
+}
+
+#ifdef HAVE_PYTHON
+bool FQTermWindow::postPythonCallback( const QString& func, PyObject* pArgs )
+{
+ return pythonCallback(func, pArgs);
+}
+#endif //HAVE_PYTHON
+
+// void FQTermWindow::setMouseMode(bool on) {
+// isMouseX11_ = on;
+// }
+
+// /* 0-left 1-middle 2-right 3-relsase 4/5-wheel
+// *
+// */
+// //void FQTermWindow::sendMouseState( int num,
+// // Qt::ButtonState btnstate, Qt::ButtonState keystate, const QPoint& pt )
+// void FQTermWindow::sendMouseState(int num, Qt::KeyboardModifier btnstate,
+// Qt::KeyboardModifier keystate, const QPoint &pt) {
+// /*
+// if(!m_bMouseX11)
+// return;
+//
+// QPoint ptc = screen_->mapToChar(pt);
+//
+// if(btnstate&Qt::LeftButton)
+// num = num==0?0:num;
+// else if(btnstate&Qt::MidButton)
+// num = num==0?1:num;
+// else if(btnstate&Qt::RightButton)
+// num = num==0?2:num;
+//
+// int state = 0;
+// if(keystate&Qt::ShiftModifier)
+// state |= 0x04;
+// if(keystate&Qt::MetaModifier)
+// state |= 0x08;
+// if(keystate&Qt::ControlModifier)
+// state |= 0x10;
+//
+// // normal buttons are passed as 0x20 + button,
+// // mouse wheel (buttons 4,5) as 0x5c + button
+// if(num>3) num += 0x3c;
+//
+// char mouse[10];
+// sprintf(mouse, "\033[M%c%c%c",
+// num+state+0x20,
+// ptc.x()+1+0x20,
+// ptc.y()+1+0x20);
+// m_pTelnet->write( mouse, strlen(mouse) );
+// */
+// }
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* Python Func */
+/* */
+/* ------------------------------------------------------------------------ */
+#ifdef HAVE_PYTHON
+
+
+void FQTermWindow::runPythonScript() {
+ QStringList fileList;
+ FQTermFileDialog fileDialog(config_);
+
+ fileList = fileDialog.getOpenNames("Choose a Python file", "Python File (*.py)");
+
+ if (!fileList.isEmpty() && fileList.count() == 1) {
+ runPythonScriptFile(fileList.at(0));
+ }
+}
+
+void FQTermWindow::runPythonScriptFile(const QString& file) {
+ QString str(QString("%1").arg(long(this)));
+ char* lp = fq_strdup(str.toUtf8().data());
+ char *argv[2]={lp,NULL};
+ // get the global python thread lock
+ PyEval_AcquireLock();
+
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+
+ PySys_SetArgv(1, argv);
+
+ runPythonFile(file);
+
+ //Clean up this thread's python interpreter reference
+ PyThreadState_Swap(NULL);
+ PyThreadState_Clear(myThreadState);
+ PyThreadState_Delete(myThreadState);
+ PyEval_ReleaseLock();
+ free((void*)lp);
+}
+
+bool FQTermWindow::pythonCallback(const QString & func, PyObject* pArgs) {
+ if(!pythonScriptLoaded_) {
+ Py_DECREF(pArgs);
+ return false;
+ };
+
+ bool done = false;
+ // get the global lock
+ PyEval_AcquireLock();
+ // get a reference to the PyInterpreterState
+
+ //Python thread references
+
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+ PyObject *pF = PyString_FromString(func.toUtf8());
+ PyObject *pFunc = PyDict_GetItem(pDict, pF);
+ Py_DECREF(pF);
+
+ if (pFunc && PyCallable_Check(pFunc))
+ {
+ PyObject *pValue = PyObject_CallObject(pFunc, pArgs);
+ Py_DECREF(pArgs);
+ if (pValue != NULL)
+ {
+ if (PyBool_Check(pValue) && pValue == Py_True)
+ done = true;
+ Py_DECREF(pValue);
+ }
+ else
+ {
+ //QMessageBox::warning(this,"Python script error", getException());
+ printf("%p: Python script error\n", this, getException().toUtf8().data());
+ }
+ }
+ else
+ {
+ PyErr_Print();
+ printf("Cannot find python %s callback function\n", func.toUtf8().data());
+ }
+
+ // swap my thread state out of the interpreter
+ PyThreadState_Swap(NULL);
+ // clear out any cruft from thread state object
+ PyThreadState_Clear(myThreadState);
+ // delete my thread state object
+ PyThreadState_Delete(myThreadState);
+ // release the lock
+ PyEval_ReleaseLock();
+
+ if (func == "autoReply")
+ startBlink();
+
+ return done;
+}
+
+
+int FQTermWindow::runPythonFile( const QString& file )
+{
+ QString buffer("def work_thread():\n"
+ "\ttry:\n\t\texecfile('");
+ buffer += QString(file).replace("\\", "\\\\");
+
+ /* Have to do it like this. PyRun_SimpleFile requires you to pass a
+ * stdio file pointer, but Vim and the Python DLL are compiled with
+ * different options under Windows, meaning that stdio pointers aren't
+ * compatible between the two. Yuk.
+ *
+ * Put the string "execfile('file')" into buffer. But, we need to
+ * escape any backslashes or single quotes in the file name, so that
+ * Python won't mangle the file name.
+ * ---- kafa
+ */
+
+ /* Put in the terminating "')" and a null */
+ buffer += "',{})\n\0";
+
+ buffer += QString("\texcept:\n"
+ "\t\texc, val, tb = sys.exc_info()\n"
+ "\t\tlines = traceback.format_exception(exc, val, tb)\n"
+ "\t\terr = string.join(lines)\n"
+ "\t\tprint err\n"
+ "\t\tf=open('%1','w')\n"
+ "\t\tf.write(err)\n"
+ "\t\tf.close()\n").arg(getErrOutputFile(this));
+
+ buffer += QString("\t\tfqterm.formatError(%1)\n").arg((long)this);
+ buffer += "\t\texit\n";
+
+ /* Execute the file */
+ PyRun_SimpleString("import thread,string,sys,traceback,fqterm");
+ PyRun_SimpleString(buffer.toUtf8());
+ PyRun_SimpleString( "thread.start_new_thread(work_thread,())\n");
+
+ return 0;
+}
+
+void FQTermWindow::initPython(const QString& file) {
+
+ // get the global python thread lock
+ PyEval_AcquireLock();
+
+ // get a reference to the PyInterpreterState
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+
+
+
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+ Py_InitModule4("fqterm", fqterm_methods,
+ NULL,(PyObject*)NULL,PYTHON_API_VERSION);
+
+ PyImport_AddModule("fqterm");
+
+ if(!file.isEmpty() )
+ {
+ QFileInfo info(file);
+ PyRun_SimpleString("import sys");
+ PyRun_SimpleString(QString("sys.path.append(\"%1/\")").arg(info.absolutePath()).toUtf8().data());
+ PyObject *pName = PyString_FromString(info.baseName().toUtf8().data());
+ pModule = PyImport_Import(pName);
+ //PyErr_Print();
+ Py_DECREF(pName);
+ if (pModule != NULL)
+ pDict = PyModule_GetDict(pModule);
+ else
+ {
+ //printf("Failed to PyImport_Import\n");
+ }
+
+ if(pDict != NULL )
+ pythonScriptLoaded_ = true;
+ else
+ {
+ //printf("Failed to PyModule_GetDict\n");
+ }
+ }
+
+ //Clean up this thread's python interpreter reference
+ PyThreadState_Swap(NULL);
+ PyThreadState_Clear(myThreadState);
+ PyThreadState_Delete(myThreadState);
+ PyEval_ReleaseLock();
+
+}
+
+void FQTermWindow::finalizePython()
+{
+ // get the global python thread lock
+ PyEval_AcquireLock();
+
+ // get a reference to the PyInterpreterState
+ PyInterpreterState * mainInterpreterState = frame_->getPythonHelper()->getPyThreadState()->interp;
+
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+
+ //Displose of current python module so we can reload in constructor.
+ if(pModule!=NULL)
+ Py_DECREF(pModule);
+
+ //Clean up this thread's python interpreter reference
+ PyThreadState_Swap(NULL);
+ PyThreadState_Clear(myThreadState);
+ PyThreadState_Delete(myThreadState);
+ PyEval_ReleaseLock();
+}
+
+#endif //HAVE_PYTHON
+
+/* ------------------------------------------------------------------------ */
+/* */
+/* HTTP Func */
+/* */
+/* ------------------------------------------------------------------------ */
+
+void FQTermWindow::openLink() {
+ QString url = session_->getUrl();
+ if (!url.isEmpty()) {
+ openUrlImpl(url);
+ }
+}
+
+void FQTermWindow::saveLink() {
+ QString url = session_->getUrl();
+ if (!url.isEmpty())
+ getHttpHelper(url, false);
+}
+
+void FQTermWindow::openUrl(QString url)
+{
+ QString caption = tr("URL Dialog");
+ QString strUrl = url;
+ QTextEdit *textEdit = new QTextEdit();
+ textEdit->setPlainText(strUrl);
+ //textEdit->setFocus();
+ textEdit->setTabChangesFocus(true);
+ textEdit->moveCursor(QTextCursor::End);
+
+
+ QPushButton *okButton = new QPushButton(tr("&Open URL"));
+ QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
+// okButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+// cancelButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+
+
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(textEdit, 0, 0, 1, -1);
+ layout->addWidget(okButton, 1, 3);
+ layout->addWidget(cancelButton, 1, 4);
+
+ QDialog dlg(this);
+
+ QFontMetrics fm(qApp->font());
+
+
+ connect(okButton, SIGNAL(pressed()), &dlg, SLOT(accept()));
+ connect(cancelButton, SIGNAL(pressed()), &dlg, SLOT(reject()));
+
+
+ dlg.setWindowTitle(caption);
+ dlg.setLayout(layout);
+ dlg.resize(fm.width(QString(30, 'W')), fm.height() * (fm.width(strUrl) / fm.width(QString(30, 'W')) + 5));
+ textEdit->clearFocus();
+ okButton->setFocus(Qt::TabFocusReason);
+ if (dlg.exec()) {
+ openUrlImpl(textEdit->toPlainText());
+ }
+}
+
+
+void FQTermWindow::openUrlImpl(QString url)
+{
+ const QString &httpBrowser = FQTermPref::getInstance()->httpBrowser_;
+ if (httpBrowser.isNull() || httpBrowser.isEmpty()) {
+#if QT_VERSION >= 0x040400
+ QDesktopServices::openUrl(QUrl::fromEncoded(url.toLocal8Bit()));
+#else
+ QDesktopServices::openUrl(url);
+#endif
+ } else {
+ runProgram(httpBrowser, url);
+ }
+}
+
+
+void FQTermWindow::previewLink() {
+ getHttpHelper(session_->getUrl(), true);
+}
+
+void FQTermWindow::copyLink() {
+ QString strUrl;
+ strUrl = session_->bbs2unicode(session_->getUrl().toLatin1());
+
+ QClipboard *clipboard = QApplication::clipboard();
+
+ clipboard->setText(strUrl, QClipboard::Selection);
+ clipboard->setText(strUrl, QClipboard::Clipboard);
+}
+
+void FQTermWindow::getHttpHelper(const QString &url, bool preview) {
+
+ const QString &strPool = FQTermPref::getInstance()->poolDir_;
+
+ FQTermHttp *http = new FQTermHttp(config_, this, strPool, session_->param().serverEncodingID_);
+ if (getSession()->param().proxyType_ != 0) {
+ QString host = getSession()->param().proxyHostName_;
+ int port = getSession()->param().proxyPort_;
+ bool auth = getSession()->param().isAuthentation_;
+ QString user = auth ? getSession()->param().proxyUserName_ : QString();
+ QString pass = auth ? getSession()->param().proxyPassword_ : QString();
+ switch (getSession()->param().proxyType_)
+ {
+ case 1:
+ case 2:
+ //no support in qt.
+ FQ_TRACE("network", 0) << "proxy type not supported by qt, download will not use proxy.";
+ break;
+ case 3:
+ http->setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, host, port, user, pass));
+ break;
+ case 4:
+ http->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, host, port, user, pass));
+ break;
+ }
+ }
+ FQTerm::StatusBar::instance()->newProgressOperation(http).setDescription(tr("Waiting header...")).setAbortSlot(http, SLOT(cancel())).setMaximum(100);
+ FQTerm::StatusBar::instance()->resetMainText();
+ FQTerm::StatusBar::instance()->setProgress(http, 0);
+
+ FQ_VERIFY(connect(http, SIGNAL(headerReceived(FQTermHttp *, const QString &)),
+ this, SLOT(startHttpDownload(FQTermHttp*,const QString&))));
+
+ FQ_VERIFY(connect(http,SIGNAL(done(QObject*)),this,SLOT(httpDone(QObject*))));
+
+ FQ_VERIFY(connect(http, SIGNAL(message(const QString &)),
+ pageViewMessage_, SLOT(showText(const QString &))));
+
+ FQ_VERIFY(connect(http, SIGNAL(done(QObject*)),
+ FQTerm::StatusBar::instance(),
+ SLOT(endProgressOperation(QObject*))));
+
+ FQ_VERIFY(connect(http, SIGNAL(percent(int)),
+ FQTerm::StatusBar::instance(), SLOT(setProgress(int))));
+
+ FQ_VERIFY(connect(http, SIGNAL(previewImage(const QString &, bool, bool)),
+ this, SLOT(httpPreviewImage(const QString &, bool, bool))));
+
+
+ http->getLink(url, preview);
+}
+
+void FQTermWindow::startHttpDownload(
+ FQTermHttp *pHttp, const QString &filedesp) {
+ FQTerm::StatusBar::instance()->newProgressOperation(pHttp).setDescription
+ (filedesp).setAbortSlot(pHttp, SLOT(cancel())).setMaximum(100);
+
+ FQTerm::StatusBar::instance()->resetMainText();
+}
+
+void FQTermWindow::httpDone(QObject *pHttp) {
+ pHttp->deleteLater();
+}
+
+void FQTermWindow::httpPreviewImage(const QString &filename, bool raiseViewer, bool done)
+{
+ if (config_->getItemValue("preference", "image").isEmpty() || done) {
+ previewImage(filename, raiseViewer);
+ }
+}
+
+void FQTermWindow::previewImage(const QString &filename, bool raiseViewer) {
+// QString strViewer = frame_->config()->getItemValue("preference", "image");
+ QString strViewer = config_->getItemValue("preference", "image");
+
+ if (strViewer.isEmpty()) {
+ frame_->viewImages(filename, raiseViewer);
+ } else if(raiseViewer) {
+ runProgram(strViewer, filename);
+ }
+
+}
+
+void FQTermWindow::beep() {
+ if (session_->param().isBeep_) {
+ if (session_->param().isBuzz_) {
+ frame_->buzz(this);
+ }
+ if (FQTermPref::getInstance()->beepSoundFileName_.isEmpty() ||
+ FQTermPref::getInstance()->openBeep_ == 3) {
+ qApp->beep();
+ }
+ else {
+ sound_ = NULL;
+
+ switch (FQTermPref::getInstance()->beepMethodID_) {
+ case 0:
+ sound_ =
+ new FQTermSystemSound(FQTermPref::getInstance()->beepSoundFileName_);
+ break;
+ case 1:
+ sound_ =
+ new FQTermExternalSound(FQTermPref::getInstance()->beepPlayerName_,
+ FQTermPref::getInstance()->beepSoundFileName_);
+ break;
+ }
+
+ if (sound_) {
+ sound_->start();
+ }
+ }
+ }
+
+ QString strMsg = session_->getMessage();
+ if (!strMsg.isEmpty()) {
+ allMessages_ += strMsg + "\n\n";
+ }
+
+ session_->setSendingMessage();
+}
+
+
+void FQTermWindow::onTitleSet(const QString& title) {
+ setWindowTitle(title);
+}
+
+
+void FQTermWindow::startBlink() {
+ if (FQTermPref::getInstance()->openTabBlinking_) {
+ if (!tabBlinkTimer_->isActive()) {
+ tabBlinkTimer_->start(500);
+ }
+ }
+}
+
+void FQTermWindow::stopBlink() {
+ if (tabBlinkTimer_->isActive()) {
+ tabBlinkTimer_->stop();
+ emit blinkTheTab(this, TRUE);
+ }
+}
+
+void FQTermWindow::setCursorType(const QPoint& mousePosition) {
+ QRect rcOld;
+ bool isUrl = false;
+ if (FQTermPref::getInstance()->openUrlCheck_) {
+ showIP(session_->isIP(ipRectangle_, rcOld));
+ if (session_->isUrl(urlRectangle_, rcOld)) {
+ setCursor(Qt::PointingHandCursor);
+ isUrl = true;
+ }
+ }
+ if (!isUrl) {
+ FQTermSession::CursorType cursorType =
+ session_->getCursorType(screen_->mapToChar(mousePosition));
+ setCursor(cursors_[cursorType]);
+ }
+}
+
+void FQTermWindow::setCursorPosition(const QPoint& mousePosition) {
+ // set cursor pos, repaint if state changed
+ QRect rc;
+ if (session_->setCursorPos(screen_->mapToChar(mousePosition), rc)) {
+ screen_->repaint(screen_->mapToRect(rc));
+
+ //re-check whether the cursor is still on the selected rectangle -- dp
+ QPoint localPos = mapFromGlobal(QCursor::pos()); //local.
+ if (!session_->getMenuRect().contains(screen_->mapToChar(localPos)))
+ {
+ QRect dummyRect;
+ rc = session_->getMenuRect();
+ session_->setCursorPos(screen_->mapToChar(localPos), dummyRect);
+ screen_->repaint(screen_->mapToRect(rc));
+ //restore the state.
+ session_->setCursorPos(screen_->mapToChar(mousePosition), dummyRect);
+ }
+ }
+}
+
+void FQTermWindow::refreshScreen() {
+ screen_->setPaintState(FQTermScreen::NewData);
+ screen_->update();
+}
+
+void FQTermWindow::repaintScreen() {
+
+ screen_->setPaintState(FQTermScreen::Repaint);
+ if (clientRect_ != QRect()) {
+ screen_->repaint(screen_->mapToRect(clientRect_));
+ } else {
+ screen_->repaint();
+ }
+ clientRect_ = QRect();
+// screen_->update(clientRect_);
+}
+
+void FQTermWindow::enterMenuItem() {
+ char cr = CHAR_CR;
+ QRect rc = session_->getMenuRect();
+ FQTermSession::PageState ps = session_->getPageState();
+ switch (ps) {
+ case FQTermSession::Menu:
+ case FQTermSession::MailMenu:
+ case FQTermSession::TOP10:
+ if (!rc.isEmpty()) {
+ char cMenu = session_->getMenuChar();
+ session_->write(&cMenu, 1);
+ session_->write(&cr, 1);
+ }
+ break;
+ case FQTermSession::ArticleList:
+ case FQTermSession::BoardList:
+ case FQTermSession::FriendMailList:
+ case FQTermSession::EliteArticleList:
+ if (!rc.isEmpty()) {
+ int n = rc.y() - session_->getBuffer()->getCaretLine();
+ // scroll lines
+ int cursorType = n>0?FQTermSession::kDown:FQTermSession::kUp;
+ n = qAbs(n);
+ while (n) {
+ session_->write(directions_[cursorType], 4);
+ n--;
+ }
+ }
+ session_->write(&cr, 1);
+ break;
+ default:
+ // TODO: process other PageState.
+ break;
+ }
+}
+
+void FQTermWindow::processLClick(const QPoint& cellClicked) {
+ int cursorType = session_->getCursorType(cellClicked);
+ switch(cursorType)
+ {
+ case FQTermSession::kHome:
+ case FQTermSession::kEnd:
+ case FQTermSession::kPageUp:
+ case FQTermSession::kPageDown:
+ session_->writeStr(directions_[cursorType]);
+ break;
+ case FQTermSession::kUp:
+ case FQTermSession::kDown:
+ case FQTermSession::kLeft:
+ session_->writeStr(directions_[cursorType]);
+ break;
+ case FQTermSession::kRight: //Hand
+ enterMenuItem();
+ break;
+ case FQTermSession::kNormal:
+ char cr = CHAR_CR;
+ session_->write(&cr, 1);
+ break;
+ }
+}
+
+void FQTermWindow::startSelecting(const QPoint& mousePosition) {
+ // clear the selected before
+ session_->clearSelect();
+ sessionUpdated();
+
+ // set the selecting flag
+ isSelecting_ = true;
+ lastMouseCell_ = screen_->mapToChar(mousePosition);
+}
+
+void FQTermWindow::onSelecting(const QPoint& mousePosition) {
+ if (mousePosition.y() < childrenRect().top()) {
+ screen_->scrollLine(-1);
+ }
+ if (mousePosition.y() > childrenRect().bottom()) {
+ screen_->scrollLine(1);
+ }
+
+ QPoint curMouseCell = screen_->mapToChar(mousePosition);
+ session_->setSelect(lastMouseCell_, curMouseCell);
+ sessionUpdated();
+}
+
+void FQTermWindow::finishSelecting(const QPoint& mousePosition) {
+ QPoint currentMouseCell = screen_->mapToChar(mousePosition);
+ session_->setSelect(currentMouseCell, lastMouseCell_);
+ refreshScreen();
+ if (session_->param().isAutoCopy_) {
+ copy();
+ }
+ isSelecting_ = false;
+}
+
+void FQTermWindow::sendKey(const int keyCode, const Qt::KeyboardModifiers modifier,
+ const QString &t) {
+ if (keyCode == Qt::Key_Shift || keyCode == Qt::Key_Control
+ || keyCode == Qt::Key_Meta || keyCode == Qt::Key_Alt) {
+ return;
+ }
+
+ int key = keyCode;
+ QString text = t;
+
+#ifdef __APPLE__
+ // On Mac, pressing Command Key (Apple Key) will set the ControlModifier flag.
+ bool alt_on = ((modifier & Qt::ControlModifier) || (modifier & Qt::AltModifier));
+ bool ctrl_on = (modifier & Qt::MetaModifier);
+#else
+ bool alt_on = ((modifier & Qt::MetaModifier) || (modifier & Qt::AltModifier));
+ bool ctrl_on = (modifier & Qt::ControlModifier);
+#endif
+ bool shift_on = (modifier & Qt::ShiftModifier);
+
+#ifdef __APPLE__
+ // Bullshit! Qt4.4.0 on Mac generates weird key evnets.
+ // fix them here.
+
+ if (ctrl_on) {
+ static const char char_map[][2] = {
+ {'@', '\x00'}, {'A', '\x01'}, {'B', '\x02'}, {'C', '\x03'}, {'D', '\x04'},
+ {'E', '\x05'}, {'F', '\x06'}, {'G', '\x07'}, {'H', '\x08'}, {'J', '\x0a'},
+ {'K', '\x0b'}, {'L', '\x0c'}, {'N', '\x0e'}, {'O', '\x0f'}, {'P', '\x10'},
+ {'Q', '\x11'}, {'R', '\x12'}, {'S', '\x13'}, {'T', '\x14'}, {'U', '\x15'},
+ {'V', '\x16'}, {'W', '\x17'}, {'X', '\x18'}, {'Y', '\x19'}, {'Z', '\x1a'},
+ {'\\', '\x1c'}, {']', '\x1d'}, {'^', '\x1e'}, {'_', '\x1f'}
+ };
+
+ const int num = sizeof(char_map)/2;
+
+ int expected_key = key;
+
+ for (int i = 0; i < num; ++i) {
+ const char *c = char_map[i];
+ if (c[0] == key) {
+ expected_key = c[1];
+ break;
+ }
+ }
+
+ if (expected_key != key) {
+ FQ_TRACE("sendkey", 5) << "translate the key code from "
+ << (int)key << "(" << (char)key << ")"
+ << " to "
+ << (int)expected_key
+ << "(" << (char)expected_key << ")"
+ << ", and change the text appropriately." ;
+ key = expected_key;
+ text.clear();
+ text.append((char) expected_key);
+ }
+ }
+
+ if (!ctrl_on && alt_on && !shift_on) {
+ if (text.size() == 0 && 0 <= key && key <= 128) {
+ FQ_TRACE("sendkey", 5)
+ << "add appropriate text according to the key code.";
+ text.append((char)key);
+ }
+ }
+
+ if (!ctrl_on && alt_on && shift_on) {
+ // fix the key code when both shift key and meta/alt key are pressed.
+ static const char char_map[][2] = {
+ {'`', '~'}, {'1', '!'}, {'2', '@'}, {'3', '#'}, {'4', '$'},
+ {'5', '%'}, {'6', '^'}, {'7', '&'}, {'8', '*'}, {'9', '('},
+ {'0', ')'}, {'-', '_'}, {'=', '+'}, {'[', '{'}, {']', '}'},
+ {'\\', '|'}, {';', ':'}, {'\'', '"'}, {',', '<'},{'.', '>'},
+ {'/', '?'}
+ };
+ const int num = sizeof(char_map)/2;
+
+ int expected_key = key;
+
+ for (int i = 0; i < num; ++i) {
+ const char *c = char_map[i];
+ if (c[0] == key) {
+ expected_key = c[1];
+ break;
+ }
+ }
+
+ if (expected_key != key) {
+ FQ_TRACE("sendkey", 5) << "translate the key code from "
+ << (int)key << "(" << (char)key << ")"
+ << " to "
+ << (int)expected_key
+ << "(" << (char)expected_key << ")";
+ key = expected_key;
+ }
+
+ if (text.size() == 0) {
+ text.append(key);
+ } else {
+ text[0] = key;
+ }
+ FQ_TRACE("sendkey", 5)
+ << "set the text for this key event as the keycode.";
+ }
+#endif
+
+ FQ_TRACE("sendkey", 5) << "(alt " << (alt_on? " on": "off")
+ << ", ctrl " << (ctrl_on? " on": "off")
+ << ", shift " << (shift_on? " on": "off") << ")"
+ << " key: " << key
+ << " text: " << (text.size() == 0 ? "NULL" : text)
+ << " (in hex: "
+ << dumpHexString << text.toStdString()
+ << dumpNormalString << ")";
+
+ if (session_->getBuffer()->isAnsiMode()) {
+ if (session_->getBuffer()->isCursorMode()) {
+ switch(key) {
+ case Qt::Key_Up:
+ session_->writeStr("\x1bOA");
+ return;
+ case Qt::Key_Down:
+ session_->writeStr("\x1bOB");
+ return;
+ case Qt::Key_Left:
+ session_->writeStr("\x1bOD");
+ return;
+ case Qt::Key_Right:
+ session_->writeStr("\x1bOC");
+ return;
+ }
+ } else {
+ switch(key) {
+ case Qt::Key_Up:
+ session_->writeStr("\x1b[A");
+ return;
+ case Qt::Key_Down:
+ session_->writeStr("\x1b[B");
+ return;
+ case Qt::Key_Left:
+ session_->writeStr("\x1b[D");
+ return;
+ case Qt::Key_Right:
+ session_->writeStr("\x1b[C");
+ return;
+ }
+ }
+ } else {
+ // VT52 mode
+ switch(key) {
+ case Qt::Key_Up:
+ // Do NOT change the parameter to "\x1bA".
+ session_->writeStr("\x1b" "A");
+ return;
+ case Qt::Key_Down:
+ // Do NOT change the parameter to "\x1bB".
+ session_->writeStr("\x1b" "B");
+ return;
+ case Qt::Key_Left:
+ // Do NOT change the parameter to "\x1bD".
+ session_->writeStr("\x1b" "D");
+ return;
+ case Qt::Key_Right:
+ // Do NOT change the parameter to "\x1bC".
+ session_->writeStr("\x1b" "C");
+ return;
+ }
+ }
+
+ if (!session_->getBuffer()->isNumericMode() &&
+ (modifier & Qt::KeypadModifier)) {
+ switch(key) {
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ {
+ char tmp[] = "\x1bOp";
+ tmp[2] = 'p' + key - Qt::Key_0;
+ session_->writeStr(tmp);
+ }
+ return;
+ case Qt::Key_Plus:
+ session_->writeStr("\x1bOl");
+ return;
+ case Qt::Key_Minus:
+ session_->writeStr("\x1bOm");
+ return;
+ case Qt::Key_Period:
+ session_->writeStr("\x1bOn");
+ return;
+ case Qt::Key_Asterisk:
+ session_->writeStr("\x1bOM");
+ return;
+ }
+ }
+
+ switch (key) {
+ case Qt::Key_Home:
+ session_->writeStr(directions_[0]);
+ return;
+ case Qt::Key_End:
+ session_->writeStr(directions_[1]);
+ return;
+ case Qt::Key_PageUp:
+ session_->writeStr(directions_[2]);
+ return;
+ case Qt::Key_PageDown:
+ session_->writeStr(directions_[3]);
+ return;
+ case Qt::Key_Up:
+ session_->writeStr(directions_[4]);
+ return;
+ case Qt::Key_Down:
+ session_->writeStr(directions_[5]);
+ return;
+ case Qt::Key_Left:
+ session_->writeStr(directions_[6]);
+ return;
+ case Qt::Key_Right:
+ session_->writeStr(directions_[7]);
+ return;
+ case Qt::Key_F1:
+ session_->writeStr("\x1b[11~");
+ return;
+ case Qt::Key_F2:
+ session_->writeStr("\x1b[12~");
+ return;
+ case Qt::Key_F3:
+ session_->writeStr("\x1b[13~");
+ return;
+ case Qt::Key_F4:
+ session_->writeStr("\x1b[14~");
+ return;
+ case Qt::Key_F5:
+ session_->writeStr("\x1b[15~");
+ return;
+ case Qt::Key_F6:
+ session_->writeStr("\x1b[17~");
+ return;
+ case Qt::Key_F7:
+ session_->writeStr("\x1b[18~");
+ return;
+ case Qt::Key_F8:
+ session_->writeStr("\x1b[19~");
+ return;
+ case Qt::Key_F9:
+ session_->writeStr("\x1b[20~");
+ return;
+ case Qt::Key_F10:
+ session_->writeStr("\x1b[21~");
+ return;
+ case Qt::Key_F11:
+ session_->writeStr("\x1b[23~");
+ return;
+ case Qt::Key_F12:
+ session_->writeStr("\x1b[24~");
+ return;
+ }
+
+ if (text.length() > 0) {
+ if (alt_on) {
+ // Use ESC to emulate Alt-XX key.
+ session_->writeStr("\x1b");
+ }
+
+ if (ctrl_on) {
+ switch(key) {
+ case Qt::Key_At: // Ctrl-@
+ case Qt::Key_Space: // Ctrl-SPACE
+ // send NULL
+ session_->write("\x0", 1);
+ return;
+ case Qt::Key_AsciiCircum: // Ctrl-^
+ case Qt::Key_AsciiTilde: // Ctrl-~
+ case Qt::Key_QuoteLeft: // Ctrl-`
+ // send RS
+ session_->write("\x1e", 1);
+ return;
+ case Qt::Key_Underscore: // Ctrl-_
+ case Qt::Key_Question: // Ctrl-?
+ // send US
+ session_->write("\x1f", 1);
+ return;
+ }
+ }
+
+ if (key == Qt::Key_Backspace) {
+ if (shift_on) {
+ session_->writeStr("\x1b[3~");
+ } else {
+ if (session_->param().backspaceType_ == 0)
+ session_->writeStr("\x08");
+ else
+ session_->writeStr("\x7f");
+ }
+ return;
+ }
+
+ if (key == Qt::Key_Delete) {
+ if (shift_on) {
+ if (session_->param().backspaceType_ == 0)
+ session_->writeStr("\x08");
+ else
+ session_->writeStr("\x7f");
+ } else {
+ session_->writeStr("\x1b[3~");
+ }
+ return;
+ }
+
+ if (key == Qt::Key_Return) {
+ if (session_->getBuffer()->isNewLineMode()) {
+ session_->write("\r\n", 2);
+ } else {
+ session_->write("\r", 1);
+ }
+ return;
+ }
+
+ QByteArray cstrTmp = session_->unicode2bbs_smart(text);
+ session_->write(cstrTmp, cstrTmp.length());
+ }
+ return;
+}
+
+void FQTermWindow::forcedRepaintScreen() {
+ QResizeEvent *re = new QResizeEvent(screen_->size(), screen_->size());
+ QApplication::postEvent(screen_, re);
+}
+
+void FQTermWindow::updateSetting(const FQTermParam& param) {
+ session_->updateSetting(param);
+ screen_->setTermFont(true,
+ QFont(param.englishFontName_,
+ param.englishFontSize_));
+ screen_->setTermFont(false,
+ QFont(param.otherFontName_,
+ param.otherFontSize_));
+ screen_->setSchema();
+
+ setWindowTitle(param.name_);
+
+ forcedRepaintScreen();
+}
+
+void FQTermWindow::setFont()
+{
+ bool isEnglish =
+ ((QAction*)(sender()))->data().toBool();
+ setFont(isEnglish);
+}
+
+void FQTermWindow::setFont(bool isEnglish) {
+ bool ok;
+ QString& fontName = isEnglish?session_->param().englishFontName_:session_->param().otherFontName_;
+ int& fontSize = isEnglish?session_->param().englishFontSize_:session_->param().otherFontSize_;
+ QFont font(fontName, fontSize);
+ font = QFontDialog::getFont(&ok, font, this, tr("Font Selector")
+#ifdef __APPLE__
+, QFontDialog::DontUseNativeDialog
+#endif
+ );
+ if (ok == true) {
+ if (FQTermPref::getInstance()->openAntiAlias_) {
+ font.setStyleStrategy(QFont::PreferAntialias);
+ }
+ screen_->setTermFont(isEnglish, font);
+ fontName = font.family();
+ fontSize = font.pointSize();
+ forcedRepaintScreen();
+ }
+}
+
+
+void FQTermWindow::runScript(const QString &filename) {
+ script_engine_->runScript(filename);
+}
+
+//-----------
+static int translateQtModifiers(Qt::KeyboardModifiers modifiers) {
+ int state = 0;
+ if (modifiers &Qt::AltModifier) {
+ state |= SBS_ALT;
+ }
+ if (modifiers &Qt::ControlModifier) {
+ state |= SBS_CTRL;
+ }
+ if (modifiers &Qt::ShiftModifier) {
+ state |= SBS_SHIFT;
+ }
+ return state;
+}
+
+static int translateQtButton(Qt::MouseButtons btnstate) {
+ int state = 0;
+ if(btnstate&Qt::LeftButton)
+ state |= SBS_LEFT_BUTTON;
+ if(btnstate&Qt::RightButton)
+ state |= SBS_RIGHT_BUTTON;
+ if(btnstate&Qt::MidButton)
+ state |= SBS_MID_BUTTON;
+ return state;
+}
+
+bool FQTermWindow::scriptKeyEvent( QKeyEvent *keyevent ){
+ bool res = false;
+ int state = 0;
+ state |= translateQtModifiers(keyevent->modifiers());
+
+ res = postScriptCallback(SFN_KEY_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("liii", this, SKET_KEY_PRESS, state, keyevent->key())
+#endif //HAVE_PYTHON
+ ,QScriptValueList() << SKET_KEY_PRESS << state << keyevent->key());
+ return res;
+}
+
+bool FQTermWindow::scriptMouseEvent(QMouseEvent *mouseevent){
+ int type = SMET_UNKOWN;
+ switch (mouseevent->type())
+ {
+ case QEvent::MouseButtonPress:
+ type = SMET_MOUSE_PRESS;
+ break;
+ case QEvent::MouseButtonRelease:
+ type = SMET_MOUSE_RELEASE;
+ break;
+ case QEvent::MouseButtonDblClick:
+ type = SMET_MOUSE_DBCLICK;
+ break;
+ case QEvent::MouseMove:
+ type = SMET_MOUSE_MOVE;
+ break;
+ }
+
+ int delta = 0;
+ int state=0;
+
+ state |= translateQtButton(mouseevent->button());
+ state |= translateQtModifiers(mouseevent->modifiers());
+
+ QPoint ptc = screen_->mapToChar(mouseevent->pos());
+ ptc.setY(ptc.y() - screen_->getBufferStart());
+ int res = postScriptCallback(SFN_MOUSE_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("liiiii", this, type, state, ptc.x(), ptc.y(),delta)
+#endif //HAVE_PYTHON
+ ,QScriptValueList() << type << state << ptc.x() << ptc.y() << delta);
+ return res;
+}
+
+bool FQTermWindow::scriptWheelEvent( QWheelEvent *wheelevent ) {
+ int type = SMET_WHEEL;
+ int delta = 0;
+ int state=0;
+ state |= translateQtModifiers(wheelevent->modifiers());
+ QPoint ptc = screen_->mapToChar(wheelevent->pos());
+ ptc.setY(ptc.y() - screen_->getBufferStart());
+ int res = postScriptCallback(SFN_MOUSE_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("liiiii", this, type, state, ptc.x(), ptc.y(),wheelevent->delta())
+#endif //HAVE_PYTHON
+ ,QScriptValueList() << type << state << ptc.x() << ptc.y() << wheelevent->delta());
+ return res;
+}
+
+const QString FQTermExternalEditor::textEditName_ = "external editor input";
+
+FQTermExternalEditor::FQTermExternalEditor(QWidget* parent)
+: QObject(parent),
+ editorProcess_(NULL),
+ started_(false) {
+ editorProcess_ = new QProcess(this);
+ FQ_VERIFY(connect(editorProcess_, SIGNAL(stateChanged(QProcess::ProcessState)),
+ this, SLOT(stateChanged(QProcess::ProcessState))));
+ clearTempFileContent();
+}
+
+FQTermExternalEditor::~FQTermExternalEditor() {
+ editorProcess_->kill();
+ QFile::remove(getTempFilename());
+ delete editorProcess_;
+}
+
+void FQTermExternalEditor::execDialog() {
+ QDialog *dialog = new QDialog((QWidget *)parent());
+ QGridLayout *layout = new QGridLayout(dialog);
+ QTextEdit *text = new QTextEdit(dialog);
+ text->setObjectName(textEditName_);
+ layout->addWidget(text);
+ QBoxLayout *rowLayout = new QBoxLayout(QBoxLayout::LeftToRight, dialog);
+ layout->addLayout(rowLayout, 1, 0, Qt::AlignHCenter);
+ QPushButton *ok = new QPushButton(tr("OK"), dialog);
+ QPushButton *cancel = new QPushButton(tr("Cancel"), dialog);
+ rowLayout->addWidget(ok);
+ rowLayout->addWidget(cancel);
+ FQ_VERIFY(connect(ok, SIGNAL(clicked()),
+ dialog, SLOT(accept())));
+ FQ_VERIFY(connect(cancel, SIGNAL(clicked()),
+ dialog, SLOT(reject())));
+ FQ_VERIFY(connect(dialog, SIGNAL(accepted()),
+ this, SLOT(readDialogData())));
+ FQ_VERIFY(connect(dialog, SIGNAL(rejected()),
+ this, SLOT(closeDialog())));
+ dialog->setModal(true);
+ dialog->exec();
+}
+
+void FQTermExternalEditor::readDialogData() {
+ QDialog *dialog = (QDialog*)sender();
+ QTextEdit* edit = (QTextEdit*)dialog->findChild<QTextEdit*>(textEditName_);
+ if (edit) {
+ emit done(edit->toPlainText());
+ }
+ closeDialog();
+}
+
+void FQTermExternalEditor::closeDialog() {
+ sender()->deleteLater();
+}
+
+void FQTermExternalEditor::start() {
+ if (FQTermPref::getInstance()->externalEditor_.isEmpty()) {
+ execDialog();
+ return;
+ }
+ if (started_)
+ return;
+ started_ = true;
+ if (FQTermPref::getInstance()->externalEditorArg_.isEmpty()) {
+ editorProcess_->start(FQTermPref::getInstance()->externalEditor_, QStringList() << getTempFilename());
+ } else {
+ FQ_TRACE("editor", 5) << FQTermPref::getInstance()->externalEditorArg_.arg(getTempFilename());
+ editorProcess_->start(FQTermPref::getInstance()->externalEditor_ + " " + FQTermPref::getInstance()->externalEditorArg_.arg(getTempFilename()));
+ }
+}
+
+
+QString FQTermExternalEditor::getTempFilename() {
+ return getPath(USER_CONFIG) + "tmp_do_not_use.txt";
+}
+
+void FQTermExternalEditor::clearTempFileContent() {
+ QFile file(getTempFilename());
+ file.open(QIODevice::Truncate | QIODevice::WriteOnly);
+ file.write("\xEF\xBB\xBF");
+ file.flush();
+ file.close();
+}
+
+void FQTermExternalEditor::stateChanged( QProcess::ProcessState state ) {
+ //FQ_TRACE("editor", 0) << "stateChanged: " << state << editorProcess_->readAllStandardOutput() << editorProcess_->readAllStandardError();
+ if (!started_ || state != QProcess::NotRunning)
+ return;
+ QFile file(getTempFilename());
+ file.open(QIODevice::ReadOnly);
+ QString result = U82U(file.readAll());
+ file.close();
+#if !defined(WIN32) && !defined(__APPLE__)
+ if (result.endsWith(OS_NEW_LINE)) {
+ result.resize(result.size() - 1);
+ }
+#endif
+ emit done(result);
+ clearTempFileContent();
+ started_ = false;
+}
+} // namespace FQTerm
+#include "fqterm_window.moc"
diff --git a/src/fqterm/fqterm_window.h b/src/fqterm/fqterm_window.h
new file mode 100644
index 0000000..011bf86
--- /dev/null
+++ b/src/fqterm/fqterm_window.h
@@ -0,0 +1,345 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_WINDOW_H
+#define FQTERM_WINDOW_H
+
+#include <QMainWindow>
+#include <QCursor>
+#include <QString>
+#include <QProcess>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "fqterm_param.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#include "fqterm_session.h"
+
+class QCloseEvent;
+class QEvent;
+class QKeyEvent;
+class QMouseEvent;
+class QMouseEvent;
+class QProgressBar;
+class QWheelEvent;
+
+namespace FQTerm {
+
+//class QProgressDialog;
+class PageViewMessage;
+class FQTermConfig;
+class FQTermImage;
+class FQTermFrame;
+class FQTermHttp;
+class FQTermScreen;
+class FQTermSession;
+class FQTermSound;
+class FQTermWindow;
+class popWidget;
+class zmodemDialog;
+class FQTermScriptEngine;
+
+class FQTermExternalEditor : public QObject {
+ Q_OBJECT;
+public:
+ FQTermExternalEditor(QWidget* parent);
+ ~FQTermExternalEditor();
+ void start();
+signals:
+ void done(const QString&);
+public slots:
+ void stateChanged(QProcess::ProcessState state);
+protected slots:
+ void readDialogData();
+ void closeDialog();
+private:
+ void execDialog();
+ QString getTempFilename();
+ void clearTempFileContent();
+
+ static const QString textEditName_;
+ bool started_;
+ QProcess* editorProcess_;
+};
+
+class FQTermWindow : public QMainWindow,
+ public FQTermScriptEventListener {
+ friend class FQTermScreen;
+
+ Q_OBJECT;
+ public:
+ FQTermWindow(FQTermConfig *, FQTermFrame *frame, FQTermParam param, int addr = -1, QWidget
+ *parent = 0, const char *name = 0, Qt::WFlags wflags = Qt::Window);
+ ~FQTermWindow();
+
+ void connectHost();
+ bool isConnected();
+
+ void disconnect();
+ //redraw the dirty lines
+ void refreshScreen();
+ //repaint a dirty rectangle.
+ void repaintScreen();
+ //force a repaint by sending a resize event
+ void forcedRepaintScreen();
+ void viewMessages();
+ void toggleAutoReply();
+ void toggleAntiIdle();
+ void toggleAutoReconnect();
+ void setFont(bool isEnglish);
+ void saveSetting(bool ask = true);
+
+ void runScript(const QString & filename);
+ int externInput(const QByteArray &);
+ int externInput(const QString &);
+ void getHttpHelper(const QString &, bool);
+
+ void openUrl(QString url);
+ void openUrlImpl(QString url);
+
+ FQTermSession * getSession() const { return session_; }
+ FQTermScreen * getScreen() const {return screen_;}
+ QPoint getUrlStartPoint() const { return urlStartPoint_; }
+ QPoint getUrlEndPoint() const { return urlEndPoint_; }
+
+ //FQTermScriptEventListener
+private:
+ virtual bool postQtScriptCallback(const QString& func, const QScriptValueList & args = QScriptValueList());
+#ifdef HAVE_PYTHON
+ virtual bool postPythonCallback(const QString& func, PyObject* pArgs);
+#endif //HAVE_PYTHON
+
+public:
+ virtual long windowID() {return long(this);}
+ //end FQTermScriptEventListener
+
+signals:
+ void resizeSignal(FQTermWindow*);
+ void refreshOthers(FQTermWindow*);
+ void blinkTheTab(FQTermWindow*, bool);
+ void connectionClosed(FQTermWindow*);
+ public slots:
+ // ui
+ void copy();
+ void paste();
+ void openAsUrl();
+ void searchIt();
+ void shareIt();
+ void externalEditor();
+ void fastPost();
+ void copyArticle();
+ void setting();
+ void setColor();
+ void runScript();
+ void stopScript();
+
+ void sendParsedString(const char*);
+ void showIP(bool show = true);
+
+ void beep();
+ void startBlink();
+ void stopBlink();
+ void onTitleSet(const QString& title);
+
+ void connectionClosed();
+
+ void messageAutoReplied();
+
+ void pasteHelper(bool);
+
+ QByteArray parseString(const QByteArray &, int *len = 0);
+
+ // void sendMouseState(int, Qt::KeyboardModifier, Qt::KeyboardModifier, const
+ // QPoint &);
+
+
+ protected slots:
+ void setFont();
+ void recreateMenu();
+
+ //refresh screen & reset cursor position
+ void sessionUpdated();
+
+ void requestUserPwd(QString *userName, QString *password, bool *isOK);
+
+ void TelnetState(int);
+ void ZmodemState(int, int, const char *);
+ void showSessionErrorMessage(QString);
+
+ void blinkTab();
+
+ void externalEditorDone(const QString& str);
+
+ //http menu
+ void previewLink();
+ void saveLink();
+ void openLink();
+ void copyLink();
+ void previewImage(const QString &filename, bool raiseViewer);
+ void httpPreviewImage(const QString &filename, bool raiseViewer, bool done);
+ void startHttpDownload(FQTermHttp *, const QString &filedesp);
+
+ void httpDone(QObject*);
+
+ // decode
+ // void setMouseMode(bool);
+ void articleCopied(int e, const QString content);
+
+
+ protected:
+ bool event(QEvent*);
+
+ void resizeEvent(QResizeEvent *);
+ void mouseDoubleClickEvent(QMouseEvent*);
+ void mouseMoveEvent(QMouseEvent*);
+ void mousePressEvent(QMouseEvent*);
+ void mouseReleaseEvent(QMouseEvent*);
+ void wheelEvent(QWheelEvent*);
+ void enterEvent(QEvent*);
+ void leaveEvent(QEvent*);
+ void changeEvent(QEvent*);
+ void closeEvent(QCloseEvent*);
+ void keyPressEvent(QKeyEvent*);
+ //void focusInEvent (QFocusEvent *);
+
+ private:
+ FQTermFrame *frame_;
+ FQTermScreen *screen_;
+ FQTermSession *session_;
+ QString allMessages_;
+ // before calling repaintScreen(), pls
+ // fill this rectangle.
+ QRect clientRect_;
+ QPoint urlEndPoint_;
+ QPoint urlStartPoint_;
+
+ QMenu *menu_;
+ QMenu *urlMenu_;
+
+ static char directions_[][5];
+ QCursor cursors_[9];
+
+ FQTermConvert encodingConverter_;
+
+ // mouse select
+ QPoint lastMouseCell_;
+ bool isSelecting_;
+
+ // address setting
+ int addressIndex_;
+
+ // url rect
+ QRect urlRectangle_;
+
+ //ip rect
+ QRect ipRectangle_;
+
+ // play sound
+ FQTermSound *sound_;
+
+
+ FQTermConfig *config_;
+ zmodemDialog *zmodemDialog_;
+
+ //osd
+ PageViewMessage *pageViewMessage_;
+
+ popWidget *popWindow_;
+ QTimer *tabBlinkTimer_;
+
+ bool isMouseClicked_;
+ bool blinkStatus_;
+
+ bool isUrlUnderLined_;
+
+ FQTermScriptEngine *script_engine_;
+ FQTermExternalEditor *externalEditor_;
+ private:
+ void addMenu();
+
+ void setCursorPosition(const QPoint& mousePosition);
+ //set cursor type according to the content
+ //show ip location info if openUrlCheck is set
+ void setCursorType(const QPoint& mousePosition);
+
+
+ void enterMenuItem();
+ void processLClick(const QPoint& cellClicked);
+
+ void startSelecting(const QPoint& mousePosition);
+ void onSelecting(const QPoint& mousePosition);
+ void finishSelecting(const QPoint& mousePosition);
+
+ void updateSetting(const FQTermParam& param);
+
+ void sendKey(const int key, const Qt::KeyboardModifiers modifier,
+ const QString &text);
+
+ bool scriptKeyEvent(QKeyEvent *keyevent);
+ bool scriptMouseEvent(QMouseEvent *mouseevent);
+ bool scriptWheelEvent(QWheelEvent *wheelevent);
+
+ void writePasting(const QString& content);
+
+
+signals:
+ //these 2 signals are connected to corresponding slots to
+ //make write thread safe.
+ int writeStringSignal(const QString& str);
+ int writeRawStringSignal(const QString& str);
+public slots:
+ //for script
+ int writeString(const QString& str) {return externInput(str);}
+ int writeRawString(const QString& str);
+public:
+ void writeString_ts(const QString& str) {emit writeStringSignal(str);}
+ void writeRawString_ts(const QString& str) {emit writeRawStringSignal(str);}
+
+
+
+//python support
+#ifdef HAVE_PYTHON
+public:
+ QString getPythonErrorMessage() {
+ return pythonErrorMessage_;
+ }
+ void runPythonScript();
+ void runPythonScriptFile(const QString&);
+
+protected:
+ bool pythonCallback(const QString &, PyObject*);
+ int runPythonFile(const QString& file);
+ void initPython(const QString& file);
+ void finalizePython();
+ //void sendMouseState(int, ButtonState, ButtonState, const QPoint&);
+private:
+ PyObject *pModule, *pDict;
+ bool pythonScriptLoaded_;
+ QString pythonErrorMessage_;
+#endif
+
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_WINDOW_H
+
diff --git a/src/fqterm/fqterm_wndmgr.cpp b/src/fqterm/fqterm_wndmgr.cpp
new file mode 100644
index 0000000..0e90b1c
--- /dev/null
+++ b/src/fqterm/fqterm_wndmgr.cpp
@@ -0,0 +1,381 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+/////////////////////////////////////////////////////////////////
+//TODO: This class has too many overlap with MDI Area.
+//It should inherit the QMdiArea...
+/////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+
+#include <QApplication>
+#include <QEvent>
+#include <QKeyEvent>
+#include <QIcon>
+#include <QKeySequence>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QTabBar>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMessageBox>
+#include <QToolButton>
+#include "fqterm_frame.h"
+#include "fqterm_path.h"
+#include "fqterm_screen.h"
+#include "fqterm_trace.h"
+#include "fqterm_window.h"
+#include "fqterm_wndmgr.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+namespace FQTerm {
+
+//constructor
+FQTermWndMgr::FQTermWndMgr(QWidget *parent, const char *name)
+ : QMdiArea(parent),
+ subWindowMax_(true),
+ subWindowSize_(640, 480),
+ tabBar_(NULL)
+ {
+ tabBar_ = new FQTermTabBar(this);
+ tabBar_->setShape(QTabBar::RoundedSouth);
+ FQ_VERIFY(connect(tabBar_, SIGNAL(currentChanged(int)),
+ this, SLOT(activateTheWindow(int))));
+ FQ_VERIFY(connect(tabBar_, SIGNAL(rightClicked(int,const QPoint&)),
+ this, SLOT(onTabRightClicked(int,const QPoint&))));
+ FQ_VERIFY(connect(tabBar_, SIGNAL(doubleClicked(int,const QPoint&)),
+ this, SLOT(onTabDoubleClicked(int,const QPoint&))));
+ setObjectName(name);
+ termFrame_ = (FQTermFrame*)parent;
+ isAfterRemoved_ = false;
+}
+
+//destructor
+FQTermWndMgr::~FQTermWndMgr(){}
+
+
+//remove window-tab-iconset
+bool FQTermWndMgr::closeWindow(FQTermWindow *mw) {
+ FQ_FUNC_TRACE("wndmgr", 3);
+ QMdiSubWindow* subWindow = FQToMDI(mw);
+ if (subWindow) {
+ return subWindow->close();
+ }
+ return false;
+}
+
+bool FQTermWndMgr::closeAllWindow() {
+ FQ_FUNC_TRACE("wndmgr", 3);
+
+ bool anyConnected = false;
+
+ for (int i = 0; i < subWindowList().size(); ++i) {
+ FQTermWindow * window = (FQTermWindow *)(subWindowList()[i]->widget());
+ if (window->isConnected()) {
+ anyConnected = true;
+ break;
+ }
+ }
+
+ bool warn = FQTermPref::getInstance()->openWarnOnClose_;
+ if (anyConnected && warn) {
+ QMessageBox mb(tr("FQTerm"),
+ tr("Still connected, do you really want to exit?"),
+ QMessageBox::Warning, QMessageBox::Yes|QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (mb.exec() != QMessageBox::Yes) {
+ return false;
+ }
+ }
+ FQTermPref::getInstance()->openWarnOnClose_ = false;
+ while (count() > 0) {
+ bool closed = subWindowList().at(0)->close();
+ if (!closed) {
+ FQTermPref::getInstance()->openWarnOnClose_ = warn;
+ return false;
+ }
+ }
+ FQTermPref::getInstance()->openWarnOnClose_ = warn;
+ return true;
+}
+
+
+
+//active the window when switch the tab
+void FQTermWndMgr::activateTheWindow(int n) {
+ FQ_FUNC_TRACE("wndmgr", 3);
+
+ if (n < 0 || n >= count() || subWindowList().at(n) == activeSubWindow())
+ return;
+
+ QMdiSubWindow *subWindow = subWindowList().at(n);
+
+ // Fix the refresh bug by send PaintEvent to session screen.
+ //subWindow->setFocus();
+ setActiveSubWindow(subWindow);
+
+}
+
+//blink the tab when message come in
+void FQTermWndMgr::blinkTheTab(FQTermWindow *mw, bool bVisible) {
+ FQ_FUNC_TRACE("wndmgr", 10);
+ static QIcon a_icon(getPath(RESOURCE) + "pic/tabpad.png");
+ static QIcon b_icon(getPath(RESOURCE) + "pic/transp.png");
+
+ //find where it is
+ QMdiSubWindow* subWindow = FQToMDI(mw);
+ if (!subWindow)
+ return;
+ int n = subWindowList().indexOf(subWindow);
+ QIcon *icon = icons_.at(n);
+ //FIXME: QIcon::Automatic
+ if (bVisible) {
+ icon->addFile(getPath(RESOURCE) + "pic/tabpad.png");
+
+ tabBar_->setTabIcon(n, a_icon);
+ } else {
+ //,QIcon::Automatic);
+ icon->addFile(getPath(RESOURCE) + "pic/transp.png");
+ tabBar_->setTabIcon(n, b_icon);
+ }
+ //,QIcon::Automatic);
+
+
+
+
+ tabBar_->update();
+}
+
+//return the number of connected window
+int FQTermWndMgr::count() {
+ return subWindowList().count();
+}
+
+FQTermWindow *FQTermWndMgr::activeWindow() {
+ return MDIToFQ(activeSubWindow());
+}
+
+
+bool FQTermWndMgr::afterRemove() {
+ if (isAfterRemoved_) {
+ isAfterRemoved_ = false;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void FQTermWndMgr::refreshAllExcept(FQTermWindow *termWindow) {
+ for (int i = 0; i < subWindowList().count(); ++i) {
+ FQTermWindow * window = (FQTermWindow *)(subWindowList()[i]->widget());
+ if (window != termWindow) {
+ window->repaintScreen();
+ }
+ }
+}
+
+
+FQTermWindow* FQTermWndMgr::newWindow( const FQTermParam &param, FQTermConfig* config, QIcon* icon, int index /*= -1*/ )
+{
+ FQTermWindow *window = new FQTermWindow(config, termFrame_, param, index, this, 0);
+ //add window-tab-icon to window manager
+
+
+ QMdiSubWindow* subWindow = addSubWindow(window);
+ subWindow->setAttribute(Qt::WA_OpaquePaintEvent);
+ subWindow->setAttribute(Qt::WA_DeleteOnClose);
+
+ icons_.append(icon);
+ if (count() == 1) {
+ termFrame_->enableMenuToolBar(true);
+ }
+ //if no this call, the tab wont display untill you resize the window
+ int idx = tabBar_->addTab(*icon, window->windowTitle());
+ tabBar_->updateGeometry();
+ tabBar_->update();
+
+ subWindow->resize(subWindowSize_);
+ if (subWindowMax_) {
+ subWindow->setWindowFlags(Qt::SubWindow | Qt::CustomizeWindowHint | Qt::WindowMinMaxButtonsHint);
+ subWindow->showMaximized();
+ } else {
+ subWindow->setWindowFlags(Qt::SubWindow | (Qt::CustomizeWindowHint
+ | Qt::WindowMinMaxButtonsHint
+ | Qt::WindowSystemMenuHint));
+ subWindow->show();
+ }
+ tabBar_->setTabData(idx, qVariantFromValue((QObject*)window));
+ FQ_VERIFY(connect(window, SIGNAL(destroyed(QObject*)),
+ this ,SLOT(onSubWindowClosed(QObject*))));
+ FQ_VERIFY(connect(window, SIGNAL(resizeSignal(FQTermWindow*)),
+ this, SLOT(subWindowResized(FQTermWindow*))));
+ FQ_VERIFY(connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(onSubWindowActivated(QMdiSubWindow*))));
+ FQ_VERIFY(connect(window, SIGNAL(blinkTheTab(FQTermWindow*, bool)),
+ this, SLOT(blinkTheTab(FQTermWindow*, bool))));
+ FQ_VERIFY(connect(window, SIGNAL(refreshOthers(FQTermWindow*)),
+ this, SLOT(refreshAllExcept(FQTermWindow*))));
+ FQ_VERIFY(connect(window, SIGNAL(connectionClosed(FQTermWindow*)),
+ this, SLOT(closeWindow(FQTermWindow*)), Qt::QueuedConnection));
+ return window;
+}
+
+void FQTermWndMgr::onSubWindowClosed(QObject* obj) {
+
+ for (int i = 0; i < tabBar_->count(); ++i) {
+ if (tabBar_->tabData(i) == qVariantFromValue(obj)) {
+ if (count() == 0) {
+ termFrame_->enableMenuToolBar(false);
+ }
+ if (i == tabBar_->currentIndex())
+ isAfterRemoved_ = true;
+ tabBar_->removeTab(i);
+ icons_.removeAt(i);
+ }
+ }
+
+}
+
+//---------------------------
+//record subwindows' size
+//---------------------------
+void
+FQTermWndMgr::subWindowResized(FQTermWindow *mw) {
+ QMdiSubWindow* subWindow = FQToMDI(mw);
+ if (!subWindow)
+ return;
+ Qt::WindowFlags wfs = subWindow->windowFlags();
+
+ if (!(subWindowMax_ = subWindow->isMaximized())){
+ if (!subWindow->isMinimized()) {
+ subWindowSize_ = subWindow->frameSize();
+ }
+ subWindow->setWindowFlags(wfs | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
+ }
+ else {
+ subWindow->setWindowFlags(wfs & ~Qt::WindowSystemMenuHint);
+ }
+
+}
+
+void FQTermWndMgr::cascade() {
+ QSize oldSize = subWindowSize_;
+ cascadeSubWindows();
+ foreach(QMdiSubWindow* subWindow, subWindowList()) {
+ if (subWindow) {
+ subWindow->resize(oldSize);
+ }
+ }
+}
+
+void FQTermWndMgr::tile() {
+ tileSubWindows();
+}
+
+void FQTermWndMgr::activateNextWindow() {
+ activateTheWindow((activeWindowIndex() + 1) % count());
+}
+
+void FQTermWndMgr::activatePrevWindow() {
+ activateTheWindow((activeWindowIndex() - 1 + count()) % count());
+}
+
+FQTermWindow * FQTermWndMgr::nthWindow(int n) {
+ return (FQTermWindow *)(subWindowList()[n]->widget());
+}
+
+void FQTermWndMgr::onSubWindowActivated(QMdiSubWindow * subWindow) {
+ int n = subWindowList().indexOf(subWindow);
+ if (n == -1)
+ return;
+ FQTermWindow* mw = MDIToFQ(subWindow);
+ if (mw->isMaximized() &&
+ afterRemove()) {
+ mw->showNormal();
+ mw->showMaximized();
+ }
+ if (tabBar_->currentIndex() != n) {
+ FQ_VERIFY(disconnect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(onSubWindowActivated(QMdiSubWindow*))));
+ tabBar_->setCurrentIndex(n);
+ FQ_VERIFY(connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(onSubWindowActivated(QMdiSubWindow*))));
+ }
+ termFrame_->updateMenuToolBar();
+}
+
+void FQTermWndMgr::onTabRightClicked(int index, const QPoint& p) {
+ QMenu* menu = FQToMDI(nthWindow(index))->systemMenu();
+ menu->popup(p);
+}
+
+void FQTermWndMgr::onTabDoubleClicked(int index, const QPoint& p) {
+ closeWindow(nthWindow(index));
+}
+
+FQTermWindow* FQTermWndMgr::MDIToFQ( QMdiSubWindow* subWindow )
+{
+ if (!subWindowList().contains(subWindow))
+ return NULL;
+ return (FQTermWindow*)subWindow->widget();
+}
+
+QMdiSubWindow* FQTermWndMgr::FQToMDI( FQTermWindow* window )
+{
+ for (int i = 0; i < subWindowList().count(); ++i) {
+ if ((FQTermWindow*)(subWindowList()[i]->widget()) == window) {
+ return subWindowList()[i];
+ }
+ }
+ return NULL;
+}
+
+int FQTermWndMgr::FQToIndex( FQTermWindow* window )
+{
+ return subWindowList().indexOf(FQToMDI(window));
+}
+
+bool FQTermWndMgr::event( QEvent* e ) {
+ if (e->type() == QEvent::ShortcutOverride) {
+ QKeyEvent* ke = (QKeyEvent*)e;
+ if (ke->key() == Qt::Key_W && ke->modifiers() == Qt::ControlModifier) {
+ ke->accept();
+ return true;
+ }
+ }
+ return QMdiArea::event(e);
+}
+void FQTermTabBar::mouseReleaseEvent( QMouseEvent * me ) {
+ int index = tabAt(me->pos());
+ if (index != -1 && me->button() == Qt::RightButton && me->modifiers() == Qt::NoModifier) {
+ emit rightClicked(index, mapToGlobal(me->pos()));
+ }
+}
+
+void FQTermTabBar::mouseDoubleClickEvent( QMouseEvent * me ) {
+ int index = tabAt(me->pos());
+ if (index != -1 && me->button() == Qt::LeftButton && me->modifiers() == Qt::NoModifier) {
+ emit doubleClicked(index, mapToGlobal(me->pos()));
+ }
+}
+} // namespace FQTerm
+
+#include "fqterm_wndmgr.moc"
diff --git a/src/fqterm/fqterm_wndmgr.h b/src/fqterm/fqterm_wndmgr.h
new file mode 100644
index 0000000..5038d8f
--- /dev/null
+++ b/src/fqterm/fqterm_wndmgr.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_WND_MGR_H
+#define FQTERM_WND_MGR_H
+
+#include <QString>
+#include <QList>
+#include <map>
+#include <utility>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QTabBar>
+
+class QEvent;
+class QIcon;
+class QSize;
+class FQTermConfig;
+namespace FQTerm {
+
+class FQTermWindow;
+class FQTermFrame;
+
+class FQTermTabBar : public QTabBar {
+ Q_OBJECT;
+public:
+ FQTermTabBar(QWidget *parent = 0) : QTabBar(parent) {}
+protected:
+ virtual void mouseReleaseEvent(QMouseEvent * me);
+ virtual void mouseDoubleClickEvent(QMouseEvent * me);
+signals:
+ void rightClicked(int index, const QPoint& p);
+ void doubleClicked(int index, const QPoint& p);
+};
+
+class FQTermWndMgr: public QMdiArea {
+ Q_OBJECT;
+ public:
+ FQTermWndMgr(QWidget *parent = 0, const char *name = 0);
+ ~FQTermWndMgr();
+
+ QTabBar* tabBar() {return tabBar_;}
+
+ FQTermWindow* newWindow(const FQTermParam &param, FQTermConfig* config, QIcon* icon, int index = -1);
+ bool closeAllWindow();
+
+
+
+ FQTermWindow *activeWindow();
+ int activeWindowIndex() {
+ return FQToIndex(activeWindow());
+ }
+ FQTermWindow *nthWindow(int n);
+ int count();
+
+ //sub-window position & size
+
+ bool getSubWindowMax() const { return subWindowMax_; }
+ void setSubWindowMax(bool val) { subWindowMax_ = val; }
+ QSize getSubWindowSize() const { return subWindowSize_; }
+ void setSubWindowSize(QSize val) { subWindowSize_ = val; }
+
+ public slots:
+ bool closeWindow(FQTermWindow *mw);
+ void onSubWindowClosed(QObject* obj);
+ //record subwindows' size changes
+ void subWindowResized(FQTermWindow *);
+ void activateTheWindow(int n);
+ void activateNextWindow();
+ void activatePrevWindow();
+ void refreshAllExcept(FQTermWindow *mw);
+ void blinkTheTab(FQTermWindow *mw, bool bVisible);
+ void cascade();
+ void tile();
+
+protected:
+
+ QList<QIcon *> icons_;
+ FQTermFrame *termFrame_;
+ bool isAfterRemoved_;
+ QSize subWindowSize_;
+ bool subWindowMax_;
+ FQTermTabBar* tabBar_;
+
+ FQTermWindow* MDIToFQ(QMdiSubWindow* subWindow);
+ QMdiSubWindow* FQToMDI(FQTermWindow* window);
+ int FQToIndex(FQTermWindow* window);
+ bool afterRemove();
+ bool event(QEvent* e);
+protected slots:
+ void onSubWindowActivated(QMdiSubWindow * subWindow);
+ void onTabRightClicked(int index, const QPoint& p);
+ void onTabDoubleClicked(int index, const QPoint& p);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_WND_MGR_H
diff --git a/src/fqterm/main.cpp b/src/fqterm/main.cpp
new file mode 100644
index 0000000..40969fd
--- /dev/null
+++ b/src/fqterm/main.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+
+#if defined(WIN32)
+#include <windows.h>
+#include <shellapi.h>
+#else
+#include <sys/stat.h>
+#include <errno.h>
+#include <locale.h>
+#endif
+
+#if defined(FQTERM_USE_STATIC_QT)
+ // You can change the definition of FQTERM_USE_STATIC_QT in
+ // fqterm/CMakeLists.txt.{linux, macos, win32}.
+
+ // static link Qt4 plugins.
+ void loadNecessaryQtPlugins() {}
+ #include <QtPlugin>
+ Q_IMPORT_PLUGIN(qkrcodecs)
+ Q_IMPORT_PLUGIN(qcncodecs)
+ Q_IMPORT_PLUGIN(qjpcodecs)
+ Q_IMPORT_PLUGIN(qtwcodecs)
+ Q_IMPORT_PLUGIN(qjpeg)
+ Q_IMPORT_PLUGIN(qgif)
+ Q_IMPORT_PLUGIN(qmng)
+#else
+ // dynamic link Qt4 plugins.
+ #include <QPluginLoader>
+ void loadNecessaryQtPlugins() {
+ static QPluginLoader qkrcodecsLoader( "qkrcodecs" );
+ static QPluginLoader qcncodecsLoader( "qcncodecs" );
+ static QPluginLoader qjpcodecsLoader( "qjpcodecs" );
+ static QPluginLoader qtwcodecsLoader( "qtwcodecs" );
+ static QPluginLoader qjpegLoader("qjpeg");
+ static QPluginLoader qgifLoader("qgif");
+ static QPluginLoader qmngLoader("qmng");
+
+ qkrcodecsLoader.load();
+ qcncodecsLoader.load();
+ qjpcodecsLoader.load();
+ qtwcodecsLoader.load();
+ qjpegLoader.load();
+ qgifLoader.load();
+ qmngLoader.load();
+ }
+#endif
+
+#include <QApplication>
+#include <QTranslator>
+#include <QFontDatabase>
+#include <QTextCodec>
+
+#include "fqterm.h"
+#include "fqterm_app.h"
+#include "fqterm_frame.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_text_line.h"
+
+
+
+
+int main(int argc, char **argv) {
+#if defined(WIN32)
+#else
+ QApplication::setGraphicsSystem("raster");
+#endif
+ FQTerm::FQTermApplication a(argc, argv);
+ // Set trace categories and level.
+ FQTerm::setMaxTraceLevel(1);
+ for (int i = 1; i < argc; ++i) {
+ QString str(argv[i]);
+ bool ok;
+ int max_level = str.toInt(&ok, 0);
+
+ if (ok) {
+ FQTerm::setMaxTraceLevel(max_level);
+ } else {
+ FQTerm::addAllowedCategory(argv[i]);
+ }
+ }
+
+ using namespace FQTerm;
+
+ loadNecessaryQtPlugins();
+
+ // char buf[] = "\xc8\xb8";
+ // QString ucs2 = QTextCodec::codecForName("Big5")->toUnicode(buf);
+ // QVector<uint> ucs4 = ucs2.toUcs4();
+ // QByteArray utf8 = ucs2.toUtf8();
+ // const char *utf8c = utf8.constData();
+
+ // FQ_TRACE("text", 0) << "\n" << dumpHexString << std::string(buf, sizeof(buf) - 1)
+ // << dumpNormalString << " \n-->"
+ // << dumpNormalString << "\nucs4 " << ucs4.size() << " " << ucs4[0]
+ // << dumpNormalString << "\nucs2 " << ucs2.size() << " " << ucs2.at(0).unicode()
+ // << dumpNormalString << "\nutf8 " << dumpHexString << utf8c;
+ //return 0;
+
+ if (!iniSettings()) {
+ return -1;
+ }
+
+ FQTermFrame *mw = new FQTermFrame();
+ mw->setWindowTitle("FQTerm " + QString(FQTERM_VERSION_STRING));
+ mw->setWindowIcon(QPixmap(getPath(RESOURCE) + "pic/fqterm.png"));
+ mw->show();
+ a.setQuitOnLastWindowClosed(false);
+ FQ_VERIFY(a.connect(mw, SIGNAL(destroyed(QObject*)), &a, SLOT(mainWindowDestroyed(QObject*)), Qt::QueuedConnection));
+ FQ_VERIFY(a.connect(&a, SIGNAL(saveData()), mw, SLOT(saveSetting())));
+ int res = a.exec();
+ return res;
+}
diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt
new file mode 100644
index 0000000..c515590
--- /dev/null
+++ b/src/protocol/CMakeLists.txt
@@ -0,0 +1,65 @@
+set(export_SRCS
+ fqterm_socket.cpp
+ fqterm_socket.h
+ fqterm_ssh_socket.h
+ fqterm_ssh_socket.cpp
+)
+
+set(internal_SRCS
+ internal/crc32.h
+ internal/fqterm_serialization.h
+ internal/fqterm_ssh_auth.h
+ internal/fqterm_ssh_buffer.h
+ internal/fqterm_ssh_cipher.h
+ internal/fqterm_ssh_const.h
+ internal/fqterm_ssh_des.h
+ internal/fqterm_ssh_hash.h
+ internal/fqterm_ssh_kex.h
+ internal/fqterm_ssh2_kex.h
+ internal/fqterm_ssh_mac.h
+ internal/fqterm_ssh_md5.h
+ internal/fqterm_ssh_packet.h
+ internal/fqterm_ssh1_packet.h
+ internal/fqterm_ssh2_packet.h
+ internal/fqterm_ssh_rsa.h
+ internal/fqterm_ssh_channel.h
+ internal/fqterm_ssh_types.h
+ internal/fqterm_ssh_pubkey.h
+ internal/crc32.cpp
+ internal/fqterm_ssh_auth.cpp
+ internal/fqterm_ssh_buffer.cpp
+ internal/fqterm_ssh_des.cpp
+ internal/fqterm_ssh_kex.cpp
+ internal/fqterm_ssh2_kex.cpp
+ internal/fqterm_ssh_mac.cpp
+ internal/fqterm_ssh_md5.cpp
+ internal/fqterm_ssh_packet.cpp
+ internal/fqterm_ssh1_packet.cpp
+ internal/fqterm_ssh2_packet.cpp
+ internal/fqterm_ssh_rsa.cpp
+ internal/fqterm_ssh_channel.cpp
+)
+
+qt4_automoc(
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${OPENSSL_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/internal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_protocol
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+add_dependencies(fqterm_protocol
+ fqterm_common
+)
diff --git a/src/protocol/fqterm_socket.cpp b/src/protocol/fqterm_socket.cpp
new file mode 100644
index 0000000..131044a
--- /dev/null
+++ b/src/protocol/fqterm_socket.cpp
@@ -0,0 +1,672 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <QByteArray>
+#include <QTcpSocket>
+#include <QProcess>
+
+#include "fqterm.h"
+#include "fqterm_socket.h"
+#include "fqterm_trace.h"
+
+#if !defined(Q_OS_BSD4) && !defined(_OS_FREEBSD_) \
+ && !defined(Q_OS_MACX) && !defined(Q_OS_DARWIN)
+#include <malloc.h>
+#endif
+
+namespace FQTerm {
+
+/* hack from wget/http.c */
+#define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
+static void base64_encode(const char *s, char *store, int length);
+static char *basic_authentication_encode(const char *user, const char *passwd,
+ const char *header);
+static int parse_http_status_line(const char *line, const char
+ **reason_phrase_ptr);
+
+const char wingate_enter = 'J' &0x1f;
+
+//==============================================================================
+//FQTermSocketPrivate
+
+//==============================================================================
+FQTermSocketPrivate::FQTermSocketPrivate(QObject *parent)
+ : QObject(parent) {
+ m_socket = new QTcpSocket(this);
+
+ // proxy related
+ proxy_type = NOPROXY;
+ proxy_state = 0;
+ bauth = false;
+
+ FQ_VERIFY(connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected())));
+ FQ_VERIFY(connect(m_socket, SIGNAL(hostFound()), this, SIGNAL(hostFound())));
+ FQ_VERIFY(connect(m_socket, SIGNAL(disconnected()), this, SIGNAL(connectionClosed())));
+
+ FQ_VERIFY(connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead())));
+ FQ_VERIFY(connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
+}
+
+FQTermSocketPrivate::~FQTermSocketPrivate() {
+ delete m_socket;
+}
+
+void FQTermSocketPrivate::setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ proxy_type = nProxyType;
+ if (proxy_type == NOPROXY) {
+ return ;
+ }
+ bauth = bAuth;
+ proxy_host = strProxyHost;
+ proxy_port = uProxyPort;
+ proxy_usr = strProxyUsr;
+ proxy_pwd = strProxyPwd;
+}
+
+void FQTermSocketPrivate::socketConnected() {
+ QByteArray strPort;
+ QByteArray command(9, 0);
+
+ char *proxyauth;
+ char *request;
+ int len = 0;
+
+ switch (proxy_type) {
+ case NOPROXY:
+ // no proxy
+ emit connected();
+ return ;
+ case WINGATE:
+ // Wingate Proxy
+ strPort.setNum(port);
+ writeBlock(host.toLocal8Bit());
+ writeBlock(" ");
+ writeBlock(strPort);
+ writeBlock(&wingate_enter); // CTRL+J
+ emit socketState(TSHOSTCONNECTED);
+ return ;
+ case SOCKS4:
+ // Socks4 Proxy
+ command.resize(9);
+ command[0] = '\x04';
+ command[1] = '\x01';
+ memcpy(command.data() + 2, &addr_host.sin_port, 2);
+ memcpy(command.data() + 4, &addr_host.sin_addr, 4);
+ writeBlock(command);
+ proxy_state = 1;
+ emit socketState(TSPROXYCONNECTED);
+ return ;
+ case SOCKS5:
+ // Socks5 Proxy
+ if (bauth) {
+ command.resize(4);
+ command[0] = '\x05';
+ command[1] = '\x02';
+ command[2] = '\x02';
+ command[3] = '\x00';
+ writeBlock(command);
+ }
+ else {
+ command.resize(3);
+ command[0] = '\x05';
+ command[1] = '\x01';
+ command[2] = '\x00';
+ writeBlock(command);
+ }
+ proxy_state = 1;
+ emit socketState(TSPROXYCONNECTED);
+ return ;
+ case HTTP:
+ proxyauth = NULL;
+ if (bauth) {
+ proxyauth = basic_authentication_encode(proxy_usr.toLocal8Bit(),
+ proxy_pwd.toLocal8Bit(), "Proxy-Authorization");
+ }
+
+ len = proxyauth != NULL ? strlen(proxyauth): 0;
+
+ request = new char[host.length() + len + 81];
+
+ sprintf(request, "CONNECT %s:%u HTTP/1.0\r\n""%s\r\n", host.toLatin1().constData(), port,
+ proxyauth != NULL ? proxyauth : "");
+
+
+ writeBlock(request);
+ delete [] request;
+ free(proxyauth);
+ proxy_state = 1;
+ emit socketState(TSPROXYCONNECTED);
+ return ;
+ default:
+ emit socketState(TSHOSTCONNECTED);
+ return ;
+ }
+}
+
+void FQTermSocketPrivate::socketReadyRead() {
+ if (proxy_type == NOPROXY || proxy_state == 0) {
+ emit readyRead();
+ }
+
+ int nbytes, nread;
+ QByteArray from_socket;
+ // get the data size
+ nbytes = bytesAvailable();
+ if (nbytes <= 0) {
+ return ;
+ }
+
+ //resize input buffer
+ from_socket.resize(0);
+
+ //read data from socket to from_socket
+ from_socket = readBlock(nbytes);
+ nread = from_socket.size();
+ //do some checks
+ if (nread <= 0) {
+ FQ_TRACE("socket", 0) << "Failed to read socket: " << nread << " <= 0";
+ return ;
+ }
+ if (nread > nbytes) {
+ FQ_TRACE("socket", 0) << "Overflow when reading socket: "
+ << " nread = " << nread
+ << " > nbytes = " << nbytes;
+ return ;
+ }
+
+ // Socks4 Proxy Reply
+ if (proxy_type == SOCKS4 && proxy_state == 1) {
+ if (nread != 8) {
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+
+ if (from_socket.at(1) == 90) {
+ emit connected();
+ } else {
+ emit socketState(TSPROXYFAIL);
+ }
+ proxy_state = 0;
+ return ;
+ }
+
+ // HTTP Proxy Reply
+ if (proxy_type == HTTP && proxy_state != 0) {
+ const char *error;
+ int statcode = parse_http_status_line(from_socket.data(), &error);
+ if (statcode >= 200 && statcode < 300) {
+ emit connected();
+ } else {
+ emit socketState(TSPROXYFAIL);
+ }
+ proxy_state = 0;
+ return ;
+ }
+
+ // Socks5 Proxy Reply
+ if (proxy_type == SOCKS5 && proxy_state != 0) {
+ socks5_reply(from_socket, nread);
+ return ;
+ }
+}
+
+void FQTermSocketPrivate::flush() {
+ m_socket->flush();
+}
+
+/////////////////////////////////////////////////////
+//originally version from qhostaddress.cpp, qt4.3.2, --dp
+static bool isIp4(const QString& address)
+{
+ QStringList ipv4 = address.split(QLatin1String("."));
+ if (ipv4.count() != 4)
+ return false;
+
+ for (int i = 0; i < 4; ++i) {
+ bool ok = false;
+ uint byteValue = ipv4.at(i).toUInt(&ok);
+ if (!ok || byteValue > 255)
+ return false;
+
+ }
+
+ return true;
+}
+/////////////////////////////////////////////////////////
+
+void FQTermSocketPrivate::connectToHost(const QString &hostname, quint16 portnumber) {
+ host = hostname;
+ port = portnumber;
+ addr_host.sin_port = htons(portnumber);
+
+ if (proxy_type == NOPROXY) {
+ m_socket->connectToHost(host, port);
+ } else {
+ //get ip addr from name
+ struct hostent *hostent;
+#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
+ WSADATA wsd;
+ if (WSAStartup(0x202, &wsd) != 0) {
+ emit socketState(TSEINIWINSOCK);
+ WSACleanup();
+ return ;
+ }
+#endif
+ // QHostAddress ha(host);
+ //ipv4 address check -- dp
+ if(isIp4(host)) {
+ hostent = gethostbyaddr( host.toLocal8Bit(), host.length(), AF_INET );
+ FQ_TRACE("ssh", 1) << "by addr";
+ } else {
+ hostent = gethostbyname(host.toLocal8Bit());
+ FQ_TRACE("ssh", 1) << "by name";
+ }
+
+ if (hostent == NULL) {
+ emit socketState(TSEGETHOSTBYNAME);
+ return ;
+ }
+ //now only ipv4 support
+ memcpy(&addr_host.sin_addr, hostent->h_addr, 4);
+ m_socket->connectToHost(proxy_host, proxy_port);
+ }
+
+}
+
+void FQTermSocketPrivate::close() {
+ m_socket->close();
+}
+
+QByteArray FQTermSocketPrivate::readBlock(unsigned long maxlen) {
+ return m_socket->read(maxlen);
+}
+
+long FQTermSocketPrivate::writeBlock(const QByteArray &data) {
+ return m_socket->write(data);
+}
+
+unsigned long FQTermSocketPrivate::bytesAvailable() {
+ return m_socket->bytesAvailable();
+}
+
+/*------------------------------------------------------------------------
+ * connect command for socks5
+ *------------------------------------------------------------------------
+ */
+void FQTermSocketPrivate::socks5_connect() {
+ QByteArray command(10, 0);
+ command[0] = '\x05';
+ command[1] = '\x01';
+ command[2] = '\x00';
+ command[3] = '\x01';
+ memcpy(command.data() + 4, &addr_host.sin_addr, 4);
+ memcpy(command.data() + 8, &addr_host.sin_port, 2);
+ writeBlock(command);
+}
+
+/*------------------------------------------------------------------------
+ * authentation command for socks5
+ *------------------------------------------------------------------------
+ */
+void FQTermSocketPrivate::socks5_auth() {
+ int ulen = proxy_usr.length();
+ int plen = proxy_pwd.length();
+ QByteArray command(3+ulen + plen, 0);
+ sprintf((char*)command.data(), " %s %s", proxy_usr.toLocal8Bit().data(),
+ proxy_pwd.toLocal8Bit().data());
+ command[0] = '\x01';
+ command[1] = ulen;
+ command[2+ulen] = plen;
+ writeBlock(command);
+}
+
+/*------------------------------------------------------------------------
+ * reply from socks5
+ *------------------------------------------------------------------------
+ */
+void FQTermSocketPrivate::socks5_reply(const QByteArray &from_socket, int nread) {
+ if (proxy_state == 1) { // Socks5 Proxy Replay 1
+ if (nread != 2) {
+ proxy_state = 0;
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+ switch (from_socket.at(1)) {
+ case '\x00':
+ // no authentation needed
+ socks5_connect();
+ proxy_state = 3;
+ emit socketState(TSCONNECTVIAPROXY);
+ return ;
+ case '\x02':
+ //need user/password
+ socks5_auth();
+ proxy_state = 2;
+ emit socketState(TSPROXYAUTH);
+ return ;
+ case '\xff':
+ proxy_state = 0;
+ emit socketState(TSPROXYFAIL);
+ return ;
+ default:
+ proxy_state = 0;
+ emit socketState(TSPROXYFAIL);
+ return ;
+ }
+ } else if (proxy_state == 2) { //Socks5 Proxy Replay 2
+ if (nread != 2) {
+ proxy_state = 0;
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+
+
+ if (from_socket.at(1) != '\00') {
+ proxy_state = 0;
+ emit socketState(TSPROXYFAIL);
+ return ;
+ }
+ socks5_connect();
+ proxy_state = 3;
+ emit socketState(TSCONNECTVIAPROXY);
+ return ;
+ } else if (proxy_state == 3) { //Socks5 Proxy Replay 3
+ proxy_state = 0;
+ if (nread != 10) {
+ emit socketState(TSPROXYERROR);
+ return ;
+ }
+ if (from_socket.at(1) != '\00') {
+ emit socketState(TSPROXYFAIL);
+ return ;
+ }
+ emit connected();
+ return ;
+ } else {
+ proxy_state = 0;
+ return ;
+ }
+}
+
+/* hack from wget/http.c */
+/* How many bytes it will take to store LEN bytes in base64. */
+#define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
+
+/* Encode the string S of length LENGTH to base64 format and place it
+ to STORE. STORE will be 0-terminated, and must point to a writable
+ buffer of at least 1+BASE64_LENGTH(length) bytes. */
+static void base64_encode(const char *s, char *store, int length) {
+ /* Conversion table. */
+ static char tbl[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/'
+ };
+ int i;
+ unsigned char *p = (unsigned char*)store;
+
+ /* Transform the 3x8 bits to 4x6 bits, as required by base64. */
+ for (i = 0; i < length; i += 3) {
+ *p++ = tbl[s[0] >> 2];
+ *p++ = tbl[((s[0] &3) << 4) + (s[1] >> 4)];
+ *p++ = tbl[((s[1] &0xf) << 2) + (s[2] >> 6)];
+ *p++ = tbl[s[2] &0x3f];
+ s += 3;
+ }
+ /* Pad the result if necessary... */
+ if (i == length + 1) {
+ *(p - 1) = '=';
+ } else if (i == length + 2) {
+ *(p - 1) = *(p - 2) = '=';
+ }
+ /* ...and zero-terminate it. */
+ *p = '\0';
+}
+
+/* Create the authentication header contents for the `Basic' scheme.
+ This is done by encoding the string `USER:PASS' in base64 and
+ prepending `HEADER: Basic ' to it. */
+static char *basic_authentication_encode(const char *user, const char *passwd,
+ const char *header) {
+ char *t1, *t2, *res;
+ int len1 = strlen(user) + 1+strlen(passwd);
+ int len2 = BASE64_LENGTH(len1);
+
+ t1 = (char*)alloca(len1 + 1);
+ sprintf(t1, "%s:%s", user, passwd);
+ t2 = (char*)alloca(1+len2);
+ base64_encode(t1, t2, len1);
+ res = (char*)malloc(len2 + 11+strlen(header));
+ sprintf(res, "%s: Basic %s\r\n", header, t2);
+
+ return res;
+}
+
+/* Parse the HTTP status line, which is of format:
+
+ HTTP-Version SP Status-Code SP Reason-Phrase
+
+ The function returns the status-code, or -1 if the status line is
+ malformed. The pointer to reason-phrase is returned in RP. */
+static int parse_http_status_line(const char *line, const char
+ **reason_phrase_ptr) {
+ /* (the variables must not be named `major' and `minor', because
+ that breaks compilation with SunOS4 cc.) */
+ int mjr, mnr, statcode;
+ const char *p;
+
+ *reason_phrase_ptr = NULL;
+
+ /* The standard format of HTTP-Version is: `HTTP/X.Y', where X is
+ major version, and Y is minor version. */
+ if (strncmp(line, "HTTP/", 5) != 0) {
+ return -1;
+ }
+ line += 5;
+
+ /* Calculate major HTTP version. */
+ p = line;
+ for (mjr = 0; QChar(*line).isDigit(); line++) {
+ mjr = 10 * mjr + (*line - '0');
+ }
+ if (*line != '.' || p == line) {
+ return -1;
+ }
+ ++line;
+
+ /* Calculate minor HTTP version. */
+ p = line;
+ for (mnr = 0; QChar(*line).isDigit(); line++) {
+ mnr = 10 * mnr + (*line - '0');
+ }
+ if (*line != ' ' || p == line) {
+ return -1;
+ }
+ /* Wget will accept only 1.0 and higher HTTP-versions. The value of
+ minor version can be safely ignored. */
+ if (mjr < 1) {
+ return -1;
+ }
+ ++line;
+
+ /* Calculate status code. */
+ if (!(QChar(*line).isDigit() && QChar(line[1]).isDigit() && QChar(line[2])
+ .isDigit())) {
+ return -1;
+ }
+ statcode = 100 *(*line - '0') + 10 *(line[1] - '0') + (line[2] - '0');
+
+ /* Set up the reason phrase pointer. */
+ line += 3;
+ /* RFC2068 requires SPC here, but we allow the string to finish
+ here, in case no reason-phrase is present. */
+ if (*line != ' ') {
+ if (! *line) {
+ *reason_phrase_ptr = line;
+ } else {
+ return -1;
+ }
+ } else {
+ *reason_phrase_ptr = line + 1;
+ }
+
+ return statcode;
+}
+
+
+//==============================================================================
+//FQTermTelnetSocket
+//==============================================================================
+
+FQTermTelnetSocket::FQTermTelnetSocket()
+ : FQTermSocket() {
+ private_socket_ = new FQTermSocketPrivate();
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connected()), this, SIGNAL(connected())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(hostFound()), this, SIGNAL(hostFound())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connectionClosed()), this, SIGNAL(connectionClosed())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(delayedCloseFinished()),
+ this, SIGNAL(delayedCloseFinished())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(readyRead()), this, SIGNAL(readyRead())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+}
+
+FQTermTelnetSocket::~FQTermTelnetSocket() {
+ delete private_socket_;
+}
+
+void FQTermTelnetSocket::flush() {
+ private_socket_->flush();
+}
+
+void FQTermTelnetSocket::setProxy(int nProxyType, bool bAuth,
+ const QString &strProxyHost,
+ quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ private_socket_->setProxy(nProxyType, bAuth, strProxyHost, uProxyPort, strProxyUsr,
+ strProxyPwd);
+}
+
+void FQTermTelnetSocket::connectToHost(const QString &host, quint16 port) {
+ private_socket_->connectToHost(host, port);
+}
+
+void FQTermTelnetSocket::close() {
+ private_socket_->close();
+}
+
+QByteArray FQTermTelnetSocket::readBlock(unsigned long maxlen) {
+ return private_socket_->readBlock(maxlen);
+}
+
+long FQTermTelnetSocket::writeBlock(const QByteArray &data) {
+ return private_socket_->writeBlock(data);
+}
+
+unsigned long FQTermTelnetSocket::bytesAvailable() {
+ return private_socket_->bytesAvailable();
+}
+
+
+FQTermLocalSocket::FQTermLocalSocket( const QString& shell_bin ) : shell_bin_(shell_bin)
+{
+ shell_process_ = new QProcess();
+ shell_process_->setProcessChannelMode(QProcess::MergedChannels);
+ FQ_VERIFY(connect(shell_process_, SIGNAL(started()), this, SIGNAL(connected())));
+ FQ_VERIFY(connect(shell_process_, SIGNAL(stateChanged(QProcess::ProcessState)), this , SLOT(stateChanged(QProcess::ProcessState))));
+ FQ_VERIFY(connect(shell_process_, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus))));
+ //FQ_VERIFY(connect(shell_process_, SIGNAL(delayedCloseFinished()), this, SIGNAL(delayedCloseFinished())));
+ FQ_VERIFY(connect(shell_process_, SIGNAL(readyRead()), this, SIGNAL(readyRead())));
+ //TODO: Error
+ //FQ_VERIFY(connect(shell_process_, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
+ //FQ_VERIFY(connect(shell_process_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+}
+
+FQTermLocalSocket::~FQTermLocalSocket()
+{
+ delete shell_process_;
+}
+
+void FQTermLocalSocket::connectToHost( const QString &host, quint16 port )
+{
+ shell_process_->start("E:/yxl/test.exe"/*C:/Windows/System32/cmd.exeshell_bin*/, QIODevice::ReadWrite | QIODevice::Unbuffered);
+}
+
+void FQTermLocalSocket::close()
+{
+ shell_process_->close();
+}
+
+QByteArray FQTermLocalSocket::readBlock( unsigned long maxlen )
+{
+ return shell_process_->read(maxlen);
+}
+
+long FQTermLocalSocket::writeBlock( const QByteArray &data )
+{
+ int count = shell_process_->write(data);
+
+ //char c;
+// shell_process_->getChar(&c);
+// shell_process_->ungetChar(c);
+ if (bytesAvailable())
+ {
+ emit readyRead();
+ }
+ return count;
+}
+
+unsigned long FQTermLocalSocket::bytesAvailable()
+{
+ return shell_process_->bytesAvailable();
+}
+
+void FQTermLocalSocket::finished( int exitCode, QProcess::ExitStatus exitStatus )
+{
+ emit connectionClosed();
+}
+void FQTermLocalSocket::stateChanged(QProcess::ProcessState newState)
+{
+ switch(newState)
+ {
+ case QProcess::NotRunning:
+ break;
+ case QProcess::Starting:
+ emit hostFound();
+ shell_process_->write("dir\n");
+ break;
+ case QProcess::Running:
+ break;
+
+ }
+}
+
+
+} // namespace FQTerm
+
+#include "fqterm_socket.moc"
diff --git a/src/protocol/fqterm_socket.h b/src/protocol/fqterm_socket.h
new file mode 100644
index 0000000..2d6240b
--- /dev/null
+++ b/src/protocol/fqterm_socket.h
@@ -0,0 +1,196 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SOCKET_H
+#define FQTERM_SOCKET_H
+
+// _OS_X_ not defined if i dont include it
+#include <QGlobalStatic>
+
+// different
+#if defined(Q_OS_WIN32) || defined(_OS_WIN32_)
+
+#include <winsock2.h>
+
+#elif defined(Q_OS_BSD4) || defined(_OS_FREEBSD_) \
+ || defined(Q_OS_MACX) || defined(Q_OS_DARWIN)
+
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#else
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+
+#endif
+
+#include <QAbstractSocket>
+#include <QString>
+#include <QStringList>
+#include <QProcess>
+
+class QTcpSocket;
+namespace FQTerm {
+/*
+ * Socket with proxy support.
+ *
+ */
+class FQTermSocketPrivate: public QObject {
+
+ Q_OBJECT;
+ public:
+ FQTermSocketPrivate(QObject *parent_ = 0);
+
+ ~FQTermSocketPrivate();
+
+ void flush();
+ void setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+ void connectToHost(const QString &hostname, quint16 portnumber);
+ void close();
+ QByteArray readBlock(unsigned long maxlen);
+ long writeBlock(const QByteArray &data);
+ unsigned long bytesAvailable();
+
+ signals:
+ void connected();
+ void hostFound();
+ void connectionClosed();
+ void delayedCloseFinished();
+ void readyRead();
+ void error(QAbstractSocket::SocketError);
+ void socketState(int);
+
+ protected slots:
+ void socketConnected();
+ void socketReadyRead();
+
+ protected:
+ // socks5 function
+ void socks5_connect();
+ void socks5_auth();
+ void socks5_reply(const QByteArray &, int);
+
+ private:
+ // proxy
+ int proxy_type;
+ QString proxy_host;
+ QString proxy_usr;
+ quint16 proxy_port;
+ QString proxy_pwd;
+ QString host;
+ quint16 port;
+ int proxy_state;
+ bool bauth;
+
+ struct sockaddr_in addr_host;
+
+ QTcpSocket *m_socket;
+};
+
+// Virtual base class for FQTermTelnetSocket and FQTermSSHSocket
+class FQTermSocket: public QObject {
+
+ Q_OBJECT;
+ public:
+ FQTermSocket(QObject *parent = 0): QObject(parent) {}
+
+ virtual ~FQTermSocket() {}
+
+ virtual void flush() = 0;
+ virtual void setProxy(int nProxyType, bool bAuth,
+ const QString &strProxyHost,
+ quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) = 0;
+ virtual void connectToHost(const QString &host, quint16 port) = 0;
+ virtual void close() = 0;
+ virtual QByteArray readBlock(unsigned long maxlen) = 0;
+ virtual long writeBlock(const QByteArray &data) = 0;
+ virtual unsigned long bytesAvailable() = 0;
+ virtual bool readyForInput() {return true;}
+ virtual bool setTermSize(int col, int row) {return 0;}
+ signals:
+ void sshAuthOK();
+ void connected();
+ void hostFound();
+ void connectionClosed();
+ void delayedCloseFinished();
+ void readyRead();
+ void error(QAbstractSocket::SocketError);
+ void errorMessage(QString);
+ void socketState(int);
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+};
+
+class FQTermTelnetSocket: public FQTermSocket {
+ private:
+ FQTermSocketPrivate *private_socket_;
+
+ public:
+ FQTermTelnetSocket();
+
+ ~FQTermTelnetSocket();
+
+ void flush();
+ void setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+ void connectToHost(const QString &host, quint16 port);
+ void close();
+ QByteArray readBlock(unsigned long maxlen);
+ long writeBlock(const QByteArray &data);
+ unsigned long bytesAvailable();
+};
+
+class FQTermLocalSocket: public FQTermSocket {
+ Q_OBJECT;
+private:
+ QString shell_bin_;
+ QProcess* shell_process_;
+public:
+ FQTermLocalSocket(const QString& shell_bin);
+ ~FQTermLocalSocket();
+ void flush(){}
+ void setProxy(int nProxyType, bool bAuth, const QString &strProxyHost,
+ quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd){}
+ void connectToHost(const QString &host, quint16 port);
+ void close();
+ QByteArray readBlock(unsigned long maxlen);
+ long writeBlock(const QByteArray &data);
+ unsigned long bytesAvailable();
+
+public slots:
+ void stateChanged(QProcess::ProcessState newState);
+ void finished (int exitCode, QProcess::ExitStatus exitStatus);
+};
+
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_SOCKET_H
diff --git a/src/protocol/fqterm_ssh_socket.cpp b/src/protocol/fqterm_ssh_socket.cpp
new file mode 100644
index 0000000..4c1e77a
--- /dev/null
+++ b/src/protocol/fqterm_ssh_socket.cpp
@@ -0,0 +1,352 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_socket.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh1_packet.h"
+#include "fqterm_ssh2_packet.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh_rsa.h"
+#include "fqterm_ssh_kex.h"
+#include "fqterm_ssh2_kex.h"
+#include "fqterm_ssh_const.h"
+#include "fqterm_ssh_auth.h"
+#include "fqterm_ssh_channel.h"
+#include "fqterm_trace.h"
+#include <QString>
+namespace FQTerm {
+
+#define V1STR "SSH-1.5-FQTermSSH\n"
+#define V2STR "SSH-2.0-FQTermSSH\n"
+#define SSH_V1_C "SSH-1.5-FQTermSSH"
+#define SSH_V2_C "SSH-2.0-FQTermSSH"
+
+FQTermSSHSocket::FQTermSSHSocket(int col, int row, const QString& termtype, const char *sshuser, const char *sshpasswd)
+ : termtype_(termtype) {
+ col_ = col;
+ row_ = row;
+ init_user_ = sshuser;
+ init_passwd_ = sshpasswd;
+
+ private_socket_ = new FQTermSocketPrivate();
+
+ input_buffer_ = NULL;
+ output_buffer_ = NULL;
+ socket_buffer_ = NULL;
+ packet_receiver_ = NULL;
+ packet_sender_ = NULL;
+ key_exchanger_ = NULL;
+ authentication_ = NULL;
+ ssh_channel_ = NULL;
+ ssh_version_ = 1;
+ is_channel_ok_ = false;
+ auth_ok_emitted_ = false;
+
+ FQ_VERIFY(connect(private_socket_, SIGNAL(hostFound()), this, SIGNAL(hostFound())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connected()), this, SIGNAL(connected())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(connectionClosed()), this, SIGNAL(connectionClosed())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(delayedCloseFinished()), this, SIGNAL(delayedCloseFinished())));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(error(QAbstractSocket::SocketError )), this, SIGNAL(error(QAbstractSocket::SocketError ))));
+ FQ_VERIFY(connect(private_socket_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+
+ FQ_VERIFY(connect(private_socket_, SIGNAL(readyRead()), this, SLOT(socketReadyRead())));
+}
+
+FQTermSSHSocket::~FQTermSSHSocket() {
+ delete private_socket_;
+ delete input_buffer_;
+ delete output_buffer_;
+ delete socket_buffer_;
+ delete packet_receiver_;
+ delete packet_sender_;
+ delete key_exchanger_;
+ delete authentication_;
+ delete ssh_channel_;
+}
+
+void FQTermSSHSocket::init(int ssh_version) {
+ // Actually we could reuse these buffers, sender/receivers, and etc.
+ // but in that case reset methods should be added to all these classes.
+ // Guys lazy as me won't do that.
+
+ delete input_buffer_;
+ delete output_buffer_;
+ delete socket_buffer_;
+ delete packet_receiver_;
+ delete packet_sender_;
+ delete key_exchanger_;
+ delete authentication_;
+ delete ssh_channel_;
+
+ is_channel_ok_ = false;
+ auth_ok_emitted_ = false;
+
+ if (ssh_version == 1) {
+ input_buffer_ = new FQTermSSHBuffer(1024);
+ output_buffer_ = new FQTermSSHBuffer(1024);
+ socket_buffer_ = new FQTermSSHBuffer(1024);
+ packet_receiver_ = new FQTermSSH1PacketReceiver;
+ packet_sender_ = new FQTermSSH1PacketSender;
+ key_exchanger_ = new FQTermSSH1Kex(SSH_V1_C, server_name_.toAscii().constData());
+ authentication_ = new FQTermSSH1PasswdAuth(init_user_, init_passwd_);
+ ssh_channel_ = new FQTermSSH1Channel;
+
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(packet_sender_, SIGNAL(dataToWrite()), this, SLOT(writeData())));
+
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexOK()), this, SLOT(kexOK())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexError(QString)), this, SLOT(handleError(QString))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_receiver_, SLOT(resetEncryption())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_sender_, SLOT(resetEncryption())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_receiver_, SLOT(startEncryption(const u_char*))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_sender_, SLOT(startEncryption(const u_char*))));
+
+ FQ_VERIFY(connect(authentication_, SIGNAL(requestUserPwd(QString *, QString *, bool *)), this, SIGNAL(requestUserPwd(QString *, QString *, bool *))));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authOK()), this, SLOT(authOK())));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelOK()), this, SLOT(channelOK())));
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelReadyRead(const char *, int)), this, SLOT(channelReadyRead(const char *, int))));
+
+ key_exchanger_->initKex(packet_receiver_, packet_sender_);
+ } else {
+ input_buffer_ = new FQTermSSHBuffer(1024);
+ output_buffer_ = new FQTermSSHBuffer(1024);
+ socket_buffer_ = new FQTermSSHBuffer(1024);
+ packet_receiver_ = new FQTermSSH2PacketReceiver;
+ packet_sender_ = new FQTermSSH2PacketSender;
+ key_exchanger_ = new FQTermSSH2Kex(SSH_V2_C, server_name_.toAscii().constData());
+ authentication_ = new FQTermSSH2PasswdAuth(init_user_, init_passwd_);
+ ssh_channel_ = new FQTermSSH2Channel;
+
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(packet_sender_, SIGNAL(dataToWrite()), this, SLOT(writeData())));
+
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexOK()), this, SLOT(kexOK())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(kexError(QString)), this, SLOT(handleError(QString))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_receiver_, SLOT(resetEncryption())));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(reKex()), packet_sender_, SLOT(resetEncryption())));
+
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_receiver_, SLOT(startEncryption(const u_char*))));
+ FQ_VERIFY(connect(key_exchanger_, SIGNAL(startEncryption(const u_char*)), packet_sender_, SLOT(startEncryption(const u_char*))));
+
+ FQ_VERIFY(connect(authentication_, SIGNAL(requestUserPwd(QString *, QString *, bool *)), this, SIGNAL(requestUserPwd(QString *, QString *, bool *))));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authOK()), this, SLOT(authOK())));
+ FQ_VERIFY(connect(authentication_, SIGNAL(authError(QString)), this, SLOT(handleError(QString))));
+
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelOK()), this, SLOT(channelOK())));
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelReadyRead(const char *, int)), this, SLOT(channelReadyRead(const char *, int))));
+ FQ_VERIFY(connect(ssh_channel_, SIGNAL(channelError(QString)), this, SLOT(handleError(QString))));
+
+ key_exchanger_->initKex(packet_receiver_, packet_sender_);
+ }
+}
+
+void FQTermSSHSocket::kexOK() {
+ FQ_TRACE("sshsocket", 3) << "Key exchange completed!";
+ authentication_->initAuth(packet_receiver_, packet_sender_);
+}
+
+void FQTermSSHSocket::authOK() {
+ FQ_TRACE("sshsocket", 3) << "Auth completed!";
+ ssh_channel_->initChannel(packet_receiver_, packet_sender_, col_, row_, termtype_);
+}
+
+void FQTermSSHSocket::channelOK() {
+ FQ_TRACE("sshsocket", 3) << "Channel established!";
+ is_channel_ok_ = true;
+ //auth_ok_emitted_ = false;
+}
+
+void FQTermSSHSocket::channelReadyRead(const char *data, int len) {
+ input_buffer_->putRawData(data, len);
+ emit readyRead();
+}
+
+unsigned long FQTermSSHSocket::socketWriteBlock(const char *data, unsigned long len) {
+ QByteArray to_write(data, len);
+ return private_socket_->writeBlock(to_write);
+}
+
+void FQTermSSHSocket::socketReadyRead() {
+ if (!auth_ok_emitted_ && is_channel_ok_) {
+ auth_ok_emitted_ = true;
+ emit sshAuthOK();
+ }
+ unsigned long size;
+
+ switch (ssh_socket_state_) {
+ case BeforeSession:
+ {
+ QByteArray str;
+ int version;
+ size = private_socket_->bytesAvailable();
+ str = private_socket_->readBlock(size);
+
+ server_name_ = QString(str).trimmed(); // remove the newline
+ version = chooseVersion(str.data());
+
+ FQ_TRACE("sshsocket", 3) << "SSH server: " << server_name_;
+ FQ_TRACE("sshsocket", 3) << "SSH version chosen: " << version;
+
+ if (version == 1) {
+ init(1);
+ ssh_version_ = 1;
+ socketWriteBlock(V1STR, strlen(V1STR));
+ } else if (version == 2) {
+ init(2);
+ ssh_version_ = 2;
+ socketWriteBlock(V2STR, strlen(V2STR));
+ } else {
+ handleError(tr("Unknown SSH version. "
+ "Check if you set the right server and port."));
+ return ;
+ }
+ ssh_socket_state_ = SockSession;
+ private_socket_->flush();
+ break;
+ }
+ case SockSession:
+ parsePacket();
+ }
+}
+
+void FQTermSSHSocket::parsePacket() {
+ unsigned long size;
+ QByteArray data;
+ size = private_socket_->bytesAvailable();
+ data = private_socket_->readBlock(size);
+
+ socket_buffer_->putRawData(data.data(), size);
+ packet_receiver_->parseData(socket_buffer_);
+}
+
+int FQTermSSHSocket::chooseVersion(const QString &ver) {
+ QString verion = ver.mid(ver.indexOf("-") + 1);
+ verion = verion.left(verion.indexOf("-"));
+
+ if (verion == "1.99" || verion == "1.3" || verion == "1.5") {
+ return 1;
+ } else if (verion == "2.0") {
+ return 2;
+ } else {
+ return - 1;
+ }
+}
+
+void FQTermSSHSocket::connectToHost(const QString &host_name, quint16 port) {
+ ssh_socket_state_ = BeforeSession;
+ private_socket_->connectToHost(host_name, port);
+}
+
+void FQTermSSHSocket::writeData() {
+ socketWriteBlock((const char*)packet_sender_->output_buffer_->data(),
+ packet_sender_->output_buffer_->len());
+ private_socket_->flush();
+}
+
+void FQTermSSHSocket::handlePacket(int type) {
+ if (ssh_version_ == 1) {
+ switch (type) {
+ case SSH1_MSG_DISCONNECT:
+ char *reason;
+ reason = (char*)packet_receiver_->getString();
+ FQ_TRACE("sshsocket", 1) << "Disconnect because: " << reason;
+ delete [] reason;
+ break;
+ default:
+ return ;
+ }
+ } else {
+ // ssh_version_ == 2;
+ switch (type) {
+ case SSH2_MSG_DISCONNECT:
+ char *reason;
+ packet_receiver_->consume(4);
+ reason = (char*)packet_receiver_->getString();
+ FQ_TRACE("sshsocket", 1) << "Disconnect because: " << reason;
+ delete[] reason;
+ break;
+ default:
+ return ;
+ }
+ }
+}
+
+unsigned long FQTermSSHSocket::bytesAvailable() {
+ return input_buffer_->len();
+}
+
+QByteArray FQTermSSHSocket::readBlock(unsigned long size) {
+ QByteArray data(size, 0);
+ input_buffer_->getRawData(data.data(), size);
+ return data;
+}
+
+long FQTermSSHSocket::writeBlock(const QByteArray &data) {
+ if (!is_channel_ok_) return 0;
+
+ unsigned long size = data.size();
+ output_buffer_->putRawData(data.data(), size);
+ return size;
+}
+
+void FQTermSSHSocket::flush() {
+ if (!is_channel_ok_) return;
+
+ int size = output_buffer_->len();
+
+ ssh_channel_->sendData((const char *)output_buffer_->data(), size);
+
+ output_buffer_->consume(size);
+}
+
+void FQTermSSHSocket::close() {
+ private_socket_->close();
+}
+
+void FQTermSSHSocket::handleError(QString reason) {
+ close();
+
+ emit errorMessage(reason);
+ emit connectionClosed();
+}
+
+void FQTermSSHSocket::setProxy(int nProxyType, bool bAuth,
+ const QString &strProxyHost,
+ quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ private_socket_->setProxy(nProxyType, bAuth, strProxyHost,
+ uProxyPort, strProxyUsr, strProxyPwd);
+}
+
+bool FQTermSSHSocket::setTermSize(int col, int row) {
+ if (ssh_channel_ && is_channel_ok_)
+ ssh_channel_->changeTermSize(col, row);
+ return true;
+}
+} // namespace FQTerm
+
+#include "fqterm_ssh_socket.moc"
diff --git a/src/protocol/fqterm_ssh_socket.h b/src/protocol/fqterm_ssh_socket.h
new file mode 100644
index 0000000..aa6fef4
--- /dev/null
+++ b/src/protocol/fqterm_ssh_socket.h
@@ -0,0 +1,131 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_SOCKET_H
+#define FQTERM_SSH_SOCKET_H
+
+#include "fqterm_socket.h"
+
+
+namespace FQTerm {
+
+
+class FQTermSocketPrivate;
+
+class FQTermSSHPacketReceiver;
+
+class FQTermSSHPacketSender;
+
+class FQTermSSHBuffer;
+
+class FQTermSSHKex;
+
+class FQTermSSHAuth;
+
+class FQTermSSHChannel;
+
+
+class FQTermSSHSocket: public FQTermSocket {
+
+ Q_OBJECT;
+private:
+ enum FQTermSSHSocketState {
+
+ BeforeSession, SockSession
+ } ssh_socket_state_;
+
+ FQTermSocketPrivate *private_socket_;
+
+
+ FQTermSSHBuffer *input_buffer_;
+
+ FQTermSSHBuffer *output_buffer_;
+
+ FQTermSSHBuffer *socket_buffer_;
+
+
+ FQTermSSHPacketReceiver *packet_receiver_;
+
+ FQTermSSHPacketSender *packet_sender_;
+
+
+ FQTermSSHKex *key_exchanger_;
+
+ FQTermSSHAuth *authentication_;
+
+ FQTermSSHChannel *ssh_channel_;
+
+ bool is_channel_ok_;
+ bool auth_ok_emitted_;
+
+ QByteArray init_user_, init_passwd_;
+
+ QString server_name_;
+
+ int ssh_version_;
+ int col_;
+ int row_;
+ QString termtype_;
+ int chooseVersion(const QString &ver);
+ unsigned long socketWriteBlock(const char *data, unsigned long len);
+ void parsePacket();
+
+private slots:
+ void handlePacket(int type);
+ void writeData();
+ void kexOK();
+ void authOK();
+ void channelOK();
+ void channelReadyRead(const char *data, int len);
+ void socketReadyRead();
+ void handleError(QString);
+
+public:
+ FQTermSSHSocket(int col = 80, int row = 24, const QString& termtype = "vt100", const char *sshuser = NULL, const char *sshpasswd = NULL);
+
+ ~FQTermSSHSocket();
+
+
+ void setProxy(int nProxyType, //0-no proxy; 1-wingate; 2-sock4; 3-socks5
+ bool bAuth, // if authentation needed
+ const QString &strProxyHost, quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+
+ void connectToHost(const QString &host_name, quint16 port);
+
+ void init(int ssh_version);
+
+ QByteArray readBlock(unsigned long size);
+ long writeBlock(const QByteArray &data);
+
+ virtual bool readyForInput() {return is_channel_ok_;}
+ virtual bool setTermSize(int col, int row);
+ unsigned long bytesAvailable();
+
+ void flush();
+ void close();
+
+};
+
+} // namespace FQTerm
+
+
+#endif //FQTERM_SSH_SOCKET_H
+
diff --git a/src/protocol/internal/crc32.cpp b/src/protocol/internal/crc32.cpp
new file mode 100644
index 0000000..2039ac8
--- /dev/null
+++ b/src/protocol/internal/crc32.cpp
@@ -0,0 +1,84 @@
+/* $OpenBSD: crc32.c,v 1.9 2003/02/12 21:39:50 markus Exp $ */
+
+/*
+ * Copyright (c) 2003 Markus Friedl. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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 "crc32.h"
+
+namespace FQTerm {
+static const u_int32_t crc32tab[] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL,
+ 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
+ 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L,
+ 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
+ 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
+ 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL,
+ 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
+ 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L,
+ 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L,
+ 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
+ 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL,
+ 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
+ 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
+ 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L,
+ 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
+ 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL,
+ 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L,
+ 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
+ 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L,
+ 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
+ 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
+ 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL,
+ 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
+ 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L,
+ 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L,
+ 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
+ 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL,
+ 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
+ 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
+ 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L,
+ 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
+ 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL,
+ 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L,
+ 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
+ 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
+};
+
+u_int32_t ssh_crc32(const u_char *buf, u_int32_t size) {
+ u_int32_t i, crc;
+
+ crc = 0;
+ for (i = 0; i < size; i++) {
+ crc = crc32tab[(crc ^ buf[i]) &0xff] ^ (crc >> 8);
+ } return crc;
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/crc32.h b/src/protocol/internal/crc32.h
new file mode 100644
index 0000000..ca95b89
--- /dev/null
+++ b/src/protocol/internal/crc32.h
@@ -0,0 +1,37 @@
+/* $OpenBSD: crc32.h,v 1.14 2003/02/12 21:39:50 markus Exp $ */
+
+/*
+ * Copyright (c) 2003 Markus Friedl. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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 SSH_CRC32_H
+#define SSH_CRC32_H
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+u_int32_t ssh_crc32(const u_char *, u_int32_t);
+
+} // namespace FQTerm
+
+#endif
diff --git a/src/protocol/internal/fqterm_serialization.h b/src/protocol/internal/fqterm_serialization.h
new file mode 100644
index 0000000..7a858c0
--- /dev/null
+++ b/src/protocol/internal/fqterm_serialization.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SERIALIZATION_H
+#define FQTERM_SERIALIZATION_H
+
+#if defined(WIN32)
+typedef unsigned __int16 u_int16_t;
+#else
+#include <arpa/inet.h>
+#endif
+
+namespace FQTerm {
+
+inline u_int16_t ntohu16(const unsigned char *buf) {
+ return (buf[0] << 8) | buf[1];
+}
+
+inline u_int32_t ntohu32(const unsigned char *buf) {
+ return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+}
+
+inline void htonu32(unsigned char *buf, u_int32_t number) {
+ buf[0] = (number >> 24) & 0xFF;
+ buf[1] = (number >> 16) & 0xFF;
+ buf[2] = (number >> 8) & 0xFF;
+ buf[3] = number & 0xFF;
+}
+
+inline void htonu16(unsigned char *buf, u_int16_t number) {
+ buf[0] = (number >> 8 & 0xFF);
+ buf[1] = (number & 0xFF);
+}
+
+} // namespace FQTerm
+
+#endif // FQTERM_SERIALIZATION_H
diff --git a/src/protocol/internal/fqterm_ssh1_packet.cpp b/src/protocol/internal/fqterm_ssh1_packet.cpp
new file mode 100644
index 0000000..ded7fe4
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh1_packet.cpp
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh1_packet.h"
+#include "fqterm_ssh_des.h"
+
+#include "fqterm_serialization.h"
+#include "crc32.h"
+
+namespace FQTerm {
+//==============================================================================
+//FQTermSSH1PacketSender
+//==============================================================================
+//==============================================================================
+//
+// SSH1 Packet Structure:
+// --------------------------------------------------------------------------
+// | length | padding | type | data | crc32 |
+// --------------------------------------------------------------------------
+// | uint32 | 1-7bytes | uchar | | 4bytes|
+// --------------------------------------------------------------------------
+// encrypt = padding + type + data + crc32
+// length = type + data + crc32
+//
+//==============================================================================
+
+void FQTermSSH1PacketSender::makePacket() {
+ int len, padding, i;
+ u_int32_t rand_val = 0;
+
+ delete output_buffer_;
+
+ len = buffer_->len() + 4; //CRC32
+ padding = 8-(len % 8);
+
+ output_buffer_ = new FQTermSSHBuffer(len + padding + 4); //pktlen and crc32
+ output_buffer_->putInt(len);
+
+ for (i = 0; i < padding; i++) {
+ if (i % 4 == 0) {
+ rand_val = rand(); // FIXME: rand() doesn't range from 0 to 2^32.
+ }
+
+ output_buffer_->putByte(rand_val &0xff);
+ rand_val >>= 8;
+ }
+
+ output_buffer_->putRawData((const char*)buffer_->data(), buffer_->len());
+ output_buffer_->putInt(ssh_crc32(output_buffer_->data() + 4, output_buffer_->len() - 4));
+
+ if (is_encrypt_) {
+ cipher_->encrypt(output_buffer_->data() + 4, output_buffer_->data() + 4, output_buffer_->len() - 4);
+ }
+
+}
+
+//==============================================================================
+//FQTermSSH1PacketReceiver
+//==============================================================================
+void FQTermSSH1PacketReceiver::parseData(FQTermSSHBuffer *input) {
+ u_int mycrc, gotcrc;
+ u_char *buf = NULL;
+ u_char *targetData = NULL;
+ u_char *sourceData = NULL;
+
+ // Get the length of the packet.
+ while (input->len() > 0) {
+ if (input->len() < 4) {
+ FQ_TRACE("ssh1packet", 3) << "The packet is too small.";
+ return ;
+ }
+ buf = input->data();
+ real_data_len_ = ntohu32(buf);
+
+ if (real_data_len_ > SSH_BUFFER_MAX) {
+ emit packetError(tr("parseData: The packet is too big"));
+ return ;
+ }
+
+ u_int total_len = (real_data_len_ + 8) &~7;
+ u_int padding_len = total_len - real_data_len_;
+
+ real_data_len_ -= 5;
+ buffer_->clear();
+
+ // Get the data of the packet.
+ if (input->len() - 4 < (long)total_len) {
+ FQ_TRACE("ssh1packet", 3) << "The packet is too small";
+ return ;
+ }
+
+ real_data_len_ = input->getInt() - 5;
+ targetData = new u_char[total_len];
+ sourceData = new u_char[total_len];
+ memset(targetData, 0, total_len);
+ memset(sourceData, 0, total_len);
+
+ input->getRawData((char*)sourceData, total_len);
+ if (is_decrypt_) {
+ cipher_->decrypt(sourceData, targetData, total_len);
+ } else {
+ memcpy(targetData, sourceData, total_len);
+ }
+
+ buffer_->putRawData((char*)targetData, total_len);
+
+ // Check the crc32.
+ buf = buffer_->data() + total_len - 4;
+ mycrc = ntohu32(buf);
+ gotcrc = ssh_crc32(buffer_->data(), total_len - 4);
+
+ if (mycrc != gotcrc) {
+ emit packetError(tr("parseData: bad CRC32"));
+ break;
+ }
+
+ // Drop the padding.
+ buffer_->consume(padding_len);
+
+ packet_type_ = buffer_->getByte();
+
+ emit packetAvaliable(packet_type_);
+
+ delete [] sourceData;
+ delete [] targetData;
+ }
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh1_packet.h b/src/protocol/internal/fqterm_ssh1_packet.h
new file mode 100644
index 0000000..a535635
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh1_packet.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH1_PACKET_H
+#define FQTERM_SSH1_PACKET_H
+
+#include "fqterm_ssh_packet.h"
+
+namespace FQTerm {
+
+class FQTermSSH1PacketSender: public FQTermSSHPacketSender {
+protected:
+ virtual void makePacket();
+};
+
+class FQTermSSH1PacketReceiver: public FQTermSSHPacketReceiver {
+public:
+ virtual void parseData(FQTermSSHBuffer *input);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH1_PACKET
diff --git a/src/protocol/internal/fqterm_ssh2_kex.cpp b/src/protocol/internal/fqterm_ssh2_kex.cpp
new file mode 100644
index 0000000..acae08d
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_kex.cpp
@@ -0,0 +1,394 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <vector>
+#include <string>
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <openssl/des.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+#include "fqterm_ssh2_kex.h"
+#include "fqterm_ssh_md5.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+static const int g = 2;
+static const int q = 128;
+static const unsigned char p[q]={
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+FQTermSSH2Kex::FQTermSSH2Kex(const char *V_C, const char *V_S)
+ : FQTermSSHKex(V_C, V_S) {
+ is_first_kex_ = true;
+ kex_state_ = FQTermSSH2Kex::BEFORE_KEXINIT;
+
+ I_C_len_ = 0;
+ I_C_ = NULL;
+ I_S_len_ = 0;
+ I_S_ = NULL;
+
+ bn_x_ = BN_new();
+ bn_e_ = BN_new();
+ bn_g_ = BN_new();
+ bn_p_ = BN_new();
+ ctx_ = BN_CTX_new();
+
+ bn_K_ = BN_new();
+ bn_f_ = BN_new();
+
+ BN_set_word(bn_g_, g);
+ BN_bin2bn(p, q, bn_p_);
+
+ session_id_ = NULL;
+}
+
+FQTermSSH2Kex::~FQTermSSH2Kex() {
+ delete[] I_C_;
+ delete[] I_S_;
+
+ BN_clear_free(bn_x_);
+ BN_clear_free(bn_e_);
+ BN_clear_free(bn_g_);
+ BN_clear_free(bn_p_);
+ BN_CTX_free(ctx_);
+
+ BN_clear_free(bn_K_);
+ BN_clear_free(bn_f_);
+
+ delete[] session_id_;
+}
+
+void FQTermSSH2Kex::initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *packetSender) {
+ packet_receiver_ = packetReceiver;
+ packet_sender_ = packetSender;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+ kex_state_ = FQTermSSH2Kex::BEFORE_KEXINIT;
+ emit reKex();
+}
+
+void FQTermSSH2Kex::handlePacket(int type) {
+ switch (kex_state_) {
+ case FQTermSSH2Kex::BEFORE_KEXINIT:
+ negotiateAlgorithms();
+ exchangeKey();
+ kex_state_ = FQTermSSH2Kex::WAIT_REPLY;
+ break;
+ case FQTermSSH2Kex::WAIT_REPLY:
+ if (verifyKey()) {
+ sendNewKeys();
+ kex_state_ = FQTermSSH2Kex::SESSIONKEY_SENT;
+ } else {
+ emit kexError(tr("Key exchange failed!"));
+ }
+ break;
+ case FQTermSSH2Kex::SESSIONKEY_SENT:
+ if (changeKeyAlg()) {
+ kex_state_ = FQTermSSH2Kex::KEYEX_OK;
+ emit kexOK();
+ }
+ break;
+ case FQTermSSH2Kex::KEYEX_OK:
+ // TODO: how about Key Re-Exchange (see RFC 4253, 9. Key Re-Exchange)
+ break;
+ }
+}
+
+void FQTermSSH2Kex::negotiateAlgorithms() {
+ FQ_FUNC_TRACE("ssh2kex", 10);
+
+ if (packet_receiver_->packetType() != SSH2_MSG_KEXINIT) {
+ emit kexError(tr("startKex: First packet is not SSH_MSG_KEXINIT"));
+ return ;
+ }
+
+ // 0. Backup the payload of this server packet.
+ I_S_len_ = packet_receiver_->packetDataLen() + 1; // add 1 bytes for packet type.
+ delete[] I_S_;
+ I_S_ = new char[I_S_len_];
+ I_S_[0] = SSH2_MSG_KEXINIT;
+ memcpy(I_S_ + 1, packet_receiver_->buffer_->data(), I_S_len_ - 1);
+
+ // 1. Parse server kex init packet
+ packet_receiver_->getRawData((char*)cookie_, 16);
+
+ std::vector<char> name_lists;
+ for (int i = 0; i < 10; ++i) {
+ int name_lists_len = packet_receiver_->getInt();
+ if (name_lists_len > 0) {
+ name_lists.resize(name_lists_len);
+ packet_receiver_->getRawData(&name_lists[0], name_lists_len);
+ FQ_TRACE("ssh2kex", 5) << "Algorithms: " << QString::fromAscii(&name_lists[0], name_lists_len);
+ } else {
+ FQ_TRACE("ssh2kex", 5) << "None Algorithms";
+ }
+ }
+
+ bool first_kex_packet_follows = packet_receiver_->getByte();
+ FQ_TRACE("ssh2kex", 5) << "first_kex_packet_follows: " << first_kex_packet_follows;
+
+ packet_receiver_->consume(4);
+
+ // 2. compose a kex init packet.
+ packet_sender_->startPacket(SSH2_MSG_KEXINIT);
+ packet_sender_->putRawData((const char*)cookie_, 16); // FIXME: generate new cookie_;
+ packet_sender_->putString("diffie-hellman-group1-sha1");
+ packet_sender_->putString("ssh-rsa");
+ packet_sender_->putString("3des-cbc");
+ packet_sender_->putString("3des-cbc");
+ packet_sender_->putString("hmac-sha1");
+ packet_sender_->putString("hmac-sha1");
+ packet_sender_->putString("none");
+ packet_sender_->putString("none");
+ packet_sender_->putString("");
+ packet_sender_->putString("");
+
+ packet_sender_->putByte(false);
+ packet_sender_->putInt(0);
+
+ // 3. backup the payload of this client packet.
+ I_C_len_ = packet_sender_->buffer_->len();
+ delete[] I_C_;
+ I_C_ = new char[I_C_len_];
+ memcpy(I_C_, packet_sender_->buffer_->data(), I_C_len_);
+
+ // 4. send packet to server
+ packet_sender_->write();
+}
+
+void FQTermSSH2Kex::exchangeKey() {
+ BN_rand(bn_x_, q, 0, -1);
+ BN_mod_exp(bn_e_, bn_g_, bn_x_, bn_p_, ctx_);
+
+ packet_sender_->startPacket(SSH2_MSG_KEXDH_INIT);
+ packet_sender_->putBN2(bn_e_);
+ packet_sender_->write();
+}
+
+static RSA *CreateRSAContext(unsigned char *host_key, int len);
+
+bool FQTermSSH2Kex::verifyKey() {
+ if (packet_receiver_->packetType() != SSH2_MSG_KEXDH_REPLY) {
+ emit kexError(tr("Expect a SSH_MSG_KEXDH_REPLY packet"));
+ return false;
+ }
+
+ // Extract data
+
+ int K_S_len = -1;
+ unsigned char *K_S = (unsigned char *)packet_receiver_->getString(&K_S_len);
+
+ packet_receiver_->getBN2(bn_f_);
+
+ int s_len = -1;
+ unsigned char *s = (unsigned char *)packet_receiver_->getString(&s_len);
+
+ BN_mod_exp(bn_K_, bn_f_, bn_x_, bn_p_, ctx_);
+
+ FQTermSSHBuffer *buffer = packet_sender_->output_buffer_;
+
+ buffer->clear();
+ buffer->putString(V_C_);
+ buffer->putString(V_S_);
+ buffer->putString(I_C_, I_C_len_);
+ buffer->putString(I_S_, I_S_len_);
+ buffer->putString((char *)K_S, K_S_len);
+ buffer->putSSH2BN(bn_e_);
+ buffer->putSSH2BN(bn_f_);
+ buffer->putSSH2BN(bn_K_);
+
+ SHA1(buffer->data(), buffer->len(), H_);
+
+ // Start verify
+ unsigned char s_H[SHA_DIGEST_LENGTH];
+ SHA1(H_, SHA_DIGEST_LENGTH, s_H);
+
+ // Ignore the first 15 bytes of the signature of H sent from server:
+ // algorithm_name_length[4], algorithm_name[7]("ssh-rsa") and signature_length[4].
+ RSA *rsactx = CreateRSAContext(K_S, K_S_len);
+ int sig_len = s_len - 15;
+ unsigned char *sig = s + 15;
+ int res = RSA_verify(NID_sha1, s_H, SHA_DIGEST_LENGTH,
+ sig, sig_len, rsactx);
+
+ RSA_free(rsactx);
+
+ delete K_S;
+ delete s;
+
+ return res == 1;
+}
+
+static RSA *CreateRSAContext(unsigned char *host_key, int len) {
+ FQTermSSHBuffer buffer(len);
+
+ buffer.putRawData((char *)host_key, len);
+
+ int algo_len = -1;
+ unsigned char *algo = (unsigned char *)buffer.getString(&algo_len);
+
+ FQ_VERIFY(std::string("ssh-rsa") == std::string((char *)algo));
+
+ int e_len = -1;
+ unsigned char *e = (unsigned char *)buffer.getString(&e_len);
+
+ int n_len = -1;
+ unsigned char *n = (unsigned char *)buffer.getString(&n_len);
+
+
+ RSA *rsa = RSA_new();
+ rsa->e = BN_new();
+ BN_bin2bn(e, e_len, rsa->e);
+
+ rsa->n = BN_new();
+ BN_bin2bn(n, n_len, rsa->n);
+
+ delete[] algo;
+ delete[] e;
+ delete[] n;
+
+ return rsa;
+}
+
+void FQTermSSH2Kex::sendNewKeys(){
+ packet_sender_->startPacket(SSH2_MSG_NEWKEYS);
+ packet_sender_->write();
+}
+
+bool FQTermSSH2Kex::changeKeyAlg() {
+ if (packet_receiver_->packetType() != SSH2_MSG_NEWKEYS) {
+ emit kexError(tr("Expect a SSH_MSG_NEWKEYS packet"));
+ return false;
+ }
+
+ if (session_id_ == NULL) {
+ session_id_ = new unsigned char[SHA_DIGEST_LENGTH];
+ memcpy(session_id_, H_, SHA_DIGEST_LENGTH);
+ }
+
+ packet_sender_->setEncryptionType(SSH_CIPHER_3DES);
+ packet_receiver_->setEncryptionType(SSH_CIPHER_3DES);
+
+ packet_sender_->setMacType(FQTERM_SSH_HMAC_SHA1);
+ packet_receiver_->setMacType(FQTERM_SSH_HMAC_SHA1);
+
+ // From RFC 4253 section 7.2:
+ // Initial IV client to server: HASH(K || H || "A" || session_id)
+ // (Here K is encoded as mpint and "A" as byte and session_id as raw
+ // data. "A" means the single character A, ASCII 65).
+ //
+ // Initial IV server to client: HASH(K || H || "B" || session_id)
+ //
+ // Encryption key client to server: HASH(K || H || "C" || session_id)
+ //
+ // Encryption key server to client: HASH(K || H || "D" || session_id)
+ //
+ // Integrity key client to server: HASH(K || H || "E" || session_id)
+ //
+ // Integrity key server to client: HASH(K || H || "F" || session_id)
+
+ int IV_c2s_len = packet_sender_->getIVSize();
+ unsigned char *IV_c2s = computeKey(IV_c2s_len, 'A');
+
+ int IV_s2c_len = packet_receiver_->getIVSize();
+ unsigned char *IV_s2c = computeKey(IV_s2c_len, 'B');
+
+ int key_c2s_len = packet_sender_->getKeySize();
+ unsigned char *key_c2s = computeKey(key_c2s_len, 'C');
+
+ int key_s2c_len = packet_receiver_->getKeySize();
+ unsigned char *key_s2c = computeKey(key_s2c_len, 'D');
+
+ int mac_key_c2s_len = packet_sender_->getMacKeySize();
+ unsigned char *mac_key_c2s = computeKey(mac_key_c2s_len, 'E');
+
+ int mac_key_s2c_len = packet_receiver_->getMacKeySize();
+ unsigned char *mac_key_s2c = computeKey(mac_key_s2c_len, 'F');
+
+
+ packet_sender_->startEncryption(key_c2s, IV_c2s);
+ packet_sender_->startMac(mac_key_c2s);
+
+ packet_receiver_->startEncryption(key_s2c, IV_s2c);
+ packet_receiver_->startMac(mac_key_s2c);
+
+
+ delete[] IV_c2s;
+ delete[] IV_s2c;
+ delete[] key_c2s;
+ delete[] key_s2c;
+ delete[] mac_key_c2s;
+ delete[] mac_key_s2c;
+
+ return true;
+}
+
+unsigned char *FQTermSSH2Kex::computeKey(int expected_len, char flag) {
+ unsigned char *key = new unsigned char[expected_len + SHA_DIGEST_LENGTH];
+
+ int len = 0;
+ SHA_CTX hash;
+
+ FQTermSSHBuffer K(BN_num_bytes(bn_K_) + 5);
+ K.putSSH2BN(bn_K_);
+
+ while (len < expected_len) {
+ SHA1_Init(&hash);
+ SHA1_Update(&hash, K.data(), K.len());
+ SHA1_Update(&hash, H_, SHA_DIGEST_LENGTH);
+
+ if (len == 0) {
+ SHA1_Update(&hash, &flag, 1);
+ SHA1_Update(&hash, session_id_, SHA_DIGEST_LENGTH);
+ } else {
+ SHA1_Update(&hash, key, len);
+ }
+
+ SHA1_Final(key + len, &hash);
+ len += SHA_DIGEST_LENGTH;
+ }
+
+ return key;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh2_kex.moc"
diff --git a/src/protocol/internal/fqterm_ssh2_kex.h b/src/protocol/internal/fqterm_ssh2_kex.h
new file mode 100644
index 0000000..671e094
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_kex.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH2_KEX_H
+#define FQTERM_SSH2_KEX_H
+
+#include <openssl/sha.h>
+
+#include "fqterm_ssh_kex.h"
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSH2Kex: public FQTermSSHKex {
+ Q_OBJECT;
+private:
+ enum FQTermSSH2KexState {
+ BEFORE_KEXINIT, WAIT_REPLY, SESSIONKEY_SENT, KEYEX_OK
+ } kex_state_;
+
+ /*
+ string V_C, the client's identification string (CR and LF
+ excluded)
+ string V_S, the server's identification string (CR and LF
+ excluded)
+ string I_C, the payload of the client's SSH_MSG_KEXINIT
+ string I_S, the payload of the server's SSH_MSG_KEXINIT
+ string K_S, the host key
+ mpint e, exchange value sent by the client
+ mpint f, exchange value sent by the server
+ mpint K, the shared secret
+ */
+
+ int I_C_len_;
+ char *I_C_;
+ int I_S_len_;
+ char *I_S_;
+
+ BIGNUM *bn_x_;
+ BIGNUM *bn_e_;
+ BIGNUM *bn_g_;
+ BIGNUM *bn_p_;
+ BN_CTX *ctx_;
+
+ BIGNUM *bn_K_;
+ BIGNUM *bn_f_;
+
+ unsigned char H_[SHA_DIGEST_LENGTH];
+
+ unsigned char *session_id_;
+
+
+
+
+ bool is_first_kex_;
+
+ FQTermSSHRSA *host_key_;
+ FQTermSSHRSA *server_key_;
+
+ u_char cookie_[16];
+ int server_flag_, ciphers_, auth_;
+// u_char session_id_[16];
+ u_char session_key_[32];
+
+ void negotiateAlgorithms();
+ void exchangeKey();
+ bool verifyKey();
+ void sendNewKeys();
+ bool changeKeyAlg();
+
+ unsigned char *computeKey(int len, char flag);
+
+public:
+ FQTermSSH2Kex(const char *V_C, const char *V_S);
+ ~FQTermSSH2Kex();
+
+ virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *outputSender);
+
+public slots:
+ void handlePacket(int type);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH2_KEX_H
diff --git a/src/protocol/internal/fqterm_ssh2_packet.cpp b/src/protocol/internal/fqterm_ssh2_packet.cpp
new file mode 100644
index 0000000..d3094d3
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_packet.cpp
@@ -0,0 +1,267 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh2_packet.h"
+#include "fqterm_ssh_des.h"
+
+#include "fqterm_serialization.h"
+#include "crc32.h"
+
+namespace FQTerm {
+//==============================================================================
+//FQTermSSH2PacketSender
+//==============================================================================
+// SSH2 Packet Structure:
+// uint32 packet_length
+// byte padding_length
+// byte[n1] payload; n1 = packet_length - padding_length - 1
+// byte[n2] random padding; n2 = padding_length
+// byte[m] mac (Message Authentication Code - MAC); m = mac_length
+//==============================================================================
+
+void FQTermSSH2PacketSender::makePacket() {
+ FQ_TRACE("ssh2packet", 9) << "----------------------------Send "
+ << (is_encrypt_ ? "Encrypted": "plain")
+ << " Packet---->>>>>>>";
+
+ // 0. compress
+ if (is_compressed_) {
+ FQ_VERIFY(false);
+ }
+
+ // 1. compute the padding length for padding.
+ int non_padding_len = 4 + 1 + buffer_->len();
+
+ int padding_block_len = 8;
+ if (is_encrypt_ && cipher_->blockSize() > padding_block_len) {
+ padding_block_len = cipher_->blockSize();
+ }
+
+ int padding_len = padding_block_len - (non_padding_len % padding_block_len);
+ if (padding_len < 4) {
+ padding_len += padding_block_len;
+ }
+
+ // 2. renew the output buffer.
+ int total_len = non_padding_len + padding_len;
+ if (is_mac_) {
+ total_len += mac_->digestSize();
+ }
+
+ delete output_buffer_;
+ output_buffer_ = new FQTermSSHBuffer(total_len);
+
+ // 3. Fill the output buffer.
+ int packet_len = 1 + buffer_->len() + padding_len;
+
+ output_buffer_->putInt(packet_len);
+ output_buffer_->putByte(padding_len);
+ output_buffer_->putRawData((const char*)buffer_->data(), buffer_->len());
+
+ u_int32_t rand_val = 0;
+ for (int i = 0; i < padding_len; i++) {
+ if (i % 4 == 0) {
+ rand_val = rand(); // FIXME: rand() doesn't range from 0 to 2^32.
+ }
+ output_buffer_->putByte(rand_val & 0xff);
+ rand_val >>= 8;
+ }
+
+ // 4. Add MAC on the entire unencrypted packet,
+ // including two length fields, 'payload' and 'random padding'.
+ if (is_mac_) {
+ const unsigned char *packet = output_buffer_->data();
+ int len = output_buffer_->len();
+
+ FQTermSSHBuffer buffer(4 + len);
+ buffer.putInt(sequence_no_);
+ buffer.putRawData((const char *)packet, len);
+
+ std::vector<u_char> digest(mac_->digestSize());
+ mac_->getDigest(buffer.data(), buffer.len(), &digest[0]);
+
+ FQ_TRACE("ssh2packet", 9) << "Making packets...";
+ FQ_TRACE("ssh2packet", 9) << "Append MAC with sequence_no_" << sequence_no_;
+ FQ_TRACE("ssh2packet", 9) << "Compute MAC with "
+ << buffer.len() << " bytes data:\n"
+ << dumpHexString << std::string((char *)buffer.data(), buffer.len());
+ FQ_TRACE("ssh2packet", 9) << "MAC data "
+ << digest.size() << " bytes:\n"
+ << dumpHexString << std::string((const char *)&digest[0], digest.size());
+
+ output_buffer_->putRawData((const char *)&digest[0], digest.size());
+ }
+
+ if (is_compressed_) {
+ FQ_VERIFY(false);
+ }
+
+ if (is_encrypt_) {
+ // as RFC 4253:
+ // When encryption is in effect, the packet length, padding
+ // length, payload, and padding fields of each packet MUST be encrypted
+ // with the given algorithm.
+
+ u_char *data = output_buffer_->data();
+ int len = output_buffer_->len() - mac_->digestSize();
+
+ FQ_TRACE("ssh2packet", 9) << "An packet (without MAC) to be encrypted:"
+ << len << " bytes:\n"
+ << dumpHexString << std::string((const char *)data, len);
+
+ cipher_->encrypt(data, data, len);
+
+ FQ_TRACE("ssh2packet", 9) << "An encrypted packet (without MAC) made:"
+ << len << " bytes:\n"
+ << dumpHexString << std::string((const char *)data, len);
+ }
+
+ ++sequence_no_;
+}
+
+void FQTermSSH2PacketSender::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH2TripleDESCBC;
+ break;
+ }
+}
+
+
+//==============================================================================
+//FQTermSSH2PacketReceiver
+//==============================================================================
+void FQTermSSH2PacketReceiver::parseData(FQTermSSHBuffer *input) {
+ FQ_TRACE("ssh2packet", 9) << "----------------------------Receive "
+ << (is_decrypt_ ? "Encrypted": "plain")
+ << " Packet----<<<<<<<";
+ while (input->len() > 0) {
+ // 1. Check the ssh packet
+ if (input->len() < 16
+ || (is_decrypt_ && input->len() < cipher_->blockSize())
+ || input->len() < last_expected_input_length_
+ ) {
+ FQ_TRACE("ssh2packet", 3)
+ << "Got an incomplete packet. Wait for more data.";
+ return ;
+ }
+
+ if (last_expected_input_length_ == 0) {
+ if (is_decrypt_) {
+ // decrypte the first block to get the packet_length field.
+ cipher_->decrypt(input->data(), input->data(), cipher_->blockSize());
+ }
+ } else {
+ // last_expected_input_length_ != 0
+ // indicates an incomplete ssh2 packet received last time,
+ // the first block of data is already decrypted at that time,
+ // so it must not be decrypted again.
+ }
+
+ int packet_len = ntohu32(input->data());
+
+ if (packet_len > SSH_BUFFER_MAX) {
+ emit packetError(tr("parseData: packet too big"));
+ return ;
+ }
+
+ int expected_input_len = 4 + packet_len + (is_mac_ ? mac_->digestSize() : 0);
+
+ if (input->len() < (long)expected_input_len) {
+ FQ_TRACE("ssh2packet", 3)
+ << "The packet is too small. Wait for more data.";
+ last_expected_input_length_ = expected_input_len;
+ return ;
+ } else {
+ last_expected_input_length_ = 0;
+ }
+
+ // 2. decrypte data.
+ if (is_decrypt_) {
+ // decrypte blocks left.
+ unsigned char *tmp = input->data() + cipher_->blockSize();
+ int left_len = expected_input_len - cipher_->blockSize() - mac_->digestSize();
+ cipher_->decrypt(tmp, tmp, left_len);
+ }
+
+ // 3. check MAC
+ if (is_mac_) {
+ int digest_len = mac_->digestSize();
+ std::vector<u_char> digest(digest_len);
+ mac_->getDigest(input->data(), expected_input_len - digest_len, &digest[0]);
+
+ u_char *received_digest = input->data() + expected_input_len - digest_len;
+
+ if (memcmp(&digest[0], received_digest, digest_len) == 0) {
+ FQ_TRACE("ssh2packet", 0) << "incorrect MAC.";
+ return ;
+ }
+ }
+
+ // 4. get every field of the ssh packet.
+ packet_len = input->getInt();
+
+ std::vector<u_char> data(packet_len);
+
+ input->getRawData((char*)&data[0], packet_len);
+ if (is_mac_) {
+ input->consume(mac_->digestSize());
+ }
+
+ int padding_len = data[0];
+
+ real_data_len_ = packet_len - 1 - padding_len;
+
+ buffer_->clear();
+ buffer_->putRawData((char*)&data[0] + 1, real_data_len_);
+
+ FQ_TRACE("ssh2packet", 9) << "Receive " << real_data_len_ << " bytes payload:\n"
+ << dumpHexString << std::string((char *)&data[0] + 1, real_data_len_);
+
+ // 5. notify others a ssh packet is parsed successfully.
+ packet_type_ = buffer_->getByte();
+ real_data_len_ -= 1;
+ emit packetAvaliable(packet_type_);
+
+ ++sequence_no_;
+ }
+}
+
+void FQTermSSH2PacketReceiver::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH2TripleDESCBC;
+ break;
+ }
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh2_packet.h b/src/protocol/internal/fqterm_ssh2_packet.h
new file mode 100644
index 0000000..c460984
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh2_packet.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH2_PACKET_H
+#define FQTERM_SSH2_PACKET_H
+
+#include "fqterm_ssh_packet.h"
+
+namespace FQTerm {
+
+class FQTermSSH2PacketSender: public FQTermSSHPacketSender {
+ protected:
+ virtual void makePacket();
+
+ public:
+ virtual void setEncryptionType(int cipherType);
+};
+
+class FQTermSSH2PacketReceiver: public FQTermSSHPacketReceiver {
+ private:
+ // greater than 0 if last time an incomplete ssh2 packet received.
+ int last_expected_input_length_;
+ public:
+ FQTermSSH2PacketReceiver()
+ : last_expected_input_length_(0) {
+ }
+
+ virtual void parseData(FQTermSSHBuffer *input);
+ virtual void setEncryptionType(int cipherType);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH2_PACKET
diff --git a/src/protocol/internal/fqterm_ssh_auth.cpp b/src/protocol/internal/fqterm_ssh_auth.cpp
new file mode 100644
index 0000000..d063d14
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_auth.cpp
@@ -0,0 +1,223 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QString>
+
+#include "fqterm_ssh_auth.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh_const.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSH1PasswdAuth
+//==============================================================================
+
+FQTermSSH1PasswdAuth::FQTermSSH1PasswdAuth(const char *sshuser,
+ const char *sshpasswd)
+ : FQTermSSHPasswdAuth(sshuser, sshpasswd) {
+ is_tried_ = false;
+ ssh_pw_auth_state_ = FQTermSSH1PasswdAuth::BEFORE_AUTH;
+}
+
+void FQTermSSH1PasswdAuth::initAuth(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output) {
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+ packet_sender_->startPacket(SSH1_CMSG_USER);
+ user_name_.clear();
+ passwd_.clear();
+
+ if (!default_user_.isEmpty() && !default_passwd_.isEmpty()) {
+ user_name_ = default_user_;
+ passwd_ = default_passwd_;
+ }
+
+ while (user_name_.isEmpty()) {
+ bool isOK = false;
+ emit requestUserPwd(&user_name_, &passwd_, &isOK);
+ // SSHLoginDialog login(&d_user, &d_passwd);
+ if (!isOK) {
+ emit authError(tr("UserCancel"));
+ return ;
+ }
+ }
+
+ packet_sender_->putString(user_name_.toLatin1());
+ packet_sender_->write();
+ ssh_pw_auth_state_ = USER_SENT;
+ is_tried_ = false;
+}
+
+void FQTermSSH1PasswdAuth::handlePacket(int type) {
+ switch (ssh_pw_auth_state_) {
+ case BEFORE_AUTH:
+ FQ_TRACE("sshauth", 0) << "Auth: We should not be here.";
+ break;
+ case USER_SENT:
+ if (type == SSH1_SMSG_SUCCESS) {
+ ssh_pw_auth_state_ = AUTH_OK;
+ emit authOK();
+ break;
+ }
+ if (type != SSH1_SMSG_FAILURE) {
+ emit authError(tr("Strange response from server"));
+ break;
+ }
+ if (is_tried_) {
+ bool isOK = false;
+ emit requestUserPwd(&user_name_, &passwd_, &isOK);
+ // SSHLoginDialog login(&d_user, &d_passwd);
+ if (!isOK) {
+ emit authError(tr("User canceled"));
+ break;
+ }
+ is_tried_ = false;
+ }
+ packet_sender_->startPacket(SSH1_CMSG_AUTH_PASSWORD);
+ packet_sender_->putString(passwd_.toLatin1());
+ packet_sender_->write();
+ is_tried_ = true;
+ break;
+ case AUTH_OK:
+ break;
+ default:
+ return ;
+ }
+}
+
+//==============================================================================
+//FQTermSSH2PasswdAuth
+//==============================================================================
+
+FQTermSSH2PasswdAuth::FQTermSSH2PasswdAuth(const char *sshuser,
+ const char *sshpasswd)
+ : FQTermSSHPasswdAuth(sshuser, sshpasswd) {
+ is_tried_ = false;
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::SERVICE_ACCEPTED;
+}
+
+void FQTermSSH2PasswdAuth::initAuth(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output) {
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+
+ packet_sender_->startPacket(SSH2_MSG_SERVICE_REQUEST);
+ packet_sender_->putString("ssh-userauth");
+ packet_sender_->write();
+
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::SERVICE_ACCEPTED;
+}
+
+void FQTermSSH2PasswdAuth::handlePacket(int type) {
+ switch (ssh_pw_auth_state_) {
+ case FQTermSSH2PasswdAuth::SERVICE_ACCEPTED:
+ sendUserPasswd();
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::USER_PASSWD_SENT;
+ break;
+ case FQTermSSH2PasswdAuth::USER_PASSWD_SENT:
+ if (check()) {
+ FQ_TRACE("ssh2passwdauth", 3) << "Auth OK.";
+
+ emit authOK();
+ ssh_pw_auth_state_ = FQTermSSH2PasswdAuth::AUTH_OK;
+ }
+ break;
+ case FQTermSSH2PasswdAuth::AUTH_OK:
+ break;
+ default:
+ return ;
+ }
+}
+
+bool FQTermSSH2PasswdAuth::check() {
+ switch(packet_receiver_->packetType()) {
+ case SSH2_MSG_USERAUTH_SUCCESS:
+ return true;
+ break;
+ case SSH2_MSG_USERAUTH_BANNER:
+ // TODO: just ignore banner messages.
+ break;
+ case SSH2_MSG_USERAUTH_FAILURE:
+ emit authError(tr("Authentication failed!"));
+ break;
+ default:
+ emit authError(tr("Unexpected packet"));
+ }
+
+ return false;
+}
+
+void FQTermSSH2PasswdAuth::sendUserPasswd() {
+ if (packet_receiver_->packetType() != SSH2_MSG_SERVICE_ACCEPT) {
+ emit authError(tr("Expect a SSH2_MSG_SERVICE_ACCEPT packet"));
+ return;
+ }
+
+ u_char *service_name = (u_char *)packet_receiver_->getString();
+
+ if (std::string((char *)service_name) != std::string("ssh-userauth")) {
+ emit authError(tr("Error when sending username and password."));
+ return;
+ }
+
+ delete[] service_name;
+
+ // byte SSH_MSG_USERAUTH_REQUEST
+ // string user name in ISO-10646 UTF-8 encoding [RFC3629]
+ // string service name in US-ASCII
+ // string method name in US-ASCII
+ // .... method specific fields
+ user_name_.clear();
+ passwd_.clear();
+
+ if (!default_user_.isEmpty() && !default_passwd_.isEmpty()) {
+ user_name_ = default_user_;
+ passwd_ = default_passwd_;
+ }
+
+ while (user_name_.isEmpty()) {
+ bool isOK = false;
+ emit requestUserPwd(&user_name_, &passwd_, &isOK);
+ if (!isOK) {
+ emit authError(tr("UserCancel"));
+ return ;
+ }
+ }
+
+ packet_sender_->startPacket(SSH2_MSG_USERAUTH_REQUEST);
+ packet_sender_->putString(user_name_.toLatin1());
+ packet_sender_->putString("ssh-connection");
+ packet_sender_->putString("password");
+ packet_sender_->putByte(false);
+ packet_sender_->putString(passwd_.toLatin1());
+ packet_sender_->write();
+}
+
+} // namespace FQTerm
+
+#include <fqterm_ssh_auth.moc>
diff --git a/src/protocol/internal/fqterm_ssh_auth.h b/src/protocol/internal/fqterm_ssh_auth.h
new file mode 100644
index 0000000..6152a71
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_auth.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_AUTH_H
+#define FQTERM_SSH_AUTH_H
+
+#include <QObject>
+
+class QString;
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSHAuth: public QObject {
+
+ Q_OBJECT;
+protected:
+ QString user_name_;
+ FQTermSSHPacketReceiver *packet_receiver_;
+ FQTermSSHPacketSender *packet_sender_;
+
+public:
+ FQTermSSHAuth(const char *sshuser = NULL)
+ : user_name_(sshuser) {
+ }
+
+ ~FQTermSSHAuth() {}
+
+ virtual void initAuth(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output) = 0;
+public slots:
+ virtual void handlePacket(int type) = 0;
+
+signals:
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+ void authOK();
+ void authError(QString);
+};
+
+class FQTermSSHPasswdAuth: public FQTermSSHAuth {
+ Q_OBJECT;
+protected:
+ QString passwd_;
+ bool is_tried_;
+
+ QString default_user_;
+ QString default_passwd_;
+
+public:
+ FQTermSSHPasswdAuth(const char *sshuser, const char *sshpasswd)
+ : FQTermSSHAuth(sshuser),
+ passwd_(sshpasswd),
+ default_user_(sshuser),
+ default_passwd_(sshpasswd) {
+ }
+};
+
+class FQTermSSH1PasswdAuth: public FQTermSSHPasswdAuth {
+ Q_OBJECT;
+private:
+ enum FQTermSSH1PasswdAuthState {
+ BEFORE_AUTH, USER_SENT, PASS_SENT, AUTH_OK
+ } ssh_pw_auth_state_;
+
+public:
+ FQTermSSH1PasswdAuth(const char *sshuser, const char *sshpasswd);
+
+public slots:
+ void handlePacket(int type);
+ void initAuth(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output);
+};
+
+class FQTermSSH2PasswdAuth: public FQTermSSHPasswdAuth {
+ Q_OBJECT;
+private:
+ enum FQTermSSH2PasswdAuthState {
+ SERVICE_ACCEPTED, USER_PASSWD_SENT, PASS_SENT, AUTH_OK
+ } ssh_pw_auth_state_;
+
+ void sendUserPasswd();
+ bool check();
+
+public:
+ FQTermSSH2PasswdAuth(const char *sshuser, const char *sshpasswd);
+
+public slots:
+ void handlePacket(int type);
+ void initAuth(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_AUTH_H
diff --git a/src/protocol/internal/fqterm_ssh_buffer.cpp b/src/protocol/internal/fqterm_ssh_buffer.cpp
new file mode 100644
index 0000000..d95497a
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_buffer.cpp
@@ -0,0 +1,302 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <vector>
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_serialization.h"
+
+namespace FQTerm {
+//==============================================================================
+// FQTermSSHBuffer
+//==============================================================================
+
+FQTermSSHBuffer::FQTermSSHBuffer(int size) {
+ alloc_size_ = size;
+ buffer_size_ = 0;
+ offset_ = 0;
+ buffer_ = new u_char[alloc_size_];
+}
+
+FQTermSSHBuffer::~FQTermSSHBuffer() {
+ delete [] buffer_;
+ offset_ = 0;
+ buffer_size_ = 0;
+ alloc_size_ = 0;
+}
+
+void FQTermSSHBuffer::ensure(int len) {
+ if (len <= (alloc_size_ - (offset_ + buffer_size_))) {
+ return ;
+ } else {
+ alloc_size_ = buffer_size_ + len;
+ rebuffer();
+ }
+}
+
+void FQTermSSHBuffer::rebuffer() {
+ u_char *newBuffer;
+ newBuffer = new u_char[alloc_size_];
+ memset(newBuffer, 0, alloc_size_);
+ memcpy(newBuffer, buffer_ + offset_, buffer_size_);
+ delete [] buffer_;
+ buffer_ = newBuffer;
+ offset_ = 0;
+}
+
+void FQTermSSHBuffer::clear() {
+ memset(buffer_, 0, alloc_size_);
+ offset_ = 0;
+ buffer_size_ = 0;
+}
+
+void FQTermSSHBuffer::consume(int len) {
+ if (len > buffer_size_) {
+ len = buffer_size_;
+ }
+
+ offset_ += len;
+ buffer_size_ -= len;
+}
+
+void FQTermSSHBuffer::putRawData(const char *data, int len) {
+ if (len < 0) {
+ FQ_TRACE("sshbuffer", 0) << "Write data error.";
+ }
+
+ ensure(len);
+ memcpy((buffer_ + offset_ + buffer_size_), data, len);
+ buffer_size_ += len;
+}
+
+void FQTermSSHBuffer::getRawData(char *data, int len) {
+ if (len <= buffer_size_ && len >= 0) {
+ memcpy(data, buffer_ + offset_, len);
+ consume(len);
+ } else {
+ FQ_TRACE("sshbuffer", 0) << "Read too many data: " << len << " bytes.";
+ }
+}
+
+//==============================================================================
+// Store an BIGNUM in the buffer with a 2-byte msb first bit count, followed by
+// (bits+7)/8 bytes of binary data, msb first.
+//==============================================================================
+
+void FQTermSSHBuffer::putSSH1BN(BIGNUM *bignum) {
+ int bits = BN_num_bits(bignum);
+ int bin_size = (bits + 7) / 8;
+ u_char *buf = new u_char[bin_size];
+ int oi;
+ u_char msg[2];
+
+ // Get the value of in binary
+ oi = BN_bn2bin(bignum, buf);
+ if (oi != bin_size) {
+ FQ_TRACE("sshbuffer", 0) << "BN_bn2bin() failed: oi = " << oi
+ << " != bin_size." << bin_size;
+ }
+
+ // Store the number of bits in the buffer in two bytes, msb first
+ htonu16(msg, bits);
+ putRawData((char*)msg, 2);
+ // Store the binary data.
+ putRawData((char*)buf, oi);
+
+ memset(buf, 0, bin_size);
+ delete [] buf;
+}
+
+
+
+void FQTermSSHBuffer::putSSH2BN(BIGNUM *bignum) {
+ // FIXME: support negative number and add error handling.
+
+ FQ_VERIFY(!bignum->neg); // currently we don't support negative big number.
+
+ if (BN_is_zero(bignum)) {
+ this->putInt(0);
+ } else {
+ u_int bytes = BN_num_bytes(bignum) + 1;
+
+ FQ_VERIFY(bytes >= 2); // currently we don't support big numbers so small
+
+ std::vector<u_char> buf(bytes);
+ buf[0] = 0;
+
+ int bin_len = BN_bn2bin(bignum, &buf[0] + 1);
+
+ FQ_VERIFY(bin_len == (int)bytes - 1);
+
+ u_int no_high_bit = (buf[1] & 0x80) ? 0 : 1;
+
+ this->putInt(bytes - no_high_bit);
+ this->putRawData((const char *)&buf[0] + no_high_bit, bytes - no_high_bit);
+ }
+}
+
+//==============================================================================
+// Retrieves a BIGNUM from the buffer.
+//==============================================================================
+
+void FQTermSSHBuffer::getSSH1BN(BIGNUM *bignum) {
+ int bits, bytes;
+ u_char buf[2];
+ u_char *bin;
+
+ // Get the number for bits.
+ getRawData((char*)buf, 2);
+ bits = ntohu16(buf);
+ // Compute the number of binary bytes that follow.
+ bytes = (bits + 7) / 8;
+ if (bytes > 8 *1024) {
+ FQ_TRACE("sshbuffer", 0) << "Can't handle BN of size " << bytes;
+ return ;
+ }
+ if (len() < bytes) {
+ FQ_TRACE("sshbuffer", 0) << "The input buffer is too small.";
+ return ;
+ }
+ bin = data();
+ BN_bin2bn(bin, bytes, bignum);
+ consume(bytes);
+}
+
+void FQTermSSHBuffer::getSSH2BN(BIGNUM *bignum) {
+ // FIXME: support negative numbers and error handling
+ int len;
+ unsigned char *hex_data = (unsigned char *)getString(&len);
+
+ FQ_VERIFY(!(len > 0 && (hex_data[0] & 0x80))); // don't support negative numbers.
+
+ FQ_VERIFY(len < 10240); // don't support so large numbers.
+
+ BIGNUM *res = BN_bin2bn(hex_data, len, bignum);
+
+ FQ_VERIFY(res != NULL);
+
+ delete hex_data;
+}
+
+u_short FQTermSSHBuffer::getWord() {
+ u_char buf[2];
+ u_short data;
+
+ getRawData((char*)buf, 2);
+ data = ntohu16(buf);
+ return data;
+}
+
+void FQTermSSHBuffer::putWord(u_short data) {
+ u_char buf[2];
+
+ htonu16(buf, data);
+ putRawData((char*)buf, 2);
+}
+
+u_int FQTermSSHBuffer::getInt() {
+ u_char buf[4];
+ u_int data;
+ getRawData((char*)buf, 4);
+ data = ntohu32(buf);
+ return data;
+}
+
+void FQTermSSHBuffer::putInt(u_int data) {
+ u_char buf[4];
+
+ htonu32(buf, data);
+ putRawData((char*)buf, 4);
+}
+
+//==============================================================================
+// Return a character from the buffer (0-255).
+//==============================================================================
+
+u_char FQTermSSHBuffer::getByte() {
+ u_char ch;
+
+ getRawData((char*) &ch, 1);
+ return ch;
+}
+
+//==============================================================================
+// Stores a character in the buffer.
+//==============================================================================
+
+void FQTermSSHBuffer::putByte(int data) {
+ u_char ch = data;
+
+ putRawData((char*) &ch, 1);
+}
+
+//==============================================================================
+// Stores an arbitrary binary string in the buffer.
+//==============================================================================
+
+void FQTermSSHBuffer::putString(const char *str, int len) {
+ if (str == NULL) {
+ FQ_TRACE("sshbuffer", 0) << "Can't put a null pointer string.";
+ return ;
+ }
+
+ if (len < 0) {
+ len = strlen(str);
+ }
+
+ putInt(len);
+ putRawData(str, len);
+}
+
+//==============================================================================
+// Return an arbitrary binary string from the buffer. The string cannot be
+// longer than 256k. The returned value points to memory allocated with new;
+// It is the responsibility of the calling function to free the data.
+//==============================================================================
+
+void *FQTermSSHBuffer::getString(int *length) {
+ u_char *data;
+ u_int len;
+
+ // Get the length.
+ len = getInt();
+ if ((long)len > buffer_size_) {
+ FQ_TRACE("sshbuffer", 0)
+ << "String length " << len
+ << " is greater than buffer size " << buffer_size_;
+ return 0;
+ }
+ // Allocate space for the string. Add one byte for a null character.
+ data = new u_char[len + 1];
+ // Get the string.
+ getRawData((char*)data, len);
+ // Append a null character to make processing easier.
+ data[len] = 0;
+ if (length != NULL) {
+ *length = len;
+ }
+ // return the length of the string.
+ return data;
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_buffer.h b/src/protocol/internal/fqterm_ssh_buffer.h
new file mode 100644
index 0000000..e06872f
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_buffer.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_BUFFER_H
+#define FQTERM_SSH_BUFFER_H
+
+#include <openssl/bn.h>
+#include <string.h>
+
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+#define SSH_BUFFER_MAX 10000000
+
+class FQTermSSHBuffer {
+ private:
+ u_char *buffer_;
+ int offset_;
+ int buffer_size_;
+ int alloc_size_;
+
+ void ensure(int len);
+ void rebuffer();
+
+ public:
+ FQTermSSHBuffer(int size);
+ ~FQTermSSHBuffer();
+
+ u_char *data() const {
+ return buffer_ + offset_;
+ }
+
+ int len() const {
+ return buffer_size_;
+ }
+
+ void consume(int len);
+
+ void clear();
+
+ void putRawData(const char *data, int len);
+ void getRawData(char *data, int len);
+
+ void putSSH1BN(BIGNUM *bignum);
+ void getSSH1BN(BIGNUM *bignum);
+
+ void putSSH2BN(BIGNUM *bignum);
+ void getSSH2BN(BIGNUM *bignum);
+
+ void putInt(u_int data);
+ u_int getInt();
+
+ void putWord(u_short data);
+ u_short getWord();
+
+ void putByte(int data);
+ u_char getByte();
+
+ void putString(const char *str, int len = -1);
+ void *getString(int *length = NULL);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_BUFFER
diff --git a/src/protocol/internal/fqterm_ssh_channel.cpp b/src/protocol/internal/fqterm_ssh_channel.cpp
new file mode 100644
index 0000000..38a755a
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_channel.cpp
@@ -0,0 +1,439 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_channel.h"
+#include "fqterm_ssh_const.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_trace.h"
+#include <QString>
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSH1Channel
+//==============================================================================
+
+FQTermSSH1Channel::FQTermSSH1Channel()
+ : FQTermSSHChannel() {
+ service_state_ = FQTermSSH1Channel::BEGIN_SERVICE;
+}
+
+void FQTermSSH1Channel::initChannel(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype) {
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+ packet_sender_->startPacket(SSH1_CMSG_REQUEST_PTY);
+ // pty request is of no use in BBS, but we do this
+ packet_sender_->putString(termtype.toLatin1());
+ packet_sender_->putInt(row); // FIXME: hardcoded term size.
+ packet_sender_->putInt(col);
+ packet_sender_->putInt(0);
+ packet_sender_->putInt(0);
+ packet_sender_->putByte(0);
+ packet_sender_->write();
+ service_state_ = FQTermSSH1Channel::REQPTY_SENT;
+
+ is_closed_ = false;
+}
+
+void FQTermSSH1Channel::changeTermSize(int col, int row) {
+ packet_sender_->startPacket(SSH1_CMSG_WINDOW_SIZE);
+ packet_sender_->putInt(row);
+ packet_sender_->putInt(col);
+ packet_sender_->putInt(0);
+ packet_sender_->putInt(0);
+ packet_sender_->write();
+}
+
+void FQTermSSH1Channel::sendData(const char *data, int len) {
+ packet_sender_->startPacket(SSH1_CMSG_STDIN_DATA);
+ packet_sender_->putInt(len);
+ packet_sender_->putRawData(data, len);
+ packet_sender_->write();
+}
+
+void FQTermSSH1Channel::closeConnection(const char *reason) {
+ packet_sender_->startPacket(SSH1_MSG_DISCONNECT);
+ packet_sender_->putString(reason);
+ packet_sender_->write();
+ is_closed_ = true;
+}
+
+void FQTermSSH1Channel::handlePacket(int type) {
+ switch (service_state_) {
+ case BEGIN_SERVICE:
+ FQ_TRACE("sshchannel", 0) << "Channel: We should not be here";
+ break;
+ case REQPTY_SENT:
+ if (type != SSH1_SMSG_SUCCESS) {
+ emit channelError(tr("Server refused pty allocation!"));
+ }
+ packet_sender_->startPacket(SSH1_CMSG_EXEC_SHELL);
+ packet_sender_->write();
+ emit channelOK();
+ service_state_ = FQTermSSH1Channel::SERVICE_OK;
+ //emit msg to tell window we could process input.
+ break;
+ case SERVICE_OK:
+ switch (type) {
+ case SSH1_SMSG_STDOUT_DATA:
+ case SSH1_SMSG_STDERR_DATA:
+ {
+ const char *data = (const char *)packet_receiver_->buffer_->data() + 4;
+ int len = packet_receiver_->packetDataLen() - 4;
+ emit channelReadyRead(data, len);
+ }
+ break;
+ case SSH1_SMSG_X11_OPEN:
+ case SSH1_SMSG_AGENT_OPEN:
+ case SSH1_MSG_PORT_OPEN:
+ {
+ int i = packet_receiver_->getInt();
+ packet_sender_->startPacket(SSH1_MSG_CHANNEL_OPEN_FAILURE);
+ packet_sender_->putInt(i);
+ packet_sender_->write();
+ }
+ break;
+ case SSH1_SMSG_EXIT_STATUS:
+ packet_sender_->startPacket(SSH1_CMSG_EXIT_CONFIRMATION);
+ packet_sender_->write();
+ closeConnection("end");
+ is_closed_ = true;
+ break;
+ case SSH1_SMSG_SUCCESS:
+ case SSH1_SMSG_FAILURE:
+ break;
+ default:
+ FQ_TRACE("sshchannel", 0) << "Unimplemented message: "
+ << service_state_;
+ }
+ }
+}
+
+
+//==============================================================================
+//FQTermSSH2Channel
+//==============================================================================
+u_int32_t FQTermSSH2Channel::generateChannelID() {
+ static u_int32_t id = 0;
+ return id++;
+}
+
+FQTermSSH2Channel::FQTermSSH2Channel()
+ : FQTermSSHChannel(),
+ col_(80),
+ row_(24),
+ termtype_("vt100") {
+ channel_id_ = generateChannelID();
+ server_channel_id_ = 0xCCCCCCCC;
+ local_window_size_ = 0;
+ channel_state_ = FQTermSSH2Channel::BEGIN_CHANNEL;
+}
+
+void FQTermSSH2Channel::initChannel(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype) {
+ FQ_FUNC_TRACE("ssh2channel", 5);
+ col_ = col;
+ row_ = row;
+ termtype_ = termtype;
+ packet_receiver_ = packet;
+ packet_sender_ = output;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)), this, SLOT(handlePacket(int))));
+
+ // byte SSH_MSG_CHANNEL_OPEN
+ // string channel type in US-ASCII only
+ // uint32 sender channel
+ // uint32 initial window size
+ // uint32 maximum packet size
+ // .... channel type specific data follows
+
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_OPEN);
+ packet_sender_->putString("session");
+ packet_sender_->putInt(channel_id_);
+ packet_sender_->putInt(MAX_LOCAL_WINDOW_SIZE); // TODO: what's the best window size?
+ packet_sender_->putInt(MAX_LOCAL_PACKET_SIZE); // TODO: what's the best maximum packet size?
+ packet_sender_->write();
+
+ server_window_size_ = 0;
+ server_max_packet_size_ = 0;
+ local_window_size_ = MAX_LOCAL_WINDOW_SIZE;
+
+ is_closed_ = false;
+}
+
+void FQTermSSH2Channel::changeTermSize(int col, int row) {
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "window-change"
+ // boolean FALSE
+ // uint32 terminal width, columns
+ // uint32 terminal height, rows
+ // uint32 terminal width, pixels
+ // uint32 terminal height, pixels
+
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_REQUEST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString("window-change");
+ packet_sender_->putByte(false);
+ packet_sender_->putInt(col);
+ packet_sender_->putInt(row);
+ packet_sender_->putInt(640); // FIXME: hard-coded screen pixels.
+ packet_sender_->putInt(480);
+ packet_sender_->write();
+}
+
+void FQTermSSH2Channel::sendData(const char *data, int len) {
+ if (len > (int)server_window_size_ || len > (int)server_max_packet_size_) {
+ FQ_TRACE("ssh2channel", 3) << "Data length is greater than server's capacity: "
+ << "data length: " << len << ", "
+ << "server window: " << server_window_size_ << ", "
+ << "server packet max size: " << server_max_packet_size_;
+ return;
+ }
+
+ // byte SSH_MSG_CHANNEL_DATA
+ // uint32 recipient channel
+ // string data
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_DATA);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString(data, len);
+ packet_sender_->write();
+
+ server_window_size_ -= len;;
+
+ FQ_TRACE("ssh2channel", 5) << len
+ << " bytes data sent, server window size left: "
+ << server_window_size_;;
+}
+
+void FQTermSSH2Channel::closeConnection(const char *reason) {
+ packet_sender_->startPacket(SSH1_MSG_DISCONNECT);
+ packet_sender_->putString(reason);
+ packet_sender_->write();
+ is_closed_ = true;
+}
+
+void FQTermSSH2Channel::requestPty() {
+ if (packet_receiver_->packetType() == SSH2_MSG_CHANNEL_OPEN_FAILURE) {
+ // TODO: Here the error reason in the packet is ignored.
+ emit channelError(tr("Server refuces to open a channel."));
+ return;
+ }
+
+ if (packet_receiver_->packetType() != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
+ emit channelError(tr("Server error when opening a channel."));
+ return;
+ }
+
+ FQ_TRACE("ssh2channel", 5) << "Channel open. Try to request a pty.";
+
+ // byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION
+ // uint32 recipient channel
+ // uint32 sender channel
+ // uint32 initial window size
+ // uint32 maximum packet size
+ // .... channel type specific data follows
+ packet_receiver_->consume(4);
+ server_channel_id_ = packet_receiver_->getInt();
+ server_window_size_ = packet_receiver_->getInt();
+ server_max_packet_size_ = packet_receiver_->getInt();
+
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "pty-req"
+ // boolean want_reply
+ // string TERM environment variable value (e.g., vt100)
+ // uint32 terminal width, characters (e.g., 80)
+ // uint32 terminal height, rows (e.g., 24)
+ // uint32 terminal width, pixels (e.g., 640)
+ // uint32 terminal height, pixels (e.g., 480)
+ // string encoded terminal modes
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_REQUEST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString("pty-req");
+ packet_sender_->putByte(true);
+ packet_sender_->putString(termtype_.toLatin1()); // TODO: hardcoded term type.
+ packet_sender_->putInt(col_); // FIXME: hardcoded screen parameters.
+ packet_sender_->putInt(row_);
+ packet_sender_->putInt(640);
+ packet_sender_->putInt(480);
+ packet_sender_->putString(""); // TODO: no modes sent.
+ packet_sender_->write();
+}
+
+
+void FQTermSSH2Channel::requestShell() {
+ if (packet_receiver_->packetType() != SSH2_MSG_CHANNEL_SUCCESS) {
+ emit channelError(tr("Server refused pty allocation!"));
+ }
+ FQ_TRACE("ssh2channel", 5) << "Pty allocated. Now try to request a shell.";
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "shell"
+ // boolean want reply
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_REQUEST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putString("shell");
+ packet_sender_->putByte(true);
+ packet_sender_->write();
+}
+
+void FQTermSSH2Channel::checkLocalWindowSize() {
+ if (local_window_size_ < MAX_LOCAL_WINDOW_SIZE/2) {
+ // byte SSH_MSG_CHANNEL_WINDOW_ADJUST
+ // uint32 recipient channel
+ // uint32 bytes to add
+ int inc = MAX_LOCAL_WINDOW_SIZE/2;
+ local_window_size_ += inc;
+
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->putInt(inc);
+ packet_sender_->write();
+ }
+}
+
+void FQTermSSH2Channel::processChannelPacket() {
+ switch (packet_receiver_->packetType()) {
+ case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
+ {
+ // byte SSH_MSG_CHANNEL_WINDOW_ADJUST
+ // uint32 recipient channel
+ // uint32 bytes to add
+ packet_receiver_->consume(4); // channel id is already checked.
+ int inc = packet_receiver_->getInt();
+ server_window_size_ += inc;
+ FQ_TRACE("ssh2channel", 5) << "Server window size increased from "
+ << server_window_size_ - inc
+ << " to " << server_window_size_;
+ }
+ break;
+ case SSH2_MSG_CHANNEL_DATA:
+ {
+ // byte SSH_MSG_CHANNEL_DATA
+ // uint32 recipient channel
+ // string data
+ packet_receiver_->consume(4);
+ int len = packet_receiver_->getInt();
+ const char *data = (const char *)packet_receiver_->buffer_->data();
+ local_window_size_ -= len;
+ checkLocalWindowSize();
+ emit channelReadyRead(data, len);
+ }
+ break;
+ case SSH2_MSG_CHANNEL_EXTENDED_DATA:
+ {
+ // byte SSH_MSG_CHANNEL_DATA
+ // uint32 recipient channel
+ // string data
+ packet_receiver_->consume(4);
+ int len = packet_receiver_->getInt();
+ const char *data = (const char *)packet_receiver_->buffer_->data();
+ local_window_size_ -= len;
+ checkLocalWindowSize();
+ emit channelReadyRead(data, len);
+ }
+ break;
+ case SSH2_MSG_CHANNEL_EOF:
+ case SSH2_MSG_CHANNEL_CLOSE:
+ // byte SSH_MSG_CHANNEL_EOF
+ // uint32 recipient channel
+ // FIXME: this error would cause the connection closed, while only the channel need be closed in ssh2.
+ emit channelError(tr("Channel closed by the server."));
+ break;
+ case SSH2_MSG_CHANNEL_REQUEST:
+ // byte SSH_MSG_CHANNEL_REQUEST
+ // uint32 recipient channel
+ // string "xon-xoff"
+ // boolean FALSE
+ // boolean client can do
+
+ // TODO: just ignore this message currently.
+ break;
+ }
+}
+
+void FQTermSSH2Channel::handlePacket(int type) {
+ // first check the channel id.
+ u_int32_t channel_id = ntohu32(packet_receiver_->buffer_->data());
+ if (channel_id != channel_id_) {
+ return;
+ }
+
+ switch (channel_state_) {
+ case FQTermSSH2Channel::BEGIN_CHANNEL:
+ requestPty();
+ channel_state_ = FQTermSSH2Channel::REQUEST_PTY_SENT;
+ break;
+ case FQTermSSH2Channel::REQUEST_PTY_SENT:
+ requestShell();
+ channel_state_ = FQTermSSH2Channel::REQUEST_SHELL_SENT;
+ break;
+ case FQTermSSH2Channel::REQUEST_SHELL_SENT:
+ switch (type) {
+ case SSH2_MSG_CHANNEL_REQUEST:
+ {
+ FQ_TRACE("ssh2channel", 8) << "SSH2_MSG_CHANNEL_REQUEST isn't supported, just send back a packet with SSH2_MSG_CHANNEL_SUCCESS if reply is needed.";
+
+ packet_receiver_->consume(4);
+ u_int32_t len = ntohu32(packet_receiver_->buffer_->data());
+ packet_receiver_->consume(4 + len);
+ bool replyNeeded = packet_receiver_->getByte();
+
+ if (replyNeeded) {
+ packet_sender_->startPacket(SSH2_MSG_CHANNEL_SUCCESS);
+ packet_sender_->putInt(server_channel_id_);
+ packet_sender_->write();
+ }
+ }
+ break;
+ case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
+ {
+ packet_receiver_->consume(4);
+ u_int32_t inc = packet_receiver_->getInt();
+ server_window_size_ += inc;
+ }
+ break;
+ case SSH2_MSG_CHANNEL_SUCCESS:
+ emit channelOK();
+ channel_state_ = FQTermSSH2Channel::CHANNEL_OK;
+ //emit a msg to tell window we could process input.
+ break;
+ case SSH2_MSG_CHANNEL_FAILURE:
+ emit channelError(tr("Can't open a shell."));
+ break;
+ default:
+ emit channelError(tr("Unsupported packet."));
+ break;
+ }
+ break;
+ case FQTermSSH2Channel::CHANNEL_OK:
+ processChannelPacket();
+ break;
+ }
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh_channel.moc"
diff --git a/src/protocol/internal/fqterm_ssh_channel.h b/src/protocol/internal/fqterm_ssh_channel.h
new file mode 100644
index 0000000..9922528
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_channel.h
@@ -0,0 +1,130 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_CHANNEL_H
+#define FQTERM_SSH_CHANNEL_H
+
+#include "fqterm_ssh_types.h"
+
+#include <QObject>
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSHChannel: public QObject {
+ Q_OBJECT;
+protected:
+ bool is_closed_;
+
+ FQTermSSHPacketReceiver *packet_receiver_;
+ FQTermSSHPacketSender *packet_sender_;
+
+public:
+ FQTermSSHChannel(){}
+ virtual ~FQTermSSHChannel(){}
+ virtual void initChannel(FQTermSSHPacketReceiver *packet,
+ FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype) = 0;
+ virtual void closeConnection(const char *reason) = 0;
+
+ // TODO: it seems this function isn't used.
+ virtual void changeTermSize(int col, int row) = 0;
+
+ virtual void sendData(const char *data, int len) = 0;
+
+public slots:
+ virtual void handlePacket(int type) = 0;
+signals:
+ void channelOK();
+ void channelReadyRead(const char *data, int len);
+ void channelError(QString);
+};
+
+class FQTermSSH1Channel: public FQTermSSHChannel {
+ Q_OBJECT;
+private:
+ enum FQTermSSH1ChannelState {
+ BEGIN_SERVICE, REQPTY_SENT,
+ //REQCMD_SENT,
+ SERVICE_OK
+ } service_state_;
+
+public:
+ FQTermSSH1Channel();
+ virtual void initChannel(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype);
+ virtual void closeConnection(const char *reason);
+ virtual void changeTermSize(int col, int row);
+ virtual void sendData(const char *data, int len);
+
+public slots:
+ virtual void handlePacket(int type);
+signals:
+ void channelReadyRead(const char *data, int len);
+};
+
+
+class FQTermSSH2Channel: public FQTermSSHChannel {
+ Q_OBJECT;
+private:
+ static u_int32_t generateChannelID();
+
+private:
+ int col_;
+ int row_;
+ QString termtype_;
+ enum FQTermSSH2ChannelState {
+ BEGIN_CHANNEL, REQUEST_PTY_SENT, REQUEST_SHELL_SENT, CHANNEL_OK
+ } channel_state_;
+
+ u_int32_t channel_id_;
+
+ enum {MAX_LOCAL_WINDOW_SIZE = 0x100000, MAX_LOCAL_PACKET_SIZE = 0x4000};
+
+ u_int32_t local_window_size_;
+
+ u_int32_t server_channel_id_;
+ u_int32_t server_window_size_; // connection packet window size;
+ u_int32_t server_max_packet_size_; // max size of each packet sent to server.
+
+ void requestPty();
+ void requestShell();
+ void processChannelPacket();
+ void checkLocalWindowSize();
+
+public:
+ FQTermSSH2Channel();
+ virtual void initChannel(FQTermSSHPacketReceiver *packet, FQTermSSHPacketSender *output,
+ int col, int row, const QString& termtype);
+ virtual void closeConnection(const char *reason);
+ virtual void changeTermSize(int col, int row);
+ virtual void sendData(const char *data, int len);
+
+public slots:
+ virtual void handlePacket(int type);
+signals:
+ void channelReadyRead(const char *data, int len);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_CHANNEL_H
diff --git a/src/protocol/internal/fqterm_ssh_cipher.h b/src/protocol/internal/fqterm_ssh_cipher.h
new file mode 100644
index 0000000..13bc9f3
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_cipher.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_CIPHER_H
+#define FQTERM_SSH_CIPHER_H
+
+#include <stdlib.h>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_const.h"
+
+namespace FQTerm {
+
+class FQTermSSHCipher {
+protected:
+ const char *d_name;
+
+public:
+ FQTermSSHCipher() {
+ d_name = NULL;
+ }
+
+ virtual ~FQTermSSHCipher(){}
+
+ const char *name() const {
+ return d_name;
+ }
+
+ virtual int blockSize() const = 0;
+ virtual int getKeySize() const = 0;
+ virtual int getIVSize() const = 0;
+
+ virtual void setIV(const u_char *data) = 0;
+ virtual void setKey(const u_char *data) = 0;
+ virtual void encrypt(const u_char *source, u_char *dest, int len) = 0;
+ virtual void decrypt(const u_char *source, u_char *dest, int len) = 0;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_CIPHER_H
diff --git a/src/protocol/internal/fqterm_ssh_const.h b/src/protocol/internal/fqterm_ssh_const.h
new file mode 100644
index 0000000..412760e
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_const.h
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERMCONST_H
+#define FQTERMCONST_H
+
+namespace FQTerm {
+
+#define SSH_CIPHER_SSH2 -3
+#define SSH_CIPHER_ILLEGAL -2
+#define SSH_CIPHER_NOT_SET -1
+#define SSH_CIPHER_NONE 0
+#define SSH_CIPHER_IDEA 1
+#define SSH_CIPHER_DES 2
+#define SSH_CIPHER_3DES 3
+#define SSH_CIPHER_BROKEN_TSS 4
+#define SSH_CIPHER_BROKEN_RC4 5
+#define SSH_CIPHER_BLOWFISH 6
+#define SSH_CIPHER_RESERVED 7
+#define SSH_CIPHER_MAX 31
+
+#define SSH1_MSG_DISCONNECT 1
+#define SSH1_SMSG_PUBLIC_KEY 2
+#define SSH1_CMSG_SESSION_KEY 3
+#define SSH1_CMSG_USER 4
+#define SSH1_CMSG_AUTH_RSA 6
+#define SSH1_SMSG_AUTH_RSA_CHALLENGE 7
+#define SSH1_CMSG_AUTH_RSA_RESPONSE 8
+#define SSH1_CMSG_AUTH_PASSWORD 9
+#define SSH1_CMSG_REQUEST_PTY 10
+#define SSH1_CMSG_WINDOW_SIZE 11
+#define SSH1_CMSG_EXEC_SHELL 12
+#define SSH1_CMSG_EXEC_CMD 13
+#define SSH1_SMSG_SUCCESS 14
+#define SSH1_SMSG_FAILURE 15
+#define SSH1_CMSG_STDIN_DATA 16
+#define SSH1_SMSG_STDOUT_DATA 17
+#define SSH1_SMSG_STDERR_DATA 18
+#define SSH1_CMSG_EOF 19
+#define SSH1_SMSG_EXIT_STATUS 20
+#define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION 21
+#define SSH1_MSG_CHANNEL_OPEN_FAILURE 22
+#define SSH1_MSG_CHANNEL_DATA 23
+#define SSH1_MSG_CHANNEL_CLOSE 24
+#define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION 25
+#define SSH1_SMSG_X11_OPEN 27
+#define SSH1_CMSG_PORT_FORWARD_REQUEST 28
+#define SSH1_MSG_PORT_OPEN 29
+#define SSH1_CMSG_AGENT_REQUEST_FORWARDING 30
+#define SSH1_SMSG_AGENT_OPEN 31
+#define SSH1_MSG_IGNORE 32
+#define SSH1_CMSG_EXIT_CONFIRMATION 33
+#define SSH1_CMSG_X11_REQUEST_FORWARDING 34
+#define SSH1_CMSG_AUTH_RHOSTS_RSA 35
+#define SSH1_MSG_DEBUG 36
+#define SSH1_CMSG_REQUEST_COMPRESSION 37
+#define SSH1_CMSG_AUTH_TIS 39
+#define SSH1_SMSG_AUTH_TIS_CHALLENGE 40
+#define SSH1_CMSG_AUTH_TIS_RESPONSE 41
+#define SSH1_CMSG_AUTH_CCARD 70
+#define SSH1_SMSG_AUTH_CCARD_CHALLENGE 71
+#define SSH1_CMSG_AUTH_CCARD_RESPONSE 72
+#define SSH1_AUTH_TIS 5
+#define SSH1_PROTOFLAG_SCREEN_NUMBER 1
+#define SSH1_PROTOFLAGS_SUPPORTED 0
+
+
+#define SSH2_MSG_DISCONNECT 1
+#define SSH2_MSG_IGNORE 2
+#define SSH2_MSG_UNIMPLEMENTED 3
+#define SSH2_MSG_DEBUG 4
+#define SSH2_MSG_SERVICE_REQUEST 5
+#define SSH2_MSG_SERVICE_ACCEPT 6
+#define SSH2_MSG_KEXINIT 20
+#define SSH2_MSG_NEWKEYS 21
+#define SSH2_MSG_KEXDH_INIT 30
+#define SSH2_MSG_KEXDH_REPLY 31
+#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30
+#define SSH2_MSG_KEX_DH_GEX_GROUP 31
+#define SSH2_MSG_KEX_DH_GEX_INIT 32
+#define SSH2_MSG_KEX_DH_GEX_REPLY 33
+#define SSH2_MSG_KEX_DH_GEX_REQUEST 34
+#define SSH2_MSG_USERAUTH_REQUEST 50
+#define SSH2_MSG_USERAUTH_FAILURE 51
+#define SSH2_MSG_USERAUTH_SUCCESS 52
+#define SSH2_MSG_USERAUTH_BANNER 53
+#define SSH2_MSG_USERAUTH_PK_OK 60
+#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60
+#define SSH2_MSG_USERAUTH_INFO_REQUEST 60
+#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61
+#define SSH2_MSG_GLOBAL_REQUEST 80
+#define SSH2_MSG_REQUEST_SUCCESS 81
+#define SSH2_MSG_REQUEST_FAILURE 82
+#define SSH2_MSG_CHANNEL_OPEN 90
+#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91
+#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92
+#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93
+#define SSH2_MSG_CHANNEL_DATA 94
+#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95
+#define SSH2_MSG_CHANNEL_EOF 96
+#define SSH2_MSG_CHANNEL_CLOSE 97
+#define SSH2_MSG_CHANNEL_REQUEST 98
+#define SSH2_MSG_CHANNEL_SUCCESS 99
+#define SSH2_MSG_CHANNEL_FAILURE 100
+#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
+#define SSH2_DISCONNECT_PROTOCOL_ERROR 2
+#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3
+#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4
+#define SSH2_DISCONNECT_RESERVED 4
+#define SSH2_DISCONNECT_MAC_ERROR 5
+#define SSH2_DISCONNECT_COMPRESSION_ERROR 6
+#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7
+#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
+#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
+#define SSH2_DISCONNECT_CONNECTION_LOST 10
+#define SSH2_DISCONNECT_BY_APPLICATION 11
+#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12
+#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13
+#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
+#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15
+#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1
+#define SSH2_OPEN_CONNECT_FAILED 2
+#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3
+#define SSH2_OPEN_RESOURCE_SHORTAGE 4
+#define SSH2_EXTENDED_DATA_STDERR 1
+
+} // namespace FQTerm
+
+#endif // FQTERMCONST_H
diff --git a/src/protocol/internal/fqterm_ssh_des.cpp b/src/protocol/internal/fqterm_ssh_des.cpp
new file mode 100644
index 0000000..603b6fe
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_des.cpp
@@ -0,0 +1,180 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <memory.h>
+#include <openssl/des.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+#include "fqterm_ssh_const.h"
+#include "fqterm_ssh_des.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+//==============================================================================
+//FQTermSSH1DES3
+//==============================================================================
+
+FQTermSSH1DES3::FQTermSSH1DES3() {
+ d_name = "des3-cbc";
+
+ memset(d_IV1, 0, sizeof(d_IV1));
+ memset(d_IV2, 0, sizeof(d_IV2));
+ memset(d_IV3, 0, sizeof(d_IV3));
+}
+
+int FQTermSSH1DES3::blockSize() const {
+ return 8;
+}
+
+void FQTermSSH1DES3::decrypt(const u_char *source, u_char *dest, int len) {
+ DES_ncbc_encrypt(source, dest, len, &d_key3, &d_IV3, DES_DECRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key2, &d_IV2, DES_ENCRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key1, &d_IV1, DES_DECRYPT);
+}
+
+void FQTermSSH1DES3::encrypt(const u_char *source, u_char *dest, int len) {
+ DES_ncbc_encrypt(source, dest, len, &d_key1, &d_IV1, DES_ENCRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key2, &d_IV2, DES_DECRYPT);
+ DES_ncbc_encrypt(dest, dest, len, &d_key3, &d_IV3, DES_ENCRYPT);
+}
+
+int FQTermSSH1DES3::getKeySize() const {
+ return 3*DES_KEY_SZ;
+}
+
+int FQTermSSH1DES3::getIVSize() const {
+ return 0;
+}
+
+void FQTermSSH1DES3::setIV(const u_char *data) {
+ memset(d_IV1, 0, sizeof(d_IV1));
+ memset(d_IV2, 0, sizeof(d_IV2));
+ memset(d_IV3, 0, sizeof(d_IV3));
+}
+
+void FQTermSSH1DES3::setKey(const u_char *data) {
+ DES_cblock key;
+ memset(key, 0, sizeof(key));
+ memcpy(key, data, sizeof(key));
+ DES_set_key(&key, &d_key1);
+ data += 8;
+ memset(key, 0, sizeof(key));
+ memcpy(key, data, sizeof(key));
+ DES_set_key(&key, &d_key2);
+ data += 8;
+ memset(key, 0, sizeof(key));
+ memcpy(key, data, sizeof(key));
+ DES_set_key(&key, &d_key3);
+}
+
+
+//==================================================
+// TripleDES-CBC
+//==================================================
+
+FQTermSSH2TripleDESCBC::FQTermSSH2TripleDESCBC() {
+ d_name = "des3-cbc";
+ ctx_ = NULL;
+}
+
+FQTermSSH2TripleDESCBC::~FQTermSSH2TripleDESCBC() {
+ if (ctx_ != NULL) {
+ EVP_CIPHER_CTX_cleanup(ctx_);
+ delete ctx_;
+ }
+}
+
+
+int FQTermSSH2TripleDESCBC::blockSize() const {
+ return 8;
+}
+
+int FQTermSSH2TripleDESCBC::getKeySize() const {
+ return 24;
+}
+
+int FQTermSSH2TripleDESCBC::getIVSize() const {
+ return 8;
+}
+
+void FQTermSSH2TripleDESCBC::setIV(const u_char *data) {
+ memcpy(IV_, data, getIVSize());
+}
+
+void FQTermSSH2TripleDESCBC::setKey(const u_char *data) {
+ memcpy(key_, data, getKeySize());
+}
+
+void FQTermSSH2TripleDESCBC::encrypt(const u_char *source, u_char *dest, int len) {
+ FQ_TRACE("3DES_CBC", 9) << "Start encrypting";
+ FQ_TRACE("3DES_CBC", 9) << "data len:" << len;
+ FQ_TRACE("3DES_CBC", 9) << "Source: \n" << dumpHexString << std::string((char *)source, len);
+
+ int ret = 0;
+ if (ctx_ == NULL) {
+ // Lazy initialization.
+ ctx_ = new EVP_CIPHER_CTX;
+ EVP_CIPHER_CTX_init(ctx_);
+ ret = EVP_CipherInit(ctx_, EVP_des_ede3_cbc(), key_, IV_, 1);
+ FQ_VERIFY(ret == 1);
+ }
+
+ ret = EVP_Cipher(ctx_, dest, source, len);
+
+ FQ_VERIFY(ret == 1);
+
+ FQ_TRACE("3DES_CBC", 9) << "Dest: \n" << dumpHexString << std::string((char *)dest, len);
+
+ FQ_TRACE("3DES_CBC", 9) << "IV:\n" << dumpHexString << std::string((char *)IV_, getIVSize());
+ FQ_TRACE("3DES_CBC", 9) << "key:\n" << dumpHexString << std::string((char *)key_, getKeySize());
+
+}
+
+void FQTermSSH2TripleDESCBC::decrypt(const u_char *source, u_char *dest, int len) {
+ FQ_TRACE("3DES_CBC", 9) << "Start dencrypting";
+ FQ_TRACE("3DES_CBC", 9) << "data len:" << len;
+ FQ_TRACE("3DES_CBC", 9) << "Source: \n" << dumpHexString << std::string((char *)source, len);
+
+ int ret = 0;
+ if (ctx_ == NULL) {
+ // Lazy initialization.
+ ctx_ = new EVP_CIPHER_CTX;
+ EVP_CIPHER_CTX_init(ctx_);
+ ret = EVP_CipherInit(ctx_, EVP_des_ede3_cbc(), key_, IV_, 0);
+ FQ_VERIFY(ret == 1);
+ }
+
+ ret = EVP_Cipher(ctx_, dest, source, len);
+
+ FQ_VERIFY(ret == 1);
+
+ FQ_TRACE("3DES_CBC", 9) << "Dest: \n" << dumpHexString << std::string((char *)dest, len);
+
+ FQ_TRACE("3DES_CBC", 9) << "IV:\n" << dumpHexString << std::string((char *)IV_, getIVSize());
+ FQ_TRACE("3DES_CBC", 9) << "key:\n" << dumpHexString << std::string((char *)key_, getKeySize());
+}
+
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_des.h b/src/protocol/internal/fqterm_ssh_des.h
new file mode 100644
index 0000000..ba153f2
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_des.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_DES_H
+#define FQTERM_SSH_DES_H
+
+#include <openssl/ssl.h>
+#include <openssl/des.h>
+
+#include "fqterm_ssh_cipher.h"
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+class FQTermSSH1DES3: public FQTermSSHCipher {
+ private:
+ DES_cblock d_IV1;
+ DES_cblock d_IV2;
+ DES_cblock d_IV3;
+ DES_key_schedule d_key1;
+ DES_key_schedule d_key2;
+ DES_key_schedule d_key3;
+ public:
+ FQTermSSH1DES3();
+
+ virtual int blockSize() const;
+ virtual int getKeySize() const;
+ virtual int getIVSize() const;
+ virtual void setIV(const u_char *data);
+ virtual void setKey(const u_char *data);
+ virtual void encrypt(const u_char *source, u_char *dest, int len);
+ virtual void decrypt(const u_char *source, u_char *dest, int len);
+};
+
+class FQTermSSH2TripleDESCBC: public FQTermSSHCipher {
+ private:
+ unsigned char IV_[8];
+ unsigned char key_[24];
+
+ EVP_CIPHER_CTX *ctx_;
+
+ public:
+ FQTermSSH2TripleDESCBC();
+ ~FQTermSSH2TripleDESCBC();
+
+ virtual int blockSize() const;
+ virtual int getKeySize() const;
+ virtual int getIVSize() const;
+ virtual void setIV(const u_char *data);
+ virtual void setKey(const u_char *data);
+ virtual void encrypt(const u_char *source, u_char *dest, int len);
+ virtual void decrypt(const u_char *source, u_char *dest, int len);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_DES_H
diff --git a/src/protocol/internal/fqterm_ssh_hash.h b/src/protocol/internal/fqterm_ssh_hash.h
new file mode 100644
index 0000000..b4679f4
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_hash.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_HASH_H
+#define FQTERM_SSH_HASH_H
+
+#include "fqterm_ssh_types.h"
+
+namespace FQTerm {
+
+class FQTermSSHHash {
+protected:
+ int d_digestLength;
+ int digestLength()const {
+ return d_digestLength;
+ }
+
+public:
+ FQTermSSHHash() {
+ d_digestLength = 0;
+ }
+ virtual ~FQTermSSHHash() {}
+
+ virtual void update(u_char *data, int len) = 0;
+ virtual void final(u_char *data) = 0;
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_HASH_H
diff --git a/src/protocol/internal/fqterm_ssh_kex.cpp b/src/protocol/internal/fqterm_ssh_kex.cpp
new file mode 100644
index 0000000..d27bf14
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_kex.cpp
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_kex.h"
+#include "fqterm_ssh_md5.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+FQTermSSHKex::FQTermSSHKex(const char *V_C, const char *V_S) {
+ V_C_ = new char[strlen(V_C) + 1];
+ V_S_ = new char[strlen(V_S) + 1];
+
+ strcpy(V_C_, V_C);
+ strcpy(V_S_, V_S);
+}
+
+FQTermSSHKex::~FQTermSSHKex() {
+ delete[] V_C_;
+ delete[] V_S_;
+}
+
+
+//==============================================================================
+//FQTermSSH1Kex
+//==============================================================================
+
+FQTermSSH1Kex::FQTermSSH1Kex(const char *V_C, const char *V_S)
+ : FQTermSSHKex(V_C, V_S) {
+ is_first_kex_ = true;
+ kex_state_ = FQTermSSH1Kex::BEFORE_PUBLICKEY;
+}
+
+FQTermSSH1Kex::~FQTermSSH1Kex(){}
+
+void FQTermSSH1Kex::initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *packetSender) {
+ packet_receiver_ = packetReceiver;
+ packet_sender_ = packetSender;
+ packet_receiver_->disconnect(this);
+ FQ_VERIFY(connect(packet_receiver_, SIGNAL(packetAvaliable(int)),
+ this, SLOT(handlePacket(int))));
+ kex_state_ = FQTermSSH1Kex::BEFORE_PUBLICKEY;
+ emit reKex();
+}
+
+void FQTermSSH1Kex::handlePacket(int type) {
+ switch (kex_state_) {
+ case FQTermSSH1Kex::BEFORE_PUBLICKEY:
+ makeSessionKey();
+ kex_state_ = FQTermSSH1Kex::SESSIONKEY_SENT;
+ break;
+ case FQTermSSH1Kex::SESSIONKEY_SENT:
+ if (type != SSH1_SMSG_SUCCESS) {
+ emit kexError(tr("Kex exchange failed!"));
+ break;
+ }
+ emit kexOK();
+ kex_state_ = FQTermSSH1Kex::KEYEX_OK;
+ break;
+ case FQTermSSH1Kex::KEYEX_OK:
+ break;
+ }
+}
+
+void FQTermSSH1Kex::makeSessionKey() {
+ int i;
+ BIGNUM *key;
+ u_int32_t rand_val;
+ int bits;
+ int rbits;
+
+ if (packet_receiver_->packetType() != SSH1_SMSG_PUBLIC_KEY) {
+ emit kexError(tr("startKex: First packet is not public key"));
+ return ;
+ }
+ packet_receiver_->getRawData((char*)cookie_, 8);
+
+ // Get the public key.
+ server_key_ = new FQTermSSHRSA;
+ bits = packet_receiver_->getInt();
+ packet_receiver_->getBN(server_key_->d_rsa->e);
+ packet_receiver_->getBN(server_key_->d_rsa->n);
+
+ rbits = BN_num_bits(server_key_->d_rsa->n);
+ if (bits != rbits) {
+ FQ_TRACE("sshkex", 0) << "Warning: Server lies about "
+ << "size of server public key: "
+ << "actual size: " << rbits
+ << " vs. anounced: " << bits;
+ FQ_TRACE("sshkex", 0) << "Warning: This may be due to "
+ << "an old implementation of ssh.";
+ }
+
+ // Get the host key.
+ host_key_ = new FQTermSSHRSA;
+ bits = packet_receiver_->getInt();
+ packet_receiver_->getBN(host_key_->d_rsa->e);
+ packet_receiver_->getBN(host_key_->d_rsa->n);
+
+ rbits = BN_num_bits(host_key_->d_rsa->n);
+ if (bits != rbits) {
+ FQ_TRACE("sshkex", 0) << "Warning: Server lies about "
+ << "size of server public key: "
+ << "actual size: " << rbits
+ << " vs. anounced: " << bits;
+ FQ_TRACE("sshkex", 0) << "Warning: This may be due to "
+ << "an old implementation of ssh.";
+ }
+
+ // Get protocol flags.
+ server_flag_ = packet_receiver_->getInt();
+ ciphers_ = packet_receiver_->getInt();
+ auth_ = packet_receiver_->getInt();
+
+ if ((ciphers_ &(1 << SSH_CIPHER_3DES)) == 0) {
+ FQ_VERIFY(false); // server do not support my cipher
+ }
+
+ makeSessionId();
+
+ // Generate an encryption key for the session. The key is a 256 bit
+ // random number, interpreted as a 32-byte key, with the least
+ // significant 8 bits being the first byte of the key.
+
+ for (i = 0; i < 32; i++) {
+ if (i % 4 == 0) {
+ rand_val = rand();
+ }
+
+ session_key_[i] = (rand_val &0xff);
+ rand_val >>= 8;
+ }
+
+ key = BN_new();
+
+ BN_set_word(key, 0);
+ for (i = 0; i < 32; i++) {
+ BN_lshift(key, key, 8);
+ if (i < 16) {
+ BN_add_word(key, session_key_[i] ^ session_id_[i]);
+ } else {
+ BN_add_word(key, session_key_[i]);
+ }
+ }
+
+ if (BN_cmp(server_key_->d_rsa->n, host_key_->d_rsa->n) < 0) {
+ server_key_->publicEncrypt(key, key);
+ host_key_->publicEncrypt(key, key);
+ } else {
+ host_key_->publicEncrypt(key, key);
+ server_key_->publicEncrypt(key, key);
+ }
+
+ delete host_key_;
+ delete server_key_;
+
+ packet_sender_->startPacket(SSH1_CMSG_SESSION_KEY);
+ packet_sender_->putByte(SSH_CIPHER_3DES);
+ packet_sender_->putRawData((const char*)cookie_, 8);
+ packet_sender_->putBN(key);
+
+ BN_free(key);
+
+ packet_sender_->putInt(1);
+ packet_sender_->write();
+
+ emit startEncryption(session_key_);
+}
+
+void FQTermSSH1Kex::makeSessionId() {
+ u_char *p;
+ FQTermSSHMD5 *md5;
+ int servlen, hostlen;
+
+ md5 = new FQTermSSHMD5;
+ servlen = BN_num_bytes(server_key_->d_rsa->n);
+ hostlen = BN_num_bytes(host_key_->d_rsa->n);
+
+ p = new u_char[servlen + hostlen];
+
+ BN_bn2bin(host_key_->d_rsa->n, p);
+ BN_bn2bin(server_key_->d_rsa->n, p + hostlen);
+ md5->update(p, servlen + hostlen);
+ md5->update(cookie_, 8);
+ md5->final(session_id_);
+ delete md5;
+ delete [] p;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh_kex.moc"
diff --git a/src/protocol/internal/fqterm_ssh_kex.h b/src/protocol/internal/fqterm_ssh_kex.h
new file mode 100644
index 0000000..b2f9c56
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_kex.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_KEX_H
+#define FQTERM_SSH_KEX_H
+
+#include <openssl/bn.h>
+#include <QObject>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_rsa.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh_const.h"
+
+namespace FQTerm {
+
+class FQTermSSHPacketReceiver;
+class FQTermSSHPacketSender;
+
+class FQTermSSHKex: public QObject {
+ Q_OBJECT;
+protected:
+ FQTermSSHPacketReceiver *packet_receiver_;
+ FQTermSSHPacketSender *packet_sender_;
+
+ char *V_C_;
+ char *V_S_;
+public:
+ // Init with
+ // string V_C, the client's identification string (CR and LF
+ // excluded)
+ // string V_S, the server's identification string (CR and LF
+ // excluded)
+ FQTermSSHKex(const char *V_C, const char *V_S);
+ virtual ~FQTermSSHKex();
+
+ virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *outputSender) = 0;
+
+public slots:
+ virtual void handlePacket(int type) = 0;
+
+signals:
+ void kexOK();
+ void reKex();
+ void kexError(QString);
+
+ void startEncryption(const u_char *sessionkey);
+
+};
+
+class FQTermSSH1Kex: public FQTermSSHKex {
+ Q_OBJECT;
+private:
+ enum FQTermSSH1KexState {
+ BEFORE_PUBLICKEY, SESSIONKEY_SENT, KEYEX_OK
+ } kex_state_;
+
+ bool is_first_kex_;
+
+ FQTermSSHRSA *host_key_;
+ FQTermSSHRSA *server_key_;
+
+ u_char cookie_[8];
+ int server_flag_, ciphers_, auth_;
+ u_char session_id_[16];
+ u_char session_key_[32];
+
+ void makeSessionId();
+ void makeSessionKey();
+
+public:
+ FQTermSSH1Kex(const char *V_C, const char *V_S);
+ ~FQTermSSH1Kex();
+ virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
+ FQTermSSHPacketSender *outputSender);
+
+ virtual void handlePacket(int type);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_KEX_H
diff --git a/src/protocol/internal/fqterm_ssh_mac.cpp b/src/protocol/internal/fqterm_ssh_mac.cpp
new file mode 100644
index 0000000..e2d345f
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_mac.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_mac.h"
+#include "fqterm_ssh_packet.h"
+
+namespace FQTerm {
+
+void FQTermSSHSHA1::setKey(const unsigned char *key) {
+ memcpy(key_, key, keySize());
+}
+
+int FQTermSSHSHA1::keySize() const {
+ return SHA_DIGEST_LENGTH;
+}
+
+int FQTermSSHSHA1::digestSize() const {
+ return SHA_DIGEST_LENGTH;
+}
+
+void FQTermSSHSHA1::getDigest(const unsigned char *data, int len, unsigned char *digest) const {
+ unsigned int tmp;
+ HMAC(EVP_sha1(), key_, SHA_DIGEST_LENGTH, data, len, digest, &tmp);
+
+ FQ_TRACE("SHA1", 9) << "Key: \n" << dumpHexString << std::string((char *)key_, SHA_DIGEST_LENGTH);
+ FQ_TRACE("SHA1", 9) << "data len:" << len;
+ FQ_TRACE("SHA1", 9) << "data:\n" << dumpHexString << std::string((char *)data, len);
+ FQ_TRACE("SHA1", 9) << "digest len:" << tmp;
+ FQ_TRACE("SHA1", 9) << "digest:\n" << dumpHexString << std::string((char *)digest, tmp);
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_mac.h b/src/protocol/internal/fqterm_ssh_mac.h
new file mode 100644
index 0000000..545909c
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_mac.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_MAC_H
+#define FQTERM_SSH_MAC_H
+
+#include <openssl/sha.h>
+
+namespace FQTerm {
+
+class FQTermSSHMac {
+public:
+ FQTermSSHMac() {}
+ virtual ~FQTermSSHMac() {}
+ virtual void setKey(const unsigned char *key) = 0;
+ virtual int keySize() const = 0;
+ virtual int digestSize() const = 0;
+ virtual void getDigest(const unsigned char *data, int len, unsigned char *digest) const = 0;
+};
+
+const int FQTERM_SSH_MAC_NONE = 0;
+const int FQTERM_SSH_HMAC_SHA1 = 1;
+
+class FQTermSSHSHA1: public FQTermSSHMac {
+ unsigned char key_[SHA_DIGEST_LENGTH];
+
+public:
+ virtual void setKey(const unsigned char *key);
+ virtual int keySize() const;
+ virtual int digestSize() const;
+ virtual void getDigest(const unsigned char *data, int len, unsigned char *digest) const;
+};
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_MAC_H
diff --git a/src/protocol/internal/fqterm_ssh_md5.cpp b/src/protocol/internal/fqterm_ssh_md5.cpp
new file mode 100644
index 0000000..10713e9
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_md5.cpp
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_ssh_md5.h"
+
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSHMD5
+//==============================================================================
+void FQTermSSHMD5::final(u_char *digest) {
+ MD5_Final(digest, &d_md5);
+}
+
+void FQTermSSHMD5::update(u_char *data, int len) {
+ MD5_Update(&d_md5, data, len);
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_md5.h b/src/protocol/internal/fqterm_ssh_md5.h
new file mode 100644
index 0000000..abb8127
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_md5.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_MD5_H
+#define FQTERM_SSH_MD5_H
+
+#include <stdio.h>
+
+#include <openssl/md5.h>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_hash.h"
+
+namespace FQTerm {
+
+class FQTermSSHMD5: public FQTermSSHHash {
+protected:
+ MD5_CTX d_md5;
+public:
+ FQTermSSHMD5()
+ : FQTermSSHHash() {
+ d_digestLength = 16;
+ MD5_Init(&d_md5);
+ }
+ virtual ~FQTermSSHMD5() {}
+
+ void update(u_char *data, int len);
+ void final(u_char *digest);
+};
+
+} // namespace FQTerm
+
+#endif //FQTERM_SSH_MD5_H
diff --git a/src/protocol/internal/fqterm_ssh_packet.cpp b/src/protocol/internal/fqterm_ssh_packet.cpp
new file mode 100644
index 0000000..9c4ff6c
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_packet.cpp
@@ -0,0 +1,242 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh_packet.h"
+#include "fqterm_ssh_des.h"
+
+#include "fqterm_serialization.h"
+#include "crc32.h"
+
+namespace FQTerm {
+
+//==============================================================================
+//FQTermSSHPacketSender
+//==============================================================================
+
+FQTermSSHPacketSender::FQTermSSHPacketSender() {
+ buffer_ = new FQTermSSHBuffer(1024);
+ output_buffer_ = new FQTermSSHBuffer(1024);
+
+ is_encrypt_ = false;
+ cipher_type_ = SSH_CIPHER_NONE;
+ cipher_ = NULL;
+ setEncryptionType(SSH_CIPHER_3DES);
+
+ is_mac_ = false;
+ mac_type_ = FQTERM_SSH_MAC_NONE;
+ mac_ = NULL;
+
+ is_compressed_ = false;
+
+ sequence_no_ = 0;
+}
+
+FQTermSSHPacketSender::~FQTermSSHPacketSender() {
+ delete buffer_;
+ delete output_buffer_;
+ if (is_encrypt_) {
+ delete cipher_;
+ }
+}
+
+void FQTermSSHPacketSender::putRawData(const char *data, int len) {
+ buffer_->putRawData(data, len);
+}
+
+void FQTermSSHPacketSender::putByte(int data) {
+ buffer_->putByte(data);
+}
+
+void FQTermSSHPacketSender::putInt(u_int data) {
+ buffer_->putInt(data);
+}
+
+void FQTermSSHPacketSender::putString(const char *string, int len) {
+ buffer_->putString(string, len);
+}
+
+void FQTermSSHPacketSender::putBN(BIGNUM *bn) {
+ buffer_->putSSH1BN(bn);
+}
+
+void FQTermSSHPacketSender::putBN2(BIGNUM *bn) {
+ buffer_->putSSH2BN(bn);
+}
+
+void FQTermSSHPacketSender::startPacket(int pkt_type) {
+ buffer_->clear();
+ buffer_->putByte(pkt_type);
+}
+
+void FQTermSSHPacketSender::write() {
+ makePacket();
+ emit dataToWrite();
+}
+
+void FQTermSSHPacketSender::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH1DES3;
+ break;
+ }
+}
+
+void FQTermSSHPacketSender::startEncryption(const u_char *key, const u_char *IV) {
+ is_encrypt_ = true;
+ cipher_->setIV(IV);
+ cipher_->setKey(key);
+}
+
+void FQTermSSHPacketSender::resetEncryption() {
+ is_encrypt_ = false;
+}
+
+void FQTermSSHPacketSender::setMacType(int macType) {
+ mac_type_ = macType;
+
+ delete mac_;
+ mac_ = NULL;
+
+ switch (mac_type_) {
+ case FQTERM_SSH_HMAC_SHA1:
+ mac_ = new FQTermSSHSHA1;
+ break;
+ }
+}
+
+void FQTermSSHPacketSender::startMac(const u_char *key) {
+ is_mac_ = true;
+ mac_->setKey(key);
+}
+
+void FQTermSSHPacketSender::resetMac() {
+ is_mac_ = false;
+}
+
+//==============================================================================
+//FQTermSSHPacketReceiver
+//==============================================================================
+
+FQTermSSHPacketReceiver::FQTermSSHPacketReceiver() {
+ buffer_ = new FQTermSSHBuffer(1024);
+
+ is_decrypt_ = false;
+ cipher_type_ = SSH_CIPHER_NONE;
+ cipher_ = NULL;
+ setEncryptionType(SSH_CIPHER_3DES);
+
+ is_mac_ = false;
+ mac_type_ = FQTERM_SSH_MAC_NONE;
+ mac_ = NULL;
+
+ is_compressed_ = false;
+
+ sequence_no_ = 0;
+}
+
+FQTermSSHPacketReceiver::~FQTermSSHPacketReceiver() {
+ delete buffer_;
+ if (is_decrypt_) {
+ delete cipher_;
+ }
+}
+
+void FQTermSSHPacketReceiver::getRawData(char *data, int length) {
+ buffer_->getRawData(data, length);
+}
+
+u_char FQTermSSHPacketReceiver::getByte() {
+ return buffer_->getByte();
+}
+
+u_int FQTermSSHPacketReceiver::getInt() {
+ return buffer_->getInt();
+}
+
+void *FQTermSSHPacketReceiver::getString(int *length) {
+ return buffer_->getString(length);
+}
+
+void FQTermSSHPacketReceiver::getBN(BIGNUM *bignum) {
+ buffer_->getSSH1BN(bignum);
+}
+
+void FQTermSSHPacketReceiver::getBN2(BIGNUM *bignum) {
+ buffer_->getSSH2BN(bignum);
+}
+
+void FQTermSSHPacketReceiver::consume(int len) {
+ buffer_->consume(len);
+}
+
+void FQTermSSHPacketReceiver::setEncryptionType(int cipherType) {
+ cipher_type_ = cipherType;
+
+ delete cipher_;
+ cipher_ = NULL;
+
+ switch (cipher_type_) {
+ case SSH_CIPHER_3DES:
+ cipher_ = new FQTermSSH1DES3;
+ break;
+ }
+}
+
+void FQTermSSHPacketReceiver::startEncryption(const u_char *key, const u_char *IV) {
+ is_decrypt_ = true;
+ cipher_->setIV(IV);
+ cipher_->setKey(key);
+}
+
+void FQTermSSHPacketReceiver::resetEncryption() {
+ is_decrypt_ = false;
+}
+
+void FQTermSSHPacketReceiver::setMacType(int macType) {
+ mac_type_ = macType;
+ delete mac_;
+ mac_ = NULL;
+
+ switch (mac_type_) {
+ case FQTERM_SSH_HMAC_SHA1:
+ mac_ = new FQTermSSHSHA1;
+ break;
+ }
+}
+
+void FQTermSSHPacketReceiver::startMac(const u_char *key) {
+ is_mac_ = true;
+ mac_->setKey(key);
+}
+
+void FQTermSSHPacketReceiver::resetMac() {
+ is_mac_ = false;
+}
+
+} // namespace FQTerm
+
+#include "fqterm_ssh_packet.moc"
diff --git a/src/protocol/internal/fqterm_ssh_packet.h b/src/protocol/internal/fqterm_ssh_packet.h
new file mode 100644
index 0000000..ed5a488
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_packet.h
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_PACKET_H
+#define FQTERM_SSH_PACKET_H
+
+#include <openssl/bn.h>
+
+#include <QObject>
+
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh_mac.h"
+#include "fqterm_ssh_cipher.h"
+#include "fqterm_serialization.h"
+
+namespace FQTerm {
+
+class FQTermSSHPacketSender: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermSSHBuffer *output_buffer_;
+ FQTermSSHBuffer *buffer_;
+
+ FQTermSSHPacketSender();
+ virtual ~FQTermSSHPacketSender();
+
+ void startPacket(int pkt_type);
+ void putByte(int data);
+ void putInt(u_int data);
+ void putString(const char *string, int len = -1);
+ void putRawData(const char *data, int length);
+ void putBN(BIGNUM *bignum);
+ void putBN2(BIGNUM *bignum);
+ void write();
+
+ int getIVSize() const { return cipher_->getIVSize();}
+ int getKeySize() const { return cipher_->getKeySize();}
+ int getMacKeySize() const { return mac_->keySize();}
+
+ public slots:
+ virtual void setEncryptionType(int cipherType);
+ void startEncryption(const u_char *key, const u_char *IV = NULL);
+ void resetEncryption();
+
+ void setMacType(int macType);
+ void startMac(const u_char *sessionkey);
+ void resetMac();
+
+ void enableCompress(int enable) {is_compressed_ = enable;};
+
+ signals:
+ void dataToWrite();
+
+ protected:
+ bool is_encrypt_;
+ int cipher_type_;
+ FQTermSSHCipher *cipher_;
+
+ bool is_mac_;
+ int mac_type_;
+ FQTermSSHMac *mac_;
+
+ bool is_compressed_;
+
+ u_int32_t sequence_no_;
+
+ virtual void makePacket() = 0;
+};
+
+class FQTermSSHPacketReceiver: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermSSHBuffer *buffer_;
+
+ FQTermSSHPacketReceiver();
+ virtual ~FQTermSSHPacketReceiver();
+
+ int packetType()const {
+ return packet_type_;
+ }
+
+ u_char getByte();
+ u_int getInt();
+ void *getString(int *length = NULL);
+ void getRawData(char *data, int length);
+ void getBN(BIGNUM *bignum);
+ void getBN2(BIGNUM *bignum);
+ void consume(int len);
+
+ virtual int packetDataLen() const { return real_data_len_;}
+ int getIVSize() const { return cipher_->getIVSize();}
+ int getKeySize() const { return cipher_->getKeySize();}
+ int getMacKeySize() const { return mac_->keySize();}
+
+ virtual void parseData(FQTermSSHBuffer *input) = 0;
+ public slots:
+ virtual void setEncryptionType(int cipherType);
+ void startEncryption(const u_char *key, const u_char *IV = NULL);
+ void resetEncryption();
+
+ void setMacType(int macType);
+ void startMac(const u_char *sessionkey);
+ void resetMac();
+
+ void enableCompress(int enable) {is_compressed_ = enable;};
+
+ signals:
+ void packetAvaliable(int type);
+ void packetError(QString);
+
+ protected:
+ bool is_decrypt_;
+ int cipher_type_;
+ FQTermSSHCipher *cipher_;
+
+ bool is_mac_;
+ int mac_type_;
+ FQTermSSHMac *mac_;
+
+ bool is_compressed_;
+
+ int packet_type_;
+ int real_data_len_;
+
+ u_int32_t sequence_no_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_PACKET
diff --git a/src/protocol/internal/fqterm_ssh_pubkey.h b/src/protocol/internal/fqterm_ssh_pubkey.h
new file mode 100644
index 0000000..0de957c
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_pubkey.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_PUB_KEY_H
+#define FQTERM_SSH_PUB_KEY_H
+
+#include <openssl/bn.h>
+
+namespace FQTerm {
+
+class FQTermSSHPubKey {
+public:
+ FQTermSSHPubKey() {}
+ virtual ~FQTermSSHPubKey() {}
+ virtual void publicEncrypt(BIGNUM *, BIGNUM*) = 0;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_PUB_KEY_H
diff --git a/src/protocol/internal/fqterm_ssh_rsa.cpp b/src/protocol/internal/fqterm_ssh_rsa.cpp
new file mode 100644
index 0000000..dd36898
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_rsa.cpp
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QGlobalStatic>
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_types.h"
+#include "fqterm_ssh_rsa.h"
+
+namespace FQTerm {
+
+FQTermSSHRSA::FQTermSSHRSA() {
+ d_rsa = RSA_new();
+ d_rsa->n = BN_new();
+ d_rsa->e = BN_new();
+}
+
+FQTermSSHRSA::~FQTermSSHRSA() {
+ if (d_rsa != NULL) {
+ RSA_free(d_rsa);
+ }
+}
+
+void FQTermSSHRSA::publicEncrypt(BIGNUM *out, BIGNUM *in) {
+ u_char *inbuf, *outbuf;
+ int len, ilen, olen;
+
+ if (BN_num_bits(d_rsa->e) < 2 || !BN_is_odd(d_rsa->e)) {
+ FQ_VERIFY(false); // public_encrypt() exponent too small or not odd.
+ }
+
+ olen = BN_num_bytes(d_rsa->n);
+ outbuf = new u_char[olen];
+
+ ilen = BN_num_bytes(in);
+ inbuf = new u_char[ilen];
+ BN_bn2bin(in, inbuf);
+
+ if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, d_rsa, RSA_PKCS1_PADDING)) <= 0) {
+ //RSA_PKCS1_PADDING = 1
+ FQ_VERIFY(false); // "rsa_public_encrypt() failed.
+ }
+
+ BN_bin2bn(outbuf, len, out);
+
+ delete [] outbuf;
+ delete [] inbuf;
+}
+
+} // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_rsa.h b/src/protocol/internal/fqterm_ssh_rsa.h
new file mode 100644
index 0000000..bfe89ce
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_rsa.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_RSA_H
+#define FQTERM_SSH_RSA_H
+
+#include <openssl/rsa.h>
+
+#include "fqterm_ssh_pubkey.h"
+
+namespace FQTerm {
+
+class FQTermSSHRSA: public FQTermSSHPubKey {
+public:
+ RSA *d_rsa;
+ FQTermSSHRSA();
+ virtual ~FQTermSSHRSA();
+
+ virtual void publicEncrypt(BIGNUM *, BIGNUM*);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_RSA_H
diff --git a/src/protocol/internal/fqterm_ssh_types.h b/src/protocol/internal/fqterm_ssh_types.h
new file mode 100644
index 0000000..c10bfac
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh_types.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_TYPES_H
+#define FQTERM_SSH_TYPES_H
+
+#include <QGlobalStatic>
+#if !defined(Q_OS_WIN32) && !defined(_OS_WIN32_)
+#include <sys/types.h>
+#else
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+#ifdef QT3_SUPPORT
+typedef Q_UINT32 u_int32_t;
+typedef Q_UINT64 u_int64_t;
+#else
+typedef quint32 u_int32_t;
+typedef quint64 u_int64_t;
+#endif // QT3_SUPPORT
+
+#endif // Q_OS_WIN32
+
+#endif // FQTERM_SSH_TYPES_H
diff --git a/src/terminal/CMakeLists.txt b/src/terminal/CMakeLists.txt
new file mode 100644
index 0000000..c3cf3db
--- /dev/null
+++ b/src/terminal/CMakeLists.txt
@@ -0,0 +1,46 @@
+set(export_SRCS
+ fqterm_buffer.h
+ fqterm_session.h
+ fqterm_text_line.h
+ fqterm_session.cpp
+ fqterm_buffer.cpp
+ fqterm_text_line.cpp
+)
+
+set(internal_SRCS
+ internal/fqterm_decode.h
+ internal/fqterm_telnet.h
+ internal/fqterm_zmodem.h
+ internal/fqterm_decode.cpp
+ internal/fqterm_telnet.cpp
+ internal/fqterm_zmodem.cpp
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/internal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_SOURCE_DIR}/../utilities
+ ${CMAKE_CURRENT_SOURCE_DIR}/../protocol
+)
+
+QT4_AUTOMOC(
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+add_library(fqterm_terminal
+ ${export_SRCS}
+ ${internal_SRCS}
+)
+
+add_dependencies(fqterm_terminal
+ fqterm_common
+ fqterm_protocol
+ fqterm_utilities
+)
diff --git a/src/terminal/fqterm_buffer.cpp b/src/terminal/fqterm_buffer.cpp
new file mode 100644
index 0000000..c00e079
--- /dev/null
+++ b/src/terminal/fqterm_buffer.cpp
@@ -0,0 +1,998 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <algorithm>
+#include <map>
+#include <vector>
+
+#include <QString>
+#include <QRect>
+#include <QRegExp>
+
+#include "fqterm.h"
+#include "common.h"
+#include "fqterm_buffer.h"
+#include "fqterm_text_line.h"
+
+namespace FQTerm {
+
+typedef std::vector<int> TabStops;
+
+/* staight from linux/drivers/char/consolemap.c, GNU GPL:ed */
+static const UTF16 VT_SPECIAL_GRAPHICS_TABLE[256]={
+ /* VT100 graphics mapped to Unicode */
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
+ 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
+ 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
+ 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
+ 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+ 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+ 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+};
+
+FQTermBuffer::FQTermBuffer(int column, int row, int max_hist_line, bool is_bbs) {
+ tab_stops_ = new TabStops;
+ num_rows_ = row;
+ num_columns_ = column;
+ max_num_hist_lines_ = max_hist_line;
+ is_bbs_ = is_bbs;
+
+ num_hist_lines_ = 0;
+
+ while (text_lines_.count() < num_rows_) {
+ text_lines_.append(new FQTermTextLine(num_columns_));
+ }
+
+ top_row_ = 0;
+ bottom_row_ = num_rows_ - 1;
+
+ is_g0_used_ = true;
+
+ is_insert_mode_ = false;
+ is_ansi_mode_ = true;
+ is_newline_mode_ = false;
+ is_cursor_mode_ = false;
+ is_numeric_mode_ = true;
+ is_origin_mode_ = false;
+ is_autowrap_mode_ = false;
+ is_autorepeat_mode_ = true;
+ is_lightbg_mode_ = false;
+
+ selection_start_ = QPoint(-1, -1);
+ selection_end_ = QPoint(-1, -1);
+}
+
+FQTermBuffer::~FQTermBuffer(){
+ foreach(FQTermTextLine *line, text_lines_) {
+ delete line;
+ }
+
+ delete (TabStops *)tab_stops_;
+}
+
+FQTermBuffer::Caret::Caret()
+ : column_(0),
+ row_(0),
+ color_(NO_COLOR),
+ attr_(NO_ATTR),
+ G0_(ASCII_SET),
+ G1_(ASCII_SET) {
+}
+
+void FQTermBuffer::setTermSize(int col, int row) {
+ FQ_TRACE("term", 3) << "Change term size to "
+ << col << "x" << row;
+
+ if (num_columns_ == col && num_rows_ == row) {
+ return;
+ }
+
+ clearSelect();
+
+ if (num_rows_ < row) {
+ for (int i = 0; i < row - num_rows_; i++) {
+ text_lines_.append(new FQTermTextLine(col));
+ }
+ } else if (num_rows_ > row) {
+ for (int i = 0; i < num_rows_ - row; i++) {
+ delete text_lines_.takeLast();
+ }
+ }
+
+ num_columns_ = col;
+ num_rows_ = row;
+
+ top_row_ = 0;
+ bottom_row_ = num_rows_ - 1;
+
+ // TODO: how about saved caret column?
+ // TODO: why make last saved equal to current position?
+ last_saved_caret_.row_ = caret_.row_ = qMin(caret_.row_, row - 1);
+
+ for (int i = 0; i < text_lines_.size(); ++i) {
+ text_lines_.at(i)->setMaxCellCount(num_columns_);
+ }
+
+// this->clearArea(0, 0, num_columns_, num_rows_, 0, 0);
+ // this->moveCaretTo(0, 0);
+
+ moveCaretTo(qMin(caret_.column_, col - 1), qMin(caret_.row_, row - 1));
+
+ emit onSetTermSize(col, row);
+ emit termSizeChanged(num_columns_, num_rows_);
+}
+
+int FQTermBuffer::getNumColumns() const {
+ return num_columns_;
+}
+
+int FQTermBuffer::getNumRows() const {
+ return num_rows_;
+}
+
+int FQTermBuffer::getNumLines() const {
+ return num_rows_ + num_hist_lines_;
+}
+
+const FQTermTextLine *FQTermBuffer::getTextLineInBuffer(int line_index) const {
+ return text_lines_.value(line_index, NULL);
+}
+
+const FQTermTextLine *FQTermBuffer::getTextLineInTerm(int line_index) const {
+ return text_lines_.value(line_index + num_hist_lines_, NULL);
+}
+
+void FQTermBuffer::setCurrentAttr(unsigned char color, unsigned char attr) {
+ caret_.color_ = color;
+ caret_.attr_ = attr;
+}
+
+void FQTermBuffer::writeText(const QString &str, int charstate) {
+
+ QString cstr = str;
+
+ FQ_TRACE("term", 8) << "Add text: \"" << cstr << "\"";
+
+#if 0
+ if ((is_g0_used_ && caret_.G0_ == SPECIAL_GRAPHICS) ||
+ (!is_g0_used_ && caret_.G1_ == SPECIAL_GRAPHICS)) {
+
+ // FIXME: will this break the utf-16 sequence?
+ for (int i = 0; i < cstr.size(); ++i) {
+ if (cstr[i] >= 0137 && cstr[i] <= 0176) {
+ cstr[i] = VT_SPECIAL_GRAPHICS_TABLE[cstr.at(i).unicode()];
+ }
+ }
+ }
+#endif
+
+ // Insert the str into the buffer. Different pieces of text might be
+ // written into different lines.
+ while (!cstr.isEmpty()) {
+ FQTermTextLine *line = text_lines_.value(num_hist_lines_ + caret_.row_, NULL);
+
+ if (line == NULL) {
+ FQ_TRACE("error", 0) << "Error: setBuffer null line";
+ return ;
+ }
+
+ if (charstate & FQTermTextLine::SECONDPART) {
+ moveCaretOffset(-1, 0);
+ }
+
+ if (caret_.column_ >= (int)line->getMaxCellCount()) {
+ // move the caret to the next line.
+ moveCaretTo(0, caret_.row_ + 1, true);
+ continue;
+ }
+
+ if (caret_.column_ > (int)line->getWidth()) {
+ line->appendWhiteSpace(caret_.column_ - line->getWidth());
+ }
+
+ unsigned cell_begin = line->getCellBegin(caret_.column_);
+ int max_width = line->getMaxCellCount() - cell_begin;
+ int element_consumed = 0;
+ int width = get_str_width((const UTF16 *)cstr.data(), cstr.size(),
+ max_width, element_consumed);
+
+ if (width < 0) {
+ break;
+ }
+
+ if (is_insert_mode_) {
+ // FIXEME: How to move cursor if the entire line is wider than
+ // line->getMaxCellCount() after insertion?
+ line->insertText((UTF16 *)cstr.data(), element_consumed, cell_begin,
+ caret_.color_, caret_.attr_, charstate);
+ if ((int)line->getWidth() > num_columns_) {
+ line->deleteText(num_columns_, line->getWidth());
+ }
+ } else {
+ line->replaceText((UTF16 *)cstr.data(), element_consumed,
+ cell_begin, qMin(cell_begin + width, line->getWidth()),
+ caret_.color_, caret_.attr_, charstate);
+ }
+ moveCaretOffset(width, 0);
+
+ if (element_consumed == 0)
+ {
+ element_consumed = 1;
+ }
+
+ if (element_consumed == cstr.size()) {
+ break;
+ }
+
+ cstr.remove(0, element_consumed);
+ }
+}
+
+void FQTermBuffer::lineFeed() {
+ FQ_TRACE("term", 8) << "add a new line";
+ if (caret_.row_ == bottom_row_)
+ scrollLinesInTerm(top_row_, 1);
+ if (is_newline_mode_) {
+ moveCaretOffset(-caret_.column_, 1);
+ } else {
+ moveCaretOffset(0, 1);
+ }
+}
+
+void FQTermBuffer::tab() {
+ FQ_TRACE("term", 8) << "add a tab";
+ int x = getTabStop(caret_.column_);
+
+ moveCaretTo(x, caret_.row_);
+}
+
+int FQTermBuffer::getTabStop(int column) {
+
+ std::vector<int> &tabs = *(TabStops *)tab_stops_;
+
+ if (tabs.size() == 0) {
+ int res = ((caret_.column_) / 8 + 1) * 8;
+ return (res < num_columns_) ? res : num_columns_ - 1;
+ }
+
+ std::vector<int>::iterator it =
+ std::upper_bound(tabs.begin(), tabs.end(), column);
+
+ int res = num_columns_ - 1;
+
+ if (it != tabs.end() && *it < res) {
+ res = *it;
+ }
+
+ if (res > num_columns_ - 1) {
+ res = num_columns_ - 1;
+ }
+
+ return res;
+}
+
+void FQTermBuffer::addTabStop() {
+ // FIXME: what if the caret is located beyond the term temporarily.
+ int x = caret_.column_;
+
+ std::vector<int> &tabs = *(TabStops *)tab_stops_;
+
+ std::vector<int>::iterator it =
+ std::lower_bound(tabs.begin(), tabs.end(), x);
+
+ if (it == tabs.end() || *it != x) {
+ tabs.insert(it, x);
+ }
+}
+
+void FQTermBuffer::clearTabStop(bool clear_all) {
+ // FIXME: what if the caret is located beyond the term temporarily.
+ std::vector<int> &tabs = *(TabStops *)tab_stops_;
+
+ if (clear_all) {
+ tabs.clear();
+ return;
+ }
+
+ int x = caret_.column_;
+
+ std::vector<int>::iterator it =
+ std::lower_bound(tabs.begin(), tabs.end(), x);
+
+ if (it != tabs.end() && *it == x) {
+ tabs.erase(it);
+ }
+}
+
+void FQTermBuffer::setMargins(int top, int bottom) {
+ FQ_TRACE("term", 3) << "Set margins: [" << top << ", " << bottom << "]";
+
+ top_row_ = qMax(top, 0);
+ bottom_row_ = qMin(qMax(bottom, 0), num_rows_ - 1);
+
+ if (is_origin_mode_) {
+ moveCaretTo(0, top_row_);
+ } else {
+ moveCaretTo(0, 0);
+ }
+}
+
+void FQTermBuffer::moveCaretTo(int column, int row, bool scroll_if_necessary) {
+ if (row != caret_.row_)
+ emit caretChangeRow();
+
+ FQ_TRACE("term", 5) << "Move caret to (" << column << ", " << row << ")";
+
+ //If th
+
+ // detect index boundary
+ if (column >= num_columns_) {
+ column = num_columns_;
+ }
+ if (column < 0) {
+ column = 0;
+ }
+
+ int scroll_lines = 0;
+
+ int stop = is_origin_mode_ ? top_row_ : 0;
+ if (row < stop) {
+ scroll_lines = row - stop;
+ row = stop;
+ }
+
+ stop = is_origin_mode_ ? bottom_row_ : num_rows_ - 1;
+ if (row > stop) {
+ scroll_lines = row - stop;
+ row = stop;
+ }
+
+ // Set dirty flag for cells of the last caret position.
+ FQTermTextLine *line = text_lines_.value(num_hist_lines_ + caret_.row_, NULL);
+ if (0 <= caret_.column_ && caret_.column_ < (int)line->getWidth()) {
+ unsigned cell_begin = line->getCellBegin(caret_.column_);
+ unsigned cell_end = line->getCellBegin(caret_.column_ + 1);
+ line->setDirtyFlag(cell_begin, cell_end);
+ }
+
+ if (scroll_if_necessary) {
+ scrollLinesInTerm(top_row_, scroll_lines);
+ }
+
+ caret_.column_ = column;
+ caret_.row_ = row;
+}
+
+void FQTermBuffer::moveCaretOffset(int column_offset, int row_offset, bool scroll_if_necessary) {
+ if (caret_.column_ >= num_columns_) {
+ // it's only allowed that the caret_.column_ >= num_columns_
+ // temporarily when a sequence of normal text is received. if we
+ // found caret_.column_ is out of bounds in other case, we should
+ // correct it first.
+ if (is_bbs_) {
+ // but the BBS (newsmth.net) assumes that the caret could be
+ // located out of the screen :(
+ } else {
+ caret_.column_ = num_columns_ - 1;
+ }
+ }
+
+ if (caret_.column_ + column_offset < 0) {
+ column_offset = -caret_.column_;
+ }
+
+ moveCaretTo(caret_.column_ + column_offset, caret_.row_ + row_offset,
+ scroll_if_necessary);
+}
+
+void FQTermBuffer::changeCaretPosition(int coloumn, int row) {
+ if (is_origin_mode_) {
+ moveCaretTo(coloumn, row + top_row_);
+ } else {
+ moveCaretTo(coloumn, row);
+ }
+}
+
+void FQTermBuffer::saveCaret() {
+ FQ_TRACE("term", 5) << "save the caret.";
+ last_saved_caret_ = caret_;
+}
+
+void FQTermBuffer::restoreCaret() {
+ FQ_TRACE("term", 5) << "restore the caret.";
+ moveCaretTo(last_saved_caret_.column_, last_saved_caret_.row_);
+ caret_ = last_saved_caret_;
+}
+
+void FQTermBuffer::SelectVtCharacterSet(VtCharSet charset, bool G0) {
+ if (G0) {
+ caret_.G0_ = charset;
+ } else {
+ caret_.G1_ = charset;
+ }
+}
+
+void FQTermBuffer::invokeCharset(bool G0) {
+ if (G0) {
+ is_g0_used_ = true;
+ } else {
+ is_g0_used_ = false;
+ }
+}
+
+void FQTermBuffer::carriageReturn() {
+ FQ_TRACE("term", 8) << "carrige return";
+ moveCaretOffset(-caret_.column_, 0);
+}
+
+int FQTermBuffer::getCaretColumn() const {
+ return caret_.column_;
+}
+
+int FQTermBuffer::getCaretRow() const {
+ return caret_.row_;
+}
+
+int FQTermBuffer::getCaretLine() const {
+ return caret_.row_ + num_hist_lines_;
+}
+
+// erase functions
+void FQTermBuffer::eraseText(int cell_count) {
+ FQ_TRACE("term", 8) << "erase " << cell_count << " cell(s) of text";
+
+ const FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ int x = line->getWidth() - caret_.column_;
+
+ clearArea(caret_.column_, caret_.row_,
+ qMin(cell_count, x), 1,
+ caret_.color_, caret_.attr_);
+}
+
+void FQTermBuffer::deleteText(int cell_count) {
+ FQ_TRACE("term", 8) << "delete " << cell_count << " cell(s) of text";
+
+ FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ int x = line->getWidth() - caret_.column_;
+
+ if (cell_count >= x) {
+ line->deleteText(caret_.column_, line->getWidth());
+ } else {
+ line->deleteText(caret_.column_, caret_.column_ + cell_count);
+ }
+}
+
+void FQTermBuffer::fillScreenWith(char c) {
+ FQ_TRACE("term", 5) << "fill screen with '" << c << "'";
+ for (int i = 0; i < num_rows_; i++) {
+ FQTermTextLine *line = text_lines_[i + num_hist_lines_];
+ line->deleteAllText();
+ line->appendWhiteSpace(num_columns_, NO_COLOR, NO_ATTR, c);
+ }
+}
+
+void FQTermBuffer::insertSpaces(int count) {
+ FQ_TRACE("term", 8) << "insert " << count << " white space(s)";
+
+ FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ int x = line->getWidth() - caret_.column_;
+
+ if (count >= x) {
+ clearArea(caret_.column_, caret_.row_, x, caret_.row_,
+ caret_.color_, caret_.attr_);
+ } else {
+ line->insertWhiteSpace(count, caret_.column_, caret_.color_, caret_.attr_);
+ }
+}
+
+void FQTermBuffer::deleteLines(int line_count) {
+ FQ_TRACE("term", 8) << "delete " << line_count << " line(s)";
+
+ int y = bottom_row_ - caret_.row_;
+
+ if (line_count >= y) {
+ clearArea(0, caret_.row_, -1, y, caret_.color_, caret_.attr_);
+ } else {
+ scrollLinesInTerm(caret_.row_, line_count);
+ }
+}
+
+void FQTermBuffer::insertLines(int count) {
+ FQ_TRACE("term", 8) << "insert " << count << " line(s)";
+
+ int y = bottom_row_ - caret_.row_;
+
+ if (count >= y) {
+ clearArea(0, caret_.row_, -1, y, caret_.color_, caret_.attr_);
+ } else {
+ scrollLinesInTerm(caret_.row_, -count);
+ }
+}
+
+void FQTermBuffer::eraseToLineEnd() {
+ FQ_TRACE("term", 8) << "erase to line end";
+
+ clearArea(caret_.column_, caret_.row_, -1, 1, caret_.color_, caret_.attr_);
+}
+
+void FQTermBuffer::eraseToLineBegin() {
+ FQ_TRACE("term", 8) << "erase to line begin";
+ clearArea(0, caret_.row_, caret_.column_ + 1, 1, caret_.color_, caret_.attr_);
+}
+
+void FQTermBuffer::eraseEntireLine() {
+ FQ_TRACE("term", 8) << "erase entire line";
+ clearArea(0, caret_.row_, -1, 1, caret_.color_, caret_.attr_);
+}
+
+// Set a line of text on screen to have been changed from start to end.
+void FQTermBuffer::setLineChanged(int index, int cell_begin, int cell_end) {
+ FQ_ASSERT(0 <= index && index < num_rows_ + num_hist_lines_);
+ text_lines_[index]->setDirtyFlag(cell_begin, cell_end);
+}
+
+void FQTermBuffer::clearLineChanged(int index) {
+ FQ_ASSERT(0 <= index && index < num_rows_ + num_hist_lines_);
+ text_lines_[index]->clearDirtyFlag();
+}
+
+void FQTermBuffer::setLineAllChanged(int index) {
+ FQ_ASSERT(0 <= index && index < num_rows_ + num_hist_lines_);
+ text_lines_[index]->setAllDirty();
+}
+
+void FQTermBuffer::scrollLinesInTerm(int startRow, int numRows) {
+ if (numRows == 0 || startRow > bottom_row_) {
+ return ;
+ }
+ if (startRow < top_row_) {
+ startRow = top_row_;
+ }
+
+ // TODO: performance issue here. Reuse the old text lines.
+ if (numRows > 0) {
+ //We are scrolling the whole screen.
+ if (startRow == 0 && caret_.row_ == num_rows_ - 1) {
+ addHistoryLine(numRows);
+ } else {
+ // delete lines from startRow, insert lines on the bottom_row_.
+ while (numRows) {
+ delete text_lines_.takeAt(num_hist_lines_ + startRow);
+ text_lines_.insert(num_hist_lines_ + bottom_row_, new FQTermTextLine(num_columns_));
+ numRows--;
+ }
+ }
+ }
+
+ // TODO: performance issue here. Reuse the old text lines.
+ if (numRows < 0) {
+ // delete lines from bottom_row_, insert lines in the startRow.
+ while (numRows) {
+ delete text_lines_.takeAt(num_hist_lines_ + bottom_row_);
+ text_lines_.insert(num_hist_lines_ + startRow, new FQTermTextLine(num_columns_));
+ numRows++;
+ }
+ }
+
+ for (int i = num_hist_lines_ + startRow; i <= num_hist_lines_ + bottom_row_; i++) {
+ text_lines_.at(i)->setAllDirty();
+ }
+}
+
+void FQTermBuffer::eraseToTermEnd() {
+ FQ_TRACE("term", 8) << "erase to term end";
+
+ if (caret_.column_ == 0 && caret_.row_ == 0) {
+ eraseEntireTerm();
+ return ;
+ }
+
+ clearArea(caret_.column_, caret_.row_, -1, 1, caret_.color_, caret_.attr_);
+
+ if (caret_.row_ < bottom_row_) {
+ clearArea(0, caret_.row_ + 1,
+ -1, bottom_row_ - caret_.row_,
+ caret_.color_, caret_.attr_);
+ }
+}
+
+void FQTermBuffer::eraseToTermBegin() {
+ FQ_TRACE("term", 8) << "erase to term begin";
+ if (caret_.column_ == num_columns_ - 1 && caret_.row_ == num_rows_ - 1) {
+ eraseEntireTerm();
+ return ;
+ }
+
+ clearArea(0, caret_.row_, caret_.column_ + 1, 1, caret_.color_, caret_.attr_);
+ if (caret_.row_ > top_row_) {
+ clearArea(0, top_row_, -1, caret_.row_, caret_.color_, caret_.attr_);
+ }
+}
+
+void FQTermBuffer::eraseEntireTerm() {
+ FQ_TRACE("term", 8) << "erase entire term";
+ addHistoryLine(num_rows_);
+ clearArea(0, 0, num_columns_, num_rows_, caret_.color_, caret_.attr_);
+}
+
+// width = -1 : clear to end
+void FQTermBuffer::clearArea(int startColumn, int startRow,
+ int width, int height,
+ unsigned char color, unsigned char attr) {
+ QByteArray cstr;
+
+ FQTermTextLine *line;
+
+ if (startRow + height > num_rows_) {
+ height = num_rows_ - startRow;
+ }
+
+ for (int i = startRow; i < height + startRow; i++) {
+ line = text_lines_[i + num_hist_lines_];
+
+ int w = width;
+
+ if (startColumn < num_columns_) {
+ if (w == -1) {
+ w = num_columns_ - startColumn;
+ }
+
+ int endX = startColumn + w;
+ if (endX > (int)line->getWidth()) {
+ endX = line->getWidth();
+ }
+
+ if(startColumn>=endX)
+ {
+ continue;
+ }
+
+ line->replaceWithWhiteSpace(w, startColumn, endX, color, attr);
+ }
+ }
+}
+
+void FQTermBuffer::addHistoryLine(int n) {
+ bool is_full = (num_hist_lines_ == max_num_hist_lines_);
+
+ // TODO: performance issue. Reuse the old lines.
+ while (n) {
+ if (num_hist_lines_ == max_num_hist_lines_) {
+ delete text_lines_.takeFirst();
+ }
+
+ text_lines_.append(new FQTermTextLine(num_columns_));
+ num_hist_lines_ = qMin(num_hist_lines_ + 1, max_num_hist_lines_);
+ n--;
+ }
+
+ for (int i = num_hist_lines_ + 0; i < num_hist_lines_ + bottom_row_; i++) {
+ text_lines_.at(i)->setAllDirty();
+ }
+
+ if (!is_full) {
+ emit bufferSizeChanged();
+ }
+}
+
+void FQTermBuffer::startDecode() {
+ last_saved_caret_.column_ = caret_.column_;
+ last_saved_caret_.row_ = caret_.row_;
+}
+
+void FQTermBuffer::endDecode() {
+ if (last_saved_caret_.row_ < num_rows_) {
+ FQTermTextLine *line = text_lines_[last_saved_caret_.row_ + num_hist_lines_];
+
+ line->safelySetDirtyFlag(last_saved_caret_.column_,
+ last_saved_caret_.column_ + 1);
+ }
+
+ if (caret_.row_ < num_rows_) {
+ FQTermTextLine *line = text_lines_.at(caret_.row_ + num_hist_lines_);
+
+ line->safelySetDirtyFlag(caret_.column_, caret_.column_ + 1);
+ }
+
+ clearSelect();
+}
+
+void FQTermBuffer::setMode(TermMode mode) {
+ FQ_TRACE("term", 8) << "set mode " << mode;
+
+ switch (mode) {
+ case INSERT_MODE:
+ is_insert_mode_ = true;
+ break;
+ case CURSOR_MODE:
+ is_cursor_mode_ = true;
+ break;
+ case ANSI_MODE:
+ is_ansi_mode_ = true;
+ case NUMERIC_MODE:
+ is_numeric_mode_ = true;
+ break;
+ case SMOOTH_MODE:
+ is_smoothscroll_mode_ = true;
+ break;
+ case NEWLINE_MODE:
+ is_newline_mode_ = true;
+ break;
+ case ORIGIN_MODE:
+ is_origin_mode_ = true;
+ this->moveCaretTo(0, top_row_);
+ break;
+ case AUTOWRAP_MODE:
+ is_autowrap_mode_ = true;
+ break;
+ case AUTOREPEAT_MODE:
+ is_autorepeat_mode_ = true;
+ break;
+ case LIGHTBG_MODE:
+ is_lightbg_mode_ = true;
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermBuffer::resetMode(TermMode mode) {
+ FQ_TRACE("term", 8) << "reset mode " << mode;
+
+ switch (mode) {
+ case INSERT_MODE:
+ is_insert_mode_ = false;
+ break;
+ case CURSOR_MODE:
+ is_cursor_mode_ = false;
+ break;
+ case ANSI_MODE:
+ is_ansi_mode_ = false;
+ case NUMERIC_MODE:
+ is_numeric_mode_ = false;
+ break;
+ case SMOOTH_MODE:
+ is_smoothscroll_mode_ = false;
+ break;
+ case NEWLINE_MODE:
+ is_newline_mode_ = false;
+ break;
+ case ORIGIN_MODE:
+ is_origin_mode_ = false;
+ this->moveCaretTo(0, 0);
+ break;
+ case AUTOWRAP_MODE:
+ is_autowrap_mode_ = false;
+ break;
+ case AUTOREPEAT_MODE:
+ is_autorepeat_mode_ = false;
+ break;
+ case LIGHTBG_MODE:
+ is_lightbg_mode_ = false;
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermBuffer::setSelect(const QPoint &pt1, const QPoint &pt2) {
+ QPoint ptSelStart, ptSelEnd;
+
+ if (pt1.y() == pt2.y()) {
+ ptSelStart = pt1.x() < pt2.x() ? pt1 : pt2;
+ ptSelEnd = pt1.x() > pt2.x() ? pt1 : pt2;
+ } else {
+ ptSelStart = pt1.y() < pt2.y() ? pt1 : pt2;
+ ptSelEnd = pt1.y() > pt2.y() ? pt1 : pt2;
+ }
+
+ int y1 = ptSelStart.y();
+ int y2 = ptSelEnd.y();
+
+ if (!(selection_start_ == QPoint(-1, -1)
+ && selection_end_ == QPoint(-1, -1))) {
+ y1 = qMin(y1, selection_start_.y());
+ y2 = qMax(y2, selection_end_.y());
+ }
+
+ for (int i = y1; i <= y2; i++) {
+ text_lines_.value(i, NULL)->setAllDirty();
+ }
+
+ selection_start_ = ptSelStart;
+ selection_end_ = ptSelEnd;
+}
+
+void FQTermBuffer::clearSelect() {
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return;
+ }
+
+ for (int i = selection_start_.y(); i <= selection_end_.y(); i++) {
+ text_lines_.value(i, NULL)->setAllDirty();
+ }
+
+ selection_start_ = selection_end_ = QPoint(-1, -1);
+}
+
+bool FQTermBuffer::isSelected(int line_index) const {
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return false;
+ } else {
+ return line_index >= selection_start_.y() && line_index <= selection_end_.y();
+ }
+}
+
+bool FQTermBuffer::isSelected(const QPoint &cell, bool is_rect_sel) const {
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return false;
+ }
+
+ if (cell.y() < 0 || cell.y() >= getNumLines()) {
+ return false;
+ }
+
+ int x1 = selection_start_.x();
+ int y1 = selection_start_.y();
+
+ int x2 = selection_end_.x();
+ int y2 = selection_end_.y();
+
+ if (cell.y() < y1 || cell.y() > y2)
+ return false;
+
+ const FQTermTextLine *line = this->getTextLineInBuffer(cell.y());
+
+ int cell_begin = 0;
+ int cell_end = cell.x() + 1;
+
+ if (is_rect_sel) {
+ int minx = qMin(x1, x2);
+ int maxx = qMax(x1, x2);
+ cell_begin = line->getCellBegin(qMin(minx, (int)line->getWidth()));
+ cell_end = line->getCellEnd(qMin(maxx + 1, (int)line->getWidth()));
+ } else {
+ if (cell.y() == y1) {
+ cell_begin = line->getCellBegin(qMin(x1, (int)line->getWidth()));
+ }
+ if (cell.y() == y2) {
+ cell_end = line->getCellEnd(qMin(x2 + 1, (int)line->getWidth()));
+ }
+ }
+
+ return cell_begin <= cell.x() && cell.x() < cell_end;
+}
+
+static void removeTrailSpace(QString &line) {
+ for (int last_non_space = line.size() - 1;
+ last_non_space >= 0; --last_non_space) {
+ QChar a = line.at(last_non_space);
+ if (!a.isSpace()) {
+ line.resize(last_non_space + 1);
+ break;
+ }
+
+ if (last_non_space == 0) {
+ line.resize(0);
+ }
+ }
+}
+
+
+QString FQTermBuffer::getTextSelected(bool is_rect_sel, bool is_color_copy,
+ const QByteArray &escape) const {
+ QString cstrSelect;
+ QString strTemp;
+
+ if (selection_start_ == QPoint(-1, -1) && selection_end_ == QPoint(-1, -1)) {
+ return cstrSelect;
+ }
+
+ QRect rc;
+
+ for (int i = selection_start_.y(); i <= selection_end_.y(); i++) {
+ strTemp.clear();
+ rc = getSelectRect(i, is_rect_sel);
+
+ FQTermTextLine *line = text_lines_.at(i);
+ unsigned cell_begin = qMax(rc.left(), 0);
+ unsigned cell_end = qMin(rc.right() + 1, (int)line->getWidth());
+ FQ_ASSERT(rc.left() + rc.width() == rc.right() + 1);
+
+ if (cell_begin < cell_end) {
+ cell_begin = line->getCellBegin(cell_begin);
+ cell_end = line->getCellEnd(cell_end);
+
+ if (is_color_copy) {
+ line->getAnsiText(cell_begin, cell_end, strTemp, escape);
+ } else {
+ line->getPlainText(cell_begin, cell_end, strTemp);
+ }
+ }
+
+ removeTrailSpace(strTemp);
+
+ cstrSelect += strTemp;
+
+ // add newline except the last line
+ if (i != selection_end_.y()) {
+ cstrSelect += OS_NEW_LINE;
+ }
+ }
+
+ return cstrSelect;
+}
+
+QRect FQTermBuffer::getSelectRect(int line_index, bool is_rect_sel) const {
+ FQ_ASSERT(isSelected(line_index));
+
+ if (is_rect_sel) {
+ return QRect(qMin(selection_start_.x(), selection_end_.x()), line_index,
+ abs(selection_end_.x() - selection_start_.x()) + 1, 1);
+ } else if (selection_start_.y() == selection_end_.y()) {
+ return QRect(selection_start_.x(), line_index,
+ qMin(selection_end_.x(), num_columns_) - selection_start_.x() + 1, 1);
+ } else if (line_index == selection_start_.y()) {
+ return QRect(selection_start_.x(), line_index,
+ qMax(0, num_columns_ - selection_start_.x()), 1);
+ } else if (line_index == selection_end_.y()) {
+ return QRect(0, line_index, qMin(num_columns_, selection_end_.x() + 1), 1);
+ } else {
+ return QRect(0, line_index, num_columns_, 1);
+ }
+}
+
+void FQTermBuffer::scrollTerm(int numRows) {
+ scrollLinesInTerm(caret_.row_, numRows);
+ moveCaretOffset(0, numRows);
+}
+
+
+} // namespace FQTerm
+
+#include "fqterm_buffer.moc"
diff --git a/src/terminal/fqterm_buffer.h b/src/terminal/fqterm_buffer.h
new file mode 100644
index 0000000..3e0ef6a
--- /dev/null
+++ b/src/terminal/fqterm_buffer.h
@@ -0,0 +1,297 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_BUFFER_H
+#define FQTERM_BUFFER_H
+
+#include <QList>
+#include <QObject>
+#include <QPoint>
+
+#include "fqterm_text_line.h"
+class QString;
+class QByteArray;
+class QRect;
+
+namespace FQTerm {
+
+class FQTermTextLine;
+
+/* Text buffer consists of characters in a matrix of cells.
+ *
+ * Buffer
+ * +--------------------------------+
+ * ||----> |
+ * || x |
+ * || |
+ * |V Y |
+ * | |
+ * . .
+ * . .
+ * . histroical lines .
+ * . .
+ * . .
+ * | |
+ * | |
+ * | |
+ * | |
+ * |+------------------------------+|
+ * |||----> ||
+ * ||| x ||
+ * ||| terminal ||
+ * ||V Y ||
+ * || ||
+ * || ||
+ * || | (caret) ||
+ * || ||
+ * || ||
+ * |+------------------------------+|
+ * +--------------------------------+
+ *
+ * Text buffer, to manage lines of characters with colors and
+ * attributes, caret positions, terminal size/margins, selection
+ * region, historical text lines, buffer write mode (insert or
+ * replace), and etc.
+ *
+ * Note: There are two coordinates, relative to terminal or entire
+ * buffer. When we use (column, row) it indicates terminal coordinate,
+ * while when we use (column, line) it indicates buffer coordinate.
+ * This rule applies both in variable names and function names.
+ **/
+class FQTermBuffer: public QObject {
+ Q_OBJECT;
+ public:
+ enum TermMode {
+ INSERT_MODE, /* otherwise replace mode */
+ ANSI_MODE, /* otherwise VT52 mode */
+ SMOOTH_MODE, /* otherwse jump mode */
+ NEWLINE_MODE, /* otherwise line feed mode */
+ CURSOR_MODE, /* otherwise reset cursor mode */
+ NUMERIC_MODE, /* otherwise application mode */
+ ORIGIN_MODE, /* otherwise absolute mode */
+ AUTOWRAP_MODE, /* otherwise non-autowrap mode */
+ AUTOREPEAT_MODE, /* otherwise non-autorepeat mode */
+ LIGHTBG_MODE, /* otherwise dark background mode */
+ };
+
+ enum VtCharSet {
+ UNITED_KINGDOM_SET,
+ ASCII_SET,
+ SPECIAL_GRAPHICS,
+ ALTERNATE_CHARACTER_ROM_STANDARD_CHARACTER_SET,
+ ALTERNATE_CHARACTER_ROM_SPECIAL_GRAPHICS
+ };
+
+ FQTermBuffer(int column, int row, int max_hist_line, bool is_bbs);
+ ~FQTermBuffer();
+
+ // Get text lines.
+ // Return null if the line_index is out of bound, return NULL.
+ const FQTermTextLine *getTextLineInBuffer(int line_index) const;
+ const FQTermTextLine *getTextLineInTerm(int line_index) const;
+
+ // Get number of columns and rows of the term, or lines of the
+ // entire buffer.
+ int getNumColumns() const;
+ int getNumRows() const;
+ int getNumLines() const;
+
+ // Set the size of the screen.
+ void setTermSize(int col, int row);
+ // set margins in term. (Generally speaking, most operations are
+ // restrictied in [top_row_, bottom_row_] of terminal.)
+ void setMargins(int top_row, int bottom_row);
+
+ // the caret's coordinate in term or buffer.
+ int getCaretColumn() const;
+ int getCaretRow() const;
+ int getCaretLine() const;
+
+ // Set current attribute.
+ void setCurrentAttr(unsigned char color, unsigned char attr);
+
+ // Below are a series of functions to modify the content of buffer.
+ // These functions will work from the current caret position.
+ // All the behaviours of these functions may be influenced by the
+ // mode of this buffer (is_insert_mode_, is_newline_mode_, and
+ // etc.).
+
+ void writeText(const QString &cstr, int charstate = FQTermTextLine::NORMAL);
+
+ void fillScreenWith(char c);
+
+ void insertSpaces(int count);
+ void insertLines(int count);
+
+ void deleteText(int cell_count);
+ void deleteLines(int line_count);
+
+ void eraseText(int cell_count);
+
+ void eraseToLineBegin();
+ void eraseToLineEnd();
+ void eraseEntireLine();
+
+ void eraseToTermBegin();
+ void eraseToTermEnd();
+ void eraseEntireTerm();
+
+ // Set a line of buffer to have been changed from start to end.
+ void setLineChanged(int index, int cell_begin, int cell_end);
+ void clearLineChanged(int index);
+ void setLineAllChanged(int index);
+
+ // Functions about caret.
+ // If the caret is moved, the cells of the position of the last caret will
+ // be marked as changed.
+ void moveCaretOffset(int coloumn_offset, int row_offset,
+ bool scroll_if_necessary = false);
+ void moveCaretTo(int coloumn, int row, bool scroll_if_necessary = false);
+ void changeCaretPosition(int coloumn, int row);
+ void saveCaret();
+ void restoreCaret();
+
+ void SelectVtCharacterSet(VtCharSet charset, bool G0);
+ void invokeCharset(bool G0);
+
+ // non-printing characters
+ void tab();
+ void carriageReturn();
+ void lineFeed();
+
+ void addTabStop();
+ void clearTabStop(bool clear_all);
+
+ // Select Mode (SM) and Reset Mode (RM) functions.
+ // See ANSI X3.64 Mode-Changing Parameters.
+ void setMode(TermMode);
+ void resetMode(TermMode);
+
+ bool isCursorMode() const { return is_cursor_mode_; }
+ bool isAnsiMode() const { return is_ansi_mode_; }
+ bool isNumericMode() const { return is_numeric_mode_; }
+ bool isAutoRepeatMode() const { return is_autorepeat_mode_; }
+ bool isLightBackgroundMode() const { return is_lightbg_mode_; }
+ bool isNewLineMode() const {return is_newline_mode_;}
+
+ // for test
+ void startDecode();
+ void endDecode();
+
+ // Functions about selection in buffer.
+ void setSelect(const QPoint &start_point, const QPoint &end_point);
+ void clearSelect();
+ bool isSelected(const QPoint &cell, bool isRectSel) const;
+ bool isSelected(int line_index) const;
+
+ QString getTextSelected(bool is_rect_sel, bool is_color_copy,
+ const QByteArray &escape) const;
+
+ // Get the rectangle of selected text of a certain line in buffer.
+ // Note: please ensure there exits any cell of the line line_index
+ // is selected.
+ QRect getSelectRect(int line_index, bool is_rect_sel) const;
+
+ //Scroll line && adjust caret pos.
+ //Scroll must occur at the line where caret is
+ void scrollTerm(int numRows);
+
+ signals:
+ void bufferSizeChanged();
+ void termSizeChanged(int column, int row);
+ void onSetTermSize(int col, int row);
+ void caretChangeRow();
+ private:
+ // Scroll lines between startRow and bottom_row_ (see setMargin()).
+ // num > 0 scroll up.
+ // num < 0 scroll down.
+ void scrollLinesInTerm(int startRow, int numRows);
+
+ // Replace a area of cells with spaces.
+ void clearArea(int startColumn, int startRow,
+ int width, int height,
+ unsigned char color, unsigned char attr);
+
+ // Append n empty lines to the buffer and make the first n lines of
+ // term historical.
+ void addHistoryLine(int n);
+
+ int getTabStop(int column);
+
+ struct Caret {
+ int column_, row_;
+ int color_, attr_;
+ VtCharSet G0_, G1_;
+
+ Caret();
+ };
+
+ // terminal size.
+ int num_columns_, num_rows_;
+
+ // term margins. (Generally speaking, most operations are
+ // restrictied in [top_row_, bottom_row_] of terminal.)
+ int top_row_, bottom_row_;
+
+ // Historical data length and max length.
+ int num_hist_lines_, max_num_hist_lines_;
+
+ // All lines of text, including both historical lines and lines in
+ // current terminal.
+ //
+ // Note: the number of historical lines, num_hist_lines, may
+ // increase from 0 to max_num_hist_lines_.
+ QList<FQTermTextLine *> text_lines_;
+
+ void *tab_stops_;
+
+ // The caret in terminal
+ Caret caret_;
+ Caret last_saved_caret_;
+
+ bool is_g0_used_; // is G0 or G1 charset used;
+
+ bool is_insert_mode_; // Is insert or replace mode.
+ bool is_ansi_mode_; // Is ansi or vt52 mode.
+ bool is_smoothscroll_mode_; // Is smooth or jump scrolling mode.
+ bool is_newline_mode_; // Is newline or linefeed mode.
+ bool is_cursor_mode_; // Is cursor key mode.
+ bool is_numeric_mode_; // Is numeric or application mode.
+ bool is_origin_mode_; // Is origin or absolute mode.
+ bool is_autowrap_mode_; // Is auto-wrap mode enabled.
+ bool is_autorepeat_mode_; // Is auto-repeat mode enabled.
+ bool is_lightbg_mode_; // Is ligth background or dark backgrond mode.
+
+ // Selection in buffer. If section start and end are in the same
+ // line, start.x should be equal to or less than end.x. Otherwise
+ // start.y should be less than end.y.
+ //
+ // If selection_start_ = selection_start_ = (-1, -1), the selection
+ // is empty.
+ QPoint selection_start_;
+ QPoint selection_end_;
+
+ // whether this buffer is used for a bbs session.
+ bool is_bbs_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_BUFFER_H
diff --git a/src/terminal/fqterm_session.cpp b/src/terminal/fqterm_session.cpp
new file mode 100644
index 0000000..6c5b513
--- /dev/null
+++ b/src/terminal/fqterm_session.cpp
@@ -0,0 +1,1648 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm.h"
+#include "common.h"
+#include "fqterm_trace.h"
+#include "fqterm_session.h"
+#include "fqterm_buffer.h"
+#include "fqterm_text_line.h"
+#include "fqterm_telnet.h"
+#include "fqterm_decode.h"
+#include "fqterm_zmodem.h"
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <windows.h>
+#endif
+
+
+#include <QString>
+#include <QTimer>
+#include <QMutex>
+#include <QRegExp>
+#include <QtAlgorithms>
+#include <QChar>
+#include <QPair>
+#include <QReadLocker>
+#include <QWriteLocker>
+#include <QReadWriteLock>
+
+namespace FQTerm {
+
+const QString FQTermSession::endOfUrl[] = {
+ "ac","ad","ae","af","ag","ai","al","am","an","ao","aq","ar","as","at",
+ "au","aw","az","ba","bb","bd","be","bf","bg","bh","bi","bj","bm","bn","bo","br",
+ "bs","bt","bv","bw","by","bz","ca","cc","cd","cf","cg","ch","ci","ck","cl","cm",
+ "cn","co","uk","com","cr","cs","cu","cv","cx","cy","cz","de","dj","dk","dm",
+ "do","dz","ec","edu","ee","eg","eh","er","es","et","fi","fj","fk","fm","fo",
+ "fr","ga","gd","ge","gf","gg","gh","gi","gl","gm","gn","gov","gp","gq","aero",
+ "asia","biz","coop","eu","info","museum","name","pro","travel","gr","gs","gt",
+ "gu","gw","gy","hk","hm","hn","hr","ht","hu","id","ie","il","im","in","int",
+ "io","iq","ir","is","it","je","jm","jo","jp","ke","kg","kh","ki","km","kn","kp",
+ "kr","kw","ky","kz","la","lb","lc","li","lk","lr","ls","lt","lu","lv","ly","ma",
+ "mc","md","mg","mh","mil","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt",
+ "mu","mv","mw","mx","my","mz","na","nc","ne","net","nf","ng","ni","nl","no",
+ "np","nr","nt","nu","nz","om","org","pa","pe","pf","pg","ph","pk","pl","pm",
+ "pn","pr","ps","pt","pw","py","qa","re","ro","ru","rw","sa","sb","sc","sd","se",
+ "sg","sh","si","sj","sk","sl","sm","sn","so","sr","sv","st","sy","sz","tc","td",
+ "tf","tg","th","tj","tk","tm","tn","to","tp","tr","tt","tv","tw","tz","ua","ug",
+ "uk","um","us","uy","uz","va","vc","ve","vg","vi","vn","vu","wf","ws","ye","yt",
+ "yu","za","zm","zw"
+};
+
+FQTermSession::FQTermSession(FQTermConfig *config, FQTermParam param) {
+ reconnectRetry_ = 0;
+ scriptListener_ = NULL;
+ param_ = param;
+ termBuffer_ = new FQTermBuffer(param_.numColumns_,
+ param_.numRows_,
+ param_.numScrollLines_,
+ param_.hostType_ == 0);
+
+ if (param.protocolType_ == 0) {
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toLatin1(),
+ param_.numRows_, param_.numColumns_, param.protocolType_, param.hostType_ );
+ } else if (param.protocolType_ == 3) {
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toLatin1(),
+ param_.numRows_, param_.numColumns_, param.protocolType_, param.hostType_ );
+ } else {
+#if defined(_NO_SSH_COMPILED)
+ QMessageBox::warning(this, "sorry",
+ "SSH support is not compiled, "
+ "FQTerm can only use Telnet!");
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toUtf8(),
+ param_.numRows_, param_.numColumns_, param.protocolType_, param.hostType_ );
+#else
+ telnet_ = new FQTermTelnet(param_.virtualTermType_.toUtf8(),
+ param_.numRows_, param_.numColumns_, param.protocolType_ , param.hostType_ ,
+ param_.sshUserName_.toUtf8(),
+ param_.sshPassword_.toUtf8());
+#endif
+ }
+
+ zmodem_ = new FQTermZmodem(config, telnet_, param.protocolType_, param.serverEncodingID_);
+ decoder_ = new FQTermDecode(termBuffer_, param.serverEncodingID_);
+ FQ_VERIFY(connect(decoder_, SIGNAL(enqReceived()), this, SLOT(onEnqReceived())));
+ FQ_VERIFY(connect(decoder_, SIGNAL(onTitleSet(const QString&)), this, SIGNAL(onTitleSet(const QString&))));
+
+ isConnected_ = false;
+#ifndef _NO_SSH_COMPILED
+ if (param.protocolType_ != 0) {
+ isSSHLogining_ = true;
+ } else {
+ isSSHLogining_ = false;
+ }
+#else
+ isSSHLogining_ = false;
+#endif
+ isTelnetLogining_ = false;
+ isIdling_ = false;
+ isSendingMessage_ = false;
+ isMouseX11_ = false;
+
+ idleTimer_ = new QTimer;
+ autoReplyTimer_ = new QTimer;
+
+ acThread_ = new ArticleCopyThread(*this, waitCondition_, bufferWriteLock_);
+
+ FQ_VERIFY(connect(decoder_, SIGNAL(mouseMode(bool)),
+ this, SLOT(setMouseMode(bool))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(readyRead(int, int)),
+ this, SLOT(readReady(int, int))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(TelnetState(int)),
+ this, SLOT(changeTelnetState(int))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(errorMessage(QString)),
+ this, SIGNAL(errorMessage(QString))));
+ FQ_VERIFY(connect(telnet_, SIGNAL(requestUserPwd(QString*, QString*, bool*)),
+ this, SIGNAL(requestUserPwd(QString*, QString*, bool*))));
+
+ FQ_VERIFY(connect(telnet_, SIGNAL(onSSHAuthOK()),
+ this, SLOT(onSSHAuthOK())));
+
+
+
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(onSetTermSize(int, int)),
+ telnet_, SLOT(windowSizeChanged(int, int))));
+
+ FQ_VERIFY(connect(zmodem_, SIGNAL(ZmodemState(int, int, const char *)),
+ this, SIGNAL(zmodemStateChanged(int, int, const char *))));
+
+ FQ_VERIFY(connect(idleTimer_, SIGNAL(timeout()), this, SLOT(onIdle())));
+ FQ_VERIFY(connect(autoReplyTimer_, SIGNAL(timeout()),
+ this, SLOT(onAutoReply())));
+
+ FQ_VERIFY(connect(acThread_, SIGNAL(articleCopied(int, const QString)),
+ this, SIGNAL(articleCopied(int, const QString))));
+
+ setAntiIdle(param_.isAntiIdle_);
+}
+
+FQTermSession::~FQTermSession() {
+ delete idleTimer_;
+ delete autoReplyTimer_;
+ delete acThread_;
+ delete termBuffer_;
+ delete telnet_;
+ delete zmodem_;
+ delete decoder_;
+}
+
+const QString FQTermSession::protocolPrefix[] = {
+ "http://", "https://", "mms://", "rstp://", "ftp://", "mailto:", "telnet://"
+};
+
+void FQTermSession::setScreenStart(int nStart) {
+ screenStartLineNumber_ = nStart;
+}
+
+bool FQTermSession::setCursorPos(const QPoint &pt, QRect &rc) {
+ QRect rectOld = getMenuRect();
+
+ cursorPoint_ = pt;
+
+ detectMenuRect();
+ QRect rectNew = getMenuRect();
+
+ rc = rectOld | rectNew;
+
+ return rectOld != rectNew;
+}
+
+QString FQTermSession::getMessage() {
+ const FQTermTextLine *line;
+ LineColorInfo colorInfo;
+ QString message;
+
+ getLineColorInfo(termBuffer_->getTextLineInTerm(0), &colorInfo);
+ if (!colorInfo.uniBackgroundColor) {
+ return message;
+ }
+
+ int i = 1;
+ termBuffer_->getTextLineInTerm(0)->getAllPlainText(message);
+
+ line = termBuffer_->getTextLineInTerm(i);
+ getLineColorInfo(line, &colorInfo);
+ while (colorInfo.uniBackgroundColor && colorInfo.hasBackgroundColor) {
+ message += "\n";
+ line->getAllPlainText(message);
+ i++;
+ line = termBuffer_->getTextLineInTerm(i);
+ getLineColorInfo(line, &colorInfo);
+ }
+ return message;
+}
+
+
+void FQTermSession::detectPageState() {
+ //for smth type bbs.
+ pageState_ = Undefined;
+ if (param_.hostType_ != 0) {
+ return;
+ }
+
+ const FQTermTextLine *line[4];
+ LineColorInfo colorInfo[4];
+ int lineIndex[4] = {0, 1, 2};
+ lineIndex[3] = termBuffer_->getNumRows() - 1;
+ for (int i = 0; i < 4; ++i) {
+ line[i] = termBuffer_->getTextLineInTerm(lineIndex[i]);
+ getLineColorInfo(line[i], colorInfo + i);
+ }
+
+ //TODO: Detect PageState in a clearer way.
+ if (!colorInfo[0].hasBackgroundColor) {
+ if (colorInfo[3].foregroundColorIndex.count() != 0 &&
+ colorInfo[3].hasBackgroundColor){
+ if (colorInfo[3].uniBackgroundColor) {
+ QString text;
+ line[3]->getAllPlainText(text);
+ if (text[0] != L'\x3010') {
+ pageState_ = Read;
+ } else {
+ pageState_ = Edit;
+ }
+ } else if (colorInfo[3].backgroundColorIndex.count() == 2 &&
+ colorInfo[3].backgroundColorIndex.at(0) == 4 &&
+ colorInfo[3].backgroundColorIndex.at(1) == 0){
+ pageState_ = Read;
+ }
+ }
+ return;
+ }
+
+ if (colorInfo[0].backgroundColorIndex.at(0) != 4
+ || !(colorInfo[3].hasBackgroundColor && colorInfo[3].backgroundColorIndex.at(0) == 4)) {
+ if (!colorInfo[3].hasBackgroundColor &&
+ colorInfo[0].foregroundColorIndex.count() == 4 &&
+ colorInfo[0].foregroundColorIndex.at(1) == 4 &&
+ colorInfo[0].foregroundColorIndex.at(2) == 7 &&
+ colorInfo[0].foregroundColorIndex.at(3) == 4){
+ pageState_ = TOP10;
+ }
+ return;
+ }
+
+ if (colorInfo[1].hasBackgroundColor && colorInfo[1].uniBackgroundColor) {
+ pageState_ = Message;
+ return;
+ }
+
+ if (colorInfo[0].uniBackgroundColor) {
+ if (!colorInfo[2].hasBackgroundColor ||
+ colorInfo[2].backgroundColorIndex.at(0) != 4 ||
+ colorInfo[2].backgroundColorIndex.count() > 3) {
+ pageState_ = Menu;
+ return;
+ }
+ }
+
+ if (!colorInfo[0].uniBackgroundColor &&
+ colorInfo[0].backgroundColorIndex.at(0) == 4 &&
+ !colorInfo[3].uniBackgroundColor) {
+ //announce, elite root
+ pageState_ = EliteArticleList;
+ return;
+ }
+
+ if (colorInfo[2].hasBackgroundColor &&
+ !colorInfo[2].uniBackgroundColor &&
+ colorInfo[2].backgroundColorIndex.at(0) == 4 &&
+ !colorInfo[3].uniBackgroundColor) {
+ pageState_ = EliteArticleList;
+ return;
+ }
+
+ if (colorInfo[0].foregroundColorIndex.indexOf(14) != -1) {
+ pageState_ = ArticleList;
+ return;
+ }
+
+ if (colorInfo[2].foregroundColorIndex.indexOf(7) != -1) {
+ QString text;
+ line[2]->getAllPlainText(text);
+ if (text[0] == ' ') {
+ pageState_ = BoardList;
+ } else {
+ pageState_ = MailMenu;
+ }
+ }
+
+}
+
+FQTermSession::CursorType FQTermSession::getCursorType(const QPoint &pt) {
+ if (screenStartLineNumber_ !=
+ (termBuffer_->getNumLines() - termBuffer_->getNumRows())) {
+ return kNormal;
+ }
+
+ QRect rc = getMenuRect();
+ CursorType nCursorType = kNormal;
+ switch (pageState_) {
+ case Undefined: // not recognized
+ if (rc.contains(pt)) {
+ //HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case Menu:
+ case MailMenu:
+ // menu
+ if (pt.x() < 5) {
+ // LEFT
+ nCursorType = kLeft;
+ } else if (rc.contains(pt)) {
+ // HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case ArticleList:
+ case BoardList:
+ case EliteArticleList:
+ case FriendMailList:
+ // list
+ if (pt.x() < 12) {
+ // LEFT
+ nCursorType = kLeft;
+ } else if (pt.y() - screenStartLineNumber_ < 3) {
+ // HOME
+ nCursorType = kHome;
+ } else if (pt.y() == termBuffer_->getNumLines() - 1) {
+ // END
+ nCursorType = kEnd;
+ } else if (pt.x() > termBuffer_->getNumColumns() - 16 &&
+ pt.y() - screenStartLineNumber_ <= termBuffer_->getNumRows() / 2) {
+ //PAGEUP
+ nCursorType = kPageUp;
+ } else if (pt.x() > termBuffer_->getNumColumns() - 16
+ && pt.y() - screenStartLineNumber_ >
+ termBuffer_->getNumRows() / 2) {
+ // PAGEDOWN
+ nCursorType = kPageDown;
+ } else if (rc.contains(pt)) {
+ // HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case Read:
+ // read
+ if (pt.x() < 12) {
+ // LEFT
+ nCursorType = kLeft;
+ } else if (pt.x() > (termBuffer_->getNumColumns() - 16) &&
+ (pt.y() - screenStartLineNumber_)
+ <= termBuffer_->getNumRows() / 2) {
+ // PAGEUP
+ nCursorType = kPageUp;
+ } else if (pt.x() > (termBuffer_->getNumColumns() - 16) &&
+ (pt.y() - screenStartLineNumber_)
+ > termBuffer_->getNumRows() / 2) {
+ // PAGEDOWN
+ nCursorType = kPageDown;
+ } else if (rc.contains(pt)) {
+ //HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case Edit:
+ // TODO: add action for kEdit state.
+ if (rc.contains(pt)) {
+ //HAND
+ nCursorType = kRight;
+ } else {
+ nCursorType = kNormal;
+ }
+ break;
+ case TOP10:
+ if (pt.x() < 12) {
+ nCursorType = kLeft;
+ } else if (rc.contains(pt)){
+ nCursorType = kRight;
+ }
+ break;
+ default:
+ FQ_TRACE("error", 2) << "Error, wrong PageState.";
+ break;
+ }
+
+ return nCursorType;
+}
+
+bool FQTermSession::isSelectedMenu(int line) {
+ // TODO: possible performance issue
+ QRect rect = getMenuRect();
+
+ // nothing selected
+ if (rect.isNull()) {
+ return false;
+ }
+
+ return line >= rect.bottom() && line <= rect.top();
+}
+
+bool FQTermSession::isSelectedMenu(const QPoint &pt) {
+ // TODO: possible performance issue
+ QRect rect = getMenuRect();
+
+ // nothing selected
+ if (rect.isNull()) {
+ return false;
+ }
+
+ return rect.contains(pt);
+}
+
+FQTermSession::PageState FQTermSession::getPageState() {
+ return pageState_;
+}
+
+char FQTermSession::getMenuChar() {
+ return menuChar_;
+}
+
+void FQTermSession::setMenuRect(int row, int col, int len) {
+ menuRect_ = QRect(col, row, len, 1);
+}
+
+QRect FQTermSession::detectMenuRect() {
+ QRect rect(0, 0, 0, 0);
+ menuRect_ = rect;
+ if (scriptListener_)
+ {
+ bool res = scriptListener_->postScriptCallback(SFN_DETECT_MENU
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ if (res) return menuRect_;
+ }
+ // current screen scrolled
+ if (screenStartLineNumber_ !=
+ (termBuffer_->getNumLines() - termBuffer_->getNumRows())) {
+ return rect;
+ }
+
+ const FQTermTextLine *line;
+ int menuStartLine = 8;
+ switch (pageState_) {
+ case Undefined: break;
+ case MailMenu:
+ menuStartLine = 7;
+ case Menu:
+ if (cursorPoint_.y() - screenStartLineNumber_ >= menuStartLine &&
+ cursorPoint_.x() > 5) {
+ line = termBuffer_->getTextLineInBuffer(cursorPoint_.y());
+ QString cstr;
+ int cell_end = line->getCellEnd(qMin(cursorPoint_.x(),
+ (int)line->getWidth()));
+ line->getPlainText(0, cell_end, cstr);
+
+ int base = cstr.lastIndexOf(" ");
+ if (base == -1) {
+ base = 0;
+ }
+
+ QRegExp reg("[a-zA-Z0-9][).\\]]");
+ char indexChar = cstr.indexOf(reg, base);
+ if (indexChar != -1) {
+ menuChar_ = cstr.at(indexChar).toLatin1();
+
+ QString strTmp = cstr.left(cstr.indexOf(reg, base));
+ int nMenuStart = get_str_width((const UTF16 *)strTmp.data(),
+ strTmp.size());
+ if (cstr[indexChar - 1] == '(' || cstr[indexChar - 1] == '[') {
+ nMenuStart--;
+ }
+
+ cstr.clear();
+ line->getAllPlainText(cstr);
+
+
+ reg = QRegExp("[^ ]");
+
+ int nMenuBaseLength = 20;
+ int cell_begin =
+ line->getCellBegin(
+ qMin(nMenuStart + nMenuBaseLength, (int)line->getWidth() - 1));
+ int char_begin = line->getCharBegin(cell_begin);
+ //last [^ ] until char_begin
+ strTmp = cstr.left(cstr.lastIndexOf(reg, char_begin) + 1);
+
+ int nMenuLength =
+ get_str_width((const UTF16 *)strTmp.data(), strTmp.size())
+ - nMenuStart;
+ if (nMenuLength == nMenuBaseLength + 1) {
+ strTmp = cstr.left(cstr.indexOf(" ", char_begin) + 1);
+ nMenuLength =
+ get_str_width((const UTF16 *)strTmp.data(), strTmp.size())
+ - nMenuStart; //base length is not enough
+ }
+
+ if (cursorPoint_.x() >= nMenuStart && cursorPoint_.x() <=
+ nMenuStart + nMenuLength) {
+ rect.setX(nMenuStart);
+ rect.setY(cursorPoint_.y());
+ rect.setWidth(nMenuLength);
+ rect.setHeight(1);
+ }
+ }
+ }
+ break;
+ case ArticleList:
+ case BoardList:
+ case FriendMailList:
+ case EliteArticleList:
+ if ((cursorPoint_.y() - screenStartLineNumber_) >= 3
+ && (cursorPoint_.y() - screenStartLineNumber_)
+ < termBuffer_->getNumRows() -1
+ && cursorPoint_.x() >= 12
+ && cursorPoint_.x() <= termBuffer_->getNumColumns() - 16) {
+ line = termBuffer_->getTextLineInBuffer(cursorPoint_.y());
+ //QString str = line->getText();
+ QString str;
+ line->getAllPlainText(str);
+
+ if (str.count(" ") != (int)str.length()) {
+ rect.setX(0);
+ rect.setY(cursorPoint_.y());
+ rect.setWidth(line->getWidth());
+ rect.setHeight(1);
+ }
+ }
+ break;
+ case Read:
+
+ break;
+ case Edit:
+ break;
+ case TOP10:
+ {
+ int ln = cursorPoint_.y() - screenStartLineNumber_;
+ if (ln >= 3 && (ln & 1) && ln <= 21 &&
+ cursorPoint_.x() >= 12 &&
+ cursorPoint_.x() <= termBuffer_->getNumColumns() - 8){
+ line = termBuffer_->getTextLineInBuffer(cursorPoint_.y());
+
+ QString str;
+ line->getAllPlainText(str);
+
+ if (str.count(" ") != (int)str.length()) {
+ if (ln == 21){
+ menuChar_ = '0';
+ } else {
+ menuChar_ = ((ln - 1) >> 1) + '0';
+ }
+
+ rect.setX(12);
+ rect.setY(cursorPoint_.y());
+ rect.setWidth(line->getWidth() - 20);
+ rect.setHeight(1);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ menuRect_ = rect;
+ return rect;
+}
+
+bool FQTermSession::isIllChar(char ch) {
+ static char illChars[] = ";'\"[]<>^";
+ return ch > '~' || ch < '!' || strchr(illChars, ch) != NULL;
+}
+
+bool FQTermSession::isUrl(QRect &rcUrl, QRect &rcOld) {
+ return checkUrl(rcUrl, rcOld, false);
+}
+
+bool FQTermSession::isIP(QRect &rcUrl, QRect &rcOld) {
+ return checkUrl(rcUrl, rcOld, true);
+}
+
+QString FQTermSession::expandUrl(const QPoint& pt, QPair<int, int>& range)
+{
+ // int at = pt.x();
+ range.first = -1;
+ range.second = -2;
+ const FQTermTextLine *textLine = termBuffer_->getTextLineInBuffer(pt.y());
+ if (textLine == NULL || pt.x() > (int)textLine->getWidth()) {
+ return "";
+ }
+
+ QString text;
+ textLine->getAllPlainText(text);
+
+ int cell_begin = textLine->getCellBegin(pt.x());
+ int at = textLine->getCharBegin(cell_begin);
+ if (at >= text.length()) {
+ return "";
+ }
+
+ int start;
+ int end;
+ for (start = at; start >= 0 && !isIllChar(text.at(start).toLatin1());
+ start--) {
+ }
+ start++;
+ for (end = at; end < text.length() && !isIllChar(text.at(end).toLatin1());
+ end++) {
+ }
+ range.first = get_str_width((const UTF16 *)text.data(), start);
+ range.second = get_str_width((const UTF16 *)text.data(), end);
+ return text.mid(start, end - start);
+}
+
+
+bool FQTermSession::checkUrl(QRect &rcUrl, QRect &rcOld, bool checkIP) {
+
+
+
+ QPoint pt = cursorPoint_;
+ int at = pt.x();
+ rcOld = urlRect_;
+
+ if (at > urlRect_.left() && at < urlRect_.right() && urlRect_.y() == pt.y()) {
+ if ( (checkIP && !ip_.isEmpty()) ||
+ (!checkIP && !url_.isEmpty()) ) {
+ rcUrl = urlRect_;
+ return true;
+ }
+
+ }
+
+ QPoint urlStartPoint;
+ QPoint urlEndPoint;
+ urlStartPoint_ = QPoint();
+ urlEndPoint_ = QPoint();
+ urlRect_ = QRect(0, 0, -1, -1);
+ if (!checkIP) {
+ url_.clear();
+ } else {
+ ip_.clear();
+ }
+
+ QString urlText;
+ //phase 1: find all consecutive legal chars
+ QPair<int, int> range;
+ urlText = expandUrl(pt, range);
+ if (range.first < 0 || range.first >= range.second) {
+ return false;
+ }
+
+
+ QRect urlRect = QRect(range.first, pt.y(), range.second - range.first, 1);
+ urlStartPoint = QPoint(range.first, pt.y());
+ urlEndPoint = QPoint(range.second, pt.y());
+
+ if (range.second == termBuffer_->getNumColumns()) {
+ for (int i = pt.y() + 1; i < termBuffer_->getNumLines(); ++i) {
+ QString lineText = expandUrl(QPoint(0, i), range);
+ if (range.first == 0) {
+ urlText += lineText;
+ urlEndPoint.setY(urlEndPoint.y() + 1);
+ urlEndPoint.setX(range.second);
+ if (range.second == termBuffer_->getNumColumns()) {
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
+ //phase 2: find protocol prefix for url
+ //if none, prefix to add is set to "mailto:" if '@' is found
+ //otherwise, the prefix is "http://" by default.
+ QString prefixToAdd;
+ int protocolIndex;
+ for (protocolIndex = 0; protocolIndex < ProtocolSupported; ++protocolIndex) {
+ int begin = urlText.indexOf(protocolPrefix[protocolIndex],
+ Qt::CaseInsensitive);
+ if (begin != -1 && begin <= at) {
+ prefixToAdd = protocolPrefix[protocolIndex];
+ urlText = urlText.mid(begin + protocolPrefix[protocolIndex].length());
+ urlStartPoint.setX(urlStartPoint.x() + begin);
+ break;
+ }
+ }
+ if (protocolIndex == ProtocolSupported) {
+ int begin = urlText.indexOf("://");
+ if (begin != -1) {
+ return false;
+ }
+ if (urlText.indexOf('@') != -1) {
+ prefixToAdd = protocolPrefix[Mailto];
+ } else {
+ prefixToAdd = protocolPrefix[Http];
+ }
+ }
+
+ //no point or duplicated points
+ if (urlText.indexOf("..") != -1 || urlText.indexOf('.') == -1) {
+ return false;
+ }
+
+ //phase 3: (for check ip) if there is a ':' before ip, there must be a '@'
+ int host_begin = qMax(urlText.lastIndexOf('@') + 1, 0);
+ int host_end = urlText.indexOf(':', host_begin);
+ if (host_end == -1) {
+ host_end = urlText.indexOf('/', host_begin);
+ }
+ if (host_end == -1) {
+ host_end = urlText.length();
+ }
+ if (host_begin >= host_end) {
+ return false;
+ }
+ if (checkIP && urlText[host_end - 1] == '*') {
+ urlText[host_end - 1] = '1';
+ }
+
+ for (int index = 0; index < urlText.length() && urlText.at(index) != '/';
+ index++) {
+ QChar cur(urlText.at(index));
+ if (!cur.isLetterOrNumber() && !QString("-_~:@.").contains(cur)) {
+ return false;
+ }
+ }
+
+ QString newIP;
+ newIP = urlText.mid(host_begin, host_end - host_begin);
+ QStringList ipv4 = newIP.split(QLatin1String("."));
+ bool isIPv4 = true;
+ if (ipv4.count() != 4){
+ isIPv4 = false;
+ }
+ foreach(QString domain, ipv4) {
+ bool ok;
+ int num = domain.toInt(&ok);
+ //won't tolerant spaces.
+ if (!ok || num < 0 || num > 255 || domain.length() > 3) {
+ isIPv4 = false;
+ break;
+ }
+ }
+
+ if (!checkIP){
+ QString lastName = ipv4.back();
+
+ int lastCharIndex = lastName.lastIndexOf(QRegExp("[a-zA-Z]"));
+ if (lastCharIndex == -1) {
+ if (!isIPv4) {
+ return false;
+ } else if (urlText == newIP) {
+ return false;
+ }
+ } else {
+ const QString *begin = endOfUrl;
+ const QString *end = endOfUrl + sizeof(endOfUrl) / sizeof(QString *);
+ if (qFind(begin, end, lastName) == end) {
+ return false;
+ }
+ }
+ url_ = prefixToAdd + urlText;
+ } else {
+ if (!isIPv4) {
+ return false;
+ }
+ ip_ = newIP;
+ }
+
+ urlRect_ = urlRect;
+ rcUrl = urlRect;
+ urlStartPoint_ = urlStartPoint;
+ urlEndPoint_ = urlEndPoint;
+ return true;
+}
+
+QString FQTermSession::getUrl() {
+ return url_;
+}
+
+QString FQTermSession::getIP() {
+ return ip_;
+}
+
+bool FQTermSession::isPageComplete() {
+ return termBuffer_->getCaretRow() == (termBuffer_->getNumRows() - 1)
+ && termBuffer_->getCaretColumn() == (termBuffer_->getNumColumns() - 1);
+}
+
+bool FQTermSession::isAntiIdle() {
+ return param_.isAntiIdle_;
+}
+
+void FQTermSession::setAntiIdle(bool antiIdle) {
+ param_.isAntiIdle_ = antiIdle;
+
+ // disabled
+ if (!param_.isAntiIdle_ && idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+
+ // enabled
+ if (param_.isAntiIdle_) {
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+ idleTimer_->start(param_.maxIdleSeconds_ *1000);
+ }
+}
+
+void FQTermSession::setAutoReconnect(bool autoReconnect) {
+ param_.isAutoReconnect_ = autoReconnect;
+ reconnectRetry_ = 0;
+ if (autoReconnect && !isConnected_) {
+ reconnectProcess();
+ }
+}
+
+
+void FQTermSession::autoReplyMessage() {
+ if (autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+ if (pageState_ != Message) {
+ return;
+ }
+ if (scriptListener_)
+ {
+ bool res = scriptListener_->postScriptCallback(SFN_AUTO_REPLY
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ if (res) return;
+ }
+ QByteArray cstrTmp = param_.replyKeyCombination_.toLocal8Bit();
+ QByteArray cstr = parseString(cstrTmp.isEmpty() ? QByteArray("^Z"): cstrTmp);
+ //cstr += m_param.m_strAutoReply.toLocal8Bit();
+ cstr += unicode2bbs(param_.autoReplyMessage_);
+ cstr += '\n';
+ telnet_->write(cstr, cstr.length());
+
+ emit messageAutoReplied();
+}
+
+QByteArray FQTermSession::parseString(const QByteArray &cstr, int *len) {
+ QByteArray parsed = "";
+
+ if (len != 0) {
+ *len = 0;
+ }
+
+ for (uint i = 0; (long)i < cstr.length(); i++) {
+ if (cstr.at(i) == '^') {
+ i++;
+ if ((long)i < cstr.length()) {
+ parsed += FQTERM_CTRL(cstr.at(i));
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else if (cstr.at(i) == '\\') {
+ i++;
+ if ((long)i < cstr.length()) {
+ if (cstr.at(i) == 'n') {
+ parsed += CHAR_CR;
+ } else if (cstr.at(i) == 'r') {
+ parsed += CHAR_LF;
+ } else if (cstr.at(i) == 't') {
+ parsed += CHAR_TAB;
+ }
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ } else {
+ parsed += cstr.at(i);
+ if (len != 0) {
+ *len = *len + 1;
+ }
+ }
+ }
+
+ return parsed;
+}
+
+void FQTermSession::reconnect() {
+ if (!isConnected_) {
+ telnet_->connectHost(param_.hostAddress_, param_.port_);
+ reconnectRetry_++;
+ }
+}
+
+void FQTermSession::reconnectProcess() {
+ if (!isConnected_ && param_.isAutoReconnect_ && (reconnectRetry_ < param_.retryTimes_ || param_.retryTimes_ == -1)) {
+ int interval = param_.reconnectInterval_ <= 0 ? 0 : param_.reconnectInterval_ * 1000;
+ QTimer::singleShot(interval, this, SLOT(reconnect()));
+ }
+}
+
+void FQTermSession::setMouseMode(bool on) {
+ isMouseX11_ = on;
+}
+
+void FQTermSession::doAutoLogin() {
+ if (!param_.preLoginCommand_.isEmpty()) {
+ QByteArray temp = parseString(param_.preLoginCommand_.toLatin1());
+ telnet_->write((const char*)(temp), temp.length());
+ }
+ if (!param_.userName_.isEmpty()) {
+ QByteArray temp = param_.userName_.toLocal8Bit();
+ telnet_->write((const char*)(temp), temp.length());
+ char ch = CHAR_CR;
+ telnet_->write(&ch, 1);
+ }
+ if (!param_.password_.isEmpty()) {
+ QByteArray temp = param_.password_.toLocal8Bit();
+ telnet_->write((const char*)(temp), temp.length());
+ char ch = CHAR_CR;
+ telnet_->write(&ch, 1);
+ }
+
+ // smth ignore continous input, so sleep 1 sec :)
+#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+
+ if (!param_.postLoginCommand_.isEmpty()) {
+ QByteArray temp = parseString(param_.postLoginCommand_.toLatin1());
+ telnet_->write((const char*)(temp), temp.length());
+ }
+ isTelnetLogining_ = false;
+}
+
+//read slot
+void FQTermSession::readReady(int size, int raw_size) {
+ FQ_ASSERT(size > 0 || raw_size > 0); // maybe raw_size is greater than 0.
+
+ raw_data_.resize(raw_size);
+ telnet_->read_raw(&raw_data_[0], raw_size);
+
+ // read raw buffer
+ int zmodem_consumed;
+ if (param_.enableZmodem_)
+ zmodem_->ZmodemRcv((uchar*)&raw_data_[0], raw_data_.size(), &(zmodem_->info),
+ zmodem_consumed);
+
+ if (zmodem_->transferstate == notransfer) {
+ //decode
+ if (size > 0) {
+ int last_size = telnet_data_.size();
+ telnet_data_.resize(last_size + size);
+ telnet_->read(&telnet_data_[0] + last_size, size);
+ int processed = 0;
+ {
+ while (!bufferWriteLock_.tryLockForWrite()) {}
+ //QWriteLocker locker(&bufferWriteLock_);
+ processed = decoder_->decode(&telnet_data_[0], telnet_data_.size());
+ bufferWriteLock_.unlock();
+ }
+ telnet_data_.erase(telnet_data_.begin(), telnet_data_.begin() + processed);
+ }
+
+ if (isTelnetLogining_) {
+ int n = termBuffer_->getCaretRow();
+ for (int y = n - 5; y < n + 5; y++) {
+ y = qMax(0, y);
+ const FQTermTextLine *pTextLine = termBuffer_->getTextLineInTerm(y);
+ if (pTextLine == NULL) {
+ continue;
+ }
+
+ // QString str = pTextLine->getText();
+ QString str;
+ pTextLine->getAllPlainText(str);
+
+ if (str.indexOf("guest") != -1 /*&& str.indexOf("new") != -1*/) {
+ doAutoLogin();
+ break;
+ }
+ }
+ }
+ // page complete when caret at the right corner
+ // this works for most but not for all
+ const FQTermTextLine *pTextLine =
+ termBuffer_->getTextLineInTerm(termBuffer_->getNumRows() - 1);
+
+ //QString strText = stripWhitespace(pTextLine->getText());
+ // TODO_UTF16: fixme! performance issue!
+ QString strText;
+ pTextLine->getAllPlainText(strText);
+
+ // TODO_UTF16: shall we disable trim?
+ strText = strText.trimmed();
+
+ if (termBuffer_->getCaretRow() == termBuffer_->getNumRows() - 1
+ && termBuffer_->getCaretColumn() >= (strText.length() - 1) / 2) {
+ waitCondition_.wakeAll();
+ }
+
+ //QToolTip::remove(this, screen_->mapToRect(m_rcUrl));
+
+ // message received
+ // 03/19/2003. the caret posion removed as a message judgement
+ // because smth.org changed
+ if (decoder_->bellReceive()) {
+ emit startAlert();
+ emit bellReceived();
+
+ bool bellConsumed = false;
+ if (scriptListener_) {
+ bellConsumed = scriptListener_->postScriptCallback(SFN_ON_BELL
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ }
+
+ if (isAutoReply() && !bellConsumed) {
+ // TODO: save messages
+ if (isIdling_) {
+ autoReplyMessage();
+ } else {
+ autoReplyTimer_->start(param_.maxIdleSeconds_ *1000 / 2);
+ }
+ }
+ }
+
+ // set page state
+ detectPageState();
+ if (scriptListener_) {
+ scriptListener_->postScriptCallback(SFN_DATA_EVENT
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ }
+ emit sessionUpdated();
+ }
+
+ if (zmodem_->transferstate == transferstop) {
+ zmodem_->transferstate = notransfer;
+ }
+}
+
+/* 0-left 1-middle 2-right 3-relsase 4/5-wheel
+ *
+ */
+//void FQTermWindow::sendMouseState( int num,
+// Qt::ButtonState btnstate, Qt::ButtonState keystate, const QPoint& pt )
+void FQTermSession::sendMouseState(int num, Qt::KeyboardModifier btnstate,
+ Qt::KeyboardModifier keystate, const QPoint &pt) {
+ /*
+ if(!m_bMouseX11)
+ return;
+
+ QPoint ptc = screen_->mapToChar(pt);
+
+ if(btnstate&Qt::LeftButton)
+ num = num==0?0:num;
+ else if(btnstate&Qt::MidButton)
+ num = num==0?1:num;
+ else if(btnstate&Qt::RightButton)
+ num = num==0?2:num;
+
+ int state = 0;
+ if(keystate&Qt::ShiftModifier)
+ state |= 0x04;
+ if(keystate&Qt::MetaModifier)
+ state |= 0x08;
+ if(keystate&Qt::ControlModifier)
+ state |= 0x10;
+
+ // normal buttons are passed as 0x20 + button,
+ // mouse wheel (buttons 4,5) as 0x5c + button
+ if(num>3) num += 0x3c;
+
+ char mouse[10];
+ sprintf(mouse, "\033[M%c%c%c",
+ num+state+0x20,
+ ptc.x()+1+0x20,
+ ptc.y()+1+0x20);
+ telnet_->write( mouse, strlen(mouse) );
+ */
+}
+
+void FQTermSession::cancelZmodem() {
+ zmodem_->zmodemCancel();
+}
+
+void FQTermSession::disconnect() {
+ telnet_->close();
+ finalizeConnection();
+}
+
+void FQTermSession::finalizeConnection() {
+ if (isConnected_) {
+ QString strMsg = "";
+ strMsg += "\n\n\n\r\n\r";
+ strMsg += "\x1b[17C\x1b[0m===========================================\n\r";
+ strMsg +=
+ "\x1b[17C Connection Closed, Press \x1b[1m\x1b[31;40mEnter\x1b[m\x1b[0m To Connect\n\r";
+ strMsg += "\x1b[17C===========================================\n";
+ decoder_->decode(strMsg.toLatin1(), strMsg.length());
+ }
+ isConnected_ = false;
+
+ if (autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+
+ emit connectionClosed();
+}
+
+// telnet state slot
+void FQTermSession::changeTelnetState(int state) {
+ switch (state) {
+ case TSRESOLVING:
+ break;
+ case TSHOSTFOUND:
+ break;
+ case TSHOSTNOTFOUND:
+ finalizeConnection();
+ break;
+ case TSCONNECTING:
+ break;
+ case TSHOSTCONNECTED:
+ isConnected_ = true;
+ reconnectRetry_ = 0;
+ if (param_.isAutoLogin_ && param_.protocolType_==0) {
+ isTelnetLogining_ = true;
+ }
+
+ break;
+ case TSPROXYCONNECTED:
+ break;
+ case TSPROXYAUTH:
+ break;
+ case TSPROXYFAIL:
+ disconnect();
+ break;
+ case TSREFUSED:
+ finalizeConnection();
+ break;
+ case TSREADERROR:
+ disconnect();
+ break;
+ case TSCLOSED:
+ finalizeConnection();
+ if (param_.isAutoReconnect_) {
+ reconnectProcess();
+ }
+ break;
+ case TSCLOSEFINISH:
+ finalizeConnection();
+ break;
+ case TSCONNECTVIAPROXY:
+ break;
+ case TSEGETHOSTBYNAME:
+ finalizeConnection();
+ break;
+ case TSEINIWINSOCK:
+ finalizeConnection();
+ break;
+ case TSERROR:
+ disconnect();
+ break;
+ case TSPROXYERROR:
+ disconnect();
+ break;
+ case TSWRITED:
+ // restart the idle timer
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+ if (param_.isAntiIdle_) {
+ idleTimer_->start(param_.maxIdleSeconds_ *1000);
+ }
+ isIdling_ = false;
+ break;
+ default:
+ break;
+ }
+
+ emit telnetStateChanged(state);
+}
+
+void FQTermSession::handleInput(const QString &text) {
+ if (text.length() > 0) {
+ QByteArray cstrTmp = unicode2bbs_smart(text);
+ telnet_->write(cstrTmp, cstrTmp.length());
+ }
+}
+
+QString FQTermSession::bbs2unicode(const QByteArray &text)
+{
+ return encoding2unicode(text, param_.serverEncodingID_);
+}
+
+QByteArray FQTermSession::unicode2bbs(const QString &text) {
+ return unicode2encoding(text, param_.serverEncodingID_);
+}
+
+
+QByteArray FQTermSession::unicode2bbs_smart(const QString &text) {
+ QByteArray strTmp;
+
+ switch(param_.serverEncodingID_)
+ {
+ case FQTERM_ENCODING_GBK:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_BIG5)
+ {
+ strTmp = U2B(text);
+ char* tmp = encodingConverter_.B2G(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2G(text);
+ }
+ break;
+ case FQTERM_ENCODING_BIG5:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_GBK)
+ {
+ strTmp = U2G(text);
+ char* tmp = encodingConverter_.G2B(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2B(text);
+ }
+ break;
+ case FQTERM_ENCODING_HKSCS:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_GBK)
+ {
+ strTmp = U2G(text);
+ char* tmp = encodingConverter_.G2B(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2H(text);
+ }
+ break;
+ case FQTERM_ENCODING_UTF8:
+ strTmp = U2U8(text);
+ break;
+ case FQTERM_ENCODING_UAO:
+ if (FQTermPref::getInstance()->imeEncodingID_ == FQTERM_ENCODING_GBK)
+ {
+ strTmp = U2G(text);
+ char* tmp = encodingConverter_.G2B(strTmp, strTmp.length());
+ strTmp = tmp;
+ delete []tmp;
+ }
+ else
+ {
+ strTmp = U2A(text);
+ }
+ break;
+ }
+
+ return strTmp;
+}
+
+
+void FQTermSession::onIdle() {
+ // do as autoreply when it is enabled
+ if (autoReplyTimer_->isActive() && param_.isAutoReply_) {
+ autoReplyMessage();
+ stopAlert();
+ return ;
+ }
+
+ isIdling_ = true;
+ // system script can handle that
+ if (scriptListener_) {
+ bool res = scriptListener_->postScriptCallback(SFN_ANTI_IDLE
+#ifdef HAVE_PYTHON
+ ,Py_BuildValue("l", scriptListener_->windowID())
+#endif //HAVE_PYTHON
+ );
+ if (res)
+ return;
+ }
+ // the default function
+ int length;
+ QByteArray cstr = parseString(param_.antiIdleMessage_.toLocal8Bit(), &length);
+ telnet_->write(cstr, length);
+}
+
+void FQTermSession::onAutoReply() {
+ // if AutoReply still enabled, then autoreply
+ if (param_.isAutoReply_) {
+ autoReplyMessage();
+ } else {
+ // else just stop the timer
+ autoReplyTimer_->stop();
+ }
+
+ stopAlert();
+}
+bool FQTermSession::isAutoReply() {
+ return param_.isAutoReply_;
+}
+
+void FQTermSession::setAutoReply(bool on) {
+ param_.isAutoReply_ = on;
+ if (!param_.isAutoReply_ && autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+}
+
+int FQTermSession::write(const char *data, int len) {
+ return telnet_->write(data, len);
+}
+
+int FQTermSession::writeStr(const char *str) {
+ return write(str, strlen(str));
+}
+
+void FQTermSession::setProxy(int type, bool needAuth,
+ const QString &hostName, quint16 portNumber,
+ const QString &userName, const QString &password) {
+ telnet_->setProxy(type, needAuth, hostName, portNumber, userName, password);
+}
+
+void FQTermSession::connectHost(const QString &hostName, quint16 portNumber) {
+ telnet_->connectHost(hostName, portNumber);
+}
+
+void FQTermSession::close() {
+ telnet_->close();
+ finalizeConnection();
+}
+
+void FQTermSession::clearLineChanged(int index) {
+ termBuffer_->clearLineChanged(index);
+}
+
+void FQTermSession::setLineAllChanged(int index) {
+ termBuffer_->setLineAllChanged(index);
+}
+
+void FQTermSession::setTermSize(int col, int row) {
+ termBuffer_->setTermSize(col, row);
+ param_.numColumns_ = col;
+ param_.numRows_ = row;
+}
+
+FQTermBuffer *FQTermSession::getBuffer() const {
+ return termBuffer_;
+}
+
+void FQTermSession::setSelect(const QPoint &pt1, const QPoint &pt2) {
+ termBuffer_->setSelect(pt1, pt2);
+}
+
+void FQTermSession::clearSelect() {
+ termBuffer_->clearSelect();
+}
+
+void FQTermSession::leaveIdle() {
+ if (autoReplyTimer_->isActive()) {
+ autoReplyTimer_->stop();
+ }
+
+ if (idleTimer_->isActive()) {
+ idleTimer_->stop();
+ }
+
+ if (param_.isAntiIdle_) {
+ idleTimer_->start(param_.maxIdleSeconds_ * 1000);
+ }
+}
+
+void FQTermSession::copyArticle() {
+ if (!acThread_->isRunning()) {
+ acThread_->start();
+ }
+}
+
+void FQTermSession::getLineColorInfo(const FQTermTextLine * line,
+ LineColorInfo * colorInfo)
+{
+ colorInfo->backgroundColorIndex.clear();
+ colorInfo->foregroundColorIndex.clear();
+ colorInfo->hasBackgroundColor = false;
+ colorInfo->uniBackgroundColor = true;
+ colorInfo->uniForegroundColor = true;
+ colorInfo->hasForegroundColor = false;
+
+ if (!line || line->getWidth() == 0) {
+ return;
+ }
+
+ const unsigned char *color = line->getColors();
+ unsigned char background = GETBG(color[0]);
+ unsigned char foreground = GETFG(color[0]);
+ colorInfo->backgroundColorIndex.append(background);
+ colorInfo->foregroundColorIndex.append(foreground);
+ //for (int i = 0; i < color.length() / 2; i++) {
+ // TODO_UTF16: why use color.length()/2 formerly?
+ for (int i = 0; i < (int)line->getWidth(); i++) {
+ if (GETBG(color[i]) != background) {
+ colorInfo->uniBackgroundColor = false;
+ background = GETBG(color[i]);
+ colorInfo->backgroundColorIndex.append(background);
+ }
+ if (GETBG(color[i]) != GETBG(NO_COLOR)) {
+ colorInfo->hasBackgroundColor = true;
+ }
+ if (GETFG(color[i]) != foreground) {
+ colorInfo->uniForegroundColor = false;
+ foreground = GETFG(color[i]);
+ colorInfo->foregroundColorIndex.append(foreground);
+ }
+ if (GETFG(color[i]) != GETFG(NO_COLOR)) {
+ colorInfo->hasForegroundColor = true;
+ }
+ }
+}
+
+bool FQTermSession::readyForInput()
+{
+ return telnet_->readyForInput();
+}
+
+void FQTermSession::onEnqReceived() {
+ if (FQTermPref::getInstance()->replyENQ_)
+ telnet_->write(ANSWERBACK_MESSAGE, sizeof(ANSWERBACK_MESSAGE));
+}
+
+void FQTermSession::onSSHAuthOK() {
+ isSSHLogining_ = false;
+ //setTermSize(80, 24);
+ //setTermSize(param_.numColumns_, param_.numRows_);
+ telnet_->windowSizeChanged(param_.numColumns_, param_.numRows_);
+}
+
+void FQTermSession::updateSetting( const FQTermParam& p ) {
+ bool toggleAutoReconnect = (p.isAutoReconnect_ != param_.isAutoReconnect_);
+ param_ = p;
+ setTermSize(p.numColumns_, p.numRows_);
+ setAntiIdle(isAntiIdle());
+ if (toggleAutoReconnect)
+ setAutoReconnect(param_.isAutoReconnect_);
+}
+
+ArticleCopyThread::ArticleCopyThread(
+ FQTermSession &bbs, QWaitCondition &waitCondition, QReadWriteLock &bufferLock)
+ : session_(bbs),
+ waitCondition_(waitCondition),
+ lock_(bufferLock) {
+ FQ_VERIFY(connect(this, SIGNAL(writeSession(const QString&)),
+ &session_, SLOT(handleInput(const QString&)),
+ Qt::QueuedConnection));
+}
+
+ArticleCopyThread::~ArticleCopyThread() {
+}
+
+static void removeTrailSpace(QString &line) {
+ for (int last_non_space = line.size() - 1;
+ last_non_space >= 0; --last_non_space) {
+ QChar a = line.at(last_non_space);
+ if (!a.isSpace()) {
+ line.resize(last_non_space + 1);
+ break;
+ }
+
+ if (last_non_space == 0) {
+ line.resize(0);
+ }
+ }
+}
+
+
+///////////////////////////////////////
+//analyze last line when copy article
+static std::pair<int, int> ParseLastLine(QString str) {
+ int startLine = -1;
+ int endLine = -1;
+ int infoStart = str.indexOf('(', str.indexOf('(') + 1);
+ int infoEnd = str.indexOf(')', infoStart);
+ int infoSplit = str.indexOf('-', infoStart);
+ if (infoStart == -1 || infoEnd == -1 || infoSplit == -1) {
+ return std::make_pair(-1, -1);
+ }
+ bool ok = true;
+ startLine = str.mid(infoStart + 1, infoSplit - infoStart - 1).toInt(&ok);
+ if (!ok) {
+ return std::make_pair(-1, -1);
+ }
+ endLine = str.mid(infoSplit + 1, infoEnd - infoSplit - 1).toInt(&ok);
+ if (!ok) {
+ return std::make_pair(-1, -1);
+ }
+ return std::make_pair(startLine, endLine);
+}
+///////////////////////////////////////
+
+
+void ArticleCopyThread::run() {
+ QReadLocker locker(&lock_);
+
+ typedef std::vector<QString> Page;
+ const FQTermBuffer *buffer = session_.getBuffer();;
+ Page page;
+
+ QString firstPageLastLine;
+ buffer->getTextLineInTerm(buffer->getNumRows() - 1)->getAllPlainText(firstPageLastLine);
+ bool MultiPage = (firstPageLastLine.indexOf("%") != -1);
+ if (!MultiPage) {
+ emit writeSession("q");
+ emit writeSession("\n");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ return;
+ }
+ buffer->getTextLineInTerm(buffer->getNumRows() - 1)->getAllPlainText(firstPageLastLine);
+ MultiPage = (firstPageLastLine.indexOf("%") != -1);
+ }
+
+ if (MultiPage) {
+ //session_.write("e", 1);
+ emit writeSession("e");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ return;
+ }
+ QString LastPageLastLine;
+ buffer->getTextLineInTerm(buffer->getNumRows() - 1)->getAllPlainText(LastPageLastLine);
+ std::pair<int, int> range = ParseLastLine(LastPageLastLine);
+ if (range.first == -1 || range.second == -1) {
+ return;
+ }
+ page.resize(range.second);
+ for (int i = range.first; i <= range.second; ++i) {
+ QString strTemp;
+ buffer->getTextLineInTerm(i - range.first)->getAllPlainText(strTemp);
+ page[i - 1] = strTemp;
+ }
+ //session_.write("s", 1);
+ emit writeSession("s");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ return;
+ }
+ }
+ else {
+ for (int i = 0; i < buffer->getNumRows() - 1; ++i) {
+ QString strTemp;
+ buffer->getTextLineInTerm(i)->getAllPlainText(strTemp);
+ page.push_back(strTemp);
+ }
+ }
+
+ while (MultiPage) {
+ // the end of article
+ int lineIndex = buffer->getNumRows() - 1;
+ //QByteArray lastLine = buffer->getLineInScreen(lineIndex)->getText();
+ QString lastLine;
+ buffer->getTextLineInTerm(lineIndex)->getAllPlainText(lastLine);
+
+ std::pair<int, int> range = ParseLastLine(lastLine);
+ if (range.first == -1 || range.second == -1) {
+ page.push_back(lastLine);
+ break;
+ }
+
+ // copy a page of lines exclude the last line.
+ for (int i = range.first; i <= range.second; ++i) {
+ QString strTemp;
+ buffer->getTextLineInTerm(i - range.first)->getAllPlainText(strTemp);
+ page[i - 1] = strTemp;
+ }
+
+
+ // wait for next page.
+ //session_.write(" ", 1);
+ emit writeSession(" ");
+ if (!waitCondition_.wait(&lock_, 10000)) {
+ emit articleCopied(DAE_TIMEOUT, "");
+ break;
+ }
+ }
+
+
+
+ QString articleText;
+
+ for (Page::iterator line = page.begin(); line != page.end(); ++line) {
+ removeTrailSpace(*line);
+ articleText += (*line);
+ articleText += (OS_NEW_LINE);
+ }
+
+ //qApp->postEvent(pWin, new QCustomEvent(DAE_FINISH));
+ emit articleCopied(DAE_FINISH, articleText);
+}
+
+} // namespace FQTerm
+
+#include "fqterm_session.moc"
diff --git a/src/terminal/fqterm_session.h b/src/terminal/fqterm_session.h
new file mode 100644
index 0000000..78aaa31
--- /dev/null
+++ b/src/terminal/fqterm_session.h
@@ -0,0 +1,344 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SESSION_H
+#define FQTERM_SESSION_H
+
+#include <vector>
+
+#include <QPoint>
+#include <QRect>
+#include <QObject>
+#include <QThread>
+#include <QString>
+#include <QWaitCondition>
+#include <QList>
+#include <QtScript/QScriptValue>
+#include <QReadWriteLock>
+#include "fqterm_param.h"
+#include "fqterm_config.h"
+#include "fqterm_convert.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif //HAVE_PYTHON
+
+class QRect;
+class QTimer;
+
+namespace FQTerm {
+
+class FQTermScriptEventListener {
+public:
+ bool postScriptCallback(const QString& func,
+#ifdef HAVE_PYTHON
+ PyObject* pArgs,
+#endif //HAVE_PYTHON
+ const QScriptValueList & args = QScriptValueList())
+ {
+ bool res = postQtScriptCallback(func, args);
+#ifdef HAVE_PYTHON
+ res = postPythonCallback(func, pArgs) || res;
+#endif //HAVE_PYTHON
+ return res;
+ }
+ virtual long windowID() = 0;
+ virtual ~FQTermScriptEventListener() {}
+private:
+ virtual bool postQtScriptCallback(const QString& func, const QScriptValueList & args = QScriptValueList()) = 0;
+#ifdef HAVE_PYTHON
+ virtual bool postPythonCallback(const QString& func, PyObject* pArgs) = 0;
+#endif //HAVE_PYTHON
+};
+
+struct LineColorInfo {
+ bool hasBackgroundColor;
+ bool hasForegroundColor;
+ bool uniBackgroundColor;
+ bool uniForegroundColor;
+ QList<unsigned char> backgroundColorIndex;
+ QList<unsigned char> foregroundColorIndex;
+};
+
+class FQTermConfig;
+class FQTermBuffer;
+class FQTermTextLine;
+class FQTermTelnet;
+class FQTermDecode;
+class FQTermZmodem;
+class ArticleCopyThread;
+
+class FQTermSession: public QObject {
+ Q_OBJECT;
+ public:
+ enum CursorType {
+ kHome = 0,
+ kEnd = 1,
+ kPageUp = 2,
+ kPageDown = 3,
+ kUp = 4,
+ kDown = 5,
+ kLeft = 6,
+ kRight = 7,
+ kNormal = 8
+ };
+
+ FQTermSession(FQTermConfig *, FQTermParam);
+ ~FQTermSession();
+
+ enum PageState {
+ Undefined = -1,
+ Menu = 0,
+ MailMenu = 1,
+ ArticleList = 2,
+ EliteArticleList = 3,
+ BoardList = 4,
+ FriendMailList = 5,
+ Message = 6,
+ Read = 7,
+ Edit = 8,
+ TOP10 = 9,
+ };
+
+ enum ProtocolIndex {
+ Http = 0,
+ Https = 1,
+ Mms = 2,
+ Rstp = 3,
+ Ftp = 4,
+ Mailto = 5,
+ Telnet = 6,
+ ProtocolSupported = 7
+ };
+
+ static const QString endOfUrl[];
+
+ static const QString protocolPrefix[];
+ PageState getPageState();
+
+ // Set current cursor postion to pt,
+ // return whether the selection rectangle is changed.
+ // the output parameter rc be a rectangle including both
+ // the new and the old selection region.
+ bool setCursorPos(const QPoint &pt, QRect &rc);
+ CursorType getCursorType(const QPoint &);
+
+ // Get the menu char detected in getSelectRect().
+ char getMenuChar();
+
+ // Get current selection rectangle.
+ // also detect the menu char if in kMenu page state.
+ QRect detectMenuRect();
+ QRect getMenuRect() {return menuRect_;}
+ void setMenuRect(int row, int col, int len);
+ // detect whether the given line or point is contained by current selection rectangle.
+ bool isSelectedMenu(int line);
+ bool isSelectedMenu(const QPoint &);
+ //selection.
+ void setSelect(const QPoint &pt1, const QPoint &pt2);
+ void clearSelect();
+
+ bool isUrl(QRect &, QRect &);
+ bool isIP(QRect &, QRect &);
+ QString getUrl();
+ QString getIP();
+
+
+
+ // Set current screen start line to help detect cursor type
+ // and select rectangle corresponding to current cursor postion.
+ void setScreenStart(int);
+
+
+
+ // Set a line of buffer to have been changed from start to end.
+ void clearLineChanged(int index);
+ void setLineAllChanged(int index);
+
+ bool isAntiIdle();
+ void setAntiIdle(bool antiIdle);
+ void leaveIdle();
+
+ bool isAutoReply();
+ void setAutoReply(bool autoReply);
+ QString getMessage();
+
+ void setAutoReconnect(bool autoReconnect);
+
+
+ bool readyForInput();
+ void setTermSize(int col, int row);
+
+ QWaitCondition& getWaitCondition() {return waitCondition_;};
+ //this function will do
+ //1. convert unicode to bbs encoding
+ //2. if there are some chars express same meaning in simplify/traditional
+ //Chinese, auto covert them by considering ime/bbs encoding.
+ QByteArray unicode2bbs_smart(const QString &);
+ QString bbs2unicode(const QByteArray &text);
+ QByteArray unicode2bbs(const QString &text);
+
+ // Write data raw data
+ int write(const char *data, int len);
+ int writeStr(const char *str);
+
+ // type: 0-no proxy; 1-wingate; 2-sock4; 3-socks5
+ // needAuth: if authentation needed
+ void setProxy(int type, bool needAuth,
+ const QString &hostname, quint16 portNumber,
+ const QString &username, const QString &password);
+ // User close the connection
+ void close();
+
+ bool isConnected() {return isConnected_;}
+ void setSendingMessage(bool sending = true) {isSendingMessage_ = sending;}
+ const QPoint& urlStartPoint() {return urlStartPoint_;}
+ const QPoint& urlEndPoint() {return urlEndPoint_;}
+
+ FQTermParam& param() {return param_;}
+ void updateSetting(const FQTermParam& p);
+ QReadWriteLock& getBufferLock() {return bufferWriteLock_;}
+
+ public:
+
+
+ public slots:
+ FQTermBuffer *getBuffer() const;
+ void connectHost(const QString &hostname, quint16 portnumber);
+ void reconnect();
+ void disconnect();
+
+ void cancelZmodem();
+ void changeTelnetState(int state);
+
+ void handleInput(const QString &text);
+
+ void copyArticle();
+
+ signals:
+ void messageAutoReplied();
+ void articleCopied(int state, const QString content);
+ void sessionUpdated();
+ void connectionClosed();
+ void bellReceived();
+ void onTitleSet(const QString&);
+ void startAlert();
+ void stopAlert();
+
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+
+ void telnetStateChanged(int state);
+ void zmodemStateChanged(int type, int value, const char *status);
+
+ void errorMessage(QString);
+
+private slots:
+ void readReady(int size, int raw_size);
+ void onIdle();
+ void onAutoReply();
+ void onEnqReceived();
+ void onSSHAuthOK();
+ void setMouseMode(bool on);
+
+private:
+ void sendMouseState(int, Qt::KeyboardModifier, Qt::KeyboardModifier, const QPoint &);
+ void getLineColorInfo(const FQTermTextLine * line, LineColorInfo * colorInfo);
+ bool isIllChar(char);
+ void detectPageState();
+ QString expandUrl(const QPoint& pt, QPair<int, int>& range);
+ bool checkUrl(QRect &, QRect &, bool);
+ QByteArray parseString(const QByteArray &cstr, int *len = 0);
+ void finalizeConnection();
+ bool isPageComplete();
+ void autoReplyMessage();
+ void reconnectProcess();
+ void doAutoLogin();
+
+private:
+ //this read-write lock will be locked as a writer's lock if the buffer is being changed
+ //so for a reader who wants to ensure thread-safe, he should lock
+ //this lock as a reader's lock.
+ mutable QReadWriteLock bufferWriteLock_;
+
+ FQTermParam param_;
+ FQTermConvert encodingConverter_;
+ bool isTelnetLogining_;
+ bool isSSHLogining_;
+
+ bool isIdling_;
+ bool isMouseX11_;
+ bool isConnected_;
+ bool isSendingMessage_;
+
+ QRect urlRect_;
+ QPoint urlStartPoint_;
+ QPoint urlEndPoint_;
+ QString url_;
+ QString ip_;
+ char menuChar_;
+ QRect menuRect_;
+ PageState pageState_;
+ QPoint cursorPoint_;
+ int screenStartLineNumber_;
+
+ FQTermZmodem *zmodem_;
+ FQTermDecode *decoder_;
+ FQTermTelnet *telnet_;
+ FQTermBuffer *termBuffer_;
+
+ QTimer *idleTimer_;
+ QTimer *autoReplyTimer_;
+
+ QWaitCondition waitCondition_;
+ ArticleCopyThread *acThread_;
+
+ std::vector<char> telnet_data_;
+ std::vector<char> raw_data_;
+
+ int reconnectRetry_;
+public:
+ void setScriptListener(FQTermScriptEventListener* pythonListener) {
+ scriptListener_ = pythonListener;
+ }
+private:
+ FQTermScriptEventListener* scriptListener_;
+};
+
+class ArticleCopyThread: public QThread {
+ Q_OBJECT;
+ public:
+ ArticleCopyThread(FQTermSession &bbs, QWaitCondition &waitCondition, QReadWriteLock &bufferLock);
+
+ ~ArticleCopyThread();
+
+ signals:
+ void articleCopied(int state, const QString content);
+ void writeSession(const QString&);
+ protected:
+ virtual void run();
+ private:
+ FQTermSession &session_;
+ QWaitCondition &waitCondition_;
+
+ QReadWriteLock &lock_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SESSION_H
diff --git a/src/terminal/fqterm_text_line.cpp b/src/terminal/fqterm_text_line.cpp
new file mode 100644
index 0000000..ed6d164
--- /dev/null
+++ b/src/terminal/fqterm_text_line.cpp
@@ -0,0 +1,541 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <QRegExp>
+#include <QString>
+
+#include "fqterm.h"
+#include "fqterm_text_line.h"
+
+namespace FQTerm {
+
+#ifndef NDEBUG
+//#define TEXT_LINE_CHECK
+#else
+//#define TEXT_LINE_CHECK
+#endif
+
+#ifndef TEXT_LINE_CHECK
+void FQTermTextLine::verifyTextLine() const {}
+void FQTermTextLine::verifyCellRange(unsigned, unsigned) const {}
+#else
+void FQTermTextLine::verifyTextLine() const {
+ unsigned last_cell = 0;
+ unsigned cur_cell = last_cell;
+
+ if (cells_.size() == 0
+ || cell_colors_.size() == 0
+ || cell_attrs_.size() == 0
+ || chars_.size() == 0
+ ) {
+ FQ_VERIFY(cells_.size() == 0);
+ FQ_VERIFY(cell_colors_.size() == 0);
+ FQ_VERIFY(cell_attrs_.size() == 0);
+ FQ_VERIFY(chars_.size() == 0);
+ return;
+ }
+
+ FQ_VERIFY(max_cell_count_ < 65536);
+ FQ_VERIFY(chars_.size() < 65536);
+ FQ_VERIFY(cells_.size() <= max_cell_count_);
+ FQ_VERIFY(cells_.size() == cell_colors_.size());
+ FQ_VERIFY(cells_.size() == cell_attrs_.size());
+
+ const UTF16 *start = &chars_[0];
+ const UTF16 *end = start + chars_.size();
+
+ for (const UTF16 *p = start; p < end;) {
+ int w = mk_advace_at_least_one_cell(&p, end);
+
+ FQ_VERIFY(w >= 0); // should be valid unicode string.
+
+ cur_cell += w;
+
+ for (unsigned i = last_cell; i < cur_cell; ++i) {
+ unsigned char_end = p - start;
+ FQ_VERIFY(cells_[i] == char_end);
+ }
+
+ last_cell = cur_cell;
+ }
+
+ FQ_VERIFY(cur_cell == getWidth());
+ FQ_VERIFY(cells_.back() == chars_.size());
+}
+
+void FQTermTextLine::verifyCellRange(unsigned cell_begin, unsigned cell_end) const {
+ FQ_VERIFY(cell_begin <= cell_end);
+ FQ_VERIFY(cell_end <= getWidth());
+
+ unsigned real_cell_begin = getCellBegin(cell_begin);
+ FQ_VERIFY(real_cell_begin == cell_begin);
+
+ unsigned real_cell_end = getCellBegin(cell_end);
+ FQ_VERIFY(real_cell_end == cell_end);
+
+ unsigned char_begin = getCharBegin(cell_begin);
+ FQ_VERIFY(char_begin <= chars_.size());
+
+ unsigned char_end = getCharEnd(cell_end);
+ FQ_VERIFY(char_begin <= char_end);
+ FQ_VERIFY(char_end <= chars_.size());
+
+}
+
+#endif
+
+FQTermTextLine::FQTermTextLine(unsigned max_cell_count)
+ : max_cell_count_(max_cell_count),
+ dirty_cell_begin_(0),
+ dirty_cell_end_(max_cell_count),
+ stored_color_(0),
+ stored_attr_(0){
+ cells_.reserve(max_cell_count_);
+ cell_colors_.reserve(max_cell_count_);
+ cell_attrs_.reserve(max_cell_count_);
+ chars_.reserve(max_cell_count_);
+}
+
+FQTermTextLine::~FQTermTextLine() {
+}
+
+void FQTermTextLine::setMaxCellCount(unsigned max_cell_count) {
+ // FIXME: how about dirty flag?
+ max_cell_count_ = max_cell_count;
+
+ if (cells_.size() > max_cell_count_) {
+ // TODO_UTF16: what if an incomplete utf-16 byte left.
+ cells_.resize(max_cell_count_);
+ cell_colors_.resize(max_cell_count_);
+ cell_attrs_.resize(max_cell_count_);
+ chars_.resize(cells_.back());
+ }
+}
+
+// Whether this line of text contains blink characters.
+bool FQTermTextLine::hasBlink() const {
+ bool blink = false;
+
+ char tempea;
+ for (unsigned i = 0; i < cells_.size(); i++) {
+ tempea = cell_attrs_[i];
+ if (GETBLINK(tempea)) {
+ blink = true;
+ break;
+ }
+ }
+
+ return blink;
+}
+
+void FQTermTextLine::setDirtyFlag(unsigned cell_begin, unsigned cell_end) {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_begin <= cell_end);
+ FQ_VERIFY(cell_end <= max_cell_count_);
+#endif
+ if (dirty_cell_begin_ > cell_begin) {
+ dirty_cell_begin_ = cell_begin;
+ }
+
+ if (dirty_cell_end_ < cell_end) {
+ dirty_cell_end_ = cell_end;
+ }
+}
+
+void FQTermTextLine::safelySetDirtyFlag(unsigned cell_begin, unsigned cell_end) {
+ if (cell_end > max_cell_count_) cell_end = max_cell_count_;
+
+ if (cell_begin >= cell_end)
+ return;
+
+ setDirtyFlag(cell_begin, cell_end);
+}
+
+void FQTermTextLine::clearDirtyFlag() {
+ dirty_cell_begin_ = 0;
+ dirty_cell_end_ = 0;
+}
+
+bool FQTermTextLine::getDirtyCells(unsigned &cell_begin, unsigned &cell_end) const {
+ cell_begin = dirty_cell_begin_;
+ cell_end = dirty_cell_end_;
+ return dirty_cell_begin_ < dirty_cell_end_;
+}
+
+void FQTermTextLine::getPlainText(unsigned cell_begin, unsigned cell_end,
+ QString &result) const {
+ verifyCellRange(cell_begin, cell_end);
+
+ if (cells_.size() == 0 || cell_begin == cell_end) return;
+
+ unsigned char_begin = getCharBegin(cell_begin);
+ unsigned char_end = getCharEnd(cell_end);
+
+ result.insert(result.size(),
+ (QChar *) &chars_[char_begin],
+ char_end - char_begin);
+
+ typedef char Verify_QChar_Is_Two_Bytes[
+ (sizeof(QChar) == 2)? 1 : -1];
+}
+
+void FQTermTextLine::getAnsiText(unsigned cell_begin, unsigned cell_end,
+ QString &result,
+ const char *escape) const {
+ verifyCellRange(cell_begin, cell_end);
+
+ if (cells_.size() == 0 || cell_begin == cell_end) return;
+
+ unsigned cur_cell = cell_begin;
+ unsigned next_cell = cell_begin;
+
+ while (cur_cell < cell_end) {
+ unsigned char color = cell_colors_[cur_cell];
+ unsigned char attr = cell_attrs_[cur_cell];
+
+ for (next_cell = cur_cell;
+ next_cell < cell_end;
+ ++next_cell) {
+ if (!(cell_colors_[next_cell] == color
+ && cell_attrs_[next_cell] == attr)) {
+ if (next_cell > getCellBegin(next_cell)) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ }
+
+ getAnsiCtrlSeq(color, attr, escape, result);
+ getPlainText(cur_cell, next_cell, result);
+ result += escape;
+ result += "0m";
+
+ cur_cell = next_cell;
+ }
+}
+
+
+void FQTermTextLine::appendWhiteSpace(
+ unsigned count, unsigned char color, unsigned char attr, UTF16 space) {
+ FQ_ASSERT(get_str_width(space) == 1);
+
+ cells_.reserve(getWidth() + count);
+ max_cell_count_ = qMax(max_cell_count_, getWidth() + count);
+
+ cell_colors_.reserve(getWidth() + count);
+ cell_attrs_.reserve(getWidth() + count);
+
+ setDirtyFlag(getWidth(), getWidth() + count);
+
+ chars_.insert(chars_.end(), count, space);
+ cell_colors_.insert(cell_colors_.end(), count, color);
+ cell_attrs_.insert(cell_attrs_.end(), count, attr);
+
+ int c = getCharEnd(getWidth());
+ for (unsigned i = 0; i < count; ++i) {
+ cells_.push_back(c + i + 1);
+ }
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::insertWhiteSpace(unsigned count, unsigned cell_begin,
+ unsigned char color, unsigned char attr,
+ UTF16 space) {
+ FQ_ASSERT(get_str_width(space) == 1);
+
+ breakCell(cell_begin);
+
+ verifyCellRange(cell_begin, getWidth());
+
+ unsigned char_begin = getCharBegin(cell_begin);
+
+ max_cell_count_ = qMax(max_cell_count_, getWidth() + count);
+
+ chars_.insert(chars_.begin() + char_begin, count, space);
+ cell_colors_.insert(cell_colors_.begin() + cell_begin, count, color);
+ cell_attrs_.insert(cell_attrs_.begin() + cell_begin, count, attr);
+
+ cells_.insert(cells_.begin() + cell_begin, count, 0);
+ for (unsigned i = cell_begin; i < cell_begin + count; ++i) {
+ cells_[i] = char_begin + (i - cell_begin) + 1;
+ }
+ for (unsigned i = cell_begin + count; i < getWidth(); ++i) {
+ cells_[i] += count;
+ }
+
+ setDirtyFlag(cell_begin, this->getWidth());
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::replaceWithWhiteSpace(
+ unsigned count, unsigned cell_begin, unsigned cell_end,
+ unsigned char color, unsigned char attr, UTF16 space) {
+ if(cell_end>cells_.size() || cell_begin>=cell_end)
+ return;
+ deleteText(cell_begin, cell_end);
+ insertWhiteSpace(count, cell_begin, color, attr, space);
+}
+
+
+
+void FQTermTextLine::insertText(const UTF16 *str, unsigned count,
+ unsigned cell_begin,
+ unsigned char color, unsigned char attr, int charstate) {
+ if (count == 0) return;
+
+ // Calculate how many cells should be occupied for str.
+ // TODO: avoid compute the width of str twice.
+ int width = get_str_width(str, count);
+
+ if (width == 0) {
+#ifdef TEXT_LINE_CHECK
+ //FQ_VERIFY(false);
+ //TODO: enable utf8 decoding
+#endif
+ return;
+ }
+
+ if (charstate & FQTermTextLine::FIRSTPART) {
+ stored_color_ = color;
+ stored_attr_ = attr;
+ width--;
+ count--;
+ if (width == 0 || count == 0) {
+ return;
+ }
+ }
+
+ breakCell(cell_begin);
+
+ verifyCellRange(cell_begin, getWidth());
+
+ unsigned char_begin = getCharBegin(cell_begin);
+
+ chars_.insert(chars_.begin() + char_begin, str, str + count);
+
+ // Insert colors.
+ cell_colors_.insert(cell_colors_.begin() + cell_begin, width, color);
+
+ // Insert attrs.
+ cell_attrs_.insert(cell_attrs_.begin() + cell_begin, width, attr);
+
+ if (charstate & FQTermTextLine::SECONDPART){
+ cell_colors_[cell_begin] = stored_color_;
+ cell_attrs_[cell_begin] = stored_attr_;
+ }
+
+
+ // Change the cells_ mapping to chars_.
+ cells_.insert(cells_.begin() + cell_begin, width, 0);
+ max_cell_count_ = qMax(max_cell_count_, getWidth());
+
+ unsigned last_cell = cell_begin;
+ unsigned cur_cell = last_cell;
+ for (const UTF16 *p = str; p < str +count;) {
+ int w = mk_advace_at_least_one_cell(&p, str + count);
+
+#ifdef TEXT_LINE_CHECK
+ // TODO_UTF16: FIXME: deal with decoding error.
+ FQ_VERIFY(w >= 0);
+#endif
+
+ cur_cell += w;
+
+ for (unsigned i = last_cell; i < cur_cell; ++i) {
+ cells_[i] = char_begin + (p - str);
+ }
+
+ last_cell = cur_cell;
+ }
+
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cur_cell == cell_begin + width);
+#endif
+
+ for (unsigned i = cell_begin + width; i < cells_.size(); ++i) {
+ cells_[i] += count;
+ }
+
+
+
+ setDirtyFlag(cell_begin, cells_.size());
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::deleteText(unsigned cell_begin, unsigned cell_end) {
+ if (cells_.size() == 0 || cell_begin == cell_end) return;
+
+ breakCell(cell_begin);
+ breakCell(cell_end);
+
+ verifyCellRange(cell_begin, cell_end);
+
+ setDirtyFlag(cell_begin, cells_.size());
+
+ unsigned char_begin = getCharBegin(cell_begin);
+ unsigned char_end = getCharEnd(cell_end);
+
+ chars_.erase(chars_.begin() + char_begin, chars_.begin() + char_end);
+
+ cells_.erase(cells_.begin() + cell_begin, cells_.begin() + cell_end);
+ cell_colors_.erase(cell_colors_.begin() + cell_begin,
+ cell_colors_.begin() + cell_end);
+ cell_attrs_.erase(cell_attrs_.begin() + cell_begin,
+ cell_attrs_.begin() + cell_end);
+
+ for (unsigned i = cell_begin; i < cells_.size(); ++i) {
+ cells_[i] -= (char_end - char_begin);
+ }
+
+ verifyTextLine();
+}
+
+void FQTermTextLine::deleteAllText() {
+ deleteText(0, getWidth());
+}
+
+void FQTermTextLine::replaceText(const UTF16 *str, unsigned count,
+ unsigned cell_begin, unsigned cell_end,
+ unsigned char color, unsigned char attr, int charstate) {
+ if (charstate & FQTermTextLine::FIRSTPART) {
+ stored_color_ = color;
+ stored_attr_ = attr;
+ count--;
+ if (count == 0)
+ {
+ return;
+ }
+ charstate &= ~FQTermTextLine::FIRSTPART;
+ }
+
+ deleteText(cell_begin, cell_end);
+ insertText(str, count, cell_begin, color, attr, charstate);
+
+ setDirtyFlag(cell_begin, cells_.size());
+}
+
+
+unsigned FQTermTextLine::getCellBegin(unsigned cell_begin) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_begin <= getWidth());
+#endif
+
+ if (cell_begin == cells_.size()) return cell_begin;
+
+ while(cell_begin > 0 && cells_[cell_begin - 1] == cells_[cell_begin]) {
+ --cell_begin;
+ }
+
+ return cell_begin;
+}
+
+unsigned FQTermTextLine::getCellEnd(unsigned cell_end) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_end <= getWidth());
+#endif
+
+ if (cell_end == 0) return cell_end;
+
+ while (cell_end < cells_.size() && cells_[cell_end - 1] == cells_[cell_end]) {
+ ++cell_end;
+ }
+
+ return cell_end;
+}
+
+unsigned FQTermTextLine::getCharBegin(unsigned cell_begin) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_begin == getCellBegin(cell_begin));
+#endif
+
+ if (cell_begin == 0) return 0;
+
+ return cells_[cell_begin - 1];
+}
+
+unsigned FQTermTextLine::getCharEnd(unsigned cell_end) const {
+#ifdef TEXT_LINE_CHECK
+ FQ_VERIFY(cell_end == getCellEnd(cell_end));
+#endif
+
+ if (cell_end == 0) return 0;
+
+ return cells_[cell_end - 1];
+}
+
+bool FQTermTextLine::breakCell(unsigned cell_begin) {
+ unsigned real_cell_begin = getCellBegin(cell_begin);
+ if (real_cell_begin == cell_begin) return false;
+
+ unsigned real_cell_end = getCellEnd(cell_begin);
+
+ verifyCellRange(real_cell_begin, real_cell_end);
+
+ unsigned cell_count = real_cell_end - real_cell_begin;
+
+ replaceWithWhiteSpace(cell_count, real_cell_begin, real_cell_end,
+ cell_colors_[cell_begin], cell_attrs_[cell_begin], URC);
+
+ return true;
+}
+
+void FQTermTextLine::getAnsiCtrlSeq(
+ unsigned char color, unsigned char attr,
+ const char *escape, QString &result) const {
+
+ int fg = GETFG(color) + 30;
+ int bg = GETBG(color) + 40;
+
+ result += escape;
+ result += QString("%1;%2").arg(fg).arg(bg);
+
+ if (GETBRIGHT(attr)) {
+ result += ";1";
+ }
+ if (GETDIM(attr)) {
+ result += ";2";
+ }
+ if (GETUNDERLINE(attr)) {
+ result += ";4";
+ }
+ if (GETBLINK(attr)) {
+ result += ";5";
+ }
+ if (GETRAPIDBLINK(attr)) {
+ result += ";6";
+ }
+ if (GETREVERSE(attr)) {
+ result += ";7";
+ }
+ if (GETINVISIBLE(attr)) {
+ result += ";8";
+ }
+
+ result += "m";
+}
+
+
+} // namespace FQTerm
diff --git a/src/terminal/fqterm_text_line.h b/src/terminal/fqterm_text_line.h
new file mode 100644
index 0000000..72ff4c0
--- /dev/null
+++ b/src/terminal/fqterm_text_line.h
@@ -0,0 +1,159 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TEXTLINE_H
+#define FQTERM_TEXTLINE_H
+
+#include <vector>
+
+#include "fqwcwidth.h"
+#include "fqterm.h"
+class QString;
+
+namespace FQTerm {
+/*
+ A text line consists of several characters in a sequence of cells. A
+ character may occupy some cells, e.g. each English letter occupies
+ one cell, while a CJK character needs two.
+
+ This class is used to manipolate a text line, delete/replace
+ characters in a given cell range, insert characters before a cell,
+ and retrieve characters/colors/attributs of a gaven cell range.
+*/
+class FQTermTextLine {
+ public:
+ FQTermTextLine(unsigned max_cell_count);
+ ~FQTermTextLine();
+
+ enum CHARSTATE{NORMAL = 0x00, FIRSTPART = 0x01, SECONDPART = 0x02};
+ // Get the number of used cells.
+ unsigned getWidth() const {return cells_.size();}
+
+ void setMaxCellCount(unsigned max_cell_count);
+ unsigned getMaxCellCount() const { return max_cell_count_; }
+
+ // Whether this line of text contains blink characters.
+ bool hasBlink() const;
+
+ // Set/get the dirty flag, that indicates which cells have been
+ // modified.
+ void setDirtyFlag(unsigned cell_begin, unsigned cell_end);
+ void safelySetDirtyFlag(unsigned cell_begin, unsigned cell_end);
+ bool getDirtyCells(unsigned &cell_begin, unsigned &cell_end) const;
+ void clearDirtyFlag();
+ void setAllDirty() {setDirtyFlag(0, max_cell_count_);}
+
+ const unsigned char *getColors() const {
+ return cells_.size() == 0 ? NULL : &cell_colors_[0];
+ }
+
+ const unsigned char *getAttributes() const {
+ return cells_.size() == 0 ? NULL : &cell_attrs_[0];
+ }
+
+ // Get plain text in [cell_begin, cell_end).
+ void getPlainText(unsigned cell_begin, unsigned cell_end,
+ QString &result) const;
+
+ void getAllPlainText(QString &result) const {
+ getPlainText(0, getWidth(), result);
+ }
+
+ // Get text in cells [cell_begin, cell_end), with color and
+ // attribute in ANSI format.
+ void getAnsiText(unsigned cell_begin, unsigned cell_end,
+ QString &result,
+ const char *escape = "\x1b\x1b") const;
+
+ void getAllAnsiText(QString &result, const char* escape = "\x1b\x1b") const {
+ getAnsiText(0, getWidth(), result, escape);
+ }
+
+ void appendWhiteSpace(unsigned count,
+ unsigned char color = NO_COLOR,
+ unsigned char attr = NO_ATTR,
+ UTF16 space = ' ');
+
+ void insertWhiteSpace(unsigned count, unsigned cell_begin,
+ unsigned char color = NO_COLOR,
+ unsigned char attr = NO_ATTR,
+ UTF16 space = ' ');
+
+ void replaceWithWhiteSpace(unsigned count,
+ unsigned cell_begin, unsigned cell_end,
+ unsigned char color = NO_COLOR,
+ unsigned char attr = NO_ATTR,
+ UTF16 space = ' ');
+
+ // insert string at specified cell,
+ void insertText(const UTF16 *str, unsigned count,
+ unsigned cell_begin,
+ unsigned char color, unsigned char attr, int charstate = FQTermTextLine::NORMAL);
+ void replaceText(const UTF16 *str, unsigned count,
+ unsigned cell_begin, unsigned cell_end,
+ unsigned char color, unsigned char attr, int charstate = FQTermTextLine::NORMAL);
+ void deleteText(unsigned cell_begin, unsigned cell_end);
+ void deleteAllText();
+
+ // If cell_begin is a begining of a readable character, return
+ // cell_begin itself, otherwise return the previous cell which starts a
+ // readable character.
+ unsigned getCellBegin(unsigned cell_begin) const;
+
+ // If cell_end is a ending of a readable character, return cell_end
+ // itself, otherwise return the next cell which finishes a
+ // readable character.
+ unsigned getCellEnd(unsigned cell_end) const;
+
+ unsigned getCharBegin(unsigned cell_begin) const;
+ unsigned getCharEnd(unsigned cell_end) const;
+
+ private:
+ unsigned max_cell_count_; // max number of cells allowed.
+
+ std::vector<uint16_t> cells_; // store the index of character in this->chars_ for each cell.
+ std::vector<unsigned char> cell_colors_; // store the color for each cell.
+ std::vector<unsigned char> cell_attrs_; // store the attribute for each cell.
+ std::vector<UTF16> chars_; // store all the character.
+
+ unsigned char stored_color_;
+ unsigned char stored_attr_;
+
+ // range of changed text.
+ unsigned dirty_cell_begin_, dirty_cell_end_;
+
+ // if the given cell isn't a beginning of characters,
+ // i.e is in the middle of a wide character,
+ // break the character into several unicode replacement characters (URC)
+ // to make the given cell be a beginning of character.
+ bool breakCell(unsigned cell_begin);
+
+ // calculate ANSI escape sequence with given color, attribute and escape strings.
+ void getAnsiCtrlSeq(unsigned char color, unsigned char attr,
+ const char *escape, QString &result) const;
+
+ // Two functions for debugging/testing.
+ void verifyTextLine() const;
+ void verifyCellRange(unsigned cell_begin, unsigned cell_end) const;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TEXTLINE_H
diff --git a/src/terminal/internal/fqterm_decode.cpp b/src/terminal/internal/fqterm_decode.cpp
new file mode 100644
index 0000000..cb7bc9a
--- /dev/null
+++ b/src/terminal/internal/fqterm_decode.cpp
@@ -0,0 +1,1279 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QByteArray>
+
+#include "fqterm.h"
+#include "fqterm_telnet.h"
+#include "fqterm_decode.h"
+#include "fqterm_buffer.h"
+#include "fqwcwidth.h"
+
+namespace FQTerm {
+
+#define MODE_MouseX11 0
+
+/************************************************************************/
+// state for FSM
+// please read ANSI decoding
+StateOption FQTermDecode::VT100StateMachine::normal_state_[] = {
+ {
+ CHAR_CR, &FQTermDecode::cr, normal_state_
+ }, {
+ CHAR_LF, &FQTermDecode::lf, normal_state_
+ }, {
+ CHAR_VT, &FQTermDecode::lf, normal_state_
+ }, {
+ CHAR_ESC, 0, esc_state_
+ }, {
+ CHAR_FF, &FQTermDecode::ff, normal_state_
+ }, {
+ CHAR_TAB, &FQTermDecode::tab, normal_state_
+ }, {
+ CHAR_BS, &FQTermDecode::bs, normal_state_
+ }, {
+ CHAR_BELL, &FQTermDecode::bell, normal_state_
+ }, {
+ CHAR_SO, &FQTermDecode::g1, normal_state_
+ }, {
+ CHAR_SI, &FQTermDecode::g0, normal_state_
+ }, {
+ CHAR_CAN, 0, normal_state_ // should be ignored
+ }, {
+ CHAR_DEL, &FQTermDecode::del, normal_state_
+ }, {
+ CHAR_NUL, 0, normal_state_ // should be ignored
+ }, {
+ CHAR_ENQ, &FQTermDecode::enq, normal_state_
+ }, {
+ CHAR_NORMAL, &FQTermDecode::normalInput, normal_state_
+ }
+};
+
+// state after a ESC_CHAR
+StateOption FQTermDecode::VT100StateMachine::esc_state_[] = {
+ {
+ '7', &FQTermDecode::saveCursor, normal_state_
+ }, {
+ '8', &FQTermDecode::restoreCursor, normal_state_
+ }, {
+ '[', &FQTermDecode::clearParam, bracket_state_
+ }, {
+ ']', &FQTermDecode::clearParam, title_state_
+ }, {
+ '(', 0, select_g0_charset_state_
+ }, {
+ ')', 0, select_g1_charset_state_
+ }, {
+ 'D', &FQTermDecode::moveCursorDown, normal_state_
+ }, {
+ 'E', &FQTermDecode::nextLine, normal_state_
+ }, {
+ 'H', &FQTermDecode::addTabStop, normal_state_
+ }, {
+ 'M', &FQTermDecode::moveCursorUp, normal_state_
+ }, {
+ '>', &FQTermDecode::setNumericKeypad, normal_state_
+ }, {
+ '=', &FQTermDecode::setAppKeypad, normal_state_
+ }, {
+ '<', &FQTermDecode::test, normal_state_
+ }, {
+ '#', 0, sharp_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC [
+StateOption FQTermDecode::VT100StateMachine::bracket_state_[] = {
+ {
+ '0', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '1', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '2', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '3', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '4', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '5', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '6', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '7', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '8', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ '9', &FQTermDecode::paramDigit, bracket_state_
+ }, {
+ ';', &FQTermDecode::nextParam, bracket_state_
+ }, {
+ '?', &FQTermDecode::clearParam, private_state_
+ }, {
+ 'A', &FQTermDecode::cursorUp, normal_state_
+ }, {
+ 'B', &FQTermDecode::cursorDown, normal_state_
+ }, {
+ 'C', &FQTermDecode::cursorRight, normal_state_
+ }, {
+ 'D', &FQTermDecode::cursorLeft, normal_state_
+ }, {
+ 'H', &FQTermDecode::cursorPosition, normal_state_
+ }, {
+ 'J', &FQTermDecode::eraseScreen, normal_state_
+ }, {
+ 'K', &FQTermDecode::eraseLine, normal_state_
+ }, {
+ 'L', &FQTermDecode::insertLine, normal_state_
+ }, {
+ 'M', &FQTermDecode::deleteLine, normal_state_
+ }, {
+ 'P', &FQTermDecode::deleteStr, normal_state_
+ }, {
+ 'X', &FQTermDecode::eraseStr, normal_state_
+ }, {
+ 'f', &FQTermDecode::cursorPosition, normal_state_
+ }, {
+ 'g', &FQTermDecode::clearTabStop, normal_state_
+ }, {
+ 'h', &FQTermDecode::setMode, normal_state_
+ }, {
+ 'l', &FQTermDecode::resetMode, normal_state_
+ }, {
+ 'm', &FQTermDecode::setAttr, normal_state_
+ }, {
+ 'q', 0, normal_state_ // ignore LED-related commands.
+ }, {
+ 'r', &FQTermDecode::setMargins, normal_state_
+ }, {
+ 's', &FQTermDecode::saveCursor, normal_state_
+ }, {
+ 'u', &FQTermDecode::restoreCursor, normal_state_
+ }, {
+ '@', &FQTermDecode::insertStr, normal_state_
+ }, {
+ CHAR_CR, &FQTermDecode::cr, bracket_state_
+ }, {
+ CHAR_LF, &FQTermDecode::lf, bracket_state_
+ }, {
+ CHAR_VT, &FQTermDecode::lf, bracket_state_
+ }, {
+ CHAR_FF, &FQTermDecode::ff, bracket_state_
+ }, {
+ CHAR_TAB, &FQTermDecode::tab, bracket_state_
+ }, {
+ CHAR_BS, &FQTermDecode::bs, bracket_state_
+ }, {
+ CHAR_BELL, &FQTermDecode::bell, bracket_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC (
+StateOption FQTermDecode::VT100StateMachine::select_g0_charset_state_[] = {
+ {
+ 'A', &FQTermDecode::selectG0A, normal_state_
+ }, {
+ 'B', &FQTermDecode::selectG0B, normal_state_
+ }, {
+ '0', &FQTermDecode::selectG00, normal_state_
+ }, {
+ '1', &FQTermDecode::selectG01, normal_state_
+ }, {
+ '2', &FQTermDecode::selectG02, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC )
+StateOption FQTermDecode::VT100StateMachine::select_g1_charset_state_[] = {
+ {
+ 'A', &FQTermDecode::selectG1A, normal_state_
+ }, {
+ 'B', &FQTermDecode::selectG1B, normal_state_
+ }, {
+ '0', &FQTermDecode::selectG10, normal_state_
+ }, {
+ '1', &FQTermDecode::selectG11, normal_state_
+ }, {
+ '2', &FQTermDecode::selectG12, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC [ ?
+StateOption FQTermDecode::VT100StateMachine::private_state_[] = {
+ {
+ '0', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '1', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '2', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '3', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '4', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '5', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '6', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '7', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '8', &FQTermDecode::paramDigit, private_state_
+ }, {
+ '9', &FQTermDecode::paramDigit, private_state_
+ }, {
+ ';', &FQTermDecode::nextParam, private_state_
+ }, {
+ 'h', &FQTermDecode::setDecPrivateMode, normal_state_
+ }, {
+ 'l', &FQTermDecode::resetDecPrivateMode, normal_state_
+ }, {
+ 's', &FQTermDecode::saveMode, normal_state_
+ }, {
+ 'r', &FQTermDecode::restoreMode, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC #
+StateOption FQTermDecode::VT100StateMachine::sharp_state_[] = {
+ {
+ '8', &FQTermDecode::fillScreen, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC ]
+// to change the terminal title dynamically.
+// Dynamic titles
+// Many people find it useful to set the title of a terminal to reflect dynamic information,
+// such as the name of the host the user is logged into, the current working directory, etc.
+// This may be done by using XTerm escape sequences. The following sequences are useful in this respect:
+// ESC]0;stringBEL Set icon name and window title to string
+// ESC]1;stringBEL Set icon name to string
+// ESC]2;stringBEL Set window title to string
+// where ESC is the escape character (\033), and BEL is the bell character (\007).
+// Currently we just ignore this.
+StateOption FQTermDecode::VT100StateMachine::title_state_[] = {
+ {
+ '0', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '1', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '2', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '4', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '5', &FQTermDecode::paramDigit, title_state_
+ }, {
+ '6', &FQTermDecode::paramDigit, title_state_
+ }, {
+ ';', &FQTermDecode::clearText, title_text_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+StateOption FQTermDecode::VT100StateMachine::title_text_state_[] = {
+ {
+ CHAR_ESC, 0, esc_state_
+ }, {
+ CHAR_BELL, &FQTermDecode::setTitle, normal_state_
+ }, {
+ CHAR_NORMAL, &FQTermDecode::collectText, title_state_
+ }
+};
+
+const char *FQTermDecode::getStateName(const StateOption *state) {
+ if (state == VT100StateMachine::normal_state_) {
+ return "VT100StateMachine::normal_state_";
+ } else if (state == VT100StateMachine::esc_state_) {
+ return "VT100StateMachine::esc_state_";
+ } else if (state == VT100StateMachine::bracket_state_) {
+ return "VT100StateMachine::bracket_state_";
+ } else if (state == VT100StateMachine::private_state_) {
+ return "VT100StateMachine::private_state_";
+ } else if (state == VT100StateMachine::title_state_) {
+ return "VT100StateMachine::title_state_";
+ } else {
+ return "Unknow";
+ }
+}
+
+
+FQTermDecode::FQTermDecode(FQTermBuffer *buffer, int server_encoding) {
+ leftToDecode_.clear();
+ termBuffer_ = buffer;
+
+ interrupt_decode_ = false;
+
+ current_state_ = VT100StateMachine::normal_state_;
+
+ default_color_ = NO_COLOR;
+ default_attr_ = NO_ATTR;
+
+ current_color_ = default_color_;
+ current_attr_ = default_attr_;
+
+ isBell_ = false;
+
+ termBuffer_->setCurrentAttr(current_color_, current_attr_);
+
+ // TODO_UTF16: please create a encoding enum.
+ server_encoding_ = server_encoding;
+
+ currentMode_[MODE_MouseX11] = savedMode_[MODE_MouseX11] = false;
+ FQ_VERIFY(connect(termBuffer_, SIGNAL(caretChangeRow()), this, SLOT(onCaretChangeRow())));
+}
+
+FQTermDecode::~FQTermDecode() {
+
+}
+
+// precess input string from telnet socket
+//void FQTermDecode::ansiDecode( const QCString &cstr, int length )
+int FQTermDecode::decode(const char *cstr, int length) {
+ inputData_ = cstr;
+ inputLength_ = length; //inputData.length();
+
+ dataIndex_ = 0;
+ isBell_ = false;
+
+ interrupt_decode_ = false;
+
+ int i;
+ StateOption *lastState;
+
+ termBuffer_->startDecode();
+
+ // here we use FSM to ANSI decoding
+ // use switch case is ok too
+ // but i think use function pointer array can make this clear
+ // you can see the defination at the beginning
+ while (dataIndex_ < inputLength_) {
+ // current state always be initialized to point to the deginning of three structures
+ // ( normalState, escState, bracketState )
+ i = 0;
+ while (current_state_[i].byte != CHAR_NORMAL && current_state_[i].byte !=
+ inputData_[dataIndex_]) {
+ i++;
+ }
+
+ // action must be allowed to redirect state change
+ // get current state with input character i ( hehe, current now become last one )
+ lastState = current_state_ + i; // good !!
+
+ bool trace_state = true;
+ if (current_state_ == VT100StateMachine::normal_state_
+ && lastState->nextState == VT100StateMachine::normal_state_) {
+ trace_state = false;
+ }
+
+ if (trace_state) {
+ FQ_TRACE("ansi", 10) << "Current state: " << getStateName(current_state_);
+ FQ_TRACE("ansi", 10) << dumpHexString << std::string("") + inputData_[dataIndex_]
+ << dumpNormalString << " " << inputData_[dataIndex_];
+ }
+
+ if (lastState->action != 0) {
+ (this->*(lastState->action))();
+ } else {
+ if (trace_state) FQ_TRACE("ansi", 10) << "No action";
+ }
+ if (trace_state) FQ_TRACE("ansi", 10) << "Next state: " << getStateName(lastState->nextState);
+
+ // reinit current state
+ current_state_ = lastState->nextState;
+
+ dataIndex_++;
+
+ if (interrupt_decode_) {
+ break;
+ }
+ }
+ termBuffer_->endDecode();
+
+ return dataIndex_;
+}
+
+
+QString FQTermDecode::bbs2unicode(const QByteArray &text) {
+ return encoding2unicode(text, server_encoding_);
+}
+
+///////////////////////////////////
+//helper function to decode utf8//
+//////////////////////////////////
+static int utf8_expected_byte_count(char first_byte)
+{
+ char expected = 0;
+ if (!(first_byte & 0x80))
+ return 0; //1 byte ascii
+ else
+ expected++;
+ if (!(first_byte & 0x40))
+ {
+ return -1; //not a leading byte.
+ }
+ if (!(first_byte & 0x20))
+ return expected;
+ else
+ expected++;
+ if (!(first_byte & 0x10))
+ return expected;
+ else
+ expected++;
+ if (!(first_byte & 0x08))
+ return expected;
+ return -1;
+}
+
+///////////////////////////////////
+//helper function to decode utf8//
+//////////////////////////////////
+static int gdbnbig5_expected_byte_count(char first_byte)
+{
+ char expected = 0;
+ if (!(first_byte & 0x80))
+ return 0; //1 byte ascii
+ else
+ expected++;
+ return expected;
+}
+
+int FQTermDecode::processInput(QByteArray& result)
+{
+ int charstate = FQTermTextLine::NORMAL;
+ int expect_bytes = 0;
+ if (leftToDecode_.size())
+ {
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ expect_bytes = gdbnbig5_expected_byte_count(leftToDecode_[0]);
+ break;
+ case FQTERM_ENCODING_UTF8:
+ expect_bytes = utf8_expected_byte_count(leftToDecode_[0]);
+ break;
+ }
+ }
+
+ //TODO: error.
+ if (expect_bytes < 0) {
+ expect_bytes = 0;
+ }
+
+
+ int n = 0;
+ int last_char_index = n;
+ while (((dataIndex_ + n) < inputLength_) && (signed(inputData_[dataIndex_ + n]) >= 0x20
+ || signed(inputData_[dataIndex_ + n]) < 0x00)) {
+
+ if (expect_bytes != 0) {
+ expect_bytes--;
+ } else {
+ last_char_index = n;
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ expect_bytes = gdbnbig5_expected_byte_count(inputData_[dataIndex_ + n]);
+ break;
+ case FQTERM_ENCODING_UTF8:
+ expect_bytes = utf8_expected_byte_count(inputData_[dataIndex_ + n]);
+ break;
+ }
+ //TODO: error.
+ if (expect_bytes < 0) {
+ expect_bytes = 0;
+ }
+
+
+ }
+
+ n++;
+ }
+
+ if (expect_bytes) {
+ if(dataIndex_ + n == inputLength_) {
+ interrupt_decode_ = true;
+ }
+ }
+
+ result.clear();
+ result.reserve(n + 1);
+ if (leftToDecode_.size()) {
+ result += leftToDecode_;
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ charstate |= FQTermTextLine::SECONDPART;
+ break;
+ case FQTERM_ENCODING_UTF8:
+ break;
+ }
+ leftToDecode_.clear();
+ }
+ int real_n = n;
+ if (expect_bytes) {
+ real_n = last_char_index;
+ leftToDecode_ = QByteArray(inputData_ + dataIndex_ + last_char_index, n - last_char_index);
+ }
+
+ result.push_back(QByteArray(inputData_ + dataIndex_, real_n));
+ if (expect_bytes) {
+ switch(server_encoding_)
+ {
+ case FQTERM_ENCODING_GBK:
+ case FQTERM_ENCODING_BIG5:
+ case FQTERM_ENCODING_HKSCS:
+ case FQTERM_ENCODING_UAO:
+ result.push_back('?'); //make sure the attr is recorded,
+ //since last -1 operation can make cstr to be empty
+ charstate |= FQTermTextLine::FIRSTPART;
+ break;
+ case FQTERM_ENCODING_UTF8:
+ break;
+ }
+ }
+
+ n--;
+ dataIndex_ += n;
+
+ return charstate;
+}
+
+
+// fill letters into char buffer
+// TODO: this function may contain bug, need double-check.
+// 1. input should be ascii-compitable encoding.
+void FQTermDecode::normalInput() {
+
+ FQ_FUNC_TRACE("ansi", 8);
+
+ // TODO_UTF16: check ascii-incompitable encoding.
+ if (signed(inputData_[dataIndex_]) < 0x20 && signed(inputData_[dataIndex_]) >= 0x00) {
+ // not print char
+ return ;
+ }
+
+ QByteArray cstr;
+ int charstate = processInput(cstr);
+
+
+
+ QString str = bbs2unicode(cstr);
+ FQ_TRACE("normal_input", 9) << "hex: " << dumpHexString
+ << str.toLocal8Bit().constData() ;
+ FQ_TRACE("normal_input", 9) << "text: " << str;
+ termBuffer_->writeText(str, charstate);
+
+}
+
+// non-printing characters functions
+void FQTermDecode::cr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ // FIXME: dirty
+ termBuffer_->carriageReturn();
+}
+
+void FQTermDecode::lf() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->lineFeed();
+}
+
+void FQTermDecode::ff() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->eraseEntireTerm();
+
+ termBuffer_->moveCaretTo(0, 0);
+}
+
+void FQTermDecode::tab() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->tab();
+}
+
+void FQTermDecode::bs() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->moveCaretOffset(-1, 0);
+}
+
+void FQTermDecode::bell() {
+ FQ_FUNC_TRACE("ansi", 8);
+ isBell_ = true;
+}
+
+void FQTermDecode::del() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->moveCaretOffset(-1, 0);
+ //termBuffer_->deleteText(1);
+}
+
+void FQTermDecode::g0() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->invokeCharset(true);
+}
+
+void FQTermDecode::g1() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->invokeCharset(false);
+}
+
+void FQTermDecode::enq() {
+ emit enqReceived();
+}
+
+void FQTermDecode::addTabStop() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->addTabStop();
+}
+
+void FQTermDecode::clearTabStop() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ if (param_[0] == 0) {
+ termBuffer_->clearTabStop(false);
+ } else if (param_[0] == 3) {
+ termBuffer_->clearTabStop(true);
+ }
+}
+
+void FQTermDecode::setMargins() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ if (isParamAvailable_) {
+ termBuffer_->setMargins(param_[0] - 1, param_[1] - 1);
+ } else {
+ termBuffer_->setMargins(0, termBuffer_->getNumRows() - 1);
+ }
+}
+
+// parameters functions
+void FQTermDecode::clearParam() {
+ FQ_FUNC_TRACE("ansi", 9);
+ paramIndex_ = 0;
+ memset(param_, 0, sizeof(param_));
+ isParamAvailable_ = false;
+}
+
+// for performance, this grabs all digits
+void FQTermDecode::paramDigit() {
+ FQ_FUNC_TRACE("ansi", 10);
+ isParamAvailable_ = true;
+
+ // make stream into number
+ // ( e.g. this input character is '1' and this param is 4
+ // after the following sentence this param is changed to 41
+ param_[paramIndex_] = param_[paramIndex_] *10+inputData_[dataIndex_] - '0';
+}
+
+void FQTermDecode::nextParam() {
+ FQ_FUNC_TRACE("ansi", 9);
+ paramIndex_++;
+}
+
+void FQTermDecode::saveCursor() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->saveCaret();
+}
+
+void FQTermDecode::restoreCursor() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->restoreCaret();
+}
+
+void FQTermDecode::cursorPosition() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int x = param_[1];
+ int y = param_[0];
+
+ if (x == 0) {
+ x = 1;
+ }
+ if (y == 0) {
+ y = 1;
+ }
+
+ termBuffer_->changeCaretPosition(x - 1, y - 1);
+}
+
+void FQTermDecode::cursorLeft() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(-n, 0);
+}
+
+void FQTermDecode::cursorRight() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(n, 0);
+}
+
+void FQTermDecode::cursorUp() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(0, -n);
+}
+
+void FQTermDecode::cursorDown() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->moveCaretOffset(0, n);
+}
+
+void FQTermDecode::moveCursorUp() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->scrollTerm(-1);//moveCaretOffset(0, -1, true);
+}
+
+void FQTermDecode::moveCursorDown() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->scrollTerm(1);//moveCaretOffset(0, 1, true);
+}
+
+void FQTermDecode::nextLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->carriageReturn();
+ termBuffer_->moveCaretOffset(0, 1, true);
+}
+
+void FQTermDecode::selectG0A() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::UNITED_KINGDOM_SET, true);
+}
+
+void FQTermDecode::selectG0B() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::ASCII_SET, true);
+}
+
+void FQTermDecode::selectG00() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::SPECIAL_GRAPHICS, true);
+}
+
+void FQTermDecode::selectG01() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_STANDARD_CHARACTER_SET, true);
+}
+
+void FQTermDecode::selectG02() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_SPECIAL_GRAPHICS, true);
+}
+
+void FQTermDecode::selectG1A() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::UNITED_KINGDOM_SET, false);
+}
+
+void FQTermDecode::selectG1B() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::ASCII_SET, false);
+}
+
+void FQTermDecode::selectG10() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(FQTermBuffer::SPECIAL_GRAPHICS, false);
+}
+
+void FQTermDecode::selectG11() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_STANDARD_CHARACTER_SET, false);
+}
+
+void FQTermDecode::selectG12() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->SelectVtCharacterSet(
+ FQTermBuffer::ALTERNATE_CHARACTER_ROM_SPECIAL_GRAPHICS, false);
+}
+
+// erase functions
+void FQTermDecode::eraseStr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->eraseText(n);
+}
+
+// insert functions
+void FQTermDecode::insertStr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->insertSpaces(n);
+}
+
+// delete functions
+void FQTermDecode::deleteStr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->deleteText(n);
+}
+
+void FQTermDecode::eraseLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ switch (param_[0]) {
+ case 0:
+ termBuffer_->eraseToLineEnd();
+ break;
+ case 1:
+ termBuffer_->eraseToLineBegin();
+ break;
+ case 2:
+ termBuffer_->eraseEntireLine();
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermDecode::insertLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->insertLines(n);
+}
+
+void FQTermDecode::deleteLine() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ int n = param_[0];
+
+ if (n < 1) {
+ n = 1;
+ }
+
+ termBuffer_->deleteLines(n);
+}
+
+void FQTermDecode::eraseScreen() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ switch (param_[0]) {
+ case 0:
+ termBuffer_->eraseToTermEnd();
+ break;
+ case 1:
+ termBuffer_->eraseToTermBegin();
+ break;
+ case 2:
+ termBuffer_->eraseEntireTerm();
+ break;
+ case 3:
+ break;
+ }
+}
+
+void FQTermDecode::setAttr() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ // get all attributes of character
+ if (!paramIndex_ && param_[0] == 0) {
+ current_color_ = default_color_;
+ current_attr_ = default_attr_;
+
+ termBuffer_->setCurrentAttr(current_color_, current_attr_);
+ return ;
+ }
+
+ unsigned char cp = current_color_;
+ unsigned char ea = current_attr_;
+ for (int n = 0; n <= paramIndex_; n++) {
+ if (param_[n] / 10 == 4) {
+ // background color
+ cp = cp &~BGMASK;
+ cp += SETBG(param_[n] % 10);
+ } else if (param_[n] / 10 == 3) {
+ // front color
+ cp = cp &~FGMASK;
+ cp += SETFG(param_[n] % 10);
+ } else {
+ switch (param_[n]) {
+ case 0:
+ // attr off
+ cp = default_color_; //NO_COLOR;
+ ea = default_attr_; //NO_ATTR;
+ break;
+ case 1:
+ // bright
+ ea = SETBRIGHT(ea);
+ break;
+ case 2:
+ // dim
+ ea = SETDIM(ea);
+ break;
+ case 4:
+ // underline
+ ea = SETUNDERLINE(ea);
+ break;
+ case 5:
+ // blink
+ ea = SETBLINK(ea);
+ break;
+ case 7:
+ // reverse
+ ea = SETREVERSE(ea);
+ break;
+ case 8:
+ // invisible
+ ea = SETINVISIBLE(ea);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ current_color_ = cp;
+ current_attr_ = ea;
+
+ termBuffer_->setCurrentAttr(current_color_, current_attr_);
+}
+
+void FQTermDecode::setMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 4:
+ termBuffer_->setMode(FQTermBuffer::INSERT_MODE);
+ break;
+ case 20:
+ termBuffer_->setMode(FQTermBuffer::NEWLINE_MODE);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::resetMode() {
+ //TODO: more modes here.
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 4:
+ termBuffer_->resetMode(FQTermBuffer::INSERT_MODE);
+ break;
+ case 20:
+ termBuffer_->resetMode(FQTermBuffer::NEWLINE_MODE);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::setDecPrivateMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1:
+ termBuffer_->setMode(FQTermBuffer::CURSOR_MODE);
+ break;
+ case 2:
+ termBuffer_->setMode(FQTermBuffer::ANSI_MODE);
+ break;
+ case 3:
+ termBuffer_->setTermSize(132, 24);
+ break;
+ case 4:
+ // smooth scrolling mode
+ // nothing to do.
+ break;
+ case 5:
+ termBuffer_->setMode(FQTermBuffer::LIGHTBG_MODE);
+ break;
+ case 6:
+ termBuffer_->setMode(FQTermBuffer::ORIGIN_MODE);
+ break;
+ case 7:
+ termBuffer_->setMode(FQTermBuffer::AUTOWRAP_MODE);
+ break;
+ case 8:
+ termBuffer_->setMode(FQTermBuffer::AUTOREPEAT_MODE);
+ break;
+ case 9:
+ // Interlace mode
+ // nothing to do.
+ break;
+ case 1000:
+ case 1001:
+ emit mouseMode(true);
+ currentMode_[MODE_MouseX11] = true;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::resetDecPrivateMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1:
+ termBuffer_->resetMode(FQTermBuffer::CURSOR_MODE);
+ break;
+ case 2:
+ termBuffer_->resetMode(FQTermBuffer::ANSI_MODE);
+ break;
+ case 3:
+ termBuffer_->setTermSize(80, 24);
+ break;
+ case 4:
+ // jump scrolling mode
+ // nothing to do.
+ break;
+ case 5:
+ termBuffer_->resetMode(FQTermBuffer::LIGHTBG_MODE);
+ break;
+ case 6:
+ termBuffer_->resetMode(FQTermBuffer::ORIGIN_MODE);
+ break;
+ case 7:
+ termBuffer_->resetMode(FQTermBuffer::AUTOWRAP_MODE);
+ break;
+ case 8:
+ termBuffer_->resetMode(FQTermBuffer::AUTOREPEAT_MODE);
+ break;
+ case 9:
+ // Interlace mode
+ // nothing to do.
+ break;
+ case 1000:
+ case 1001:
+ currentMode_[MODE_MouseX11] = false;
+ emit mouseMode(false);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::setNumericKeypad() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->setMode(FQTermBuffer::NUMERIC_MODE);
+}
+
+void FQTermDecode::setAppKeypad() {
+ FQ_FUNC_TRACE("ansi", 8);
+ termBuffer_->resetMode(FQTermBuffer::NUMERIC_MODE);
+}
+
+void FQTermDecode::saveMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1000:
+ case 1001:
+ savedMode_[MODE_MouseX11] = currentMode_[MODE_MouseX11];
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::restoreMode() {
+ FQ_FUNC_TRACE("ansi", 8);
+ logParam();
+
+ for (int i = 0; i <= paramIndex_; i++) {
+ int n = param_[i];
+ switch (n) {
+ case 1000:
+ case 1001:
+ currentMode_[MODE_MouseX11] = savedMode_[MODE_MouseX11];
+ emit mouseMode(currentMode_[MODE_MouseX11]);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FQTermDecode::fillScreen() {
+ FQ_FUNC_TRACE("ansi", 8);
+
+ termBuffer_->fillScreenWith('E');
+}
+
+void FQTermDecode::test() {
+ FQ_FUNC_TRACE("ansi", 8);
+}
+
+void FQTermDecode::logParam() const {
+ if (isParamAvailable_) {
+ for (int i = 8; i <= paramIndex_; ++i) {
+ FQ_TRACE("ansi", 8) << "Parameter[" << i << "] = " << param_[i];
+ }
+ } else {
+ FQ_TRACE("ansi", 8) << "No parameter.";
+ }
+}
+
+void FQTermDecode::onCaretChangeRow() {
+ leftToDecode_.clear();
+}
+
+void FQTermDecode::setTitle() {
+ if (!isParamAvailable_) {
+ return;
+ }
+ switch(param_[0])
+ {
+ case 0:
+ //icon and text
+ break;
+ case 1:
+ //icon
+ break;
+ case 2:
+ //text
+ emit onTitleSet(bbs2unicode(textParam_));
+ break;
+ case 46:
+ //log file
+ break;
+ case 50:
+ //font
+ break;
+ default:
+ break;
+ }
+}
+
+void FQTermDecode::collectText() {
+ FQ_FUNC_TRACE("ansi", 10);
+ if (textParam_.length() < 4096)
+ textParam_ += inputData_[dataIndex_];
+}
+
+void FQTermDecode::clearText() {
+ FQ_FUNC_TRACE("ansi", 10);
+ textParam_.clear();
+}
+
+
+
+
+} // namespace FQTerm
+
+#include "fqterm_decode.moc"
diff --git a/src/terminal/internal/fqterm_decode.h b/src/terminal/internal/fqterm_decode.h
new file mode 100644
index 0000000..5f3f46d
--- /dev/null
+++ b/src/terminal/internal/fqterm_decode.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_DECODE_H
+#define FQTERM_DECODE_H
+
+#include <QObject>
+#include "fqterm_text_line.h"
+
+namespace FQTerm {
+
+class FQTermDecode;
+class FQTermBuffer;
+class FQTermTelnet;
+
+// this for FSM
+typedef void(FQTermDecode:: *StateFunc)();
+
+struct StateOption {
+ int byte; // char value to look for; -1==end/default
+ StateFunc action;
+ StateOption *nextState;
+};
+
+class FQTermDecode: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermDecode(FQTermBuffer *, int server_encoding);
+ ~FQTermDecode();
+
+
+ // translate data from telnet socket to our own buffer
+ // return how many bytes are processed.
+ int decode(const char *cstr, int length);
+
+ bool bellReceive() {
+ return isBell_;
+ }
+
+ void setServerEncoding(int encoding) {
+ server_encoding_ = encoding;
+ }
+
+
+ //signals:
+ // void decodeFinished();
+ signals:
+ void mouseMode(bool);
+ void enqReceived();
+ void onTitleSet(const QString&);
+ public slots:
+ void onCaretChangeRow();
+ private:
+ // escape sequence actions
+ // you'd better see FSM structure array in FQTermDecode.cpp
+
+ void setAttr();
+ void setMargins();
+
+ // char screen functions
+ void deleteStr();
+ void deleteLine();
+ void insertStr();
+ void insertLine();
+ void eraseStr();
+ void eraseLine();
+ void eraseScreen();
+
+ // cursor functions
+ void saveCursor();
+ void restoreCursor();
+ void cursorPosition();
+
+ // Move cursor, stop at boundary.
+ void cursorLeft();
+ void cursorDown();
+ void cursorRight();
+ void cursorUp();
+
+ // Move cursor, scroll at boundary.
+ void moveCursorUp();
+ void moveCursorDown();
+ void nextLine();
+
+ void selectG0A();
+ void selectG0B();
+ void selectG00();
+ void selectG01();
+ void selectG02();
+
+ void selectG1A();
+ void selectG1B();
+ void selectG10();
+ void selectG11();
+ void selectG12();
+
+ // other escape sequence actions
+ void normalInput();
+
+ //title settings
+ void setTitle();
+ void collectText();
+ void clearText();
+
+ // action parameters
+ void clearParam();
+ void paramDigit();
+ void nextParam();
+
+ // non-printing characters
+ void cr(), lf(), ff(), bell(), tab(), bs(), del(), g0(), g1(), enq();
+
+ void addTabStop();
+ void clearTabStop();
+
+ void setMode();
+ void resetMode();
+ void setDecPrivateMode();
+ void resetDecPrivateMode();
+ void setNumericKeypad();
+ void setAppKeypad();
+
+ void saveMode();
+ void restoreMode();
+
+ // video alignment test - fill screen with E's.
+ void fillScreen();
+
+ void test();
+
+ private:
+
+ bool isBell_;
+ // short currentAttr_, defaultAttr_;
+ unsigned char current_color_, default_color_;
+ unsigned char current_attr_, default_attr_;
+
+ // ********** ansi decoder states ****************
+ StateOption *current_state_;
+
+ struct VT100StateMachine {
+ static StateOption normal_state_[], esc_state_[], bracket_state_[];
+ static StateOption private_state_[], sharp_state_[];
+ static StateOption title_state_[], title_text_state_[];
+ static StateOption select_g0_charset_state_[], select_g1_charset_state_[];
+ };
+
+ static const char *getStateName(const StateOption *state);
+
+ void logParam() const;
+
+
+ bool interrupt_decode_;
+
+ // ********** decoder *****************
+ const char *inputData_;
+ int inputLength_, dataIndex_;
+
+ int paramIndex_, param_[30];
+ bool isParamAvailable_;
+
+ QByteArray textParam_;
+
+ bool savedMode_[30];
+ bool currentMode_[30];
+
+ FQTermBuffer *termBuffer_;
+ int server_encoding_;
+
+ QString bbs2unicode(const QByteArray &text);
+ int processInput(QByteArray& result);
+ QByteArray leftToDecode_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_DECODE_H
diff --git a/src/terminal/internal/fqterm_telnet.cpp b/src/terminal/internal/fqterm_telnet.cpp
new file mode 100644
index 0000000..2446b8a
--- /dev/null
+++ b/src/terminal/internal/fqterm_telnet.cpp
@@ -0,0 +1,1041 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <QAbstractSocket>
+
+#include "fqterm.h"
+#include "fqterm_telnet.h"
+#include "fqterm_socket.h"
+
+#ifndef _NO_SSH_COMPILED
+#include "fqterm_ssh_socket.h"
+#endif
+
+/* TELNET Command Codes: */
+/* Hints: These NVT control characters are sent from client to server, So
+ the client side will not receive these commands */
+#define TCSB (u_char)250 /* Start Subnegotiation */
+#define TCSE (u_char)240 /* End Of Subnegotiation */
+#define TCNOP (u_char)241 /* No Operation */
+#define TCDM (u_char)242 /* Data Mark (for Sync) */
+#define TCBRK (u_char)243 /* NVT Character BRK */
+#define TCIP (u_char)244 /* Interrupt Process */
+#define TCAO (u_char)245 /* Abort Output */
+#define TCAYT (u_char)246 /* "Are You There?" Function */
+#define TCEC (u_char)247 /* Erase Character */
+#define TCEL (u_char)248 /* Erase Line */
+#define TCGA (u_char)249 /* "Go Ahead" Function */
+#define TCWILL (u_char)251 /* Desire/Confirm Will Do Option*/
+#define TCWONT (u_char)252 /* Refusal To Do Option */
+#define TCDO (u_char)253 /* Request To Do Option */
+#define TCDONT (u_char)254 /* Request NOT To Do Option */
+#define TCIAC (u_char)255 /* Interpret As Command Escape */
+
+/* Telnet Option Codes: */
+#define TOTXBINARY (u_char) 0 /* TRANSMIT-BINARY option */
+#define TOECHO (u_char) 1 /* ECHO Option */
+#define TONOGA (u_char) 3 /* Suppress Go-Ahead Option */
+#define TOTERMTYPE (u_char) 24 /* Terminal-Type Option */
+#define TONAWS (u_char) 31 /* Window Size */
+
+/* Network Virtual Printer Special Characters: */
+/* In normal situations, these characters will to translated into local
+ control characters , then pass to upper layer term. But in our situation,
+ we can pass them to term directly */
+
+#define VPLF '\n' /* Line Feed */
+#define VPCR '\r' /* Carriage Return */
+#define VPBEL '\a' /* Bell (attention signal) */
+#define VPBS '\b' /* Back Space */
+#define VPHT '\t' /* Horizontal Tab */
+#define VPVT '\v' /* Vertical Tab */
+#define VPFF '\f' /* Form Feed */
+
+/* Keyboard Command Characters: */
+
+/* Option Subnegotiation Constants: */
+#define TT_IS 0 /* TERMINAL_TYPE option "IS" command */
+#define TT_SEND 1 /* TERMINAL_TYPE option "SEND" command */
+
+/* Telnet Socket-Input FSM States: */
+#define TSDATA 0 /* normal data processing */
+#define TSIAC 1 /* have seen IAC */
+#define TSWOPT 2 /* have seen IAC-{WILL/WONT} */
+#define TSDOPT 3 /* have seen IAC-{DO/DONT} */
+#define TSSUBNEG 4 /* have seen IAC-SB */
+#define TSSUBIAC 5 /* have seen IAC-SB-...-IAC */
+// if any state added here, please update NTSTATES (currently 6).
+
+// Telnet Option Subnegotiation FSM States:
+#define SS_START 0 // initial state
+#define SS_TERMTYPE 1 // TERMINAL_TYPE option subnegotiation
+#define SS_END 2 // state after all legal input
+// if any state added here, please update NSSTATES (currently 3).
+
+#define FSINVALID 0xff // an invalid state number
+#define TCANY (NCHRS+1) // match any character
+
+#define TINVALID 0xff // an invalid transition index
+
+namespace FQTerm {
+
+struct fsm_trans FQTermTelnet::ttstab[] = {
+ /* State Input Next State Action */
+ /* ------ ------ ----------- ------- */
+ {
+ TSDATA, TCIAC, TSIAC, &FQTermTelnet::no_op
+ }, {
+ TSDATA, TCANY, TSDATA, &FQTermTelnet::ttputc
+ }, {
+ TSIAC, TCIAC, TSDATA, &FQTermTelnet::ttputc
+ }, {
+ TSIAC, TCSB, TSSUBNEG, &FQTermTelnet::no_op
+ }, {/* Telnet Commands */
+ TSIAC, TCNOP, TSDATA, &FQTermTelnet::no_op
+ }, {
+ TSIAC, TCDM, TSDATA, &FQTermTelnet::tcdm
+ }, { /* Option Negotiation */
+ TSIAC, TCWILL, TSWOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCWONT, TSWOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCDO, TSDOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCDONT, TSDOPT, &FQTermTelnet::recopt
+ }, {
+ TSIAC, TCANY, TSDATA, &FQTermTelnet::no_op
+ }, { /* Option Subnegotion */
+ TSSUBNEG, TCIAC, TSSUBIAC, &FQTermTelnet::no_op
+ }, {
+ TSSUBNEG, TCANY, TSSUBNEG, &FQTermTelnet::subopt
+ }, {
+ TSSUBIAC, TCSE, TSDATA, &FQTermTelnet::subend
+ }, {
+ TSSUBIAC, TCANY, TSSUBNEG, &FQTermTelnet::subopt
+ }, {
+ TSWOPT, TOECHO, TSDATA, &FQTermTelnet::do_echo
+ }, {
+ TSWOPT, TONOGA, TSDATA, &FQTermTelnet::do_noga
+ }, {
+ TSWOPT, TOTXBINARY, TSDATA, &FQTermTelnet::do_txbinary
+ }, {
+ TSWOPT, TCANY, TSDATA, &FQTermTelnet::do_notsup
+ },{
+ TSDOPT, TONAWS, TSDATA, &FQTermTelnet::will_naws
+ }, {
+ TSDOPT, TOTERMTYPE, TSDATA, &FQTermTelnet::will_termtype
+ }, {
+ TSDOPT, TOTXBINARY, TSDATA, &FQTermTelnet::will_txbinary
+ }, {
+ TSDOPT, TCANY, TSDATA, &FQTermTelnet::will_notsup
+ }, {
+ FSINVALID, TCANY, FSINVALID, &FQTermTelnet::tnabort
+ },
+};
+
+
+struct fsm_trans FQTermTelnet::substab[] = {
+ /* State Input Next State Action */
+ /* ---------------------------------------------------- */
+ {
+ SS_START, TOTERMTYPE, SS_TERMTYPE, &FQTermTelnet::no_op
+ }, {
+ SS_START, TCANY, SS_END, &FQTermTelnet::no_op
+ }, {
+ SS_TERMTYPE, TT_SEND, SS_END, &FQTermTelnet::subtermtype
+ }, {
+ SS_TERMTYPE, TCANY, SS_END, &FQTermTelnet::no_op
+ }, {
+ SS_END, TCANY, SS_END, &FQTermTelnet::no_op
+ }, {
+ FSINVALID, TCANY, FSINVALID, &FQTermTelnet::tnabort
+ },
+};
+
+
+
+/*------------------------------------------------------------------------
+ * Constructor
+ *------------------------------------------------------------------------
+ */
+FQTermTelnet::FQTermTelnet(const QString &strTermType, int rows, int columns,
+ int protocolType, int hostType, const char *sshuser, const char *sshpasswd)
+ : from_socket(),
+ to_ansi(),
+ from_ansi(),
+ to_socket(),
+ hostType_(hostType),
+ protocolType_(protocolType) {
+ term = new char[21];
+ memset(term, 0, sizeof(term));
+ // TODO: clean up, need???
+#ifdef WIN32
+ _snprintf(term, sizeof(term), "%s", strTermType.toLatin1().constData());
+#else
+ strncpy(term,strTermType.toLatin1(),20);
+#endif
+
+ wx = columns;
+ wy = rows;
+ wsize = 0;
+ done_naws = 0;
+ synching = 0;
+ doecho = 0;
+ sndbinary = 0;
+ rcvbinary = 0;
+ noga = 0;
+ termtype = 0;
+ naws = 0;
+ server_sent_do_naws = 0;
+ raw_size = 0;
+
+#ifndef _NO_SSH_COMPILED
+ if (protocolType == 1 || protocolType == 2) {
+ socket = new FQTermSSHSocket(columns, rows, strTermType, sshuser, sshpasswd);
+ FQ_VERIFY(connect(socket, SIGNAL(sshAuthOK()),
+ this, SIGNAL(onSSHAuthOK())));
+ } else if (protocolType == 3) {
+ socket = new FQTermLocalSocket("");
+ } else {
+ socket = new FQTermTelnetSocket();
+ }
+#else
+ socket = new FQTermTelnetSocket();
+#endif
+
+ // connect signal and slots
+ FQ_VERIFY(connect(socket, SIGNAL(connected()), this, SLOT(connected())));
+ FQ_VERIFY(connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead())));
+ FQ_VERIFY(connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(showError(QAbstractSocket::SocketError))));
+ FQ_VERIFY(connect(socket, SIGNAL(hostFound()), this, SLOT(hostFound())));
+ FQ_VERIFY(connect(socket, SIGNAL(delayedCloseFinished()),
+ this, SLOT(delayCloseFinished())));
+ FQ_VERIFY(connect(socket, SIGNAL(connectionClosed()), this, SLOT(closed())));
+ FQ_VERIFY(connect(socket, SIGNAL(socketState(int)), this, SIGNAL(TelnetState(int))));
+
+ FQ_VERIFY(connect(socket, SIGNAL(requestUserPwd(QString *, QString *, bool *)),
+ this, SIGNAL(requestUserPwd(QString *, QString *, bool *))));
+
+ FQ_VERIFY(connect(socket, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString))));
+
+ // Init telnet, mainly the FSMs
+ init_telnet();
+}
+
+/*------------------------------------------------------------------------
+ * destructor
+ *------------------------------------------------------------------------
+ */
+FQTermTelnet::~FQTermTelnet() {
+ // delete objects
+ delete [] term;
+ delete socket;
+}
+
+
+
+/*------------------------------------------------------------------------
+ * init_telnet
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::init_telnet() {
+ fsmbuild(); /* setup FSMs */
+}
+
+
+/*------------------------------------------------------------------------
+ * fsmbuild - build the Finite State Machine data structures
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::fsmbuild() {
+ fsminit(ttfsm, ttstab, NTSTATES);
+ ttstate = TSDATA;
+
+ fsminit(subfsm, substab, NSSTATES);
+ substate = SS_START;
+
+}
+
+/*------------------------------------------------------------------------
+ * fsminit - Finite State Machine initializer
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::fsminit(u_char fsm[][NCHRS], struct fsm_trans ttab[], int
+ nstates) {
+ struct fsm_trans *pt;
+ int sn, ti, cn;
+
+ for (cn = 0; cn < NCHRS; ++cn) {
+ for (ti = 0; ti < nstates; ++ti) {
+ fsm[ti][cn] = TINVALID;
+ }
+ }
+
+ for (ti = 0; ttab[ti].ft_state != FSINVALID; ++ti) {
+ pt = &ttab[ti];
+ sn = pt->ft_state;
+ if (pt->ft_char == TCANY) {
+ for (cn = 0; cn < NCHRS; ++cn) {
+ if (fsm[sn][cn] == TINVALID) {
+ fsm[sn][cn] = ti;
+ }
+ }
+ } else {
+ fsm[sn][pt->ft_char] = ti;
+ }
+ }
+
+ /* set all uninitialized indices to an invalid transition */
+ for (cn = 0; cn < NCHRS; ++cn) {
+ for (ti = 0; ti < nstates; ++ti) {
+ if (fsm[ti][cn] == TINVALID) {
+ fsm[ti][cn] = ti;
+ }
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------
+ * connect to host
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::connectHost(const QString &hostname, quint16 portnumber) {
+ done_naws = 0;
+ synching = 0;
+ doecho = 0;
+ sndbinary = 0;
+ rcvbinary = 0;
+ noga = 0;
+ termtype = 0;
+ naws = 0;
+
+ socket->connectToHost(hostname, portnumber);
+ // host name resolving
+ emit TelnetState(TSRESOLVING);
+}
+
+void FQTermTelnet::windowSizeChanged(int x, int y) {
+ wx = x;
+ wy = y;
+ if (bConnected) {
+ if (hostType_ == 1 && (protocolType_ == 1 || protocolType_ == 2)) {
+ //This is a *nix host, with ssh connection.
+ socket->setTermSize(x, y);
+ return;
+ }
+ naws = 0;
+
+ QByteArray cmd(10, 0);
+ cmd[0] = (char)TCIAC;
+ cmd[1] = (char)TCSB;
+ cmd[2] = (char)TONAWS;
+ cmd[3] = (char)(short(wx) >> 8);
+ cmd[4] = (char)(short(wx) & 0xff);
+ cmd[5] = (char)(short(wy) >> 8);
+ cmd[6] = (char)(short(wy) & 0xff);
+ cmd[7] = (char)TCIAC;
+ cmd[8] = (char)TCSE;
+ socket->writeBlock(cmd);
+
+ }
+}
+
+/*------------------------------------------------------------------------
+ * set proxy
+ *-----------------------------------------------------------------------
+ */
+void FQTermTelnet::setProxy(int nProxyType, bool bAuth, const QString
+ &strProxyHost, quint16 uProxyPort,
+ const QString &strProxyUsr,
+ const QString &strProxyPwd) {
+ socket->setProxy(nProxyType, bAuth, strProxyHost,
+ uProxyPort, strProxyUsr, strProxyPwd);
+}
+
+/*------------------------------------------------------------------------
+ * close connection
+ *-----------------------------------------------------------------------
+ */
+
+void FQTermTelnet::close() {
+ socket->close();
+}
+
+/*------------------------------------------------------------------------
+ * SLOT connected
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::connected() {
+ bConnected = true;
+ emit TelnetState(TSHOSTCONNECTED);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT closed
+ *------------------------------------------------------------------------
+ */
+
+void FQTermTelnet::closed() {
+ bConnected = false;
+ emit TelnetState(TSCLOSED);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT delayCloseFinished
+ *------------------------------------------------------------------------
+ */
+
+void FQTermTelnet::delayCloseFinished() {
+ bConnected = false;
+ emit TelnetState(TSCLOSEFINISH);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT hostFound
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::hostFound() {
+ emit TelnetState(TSHOSTFOUND);
+}
+
+/*------------------------------------------------------------------------
+ * SLOT error
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::showError(QAbstractSocket::SocketError index) {
+
+ switch (index) {
+ case QAbstractSocket::ConnectionRefusedError: emit TelnetState(TSREFUSED);
+ break;
+ case QAbstractSocket::HostNotFoundError: emit TelnetState(TSHOSTNOTFOUND);
+ break;
+ //FIXME: am I right
+ case QAbstractSocket::SocketAccessError: emit TelnetState(TSREADERROR);
+ break;
+ case QAbstractSocket::RemoteHostClosedError: emit TelnetState(TSCLOSED);
+ break;
+ default:
+ emit TelnetState(TSERROR);
+ ;
+ break;
+ }
+
+}
+
+/*------------------------------------------------------------------------
+ * SLOOT socketReadyRead -
+ * when socket has data to upload, it send out readyRead() signal, it
+ * invokes this SLOT to read data in, do telnet decode job, and send out
+ * readyRead() SIGNAL to upper layer
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::socketReadyRead() {
+ int nbytes, nread;
+ // TODO_UTF16: check this function.
+
+ // get the data size
+ nbytes = socket->bytesAvailable();
+ if (nbytes <= 0) {
+ return ;
+ }
+
+ raw_size = nbytes;
+
+ //resize input buffer
+ from_socket.resize(0);
+
+ //read data from socket to from_socket
+ from_socket = socket->readBlock(nbytes);
+ nread = from_socket.size();
+ //do some checks
+ if (nread <= 0) {
+ FQ_TRACE("telnet", 8) << "Failed to read socket: " << nread << " <= 0.";
+ return ;
+ }
+ if (nread > nbytes) {
+ FQ_TRACE("telnet", 0) << "Overflow when reading socket: "
+ << " nread = " << nread
+ << " > nbytes = " << nbytes;
+ return ;
+ }
+
+ //resize output buffer
+ to_ansi.resize(2 *nread);
+ to_socket.resize(4 *nread);
+
+ rsize = 0;
+ wsize = 0;
+
+ // do telnet decode job...
+ struct fsm_trans *pt;
+ int i, ti;
+
+ u_char c;
+ for (i = 0; i < nread; ++i) {
+ c = (u_char)(from_socket[i]);
+ ti = ttfsm[ttstate][c];
+ pt = &ttstab[ti];
+ (this->*(pt->ft_action))((int)c);
+ ttstate = pt->ft_next;
+ }
+
+ // flush the to_socket buffer, it contain response to server
+ if (wsize > 0) {
+ socket->writeBlock(to_socket.left(wsize));
+ socket->flush();
+ }
+
+ /* send SIGNAL readyRead() with the size of data available*/
+ if (rsize > 0 || raw_size > 0) {
+ emit readyRead(rsize, raw_size);
+ }
+
+}
+
+int FQTermTelnet::raw_len() {
+ return raw_size;
+}
+
+/*------------------------------------------------------------------------
+ * actions
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::read_raw(char *data, uint maxlen) {
+ //do some checks
+ if (data == 0) {
+ FQ_TRACE("telnet", 0) << "NULL pointer.";
+ return -1;
+ }
+ if ((long)maxlen < raw_size) {
+ /* we need all data be read out in one read */
+ FQ_TRACE("telnet", 0) << "The upper layer's buffer is too small.";
+ return -1;
+ }
+
+ //do it, memcpy( destination, source, size)
+ memcpy(data, from_socket.data(), raw_size);
+ return raw_size;
+}
+
+
+/*------------------------------------------------------------------------
+ * actions
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::read(char *data, uint maxlen) {
+ //do some checks
+ if (data == 0) {
+ FQ_TRACE("telent", 0) << "NULL pointer.";
+ return -1;
+ }
+ if (maxlen < rsize) {
+ /* we need all data be read out in one read */
+ FQ_TRACE("telnet", 0) << "The upper layer's buffer is too small.";
+ return -1;
+ }
+
+ //do it, memcpy( destination, source, size)
+ memcpy(data, to_ansi.data(), rsize);
+
+ FQ_TRACE("telnet", 8) << "read " << rsize << " bytes:\n"
+ << dumpHexString << std::string(data, rsize);
+
+ return rsize;
+}
+
+/*------------------------------------------------------------------------
+ * actions
+ *------------------------------------------------------------------------
+ */
+
+
+/*------------------------------------------------------------------------
+ * writeBlock
+ * write data from data-> to socket, the length of data is len
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::write(const char *data, uint len) {
+ // TODO: accept data, (This seems can be removed????)
+ from_ansi.resize(len);
+ memcpy(from_ansi.data(), data, len);
+
+ // resize output buffer
+ to_socket.resize(2 *len);
+ wsize = 0;
+
+ // process keyboard input
+ // because we use GUI, there is no need to support a "command mode"
+ // So the keyboard-input FSM isnt' necessary.
+
+ uint i;
+
+ u_char c; // TODO: for gcc's happy :)
+ for (i = 0; i < len; ++i) {
+ c = (u_char)(from_ansi[i]);
+ soputc((int)c);
+ }
+
+ FQ_TRACE("telnet", 2) << "write " << len << " bytes:\n"
+ << dumpHexString << std::string(data, len);
+
+ //flush socket
+ socket->writeBlock(to_socket.left(wsize));
+ socket->flush();
+
+ emit TelnetState(TSWRITED);
+ return 0;
+}
+
+
+/*------------------------------------------------------------------------
+ * Trans functions
+ * All trans functions use from_socket, to_ansi, to_socket buffers, and
+ * rsize, wsize .
+ *------------------------------------------------------------------------
+ */
+
+/*------------------------------------------------------------------------
+ * tcdm - handle the telnet "DATA MARK" command (marks end of SYNCH)
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::tcdm(int) {
+ if (synching > 0) {
+ synching--;
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * rcvurg - receive urgent data input (indicates a telnet SYNCH)
+ *------------------------------------------------------------------------
+ */
+/*
+ int FQTermTelnet::rcvurg(int sig)
+ {
+ synching++;
+ }
+*/
+
+/*------------------------------------------------------------------------
+ * recopt - record option type
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::recopt(int c) {
+ option_cmd = c;
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * no_op - do nothing
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::no_op(int) {
+ return 0;
+}
+
+
+/*------------------------------------------------------------------------
+ * do_echo - handle TELNET WILL/WON'T ECHO option
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::do_echo(int c) {
+ if (doecho) {
+ if (option_cmd == TCWILL) {
+ return 0;
+ }
+ /* already doing ECHO */
+ } else if (option_cmd == TCWONT) {
+ return 0;
+ }
+ /* already NOT doing ECHO */
+
+ doecho = !doecho;
+
+ putc_down(TCIAC);
+ if (doecho) {
+ putc_down(TCDO);
+ } else {
+ putc_down(TCDONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * putc_down - put a character in to_socket buffer.
+ * wsize represent the number of bytes in to_socket buffer, and the buffer
+ * is addressed from 0, NOT 1.
+ *------------------------------------------------------------------------
+ */
+void FQTermTelnet::putc_down(u_char c) {
+ // check overflow
+ if ((long)(wsize + 1) > to_socket.size()) {
+ FQ_TRACE("telnet", 0) << "Buffer to_socket overflow.";
+ return ;
+ }
+ // put it in the buffer
+ //to_socket->replace(wsize, 1, (const char *)&c);
+ to_socket[wsize] = c;
+
+ wsize++;
+ return ;
+}
+
+/*------------------------------------------------------------------------
+ * do_notsup - handle an unsupported telnet "will/won't" option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::do_notsup(int c) {
+ putc_down(TCIAC);
+ putc_down(TCDONT);
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * do_noga - don't do telnet Go-Ahead's
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::do_noga(int c) {
+ if (noga) {
+ if (option_cmd == TCWILL) {
+ return 0;
+ }
+ } else if (option_cmd == TCWONT) {
+ return 0;
+ }
+
+ noga = !noga;
+
+ putc_down(TCIAC);
+ if (noga) {
+ putc_down(TCDO);
+ } else {
+ putc_down(TCDONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * do_txbinary - handle telnet "will/won't" TRANSMIT-BINARY option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::do_txbinary(int c) {
+ if (rcvbinary) {
+ if (option_cmd == TCWILL) {
+ return 0;
+ }
+ } else if (option_cmd == TCWONT) {
+ return 0;
+ }
+
+ rcvbinary = !rcvbinary;
+
+ putc_down(TCIAC);
+ if (rcvbinary) {
+ putc_down(TCDO);
+ } else {
+ putc_down(TCDONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * will_notsup - handle an unsupported telnet "do/don't" option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::will_notsup(int c) {
+ putc_down(TCIAC);
+ putc_down(TCWONT);
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * will_txbinary - handle telnet "do/don't" TRANSMIT-BINARY option
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::will_txbinary(int c) {
+ if (sndbinary) {
+ if (option_cmd == TCDO) {
+ return 0;
+ }
+ } else if (option_cmd == TCDONT) {
+ return 0;
+ }
+
+ sndbinary = !sndbinary;
+
+ putc_down(TCIAC);
+ if (sndbinary) {
+ putc_down(TCWILL);
+ } else {
+ putc_down(TCWONT);
+ }
+ putc_down((char)c);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * will_termtype - handle telnet "do/don't" TERMINAL-TYPE option
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::will_termtype(int c) {
+ if (termtype) {
+ if (option_cmd == TCDO) {
+ return 0;
+ }
+ } else if (option_cmd == TCDONT) {
+ return 0;
+ }
+
+ termtype = !termtype;
+
+ putc_down(TCIAC);
+
+ if (termtype) {
+ putc_down(TCWILL);
+ } else {
+ putc_down(TCWONT);
+ }
+
+ putc_down((char)c);
+
+ // TODO: Do NOT use this assume! some foolish BBS not response the request
+ /* The client expects that once the remote application receives
+ terminal type information it will send control sequences for
+ the terminal, which cannot be sent using the NVT encoding, So
+ change the transfer mode to binary in both directions */
+ /* set up binary data path; send WILL, DO */
+ /* if (termtype) {
+ option_cmd = TCWILL;
+ do_txbinary(TOTXBINARY);
+ option_cmd = TCDO;
+ will_txbinary(TOTXBINARY);
+ }
+ */
+ return 0;
+}
+
+int FQTermTelnet::will_naws(int c) {
+ if (naws) {
+ if (option_cmd == TCDO)
+ return 0;
+ } else if (option_cmd == TCDONT)
+ return 0;
+
+
+ naws = !naws;
+
+ putc_down(TCIAC);
+ if (naws)
+ putc_down(TCWILL);
+ else
+ putc_down(TCWONT);
+ putc_down((char)c);
+
+ putc_down(TCIAC);
+ putc_down(TCSB);
+ putc_down(TONAWS);
+ putc_down((char)(short(wx) >> 8));
+ putc_down((char)(short(wx)&0xff));
+ putc_down((char)(short(wy) >> 8));
+ putc_down((char)(short(wy)&0xff));
+ putc_down(((char)TCIAC));
+ putc_down((char)TCSE);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * subopt - do option subnegotiation FSM transitions
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::subopt(int c) {
+ struct fsm_trans *pt;
+ int ti;
+
+ ti = subfsm[substate][c];
+ pt = &substab[ti];
+ (this->*(pt->ft_action))(c);
+ substate = pt->ft_next;
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * subtermtype - do terminal type option subnegotation
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::subtermtype(int) {
+ char *i;
+ /* have received IAC.SB.TERMTYPE.SEND */
+
+ putc_down(TCIAC);
+ putc_down(TCSB);
+ putc_down(TOTERMTYPE);
+ putc_down(TT_IS);
+
+ //write term type string
+ //fputs(term, sfp);
+ for (i = term; (*i) != '\000'; i++) {
+ putc_down(*i);
+ }
+
+ putc_down(TCIAC);
+ putc_down(TCSE);
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * subend - end of an option subnegotiation; reset FSM
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::subend(int) {
+ substate = SS_START;
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * soputc - move a character from the keyboard to the socket
+ * convert an character into the NVT encoding and send it
+ * through the socket to the server.
+ *------------------------------------------------------------------------
+ */
+
+int FQTermTelnet::soputc(int c) {
+ if (sndbinary) {
+ if (c == TCIAC) {
+ putc_down(TCIAC);
+ }
+ /* byte-stuff IAC */
+ putc_down(c);
+ return 0;
+ }
+
+ //c &= 0x7f; /* 7-bit ASCII only ???*/
+ // Convert local special characters to NVT characters
+ /* TODO: // BBS don't need control signals
+ if (c == t_intrc || c == t_quitc) { // Interrupt
+ putc_down(TCIAC);
+ putc_down(TCIP);
+ } else if (c == sg_erase) { // Erase Char
+ putc_down(TCIAC);
+ putc_down(TCEC);
+ } else if (c == sg_kill) { // Erase Line
+ putc_down(TCIAC);
+ putc_down(TCEL);
+ } else if (c == t_flushc) { // Abort Output
+ putc_down(TCIAC);
+ putc_down(TCAO);
+ } else */
+ putc_down((char)c);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * xputc - putc to upper layer with optional file scripting
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::xputc_up(char ch) {
+ if ((long)(rsize + 1) > to_ansi.size()) {
+ FQ_TRACE("telnet", 0) << "Buffer to_ansi overflow.";
+ return - 1;
+ }
+ //to_ansi->replace(wsize, 1, &ch);
+ to_ansi[rsize] = u_char(ch);
+ rsize++;
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * xfputs - fputs with optional file scripting
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::xputs_up(char *str) {
+ /*if (scrfp)
+ fputs(str, scrfp);*/
+
+ char *i;
+ for (i = str; (*i) != '\000'; i++) {
+ xputc_up(*i);
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * ttputc - print a single character on a Network Virtual Terminal
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::ttputc(int c) {
+ if (rcvbinary) {
+ xputc_up((char)c); /* print uninterpretted */
+ return 0;
+ }
+ /* no data, if in SYNCH */
+ /*
+ if (synching)
+ return 0;
+ */
+ /* TODO: FQTermTelnet doesnot interpret NVT code, provide datas to upper
+ layer directly. So, <cr><lf> will not be replaced with <lf>
+ */
+ xputc_up((char)c);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * invalid state reached, aborted
+ *------------------------------------------------------------------------
+ */
+int FQTermTelnet::tnabort(int) {
+ FQ_VERIFY(false); // "invalid state reached, aborted";
+ // exit(-1);
+ return -1;
+}
+
+bool FQTermTelnet::readyForInput()
+{
+ return socket->readyForInput();
+}
+
+
+
+} // namespace FQTerm
+
+#include "fqterm_telnet.moc"
diff --git a/src/terminal/internal/fqterm_telnet.h b/src/terminal/internal/fqterm_telnet.h
new file mode 100644
index 0000000..33e8c6e
--- /dev/null
+++ b/src/terminal/internal/fqterm_telnet.h
@@ -0,0 +1,195 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TELNET_H
+#define FQTERM_TELNET_H
+
+#include <QAbstractSocket>
+#include <QByteArray>
+
+namespace FQTerm {
+
+#ifndef u_char
+#define u_char uchar
+#endif
+
+#define NTSTATES 6 // # of Telnet Socket-Input FSM States
+#define NSSTATES 3 // # of Telnet Option Subnegotiation FSM States
+#define NCHRS 256 // # of valid characters
+
+// decleration
+class FQTermTelnet;
+// actionFunc is a pointer, point to a FQTermTelnet's func
+typedef int(FQTermTelnet:: *ptrActionFunc)(int c);
+
+//fsm struct
+struct fsm_trans {
+ u_char ft_state; // current state
+ short ft_char; // input character
+ u_char ft_next; // next state
+ ptrActionFunc ft_action; // action to take
+};
+
+
+/*------------------------------------------------------------------------------
+ * FQTermTelnet class definition
+ *-------------------------------------------------------------------------------
+ */
+class FQTermSocket;
+
+// Telnet connection, a wrapper of socket.
+// It will translate raw NVT data from low level socket to ansi data,
+// and then upper level application can read it.
+// It also can send ascii data (0~127).
+class FQTermTelnet: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermTelnet(const QString &termtype, int rows, int numColumns, int protocolType, int hostType, const
+ char *sshuser = NULL, const char *sshpasswd = NULL);
+ ~FQTermTelnet();
+
+ void setProxy(int nProxyType, //0-no proxy; 1-wingate; 2-sock4; 3-socks5
+ bool bAuth, // if authentation needed
+ const QString &strProxyHost, quint16 uProxyPort, const QString &strProxyUsr,
+ const QString &strProxyPwd);
+ void connectHost(const QString &hostname, quint16 portnumber);
+
+ // Read ansi data.
+ int read(char *data, uint maxlen);
+
+ // Write data raw data
+ int write(const char *data, uint len);
+
+ void close(); // User close the connection
+
+ int raw_len();
+ int read_raw(char *data, uint maxlen);
+
+ bool readyForInput();
+
+
+ signals:
+ void readyRead(int, int); // There are datas to be read out
+ void TelnetState(int); // The state telnet, defined as TSXXXX in fqterm.h
+ void requestUserPwd(QString *user, QString *pwd, bool *isOK);
+ void errorMessage(QString);
+
+ public slots:
+ void windowSizeChanged(int, int);
+
+ private slots:
+ // Retrieve data from socket, translate NVT data to ansi data,
+ // then notify data ready.
+ void socketReadyRead();
+
+ void connected();
+ void showError(QAbstractSocket::SocketError);
+ void hostFound();
+ void delayCloseFinished();
+ void closed();
+ protected:
+ //init structure fsm
+ void init_telnet();
+ void fsmbuild();
+ void fsminit(u_char fsm[][NCHRS], struct fsm_trans ttab[], int nstates);
+
+ //actions
+ int tcdm(int);
+ int recopt(int);
+ int no_op(int);
+ int do_echo(int);
+ int do_notsup(int);
+ int do_noga(int);
+ int do_txbinary(int);
+ int will_notsup(int);
+ int will_txbinary(int);
+ int will_termtype(int);
+ int will_naws(int);
+ int subopt(int);
+ int subtermtype(int);
+ int subend(int);
+ int soputc(int);
+ int ttputc(int);
+ int tnabort(int);
+
+ //utility functions
+ int xputc_up(char);
+ int xputs_up(char*);
+ void putc_down(u_char);
+
+signals:
+
+ void onSSHAuthOK();
+
+ private:
+ // Boolean Flags
+ char synching, doecho, sndbinary, rcvbinary;
+ char noga;
+ char naws;
+ char server_sent_do_naws;
+ u_char option_cmd; // has value WILL, WONT, DO, or DONT
+
+ char termtype; // non-zero if received "DO TERMTYPE"
+ char *term; // terminal name
+
+ /* // TODO: BBS don't need control signals
+ // Special keys - Terminal control characters
+ // need work...
+ static const char t_flushc=FQTERM_CTRL('S'); // Abort Output i.e:(^S)
+ static const char t_intrc=FQTERM_CTRL('C'); // Interrupt i.e:(^C)
+ static const char t_quitc=FQTERM_CTRL('\\'); // Quit i.e:(^\)
+ static const char sg_erase=FQTERM_CTRL('?'); // Erase a character i.e:(^?)
+ static const char sg_kill=FQTERM_CTRL('U'); // Kill a line i.e:(^U)
+ */
+
+ // FSM stuffs
+ static struct fsm_trans ttstab[];
+ int ttstate;
+ u_char ttfsm[NTSTATES][NCHRS];
+
+ static struct fsm_trans substab[];
+ int substate;
+ u_char subfsm[NSSTATES][NCHRS];
+
+ // socket stuffs
+ FQTermSocket *socket;
+
+ //Pointers to internal buffers
+ //
+ // |-->from_socket-->process-->to_ansi-->|
+ // socket<---> <---> ansi decode
+ // |<---to_socket<--process<--from_ansi--|
+ //
+ QByteArray from_socket, to_ansi, from_ansi, to_socket;
+ uint rsize; // size of to_ansi buffer
+ uint wsize; // size of to_socket buffer
+
+ // for test
+ int wx, wy;
+ int done_naws;
+ bool bConnected;
+ int raw_size;
+ int hostType_;
+ int protocolType_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TELNET_H
diff --git a/src/terminal/internal/fqterm_zmodem.cpp b/src/terminal/internal/fqterm_zmodem.cpp
new file mode 100644
index 0000000..afb99c9
--- /dev/null
+++ b/src/terminal/internal/fqterm_zmodem.cpp
@@ -0,0 +1,3056 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QApplication>
+#include <QString>
+#include <QFileDialog>
+#include <QFileInfo>
+
+#include "fqterm.h"
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_telnet.h"
+#include "fqterm_zmodem.h"
+#include "fqterm_filedialog.h"
+
+#ifdef FQTERM_ZMODEM_DEBUG
+#include <sys/time.h>
+#endif
+
+namespace FQTerm {
+
+static const uchar zeros[4] = {
+ 0, 0, 0, 0
+};
+
+static const char hexChars[] = "0123456789abcdef";
+
+static const uchar AckStr[1] = {
+ ACK
+};
+static const uchar NakStr[1] = {
+ NAK
+};
+static const uchar CanStr[2] = {
+ CAN, CAN
+};
+static const uchar eotstr[1] = {
+ EOT
+};
+
+
+/*
+ * Crc calculation stuff
+ */
+
+/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
+unsigned short crctab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129,
+ 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273,
+ 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a,
+ 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6,
+ 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf,
+ 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695,
+ 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc,
+ 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4,
+ 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf,
+ 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5,
+ 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a,
+ 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32,
+ 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59,
+ 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9,
+ 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290,
+ 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8,
+ 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481,
+ 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f,
+ 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676,
+ 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a,
+ 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75,
+ 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f,
+ 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64,
+ 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c,
+ 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93,
+ 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+/*
+ * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
+ * NOTE: First argument must be in range 0 to 255.
+ * Second argument is referenced twice.
+ *
+ * Programmers may incorporate any or all code into their programs,
+ * giving proper credit within the source. Publication of the
+ * source routines is permitted so long as proper credit is given
+ * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
+ * Omen Technology.
+ */
+
+#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
+
+/*
+ * Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+
+/* First, the polynomial itself and its table of feedback terms. The */
+/* polynomial is */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in */
+/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+/* the MSB being 1. */
+
+/* Note that the usual hardware shift register implementation, which */
+/* is what we're using (we're merely optimizing it by doing eight-bit */
+/* chunks at a time) shifts bits into the lowest-order term. In our */
+/* implementation, that means shifting towards the right. Why do we */
+/* do it this way? Because the calculated CRC must be transmitted in */
+/* order from highest-order term to lowest-order term. UARTs transmit */
+/* characters in order from LSB to MSB. By storing the CRC this way, */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part. Reception works similarly. */
+
+/* The feedback terms table consists of 256, 32-bit entries. Notes: */
+/* */
+/* The table can be generated at runtime if desired; code to do so */
+/* is shown later. It might not be obvious, but the feedback */
+/* terms simply represent the results of eight shift/xor opera- */
+/* tions for all combinations of data and CRC register values. */
+/* */
+/* The values must be right-shifted by eight bits by the "updcrc" */
+/* logic; the shift must be unsigned (bring in zeroes). On some */
+/* hardware you could probably optimize the shift in assembler by */
+/* using byte-swap instructions. */
+
+unsigned long cr3tab[] = {
+ /* CRC polynomial 0xedb88320 */
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+ };
+
+#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
+
+#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
+
+
+
+#if 1
+StateTable FQTermZmodem::RStartOps[] = {
+ {ZSINIT, &FQTermZmodem::GotSinit, 0, 1, RSinitWait},
+ /* SINIT, wait for attn str */
+ {ZFILE, &FQTermZmodem::GotFile, 0, 0, RFileName},
+ /* FILE, wait for filename */
+ {ZRQINIT, &FQTermZmodem::SendRinit, 0, 1, RStart},
+ /* sender confused, resend */
+ {ZFIN, &FQTermZmodem::GotFin, 1, 0, RFinish},
+ /* sender shutting down */
+ {ZNAK, &FQTermZmodem::SendRinit, 1, 0, RStart},
+ /* RINIT was bad, resend */
+ {ZFREECNT, &FQTermZmodem::GotFreecnt, 0, 0, RStart},
+ /* sender wants free space */
+ {ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData},
+ /* sender wants command */
+ {ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData},
+ /* sender wants to send msg */
+ {ZRINIT, &FQTermZmodem::ZmodemTInit, 1, 1, TStart},
+ {99, &FQTermZmodem::ZPF, 0, 0, RStart}
+ /* anything else is an error */
+};
+
+StateTable FQTermZmodem::RSinitWaitOps[] = {
+ /* waiting for data */
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, RSinitWait
+ },
+};
+
+StateTable FQTermZmodem::RFileNameOps[] = {
+ /* waiting for file name */
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, RFileName
+ },
+};
+
+StateTable FQTermZmodem::RCrcOps[] = {
+ /* waiting for CRC */
+ {
+ ZCRC, &FQTermZmodem::GotFileCrc, 0, 0, RFile
+ }, { /* sender sent it */
+ ZNAK, &FQTermZmodem::ResendCrcReq, 0, 0, RCrc
+ }, { /* ZCRC was bad, resend */
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ }, { /* sender confused, restart */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ 99, &FQTermZmodem::ZPF, 0, 0, RCrc
+ },
+};
+
+
+StateTable FQTermZmodem::RFileOps[] = {
+ /* waiting for ZDATA */
+ {
+ ZDATA, &FQTermZmodem::GotData, 0, 0, RData
+ }, { /* got it */
+ ZNAK, &FQTermZmodem::ResendRpos, 0, 0, RFile
+ }, { /* ZRPOS was bad, resend */
+ ZEOF, &FQTermZmodem::GotEof, 0, 0, RStart
+ }, { /* end of file */
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ }, { /* sender confused, restart */
+ ZFILE, &FQTermZmodem::ResendRpos, 0, 0, RFile
+ }, { /* ZRPOS was bad, resend */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ 99, &FQTermZmodem::ZPF, 0, 0, RFile
+ },
+};
+
+/* waiting for data, but a packet could possibly arrive due
+ * to error recovery or something
+ */
+StateTable FQTermZmodem::RDataOps[] = {
+ {
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ }, { /* sender confused, restart */
+ ZFILE, &FQTermZmodem::GotFile, 0, 1, RFileName
+ }, { /* start a new file (??) */
+ ZNAK, &FQTermZmodem::ResendRpos, 1, 1, RFile
+ }, { /* ZRPOS was bad, resend */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ ZDATA, &FQTermZmodem::GotData, 0, 1, RData
+ }, { /* file data follows */
+ ZEOF, &FQTermZmodem::GotEof, 1, 1, RStart
+ }, { /* end of file */
+ 99, &FQTermZmodem::ZPF, 0, 0, RData
+ },
+};
+
+/* here if we've sent ZFERR or ZABORT. Waiting for ZFIN */
+
+StateTable FQTermZmodem::RFinishOps[] = {
+
+ {
+ ZRQINIT, &FQTermZmodem::SendRinit, 1, 1, RStart
+ } , { /* sender confused, restart */
+ ZFILE, &FQTermZmodem::GotFile, 1, 1, RFileName
+ }, { /* start a new file */
+ ZNAK, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* resend ZFIN */
+ ZFIN, &FQTermZmodem::GotFin, 1, 1, RFinish
+ }, { /* sender signing off */
+ 99, &FQTermZmodem::ZPF, 0, 0, RFinish
+ },
+};
+
+
+/* sent ZRQINIT, waiting for response */
+StateTable FQTermZmodem::TStartOps[] = {
+ {
+ ZRINIT, &FQTermZmodem::GotRinit, 1, 1, TStart
+ }, {
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 1, 0, TStart
+ }, {
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZNAK, &FQTermZmodem::Ignore, 0, 0, TStart
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, TStart
+ },
+};
+
+/* sent ZSINIT, waiting for response */
+StateTable FQTermZmodem::TInitOps[] = {
+ {
+ ZACK, &FQTermZmodem::RetDone, 1, 0, TInit
+ }, {
+ ZNAK, &FQTermZmodem::SendZSInit, 1, 0, TInit
+ }, {
+ ZRINIT, &FQTermZmodem::GotRinit, 1, 1, TInit
+ }, { /* redundant, but who cares */
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 1, 0, TInit
+ }, {
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, TInit
+ },
+};
+
+/* sent ZFILE, waiting for response */
+StateTable FQTermZmodem::FileWaitOps[] = {
+ {
+ ZRPOS, &FQTermZmodem::SendFileData, 1, 1, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 0, TStart
+ }, {
+ ZCRC, &FQTermZmodem::SendFileCrc, 1, 0, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::sendFilename, 1, 0, FileWait
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 1, 0, FileWait
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ ZACK, &FQTermZmodem::SendFileData, 1, 0, Sending
+ }, { // receiver always sends ZACK back
+ 99, &FQTermZmodem::ZPF, 0, 0, FileWait
+ },
+};
+
+/* sent file CRC, waiting for response */
+StateTable FQTermZmodem::CrcWaitOps[] = {
+ {
+ ZRPOS, &FQTermZmodem::SendFileData, 1, 0, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 0, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::SendFileCrc, 1, 0, CrcWait
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZCRC, &FQTermZmodem::SendFileCrc, 0, 0, CrcWait
+ }, {
+ ZCHALLENGE, &FQTermZmodem::AnswerChallenge, 0, 0, CrcWait
+ }, {
+ ZCOMMAND, &FQTermZmodem::GotCommand, 0, 0, CommandData
+ }, {
+ ZSTDERR, &FQTermZmodem::GotStderr, 0, 0, StderrData
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, CrcWait
+ },
+};
+
+/* sending data, interruptable */
+StateTable FQTermZmodem::SendingOps[] = {
+ {
+ ZACK, &FQTermZmodem::GotSendAck, 0, 0, Sending
+ }, {
+ ZRPOS, &FQTermZmodem::GotSendPos, 1, 1, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::GotSendNak, 1, 1, Sending
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ },{ /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendWait
+ },
+};
+
+/* sent data, need to send EOF */
+StateTable FQTermZmodem::SendDoneOps[] = {
+ {
+ ZACK, &FQTermZmodem::GotSendDoneAck, 0, 0, SendWait
+ }, {
+ ZRPOS, &FQTermZmodem::GotSendPos, 1, 1, Sending
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::GotSendNak, 1, 1, Sending
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendWait
+ },
+};
+
+/* sending data, waiting for ACK */
+StateTable FQTermZmodem::SendWaitOps[] = {
+ {
+ ZACK, &FQTermZmodem::GotSendWaitAck, 0, 0, Sending
+ }, {
+ ZRPOS, &FQTermZmodem::GotSendPos, 0, 0, SendWait
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, FileWait
+ }, {
+ ZNAK, &FQTermZmodem::GotSendNak, 0, 0, Sending
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendWait
+ },
+};
+
+/* sent ZEOF, waiting for new RINIT */
+StateTable FQTermZmodem::SendEofOps[] = {
+ {
+ ZRINIT, &FQTermZmodem::SkipFile, 1, 0, TFinish
+ }, { /* successful completion */
+ ZACK, &FQTermZmodem::Ignore, 0, 0, SendEof
+ }, { /* probably ACK from last packet */
+ ZRPOS, &FQTermZmodem::GotSendPos, 1, 1, SendWait
+ }, {
+ ZSKIP, &FQTermZmodem::SkipFile, 1, 1, TStart
+ }, {
+ ZNAK, &FQTermZmodem::ResendEof, 1, 0, SendEof
+ }, {
+ ZRINIT, &FQTermZmodem::sendFilename, 1, 1, FileWait
+ }, { /* rcvr confused, retry file */
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, SendEof
+ },
+};
+
+StateTable FQTermZmodem::TFinishOps[] = {
+ {
+ ZFIN, &FQTermZmodem::OverAndOut, 1, 1, Done
+ }, {
+ ZNAK, &FQTermZmodem::ZmodemTFinish, 1, 1, TFinish
+ }, {
+ ZRINIT, &FQTermZmodem::ZmodemTFinish, 1, 1, TFinish
+ }, {
+ ZABORT, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ ZFERR, &FQTermZmodem::GotAbort, 1, 1, TFinish
+ }, {
+ 99, &FQTermZmodem::ZPF, 0, 0, TFinish
+ },
+};
+
+StateTable FQTermZmodem::CommandDataOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, CommandData
+ },
+};
+
+StateTable FQTermZmodem::CommandWaitOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, CommandWait
+ },
+};
+
+StateTable FQTermZmodem::StderrDataOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, StderrData
+ },
+};
+
+StateTable FQTermZmodem::DoneOps[] = {
+ {
+ 99, &FQTermZmodem::ZPF, 0, 0, Done
+ },
+};
+
+StateTable *FQTermZmodem::tables[] = {
+ FQTermZmodem::RStartOps, FQTermZmodem::RSinitWaitOps, FQTermZmodem::RFileNameOps,
+ FQTermZmodem::RCrcOps, FQTermZmodem::RFileOps, FQTermZmodem::RDataOps,
+ FQTermZmodem::RDataOps, /* RDataErr is the same as RData */
+ FQTermZmodem::RFinishOps,
+
+ FQTermZmodem::TStartOps, FQTermZmodem::TInitOps, FQTermZmodem::FileWaitOps,
+ FQTermZmodem::CrcWaitOps, FQTermZmodem::SendingOps, FQTermZmodem::SendWaitOps,
+ FQTermZmodem::SendDoneOps, FQTermZmodem::SendEofOps, FQTermZmodem::TFinishOps,
+
+ FQTermZmodem::CommandDataOps, FQTermZmodem::CommandWaitOps,
+ FQTermZmodem::StderrDataOps, FQTermZmodem::DoneOps,
+};
+
+const char *FQTermZmodem::hdrnames[] = {
+ "ZRQINIT", "ZRINIT", "ZSINIT", "ZACK", "ZFILE", "ZSKIP", "ZNAK", "ZABORT",
+ "ZFIN", "ZRPOS", "ZDATA", "ZEOF", "ZFERR", "ZCRC", "ZCHALLENGE", "ZCOMPL",
+ "ZCAN", "ZFREECNT", "ZCOMMAND", "ZSTDERR",
+};
+
+#endif
+
+FQTermZmodem::FQTermZmodem(FQTermConfig *config, FQTermTelnet *netinterface, int type, int serverEncoding) {
+
+ //now set network interface Telnet
+
+ connectionType = type;
+
+ serverEncodingID = serverEncoding;
+
+ switch (connectionType) {
+ case 0:
+ case 1:
+ case 2:
+ telnet_ = netinterface;
+ break;
+ default:
+ FQ_TRACE("zmodem", 0) << "connection type unknown! Expect segmentation fault!";
+ telnet_ = netinterface;
+ break;
+ }
+
+ config_ = config;
+
+ sending = false;
+
+ transferstate = notransfer;
+
+ zmodemTimer = new QTimer(this);
+ FQ_VERIFY(connect(zmodemTimer, SIGNAL(timeout()), this, SLOT(ZmodemTimeout())));
+
+#ifdef FQTERM_ZMODEM_DEBUG
+ zmodemlogfile = fopen("zmodem.log", "w+");
+ fprintf(zmodemlogfile, "%s", "\n================================\n");
+ fclose(zmodemlogfile);
+#endif
+
+
+ //init struct INFO
+ info.zrinitflags = CANFDX | CANOVIO | CANBRK | CANFC32;
+ info.zsinitflags = 0;
+ info.attn = NULL;
+ info.bufsize = 0; /* full streaming */
+ info.buffer = NULL;
+
+ zerrno = 0;
+ lastPullByte = 0;
+
+ ZmodemReset(&info);
+ // other init function not complete
+
+}
+
+FQTermZmodem::~FQTermZmodem(){}
+
+int FQTermZmodem::ZmodemTInit(ZModem *info) {
+ int err;
+ int i;
+
+ info->state = TStart;
+ info->Protocol = ZMODEM;
+ info->crc32 = 0;
+ info->packetCount = 0;
+ info->errCount = 0;
+ info->escCtrl = info->escHibit = info->atSign = info->escape = 0;
+ info->InputState = Idle;
+ info->canCount = info->chrCount = 0;
+ info->windowCount = 0;
+ info->filename = NULL;
+ info->bufsize = 0;
+ info->interrupt = 0;
+ info->waitflag = 0;
+
+ // if( info->packetsize <= 0 )
+ info->packetsize = 8096;
+ info->windowsize = 0;
+ //we won't be receiving much data, pick a reasonable buffer
+ // size (largest packet will do)
+ //
+
+ i = info->packetsize *2;
+
+ if (info->buffer != NULL) {
+ free(info->buffer);
+ info->buffer = NULL;
+ }
+ //since in the constructor function buffer is malloc
+
+ if (i < 1024) {
+ i = 1024;
+ }
+ info->buffer = (uchar*)malloc(i);
+
+ ZIFlush(info);
+
+// FQTermConfig *config = new FQTermConfig(getPath(USER_CONFIG) + "fqterm.cfg");
+// QString strPrevSave = config->getItemValue("global", "previous");
+
+// if (strPrevSave.isEmpty()) {
+// strFileList = QFileDialog::getOpenFileNames(0, "Choose the files",
+// getPath(USER_CONFIG), "All files(*)");
+// } else {
+// strFileList = QFileDialog::getOpenFileNames(0, "Choose the files",
+// strPrevSave, "All files(*)");
+// }
+ FQTermFileDialog fileDialog(config_);
+ strFileList = fileDialog.getOpenNames("Choose a file to upload", "");
+ if (strFileList.count() != 0) {
+ QStringList::Iterator itFile = strFileList.begin();
+ QFileInfo fi(*itFile);
+ }
+
+ this->transferstate = transferstop;
+
+ // optional: send "rz\r" to remote end
+ if (DoInitRZ) {
+ if ((err = ZXmitStr((uchar*)"rz\r", 3, info))) {
+ return err;
+ }
+ }
+
+ if ((err = ZXmitHdr(ZRQINIT, ZHEX, zeros, info))) {
+ // nudge receiver
+ return err;
+ }
+
+ info->timeout = 60;
+
+ zmodemlog("ZmodemTInit[%s]: sent ZRQINIT\n", sname(info));
+
+ return 0;
+}
+
+
+int FQTermZmodem::ZmodemTFile(char *file, char *rfile, uint f0, uint f1, uint f2,
+ uint f3, int filesRem, int bytesRem, ZModem *info) {
+ if (file == NULL || (info->file = fopen(file, "rb")) == NULL) {
+ return ZmErrCantOpen;
+ }
+
+ info->fileEof = 0;
+ info->filename = file;
+ if (rfile != NULL) {
+ info->rfilename = rfile;
+ } else {
+ info->rfilename = strdup("noname");
+ }
+ info->filesRem = filesRem;
+ info->bytesRem = bytesRem;
+ info->fileFlags[3] = f0;
+ info->fileFlags[2] = f1;
+ info->fileFlags[1] = f2;
+ info->fileFlags[0] = f3;
+ info->offset = info->lastOffset = 0;
+ info->len = info->date = info->fileType = info->mode = 0;
+ if (info->filename != NULL) {
+ struct stat buf;
+ if (stat(info->filename, &buf) == 0) {
+ info->len = buf.st_size;
+ info->date = buf.st_mtime;
+ info->fileType = 0;
+ info->mode = (buf.st_mode &0777) | 0100000;
+ }
+ }
+
+ if (info->Protocol == XMODEM) {
+ return YSendData(info);
+ }
+
+ if (info->Protocol == YMODEM) {
+ return YSendFilename(info);
+ }
+
+ info->state = FileWait;
+ ZStatus(FileBegin, info->bytesRem, info->rfilename);
+ zmodemlog("ZmodemTFile[%s]: send ZFILE(%s)\n", sname(info), info->rfilename);
+ return sendFilename(info);
+}
+
+
+int FQTermZmodem::ZmodemTFinish(ZModem *info) {
+ int i;
+ if (info->Protocol == XMODEM) {
+ return ZmDone;
+ }
+
+ if (info->Protocol == YMODEM) {
+ return YSendFin(info);
+ }
+
+ info->state = TFinish;
+ if (info->buffer != NULL) {
+ free(info->buffer);
+ info->buffer = NULL;
+ }
+ zmodemlog("ZmodemTFinish[%s]: send ZFIN\n", sname(info));
+ i = ZXmitHdr(ZFIN, ZHEX, zeros, info);
+
+ return i;
+}
+
+
+
+int FQTermZmodem::ZmodemAbort(ZModem *info) {
+ uchar canistr[] = {
+ CAN, CAN, CAN, CAN, CAN, CAN, CAN, CAN, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0
+ };
+ info->state = Done;
+ ZIFlush(info);
+ ZOFlush(info);
+
+ transferstate = transferstop; // transfer complete
+ ZmodemReset(info); //Tranfer complete, zmodem return to receive state
+
+ zmodemlog("ZmodemAbort[%s]: send CAN\n", sname(info));
+ return ZXmitStr(canistr, sizeof(canistr), info);
+}
+
+
+int FQTermZmodem::ZmodemRInit(ZModem *info) {
+ info->packetCount = 0;
+ info->offset = 0;
+ info->errCount = 0;
+ info->escCtrl = info->escHibit = info->atSign = info->escape = 0;
+ info->InputState = Idle;
+ info->canCount = info->chrCount = 0;
+ info->filename = NULL;
+ info->interrupt = 0;
+ info->waitflag = 0;
+ info->attn = NULL;
+ info->file = NULL;
+
+ if (info->buffer != NULL) {
+ free(info->buffer);
+ info->buffer = NULL;
+ }
+
+ info->buffer = (uchar*)malloc(1024);
+
+ info->state = RStart;
+ info->timeoutCount = 0;
+
+ ZIFlush(info);
+
+ /* Don't send ZRINIT right away, there might be a ZRQINIT in
+ * the input buffer. Instead, set timeout to zero and return.
+ * This will allow ZmodemRcv() to check the input stream first.
+ * If nothing found, a ZRINIT will be sent immediately.
+ */
+ info->timeout = 0;
+
+ zmodemlog("ZmodemRInit[%s]: flush input, new state = RStart\n", sname(info));
+
+ return 0;
+}
+
+int FQTermZmodem::ZmodemRcv(uchar *str, int len, ZModem *info,
+ int &consumed_bytes) {
+ register uchar c;
+ int err;
+
+ zmodemlog("zmodemRcv called");
+
+ info->rcvlen = len;
+
+ while (--info->rcvlen >= 0) {
+ c = *str++;
+
+ if (c == CAN) {
+ if (++info->canCount >= 5) {
+ ZStatus(RmtCancel, 0, NULL);
+ consumed_bytes = len - info->rcvlen - 1;
+ return ZmErrCancel;
+ }
+ } else {
+ info->canCount = 0;
+ }
+
+ if (info->InputState == Ysend) {
+ if ((err = YsendChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ } else if (info->InputState == Yrcv) {
+ if ((err = YrcvChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ } else if (c != XON && c != XOFF) {
+ /* now look at what we have */
+ switch (info->InputState) {
+ case Idle:
+ if ((err = IdleChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ case Inhdr:
+ if ((err = HdrChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ case Indata:
+ if ((err = DataChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ case Finish:
+ if ((err = FinishChar(c, info))) {
+ consumed_bytes = len - info->rcvlen - 1;
+ return err;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ consumed_bytes = len - info->rcvlen - 1;
+ return 0;
+}
+
+
+
+
+int FQTermZmodem::ZmodemTimeout( /*ZModem *info*/) {
+ /* timed out while waiting for input */
+
+ ++info.timeoutCount;
+
+ zmodemlog("timeout %d [%s]\n", info.timeoutCount, sname(&info));
+
+ switch (info.state) {
+ /* receive */
+ case RStart:
+ /* waiting for INIT frame from other end */
+ if (info.timeoutCount > 4) {
+ return YmodemRInit(&info);
+ }
+
+ case RSinitWait:
+ case RFileName:
+ if (info.timeout > 0) {
+ ZStatus(SndTimeout, info.timeoutCount, NULL);
+ }
+ if (info.timeoutCount > 4) {
+ return ZmErrRcvTo;
+ }
+ info.state = RStart;
+ return SendRinit(&info);
+
+ case RCrc:
+ case RFile:
+ case RData:
+ ZStatus(SndTimeout, info.timeoutCount, NULL);
+ if (info.timeoutCount > 2) {
+ info.timeoutCount = 0;
+ info.state = RStart;
+ return SendRinit(&info);
+ }
+ return info.state == RCrc ? ResendCrcReq(&info): ResendRpos(&info);
+
+ case RFinish:
+ ZStatus(SndTimeout, info.timeoutCount, NULL);
+ return ZmDone;
+
+ case YRStart:
+ case YRDataWait:
+ case YRData:
+ case YREOF:
+ return YrcvTimeout(&info);
+
+ /* transmit */
+ case TStart:
+ /* waiting for INIT frame from other end */
+ case TInit:
+ /* sent INIT, waiting for ZACK */
+ case FileWait:
+ /* sent file header, waiting for ZRPOS */
+ case CrcWait:
+ /* sent file crc, waiting for ZRPOS */
+ case SendWait:
+ /* waiting for ZACK */
+ case SendEof:
+ /* sent EOF, waiting for ZACK */
+ case TFinish:
+ /* sent ZFIN, waiting for ZFIN */
+ case YTStart:
+ case YTFile:
+ case YTDataWait:
+ case YTData:
+ case YTEOF:
+ case YTFin:
+ ZStatus(RcvTimeout, 0, NULL);
+ return ZmErrRcvTo;
+
+ case Sending:
+ /* sending data subpackets, ready for int */
+ return SendMoreFileData(&info);
+
+ /* general */
+ case CommandData:
+ /* waiting for command data */
+ case StderrData:
+ /* waiting for stderr data */
+ return ZmErrSndTo;
+ case CommandWait:
+ /* waiting for command to execute */
+ return ZmErrCmdTo;
+ case Done:
+ return ZmDone;
+ default:
+ return 0;
+ }
+}
+
+
+
+int FQTermZmodem::ZmodemAttention(ZModem *info) {
+ /* attention received from remote end */
+ if (info->state == Sending) {
+ ZOFlush(info);
+ info->interrupt = 1;
+ }
+ return 0;
+}
+
+int FQTermZmodem::YmodemTInit(ZModem *info) {
+ info->state = YTStart;
+ info->Protocol = YMODEM;
+ info->errCount = 0;
+ info->InputState = Ysend;
+ info->canCount = info->chrCount = 0;
+ info->windowCount = 0;
+ info->filename = NULL;
+
+ if (info->packetsize != 1024) {
+ info->packetsize = 128;
+ }
+
+ info->buffer = (uchar*)malloc(1024);
+
+ ZIFlush(info);
+ ZFlowControl(0, info);
+
+ info->timeout = 60;
+
+ return 0;
+}
+
+
+int FQTermZmodem::XmodemTInit(ZModem *info) {
+ (void)YmodemTInit(info);
+ info->Protocol = XMODEM;
+ return 0;
+}
+
+
+int FQTermZmodem::YmodemRInit(ZModem *info) {
+ info->errCount = 0;
+ info->InputState = Yrcv;
+ info->canCount = info->chrCount = 0;
+ info->noiseCount = 0;
+ info->filename = NULL;
+ info->file = NULL;
+
+ if (info->buffer == NULL) {
+ info->buffer = (uchar*)malloc(1024);
+ }
+
+ info->state = YRStart;
+ info->packetCount = -1;
+ info->timeoutCount = 0;
+ info->timeout = 10;
+ info->offset = 0;
+
+ ZIFlush(info);
+
+ return ZXmitStr((uchar*)"C", 1, info);
+}
+
+
+int FQTermZmodem::XmodemRInit(ZModem *info) {
+#if 0
+ int err;
+
+ state = Start;
+ protocol = prot;
+ ymodem = prot == Ymodem || prot == YmodemG;
+
+ if (ymodem) {
+ strcpy(xmDefPath, file);
+ } else {
+ strcpy(xmFilename, file);
+ }
+
+ eotCount = errorCount = errorCount2 = 0;
+
+ if (err = XmodemRStart()) {
+ return err;
+ }
+
+ state = Init;
+ packetId = ymodem ? 255 : 0;
+ packetCount = 0;
+
+ pktHdrLen = protocol == Xmodem ? 3 : 4;
+#endif
+ return 0;
+}
+
+
+ulong FQTermZmodem::FileCrc(char *name) {
+ ulong crc;
+ FILE *ifile = fopen(name, "rb");
+ int i;
+
+ if (ifile == NULL)
+ /* shouldn't happen, since we did access(2) */ {
+ return 0;
+ }
+
+ crc = 0xffffffff;
+
+ while ((i = fgetc(ifile)) != EOF) {
+ crc = UPDC32(i, crc);
+ }
+
+ fclose(ifile);
+ return ~crc;
+}
+
+
+
+const char *FQTermZmodem::sname(ZModem *info) {
+ return sname2(info->state);
+}
+
+const char *FQTermZmodem::sname2(ZMState state) {
+ const char *names[] = {
+ "RStart", "RSinitWait", "RFileName", "RCrc", "RFile", "RData", "RDataErr",
+ "RFinish", "TStart", "TInit", "FileWait", "CrcWait", "Sending", "SendWait",
+ "SendDone", "SendEof", "TFinish", "CommandData", "CommandWait", "StderrData",
+ "Done", "YTStart", "YTFile", "YTDataWait", "YTData", "YTEOF", "YTFin",
+ "YRStart", "YRDataWait", "YRData", "YREOF"
+ };
+
+ return names[(int)state];
+
+}
+
+
+int FQTermZmodem::ZXmitChr(uchar c, ZModem *info) {
+ // to be completed
+ return 0;
+}
+
+int FQTermZmodem::ZXmitStr(const uchar *str, int len, ZModem *info) {
+ //to be completed
+ telnet_->write((const char*)str, (uint)len);
+ return 0;
+}
+
+void FQTermZmodem::ZIFlush(ZModem *info) {
+ //to be completed
+}
+
+void FQTermZmodem::ZOFlush(ZModem *info) {
+ //to be completed
+}
+
+int FQTermZmodem::ZAttn(ZModem *info) {
+ //to be completed
+ return 0;
+}
+
+void FQTermZmodem::ZStatus(int type, int value, const char *status) {
+ emit ZmodemState(type, value, status);
+ switch (type) {
+ case RcvByteCount:
+ FQ_TRACE("zmodem", 5) << value << " bytes received.";
+ break;
+ case SndByteCount:
+ FQ_TRACE("zmodem", 5) << value << " bytes sent.";
+ break;
+ case RcvTimeout:
+ /* receiver did not respond, aborting */
+ FQ_TRACE("zmodem", 0) << "Zmodem time out!";
+ break;
+ case SndTimeout:
+ /* value is # of consecutive send timeouts */
+ FQ_TRACE("zmodem", 0) << "Zmodem time out after trying "
+ << value << " times";
+ break;
+ case RmtCancel:
+ /* remote end has cancelled */
+ FQ_TRACE("zmodem", 1) << "Zmodem canceled by remote peer";
+ break;
+ case ProtocolErr:
+ /* protocol error has occurred, val=hdr */
+ FQ_TRACE("zmodem", 0) << "Unhandled header " << value
+ << " at state " << status;
+ break;
+ case RemoteMessage:
+ /* message from remote end */
+ FQ_TRACE("zmodem", 0) << "Message from remote peer: " << status;
+ break;
+ case DataErr:
+ /* data error, val=error count */
+ FQ_TRACE("zmodem", 0) << "Data errors " << value;
+ break;
+ case FileErr:
+ /* error writing file, val=errno */
+ FQ_TRACE("zmodem", 0) << "Falied to write file.";
+ break;
+ case FileBegin:
+ /* file transfer begins, str=name */
+ FQ_TRACE("zmodem", 0) << "Starting file: " << status;
+ break;
+ case FileEnd:
+ /* file transfer ends, str=name */
+ FQ_TRACE("zmodem", 0) << "Finishing file: " << status;
+ break;
+ case FileSkip:
+ /* file being skipped, str=name */
+ FQ_TRACE("zmodem", 0) << "Skipping file: " << status;
+ break;
+ }
+}
+
+FILE *FQTermZmodem::ZOpenFile(char *name, ulong crc, ZModem *info) {
+ //to be complete
+ FILE *rval;
+ int apnd = 0;
+ QString strText;
+ strText = encoding2unicode(name, serverEncodingID);
+ QString str = FQTermPref::getInstance()->zmodemDir_ + strText;
+
+ QString zpath = QFileInfo(FQTermPref::getInstance()->zmodemDir_).absoluteFilePath();
+ QString path = QFileInfo(str).absoluteFilePath();
+
+ lastDownloadedFilename_ = path;
+
+ if (path.startsWith(zpath)) {
+ // Ensure that file is only saved under zmodemDir_.
+ // TODO: lazy, should use bbs2unicode
+ rval = fopen(str.toLocal8Bit(), apnd ? "ab" : "wb");
+ } else {
+ rval = NULL;
+ }
+
+ if (rval == NULL) {
+ perror(name);
+ }
+
+ return rval;
+}
+
+int FQTermZmodem::ZXmitHdr(int type, int format, const uchar data[4], ZModem *info) {
+ if (format == ZBIN && info->crc32) {
+ format = ZBIN32;
+ }
+
+ switch (format) {
+ case ZHEX:
+ return ZXmitHdrHex(type, data, info);
+
+ case ZBIN:
+ return ZXmitHdrBin(type, data, info);
+
+ case ZBIN32:
+ return ZXmitHdrBin32(type, data, info);
+
+ default:
+ return 0;
+ }
+}
+
+
+int FQTermZmodem::ZXmitHdrHex(int type, const uchar data[4], ZModem *info) {
+ uchar buffer[128];
+ uchar *ptr = buffer;
+ uint crc;
+ int i;
+
+ zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type],
+ data[0], data[1], data[2], data[3], ZDec4(data));
+
+ *ptr++ = ZPAD;
+ *ptr++ = ZPAD;
+ *ptr++ = ZDLE;
+ *ptr++ = ZHEX;
+
+ ptr = putHex(ptr, type);
+ crc = updcrc(type, 0);
+ for (i = 4; --i >= 0; ++data) {
+ ptr = putHex(ptr, *data);
+ crc = updcrc(*data, crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putHex(ptr, (crc >> 8) &0xff);
+ ptr = putHex(ptr, crc &0xff);
+ *ptr++ = '\r';
+ *ptr++ = '\n';
+ if (type != ZACK && type != ZFIN) {
+ *ptr++ = XON;
+ }
+
+ return ZXmitStr(buffer, ptr - buffer, info);
+}
+
+
+int FQTermZmodem::ZXmitHdrBin(int type, const uchar data[4], ZModem *info) {
+ uchar buffer[128];
+ uchar *ptr = buffer;
+ uint crc;
+ int len;
+
+ zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type],
+ data[0], data[1], data[2], data[3], ZDec4(data));
+
+ *ptr++ = ZPAD;
+ *ptr++ = ZDLE;
+ *ptr++ = ZBIN;
+
+ ptr = putZdle(ptr, type, info);
+ crc = updcrc(type, 0);
+ for (len = 4; --len >= 0; ++data) {
+ ptr = putZdle(ptr, *data, info);
+ crc = updcrc(*data, crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putZdle(ptr, (crc >> 8) &0xff, info);
+ ptr = putZdle(ptr, crc &0xff, info);
+
+ len = ptr - buffer;
+ return ZXmitStr(buffer, len, info);
+}
+
+int FQTermZmodem::ZXmitHdrBin32(int type, const uchar data[4], ZModem *info) {
+ uchar buffer[128];
+ uchar *ptr = buffer;
+ ulong crc;
+ int len;
+
+ zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type],
+ data[0], data[1], data[2], data[3], ZDec4(data));
+
+ *ptr++ = ZPAD;
+ *ptr++ = ZDLE;
+ *ptr++ = ZBIN32;
+ ptr = putZdle(ptr, type, info);
+ crc = UPDC32(type, 0xffffffffL);
+ for (len = 4; --len >= 0; ++data) {
+ ptr = putZdle(ptr, *data, info);
+ crc = UPDC32(*data, crc);
+ }
+ crc = ~crc;
+ for (len = 4; --len >= 0; crc >>= 8) {
+ ptr = putZdle(ptr, crc &0xff, info);
+ }
+
+ len = ptr - buffer;
+ return ZXmitStr(buffer, len, info);
+}
+
+
+uchar *FQTermZmodem::putZdle(uchar *ptr, uchar c, ZModem *info) {
+ uchar c2 = c &0177;
+
+ if (c == ZDLE || c2 == 020 || c2 == 021 || c2 == 023 || c2 == 0177 || (c2 ==
+ 015 && connectionType == 0 /*&& info->atSign*/) ||
+#ifdef COMMENT
+ c2 == 035 || (c2 == '~' && info->lastCR) ||
+#endif /* COMMENT */
+ c2 == 035 || (c2 < 040 && info->escCtrl)) {
+ *ptr++ = ZDLE;
+ if (c == 0177) {
+ *ptr = ZRUB0;
+ } else if (c == 0377) {
+ *ptr = ZRUB1;
+ } else {
+ *ptr = c ^ 0100;
+ }
+ } else {
+ *ptr = c;
+ }
+
+ info->atSign = c2 == '@';
+ info->lastCR = c2 == '\r';
+
+ return ++ptr;
+}
+
+
+uchar *FQTermZmodem::ZEnc4(ulong n) {
+ static uchar buf[4];
+ buf[0] = n &0xff;
+ n >>= 8;
+ buf[1] = n &0xff;
+ n >>= 8;
+ buf[2] = n &0xff;
+ n >>= 8;
+ buf[3] = n &0xff;
+ return buf;
+}
+
+ulong FQTermZmodem::ZDec4(const uchar buf[4]) {
+ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+}
+
+
+
+
+int FQTermZmodem::YrcvChar(char c, register ZModem *info) {
+ int err;
+
+ if (info->canCount >= 2) {
+ ZStatus(RmtCancel, 0, NULL);
+ return ZmErrCancel;
+ }
+
+ switch (info->state) {
+ case YREOF:
+ if (c == EOT) {
+ ZCloseFile(info);
+ info->file = NULL;
+ ZStatus(FileEnd, 0, info->filename);
+ if (info->filename != NULL) {
+ free(info->filename);
+ }
+ if ((err = acceptPacket(info)) != 0) {
+ return err;
+ }
+ info->packetCount = -1;
+ info->offset = 0;
+ info->state = YRStart;
+ return ZXmitStr((uchar*)"C", 1, info);
+ }
+ /* else, drop through */
+
+ case YRStart:
+ case YRDataWait:
+ switch (c) {
+ case SOH:
+ case STX:
+ info->pktLen = c == SOH ? (128+4): (1024+4);
+ info->state = YRData;
+ info->chrCount = 0;
+ info->timeout = 1;
+ info->noiseCount = 0;
+ info->crc = 0;
+ break;
+
+ case EOT:
+ /* ignore first EOT to protect against false eot */
+ info->state = YREOF;
+ return rejectPacket(info);
+
+ default:
+ if (++info->noiseCount > 135) {
+ return ZXmitStr(NakStr, 1, info);
+ }
+ break;
+ }
+ break;
+
+ case YRData:
+ info->buffer[info->chrCount++] = c;
+ if (info->chrCount >= info->pktLen) {
+ return ProcessPacket(info);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int FQTermZmodem::YrcvTimeout(ZModem *info) {
+ switch (info->state) {
+ case YRStart:
+ if (info->timeoutCount >= 10) {
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrInitTo;
+ }
+ return ZXmitStr((uchar*)"C", 1, info);
+
+ case YRDataWait:
+ case YREOF:
+ case YRData:
+ if (info->timeoutCount >= 10) {
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrRcvTo;
+ }
+ return ZXmitStr(NakStr, 1, info);
+ default:
+ return 0;
+ }
+}
+
+
+void FQTermZmodem::ZIdleStr(uchar *buffer, int len, ZModem *info) {
+ //to be completed
+}
+
+
+int FQTermZmodem::FinishChar(char c, register ZModem *info) {
+ if (c == 'O') {
+ if (++info->chrCount >= 2) {
+ return ZmDone;
+ }
+ } else {
+ info->chrCount = 0;
+ }
+ return 0;
+}
+
+
+
+int FQTermZmodem::DataChar(uchar c, register ZModem *info) {
+ if (c == ZDLE) {
+ info->escape = 1;
+ return 0;
+ }
+
+ if (info->escape) {
+ info->escape = 0;
+ switch (c) {
+ case ZCRCE:
+ case ZCRCG:
+ case ZCRCQ:
+ case ZCRCW:
+ info->PacketType = c;
+ info->crcCount = (info->DataType == ZBIN32) ? 4 : 2;
+ if (info->DataType == ZBIN) {
+ info->crc = updcrc(c, info->crc);
+ } else {
+ info->crc = UPDC32(c, info->crc);
+ }
+ return 0;
+ case ZRUB0:
+ c = 0177;
+ break;
+ case ZRUB1:
+ c = 0377;
+ break;
+ default:
+ c ^= 0100;
+ break;
+ }
+ }
+ if (connectionType == 0) {
+ if (lastPullByte == 0x0d && c == 0x00) {
+ lastPullByte = 0;
+ return 0;
+ } else if (lastPullByte == 0xff && c == 0xff) {
+ lastPullByte = 0;
+ return 0;
+ }
+ }
+ lastPullByte = c;
+
+ switch (info->DataType) {
+ /* TODO: are hex data packets ever used? */
+ case ZBIN:
+ info->crc = updcrc(c, info->crc);
+ if (info->crcCount == 0) {
+ info->buffer[info->chrCount++] = c;
+ } else if (--info->crcCount == 0) {
+ return ZDataReceived(info, (info->crc &0xffff) == 0);
+ }
+ break;
+
+
+ case ZBIN32:
+ info->crc = UPDC32(c, info->crc);
+ if (info->crcCount == 0) {
+ info->buffer[info->chrCount++] = c;
+ } else if (--info->crcCount == 0) {
+ return ZDataReceived(info, info->crc == 0xdebb20e3);
+ }
+ break;
+ }
+ return 0;
+}
+
+
+int FQTermZmodem::HdrChar(uchar c, register ZModem *info) {
+ int i;
+ int crc = 0;
+
+ if (c == ZDLE) {
+ info->escape = 1;
+ return 0;
+ }
+
+ if (info->escape) {
+ info->escape = 0;
+ switch (c) {
+ case ZRUB0:
+ c = 0177;
+ break;
+ case ZRUB1:
+ c = 0377;
+ break;
+ default:
+ c ^= 0100;
+ break;
+ }
+ }
+
+ if (info->chrCount == 0) {
+ /* waiting for format */
+ switch (c) {
+ case ZHEX:
+ case ZBIN:
+ case ZBIN32:
+ info->DataType = c;
+ info->chrCount = 1;
+ info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL;
+ memset(info->hdrData, 0, sizeof(info->hdrData));
+ break;
+ default:
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+ return 0;
+ }
+
+
+ switch (info->DataType) {
+ /* hex header is 14 hex digits, cr, lf. Optional xon is ignored */
+ case ZHEX:
+ if (info->chrCount <= 14 && !isxdigit(c)) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+
+ if (info->chrCount <= 14) {
+ i = (info->chrCount - 1) / 2;
+ info->hdrData[i] = rcvHex(info->hdrData[i], c);
+ }
+
+ if (info->chrCount == 16) {
+ crc = 0;
+ for (i = 0; i < 7; ++i) {
+ crc = updcrc(info->hdrData[i], crc);
+ }
+ info->InputState = Idle;
+ info->chrCount = 0;
+ if ((crc &0xffff) != 0) {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ } else {
+ return ZProtocol(info);
+ }
+ }
+ else {
+ ++info->chrCount;
+ }
+ break;
+
+
+ case ZBIN:
+ /* binary header is type, 4 bytes data, 2 bytes CRC */
+ info->hdrData[info->chrCount - 1] = c;
+ info->crc = updcrc(c, info->crc);
+ if (++info->chrCount > 7) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ if ((crc &0xffff) != 0) {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ } else {
+ return ZProtocol(info);
+ }
+ }
+ break;
+
+
+ case ZBIN32:
+ /* binary32 header is type, 4 bytes data, 4 bytes CRC */
+ info->hdrData[info->chrCount - 1] = c;
+ info->crc = UPDC32(c, info->crc);
+ if (++info->chrCount > 9) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ if (info->crc != 0xdebb20e3)
+ /* see note below */ {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ } else {
+ return ZProtocol(info);
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+
+
+
+int FQTermZmodem::IdleChar(uchar c, register ZModem *info) {
+ if (info->chrCount == 0) {
+ if (c == ZPAD) {
+ ++info->chrCount;
+ } else if (info->state == Sending && ++info->noiseCount > MaxNoise) {
+ info->waitflag = 1;
+ } else if (info->state == TStart && (c == 'C' || c == 'G' || c == NAK)) {
+ /* switch to ymodem */
+ info->state = YTStart;
+ info->InputState = Ysend;
+ info->Protocol = YMODEM;
+ return YsendChar(c, info);
+ } else {
+ ZIdleStr(&c, 1, info);
+ }
+ }
+
+ else {
+ switch (c) {
+ case ZPAD:
+ ++info->chrCount;
+ break;
+ case ZDLE:
+ info->InputState = Inhdr;
+ info->chrCount = 0;
+ break;
+ default:
+ while (--info->chrCount >= 0) {
+ ZIdleStr((uchar*)"*", 1, info);
+ }
+ info->chrCount = 0;
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+int FQTermZmodem::YsendChar(char c, ZModem *info) {
+ int err;
+
+ if (info->canCount >= 2) {
+ ZStatus(RmtCancel, 0, NULL);
+ return ZmErrCancel;
+ }
+
+ switch (info->state) {
+ case YTStart:
+ /* wait for 'G', 'C' or NAK */
+ switch (c) {
+ case 'G':
+ /* streaming YModem */
+ case 'C':
+ /* CRC YModem */
+ case NAK:
+ /* checksum YModem */
+ info->PacketType = c;
+ return ZmDone;
+ default:
+ return 0;
+ }
+
+ case YTFile:
+ /* sent filename, waiting for ACK or NAK */
+ switch (c) {
+ case NAK:
+ /* resend */
+ case 'C':
+ case 'G':
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return YSendFilename(info);
+ case ACK:
+ info->state = YTDataWait;
+ default:
+ return 0;
+ }
+
+ case YTDataWait:
+ /* sent filename, waiting for G,C or NAK */
+ switch (c) {
+ case NAK:
+ case 'C':
+ case 'G':
+ info->chrCount = 0;
+ if (info->PacketType == 'G') {
+ /* send it all at once */
+ while (info->state == YTData) {
+ if ((err = YSendData(info))) {
+ return err;
+ }
+ }
+ return 0;
+ } else {
+ return YSendData(info);
+ }
+ break;
+ default:
+ return 0;
+ }
+
+ case YTData:
+ /* sent data, waiting for ACK or NAK */
+ switch (c) {
+ case 'C':
+ case 'G':
+ /* protocol failure, resend filename */
+ if (info->Protocol == YMODEM) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ info->state = YTFile;
+ rewind(info->file);
+ return YSendFilename(info);
+ }
+ /* else XModem, treat it like a NAK */
+ case NAK:
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return YXmitData(info->buffer + info->bufp, info->ylen, info);
+ case ACK:
+ info->offset += info->ylen;
+ info->bufp += info->ylen;
+ info->chrCount -= info->ylen;
+ ZStatus(SndByteCount, info->offset, NULL);
+ return YSendData(info);
+ default:
+ return 0;
+ }
+
+ case YTEOF:
+ /* sent EOF, waiting for ACK or NAK */
+ switch (c) {
+ case NAK:
+ return ZXmitStr(eotstr, 1, info);
+ case ACK:
+ info->state = info->Protocol == YMODEM ? YTStart : Done;
+ return ZmDone;
+ default:
+ return 0;
+ }
+
+ case YTFin:
+ /* sent Fin, waiting for ACK or NAK */
+ switch (c) {
+ case NAK:
+ return YSendFin(info);
+ case ACK:
+ return ZmDone;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
+
+
+int FQTermZmodem::ZProtocol(register ZModem *info) {
+ register StateTable *table;
+
+ zmodemlog("received %s: %2.2x %2.2x %2.2x %2.2x = %lx\n",
+ hdrnames[info->hdrData[0]], info->hdrData[1], info->hdrData[2],
+ info->hdrData[3], info->hdrData[4], ZDec4(info->hdrData + 1));
+
+ /* Flags are sent in F3 F2 F1 F0 order. Data is sent in P0 P1 P2 P3 */
+
+ info->timeoutCount = 0;
+ info->noiseCount = 0;
+
+ // zmodemTimer->start(info->timeout*1000);
+
+ table = tables[(int)info->state];
+ while (table->type != 99 && table->type != info->hdrData[0]) {
+ ++table;
+ }
+
+ zmodemlog(" state %s => %s, iflush=%d, oflush=%d, call %x\n", sname(info),
+ sname2(table->newstate), table->IFlush, table->OFlush, table->func);
+
+ info->state = table->newstate;
+
+ if (table->IFlush) {
+ info->rcvlen = 0;
+ ZIFlush(info);
+ }
+ if (table->OFlush) {
+ ZOFlush(info);
+ }
+ return (this->*(table->func))(info);
+}
+
+
+int FQTermZmodem::ZDataReceived(register ZModem *info, int crcGood) {
+ switch (info->state) {
+ case RSinitWait:
+ return GotSinitData(info, crcGood);
+ case RFileName:
+ return GotFileName(info, crcGood);
+ case RData:
+ return GotFileData(info, crcGood);
+ case CommandData:
+ return GotCommandData(info, crcGood);
+ case StderrData:
+ return GotStderrData(info, crcGood);
+ default:
+ return ZPF(info);
+ }
+}
+
+
+int FQTermZmodem::ZPF(ZModem *info) {
+ info->waitflag = 1; /* pause any in-progress transmission */
+ ZStatus(ProtocolErr, info->hdrData[0], sname(info));
+ return 0;
+}
+
+
+int FQTermZmodem::Ignore(ZModem *info) {
+ return 0;
+}
+
+
+int FQTermZmodem::AnswerChallenge(register ZModem *info) {
+ return ZXmitHdrHex(ZACK, info->hdrData + 1, info);
+}
+
+
+int FQTermZmodem::GotAbort(register ZModem *info) {
+ ZStatus(RmtCancel, 0, NULL);
+ return ZXmitHdrHex(ZFIN, zeros, info);
+}
+
+
+int FQTermZmodem::GotCancel(ZModem *info) {
+ return ZmErrCancel;
+}
+
+
+int FQTermZmodem::GotCommand(ZModem *info) {
+ uchar rbuf[4];
+ /* TODO: add command capability */
+
+
+ /// EPERM not defined????????
+
+ rbuf[0] = EPERM;
+ rbuf[1] = rbuf[2] = rbuf[3] = 0;
+ return ZXmitHdrHex(ZCOMPL, rbuf, info);
+}
+
+int FQTermZmodem::GotStderr(register ZModem *info) {
+ info->InputState = Indata;
+ info->chrCount = 0;
+ return 0;
+}
+
+
+int FQTermZmodem::RetDone(ZModem *info) {
+
+
+ return ZmDone;
+}
+
+
+int FQTermZmodem::GotCommandData(register ZModem *info, int crcGood) {
+ /* TODO */
+ return 0;
+}
+
+
+int FQTermZmodem::GotStderrData(register ZModem *info, int crcGood) {
+ info->buffer[info->chrCount] = '\0';
+ ZStatus(RemoteMessage, info->chrCount, (char*)info->buffer);
+ return 0;
+}
+
+
+int FQTermZmodem::GotFileName(ZModem *info, int crcGood) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+
+ if (!crcGood) {
+ zmodemlog("GotFileName[%s]: bad crc, send ZNAK\n", sname(info));
+ info->state = RStart;
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+
+ parseFileName(info, (char*)info->buffer);
+
+ if ((info->f1 &ZMMASK) == ZMCRC) {
+ info->state = RCrc;
+ return ZXmitHdrHex(ZCRC, zeros, info);
+ }
+
+ zmodemlog("GotFileName[%s]: good crc, call requestFile\n", sname(info));
+ info->state = RFile;
+ return requestFile(info, 0);
+}
+
+
+int FQTermZmodem::ResendCrcReq(ZModem *info) {
+ zmodemlog("ResendCrcReq[%s]: send ZCRC\n", sname(info));
+ return ZXmitHdrHex(ZCRC, zeros, info);
+}
+
+
+int FQTermZmodem::GotSinitData(ZModem *info, int crcGood) {
+ info->InputState = Idle;
+ info->chrCount = 0;
+ info->state = RStart;
+
+ zmodemlog("GotSinitData[%s]: crcGood=%d\n", sname(info), crcGood);
+
+ if (!crcGood) {
+ return ZXmitHdrHex(ZNAK, zeros, info);
+ }
+
+ if (info->attn != NULL) {
+ free(info->attn);
+ }
+ info->attn = NULL;
+ if (info->buffer[0] != '\0') {
+ info->attn = strdup((char*)info->buffer);
+ }
+ return ZXmitHdrHex(ZACK, ZEnc4(SerialNo), info);
+}
+
+
+int FQTermZmodem::ResendRpos(ZModem *info) {
+ zmodemlog("ResendRpos[%s]: send ZRPOS(%ld)\n", sname(info), info->offset);
+ return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info);
+}
+
+
+int FQTermZmodem::GotFileData(ZModem *info, int crcGood) {
+ /* OK, now what? Fushing the buffers and executing the
+ * attn sequence has likely chopped off the input stream
+ * mid-packet. Now we switch to idle mode and treat all
+ * incoming stuff like noise until we get a new valid
+ * packet.
+ */
+
+ if (!crcGood) {
+ /* oh bugger, an error. */
+ zmodemlog("GotFileData[%s]: bad crc, send ZRPOS(%ld), new state = RFile\n",
+ sname(info), info->offset);
+ ZStatus(DataErr, ++info->errCount, NULL);
+ if (info->errCount > MaxErrs) {
+ ZmodemAbort(info);
+ return ZmDataErr;
+ } else {
+ info->state = RFile;
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return fileError(info, ZRPOS, info->offset);
+ }
+ }
+
+ if (ZWriteFile(info->buffer, info->chrCount, info->file, info)) {
+ /* RED ALERT! Could not write the file. */
+ ZStatus(FileErr, zerrno, NULL);
+ info->state = RFinish;
+ info->InputState = Idle;
+ info->chrCount = 0;
+ return fileError(info, ZFERR, zerrno);
+ }
+
+ zmodemlog("GotFileData[%s]: %ld.%d,", sname(info), info->offset,
+ info->chrCount);
+ info->offset += info->chrCount;
+ ZStatus(RcvByteCount, info->offset, NULL);
+
+ /* if this was the last data subpacket, leave data mode */
+ if (info->PacketType == ZCRCE || info->PacketType == ZCRCW) {
+ zmodemlog(" ZCRCE|ZCRCW, new state RFile");
+ info->state = RFile;
+ info->InputState = Idle;
+ info->chrCount = 0;
+ } else {
+ zmodemlog(" call dataSetup");
+ (void)dataSetup(info);
+ }
+
+ if (info->PacketType == ZCRCQ || info->PacketType == ZCRCW) {
+ zmodemlog(", send ZACK\n");
+ return ZXmitHdrHex(ZACK, ZEnc4(info->offset), info);
+ } else {
+ zmodemlog("\n");
+ }
+
+ return 0;
+}
+
+int FQTermZmodem::SendRinit(ZModem *info) {
+ uchar dbuf[4];
+
+
+
+#ifdef COMMENT
+ if (info->timeoutCount >= 5)
+ /* TODO: switch to Ymodem */
+#endif /* COMMENT */
+ {
+ transferstate = transferstart;
+ }
+ //transfer would be active, it must be set to false when transfer complete or abort
+ zmodemlog("SendRinit[%s]: send ZRINIT\n", sname(info));
+
+ info->timeout = ResponseTime;
+ dbuf[0] = info->bufsize &0xff;
+ dbuf[1] = (info->bufsize >> 8) &0xff;
+ dbuf[2] = 0;
+ dbuf[3] = info->zrinitflags;
+ return ZXmitHdrHex(ZRINIT, dbuf, info);
+}
+
+
+int FQTermZmodem::SendMoreFileData(ZModem *info) {
+ int type;
+ int qfull = 0;
+ int err;
+ int len; /* max # chars to send this packet */
+ long pending; /* # of characters sent but not acknowledged */
+
+ /* ZCRCE: CRC next, frame ends, header follows
+ * ZCRCG: CRC next, frame continues nonstop
+ * ZCRCQ: CRC next, send ZACK, frame continues nonstop
+ * ZCRCW: CRC next, send ZACK, frame ends, header follows
+ */
+
+ if (info->interrupt) {
+ /* Bugger, receiver sent an interrupt. Enter a wait state
+ * and see what they want. Next header *should* be ZRPOS.
+ */
+ info->state = SendWait;
+ info->timeout = 60;
+ return 0;
+ }
+
+ /* Find out how many bytes we can transfer in the next packet */
+
+ len = info->packetsize;
+
+ pending = info->offset - info->lastOffset;
+
+ if (info->windowsize != 0 && info->windowsize - pending <= len) {
+ len = info->windowsize - pending;
+ qfull = 1;
+ }
+ if (info->bufsize != 0 && info->bufsize - pending <= len) {
+ len = info->bufsize - pending;
+ qfull = 1;
+ }
+
+ if (len == 0) {
+ /* window still full, keep waiting */
+ info->state = SendWait;
+ info->timeout = 60;
+ return 0;
+ }
+
+
+ /* OK, we can safely transmit 'len' bytes of data. Start reading
+ * file until buffer is full.
+ */
+
+ len -= 10; /* Pre-deduct 10 bytes for trailing CRC */
+
+
+ /* find out what kind of packet to send */
+ if (info->waitflag) {
+ type = ZCRCW;
+ info->waitflag = 0;
+ }
+#ifdef COMMENT
+ else if (info->fileEof) {
+ type = ZCRCE;
+ }
+#endif /* COMMENT */
+ else if (qfull) {
+ type = ZCRCW;
+ } else {
+ switch (info->Streaming) {
+ case Full:
+ case Segmented:
+ type = ZCRCG;
+ break;
+
+ case StrWindow:
+ if ((info->windowCount += len) < info->windowsize / 4) {
+ type = ZCRCG;
+ } else {
+ type = ZCRCQ;
+ info->windowCount = 0;
+ }
+ break;
+
+ default:
+ case SlidingWindow:
+ type = ZCRCQ;
+ break;
+ }
+ }
+
+ {
+ int crc32 = info->crc32;
+ int c = 0, c2, atSign = 0;
+ ulong crc;
+ uchar *ptr = info->buffer;
+
+ crc = crc32 ? 0xffffffff : 0;
+
+ /* read characters from file and put into buffer until buffer is
+ * full or file is exhausted
+ */
+
+
+ while (len > 0 && (c = getc(info->file)) != EOF) {
+ if (!crc32) {
+ crc = updcrc(c, crc);
+ } else {
+ crc = UPDC32(c, crc);
+ }
+
+ /* zmodem protocol requires that CAN(ZDLE), DLE, XON, XOFF and
+ * a CR following '@' be escaped. In addition, I escape '^]'
+ * to protect telnet, "<CR>~." to protect rlogin, and ESC for good
+ * measure.
+ */
+ c2 = c &0177;
+ if (c == ZDLE || c2 == 020 || c2 == 021 || c2 == 023 || c2 == 0177 || c2 ==
+ '\r' || c2 == '\n' || c2 == 033 || c2 == 035 || (c2 < 040 && info->escCtrl)) {
+ *ptr++ = ZDLE;
+ if (c == 0177) {
+ *ptr = ZRUB0;
+ } else if (c == 0377) {
+ *ptr = ZRUB1;
+ } else {
+ *ptr = c ^ 0100;
+ }
+ len -= 2;
+ } else {
+ *ptr = c;
+ --len;
+ }
+ ++ptr;
+
+ atSign = c2 == '@';
+ ++info->offset;
+ }
+
+ /* if we've reached file end, a ZEOF header will follow. If
+ * there's room in the outgoing buffer for it, end the packet
+ * with ZCRCE and append the ZEOF header. If there isn't room,
+ * we'll have to do a ZCRCW
+ */
+ if ((info->fileEof = (c == EOF))) {
+ if (qfull || (info->bufsize != 0 && len < 24)) {
+ type = ZCRCW;
+ } else {
+ type = ZCRCE;
+ }
+ }
+
+ *ptr++ = ZDLE;
+ if (!crc32) {
+ crc = updcrc(type, crc);
+ } else {
+ crc = UPDC32(type, crc);
+ }
+ *ptr++ = type;
+
+ if (!crc32) {
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putZdle(ptr, (crc >> 8) &0xff, info);
+ ptr = putZdle(ptr, crc &0xff, info);
+ } else {
+ crc = ~crc;
+ for (len = 4; --len >= 0; crc >>= 8) {
+ ptr = putZdle(ptr, crc &0xff, info);
+ }
+ }
+
+ len = ptr - info->buffer;
+ }
+
+ ZStatus(SndByteCount, info->offset, NULL);
+
+ if ((err = ZXmitStr(info->buffer, len, info))) {
+ return err;
+ }
+
+#ifdef COMMENT
+ if ((err = ZXmitData(ZBIN, len, uchar(type), info->buffer, info))) {
+ return err;
+ }
+#endif /* COMMENT */
+
+ /* finally, do we want to wait after this packet? */
+
+ switch (type) {
+ case ZCRCE:
+ info->state = SendEof;
+ info->timeout = 60;
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+ case ZCRCW:
+ info->state = info->fileEof ? SendDone : SendWait;
+ info->timeout = 60;
+ break;
+ default:
+ info->state = Sending;
+ info->timeout = 0;
+ break;
+ }
+
+
+#ifdef COMMENT
+ if (info->fileEof) {
+ /* Yes, file is done, send EOF and wait */
+ info->state = SendEof;
+ info->timeout = 60;
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+ } else if (type == ZCRCW) {
+ info->state = SendWait;
+ info->timeout = 60;
+ } else {
+ info->state = Sending;
+ info->timeout = 0;
+ }
+#endif /* COMMENT */
+ return 0;
+}
+
+
+uint FQTermZmodem::rcvHex(uint i, char c) {
+ if (c <= '9') {
+ c -= '0';
+ } else if (c <= 'F') {
+ c -= 'A' - 10;
+ } else {
+ c -= 'a' - 10;
+ }
+ return (i << 4) + c;
+}
+
+
+int FQTermZmodem::dataSetup(register ZModem *info) {
+ info->InputState = Indata;
+ info->chrCount = 0;
+ info->crcCount = 0;
+ info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL;
+ return 0;
+}
+
+int FQTermZmodem::ZWriteFile(uchar *buffer, int len, FILE *file, ZModem*) {
+ return (int)fwrite(buffer, 1, len, file) == len ? 0 : ZmErrSys;
+}
+
+int FQTermZmodem::ZCloseFile(ZModem *info) {
+ //to be completed
+ fclose(info->file);
+ return 0;
+}
+
+void FQTermZmodem::ZFlowControl(int onoff, ZModem *info) {
+ //to be completed
+}
+
+int FQTermZmodem::GotSinit(ZModem *info) {
+ zmodemlog("GotSinit[%s]: call dataSetup\n", sname(info));
+
+ info->zsinitflags = info->hdrData[4];
+ info->escCtrl = info->zsinitflags &TESCCTL;
+ info->escHibit = info->zsinitflags &TESC8;
+ ZFlowControl(1, info);
+ return dataSetup(info);
+}
+
+int FQTermZmodem::GotFile(ZModem *info) {
+ zmodemlog("GotFile[%s]: call dataSetup\n", sname(info));
+
+ info->errCount = 0;
+ info->f0 = info->hdrData[4];
+ info->f1 = info->hdrData[3];
+ info->f2 = info->hdrData[2];
+ info->f3 = info->hdrData[1];
+ return dataSetup(info);
+}
+
+int FQTermZmodem::GotFin(ZModem *info) {
+ int i;
+ zmodemlog("GotFin[%s]: send ZFIN\n", sname(info));
+ info->InputState = Finish;
+ info->chrCount = 0;
+ if (info->filename != NULL) {
+ free(info->filename);
+ }
+ i = ZXmitHdrHex(ZFIN, zeros, info);
+ ZmodemReset(info);
+ transferstate = transferstop; // transfer complete
+ return i;
+}
+
+
+int FQTermZmodem::GotData(ZModem *info) {
+ int err;
+
+ zmodemlog("GotData[%s]:\n", sname(info));
+
+ if (ZDec4(info->hdrData + 1) != info->offset) {
+ if (info->attn != NULL && (err = ZAttn(info)) != 0) {
+ return err;
+ }
+ zmodemlog(" bad, send ZRPOS(%ld)\n", info->offset);
+ return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info);
+ }
+
+ /* Let's do it! */
+ zmodemlog(" call dataSetup\n");
+ return dataSetup(info);
+}
+
+int FQTermZmodem::GotEof(ZModem *info) {
+ zmodemlog("GotEof[%s]: offset=%ld\n", sname(info), info->offset);
+ if (ZDec4(info->hdrData + 1) != info->offset) {
+ zmodemlog("zdec4(info->hdrdata+1)=%ld\n", ZDec4(info->hdrData + 1));
+ zmodemlog(" bad length, state = RFile\n");
+ info->state = RFile;
+ return 0; /* it was probably spurious */
+ }
+
+ /* TODO: if we can't close the file, send a ZFERR */
+
+ ZCloseFile(info);
+ info->file = NULL;
+ ZStatus(FileEnd, 0, info->filename);
+ if (info->filename != NULL) {
+ free(info->filename);
+ info->filename = NULL;
+ }
+ return SendRinit(info);
+}
+
+int FQTermZmodem::GotFreecnt(ZModem *info) {
+ /* TODO: how do we find free space on system? */
+ return ZXmitHdrHex(ZACK, ZEnc4(0xffffffff), info);
+}
+
+
+int FQTermZmodem::GotFileCrc(ZModem *info) {
+ zmodemlog("GotFileCrc[%s]: call requestFile\n", sname(info));
+ return requestFile(info, ZDec4(info->hdrData + 1));
+}
+
+int FQTermZmodem::requestFile(ZModem *info, ulong crc) {
+ info->file = ZOpenFile((char*)info->buffer, crc, info);
+
+ if (info->file == NULL) {
+ zmodemlog("requestFile[%s]: send ZSKIP\n", sname(info));
+
+ info->state = RStart;
+ ZStatus(FileSkip, 0, info->filename);
+ return ZXmitHdrHex(ZSKIP, zeros, info);
+ } else {
+ zmodemlog("requestFile[%s]: send ZRPOS(%ld)\n", sname(info), info->offset);
+ info->offset = info->f0 == ZCRESUM ? ftell(info->file): 0;
+ info->state = RFile;
+ ZStatus(FileBegin, info->len, info->filename);
+ return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info);
+ }
+}
+
+void FQTermZmodem::parseFileName(ZModem *info, char *fileinfo) {
+ char *ptr;
+ int serial = 0;
+
+ info->len = info->mode = info->filesRem = info->bytesRem = info->fileType = 0;
+ ptr = fileinfo + strlen(fileinfo) + 1;
+ if (info->filename != NULL) {
+ free(info->filename);
+ }
+ info->filename = strdup(fileinfo);
+ sscanf(ptr, "%d %lo %o %o %d %d %d", &info->len, &info->date, &info->mode,
+ &serial, &info->filesRem, &info->bytesRem, &info->fileType);
+}
+
+
+
+int FQTermZmodem::fileError(ZModem *info, int type, int data) {
+ int err;
+
+ info->InputState = Idle;
+ info->chrCount = 0;
+
+ if (info->attn != NULL && (err = ZAttn(info)) != 0) {
+ return err;
+ }
+ return ZXmitHdrHex(type, ZEnc4(data), info);
+}
+
+
+int FQTermZmodem::ProcessPacket(ZModem *info) {
+ int idx = (uchar)info->buffer[0];
+ int idxc = (uchar)info->buffer[1];
+ int crc0, crc1;
+ int err;
+
+ info->state = YRDataWait;
+
+ if (idxc != 255-idx) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return rejectPacket(info);
+ }
+
+ if (idx == (info->packetCount % 256))
+ /* quietly ignore dup */ {
+ return acceptPacket(info);
+ }
+
+ if (idx != (info->packetCount + 1) % 256) {
+ /* out of sequence */
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrSequence;
+ }
+
+ crc0 = (uchar)info->buffer[info->pktLen - 2] << 8
+ | (uchar)info->buffer[info->pktLen - 1];
+ crc1 = calcCrc(info->buffer + 2, info->pktLen - 4);
+ if (crc0 != crc1) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ return rejectPacket(info);
+ }
+
+ ++info->packetCount;
+
+ if (info->packetCount == 0) {
+ /* packet 0 is filename */
+ if (info->buffer[2] == '\0') {
+ /* null filename is FIN */
+ (void)acceptPacket(info);
+ return ZmDone;
+ }
+
+ parseFileName(info, (char*)info->buffer + 2);
+ info->file = ZOpenFile(info->filename, 0, info);
+ if (info->file == NULL) {
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrCantOpen;
+ }
+ if ((err = acceptPacket(info)) != 0) {
+ return err;
+ }
+ return ZXmitStr((uchar*)"C", 1, info);
+ }
+
+
+ if (ZWriteFile(info->buffer + 2, info->pktLen - 4, info->file, info)) {
+ ZStatus(FileErr, zerrno, NULL);
+ (void)ZXmitStr(CanStr, 2, info);
+ return ZmErrSys;
+ }
+ info->offset += info->pktLen - 4;
+ ZStatus(RcvByteCount, info->offset, NULL);
+
+ (void)acceptPacket(info);
+ return 0;
+}
+
+int FQTermZmodem::rejectPacket(ZModem *info) {
+ info->timeout = 10;
+ return ZXmitStr(NakStr, 1, info);
+}
+
+
+int FQTermZmodem::acceptPacket(ZModem *info) {
+ info->state = YRDataWait;
+ info->timeout = 10;
+ return ZXmitStr(AckStr, 1, info);
+}
+
+
+int FQTermZmodem::calcCrc(uchar *str, int len) {
+ int crc = 0;
+ while (--len >= 0) {
+ crc = updcrc(*str++, crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ return crc &0xffff;
+}
+
+
+char *FQTermZmodem::strdup(const char *str) {
+ char *rval;
+ int len = strlen(str) + 1;
+ rval = (char*)malloc(len);
+ strcpy(rval, str);
+ return rval;
+}
+
+
+int FQTermZmodem::ZXmitData(int format, int len, uchar term, uchar *data, ZModem
+ *info) {
+ uchar *ptr = info->buffer;
+ uint crc;
+
+ if (format == ZBIN && info->crc32) {
+ format = ZBIN32;
+ }
+
+ zmodemlog("ZXmiteData: fmt=%c, len=%d, term=%c\n", format, len, term);
+
+ crc = (format == ZBIN) ? 0 : 0xffffffff;
+
+ while (--len >= 0) {
+ if (format == ZBIN) {
+ crc = updcrc(*data, crc);
+ } else {
+ crc = UPDC32(*data, crc);
+ }
+ ptr = putZdle(ptr, *data++, info);
+ }
+
+ *ptr++ = ZDLE;
+ if (format == ZBIN) {
+ crc = updcrc(term, crc);
+ } else {
+ crc = UPDC32(term, crc);
+ }
+ *ptr++ = term;
+ if (format == ZBIN) {
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ ptr = putZdle(ptr, (crc >> 8) &0xff, info);
+ ptr = putZdle(ptr, crc &0xff, info);
+ } else {
+ crc = ~crc;
+ for (len = 4; --len >= 0; crc >>= 8) {
+ ptr = putZdle(ptr, crc &0xff, info);
+ }
+ }
+
+ return ZXmitStr(info->buffer, ptr - info->buffer, info);
+}
+
+
+
+int FQTermZmodem::YXmitData(uchar *buffer, int len, ZModem *info) {
+ uchar hdr[3];
+ uchar trail[2];
+ ulong crc = 0;
+ int i, err;
+
+ hdr[0] = len == 1024 ? STX : SOH;
+ hdr[1] = info->packetCount;
+ hdr[2] = ~hdr[1];
+ if ((err = ZXmitStr(hdr, 3, info)) || (err = ZXmitStr(buffer, len, info))) {
+ return err;
+ }
+
+ if (info->PacketType == NAK) {
+ /* checksum */
+ for (i = 0; i < len; ++i) {
+ crc += buffer[i];
+ }
+ trail[0] = crc % 256;
+ return ZXmitStr(trail, 1, info);
+ } else {
+ for (i = 0; i < len; ++i) {
+ crc = updcrc(buffer[i], crc);
+ }
+ crc = updcrc(0, crc);
+ crc = updcrc(0, crc);
+ trail[0] = crc / 256;
+ trail[1] = crc % 256;
+ return ZXmitStr(trail, 2, info);
+ }
+}
+
+
+int FQTermZmodem::YSendFilename(ZModem *info) {
+ int i, len;
+ uchar obuf[1024];
+ uchar *ptr = obuf;
+
+ info->state = info->PacketType != 'G' ? YTFile : YTDataWait;
+ info->packetCount = 0;
+ info->offset = 0;
+
+ i = strlen(info->rfilename);
+ memcpy(ptr, info->rfilename, i + 1);
+ ptr += i + 1;
+ sprintf((char*)ptr, "%d %lo %o 0", info->len, info->date, info->mode);
+ ptr += strlen((char*)ptr);
+ *ptr++ = '\0';
+ /* pad out to 128 bytes or 1024 bytes */
+ i = ptr - obuf;
+ len = i > 128 ? 1024 : 128;
+ for (; i < len; ++i) {
+ *ptr++ = '\0';
+ }
+
+ return YXmitData(obuf, len, info);
+}
+
+int FQTermZmodem::YSendData(ZModem *info) {
+ int i;
+
+ /* are there characters still in the read buffer? */
+
+ if (info->chrCount <= 0) {
+ info->bufp = 0;
+ info->chrCount = fread(info->buffer, 1, info->packetsize, info->file);
+ info->fileEof = feof(info->file);
+ }
+
+ if (info->chrCount <= 0) {
+ fclose(info->file);
+ info->state = YTEOF;
+ return ZXmitStr(eotstr, 1, info);
+ }
+
+ /* pad out to 128 bytes if needed */
+ if (info->chrCount < 128) {
+ i = 128-info->chrCount;
+ memset(info->buffer + info->bufp + info->chrCount, 0x1a, i);
+ info->chrCount = 128;
+ }
+
+ info->ylen = info->chrCount >= 1024 ? 1024 : 128;
+ ++info->packetCount;
+
+ info->state = YTData;
+
+ return YXmitData(info->buffer + info->bufp, info->ylen, info);
+}
+
+
+int FQTermZmodem::YSendFin(ZModem *info) {
+ uchar obuf[128];
+
+ info->state = YTFin;
+ info->packetCount = 0;
+
+ memset(obuf, 0, 128);
+
+ return YXmitData(obuf, 128, info);
+}
+
+int FQTermZmodem::sendFilename(ZModem *info) {
+ int err;
+ int i;
+ uchar obuf[2048];
+ uchar *ptr = obuf;
+
+ info->state = FileWait;
+
+ if ((err = ZXmitHdr(ZFILE, ZBIN, info->fileFlags, info))) {
+ return err;
+ }
+
+ i = strlen(info->rfilename);
+ memcpy(ptr, info->rfilename, i + 1);
+ ptr += i + 1;
+ sprintf((char*)ptr, "%d %lo %o 0 %d %d 0", info->len, info->date, info->mode,
+ info->filesRem, info->bytesRem);
+ ptr += strlen((char*)ptr);
+ *ptr++ = '\0';
+
+ return ZXmitData(ZBIN, ptr - obuf, ZCRCW, obuf, info);
+}
+
+int FQTermZmodem::GotRinit(ZModem *info) {
+ if (strFileList.count() == 0) {
+ return ZmodemTFinish(info);
+ }
+
+
+ info->bufsize = info->hdrData[1] + info->hdrData[2] *256;
+ info->zrinitflags = info->hdrData[4] + info->hdrData[3] *256;
+ info->crc32 = info->zrinitflags &CANFC32;
+ info->escCtrl = info->zrinitflags &ESCCTL;
+ info->escHibit = info->zrinitflags &ESC8;
+
+ /* Full streaming: If receiver can overlap I/O, and if
+ * the sender can sample the reverse channel without hanging,
+ * and the receiver has not specified a buffer size, then we
+ * can simply blast away with ZCRCG packets. If the receiver
+ * detects an error, it sends an attn sequence and a new ZRPOS
+ * header to restart the file where the error occurred.
+ *
+ * [note that zmodem8.doc does not define how much noise is
+ * required to trigger a ZCRCW packet. We arbitrarily choose
+ * 64 bytes]
+ *
+ * If 'windowsize' is nonzero, and the receiver can do full
+ * duplex, ZCRCQ packets are sent instead of ZCRCG, to keep track
+ * of the number of characters in the queue. If the queue fills
+ * up, we pause and wait for a ZACK.
+ *
+ *
+ * Full Streaming with Reverse Interrupt: If sender cannot
+ * sample the input stream, then we define an Attn sequence
+ * that will be used to interrupt transmission.
+ *
+ *
+ * Full Streaming with Sliding Window: If sender cannot
+ * sample input stream or respond to Attn signal, we send
+ * several ZCRCQ packets until we're sure the receiver must
+ * have sent back at least one ZACK. Then we stop sending and
+ * read that ZACK. Then we send one more packet and so on.
+ *
+ *
+ * Segmented Streaming: If receiver cannot overlap I/O or can't do
+ * full duplex and has specified a maximum receive buffer size,
+ * whenever the buffer size is reached, we send a ZCRCW packet.
+ *
+ * TODO: what if receiver can't overlap, but hasn't set a buffer
+ * size?
+ *
+ * ZCRCE: CRC next, frame ends, header follows
+ * ZCRCG: CRC next, frame continues nonstop
+ * ZCRCQ: CRC next, send ZACK, frame continues nonstop
+ * ZCRCW: CRC next, send ZACK, frame ends, header follows
+ */
+
+ transferstate = transferstart;
+
+ ZFlowControl(1, info);
+
+ if ((info->zrinitflags &(CANFDX | CANOVIO)) == (CANFDX | CANOVIO) &&
+ (SendSample || SendAttn) && info->bufsize == 0) {
+ if (info->windowsize == 0) {
+ info->Streaming = Full;
+ } else {
+ info->Streaming = StrWindow;
+ }
+ }
+
+ else if ((info->zrinitflags &(CANFDX | CANOVIO)) == (CANFDX | CANOVIO) &&
+ info->bufsize == 0) {
+ info->Streaming = SlidingWindow;
+ }
+
+ else {
+ info->Streaming = Segmented;
+ }
+ // get filenames to transfer
+ zmodemlog("GotRinit[%s]\n", sname(info));
+
+ if (AlwaysSinit || info->zsinitflags != 0 || info->attn != NULL) {
+ SendZSInit(info);
+ }
+
+
+ itFile = strFileList.begin();
+ QFileInfo fi(*itFile);
+ FQ_TRACE("zmodem", 0) << "Number of files to be transfered: "
+ << strFileList.count();
+ char *filename = strdup(fi.absoluteFilePath().toLatin1());
+ char *rfilename = strdup(fi.fileName().toLatin1());
+ ZmodemTFile(filename, rfilename, 0, 0, 0, 0, strFileList.count(), fi.size(),
+ info);
+ strFileList.erase(itFile);
+ return ZmDone;
+}
+
+
+int FQTermZmodem::SendZSInit(ZModem *info) {
+ char tmp = '\0';
+ int err;
+ //char *at = (info->attn != NULL) ? info->attn : "" ;
+ char *at;
+ if (info->attn != NULL) {
+ at = info->attn;
+ } else {
+ at = &tmp;
+ }
+ uchar fbuf[4];
+
+ /* TODO: zmodem8.doc states: "If the ZSINIT header specifies
+ * ESCCTL or ESC8, a HEX header is used, and the receiver
+ * activates the specified ESC modes before reading the following
+ * data subpacket." What does that mean?
+ */
+
+ zmodemlog("SendZSInit[%s]\n", sname(info));
+
+ info->state = TInit;
+ fbuf[0] = fbuf[1] = fbuf[2] = 0;
+ fbuf[3] = info->zsinitflags;
+ if ((err = ZXmitHdr(ZSINIT, ZBIN, fbuf, info)) || (err = ZXmitData(ZBIN,
+ strlen(at) + 1, ZCRCW, (uchar*)at, info))) {
+ return err;
+ }
+ return 0;
+}
+
+
+int FQTermZmodem::SendFileCrc(ZModem *info) {
+ ulong crc;
+
+ crc = FileCrc(info->filename);
+
+ zmodemlog("SendFileCrc[%s]: %lx\n", sname(info), crc);
+
+ return ZXmitHdrHex(ZCRC, ZEnc4(crc), info);
+}
+
+int FQTermZmodem::GotSendAck(ZModem *info) {
+ ulong offset;
+
+ offset = ZDec4(info->hdrData + 1);
+
+ if (offset > info->lastOffset) {
+ info->lastOffset = offset;
+ }
+
+ zmodemlog("GotSendAck[%s]: %lx\n", sname(info), info->offset);
+
+ return 0; /* DONT send more data, that will happen
+ * later anyway */
+}
+
+int FQTermZmodem::GotSendDoneAck(ZModem *info) {
+ ulong offset;
+
+ offset = ZDec4(info->hdrData + 1);
+
+ if (offset > info->lastOffset) {
+ info->lastOffset = offset;
+ }
+
+ zmodemlog("GotSendDoneAck[%s]: %ld\n", sname(info), info->offset);
+
+ info->state = SendEof;
+ info->timeout = 60;
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+}
+
+int FQTermZmodem::GotSendNak(ZModem *info) {
+ info->offset = info->zrposOffset;
+
+ fseek(info->file, info->offset, 0);
+
+ /* TODO: what if fseek fails? Send EOF? */
+
+ zmodemlog("GotSendNak[%s]: %ld\n", sname(info), info->offset);
+
+ return SendMoreFileData(info);
+}
+
+int FQTermZmodem::GotSendWaitAck(ZModem *info) {
+
+ ulong offset;
+ int err;
+
+ offset = ZDec4(info->hdrData + 1);
+
+ FQ_TRACE("zmodem", 10) << "last = " << info->lastOffset
+ << ", now = " << offset;
+
+ if (offset > info->lastOffset) {
+ info->lastOffset = offset;
+ }
+
+ //receiver return -1 without setting this flag, kingson 00:07 14-07-04
+ info->waitflag = 1;
+
+ zmodemlog("GotSendWaitAck[%s]\n", sname(info), offset);
+
+ if ((err = ZXmitHdr(ZDATA, ZBIN, info->hdrData + 1, info))) {
+ return err;
+ }
+ return SendMoreFileData(info);
+}
+
+int FQTermZmodem::SkipFile(ZModem *info) {
+ zmodemlog("SkipFile[%s]\n", sname(info));
+ ZStatus(FileEnd, 0, info->rfilename);
+ fclose(info->file);
+
+ // stupid SMTH doesnt send further command, kick
+ // lets send files in the list
+ info->state = TStart;
+ return GotRinit(info);
+}
+
+int FQTermZmodem::GotSendPos(ZModem *info) {
+ ZStatus(DataErr, ++info->errCount, NULL);
+ info->waitflag = 1; /* next pkt should wait, to resync */
+ FQ_TRACE("zmodem", 9) << "GotSendPos, offset = " << info->offset;
+ zmodemlog("GotSendPos[%s] %lx\n", sname(info), info->offset);
+ return startFileData(info);
+}
+
+int FQTermZmodem::SendFileData(ZModem *info) {
+ info->waitflag = 0;
+ return startFileData(info);
+}
+
+int FQTermZmodem::ResendEof(ZModem *info) {
+ return ZXmitHdrHex(ZEOF, ZEnc4(info->offset), info);
+}
+
+int FQTermZmodem::OverAndOut(ZModem *info) {
+ zmodemlog("OverAndOut[%s]\n", sname(info));
+
+ ZXmitStr((uchar*)"OO", 2, info);
+
+ transferstate = transferstop; // transfer complete
+
+ ZmodemReset(info); //Tranfer complete, zmodem return to receive state
+
+ return ZmDone;
+}
+
+int FQTermZmodem::startFileData(ZModem *info) {
+ int err;
+
+ info->offset = info->lastOffset = info->zrposOffset = ZDec4(info->hdrData + 1);
+
+ fseek(info->file, info->offset, 0);
+
+ /* TODO: what if fseek fails? Send EOF? */
+
+ zmodemlog("startFileData[%s]: %lx\n", sname(info), info->offset);
+
+ if ((err = ZXmitHdr(ZDATA, ZBIN, ZEnc4(info->offset), info))) {
+ return err;
+ }
+ return SendMoreFileData(info);
+}
+
+uchar *FQTermZmodem::putHex(uchar *ptr, uchar c) {
+ *ptr++ = hexChars[(c >> 4) &0xf];
+ *ptr++ = hexChars[c &0xf];
+ return ptr;
+}
+
+
+int FQTermZmodem::ZmodemReset(ZModem *info) {
+ zmodemlog("\nZmodemReset\n");
+
+ ZmodemRInit(info);
+
+ return 0;
+}
+
+
+void FQTermZmodem::zmodemlog(const char *fmt, ...) {
+ // only for debug
+#ifdef FQTERM_ZMODEM_DEBUG
+ va_list ap;
+ struct timeval tv;
+ struct tm *tm;
+ static int do_ts = 1;
+
+ zmodemlogfile = fopen("zmodem.log", "a");
+
+ if (zmodemlogfile == NULL) {
+ return ;
+ }
+
+ if (do_ts) {
+ gettimeofday(&tv, NULL);
+ tm = localtime(&tv.tv_sec);
+ fprintf(zmodemlogfile, "%2.2d:%2.2d:%2.2d.%2.2ld: ", tm->tm_hour, tm->tm_min,
+ tm->tm_sec, tv.tv_usec / 10000);
+ }
+ do_ts = strchr(fmt, '\n') != NULL;
+
+ va_start(ap, fmt);
+ vfprintf(zmodemlogfile, fmt, ap);
+ va_end(ap);
+
+ fclose(zmodemlogfile);
+#endif
+
+}
+
+void FQTermZmodem::zmodemCancel() {
+ ZmodemAbort(&info);
+}
+
+} // namespace FQTerm
+
+#include "fqterm_zmodem.moc"
+
diff --git a/src/terminal/internal/fqterm_zmodem.h b/src/terminal/internal/fqterm_zmodem.h
new file mode 100644
index 0000000..bd1f4f4
--- /dev/null
+++ b/src/terminal/internal/fqterm_zmodem.h
@@ -0,0 +1,623 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ZMODEM_H
+#define FQTERM_ZMODEM_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <QByteArray>
+#include <QObject>
+#include <QTimer>
+#include <QFile>
+#include <QStringList>
+
+namespace FQTerm {
+
+/* PARAMETERS
+ *
+ * The following #defines control the behavior of the Zmodem
+ * package. Note that these may be replaced with variables
+ * if you like. For example, "#define DoInitRZ" may be replaced
+ * with "extern int DoInitRz" to use a global variable, or with
+ * "#define DoInitRZ (info->doInitRz)" to use a variable you
+ * add to the ZModem structure.
+ *
+ * It is assumed that the compiler is good enough to optimize
+ * "if( 0 )" and "if( 1 )" cases. If not, you may wish to modify
+ * the source code to use #ifdef instead.
+ */
+
+#define DoInitRZ 1 /* send initial "rz\r" when transmitting */
+#define AllowCommand 0 /* allow remote end to execute commands */
+#define SendSample 1 /* sender can sample reverse channel */
+#define SendAttn 1 /* sender can be interrupted with Attn signal */
+#define ResponseTime 10 /* reasonable response time for sender to
+ * respond to requests from receiver */
+#define SerialNo 1 /* receiver serial # */
+#define MaxNoise 64 /* max "noise" characters before transmission
+ * pauses */
+#define MaxErrs 30 /* Max receive errors before cancel */
+#define AlwaysSinit 1 /* always send ZSINIT header, even if not
+ * needed, this makes protocol more robust */
+
+#define SendOnly 0 /* compiles smaller version for send only */
+#define RcvOnly 0 /* compiles smaller version for receive only */
+
+enum enum_InputState {
+ Idle, Padding, Inhdr, Indata, Finish, Ysend, Yrcv
+};
+enum enum_Protocol {
+ XMODEM, YMODEM, ZMODEM
+};
+enum enum_Streaming {
+ Full, StrWindow, SlidingWindow, Segmented
+};
+enum enum_transferstate {
+ notransfer, transferstart, transferstop
+};
+
+
+/* Internal State */
+
+typedef enum zmstate {
+ /* receive */
+ RStart, /* sent RINIT, waiting for ZFILE or SINIT */
+ RSinitWait, /* got SINIT, waiting for data */
+ RFileName, /* got ZFILE, waiting for filename & info */
+ RCrc, /* got filename, want crc too */
+ RFile, /* got filename, ready to read */
+ RData, /* reading data */
+ RDataErr, /* encountered error, ignoring input */
+ RFinish, /* sent ZFIN, waiting for 'OO' */
+
+ /* transmit */
+ TStart, /* waiting for INIT frame from other end */
+ TInit, /* received INIT, sent INIT, waiting for ZACK */
+ FileWait, /* sent file header, waiting for ZRPOS */
+ CrcWait, /* sent file crc, waiting for ZRPOS */
+ Sending, /* sending data subpackets, ready for int */
+ SendWait, /* waiting for ZACK */
+ SendDone, /* file finished, need to send EOF */
+ SendEof, /* sent EOF, waiting for ZACK */
+ TFinish, /* sent ZFIN, waiting for ZFIN */
+
+ /* general */
+ CommandData, /* waiting for command data */
+ CommandWait, /* waiting for command to execute */
+ StderrData, /* waiting for stderr data */
+ Done,
+
+ /* x/ymodem transmit */
+ YTStart, /* waiting for 'G', 'C' or NAK */
+ YTFile, /* sent filename, waiting for ACK */
+ YTDataWait, /* ready to send data, waiting for 'C' */
+ YTData, /* sent data, waiting for ACK */
+ YTEOF, /* sent eof, waiting for ACK */
+ YTFin, /* sent null filename, waiting for ACK */
+
+ /* x/ymodem receive */
+ YRStart, /* sent 'C', waiting for filename */
+ YRDataWait, /* received filename, waiting for data */
+ YRData, /* receiving filename or data */
+ YREOF /* received first EOT, waiting for 2nd */
+
+} ZMState;
+
+
+
+
+typedef struct {
+ int ifd; /* input fd, for use by caller's routines */
+ int ofd; /* output fd, for use by caller's routines */
+ FILE *file; /* file being transfered */
+ int zrinitflags; /* receiver capabilities, see below */
+ int zsinitflags; /* sender capabilities, see below */
+ char *attn; /* attention string, see below */
+ int timeout; /* timeout value, in seconds */
+ int bufsize; /* receive buffer size, bytes */
+ int packetsize; /* preferred transmit packet size */
+ int windowsize; /* max window size */
+
+ /* file attributes: read-only */
+
+ int filesRem, bytesRem;
+ uchar f0, f1, f2, f3; /* file flags */
+ int len, mode, fileType; /* file flags */
+ ulong date; /* file date */
+
+ /* From here down, internal to Zmodem package */
+
+ ZMState state; /* protocol internal state */
+ char *filename; /* filename */
+ char *rfilename; /* remote filename */
+ int crc32; /* use 32-bit crc */
+ int pktLen; /* length of this packet */
+ int DataType; /* input data type */
+ int PacketType; /* type of this packet */
+ int rcvlen;
+ int chrCount; /* chars received in current header/buffer */
+ int crcCount; /* crc characters remaining at end of buffer */
+ int canCount; /* how many CAN chars received? */
+ int noiseCount; /* how many noise chars received? */
+ int errorFlush; /* ignore incoming data because of error */
+ uchar *buffer; /* data buffer */
+ ulong offset; /* file offset */
+ ulong lastOffset; /* last acknowledged offset */
+ ulong zrposOffset; /* last offset specified w/zrpos */
+ int ylen, bufp; /* len,location of last Ymodem packet */
+ int fileEof; /* file eof reached */
+ int packetCount; /* # packets received */
+ int errCount; /* how many data errors? */
+ int timeoutCount; /* how many times timed out? */
+ int windowCount; /* how much data sent in current window */
+ int atSign; /* last char was '@' */
+ int lastCR; /* last char was CR */
+ int escCtrl; /* other end requests ctrl chars be escaped */
+ int escHibit; /* other end requests hi bit be escaped */
+ int escape; /* next character is escaped */
+ int interrupt; /* received attention signal */
+ int waitflag; /* next send should wait */
+ /* parser state */
+ // enum enum_InputState {Idle, Padding, Inhdr, Indata, Finish, Ysend, Yrcv} InputState ;
+ enum_InputState InputState;
+ // enum enum_Protocol {XMODEM, YMODEM, ZMODEM} Protocol ;
+ enum_Protocol Protocol;
+ uchar hdrData[9]; /* header type and data */
+ uchar fileFlags[4]; /* file xfer flags */
+ ulong crc; /* crc of incoming header/data */
+ // enum enum_Streaming {Full, StrWindow, SlidingWindow, Segmented} Streaming ;
+ enum_Streaming Streaming;
+} ZModem;
+
+
+
+/* ZRINIT flags. Describe receiver capabilities */
+
+#define CANFDX 1 /* Rx is Full duplex */
+#define CANOVIO 2 /* Rx can overlap I/O */
+#define CANBRK 4 /* Rx can send a break */
+#define CANCRY 010 /* Rx can decrypt */
+#define CANLZW 020 /* Rx can uncompress */
+#define CANFC32 040 /* Rx can use 32-bit crc */
+#define ESCCTL 0100 /* Rx needs control chars escaped */
+#define ESC8 0200 /* Rx needs 8th bit escaped. */
+
+/* ZSINIT flags. Describe sender capabilities */
+
+#define TESCCTL 0100 /* Tx needs control chars escaped */
+#define TESC8 0200 /* Tx needs 8th bit escaped. */
+
+
+/* ZFILE transfer flags */
+
+/* F0 */
+#define ZCBIN 1 /* binary transfer */
+#define ZCNL 2 /* convert NL to local eol convention */
+#define ZCRESUM 3 /* resume interrupted file xfer, or append to a
+ growing file. */
+
+/* F1 */
+#define ZMNEWL 1 /* transfer if source newer or longer */
+#define ZMCRC 2 /* transfer if different CRC or length */
+#define ZMAPND 3 /* append to existing file, if any */
+#define ZMCLOB 4 /* replace existing file */
+#define ZMNEW 5 /* transfer if source is newer */
+#define ZMDIFF 6 /* transfer if dates or lengths different */
+#define ZMPROT 7 /* protect: transfer only if dest doesn't exist */
+#define ZMCHNG 8 /* change filename if destination exists */
+#define ZMMASK 037 /* mask for above. */
+#define ZMSKNOLOC 0200 /* skip if not present at Rx end */
+
+/* F2 */
+#define ZTLZW 1 /* lzw compression */
+#define ZTRLE 3 /* run-length encoding */
+
+/* F3 */
+#define ZCANVHDR 1 /* variable headers ok */
+#define ZRWOVR 4 /* byte position for receive window override/256 */
+#define ZXSPARS 64 /* encoding for sparse file ops. */
+
+
+
+/* ATTN string special characters. All other characters sent verbose */
+
+#define ATTNBRK '\335' /* send break signal */
+#define ATTNPSE '\336' /* pause for one second */
+
+/* error code definitions [O] means link still open */
+
+#define ZmDone -1 /* done */
+#define ZmErrInt -2 /* internal error */
+#define ZmErrSys -3 /* system error, see errno */
+#define ZmErrNotOpen -4 /* communication channel not open */
+#define ZmErrCantOpen -5 /* can't open file, see errno [O] */
+#define ZmFileTooLong -6 /* remote filename too long [O] */
+#define ZmFileCantWrite -7 /* could not write file, see errno */
+#define ZmDataErr -8 /* too many data errors */
+#define ZmErrInitTo -10 /* transmitter failed to respond to init req. */
+#define ZmErrSequence -11 /* packet received out of sequence */
+#define ZmErrCancel -12 /* cancelled by remote end */
+#define ZmErrRcvTo -13 /* remote receiver timed out during transfer */
+#define ZmErrSndTo -14 /* remote sender timed out during transfer */
+#define ZmErrCmdTo -15 /* remote command timed out */
+
+
+
+/* ZModem character definitions */
+
+#define ZDLE 030 /* zmodem escape is CAN */
+#define ZPAD '*' /* pad */
+#define ZBIN 'A' /* introduces 16-bit crc binary header */
+#define ZHEX 'B' /* introduces 16-bit crc hex header */
+#define ZBIN32 'C' /* introduces 32-bit crc binary header */
+#define ZBINR32 'D' /* introduces RLE packed binary frame w/32-bit crc */
+#define ZVBIN 'a' /* alternate ZBIN */
+#define ZVHEX 'b' /* alternate ZHEX */
+#define ZVBIN32 'c' /* alternate ZBIN32 */
+#define ZVBINR32 'd' /* alternate ZBINR32 */
+#define ZRESC 0177 /* RLE flag/escape character */
+
+
+
+/* ZModem header type codes */
+
+#define ZRQINIT 0 /* request receive init */
+#define ZRINIT 1 /* receive init */
+#define ZSINIT 2 /* send init sequence, define Attn */
+#define ZACK 3 /* ACK */
+#define ZFILE 4 /* file name, from sender */
+#define ZSKIP 5 /* skip file command, from receiver */
+#define ZNAK 6 /* last packet was garbled */
+#define ZABORT 7 /* abort */
+#define ZFIN 8 /* finish session */
+#define ZRPOS 9 /* resume file from this position, from receiver */
+#define ZDATA 10 /* data packets to follow, from sender */
+#define ZEOF 11 /* end of file, from sender */
+#define ZFERR 12 /* fatal i/o error, from receiver */
+#define ZCRC 13 /* request for file crc, from receiver */
+#define ZCHALLENGE 14 /* "send this number back to me", from receiver */
+#define ZCOMPL 15 /* request is complete */
+#define ZCAN 16 /* other end cancelled with CAN-CAN-CAN-CAN-CAN */
+#define ZFREECNT 17 /* request for free bytes on filesystem */
+#define ZCOMMAND 18 /* command, from sending program */
+#define ZSTDERR 19 /* output this message to stderr */
+
+
+/* ZDLE escape sequences */
+
+
+#define ZCRCE 'h' /* CRC next, frame ends, header follows */
+#define ZCRCG 'i' /* CRC next, frame continues nonstop */
+#define ZCRCQ 'j' /* CRC next, send ZACK, frame continues nonstop */
+#define ZCRCW 'k' /* CRC next, send ZACK, frame ends */
+#define ZRUB0 'l' /* translate to 0177 */
+#define ZRUB1 'm' /* translate to 0377 */
+
+
+/* ascii definitions */
+
+#define SOH 1 /* ^A */
+#define STX 2 /* ^B */
+#define EOT 4 /* ^D */
+#define ACK 6 /* ^F */
+#define DLE 16 /* ^P */
+#define XON 17 /* ^Q */
+#define XOFF 19 /* ^S */
+#define NAK 21 /* ^U */
+#define SYN 22 /* ^V */
+#define CAN 24 /* ^X */
+
+
+/* state table entry. There is one row of the table per
+ * possible state. Each row is a row of all reasonable
+ * inputs for this state. The entries are sorted so that
+ * the most common inputs occur first, to reduce search time
+ * Unexpected input is reported and ignored, as it might be
+ * caused by echo or something.
+ *
+ * Extra ZRINIT headers are the receiver trying to resync.
+ */
+class FQTermConfig;
+
+class FQTermZmodem;
+
+class FQTermTelnet;
+
+class FQTermFileDialog;
+
+typedef int(FQTermZmodem:: *ActionFunc)(ZModem*);
+
+typedef struct {
+ int type; /* frame type */
+ // int (*func)(ZModem *) ; /* transition function */
+ ActionFunc func;
+ int IFlush; /* flag: flush input first */
+ int OFlush; /* flag: flush output first */
+ ZMState newstate; /* new state. May be overridden by func */
+} StateTable;
+
+//class FQTermTelnet;
+
+class FQTermZmodem: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermZmodem(FQTermConfig *config, FQTermTelnet *netinterface, int type, int serverEncoding);
+ ~FQTermZmodem();
+
+ /* zmodem-supplied functions: */
+ int ZmodemTInit(ZModem *info);
+ int ZmodemTFile(char *file, char *rmtname, uint f0, uint f1, uint f2, uint f3,
+ int filesRem, int bytesRem, ZModem *info);
+ int ZmodemTFinish(ZModem *info);
+ int ZmodemAbort(ZModem *info);
+ int ZmodemRInit(ZModem *info);
+ int ZmodemRcv(uchar *str, int len, ZModem *info, int &consumed_bytes);
+ int ZmodemAttention(ZModem *info);
+
+ int ZmodemReset(ZModem *info);
+
+ int YmodemTInit(ZModem *info);
+ int XmodemTInit(ZModem *info);
+ int YmodemRInit(ZModem *info);
+ int XmodemRInit(ZModem *info);
+
+ ulong FileCrc(char *name);
+ const char *sname(ZModem*);
+ const char *sname2(ZMState);
+
+ /* caller-supplied functions: */
+ int ZXmitChr(uchar c, ZModem *info);
+ int ZXmitStr(const uchar *str, int len, ZModem *info);
+ void ZIFlush(ZModem *info);
+ void ZOFlush(ZModem *info);
+ int ZAttn(ZModem *info);
+ void ZStatus(int type, int value, const char *status);
+ FILE *ZOpenFile(char *name, ulong crc, ZModem *info);
+
+ int ZWriteFile(uchar *buffer, int len, FILE *, ZModem*);
+ int ZCloseFile(ZModem *info);
+ void ZFlowControl(int onoff, ZModem *info);
+
+ /* end caller-supplied functions */
+
+ int ZXmitHdr(int type, int format, const uchar data[4], ZModem *info);
+ int ZXmitHdrHex(int type, const uchar data[4], ZModem *info);
+ int ZXmitHdrBin(int type, const uchar data[4], ZModem *info);
+ int ZXmitHdrBin32(int type, const uchar data[4], ZModem *info);
+ uchar *putZdle(uchar *ptr, uchar c, ZModem *info);
+ uchar *putHex(uchar *ptr, uchar c);
+
+ uchar *ZEnc4(ulong n);
+ ulong ZDec4(const uchar buf[4]);
+
+ int YrcvChar(char c, register ZModem *info);
+ int YrcvTimeout(register ZModem *info);
+ void ZIdleStr(uchar *buffer, int len, ZModem *info);
+
+ /* LEXICAL BOX: handle characters received from remote end.
+ * These may be header, data or noise.
+ *
+ * This section is a finite state machine for parsing headers
+ * and reading input data. The info->chrCount field is effectively
+ * the state variable.
+ */
+
+ int FinishChar(char c, register ZModem *info);
+ int DataChar(uchar c, register ZModem *info);
+ int HdrChar(uchar c, register ZModem *info);
+ int IdleChar(uchar c, register ZModem *info);
+
+ int YsendChar(char c, ZModem *info);
+
+ int ZPF(ZModem *info);
+ int Ignore(ZModem *info);
+ int AnswerChallenge(register ZModem *info);
+ int GotAbort(register ZModem *info);
+ int GotCancel(ZModem *info);
+ int GotCommand(ZModem *info);
+ int GotStderr(register ZModem *info);
+ int RetDone(ZModem *info);
+ int GotCommandData(register ZModem *info, int crcGood);
+ int GotStderrData(register ZModem *info, int crcGood);
+
+ int GotFileName(ZModem *info, int crcGood);
+ int ResendCrcReq(ZModem *info);
+ int GotSinitData(ZModem *info, int crcGood);
+ int ResendRpos(ZModem *info);
+ int GotFileData(ZModem *info, int crcGood);
+ int SendRinit(ZModem *info);
+
+ int GotSinit(ZModem *info);
+ int GotFile(ZModem *info);
+ int GotFin(ZModem *info);
+ int GotData(ZModem *info);
+ int GotEof(ZModem *info);
+ int GotFreecnt(ZModem *info);
+ int GotFileCrc(ZModem *info);
+
+ int GotRinit(ZModem*);
+ int SendZSInit(ZModem*);
+ int SendFileCrc(ZModem*);
+ int GotSendAck(ZModem*);
+ int GotSendDoneAck(ZModem*);
+ int GotSendNak(ZModem*);
+ int GotSendWaitAck(ZModem*);
+ int SkipFile(ZModem*);
+ int GotSendPos(ZModem*);
+
+ int requestFile(ZModem *info, ulong crc);
+ void parseFileName(ZModem *info, char *fileinfo);
+ int fileError(ZModem *info, int type, int data);
+
+ int ProcessPacket(ZModem *info);
+ int rejectPacket(ZModem *info);
+ int acceptPacket(ZModem *info);
+
+ int calcCrc(uchar *str, int len);
+
+ char *strdup(const char *str);
+
+ int SendMoreFileData(ZModem *info);
+
+ uint rcvHex(uint i, char c);
+
+ int ZDataReceived(register ZModem *info, int crcGood);
+ int dataSetup(register ZModem *info);
+ int ZProtocol(register ZModem *info);
+
+ int ZXmitData(int, int, uchar, uchar *data, ZModem*);
+ int YXmitData(uchar *, int, ZModem*);
+
+ int YSendFilename(ZModem*);
+ int YSendData(ZModem*);
+ int YSendFin(ZModem*);
+
+ int sendFilename(ZModem*);
+ int SendFileData(ZModem*);
+ int ResendEof(ZModem*);
+
+ int OverAndOut(ZModem*);
+
+ int startFileData(ZModem *info);
+
+ void zmodemlog(const char *fmt, ...);
+
+ // interface function
+ // all not completed
+ void transferTimeOut(void*);
+ void upload(char*);
+ void uploadNext(char*);
+ void transferFinish();
+ void xferCancel();
+
+ /* data received from remote, pass it to Zmodem funcs */
+ void transferSendData(char *, int);
+ void TransferCancel();
+
+#if 1
+ static StateTable RStartOps[];
+ static StateTable RSinitWaitOps[];
+ static StateTable RFileNameOps[];
+ static StateTable RCrcOps[];
+ static StateTable RFileOps[];
+ static StateTable RDataOps[];
+ static StateTable RFinishOps[];
+
+
+ static StateTable TStartOps[];
+ static StateTable TInitOps[];
+ static StateTable FileWaitOps[];
+ static StateTable CrcWaitOps[];
+ static StateTable SendingOps[];
+ static StateTable SendDoneOps[];
+ static StateTable SendWaitOps[];
+ static StateTable SendEofOps[];
+ static StateTable TFinishOps[];
+
+ static StateTable CommandDataOps[];
+ static StateTable CommandWaitOps[];
+ static StateTable StderrDataOps[];
+ static StateTable DoneOps[];
+
+ static StateTable *tables[];
+ static const char *hdrnames[];
+#endif
+
+#if 0
+ StateTable RStartOps[];
+ StateTable RSinitWaitOps[];
+ StateTable RFileNameOps[];
+ StateTable RCrcOps[];
+ StateTable RFileOps[];
+ StateTable RDataOps[];
+ StateTable RFinishOps[];
+
+
+ StateTable TStartOps[];
+ StateTable TInitOps[];
+ StateTable FileWaitOps[];
+ StateTable CrcWaitOps[];
+ StateTable SendingOps[];
+ StateTable SendDoneOps[];
+ StateTable SendWaitOps[];
+ StateTable SendEofOps[];
+ StateTable TFinishOps[];
+
+ StateTable CommandDataOps[];
+ StateTable CommandWaitOps[];
+ StateTable StderrDataOps[];
+ StateTable DoneOps[];
+
+ StateTable *tables[];
+ char *hdrnames[];
+#endif
+ FQTermTelnet *telnet_;
+ FQTermConfig *config_;
+ // Dialog
+ // QDialog *zmodemDialog, uploadListDialog;
+
+ bool sending;
+
+ enum_transferstate transferstate;
+
+ ZModem info;
+
+ // connection type, e.g. telnet or ssh , 0=telnet, 1=ssh
+
+ int connectionType;
+
+ // Timer
+ QTimer *zmodemTimer;
+
+ //log file
+ FILE *zmodemlogfile;
+
+ int zerrno;
+ uchar lastPullByte;
+
+ QStringList strFileList;
+ QStringList::Iterator itFile;
+
+ int serverEncodingID;
+
+ QString lastDownloadedFilename_;
+
+ // end Member
+ signals:
+ void ZmodemState(int, int, const char *);
+
+ public slots:
+ void zmodemCancel();
+ int ZmodemTimeout();
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_ZMODEM_H
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
new file mode 100644
index 0000000..09af483
--- /dev/null
+++ b/src/ui/CMakeLists.txt
@@ -0,0 +1,122 @@
+set(fqterm_ui_SRCS
+ aboutdialog.h
+ addrdialog.h
+ articledialog.h
+ keydialog.h
+ msgdialog.h
+ prefdialog.h
+ quickdialog.h
+ schemadialog.h
+ soundconf.h
+ sshlogindialog.h
+ zmodemdialog.h
+ aboutdialog.cpp
+ addrdialog.cpp
+ articledialog.cpp
+ keydialog.cpp
+ msgdialog.cpp
+ prefdialog.cpp
+ quickdialog.cpp
+ schemadialog.cpp
+ soundconf.cpp
+ sshlogindialog.cpp
+ zmodemdialog.cpp
+ osdmessage.h
+ osdmessage.cpp
+ overlayWidget.h
+ overlayWidget.cpp
+ pictureflow.h
+ pictureflow.cpp
+ popupMessage.h
+ popupMessage.cpp
+ popwidget.h
+ popwidget.cpp
+ progressBar.h
+ progressBar.cpp
+ fqterm_time_label.h
+ fqterm_time_label.cpp
+ fqterm_tool_button.h
+ fqterm_tool_button.cpp
+ imageviewer.h
+ imageviewer.cpp
+ shortcutdialog.h
+ shortcutdialog.cpp
+ statusBar.h
+ statusBar.cpp
+ fqterm_canvas.h
+ fqterm_canvas.cpp
+ sitemanager.h
+ sitemanager.cpp
+ iplookup.h
+ iplookup.cpp
+ defineescape.h
+ defineescape.cpp
+)
+
+set(fqterm_ui_gen_HS
+ ui_aboutdialog.h
+ ui_addrdialog.h
+ ui_articledialog.h
+ ui_keydialog.h
+ ui_msgdialog.h
+ ui_prefdialog.h
+ ui_quickdialog.h
+ ui_schemadialog.h
+ ui_sitemanager.h
+ ui_soundconf.h
+ ui_sshlogin.h
+ ui_zmodemdialog.h
+ ui_iplookup.h
+ ui_defineescape.h
+)
+
+set(fqterm_ui_UIS
+ aboutdialog.ui
+ addrdialog.ui
+ articledialog.ui
+ keydialog.ui
+ msgdialog.ui
+ prefdialog.ui
+ quickdialog.ui
+ schemadialog.ui
+ sitemanager.ui
+ soundconf.ui
+ sshlogin.ui
+ zmodemdialog.ui
+ iplookup.ui
+ defineescape.ui
+)
+
+qt4_wrap_ui(fqterm_ui_UIS_H
+ ${fqterm_ui_UIS}
+)
+
+qt4_automoc(
+ ${fqterm_ui_SRCS}
+ ${fqterm_ui_gen_HS}
+)
+
+qt4_create_translation(fqterm_ui_qm_file
+ ${fqterm_ui_UIS}
+ ${fqterm_ui_SRCS}
+ ${CMAKE_SOURCE_DIR}/res/dict/ui_zh_CN.ts
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_SOURCE_DIR}/../utilities
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_ui
+ ${fqterm_ui_SRCS}
+ ${fqterm_ui_gen_HS}
+)
+
+add_dependencies(fqterm_ui
+ fqterm_common
+ fqterm_utilities
+)
diff --git a/src/ui/aboutdialog.cpp b/src/ui/aboutdialog.cpp
new file mode 100644
index 0000000..5c56dcc
--- /dev/null
+++ b/src/ui/aboutdialog.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPixmap>
+#include <QFile>
+#include <QTextBrowser>
+#include <QTextStream>
+#include <QtGlobal>
+
+#include "fqterm.h"
+#include "fqterm_path.h"
+#include "aboutdialog.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a aboutDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+aboutDialog::aboutDialog(QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl) {
+ ui_.setupUi(this);
+
+ QFile file(getPath(RESOURCE) + "credits");
+ if (file.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&file);
+ QString line;
+ while (!stream.atEnd()) {
+ // line of text excluding '\n'
+ line += stream.readLine() + "\n";
+ }
+ ui_.TextBrowser->setPlainText(line);
+ file.close();
+ }
+ QString aboutText = "FQTerm " + QString(FQTERM_VERSION_STRING) + QString("\nSVN revision ") + QString(FQTERM_SVN_REVISION) + QString("\n Built with Qt") + QT_VERSION_STR + QString("\n Running with Qt ") + qVersion();
+ if (QString(FQTERM_VERSION_STRING).startsWith("0.9.8")) {
+ aboutText += "\n>>2012 - End of the world edition<<";
+ }
+ ui_.TextLabel->setText(aboutText);
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+aboutDialog::~aboutDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+} // namespace FQTerm
+
+#include "aboutdialog.moc"
diff --git a/src/ui/aboutdialog.h b/src/ui/aboutdialog.h
new file mode 100644
index 0000000..cf40c4b
--- /dev/null
+++ b/src/ui/aboutdialog.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ABOUT_DIALOG_H
+#define FQTERM_ABOUT_DIALOG_H
+
+#include "ui_aboutdialog.h"
+
+namespace FQTerm {
+
+class aboutDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ aboutDialog(QWidget *parent = 0, Qt::WFlags fl = 0);
+ ~aboutDialog();
+ private:
+ Ui::aboutDialog ui_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_ABOUT_DIALOG_H
diff --git a/src/ui/aboutdialog.ui b/src/ui/aboutdialog.ui
new file mode 100644
index 0000000..5770cd8
--- /dev/null
+++ b/src/ui/aboutdialog.ui
@@ -0,0 +1,175 @@
+<ui version="4.0" >
+ <class>aboutDialog</class>
+ <widget class="QDialog" name="aboutDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="mouseTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle" >
+ <string>About FQTerm</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="pixmapLabel" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="scaledContents" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="TextLabel" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>FQTerm</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QTabWidget" name="mainTabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab1" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>376</width>
+ <height>194</height>
+ </rect>
+ </property>
+ <attribute name="title" >
+ <string>About</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;br />FQTerm&lt;br />&lt;br />&lt;br />&lt;a href="http://code.google.com/p/fqterm">&lt;span style=" text-decoration: underline; color:#0000ff;">http://code.google.com/p/fqterm&lt;/span>&lt;/a>&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="openExternalLinks" >
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags" >
+ <set>Qt::TextBrowserInteraction</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab2" >
+ <property name="geometry" >
+ <rect>
+ <x>77</x>
+ <y>97</y>
+ <width>944</width>
+ <height>522</height>
+ </rect>
+ </property>
+ <attribute name="title" >
+ <string>Authors</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="text" >
+ <string>fqterm@gmail.com
+
+devilphoenix@newsmth</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab3" >
+ <property name="geometry" >
+ <rect>
+ <x>100</x>
+ <y>120</y>
+ <width>944</width>
+ <height>522</height>
+ </rect>
+ </property>
+ <attribute name="title" >
+ <string>Credits</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QTextBrowser" name="TextBrowser" >
+ <property name="html" >
+ <string>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
+&lt;p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <tabstops>
+ <tabstop>closeButton</tabstop>
+ <tabstop>mainTabWidget</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>closeButton</sender>
+ <signal>clicked()</signal>
+ <receiver>aboutDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>339</x>
+ <y>261</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>211</x>
+ <y>249</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/addrdialog.cpp b/src/ui/addrdialog.cpp
new file mode 100644
index 0000000..79e62a8
--- /dev/null
+++ b/src/ui/addrdialog.cpp
@@ -0,0 +1,396 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPixmap>
+#include <QMessageBox>
+#include <QColorDialog>
+#include <QFontDialog>
+#include <QPainter>
+#include <QFileDialog>
+#include <QPalette>
+#include <QMenu>
+
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "addrdialog.h"
+#include "schemadialog.h"
+
+namespace FQTerm {
+
+const int addrDialog::ports[3] = {23, 22, 22};
+
+/*
+ * Constructs a addrDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+addrDialog::addrDialog(QWidget *parent_, const FQTermParam& parameter, int buttons, Qt::WFlags fl)
+ : QDialog(parent_, fl),
+ menuButtonGroup_(this),
+ param_(parameter) {
+ ui_.setupUi(this);
+ menuButtonGroup_.addButton(ui_.radioButton1, 0);
+ menuButtonGroup_.addButton(ui_.radioButton2, 1);
+ menuButtonGroup_.addButton(ui_.radioButton3, 2);
+ if (!(buttons & SAVE))
+ ui_.savePushButton->setVisible(false);
+ if (!(buttons & APPLY))
+ ui_.applyPushButton->setVisible(false);
+ QMenu *fontMenu = new QMenu(this);
+ for (int i = 0; i < 2; ++i) {
+ QAction *act = fontMenu->addAction(FQTermParam::getLanguageName(bool(i)) + " Font", this, SLOT(onFont()));
+ act->setData(i);
+ }
+ ui_.fontToolButton->setMenu(fontMenu);
+ setUIFromParam();
+ connector();
+}
+
+void addrDialog::setParamFromUI() {
+ param_.name_ = ui_.nameLineEdit->text();
+ param_.hostAddress_ = ui_.addrLineEdit->text();
+ param_.port_ = ui_.portLineEdit->text().toUShort();
+ param_.hostType_ = ui_.hostTypeComboBox->currentIndex();
+ param_.preLoginCommand_ = ui_.preloginLineEdit->text();
+ param_.userName_ = ui_.userLineEdit->text();
+ param_.password_ = ui_.passwdLineEdit->text();
+ param_.postLoginCommand_ = ui_.postloginLineEdit->text();
+ param_.serverEncodingID_ = ui_.bbscodeComboBox->currentIndex();
+ param_.isFontAutoFit_ = ui_.fontAdjustComboBox->currentIndex();
+ param_.isAlwaysHighlight_ = ui_.highlightCheckBox->isChecked();
+ param_.isAnsiColor_ = ui_.ansicolorCheckBox->isChecked();
+ param_.backgroundColor_ = ui_.fontPreviewer->palette().color(QPalette::Background);
+ param_.foregroundColor_ = ui_.fontPreviewer->palette().color(QPalette::Foreground);
+ param_.schemaFileName_ = ui_.schemaComboBox->currentText().isEmpty() || ui_.schemaComboBox->currentIndex() >= schemaDialog::getSchemaList().count()
+ ? "" : schemaDialog::getSchemaList()[ui_.schemaComboBox->currentIndex()].absoluteFilePath();
+ param_.virtualTermType_ = ui_.termtypeLineEdit->text();
+ param_.keyboardType_ = ui_.keytypeComboBox->currentIndex();
+ param_.backspaceType_ = ui_.backspace8->isChecked()?0:1;
+ param_.numColumns_ = ui_.columnLineEdit->text().toInt();
+ param_.numRows_ = ui_.rowLineEdit->text().toInt();
+ param_.numScrollLines_ = ui_.scrollLineEdit->text().toInt();
+ param_.cursorType_ = ui_.cursorTypeComboBox->currentIndex();
+ param_.escapeString_ = ui_.escapeLineEdit->text();
+ param_.proxyType_ = ui_.proxytypeComboBox->currentIndex();
+ param_.proxyHostName_ = ui_.proxyaddrLineEdit->text();
+ param_.proxyPort_ = ui_.proxyportLineEdit->text().toUShort();
+ param_.isAuthentation_ = ui_.authentationGroup->isChecked();
+ param_.proxyUserName_ = ui_.proxyuserLineEdit->text();
+ param_.proxyPassword_ = ui_.proxypasswdLineEdit->text();
+ param_.protocolType_ = ui_.protocolComboBox->currentIndex();
+ if (param_.port_ != ports[param_.protocolType_]) {
+ ui_.portCheckBox->setChecked(true);
+ }
+ switch(param_.protocolType_)
+ {
+ case 0:
+ param_.isAutoLogin_ = ui_.telnetAutoLoginGroup->isChecked();
+ break;
+ case 1:
+ case 2:
+ param_.isAutoLogin_ = ui_.sshAutoLoginGroup->isChecked();
+ case 100:
+ break;
+ }
+ param_.sshUserName_ = ui_.sshuserLineEdit->text();
+ param_.sshPassword_ = ui_.sshpasswdLineEdit->text();
+ param_.maxIdleSeconds_ = ui_.idletimeLineEdit->text().toInt();
+ param_.replyKeyCombination_ = ui_.replykeyLineEdit->text();
+ if (param_.replyKeyCombination_.isNull()) {
+ FQ_TRACE("addrdialog", 0) << "Key combination for reply is NULL.";
+ }
+ param_.antiIdleMessage_ = ui_.antiLineEdit->text();
+ param_.isAntiIdle_ = ui_.antiIdleGroupBox->isChecked();
+ param_.isAutoReply_ = ui_.replyCheckBox->isChecked();
+ param_.autoReplyMessage_ = ui_.replyLineEdit->text();
+ param_.isAutoReconnect_ = ui_.reconnectCheckBox->isChecked();
+ param_.reconnectInterval_ = ui_.reconnectLineEdit->text().toInt();
+ param_.retryTimes_ = ui_.retryLineEdit->text().toInt();
+ param_.isAutoCloseWin_ = ui_.autoCloseWinCheckBox->isChecked();
+ param_.isAutoLoadScript_ = ui_.scriptCheckBox->isChecked();
+ param_.enableZmodem_ = ui_.zmodemCheck->isChecked();
+ param_.isBeep_ = ui_.beepCheck->isChecked();
+ param_.isBuzz_ = ui_.buzzCheck->isChecked();
+ param_.isSupportMouse_ = ui_.mouseCheck->isChecked();
+ param_.autoLoadedScriptFileName_ = ui_.scriptLineEdit->text();
+ param_.menuType_ = menuButtonGroup_.checkedId();
+ param_.menuColor_ = ui_.menuLabel->palette().color(QPalette::Background);
+ param_.alignMode_ = ui_.alignComboBox->currentIndex();
+ param_.charSpacing_ = ui_.charSpacingSpinBox->value();
+ param_.lineSpacing_ = ui_.lineSpacingSpinBox->value();
+}
+
+void addrDialog::setUIFromParam() {
+
+ updateSchemaList(param_.schemaFileName_);
+ QString strTmp;
+ ui_.nameLineEdit->setText(param_.name_);
+ ui_.addrLineEdit->setText(param_.hostAddress_);
+ ui_.hostTypeComboBox->setCurrentIndex(param_.hostType_);
+// ui_.autoLoginCheckBox->setChecked(param_.isAutoLogin_);
+ ui_.preloginLineEdit->setText(param_.preLoginCommand_);
+ ui_.userLineEdit->setText(param_.userName_);
+ ui_.passwdLineEdit->setText(param_.password_);
+ ui_.postloginLineEdit->setText(param_.postLoginCommand_);
+ ui_.bbscodeComboBox->setCurrentIndex(param_.serverEncodingID_);
+ ui_.fontAdjustComboBox->setCurrentIndex(param_.isFontAutoFit_);
+ ui_.highlightCheckBox->setChecked(param_.isAlwaysHighlight_);
+ ui_.ansicolorCheckBox->setChecked(param_.isAnsiColor_);
+ ui_.termtypeLineEdit->setText(param_.virtualTermType_);
+ ui_.keytypeComboBox->setCurrentIndex(param_.keyboardType_);
+ ui_.backspace8->setChecked(param_.backspaceType_ == 0);
+ ui_.backspace127->setChecked(param_.backspaceType_ == 1);
+ strTmp.setNum(param_.numColumns_);
+ ui_.columnLineEdit->setText(strTmp);
+ strTmp.setNum(param_.numRows_);
+ ui_.rowLineEdit->setText(strTmp);
+ strTmp.setNum(param_.numScrollLines_);
+ ui_.scrollLineEdit->setText(strTmp);
+ ui_.cursorTypeComboBox->setCurrentIndex(param_.cursorType_);
+ ui_.escapeLineEdit->setText(param_.escapeString_);
+ ui_.proxytypeComboBox->setCurrentIndex(param_.proxyType_);
+ ui_.proxyaddrLineEdit->setText(param_.proxyHostName_);
+ strTmp.setNum(param_.proxyPort_);
+ ui_.proxyportLineEdit->setText(strTmp);
+ ui_.authentationGroup->setChecked(param_.isAuthentation_);
+ ui_.proxyuserLineEdit->setText(param_.proxyUserName_);
+ ui_.proxypasswdLineEdit->setText(param_.proxyPassword_);
+ ui_.protocolComboBox->setCurrentIndex(param_.protocolType_);
+ onProtocol(param_.protocolType_);
+ strTmp.setNum(param_.port_);
+ ui_.portLineEdit->setText(strTmp);
+ ui_.portCheckBox->setChecked(param_.port_ != ports[param_.protocolType_]);
+ ui_.sshuserLineEdit->setText(param_.sshUserName_);
+ ui_.sshpasswdLineEdit->setText(param_.sshPassword_);
+ strTmp.setNum(param_.maxIdleSeconds_);
+ ui_.idletimeLineEdit->setText(strTmp);
+ ui_.replykeyLineEdit->setText(param_.replyKeyCombination_);
+ ui_.antiLineEdit->setText(param_.antiIdleMessage_);
+ ui_.antiIdleGroupBox->setChecked(param_.isAntiIdle_);
+ ui_.replyCheckBox->setChecked(param_.isAutoReply_);
+ ui_.replyLineEdit->setEnabled(param_.isAutoReply_);
+ ui_.replyLineEdit->setText(param_.autoReplyMessage_);
+ ui_.reconnectCheckBox->setChecked(param_.isAutoReconnect_);
+ ui_.reconnectLineEdit->setEnabled(param_.isAutoReconnect_);
+ ui_.retryLineEdit->setEnabled(param_.isAutoReconnect_);
+ ui_.alignComboBox->setCurrentIndex(param_.alignMode_);
+ ui_.charSpacingSpinBox->setValue(param_.charSpacing_);
+ ui_.lineSpacingSpinBox->setValue(param_.lineSpacing_);
+ strTmp.setNum(param_.reconnectInterval_);
+ ui_.reconnectLineEdit->setText(strTmp);
+ strTmp.setNum(param_.retryTimes_);
+ ui_.retryLineEdit->setText(strTmp);
+ ui_.autoCloseWinCheckBox->setChecked(param_.isAutoCloseWin_);
+ ui_.scriptCheckBox->setChecked(param_.isAutoLoadScript_);
+ ui_.scriptLineEdit->setText(param_.autoLoadedScriptFileName_);
+ ui_.zmodemCheck->setChecked(param_.enableZmodem_);
+ ui_.beepCheck->setChecked(param_.isBeep_);
+ ui_.buzzCheck->setChecked(param_.isBuzz_);
+ ui_.mouseCheck->setChecked(param_.isSupportMouse_);
+ //ui.menuGroup->setButton(param_.m_nMenuType);
+ QRadioButton *rbMenu = qobject_cast < QRadioButton * > (menuButtonGroup_.button
+ (param_.menuType_));
+ rbMenu->setChecked(true);
+ previewFont();
+ previewMenu();
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+addrDialog::~addrDialog() {
+}
+
+
+void addrDialog::onOK() {
+ setParamFromUI();
+ done(1);
+}
+
+void addrDialog::onSave() {
+ setParamFromUI();
+ done(2);
+}
+void addrDialog::onCancel() {
+ done(0);
+}
+
+
+
+void addrDialog::onFgcolor() {
+ QColor color = QColorDialog::getColor(param_.foregroundColor_);
+ if (color.isValid() == TRUE) {
+ param_.foregroundColor_ = color;
+ previewFont();
+ }
+}
+
+void addrDialog::onBgcolor() {
+ QColor color = QColorDialog::getColor(param_.backgroundColor_);
+ if (color.isValid() == TRUE) {
+ param_.backgroundColor_ = color;
+ previewFont();
+ }
+}
+
+
+
+void addrDialog::onProtocol(int n) {
+ ui_.portCheckBox->setChecked(false);
+ ui_.portLineEdit->setText(QString("%1").arg(ports[n]));
+ switch(n)
+ {
+ case 0: //telnet
+ ui_.telnetAutoLoginGroup->setEnabled(true);
+ ui_.telnetAutoLoginGroup->setChecked(param_.isAutoLogin_);
+ ui_.sshAutoLoginGroup->setEnabled(false);
+ ui_.sshAutoLoginGroup->setChecked(false);
+ break;
+ case 1:
+#if defined(_NO_SSH_COMPILED)
+ QMessageBox::warning(this, "sorry",
+ "SSH support is not compiled, check your OpenSSL and try to recompile FQTerm");
+ ui_.protocolComboBox->setCurrentItem(0);
+#else
+ ui_.telnetAutoLoginGroup->setEnabled(false);
+ ui_.telnetAutoLoginGroup->setChecked(false);
+ ui_.sshAutoLoginGroup->setEnabled(true);
+ ui_.sshAutoLoginGroup->setChecked(param_.isAutoLogin_);
+#endif
+ break;
+ case 2:
+#if defined(_NO_SSH_COMPILED)
+ QMessageBox::warning(this, "sorry",
+ "SSH support is not compiled, check your OpenSSL and try to recompile FQTerm");
+ ui_.protocolComboBox->setCurrentItem(0);
+#else
+ ui_.telnetAutoLoginGroup->setEnabled(false);
+ ui_.telnetAutoLoginGroup->setChecked(false);
+ ui_.sshAutoLoginGroup->setEnabled(true);
+ ui_.sshAutoLoginGroup->setChecked(param_.isAutoLogin_);
+#endif
+ break;
+ }
+}
+
+void addrDialog::onChooseScript() {
+ QString path = getPath(RESOURCE) + "script";
+
+ QString strFile = QFileDialog::getOpenFileName(this, "choose a script file",
+ path, "JavaScript/Python File (*.js *.py)");
+
+ if (strFile.isNull()) {
+ return ;
+ }
+
+ ui_.scriptLineEdit->setText(strFile);
+}
+
+void addrDialog::onMenuColor() {
+ QColor color = QColorDialog::getColor(param_.menuColor_);
+ if (color.isValid() == TRUE) {
+ param_.menuColor_ = color;
+ previewMenu();
+ }
+}
+
+void addrDialog::previewFont() {
+ //issue 98 preview both en and zh
+
+ QPalette palette;
+ palette.setColor(QPalette::Window, param_.backgroundColor_);
+ palette.setColor(QPalette::WindowText, param_.foregroundColor_);
+ ui_.fontPreviewer->setPalette(palette);
+ QString sample("<html><body style=\" font-family:'" + param_.englishFontName_
+ + "'; font-size:" + QString().setNum(param_.englishFontSize_)
+ + "pt;\"><BR>AaBbCc</body></html>");
+ sample += QString("<html><body style=\" font-family:'"
+ + param_.otherFontName_ + "'; font-size:"
+ + QString().setNum(param_.otherFontSize_) + "pt;\">"
+ + param_.otherFontName_ + "<BR></body></html>");
+ ui_.fontPreviewer->setText(sample);
+}
+
+
+void addrDialog::connector() {
+ FQ_VERIFY(connect(ui_.applyPushButton, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.savePushButton, SIGNAL(clicked()), this, SLOT(onSave())));
+ FQ_VERIFY(connect(ui_.closePushButton, SIGNAL(clicked()), this, SLOT(onCancel())));
+
+
+ FQ_VERIFY(connect(ui_.fgcolorPushButton, SIGNAL(clicked()), this, SLOT(onFgcolor())));
+ FQ_VERIFY(connect(ui_.bgcolorPushButton, SIGNAL(clicked()), this, SLOT(onBgcolor())));
+
+ FQ_VERIFY(connect(ui_.protocolComboBox, SIGNAL(activated(int)), this, SLOT(onProtocol(int))));
+
+ FQ_VERIFY(connect(ui_.scriptPushButton, SIGNAL(clicked()), this, SLOT(onChooseScript())));
+
+ FQ_VERIFY(connect(ui_.menuColorButton, SIGNAL(clicked()), this, SLOT(onMenuColor())));
+}
+
+void addrDialog::previewMenu() {
+ QPalette palette;
+ palette.setColor(QPalette::Window, param_.menuColor_);
+ ui_.menuLabel->setPalette(palette);
+}
+
+void addrDialog::onFont() {
+ bool isEnglish = ((QAction*)(sender()))->data().toBool();
+ bool ok;
+ QString& fontName = isEnglish?param_.englishFontName_:param_.otherFontName_;
+ int& fontSize = isEnglish?param_.englishFontSize_:param_.otherFontSize_;
+ QFont now(fontName, fontSize);
+
+ QFont font = QFontDialog::getFont(&ok, now, this, tr("Font Selector")
+#ifdef __APPLE__
+ , QFontDialog::DontUseNativeDialog
+#endif
+ );
+ if (ok == true) {
+ fontName = font.family();
+ fontSize = font.pointSize();
+ previewFont();
+ }
+}
+
+void addrDialog::updateSchemaList(const QString& currentSchema) {
+ ui_.schemaComboBox->clear();
+ QFileInfoList lstFile = schemaDialog::getSchemaList();
+ foreach(QFileInfo fi, lstFile) {
+ FQTermConfig *pConf = new FQTermConfig(fi.absoluteFilePath());
+ ui_.schemaComboBox->addItem(pConf->getItemValue("schema", "title"));
+ delete pConf;
+ }
+ ui_.schemaComboBox->addItem("");
+ int schemaIdx = lstFile.indexOf(currentSchema);
+ if (schemaIdx < 0)
+ schemaIdx = ui_.schemaComboBox->count() - 1;
+ ui_.schemaComboBox->setCurrentIndex(schemaIdx);
+}
+
+} // namespace FQTerm
+
+#include "addrdialog.moc"
diff --git a/src/ui/addrdialog.h b/src/ui/addrdialog.h
new file mode 100644
index 0000000..8405a0a
--- /dev/null
+++ b/src/ui/addrdialog.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ADDR_DIALOG_H
+#define FQTERM_ADDR_DIALOG_H
+
+#include <QButtonGroup>
+
+#include "fqterm_param.h"
+#include "ui_addrdialog.h"
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class addrDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ enum BUTTONS{SAVE = 0x01, APPLY = 0x02};
+ addrDialog(QWidget *parent_ = 0, const FQTermParam& param = FQTermParam(), int buttons = SAVE | APPLY, Qt::WFlags fl = 0);
+ ~addrDialog();
+ void setParam(const FQTermParam& param) {
+ param_ = param;
+ }
+ FQTermParam param() {
+ return param_;
+ }
+
+ enum Tabs{General, Display, Terminal, Keyboard, Proxy, Misc, Mouse};
+ void setCurrentTabIndex(Tabs tab) {
+ ui_.tabWidget->setCurrentIndex(tab);
+ }
+
+ static const int ports[3]; // telnet, ssh1, ssh2
+
+ protected slots:
+ void onOK();
+ void onSave();
+ void onCancel();
+ void onFgcolor();
+ void onBgcolor();
+ void onProtocol(int);
+ void onChooseScript();
+ void onMenuColor();
+ void onFont();
+
+ protected:
+ void connector();
+ bool isChanged();
+ void previewFont();
+ void previewMenu();
+ void setUIFromParam();
+ void setParamFromUI();
+
+ QButtonGroup menuButtonGroup_;
+
+ private:
+
+ FQTermParam param_;
+ Ui::addrDialog ui_;
+
+ void updateSchemaList(const QString& currentFile);
+};
+
+
+
+
+} // namespace FQTerm
+
+#endif // FQTERM_ADDR_DIALOG_H
diff --git a/src/ui/addrdialog.ui b/src/ui/addrdialog.ui
new file mode 100644
index 0000000..e5dc40b
--- /dev/null
+++ b/src/ui/addrdialog.ui
@@ -0,0 +1,1211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>addrDialog</class>
+ <widget class="QDialog" name="addrDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>493</width>
+ <height>383</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Site Setting</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="applyPushButton">
+ <property name="text">
+ <string>Apply (&amp;Temporarily)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="closePushButton">
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="savePushButton">
+ <property name="text">
+ <string>&amp;Apply (Save)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="4">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="Widget2">
+ <attribute name="title">
+ <string>General</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel1">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3">
+ <widget class="QLineEdit" name="nameLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel2">
+ <property name="text">
+ <string>Address</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="3">
+ <widget class="QLineEdit" name="addrLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel1_3">
+ <property name="text">
+ <string>Protocol</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="protocolComboBox">
+ <item>
+ <property name="text">
+ <string>Telnet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SSH1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SSH2</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLineEdit" name="portLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="TextLabel3_6">
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="hostTypeComboBox">
+ <item>
+ <property name="text">
+ <string>BBS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>*NIX</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="4">
+ <widget class="QGroupBox" name="telnetAutoLoginGroup">
+ <property name="title">
+ <string>Telnet Auto Login</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel1_2">
+ <property name="text">
+ <string>Prelogin</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="preloginLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel4">
+ <property name="text">
+ <string>User</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="userLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel5">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="passwdLineEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="TextLabel11">
+ <property name="text">
+ <string>Postlogin</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="postloginLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QCheckBox" name="portCheckBox">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4">
+ <widget class="QGroupBox" name="sshAutoLoginGroup">
+ <property name="title">
+ <string>SSH Auto Login</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel2_3">
+ <property name="text">
+ <string>User</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="sshuserLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel3_3">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="sshpasswdLineEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab1">
+ <attribute name="title">
+ <string>Display</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel6">
+ <property name="text">
+ <string>BBS Encoding</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="bbscodeComboBox">
+ <item>
+ <property name="text">
+ <string>GBK</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>UTF8</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5-HKSCS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5-UAO</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="highlightCheckBox">
+ <property name="text">
+ <string>Always Hightlight</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" rowspan="4" colspan="4">
+ <widget class="QLabel" name="fontPreviewer">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>TextLabel3</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Align Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QSpinBox" name="lineSpacingSpinBox"/>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Line Spacing</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QSpinBox" name="charSpacingSpinBox"/>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Char Spacing</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="ansicolorCheckBox">
+ <property name="text">
+ <string>ANSI Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4">
+ <widget class="QComboBox" name="alignComboBox">
+ <item>
+ <property name="text">
+ <string>Align Mid</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Align Bottom</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Align Top</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="7" column="4">
+ <widget class="QComboBox" name="schemaComboBox"/>
+ </item>
+ <item row="6" column="4">
+ <widget class="QPushButton" name="bgcolorPushButton">
+ <property name="text">
+ <string>Background</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="4">
+ <widget class="QPushButton" name="fgcolorPushButton">
+ <property name="text">
+ <string>Text Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4">
+ <widget class="QToolButton" name="fontToolButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Font</string>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::InstantPopup</enum>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextOnly</enum>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::DownArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QComboBox" name="fontAdjustComboBox">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Keep Font; Adjust Row/Column.</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Keep Row/Column; Adjust Font.</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Keep Font; Keep Row/Column.</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab2">
+ <attribute name="title">
+ <string>Terminal</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel1_5">
+ <property name="text">
+ <string>Term Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="termtypeLineEdit"/>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="TextLabel2_5">
+ <property name="text">
+ <string>Key Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QComboBox" name="keytypeComboBox">
+ <item>
+ <property name="text">
+ <string>VT100</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>XTERM</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BBS</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel3_4">
+ <property name="text">
+ <string>Columns</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="columnLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="TextLabel5_3">
+ <property name="text">
+ <string>Scroll Lines</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLineEdit" name="scrollLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel4_3">
+ <property name="text">
+ <string>Rows</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="rowLineEdit"/>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="TextLabel6_3">
+ <property name="text">
+ <string>Cursor Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QComboBox" name="cursorTypeComboBox">
+ <item>
+ <property name="text">
+ <string>Block</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Underline</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>I Type</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLabel" name="TextLabel1_4">
+ <property name="text">
+ <string>Escape string (i.e. *[ )</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" colspan="2">
+ <widget class="QLineEdit" name="escapeLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab7">
+ <attribute name="title">
+ <string>Keyboard</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="BackSpace">
+ <property name="title">
+ <string>BackSpace Setting</string>
+ </property>
+ <layout class="QGridLayout" name="_3">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="backspace8">
+ <property name="text">
+ <string>Send backspace as ^H</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="backspace127">
+ <property name="text">
+ <string>Send backspace as ^? (127)</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab3">
+ <attribute name="title">
+ <string>Proxy</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel2_2">
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="proxytypeComboBox">
+ <item>
+ <property name="text">
+ <string>None</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Wingate</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SOCKS4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SOCKS5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>HTTP</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel3_2">
+ <property name="text">
+ <string>Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="proxyaddrLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="TextLabel4_2">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLineEdit" name="proxyportLineEdit"/>
+ </item>
+ <item row="2" column="0" colspan="4">
+ <widget class="QGroupBox" name="authentationGroup">
+ <property name="title">
+ <string>Authentation</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel5_2">
+ <property name="text">
+ <string>User</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="proxyuserLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel5_4">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="proxypasswdLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="Widget3">
+ <attribute name="title">
+ <string>Misc</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="5">
+ <widget class="QGroupBox" name="antiIdleGroupBox">
+ <property name="title">
+ <string>Anti-idle</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="antiLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="TextLabel8">
+ <property name="text">
+ <string>Max Idle Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="idletimeLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="TextLabel9">
+ <property name="text">
+ <string>s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Anti-idle String</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Key to reply message</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLineEdit" name="replykeyLineEdit"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QCheckBox" name="replyCheckBox">
+ <property name="text">
+ <string>Autoreply Message</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="3">
+ <widget class="QLineEdit" name="replyLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <widget class="QCheckBox" name="reconnectCheckBox">
+ <property name="text">
+ <string>When disconnected, reconnect every</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3">
+ <widget class="QLineEdit" name="reconnectLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4">
+ <widget class="QLabel" name="textLabel2">
+ <property name="text">
+ <string>s</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="textLabel4">
+ <property name="text">
+ <string>For Maximum</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="2">
+ <widget class="QLineEdit" name="retryLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" colspan="2">
+ <widget class="QLabel" name="textLabel5">
+ <property name="text">
+ <string>Times (-1 means infinite)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="2">
+ <widget class="QCheckBox" name="scriptCheckBox">
+ <property name="text">
+ <string>Load Control Script</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="3">
+ <widget class="QLineEdit" name="scriptLineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="3" colspan="2">
+ <widget class="QPushButton" name="scriptPushButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QCheckBox" name="zmodemCheck">
+ <property name="text">
+ <string>Enable Zmodem</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="3">
+ <widget class="QCheckBox" name="buzzCheck">
+ <property name="text">
+ <string>Enable Buzz</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="2">
+ <widget class="QCheckBox" name="beepCheck">
+ <property name="text">
+ <string>Enable Beep</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="3">
+ <widget class="QCheckBox" name="autoCloseWinCheckBox">
+ <property name="text">
+ <string>When disconnected, close window automatically</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab4">
+ <attribute name="title">
+ <string>Mouse</string>
+ </attribute>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="menuGroup">
+ <property name="title">
+ <string>Menu Type</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="radioButton1">
+ <property name="text">
+ <string>Underline</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="radioButton2">
+ <property name="text">
+ <string>Reverse</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QRadioButton" name="radioButton3">
+ <property name="text">
+ <string>Custom Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="menuLabel">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Menu Color</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="menuColorButton">
+ <property name="text">
+ <string>Color...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="mouseCheck">
+ <property name="text">
+ <string>Enable Mouse Support</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>nameLineEdit</tabstop>
+ <tabstop>addrLineEdit</tabstop>
+ <tabstop>portLineEdit</tabstop>
+ <tabstop>hostTypeComboBox</tabstop>
+ <tabstop>preloginLineEdit</tabstop>
+ <tabstop>userLineEdit</tabstop>
+ <tabstop>passwdLineEdit</tabstop>
+ <tabstop>postloginLineEdit</tabstop>
+ <tabstop>bbscodeComboBox</tabstop>
+ <tabstop>highlightCheckBox</tabstop>
+ <tabstop>termtypeLineEdit</tabstop>
+ <tabstop>keytypeComboBox</tabstop>
+ <tabstop>columnLineEdit</tabstop>
+ <tabstop>scrollLineEdit</tabstop>
+ <tabstop>rowLineEdit</tabstop>
+ <tabstop>cursorTypeComboBox</tabstop>
+ <tabstop>escapeLineEdit</tabstop>
+ <tabstop>idletimeLineEdit</tabstop>
+ <tabstop>replykeyLineEdit</tabstop>
+ <tabstop>replyCheckBox</tabstop>
+ <tabstop>replyLineEdit</tabstop>
+ <tabstop>reconnectCheckBox</tabstop>
+ <tabstop>reconnectLineEdit</tabstop>
+ <tabstop>retryLineEdit</tabstop>
+ <tabstop>autoCloseWinCheckBox</tabstop>
+ <tabstop>scriptCheckBox</tabstop>
+ <tabstop>scriptLineEdit</tabstop>
+ <tabstop>scriptPushButton</tabstop>
+ <tabstop>radioButton1</tabstop>
+ <tabstop>radioButton2</tabstop>
+ <tabstop>radioButton3</tabstop>
+ <tabstop>menuColorButton</tabstop>
+ <tabstop>applyPushButton</tabstop>
+ <tabstop>closePushButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>menuColorButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>260</x>
+ <y>79</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>392</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>menuColorButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>53</x>
+ <y>79</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>392</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>menuColorButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>392</x>
+ <y>79</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>392</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>replyCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>replyLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>23</x>
+ <y>158</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>168</x>
+ <y>156</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>reconnectCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>reconnectLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>23</x>
+ <y>184</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>295</x>
+ <y>182</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>reconnectCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>retryLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>23</x>
+ <y>184</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>147</x>
+ <y>213</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>scriptCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>26</x>
+ <y>236</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>26</x>
+ <y>261</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>scriptCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptPushButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>26</x>
+ <y>236</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>289</x>
+ <y>260</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>portCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>portLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>187</x>
+ <y>108</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>209</x>
+ <y>108</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>antiIdleGroupBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>antiLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>89</x>
+ <y>42</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>145</x>
+ <y>67</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>antiIdleGroupBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>idletimeLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>114</x>
+ <y>40</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>270</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>beepCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>buzzCheck</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>223</x>
+ <y>301</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>298</x>
+ <y>299</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/articledialog.cpp b/src/ui/articledialog.cpp
new file mode 100644
index 0000000..43ba617
--- /dev/null
+++ b/src/ui/articledialog.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "articledialog.h"
+#include <QFileDialog>
+#include <QMessageBox>
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+#include "fqterm_filedialog.h"
+
+/*
+ * Constructs a articleDialog as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+namespace FQTerm {
+
+articleDialog::articleDialog(FQTermConfig *config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl) {
+ ui_.setupUi(this);
+ connectSlots();
+
+ config_ = config;
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+articleDialog::~articleDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+void articleDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.selectButton, SIGNAL(clicked()), this, SLOT(onSelect())));
+ FQ_VERIFY(connect(ui_.copyButton, SIGNAL(clicked()), this, SLOT(onCopy())));
+ FQ_VERIFY(connect(ui_.saveButton, SIGNAL(clicked()), this, SLOT(onSave())));
+ FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()), this, SLOT(onClose())));
+}
+
+void articleDialog::onSelect() {
+ ui_.textBrowser->selectAll();
+}
+
+void articleDialog::onCopy() {
+ ui_.textBrowser->copy();
+ // QString strText = textBrowser->selectedText();
+ //
+ // QClipboard *clipboard = QApplication::clipboard();
+ //
+ // #if (QT_VERSION>=0x030100)
+ // clipboard->setText(strText, QClipboard::Selection );
+ // clipboard->setText(strText, QClipboard::Clipboard );
+ // #else
+ // clipboard->setText(strText);
+ // #endif
+}
+
+void articleDialog::onSave() {
+
+ QString filename;
+ FQTermFileDialog fileDialog(config_);
+ filename = fileDialog.getSaveName(NULL, "");
+
+ if (!filename.isNull()) {
+ QFile f(filename);
+ if ((f.open(QIODevice::WriteOnly))) {
+ f.write(articleText_.toLocal8Bit());
+ f.close();
+ } else {
+ QMessageBox mb("Access file error:", filename, QMessageBox::Warning, 0, 0, 0,
+ this, 0);
+ mb.exec();
+ }
+ }
+}
+
+void articleDialog::onClose() {
+ done(0);
+}
+
+} // namespace FQTerm
+
+#include "articledialog.moc"
diff --git a/src/ui/articledialog.h b/src/ui/articledialog.h
new file mode 100644
index 0000000..0e40cbf
--- /dev/null
+++ b/src/ui/articledialog.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ARTICLEDIALOG_H
+#define FQTERM_ARTICLEDIALOG_H
+
+#include "ui_articledialog.h"
+
+namespace FQTerm {
+
+class FQTermConfig;
+class FQTermFileDialog;
+
+class articleDialog: public QDialog {
+ Q_OBJECT;
+public:
+ articleDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~articleDialog();
+
+ QString articleText_;
+ Ui::articleDialog ui_;
+protected:
+ void connectSlots();
+protected slots:
+ void onClose();
+ void onSave();
+ void onSelect();
+ void onCopy();
+private:
+ FQTermConfig * config_;
+};
+
+} // name space FQTerm
+
+#endif // FQTERM_ARTICLEDIALOG_H
diff --git a/src/ui/articledialog.ui b/src/ui/articledialog.ui
new file mode 100644
index 0000000..436671f
--- /dev/null
+++ b/src/ui/articledialog.ui
@@ -0,0 +1,132 @@
+<ui version="4.0" >
+ <class>articleDialog</class>
+ <widget class="QDialog" name="articleDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>542</width>
+ <height>487</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Article Viewer</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="8" >
+ <widget class="QTextBrowser" name="textBrowser" />
+ </item>
+ <item row="1" column="4" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>50</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="6" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>410</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="6" colspan="2" >
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="selectButton" >
+ <property name="text" >
+ <string>Select All</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="7" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="5" colspan="2" >
+ <widget class="QPushButton" name="saveButton" >
+ <property name="text" >
+ <string>Save...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QPushButton" name="copyButton" >
+ <property name="text" >
+ <string>Copy</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/defineescape.cpp b/src/ui/defineescape.cpp
new file mode 100644
index 0000000..e9dd655
--- /dev/null
+++ b/src/ui/defineescape.cpp
@@ -0,0 +1,51 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "defineescape.h"
+#include "fqterm.h"
+
+namespace FQTerm {
+
+DefineEscapeDialog::~DefineEscapeDialog()
+{
+}
+
+DefineEscapeDialog::DefineEscapeDialog(QString& strEsc, QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/)
+: QDialog(parent_, fl), strEsc_(strEsc)
+{
+ ui_.setupUi(this);
+ ui_.edtEscape->setText(strEsc_);
+ FQ_VERIFY(connect(ui_.btnOK, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.btnCancel, SIGNAL(clicked()), this, SLOT(onCancel())));
+}
+
+void DefineEscapeDialog::onOK()
+{
+ strEsc_ = ui_.edtEscape->text();
+ done(1);
+}
+
+void DefineEscapeDialog::onCancel()
+{
+ done(0);
+}
+} //namespace FQTerm
+
+#include "defineescape.moc"
diff --git a/src/ui/defineescape.h b/src/ui/defineescape.h
new file mode 100644
index 0000000..0083603
--- /dev/null
+++ b/src/ui/defineescape.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef __FQTERM_DEFINEESCAPE__
+#define __FQTERM_DEFINEESCAPE__
+
+#include <QDialog>
+#include "ui_defineescape.h"
+namespace FQTerm {
+
+class DefineEscapeDialog : public QDialog {
+ Q_OBJECT;
+public:
+ DefineEscapeDialog(QString& strEsc, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~DefineEscapeDialog();
+
+protected slots:
+ void onOK();
+ void onCancel();
+private:
+ QString& strEsc_;
+ Ui::dlgDefineEscape ui_;
+};
+
+} //namespace FQTerm
+
+#endif //__FQTERM_DEFINEESCAPE__ \ No newline at end of file
diff --git a/src/ui/defineescape.ui b/src/ui/defineescape.ui
new file mode 100644
index 0000000..6549610
--- /dev/null
+++ b/src/ui/defineescape.ui
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>dlgDefineEscape</class>
+ <widget class="QDialog" name="dlgDefineEscape">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>213</width>
+ <height>121</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Define Escape</string>
+ </property>
+ <widget class="QLabel" name="lblEscape">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>10</y>
+ <width>81</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Escape String *[</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="edtEscape">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>40</y>
+ <width>171</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QWidget" name="">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>76</y>
+ <width>171</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="btnOK">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/fqterm_canvas.cpp b/src/ui/fqterm_canvas.cpp
new file mode 100644
index 0000000..f17ee58
--- /dev/null
+++ b/src/ui/fqterm_canvas.cpp
@@ -0,0 +1,537 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QCloseEvent>
+#include <QKeyEvent>
+#include <QResizeEvent>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMenuBar>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QLabel>
+#include <QMatrix>
+#include <QToolBar>
+#include <QActionGroup>
+#include <QToolButton>
+#include <QDesktopServices>
+#include <QDir>
+#include <QUrl>
+#include <QImageReader>
+#include <QMovie>
+
+#include "fqterm_canvas.h"
+#include "fqterm.h"
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_filedialog.h"
+
+namespace FQTerm {
+
+FQTermCanvas::FQTermCanvas(FQTermConfig * config, QWidget *parent, Qt::WFlags f)
+ : QScrollArea(parent),
+ adjustMode_(Fit),
+ aspectRatioMode_(Qt::KeepAspectRatio){
+ // TODO: dirty trick
+
+ if (f == 0) {
+ isEmbedded = true;
+ } else {
+ isEmbedded = false;
+ }
+
+ config_ = config;
+
+ menu_ = new QMenu(parent);
+ menu_->addAction(tr("zoom 1:1"), this, SLOT(oriSize()), tr("Ctrl+Z"));
+ menu_->addAction(tr("adjust size"), this, SLOT(autoAdjust()), tr("Ctrl+X"));
+ menu_->addSeparator();
+ QAction* zoomInAction = menu_->addAction(tr("zoom in"), this,
+ SLOT(zoomIn()), tr("Ctrl+="));
+ QAction* zoomOutAction = menu_->addAction(tr("zoom out"), this,
+ SLOT(zoomOut()), tr("Ctrl+-"));
+ if (!isEmbedded) {
+ menu_->addAction(tr("fullscreen"), this, SLOT(fullScreen()), tr("Ctrl+F"));
+ }
+ menu_->addSeparator();
+ menu_->addAction(tr("rotate CW 90"), this, SLOT(cwRotate()),
+ tr("Ctrl+]"));
+ menu_->addAction(tr("rotate CCW 90"), this, SLOT(ccwRotate()),
+ tr("Ctrl+["));
+ menu_->addSeparator();
+ gifPlayAction_ = menu_->addAction(tr("play gif"), this,
+ SLOT(playGIF()), tr("Ctrl+/"));
+ menu_->addSeparator();
+ menu_->addAction(tr("save as"), this, SLOT(saveImage()), tr("Ctrl+S"));
+ menu_->addAction(tr("copy to"), this, SLOT(copyImage()), tr("Ctrl+C"));
+ menu_->addAction(tr("silent copy"), this, SLOT(silentCopy()),
+ tr("Shift+S"));
+
+ if (!isEmbedded) {
+ menu_->addAction(tr("delete"), this, SLOT(deleteImage()), tr("Ctrl+D"));
+
+ menu_->addSeparator();
+ menu_->addAction(tr("exit"), this, SLOT(close()), tr("Ctrl+Q"));
+ }
+
+ toolBar_ = new QToolBar(this);
+
+ toolBar_->addAction(QIcon(getPath(RESOURCE) + "pic/ViewerButtons/open.png"),
+ tr("Open Dir"), this, SLOT(openDir()));
+
+ zoomInAction->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomin.png"));
+ zoomOutAction->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomout.png"));
+
+ toolBar_->addAction(zoomInAction);
+ toolBar_->addAction(zoomOutAction);
+
+ QActionGroup* gifGroup = new QActionGroup(this);
+ gifPlayAction_->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/play_gif.png"));
+ toolBar_->addAction(gifPlayAction_);
+
+ QActionGroup* showSettingGroup = new QActionGroup(this);
+ QMenu* showSettingMenu = new QMenu(this);
+
+ QAction* showSettingFitAction =
+ showSettingMenu->addAction(tr("show Fit"), this, SLOT(SetAdjustMode()));
+ showSettingFitAction->setCheckable(true);
+ showSettingFitAction->setData(Fit);
+ showSettingGroup->addAction(showSettingFitAction);
+
+ QAction* showSettingMaxFitAction =
+ showSettingMenu->addAction(tr("show MaxFit"),
+ this, SLOT(SetAdjustMode()));
+ showSettingMaxFitAction->setCheckable(true);
+ showSettingMaxFitAction->setData(MaxFit);
+ showSettingGroup->addAction(showSettingMaxFitAction);
+
+ QAction* showSettingOriginAction =
+ showSettingMenu->addAction(tr("show Origin"),
+ this, SLOT(SetAdjustMode()));
+ showSettingOriginAction->setCheckable(true);
+ showSettingOriginAction->setData(Origin);
+ showSettingGroup->addAction(showSettingOriginAction);
+
+ QAction* showSettingStrechAction =
+ showSettingMenu->addAction(tr("show Stretch"),
+ this, SLOT(SetAdjustMode()));
+ showSettingStrechAction->setCheckable(true);
+ showSettingStrechAction->setData(Stretch);
+ showSettingGroup->addAction(showSettingStrechAction);
+
+ QToolButton* showSettingButton = new QToolButton(this);
+ QAction* dummyAction = new QAction(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/adjustsize.png"),
+ tr("Adjust Mode"), showSettingButton);
+ showSettingButton->setDefaultAction(dummyAction);
+ showSettingButton->setMenu(showSettingMenu);
+ showSettingButton->setPopupMode(QToolButton::InstantPopup);
+
+ showSettingFitAction->setChecked(true);
+
+ toolBar_->addWidget(showSettingButton);
+
+
+
+#if QT_VERSION >= 0x040200
+ setAlignment(Qt::AlignCenter);
+#endif
+ label_ = new QLabel(viewport());
+ label_->setScaledContents(true);
+ label_->setAlignment(Qt::AlignCenter);
+ label_->setText(tr("No Preview Available"));
+ setWidget(label_);
+ // resize(200, 100);
+}
+
+FQTermCanvas::~FQTermCanvas() {
+ //delete label;
+ //delete m_pMenu;
+}
+
+void FQTermCanvas::oriSize() {
+ useAdjustMode_ = false;
+ imageSize_ = image_.size();
+ adjustSize(size());
+}
+
+void FQTermCanvas::zoomIn() {
+ useAdjustMode_ = false;
+ resizeImage(0.05f);
+}
+
+void FQTermCanvas::zoomOut() {
+ useAdjustMode_ = false;
+ resizeImage(-0.05f);
+}
+
+void FQTermCanvas::autoAdjust() {
+ useAdjustMode_ = true;
+ adjustSize(size());
+}
+
+void FQTermCanvas::cwRotate() {
+ rotateImage(90);
+}
+
+void FQTermCanvas::ccwRotate() {
+ rotateImage(-90);
+}
+
+void FQTermCanvas::fullScreen() {
+ if (!isFullScreen()) {
+ showFullScreen();
+ } else {
+ showNormal();
+ }
+}
+
+void FQTermCanvas::loadImage(const QString& name, bool performAdjust) {
+ if (label_->movie()) {
+ label_->movie()->stop();
+ label_->setMovie(NULL);
+ }
+
+ gifPlayAction_->setEnabled(name.endsWith("gif"));
+
+
+ bool res = image_.load(name);
+ if (!res) {
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ !res && it != formats.end();
+ ++it) {
+ res = image_.load(name, it->data());
+ }
+ }
+ if (!image_.isNull()) {
+ fileName_ = QFileInfo(name).absoluteFilePath();
+ setWindowTitle(QFileInfo(name).fileName());
+
+ useAdjustMode_ = true;
+
+ if (!isEmbedded) {
+ QSize szView(image_.size());
+ szView.scale(640, 480, aspectRatioMode_);
+
+ if (szView.width() < image_.width()) {
+ imageSize_ = szView;
+ label_->resize(imageSize_);
+ label_->clear();
+ label_->setAlignment(Qt::AlignCenter);
+ label_->setPixmap(scaleImage(imageSize_));
+
+ if (!isEmbedded) {
+ resize(szView *1.1);
+ }
+ } else {
+ imageSize_ = image_.size();
+ label_->resize(imageSize_);
+ label_->setPixmap(QPixmap::fromImage(image_));
+ if (!isEmbedded) {
+ resize(imageSize_ + QSize(5, 5));
+ }
+ }
+ }
+ if (isEmbedded) {
+ label_->hide();
+ if (performAdjust) autoAdjust();
+ else label_->setPixmap(QPixmap::fromImage(image_));
+
+ label_->show();
+ }
+
+ } else {
+ FQ_TRACE("canvas", 1) << "Can't load the image: " << name;
+ }
+}
+
+void FQTermCanvas::playGIF() {
+ if (fileName_.endsWith("gif")) {
+ gifPlayer_.setFileName(fileName_);
+ if (gifPlayer_.isValid()) {
+ label_->setMovie(&gifPlayer_);
+ gifPlayer_.stop();
+ gifPlayer_.start();
+ return;
+ }
+ }
+}
+
+void FQTermCanvas::resizeImage(float ratio) {
+ QSize szImg = imageSize_;
+ szImg *= (1+ratio);
+ //we dont need so big
+ if (szImg.width() > 10000 || szImg.height() > 10000 ||
+ szImg.width() < 1 || szImg.height() < 1) {
+ return ;
+ }
+ imageSize_ = szImg;
+
+ if (!isFullScreen() && !isEmbedded) {
+ resize(imageSize_ *1.1);
+ } else {
+ adjustSize(size());
+ }
+}
+
+void FQTermCanvas::rotateImage(float ang) {
+ QMatrix wm;
+
+ wm.rotate(ang);
+
+ image_ = image_.transformed(wm, Qt::SmoothTransformation);
+
+ imageSize_ = image_.size();
+
+ adjustSize(size());
+}
+
+void FQTermCanvas::copyImage() {
+ QFileInfo fi(fileName_);
+// QString strSave =
+// QFileDialog::getSaveFileName(
+// this,tr("Choose a filename to save under"),
+// QDir::currentPath() + fi.fileName());
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(fi.fileName(), "");
+ if (strSave.isEmpty()) {
+ return ;
+ }
+ QFile file(fileName_);
+ if (file.open(QIODevice::ReadOnly)) {
+ QFile save(strSave);
+ if (save.open(QIODevice::WriteOnly)) {
+ QByteArray ba = file.readAll();
+ QDataStream ds(&save);
+ ds.writeRawData(ba, ba.size());
+ save.close();
+ }
+ file.close();
+ }
+}
+
+void FQTermCanvas::silentCopy() {
+ // save it to $savefiledialog
+ QString strPath = config_->getItemValue("global", "savefiledialog");
+
+ QFileInfo fi(fileName_);
+ QString strSave = strPath + "/" + fi.fileName();
+
+ fi.setFile(strSave);
+
+ // add (%d) if exist
+ int i = 1;
+ while (fi.exists()) {
+ strSave = QString("%1/%2(%3).%4").arg(fi.dir().path()).arg
+ (fi.completeBaseName()).arg(i).arg(fi.suffix());
+ fi.setFile(strSave);
+ }
+
+ // copy it
+ QFile file(fileName_);
+ if (file.open(QIODevice::ReadOnly)) {
+ QFile save(strSave);
+ if (save.open(QIODevice::WriteOnly)) {
+ QByteArray ba = file.readAll();
+ QDataStream ds(&save);
+ ds.writeRawData(ba, ba.size());
+ save.close();
+ }
+ file.close();
+ }
+}
+
+QPixmap FQTermCanvas::scaleImage(const QSize &sz) {
+ return QPixmap::fromImage(
+ image_.scaled(sz, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+}
+
+void FQTermCanvas::moveImage(float dx, float dy) {
+ scrollContentsBy(int(widget()->width()*dx), int(widget()->height() *dy));
+}
+
+void FQTermCanvas::saveImage() {
+
+ QFileInfo fi(fileName_);
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(fi.fileName(), "");
+ if (strSave.isEmpty()) {
+ return ;
+ }
+ QString fmt = fi.suffix().toUpper();
+ if (!image_.save(strSave, fmt.toLatin1())) {
+ QMessageBox::warning(this, tr("Failed to save file"),
+ tr("Cant save file, maybe format not supported"));
+ }
+}
+
+void FQTermCanvas::deleteImage() {
+ QFile::remove(fileName_);
+ close();
+}
+
+void FQTermCanvas::closeEvent(QCloseEvent *ce) {
+ if (!isEmbedded) {
+ delete this;
+ }
+}
+
+void FQTermCanvas::viewportResizeEvent(QResizeEvent *re) {
+ adjustSize(re->size());
+}
+
+void FQTermCanvas::mousePressEvent(QMouseEvent *me) {
+ /* remove this to avoid click by mistake
+ if(me->button()&LeftButton)
+ {
+ close();
+ return;
+ }
+ */
+ if (me->button() &Qt::RightButton) {
+ menu_->popup(me->globalPos());
+ }
+}
+
+void FQTermCanvas::keyPressEvent(QKeyEvent *ke) {
+ switch (ke->key()) {
+ case Qt::Key_Escape:
+ if (!isEmbedded) {
+ if (isFullScreen()) {
+ showNormal();
+ } else {
+ close();
+ }
+ }
+
+ break;
+ case Qt::Key_D:
+ if (!isEmbedded){
+ deleteImage();
+ }
+ break;
+ case Qt::Key_Q:
+ if (!isEmbedded){
+ close();
+ }
+ break;
+ }
+}
+
+void FQTermCanvas::adjustSize(QSize szView) {
+ szView -= QSize(2 * frameWidth(), 2 * frameWidth());
+ if (label_->pixmap() == NULL && image_.isNull()) {
+ label_->resize(szView);
+ return ;
+ }
+
+ QSize szImg = imageSize_;
+
+ if (useAdjustMode_) {
+ szImg = image_.size();
+ switch(adjustMode_)
+ {
+ case MaxFit:
+ szImg.scale(szView, aspectRatioMode_);
+ break;
+ case Fit:
+ if (szImg.width() > szView.width() || szImg.height() > szView.height() ||
+ szImg.width() < image_.width()) {
+ szImg.scale(szView, aspectRatioMode_);
+ }
+ szImg = szImg.boundedTo(image_.size());
+ if (szImg.width() < 1 || szImg.height() < 1) {
+ return;
+ }
+ break;
+ case Origin:
+ break;
+ case Stretch:
+ szImg = szView;
+ break;
+ }
+ }
+
+ imageSize_ = szImg;
+ label_->resize(imageSize_);
+ label_->setPixmap(scaleImage(imageSize_));
+}
+
+void FQTermCanvas::resizeEvent(QResizeEvent * event) {
+ if (useAdjustMode_){
+ autoAdjust();
+ }
+ else adjustSize(size());
+ QScrollArea::resizeEvent(event);
+}
+
+QMenu* FQTermCanvas::menu() {
+ return menu_;
+}
+
+
+QToolBar* FQTermCanvas::ToolBar() {
+ return toolBar_;
+}
+
+void FQTermCanvas::SetAdjustMode(AdjustMode am) {
+ adjustMode_ = am;
+ if (adjustMode_ == Stretch) {
+ aspectRatioMode_ = Qt::IgnoreAspectRatio;
+ }
+ else {
+ aspectRatioMode_ = Qt::KeepAspectRatio;
+ }
+ autoAdjust();
+}
+
+void FQTermCanvas::SetAdjustMode() {
+ SetAdjustMode(AdjustMode((((QAction*)sender())->data()).toInt()));
+}
+
+void FQTermCanvas::openDir() {
+ QString poolPath = config_->getItemValue("preference", "pool");
+ if (poolPath.isEmpty()) {
+ poolPath = getPath(USER_CONFIG) + "pool/";
+ }
+#ifdef WIN32
+ QString path = "file:///" + poolPath;
+#else
+ QString path = "file://" + poolPath;
+#endif
+ QDesktopServices::openUrl(path);
+}
+
+void FQTermCanvas::updateImage(const QString& filename)
+{
+ if (QFileInfo(filename).absoluteFilePath().toLower() == fileName_) {
+ loadImage(fileName_);
+ }
+
+}
+
+
+} // namespace FQTerm
+
+#include "fqterm_canvas.moc"
diff --git a/src/ui/fqterm_canvas.h b/src/ui/fqterm_canvas.h
new file mode 100644
index 0000000..be15879
--- /dev/null
+++ b/src/ui/fqterm_canvas.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_CANVAS_H
+#define FQTERM_CANVAS_H
+
+#include <QScrollArea>
+#include <QImage>
+#include <QMovie>
+
+class QAction;
+class QLabel;
+class QMenu;
+class QCloseEvent;
+class QMouseEvent;
+class QKeyEvent;
+class QResizeEvent;
+class QToolBar;
+class QImage;
+
+namespace FQTerm {
+
+class FQTermConfig;
+class ExifExtractor;
+class FQTermFileDialog;
+
+class FQTermCanvas: public QScrollArea {
+ Q_OBJECT;
+ public:
+ FQTermCanvas(FQTermConfig *, QWidget *parent_ = NULL, Qt::WFlags f = Qt::Window);
+ ~FQTermCanvas();
+
+ enum AdjustMode{Origin, Fit, Stretch, MaxFit};
+
+ void updateImage(const QString& filename);
+ void loadImage(const QString&, bool = true);
+ QMenu* menu();
+ QToolBar* ToolBar();
+ public slots:
+ void oriSize();
+ void zoomIn();
+ void zoomOut();
+ void autoAdjust();
+ void fullScreen();
+ void saveImage();
+ void copyImage();
+ void silentCopy();
+ void cwRotate();
+ void ccwRotate();
+ void deleteImage();
+ void SetAdjustMode(AdjustMode am);
+ void openDir();
+ void playGIF();
+ protected slots:
+ void SetAdjustMode();
+ protected:
+ void resizeEvent (QResizeEvent * event);
+ void moveImage(float, float);
+ void resizeImage(float);
+ void rotateImage(float);
+
+ void closeEvent(QCloseEvent*);
+ void mousePressEvent(QMouseEvent*);
+ void keyPressEvent(QKeyEvent *ke);
+ void viewportResizeEvent(QResizeEvent *re);
+ void adjustSize(QSize);
+ QPixmap scaleImage(const QSize &);
+ protected:
+ QLabel *label_;
+ bool useAdjustMode_;
+ QSize imageSize_;
+ QString fileName_;
+ QImage image_;
+ QMovie gifPlayer_;
+ QMenu *menu_;
+ QToolBar *toolBar_;
+ FQTermConfig * config_;
+ QAction* gifPlayAction_;
+
+ AdjustMode adjustMode_;
+ Qt::AspectRatioMode aspectRatioMode_;
+ // TODO: Very dirty trick, I hate it
+ bool isEmbedded;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_CANVAS_H
diff --git a/src/ui/fqterm_time_label.cpp b/src/ui/fqterm_time_label.cpp
new file mode 100644
index 0000000..1d05b0e
--- /dev/null
+++ b/src/ui/fqterm_time_label.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_time_label.h"
+
+#include <QLabel>
+#include <QTimerEvent>
+#include <QDateTime>
+
+namespace FQTerm {
+
+//constructor
+FQTermTimeLabel::FQTermTimeLabel(QWidget *parent, const char *name, Qt::WFlags f)
+ : QLabel(parent, f) {
+ setAlignment(Qt::AlignHCenter);
+ currentTime_ = new QTime();
+ currentTime_->start();
+ startTimer(1000);
+}
+
+//destructor
+FQTermTimeLabel::~FQTermTimeLabel() {
+ delete currentTime_;
+}
+
+//timer to display the current time
+void FQTermTimeLabel::timerEvent(QTimerEvent*) {
+ setText(currentTime_->currentTime().toString());
+}
+
+} // namespace FQTerm
+
+#include "fqterm_time_label.moc"
diff --git a/src/ui/fqterm_time_label.h b/src/ui/fqterm_time_label.h
new file mode 100644
index 0000000..ac510b6
--- /dev/null
+++ b/src/ui/fqterm_time_label.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TIME_LABEL_H
+#define FQTERM_TIME_LABEL_H
+
+#include <QTimerEvent>
+#include <QLabel>
+
+class QTime;
+
+namespace FQTerm {
+
+class FQTermTimeLabel: public QLabel {
+ Q_OBJECT;
+ public:
+ FQTermTimeLabel(QWidget *parent, const char *name = 0, Qt::WFlags f = 0);
+ ~FQTermTimeLabel();
+
+ protected:
+ QTime *currentTime_;
+ void timerEvent(QTimerEvent*);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TIME_LABEL_H
diff --git a/src/ui/fqterm_tool_button.cpp b/src/ui/fqterm_tool_button.cpp
new file mode 100644
index 0000000..4680e6f
--- /dev/null
+++ b/src/ui/fqterm_tool_button.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_tool_button.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+FQTermToolButton::FQTermToolButton(QWidget *parent_, int id, QString name)
+ : QToolButton(parent_) {
+ setObjectName(name);
+ this->id_ = id;
+ FQ_VERIFY(connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())));
+}
+
+FQTermToolButton::~FQTermToolButton(){}
+
+void FQTermToolButton::slotClicked() {
+ emit(buttonClicked(id_));
+}
+
+} // namespace FQTerm
+
+#include "fqterm_tool_button.moc"
diff --git a/src/ui/fqterm_tool_button.h b/src/ui/fqterm_tool_button.h
new file mode 100644
index 0000000..56f5626
--- /dev/null
+++ b/src/ui/fqterm_tool_button.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_TOOL_BUTTON_H
+#define FQTERM_TOOL_BUTTON_H
+
+#include <QToolButton>
+
+namespace FQTerm {
+
+class FQTermToolButton: public QToolButton {
+ Q_OBJECT;
+ public:
+ FQTermToolButton(QWidget *parent_, int id, QString name = "");
+ ~FQTermToolButton();
+
+ signals:
+ void buttonClicked(int);
+
+ protected slots:
+ void slotClicked();
+
+ protected:
+ int id_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_TOOL_BUTTON_H
diff --git a/src/ui/imageviewer.cpp b/src/ui/imageviewer.cpp
new file mode 100644
index 0000000..296c5a8
--- /dev/null
+++ b/src/ui/imageviewer.cpp
@@ -0,0 +1,1749 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QAction>
+#include <QBuffer>
+#include <QCursor>
+#include <QComboBox>
+#include <QDateTime>
+#include <QDataStream>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QIcon>
+#include <QKeyEvent>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMenuBar>
+#include <QPainter>
+#include <QPixmap>
+#include <QPushButton>
+#include <QSizeGrip>
+#include <QString>
+#include <QTextCodec>
+#include <QTimer>
+#include <QToolTip>
+#include <QTransform>
+#include <QTreeView>
+#include <QTextEdit>
+#include <QHeaderView>
+#include <QImageReader>
+
+#include "fqterm_canvas.h"
+#include "fqterm_config.h"
+#include "fqterm_exif_extractor.h"
+#include "fqterm_filedialog.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+#include "imageviewer.h"
+
+
+namespace FQTerm {
+
+ typedef enum {
+ V_UNKNOWN = -1,
+ V_ORIGINAL = 0,
+ V_SHADOW,
+ V_BESTFIT,
+ V_ZOOMIN,
+ V_ZOOMOUT,
+ V_ROTLEFT,
+ V_ROTRIGHT,
+ V_FULLSCREEN
+ } slideViewModes;
+
+ typedef enum {
+ SORT_UNSORTED = -1,
+ SORT_LIKE,
+ SORT_NEW,
+ SORT_TRASH,
+ SORT_RECOVER,
+ SORT_TITLE
+ } slideSortFlags;
+
+
+ typedef enum {
+ STAT_UNKNOWN = -1,
+ STAT_LIKE,
+ STAT_NEW,
+ STAT_TRASH,
+ STAT_RECOVER,
+ STAT_TITLE,
+ STAT_ALL
+ } slideStatus;
+
+ typedef enum {
+ GEN_UNKNOWN = -1,
+ GEN_CANCEL,
+ GEN_NOCHANGE,
+ GEN_RESHUFFLE,
+ GEN_NOTAG,
+ GEN_INTRASH,
+ GEN_INTRASHES,
+ GEN_TOSAVE,
+ GEN_TOSAVES,
+ GEN_TRASH,
+ GEN_TRASHES,
+ GEN_NOTRASH,
+ GEN_RECOVER,
+ GEN_RECOVERS,
+ GEN_NORECOVER,
+ GEN_SAVE,
+ GEN_SAVES,
+ GEN_DELETE,
+ GEN_DELETES,
+ GEN_SEARCHWRAP,
+ GEN_SEARCHNOMATCH
+ } generalStatus;
+
+ static const char *fqloraTagStatus[] = {
+ "Like",
+ "New",
+ "Trash",
+ "Recover",
+ "Title"
+ };
+
+ static const char *fqloraGeneralStatus[] = {
+ "Canceled.",
+ "No changes for ",
+ "Reshuffled by ",
+ "No tags by ",
+ "item in the trash.",
+ "items in the trash.",
+ "item to save.",
+ "items to save.",
+ "image trashed.",
+ "images trashed.",
+ "Nothing to trash.",
+ "image recovered.",
+ "images recovered.",
+ "Nothing to recover.",
+ "image saved in ",
+ "images saved in ",
+ "image deleted.",
+ "images deleted.",
+ "Search wrapped.",
+ "No matches."
+ };
+
+ static const int toolBarFixedHeight = 40;
+ static const int statusBarFixedHeight = 18;
+ static const QSize sortBoxFixedSize(110, 25);
+
+ static const QString &iconPath(const QString &fileName) {
+
+ static QString p = "";
+
+ if (!fileName.isEmpty()) {
+ p = getPath(RESOURCE) + ICON_SOURCE + fileName;
+ }
+
+ return p;
+ }
+
+ const QString &isPlural(const int num, const int status) {
+
+ static QString m = "";
+
+ if (num == 1) {
+ return (m = fqloraGeneralStatus[status]);
+ } else if (num > 1 && status > GEN_UNKNOWN && status < GEN_DELETES) {
+ return (m = fqloraGeneralStatus[status + 1]);
+ }
+
+ return (m = fqloraGeneralStatus[GEN_UNKNOWN]);
+ }
+
+ // get user's desktop rectangle
+ static const QRect &desktopSize() {
+
+ static QRect size;
+ QDesktopWidget myDesktop;
+ return ((size = myDesktop.screenGeometry(myDesktop.primaryScreen())));
+ }
+
+ // FQTermImageFlow
+ FQTermImageFlow::~FQTermImageFlow() {
+
+ delete statusBar_;
+ delete imageMenu_;
+ delete imageFlow_;
+
+ statusBar_ = NULL;
+ imageMenu_ = NULL;
+ imageFlow_ = NULL;
+ }
+
+ FQTermImageFlow::FQTermImageFlow(FQTermConfig * config, QWidget *parent,
+ Qt::WindowFlags wflag) :
+ FQTermImage(parent, wflag),
+ imageFlow_(new ImageFlow(this)),
+ imageMenu_(new ImageMenu(this)),
+ statusBar_(new QStatusBar(this)),
+ config_(config) {
+
+ setWindowTitle(IMAGE_BROWSER_NAME);
+ setAutoFillBackground(true);
+ setBackgroundRole(QPalette::Midlight);
+ setFixedSize(desktopSize().width() / 1.3, desktopSize().height() / 1.9);
+
+ FQ_VERIFY(connect(this, SIGNAL(isTrashEmpty()), this, SLOT(checkTrashState())));
+
+ // emblem state
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(emblemStatus(const int)), imageMenu_, SLOT(updateEmblems(const int))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(toggleFlowStatus(const int)), imageFlow_, SLOT(toggleStatus(const int))));
+
+ // clear state
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(clearStatus(const bool)), imageMenu_, SLOT(updateClear(const bool))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(clearImages()), this, SLOT(clearImages())));
+
+ // save state
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(saveStatus(const bool)), imageMenu_, SLOT(updateSave(const bool))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(saveImages()), this, SLOT(saveImages())));
+
+ // trash state
+ FQ_VERIFY(connect(this, SIGNAL(trashStatus(const bool)), imageMenu_, SLOT(updateDustbin(const bool))));
+ FQ_VERIFY(connect(imageMenu_, SIGNAL(recoverImages()), this, SLOT(recoverImages())));
+
+ // constructs a tool bar and its tool buttons
+ QAction *closeBrowserAct = new QAction(QIcon(iconPath("window-close.png")), tr("Close"), this);
+ closeBrowserAct->setShortcut(QKeySequence(Qt::Key_Q));
+ FQ_VERIFY(connect(closeBrowserAct, SIGNAL(triggered()), this, SLOT(close())));
+
+ QAction *trashAllAct = new QAction(QIcon(iconPath("trash-empty.png")), tr("Trash All"), this);
+ trashAllAct->setShortcut(QKeySequence(Qt::Key_Delete));
+ FQ_VERIFY(connect(trashAllAct, SIGNAL(triggered()), this, SLOT(trashAllImages())));
+
+ QLabel *sortLabel = new QLabel(this);
+ sortLabel->setMargin(5);
+ sortLabel->setToolTip("Reshuffle images by tags");
+ sortLabel->setPixmap(QPixmap(iconPath("edit-shuffle.png")));
+
+ QComboBox *sortBox = new QComboBox(this);
+ sortBox->setFocusPolicy(Qt::ClickFocus);
+ sortBox->setFont(QFont("Serif", 12));
+ sortBox->setFrame(false);
+ sortBox->setFixedSize(sortBoxFixedSize);
+ sortBox->insertItem(0, QIcon(iconPath("emblem-like-16x16.png")), tr("Like "));
+ sortBox->insertItem(1, QIcon(iconPath("emblem-new-16x16.png")), tr("New "));
+ sortBox->insertItem(2, QIcon(iconPath("emblem-trash-16x16.png")), tr("Trash "));
+ sortBox->insertItem(3, QIcon(iconPath("emblem-recover-16x16.png")), tr("Recover "));
+ sortBox->insertItem(4, QIcon(iconPath("emblem-title-16x16.png")), tr("Title "));
+ FQ_VERIFY(connect(sortBox, SIGNAL(currentIndexChanged(int)), this, SLOT(reshuffleImages(int))));
+
+ QToolBar *toolBar = new QToolBar(this);
+ toolBar->setFixedHeight(toolBarFixedHeight);
+ toolBar->setIconSize(QSize(32, 32));
+ toolBar->addAction(closeBrowserAct);
+ toolBar->addSeparator();
+ toolBar->addWidget(sortLabel);
+ toolBar->addWidget(sortBox);
+ toolBar->addSeparator();
+ toolBar->addAction(trashAllAct);
+
+ // constructs a status bar to show instant messages
+ statusBar_->setSizeGripEnabled(false);
+ statusBar_->setFixedHeight(statusBarFixedHeight);
+ statusBar_->setFont(QFont("Serif", 10, QFont::Bold));
+ FQ_VERIFY(connect(imageFlow_, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &))));
+ FQ_VERIFY(connect(this, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &))));
+ // constructs a horizontal layout
+ QVBoxLayout *vBox = new QVBoxLayout(this);
+ vBox->setMargin(0);
+ vBox->setSpacing(0);
+ vBox->addWidget(toolBar);
+ vBox->addWidget(imageFlow_);
+ vBox->addWidget(imageMenu_);
+ vBox->addWidget(statusBar_);
+ vBox->setEnabled(true);
+ setLayout(vBox);
+ }
+
+ const QString &FQTermImageFlow::poolSource(void) const {
+
+ static QString p = "";
+
+ p = config_->getItemValue("preference", "pool");
+
+ if (p.isEmpty()) {
+ p = getPath(USER_CONFIG) + POOL_SOURCE;
+ }
+
+ return p;
+ }
+
+ const QString &FQTermImageFlow::trashSource(void) const {
+
+ static QString p = "";
+
+ p = poolSource() + TRASH_SOURCE;
+ return p;
+ }
+
+ // these three functions below are kept for
+ // API compatibility.
+ void FQTermImageFlow::adjustItemSize() {
+
+ }
+
+ void FQTermImageFlow::scrollTo(const QString &filePath) {
+
+ }
+
+ void FQTermImageFlow::updateImage(const QString &filePath) {
+
+ }
+
+ // slots and functions
+ void FQTermImageFlow::loadImages(const int status) {
+
+ int i;
+ int itemStatus = (status == STAT_RECOVER) ? status : STAT_UNKNOWN;
+ QString comment;
+ QFileInfoList sourceList = sortedList(poolSource());
+ QFileInfoList targetList = imageFlow_->digest(STAT_ALL);
+
+ for (i = 0; i < sourceList.count(); i++) {
+
+ if (!targetList.contains(sourceList[i])) {
+
+ QImage image;
+
+ if (!image.load(sourceList[i].absoluteFilePath())) {
+ QFileIconProvider iconProvider;
+ image = iconProvider.icon(sourceList[i]).pixmap(desktopSize().height() / 6.0).toImage();
+ } else {
+ image = image.scaled(desktopSize().width() / 6.0, desktopSize().height() / 6.0,
+ Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ }
+
+ /* TODO */
+ /* there should be a more flexible */
+ /* method to deal with items' status */
+ if (status == STAT_ALL) {
+ itemStatus = STAT_NEW;
+ }
+
+ ImageFlowItem newItem(image, sourceList[i], comment,itemStatus);
+ imageFlow_->add(newItem);
+ }
+ }
+ }
+
+ void FQTermImageFlow::reshuffleImages(const int status) {
+
+ // there are images in the pool directory
+ QList<qint64> itemKeys = imageFlow_->sort(status);
+
+ if (imageFlow_->reorder(itemKeys)) {
+ imageFlow_->setCurrentSlide(0);
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_RESHUFFLE]) + tr(fqloraTagStatus[status]));
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOCHANGE]) + tr(fqloraTagStatus[status]));
+ }
+ }
+
+ void FQTermImageFlow::saveImages() {
+
+ QFileInfoList toSave = imageFlow_->digest(STAT_LIKE);
+
+ if (!toSave.isEmpty()) {
+
+ QMessageBox box;
+ box.setWindowModality(Qt::NonModal);
+ box.setWindowTitle("Information");
+ box.setIconPixmap(QPixmap(iconPath("emblem-info.png")));
+ box.setTextFormat(Qt::RichText);
+ box.setText(QString("<b>%1</b> ").arg(toSave.count()) + isPlural(toSave.count(), GEN_TOSAVE));
+ QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
+ QPushButton *saveAllButton = box.addButton(QMessageBox::SaveAll);
+ box.setDefaultButton(cancelButton);
+ box.exec();
+
+ if (box.clickedButton() == saveAllButton) {
+
+ FQTermFileDialog fileDialog(config_);
+ QString savePath =
+ fileDialog.getExistingDirectory(tr("Save your likes under"), "*");
+
+ if (savePath.isEmpty()) {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
+ return;
+ }
+
+ int i;
+ for (i = 0; i < toSave.count(); i++) {
+ QFile::rename(toSave[i].absoluteFilePath(), savePath + toSave[i].fileName());
+ }
+
+ imageFlow_->strip(STAT_LIKE);
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_SAVE) + savePath);
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
+ }
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_LIKE]));
+ }
+ }
+
+ void FQTermImageFlow::checkTrashState() {
+
+ QDir trashPath(trashSource());
+
+ if (trashPath.count() <= 2) {
+ emit trashStatus(false);
+ } else {
+ emit trashStatus(true);
+ }
+ }
+
+ void FQTermImageFlow::clearImages() {
+
+ int i;
+ QString trashPath = trashSource();
+ QDir trashDir(trashPath);
+ QFileInfoList toRemove = imageFlow_->digest(STAT_TRASH);
+
+ if (!trashDir.exists()) {
+ trashDir.mkdir(trashPath);
+ }
+
+ if (!toRemove.isEmpty()) {
+
+ for (i = 0; i < toRemove.count(); i++) {
+ if (QFile::exists(toRemove[i].absoluteFilePath())) {
+ QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName());
+ }
+ }
+
+ imageFlow_->strip(STAT_TRASH);
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH));
+ emit isTrashEmpty();
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH]));
+ }
+ }
+
+ void FQTermImageFlow::trashAllImages() {
+
+ int i;
+ QString trashPath = trashSource();
+ QDir trashDir(trashPath);
+ QFileInfoList toRemove = imageFlow_->digest(STAT_ALL);
+
+ if (!trashDir.exists()) {
+ trashDir.mkdir(trashPath);
+ }
+
+ if (imageFlow_->count() > 0) {
+ for (i = 0; i < imageFlow_->count(); i++) {
+ if (QFile::exists(toRemove[i].absoluteFilePath())) {
+ QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName());
+ }
+ }
+
+ imageFlow_->clear();
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH));
+ emit isTrashEmpty();
+ } else {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH]));
+ }
+ }
+
+ void FQTermImageFlow::recoverImages() {
+
+ QString trashPath = trashSource();
+ QDir trashDir(trashPath);
+
+ if (!trashDir.exists()) {
+ trashDir.mkdir(trashPath);
+ } else if (trashDir.count() > 2) {
+
+ int action = -1;;
+ QFileInfoList toRecover = sortedList(trashPath);
+
+ if (!toRecover.isEmpty()) {
+
+ QMessageBox box;
+ box.setWindowModality(Qt::NonModal);
+ box.setWindowTitle("Take action");
+ box.setIconPixmap(QPixmap(iconPath("emblem-info.png")));
+ box.setTextFormat(Qt::RichText);
+ box.setText(QString("<b>%1</b> ").arg(toRecover.count()) + isPlural(toRecover.count(), GEN_INTRASH));
+ QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
+ QPushButton *recoverButton = box.addButton(tr("Recover"), QMessageBox::ApplyRole);
+ recoverButton->setIcon(QIcon(iconPath("button-recover.png")));
+ QPushButton *deleteButton = box.addButton(tr("Delete"), QMessageBox::ApplyRole);
+ deleteButton->setIcon(QIcon(iconPath("button-delete.png")));
+ box.setDefaultButton(cancelButton);
+ box.exec();
+
+ if (box.clickedButton() == cancelButton) {
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
+ return;
+ } else if (box.clickedButton() == recoverButton) {
+ action = 1;
+ } else if (box.clickedButton() == deleteButton) {
+ action = 0;
+ }
+
+ int i;
+ QFile imageFile;
+ QString poolPath = poolSource();
+
+ for (i = 0; i < toRecover.count(); i++) {
+ if (action == 1) {
+ QFile::rename(toRecover[i].absoluteFilePath(), poolPath + toRecover[i].fileName());
+ } else if (action == 0) {
+ imageFile.setFileName(toRecover[i].absoluteFilePath());
+ imageFile.remove();
+ }
+ }
+
+ if (action == 1) {
+ loadImages(STAT_RECOVER);
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_RECOVER));
+ } else if (action == 0) {
+ emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_DELETE));
+ }
+ }
+ } else {
+
+ emit statusMessage(tr(fqloraGeneralStatus[GEN_NORECOVER]));
+ }
+
+ emit isTrashEmpty();
+ }
+
+
+ void FQTermImageFlow::showStatusMessage(const QString &message) {
+
+ if (statusBar_) {
+ statusBar_->showMessage(message, 3000);
+ }
+ }
+
+ QFileInfoList FQTermImageFlow::sortedList(const QString &path) {
+
+ QDir sortPath(path);
+
+ if (!sortPath.exists()) {
+ sortPath.mkdir(path);
+ }
+
+ QStringList filters;
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ it != formats.end();
+ ++it) {
+ QString filter("*.");
+ filter.append(it->data());
+ filters << filter;
+ }
+ sortPath.setNameFilters(filters);
+
+ return (sortPath.entryInfoList(QDir::Files | QDir::Readable | QDir::NoSymLinks, QDir::Time));
+ }
+
+ // FQTermImageFlow events.
+ void FQTermImageFlow::showEvent(QShowEvent *event) {
+
+ emit isTrashEmpty();
+
+ if (imageFlow_->count() <= 0) {
+ loadImages(STAT_UNKNOWN);
+ move((desktopSize().width() - width()) / 2.0, (desktopSize().height() - height()) / 2.0);
+ } else {
+ // TODO: insert new images
+ loadImages(STAT_ALL);
+ }
+ }
+
+ void FQTermImageFlow::closeEvent(QCloseEvent *event) {
+
+ hide();
+ }
+
+ class ImageMenu::Private {
+ public:
+ int emblemStatus;
+ bool dustbinStatus;
+ bool saveStatus;
+ bool clearStatus;
+
+ QString tipMessage;
+
+ QRect rectLike;
+ QRect rectTrash;
+ QRect rectNew;
+ QRect rectRecover;
+ QRect rectEmblems;
+
+ QRect rectClear;
+ QRect rectSave;
+ QRect rectDustbin;
+
+ QPixmap pixmapLike, pixmapLikeGray;
+ QPixmap pixmapTrash, pixmapTrashGray;
+ QPixmap pixmapNew, pixmapNewGray;
+ QPixmap pixmapRecover, pixmapRecoverGray;
+
+ QPixmap pixmapClear, pixmapClearGray;
+ QPixmap pixmapSave, pixmapSaveGray;
+ QPixmap pixmapDustbin, pixmapDustbinGray;
+ };
+
+ //ImageMenu
+ ImageMenu::ImageMenu(QWidget *parent)
+ : fh(new ImageMenu::Private) {
+
+ setAutoFillBackground(true);
+ setBackgroundRole(QPalette::Shadow);
+ setFocusPolicy(Qt::NoFocus);
+ setMouseTracking(true);
+ setFixedHeight(60);
+
+ fh->emblemStatus = -2;
+ fh->dustbinStatus = false;
+ fh->saveStatus = false;
+ fh->clearStatus = false;
+
+ fh->tipMessage = "";
+
+ fh->rectLike = QRect(50, 14, 32, 32);
+ fh->rectTrash = QRect(100, 14, 32, 32);
+ fh->rectNew = QRect(150, 14, 32, 32);
+ fh->rectRecover = QRect(200, 14, 32, 32);
+ fh->rectEmblems = QRect(50, 14, 232, 32);
+
+ fh->rectClear = QRect(300, 14, 32, 32);
+ fh->rectSave = QRect(350, 14, 32, 32);
+ fh->rectDustbin = QRect(400, 14, 32, 32);
+
+ fh->pixmapLike = QPixmap(iconPath("emblem-like.png"));
+ fh->pixmapLikeGray = QPixmap(iconPath("emblem-like-gray.png"));
+
+ fh->pixmapTrash = QPixmap(iconPath("emblem-trash.png"));
+ fh->pixmapTrashGray = QPixmap(iconPath("emblem-trash-gray.png"));
+
+ fh->pixmapNew = QPixmap(iconPath("emblem-new.png"));
+ fh->pixmapNewGray = QPixmap(iconPath("emblem-new-gray.png"));
+
+ fh->pixmapRecover = QPixmap(iconPath("emblem-recover.png"));
+ fh->pixmapRecoverGray = QPixmap(iconPath("emblem-recover-gray.png"));
+
+ fh->pixmapClear = QPixmap(iconPath("clear-state.png"));
+ fh->pixmapClearGray = QPixmap(iconPath("clear-state-gray.png"));
+
+ fh->pixmapSave = QPixmap(iconPath("save-state.png"));
+ fh->pixmapSaveGray = QPixmap(iconPath("save-state-gray.png"));
+
+ fh->pixmapDustbin = QPixmap(iconPath("trash-state.png"));
+ fh->pixmapDustbinGray = QPixmap(iconPath("trash-state-gray.png"));
+ }
+
+ ImageMenu::~ImageMenu() {
+
+ delete fh;
+ fh = NULL;
+ }
+
+ void ImageMenu::updateEmblems(const int status) {
+
+ if (fh->emblemStatus != status) {
+ update(fh->rectEmblems);
+ }
+
+ fh->emblemStatus = status;
+ }
+
+ void ImageMenu::updateClear(const bool hasOrNot) {
+
+ if (fh->clearStatus != hasOrNot) {
+ update(fh->rectClear);
+ }
+
+ fh->clearStatus = hasOrNot;
+ }
+
+ void ImageMenu::updateSave(const bool hasOrNot) {
+
+ if (fh->saveStatus != hasOrNot) {
+ update(fh->rectSave);
+ }
+
+ fh->saveStatus = hasOrNot;
+ }
+
+ void ImageMenu::updateDustbin(const bool fullOrNot) {
+
+ if (fh->dustbinStatus != fullOrNot) {
+ update(fh->rectDustbin);
+ }
+
+ fh->dustbinStatus = fullOrNot;
+ }
+
+ void ImageMenu::paintEvent(QPaintEvent *event) {
+
+ QPainter p(this);
+
+ p.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
+
+ if (fh->emblemStatus == STAT_LIKE) {
+ p.drawPixmap(fh->rectLike, fh->pixmapLike);
+ } else {
+ p.drawPixmap(fh->rectLike, fh->pixmapLikeGray);
+ }
+
+ if (fh->emblemStatus == STAT_TRASH) {
+ p.drawPixmap(fh->rectTrash, fh->pixmapTrash);
+ } else {
+ p.drawPixmap(fh->rectTrash, fh->pixmapTrashGray);
+ }
+
+ if (fh->emblemStatus == STAT_NEW) {
+ p.drawPixmap(fh->rectNew, fh->pixmapNew);
+ } else {
+ p.drawPixmap(fh->rectNew, fh->pixmapNewGray);
+ }
+
+ if (fh->emblemStatus == STAT_RECOVER) {
+ p.drawPixmap(fh->rectRecover, fh->pixmapRecover);
+ } else {
+ p.drawPixmap(fh->rectRecover, fh->pixmapRecoverGray);
+ }
+
+ if (fh->clearStatus == true) {
+ p.drawPixmap(fh->rectClear, fh->pixmapClear);
+ } else {
+ p.drawPixmap(fh->rectClear, fh->pixmapClearGray);
+ }
+
+ if (fh->saveStatus == true) {
+ p.drawPixmap(fh->rectSave, fh->pixmapSave);
+ } else {
+ p.drawPixmap(fh->rectSave, fh->pixmapSaveGray);
+ }
+
+ if (fh->dustbinStatus == true) {
+ p.drawPixmap(fh->rectDustbin, fh->pixmapDustbin);
+ } else {
+ p.drawPixmap(fh->rectDustbin, fh->pixmapDustbinGray);
+ }
+
+ p.end();
+ }
+
+ void ImageMenu::mouseReleaseEvent(QMouseEvent *event) {
+
+ if (event->button() == Qt::LeftButton
+ || event->button() == Qt::RightButton) {
+
+ if (fh->rectLike.contains(event->pos())) {
+ emit toggleFlowStatus(STAT_LIKE);
+ }
+
+ if (fh->rectTrash.contains(event->pos())) {
+ emit toggleFlowStatus(STAT_TRASH);
+ }
+
+ if (fh->rectClear.contains(event->pos())) {
+ emit clearImages();
+ }
+
+ if (fh->rectSave.contains(event->pos())) {
+ emit saveImages();
+ }
+
+ if (fh->rectDustbin.contains(event->pos())) {
+ emit recoverImages();
+ }
+ }
+ }
+
+ // ImageFlow: this subclasses PictureFlow
+ class ImageFlow::Private {
+ public:
+ int emblemStatus;
+ int likeCount;
+ int clearCount;
+
+ QList<QByteArray> itemsTitles;
+ QHash<QByteArray, qint64> itemsTitleKeyPairs;
+ QList<ImageFlowItem> items;
+ };
+
+ ImageFlow::~ImageFlow() {
+
+ delete m;
+ m = NULL;
+ }
+
+ // construct an emptry pictureflow.
+ ImageFlow::ImageFlow(QWidget *parent)
+ : PictureFlow(parent), m(new ImageFlow::Private) {
+
+ // initial setup
+ setFocusPolicy(Qt::StrongFocus);
+ setZoomFactor(120);
+ setSlideCount(0);
+ m->emblemStatus = -1;
+ m->likeCount = 0;
+ m->clearCount = 0;
+ }
+
+ const ImageFlowItem& ImageFlow::operator[](int index) const {
+
+ return (m->items[index]);
+ }
+
+ ImageFlowItem& ImageFlow::operator[](int index) {
+
+ return (m->items[index]);
+ }
+
+ const ImageFlowItem& ImageFlow::at(int index) const {
+
+ return (m->items[index]);
+ }
+
+ void ImageFlow::add(const ImageFlowItem &item) {
+
+ QByteArray title = item.info().fileName().toLocal8Bit();
+
+ m->items.append(item);
+ m->itemsTitles.append(title);
+ m->itemsTitleKeyPairs.insert(title, item.key());
+
+ // set the status pixmap
+ int index = m->items.indexOf(item);
+ m->items[index].setStatus(item.status());
+
+ int count = m->items.count();
+ setSlideCount(count);
+ setSlide(count - 1, item.image());
+ }
+
+ QList<QByteArray>& ImageFlow::itemsTitles() const {
+
+ return (m->itemsTitles);
+ }
+
+ void ImageFlow::clear() {
+
+ m->items.clear();
+ setSlideCount(0);
+ setCurrentSlide(0);
+ PictureFlow::clear();
+ }
+
+ int ImageFlow::count() const {
+
+ return (m->items.count());
+ }
+
+ int ImageFlow::size() const {
+
+ return (m->items.size());
+ }
+
+ QFileInfoList& ImageFlow::digest(const int status) {
+
+ int i;
+ int count = m->items.size();
+ static QFileInfoList result;
+
+ result.clear();
+
+ for (i = 0; i < count; i++) {
+ switch (status) {
+ case STAT_ALL:
+ result.append(m->items[i].info());
+ break;
+ default:
+ if (m->items[i].status() == status) {
+ result.append(m->items[i].info());
+ }
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ void ImageFlow::strip(const int status) {
+
+ int i;
+ int count = m->items.count();
+ QList<int> dirtyIndexes;
+
+ // We cannot delete items in a loop because
+ // items count will change while deleting.
+ // A better method is to use another list
+ // to record 'dirty' items, and by looping this
+ // dirty list, we can correctly delete those
+ // dirty items successfully.
+ for (i = 0; i < count; i++) {
+ if (m->items[i].status() == status) {
+ dirtyIndexes.append(i);
+ }
+ }
+
+ if (!dirtyIndexes.isEmpty()) {
+
+ for (i = 0; i < dirtyIndexes.count(); i++) {
+ // Note: dirtyIndexes[i] - i: the actual
+ // position of the dirty item.
+ m->items.removeAt(dirtyIndexes[i] - i);
+ }
+
+ dirtyIndexes.clear();
+ reorder(sort(STAT_ALL));
+
+ for (i = 0; i < m->items.count(); i++) {
+ setSlide(i, m->items[i].image());
+ }
+
+ setSlideCount(i);
+ setCurrentSlide(0);
+
+ switch(status) {
+ case STAT_LIKE:
+ m->likeCount = 0;
+ emit saveStatus(false);
+ emit emblemStatus(STAT_UNKNOWN);
+ break;
+ case STAT_TRASH:
+ m->clearCount = 0;
+ emit clearStatus(false);
+ emit emblemStatus(STAT_UNKNOWN);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ QList<qint64> ImageFlow::sort(const int status) {
+
+ int i;
+ int count = m->items.count();
+ QList<qint64> itemKeys;
+
+ switch (status) {
+ case STAT_TITLE:
+ qStableSort(m->itemsTitles.begin(), m->itemsTitles.end(), qLess<QByteArray>());
+ for (i = 0; i < m->itemsTitles.count(); i++) {
+ itemKeys.append(m->itemsTitleKeyPairs.value(m->itemsTitles[i]));
+ }
+ break;
+ default:
+ for (i = 0; i < count; i++) {
+ if (m->items[i].status() == status) {
+ itemKeys.prepend(m->items[i].key());
+ } else {
+ itemKeys.append(m->items[i].key());
+ }
+ }
+ break;
+ }
+
+ // this might be unnecessary here.
+ return itemKeys;
+ }
+
+ bool ImageFlow::reorder(const QList<qint64>& itemsKey) {
+
+ int items_count = m->items.size();
+
+ if (itemsKey.size() != items_count) {
+
+ return (false);
+ }
+
+ // Collect Items Key
+ QList<qint64> currentItemsKey;
+ for (int i = 0; i < items_count; i++) {
+
+ currentItemsKey.append(m->items.at(i).key());
+ }
+
+ if (currentItemsKey == itemsKey) {
+ // if identical, we don't sort.
+ return (false);
+ }
+
+ // Swap Items
+ for (int i=0; i < items_count; i++) {
+
+ int index = currentItemsKey.indexOf(itemsKey.at(i));
+ if (i == index) {
+ continue;
+ }
+
+ QImage imgA = m->items[i].image();
+ QImage imgB = m->items[index].image();
+
+ setSlide(index, imgA);
+ setSlide(i, imgB);
+
+ m->items.swap(i, index);
+ currentItemsKey.swap(i, index);
+ }
+
+ update();
+ rehash();
+ return(true);
+ }
+
+ void ImageFlow::rehash(void) {
+
+ int count = m->items.count();
+
+ if (count <= 0) {
+ return;
+ }
+
+ int i;
+
+ m->itemsTitles.clear();
+ m->itemsTitleKeyPairs.clear();
+
+ qint64 k;
+ QByteArray b;
+
+ for (i = 0; i < count; i++) {
+ k = m->items[i].key();
+ b = m->items[i].info().fileName().toLocal8Bit();
+ m->itemsTitles.append(b);
+ m->itemsTitleKeyPairs.insert(b, k);
+ }
+ }
+
+ void ImageFlow::toggleStatus(const int status) {
+
+ int index = currentSlide();
+ int count = m->items.count();
+
+ if (index >= 0 && index < count) {
+
+ setUpdatesEnabled(false);
+ if (m->items[index].status() != status) {
+
+ switch (status) {
+ case STAT_LIKE:
+ m->likeCount++;
+ if (m->items[index].status() == STAT_TRASH) {
+ m->clearCount--;
+ }
+ emit saveStatus(true);
+ break;
+ case STAT_TRASH:
+ m->clearCount++;
+ if (m->items[index].status() == STAT_LIKE) {
+ m->likeCount--;
+ }
+ emit clearStatus(true);
+ break;
+ default:
+ break;
+ }
+
+ m->items[index].setStatus(status);
+ emit statusMessage(tr("Tagged as ") + tr(fqloraTagStatus[status]));
+
+ } else {
+
+ switch (status) {
+ case STAT_LIKE:
+ m->likeCount--;
+ break;
+ case STAT_TRASH:
+ m->clearCount--;
+ break;
+ default:
+ break;
+ }
+
+ m->items[index].setStatus(STAT_UNKNOWN);
+ emit statusMessage("Tag cleared");
+ }
+
+ if (m->likeCount <= 0) {
+ emit saveStatus(false);
+ } else {
+ emit saveStatus(true);
+ }
+
+ if (m->clearCount <= 0) {
+ emit clearStatus(false);
+ } else {
+ emit clearStatus(true);
+ }
+
+ setUpdatesEnabled(true);
+ }
+ }
+
+ void ImageFlow::setCurrentImage(const int index) {
+
+ int count = size();
+
+ if (count > 0 && index > 0 && index < count) {
+
+ setCurrentSlide(index);
+ }
+ }
+
+// events
+ void ImageFlow::paintEvent(QPaintEvent *event) {
+
+ PictureFlow::paintEvent(event);
+
+ if (slideCount() < 1) {
+ return;
+ }
+
+ QPainter p(this);
+
+ // White Pen for File Info
+ p.setPen(Qt::gray);
+
+ int cw = width() / 2;
+ int wh = height();
+
+ ImageFlowItem& item = m->items[currentSlide()];
+
+ // Draw File Name if it's not empty
+ QString title = item.info().fileName();
+ if (!title.isEmpty()) {
+
+ p.setFont(QFont(p.font().family(), p.font().pointSize() + 1, QFont::Bold));
+ p.drawText(cw - (QFontMetrics(p.font()).width(title) / 2), wh - 20, title);
+ }
+
+ p.end();
+
+ if (m->emblemStatus != item.status()) {
+ emit emblemStatus(item.status());
+ }
+
+ m->emblemStatus = item.status();
+ }
+
+ // ImageFlowItem
+ class ImageFlowItem::Private {
+ public:
+ QString filePath;
+ QFileInfo info;
+ QString comment;
+ QImage image;
+ int status;
+ qint64 key;
+
+ };
+
+ ImageFlowItem::~ImageFlowItem() {
+
+ delete m;
+ m = NULL;
+ }
+
+ // constructs an empty item
+ ImageFlowItem::ImageFlowItem(QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ ImageFlowItem::ImageFlowItem(const ImageFlowItem &item)
+ : QObject(item.parent()), m(new ImageFlowItem::Private) {
+
+ operator=(item);
+ }
+
+ // constructs an item with a given image
+ ImageFlowItem::ImageFlowItem(const QImage &image, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // constructs an image with given image and title
+ ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->info = info;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // constructs an image with given image, title and comment
+ ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString &comment, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->info = info;
+ m->comment = comment;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // constructs an image with given image, title, type, size, time and state
+ ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString& comment, const int status, QObject *parent)
+ : QObject(parent), m(new ImageFlowItem::Private) {
+
+ m->image = image;
+ m->info = info;
+ m->comment = comment;
+ m->status = status;
+
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ // funcs and slots
+ ImageFlowItem& ImageFlowItem::operator=(const ImageFlowItem &item) {
+
+ m->info = item.m->info;
+ m->comment = item.m->comment;
+ m->key = item.m->key;
+
+ if (item.m->filePath.isEmpty()) {
+ m->image = item.m->image;
+ } else {
+ setImage(item.m->filePath, m->key);
+ }
+
+ return (*this);
+ }
+
+ bool ImageFlowItem::operator==(const ImageFlowItem& item) const {
+
+ return (item.m->key == m->key);
+ }
+
+ bool ImageFlowItem::operator!=(const ImageFlowItem& item) const {
+
+ return (item.m->key != m->key);
+ }
+
+ const QString& ImageFlowItem::comment() const {
+
+ return (m->comment);
+ }
+
+ const QImage& ImageFlowItem::image() const {
+
+ return (m->image);
+ }
+
+ int ImageFlowItem::status(void) const {
+
+ return (m->status);
+ }
+
+ const QFileInfo& ImageFlowItem::info(void) const {
+
+ return (m->info);
+ }
+
+ qint64 ImageFlowItem::key() const {
+
+ return (m->key);
+ }
+
+ void ImageFlowItem::setInfo(const QFileInfo& info) {
+
+ m->info = info;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ void ImageFlowItem::setComment(const QString &comment) {
+
+ m->comment = comment;
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ void ImageFlowItem::setImage(const QImage &image) {
+
+ m->image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ void ImageFlowItem::setImage(const QString &filePath, int size) {
+
+ m->filePath = filePath;
+ m->key = size;
+
+ QTimer::singleShot(1000, this, SLOT(loadImage()));
+ }
+
+ void ImageFlowItem::setStatus(const int status) {
+
+ m->status = status;
+ }
+
+ void ImageFlowItem::loadImage() {
+
+ int imageHeight = m->key;
+
+ if (!m->image.load(m->filePath)) {
+ QFileIconProvider iconProvider;
+ m->image = iconProvider.icon(QFileInfo(m->filePath)).pixmap(imageHeight).toImage();
+ } else {
+ m->image = resizeImage(m->image, imageHeight);
+ }
+
+ m->filePath.clear();
+ m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
+ }
+
+ QImage ImageFlowItem::resizeImage(const QImage &image, int size) {
+
+ if (size == image.width() && size == image.height()) {
+ return image;
+ }
+
+ double scaleWidth = size / (double)image.width();
+ double scaleHeight = size / (double)image.height();
+ double smaller = qMin(scaleWidth, scaleHeight);
+
+ int w = (int) qRound(smaller * image.width());
+ int h = (int) qRound(smaller * image.height());
+
+ return (image.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+
+ // original viewer
+ void FQTermImageOrigin::onChange(const QModelIndex & index) {
+
+ if (!model_->isDir(index)) {
+
+ if (!isHidden())
+ canvas_->hide();
+
+ QString exifInfo = QString::fromStdString(exifExtractor_->extractExifInfo(model_->filePath(tree_->currentIndex()).toLocal8Bit().data()));
+ bool resized = false;
+
+ if (exifInfo != "") {
+
+ if (!isExifTableShown_) {
+ adjustLayout(true);
+ isExifTableShown_ = true;
+ resized = true;
+ }
+
+ updateExifInfo();
+ } else {
+
+ if (isExifTableShown_) {
+ adjustLayout(false);
+ isExifTableShown_ = false;
+ resized = true;
+ }
+ }
+
+ QString path = QDir::toNativeSeparators(model_->filePath(index));
+
+ if (path.endsWith(QDir::separator()))
+ path.chop(1);
+
+ canvas_->loadImage(path, !resized);
+
+ // canvas_->autoAdjust();
+ if (!isHidden())
+ canvas_->show();
+ }
+ }
+
+ FQTermImageOrigin::~FQTermImageOrigin() {
+ delete menuBar_;
+ delete canvas_;
+ delete tree_;
+ delete model_;
+ }
+
+ FQTermImageOrigin::FQTermImageOrigin(FQTermConfig * config, QWidget *parent,
+ Qt::WindowFlags wflag) :
+ FQTermImage(parent, wflag),
+ config_(config),
+ isExifTableShown_(false) {
+
+ setWindowTitle(tr("FQTerm Image Viewer"));
+ ItemDelegate* itemDelegate = new ItemDelegate;
+ exifExtractor_ = new ExifExtractor;
+ exifTable_ = new ExifTable(this);
+ exifTable_->setTextFormat(Qt::RichText);
+ exifTable_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ canvas_ = new FQTermCanvas(config, this, 0);
+ canvas_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ model_ = new ImageViewerDirModel;
+ tree_ = new QTreeView;
+
+
+ tree_->setModel(model_);
+ tree_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ adjustItemSize();
+ tree_->setItemDelegate(itemDelegate);
+ tree_->setColumnWidth(0, 150);
+ tree_->setColumnWidth(1, 0);
+
+ tree_->hideColumn(0);
+
+ tree_->setUniformRowHeights(true);
+ tree_->setWordWrap(true);
+ //tree_->header()->setResizeMode(0, QHeaderView::Fixed);
+ //tree_->header()->setResizeMode(1, QHeaderView::ResizeToContents);
+ //tree_->header()->resizeSection(0, 150);
+ //tree_->header()->resizeSection(1, 1);
+ comboBox_ = new QComboBox(this);
+ comboBox_->addItem(tr("Sort by name"), QDir::Name);
+ comboBox_->addItem(tr("Sort by time"), QDir::Time);
+ comboBox_->addItem(tr("Sort by size"), QDir::Size);
+ comboBox_->addItem(tr("Sort by type"), QDir::Type);
+
+ FQ_VERIFY(connect(comboBox_, SIGNAL(currentIndexChanged(int)), this, SLOT(sortFileList(int))));
+
+ comboBox_->setCurrentIndex(1);
+
+ layout_ = new QGridLayout;
+ menuBar_ = new QMenuBar(this);
+ menuBar_->addMenu(canvas_->menu());
+ menuBar_->resize(1,1);
+
+ canvas_->ToolBar()->addAction(
+ QIcon(getPath(RESOURCE) + ICON_SOURCE + "prev.png"), tr("Previous"),
+ this, SLOT(previous()));
+ canvas_->ToolBar()->addAction(
+ QIcon(getPath(RESOURCE) + ICON_SOURCE + "next.png"), tr("Next"),
+ this, SLOT(next()));
+
+ layout_->addWidget(tree_, 0, 0, 12, 1);
+ layout_->addWidget(comboBox_, 12, 0, 1, 1);
+ layout_->addWidget(canvas_, 0, 1, 12, 10);
+ // layout_->addWidget(exifTable_, 10, 1, 2, 10);
+ layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter);
+ layout_->setColumnMinimumWidth(0, tree_->columnWidth(0) + 150);
+ setLayout(layout_);
+
+ /*
+ FQ_VERIFY(connect(tree_, SIGNAL(clicked(const QModelIndex &)),
+ this, SLOT(onChange(const QModelIndex &))));
+ */
+ FQ_VERIFY(connect(tree_, SIGNAL(activated(const QModelIndex &)),
+ this, SLOT(onChange(const QModelIndex &))));
+ FQ_VERIFY(connect(tree_->selectionModel(),
+ SIGNAL(selectionChanged(const QItemSelection&,
+ const QItemSelection&)),
+ this, SLOT(selectionChanged(const QItemSelection&,
+ const QItemSelection&))));
+ FQ_VERIFY(connect(exifTable_, SIGNAL(showExifDetails()),
+ this, SLOT(showFullExifInfo())));
+ }
+
+ void FQTermImageOrigin::scrollTo(const QString& filename) {
+
+ QString path = QFileInfo(filename).absolutePath();
+ model_->refresh();
+ tree_->setRootIndex(model_->index(path));
+ canvas_->loadImage(filename);
+
+ if (canvas_->isHidden() && !isHidden()) {
+ canvas_->show();
+ }
+
+ const QModelIndex& index = model_->index(filename);
+ tree_->scrollTo(index);
+ tree_->setCurrentIndex(index);
+ }
+
+ void FQTermImageOrigin::updateImage(const QString& filename) {
+
+ static int i = 0;
+ if (++i == 10) {
+ model_->refresh(model_->index(filename));
+ i = 0;
+ }
+ canvas_->updateImage(filename);
+ }
+
+ void FQTermImageOrigin::previous() {
+
+ const QModelIndex& index = tree_->indexAbove(tree_->currentIndex());
+ if (index.isValid()) {
+ tree_->setCurrentIndex(index);
+ canvas_->loadImage(QDir::toNativeSeparators(model_->filePath(index)));
+ }
+ }
+
+ void FQTermImageOrigin::next() {
+
+ const QModelIndex& index = tree_->indexBelow(tree_->currentIndex());
+ if (index.isValid()) {
+ tree_->setCurrentIndex(index);
+ canvas_->loadImage(QDir::toNativeSeparators(model_->filePath(index)));
+ }
+ }
+
+ void FQTermImageOrigin::adjustItemSize() {
+
+ QFontMetrics fm(font());
+ ItemDelegate::size_.setWidth(qMax(128, fm.width("WWWWWWWW.WWW")));
+ ItemDelegate::size_.setHeight(fm.height() + 150);
+ }
+
+ void FQTermImageOrigin::selectionChanged(const QItemSelection & selected,
+ const QItemSelection & deselected) {
+
+ onChange(tree_->selectionModel()->currentIndex());
+ }
+
+ void FQTermImageOrigin::sortFileList(int index) {
+
+ model_->setSorting(QDir::SortFlag(comboBox_->itemData(index).toInt()));
+ QString poolPath = config_->getItemValue("preference", "pool");
+
+ if (poolPath.isEmpty()) {
+ poolPath = getPath(USER_CONFIG) + "pool/";
+ }
+
+ tree_->setRootIndex(model_->index(poolPath));
+ }
+
+ void FQTermImageOrigin::showFullExifInfo() {
+
+ QString exifInfo = QString::fromStdString(exifExtractor_->extractExifInfo(model_->filePath(tree_->currentIndex()).toLocal8Bit().data()));
+ QString comment;
+
+ if ((*exifExtractor_)["UserComment"].length() > 8) {
+
+ QString commentEncoding = QString::fromStdString((*exifExtractor_)["UserComment"].substr(0, 8));
+
+ if (commentEncoding.startsWith("UNICODE")) {
+ //UTF-16
+ QTextCodec* c = QTextCodec::codecForName("UTF-16");
+ comment = c->toUnicode((*exifExtractor_)["UserComment"].substr(8).c_str());
+ } else if (commentEncoding.startsWith("JIS")) {
+ //JIS X 0208
+ QTextCodec* c = QTextCodec::codecForName("JIS X 0208");
+ comment = c->toUnicode((*exifExtractor_)["UserComment"].substr(8).c_str());
+ } else {
+ comment = QString::fromStdString((*exifExtractor_)["UserComment"].substr(8));
+ }
+ }
+
+
+ QTextEdit* info = new QTextEdit;
+ info->setText(exifInfo + tr("Comment : ") + comment + "\n");
+ info->setWindowFlags(Qt::Dialog);
+ info->setAttribute(Qt::WA_DeleteOnClose);
+ info->setAttribute(Qt::WA_ShowModal);
+ // info->setLineWrapMode(QTextEdit::NoWrap);
+ info->setReadOnly(true);
+ QFontMetrics fm(font());
+ info->resize(fm.width("Orientation : 1st row - 1st col : top - left side "), fm.height() * 20);
+ info->show();
+ }
+
+ void FQTermImageOrigin::adjustLayout(bool withExifTable) {
+
+ if (withExifTable) {
+
+ layout_->addWidget(canvas_, 0, 1, 11, 10);
+ layout_->addWidget(exifTable_, 11, 1, 1, 10, Qt::AlignHCenter);
+ if (!isHidden() && exifTable_->isHidden()) {
+ exifTable_->show();
+ }
+
+ layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter);
+ } else {
+ layout_->addWidget(canvas_, 0, 1, 12, 10);
+ layout_->removeWidget(exifTable_);
+ exifTable_->hide();
+ layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter);
+ }
+ }
+
+ void FQTermImageOrigin::updateExifInfo() {
+
+ exifTable_->clear();
+
+ QString exifInfoToShow = "<table border=\"1\"><tr><td>"
+ + tr("Model") + " : " + QString::fromStdString((*exifExtractor_)["Model"]) + "</td><td>"
+ + QString::fromStdString((*exifExtractor_)["DateTime"]) + "</td><td>"
+ + QString::fromStdString((*exifExtractor_)["Flash"]) + "</td>"
+ + "</tr><tr><td>"
+ + tr("ExposureTime") + " : " + QString::fromStdString((*exifExtractor_)["ExposureTime"]) + "</td><td>"
+ + tr("FNumber") + " : " + QString::fromStdString((*exifExtractor_)["FNumber"]) + "</td><td>"
+ + tr("ISO") + " : " + QString::fromStdString((*exifExtractor_)["ISOSpeedRatings"]) + "</td>"
+ + "</tr><tr><td>"
+ + tr("FocalLength") + " : " + QString::fromStdString((*exifExtractor_)["FocalLength"]) + "</td><td>"
+ + tr("MeteringMode") + " : " + QString::fromStdString((*exifExtractor_)["MeteringMode"]) + "</td><td>"
+ + tr("ExposureBias") + " : " + QString::fromStdString((*exifExtractor_)["ExposureBiasValue"]) + "</td></tr></tabel>";
+
+ exifTable_->setText(exifInfoToShow);
+ if (!isHidden() && exifTable_->isHidden()) {
+ exifTable_->show();
+ }
+ }
+
+ void FQTermImageOrigin::closeEvent( QCloseEvent *clse ) {
+
+ hide();
+ clse->ignore();
+ return ;
+ }
+
+ ImageViewerDirModel::ImageViewerDirModel(QObject *parent /*= 0*/)
+ : QDirModel(parent) {
+
+ //insertColumn(1);
+ QStringList nameFilterList;
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ it != formats.end();
+ ++it) {
+ QString filter("*.");
+ filter.append(it->data());
+ nameFilterList << filter;
+ }
+ setNameFilters(nameFilterList);
+ setFilter(QDir::Files);
+ }
+
+ int ImageViewerDirModel::columnCount(const QModelIndex &/*parent*/) const {
+
+ return 2;
+ }
+
+ QVariant ImageViewerDirModel::headerData(
+ int section, Qt::Orientation orientation, int role) const {
+ //if (section == 0) return QVariant();
+ if (role == Qt::DisplayRole) {
+ // if (section == 1) {
+ return QString(tr("Image Preview"));
+ //}
+ }
+ return QDirModel::headerData(section, orientation, role);
+ }
+
+ QVariant ImageViewerDirModel::data(const QModelIndex &index, int role) const {
+ //if (index.column() == 0) return QVariant();
+ if (role == Qt::DecorationRole) {
+ if (isDir(index)) {
+ return QVariant();
+ }
+
+ QString path = QDir::toNativeSeparators(filePath(index));
+ if (path.endsWith(QDir::separator()))
+ path.chop(1);
+
+ QPixmap pixmap;
+ bool res = pixmap.load(path);
+ if (!res) {
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ !res && it != formats.end();
+ ++it) {
+ res = pixmap.load(path, it->data());
+ }
+ }
+
+ if (pixmap.height() > 128 || pixmap.width() > 128) {
+ return pixmap.scaled(128, 128,
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+
+ return pixmap;
+ } else if (role == Qt::DisplayRole) {
+ return fileName(index);
+ }/*
+ else if (role == Qt::TextAlignmentRole) {
+ return Qt::Qt::AlignBottom;
+ }*/
+ return QVariant();
+ }
+
+ QSize ItemDelegate::size_;
+
+ void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & option,
+ const QModelIndex & index ) const {
+ //if (index.column() == 0) return;
+ QStyleOptionViewItemV3 opt = setOptions(index, option);
+
+ // prepare
+ painter->save();
+
+ // get the data and the rectangles
+ const QPixmap& pixmap
+ = qvariant_cast<QPixmap>(index.data(Qt::DecorationRole));
+ QRect decorationRect = QRect(opt.rect.topLeft(), pixmap.size());
+ decorationRect.moveTo(decorationRect.left(), decorationRect.top() + 10);
+ const QString& text = index.data(Qt::DisplayRole).toString();
+ QFontMetrics fm(painter->font());
+ QRect displayRect = QRect(decorationRect.bottomLeft(),
+ QSize(fm.width(text),fm.height()));
+
+ QRect checkRect;
+ Qt::CheckState checkState = Qt::Unchecked;
+ QVariant value = index.data(Qt::CheckStateRole);
+
+ if (value.isValid()) {
+ checkState = static_cast<Qt::CheckState>(value.toInt());
+ checkRect = check(opt, opt.rect, value);
+ }
+
+ // do the layout
+
+ // doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
+
+ // draw the item
+
+ drawBackground(painter, opt, index);
+ painter->drawPixmap(decorationRect, pixmap);
+ painter->drawText(displayRect, text);
+
+ drawFocus(painter, opt, displayRect);
+
+ // done
+ painter->restore();
+ }
+
+ void ExifTable::mouseReleaseEvent(QMouseEvent *pEvent) {
+
+ if (pEvent->button() == Qt::LeftButton) {
+ emit(showExifDetails());
+ }
+ }
+
+ ExifTable::ExifTable(QWidget *parent) : QLabel(parent) {
+
+ }
+
+ FQTermImage::FQTermImage( QWidget * parent, Qt::WindowFlags f ) : QWidget(parent, f) {
+ }
+
+} // namespace FQTerm
+
+#include "imageviewer.moc"
diff --git a/src/ui/imageviewer.h b/src/ui/imageviewer.h
new file mode 100644
index 0000000..ba98559
--- /dev/null
+++ b/src/ui/imageviewer.h
@@ -0,0 +1,336 @@
+
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef IMAGE_VIERWER_H
+#define IMAGE_VIERWER_H
+
+#include <QDesktopWidget>
+#include <QDirModel>
+#include <QLabel>
+#include <QPainter>
+#include <QPixmapCache>
+#include <QScrollArea>
+#include <QStatusBar>
+#include <QToolButton>
+#include <QToolBar>
+#include <QLayout>
+#include <QItemDelegate>
+#include <QItemSelection>
+
+class QString;
+class QPushButton;
+class QVBoxLayout;
+class QHBoxLayout;
+class QMenuBar;
+class QTreeView;
+class QComboBox;
+
+#include "pictureflow.h"
+
+namespace FQTerm {
+
+#define DISP_MARGIN (10.0) // show a margin
+#define PIXMAP_CACHESIZE (5120) // in KBytes
+#define ZOOMIN_FACTOR (1.15)
+#define ZOOMOUT_FACTOR (0.85)
+#define ROTLEFT_DEG (-90.0)
+#define ROTRIGHT_DEG (90.0)
+#define IMG_CHUNK (16384) // in bytes
+
+#define IMAGE_BROWSER_NAME "FQLora [Image Companion for FQTerm]"
+#define ICON_SOURCE "pic/ViewerButtons/"
+#define POOL_SOURCE "pool/"
+#define SHADOW_SOURCE "shadow-cache/"
+#define TRASH_SOURCE ".Trash/"
+
+#define EMBLEM_LIKE "emblem-like.png"
+#define EMBLEM_NEW "emblem-new.png"
+#define EMBLEM_RECOVER "emblem-recover.png"
+#define EMBLEM_TRASH "emblem-trash.png"
+#define EMBLEM_TITLE "emblem-title.png"
+
+ class FQTermConfig;
+ class FQTermFileDialog;
+
+
+ class FQTermImage : public QWidget {
+ Q_OBJECT;
+ public:
+ FQTermImage(QWidget * parent, Qt::WindowFlags f);
+ virtual void adjustItemSize() = 0;
+ virtual void scrollTo(const QString &) = 0;
+ virtual void updateImage(const QString &) = 0;
+ };
+
+ class ImageFlow;
+ class ImageMenu;
+ class ImageFlowItem;
+
+ class FQTermImageFlow: public FQTermImage {
+ Q_OBJECT;
+
+ public:
+ FQTermImageFlow(FQTermConfig *, QWidget *, Qt::WindowFlags);
+ ~FQTermImageFlow();
+
+ /* don't modify the funcs below */
+ /* they are for API compatibiliy */
+ void adjustItemSize();
+ void scrollTo(const QString &);
+ void updateImage(const QString &);
+ /*********************************/
+
+ public slots:
+ void saveImages(void);
+ void clearImages(void);
+ void trashAllImages(void);
+ void recoverImages(void);
+ void showStatusMessage(const QString &message);
+
+ private:
+ ImageFlow *imageFlow_;
+ ImageMenu *imageMenu_;
+ QStatusBar *statusBar_;
+ FQTermConfig *config_;
+
+ QFileInfoList sortedList(const QString &path);
+ const QString& poolSource(void) const;
+ const QString& trashSource(void) const;
+
+ private slots:
+ void loadImages(const int status);
+ void reshuffleImages(const int status);
+ void checkTrashState(void);
+
+ signals:
+ void statusMessage(const QString &message);
+ void isTrashEmpty(void);
+ void trashStatus(const bool fullOrNot);
+ void saveStatus(const bool hasOrNot);
+ void clearStatus(const bool hasOrNot);
+
+ protected:
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+ };
+
+ class ImageMenu: public QLabel {
+ Q_OBJECT;
+
+ public:
+ ImageMenu(QWidget *parent = 0);
+ ~ImageMenu();
+
+ public slots:
+ void updateEmblems(const int status);
+ void updateDustbin(const bool fullOrNot);
+ void updateSave(const bool hasOrNot);
+ void updateClear(const bool hasOrNot);
+
+ signals:
+ void toggleFlowStatus(const int status);
+ void recoverImages(void);
+ void saveImages(void);
+ void clearImages(void);
+
+ private:
+ class Private;
+ Private *fh;
+
+ protected:
+ void paintEvent(QPaintEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ };
+
+ class ImageFlow: public PictureFlow {
+ Q_OBJECT;
+ Q_PROPERTY(QList<QByteArray> itemsTitles READ itemsTitles);
+
+ public:
+ ImageFlow(QWidget *parent);
+ ~ImageFlow();
+
+ const ImageFlowItem& operator[](int index) const;
+ ImageFlowItem& operator[](int index);
+ const ImageFlowItem& at(int index) const;
+
+ QList<QByteArray>& itemsTitles(void) const;
+
+ QFileInfoList& digest(const int status);
+ void strip(const int status);
+ QList<qint64> sort(const int status);
+ bool reorder(const QList<qint64>& itemsKey);
+
+ public slots:
+ void add(const ImageFlowItem &item);
+ void clear(void);
+ int count(void) const;
+ int size(void) const;
+ void rehash(void);
+ void toggleStatus(const int status);
+ void setCurrentImage(const int index);
+
+ private:
+ class Private;
+ Private *m;
+
+ signals:
+ void statusMessage(const QString &message);
+ void emblemStatus(const int status);
+ void saveStatus(const bool hasOrNot);
+ void clearStatus(const bool hasOrNot);
+ void titlesChanged(QList<QByteArray> &titles);
+
+ protected:
+ void paintEvent(QPaintEvent *event);
+ };
+
+ class ImageFlowItem: public QObject {
+ Q_OBJECT;
+
+ Q_PROPERTY(qint64 key READ key);
+ Q_PROPERTY(int status READ status WRITE setStatus);
+ Q_PROPERTY(QImage image READ image WRITE setImage);
+ Q_PROPERTY(QFileInfo info READ info WRITE setInfo);
+ Q_PROPERTY(QString comment READ comment WRITE setComment);
+
+ public:
+ ImageFlowItem(QObject *parent = 0);
+ ImageFlowItem(const ImageFlowItem &item);
+ ImageFlowItem(const QImage &image, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, const int state, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, const QString &comment, QObject *parent = 0);
+ ImageFlowItem(const QImage &image, const QFileInfo &info, const QString& comment, const int status, QObject *parent = 0);
+ ~ImageFlowItem();
+
+ const QFileInfo& info(void) const;
+ const QString& comment(void) const;
+ const QImage& image(void) const;
+ int status(void) const;
+ qint64 key(void) const;
+
+ ImageFlowItem& operator=(const ImageFlowItem &item);
+ bool operator==(const ImageFlowItem &item) const;
+ bool operator!=(const ImageFlowItem &item) const;
+
+ public slots:
+ void setStatus(const int status);
+ void setInfo(const QFileInfo &info);
+ void setComment(const QString &comment);
+ void setImage(const QImage &image);
+ void setImage(const QString &filePath, int size);
+
+ private slots:
+ void loadImage(void);
+
+ private:
+ QImage resizeImage(const QImage &image, int size);
+ class Private;
+ Private *m;
+
+ };
+
+///////////////////////////////////////////////////////
+//////// the origin image viewer //////////////////////
+///////////////////////////////////////////////////////
+
+ class FQTermCanvas;
+ class ExifExtractor;
+
+ class ItemDelegate : public QItemDelegate {
+ public:
+ ItemDelegate() {
+ size_ = QSize(250,200);
+ }
+
+ QSize sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const {
+ //if (index.column() == 0) return QSize(1, 1);
+ return size_;
+ }
+
+ void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
+ static QSize size_;
+ };
+
+ class ExifTable : public QLabel {
+ Q_OBJECT;
+
+ public:
+ ExifTable(QWidget *parent);
+
+ signals:
+ void showExifDetails();
+
+ protected:
+ void mouseReleaseEvent(QMouseEvent *pEvent);
+ };
+
+ class ImageViewerDirModel : public QDirModel {
+ public:
+ ImageViewerDirModel(QObject *parent = 0);
+
+ int columnCount(const QModelIndex & = QModelIndex()) const;
+ QVariant headerData ( int section, Qt::Orientation orientation, int role) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ };
+
+
+ class FQTermImageOrigin: public FQTermImage {
+ Q_OBJECT;
+
+ public:
+ FQTermImageOrigin(FQTermConfig * config, QWidget *parent, Qt::WindowFlags wflag);
+ ~FQTermImageOrigin();
+ void scrollTo(const QString& filename);
+ void updateImage(const QString& filename);
+
+ public slots:
+ void onChange(const QModelIndex & index);
+ void next();
+ void previous();
+ void adjustItemSize();
+ void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
+ void sortFileList(int index);
+ void showFullExifInfo();
+ void adjustLayout(bool withExifTable);
+ void updateExifInfo();
+
+ protected:
+ void closeEvent(QCloseEvent *clse);
+
+ private:
+ FQTermCanvas* canvas_;
+ QTreeView* tree_;
+ ImageViewerDirModel* model_;
+ QMenuBar* menuBar_;
+ QComboBox* comboBox_;
+ FQTermConfig* config_;
+ ExifExtractor* exifExtractor_;
+ ExifTable* exifTable_;
+ QGridLayout* layout_;
+ bool isExifTableShown_;
+ };
+
+
+} // namespace FQTerm
+
+#endif // IMAGE_VIERWER_H
diff --git a/src/ui/iplookup.cpp b/src/ui/iplookup.cpp
new file mode 100644
index 0000000..e84c126
--- /dev/null
+++ b/src/ui/iplookup.cpp
@@ -0,0 +1,56 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "iplookup.h"
+#include "fqterm_ip_location.h"
+#include "fqterm.h"
+namespace FQTerm {
+
+
+
+IPLookupDialog::~IPLookupDialog(){
+
+}
+
+IPLookupDialog::IPLookupDialog( QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/ ) : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+ FQ_VERIFY(connect(ui_.lookupPushButton, SIGNAL(clicked()), this, SLOT(onLookup())));
+ FQ_VERIFY(connect(ui_.finishedPushButton, SIGNAL(clicked()), this, SLOT(onFinished())));
+}
+
+void IPLookupDialog::onLookup() {
+ QString country, city;
+ QString ip = ui_.ipLineEdit->text();
+ FQTermIPLocation *ipLocation = FQTermIPLocation::getInstance();
+ if (ipLocation == NULL) {
+ ui_.addressLineEdit->setText(QApplication::translate("IPLookupDialog", "IP database file does NOT exist", 0, QApplication::UnicodeUTF8));
+ } else if (!ipLocation->getLocation(ip, country, city)) {
+ ui_.addressLineEdit->setText(QApplication::translate("IPLookupDialog", "Invalid IP", 0, QApplication::UnicodeUTF8));
+ } else {
+ ui_.addressLineEdit->setText(country + " " + city);
+ }
+}
+
+void IPLookupDialog::onFinished() {
+ done(0);
+}
+} //namespace FQTerm
+
+#include "iplookup.moc" \ No newline at end of file
diff --git a/src/ui/iplookup.h b/src/ui/iplookup.h
new file mode 100644
index 0000000..4f38a5a
--- /dev/null
+++ b/src/ui/iplookup.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef __FQTERM_IPLOOKUP__
+#define __FQTERM_IPLOOKUP__
+
+#include <QDialog>
+#include "ui_iplookup.h"
+namespace FQTerm {
+
+class IPLookupDialog : public QDialog {
+ Q_OBJECT;
+public:
+ IPLookupDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~IPLookupDialog();
+
+protected slots:
+ void onLookup();
+ void onFinished();
+private:
+ Ui::IPLookupDialog ui_;
+};
+
+} //namespace FQTerm
+
+#endif //__FQTERM_IPLOOKUP__ \ No newline at end of file
diff --git a/src/ui/iplookup.ui b/src/ui/iplookup.ui
new file mode 100644
index 0000000..507a456
--- /dev/null
+++ b/src/ui/iplookup.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>IPLookupDialog</class>
+ <widget class="QDialog" name="IPLookupDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>319</width>
+ <height>112</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>IP Lookup</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>IP Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="ipLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Physical Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="addressLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="lookupPushButton">
+ <property name="text">
+ <string>Lookup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="finishedPushButton">
+ <property name="text">
+ <string>Finished</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/keydialog.cpp b/src/ui/keydialog.cpp
new file mode 100644
index 0000000..2e3aadb
--- /dev/null
+++ b/src/ui/keydialog.cpp
@@ -0,0 +1,285 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QFileDialog>
+
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "keydialog.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a keyDialog as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+keyDialog::keyDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ keyButtonGroup_(this),
+ config_(config) {
+ ui_.setupUi(this);
+
+ keyButtonGroup_.addButton(ui_.radioButton1, 0);
+ keyButtonGroup_.addButton(ui_.radioButton2, 1);
+ keyButtonGroup_.addButton(ui_.radioButton3, 2);
+
+ connectSlots();
+
+ loadName();
+}
+
+keyDialog::~keyDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+void keyDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.nameListWidget, SIGNAL(currentRowChanged(int)),
+ this, SLOT(onNamechange(int))));
+ FQ_VERIFY(connect(ui_.addButton, SIGNAL(clicked()), this, SLOT(onAdd())));
+ FQ_VERIFY(connect(ui_.deleteButton, SIGNAL(clicked()), this, SLOT(onDelete())));
+ FQ_VERIFY(connect(ui_.updateButton, SIGNAL(clicked()), this, SLOT(onUpdate())));
+ FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()), this, SLOT(onClose())));
+ FQ_VERIFY(connect(ui_.upButton, SIGNAL(clicked()), this, SLOT(onUp())));
+ FQ_VERIFY(connect(ui_.downButton, SIGNAL(clicked()), this, SLOT(onDown())));
+ FQ_VERIFY(connect(ui_.leftButton, SIGNAL(clicked()), this, SLOT(onLeft())));
+ FQ_VERIFY(connect(ui_.rightButton, SIGNAL(clicked()), this, SLOT(onRight())));
+ FQ_VERIFY(connect(ui_.enterButton, SIGNAL(clicked()), this, SLOT(onEnter())));
+// FQ_VERIFY(connect(&keyButtonGroup_, SIGNAL(buttonClicked(int)), this, SLOT(onSelect(int))));
+ FQ_VERIFY(connect(ui_.scriptButton, SIGNAL(clicked()), this, SLOT(onChooseScript())));
+ FQ_VERIFY(connect(ui_.programButton, SIGNAL(clicked()), this, SLOT(onProgram())));
+
+}
+
+void keyDialog::onNamechange(int item) {
+ loadKey(item);
+}
+
+void keyDialog::onAdd() {
+ QString strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+
+ strTmp.setNum(num + 1);
+ config_->setItemValue("key", "num", strTmp);
+
+ QString strValue;
+ switch (keyButtonGroup_.checkedId()) {
+ case 0:
+ strValue = "0" + ui_.keyEdit->text();
+ break;
+ case 1:
+ strValue = "1" + ui_.scriptEdit->text();
+ break;
+ case 2:
+ strValue = "2" + ui_.programEdit->text();
+ break;
+ }
+ strTmp = QString("key%1").arg(num);
+ config_->setItemValue("key", strTmp, strValue);
+
+ strTmp = QString("name%1").arg(num);
+ config_->setItemValue("key", strTmp, ui_.nameEdit->text());
+
+ strTmp = QString("shortcut%1").arg(num);
+ config_->setItemValue("key", strTmp, ui_.shortcutEdit->text());
+
+ ui_.nameListWidget->addItem(ui_.nameEdit->text());
+ ui_.nameListWidget->setCurrentRow(ui_.nameListWidget->count() -1);
+}
+
+void keyDialog::onDelete() {
+ QString strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+ if (num == 0) {
+ return ;
+ }
+ strTmp.setNum(num -1);
+ config_->setItemValue("key", "num", strTmp);
+
+ int index = ui_.nameListWidget->currentRow();
+ QString strItem1, strItem2;
+ for (int i = index; i < num -1; i++) {
+ strItem1 = QString("key%1").arg(i);
+ strItem2 = QString("key%1").arg(i + 1);
+ config_->setItemValue("key", strItem1, config_->getItemValue("key", strItem2));
+ strItem1 = QString("name%1").arg(i);
+ strItem2 = QString("name%1").arg(i + 1);
+ config_->setItemValue("key", strItem1, config_->getItemValue("key", strItem2));
+ }
+
+ ui_.nameListWidget->takeItem(index);
+ ui_.nameListWidget->setCurrentRow(qMin(index, ui_.nameListWidget->count() -1));
+}
+
+void keyDialog::onUpdate() {
+ int index = ui_.nameListWidget->currentRow();
+ if (index < 0) {
+ return ;
+ }
+
+ QString strValue;
+ switch (keyButtonGroup_.checkedId()) {
+ case 0:
+ strValue = "0" + ui_.keyEdit->text();
+ break;
+ case 1:
+ strValue = "1" + ui_.scriptEdit->text();
+ break;
+ case 2:
+ strValue = "2" + ui_.programEdit->text();
+ break;
+ }
+
+ QString strTmp;
+
+ strTmp = QString("key%1").arg(index);
+ config_->setItemValue("key", strTmp, strValue);
+
+ strTmp = QString("name%1").arg(index);
+ config_->setItemValue("key", strTmp, ui_.nameEdit->text());
+
+ strTmp = QString("shortcut%1").arg(index);
+ config_->setItemValue("key", strTmp, ui_.shortcutEdit->text());
+
+ ui_.nameListWidget->item(index)->setText(ui_.nameEdit->text());
+}
+
+void keyDialog::onClose() {
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+ done(1);
+}
+
+void keyDialog::onUp() {
+ ui_.keyEdit->insert("^[[A");
+}
+
+void keyDialog::onDown() {
+ ui_.keyEdit->insert("^[[B");
+}
+
+void keyDialog::onLeft() {
+ ui_.keyEdit->insert("^[[D");
+}
+
+void keyDialog::onRight() {
+ ui_.keyEdit->insert("^[[C");
+}
+
+void keyDialog::onEnter() {
+ ui_.keyEdit->insert("^M");
+}
+
+// void keyDialog::onSelect(int id)
+// {
+// switch(id)
+// {
+// case 0: // key
+// ui.keyEdit->setEnabled(true);
+// ui.scriptEdit->setEnabled(false);
+// ui.scriptButton->setEnabled(false);
+// ui.programEdit->setEnabled(false);
+// ui.programButton->setEnabled(false);
+// break;
+// case 1: // script
+// ui.keyEdit->setEnabled(false);
+// ui.scriptEdit->setEnabled(true);
+// ui.scriptButton->setEnabled(true);
+// ui.programEdit->setEnabled(false);
+// ui.programButton->setEnabled(false);
+// break;
+// case 2: // program
+// ui.scriptEdit->setEnabled(false);
+// ui.scriptButton->setEnabled(false);
+// ui.keyEdit->setEnabled(false);
+// ui.programEdit->setEnabled(true);
+// ui.programButton->setEnabled(true);
+// break;
+// }
+// }
+void keyDialog::onChooseScript() {
+ QString script = QFileDialog::getOpenFileName(
+ this, "Select a script", QDir::currentPath(), "JavaScript File (*.js)");
+ if (!script.isEmpty()) {
+ ui_.scriptEdit->setText(script);
+ }
+}
+
+void keyDialog::onProgram() {
+ QString program = QFileDialog::getOpenFileName(
+ this, "Select a program", QDir::currentPath(), "*");
+ if (!program.isNull()) {
+ ui_.programEdit->setText(program);
+ }
+}
+
+void keyDialog::loadName() {
+ QString strTmp = config_->getItemValue("key", "num");
+ int num = strTmp.toInt();
+ for (int i = 0; i < num; i++) {
+ strTmp = QString("name%1").arg(i);
+ ui_.nameListWidget->addItem(config_->getItemValue("key", strTmp));
+ }
+ if (num > 0) {
+ ui_.nameListWidget->setCurrentRow(0);
+ } else {
+ ui_.radioButton1->setChecked(true);
+ //onSelect(0);
+ }
+}
+
+void keyDialog::loadKey(int n) {
+ QString strTmp = config_->getItemValue("key", "num");
+ if (n >= strTmp.toInt()) {
+ return ;
+ }
+
+ QString strItem;
+
+ strItem = QString("name%1").arg(n);
+ ui_.nameEdit->setText(config_->getItemValue("key", strItem));
+
+ strItem = QString("key%1").arg(n);
+ strTmp = config_->getItemValue("key", strItem);
+ if (strTmp[0] == '0') {
+ ui_.keyEdit->setText(strTmp.mid(1));
+ ui_.radioButton1->setChecked(true);
+ //onSelect(0);
+ } else if (strTmp[0] == '1') {
+ ui_.scriptEdit->setText(strTmp.mid(1));
+ ui_.radioButton2->setChecked(true);
+ //onSelect(7);
+ } else if (strTmp[0] == '2') {
+ ui_.programEdit->setText(strTmp.mid(1));
+ ui_.radioButton3->setChecked(true);
+ //onSelect(6);
+ }
+ strItem = QString("shortcut%1").arg(n);
+ strTmp = config_->getItemValue("key", strItem);
+ ui_.shortcutEdit->setText(strTmp);
+}
+
+} // namespace FQTerm
+
+#include "keydialog.moc"
diff --git a/src/ui/keydialog.h b/src/ui/keydialog.h
new file mode 100644
index 0000000..fa087c3
--- /dev/null
+++ b/src/ui/keydialog.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_KEY_DIALOG_H
+#define FQTERM_KEY_DIALOG_H
+
+#include "ui_keydialog.h"
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class keyDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ keyDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~keyDialog();
+
+ protected:
+ void connectSlots();
+ void loadKey(int);
+ void loadName();
+
+ protected slots:
+ void onNamechange(int);
+ void onClose();
+ void onAdd();
+ void onDelete();
+ void onUpdate();
+ void onChooseScript();
+ void onProgram();
+ void onUp();
+ void onDown();
+ void onLeft();
+ void onRight();
+ void onEnter();
+ // void onSelect(int);
+ private:
+ Ui::keyDialog ui_;
+ QButtonGroup keyButtonGroup_;
+ FQTermConfig * config_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_KEY_DIALOG_H
diff --git a/src/ui/keydialog.ui b/src/ui/keydialog.ui
new file mode 100644
index 0000000..34b8124
--- /dev/null
+++ b/src/ui/keydialog.ui
@@ -0,0 +1,665 @@
+<ui version="4.0" >
+ <class>keyDialog</class>
+ <widget class="QDialog" name="keyDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>463</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Key Setup</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="10" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="addButton" >
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteButton" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="updateButton" >
+ <property name="text" >
+ <string>Update</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="10" >
+ <widget class="QListWidget" name="nameListWidget" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="textLabel1" >
+ <property name="text" >
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" colspan="4" >
+ <widget class="QLineEdit" name="nameEdit" />
+ </item>
+ <item row="3" column="0" colspan="2" >
+ <widget class="QLabel" name="shortcutLabel" >
+ <property name="text" >
+ <string>Short Cut</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3" colspan="4" >
+ <widget class="QLineEdit" name="shortcutEdit" />
+ </item>
+ <item row="4" column="0" colspan="10" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Define</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QRadioButton" name="radioButton1" >
+ <property name="text" >
+ <string>Key</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="8" >
+ <widget class="QLineEdit" name="keyEdit" />
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QLabel" name="textLabel3" >
+ <property name="text" >
+ <string>General Keys</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QPushButton" name="upButton" >
+ <property name="text" >
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4" >
+ <widget class="QPushButton" name="downButton" >
+ <property name="text" >
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5" >
+ <widget class="QPushButton" name="leftButton" >
+ <property name="text" >
+ <string>Left</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6" colspan="2" >
+ <widget class="QPushButton" name="rightButton" >
+ <property name="text" >
+ <string>Right</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="8" >
+ <widget class="QPushButton" name="enterButton" >
+ <property name="text" >
+ <string>Enter</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QRadioButton" name="radioButton2" >
+ <property name="text" >
+ <string>Script</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="5" >
+ <widget class="QLineEdit" name="scriptEdit" />
+ </item>
+ <item row="2" column="7" colspan="2" >
+ <widget class="QPushButton" name="scriptButton" >
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2" >
+ <widget class="QRadioButton" name="radioButton3" >
+ <property name="text" >
+ <string>Program</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" colspan="5" >
+ <widget class="QLineEdit" name="programEdit" />
+ </item>
+ <item row="3" column="7" colspan="2" >
+ <widget class="QPushButton" name="programButton" >
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>keyEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>69</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>109</x>
+ <y>230</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>upButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>66</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>151</x>
+ <y>266</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>downButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>237</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>234</x>
+ <y>267</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leftButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>69</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>299</x>
+ <y>263</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>rightButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>50</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>359</x>
+ <y>265</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>enterButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>64</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>417</x>
+ <y>264</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>246</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>124</x>
+ <y>314</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>41</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>362</x>
+ <y>293</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>245</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>111</x>
+ <y>354</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>64</x>
+ <y>230</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>409</x>
+ <y>343</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>keyEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>296</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>101</x>
+ <y>230</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>upButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>85</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>142</x>
+ <y>284</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>downButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>307</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>205</x>
+ <y>277</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leftButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>21</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>299</x>
+ <y>277</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>rightButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>25</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>359</x>
+ <y>284</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>enterButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>81</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>419</x>
+ <y>266</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>76</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>119</x>
+ <y>290</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>82</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>341</x>
+ <y>290</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>294</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>113</x>
+ <y>354</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>83</x>
+ <y>305</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>346</x>
+ <y>354</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>keyEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>339</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>116</x>
+ <y>248</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>upButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>173</x>
+ <y>271</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>downButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>96</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>200</x>
+ <y>284</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leftButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>299</x>
+ <y>270</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>rightButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>20</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>359</x>
+ <y>275</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>enterButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>90</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>419</x>
+ <y>277</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>77</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>269</x>
+ <y>312</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>scriptButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>98</x>
+ <y>333</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>346</x>
+ <y>309</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>349</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>128</x>
+ <y>349</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>radioButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>programButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>73</x>
+ <y>335</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>342</x>
+ <y>335</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/msgdialog.cpp b/src/ui/msgdialog.cpp
new file mode 100644
index 0000000..1db7495
--- /dev/null
+++ b/src/ui/msgdialog.cpp
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include "msgdialog.h"
+
+msgDialog::msgDialog(QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl) {
+ ui_.setupUi(this);
+ // signals and slots connections
+ //QVERIFY(connect( okButton, SIGNAL( clicked() ), this, SLOT( accept() ) ));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+msgDialog::~msgDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void msgDialog::setMessageText(const QString& message) {
+ ui_.msgBrowser->setPlainText(message);
+}
+
+#include "msgdialog.moc"
diff --git a/src/ui/msgdialog.h b/src/ui/msgdialog.h
new file mode 100644
index 0000000..e3c5185
--- /dev/null
+++ b/src/ui/msgdialog.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_MSGDIALOG_H
+#define FQTERM_MSGDIALOG_H
+
+#include "ui_msgdialog.h"
+
+class msgDialog: public QDialog {
+ Q_OBJECT;
+public:
+ msgDialog(QWidget *parent = 0, Qt::WFlags fl = 0);
+ ~msgDialog();
+ void setMessageText(const QString& message);
+ Ui::msgDialog ui_;
+};
+
+#endif // FQTERM_MSGDIALOG_H
diff --git a/src/ui/msgdialog.ui b/src/ui/msgdialog.ui
new file mode 100644
index 0000000..93ff1c4
--- /dev/null
+++ b/src/ui/msgdialog.ui
@@ -0,0 +1,86 @@
+<ui version="4.0" >
+ <class>msgDialog</class>
+ <widget class="QDialog" name="msgDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>586</width>
+ <height>393</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Messages Viewer</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" colspan="3" >
+ <widget class="QTextBrowser" name="msgBrowser" />
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>msgDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>311</x>
+ <y>403</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>396</x>
+ <y>403</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/osdmessage.cpp b/src/ui/osdmessage.cpp
new file mode 100644
index 0000000..1b0883f
--- /dev/null
+++ b/src/ui/osdmessage.cpp
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPaintEvent>
+#include <QCursor>
+#include <QTimer>
+#include <QApplication>
+#include <QPainter>
+#include <QBitmap>
+#include <QPalette>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+
+#include "osdmessage.h"
+
+namespace FQTerm {
+
+PageViewMessage::PageViewMessage(QWidget *parent_)
+ : QWidget(parent_),
+ timer_(0),
+ message_() {
+ setFocusPolicy(Qt::NoFocus);
+ //setBackgroundMode( Qt::NoBackground );
+ QPalette palette;
+ palette.setColor(backgroundRole(), qApp->palette().color(QPalette::Active,
+ QPalette::Background));
+ setPalette(palette);
+ // setPaletteBackgroundColor(qApp->palette().color(QPalette::Active, QPalette::Background));
+ setCursor(QCursor(Qt::ArrowCursor));
+ move(10, 10);
+ resize(0, 0);
+ hide();
+}
+
+// give to Caesar what Caesar owns: code taken from Amarok's osd.h/.cpp
+// "redde (reddite, pl.) cesari quae sunt cesaris", just btw. ;)
+void PageViewMessage::display(const QString &message, Icon icon, int durationMs, QPoint pos, PageViewMessage::Alignment ali)
+{
+ displayImpl(message, icon, false, durationMs, pos, ali);
+}
+
+void PageViewMessage::display(const QString &message, QPoint pos, Icon icon)
+{
+ displayImpl(message, icon, false, 4000, pos, TopLeft);
+}
+
+QRect PageViewMessage::displayCheck(const QString &message, Icon icon)
+{
+ return displayImpl(message, icon, true);
+}
+
+QRect PageViewMessage::displayImpl(const QString &message, Icon icon, bool check, int durationMs, QPoint pos, Alignment ali)
+{
+ //FIXME: add a option in fqterm too.
+ /*
+ if ( !KpdfSettings::showOSD() )
+ {
+ hide();
+ return;
+ }
+ */
+ // determine text rectangle
+
+ if (!isHidden() && message == message_) {
+ timer_->setSingleShot(true);
+ timer_->start(durationMs);
+ return QRect(QPoint(0, 0), size());
+ }
+ message_ = message;
+ QRect textRect = fontMetrics().boundingRect(message);
+ textRect.translate(-textRect.left(), -textRect.top());
+ textRect.adjust(0, 0, 2, 2);
+ int width = textRect.width(), height = textRect.height(), textXOffset = 0,
+ shadowOffset = message.isRightToLeft() ? -1: 1;
+
+ // load icon (if set) and update geometry
+ // [FQTerm], we don't have a icon at this time.
+
+ QPixmap symbol;
+ if (icon != None) {
+ switch (icon) {
+ //case Find:
+ //symbol = SmallIcon( "viewmag" );
+ //break;
+ case Error:
+ symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png");
+ break;
+ case Warning:
+ symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_warning.png");
+ break;
+ default:
+ symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_info.png");
+ break;
+ }
+ textXOffset = 2+symbol.width();
+ width += textXOffset;
+ height = qMax(height, symbol.height());
+ }
+
+ QRect geometry(0, 0, width + 10, height + 8);
+
+ if (check)
+ return geometry;
+
+ // resize pixmap, mask and widget
+ static QPixmap mask;
+ mask = QPixmap(geometry.size());
+ pixmap_ = QPixmap(geometry.size());
+ resize(geometry.size());
+
+ switch(ali)
+ {
+ case TopLeft:
+ move(pos);
+ break;
+ case TopRight:
+ move(pos - geometry.topRight());
+ break;
+ case BottomLeft:
+ move(pos - geometry.bottomLeft());
+ break;
+ case BottomRight:
+ move(pos - geometry.bottomRight());
+ break;
+ }
+
+ // create and set transparency mask
+ QPainter maskPainter(&mask);
+ mask.fill(Qt::black);
+ maskPainter.setBrush(Qt::white);
+ maskPainter.drawRoundRect(geometry, 1600 / geometry.width(), 1600 /
+ geometry.height());
+ setMask(mask.createHeuristicMask());
+
+ // draw background
+ QPainter bufferPainter(&pixmap_);
+ bufferPainter.setPen(Qt::black);
+ bufferPainter.setBrush(palette().brush(QPalette::Window));
+ bufferPainter.drawRoundRect(geometry, 1600 / geometry.width(), 1600 /
+ geometry.height());
+
+ // draw icon if present
+ if (!symbol.isNull()) {
+ bufferPainter.drawPixmap(5, 4, symbol, 0, 0, symbol.width(), symbol.height());
+ }
+
+ // draw shadow and text
+ int yText = geometry.height() - height / 2;
+ bufferPainter.setPen(palette().color(QPalette::Window).dark(115));
+ bufferPainter.drawText(5+textXOffset + shadowOffset, yText + 1, message);
+ bufferPainter.setPen(palette().color(QPalette::WindowText));
+ bufferPainter.drawText(5+textXOffset, yText, message);
+
+ // show widget and schedule a repaint
+ show();
+ update();
+
+ // close the message window after given mS
+ if (durationMs > 0) {
+ if (!timer_) {
+ timer_ = new QTimer(this);
+ timer_->setSingleShot(true);
+ FQ_VERIFY(connect(timer_, SIGNAL(timeout()), SLOT(hide())));
+ }
+ timer_->start(durationMs);
+ } else if (timer_) {
+ timer_->stop();
+ }
+
+ return QRect(QPoint(0, 0), size());
+}
+
+void PageViewMessage::paintEvent(QPaintEvent *e) {
+ QPainter p(this);
+ p.drawPixmap(e->rect().topLeft(), pixmap_, e->rect());
+}
+
+void PageViewMessage::mousePressEvent(QMouseEvent * /*e*/) {
+ if (timer_) {
+ timer_->stop();
+ }
+ hide();
+}
+
+void PageViewMessage::hideEvent( QHideEvent * event ) {
+ emit hideAt(geometry ());
+ QWidget::hideEvent(event);
+}
+
+} // namespace FQTerm
+
+#include "osdmessage.moc"
diff --git a/src/ui/osdmessage.h b/src/ui/osdmessage.h
new file mode 100644
index 0000000..fe29d4d
--- /dev/null
+++ b/src/ui/osdmessage.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_OSD_MESSAGE_H
+#define FQTERM_OSD_MESSAGE_H
+
+#include <QPixmap>
+#include <QWidget>
+#include <QHideEvent>
+
+namespace FQTerm {
+
+/**
+ * A widget that displays messages in the top-left corner.
+ */
+class PageViewMessage: public QWidget {
+ Q_OBJECT;
+ public:
+ PageViewMessage(QWidget *parent_);
+
+ enum Alignment {
+ TopLeft, TopRight, BottomLeft, BottomRight
+ };
+ enum Icon {
+ None, Info, Warning, Error, Find
+ };
+ void display(const QString &message, Icon icon = Info, int durationMs = 4000,
+ QPoint pos = QPoint(10, 10), Alignment ali = TopLeft);
+ void display(const QString &message, QPoint pos, Icon icon = Info);
+ QRect displayCheck(const QString &message, Icon icon = Info);
+ public slots:
+ void showText(const QString &message){
+ display(message);
+ }
+ protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ QRect displayImpl(const QString &message, Icon icon = Info,
+ bool check = false, int durationMs = 4000,
+ QPoint pos = QPoint(10, 10), Alignment ali = TopLeft);
+ void hideEvent(QHideEvent * event);
+ private:
+ QPixmap pixmap_;
+ QTimer *timer_;
+ QString message_;
+signals:
+ void hideAt(const QRect& rect);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_OSD_MESSAGE_H
diff --git a/src/ui/overlayWidget.cpp b/src/ui/overlayWidget.cpp
new file mode 100644
index 0000000..74f0659
--- /dev/null
+++ b/src/ui/overlayWidget.cpp
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPoint>
+#include <QFrame>
+#include <QResizeEvent>
+#include <QEvent>
+
+#include "overlayWidget.h"
+
+namespace FQTerm {
+
+OverlayWidget::OverlayWidget(QWidget *parent, QWidget *anchor)
+ : QFrame(parent->parentWidget()->parentWidget()),
+ anchor_(anchor),
+ parent_(parent) {
+ parent->installEventFilter(this);
+
+ hide();
+}
+
+void OverlayWidget::reposition() {
+ setMaximumSize(parentWidget()->size());
+ adjustSize();
+
+ // p is in the alignWidget's coordinates
+ QPoint p;
+
+ p.setX(anchor_->width() - width());
+ p.setY(-height());
+
+ // Position in the toplevelwidget's coordinates
+ QPoint pTopLevel = anchor_->mapTo(topLevelWidget(), p);
+
+ // Position in the widget's parentWidget coordinates
+ QPoint pParent = parentWidget()->mapFrom(topLevelWidget(), pTopLevel);
+ // keep it on the screen
+ if (pParent.x() < 0) {
+ pParent.rx() = 0;
+ }
+
+ // Move 'this' to that position.
+ move(pParent);
+}
+
+bool OverlayWidget::eventFilter(QObject *o, QEvent *e) {
+ if (e->type() == QEvent::Move || e->type() == QEvent::Resize) {
+ reposition();
+ }
+
+ return QFrame::eventFilter(o, e);
+}
+
+void OverlayWidget::resizeEvent(QResizeEvent *ev) {
+ reposition();
+ QFrame::resizeEvent(ev);
+}
+
+bool OverlayWidget::event(QEvent *e) {
+ if (e->type() == QEvent::ChildAdded) {
+ adjustSize();
+ }
+
+ return QFrame::event(e);
+}
+
+}
diff --git a/src/ui/overlayWidget.h b/src/ui/overlayWidget.h
new file mode 100644
index 0000000..edab3f6
--- /dev/null
+++ b/src/ui/overlayWidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERMOVERLAYWIDGET_H
+#define FQTERMOVERLAYWIDGET_H
+
+#include <QFrame>
+#include <QResizeEvent>
+#include <QEvent>
+#include <QHBoxLayout>
+
+namespace FQTerm {
+class OverlayWidget: public QFrame {
+ public:
+ /**
+ * The widget is parented to the toplevelwidget of alignWidget,
+ * this could be an issue if that widget has an autoAdd Layout
+ */
+ OverlayWidget(QWidget *parent, QWidget *anchor);
+ virtual void reposition();
+
+ protected:
+ virtual void resizeEvent(QResizeEvent*);
+ virtual bool eventFilter(QObject *, QEvent*);
+ virtual bool event(QEvent*);
+
+ private:
+ QWidget *anchor_;
+ QWidget *parent_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERMOVERLAYWIDGET_H
diff --git a/src/ui/pictureflow.cpp b/src/ui/pictureflow.cpp
new file mode 100644
index 0000000..cd749f0
--- /dev/null
+++ b/src/ui/pictureflow.cpp
@@ -0,0 +1,1201 @@
+
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+/*
+ PictureFlow - animated image show widget
+ http://pictureflow.googlecode.com
+
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#include "pictureflow.h"
+
+#include <QBasicTimer>
+#include <QMouseEvent>
+#include <QCache>
+#include <QImage>
+#include <QKeyEvent>
+#include <QPainter>
+#include <QPixmap>
+#include <QTimer>
+#include <QVector>
+#include <QWidget>
+
+// uncomment this to enable bilinear filtering for texture mapping
+// gives much better rendering, at the cost of memory space
+// #define PICTUREFLOW_BILINEAR_FILTER
+
+// for fixed-point arithmetic, we need minimum 32-bit long
+// long long (64-bit) might be useful for multiplication and division
+typedef long PFreal;
+#define PFREAL_SHIFT 10
+#define PFREAL_FACTOR (1 << PFREAL_SHIFT)
+#define PFREAL_ONE (1 << PFREAL_SHIFT)
+#define PFREAL_HALF (PFREAL_ONE >> 1)
+
+inline PFreal fmul(PFreal a, PFreal b)
+{
+ return ((long long)(a))*((long long)(b)) >> PFREAL_SHIFT;
+}
+
+inline PFreal fdiv(PFreal num, PFreal den)
+{
+ long long p = (long long)(num) << (PFREAL_SHIFT*2);
+ long long q = p / (long long)den;
+ long long r = q >> PFREAL_SHIFT;
+
+ return r;
+}
+
+#define IANGLE_MAX 1024
+#define IANGLE_MASK 1023
+
+// warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed!
+static const PFreal sinTable[IANGLE_MAX] = {
+ 3, 9, 15, 21, 28, 34, 40, 47,
+ 53, 59, 65, 72, 78, 84, 90, 97,
+ 103, 109, 115, 122, 128, 134, 140, 147,
+ 153, 159, 165, 171, 178, 184, 190, 196,
+ 202, 209, 215, 221, 227, 233, 239, 245,
+ 251, 257, 264, 270, 276, 282, 288, 294,
+ 300, 306, 312, 318, 324, 330, 336, 342,
+ 347, 353, 359, 365, 371, 377, 383, 388,
+ 394, 400, 406, 412, 417, 423, 429, 434,
+ 440, 446, 451, 457, 463, 468, 474, 479,
+ 485, 491, 496, 501, 507, 512, 518, 523,
+ 529, 534, 539, 545, 550, 555, 561, 566,
+ 571, 576, 581, 587, 592, 597, 602, 607,
+ 612, 617, 622, 627, 632, 637, 642, 647,
+ 652, 656, 661, 666, 671, 675, 680, 685,
+ 690, 694, 699, 703, 708, 712, 717, 721,
+ 726, 730, 735, 739, 743, 748, 752, 756,
+ 760, 765, 769, 773, 777, 781, 785, 789,
+ 793, 797, 801, 805, 809, 813, 816, 820,
+ 824, 828, 831, 835, 839, 842, 846, 849,
+ 853, 856, 860, 863, 866, 870, 873, 876,
+ 879, 883, 886, 889, 892, 895, 898, 901,
+ 904, 907, 910, 913, 916, 918, 921, 924,
+ 927, 929, 932, 934, 937, 939, 942, 944,
+ 947, 949, 951, 954, 956, 958, 960, 963,
+ 965, 967, 969, 971, 973, 975, 977, 978,
+ 980, 982, 984, 986, 987, 989, 990, 992,
+ 994, 995, 997, 998, 999, 1001, 1002, 1003,
+ 1004, 1006, 1007, 1008, 1009, 1010, 1011, 1012,
+ 1013, 1014, 1015, 1015, 1016, 1017, 1018, 1018,
+ 1019, 1019, 1020, 1020, 1021, 1021, 1022, 1022,
+ 1022, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
+ 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1022,
+ 1022, 1022, 1021, 1021, 1020, 1020, 1019, 1019,
+ 1018, 1018, 1017, 1016, 1015, 1015, 1014, 1013,
+ 1012, 1011, 1010, 1009, 1008, 1007, 1006, 1004,
+ 1003, 1002, 1001, 999, 998, 997, 995, 994,
+ 992, 990, 989, 987, 986, 984, 982, 980,
+ 978, 977, 975, 973, 971, 969, 967, 965,
+ 963, 960, 958, 956, 954, 951, 949, 947,
+ 944, 942, 939, 937, 934, 932, 929, 927,
+ 924, 921, 918, 916, 913, 910, 907, 904,
+ 901, 898, 895, 892, 889, 886, 883, 879,
+ 876, 873, 870, 866, 863, 860, 856, 853,
+ 849, 846, 842, 839, 835, 831, 828, 824,
+ 820, 816, 813, 809, 805, 801, 797, 793,
+ 789, 785, 781, 777, 773, 769, 765, 760,
+ 756, 752, 748, 743, 739, 735, 730, 726,
+ 721, 717, 712, 708, 703, 699, 694, 690,
+ 685, 680, 675, 671, 666, 661, 656, 652,
+ 647, 642, 637, 632, 627, 622, 617, 612,
+ 607, 602, 597, 592, 587, 581, 576, 571,
+ 566, 561, 555, 550, 545, 539, 534, 529,
+ 523, 518, 512, 507, 501, 496, 491, 485,
+ 479, 474, 468, 463, 457, 451, 446, 440,
+ 434, 429, 423, 417, 412, 406, 400, 394,
+ 388, 383, 377, 371, 365, 359, 353, 347,
+ 342, 336, 330, 324, 318, 312, 306, 300,
+ 294, 288, 282, 276, 270, 264, 257, 251,
+ 245, 239, 233, 227, 221, 215, 209, 202,
+ 196, 190, 184, 178, 171, 165, 159, 153,
+ 147, 140, 134, 128, 122, 115, 109, 103,
+ 97, 90, 84, 78, 72, 65, 59, 53,
+ 47, 40, 34, 28, 21, 15, 9, 3,
+ -4, -10, -16, -22, -29, -35, -41, -48,
+ -54, -60, -66, -73, -79, -85, -91, -98,
+ -104, -110, -116, -123, -129, -135, -141, -148,
+ -154, -160, -166, -172, -179, -185, -191, -197,
+ -203, -210, -216, -222, -228, -234, -240, -246,
+ -252, -258, -265, -271, -277, -283, -289, -295,
+ -301, -307, -313, -319, -325, -331, -337, -343,
+ -348, -354, -360, -366, -372, -378, -384, -389,
+ -395, -401, -407, -413, -418, -424, -430, -435,
+ -441, -447, -452, -458, -464, -469, -475, -480,
+ -486, -492, -497, -502, -508, -513, -519, -524,
+ -530, -535, -540, -546, -551, -556, -562, -567,
+ -572, -577, -582, -588, -593, -598, -603, -608,
+ -613, -618, -623, -628, -633, -638, -643, -648,
+ -653, -657, -662, -667, -672, -676, -681, -686,
+ -691, -695, -700, -704, -709, -713, -718, -722,
+ -727, -731, -736, -740, -744, -749, -753, -757,
+ -761, -766, -770, -774, -778, -782, -786, -790,
+ -794, -798, -802, -806, -810, -814, -817, -821,
+ -825, -829, -832, -836, -840, -843, -847, -850,
+ -854, -857, -861, -864, -867, -871, -874, -877,
+ -880, -884, -887, -890, -893, -896, -899, -902,
+ -905, -908, -911, -914, -917, -919, -922, -925,
+ -928, -930, -933, -935, -938, -940, -943, -945,
+ -948, -950, -952, -955, -957, -959, -961, -964,
+ -966, -968, -970, -972, -974, -976, -978, -979,
+ -981, -983, -985, -987, -988, -990, -991, -993,
+ -995, -996, -998, -999, -1000, -1002, -1003, -1004,
+ -1005, -1007, -1008, -1009, -1010, -1011, -1012, -1013,
+ -1014, -1015, -1016, -1016, -1017, -1018, -1019, -1019,
+ -1020, -1020, -1021, -1021, -1022, -1022, -1023, -1023,
+ -1023, -1024, -1024, -1024, -1024, -1024, -1024, -1024,
+ -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1023,
+ -1023, -1023, -1022, -1022, -1021, -1021, -1020, -1020,
+ -1019, -1019, -1018, -1017, -1016, -1016, -1015, -1014,
+ -1013, -1012, -1011, -1010, -1009, -1008, -1007, -1005,
+ -1004, -1003, -1002, -1000, -999, -998, -996, -995,
+ -993, -991, -990, -988, -987, -985, -983, -981,
+ -979, -978, -976, -974, -972, -970, -968, -966,
+ -964, -961, -959, -957, -955, -952, -950, -948,
+ -945, -943, -940, -938, -935, -933, -930, -928,
+ -925, -922, -919, -917, -914, -911, -908, -905,
+ -902, -899, -896, -893, -890, -887, -884, -880,
+ -877, -874, -871, -867, -864, -861, -857, -854,
+ -850, -847, -843, -840, -836, -832, -829, -825,
+ -821, -817, -814, -810, -806, -802, -798, -794,
+ -790, -786, -782, -778, -774, -770, -766, -761,
+ -757, -753, -749, -744, -740, -736, -731, -727,
+ -722, -718, -713, -709, -704, -700, -695, -691,
+ -686, -681, -676, -672, -667, -662, -657, -653,
+ -648, -643, -638, -633, -628, -623, -618, -613,
+ -608, -603, -598, -593, -588, -582, -577, -572,
+ -567, -562, -556, -551, -546, -540, -535, -530,
+ -524, -519, -513, -508, -502, -497, -492, -486,
+ -480, -475, -469, -464, -458, -452, -447, -441,
+ -435, -430, -424, -418, -413, -407, -401, -395,
+ -389, -384, -378, -372, -366, -360, -354, -348,
+ -343, -337, -331, -325, -319, -313, -307, -301,
+ -295, -289, -283, -277, -271, -265, -258, -252,
+ -246, -240, -234, -228, -222, -216, -210, -203,
+ -197, -191, -185, -179, -172, -166, -160, -154,
+ -148, -141, -135, -129, -123, -116, -110, -104,
+ -98, -91, -85, -79, -73, -66, -60, -54,
+ -48, -41, -35, -29, -22, -16, -10, -4
+};
+
+// this is the program the generate the above table
+#if 0
+#include <stdio.h>
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define PFREAL_ONE 1024
+#define IANGLE_MAX 1024
+
+int main(int, char**)
+{
+ FILE*f = fopen("table.c","wt");
+ fprintf(f,"PFreal sinTable[] = {\n");
+ for(int i = 0; i < 128; ++i)
+ {
+ for(int j = 0; j < 8; ++j)
+ {
+ int iang = j+i*8;
+ double ii = (double)iang + 0.5;
+ double angle = ii * 2 * M_PI / IANGLE_MAX;
+ double sinAngle = sin(angle);
+ fprintf(f,"%6d, ", (int)(floor(PFREAL_ONE*sinAngle)));
+ }
+ fprintf(f,"\n");
+ }
+ fprintf(f,"};\n");
+ fclose(f);
+
+ return 0;
+}
+#endif
+
+inline PFreal fsin(int iangle)
+{
+ while(iangle < 0)
+ iangle += IANGLE_MAX;
+ return sinTable[iangle & IANGLE_MASK];
+}
+
+inline PFreal fcos(int iangle)
+{
+ // quarter phase shift
+ return fsin(iangle + (IANGLE_MAX >> 2));
+}
+
+namespace FQTerm {
+
+struct SlideInfo
+{
+ int slideIndex;
+ int angle;
+ PFreal cx;
+ PFreal cy;
+};
+
+class PictureFlowPrivate
+{
+public:
+ PictureFlowPrivate(PictureFlow* widget);
+
+ int slideCount() const;
+ void setSlideCount(int count);
+
+ QSize slideSize() const;
+ void setSlideSize(QSize size);
+
+ int zoomFactor() const;
+ void setZoomFactor(int z);
+
+ QImage slide(int index) const;
+ void setSlide(int index, const QImage& image);
+
+ int currentSlide() const;
+ void setCurrentSlide(int index);
+
+ void showPrevious();
+ void showNext();
+ void showSlide(int index);
+
+ void resize(int w, int h);
+
+ void render();
+ void startAnimation();
+ void updateAnimation();
+
+ QImage buffer;
+ QBasicTimer animateTimer;
+ QVector<QRect> slidesRect;
+
+private:
+ PictureFlow* widget;
+
+ int slideWidth;
+ int slideHeight;
+ int zoom;
+
+ QVector<QImage> slideImages;
+ int centerIndex;
+
+ SlideInfo centerSlide;
+ QVector<SlideInfo> leftSlides;
+ QVector<SlideInfo> rightSlides;
+
+ QVector<PFreal> rays;
+ int itilt;
+ int spacing;
+ PFreal offsetX;
+ PFreal offsetY;
+
+ QImage blankSurface;
+ QCache<int, QImage> surfaceCache;
+ QTimer triggerTimer;
+
+ int slideFrame;
+ int step;
+ int target;
+ int fade;
+
+ void recalc(int w, int h);
+ QRect renderSlide(const SlideInfo &slide, int alpha=256, int col1=-1, int col=-1);
+ QImage* surface(int slideIndex);
+ void triggerRender();
+ void resetSlides();
+};
+
+PictureFlowPrivate::PictureFlowPrivate(PictureFlow* w)
+{
+ widget = w;
+
+ slideWidth = 200;
+ slideHeight = 200;
+ zoom = 100;
+
+ centerIndex = 0;
+
+ slideFrame = 0;
+ step = 0;
+ target = 0;
+ fade = 256;
+
+ triggerTimer.setSingleShot(true);
+ triggerTimer.setInterval(0);
+ QObject::connect(&triggerTimer, SIGNAL(timeout()), widget, SLOT(render()));
+
+ recalc(200, 200);
+ resetSlides();
+}
+
+int PictureFlowPrivate::slideCount() const
+{
+ return slideImages.count();
+}
+
+void PictureFlowPrivate::setSlideCount(int count)
+{
+ slideImages.resize(count);
+ surfaceCache.clear();
+ resetSlides();
+ triggerRender();
+}
+
+QSize PictureFlowPrivate::slideSize() const
+{
+ return QSize(slideWidth, slideHeight);
+}
+
+void PictureFlowPrivate::setSlideSize(QSize size)
+{
+ slideWidth = size.width();
+ slideHeight = size.height();
+ recalc(buffer.width(), buffer.height());
+ triggerRender();
+}
+
+int PictureFlowPrivate::zoomFactor() const
+{
+ return zoom;
+}
+
+void PictureFlowPrivate::setZoomFactor(int z)
+{
+ if(z <= 0)
+ return;
+
+ zoom = z;
+ recalc(buffer.width(), buffer.height());
+ triggerRender();
+}
+
+QImage PictureFlowPrivate::slide(int index) const
+{
+ return slideImages[index];
+}
+
+void PictureFlowPrivate::setSlide(int index, const QImage& image)
+{
+ if((index >= 0) && (index < slideImages.count()))
+ {
+ slideImages[index] = image;
+ surfaceCache.remove(index);
+ triggerRender();
+ }
+}
+
+int PictureFlowPrivate::currentSlide() const
+{
+ return centerIndex;
+}
+
+void PictureFlowPrivate::setCurrentSlide(int index)
+{
+ step = 0;
+ centerIndex = qBound(index, 0, slideImages.count()-1);
+ target = centerIndex;
+ slideFrame = index << 16;
+ resetSlides();
+ triggerRender();
+}
+
+void PictureFlowPrivate::showPrevious()
+{
+ if(step >= 0)
+ {
+ if(centerIndex > 0)
+ {
+ target = centerIndex - 1;
+ startAnimation();
+ }
+ }
+ else
+ {
+ target = qMax(0, centerIndex - 2);
+ }
+}
+
+void PictureFlowPrivate::showNext()
+{
+ if(step <= 0)
+ {
+ if(centerIndex < slideImages.count()-1)
+ {
+ target = centerIndex + 1;
+ startAnimation();
+ }
+ }
+ else
+ {
+ target = qMin(centerIndex + 2, slideImages.count()-1);
+ }
+}
+
+void PictureFlowPrivate::showSlide(int index)
+{
+ index = qMax(index, 0);
+ index = qMin(slideImages.count()-1, index);
+
+ target = index;
+ startAnimation();
+}
+
+void PictureFlowPrivate::resize(int w, int h)
+{
+ recalc(w, h);
+ resetSlides();
+ triggerRender();
+}
+
+
+// adjust slides so that they are in "steady state" position
+void PictureFlowPrivate::resetSlides()
+{
+ centerSlide.angle = 0;
+ centerSlide.cx = 0;
+ centerSlide.cy = 0;
+ centerSlide.slideIndex = centerIndex;
+
+ leftSlides.clear();
+ leftSlides.resize(6);
+ for(int i = 0; i < leftSlides.count(); ++i)
+ {
+ SlideInfo& si = leftSlides[i];
+ si.angle = itilt;
+ si.cx = -(offsetX + spacing*i*PFREAL_ONE);
+ si.cy = offsetY;
+ si.slideIndex = centerIndex-1-i;
+ }
+
+ rightSlides.clear();
+ rightSlides.resize(6);
+ for(int i = 0; i < rightSlides.count(); ++i)
+ {
+ SlideInfo& si = rightSlides[i];
+ si.angle = -itilt;
+ si.cx = offsetX + spacing*i*PFREAL_ONE;
+ si.cy = offsetY;
+ si.slideIndex = centerIndex+1+i;
+ }
+}
+
+#define BILINEAR_STRETCH_HOR 4
+#define BILINEAR_STRETCH_VER 4
+
+static QImage scaleImage (QImage image, int w, int h) {
+ // I don't have to scale it
+ if (w == image.width() && h == image.height())
+ return(image);
+
+ QImage output(w, h, QImage::Format_ARGB32_Premultiplied);
+ output.fill(0);
+
+ double scaleHeight = w / (double) image.height();
+ double scaleWidth = h / (double) image.width();
+
+ double s = qMin(scaleWidth, scaleHeight);
+
+ int sw = (int) qRound(s * image.width());
+ int sh = (int) qRound(s * image.height());
+
+ // Scale Image
+ QImage imgScaled = image.scaled(sw, sh, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+
+ int _x = (w - sw) / 2;
+ int _y = (h - sh);
+
+ for (int x = 0; x < imgScaled.width(); ++x) {
+ for (int y = 0; y < imgScaled.height(); ++y) {
+ output.setPixel(x + _x, y + _y, imgScaled.pixel(x, y));
+ }
+ }
+
+ return(output);
+}
+
+static QImage prepareSurface(QImage img, int w, int h)
+{
+ img = scaleImage(img, w, h);
+
+ // slightly larger, to accomodate for the reflection
+ int hs = h * 2;
+ int hofs = h / 3;
+
+ // offscreen buffer: black is sweet
+ QImage result(hs, w, QImage::Format_RGB32);
+ result.fill(0);
+
+ // transpose the image, this is to speed-up the rendering
+ // because we process one column at a time
+ // (and much better and faster to work row-wise, i.e in one scanline)
+ for(int x = 0; x < w; x++)
+ for(int y = 0; y < h; y++)
+ result.setPixel(hofs + y, x, img.pixel(x, y));
+
+ // create the reflection
+ int ht = hs - h - hofs;
+ int hte = ht;
+ for(int x = 0; x < w; x++)
+ for(int y = 0; y < ht; y++)
+ {
+ QRgb color = img.pixel(x, img.height()-y-1);
+ int a = qAlpha(color);
+ int r = qRed(color) * a / 256 * (hte - y) / hte * 3/5;
+ int g = qGreen(color) * a / 256 * (hte - y) / hte * 3/5;
+ int b = qBlue(color) * a / 256 * (hte - y) / hte * 3/5;
+ result.setPixel(h+hofs+y, x, qRgb(r, g, b));
+ }
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int hh = BILINEAR_STRETCH_VER*hs;
+ int ww = BILINEAR_STRETCH_HOR*w;
+ result = scaleImage(result, hh, ww);
+#endif
+
+ return result;
+}
+
+
+// get transformed image for specified slide
+// if it does not exist, create it and place it in the cache
+QImage* PictureFlowPrivate::surface(int slideIndex)
+{
+ if(slideIndex < 0)
+ return 0;
+ if(slideIndex >= slideImages.count())
+ return 0;
+
+ if(surfaceCache.contains(slideIndex))
+ return surfaceCache[slideIndex];
+
+ QImage img = widget->slide(slideIndex);
+ if(img.isNull())
+ {
+ if(blankSurface.isNull())
+ {
+ blankSurface = QImage(slideWidth, slideHeight, QImage::Format_RGB32);
+
+ QPainter painter(&blankSurface);
+ QPoint p1(slideWidth*4/10, 0);
+ QPoint p2(slideWidth*6/10, slideHeight);
+ QLinearGradient linearGrad(p1, p2);
+ linearGrad.setColorAt(0, Qt::black);
+ linearGrad.setColorAt(1, Qt::white);
+ painter.setBrush(linearGrad);
+ painter.fillRect(0, 0, slideWidth, slideHeight, QBrush(linearGrad));
+
+ painter.setPen(QPen(QColor(64,64,64), 4));
+ painter.setBrush(QBrush());
+ painter.drawRect(2, 2, slideWidth-3, slideHeight-3);
+ painter.end();
+ blankSurface = prepareSurface(blankSurface, slideWidth, slideHeight);
+ }
+ return &blankSurface;
+ }
+
+ surfaceCache.insert(slideIndex, new QImage(prepareSurface(img, slideWidth, slideHeight)));
+ return surfaceCache[slideIndex];
+}
+
+
+// Schedules rendering the slides. Call this function to avoid immediate
+// render and thus cause less flicker.
+void PictureFlowPrivate::triggerRender()
+{
+ triggerTimer.start();
+}
+
+// Render the slides. Updates only the offscreen buffer.
+void PictureFlowPrivate::render()
+{
+ buffer.fill(Qt::black);
+
+ int nleft = leftSlides.count();
+ int nright = rightSlides.count();
+
+ QRect r = renderSlide(centerSlide);
+ int c1 = r.left();
+ int c2 = r.right();
+
+ if(step == 0)
+ {
+ slidesRect.clear();
+ slidesRect.resize(11);
+
+ // no animation, boring plain rendering
+ for(int index = 0; index < nleft-1; index++)
+ {
+ int alpha = (index < nleft-2) ? 256 : 128;
+ QRect rs = renderSlide(leftSlides[index], alpha, 0, c1-1);
+ slidesRect[index] = rs;
+ if(!rs.isEmpty())
+ c1 = rs.left();
+ }
+ slidesRect[5] = r;
+ for(int index = 0; index < nright-1; index++)
+ {
+ int alpha = (index < nright-2) ? 256 : 128;
+ QRect rs = renderSlide(rightSlides[index], alpha, c2+1, buffer.width());
+ slidesRect[6 + index] = rs;
+ if(!rs.isEmpty())
+ c2 = rs.right();
+ }
+ }
+ else
+ {
+ // the first and last slide must fade in/fade out
+ for(int index = 0; index < nleft; index++)
+ {
+ int alpha = 256;
+ if(index == nleft-1)
+ alpha = (step > 0) ? 0 : 128-fade/2;
+ if(index == nleft-2)
+ alpha = (step > 0) ? 128-fade/2 : 256-fade/2;
+ if(index == nleft-3)
+ alpha = (step > 0) ? 256-fade/2 : 256;
+ QRect rs = renderSlide(leftSlides[index], alpha, 0, c1-1);
+ if(!rs.isEmpty())
+ c1 = rs.left();
+ }
+ for(int index = 0; index < nright; index++)
+ {
+ int alpha = (index < nright-2) ? 256 : 128;
+ if(index == nright-1)
+ alpha = (step > 0) ? fade/2 : 0;
+ if(index == nright-2)
+ alpha = (step > 0) ? 128+fade/2 : fade/2;
+ if(index == nright-3)
+ alpha = (step > 0) ? 256 : 128+fade/2;
+ QRect rs = renderSlide(rightSlides[index], alpha, c2+1, buffer.width());
+ if(!rs.isEmpty())
+ c2 = rs.right();
+ }
+ }
+}
+
+// Renders a slide to offscreen buffer. Returns a rect of the rendered area.
+// alpha=256 means normal, alpha=0 is fully black, alpha=128 half transparent
+// col1 and col2 limit the column for rendering.
+QRect PictureFlowPrivate::renderSlide(const SlideInfo &slide, int alpha,
+int col1, int col2)
+{
+ QImage* src = surface(slide.slideIndex);
+ if(!src)
+ return QRect();
+
+ QRect rect(0, 0, 0, 0);
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int sw = src->height() / BILINEAR_STRETCH_HOR;
+ int sh = src->width() / BILINEAR_STRETCH_VER;
+#else
+ int sw = src->height();
+ int sh = src->width();
+#endif
+ int h = buffer.height();
+ int w = buffer.width();
+
+ if(col1 > col2)
+ {
+ int c = col2;
+ col2 = col1;
+ col1 = c;
+ }
+
+ col1 = (col1 >= 0) ? col1 : 0;
+ col2 = (col2 >= 0) ? col2 : w-1;
+ col1 = qMin(col1, w-1);
+ col2 = qMin(col2, w-1);
+
+ int distance = h * 100 / zoom;
+ PFreal sdx = fcos(slide.angle);
+ PFreal sdy = fsin(slide.angle);
+ PFreal xs = slide.cx - slideWidth * sdx/2;
+ PFreal ys = slide.cy - slideWidth * sdy/2;
+ PFreal dist = distance * PFREAL_ONE;
+
+ int xi = qMax((PFreal)0, ((w*PFREAL_ONE/2) + fdiv(xs*h, dist+ys)) >> PFREAL_SHIFT);
+ if(xi >= w)
+ return rect;
+
+ bool flag = false;
+ rect.setLeft(xi);
+
+ for(int x = qMax(xi, col1); x <= col2; x++)
+ {
+ PFreal hity = 0;
+ PFreal fk = rays[x];
+ if(sdy)
+ {
+ fk = fk - fdiv(sdx,sdy);
+ hity = -fdiv((rays[x]*distance - slide.cx + slide.cy*sdx/sdy), fk);
+ }
+
+ dist = distance*PFREAL_ONE + hity;
+ if(dist < 0)
+ continue;
+
+ PFreal hitx = fmul(dist, rays[x]);
+ PFreal hitdist = fdiv(hitx - slide.cx, sdx);
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int column = sw*BILINEAR_STRETCH_HOR/2 + (hitdist*BILINEAR_STRETCH_HOR >> PFREAL_SHIFT);
+ if(column >= sw*BILINEAR_STRETCH_HOR)
+ break;
+#else
+ int column = sw/2 + (hitdist >> PFREAL_SHIFT);
+ if(column >= sw)
+ break;
+#endif
+ if(column < 0)
+ continue;
+
+ rect.setRight(x);
+ if(!flag)
+ rect.setLeft(x);
+ flag = true;
+
+ int y1 = h/2;
+ int y2 = y1+ 1;
+ QRgb* pixel1 = (QRgb*)(buffer.scanLine(y1)) + x;
+ QRgb* pixel2 = (QRgb*)(buffer.scanLine(y2)) + x;
+ QRgb pixelstep = pixel2 - pixel1;
+
+#ifdef PICTUREFLOW_BILINEAR_FILTER
+ int center = (sh*BILINEAR_STRETCH_VER/2);
+ int dy = dist*BILINEAR_STRETCH_VER / h;
+#else
+ int center = (sh/2);
+ int dy = dist / h;
+#endif
+ int p1 = center*PFREAL_ONE - dy/2;
+ int p2 = center*PFREAL_ONE + dy/2;
+
+ const QRgb *ptr = (const QRgb*)(src->scanLine(column));
+ if(alpha == 256)
+ while((y1 >= 0) && (y2 < h) && (p1 >= 0))
+ {
+ *pixel1 = ptr[p1 >> PFREAL_SHIFT];
+ *pixel2 = ptr[p2 >> PFREAL_SHIFT];
+ p1 -= dy;
+ p2 += dy;
+ y1--;
+ y2++;
+ pixel1 -= pixelstep;
+ pixel2 += pixelstep;
+ }
+ else
+ while((y1 >= 0) && (y2 < h) && (p1 >= 0))
+ {
+ QRgb c1 = ptr[p1 >> PFREAL_SHIFT];
+ QRgb c2 = ptr[p2 >> PFREAL_SHIFT];
+
+ int r1 = qRed(c1) * alpha/256;
+ int g1 = qGreen(c1) * alpha/256;
+ int b1 = qBlue(c1) * alpha/256;
+ int r2 = qRed(c2) * alpha/256;
+ int g2 = qGreen(c2) * alpha/256;
+ int b2 = qBlue(c2) * alpha/256;
+
+ *pixel1 = qRgb(r1, g1, b1);
+ *pixel2 = qRgb(r2, g2, b2);
+ p1 -= dy;
+ p2 += dy;
+ y1--;
+ y2++;
+ pixel1 -= pixelstep;
+ pixel2 += pixelstep;
+ }
+ }
+
+ rect.setTop(0);
+ rect.setBottom(h-1);
+ return rect;
+}
+
+// Updates look-up table and other stuff necessary for the rendering.
+// Call this when the viewport size or slide dimension is changed.
+void PictureFlowPrivate::recalc(int ww, int wh)
+{
+ int w = (ww+1)/2;
+ int h = (wh+1)/2;
+ buffer = QImage(ww, wh, QImage::Format_RGB32);
+ buffer.fill(0);
+
+ rays.resize(w*2);
+
+ for(int i = 0; i < w; ++i)
+ {
+ PFreal gg = (PFREAL_HALF + i * PFREAL_ONE) / (2*h);
+ rays[w-i-1] = -gg;
+ rays[w+i] = gg;
+ }
+
+
+ itilt = 70 * IANGLE_MAX / 360; // approx. 70 degrees tilted
+
+ offsetX = slideWidth/2 * (PFREAL_ONE-fcos(itilt));
+ offsetY = slideWidth/2 * fsin(itilt);
+ offsetX += slideWidth * PFREAL_ONE;
+ offsetY += slideWidth * PFREAL_ONE / 4;
+ spacing = 40;
+
+ surfaceCache.clear();
+ blankSurface = QImage();
+}
+
+void PictureFlowPrivate::startAnimation()
+{
+#if 1
+ if(!animateTimer.isActive())
+ {
+ step = (target < centerSlide.slideIndex) ? -1 : 1;
+ animateTimer.start(30, widget);
+ }
+#else
+ if (animateTimer.isActive())
+ animateTimer.stop();
+
+ step = (target < centerSlide.slideIndex) ? -1 : 1;
+ animateTimer.start(30, widget);
+#endif
+}
+
+// Updates the animation effect. Call this periodically from a timer.
+void PictureFlowPrivate::updateAnimation()
+{
+ if(!animateTimer.isActive())
+ return;
+ if(step == 0)
+ return;
+
+ int speed = 16384;
+
+ // deaccelerate when approaching the target
+ if(true)
+ {
+ const int max = 2 * 65536;
+
+ int fi = slideFrame;
+ fi -= (target << 16);
+ if(fi < 0)
+ fi = -fi;
+ fi = qMin(fi, max);
+
+ int ia = IANGLE_MAX * (fi-max/2) / (max*2);
+ speed = 512 + 16384 * (PFREAL_ONE+fsin(ia))/PFREAL_ONE;
+ }
+
+ slideFrame += speed*step;
+
+ int index = slideFrame >> 16;
+ int pos = slideFrame & 0xffff;
+ int neg = 65536 - pos;
+ int tick = (step < 0) ? neg : pos;
+ PFreal ftick = (tick * PFREAL_ONE) >> 16;
+
+ // the leftmost and rightmost slide must fade away
+ fade = pos / 256;
+
+ if(step < 0)
+ index++;
+ if(centerIndex != index)
+ {
+ centerIndex = index;
+ slideFrame = index << 16;
+ centerSlide.slideIndex = centerIndex;
+ for(int i = 0; i < leftSlides.count(); ++i)
+ leftSlides[i].slideIndex = centerIndex-1-i;
+ for(int i = 0; i < rightSlides.count(); ++i)
+ rightSlides[i].slideIndex = centerIndex+1+i;
+ }
+
+ centerSlide.angle = (step * tick * itilt) >> 16;
+ centerSlide.cx = -step * fmul(offsetX, ftick);
+ centerSlide.cy = fmul(offsetY, ftick);
+
+ if(centerIndex == target)
+ {
+ resetSlides();
+ animateTimer.stop();
+ triggerRender();
+ step = 0;
+ fade = 256;
+ return;
+ }
+
+ for(int i = 0; i < leftSlides.count(); ++i)
+ {
+ SlideInfo& si = leftSlides[i];
+ si.angle = itilt;
+ si.cx = -(offsetX + spacing*i*PFREAL_ONE + step*spacing*ftick);
+ si.cy = offsetY;
+ }
+
+ for(int i = 0; i < rightSlides.count(); ++i)
+ {
+ SlideInfo& si = rightSlides[i];
+ si.angle = -itilt;
+ si.cx = offsetX + spacing*i*PFREAL_ONE - step*spacing*ftick;
+ si.cy = offsetY;
+ }
+
+ if(step > 0)
+ {
+ PFreal ftick = (neg * PFREAL_ONE) >> 16;
+ rightSlides[0].angle = -(neg * itilt) >> 16;
+ rightSlides[0].cx = fmul(offsetX, ftick);
+ rightSlides[0].cy = fmul(offsetY, ftick);
+ }
+ else
+ {
+ PFreal ftick = (pos * PFREAL_ONE) >> 16;
+ leftSlides[0].angle = (pos * itilt) >> 16;
+ leftSlides[0].cx = -fmul(offsetX, ftick);
+ leftSlides[0].cy = fmul(offsetY, ftick);
+ }
+
+ // must change direction ?
+ if(target < index) if(step > 0)
+ step = -1;
+ if(target > index) if(step < 0)
+ step = 1;
+
+ triggerRender();
+}
+
+// -----------------------------------------
+
+PictureFlow::PictureFlow(QWidget* parent): QWidget(parent)
+{
+ d = new PictureFlowPrivate(this);
+
+ setAttribute(Qt::WA_StaticContents, true);
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+}
+
+PictureFlow::~PictureFlow()
+{
+ delete d;
+}
+
+int PictureFlow::slideCount() const
+{
+ return d->slideCount();
+}
+
+void PictureFlow::setSlideCount(int count)
+{
+ d->setSlideCount(count);
+}
+
+QSize PictureFlow::slideSize() const
+{
+ return d->slideSize();
+}
+
+void PictureFlow::setSlideSize(QSize size)
+{
+ d->setSlideSize(size);
+}
+
+int PictureFlow::zoomFactor() const
+{
+ return d->zoomFactor();
+}
+
+void PictureFlow::setZoomFactor(int z)
+{
+ d->setZoomFactor(z);
+}
+
+QImage PictureFlow::slide(int index) const
+{
+ return d->slide(index);
+}
+
+void PictureFlow::setSlide(int index, const QImage& image)
+{
+ d->setSlide(index, image);
+}
+
+void PictureFlow::setSlide(int index, const QPixmap& pixmap)
+{
+ d->setSlide(index, pixmap.toImage());
+}
+
+int PictureFlow::currentSlide() const
+{
+ return d->currentSlide();
+}
+
+void PictureFlow::setCurrentSlide(int index)
+{
+ d->setCurrentSlide(index);
+}
+
+void PictureFlow::clear()
+{
+ d->setSlideCount(0);
+}
+
+void PictureFlow::render()
+{
+ d->render();
+ update();
+}
+
+void PictureFlow::showPrevious()
+{
+ d->showPrevious();
+}
+
+void PictureFlow::showNext()
+{
+ d->showNext();
+}
+
+void PictureFlow::showSlide(int index)
+{
+ d->showSlide(index);
+}
+
+void PictureFlow::showSlideAt (int x, int y) {
+ if (d->slidesRect[5].contains(x, y))
+ return;
+
+ if (x < d->slidesRect[5].x()) {
+ for (int i=0; i < 5; ++i) {
+ if (d->slidesRect[i].contains(x, y)) {
+ showSlide(d->currentSlide() - (i + 1));
+ return;
+ }
+ }
+ } else {
+ for (int i=6; i < 11; ++i) {
+ if (d->slidesRect[i].contains(x, y)) {
+ showSlide(d->currentSlide() + (i - 5));
+ return;
+ }
+ }
+ }
+}
+
+void PictureFlow::keyPressEvent(QKeyEvent* event)
+{
+
+ switch (event->key()) {
+ case Qt::Key_Left:
+ if(event->modifiers() == Qt::AltModifier) {
+ showSlide(currentSlide() - 5);
+ } else {
+ showPrevious();
+ }
+ event->accept();
+ return;
+ case Qt::Key_Right:
+ if(event->modifiers() == Qt::AltModifier) {
+ showSlide(currentSlide() + 5);
+ } else {
+ showNext();
+ }
+ event->accept();
+ return;
+ case Qt::Key_Up:
+ showSlide(currentSlide() + 10);
+ event->accept();
+ return;
+ case Qt::Key_Down:
+ showSlide(currentSlide() - 10);
+ event->accept();
+ return;
+ default:
+ break;
+ }
+
+ event->ignore();
+}
+
+void PictureFlow::mouseReleaseEvent (QMouseEvent *event) {
+ showSlideAt(event->x(), event->y());
+}
+
+void PictureFlow::mouseMoveEvent (QMouseEvent *event) {
+ showSlideAt(event->x(), event->y());
+}
+
+void PictureFlow::wheelEvent (QWheelEvent *event) {
+ int numDegrees = event->delta() / 8;
+ int numSteps = numDegrees / 15;
+
+ d->showSlide(d->currentSlide() + numSteps);
+ event->accept();
+}
+
+void PictureFlow::paintEvent(QPaintEvent* event)
+{
+ Q_UNUSED(event);
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ painter.drawImage(QPoint(0,0), d->buffer);
+}
+
+void PictureFlow::resizeEvent(QResizeEvent* event)
+{
+ d->resize(width(), height());
+ QWidget::resizeEvent(event);
+}
+
+void PictureFlow::timerEvent(QTimerEvent* event)
+{
+ if(event->timerId() == d->animateTimer.timerId())
+ d->updateAnimation();
+ else
+ QWidget::timerEvent(event);
+}
+
+} // namespace FQTerm
+
+#include "pictureflow.moc"
diff --git a/src/ui/pictureflow.h b/src/ui/pictureflow.h
new file mode 100644
index 0000000..c9cf5aa
--- /dev/null
+++ b/src/ui/pictureflow.h
@@ -0,0 +1,198 @@
+
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+/*
+ PictureFlow - animated image show widget
+ http://pictureflow.googlecode.com
+
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef PICTUREFLOW_H
+#define PICTUREFLOW_H
+
+#include <QWidget>
+
+namespace FQTerm {
+
+class PictureFlowPrivate;
+
+/*!
+ Class PictureFlow implements an image show widget with animation effect
+ like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form
+ of slides, one main slide is shown at the center with few slides on
+ the left and right sides of the center slide. When the next or previous
+ slide is brought to the front, the whole slides flow to the right or
+ the right with smooth animation effect; until the new slide is finally
+ placed at the center.
+
+ */
+class PictureFlow : public QWidget
+{
+Q_OBJECT
+
+ Q_PROPERTY(int slideCount READ slideCount WRITE setSlideCount)
+ Q_PROPERTY(int currentSlide READ currentSlide WRITE setCurrentSlide)
+ Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize)
+ Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)
+
+public:
+ /*!
+ Creates a new PictureFlow widget.
+ */
+ PictureFlow(QWidget* parent = 0);
+
+ /*!
+ Destroys the widget.
+ */
+ ~PictureFlow();
+
+ /*!
+ Returns the total number of slides.
+ */
+ int slideCount() const;
+
+ /*!
+ Sets the total number of slides.
+ */
+ void setSlideCount(int count);
+
+ /*!
+ Returns the dimension of each slide (in pixels).
+ */
+ QSize slideSize() const;
+
+ /*!
+ Sets the dimension of each slide (in pixels).
+ */
+ void setSlideSize(QSize size);
+
+ /*!
+ Sets the zoom factor (in percent).
+ */
+ void setZoomFactor(int zoom);
+
+ /*!
+ Returns the zoom factor (in percent).
+ */
+ int zoomFactor() const;
+
+ /*!
+ Returns QImage of specified slide.
+ This function will be called only whenever necessary, e.g. the 100th slide
+ will not be retrived when only the first few slides are visible.
+ */
+ virtual QImage slide(int index) const;
+
+ /*!
+ Sets an image for specified slide. If the slide already exists,
+ it will be replaced.
+ */
+ virtual void setSlide(int index, const QImage& image);
+
+ /*!
+ Sets a pixmap for specified slide. If the slide already exists,
+ it will be replaced.
+ */
+ virtual void setSlide(int index, const QPixmap& pixmap);
+
+ /*!
+ Returns the index of slide currently shown in the middle of the viewport.
+ */
+ int currentSlide() const;
+
+signals:
+ void slideSelected (int index);
+
+public slots:
+
+ /*!
+ Sets slide to be shown in the middle of the viewport. No animation
+ effect will be produced, unlike using showSlide.
+ */
+ void setCurrentSlide(int index);
+
+ /*!
+ Clears images of all slides.
+ */
+ void clear();
+
+ /*!
+ Rerender the widget. Normally this function will be automatically invoked
+ whenever necessary, e.g. during the transition animation.
+ */
+ void render();
+
+ /*!
+ Shows previous slide using animation effect.
+ */
+ void showPrevious();
+
+ /*!
+ Shows next slide using animation effect.
+ */
+ void showNext();
+
+ /*!
+ Go to specified slide using animation effect.
+ */
+ void showSlide(int index);
+
+
+ /*!
+ Go to slide at specified position using animation effect.
+ */
+ void showSlideAt(int x, int y);
+
+protected:
+ void mouseReleaseEvent (QMouseEvent *event);
+ void mouseMoveEvent (QMouseEvent *event);
+ void wheelEvent (QWheelEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void timerEvent(QTimerEvent *event);
+
+private:
+ PictureFlowPrivate* d;
+};
+
+} // namespace FQTerm
+
+#endif // PICTUREFLOW_H
diff --git a/src/ui/popupMessage.cpp b/src/ui/popupMessage.cpp
new file mode 100644
index 0000000..6b89b38
--- /dev/null
+++ b/src/ui/popupMessage.cpp
@@ -0,0 +1,316 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QVBoxLayout>
+#include <QPixmap>
+#include <QHBoxLayout>
+#include <QTimerEvent>
+#include <QLabel>
+#include <QMessageBox>
+#include <QTimer>
+#include <QFont>
+#include <QPushButton>
+#include <QPainter>
+
+#include "popupMessage.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+PopupMessage::PopupMessage(QWidget *parent_, QWidget *anchor, int timeout)
+ : OverlayWidget(parent_, anchor),
+ anchor_(anchor),
+ parent_(parent_),
+ maskEffect_(Slide),
+ dissolveSize_(0),
+ dissolveDelta_(-1),
+ offset_(0),
+ counter_(0),
+ stage_(1),
+ timeout_(timeout),
+ isCounterShown_(true) {
+ setFrameStyle(QFrame::Panel | QFrame::Raised);
+ setFrameShape(QFrame::StyledPanel);
+ // overrideWindowFlags( Qt::WX11BypassWM );
+
+ QHBoxLayout *hbox;
+ QLabel *label;
+ QLabel *alabel;
+ //KActiveLabel *alabel;
+
+ layout_ = new QVBoxLayout(this); //, 9 /*margin*/, 6 /*spacing*/ );
+ layout_->setMargin(9);
+ layout_->setSpacing(6);
+
+ hbox = new QHBoxLayout; //( layout_, 12 );
+ hbox->setMargin(12);
+
+ layout_->addLayout(hbox);
+
+ hbox->addWidget(countDownFrame_ = new QFrame(this)); //, "counterVisual" ) );
+ countDownFrame_->setObjectName("counterVisual");
+ countDownFrame_->setFixedWidth(fontMetrics().width("X"));
+ countDownFrame_->setFrameStyle(QFrame::Plain | QFrame::Box);
+ QPalette tmp_palette;
+ tmp_palette.setColor(countDownFrame_->foregroundRole(), palette().color
+ (QPalette::Window).dark());
+ countDownFrame_->setPalette(tmp_palette);
+ // m_countdownFrame->setPaletteForegroundColor( paletteBackgroundColor().dark() );
+
+ label = new QLabel(this); //, "image" );
+ label->setObjectName("image");
+ hbox->addWidget(label);
+ label->hide();
+
+ alabel = new QLabel("Details of the tasks: ", this); //, "label");
+ alabel->setObjectName("label");
+ //alabel = new KActiveLabel( this, "label" );
+ //alabel->setTextFormat( Qt::RichText );
+ alabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+
+ hbox->addWidget(alabel);
+
+ hbox = new QHBoxLayout;
+
+ layout_->addLayout(hbox);
+
+ hbox->addItem(new QSpacerItem(4, 4, QSizePolicy::Expanding,
+ QSizePolicy::Preferred));
+ //FIXME: add icon
+ QPushButton *tmp_button = new QPushButton("Close", this);
+ tmp_button->setObjectName("closeButton");
+ hbox->addWidget(tmp_button); //, "closeButton" ) );
+
+ FQ_VERIFY(connect(findChild < QPushButton * > ("closeButton"), SIGNAL(clicked()),
+ SLOT(close())));
+}
+
+void PopupMessage::addWidget(QWidget *widget) {
+ layout_->addWidget(widget);
+ adjustSize();
+}
+
+void PopupMessage::showCloseButton(const bool show) {
+ findChild < QPushButton * > ("closeButton")->setShown(show);
+ adjustSize();
+}
+
+void PopupMessage::showCounter(const bool show) {
+ isCounterShown_ = show;
+ findChild < QFrame * > ("counterVisual")->setShown(show);
+ adjustSize();
+}
+
+void PopupMessage::setText(const QString &text) {
+ findChild < QLabel * > ("label")->setText(text);
+ adjustSize();
+}
+
+void PopupMessage::setImage(const QString &location_) {
+ findChild < QLabel * > ("image")->setPixmap(QPixmap(location_));
+ adjustSize();
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Public Slots
+////////////////////////////////////////////////////////////////////////
+
+void PopupMessage::close() { //SLOT
+ stage_ = 3;
+ killTimer(timerId_);
+ timerId_ = startTimer(6);
+}
+
+void PopupMessage::display() { //SLOT
+ dissolveSize_ = 24;
+ dissolveDelta_ = -1;
+
+ if (maskEffect_ == Dissolve) {
+ // necessary to create the mask
+ maskBitmap_ = QBitmap(width(), height());
+ // make the mask empty and hence will not show widget with show() called below
+ dissolveMask();
+ timerId_ = startTimer(1000 / 30);
+ } else {
+ timerId_ = startTimer(6);
+ }
+ show();
+}
+
+////////////////////////////////////////////////////////////////////////
+// Protected
+////////////////////////////////////////////////////////////////////////
+
+void PopupMessage::timerEvent(QTimerEvent*) {
+ switch (maskEffect_) {
+ case Plain:
+ plainMask();
+ break;
+
+ case Slide:
+ slideMask();
+ break;
+
+ case Dissolve:
+ dissolveMask();
+ break;
+ }
+}
+
+void PopupMessage::countDown() {
+ if (!timeout_) {
+ killTimer(timerId_);
+ return ;
+ }
+
+ QFrame * &h = countDownFrame_;
+
+ if (counter_ < h->height() - 3) {
+ QPainter(h).fillRect(2, 2, h->width() - 4, counter_, palette().color
+ (QPalette::Active, QPalette::Highlight));
+ }
+
+ if (!testAttribute(Qt::WA_UnderMouse)) {
+ counter_++;
+ }
+
+ if (counter_ > h->height()) {
+ stage_ = 3;
+ killTimer(timerId_);
+ timerId_ = startTimer(6);
+ } else {
+ killTimer(timerId_);
+ timerId_ = startTimer(timeout_ / h->height());
+ }
+}
+
+void PopupMessage::dissolveMask() {
+ if (stage_ == 1) {
+ //repaint( false );
+ QPainter maskPainter(&maskBitmap_);
+
+ maskBitmap_.fill(Qt::black);
+
+ maskPainter.setBrush(Qt::white);
+ maskPainter.setPen(Qt::white);
+ maskPainter.drawRect(maskBitmap_.rect());
+
+ dissolveSize_ += dissolveDelta_;
+
+ if (dissolveSize_ > 0) {
+ //maskPainter.setCompositionMode( Qt::EraseROP );
+ //FIXME: QRubberBand
+
+ int x, y, s;
+ const int size = 16;
+
+ for (y = 0; y < height() + size; y += size) {
+ x = width();
+ s = dissolveSize_ * x / 128;
+
+ for (; x > size; x -= size, s -= 2) {
+ if (s < 0) {
+ break;
+ }
+
+ maskPainter.drawEllipse(x - s / 2, y - s / 2, s, s);
+ }
+ }
+ } else if (dissolveSize_ < 0) {
+ dissolveDelta_ = 1;
+ killTimer(timerId_);
+
+ if (timeout_) {
+ timerId_ = startTimer(40);
+ stage_ = 2;
+ }
+ }
+
+ setMask(maskBitmap_);
+ } else if (stage_ == 2) {
+ countDown();
+ } else {
+ deleteLater();
+ }
+}
+
+
+void PopupMessage::plainMask() {
+ switch (stage_) {
+ case 1:
+ // Raise
+ killTimer(timerId_);
+ if (timeout_) {
+ timerId_ = startTimer(40);
+ stage_ = 2;
+ }
+
+ break;
+
+ case 2:
+ // Counter
+ countDown();
+ break;
+
+ case 3:
+ // Lower/Remove
+ deleteLater();
+ }
+}
+
+
+void PopupMessage::slideMask() {
+ switch (stage_) {
+ case 1:
+ //raise
+ move(0, parent_->y() - offset_);
+
+ offset_++;
+ if (offset_ > height()) {
+ killTimer(timerId_);
+
+ if (timeout_) {
+ timerId_ = startTimer(40);
+ stage_ = 2;
+ }
+ }
+
+ break;
+
+ case 2:
+ //fill in pause timer bar
+ countDown();
+ break;
+
+ case 3:
+ //lower
+ offset_--;
+ move(0, parent_->y() - offset_);
+
+ if (offset_ < 0) {
+ deleteLater();
+ }
+ }
+}
+
+} // namespace FQTerm
+
+#include "popupMessage.moc"
diff --git a/src/ui/popupMessage.h b/src/ui/popupMessage.h
new file mode 100644
index 0000000..1877b1c
--- /dev/null
+++ b/src/ui/popupMessage.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+//WARNING this is not meant for use outside this unit!
+
+
+#ifndef FQTERM_POPUP_MESSAGE_H
+#define FQTERM_POPUP_MESSAGE_H
+
+#include "overlayWidget.h"
+
+// #include <qbitmap.h>
+// #include <qlayout.h>
+// #include <qpixmap.h>
+//Added by qt3to4:
+#include <QVBoxLayout>
+#include <QTimerEvent>
+#include <QFrame>
+#include <QBitmap>
+#include <QPixmap>
+
+namespace FQTerm {
+/**
+ * @class PopupMessage
+ * @short Widget that animates itself into a position relative to an anchor widget
+ */
+class PopupMessage: public OverlayWidget {
+ Q_OBJECT;
+ public:
+ /**
+ * @param anchor : which widget to tie the popup widget to.
+ * @param timeout : how long to wait before auto closing. A value of 0 means close
+ * only on pressing the closeButton or close() is called.
+ */
+ PopupMessage(QWidget *parent_, QWidget *anchor, int timeout = 5000
+ /*milliseconds*/);
+
+ enum MaskEffect {
+ Plain, Slide, Dissolve
+ };
+
+ void addWidget(QWidget *widget);
+ void showCloseButton(const bool show);
+ void showCounter(const bool show);
+ void setImage(const QString &location_);
+ void setMaskEffect(const MaskEffect type) {
+ maskEffect_ = type;
+ }
+ void setText(const QString &text);
+ void setTimeout(const int time) {
+ timeout_ = time;
+ }
+
+ public slots:
+ void close();
+ void display();
+
+ protected:
+ void timerEvent(QTimerEvent*);
+ void countDown();
+
+ /**
+ * @short Gradually show widget by dissolving from background
+ */
+ void dissolveMask();
+
+ /**
+ * @short instantly display widget
+ */
+ void plainMask();
+
+ /**
+ * @short animation to slide the widget into view
+ */
+ void slideMask();
+
+ private:
+ QVBoxLayout *layout_;
+ QFrame *countDownFrame_;
+ QWidget *anchor_;
+ QWidget *parent_;
+ QBitmap maskBitmap_;
+ MaskEffect maskEffect_;
+
+ int dissolveSize_;
+ int dissolveDelta_;
+
+ int offset_;
+ int counter_;
+ int stage_;
+ int timeout_;
+ int timerId_;
+
+ bool isCounterShown_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_POPUP_MESSAGE_H
diff --git a/src/ui/popwidget.cpp b/src/ui/popwidget.cpp
new file mode 100644
index 0000000..1c702ed
--- /dev/null
+++ b/src/ui/popwidget.cpp
@@ -0,0 +1,177 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "popwidget.h"
+
+#include <QPixmap>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QTimer>
+#include <QLabel>
+
+#include <QMouseEvent>
+#include <QPalette>
+
+namespace FQTerm {
+
+extern QString pathLib;
+
+popWidget::popWidget(FQTermWindow *win, QWidget *parent_, const char *name,
+ Qt::WFlags f)
+ : QWidget(parent_, f) {
+ // QPixmap pxm(QPixmap(pathLib+"pic/popwidget.png") );
+ // if(!pxm.isNull())
+ // {
+ // resize(pxm.width(), pxm.height());
+ // QPalette palette;
+ // palette.setBrush(backgroundRole(), QBrush(pxm));
+ // setPalette(palette);
+ // //setBackgroundPixmap(pxm);
+ // }
+ // else
+ // {
+ // resize(200, 120);
+ // }
+ //
+ // label_ = new QLabel(this);
+ // label_->setGeometry( QRect( 5, height()/3, width()-10, height()*2/3 ) );
+ // label_->setAlignment( Qt::AlignTop );
+ // label_->setWordWrap(true);
+ // if(!pxm.isNull()){
+ // QPalette palette;
+ // palette.setBrush(label_->backgroundRole(), QBrush(pxm));
+ // label_->setPalette(palette);
+ // // label_->setBackgroundPixmap(pxm);
+ // }
+ // else {
+ // QPalette palette;
+ // palette.setColor(label_->backgroundRole(), QColor(249,250,229));
+ // label_->setPalette(palette);
+ // //label_->setBackgroundColor(QColor(249,250,229));
+ // }
+ // //label_->setBackgroundOrigin( ParentOrigin );
+ // label_->setFont(QFont(qApp->font().family(), 12));
+ //
+ // pTimer = new QTimer(this);
+ // QVERIFY(connect(pTimer, SIGNAL(timeout()), this, SLOT(showTimer())));
+ //
+ // stateID = -1;
+ //
+ // stepID_ = 2;
+ //
+ // intervalID_ = 500/(height()/stepID_);
+ //
+ // setFocusPolicy(Qt::NoFocus);
+ //
+ // termWindow_ = win;
+ //
+ // hide();
+ //
+ // Display *dsp = QX11Info::display();
+ // int screen = DefaultScreen(dsp);
+ // Window root = RootWindow(dsp, screen);
+ //
+ // WId winid = this->winId();
+ //
+ // XEvent ev;
+ // memset(&ev, 0, sizeof(ev));
+ //
+ // ev.xclient.type = ClientMessage;
+ // ev.xclient.termWindow_ = winid;
+ // ev.xclient.message_type = XInternAtom (dsp, "_NET_WM_DESKTOP", False );
+ // ev.xclient.format = 32;
+ // ev.xclient.data.l[0] = -1;
+ // ev.xclient.data.l[1] = 0l;
+ // ev.xclient.data.l[2] = 0l;
+ // ev.xclient.data.l[3] = 0l;
+ // ev.xclient.data.l[4] = 0l;
+ //
+ // XSendEvent(dsp, root, False, SubstructureRedirectMask|SubstructureNotifyMask, &ev);
+ // XSync(dsp, False);
+}
+
+popWidget::~popWidget() {
+ // delete pTimer;
+}
+
+void popWidget::mousePressEvent(QMouseEvent *me) {
+ // QWidgetList list = QApplication::topLevelWidgets();
+ //
+ // //((FQTermFrame *)qApp->mainWidget())->popupFocusIn(termWindow_);
+ //
+ // if(stateID==1)
+ // {
+ // stateID = 2;
+ // pTimer->setInterval(intervalID_);
+ // }
+}
+
+
+void popWidget::popup() {
+ // pTimer->start(intervalID_);
+ // stateID = 0;
+ //
+ // desktopRectangle_ = qApp->desktop()->rect();
+ // position_ = QPoint( desktopRectangle_.width()-width()-5, desktopRectangle_.height()-5 );
+ // move(position_);
+ //
+ // if(!isVisible())
+ // show();
+}
+
+void popWidget::setText(const QString &str) {
+ // label_->setText(str);
+}
+
+void popWidget::showTimer() {
+ // switch(stateID)
+ // {
+ // case 0: // popup
+ // if(position_.y()+height()+5>desktopRectangle_.height())
+ // position_.setY( position_.y() - stepID_ );
+ // else
+ // {
+ // stateID = 1;
+ // pTimer->setInterval(5000);
+ // }
+ // break;
+ // case 1: // wait
+ // stateID = 2;
+ // pTimer->setInterval(intervalID_);
+ // break;
+ // case 2: // hiding
+ // if(position_.y()<desktopRectangle_.height())
+ // position_.setY( position_.y() + stepID_ );
+ // else
+ // {
+ // stateID = -1;
+ // pTimer->stop();
+ // }
+ // break;
+ // default:
+ //
+ // break;
+ // }
+ // move(position_);
+}
+
+} // namespace FQTerm
+
+#include "popwidget.moc"
diff --git a/src/ui/popwidget.h b/src/ui/popwidget.h
new file mode 100644
index 0000000..2a02c7d
--- /dev/null
+++ b/src/ui/popwidget.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_POP_WIDGET_H
+#define FQTERM_POP_WIDGET_H
+
+#include <QWidget>
+//Added by qt3to4:
+#include <QMouseEvent>
+#include <QLabel>
+
+class QTimer;
+class QLabel;
+
+namespace FQTerm {
+
+class FQTermWindow;
+
+class popWidget: public QWidget {
+ Q_OBJECT;
+ public:
+ // #if (QT_VERSION>=310)
+ // popWidget(FQTermWindow * win, QWidget *parent = 0, const char *name=0, WFlags f=WStyle_Splash);
+ // #else
+ popWidget(FQTermWindow *win, QWidget *parent_ = 0, const char *name = 0,
+ Qt::WFlags f = Qt::WindowStaysOnTopHint
+ | Qt::X11BypassWindowManagerHint
+ | Qt::Tool);
+ // #endif
+ ~popWidget();
+
+ void popup();
+ void setText(const QString &);
+
+ public slots:
+ void showTimer();
+
+ protected:
+ QTimer *pTimer;
+ int stateID; // -1 hide, 0 popup, 1 wait, 2 hiding
+ QPoint position_;
+ QRect desktopRectangle_;
+ int stepID_;
+ int intervalID_;
+ QLabel *label_;
+ FQTermWindow *termWindow_;
+
+ void mousePressEvent(QMouseEvent*);
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_POP_WIDGET_H
diff --git a/src/ui/prefdialog.cpp b/src/ui/prefdialog.cpp
new file mode 100644
index 0000000..9f01a08
--- /dev/null
+++ b/src/ui/prefdialog.cpp
@@ -0,0 +1,332 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QCloseEvent>
+#include <QComboBox>
+#include <QFileDialog>
+
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "prefdialog.h"
+#include "soundconf.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a prefDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+prefDialog::prefDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ soundButtonGroup_(this),
+ verticalSettingButtonGroup_(this),
+ config_(config){
+ ui_.setupUi(this);
+ fileDialog_ = new FQTermFileDialog(config_);
+ soundButtonGroup_.addButton(ui_.noneRadioButton, 0);
+ soundButtonGroup_.addButton(ui_.beepRadioButton, 1);
+ soundButtonGroup_.addButton(ui_.fileRadioButton, 2);
+ verticalSettingButtonGroup_.addButton(ui_.topRadioButton, 0);
+ verticalSettingButtonGroup_.addButton(ui_.middleRadioButton, 1);
+ verticalSettingButtonGroup_.addButton(ui_.bottomRadioButton, 2);
+
+ connectSlots();
+
+ loadSetting();
+
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+prefDialog::~prefDialog() {
+ // no need to delete child widgets, Qt does it all for us
+ delete fileDialog_;
+}
+
+void prefDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.okPushButton, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.cancelPushButton, SIGNAL(clicked()), this, SLOT(onCancel())));
+ FQ_VERIFY(connect(ui_.selectsoundPushButton, SIGNAL(clicked()), this, SLOT(onSound())));
+ FQ_VERIFY(connect(ui_.choosehttpPushButton, SIGNAL(clicked()), this, SLOT(onHttp())));
+ //FQ_VERIFY(connect(ButtonGroup1 , SIGNAL(clicked(int)), this, SLOT(onBeep(int)) ));
+ FQ_VERIFY(connect(ui_.browsePushButton, SIGNAL(clicked()), this, SLOT(onBrowse())));
+ FQ_VERIFY(connect(ui_.imagePushButton, SIGNAL(clicked()), this, SLOT(onImage())));
+ FQ_VERIFY(connect(ui_.poolPushButton, SIGNAL(clicked()), this, SLOT(onPool())));
+ FQ_VERIFY(connect(ui_.styleSheetPushButton, SIGNAL(clicked()), this, SLOT(onStyleSheet())));
+ FQ_VERIFY(connect(ui_.editorPushButton, SIGNAL(clicked()), this, SLOT(onEditor())));
+}
+
+void prefDialog::loadSetting() {
+
+ QString strTmp;
+
+ strTmp = config_->getItemValue("preference", "displayoffset");
+ ui_.displayOffsetSlider->setSliderPosition(strTmp.toInt());
+
+ strTmp = config_->getItemValue("preference", "xim");
+ ui_.ximComboBox->setCurrentIndex(strTmp.toInt());
+
+ strTmp = config_->getItemValue("preference", "wordwrap");
+ ui_.wordLineEdit3->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "smartww");
+ ui_.smartCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "wheel");
+ ui_.wheelCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "url");
+ ui_.urlCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "logmsg");
+ ui_.saveCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "blinktab");
+ ui_.blinkCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "warn");
+ ui_.warnCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "beep");
+ qobject_cast<QRadioButton *>(soundButtonGroup_.button(strTmp.toInt()))->setChecked(true);
+
+ strTmp = config_->getItemValue("preference", "vsetting");
+ qobject_cast<QRadioButton *>(verticalSettingButtonGroup_.button(strTmp.toInt()))->setChecked(true);
+
+ strTmp = config_->getItemValue("preference", "enq");
+ ui_.enqCheckBox->setChecked(strTmp != "0");
+
+ //ButtonGroup1->find(strTmp.toInt()))->setChecked(true);
+
+ // if(strTmp.toInt()!=2)
+ // {
+ // wavefileLineEdit->setEnabled(false);
+ // selectsoundPushButton->setEnabled(false);
+ // }
+
+ strTmp = config_->getItemValue("preference", "wavefile");
+ ui_.wavefileLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "antialias");
+ ui_.aacheckBox->setChecked(strTmp != "0");
+
+
+ strTmp = config_->getItemValue("preference", "tray");
+ ui_.trayCheckBox->setChecked(strTmp != "0");
+
+ strTmp = config_->getItemValue("preference", "clearpool");
+ ui_.clearCheckBox->setChecked(strTmp == "1");
+
+ strTmp = config_->getItemValue("preference", "pool");
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "pool/";
+ }
+ ui_.poolLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "http");
+ ui_.httpLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "zmodem");
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "zmodem/";
+ }
+ ui_.zmodemLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "image");
+ ui_.imageLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "qssfile");
+ ui_.styleSheetLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "editor");
+ ui_.editorLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "editorarg");
+ ui_.editorArgLineEdit->setText(strTmp);
+
+ strTmp = config_->getItemValue("preference", "asciienhance");
+ ui_.asciiEnhanceCheckBox->setChecked(strTmp == "1");
+}
+
+void prefDialog::saveSetting() {
+
+ QString strTmp;
+
+ strTmp.setNum(ui_.displayOffsetSlider->sliderPosition());
+ config_->setItemValue("preference", "displayoffset", strTmp);
+
+ strTmp.setNum(ui_.ximComboBox->currentIndex());
+ config_->setItemValue("preference", "xim", strTmp);
+
+
+ config_->setItemValue("preference", "wordwrap", ui_.wordLineEdit3->text());
+
+ strTmp.setNum(ui_.smartCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "smartww", strTmp);
+
+ strTmp.setNum(ui_.wheelCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "wheel", strTmp);
+
+ strTmp.setNum(ui_.urlCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "url", strTmp);
+
+ strTmp.setNum(ui_.saveCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "logmsg", strTmp);
+
+ strTmp.setNum(ui_.blinkCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "blinktab", strTmp);
+
+ strTmp.setNum(ui_.warnCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "warn", strTmp);
+
+ strTmp.setNum(ui_.aacheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "antialias", strTmp);
+
+ strTmp.setNum(ui_.trayCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "tray", strTmp);
+
+ strTmp.setNum(ui_.enqCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "enq", strTmp);
+
+ strTmp.setNum(soundButtonGroup_.checkedId());
+ config_->setItemValue("preference", "beep", strTmp);
+
+ strTmp.setNum(verticalSettingButtonGroup_.checkedId());
+ config_->setItemValue("preference", "vsetting", strTmp);
+
+ if (strTmp == "2") {
+ config_->setItemValue("preference", "wavefile", ui_.wavefileLineEdit->text());
+ }
+
+ strTmp.setNum(ui_.clearCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "clearpool", strTmp);
+
+ strTmp.setNum(ui_.asciiEnhanceCheckBox->isChecked() ? 1 : 0);
+ config_->setItemValue("preference", "asciienhance", strTmp);
+
+ strTmp = ui_.poolLineEdit->text();
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "pool/";
+ }
+ config_->setItemValue("preference", "pool", strTmp);
+
+ strTmp = ui_.zmodemLineEdit->text();
+ if (strTmp.isEmpty()) {
+ strTmp = getPath(USER_CONFIG) + "zmodem/";
+ }
+ config_->setItemValue("preference", "zmodem", strTmp);
+ config_->setItemValue("preference", "http", ui_.httpLineEdit->text());
+ config_->setItemValue("preference", "image", ui_.imageLineEdit->text());
+
+ config_->setItemValue("preference", "qssfile", ui_.styleSheetLineEdit->text().trimmed());
+
+ config_->setItemValue("preference", "editor", ui_.editorLineEdit->text());
+ config_->setItemValue("preference", "editorarg", ui_.editorArgLineEdit->text());
+
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void prefDialog::closeEvent(QCloseEvent*) {
+ reject();
+}
+
+void prefDialog::onOK() {
+ saveSetting();
+ done(1);
+}
+
+void prefDialog::onCancel() {
+ done(0);
+}
+
+void prefDialog::onSound() {
+ soundConf soundconf(config_, this);
+ if (soundconf.exec() == 1) {
+ loadSetting();
+ }
+
+}
+
+void prefDialog::onHttp() {
+ QString http = fileDialog_->getOpenName("Choose a WWW browser", "*");
+ if (!http.isEmpty()) {
+ ui_.httpLineEdit->setText(http);
+ }
+
+}
+
+// void prefDialog::onBeep( int id )
+// {
+// if(id==2)
+// {
+// ui.wavefileLineEdit->setEnabled(true);
+// ui.selectsoundPushButton->setEnabled(true);
+// }
+// else if(id==0 || id==1 )
+// {
+// ui.wavefileLineEdit->setEnabled(false);
+// ui.selectsoundPushButton->setEnabled(false);
+// }
+// }
+
+void prefDialog::onBrowse() {
+ QString dir = fileDialog_->getExistingDirectory("Choose a directory", ui_.zmodemLineEdit->text());
+ if (!dir.isEmpty()) {
+ ui_.zmodemLineEdit->setText(dir);
+ }
+}
+
+void prefDialog::onImage() {
+ QString image = fileDialog_->getOpenName("Choose an Image Viewer", "*");
+ if (!image.isEmpty()) {
+ ui_.imageLineEdit->setText(image);
+ }
+}
+
+void prefDialog::onPool() {
+ QString pool = fileDialog_->getExistingDirectory("Choose a directory", ui_.poolLineEdit->text());
+ if (!pool.isEmpty()) {
+ ui_.poolLineEdit->setText(pool);
+ }
+}
+
+void prefDialog::onStyleSheet()
+{
+ QString qssFile = fileDialog_->getOpenName("Choose a QSS File", "Qt Style Sheets (*.qss *.QSS)");
+ if (!qssFile.isEmpty()) {
+ ui_.styleSheetLineEdit->setText(qssFile);
+ }
+}
+
+void prefDialog::onEditor() {
+ QString editor = fileDialog_->getOpenName("Choose a directory", ui_.editorLineEdit->text());
+ if (!editor.isEmpty()) {
+ ui_.editorLineEdit->setText(editor);
+ }
+}
+} // namespace FQTerm
+
+#include "prefdialog.moc"
diff --git a/src/ui/prefdialog.h b/src/ui/prefdialog.h
new file mode 100644
index 0000000..99e58c6
--- /dev/null
+++ b/src/ui/prefdialog.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_PREF_DIALOG_H
+#define FQTERM_PREF_DIALOG_H
+
+#include "ui_prefdialog.h"
+#include "fqterm_filedialog.h"
+
+class QCloseEvnt;
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class prefDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ prefDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~prefDialog();
+
+ protected slots:
+ void onOK();
+ void onCancel();
+ void onSound();
+ void onHttp();
+ // void onBeep(int);
+ void onBrowse();
+ void onImage();
+ void onPool();
+ void onStyleSheet();
+ void onEditor();
+ protected:
+ void closeEvent(QCloseEvent*);
+ void connectSlots();
+ void loadSetting();
+ void saveSetting();
+
+ private:
+ Ui::prefDialog ui_;
+ QButtonGroup soundButtonGroup_;
+ QButtonGroup verticalSettingButtonGroup_;
+ FQTermConfig * config_;
+ FQTermFileDialog *fileDialog_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_PREF_DIALOG_H
diff --git a/src/ui/prefdialog.ui b/src/ui/prefdialog.ui
new file mode 100644
index 0000000..9aaf484
--- /dev/null
+++ b/src/ui/prefdialog.ui
@@ -0,0 +1,644 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>prefDialog</class>
+ <widget class="QDialog" name="prefDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>619</width>
+ <height>584</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Preference</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="3">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1_2">
+ <property name="text">
+ <string>Paste Word-Wrap At</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="wordLineEdit3"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="smartCheckBox">
+ <property name="text">
+ <string>Enable Smart Word-Wrap</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" rowspan="2">
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="wheelCheckBox">
+ <property name="text">
+ <string>Alternative Mouse Wheel Control</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="urlCheckBox">
+ <property name="text">
+ <string>Detect URL When Mouse Move</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="saveCheckBox">
+ <property name="text">
+ <string>Save Message To File</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="blinkCheckBox">
+ <property name="text">
+ <string>Blink Tab When Receive Message</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="warnCheckBox">
+ <property name="text">
+ <string>Warn When Exit Connected</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="aacheckBox">
+ <property name="text">
+ <string>AntiAlias</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="trayCheckBox">
+ <property name="text">
+ <string>Show As Tray When Close</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="clearCheckBox">
+ <property name="text">
+ <string>Clear ZModem And HTTP Directory When Exit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="enqCheckBox">
+ <property name="text">
+ <string>Reply when ENQ received</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="asciiEnhanceCheckBox">
+ <property name="text">
+ <string>ASCII Art Enhance Mode</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1" rowspan="2" colspan="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Sound When Receive Messages</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="noneRadioButton">
+ <property name="text">
+ <string>None</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="beepRadioButton">
+ <property name="text">
+ <string>Beep</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QRadioButton" name="fileRadioButton">
+ <property name="text">
+ <string>Sound File</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLineEdit" name="wavefileLineEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="selectsoundPushButton">
+ <property name="text">
+ <string>Configure</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1">
+ <property name="text">
+ <string>Input Method</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ximComboBox">
+ <item>
+ <property name="text">
+ <string>GBK</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BIG5</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Display Offset</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="displayOffsetSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="verticalDisplayGroupBox">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Vertical Display</string>
+ </property>
+ <widget class="QRadioButton" name="topRadioButton">
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>15</y>
+ <width>84</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Top</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="middleRadioButton">
+ <property name="geometry">
+ <rect>
+ <x>123</x>
+ <y>15</y>
+ <width>84</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Middle</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="bottomRadioButton">
+ <property name="geometry">
+ <rect>
+ <x>234</x>
+ <y>15</y>
+ <width>84</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Bottom</string>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>287</width>
+ <height>28</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>Zmodem Directory</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_3">
+ <property name="text">
+ <string>HTTP Directory</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel9">
+ <property name="text">
+ <string>StyleSheet File</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3">
+ <property name="text">
+ <string>HTTP Browser</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Image Viewer</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_4">
+ <property name="text">
+ <string>Editor &amp; Args</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLineEdit" name="zmodemLineEdit"/>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLineEdit" name="poolLineEdit"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLineEdit" name="styleSheetLineEdit"/>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLineEdit" name="httpLineEdit"/>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QLineEdit" name="imageLineEdit"/>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLineEdit" name="editorLineEdit"/>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLineEdit" name="editorArgLineEdit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QPushButton" name="browsePushButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="poolPushButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="styleSheetPushButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="choosehttpPushButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="imagePushButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="editorPushButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="Line" name="Line1">
+ <property name="frameShape">
+ <enum>QFrame::HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="3">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okPushButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelPushButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>wordLineEdit3</tabstop>
+ <tabstop>smartCheckBox</tabstop>
+ <tabstop>wheelCheckBox</tabstop>
+ <tabstop>urlCheckBox</tabstop>
+ <tabstop>saveCheckBox</tabstop>
+ <tabstop>blinkCheckBox</tabstop>
+ <tabstop>warnCheckBox</tabstop>
+ <tabstop>aacheckBox</tabstop>
+ <tabstop>trayCheckBox</tabstop>
+ <tabstop>clearCheckBox</tabstop>
+ <tabstop>noneRadioButton</tabstop>
+ <tabstop>beepRadioButton</tabstop>
+ <tabstop>fileRadioButton</tabstop>
+ <tabstop>selectsoundPushButton</tabstop>
+ <tabstop>wavefileLineEdit</tabstop>
+ <tabstop>ximComboBox</tabstop>
+ <tabstop>zmodemLineEdit</tabstop>
+ <tabstop>browsePushButton</tabstop>
+ <tabstop>poolLineEdit</tabstop>
+ <tabstop>poolPushButton</tabstop>
+ <tabstop>httpLineEdit</tabstop>
+ <tabstop>choosehttpPushButton</tabstop>
+ <tabstop>imageLineEdit</tabstop>
+ <tabstop>imagePushButton</tabstop>
+ <tabstop>okPushButton</tabstop>
+ <tabstop>cancelPushButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>noneRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>wavefileLineEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>290</x>
+ <y>95</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>290</x>
+ <y>125</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>noneRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>selectsoundPushButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>360</x>
+ <y>80</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>120</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>beepRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>wavefileLineEdit</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>393</x>
+ <y>90</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>366</x>
+ <y>129</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>beepRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>selectsoundPushButton</receiver>
+ <slot>setDisabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>413</x>
+ <y>92</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>449</x>
+ <y>125</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>wavefileLineEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>467</x>
+ <y>97</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>380</x>
+ <y>126</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>selectsoundPushButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>502</x>
+ <y>86</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>493</x>
+ <y>128</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/progressBar.cpp b/src/ui/progressBar.cpp
new file mode 100644
index 0000000..9da0479
--- /dev/null
+++ b/src/ui/progressBar.cpp
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QLabel>
+#include <QPixmap>
+#include <QProgressBar>
+#include <QPushButton>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "progressBar.h"
+
+namespace FQTerm {
+
+ProgressBar::ProgressBar(QWidget *parent, QLabel *label)
+ : QProgressBar(parent),
+ label_(label),
+ isFinished_(false) {
+ //DEBUG_FUNC_INFO
+ setMaximum(100);
+ label_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ abortButton_ = new QPushButton("Abort", parent);
+ abortButton_->setObjectName("Abort");
+ abortButton_->hide();
+ //m_abort->setText( tr("Abort") );
+ abortButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png"));
+ label_->show();
+ show();
+}
+
+ProgressBar::~ProgressBar() {
+ //DEBUG_FUNC_INFO
+}
+
+ProgressBar &ProgressBar::setDescription(const QString &text) {
+ description_ = text;
+ label_->setText(text);
+
+ return *this;
+}
+
+ProgressBar &ProgressBar::setStatus(const QString &text) {
+ QString s = description_;
+ s += " [";
+ s += text;
+ s += ']';
+
+ label_->setText(s);
+ parentWidget()->adjustSize();
+
+ return *this;
+}
+
+ProgressBar &ProgressBar::setAbortSlot(QObject *receiver, const char *slot) {
+ FQ_VERIFY(connect(abortButton_, SIGNAL(clicked()), receiver, slot));
+ FQ_VERIFY(connect(abortButton_, SIGNAL(clicked()), this, SLOT(hide())));
+ abortButton_->show();
+
+ parentWidget()->adjustSize();
+
+ return *this;
+}
+
+void ProgressBar::setDone() {
+ if (!isFinished_) {
+ isFinished_ = true;
+ abortButton_->setEnabled(false);
+ setStatus(tr("Done"));
+ } else {
+ // then we we're aborted
+ setStatus(tr("Aborted"));
+ }
+}
+
+void ProgressBar::hide() {
+ //NOTE naughty
+
+ isFinished_ = true;
+ abortButton_->setEnabled(false);
+ setStatus(tr("Aborting..."));
+}
+
+} // namespace FQTerm
diff --git a/src/ui/progressBar.h b/src/ui/progressBar.h
new file mode 100644
index 0000000..9c2f539
--- /dev/null
+++ b/src/ui/progressBar.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+//WARNING this is not meant for use outside this unit!
+
+#ifndef FQTERM_PROGRESSBAR_H
+#define FQTERM_PROGRESSBAR_H
+
+#include <QProgressBar>
+#include <QLabel>
+
+class QLabel;
+class QPushButton;
+
+namespace FQTerm {
+/**
+ * @class KDE::ProgressBar
+ * @short ProgressBar class with some useful additions
+ */
+class ProgressBar: public QProgressBar {
+ friend class StatusBar;
+
+ public:
+ /** @param text a 1-6 word description of the progress operation */
+ ProgressBar &setDescription(const QString &text);
+
+ /** @param text eg. Scanning, Reading. The state of the operation */
+ ProgressBar &setStatus(const QString &text);
+
+ /** set the recipient slot for the abort button */
+ ProgressBar &setAbortSlot(QObject *receiver, const char *slot);
+
+ void setDone();
+
+ QString description()const {
+ return description_;
+ }
+
+ protected:
+ ProgressBar(QWidget *parent, QLabel *label);
+ ~ProgressBar();
+
+ virtual void hide();
+
+ QLabel *label_;
+ QString description_;
+ bool isFinished_;
+
+ QPushButton *abortButton_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_PROGRESSBAR_H
diff --git a/src/ui/quickdialog.cpp b/src/ui/quickdialog.cpp
new file mode 100644
index 0000000..1ac3888
--- /dev/null
+++ b/src/ui/quickdialog.cpp
@@ -0,0 +1,258 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include <QCloseEvent>
+#include <QComboBox>
+#include <QPixmap>
+#include <QImage>
+#include <QPixmap>
+#include <QMessageBox>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "addrdialog.h"
+#include "quickdialog.h"
+
+namespace FQTerm {
+
+//extern QString fileCfg;
+//extern QString addrCfg;
+
+extern void saveAddress(FQTermConfig *, int, const FQTermParam &);
+
+const int quickDialog::ports[3] = {23, 22, 22};
+
+quickDialog::quickDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ config_(config) {
+ ui_.setupUi(this);
+
+ ui_.addPushButton->setIcon(QPixmap(getPath(RESOURCE) + "pic/address_book.png"));
+
+ ui_.addPushButton->setToolTip(tr("Add To AddressBook"));
+
+ ui_.connectPushButton->setDefault(true);
+
+ connectSlots();
+
+ loadHistory();
+
+// adjustSize();
+// setFixedSize(size());
+
+}
+
+quickDialog::~quickDialog() {
+}
+
+void quickDialog::closeEvent(QCloseEvent*) {
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+ reject();
+}
+
+void quickDialog::loadHistory() {
+ QString defaultIndex = config_->getItemValue("global", "quickdefaultindex");
+ if (defaultIndex.isEmpty()) {
+ config_->setItemValue("global", "quick default index", "0");
+ defaultIndex = "0";
+ }
+ QString strTmp = config_->getItemValue("quick list", "num");
+ QString strSection;
+ for (int i = 0; i < strTmp.toInt(); i++) {
+ strSection = QString("quick %1").arg(i);
+ ui_.historyComboBox->addItem(config_->getItemValue(strSection.toLatin1(), "addr"));
+ }
+
+ int index = defaultIndex.toInt();
+ if (strTmp.toInt() > index) {
+ ui_.historyComboBox->setCurrentIndex(index);
+ listChanged(index);
+ }
+}
+
+void quickDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.historyComboBox, SIGNAL(activated(int)), this, SLOT(listChanged(int))));
+ FQ_VERIFY(connect(ui_.protocolComboBox, SIGNAL(activated(int)), this, SLOT(onSelectProtocol(int))));
+ FQ_VERIFY(connect(ui_.addPushButton, SIGNAL(clicked()), this, SLOT(onAdd())));
+ FQ_VERIFY(connect(ui_.deletePushButton, SIGNAL(clicked()), this, SLOT(onDelete())));
+ FQ_VERIFY(connect(ui_.advPushButton, SIGNAL(clicked()), this, SLOT(onAdvance())));
+ FQ_VERIFY(connect(ui_.connectPushButton, SIGNAL(clicked()), this, SLOT(onConnect())));
+ FQ_VERIFY(connect(ui_.closePushButton, SIGNAL(clicked()), this, SLOT(onClose())));
+}
+
+void quickDialog::listChanged(int index) {
+ QString strTmp = config_->getItemValue("quick list", "num");
+ if (strTmp == "0") {
+ return ;
+ }
+ loadParam(index);
+ setUIFromParam();
+}
+
+void quickDialog::onAdd() {
+ setParamFromUI();
+
+ FQTermConfig *pAddrConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ QString strTmp;
+ strTmp = pAddrConf->getItemValue("bbs list", "num");
+ int num = strTmp.toInt();
+ strTmp.setNum(num + 1);
+ pAddrConf->setItemValue("bbs list", "num", strTmp);
+ saveAddress(pAddrConf, num, param_);
+ pAddrConf->save(getPath(USER_CONFIG) + "address.cfg");
+}
+
+void quickDialog::onDelete() {
+ int index = ui_.historyComboBox->currentIndex();
+
+ QString strTmp = config_->getItemValue("quick list", "num");
+ int num = strTmp.toInt();
+
+ if (num != 0 && index != -1) {
+ QString strSection = QString("quick %1").arg(index);
+ if (!config_->deleteSection(strSection.toLatin1())) {
+ return ;
+ }
+ ui_.historyComboBox->removeItem(index);
+
+ for (int i = index + 1; i < num; i++) {
+ strTmp = QString("quick %1").arg(i);
+ strSection = QString("quick %1").arg(i - 1);
+ config_->renameSection(strTmp.toLatin1(), strSection.toLatin1());
+ }
+
+ strTmp = config_->getItemValue("quick list", "num");
+ strTmp.setNum(qMax(0, strTmp.toInt() - 1));
+ config_->setItemValue("quick list", "num", strTmp.toLatin1());
+
+ // update
+ if (num > 1) {
+ ui_.historyComboBox->setCurrentIndex(qMin(index, num - 2));
+ listChanged(qMin(index, num - 2));
+ }
+ }
+}
+
+void quickDialog::onAdvance() {
+ setParamFromUI();
+
+ addrDialog set(this, param_, addrDialog::APPLY);
+
+ if (set.exec() == 1) {
+ param_ = set.param();
+ setUIFromParam();
+ }
+}
+
+void quickDialog::onConnect() {
+ if (ui_.historyComboBox->currentText().isEmpty() || ui_.portEdit->text().isEmpty()) {
+ QMessageBox mb("FQTerm", "address or port cant be blank", QMessageBox::Warning,
+ QMessageBox::Ok | QMessageBox::Default, 0, 0);
+ mb.exec();
+ return ;
+ }
+
+ setParamFromUI();
+ FQTermParam newParam = param_;
+ loadParam(ui_.historyComboBox->currentIndex());
+
+ QString strTmp = config_->getItemValue("quick list", "num");
+ if (strTmp.isEmpty() || strTmp == "-1") {
+ strTmp = "0";
+ }
+ int num = strTmp.toInt();
+ if (ui_.historyComboBox->currentIndex() == -1 ||
+ newParam.hostAddress_ != param_.hostAddress_ ||
+ newParam.protocolType_ != param_.protocolType_ ||
+ newParam.port_ != param_.port_) {
+ //changed. add new info
+ param_ = newParam;
+ saveParam(num);
+ ui_.historyComboBox->addItem(param_.hostAddress_);
+ ui_.historyComboBox->setCurrentIndex(num);
+ config_->setItemValue("quick list", "num", QString("%1").arg(num + 1));
+ } else {
+ param_ = newParam;
+ }
+
+ config_->setItemValue("global", "quickdefaultindex",
+ QString("%1").arg(ui_.historyComboBox->currentIndex()));
+ done(1);
+}
+
+void quickDialog::onClose() {
+ done(0);
+}
+
+void quickDialog::onSelectProtocol(int index)
+{
+ ui_.portCheck->setChecked(false);
+ ui_.portEdit->setText(QString("%1").arg(ports[index]));
+}
+
+void quickDialog::setUIFromParam()
+{
+ ui_.historyComboBox->setItemText(ui_.historyComboBox->currentIndex(), param_.hostAddress_);
+ ui_.protocolComboBox->setCurrentIndex(param_.protocolType_);
+ ui_.portEdit->setText(QString("%1").arg(param_.port_));
+ if (param_.port_ != ports[param_.protocolType_]) {
+ ui_.portCheck->setChecked(true);
+ }
+ else {
+ ui_.portCheck->setChecked(false);
+ }
+}
+
+void quickDialog::setParamFromUI()
+{
+ param_.name_ = ui_.historyComboBox->currentText();
+ param_.hostAddress_ = ui_.historyComboBox->currentText();
+ param_.protocolType_ = ui_.protocolComboBox->currentIndex();
+ bool ok;
+ param_.port_ = ui_.portEdit->text().toInt(&ok);
+ if (!ok) {
+ param_.port_ = ports[param_.protocolType_];
+ }
+}
+
+void quickDialog::loadParam(int index)
+{
+ param_ = FQTermParam();
+ QString strSection = QString("quick %1").arg(index);
+ param_.name_ = config_->getItemValue(strSection, "addr");
+ param_.hostAddress_ = param_.name_;
+ param_.protocolType_ = config_->getItemValue(strSection, "protocol").toInt();
+ param_.port_ = config_->getItemValue(strSection, "port").toInt();
+}
+
+void quickDialog::saveParam(int index)
+{
+ QString strSection = QString("quick %1").arg(index);
+ config_->setItemValue(strSection, "addr", param_.hostAddress_);
+ config_->setItemValue(strSection, "protocol", QString("%1").arg(param_.protocolType_));
+ config_->setItemValue(strSection, "port", QString("%1").arg(param_.port_));
+}
+} // namespace FQTerm
+
+#include "quickdialog.moc"
diff --git a/src/ui/quickdialog.h b/src/ui/quickdialog.h
new file mode 100644
index 0000000..bbcae89
--- /dev/null
+++ b/src/ui/quickdialog.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_QUICK_DIALOG_H
+#define FQTERM_QUICK_DIALOG_H
+
+#include "fqterm_param.h"
+#include "ui_quickdialog.h"
+//Added by qt3to4:
+//#include <QCloseEvent>
+
+class QCloseEvent;
+class QResizeEvent;
+
+namespace FQTerm {
+
+class FQTermConfig;
+
+class quickDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ quickDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~quickDialog();
+
+ FQTermParam param_;
+
+ static const int ports[3];
+
+ protected slots:
+ void listChanged(int); //
+ void onAdd();
+ void onDelete();
+ void onAdvance();
+ void onConnect(); //
+ void onClose();
+ void onSelectProtocol(int index);
+
+ private:
+
+ void closeEvent(QCloseEvent*); //
+ void connectSlots();
+ void loadHistory(); //
+ void setUIFromParam();
+ void setParamFromUI();
+ void loadParam(int index);
+ void saveParam(int index);
+
+ FQTermConfig *config_;
+
+ private:
+ Ui::quickDialog ui_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_QUICK_DIALOG_H
diff --git a/src/ui/quickdialog.ui b/src/ui/quickdialog.ui
new file mode 100644
index 0000000..867596d
--- /dev/null
+++ b/src/ui/quickdialog.ui
@@ -0,0 +1,211 @@
+<ui version="4.0" >
+ <class>quickDialog</class>
+ <widget class="QDialog" name="quickDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>394</width>
+ <height>117</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Quick Login</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="TextLabel4" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>Host Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="historyComboBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ <property name="insertPolicy" >
+ <enum>QComboBox::NoInsert</enum>
+ </property>
+ <property name="duplicatesEnabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deletePushButton" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addPushButton" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset>
+ <normaloff/>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="advPushButton" >
+ <property name="text" >
+ <string>Advanced</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="connectPushButton" >
+ <property name="text" >
+ <string>Connect</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closePushButton" >
+ <property name="text" >
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="TextLabel6" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Protocol</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="protocolComboBox" >
+ <item>
+ <property name="text" >
+ <string>Telnet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH2</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="portCheck" >
+ <property name="text" >
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="portEdit" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>23</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <tabstops>
+ <tabstop>historyComboBox</tabstop>
+ <tabstop>deletePushButton</tabstop>
+ <tabstop>addPushButton</tabstop>
+ <tabstop>advPushButton</tabstop>
+ <tabstop>connectPushButton</tabstop>
+ <tabstop>closePushButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>portCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>portEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>151</x>
+ <y>54</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>203</x>
+ <y>54</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/schemadialog.cpp b/src/ui/schemadialog.cpp
new file mode 100644
index 0000000..d5a197b
--- /dev/null
+++ b/src/ui/schemadialog.cpp
@@ -0,0 +1,323 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QFileDialog>
+#include <QColorDialog>
+#include <QComboBox>
+#include <QMessageBox>
+
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "schemadialog.h"
+
+namespace FQTerm {
+
+schemaDialog::schemaDialog(QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ buttonGroup_(this) {
+ ui_.setupUi(this);
+ buttonGroup_.addButton(ui_.noneRadioButton, 0);
+ buttonGroup_.addButton(ui_.imageRadioButton, 1);
+
+ lastItemID_ = -1;
+ isModified_ = false;
+
+ ui_.alphaSlider->setMinimum(0);
+ ui_.alphaSlider->setMaximum(100);
+ ui_.alphaSlider->setSingleStep(1);
+ ui_.alphaSlider->setPageStep(10);
+
+ // ui.bgButtonGroup->setRadioButtonExclusive(true);
+ colorButtons[0] = ui_.clr0Button;
+ colorButtons[1] = ui_.clr1Button;
+ colorButtons[2] = ui_.clr2Button;
+ colorButtons[3] = ui_.clr3Button;
+ colorButtons[4] = ui_.clr4Button;
+ colorButtons[5] = ui_.clr5Button;
+ colorButtons[6] = ui_.clr6Button;
+ colorButtons[7] = ui_.clr7Button;
+ colorButtons[8] = ui_.clr8Button;
+ colorButtons[9] = ui_.clr9Button;
+ colorButtons[10] = ui_.clr10Button;
+ colorButtons[11] = ui_.clr11Button;
+ colorButtons[12] = ui_.clr12Button;
+ colorButtons[13] = ui_.clr13Button;
+ colorButtons[14] = ui_.clr14Button;
+ colorButtons[15] = ui_.clr15Button;
+
+ connectSlots();
+ loadList();
+}
+
+
+schemaDialog::~schemaDialog(){}
+
+
+void schemaDialog::connectSlots() {
+ FQ_VERIFY(connect(ui_.saveButton, SIGNAL(clicked()), this, SLOT(saveSchema())));
+ FQ_VERIFY(connect(ui_.removeButton, SIGNAL(clicked()), this, SLOT(removeSchema())));
+ FQ_VERIFY(connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(onOK())));
+ FQ_VERIFY(connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(onCancel())));
+
+ for (int i = 0; i < 16; ++i) {
+ FQ_VERIFY(connect(colorButtons[i], SIGNAL(clicked()), this, SLOT(buttonClicked())));
+ }
+
+ FQ_VERIFY(connect(ui_.nameListWidget, SIGNAL(currentRowChanged(int)),
+ this, SLOT(nameChanged(int))));
+
+
+ FQ_VERIFY(connect(ui_.chooseButton, SIGNAL(clicked()),
+ this, SLOT(chooseImage())));
+
+ FQ_VERIFY(connect(ui_.titleLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(modified(const QString &))));
+ FQ_VERIFY(connect(ui_.imageLineEdit, SIGNAL(textChanged(const QString &)),
+ this, SLOT(modified(const QString &))));
+ FQ_VERIFY(connect(ui_.alphaSlider, SIGNAL(valueChanged(int)),
+ this, SLOT(modified(int))));
+ FQ_VERIFY(connect(ui_.optionComboBox, SIGNAL(activated(int)),
+ this, SLOT(modified(int))));
+ FQ_VERIFY(connect(ui_.coverComboBox, SIGNAL(activated(int)),
+ this, SLOT(modified(int))));
+ FQ_VERIFY(connect(ui_.noneRadioButton, SIGNAL(toggled(bool)),
+ this, SLOT(modified(bool))));
+ FQ_VERIFY(connect(ui_.imageRadioButton, SIGNAL(toggled(bool)),
+ this, SLOT(modified(bool))));
+ FQ_VERIFY(connect(ui_.alphaCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(modified(bool))));
+}
+
+void schemaDialog::loadList() {
+ QFileInfoList lstFile = getSchemaList();
+
+ //if(lstFile != NULL)
+ {
+ foreach(QFileInfo fi, lstFile) {
+ FQTermConfig *pConf = new FQTermConfig(fi.absoluteFilePath());
+ QListWidgetItem* item = new QListWidgetItem(pConf->getItemValue("schema", "title"), ui_.nameListWidget);
+ item->setData(Qt::UserRole, fi.absoluteFilePath());
+ ui_.nameListWidget->addItem(item);
+ delete pConf;
+ }
+ }
+ if (ui_.nameListWidget->count() != 0) {
+ ui_.nameListWidget->setCurrentRow(0);
+ }
+}
+
+void schemaDialog::loadSchema(const QString &strSchemaFile) {
+ FQTermConfig *pConf = new FQTermConfig(strSchemaFile);
+
+ title_ = pConf->getItemValue("schema", "title");
+ //0 -- none 1 -- image
+ int type = pConf->getItemValue("background", "type").toInt();
+ if (type == 0) {
+ ui_.noneRadioButton->setChecked(true);
+ } else if (type == 1) {
+ ui_.imageRadioButton->setChecked(true);
+ }
+ ui_.imageLineEdit->setText(pConf->getItemValue("image", "name"));
+ QString strTmp = pConf->getItemValue("image", "render");
+ ui_.optionComboBox->setCurrentIndex(strTmp.toInt());
+ strTmp = pConf->getItemValue("image", "cover");
+ ui_.coverComboBox->setCurrentIndex(strTmp.toInt());
+ ui_.alphaCheckBox->setChecked(pConf->getItemValue("image", "usealpha").toInt());
+ ui_.alphaSlider->setValue(pConf->getItemValue("image", "alpha").toInt());
+
+ for (int i = 0; i < 16; ++i) {
+ colors[i].setNamedColor(pConf->getItemValue("color", QString("color%1").arg(i)));
+ }
+
+ delete pConf;
+
+ updateView();
+
+}
+
+QFileInfoList schemaDialog::getSchemaList() {
+ QDir dir;
+ dir.setNameFilters(QStringList("*.schema"));
+ dir.setPath(getPath(USER_CONFIG) + "schema");
+ return dir.entryInfoList();
+}
+
+int schemaDialog::saveNumSchema(int n) {
+
+ int saved = n;
+ title_ = ui_.titleLineEdit->text();
+
+ QString schemaFileName = getPath(USER_CONFIG) + "schema/" + title_ + ".schema";
+ QListWidgetItem* item = ui_.nameListWidget->currentItem();
+ // create a new schema if title changed
+ QString test = ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString();
+ if (QFileInfo(schemaFileName) != QFileInfo(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString())) {
+ item = new QListWidgetItem(title_, ui_.nameListWidget);
+ item->setData(Qt::UserRole, schemaFileName);
+ ui_.nameListWidget->addItem(item);
+ saved = ui_.nameListWidget->row(item);
+ }
+
+ FQTermConfig *pConf = new FQTermConfig(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString());
+
+ pConf->setItemValue("schema", "title", title_);
+
+ QString strTmp;
+ //0 -- none 1 -- image
+ int type = 0;
+
+ if (ui_.noneRadioButton->isChecked()) {
+ type = 0;
+ } else if (ui_.imageRadioButton->isChecked()) {
+ type = 1;
+ }
+ strTmp.setNum(type);
+ pConf->setItemValue("background", "type", strTmp);
+
+ pConf->setItemValue("image", "name", ui_.imageLineEdit->text());
+
+
+ strTmp.setNum(ui_.optionComboBox->currentIndex());
+ pConf->setItemValue("image", "render", strTmp);
+
+ strTmp.setNum(ui_.coverComboBox->currentIndex());
+ pConf->setItemValue("image", "cover", strTmp);
+
+ pConf->setItemValue("image", "usealpha", ui_.alphaCheckBox->isChecked() ? "1" : "0");
+
+ strTmp.setNum(ui_.alphaSlider->value());
+ pConf->setItemValue("image", "alpha", strTmp);
+
+
+ for (int i = 0; i < 16; ++i) {
+ pConf->setItemValue("color", QString("color%1").arg(i), colors[i].name());
+ }
+
+ pConf->save(schemaFileName);
+
+ delete pConf;
+
+ clearModified();
+ emit schemaEdited();
+ return saved;
+}
+
+void schemaDialog::updateView() {
+ // title
+ ui_.titleLineEdit->setText(title_);
+ for (int i = 0; i < 16; ++i) {
+ QPalette palette;
+ palette.setColor(QPalette::Button, colors[i]);
+ colorButtons[i]->setPalette(palette);
+ }
+
+ // load from file, nothing changed
+ clearModified();
+}
+
+void schemaDialog::buttonClicked() {
+ QPushButton *button = (QPushButton*)sender();
+ QColor color =
+ QColorDialog::getColor(button->palette().color(button->backgroundRole()));
+ if (color.isValid() == true) {
+ QPalette palette;
+ palette.setColor(QPalette::Button, color);
+ button->setPalette(palette);
+ modified();
+ }
+ for (int i = 0; i < 16; ++i) {
+ if (colorButtons[i] == button) {
+ colors[i] = color;
+ break;
+ }
+ }
+}
+
+void schemaDialog::nameChanged(int item) {
+ if (isModified_) {
+ QMessageBox mb("FQTerm", "Setting changed, do you want to save?",
+ QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape, 0, this);
+ if (mb.exec() == QMessageBox::Yes) {
+ if (lastItemID_ != -1) {
+ saveNumSchema(lastItemID_);
+ }
+ }
+ }
+
+ int n = item; //nameListBox->index(item);
+ lastItemID_ = n;
+
+
+ loadSchema(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString());
+ updateView();
+ ui_.nameListWidget->setCurrentRow(n, QItemSelectionModel::Select);
+}
+
+
+void schemaDialog::chooseImage() {
+ QString img = QFileDialog::getOpenFileName(
+ this, "Choose an image", QDir::currentPath());
+ if (!img.isNull()) {
+ ui_.imageLineEdit->setText(img);
+ isModified_ = true;
+ }
+}
+
+
+
+void schemaDialog::saveSchema() {
+ // get current schema file name
+ int n = ui_.nameListWidget->currentRow();
+ int saved = saveNumSchema(n);
+ lastItemID_ = saved;
+ ui_.nameListWidget->setCurrentRow(saved, QItemSelectionModel::Select);
+}
+
+void schemaDialog::removeSchema() {
+ QFileInfo fi(ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString());
+ if (fi.isWritable()) {
+ QFile::remove(ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString());
+ int n = ui_.nameListWidget->currentRow();
+ delete ui_.nameListWidget->takeItem(n);
+ emit schemaEdited();
+ } else {
+ QMessageBox::warning(this, "Error",
+ "This is a system schema. Permission Denied");
+ }
+}
+
+void schemaDialog::onOK() {
+ saveSchema();
+ done(1);
+}
+
+void schemaDialog::onCancel() {
+ done(0);
+}
+
+
+
+
+} // namespace FQTerm
+
+#include "schemadialog.moc"
diff --git a/src/ui/schemadialog.h b/src/ui/schemadialog.h
new file mode 100644
index 0000000..c2ef977
--- /dev/null
+++ b/src/ui/schemadialog.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SCHEMADIALOG_H
+#define FQTERM_SCHEMADIALOG_H
+
+#include "ui_schemadialog.h"
+#include <QStringList>
+namespace FQTerm {
+
+class schemaDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ schemaDialog(QWidget *parent = 0, Qt::WFlags fl = 0);
+ ~schemaDialog();
+
+ static QFileInfoList getSchemaList();
+ protected:
+ QColor colors[16];
+ QPushButton * colorButtons[16];
+ QString title_;
+ QStringList fileList_;
+
+ bool isModified_;
+ int lastItemID_;
+ private:
+ Ui::schemaDialog ui_;
+ QButtonGroup buttonGroup_;
+
+ protected:
+ void connectSlots();
+
+ void loadList();
+ void loadSchema(const QString &schemaFileName);
+ int saveNumSchema(int n = -1);
+
+ void updateView();
+
+ protected slots:
+ void buttonClicked();
+ void nameChanged(int);
+ void chooseImage();
+
+ void saveSchema();
+ void removeSchema();
+
+ void onOK();
+ void onCancel();
+
+ void modified(const QString&) {modified();}
+ void modified(int) {modified();}
+ void modified(bool) {modified();}
+ void modified() {isModified_ = true;}
+
+ void clearModified() {isModified_ = false;}
+
+signals:
+ void schemaEdited();
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SCHEMADIALOG_H
diff --git a/src/ui/schemadialog.ui b/src/ui/schemadialog.ui
new file mode 100644
index 0000000..0d987bb
--- /dev/null
+++ b/src/ui/schemadialog.ui
@@ -0,0 +1,539 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>schemaDialog</class>
+ <widget class="QDialog" name="schemaDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>612</width>
+ <height>334</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Schema Editor</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Title</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="8">
+ <widget class="QLineEdit" name="titleLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>0-7</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="clr0Button">
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="clr1Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="clr2Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QPushButton" name="clr3Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5">
+ <widget class="QPushButton" name="clr4Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6">
+ <widget class="QPushButton" name="clr5Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="7">
+ <widget class="QPushButton" name="clr6Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="8">
+ <widget class="QPushButton" name="clr7Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="textLabel2">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text">
+ <string>8-15</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="clr8Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="clr9Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QPushButton" name="clr10Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4">
+ <widget class="QPushButton" name="clr11Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="5">
+ <widget class="QPushButton" name="clr12Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="6">
+ <widget class="QPushButton" name="clr13Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="7">
+ <widget class="QPushButton" name="clr14Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="8">
+ <widget class="QPushButton" name="clr15Button">
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="8">
+ <widget class="QListWidget" name="nameListWidget"/>
+ </item>
+ <item row="4" column="1" colspan="8">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QPushButton" name="saveButton">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeButton">
+ <property name="text">
+ <string>Remove </string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Background</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="noneRadioButton">
+ <property name="text">
+ <string>None</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLineEdit" name="imageLineEdit"/>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="chooseButton">
+ <property name="text">
+ <string>Choose</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="imageRadioButton">
+ <property name="text">
+ <string>Image</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="optionComboBox">
+ <item>
+ <property name="text">
+ <string>Tile</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Center</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Scale</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="coverComboBox">
+ <item>
+ <property name="text">
+ <string>Whole</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Padding</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="TextLabel2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Min</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="alphaSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Max</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0">
+ <widget class="QCheckBox" name="alphaCheckBox">
+ <property name="text">
+ <string>Alpha</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Render</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Coverage</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="ForAlignment">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLineEdit" name="ForAlignment_2">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Note:
+ Alpha will only apply on background
+ If Coverage is set to Padding
+ Alpha will take no effect
+</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/shortcutdialog.cpp b/src/ui/shortcutdialog.cpp
new file mode 100644
index 0000000..0b73ab3
--- /dev/null
+++ b/src/ui/shortcutdialog.cpp
@@ -0,0 +1,176 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "shortcutdialog.h"
+#include "fqterm_shortcuthelper.h"
+
+#include <QTableWidget>
+#include <QKeyEvent>
+#include <QGridLayout>
+#include <QPushButton>
+#include <QHeaderView>
+#include <QStringList>
+#include <QScrollBar>
+#include <QLabel>
+#include <QSignalMapper>
+namespace FQTerm
+{
+FQTermShortcutDialog::FQTermShortcutDialog(FQTermShortcutHelper* helper, QWidget *parent_, Qt::WFlags fl)
+ : QDialog(parent_, fl),
+ helper_(helper),
+ table_(NULL) {
+ setWindowTitle(tr("Shortcut Setting"));
+ //grabKeyboard();
+ if (helper_)
+ {
+ QSignalMapper* signalMapper = new QSignalMapper(this);
+ int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1;
+ int column = 3;
+ table_ = new QTableWidget(row, column, this);
+ table_->clear();
+ QStringList header;
+ header << tr("Description") << tr("Shortcut") << "";
+ table_->setHorizontalHeaderLabels(header);
+ for (int i = 0; i < row; ++i) {
+ for (int j = 0; j < column; ++j) {
+ if (j == 0) {
+ QTableWidgetItem* item = new QTableWidgetItem;
+ table_->setItem(i, j, item);
+ item->setFlags(item->flags() & ~Qt::ItemIsEditable);
+ item->setText(helper_->getShortcutDescription(i + 1));
+ } else if (j == 1) {
+ FQTermShortcutTableWidget* stw = new FQTermShortcutTableWidget(table_);
+ stw->setReadOnly(true);
+ stw->setText(helper_->getShortcutText(i + 1));
+ table_->setCellWidget(i, j, stw);
+ }else {
+ QPushButton* btn = new QPushButton(tr("default"), table_);
+ table_->setCellWidget(i, j, btn);
+ FQ_VERIFY(connect(btn, SIGNAL(clicked()), signalMapper, SLOT(map())));
+ signalMapper->setMapping(btn, i);
+ }
+ }
+ }
+ table_->resizeColumnsToContents();
+ int tableWidth = table_->horizontalHeader()->length();
+ if (table_->horizontalScrollBar() && table_->horizontalScrollBar()->isVisible()) {
+ tableWidth += table_->horizontalScrollBar()->width();
+ }
+ QPushButton* okBtn = new QPushButton(tr("OK"), this);
+ FQ_VERIFY(connect(okBtn, SIGNAL(clicked()), this, SLOT(okBtnClicked())));
+ QPushButton* applyBtn = new QPushButton(tr("Apply"), this);
+ FQ_VERIFY(connect(applyBtn, SIGNAL(clicked()), this, SLOT(applyBtnClicked())));
+ QPushButton* cancelBtn = new QPushButton(tr("Cancel"), this);
+ FQ_VERIFY(connect(cancelBtn, SIGNAL(clicked()), this, SLOT(cancelBtnClicked())));
+ QPushButton* resetBtn = new QPushButton(tr("Reset All"), this);
+ FQ_VERIFY(connect(resetBtn, SIGNAL(clicked()), this, SLOT(resetBtnClicked())));
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ QGridLayout* layout = new QGridLayout(this);
+ QLabel* label = new QLabel(tr("Press key/combines on Shortcut column.\nNote Del is reserved for clear shortcut setting."));
+ layout->addWidget(label, 0, 0, 1, -1);
+ layout->addWidget(table_, 1, 0, 1, -1);
+ layout->addWidget(okBtn, 2, 0);
+ layout->addWidget(applyBtn, 2, 1);
+ layout->addWidget(cancelBtn, 2, 2);
+ layout->addWidget(resetBtn, 2, 3);
+ setLayout(layout);
+ int left = 0;
+ int right = 0;
+ layout->getContentsMargins(&left, NULL, &right, NULL);
+ table_->horizontalHeader()->setStretchLastSection(true);
+ tableWidth *= 1.1;
+ resize(tableWidth + left + right, height());
+ FQ_VERIFY(connect(signalMapper, SIGNAL(mapped(int)),this, SLOT(defaultClicked(int))));
+ }
+}
+
+FQTermShortcutDialog::~FQTermShortcutDialog() {
+ //releaseKeyboard();
+}
+
+void FQTermShortcutDialog::defaultClicked(int row) {
+ ((QLineEdit*)table_->cellWidget(row, 1))->setText(helper_->getShortcutDefaultText(row + 1));
+}
+
+void FQTermShortcutDialog::okBtnClicked() {
+ applyChanges();
+ done(true);
+}
+
+void FQTermShortcutDialog::applyBtnClicked() {
+ applyChanges();
+}
+
+void FQTermShortcutDialog::cancelBtnClicked() {
+ done(false);
+}
+
+void FQTermShortcutDialog::resetBtnClicked() {
+ int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1;
+ for (int i = 0; i < row; ++i) {
+ ((QLineEdit*)table_->cellWidget(i, 1))->setText(helper_->getShortcutDefaultText(i + 1));
+ }
+}
+
+void FQTermShortcutDialog::applyChanges() {
+ int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1;
+ for (int i = 0; i < row; ++i) {
+ helper_->setShortcutText(i + 1, ((QLineEdit*)table_->cellWidget(i, 1))->text());
+ }
+}
+
+void FQTermShortcutTableWidget::keyReleaseEvent(QKeyEvent * event) {
+ if (event) {
+ event->accept();
+ }
+}
+
+void FQTermShortcutTableWidget::keyPressEvent(QKeyEvent * event) {
+ if (event) {
+ event->accept();
+ if (event == QKeySequence::Delete) {
+ setText("");
+ } else {
+ //Thank you hooey.
+ int key = event->key();
+ Qt::KeyboardModifiers mod = event->modifiers();
+
+ if (key == Qt::Key_Shift ||
+ key == Qt::Key_Control ||
+ key == Qt::Key_Meta ||
+ key == Qt::Key_Alt ||
+ key == Qt::Key_AltGr)
+ return;
+ QString text = "";
+ if (mod != Qt::NoModifier) {
+ QKeySequence seqMod(mod);
+ text = seqMod.toString(QKeySequence::NativeText);
+ }
+ QKeySequence seqKey(key);
+ text += seqKey.toString(QKeySequence::NativeText);
+ setText(text);
+ }
+ }
+}
+
+}//namespace FQTerm
+
+
+#include "shortcutdialog.moc"
diff --git a/src/ui/shortcutdialog.h b/src/ui/shortcutdialog.h
new file mode 100644
index 0000000..d8fd109
--- /dev/null
+++ b/src/ui/shortcutdialog.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SHORTCUT_DIALOG_H
+#define FQTERM_SHORTCUT_DIALOG_H
+#include <QDialog>
+#include <QLineEdit>
+class QTableWidget;
+namespace FQTerm
+{
+class FQTermShortcutHelper;
+
+class FQTermShortcutTableWidget : public QLineEdit
+{
+public:
+ FQTermShortcutTableWidget(QWidget* parent) : QLineEdit(parent) {
+ }
+protected:
+ void keyReleaseEvent(QKeyEvent * event);
+ void keyPressEvent(QKeyEvent * event);
+};
+
+class FQTermShortcutDialog : public QDialog
+{
+ Q_OBJECT;
+public:
+ FQTermShortcutDialog(FQTermShortcutHelper* helper, QWidget *parent_ = 0, Qt::WFlags fl = Qt::Dialog);
+ ~FQTermShortcutDialog();
+private:
+ FQTermShortcutHelper* helper_;
+ QTableWidget* table_;
+protected slots:
+ void defaultClicked(int row);
+ void okBtnClicked();
+ void applyBtnClicked();
+ void cancelBtnClicked();
+ void resetBtnClicked();
+private:
+ void applyChanges();
+};
+}//namespace FQTerm
+
+
+#endif //FQTERM_SHORTCUT_DIALOG_H
diff --git a/src/ui/sitemanager.cpp b/src/ui/sitemanager.cpp
new file mode 100644
index 0000000..29f2ccd
--- /dev/null
+++ b/src/ui/sitemanager.cpp
@@ -0,0 +1,412 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QTextCharFormat>
+#include <QDialog>
+#include <QIntValidator>
+#include <QPainter>
+#include <QResizeEvent>
+#include <QPalette>
+#include <QListWidgetItem>
+#include <QMessageBox>
+
+#include "fqterm_config.h"
+#include "fqterm_param.h"
+#include "fqterm_param.h"
+#include "fqterm_path.h"
+#include "fqterm_trace.h"
+
+#include "sitemanager.h"
+
+namespace FQTerm{
+
+int siteDialog::ports[] = {23, 22, 22, 0};
+
+siteDialog::siteDialog(QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/)
+ : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+
+ config_ = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg");
+ QStringList name_list;
+ loadNameList(config_, name_list);
+ ui_.siteList->addItems(name_list);
+
+ if (ui_.siteList->count() != 0) {
+ setCurrentSite(0);
+ loadCurrentParam();
+ setUIFromParam();
+ }
+ else {
+ ui_.editGroup->setDisabled(true);
+ }
+ connector();
+}
+
+siteDialog::~siteDialog() {
+ config_->save(getPath(USER_CONFIG) + "address.cfg");
+ delete config_;
+}
+
+void siteDialog::onSelectProtocol(int index) {
+ ui_.portCheck->setChecked(false);
+ ui_.portEdit->setText(QString("%1").arg(ports[index]));
+}
+
+void siteDialog::setParamFromUI() {
+ param_.name_ = ui_.nameEdit->text();
+ param_.hostAddress_ = ui_.addrEdit->text();
+ param_.protocolType_ = ui_.protocolCombo->currentIndex();
+ bool ok;
+ int port = ui_.portEdit->text().toInt(&ok);
+ param_.port_ = (ok && port >= 0 && port <= 65535)?port:ports[ui_.protocolCombo->currentIndex()];
+ param_.hostType_ = ui_.hostTypeCombo->currentIndex();
+ if (!ui_.proxyCheck->isChecked()) {
+ param_.proxyType_ = 0;
+ }
+ param_.isAutoLogin_ = ui_.autoLoginCheck->isChecked();
+}
+
+//auto fix errors.
+void siteDialog::setUIFromParam() {
+ ui_.nameEdit->setText(param_.name_);
+ ui_.addrEdit->setText(param_.hostAddress_);
+ ui_.protocolCombo->setCurrentIndex(param_.protocolType_);
+ ui_.portCheck->setCheckState(param_.port_ == ports[ui_.protocolCombo->currentIndex()]?Qt::Unchecked:Qt::Checked);
+ ui_.portEdit->setText(QString("%1").arg(param_.port_));
+ ui_.hostTypeCombo->setCurrentIndex(param_.hostType_);
+ ui_.proxyCheck->setCheckState(param_.proxyType_?Qt::Checked:Qt::Unchecked);
+ ui_.autoLoginCheck->setCheckState(param_.isAutoLogin_?Qt::Checked:Qt::Unchecked);
+
+ previewFont();
+}
+
+void siteDialog::loadCurrentParam() {
+ if (ui_.siteList->count() == 0) {
+ return;
+ }
+ loadAddress(config_, currentSiteIndex(), param_);
+}
+
+void siteDialog::saveCurrentParam() {
+ if (ui_.siteList->count() == 0) {
+ return;
+ }
+ saveAddress(config_, currentSiteIndex(), param_);
+}
+
+void siteDialog::previewFont() {
+ //issue 98
+
+ QPalette palette;
+ palette.setColor(QPalette::Window, param_.backgroundColor_);
+ palette.setColor(QPalette::WindowText, param_.foregroundColor_);
+ ui_.fontPreviewer->setPalette(palette);
+
+ QString sample("<html><body style=\" font-family:'"
+ + param_.englishFontName_ + "'; font-size:"
+ + QString().setNum(param_.englishFontSize_)
+ + "pt;\"><BR>AaBbCc</body></html>");
+ sample += QString("<html><body style=\" font-family:'"
+ + param_.otherFontName_ + "'; font-size:"
+ + QString().setNum(param_.otherFontSize_) + "pt;\">"
+ + param_.otherFontName_ + "<BR></body></html>");
+ ui_.fontPreviewer->setText(sample);
+}
+
+void siteDialog::swapSite(int first, int second) {
+ FQTermParam firstParam;
+ FQTermParam secondParam;
+ loadAddress(config_, first, firstParam);
+ loadAddress(config_, second, secondParam);
+ saveAddress(config_, first, secondParam);
+ saveAddress(config_, second, firstParam);
+
+ QListWidgetItem* firstItem = ui_.siteList->item(first);
+ QListWidgetItem* secondItem = ui_.siteList->item(second);
+ QString tmpStr = firstItem->text();
+ firstItem->setText(secondItem->text());
+ secondItem->setText(tmpStr);
+}
+
+int siteDialog::moveSite(int pos, int offset)
+{
+ int newPos = pos + offset;
+ int step = offset>0?1:-1;
+ if (newPos >= ui_.siteList->count() || newPos < 0) {
+ return pos;
+ }
+ for(int i = pos; i != newPos; i += step) {
+ swapSite(i , i + step);
+ }
+ return newPos;
+}
+
+QMessageBox::StandardButton siteDialog::checkModification(int row) { //with current display
+ FQTermParam originParam;
+ loadAddress(config_, row, originParam);
+ setParamFromUI();
+ QMessageBox::StandardButton ret = QMessageBox::No;
+ if (!(originParam == param_)) {
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
+ msgBox.setIcon(QMessageBox::Warning);
+ msgBox.setWindowTitle(tr("Warning"));
+ msgBox.setText(tr("The site configuration has been changed.\nTo save, press Yes.\nTo discard, press No.\nTo continue editing, press Cancel"));
+
+
+ switch(ret = static_cast<QMessageBox::StandardButton>(msgBox.exec())) {
+ case QMessageBox::No:
+ param_ = originParam;
+ break;
+ default:
+ break;
+ }
+ ui_.siteList->item(row)->setText(param_.name_);
+ }
+ return ret;
+}
+
+void siteDialog::onSelectSite(QListWidgetItem* current, QListWidgetItem* previous)
+{
+ int currentRow = ui_.siteList->row(current);
+ int previousRow = ui_.siteList->row(previous);
+ if (currentRow < 0) {
+ ui_.editGroup->setDisabled(true);
+ }
+ else {
+ ui_.editGroup->setEnabled(true);
+ }
+ if (previousRow >= 0){
+ if (checkModification(previousRow) == QMessageBox::Cancel) {
+ forcedSetCurrentSite(previousRow);
+ return;
+ }
+ saveAddress(config_, previousRow, param_);
+ }
+ if (currentRow >= 0){
+ loadAddress(config_, currentRow, param_);
+ setUIFromParam();
+ }
+
+}
+
+//without emit a signal
+void siteDialog::forcedSetCurrentSite(int row)
+{
+ FQ_VERIFY(disconnect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+ this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*))));
+ ui_.siteList->setCurrentRow(row);
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+ this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*))));
+}
+
+//emit a signal
+void siteDialog::setCurrentSite(int row)
+{
+ ui_.siteList->setCurrentRow(row);
+}
+
+void siteDialog::removeSite(int row)
+{
+ if (row < 0) {
+ return;
+ }
+ int last = ui_.siteList->count() - 1;
+ setCurrentSite(last - 1);
+ moveSite(row, last - row);
+ config_->deleteSection(QString("%1").arg(last));
+ config_->setItemValue("bbs list", "num", QString("%1").arg(last));
+ delete ui_.siteList->takeItem(last);
+
+ loadCurrentParam();
+ setUIFromParam();
+}
+
+void siteDialog::onNew() {
+ int row = ui_.siteList->count();
+ if (row < 0) {
+ row = 0;
+ }
+ config_->setItemValue("bbs list", "num", QString("%1").arg(row + 1));
+
+ FQTermParam newParam;
+ loadAddress(config_, -1, newParam);
+ saveAddress(config_, row, newParam);
+ ui_.siteList->addItem(newParam.name_);
+ setCurrentSite(row);
+}
+
+void siteDialog::onDelete() {
+ if (ui_.siteList->count() == 0) {
+ return;
+ }
+ QMessageBox msgBox;
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ msgBox.setIcon(QMessageBox::Warning);
+ msgBox.setWindowTitle(tr("Warning"));
+ msgBox.setText(tr("Are you sure to DELETE this site?"));
+ switch(msgBox.exec())
+ {
+ case QMessageBox::Yes:
+ removeSite(currentSiteIndex());
+ break;
+ case QMessageBox::No:
+ break;
+ }
+}
+
+void siteDialog::siteNameChanged( QString name ) {
+ QListWidgetItem* item = ui_.siteList->currentItem();
+ if (item) {
+ item->setText(name);
+ }
+}
+
+void siteDialog::setSiteSelected() {
+ int row = currentSiteIndex();
+ if(row >= 0) {
+ ui_.siteList->item(row)->setSelected(true);
+ }
+}
+
+void siteDialog::close(int doneValue) {
+ if (ui_.siteList->count() > 0) {
+ switch(checkModification(currentSiteIndex())) {
+ case QMessageBox::Yes:
+ onApply();
+ break;
+ case QMessageBox::No:
+ loadCurrentParam();
+ break;
+ case QMessageBox::Cancel:
+ return;
+ default:
+ break;
+ }
+ }
+ done(doneValue);
+}
+
+void siteDialog::onReset() {
+ loadCurrentParam();
+ setUIFromParam();
+}
+
+void siteDialog::onApply() {
+ setParamFromUI();
+ saveCurrentParam();
+ setUIFromParam();
+}
+
+void siteDialog::onUp() {
+ int newPos = moveSite(currentSiteIndex(), -1);
+ forcedSetCurrentSite(newPos);
+}
+
+void siteDialog::onDown() {
+ int newPos = moveSite(currentSiteIndex(), 1);
+ forcedSetCurrentSite(newPos);
+}
+
+void siteDialog::onClose() {
+ close(0);
+}
+
+void siteDialog::onConnect() {
+ close(1);
+}
+
+void siteDialog::resizeEvent( QResizeEvent * re ) {
+ previewFont();
+}
+
+FQTermParam siteDialog::currentParameter() {
+ return param_;
+}
+
+int siteDialog::currentSiteIndex() {
+ return ui_.siteList->currentRow();
+}
+
+void siteDialog::onAdvance() {
+ setting(addrDialog::General);
+}
+
+void siteDialog::setting(addrDialog::Tabs tab) {
+ setParamFromUI();
+ addrDialog addr(this, param_, addrDialog::APPLY);
+ addr.setCurrentTabIndex(tab);
+ int res = addr.exec();
+ if (res == 1) {
+ param_ = addr.param();
+ setUIFromParam();
+ }
+}
+
+void siteDialog::onProxy() {
+ setting(addrDialog::Proxy);
+}
+
+void siteDialog::onAutoLogin() {
+ setting(addrDialog::General);
+}
+
+void siteDialog::onDblClicked(QListWidgetItem * item) {
+ onConnect();
+}
+
+void siteDialog::connector() {
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(itemSelectionChanged()),
+ this, SLOT(setSiteSelected())));
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+ this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*))));
+ FQ_VERIFY(connect(ui_.nameEdit, SIGNAL(textChanged(QString)),
+ this, SLOT(siteNameChanged(QString))));
+ FQ_VERIFY(connect(ui_.protocolCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(onSelectProtocol(int))));
+ FQ_VERIFY(connect(ui_.resetButton, SIGNAL(clicked()),
+ this, SLOT(onReset())));
+ FQ_VERIFY(connect(ui_.upButton, SIGNAL(clicked()),
+ this, SLOT(onUp())));
+ FQ_VERIFY(connect(ui_.downButton, SIGNAL(clicked()),
+ this, SLOT(onDown())));
+ FQ_VERIFY(connect(ui_.newButton, SIGNAL(clicked()),
+ this, SLOT(onNew())));
+ FQ_VERIFY(connect(ui_.deleteButton, SIGNAL(clicked()),
+ this, SLOT(onDelete())));
+ FQ_VERIFY(connect(ui_.applyButton, SIGNAL(clicked()),
+ this, SLOT(onApply())));
+ FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()),
+ this, SLOT(onClose())));
+ FQ_VERIFY(connect(ui_.connectButton, SIGNAL(clicked()),
+ this, SLOT(onConnect())));
+ FQ_VERIFY(connect(ui_.advanceButton, SIGNAL(clicked()),
+ this, SLOT(onAdvance())));
+ FQ_VERIFY(connect(ui_.proxyButton, SIGNAL(clicked()),
+ this, SLOT(onProxy())));
+ FQ_VERIFY(connect(ui_.autoLoginButton, SIGNAL(clicked()),
+ this, SLOT(onAutoLogin())));
+ FQ_VERIFY(connect(ui_.siteList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
+ this, SLOT(onDblClicked(QListWidgetItem *))));
+}
+
+} //namespace FQTerm
+
+#include "sitemanager.moc"
diff --git a/src/ui/sitemanager.h b/src/ui/sitemanager.h
new file mode 100644
index 0000000..6aae387
--- /dev/null
+++ b/src/ui/sitemanager.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SITEMANGER_H
+#define FQTERM_SITEMANGER_H
+
+#include "addrdialog.h"
+
+#include "ui_sitemanager.h"
+#include "ui_quickdialog.h"
+
+class QListWidgetItem;
+
+namespace FQTerm {
+class FQTermParam;
+class FQTermConfig;
+
+class siteDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ siteDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0);;
+ ~siteDialog();
+
+ FQTermParam currentParameter();
+
+ int currentSiteIndex();
+
+ private:
+ void connector();
+
+ void resizeEvent(QResizeEvent * re);
+
+ //Note: changes are made on config_
+ void saveCurrentParam();
+ void loadCurrentParam();
+
+ void setParamFromUI();
+ void setUIFromParam();
+
+ void previewFont();
+
+ void swapSite(int first, int second);
+ int moveSite(int pos, int offset);
+ void forcedSetCurrentSite(int row);
+ void setCurrentSite(int row);
+
+ QMessageBox::StandardButton checkModification(int row);
+
+ void removeSite(int row);
+
+ void close(int doneValue);
+ void setting(addrDialog::Tabs tab);
+
+
+ protected slots:
+ void onSelectSite(QListWidgetItem* current, QListWidgetItem* previous);
+ void siteNameChanged(QString name);
+ void setSiteSelected();
+
+ void onSelectProtocol(int index);
+
+ void onReset();
+ void onApply();
+ void onUp();
+ void onDown();
+ void onNew();
+ void onDelete();
+ void onClose();
+ void onConnect();
+
+ void onAdvance();
+ void onProxy();
+ void onAutoLogin();
+ void onDblClicked(QListWidgetItem * item);
+
+ private:
+ FQTermConfig *config_;
+ FQTermParam param_;
+
+ Ui::siteManager ui_;
+
+ static int ports[]; //telnet, ssh1, ssh2
+};
+
+} //FQTerm namespace
+
+#endif // FQTERM_SITEMANGER_H
diff --git a/src/ui/sitemanager.ui b/src/ui/sitemanager.ui
new file mode 100644
index 0000000..9b085ed
--- /dev/null
+++ b/src/ui/sitemanager.ui
@@ -0,0 +1,593 @@
+<ui version="4.0" >
+ <class>siteManager</class>
+ <widget class="QDialog" name="siteManager" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>481</width>
+ <height>495</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Address Book</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="2" >
+ <widget class="QListWidget" name="siteList" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QPushButton" name="upButton" >
+ <property name="text" >
+ <string>&amp;Up</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="downButton" >
+ <property name="text" >
+ <string>&amp;Down</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QGroupBox" name="editGroup" >
+ <property name="title" >
+ <string/>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="nameLabel" >
+ <property name="text" >
+ <string>Site Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QLineEdit" name="nameEdit" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="addrLabel" >
+ <property name="text" >
+ <string>Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="3" >
+ <widget class="QLineEdit" name="addrEdit" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="protocolLabel" >
+ <property name="text" >
+ <string>Protocol</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QComboBox" name="protocolCombo" >
+ <item>
+ <property name="text" >
+ <string>Telnet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>SSH2</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QCheckBox" name="portCheck" >
+ <property name="text" >
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" >
+ <widget class="QLineEdit" name="portEdit" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="hostTypeLabel" >
+ <property name="text" >
+ <string>Host Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QComboBox" name="hostTypeCombo" >
+ <item>
+ <property name="text" >
+ <string>BBS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>*NIX</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QCheckBox" name="proxyCheck" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Use Proxy</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QPushButton" name="proxyButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Setting...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QCheckBox" name="autoLoginCheck" >
+ <property name="text" >
+ <string>Auto Login</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" >
+ <widget class="QPushButton" name="autoLoginButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Setting...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" >
+ <widget class="QLabel" name="label_10" >
+ <property name="text" >
+ <string>Font Preview</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" colspan="3" >
+ <widget class="QLabel" name="fontPreviewer" >
+ <property name="autoFillBackground" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Font Previewer</string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0" colspan="4" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>55</width>
+ <height>25</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="resetButton" >
+ <property name="text" >
+ <string>&amp;Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>54</width>
+ <height>25</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="advanceButton" >
+ <property name="text" >
+ <string>A&amp;dvance</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="7" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="newButton" >
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteButton" >
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="connectButton" >
+ <property name="text" >
+ <string>C&amp;onnect</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyButton" >
+ <property name="text" >
+ <string>&amp;Save</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton" >
+ <property name="text" >
+ <string>&amp;Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ <widget class="QLabel" name="label" >
+ <property name="geometry" >
+ <rect>
+ <x>9</x>
+ <y>553</y>
+ <width>31</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_2" >
+ <property name="geometry" >
+ <rect>
+ <x>120</x>
+ <y>553</y>
+ <width>30</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_3" >
+ <property name="geometry" >
+ <rect>
+ <x>156</x>
+ <y>553</y>
+ <width>78</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_4" >
+ <property name="geometry" >
+ <rect>
+ <x>240</x>
+ <y>553</y>
+ <width>69</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_5" >
+ <property name="geometry" >
+ <rect>
+ <x>410</x>
+ <y>553</y>
+ <width>34</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_6" >
+ <property name="geometry" >
+ <rect>
+ <x>369</x>
+ <y>553</y>
+ <width>35</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_7" >
+ <property name="geometry" >
+ <rect>
+ <x>46</x>
+ <y>553</y>
+ <width>30</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_8" >
+ <property name="geometry" >
+ <rect>
+ <x>82</x>
+ <y>553</y>
+ <width>32</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_9" >
+ <property name="geometry" >
+ <rect>
+ <x>315</x>
+ <y>553</y>
+ <width>48</width>
+ <height>0</height>
+ </rect>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </widget>
+ <tabstops>
+ <tabstop>siteList</tabstop>
+ <tabstop>nameEdit</tabstop>
+ <tabstop>addrEdit</tabstop>
+ <tabstop>protocolCombo</tabstop>
+ <tabstop>portCheck</tabstop>
+ <tabstop>portEdit</tabstop>
+ <tabstop>hostTypeCombo</tabstop>
+ <tabstop>proxyCheck</tabstop>
+ <tabstop>autoLoginCheck</tabstop>
+ <tabstop>connectButton</tabstop>
+ <tabstop>upButton</tabstop>
+ <tabstop>downButton</tabstop>
+ <tabstop>resetButton</tabstop>
+ <tabstop>advanceButton</tabstop>
+ <tabstop>newButton</tabstop>
+ <tabstop>deleteButton</tabstop>
+ <tabstop>applyButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ <tabstop>proxyButton</tabstop>
+ <tabstop>autoLoginButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>portCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>portEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>372</x>
+ <y>81</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>477</x>
+ <y>83</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>proxyCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>proxyButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>235</x>
+ <y>141</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>285</x>
+ <y>126</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>autoLoginCheck</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>autoLoginButton</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>232</x>
+ <y>155</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>361</x>
+ <y>172</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/soundconf.cpp b/src/ui/soundconf.cpp
new file mode 100644
index 0000000..2681b83
--- /dev/null
+++ b/src/ui/soundconf.cpp
@@ -0,0 +1,178 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QMessageBox>
+#include <QFileDialog>
+
+#include "fqterm.h"
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_sound.h"
+
+#include "soundconf.h"
+
+namespace FQTerm {
+/*
+ * Constructs a fSoundConf which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+soundConf::soundConf(FQTermConfig * config, QWidget *parent, Qt::WFlags fl)
+ : QDialog(parent, fl),
+ buttonGroup_(this),
+ config_(config){
+ ui_.setupUi(this);
+ buttonGroup_.addButton(ui_.radioButton1, 0);
+ buttonGroup_.addButton(ui_.radioButton2, 1);
+ sound_ = NULL;
+ loadSetting();
+ FQ_VERIFY(connect(ui_.bfSelect, SIGNAL(clicked()),
+ this, SLOT(onSelectFile())));
+ FQ_VERIFY(connect(ui_.bpSelect, SIGNAL(clicked()),
+ this, SLOT(onSelectProg())));
+ FQ_VERIFY(connect(ui_.bpTest, SIGNAL(clicked()),
+ this, SLOT(onTestPlay())));
+ FQ_VERIFY(connect(ui_.bOK, SIGNAL(clicked()),
+ this, SLOT(accept())));
+ FQ_VERIFY(connect(ui_.bCancel, SIGNAL(clicked()),
+ this, SLOT(reject())));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+soundConf::~soundConf() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * public slot
+ */
+void soundConf::onSelectFile() {
+ FQTermFileDialog fileDialog(config_);
+ QString soundfile = fileDialog.getOpenName("Choose a WAVE file", "WAVE Audio Files (*.wav *.WAV)");
+ if (!soundfile.isEmpty()) {
+ ui_.leFile->setText(soundfile);
+ }
+}
+
+/*
+ * public slot
+ */
+void soundConf::onSelectProg() {
+ FQTermFileDialog fileDialog(config_);
+ QString progfile = fileDialog.getOpenName("Choose a program", "");
+ if (!progfile.isEmpty()) {
+ ui_.leProg->setText(progfile);
+ }
+}
+
+/*
+ * public slot
+ */
+void soundConf::onPlayMethod(int id) {
+FQ_TRACE("sconf", 0) << id << ": " << buttonGroup_.checkedId();
+ ui_.bpSelect->setEnabled(id == 1 || buttonGroup_.checkedId() == 1);
+}
+
+void soundConf::onTestPlay() {
+ if (ui_.leFile->text().isEmpty()) {
+ QMessageBox::critical(this, tr("No sound file"),
+ tr("You have to select a file to test the sound"), tr("&Ok"));
+
+ return;
+ }
+
+ sound_ = NULL;
+
+ switch (buttonGroup_.checkedId()) {
+ case 0:
+ sound_ = new FQTermSystemSound(ui_.leFile->text());
+ break;
+ case 1:
+ if (ui_.leProg->text().isEmpty()) {
+ QMessageBox::critical(this, tr("No player"),
+ tr("You have to specify an external player"), tr("&Ok"));
+
+ break;
+ }
+
+ sound_ = new FQTermExternalSound(ui_.leProg->text(), ui_.leFile->text());
+ break;
+ }
+
+ if (sound_) {
+ sound_->start();
+ }
+}
+
+void soundConf::loadSetting() {
+
+ QString strTmp;
+
+ strTmp = config_->getItemValue("preference", "wavefile");
+ if (!strTmp.isEmpty()) {
+ ui_.leFile->setText(strTmp);
+ }
+
+ strTmp = config_->getItemValue("preference", "playmethod");
+
+ int valTmp = !strTmp.isEmpty()? strTmp.toInt(): -1;
+
+ if (valTmp >= 0 && valTmp <= 1) {
+ buttonGroup_.button(valTmp)->setChecked(true);
+ if (valTmp == 1) {
+ strTmp = config_->getItemValue("preference", "externalplayer");
+ if (!strTmp.isEmpty()) {
+ ui_.leProg->setText(strTmp);
+ }
+ }
+ }
+}
+
+void soundConf::saveSetting() {
+
+ QString strTmp;
+
+ config_->setItemValue("preference", "beep", "2");
+
+ config_->setItemValue("preference", "wavefile", ui_.leFile->text());
+
+ strTmp.setNum(buttonGroup_.checkedId());
+ config_->setItemValue("preference", "playmethod", strTmp);
+
+ if (strTmp == "1") {
+ config_->setItemValue("preference", "externalplayer", ui_.leProg->text());
+ }
+
+ config_->save(getPath(USER_CONFIG) + "fqterm.cfg");
+}
+
+void soundConf::accept() {
+ saveSetting();
+ QDialog::accept();
+}
+
+} // namespace FQTerm
+
+#include "soundconf.moc"
diff --git a/src/ui/soundconf.h b/src/ui/soundconf.h
new file mode 100644
index 0000000..5b4fe4c
--- /dev/null
+++ b/src/ui/soundconf.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SOUND_CONF_H
+#define FQTERM_SOUND_CONF_H
+
+#include "ui_soundconf.h"
+#include "fqterm_filedialog.h"
+
+namespace FQTerm {
+
+class FQTermSound;
+class FQTermConfig;
+
+class soundConf: public QDialog {
+ Q_OBJECT;
+ public:
+ soundConf(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~soundConf();
+ void loadSetting();
+ void saveSetting();
+
+ public slots:
+ void onSelectFile();
+ void onSelectProg();
+ void onPlayMethod(int id);
+ void onTestPlay();
+ protected slots:
+ void accept();
+
+ private:
+ FQTermSound *sound_;
+ Ui::soundConf ui_;
+ QButtonGroup buttonGroup_;
+ FQTermConfig * config_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SOUND_CONF_H
diff --git a/src/ui/soundconf.ui b/src/ui/soundconf.ui
new file mode 100644
index 0000000..9cfe761
--- /dev/null
+++ b/src/ui/soundconf.ui
@@ -0,0 +1,162 @@
+<ui version="4.0" >
+ <class>soundConf</class>
+ <widget class="QDialog" name="soundConf" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>308</width>
+ <height>269</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Configure</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Sound File:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLineEdit" name="leFile" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QPushButton" name="bfSelect" >
+ <property name="text" >
+ <string>Select...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Play With:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QRadioButton" name="radioButton1" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Internal</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QRadioButton" name="radioButton2" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>External</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QPushButton" name="bpTest" >
+ <property name="text" >
+ <string>Test</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <widget class="QGroupBox" name="groupBox_3" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="title" >
+ <string>External Program:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLineEdit" name="leProg" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QPushButton" name="bpSelect" >
+ <property name="text" >
+ <string>Select...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="1" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="bOK" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bCancel" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections>
+ <connection>
+ <sender>radioButton2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>groupBox_3</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>124</x>
+ <y>136</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>123</x>
+ <y>176</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/ui/sshlogin.ui b/src/ui/sshlogin.ui
new file mode 100644
index 0000000..8794a57
--- /dev/null
+++ b/src/ui/sshlogin.ui
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SSHLogin</class>
+ <widget class="QDialog" name="SSHLogin">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>295</width>
+ <height>170</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Login</string>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="textLabel2_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Please enter your username and password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>UserName:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="leUserName"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="textLabel2">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QLineEdit" name="lePassword"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QPushButton" name="bOK">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QPushButton" name="bCancel">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/sshlogindialog.cpp b/src/ui/sshlogindialog.cpp
new file mode 100644
index 0000000..cd858cb
--- /dev/null
+++ b/src/ui/sshlogindialog.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QString>
+#include <QLineEdit>
+
+#include "fqterm_trace.h"
+#include "sshlogindialog.h"
+
+namespace FQTerm {
+
+/*
+ * Constructs a fSSHLogin which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+SSHLoginDialog::SSHLoginDialog(QString *username, QString *password,
+ QWidget *parent_, Qt::WFlags fl)
+ : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+ setWindowTitle(parent_->windowTitle());
+ strUserName = username;
+ strPassword = password;
+ ui_.lePassword->setEchoMode(QLineEdit::Password);
+ ui_.leUserName->setText(*username);
+ ui_.lePassword->setText(*password);
+ if (!username->isEmpty()) {
+ ui_.leUserName->setDisabled(true);
+ ui_.lePassword->setFocus();
+ } else {
+ ui_.leUserName->setDisabled(false);
+ ui_.leUserName->setFocus();
+ }
+
+ FQ_VERIFY(connect(ui_.bOK, SIGNAL(clicked()), this, SLOT(accept())));
+ FQ_VERIFY(connect(ui_.bCancel, SIGNAL(clicked()), this, SLOT(reject())));
+ FQ_VERIFY(connect(ui_.leUserName, SIGNAL(returnPressed()), this, SLOT(moveFocus())));
+ FQ_VERIFY(connect(ui_.lePassword, SIGNAL(returnPressed()), this, SLOT(accept())));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+SSHLoginDialog::~SSHLoginDialog() {
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void SSHLoginDialog::accept() {
+ *strUserName = ui_.leUserName->text();
+ *strPassword = ui_.lePassword->text();
+ QDialog::accept();
+}
+
+void SSHLoginDialog::moveFocus()
+{
+ ui_.lePassword->setFocus();
+}
+
+} // namespace FQTerm
+
+#include "sshlogindialog.moc"
diff --git a/src/ui/sshlogindialog.h b/src/ui/sshlogindialog.h
new file mode 100644
index 0000000..e3295cc
--- /dev/null
+++ b/src/ui/sshlogindialog.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_SSH_LOGIN_H
+#define FQTERM_SSH_LOGIN_H
+
+#include "ui_sshlogin.h"
+
+namespace FQTerm {
+
+class SSHLoginDialog: public QDialog {
+ Q_OBJECT;
+public:
+ SSHLoginDialog(QString *username, QString *password,
+ QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~SSHLoginDialog();
+private:
+ QString *strUserName;
+ QString *strPassword;
+ Ui::SSHLogin ui_;
+private slots:
+ void accept();
+ void moveFocus();
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_SSH_LOGIN_H
diff --git a/src/ui/statusBar.cpp b/src/ui/statusBar.cpp
new file mode 100644
index 0000000..be48fc4
--- /dev/null
+++ b/src/ui/statusBar.cpp
@@ -0,0 +1,530 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QPaintEvent>
+#include <QEvent>
+#include <QHBoxLayout>
+#include <QCustomEvent>
+#include <QProgressBar>
+#include <QToolButton>
+#include <QPushButton>
+#include <QPainter>
+#include <QPixmap>
+#include <QMessageBox>
+#include <QApplication>
+#include <QToolTip>
+
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+
+#include "popupMessage.h"
+#include "progressBar.h"
+#include "overlayWidget.h"
+#include "statusBar.h"
+
+namespace FQTerm {
+
+//TODO allow for uncertain progress periods
+
+StatusBar *StatusBar::singletonStatusBar_ = 0;
+
+StatusBar::StatusBar(QWidget *parent, const char *name)
+ : QWidget(parent) {
+ setObjectName(name);
+ singletonStatusBar_ = this;
+ QBoxLayout *mainlayout = new QHBoxLayout(this); //, 2, /*spacing*/5 );
+ mainlayout->setMargin(0);
+ mainlayout->setSpacing(5);
+
+ //we need extra spacing due to the way we paint the surrounding boxes
+ QBoxLayout *layout = new QHBoxLayout;
+ layout->setSpacing(5);
+ mainlayout->addLayout(layout);
+
+ m_mainTextLabel = new QLabel(this);
+ m_mainTextLabel->setObjectName("mainTextLabel");
+ m_mainTextLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+
+ QWidget *mainProgressBarBox = new QWidget(this);
+ mainProgressBarBox->setObjectName("progressBox");
+
+ QHBoxLayout *mainProgressBarLayout = new QHBoxLayout(mainProgressBarBox);
+ mainProgressBarLayout->setContentsMargins(0, 0, 0, 0);
+
+ QToolButton *b1 = new QToolButton(mainProgressBarBox);
+ b1->setObjectName("cancelButton");
+ b1->setContentsMargins(0, 0, 0, 0);
+ b1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+ mainProgressBarLayout->addWidget(b1);
+
+ mainProgressBar_ = new QProgressBar(mainProgressBarBox);
+ mainProgressBar_->setObjectName("mainProgressBar");
+ mainProgressBarLayout->addWidget(mainProgressBar_);
+
+ QToolButton *b2 = new QToolButton(mainProgressBarBox);
+ b2->setObjectName("showAllProgressDetails");
+ b2->setContentsMargins(0,0,0,0);
+ b2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+ mainProgressBarLayout->addWidget(b2);
+
+ mainProgressBarLayout->setSpacing(2);
+ mainProgressBarBox->hide();
+
+ layout->addWidget(mainProgressBarBox);
+ layout->addWidget(m_mainTextLabel);
+
+ layout->setStretchFactor(m_mainTextLabel, 2);
+ layout->setStretchFactor(mainProgressBarBox, 1);
+
+ otherWidgetLayout_ = new QHBoxLayout;
+ otherWidgetLayout_->setSpacing(0);
+ mainlayout->addLayout(otherWidgetLayout_);
+
+ mainlayout->setStretchFactor(layout, 6);
+ mainlayout->setStretchFactor(otherWidgetLayout_, 4);
+
+ b1->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png"));
+ b2->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_info.png"));
+ b2->setCheckable(true);
+ b1->setToolTip(tr("Abort all background-operations"));
+ b2->setToolTip(tr("Show progress detail"));
+
+ FQ_VERIFY(connect(b1, SIGNAL(clicked()), SLOT(abortAllProgressOperations())));
+ FQ_VERIFY(connect(b2, SIGNAL(toggled(bool)), SLOT(toggleProgressWindow(bool))));
+
+ popupProgressMessage_ = new PopupMessage(this, mainProgressBarBox, 0);
+ popupProgressMessage_->showCloseButton(false);
+ popupProgressMessage_->showCounter(false);
+
+ popupProgressMessage_->setFrameStyle(QFrame::Box | QFrame::Raised);
+ popupProgressMessage_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+}
+
+void StatusBar::addWidget(QWidget *widget) {
+ otherWidgetLayout_->addWidget(widget);
+}
+
+
+/// reimplemented functions
+
+void StatusBar::ensurePolished() {
+ QWidget::ensurePolished();
+
+ int h = 0;
+ QObjectList list = children();
+
+ //for( QObject * o = list.first(); o; o = list.next() ) {
+ foreach(QObject *o, list) {
+ if (o->inherits("QWidget")) {
+ int _h = static_cast < QWidget * > (o)->minimumSizeHint().height();
+ if (_h > h) {
+ h = _h;
+ }
+
+
+ if (o->inherits("QLabel")) {
+ static_cast < QLabel * > (o)->setIndent(4);
+ }
+ }
+ }
+
+ h -= 4; // it's too big usually
+
+ //for ( QObject * o = list.first(); o; o = list.next() )
+ foreach(QObject *o, list)static_cast < QWidget * > (o)->setFixedHeight(h);
+
+ //delete list;
+}
+
+void StatusBar::paintEvent(QPaintEvent*) {
+ QObjectList list = children(); //queryList( "QWidget", 0, false, false );
+ QPainter p(this);
+
+ //for( QObject * o = list.first(); o; o = list.next() ) {
+ foreach(QObject *o, list) {
+ if (o->inherits("QWidget")) {
+ QWidget *w = (QWidget*)o;
+
+ if (!w->isVisible()) {
+ continue;
+ }
+
+ /*style().drawPrimitive(
+ QStyle::PE_StatusBarSection,
+ &p,
+ QRect( w->x() - 1, w->y() - 1, w->width() + 2, w->height() + 2 ),
+ colorGroup(),
+ QStyle::State_None,
+ QStyleOption( w ) );*/
+ }
+ }
+
+ //delete list;
+}
+
+bool StatusBar::event(QEvent *e) {
+ if (e->type() == QEvent::LayoutRequest) {
+ update();
+ }
+
+ return QWidget::event(e);
+}
+
+
+/// Messaging system
+
+void StatusBar::setMainText(const QString &text) {
+ mainText_ = text;
+
+ // it may not be appropriate for us to set the mainText yet
+ resetMainText();
+}
+
+void StatusBar::shortMessage(const QString &text) {
+ m_mainTextLabel->setText(text);
+ m_mainTextLabel->setPalette(QToolTip::palette());
+
+ //SingleShotPool::startTimer( 5000, this, SLOT(resetMainText()) );
+ resetMainText();
+}
+
+void StatusBar::resetMainText() {
+ /*
+ if( sender() )
+ debug() << sender()->name() << endl;
+
+ // don't reset if we are showing a shortMessage
+ if( SingleShotPool::isActive( this, SLOT(resetMainText()) ) )
+ return;
+ */
+ m_mainTextLabel->setPalette(QPalette());
+
+ if (allDone()) {
+ m_mainTextLabel->setText(mainText_);
+ }
+
+ else {
+ //m_mainTextLabel->setPaletteBackgroundColor( m_mainTextLabel->paletteBackgroundColor().dark( 110 ) );
+ m_mainTextLabel->setPalette(QToolTip::palette());
+
+ ProgressBar *bar = 0;
+ uint count = 0;
+
+ for (ProgressMap::ConstIterator it = progressMap_.begin();
+ it != progressMap_.end(); ++it ) {
+ if (!(*it)->isFinished_) {
+ bar = *it;
+ count++;
+ }
+ }
+
+ if (count == 1) {
+ m_mainTextLabel->setText(bar->description() + "...");
+ } else {
+ m_mainTextLabel->setText(tr("Multiple background-tasks running"));
+ }
+ }
+}
+/*
+ void
+ StatusBar::shortLongMessage( const QString &_short, const QString &_long )
+ {
+ shortMessage( _short );
+
+ if ( !_long.isEmpty() ) {
+ AMAROK_NOTIMPLEMENTED
+ }
+ }
+*/
+//void
+//StatusBar::longMessage( const QString &text, int /*type*/ )
+/*{
+ PopupMessage * message;
+ message = new PopupMessage( this, m_mainTextLabel );
+ message->setText( text );
+
+ if ( !m_messageQueue.isEmpty() )
+ message->stackUnder( m_messageQueue.last() );
+
+ message->reposition();
+ message->display();
+
+ raise();
+
+ m_messageQueue += message;
+ }
+*/
+
+//void
+//StatusBar::longMessageThreadSafe( const QString &text, int /*type*/ )
+/*{
+ QCustomEvent * e = new QCustomEvent( 1000 );
+ e->setData( new QString( text ) );
+ QApplication::postEvent( this, e );
+ }
+*/
+// void
+// StatusBar::customEvent( QCustomEvent *e )
+// {
+// QString *s = static_cast<QString*>( e->data() );
+// shortMessage( *s );
+// delete s;
+//}
+
+
+/// application wide progress monitor
+
+inline bool StatusBar::allDone() {
+ for (ProgressMap::Iterator it = progressMap_.begin(), end =
+ progressMap_.end(); it != end; ++it)
+ if ((*it)->isFinished_ == false) {
+ return false;
+ }
+
+ return true;
+}
+
+ProgressBar &StatusBar::newProgressOperation(QObject *owner) {
+ if (progressMap_.contains(owner)) {
+ return *progressMap_[owner];
+ }
+
+ if (allDone()) {
+ // if we're allDone then we need to remove the old progressBars before
+ // we start anything new or the total progress will not be accurate
+ pruneProgressBars();
+ } else {
+ (progressBox()->findChild < QWidget * > ("showAllProgressDetails"))->show();
+ }
+
+ QWidget *hbox = new QWidget(popupProgressMessage_);
+ QHBoxLayout *hlayout = new QHBoxLayout(hbox);
+ QLabel *label = new QLabel(hbox);
+ hlayout->addWidget(label);
+ ProgressBar *pBar = new ProgressBar(hbox, label);
+ hlayout->addWidget(pBar);
+ hbox->show();
+ popupProgressMessage_->addWidget(hbox);
+ progressMap_.insert(owner, pBar);
+
+
+ FQ_VERIFY(connect(owner, SIGNAL(destroyed(QObject*)), SLOT(endProgressOperation(QObject*))));
+
+ // so we can show the correct progress information
+ // after the ProgressBar is setup
+ //SingleShotPool::startTimer( 0, this, SLOT(updateProgressAppearance()) );
+ updateProgressAppearance();
+
+ progressBox()->show();
+ cancelButton()->setEnabled(true);
+
+ return *progressMap_[owner];
+}
+/*
+ ProgressBar&
+ StatusBar::newProgressOperation( KIO::Job *job )
+ {
+ ProgressBar & bar = newProgressOperation( (QObject*)job );
+ bar.setTotalSteps( 100 );
+
+ if(!allDone())
+ static_cast<QWidget*>(progressBox()->child("showAllProgressDetails"))->show();
+ QVERIFY(connect( job, SIGNAL(result( KIO::Job* )), SLOT(endProgressOperation())));
+ //TODO QVERIFY(connect( job, SIGNAL(infoMessage( KIO::Job *job, const QString& )), SLOT() ));
+ QVERIFY(connect( job, SIGNAL(percent( KIO::Job*, unsigned long )), SLOT(setProgress( KIO::Job*, unsigned long ))));
+
+ return bar;
+ }
+*/
+/*
+ void
+ StatusBar::endProgressOperation()
+ {
+ QObject *owner = (QObject*)sender(); //HACK deconsting it
+ KIO::Job *job = dynamic_cast<KIO::Job*>( owner );
+
+ //FIXME doesn't seem to work for KIO::DeleteJob, it has it's own error handler and returns no error too
+ // if you try to delete http urls for instance <- KDE SUCKS!
+
+ if( job && job->error() )
+ longMessage( job->errorString(), Error );
+
+ endProgressOperation( owner );
+ }
+*/
+void StatusBar::endProgressOperation(QObject *owner) {
+ //the owner of this progress operation has been deleted
+ //we need to stop listening for progress from it
+ //NOTE we don't delete it yet, as this upsets some
+ //things, we just call setDone().
+
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setDone();
+
+ if (allDone() && popupProgressMessage_->isHidden()) {
+ cancelButton()->setEnabled(false);
+ //SingleShotPool::startTimer( 2000, this, SLOT(hideMainProgressBar()) );
+ hideMainProgressBar();
+ }
+
+ updateTotalProgress();
+}
+
+void StatusBar::abortAllProgressOperations() { //slot
+ for (ProgressMap::Iterator it = progressMap_.begin(), end =
+ progressMap_.end(); it != end; ++it) {
+ (*it)->abortButton_->animateClick();
+ }
+
+ m_mainTextLabel->setText(tr("Aborting all jobs..."));
+
+ cancelButton()->setEnabled(false);
+}
+
+void StatusBar::toggleProgressWindow(bool show) { //slot
+ popupProgressMessage_->adjustSize();
+ //FIXME shouldn't be needed, adding bars doesn't seem to do this
+ popupProgressMessage_->setShown(show);
+
+ if (!show) {
+ hideMainProgressBar();
+ }
+ //SingleShotPool::startTimer( 2000, this, SLOT(hideMainProgressBar()) );
+}
+
+void StatusBar::showMainProgressBar() {
+ if (!allDone()) {
+ progressBox()->show();
+ }
+}
+
+void StatusBar::hideMainProgressBar() {
+ if (allDone() && popupProgressMessage_->isHidden()) {
+ pruneProgressBars();
+
+ resetMainText();
+
+ mainProgressBar_->setValue(0);
+ progressBox()->close();
+ }
+}
+
+void StatusBar::setProgress(int steps) {
+ setProgress(sender(), steps);
+}
+/*
+ void
+ StatusBar::setProgress( KIO::Job *job, unsigned long percent )
+ {
+ setProgress( ( QObject* ) job, percent );
+ }
+*/
+void StatusBar::setProgress(const QObject *owner, int steps) {
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setValue(steps);
+
+ updateTotalProgress();
+}
+
+void StatusBar::setProgressStatus(const QObject *owner, const QString &text) {
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setStatus(text);
+}
+
+void StatusBar::incrementProgress() {
+ incrementProgress(sender());
+}
+
+void StatusBar::incrementProgress(const QObject *owner) {
+ if (!progressMap_.contains(owner)) {
+ return ;
+ }
+
+ progressMap_[owner]->setValue(progressMap_[owner]->value() + 1);
+
+ updateTotalProgress();
+}
+
+void StatusBar::updateTotalProgress() {
+ uint totalSteps = 0;
+ uint progress = 0;
+
+ for (ProgressMap::ConstIterator it = progressMap_.begin();
+ it != progressMap_.end(); ++it ) {
+ totalSteps += (*it)->maximum();
+ progress += (*it)->value();
+ }
+
+ if (totalSteps == 0 && progress == 0) {
+ return ;
+ }
+
+ mainProgressBar_->setMaximum(totalSteps);
+ mainProgressBar_->setValue(progress);
+
+ pruneProgressBars();
+}
+
+void StatusBar::updateProgressAppearance() {
+ toggleProgressWindowButton()->setShown(progressMap_.count() > 1);
+
+ resetMainText();
+
+ updateTotalProgress();
+}
+
+void StatusBar::pruneProgressBars() {
+ ProgressMap::Iterator it = progressMap_.begin();
+ const ProgressMap::Iterator end = progressMap_.end();
+ int count = 0;
+ bool removedBar = false;
+ while (it != end)
+ if ((*it)->isFinished_ == true) {
+ delete (*it)->label_;
+ delete (*it)->abortButton_;
+ delete (*it);
+
+ ProgressMap::Iterator jt = it;
+ ++it;
+ progressMap_.erase(jt);
+ removedBar = true;
+ } else {
+ ++it;
+ ++count;
+ }
+ if (count == 1 && removedBar) { //if its gone from 2 or more bars to one bar...
+ resetMainText();
+ (progressBox()->findChild < QWidget * > ("showAllProgressDetails"))->hide();
+ popupProgressMessage_->setShown(false);
+ }
+}
+
+} //namespace FQTerm
+
+#include "statusBar.moc"
diff --git a/src/ui/statusBar.h b/src/ui/statusBar.h
new file mode 100644
index 0000000..9737f90
--- /dev/null
+++ b/src/ui/statusBar.h
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_STATUSBAR_H
+#define FQTERM_STATUSBAR_H
+
+#include "progressBar.h" //convenience
+// #include <qwidget.h> //baseclass
+// #include <qmap.h> //stack allocated
+// #include <q3valuelist.h> //stack allocated
+//Added by qt3to4:
+// #include <QCustomEvent>
+#include <QLabel>
+#include <QEvent>
+#include <QPaintEvent>
+#include <QMap>
+#include <QList>
+#include <QWidget>
+#include <QProgressBar>
+
+class QString;
+class QLayout;
+class QLabel;
+class QString;
+
+namespace FQTerm {
+
+class PopupMessage;
+typedef QMap < const QObject *, ProgressBar * > ProgressMap;
+
+class StatusBar: public QWidget {
+ Q_OBJECT;
+ public:
+ StatusBar(QWidget *parent_, const char *name = "mainStatusBar");
+ static StatusBar *instance() {
+ return singletonStatusBar_
+ ;
+ }
+ /**
+ * Start a progress operation, if owner is 0, the return value is
+ * undefined - the application will probably crash.
+ * @param owner controls progress for this operation
+ * @return the progressBar so you can configure its parameters
+ * @see setProgress( QObject*, int )
+ * @see incrementProgress( QObject* )
+ * @see setProgressStatus( const QObject*, const QString& )
+ */
+ ProgressBar &newProgressOperation(QObject *owner);
+
+ void setProgress(const QObject *owner, int steps);
+ void incrementProgress(const QObject *owner);
+ void setProgressStatus(const QObject *owner, const QString &text);
+ public slots:
+ void setMainText(const QString &text);
+ void resetMainText();
+ void shortMessage(const QString &text);
+ /** Stop anticipating progress from sender() */
+ //void endProgressOperation();
+
+ /** Stop anticipating progress from @param owner */
+ void endProgressOperation(QObject *owner);
+
+ /**
+ * Convenience function works like setProgress( QObject*, int )
+ * Uses the return value from sender() to determine the owner of
+ * the progress bar in question
+ */
+ void setProgress(int steps);
+
+ /**
+ * Convenience function works like incrementProgress( QObject* )
+ * Uses the return value from sender() to determine the owner of
+ * the progress bar in question
+ */
+ void incrementProgress();
+
+ public slots:
+ void toggleProgressWindow(bool show);
+ void abortAllProgressOperations();
+
+ private slots:
+ /** For internal use against KIO::Jobs */
+ //void setProgress( KIO::Job*, unsigned long percent );
+ void showMainProgressBar();
+ void hideMainProgressBar();
+ void updateProgressAppearance();
+
+ protected:
+ virtual void ensurePolished();
+ // virtual void customEvent( QCustomEvent* );
+ virtual void paintEvent(QPaintEvent*);
+ virtual bool event(QEvent*);
+
+ /**
+ * You must parent the widget to the statusbar, we won't do that
+ * for you! The widget will be added to the right of the layout.
+ * Currently you must add widgets before the statusbar gets shown
+ * for the first time, because we are not currently very flexible.
+ */
+ void addWidget(QWidget *widget);
+
+ QLabel *m_mainTextLabel;
+ private:
+ void updateTotalProgress();
+ bool allDone(); ///@return true if all progress operations are complete
+ void pruneProgressBars(); /// deletes old progress bars
+
+ QWidget *cancelButton() {
+ return findChild<QWidget *>("cancelButton");
+ }
+ QWidget *toggleProgressWindowButton() {
+ return findChild<QWidget *>("showAllProgressDetails");
+ }
+ QWidget *progressBox() {
+ return findChild <QWidget *>("progressBox");
+ }
+
+ PopupMessage *popupProgressMessage_;
+ QProgressBar *mainProgressBar_;
+
+ ProgressMap progressMap_;
+ // QList<QWidget *> m_messageQueue;
+ QString mainText_;
+
+ QLayout *otherWidgetLayout_;
+ static StatusBar *singletonStatusBar_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_STATUSBAR_H
diff --git a/src/ui/zmodemdialog.cpp b/src/ui/zmodemdialog.cpp
new file mode 100644
index 0000000..629a40a
--- /dev/null
+++ b/src/ui/zmodemdialog.cpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QMessageBox>
+
+#include "fqterm_trace.h"
+#include "zmodemdialog.h"
+
+namespace FQTerm {
+
+zmodemDialog::zmodemDialog(QWidget *parent_, Qt::WFlags fl)
+ : QDialog(parent_, fl) {
+ ui_.setupUi(this);
+ FQ_VERIFY(connect(ui_.buttonCancel, SIGNAL(clicked()), this, SLOT(slotCancel())));
+}
+
+zmodemDialog::~zmodemDialog(){}
+
+void zmodemDialog::setProgress(int offset) {
+ ui_.pbProgress->setValue(offset);
+ QString strTmp;
+ strTmp = QString("%1 out of %2 bytes").arg(offset).arg(ui_.pbProgress->maximum()
+ );
+ ui_.labelStatus->setText(strTmp);
+}
+
+void zmodemDialog::setFileInfo(const QString &name, int size) {
+ ui_.labelFileName->setText(name);
+ ui_.pbProgress->setMaximum(size);
+}
+
+void zmodemDialog::addErrorLog(const QString &err) {
+ // FIXME:display error message;
+ //browserError->append(err);
+}
+
+void zmodemDialog::clearErrorLog() {
+ //browserError->clear();
+}
+
+void zmodemDialog::slotCancel() {
+ QMessageBox mb("FQTerm", "We dont support cancel operation yet. "
+ "But you can try, it will crash when downloading.\n"
+ "Do you want to continue?",
+ QMessageBox::Warning, QMessageBox::Yes,
+ QMessageBox::No | QMessageBox::Escape | QMessageBox::Default,
+ 0, this);
+ if (mb.exec() == QMessageBox::Yes) {
+ emit canceled();
+ hide();
+ }
+}
+
+} // namespace FQTerm
+
+#include "zmodemdialog.moc"
diff --git a/src/ui/zmodemdialog.h b/src/ui/zmodemdialog.h
new file mode 100644
index 0000000..f310b64
--- /dev/null
+++ b/src/ui/zmodemdialog.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_ZMODEM_DIALOG_H
+#define FQTERM_ZMODEM_DIALOG_H
+
+#include "ui_zmodemdialog.h"
+
+namespace FQTerm {
+
+class zmodemDialog: public QDialog {
+ Q_OBJECT;
+ public:
+ zmodemDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0);
+ ~zmodemDialog();
+
+ void setFileInfo(const QString &, int);
+ void addErrorLog(const QString &);
+ void clearErrorLog();
+ void setProgress(int);
+
+ public slots:
+ void slotCancel();
+
+ signals:
+ void canceled();
+
+ private:
+ Ui::zmodemDialog ui_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_ZMODEM_DIALOG_H
diff --git a/src/ui/zmodemdialog.ui b/src/ui/zmodemdialog.ui
new file mode 100644
index 0000000..9f2bb2b
--- /dev/null
+++ b/src/ui/zmodemdialog.ui
@@ -0,0 +1,105 @@
+<ui version="4.0" >
+ <class>zmodemDialog</class>
+ <widget class="QDialog" name="zmodemDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>333</width>
+ <height>259</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Zmodem Status</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" colspan="3" >
+ <widget class="QLabel" name="labelFileName" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>textLabel1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>121</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>111</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3" >
+ <widget class="QTextBrowser" name="textBrowser" />
+ </item>
+ <item row="2" column="0" colspan="3" >
+ <widget class="QLabel" name="labelStatus" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>textLabel2</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QProgressBar" name="pbProgress" >
+ <property name="value" >
+ <number>24</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/unite/CMakeLists.txt b/src/unite/CMakeLists.txt
new file mode 100644
index 0000000..b093576
--- /dev/null
+++ b/src/unite/CMakeLists.txt
@@ -0,0 +1,46 @@
+set(fqunite_SRCS
+ fqterm_mini_server.h
+ fqterm_mini_server.cpp
+)
+
+set(fqunite_internal_SRCS
+ internal/unite.h
+ internal/user.h
+ internal/user.cpp
+ internal/board.h
+ internal/board.cpp
+ internal/article.h
+ internal/article.cpp
+ internal/session.h
+ internal/session.cpp
+ internal/state.h
+ internal/state.cpp
+ internal/statebuilder.h
+ internal/statebuilder.cpp
+)
+
+qt4_automoc(
+ ${fqunite_SRCS}
+ ${fqunite_internal_SRCS}
+)
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${QT_QTXML_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${OPENSSL_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/internal
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_unite
+ ${fqunite_SRCS}
+ ${fqunite_internal_SRCS}
+)
+
+add_dependencies(fqterm_unite
+ fqterm_common
+)
diff --git a/src/unite/fqterm_mini_server.cpp b/src/unite/fqterm_mini_server.cpp
new file mode 100644
index 0000000..2b18faf
--- /dev/null
+++ b/src/unite/fqterm_mini_server.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "fqterm_mini_server.h"
+#include "fqterm_trace.h"
+#include "fqterm_path.h"
+#include "fqterm.h"
+#include <QByteArray>
+#include <QTimer>
+#include <QFile>
+#include <QtGui/QApplication>
+#include <queue>
+namespace FQTerm {
+
+
+void FQTermMiniServerThread::run()
+{
+ setTerminationEnabled();
+ FQTermMiniServer miniServer;
+ //miniServer.setMaxPendingConnections(1);
+ miniServer.listen(QHostAddress::LocalHost, 35172);
+ exec();
+ miniServer.close();
+ miniServer.finalizeMiniServer();
+}
+
+FQTermMiniServer::FQTermMiniServer(QObject * parent)
+ : QTcpServer(parent) {
+}
+
+
+FQTermMiniServer::~FQTermMiniServer() {
+}
+
+void FQTermMiniServer::incomingConnection( int socketDescriptor ) {
+ FQTermUniteSession* session = new FQTermUniteSession(socketDescriptor);
+ FQ_VERIFY(connect(this, SIGNAL(quit()), session, SLOT(quit()), Qt::QueuedConnection));
+ session->start();
+}
+
+void FQTermMiniServer::finalizeMiniServer() {
+ emit quit();
+}
+
+
+
+
+
+
+
+
+} //namespace FQTerm
+
+#include "fqterm_mini_server.moc"
diff --git a/src/unite/fqterm_mini_server.h b/src/unite/fqterm_mini_server.h
new file mode 100644
index 0000000..3295137
--- /dev/null
+++ b/src/unite/fqterm_mini_server.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_MINI_SERVER_H
+#define FQTERM_MINI_SERVER_H
+
+#include <QThread>
+#include <QByteArray>
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <QString>
+#include "internal/session.h"
+
+namespace FQTerm {
+
+
+class FQTermMiniServer : public QTcpServer {
+ Q_OBJECT;
+public:
+ FQTermMiniServer( QObject * parent = 0 );
+ ~FQTermMiniServer();
+ void finalizeMiniServer();
+protected:
+ void incomingConnection(int socketDescriptor);
+signals:
+ void quit();
+};
+
+
+class FQTermMiniServerThread : public QThread{
+protected:
+ virtual void run();
+
+};
+//----------------------------------------------------------------------------------
+// this for FSM
+class FQTermUniteDecode;
+
+//----------------------------------------------------------------------------------
+
+
+class FQTermUniteSession;
+class FQTermUniteState;
+
+
+
+//use XML to describe the site.
+//each session contains user info, not in the reverse way.
+//each session has 1. state (edit, read, menu), 2. strategy (decided by state) 3. context (with which strategy could decide next step. i.e. inner state)
+} //namespace FQTerm
+#endif
diff --git a/src/unite/internal/article.cpp b/src/unite/internal/article.cpp
new file mode 100644
index 0000000..c5905f8
--- /dev/null
+++ b/src/unite/internal/article.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
diff --git a/src/unite/internal/article.h b/src/unite/internal/article.h
new file mode 100644
index 0000000..43ca0cb
--- /dev/null
+++ b/src/unite/internal/article.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_ARTICLE
+#define FQTERM_UNITE_ARTICLE
+
+namespace FQTerm {
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/board.cpp b/src/unite/internal/board.cpp
new file mode 100644
index 0000000..c5905f8
--- /dev/null
+++ b/src/unite/internal/board.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
diff --git a/src/unite/internal/board.h b/src/unite/internal/board.h
new file mode 100644
index 0000000..a23db18
--- /dev/null
+++ b/src/unite/internal/board.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_BOARD
+#define FQTERM_UNITE_BOARD
+
+namespace FQTerm {
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/session.cpp b/src/unite/internal/session.cpp
new file mode 100644
index 0000000..6964287
--- /dev/null
+++ b/src/unite/internal/session.cpp
@@ -0,0 +1,138 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#include "state.h"
+#include "fqterm.h"
+#include <QApplication>
+#include <algorithm>
+#include "statebuilder.h"
+namespace FQTerm{
+
+void FQTermUniteSessionContext::write(const QByteArray& str) {
+ session_->write(str);
+}
+
+FQTermUniteSessionContext::FQTermUniteSessionContext(FQTermUniteSession* session) : QObject(session), session_(session) {
+ stateTable_[WELCOME] = new FQTermWelcomeState(this);
+ stateTable_[EXITING] = new FQTermExitState(this);
+ stateTable_[READING] = new FQTermReadingState(this);
+ stateTable_[HELP] = new FQTermHelpState(this);
+ setCurrentState(WELCOME);
+}
+
+void FQTermUniteSessionContext::processInput(const QByteArray& input) {
+ inputBuffer_ += input;
+ while(true) {
+ int consumed = currentState_->processInput(inputBuffer_);
+ inputBuffer_ = inputBuffer_.mid(consumed);
+ if (!consumed || inputBuffer_.size() == 0) {
+ break;
+ }
+ }
+}
+
+void FQTermUniteSessionContext::quit() {
+ session_->quit();
+}
+
+
+
+FQTermUniteState* FQTermUniteSessionContext::setCurrentState(int state, bool init /*= true*/) {
+ StateTableIterator it = stateTable_.find(state);
+ if (it != stateTable_.end()) {
+ currentState_ = it->second;
+ if (init)
+ currentState_->initialize();
+ }
+ return currentState_;
+}
+
+
+
+FQTermUniteSession::FQTermUniteSession(int socketDescriptor ) : context_(NULL) {
+ moveToThread(this);
+ socket_ = new QTcpSocket;
+ FQ_VERIFY(connect(socket_, SIGNAL(readyRead()),
+ this, SLOT(readyRead()),Qt::DirectConnection));
+ FQ_VERIFY(connect(socket_, SIGNAL(disconnected()),
+ this, SLOT(disconnected()),Qt::DirectConnection));
+ FQ_VERIFY(connect(socket_, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
+ this, SLOT(stateChanged(QAbstractSocket::SocketState)),Qt::DirectConnection));
+ FQ_VERIFY(connect(socket_, SIGNAL(error(QAbstractSocket::SocketError)),
+ this, SLOT(error(QAbstractSocket::SocketError)),Qt::DirectConnection));
+
+ // FQ_VERIFY(connect(socket_, SIGNAL(connected()),
+ // this, SLOT(welcome()),Qt::DirectConnection));
+
+ socket_->setSocketDescriptor(socketDescriptor);
+ socket_->moveToThread(this);
+ setTerminationEnabled();
+
+ StateBuilder sb;
+ sb.BuildState();
+}
+
+
+FQTermUniteSession::~FQTermUniteSession() {
+ socket_->close();
+ delete socket_;
+ socket_ = NULL;
+}
+
+void FQTermUniteSession::welcome()
+{
+ context_ = new FQTermUniteSessionContext(this);
+}
+
+void FQTermUniteSession::readyRead() {
+ if (context_) {
+ context_->processInput(socket_->readAll());
+ }
+}
+
+void FQTermUniteSession::write( const QByteArray& output ) {
+ socket_->write(output);
+}
+
+void FQTermUniteSession::run() {
+ welcome();
+ exec();
+ disconnected();
+}
+
+
+void FQTermUniteSession::disconnected() {
+ if (!isRunning())
+ return;
+ quit();
+ moveToThread(QApplication::instance()->thread());
+ deleteLater();
+}
+
+void FQTermUniteSession::stateChanged( QAbstractSocket::SocketState socketState ) {
+}
+
+void FQTermUniteSession::error(QAbstractSocket::SocketError socketError) {
+}
+
+
+}
+
+#include "session.moc" \ No newline at end of file
diff --git a/src/unite/internal/session.h b/src/unite/internal/session.h
new file mode 100644
index 0000000..a5959a1
--- /dev/null
+++ b/src/unite/internal/session.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+#ifndef FQTERM_UNITE_SESSION
+#define FQTERM_UNITE_SESSION
+
+#include <QObject>
+#include <QThread>
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <map>
+namespace FQTerm {
+
+class FQTermUniteState;
+class FQTermUniteSession;
+class FQTermUniteSessionContext : public QObject {
+ Q_OBJECT;
+public:
+ FQTermUniteSessionContext(FQTermUniteSession* session);
+ void write(const QByteArray& str);
+ void processInput(const QByteArray& input);
+ void quit();
+ enum STATE{WELCOME = 0, EXITING = 1, READING = 2, HELP = 3};
+ FQTermUniteState* setCurrentState(int state, bool init = true);
+
+ int row() {return 24;}
+ int column() {return 80;}
+private:
+ FQTermUniteSession* session_;
+ FQTermUniteState* currentState_;
+ QByteArray inputBuffer_;
+ typedef std::map<int, FQTermUniteState*> StateTable;
+ typedef std::map<int, FQTermUniteState*>::iterator StateTableIterator;
+ StateTable stateTable_;
+};
+
+
+class FQTermUniteSession : public QThread {
+ Q_OBJECT;
+public:
+ FQTermUniteSession(int socketDescriptor);
+ ~FQTermUniteSession();
+ void write(const QByteArray& output);
+
+protected:
+ virtual void run();
+ protected slots:
+ void readyRead();
+ void disconnected();
+ void stateChanged(QAbstractSocket::SocketState socketState);
+ void error(QAbstractSocket::SocketError socketError);
+ void welcome();
+private:
+ QTcpSocket* socket_;
+ FQTermUniteSessionContext* context_;
+
+};
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/state.cpp b/src/unite/internal/state.cpp
new file mode 100644
index 0000000..39241b0
--- /dev/null
+++ b/src/unite/internal/state.cpp
@@ -0,0 +1,676 @@
+#include "fqterm.h"
+#include "fqterm_path.h"
+#include <algorithm>
+#include "state.h"
+#include <QDomDocument>
+
+namespace FQTerm{
+
+int FQTermUniteMenu::addEntry( char key )
+{
+ entries_.push_back(tolower(key));
+ return entries_.size() - 1;
+}
+
+int FQTermUniteMenu::findEntry( char key )
+{
+ std::vector<char>::iterator it = std::find(entries_.begin(), entries_.end(), tolower(key));
+ if (it == entries_.end()) {return -1;}
+ return std::distance(entries_.begin(), it);
+}
+
+void FQTermUniteMenu::clearEntry()
+{
+ entries_.clear();
+ clearPointer(current_);
+ current_ = 0;
+}
+
+int FQTermUniteMenu::currentEntry()
+{
+ return current_;
+}
+
+int FQTermUniteMenu::setCurrentEntry( char key )
+{
+ int next = findEntry(key);
+ if (next == -1)
+ return currentEntry();
+ clearPointer(current_);
+ current_ = next;
+ drawPointer(current_);
+ return current_;
+}
+
+int FQTermUniteMenu::setCurrentIndex( int index )
+{
+ clearPointer(current_);
+ current_ = index;
+ drawPointer(current_);
+ return current_;
+}
+
+int FQTermUniteMenu::nextEntry()
+{
+ if (!entries_.size())
+ return current_;
+ clearPointer(current_);
+ current_++;
+ current_ %= entries_.size();
+ drawPointer(current_);
+ return current_;
+}
+
+int FQTermUniteMenu::prevEntry()
+{
+ if (!entries_.size())
+ return current_;
+ clearPointer(current_);
+ current_--;
+ current_ += entries_.size();
+ current_ %= entries_.size();
+ drawPointer(current_);
+ return current_;
+}
+
+
+StateOption FQTermUniteDecode::EscStateMachine::normal_state_[] = {
+ {
+ CHAR_ESC, 0, esc_state_
+ }, {
+ CHAR_NORMAL, &FQTermUniteDecode::normalInput, normal_state_
+ }
+};
+
+// state after a ESC_CHAR
+StateOption FQTermUniteDecode::EscStateMachine::esc_state_[] = {
+ {
+ '[', &FQTermUniteDecode::clearParam, bracket_state_
+ }, {
+ CHAR_ESC, &FQTermUniteDecode::doubleEsc, normal_state_
+ },{
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+// state after ESC [
+StateOption FQTermUniteDecode::EscStateMachine::bracket_state_[] = {
+ {
+ '0', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '1', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '2', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '3', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '4', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '5', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '6', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '7', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '8', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ '9', &FQTermUniteDecode::paramDigit, bracket_state_
+ }, {
+ 'A', &FQTermUniteDecode::cursorUp, normal_state_
+ }, {
+ 'B', &FQTermUniteDecode::cursorDown, normal_state_
+ }, {
+ 'C', &FQTermUniteDecode::cursorRight, normal_state_
+ }, {
+ 'D', &FQTermUniteDecode::cursorLeft, normal_state_
+ }, {
+ '~', &FQTermUniteDecode::functionKey, normal_state_
+ }, {
+ CHAR_NORMAL, 0, normal_state_
+ }
+};
+
+int FQTermUniteDecode::processInput(const QByteArray& input) {
+ data_ = input.data();
+ currentByte_ = 0;
+ inputLength_ = input.size();
+ /*
+ for (int i = 0; i < input.size(); ++i) {
+ bool res = keyReceived(input[i]);
+ if (!res) {
+ return i + 1;
+ }
+ }
+ */
+
+ int i;
+ StateOption *lastState;
+
+ while (currentByte_ < inputLength_) {
+ // current state always be initialized to point to the beginning of three structures
+ // ( normalState, escState, bracketState )
+ i = 0;
+ while (current_state_[i].byte != CHAR_NORMAL && current_state_[i].byte !=
+ data_[currentByte_]) {
+ i++;
+ }
+
+ lastState = current_state_ + i;
+
+ bool stopDecode;
+ if (lastState->action != 0) {
+ stopDecode = (this->*(lastState->action))();
+ }
+
+ // reinit current state
+ current_state_ = lastState->nextState;
+
+ currentByte_++;
+ if (stopDecode)
+ break;
+
+ }
+
+ return currentByte_;
+}
+
+FQTermUniteDecode::FQTermUniteDecode() {
+ current_state_ = EscStateMachine::normal_state_;
+ data_ = NULL;
+ inputLength_ = 0;
+ currentByte_ = 0;
+}
+
+bool FQTermUniteDecode::clearParam() {
+ param_ = -1;
+ return true;
+}
+
+bool FQTermUniteDecode::cursorLeft() {
+ return keyReceived(LEFT);
+}
+
+bool FQTermUniteDecode::cursorDown() {
+ return keyReceived(DOWN);
+}
+
+bool FQTermUniteDecode::cursorRight() {
+ return keyReceived(RIGHT);
+}
+
+bool FQTermUniteDecode::cursorUp() {
+ return keyReceived(UP);
+}
+
+bool FQTermUniteDecode::normalInput() {
+ return keyReceived(data_[currentByte_]);
+}
+
+bool FQTermUniteDecode::doubleEsc() {
+ return keyReceived(DOUBLEESC);
+}
+
+bool FQTermUniteDecode::paramDigit() {
+ if (param_ < 0) {
+ param_ = 0;
+ }
+ param_ = param_ * 10 + (data_[currentByte_] - '0');
+ return true;
+}
+
+bool FQTermUniteDecode::functionKey() {
+ int key;
+ switch (param_) {
+ case 1: key = HOME; break;
+ case 3: key = DELETE; break;
+ case 4: key = END; break;
+ case 5: key = PGUP; break;
+ case 6: key = PGDOWN; break;
+ case 11: key = F1; break;
+ case 12: key = F2; break;
+ case 13: key = F3; break;
+ case 14: key = F4; break;
+ case 15: key = F5; break;
+ case 17: key = F6; break;
+ case 18: key = F7; break;
+ case 19: key = F8; break;
+ case 20: key = F9; break;
+ case 21: key = F10; break;
+ case 23: key = F11; break;
+ case 24: key = F12; break;
+ default:
+ break;
+ }
+ return keyReceived(key);
+}
+
+FQTermUniteState::FQTermUniteState(FQTermUniteSessionContext* context) : context_(context) {
+
+}
+
+void FQTermUniteState::write( const QByteArray& output ) {
+ context_->write(output);
+}
+
+QByteArray FQTermUniteState::escape() {
+ return "\x1b";
+}
+
+void FQTermUniteState::moveCursorRelative(int dx, int dy) {
+ //Esc[ValueA Move cursor up n lines CUU
+ //Esc[ValueB Move cursor down n lines CUD
+ //Esc[ValueC Move cursor right n lines CUF
+ //Esc[ValueD Move cursor left n lines CUB
+ if (dy > 0) {
+ write(escape() + QString("[%1").arg(dy).toLocal8Bit() + "B");
+ }
+ if (dy < 0) {
+ write(escape() + QString("[%1").arg(-dy).toLocal8Bit() + "A");
+ }
+ if (dx > 0) {
+ write(escape() + QString("[%1").arg(dx).toLocal8Bit() + "C");
+ }
+ if (dx < 0) {
+ write(escape() + QString("[%1").arg(-dx).toLocal8Bit() + "D");
+ }
+
+}
+
+
+void FQTermUniteState::moveCursorAbsolute(int x, int y) {
+ //Esc[Line;ColumnH Move cursor to screen location v,h CUP
+ write(escape() + QString("[%1;%2H").arg(y).arg(x).toLocal8Bit());
+}
+
+void FQTermUniteState::moveCursorHome() {
+ write(escape() + "[H");
+}
+
+void FQTermUniteState::scrollWindow(int dy) {
+ //EscD Move/scroll window up one line IND
+ //EscM Move/scroll window down one line RI
+
+ if (dy > 0) {
+ for (int i = 0; i < dy; ++i)
+ write(escape() + "D");
+ }
+ if (dy < 0) {
+ dy = -dy;
+ for (int i = 0; i < dy; ++i)
+ write(escape() + "M");
+ }
+}
+
+void FQTermUniteState::moveCursorNextLine() {
+ //EscE Move to next line NEL
+ write(escape() + "E");
+
+}
+
+void FQTermUniteState::saveCursor() {
+ //Esc7 Save cursor position and attributes DECSC
+ write(escape() + "7");
+}
+
+void FQTermUniteState::restoreCursor() {
+ //Esc8 Restore cursor position and attributes DECSC
+ write(escape() + "8");
+}
+
+void FQTermUniteState::setAttr(int attr) {
+ if (attr == -1) {
+ write(escape() + "[m");
+ } else {
+ write(escape() + QString("[%1m").arg(attr).toLocal8Bit());
+ }
+}
+
+void FQTermUniteState::setForegroundColor(int color, bool highlight /*= true*/) {
+ int hl = highlight?1:0;
+ write(escape() + QString("[%1;3%2m").arg(hl).arg(color).toLocal8Bit());
+}
+
+void FQTermUniteState::setBackgroundColor(int color) {
+ write(escape() + QString("[4%1m").arg(color).toLocal8Bit());
+}
+
+void FQTermUniteState::clearLine(int part) {
+ write(escape() + QString("[%1K").arg(part).toLocal8Bit());
+}
+
+void FQTermUniteState::clearScreen(int part) {
+ write(escape() + QString("[%1J").arg(part).toLocal8Bit());
+}
+
+void FQTermUniteState::setWindowRange(int startLine, int endLine) {
+ write(escape() + QString("[%1;%2r").arg(startLine).arg(endLine).toLocal8Bit());
+}
+
+
+QByteArray FQTermUniteState::cursorStr() {
+ QChar c(0x25c6);
+ QString str(c);
+ return str.toUtf8();
+}
+FQTermWelcomeState::FQTermWelcomeState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) {
+ addEntry('h');
+ addEntry('x');
+}
+
+void FQTermWelcomeState::initialize() {
+ moveCursorHome();
+ clearScreen(WHOLESCREEN);
+
+
+
+ QFile welcomeFile(getPath(RESOURCE) + "unite/welcome");
+ welcomeFile.open(QIODevice::ReadOnly);
+ QByteArray str = welcomeFile.readAll();
+ write(str);
+ setCurrentIndex(currentEntry());
+ return;
+}
+
+bool FQTermWelcomeState::keyReceived(int key) {
+ if (tolower(key) == 'j' || key == UP) {
+ prevEntry();
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ nextEntry();
+ } else if (key == '\r' || key == RIGHT) {
+ enterEntry();
+ return false;
+ } else if (tolower(key) <= 'z' && tolower(key) >= 'a') {
+ setCurrentEntry(key);
+ }
+ return true;
+}
+
+void FQTermWelcomeState::enterEntry() {
+ if (currentEntry() == 1) {
+ setNextState(FQTermUniteSessionContext::EXITING);
+ } else if (currentEntry() == 0) {
+ setNextState(FQTermUniteSessionContext::HELP);
+ }
+}
+
+void FQTermWelcomeState::clearPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(" ");
+ moveCursorHome();
+}
+
+void FQTermWelcomeState::drawPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(cursorStr());
+ moveCursorHome();
+}
+
+
+
+void FQTermExitState::initialize() {
+ clearScreen(WHOLESCREEN);
+ QFile welcomeFile(getPath(RESOURCE) + "unite/exit");
+ welcomeFile.open(QIODevice::ReadOnly);
+ QByteArray str = welcomeFile.readAll();
+ write(str);
+ setCurrentIndex(0);
+}
+
+void FQTermExitState::clearPointer(int index) {
+ moveCursorAbsolute(28, 10 + index);
+ setBackgroundColor(BLUE);
+ write(" ");
+ //moveCursorHome();
+}
+
+void FQTermExitState::drawPointer( int index ) {
+ moveCursorAbsolute(28, 10 + index);
+ setBackgroundColor(BLUE);
+ write(cursorStr());
+ //moveCursorHome();
+}
+
+void FQTermExitState::enterEntry() {
+ if (currentEntry() == 1) {
+ quit();
+ } else {
+ setNextState(FQTermUniteSessionContext::WELCOME);
+ }
+}
+
+bool FQTermExitState::keyReceived( int key )
+{
+ if (tolower(key) == 'j' || key == UP) {
+ prevEntry();
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ nextEntry();
+ } else if (key == '\r') {
+ enterEntry();
+ return false;
+ } else if (key >= '0' && key <= '9') {
+ setCurrentEntry(key);
+ } else if (tolower(key) == 'c') {
+ setCurrentIndex(0);
+ enterEntry();
+ return false;
+ }
+ //moveCursorHome();
+ return true;
+}
+
+FQTermExitState::FQTermExitState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) {
+ addEntry('1');
+ addEntry('2');
+}
+
+SplittedArticleBuffer::SplittedArticleBuffer(const QByteArray& utf8Content, int column, int row) {
+ std::vector<QString> strList;
+ QString content = QString::fromUtf8(utf8Content);
+ lines_.reserve(row);
+ int start = 0;
+ for(;;) {
+ int newStart = findNextLine(content, start, column);
+ if (newStart == -1) {
+ lines_.push_back(content.mid(start).toUtf8());
+ break;
+ } else {
+ lines_.push_back(content.mid(start, newStart - start).toUtf8());
+ start = newStart;
+ }
+ }
+}
+
+int SplittedArticleBuffer::findNextLine(const QString& str, int start, int column) {
+ int count = 0;
+ for (int i = start; i < str.length(); ++i) {
+ if (str[i] == '\t') {
+ count += 2;
+ } else {
+ count += str[i] <= 0x7F ? 1 : 2;
+ }
+ if (count > column) {
+ return i;
+ }
+ if (str[i] == '\n') {
+ if (i + 1 < str.length())
+ return i + 1;
+ }
+ }
+ return -1;
+}
+
+void FQTermReadingState::initialize() {
+ clearScreen(WHOLESCREEN);
+ moveCursorHome();
+ drawLines(row() - 1, 1);
+ drawFooter();
+ moveCursorAbsolute(column(), row());
+}
+
+
+void FQTermReadingState::setFile(const QString& filename) {
+ currentStartLine_ = 0;
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ content_ = file.readAll();
+ delete saBuffer_;
+ saBuffer_ = new SplittedArticleBuffer(content_, column(), row());
+}
+
+FQTermReadingState::FQTermReadingState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) {
+ returnState_ = FQTermUniteSessionContext::WELCOME;
+ currentStartLine_ = 0;
+ saBuffer_ = 0;
+}
+
+bool FQTermReadingState::keyReceived( int key ) {
+ if (tolower(key) == 'q' || key == LEFT || !saBuffer_) {
+ setNextState(returnState_);
+ return false;
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ adjustLineByDiff(1);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (tolower(key) == 'j' || key == UP) {
+ adjustLineByDiff(-1);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == PGDOWN || key == ' ' || key == RIGHT) {
+ adjustLineByDiff(row() - 2);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == PGUP) {
+ adjustLineByDiff(-row() + 2);
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == HOME) {
+ adjustLineByDiff(-saBuffer_->count());
+ drawLines(row() - 1, 1);
+ drawFooter();
+ } else if (key == END) {
+ adjustLineByDiff(saBuffer_->count());
+ drawLines(row() - 1, 1);
+ drawFooter();
+ }
+ return true;
+}
+
+void FQTermReadingState::drawFooter() {
+ if (!saBuffer_)
+ return;
+ cursorGuard(*this);
+ moveCursorAbsolute(1, row());
+ setBackgroundColor(BLUE);
+ QByteArray footer = QString("Current Line: (%1-%2) Total: %3").arg(currentStartLine_ + 1).arg(qMin(saBuffer_->count(), currentStartLine_ + row() - 1)).arg(saBuffer_->count()).toLocal8Bit();
+ footer += QByteArray(column() - footer.size(), ' ');
+ write(footer);
+ setAttr(CLEARATTR);
+}
+
+void FQTermReadingState::adjustLineByDiff(int delta) {
+ if (!saBuffer_)
+ return;
+ currentStartLine_ += delta;
+ if (currentStartLine_ + row() - 1 >= saBuffer_->count())
+ currentStartLine_ = saBuffer_->count() - (row() - 1);
+ if (currentStartLine_ < 0)
+ currentStartLine_ = 0;
+}
+
+
+void FQTermReadingState::drawLines(int count, int yPos) {
+ if (!saBuffer_)
+ return;
+ cursorGuard cg(*this);
+ QByteArray blankLine(column(), ' ');
+ for (int i = 0; i < count; ++i) {
+ moveCursorAbsolute(1, yPos + i);
+ clearLine(WHOLELINE);
+ if (currentStartLine_ + yPos + i - 1 >= saBuffer_->count()) {
+ write(blankLine);
+ } else {
+ write(saBuffer_->retriveLine(currentStartLine_ + yPos + i - 1));
+ }
+ }
+}
+
+FQTermReadingState::~FQTermReadingState() {
+ delete saBuffer_;
+}
+
+
+
+
+
+FQTermHelpState::FQTermHelpState(FQTermUniteSessionContext* context) : FQTermUniteState(context) {
+ addEntry('s'); //0.entry for script
+ addEntry('t'); //1.entry for shortcut
+ addEntry('u'); //2.entry for unix host
+ addEntry('x'); //3.entry for quit to welcome
+}
+
+void FQTermHelpState::initialize() {
+ moveCursorHome();
+ clearScreen(WHOLESCREEN);
+ QFile welcomeFile(getPath(RESOURCE) + "unite/help");
+ welcomeFile.open(QIODevice::ReadOnly);
+ QByteArray str = welcomeFile.readAll();
+ write(str);
+ setCurrentIndex(currentEntry());
+ return;
+}
+
+bool FQTermHelpState::keyReceived(int key) {
+ if (tolower(key) == 'j' || key == UP) {
+ prevEntry();
+ } else if (tolower(key) == 'k' || key == DOWN) {
+ nextEntry();
+ } else if (key == '\r' || key == RIGHT) {
+ enterEntry();
+ return false;
+ } else if (tolower(key) <= 'z' && tolower(key) >= 'a') {
+ setCurrentEntry(key);
+ }
+ return true;
+}
+
+void FQTermHelpState::enterEntry() {
+ if (currentEntry() == 3) {
+ setNextState(FQTermUniteSessionContext::WELCOME);
+ return;
+ }
+
+ QString doc;
+ switch(currentEntry())
+ {
+ case 0:
+ doc = "script-doc";
+ break;
+ case 1:
+ doc = "shortcut-doc";
+ break;
+ case 2:
+ doc = "ssh-unix-doc";
+ break;
+ }
+ FQTermUniteState* reader = setNextState(FQTermUniteSessionContext::READING, false);
+ ((FQTermReadingState*)reader)->setFile(getPath(RESOURCE) + "unite/" + doc);
+ ((FQTermReadingState*)reader)->setReturnState(FQTermUniteSessionContext::HELP);
+ reader->initialize();
+}
+
+void FQTermHelpState::clearPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(" ");
+ moveCursorHome();
+}
+
+void FQTermHelpState::drawPointer(int index) {
+ moveCursorAbsolute(7, 11 + index);
+ write(cursorStr());
+ moveCursorHome();
+}
+
+} // namespace FQTerm
+
+#include "state.moc" \ No newline at end of file
diff --git a/src/unite/internal/state.h b/src/unite/internal/state.h
new file mode 100644
index 0000000..e294372
--- /dev/null
+++ b/src/unite/internal/state.h
@@ -0,0 +1,219 @@
+#ifndef FQTERM_UNITE_STATE
+#define FQTERM_UNITE_STATE
+
+#include <QByteArray>
+#include "session.h"
+
+namespace FQTerm {
+class FQTermUniteDecode;
+typedef bool (FQTermUniteDecode:: *StateFunc)();
+
+struct StateOption {
+ int byte; // char value to look for; -1==end/default
+ StateFunc action;
+ StateOption *nextState;
+};
+
+
+
+class FQTermUniteDecode {
+public:
+ FQTermUniteDecode();
+ virtual ~FQTermUniteDecode() {}
+ //should return number of chars consumed
+ virtual int processInput(const QByteArray& input);
+protected:
+ virtual bool keyReceived(int key) = 0;
+ //tab = 7, backspace = 8, delete is *[3~, page up is 5~, page down is 6~, home is 1~, end is 4~, double esc is double esc,
+ //up is A, down is B, left is D, right is C.
+ //F1 - F12 11~ 12~ 13~ 14~ 15~ 17~ 18~ 19~ 20~ 21~ 23~ 24~
+ //static char* specialKeys[];
+ enum SPECIALKEY{SPECIALKEYSTART = 0x10000, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
+ UP, DOWN, LEFT, RIGHT, DOUBLEESC, INSERT, HOME, END, PGUP, PGDOWN, DELETE};
+
+ // Virtual Keys: move cursor
+ bool cursorLeft();
+ bool cursorDown();
+ bool cursorRight();
+ bool cursorUp();
+
+ // other escape sequence actions
+ bool normalInput();
+
+ //double esc pressed
+ bool doubleEsc();
+
+ // action parameters
+ bool clearParam();
+ bool paramDigit();
+ //function key map
+ bool functionKey();
+private:
+ // ********** decoder states ****************
+ StateOption *current_state_;
+ int param_; //valid when > 0.
+ const char* data_;
+ int inputLength_;
+ int currentByte_;
+ QByteArray leftToDecode_;
+ struct EscStateMachine {
+ static StateOption normal_state_[], esc_state_[], bracket_state_[];
+ };
+};
+
+class FQTermUniteState : public QObject,
+ public FQTermUniteDecode {
+ Q_OBJECT;
+public:
+ FQTermUniteState(FQTermUniteSessionContext* context);
+ virtual ~FQTermUniteState() {}
+ virtual void initialize() = 0;
+
+
+protected:
+ //util functions
+ //cursor manipulations
+ void moveCursorRelative(int dx, int dy);
+ void moveCursorAbsolute(int x, int y);
+ void moveCursorHome();
+ //To scroll up, dy < 0, scroll down, dy > 0.
+ void scrollWindow(int dy);
+ void moveCursorNextLine();
+ void saveCursor();
+ void restoreCursor();
+
+ //attr control
+ enum CHARATTR{DEFAULTATTR = -1, CLEARATTR = 0, BOLD = 1, LOWINTENSITY = 2, UNDERLINE = 4, BLINK = 5, REVERSECOLOR = 7, INVISIBLE = 8};
+ void setAttr(int attr);
+ enum CHARCOLOR{BLACK = 0, RED = 1, GREEN = 2, YELLOW = 3, BLUE = 4, PURPLE = 5, INDIGO = 6, WHITE = 7};
+ void setForegroundColor(int color, bool highlight = true);
+ void setBackgroundColor(int color);
+
+ //clear lines/screen
+ enum CLEARLINE{CURSORRIGHT = 0, CURSORLEFT = 1, WHOLELINE = 2};
+ void clearLine(int part);
+ enum CLEARSCREEN{CURSORDOWN = 0, CURSORUP = 1, WHOLESCREEN = 2};
+ void clearScreen(int part);
+
+ //window setting
+ void setWindowRange(int startLine, int endLine);
+
+ QByteArray escape();
+ QByteArray cursorStr();
+ void write(const QByteArray& output);
+ void quit() {context_->quit();}
+ FQTermUniteState* setNextState(int state, bool init = true) {return context_->setCurrentState(state, init);}
+ int row() {return context_->row();}
+ int column() {return context_->column();}
+
+
+ friend struct cursorGuard;
+ struct cursorGuard {
+ cursorGuard(FQTermUniteState& state) : state_(state) {state_.saveCursor();}
+ ~cursorGuard() {state_.restoreCursor();}
+ private:
+ FQTermUniteState& state_;
+ };
+private:
+ FQTermUniteSessionContext* context_;
+ int lastState_;
+};
+
+class FQTermUniteMenu {
+public:
+ FQTermUniteMenu() {current_ = 0;}
+ virtual ~FQTermUniteMenu() {}
+protected:
+ int addEntry(char key);
+ int findEntry(char key);
+ void clearEntry();
+ int currentEntry();
+ int setCurrentEntry(char key);
+ int setCurrentIndex(int index);
+
+ int nextEntry();
+ int prevEntry();
+ virtual void clearPointer(int index) = 0;
+ virtual void drawPointer(int index) = 0;
+ virtual void enterEntry() = 0;
+private:
+ std::vector<char> entries_;
+ int current_;
+};
+
+
+class FQTermWelcomeState : public FQTermUniteState, public FQTermUniteMenu {
+ Q_OBJECT;
+public:
+ FQTermWelcomeState(FQTermUniteSessionContext* context);
+ virtual void initialize();
+protected:
+ virtual bool keyReceived(int key);
+private:
+ virtual void clearPointer(int index);
+ virtual void drawPointer(int index);
+ virtual void enterEntry();
+};
+
+class FQTermExitState : public FQTermUniteState, public FQTermUniteMenu {
+ Q_OBJECT;
+public:
+ FQTermExitState(FQTermUniteSessionContext* context);
+ virtual void initialize();
+protected:
+ virtual bool keyReceived(int key);
+private:
+ virtual void clearPointer(int index);
+ virtual void drawPointer(int index);
+ void enterEntry();
+};
+
+class SplittedArticleBuffer {
+public:
+ SplittedArticleBuffer(const QByteArray& utf8Content, int column, int row = 24);
+ ~SplittedArticleBuffer() {}
+ int count() {return lines_.size();}
+ QByteArray& retriveLine(size_t index) {return lines_[index];}
+private:
+ static int findNextLine(const QString& str, int start, int column);
+ std::vector<QByteArray> lines_;
+};
+
+//TODO: content should be shared.
+//TODO: buffer should be opt-ed.
+class FQTermReadingState : public FQTermUniteState {
+ Q_OBJECT;
+public:
+ FQTermReadingState(FQTermUniteSessionContext* context);
+ ~FQTermReadingState();
+ virtual void initialize();
+ void setFile(const QString& filename);
+ void setReturnState(int state) {returnState_ = state;}
+protected:
+ virtual bool keyReceived(int key);
+private:
+ void drawLines(int count, int yPos);
+ void drawFooter();
+ void adjustLineByDiff(int delta);
+ SplittedArticleBuffer* saBuffer_;
+ QByteArray content_;
+ int currentStartLine_;
+ int returnState_;
+};
+
+
+class FQTermHelpState : public FQTermUniteState, public FQTermUniteMenu {
+ Q_OBJECT;
+public:
+ FQTermHelpState(FQTermUniteSessionContext* context);
+ virtual void initialize();
+protected:
+ virtual bool keyReceived(int key);
+private:
+ virtual void clearPointer(int index);
+ virtual void drawPointer(int index);
+ virtual void enterEntry();
+};
+
+} // namespace FQTerm
+#endif \ No newline at end of file
diff --git a/src/unite/internal/statebuilder.cpp b/src/unite/internal/statebuilder.cpp
new file mode 100644
index 0000000..48ea6f6
--- /dev/null
+++ b/src/unite/internal/statebuilder.cpp
@@ -0,0 +1,32 @@
+
+#include "statebuilder.h"
+#include "fqterm.h"
+#include "fqterm_path.h"
+
+#include <QDomDocument>
+#include <QFile>
+
+namespace FQTerm {
+
+void StateBuilder::BuildState()
+{
+ QDomDocument domDocument;
+ QFile welcome(getPath(RESOURCE) + "unite/welcom.xml");
+ welcome.open(QIODevice::ReadOnly);
+ QString errorStr;
+ int errorLine;
+ int errorColumn;
+ domDocument.setContent(welcome.readAll(), true, &errorStr, &errorLine, &errorColumn);
+ QDomElement root = domDocument.firstChildElement("page");
+ if (root.isNull())
+ {
+
+ }
+ QDomAttr a = root.attributeNode("type");
+ //cout << a.value() << endl;
+
+
+}
+
+
+} \ No newline at end of file
diff --git a/src/unite/internal/statebuilder.h b/src/unite/internal/statebuilder.h
new file mode 100644
index 0000000..f323ecd
--- /dev/null
+++ b/src/unite/internal/statebuilder.h
@@ -0,0 +1,16 @@
+
+#ifndef FQTERM_UNITE_STATEBUILDER
+#define FQTERM_UNITE_STATEBUILDER
+
+namespace FQTerm {
+
+class FQTermState;
+
+class StateBuilder
+{
+public:
+ void BuildState();
+};
+
+}
+#endif \ No newline at end of file
diff --git a/src/unite/internal/unite.h b/src/unite/internal/unite.h
new file mode 100644
index 0000000..cc614a7
--- /dev/null
+++ b/src/unite/internal/unite.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_USER
+#define FQTERM_UNITE_USER
+
+namespace FQTerm {
+//to make it more clear, a general method to serialize c++
+//classes is needed.
+class FQUUser {
+public:
+private:
+
+};
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/unite/internal/user.cpp b/src/unite/internal/user.cpp
new file mode 100644
index 0000000..c5905f8
--- /dev/null
+++ b/src/unite/internal/user.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
diff --git a/src/unite/internal/user.h b/src/unite/internal/user.h
new file mode 100644
index 0000000..cc614a7
--- /dev/null
+++ b/src/unite/internal/user.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+* fqterm, a terminal emulator for both BBS and *nix. *
+* Copyright (C) 2008 fqterm development group. *
+* *
+* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+***************************************************************************/
+
+#ifndef FQTERM_UNITE_USER
+#define FQTERM_UNITE_USER
+
+namespace FQTerm {
+//to make it more clear, a general method to serialize c++
+//classes is needed.
+class FQUUser {
+public:
+private:
+
+};
+
+} //namespace FQTerm
+
+#endif //FQTERM_UNITE_USER \ No newline at end of file
diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt
new file mode 100644
index 0000000..af3c169
--- /dev/null
+++ b/src/utilities/CMakeLists.txt
@@ -0,0 +1,33 @@
+set(fqterm_utilities_SRCS
+ fqterm_convert.h
+ fqterm_http.h
+ fqterm_ip_location.h
+ fqterm_convert.cpp
+ fqterm_http.cpp
+ fqterm_ip_location.cpp
+)
+
+set(fq_SRCS
+ fqwcwidth.h
+ fqwcwidth.cpp
+)
+
+qt4_automoc(${fqterm_utilities_SRCS})
+
+include_directories(
+ ${QT_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
+ ${QT_QTGUI_INCLUDE_DIR}
+ ${QT_QTNETWORK_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+add_library(fqterm_utilities
+ ${fqterm_utilities_SRCS}
+ ${fq_SRCS}
+)
+
+add_dependencies(fqterm_utilities
+ fqterm_common
+)
diff --git a/src/utilities/fqterm_convert.cpp b/src/utilities/fqterm_convert.cpp
new file mode 100644
index 0000000..3ac821d
--- /dev/null
+++ b/src/utilities/fqterm_convert.cpp
@@ -0,0 +1,3485 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_convert.h"
+
+namespace FQTerm {
+
+const char BtoG_bad1 = '\xa1';
+const char BtoG_bad2 = '\xf5';
+const char GtoB_bad1 = '\xa1';
+const char GtoB_bad2 = '\xbc';
+
+#define HIGHBYTE(word) (word)>>8 & 0x00ff
+#define LOWBYTE(word) (word) & 0x00ff
+#define MAKEWORD(c1,c2) ( (c1)<<8 & 0xff00 ) | c2
+FQTermConvert::FQTermConvert(){}
+
+FQTermConvert::~FQTermConvert(){}
+
+char *FQTermConvert::G2B(const char *string, int length) {
+ static char save = '\0';
+ if (length == 0) {
+ return 0;
+ }
+ char *s = new char[length + 2]; //because we may have the save char
+ int len = length;
+ const char *p = string;
+ int n = 0;
+
+ if (save != '\0') {
+ g2b(save, *p, s);
+ n = 2;
+ p++;
+ save = '\0';
+ len++;
+ }
+
+ while (p < string + length && *p != '\0') {
+ if (*p &0x80) {
+ // reach the end this is half of a word, save it
+ if (p == string + length - 1) {
+ save = *p;
+ len--;
+ break;
+ }
+
+ g2b(*p, *(p + 1), s + n);
+ n += 2;
+ p += 2;
+ } else {
+ s[n] = *p;
+ p++;
+ n++;
+ }
+ }
+
+ s[len] = '\0';
+ return s;
+}
+
+void FQTermConvert::g2b(unsigned char c1, unsigned char c2, char *s) {
+ unsigned int i;
+ if ((c2 >= 0xa1) && (c2 <= 0xfe)) {
+ if ((c1 >= 0xa1) && (c1 <= 0xa9)) {
+ i = ((c1 - 0xa1) *94+(c2 - 0xa1)) *2;
+ s[0] = GtoB[i++];
+ s[1] = GtoB[i];
+ return ;
+ } else if ((c1 >= 0xb0) && (c1 <= 0xf7)) {
+ i = ((c1 - 0xb0 + 9) *94+(c2 - 0xa1)) *2;
+ s[0] = GtoB[i++];
+ s[1] = GtoB[i];
+ return ;
+ }
+ }
+ s[0] = GtoB_bad1;
+ s[1] = GtoB_bad2;
+}
+
+char *FQTermConvert::B2G(const char *string, int length) {
+ static char save = '\0';
+ if (length == 0) {
+ return 0;
+ }
+ char *s = new char[length + 2]; //because we may have the save char
+ int len = length;
+ const char *p = string;
+ int n = 0;
+
+ if (save != '\0') {
+ b2g(save, *p, s);
+ n = 2;
+ p++;
+ save = '\0';
+ len++;
+ }
+
+ while (p < string + length && *p != '\0') {
+ if (*p &0x80) {
+ // reach the end this is half of a word, save it
+ if (p == string + length - 1) {
+ save = *p;
+ len--;
+ break;
+ }
+
+ b2g(*p, *(p + 1), s + n);
+ p += 2;
+ n += 2;
+ } else {
+ s[n] = *p;
+ p++;
+ n++;
+ }
+ }
+
+ s[len] = '\0';
+ return s;
+}
+
+void FQTermConvert::b2g(unsigned char c1, unsigned char c2, char *s) {
+ unsigned int i;
+ if ((c1 >= 0xa1) && (c1 <= 0xf9)) {
+ if ((c2 >= 0x40) && (c2 <= 0x7e)) {
+ i = ((c1 - 0xa1) *157+(c2 - 0x40)) *2;
+ s[0] = BtoG[i++];
+ s[1] = BtoG[i];
+ return ;
+ } else if ((c2 >= 0xa1) && (c2 <= 0xfe)) {
+ i = ((c1 - 0xa1) *157+(c2 - 0xa1) + 63) *2;
+ s[0] = BtoG[i++];
+ s[1] = BtoG[i];
+ return ;
+ }
+ }
+ s[0] = BtoG_bad1;
+ s[1] = BtoG_bad2;
+}
+
+unsigned char FQTermConvert::GtoB[] = {
+ 0xa1, 0x40, 0xa1, 0x42, 0xa1, 0x43, 0xa1, 0x4f, 0xa1, 0xc2, 0xa1, 0xbc, 0xa1,
+ 0x4c, 0xa1, 0xb2, 0xa1, 0xbc, 0xa2, 0x77, 0xa1, 0xe3, 0xa1, 0xfc, 0xa1, 0x4b,
+ 0xa1, 0xa5, 0xa1, 0xa6, 0xa1, 0xa7, 0xa1, 0xa8, 0xa1, 0x65, 0xa1, 0x66, 0xa1,
+ 0x71, 0xa1, 0x72, 0xa1, 0x6d, 0xa1, 0x6e, 0xa1, 0x75, 0xa1, 0x76, 0xa1, 0x79,
+ 0xa1, 0x7a, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0x69, 0xa1, 0x6a, 0xa1, 0xd3, 0xa1,
+ 0xd1, 0xa1, 0xd2, 0xa1, 0x4a, 0xa3, 0x4e, 0xa1, 0xbc, 0xa3, 0x55, 0xa3, 0x53,
+ 0xa1, 0xe5, 0xa1, 0xe4, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xd4, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xe7, 0xa1, 0xbc, 0xa1, 0xf3, 0xa1, 0xec, 0xa1, 0xed, 0xa1, 0xdd,
+ 0xa1, 0xbc, 0xa1, 0xdc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xda, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xd8, 0xa1, 0xd9, 0xa1, 0xdb, 0xa1, 0xee, 0xa1, 0xef, 0xa1, 0xf1,
+ 0xa1, 0xf0, 0xa2, 0x58, 0xa1, 0xac, 0xa1, 0xaa, 0xa2, 0x4a, 0xa2, 0x43, 0xa1,
+ 0xbc, 0xa2, 0x46, 0xa2, 0x47, 0xa1, 0xbc, 0xa1, 0xb1, 0xa1, 0xbc, 0xa1, 0xb8,
+ 0xa1, 0xb9, 0xa1, 0xb3, 0xa1, 0xb4, 0xa1, 0xb7, 0xa1, 0xba, 0xa1, 0xbb, 0xa1,
+ 0xbc, 0xa1, 0xbd, 0xa1, 0xb5, 0xa1, 0xb6, 0xa1, 0xb0, 0xa1, 0xf7, 0xa1, 0xf6,
+ 0xa1, 0xf4, 0xa1, 0xf5, 0xa2, 0xa4, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0xb9, 0xa2,
+ 0xba, 0xa2, 0xbb, 0xa2, 0xbc, 0xa2, 0xbd, 0xa2, 0xbe, 0xa2, 0xbf, 0xa2, 0xc0,
+ 0xa2, 0xc1, 0xa2, 0xc2, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0x49, 0xa1, 0xa9, 0xa1, 0xad, 0xa2, 0x43, 0xa2, 0x48, 0xa1, 0xae, 0xa1, 0xac,
+ 0xa1, 0x5d, 0xa1, 0x5e, 0xa1, 0xaf, 0xa1, 0xcf, 0xa1, 0x41, 0xa1, 0xd0, 0xa1,
+ 0x44, 0xa1, 0xfe, 0xa2, 0xaf, 0xa2, 0xb0, 0xa2, 0xb1, 0xa2, 0xb2, 0xa2, 0xb3,
+ 0xa2, 0xb4, 0xa2, 0xb5, 0xa2, 0xb6, 0xa2, 0xb7, 0xa2, 0xb8, 0xa1, 0x47, 0xa1,
+ 0x46, 0xa1, 0xd5, 0xa1, 0xd7, 0xa1, 0xd6, 0xa1, 0x48, 0xa2, 0x49, 0xa2, 0xcf,
+ 0xa2, 0xd0, 0xa2, 0xd1, 0xa2, 0xd2, 0xa2, 0xd3, 0xa2, 0xd4, 0xa2, 0xd5, 0xa2,
+ 0xd6, 0xa2, 0xd7, 0xa2, 0xd8, 0xa2, 0xd9, 0xa2, 0xda, 0xa2, 0xdb, 0xa2, 0xdc,
+ 0xa2, 0xdd, 0xa2, 0xde, 0xa2, 0xdf, 0xa2, 0xe0, 0xa2, 0xe1, 0xa2, 0xe2, 0xa2,
+ 0xe3, 0xa2, 0xe4, 0xa2, 0xe5, 0xa2, 0xe6, 0xa2, 0xe7, 0xa2, 0xe8, 0xa1, 0xa3,
+ 0xa2, 0x40, 0xa1, 0xa4, 0xa1, 0x73, 0xa1, 0x5a, 0xa1, 0xab, 0xa2, 0xe9, 0xa2,
+ 0xea, 0xa2, 0xeb, 0xa2, 0xec, 0xa2, 0xed, 0xa2, 0xee, 0xa2, 0xef, 0xa2, 0xf0,
+ 0xa2, 0xf1, 0xa2, 0xf2, 0xa2, 0xf3, 0xa2, 0xf4, 0xa2, 0xf5, 0xa2, 0xf6, 0xa2,
+ 0xf7, 0xa2, 0xf8, 0xa2, 0xf9, 0xa2, 0xfa, 0xa2, 0xfb, 0xa2, 0xfc, 0xa2, 0xfd,
+ 0xa2, 0xfe, 0xa3, 0x40, 0xa3, 0x41, 0xa3, 0x42, 0xa3, 0x43, 0xa1, 0x61, 0xa1,
+ 0x55, 0xa1, 0x62, 0xa1, 0xc2, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa3, 0x44, 0xa3, 0x45, 0xa3, 0x46, 0xa3, 0x47, 0xa3,
+ 0x48, 0xa3, 0x49, 0xa3, 0x4a, 0xa3, 0x4b, 0xa3, 0x4c, 0xa3, 0x4d, 0xa3, 0x4e,
+ 0xa3, 0x4f, 0xa3, 0x50, 0xa3, 0x51, 0xa3, 0x52, 0xa3, 0x53, 0xa3, 0x54, 0xa3,
+ 0x55, 0xa3, 0x56, 0xa3, 0x57, 0xa3, 0x58, 0xa3, 0x59, 0xa3, 0x5a, 0xa3, 0x5b,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa3, 0x5c, 0xa3, 0x5d, 0xa3, 0x5e, 0xa3, 0x5f, 0xa3, 0x60,
+ 0xa3, 0x61, 0xa3, 0x62, 0xa3, 0x63, 0xa3, 0x64, 0xa3, 0x65, 0xa3, 0x66, 0xa3,
+ 0x67, 0xa3, 0x68, 0xa3, 0x69, 0xa3, 0x6a, 0xa3, 0x6b, 0xa3, 0x6c, 0xa3, 0x6d,
+ 0xa3, 0x6e, 0xa3, 0x6f, 0xa3, 0x70, 0xa3, 0x71, 0xa3, 0x72, 0xa3, 0x73, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa3, 0x74, 0xa3,
+ 0x75, 0xa3, 0x76, 0xa3, 0x77, 0xa3, 0x78, 0xa3, 0x79, 0xa3, 0x7a, 0xa3, 0x7b,
+ 0xa3, 0x7c, 0xa3, 0x7d, 0xa3, 0x7e, 0xa3, 0xa1, 0xa3, 0xa2, 0xa3, 0xa3, 0xa3,
+ 0xa4, 0xa3, 0xa5, 0xa3, 0xa6, 0xa3, 0xa7, 0xa3, 0xa8, 0xa3, 0xa9, 0xa3, 0xaa,
+ 0xa3, 0xab, 0xa3, 0xac, 0xa3, 0xad, 0xa3, 0xae, 0xa3, 0xaf, 0xa3, 0xb0, 0xa3,
+ 0xb1, 0xa3, 0xb2, 0xa3, 0xb3, 0xa3, 0xb4, 0xa3, 0xb5, 0xa3, 0xb6, 0xa3, 0xb7,
+ 0xa3, 0xb8, 0xa3, 0xb9, 0xa3, 0xba, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa2, 0x77, 0xa1, 0xbc, 0xa2, 0x78, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa2, 0x7a, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x7b, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa2, 0x7c, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x7d,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x75, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x74, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2,
+ 0x73, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa2, 0x72, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa2, 0x71, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xb0, 0xda, 0xaa, 0xfc, 0xae, 0x4a, 0xae, 0xc1, 0xab, 0x75, 0xad,
+ 0xfc, 0xab, 0x73, 0xbd, 0x4a, 0xc0, 0xf9, 0xc4, 0xa7, 0xb8, 0x47, 0xa6, 0xe3,
+ 0xc3, 0xaa, 0xb7, 0x52, 0xb9, 0x69, 0xbe, 0x62, 0xae, 0xf2, 0xa6, 0x77, 0xad,
+ 0xcd, 0xab, 0xf6, 0xb7, 0x74, 0xa9, 0xa4, 0xd3, 0x69, 0xae, 0xd7, 0xbb, 0xea,
+ 0xa9, 0xf9, 0xaf, 0x73, 0xa5, 0x57, 0xb1, 0xce, 0xbc, 0xf5, 0xbf, 0xac, 0xc3,
+ 0xcd, 0xb6, 0xc6, 0xb6, 0xf8, 0xbe, 0xd2, 0xbf, 0x44, 0xaa, 0xdd, 0xae, 0xc3,
+ 0xa5, 0xb6, 0xa5, 0x7a, 0xa7, 0x61, 0xaf, 0xb9, 0xa4, 0x4b, 0xac, 0xcd, 0xa4,
+ 0xda, 0xa9, 0xde, 0xb6, 0x5b, 0xb9, 0x76, 0xa7, 0xe2, 0xaf, 0xd2, 0xc5, 0xf2,
+ 0xc5, 0x51, 0xbd, 0x7d, 0xaa, 0xa8, 0xa5, 0xd5, 0xac, 0x66, 0xa6, 0xca, 0xc2,
+ 0x5c, 0xa8, 0xd5, 0xb1, 0xd1, 0xab, 0xf4, 0xde, 0xfb, 0xb4, 0xb3, 0xaf, 0x5a,
+ 0xb7, 0x68, 0xa7, 0xe6, 0xaf, 0xeb, 0xb9, 0x7b, 0xaa, 0x4f, 0xaa, 0xa9, 0xa7,
+ 0xea, 0xa9, 0xd5, 0xa6, 0xf1, 0xc3, 0xa4, 0xa5, 0x62, 0xbf, 0xec, 0xb2, 0xcc,
+ 0xa8, 0xb9, 0xc0, 0xb0, 0xb1, 0xf5, 0xba, 0x5d, 0xbb, 0x48, 0xb8, 0x6a, 0xb4,
+ 0xce, 0xbd, 0x53, 0xb0, 0x46, 0xc2, 0xe9, 0xb3, 0xc4, 0xc1, 0xbd, 0xad, 0x63,
+ 0xad, 0x4d, 0xa5, 0x5d, 0xbd, 0xc7, 0xad, 0xe9, 0xc1, 0xa1, 0xb9, 0x72, 0xab,
+ 0x4f, 0xb3, 0xf9, 0xb9, 0xa1, 0xc4, 0x5f, 0xa9, 0xea, 0xb3, 0xf8, 0xbc, 0xc9,
+ 0xb0, 0x5c, 0xc0, 0x6a, 0xc3, 0x7a, 0xaa, 0x4d, 0xb8, 0x4f, 0xb4, 0x64, 0xa8,
+ 0xf5, 0xa5, 0x5f, 0xbd, 0xfa, 0xad, 0x49, 0xa8, 0xa9, 0xbe, 0x58, 0xad, 0xbf,
+ 0xaf, 0x56, 0xb3, 0xc6, 0xbe, 0xce, 0xb5, 0x48, 0xb3, 0x51, 0xa9, 0x62, 0xad,
+ 0x66, 0xa5, 0xbb, 0xb2, 0xc2, 0xb1, 0x59, 0xc1, 0x5e, 0xac, 0xc7, 0xac, 0xa6,
+ 0xc2, 0xdb, 0xb0, 0x6e, 0xb9, 0x47, 0xbb, 0xf3, 0xa4, 0xf1, 0xbb, 0xc0, 0xb5,
+ 0xa7, 0xa9, 0xbc, 0xba, 0xd1, 0xe3, 0xc9, 0xbd, 0xaa, 0xb2, 0xa6, 0xc0, 0xc5,
+ 0xcf, 0x68, 0xb9, 0xf4, 0xa7, 0xc8, 0xde, 0xcd, 0xb3, 0xac, 0xb1, 0xcd, 0xb9,
+ 0xfa, 0xa5, 0xb2, 0xb9, 0x40, 0xbe, 0xc0, 0xc1, 0x75, 0xc1, 0xd7, 0xb0, 0xa1,
+ 0xc3, 0x40, 0xc3, 0xe4, 0xbd, 0x73, 0xb6, 0x53, 0xab, 0xf3, 0xab, 0x4b, 0xc5,
+ 0xdc, 0xa4, 0xcb, 0xbf, 0xeb, 0xc5, 0x47, 0xc4, 0x7c, 0xb9, 0x4d, 0xbc, 0xd0,
+ 0xb3, 0x43, 0xbd, 0xa8, 0xaa, 0xed, 0xc5, 0xbe, 0xe5, 0x78, 0xa7, 0x4f, 0xc3,
+ 0xa7, 0xb1, 0x6c, 0xd9, 0x79, 0xc3, 0x78, 0xc0, 0xd8, 0xbb, 0xab, 0xec, 0xe8,
+ 0xa7, 0x4c, 0xa6, 0x42, 0xac, 0x60, 0xa4, 0xfe, 0xaa, 0xc3, 0xbb, 0xe6, 0xac,
+ 0xb1, 0xaf, 0x66, 0xa8, 0xc3, 0xac, 0xc1, 0xb5, 0xd4, 0xbc, 0xbd, 0xbc, 0xb7,
+ 0xd2, 0xdc, 0xaa, 0x69, 0xb3, 0xd5, 0xab, 0x6b, 0xb7, 0x69, 0xb9, 0x60, 0xba,
+ 0xe4, 0xa7, 0x42, 0xa9, 0xad, 0xb2, 0xed, 0xb2, 0xe4, 0xbb, 0x4b, 0xb4, 0xf1,
+ 0xaa, 0x79, 0xbb, 0xe9, 0xae, 0xb7, 0xa4, 0x52, 0xad, 0xf7, 0xb8, 0xc9, 0xb0,
+ 0xf0, 0xa4, 0xa3, 0xa5, 0xac, 0xa8, 0x42, 0xc3, 0xaf, 0xb3, 0xa1, 0xa9, 0xc6,
+ 0xc0, 0xbf, 0xb2, 0x71, 0xb5, 0xf4, 0xa7, 0xf7, 0xa4, 0x7e, 0xb0, 0x5d, 0xb8,
+ 0x42, 0xbd, 0xf2, 0xb1, 0xc4, 0xb1, 0x6d, 0xb5, 0xe6, 0xbd, 0xb2, 0xc0, 0x5c,
+ 0xb0, 0xd1, 0xc5, 0xfa, 0xb4, 0xdd, 0xba, 0x46, 0xba, 0x47, 0xc0, 0xe9, 0xbb,
+ 0x61, 0xbf, 0xb5, 0xad, 0xdc, 0xb7, 0xc9, 0xc2, 0xc3, 0xbe, 0xde, 0xc1, 0x57,
+ 0xbc, 0xd1, 0xb1, 0xe4, 0xaf, 0xf3, 0xb4, 0x5a, 0xb5, 0xa6, 0xb0, 0xbc, 0xa5,
+ 0x55, 0xb4, 0xfa, 0xbc, 0x68, 0xf3, 0x4f, 0xb4, 0xa1, 0xa4, 0x65, 0xd3, 0xb3,
+ 0xaf, 0xf9, 0xac, 0x64, 0xe2, 0xed, 0xb7, 0x67, 0xb9, 0xee, 0xa7, 0xc3, 0xae,
+ 0x74, 0xb8, 0xd2, 0xa9, 0xee, 0xae, 0xe3, 0xb0, 0x5b, 0xc4, 0x65, 0xba, 0x55,
+ 0xc2, 0xcd, 0xc6, 0x61, 0xc5, 0xfe, 0xc4, 0xf1, 0xc3, 0xea, 0xb2, 0xa3, 0xc4,
+ 0xc4, 0xc5, 0xb8, 0xa9, 0xf7, 0xb2, 0x73, 0xb3, 0xf5, 0xb9, 0xc1, 0xb1, 0x60,
+ 0xaa, 0xf8, 0xc0, 0x76, 0xb8, 0x7a, 0xbc, 0x74, 0xb4, 0xaf, 0xba, 0x5a, 0xb0,
+ 0xdb, 0xad, 0xd2, 0xb6, 0x57, 0xa7, 0xdb, 0xb6, 0x72, 0xb4, 0xc2, 0xbc, 0x4a,
+ 0xbc, 0xe9, 0xb1, 0x5f, 0xa7, 0x6e, 0xaa, 0xa3, 0xa8, 0xae, 0xa7, 0xe8, 0xba,
+ 0x4d, 0xb4, 0x77, 0xb9, 0xfd, 0xba, 0xab, 0xd7, 0xeb, 0xa6, 0xda, 0xa8, 0xb0,
+ 0xb9, 0xd0, 0xb1, 0xe1, 0xa7, 0xd5, 0xa8, 0x49, 0xb3, 0xaf, 0xb6, 0x58, 0xc5,
+ 0xa8, 0xbc, 0xb5, 0xba, 0xd9, 0xab, 0xb0, 0xbe, 0xed, 0xa6, 0xa8, 0xa7, 0x65,
+ 0xad, 0xbc, 0xb5, 0x7b, 0xc3, 0x67, 0xbc, 0xe1, 0xb8, 0xdb, 0xa9, 0xd3, 0xb3,
+ 0x78, 0xc1, 0xfe, 0xaf, 0xaf, 0xa6, 0x59, 0xb7, 0xf6, 0xab, 0xf9, 0xb0, 0xcd,
+ 0xa6, 0xc0, 0xbf, 0xf0, 0xa6, 0xa2, 0xb9, 0xa3, 0xae, 0xa2, 0xbe, 0xa6, 0xa8,
+ 0xd7, 0xa4, 0xd8, 0xa8, 0xaa, 0xaf, 0xcd, 0xa5, 0xb8, 0xbf, 0x4b, 0xa5, 0x52,
+ 0xa8, 0x52, 0xc2, 0xce, 0xb1, 0x52, 0xc3, 0x64, 0xa9, 0xe2, 0xb9, 0x53, 0xc3,
+ 0xa5, 0xc5, 0x43, 0xb8, 0x59, 0xb7, 0x54, 0xc4, 0x77, 0xa4, 0xb3, 0xba, 0xf7,
+ 0xe2, 0xe4, 0xc1, 0xe0, 0xaf, 0xe4, 0xaa, 0xec, 0xa5, 0x58, 0xc3, 0x6f, 0xbc,
+ 0x70, 0xc3, 0xdc, 0xbe, 0x53, 0xc2, 0xfa, 0xde, 0x51, 0xb0, 0xa3, 0xb7, 0xa1,
+ 0xc2, 0xa6, 0xc0, 0x78, 0xc5, 0xf7, 0xdd, 0x7a, 0xc4, 0xb2, 0xb3, 0x42, 0xb4,
+ 0xa2, 0xa4, 0x74, 0xac, 0xef, 0xdd, 0xdc, 0xb6, 0xc7, 0xb2, 0xee, 0xb3, 0xdd,
+ 0xa6, 0xea, 0xbd, 0x48, 0xb5, 0xa1, 0xbc, 0x6c, 0xa7, 0xc9, 0xc2, 0xf4, 0xb3,
+ 0xd0, 0xa7, 0x6a, 0xaa, 0xa4, 0xb4, 0xa8, 0xc1, 0xe8, 0xab, 0xab, 0xac, 0x4b,
+ 0xdd, 0xcf, 0xbe, 0x4a, 0xae, 0x42, 0xb2, 0x45, 0xaf, 0xc2, 0xc4, 0xf8, 0xc2,
+ 0x57, 0xba, 0xef, 0xb2, 0xab, 0xaf, 0xfd, 0xba, 0xcf, 0xbb, 0xdb, 0xc3, 0xe3,
+ 0xb7, 0x4f, 0xb2, 0xa1, 0xb5, 0xfc, 0xa6, 0xb9, 0xa8, 0xeb, 0xbd, 0xe7, 0xa6,
+ 0xb8, 0xc1, 0x6f, 0xbd, 0xb5, 0xa7, 0x77, 0xa5, 0x5e, 0xb1, 0x71, 0xc2, 0x4f,
+ 0xb4, 0xea, 0xb2, 0xca, 0xbe, 0x4c, 0xc1, 0x4c, 0xab, 0x50, 0xf9, 0x4f, 0xbf,
+ 0x79, 0xc2, 0xab, 0xba, 0x52, 0xb1, 0x5a, 0xb6, 0xca, 0xaf, 0xdc, 0xb7, 0xf1,
+ 0xba, 0xe9, 0xb2, 0x66, 0xbb, 0x41, 0xa7, 0xf8, 0xa6, 0x73, 0xa4, 0x6f, 0xbd,
+ 0x52, 0xbc, 0xbc, 0xb7, 0x62, 0xb1, 0xb9, 0xae, 0xc0, 0xbf, 0xf9, 0xb7, 0x66,
+ 0xb9, 0x46, 0xb5, 0xaa, 0xbd, 0x44, 0xa5, 0xb4, 0xa4, 0x6a, 0xa7, 0x62, 0xa4,
+ 0xef, 0xd8, 0x56, 0xc0, 0xb9, 0xb1, 0x61, 0xac, 0x70, 0xa5, 0x4e, 0xb6, 0x55,
+ 0xb3, 0x55, 0xab, 0xdd, 0xb6, 0x65, 0xab, 0xe5, 0xaf, 0xd4, 0xbe, 0xe1, 0xa4,
+ 0xa6, 0xb3, 0xe6, 0xe8, 0x58, 0xe5, 0xb8, 0xc1, 0x78, 0xa5, 0xb9, 0xb4, 0xe1,
+ 0xa6, 0xfd, 0xbc, 0xaa, 0xb2, 0x48, 0xbd, 0xcf, 0xbc, 0x75, 0xb3, 0x4a, 0xb7,
+ 0xed, 0xbe, 0xd7, 0xc4, 0xd2, 0xc0, 0xfa, 0xc0, 0xc9, 0xa4, 0x4d, 0xb7, 0x6f,
+ 0xc1, 0xd0, 0xad, 0xcb, 0xae, 0x71, 0xc3, 0xab, 0xbe, 0xc9, 0xa8, 0xec, 0xbd,
+ 0x5f, 0xb1, 0xa5, 0xb9, 0x44, 0xb5, 0x73, 0xbc, 0x77, 0xb1, 0x6f, 0xaa, 0xba,
+ 0xc3, 0xde, 0xbf, 0x4f, 0xb5, 0x6e, 0xb5, 0xa5, 0xc0, 0xfc, 0xb9, 0xb9, 0xbe,
+ 0x48, 0xb3, 0xf6, 0xa7, 0x43, 0xba, 0x77, 0xad, 0x7d, 0xbc, 0xc4, 0xb2, 0xc3,
+ 0xa8, 0x66, 0xba, 0xb0, 0xbb, 0x43, 0xb9, 0xde, 0xa9, 0xe8, 0xa9, 0xb3, 0xa6,
+ 0x61, 0xb8, 0xa6, 0xb2, 0xc4, 0xab, 0xd2, 0xa7, 0xcc, 0xbb, 0xbc, 0xbd, 0x6c,
+ 0xc4, 0x41, 0xd5, 0x69, 0xb7, 0xbf, 0xb8, 0x4b, 0xc2, 0x49, 0xa8, 0xe5, 0xc0,
+ 0x51, 0xb9, 0xd4, 0xb9, 0x71, 0xa6, 0xfa, 0xa8, 0x6c, 0xa9, 0xb1, 0xb1, 0x7d,
+ 0xb3, 0xfe, 0xbe, 0xfd, 0xb7, 0xb5, 0xb8, 0x4d, 0xa5, 0x70, 0xc0, 0x4a, 0xad,
+ 0xe4, 0xa4, 0x4e, 0xb1, 0xbc, 0xa6, 0x51, 0xb3, 0xa8, 0xbd, 0xd5, 0xb6, 0x5e,
+ 0xaf, 0x52, 0xba, 0xd0, 0xbd, 0xba, 0xad, 0xa1, 0xbf, 0xd2, 0xc5, 0x7c, 0xa4,
+ 0x42, 0xa8, 0x6e, 0xa5, 0x6d, 0xb0, 0x76, 0xb3, 0xbb, 0xb9, 0xa9, 0xbf, 0xf5,
+ 0xa9, 0x77, 0xad, 0x71, 0xa5, 0xe1, 0xaa, 0x46, 0xa5, 0x56, 0xb8, 0xb3, 0xc0,
+ 0xb4, 0xb0, 0xca, 0xb4, 0xc9, 0xcb, 0xbe, 0xab, 0xf0, 0xad, 0xe1, 0xac, 0x7d,
+ 0xb0, 0xc2, 0xa7, 0xdd, 0xb0, 0xab, 0xb0, 0x7e, 0xa8, 0xa7, 0xb3, 0x72, 0xb5,
+ 0x6b, 0xb3, 0xa3, 0xb7, 0xfe, 0xac, 0x72, 0xc3, 0x7d, 0xbf, 0x57, 0xc5, 0xaa,
+ 0xb0, 0xf4, 0xb8, 0x40, 0xbd, 0xe4, 0xa7, 0xf9, 0xc1, 0xe1, 0xa8, 0x7b, 0xab,
+ 0xd7, 0xb4, 0xe7, 0xa7, 0xaa, 0xba, 0xdd, 0xb5, 0x75, 0xc1, 0xeb, 0xac, 0x71,
+ 0xc2, 0x5f, 0xbd, 0x76, 0xb0, 0xef, 0xa7, 0x49, 0xb6, 0xa4, 0xb9, 0xef, 0xbc,
+ 0x5b, 0xbe, 0xb7, 0xc3, 0xdb, 0xb4, 0xb0, 0xb9, 0x79, 0xa7, 0x79, 0xb6, 0x77,
+ 0xac, 0xde, 0xb9, 0x50, 0xd5, 0x73, 0xce, 0x47, 0xa6, 0x68, 0xb9, 0xdc, 0xce,
+ 0x57, 0xb8, 0xfa, 0xa6, 0xb7, 0xb8, 0xf6, 0xb2, 0xeb, 0xa8, 0xef, 0xb4, 0x6b,
+ 0xbc, 0x5a, 0xb8, 0xbf, 0xae, 0x6f, 0xc3, 0x5a, 0xab, 0x58, 0xc3, 0x42, 0xb3,
+ 0x5f, 0xae, 0x5a, 0xb4, 0x63, 0xa4, 0xcc, 0xa7, 0xe3, 0xb9, 0x4b, 0xb6, 0x6b,
+ 0xbe, 0x6a, 0xae, 0xa6, 0xa6, 0xd3, 0xa8, 0xe0, 0xa6, 0xd5, 0xba, 0xb8, 0xbb,
+ 0xe7, 0xac, 0x7c, 0xa4, 0x47, 0xb6, 0x4c, 0xb5, 0x6f, 0xbb, 0x40, 0xb5, 0xad,
+ 0xa5, 0xef, 0xa5, 0x46, 0xbb, 0xd6, 0xaa, 0x6b, 0xb5, 0x57, 0xc3, 0xbf, 0xa6,
+ 0x7c, 0xb5, 0x66, 0xc2, 0xbd, 0xbc, 0xd4, 0xc4, 0x73, 0xb3, 0xab, 0xc1, 0x63,
+ 0xa4, 0x5a, 0xb7, 0xd0, 0xa4, 0xcf, 0xaa, 0xf0, 0xad, 0x53, 0xb3, 0x63, 0xa5,
+ 0xc7, 0xb6, 0xba, 0xaa, 0x78, 0xa7, 0x7b, 0xaa, 0xda, 0xa4, 0xe8, 0xaa, 0xd5,
+ 0xa9, 0xd0, 0xa8, 0xbe, 0xa7, 0xab, 0xa5, 0xe9, 0xb3, 0x58, 0xaf, 0xbc, 0xa9,
+ 0xf1, 0xb5, 0xe1, 0xab, 0x44, 0xb0, 0xd8, 0xad, 0xb8, 0xaa, 0xce, 0xad, 0xea,
+ 0xbd, 0xda, 0xa7, 0x70, 0xaa, 0xcd, 0xbc, 0x6f, 0xaa, 0x6d, 0xb6, 0x4f, 0xaa,
+ 0xe2, 0xd7, 0xf4, 0xa7, 0x68, 0xaa, 0x5e, 0xa4, 0xc0, 0xaf, 0xc9, 0xbc, 0x58,
+ 0xb5, 0x49, 0xa8, 0x57, 0xaf, 0xbb, 0xbe, 0xc4, 0xa5, 0xf7, 0xa9, 0xc1, 0xbc,
+ 0xab, 0xc1, 0x54, 0xc2, 0xd7, 0xab, 0xca, 0xb7, 0xac, 0xb8, 0xc1, 0xae, 0x70,
+ 0xbe, 0x57, 0xad, 0xb7, 0xba, 0xc6, 0xb2, 0x6c, 0xb3, 0x7b, 0xb6, 0xbe, 0xc1,
+ 0x5f, 0xbf, 0xd8, 0xa9, 0x5e, 0xbb, 0xf1, 0xa6, 0xf2, 0xa7, 0x5f, 0xa4, 0xd2,
+ 0xbc, 0xc5, 0xbd, 0xa7, 0xb9, 0xe5, 0xa7, 0xdf, 0xa9, 0xd8, 0xbf, 0xe7, 0xb4,
+ 0x54, 0xac, 0x74, 0xb2, 0xc5, 0xa5, 0xf1, 0xab, 0x52, 0xaa, 0x41, 0xaf, 0x42,
+ 0xb2, 0x65, 0xba, 0xd6, 0xb5, 0xf6, 0xa5, 0xb1, 0xa8, 0x6a, 0xbc, 0xbe, 0xbb,
+ 0xb2, 0xad, 0xc1, 0xb0, 0x79, 0xa9, 0xf2, 0xb2, 0xe3, 0xb5, 0xc6, 0xa9, 0xb2,
+ 0xbb, 0x47, 0xad, 0x75, 0xb0, 0xc6, 0xc2, 0xd0, 0xbd, 0xe1, 0xb4, 0x5f, 0xb3,
+ 0xc5, 0xa5, 0x49, 0xaa, 0xfa, 0xa4, 0xf7, 0xb8, 0xa1, 0xad, 0x74, 0xb4, 0x49,
+ 0xad, 0x72, 0xaa, 0xfe, 0xb0, 0xfc, 0xbf, 0xa3, 0xa9, 0x4a, 0xbe, 0xbf, 0xb9,
+ 0xc7, 0xb8, 0xd3, 0xa7, 0xef, 0xb7, 0xa7, 0xb6, 0x74, 0xbb, 0x5c, 0xb5, 0x40,
+ 0xb7, 0x46, 0xa5, 0xcc, 0xb1, 0xec, 0xac, 0x61, 0xac, 0xf1, 0xa8, 0x78, 0xbb,
+ 0xb0, 0xb7, 0x50, 0xb5, 0x7a, 0xb4, 0xb1, 0xc6, 0x42, 0xa9, 0xa3, 0xad, 0xe8,
+ 0xbf, 0xfb, 0xac, 0xfb, 0xa8, 0x7a, 0xba, 0xf5, 0xb1, 0x5e, 0xb4, 0xe4, 0xba,
+ 0x62, 0xbf, 0x74, 0xaf, 0x6f, 0xb0, 0xaa, 0xbb, 0x49, 0xaf, 0xcc, 0xbf, 0x7c,
+ 0xb7, 0x64, 0xc2, 0xee, 0xbd, 0x5a, 0xa7, 0x69, 0xad, 0xf4, 0xba, 0x71, 0xc0,
+ 0xc1, 0xa4, 0xe0, 0xc2, 0x46, 0xaf, 0xde, 0xaa, 0xb8, 0xb3, 0xce, 0xad, 0xb2,
+ 0xb8, 0xaf, 0xae, 0xe6, 0xb5, 0xf0, 0xbb, 0xd5, 0xb9, 0x6a, 0xbb, 0xcc, 0xad,
+ 0xd3, 0xa6, 0x55, 0xb5, 0xb9, 0xae, 0xda, 0xb8, 0xf2, 0xaf, 0xd1, 0xa7, 0xf3,
+ 0xa9, 0xb0, 0xc3, 0xbc, 0xae, 0x47, 0xaf, 0xd5, 0xb1, 0xf0, 0xa4, 0x75, 0xa7,
+ 0xf0, 0xa5, 0x5c, 0xae, 0xa5, 0xc5, 0xc7, 0xa8, 0xd1, 0xb0, 0x60, 0xa4, 0xbd,
+ 0xae, 0x63, 0xa4, 0x7d, 0xbe, 0x64, 0xa8, 0x45, 0xab, 0xfd, 0xb0, 0x5e, 0xa6,
+ 0x40, 0xb9, 0x5f, 0xa4, 0xc4, 0xb7, 0xbe, 0xad, 0x65, 0xaa, 0xaf, 0xab, 0xaf,
+ 0xba, 0x63, 0xc1, 0xca, 0xb0, 0xf7, 0xb6, 0x64, 0xdb, 0xa3, 0xa9, 0x42, 0xe3,
+ 0x54, 0xa6, 0xf4, 0xaa, 0x66, 0xa9, 0x74, 0xa9, 0x68, 0xb9, 0xaa, 0xa5, 0x6a,
+ 0xc5, 0xdb, 0xb0, 0xa9, 0xa8, 0xa6, 0xaa, 0xd1, 0xac, 0x47, 0xc5, 0x55, 0xa9,
+ 0x54, 0xb6, 0xb1, 0xa8, 0xed, 0xa5, 0xca, 0xd4, 0x6c, 0xb9, 0xe8, 0xb1, 0xbe,
+ 0xbb, 0x6f, 0xa8, 0xc4, 0xa9, 0xe4, 0xa9, 0xc7, 0xb4, 0xc3, 0xc3, 0xf6, 0xa9,
+ 0x78, 0xab, 0x61, 0xc6, 0x5b, 0xba, 0xde, 0xc0, 0x5d, 0xc5, 0xf8, 0xba, 0x44,
+ 0xc4, 0xe9, 0xb3, 0x65, 0xa5, 0xfa, 0xbc, 0x73, 0xb3, 0x7d, 0xba, 0xc0, 0xb3,
+ 0x57, 0xa6, 0x63, 0xd6, 0xba, 0xc2, 0x6b, 0xc0, 0x74, 0xbb, 0xd3, 0xad, 0x79,
+ 0xb0, 0xad, 0xb8, 0xde, 0xac, 0xd1, 0xae, 0xdb, 0xc2, 0x64, 0xb8, 0xf7, 0xb6,
+ 0x51, 0xbc, 0x44, 0xbe, 0x40, 0xba, 0x75, 0xb4, 0xd2, 0xc1, 0xe7, 0xb3, 0xa2,
+ 0xb0, 0xea, 0xaa, 0x47, 0xbb, 0x71, 0xb9, 0x4c, 0xab, 0xa2, 0xc0, 0x65, 0xab,
+ 0xc4, 0xae, 0xfc, 0xae, 0xf3, 0xa5, 0xe8, 0xae, 0x60, 0xc0, 0x62, 0xb6, 0x6f,
+ 0xe9, 0x77, 0xcd, 0xd5, 0xc1, 0xfa, 0xa7, 0x74, 0xb2, 0x5b, 0xb4, 0x48, 0xa8,
+ 0xe7, 0xb3, 0xdb, 0xa8, 0x75, 0xbf, 0xab, 0xbe, 0xd9, 0xae, 0xc2, 0xa7, 0xf2,
+ 0xbe, 0xd1, 0xae, 0xab, 0xb2, 0x6b, 0xa6, 0xbd, 0xba, 0x7e, 0xc9, 0x71, 0xaa,
+ 0x43, 0xaf, 0xe8, 0xc0, 0xa2, 0xc0, 0x7a, 0xbb, 0xa8, 0xb2, 0x40, 0xb0, 0x71,
+ 0xa6, 0x6e, 0xaf, 0xd3, 0xb8, 0xb9, 0xaf, 0x45, 0xa8, 0xfe, 0xb3, 0xdc, 0xb2,
+ 0xfc, 0xdb, 0x5d, 0xae, 0xd6, 0xa5, 0xdd, 0xa9, 0x4d, 0xa6, 0xf3, 0xa6, 0x58,
+ 0xb2, 0xb0, 0xb8, 0xe8, 0xbb, 0xd2, 0xaa, 0x65, 0xb2, 0x55, 0xbb, 0xae, 0xbd,
+ 0xc5, 0xc5, 0x62, 0xb6, 0x50, 0xbc, 0x4b, 0xb6, 0xc2, 0xb2, 0xaa, 0xab, 0xdc,
+ 0xac, 0xbd, 0xab, 0xeb, 0xad, 0xf3, 0xa6, 0xeb, 0xbe, 0xee, 0xbf, 0xc5, 0xab,
+ 0xed, 0xc5, 0x46, 0xab, 0xa1, 0xaf, 0x4d, 0xad, 0x69, 0xc2, 0x45, 0xac, 0x78,
+ 0xa7, 0xbb, 0xa5, 0xb0, 0xac, 0xf5, 0xb3, 0xef, 0xab, 0x4a, 0xb5, 0x55, 0xa7,
+ 0x71, 0xab, 0x70, 0xad, 0xd4, 0xab, 0xe1, 0xa9, 0x49, 0xa5, 0x47, 0xa9, 0xbf,
+ 0xb7, 0xe4, 0xb3, 0xfd, 0xb8, 0xac, 0xad, 0x4a, 0xbd, 0xb9, 0xaa, 0xb0, 0xbd,
+ 0x6b, 0xb4, 0xf2, 0xa9, 0xb7, 0xaa, 0xea, 0xb0, 0xe4, 0xc5, 0x40, 0xa4, 0xac,
+ 0xba, 0xad, 0xa4, 0xe1, 0xaa, 0xe1, 0xbc, 0x4d, 0xb5, 0xd8, 0xb7, 0xe2, 0xb7,
+ 0xc6, 0xb5, 0x65, 0xb9, 0xba, 0xa4, 0xc6, 0xb8, 0xdc, 0xba, 0x69, 0xab, 0xde,
+ 0xc3, 0x68, 0xb2, 0x61, 0xc3, 0x61, 0xc5, 0x77, 0xc0, 0xf4, 0xae, 0xd9, 0xc1,
+ 0xd9, 0xbd, 0x77, 0xb4, 0xab, 0xb1, 0x77, 0xb3, 0xea, 0xba, 0xc8, 0xb8, 0xe6,
+ 0xb7, 0xd8, 0xb5, 0x41, 0xab, 0xc6, 0xa4, 0xdb, 0xaf, 0xee, 0xb7, 0x57, 0xb6,
+ 0xc0, 0xc1, 0x44, 0xbd, 0xc0, 0xc2, 0xae, 0xac, 0xd3, 0xb0, 0xc4, 0xb4, 0x71,
+ 0xb7, 0xd7, 0xae, 0xcc, 0xb7, 0x45, 0xab, 0xe9, 0xc1, 0xc0, 0xa6, 0xc7, 0xb4,
+ 0xa7, 0xbd, 0xf7, 0xc0, 0xb2, 0xab, 0xec, 0xb5, 0xee, 0xa6, 0x5e, 0xb7, 0xb4,
+ 0xae, 0xac, 0xbc, 0x7a, 0xa5, 0x63, 0xb4, 0x66, 0xb1, 0xe2, 0xb8, 0xec, 0xc2,
+ 0xa9, 0xb7, 0x7c, 0xc0, 0xed, 0xb6, 0xd7, 0xbf, 0xd0, 0xbb, 0xa3, 0xc3, 0xb8,
+ 0xb8, 0xa7, 0xa9, 0xfc, 0xb1, 0x42, 0xbb, 0xee, 0xb4, 0xfd, 0xb2, 0x56, 0xc1,
+ 0xc5, 0xac, 0xa1, 0xa5, 0xeb, 0xa4, 0xf5, 0xc0, 0xf2, 0xa9, 0xce, 0xb4, 0x62,
+ 0xc0, 0x4e, 0xb3, 0x66, 0xba, 0xd7, 0xc0, 0xbb, 0xa7, 0xa3, 0xb0, 0xf2, 0xbe,
+ 0xf7, 0xb7, 0xee, 0xbd, 0x5d, 0xbf, 0x6e, 0xba, 0xdf, 0xa6, 0xd9, 0xc4, 0xc8,
+ 0xb8, 0xf1, 0xbf, 0x45, 0xc3, 0xd5, 0xc2, 0xfb, 0xae, 0x56, 0xc1, 0x5a, 0xbd,
+ 0x72, 0xa6, 0x4e, 0xb7, 0xa5, 0xb4, 0xc6, 0xbf, 0xe8, 0xc4, 0x79, 0xb6, 0xb0,
+ 0xa4, 0xce, 0xab, 0xe6, 0xaf, 0x65, 0xa8, 0x56, 0xa7, 0x59, 0xb6, 0xfa, 0xaf,
+ 0xc5, 0xc0, 0xbd, 0xb4, 0x58, 0xaf, 0xe1, 0xa4, 0x76, 0xc1, 0xaa, 0xa7, 0xde,
+ 0xbe, 0xac, 0xa9, 0x75, 0xc9, 0xab, 0xb2, 0xbd, 0xbe, 0xaf, 0xb1, 0xaa, 0xc0,
+ 0xd9, 0xb1, 0x48, 0xb1, 0x49, 0xad, 0x70, 0xb0, 0x4f, 0xac, 0x4a, 0xa7, 0xd2,
+ 0xbb, 0xda, 0xa7, 0xb2, 0xc4, 0x7e, 0xac, 0xf6, 0xb9, 0xc5, 0xcf, 0x45, 0xa7,
+ 0xa8, 0xa8, 0xce, 0xae, 0x61, 0xa5, 0x5b, 0xb2, 0xf3, 0xc0, 0x55, 0xb8, 0xeb,
+ 0xa5, 0xd2, 0xb9, 0x5b, 0xb0, 0xb2, 0xbd, 0x5b, 0xbb, 0xf9, 0xac, 0x5b, 0xbe,
+ 0x72, 0xb6, 0xf9, 0xc4, 0xe8, 0xba, 0xca, 0xb0, 0xed, 0xa6, 0x79, 0xba, 0xe0,
+ 0xb6, 0xa1, 0xb7, 0xce, 0xad, 0xdd, 0xaa, 0xd3, 0xc1, 0x7d, 0xab, 0xc1, 0xbd,
+ 0x70, 0xc3, 0xb5, 0xc0, 0xcb, 0xac, 0x5a, 0xc6, 0x50, 0xc6, 0x50, 0xb4, 0x7a,
+ 0xbe, 0xdf, 0xc2, 0xb2, 0xbb, 0xfc, 0xb0, 0xc5, 0xb4, 0xee, 0xc2, 0xcb, 0xc2,
+ 0x65, 0xc5, 0xb3, 0xbd, 0xee, 0xbd, 0xe2, 0xa8, 0xa3, 0xc1, 0xe4, 0xbd, 0x62,
+ 0xa5, 0xf3, 0xb0, 0xb7, 0xc4, 0xa5, 0xbc, 0x43, 0xc0, 0x5e, 0xba, 0xa5, 0xc2,
+ 0x71, 0xbc, 0xee, 0xab, 0xd8, 0xbb, 0xf8, 0xab, 0xb8, 0xb1, 0x4e, 0xbc, 0xdf,
+ 0xa6, 0xbf, 0xc3, 0xa6, 0xbd, 0xb1, 0xbc, 0xd5, 0xbc, 0xfa, 0xc1, 0xbf, 0xa6,
+ 0x4b, 0xc2, 0xe6, 0xad, 0xb0, 0xbf, 0xbc, 0xb4, 0xd4, 0xc1, 0x47, 0xb5, 0x4a,
+ 0xbd, 0xa6, 0xa5, 0xe6, 0xad, 0xa5, 0xbc, 0xe5, 0xc5, 0xba, 0xbc, 0x62, 0xc4,
+ 0x5a, 0xc5, 0xcd, 0xbb, 0xc7, 0xc1, 0x42, 0xb9, 0xae, 0xb8, 0x7d, 0xac, 0xbe,
+ 0xa8, 0xa4, 0xbb, 0xe5, 0xc3, 0xba, 0xb5, 0xb1, 0xb6, 0xcf, 0xb1, 0xd0, 0xbb,
+ 0xc3, 0xc3, 0xe2, 0xb8, 0xfb, 0xa5, 0x73, 0xb5, 0xa2, 0xb4, 0xa6, 0xb1, 0xb5,
+ 0xac, 0xd2, 0xd6, 0xc5, 0xb5, 0xf3, 0xb6, 0xa5, 0xba, 0x49, 0xa7, 0x54, 0xb8,
+ 0x60, 0xae, 0xdc, 0xb3, 0xc7, 0xb1, 0xb6, 0xb7, 0xfb, 0xba, 0xdc, 0xbc, 0xe4,
+ 0xb5, 0xb2, 0xb8, 0xd1, 0xa9, 0x6a, 0xa7, 0xd9, 0xc2, 0xc7, 0xaa, 0xe3, 0xac,
+ 0xc9, 0xad, 0xc9, 0xa4, 0xb6, 0xac, 0xce, 0xbb, 0x7c, 0xa9, 0xa1, 0xa4, 0x79,
+ 0xb5, 0xac, 0xa4, 0xe7, 0xaa, 0xf7, 0xa4, 0xb5, 0xac, 0x7a, 0xc3, 0xcc, 0xba,
+ 0xf2, 0xc0, 0x41, 0xb6, 0xc8, 0xc2, 0xd4, 0xb6, 0x69, 0xe0, 0xda, 0xae, 0xca,
+ 0xb8, 0x54, 0xaa, 0xf1, 0xc2, 0x75, 0xae, 0xfb, 0xba, 0xc9, 0xab, 0x6c, 0xaf,
+ 0xf0, 0xb9, 0xb8, 0xb2, 0xf4, 0xb7, 0xfa, 0xb4, 0xb9, 0xc4, 0x48, 0xa8, 0xca,
+ 0xc5, 0xe5, 0xba, 0xeb, 0xb8, 0x65, 0xb8, 0x67, 0xa4, 0xab, 0xc4, 0xb5, 0xb4,
+ 0xba, 0xc0, 0x56, 0xc0, 0x52, 0xb9, 0xd2, 0xb7, 0x71, 0xc3, 0xe8, 0xae, 0x7c,
+ 0xb5, 0x6a, 0xb9, 0x74, 0xb3, 0xba, 0xc4, 0x76, 0xd0, 0xe4, 0xac, 0xb3, 0xb5,
+ 0x7e, 0xb4, 0xaa, 0xa8, 0x73, 0xaa, 0xc8, 0xa8, 0x68, 0xad, 0xb4, 0xa4, 0x5b,
+ 0xa8, 0x62, 0xa4, 0x45, 0xb0, 0x73, 0xb4, 0x5c, 0xb1, 0xcf, 0xc2, 0xc2, 0xa6,
+ 0xdd, 0xb8, 0xa4, 0xa9, 0x53, 0xb4, 0x4e, 0xaa, 0xb9, 0xc1, 0xf9, 0xa9, 0xeb,
+ 0xaa, 0xae, 0xaf, 0x6a, 0xa9, 0x7e, 0xbe, 0x73, 0xb5, 0xe2, 0xa7, 0xbd, 0xa9,
+ 0x43, 0xaf, 0x78, 0xc1, 0x7c, 0xaa, 0x71, 0xbb, 0x45, 0xa9, 0xda, 0xbe, 0xda,
+ 0xa5, 0xa8, 0xa8, 0xe3, 0xb6, 0x5a, 0xbd, 0xf5, 0xbf, 0xf7, 0xad, 0xd1, 0xa5,
+ 0x79, 0xc4, 0xdf, 0xac, 0xb2, 0xbc, 0x40, 0xae, 0xbd, 0xc3, 0x59, 0xae, 0x53,
+ 0xad, 0xc2, 0xb2, 0xb2, 0xa8, 0xf7, 0xb8, 0x68, 0xe5, 0xb1, 0xc5, 0xcc, 0xa7,
+ 0xe0, 0xb1, 0xb8, 0xad, 0xcf, 0xc0, 0xef, 0xc4, 0xb1, 0xa8, 0x4d, 0xb3, 0x5a,
+ 0xb5, 0xb4, 0xa7, 0xa1, 0xb5, 0xdf, 0xb6, 0x76, 0xad, 0x78, 0xa7, 0x67, 0xae,
+ 0x6d, 0xab, 0x54, 0xb5, 0xa4, 0xc0, 0xe0, 0xb0, 0x70, 0xc2, 0x40, 0xb3, 0xd8,
+ 0xa9, 0x40, 0xa5, 0x64, 0xab, 0xa3, 0xb6, 0x7d, 0xb4, 0x7b, 0xb7, 0xa2, 0xb3,
+ 0xcd, 0xb4, 0x6e, 0xa5, 0x5a, 0xb3, 0xf4, 0xb0, 0xc9, 0xa7, 0xa2, 0xac, 0xe5,
+ 0xac, 0xdd, 0xb1, 0x64, 0xba, 0x42, 0xc1, 0x52, 0xa6, 0xaa, 0xa7, 0xdc, 0xa4,
+ 0xae, 0xaa, 0xa1, 0xa6, 0xd2, 0xab, 0xfe, 0xaf, 0x4e, 0xbe, 0x61, 0xa9, 0x56,
+ 0xad, 0x56, 0xac, 0x5f, 0xb4, 0xca, 0xbd, 0x57, 0xc1, 0xfb, 0xac, 0xec, 0xb4,
+ 0xdf, 0xab, 0x79, 0xa5, 0x69, 0xb4, 0xf7, 0xa7, 0x4a, 0xa8, 0xe8, 0xab, 0xc8,
+ 0xbd, 0xd2, 0xaa, 0xd6, 0xb0, 0xd9, 0xbe, 0xc1, 0xc0, 0xb5, 0xa7, 0x7c, 0xa7,
+ 0x5c, 0xaa, 0xc5, 0xae, 0xa3, 0xa4, 0xd5, 0xb1, 0xb1, 0xe1, 0xe0, 0xa4, 0x66,
+ 0xa6, 0xa9, 0xb1, 0x46, 0xac, 0x5c, 0xad, 0xfa, 0xb8, 0x5d, 0xad, 0x57, 0xbb,
+ 0xc5, 0xae, 0x77, 0xbf, 0xc7, 0xa6, 0x6a, 0xab, 0xb1, 0xce, 0xd8, 0xb8, 0xf3,
+ 0xaf, 0xe3, 0xb6, 0xf4, 0xb8, 0x5f, 0xbb, 0xfb, 0xa7, 0xd6, 0xbc, 0x65, 0xb4,
+ 0xda, 0xa6, 0x4a, 0xb5, 0xa8, 0xa8, 0x67, 0xae, 0xd8, 0xc4, 0x71, 0xb2, 0xb5,
+ 0xc3, 0x6d, 0xaa, 0x70, 0xc1, 0xab, 0xb2, 0xaf, 0xf5, 0xc9, 0xbf, 0x73, 0xb8,
+ 0xaa, 0xab, 0xb6, 0xbb, 0xed, 0xb3, 0xc8, 0xf5, 0x58, 0xb7, 0x5c, 0xbc, 0xec,
+ 0xa9, 0x5b, 0xa9, 0xf8, 0xae, 0xb9, 0xa7, 0x78, 0xac, 0x41, 0xc2, 0x58, 0xb9,
+ 0xf8, 0xc1, 0xef, 0xa9, 0x55, 0xa9, 0xd4, 0xb3, 0xe2, 0xc4, 0xfa, 0xc3, 0xbe,
+ 0xbb, 0xb6, 0xb0, 0xd5, 0xb5, 0xdc, 0xa8, 0xd3, 0xbf, 0xe0, 0xc2, 0xc5, 0xb0,
+ 0xfd, 0xc4, 0xe6, 0xc4, 0x64, 0xc4, 0x78, 0xc1, 0xf1, 0xc4, 0xf5, 0xc4, 0x69,
+ 0xf8, 0xc2, 0xc5, 0xf3, 0xc4, 0xfd, 0xc3, 0x69, 0xc6, 0x6c, 0xc4, 0xea, 0xc0,
+ 0xdd, 0xb2, 0x77, 0xb7, 0x7d, 0xaf, 0x54, 0xb4, 0x59, 0xad, 0xa6, 0xae, 0xd4,
+ 0xae, 0xf6, 0xbc, 0xb4, 0xb3, 0xd2, 0xa8, 0x63, 0xa6, 0xd1, 0xa8, 0xd0, 0xab,
+ 0xbe, 0xb9, 0x54, 0xaf, 0x4f, 0xe5, 0xfc, 0xb0, 0xc7, 0xbc, 0xd6, 0xb9, 0x70,
+ 0xc5, 0x4a, 0xc1, 0xa2, 0xbd, 0x55, 0xb2, 0xd6, 0xc0, 0x77, 0xc2, 0x53, 0xbe,
+ 0xdd, 0xa6, 0xd8, 0xc3, 0xfe, 0xb2, 0x5c, 0xd9, 0xb1, 0xb7, 0xab, 0xa7, 0x4e,
+ 0xcd, 0xf9, 0xb1, 0xf9, 0xb2, 0x70, 0xbe, 0xa4, 0xc6, 0x58, 0xbb, 0xa9, 0xc2,
+ 0xf7, 0xba, 0x76, 0xb2, 0x7a, 0xa7, 0xf5, 0xb8, 0xcc, 0xc3, 0x55, 0xc2, 0xa7,
+ 0xb2, 0xfa, 0xaf, 0xef, 0xa6, 0x4f, 0xae, 0xdf, 0xc4, 0x52, 0xbc, 0x46, 0xc0,
+ 0x79, 0xc4, 0x74, 0xbe, 0xfa, 0xa7, 0x51, 0xe0, 0xf4, 0xa8, 0xd2, 0xab, 0x57,
+ 0xb5, 0x67, 0xa5, 0xdf, 0xb2, 0xc9, 0xc3, 0x77, 0xc1, 0xf5, 0xa4, 0x4f, 0xbc,
+ 0xfe, 0xad, 0xf9, 0xad, 0xc7, 0xc1, 0x70, 0xbd, 0xac, 0xb3, 0x73, 0xc5, 0x49,
+ 0xb7, 0x47, 0xbc, 0xa6, 0xba, 0xa7, 0xc3, 0xae, 0xc0, 0xc4, 0xc1, 0x79, 0xc3,
+ 0xec, 0xc5, 0xca, 0xb7, 0xd2, 0xbd, 0x6d, 0xc2, 0xb3, 0xb2, 0x44, 0xbc, 0xd9,
+ 0xb8, 0x64, 0xa8, 0x7d, 0xa8, 0xe2, 0xbd, 0xf8, 0xb6, 0x71, 0xb4, 0xbd, 0xab,
+ 0x47, 0xbd, 0xcc, 0xbc, 0xba, 0xb2, 0xe1, 0xb9, 0xb1, 0xc0, 0xf8, 0xbf, 0x52,
+ 0xb9, 0xe9, 0xbf, 0xf1, 0xbc, 0xe3, 0xa4, 0x46, 0xe1, 0xe6, 0xf4, 0xef, 0xb9,
+ 0xf9, 0xae, 0xc6, 0xa6, 0x43, 0xb5, 0xf5, 0xaf, 0x50, 0xa6, 0x48, 0xc2, 0x79,
+ 0xb5, 0x59, 0xaa, 0x4c, 0xc1, 0x43, 0xc0, 0x4d, 0xc1, 0x7b, 0xbe, 0x46, 0xc5,
+ 0xec, 0xb2, 0x4f, 0xbb, 0xfe, 0xb8, 0xee, 0xa7, 0x5b, 0xa9, 0xf0, 0xac, 0xc2,
+ 0xb5, 0xd9, 0xb9, 0x73, 0xc4, 0xd6, 0xb9, 0x61, 0xa7, 0x44, 0xb2, 0xdc, 0xad,
+ 0xe2, 0xc6, 0x46, 0xb3, 0xae, 0xc0, 0xad, 0xbb, 0xe2, 0xa5, 0x74, 0xa5, 0x4f,
+ 0xb7, 0xc8, 0xaf, 0x5b, 0xba, 0x68, 0xb2, 0xb8, 0xc3, 0x48, 0xaf, 0x64, 0xbc,
+ 0x42, 0xbd, 0x46, 0xac, 0x79, 0xac, 0x68, 0xa4, 0xbb, 0xc0, 0x73, 0xc5, 0xa4,
+ 0xc4, 0x56, 0xc5, 0xa2, 0xc1, 0x4b, 0xb6, 0xa9, 0xc3, 0x62, 0xc3, 0x6c, 0xc3,
+ 0xf7, 0xbc, 0xd3, 0xb0, 0xfa, 0xba, 0x4f, 0xc1, 0x4d, 0xba, 0x7c, 0xad, 0xae,
+ 0xc4, 0xaa, 0xbf, 0x63, 0xc6, 0x60, 0xc3, 0x66, 0xc4, 0x6c, 0xbe, 0xdb, 0xb3,
+ 0xbf, 0xb8, 0xb8, 0xbe, 0x7c, 0xc4, 0x53, 0xb8, 0x4c, 0xc5, 0x53, 0xb8, 0xf4,
+ 0xb8, 0xef, 0xb3, 0xc0, 0xe9, 0xf0, 0xb8, 0x53, 0xbf, 0xfd, 0xb3, 0xb0, 0xbc,
+ 0xae, 0xc6, 0x6a, 0xa7, 0x66, 0xbe, 0x54, 0xab, 0x51, 0xae, 0xc8, 0xbc, 0x69,
+ 0xb9, 0xf0, 0xc1, 0x5c, 0xbc, 0x7b, 0xb4, 0xe2, 0xab, 0xdf, 0xb2, 0x76, 0xc2,
+ 0x6f, 0xba, 0xf1, 0xc5, 0x72, 0xc5, 0xcb, 0xc5, 0x70, 0xc6, 0x65, 0xa7, 0x5a,
+ 0xb6, 0xc3, 0xb1, 0xb0, 0xb2, 0xa4, 0xb1, 0xc1, 0xbd, 0xfc, 0xad, 0xdb, 0xa8,
+ 0xda, 0xb2, 0x5f, 0xba, 0xfa, 0xbd, 0xd7, 0xc5, 0xda, 0xc1, 0xb3, 0xc3, 0xb9,
+ 0xc5, 0xde, 0xc6, 0x72, 0xc6, 0x59, 0xc5, 0x5b, 0xbb, 0x72, 0xb8, 0xa8, 0xac,
+ 0xa5, 0xc0, 0x64, 0xb5, 0xb8, 0xb6, 0xfd, 0xb3, 0xc2, 0xba, 0xbf, 0xbd, 0x58,
+ 0xbf, 0xc2, 0xb0, 0xa8, 0xbd, 0x7c, 0xb9, 0xc0, 0xb6, 0xdc, 0xae, 0x49, 0xb6,
+ 0x52, 0xb3, 0xc1, 0xbd, 0xe6, 0xc1, 0xda, 0xaf, 0xdf, 0xbf, 0x66, 0xc4, 0x43,
+ 0xc6, 0x5a, 0xba, 0xa1, 0xbd, 0xaf, 0xb0, 0xd2, 0xba, 0x43, 0xba, 0xa9, 0xf0,
+ 0xe3, 0xa8, 0x7e, 0xaf, 0xed, 0xaa, 0xbc, 0xaa, 0x5d, 0xa6, 0xa3, 0xb2, 0xf5,
+ 0xbf, 0xdf, 0xad, 0x54, 0xc1, 0xe3, 0xa4, 0xf2, 0xa5, 0xd9, 0xb9, 0x67, 0xa5,
+ 0x66, 0xad, 0x5a, 0xab, 0x5f, 0xb4, 0x55, 0xbb, 0xaa, 0xb6, 0x54, 0xbb, 0xf2,
+ 0xaa, 0xb4, 0xaa, 0x54, 0xb1, 0xf6, 0xa1, 0xbc, 0xbe, 0x60, 0xb7, 0xd1, 0xa8,
+ 0x53, 0xac, 0xdc, 0xb4, 0x43, 0xc1, 0xe2, 0xa8, 0x43, 0xac, 0xfc, 0xac, 0x4e,
+ 0xb4, 0x4b, 0xa9, 0x66, 0xb4, 0x41, 0xaa, 0xf9, 0xb4, 0x65, 0xad, 0xcc, 0xb5,
+ 0xde, 0xbb, 0x58, 0xc2, 0x63, 0xb7, 0xf9, 0xbf, 0xf8, 0xb2, 0x72, 0xb9, 0xda,
+ 0xa9, 0x73, 0xd6, 0xa9, 0xee, 0xc5, 0xc3, 0xfb, 0xc1, 0x53, 0xb0, 0x67, 0xc1,
+ 0xbc, 0xc0, 0xb1, 0xa6, 0xcc, 0xaf, 0xb5, 0xb3, 0x56, 0xaa, 0x63, 0xbb, 0x65,
+ 0xb1, 0x4b, 0xbe, 0xad, 0xb4, 0xd6, 0xaf, 0x76, 0xba, 0xf8, 0xb0, 0xc3, 0xa7,
+ 0x4b, 0xab, 0x6a, 0xae, 0x59, 0xbd, 0x71, 0xad, 0xb1, 0xad, 0x5d, 0xb4, 0x79,
+ 0xba, 0xcb, 0xc2, 0xc6, 0xac, 0xed, 0xb4, 0xf9, 0xbc, 0x71, 0xa7, 0xae, 0xbd,
+ 0xb0, 0xb7, 0xc0, 0xa5, 0xc1, 0xa9, 0xd7, 0xa5, 0xd7, 0xb1, 0xd3, 0xbc, 0xa7,
+ 0xbb, 0xd4, 0xa9, 0xfa, 0xbf, 0xc1, 0xbb, 0xef, 0xbb, 0xca, 0xa6, 0x57, 0xa9,
+ 0x52, 0xc2, 0xd5, 0xba, 0x4e, 0xbc, 0xb1, 0xc4, 0xa8, 0xbc, 0xd2, 0xbd, 0xa4,
+ 0xbf, 0x69, 0xbc, 0xaf, 0xc5, 0x5d, 0xa9, 0xd9, 0xa5, 0xbd, 0xb2, 0xf6, 0xbe,
+ 0xa5, 0xc0, 0x71, 0xaa, 0x6a, 0xba, 0x7a, 0xb9, 0xe6, 0xad, 0xaf, 0xbf, 0xd1,
+ 0xa6, 0xc8, 0xac, 0x59, 0xa9, 0xe6, 0xa8, 0x64, 0xaf, 0x61, 0xa9, 0x69, 0xa5,
+ 0xc0, 0xb9, 0xd3, 0xbc, 0xc7, 0xb9, 0xf5, 0xb6, 0xd2, 0xbc, 0x7d, 0xa4, 0xec,
+ 0xa5, 0xd8, 0xb7, 0xfc, 0xaa, 0xaa, 0xbf, 0x70, 0xae, 0xb3, 0xad, 0xfe, 0xa7,
+ 0x6f, 0xb6, 0x75, 0xa8, 0xba, 0xae, 0x52, 0xaf, 0xc7, 0xa6, 0xbb, 0xa4, 0x44,
+ 0xa5, 0xa4, 0xad, 0x40, 0xa9, 0x60, 0xab, 0x6e, 0xa8, 0x6b, 0xc3, 0xf8, 0xc5,
+ 0x6e, 0xbc, 0xb8, 0xb8, 0xa3, 0xb4, 0x6f, 0xbe, 0x78, 0xd5, 0xef, 0xa9, 0x4f,
+ 0xbe, 0x6b, 0xa4, 0xba, 0xb9, 0xe0, 0xaf, 0xe0, 0xa9, 0x67, 0xc0, 0x4f, 0xad,
+ 0xd9, 0xaa, 0x64, 0xa5, 0xa7, 0xc0, 0xc0, 0xa7, 0x41, 0xb0, 0xce, 0xbf, 0xb0,
+ 0xb0, 0x66, 0xb7, 0xc4, 0xe7, 0x59, 0xa9, 0xe0, 0xa6, 0x7e, 0xbd, 0x56, 0xc2,
+ 0x5b, 0xb1, 0xc9, 0xa9, 0xc0, 0xae, 0x51, 0xc6, 0x43, 0xb3, 0xbe, 0xa7, 0xbf,
+ 0xae, 0xba, 0xc2, 0xbf, 0xc4, 0x5e, 0xef, 0xbf, 0xc6, 0x68, 0xc2, 0xec, 0xaf,
+ 0x49, 0xb1, 0x7a, 0xc2, 0x66, 0xc0, 0xf1, 0xbe, 0xae, 0xb9, 0xe7, 0xc0, 0xbe,
+ 0xc0, 0xd7, 0xa4, 0xfb, 0xa7, 0xe1, 0xb6, 0x73, 0xaf, 0xc3, 0xc1, 0x77, 0xbf,
+ 0x40, 0xb9, 0x41, 0xa7, 0xcb, 0xa5, 0xa3, 0xa7, 0x56, 0xab, 0xe3, 0xa4, 0x6b,
+ 0xb7, 0x78, 0xad, 0x68, 0xba, 0xc4, 0xae, 0xbf, 0xc0, 0xb6, 0xc4, 0x7a, 0xbf,
+ 0xd5, 0xae, 0x40, 0xbc, 0xda, 0xc5, 0xc3, 0xbc, 0xde, 0xc3, 0xc2, 0xb9, 0xc3,
+ 0xb0, 0xb8, 0xe2, 0x78, 0xb0, 0xd4, 0xad, 0x77, 0xaa, 0xa6, 0xa9, 0xac, 0xa9,
+ 0xc8, 0xb5, 0x5d, 0xa9, 0xe7, 0xb1, 0xc6, 0xb5, 0x50, 0xb1, 0x72, 0xb4, 0xfb,
+ 0xac, 0xa3, 0xc3, 0x6b, 0xbc, 0xef, 0xbd, 0x4c, 0xbd, 0x59, 0xac, 0xdf, 0xaf,
+ 0x60, 0xa7, 0x50, 0xab, 0x71, 0xa5, 0xe3, 0xc3, 0x65, 0xae, 0xc7, 0xea, 0xe5,
+ 0xad, 0x44, 0xa9, 0xdf, 0xa9, 0x48, 0xa7, 0x53, 0xac, 0xb6, 0xb3, 0x54, 0xb6,
+ 0x5d, 0xaa, 0x77, 0xa9, 0x41, 0xad, 0x46, 0xb0, 0xf6, 0xbb, 0x70, 0xbd, 0xdf,
+ 0xb3, 0xad, 0xb0, 0x74, 0xa8, 0xd8, 0xa8, 0x4b, 0xbc, 0x51, 0xac, 0xd6, 0xaf,
+ 0x79, 0xa9, 0xe1, 0xb2, 0x69, 0xbc, 0xea, 0xb4, 0x5e, 0xbd, 0xb4, 0xb4, 0xd7,
+ 0xb8, 0x4e, 0xc1, 0x4f, 0xbf, 0xb1, 0xaa, 0x42, 0xc4, 0x50, 0xb1, 0xb7, 0xb8,
+ 0x49, 0xcb, 0xf2, 0xcf, 0xec, 0xc5, 0x52, 0xa7, 0xe5, 0xa9, 0xdc, 0xbc, 0x41,
+ 0xb5, 0x5c, 0xac, 0x73, 0xb0, 0xe0, 0xb5, 0xca, 0xaf, 0x68, 0xa5, 0xd6, 0xa4,
+ 0xc7, 0xb5, 0x6c, 0xbb, 0xf7, 0xa7, 0xbe, 0xc4, 0xb4, 0xbd, 0x67, 0xb0, 0xbe,
+ 0xa4, 0xf9, 0xc4, 0x46, 0xc4, 0xc6, 0xba, 0x7d, 0xbf, 0x5d, 0xb2, 0xbc, 0xba,
+ 0x4a, 0xbf, 0x68, 0xab, 0xf7, 0xc0, 0x57, 0xb3, 0x68, 0xab, 0x7e, 0xb8, 0x75,
+ 0xa5, 0xe2, 0xa9, 0x57, 0xc4, 0xab, 0xb5, 0xd3, 0xa5, 0xad, 0xbe, 0xcc, 0xb2,
+ 0x7e, 0xb5, 0xfb, 0xab, 0xcc, 0xa9, 0x59, 0xbc, 0xe2, 0xbb, 0xe1, 0xb1, 0x43,
+ 0xaf, 0x7d, 0xbe, 0x7a, 0xad, 0xa2, 0xb2, 0xcb, 0xad, 0xe5, 0xbc, 0xb3, 0xe7,
+ 0x45, 0xb9, 0xb2, 0xb3, 0x40, 0xb8, 0xb2, 0xb5, 0xd0, 0xbb, 0x5a, 0xae, 0x48,
+ 0xbe, 0xeb, 0xae, 0x45, 0xb4, 0xb6, 0xae, 0xfa, 0xc3, 0xd0, 0xc3, 0x6e, 0xc2,
+ 0x72, 0xb4, 0xc1, 0xb4, 0xdb, 0xb4, 0xcf, 0xb1, 0xad, 0xa9, 0x64, 0xa4, 0x43,
+ 0xd0, 0xe2, 0xba, 0xa3, 0xac, 0x6d, 0xcb, 0x50, 0xa8, 0xe4, 0xb4, 0xd1, 0xa9,
+ 0x5f, 0xaa, 0x5b, 0xb2, 0xa5, 0xb1, 0x54, 0xc2, 0xc0, 0xbb, 0xf4, 0xba, 0x58,
+ 0xac, 0xe8, 0xaa, 0xc2, 0xc3, 0x4d, 0xb0, 0x5f, 0xb0, 0x5a, 0xa4, 0x5e, 0xa5,
+ 0xf8, 0xb1, 0xd2, 0xab, 0xb4, 0xac, 0xe4, 0xbe, 0xb9, 0xae, 0xf0, 0xa8, 0xb4,
+ 0xb1, 0xf3, 0xa8, 0x54, 0xaa, 0x5f, 0xb0, 0x57, 0xd5, 0x74, 0xab, 0xea, 0xac,
+ 0xa2, 0xb2, 0x6f, 0xc9, 0xe7, 0xa1, 0xbc, 0xb9, 0x5d, 0xa4, 0x64, 0xbe, 0x45,
+ 0xc3, 0xb1, 0xa5, 0x61, 0xc1, 0xbe, 0xb0, 0xae, 0xc0, 0x72, 0xbf, 0xfa, 0xb9,
+ 0x58, 0xab, 0x65, 0xbc, 0xe7, 0xbb, 0xba, 0xb2, 0x4c, 0xc4, 0xfe, 0xb9, 0xd5,
+ 0xb4, 0x4f, 0xa4, 0xed, 0xba, 0x70, 0xba, 0x6a, 0xb6, 0xe6, 0xb5, 0xc4, 0xaa,
+ 0xca, 0xc0, 0xf0, 0xc1, 0xa5, 0xb1, 0x6a, 0xb7, 0x6d, 0xbe, 0xf5, 0xc1, 0xea,
+ 0xba, 0x56, 0xae, 0xa8, 0xbe, 0xf4, 0xc1, 0x40, 0xb3, 0xec, 0xb9, 0xb4, 0xa5,
+ 0xa9, 0xc0, 0x54, 0xbc, 0xc0, 0xc2, 0xbc, 0xae, 0x6b, 0xab, 0x4e, 0xc2, 0xac,
+ 0xa4, 0xc1, 0xad, 0x58, 0xa5, 0x42, 0xa9, 0xc4, 0xc5, 0xd1, 0xb4, 0xdc, 0xab,
+ 0x49, 0xbf, 0xcb, 0xaf, 0xb3, 0xb5, 0x5e, 0xb6, 0xd4, 0xaa, 0xe0, 0xbe, 0xe0,
+ 0xb8, 0x56, 0xb9, 0xec, 0xa8, 0x47, 0xab, 0x43, 0xbb, 0xb4, 0xb2, 0x42, 0xb6,
+ 0xc9, 0xad, 0xeb, 0xb2, 0x4d, 0xc0, 0xba, 0xb4, 0xb8, 0xd9, 0xe6, 0xb1, 0xa1,
+ 0xb3, 0xbc, 0xbd, 0xd0, 0xbc, 0x79, 0xc3, 0xa3, 0xbd, 0x61, 0xac, 0xee, 0xa5,
+ 0x43, 0xaa, 0xf4, 0xb2, 0x79, 0xa8, 0x44, 0xa5, 0x7d, 0xad, 0xa9, 0xaa, 0x73,
+ 0xc1, 0xcd, 0xb0, 0xcf, 0xb3, 0x49, 0xa6, 0xb1, 0xc2, 0xdf, 0xa9, 0x7d, 0xc5,
+ 0x58, 0xb4, 0xeb, 0xa8, 0xfa, 0xb0, 0xf9, 0xc6, 0x54, 0xbd, 0xec, 0xa5, 0x68,
+ 0xb0, 0xe9, 0xf9, 0xaf, 0xc5, 0x76, 0xee, 0xc7, 0xac, 0x75, 0xa5, 0xfe, 0xb2,
+ 0xac, 0xae, 0xb1, 0xa4, 0xfc, 0xa8, 0xe9, 0xc4, 0x55, 0xaf, 0xca, 0xcd, 0x50,
+ 0xbf, 0x61, 0xab, 0x6f, 0xc4, 0x4e, 0xba, 0x65, 0xbd, 0x54, 0xb3, 0xb6, 0xb8,
+ 0xc8, 0xb8, 0x73, 0xb5, 0x4d, 0xbf, 0x55, 0xa5, 0x54, 0xac, 0x56, 0xc5, 0x7b,
+ 0xc4, 0x5b, 0xc4, 0x63, 0xc4, 0x57, 0xc5, 0xfd, 0xc4, 0xc7, 0xc2, 0x5a, 0xc2,
+ 0xb6, 0xb7, 0x53, 0xbc, 0xf6, 0xa4, 0xd0, 0xa4, 0xaf, 0xa4, 0x48, 0xa7, 0xd4,
+ 0xb6, 0xb4, 0xa5, 0xf4, 0xbb, 0x7b, 0xa4, 0x62, 0xa7, 0xb3, 0xac, 0xf7, 0xa5,
+ 0xb5, 0xa4, 0xb4, 0xa4, 0xe9, 0xa6, 0xa5, 0xaf, 0xf1, 0xbb, 0x54, 0xba, 0x61,
+ 0xbf, 0xc4, 0xba, 0xb2, 0xb7, 0xbb, 0xae, 0x65, 0xb5, 0xb3, 0xa4, 0xbe, 0xb4,
+ 0x7c, 0xac, 0x58, 0xa6, 0xd7, 0xaf, 0xf8, 0xc4, 0xaf, 0xbe, 0xa7, 0xc0, 0xa9,
+ 0xa6, 0x70, 0xb0, 0x64, 0xa8, 0xc5, 0xa6, 0xbc, 0xa4, 0x4a, 0xbf, 0xc8, 0xb3,
+ 0x6e, 0xa8, 0xbf, 0xbf, 0xb6, 0xb7, 0xe7, 0xbe, 0x55, 0xb6, 0x7c, 0xbc, 0xed,
+ 0xad, 0x59, 0xae, 0x7a, 0xbc, 0xbb, 0xcf, 0x73, 0xc2, 0xc4, 0xb8, 0x7c, 0xc4,
+ 0xce, 0xb6, 0xeb, 0xc1, 0xc9, 0xa4, 0x54, 0xa4, 0x54, 0xb3, 0xca, 0xb4, 0xb2,
+ 0xae, 0xe1, 0xb6, 0xda, 0xb3, 0xe0, 0xb7, 0x6b, 0xc4, 0xcc, 0xb1, 0xbd, 0xb7,
+ 0x41, 0xb7, 0xe6, 0xa6, 0xe2, 0xc0, 0xdf, 0xb4, 0xcb, 0xb9, 0xac, 0xb2, 0xef,
+ 0xac, 0xe2, 0xb1, 0xfe, 0xab, 0x62, 0xa8, 0x46, 0xaf, 0xbd, 0xb6, 0xcc, 0xd4,
+ 0xa3, 0xb7, 0xd9, 0xbf, 0x7a, 0xc5, 0xce, 0xac, 0xc0, 0xd0, 0x73, 0xa7, 0xfc,
+ 0xa4, 0x73, 0xa7, 0x52, 0xba, 0xb4, 0xad, 0x6d, 0xb0, 0x7b, 0xb0, 0xa2, 0xbe,
+ 0xd5, 0xc4, 0xba, 0xbf, 0xaf, 0xb5, 0xbd, 0xa6, 0xc2, 0xae, 0xb0, 0xc2, 0xb5,
+ 0xe1, 0x61, 0xb6, 0xcb, 0xb0, 0xd3, 0xbd, 0xe0, 0xae, 0xce, 0xa4, 0x57, 0xa9,
+ 0x7c, 0xbb, 0x6e, 0xb1, 0xe9, 0xae, 0xb4, 0xb5, 0x79, 0xbf, 0x4e, 0xa8, 0xa2,
+ 0xa4, 0x63, 0xbb, 0xe0, 0xa4, 0xd6, 0xad, 0xef, 0xaa, 0xf2, 0xb2, 0xd0, 0xb0,
+ 0xf8, 0xbb, 0xad, 0xb3, 0x44, 0xa6, 0xde, 0xaa, 0xd9, 0xb3, 0x6a, 0xc4, 0xe1,
+ 0xae, 0x67, 0xc4, 0xe0, 0xaf, 0x41, 0xaa, 0xc0, 0xb3, 0x5d, 0xaf, 0x7e, 0xa5,
+ 0xd3, 0xa9, 0x44, 0xa6, 0xf9, 0xa8, 0xad, 0xb2, 0x60, 0xae, 0x57, 0xb2, 0xd4,
+ 0xaf, 0xab, 0xa8, 0x48, 0xbc, 0x66, 0xc2, 0x54, 0xac, 0xc6, 0xb5, 0xc7, 0xb7,
+ 0x56, 0xba, 0xaf, 0xc1, 0x6e, 0xa5, 0xcd, 0xb5, 0x63, 0xac, 0xb9, 0xa4, 0xc9,
+ 0xc3, 0xb7, 0xac, 0xd9, 0xb2, 0xb1, 0xb3, 0xd1, 0xb3, 0xd3, 0xb8, 0x74, 0xae,
+ 0x76, 0xa5, 0xa2, 0xb7, 0xe0, 0xac, 0x49, 0xc0, 0xe3, 0xb8, 0xd6, 0xab, 0xcd,
+ 0xbd, 0xbe, 0xa4, 0x51, 0xa5, 0xdb, 0xac, 0x42, 0xae, 0xc9, 0xa4, 0xb0, 0xad,
+ 0xb9, 0xbb, 0x6b, 0xb9, 0xea, 0xc3, 0xd1, 0xa5, 0x76, 0xa5, 0xda, 0xa8, 0xcf,
+ 0xab, 0xcb, 0xbe, 0x70, 0xa9, 0x6c, 0xa6, 0xa1, 0xa5, 0xdc, 0xa4, 0x68, 0xa5,
+ 0x40, 0xac, 0x55, 0xa8, 0xc6, 0xab, 0xf8, 0xbb, 0x7d, 0xb3, 0x75, 0xb6, 0xd5,
+ 0xac, 0x4f, 0xb6, 0xdd, 0xbe, 0xbd, 0xbe, 0x41, 0xa5, 0x4b, 0xa8, 0xcd, 0xc4,
+ 0xc0, 0xb9, 0xa2, 0xa4, 0xf3, 0xa5, 0xab, 0xab, 0xee, 0xab, 0xc7, 0xb5, 0xf8,
+ 0xb8, 0xd5, 0xa6, 0xac, 0xa4, 0xe2, 0xad, 0xba, 0xa6, 0x75, 0xb9, 0xd8, 0xb1,
+ 0xc2, 0xb0, 0xe2, 0xa8, 0xfc, 0xbd, 0x47, 0xc3, 0x7e, 0xbd, 0xad, 0xbc, 0xcf,
+ 0xae, 0xde, 0xae, 0xed, 0xa7, 0xe7, 0xbf, 0xe9, 0xa8, 0xfb, 0xb5, 0xce, 0xb2,
+ 0x51, 0xb2, 0xa8, 0xae, 0xd1, 0xc5, 0xab, 0xb1, 0x45, 0xbc, 0xf4, 0xc1, 0xa6,
+ 0xb4, 0xbb, 0xc0, 0xc6, 0xb8, 0x70, 0xb8, 0xbe, 0xb6, 0xc1, 0xb9, 0xab, 0xc4,
+ 0xdd, 0xb3, 0x4e, 0xad, 0x7a, 0xbe, 0xf0, 0xa7, 0xf4, 0xa6, 0xa7, 0xbd, 0xdd,
+ 0xb9, 0xd6, 0xb1, 0x66, 0xbc, 0xc6, 0xba, 0xa4, 0xae, 0xa4, 0xa8, 0xea, 0xad,
+ 0x41, 0xba, 0x4c, 0xb0, 0x49, 0xa5, 0xcf, 0xab, 0xd3, 0xae, 0xea, 0xac, 0x43,
+ 0xc1, 0xf7, 0xc2, 0xf9, 0xb2, 0x6e, 0xbd, 0xd6, 0xa4, 0xf4, 0xba, 0xce, 0xb5,
+ 0x7c, 0xa7, 0x6d, 0xc0, 0xfe, 0xb6, 0xb6, 0xb5, 0xcf, 0xbb, 0xa1, 0xba, 0xd3,
+ 0xae, 0xd2, 0xc3, 0x7b, 0xb4, 0xb5, 0xbc, 0xb9, 0xbc, 0x52, 0xab, 0xe4, 0xa8,
+ 0x70, 0xa5, 0x71, 0xb5, 0xb7, 0xa6, 0xba, 0xb8, 0x76, 0xa6, 0x78, 0xb6, 0xe0,
+ 0xa5, 0x7c, 0xa6, 0xf8, 0xa6, 0xfc, 0xb9, 0x7d, 0xa4, 0x78, 0xc3, 0x50, 0xc1,
+ 0x71, 0xbc, 0xa3, 0xb9, 0x7c, 0xb0, 0x65, 0xa7, 0xba, 0xb3, 0x5e, 0xbb, 0x77,
+ 0xb7, 0x6a, 0xbf, 0xb4, 0xc2, 0x5d, 0xb9, 0xc2, 0xc4, 0xac, 0xb6, 0x70, 0xab,
+ 0x55, 0xaf, 0xc0, 0xb3, 0x74, 0xb5, 0xaf, 0xe0, 0xf4, 0xb6, 0xec, 0xb7, 0xb9,
+ 0xb1, 0x4a, 0xb6, 0x44, 0xb5, 0xc2, 0xbb, 0xc4, 0xbb, 0x5b, 0xba, 0xe2, 0xc1,
+ 0xf6, 0xb6, 0xa6, 0xc0, 0x48, 0xb8, 0x6b, 0xc5, 0xe8, 0xb8, 0x48, 0xb7, 0xb3,
+ 0xc1, 0x4a, 0xb9, 0x45, 0xc0, 0x47, 0xaf, 0xa9, 0xae, 0x5d, 0xb7, 0x6c, 0xb5,
+ 0xab, 0xbb, 0x62, 0xb1, 0xf4, 0xad, 0xf6, 0xc1, 0x59, 0xba, 0xbe, 0xaf, 0xc1,
+ 0xc2, 0xea, 0xa9, 0xd2, 0xb6, 0xf2, 0xa5, 0x4c, 0xa5, 0xa6, 0xa6, 0x6f, 0xb6,
+ 0xf0, 0xc3, 0xa1, 0xbe, 0xd8, 0xc1, 0xcf, 0xbd, 0xf1, 0xad, 0x4c, 0xad, 0x61,
+ 0xa9, 0xef, 0xa5, 0x78, 0xae, 0xf5, 0xa1, 0xbc, 0xa4, 0xd3, 0xba, 0x41, 0xa8,
+ 0x4f, 0xa7, 0x7e, 0xc5, 0x75, 0xb3, 0x67, 0xc5, 0xf5, 0xc5, 0x79, 0xbe, 0xc2,
+ 0xc0, 0xc8, 0xb7, 0xf0, 0xbc, 0xe6, 0xc3, 0xd3, 0xbd, 0xcd, 0xa9, 0x5a, 0xb4,
+ 0xe0, 0xb3, 0x52, 0xba, 0xd2, 0xb1, 0xb4, 0xb9, 0xc4, 0xac, 0xb4, 0xb4, 0xf6,
+ 0xb6, 0xed, 0xb7, 0x65, 0xb0, 0xf3, 0xb4, 0xc5, 0xbd, 0xa3, 0xad, 0xf0, 0xbf,
+ 0x7d, 0xad, 0xd5, 0xbd, 0xf6, 0xb2, 0x49, 0xbd, 0xeb, 0xbf, 0x53, 0xb1, 0xc7,
+ 0xc0, 0xdc, 0xb7, 0xca, 0xb8, 0x6c, 0xb5, 0xe5, 0xae, 0xe7, 0xb0, 0x6b, 0xb2,
+ 0x5e, 0xb3, 0xb3, 0xb0, 0x51, 0xae, 0x4d, 0xaf, 0x53, 0xc4, 0xf0, 0xc4, 0xcb,
+ 0xaf, 0x6b, 0xc1, 0xc3, 0xb1, 0xe8, 0xad, 0xe7, 0xbd, 0xf0, 0xbe, 0x4f, 0xb4,
+ 0xa3, 0xc3, 0x44, 0xbf, 0xe1, 0xb3, 0xda, 0xc5, 0xe9, 0xb4, 0xc0, 0xc0, 0xa1,
+ 0xb1, 0xa7, 0xae, 0xf7, 0xab, 0x63, 0xb1, 0x50, 0xa4, 0xd1, 0xb2, 0x4b, 0xb6,
+ 0xf1, 0xa5, 0xd0, 0xb2, 0xa2, 0xab, 0xef, 0xbb, 0x51, 0xb5, 0xc9, 0xac, 0x44,
+ 0xb1, 0xf8, 0xad, 0x7c, 0xb2, 0xb7, 0xb8, 0xf5, 0xb6, 0x4b, 0xc5, 0x4b, 0xa9,
+ 0xab, 0xc6, 0x55, 0xc5, 0xa5, 0xd6, 0x4c, 0xa5, 0xc5, 0xa7, 0xca, 0xb0, 0xb1,
+ 0xab, 0x46, 0xae, 0x78, 0xae, 0xbc, 0xb8, 0xa5, 0xb3, 0x71, 0xae, 0xe4, 0xe0,
+ 0xac, 0xc0, 0xfb, 0xa6, 0x50, 0xbb, 0xc9, 0xa7, 0xcd, 0xb5, 0xa3, 0xb1, 0xed,
+ 0xd1, 0xb6, 0xb5, 0xa9, 0xb2, 0xce, 0xb5, 0x68, 0xb0, 0xbd, 0xa7, 0xeb, 0xc0,
+ 0x59, 0xb3, 0x7a, 0xa5, 0x59, 0xa8, 0x72, 0xac, 0xf0, 0xb9, 0xcf, 0xae, 0x7b,
+ 0xb3, 0x7e, 0xb6, 0xee, 0xb1, 0x4f, 0xa4, 0x67, 0xa6, 0x52, 0xa8, 0xdf, 0xb4,
+ 0xf8, 0xb9, 0xce, 0xb1, 0xc0, 0xc0, 0x5a, 0xbb, 0x4c, 0xb8, 0xc0, 0xbf, 0xc6,
+ 0xb0, 0x68, 0xa7, 0x5d, 0xa4, 0xd9, 0xc1, 0x76, 0xa9, 0xec, 0xa6, 0xab, 0xb2,
+ 0xe6, 0xc0, 0x6b, 0xaa, 0xfb, 0xb9, 0xa4, 0xbe, 0x6d, 0xbe, 0xf2, 0xa7, 0xb4,
+ 0xa9, 0xdd, 0xb3, 0xe8, 0xab, 0xf5, 0xab, 0x7a, 0xb5, 0xec, 0xba, 0xda, 0xab,
+ 0xbd, 0xa5, 0xcb, 0xc4, 0xfb, 0xac, 0x6e, 0xa5, 0x7e, 0xbd, 0xdc, 0xc5, 0x73,
+ 0xc6, 0x57, 0xaa, 0xb1, 0xb9, 0x78, 0xa4, 0x59, 0xd6, 0x4a, 0xa7, 0xb9, 0xb8,
+ 0x4a, 0xae, 0xbe, 0xb1, 0xdf, 0xb5, 0x70, 0xb1, 0x7b, 0xa9, 0x7b, 0xb0, 0xfb,
+ 0xb8, 0x55, 0xb5, 0xc3, 0xa8, 0x4c, 0xa4, 0xfd, 0xa4, 0x60, 0xaa, 0x50, 0xba,
+ 0xf4, 0xa9, 0xb9, 0xa9, 0xf4, 0xb1, 0xe6, 0xa7, 0xd1, 0xa6, 0x6b, 0xab, 0xc2,
+ 0xc4, 0xde, 0xb7, 0x4c, 0xa6, 0x4d, 0xad, 0xb3, 0xb9, 0x48, 0xae, 0xe9, 0xb3,
+ 0xf2, 0xb0, 0xdf, 0xb1, 0xa9, 0xac, 0xb0, 0xc0, 0xe5, 0xba, 0xfb, 0xb8, 0xab,
+ 0xb5, 0xe4, 0xa9, 0x65, 0xb0, 0xb6, 0xb0, 0xb0, 0xa7, 0xc0, 0xbd, 0x6e, 0xa5,
+ 0xbc, 0xbd, 0xab, 0xa8, 0xfd, 0xac, 0xc8, 0xad, 0x47, 0xb3, 0xde, 0xc3, 0x51,
+ 0xa6, 0xec, 0xb4, 0xf4, 0xbf, 0xd7, 0xb1, 0x4c, 0xbc, 0xa2, 0xbd, 0xc3, 0xbd,
+ 0x45, 0xb7, 0xc5, 0xb0, 0x41, 0xa4, 0xe5, 0xbb, 0x44, 0xaf, 0xbe, 0xa7, 0x6b,
+ 0xc3, 0xad, 0xaf, 0xbf, 0xb0, 0xdd, 0xb6, 0xe4, 0xaf, 0xce, 0xc2, 0x7c, 0xbe,
+ 0xe2, 0xbd, 0xbd, 0xb4, 0xf5, 0xba, 0xdb, 0xa7, 0xda, 0xba, 0x57, 0xaa, 0xd7,
+ 0xb4, 0xa4, 0xa8, 0x55, 0xa7, 0xc5, 0xb6, 0xe3, 0xc2, 0xeb, 0xaf, 0x51, 0xa6,
+ 0xc3, 0xbb, 0x7a, 0xab, 0xce, 0xb5, 0x4c, 0xbf, 0xbe, 0xb1, 0xef, 0xa7, 0x5e,
+ 0xa7, 0x64, 0xa4, 0xf0, 0xaa, 0x5a, 0xa4, 0xad, 0xae, 0xb8, 0xa4, 0xc8, 0xbb,
+ 0x52, 0xa5, 0xee, 0xab, 0x56, 0xb6, 0xf5, 0xa5, 0xb3, 0xc3, 0xfa, 0xb1, 0xe0,
+ 0xaa, 0xab, 0xa4, 0xc5, 0xb0, 0xc8, 0xae, 0xa9, 0xbb, 0x7e, 0xa9, 0xf5, 0xba,
+ 0xb3, 0xaa, 0x52, 0xa6, 0xe8, 0xd6, 0xb4, 0xaa, 0xbf, 0xb4, 0xb7, 0xbc, 0x48,
+ 0xa7, 0x6c, 0xbf, 0xfc, 0xc4, 0xeb, 0xb5, 0x7d, 0xae, 0xa7, 0xa7, 0xc6, 0xb1,
+ 0x78, 0xbd, 0xa5, 0xa4, 0x69, 0xb1, 0xa4, 0xba, 0xb6, 0xb2, 0x6d, 0xb7, 0xcb,
+ 0xa6, 0xc1, 0xb5, 0x52, 0xc0, 0xca, 0xc5, 0xa7, 0xae, 0x75, 0xb2, 0xdf, 0xb7,
+ 0x40, 0xb3, 0xdf, 0xbb, 0xd1, 0xac, 0x7e, 0xa8, 0x74, 0xbb, 0xd8, 0xc0, 0xb8,
+ 0xb2, 0xd3, 0xbd, 0x4d, 0xbd, 0xbc, 0xa7, 0x58, 0xc1, 0xf8, 0xc1, 0xd2, 0xb7,
+ 0x76, 0xae, 0x6c, 0xab, 0x4c, 0xaf, 0x55, 0xa4, 0x55, 0xb7, 0x48, 0xae, 0x4c,
+ 0xc0, 0x7e, 0xb1, 0xc8, 0xa1, 0xbc, 0xa5, 0xfd, 0xa5, 0x50, 0xc2, 0x41, 0xc5,
+ 0xd6, 0xab, 0x77, 0xbd, 0xe5, 0xbb, 0xce, 0xb2, 0xec, 0xb6, 0xa2, 0xb2, 0x43,
+ 0xa9, 0xb6, 0xb6, 0xfb, 0xc5, 0xe3, 0xc0, 0x49, 0xb2, 0x7b, 0xc4, 0x6d, 0xbf,
+ 0xa4, 0xb8, 0xa2, 0xc0, 0x60, 0xb8, 0x72, 0xbe, 0xcb, 0xb3, 0xb4, 0xad, 0xad,
+ 0xbd, 0x75, 0xac, 0xdb, 0xb4, 0x5b, 0xc6, 0x5e, 0xad, 0xbb, 0xbd, 0x63, 0xc1,
+ 0xb8, 0xb4, 0xf0, 0xb6, 0x6d, 0xb5, 0xbe, 0xb2, 0xbb, 0xb8, 0xd4, 0xb7, 0x51,
+ 0xc5, 0x54, 0xa8, 0xc9, 0xb6, 0xb5, 0xab, 0xd1, 0xbe, 0xf3, 0xb9, 0xb3, 0xa6,
+ 0x56, 0xb6, 0x48, 0xbf, 0xbd, 0xb5, 0x76, 0xbe, 0x5d, 0xab, 0x64, 0xad, 0xfd,
+ 0xc4, 0xdb, 0xbe, 0x50, 0xae, 0xf8, 0xae, 0x64, 0xb2, 0x63, 0xbe, 0xe5, 0xa4,
+ 0x70, 0xa7, 0xb5, 0xae, 0xd5, 0xa8, 0x76, 0xbc, 0x53, 0xaf, 0xba, 0xae, 0xc4,
+ 0xb7, 0xa4, 0xa8, 0xc7, 0xb7, 0xb2, 0xc3, 0xc8, 0xbe, 0x63, 0xa8, 0xf3, 0xae,
+ 0xb5, 0xc4, 0xe2, 0xa8, 0xb8, 0xb1, 0xd7, 0xaf, 0xd9, 0xbf, 0xd3, 0xbc, 0x67,
+ 0xb1, 0xf1, 0xa8, 0xf8, 0xc3, 0xc9, 0xbe, 0xd3, 0xaa, 0x6e, 0xc2, 0x6d, 0xc1,
+ 0xc2, 0xae, 0x68, 0xc1, 0x7e, 0xaa, 0xe4, 0xbe, 0x4e, 0xaa, 0x59, 0xa8, 0xaf,
+ 0xb7, 0x73, 0xca, 0xe3, 0xa4, 0xdf, 0xab, 0x48, 0xf4, 0xb5, 0xac, 0x50, 0xb8,
+ 0x7b, 0xb5, 0x56, 0xb4, 0x69, 0xbf, 0xb3, 0xa6, 0x44, 0xab, 0xac, 0xa7, 0xce,
+ 0xa8, 0xb7, 0xa6, 0xe6, 0xbf, 0xf4, 0xa9, 0xaf, 0xa7, 0xf6, 0xa9, 0xca, 0xa9,
+ 0x6d, 0xa5, 0x53, 0xa5, 0xfb, 0xaf, 0xdd, 0xa6, 0x49, 0xac, 0xa4, 0xb6, 0xaf,
+ 0xba, 0xb5, 0xa5, 0xf0, 0xad, 0xd7, 0xb2, 0xdb, 0xa6, 0xb4, 0xb6, 0xe5, 0xc4,
+ 0xc3, 0xa8, 0x71, 0xb3, 0x53, 0xc2, 0xb8, 0xbc, 0x56, 0xa6, 0xa6, 0xbb, 0xdd,
+ 0xb5, 0xea, 0xbc, 0x4e, 0xb6, 0xb7, 0xae, 0x7d, 0xb3, 0x5c, 0xbb, 0x57, 0xb3,
+ 0xa4, 0xb1, 0xd4, 0xa6, 0xb0, 0xa7, 0xc7, 0xaf, 0x62, 0xab, 0xf2, 0xb5, 0xb6,
+ 0xb4, 0x42, 0xba, 0xfc, 0xc4, 0xf2, 0xb0, 0x61, 0xb3, 0xd9, 0xab, 0xc5, 0xc4,
+ 0x61, 0xb1, 0xdb, 0xa5, 0xc8, 0xbf, 0xef, 0xc5, 0x7e, 0xaf, 0x74, 0xb5, 0xba,
+ 0xb9, 0x75, 0xc1, 0xa7, 0xbe, 0xc7, 0xa5, 0xde, 0xb3, 0xb7, 0xa6, 0xe5, 0xb3,
+ 0xd4, 0xe2, 0xc0, 0xb4, 0x60, 0xa6, 0xaf, 0xb8, 0xdf, 0xb4, 0x4d, 0xb9, 0xa5,
+ 0xa8, 0xb5, 0xae, 0xee, 0xa6, 0xc4, 0xb0, 0x56, 0xb0, 0x54, 0xbb, 0xb9, 0xa8,
+ 0xb3, 0xc0, 0xa3, 0xa9, 0xe3, 0xbe, 0x7e, 0xc0, 0x6e, 0xa7, 0x72, 0xa4, 0x58,
+ 0xaa, 0xde, 0xa4, 0xfa, 0xb0, 0x48, 0xb1, 0x56, 0xb8, 0xc5, 0xb2, 0x50, 0xb6,
+ 0xae, 0xb0, 0xd7, 0xa8, 0xc8, 0xb3, 0x59, 0xb2, 0x6a, 0xc3, 0x60, 0xec, 0x49,
+ 0xb7, 0xcf, 0xb2, 0x54, 0xc6, 0x51, 0xc4, 0x59, 0xac, 0xe3, 0xe3, 0xe9, 0xc5,
+ 0xc9, 0xa9, 0xb5, 0xa8, 0xa5, 0xc3, 0x43, 0xc0, 0x46, 0xaa, 0xa2, 0xaa, 0x75,
+ 0xa9, 0x61, 0xb1, 0xbb, 0xb2, 0xb4, 0xad, 0x6c, 0xba, 0x74, 0xc6, 0x41, 0xb3,
+ 0xf7, 0xbf, 0x50, 0xb9, 0xbd, 0xb5, 0x78, 0xb6, 0xad, 0xad, 0xf1, 0xab, 0xdb,
+ 0xbf, 0x56, 0xae, 0x62, 0xbf, 0xce, 0xc5, 0xe7, 0xac, 0x6f, 0xa5, 0xa1, 0xc0,
+ 0x6d, 0xaf, 0xb1, 0xb7, 0xa8, 0xb4, 0xad, 0xa8, 0xcb, 0xba, 0xc5, 0xa6, 0xcf,
+ 0xac, 0x76, 0xb6, 0xa7, 0xae, 0xf1, 0xa5, 0xf5, 0xc4, 0x6f, 0xbe, 0x69, 0xbc,
+ 0xcb, 0xba, 0x79, 0xc1, 0xdc, 0xb8, 0x79, 0xa7, 0xaf, 0xba, 0xbd, 0xb7, 0x6e,
+ 0xb3, 0xf3, 0xbb, 0xbb, 0xbd, 0x60, 0xc1, 0xc1, 0xab, 0xc0, 0xab, 0x72, 0xaf,
+ 0xe6, 0xc3, 0xc4, 0xad, 0x6e, 0xc4, 0xa3, 0xb7, 0xa6, 0xbc, 0x4f, 0xad, 0x43,
+ 0xb7, 0xdd, 0xb3, 0xa5, 0xa7, 0x4d, 0xa4, 0x5d, 0xad, 0xb6, 0xb1, 0xb3, 0xb7,
+ 0x7e, 0xb8, 0xad, 0xa6, 0xb2, 0xb5, 0xc5, 0xa9, 0x5d, 0xb2, 0x47, 0xa4, 0x40,
+ 0xb3, 0xfc, 0xc2, 0xe5, 0xb4, 0xa5, 0xe4, 0x76, 0xa8, 0xcc, 0xa5, 0xec, 0xa6,
+ 0xe7, 0xc0, 0x5b, 0xa6, 0x69, 0xbf, 0xf2, 0xb2, 0xbe, 0xbb, 0xf6, 0xaf, 0xd8,
+ 0xba, 0xc3, 0xa8, 0x5e, 0xa9, 0x79, 0xab, 0xbc, 0xc2, 0x55, 0xb4, 0xc8, 0xc3,
+ 0xc6, 0xad, 0xca, 0xa4, 0x77, 0xa4, 0x41, 0xa8, 0x6f, 0xa5, 0x48, 0xc3, 0xc0,
+ 0xa7, 0xed, 0xa9, 0xf6, 0xa8, 0xb6, 0xa6, 0x7a, 0xbb, 0xf5, 0xa7, 0xd0, 0xc1,
+ 0x72, 0xb6, 0x68, 0xb8, 0x77, 0xac, 0xcc, 0xa5, 0xe7, 0xb8, 0xc7, 0xb7, 0x4e,
+ 0xbc, 0xdd, 0xbe, 0xd0, 0xb8, 0x71, 0xaf, 0x71, 0xb7, 0xb8, 0xb8, 0xda, 0xc4,
+ 0xb3, 0xbd, 0xcb, 0xc4, 0xb6, 0xb2, 0xa7, 0xc1, 0x6c, 0xb2, 0xdd, 0xc3, 0xb6,
+ 0xaf, 0xf4, 0xbd, 0xae, 0xa6, 0x5d, 0xae, 0xef, 0xad, 0xb5, 0xb3, 0xb1, 0xab,
+ 0xc3, 0xa7, 0x75, 0xbb, 0xc8, 0xb2, 0x5d, 0xb1, 0x47, 0xb6, 0xbc, 0xa4, 0xa8,
+ 0xa4, 0xde, 0xc1, 0xf4, 0xa6, 0x4c, 0xad, 0x5e, 0xc4, 0xe5, 0xc0, 0xa6, 0xc6,
+ 0x4e, 0xc0, 0xb3, 0xc5, 0xd5, 0xbc, 0xfc, 0xbf, 0xc3, 0xc0, 0xe7, 0xba, 0xb7,
+ 0xc3, 0xc7, 0xaa, 0xef, 0xc4, 0xb9, 0xac, 0xd5, 0xbc, 0x76, 0xbf, 0x6f, 0xb5,
+ 0x77, 0xac, 0x4d, 0xb3, 0xe9, 0xbe, 0xd6, 0xb6, 0xc4, 0xc1, 0x73, 0xf7, 0xea,
+ 0xb1, 0x65, 0xb9, 0x6c, 0xbf, 0xe3, 0xb8, 0xba, 0xb5, 0xfa, 0xaa, 0x61, 0xb4,
+ 0xe9, 0xa5, 0xc3, 0xb1, 0x76, 0xab, 0x69, 0xa5, 0xce, 0xab, 0xd5, 0xc0, 0x75,
+ 0xb1, 0x79, 0xbc, 0x7e, 0xa4, 0xd7, 0xa5, 0xd1, 0xb6, 0x6c, 0xb9, 0x5c, 0xb5,
+ 0x53, 0xaa, 0x6f, 0xb9, 0x43, 0xa8, 0xbb, 0xa6, 0xb3, 0xa4, 0xcd, 0xa5, 0x6b,
+ 0xa6, 0xf6, 0xb9, 0x56, 0xbb, 0xa4, 0xa4, 0x53, 0xa5, 0xae, 0xa8, 0xb1, 0xb2,
+ 0x4a, 0xa9, 0xf3, 0xaa, 0xbb, 0xb7, 0xae, 0xb8, 0xb7, 0xb7, 0x4d, 0xc1, 0xd6,
+ 0xa7, 0x45, 0xab, 0x5c, 0xb9, 0x4f, 0xb3, 0xbd, 0xb4, 0x72, 0xb4, 0xfc, 0xba,
+ 0xae, 0xb6, 0xa8, 0xa4, 0xa9, 0xae, 0x54, 0xab, 0x42, 0xbb, 0x50, 0xc0, 0xac,
+ 0xac, 0xea, 0xa6, 0x74, 0xbb, 0x79, 0xa6, 0xd0, 0xa5, 0xc9, 0xb0, 0xec, 0xa8,
+ 0xa1, 0xc6, 0x7b, 0xa6, 0x53, 0xb9, 0x4a, 0xb3, 0xeb, 0xae, 0x6e, 0xb1, 0x73,
+ 0xc2, 0xa1, 0xb1, 0xfd, 0xba, 0xbb, 0xa8, 0x7c, 0xc5, 0x41, 0xaf, 0x44, 0xb4,
+ 0x4a, 0xb8, 0xce, 0xb9, 0x77, 0xbf, 0xdd, 0xb6, 0xbf, 0xc0, 0x70, 0xb2, 0x57,
+ 0xad, 0xde, 0xa4, 0xb8, 0xab, 0xae, 0xb0, 0x4b, 0xad, 0xec, 0xb4, 0xa9, 0xc1,
+ 0xd5, 0xb6, 0xe9, 0xad, 0xfb, 0xb6, 0xea, 0xb7, 0xe1, 0xb7, 0xbd, 0xbd, 0x74,
+ 0xbb, 0xb7, 0xad, 0x62, 0xc4, 0x40, 0xab, 0xe8, 0xb0, 0x7c, 0xa4, 0xea, 0xac,
+ 0xf9, 0xb6, 0x56, 0xc5, 0x44, 0xc6, 0x5f, 0xa9, 0xa8, 0xb8, 0x66, 0xa4, 0xeb,
+ 0xae, 0xae, 0xbe, 0x5c, 0xaf, 0xd0, 0xb6, 0xb3, 0xe0, 0xa8, 0xa4, 0xc3, 0xb9,
+ 0x6b, 0xa4, 0xb9, 0xb9, 0x42, 0xc4, 0xad, 0xc1, 0xdf, 0xb7, 0x77, 0xc3, 0xfd,
+ 0xa5, 0xa5, 0xa5, 0x60, 0xaf, 0x7b, 0xc2, 0xf8, 0xae, 0xe2, 0xab, 0x76, 0xa8,
+ 0x61, 0xae, 0x5f, 0xb8, 0xfc, 0xa6, 0x41, 0xa6, 0x62, 0xab, 0xa5, 0xf6, 0xe3,
+ 0xbc, 0xc8, 0xc6, 0x67, 0xc5, 0x42, 0xc5, 0xa6, 0xb8, 0xae, 0xbe, 0x44, 0xc1,
+ 0x56, 0xc6, 0x77, 0xc4, 0xa6, 0xb4, 0xc7, 0xa6, 0xad, 0xbe, 0xfe, 0xb0, 0x44,
+ 0xc4, 0xbc, 0xbe, 0xb8, 0xb3, 0x79, 0xa8, 0x6d, 0xa8, 0x5f, 0xc0, 0xea, 0xb3,
+ 0x64, 0xbe, 0xdc, 0xab, 0x68, 0xbf, 0x41, 0xb8, 0xe9, 0xab, 0xe7, 0xbc, 0x57,
+ 0xbc, 0xa8, 0xb4, 0xbf, 0xc3, 0xd8, 0xb2, 0xcf, 0xb3, 0xe5, 0xb4, 0xed, 0xa5,
+ 0xbe, 0xaa, 0xee, 0xee, 0xd4, 0xb9, 0x68, 0xaf, 0x77, 0xac, 0x5d, 0xba, 0x5e,
+ 0xa9, 0x51, 0xa5, 0x45, 0xac, 0xb5, 0xb6, 0x42, 0xba, 0x4b, 0xc2, 0x4e, 0xa6,
+ 0x76, 0xaf, 0xb6, 0xb6, 0xc5, 0xb9, 0xeb, 0xc2, 0xa4, 0xc0, 0xd6, 0xb8, 0xe2,
+ 0xd6, 0xdf, 0xaa, 0x67, 0xb7, 0xf8, 0xb1, 0xd9, 0xc1, 0xd3, 0xb9, 0xf1, 0xae,
+ 0x69, 0xc5, 0xd9, 0xb4, 0xcc, 0xa6, 0xfb, 0xbe, 0xd4, 0xaf, 0xb8, 0xb4, 0xef,
+ 0xba, 0xec, 0xbc, 0xcc, 0xb3, 0xb9, 0xb9, 0xfc, 0xba, 0x73, 0xb1, 0x69, 0xb4,
+ 0x78, 0xba, 0xa6, 0xa7, 0xfa, 0xa4, 0x56, 0xb1, 0x62, 0xbd, 0xe3, 0xa5, 0x4d,
+ 0xb5, 0xc8, 0xbf, 0x60, 0xbb, 0xd9, 0xa9, 0xdb, 0xac, 0x4c, 0xa7, 0xe4, 0xaa,
+ 0x68, 0xbb, 0xaf, 0xb7, 0xd3, 0xb8, 0x6e, 0xa5, 0xfc, 0xbb, 0x46, 0xa5, 0x6c,
+ 0xbe, 0x42, 0xa7, 0xe9, 0xad, 0xf5, 0xee, 0x68, 0xc2, 0xe1, 0xaa, 0xcc, 0xeb,
+ 0xe3, 0xbd, 0xa9, 0xb3, 0x6f, 0xae, 0xfd, 0xac, 0xc3, 0xb7, 0x72, 0xaf, 0x75,
+ 0xba, 0xc2, 0xaf, 0x7a, 0xbf, 0xb2, 0xad, 0x73, 0xb0, 0x77, 0xb0, 0xbb, 0xaa,
+ 0x45, 0xaf, 0x6c, 0xb6, 0x45, 0xbe, 0x5f, 0xae, 0xb6, 0xc2, 0xed, 0xb0, 0x7d,
+ 0xbb, 0x5d, 0xb1, 0xc3, 0xb8, 0x43, 0xa9, 0xba, 0xb2, 0x75, 0xaa, 0xa7, 0xa9,
+ 0xc3, 0xbe, 0xe3, 0xac, 0x40, 0xa5, 0xbf, 0xac, 0x46, 0xb4, 0x56, 0xc4, 0x70,
+ 0xbe, 0x47, 0xb5, 0xfd, 0xaa, 0xdb, 0xaa, 0x4b, 0xa4, 0xe4, 0xa7, 0x73, 0xbb,
+ 0x6a, 0xaa, 0xbe, 0xaa, 0xcf, 0xaf, 0xd7, 0xa5, 0xc4, 0xa4, 0xa7, 0xc2, 0xb4,
+ 0xc2, 0xbe, 0xaa, 0xbd, 0xb4, 0xd3, 0xb4, 0xde, 0xb0, 0xf5, 0xad, 0xc8, 0xcb,
+ 0xbb, 0xa7, 0x7d, 0xab, 0xfc, 0xa4, 0xee, 0xb3, 0x6b, 0xb0, 0xa6, 0xa6, 0xae,
+ 0xaf, 0xc8, 0xa7, 0xd3, 0xbc, 0xb0, 0xc2, 0x59, 0xa6, 0xdc, 0xad, 0x50, 0xb8,
+ 0x6d, 0xbc, 0x6d, 0xab, 0xcf, 0xa8, 0xee, 0xb4, 0xbc, 0xaf, 0xb4, 0xb8, 0x58,
+ 0xbd, 0xe8, 0xaa, 0xa5, 0xb2, 0xa9, 0xba, 0xa2, 0xaa, 0x76, 0xb2, 0xbf, 0xa4,
+ 0xa4, 0xac, 0xd8, 0xa9, 0xbe, 0xc4, 0xc1, 0xb0, 0x4a, 0xb2, 0xd7, 0xba, 0xd8,
+ 0xb8, 0x7e, 0xad, 0xab, 0xa5, 0xf2, 0xb2, 0xb3, 0xa6, 0xe0, 0xa9, 0x50, 0xa6,
+ 0x7b, 0xac, 0x77, 0xee, 0xa4, 0xb5, 0xb0, 0xb6, 0x62, 0xa8, 0x79, 0xa9, 0xaa,
+ 0xa9, 0x47, 0xbd, 0x4b, 0xa9, 0x7a, 0xb1, 0xde, 0xc6, 0x4a, 0xaf, 0x5d, 0xae,
+ 0xe8, 0xb5, 0xef, 0xa6, 0xb6, 0xbd, 0xde, 0xbd, 0xd1, 0xb8, 0xdd, 0xb3, 0x76,
+ 0xa6, 0xcb, 0xc0, 0xeb, 0xb5, 0x4e, 0xa9, 0xd6, 0xc6, 0x66, 0xc5, 0xf1, 0xa5,
+ 0x44, 0xb5, 0xdb, 0xac, 0x57, 0xa7, 0x55, 0xb3, 0x45, 0xb6, 0x4a, 0xc5, 0xb1,
+ 0xbf, 0x76, 0xa6, 0xed, 0xaa, 0x60, 0xaf, 0xac, 0xbe, 0x6e, 0xa7, 0xec, 0xa4,
+ 0xf6, 0xab, 0xfb, 0xb1, 0x4d, 0xbf, 0x6a, 0xc2, 0xe0, 0xbc, 0xb6, 0xc1, 0xc8,
+ 0xbd, 0x66, 0xbc, 0xce, 0xb2, 0xf8, 0xb8, 0xcb, 0xa7, 0xa9, 0xbc, 0xb2, 0xa7,
+ 0xa7, 0xaa, 0xac, 0xb4, 0xd5, 0xc0, 0x40, 0xb0, 0x6c, 0xc2, 0xd8, 0xbc, 0x59,
+ 0xba, 0xf3, 0xbd, 0xce, 0xb7, 0xc7, 0xae, 0xbb, 0xa9, 0xe5, 0xa8, 0xf4, 0xae,
+ 0xe0, 0xb5, 0x5a, 0xad, 0x5f, 0xb0, 0x75, 0xb0, 0xd6, 0xb5, 0xdb, 0xa8, 0x60,
+ 0xbf, 0x42, 0xaf, 0xf7, 0xab, 0x74, 0xb8, 0xea, 0xab, 0xba, 0xb4, 0xfe, 0xb2,
+ 0x64, 0xa7, 0xb6, 0xb5, 0xb5, 0xa5, 0x4a, 0xac, 0xf3, 0xb7, 0xba, 0xa4, 0x6c,
+ 0xa6, 0xdb, 0xba, 0x7b, 0xa6, 0x72, 0xc3, 0x4f, 0xb4, 0xc4, 0xc2, 0xdc, 0xa9,
+ 0x76, 0xba, 0xee, 0xc1, 0x60, 0xc1, 0x61, 0xb9, 0x51, 0xa8, 0xab, 0xab, 0xb5,
+ 0xb4, 0x7e, 0xaf, 0xb2, 0xa8, 0xac, 0xa8, 0xf2, 0xb1, 0xda, 0xaf, 0xaa, 0xb6,
+ 0x41, 0xaa, 0xfd, 0xb2, 0xd5, 0xc6, 0x70, 0xc4, 0xa1, 0xbc, 0x4c, 0xbe, 0x4b,
+ 0xb3, 0xcc, 0xb8, 0x6f, 0xb4, 0x4c, 0xbf, 0xed, 0xac, 0x51, 0xa5, 0xaa, 0xa6,
+ 0xf5, 0xac, 0x67, 0xb0, 0xb5, 0xa7, 0x40, 0xa7, 0xa4, 0xae, 0x79, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xc9, 0x48, 0xc9, 0x46, 0xa4,
+ 0x61, 0xa4, 0xa2, 0xa4, 0xdc, 0xa4, 0xca, 0xa5, 0x41, 0xa5, 0xe5, 0xa5, 0xe0,
+ 0xb0, 0xac, 0xd1, 0x65, 0xbe, 0xb5, 0xa1, 0xbc, 0xac, 0xeb, 0xa1, 0xbc, 0xa4,
+ 0x50, 0xc9, 0x47, 0xa4, 0xd4, 0xa4, 0xf8, 0xa5, 0x67, 0xa5, 0xc2, 0xc9, 0xc7,
+ 0xad, 0x4e, 0xd8, 0x50, 0xb7, 0xb6, 0xe2, 0xe9, 0xa1, 0xbc, 0xa1, 0xbc, 0xab,
+ 0x45, 0xe8, 0xf3, 0xc9, 0x41, 0xa5, 0xe4, 0xc9, 0x51, 0xaa, 0xcb, 0xa7, 0xb8,
+ 0xb6, 0xde, 0xe1, 0x4c, 0xa4, 0xb7, 0xcd, 0xf8, 0xad, 0xed, 0xf1, 0xef, 0xb3,
+ 0xd6, 0xbc, 0x72, 0xc5, 0xe2, 0xc5, 0xac, 0xc9, 0x43, 0xa5, 0x72, 0xd4, 0x6f,
+ 0xb9, 0xbc, 0xb0, 0xd0, 0xf0, 0xf3, 0xa8, 0xf6, 0xca, 0x72, 0xa1, 0xbc, 0xa4,
+ 0xc2, 0xa6, 0x46, 0xcd, 0xf0, 0xcb, 0xd2, 0xe4, 0xf3, 0xb3, 0xcf, 0xab, 0x66,
+ 0xd0, 0xe9, 0xd0, 0xe6, 0xad, 0xe6, 0xe3, 0xc7, 0xb6, 0xd1, 0xb9, 0xbb, 0xe1,
+ 0x42, 0xa1, 0xbc, 0xbe, 0xb0, 0xa1, 0xbc, 0xaa, 0xc9, 0xa1, 0xbc, 0xa4, 0xb1,
+ 0xc9, 0x53, 0xc9, 0x52, 0xc9, 0x65, 0xc9, 0x68, 0xa1, 0xbc, 0xa5, 0x51, 0xdc,
+ 0xba, 0xa5, 0xf6, 0xc9, 0xb7, 0xca, 0x5f, 0xc9, 0xae, 0xad, 0xce, 0xb3, 0xc9,
+ 0xa5, 0xea, 0xa6, 0xee, 0xa6, 0xf0, 0xca, 0x61, 0xa7, 0xf1, 0xa7, 0x48, 0xa7,
+ 0x46, 0xca, 0x63, 0xa6, 0xef, 0xa1, 0xbc, 0xa6, 0xf7, 0xcb, 0xb8, 0xcb, 0xb9,
+ 0xa8, 0xdd, 0xcb, 0xba, 0xa8, 0xd4, 0xa8, 0xdc, 0xa8, 0xdb, 0xa8, 0xd9, 0xbe,
+ 0xab, 0xcb, 0xb3, 0xbb, 0xfa, 0xcb, 0xc6, 0xbe, 0xa9, 0xc5, 0x6b, 0xc4, 0xd7,
+ 0xcd, 0xde, 0xab, 0x5a, 0xcd, 0xe3, 0xcd, 0xe5, 0xab, 0x4d, 0xab, 0x53, 0xad,
+ 0xc4, 0xad, 0xc5, 0xb0, 0xb4, 0xad, 0xd6, 0xd0, 0xd3, 0xb0, 0xbf, 0xa1, 0xbc,
+ 0xad, 0xd8, 0xad, 0xda, 0xd0, 0xd7, 0xad, 0xbe, 0xad, 0xc3, 0xad, 0xd0, 0xe0,
+ 0xf3, 0xb0, 0xb3, 0xb0, 0xba, 0xd4, 0x55, 0xb0, 0xb9, 0xb6, 0xcd, 0xdc, 0xbc,
+ 0xc5, 0x6c, 0xbe, 0xaa, 0xf5, 0xc0, 0xdc, 0xbf, 0xb9, 0xaf, 0xe4, 0xea, 0xb9,
+ 0xb0, 0xe0, 0xfa, 0xe0, 0xf0, 0xb9, 0xad, 0xe4, 0xeb, 0xe4, 0xee, 0xc9, 0x69,
+ 0xc9, 0xf8, 0xca, 0x65, 0xdc, 0xc2, 0xab, 0x5b, 0xef, 0xb6, 0xc9, 0xf8, 0xf7,
+ 0x40, 0xa4, 0xbc, 0xb4, 0x53, 0xc6, 0x64, 0xef, 0x55, 0xf6, 0xd8, 0xc4, 0xdc,
+ 0xa1, 0xbc, 0xab, 0x6d, 0xd0, 0xb1, 0xb0, 0xcb, 0xe0, 0xed, 0xa6, 0x67, 0xa8,
+ 0xe1, 0xa1, 0xbc, 0xab, 0x5e, 0xad, 0xbd, 0xb3, 0x4f, 0xd7, 0xc0, 0xc1, 0xb6,
+ 0xf9, 0x43, 0xb8, 0xcf, 0xb8, 0x5b, 0xbe, 0xc6, 0xf2, 0xdd, 0xc3, 0xbd, 0xa1,
+ 0xbc, 0xc9, 0xbc, 0xa8, 0xe6, 0xcb, 0xce, 0xa1, 0xbc, 0xa1, 0xbc, 0xb6, 0xef,
+ 0xad, 0xdf, 0xf3, 0x65, 0xb0, 0x50, 0xb0, 0x52, 0xb0, 0x53, 0xf0, 0xdd, 0xdb,
+ 0xd6, 0xb3, 0x5b, 0xb5, 0xfe, 0xb6, 0x46, 0xb6, 0x43, 0xdb, 0xdc, 0xb6, 0x40,
+ 0xdb, 0xdf, 0xe0, 0x46, 0xe0, 0x4c, 0xe0, 0x47, 0xb8, 0xd7, 0xb8, 0xd9, 0xe0,
+ 0x4d, 0xb8, 0xe1, 0xb8, 0xe0, 0xbd, 0xd8, 0xeb, 0xa1, 0xe0, 0x48, 0xbb, 0xa6,
+ 0xbb, 0xa2, 0xbb, 0xa5, 0xe4, 0x4d, 0xe7, 0xd4, 0xe7, 0xd8, 0xbd, 0xd3, 0xbd,
+ 0xdb, 0xe7, 0xdc, 0xbd, 0xd4, 0xbd, 0xd9, 0xbf, 0xdb, 0xbf, 0xcf, 0xeb, 0xa6,
+ 0xbf, 0xd6, 0xeb, 0xa7, 0xbf, 0xd9, 0xbf, 0xdc, 0xbf, 0xda, 0xbf, 0xcd, 0xbf,
+ 0xd4, 0xeb, 0xab, 0xc2, 0xd3, 0xc6, 0x6d, 0xee, 0xa2, 0xee, 0xb0, 0xc1, 0xc4,
+ 0xc2, 0xd6, 0xf7, 0x56, 0xf2, 0xfb, 0xc3, 0xd7, 0xc3, 0xd4, 0xf9, 0xa9, 0xc4,
+ 0xb8, 0xc6, 0x40, 0xa1, 0xbc, 0xce, 0xaf, 0xa1, 0xbc, 0xca, 0x56, 0xa6, 0xe9,
+ 0xa8, 0xc0, 0xa8, 0xc1, 0xcd, 0xd9, 0xcd, 0xda, 0xab, 0x40, 0xb0, 0xa4, 0xd0,
+ 0xc2, 0xd4, 0x46, 0xdc, 0xa1, 0xb3, 0xb5, 0xb6, 0xab, 0xb3, 0xb2, 0xdc, 0x7e,
+ 0xb6, 0xaa, 0xe0, 0xd4, 0xee, 0xf5, 0xca, 0x52, 0xca, 0x54, 0xf1, 0x4b, 0xca,
+ 0x51, 0xe0, 0xa9, 0xcb, 0xa8, 0xcd, 0xd4, 0xcd, 0xd6, 0xaa, 0xf5, 0xbf, 0xf3,
+ 0xaa, 0xf3, 0xcd, 0xd7, 0xd3, 0xf7, 0xd0, 0xbb, 0xd0, 0xbc, 0xeb, 0xd7, 0xa1,
+ 0xbc, 0xd0, 0xbd, 0xdc, 0x50, 0xc5, 0xb0, 0xb0, 0x72, 0xd3, 0xfc, 0xd3, 0xfb,
+ 0xd3, 0xfa, 0xd7, 0xef, 0xd7, 0xe8, 0xb6, 0x6e, 0xdc, 0x52, 0xe4, 0x6b, 0xbb,
+ 0xc2, 0xe4, 0x68, 0xbe, 0x49, 0xe8, 0x54, 0xc1, 0xdd, 0xf4, 0xe1, 0xf6, 0x5a,
+ 0xaf, 0xec, 0xab, 0xb7, 0xe4, 0xf4, 0xa7, 0x57, 0xca, 0x6f, 0xa8, 0xf0, 0xd0,
+ 0xf8, 0xa1, 0xbc, 0xd4, 0x6d, 0xbc, 0x45, 0xad, 0xee, 0xc0, 0xe8, 0xf4, 0x77,
+ 0xa1, 0xbc, 0xc9, 0x42, 0xa1, 0xbc, 0xd4, 0x4a, 0xa1, 0xbc, 0xa5, 0xaf, 0xaf,
+ 0x63, 0xd0, 0x57, 0xca, 0xac, 0xb0, 0xee, 0xa1, 0xbc, 0xb9, 0xd1, 0xe9, 0x4f,
+ 0xbe, 0xc3, 0xc0, 0xa4, 0xa6, 0x66, 0xa6, 0x64, 0xc9, 0xc9, 0xa6, 0x60, 0xc2,
+ 0x52, 0xc9, 0xc8, 0xa6, 0x65, 0xc3, 0x63, 0xa7, 0xa6, 0xa1, 0xbc, 0xa9, 0x58,
+ 0xa1, 0xbc, 0xcb, 0xf5, 0xf1, 0xf6, 0xa9, 0x5c, 0xcb, 0xfb, 0xcc, 0x40, 0xcb,
+ 0xf4, 0xcb, 0xf8, 0xcb, 0xfc, 0xd4, 0xc1, 0xce, 0x53, 0xce, 0x54, 0xdc, 0xe5,
+ 0xd4, 0xba, 0xa1, 0xbc, 0xa1, 0xbc, 0xab, 0xb2, 0xab, 0xad, 0xd1, 0x4c, 0xb6,
+ 0xf6, 0xb3, 0xfa, 0xdc, 0xe4, 0xd1, 0x4d, 0xd1, 0x52, 0xd4, 0xb2, 0xa1, 0xbc,
+ 0xd4, 0xb7, 0xb0, 0xf1, 0xa1, 0xbc, 0xd4, 0xb8, 0xd4, 0xcb, 0xd4, 0xb5, 0xd4,
+ 0xb4, 0xd4, 0xb3, 0xd8, 0xa2, 0xd8, 0xa1, 0xa1, 0xbc, 0xb3, 0xfb, 0xdc, 0xed,
+ 0xa1, 0xbc, 0xe1, 0x5b, 0xe1, 0x56, 0xa1, 0xbc, 0xbc, 0x55, 0xc4, 0xc9, 0xc5,
+ 0x67, 0xc5, 0x74, 0xa1, 0xbc, 0xca, 0x4d, 0xca, 0x4e, 0xcb, 0x7a, 0xcb, 0xa1,
+ 0xcd, 0xbf, 0xcb, 0xa3, 0xcb, 0x7c, 0xcb, 0x7d, 0xeb, 0x52, 0xaa, 0xdc, 0xcd,
+ 0xb4, 0xea, 0xfc, 0xaa, 0xe8, 0xaa, 0xe7, 0xf4, 0xbe, 0xa1, 0xbc, 0xad, 0x55,
+ 0xcd, 0xb6, 0xaa, 0xe9, 0xcd, 0xba, 0xb3, 0x41, 0xb5, 0xe7, 0xe7, 0x76, 0xcd,
+ 0xc1, 0xcd, 0xbe, 0xcd, 0xc0, 0xa1, 0xbc, 0xaa, 0xdf, 0xa1, 0xbc, 0xad, 0x52,
+ 0xcd, 0xc3, 0xd0, 0x77, 0xad, 0x5b, 0xa1, 0xbc, 0xd0, 0xa1, 0xf4, 0xb8, 0xd0,
+ 0x6e, 0xad, 0x60, 0xd0, 0x75, 0xad, 0x5c, 0xa1, 0xbc, 0xd0, 0x7a, 0xd0, 0x7b,
+ 0xad, 0x64, 0xe7, 0x72, 0xa1, 0xbc, 0xad, 0x67, 0xb6, 0xf7, 0xde, 0x72, 0xd0,
+ 0xa2, 0xd0, 0x71, 0xd3, 0x7d, 0xd3, 0x77, 0xea, 0xfe, 0xe7, 0x6e, 0xd3, 0xa5,
+ 0xb2, 0xf7, 0xd3, 0xa6, 0xaf, 0xf5, 0xaf, 0xfc, 0xd7, 0x6c, 0xeb, 0x4c, 0xd3,
+ 0xac, 0xaf, 0xf6, 0xd3, 0xae, 0xaf, 0xfe, 0xee, 0x50, 0xaf, 0xfb, 0xaf, 0xfa,
+ 0xc2, 0xc9, 0xd3, 0x74, 0xd0, 0x72, 0xd3, 0x73, 0xba, 0xba, 0xe2, 0x6c, 0xeb,
+ 0x43, 0xd3, 0xa3, 0xf0, 0xb0, 0xa1, 0xbc, 0xbb, 0x5e, 0xdf, 0xd2, 0xa1, 0xbc,
+ 0xd7, 0x74, 0xb2, 0xf2, 0xe3, 0xc2, 0xb8, 0xb1, 0xb2, 0xfb, 0xd7, 0x6d, 0xb2,
+ 0xf9, 0xa1, 0xbc, 0xbb, 0x59, 0xb2, 0xfe, 0xee, 0x56, 0xd7, 0x67, 0xd7, 0x68,
+ 0xeb, 0x4f, 0xb2, 0xfd, 0xb2, 0xf1, 0xb2, 0xf0, 0xd7, 0x5b, 0xc5, 0x61, 0xa1,
+ 0xbc, 0xb5, 0xd7, 0xdb, 0x6d, 0xdb, 0x6f, 0xdb, 0x70, 0xd4, 0xbb, 0xa1, 0xbc,
+ 0xb5, 0xd6, 0xdb, 0x6e, 0xb5, 0xe0, 0xdb, 0x75, 0xa1, 0xbc, 0xb5, 0xe3, 0xdb,
+ 0x7b, 0xdb, 0x7c, 0xb5, 0xe8, 0xb5, 0xe9, 0xdb, 0x79, 0xb5, 0xd1, 0xb5, 0xd2,
+ 0xdb, 0x5e, 0xdb, 0xa5, 0xb5, 0xd5, 0xdb, 0x60, 0xbf, 0xa2, 0xb5, 0xdd, 0xdb,
+ 0x72, 0xa1, 0xbc, 0xdf, 0xb1, 0xdf, 0xb8, 0xdf, 0xb9, 0xdf, 0xbb, 0xeb, 0x41,
+ 0xa1, 0xbc, 0xdf, 0xc2, 0xeb, 0x44, 0xdf, 0xc4, 0xb8, 0xb0, 0xb8, 0xb6, 0xb8,
+ 0xb4, 0xdf, 0xac, 0xe7, 0x6f, 0xdf, 0xd5, 0xb8, 0xa9, 0xb8, 0xb5, 0xe3, 0xb8,
+ 0xe3, 0xb9, 0xe3, 0xbd, 0xc5, 0x5a, 0xa1, 0xbc, 0xbb, 0x5f, 0xbb, 0x63, 0xbb,
+ 0x55, 0xe3, 0xb0, 0xf7, 0xf0, 0xe3, 0xae, 0xe3, 0xb6, 0xe3, 0xb7, 0xe3, 0xac,
+ 0xf1, 0x6a, 0xee, 0x40, 0xe7, 0x5c, 0xbf, 0x5f, 0xa1, 0xbc, 0xe7, 0x75, 0xf5,
+ 0xfd, 0xe7, 0x54, 0xc4, 0xa9, 0xea, 0xf8, 0xe7, 0x4d, 0xbd, 0xb6, 0xe7, 0x64,
+ 0xbf, 0xb7, 0xbf, 0xb8, 0xbf, 0xb9, 0xeb, 0x42, 0xbf, 0xbf, 0xee, 0x44, 0xea,
+ 0x7b, 0xbf, 0xbb, 0xf4, 0xbf, 0xed, 0xfb, 0xed, 0xfc, 0xc1, 0xa9, 0xc1, 0xa8,
+ 0xed, 0xf5, 0xee, 0x52, 0xc3, 0xc1, 0xc1, 0xa3, 0xee, 0x51, 0xc2, 0xca, 0xf0,
+ 0xb8, 0xc2, 0xc8, 0xc4, 0xf6, 0xa1, 0xbc, 0xf2, 0xd4, 0xf4, 0xb9, 0xf5, 0xf8,
+ 0xf4, 0xc1, 0xf5, 0xfc, 0xc4, 0xf4, 0xf7, 0xf3, 0xa4, 0x7b, 0xab, 0xd9, 0xc9,
+ 0xcb, 0xb9, 0xdd, 0xd0, 0x55, 0xab, 0xb3, 0xae, 0x4f, 0xae, 0x4e, 0xb0, 0xcc,
+ 0xa4, 0x71, 0xc9, 0xd5, 0xa7, 0xbc, 0xc0, 0xaa, 0xa1, 0xbc, 0xb1, 0xbf, 0xe1,
+ 0xde, 0xcc, 0xbd, 0xcc, 0xb9, 0xa9, 0xe9, 0xa9, 0xed, 0xab, 0xfa, 0xe5, 0xb9,
+ 0xce, 0xdf, 0xd1, 0xba, 0xd1, 0xbb, 0xd1, 0xb8, 0xd5, 0x6d, 0xd9, 0x5e, 0xb1,
+ 0xba, 0xb1, 0xcc, 0xd5, 0x71, 0xba, 0x51, 0xd5, 0x79, 0xb1, 0xc5, 0xd5, 0x68,
+ 0xb1, 0xca, 0xd5, 0x7a, 0xe1, 0xe8, 0xd9, 0x60, 0xa1, 0xbc, 0xd9, 0x5d, 0xbc,
+ 0xc3, 0xd9, 0x67, 0xa1, 0xbc, 0xd9, 0x55, 0xb4, 0xac, 0xb4, 0x7d, 0xd9, 0x64,
+ 0xef, 0xd2, 0xdd, 0xae, 0xdd, 0xb6, 0xdd, 0xb8, 0xdd, 0x7d, 0xdd, 0xaa, 0xdd,
+ 0xab, 0xdd, 0xba, 0xe1, 0xe7, 0xf4, 0x4c, 0xba, 0x54, 0xe5, 0xaf, 0xba, 0x50,
+ 0xc2, 0x5e, 0xef, 0xd7, 0xbc, 0xc1, 0xf5, 0xcd, 0xa1, 0xbc, 0xe9, 0xa6, 0xe9,
+ 0xa4, 0xec, 0xec, 0xc0, 0xc2, 0xf2, 0x45, 0xf7, 0xdd, 0xf8, 0xef, 0xa4, 0x7c,
+ 0xca, 0xd6, 0xa1, 0xbc, 0xb7, 0x49, 0xa1, 0xbc, 0xa5, 0x77, 0xbc, 0x54, 0xa5,
+ 0x6e, 0xa5, 0x6f, 0xa5, 0x7b, 0xa6, 0x5c, 0xa1, 0xbc, 0xa6, 0x5b, 0xa1, 0xbc,
+ 0xe5, 0x46, 0xc5, 0x6d, 0xca, 0x79, 0xf1, 0xf2, 0xa7, 0x63, 0xa1, 0xbc, 0xd0,
+ 0xf9, 0xce, 0x4a, 0xa1, 0xbc, 0xa1, 0xbc, 0xcb, 0xdf, 0xa1, 0xbc, 0xa9, 0x45,
+ 0xa9, 0x4b, 0xcb, 0xef, 0xa9, 0x4e, 0xc0, 0x7b, 0xa9, 0x46, 0xa9, 0x4c, 0xcb,
+ 0xe7, 0xa1, 0xbc, 0xa1, 0xbc, 0xcd, 0xfc, 0xab, 0x7b, 0xa1, 0xbc, 0xe8, 0xfd,
+ 0xab, 0xa8, 0xab, 0x78, 0xe4, 0xf9, 0xb9, 0xcd, 0xce, 0x4d, 0xa1, 0xbc, 0xe9,
+ 0x41, 0xab, 0xa6, 0xab, 0xa9, 0xa1, 0xbc, 0xe9, 0x44, 0xa1, 0xbc, 0xec, 0xc1,
+ 0xab, 0xa7, 0xab, 0x7d, 0xa1, 0xbc, 0xbe, 0xba, 0xcd, 0xfe, 0xce, 0x4e, 0xe1,
+ 0x4d, 0xd0, 0xf4, 0xbc, 0x47, 0xae, 0x43, 0xad, 0xf8, 0xd0, 0xf5, 0xdc, 0xd4,
+ 0xa1, 0xbc, 0xae, 0x44, 0xd0, 0xfc, 0xae, 0x41, 0xd4, 0x77, 0xb9, 0xc9, 0xd8,
+ 0x6f, 0xd8, 0x70, 0xa1, 0xbc, 0xc4, 0xda, 0xb0, 0xe7, 0xb0, 0xde, 0xa1, 0xbc,
+ 0xd4, 0x75, 0xd4, 0x73, 0xad, 0xf2, 0xb0, 0xdc, 0xd4, 0x71, 0xd4, 0x72, 0xd8,
+ 0x6a, 0xb0, 0xe6, 0xd4, 0x7c, 0xb0, 0xe3, 0xb3, 0xe3, 0xdc, 0xd6, 0xb3, 0xe4,
+ 0xb3, 0xed, 0xa1, 0xbc, 0xd8, 0x6e, 0xd8, 0x71, 0xb3, 0xe7, 0xb3, 0xee, 0xdc,
+ 0xdb, 0xd8, 0x66, 0xb3, 0xd7, 0xb6, 0xd8, 0xb9, 0xc6, 0xf4, 0x41, 0xb3, 0xe1,
+ 0xb3, 0xf1, 0xa1, 0xbc, 0xb9, 0xc8, 0xb6, 0xe8, 0xb9, 0xca, 0xb6, 0xdf, 0xc4,
+ 0xd9, 0xa1, 0xbc, 0xdc, 0xd2, 0xb6, 0xdb, 0xdc, 0xd0, 0xdc, 0xd3, 0xb6, 0xe2,
+ 0xb6, 0xe7, 0xdc, 0xdd, 0xbe, 0xbc, 0xdc, 0xcc, 0xdc, 0xde, 0xb6, 0xd9, 0xa1,
+ 0xbc, 0xb6, 0xe1, 0xc5, 0xaf, 0xa1, 0xbc, 0xb9, 0xcb, 0xe1, 0x49, 0xe1, 0x4e,
+ 0xc4, 0x58, 0xa1, 0xbc, 0xb9, 0xbe, 0xb9, 0xbf, 0xe1, 0x47, 0xa1, 0xbc, 0xe4,
+ 0xfe, 0xbc, 0x49, 0xbc, 0x50, 0xe5, 0x44, 0xa1, 0xbc, 0xbe, 0xbe, 0xbe, 0xb2,
+ 0xc2, 0x50, 0xe4, 0xf8, 0xa1, 0xbc, 0xec, 0xc3, 0xbe, 0xb6, 0xbe, 0xbb, 0xbe,
+ 0xb3, 0xa1, 0xbc, 0xa1, 0xbc, 0xc0, 0x7d, 0xec, 0xc0, 0xa1, 0xbc, 0xf8, 0xee,
+ 0xc9, 0x49, 0xa6, 0x5f, 0xc9, 0xc6, 0xd4, 0xac, 0xa7, 0x7a, 0xcb, 0xf1, 0xab,
+ 0xaa, 0xae, 0x46, 0xd4, 0xab, 0xb0, 0xeb, 0xe9, 0x47, 0xb4, 0x57, 0xcc, 0x6f,
+ 0xcc, 0x6e, 0xa9, 0xae, 0xec, 0xdb, 0xe1, 0xb2, 0xb9, 0xf6, 0xb1, 0x63, 0xd8,
+ 0xf2, 0xb9, 0xf7, 0xb9, 0xf3, 0xa1, 0xbc, 0xbc, 0x6e, 0xa7, 0xc4, 0xc9, 0xd7,
+ 0xca, 0xc0, 0xa7, 0xc1, 0xb9, 0xf2, 0xca, 0xc2, 0xae, 0x73, 0xa1, 0xbc, 0xa7,
+ 0xc2, 0xb4, 0x50, 0xa1, 0xbc, 0xcc, 0x5e, 0xcc, 0x65, 0xa1, 0xbc, 0xcc, 0x61,
+ 0xa9, 0xa6, 0xa9, 0xa7, 0xcc, 0x63, 0xa1, 0xbc, 0xa9, 0xa2, 0xe9, 0x61, 0xab,
+ 0xd0, 0xe5, 0x69, 0xce, 0x7d, 0xb1, 0x57, 0xe5, 0x63, 0xd4, 0xfb, 0xb1, 0x5d,
+ 0xd4, 0xfc, 0xd5, 0x44, 0xb1, 0x5c, 0xd4, 0xf4, 0xb1, 0x53, 0xb1, 0x55, 0xc0,
+ 0xaf, 0xa1, 0xbc, 0xb4, 0x51, 0xd8, 0xe6, 0xdd, 0x52, 0xd8, 0xe3, 0xb7, 0x44,
+ 0xe1, 0xa8, 0xd8, 0xdb, 0xd8, 0xdd, 0xdd, 0x4f, 0xb7, 0x43, 0xa1, 0xbc, 0xe1,
+ 0xa3, 0xe5, 0x62, 0xbc, 0x6a, 0xc1, 0xc7, 0xec, 0xda, 0xc5, 0x71, 0xc9, 0x4c,
+ 0xa7, 0xcf, 0xcc, 0x75, 0xab, 0xe0, 0xab, 0xe2, 0xab, 0xe1, 0xb1, 0x74, 0xb1,
+ 0x70, 0xb1, 0x75, 0xb4, 0x61, 0xdd, 0x64, 0xbc, 0x78, 0xe9, 0x75, 0xc5, 0xfc,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xc9, 0xa6, 0xca, 0x43, 0xc2, 0x78, 0xa1, 0xbc, 0xcb,
+ 0x63, 0xcb, 0x65, 0xaa, 0xad, 0xa1, 0xbc, 0xcd, 0x61, 0xcf, 0xc0, 0xea, 0x61,
+ 0xac, 0xbc, 0xde, 0xac, 0xd2, 0xa5, 0xaf, 0x58, 0xd2, 0xaa, 0xd2, 0xa8, 0xea,
+ 0x60, 0xd2, 0xa4, 0xd2, 0xa9, 0xd6, 0x61, 0xb2, 0x74, 0xc5, 0x7a, 0xd6, 0x65,
+ 0xd6, 0x69, 0xd6, 0x60, 0xf4, 0x6e, 0xda, 0x70, 0xa1, 0xbc, 0xb5, 0x54, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xda, 0x71, 0xba, 0xbc, 0xe2, 0xcb, 0xbc, 0xfb, 0xe6, 0x79,
+ 0xea, 0x5e, 0xed, 0x65, 0xf5, 0xdd, 0xa6, 0xdf, 0xb9, 0xd9, 0xb6, 0xb8, 0xb9,
+ 0xdb, 0xa1, 0xbc, 0xa1, 0xbc, 0xef, 0x4f, 0xb6, 0xbb, 0xf1, 0xad, 0xb6, 0xb9,
+ 0xdc, 0xae, 0xb6, 0xbd, 0xb9, 0x7e, 0xbb, 0xe8, 0xe8, 0xc1, 0xbe, 0x6c, 0xc0,
+ 0x5f, 0xa1, 0xbc, 0xc3, 0x49, 0xf3, 0xb1, 0xf3, 0xaf, 0xc4, 0x44, 0xa1, 0xbc,
+ 0xf5, 0x57, 0xa1, 0xbc, 0xc9, 0x79, 0xe5, 0x75, 0xca, 0xcd, 0xa9, 0xb4, 0xce,
+ 0xba, 0xab, 0xd6, 0xd5, 0x49, 0xb1, 0x67, 0xb1, 0x68, 0xd5, 0x4b, 0xbd, 0xe9,
+ 0xe1, 0xbc, 0xe1, 0xb6, 0xe5, 0x73, 0xe9, 0x72, 0xe9, 0x6f, 0xc1, 0x74, 0xa1,
+ 0xbc, 0xc9, 0x7b, 0xa6, 0xa4, 0xc4, 0x62, 0xbc, 0xad, 0xca, 0xdb, 0xe1, 0xd3,
+ 0xca, 0xdd, 0xca, 0xde, 0xb7, 0x5a, 0xb1, 0xa3, 0xb7, 0x5b, 0xa7, 0xd8, 0xca,
+ 0xd9, 0xa7, 0xd7, 0xcc, 0x7c, 0xa9, 0xc5, 0xcc, 0x7b, 0xa9, 0xcd, 0xa9, 0xc2,
+ 0xcc, 0xa9, 0xa9, 0xcb, 0xa9, 0xcc, 0xcc, 0xa2, 0xe9, 0x7d, 0xa9, 0xc9, 0xba,
+ 0x45, 0xec, 0xe6, 0xb4, 0x6c, 0xb7, 0x5f, 0xce, 0xcb, 0xab, 0xf1, 0xd9, 0x40,
+ 0xae, 0xaf, 0xae, 0xaa, 0xe1, 0xc7, 0xd1, 0xa7, 0xd1, 0xa8, 0xd1, 0xa5, 0xae,
+ 0xad, 0xd1, 0xaa, 0xb4, 0x67, 0xb1, 0xa2, 0xd5, 0x5e, 0xd5, 0x5c, 0xb1, 0xa6,
+ 0xb1, 0xa8, 0xb1, 0xab, 0xb1, 0x7c, 0xb7, 0x59, 0xe5, 0xa6, 0xb4, 0x6a, 0xb4,
+ 0x68, 0xb4, 0x6d, 0xb4, 0x73, 0xb4, 0x70, 0xdd, 0x68, 0xdd, 0x67, 0xba, 0x48,
+ 0xbc, 0xa9, 0xbc, 0xac, 0xbc, 0xa5, 0xa1, 0xbc, 0xbe, 0xcf, 0xc3, 0x6a, 0xa9,
+ 0xbd, 0xf1, 0x6f, 0xad, 0xac, 0xd8, 0x45, 0xc1, 0xf2, 0xb6, 0xa3, 0xb6, 0x7b,
+ 0xdc, 0x7a, 0xf6, 0x6b, 0xbe, 0x5b, 0xe8, 0xa7, 0xf9, 0xc4, 0xe8, 0xa6, 0xec,
+ 0x48, 0xec, 0x4b, 0xf1, 0xbe, 0xec, 0x4c, 0xec, 0x4e, 0xec, 0x46, 0xee, 0xf1,
+ 0xc1, 0xf0, 0xc2, 0xf3, 0xc2, 0xf5, 0xc2, 0xf6, 0xf5, 0x45, 0xa1, 0xbc, 0xc9,
+ 0x62, 0xa9, 0xcf, 0xa1, 0xbc, 0xc9, 0xfd, 0xc9, 0xfa, 0xc9, 0xfc, 0xf5, 0xd3,
+ 0xa8, 0x4a, 0xa8, 0x4e, 0xa8, 0x5c, 0xa8, 0x50, 0xa8, 0x51, 0xcb, 0x53, 0xa8,
+ 0x58, 0xa8, 0x5a, 0xa8, 0x59, 0xd9, 0xec, 0xcc, 0xf8, 0xcc, 0xf4, 0xcc, 0xf5,
+ 0xf2, 0x5d, 0xc3, 0x79, 0xaa, 0x74, 0xaa, 0x72, 0xa1, 0xbc, 0xaa, 0x7e, 0xaa,
+ 0x7d, 0xef, 0xf6, 0xcc, 0xf0, 0xcc, 0xf1, 0xaa, 0x62, 0xaa, 0x6c, 0xaa, 0x7b,
+ 0xae, 0xf9, 0xac, 0xa7, 0xac, 0xa8, 0xac, 0x7b, 0xaf, 0x48, 0xd9, 0xfe, 0xcf,
+ 0xa7, 0xcf, 0x77, 0xcf, 0x78, 0xac, 0xad, 0xac, 0xae, 0xe9, 0xf8, 0xac, 0xab,
+ 0xac, 0xac, 0xcf, 0x7a, 0xc2, 0x73, 0xe2, 0x71, 0xbc, 0xf1, 0xcf, 0x76, 0xd2,
+ 0x50, 0xd2, 0x4f, 0xd5, 0xe9, 0xe6, 0x5c, 0xd2, 0x55, 0xae, 0xfe, 0xaf, 0x4b,
+ 0xa1, 0xbc, 0xd2, 0x57, 0xd2, 0x5a, 0xd2, 0x46, 0xb2, 0x5a, 0xb2, 0x4e, 0xb2,
+ 0x58, 0xb2, 0x53, 0xc2, 0x70, 0xb2, 0x67, 0xd5, 0xed, 0xbf, 0x49, 0xb2, 0x68,
+ 0xd5, 0xf3, 0xb2, 0x46, 0xc2, 0x6e, 0xd5, 0xe1, 0xd5, 0xf1, 0xb2, 0x52, 0xd9,
+ 0xf1, 0xb4, 0xf3, 0xb5, 0x42, 0xda, 0x47, 0xde, 0x59, 0xb5, 0x47, 0xe2, 0xa9,
+ 0xda, 0x4b, 0xb4, 0xe6, 0xb4, 0xe8, 0xb4, 0xec, 0xb5, 0x44, 0xf9, 0xd0, 0xde,
+ 0x4c, 0xb7, 0xc2, 0xf5, 0xd4, 0xe2, 0xa5, 0xef, 0xef, 0xb7, 0xc1, 0xb7, 0xcc,
+ 0xde, 0x50, 0xa1, 0xbc, 0xde, 0x54, 0xe6, 0x5f, 0xb7, 0xcd, 0xde, 0x58, 0xde,
+ 0x46, 0xb7, 0xbc, 0xde, 0x48, 0xe6, 0x43, 0xf2, 0x5e, 0xc3, 0x74, 0xa1, 0xbc,
+ 0xba, 0xa8, 0xe2, 0xa3, 0xba, 0xaa, 0xe2, 0xa1, 0xc4, 0x6b, 0xef, 0xf5, 0xba,
+ 0xac, 0xe2, 0x75, 0xba, 0x78, 0xe6, 0x41, 0xe6, 0x40, 0xe6, 0x42, 0xbc, 0xe8,
+ 0xe6, 0x4c, 0xbc, 0xe0, 0xbc, 0xeb, 0xc3, 0x75, 0xea, 0x41, 0xbf, 0x43, 0xbf,
+ 0x46, 0xbf, 0x47, 0xbe, 0xfc, 0xc0, 0xe1, 0xc0, 0xe4, 0xed, 0x57, 0xc0, 0xda,
+ 0xc0, 0xde, 0xc3, 0x76, 0xf2, 0x63, 0xc3, 0x73, 0xf4, 0x65, 0xf4, 0x5c, 0xf8,
+ 0xaf, 0xc5, 0xf4, 0xa1, 0xbc, 0xc9, 0x73, 0xcc, 0x58, 0xcc, 0x57, 0xab, 0xc9,
+ 0xae, 0x66, 0xda, 0xac, 0xc4, 0xca, 0xba, 0x53, 0xb9, 0xed, 0xbc, 0x64, 0xeb,
+ 0x72, 0xbe, 0xc8, 0xee, 0xbf, 0xee, 0xaa, 0xa1, 0xbc, 0xcd, 0xce, 0xcd, 0xd1,
+ 0xad, 0x7e, 0xd0, 0xb5, 0xad, 0xa3, 0xc2, 0xe2, 0xad, 0x7b, 0xb3, 0x77, 0xad,
+ 0xa4, 0xb0, 0x6d, 0xd3, 0xef, 0xd7, 0xe3, 0xc5, 0xdd, 0xd7, 0xe4, 0xb3, 0x70,
+ 0xb3, 0x7c, 0xd7, 0xe7, 0xb6, 0x66, 0xb6, 0x6a, 0xdc, 0x4d, 0xdc, 0x4f, 0xe0,
+ 0xa1, 0xb9, 0x4e, 0xe0, 0x7d, 0xb9, 0x49, 0xbe, 0x43, 0xbb, 0xb8, 0xbb, 0xbd,
+ 0xbb, 0xbf, 0xbe, 0xe6, 0xbf, 0xee, 0xc1, 0xd8, 0xc1, 0xdb, 0xc2, 0xe4, 0xc2,
+ 0xe3, 0xc3, 0xe5, 0xa1, 0xbc, 0xb1, 0x6b, 0xce, 0xbd, 0xd8, 0xf4, 0xc9, 0x75,
+ 0xab, 0xa4, 0xae, 0x6a, 0xd4, 0xf3, 0xb4, 0x47, 0xe1, 0xa2, 0xc0, 0xab, 0xc4,
+ 0xf3, 0xd1, 0x79, 0xa9, 0xb8, 0xab, 0xda, 0xd7, 0x58, 0xb4, 0x5d, 0xf7, 0xa7,
+ 0xc9, 0x4b, 0xa6, 0x71, 0xa6, 0x6d, 0xa7, 0xb0, 0xbc, 0x61, 0xb9, 0xe1, 0xa7,
+ 0xad, 0xca, 0xb5, 0xa9, 0x6e, 0xd8, 0xb5, 0xa7, 0xac, 0xa7, 0xb1, 0xa9, 0x71,
+ 0xcc, 0x48, 0xa9, 0x6f, 0xa9, 0x6b, 0xa9, 0x63, 0xd4, 0xd5, 0xbc, 0x63, 0xce,
+ 0x67, 0xf6, 0xdc, 0xab, 0xbb, 0xab, 0xb9, 0xa1, 0xbc, 0xae, 0x5b, 0xae, 0x5c,
+ 0xb4, 0x45, 0xbc, 0x5f, 0xae, 0x50, 0xae, 0x58, 0xae, 0x55, 0xb0, 0xfe, 0xd4,
+ 0xd1, 0xb1, 0x44, 0xd4, 0xd0, 0xb1, 0x40, 0xb1, 0x41, 0xbc, 0x60, 0xa1, 0xbc,
+ 0xb6, 0xfe, 0xb4, 0x44, 0xb4, 0x40, 0xd8, 0xb8, 0xb6, 0xfc, 0xe1, 0x72, 0xb7,
+ 0x42, 0xe9, 0x54, 0xc0, 0xa7, 0xdc, 0xf7, 0xe1, 0x75, 0xb9, 0xe4, 0xe9, 0x52,
+ 0xb9, 0xe2, 0xb9, 0xdf, 0xb9, 0xe3, 0xe1, 0x6b, 0xbc, 0x5e, 0xe9, 0x51, 0xe9,
+ 0x58, 0xec, 0xd0, 0xc0, 0xa8, 0xc4, 0x5c, 0xc9, 0xd4, 0xa1, 0xbc, 0xa7, 0xb7,
+ 0xcc, 0x56, 0xb4, 0x46, 0xa4, 0x6d, 0xa4, 0x6e, 0xcc, 0x55, 0xe8, 0xca, 0xbe,
+ 0x6f, 0xbe, 0x74, 0xf5, 0x5f, 0xc5, 0xe6, 0xbe, 0x71, 0xe8, 0xce, 0xc5, 0xbb,
+ 0xf7, 0x7e, 0xc0, 0x63, 0xc6, 0x7a, 0xf1, 0xaf, 0xf1, 0xb2, 0xf1, 0xb6, 0xf6,
+ 0x7c, 0xf5, 0x63, 0xc4, 0x45, 0xf6, 0x7d, 0xf5, 0x61, 0xf5, 0x62, 0xc5, 0x59,
+ 0xf6, 0x7b, 0xf7, 0x7c, 0xc6, 0x6b, 0xf9, 0xb3, 0xa1, 0xbc, 0xac, 0xfa, 0xac,
+ 0xf4, 0xac, 0xf8, 0xd0, 0x4b, 0xf5, 0xe7, 0xaf, 0xc6, 0xaf, 0xc4, 0xd3, 0x56,
+ 0xd6, 0xe6, 0xb2, 0xd8, 0xb2, 0xd9, 0xbf, 0xa8, 0xb2, 0xd1, 0xb2, 0xd2, 0xd6,
+ 0xed, 0xa1, 0xbc, 0xda, 0xfb, 0xb5, 0xbc, 0xdf, 0x58, 0xdf, 0x60, 0xdf, 0x57,
+ 0xba, 0xf0, 0xba, 0xf6, 0xe3, 0x6e, 0xa1, 0xbc, 0xe3, 0x6c, 0xbd, 0x78, 0xba,
+ 0xfe, 0xe3, 0x71, 0xe3, 0x65, 0xba, 0xed, 0xba, 0xfd, 0xbd, 0x79, 0xe6, 0xe7,
+ 0xbd, 0x7b, 0xbd, 0x7a, 0xf0, 0x72, 0xe6, 0xeb, 0xe6, 0xec, 0xe6, 0xed, 0xea,
+ 0xd8, 0xe6, 0xe8, 0xbf, 0xa7, 0xbf, 0xa6, 0xea, 0xd0, 0xbf, 0xa5, 0xed, 0xd0,
+ 0xbf, 0x7e, 0xbf, 0xa1, 0xc4, 0x7d, 0xc1, 0x65, 0xc1, 0x67, 0xc1, 0x5d, 0xc1,
+ 0x5b, 0xc1, 0x62, 0xf5, 0xe9, 0xc2, 0xb7, 0xc2, 0xb9, 0xc5, 0xb7, 0xf4, 0xad,
+ 0xf2, 0xb2, 0xf2, 0xb4, 0xf9, 0x40, 0xa1, 0xbc, 0xbd, 0x42, 0xa1, 0xbc, 0xcd,
+ 0x72, 0xb0, 0x6f, 0xca, 0x45, 0xbf, 0x59, 0xde, 0xb3, 0xcd, 0x6a, 0xaa, 0xb3,
+ 0xaa, 0xb2, 0xcf, 0xc8, 0xc4, 0x6e, 0xac, 0xbf, 0xac, 0xc5, 0xac, 0xc4, 0xa1,
+ 0xbc, 0xcf, 0xc9, 0xd2, 0xad, 0xd2, 0xac, 0xb9, 0x7a, 0xb2, 0x78, 0xd2, 0xb2,
+ 0xd2, 0xb0, 0xaf, 0x5f, 0xc3, 0xa2, 0xb7, 0xe9, 0xe6, 0xa3, 0xb5, 0x58, 0xb7,
+ 0xeb, 0xb5, 0x61, 0xb5, 0x5b, 0xb5, 0x62, 0xda, 0x7c, 0xda, 0x7a, 0xda, 0x7b,
+ 0xb5, 0x60, 0xda, 0xa1, 0xb7, 0xe8, 0xb7, 0xec, 0xde, 0xb6, 0xb7, 0xe5, 0xb7,
+ 0xea, 0xc0, 0xf5, 0xba, 0xc1, 0xbd, 0x40, 0xbf, 0x58, 0xc4, 0xed, 0xbd, 0x41,
+ 0xe6, 0xa6, 0xe6, 0xa2, 0xbc, 0xfd, 0xbf, 0x5c, 0xc0, 0xf6, 0xc0, 0xf3, 0xed,
+ 0x69, 0xc2, 0x7a, 0xc5, 0xd0, 0xf4, 0x6f, 0xf1, 0xa4, 0xf3, 0xa5, 0xc3, 0xfc,
+ 0xcb, 0x42, 0xa8, 0x40, 0xa7, 0xfb, 0xcb, 0x43, 0xe2, 0x59, 0xf4, 0x55, 0xaa,
+ 0x4a, 0xaa, 0x57, 0xaa, 0x48, 0xcc, 0xd9, 0xa1, 0xbc, 0xaa, 0x53, 0xd9, 0xb3,
+ 0xbc, 0xd7, 0xb1, 0xfa, 0xaa, 0x44, 0xaa, 0x49, 0xaa, 0x56, 0xcf, 0x55, 0xc0,
+ 0xcd, 0xcf, 0x43, 0xf4, 0x53, 0xac, 0x5e, 0xac, 0x69, 0xf4, 0x56, 0xac, 0x6a,
+ 0xcf, 0x4a, 0xac, 0x63, 0xcf, 0x4c, 0xac, 0x6c, 0xb1, 0xf7, 0xcf, 0x61, 0xac,
+ 0x65, 0xac, 0x6b, 0xf2, 0x52, 0xce, 0xfb, 0xec, 0xf7, 0xd1, 0xdc, 0xd1, 0xdd,
+ 0xd9, 0xb2, 0xbe, 0xf8, 0xd1, 0xe8, 0xb7, 0xa9, 0xd1, 0xe9, 0xe2, 0x4e, 0xb1,
+ 0xf2, 0xd1, 0xeb, 0xa1, 0xbc, 0xbe, 0xec, 0xae, 0xec, 0xc0, 0xcc, 0xae, 0xe5,
+ 0xf7, 0xe1, 0xa1, 0xbc, 0xd1, 0xdb, 0xae, 0xdd, 0xb1, 0xeb, 0xd5, 0xc0, 0xd5,
+ 0xbe, 0xd5, 0xc1, 0xb1, 0xea, 0xd5, 0xc4, 0xf9, 0xbb, 0xb4, 0xd8, 0xd9, 0xc8,
+ 0xc3, 0x70, 0xe5, 0xde, 0xb4, 0xcd, 0xf7, 0xe2, 0xdd, 0xde, 0xd9, 0xca, 0xbc,
+ 0xcd, 0xdd, 0xd4, 0xb4, 0xd0, 0xd9, 0xb9, 0xdd, 0xce, 0xdd, 0xd2, 0xb7, 0xa3,
+ 0xdd, 0xd3, 0xb7, 0xaf, 0xc6, 0x56, 0xb7, 0xaa, 0xa1, 0xbc, 0xa1, 0xbc, 0xdd,
+ 0xdf, 0xdd, 0xe0, 0xba, 0x6c, 0xc4, 0x68, 0xc3, 0x71, 0xe2, 0x41, 0xf5, 0xd1,
+ 0xdd, 0xc9, 0xb7, 0xb0, 0xb7, 0xad, 0xba, 0x64, 0xe2, 0x49, 0xba, 0x66, 0xba,
+ 0x67, 0xba, 0x6b, 0xe2, 0x52, 0xe1, 0xfc, 0xba, 0x60, 0xe2, 0x54, 0xc2, 0x62,
+ 0xba, 0x5f, 0xf2, 0x4c, 0xe2, 0x4a, 0xe5, 0xd3, 0xc0, 0xce, 0xbc, 0xd8, 0xe5,
+ 0xcc, 0xe5, 0xe8, 0xf2, 0x55, 0xe5, 0xda, 0xbe, 0xf1, 0xe9, 0xc4, 0xc0, 0xd2,
+ 0xe9, 0xd1, 0xe9, 0xc8, 0xbe, 0xf6, 0xec, 0xfe, 0xc3, 0x72, 0xbe, 0xea, 0xe9,
+ 0xca, 0xbe, 0xef, 0xf2, 0x58, 0xed, 0x44, 0xc0, 0xd1, 0xec, 0xf5, 0xc0, 0xd0,
+ 0xa1, 0xbc, 0xb7, 0xdf, 0xe6, 0x76, 0xaa, 0x5c, 0xcf, 0x65, 0xbc, 0xdc, 0xcf,
+ 0x66, 0xe2, 0x66, 0xc0, 0xd4, 0xd5, 0xdc, 0xe9, 0xe3, 0xdd, 0xfb, 0xc2, 0x6c,
+ 0xe9, 0xe2, 0xb0, 0x62, 0xb3, 0x6d, 0xa1, 0xbc, 0xb6, 0x61, 0xf8, 0x47, 0xdc,
+ 0x40, 0xb6, 0x63, 0xdc, 0x48, 0xa1, 0xbc, 0xf7, 0x65, 0xdb, 0xfe, 0xb8, 0xfd,
+ 0xb8, 0xfe, 0xe0, 0x79, 0xe0, 0x78, 0xbb, 0xb3, 0xbd, 0xfb, 0xbd, 0xfe, 0xbd,
+ 0xf9, 0xbd, 0xfd, 0xbf, 0xea, 0xf1, 0x46, 0xc3, 0xe1, 0xa1, 0xbc, 0xcc, 0xb1,
+ 0xe1, 0xd7, 0xb1, 0xae, 0xb4, 0x75, 0xb7, 0x61, 0xb7, 0x60, 0xdd, 0x75, 0xdd,
+ 0x76, 0xe1, 0xd6, 0xbb, 0x4e, 0xbf, 0x5e, 0xd2, 0xbe, 0xde, 0xc0, 0xed, 0x72,
+ 0xed, 0x70, 0xf0, 0x49, 0xa1, 0xbc, 0xc9, 0xee, 0xc9, 0xed, 0xca, 0xf8, 0xa9,
+ 0xfe, 0xbe, 0xe8, 0xaa, 0x58, 0xcc, 0xca, 0xa9, 0xfd, 0xa9, 0xfb, 0xcd, 0x52,
+ 0xac, 0x54, 0xce, 0xf5, 0xce, 0xf6, 0xac, 0x52, 0xce, 0xeb, 0xbc, 0xca, 0xaf,
+ 0xcf, 0xd1, 0xd4, 0xbe, 0xe7, 0xae, 0xd0, 0xae, 0xcb, 0xb7, 0x75, 0xd5, 0xaa,
+ 0xa1, 0xbc, 0xb4, 0xbe, 0xb7, 0x79, 0xdd, 0xc0, 0xc0, 0xc7, 0xba, 0x5c, 0xe9,
+ 0xb4, 0xef, 0xdb, 0xc2, 0x60, 0xc4, 0x66, 0xc4, 0xe4, 0xb6, 0x4e, 0xdb, 0xea,
+ 0xdb, 0xe8, 0xb6, 0x4d, 0xf0, 0xf4, 0xb8, 0xed, 0xb8, 0xf0, 0xf6, 0x52, 0xbb,
+ 0xac, 0xe7, 0xec, 0xe4, 0x53, 0xa1, 0xbc, 0xe7, 0xee, 0xc1, 0xcc, 0xdb, 0xd1,
+ 0xc1, 0xbb, 0xe4, 0x44, 0xf7, 0x53, 0xbf, 0xcc, 0xee, 0x7a, 0xc2, 0xd1, 0xf2,
+ 0xf3, 0xcf, 0xbd, 0xa1, 0xbc, 0xa6, 0xc9, 0xa1, 0xbc, 0xac, 0xba, 0xd6, 0x5c,
+ 0xd6, 0x5f, 0xb5, 0x51, 0xda, 0x6c, 0xde, 0xa5, 0xa1, 0xbc, 0xba, 0xb9, 0xae,
+ 0xb2, 0xd5, 0x66, 0xd9, 0x54, 0xe1, 0xee, 0xc0, 0xbc, 0xac, 0xfe, 0xa1, 0xbc,
+ 0xd9, 0xe5, 0xb7, 0xb7, 0xe5, 0xf7, 0xde, 0x40, 0xbe, 0xfb, 0xf2, 0x5b, 0xe9,
+ 0xe8, 0xf6, 0xe7, 0xc9, 0x7e, 0xc9, 0xf7, 0xcb, 0x49, 0xcb, 0x4a, 0xcf, 0x6c,
+ 0xb4, 0xe3, 0xae, 0xf4, 0xd5, 0xdf, 0xba, 0x72, 0xa1, 0xbc, 0xb1, 0xd5, 0xa1,
+ 0xbc, 0xc3, 0x7c, 0xb7, 0xde, 0xbc, 0xf8, 0xac, 0xb8, 0xe7, 0x7e, 0xa6, 0x47,
+ 0xa1, 0xbc, 0xcb, 0x78, 0xa8, 0x77, 0xa1, 0xbc, 0xcc, 0xd2, 0xa1, 0xbc, 0xaa,
+ 0xd0, 0xaa, 0xd2, 0xcd, 0xb0, 0xaa, 0xd4, 0xa1, 0xbc, 0xc4, 0x67, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xc4, 0xa4, 0xad, 0x4b, 0xd0, 0x5b, 0xad, 0x48, 0xd0, 0x5f, 0xd0,
+ 0x67, 0xd0, 0x65, 0xce, 0xfa, 0xad, 0x4f, 0xd7, 0x48, 0xaf, 0xd6, 0xaf, 0xdb,
+ 0xaf, 0xda, 0xc1, 0x7a, 0xa1, 0xbc, 0xd3, 0x6a, 0xaf, 0xe2, 0xae, 0xd3, 0xa1,
+ 0xbc, 0xb3, 0x62, 0xdf, 0xa2, 0xd7, 0x4c, 0xd7, 0x4b, 0xd7, 0x45, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xb5, 0xcb, 0xb5, 0xcc, 0xb5, 0xcd, 0xa1, 0xbc, 0xa1, 0xbc, 0xb8,
+ 0x78, 0xdf, 0x73, 0xdf, 0x76, 0xa1, 0xbc, 0xe3, 0xa6, 0xa1, 0xbc, 0xdf, 0x7d,
+ 0xdc, 0xe6, 0xdc, 0xf9, 0xbb, 0x4a, 0xbb, 0x4d, 0xc2, 0xc1, 0xbc, 0xf0, 0xe6,
+ 0xfd, 0xa1, 0xbc, 0xed, 0xea, 0xc2, 0x61, 0xed, 0xeb, 0xed, 0xe8, 0xa1, 0xbc,
+ 0xea, 0xe9, 0xc2, 0x6a, 0xd5, 0xd8, 0xd9, 0xda, 0xdd, 0xf7, 0xdd, 0xf5, 0xbe,
+ 0xf9, 0xe4, 0xcd, 0xbb, 0xe3, 0xc1, 0xfc, 0xc4, 0x42, 0xf6, 0x74, 0xa1, 0xbc,
+ 0xc9, 0x5f, 0xdd, 0x62, 0xc1, 0xd4, 0xee, 0x7d, 0xb4, 0xb4, 0xf8, 0x7e, 0xc4,
+ 0xe3, 0xa9, 0xf3, 0xd1, 0xcf, 0xd1, 0xd1, 0xd1, 0xd0, 0xb1, 0xdc, 0xb1, 0xdd,
+ 0xd9, 0x7e, 0xba, 0x59, 0xb7, 0xd5, 0xde, 0x6d, 0xbf, 0x4c, 0xe2, 0xc4, 0xa1,
+ 0xbc, 0xa1, 0xbc, 0xcf, 0xae, 0xac, 0xaf, 0xcf, 0xb1, 0xea, 0x4d, 0xaf, 0x4c,
+ 0xd6, 0x51, 0xd6, 0x55, 0xbf, 0x54, 0xda, 0x5a, 0xda, 0x5d, 0xa1, 0xbc, 0xb7,
+ 0xd4, 0xb7, 0xdb, 0xa1, 0xbc, 0xde, 0x73, 0xa1, 0xbc, 0xde, 0x74, 0xa1, 0xbc,
+ 0xa1, 0xbc, 0xe6, 0x72, 0xe6, 0x69, 0xbc, 0xf7, 0xe6, 0x66, 0xc0, 0xee, 0xea,
+ 0x4f, 0xc0, 0xe6, 0xef, 0xfb, 0xf5, 0xda, 0xc6, 0x79, 0xa1, 0xbc, 0xc2, 0x76,
+ 0xb7, 0xd6, 0xbf, 0x51, 0xa9, 0xd1, 0xcc, 0xb2, 0xce, 0xd3, 0xb1, 0xaf, 0xb4,
+ 0x76, 0xa1, 0xbc, 0xaa, 0xc1, 0xac, 0xe6, 0xac, 0xe7, 0xd7, 0xb6, 0xd2, 0xe9,
+ 0xd2, 0xea, 0xaf, 0xae, 0xf2, 0xa5, 0xaf, 0xad, 0xaf, 0xa8, 0xba, 0xd5, 0xd6,
+ 0xbd, 0xb8, 0x52, 0xc1, 0x49, 0xe2, 0xf9, 0xe6, 0xcb, 0xc1, 0x48, 0xc5, 0xa1,
+ 0xca, 0xd7, 0xca, 0xd8, 0xef, 0xc8, 0xd1, 0x7c, 0xd1, 0x7d, 0xd1, 0x7e, 0xd1,
+ 0xa1, 0xae, 0x7e, 0xae, 0xa1, 0xe1, 0xc3, 0xb7, 0x5e, 0xb7, 0x5d, 0xbc, 0x7c,
+ 0xbe, 0xcd, 0xe9, 0x76, 0xc0, 0xb7, 0xc2, 0x56, 0xf9, 0xba, 0xa1, 0xbc, 0xa6,
+ 0xd6, 0xcc, 0xee, 0xed, 0x4f, 0xd9, 0xe7, 0xc1, 0x46, 0xcd, 0x7a, 0xe2, 0xee,
+ 0xcf, 0xf1, 0xda, 0xcf, 0xa1, 0xbc, 0xcf, 0xeb, 0xac, 0x48, 0xaf, 0xa2, 0xa1,
+ 0xbc, 0xaf, 0x7c, 0xa1, 0xbc, 0xc4, 0x72, 0xf5, 0xe2, 0xaf, 0xa4, 0xa1, 0xbc,
+ 0xaf, 0xa1, 0xd2, 0xda, 0xd2, 0xd9, 0xd2, 0xe2, 0xb2, 0xba, 0xda, 0xc9, 0xda,
+ 0xc6, 0xed, 0xa6, 0xd6, 0xb9, 0xd6, 0xbb, 0xa1, 0xbc, 0xd6, 0xb8, 0xda, 0xcb,
+ 0xbf, 0x6c, 0xb8, 0x50, 0xde, 0xe5, 0xde, 0xe4, 0xea, 0xa7, 0xde, 0xec, 0xba,
+ 0xd4, 0xe2, 0xeb, 0xa1, 0xbc, 0xe2, 0xf3, 0xe6, 0xc6, 0xa1, 0xbc, 0xe6, 0xca,
+ 0xbf, 0x6b, 0xed, 0xaa, 0xed, 0xab, 0xc1, 0x45, 0xf0, 0x58, 0xf4, 0x7d, 0xf2,
+ 0xa4, 0xf2, 0xa1, 0xf7, 0xce, 0xdc, 0xb0, 0xef, 0xb0, 0xf3, 0xf5, 0xcd, 0x77,
+ 0xcf, 0xe2, 0xa1, 0xbc, 0xac, 0xda, 0xac, 0xe0, 0xcf, 0xe0, 0xd2, 0xd6, 0xd2,
+ 0xd7, 0xd2, 0xd5, 0xd6, 0xaa, 0xd6, 0xb0, 0xd6, 0xb2, 0xb2, 0xb6, 0xb7, 0xfd,
+ 0xc2, 0xa5, 0xda, 0xbb, 0xa1, 0xbc, 0xde, 0xdd, 0xb8, 0x45, 0xb8, 0x46, 0xb8,
+ 0x44, 0xba, 0xcd, 0xe6, 0xbc, 0xba, 0xcc, 0xe2, 0xe7, 0xbd, 0x4f, 0xbd, 0x50,
+ 0xbf, 0x67, 0xbf, 0x65, 0xc0, 0xfd, 0xed, 0x7a, 0xc2, 0xa2, 0xcb, 0x6d, 0xcd,
+ 0x71, 0xac, 0xca, 0xac, 0xcb, 0xcf, 0xdb, 0xd2, 0xc1, 0xda, 0xae, 0xde, 0xc4,
+ 0xa1, 0xbc, 0xd0, 0x4d, 0xd3, 0x5c, 0xaf, 0xcb, 0xdb, 0xe0, 0xdf, 0x6a, 0xf2,
+ 0xbc, 0xa1, 0xbc, 0xbf, 0xa9, 0xc5, 0xf9, 0xed, 0xe3, 0xaf, 0x72, 0xbf, 0x64,
+ 0xf7, 0xf8, 0xa1, 0xbc, 0xd0, 0xc1, 0xd0, 0xc0, 0xb0, 0x7a, 0xb0, 0x78, 0xd4,
+ 0x42, 0xd8, 0x41, 0xb3, 0xa9, 0xd7, 0xfc, 0xeb, 0xea, 0xb3, 0xa6, 0xd7, 0xfd,
+ 0xa1, 0xbc, 0xdc, 0x67, 0xb9, 0x64, 0xb6, 0x7a, 0xb6, 0x78, 0xdc, 0x62, 0xdc,
+ 0x70, 0xdc, 0x6f, 0xdc, 0x64, 0xdc, 0x6a, 0xe0, 0xb1, 0xe0, 0xb2, 0xb9, 0x57,
+ 0xe0, 0xb3, 0xa1, 0xbc, 0xb9, 0x5a, 0xb9, 0x59, 0xe0, 0xb5, 0xe0, 0xbb, 0xe0,
+ 0xba, 0xb9, 0x66, 0xc5, 0xe0, 0xe0, 0xb0, 0xb9, 0x62, 0xe0, 0xae, 0xb9, 0x63,
+ 0xe0, 0xb7, 0xb9, 0x65, 0xc5, 0x4d, 0xbe, 0x52, 0xe4, 0x7b, 0xe4, 0x7a, 0xe4,
+ 0x7d, 0xe4, 0xa8, 0xe8, 0x68, 0xc4, 0xc2, 0xa1, 0xbc, 0xc5, 0x4c, 0xa1, 0xbc,
+ 0xe4, 0xa1, 0xf1, 0x5a, 0xbb, 0xcb, 0xe8, 0x6f, 0xe4, 0xb7, 0xf4, 0xf3, 0xbb,
+ 0xcd, 0xe4, 0xa6, 0xf3, 0x6a, 0xe4, 0xa2, 0xbf, 0xfe, 0xe4, 0xa3, 0xe0, 0xb6,
+ 0xf4, 0xe7, 0xbb, 0xcf, 0xe4, 0xa7, 0xf4, 0xf9, 0xeb, 0xe4, 0xe8, 0x69, 0xc3,
+ 0xf4, 0xa1, 0xbc, 0xbe, 0x59, 0xe8, 0x70, 0xe8, 0x72, 0xbe, 0x56, 0xe8, 0x6e,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xe8, 0x63, 0xe8, 0x6a, 0xe8, 0x76, 0xeb,
+ 0xe8, 0xeb, 0xe1, 0xa1, 0xbc, 0xeb, 0xe6, 0xa1, 0xbc, 0xeb, 0xe9, 0xc0, 0x43,
+ 0xc0, 0x44, 0xa1, 0xbc, 0xa1, 0xbc, 0xeb, 0xdf, 0xeb, 0xe0, 0xc0, 0x45, 0xc1,
+ 0xe6, 0xee, 0xd2, 0xee, 0xd6, 0xc1, 0xee, 0xee, 0xd0, 0xf1, 0x5c, 0xc1, 0xec,
+ 0xa1, 0xbc, 0xc3, 0xf3, 0xc3, 0xf2, 0xf4, 0xf0, 0xa1, 0xbc, 0xf3, 0x68, 0xc2,
+ 0xf0, 0xc5, 0x4f, 0xa1, 0xbc, 0xf1, 0x5e, 0xc2, 0xef, 0xf1, 0x53, 0xf7, 0x67,
+ 0xc3, 0xf0, 0xc3, 0xed, 0xc3, 0xee, 0xc3, 0xf1, 0xf3, 0x60, 0xc3, 0xeb, 0xf3,
+ 0x61, 0xc3, 0xe9, 0xf4, 0xec, 0xa1, 0xbc, 0xf4, 0xf5, 0xa1, 0xbc, 0xf4, 0xe8,
+ 0xf9, 0x53, 0xf4, 0xea, 0xa1, 0xbc, 0xf3, 0x66, 0xf4, 0xf1, 0xf7, 0x69, 0xc5,
+ 0x4e, 0xf6, 0x5e, 0xa1, 0xbc, 0xc5, 0xdf, 0xc1, 0xe9, 0xcf, 0xe8, 0xda, 0xc4,
+ 0xb9, 0x6e, 0xcf, 0xf9, 0xd2, 0xf1, 0xaf, 0xb0, 0xd2, 0xed, 0xa1, 0xbc, 0xb4,
+ 0x52, 0xda, 0xd8, 0xda, 0xd6, 0xb8, 0x5c, 0xb8, 0x5a, 0xe6, 0xd2, 0xbd, 0x5e,
+ 0xc2, 0xa8, 0xc2, 0x48, 0xc3, 0x4c, 0xf6, 0xf8, 0xac, 0xd4, 0xb2, 0xae, 0xb5,
+ 0x71, 0xde, 0xd5, 0xed, 0x78, 0xd2, 0xbc, 0xb2, 0x7d, 0xa8, 0x69, 0xb9, 0xa7,
+ 0xbb, 0xf0, 0xe8, 0xe9, 0xbe, 0x7d, 0xc0, 0x6c, 0xf3, 0xf0, 0xf9, 0xb7, 0xec,
+ 0xa9, 0xec, 0xae, 0xc5, 0xee, 0xef, 0x7b, 0xf7, 0xc1, 0xef, 0x7e, 0xef, 0xa2,
+ 0xc6, 0x7d, 0xf1, 0xd0, 0xf9, 0xcf, 0xc3, 0x5b, 0xf1, 0xd9, 0xf8, 0x71, 0xf1,
+ 0xcf, 0xc4, 0x4d, 0xa1, 0xbc, 0xc4, 0x4f, 0xf3, 0xed, 0xc4, 0x4c, 0xf5, 0x7c,
+ 0xf5, 0xa7, 0xa1, 0xbc, 0xa1, 0xbc, 0xf5, 0xad, 0xc5, 0x63, 0xf6, 0xb4, 0xc6,
+ 0x78, 0xc5, 0xc2, 0xf7, 0xba, 0xf8, 0x63, 0xf8, 0x6b, 0xf8, 0x6c, 0xf8, 0x66,
+ 0xa1, 0xbc, 0xc6, 0x4f, 0xc6, 0x7c, 0xa1, 0xbc, 0xcb, 0x6f, 0xf0, 0x4b, 0xc2,
+ 0x7e, 0xaa, 0xb7, 0xa1, 0xbc, 0xac, 0xd0, 0xaf, 0x69, 0xde, 0xcb, 0xaf, 0x6e,
+ 0xd2, 0xc6, 0xaf, 0x70, 0xd2, 0xc3, 0xa1, 0xbc, 0xaf, 0x6d, 0xa1, 0xbc, 0xb2,
+ 0xad, 0xb5, 0x69, 0xc0, 0xf7, 0xda, 0xb2, 0xda, 0xb5, 0xed, 0x77, 0xda, 0xaf,
+ 0xde, 0xc9, 0xb7, 0xf3, 0xde, 0xcc, 0xb7, 0xf5, 0xde, 0xcf, 0xb7, 0xef, 0xed,
+ 0x76, 0xe2, 0xdc, 0xe6, 0xb0, 0xe2, 0xdf, 0xe6, 0xaf, 0xa1, 0xbc, 0xe2, 0xdd,
+ 0xe6, 0xb1, 0xe6, 0xb7, 0xea, 0x70, 0xbd, 0x49, 0xbd, 0x43, 0xa1, 0xbc, 0xea,
+ 0x6c, 0xea, 0x73, 0xf6, 0xf4, 0xea, 0x71, 0xed, 0x74, 0xc5, 0x7d, 0xea, 0x6f,
+ 0xa1, 0xbc, 0xc4, 0xee, 0xa1, 0xbc, 0xf0, 0x4a, 0xc2, 0x7d, 0xc5, 0xf6, 0xa1,
+ 0xbc, 0xd6, 0xf6, 0xda, 0xdc, 0xcd, 0xa5, 0xaa, 0xc6, 0xcf, 0xfe, 0xd2, 0xf6,
+ 0xaf, 0xb7, 0xb2, 0xc0, 0xc4, 0x75, 0xb8, 0x5e, 0xe3, 0x4c, 0xe3, 0x4a, 0xea,
+ 0xb2, 0xe6, 0xd5, 0xa1, 0xbc, 0xd0, 0xae, 0xd3, 0xd4, 0xb0, 0x4d, 0xd3, 0xd7,
+ 0xb0, 0x4c, 0xd7, 0xb5, 0xc3, 0xcb, 0xdb, 0xcb, 0xdb, 0xca, 0xdb, 0xcf, 0xee,
+ 0x72, 0xdf, 0xf4, 0xf2, 0xf0, 0xf0, 0xd9, 0xe3, 0xf7, 0xbb, 0x75, 0xe3, 0xfc,
+ 0xbb, 0x74, 0xe3, 0xfa, 0xe4, 0x40, 0xbf, 0xca, 0xe7, 0xc8, 0xbd, 0xc8, 0xc1,
+ 0xb9, 0xbd, 0xca, 0xc4, 0xb0, 0xbf, 0xc9, 0xc1, 0xb7, 0xee, 0x75, 0xf4, 0xcb,
+ 0xf9, 0x4b, 0xa5, 0xd4, 0xad, 0x45, 0xe2, 0xe1, 0xb5, 0x72, 0xac, 0xe1, 0xa6,
+ 0xd4, 0xd0, 0x54, 0xd3, 0x66, 0xb2, 0xe0, 0xa1, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc,
+ 0xbd, 0xa2, 0xed, 0xe7, 0xea, 0xe6, 0xbf, 0xae, 0xa1, 0xbc, 0xb5, 0xc0, 0xcd,
+ 0xaa, 0xd7, 0x43, 0xb2, 0xe2, 0xf4, 0xb2, 0xb5, 0xc1, 0xf0, 0x7c, 0xc1, 0x6d,
+ 0xb5, 0xf7, 0xdc, 0xac, 0xe0, 0xe0, 0xe0, 0xde, 0xbe, 0x65, 0xbe, 0x67, 0xbf,
+ 0x6f, 0xe8, 0xb8, 0xc0, 0x58, 0xc3, 0x45, 0xc3, 0x46, 0xf9, 0xae, 0xf5, 0x4f,
+ 0xf3, 0xa8, 0xc5, 0x56, 0xa1, 0xbc, 0xc6, 0x49, 0xca, 0x4f, 0xb0, 0x40, 0xcd,
+ 0xc8, 0xf0, 0xca, 0xf2, 0xe3, 0xad, 0x6b, 0xd0, 0xa8, 0xad, 0x6a, 0xd3, 0xba,
+ 0xd3, 0xbc, 0xd3, 0xc2, 0xb8, 0xc3, 0xc4, 0xae, 0xd3, 0xc8, 0xb0, 0x47, 0xb0,
+ 0x42, 0xb0, 0x43, 0xb0, 0x45, 0xb3, 0x46, 0xb3, 0x47, 0xb3, 0x48, 0xc4, 0xf7,
+ 0xd7, 0xa5, 0xd7, 0xa4, 0xb3, 0x4b, 0xb3, 0x4c, 0xb3, 0x4d, 0xf2, 0xde, 0xd7,
+ 0xab, 0xdb, 0xbc, 0xdf, 0xe6, 0xc2, 0xcc, 0xb5, 0xed, 0xeb, 0x6b, 0xb5, 0xf1,
+ 0xb8, 0xbb, 0xb5, 0xf2, 0xf4, 0xc5, 0xb5, 0xeb, 0xdb, 0xb1, 0xdb, 0xbf, 0xb8,
+ 0xc2, 0xb8, 0xbd, 0xdf, 0xea, 0xb8, 0xbc, 0xb8, 0xc4, 0xdf, 0xef, 0xdf, 0xec,
+ 0xe3, 0xd6, 0xbb, 0x66, 0xe3, 0xdb, 0xbb, 0x68, 0xe3, 0xda, 0xe3, 0xf2, 0xe3,
+ 0xe2, 0xc1, 0xb4, 0xbb, 0x69, 0xe3, 0xeb, 0xbb, 0x6d, 0xbb, 0x6c, 0xbb, 0x64,
+ 0xbd, 0xb8, 0xbb, 0x67, 0xa1, 0xbc, 0xf4, 0xc6, 0xe7, 0xbc, 0xbd, 0xbb, 0xa1,
+ 0xbc, 0xbd, 0xc1, 0xe7, 0xb8, 0xa1, 0xbc, 0xbd, 0xc2, 0xe7, 0xa2, 0xc1, 0xb2,
+ 0xe7, 0xa3, 0xbd, 0xbf, 0xe7, 0xba, 0xeb, 0x5e, 0xee, 0x67, 0xa1, 0xbc, 0xc1,
+ 0xaf, 0xc1, 0xb0, 0xeb, 0x60, 0xeb, 0x67, 0xee, 0x5a, 0xeb, 0x5d, 0xbf, 0xc0,
+ 0xc1, 0xb1, 0xf0, 0xc1, 0xee, 0x5d, 0xee, 0x5f, 0xc1, 0xae, 0xc1, 0xb5, 0xf0,
+ 0xc7, 0xee, 0x6e, 0xc1, 0xad, 0xc1, 0xac, 0xee, 0x69, 0xf0, 0xbe, 0xf0, 0xc0,
+ 0xc2, 0xcf, 0xa1, 0xbc, 0xf4, 0xc9, 0xf4, 0xc8, 0xc3, 0xca, 0xf2, 0xe7, 0xf6,
+ 0x42, 0xc4, 0xf9, 0xc5, 0xfb, 0xf9, 0x6e, 0xa6, 0xce, 0xc4, 0xa2, 0xc1, 0x6a,
+ 0xed, 0xe1, 0xaf, 0xe7, 0xaa, 0xc7, 0xac, 0xf2, 0xd3, 0x44, 0xbf, 0x77, 0xd3,
+ 0x40, 0xb8, 0x63, 0xd3, 0x45, 0xd6, 0xd7, 0xd3, 0x43, 0xd6, 0xcc, 0xd6, 0xdb,
+ 0xd6, 0xd4, 0xb2, 0xc6, 0xb2, 0xc8, 0xd6, 0xd6, 0xb2, 0xc1, 0xd6, 0xce, 0xd6,
+ 0xd1, 0xd6, 0xd2, 0xf8, 0xfb, 0xb2, 0xc7, 0xda, 0xe5, 0xed, 0xc3, 0xda, 0xe6,
+ 0xba, 0xe1, 0xda, 0xe2, 0xba, 0xe5, 0xb8, 0x61, 0xb8, 0x62, 0xa1, 0xbc, 0xa1,
+ 0xbc, 0xdf, 0x4b, 0xdf, 0x4e, 0xe3, 0x52, 0xed, 0xbd, 0xe6, 0xd7, 0xba, 0xe6,
+ 0xe6, 0xd9, 0xba, 0xe3, 0xf6, 0xfb, 0xe3, 0x58, 0xc2, 0xb0, 0xe3, 0x4f, 0xa1,
+ 0xbc, 0xc2, 0xad, 0xbd, 0x65, 0xc2, 0xb1, 0xbd, 0x68, 0xbd, 0x6a, 0xea, 0xba,
+ 0xea, 0xbd, 0xea, 0xbc, 0xbf, 0x7b, 0xea, 0xc1, 0xc1, 0x50, 0xc1, 0x4e, 0xa1,
+ 0xbc, 0xed, 0xbb, 0xf8, 0xb8, 0xed, 0xc2, 0xf0, 0x65, 0xc2, 0xaf, 0xf0, 0x68,
+ 0xc3, 0xb0, 0xc5, 0xa3, 0xc3, 0xb3, 0xaa, 0xd8, 0xd3, 0x70, 0xb2, 0xea, 0xbc,
+ 0xf3, 0xaf, 0xe5, 0xd3, 0xd0, 0xd0, 0x69, 0xad, 0x51, 0xf2, 0xc3, 0xa1, 0xbc,
+ 0xd3, 0x71, 0xaf, 0xea, 0xaf, 0xe9, 0xd7, 0x53, 0xf7, 0x46, 0xd7, 0x54, 0xd7,
+ 0x56, 0xa1, 0xbc, 0xdf, 0xa5, 0xdf, 0xa4, 0xbb, 0x53, 0xe7, 0x46, 0xed, 0xf1,
+ 0xf0, 0xa2, 0xf4, 0xb6, 0xd3, 0xda, 0xb8, 0xcd, 0xb3, 0x50, 0xb8, 0xca, 0xb8,
+ 0xc6, 0xc3, 0xce, 0xd6, 0xf4, 0xdf, 0x6d, 0xdf, 0x6e, 0xbd, 0x7e, 0xe6, 0xf3,
+ 0xbf, 0xaa, 0xaa, 0xc4, 0xae, 0xc5, 0xd3, 0x4a, 0xf5, 0xe6, 0xf8, 0xfd, 0xda,
+ 0xe8, 0xda, 0xe7, 0xdf, 0x54, 0xe3, 0x60, 0xba, 0xea, 0xc1, 0x58, 0xa1, 0xbc,
+ 0xe6, 0xe1, 0xa1, 0xbc, 0xe6, 0xe0, 0xe6, 0xdf, 0xea, 0xc9, 0xed, 0xcf, 0xa6,
+ 0xe1, 0xba, 0x5b, 0xac, 0xfd, 0xb2, 0xde, 0xb5, 0xbf, 0xe3, 0x7d, 0xbb, 0x42,
+ 0xe6, 0xf9, 0xbd, 0xa1, 0xbf, 0xad, 0xc1, 0x6b, 0xa6, 0xcd, 0xed, 0xde, 0xe3,
+ 0x75, 0xe3, 0x76, 0xed, 0xd9, 0xf9, 0x41, 0xbe, 0xa2, 0xc4, 0x54, 0xad, 0x76,
+ 0xdb, 0xed, 0xe0, 0x64, 0xe0, 0x5e, 0xf9, 0x6f, 0xb3, 0x69, 0xbd, 0xea, 0xd3,
+ 0xde, 0xb3, 0x61, 0xad, 0xaa, 0xd3, 0xfe, 0xd4, 0x40, 0xd4, 0x41, 0xdc, 0x5e,
+ 0xdc, 0x60, 0xdc, 0x5d, 0xa1, 0xbc, 0xb9, 0x55, 0xe0, 0xad, 0xc6, 0x6f, 0xf9,
+ 0x71, 0xe4, 0x73, 0xbb, 0xc6, 0xe4, 0x74, 0xa1, 0xbc, 0xe8, 0x5b, 0xeb, 0xd9,
+ 0xeb, 0xdb, 0xeb, 0xda, 0xee, 0xc6, 0xc1, 0xde, 0xf1, 0x52, 0xf3, 0x5f, 0xc3,
+ 0xe7, 0xf1, 0x51, 0xf4, 0xe4, 0xc4, 0xbf, 0xc5, 0x48, 0xa8, 0xa8, 0xf6, 0xc9,
+ 0xc4, 0xbb, 0xe0, 0x72, 0xe4, 0x60, 0xc2, 0xd9, 0xf1, 0x44, 0xd3, 0xe5, 0xd7,
+ 0xd9, 0xd7, 0xd6, 0xb3, 0x6c, 0xee, 0xbe, 0xdb, 0xf4, 0xdb, 0xfa, 0xb6, 0x5c,
+ 0xf7, 0x60, 0xb6, 0x59, 0xdb, 0xf6, 0xb6, 0x5f, 0xb6, 0x60, 0xe0, 0x69, 0xc3,
+ 0xdf, 0xc2, 0xde, 0xe0, 0x6e, 0xf7, 0x5f, 0xc5, 0x45, 0xb8, 0xf8, 0xe4, 0x57,
+ 0xe4, 0x5b, 0xe8, 0x40, 0xbd, 0xef, 0xbd, 0xf3, 0xc5, 0xae, 0xe7, 0xf7, 0xe7,
+ 0xf4, 0xc5, 0xad, 0xa1, 0xbc, 0xeb, 0xc0, 0xbf, 0xe5, 0xbf, 0xe6, 0xeb, 0xc4,
+ 0xbf, 0xe2, 0xc1, 0xce, 0xeb, 0xc5, 0xbf, 0xe4, 0xc6, 0x5c, 0xc2, 0xda, 0xc1,
+ 0xd1, 0xf7, 0x5d, 0xc3, 0xdd, 0xc3, 0xda, 0xf3, 0x53, 0xc3, 0xe0, 0xc4, 0xbd,
+ 0xc6, 0x6e, 0xf7, 0x5e, 0xf7, 0x61, 0xf9, 0x70, 0xf8, 0xc3, 0xcb, 0xa4, 0xb6,
+ 0x49, 0xb8, 0xe7, 0xe0, 0x5a, 0xf0, 0xf1, 0xee, 0xb7, 0xb1, 0xd8, 0xd7, 0xc6,
+ 0xc2, 0xd2, 0xdb, 0xd4, 0xe0, 0x43, 0xdf, 0xfd, 0xe4, 0x48, 0xf2, 0xf5, 0xb8,
+ 0xe4, 0xf0, 0xe7, 0xe8, 0xb0, 0xb3, 0xb8, 0xc6, 0x45, 0xb6, 0xb2, 0xbe, 0x5e,
+ 0xc5, 0xb4, 0xe8, 0xae, 0xc0, 0x50, 0xc0, 0x4b, 0xc3, 0xf9, 0xc6, 0x47, 0xc4,
+ 0xc5, 0xc5, 0xb5, 0xef, 0xb5, 0xc4, 0xd4, 0xf5, 0xbe, 0xf5, 0xbb, 0xc5, 0x68,
+ 0xc5, 0x69, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0x53, 0xe0, 0xef, 0xef, 0xb1, 0xf9,
+ 0x65, 0xab, 0x41, 0xd4, 0x47, 0xb9, 0x6d, 0xe0, 0xd5, 0xbb, 0xdc, 0xc2, 0xa3,
+ 0xf8, 0x41, 0xe4, 0xa9, 0xc6, 0x71, 0xe8, 0x74, 0xc3, 0xf5, 0xee, 0xde, 0xf3,
+ 0x6c, 0xee, 0xdc, 0xa1, 0xbc, 0xf8, 0xca, 0xbe, 0x7b, 0xe8, 0xdb, 0xf8, 0x5b,
+ 0xa1, 0xbc, 0xa1, 0xbc, 0xc6, 0x74, 0xbf, 0x71, 0xec, 0x7b, 0xc6, 0x4d, 0xec,
+ 0x7c, 0xc2, 0x44, 0xef, 0x6a, 0xc2, 0x43, 0xef, 0x6c, 0xf9, 0x5c, 0xc2, 0x42,
+ 0xf3, 0xd0, 0xf8, 0x58, 0xf1, 0xc7, 0xf9, 0xce, 0xc5, 0xbf, 0xf7, 0xae, 0xf6,
+ 0xad, 0xf7, 0xb2, 0xc3, 0x58, 0xc3, 0x54, 0xf1, 0xc3, 0xc3, 0x56, 0xc4, 0x4a,
+ 0xf3, 0xc7, 0xf3, 0xc8, 0xf3, 0xd6, 0xf3, 0xcb, 0xc4, 0x49, 0xa1, 0xbc, 0xf3,
+ 0xcd, 0xf3, 0xce, 0xc4, 0x4b, 0xa1, 0xbc, 0xf3, 0xcf, 0xa1, 0xbc, 0xf5, 0x6b,
+ 0xc6, 0x73, 0xc4, 0xcf, 0xf5, 0x6e, 0xf5, 0x76, 0xa1, 0xbc, 0xa1, 0xbc, 0xf7,
+ 0xb4, 0xc5, 0x5f, 0xf6, 0xae, 0xc5, 0x60, 0xf6, 0xaf, 0xf7, 0xaf, 0xc5, 0xc0,
+ 0xf7, 0xab, 0xc5, 0xc1, 0xa1, 0xbc, 0xa1, 0xbc, 0xc5, 0xed, 0xc5, 0xeb, 0xf8,
+ 0x57, 0xf8, 0xd7, 0xbb, 0xde, 0xbb, 0xdf, 0xc5, 0xb6, 0xa1, 0xbc, 0xec, 0x56,
+ 0xc6, 0x69, 0xf1, 0x7c, 0xc2, 0xfd, 0xa1, 0xbc, 0xa1, 0xbc, 0xe4, 0xda, 0xbb,
+ 0xeb, 0xbe, 0x75, 0xf6, 0xbc, 0xa1, 0xbc, 0xa1, 0xbc, 0xc0, 0x66, 0xc3, 0x4e,
+ 0xf1, 0xb9, 0xc5, 0x5c, 0xf3, 0xc1, 0xc6, 0x62, 0xf8, 0xd4, 0xc5, 0xea, 0xbe,
+ 0x79, 0xe8, 0xd9, 0xc6, 0x4c, 0xc3, 0x52, 0xef, 0x69, 0xc3, 0x53, 0xc5, 0x5e,
+ 0xc5, 0x57, 0xc5, 0xe4, 0xc3, 0x4b, 0xc5, 0xb9, 0xf7, 0x76, 0xd4, 0x49, 0xb9,
+ 0xa6, 0xbb, 0xec, 0xbe, 0x77, 0xe8, 0xd4, 0xc0, 0x67, 0xc0, 0x68, 0xec, 0x70,
+ 0xf1, 0xbb, 0xa1, 0xbc, 0xc6, 0x4b, 0xf8, 0x55, 0xc6, 0x63, 0xbb, 0xf2, 0xbe,
+ 0xa3, 0xed, 0xdd, 0xb9, 0xa8, 0xec, 0xb1, 0xec, 0xaf, 0xc2, 0x47, 0xc4, 0x51,
+ 0xc3, 0xef, 0xc5, 0x65, 0xc5, 0xef, 0xc2, 0x4c, 0xc2, 0x4a, 0xc2, 0x4b, 0xc3,
+ 0x5c, 0xf1, 0xe0, 0xa1, 0xbc, 0xc6, 0x75, 0xf5, 0xb6, 0xf5, 0xb4, 0xf8, 0x76,
+ 0xc5, 0x66, 0xef, 0xb4, 0xc3, 0x5e, 0xc4, 0xd3, 0xc5, 0xc4, 0xf8, 0x7b, 0xec,
+ 0xb8, 0xc2, 0x4d, 0xa1, 0xbc,
+};
+
+unsigned char FQTermConvert::BtoG[] = {
+ 0xa1, 0xa1, 0xa3, 0xac, 0xa1, 0xa2, 0xa1, 0xa3, 0xa3, 0xae, 0xa3, 0xae, 0xa3,
+ 0xbb, 0xa3, 0xba, 0xa3, 0xbf, 0xa3, 0xa1, 0xa1, 0xc3, 0xa1, 0xad, 0xa1, 0xa7,
+ 0xa3, 0xac, 0xa1, 0xa2, 0xa1, 0xa4, 0xa1, 0xa4, 0xa3, 0xbb, 0xa3, 0xba, 0xa3,
+ 0xbf, 0xa3, 0xa1, 0xa3, 0xfc, 0xa1, 0xf5, 0xa3, 0xfc, 0xa1, 0xf5, 0xa3, 0xfc,
+ 0xa3, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa3, 0xa8, 0xa3, 0xa9, 0xa3, 0xa8, 0xa3,
+ 0xa9, 0xa3, 0xfb, 0xa3, 0xfd, 0xa3, 0xfb, 0xa3, 0xfd, 0xa1, 0xb2, 0xa1, 0xb3,
+ 0xa1, 0xb2, 0xa1, 0xb3, 0xa1, 0xbe, 0xa1, 0xbf, 0xa1, 0xbe, 0xa1, 0xbf, 0xa1,
+ 0xb6, 0xa1, 0xb7, 0xa1, 0xb6, 0xa1, 0xb7, 0xa1, 0xb4, 0xa1, 0xb5, 0xa3, 0xde,
+ 0xa1, 0xb5, 0xa1, 0xb8, 0xa1, 0xb9, 0xa1, 0xb8, 0xa1, 0xb9, 0xa1, 0xba, 0xa1,
+ 0xbb, 0xa1, 0xba, 0xa1, 0xbb, 0xa3, 0xa8, 0xa3, 0xa9, 0xa3, 0xfb, 0xa3, 0xfd,
+ 0xa3, 0xdb, 0xa3, 0xdd, 0xa1, 0xae, 0xa1, 0xaf, 0xa1, 0xb0, 0xa1, 0xb1, 0xa3,
+ 0xa2, 0xa1, 0xe5, 0xa3, 0xe0, 0xa1, 0xe4, 0xa3, 0xa3, 0xa3, 0xa6, 0xa3, 0xaa,
+ 0xa1, 0xf9, 0xa1, 0xec, 0xa1, 0xa8, 0xa1, 0xf0, 0xa1, 0xf1, 0xa1, 0xf7, 0xa1,
+ 0xf8, 0xa1, 0xf2, 0xa1, 0xee, 0xa1, 0xef, 0xa1, 0xf3, 0xa1, 0xf4, 0xa1, 0xf5,
+ 0xa1, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xa5, 0xa1,
+ 0xf5, 0xa3, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa3, 0xa3, 0xa3, 0xa6, 0xa3, 0xaa, 0xa3, 0xab, 0xa3,
+ 0xad, 0xa1, 0xc1, 0xa1, 0xc2, 0xa1, 0xc0, 0xa1, 0xcc, 0xa3, 0xbc, 0xa3, 0xbe,
+ 0xa3, 0xbd, 0xa1, 0xdc, 0xa1, 0xdd, 0xa1, 0xd9, 0xa1, 0xde, 0xa1, 0xd6, 0xa1,
+ 0xd4, 0xa3, 0xab, 0xa3, 0xad, 0xa3, 0xbc, 0xa3, 0xbe, 0xa3, 0xbd, 0xa1, 0xab,
+ 0xa1, 0xc9, 0xa1, 0xc8, 0xa1, 0xf5, 0xa1, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xd2, 0xa1, 0xd3, 0xa1, 0xdf, 0xa1, 0xe0, 0xa1, 0xe2,
+ 0xa1, 0xe1, 0xa1, 0xf5, 0xa1, 0xd1, 0xa1, 0xfc, 0xa1, 0xfd, 0xa1, 0xfb, 0xa1,
+ 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xac, 0xa1, 0xf5,
+ 0xa3, 0xaf, 0xa3, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xe7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xe9, 0xa1, 0xea, 0xa3, 0xa5, 0xa3, 0xc0, 0xa1, 0xe6, 0xa1, 0xf5,
+ 0xa1, 0xe7, 0xa3, 0xa5, 0xa3, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xe3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa9, 0xe0, 0xa9, 0xd8,
+ 0xa9, 0xd0, 0xa9, 0xc8, 0xa9, 0xc0, 0xa1, 0xf5, 0xa1, 0xaa, 0xa9, 0xa6, 0xa1,
+ 0xf5, 0xa9, 0xb0, 0xa9, 0xb4, 0xa9, 0xb8, 0xa9, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa3, 0xb0, 0xa3, 0xb1, 0xa3, 0xb2, 0xa3, 0xb3, 0xa3, 0xb4, 0xa3, 0xb5, 0xa3,
+ 0xb6, 0xa3, 0xb7, 0xa3, 0xb8, 0xa3, 0xb9, 0xa2, 0xf1, 0xa2, 0xf2, 0xa2, 0xf3,
+ 0xa2, 0xf4, 0xa2, 0xf5, 0xa2, 0xf6, 0xa2, 0xf7, 0xa2, 0xf8, 0xa2, 0xf9, 0xa2,
+ 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa3,
+ 0xc1, 0xa3, 0xc2, 0xa3, 0xc3, 0xa3, 0xc4, 0xa3, 0xc5, 0xa3, 0xc6, 0xa3, 0xc7,
+ 0xa3, 0xc8, 0xa3, 0xc9, 0xa3, 0xca, 0xa3, 0xcb, 0xa3, 0xcc, 0xa3, 0xcd, 0xa3,
+ 0xce, 0xa3, 0xcf, 0xa3, 0xd0, 0xa3, 0xd1, 0xa3, 0xd2, 0xa3, 0xd3, 0xa3, 0xd4,
+ 0xa3, 0xd5, 0xa3, 0xd6, 0xa3, 0xd7, 0xa3, 0xd8, 0xa3, 0xd9, 0xa3, 0xda, 0xa3,
+ 0xe1, 0xa3, 0xe2, 0xa3, 0xe3, 0xa3, 0xe4, 0xa3, 0xe5, 0xa3, 0xe6, 0xa3, 0xe7,
+ 0xa3, 0xe8, 0xa3, 0xe9, 0xa3, 0xea, 0xa3, 0xeb, 0xa3, 0xec, 0xa3, 0xed, 0xa3,
+ 0xee, 0xa3, 0xef, 0xa3, 0xf0, 0xa3, 0xf1, 0xa3, 0xf2, 0xa3, 0xf3, 0xa3, 0xf4,
+ 0xa3, 0xf5, 0xa3, 0xf6, 0xa3, 0xf7, 0xa3, 0xf8, 0xa3, 0xf9, 0xa3, 0xfa, 0xa6,
+ 0xa1, 0xa6, 0xa2, 0xa6, 0xa3, 0xa6, 0xa4, 0xa6, 0xa5, 0xa6, 0xa6, 0xa6, 0xa7,
+ 0xa6, 0xa8, 0xa6, 0xa9, 0xa6, 0xaa, 0xa1, 0xc4, 0xa6, 0xac, 0xa6, 0xad, 0xa6,
+ 0xae, 0xa6, 0xaf, 0xa1, 0xc7, 0xa6, 0xb1, 0xa1, 0xc6, 0xa6, 0xb3, 0xa6, 0xb4,
+ 0xa6, 0xb5, 0xa6, 0xb6, 0xa6, 0xb7, 0xa6, 0xb8, 0xa6, 0xc1, 0xa6, 0xc2, 0xa6,
+ 0xc3, 0xa6, 0xc4, 0xa6, 0xc5, 0xa6, 0xc6, 0xa6, 0xc7, 0xa6, 0xc8, 0xa6, 0xc9,
+ 0xa6, 0xca, 0xa6, 0xcb, 0xa6, 0xcc, 0xa6, 0xcd, 0xa6, 0xce, 0xa6, 0xcf, 0xa6,
+ 0xd0, 0xa6, 0xd1, 0xa6, 0xd2, 0xa6, 0xd3, 0xa6, 0xd4, 0xa6, 0xd5, 0xa6, 0xd6,
+ 0xa6, 0xd7, 0xa6, 0xd8, 0xa8, 0xc5, 0xa8, 0xc6, 0xa8, 0xc7, 0xa8, 0xc8, 0xa8,
+ 0xc9, 0xa8, 0xca, 0xa8, 0xcb, 0xa8, 0xcc, 0xa8, 0xcd, 0xa8, 0xce, 0xa8, 0xcf,
+ 0xa8, 0xd0, 0xa8, 0xd1, 0xa8, 0xd2, 0xa8, 0xd3, 0xa8, 0xd4, 0xa8, 0xd5, 0xa8,
+ 0xd6, 0xa8, 0xd7, 0xa8, 0xd8, 0xa8, 0xd9, 0xa8, 0xda, 0xa8, 0xdb, 0xa8, 0xdc,
+ 0xa8, 0xdd, 0xa8, 0xde, 0xa8, 0xdf, 0xa8, 0xe0, 0xa8, 0xe1, 0xa8, 0xe2, 0xa8,
+ 0xe3, 0xa8, 0xe4, 0xa8, 0xe5, 0xa8, 0xe6, 0xa8, 0xe7, 0xa8, 0xe8, 0xa8, 0xe9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd2, 0xbb, 0xd2, 0xd2, 0xb6, 0xa1, 0xc6,
+ 0xdf, 0xc4, 0xcb, 0xbe, 0xc5, 0xc1, 0xcb, 0xb6, 0xfe, 0xc8, 0xcb, 0xb6, 0xf9,
+ 0xc8, 0xeb, 0xb0, 0xcb, 0xbc, 0xb8, 0xb5, 0xb6, 0xb5, 0xf3, 0xc1, 0xa6, 0xd8,
+ 0xb0, 0xca, 0xae, 0xb2, 0xb7, 0xd3, 0xd6, 0xc8, 0xfd, 0xcf, 0xc2, 0xd5, 0xc9,
+ 0xc9, 0xcf, 0xd1, 0xbe, 0xcd, 0xe8, 0xb7, 0xb2, 0xbe, 0xc3, 0xc3, 0xb4, 0xd2,
+ 0xb2, 0xc6, 0xf2, 0xd3, 0xda, 0xcd, 0xf6, 0xd8, 0xa3, 0xc8, 0xd0, 0xc9, 0xd7,
+ 0xc7, 0xa7, 0xb2, 0xe6, 0xbf, 0xda, 0xcd, 0xc1, 0xca, 0xbf, 0xcf, 0xa6, 0xb4,
+ 0xf3, 0xc5, 0xae, 0xd7, 0xd3, 0xe6, 0xdd, 0xe6, 0xde, 0xb4, 0xe7, 0xd0, 0xa1,
+ 0xde, 0xcc, 0xca, 0xac, 0xc9, 0xbd, 0xb4, 0xa8, 0xb9, 0xa4, 0xbc, 0xba, 0xd2,
+ 0xd1, 0xcb, 0xc8, 0xbd, 0xed, 0xb8, 0xc9, 0xde, 0xc3, 0xdf, 0xae, 0xb9, 0xad,
+ 0xb2, 0xc5, 0xb3, 0xf3, 0xd8, 0xa4, 0xb2, 0xbb, 0xd6, 0xd0, 0xb7, 0xe1, 0xb5,
+ 0xa4, 0xd6, 0xae, 0xd2, 0xfc, 0xd3, 0xe8, 0xd4, 0xc6, 0xbe, 0xae, 0xbb, 0xa5,
+ 0xce, 0xe5, 0xbf, 0xba, 0xc8, 0xca, 0xca, 0xb2, 0xd8, 0xea, 0xc6, 0xcd, 0xb3,
+ 0xf0, 0xc8, 0xd4, 0xbd, 0xf1, 0xbd, 0xe9, 0xd8, 0xc6, 0xd4, 0xaa, 0xd4, 0xca,
+ 0xc4, 0xda, 0xc1, 0xf9, 0xd9, 0xe2, 0xb9, 0xab, 0xc8, 0xdf, 0xd0, 0xd7, 0xb7,
+ 0xd6, 0xc7, 0xd0, 0xd8, 0xd7, 0xd4, 0xc8, 0xb9, 0xb4, 0xce, 0xf0, 0xbb, 0xaf,
+ 0xc6, 0xa5, 0xce, 0xe7, 0xc9, 0xfd, 0xd8, 0xa6, 0xb1, 0xe5, 0xb6, 0xf2, 0xd3,
+ 0xd1, 0xbc, 0xb0, 0xb7, 0xb4, 0xc8, 0xc9, 0xcc, 0xec, 0xb7, 0xf2, 0xcc, 0xab,
+ 0xd8, 0xb2, 0xbf, 0xd7, 0xc9, 0xd9, 0xd3, 0xc8, 0xb3, 0xdf, 0xcd, 0xcd, 0xb0,
+ 0xcd, 0xbb, 0xc3, 0xd8, 0xa5, 0xb5, 0xf5, 0xd2, 0xfd, 0xd0, 0xc4, 0xb8, 0xea,
+ 0xbb, 0xa7, 0xca, 0xd6, 0xd4, 0xfa, 0xd6, 0xa7, 0xce, 0xc4, 0xb6, 0xb7, 0xbd,
+ 0xef, 0xb7, 0xbd, 0xc8, 0xd5, 0xd4, 0xbb, 0xd4, 0xc2, 0xc4, 0xbe, 0xc7, 0xb7,
+ 0xd6, 0xb9, 0xb4, 0xf5, 0xce, 0xe3, 0xb1, 0xc8, 0xc3, 0xab, 0xca, 0xcf, 0xcb,
+ 0xae, 0xbb, 0xf0, 0xd7, 0xa6, 0xb8, 0xb8, 0xd8, 0xb3, 0xc6, 0xac, 0xd1, 0xc0,
+ 0xc5, 0xa3, 0xc8, 0xae, 0xcd, 0xf5, 0xb1, 0xfb, 0xca, 0xc0, 0xd8, 0xa7, 0xc7,
+ 0xd2, 0xc7, 0xf0, 0xd6, 0xf7, 0xd5, 0xa7, 0xb7, 0xa6, 0xba, 0xf5, 0xd2, 0xd4,
+ 0xb8, 0xb6, 0xd7, 0xd0, 0xca, 0xcb, 0xcb, 0xfb, 0xd5, 0xcc, 0xb4, 0xfa, 0xc1,
+ 0xee, 0xcf, 0xc9, 0xd8, 0xf0, 0xb3, 0xe4, 0xd0, 0xd6, 0xc8, 0xbd, 0xb2, 0xe1,
+ 0xb6, 0xac, 0xb0, 0xbc, 0xb3, 0xf6, 0xcd, 0xb9, 0xbf, 0xaf, 0xbc, 0xd3, 0xb9,
+ 0xa6, 0xb0, 0xfc, 0xb4, 0xd2, 0xb1, 0xb1, 0xd4, 0xd1, 0xc7, 0xaa, 0xb0, 0xeb,
+ 0xbb, 0xdc, 0xbf, 0xa8, 0xd5, 0xbc, 0xc3, 0xae, 0xd8, 0xb4, 0xc8, 0xa5, 0xbf,
+ 0xc9, 0xb9, 0xc5, 0xd3, 0xd2, 0xd5, 0xd9, 0xb6, 0xa3, 0xdf, 0xb5, 0xdf, 0xb6,
+ 0xb5, 0xf0, 0xcb, 0xbe, 0xd8, 0xcf, 0xbd, 0xd0, 0xc1, 0xed, 0xd6, 0xbb, 0xca,
+ 0xb7, 0xdf, 0xb3, 0xcc, 0xa8, 0xbe, 0xe4, 0xb0, 0xc8, 0xdf, 0xb7, 0xcb, 0xc4,
+ 0xc7, 0xf4, 0xcd, 0xe2, 0xd1, 0xeb, 0xca, 0xa7, 0xc5, 0xab, 0xc4, 0xcc, 0xd4,
+ 0xd0, 0xcb, 0xfc, 0xc4, 0xe1, 0xbe, 0xde, 0xc7, 0xc9, 0xd7, 0xf3, 0xca, 0xd0,
+ 0xb2, 0xbc, 0xc6, 0xbd, 0xd3, 0xd7, 0xdb, 0xcd, 0xba, 0xeb, 0xb8, 0xa5, 0xb1,
+ 0xd8, 0xce, 0xec, 0xb4, 0xf2, 0xc8, 0xd3, 0xb0, 0xc7, 0xc6, 0xcb, 0xb3, 0xe2,
+ 0xb5, 0xa9, 0xca, 0xf5, 0xb1, 0xbe, 0xce, 0xb4, 0xc4, 0xa9, 0xd4, 0xfd, 0xd5,
+ 0xfd, 0xc4, 0xb8, 0xc3, 0xf1, 0xd8, 0xb5, 0xd3, 0xc0, 0xd6, 0xad, 0xcd, 0xa1,
+ 0xb7, 0xba, 0xb7, 0xb8, 0xd0, 0xfe, 0xd3, 0xf1, 0xb9, 0xcf, 0xcd, 0xdf, 0xb8,
+ 0xca, 0xc9, 0xfa, 0xd3, 0xc3, 0xcb, 0xa6, 0xcc, 0xef, 0xd3, 0xc9, 0xbc, 0xd7,
+ 0xc9, 0xea, 0xf1, 0xe2, 0xb0, 0xd7, 0xc6, 0xa4, 0xc3, 0xf3, 0xc4, 0xbf, 0xc3,
+ 0xac, 0xca, 0xb8, 0xca, 0xaf, 0xca, 0xbe, 0xba, 0xcc, 0xd1, 0xa8, 0xc1, 0xa2,
+ 0xd8, 0xa9, 0xb6, 0xaa, 0xc6, 0xb9, 0xc5, 0xd2, 0xd8, 0xc0, 0xd8, 0xa8, 0xbd,
+ 0xbb, 0xd2, 0xe0, 0xba, 0xa5, 0xb7, 0xc2, 0xd8, 0xf8, 0xbb, 0xef, 0xd2, 0xc1,
+ 0xb7, 0xf2, 0xce, 0xe9, 0xb7, 0xa5, 0xd0, 0xdd, 0xb7, 0xfc, 0xd6, 0xd9, 0xbc,
+ 0xfe, 0xc8, 0xce, 0xd1, 0xf6, 0xd8, 0xf2, 0xb7, 0xdd, 0xc6, 0xf3, 0xa1, 0xf5,
+ 0xb9, 0xe2, 0xd0, 0xd7, 0xd5, 0xd7, 0xcf, 0xc8, 0xc8, 0xab, 0xb9, 0xb2, 0xd4,
+ 0xd9, 0xb1, 0xf9, 0xc1, 0xd0, 0xd0, 0xcc, 0xbb, 0xae, 0xd8, 0xd8, 0xeb, 0xbe,
+ 0xc1, 0xd3, 0xd0, 0xd9, 0xbf, 0xef, 0xbd, 0xb3, 0xd3, 0xa1, 0xce, 0xa3, 0xbc,
+ 0xaa, 0xc0, 0xf4, 0xcd, 0xac, 0xb5, 0xf5, 0xcd, 0xc2, 0xd3, 0xf5, 0xb4, 0xe7,
+ 0xb8, 0xf7, 0xcf, 0xf2, 0xc3, 0xfb, 0xba, 0xcf, 0xb3, 0xd4, 0xba, 0xf3, 0xdf,
+ 0xba, 0xdf, 0xb8, 0xd2, 0xf2, 0xbb, 0xd8, 0xe0, 0xee, 0xdb, 0xda, 0xb5, 0xd8,
+ 0xd4, 0xda, 0xb9, 0xe7, 0xdb, 0xd8, 0xdb, 0xdd, 0xdb, 0xd7, 0xd9, 0xed, 0xb6,
+ 0xe0, 0xd2, 0xc4, 0xbf, 0xe4, 0xcd, 0xfd, 0xbc, 0xe9, 0xe5, 0xfa, 0xba, 0xc3,
+ 0xcb, 0xfd, 0xc8, 0xe7, 0xe5, 0xf9, 0xd7, 0xd6, 0xb4, 0xe6, 0xd3, 0xee, 0xca,
+ 0xd8, 0xd5, 0xac, 0xb0, 0xb2, 0xcb, 0xc2, 0xbc, 0xe2, 0xd2, 0xd9, 0xd6, 0xdd,
+ 0xb7, 0xab, 0xb2, 0xa2, 0xc4, 0xea, 0xca, 0xbd, 0xb3, 0xda, 0xc3, 0xa6, 0xe2,
+ 0xe2, 0xc8, 0xd6, 0xd0, 0xe7, 0xca, 0xf9, 0xb3, 0xc9, 0xbf, 0xdb, 0xbf, 0xb8,
+ 0xcd, 0xd0, 0xca, 0xd5, 0xd4, 0xe7, 0xd6, 0xbc, 0xd1, 0xae, 0xd0, 0xf1, 0xc7,
+ 0xfa, 0xd2, 0xb7, 0xd3, 0xd0, 0xd0, 0xe0, 0xc6, 0xd3, 0xd6, 0xec, 0xb6, 0xe4,
+ 0xb4, 0xce, 0xb4, 0xcb, 0xcb, 0xc0, 0xc4, 0xca, 0xc8, 0xea, 0xba, 0xb9, 0xce,
+ 0xdb, 0xbd, 0xad, 0xb3, 0xd8, 0xcf, 0xab, 0xc9, 0xc7, 0xce, 0xdb, 0xd1, 0xb4,
+ 0xa1, 0xf5, 0xb7, 0xba, 0xbb, 0xd2, 0xc4, 0xb2, 0xea, 0xf2, 0xb0, 0xd9, 0xd6,
+ 0xf1, 0xc3, 0xd7, 0xf4, 0xe9, 0xf3, 0xbe, 0xd1, 0xf2, 0xd3, 0xf0, 0xc0, 0xcf,
+ 0xbf, 0xbc, 0xb6, 0xf8, 0xf1, 0xe7, 0xb6, 0xfa, 0xed, 0xb2, 0xc8, 0xe2, 0xc0,
+ 0xdf, 0xbc, 0xa1, 0xb3, 0xbc, 0xd7, 0xd4, 0xd6, 0xc1, 0xbe, 0xca, 0xc9, 0xe0,
+ 0xe2, 0xb6, 0xd6, 0xdb, 0xf4, 0xde, 0xc9, 0xab, 0xb0, 0xac, 0xb3, 0xe6, 0xd1,
+ 0xaa, 0xd0, 0xd0, 0xd2, 0xc2, 0xce, 0xf7, 0xda, 0xe4, 0xb4, 0xae, 0xba, 0xe0,
+ 0xce, 0xbb, 0xd7, 0xa1, 0xd8, 0xf9, 0xd9, 0xa2, 0xd8, 0xfa, 0xb0, 0xe9, 0xb7,
+ 0xf0, 0xba, 0xce, 0xb9, 0xc0, 0xd7, 0xf4, 0xd3, 0xd3, 0xd9, 0xa4, 0xcb, 0xc5,
+ 0xc9, 0xec, 0xb5, 0xe8, 0xd5, 0xbc, 0xcb, 0xc6, 0xb5, 0xab, 0xd3, 0xb6, 0xd7,
+ 0xf7, 0xc4, 0xe3, 0xb2, 0xae, 0xb5, 0xcd, 0xc1, 0xe6, 0xd3, 0xe0, 0xd8, 0xfe,
+ 0xb2, 0xbc, 0xd8, 0xfd, 0xb6, 0xd2, 0xbf, 0xcb, 0xc3, 0xe2, 0xb1, 0xf8, 0xd2,
+ 0xb1, 0xc0, 0xe4, 0xb1, 0xf0, 0xc5, 0xd0, 0xc0, 0xfb, 0xc9, 0xbe, 0xc5, 0xd9,
+ 0xbd, 0xd9, 0xd6, 0xfa, 0xc5, 0xac, 0xdb, 0xbe, 0xcf, 0xbb, 0xbc, 0xb4, 0xc2,
+ 0xd1, 0xc1, 0xdf, 0xbf, 0xd4, 0xcd, 0xcc, 0xce, 0xe1, 0xb7, 0xf1, 0xb3, 0xdf,
+ 0xb0, 0xc9, 0xb4, 0xf4, 0xdf, 0xc0, 0xce, 0xe2, 0xb3, 0xca, 0xc2, 0xc0, 0xbe,
+ 0xfd, 0xb7, 0xd4, 0xb8, 0xe6, 0xb4, 0xb5, 0xce, 0xc7, 0xce, 0xfc, 0xcb, 0xb1,
+ 0xb3, 0xb3, 0xc4, 0xc5, 0xb7, 0xcd, 0xba, 0xf0, 0xd1, 0xbd, 0xd6, 0xa8, 0xba,
+ 0xac, 0xd2, 0xf7, 0xcc, 0xfd, 0xb4, 0xd1, 0xc0, 0xa7, 0xb6, 0xda, 0xe0, 0xf1,
+ 0xb7, 0xbb, 0xbf, 0xd3, 0xd6, 0xb7, 0xcc, 0xae, 0xbe, 0xf9, 0xbf, 0xb2, 0xbb,
+ 0xf8, 0xd7, 0xf8, 0xbb, 0xb5, 0xdb, 0xdf, 0xd7, 0xb3, 0xbc, 0xd0, 0xd7, 0xb1,
+ 0xb6, 0xca, 0xb7, 0xc1, 0xe6, 0xa4, 0xe5, 0xfe, 0xc3, 0xee, 0xd1, 0xfd, 0xe5,
+ 0xfb, 0xe6, 0xa5, 0xbc, 0xcb, 0xc8, 0xd1, 0xcd, 0xd7, 0xd0, 0xa2, 0xd7, 0xce,
+ 0xe6, 0xda, 0xd8, 0xc3, 0xcd, 0xea, 0xcb, 0xce, 0xba, 0xea, 0xde, 0xce, 0xbe,
+ 0xd6, 0xc6, 0xa8, 0xc4, 0xf2, 0xce, 0xb2, 0xe1, 0xaa, 0xe1, 0xaf, 0xb2, 0xed,
+ 0xe1, 0xa7, 0xce, 0xd7, 0xcf, 0xa3, 0xd0, 0xf2, 0xb1, 0xd3, 0xb4, 0xb2, 0xcd,
+ 0xa2, 0xc5, 0xaa, 0xb5, 0xdc, 0xcd, 0xae, 0xd0, 0xce, 0xe1, 0xdd, 0xd2, 0xdb,
+ 0xcd, 0xfc, 0xbc, 0xc9, 0xd6, 0xbe, 0xc8, 0xcc, 0xb3, 0xc0, 0xbf, 0xec, 0xe2,
+ 0xee, 0xe2, 0xec, 0xbd, 0xe4, 0xce, 0xd2, 0xb3, 0xad, 0xbf, 0xb9, 0xb6, 0xb6,
+ 0xbc, 0xbc, 0xb7, 0xf6, 0xbe, 0xf1, 0xc5, 0xa4, 0xb0, 0xd1, 0xb6, 0xf3, 0xd5,
+ 0xd2, 0xc5, 0xfa, 0xb0, 0xe2, 0xca, 0xe3, 0xb3, 0xb6, 0xd5, 0xdb, 0xb0, 0xe7,
+ 0xcd, 0xb6, 0xd7, 0xa5, 0xd2, 0xd6, 0xa1, 0xf5, 0xb8, 0xc4, 0xb9, 0xa5, 0xd8,
+ 0xfc, 0xba, 0xb5, 0xb8, 0xfc, 0xca, 0xf8, 0xc0, 0xee, 0xd0, 0xd3, 0xb2, 0xc4,
+ 0xb4, 0xe5, 0xb6, 0xc5, 0xd5, 0xc8, 0xe8, 0xbd, 0xc9, 0xbc, 0xb8, 0xcb, 0xb8,
+ 0xdc, 0xe8, 0xbc, 0xa1, 0xf5, 0xb2, 0xbd, 0xc3, 0xbf, 0xc7, 0xf3, 0xb9, 0xaf,
+ 0xc9, 0xb3, 0xc7, 0xdf, 0xc9, 0xf2, 0xb3, 0xc1, 0xe3, 0xe4, 0xc5, 0xe6, 0xcd,
+ 0xf4, 0xbe, 0xf6, 0xe3, 0xe5, 0xcc, 0xad, 0xe3, 0xe7, 0xe3, 0xe8, 0xb3, 0xe5,
+ 0xc3, 0xbb, 0xc6, 0xfb, 0xce, 0xd6, 0xbc, 0xb3, 0xb7, 0xda, 0xe3, 0xea, 0xe3,
+ 0xec, 0xe3, 0xeb, 0xa1, 0xf5, 0xe3, 0xe6, 0xa1, 0xf5, 0xd2, 0xca, 0xd4, 0xee,
+ 0xd7, 0xc6, 0xd4, 0xd6, 0xbe, 0xc4, 0xc0, 0xce, 0xc4, 0xb5, 0xcb, 0xfc, 0xb5,
+ 0xd2, 0xbf, 0xf1, 0xbe, 0xc1, 0xf0, 0xae, 0xb8, 0xa6, 0xc4, 0xd0, 0xb5, 0xe9,
+ 0xd4, 0xed, 0xb6, 0xa2, 0xd2, 0xd3, 0xcb, 0xbd, 0xd0, 0xe3, 0xcd, 0xba, 0xbe,
+ 0xbf, 0xcf, 0xb5, 0xba, 0xb1, 0xd0, 0xa4, 0xeb, 0xc1, 0xb8, 0xce, 0xd6, 0xe2,
+ 0xb8, 0xd8, 0xb6, 0xc7, 0xd3, 0xfd, 0xc1, 0xbc, 0xc3, 0xa2, 0xd3, 0xf3, 0xc9,
+ 0xd6, 0xbc, 0xfb, 0xbd, 0xc7, 0xd1, 0xd4, 0xb9, 0xc8, 0xb6, 0xb9, 0xf5, 0xb9,
+ 0xb1, 0xb4, 0xb3, 0xe0, 0xd7, 0xdf, 0xd7, 0xe3, 0xc9, 0xed, 0xb3, 0xb5, 0xd0,
+ 0xc1, 0xb3, 0xbd, 0xd3, 0xd8, 0xe5, 0xc6, 0xd1, 0xb8, 0xc6, 0xf9, 0xd1, 0xb2,
+ 0xd2, 0xd8, 0xd0, 0xcf, 0xd0, 0xb0, 0xb0, 0xee, 0xc4, 0xc7, 0xd3, 0xcf, 0xb2,
+ 0xc9, 0xc0, 0xef, 0xb7, 0xc0, 0xc8, 0xee, 0xda, 0xe5, 0xda, 0xe6, 0xa1, 0xf5,
+ 0xb2, 0xa2, 0xb9, 0xd4, 0xc8, 0xe9, 0xca, 0xc2, 0xd0, 0xa9, 0xd1, 0xc7, 0xcf,
+ 0xed, 0xbe, 0xa9, 0xd1, 0xf0, 0xd2, 0xc0, 0xca, 0xcc, 0xbc, 0xd1, 0xca, 0xb9,
+ 0xc0, 0xd0, 0xb9, 0xa9, 0xc0, 0xfd, 0xc0, 0xb4, 0xd9, 0xa9, 0xb0, 0xdb, 0xb2,
+ 0xa2, 0xb3, 0xde, 0xc5, 0xe5, 0xd9, 0xac, 0xc2, 0xd8, 0xd9, 0xab, 0xd9, 0xaa,
+ 0xd9, 0xa7, 0xa1, 0xf5, 0xcd, 0xc3, 0xb6, 0xf9, 0xd9, 0xee, 0xc1, 0xbd, 0xbe,
+ 0xdf, 0xc6, 0xe4, 0xb5, 0xe4, 0xd9, 0xfd, 0xba, 0xaf, 0xbf, 0xcc, 0xc8, 0xaf,
+ 0xcb, 0xa2, 0xb4, 0xcc, 0xb5, 0xbd, 0xb9, 0xce, 0xd6, 0xc6, 0xb6, 0xe7, 0xdb,
+ 0xc0, 0xa1, 0xf5, 0xd7, 0xe4, 0xd0, 0xad, 0xd7, 0xbf, 0xb1, 0xb0, 0xd8, 0xd4,
+ 0xbe, 0xed, 0xd0, 0xb6, 0xd0, 0xf4, 0xc8, 0xa1, 0xca, 0xe5, 0xca, 0xdc, 0xce,
+ 0xb6, 0xba, 0xc7, 0xbf, 0xa7, 0xc5, 0xde, 0xb9, 0xbe, 0xbe, 0xd7, 0xc9, 0xeb,
+ 0xdf, 0xc8, 0xdf, 0xcd, 0xd6, 0xe4, 0xc5, 0xd8, 0xba, 0xf4, 0xb8, 0xc0, 0xdf,
+ 0xc9, 0xdf, 0xce, 0xba, 0xcd, 0xdf, 0xcb, 0xc4, 0xd8, 0xd6, 0xdc, 0xd5, 0xa6,
+ 0xc3, 0xfc, 0xbe, 0xcc, 0xb9, 0xcc, 0xc0, 0xac, 0xbf, 0xc0, 0xc6, 0xba, 0xdb,
+ 0xe1, 0xc6, 0xc2, 0xcc, 0xb9, 0xc0, 0xa4, 0xdb, 0xe5, 0xd2, 0xb9, 0xb7, 0xee,
+ 0xc6, 0xe6, 0xc4, 0xce, 0xd1, 0xd9, 0xb1, 0xbc, 0xe6, 0xaa, 0xc6, 0xde, 0xce,
+ 0xaf, 0xc3, 0xc3, 0xc4, 0xdd, 0xb9, 0xc3, 0xc4, 0xb7, 0xbd, 0xe3, 0xe6, 0xa9,
+ 0xca, 0xbc, 0xd0, 0xd5, 0xe6, 0xa2, 0xe6, 0xa8, 0xc4, 0xe3, 0xe6, 0xa6, 0xa1,
+ 0xf5, 0xc3, 0xcf, 0xb9, 0xc2, 0xbc, 0xbe, 0xd7, 0xda, 0xb6, 0xa8, 0xb9, 0xd9,
+ 0xd2, 0xcb, 0xd6, 0xe6, 0xcd, 0xf0, 0xc9, 0xd0, 0xc7, 0xfc, 0xbe, 0xd3, 0xbd,
+ 0xec, 0xe1, 0xba, 0xb8, 0xd4, 0xb0, 0xb6, 0xd1, 0xd2, 0xe1, 0xb6, 0xe1, 0xb7,
+ 0xd4, 0xc0, 0xc1, 0xb1, 0xd6, 0xe3, 0xcc, 0xfb, 0xc5, 0xc1, 0xb2, 0xaf, 0xe0,
+ 0xfb, 0xd0, 0xd2, 0xb8, 0xfd, 0xb5, 0xea, 0xb8, 0xae, 0xb5, 0xd7, 0xe2, 0xd2,
+ 0xd1, 0xd3, 0xcf, 0xd2, 0xbb, 0xa1, 0xe5, 0xf3, 0xcd, 0xf9, 0xd5, 0xf7, 0xb7,
+ 0xf0, 0xb1, 0xcb, 0xe3, 0xc3, 0xd6, 0xd2, 0xba, 0xf6, 0xc4, 0xee, 0xb7, 0xde,
+ 0xe2, 0xf3, 0xd5, 0xfa, 0xc7, 0xd3, 0xe2, 0xf0, 0xb2, 0xc0, 0xb9, 0xd6, 0xc5,
+ 0xc2, 0xe2, 0xf9, 0xd0, 0xd4, 0xe2, 0xf5, 0xe2, 0xf6, 0xe2, 0xf2, 0xbb, 0xf2,
+ 0xe3, 0xde, 0xb7, 0xbf, 0xec, 0xe5, 0xcb, 0xf9, 0xb3, 0xd0, 0xc0, 0xad, 0xb0,
+ 0xe8, 0xd6, 0xf4, 0xc3, 0xf2, 0xb7, 0xf7, 0xc4, 0xa8, 0xbe, 0xdc, 0xd5, 0xd0,
+ 0xc5, 0xfb, 0xcd, 0xd8, 0xb0, 0xce, 0xc5, 0xd7, 0xc4, 0xe9, 0xc5, 0xea, 0xb3,
+ 0xe9, 0xd1, 0xba, 0xb9, 0xd5, 0xd7, 0xbe, 0xc4, 0xb4, 0xc5, 0xc4, 0xb5, 0xd6,
+ 0xde, 0xd5, 0xb1, 0xa7, 0xbe, 0xd0, 0xcd, 0xcf, 0xde, 0xd6, 0xb2, 0xf0, 0xcc,
+ 0xa7, 0xc1, 0xe0, 0xb7, 0xc5, 0xb8, 0xab, 0xd3, 0xda, 0xcd, 0xfa, 0xce, 0xf4,
+ 0xd2, 0xd7, 0xb2, 0xfd, 0xc0, 0xa5, 0xb0, 0xba, 0xc3, 0xf7, 0xea, 0xc0, 0xbb,
+ 0xe8, 0xea, 0xbf, 0xea, 0xbb, 0xc9, 0xfd, 0xb7, 0xfe, 0xc5, 0xf3, 0xba, 0xbc,
+ 0xe8, 0xca, 0xd5, 0xed, 0xb6, 0xab, 0xb9, 0xfb, 0xe8, 0xc3, 0xe8, 0xcb, 0xe8,
+ 0xc1, 0xd6, 0xa6, 0xc1, 0xd6, 0xb1, 0xad, 0xbd, 0xdc, 0xb0, 0xe5, 0xcd, 0xf7,
+ 0xcb, 0xc9, 0xce, 0xf6, 0xe8, 0xc6, 0xc3, 0xb6, 0xa1, 0xf5, 0xe8, 0xcc, 0xe8,
+ 0xc2, 0xea, 0xbd, 0xd0, 0xc0, 0xce, 0xe4, 0xc6, 0xe7, 0xe9, 0xe2, 0xc3, 0xa5,
+ 0xb7, 0xd5, 0xc6, 0xfc, 0xd7, 0xa2, 0xd3, 0xbe, 0xe3, 0xfb, 0xc3, 0xda, 0xc4,
+ 0xe0, 0xba, 0xd3, 0xb9, 0xc1, 0xd5, 0xb4, 0xd5, 0xd3, 0xb2, 0xa8, 0xc4, 0xad,
+ 0xb7, 0xa8, 0xe3, 0xfc, 0xb7, 0xd0, 0xd0, 0xb9, 0xd3, 0xcd, 0xbf, 0xf6, 0xbe,
+ 0xda, 0xe3, 0xf4, 0xc7, 0xf6, 0xe3, 0xf3, 0xd1, 0xd8, 0xd6, 0xce, 0xc5, 0xdd,
+ 0xb7, 0xba, 0xb2, 0xb4, 0xa1, 0xf5, 0xe3, 0xfd, 0xa1, 0xf5, 0xe3, 0xf7, 0xe3,
+ 0xf6, 0xbf, 0xbb, 0xd1, 0xd7, 0xb3, 0xb4, 0xb4, 0xb6, 0xd6, 0xcb, 0xc5, 0xc0,
+ 0xd5, 0xf9, 0xb0, 0xd6, 0xb0, 0xe6, 0xc4, 0xc1, 0xce, 0xef, 0xd7, 0xb4, 0xe1,
+ 0xf2, 0xbe, 0xd1, 0xb9, 0xb7, 0xba, 0xfc, 0xcd, 0xe6, 0xe7, 0xe5, 0xe7, 0xe4,
+ 0xc3, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xde, 0xb8, 0xed, 0xbe, 0xce, 0xb5,
+ 0xc4, 0xd3, 0xdb, 0xc3, 0xa4, 0xd6, 0xb1, 0xd6, 0xaa, 0xce, 0xf9, 0xc9, 0xe7,
+ 0xec, 0xeb, 0xc6, 0xee, 0xb1, 0xfc, 0xf4, 0xcc, 0xbf, 0xd5, 0xf1, 0xb7, 0xf3,
+ 0xc3, 0xbe, 0xc0, 0xd8, 0xe8, 0xc7, 0xbc, 0xd8, 0xc2, 0xd5, 0xdf, 0xb7, 0xce,
+ 0xb7, 0xca, 0xd6, 0xab, 0xeb, 0xc5, 0xb9, 0xc9, 0xeb, 0xc6, 0xbc, 0xe7, 0xeb,
+ 0xc8, 0xb7, 0xbe, 0xbf, 0xcf, 0xce, 0xd4, 0xf4, 0xa7, 0xc9, 0xe1, 0xb7, 0xbc,
+ 0xd6, 0xa5, 0xdc, 0xbd, 0xb0, 0xc5, 0xd1, 0xbf, 0xdc, 0xcf, 0xc7, 0xdb, 0xbb,
+ 0xa8, 0xb7, 0xd2, 0xbd, 0xe6, 0xd0, 0xbe, 0xdc, 0xbf, 0xa1, 0xf5, 0xdc, 0xc1,
+ 0xdc, 0xc0, 0xdc, 0xc6, 0xbb, 0xa2, 0xca, 0xad, 0xb3, 0xf5, 0xb1, 0xed, 0xd4,
+ 0xfe, 0xd3, 0xad, 0xb7, 0xb5, 0xbd, 0xfc, 0xc9, 0xdb, 0xdb, 0xa1, 0xc7, 0xf1,
+ 0xda, 0xfd, 0xb2, 0xc9, 0xbd, 0xf0, 0xb3, 0xa4, 0xc3, 0xc5, 0xb8, 0xb7, 0xcd,
+ 0xd3, 0xb0, 0xa2, 0xd7, 0xe8, 0xb8, 0xbd, 0xda, 0xe9, 0xf6, 0xbf, 0xd3, 0xea,
+ 0xc7, 0xe0, 0xb7, 0xc7, 0xd8, 0xbd, 0xcd, 0xa4, 0xc1, 0xc1, 0xd0, 0xc5, 0xc7,
+ 0xd6, 0xba, 0xee, 0xb1, 0xe3, 0xcf, 0xc0, 0xd9, 0xb8, 0xc7, 0xce, 0xb1, 0xa3,
+ 0xb4, 0xd9, 0xc2, 0xc2, 0xb7, 0xfd, 0xd9, 0xb9, 0xbf, 0xa1, 0xcb, 0xd7, 0xce,
+ 0xea, 0xc0, 0xfe, 0xb6, 0xed, 0xcf, 0xb5, 0xd9, 0xb5, 0xd9, 0xde, 0xd3, 0xe1,
+ 0xbe, 0xd6, 0xd9, 0xf0, 0xc3, 0xb0, 0xeb, 0xd0, 0xb9, 0xda, 0xc9, 0xb2, 0xcc,
+ 0xea, 0xcf, 0xf7, 0xc7, 0xb0, 0xd8, 0xdd, 0xbf, 0xcb, 0xd4, 0xf2, 0xd3, 0xc2,
+ 0xc3, 0xe3, 0xb2, 0xaa, 0xbe, 0xa2, 0xd9, 0xe9, 0xc4, 0xcf, 0xc8, 0xb4, 0xba,
+ 0xf1, 0xc5, 0xd1, 0xd2, 0xa7, 0xb0, 0xa7, 0xd7, 0xc9, 0xb0, 0xa5, 0xd4, 0xd5,
+ 0xcf, 0xcc, 0xdf, 0xd7, 0xbf, 0xc8, 0xcd, 0xdb, 0xdf, 0xd3, 0xd1, 0xca, 0xdf,
+ 0xe4, 0xc6, 0xb7, 0xba, 0xe5, 0xb9, 0xfe, 0xbf, 0xa9, 0xe5, 0xeb, 0xd4, 0xdb,
+ 0xdf, 0xdd, 0xdf, 0xe3, 0xdf, 0xd6, 0xdf, 0xde, 0xe0, 0xf3, 0xb4, 0xb9, 0xd0,
+ 0xcd, 0xdb, 0xf3, 0xd4, 0xab, 0xb9, 0xb8, 0xb3, 0xc7, 0xbf, 0xe5, 0xdb, 0xf2,
+ 0xde, 0xc8, 0xc6, 0xf5, 0xd7, 0xe0, 0xbf, 0xfc, 0xdb, 0xbc, 0xbd, 0xaa, 0xe6,
+ 0xb0, 0xd7, 0xcb, 0xe6, 0xaf, 0xd2, 0xcc, 0xcd, 0xde, 0xc0, 0xd1, 0xd6, 0xb6,
+ 0xd2, 0xa6, 0xbc, 0xe9, 0xcd, 0xfe, 0xd2, 0xf6, 0xba, 0xa2, 0xd0, 0xfb, 0xbb,
+ 0xc2, 0xca, 0xd2, 0xbf, 0xcd, 0xe5, 0xb6, 0xb7, 0xe2, 0xca, 0xba, 0xc6, 0xc1,
+ 0xca, 0xac, 0xce, 0xdd, 0xd6, 0xc5, 0xe1, 0xbc, 0xcf, 0xef, 0xb5, 0xdb, 0xcb,
+ 0xa7, 0xa1, 0xf5, 0xd3, 0xc4, 0xe2, 0xd4, 0xb6, 0xc8, 0xbd, 0xa8, 0xde, 0xc4,
+ 0xe5, 0xf4, 0xd1, 0xe5, 0xba, 0xdc, 0xb4, 0xfd, 0xbb, 0xb2, 0xc2, 0xc9, 0xe1,
+ 0xdf, 0xba, 0xf3, 0xe1, 0xe0, 0xc5, 0xad, 0xcb, 0xbc, 0xb5, 0xa1, 0xbc, 0xb1,
+ 0xd4, 0xf5, 0xd4, 0xb9, 0xbb, 0xd0, 0xc7, 0xa1, 0xba, 0xde, 0xbb, 0xd6, 0xba,
+ 0xe3, 0xca, 0xd1, 0xcc, 0xf1, 0xb6, 0xb2, 0xe3, 0xa1, 0xd0, 0xf4, 0xb1, 0xe2,
+ 0xb0, 0xdd, 0xcd, 0xda, 0xb0, 0xb4, 0xc6, 0xb4, 0xca, 0xc3, 0xb3, 0xd6, 0xde,
+ 0xd7, 0xd7, 0xa7, 0xd6, 0xb8, 0xb9, 0xb0, 0xbf, 0xbd, 0xd5, 0xfc, 0xc0, 0xa8,
+ 0xca, 0xb0, 0xcb, 0xa9, 0xcc, 0xf4, 0xb9, 0xd2, 0xd5, 0xfe, 0xb9, 0xca, 0xed,
+ 0xbd, 0xca, 0xa9, 0xbc, 0xc8, 0xb4, 0xba, 0xd5, 0xd1, 0xd3, 0xb3, 0xc3, 0xc1,
+ 0xca, 0xc7, 0xd0, 0xc7, 0xd7, 0xf2, 0xea, 0xc5, 0xa1, 0xf5, 0xea, 0xc2, 0xca,
+ 0xc1, 0xc8, 0xbe, 0xd6, 0xf9, 0xc8, 0xe1, 0xc4, 0xb3, 0xbc, 0xed, 0xbc, 0xdc,
+ 0xbf, 0xdd, 0xd5, 0xa4, 0xe8, 0xd1, 0xbf, 0xc2, 0xb1, 0xfa, 0xb8, 0xcc, 0xb9,
+ 0xd5, 0xe8, 0xd6, 0xb2, 0xe9, 0xe8, 0xdb, 0xb0, 0xd8, 0xd7, 0xf5, 0xc1, 0xf8,
+ 0xe8, 0xd2, 0xe8, 0xd4, 0xe8, 0xdc, 0xe8, 0xd8, 0xc6, 0xe2, 0xcd, 0xe1, 0xd1,
+ 0xea, 0xb4, 0xf9, 0xb6, 0xce, 0xb6, 0xbe, 0xc5, 0xfe, 0xb7, 0xfa, 0xc8, 0xaa,
+ 0xd1, 0xf3, 0xd6, 0xde, 0xba, 0xe9, 0xc1, 0xf7, 0xbd, 0xf2, 0xe4, 0xa3, 0xb6,
+ 0xfd, 0xb6, 0xb4, 0xcf, 0xb4, 0xbb, 0xee, 0xc7, 0xa2, 0xc5, 0xc9, 0xd0, 0xda,
+ 0xc2, 0xe5, 0xb1, 0xc3, 0xe4, 0xa1, 0xe4, 0xa2, 0xa1, 0xf5, 0xd0, 0xb9, 0xe4,
+ 0xac, 0xe4, 0xad, 0xe4, 0xa9, 0xe4, 0xaa, 0xec, 0xc5, 0xce, 0xaa, 0xb1, 0xfe,
+ 0xbe, 0xe6, 0xbe, 0xbc, 0xcc, 0xbf, 0xd5, 0xa8, 0xc5, 0xda, 0xa1, 0xf5, 0xeb,
+ 0xbc, 0xc9, 0xfc, 0xea, 0xf4, 0xb5, 0xd6, 0xe1, 0xf7, 0xba, 0xdd, 0xbd, 0xc6,
+ 0xe7, 0xe8, 0xc9, 0xba, 0xb2, 0xa3, 0xc1, 0xe1, 0xd5, 0xe4, 0xe7, 0xea, 0xe7,
+ 0xe9, 0xc9, 0xf5, 0xb1, 0xc2, 0xce, 0xb7, 0xbd, 0xe7, 0xee, 0xb0, 0xee, 0xb1,
+ 0xd2, 0xdf, 0xb0, 0xcc, 0xbd, 0xea, 0xa1, 0xf5, 0xf0, 0xe0, 0xb9, 0xef, 0xbd,
+ 0xd4, 0xbb, 0xca, 0xf0, 0xa7, 0xd3, 0xaf, 0xc5, 0xe8, 0xb1, 0xad, 0xd6, 0xd1,
+ 0xca, 0xa1, 0xed, 0xef, 0xcf, 0xe0, 0xc3, 0xbc, 0xbf, 0xb4, 0xb6, 0xdc, 0xc5,
+ 0xce, 0xed, 0xf0, 0xf1, 0xe6, 0xc9, 0xb0, 0xd1, 0xd0, 0xc6, 0xf6, 0xbf, 0xb3,
+ 0xec, 0xec, 0xec, 0xed, 0xc6, 0xed, 0xa1, 0xf5, 0xd3, 0xed, 0xd8, 0xae, 0xbf,
+ 0xc6, 0xc3, 0xeb, 0xc7, 0xef, 0xb4, 0xa9, 0xcd, 0xbb, 0xb8, 0xcd, 0xf3, 0xc4,
+ 0xd7, 0xd1, 0xe6, 0xfb, 0xba, 0xec, 0xbc, 0xcd, 0xc8, 0xd2, 0xe6, 0xfc, 0xd4,
+ 0xbc, 0xe6, 0xfa, 0xb8, 0xd7, 0xc3, 0xc0, 0xf4, 0xe0, 0xeb, 0xa3, 0xc4, 0xcd,
+ 0xcb, 0xa3, 0xd7, 0xa8, 0xd2, 0xae, 0xc5, 0xd6, 0xf1, 0xe3, 0xc5, 0xdf, 0xce,
+ 0xb8, 0xeb, 0xd0, 0xb1, 0xb3, 0xba, 0xfa, 0xeb, 0xce, 0xcc, 0xa5, 0xb0, 0xfb,
+ 0xd8, 0xb7, 0xeb, 0xd5, 0xd6, 0xc2, 0xf4, 0xae, 0xdc, 0xd1, 0xb7, 0xb6, 0xc3,
+ 0xa9, 0xdc, 0xc4, 0xbf, 0xc1, 0xbf, 0xe0, 0xc7, 0xd1, 0xc8, 0xf4, 0xc3, 0xaf,
+ 0xdc, 0xd4, 0xdc, 0xdb, 0xc3, 0xe7, 0xd3, 0xa2, 0xd7, 0xc2, 0xdc, 0xd9, 0xcc,
+ 0xa6, 0xd4, 0xb7, 0xb0, 0xfa, 0xdc, 0xdf, 0xb9, 0xb6, 0xb1, 0xbd, 0xdc, 0xe2,
+ 0xc5, 0xb0, 0xba, 0xe7, 0xf2, 0xb5, 0xf2, 0xb3, 0xd1, 0xdc, 0xc9, 0xc0, 0xd2,
+ 0xaa, 0xbd, 0xee, 0xbc, 0xc6, 0xb6, 0xa9, 0xb8, 0xbc, 0xd5, 0xea, 0xb8, 0xba,
+ 0xb8, 0xb0, 0xf4, 0xf1, 0xc5, 0xbf, 0xbe, 0xfc, 0xb9, 0xec, 0xca, 0xf6, 0xe5,
+ 0xc8, 0xcc, 0xf6, 0xb5, 0xcf, 0xe5, 0xc4, 0xb5, 0xfc, 0xc6, 0xc8, 0xe5, 0xc6,
+ 0xe5, 0xca, 0xbd, 0xbc, 0xc0, 0xc9, 0xd3, 0xf4, 0xa1, 0xf5, 0xc7, 0xf5, 0xf4,
+ 0xfa, 0xd6, 0xd8, 0xe3, 0xc5, 0xcf, 0xde, 0xc2, 0xaa, 0xc4, 0xb0, 0xbd, 0xb5,
+ 0xc3, 0xe6, 0xb8, 0xef, 0xce, 0xa4, 0xbe, 0xc2, 0xd2, 0xf4, 0xd2, 0xb3, 0xb7,
+ 0xe7, 0xb7, 0xc9, 0xca, 0xb3, 0xca, 0xd7, 0xcf, 0xe3, 0xb3, 0xcb, 0xd9, 0xf1,
+ 0xd9, 0xc4, 0xb1, 0xb6, 0xb7, 0xc2, 0xb8, 0xa9, 0xbe, 0xeb, 0xd9, 0xc5, 0xd9,
+ 0xba, 0xd9, 0xbb, 0xd0, 0xd2, 0xc1, 0xa9, 0xd6, 0xb5, 0xbd, 0xe8, 0xd2, 0xd0,
+ 0xb5, 0xb9, 0xc3, 0xc7, 0xb0, 0xb3, 0xd8, 0xf6, 0xbe, 0xf3, 0xd9, 0xc6, 0xbe,
+ 0xe3, 0xb3, 0xab, 0xb8, 0xf6, 0xba, 0xf2, 0xcc, 0xc8, 0xd9, 0xbd, 0xd0, 0xde,
+ 0xd9, 0xc1, 0xc4, 0xdf, 0xd9, 0xc2, 0xc2, 0xd7, 0xb2, 0xd6, 0xbc, 0xe6, 0xd4,
+ 0xa9, 0xda, 0xa4, 0xda, 0xa3, 0xb6, 0xb3, 0xc1, 0xe8, 0xd7, 0xbc, 0xb5, 0xf2,
+ 0xc6, 0xca, 0xd8, 0xe0, 0xcc, 0xde, 0xb8, 0xd5, 0xb0, 0xfe, 0xb7, 0xcb, 0xc7,
+ 0xe4, 0xd4, 0xad, 0xd8, 0xc8, 0xdb, 0xc5, 0xc9, 0xda, 0xcc, 0xc6, 0xd1, 0xe4,
+ 0xe0, 0xa1, 0xba, 0xdf, 0xb8, 0xe7, 0xd5, 0xdc, 0xcb, 0xf4, 0xb2, 0xb8, 0xdf,
+ 0xed, 0xc1, 0xa8, 0xbf, 0xde, 0xd4, 0xb1, 0xb0, 0xa6, 0xcf, 0xf8, 0xc4, 0xc4,
+ 0xc5, 0xb6, 0xdf, 0xf3, 0xb4, 0xbd, 0xdf, 0xec, 0xdf, 0xf1, 0xc6, 0xd4, 0xe0,
+ 0xf4, 0xb9, 0xa1, 0xc6, 0xd2, 0xc2, 0xf1, 0xb0, 0xa3, 0xa1, 0xf5, 0xcf, 0xc4,
+ 0xcc, 0xd7, 0xde, 0xca, 0xde, 0xc9, 0xe6, 0xb6, 0xc4, 0xef, 0xc4, 0xc8, 0xbe,
+ 0xea, 0xd3, 0xe9, 0xe6, 0xb8, 0xbc, 0xa7, 0xc9, 0xef, 0xe6, 0xb7, 0xc3, 0xe4,
+ 0xb6, 0xf0, 0xe6, 0xb2, 0xe6, 0xb3, 0xcb, 0xef, 0xa1, 0xf5, 0xd4, 0xd7, 0xba,
+ 0xa6, 0xbc, 0xd2, 0xd1, 0xe7, 0xb9, 0xac, 0xcf, 0xfc, 0xc8, 0xdd, 0xe5, 0xb7,
+ 0xc9, 0xe4, 0xd0, 0xbc, 0xd5, 0xb9, 0xe5, 0xec, 0xc7, 0xcd, 0xcf, 0xbf, 0xbe,
+ 0xfe, 0xd3, 0xf8, 0xb6, 0xeb, 0xb7, 0xe5, 0xb5, 0xba, 0xa1, 0xf5, 0xe1, 0xad,
+ 0xb2, 0xee, 0xcf, 0xaf, 0xca, 0xa6, 0xbf, 0xe2, 0xcd, 0xa5, 0xd7, 0xf9, 0xc8,
+ 0xf5, 0xcd, 0xbd, 0xbe, 0xb6, 0xd0, 0xec, 0xed, 0xa6, 0xed, 0xa7, 0xb3, 0xdc,
+ 0xbf, 0xd6, 0xcb, 0xa1, 0xb9, 0xa7, 0xb6, 0xf7, 0xcf, 0xa2, 0xc7, 0xc4, 0xce,
+ 0xf2, 0xe3, 0xa4, 0xba, 0xb7, 0xbb, 0xda, 0xe3, 0xa9, 0xd4, 0xc3, 0xe3, 0xa3,
+ 0xc9, 0xc8, 0xc8, 0xad, 0xea, 0xfc, 0xc4, 0xc3, 0xc9, 0xd3, 0xd0, 0xae, 0xd5,
+ 0xf1, 0xb2, 0xb6, 0xce, 0xe6, 0xc0, 0xa6, 0xc4, 0xf3, 0xd7, 0xbd, 0xcd, 0xa6,
+ 0xbe, 0xe8, 0xcd, 0xec, 0xc5, 0xb2, 0xb4, 0xec, 0xb0, 0xa4, 0xba, 0xb4, 0xb0,
+ 0xc6, 0xd0, 0xa7, 0xf4, 0xcd, 0xc1, 0xcf, 0xc5, 0xd4, 0xc2, 0xc3, 0xca, 0xb1,
+ 0xbd, 0xfa, 0xea, 0xcc, 0xbb, 0xce, 0xc9, 0xb9, 0xc9, 0xce, 0xa1, 0xf5, 0xea,
+ 0xcb, 0xca, 0xe9, 0xcb, 0xb7, 0xeb, 0xde, 0xc0, 0xca, 0xd0, 0xa3, 0xba, 0xcb,
+ 0xb0, 0xb8, 0xbf, 0xf2, 0xbb, 0xb8, 0xb8, 0xf9, 0xb9, 0xf0, 0xbd, 0xdb, 0xe8,
+ 0xf2, 0xca, 0xe1, 0xc0, 0xf5, 0xd7, 0xc0, 0xc9, 0xa3, 0xd4, 0xd4, 0xb2, 0xf1,
+ 0xcd, 0xa9, 0xe8, 0xee, 0xb8, 0xf1, 0xcc, 0xd2, 0xd6, 0xea, 0xce, 0xa6, 0xcb,
+ 0xa8, 0xa1, 0xf5, 0xe8, 0xec, 0xca, 0xe2, 0xd1, 0xb3, 0xd2, 0xf3, 0xc6, 0xf8,
+ 0xd1, 0xf5, 0xb0, 0xb1, 0xba, 0xa4, 0xeb, 0xb3, 0xcc, 0xa9, 0xc0, 0xcb, 0xcc,
+ 0xe9, 0xcf, 0xfb, 0xe3, 0xfe, 0xc6, 0xd6, 0xbd, 0xfe, 0xba, 0xa3, 0xd5, 0xe3,
+ 0xe4, 0xb8, 0xc0, 0xef, 0xc9, 0xe6, 0xb8, 0xa1, 0xbf, 0xa3, 0xd4, 0xa1, 0xba,
+ 0xc6, 0xd3, 0xbf, 0xa1, 0xf5, 0xe4, 0xa4, 0xc4, 0xf9, 0xa1, 0xf5, 0xe4, 0xb9,
+ 0xec, 0xc8, 0xba, 0xe6, 0xbf, 0xbe, 0xc0, 0xd3, 0xc1, 0xd2, 0xce, 0xda, 0xb5,
+ 0xf9, 0xcc, 0xd8, 0xc0, 0xc7, 0xcf, 0xc1, 0xb1, 0xb7, 0xc0, 0xea, 0xe1, 0xfa,
+ 0xd7, 0xc8, 0xb0, 0xe0, 0xc1, 0xf0, 0xc5, 0xe5, 0xd6, 0xe9, 0xb9, 0xe7, 0xe7,
+ 0xf3, 0xc5, 0xcf, 0xc4, 0xb6, 0xd0, 0xf3, 0xdb, 0xce, 0xc1, 0xf4, 0xbc, 0xb2,
+ 0xb2, 0xa1, 0xd6, 0xa2, 0xc6, 0xa3, 0xf0, 0xe1, 0xbe, 0xd2, 0xcc, 0xdb, 0xd5,
+ 0xee, 0xf0, 0xe8, 0xf0, 0xe3, 0xb8, 0xde, 0xf0, 0xe5, 0xd2, 0xe6, 0xee, 0xc1,
+ 0xb0, 0xbb, 0xd1, 0xa3, 0xd5, 0xe6, 0xc3, 0xdf, 0xd5, 0xa3, 0xbe, 0xd8, 0xc5,
+ 0xe9, 0xd5, 0xe8, 0xd4, 0xd2, 0xed, 0xc0, 0xc6, 0xc6, 0xc9, 0xe9, 0xed, 0xc6,
+ 0xed, 0xbe, 0xa1, 0xf5, 0xed, 0xc4, 0xc5, 0xda, 0xc3, 0xd8, 0xd3, 0xd3, 0xec,
+ 0xf4, 0xcb, 0xee, 0xd7, 0xe6, 0xc9, 0xf1, 0xd7, 0xa3, 0xec, 0xf3, 0xec, 0xf1,
+ 0xb3, 0xd3, 0xef, 0xf7, 0xd1, 0xed, 0xd7, 0xe2, 0xc7, 0xd8, 0xd6, 0xc8, 0xc3,
+ 0xd8, 0xd5, 0xad, 0xf1, 0xba, 0xd5, 0xbe, 0xb0, 0xca, 0xd0, 0xa6, 0xb7, 0xdb,
+ 0xb7, 0xc4, 0xc9, 0xb4, 0xce, 0xc6, 0xce, 0xc9, 0xcb, 0xd8, 0xcb, 0xf7, 0xb4,
+ 0xbf, 0xc5, 0xa6, 0xe7, 0xa2, 0xbc, 0xb6, 0xe7, 0xa1, 0xc4, 0xc9, 0xd6, 0xbd,
+ 0xb7, 0xd7, 0xc8, 0xb1, 0xee, 0xb9, 0xb8, 0xe1, 0xb3, 0xe1, 0xce, 0xcc, 0xea,
+ 0xc8, 0xd4, 0xc5, 0xb8, 0xfb, 0xb0, 0xd2, 0xba, 0xc4, 0xb5, 0xa2, 0xb9, 0xa2,
+ 0xeb, 0xd7, 0xd6, 0xac, 0xd2, 0xc8, 0xd0, 0xb2, 0xeb, 0xd9, 0xeb, 0xd8, 0xb4,
+ 0xe0, 0xd0, 0xd8, 0xb8, 0xec, 0xc2, 0xf6, 0xc4, 0xdc, 0xbc, 0xb9, 0xeb, 0xdd,
+ 0xbf, 0xe8, 0xb3, 0xf4, 0xf4, 0xab, 0xd2, 0xa8, 0xf3, 0xc2, 0xba, 0xbd, 0xf4,
+ 0xb3, 0xf4, 0xb2, 0xb0, 0xe3, 0xdb, 0xbb, 0xc3, 0xa3, 0xbb, 0xc4, 0xc0, 0xf3,
+ 0xbe, 0xa3, 0xc8, 0xd7, 0xbc, 0xf6, 0xb2, 0xdd, 0xd2, 0xf0, 0xdc, 0xee, 0xdc,
+ 0xf3, 0xd7, 0xc8, 0xc8, 0xe3, 0xb2, 0xe8, 0xdc, 0xf8, 0xdc, 0xf7, 0xdc, 0xef,
+ 0xb4, 0xc4, 0xdc, 0xf5, 0xf2, 0xaf, 0xce, 0xc3, 0xf2, 0xbd, 0xf2, 0xbe, 0xd4,
+ 0xe9, 0xf2, 0xbf, 0xb0, 0xf6, 0xf2, 0xbc, 0xd1, 0xc1, 0xcb, 0xa5, 0xd6, 0xd4,
+ 0xd4, 0xac, 0xf1, 0xc7, 0xf1, 0xc5, 0xd6, 0xbb, 0xbc, 0xc7, 0xda, 0xa6, 0xcc,
+ 0xd6, 0xda, 0xa7, 0xda, 0xa8, 0xd1, 0xb6, 0xcd, 0xd0, 0xd1, 0xb5, 0xc6, 0xfd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xc6, 0xf1, 0xb2, 0xf2, 0xb1, 0xaa, 0xb2, 0xc6, 0xb9,
+ 0xb1, 0xc6, 0xf0, 0xb9, 0xaa, 0xd0, 0xf9, 0xe9, 0xed, 0xa1, 0xf5, 0xc8, 0xe8,
+ 0xcb, 0xcd, 0xc4, 0xe6, 0xc3, 0xd4, 0xcd, 0xcb, 0xc4, 0xcb, 0xbb, 0xd8, 0xcc,
+ 0xd3, 0xd7, 0xb7, 0xe5, 0xcb, 0xb1, 0xc5, 0xe7, 0xdf, 0xbf, 0xa4, 0xba, 0xc2,
+ 0xdb, 0xab, 0xbe, 0xc6, 0xc5, 0xe4, 0xd7, 0xc3, 0xb6, 0xa4, 0xd5, 0xeb, 0xee,
+ 0xc8, 0xb8, 0xaa, 0xee, 0xc7, 0xc9, 0xc1, 0xd4, 0xba, 0xd5, 0xf3, 0xb6, 0xb8,
+ 0xb1, 0xdd, 0xc9, 0xc2, 0xb3, 0xfd, 0xda, 0xea, 0xc9, 0xfd, 0xd6, 0xbb, 0xbc,
+ 0xa2, 0xc2, 0xed, 0xb9, 0xc7, 0xb8, 0xdf, 0xb6, 0xb7, 0xd8, 0xaa, 0xb9, 0xed,
+ 0xc7, 0xac, 0xa1, 0xf5, 0xce, 0xb1, 0xcd, 0xa3, 0xbc, 0xd9, 0xd9, 0xc8, 0xd9,
+ 0xbc, 0xd7, 0xf6, 0xce, 0xb0, 0xbd, 0xa1, 0xc5, 0xbc, 0xd9, 0xcb, 0xd9, 0xc9,
+ 0xd5, 0xec, 0xb2, 0xe0, 0xcd, 0xb5, 0xc6, 0xab, 0xd9, 0xbf, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb6, 0xb5, 0xc3, 0xe1, 0xbb, 0xcb, 0xbc, 0xf4, 0xb8, 0xb1, 0xc0, 0xd5,
+ 0xce, 0xf1, 0xbf, 0xb1, 0xb6, 0xaf, 0xd9, 0xeb, 0xde, 0xcb, 0xb3, 0xd7, 0xc4,
+ 0xe4, 0xc7, 0xf8, 0xd8, 0xd2, 0xb2, 0xce, 0xc2, 0xfc, 0xc9, 0xcc, 0xc5, 0xbe,
+ 0xc0, 0xb2, 0xd7, 0xc4, 0xd1, 0xc6, 0xb7, 0xc8, 0xbf, 0xd0, 0xb0, 0xa1, 0xb3,
+ 0xaa, 0xe0, 0xa2, 0xce, 0xca, 0xdf, 0xfb, 0xce, 0xa8, 0xc6, 0xa1, 0xc4, 0xee,
+ 0xca, 0xdb, 0xe0, 0xa8, 0xbb, 0xa3, 0xcf, 0xce, 0xe0, 0xa6, 0xdf, 0xfa, 0xa1,
+ 0xf5, 0xc8, 0xa6, 0xb9, 0xfa, 0xe0, 0xf6, 0xd3, 0xf2, 0xbc, 0xe1, 0xdb, 0xd1,
+ 0xb6, 0xd1, 0xb2, 0xba, 0xdb, 0xfd, 0xbb, 0xf9, 0xcc, 0xc3, 0xb6, 0xc2, 0xd6,
+ 0xb4, 0xc5, 0xe0, 0xb9, 0xbb, 0xc9, 0xdd, 0xc8, 0xa2, 0xc2, 0xa6, 0xcd, 0xf1,
+ 0xb8, 0xbe, 0xc0, 0xb7, 0xe6, 0xb9, 0xe6, 0xbd, 0xe6, 0xbe, 0xbb, 0xe9, 0xc6,
+ 0xc5, 0xe6, 0xbb, 0xca, 0xeb, 0xbf, 0xdc, 0xd2, 0xfa, 0xbc, 0xc4, 0xbc, 0xc5,
+ 0xcb, 0xde, 0xc3, 0xdc, 0xce, 0xbe, 0xd7, 0xa8, 0xbd, 0xab, 0xcd, 0xc0, 0xcc,
+ 0xeb, 0xa1, 0xf5, 0xb3, 0xe7, 0xe1, 0xc7, 0xc6, 0xe9, 0xe1, 0xc8, 0xd1, 0xc2,
+ 0xe1, 0xbf, 0xc0, 0xa5, 0xb1, 0xc0, 0xb4, 0xde, 0xc2, 0xd8, 0xe1, 0xc5, 0xe1,
+ 0xc2, 0xb8, 0xda, 0xb3, 0xb2, 0xb3, 0xa3, 0xb4, 0xf8, 0xd5, 0xca, 0xe1, 0xa1,
+ 0xbf, 0xb5, 0xd3, 0xb9, 0xca, 0xfc, 0xe2, 0xd6, 0xe2, 0xd7, 0xd5, 0xc5, 0xc7,
+ 0xbf, 0xe5, 0xe7, 0xb1, 0xf2, 0xb2, 0xca, 0xb5, 0xf1, 0xb5, 0xc3, 0xe1, 0xe3,
+ 0xb4, 0xd3, 0xc5, 0xc7, 0xd3, 0xf9, 0xe1, 0xe2, 0xe1, 0xe4, 0xd3, 0xc1, 0xbb,
+ 0xbc, 0xcf, 0xa4, 0xd3, 0xc6, 0xc4, 0xfa, 0xcd, 0xef, 0xe3, 0xb2, 0xb5, 0xeb,
+ 0xc6, 0xe0, 0xc7, 0xe9, 0xe3, 0xac, 0xe2, 0xea, 0xcf, 0xa7, 0xb5, 0xbf, 0xe3,
+ 0xaf, 0xcc, 0xe8, 0xe3, 0xb0, 0xce, 0xa9, 0xbc, 0xc2, 0xe3, 0xb1, 0xb6, 0xd8,
+ 0xc6, 0xdd, 0xea, 0xa9, 0xec, 0xe8, 0xc2, 0xd3, 0xbf, 0xd8, 0xbe, 0xed, 0xd2,
+ 0xb4, 0xcc, 0xbd, 0xbd, 0xd3, 0xbd, 0xdd, 0xc5, 0xf5, 0xbe, 0xf2, 0xb4, 0xeb,
+ 0xde, 0xdf, 0xd1, 0xda, 0xb5, 0xf4, 0xc9, 0xa8, 0xb9, 0xd2, 0xde, 0xd1, 0xcd,
+ 0xc6, 0xc2, 0xd5, 0xca, 0xda, 0xd5, 0xf5, 0xb2, 0xc9, 0xde, 0xe4, 0xc5, 0xc5,
+ 0xcc, 0xcd, 0xcf, 0xc6, 0xc4, 0xed, 0xde, 0xe6, 0xc9, 0xe1, 0xde, 0xe0, 0xb1,
+ 0xd6, 0xb0, 0xbd, 0xbe, 0xc8, 0xbd, 0xcc, 0xb0, 0xdc, 0xc6, 0xf4, 0xc3, 0xf4,
+ 0xd0, 0xf0, 0xeb, 0xb7, 0xa1, 0xf5, 0xd0, 0xb1, 0xf5, 0xfa, 0xd5, 0xb6, 0xd7,
+ 0xe5, 0xd0, 0xfd, 0xec, 0xba, 0xec, 0xbb, 0xd6, 0xe7, 0xcd, 0xed, 0xce, 0xee,
+ 0xb3, 0xbf, 0xbb, 0xde, 0xa1, 0xf5, 0xb2, 0xdc, 0xa1, 0xf5, 0xcd, 0xfb, 0xc1,
+ 0xba, 0xcc, 0xdd, 0xc9, 0xd2, 0xe8, 0xf7, 0xe8, 0xf3, 0xb8, 0xcb, 0xcd, 0xb0,
+ 0xc0, 0xa6, 0xce, 0xe0, 0xb9, 0xa3, 0xd0, 0xb5, 0xe8, 0xe8, 0xc6, 0xfa, 0xcb,
+ 0xf3, 0xb0, 0xf0, 0xc3, 0xb7, 0xe8, 0xd9, 0xcc, 0xf5, 0xc0, 0xe6, 0xe8, 0xc9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xd3, 0xfb, 0xc9, 0xb1, 0xba, 0xc1, 0xc7, 0xf2, 0xc7,
+ 0xe2, 0xcf, 0xd1, 0xc1, 0xb9, 0xb4, 0xbe, 0xe4, 0xc8, 0xd2, 0xba, 0xb5, 0xad,
+ 0xcc, 0xca, 0xd3, 0xd9, 0xcc, 0xed, 0xc7, 0xb3, 0xc7, 0xe5, 0xe4, 0xbf, 0xc1,
+ 0xdc, 0xd1, 0xc4, 0xca, 0xe7, 0xe4, 0xcc, 0xe4, 0xc1, 0xd1, 0xcd, 0xba, 0xd4,
+ 0xbb, 0xec, 0xd4, 0xa8, 0xe4, 0xc0, 0xc6, 0xe0, 0xe4, 0xbe, 0xba, 0xad, 0xc0,
+ 0xe1, 0xd2, 0xf9, 0xcc, 0xd4, 0xc2, 0xd9, 0xc9, 0xee, 0xbb, 0xb4, 0xbe, 0xbb,
+ 0xcf, 0xfd, 0xd7, 0xcd, 0xb8, 0xa2, 0xb4, 0xe3, 0xe4, 0xc3, 0xe4, 0xc6, 0xc5,
+ 0xeb, 0xd1, 0xc9, 0xba, 0xb8, 0xb7, 0xe9, 0xcf, 0xa9, 0xcb, 0xac, 0xc7, 0xa3,
+ 0xc0, 0xe7, 0xb2, 0xc2, 0xc3, 0xcd, 0xb2, 0xfe, 0xe2, 0xa3, 0xd5, 0xf8, 0xc2,
+ 0xca, 0xc0, 0xc5, 0xe7, 0xf0, 0xc7, 0xf2, 0xc0, 0xed, 0xcf, 0xd6, 0xa1, 0xf5,
+ 0xf0, 0xad, 0xc6, 0xbf, 0xb4, 0xc9, 0xcc, 0xf0, 0xb2, 0xfa, 0xc2, 0xd4, 0xc6,
+ 0xe8, 0xb1, 0xcf, 0xd2, 0xec, 0xca, 0xe8, 0xd6, 0xcc, 0xba, 0xdb, 0xb4, 0xc3,
+ 0xc8, 0xac, 0xf0, 0xea, 0xf0, 0xa8, 0xbf, 0xf8, 0xba, 0xd0, 0xca, 0xa2, 0xbe,
+ 0xec, 0xd6, 0xda, 0xd1, 0xdb, 0xbf, 0xf4, 0xed, 0xf8, 0xcc, 0xf7, 0xc1, 0xf2,
+ 0xd6, 0xec, 0xed, 0xca, 0xcf, 0xe9, 0xc6, 0xb1, 0xbc, 0xc0, 0xd2, 0xc6, 0xd6,
+ 0xcf, 0xf1, 0xbb, 0xf3, 0xd2, 0xb1, 0xbf, 0xb5, 0xd1, 0xb5, 0xda, 0xb7, 0xfb,
+ 0xf3, 0xcf, 0xf3, 0xd7, 0xf3, 0xd0, 0xc1, 0xa3, 0xb4, 0xd6, 0xc6, 0xc9, 0xb0,
+ 0xed, 0xcf, 0xd2, 0xcd, 0xb3, 0xd4, 0xfa, 0xc9, 0xdc, 0xe7, 0xa8, 0xe7, 0xa9,
+ 0xcf, 0xb8, 0xc9, 0xf0, 0xd7, 0xe9, 0xc0, 0xdb, 0xd6, 0xd5, 0xe7, 0xa5, 0xe7,
+ 0xa6, 0xb2, 0xa7, 0xd0, 0xdf, 0xc1, 0xe7, 0xd2, 0xee, 0xf4, 0xe1, 0xcf, 0xb0,
+ 0xf1, 0xea, 0xc1, 0xc4, 0xf1, 0xf6, 0xb8, 0xac, 0xb2, 0xb1, 0xb4, 0xbd, 0xcd,
+ 0xd1, 0xd0, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xa9, 0xb6, 0xe6, 0xcf, 0xcf,
+ 0xb2, 0xb0, 0xb4, 0xac, 0xc9, 0xaf, 0xdd, 0xb8, 0xdd, 0xb7, 0xdd, 0xa9, 0xbc,
+ 0xd4, 0xbe, 0xa5, 0xc3, 0xa7, 0xc4, 0xaa, 0xdc, 0xec, 0xd7, 0xaf, 0xdd, 0xae,
+ 0xc0, 0xf2, 0xdd, 0xac, 0xba, 0xc9, 0xdd, 0xb6, 0xdd, 0xb1, 0xc6, 0xce, 0xdc,
+ 0xc8, 0xb4, 0xa6, 0xb1, 0xeb, 0xc9, 0xdf, 0xd6, 0xfb, 0xf2, 0xc0, 0xf2, 0xc1,
+ 0xf2, 0xc2, 0xc7, 0xf9, 0xb5, 0xb0, 0xf2, 0xc6, 0xf2, 0xc7, 0xf2, 0xc8, 0xca,
+ 0xf5, 0xd9, 0xf2, 0xf4, 0xc2, 0xb1, 0xbb, 0xcc, 0xbb, 0xd0, 0xe4, 0xc5, 0xdb,
+ 0xb4, 0xfc, 0xc3, 0xd9, 0xb9, 0xe6, 0xb7, 0xc3, 0xd1, 0xc8, 0xbe, 0xf7, 0xda,
+ 0xab, 0xd0, 0xed, 0xc9, 0xe8, 0xcb, 0xcf, 0xb6, 0xef, 0xd0, 0xc0, 0xf4, 0xf9,
+ 0xeb, 0xe0, 0xb7, 0xb7, 0xd4, 0xf0, 0xb9, 0xe1, 0xbb, 0xf5, 0xcc, 0xb0, 0xc6,
+ 0xb6, 0xf4, 0xf6, 0xc9, 0xe2, 0xd6, 0xba, 0xf5, 0xc3, 0xe9, 0xee, 0xc8, 0xed,
+ 0xd5, 0xe2, 0xe5, 0xd0, 0xcd, 0xa8, 0xb6, 0xba, 0xc1, 0xac, 0xcb, 0xd9, 0xca,
+ 0xc5, 0xd6, 0xf0, 0xe5, 0xc9, 0xb3, 0xd1, 0xd4, 0xec, 0xcd, 0xb8, 0xb7, 0xea,
+ 0xe5, 0xd1, 0xb9, 0xe4, 0xcd, 0xbe, 0xb2, 0xbf, 0xb9, 0xf9, 0xb6, 0xbc, 0xd0,
+ 0xef, 0xd2, 0xb0, 0xee, 0xce, 0xbf, 0xdb, 0xb5, 0xf6, 0xee, 0xcb, 0xa1, 0xf5,
+ 0xb7, 0xb0, 0xb1, 0xd5, 0xc5, 0xe3, 0xc1, 0xea, 0xb3, 0xc2, 0xc2, 0xbd, 0xd2,
+ 0xf5, 0xda, 0xf0, 0xcc, 0xd5, 0xcf, 0xdd, 0xda, 0xee, 0xc8, 0xb8, 0xd1, 0xa9,
+ 0xf6, 0xa7, 0xd5, 0xc2, 0xbe, 0xb9, 0xb6, 0xa5, 0xc7, 0xea, 0xd3, 0xe3, 0xc4,
+ 0xf1, 0xc2, 0xb1, 0xc2, 0xb9, 0xc2, 0xf3, 0xc2, 0xe9, 0xbc, 0xd2, 0xb0, 0xf8,
+ 0xb8, 0xb5, 0xb1, 0xb8, 0xbd, 0xdc, 0xbf, 0xfe, 0xd8, 0xf7, 0xc9, 0xa1, 0xd0,
+ 0xa7, 0xd7, 0xee, 0xbf, 0xad, 0xb8, 0xee, 0xd8, 0xdc, 0xb4, 0xb4, 0xca, 0xa3,
+ 0xc0, 0xcd, 0xca, 0xa4, 0xd1, 0xab, 0xb2, 0xa9, 0xd8, 0xca, 0xe0, 0xb4, 0xbf,
+ 0xa6, 0xd0, 0xfa, 0xcc, 0xe4, 0xba, 0xb0, 0xba, 0xc8, 0xb4, 0xad, 0xce, 0xb9,
+ 0xcf, 0xb2, 0xc9, 0xa5, 0xe0, 0xb8, 0xc0, 0xae, 0xe0, 0xa9, 0xe0, 0xab, 0xd4,
+ 0xfb, 0xb5, 0xa5, 0xe0, 0xb0, 0xcd, 0xd9, 0xd3, 0xb4, 0xbb, 0xbd, 0xd3, 0xf7,
+ 0xc7, 0xc7, 0xe0, 0xac, 0xe0, 0xb1, 0xba, 0xed, 0xa1, 0xf5, 0xe0, 0xb9, 0xce,
+ 0xa7, 0xd2, 0xa2, 0xbf, 0xb0, 0xb3, 0xa1, 0xb5, 0xcc, 0xd1, 0xdf, 0xb1, 0xa8,
+ 0xb1, 0xa4, 0xdb, 0xf6, 0xdc, 0xa9, 0xd2, 0xbc, 0xba, 0xf8, 0xb5, 0xec, 0xe6,
+ 0xc3, 0xc3, 0xc4, 0xd0, 0xf6, 0xc3, 0xbd, 0xe6, 0xc2, 0xe6, 0xb4, 0xe6, 0xdc,
+ 0xe5, 0xee, 0xba, 0xae, 0xb8, 0xbb, 0xd4, 0xa2, 0xc3, 0xc2, 0xd7, 0xf0, 0xd1,
+ 0xb0, 0xbe, 0xcd, 0xc7, 0xb6, 0xe1, 0xb0, 0xe1, 0xcb, 0xef, 0xfa, 0xd9, 0xe3,
+ 0xb7, 0xf9, 0xc3, 0xb1, 0xd6, 0xa1, 0xe0, 0xf8, 0xbc, 0xb8, 0xc0, 0xc8, 0xb2,
+ 0xde, 0xcf, 0xe1, 0xbe, 0xc7, 0xe5, 0xf6, 0xc5, 0xed, 0xb8, 0xb4, 0xd1, 0xad,
+ 0xe1, 0xe5, 0xbb, 0xf3, 0xb6, 0xf1, 0xb1, 0xaf, 0xc3, 0xc6, 0xbb, 0xdd, 0xe3,
+ 0xab, 0xe3, 0xb6, 0xd0, 0xca, 0xe3, 0xb5, 0xb6, 0xe8, 0xe2, 0xfc, 0xe3, 0xb7,
+ 0xbf, 0xae, 0xc4, 0xd5, 0xe3, 0xb9, 0xbb, 0xcc, 0xd3, 0xe4, 0xe3, 0xb8, 0xa1,
+ 0xf5, 0xea, 0xaa, 0xec, 0xe9, 0xb3, 0xb8, 0xd5, 0xc6, 0xc3, 0xe8, 0xbc, 0xf0,
+ 0xbf, 0xab, 0xc8, 0xe0, 0xde, 0xf1, 0xd7, 0xe1, 0xb2, 0xe5, 0xb4, 0xa7, 0xcc,
+ 0xe1, 0xce, 0xd5, 0xd2, 0xbe, 0xbd, 0xd2, 0xbb, 0xd3, 0xb4, 0xb7, 0xd4, 0xae,
+ 0xbe, 0xbe, 0xbb, 0xbb, 0xde, 0xf0, 0xd1, 0xef, 0xb1, 0xb3, 0xb3, 0xa8, 0xb6,
+ 0xd8, 0xb8, 0xd2, 0xc9, 0xa2, 0xb0, 0xdf, 0xec, 0xb3, 0xcb, 0xb9, 0xc6, 0xd5,
+ 0xce, 0xfa, 0xc7, 0xe7, 0xbe, 0xa7, 0xbe, 0xb0, 0xca, 0xee, 0xd6, 0xc7, 0xc1,
+ 0xc0, 0xea, 0xd0, 0xd4, 0xf8, 0xcc, 0xe6, 0xc6, 0xda, 0xb3, 0xaf, 0xb9, 0xd7,
+ 0xd7, 0xd8, 0xcc, 0xc4, 0xbc, 0xac, 0xd4, 0xe6, 0xd2, 0xce, 0xb6, 0xb0, 0xbf,
+ 0xc3, 0xc9, 0xad, 0xd5, 0xbb, 0xe8, 0xfe, 0xb0, 0xf4, 0xc6, 0xdc, 0xe9, 0xa6,
+ 0xc6, 0xe5, 0xb9, 0xf7, 0xd6, 0xb2, 0xbd, 0xb7, 0xd7, 0xb5, 0xc3, 0xde, 0xc5,
+ 0xef, 0xe8, 0xfa, 0xa1, 0xf5, 0xbf, 0xee, 0xc6, 0xdb, 0xc7, 0xd5, 0xb2, 0xd0,
+ 0xd6, 0xb3, 0xbf, 0xc7, 0xcc, 0xba, 0xb5, 0xaa, 0xc2, 0xc8, 0xeb, 0xb2, 0xb8,
+ 0xdb, 0xd3, 0xce, 0xe4, 0xd5, 0xb6, 0xc9, 0xe4, 0xd6, 0xd3, 0xbf, 0xb4, 0xd5,
+ 0xc7, 0xfe, 0xe4, 0xd7, 0xd4, 0xfc, 0xbc, 0xf5, 0xd5, 0xbf, 0xcf, 0xe6, 0xb2,
+ 0xb3, 0xba, 0xfe, 0xe4, 0xce, 0xce, 0xbc, 0xce, 0xd0, 0xcc, 0xc0, 0xbf, 0xca,
+ 0xcd, 0xc4, 0xc3, 0xec, 0xb2, 0xe2, 0xc5, 0xc8, 0xd3, 0xe5, 0xbb, 0xeb, 0xd7,
+ 0xcc, 0xb8, 0xc8, 0xbb, 0xc1, 0xe4, 0xcf, 0xe3, 0xfd, 0xe4, 0xd8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe4, 0xd2, 0xb1, 0xba, 0xb7, 0xd9, 0xbd, 0xb9, 0xd1, 0xe6, 0xce,
+ 0xde, 0xc8, 0xbb, 0xd6, 0xf3, 0xa1, 0xf5, 0xc5, 0xc6, 0xea, 0xf7, 0xcf, 0xac,
+ 0xd3, 0xcc, 0xe2, 0xab, 0xba, 0xef, 0xd0, 0xc9, 0xb7, 0xa9, 0xe7, 0xf7, 0xc1,
+ 0xd5, 0xd7, 0xc1, 0xe7, 0xfa, 0xc5, 0xfd, 0xc5, 0xc3, 0xc7, 0xd9, 0xa1, 0xf5,
+ 0xe8, 0xa1, 0xe7, 0xf9, 0xe7, 0xfb, 0xc9, 0xfb, 0xcb, 0xd5, 0xbb, 0xad, 0xb7,
+ 0xac, 0xc1, 0xa1, 0xcd, 0xb4, 0xf0, 0xeb, 0xbe, 0xb7, 0xb6, 0xbb, 0xc6, 0xa6,
+ 0xa1, 0xf5, 0xb5, 0xc7, 0xb7, 0xa2, 0xcd, 0xee, 0xf0, 0xa9, 0xf1, 0xe5, 0xb5,
+ 0xc1, 0xc0, 0xa7, 0xb6, 0xcc, 0xcf, 0xf5, 0xd3, 0xb2, 0xd1, 0xe2, 0xc9, 0xd4,
+ 0xb8, 0xd1, 0xb3, 0xcc, 0xcb, 0xb0, 0xcf, 0xa1, 0xbe, 0xbd, 0xb4, 0xb0, 0xbd,
+ 0xd1, 0xcd, 0xaf, 0xbf, 0xa2, 0xb5, 0xc8, 0xb2, 0xdf, 0xb1, 0xca, 0xbf, 0xf0,
+ 0xcd, 0xb2, 0xb4, 0xf0, 0xcb, 0xf1, 0xbd, 0xee, 0xb7, 0xa4, 0xd6, 0xfe, 0xcb,
+ 0xda, 0xd6, 0xe0, 0xbd, 0xca, 0xbd, 0xe1, 0xc8, 0xde, 0xbe, 0xf8, 0xd7, 0xcf,
+ 0xd0, 0xf5, 0xcb, 0xbf, 0xc2, 0xe7, 0xb8, 0xf8, 0xd1, 0xa4, 0xa1, 0xf5, 0xe7,
+ 0xad, 0xc9, 0xc6, 0xcf, 0xe8, 0xf4, 0xe2, 0xf1, 0xf3, 0xf1, 0xf8, 0xcb, 0xe0,
+ 0xcd, 0xf3, 0xc7, 0xbb, 0xd2, 0xb8, 0xb8, 0xad, 0xc9, 0xf6, 0xd5, 0xcd, 0xcc,
+ 0xf3, 0xc6, 0xa2, 0xeb, 0xe7, 0xeb, 0xe8, 0xeb, 0xe9, 0xca, 0xe6, 0xcb, 0xb4,
+ 0xc6, 0xd0, 0xdd, 0xcd, 0xdd, 0xce, 0xc6, 0xbc, 0xb2, 0xa4, 0xdd, 0xd1, 0xdd,
+ 0xc2, 0xdd, 0xbc, 0xbb, 0xaa, 0xc1, 0xe2, 0xa1, 0xf5, 0xd6, 0xf8, 0xc0, 0xb3,
+ 0xdd, 0xd4, 0xc3, 0xc8, 0xbe, 0xfa, 0xdd, 0xc4, 0xb7, 0xc6, 0xbe, 0xd5, 0xdd,
+ 0xc7, 0xce, 0xae, 0xcc, 0xd1, 0xb2, 0xcb, 0xdc, 0xc9, 0xdd, 0xca, 0xdd, 0xcb,
+ 0xd0, 0xe9, 0xf2, 0xd4, 0xcd, 0xdc, 0xf2, 0xce, 0xbb, 0xd7, 0xd6, 0xeb, 0xb8,
+ 0xf2, 0xf2, 0xd0, 0xf2, 0xd2, 0xbd, 0xd6, 0xb2, 0xc3, 0xc1, 0xd1, 0xb8, 0xa4,
+ 0xf1, 0xfb, 0xca, 0xd3, 0xd7, 0xa2, 0xd3, 0xbd, 0xc6, 0xc0, 0xb4, 0xca, 0xd6,
+ 0xa4, 0xda, 0xac, 0xda, 0xb0, 0xd7, 0xe7, 0xd5, 0xa9, 0xda, 0xae, 0xcb, 0xdf,
+ 0xd5, 0xef, 0xda, 0xad, 0xa1, 0xf5, 0xcf, 0xf3, 0xf5, 0xf5, 0xd6, 0xfc, 0xcc,
+ 0xf9, 0xb7, 0xa1, 0xea, 0xdd, 0xea, 0xda, 0xb7, 0xd1, 0xba, 0xd8, 0xb9, 0xf3,
+ 0xc2, 0xf2, 0xb1, 0xe1, 0xc3, 0xb3, 0xb4, 0xfb, 0xd4, 0xbd, 0xb3, 0xac, 0xb3,
+ 0xc3, 0xf5, 0xc9, 0xbe, 0xe0, 0xb0, 0xcf, 0xf5, 0xc7, 0xc5, 0xdc, 0xb5, 0xf8,
+ 0xf5, 0xcb, 0xf5, 0xcc, 0xe9, 0xf0, 0xd6, 0xe1, 0xe9, 0xf3, 0xb9, 0xbc, 0xb4,
+ 0xfe, 0xe5, 0xd3, 0xd6, 0xdc, 0xd2, 0xdd, 0xbd, 0xf8, 0xe5, 0xd4, 0xb6, 0xf5,
+ 0xd3, 0xca, 0xcf, 0xe7, 0xdb, 0xb1, 0xba, 0xa8, 0xcb, 0xd6, 0xc1, 0xbf, 0xb3,
+ 0xae, 0xc5, 0xa5, 0xb8, 0xc6, 0xc4, 0xc6, 0xbe, 0xfb, 0xb6, 0xdb, 0xee, 0xd4,
+ 0xa1, 0xf5, 0xee, 0xd3, 0xe3, 0xc9, 0xc8, 0xf2, 0xbf, 0xaa, 0xcf, 0xd0, 0xbc,
+ 0xe4, 0xcf, 0xd0, 0xe3, 0xc8, 0xb6, 0xd3, 0xbd, 0xd7, 0xcb, 0xe5, 0xd1, 0xf4,
+ 0xd3, 0xe7, 0xc2, 0xa1, 0xda, 0xf2, 0xda, 0xef, 0xb5, 0xcc, 0xd1, 0xe3, 0xd1,
+ 0xc5, 0xd0, 0xdb, 0xbc, 0xaf, 0xb9, 0xcd, 0xf6, 0xa9, 0xd4, 0xc6, 0xc8, 0xcd,
+ 0xcf, 0xee, 0xcb, 0xb3, 0xd0, 0xeb, 0xe2, 0xb8, 0xe2, 0xbf, 0xb7, 0xb9, 0xe2,
+ 0xbd, 0xd2, 0xfb, 0xe2, 0xc1, 0xb7, 0xeb, 0xd4, 0xa6, 0xbb, 0xc6, 0xca, 0xf2,
+ 0xba, 0xda, 0xc2, 0xd2, 0xd3, 0xb6, 0xd5, 0xae, 0xb0, 0xc1, 0xb4, 0xab, 0xbd,
+ 0xf6, 0xc7, 0xe3, 0xb4, 0xdf, 0xc9, 0xcb, 0xc9, 0xb5, 0xd9, 0xcc, 0xa1, 0xf5,
+ 0xbd, 0xcb, 0xb2, 0xf9, 0xd8, 0xe2, 0xc4, 0xbc, 0xbd, 0xcb, 0xc7, 0xda, 0xca,
+ 0xc6, 0xbc, 0xa8, 0xbb, 0xe3, 0xe0, 0xb5, 0xe0, 0xcb, 0xc9, 0xa4, 0xe0, 0xc2,
+ 0xc2, 0xf0, 0xca, 0xc8, 0xd8, 0xc4, 0xe0, 0xbe, 0xcb, 0xc3, 0xe0, 0xcd, 0xe0,
+ 0xc5, 0xce, 0xd8, 0xce, 0xcb, 0xd0, 0xe1, 0xc7, 0xba, 0xe0, 0xc6, 0xe0, 0xbc,
+ 0xd4, 0xb0, 0xd4, 0xb2, 0xc8, 0xfb, 0xcb, 0xdc, 0xcc, 0xc1, 0xcd, 0xbf, 0xda,
+ 0xa3, 0xcb, 0xfe, 0xcc, 0xee, 0xcb, 0xfa, 0xce, 0xc1, 0xbf, 0xe9, 0xce, 0xeb,
+ 0xdb, 0xf5, 0xdc, 0xe3, 0xb0, 0xc2, 0xbc, 0xde, 0xbc, 0xb5, 0xcf, 0xd3, 0xe6,
+ 0xc5, 0xc2, 0xe8, 0xe6, 0xc1, 0xcf, 0xb1, 0xc9, 0xa9, 0xe6, 0xc7, 0xe1, 0xd4,
+ 0xe1, 0xcf, 0xbb, 0xcf, 0xb8, 0xc9, 0xc1, 0xae, 0xcf, 0xc3, 0xdf, 0xb1, 0xbb,
+ 0xe3, 0xc5, 0xd4, 0xce, 0xa2, 0xd3, 0xde, 0xd2, 0xe2, 0xb4, 0xc8, 0xb8, 0xd0,
+ 0xcf, 0xeb, 0xb0, 0xae, 0xc8, 0xc7, 0xb3, 0xee, 0xd3, 0xfa, 0xc9, 0xf7, 0xbb,
+ 0xc5, 0xc0, 0xf5, 0xe3, 0xb3, 0xe2, 0xe9, 0xe2, 0xeb, 0xc0, 0xa2, 0xed, 0xaa,
+ 0xed, 0xa9, 0xe2, 0xfd, 0xea, 0xac, 0xea, 0xab, 0xb4, 0xea, 0xd5, 0xa5, 0xb8,
+ 0xe3, 0xcc, 0xc2, 0xb4, 0xee, 0xb2, 0xeb, 0xb0, 0xe1, 0xb2, 0xab, 0xcb, 0xd1,
+ 0xc9, 0xa6, 0xcb, 0xf0, 0xc7, 0xc0, 0xd2, 0xa1, 0xb5, 0xb7, 0xb9, 0xb9, 0xbe,
+ 0xb4, 0xd5, 0xe5, 0xd0, 0xc2, 0xb0, 0xb5, 0xea, 0xcd, 0xcf, 0xbe, 0xd4, 0xce,
+ 0xc5, 0xaf, 0xea, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xbb, 0xe1, 0xc0, 0xc6, 0xd2,
+ 0xb5, 0xb3, 0xfe, 0xbf, 0xac, 0xe9, 0xaa, 0xd0, 0xa8, 0xbc, 0xab, 0xd2, 0xac,
+ 0xb8, 0xc5, 0xd1, 0xee, 0xe8, 0xe5, 0xe9, 0xae, 0xc0, 0xe3, 0xb7, 0xe3, 0xe9,
+ 0xba, 0xd3, 0xdc, 0xe9, 0xac, 0xe9, 0xb9, 0xa1, 0xf5, 0xd0, 0xaa, 0xcb, 0xea,
+ 0xbb, 0xd9, 0xb5, 0xee, 0xd8, 0xb9, 0xeb, 0xa6, 0xd2, 0xe7, 0xcb, 0xdd, 0xd7,
+ 0xd2, 0xc8, 0xdc, 0xe4, 0xe8, 0xd4, 0xb4, 0xb9, 0xb5, 0xb5, 0xe1, 0xc3, 0xf0,
+ 0xe4, 0xdf, 0xe4, 0xdb, 0xca, 0xaa, 0xc4, 0xe7, 0xce, 0xc2, 0xbb, 0xac, 0xd7,
+ 0xbc, 0xc1, 0xef, 0xb2, 0xd7, 0xcc, 0xcf, 0xcf, 0xaa, 0xe4, 0xe0, 0xe4, 0xe5,
+ 0xbc, 0xe5, 0xd1, 0xcc, 0xb7, 0xb3, 0xc3, 0xba, 0xc1, 0xb6, 0xd5, 0xd5, 0xec,
+ 0xcf, 0xec, 0xbe, 0xec, 0xe3, 0xbb, 0xcd, 0xbb, 0xc0, 0xc9, 0xb7, 0xcf, 0xba,
+ 0xec, 0xd0, 0xa1, 0xf5, 0xd2, 0xaf, 0xeb, 0xba, 0xe9, 0xe0, 0xca, 0xa8, 0xd4,
+ 0xb3, 0xbb, 0xab, 0xc0, 0xc5, 0xba, 0xf7, 0xe8, 0xa6, 0xc9, 0xaa, 0xc8, 0xf0,
+ 0xe8, 0xa3, 0xe7, 0xf5, 0xe8, 0xa7, 0xe7, 0xf8, 0xe8, 0xa4, 0xb5, 0xb1, 0xbb,
+ 0xfb, 0xf0, 0xf6, 0xcc, 0xb5, 0xb4, 0xe1, 0xc2, 0xe9, 0xf0, 0xf2, 0xb1, 0xd4,
+ 0xf0, 0xf4, 0xb3, 0xd5, 0xc2, 0xe9, 0xd5, 0xb5, 0xc3, 0xcb, 0xbe, 0xa6, 0xbd,
+ 0xde, 0xc4, 0xc0, 0xed, 0xf9, 0xb6, 0xbd, 0xb6, 0xc3, 0xd8, 0xba, 0xb2, 0xc7,
+ 0xd5, 0xf6, 0xee, 0xa2, 0xed, 0xfe, 0xee, 0xa1, 0xb0, 0xab, 0xcb, 0xe9, 0xc5,
+ 0xf6, 0xcd, 0xeb, 0xb5, 0xe2, 0xc2, 0xb5, 0xb5, 0xef, 0xc5, 0xf0, 0xb1, 0xae,
+ 0xed, 0xd4, 0xa1, 0xf5, 0xec, 0xf7, 0xc2, 0xbb, 0xbd, 0xfb, 0xcd, 0xf2, 0xc7,
+ 0xdd, 0xc0, 0xe2, 0xd6, 0xc9, 0xb3, 0xed, 0xef, 0xfe, 0xd9, 0xf7, 0xef, 0xfd,
+ 0xbf, 0xdf, 0xf1, 0xbd, 0xbf, 0xea, 0xbd, 0xda, 0xf3, 0xde, 0xf3, 0xdf, 0xf3,
+ 0xc8, 0xc1, 0xbb, 0xbe, 0xac, 0xd4, 0xc1, 0xbe, 0xad, 0xbe, 0xee, 0xc0, 0xa7,
+ 0xb0, 0xf3, 0xcb, 0xe7, 0xcc, 0xd0, 0xd6, 0xc3, 0xd5, 0xd6, 0xd7, 0xef, 0xca,
+ 0xf0, 0xd2, 0xe5, 0xcf, 0xdb, 0xc8, 0xba, 0xca, 0xa5, 0xc6, 0xb8, 0xcb, 0xc1,
+ 0xd2, 0xde, 0xeb, 0xec, 0xd1, 0xfc, 0xb3, 0xa6, 0xd0, 0xc8, 0xc8, 0xf9, 0xbd,
+ 0xc5, 0xd6, 0xd7, 0xb8, 0xb9, 0xcf, 0xd9, 0xc4, 0xd4, 0xbe, 0xcb, 0xcd, 0xa7,
+ 0xb5, 0xd9, 0xbb, 0xe7, 0xc2, 0xe4, 0xdd, 0xe6, 0xbf, 0xfb, 0xce, 0xad, 0xba,
+ 0xf9, 0xd2, 0xb6, 0xd4, 0xe1, 0xb8, 0xf0, 0xdd, 0xe0, 0xdd, 0xab, 0xc6, 0xcf,
+ 0xb6, 0xad, 0xdd, 0xe2, 0xdd, 0xe7, 0xdd, 0xe1, 0xd3, 0xdd, 0xc2, 0xb2, 0xba,
+ 0xc5, 0xd3, 0xbc, 0xf2, 0xd1, 0xf2, 0xda, 0xf2, 0xd8, 0xca, 0xf1, 0xb6, 0xea,
+ 0xcd, 0xc9, 0xb7, 0xe4, 0xf2, 0xd7, 0xf2, 0xb9, 0xf2, 0xdb, 0xd1, 0xc3, 0xf4,
+ 0xc4, 0xd2, 0xe1, 0xc8, 0xb9, 0xb2, 0xb9, 0xf4, 0xc3, 0xd7, 0xb0, 0xc0, 0xef,
+ 0xf4, 0xc1, 0xd4, 0xa3, 0xd9, 0xf6, 0xa1, 0xf5, 0xbd, 0xe2, 0xb2, 0xef, 0xb8,
+ 0xc3, 0xcf, 0xea, 0xca, 0xd4, 0xca, 0xab, 0xda, 0xb5, 0xbf, 0xe4, 0xda, 0xb6,
+ 0xd2, 0xe8, 0xb3, 0xcf, 0xbb, 0xb0, 0xd6, 0xef, 0xb9, 0xee, 0xd1, 0xaf, 0xda,
+ 0xb9, 0xda, 0xb8, 0xd5, 0xb2, 0xa1, 0xf5, 0xf6, 0xa4, 0xa1, 0xf5, 0xbb, 0xbf,
+ 0xf5, 0xf6, 0xba, 0xd1, 0xd4, 0xf4, 0xd7, 0xca, 0xbc, 0xd6, 0xbb, 0xdf, 0xea,
+ 0xdf, 0xc1, 0xde, 0xc2, 0xb8, 0xea, 0xe0, 0xbc, 0xa3, 0xb8, 0xfa, 0xbf, 0xe7,
+ 0xc2, 0xb7, 0xcc, 0xf8, 0xb6, 0xe5, 0xb9, 0xf2, 0xf5, 0xd3, 0xa1, 0xf5, 0xb6,
+ 0xe3, 0xbd, 0xcf, 0xd4, 0xd8, 0xe9, 0xf8, 0xe9, 0xf9, 0xb1, 0xd9, 0xc5, 0xa9,
+ 0xd4, 0xcb, 0xd3, 0xce, 0xb5, 0xc0, 0xcb, 0xec, 0xb4, 0xef, 0xb1, 0xc6, 0xce,
+ 0xa5, 0xe5, 0xda, 0xd3, 0xf6, 0xb6, 0xf4, 0xb9, 0xfd, 0xb1, 0xe9, 0xe5, 0xd8,
+ 0xd3, 0xe2, 0xb6, 0xdd, 0xd7, 0xde, 0xa1, 0xf5, 0xb3, 0xea, 0xc0, 0xd2, 0xf5,
+ 0xa4, 0xd3, 0xd4, 0xee, 0xdc, 0xc7, 0xaf, 0xee, 0xe0, 0xee, 0xdf, 0xbc, 0xd8,
+ 0xd3, 0xcb, 0xc7, 0xa6, 0xc5, 0xd9, 0xb9, 0xb3, 0xb2, 0xac, 0xc1, 0xe5, 0xee,
+ 0xe7, 0xee, 0xe9, 0xee, 0xd2, 0xee, 0xeb, 0xee, 0xe4, 0xc3, 0xad, 0xd5, 0xa2,
+ 0xb0, 0xaf, 0xb8, 0xf4, 0xd4, 0xc9, 0xd3, 0xba, 0xf6, 0xc1, 0xef, 0xf4, 0xa1,
+ 0xf5, 0xc0, 0xd7, 0xb5, 0xe7, 0xb1, 0xa2, 0xc1, 0xe3, 0xbe, 0xb8, 0xd1, 0xa5,
+ 0xb0, 0xd0, 0xd4, 0xa4, 0xcd, 0xe7, 0xb6, 0xd9, 0xe7, 0xef, 0xb0, 0xe4, 0xcb,
+ 0xcc, 0xcb, 0xc7, 0xe2, 0xc2, 0xb1, 0xa5, 0xca, 0xce, 0xb3, 0xdb, 0xcd, 0xd4,
+ 0xd1, 0xb1, 0xf7, 0xd5, 0xf0, 0xaf, 0xf7, 0xe4, 0xb6, 0xa6, 0xb9, 0xc4, 0xca,
+ 0xf3, 0xc9, 0xae, 0xd9, 0xd7, 0xbd, 0xc4, 0xd9, 0xd2, 0xd9, 0xd4, 0xc1, 0xc5,
+ 0xc6, 0xcd, 0xcf, 0xf1, 0xc7, 0xc8, 0xb9, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xbe,
+ 0xa4, 0xb5, 0xca, 0xbb, 0xae, 0xd8, 0xe3, 0xd8, 0xd1, 0xd1, 0xe1, 0xe0, 0xd5,
+ 0xe0, 0xd6, 0xc2, 0xef, 0xb3, 0xa2, 0xcb, 0xd4, 0xc5, 0xbb, 0xcc, 0xbe, 0xbc,
+ 0xce, 0xe0, 0xb6, 0xb8, 0xc2, 0xe0, 0xbb, 0xdf, 0xf5, 0xe0, 0xbd, 0xe0, 0xd0,
+ 0xa1, 0xf5, 0xdf, 0xd9, 0xcd, 0xc5, 0xcd, 0xbc, 0xb3, 0xbe, 0xdb, 0xd3, 0xbe,
+ 0xb3, 0xc4, 0xb9, 0xb5, 0xe6, 0xc7, 0xb5, 0xca, 0xfb, 0xa1, 0xf5, 0xca, 0xd9,
+ 0xe2, 0xb7, 0xc3, 0xce, 0xe2, 0xb9, 0xb6, 0xe1, 0xde, 0xc6, 0xb5, 0xd5, 0xe6,
+ 0xcf, 0xc4, 0xdb, 0xe5, 0xfd, 0xe6, 0xce, 0xe6, 0xd0, 0xe6, 0xcc, 0xb7, 0xf5,
+ 0xc4, 0xaf, 0xc4, 0xfe, 0xb9, 0xd1, 0xc1, 0xc8, 0xca, 0xb5, 0xd5, 0xaf, 0xc7,
+ 0xde, 0xe5, 0xbb, 0xb2, 0xec, 0xb6, 0xd4, 0xc2, 0xc5, 0xd5, 0xb8, 0xe1, 0xab,
+ 0xe1, 0xa4, 0xb1, 0xd2, 0xc4, 0xbb, 0xe0, 0xfe, 0xe1, 0xa3, 0xc0, 0xaa, 0xc1,
+ 0xce, 0xb1, 0xd7, 0xb1, 0xf0, 0xd5, 0xc3, 0xb3, 0xb9, 0xd2, 0xf3, 0xd4, 0xb8,
+ 0xcc, 0xac, 0xbf, 0xb6, 0xc2, 0xfd, 0xb9, 0xdf, 0xe2, 0xfa, 0xb2, 0xd1, 0xb2,
+ 0xd2, 0xe3, 0xbc, 0xbd, 0xd8, 0xc6, 0xb2, 0xd5, 0xaa, 0xcb, 0xa4, 0xb3, 0xb7,
+ 0xc3, 0xfe, 0xc2, 0xa7, 0xdf, 0xa1, 0xde, 0xe2, 0xb4, 0xdd, 0xe5, 0xba, 0xde,
+ 0xfd, 0xb2, 0xf4, 0xc7, 0xc3, 0xce, 0xd3, 0xc6, 0xec, 0xec, 0xbd, 0xb3, 0xa9,
+ 0xf4, 0xdf, 0xea, 0xd4, 0xb0, 0xf1, 0xd5, 0xa5, 0xe9, 0xc5, 0xe9, 0xc2, 0xc8,
+ 0xd9, 0xb8, 0xdc, 0xb9, 0xb9, 0xe9, 0xbb, 0xc8, 0xb6, 0xe9, 0xbd, 0xe9, 0xbe,
+ 0xc1, 0xf1, 0xbb, 0xb1, 0xc7, 0xb9, 0xe9, 0xbf, 0xe9, 0xb3, 0xa1, 0xf5, 0xc5,
+ 0xcc, 0xa1, 0xf5, 0xc7, 0xb8, 0xb8, 0xe8, 0xeb, 0xb5, 0xd5, 0xc4, 0xd1, 0xdd,
+ 0xb9, 0xf6, 0xc0, 0xec, 0xb5, 0xce, 0xe4, 0xf6, 0xd1, 0xfa, 0xc4, 0xae, 0xd7,
+ 0xd5, 0xc2, 0xa9, 0xc6, 0xaf, 0xba, 0xba, 0xc2, 0xfa, 0xd6, 0xcd, 0xc6, 0xe1,
+ 0xca, 0xfe, 0xbd, 0xa5, 0xd5, 0xc7, 0xc1, 0xb0, 0xe4, 0xee, 0xc2, 0xfe, 0xe4,
+ 0xf0, 0xb3, 0xba, 0xe4, 0xf4, 0xbb, 0xa6, 0xd3, 0xe6, 0xc9, 0xf8, 0xb5, 0xd3,
+ 0xc2, 0xb1, 0xc8, 0xdb, 0xce, 0xf5, 0xc9, 0xbf, 0xd0, 0xdc, 0xcf, 0xa8, 0xd3,
+ 0xab, 0xb6, 0xfb, 0xea, 0xfb, 0xdc, 0xfd, 0xd3, 0xfc, 0xe2, 0xaf, 0xd1, 0xfe,
+ 0xcb, 0xf6, 0xc2, 0xea, 0xb9, 0xe5, 0xe8, 0xa9, 0xd5, 0xe7, 0xd2, 0xc9, 0xc5,
+ 0xb1, 0xd1, 0xf1, 0xb7, 0xe8, 0xd3, 0xfa, 0xbb, 0xbe, 0xbe, 0xa1, 0xbc, 0xe0,
+ 0xc3, 0xe9, 0xee, 0xa5, 0xee, 0xa3, 0xcb, 0xaf, 0xb4, 0xc5, 0xb5, 0xfa, 0xb1,
+ 0xcc, 0xcc, 0xbc, 0xcb, 0xb6, 0xed, 0xd9, 0xec, 0xf5, 0xb8, 0xa3, 0xbb, 0xf6,
+ 0xd6, 0xd6, 0xb3, 0xc6, 0xcd, 0xdd, 0xce, 0xd1, 0xbd, 0xdf, 0xb6, 0xcb, 0xb9,
+ 0xdc, 0xbb, 0xfe, 0xbc, 0xe3, 0xf3, 0xdb, 0xcb, 0xe3, 0xf3, 0xe9, 0xb2, 0xad,
+ 0xf3, 0xdd, 0xf3, 0xe7, 0xb8, 0xf6, 0xa1, 0xf5, 0xb4, 0xe2, 0xf4, 0xd5, 0xbe,
+ 0xab, 0xd5, 0xc0, 0xe7, 0xba, 0xd7, 0xdb, 0xb4, 0xc2, 0xe7, 0xb1, 0xc2, 0xcc,
+ 0xbd, 0xf4, 0xd7, 0xba, 0xcd, 0xf8, 0xb8, 0xd9, 0xe7, 0xb2, 0xb3, 0xf1, 0xc3,
+ 0xe0, 0xb2, 0xca, 0xc2, 0xda, 0xce, 0xac, 0xd0, 0xf7, 0xe7, 0xbb, 0xe7, 0xb7,
+ 0xb7, 0xa3, 0xb4, 0xe4, 0xf4, 0xe4, 0xb5, 0xd4, 0xce, 0xc5, 0xbe, 0xdb, 0xd5,
+ 0xd8, 0xb8, 0xaf, 0xb0, 0xf2, 0xb8, 0xe0, 0xeb, 0xf5, 0xb2, 0xb2, 0xcd, 0xc8,
+ 0xeb, 0xf6, 0xea, 0xb0, 0xcc, 0xa8, 0xd3, 0xeb, 0xcc, 0xf2, 0xce, 0xe8, 0xf4,
+ 0xbb, 0xc8, 0xd8, 0xdd, 0xef, 0xcf, 0xaf, 0xd0, 0xee, 0xc3, 0xc9, 0xdd, 0xb0,
+ 0xc6, 0xd1, 0xcb, 0xe2, 0xb8, 0xc7, 0xd5, 0xf4, 0xdd, 0xa5, 0xdd, 0xed, 0xa1,
+ 0xf5, 0xb2, 0xd4, 0xcb, 0xf2, 0xdd, 0xee, 0xf2, 0xea, 0xc3, 0xdb, 0xf2, 0xdf,
+ 0xf2, 0xec, 0xf2, 0xe1, 0xf2, 0xe6, 0xd6, 0xa9, 0xca, 0xb4, 0xf2, 0xe9, 0xf2,
+ 0xe8, 0xc9, 0xd1, 0xb9, 0xd3, 0xc5, 0xe1, 0xb9, 0xfc, 0xc2, 0xe3, 0xd6, 0xc6,
+ 0xf1, 0xd4, 0xf1, 0xd2, 0xa1, 0xf5, 0xcb, 0xd0, 0xd6, 0xbe, 0xd3, 0xef, 0xce,
+ 0xdc, 0xc8, 0xcf, 0xbd, 0xeb, 0xca, 0xc4, 0xce, 0xf3, 0xcb, 0xb5, 0xda, 0xbe,
+ 0xbb, 0xe5, 0xd3, 0xd5, 0xda, 0xbf, 0xda, 0xbd, 0xa1, 0xf5, 0xba, 0xc0, 0xc0,
+ 0xea, 0xc3, 0xb2, 0xb1, 0xf6, 0xea, 0xe2, 0xc9, 0xde, 0xba, 0xd5, 0xd5, 0xd4,
+ 0xb8, 0xcf, 0xbe, 0xd6, 0xb8, 0xa8, 0xe9, 0xfc, 0xc7, 0xe1, 0xcd, 0xec, 0xc0,
+ 0xb1, 0xd4, 0xb6, 0xe5, 0xdc, 0xd1, 0xb7, 0xc7, 0xb2, 0xd2, 0xa3, 0xb5, 0xdd,
+ 0xe5, 0xdd, 0xa1, 0xf5, 0xe5, 0xde, 0xb1, 0xc9, 0xa1, 0xf5, 0xdb, 0xb4, 0xbd,
+ 0xcd, 0xcb, 0xe1, 0xbf, 0xe1, 0xf5, 0xa9, 0xbd, 0xc2, 0xd2, 0xf8, 0xcd, 0xad,
+ 0xc3, 0xfa, 0xee, 0xf9, 0xb8, 0xf5, 0xee, 0xfd, 0xcf, 0xce, 0xef, 0xa7, 0xa1,
+ 0xf5, 0xcf, 0xb3, 0xba, 0xd2, 0xb9, 0xeb, 0xc3, 0xf6, 0xb8, 0xf3, 0xb7, 0xa7,
+ 0xb8, 0xf3, 0xcf, 0xb6, 0xd5, 0xcf, 0xbc, 0xca, 0xb4, 0xc6, 0xf6, 0xc3, 0xd0,
+ 0xe8, 0xf7, 0xb0, 0xf7, 0xb1, 0xc9, 0xd8, 0xc6, 0xc4, 0xc1, 0xec, 0xec, 0xaa,
+ 0xcc, 0xa8, 0xbd, 0xc8, 0xb1, 0xfd, 0xb6, 0xfc, 0xe2, 0xc3, 0xb2, 0xb5, 0xb0,
+ 0xb9, 0xf7, 0xbb, 0xf7, 0xd6, 0xbf, 0xfd, 0xbb, 0xea, 0xc3, 0xf9, 0xf0, 0xb0,
+ 0xb7, 0xef, 0xc3, 0xb4, 0xb1, 0xc7, 0xc6, 0xeb, 0xd2, 0xda, 0xd2, 0xc7, 0xc6,
+ 0xa7, 0xbd, 0xa9, 0xbc, 0xdb, 0xd9, 0xaf, 0xbf, 0xeb, 0xbc, 0xf3, 0xa1, 0xf5,
+ 0xc1, 0xdd, 0xbe, 0xe7, 0xc5, 0xfc, 0xc1, 0xf5, 0xbd, 0xa3, 0xb9, 0xf4, 0xdb,
+ 0xc4, 0xc0, 0xf7, 0xdf, 0xeb, 0xce, 0xfb, 0xe0, 0xda, 0xb3, 0xb0, 0xba, 0xd9,
+ 0xd7, 0xec, 0xbb, 0xa9, 0xd0, 0xea, 0xd2, 0xad, 0xe0, 0xdb, 0xc5, 0xe7, 0xcb,
+ 0xbb, 0xd0, 0xa5, 0xdf, 0xb4, 0xdc, 0xaf, 0xd0, 0xe6, 0xd4, 0xf6, 0xb7, 0xd8,
+ 0xd7, 0xb9, 0xb6, 0xe9, 0xb6, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd2, 0xe6,
+ 0xb5, 0xe6, 0xbf, 0xe5, 0xfc, 0xbd, 0xbf, 0xe6, 0xac, 0xe5, 0xbc, 0xbf, 0xed,
+ 0xc9, 0xf3, 0xd0, 0xb4, 0xb2, 0xe3, 0xc2, 0xc4, 0xe1, 0xd8, 0xa1, 0xf5, 0xb4,
+ 0xb1, 0xd6, 0xc4, 0xe1, 0xa6, 0xb7, 0xcf, 0xb3, 0xf8, 0xc3, 0xed, 0xd8, 0xcb,
+ 0xb9, 0xe3, 0xb3, 0xa7, 0xb5, 0xaf, 0xd3, 0xb0, 0xb5, 0xc2, 0xe1, 0xe7, 0xc7,
+ 0xec, 0xbb, 0xdb, 0xc2, 0xc7, 0xed, 0xab, 0xc4, 0xbd, 0xd3, 0xc7, 0xc6, 0xdd,
+ 0xce, 0xbf, 0xcb, 0xcb, 0xd3, 0xfb, 0xe3, 0xbf, 0xc1, 0xaf, 0xc3, 0xf5, 0xd4,
+ 0xf7, 0xe3, 0xbd, 0xb5, 0xac, 0xb7, 0xdf, 0xe3, 0xbe, 0xe2, 0xe4, 0xc2, 0xbe,
+ 0xc4, 0xa6, 0xd6, 0xbf, 0xc4, 0xa1, 0xd7, 0xb2, 0xc6, 0xcb, 0xc0, 0xcc, 0xb3,
+ 0xc5, 0xd7, 0xab, 0xb2, 0xa6, 0xc4, 0xd3, 0xcb, 0xba, 0xc1, 0xc3, 0xc8, 0xf6,
+ 0xb4, 0xe9, 0xb2, 0xa5, 0xb8, 0xa7, 0xc4, 0xed, 0xc7, 0xcb, 0xdf, 0xa4, 0xb5,
+ 0xa7, 0xde, 0xec, 0xb5, 0xd0, 0xb7, 0xf3, 0xca, 0xfd, 0xc4, 0xba, 0xd4, 0xdd,
+ 0xb1, 0xa9, 0xea, 0xc7, 0xd1, 0xf9, 0xd5, 0xc1, 0xe9, 0xa4, 0xd7, 0xae, 0xca,
+ 0xe0, 0xb1, 0xea, 0xb2, 0xdb, 0xc4, 0xa3, 0xc2, 0xa5, 0xb7, 0xae, 0xbd, 0xb0,
+ 0xc0, 0xd6, 0xe8, 0xc8, 0xe9, 0xca, 0xc1, 0xba, 0xc5, 0xb7, 0xcc, 0xbe, 0xe9,
+ 0xe4, 0xd2, 0xe3, 0xc5, 0xb9, 0xbd, 0xac, 0xe4, 0xfc, 0xb3, 0xce, 0xc6, 0xc3,
+ 0xc1, 0xca, 0xbd, 0xe0, 0xbd, 0xbd, 0xcc, 0xb6, 0xc7, 0xb1, 0xe4, 0xfa, 0xb3,
+ 0xb1, 0xc5, 0xec, 0xe4, 0xfd, 0xc0, 0xa3, 0xc8, 0xf3, 0xbd, 0xa7, 0xc5, 0xcb,
+ 0xeb, 0xf8, 0xe4, 0xb1, 0xa1, 0xf5, 0xf4, 0xaa, 0xca, 0xec, 0xb0, 0xbe, 0xc8,
+ 0xc8, 0xec, 0xd9, 0xeb, 0xbb, 0xa1, 0xf5, 0xbd, 0xb1, 0xe2, 0xb1, 0xd3, 0xa8,
+ 0xe8, 0xb0, 0xc1, 0xa7, 0xe8, 0xaa, 0xe8, 0xad, 0xe7, 0xdc, 0xf1, 0xa4, 0xb4,
+ 0xf1, 0xce, 0xc1, 0xc1, 0xf6, 0xca, 0xdd, 0xb4, 0xaf, 0xf1, 0xa3, 0xb0, 0xa8,
+ 0xd6, 0xe5, 0xc5, 0xcc, 0xcf, 0xb9, 0xc3, 0xd0, 0xee, 0xa7, 0xee, 0xa8, 0xa1,
+ 0xf5, 0xb4, 0xe8, 0xb0, 0xf5, 0xc8, 0xb7, 0xc0, 0xda, 0xc4, 0xeb, 0xbf, 0xc4,
+ 0xc2, 0xeb, 0xc5, 0xcd, 0xb8, 0xe5, 0xbc, 0xda, 0xb9, 0xc8, 0xbb, 0xfc, 0xf0,
+ 0xa2, 0xb5, 0xbe, 0xd2, 0xa4, 0xc7, 0xee, 0xbc, 0xfd, 0xcf, 0xe4, 0xb7, 0xb6,
+ 0xf3, 0xf0, 0xd7, 0xad, 0xc6, 0xaa, 0xf3, 0xf2, 0xa1, 0xf5, 0xf3, 0xf3, 0xba,
+ 0xfd, 0xb5, 0xde, 0xc1, 0xb7, 0xce, 0xb3, 0xd6, 0xc2, 0xbc, 0xea, 0xc3, 0xe5,
+ 0xbc, 0xa9, 0xb1, 0xe0, 0xd4, 0xb5, 0xcf, 0xdf, 0xb6, 0xd0, 0xbb, 0xba, 0xe7,
+ 0xb6, 0xe7, 0xbc, 0xe7, 0xbf, 0xe7, 0xbe, 0xc2, 0xee, 0xb0, 0xd5, 0xf4, 0xc9,
+ 0xf4, 0xe6, 0xf1, 0xee, 0xcc, 0xc5, 0xc4, 0xa4, 0xcf, 0xa5, 0xbd, 0xba, 0xb7,
+ 0xf4, 0xb1, 0xec, 0xd5, 0xe1, 0xb1, 0xce, 0xce, 0xb5, 0xc1, 0xab, 0xca, 0xdf,
+ 0xd2, 0xf1, 0xc2, 0xfb, 0xc3, 0xef, 0xbd, 0xaf, 0xb2, 0xcc, 0xb2, 0xb7, 0xc5,
+ 0xee, 0xb4, 0xd0, 0xde, 0xa3, 0xa1, 0xf5, 0xf2, 0xeb, 0xba, 0xfb, 0xb5, 0xfb,
+ 0xf2, 0xf0, 0xcf, 0xba, 0xce, 0xcf, 0xca, 0xad, 0xf2, 0xf9, 0xbb, 0xc8, 0xf2,
+ 0xf2, 0xf2, 0xf5, 0xce, 0xc0, 0xb3, 0xe5, 0xba, 0xd6, 0xb8, 0xb4, 0xb0, 0xfd,
+ 0xf1, 0xd9, 0xa1, 0xf5, 0xf1, 0xdb, 0xd2, 0xea, 0xc1, 0xc2, 0xcc, 0xb8, 0xd7,
+ 0xbb, 0xb5, 0xae, 0xc7, 0xeb, 0xd6, 0xee, 0xbf, 0xce, 0xda, 0xc3, 0xda, 0xc6,
+ 0xb5, 0xf7, 0xcb, 0xad, 0xc2, 0xdb, 0xda, 0xba, 0xda, 0xc7, 0xb7, 0xcc, 0xda,
+ 0xc4, 0xcd, 0xe3, 0xca, 0xfa, 0xd6, 0xed, 0xc5, 0xe2, 0xc9, 0xcd, 0xb8, 0xb3,
+ 0xbc, 0xfa, 0xd5, 0xcb, 0xb6, 0xc4, 0xcf, 0xcd, 0xc2, 0xf4, 0xb4, 0xcd, 0xd6,
+ 0xca, 0xe2, 0xd9, 0xf4, 0xf7, 0xcc, 0xcb, 0xc8, 0xa4, 0xa1, 0xf5, 0xbc, 0xf9,
+ 0xf5, 0xd7, 0xcc, 0xdf, 0xcc, 0xa4, 0xb2, 0xc8, 0xf5, 0xd8, 0xa1, 0xf5, 0xbe,
+ 0xe1, 0xcc, 0xc9, 0xbb, 0xd4, 0xc1, 0xbe, 0xea, 0xa1, 0xb1, 0xb2, 0xe9, 0xfd,
+ 0xc2, 0xd6, 0xea, 0xa2, 0xe9, 0xfe, 0xb9, 0xf5, 0xca, 0xca, 0xd5, 0xda, 0xe5,
+ 0xdb, 0xd4, 0xe2, 0xc7, 0xa8, 0xc1, 0xda, 0xd6, 0xa3, 0xb5, 0xcb, 0xdb, 0xb6,
+ 0xb4, 0xbc, 0xd7, 0xed, 0xb4, 0xd7, 0xeb, 0xe7, 0xd0, 0xbf, 0xcc, 0xe0, 0xcf,
+ 0xfa, 0xc6, 0xcc, 0xee, 0xed, 0xb3, 0xfa, 0xc2, 0xc1, 0xc8, 0xf1, 0xef, 0xb1,
+ 0xb7, 0xe6, 0xb1, 0xb5, 0xef, 0xae, 0xba, 0xb8, 0xe3, 0xcc, 0xd4, 0xc4, 0xcf,
+ 0xf6, 0xf6, 0xaa, 0xd5, 0xf0, 0xc3, 0xb9, 0xbf, 0xbf, 0xb0, 0xb0, 0xd0, 0xac,
+ 0xb9, 0xae, 0xf2, 0xa1, 0xa1, 0xf5, 0xf2, 0xa2, 0xb9, 0xce, 0xd1, 0xf8, 0xb6,
+ 0xf6, 0xc4, 0xd9, 0xe2, 0xc5, 0xcd, 0xd5, 0xd7, 0xa4, 0xe6, 0xe1, 0xca, 0xbb,
+ 0xe6, 0xe5, 0xbc, 0xdd, 0xbe, 0xd4, 0xe6, 0xe2, 0xf7, 0xbc, 0xb7, 0xa2, 0xf7,
+ 0xd7, 0xc4, 0xd6, 0xf7, 0xc8, 0xc6, 0xc7, 0xf6, 0xcf, 0xc2, 0xb3, 0xf0, 0xb2,
+ 0xd1, 0xbb, 0xf5, 0xfb, 0xf4, 0xef, 0xf7, 0xe2, 0xc0, 0xe8, 0xc4, 0xab, 0xb3,
+ 0xdd, 0xc8, 0xe5, 0xbe, 0xa1, 0xd9, 0xb1, 0xd9, 0xcf, 0xd9, 0xad, 0xbc, 0xbd,
+ 0xc3, 0xdd, 0xc4, 0xfd, 0xbc, 0xc1, 0xd8, 0xe6, 0xd1, 0xab, 0xe0, 0xdf, 0xe0,
+ 0xe6, 0xb5, 0xb1, 0xd8, 0xac, 0xe0, 0xe4, 0xb6, 0xd6, 0xd4, 0xeb, 0xc6, 0xf7,
+ 0xdf, 0xe6, 0xe0, 0xe5, 0xe0, 0xc8, 0xca, 0xc9, 0xe0, 0xde, 0xb8, 0xc1, 0xb1,
+ 0xda, 0xbf, 0xd1, 0xcc, 0xb3, 0xdb, 0xd5, 0xb7, 0xdc, 0xa1, 0xf5, 0xd9, 0xf8,
+ 0xd1, 0xa7, 0xe5, 0xbe, 0xb5, 0xbc, 0xc7, 0xbf, 0xcf, 0xdc, 0xc6, 0xbe, 0xed,
+ 0xac, 0xb1, 0xb9, 0xe3, 0xc1, 0xd2, 0xe4, 0xba, 0xb6, 0xb0, 0xc3, 0xd0, 0xb8,
+ 0xd5, 0xbd, 0xc9, 0xc3, 0xd3, 0xb5, 0xb5, 0xb2, 0xcc, 0xa2, 0xba, 0xb3, 0xbe,
+ 0xdd, 0xc2, 0xb0, 0xd4, 0xf1, 0xc0, 0xde, 0xb2, 0xd9, 0xbc, 0xf1, 0xc7, 0xdc,
+ 0xb5, 0xa3, 0xce, 0xce, 0xd5, 0xfb, 0xc0, 0xfa, 0xcf, 0xfe, 0xe5, 0xdf, 0xea,
+ 0xca, 0xea, 0xbc, 0xa1, 0xf5, 0xe9, 0xd7, 0xc6, 0xd3, 0xe8, 0xeb, 0xb3, 0xc8,
+ 0xba, 0xe1, 0xe9, 0xd9, 0xca, 0xf7, 0xe9, 0xcf, 0xcd, 0xd6, 0xcf, 0xf0, 0xc7,
+ 0xc5, 0xc7, 0xc1, 0xe9, 0xd4, 0xbb, 0xfa, 0xe8, 0xe3, 0xec, 0xa8, 0xc0, 0xfa,
+ 0xeb, 0xa9, 0xe5, 0xa5, 0xb5, 0xed, 0xd4, 0xe8, 0xc5, 0xa8, 0xd4, 0xf3, 0xd7,
+ 0xc7, 0xe5, 0xa2, 0xb0, 0xc4, 0xbc, 0xa4, 0xe5, 0xa3, 0xe5, 0xa4, 0xa1, 0xf5,
+ 0xe4, 0xc5, 0xa1, 0xf5, 0xb3, 0xe3, 0xec, 0xc0, 0xc1, 0xd7, 0xc9, 0xd5, 0xb5,
+ 0xc6, 0xd1, 0xe0, 0xec, 0xe4, 0xc1, 0xc7, 0xcc, 0xcc, 0xec, 0xcb, 0xc8, 0xbc,
+ 0xd1, 0xe6, 0xb6, 0xc0, 0xe8, 0xab, 0xe7, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8,
+ 0xb1, 0xc6, 0xb0, 0xea, 0xb1, 0xdd, 0xf9, 0xd5, 0xce, 0xc8, 0xb3, 0xa1, 0xf5,
+ 0xc2, 0xac, 0xee, 0xc2, 0xee, 0xaa, 0xc2, 0xf7, 0xee, 0xa9, 0xc6, 0xb3, 0xc4,
+ 0xa5, 0xd7, 0xa9, 0xed, 0xe0, 0xed, 0xd3, 0xd3, 0xf9, 0xbb, 0xfd, 0xd3, 0xb1,
+ 0xc4, 0xc2, 0xf6, 0xd5, 0xa1, 0xf5, 0xbf, 0xfa, 0xb8, 0xdd, 0xa1, 0xf5, 0xd6,
+ 0xfe, 0xf3, 0xc6, 0xa1, 0xf5, 0xb4, 0xdb, 0xc9, 0xb8, 0xf3, 0xf7, 0xb8, 0xe2,
+ 0xcc, 0xc7, 0xe7, 0xcb, 0xe7, 0xcc, 0xdd, 0xd3, 0xb8, 0xbf, 0xcf, 0xd8, 0xe7,
+ 0xc9, 0xe7, 0xc7, 0xe7, 0xc6, 0xe7, 0xa7, 0xee, 0xbe, 0xf4, 0xcb, 0xba, 0xb2,
+ 0xb0, 0xbf, 0xf4, 0xe7, 0xf1, 0xf1, 0xc9, 0xc5, 0xc4, 0xe5, 0xc5, 0xf2, 0xd5,
+ 0xe9, 0xd0, 0xcb, 0xcb, 0xd2, 0xb2, 0xd5, 0xc8, 0xef, 0xde, 0xa5, 0xde, 0xa6,
+ 0xde, 0xa7, 0xb5, 0xb4, 0xde, 0xac, 0xbd, 0xb6, 0xcf, 0xf4, 0xce, 0xdf, 0xde,
+ 0xa9, 0xf3, 0xa6, 0xc3, 0xf8, 0xc2, 0xec, 0xd3, 0xa9, 0xc8, 0xda, 0xba, 0xe2,
+ 0xcd, 0xca, 0xbf, 0xe3, 0xc8, 0xec, 0xf1, 0xdd, 0xf1, 0xd7, 0xc7, 0xd7, 0xea,
+ 0xec, 0xda, 0xd0, 0xd1, 0xe8, 0xda, 0xc9, 0xbb, 0xe4, 0xc4, 0xb1, 0xb5, 0xfd,
+ 0xd0, 0xb3, 0xda, 0xd1, 0xc5, 0xb5, 0xda, 0xcb, 0xce, 0xbd, 0xb7, 0xed, 0xda,
+ 0xcd, 0xda, 0xcf, 0xda, 0xc8, 0xda, 0xce, 0xd4, 0xa5, 0xa1, 0xf5, 0xc3, 0xa8,
+ 0xc0, 0xb5, 0xcc, 0xe3, 0xf5, 0xe2, 0xd3, 0xbb, 0xf5, 0xe5, 0xf5, 0xdf, 0xf5,
+ 0xe0, 0xb7, 0xf8, 0xbc, 0xad, 0xca, 0xe4, 0xea, 0xa3, 0xb1, 0xe6, 0xb0, 0xec,
+ 0xd7, 0xf1, 0xe5, 0xe0, 0xd1, 0xa1, 0xb3, 0xd9, 0xc1, 0xc9, 0xd2, 0xc5, 0xda,
+ 0xfe, 0xd0, 0xd1, 0xb6, 0xa7, 0xb1, 0xed, 0xbe, 0xe2, 0xc3, 0xcc, 0xb4, 0xed,
+ 0xc7, 0xae, 0xb8, 0xd6, 0xce, 0xfd, 0xc2, 0xbc, 0xef, 0xa3, 0xd7, 0xb6, 0xbd,
+ 0xf5, 0xa1, 0xf5, 0xef, 0xbf, 0xef, 0xc0, 0xef, 0xc5, 0xd1, 0xd6, 0xcb, 0xed,
+ 0xcb, 0xe6, 0xcf, 0xd5, 0xb5, 0xf1, 0xf6, 0xae, 0xd5, 0xb4, 0xc1, 0xd8, 0xbb,
+ 0xf4, 0xc4, 0xde, 0xf6, 0xad, 0xb5, 0xe5, 0xbe, 0xb2, 0xcc, 0xf3, 0xc7, 0xca,
+ 0xbc, 0xd5, 0xbe, 0xb1, 0xc6, 0xb5, 0xf2, 0xa5, 0xcd, 0xb7, 0xcd, 0xc7, 0xd2,
+ 0xc3, 0xb2, 0xcd, 0xb9, 0xdd, 0xbd, 0xa4, 0xe2, 0xc6, 0xcf, 0xda, 0xeb, 0xc8,
+ 0xba, 0xa7, 0xe6, 0xe9, 0xc2, 0xe6, 0xba, 0xa1, 0xf7, 0xc0, 0xf7, 0xd9, 0xf7,
+ 0xda, 0xba, 0xe5, 0xb1, 0xab, 0xcd, 0xd2, 0xf0, 0xb3, 0xd1, 0xec, 0xd1, 0xbc,
+ 0xc1, 0xee, 0xd4, 0xa7, 0xc4, 0xac, 0xc7, 0xad, 0xc1, 0xfa, 0xb9, 0xea, 0xd3,
+ 0xc5, 0xb3, 0xa5, 0xc0, 0xdc, 0xb4, 0xa2, 0xc0, 0xf8, 0xba, 0xbf, 0xdf, 0xcc,
+ 0xb3, 0xa2, 0xe0, 0xe9, 0xcf, 0xc5, 0xcc, 0xe7, 0xba, 0xbe, 0xd1, 0xb9, 0xdb,
+ 0xd6, 0xa1, 0xf5, 0xd3, 0xa4, 0xe6, 0xc9, 0xe6, 0xd6, 0xc8, 0xe6, 0xde, 0xcf,
+ 0xe5, 0xf0, 0xd3, 0xec, 0xc1, 0xeb, 0xd4, 0xc0, 0xe1, 0xc9, 0xb0, 0xef, 0xc3,
+ 0xd6, 0xbb, 0xd5, 0xd3, 0xa6, 0xb6, 0xae, 0xbf, 0xd2, 0xc5, 0xb3, 0xed, 0xae,
+ 0xcf, 0xb7, 0xb4, 0xf7, 0xc7, 0xe6, 0xbb, 0xf7, 0xeb, 0xa2, 0xbc, 0xb7, 0xc5,
+ 0xa1, 0xb2, 0xc1, 0xc4, 0xe2, 0xb8, 0xe9, 0xdf, 0xaa, 0xa1, 0xf5, 0xc1, 0xb2,
+ 0xb1, 0xd0, 0xca, 0xef, 0xea, 0xd3, 0xcc, 0xb4, 0xb5, 0xb5, 0xcf, 0xad, 0xbc,
+ 0xec, 0xe8, 0xed, 0xe8, 0xce, 0xe9, 0xc9, 0xc5, 0xf6, 0xe9, 0xde, 0xe9, 0xdc,
+ 0xe9, 0xd1, 0xa1, 0xf5, 0xe9, 0xe7, 0xa1, 0xf5, 0xd5, 0xb1, 0xc5, 0xa2, 0xb1,
+ 0xf5, 0xbc, 0xc3, 0xe5, 0xa9, 0xc3, 0xc9, 0xcc, 0xce, 0xc0, 0xc4, 0xe5, 0xaa,
+ 0xc9, 0xac, 0xbf, 0xa3, 0xe5, 0xa6, 0xa1, 0xf5, 0xca, 0xaa, 0xe5, 0xa7, 0xce,
+ 0xab, 0xec, 0xdd, 0xd3, 0xaa, 0xdb, 0xc6, 0xb2, 0xd3, 0xd4, 0xef, 0xd6, 0xf2,
+ 0xbb, 0xd9, 0xbb, 0xe2, 0xec, 0xdb, 0xbe, 0xf4, 0xc7, 0xbd, 0xc4, 0xfc, 0xbb,
+ 0xf1, 0xe8, 0xb3, 0xbb, 0xb7, 0xe8, 0xa8, 0xe8, 0xb2, 0xf0, 0xec, 0xc1, 0xc6,
+ 0xb0, 0xa9, 0xb5, 0xb4, 0xcd, 0xab, 0xb5, 0xc9, 0xee, 0xab, 0xcb, 0xb2, 0xc7,
+ 0xc6, 0xc1, 0xcb, 0xbd, 0xc3, 0xc1, 0xd7, 0xbb, 0xc7, 0xed, 0xe3, 0xed, 0xb6,
+ 0xbd, 0xb8, 0xec, 0xfb, 0xec, 0xf8, 0xcb, 0xeb, 0xc1, 0xfe, 0xb4, 0xd8, 0xc2,
+ 0xa8, 0xf3, 0xfa, 0xc5, 0xf1, 0xf3, 0xf9, 0xa1, 0xf5, 0xbf, 0xb7, 0xc3, 0xd3,
+ 0xb7, 0xe0, 0xc4, 0xa3, 0xd4, 0xe3, 0xb2, 0xda, 0xf4, 0xd6, 0xcb, 0xf5, 0xbc,
+ 0xa8, 0xe7, 0xd1, 0xc2, 0xc6, 0xe7, 0xd0, 0xb1, 0xc1, 0xb7, 0xec, 0xd7, 0xdc,
+ 0xd7, 0xdd, 0xe7, 0xd2, 0xb7, 0xb1, 0xcf, 0xcb, 0xe7, 0xce, 0xa1, 0xf5, 0xe7,
+ 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xc0, 0xf4, 0xe8, 0xd2, 0xed, 0xf1, 0xfa,
+ 0xc9, 0xf9, 0xb4, 0xcf, 0xc1, 0xaa, 0xcb, 0xca, 0xd2, 0xdc, 0xd3, 0xb7, 0xe2,
+ 0xdf, 0xb1, 0xdb, 0xcd, 0xce, 0xc5, 0xa7, 0xb5, 0xa8, 0xc1, 0xb3, 0xeb, 0xda,
+ 0xc1, 0xd9, 0xbe, 0xd9, 0xbc, 0xe8, 0xd0, 0xbd, 0xb1, 0xa1, 0xc0, 0xd9, 0xde,
+ 0xb5, 0xbd, 0xaa, 0xc7, 0xbe, 0xca, 0xed, 0xd1, 0xa6, 0xde, 0xb1, 0xde, 0xb0,
+ 0xbc, 0xbb, 0xbf, 0xf7, 0xf3, 0xb0, 0xf3, 0xaf, 0xf3, 0xab, 0xf2, 0xfe, 0xf3,
+ 0xa1, 0xf3, 0xa7, 0xf2, 0xf7, 0xc2, 0xdd, 0xf2, 0xe5, 0xf3, 0xac, 0xd9, 0xf4,
+ 0xf1, 0xde, 0xcf, 0xe5, 0xf1, 0xda, 0xa1, 0xf5, 0xea, 0xe9, 0xc3, 0xd5, 0xb0,
+ 0xf9, 0xc7, 0xab, 0xbd, 0xb2, 0xbb, 0xd1, 0xd2, 0xa5, 0xd0, 0xbb, 0xcc, 0xdc,
+ 0xda, 0xd7, 0xbb, 0xed, 0xcf, 0xaa, 0xe1, 0xd9, 0xd7, 0xac, 0xc8, 0xfc, 0xb9,
+ 0xba, 0xa1, 0xf5, 0xea, 0xe7, 0xc7, 0xf7, 0xf5, 0xe3, 0xcc, 0xa3, 0xb5, 0xb8,
+ 0xf5, 0xe8, 0xcf, 0xbd, 0xd5, 0xb7, 0xec, 0xb1, 0xd4, 0xaf, 0xd3, 0xdf, 0xb1,
+ 0xdc, 0xe5, 0xe1, 0xbb, 0xb9, 0xc2, 0xf5, 0xe5, 0xe2, 0xd1, 0xfb, 0xdb, 0xb8,
+ 0xf5, 0xb1, 0xd4, 0xcd, 0xb3, 0xf3, 0xb6, 0xc6, 0xc3, 0xbe, 0xc3, 0xaa, 0xbc,
+ 0xfc, 0xc1, 0xb4, 0xef, 0xc6, 0xb9, 0xf8, 0xb4, 0xb8, 0xef, 0xf1, 0xc7, 0xc2,
+ 0xb6, 0xcd, 0xef, 0xcc, 0xa1, 0xf5, 0xef, 0xc9, 0xc0, 0xab, 0xe3, 0xd7, 0xc0,
+ 0xbb, 0xe3, 0xc7, 0xb0, 0xe5, 0xd2, 0xfe, 0xc1, 0xa5, 0xcb, 0xe4, 0xcb, 0xaa,
+ 0xcf, 0xbc, 0xbe, 0xcf, 0xba, 0xab, 0xbf, 0xc5, 0xec, 0xab, 0xce, 0xb9, 0xb3,
+ 0xd2, 0xbf, 0xa5, 0xcf, 0xca, 0xf6, 0xde, 0xf6, 0xdb, 0xf6, 0xd9, 0xba, 0xe8,
+ 0xb8, 0xeb, 0xf7, 0xe7, 0xf0, 0xa4, 0xb5, 0xe3, 0xf7, 0xed, 0xf7, 0xee, 0xf7,
+ 0xec, 0xf7, 0xfd, 0xd5, 0xab, 0xb4, 0xd4, 0xe0, 0xe0, 0xcf, 0xf2, 0xdb, 0xdb,
+ 0xc0, 0xdd, 0xc9, 0xf4, 0xd2, 0xcd, 0xed, 0xaf, 0xb4, 0xc1, 0xc0, 0xa9, 0xd6,
+ 0xc0, 0xc8, 0xc5, 0xc4, 0xec, 0xb0, 0xda, 0xcb, 0xd3, 0xdf, 0xa2, 0xb6, 0xcf,
+ 0xea, 0xd7, 0xeb, 0xfc, 0xe9, 0xc4, 0xc3, 0xca, 0xb9, 0xf1, 0xbc, 0xf7, 0xc4,
+ 0xfb, 0xe8, 0xfe, 0xa1, 0xf5, 0xcc, 0xa8, 0xec, 0xa3, 0xb9, 0xe9, 0xe9, 0xeb,
+ 0xd0, 0xba, 0xe4, 0xc9, 0xc2, 0xcb, 0xe4, 0xc2, 0xbd, 0xa6, 0xc6, 0xd9, 0xe4,
+ 0xaf, 0xd1, 0xac, 0xbd, 0xfd, 0xec, 0xe2, 0xa1, 0xf5, 0xe1, 0xee, 0xc1, 0xd4,
+ 0xe8, 0xb5, 0xa1, 0xf5, 0xce, 0xcd, 0xf1, 0xb1, 0xf0, 0xdd, 0xd3, 0xfa, 0xee,
+ 0xad, 0xf6, 0xc4, 0xd5, 0xb0, 0xed, 0xfa, 0xb4, 0xa1, 0xc0, 0xf1, 0xf0, 0xa3,
+ 0xbb, 0xe0, 0xa1, 0xf5, 0xb4, 0xdc, 0xc7, 0xcf, 0xf3, 0xef, 0xbb, 0xc9, 0xf4,
+ 0xa2, 0xf3, 0xec, 0xf3, 0xf1, 0xbc, 0xf2, 0xc1, 0xb8, 0xd6, 0xaf, 0xc9, 0xc9,
+ 0xc8, 0xc6, 0xe7, 0xd4, 0xd0, 0xe5, 0xe7, 0xd5, 0xa1, 0xf5, 0xcc, 0xb3, 0xc7,
+ 0xcc, 0xb7, 0xad, 0xd6, 0xb0, 0xc4, 0xf4, 0xc6, 0xea, 0xeb, 0xf7, 0xbe, 0xc9,
+ 0xb2, 0xd8, 0xc8, 0xf8, 0xc0, 0xb6, 0xc3, 0xea, 0xbd, 0xe5, 0xde, 0xb9, 0xdc,
+ 0xf9, 0xde, 0xb7, 0xbc, 0xf6, 0xf2, 0xcd, 0xb2, 0xf5, 0xb3, 0xe6, 0xf3, 0xb4,
+ 0xb8, 0xb2, 0xea, 0xee, 0xf5, 0xfc, 0xda, 0xd3, 0xbd, 0xf7, 0xc3, 0xfd, 0xda,
+ 0xd8, 0xb7, 0xe1, 0xd7, 0xb8, 0xf5, 0xbe, 0xf5, 0xe7, 0xb1, 0xc4, 0xd7, 0xd9,
+ 0xbc, 0xa3, 0xf5, 0xcf, 0xc7, 0xfb, 0xd7, 0xaa, 0xd5, 0xde, 0xe5, 0xc7, 0xe5,
+ 0xe4, 0xe5, 0xe3, 0xd2, 0xbd, 0xbd, 0xb4, 0xc0, 0xe5, 0xc8, 0xdb, 0xb0, 0xf7,
+ 0xcb, 0xf8, 0xce, 0xd9, 0xc4, 0xf8, 0xd5, 0xf2, 0xb8, 0xe4, 0xef, 0xd7, 0xef,
+ 0xd3, 0xb4, 0xb8, 0xc7, 0xb9, 0xe3, 0xd8, 0xb4, 0xb3, 0xe3, 0xd9, 0xe3, 0xda,
+ 0xc0, 0xeb, 0xd4, 0xd3, 0xcb, 0xab, 0xb3, 0xfb, 0xbc, 0xa6, 0xa1, 0xf5, 0xf7,
+ 0xb7, 0xc7, 0xef, 0xb1, 0xde, 0xa1, 0xf5, 0xb6, 0xee, 0xd1, 0xd5, 0xcc, 0xe2,
+ 0xf2, 0xa6, 0xf2, 0xa7, 0xa1, 0xf5, 0xc1, 0xf3, 0xe2, 0xc8, 0xc0, 0xa1, 0xf7,
+ 0xd1, 0xf0, 0xa5, 0xc6, 0xef, 0xf7, 0xc1, 0xd7, 0xd7, 0xcb, 0xc9, 0xce, 0xba,
+ 0xf7, 0xcb, 0xf7, 0xcd, 0xf6, 0xe8, 0xc0, 0xf0, 0xf6, 0xea, 0xa1, 0xf5, 0xf6,
+ 0xe7, 0xbe, 0xe9, 0xb6, 0xec, 0xf0, 0xc0, 0xf7, 0xef, 0xa1, 0xf5, 0xf7, 0xf8,
+ 0xb2, 0xf6, 0xd1, 0xca, 0xbb, 0xb5, 0xc2, 0xa2, 0xdb, 0xde, 0xb3, 0xe8, 0xc5,
+ 0xd3, 0xc2, 0xae, 0xb3, 0xcd, 0xbb, 0xb3, 0xc0, 0xc1, 0xe3, 0xc2, 0xc5, 0xca,
+ 0xc2, 0xa3, 0xbf, 0xf5, 0xc6, 0xd8, 0xb3, 0xf7, 0xe8, 0xfc, 0xe9, 0xb5, 0xe9,
+ 0xd6, 0xe5, 0xad, 0xe4, 0xec, 0xe4, 0xfe, 0xe5, 0xab, 0xc1, 0xa4, 0xb1, 0xf4,
+ 0xe3, 0xf2, 0xb1, 0xac, 0xcb, 0xb8, 0xeb, 0xb9, 0xb6, 0xbf, 0xca, 0xde, 0xcc,
+ 0xa1, 0xe7, 0xf4, 0xc7, 0xed, 0xb0, 0xea, 0xb3, 0xeb, 0xbd, 0xae, 0xb1, 0xf1,
+ 0xb3, 0xd5, 0xc3, 0xc9, 0xb0, 0xad, 0xb5, 0xbb, 0xbb, 0xf1, 0xce, 0xc8, 0xc1,
+ 0xb1, 0xb2, 0xbe, 0xf4, 0xa4, 0xc7, 0xa9, 0xe9, 0xdc, 0xf4, 0xa6, 0xcf, 0xb5,
+ 0xbc, 0xeb, 0xd2, 0xef, 0xc9, 0xfe, 0xbb, 0xe6, 0xc2, 0xde, 0xbd, 0xc9, 0xeb,
+ 0xfe, 0xb8, 0xfe, 0xd9, 0xfa, 0xc0, 0xb0, 0xb7, 0xaa, 0xd2, 0xd5, 0xde, 0xb4,
+ 0xc5, 0xba, 0xcc, 0xd9, 0xd2, 0xa9, 0xa1, 0xf5, 0xd2, 0xcf, 0xd3, 0xac, 0xd0,
+ 0xab, 0xd0, 0xb7, 0xf3, 0xb8, 0xf1, 0xc9, 0xbd, 0xf3, 0xb0, 0xc0, 0xf4, 0xc5,
+ 0xbb, 0xa9, 0xc6, 0xd7, 0xca, 0xb6, 0xd6, 0xa4, 0xcc, 0xb7, 0xda, 0xdc, 0xbc,
+ 0xa5, 0xa1, 0xf5, 0xda, 0xdb, 0xd4, 0xf9, 0xd4, 0xde, 0xf5, 0xeb, 0xb6, 0xd7,
+ 0xb3, 0xf9, 0xf5, 0xea, 0xb5, 0xc5, 0xf5, 0xce, 0xf5, 0xed, 0xea, 0xa5, 0xbd,
+ 0xce, 0xb4, 0xc7, 0xb1, 0xdf, 0xe5, 0xe5, 0xc6, 0xc9, 0xf5, 0xb4, 0xbe, 0xb5,
+ 0xef, 0xe1, 0xb2, 0xf9, 0xef, 0xdf, 0xc1, 0xb4, 0xef, 0xdb, 0xef, 0xdc, 0xf7,
+ 0xe9, 0xef, 0xda, 0xef, 0xdd, 0xef, 0xcf, 0xef, 0xce, 0xef, 0xac, 0xf6, 0xc9,
+ 0xb9, 0xd8, 0xc2, 0xa4, 0xc4, 0xd1, 0xf6, 0xaf, 0xce, 0xed, 0xc3, 0xd2, 0xe8,
+ 0xba, 0xd4, 0xcf, 0xc0, 0xe0, 0xd4, 0xb8, 0xb5, 0xdf, 0xec, 0xac, 0xc2, 0xf8,
+ 0xe2, 0xcb, 0xe6, 0xf0, 0xc6, 0xad, 0xba, 0xfa, 0xbe, 0xa8, 0xf6, 0xf0, 0xf6,
+ 0xeb, 0xf6, 0xf4, 0xf0, 0xc8, 0xf0, 0xc4, 0xc8, 0xb5, 0xf0, 0xc6, 0xc5, 0xf4,
+ 0xf7, 0xe8, 0xc0, 0xf6, 0xc2, 0xb4, 0xf4, 0xf0, 0xc8, 0xb0, 0xc1, 0xfc, 0xc8,
+ 0xc2, 0xe0, 0xd3, 0xd1, 0xcf, 0xbd, 0xc0, 0xc8, 0xc0, 0xe6, 0xd7, 0xc4, 0xef,
+ 0xc4, 0xf5, 0xb1, 0xa6, 0xa1, 0xf5, 0xd0, 0xfc, 0xe2, 0xe3, 0xc8, 0xc1, 0xc0,
+ 0xb9, 0xb2, 0xf3, 0xea, 0xd8, 0xeb, 0xca, 0xe9, 0xb4, 0xc0, 0xbd, 0xc3, 0xd6,
+ 0xe4, 0xf2, 0xc2, 0xaf, 0xcf, 0xd7, 0xe7, 0xe7, 0xd1, 0xf7, 0xd5, 0xf7, 0xbf,
+ 0xf3, 0xed, 0xc2, 0xb7, 0xaf, 0xc0, 0xf9, 0xf1, 0xbc, 0xbe, 0xba, 0xb3, 0xef,
+ 0xc0, 0xba, 0xbc, 0xae, 0xc5, 0xb4, 0xcd, 0xc5, 0xb1, 0xe8, 0xe7, 0xcd, 0xbc,
+ 0xcc, 0xd7, 0xeb, 0xf3, 0xbf, 0xd2, 0xab, 0xeb, 0xcd, 0xbd, 0xa2, 0xd4, 0xe5,
+ 0xb0, 0xaa, 0xc4, 0xa2, 0xdd, 0xfe, 0xc2, 0xab, 0xc6, 0xbb, 0xcb, 0xd5, 0xd4,
+ 0xcc, 0xf2, 0xba, 0xc8, 0xe4, 0xf1, 0xdc, 0xbe, 0xf5, 0xb4, 0xa5, 0xd2, 0xe9,
+ 0xc6, 0xa9, 0xbe, 0xaf, 0xd2, 0xeb, 0xd4, 0xeb, 0xda, 0xde, 0xd3, 0xae, 0xc9,
+ 0xc4, 0xf5, 0xbb, 0xd4, 0xea, 0xf5, 0xee, 0xcc, 0xa4, 0xf5, 0xb7, 0xca, 0xcd,
+ 0xd6, 0xd3, 0xee, 0xf3, 0xd0, 0xe2, 0xb2, 0xfb, 0xf6, 0xb1, 0xc6, 0xae, 0xc8,
+ 0xc4, 0xbc, 0xa2, 0xdc, 0xb0, 0xe5, 0xb9, 0xcc, 0xda, 0xc9, 0xa7, 0xa1, 0xf5,
+ 0xc8, 0xfa, 0xf6, 0xfa, 0xcf, 0xcc, 0xc3, 0xe6, 0xb5, 0xb3, 0xf7, 0xf9, 0xf6,
+ 0xb4, 0xb3, 0xf6, 0xc1, 0xe4, 0xd9, 0xb3, 0xa1, 0xf5, 0xe0, 0xbf, 0xdf, 0xf9,
+ 0xcf, 0xf9, 0xd9, 0xe7, 0xca, 0xf4, 0xce, 0xa1, 0xbe, 0xe5, 0xc9, 0xe5, 0xc9,
+ 0xe3, 0xd0, 0xaf, 0xec, 0xb5, 0xea, 0xd9, 0xd3, 0xa3, 0xc0, 0xb8, 0xe8, 0xf9,
+ 0xbc, 0xdf, 0xb9, 0xe0, 0xc0, 0xc3, 0xce, 0xfe, 0xa1, 0xf5, 0xe8, 0xac, 0xf1,
+ 0xae, 0xeb, 0xca, 0xcc, 0xd9, 0xb2, 0xf8, 0xd0, 0xf8, 0xe5, 0xf1, 0xde, 0xc1,
+ 0xc0, 0xbc, 0xde, 0xba, 0xf2, 0xc3, 0xb4, 0xc0, 0xf3, 0xbb, 0xc0, 0xaf, 0xcd,
+ 0xe0, 0xa1, 0xf5, 0xc0, 0xc0, 0xc7, 0xb4, 0xbb, 0xa4, 0xd3, 0xfe, 0xd4, 0xdf,
+ 0xb3, 0xec, 0xd4, 0xbe, 0xf5, 0xd2, 0xba, 0xe4, 0xb1, 0xe7, 0xf5, 0xb8, 0xc1,
+ 0xad, 0xc0, 0xd8, 0xcc, 0xfa, 0xee, 0xf5, 0xee, 0xec, 0xef, 0xed, 0xef, 0xd4,
+ 0xb1, 0xd9, 0xb0, 0xd4, 0xc5, 0xf9, 0xc2, 0xb6, 0xcf, 0xec, 0xb9, 0xcb, 0xf2,
+ 0xab, 0xf7, 0xcf, 0xc7, 0xfd, 0xe6, 0xf4, 0xdd, 0xeb, 0xc2, 0xe2, 0xf7, 0xc3,
+ 0xc4, 0xa7, 0xf7, 0xce, 0xf7, 0xa2, 0xf7, 0xa4, 0xdd, 0xba, 0xba, 0xd7, 0xf0,
+ 0xce, 0xc8, 0xf5, 0xf7, 0xea, 0xf7, 0xf6, 0xdc, 0xb1, 0xf6, 0xb7, 0xf6, 0xb8,
+ 0xc4, 0xf6, 0xd9, 0xb2, 0xd9, 0xce, 0xdf, 0xbd, 0xc4, 0xd2, 0xc2, 0xde, 0xc2,
+ 0xcf, 0xe1, 0xdb, 0xc2, 0xcd, 0xcd, 0xe4, 0xdc, 0xb2, 0xcc, 0xaf, 0xc8, 0xa8,
+ 0xbb, 0xb6, 0xc8, 0xf7, 0xcc, 0xb2, 0xe2, 0xa4, 0xc8, 0xbf, 0xb5, 0xfe, 0xf1,
+ 0xab, 0xd1, 0xa2, 0xec, 0xfc, 0xc1, 0xfd, 0xf4, 0xa5, 0xc1, 0xfb, 0xcc, 0xfd,
+ 0xd4, 0xe0, 0xcf, 0xae, 0xb3, 0xc4, 0xa1, 0xf5, 0xb6, 0xc1, 0xca, 0xea, 0xd8,
+ 0xcd, 0xf5, 0xdc, 0xf5, 0xd9, 0xe0, 0xce, 0xdb, 0xaa, 0xd6, 0xfd, 0xbc, 0xf8,
+ 0xbc, 0xf8, 0xf6, 0xab, 0xf6, 0xb2, 0xf7, 0xb2, 0xe7, 0xd6, 0xb2, 0xfc, 0xf7,
+ 0xd2, 0xbd, 0xbe, 0xe6, 0xe7, 0xd4, 0xe0, 0xd0, 0xeb, 0xb1, 0xee, 0xf6, 0xe3,
+ 0xf7, 0xa7, 0xf7, 0xa9, 0xf0, 0xd1, 0xc5, 0xb8, 0xf7, 0xfa, 0xf6, 0xb9, 0xf6,
+ 0xba, 0xb9, 0xa8, 0xcb, 0xd5, 0xd1, 0xd2, 0xc1, 0xb5, 0xc2, 0xce, 0xbe, 0xf0,
+ 0xbd, 0xc1, 0xc9, 0xb9, 0xa1, 0xf5, 0xe8, 0xb6, 0xc7, 0xd4, 0xc7, 0xa9, 0xa1,
+ 0xf5, 0xd9, 0xdf, 0xd3, 0xa7, 0xcf, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xd5, 0xba,
+ 0xc2, 0xdc, 0xb9, 0xc6, 0xb1, 0xe4, 0xe5, 0xce, 0xc2, 0xdf, 0xef, 0xf0, 0xee,
+ 0xe5, 0xa1, 0xf5, 0xd8, 0xcc, 0xcf, 0xd4, 0xf7, 0xd0, 0xbe, 0xaa, 0xe6, 0xe4,
+ 0xd1, 0xe9, 0xcb, 0xe8, 0xcc, 0xe5, 0xf7, 0xc7, 0xf7, 0xad, 0xc1, 0xdb, 0xf7,
+ 0xac, 0xf0, 0xb8, 0xf7, 0xeb, 0xc3, 0xb9, 0xd6, 0xf6, 0xb0, 0xd3, 0xc0, 0xbf,
+ 0xe5, 0xb1, 0xcc, 0xb1, 0xf1, 0xb2, 0xb4, 0xa3, 0xb9, 0xde, 0xee, 0xbf, 0xb2,
+ 0xcf, 0xf3, 0xbc, 0xe1, 0xe9, 0xc8, 0xc3, 0xb2, 0xf7, 0xda, 0xdf, 0xd1, 0xde,
+ 0xb8, 0xd3, 0xc4, 0xf0, 0xa1, 0xf5, 0xf6, 0xa8, 0xc1, 0xe9, 0xf6, 0xb0, 0xc7,
+ 0xa7, 0xf2, 0xad, 0xd6, 0xe8, 0xf7, 0xde, 0xf7, 0xca, 0xf6, 0xd7, 0xd3, 0xa5,
+ 0xf0, 0xd8, 0xbc, 0xee, 0xd1, 0xce, 0xf2, 0xfc, 0xf6, 0xbb, 0xc8, 0xa3, 0xcc,
+ 0xfc, 0xe9, 0xad, 0xcd, 0xe5, 0xc0, 0xe9, 0xc2, 0xe1, 0xc2, 0xf9, 0xb9, 0xdb,
+ 0xf5, 0xe6, 0xd0, 0xc6, 0xcf, 0xe2, 0xd4, 0xbf, 0xc2, 0xad, 0xb2, 0xf6, 0xf7,
+ 0xc5, 0xf7, 0xe0, 0xd9, 0xe4, 0xc2, 0xd0, 0xd6, 0xf5, 0xd4, 0xde, 0xc4, 0xf7,
+ 0xf7, 0xb5, 0xc2, 0xbf, 0xe6, 0xf7, 0xc0, 0xc2, 0xda, 0xd4, 0xf5, 0xef, 0xf5,
+ 0xa6, 0xd7, 0xea, 0xf6, 0xc7, 0xc2, 0xe0, 0xf6, 0xf9, 0xf6, 0xd4, 0xf7, 0xf2,
+ 0xd1, 0xde, 0xd4, 0xe4, 0xf0, 0xd0, 0xec, 0xe0, 0xe6, 0xea, 0xd3, 0xf4, 0xf0,
+ 0xd9, 0xf0, 0xbd, 0xd3, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xbf, 0xdb, 0xc9, 0xd8, 0xce, 0xb3, 0xa7, 0xcd,
+ 0xf2, 0xd8, 0xa2, 0xd8, 0xb1, 0xd8, 0xa1, 0xe0, 0xed, 0xd8, 0xa3, 0xe5, 0xf8,
+ 0xe1, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xd3, 0xeb, 0xa1, 0xf5, 0xd8, 0xc1, 0xd8,
+ 0xec, 0xd8, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb0, 0xba, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec,
+ 0xaf, 0xa1, 0xf5, 0xc6, 0xf8, 0xe3, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xed,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xee, 0xd9, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xca, 0xa5, 0xa1, 0xf5, 0xba, 0xbb, 0xc4, 0xfe,
+ 0xe5, 0xb3, 0xa1, 0xf5, 0xe5, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2,
+ 0xcf, 0xa1, 0xf5, 0xe2, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xad, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xec, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xbf, 0xd3, 0xc5, 0xa1, 0xf5, 0xd8, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xdb, 0xd0, 0xc4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd8, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd9, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xcd, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xef, 0xd8, 0xb6, 0xdb, 0xdc,
+ 0xdb, 0xd9, 0xa1, 0xf5, 0xde, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd8, 0xde, 0xcd,
+ 0xa1, 0xf5, 0xe1, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbf, 0xaa, 0xd7,
+ 0xaf, 0xd2, 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xe3,
+ 0xa1, 0xf5, 0xba, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xc7, 0xa4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xb9, 0xea, 0xb8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbb, 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xeb, 0xae, 0xd9, 0xdb, 0xa1, 0xf5, 0xe3, 0xe1, 0xa1, 0xf5, 0xe3, 0xe2,
+ 0xe3, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xed, 0xa1,
+ 0xf5, 0xe7, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xf8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xb4, 0xdc, 0xb5, 0xf2, 0xae, 0xa1, 0xf5, 0xda,
+ 0xf8, 0xda, 0xf5, 0xa1, 0xf5, 0xda, 0xf6, 0xa1, 0xf5, 0xda, 0xe3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcc,
+ 0xe5, 0xd8, 0xf4, 0xa1, 0xf5, 0xd8, 0xfb, 0xa1, 0xf5, 0xd9, 0xa1, 0xa1, 0xf5,
+ 0xd9, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd8, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdf, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xd0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe6, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xa9, 0xa1,
+ 0xf5, 0xe1, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xd1, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdf, 0xaf, 0xec, 0xfd, 0xec, 0xfe, 0xe2, 0xed, 0xa1, 0xf5, 0xe2,
+ 0xe5, 0xa1, 0xf5, 0xe2, 0xe7, 0xe2, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd0, 0xda, 0xd0, 0xc3, 0xbb, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xab, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc8, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xbf, 0xbc, 0xea, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xbb, 0xe8,
+ 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xaf,
+ 0xeb, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6,
+ 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf0,
+ 0xa1, 0xf5, 0xe1, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xae, 0xa1, 0xf5, 0xf0, 0xdb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xeb, 0xc0, 0xa1, 0xf5, 0xdc, 0xb6, 0xa1, 0xf5, 0xdc, 0xba, 0xdc, 0xbb,
+ 0xa1, 0xf5, 0xdc, 0xb7, 0xa1, 0xf5, 0xdc, 0xb9, 0xf5, 0xf4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xda, 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9,
+ 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xa5, 0xd9, 0xa6,
+ 0xd9, 0xa8, 0xd6, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6, 0xb1, 0xa1, 0xf5, 0xe1,
+ 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xb0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xda, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcc, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xc6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf,
+ 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdf, 0xca, 0xa1, 0xf5, 0xe0, 0xf2, 0xc5, 0xf7, 0xa1, 0xf5, 0xdb,
+ 0xe8, 0xdb, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xe9, 0xa1, 0xf5, 0xc7, 0xf0,
+ 0xdb, 0xe6, 0xdb, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xe7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xa7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xdf,
+ 0xe6, 0xdb, 0xe5, 0xb5, 0xe5, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe1, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xb5, 0xa1, 0xf5,
+ 0xe1, 0xb8, 0xc1, 0xeb, 0xe1, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xfa, 0xe0, 0xf9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xde, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf1, 0xe2, 0xef,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xaf, 0xea, 0xa7, 0xec,
+ 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xc7, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xde, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xd3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xbe, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xc3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8,
+ 0xc4, 0xa1, 0xf5, 0xb9, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xab, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xb3, 0xa1, 0xf5, 0xe3, 0xf9, 0xe3, 0xfa, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe3, 0xef, 0xe3, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xee, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc5, 0xa2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xc8, 0xb2, 0xa1, 0xf5, 0xea, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf4,
+ 0xa1, 0xf5, 0xb5, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe7, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xaf, 0xe7, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xb7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcb, 0xfb, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xf4,
+ 0xa1, 0xf5, 0xb0, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xc7, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xbe, 0xa1, 0xf5, 0xdc, 0xc5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xcc, 0xdc, 0xb8, 0xdc, 0xcd, 0xdc, 0xcb, 0xa1, 0xf5, 0xdc, 0xd2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xb0, 0xa1, 0xf5, 0xf2, 0xb1, 0xd8,
+ 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xc3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xfb, 0xba, 0xaa, 0xda, 0xfc, 0xdb, 0xa2, 0xa1,
+ 0xf5, 0xda, 0xe7, 0xda, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xb4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xb6, 0xa1, 0xf5, 0xd9,
+ 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xd9, 0xef, 0xb1, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xc7,
+ 0xc0, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xd2, 0xa1, 0xf5, 0xdf, 0xe7, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb6, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf,
+ 0xda, 0xdf, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xec,
+ 0xdb, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb8, 0xb4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6,
+ 0xad, 0xcf, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbf, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xe1, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb4, 0xc3, 0xa1, 0xf5, 0xe2, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5,
+ 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe2, 0xfe, 0xd0, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbf, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb8, 0xf1,
+ 0xa1, 0xf5, 0xde, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xea, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xc3, 0xea, 0xc4, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xd4, 0xe8, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb9, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xcf, 0xa1, 0xf5, 0xbc, 0xcf,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xd5, 0xa1, 0xf5, 0xe8,
+ 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xad, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe8, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xe3, 0xe9,
+ 0xe5, 0xa1, 0xf5, 0xb1, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xb1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xdd, 0xa1, 0xf5, 0xc8,
+ 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb2, 0xe4, 0xa7, 0xe4, 0xa8, 0xa1, 0xf5,
+ 0xe4, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbd, 0xe0, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xa6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc4, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xea, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xe6, 0xe7,
+ 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xce, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xb2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xf1, 0xa1, 0xf5, 0xed, 0xed, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xbc, 0xc5, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xed, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf5, 0xd6, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6,
+ 0xfd, 0xa1, 0xf5, 0xee, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xe8, 0xde, 0xc7, 0xa1, 0xf5, 0xdb, 0xcf, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xeb, 0xd1, 0xca, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb,
+ 0xd3, 0xa1, 0xf5, 0xeb, 0xd2, 0xa1, 0xf5, 0xf4, 0xad, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc6, 0xbb, 0xdc, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xe6, 0xdc,
+ 0xfb, 0xc9, 0xbb, 0xa1, 0xf5, 0xdc, 0xda, 0xa1, 0xf5, 0xdc, 0xd3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xdd, 0xdc, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xd6, 0xdc, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1,
+ 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe5, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb,
+ 0xa4, 0xdb, 0xa5, 0xdb, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xc6, 0xee, 0xc5,
+ 0xda, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb1, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xbe, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6,
+ 0xe0, 0xb9, 0xcc, 0xbe, 0xbb, 0xa1, 0xf5, 0xd8, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd8, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc7, 0xe6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xea, 0xdf, 0xee,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xc1, 0xdf, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf,
+ 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdb, 0xf4, 0xdb, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdb, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd8, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xa2, 0xed, 0xa3, 0xed,
+ 0xa4, 0xed, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xa8, 0xa1, 0xf5,
+ 0xe3, 0xa6, 0xe3, 0xa7, 0xa1, 0xf5, 0xe3, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xb1, 0xa1, 0xf5, 0xde, 0xdc, 0xa1, 0xf5, 0xde,
+ 0xda, 0xde, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xec, 0xb7, 0xec, 0xb9, 0xec, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xea,
+ 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe8, 0xf1, 0xe8, 0xe0, 0xe8, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6,
+ 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe8, 0xe4, 0xe8, 0xe6, 0xa1, 0xf5, 0xe8, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb4,
+ 0xe4, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb7, 0xa1,
+ 0xf5, 0xe4, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xbc, 0xa1, 0xf5, 0xcd, 0xbf,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xfe, 0xe1, 0xf9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xfc, 0xe2, 0xa1, 0xe1, 0xfb, 0xa1, 0xf5, 0xe7,
+ 0xee, 0xe7, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xf2, 0xa1, 0xf5, 0xe7, 0xf1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xac, 0xa1, 0xf5, 0xea, 0xb2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xee, 0xb3, 0xa1, 0xf5, 0xf0, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0,
+ 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xf4, 0xed, 0xf2, 0xed, 0xf3, 0xa1, 0xf5, 0xed, 0xc8,
+ 0xed, 0xc7, 0xa1, 0xf5, 0xb2, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xec, 0xee, 0xa1, 0xf5, 0xec, 0xef, 0xec, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xef,
+ 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xc7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf3, 0xcb, 0xf3, 0xc5, 0xf3, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe7, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xee, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb0, 0xb7, 0xeb, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf4, 0xa8, 0xf4, 0xb1, 0xa1, 0xf5, 0xdc, 0xfc, 0xdc, 0xfa, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xa2, 0xa1, 0xf5,
+ 0xdc, 0xeb, 0xdc, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xf2, 0xa1, 0xf5, 0xdc, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb2, 0xe7, 0xa1, 0xf5, 0xbc, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xb6, 0xa1, 0xf5, 0xf2, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xbb, 0xb2, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xad, 0xf4, 0xac, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf1, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xc6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf4, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb8, 0xcf, 0xa1, 0xf5, 0xf5, 0xc0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xca,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xa3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xae, 0xdb, 0xad, 0xdb, 0xac, 0xa1, 0xf5, 0xf4, 0xfb, 0xf4, 0xfc,
+ 0xf4, 0xfd, 0xee, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xec, 0xf6,
+ 0xc0, 0xa1, 0xf5, 0xf7, 0xd4, 0xdb, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xc6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb9, 0xd0, 0xdb, 0xc3, 0xa1,
+ 0xf5, 0xd8, 0xd0, 0xa1, 0xf5, 0xe0, 0xa3, 0xe0, 0xa4, 0xdf, 0xfe, 0xa1, 0xf5,
+ 0xdf, 0xfd, 0xa1, 0xf5, 0xdf, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe0, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc9, 0xb6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe0, 0xf5, 0xe0, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdb, 0xfa, 0xdc, 0xa5, 0xdc, 0xa4, 0xdc, 0xa3, 0xa1, 0xf5, 0xdb,
+ 0xfc, 0xdc, 0xa1, 0xa1, 0xf5, 0xdb, 0xef, 0xdd, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdc, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xbc, 0xe6,
+ 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xab, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xed, 0xe1, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xc1, 0xe1, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xc4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xd5, 0xa1, 0xf5, 0xe2, 0xd8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xae, 0xa1, 0xf5, 0xe3, 0xad, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbe, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xfd,
+ 0xa1, 0xf5, 0xde, 0xe5, 0xb5, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde,
+ 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xe1, 0xa1, 0xf5, 0xb6, 0xde,
+ 0xc6, 0xfe, 0xbe, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xe3, 0xde,
+ 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xea, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb2, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe8, 0xf5, 0xa1, 0xf5, 0xe8, 0xf4, 0xe8, 0xf6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe8, 0xf8, 0xd8, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb1, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xec, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xe8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xeb, 0xb4, 0xb5, 0xed, 0xe4, 0xca, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xba, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xc4, 0xa1, 0xf5, 0xc4, 0xd7, 0xa1, 0xf5,
+ 0xe4, 0xcb, 0xa1, 0xf5, 0xe4, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcd, 0xe9, 0xbe, 0xd6,
+ 0xcc, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea,
+ 0xf6, 0xe2, 0xa7, 0xe2, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xa5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc3, 0xd0, 0xed, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xf6, 0xa1, 0xf5, 0xed, 0xf7, 0xa1, 0xf5, 0xce, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd1, 0xed, 0xce, 0xb9, 0xe8, 0xed, 0xcf,
+ 0xa1, 0xf5, 0xec, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc0, 0xeb, 0xa1, 0xf5, 0xbd, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xcc, 0xa1, 0xf5, 0xf3, 0xd3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf3, 0xd4, 0xf3, 0xd5, 0xa1, 0xf5, 0xf3, 0xce, 0xa1, 0xf5,
+ 0xf3, 0xd1, 0xf3, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xcd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd5, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xc6, 0xa1, 0xf5, 0xf1,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xf5, 0xa1,
+ 0xf5, 0xeb, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xeb, 0xe3, 0xeb, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xb4, 0xf4, 0xb6, 0xa1, 0xf5, 0xf4, 0xb7, 0xa1, 0xf5,
+ 0xe5, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xb6,
+ 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xb3, 0xdd, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xf0, 0xdd, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xc5, 0xf2, 0xc4, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xca, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xc8, 0xec, 0xee, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xf3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xfb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc1, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xcd, 0xe5, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xd2, 0xdb,
+ 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xb3, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdb, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb2, 0xa1, 0xf5, 0xb7, 0xd3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xee, 0xcc, 0xee, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xca, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe3, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8,
+ 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb4, 0xf6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xae, 0xdf, 0xf6, 0xdf, 0xf7,
+ 0xe0, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xa7, 0xdc, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe6, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xc4, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe1, 0xd1, 0xa1, 0xf5, 0xe1, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xcc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xa2, 0xa1, 0xf5, 0xe5,
+ 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xa2, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xfe, 0xde, 0xef,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xde, 0xeb, 0xde, 0xde, 0xa1, 0xf5, 0xde, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xde, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xed, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xec, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xe2, 0xe8,
+ 0xe2, 0xe8, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe9, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xb1, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xfb, 0xa1, 0xf5, 0xe9, 0xa3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xec, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xc8, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa5, 0xc7,
+ 0xe8, 0xed, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xed,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xcd, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xa5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xd0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xcc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xcd, 0xa1, 0xf5, 0xcd, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe2, 0xa9, 0xe2, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xfd, 0xe7, 0xfe,
+ 0xe7, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe5, 0xb8, 0xa1, 0xf5, 0xee, 0xb4, 0xf0, 0xf0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xee, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xf3,
+ 0xa1, 0xf5, 0xed, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xcb, 0xa1, 0xf5, 0xed,
+ 0xd2, 0xc8, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xba, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xfc, 0xa1, 0xf5, 0xef,
+ 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xd8, 0xf3, 0xda, 0xf4, 0xd2, 0xf4, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcf, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xb0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xba, 0xca, 0xdd, 0xcf, 0xa1, 0xf5, 0xdd, 0xd2,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xbd,
+ 0xdd, 0xc3, 0xdd, 0xbe, 0xdd, 0xbf, 0xa1, 0xf5, 0xdd, 0xd5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xcc, 0xa1, 0xf5,
+ 0xdd, 0xc8, 0xdd, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb9,
+ 0xbd, 0xa1, 0xf5, 0xdd, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf2, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xcb, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1,
+ 0xcb, 0xf1, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xcc, 0xa1, 0xf5,
+ 0xea, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xfd, 0xa1, 0xf5, 0xda, 0xaa, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xaf, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xda, 0xb1, 0xee, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xdc, 0xa1, 0xf5, 0xea, 0xdb,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc5, 0xa1, 0xf5, 0xf5, 0xca, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xf7, 0xe9, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xd5, 0xa1, 0xf5, 0xe5, 0xd6, 0xdb, 0xa9, 0xa1, 0xf5, 0xdb, 0xb2,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xa2, 0xf4, 0xfe, 0xa1, 0xf5,
+ 0xf5, 0xa1, 0xa1, 0xf5, 0xee, 0xd5, 0xa1, 0xf5, 0xee, 0xd8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xee, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xd7, 0xee, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe3, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xf1, 0xda, 0xed, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xfc, 0xa1, 0xf5, 0xe2, 0xc0, 0xa1,
+ 0xf5, 0xed, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcf, 0xc9, 0xd8, 0xf1, 0xa1, 0xf5, 0xd9,
+ 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xdd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe0, 0xc3, 0xa1, 0xf5, 0xe0, 0xc1, 0xe0, 0xc4, 0xdf, 0xef, 0xa1, 0xf5, 0xe0,
+ 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xb2, 0xa1, 0xf5,
+ 0xe0, 0xc7, 0xe0, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xf7, 0xdb, 0xee, 0xeb, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xba, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xc1, 0xa1, 0xf5,
+ 0xe6, 0xca, 0xa1, 0xf5, 0xeb, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe1, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xcf, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xb0, 0xa1, 0xf5, 0xe1, 0xe6, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe3, 0xbb, 0xe3, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xad, 0xea, 0xae, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb4, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xf7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xf8, 0xde, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xde,
+ 0xf4, 0xa1, 0xf5, 0xcc, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xce, 0xe6, 0xb4, 0xb7,
+ 0xa1, 0xf5, 0xde, 0xf5, 0xa1, 0xf5, 0xde, 0xf6, 0xa1, 0xf5, 0xde, 0xfa, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xd2, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe9, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xa8,
+ 0xb4, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xa9, 0xe9, 0xab, 0xe9, 0xa5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb4, 0xaa, 0xa1, 0xf5, 0xe9, 0xa2, 0xe9, 0xb1, 0xe9, 0xb2, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd8, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xa7,
+ 0xa1, 0xf5, 0xec, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xea, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe7, 0xa1, 0xf5, 0xe4, 0xe9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe4, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe1,
+ 0xb3, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe4, 0xe6, 0xe4, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdc, 0xe4, 0xec, 0xd2, 0xec, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xf9, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd5, 0xe8, 0xe7, 0xe2,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xb3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf0, 0xf1, 0xa1, 0xf5, 0xf0, 0xe2, 0xf0, 0xf3, 0xb1, 0xd4,
+ 0xa1, 0xf5, 0xf0, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd6, 0xed, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc2, 0xe3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb0,
+ 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb2,
+ 0xdf, 0xa1, 0xf5, 0xf3, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xe3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xd3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe7, 0xb0, 0xe7, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xee, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xc7, 0xf4, 0xc8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd6, 0xfa, 0xa1, 0xf5, 0xeb, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xee,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb,
+ 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xe1, 0xa1, 0xf5, 0xf4, 0xba, 0xf4, 0xb9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd,
+ 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xd7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xd8, 0xdd,
+ 0xd9, 0xa1, 0xf5, 0xdd, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xdd, 0xa1, 0xf5, 0xdd, 0xdf, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xa6, 0xd2,
+ 0xa9, 0xa1, 0xf5, 0xdd, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xcc,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xd9, 0xa1, 0xf5, 0xf2, 0xdd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf1, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xfe, 0xb4, 0xa5, 0xa1, 0xf5, 0xda, 0xb2, 0xda, 0xb4, 0xda,
+ 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xb3, 0xda, 0xb7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xc7, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xf7, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf5, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xd0, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xfb, 0xe9, 0xfa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xd9, 0xa1, 0xf5, 0xe5, 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd4, 0xc7, 0xda, 0xf9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xcd, 0xaa, 0xf5, 0xa5, 0xee, 0xe8, 0xa1, 0xf5, 0xee, 0xe6, 0xee, 0xda,
+ 0xee, 0xdb, 0xee, 0xdd, 0xa1, 0xf5, 0xee, 0xe1, 0xef, 0xa5, 0xee, 0xea, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xee, 0xe3, 0xee, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xda, 0xf3, 0xf6, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xbd, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xfe, 0xa1,
+ 0xf5, 0xf1, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xec, 0xa1, 0xf5, 0xf6, 0xbc, 0xd9, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd9, 0xc7, 0xc0, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd9, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xd8, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xd7, 0xa1, 0xf5, 0xe0, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xc5, 0xdf, 0xe9,
+ 0xe0, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdc, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdc, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc9,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe6, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xef, 0xe1, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xd0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe0, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xdb, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xda, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xa8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe2, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xaf, 0xea, 0xa8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde,
+ 0xd2, 0xa1, 0xf5, 0xbf, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc1, 0xcc, 0xde, 0xfb, 0xde, 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xbc, 0xe9, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe8, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xc0, 0xa1,
+ 0xf5, 0xe9, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xbf,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xf8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xe6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xfe, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe4, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc5, 0xbd, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xf1, 0xa1, 0xf5,
+ 0xe4, 0xef, 0xa1, 0xf5, 0xe4, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4,
+ 0xd3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xec, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb4, 0xf4, 0xe2, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xf8, 0xf0,
+ 0xfd, 0xa1, 0xf5, 0xf0, 0xfa, 0xa1, 0xf5, 0xf1, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xb3, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xa6, 0xa1, 0xf5, 0xd8, 0xba, 0xa1,
+ 0xf5, 0xed, 0xda, 0xa1, 0xf5, 0xb2, 0xea, 0xed, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb1, 0xe2, 0xa1, 0xf5, 0xf1, 0xbf, 0xa1, 0xf5,
+ 0xf1, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xe4, 0xa1, 0xf5, 0xb9, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xeb,
+ 0xa1, 0xf5, 0xd4, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf4, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xb9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7,
+ 0xb5, 0xa1, 0xf5, 0xe7, 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xb8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xeb, 0xf4, 0xec, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xbc, 0xeb, 0xf0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xf5, 0xa1, 0xf5, 0xdd, 0xf2,
+ 0xa1, 0xf5, 0xdd, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xf3, 0xdd, 0xf4, 0xdd, 0xe8, 0xdd, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdd, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd,
+ 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xe1, 0xa1, 0xf5,
+ 0xb1, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xe2, 0xf2, 0xe0, 0xc0,
+ 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xe4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1,
+ 0xd1, 0xa1, 0xf5, 0xf2, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd5, 0xa1, 0xf5, 0xf1, 0xd3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea,
+ 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xea, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xd4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xd5, 0xd3, 0xbb, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf5, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb,
+ 0xb3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xa8, 0xf5, 0xaa, 0xa1, 0xf5, 0xd2, 0xbf, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xee, 0xef, 0xee, 0xee, 0xa1, 0xf5, 0xee, 0xf0, 0xa1, 0xf5,
+ 0xee, 0xf7, 0xef, 0xa2, 0xef, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xfe, 0xef,
+ 0xa8, 0xee, 0xf1, 0xf6, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xa9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xba, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xd3, 0xd9, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xd9,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd8, 0xdb, 0xdb, 0xbd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xe1, 0xdf, 0xd8, 0xb6, 0xf1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe0, 0xd9, 0xd1, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe0, 0xdc, 0xa1, 0xf5, 0xdf, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xd7, 0xe1, 0xc0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe1, 0xbd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xdc, 0xa1, 0xf5, 0xe2, 0xd0, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb1, 0xef, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xfe, 0xa1, 0xf5, 0xbe, 0xef, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xa7, 0xde, 0xd8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xcb, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xac, 0xa1, 0xf5, 0xe9, 0xc8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xfd, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe9, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xa7, 0xa1, 0xf5, 0xf2, 0xa3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc0, 0xd4, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xf8, 0xe4, 0xf7, 0xe4,
+ 0xf9, 0xe4, 0xea, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xb3, 0xce, 0xa1, 0xf5, 0xe4, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4,
+ 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xec,
+ 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xaf, 0xe7, 0xf6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe8, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xfb, 0xf0, 0xf9, 0xf0, 0xfe, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xa1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xed, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xdf, 0xec, 0xfa, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xa1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xc1, 0xa1, 0xf5, 0xf3, 0xe6, 0xa1, 0xf5, 0xf3,
+ 0xe8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xdb,
+ 0xf4, 0xda, 0xf4, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe7, 0xbd, 0xe7, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xc1, 0xe7, 0xc2,
+ 0xe7, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xe5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc6, 0xcc, 0xf4, 0xbc, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xa2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xfd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xe8, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xea,
+ 0xdd, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd,
+ 0xfb, 0xdc, 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xbd, 0xa1, 0xf5, 0xf2, 0xf6, 0xf2, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xd0, 0xab, 0xce, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xf3, 0xa1, 0xf5, 0xf2, 0xfa, 0xa1, 0xf5, 0xf2, 0xef, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xc1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda,
+ 0xc2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd6, 0xdc, 0xa1, 0xf5,
+ 0xea, 0xe3, 0xa1, 0xf5, 0xea, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf5, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xda, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdb, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb5, 0xa6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf5, 0xac, 0xd5, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xee, 0xf2, 0xef, 0xab, 0xef, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xef, 0xb2, 0xee, 0xfa, 0xef, 0xaf, 0xa1, 0xf5, 0xef, 0xb0, 0xa1, 0xf5, 0xf6,
+ 0xc8, 0xa1, 0xf5, 0xef, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xcf, 0xe3, 0xcd, 0xa1, 0xf5, 0xd1, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xac, 0xa1, 0xf5, 0xf6,
+ 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf2, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xc4, 0xb2, 0xb8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6,
+ 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf7, 0xc9, 0xd0, 0xd0, 0xf6, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd8, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xd5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xe0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe0, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xd4, 0xa1, 0xf5, 0xe6, 0xd3, 0xe6, 0xcd,
+ 0xa1, 0xf5, 0xe6, 0xc8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd4, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe1, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xdd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe1, 0xe8, 0xed, 0xad, 0xba, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xa8, 0xa1, 0xf5, 0xdf, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xd5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xd3, 0xa1,
+ 0xf5, 0xe9, 0xd8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xec, 0xe9,
+ 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xab, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc2,
+ 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe4, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xc7, 0xa1, 0xf5, 0xec, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xb3,
+ 0xa1, 0xf5, 0xe1, 0xfd, 0xe1, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf1, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xac, 0xf1, 0xa2, 0xf1, 0xa9, 0xa1,
+ 0xf5, 0xf1, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xd7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xf4, 0xa1,
+ 0xf5, 0xf3, 0xf6, 0xf3, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xf8,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf4, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe7, 0xc8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc5, 0xd5, 0xf1, 0xf0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xec, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xcb, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xbf, 0xa1, 0xf5, 0xdc, 0xe9, 0xa1, 0xf5, 0xdd, 0xdb, 0xde, 0xa8, 0xdd, 0xa1,
+ 0xdd, 0xde, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdc, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xb5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdc, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa5,
+ 0xf2, 0xfb, 0xa1, 0xf5, 0xf3, 0xa2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd0,
+ 0xfa, 0xda, 0xbb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xca,
+ 0xda, 0xcc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd2, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xde,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xe1, 0xf5, 0xe4, 0xd3, 0xe2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xa6, 0xa1, 0xf5, 0xf5, 0xad, 0xf5, 0xaf,
+ 0xf5, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xc3, 0xef, 0xc4, 0xef,
+ 0xba, 0xa1, 0xf5, 0xd5, 0xe0, 0xef, 0xaa, 0xa1, 0xf5, 0xef, 0xbc, 0xa1, 0xf5,
+ 0xef, 0xb9, 0xef, 0xbe, 0xee, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xd5, 0xa1, 0xf5, 0xe3, 0xd0, 0xd1,
+ 0xcb, 0xa1, 0xf5, 0xe3, 0xd1, 0xe3, 0xd3, 0xa1, 0xf5, 0xe3, 0xd4, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb2, 0xb5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xd6, 0xf6, 0xd8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf0, 0xb7, 0xf7, 0xe6, 0xa1, 0xf5, 0xf7, 0xe5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xfc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe0, 0xea, 0xdf, 0xe2, 0xa1, 0xf5, 0xe0, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe1, 0xda, 0xe0, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xfb,
+ 0xa1, 0xf5, 0xb1, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xa9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xdd, 0xa1, 0xf5, 0xe8, 0xdf, 0xbc, 0xd6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xbd, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbd, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xed, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe5, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe1, 0xfd, 0xe2, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe8, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xea, 0xb5, 0xa1, 0xf5, 0xea, 0xb4, 0xa1, 0xf5, 0xf1, 0xaa, 0xa1, 0xf5,
+ 0xf0, 0xf7, 0xf0, 0xef, 0xf0, 0xab, 0xa1, 0xf5, 0xee, 0xac, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe1, 0xed,
+ 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xfc, 0xa1, 0xf5, 0xf3, 0xe5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xfe, 0xf3, 0xd9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xc0, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xdd, 0xe7, 0xca, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf4, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xe3, 0xf4, 0xea, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf3, 0xc1, 0xa1, 0xf5, 0xee, 0xc0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf1, 0xef, 0xeb, 0xfe, 0xa1, 0xf5, 0xeb, 0xfb, 0xeb, 0xfd, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc2, 0xa6, 0xf4, 0xbd, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xde, 0xae, 0xde, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xf7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xcc, 0xea, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdc, 0xf6, 0xde, 0xb6, 0xde, 0xb3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdd, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xa9, 0xa1, 0xf5, 0xf3, 0xaa, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xfc,
+ 0xd5, 0xdd, 0xf3, 0xb1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf1, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xed, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xec, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd5, 0xa1, 0xf5,
+ 0xd6, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5,
+ 0xc0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf5, 0xc4, 0xe5, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc3, 0xd1, 0xf5, 0xb0, 0xc8, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xca, 0xa1,
+ 0xf5, 0xef, 0xc7, 0xd5, 0xeb, 0xd5, 0xa1, 0xa1, 0xf5, 0xef, 0xc8, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xcc, 0xa1, 0xf5, 0xf6,
+ 0xca, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xd6,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xf4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xba, 0xfd, 0xa1, 0xf5, 0xe2, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xcc, 0xf6, 0xda, 0xa1, 0xf5, 0xf6, 0xdc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xbb, 0xa1, 0xf5, 0xf0, 0xbc,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xed, 0xea, 0xf6, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf7, 0xf6, 0xb3, 0xd9,
+ 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xf6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xa1, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xde, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xdf, 0xa3, 0xa1, 0xf5, 0xe1, 0xa6, 0xa1, 0xf5, 0xea, 0xd6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xec, 0xf2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xde, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe4, 0xf3, 0xe3, 0xf8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xde, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xb6, 0xf1, 0xb0, 0xf0, 0xdc,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe4,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xa1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xbb, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xc0,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xf9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf4, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdd, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xb2, 0xa1, 0xf5, 0xf3, 0xb3, 0xf3, 0xa8, 0xa1,
+ 0xf5, 0xf6, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xad, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf2, 0xb1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xc7, 0xfe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xda, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xc3, 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xa5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf5, 0xf8, 0xa1, 0xf5, 0xd8, 0xd3, 0xea, 0xde, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xd4, 0xe3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xbf, 0xa1, 0xf5, 0xea, 0xa4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xda, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xb5, 0xf5, 0xb2, 0xef, 0xd8, 0xc1, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xf8, 0xa1, 0xf5, 0xef, 0xcb, 0xa1, 0xf5, 0xef,
+ 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xf6, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xb6, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xbe,
+ 0xa1, 0xf5, 0xe6, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xec, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe6, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xc2, 0xa1, 0xf5,
+ 0xf7, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xd2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf6, 0xe9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xe1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf0, 0xc3, 0xf0, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xc1, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xd8, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdf, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe8, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xcd, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe9, 0xda, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xaa, 0xa1, 0xf5, 0xe3,
+ 0xf1, 0xe4, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xac,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe6, 0xec, 0xf2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xd8, 0xa1,
+ 0xf5, 0xe7, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf4, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xde, 0xbc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd9, 0xf9, 0xf2, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xcf, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xef, 0xa1,
+ 0xf5, 0xf6, 0xa3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xda, 0xda, 0xd7, 0xab, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb2,
+ 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xec, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xb3, 0xef, 0xde, 0xef, 0xe0, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xa5, 0xef, 0xea, 0xa1, 0xf5, 0xef, 0xd2, 0xa1,
+ 0xf5, 0xef, 0xa1, 0xa1, 0xf5, 0xf6, 0xcb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8,
+ 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf2, 0xaa, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xca, 0xa1, 0xf5, 0xe2, 0xc9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf7, 0xc4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf6, 0xec, 0xf6, 0xed, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xef, 0xa1,
+ 0xf5, 0xf6, 0xf2, 0xf6, 0xf3, 0xf6, 0xf6, 0xf6, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xee, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xb5, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf0, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xed, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xfc, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xd0, 0xa1, 0xf5,
+ 0xe8, 0xc0, 0xe8, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xe5, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xa8,
+ 0xe8, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xdb, 0xc7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xed, 0xe5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xe7, 0xd7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf1, 0xf7, 0xa1, 0xf5, 0xa1, 0xf5, 0xd0, 0xc6, 0xf4, 0xbf, 0xa1, 0xf5,
+ 0xdc, 0xd7, 0xde, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdc,
+ 0xc2, 0xde, 0xad, 0xa1, 0xf5, 0xde, 0xbf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf2, 0xd3, 0xf2, 0xee, 0xa1, 0xf5, 0xf3, 0xb7, 0xf3, 0xb6, 0xa1, 0xf5, 0xf1,
+ 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbb, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xdb, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xb6, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xef, 0xa6, 0xef, 0xe6, 0xa1, 0xf5, 0xef, 0xe8, 0xa1, 0xf5,
+ 0xef, 0xe2, 0xa1, 0xf5, 0xa1, 0xf5, 0xc1, 0xcd, 0xef, 0xd0, 0xef, 0xeb, 0xa1,
+ 0xf5, 0xee, 0xfc, 0xa1, 0xf5, 0xef, 0xe4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xef, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xdb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xa9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xcd, 0xc0, 0xa1, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xe3, 0xa1, 0xf5,
+ 0xe6, 0xf2, 0xe6, 0xf3, 0xe6, 0xef, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xf8, 0xca, 0xc7, 0xa1, 0xf5,
+ 0xf6, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf6, 0xfc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf0, 0xc9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xca, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf4, 0xa1, 0xf5, 0xf7, 0xf3,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xb6, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xf6, 0xb5, 0xa1, 0xf5, 0xd9, 0xd0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbf, 0xf9, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xdf, 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe9, 0xb7, 0xa1, 0xf5, 0xe3, 0xe3, 0xe4, 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xec, 0xdf, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xb5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xc3, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf4, 0xcf, 0xe6, 0xfe, 0xa1, 0xf5, 0xe7, 0xd3, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc0, 0xdb, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xde, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xc0, 0xdd, 0xfc, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc3, 0xef, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xea, 0xe1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdb, 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xee, 0xa1, 0xf5,
+ 0xbb, 0xb7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xcb, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xec, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xe6, 0xf5, 0xe6, 0xee, 0xe6, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xe5, 0xf7, 0xa3, 0xf7,
+ 0xa5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xcf, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xbd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xbc, 0xb9, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5,
+ 0xba, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd9, 0xe6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xae,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd4,
+ 0xdc, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xeb, 0xac, 0xc0, 0xec, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf1, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf0, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xea, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xc2, 0xab, 0xd9, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf4, 0xb5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xea, 0xeb, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xd9, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf5, 0xe9, 0xf5, 0xf0,
+ 0xf5, 0xd1, 0xf5, 0xc8, 0xf5, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9,
+ 0xf6, 0xa1, 0xf5, 0xef, 0xd9, 0xa1, 0xf5, 0xef, 0xec, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xd3, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe6, 0xf6, 0xa1, 0xf5, 0xe6, 0xe8, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe5, 0xf7,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xa8, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6,
+ 0xe4, 0xf7, 0xa6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xe6, 0xa1, 0xf5, 0xf7, 0xa1,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xd2, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xba,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xed, 0xe8,
+ 0xba, 0xcd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xdf, 0xac, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe8, 0xef, 0xe9,
+ 0xa1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xd3, 0xb8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xdd, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xde, 0xc2, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xee, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd1, 0xe7, 0xf6, 0xc5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe9, 0xf1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc0, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xdf, 0xa1, 0xf5, 0xf7,
+ 0xae, 0xf6, 0xe0, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xd1, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xd3, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf0, 0xd6, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xf0, 0xd4, 0xf0, 0xd5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xc2, 0xf0,
+ 0xc2, 0xa1, 0xf5, 0xb7, 0xb2, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xfb, 0xa1, 0xf5, 0xa1, 0xf5, 0xec,
+ 0xb4, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xc4, 0xf6, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xe5, 0xb0, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xfd, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xbd, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xc0, 0xbe, 0xf5, 0xf3, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xce, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7,
+ 0xc6, 0xa1, 0xf5, 0xa1, 0xf5, 0xf7, 0xaf, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xd3, 0xae, 0xa1, 0xf5, 0xa1, 0xf5, 0xdd, 0xba, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe0,
+ 0xec, 0xdf, 0xad, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3,
+ 0xd6, 0xa1, 0xf5, 0xf4, 0xd0, 0xa1, 0xf5, 0xe7, 0xda, 0xf4, 0xee, 0xa1, 0xf5,
+ 0xd9, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf1, 0xe1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xb4, 0xda,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xef, 0xe7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe2, 0xc3, 0xa1, 0xf5, 0xa1, 0xf5, 0xf6, 0xdd,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf6, 0xbe, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf3, 0xbd, 0xf4, 0xf5, 0xf5,
+ 0xf2, 0xf5, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xda, 0xdd, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xf2, 0xa8, 0xc8, 0xa7, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xe6, 0xf8, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xf0, 0xb5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xed, 0xb0, 0xe8, 0xf9, 0xa1, 0xf5, 0xb1, 0xee, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xe3, 0xce, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xf6, 0xe2, 0xf0, 0xbf, 0xe4, 0xd9, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xd0, 0xe2, 0xc0, 0xef, 0xa1, 0xf5,
+ 0xba, 0xe3, 0xd7, 0xb1, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+ 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1,
+ 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5, 0xa1, 0xf5,
+};
+
+} // namespace FQTerm
diff --git a/src/utilities/fqterm_convert.h b/src/utilities/fqterm_convert.h
new file mode 100644
index 0000000..d7b226c
--- /dev/null
+++ b/src/utilities/fqterm_convert.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_CONVERT_H
+#define FQTERM_CONVERT_H
+
+namespace FQTerm {
+
+class FQTermConvert {
+ public:
+ FQTermConvert();
+ ~FQTermConvert();
+
+ char *G2B(const char *string, int length);
+ char *B2G(const char *string, int length);
+
+ private:
+ void g2b(unsigned char c1, unsigned char c2, char *s);
+ void b2g(unsigned char c1, unsigned char c2, char *s);
+
+ static unsigned char GtoB[];
+ static unsigned char BtoG[];
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_CONVERT_H
diff --git a/src/utilities/fqterm_http.cpp b/src/utilities/fqterm_http.cpp
new file mode 100644
index 0000000..57cde46
--- /dev/null
+++ b/src/utilities/fqterm_http.cpp
@@ -0,0 +1,264 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm.h"
+#include "fqterm_path.h"
+#include "fqterm_http.h"
+#include "fqterm_config.h"
+#include "fqterm_filedialog.h"
+
+namespace FQTerm {
+
+QMap<QString, int> FQTermHttp::downloadMap_;
+QMutex FQTermHttp::mutex_;
+
+FQTermHttp::FQTermHttp(FQTermConfig *config, QWidget *p, const QString &poolDir, int serverEncodingID)
+ : nam_(new QNetworkAccessManager), poolDir_(poolDir) {
+ // m_pDialog = NULL;
+ config_ = config;
+
+ serverEncodingID_ = serverEncodingID;
+
+ }
+
+FQTermHttp::~FQTermHttp() {
+}
+
+void FQTermHttp::cancel() {
+ if(netreply_){
+ netreply_->abort();
+ }
+ if (QFile::exists(cacheFileName_)) {
+ QFile::remove(cacheFileName_);
+ }
+
+ emit done(this);
+}
+
+
+
+void FQTermHttp::getLink(const QString &url, bool preview) {
+ QUrl u(url);
+ getLink(u,preview);
+}
+
+void FQTermHttp::getLink(const QUrl& url, bool preview) {
+ QUrl u=url;
+ isExisting_ = false;
+ isPreview_ = preview;
+ previewEmitted = false;
+ lastPercent_ = 0;
+ if (u.isRelative() || u.scheme() == "file") {
+ emit previewImage(cacheFileName_, false, true);
+ emit done(this);
+ return ;
+ }
+
+ if (QFile::exists(getPath(USER_CONFIG) + "hosts.cfg")) {
+ config_ = new FQTermConfig(getPath(USER_CONFIG) + "hosts.cfg");
+ QString strTmp = config_->getItemValue("hosts", u.host().toLocal8Bit());
+ if (!strTmp.isEmpty()) {
+ QString strUrl = u.toString();
+ strUrl.replace(QRegExp(u.host(), Qt::CaseInsensitive), strTmp);
+ u = strUrl;
+ }
+ }
+ if (!(netreply_ && netreply_->hasRawHeader("Location"))) {
+ cacheFileName_ = QFileInfo(u.path()).fileName();
+ }
+ if(netreply_){
+ netreply_->blockSignals(true);
+ netreply_.take()->deleteLater();
+ }
+
+ netreply_.reset(nam_->get(QNetworkRequest(u)));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(finished()), this, SLOT(httpDone())));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(downloadProgress(qint64, qint64)),this, SLOT(httpRead(qint64, qint64))));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(error( QNetworkReply::NetworkError)), this, SLOT(httpError(QNetworkReply::NetworkError))));
+ FQ_VERIFY(connect(netreply_.data(), SIGNAL(metaDataChanged()), this, SLOT(httpResponse())));
+}
+
+void FQTermHttp::httpResponse() {
+ if (netreply_->hasRawHeader("Location")) {
+ //FIXME: according to RC, this code still could not work
+ //if the server send the relative location.
+ QString realLocation = netreply_->header(QNetworkRequest::LocationHeader).toString();
+ QUrl u = realLocation;
+ if (u.isRelative() ) {
+ u=netreply_->url().resolved(u);
+ }
+ cacheFileName_ = QFileInfo(u.path()).fileName(); // update filename
+ getLink(u,isPreview_);
+ return;
+ }
+
+ QString ValueString;
+ QString filename;
+
+ ValueString = netreply_->header(QNetworkRequest::ContentLengthHeader).toString();
+ int FileLength = ValueString.toInt();
+
+ ValueString = netreply_->rawHeader("Content-Disposition");
+ // ValueString = ValueString.mid(ValueString.find(';') + 1).stripWhiteSpace();
+ // if(ValueString.lower().find("filename") == 0)
+ // m_strHttpFile = ValueString.mid(ValueString.find('=') + 1).stripWhiteSpace();
+ if (ValueString.right(1) != ";") {
+ ValueString += ";";
+ }
+ QRegExp re("filename=.*;", Qt::CaseInsensitive);
+ re.setMinimal(true);
+ //Dont FIXME:this will also split filenames with ';' inside, does anyone really do this?
+ int pos = re.indexIn(ValueString);
+ if (pos != -1) {
+ cacheFileName_ = ValueString.mid(pos + 9, re.matchedLength() - 10);
+ }
+ //cacheFileName_ = encoding2unicode(cacheFileName_.toLatin1(), serverEncodingID_);
+ filename = cacheFileName_;
+
+ if (isPreview_) {
+ cacheFileName_ = poolDir_ + cacheFileName_;
+
+ QFileInfo fi(cacheFileName_);
+
+ int i = 1;
+ QFileInfo fi2 = fi;
+
+ mutex_.lock();
+ if (downloadMap_.find(cacheFileName_) == downloadMap_.end() && !fi2.exists()) {
+ downloadMap_[cacheFileName_] = FileLength;
+ }
+ while (fi2.exists()) {
+
+ QMap<QString, int>::iterator ii;
+ if ((ii = downloadMap_.find(cacheFileName_)) != downloadMap_.end()) {
+ if (ii.value() == FileLength) {
+ mutex_.unlock();
+ netreply_->abort();
+ isExisting_ = true;
+ emit headerReceived(this, filename);
+ emit done(this);
+ return;
+ }
+ }
+
+ if (fi2.size() == FileLength) {
+ mutex_.unlock();
+ isExisting_ = true;
+ emit headerReceived(this, filename);
+ netreply_->abort();
+ return;
+ } else {
+ cacheFileName_ = QString("%1/%2(%3).%4").arg(fi.path())
+ .arg(fi.completeBaseName()).arg(i).arg(fi.suffix());
+ fi2.setFile(cacheFileName_);
+ if (!fi2.exists()) {
+ downloadMap_[cacheFileName_] = FileLength;
+ break;
+ }
+
+ i++;
+ }
+ }
+ mutex_.unlock();
+
+ fi.setFile(cacheFileName_);
+
+ QString strExt = fi.suffix().toLower();
+ if (strExt == "jpg" || strExt == "jpeg" || strExt == "gif" || strExt == "mng"
+ || strExt == "png" || strExt == "bmp") {
+ isPreview_ = true;
+ } else {
+ isPreview_ = false;
+ }
+ } else {
+ //getSaveFileName(cacheFileName_, NULL, strSave);
+ mutex_.lock();
+
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(cacheFileName_, "*");
+ mutex_.unlock();
+ // no filename specified which means the user canceled this download
+ if (strSave.isEmpty()) {
+ netreply_->abort();
+ emit done(this);
+ return ;
+ }
+ cacheFileName_ = strSave;
+ }
+
+ emit headerReceived(this, filename);
+}
+
+
+void FQTermHttp::httpRead(qint64 done, qint64 total) {
+ QByteArray ba = netreply_->readAll();
+ QFile file(cacheFileName_);
+ if (file.open(QIODevice::ReadWrite | QIODevice::Append)) {
+ QDataStream ds(&file);
+ ds.writeRawData(ba, ba.size());
+ file.close();
+ }
+ if (total != 0) {
+ //m_pDialog->setProgress(done,total);
+ int p = done *100 / total;
+ if (p - lastPercent_ >= 10 && isPreview_ && QFileInfo(cacheFileName_).suffix().toLower() == "jpg") {
+ if (!previewEmitted) {
+ emit previewImage(cacheFileName_,true, false);
+ previewEmitted = true;
+ } else {
+ emit previewImage(cacheFileName_,false, false);
+ }
+ lastPercent_ = p;
+ }
+ emit percent(p);
+ }
+}
+
+void FQTermHttp::httpDone() {
+ mutex_.lock();
+ downloadMap_.remove(cacheFileName_);
+ mutex_.unlock();
+ if (isPreview_) {
+ emit previewImage(cacheFileName_, true, true);
+ } else {
+ emit message("Download one file successfully");
+ }
+ emit done(this);
+}
+
+void FQTermHttp::httpError(QNetworkReply::NetworkError code) {
+ switch(code)
+ {
+ case QNetworkReply::OperationCanceledError:
+ break;
+ default:
+ QMessageBox::critical(NULL, tr("Download Error"), tr("Failed to download file\n code=%1").arg(code));
+ //deleteLater(); /*Not needed. http done will be called and this will cause a double free.
+ //return;
+ break;
+ }
+}
+
+void FQTermHttp::setProxy(const QNetworkProxy & proxy) {
+ nam_->setProxy(proxy);
+}
+} // namespace FQTerm
+
+#include "fqterm_http.moc"
diff --git a/src/utilities/fqterm_http.h b/src/utilities/fqterm_http.h
new file mode 100644
index 0000000..4c029d9
--- /dev/null
+++ b/src/utilities/fqterm_http.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_HTTP_H
+#define FQTERM_HTTP_H
+
+#include <QObject>
+#include <QMutex>
+#include <QMap>
+#include <QScopedPointer>
+#include <QNetworkReply>
+
+class QNetworkProxy;
+class QNetworkAccessManager;
+
+namespace FQTerm {
+
+class FQTermConfig;
+class FQTermFileDialog;
+
+class FQTermHttp: public QObject {
+ Q_OBJECT;
+ public:
+ FQTermHttp(FQTermConfig *, QWidget*, const QString &poolDir, int serverEncodingID);
+ ~FQTermHttp();
+
+ void getLink(const QString &, bool);
+ void getLink(const QUrl &, bool);
+ void setProxy (const QNetworkProxy & proxy);
+ signals:
+ void done(QObject*);
+ void message(const QString &);
+ void percent(int);
+ void headerReceived(FQTermHttp *, const QString &filename);
+ void previewImage(const QString &filename, bool raiseViewer, bool done);
+
+ public slots:
+ void cancel();
+
+ protected slots:
+ void httpDone();
+ void httpRead(qint64, qint64);
+ void httpError(QNetworkReply::NetworkError);
+ void httpResponse();
+
+ protected:
+ QScopedPointer<QNetworkAccessManager> nam_;
+ QScopedPointer<QNetworkReply> netreply_;
+ QString cacheFileName_;
+ bool previewEmitted;
+ bool isPreview_;
+ bool isExisting_;
+ int lastPercent_;
+ int serverEncodingID_;
+
+ QString poolDir_;
+
+ static QMap<QString, int> downloadMap_;
+ static QMutex mutex_;
+
+ FQTermConfig *config_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_HTTP_H
diff --git a/src/utilities/fqterm_ip_location.cpp b/src/utilities/fqterm_ip_location.cpp
new file mode 100644
index 0000000..ea5946d
--- /dev/null
+++ b/src/utilities/fqterm_ip_location.cpp
@@ -0,0 +1,265 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <QString>
+#include <QRegExp>
+#include <QDir>
+#include <QStringList>
+#include <ctype.h>
+
+#ifdef Q_OS_WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#include "fqterm_trace.h"
+#include "fqterm_ip_location.h"
+#include "fqterm_path.h"
+#include "fqterm.h"
+
+namespace FQTerm {
+
+FQTermIPLocation* FQTermIPLocation::instance_ = NULL;
+
+FQTermIPLocation::FQTermIPLocation(const QString &pathLib) {
+ ipDatabase_ = new IPDatabase;
+ ipDatabase_->ipfp = NULL;
+
+ isFileExiting_ = true;
+
+ //case-insensitive match
+ QDir dir(pathLib);
+ QStringList files = dir.entryList(QStringList(
+ "[Qq][Qq][Ww][Rr][Yy].[Dd][Aa][Tt]"), QDir::Files);
+ if (!files.isEmpty()) {
+ if ((ipDatabase_->ipfp = fopen((pathLib + (files.at(0))).toLocal8Bit(), "rb")) == NULL) {
+ FQ_TRACE("iplocation", 0) << "Can't open ip database file!";
+ isFileExiting_ = false;
+ }
+ } else {
+ isFileExiting_ = false;
+ }
+
+}
+
+FQTermIPLocation::~FQTermIPLocation() {
+ if (ipDatabase_->ipfp != NULL) {
+ fclose(ipDatabase_->ipfp);
+ }
+ delete ipDatabase_;
+}
+
+uint32 FQTermIPLocation::byteArrayToInt(char *ip, int count) {
+ uint32 tmp, ret = 0L;
+ if (count < 1 || count > 4) {
+ FQ_TRACE("iplocation", 0) << "byteArrayToInt() error!";
+ return 0;
+ }
+ for (int i = 0; i < count; i++) {
+ tmp = ((uint32)ip[i]) &0x000000FF;
+ ret |= (tmp << (8 *i));
+ }
+ return ret;
+}
+
+void FQTermIPLocation::readFrom(FILE *fp, uint32 offset, char *buf, int len) {
+ if (fseek(fp, (long)offset, SEEK_SET) == -1) {
+ FQ_TRACE("iplocation", 0) << "readFrom() error 1";
+ memset(buf, 0, len);
+ return ;
+ }
+ if (fread(buf, sizeof(char), len, fp) == 0) {
+ FQ_TRACE("iplocation", 0) << "readFrom() error 2";
+ memset(buf, 0, len);
+ return ;
+ }
+ return ;
+}
+
+int FQTermIPLocation::readLineFrom(FILE *fp, uint32 offset, QByteArray &ret_str) {
+ char str[512];
+ if (fseek(fp, (long)offset, SEEK_SET) == -1) {
+ FQ_TRACE("iplocation", 0) << "readLineFrom error 1";
+ ret_str = QByteArray();
+ return -1;
+ }
+ if (fgets((char*)str, 512, fp) == NULL) {
+ FQ_TRACE("iplocation", 0) << "readLineFrom error 2";
+ ret_str = QByteArray();
+ return -1;
+ }
+ ret_str = QByteArray(str);
+ return (ret_str.length());
+}
+
+uint32 FQTermIPLocation::getString(FILE *fp, uint32 offset, uint32 lastoffset,
+ QByteArray &ret, unsigned int flag, int maxRecursiveDepth) {
+ if (maxRecursiveDepth <= 0)
+ return 0;
+ unsigned int fg;
+ if (fp == NULL) {
+ return 0;
+ }
+ char buf[3] = {0};
+ readFrom(fp, offset, buf, 1);
+ if (buf[0] == 0x01 || buf[0] == 0x02) {
+ fg = buf[0];
+ readFrom(fp, offset + 1, buf, 3);
+ return getString(fp, byteArrayToInt(buf, 3), offset, ret, fg, maxRecursiveDepth - 1);
+ } else {
+ readLineFrom(fp, offset, ret);
+ }
+ switch (flag) {
+ case 0x01:
+ return 0;
+ case 0x02:
+ return lastoffset + 4;
+ default:
+ return offset + ret.length() + 1;
+ }
+}
+
+
+void FQTermIPLocation::getCountryCity(FILE *fp, uint32 offset, QByteArray &country,
+ QByteArray &city) {
+ uint32 next_offset;
+ if (fp == NULL) {
+ return ;
+ }
+ next_offset = getString(fp, offset, 0L, country, 0);
+ if (next_offset == 0) {
+ city = "";
+ } else {
+ getString(fp, next_offset, 0L, city, 0);
+ }
+ return ;
+}
+
+void FQTermIPLocation::setIpRange(int rec_no, IPDatabase *f) {
+ uint32 offset;
+ if (f == NULL) {
+ return ;
+ }
+ char buf[7] = {0};
+ offset = f->offset_first_start_ip + rec_no * 7;
+ readFrom(f->ipfp, offset, buf, 7);
+ f->cur_start_ip = byteArrayToInt(buf, 4);
+ f->offset_cur_end_ip = byteArrayToInt(buf + 4, 3);
+
+ readFrom(f->ipfp, f->offset_cur_end_ip, buf, 4);
+ f->cur_end_ip = byteArrayToInt(buf, 4);
+
+}
+
+bool FQTermIPLocation::getLocation(QString &url, QString &country, QString &city)
+{
+ QByteArray gbCountry, gbCity;
+ bool result = getLocation(url, gbCountry, gbCity);
+ country = encoding2unicode(gbCountry, FQTERM_ENCODING_GBK);
+ city = encoding2unicode(gbCity, FQTERM_ENCODING_GBK);
+ return result;
+}
+
+bool FQTermIPLocation::getLocation(QString &url, QByteArray &country,
+ QByteArray &city) {
+ int rec, record_count, B, E;
+ uint32 ip;
+#ifdef Q_OS_WIN32
+ uint32 ipValue = inet_addr((const char*)url.toLatin1());
+#else
+ in_addr_t ipValue = inet_addr((const char*)url.toLatin1());
+#endif
+ if ((int)ipValue == -1) {
+ return false;
+ } else {
+ ip = ntohl(ipValue);
+ }
+
+ char buf[4] = {0};
+ readFrom(ipDatabase_->ipfp, 0L, (char*)buf, 4);
+ ipDatabase_->offset_first_start_ip = byteArrayToInt((char*)buf, 4);
+ readFrom(ipDatabase_->ipfp, 4L, (char*)buf, 4);
+ ipDatabase_->offset_last_start_ip = byteArrayToInt((char*)buf, 4);
+
+ record_count = (ipDatabase_->offset_last_start_ip - ipDatabase_->offset_first_start_ip) / 7;
+ if (record_count <= 1) {
+ return FALSE;
+ }
+
+ // search for right range
+ B = 0;
+ E = record_count;
+ while (B < E-1) {
+ rec = (B + E) / 2;
+ setIpRange(rec, ipDatabase_);
+ if (ip == ipDatabase_->cur_start_ip) {
+ B = rec;
+ break;
+ }
+ if (ip > ipDatabase_->cur_start_ip) {
+ B = rec;
+ } else {
+ E = rec;
+ }
+ }
+ setIpRange(B, ipDatabase_);
+
+ if (ipDatabase_->cur_start_ip <= ip && ip <= ipDatabase_->cur_end_ip) {
+ getCountryCity(ipDatabase_->ipfp, ipDatabase_->offset_cur_end_ip + 4, country, city);
+ //country.replace( country.find( "CZ88.NET", 0, FALSE ), 8, "" );
+ if ((rec = country.toUpper().indexOf("CZ88.NET", 0)) >= 0) {
+ country.replace(rec, 8, "********");
+ }
+ if ((rec = city.toUpper().indexOf("CZ88.NET", 0)) >= 0) {
+ city.replace(rec, 8, "********");
+ }
+
+ } else {
+ // not in this range... miss
+ country = "unkown";
+ city = "";
+ }
+ // if ip_start<=ip<=ip_end
+ return TRUE;
+}
+
+FQTermIPLocation* FQTermIPLocation::getInstance() {
+ if (instance_ == NULL) {
+ instance_ = new FQTermIPLocation(getPath(USER_CONFIG));
+ if (instance_->isFileExiting_ == NULL) {
+ delete instance_;
+ instance_ = new FQTermIPLocation(getPath(RESOURCE));
+ if (instance_->isFileExiting_ == NULL) {
+ delete instance_;
+ instance_ = NULL;
+ }
+ }
+ }
+ return instance_;
+}
+
+void FQTermIPLocation::Destroy() {
+ delete instance_;
+ instance_ = NULL;
+}
+
+} // namespace FQTerm
diff --git a/src/utilities/fqterm_ip_location.h b/src/utilities/fqterm_ip_location.h
new file mode 100644
index 0000000..55de36b
--- /dev/null
+++ b/src/utilities/fqterm_ip_location.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_IPLOCATION_H
+#define FQTERM_IPLOCATION_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+class QString;
+
+namespace FQTerm {
+
+#define MAX_RECURSIVE_IP_DATA_DEPTH 100
+
+typedef unsigned long uint32;
+
+
+class FQTermIPLocation {
+public:
+ static FQTermIPLocation* getInstance();
+ static void Destroy();
+
+ bool getLocation(QString &url, QString &country, QString &city);
+ bool getLocation(QString &url, QByteArray &country, QByteArray &city);
+
+private:
+ struct IPDatabase {
+ uint32 offset_first_start_ip; // first abs offset of start ip
+ uint32 offset_last_start_ip; // last abs offset of start ip
+ uint32 cur_start_ip; // start ip of current search range
+ uint32 cur_end_ip; // end ip of current search range
+ uint32 offset_cur_end_ip; // where is the current end ip saved
+ FILE *ipfp; // IO Channel to read file
+ };
+
+ FQTermIPLocation(const QString &pathLib);
+ ~FQTermIPLocation();
+ uint32 byteArrayToInt(char *ip, int count);
+ void readFrom(FILE *fp, uint32 offset, char *buf, int len);
+ int readLineFrom(FILE *fp, uint32 offset, QByteArray &ret_str);
+ uint32 getString(FILE *fp, uint32 offset, uint32 lastoffset, QByteArray &str,
+ unsigned int flag, int maxRecursiveDepth = MAX_RECURSIVE_IP_DATA_DEPTH);
+ void getCountryCity(FILE *fp, uint32 offset, QByteArray &country, QByteArray &city);
+ void setIpRange(int rec_no, IPDatabase *f);
+
+
+ IPDatabase *ipDatabase_;
+ bool isFileExiting_;
+
+ static FQTermIPLocation* instance_;
+};
+
+} // namespace FQTerm
+
+#endif // FQTERM_IPLOCATION_H
diff --git a/src/utilities/fqwcwidth.cpp b/src/utilities/fqwcwidth.cpp
new file mode 100644
index 0000000..fc980e5
--- /dev/null
+++ b/src/utilities/fqwcwidth.cpp
@@ -0,0 +1,468 @@
+/*
+ * This is an implementation of wcwidth() and wcswidth() (defined in
+ * IEEE Std 1002.1-2001) for Unicode.
+ *
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
+ *
+ * In fixed-width output devices, Latin characters all occupy a single
+ * "cell" position of equal width, whereas ideographic CJK characters
+ * occupy two such cells. Interoperability between terminal-line
+ * applications and (teletype-style) character terminals using the
+ * UTF-8 encoding requires agreement on which character should advance
+ * the cursor by how many cell positions. No established formal
+ * standards exist at present on which Unicode character shall occupy
+ * how many cell positions on character terminals. These routines are
+ * a first attempt of defining such behavior based on simple rules
+ * applied to data provided by the Unicode Consortium.
+ *
+ * For some graphical characters, the Unicode standard explicitly
+ * defines a character-cell width via the definition of the East Asian
+ * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
+ * In all these cases, there is no ambiguity about which width a
+ * terminal shall use. For characters in the East Asian Ambiguous (A)
+ * class, the width choice depends purely on a preference of backward
+ * compatibility with either historic CJK or Western practice.
+ * Choosing single-width for these characters is easy to justify as
+ * the appropriate long-term solution, as the CJK practice of
+ * displaying these characters as double-width comes from historic
+ * implementation simplicity (8-bit encoded characters were displayed
+ * single-width and 16-bit ones double-width, even for Greek,
+ * Cyrillic, etc.) and not any typographic considerations.
+ *
+ * Much less clear is the choice of width for the Not East Asian
+ * (Neutral) class. Existing practice does not dictate a width for any
+ * of these characters. It would nevertheless make sense
+ * typographically to allocate two character cells to characters such
+ * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
+ * represented adequately with a single-width glyph. The following
+ * routines at present merely assign a single-cell width to all
+ * neutral characters, in the interest of simplicity. This is not
+ * entirely satisfactory and should be reconsidered before
+ * establishing a formal standard in this area. At the moment, the
+ * decision which Not East Asian (Neutral) characters should be
+ * represented by double-width glyphs cannot yet be answered by
+ * applying a simple rule from the Unicode database content. Setting
+ * up a proper standard for the behavior of UTF-8 character terminals
+ * will require a careful analysis not only of each Unicode character,
+ * but also of each presentation form, something the author of these
+ * routines has avoided to do so far.
+ *
+ * http://www.unicode.org/unicode/reports/tr11/
+ *
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to this software.
+ *
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+
+/*
+ * For wchar_t may be of 16 bits on some platforms, use uint32_t instead.
+ *
+ */
+
+#include "fqwcwidth.h"
+#include "fqterm_trace.h"
+
+namespace FQTerm {
+
+struct interval {
+ uint32_t first;
+ uint32_t last;
+};
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(uint32_t ucs, const struct interval *table, int max) {
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].last)
+ return 0;
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].last)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* The following two functions define the column width of an ISO 10646
+ * character as follows:
+ *
+ * - The null character (U+0000) has a column width of 0.
+ *
+ * - Other C0/C1 control characters and DEL will lead to a return
+ * value of -1.
+ *
+ * - Non-spacing and enclosing combining characters (general
+ * category code Mn or Me in the Unicode database) have a
+ * column width of 0.
+ *
+ * - SOFT HYPHEN (U+00AD) has a column width of 1.
+ *
+ * - Other format characters (general category code Cf in the Unicode
+ * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *
+ * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
+ * have a column width of 0.
+ *
+ * - Spacing characters in the East Asian Wide (W) or East Asian
+ * Full-width (F) category as defined in Unicode Technical
+ * Report #11 have a column width of 2.
+ *
+ * - All remaining characters (including all printable
+ * ISO 8859-1 and WGL4 characters, Unicode control characters,
+ * etc.) have a column width of 1.
+ *
+ * This implementation assumes that uint32_t characters are encoded
+ * in ISO 10646.
+ */
+
+int mk_wcwidth(uint32_t ucs)
+{
+ /* sorted list of non-overlapping intervals of non-spacing characters */
+ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
+ static const struct interval combining[] = {
+ { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
+ { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+ { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
+ { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
+ { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+ { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
+ { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
+ { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
+ { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
+ { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
+ { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
+ { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
+ { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
+ { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
+ { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
+ { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
+ { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
+ { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
+ { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
+ { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+ { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
+ { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
+ { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
+ { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
+ { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
+ { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
+ { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
+ { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
+ { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
+ { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
+ { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
+ { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
+ { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
+ { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
+ { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
+ { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
+ { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
+ { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
+ { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
+ { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
+ { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
+ { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
+ { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
+ { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
+ { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
+ { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
+ { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
+ { 0xE0100, 0xE01EF }
+ };
+
+ /* test for 8-bit control characters */
+ if (ucs == 0)
+ return 0;
+ if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
+ return -1;
+
+ /* binary search in table of non-spacing characters */
+ if (bisearch(ucs, combining,
+ sizeof(combining) / sizeof(struct interval) - 1))
+ return 0;
+
+ /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+ return 1 +
+ (ucs >= 0x1100 &&
+ (ucs <= 0x115f || /* Hangul Jamo init. consonants */
+ ucs == 0x2329 || ucs == 0x232a ||
+ (ucs >= 0x2e80 && ucs <= 0xa4cf &&
+ ucs != 0x303f) || /* CJK ... Yi */
+ (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+ (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+ (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
+ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+ (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
+ (ucs >= 0xffe0 && ucs <= 0xffe6) ||
+ (ucs >= 0x20000 && ucs <= 0x2fffd) ||
+ (ucs >= 0x30000 && ucs <= 0x3fffd)));
+}
+
+
+int mk_wcswidth(const uint32_t *pwcs, size_t n)
+{
+ int w, width = 0;
+
+ for (;*pwcs && n-- > 0; pwcs++)
+ if ((w = mk_wcwidth(*pwcs)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
+
+
+int mk_wcswidth(const UTF16 *utf16_str, size_t n)
+{
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0; utf16_str++)
+ if ((w = mk_wcwidth(*utf16_str)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
+
+int mk_wcswidth(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ const UTF16 *org = utf16_str;
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0 && width < max_width; utf16_str++)
+ if ((w = mk_wcwidth(*utf16_str)) < 0)
+ return -1;
+ else
+ width += w;
+
+ FQ_VERIFY(width <= max_width);
+
+ element_consumed = utf16_str - org;
+
+ return width;
+}
+
+int mk_advance_one_code_point(const UTF16 **p, const UTF16 *end) {
+ FQ_ASSERT(*p < end);
+
+ // TODO_UTF16: FIXME: only support BMP here.
+ *p = *p + 1;
+ return get_str_width(**p);
+}
+
+int mk_advace_at_least_one_cell(const UTF16 **p, const UTF16 *end) {
+ FQ_ASSERT(*p < end);
+
+ // TODO_UTF16: FIXME: only support BMP here.
+ int w = 0;
+ int width = 0;
+ do {
+ w = get_str_width(**p);
+ width += w;
+ *p = *p + 1;
+ } while (w == 0 && *p < end);
+
+ if (w < 0) {
+ return -1;
+ }
+
+ while (*p < end && get_str_width(**p) == 0) {
+ *p = *p + 1;
+ }
+
+ return width;
+}
+
+/*
+ * The following functions are the same as mk_wcwidth() and
+ * mk_wcswidth(), except that spacing characters in the East Asian
+ * Ambiguous (A) category as defined in Unicode Technical Report #11
+ * have a column width of 2. This variant might be useful for users of
+ * CJK legacy encodings who want to migrate to UCS without changing
+ * the traditional terminal character-width behaviour. It is not
+ * otherwise recommended for general use.
+ */
+int mk_wcwidth_cjk(uint32_t ucs)
+{
+ /* sorted list of non-overlapping intervals of East Asian Ambiguous
+ * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
+ static const struct interval ambiguous[] = {
+ { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
+ { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
+ { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
+ { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
+ { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
+ { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
+ { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
+ { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
+ { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
+ { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
+ { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
+ { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
+ { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
+ { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
+ { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
+ { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
+ { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
+ { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
+ { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
+ { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
+ { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
+ { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
+ { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
+ { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
+ { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
+ { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
+ { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
+ { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
+ { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
+ { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
+ { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
+ { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
+ { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
+ { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
+ { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
+ { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
+ { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
+ { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
+ { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
+ { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
+ { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
+ { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
+ { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
+ { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
+ { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
+ { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
+ { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
+ { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
+ { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
+ { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
+ { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
+ { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
+ };
+
+ /* binary search in table of non-spacing characters */
+ if (bisearch(ucs, ambiguous,
+ sizeof(ambiguous) / sizeof(struct interval) - 1))
+ return 2;
+
+ return mk_wcwidth(ucs);
+}
+
+
+int mk_wcswidth_cjk(const uint32_t *pwcs, size_t n)
+{
+ int w, width = 0;
+
+ for (;*pwcs && n-- > 0; pwcs++)
+ if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
+
+int mk_wcswidth_cjk(const UTF16 *utf16_str, size_t n)
+{
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0; utf16_str++) {
+ if ((w = mk_wcwidth_cjk(*utf16_str)) < 0)
+ return -1;
+ else
+ width += w;
+ }
+
+ return width;
+}
+
+int mk_wcswidth_cjk(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ const UTF16 *org = utf16_str;
+ int w, width = 0;
+
+ // FIXME: only BMP is supported here.
+ for (;*utf16_str && n-- > 0 && width < max_width; utf16_str++) {
+ const UTF16 *bak_str = utf16_str;
+ int bak_width = width;
+
+ if ((w = mk_wcwidth_cjk(*utf16_str)) < 0) {
+ return -1;
+ } else {
+ width += w;
+ }
+
+ if (width > max_width) {
+ utf16_str = bak_str;
+ width = bak_width;
+ if (utf16_str == org) {
+ return -1;
+ } else {
+ break;
+ }
+ }
+ }
+
+ element_consumed = utf16_str - org;
+ return width;
+}
+
+
+#define USE_CJK_WIDTH
+
+
+// TODO_UTF16: if we don't use CJK width, we will get wrong text layout.
+#ifdef USE_CJK_WIDTH
+
+int get_str_width(uint32_t ucs) {
+ return mk_wcwidth_cjk(ucs);
+}
+
+int get_str_width(const uint32_t *pwcs, size_t n) {
+ return mk_wcswidth_cjk(pwcs, n);
+}
+
+int get_str_width(const UTF16 *utf16_str, size_t n) {
+ return mk_wcswidth_cjk(utf16_str, n);
+}
+
+int get_str_width(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ return mk_wcswidth_cjk(utf16_str, n, max_width, element_consumed);
+}
+
+#else
+
+int get_str_width(uint32_t ucs) {
+ return mk_wcwidth(ucs);
+}
+int get_str_width(const uint32_t *pwcs, size_t n) {
+ return mk_wcswidth(pwcs, n);
+}
+int get_str_width(const UTF16 *utf16_str, size_t n) {
+ return mk_wcswidth(utf16_str, n);
+}
+
+int get_str_width(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed) {
+ return mk_wcswidth(utf16_str, n, max_width, element_consumed);
+}
+
+#endif
+
+} // namespace FQTerm
diff --git a/src/utilities/fqwcwidth.h b/src/utilities/fqwcwidth.h
new file mode 100644
index 0000000..b2007bc
--- /dev/null
+++ b/src/utilities/fqwcwidth.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef FQTERM_FQWCWIDTH_H
+#define FQTERM_FQWCWIDTH_H
+
+#ifdef WIN32
+#define uint32_t unsigned __int32
+#define uint16_t unsigned __int16
+typedef wchar_t UTF16;
+#else // WIN32
+#include <stdio.h>
+#include <stdint.h>
+typedef uint16_t UTF16;
+#endif // WIN32
+
+typedef char Verify_UTF16_Is_Two_Bytes[
+ (sizeof(UTF16) == 2)? 1 : -1];
+
+namespace FQTerm {
+
+//const uint16_t URC = 0xfffd; // the Unicode Replacement Character
+// TODO_UTF16: 0xfffd is of width 2, which is not desired.
+const uint16_t URC = '?'; // use '?' instead of the Unicode Replacement Character
+
+const int MAX_CELLS_PER_CHAR = 2;
+
+int get_str_width(uint32_t ucs);
+int get_str_width(const uint32_t *pwcs, size_t n);
+int get_str_width(const UTF16 *utf16_str, size_t n);
+int get_str_width(const UTF16 *utf16_str, size_t n, int max_width, int &element_consumed);
+
+// Move p to next code point in max_n UTF16 characters.
+// Return the width of the current code point.
+int mk_advance_one_code_point(const UTF16 **p, const UTF16 *end);
+
+// Move p to next code point in max_n UTF16 characters.
+// Return the width.
+int mk_advace_at_least_one_cell(const UTF16 **p, const UTF16 *end);
+
+} // namespace FQTerm
+
+#endif // FQTERM_FQWCWIDTH_H