author | Dan |
Wed, 06 Feb 2008 18:41:47 -0500 | |
changeset 401 | 6ae6e387a0e3 |
parent 400 | 7eef739a5b81 |
child 402 | d907601ccad2 |
--- a/includes/captcha.php Mon Feb 04 05:52:12 2008 -0500 +++ b/includes/captcha.php Wed Feb 06 18:41:47 2008 -0500 @@ -11,738 +11,178 @@ * * 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 details. - * - * This file contains code written by Paul Sohier (www.paulscripts.nl). The CAPTCHA code was ported from the phpBB Better - * Captcha mod, and has been released under the GPLv2 by the original author. - * - * This file contains code written by the phpBB team (www.phpbb.com). phpBB is licensed under the GPLv2. + */ + +/** + * The base class for CAPTCHA engines. + * @package Enano + * @subpackage User management + * @copyright 2008 Dan Fuhry */ -class captcha +class captcha_base { - var $chars, $confirm_id, $compat, $code, $captcha_config; - function __construct($code) + + /** + * Our session ID + * @var string + */ + + private $session_id; + + /** + * Our saved session data + * @var array + */ + + private $session_data; + + /** + * The confirmation code we're generating. + * @var string + */ + + private $code = ''; + + /** + * Numerical ID (primary key) for our session + * @var int + */ + + private $id = 0; + + /** + * Constructor. + * @param string Session ID for captcha + */ + + function __construct($session_id, $row = false) { global $db, $session, $paths, $template, $plugins; // Common objects - - // Check if GD exists, otherwise we will use the fallback phpBB confirm image - $this->compat = false; - if(!extension_loaded("gd")){ - $this->compat = true; + if ( !preg_match('/^[a-f0-9]{32}([a-z0-9]{8})?$/', $session_id) ) + { + throw new Exception('Invalid session ID'); } - if(!function_exists("gd_info") || !function_exists('imagettftext')){ - $this->compat = true; + $this->session_id = $session_id; + // If we weren't supplied with session info, retreive it + if ( !is_array($row) ) + { + $q = $db->sql_query('SELECT code_id, code, session_data FROM ' . table_prefix . "captcha WHERE session_id = '$session_id';"); + if ( !$q ) + $db->_die(); + $row = $db->fetchrow(); + $row['code_id'] = intval($row['code_id']); + $db->free_result(); } - $this->code = $code; - - $hex = Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); - $latticecolor = '#'; - for($i=0;$i<6;$i++) $latticecolor .= $hex[mt_rand(0, 15)]; + if ( !isset($row['code']) || !isset($row['session_data']) || !is_int(@$row['code_id']) ) + { + throw new Exception('Row doesn\'t contain what we need (code and session_data)'); + } + $this->session_data = ( is_array($x = @unserialize($row['session_data'])) ) ? $x : array(); + $this->code = $row['code']; + $this->id = $row['code_id']; - $this->captcha_config = array ( - 'width' => '350', - 'height' => '90', - 'background_color' => '#E5ECF9', - 'jpeg' => '0', - 'jpeg_quality' => '95', - 'pre_letters' => '1', - 'pre_letters_great' => '0', - 'font' => '1', - 'chess' => '2', - 'ellipses' => '2', - 'arcs' => '2', - 'lines' => '2', - 'image' => '0', - 'gammacorrect' => '0.8', - 'foreground_lattice_x' => (string)mt_rand(25, 30), - 'foreground_lattice_y' => (string)mt_rand(25, 30), - 'lattice_color' => $latticecolor, - ); + // run any custom init functions + if ( function_exists(array($this, 'construct_hook')) ) + $this->construct_hook(); } - function captcha($code) - { - $this->__construct($code); - } - function dss_rand() + + /** + * Retrieves a key from the session data set + * @param int|string Key to fetch + * @param mixed Default value for key + * @return mixed + */ + + function session_fetch($key, $default = false) { - global $db; - - $val = microtime() . mt_rand(); - $val = md5($val . 'a'); - return substr($val, 4, 16); + return ( isset($this->session_data[$key]) ) ? $this->session_data[$key] : $default; } - function make_image() + /** + * Stores a value in the session's data set. Change must be committed using $captcha->session_commit() + * @param int|string Name of key + * @param mixed Value - can be an array, string, int, or double, but probably not objects :-) + */ + + function session_store($key, $value) { - $code=$this->code; - if($this->compat) - { - // We can we will generate a single filtered png - // Thanks to DavidMJ for emulating zlib within the code :) - $_png = $this->define_filtered_pngs(); - - $total_width = 320; - $total_height = 50; - $img_height = 40; - $img_width = 0; - $l = 0; - - list($usec, $sec) = explode(' ', microtime()); - mt_srand($sec * $usec); - - $char_widths = array(); - for ($i = 0; $i < strlen($code); $i++) - { - $char = $code{$i}; - - $width = mt_rand(0, 4); - $char_widths[] = $width; - $img_width += $_png[$char]['width'] - $width; - } - - $offset_x = mt_rand(0, $total_width - $img_width); - $offset_y = mt_rand(0, $total_height - $img_height); - - $image = ''; - $hold_chars = array(); - for ($i = 0; $i < $total_height; $i++) - { - $image .= chr(0); - - if ($i > $offset_y && $i < $offset_y + $img_height) - { - $j = 0; - - for ($k = 0; $k < $offset_x; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - - for ($k = 0; $k < strlen($code); $k++) - { - $char = $code{$k}; - - if (empty($hold_chars[$char])) - { - $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); - } - $image .= $this->randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); - $j++; - } - - for ($k = $offset_x + $img_width; $k < $total_width; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - - $l++; - } - else - { - for ($k = 0; $k < $total_width; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - } - - } - unset($hold); - - $image = $this->create_png($image, $total_width, $total_height); + $this->session_data[$key] = $value; + } + + /** + * Commits changes to the session data set to the database. + */ + + function session_commit() + { + global $db, $session, $paths, $template, $plugins; // Common objects + $session_data = serialize($this->session_data); + $session_data = $db->escape($session_data); + $code = $db->escape($this->code); + + $q = $db->sql_query('UPDATE ' . table_prefix . "captcha SET code = '$code', session_data = '$session_data' WHERE code_id = {$this->id};"); + if ( !$q ) + $db->_die(); + } + + /** + * Changes the confirmation code + * @param string New string + */ - // Output image - header('Content-Type: image/png'); - header('Cache-control: no-cache, no-store'); - echo $image; - - unset($image); - unset($_png); - } elseif(defined('ENANO_CAPTCHA_BIGNFAT')) { - // Prefs - $total_width = $this->captcha_config['width']; - $total_height = $this->captcha_config['height']; - - $hex_bg_color = $this->get_rgb($this->captcha_config['background_color']); - $bg_color = array(); - $bg_color = explode(",", $hex_bg_color); - - $jpeg = $this->captcha_config['jpeg']; - $img_quality = $this->captcha_config['jpeg_quality']; - // Max quality is 95 - - $pre_letters = $this->captcha_config['pre_letters']; - $pre_letter_great = $this->captcha_config['pre_letters_great']; - $rnd_font = $this->captcha_config['font']; - $chess = $this->captcha_config['chess']; - $ellipses = $this->captcha_config['ellipses']; - $arcs = $this->captcha_config['arcs']; - $lines = $this->captcha_config['lines']; - $image = $this->captcha_config['image']; - - $gammacorrect = $this->captcha_config['gammacorrect']; - - $foreground_lattice_y = $this->captcha_config['foreground_lattice_y']; - $foreground_lattice_x = $this->captcha_config['foreground_lattice_x']; - $hex_lattice_color = $this->get_rgb($this->captcha_config['lattice_color']); - $rgb_lattice_color = array(); - $rgb_lattice_color = explode(",", $hex_lattice_color); - - $font_debug = false; - - // Fonts and images init - if ($image) - { - $bg_imgs = array(); - if ($img_dir = opendir(ENANO_ROOT.'/includes/captcha/pics/')) - { - while (true == ($file = @readdir($img_dir))) - { - if ((substr(strtolower($file), -3) == 'jpg') || (substr(strtolower($file), -3) == 'gif')) - { - $bg_imgs[] = $file; - } - } - closedir($img_dir); - } - // Grab a random Background Image or set FALSE if none was found - $bg_img = ( count($bg_imgs) ) ? rand(0, (count($bg_imgs)-1)) : false; - } - - $fonts = array(); - if ($fonts_dir = opendir(ENANO_ROOT.'/includes/captcha/fonts/')) - { - while (true == ($file = @readdir($fonts_dir))) - { - if ((substr(strtolower($file), strlen($file)-3, strlen($file)) == 'ttf')) - { - $fonts[] = $file; - } - } - closedir($fonts_dir); - } else { - die('Error reading directory: '.ENANO_ROOT.'/includes/captcha/fonts/'); - } - $font = rand(0, (count($fonts)-1)); - - // Generate - $image = ($this->gdVersion() >= 2) ? imagecreatetruecolor($total_width, $total_height) : imagecreate($total_width, $total_height); - $background_color = imagecolorallocate($image, $bg_color[0], $bg_color[1], $bg_color[2]); - imagefill($image, 0, 0, $background_color); - - // Generate backgrund - if ($chess == '1' || $chess == '2' && rand(0,1)) - { - // Draw rectangles - for($i = 0; $i <= 8; $i++) - { - $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); - imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height), $rectanglecolor); - $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); - imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height/2), $rectanglecolor); - } - } - if ($ellipses == '1' || $ellipses == '2' && rand(0,1)) - { - // Draw random ellipses - for ($i = 1; $i <= 60; $i++) - { - $ellipsecolor = imagecolorallocate($image, rand(100,250),rand(100,250),rand(100,250)); - imagefilledellipse($image, round(rand(0, $total_width)), round(rand(0, $total_height)), round(rand(0, $total_width/8)), round(rand(0, $total_height/4)), $ellipsecolor); - } - } - if ($arcs == '1' || $arcs == '2' && rand(0,1)) - { - // Draw random partial ellipses - for ($i = 0; $i <= 30; $i++) - { - $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); - $cx = round(rand(1, $total_width)); - $cy = round(rand(1, $total_height)); - $int_w = round(rand(1, $total_width/2)); - $int_h = round(rand(1, $total_height)); - imagearc($image, $cx, $cy, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); - imagearc($image, $cx-1, $cy-1, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); - } - } - if ($lines == '1' || $lines == '2' && rand(0,1)) - { - // Draw random lines - for ($i = 0; $i <= 50; $i++) - { - $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); - imageline($image, round(rand(1, $total_width*3)), round(rand(1, $total_height*5)), round(rand(1, $total_width/2)), round(rand(1, $total_height*2)), $linecolor); - } - } - - $text_color_array = array('255,51,0', '51,77,255', '204,51,102', '0,153,0', '255,166,2', '255,0,255', '255,0,0', '0,255,0', '0,0,255', '0,255,255'); - shuffle($text_color_array); - $pre_text_color_array = array('255,71,20', '71,20,224', '224,71,122', '20,173,20', '255,186,22', '25,25,25'); - shuffle($pre_text_color_array); - $white = imagecolorallocate($image, 255, 255, 255); - $gray = imagecolorallocate($image, 100, 100, 100); - $black = imagecolorallocate($image, 0, 0, 0); - $lattice_color = imagecolorallocate($image, $rgb_lattice_color[0], $rgb_lattice_color[1], $rgb_lattice_color[2]); - - $x_char_position = (round(($total_width - 12) / strlen($code)) + mt_rand(-3, 5)); - - for ($i = 0; $i < strlen($code); $i++) - { - mt_srand((double)microtime()*1000000); - - $char = $code{$i}; - $size = mt_rand(floor($total_height / 3.5), ceil($total_height / 2.8)); - $font = ($rnd_font) ? rand(0, (count($fonts)-1)) : $font; - $angle = mt_rand(-30, 30); - - $char_pos = array(); - $char_pos = imagettfbbox($size, $angle, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - $letter_width = abs($char_pos[0]) + abs($char_pos[4]); - $letter_height = abs($char_pos[1]) + abs($char_pos[5]); - - $x_pos = ($x_char_position / 4) + ($i * $x_char_position); - ($i == strlen($code)-1 && $x_pos >= ($total_width - ($letter_width + 5))) ? $x_pos = ($total_width - ($letter_width + 5)) : ''; - $y_pos = mt_rand(($size * 1.4 ), $total_height - ($size * 0.4)); - - // Pre letters - $size = ($pre_letter_great) ? $size + (2 * $pre_letters) : $size - (2 * $pre_letters); - for ($count = 1; $count <= $pre_letters; $count++) - { - $pre_angle = $angle + mt_rand(-20, 20); - - $text_color = $pre_text_color_array[mt_rand(0,count($pre_text_color_array)-1)]; - $text_color = explode(",", $text_color); - $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); - - imagettftext($image, $size, $pre_angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $pre_angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $pre_angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - - $size = ($pre_letter_great) ? $size - 2 : $size + 2; - } - - // Final letters - $text_color = $text_color_array[mt_rand(0,count($text_color_array)-1)]; - $text_color = explode(",", $text_color); - $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); - - imagettftext($image, $size, $angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - } - - - ($gammacorrect) ? imagegammacorrect($image, 1.0, $gammacorrect) : ''; - - // Generate a white lattice in foreground - if ($foreground_lattice_y) - { - // x lines - $ih = round($total_height / $foreground_lattice_y); - for ($i = 0; $i <= $ih; $i++) - { - imageline($image, 0, $i*$foreground_lattice_y, $total_width, $i*$foreground_lattice_y, $lattice_color); - } - } - if ($foreground_lattice_x) - { - // y lines - $iw = round($total_width / $foreground_lattice_x); - for ($i = 0; $i <= $iw; $i++) - { - imageline($image, $i*$foreground_lattice_x, 0, $i*$foreground_lattice_x, $total_height, $lattice_color); - } - } - - // Font debug - if ($font_debug && !$rnd_font) - { - imagestring($image, 5, 2, 0, $fonts[$font], $white); - imagestring($image, 5, 5, 0, $fonts[$font], $white); - imagestring($image, 5, 4, 2, $fonts[$font], $gray); - imagestring($image, 5, 3, 1, $fonts[$font], $black); - } - - // Display - header("Last-Modified: " . gmdate("D, d M Y H:i:s") ." GMT"); - header("Pragma: no-cache"); - header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate"); - (!$jpeg) ? header("Content-Type: image/png") : header("Content-Type: image/jpeg"); - - (!$jpeg) ? imagepng($image) : imagejpeg($image, '', $img_quality); - imagedestroy($image); - } else { - /** - * The next part is orginnaly written by ted from mastercode.nl and modified for use in Enano. - **/ - header("content-type:image/png"); - header('Cache-control: no-cache, no-store'); - $breedte = 320; - $hoogte = 60; - $img = imagecreatetruecolor($breedte,$hoogte); - $achtergrond = imagecolorallocate($img, $this->color("bg"), $this->color("bg"), $this->color("bg")); - - imagefilledrectangle($img, 0, 0, $breedte-1, $hoogte-1, $achtergrond); - for($g = 0;$g < 30; $g++) - { - $t = $this->dss_rand(); - $t = $t[0]; - - $ypos = rand(0,$hoogte); - $xpos = rand(0,$breedte); - - $kleur = imagecolorallocate($img, $this->color("bgtekst"), $this->color("bgtekst"), $this->color("bgtekst")); - - imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur, $this->font(), $t); - } - $stukje = $breedte / (strlen($code) + 3); - - for($j = 0;$j < strlen($code); $j++) - { - - - $tek = $code[$j]; - $ypos = rand(33,43); - $xpos = $stukje * ($j+1); - - $kleur2 = imagecolorallocate($img, $this->color("tekst"), $this->color("tekst"), $this->color("tekst")); - - imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur2, $this->font() , $tek); - } - - imagepng($img); + function set_code($code) + { + if ( !is_string($code) ) + return false; + + $this->code = $code; + } + + /** + * Returns the confirmation code + * @return string + */ + + function get_code() + { + return $this->code; + } + +} + +/** + * Returns a new captcha object + * @param string Session ID + * @param string Optional - engine to load + * @param array Optional row to send to the captcha engine + */ + +function captcha_object($session_id, $engine = false, $row = false) +{ + static $singletons = array(); + if ( !$engine ) + { + $engine = getConfig('captcha_engine'); + if ( !$engine ) + { + $engine = 'bc'; } } - /** - * Some functions :) - * Also orginally written by mastercode.nl - **/ - /** - * Function to create a random color - * @param $type string Mode for the color - * @return int - **/ - function color($type) - { - switch($type) - { - case "bg": - $kleur = rand(224,255); - break; - case "tekst": - $kleur = rand(0,127); - break; - case "bgtekst": - $kleur = rand(200,224); - break; - default: - $kleur = rand(0,255); - break; - } - return $kleur; - } - /** - * Function to ranom the size - * @return int - **/ - function size() - { - $grootte = rand(14,30); - return $grootte; - } - /** - * Function to random the posistion - * @return int - **/ - function move() - { - $draai = rand(-25,25); - return $draai; - } - /** - * Function to return a ttf file from fonts map - * @return string - **/ - function font() + if( !extension_loaded("gd") || !function_exists("gd_info") || !function_exists('imagettftext') ) { - $f = @opendir(ENANO_ROOT . '/includes/captcha/fonts/'); - if(!$f) die('Can\'t open '.ENANO_ROOT.'/includes/captcha/fonts/ for reading'); - $ar = array(); - while(($file = @readdir($f)) !== false) - { - if(!in_array($file, array('.','..')) && strstr($file, '.ttf')) - { - $ar[] = $file; - } - } - if(count($ar)) - { - shuffle($ar); - $i = rand(0,(count($ar) - 1)); - return ENANO_ROOT . '/includes/captcha/fonts/' . $ar[$i]; - } + $engine = 'failsafe'; } - - // This is designed to randomise the pixels of the image data within - // certain limits so as to keep it readable. It also varies the image - // width a little - function randomise($scanline, $width) - { - $new_line = ''; - $start = floor($width/2); - $end = strlen($scanline) - ceil($width/2); - - for ($i = $start; $i < $end; $i++) - { - $pixel = ord($scanline{$i}); - - if ($pixel < 190) - { - $new_line .= chr(mt_rand(0, 205)); - } - else if ($pixel > 190) - { - $new_line .= chr(mt_rand(145, 255)); - } - else - { - $new_line .= $scanline{$i}; - } - } - - return $new_line; - } - - // This creates a chunk of the given type, with the given data - // of the given length adding the relevant crc - function png_chunk($length, $type, $data) - { - $raw = $type; - $raw .= $data; - $crc = crc32($raw); - $raw .= pack('C4', $crc >> 24, $crc >> 16, $crc >> 8, $crc); - - return pack('C4', $length >> 24, $length >> 16, $length >> 8, $length) . $raw; - } - - // Creates greyscale 8bit png - The PNG spec can be found at - // http://www.libpng.org/pub/png/spec/PNG-Contents.html we use - // png because it's a fully recognised open standard and supported - // by practically all modern browsers and OSs - function create_png($raw_image, $width, $height) - + if ( !class_exists("captcha_engine_$engine") ) { - // SIG - $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10); - // IHDR - $raw = pack('C4', $width >> 24, $width >> 16, $width >> 8, $width); - $raw .= pack('C4', $height >> 24, $height >> 16, $height >> 8, $height); - $raw .= pack('C5', 8, 0, 0, 0, 0); - $image .= $this->png_chunk(13, 'IHDR', $raw); - - if (@extension_loaded('zlib')) - { - $raw_image = gzcompress($raw_image); - $length = strlen($raw_image); - } - else - { - // The total length of this image, uncompressed, is just a calculation of pixels - $length = ($width + 1) * $height; - - // Adler-32 hash generation - // Optimized Adler-32 loop ported from the GNU Classpath project - $temp_length = $length; - $s1 = 1; - $s2 = $index = 0; - - while ($temp_length > 0) - { - // We can defer the modulo operation: - // s1 maximally grows from 65521 to 65521 + 255 * 3800 - // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 - $substract_value = ($temp_length < 3800) ? $temp_length : 3800; - $temp_length -= $substract_value; - - while (--$substract_value >= 0) - { - $s1 += ord($raw_image[$index]); - $s2 += $s1; - - $index++; - } - - $s1 %= 65521; - $s2 %= 65521; - } - $adler_hash = pack('N', ($s2 << 16) | $s1); - - // This is the same thing as gzcompress($raw_image, 0) but does not need zlib - $raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash; - - // The Zlib header + Adler hash make us add on 11 - $length += 11; - } - - // IDAT - $image .= $this->png_chunk($length, 'IDAT', $raw_image); - - // IEND - $image .= $this->png_chunk(0, 'IEND', ''); - - return $image; + require_once ENANO_ROOT . "/includes/captcha/engine_{$engine}.php"; } - - // Each 'data' element is base64_encoded uncompressed IDAT - // png image data - function define_filtered_pngs() + if ( !class_exists("captcha_engine_$engine") ) { - $_png = array( - '0' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==','width' => 40), - '1' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '2' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=','width' => 40), - '3' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '4' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '5' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '6' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '7' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '8' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '9' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'A' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'B' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'C' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'D' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'E' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'F' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'G' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'H' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'I' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'J' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'K' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'L' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'M' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'N' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'O' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'P' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'Q' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'R' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'S' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'T' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'U' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'V' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'W' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'X' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'Y' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'Z' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - ); - - return $_png; + throw new Exception("Expected but couldn't find class for captcha engine: captcha_engine_$engine"); } - - // These define base64_encoded raw png image data used - // when we cannot generate our own single png image - function define_raw_pngs() - { - $_png = array( - '0' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QKCNGXKO6AAAAB3RJTUUH0wUOEDQ6EUG1VwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNpj/M9AHGAiUt2wVvhyaqAqKyOjpG3jQwaGv+e+IUn9RwJfSjjg4iwFP1aKJD6HyyErfGGAYrquIoP5E2wK/zigu0v5wH9sChdgeKDqP1aFGhBZmxv/z0Dd4IxV4RWIpMQHIPuJAITzAqEQETx7IFQIP5CQNoJwDmALxzMQCuyjg1chnBPYwtECwr8AZN41h0p6YHOjAkTuwf//77wYuCEcFWwKOWA2fM1iZuuHcASwKYQ55c9ENuasrxgRjKlwJS+D17v/hBUeUGYwv/sfn0IRiJQZJIbxuFEFagjvSlDUQNgK2GIGqpC1JRhIfoAqxBYz0DRhn8IMJO+giKEqhMaMJBeI3AHhIKdkRPqG8DlAifqFADyasKRHO6h1Z/6fMYEwTbCmx3cWGCl8CTaFwBhGz+M2/7EpXMvOnBmIok7jBVaFz/Mi3/1pQORrhpgPyOr+M8IL0j9/gKpeLjhy5QEwoDVsYuRR3cE4IktcAJNx8cJaZBeQAAAAAElFTkSuQmCC', - '1' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMi//xxVKAAAAB3RJTUUH0wUOEDYLcqnX7wAAAAlwSFlzAAALEgAACxIB0t1+/AAAAHpJREFUeNpj/M9AHGAiUh1WhR8FGUGAsMKaD9iM/I8BlmCVwVS4hoUohT8qcNiFyv2zQIWBCIV3amRwu54RKcDRAgQ1KigIcJYK7CqR3QsCFmf+Y8qgeQakbANMAz6FKjUXECbj8zWa76nm61GFw1UhI10KqVGFNFQIADdK9Zj7PsV9AAAAAElFTkSuQmCC', - '2' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMwPUBEjoAAAAB3RJTUUH0wUOEDUqFe2UcgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQxJREFUeNpj/M9AHGAiUt2owkGrkAWF93LFgStPfjCwyGiYRGijqfyPAH9aOJAkQl78RwbICkNQjdB4gUNhD7qzLLAr/CKA4YENSAoRvl7zAUJXvPmxhgfCXILVMxEQvg+IDVUhgtVqDYjkDhD7B2aQIMIx5cOTN29evLAAsaEKObBajQzmQOQMcIQjHLwQgSisIaDwBdS5LHfwK7yhAHVVyX+8CrdAA5HB5gdehQ3Yoxpd4ZcAmDqbD//xKISEIjhU//zHoxDmXQaeFRhOZ8CmzuDOf3wKf8DsDfnyH6/CHJi6P//xKjyDJethVehBpMI7DPgVwrPCCgb8AK5wDwGFcNMF8EkCASOx1QcAGUxu1untnFIAAAAASUVORK5CYII=', - '3' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMxBQugk2AAAAB3RJTUUH0wUOEDU3duv4qwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATdJREFUeNpj/M9AHGAiUt0IVciCzPm7ZceZB28YGBQkLHwcmNFU/keANRJI4ioH/qMAJIUlaHatwaFwBrqrOO5gVfiCB8P9KVgVVkAtnPDh/wkLCFsGq0IFiGQLiH0D06P/GWHJ7O+NOzfuXLlzQRrEhgSawHscwYPurxAcwQMBf/4/aIAYyHIGr8IEeDhO+Y9XoQNUncwOVHGMRPEDSovc+IkzrpGDCQgUbuC1WgBhhsIHfAp3vPn/oIIFKfRxKQSDGohCA4IKX0DTD7YoRAWMUJ9iyQpbn4DBBWUQ5yFEDDnFw622gXAzwBxoYvfB5sYlUI0lD/4/gWWKJdgU/tHAcKjCD6y+PsGCpo4FJbaRgmcNqkqWCThTzxkTJHXo+Ro1HA9uOPHiATDlKJj4eKCVFIzDqWgGAK7GW/haPS+zAAAAAElFTkSuQmCC', - '4' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMyqWttCEAAAAB3RJTUUH0wUOEDUxn4hdngAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKBJREFUeNpj/M9AHGAiUh2FCucyQgCK4H9McIAFixwWhQ8kGIhS+MWAgTiFIQzEKWxhIE7hFgbiFF7hASkQIajwjQpInuUAIYV/XMDyU/4TUlgAlk75T0jhArCszR9CCk+AY07mxX8CCp+AY47nzH8CCn+YgOWW/CekMAYsVfMfl0JGmCBq4kNEDp2zAn0UMmItABjRvDykPTO43DgyFQIANP6pTFLWAdoAAAAASUVORK5CYII=', - '5' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMzPy3XhEAAAAB3RJTUUH0wUOEDUk8lW5dQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQpJREFUeNpj/M9AHGAiUt2oQuIVfmREBzgU3iHWxAfEKiTaRFpZnfAfAbAr/AsxUYagiVCbeQgqhPpFYmukLCOrZupRNJUIB02BCAjAZCK+/Ed2LoJZgm6bzRfsCgMw3JWAXaEBpg8uIGSRPPMBQmXc+P+iggXCnoOQZUQK1K8PgEAjGcQs7QGL6FzG5mtkcAUiyYIQYcRRUkDTLEIWR1b4ixamQMPhrKUP3rx48eDNFXmwdyFiOthixgXqaTAnBcKpwRaOS6A6Mx78fwBVx/IAm8I/KsTGzAkWNHUyb7Ar/L8GNSlK3MCRev7/v+CApC7kBUoUoAX4yQ0nHjwAWqpiE6GNFgNDoAwHAKC2Q2lMNcCmAAAAAElFTkSuQmCC', - '6' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNAObRd4vAAAAB3RJTUUH0wUOEDUc2lcB6wAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUh2Gwq2puryMjKKmmSfRVf5HBkcMEBI+L1CkUBROYUE2QuMFLoVr0CzzwKHwhQC6szZgV1gAtfHI/xs2mEYywsPxp8QHEMVxQ56B4aaJiIKIiIRCPDZf74DwI/5jB4hwPAChbAgG+BWoExlOxkoysuqW3sUV4BoQ/p0SqARLB44AF4HIByDMKMCuEIu7phCrUOADNl/DgMOJ/09SIMwPC7B5hgfC1/kB4kRAOC7YrFaByM0Ac85AOCLYrFaBhSMIQNPlG2wBDg3HP2CSGU/MuEAoiKVXUWxB9cwPiG8UwEGSg5FCMNOjwZ4/byqgpqwgMoWr/MGeZ1agqWPZgSNz/Z+AqnDCf1wK/29B8qbKDhQpRtTE8HfLjjMP3jDwKJh4hKCGJSPNC6lRhTRWCABWpdoxd/bZ4QAAAABJRU5ErkJggg==', - '7' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNA18/fMoAAAAB3RJTUUH0wUOEDUVo4u5TwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt2oQnorZIGzGLFJIyJ40HqGhUiFPFuQ/YUFPBGBmLcDSQybwj8OEDOW/CegsAeiruQ/AYV3OMDqTP4QUugCceCN/wQUQn1a8Z+Awj8qYHUiHwgpXAAxcMJ/Qgp1wOoEPhBSuANiYM5/QgpjIAovEFL4gweszgAz0NASxZ4vYMqHYDKDBiIWhWhWa0CS1x9CVn+8AaYsmAlZfQRC6RDMChADGTQIKjxDrMI7EEoBi0JGlMJe8AOY+sFOSCEeQHQBAABCZ7xyT9fJhwAAAABJRU5ErkJggg==', - '8' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNBeBnwpSAAAAB3RJTUUH0wUOEDUOKe5wowAAAAlwSFlzAAALEgAACxIB0t1+/AAAATVJREFUeNpj/M9AHGAiUt1AKmRB459cc+DBGwYWGQ2LEG1Umf/I4IELkozLA2QpFIUXJFDMEDiBQ+EHGTR3yHzArrAFwwct2BXqQGQ1zvw/owFh6mBXCDXmDJB5BsOrjEhxzfoHIgkiGCGB9xtrgEPtOwvEV6FWY4+ZAAgVc5LhZgKEGYI9wN+gBiPu4Pl/BFWlxA1cMfN/C0rUr8AVhX8K0KyuwaEwASNmarAqPACVTXnw/0oENBFewKYQGhYZYE4MVBM2hVAvQ1LhHQhHBVsUMjIgYhCdhy3PPASTd6GOxBYz0KhOQHajDjY3pkC1Rlz5fweqjqEAm8ILGK5gYLlDZICXYI+ZLzZo6gL+4EgUfyo4kJQJtCCpQ8kKQPB2zZ47L14AU5iMgUMAN7IM43AqHwdQIQAhMPz6Gz5V/wAAAABJRU5ErkJggg==', - '9' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNCQ+T2tEAAAAB3RJTUUH0wUOEDUHUDLIBwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAUZJREFUeNpj/M9AHGAiUh26wr9rE3V5GRlFTTM3/kVT+R8Z7FBBSKjsQJFCUTiFBcWMCbgUHmBBs20FdoV/VNDUMQi8wapwDVS65s2fPToQZgFWhRFIkm8kwGyeH9gUQm2+Aua0QDhb4LJI4XgHQmmDSRMIZw+emIEENAeEcwObQhEIdQHiABRbUGPGBSIQAWL/gHqbB5tnJkC1Fjz5f8IGwxwkhR8EsCQarFE4hViF/wsQCgKgHsSu8H8HLFkUQL2rgUPh/zslOiwMEjFH/kND2geXQvQgqMAWhSjgAIRygAswIuXCpXfevHjz4M0ZdQaGhxo/wAnyBTuWmPnvARGxuPH/iAa+9Ph/A7r9Ai+wK/zvg6ZwzX8cCl9oICtjmfIfl8L/bwIQ6gyO/Met8P//EwUmwHTJo5OyBU2CkdaF1KhCWisEAM/sJxmZkdWnAAAAAElFTkSuQmCC', - 'A' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFwy1U7TfAAAAB3RJTUUH0wUOEC0ZKCZtPQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAO1JREFUeNrt1LERwiAUBuAHZ2GRwsIypQMwQEZwgBQpM4QDZBSLFI7gCA5gQWGRdA5gkTuMSh48eMTUnq96wH98B+QiDCwruTD3D76qF676ueAp0Y9lSBXeSkFWaLAje3T+kkzK4SgpBzZw8pqxJWcdOJuRsyGPbWDk0tS20zw9SXsobdfytJVXdzNsP61i6Zt3K7Ht0UeUgbPdjsrOXMd+2IS2C2qb271HVWi7YANcNXFQsUEVBTXwNdl46jYRxPl52dnwRUZbhkLSDmS8DnxFRWiULxg8UxvobefuRR8ZQYDKtffVVcQWv/RrfgJC4bd0upw4MQAAAABJRU5ErkJggg==', - 'B' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGAusrz2zAAAAB3RJTUUH0wUOEC01Gv4B3gAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNpj/M9AHGAiUh0tFTKiAUHL2rsoKv9DARZDWFr+IwA+hQwMFcQqZDhCrMIIYhWK4FYIYv8444PuV+wK//9/A+UJwBUSCHAL3OEIsdoFyttCpGdiiAtHjoY/RCnk6PlBbBRKrCE6CqcQq5DlDs5whIT3CgUI788EvOEIBCegXB2YPCNMBSNMISqf5TeUjysK90LpP/itfrFEAhZCMHkWdKMYUbk2MAah7BqD02pUYEFkgMu8IE6hD0IdpmegwSejoKLjoY7syaFU7A0HhQA2e4cJytImvAAAAABJRU5ErkJggg==', - 'C' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGBbPqVFqAAAAB3RJTUUH0wUOEC4BEGemqAAAAAlwSFlzAAALEgAACxIB0t1+/AAAASlJREFUeNpj/M9AHGAiUt2owkGrkAWV+3TDgRtPPjBwyGiYBOijSv1HAlcCkGUcTiDLISvsQDOeZQp2hQWYDpuCTeEEbD44ganwDgc2vxpgKoyAyUWc+f9hjgCMtwFd4RuYRxog/ueBcl3QFc6BSmj8gfBrwE40yFmCrjABqrAH5mSZgJ4jX7AEjwlU4Zn/OAAsrp9AaRlccc0IzdeMsBilOPWQrBDmtpfEKnwBpZ8qZq58i6IS6vscKHcBcgQYlOz4gh6OK6AKfaB8G5hN6Aq/wBLPHjB3CczCFIzUA0u2PD0v/j9pgaf1ExgK3wgwYAEOWFL4GizqWC5gyzM1mArnEJkLZ2DPhf//n3BAVmeDkq8ZUZPL3TUn7gBLCgYFBYsAcxQZRmKrDwABNsv9SJSDwwAAAABJRU5ErkJggg==', - 'D' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGC1+orhOAAAAB3RJTUUH0wUOEC4yr7fHvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt1AKmSBsxiRhXlkNBxCpFFU/ocBTDMyPvxHADwKGRgUbhCpkEHiCZEKGRyIVciwArdCIPPFGg8YzwSvQiBogXFvEFD43wDKnQDl44yZGCh9glAU2sCsJqRQBkq/gMUw3G2wuP6PnU/H9PgRSgsQUvgESosQUngFSqsQUrgCSsNiCFcU7oBx9+CL6w8XamB5SeUPkelxAZEJ1+YPcQolXhCXFTTuEJULOUq+IOVrFgasQELBxMaHG1mEcTiVjwOoEADAIkCnGpmJKgAAAABJRU5ErkJggg==', - 'E' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGDeDwEE0AAAAB3RJTUUH0wUOEC8CkHXGUwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt2owkGrkAXGYMQqjUgJQ8EzpPsa05+D140oMYTk4KEQ4MMqZqgUhcM1czESW30AABfqB1XDnLzcAAAAAElFTkSuQmCC', - 'F' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGQe8AkDZAAAAB3RJTUUH0wUOEC8JB6cf2wAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt3wUsiCYDJikUYE3lDwDDm+xvTp4HUjIoaQXTsUAnxYxcyoQryAcUSWuAAW/gZTg/yEMAAAAABJRU5ErkJggg==', - 'G' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRFI1vWIAAAAB3RJTUUH0wUOEC8QY8y3GwAAAAlwSFlzAAALEgAACxIB0t1+/AAAASZJREFUeNpj/M9AHGAiUt0IVciCwvt7ZM+FOy8+MDBwSEho2AQII8v9R4A/U2RQtHEUfEBIIim8YYBhn8oNLAqP8GBxmcwbDIU3sKljYIhAV/jHgAE7uICmcAJMQqDmwp//D2YowPgxqAr/wPyr8QAi8EEHwleIQFW4BxYicG+eEHEomHECET5QhRVQhQn/cQFoFJ6AKgwgFNcPoFwdnAoZIXmGERahKDwkIdqlR1j4PiRW4RVCCmExvQenQrSYEXiDiAoUBfC4loAK23yBSnzArhCRehRmAJPFnRUxHDgU/lDA7zZECj/Cgl2dAkaeWYNVZcoHDIX/94hgKLM4gS27/v9QIICizGMDkiQjSon7c8eBCw+e/GFgkZEwsHCRRpZiHE5FMwCa2YE+WcAOUwAAAABJRU5ErkJggg==', - 'H' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRw2Z4k1AAAAB3RJTUUH0wUOEC8agxleBQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD1JREFUeNpj/M9AHGAiUt2oQvyABUozQml4+KMLDAXPDAWFLGh8RlwKh4JnaB88GOlxELhxVCFewDgEynAAN2sFVHAvevkAAAAASUVORK5CYII=', - 'I' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGSlg1E0WAAAAB3RJTUUH0wUOEC86uHd+zQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt1AKmRBMBkxJJE9OhQ8Q32FjGhxDQsjjCQwFDwzqnCwKkRKZqO5EBMwDqcSl2iFAMMeB0s/kLo2AAAAAElFTkSuQmCC', - 'J' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGywiiNsbAAAAB3RJTUUH0wUOEDAFw0tdbgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKdJREFUeNpj/M9AHGAiUh3xClmwijJCaSR3Ud/qUYWjCklTyIHEhifctw8ePHgCxO+B7L9QMQlsChW+QOiX4gwMd6BiItisVoHSB6AYWQwM/kNBBszkC/9PwKyc8B8B4Ar3YPHMHWwK/xtgqAv4j1XhEfScK/EEu8L/a1BVStz4j0Ph/yPItoe8QFH3nxGlkNq75cKDB0DDVBwitNEcwjhwpdmoQrwAAN6ioiFapgUdAAAAAElFTkSuQmCC', - 'K' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHAEoFhGpAAAAB3RJTUUH0wUOEDANzZDVXAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPZJREFUeNpj/M9AHGAiUt2owgFSyAgFMOGDrDARxkKo0H8wYEDh/b/AAzepACqEVeEdCQx1WBW+0ICry/mPR+EXE7i6kD94FP5xwaYOi8IIrOowFRbA1Xkgq8NQ2ANXZ/PlPx6FS3CpQ1fIAmOIoKn7jxbXf2CMNxvQIxvVRAQQ+YDXaiSQQqxChiOEFGoIQGidP/gVStxogLI68CqUuPH/BzSVcTzAoxCo7v//ObBIxK0QrO7/H1iCXIFT4QkIFxbaMh9wKYQJO0D5OYQUnoDF/QkCCuHJ1+APAYV3YOloAgGF8JTO84SAwjfQiGQIgPAZqV4rAACnKSarzdlc4gAAAABJRU5ErkJggg==', - 'L' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHA64qQw4AAAAB3RJTUUH0wUOEDAXMPIsJgAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt2QUMiCYDJCaezhMBQ8M6pwVCEdFLJgCjEisRH5Zyh4hvoKGUdkQUq0QgARaARRV9jUFQAAAABJRU5ErkJggg==', - 'M' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHBhMfblpAAAAB3RJTUUH0wUOEDAqaJpgNwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPNJREFUeNrdlK0OgzAUhS8bCQYxMYmcmEAgEAgejQfZQyG2pAIxOYlATkAu691o2tvSYia2iv7lyzn3NG0jhG1tt5H7Aggom7ZuaKPhBFqKV+pFWDGjjcxStEAYXuvBkrKtoVX+gdRiK9i6sxjgeVGUMJzWwZLACaZOTqoAOAronmrlBuvPkQsIgHn8BqnE2AMmhaaYJ57jqTRFMwsDyW249XaJLhAujizm7UFM5XCUXTqiTvBLQYWRc7H3WWt+3NmlyGbOGh9q/45mjQxUb+CA6A2jSqu5MweX0ooQWLJxLYx6fz0GwmBOsww5GP3At/dX4Ayb7qpFI9y5ygAAAABJRU5ErkJggg==', - 'N' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHC6DxyzwAAAAB3RJTUUH0wUOEDAye/b4YQAAAAlwSFlzAAALEgAACxIB0t1+/AAAALRJREFUeNpj/M9AHGAiUt0IV8gIARsRMlAROP8/BEB5Ii/+/0cVgXNRhRk8iFXIMIFYhRxXiFTIYPCDSIUMBcQqZNhDrEKZN0QqZAggViHDHIIKRSAUzx1CCrdAaZM/BBT+z4Eyaggp/KEDYbAcIaDw/wUWCEuBkML/PagBgFvhfxdiFT4RIVLh/zXEKvyfQqzCLypEKvx/hoVIhf9biFX4x4ZIhf8fCBCp8P8KNBHG4VQ0AwDEOyeZhO5p1AAAAABJRU5ErkJggg==', - 'O' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQExDSDoAAAAB3RJTUUH0wUOEDA4myMRfwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUt3wUsiCyv265ciZJ08YGGRkDGwCuFGk/iOBDwU8SDIcGS+Q5JAV7hBBs45nAVaFC1gwXTYBi8IdWNQxMCzAUPhBBJs6Bp4n6AoLYFI6az78f7NEB8ZNQFP4QwAqEfADwg+A+f0NqsI1UHGBDzCnSKC6EhYzB6B0Cj+UwZ+CKgNTeAZKu8C94QGlL6DGjAyU+wAeXC+gIiIQLiM0KzDC9CFCBlWICsnsL3aFMDc+hcs8QZWBKYSF2g24whvYFZpA6T1whUegNCwyoYGxAmYyLGZ+wOxYghqFX2BpO+APmP8nBspHj2uk1LPizf8PGyxgXPTUQ3x6JDqF//8/AYs6bHkGmCYF0O3FnguBCSaFA0kZS8IDJDlG1IIUVFK8eABMWzI6DgHCyDKMI7LEBQCD5YgI9wbKGgAAAABJRU5ErkJggg==', - 'P' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQvR2Mn2AAAAB3RJTUUH0wUOEDEDMzPJGgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKVJREFUeNpj/M9AHGAiUh05ChlRAKdu4k5Ulf9hANMQiwf/EQCfQgaJB0QqZHAhViHDEbg0AV8vwRM8QN0v5vBAOSfw+BrMWQDl8MClGeEKGGEKQcRXHmQemTGD1RMy+N14o4MDyvGAS7NgGMaIzPHAYyIy4HhBZMy0EBmFIX+IUsjRgqQOi2fAgEVBwyVGGEUEQw2O3EbLzDWSFDIOhtJsVCEWAAC/Yt2X+2PYcgAAAABJRU5ErkJggg==', - 'Q' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHRxSC0wxAAAAB3RJTUUH0wUOEDEKSu9xvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAW1JREFUeNpj/M9AHGAiUt2QUMiCzPm65cCZF08YGGRkDBx8uNFU/oeDDwU8SOIcBS/+IwOEwh0iaEYIrMCqcA4LprsmYFG4A4s6BoYFGAo/iGBTx8DzAl1hAUxKZ8WH/29W6MC4KWgKfwhAJXx+gPl/QmB+/4KqcANUXOQDVPiLBFRkCUwhJGb2wGzihzK4U6CMA6hReAbKc4F7wwFKX0CNGRkoB+HJJ1ARGZgAIziFM8J0IUIGXYjMZPaXkEJYYDyBiz+EuRFVoQKUdwWIz6qWvmRguAMVkUBVaIIUalPu9GgshIefAWrwrIHp//L/DQc4KjFiBi2uQ/7832KB5AX0uP5fAZOx2PDhfwNCIXrq+f9BhgEb4HmCkcL3YE3hSHkBnmfWYFMpsoaYXAgGDgcwFKLlaxYOCG2DqRCYrldkmIACUMIgZsaTI5Cg3IBNISp4AoovlT+EFf7/kYPkb3wK//8/YAGPGcYhUIYDAHBC9Yak1w7iAAAAAElFTkSuQmCC', - 'R' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHSkEuIgSAAAAB3RJTUUH0wUOEDEUsOBM3QAAAAlwSFlzAAALEgAACxIB0t1+/AAAAOZJREFUeNpj/M9AHGAiUh0NFLJAaUY0YRkJHYcQdmSh/xCAzRCZHf8RAJ9CBpYNRCpkEHgBV4jfMx+mEOVGIDDAaTWY82aPBZTLgV8hUCkaH6cbP8B8gxHgyODjgwstMDfiVIgWQyFE+lrhB3EBznOFuJgxuUFMXPPEbPmDpA53FH55osKMIoAe4F826MDMvPMfj9WgWFGBBeIf/Ar/H4FxJhBQ+B8WzCIfCCi8A4uvBgIK/2fA/POCgMIXHFBuDqH02ABLM3cIKPwgAuVHEFD4fwJM4AIBhT9goe4AFWAcAsXesFIIAEvJyZHTCSiTAAAAAElFTkSuQmCC', - 'S' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHTRnvuTLAAAAB3RJTUUH0wUOEDEbIF9RTAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVZJREFUeNpj/M9AHGAiUt2oQvyABYX398CWK3de/GBgkVEw8HFgRpH7jwSWqCDLyCxAlkNS+CcG3boY7AozMB3Wgk3hGSw+4HgBl0b4egIWhT9mYPGMBFQg4MH/D2tgvrKASzPC0yMjlP7CDSTOmrDIMDDwiHBsxzSRBypw5j9WgFDoAPNAxIQjX/ApXIDsC4OCLV9wKfzjwIACOEIO4IiZFxbooePzAqvC/z9qONBUStzAqvD//zc9BqgqNX5gVwgETxbkmCClvSk4FYLdsCMCptAGI2YSGV78+PLmz5MX4mDu1ByIMM9n9JiBxe4caGChy8MZMMsUIEFyAMoVwVC4BGaEwpI3/9/MEYGlJQyFPwQYsIE1mL7GlnCR0iNSXLtgqpO4gy1mvtigq1NAxCBKgP9pEUFWxlOCnNIYUYrmn3v23Ljx5gsw88sYOPhwI0sxDoEyHAABtSc836a1EQAAAABJRU5ErkJggg==', - 'T' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHgUdTbcyAAAAB3RJTUUH0wUOEDEgkVS4aAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADdJREFUeNpj/M9AHGAiUt0IVcgCpRlxyMODeSh4hmiFjGipB+Z7jEQ1FDwzqnBU4WBSyDicimYAb/AFTaJpyH8AAAAASUVORK5CYII=', - 'U' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHhEHl2NPAAAAB3RJTUUH0wUOEDEon48wWgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKlJREFUeNpj/M9AHGAiUh3xClmgNCOUhrsEXYD6Vo8qHFVIuUIVKP0USr+E0jLoCjWg9A4ovQVNHJjUIaADZsILMPeFApRfA5X/D1N4AaZRYc6b/2+WwNQxXEBX+N8Bqxcc/mMoPMGCRR3LBUyF/2dgUTjjPxaF/6egm8ky5T9Whf9P2KCoMziBJPefEaWQurjnzIMXL34wsMhoWHiYo2hjHLjSbFQhXgAAKzejCLAOcVMAAAAASUVORK5CYII=', - 'V' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHh/gL05IAAAAB3RJTUUH0wUOEDEuduyVbwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVNJREFUeNpj/M9AHGAiUt2owoFRaMgIAYlIMqlQMUMo/z8ITIByRP78hwMRqNgECBei8AULVPQIXN0RqAjLGwgfYrW4B1R4DdzmLVDaQxjZ6v8roDwVuIkqMK3/ka3+/0MAKn4FKn4D5uof/5GtZmCPgEpsQHNDBDsDitVwt5tA+RZQ/pn/qFYj3PQEzHsC5WnA3QyPmQQU3+5AE0VYDTfDBcxzgQbik/8YVv93gMp9AbK/cEAD8T+m1TBb/oD8veEHhs0IE2GmxADZMRAmz4//WKxGkv3DA2Gm/MeqcA/Ujj1w1hHsCv/LQKQz/megRzyawgqIvAxMRwsuhbCEAEvGT3AphEUwNCU5IEv9R8lcUH9/wAxE5HAEgjccSBI8X3CbKOyBxAnhxm3i/w1IEgdQZFA98/+PCFydDKo6VKsZmGPQ0wgOq/+fgYvfQTORkeq1AgCIAvD7+THsDgAAAABJRU5ErkJggg==', - 'W' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFhZRKnzkAAAAB3RJTUUH0wUOEDIR66frkQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNrtlK1ywkAUhZdMZsJMKyIqKhAIBAKBiEBEVCDyCJV9iIo+Do9QGRERgUBEVCAqKhAIREVERURnTvfn3t27xSA6g+kOQ/ZkP/aec5NlBHXZSC7k/sE/AhUwoVkDPQ58/2RUQ2IC6B1XpN7MV8tg62/pUdjSDO7OwR2J0pbekpqZYlMG50bNSGwBDQ4pyV5YtCZ7mqZf1mO2IN2Jynba0XRx49pThjQCbEKWFfVRpIlBzlK4PuLdpxEWlTr4LHvYMEDOaTYS3HCW3DAJt8mmaSXYchZbOfEzkyYGZRbrEbX8qe7GMpLqFeyxV9F4fon1pwcxjxbqJpJTBPBJLoyHYSz1I3xq78aOMssepHZZHFjKhbX9/AZd6e9bsdABeyHTQXiE2PLO6PugCwiP/r1QVLYSlpXwKE1Wno7b7jY+hoWj0aegPyA9+jPrzgqwZJ0j8hhMVtElmDoD19FFPAvamc+sOXBm+KdYEzC63p/9D7Tr72kj/8qjAAAAAElFTkSuQmCC', - 'X' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHi/G9n7kAAAAB3RJTUUH0wUOEDIXAsROpAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAT9JREFUeNpj/M9AHGAiUt3IVhjKCAFr4RJroSKBMIH/YPBEAMITeQLh//8gAxHggQlAFf6fAdXnA+WnQPkT/qMp/O8AlVkA5h2A8kz+YCi8wQGREngA5PxQgXBYzvzHUPi/A2qIA5BdAmUX/Mei8I8BVHbK/wssEJbMB2wK/5+ASvPcgGlZ8x+rQriFAmghgKHwiwJKXPA8wKXw/x4UhT3/cSr8n4CkzuAPHoVvRODqWE6gyPxHTT1ffiAUCjCgAhRtDkgSFnisnoJixAScCh/wEBk8DmiucsChcA5MQQSMMQWrQlgiZ0iAByey5QiFPlBZnS//v+hgxjZc4QKYKVeAnCswby3AUAi3eAGKNoEn6Ap94A5EjXUfNIUrEA6EALgzl6AohCUGsAMhAOZMkTfICkMw3I5wZgiEyzicimYAFRFkVwgDfJ0AAAAASUVORK5CYII=', - 'Y' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHjkyIsu1AAAAB3RJTUUH0wUOEDIkvRQvsgAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNrt1L0NgzAQBWAcUVB6AAZgBAoKhmAICoZgCAoKxmAECkbwABSUlBRILwF8duwYhFJEihJ37+6T5T9g8K6N20X3FdDDNjKKOeTIqZLtWcKBU73bCx1lPhgQNTWieY1zRLmGCZFQp1xTSSmBDUUgW754BF+GQLxAPUkMxMb0FlzUsqpKLXhxQPRqo+oIerggCvuMC7jhFJounA4gWhO2OIL6Jp/uzglHrh0fTyAaDRucQaTkUpxDQVBYDWZ/hYze6bsv/A8/DNlP/kgvwzuer4kCMGPZDgAAAABJRU5ErkJggg==', - 'Z' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHwfqWOdfAAAAB3RJTUUH0wUOEDIrLasyIwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAL5JREFUeNrl1C0OwkAQBWCWQIJEVPQIFT0GAlHBMRBIBKIHqahAIDlERY9R0UOs3ORh5qVLunmp5GfUZvczbzKzDqtltV7ofgtueHCp16h33xBGwn0KYqoTO/J868Csaj418e0cPujOkLDfmTsECcfcXOGhoC/NZQMUDBUDd5DwxiAtJGzprpCw48xVQcIhM1d6KOgLc/kIBcORgXtIeGGQOyRs6Oq0g7P92YbkRE7bRZhcwhh+6nLF5f7yx30B8Z7FgxzMWtEAAAAASUVORK5CYII=', - ); - - return $_png; - } - - // Function get_rgb by Frank Burian - // http://www.phpfuncs.org/?content=show&id=46 - function get_rgb($hex) { - $hex_array = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, - 'F' => 15); - $hex = str_replace('#', '', strtoupper($hex)); - if (($length = strlen($hex)) == 3) { - $hex = $hex{0}.$hex{0}.$hex{1}.$hex{1}.$hex{2}.$hex{2}; - $length = 6; - } - if ($length != 6 or strlen(str_replace(array_keys($hex_array), '', $hex))) - return NULL; - $rgb['r'] = $hex_array[$hex{0}] * 16 + $hex_array[$hex{1}]; - $rgb['g'] = $hex_array[$hex{2}] * 16 + $hex_array[$hex{3}]; - $rgb['b']= $hex_array[$hex{4}] * 16 + $hex_array[$hex{5}]; - return $rgb['r'].','.$rgb['g'].','.$rgb['b']; - } - - // Function gdVersion by Hagan Fox - // http://de3.php.net/manual/en/function.gd-info.php#52481 - function gdVersion($user_ver = 0) - { - if (! extension_loaded('gd')) { return; } - static $gd_ver = 0; - // Just accept the specified setting if it's 1. - if ($user_ver == 1) { $gd_ver = 1; return 1; } - // Use the static variable if function was called previously. - if ($user_ver !=2 && $gd_ver > 0 ) { return $gd_ver; } - // Use the gd_info() function if possible. - if (function_exists('gd_info')) { - $ver_info = gd_info(); - preg_match('/\d/', $ver_info['GD Version'], $match); - $gd_ver = $match[0]; - return $match[0]; - } - // If phpinfo() is disabled use a specified / fail-safe choice... - if (preg_match('/phpinfo/', ini_get('disable_functions'))) { - if ($user_ver == 2) { - $gd_ver = 2; - return 2; - } else { - $gd_ver = 1; - return 1; - } - } - // ...otherwise use phpinfo(). - ob_start(); - phpinfo(8); - $info = ob_get_contents(); - ob_end_clean(); - $info = stristr($info, 'gd version'); - preg_match('/\d/', $info, $match); - $gd_ver = $match[0]; - return $match[0]; - } - + $class = "captcha_engine_$engine"; + return new $class($session_id, $row); } -// define('ENANO_CAPTCHA_BIGNFAT', ''); - ?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/dicts/default.php Wed Feb 06 18:41:47 2008 -0500 @@ -0,0 +1,6690 @@ +<?php +$dict = array( +'aback', +'abacus', +'abaft', +'abase', +'abaser', +'abate', +'abated', +'abater', +'abbess', +'abbey', +'abbot', +'abduct', +'abeam', +'abhor', +'abider', +'abject', +'abjure', +'ablate', +'ablaze', +'abler', +'abloom', +'aboard', +'abode', +'abound', +'about', +'above', +'abroad', +'abrupt', +'abseil', +'absent', +'absurd', +'abused', +'abuses', +'abuzz', +'abyss', +'acacia', +'accede', +'accent', +'accept', +'access', +'accost', +'accrue', +'accuse', +'acetic', +'ached', +'achene', +'aches', +'aching', +'acorn', +'acquit', +'acrid', +'across', +'acting', +'active', +'actual', +'acuity', +'acumen', +'acute', +'adage', +'adagio', +'adapt', +'addend', +'addle', +'adduct', +'adept', +'adhere', +'adieu', +'adjoin', +'adjust', +'adman', +'admen', +'admit', +'adobe', +'adopts', +'adore', +'adorn', +'adrift', +'adroit', +'adult', +'advent', +'advert', +'advice', +'aegis', +'aerial', +'aether', +'affair', +'affine', +'affix', +'afford', +'affray', +'afield', +'afire', +'aflame', +'afloat', +'afoot', +'afore', +'afoul', +'afraid', +'afresh', +'after', +'afters', +'again', +'agape', +'agate', +'agave', +'ageing', +'ageism', +'ageist', +'agency', +'agenda', +'agent', +'agents', +'aghast', +'agile', +'agleam', +'aglow', +'agony', +'agouti', +'agreer', +'ahead', +'aided', +'airing', +'airway', +'aisle', +'aitch', +'alack', +'albeit', +'albino', +'album', +'alcove', +'aleph', +'algae', +'algal', +'alias', +'alibi', +'alight', +'align', +'aligns', +'alike', +'alive', +'alkali', +'alkyd', +'alkyl', +'allay', +'allele', +'alley', +'allier', +'allies', +'allot', +'allots', +'allow', +'allows', +'alloy', +'almond', +'almost', +'alnico', +'aloft', +'aloha', +'alone', +'along', +'aloof', +'aloud', +'alpaca', +'alpha', +'altar', +'alter', +'alumna', +'alumni', +'always', +'amass', +'amaze', +'amber', +'ambit', +'amble', +'ambles', +'ambush', +'amends', +'amener', +'amerce', +'amide', +'amidst', +'amigo', +'amine', +'amino', +'amiss', +'amity', +'amnion', +'amoeba', +'among', +'amoral', +'amount', +'amour', +'ampere', +'ample', +'amulet', +'amused', +'anders', +'angle', +'angora', +'angry', +'angst', +'animal', +'animus', +'anion', +'anise', +'ankle', +'anklet', +'annal', +'anneal', +'annex', +'annexe', +'annoy', +'annual', +'annul', +'annuli', +'annum', +'anode', +'anoint', +'anomic', +'anomie', +'anorak', +'anther', +'antic', +'antler', +'antral', +'anvil', +'anyhow', +'anyone', +'anyway', +'aorist', +'aorta', +'apace', +'apart', +'apathy', +'aphid', +'apical', +'apiece', +'apish', +'aplomb', +'apogee', +'apolar', +'appeal', +'appear', +'append', +'apple', +'applet', +'approx', +'apron', +'apter', +'aptest', +'arable', +'arbour', +'arcade', +'arcana', +'arcane', +'ardent', +'ardour', +'areal', +'arena', +'areola', +'argent', +'argon', +'argosy', +'argot', +'argue', +'argued', +'argues', +'aright', +'arise', +'arisen', +'ariser', +'armada', +'armed', +'armer', +'armful', +'arming', +'armlet', +'armour', +'armpit', +'aroma', +'arose', +'around', +'arrack', +'arrant', +'arras', +'array', +'arrive', +'arrow', +'arroyo', +'arsine', +'arson', +'artful', +'artist', +'ascend', +'ascent', +'ashen', +'asher', +'ashlar', +'ashore', +'ashram', +'aside', +'asked', +'askew', +'aslant', +'asleep', +'aspect', +'aspen', +'aspic', +'assay', +'assen', +'assent', +'asses', +'assess', +'asset', +'assign', +'assist', +'assize', +'assort', +'assume', +'aster', +'astern', +'asthma', +'astir', +'astral', +'astray', +'astute', +'asylum', +'ataxia', +'ataxic', +'atilt', +'atlas', +'atoll', +'atomic', +'atonal', +'atria', +'atrial', +'atrium', +'attach', +'attain', +'attar', +'attend', +'attic', +'attire', +'attune', +'auburn', +'audio', +'audit', +'auger', +'aught', +'augite', +'augur', +'augury', +'august', +'auntie', +'aunty', +'aural', +'aurora', +'auteur', +'author', +'autumn', +'auxin', +'avant', +'avast', +'avatar', +'avaunt', +'avenge', +'avenue', +'averse', +'avert', +'avian', +'aviary', +'avouch', +'avowal', +'avowed', +'avower', +'avows', +'await', +'awake', +'award', +'aware', +'awash', +'aweigh', +'awful', +'awhile', +'awing', +'awning', +'awoke', +'awoken', +'axial', +'azalea', +'azure', +'babble', +'babel', +'baboon', +'backer', +'backup', +'bacon', +'baddie', +'badge', +'badger', +'badman', +'badmen', +'bagel', +'bagful', +'bagged', +'baggy', +'bailee', +'bailer', +'bailey', +'bails', +'bairn', +'baiter', +'baize', +'baked', +'bakery', +'baking', +'balboa', +'balder', +'baleen', +'ballet', +'balls', +'ballsy', +'balmy', +'balsa', +'balun', +'bamboo', +'banal', +'banana', +'banded', +'bander', +'bandit', +'bands', +'bandy', +'bangle', +'banish', +'banjo', +'banner', +'banns', +'bantam', +'banter', +'banyan', +'banzai', +'baobab', +'barbel', +'barber', +'barfly', +'bargy', +'barium', +'barker', +'barley', +'baron', +'barony', +'barque', +'barre', +'barred', +'barrel', +'barren', +'barrio', +'barrow', +'barter', +'baryon', +'basal', +'basalt', +'based', +'baser', +'bases', +'basher', +'basic', +'basil', +'basing', +'basis', +'basset', +'basso', +'baste', +'batch', +'bated', +'bater', +'bathe', +'bathos', +'batik', +'bating', +'batman', +'batmen', +'baton', +'battle', +'batty', +'bauble', +'baulky', +'bawdy', +'bawler', +'bayou', +'bazaar', +'beach', +'beadle', +'beady', +'beagle', +'beanie', +'beano', +'bears', +'beast', +'beaten', +'beaut', +'beaux', +'bebop', +'becalm', +'became', +'beckon', +'become', +'bedaub', +'bedbug', +'bedeck', +'bedim', +'bedlam', +'bedpan', +'bedsit', +'beech', +'beefy', +'beery', +'beetle', +'beeves', +'befall', +'befell', +'befit', +'befog', +'before', +'befoul', +'began', +'beggar', +'begin', +'begone', +'begot', +'begum', +'begun', +'behalf', +'behead', +'beheld', +'behest', +'behind', +'behold', +'behove', +'beige', +'being', +'belate', +'belay', +'belch', +'belfry', +'belie', +'belief', +'belier', +'belle', +'bellow', +'belly', +'belong', +'below', +'belted', +'beluga', +'beman', +'bemire', +'bemoan', +'bemuse', +'bench', +'bends', +'benign', +'benumb', +'berate', +'bereft', +'beret', +'berry', +'berth', +'beryl', +'beseem', +'beset', +'beside', +'besot', +'bester', +'bestir', +'bestow', +'betake', +'betcha', +'betel', +'bethel', +'betide', +'betook', +'betray', +'bevel', +'bewail', +'beware', +'beyond', +'bezel', +'biased', +'bicarb', +'biceps', +'bicker', +'bidden', +'bidder', +'biddy', +'bider', +'bidet', +'bigamy', +'biggie', +'bight', +'bigot', +'bigwig', +'bijou', +'bijoux', +'bikini', +'bilge', +'billow', +'billy', +'bimbo', +'binary', +'binder', +'bindle', +'binge', +'bingen', +'bingo', +'bionic', +'biopic', +'biopsy', +'biota', +'biotin', +'biped', +'birch', +'birdie', +'birth', +'births', +'bisect', +'bishop', +'bison', +'bisque', +'bistro', +'bitchy', +'biting', +'bitser', +'bitten', +'bitty', +'bizzes', +'black', +'blade', +'blame', +'blanc', +'blanch', +'bland', +'blank', +'blare', +'blast', +'blazon', +'bleach', +'bleak', +'bleary', +'bleat', +'bleed', +'bleep', +'blench', +'blend', +'blight', +'blimey', +'blimp', +'blink', +'blinks', +'bliss', +'blithe', +'blitz', +'bloat', +'block', +'bloke', +'blond', +'blonde', +'bloody', +'bloom', +'bloop', +'blotch', +'blotto', +'blouse', +'blown', +'blowy', +'blowzy', +'bluer', +'bluest', +'bluesy', +'bluff', +'bluing', +'bluish', +'blunt', +'blurb', +'blurry', +'blurt', +'board', +'boards', +'boasts', +'bobbin', +'bobble', +'bobby', +'bobcat', +'boccie', +'bodega', +'bodice', +'bodied', +'boding', +'bodkin', +'boffin', +'boggle', +'boggy', +'bogus', +'boiled', +'boiler', +'bolero', +'bolted', +'bolter', +'bolts', +'bolus', +'bonbon', +'bongo', +'bonito', +'bonnet', +'bonnie', +'bonny', +'bonsai', +'bonus', +'bonzes', +'booby', +'boodle', +'boogie', +'boohoo', +'booked', +'bookie', +'books', +'boomer', +'boost', +'bootee', +'booth', +'booty', +'booze', +'boozy', +'borate', +'borax', +'boring', +'borne', +'boron', +'borzoi', +'bosomy', +'boson', +'bosser', +'bossy', +'bosun', +'botch', +'botfly', +'bother', +'bothy', +'bottle', +'bough', +'bought', +'bouncy', +'bovine', +'bowed', +'bowel', +'bower', +'bowing', +'bowser', +'bowwow', +'bowyer', +'boxcar', +'boxful', +'boxing', +'boyer', +'boyish', +'bracer', +'bract', +'braid', +'brainy', +'braise', +'brake', +'branch', +'brand', +'brands', +'brandy', +'brash', +'brass', +'brassy', +'bratty', +'brave', +'bravo', +'brawl', +'brawn', +'brawny', +'brayer', +'braze', +'brazen', +'breach', +'bread', +'bream', +'breech', +'breed', +'breeze', +'breezy', +'breve', +'brevet', +'brewer', +'briar', +'brick', +'bridal', +'bride', +'bridge', +'bridle', +'brief', +'brier', +'bright', +'brine', +'briner', +'bring', +'brink', +'briny', +'brisk', +'broach', +'broad', +'brogue', +'broil', +'broke', +'broken', +'broker', +'bronc', +'bronco', +'bronze', +'brooch', +'broody', +'brook', +'broom', +'brose', +'broth', +'brown', +'brows', +'browse', +'bruin', +'bruise', +'bruit', +'brunch', +'brunet', +'brunt', +'brush', +'bruter', +'bubble', +'bubbly', +'buboes', +'bucker', +'buckle', +'buddy', +'budge', +'budgie', +'buffet', +'bugger', +'buggy', +'bugle', +'build', +'builds', +'bulgy', +'bulker', +'bulky', +'bullet', +'bully', +'bummed', +'bumper', +'bumpy', +'bunch', +'bunchy', +'bundle', +'bungee', +'bunker', +'bunkum', +'bunny', +'burble', +'burbs', +'burden', +'bureau', +'burgh', +'burgle', +'burial', +'buried', +'burier', +'burlap', +'burler', +'burly', +'burned', +'burnt', +'burrow', +'bursa', +'bursae', +'bursar', +'burst', +'bursts', +'bushel', +'busher', +'bushy', +'buskin', +'busman', +'busmen', +'busted', +'butane', +'butene', +'butler', +'butter', +'butyl', +'buying', +'buyout', +'byers', +'bygone', +'byline', +'byname', +'bypass', +'bypath', +'byplay', +'byroad', +'byway', +'byword', +'cabal', +'cabala', +'cabana', +'caber', +'cable', +'cacao', +'cache', +'cacher', +'cackle', +'cacti', +'cactus', +'caddie', +'caddy', +'cadent', +'cadet', +'cadge', +'cadre', +'caeca', +'caecal', +'caecum', +'caftan', +'cagey', +'cagier', +'cahoot', +'cairn', +'calico', +'caliph', +'calla', +'callee', +'callow', +'calls', +'calve', +'calves', +'calyx', +'camel', +'cameo', +'camion', +'camped', +'camps', +'campus', +'campy', +'canal', +'canard', +'canary', +'cancan', +'cancel', +'candid', +'candle', +'candy', +'canine', +'caning', +'canker', +'cannon', +'cannot', +'canny', +'canopy', +'canst', +'canted', +'canter', +'canto', +'canton', +'cantor', +'cants', +'canvas', +'canyon', +'caper', +'capita', +'capon', +'capped', +'captor', +'carafe', +'carat', +'carboy', +'cared', +'careen', +'career', +'cares', +'caress', +'caret', +'cargo', +'caries', +'caring', +'carnal', +'carny', +'carob', +'carol', +'carom', +'carpal', +'carpel', +'carpi', +'carpus', +'carrel', +'carrot', +'carte', +'cartel', +'carven', +'casaba', +'casbah', +'cased', +'casein', +'cashew', +'casing', +'casino', +'cassia', +'caste', +'castle', +'castor', +'casual', +'catchy', +'cater', +'catgut', +'cation', +'catkin', +'catnap', +'catnip', +'cattle', +'catty', +'caucus', +'caudal', +'caught', +'caulk', +'causal', +'caused', +'caveat', +'caver', +'cavern', +'caves', +'cavil', +'caving', +'cavity', +'cavort', +'cayman', +'cease', +'cedar', +'celery', +'cellar', +'cement', +'censer', +'cereal', +'cerise', +'cerium', +'cermet', +'chador', +'chafe', +'chafer', +'chaff', +'chain', +'chaise', +'chalet', +'chalky', +'champ', +'chancy', +'chant', +'chaos', +'chapel', +'chard', +'charge', +'chary', +'chase', +'chasm', +'chaste', +'chatty', +'cheap', +'cheat', +'check', +'checks', +'cheek', +'cheeky', +'cheep', +'cheer', +'cheery', +'cheese', +'cheesy', +'cheque', +'cherry', +'chert', +'cherub', +'chest', +'chesty', +'chewy', +'chicer', +'chichi', +'chick', +'chicle', +'chide', +'child', +'chilli', +'chilly', +'chime', +'chimp', +'china', +'chine', +'chink', +'chino', +'chintz', +'chippy', +'chiral', +'chirp', +'chirpy', +'chisel', +'chitin', +'chive', +'chivvy', +'chock', +'choice', +'choir', +'chokes', +'choler', +'chomp', +'choose', +'choosy', +'choppy', +'choral', +'chord', +'chorea', +'chorus', +'chose', +'chosen', +'chrism', +'chroma', +'chrome', +'chubby', +'chuck', +'chuff', +'chukka', +'chummy', +'chump', +'chunky', +'churl', +'churn', +'chute', +'chyme', +'cicada', +'cider', +'cigar', +'cilia', +'cilium', +'cinch', +'cinema', +'circa', +'circle', +'circus', +'cirque', +'cirri', +'cirrus', +'cissy', +'citron', +'citrus', +'civet', +'civic', +'civics', +'civil', +'clack', +'claim', +'clammy', +'clamp', +'clang', +'claque', +'clash', +'clasp', +'classy', +'clause', +'clave', +'claver', +'clawer', +'clean', +'cleans', +'clear', +'cleat', +'cleave', +'cleft', +'clench', +'cleric', +'clerk', +'clever', +'clevis', +'click', +'client', +'cliff', +'climax', +'climb', +'clime', +'cling', +'clingy', +'clinic', +'clink', +'clique', +'cloaca', +'cloak', +'cloche', +'clock', +'clomp', +'clonal', +'clone', +'clonk', +'close', +'closed', +'closer', +'closes', +'cloth', +'clothe', +'clouds', +'cloudy', +'clout', +'clove', +'cloven', +'clown', +'cluck', +'clump', +'clumpy', +'clumsy', +'clung', +'clunky', +'clutch', +'coaler', +'coarse', +'coast', +'coated', +'coater', +'coats', +'cobalt', +'cobble', +'coble', +'cobra', +'cobweb', +'cocci', +'coccus', +'coccyx', +'cockle', +'cocky', +'cocoa', +'cocoon', +'coddle', +'codec', +'coded', +'coder', +'codex', +'codger', +'coding', +'codon', +'coeval', +'coffee', +'cogent', +'cognac', +'cohere', +'cohort', +'cokey', +'coleus', +'colic', +'collar', +'colony', +'colter', +'comae', +'combed', +'combo', +'comedy', +'comely', +'comer', +'comes', +'comet', +'cometh', +'comfit', +'comfy', +'comic', +'coming', +'comity', +'commie', +'commit', +'common', +'comply', +'conch', +'conchs', +'concur', +'condo', +'condor', +'confab', +'conga', +'conger', +'conic', +'conics', +'conman', +'conmen', +'conner', +'consul', +'contd', +'convex', +'convoy', +'cooked', +'cooker', +'cookie', +'cooled', +'coolie', +'cooper', +'cootie', +'copay', +'coper', +'copied', +'copies', +'coping', +'copper', +'copra', +'copse', +'copter', +'coral', +'corbel', +'corder', +'cords', +'corgi', +'coring', +'corked', +'corks', +'cornea', +'corner', +'cornet', +'corny', +'corona', +'corps', +'corpse', +'corpus', +'corral', +'corset', +'cortex', +'corves', +'cosign', +'cosine', +'cosmic', +'cosmos', +'costly', +'cotton', +'couch', +'cougar', +'cough', +'could', +'counts', +'county', +'couple', +'coupon', +'course', +'court', +'cousin', +'covary', +'coven', +'covers', +'covert', +'covet', +'covey', +'coward', +'cowboy', +'cowpox', +'cowrie', +'coyed', +'coyote', +'coypu', +'cozen', +'crabby', +'cradle', +'crafty', +'craggy', +'cramp', +'crane', +'cranky', +'cranny', +'crape', +'crass', +'crate', +'crater', +'cravat', +'crave', +'craver', +'crawl', +'crawly', +'craze', +'crazy', +'creak', +'creaky', +'creamy', +'crease', +'create', +'credo', +'creed', +'creeds', +'creek', +'creel', +'creepy', +'creme', +'creole', +'crepe', +'crept', +'cress', +'crest', +'cretin', +'crewel', +'crick', +'cries', +'crime', +'crimp', +'cringe', +'crises', +'crisis', +'crispy', +'criss', +'croak', +'croaky', +'crock', +'crocus', +'croft', +'crone', +'crony', +'crook', +'croon', +'crops', +'crouch', +'croup', +'croupy', +'crowds', +'crown', +'cruddy', +'crude', +'cruel', +'cruet', +'cruise', +'crumb', +'crumby', +'crummy', +'crump', +'crunch', +'cruse', +'crusty', +'crutch', +'crypt', +'cuber', +'cubic', +'cubism', +'cubit', +'cuboid', +'cuckoo', +'cuddly', +'cudgel', +'cueing', +'culler', +'culpa', +'cumber', +'cumin', +'cumuli', +'cupful', +'cupid', +'cupola', +'cupric', +'curacy', +'curare', +'curate', +'curdle', +'curfew', +'curia', +'curiae', +'curial', +'curie', +'curio', +'curium', +'curled', +'curlew', +'curls', +'curly', +'curry', +'curse', +'cursed', +'cursor', +'curtsy', +'curve', +'curved', +'curvy', +'cushy', +'cussed', +'cusser', +'cusses', +'cutesy', +'cutler', +'cutlet', +'cuttle', +'cutup', +'cyborg', +'cycad', +'cycled', +'cycler', +'cycles', +'cyder', +'cygnet', +'cynic', +'cypher', +'dabber', +'dabble', +'dacha', +'dactyl', +'daddy', +'daemon', +'daffy', +'dahlia', +'daily', +'dainty', +'daisy', +'daleth', +'dally', +'damask', +'dammit', +'damner', +'dampen', +'damsel', +'damson', +'dance', +'dandle', +'dandy', +'danger', +'dapper', +'dapple', +'daring', +'darken', +'darkly', +'dative', +'datum', +'davit', +'dawdle', +'daybed', +'deaden', +'deadly', +'deafen', +'deals', +'dealt', +'dearth', +'deary', +'debar', +'debark', +'debase', +'debate', +'debit', +'debris', +'debtor', +'debug', +'decade', +'decaf', +'decal', +'decay', +'deceit', +'decent', +'decile', +'decoy', +'decree', +'deduct', +'deeds', +'deejay', +'deepen', +'deface', +'defame', +'defeat', +'defend', +'defer', +'defile', +'define', +'defog', +'deform', +'defuse', +'degas', +'degree', +'deign', +'deist', +'deity', +'delay', +'delft', +'delta', +'deluge', +'deluxe', +'delve', +'demean', +'demise', +'demit', +'demob', +'demon', +'demote', +'demur', +'demure', +'dengue', +'denial', +'denim', +'dense', +'denser', +'dental', +'dented', +'dents', +'denude', +'depart', +'depict', +'deploy', +'depot', +'depth', +'deputy', +'derail', +'derby', +'derive', +'dermal', +'dermis', +'desalt', +'descry', +'desert', +'desist', +'despot', +'detain', +'deter', +'detest', +'detox', +'detune', +'devise', +'devote', +'devour', +'devout', +'dewar', +'dexes', +'dexter', +'dhoti', +'dials', +'diaper', +'diatom', +'dibble', +'dicer', +'dices', +'dicey', +'dicier', +'dicing', +'dickey', +'dicta', +'dictum', +'diddle', +'didst', +'diesel', +'differ', +'digit', +'digram', +'diker', +'diktat', +'dilate', +'dilute', +'dimity', +'dimmed', +'dimple', +'dimply', +'dimwit', +'dinar', +'dinghy', +'dingle', +'dingo', +'dingy', +'dinky', +'diode', +'dioxin', +'dipole', +'dippy', +'dirge', +'dirty', +'disant', +'disarm', +'disbar', +'disco', +'discus', +'dismal', +'dismay', +'dispel', +'distal', +'distil', +'disuse', +'ditch', +'dither', +'ditto', +'ditty', +'divan', +'dived', +'divers', +'divert', +'divest', +'divot', +'divvy', +'dobbin', +'docile', +'dodder', +'dodge', +'dodgem', +'dodgy', +'dogged', +'doggo', +'doggy', +'dogleg', +'dogma', +'doily', +'doing', +'doings', +'doled', +'doles', +'doling', +'dollar', +'dolly', +'dolmen', +'dolour', +'domain', +'domes', +'domino', +'donate', +'dongle', +'donkey', +'donor', +'doodle', +'dooper', +'dopant', +'dopey', +'dopier', +'dorky', +'dorsal', +'dosage', +'dotage', +'dotard', +'dotty', +'double', +'doubts', +'douche', +'dough', +'doughy', +'douse', +'douser', +'dowdy', +'dowel', +'downy', +'dowry', +'dowse', +'doyen', +'dozen', +'dozer', +'draggy', +'dragon', +'drain', +'drake', +'drama', +'drank', +'drawee', +'draws', +'dreamt', +'dreamy', +'drear', +'dreary', +'dredge', +'drench', +'dressy', +'drill', +'drippy', +'drive', +'drivel', +'driven', +'drives', +'drogue', +'droll', +'droner', +'drool', +'droop', +'droopy', +'drops', +'dropsy', +'dross', +'drove', +'drown', +'drowse', +'drowsy', +'drudge', +'druid', +'drunk', +'drupe', +'dryad', +'dryer', +'dryish', +'dryly', +'dubbed', +'dubbin', +'ducal', +'ducat', +'duchy', +'ducker', +'ducky', +'ducted', +'ducts', +'duenna', +'duffel', +'dugout', +'dulcet', +'dumdum', +'dummy', +'dumpy', +'dunce', +'dunker', +'dunno', +'dupion', +'duple', +'duplex', +'duress', +'during', +'durst', +'durum', +'dusky', +'dusty', +'duvet', +'duxes', +'dwarf', +'dwell', +'dwells', +'dwelt', +'dybbuk', +'dyeing', +'dying', +'dynamo', +'eagle', +'eaglet', +'earful', +'early', +'earned', +'earthy', +'earwax', +'earwig', +'eased', +'easel', +'easer', +'eases', +'easily', +'easing', +'eater', +'eatery', +'eating', +'ebony', +'echoes', +'echoic', +'eczema', +'edging', +'edible', +'edict', +'edited', +'editor', +'edits', +'eerie', +'eerily', +'efface', +'effete', +'effigy', +'efflux', +'eggcup', +'egger', +'eggnog', +'egoism', +'egress', +'egret', +'eider', +'eight', +'eighty', +'either', +'eject', +'ejecta', +'eland', +'elans', +'elapse', +'elate', +'elated', +'elater', +'elbow', +'elder', +'eldest', +'elects', +'elegy', +'eleven', +'elfin', +'elfish', +'elicit', +'elide', +'elite', +'elixir', +'elodea', +'elope', +'eloper', +'eluate', +'elute', +'elven', +'elver', +'elves', +'elvish', +'email', +'embalm', +'embank', +'embark', +'embed', +'ember', +'emblem', +'embody', +'emboss', +'embryo', +'emcee', +'emend', +'emerge', +'emery', +'emetic', +'emote', +'employ', +'emptor', +'empty', +'enable', +'enact', +'enacts', +'enamel', +'encamp', +'encase', +'encode', +'encore', +'encyst', +'ending', +'endive', +'endow', +'endue', +'enema', +'enemy', +'enfold', +'engage', +'engine', +'engram', +'engulf', +'enigma', +'enjoin', +'enlist', +'enmesh', +'enmity', +'ennui', +'enough', +'enrage', +'enrich', +'enrol', +'ensign', +'ensue', +'ensure', +'entail', +'enters', +'entire', +'entity', +'entomb', +'entrap', +'entry', +'envied', +'envoy', +'enzyme', +'eolith', +'epoch', +'epochs', +'epoxy', +'equal', +'equine', +'equip', +'equips', +'equity', +'equiv', +'erase', +'erbium', +'erect', +'ergot', +'ermine', +'erode', +'erotic', +'errand', +'errant', +'errata', +'erring', +'error', +'ersatz', +'eschew', +'escort', +'escrow', +'escudo', +'esprit', +'estate', +'esteem', +'etalon', +'ethane', +'ether', +'ethic', +'ethnic', +'ethos', +'ethyl', +'euchre', +'eunuch', +'eureka', +'evener', +'evenly', +'event', +'evict', +'evince', +'evoke', +'evolve', +'exact', +'exacts', +'excel', +'excise', +'exempt', +'exeunt', +'exhume', +'exile', +'exist', +'exodus', +'exotic', +'expect', +'expend', +'expert', +'expiry', +'expose', +'extant', +'extend', +'extent', +'extol', +'extort', +'extra', +'exude', +'exurb', +'eyeful', +'eyelet', +'eyelid', +'fable', +'fabled', +'fabler', +'fables', +'fabric', +'facer', +'facial', +'facile', +'facing', +'facto', +'factor', +'fading', +'faerie', +'faint', +'faire', +'fairly', +'fairy', +'fakir', +'falcon', +'fallen', +'fallow', +'falls', +'false', +'falter', +'family', +'famine', +'famish', +'famous', +'fanout', +'farad', +'farce', +'farer', +'farina', +'farrow', +'fascia', +'fasten', +'fatale', +'fatso', +'fatten', +'fatty', +'fatwa', +'fault', +'faulty', +'fauna', +'fealty', +'feast', +'fedora', +'feeble', +'feeds', +'feign', +'feint', +'feisty', +'feline', +'fellah', +'fellow', +'felon', +'felony', +'female', +'femme', +'femur', +'fence', +'fenced', +'fencer', +'fennel', +'feral', +'ferny', +'ferret', +'ferro', +'ferule', +'fervid', +'fesses', +'festal', +'fester', +'fetter', +'fettle', +'feudal', +'fiasco', +'fibre', +'fibrin', +'fibula', +'fiche', +'fichu', +'fickle', +'ficus', +'fiddle', +'fidget', +'fiend', +'fierce', +'fiery', +'fiesta', +'fifth', +'fifty', +'fight', +'filch', +'filial', +'filing', +'fills', +'filly', +'filmy', +'filthy', +'finale', +'finch', +'finely', +'finer', +'finery', +'finest', +'finger', +'finial', +'fining', +'finis', +'finish', +'finite', +'finny', +'fiord', +'fires', +'firing', +'firkin', +'firmer', +'firmly', +'first', +'firth', +'fiscal', +'fished', +'fisher', +'fishy', +'fitful', +'fitted', +'fitter', +'fiver', +'fixate', +'fixed', +'fixes', +'fixing', +'fixity', +'fizzer', +'fizzle', +'fizzy', +'fjord', +'flabby', +'flack', +'flagon', +'flail', +'flair', +'flake', +'flaker', +'flaky', +'flamed', +'flamen', +'flamer', +'flames', +'flange', +'flank', +'flanks', +'flaps', +'flashy', +'flask', +'flatus', +'flaxen', +'fleck', +'fledge', +'fleece', +'fleecy', +'fleer', +'fleet', +'fleshy', +'flews', +'flexes', +'flick', +'flier', +'fliest', +'flimsy', +'flinch', +'fling', +'flinty', +'flirt', +'float', +'flock', +'flood', +'floor', +'floozy', +'floppy', +'floral', +'floret', +'florid', +'florin', +'floss', +'flossy', +'flour', +'floury', +'flout', +'flowed', +'flown', +'fluent', +'fluffy', +'fluke', +'fluky', +'flume', +'flung', +'flunk', +'flunky', +'flurry', +'flush', +'flute', +'fluxes', +'flyby', +'flybys', +'flyer', +'flying', +'foamer', +'foamy', +'fogey', +'foggy', +'foible', +'foist', +'folder', +'foliar', +'folio', +'folks', +'folksy', +'folly', +'foment', +'fondue', +'foodie', +'forage', +'foray', +'forbid', +'force', +'forced', +'forcer', +'forego', +'forged', +'forges', +'forget', +'forgo', +'forgot', +'forker', +'format', +'formed', +'former', +'formic', +'forms', +'forte', +'forth', +'forty', +'forum', +'fought', +'fouls', +'found', +'founds', +'fount', +'fourth', +'fovea', +'foveae', +'foveal', +'fowler', +'foxed', +'foxes', +'foxing', +'foyer', +'fracas', +'frail', +'frame', +'framed', +'franc', +'frank', +'fraud', +'freak', +'freaky', +'freeze', +'freon', +'fresco', +'friar', +'friary', +'fridge', +'fried', +'fries', +'frieze', +'frigid', +'frill', +'frilly', +'fringe', +'frisky', +'frizz', +'frizzy', +'frock', +'froid', +'frolic', +'frond', +'front', +'frosts', +'frosty', +'froth', +'frothy', +'frowzy', +'froze', +'frozen', +'frugal', +'fruit', +'fruity', +'frump', +'frumpy', +'fryer', +'fuddle', +'fudge', +'fugal', +'fugue', +'fuhrer', +'fulfil', +'fuller', +'funds', +'fungal', +'fungi', +'fungus', +'funky', +'funnel', +'funny', +'furore', +'furrow', +'furry', +'furze', +'fused', +'fusee', +'fuses', +'fusing', +'fusion', +'fusser', +'fussy', +'fusty', +'futile', +'futon', +'future', +'fuzzy', +'gabble', +'gabby', +'gable', +'gabler', +'gadfly', +'gaffe', +'gaggle', +'gaiety', +'gaily', +'gained', +'gains', +'galaxy', +'galen', +'galena', +'galley', +'gallon', +'gallop', +'galoot', +'galore', +'galosh', +'gambit', +'gamble', +'gambol', +'gamest', +'gamete', +'gamin', +'gamine', +'gaming', +'gamma', +'gamut', +'gander', +'ganger', +'gannet', +'gantry', +'gaper', +'garage', +'garble', +'garde', +'garden', +'gargle', +'garish', +'garlic', +'garner', +'garnet', +'garret', +'gasbag', +'gasket', +'gasses', +'gassy', +'gateau', +'gauche', +'gaucho', +'gaudy', +'gauger', +'gaunt', +'gauss', +'gauze', +'gauzy', +'gavel', +'gawker', +'gawky', +'gazebo', +'gecko', +'geese', +'geezer', +'geisha', +'gelcap', +'gelid', +'genial', +'genii', +'genius', +'genome', +'genre', +'gentry', +'genus', +'geode', +'gerbil', +'gerund', +'getup', +'gewgaw', +'ghetto', +'ghost', +'ghoul', +'giant', +'gibber', +'gibbon', +'giber', +'giddy', +'gifted', +'giggly', +'giller', +'gillie', +'gimlet', +'gimpy', +'ginkgo', +'gipsy', +'girdle', +'girlie', +'girth', +'given', +'giveth', +'giving', +'glade', +'gladly', +'gland', +'glans', +'glassy', +'glaze', +'glazed', +'gleam', +'glean', +'glide', +'glint', +'glitch', +'glitz', +'glitzy', +'global', +'globe', +'gloomy', +'glory', +'glossy', +'glower', +'glued', +'gluier', +'gluon', +'glutei', +'gluten', +'glycol', +'glyph', +'gnarl', +'gnash', +'gnawer', +'gneiss', +'gnome', +'gnomic', +'goalie', +'goatee', +'gobbet', +'gobble', +'goblet', +'goblin', +'godly', +'godson', +'goggle', +'going', +'goitre', +'golden', +'golly', +'gonad', +'gooder', +'goodly', +'goody', +'goofy', +'googly', +'gooier', +'goose', +'gopher', +'gorge', +'gorger', +'gorgon', +'goring', +'gorse', +'gospel', +'gotta', +'gotten', +'gouge', +'gourd', +'gouty', +'graded', +'grades', +'graft', +'grail', +'grain', +'grainy', +'gramme', +'grand', +'grange', +'granny', +'grant', +'grape', +'graph', +'grass', +'grassy', +'grates', +'gratis', +'grave', +'gravel', +'graven', +'gravid', +'gravy', +'grazer', +'grease', +'greasy', +'great', +'grebe', +'greedy', +'green', +'greet', +'greyer', +'grief', +'grill', +'grille', +'grilse', +'grime', +'grimy', +'grinds', +'gringo', +'gripe', +'grisly', +'grist', +'gritty', +'groan', +'groat', +'grocer', +'groggy', +'groom', +'groove', +'groovy', +'gross', +'grotto', +'ground', +'group', +'groups', +'grouse', +'grout', +'grove', +'grovel', +'grows', +'grubby', +'gruff', +'grumpy', +'grunge', +'grungy', +'grunt', +'guano', +'guard', +'guava', +'guest', +'guffaw', +'guide', +'guider', +'guides', +'guild', +'guile', +'guilty', +'guinea', +'guise', +'gulden', +'gullet', +'gulley', +'gully', +'gummy', +'gunky', +'gunman', +'gunmen', +'gunny', +'guppy', +'gurgle', +'gushy', +'gusset', +'gusto', +'gusty', +'gutsy', +'gutta', +'gutter', +'guzzle', +'gypped', +'gypsum', +'gypsy', +'habeas', +'habits', +'hackle', +'hades', +'hadron', +'hadst', +'haggis', +'haggle', +'haiku', +'hairdo', +'hairy', +'hajjes', +'hajji', +'halal', +'haled', +'haler', +'hales', +'halide', +'haling', +'halite', +'hallo', +'hallow', +'haloes', +'halon', +'halter', +'halve', +'halves', +'hamlet', +'hammer', +'hammy', +'hamper', +'handed', +'handle', +'hands', +'hangar', +'hangs', +'hangup', +'hankie', +'hanky', +'hansom', +'happen', +'happy', +'harass', +'harden', +'hardy', +'harem', +'harken', +'harmed', +'harmer', +'harpy', +'harrow', +'harry', +'harsh', +'hasher', +'hassle', +'haste', +'hasten', +'hasty', +'hatred', +'hauled', +'hauler', +'hauls', +'haunch', +'haven', +'haver', +'havoc', +'hayer', +'haymow', +'hazard', +'hazel', +'hazing', +'hdqrs', +'heads', +'heady', +'healed', +'health', +'heard', +'hearer', +'hears', +'hearse', +'hearth', +'hearty', +'heave', +'heaven', +'heaves', +'heavy', +'heckle', +'hectic', +'hector', +'heeded', +'heehaw', +'hefty', +'hegira', +'heifer', +'heigh', +'height', +'helium', +'helix', +'hello', +'helmet', +'helot', +'helter', +'helve', +'hempen', +'hence', +'henge', +'henna', +'henry', +'herbal', +'hereat', +'hereby', +'herein', +'hereof', +'heresy', +'hereto', +'hermit', +'heroes', +'heroic', +'heroin', +'heron', +'herpes', +'hertz', +'hexane', +'hexer', +'heyday', +'hiatus', +'hicks', +'hidden', +'hidey', +'hiding', +'hieing', +'hight', +'hijack', +'hilly', +'hinder', +'hinge', +'hinged', +'hinger', +'hinges', +'hippie', +'hippo', +'hippy', +'hired', +'hires', +'hiring', +'hisser', +'hitch', +'hither', +'hoard', +'hoarse', +'hoary', +'hobbit', +'hobble', +'hobby', +'hobnob', +'hockey', +'hocus', +'hodge', +'hogan', +'hogger', +'hoist', +'hoity', +'hokey', +'holder', +'holds', +'holey', +'hollow', +'holly', +'homage', +'homely', +'homey', +'homier', +'homily', +'homing', +'honer', +'honest', +'honey', +'hooded', +'hoodoo', +'hooey', +'hoofer', +'hookah', +'hooker', +'hookup', +'hooper', +'hoopla', +'hooray', +'hoover', +'hooves', +'hoper', +'horde', +'horned', +'horner', +'hornet', +'horrid', +'horror', +'horsey', +'hosier', +'hotbed', +'hotbox', +'hotel', +'hotpot', +'hotrod', +'hough', +'hound', +'houri', +'hourly', +'housed', +'houser', +'hovel', +'howdah', +'hoyden', +'hubbub', +'hubby', +'hubris', +'huddle', +'huffy', +'hullo', +'humane', +'humble', +'humbug', +'humeri', +'humid', +'hummus', +'humph', +'humus', +'hunch', +'hunger', +'hungry', +'hunky', +'hurdle', +'hurrah', +'hurray', +'hurter', +'hurtle', +'husky', +'hussar', +'hussy', +'hustle', +'hutch', +'hyaena', +'hydra', +'hydro', +'hyena', +'hymnal', +'hyper', +'hyrax', +'hyssop', +'iambi', +'iambic', +'iambus', +'ibidem', +'icebox', +'icecap', +'icicle', +'icing', +'ictus', +'ideate', +'idiocy', +'idiom', +'igloo', +'ignite', +'ignore', +'iguana', +'ileum', +'iliac', +'ilium', +'illume', +'imago', +'imbibe', +'imbue', +'immure', +'impact', +'impair', +'impala', +'impale', +'impart', +'imped', +'impede', +'impend', +'imping', +'impish', +'imply', +'import', +'impose', +'impugn', +'impute', +'inane', +'inborn', +'inbred', +'incest', +'incite', +'income', +'incurs', +'indeed', +'indict', +'indigo', +'indite', +'indium', +'indoor', +'induct', +'inept', +'inert', +'infamy', +'infant', +'infect', +'infill', +'infirm', +'infix', +'inflow', +'influx', +'inform', +'infra', +'ingot', +'inhere', +'inject', +'injure', +'inlaid', +'inland', +'inlay', +'inlet', +'inlier', +'inmate', +'inmost', +'innate', +'inner', +'input', +'inroad', +'inrush', +'insane', +'insert', +'inset', +'inside', +'instal', +'insure', +'intact', +'intake', +'intend', +'intent', +'inter', +'intern', +'inters', +'intone', +'intra', +'intro', +'intuit', +'inure', +'invent', +'invest', +'inward', +'iodate', +'iodide', +'iodine', +'iodise', +'iodize', +'ionic', +'ionise', +'ionize', +'ipecac', +'irate', +'irenic', +'ironer', +'irony', +'irrupt', +'island', +'islet', +'isobar', +'isomer', +'ispell', +'issued', +'issues', +'italic', +'itchy', +'itself', +'ivory', +'jabber', +'jabot', +'jackal', +'jaded', +'jagged', +'jaggy', +'jaguar', +'jalopy', +'jangle', +'jarful', +'jargon', +'jasper', +'jaunty', +'jazzy', +'jeans', +'jeerer', +'jejuna', +'jejune', +'jelly', +'jemmy', +'jennet', +'jenny', +'jerker', +'jerkin', +'jerky', +'jerry', +'jersey', +'jetsam', +'jetty', +'jewel', +'jiffy', +'jigger', +'jiggle', +'jiggly', +'jigsaw', +'jihad', +'jilter', +'jingle', +'jingly', +'jingo', +'jinked', +'jitsu', +'jitter', +'jobber', +'jockey', +'jocose', +'jocund', +'joggle', +'johnny', +'joined', +'joiner', +'joins', +'joint', +'joints', +'joist', +'jokey', +'jolly', +'jongg', +'jostle', +'joule', +'jounce', +'joust', +'jovial', +'jowly', +'joyed', +'joyful', +'joyous', +'judder', +'judger', +'jugful', +'juice', +'juicy', +'jujube', +'jumble', +'jumbo', +'jumpy', +'junco', +'jungle', +'junior', +'junket', +'junkie', +'junky', +'junta', +'juries', +'jurist', +'juror', +'juster', +'justly', +'kaboom', +'kabuki', +'kaftan', +'kaiser', +'kaolin', +'kapok', +'kappa', +'kaput', +'karate', +'karma', +'karmic', +'kayak', +'kazoo', +'kebab', +'keeler', +'keener', +'kelvin', +'kennel', +'kerned', +'kernel', +'ketch', +'ketone', +'kettle', +'keypad', +'khaki', +'kibble', +'kibosh', +'kicky', +'kiddie', +'kiddo', +'kidnap', +'kidney', +'killer', +'kilohm', +'kilter', +'kimono', +'kinda', +'kindle', +'kindly', +'kingly', +'kinked', +'kinky', +'kiosk', +'kipper', +'kirsch', +'kismet', +'kitbag', +'kitsch', +'kitty', +'klaxon', +'kludge', +'knack', +'knead', +'kneel', +'knell', +'knelt', +'knick', +'knife', +'knight', +'knish', +'knives', +'knobby', +'knock', +'knoll', +'knotty', +'knower', +'known', +'knurl', +'koala', +'kooky', +'kopeck', +'kopeks', +'kosher', +'kowtow', +'kraal', +'kraft', +'krill', +'krona', +'krone', +'kroner', +'kronor', +'kronur', +'kudos', +'kudzu', +'kulaks', +'label', +'labia', +'labial', +'labile', +'labium', +'labour', +'laced', +'lacer', +'laces', +'lacier', +'lacing', +'lackey', +'lactic', +'lacuna', +'ladder', +'laddie', +'laden', +'lading', +'ladle', +'lagoon', +'laird', +'laity', +'lambda', +'lamber', +'lamed', +'lament', +'lamina', +'lamper', +'lance', +'lancet', +'landau', +'lander', +'lanky', +'lapdog', +'lapel', +'lapin', +'lappet', +'lapse', +'lapser', +'laptop', +'larch', +'lards', +'lardy', +'large', +'largo', +'lariat', +'larker', +'larva', +'larvae', +'larval', +'larynx', +'lashed', +'lasher', +'lassie', +'lasso', +'lasted', +'lasts', +'latch', +'latent', +'later', +'latest', +'latex', +'lathe', +'lather', +'latish', +'latte', +'latter', +'lauder', +'lauds', +'launch', +'laurel', +'lavage', +'lavish', +'lawful', +'lawyer', +'laxes', +'laxity', +'layer', +'laying', +'layman', +'laymen', +'layout', +'layup', +'lazuli', +'leach', +'leaded', +'leaden', +'leader', +'leafy', +'league', +'leaker', +'leaky', +'leaner', +'leant', +'leaper', +'leapt', +'learn', +'learns', +'learnt', +'lease', +'leash', +'least', +'leave', +'leaves', +'lecher', +'ledge', +'leech', +'leery', +'leeway', +'legacy', +'legal', +'legato', +'legend', +'leggy', +'legit', +'legume', +'lemma', +'lemme', +'lemon', +'lemony', +'lemur', +'length', +'lenser', +'lentil', +'lento', +'leper', +'lepta', +'lepton', +'lesion', +'lessee', +'lesser', +'lessor', +'lethal', +'letter', +'letup', +'level', +'levity', +'lewis', +'lexeme', +'liable', +'liaise', +'libel', +'libero', +'lichee', +'lichen', +'licit', +'licker', +'lieder', +'liege', +'lieut', +'lieux', +'ligand', +'light', +'lignum', +'likely', +'liken', +'liker', +'likest', +'liking', +'lilac', +'lilly', +'limbo', +'limper', +'limpet', +'limpid', +'linage', +'linden', +'lineal', +'linear', +'lined', +'linen', +'lines', +'linger', +'lingo', +'lining', +'linked', +'links', +'linnet', +'lintel', +'linty', +'lipase', +'lipid', +'lippy', +'liquid', +'liquor', +'lisle', +'lissom', +'listed', +'listen', +'litany', +'lithe', +'litmus', +'litre', +'litter', +'little', +'lived', +'lively', +'liven', +'lives', +'livest', +'livid', +'living', +'lizard', +'llama', +'loads', +'loamy', +'loath', +'loathe', +'loaves', +'lobar', +'lobule', +'local', +'locale', +'lochs', +'locked', +'locket', +'locks', +'locus', +'locust', +'lodge', +'lodged', +'lodges', +'lofter', +'lofty', +'loggia', +'logia', +'logic', +'login', +'logjam', +'logout', +'loiter', +'loller', +'lolly', +'lonely', +'loofah', +'looked', +'looks', +'lookup', +'loony', +'looper', +'loopy', +'loose', +'loosed', +'looses', +'loper', +'lordly', +'loris', +'lorry', +'lossy', +'lotion', +'lotto', +'lotus', +'louden', +'lounge', +'loupe', +'louse', +'lousy', +'louvre', +'loved', +'lovely', +'loving', +'lowish', +'lowly', +'loyal', +'lubber', +'lucent', +'lucid', +'lucky', +'lucre', +'luger', +'lumbar', +'lumber', +'lumen', +'lumpen', +'lumper', +'lumpy', +'lunacy', +'lunar', +'lunate', +'lunch', +'lunge', +'lunger', +'lupin', +'lupine', +'lupus', +'lurch', +'lurer', +'lurex', +'lurid', +'lustre', +'lusty', +'luting', +'luxury', +'lyceum', +'lychee', +'lying', +'lymph', +'lynch', +'lyric', +'lyrist', +'lysine', +'macaw', +'macer', +'macho', +'macro', +'macron', +'madam', +'madame', +'madcap', +'madden', +'madman', +'madmen', +'madras', +'maggot', +'magic', +'magma', +'magnum', +'magpie', +'mahout', +'maiden', +'mainly', +'mains', +'maize', +'major', +'makes', +'making', +'malady', +'malice', +'malign', +'mallet', +'mallow', +'malted', +'malty', +'mamba', +'mambo', +'mammal', +'mammy', +'manage', +'mangle', +'mango', +'mangy', +'mania', +'maniac', +'manic', +'manioc', +'manly', +'manna', +'manned', +'manner', +'manor', +'manse', +'manta', +'mantel', +'mantis', +'mantle', +'mantra', +'manual', +'manure', +'maple', +'mapped', +'maraca', +'maraud', +'marble', +'march', +'margin', +'maria', +'marine', +'marked', +'market', +'markka', +'marks', +'marlin', +'marmot', +'maroon', +'marque', +'marred', +'marrow', +'marry', +'marshy', +'marten', +'martin', +'martyr', +'marvel', +'mascot', +'masked', +'masks', +'mason', +'masque', +'massif', +'master', +'maths', +'mating', +'matins', +'matrix', +'matron', +'matte', +'matter', +'mature', +'matzo', +'mauve', +'maxim', +'maxima', +'maxing', +'maybe', +'mayday', +'mayfly', +'mayhap', +'mayhem', +'mayor', +'mayst', +'mazer', +'meadow', +'meagre', +'mealy', +'meaner', +'meanie', +'meanly', +'meant', +'measly', +'meaty', +'medal', +'meddle', +'media', +'medial', +'median', +'medico', +'medium', +'medley', +'meeter', +'megohm', +'mellow', +'melon', +'melted', +'melter', +'melts', +'member', +'memoir', +'memory', +'mender', +'menial', +'meninx', +'mental', +'mentor', +'mercer', +'merge', +'merino', +'merlin', +'merry', +'mescal', +'meshed', +'meson', +'messy', +'metal', +'meter', +'method', +'methyl', +'metier', +'metro', +'mettle', +'mezzo', +'miasma', +'mickey', +'midday', +'midden', +'middle', +'middy', +'midge', +'midget', +'midrib', +'midst', +'midway', +'mighty', +'mikado', +'milady', +'milch', +'milden', +'mildew', +'miler', +'milieu', +'milky', +'millet', +'mimer', +'mimosa', +'minded', +'minder', +'mined', +'mines', +'mingle', +'minim', +'minima', +'mining', +'minion', +'minke', +'minnow', +'minor', +'minty', +'minuet', +'minus', +'minute', +'mirage', +'misery', +'misfit', +'mishap', +'mislay', +'misled', +'missal', +'misses', +'missus', +'misty', +'misuse', +'mitre', +'mitten', +'mixed', +'mixes', +'mixing', +'mizzen', +'mobber', +'mocha', +'mocker', +'modal', +'model', +'modem', +'modern', +'modest', +'modish', +'moduli', +'modulo', +'modus', +'moggie', +'mogul', +'mohair', +'moiety', +'moire', +'moist', +'molal', +'molar', +'molly', +'molten', +'moment', +'momma', +'monad', +'money', +'monger', +'monies', +'monism', +'monkey', +'monody', +'month', +'mooch', +'moody', +'moose', +'mooter', +'moped', +'mopish', +'moppet', +'moral', +'morass', +'moray', +'morbid', +'morel', +'morgue', +'morose', +'morph', +'morris', +'morrow', +'morsel', +'mortal', +'mortar', +'mortem', +'mosaic', +'mosey', +'mosque', +'mossy', +'motel', +'motet', +'mother', +'motif', +'motile', +'motion', +'motive', +'motley', +'mottle', +'motto', +'mould', +'moulds', +'mouldy', +'moult', +'mound', +'mounts', +'mouse', +'mousey', +'mousse', +'mousy', +'mouthy', +'moved', +'mover', +'moves', +'moving', +'mowing', +'mucker', +'mucky', +'mucosa', +'mucous', +'mucus', +'muddle', +'muddy', +'muesli', +'muffin', +'muffle', +'mufti', +'muggy', +'mulch', +'mulct', +'mulish', +'mullah', +'mullet', +'multi', +'mumble', +'mumbo', +'mummer', +'mummy', +'mumps', +'munch', +'munge', +'mural', +'murder', +'murky', +'murmur', +'muscat', +'muscle', +'muser', +'museum', +'mushy', +'music', +'muskeg', +'musky', +'muslin', +'mussel', +'muster', +'musty', +'mutant', +'mutate', +'muted', +'mutely', +'muter', +'mutest', +'mutiny', +'mutter', +'mutton', +'mutual', +'muumuu', +'muzzle', +'mynah', +'myopia', +'myopic', +'myriad', +'myrrh', +'myself', +'mystic', +'nabob', +'nacho', +'nacre', +'nadir', +'naffer', +'naiad', +'naifs', +'nailer', +'naive', +'naked', +'namby', +'named', +'namely', +'namer', +'nanny', +'napalm', +'napkin', +'nappy', +'narky', +'narrow', +'nasty', +'natal', +'natch', +'nation', +'native', +'natter', +'natty', +'nature', +'nausea', +'naval', +'navel', +'navvy', +'nearby', +'neaten', +'nebula', +'necker', +'nectar', +'needed', +'needer', +'needy', +'negate', +'neigh', +'nelson', +'nephew', +'nerdy', +'nerve', +'nervy', +'nester', +'nestle', +'nether', +'netter', +'nettle', +'neural', +'neuron', +'never', +'newbie', +'newel', +'newish', +'newsy', +'newton', +'nexus', +'niacin', +'nibble', +'nicety', +'niche', +'nickel', +'niece', +'nifty', +'night', +'nights', +'nimbi', +'nimble', +'nimbus', +'ninety', +'ninja', +'ninny', +'nippy', +'nitwit', +'nobody', +'nodal', +'noddle', +'noddy', +'nodule', +'noggin', +'nohow', +'noire', +'noisy', +'nomad', +'nonage', +'nonce', +'nones', +'noodle', +'noose', +'normal', +'north', +'nosey', +'nosing', +'notary', +'notch', +'notify', +'notion', +'nougat', +'nought', +'nounal', +'novae', +'novena', +'novice', +'noway', +'nozzle', +'nuance', +'nubby', +'nubile', +'nuclei', +'nuder', +'nudes', +'nudge', +'nudger', +'nugget', +'number', +'nuncio', +'nurse', +'nurser', +'nutate', +'nutmeg', +'nutria', +'nutty', +'nuzzle', +'nylon', +'nymph', +'oafish', +'oaken', +'oakum', +'oases', +'oasis', +'oaten', +'obese', +'obeyer', +'oblate', +'oblige', +'oblong', +'oboist', +'obtuse', +'occult', +'occur', +'ocean', +'ocelot', +'ochre', +'octal', +'octane', +'octant', +'octave', +'octavo', +'octet', +'octile', +'ocular', +'oddity', +'odious', +'odium', +'odour', +'oedema', +'oeuvre', +'offal', +'offer', +'offing', +'offish', +'offset', +'often', +'ogive', +'ogress', +'ogrish', +'okapi', +'olden', +'oldie', +'oldish', +'olefin', +'olive', +'omega', +'omelet', +'oncer', +'onion', +'onrush', +'onset', +'onside', +'onward', +'oodles', +'opaque', +'opened', +'opens', +'opiate', +'opine', +'opioid', +'opium', +'oppose', +'optic', +'optics', +'optima', +'option', +'oracle', +'orang', +'orate', +'orator', +'orchid', +'ordain', +'ordeal', +'ordure', +'oriel', +'origin', +'oriole', +'orison', +'ormolu', +'ornate', +'orphan', +'orris', +'osier', +'osmium', +'osprey', +'ossify', +'ostler', +'other', +'otiose', +'otter', +'ought', +'ounce', +'outang', +'outcry', +'outdo', +'outer', +'outfit', +'outfox', +'outgo', +'outing', +'outlay', +'output', +'overdo', +'overly', +'overt', +'owlet', +'owlish', +'owned', +'owner', +'oxalic', +'oxbow', +'oxide', +'oxtail', +'oyster', +'ozone', +'pacer', +'paces', +'pacey', +'packed', +'packs', +'padded', +'paddle', +'paddy', +'padre', +'paean', +'paella', +'paeony', +'pagan', +'paged', +'pagoda', +'paint', +'paired', +'palace', +'palate', +'palely', +'paler', +'palest', +'paling', +'palish', +'pallid', +'pallor', +'palmer', +'palmy', +'palsy', +'paltry', +'pamby', +'pampas', +'panama', +'panda', +'pander', +'panel', +'panic', +'panky', +'pansy', +'pantry', +'panzer', +'papacy', +'papal', +'papaw', +'papaya', +'papers', +'papery', +'papist', +'papyri', +'parade', +'parcel', +'parch', +'pardon', +'parer', +'parers', +'pares', +'pariah', +'paring', +'parish', +'parity', +'parka', +'parky', +'parley', +'parody', +'parole', +'parry', +'parse', +'parsec', +'parsed', +'parson', +'parter', +'partly', +'parts', +'party', +'pascal', +'pasha', +'passim', +'pasta', +'paste', +'pastel', +'paster', +'pastis', +'pastor', +'pastry', +'pasts', +'pasty', +'patch', +'patchy', +'paten', +'patent', +'pater', +'pathos', +'patina', +'patio', +'patois', +'patrol', +'patten', +'patter', +'patty', +'paunch', +'pause', +'paved', +'paver', +'paves', +'paving', +'pawner', +'paxes', +'payee', +'payer', +'payout', +'peace', +'peach', +'peachy', +'peahen', +'peaky', +'pealed', +'peals', +'peanut', +'pearl', +'pearly', +'peats', +'peaty', +'pebble', +'pebbly', +'pecan', +'pectic', +'pectin', +'pedal', +'peddle', +'pedlar', +'peeled', +'peeler', +'peeve', +'peewee', +'pekoe', +'pelmet', +'pelter', +'pelvic', +'pelvis', +'penal', +'pence', +'pencil', +'penman', +'penmen', +'pennon', +'penury', +'peony', +'people', +'pepper', +'peppy', +'pepsin', +'peptic', +'perch', +'percha', +'peril', +'perky', +'permit', +'peruke', +'peruse', +'peseta', +'pesky', +'pestle', +'pesto', +'petal', +'petard', +'petite', +'petrel', +'petrol', +'petty', +'pewee', +'pewit', +'pewter', +'peyote', +'phage', +'phalli', +'phase', +'phenol', +'phenyl', +'phial', +'phlegm', +'phloem', +'phlox', +'phobia', +'phobic', +'phoebe', +'phoney', +'phonic', +'phonon', +'phony', +'phooey', +'photo', +'photon', +'phrase', +'phyla', +'phylum', +'physic', +'piano', +'piazza', +'picked', +'picket', +'pickle', +'picky', +'picnic', +'picot', +'piddle', +'pidgin', +'piece', +'piecer', +'pieing', +'piety', +'piffle', +'piggy', +'piglet', +'pigsty', +'pilaf', +'pilers', +'pileup', +'pilfer', +'piling', +'pillar', +'pillow', +'pimple', +'pimply', +'pince', +'pincer', +'pinch', +'pineal', +'pinged', +'pinger', +'pinion', +'pinkie', +'pinky', +'pinna', +'pinnae', +'pinned', +'pious', +'piping', +'pipit', +'pippin', +'pique', +'piracy', +'pisser', +'piste', +'pistil', +'pistol', +'piston', +'pitch', +'pithy', +'pitman', +'piton', +'pixel', +'pixie', +'pixmap', +'pizazz', +'pizza', +'placed', +'placer', +'placid', +'plague', +'plaice', +'plaid', +'plains', +'plaint', +'plait', +'planar', +'plane', +'planet', +'plank', +'plant', +'plaque', +'plash', +'plasm', +'plasma', +'plate', +'platen', +'played', +'plays', +'plaza', +'please', +'pleat', +'pledge', +'plenty', +'plenum', +'pleura', +'plexus', +'pliant', +'pliers', +'plight', +'plinth', +'plover', +'plucky', +'plugs', +'plumb', +'plume', +'plummy', +'plump', +'plunge', +'plunk', +'plural', +'plush', +'plushy', +'poach', +'pocket', +'pocus', +'podgy', +'podium', +'poesy', +'poetic', +'poetry', +'pogrom', +'point', +'pointy', +'poise', +'poison', +'polar', +'poler', +'policy', +'polio', +'polish', +'polite', +'polka', +'pollen', +'poller', +'pomade', +'pommel', +'pompom', +'ponce', +'poncho', +'ponder', +'pongee', +'pooch', +'poodle', +'popgun', +'poplar', +'poplin', +'poppet', +'poppy', +'porch', +'porky', +'porous', +'portal', +'porter', +'portly', +'poser', +'poseur', +'posing', +'posses', +'possum', +'postal', +'posted', +'poster', +'posts', +'potage', +'potash', +'potato', +'potent', +'potful', +'potion', +'potty', +'pouch', +'pouffe', +'pounce', +'pound', +'pourri', +'powder', +'power', +'powwow', +'praise', +'prank', +'prawn', +'praxes', +'praxis', +'prayer', +'preach', +'precut', +'preen', +'prefab', +'prefix', +'premed', +'premix', +'press', +'presto', +'pretty', +'price', +'priced', +'pricer', +'pricey', +'priest', +'primal', +'prime', +'primp', +'prince', +'print', +'prints', +'prions', +'prior', +'priori', +'priory', +'prise', +'priser', +'prism', +'prissy', +'privet', +'privy', +'prize', +'prober', +'prolix', +'promo', +'prompt', +'prone', +'prong', +'pronto', +'proof', +'proper', +'prose', +'proser', +'prosy', +'protea', +'proton', +'proud', +'prove', +'proved', +'proven', +'proves', +'prowl', +'proxy', +'prune', +'pseudo', +'pshaw', +'psych', +'psyche', +'psycho', +'psychs', +'puddle', +'pudgy', +'pueblo', +'puffer', +'puffin', +'puffy', +'pukka', +'pullet', +'pulley', +'pulper', +'pulpit', +'pulpy', +'pulsar', +'pulse', +'pulsed', +'pulser', +'pulses', +'pumice', +'pummel', +'pumper', +'punchy', +'pundit', +'punky', +'punnet', +'pupae', +'pupal', +'pupate', +'pupil', +'puppy', +'purdah', +'purge', +'purine', +'purism', +'purist', +'purity', +'purple', +'purse', +'pursue', +'purvey', +'pushy', +'putrid', +'putsch', +'puttee', +'putter', +'putty', +'pygmy', +'pyjama', +'pyknic', +'pylon', +'pylori', +'pyrite', +'python', +'pyxis', +'quack', +'quaff', +'quail', +'quaint', +'quake', +'quaky', +'qualm', +'quango', +'quanta', +'quark', +'quarry', +'quart', +'quarto', +'quartz', +'quasar', +'quash', +'quasi', +'quaver', +'queasy', +'queen', +'queer', +'quell', +'quench', +'quern', +'query', +'quest', +'quests', +'queue', +'queuer', +'quiche', +'quick', +'quiet', +'quiff', +'quill', +'quilt', +'quince', +'quinsy', +'quint', +'quire', +'quirk', +'quirky', +'quirt', +'quite', +'quiver', +'quizzy', +'quoin', +'quoit', +'quorum', +'quoted', +'quoter', +'quoth', +'qwerty', +'rabbi', +'rabble', +'rabid', +'rabies', +'raceme', +'racism', +'racket', +'radar', +'radial', +'radian', +'radii', +'radish', +'radium', +'radius', +'radix', +'radon', +'raffia', +'raffle', +'ragbag', +'ragged', +'raglan', +'ragout', +'ragtag', +'railer', +'rainy', +'raise', +'raisin', +'raison', +'rajah', +'raker', +'rakish', +'rally', +'ramie', +'ramjet', +'ranch', +'rancid', +'ranee', +'range', +'rangy', +'ranked', +'ranker', +'rankle', +'rapid', +'rapier', +'rapine', +'rappel', +'rarefy', +'rarity', +'rascal', +'rasper', +'raspy', +'raster', +'rather', +'rating', +'ratio', +'ration', +'rattan', +'rattle', +'rattly', +'ratty', +'ravage', +'ravel', +'raven', +'ravine', +'rayon', +'razor', +'reach', +'react', +'reacts', +'reader', +'reads', +'ready', +'realm', +'rebate', +'rebel', +'rebook', +'rebut', +'recall', +'recap', +'recent', +'recipe', +'recite', +'reckon', +'recoil', +'recopy', +'record', +'recoup', +'rector', +'recur', +'recurs', +'redact', +'redbud', +'redcap', +'redden', +'redeem', +'redial', +'redraw', +'reedy', +'reeve', +'refile', +'refill', +'refine', +'refit', +'reflex', +'refuge', +'refund', +'refuse', +'regain', +'regale', +'regard', +'reggae', +'regime', +'regrow', +'rehab', +'rehang', +'rehear', +'reheat', +'rehire', +'reign', +'reject', +'rejoin', +'reknit', +'relax', +'relay', +'relic', +'relict', +'relief', +'reline', +'relish', +'relit', +'reload', +'relock', +'remain', +'remake', +'remand', +'remap', +'remark', +'remelt', +'remind', +'remiss', +'remit', +'remix', +'remote', +'remove', +'render', +'renege', +'rennet', +'rennin', +'renown', +'rental', +'reopen', +'repack', +'repair', +'repast', +'repave', +'repeal', +'repel', +'repent', +'replay', +'reply', +'report', +'repose', +'repost', +'reread', +'resat', +'rescue', +'resent', +'reset', +'reship', +'resift', +'resign', +'resin', +'resiny', +'resole', +'result', +'resume', +'retail', +'retain', +'retch', +'retest', +'retina', +'retool', +'retort', +'retro', +'retry', +'retune', +'revamp', +'revere', +'revet', +'revile', +'revise', +'revive', +'revue', +'rewash', +'rewed', +'rewind', +'rhesus', +'rheum', +'rheumy', +'rhino', +'rhyme', +'ribald', +'ribbon', +'richen', +'ridden', +'riddle', +'rider', +'riders', +'ridge', +'ridgy', +'riding', +'riffle', +'rifled', +'rigger', +'right', +'rights', +'rigid', +'rigour', +'rinse', +'rinser', +'ripely', +'riper', +'ripple', +'ripply', +'ripsaw', +'risen', +'risky', +'ritual', +'ritzy', +'riven', +'river', +'riyal', +'roach', +'roadie', +'roast', +'robber', +'robed', +'robin', +'robot', +'robust', +'rocker', +'rocky', +'rococo', +'rodent', +'rodeo', +'roger', +'rogue', +'roller', +'rondo', +'rookie', +'roomy', +'roost', +'ropey', +'rosary', +'roster', +'rotary', +'rotate', +'rotor', +'rotten', +'rotter', +'rotund', +'rouble', +'rouge', +'rough', +'rouse', +'rouser', +'roust', +'route', +'rowdy', +'rowel', +'royal', +'rubati', +'rubato', +'rubber', +'rubble', +'rubout', +'rubric', +'ruddy', +'ruffle', +'rugby', +'ruled', +'ruler', +'ruling', +'rumba', +'rumble', +'rumen', +'rummer', +'rummy', +'rumour', +'rumple', +'rumply', +'rumpus', +'runlet', +'runnel', +'runner', +'runny', +'runty', +'runway', +'rupee', +'rupiah', +'rural', +'rushy', +'russet', +'rustic', +'rustle', +'rustre', +'rutty', +'sable', +'sabot', +'sabra', +'sabre', +'sachem', +'sachet', +'sacker', +'sacra', +'sacral', +'sacred', +'sacrum', +'sadden', +'saddle', +'safari', +'safely', +'safety', +'sagely', +'saggy', +'sahib', +'sailor', +'saint', +'saker', +'salaam', +'salad', +'salami', +'salary', +'saline', +'sallow', +'sally', +'salmon', +'salon', +'saloon', +'salsa', +'salted', +'salts', +'salty', +'salvo', +'samba', +'sampan', +'sample', +'sandal', +'sander', +'sandy', +'sanely', +'sappy', +'sarong', +'sateen', +'satin', +'satiny', +'satori', +'satrap', +'satyr', +'saucer', +'saucy', +'sauna', +'savant', +'saved', +'savour', +'savoy', +'sawfly', +'sawyer', +'saying', +'scabby', +'scalar', +'scald', +'scale', +'scaled', +'scales', +'scalp', +'scaly', +'scamp', +'scampi', +'scans', +'scanty', +'scape', +'scarab', +'scarce', +'scarer', +'scarf', +'scarp', +'scary', +'scathe', +'scent', +'schema', +'scheme', +'schism', +'schist', +'schizo', +'school', +'schuss', +'schwa', +'scion', +'scoff', +'scold', +'sconce', +'scone', +'scoot', +'scope', +'scored', +'scores', +'scotch', +'scour', +'scout', +'scowl', +'scrag', +'scram', +'scrap', +'scrape', +'scrawl', +'scree', +'screed', +'screen', +'screw', +'screwy', +'scribe', +'scrim', +'scrimp', +'scrip', +'script', +'scroll', +'scrub', +'scrum', +'scuba', +'scuff', +'scull', +'sculpt', +'scummy', +'scurf', +'scurfy', +'scurry', +'scurvy', +'scythe', +'seabed', +'sealer', +'seaman', +'seamer', +'seance', +'season', +'seater', +'seaway', +'secant', +'secede', +'second', +'secret', +'sector', +'sects', +'secure', +'sedan', +'sedge', +'sedgy', +'seeded', +'seeder', +'seedy', +'seeing', +'seemly', +'seethe', +'segue', +'seine', +'seisin', +'seize', +'seldom', +'select', +'seller', +'selves', +'sempre', +'senate', +'sender', +'senile', +'senior', +'senna', +'sense', +'sensor', +'sentry', +'sepal', +'sepia', +'sepoy', +'sepses', +'sepsis', +'septa', +'septet', +'septum', +'sequel', +'sequin', +'serape', +'serene', +'serge', +'series', +'serif', +'sermon', +'serous', +'serum', +'serve', +'served', +'server', +'serves', +'servo', +'sesame', +'settee', +'settle', +'seven', +'severe', +'sewage', +'sewer', +'sexpot', +'sextet', +'sexton', +'shabby', +'shack', +'shaded', +'shady', +'shaft', +'shaggy', +'shake', +'shaken', +'shaky', +'shale', +'shall', +'shalom', +'shaman', +'shandy', +'shank', +'shanty', +'shaped', +'shapes', +'shard', +'share', +'shared', +'shark', +'sharp', +'shave', +'shaven', +'shawl', +'shawm', +'shchi', +'sheaf', +'shear', +'sheath', +'sheave', +'sheen', +'sheeny', +'sheep', +'sheer', +'sheet', +'sheik', +'sheikh', +'shekel', +'shelf', +'shell', +'shelve', +'sherds', +'sherry', +'shield', +'shifty', +'shimmy', +'shine', +'shiny', +'ships', +'shire', +'shirk', +'shirr', +'shirt', +'shiver', +'shoal', +'shoat', +'shoddy', +'shogun', +'shone', +'shook', +'shoot', +'shoots', +'shore', +'shorn', +'short', +'shorty', +'shots', +'should', +'shout', +'shouts', +'shove', +'showed', +'shower', +'shown', +'shows', +'showy', +'shrank', +'shred', +'shrew', +'shrewd', +'shriek', +'shrift', +'shrike', +'shrill', +'shrimp', +'shrine', +'shrink', +'shrive', +'shroud', +'shrub', +'shrug', +'shrunk', +'shtick', +'shunt', +'shush', +'shyer', +'shyest', +'shyly', +'sicken', +'sickie', +'sickly', +'sided', +'sides', +'siding', +'sidle', +'siege', +'sienna', +'sierra', +'siesta', +'sieve', +'sifted', +'sifts', +'sigma', +'signet', +'signor', +'signs', +'silage', +'silent', +'silica', +'silken', +'silky', +'silly', +'silty', +'simian', +'simile', +'simmer', +'simon', +'simony', +'simoom', +'simper', +'simple', +'since', +'sinew', +'sinful', +'singe', +'single', +'sinter', +'sinus', +'siphon', +'siren', +'sisal', +'sissy', +'sister', +'sitcom', +'sitter', +'sixer', +'sixth', +'sixty', +'sized', +'sizes', +'sizing', +'sizzle', +'skate', +'skeet', +'skein', +'skewer', +'skiff', +'skill', +'skimpy', +'skinny', +'skirt', +'skirts', +'skivvy', +'skulk', +'skull', +'skunk', +'skyway', +'slack', +'slain', +'slake', +'slalom', +'slang', +'slangy', +'slant', +'slash', +'slate', +'slaver', +'sledge', +'sleek', +'sleeps', +'sleepy', +'sleet', +'sleety', +'sleeve', +'sleigh', +'slept', +'sleuth', +'slice', +'slick', +'slide', +'slime', +'slimy', +'sling', +'slink', +'slinky', +'sliver', +'slogan', +'sloop', +'slope', +'sloppy', +'slosh', +'slouch', +'slough', +'sloven', +'sludge', +'sludgy', +'sluice', +'slummy', +'slump', +'slung', +'slunk', +'slurp', +'slurry', +'slushy', +'slyly', +'smack', +'small', +'smarmy', +'smart', +'smarts', +'smear', +'smell', +'smelly', +'smelt', +'smiler', +'smiley', +'smirch', +'smirk', +'smite', +'smiter', +'smithy', +'smock', +'smoggy', +'smoke', +'smoky', +'smooch', +'smote', +'smudgy', +'snack', +'snafu', +'snail', +'snake', +'snaky', +'snappy', +'snaps', +'snare', +'snarer', +'snarly', +'snatch', +'snazzy', +'sneaky', +'sneeze', +'snick', +'snide', +'sniff', +'snipe', +'snippy', +'snitch', +'snivel', +'snobby', +'snood', +'snook', +'snoop', +'snoopy', +'snooty', +'snooze', +'snore', +'snort', +'snotty', +'snout', +'snowy', +'snuff', +'soaker', +'soapy', +'soarer', +'soccer', +'socio', +'sodden', +'sodium', +'soever', +'soften', +'softer', +'softly', +'softy', +'soggy', +'soiled', +'soiree', +'solace', +'solar', +'solder', +'soled', +'solely', +'soles', +'solid', +'soling', +'solute', +'solve', +'solved', +'sombre', +'sonar', +'sonata', +'sonnet', +'sonny', +'soothe', +'sooty', +'soppy', +'sorbet', +'sordid', +'sorrel', +'sorrow', +'sorry', +'sorted', +'sorter', +'sortie', +'sough', +'sought', +'sound', +'soupy', +'source', +'souse', +'south', +'soviet', +'sower', +'spacey', +'spadix', +'spank', +'spare', +'spark', +'sparky', +'spars', +'sparse', +'spasm', +'spate', +'spathe', +'spatio', +'spavin', +'spawn', +'speak', +'speaks', +'spear', +'specie', +'speck', +'speedy', +'spell', +'spelt', +'spend', +'spent', +'sphinx', +'spice', +'spicy', +'spider', +'spiel', +'spiffy', +'spigot', +'spike', +'spiky', +'spill', +'spilt', +'spinal', +'spinet', +'spiny', +'spiral', +'spire', +'spired', +'spires', +'spirit', +'spiry', +'spite', +'splat', +'splay', +'spleen', +'splice', +'spline', +'splint', +'split', +'spoil', +'spoilt', +'spoken', +'spongy', +'spoof', +'spook', +'spooky', +'spool', +'spoor', +'spore', +'sporty', +'spots', +'spotty', +'spouse', +'spout', +'sprain', +'sprang', +'sprat', +'sprawl', +'spray', +'spree', +'sprig', +'sprint', +'sprite', +'sprout', +'spruce', +'sprue', +'sprung', +'spryer', +'spryly', +'spume', +'spumy', +'spurge', +'spurn', +'spurt', +'sputa', +'squab', +'squad', +'squall', +'square', +'squash', +'squat', +'squaw', +'squawk', +'squeal', +'squib', +'squid', +'squint', +'squire', +'squirl', +'squirm', +'squirt', +'stably', +'stadia', +'staff', +'stager', +'stagy', +'staid', +'stair', +'stake', +'stale', +'stalk', +'stall', +'stamen', +'stamp', +'stance', +'stank', +'stanza', +'staple', +'stare', +'stark', +'starry', +'start', +'starts', +'starve', +'stash', +'stasis', +'state', +'stated', +'stater', +'states', +'static', +'stator', +'statue', +'status', +'stave', +'stayer', +'stead', +'steady', +'steak', +'steal', +'steamy', +'steed', +'steel', +'steely', +'steep', +'steers', +'stein', +'stench', +'steno', +'steppe', +'stereo', +'stern', +'sticky', +'stiff', +'stigma', +'stile', +'still', +'stingy', +'stink', +'stinky', +'stint', +'stitch', +'stoat', +'stock', +'stodgy', +'stoic', +'stoke', +'stole', +'stolen', +'stolid', +'stolon', +'stoma', +'stomal', +'stomp', +'stoner', +'stony', +'stood', +'stooge', +'stool', +'stoop', +'store', +'storer', +'storey', +'stork', +'stormy', +'story', +'stoup', +'stout', +'stove', +'strafe', +'strain', +'strait', +'strand', +'strap', +'strata', +'strati', +'straw', +'stray', +'streak', +'stream', +'street', +'strew', +'strewn', +'stria', +'striae', +'stride', +'strife', +'strim', +'string', +'strip', +'stripe', +'strive', +'strobe', +'strode', +'stroke', +'stroll', +'strop', +'strove', +'struck', +'strum', +'strung', +'strut', +'stubby', +'stucco', +'stuck', +'studio', +'stuff', +'stuffs', +'stuffy', +'stump', +'stumpy', +'stung', +'stunk', +'stupid', +'stupor', +'sturdy', +'style', +'styler', +'styli', +'stylus', +'stymie', +'suave', +'subdue', +'sublet', +'submit', +'subnet', +'suborn', +'subset', +'subtle', +'subtly', +'suburb', +'subway', +'sucker', +'suckle', +'sudden', +'sudsy', +'suede', +'sugar', +'sugary', +'suite', +'suited', +'suitor', +'sulky', +'sullen', +'sully', +'sultan', +'sultry', +'sumac', +'summon', +'sundae', +'sunder', +'sundry', +'sunken', +'sunlit', +'sunny', +'sunset', +'suntan', +'super', +'superb', +'supine', +'supple', +'supply', +'supra', +'surer', +'surety', +'surge', +'surly', +'surtax', +'survey', +'sushi', +'sutler', +'suture', +'svelte', +'swain', +'swami', +'swampy', +'swanky', +'sward', +'swarm', +'swart', +'swash', +'swatch', +'swath', +'swathe', +'swear', +'sweaty', +'swede', +'sweet', +'swell', +'swept', +'swerve', +'swift', +'swill', +'swine', +'swipe', +'swirl', +'swirly', +'swish', +'switch', +'swivel', +'swizz', +'swoon', +'swoop', +'swoosh', +'swore', +'sworn', +'swung', +'sylph', +'sylvan', +'synch', +'syndic', +'synod', +'syntax', +'syphon', +'syrup', +'syrupy', +'syzygy', +'tabby', +'tabla', +'table', +'tablet', +'taboo', +'tabor', +'tacit', +'tackle', +'tacky', +'tactic', +'tagged', +'taiga', +'taint', +'taken', +'taker', +'talcum', +'talkie', +'talky', +'tallow', +'tally', +'talon', +'talus', +'tamale', +'tamed', +'tamper', +'tandem', +'tangle', +'tango', +'tangy', +'tanned', +'tannin', +'tansy', +'tantra', +'taper', +'tapir', +'tapped', +'tappet', +'tardy', +'target', +'tariff', +'tarmac', +'tarot', +'tarpon', +'tarry', +'tarsal', +'tarsi', +'tarsus', +'tartan', +'tartar', +'tassel', +'tastes', +'tasty', +'tatter', +'tattle', +'tattoo', +'taught', +'taupe', +'tavern', +'tawdry', +'tawny', +'taxer', +'taxies', +'taxing', +'teabag', +'teapot', +'tease', +'teasel', +'teazel', +'teazle', +'techs', +'teddy', +'tedium', +'teens', +'teeny', +'teepee', +'teeter', +'teeth', +'teethe', +'telex', +'teller', +'telly', +'temper', +'tempi', +'temple', +'tempo', +'tempt', +'tenant', +'tench', +'tended', +'tendon', +'tends', +'tenet', +'tenner', +'tennis', +'tenon', +'tenor', +'tenpin', +'tense', +'tensor', +'tenter', +'tenth', +'tents', +'tenure', +'tepee', +'tepid', +'tercel', +'terns', +'terry', +'terse', +'tested', +'tests', +'testy', +'tetchy', +'tether', +'tetra', +'thane', +'thatch', +'theft', +'their', +'theism', +'theist', +'theme', +'thence', +'there', +'therm', +'these', +'thesis', +'theta', +'thick', +'thief', +'thieve', +'thigh', +'thine', +'thing', +'think', +'third', +'thirst', +'thirty', +'thole', +'thorax', +'thorny', +'those', +'though', +'thrall', +'thrash', +'thread', +'threat', +'three', +'thresh', +'threw', +'thrice', +'throb', +'throe', +'throne', +'throng', +'throw', +'thrown', +'thrum', +'thrush', +'thrust', +'thumb', +'thump', +'thunk', +'thwack', +'thwart', +'thyme', +'thymus', +'tiara', +'tibia', +'tibiae', +'tickle', +'tidal', +'tiger', +'tight', +'tilde', +'tiled', +'tilled', +'tiller', +'tilth', +'timber', +'timbre', +'timed', +'timely', +'timer', +'timid', +'timing', +'tinder', +'tinge', +'tingle', +'tingly', +'tinker', +'tinkle', +'tinny', +'tinpot', +'tinsel', +'tippet', +'tipple', +'tipsy', +'tiptoe', +'tiptop', +'tirade', +'tired', +'tiring', +'tissue', +'titan', +'titbit', +'tithe', +'title', +'titled', +'titre', +'titter', +'tittle', +'tizzy', +'toady', +'toast', +'toasty', +'tocsin', +'today', +'toddle', +'toddy', +'toecap', +'toffee', +'toggle', +'toilet', +'toity', +'token', +'tomato', +'tomboy', +'tomcat', +'tomtit', +'tonal', +'toned', +'toner', +'tongue', +'tonic', +'toning', +'tonne', +'tonsil', +'tooled', +'tools', +'tooth', +'toothy', +'tootle', +'toots', +'tootsy', +'topaz', +'toper', +'topic', +'topple', +'toque', +'torch', +'toroid', +'torpid', +'torpor', +'torque', +'torrid', +'torso', +'torte', +'torus', +'total', +'totem', +'totter', +'toucan', +'touch', +'touchy', +'tough', +'toupee', +'tourer', +'tousle', +'toward', +'towbar', +'towel', +'tower', +'townee', +'townie', +'toxic', +'toxin', +'trace', +'traced', +'traces', +'tracts', +'tragic', +'trail', +'trails', +'train', +'trains', +'trait', +'traits', +'tramp', +'trance', +'trashy', +'trauma', +'travel', +'trawl', +'tread', +'treat', +'treats', +'treaty', +'treble', +'tremor', +'trench', +'trendy', +'trews', +'triad', +'triage', +'tribal', +'trice', +'tricky', +'tried', +'tries', +'trifle', +'trike', +'trilby', +'trill', +'triode', +'tripe', +'triple', +'triply', +'tripod', +'tripos', +'trite', +'triune', +'trivet', +'trivia', +'troika', +'troll', +'tromp', +'troop', +'trophy', +'tropic', +'troth', +'trough', +'troupe', +'trout', +'trove', +'trowel', +'truant', +'truce', +'truck', +'trudge', +'truism', +'truly', +'trump', +'trunk', +'truss', +'trusty', +'truth', +'tryst', +'tsetse', +'tubby', +'tubing', +'tubule', +'tucker', +'tulip', +'tulle', +'tumble', +'tumid', +'tummy', +'tumour', +'tumult', +'tundra', +'tuned', +'tunes', +'tunic', +'tuning', +'tunnel', +'tunny', +'tupelo', +'turban', +'turbid', +'turbo', +'turbot', +'tureen', +'turfy', +'turgid', +'turkey', +'turned', +'turner', +'turnip', +'turret', +'turtle', +'turvy', +'tussle', +'tutor', +'tutti', +'tuxedo', +'twain', +'twang', +'twangy', +'tweak', +'tweed', +'tweedy', +'tweet', +'tweeze', +'twelve', +'twenty', +'twerp', +'twice', +'twiggy', +'twilit', +'twill', +'twine', +'twinge', +'twirl', +'twist', +'twisty', +'twitch', +'tycoon', +'typed', +'typhus', +'typify', +'tyrant', +'tyred', +'ukase', +'ulcer', +'ulnae', +'ulnar', +'ulster', +'ultimo', +'ultra', +'umbel', +'umber', +'umbra', +'umbrae', +'umlaut', +'umpire', +'unable', +'unary', +'unban', +'unbar', +'unbend', +'unbolt', +'uncial', +'unclad', +'uncle', +'uncool', +'uncork', +'uncurl', +'uncut', +'under', +'undue', +'unease', +'uneven', +'unfair', +'unfelt', +'unfit', +'unfix', +'unhand', +'unholy', +'unhurt', +'union', +'unique', +'unisex', +'unison', +'unite', +'unity', +'unjust', +'unkind', +'unkink', +'unlace', +'unlap', +'unlike', +'unlink', +'unlit', +'unload', +'unlock', +'unmake', +'unmask', +'unmesh', +'unmet', +'unpack', +'unpick', +'unpin', +'unplug', +'unread', +'unreal', +'unrest', +'unruly', +'unsafe', +'unset', +'unshod', +'unsnap', +'unsure', +'unties', +'until', +'untrue', +'unwind', +'unwire', +'unyoke', +'upbeat', +'update', +'upend', +'upheld', +'uphill', +'uphold', +'upkeep', +'upland', +'uplift', +'uplink', +'upload', +'upped', +'upper', +'upping', +'uppish', +'uppity', +'uprate', +'uproar', +'uproot', +'upset', +'upshot', +'upside', +'uptake', +'uptime', +'uptown', +'upturn', +'upward', +'upwind', +'uracil', +'urban', +'urbane', +'urchin', +'ureter', +'urgent', +'urinal', +'ursine', +'usable', +'usage', +'useful', +'using', +'usual', +'usurer', +'usury', +'utile', +'utmost', +'utopia', +'utter', +'uvula', +'uvular', +'vacant', +'vacate', +'vacua', +'vacuum', +'vagary', +'vague', +'valet', +'valise', +'valley', +'valour', +'valued', +'valuer', +'values', +'vamped', +'vamps', +'vandal', +'vanity', +'vapid', +'vapour', +'varied', +'varlet', +'vassal', +'vault', +'vaunt', +'vector', +'vegan', +'veggie', +'velar', +'veldt', +'vellum', +'velour', +'velum', +'velvet', +'vendor', +'venial', +'venom', +'venous', +'vented', +'venue', +'verbal', +'verge', +'verger', +'verify', +'verity', +'vermin', +'vernal', +'versa', +'verse', +'versed', +'verso', +'versus', +'vertex', +'verve', +'vesper', +'vessel', +'vestal', +'vetch', +'vetoes', +'viable', +'viand', +'vicar', +'victor', +'video', +'views', +'vigil', +'vigour', +'viking', +'viler', +'vilify', +'villa', +'villi', +'villus', +'vinous', +'vinyl', +'violet', +'violin', +'viper', +'virago', +'viral', +'vireo', +'virus', +'visage', +'viscid', +'viscus', +'vision', +'visit', +'visits', +'visor', +'vista', +'visual', +'vitae', +'vitro', +'vivace', +'vivid', +'vivify', +'vixen', +'vizier', +'vocab', +'vodka', +'vogue', +'voice', +'voiced', +'voices', +'voided', +'voids', +'voile', +'volley', +'volte', +'volume', +'volute', +'voodoo', +'vortex', +'votary', +'vouch', +'vowel', +'voyage', +'vulgar', +'wacky', +'waddle', +'wafer', +'waffle', +'wager', +'waggle', +'wagon', +'wailer', +'waist', +'waive', +'waken', +'wakeup', +'walkie', +'wallet', +'wallop', +'wallow', +'walnut', +'walrus', +'waltz', +'wampum', +'wander', +'wangle', +'wanted', +'wanton', +'wapiti', +'warble', +'warded', +'warden', +'warder', +'warier', +'warmer', +'warmly', +'warmth', +'warren', +'washed', +'washes', +'waste', +'watery', +'wattle', +'waver', +'waxen', +'waylay', +'weaken', +'wealth', +'wearer', +'wears', +'weasel', +'weave', +'weaves', +'wedded', +'wedge', +'weedy', +'weekly', +'weenie', +'weensy', +'weeny', +'weepy', +'weevil', +'weigh', +'weight', +'weird', +'welled', +'wells', +'welsh', +'welter', +'wench', +'whack', +'whale', +'wharf', +'wheal', +'wheat', +'wheel', +'wheeze', +'wheezy', +'whelk', +'whelm', +'whelp', +'whence', +'where', +'which', +'whiff', +'while', +'whilom', +'whilst', +'whims', +'whimsy', +'whinny', +'whiny', +'whirl', +'whirr', +'whisk', +'whisky', +'whist', +'white', +'whiten', +'whitey', +'whole', +'wholly', +'whoop', +'whoosh', +'whorl', +'whose', +'whoso', +'wicked', +'wicket', +'widen', +'widget', +'widow', +'width', +'wield', +'wifely', +'wiggle', +'wiggly', +'wigwag', +'wigwam', +'wilder', +'wilful', +'willed', +'willow', +'wimple', +'wimpy', +'wince', +'winch', +'winds', +'windy', +'winery', +'winkle', +'winnow', +'winter', +'wintry', +'wired', +'wirer', +'wiring', +'wisdom', +'wised', +'wiser', +'wises', +'wisest', +'wising', +'wispy', +'withal', +'wither', +'within', +'witty', +'wives', +'wizen', +'wobbly', +'woken', +'wolves', +'woman', +'wombat', +'women', +'wonky', +'wooden', +'woods', +'woody', +'woolly', +'woozy', +'wordy', +'worker', +'wormer', +'wormy', +'worse', +'worsen', +'worst', +'worthy', +'would', +'wound', +'wounds', +'woven', +'wrack', +'wraith', +'wrasse', +'wreak', +'wreath', +'wreck', +'wrest', +'wring', +'write', +'writes', +'writhe', +'wrong', +'wroth', +'wrung', +'wryer', +'wryest', +'wryly', +'wurzel', +'xenon', +'xylem', +'xylol', +'yammer', +'yarrow', +'yeasty', +'yellow', +'yeoman', +'yeomen', +'yield', +'yikes', +'yippee', +'yobbo', +'yodel', +'yoked', +'yokel', +'yokes', +'yoking', +'yonder', +'young', +'youth', +'yucca', +'yucky', +'yummy', +'yuppie', +'zealot', +'zebra', +'zenith', +'zephyr', +'zeroes', +'zeugma', +'zigzag', +'zilch', +'zinnia', +'zippy', +'zither', +'zloty', +'zodiac', +'zombie', +'zonked', +'zygote' +); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/engine_default.php Wed Feb 06 18:41:47 2008 -0500 @@ -0,0 +1,150 @@ +<?php + +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 (Caoineag alpha 1) + * Copyright (C) 2006-2007 Dan Fuhry + * captcha.php - visual confirmation system used during registration + * + * This program is Free Software; you can redistribute 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 details. + * + * This file contains code written by Paul Sohier (www.paulscripts.nl). The CAPTCHA code was ported from the phpBB Better + * Captcha mod, and has been released under the GPLv2 by the original author. + */ + +/** + * The default CAPTCHA engine. Generates medium-strength captchas with very good performance. + * @package Enano + * @subpackage User management + * @copyright 2007-2008 Dan Fuhry + * @copyright Paul Sohier + */ + +class captcha_engine_default extends captcha_base +{ + function make_image() + { + $code =& strtoupper($this->get_code()); + + /** + * The next part is orginnaly written by ted from mastercode.nl and modified for use in Enano. + **/ + header("content-type:image/png"); + header('Cache-control: no-cache, no-store'); + $breedte = 320; + $hoogte = 60; + $img = imagecreatetruecolor($breedte,$hoogte); + $achtergrond = imagecolorallocate($img, $this->color("bg"), $this->color("bg"), $this->color("bg")); + + imagefilledrectangle($img, 0, 0, $breedte-1, $hoogte-1, $achtergrond); + for($g = 0;$g < 30; $g++) + { + $t = $this->dss_rand(); + $t = $t[0]; + + $ypos = rand(0,$hoogte); + $xpos = rand(0,$breedte); + + $kleur = imagecolorallocate($img, $this->color("bgtekst"), $this->color("bgtekst"), $this->color("bgtekst")); + + imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur, $this->font(), $t); + } + $stukje = $breedte / (strlen($code) + 3); + + for($j = 0;$j < strlen($code); $j++) + { + + + $tek = $code[$j]; + $ypos = rand(33,43); + $xpos = $stukje * ($j+1); + + $kleur2 = imagecolorallocate($img, $this->color("tekst"), $this->color("tekst"), $this->color("tekst")); + + imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur2, $this->font() , $tek); + } + + imagepng($img); + } + + /** + * Some functions :) + * Also orginally written by mastercode.nl + **/ + /** + * Function to create a random color + * @param $type string Mode for the color + * @return int + **/ + function color($type) + { + switch($type) + { + case "bg": + $kleur = rand(224,255); + break; + case "tekst": + $kleur = rand(0,127); + break; + case "bgtekst": + $kleur = rand(200,224); + break; + default: + $kleur = rand(0,255); + break; + } + return $kleur; + } + /** + * Function to ranom the size + * @return int + **/ + function size() + { + $grootte = rand(14,30); + return $grootte; + } + /** + * Function to random the posistion + * @return int + **/ + function move() + { + $draai = rand(-25,25); + return $draai; + } + + /** + * Function to return a ttf file from fonts map + * @return string + **/ + function font() + { + $f = @opendir(ENANO_ROOT . '/includes/captcha/fonts/'); + if(!$f) die('Can\'t open includes/captcha/fonts/ for reading'); + $ar = array(); + while(($file = @readdir($f)) !== false) + { + if(!in_array($file, array('.','..')) && strstr($file, '.ttf')) + { + $ar[] = $file; + } + } + if(count($ar)) + { + shuffle($ar); + $i = rand(0,(count($ar) - 1)); + return ENANO_ROOT . '/includes/captcha/fonts/' . $ar[$i]; + } + } + function dss_rand() + { + $val = microtime() . mt_rand(); + $val = md5($val . 'a'); + return substr($val, 4, 16); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/engine_failsafe.php Wed Feb 06 18:41:47 2008 -0500 @@ -0,0 +1,313 @@ +<?php + +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 (Caoineag alpha 1) + * Copyright (C) 2006-2007 Dan Fuhry + * captcha.php - visual confirmation system used during registration + * + * This program is Free Software; you can redistribute 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 details. + * + * This file contains code written by the phpBB team (www.phpbb.com). phpBB is licensed under the GPLv2. + */ + +/** + * Failsafe (no-GD) captcha engine. + * @package Enano + * @subpackage User management + * @copyright 2007-2008 Dan Fuhry + * @copyright 2002-2008 phpBB Group + */ + +class captcha_engine_failsafe extends captcha_base +{ + function make_image() + { + $code =& strtoupper($this->get_code()); + // We can we will generate a single filtered png + // Thanks to DavidMJ for emulating zlib within the code :) + $_png = $this->define_filtered_pngs(); + + $total_width = 320; + $total_height = 50; + $img_height = 40; + $img_width = 0; + $l = 0; + + list($usec, $sec) = explode(' ', microtime()); + mt_srand($sec * $usec); + + $char_widths = array(); + for ($i = 0; $i < strlen($code); $i++) + { + $char = $code{$i}; + + $width = mt_rand(0, 4); + $char_widths[] = $width; + $img_width += $_png[$char]['width'] - $width; + } + + $offset_x = mt_rand(0, $total_width - $img_width); + $offset_y = mt_rand(0, $total_height - $img_height); + + $image = ''; + $hold_chars = array(); + for ($i = 0; $i < $total_height; $i++) + { + $image .= chr(0); + + if ($i > $offset_y && $i < $offset_y + $img_height) + { + $j = 0; + + for ($k = 0; $k < $offset_x; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + + for ($k = 0; $k < strlen($code); $k++) + { + $char = $code{$k}; + + if (empty($hold_chars[$char])) + { + $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); + } + $image .= $this->randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); + $j++; + } + + for ($k = $offset_x + $img_width; $k < $total_width; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + + $l++; + } + else + { + for ($k = 0; $k < $total_width; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + } + + } + unset($hold); + + $image = $this->create_png($image, $total_width, $total_height); + + // Output image + header('Content-Type: image/png'); + header('Cache-control: no-cache, no-store'); + echo $image; + + unset($image); + unset($_png); + } + // This creates a chunk of the given type, with the given data + // of the given length adding the relevant crc + function png_chunk($length, $type, $data) + { + $raw = $type; + $raw .= $data; + $crc = crc32($raw); + $raw .= pack('C4', $crc >> 24, $crc >> 16, $crc >> 8, $crc); + + return pack('C4', $length >> 24, $length >> 16, $length >> 8, $length) . $raw; + } + + // Creates greyscale 8bit png - The PNG spec can be found at + // http://www.libpng.org/pub/png/spec/PNG-Contents.html we use + // png because it's a fully recognised open standard and supported + // by practically all modern browsers and OSs + function create_png($raw_image, $width, $height) + + { + // SIG + $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10); + // IHDR + $raw = pack('C4', $width >> 24, $width >> 16, $width >> 8, $width); + $raw .= pack('C4', $height >> 24, $height >> 16, $height >> 8, $height); + $raw .= pack('C5', 8, 0, 0, 0, 0); + $image .= $this->png_chunk(13, 'IHDR', $raw); + + if (@extension_loaded('zlib')) + { + $raw_image = gzcompress($raw_image); + $length = strlen($raw_image); + } + else + { + // The total length of this image, uncompressed, is just a calculation of pixels + $length = ($width + 1) * $height; + + // Adler-32 hash generation + // Optimized Adler-32 loop ported from the GNU Classpath project + $temp_length = $length; + $s1 = 1; + $s2 = $index = 0; + + while ($temp_length > 0) + { + // We can defer the modulo operation: + // s1 maximally grows from 65521 to 65521 + 255 * 3800 + // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 + $substract_value = ($temp_length < 3800) ? $temp_length : 3800; + $temp_length -= $substract_value; + + while (--$substract_value >= 0) + { + $s1 += ord($raw_image[$index]); + $s2 += $s1; + + $index++; + } + + $s1 %= 65521; + $s2 %= 65521; + } + $adler_hash = pack('N', ($s2 << 16) | $s1); + + // This is the same thing as gzcompress($raw_image, 0) but does not need zlib + $raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash; + + // The Zlib header + Adler hash make us add on 11 + $length += 11; + } + + // IDAT + $image .= $this->png_chunk($length, 'IDAT', $raw_image); + + // IEND + $image .= $this->png_chunk(0, 'IEND', ''); + + return $image; + } + + // Each 'data' element is base64_encoded uncompressed IDAT + // png image data + function define_filtered_pngs() + { + $_png = array( + '0' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==','width' => 40), + '1' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '2' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=','width' => 40), + '3' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '4' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '5' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '6' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '7' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '8' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '9' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'A' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'B' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'C' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'D' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'E' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'F' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'G' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'H' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'I' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'J' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'K' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'L' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'M' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'N' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'O' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'P' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'Q' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'R' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'S' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'T' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'U' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'V' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'W' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'X' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'Y' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'Z' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + ); + + return $_png; + } + + // These define base64_encoded raw png image data used + // when we cannot generate our own single png image + function define_raw_pngs() + { + $_png = array( + '0' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QKCNGXKO6AAAAB3RJTUUH0wUOEDQ6EUG1VwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNpj/M9AHGAiUt2wVvhyaqAqKyOjpG3jQwaGv+e+IUn9RwJfSjjg4iwFP1aKJD6HyyErfGGAYrquIoP5E2wK/zigu0v5wH9sChdgeKDqP1aFGhBZmxv/z0Dd4IxV4RWIpMQHIPuJAITzAqEQETx7IFQIP5CQNoJwDmALxzMQCuyjg1chnBPYwtECwr8AZN41h0p6YHOjAkTuwf//77wYuCEcFWwKOWA2fM1iZuuHcASwKYQ55c9ENuasrxgRjKlwJS+D17v/hBUeUGYwv/sfn0IRiJQZJIbxuFEFagjvSlDUQNgK2GIGqpC1JRhIfoAqxBYz0DRhn8IMJO+giKEqhMaMJBeI3AHhIKdkRPqG8DlAifqFADyasKRHO6h1Z/6fMYEwTbCmx3cWGCl8CTaFwBhGz+M2/7EpXMvOnBmIok7jBVaFz/Mi3/1pQORrhpgPyOr+M8IL0j9/gKpeLjhy5QEwoDVsYuRR3cE4IktcAJNx8cJaZBeQAAAAAElFTkSuQmCC', + '1' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMi//xxVKAAAAB3RJTUUH0wUOEDYLcqnX7wAAAAlwSFlzAAALEgAACxIB0t1+/AAAAHpJREFUeNpj/M9AHGAiUh1WhR8FGUGAsMKaD9iM/I8BlmCVwVS4hoUohT8qcNiFyv2zQIWBCIV3amRwu54RKcDRAgQ1KigIcJYK7CqR3QsCFmf+Y8qgeQakbANMAz6FKjUXECbj8zWa76nm61GFw1UhI10KqVGFNFQIADdK9Zj7PsV9AAAAAElFTkSuQmCC', + '2' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMwPUBEjoAAAAB3RJTUUH0wUOEDUqFe2UcgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQxJREFUeNpj/M9AHGAiUt2owkGrkAWF93LFgStPfjCwyGiYRGijqfyPAH9aOJAkQl78RwbICkNQjdB4gUNhD7qzLLAr/CKA4YENSAoRvl7zAUJXvPmxhgfCXILVMxEQvg+IDVUhgtVqDYjkDhD7B2aQIMIx5cOTN29evLAAsaEKObBajQzmQOQMcIQjHLwQgSisIaDwBdS5LHfwK7yhAHVVyX+8CrdAA5HB5gdehQ3Yoxpd4ZcAmDqbD//xKISEIjhU//zHoxDmXQaeFRhOZ8CmzuDOf3wKf8DsDfnyH6/CHJi6P//xKjyDJethVehBpMI7DPgVwrPCCgb8AK5wDwGFcNMF8EkCASOx1QcAGUxu1untnFIAAAAASUVORK5CYII=', + '3' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMxBQugk2AAAAB3RJTUUH0wUOEDU3duv4qwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATdJREFUeNpj/M9AHGAiUt0IVciCzPm7ZceZB28YGBQkLHwcmNFU/keANRJI4ioH/qMAJIUlaHatwaFwBrqrOO5gVfiCB8P9KVgVVkAtnPDh/wkLCFsGq0IFiGQLiH0D06P/GWHJ7O+NOzfuXLlzQRrEhgSawHscwYPurxAcwQMBf/4/aIAYyHIGr8IEeDhO+Y9XoQNUncwOVHGMRPEDSovc+IkzrpGDCQgUbuC1WgBhhsIHfAp3vPn/oIIFKfRxKQSDGohCA4IKX0DTD7YoRAWMUJ9iyQpbn4DBBWUQ5yFEDDnFw622gXAzwBxoYvfB5sYlUI0lD/4/gWWKJdgU/tHAcKjCD6y+PsGCpo4FJbaRgmcNqkqWCThTzxkTJHXo+Ro1HA9uOPHiATDlKJj4eKCVFIzDqWgGAK7GW/haPS+zAAAAAElFTkSuQmCC', + '4' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMyqWttCEAAAAB3RJTUUH0wUOEDUxn4hdngAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKBJREFUeNpj/M9AHGAiUh2FCucyQgCK4H9McIAFixwWhQ8kGIhS+MWAgTiFIQzEKWxhIE7hFgbiFF7hASkQIajwjQpInuUAIYV/XMDyU/4TUlgAlk75T0jhArCszR9CCk+AY07mxX8CCp+AY47nzH8CCn+YgOWW/CekMAYsVfMfl0JGmCBq4kNEDp2zAn0UMmItABjRvDykPTO43DgyFQIANP6pTFLWAdoAAAAASUVORK5CYII=', + '5' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMzPy3XhEAAAAB3RJTUUH0wUOEDUk8lW5dQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQpJREFUeNpj/M9AHGAiUt2oQuIVfmREBzgU3iHWxAfEKiTaRFpZnfAfAbAr/AsxUYagiVCbeQgqhPpFYmukLCOrZupRNJUIB02BCAjAZCK+/Ed2LoJZgm6bzRfsCgMw3JWAXaEBpg8uIGSRPPMBQmXc+P+iggXCnoOQZUQK1K8PgEAjGcQs7QGL6FzG5mtkcAUiyYIQYcRRUkDTLEIWR1b4ixamQMPhrKUP3rx48eDNFXmwdyFiOthixgXqaTAnBcKpwRaOS6A6Mx78fwBVx/IAm8I/KsTGzAkWNHUyb7Ar/L8GNSlK3MCRev7/v+CApC7kBUoUoAX4yQ0nHjwAWqpiE6GNFgNDoAwHAKC2Q2lMNcCmAAAAAElFTkSuQmCC', + '6' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNAObRd4vAAAAB3RJTUUH0wUOEDUc2lcB6wAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUh2Gwq2puryMjKKmmSfRVf5HBkcMEBI+L1CkUBROYUE2QuMFLoVr0CzzwKHwhQC6szZgV1gAtfHI/xs2mEYywsPxp8QHEMVxQ56B4aaJiIKIiIRCPDZf74DwI/5jB4hwPAChbAgG+BWoExlOxkoysuqW3sUV4BoQ/p0SqARLB44AF4HIByDMKMCuEIu7phCrUOADNl/DgMOJ/09SIMwPC7B5hgfC1/kB4kRAOC7YrFaByM0Ac85AOCLYrFaBhSMIQNPlG2wBDg3HP2CSGU/MuEAoiKVXUWxB9cwPiG8UwEGSg5FCMNOjwZ4/byqgpqwgMoWr/MGeZ1agqWPZgSNz/Z+AqnDCf1wK/29B8qbKDhQpRtTE8HfLjjMP3jDwKJh4hKCGJSPNC6lRhTRWCABWpdoxd/bZ4QAAAABJRU5ErkJggg==', + '7' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNA18/fMoAAAAB3RJTUUH0wUOEDUVo4u5TwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt2oQnorZIGzGLFJIyJ40HqGhUiFPFuQ/YUFPBGBmLcDSQybwj8OEDOW/CegsAeiruQ/AYV3OMDqTP4QUugCceCN/wQUQn1a8Z+Awj8qYHUiHwgpXAAxcMJ/Qgp1wOoEPhBSuANiYM5/QgpjIAovEFL4gweszgAz0NASxZ4vYMqHYDKDBiIWhWhWa0CS1x9CVn+8AaYsmAlZfQRC6RDMChADGTQIKjxDrMI7EEoBi0JGlMJe8AOY+sFOSCEeQHQBAABCZ7xyT9fJhwAAAABJRU5ErkJggg==', + '8' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNBeBnwpSAAAAB3RJTUUH0wUOEDUOKe5wowAAAAlwSFlzAAALEgAACxIB0t1+/AAAATVJREFUeNpj/M9AHGAiUt1AKmRB459cc+DBGwYWGQ2LEG1Umf/I4IELkozLA2QpFIUXJFDMEDiBQ+EHGTR3yHzArrAFwwct2BXqQGQ1zvw/owFh6mBXCDXmDJB5BsOrjEhxzfoHIgkiGCGB9xtrgEPtOwvEV6FWY4+ZAAgVc5LhZgKEGYI9wN+gBiPu4Pl/BFWlxA1cMfN/C0rUr8AVhX8K0KyuwaEwASNmarAqPACVTXnw/0oENBFewKYQGhYZYE4MVBM2hVAvQ1LhHQhHBVsUMjIgYhCdhy3PPASTd6GOxBYz0KhOQHajDjY3pkC1Rlz5fweqjqEAm8ILGK5gYLlDZICXYI+ZLzZo6gL+4EgUfyo4kJQJtCCpQ8kKQPB2zZ47L14AU5iMgUMAN7IM43AqHwdQIQAhMPz6Gz5V/wAAAABJRU5ErkJggg==', + '9' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNCQ+T2tEAAAAB3RJTUUH0wUOEDUHUDLIBwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAUZJREFUeNpj/M9AHGAiUh26wr9rE3V5GRlFTTM3/kVT+R8Z7FBBSKjsQJFCUTiFBcWMCbgUHmBBs20FdoV/VNDUMQi8wapwDVS65s2fPToQZgFWhRFIkm8kwGyeH9gUQm2+Aua0QDhb4LJI4XgHQmmDSRMIZw+emIEENAeEcwObQhEIdQHiABRbUGPGBSIQAWL/gHqbB5tnJkC1Fjz5f8IGwxwkhR8EsCQarFE4hViF/wsQCgKgHsSu8H8HLFkUQL2rgUPh/zslOiwMEjFH/kND2geXQvQgqMAWhSjgAIRygAswIuXCpXfevHjz4M0ZdQaGhxo/wAnyBTuWmPnvARGxuPH/iAa+9Ph/A7r9Ai+wK/zvg6ZwzX8cCl9oICtjmfIfl8L/bwIQ6gyO/Met8P//EwUmwHTJo5OyBU2CkdaF1KhCWisEAM/sJxmZkdWnAAAAAElFTkSuQmCC', + 'A' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFwy1U7TfAAAAB3RJTUUH0wUOEC0ZKCZtPQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAO1JREFUeNrt1LERwiAUBuAHZ2GRwsIypQMwQEZwgBQpM4QDZBSLFI7gCA5gQWGRdA5gkTuMSh48eMTUnq96wH98B+QiDCwruTD3D76qF676ueAp0Y9lSBXeSkFWaLAje3T+kkzK4SgpBzZw8pqxJWcdOJuRsyGPbWDk0tS20zw9SXsobdfytJVXdzNsP61i6Zt3K7Ht0UeUgbPdjsrOXMd+2IS2C2qb271HVWi7YANcNXFQsUEVBTXwNdl46jYRxPl52dnwRUZbhkLSDmS8DnxFRWiULxg8UxvobefuRR8ZQYDKtffVVcQWv/RrfgJC4bd0upw4MQAAAABJRU5ErkJggg==', + 'B' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGAusrz2zAAAAB3RJTUUH0wUOEC01Gv4B3gAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNpj/M9AHGAiUh0tFTKiAUHL2rsoKv9DARZDWFr+IwA+hQwMFcQqZDhCrMIIYhWK4FYIYv8444PuV+wK//9/A+UJwBUSCHAL3OEIsdoFyttCpGdiiAtHjoY/RCnk6PlBbBRKrCE6CqcQq5DlDs5whIT3CgUI788EvOEIBCegXB2YPCNMBSNMISqf5TeUjysK90LpP/itfrFEAhZCMHkWdKMYUbk2MAah7BqD02pUYEFkgMu8IE6hD0IdpmegwSejoKLjoY7syaFU7A0HhQA2e4cJytImvAAAAABJRU5ErkJggg==', + 'C' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGBbPqVFqAAAAB3RJTUUH0wUOEC4BEGemqAAAAAlwSFlzAAALEgAACxIB0t1+/AAAASlJREFUeNpj/M9AHGAiUt2owkGrkAWV+3TDgRtPPjBwyGiYBOijSv1HAlcCkGUcTiDLISvsQDOeZQp2hQWYDpuCTeEEbD44ganwDgc2vxpgKoyAyUWc+f9hjgCMtwFd4RuYRxog/ueBcl3QFc6BSmj8gfBrwE40yFmCrjABqrAH5mSZgJ4jX7AEjwlU4Zn/OAAsrp9AaRlccc0IzdeMsBilOPWQrBDmtpfEKnwBpZ8qZq58i6IS6vscKHcBcgQYlOz4gh6OK6AKfaB8G5hN6Aq/wBLPHjB3CczCFIzUA0u2PD0v/j9pgaf1ExgK3wgwYAEOWFL4GizqWC5gyzM1mArnEJkLZ2DPhf//n3BAVmeDkq8ZUZPL3TUn7gBLCgYFBYsAcxQZRmKrDwABNsv9SJSDwwAAAABJRU5ErkJggg==', + 'D' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGC1+orhOAAAAB3RJTUUH0wUOEC4yr7fHvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt1AKmSBsxiRhXlkNBxCpFFU/ocBTDMyPvxHADwKGRgUbhCpkEHiCZEKGRyIVciwArdCIPPFGg8YzwSvQiBogXFvEFD43wDKnQDl44yZGCh9glAU2sCsJqRQBkq/gMUw3G2wuP6PnU/H9PgRSgsQUvgESosQUngFSqsQUrgCSsNiCFcU7oBx9+CL6w8XamB5SeUPkelxAZEJ1+YPcQolXhCXFTTuEJULOUq+IOVrFgasQELBxMaHG1mEcTiVjwOoEADAIkCnGpmJKgAAAABJRU5ErkJggg==', + 'E' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGDeDwEE0AAAAB3RJTUUH0wUOEC8CkHXGUwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt2owkGrkAXGYMQqjUgJQ8EzpPsa05+D140oMYTk4KEQ4MMqZqgUhcM1czESW30AABfqB1XDnLzcAAAAAElFTkSuQmCC', + 'F' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGQe8AkDZAAAAB3RJTUUH0wUOEC8JB6cf2wAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt3wUsiCYDJikUYE3lDwDDm+xvTp4HUjIoaQXTsUAnxYxcyoQryAcUSWuAAW/gZTg/yEMAAAAABJRU5ErkJggg==', + 'G' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRFI1vWIAAAAB3RJTUUH0wUOEC8QY8y3GwAAAAlwSFlzAAALEgAACxIB0t1+/AAAASZJREFUeNpj/M9AHGAiUt0IVciCwvt7ZM+FOy8+MDBwSEho2AQII8v9R4A/U2RQtHEUfEBIIim8YYBhn8oNLAqP8GBxmcwbDIU3sKljYIhAV/jHgAE7uICmcAJMQqDmwp//D2YowPgxqAr/wPyr8QAi8EEHwleIQFW4BxYicG+eEHEomHECET5QhRVQhQn/cQFoFJ6AKgwgFNcPoFwdnAoZIXmGERahKDwkIdqlR1j4PiRW4RVCCmExvQenQrSYEXiDiAoUBfC4loAK23yBSnzArhCRehRmAJPFnRUxHDgU/lDA7zZECj/Cgl2dAkaeWYNVZcoHDIX/94hgKLM4gS27/v9QIICizGMDkiQjSon7c8eBCw+e/GFgkZEwsHCRRpZiHE5FMwCa2YE+WcAOUwAAAABJRU5ErkJggg==', + 'H' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRw2Z4k1AAAAB3RJTUUH0wUOEC8agxleBQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD1JREFUeNpj/M9AHGAiUt2oQvyABUozQml4+KMLDAXPDAWFLGh8RlwKh4JnaB88GOlxELhxVCFewDgEynAAN2sFVHAvevkAAAAASUVORK5CYII=', + 'I' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGSlg1E0WAAAAB3RJTUUH0wUOEC86uHd+zQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt1AKmRBMBkxJJE9OhQ8Q32FjGhxDQsjjCQwFDwzqnCwKkRKZqO5EBMwDqcSl2iFAMMeB0s/kLo2AAAAAElFTkSuQmCC', + 'J' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGywiiNsbAAAAB3RJTUUH0wUOEDAFw0tdbgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKdJREFUeNpj/M9AHGAiUh3xClmwijJCaSR3Ud/qUYWjCklTyIHEhifctw8ePHgCxO+B7L9QMQlsChW+QOiX4gwMd6BiItisVoHSB6AYWQwM/kNBBszkC/9PwKyc8B8B4Ar3YPHMHWwK/xtgqAv4j1XhEfScK/EEu8L/a1BVStz4j0Ph/yPItoe8QFH3nxGlkNq75cKDB0DDVBwitNEcwjhwpdmoQrwAAN6ioiFapgUdAAAAAElFTkSuQmCC', + 'K' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHAEoFhGpAAAAB3RJTUUH0wUOEDANzZDVXAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPZJREFUeNpj/M9AHGAiUt2owgFSyAgFMOGDrDARxkKo0H8wYEDh/b/AAzepACqEVeEdCQx1WBW+0ICry/mPR+EXE7i6kD94FP5xwaYOi8IIrOowFRbA1Xkgq8NQ2ANXZ/PlPx6FS3CpQ1fIAmOIoKn7jxbXf2CMNxvQIxvVRAQQ+YDXaiSQQqxChiOEFGoIQGidP/gVStxogLI68CqUuPH/BzSVcTzAoxCo7v//ObBIxK0QrO7/H1iCXIFT4QkIFxbaMh9wKYQJO0D5OYQUnoDF/QkCCuHJ1+APAYV3YOloAgGF8JTO84SAwjfQiGQIgPAZqV4rAACnKSarzdlc4gAAAABJRU5ErkJggg==', + 'L' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHA64qQw4AAAAB3RJTUUH0wUOEDAXMPIsJgAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt2QUMiCYDJCaezhMBQ8M6pwVCEdFLJgCjEisRH5Zyh4hvoKGUdkQUq0QgARaARRV9jUFQAAAABJRU5ErkJggg==', + 'M' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHBhMfblpAAAAB3RJTUUH0wUOEDAqaJpgNwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPNJREFUeNrdlK0OgzAUhS8bCQYxMYmcmEAgEAgejQfZQyG2pAIxOYlATkAu691o2tvSYia2iv7lyzn3NG0jhG1tt5H7Aggom7ZuaKPhBFqKV+pFWDGjjcxStEAYXuvBkrKtoVX+gdRiK9i6sxjgeVGUMJzWwZLACaZOTqoAOAronmrlBuvPkQsIgHn8BqnE2AMmhaaYJ57jqTRFMwsDyW249XaJLhAujizm7UFM5XCUXTqiTvBLQYWRc7H3WWt+3NmlyGbOGh9q/45mjQxUb+CA6A2jSqu5MweX0ooQWLJxLYx6fz0GwmBOsww5GP3At/dX4Ayb7qpFI9y5ygAAAABJRU5ErkJggg==', + 'N' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHC6DxyzwAAAAB3RJTUUH0wUOEDAye/b4YQAAAAlwSFlzAAALEgAACxIB0t1+/AAAALRJREFUeNpj/M9AHGAiUt0IV8gIARsRMlAROP8/BEB5Ii/+/0cVgXNRhRk8iFXIMIFYhRxXiFTIYPCDSIUMBcQqZNhDrEKZN0QqZAggViHDHIIKRSAUzx1CCrdAaZM/BBT+z4Eyaggp/KEDYbAcIaDw/wUWCEuBkML/PagBgFvhfxdiFT4RIVLh/zXEKvyfQqzCLypEKvx/hoVIhf9biFX4x4ZIhf8fCBCp8P8KNBHG4VQ0AwDEOyeZhO5p1AAAAABJRU5ErkJggg==', + 'O' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQExDSDoAAAAB3RJTUUH0wUOEDA4myMRfwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUt3wUsiCyv265ciZJ08YGGRkDGwCuFGk/iOBDwU8SDIcGS+Q5JAV7hBBs45nAVaFC1gwXTYBi8IdWNQxMCzAUPhBBJs6Bp4n6AoLYFI6az78f7NEB8ZNQFP4QwAqEfADwg+A+f0NqsI1UHGBDzCnSKC6EhYzB6B0Cj+UwZ+CKgNTeAZKu8C94QGlL6DGjAyU+wAeXC+gIiIQLiM0KzDC9CFCBlWICsnsL3aFMDc+hcs8QZWBKYSF2g24whvYFZpA6T1whUegNCwyoYGxAmYyLGZ+wOxYghqFX2BpO+APmP8nBspHj2uk1LPizf8PGyxgXPTUQ3x6JDqF//8/AYs6bHkGmCYF0O3FnguBCSaFA0kZS8IDJDlG1IIUVFK8eABMWzI6DgHCyDKMI7LEBQCD5YgI9wbKGgAAAABJRU5ErkJggg==', + 'P' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQvR2Mn2AAAAB3RJTUUH0wUOEDEDMzPJGgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKVJREFUeNpj/M9AHGAiUh05ChlRAKdu4k5Ulf9hANMQiwf/EQCfQgaJB0QqZHAhViHDEbg0AV8vwRM8QN0v5vBAOSfw+BrMWQDl8MClGeEKGGEKQcRXHmQemTGD1RMy+N14o4MDyvGAS7NgGMaIzPHAYyIy4HhBZMy0EBmFIX+IUsjRgqQOi2fAgEVBwyVGGEUEQw2O3EbLzDWSFDIOhtJsVCEWAAC/Yt2X+2PYcgAAAABJRU5ErkJggg==', + 'Q' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHRxSC0wxAAAAB3RJTUUH0wUOEDEKSu9xvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAW1JREFUeNpj/M9AHGAiUt2QUMiCzPm65cCZF08YGGRkDBx8uNFU/oeDDwU8SOIcBS/+IwOEwh0iaEYIrMCqcA4LprsmYFG4A4s6BoYFGAo/iGBTx8DzAl1hAUxKZ8WH/29W6MC4KWgKfwhAJXx+gPl/QmB+/4KqcANUXOQDVPiLBFRkCUwhJGb2wGzihzK4U6CMA6hReAbKc4F7wwFKX0CNGRkoB+HJJ1ARGZgAIziFM8J0IUIGXYjMZPaXkEJYYDyBiz+EuRFVoQKUdwWIz6qWvmRguAMVkUBVaIIUalPu9GgshIefAWrwrIHp//L/DQc4KjFiBi2uQ/7832KB5AX0uP5fAZOx2PDhfwNCIXrq+f9BhgEb4HmCkcL3YE3hSHkBnmfWYFMpsoaYXAgGDgcwFKLlaxYOCG2DqRCYrldkmIACUMIgZsaTI5Cg3IBNISp4AoovlT+EFf7/kYPkb3wK//8/YAGPGcYhUIYDAHBC9Yak1w7iAAAAAElFTkSuQmCC', + 'R' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHSkEuIgSAAAAB3RJTUUH0wUOEDEUsOBM3QAAAAlwSFlzAAALEgAACxIB0t1+/AAAAOZJREFUeNpj/M9AHGAiUh0NFLJAaUY0YRkJHYcQdmSh/xCAzRCZHf8RAJ9CBpYNRCpkEHgBV4jfMx+mEOVGIDDAaTWY82aPBZTLgV8hUCkaH6cbP8B8gxHgyODjgwstMDfiVIgWQyFE+lrhB3EBznOFuJgxuUFMXPPEbPmDpA53FH55osKMIoAe4F826MDMvPMfj9WgWFGBBeIf/Ar/H4FxJhBQ+B8WzCIfCCi8A4uvBgIK/2fA/POCgMIXHFBuDqH02ABLM3cIKPwgAuVHEFD4fwJM4AIBhT9goe4AFWAcAsXesFIIAEvJyZHTCSiTAAAAAElFTkSuQmCC', + 'S' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHTRnvuTLAAAAB3RJTUUH0wUOEDEbIF9RTAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVZJREFUeNpj/M9AHGAiUt2oQvyABYX398CWK3de/GBgkVEw8HFgRpH7jwSWqCDLyCxAlkNS+CcG3boY7AozMB3Wgk3hGSw+4HgBl0b4egIWhT9mYPGMBFQg4MH/D2tgvrKASzPC0yMjlP7CDSTOmrDIMDDwiHBsxzSRBypw5j9WgFDoAPNAxIQjX/ApXIDsC4OCLV9wKfzjwIACOEIO4IiZFxbooePzAqvC/z9qONBUStzAqvD//zc9BqgqNX5gVwgETxbkmCClvSk4FYLdsCMCptAGI2YSGV78+PLmz5MX4mDu1ByIMM9n9JiBxe4caGChy8MZMMsUIEFyAMoVwVC4BGaEwpI3/9/MEYGlJQyFPwQYsIE1mL7GlnCR0iNSXLtgqpO4gy1mvtigq1NAxCBKgP9pEUFWxlOCnNIYUYrmn3v23Ljx5gsw88sYOPhwI0sxDoEyHAABtSc836a1EQAAAABJRU5ErkJggg==', + 'T' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHgUdTbcyAAAAB3RJTUUH0wUOEDEgkVS4aAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADdJREFUeNpj/M9AHGAiUt0IVcgCpRlxyMODeSh4hmiFjGipB+Z7jEQ1FDwzqnBU4WBSyDicimYAb/AFTaJpyH8AAAAASUVORK5CYII=', + 'U' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHhEHl2NPAAAAB3RJTUUH0wUOEDEon48wWgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKlJREFUeNpj/M9AHGAiUh3xClmgNCOUhrsEXYD6Vo8qHFVIuUIVKP0USr+E0jLoCjWg9A4ovQVNHJjUIaADZsILMPeFApRfA5X/D1N4AaZRYc6b/2+WwNQxXEBX+N8Bqxcc/mMoPMGCRR3LBUyF/2dgUTjjPxaF/6egm8ky5T9Whf9P2KCoMziBJPefEaWQurjnzIMXL34wsMhoWHiYo2hjHLjSbFQhXgAAKzejCLAOcVMAAAAASUVORK5CYII=', + 'V' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHh/gL05IAAAAB3RJTUUH0wUOEDEuduyVbwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVNJREFUeNpj/M9AHGAiUt2owoFRaMgIAYlIMqlQMUMo/z8ITIByRP78hwMRqNgECBei8AULVPQIXN0RqAjLGwgfYrW4B1R4DdzmLVDaQxjZ6v8roDwVuIkqMK3/ka3+/0MAKn4FKn4D5uof/5GtZmCPgEpsQHNDBDsDitVwt5tA+RZQ/pn/qFYj3PQEzHsC5WnA3QyPmQQU3+5AE0VYDTfDBcxzgQbik/8YVv93gMp9AbK/cEAD8T+m1TBb/oD8veEHhs0IE2GmxADZMRAmz4//WKxGkv3DA2Gm/MeqcA/Ujj1w1hHsCv/LQKQz/megRzyawgqIvAxMRwsuhbCEAEvGT3AphEUwNCU5IEv9R8lcUH9/wAxE5HAEgjccSBI8X3CbKOyBxAnhxm3i/w1IEgdQZFA98/+PCFydDKo6VKsZmGPQ0wgOq/+fgYvfQTORkeq1AgCIAvD7+THsDgAAAABJRU5ErkJggg==', + 'W' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFhZRKnzkAAAAB3RJTUUH0wUOEDIR66frkQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNrtlK1ywkAUhZdMZsJMKyIqKhAIBAKBiEBEVCDyCJV9iIo+Do9QGRERgUBEVCAqKhAIREVERURnTvfn3t27xSA6g+kOQ/ZkP/aec5NlBHXZSC7k/sE/AhUwoVkDPQ58/2RUQ2IC6B1XpN7MV8tg62/pUdjSDO7OwR2J0pbekpqZYlMG50bNSGwBDQ4pyV5YtCZ7mqZf1mO2IN2Jynba0XRx49pThjQCbEKWFfVRpIlBzlK4PuLdpxEWlTr4LHvYMEDOaTYS3HCW3DAJt8mmaSXYchZbOfEzkyYGZRbrEbX8qe7GMpLqFeyxV9F4fon1pwcxjxbqJpJTBPBJLoyHYSz1I3xq78aOMssepHZZHFjKhbX9/AZd6e9bsdABeyHTQXiE2PLO6PugCwiP/r1QVLYSlpXwKE1Wno7b7jY+hoWj0aegPyA9+jPrzgqwZJ0j8hhMVtElmDoD19FFPAvamc+sOXBm+KdYEzC63p/9D7Tr72kj/8qjAAAAAElFTkSuQmCC', + 'X' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHi/G9n7kAAAAB3RJTUUH0wUOEDIXAsROpAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAT9JREFUeNpj/M9AHGAiUt3IVhjKCAFr4RJroSKBMIH/YPBEAMITeQLh//8gAxHggQlAFf6fAdXnA+WnQPkT/qMp/O8AlVkA5h2A8kz+YCi8wQGREngA5PxQgXBYzvzHUPi/A2qIA5BdAmUX/Mei8I8BVHbK/wssEJbMB2wK/5+ASvPcgGlZ8x+rQriFAmghgKHwiwJKXPA8wKXw/x4UhT3/cSr8n4CkzuAPHoVvRODqWE6gyPxHTT1ffiAUCjCgAhRtDkgSFnisnoJixAScCh/wEBk8DmiucsChcA5MQQSMMQWrQlgiZ0iAByey5QiFPlBZnS//v+hgxjZc4QKYKVeAnCswby3AUAi3eAGKNoEn6Ap94A5EjXUfNIUrEA6EALgzl6AohCUGsAMhAOZMkTfICkMw3I5wZgiEyzicimYAFRFkVwgDfJ0AAAAASUVORK5CYII=', + 'Y' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHjkyIsu1AAAAB3RJTUUH0wUOEDIkvRQvsgAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNrt1L0NgzAQBWAcUVB6AAZgBAoKhmAICoZgCAoKxmAECkbwABSUlBRILwF8duwYhFJEihJ37+6T5T9g8K6N20X3FdDDNjKKOeTIqZLtWcKBU73bCx1lPhgQNTWieY1zRLmGCZFQp1xTSSmBDUUgW754BF+GQLxAPUkMxMb0FlzUsqpKLXhxQPRqo+oIerggCvuMC7jhFJounA4gWhO2OIL6Jp/uzglHrh0fTyAaDRucQaTkUpxDQVBYDWZ/hYze6bsv/A8/DNlP/kgvwzuer4kCMGPZDgAAAABJRU5ErkJggg==', + 'Z' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHwfqWOdfAAAAB3RJTUUH0wUOEDIrLasyIwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAL5JREFUeNrl1C0OwkAQBWCWQIJEVPQIFT0GAlHBMRBIBKIHqahAIDlERY9R0UOs3ORh5qVLunmp5GfUZvczbzKzDqtltV7ofgtueHCp16h33xBGwn0KYqoTO/J868Csaj418e0cPujOkLDfmTsECcfcXOGhoC/NZQMUDBUDd5DwxiAtJGzprpCw48xVQcIhM1d6KOgLc/kIBcORgXtIeGGQOyRs6Oq0g7P92YbkRE7bRZhcwhh+6nLF5f7yx30B8Z7FgxzMWtEAAAAASUVORK5CYII=', + ); + + return $_png; + } + + // This is designed to randomise the pixels of the image data within + // certain limits so as to keep it readable. It also varies the image + // width a little + function randomise($scanline, $width) + { + $new_line = ''; + $start = floor($width/2); + $end = strlen($scanline) - ceil($width/2); + + for ($i = $start; $i < $end; $i++) + { + $pixel = ord($scanline{$i}); + + if ($pixel < 190) + { + $new_line .= chr(mt_rand(0, 205)); + } + else if ($pixel > 190) + { + $new_line .= chr(mt_rand(145, 255)); + } + else + { + $new_line .= $scanline{$i}; + } + } + + return $new_line; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/engine_freecap.php Wed Feb 06 18:41:47 2008 -0500 @@ -0,0 +1,810 @@ +<?php +/************************************************************\ +* +* freeCap v1.4.1 Copyright 2005 Howard Yeend +* www.puremango.co.uk +* +* This file is part of freeCap. +* +* freeCap 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. +* +* freeCap 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 freeCap; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* +\************************************************************/ + +/** + * A port of the freeCap captcha engine to Enano. + */ + +class captcha_engine_freecap extends captcha_base +{ + + var $site_tags = array(); + var $tag_pos = 0; + var $rand_func = "mt_rand"; + var $seed_func = "mt_srand"; + var $hash_func = "sha1"; + var $output = "png"; + var $use_dict = false; + var $dict_location = ""; + var $max_word_length = 7; + var $col_type = 1; + var $max_attempts = 20; + var $font_locations = Array(); + var $bg_type = 3; + var $blur_bg = false; + var $bg_images = Array(); + var $merge_type = 0; + var $morph_bg = true; + var $im, $im2, $im3; + var $font_size = 36; + var $debug = false; + + function __construct($s, $r = false) + { + parent::__construct($s, $r); + + // try to avoid the 'free p*rn' method of CAPTCHA circumvention + // see en.wikipedia.org/wiki/CAPTCHA for more info + // $this->site_tags[0] = "To avoid spam, please do NOT enter the text if"; + // $this->site_tags[1] = "this site is not puremango.co.uk"; + // or more simply: + // $site_tags[0] = "for use only on puremango.co.uk"; + // reword or add lines as you please + // or if you don't want any text: + $this->site_tags = array(); + + // where to write the above: + // 0=top + // 1=bottom + // 2=both + $this->tag_pos = 1; + + // functions to call for random number generation + // mt_rand produces 'better' random numbers + // but if your server doesn't support it, it's fine to use rand instead + $this->rand_func = "mt_rand"; + $this->seed_func = "mt_srand"; + + // which type of hash to use? + // possible values: "sha1", "md5", "crc32" + // sha1 supported by PHP4.3.0+ + // md5 supported by PHP3+ + // crc32 supported by PHP4.0.1+ + $this->hash_func = $this->session_fetch('hash_func', 'sha1'); + // store in session so can validate in form processor + + // image type: + // possible values: "jpg", "png", "gif" + // jpg doesn't support transparency (transparent bg option ends up white) + // png isn't supported by old browsers (see http://www.libpng.org/pub/png/pngstatus.html) + // gif may not be supported by your GD Lib. + $this->output = "png"; + + // 0=generate pseudo-random string, true=use dictionary + // dictionary is easier to recognise + // - both for humans and computers, so use random string if you're paranoid. + $this->use_dict = false; + // if your server is NOT set up to deny web access to files beginning ".ht" + // then you should ensure the dictionary file is kept outside the web directory + // eg: if www.foo.com/index.html points to c:\website\www\index.html + // then the dictionary should be placed in c:\website\dict.txt + // test your server's config by trying to access the dictionary through a web browser + // you should NOT be able to view the contents. + // can leave this blank if not using dictionary + $this->dict_location = ENANO_ROOT . "/includes/captcha/dicts/default.php"; + + // used to calculate image width, and for non-dictionary word generation + $this->max_word_length = 7; + + // text colour + // 0=one random colour for all letters + // 1=different random colour for each letter + $this->col_type = 1; + + // maximum times a user can refresh the image + // on a 6500 word dictionary, I think 15-50 is enough to not annoy users and make BF unfeasble. + // further notes re: BF attacks in "avoid brute force attacks" section, below + // on the other hand, those attempting OCR will find the ability to request new images + // very useful; if they can't crack one, just grab an easier target... + // for the ultra-paranoid, setting it to <5 will still work for most users + $this->max_attempts = 20; + + // list of fonts to use + // font size should be around 35 pixels wide for each character. + // you can use my GD fontmaker script at www.puremango.co.uk to create your own fonts + // There are other programs to can create GD fonts, but my script allows a greater + // degree of control over exactly how wide each character is, and is therefore + // recommended for 'special' uses. For normal use of GD fonts, + // the GDFontGenerator @ http://www.philiplb.de is excellent for convering ttf to GD + + // the fonts included with freeCap *only* include lowercase alphabetic characters + // so are not suitable for most other uses + // to increase security, you really should add other fonts + $this->font_locations = Array( + //ENANO_ROOT . "/includes/captcha/fonts/assimila.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/elephant.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/swash_normal.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/trekker_regular.ttf" + ENANO_ROOT . "/includes/captcha/fonts/FreeMonoBold.ttf", + ENANO_ROOT . "/includes/captcha/fonts/FreeSerifBold.ttf", + ENANO_ROOT . "/includes/captcha/fonts/LiberationSans-Bold.ttf", + ); + + // background: + // 0=transparent (if jpg, white) + // 1=white bg with grid + // 2=white bg with squiggles + // 3=morphed image blocks + // 'random' background from v1.3 didn't provide any extra security (according to 2 independent experts) + // many thanks to http://ocr-research.org.ua and http://sam.zoy.org/pwntcha/ for testing + // for jpgs, 'transparent' is white + $this->bg_type = 3; + // should we blur the background? (looks nicer, makes text easier to read, takes longer) + $this->blur_bg = false; + + // for bg_type 3, which images should we use? + // if you add your own, make sure they're fairly 'busy' images (ie a lot of shapes in them) + $this->bg_images = Array( + ENANO_ROOT . "/includes/captcha/pics/freecap_im1.jpg", + ENANO_ROOT . "/includes/captcha/pics/freecap_im2.jpg", + ENANO_ROOT . "/includes/captcha/pics/freecap_im3.jpg", + ENANO_ROOT . "/includes/captcha/pics/freecap_im4.jpg", + ENANO_ROOT . "/includes/captcha/pics/allyourbase.jpg" + ); + + // for non-transparent backgrounds only: + // if 0, merges CAPTCHA with bg + // if 1, write CAPTCHA over bg + $this->merge_type = 0; + // should we morph the bg? (recommend yes, but takes a little longer to compute) + $this->morph_bg = true; + + // you shouldn't need to edit anything below this, but it's extensively commented if you do want to play + // have fun, and email me with ideas, or improvements to the code (very interested in speed improvements) + // hope this script saves some spam :-) + } + + ////////////////////////////////////////////////////// + ////// Functions: + ////////////////////////////////////////////////////// + function make_seed() { + // from http://php.net/srand + list($usec, $sec) = explode(' ', microtime()); + return (float) $sec + ((float) $usec * 100000); + } + + function rand_color() { + $rf =& $this->rand_func; + if($this->bg_type==3) + { + // needs darker colour.. + return $rf(10,100); + } else { + return $rf(60,170); + } + } + + function myImageBlur($im) + { + // w00t. my very own blur function + // in GD2, there's a gaussian blur function. bunch of bloody show-offs... :-) + + $width = imagesx($im); + $height = imagesy($im); + + $temp_im = ImageCreateTrueColor($width,$height); + $bg = ImageColorAllocate($temp_im,150,150,150); + + // preserves transparency if in orig image + ImageColorTransparent($temp_im,$bg); + + // fill bg + ImageFill($temp_im,0,0,$bg); + + // anything higher than 3 makes it totally unreadable + // might be useful in a 'real' blur function, though (ie blurring pictures not text) + $distance = 1; + // use $distance=30 to have multiple copies of the word. not sure if this is useful. + + // blur by merging with itself at different x/y offsets: + ImageCopyMerge($temp_im, $im, 0, 0, 0, $distance, $width, $height-$distance, 70); + ImageCopyMerge($im, $temp_im, 0, 0, $distance, 0, $width-$distance, $height, 70); + ImageCopyMerge($temp_im, $im, 0, $distance, 0, 0, $width, $height, 70); + ImageCopyMerge($im, $temp_im, $distance, 0, 0, 0, $width, $height, 70); + // remove temp image + ImageDestroy($temp_im); + + return $im; + } + + function sendImage($pic) + { + // output image with appropriate headers + global $output,$im,$im2,$im3; + // ENANO - obfuscation technique disabled + // (this is for ethical reasons - ask dan at enanocms.org for information on why) + // Basically it outputs an X-Captcha header showing freeCap version, etc. Unnecessary + // header(base64_decode("WC1DYXB0Y2hhOiBmcmVlQ2FwIDEuNCAtIHd3dy5wdXJlbWFuZ28uY28udWs=")); + + if ( $this->debug ) + { + $x = imagesx($pic) - 70; + $y = imagesy($pic) - 20; + + $code = $this->get_code(); + $red = ImageColorAllocateAlpha($pic, 0xAA, 0, 0, 72); + ImageString($pic, 5, $x, $y, $code, $red); + ImageString($pic, 5, 5, $y, "[debug mode]", $red); + } + + switch($this->output) + { + // add other cases as desired + case "jpg": + header("Content-Type: image/jpeg"); + ImageJPEG($pic); + break; + case "gif": + header("Content-Type: image/gif"); + ImageGIF($pic); + break; + case "png": + default: + header("Content-Type: image/png"); + ImagePNG($pic); + break; + } + + // kill GD images (removes from memory) + ImageDestroy($this->im); + ImageDestroy($this->im2); + ImageDestroy($pic); + if(!empty($this->im3)) + { + ImageDestroy($this->im3); + } + exit(); + } + + function make_image() + { + ////////////////////////////////////////////////////// + ////// Create Images + initialise a few things + ////////////////////////////////////////////////////// + + // seed random number generator + // PHP 4.2.0+ doesn't need this, but lower versions will + $this->seed_func($this->make_seed()); + + // how faded should the bg be? (100=totally gone, 0=bright as the day) + // to test how much protection the bg noise gives, take a screenshot of the freeCap image + // and take it into a photo editor. play with contrast and brightness. + // If you can remove most of the bg, then it's not a good enough percentage + switch($this->bg_type) + { + case 0: + break; + case 1: + case 2: + $bg_fade_pct = 65; + break; + case 3: + $bg_fade_pct = 50; + break; + } + // slightly randomise the bg fade + $bg_fade_pct += $this->rand_func(-2,2); + + // read each font and get font character widths + // $font_widths = Array(); + // for($i=0 ; $i<sizeof($this->font_locations) ; $i++) + // { + // $handle = fopen($this->font_locations[$i],"r"); + // // read header of GD font, up to char width + // $c_wid = fread($handle,15); + // $font_widths[$i] = ord($c_wid{8})+ord($c_wid{9})+ord($c_wid{10})+ord($c_wid{11}); + // fclose($handle); + // } + + // modify image width depending on maximum possible length of word + // you shouldn't need to use words > 6 chars in length really. + $width = ($this->max_word_length*($this->font_size+10)+75); + $height = 90; + + $this->im = ImageCreateTrueColor($width, $height); + $this->im2 = ImageCreateTrueColor($width, $height); + + //////////////////////////////////////////////////////// + // GENERATE IMAGE // + //////////////////////////////////////////////////////// + + $word = $this->get_code(); + + // save hash of word for comparison + // using hash so that if there's an insecurity elsewhere (eg on the form processor), + // an attacker could only get the hash + // also, shared servers usually give all users access to the session files + // echo `ls /tmp`; and echo `more /tmp/someone_elses_session_file`; usually work + // so even if your site is 100% secure, someone else's site on your server might not be + // hence, even if attackers can read the session file, they can't get the freeCap word + // (though most hashes are easy to brute force for simple strings) + + ////////////////////////////////////////////////////// + ////// Fill BGs and Allocate Colours: + ////////////////////////////////////////////////////// + + // set tag colour + // have to do this before any distortion + // (otherwise colour allocation fails when bg type is 1) + $tag_col = ImageColorAllocate($this->im,10,10,10); + $site_tag_col2 = ImageColorAllocate($this->im2,0,0,0); + + // set debug colours (text colours are set later) + $debug = ImageColorAllocate($this->im, 255, 0, 0); + $debug2 = ImageColorAllocate($this->im2, 255, 0, 0); + + // set background colour (can change to any colour not in possible $text_col range) + // it doesn't matter as it'll be transparent or coloured over. + // if you're using bg_type 3, you might want to try to ensure that the color chosen + // below doesn't appear too much in any of your background images. + $bg = ImageColorAllocate($this->im, 254, 254, 254); + $bg2 = ImageColorAllocate($this->im2, 254, 254, 254); + + // set transparencies + ImageColorTransparent($this->im,$bg); + // im2 transparent to allow characters to overlap slightly while morphing + ImageColorTransparent($this->im2,$bg2); + + // fill backgrounds + ImageFill($this->im,0,0,$bg); + ImageFill($this->im2,0,0,$bg2); + + if($this->bg_type!=0) + { + // generate noisy background, to be merged with CAPTCHA later + // any suggestions on how best to do this much appreciated + // sample code would be even better! + // I'm not an OCR expert (hell, I'm not even an image expert; puremango.co.uk was designed in MsPaint) + // so the noise models are based around my -guesswork- as to what would make it hard for an OCR prog + // ideally, the character obfuscation would be strong enough not to need additional background noise + // in any case, I hope at least one of the options given here provide some extra security! + + $this->im3 = ImageCreateTrueColor($width,$height); + $temp_bg = ImageCreateTrueColor($width*1.5,$height*1.5); + $bg3 = ImageColorAllocate($this->im3,255,255,255); + ImageFill($this->im3,0,0,$bg3); + $temp_bg_col = ImageColorAllocate($temp_bg,255,255,255); + ImageFill($temp_bg,0,0,$temp_bg_col); + + // we draw all noise onto temp_bg + // then if we're morphing, merge from temp_bg to im3 + // or if not, just copy a $widthx$height portion of $temp_bg to $this->im3 + // temp_bg is much larger so that when morphing, the edges retain the noise. + + if($this->bg_type==1) + { + // grid bg: + + // draw grid on x + for($i=$this->rand_func(6,20) ; $i<$width*2 ; $i+=$this->rand_func(10,25)) + { + ImageSetThickness($temp_bg,$this->rand_func(2,6)); + $text_r = $this->rand_func(100,150); + $text_g = $this->rand_func(100,150); + $text_b = $this->rand_func(100,150); + $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); + + ImageLine($temp_bg,$i,0,$i,$height*2,$text_colour3); + } + // draw grid on y + for($i=$this->rand_func(6,20) ; $i<$height*2 ; $i+=$this->rand_func(10,25)) + { + ImageSetThickness($temp_bg,$this->rand_func(2,6)); + $text_r = $this->rand_func(100,150); + $text_g = $this->rand_func(100,150); + $text_b = $this->rand_func(100,150); + $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); + + ImageLine($temp_bg,0,$i,$width*2, $i ,$text_colour3); + } + } else if($this->bg_type==2) { + // draw squiggles! + + $bg3 = ImageColorAllocate($this->im3,255,255,255); + ImageFill($this->im3,0,0,$bg3); + ImageSetThickness($temp_bg,4); + + for($i=0 ; $i<strlen($word)+1 ; $i++) + { + $text_r = $this->rand_func(100,150); + $text_g = $this->rand_func(100,150); + $text_b = $this->rand_func(100,150); + $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); + + $points = Array(); + // draw random squiggle for each character + // the longer the loop, the more complex the squiggle + // keep random so OCR can't say "if found shape has 10 points, ignore it" + // each squiggle will, however, be a closed shape, so OCR could try to find + // line terminations and start from there. (I don't think they're that advanced yet..) + for($j=1 ; $j<$this->rand_func(5,10) ; $j++) + { + $points[] = $this->rand_func(1*(20*($i+1)),1*(50*($i+1))); + $points[] = $this->rand_func(30,$height+30); + } + + ImagePolygon($temp_bg,$points,intval(sizeof($points)/2),$text_colour3); + } + + } else if($this->bg_type==3) { + // take random chunks of $this->bg_images and paste them onto the background + + for($i=0 ; $i<sizeof($this->bg_images) ; $i++) + { + // read each image and its size + $temp_im[$i] = ImageCreateFromJPEG($this->bg_images[$i]); + $temp_width[$i] = imagesx($temp_im[$i]); + $temp_height[$i] = imagesy($temp_im[$i]); + } + + $blocksize = $this->rand_func(20,60); + for($i=0 ; $i<$width*2 ; $i+=$blocksize) + { + // could randomise blocksize here... hardly matters + for($j=0 ; $j<$height*2 ; $j+=$blocksize) + { + $this->image_index = $this->rand_func(0,sizeof($temp_im)-1); + $cut_x = $this->rand_func(0,$temp_width[$this->image_index]-$blocksize); + $cut_y = $this->rand_func(0,$temp_height[$this->image_index]-$blocksize); + ImageCopy($temp_bg, $temp_im[$this->image_index], $i, $j, $cut_x, $cut_y, $blocksize, $blocksize); + } + } + for($i=0 ; $i<sizeof($temp_im) ; $i++) + { + // remove bgs from memory + ImageDestroy($temp_im[$i]); + } + + // for debug: + //sendImage($temp_bg); + } + + // for debug: + //sendImage($this->im3); + + if($this->morph_bg) + { + // morph background + // we do this separately to the main text morph because: + // a) the main text morph is done char-by-char, this is done across whole image + // b) if an attacker could un-morph the bg, it would un-morph the CAPTCHA + // hence bg is morphed differently to text + // why do we morph it at all? it might make it harder for an attacker to remove the background + // morph_chunk 1 looks better but takes longer + + // this is a different and less perfect morph than the one we do on the CAPTCHA + // occasonally you get some dark background showing through around the edges + // it doesn't need to be perfect as it's only the bg. + $morph_chunk = $this->rand_func(1,5); + $morph_y = 0; + for($x=0 ; $x<$width ; $x+=$morph_chunk) + { + $morph_chunk = $this->rand_func(1,5); + $morph_y += $this->rand_func(-1,1); + ImageCopy($this->im3, $temp_bg, $x, 0, $x+30, 30+$morph_y, $morph_chunk, $height*2); + } + + ImageCopy($temp_bg, $this->im3, 0, 0, 0, 0, $width, $height); + + $morph_x = 0; + for($y=0 ; $y<=$height; $y+=$morph_chunk) + { + $morph_chunk = $this->rand_func(1,5); + $morph_x += $this->rand_func(-1,1); + ImageCopy($this->im3, $temp_bg, $morph_x, $y, 0, $y, $width, $morph_chunk); + + } + } else { + // just copy temp_bg onto im3 + ImageCopy($this->im3,$temp_bg,0,0,30,30,$width,$height); + } + + ImageDestroy($temp_bg); + + if($this->blur_bg) + { + $this->myImageBlur($this->im3); + } + } + // for debug: + //sendImage($this->im3); + + ////////////////////////////////////////////////////// + ////// Write Word + ////////////////////////////////////////////////////// + + // write word in random starting X position + $word_start_x = $this->rand_func(5,32); + // y positions jiggled about later + $word_start_y = 50; + + // use last pixelwidth + $font_pixelwidth = $this->font_size + 10; + + if($this->col_type==0) + { + $text_r = $this->rand_color(); + $text_g = $this->rand_color(); + $text_b = $this->rand_color(); + $text_colour2 = ImageColorAllocate($this->im2, $text_r, $text_g, $text_b); + } + + // write each char in different font + for($i=0 ; $i<strlen($word) ; $i++) + { + if($this->col_type==1) + { + $text_r = $this->rand_color(); + $text_g = $this->rand_color(); + $text_b = $this->rand_color(); + $text_colour2 = ImageColorAllocate($this->im2, $text_r, $text_g, $text_b); + } + + $j = $this->rand_func(0,sizeof($this->font_locations)-1); + // $font = ImageLoadFont($this->font_locations[$j]); + // ImageString($this->im2, $font, $word_start_x+($font_widths[$j]*$i), $word_start_y, $word{$i}, $text_colour2); + ImageTTFText($this->im2, $this->font_size, 0, $word_start_x+(($font_pixelwidth)*$i), $word_start_y, $text_colour2, $this->font_locations[$j], $word{$i}); + } + + // for debug: + // $this->sendImage($this->im2); + + ////////////////////////////////////////////////////// + ////// Morph Image: + ////////////////////////////////////////////////////// + + // calculate how big the text is in pixels + // (so we only morph what we need to) + $word_pix_size = $word_start_x+(strlen($word)*$font_pixelwidth); + + // firstly move each character up or down a bit: + $y_pos = 0; + for($i=$word_start_x ; $i<$word_pix_size ; $i+=$font_pixelwidth) + { + // move on Y axis + // deviates at least 4 pixels between each letter + $prev_y = $y_pos; + do{ + $y_pos = $this->rand_func(-5,5); + } while($y_pos<$prev_y+2 && $y_pos>$prev_y-2); + ImageCopy($this->im, $this->im2, $i, $y_pos, $i, 0, $font_pixelwidth, $height); + + // for debug: + // ImageRectangle($this->im,$i,$y_pos+10,$i+$font_pixelwidth,$y_pos+70,$debug); + } + + // for debug: + // $this->sendImage($this->im); + + ImageFilledRectangle($this->im2,0,0,$width,$height,$bg2); + + // randomly morph each character individually on x-axis + // this is where the main distortion happens + // massively improved since v1.2 + $y_chunk = 1; + $morph_factor = 1; + $morph_x = 0; + for($j=0 ; $j<strlen($word) ; $j++) + { + $y_pos = 0; + for($i=0 ; $i<=$height; $i+=$y_chunk) + { + $orig_x = $word_start_x+($j*$font_pixelwidth); + // morph x += so that instead of deviating from orig x each time, we deviate from where we last deviated to + // get it? instead of a zig zag, we get more of a sine wave. + // I wish we could deviate more but it looks crap if we do. + $morph_x += $this->rand_func(-$morph_factor,$morph_factor); + // had to change this to ImageCopyMerge when starting using ImageCreateTrueColor + // according to the manual; "when (pct is) 100 this function behaves identically to imagecopy()" + // but this is NOT true when dealing with transparencies... + ImageCopyMerge($this->im2, $this->im, $orig_x+$morph_x, $i+$y_pos, $orig_x, $i, $font_pixelwidth, $y_chunk, 100); + + // for debug: + //ImageLine($this->im2, $orig_x+$morph_x, $i, $orig_x+$morph_x+1, $i+$y_chunk, $debug2); + //ImageLine($this->im2, $orig_x+$morph_x+$font_pixelwidth, $i, $orig_x+$morph_x+$font_pixelwidth+1, $i+$y_chunk, $debug2); + } + } + + // for debug: + //sendImage($this->im2); + + ImageFilledRectangle($this->im,0,0,$width,$height,$bg); + // now do the same on the y-axis + // (much easier because we can just do it across the whole image, don't have to do it char-by-char) + $y_pos = 0; + $x_chunk = 1; + for($i=0 ; $i<=$width ; $i+=$x_chunk) + { + // can result in image going too far off on Y-axis; + // not much I can do about that, apart from make image bigger + // again, I wish I could do 1.5 pixels + $y_pos += $this->rand_func(-1,1); + ImageCopy($this->im, $this->im2, $i, $y_pos, $i, 0, $x_chunk, $height); + + // for debug: + //ImageLine($this->im,$i+$x_chunk,0,$i+$x_chunk,100,$debug); + //ImageLine($this->im,$i,$y_pos+25,$i+$x_chunk,$y_pos+25,$debug); + } + + // for debug: + //sendImage($this->im); + + // blur edges: + // doesn't really add any security, but looks a lot nicer, and renders text a little easier to read + // for humans (hopefully not for OCRs, but if you know better, feel free to disable this function) + // (and if you do, let me know why) + $this->myImageBlur($this->im); + + // for debug: + //sendImage($this->im); + + if($this->output!="jpg" && $this->bg_type==0) + { + // make background transparent + ImageColorTransparent($this->im,$bg); + } + + + + + + ////////////////////////////////////////////////////// + ////// Try to avoid 'free p*rn' style CAPTCHA re-use + ////////////////////////////////////////////////////// + // ('*'ed to stop my site coming up for certain keyword searches on google) + + // can obscure CAPTCHA word in some cases.. + + // write site tags 'shining through' the morphed image + ImageFilledRectangle($this->im2,0,0,$width,$height,$bg2); + if(is_array($this->site_tags)) + { + for($i=0 ; $i<sizeof($this->site_tags) ; $i++) + { + // ensure tags are centered + $tag_width = strlen($this->site_tags[$i])*6; + // write tag is chosen position + if($this->tag_pos==0 || $this->tag_pos==2) + { + // write at top + ImageString($this->im2, 2, intval($width/2)-intval($tag_width/2), (10*$i), $this->site_tags[$i], $site_tag_col2); + } + if($this->tag_pos==1 || $this->tag_pos==2) + { + // write at bottom + ImageString($this->im2, 2, intval($width/2)-intval($tag_width/2), ($height-34+($i*10)), $this->site_tags[$i], $site_tag_col2); + } + } + } + ImageCopyMerge($this->im2,$this->im,0,0,0,0,$width,$height,80); + ImageCopy($this->im,$this->im2,0,0,0,0,$width,$height); + // for debug: + //sendImage($this->im); + + + + + ////////////////////////////////////////////////////// + ////// Merge with obfuscated background + ////////////////////////////////////////////////////// + + if($this->bg_type!=0) + { + // merge bg image with CAPTCHA image to create smooth background + + // fade bg: + if($this->bg_type!=3) + { + $temp_im = ImageCreateTrueColor($width,$height); + $white = ImageColorAllocate($temp_im,255,255,255); + ImageFill($temp_im,0,0,$white); + ImageCopyMerge($this->im3,$temp_im,0,0,0,0,$width,$height,$bg_fade_pct); + // for debug: + //sendImage($this->im3); + ImageDestroy($temp_im); + $c_fade_pct = 50; + } else { + $c_fade_pct = $bg_fade_pct; + } + + // captcha over bg: + // might want to not blur if using this method + // otherwise leaves white-ish border around each letter + if($this->merge_type==1) + { + ImageCopyMerge($this->im3,$this->im,0,0,0,0,$width,$height,100); + ImageCopy($this->im,$this->im3,0,0,0,0,$width,$height); + } else { + // bg over captcha: + ImageCopyMerge($this->im,$this->im3,0,0,0,0,$width,$height,$c_fade_pct); + } + } + // for debug: + //sendImage($this->im); + + + ////////////////////////////////////////////////////// + ////// Write tags, remove variables and output! + ////////////////////////////////////////////////////// + + // tag it + // feel free to remove/change + // but if it's not essential I'd appreciate you leaving it + // after all, I've put a lot of work into this and am giving it away for free + // the least you could do is give me credit (or buy me stuff from amazon!) + // but I understand that in professional environments, your boss might not like this tag + // so that's cool. + $tag_str = ""; + // for debug: + //$tag_str = "[".$word."]"; + + // ensure tag is right-aligned + $tag_width = strlen($tag_str)*6; + // write tag + ImageString($this->im, 2, $width-$tag_width, $height-13, $tag_str, $tag_col); + + // unset all sensetive vars + // in case someone include()s this file on a shared server + // you might think this unneccessary, as it exit()s + // but by using register_shutdown_function + // on a -very- insecure shared server, they -might- be able to get the word + unset($word); + // the below aren't really essential, but might aid an OCR attack if discovered. + // so we unset them + + // output final image :-) + $this->sendImage($this->im); + // (sendImage also destroys all used images) + } + + function rand_func($s, $m) + { + global $_starttime; + $tn = microtime_float() - $_starttime; + if ( $tn > 5 ) + { + echo '<pre>'; + enano_debug_print_backtrace(); + echo '</pre>'; + exit; + } + $rf =& $this->rand_func; + return $rf($s, $m); + } + + function seed_func($s) + { + $rf =& $this->seed_func; + return $rf($s); + } + + function hash_func($s) + { + $rf =& $this->hash_func; + return $rf($s); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/engine_potpourri.php Wed Feb 06 18:41:47 2008 -0500 @@ -0,0 +1,332 @@ +<?php + +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 (Caoineag alpha 1) + * Copyright (C) 2006-2007 Dan Fuhry + * captcha.php - visual confirmation system used during registration + * + * This program is Free Software; you can redistribute 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 details. + */ + +/** + * A more complex captcha engine that relies on GD. + * @package Enano + * @subpackage User management + * @copyright 2007-2008 Dan Fuhry + * @copyright 2002-2008 phpBB Group + */ + +class captcha_engine_potpourri extends captcha_base +{ + var $captcha_config; + + function __construct($sid, $r = false) + { + parent::__construct($sid, $r); + + $hex = Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + $latticecolor = '#'; + for ( $i = 0; $i < 6; $i++ ) + $latticecolor .= $hex[mt_rand(0, 15)]; + + $this->captcha_config = array ( + 'width' => '350', + 'height' => '90', + 'background_color' => '#E5ECF9', + 'jpeg' => '0', + 'jpeg_quality' => '95', + 'pre_letters' => '1', + 'pre_letters_great' => '0', + 'font' => '1', + 'chess' => '2', + 'ellipses' => '2', + 'arcs' => '2', + 'lines' => '2', + 'image' => '0', + 'gammacorrect' => '0.8', + 'foreground_lattice_x' => (string)mt_rand(25, 30), + 'foreground_lattice_y' => (string)mt_rand(25, 30), + 'lattice_color' => $latticecolor, + ); + } + + function make_image() + { + $code = $this->get_code(); + + // Prefs + $total_width = $this->captcha_config['width']; + $total_height = $this->captcha_config['height']; + + $hex_bg_color = $this->get_rgb($this->captcha_config['background_color']); + $bg_color = array(); + $bg_color = explode(",", $hex_bg_color); + + $jpeg = $this->captcha_config['jpeg']; + $img_quality = $this->captcha_config['jpeg_quality']; + // Max quality is 95 + + $pre_letters = $this->captcha_config['pre_letters']; + $pre_letter_great = $this->captcha_config['pre_letters_great']; + $rnd_font = $this->captcha_config['font']; + $chess = $this->captcha_config['chess']; + $ellipses = $this->captcha_config['ellipses']; + $arcs = $this->captcha_config['arcs']; + $lines = $this->captcha_config['lines']; + $image = $this->captcha_config['image']; + + $gammacorrect = $this->captcha_config['gammacorrect']; + + $foreground_lattice_y = $this->captcha_config['foreground_lattice_y']; + $foreground_lattice_x = $this->captcha_config['foreground_lattice_x']; + $hex_lattice_color = $this->get_rgb($this->captcha_config['lattice_color']); + $rgb_lattice_color = array(); + $rgb_lattice_color = explode(",", $hex_lattice_color); + + $font_debug = false; + + // Fonts and images init + if ($image) + { + $bg_imgs = array(); + if ($img_dir = opendir(ENANO_ROOT.'/includes/captcha/pics/')) + { + while (true == ($file = @readdir($img_dir))) + { + if ((substr(strtolower($file), -3) == 'jpg') || (substr(strtolower($file), -3) == 'gif')) + { + $bg_imgs[] = $file; + } + } + closedir($img_dir); + } + // Grab a random Background Image or set FALSE if none was found + $bg_img = ( count($bg_imgs) ) ? rand(0, (count($bg_imgs)-1)) : false; + } + + $fonts = array(); + if ($fonts_dir = opendir(ENANO_ROOT . '/includes/captcha/fonts/')) + { + while (true == ($file = @readdir($fonts_dir))) + { + if ((substr(strtolower($file), strlen($file)-3, strlen($file)) == 'ttf')) + { + $fonts[] = $file; + } + } + closedir($fonts_dir); + } else { + die('Error reading directory: '.ENANO_ROOT.'/includes/captcha/fonts/'); + } + $font = mt_rand(0, (count($fonts)-1)); + + // Generate + $image = ($this->gdVersion() >= 2) ? imagecreatetruecolor($total_width, $total_height) : imagecreate($total_width, $total_height); + $background_color = imagecolorallocate($image, $bg_color[0], $bg_color[1], $bg_color[2]); + imagefill($image, 0, 0, $background_color); + + // Generate backgrund + if ($chess == '1' || $chess == '2' && rand(0,1)) + { + // Draw rectangles + for($i = 0; $i <= 8; $i++) + { + $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); + imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height), $rectanglecolor); + $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); + imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height/2), $rectanglecolor); + } + } + if ($ellipses == '1' || $ellipses == '2' && rand(0,1)) + { + // Draw random ellipses + for ($i = 1; $i <= 60; $i++) + { + $ellipsecolor = imagecolorallocate($image, rand(100,250),rand(100,250),rand(100,250)); + imagefilledellipse($image, round(rand(0, $total_width)), round(rand(0, $total_height)), round(rand(0, $total_width/8)), round(rand(0, $total_height/4)), $ellipsecolor); + } + } + if ($arcs == '1' || $arcs == '2' && rand(0,1)) + { + // Draw random partial ellipses + for ($i = 0; $i <= 30; $i++) + { + $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); + $cx = round(rand(1, $total_width)); + $cy = round(rand(1, $total_height)); + $int_w = round(rand(1, $total_width/2)); + $int_h = round(rand(1, $total_height)); + imagearc($image, $cx, $cy, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); + imagearc($image, $cx-1, $cy-1, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); + } + } + if ($lines == '1' || $lines == '2' && rand(0,1)) + { + // Draw random lines + for ($i = 0; $i <= 50; $i++) + { + $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); + imageline($image, round(rand(1, $total_width*3)), round(rand(1, $total_height*5)), round(rand(1, $total_width/2)), round(rand(1, $total_height*2)), $linecolor); + } + } + + $text_color_array = array('255,51,0', '51,77,255', '204,51,102', '0,153,0', '255,166,2', '255,0,255', '255,0,0', '0,255,0', '0,0,255', '0,255,255'); + shuffle($text_color_array); + $pre_text_color_array = array('255,71,20', '71,20,224', '224,71,122', '20,173,20', '255,186,22', '25,25,25'); + shuffle($pre_text_color_array); + $white = imagecolorallocate($image, 255, 255, 255); + $gray = imagecolorallocate($image, 100, 100, 100); + $black = imagecolorallocate($image, 0, 0, 0); + $lattice_color = imagecolorallocate($image, $rgb_lattice_color[0], $rgb_lattice_color[1], $rgb_lattice_color[2]); + + $x_char_position = (round(($total_width - 12) / strlen($code)) + mt_rand(-3, 5)); + + for ($i = 0; $i < strlen($code); $i++) + { + mt_srand((double)microtime()*1000000); + + $char = $code{$i}; + $size = mt_rand(floor($total_height / 3.5), ceil($total_height / 2.8)); + $font = ($rnd_font) ? rand(0, (count($fonts)-1)) : $font; + $angle = mt_rand(-30, 30); + + $char_pos = array(); + $char_pos = imagettfbbox($size, $angle, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + $letter_width = abs($char_pos[0]) + abs($char_pos[4]); + $letter_height = abs($char_pos[1]) + abs($char_pos[5]); + + $x_pos = ($x_char_position / 4) + ($i * $x_char_position); + ($i == strlen($code)-1 && $x_pos >= ($total_width - ($letter_width + 5))) ? $x_pos = ($total_width - ($letter_width + 5)) : ''; + $y_pos = mt_rand(($size * 1.4 ), $total_height - ($size * 0.4)); + + // Pre letters + $size = ($pre_letter_great) ? $size + (2 * $pre_letters) : $size - (2 * $pre_letters); + for ($count = 1; $count <= $pre_letters; $count++) + { + $pre_angle = $angle + mt_rand(-20, 20); + + $text_color = $pre_text_color_array[mt_rand(0,count($pre_text_color_array)-1)]; + $text_color = explode(",", $text_color); + $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); + + imagettftext($image, $size, $pre_angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $pre_angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $pre_angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + + $size = ($pre_letter_great) ? $size - 2 : $size + 2; + } + + // Final letters + $text_color = $text_color_array[mt_rand(0,count($text_color_array)-1)]; + $text_color = explode(",", $text_color); + $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); + + imagettftext($image, $size, $angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + } + + + ($gammacorrect) ? imagegammacorrect($image, 1.0, $gammacorrect) : ''; + + // Generate a white lattice in foreground + if ($foreground_lattice_y) + { + // x lines + $ih = round($total_height / $foreground_lattice_y); + for ($i = 0; $i <= $ih; $i++) + { + imageline($image, 0, $i*$foreground_lattice_y, $total_width, $i*$foreground_lattice_y, $lattice_color); + } + } + if ($foreground_lattice_x) + { + // y lines + $iw = round($total_width / $foreground_lattice_x); + for ($i = 0; $i <= $iw; $i++) + { + imageline($image, $i*$foreground_lattice_x, 0, $i*$foreground_lattice_x, $total_height, $lattice_color); + } + } + + // Font debug + if ($font_debug && !$rnd_font) + { + imagestring($image, 5, 2, 0, $fonts[$font], $white); + imagestring($image, 5, 5, 0, $fonts[$font], $white); + imagestring($image, 5, 4, 2, $fonts[$font], $gray); + imagestring($image, 5, 3, 1, $fonts[$font], $black); + } + + // Display + header("Last-Modified: " . gmdate("D, d M Y H:i:s") ." GMT"); + header("Pragma: no-cache"); + header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate"); + (!$jpeg) ? header("Content-Type: image/png") : header("Content-Type: image/jpeg"); + + (!$jpeg) ? imagepng($image) : imagejpeg($image, '', $img_quality); + imagedestroy($image); + } + + // Function get_rgb by Frank Burian + // http://www.phpfuncs.org/?content=show&id=46 + function get_rgb($hex) { + $hex_array = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, + 'F' => 15); + $hex = str_replace('#', '', strtoupper($hex)); + if (($length = strlen($hex)) == 3) { + $hex = $hex{0}.$hex{0}.$hex{1}.$hex{1}.$hex{2}.$hex{2}; + $length = 6; + } + if ($length != 6 or strlen(str_replace(array_keys($hex_array), '', $hex))) + return NULL; + $rgb['r'] = $hex_array[$hex{0}] * 16 + $hex_array[$hex{1}]; + $rgb['g'] = $hex_array[$hex{2}] * 16 + $hex_array[$hex{3}]; + $rgb['b']= $hex_array[$hex{4}] * 16 + $hex_array[$hex{5}]; + return $rgb['r'].','.$rgb['g'].','.$rgb['b']; + } + + // Function gdVersion by Hagan Fox + // http://de3.php.net/manual/en/function.gd-info.php#52481 + function gdVersion($user_ver = 0) + { + if (! extension_loaded('gd')) { return; } + static $gd_ver = 0; + // Just accept the specified setting if it's 1. + if ($user_ver == 1) { $gd_ver = 1; return 1; } + // Use the static variable if function was called previously. + if ($user_ver !=2 && $gd_ver > 0 ) { return $gd_ver; } + // Use the gd_info() function if possible. + if (function_exists('gd_info')) { + $ver_info = gd_info(); + preg_match('/\d/', $ver_info['GD Version'], $match); + $gd_ver = $match[0]; + return $match[0]; + } + // If phpinfo() is disabled use a specified / fail-safe choice... + if (preg_match('/phpinfo/', ini_get('disable_functions'))) { + if ($user_ver == 2) { + $gd_ver = 2; + return 2; + } else { + $gd_ver = 1; + return 1; + } + } + // ...otherwise use phpinfo(). + ob_start(); + phpinfo(8); + $info = ob_get_contents(); + ob_end_clean(); + $info = stristr($info, 'gd version'); + preg_match('/\d/', $info, $match); + $gd_ver = $match[0]; + return $match[0]; + } +}
--- a/includes/pageutils.php Mon Feb 04 05:52:12 2008 -0500 +++ b/includes/pageutils.php Wed Feb 06 18:41:47 2008 -0500 @@ -402,7 +402,7 @@ if($ticker < $numrows) echo '<td class="' . $cls . '" style="padding: 0;"><input ' . $s2 . 'name="diff2" type="radio" value="' . $r['time_id'] . '" id="diff2_' . $r['time_id'] . '" class="clsDiff2Radio" onclick="selectDiff2Button(this);" /></td>'."\n"; else echo '<td class="' . $cls . '"></td>'; // Date and time - echo '<td class="' . $cls . '">' . enano_date('d M Y h:i a', intval($r['time_id'])) . '</td class="' . $cls . '">'."\n"; + echo '<td class="' . $cls . '" style="white-space: nowrap;">' . enano_date('d M Y h:i a', intval($r['time_id'])) . '</td class="' . $cls . '">'."\n"; // User if ( $session->get_permissions('mod_misc') && is_valid_ip($r['author']) )
--- a/includes/sessions.php Mon Feb 04 05:52:12 2008 -0500 +++ b/includes/sessions.php Wed Feb 06 18:41:47 2008 -0500 @@ -1793,7 +1793,6 @@ list($user_id) = $db->fetchrow_num(); $db->free_result(); - $user_id =& $row['user_id']; $this->sql('INSERT INTO '.table_prefix.'users_extra(user_id) VALUES(' . $user_id . ');'); } @@ -2744,27 +2743,75 @@ function make_captcha($len = 7) { + global $db, $session, $paths, $template, $plugins; // Common objects $code = $this->generate_captcha_code($len); $hash = md5(microtime() . mt_rand()); - $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key,salt,auth_level,source_ip,user_id) VALUES(\''.$hash.'\', \'\', -1, \''.ip2hex($_SERVER['REMOTE_ADDR']).'\', -2);'); + $session_data = $db->escape(serialize(array())); + + // sanity check + if ( !is_valid_ip(@$_SERVER['REMOTE_ADDR']) || !is_int($this->user_id) ) + return false; + + $this->sql('INSERT INTO '.table_prefix.'captcha(session_id, code, session_data, source_ip, user_id)' . " VALUES('$hash', '$code', '$session_data', '{$_SERVER['REMOTE_ADDR']}', {$this->user_id});"); return $hash; } /** - * Generates the actual confirmation code text. - * @param int String length + * Generates a "pronouncable" or "human-friendly" word using various phonics rules + * @param int Optional. The length of the word. * @return string */ function generate_captcha_code($len = 7) { - $chars = array('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', '1', '2', '3', '4', '5', '6', '7', '8', '9'); - $s = ''; + // don't use k and x, they get mixed up a lot + $consonants = 'bcdfghmnpqrsvwyz'; + $vowels = 'aeiou'; + $prev = 'vowel'; + $prev_l = ''; + $word = ''; + $allow_next_vowel = true; for ( $i = 0; $i < $len; $i++ ) { - $s .= $chars[mt_rand(0, count($chars)-1)]; + if ( $prev == 'vowel' ) + { + $allow_next_vowel = false; + if ( $prev_l == 'o' && mt_rand(0, 3) == 3 && $allow_next_vowel ) + $word .= 'i'; + else if ( $prev_l == 'q' && mt_rand(0, 3) != 1 && $allow_next_vowel ) + $word .= 'u'; + else if ( $prev_l == 'o' && mt_rand(0, 3) == 2 && $allow_next_vowel ) + $word .= 'u'; + else if ( $prev_l == 'a' && mt_rand(0, 3) == 3 && $allow_next_vowel ) + $word .= 'i'; + else if ( $prev_l == 'a' && mt_rand(0, 10) == 7 && $allow_next_vowel ) + $word .= 'o'; + else if ( $prev_l == 'a' && mt_rand(0, 7) == 2 && $allow_next_vowel ) + $word .= 'u'; + else + { + $allow_next_vowel = true; + $word .= $consonants{mt_rand(0, (strlen($consonants)-1))}; + } + } + else if ( $prev == 'consonant' ) + { + if ( $prev_l == 'p' && mt_rand(0, 7) == 4 ) + $word .= 't'; + else if ( $prev_l == 'p' && mt_rand(0, 5) == 1 ) + $word .= 'h'; + else + $word .= $vowels{mt_rand(0, (strlen($vowels)-1))}; + } + $prev_l = substr($word, -1); + $l = ( mt_rand(0, 1) == 1 ) ? strtoupper($prev_l) : strtolower($prev_l); + $word = substr($word, 0, -1) . $l; + if ( strstr('aeiou', $prev_l) ) + $prev = 'vowel'; + else + $prev = 'consonant'; } - return $s; + return $word; } /** @@ -2776,15 +2823,20 @@ function get_captcha($hash) { global $db, $session, $paths, $template, $plugins; // Common objects - $s = $this->sql('SELECT salt FROM '.table_prefix.'session_keys WHERE session_key=\''.$db->escape($hash).'\' AND source_ip=\''.ip2hex($_SERVER['REMOTE_ADDR']).'\';'); - if ( $db->numrows() < 1 ) + + if ( !preg_match('/^[a-f0-9]{32}([a-z0-9]{8})?$/', $hash) ) { return false; } - $r = $db->fetchrow(); + + $q = $this->sql('SELECT code_id, code FROM ' . table_prefix . "captcha WHERE session_id = '$hash';"); + if ( $db->numrows() < 1 ) + return false; + + list($code_id, $code) = $db->fetchrow_num(); $db->free_result(); - $this->sql('DELETE FROM ' . table_prefix . 'session_keys WHERE salt=\'' . $db->escape($r['salt']) . '\';'); - return $r['salt']; + $this->sql('DELETE FROM ' . table_prefix . "captcha WHERE code_id = $code_id;"); + return $code; } /** @@ -2793,7 +2845,6 @@ function kill_captcha() { - // $this->sql('DELETE FROM '.table_prefix.'session_keys WHERE user_id=-2 AND source_ip=\''.ip2hex($_SERVER['REMOTE_ADDR']).'\';'); return true; }
--- a/install/schemas/mysql_stage2.sql Mon Feb 04 05:52:12 2008 -0500 +++ b/install/schemas/mysql_stage2.sql Wed Feb 06 18:41:47 2008 -0500 @@ -105,6 +105,7 @@ user_has_avatar tinyint(1) NOT NULL DEFAULT 0, avatar_type ENUM('jpg', 'png', 'gif') NOT NULL DEFAULT 'png', user_registration_ip varchar(39), + user_rank int(12) UNSIGNED NOT NULL DEFAULT 1, PRIMARY KEY (user_id) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; @@ -255,7 +256,7 @@ action ENUM('credential', 'level') NOT NULL DEFAULT 'credential', timestamp int(12) NOT NULL DEFAULT 0, PRIMARY KEY ( id ) -) CHARACTER SET `utf8`; +) CHARACTER SET `utf8` COLLATE `utf8_bin`; -- Added in 1.1.1 @@ -266,7 +267,7 @@ lang_name_native varchar(64) NOT NULL, last_changed int(12) NOT NULL DEFAULT 0, PRIMARY KEY ( lang_id ) -) CHARACTER SET `utf8`; +) CHARACTER SET `utf8` COLLATE `utf8_bin`; -- Added in 1.1.1 @@ -277,7 +278,28 @@ string_name varchar(64) NOT NULL, string_content longtext NOT NULL, PRIMARY KEY ( string_id ) -); +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}ranks( + rank_id int(12) NOT NULL auto_increment, + rank_title varchar(63) NOT NULL DEFAULT '', + rank_style varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY ( rank_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}captcha( + code_id int(12) NOT NULL auto_increment, + session_id varchar(40) NOT NULL DEFAULT '', + code varchar(64) NOT NULL DEFAULT '', + session_data text, + source_ip varchar(39), + user_id int(12), + PRIMARY KEY ( code_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; INSERT INTO {{TABLE_PREFIX}}config(config_name, config_value) VALUES ('site_name', '{{SITE_NAME}}'), @@ -326,6 +348,11 @@ INSERT INTO {{TABLE_PREFIX}}users_extra(user_id) VALUES (2); + +INSERT INTO {{TABLE_PREFIX}}ranks(rank_id, rank_title, rank_style) VALUES + (1, 'user_rank_member', ''), + (2, 'user_rank_mod', 'font-weight: bold; color: #00AA00;'), + (3, 'user_rank_admin', 'font-weight: bold; color: #AA0000;'); INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type,system_group) VALUES(1, 'Everyone', 3, 1), (2,'Administrators',3,1),
--- a/install/schemas/postgresql_stage2.sql Mon Feb 04 05:52:12 2008 -0500 +++ b/install/schemas/postgresql_stage2.sql Wed Feb 06 18:41:47 2008 -0500 @@ -104,6 +104,7 @@ user_has_avatar smallint NOT NULL, avatar_type varchar(3) NOT NULL, user_registration_ip varchar(39), + user_rank int NOT NULL DEFAULT 1, CHECK (avatar_type IN ('jpg', 'png', 'gif')), PRIMARY KEY (user_id) ); @@ -277,6 +278,25 @@ string_content text NOT NULL ); +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}ranks( + rank_id SERIAL, + rank_title varchar(63) NOT NULL DEFAULT '', + rank_style varchar(255) NOT NULL DEFAULT '' +); + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}captcha( + code_id SERIAL, + session_id varchar(40) NOT NULL DEFAULT '', + code varchar(64) NOT NULL DEFAULT '', + session_data text, + source_ip varchar(39), + user_id int +); + INSERT INTO {{TABLE_PREFIX}}config(config_name, config_value) VALUES ('site_name', '{{SITE_NAME}}'), ('main_page', 'Main_Page'), @@ -324,6 +344,11 @@ INSERT INTO {{TABLE_PREFIX}}users_extra(user_id) VALUES (2); + +INSERT INTO {{TABLE_PREFIX}}ranks(rank_id, rank_title, rank_style) VALUES + (1, 'user_rank_member', ''), + (2, 'user_rank_mod', 'font-weight: bold; color: #00AA00;'), + (3, 'user_rank_admin', 'font-weight: bold; color: #AA0000;'); INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type,system_group) VALUES(1, 'Everyone', 3, 1), (2,'Administrators',3,1),
--- a/plugins/SpecialUserFuncs.php Mon Feb 04 05:52:12 2008 -0500 +++ b/plugins/SpecialUserFuncs.php Wed Feb 06 18:41:47 2008 -0500 @@ -1319,37 +1319,21 @@ } $hash = $paths->getParam(0); - if ( !$hash || !preg_match('#^([0-9a-f]*){32,32}$#i', $hash) ) + if ( !$hash || !preg_match('#^([0-9a-f]*){32,40}$#i', $hash) ) { $paths->main_page(); } - // Determine code length - $ip = ip2hex($_SERVER['REMOTE_ADDR']); - if ( !$ip ) - die('(very desperate) Hacking attempt'); - $q = $db->sql_query('SELECT CHAR_LENGTH(salt) AS len FROM ' . table_prefix . 'session_keys WHERE session_key = \'' . $db->escape($hash) . '\' AND source_ip = \'' . $db->escape($ip) . '\';'); + $code = $session->generate_captcha_code(); + $q = $db->sql_query('UPDATE ' . table_prefix . "captcha SET code = '$code' WHERE session_id = '$hash';"); if ( !$q ) - $db->_die('SpecialUserFuncs selecting CAPTCHA code'); - if ( $db->numrows() < 1 ) - die('Invalid hash or hacking attempt by IP'); - - // Generate code - $row = $db->fetchrow(); - $db->free_result(); - $len = intval($row['len']); - if ( $len < 4 ) - $len = 7; - $code = $session->generate_captcha_code($len); - - // Update database with new code - $q = $db->sql_query('UPDATE ' . table_prefix . 'session_keys SET salt = \'' . $code . '\' WHERE session_key = \'' . $db->escape($hash) . '\' AND source_ip = \'' . $db->escape($ip) . '\';'); - if ( !$q ) - $db->_die('SpecialUserFuncs generating new CAPTCHA confirmation code'); + $db->_die(); require ( ENANO_ROOT.'/includes/captcha.php' ); - $captcha = new captcha($code); + $captcha = captcha_object($hash, 'freecap'); + $captcha->debug = true; $captcha->make_image(); + exit; }