diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index e2a231207d673..e755493d711db 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -62,14 +62,19 @@ The following methods draw shapes onto the FrameBuffer. Fill the entire FrameBuffer with the specified color. -.. method:: FrameBuffer.pixel(x, y[, c]) +.. method:: FrameBuffer.pixel(x, y[, c, alpha=0xFF]) If *c* is not given, get the color value of the specified pixel. If *c* is given, set the specified pixel to the given color. -.. method:: FrameBuffer.hline(x, y, w, c) -.. method:: FrameBuffer.vline(x, y, h, c) -.. method:: FrameBuffer.line(x1, y1, x2, y2, c) + The optional *alpha* parameter is a value from 0 to 255 which + indicates the transparency to use when setting the pixel (0 is + completely transparent, 255 is completely opaque). The if not + specified, the pixel is drawn opaquely. + +.. method:: FrameBuffer.hline(x, y, w, c[, alpha=0xFF]) +.. method:: FrameBuffer.vline(x, y, h, c[, alpha=0xFF]) +.. method:: FrameBuffer.line(x1, y1, x2, y2, c[, alpha=0xFF]) Draw a line from a set of coordinates using the given color and a thickness of 1 pixel. The `line` method draws the line up to @@ -77,14 +82,22 @@ The following methods draw shapes onto the FrameBuffer. methods draw horizontal and vertical lines respectively up to a given length. -.. method:: FrameBuffer.rect(x, y, w, h, c[, f]) + The optional *alpha* parameter is a value from 0 to 255 which + indicates the transparency to use when drawing the line. The + default is 255 (completely opaque). + +.. method:: FrameBuffer.rect(x, y, w, h, c[, f, alpha=0xFF]) - Draw a rectangle at the given location, size and color. + Draw a rectangle at the given location, size, color and transparency. The optional *f* parameter can be set to ``True`` to fill the rectangle. Otherwise just a one pixel outline is drawn. -.. method:: FrameBuffer.ellipse(x, y, xr, yr, c[, f, m]) + The optional *alpha* parameter is a value from 0 to 255 which + indicates the transparency to use when drawing the rectangle. The + default is 255 (completely opaque). + +.. method:: FrameBuffer.ellipse(x, y, xr, yr, c[, f, m, alpha=0xFF]) Draw an ellipse at the given location. Radii *xr* and *yr* define the geometry; equal values cause a circle to be drawn. The *c* parameter @@ -98,7 +111,11 @@ The following methods draw shapes onto the FrameBuffer. to be drawn, with bit 0 specifying Q1, b1 Q2, b2 Q3 and b3 Q4. Quadrants are numbered counterclockwise with Q1 being top right. -.. method:: FrameBuffer.poly(x, y, coords, c[, f]) + The optional *alpha* parameter is a value from 0 to 255 which + indicates the transparency to use when drawing the ellipse. The + default is 255 (completely opaque). + +.. method:: FrameBuffer.poly(x, y, coords, c[, f, alpha=0xFF]) Given a list of coordinates, draw an arbitrary (convex or concave) closed polygon at the given x, y location using the given color. @@ -109,16 +126,23 @@ The following methods draw shapes onto the FrameBuffer. The optional *f* parameter can be set to ``True`` to fill the polygon. Otherwise just a one pixel outline is drawn. + The optional *alpha* parameter is a value from 0 to 255 which + indicates the transparency to use when drawing the polygon. The + default is 255 (completely opaque). + Drawing text ------------ -.. method:: FrameBuffer.text(s, x, y[, c]) +.. method:: FrameBuffer.text(s, x, y[, c, alpha=0xFF]) Write text to the FrameBuffer using the coordinates as the upper-left corner of the text. The color of the text can be defined by the optional argument but is otherwise a default value of 1. All characters have dimensions of 8x8 pixels and there is currently no way to change the font. + The optional *alpha* parameter is a value from 0 to 255 which + indicates the transparency to use when drawing the text. The + default is 255 (completely opaque). Other methods ------------- @@ -128,14 +152,9 @@ Other methods Shift the contents of the FrameBuffer by the given vector. This may leave a footprint of the previous colors in the FrameBuffer. -.. method:: FrameBuffer.blit(fbuf, x, y, key=-1, palette=None) +.. method:: FrameBuffer.blit(fbuf, x, y, key=-1, palette=None, alpha=0xFF) Draw another FrameBuffer on top of the current one at the given coordinates. - If *key* is specified then it should be a color integer and the - corresponding color will be considered transparent: all pixels with that - color value will not be drawn. (If the *palette* is specified then the *key* - is compared to the value from *palette*, not to the value directly from - *fbuf*.) *fbuf* can be another FrameBuffer instance, or a tuple or list of the form:: @@ -149,6 +168,12 @@ Other methods of the tuple/list are the same as the arguments to the constructor except that the *buffer* here can be read-only. + If *key* is specified then it should be a color integer and the + corresponding color will be considered transparent: all pixels with that + color value will not be drawn. (If the *palette* is specified then the *key* + is compared to the value from *palette*, not to the value directly from + *fbuf*.) + The *palette* argument enables blitting between FrameBuffers with differing formats. Typical usage is to render a monochrome or grayscale glyph/icon to a color display. The *palette* is a FrameBuffer instance whose format is @@ -160,6 +185,16 @@ Other methods current pixel will be that of that *palette* pixel whose x position is the color of the corresponding source pixel. + The *alpha* parameter is either a value from 0 to 255 which indicates the + transparency to use when overlaying the buffer, or is a monochrome or + grayscale mask buffer of the same size as the buffer being drawn, indicating + the transparency for each pixel. The mask buffer can either be another + FrameBuffer or a tuple as described above for the *fbuf* parameter. If both + *key* and *alpha* are used, any pixels of the *key* color will be transparent + and the *alpha* value will be ignored for those pixels. + + An alpha mask buffer cannot have the RGB565 pixel format. + Constants --------- @@ -192,7 +227,29 @@ Constants .. data:: framebuf.RGB565 - Red Green Blue (16-bit, 5+6+5) color format + Red Green Blue (16-bit, 5+6+5, native) color format in native byte-order. + +.. data:: framebuf.RGB565_BS + + Red Green Blue (16-bit, 5+6+5, non-native) color format. This format uses + color values supplied with a non-native bit-pattern (ie. instead of + ``rrrrrggggggbbbbb`` the values are byte-swapped ``gggbbbbbrrrrrggg`` where + the least-significant bits of the green channel occur first). This is a + legacy format to ease migration for the common case of systems which used + displays with an opposite byte-order to microcontroller. + +.. data:: framebuf.RGB565_LE + + Red Green Blue (16-bit, 5+6+5, little-endian) color format in little-endian + byte order. This defines a 16-bit format where the bytes are stored in + little-endian order. If the system is little-endian, this is the same as + ``RGB565``. + +.. data:: framebuf.RGB565_BE + + Red Green Blue (16-bit, 5+6+5, big-endian) color format in big-endian byte + order. This defines a 16-bit format where the bytes are stored in + big-endian order. If the system is big-endian, this is the same as ``RGB565``. .. data:: framebuf.GS2_HMSB @@ -205,3 +262,46 @@ Constants .. data:: framebuf.GS8 Grayscale (8-bit) color format + +.. data:: framebuf.ALPHA + + Whether or not the framebuf module was compiled with support for alpha + values. + + If this is False, all alpha parameters will be ignored, lines and + polygons will be rendered with non-anti-aliasing algorithms, and drawing + will be done full opaquely. In the ``framebuf.blit`` method a monochrome + buffer can be used as the *alpha* parameter to provide a binary mask (0 + is transparent, 1 is opaque), but other values are ignored or are errors. + + If this is True, alpha parameters will act as specified in the descriptions, + anti-aliased algorithms will be used for rendering lines and polygons, and + ``framebuf.blit`` can use grayscale masks. + + There is currently no support for rendering antialiased ellipses. + +.. note:: + In Micropython 1.26 and earlier, the RGB565 format did not need + to know aout the internal color channels within each 16-bit value. + As a result, it did not care about the byte-order of the values stored + as pixels. Many display devices use big-endian RGB565, and so code that + used them from little-endian microcontrollers would simply provide colors + as big-endian RGB565 values (ie. using ``0b00000000_11111000`` for red + instead of ``0b11111000_00000000``). + + The introduction of support for alpha blending means that the RGB565 format + is assuming native byte-order for the layout of color channels within the + 16-bits of a pixel. This breaks code that uses byte-swapped color values, + but it can be adapted either by: + + * using firmware compiled with alpha support disabled via the + ``MICROPY_PY_FRAMEBUF_ALPHA`` flag; or + + * replacing the use of ``RGB565`` format with the byte-swapped + ``RGB565_BS`` format; or + + * using ``RGB565_BE`` or ``RGB565_LE`` as appropriate for the target + hardware and change color values to use native byte-order. + + New code which needs to support buffers of a particular byte-order should + use the last option. diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c index 5fd7c6be3a456..9cc7364bf6dd7 100644 --- a/examples/natmod/framebuf/framebuf.c +++ b/examples/natmod/framebuf/framebuf.c @@ -1,5 +1,6 @@ #define MICROPY_PY_ARRAY (1) #define MICROPY_PY_FRAMEBUF (1) +#define MICROPY_PY_FRAMEBUF_ALPHA (1) #include "py/dynruntime.h" @@ -44,11 +45,15 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a mp_store_global(MP_QSTR_MVLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); mp_store_global(MP_QSTR_MONO_VLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); mp_store_global(MP_QSTR_RGB565, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565)); + mp_store_global(MP_QSTR_RGB565_BS, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565_BS)); + mp_store_global(MP_QSTR_RGB565_BE, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565_BE)); + mp_store_global(MP_QSTR_RGB565_LE, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565_LE)); mp_store_global(MP_QSTR_GS2_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS2_HMSB)); mp_store_global(MP_QSTR_GS4_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB)); mp_store_global(MP_QSTR_GS8, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS8)); mp_store_global(MP_QSTR_MONO_HLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB)); mp_store_global(MP_QSTR_MONO_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB)); + mp_store_global(MP_QSTR_ALPHA, MP_OBJ_NEW_SMALL_INT(MICROPY_PY_FRAMEBUF_ALPHA)); MP_DYNRUNTIME_INIT_EXIT } diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 593125aa16f91..a090c341de45d 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -57,13 +57,15 @@ typedef struct _mp_framebuf_p_t { } mp_framebuf_p_t; // constants for formats -#define FRAMEBUF_MVLSB (0) -#define FRAMEBUF_RGB565 (1) -#define FRAMEBUF_GS2_HMSB (5) -#define FRAMEBUF_GS4_HMSB (2) -#define FRAMEBUF_GS8 (6) -#define FRAMEBUF_MHLSB (3) -#define FRAMEBUF_MHMSB (4) +#define FRAMEBUF_MVLSB (0) +#define FRAMEBUF_RGB565 (1) +#define FRAMEBUF_RGB565_NN (7) +#define FRAMEBUF_RGB565_BS (8) +#define FRAMEBUF_GS2_HMSB (5) +#define FRAMEBUF_GS4_HMSB (2) +#define FRAMEBUF_GS8 (6) +#define FRAMEBUF_MHLSB (3) +#define FRAMEBUF_MHMSB (4) // Functions for MHLSB and MHMSB @@ -117,7 +119,10 @@ static void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigne } } -// Functions for RGB565 format +// Functions for RGB565 formats +// +// Internally we use 'native' and 'non-native' formats, and then expose those as big- or little- +// endian to Python as appropriate. static void rgb565_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { ((uint16_t *)fb->buf)[x + y * fb->stride] = col; @@ -137,6 +142,27 @@ static void rgb565_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsign } } +static void rgb565_non_native_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { + col = __builtin_bswap16(col); + ((uint16_t *)fb->buf)[x + y * fb->stride] = col; +} + +static uint32_t rgb565_non_native_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { + uint32_t col = ((uint16_t *)fb->buf)[x + y * fb->stride]; + return __builtin_bswap16(col); +} + +static void rgb565_non_native_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) { + col = __builtin_bswap16(col); + uint16_t *b = &((uint16_t *)fb->buf)[x + y * fb->stride]; + while (h--) { + for (unsigned int ww = w; ww; --ww) { + *b++ = col; + } + b += fb->stride - w; + } +} + // Functions for GS2_HMSB format static void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { @@ -234,6 +260,8 @@ static void gs8_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned static mp_framebuf_p_t formats[] = { [FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect}, [FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect}, + [FRAMEBUF_RGB565_BS] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect}, + [FRAMEBUF_RGB565_NN] = {rgb565_non_native_setpixel, rgb565_non_native_getpixel, rgb565_non_native_fill_rect}, [FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect}, [FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect}, [FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect}, @@ -241,13 +269,89 @@ static mp_framebuf_p_t formats[] = { [FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect}, }; -static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { +#if MICROPY_PY_FRAMEBUF_ALPHA + +#ifndef FRAMEBUF_GET_ALPHA_ARG +#define FRAMEBUF_GET_ALPHA_ARG(idx) ((n_args > idx) ? mp_obj_get_int(args_in[idx]) : 0xFF) +#endif // GET_ALPHA_ARG + +typedef struct __attribute__((packed)) rgb565 { + uint8_t b : 5; + uint8_t g : 6; + uint8_t r : 5; +} rgb565; +typedef union { + uint16_t u16; + rgb565 rgb; +} urgb565; + +static uint32_t alpha_mult(uint32_t c, uint32_t alpha) { + // Efficient, correct alpha multiplication following Van Aken. + // See https://arxiv.org/pdf/2202.02864 + c *= alpha; + c += 0x80U; + c += c >> 8; + return c >> 8; +} + +static uint32_t alpha_blend(uint32_t c1, uint32_t c2, uint32_t alpha) { + return alpha_mult(c1, 0xff - alpha) + alpha_mult(c2, alpha); +} + +static void setpixel(const mp_obj_framebuf_t *fb, mp_int_t x, mp_int_t y, uint32_t col, mp_int_t alpha) { + if (alpha <= 0) { + // nothing to do + return; + } else if (alpha < 0xff) { + uint16_t pix_col = formats[fb->format].getpixel(fb, x, y); + uint16_t col16 = col; + urgb565 pix_col_struct; + urgb565 col_struct; + switch (fb->format) { + case FRAMEBUF_RGB565: + case FRAMEBUF_RGB565_BS: + case FRAMEBUF_RGB565_NN: + if (fb->format == FRAMEBUF_RGB565_BS) { + // The colors are specified in non-native endianness in Python. + // We need to byteswap to get native endianness. + col16 = __builtin_bswap16(col); + pix_col = __builtin_bswap16(pix_col); + } + // convert to bit-packed rgb struct + pix_col_struct = *(urgb565 *)&pix_col; + col_struct = *(urgb565 *)&col16; + // blend channels + col_struct.rgb.r = alpha_blend(pix_col_struct.rgb.r, col_struct.rgb.r, alpha); + col_struct.rgb.g = alpha_blend(pix_col_struct.rgb.g, col_struct.rgb.g, alpha); + col_struct.rgb.b = alpha_blend(pix_col_struct.rgb.b, col_struct.rgb.b, alpha); + // convert back to int + col = *(uint16_t *)&col_struct; + if (fb->format == FRAMEBUF_RGB565_BS) { + // byteswap back to get non-native endianness for storage. + col = __builtin_bswap16(col); + } + break; + default: + col = alpha_blend(pix_col, col, alpha); + } + } + formats[fb->format].setpixel(fb, x, y, col); +} +#else // MICROPY_PY_FRAMEBUF_ALPHA + +#ifndef FRAMEBUF_GET_ALPHA_ARG +#define FRAMEBUF_GET_ALPHA_ARG(idx) (0xFF) +#endif // GET_ALPHA_ARG + +static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col, mp_int_t alpha) { + (void)alpha; formats[fb->format].setpixel(fb, x, y, col); } +#endif // MICROPY_PY_FRAMEBUF_ALPHA -static void setpixel_checked(const mp_obj_framebuf_t *fb, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask) { - if (mask && 0 <= x && x < fb->width && 0 <= y && y < fb->height) { - setpixel(fb, x, y, col); +static void setpixel_checked(const mp_obj_framebuf_t *fb, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask, mp_int_t alpha) { + if (mask && alpha > 0 && 0 <= x && x < fb->width && 0 <= y && y < fb->height) { + setpixel(fb, x, y, col, alpha); } } @@ -255,7 +359,33 @@ static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, uns return formats[fb->format].getpixel(fb, x, y); } -static void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { +#if MICROPY_PY_FRAMEBUF_ALPHA +static void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col, mp_int_t alpha) { + if (alpha == 0 || h < 1 || w < 1 || x + w <= 0 || y + h <= 0 || y >= fb->height || x >= fb->width) { + // No operation needed. + return; + } + + // clip to the framebuffer + int xend = MIN(fb->width, x + w); + int yend = MIN(fb->height, y + h); + x = MAX(x, 0); + y = MAX(y, 0); + + if (alpha >= 0xff) { + formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col); + } else { + for (; y < yend; ++y) { + for (int x0 = x; x0 < xend; ++x0) { + setpixel(fb, x0, y, col, alpha); + } + } + } +} +#else // MICROPY_PY_FRAMEBUF_ALPHA +static void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col, mp_int_t alpha) { + (void)alpha; + if (h < 1 || w < 1 || x + w <= 0 || y + h <= 0 || y >= fb->height || x >= fb->width) { // No operation needed. return; @@ -269,6 +399,7 @@ static void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, u formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col); } +#endif // MICROPY_PY_FRAMEBUF_ALPHA static mp_obj_t framebuf_make_new_helper(size_t n_args, const mp_obj_t *args_in, unsigned int buf_flags, mp_obj_framebuf_t *o) { @@ -310,6 +441,8 @@ static mp_obj_t framebuf_make_new_helper(size_t n_args, const mp_obj_t *args_in, bpp = 8; break; case FRAMEBUF_RGB565: + case FRAMEBUF_RGB565_BS: + case FRAMEBUF_RGB565_NN: bpp = 16; break; default: @@ -364,10 +497,10 @@ static mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); mp_int_t args[5]; // x, y, w, h, col framebuf_args(args_in, args, 5); - fill_rect(self, args[0], args[1], args[2], args[3], args[4]); + fill_rect(self, args[0], args[1], args[2], args[3], args[4], FRAMEBUF_GET_ALPHA_ARG(6)); return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 7, framebuf_fill_rect); static mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); @@ -379,12 +512,12 @@ static mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args_in) { return MP_OBJ_NEW_SMALL_INT(getpixel(self, x, y)); } else { // set - setpixel(self, x, y, mp_obj_get_int(args_in[3])); + setpixel(self, x, y, mp_obj_get_int(args_in[3]), FRAMEBUF_GET_ALPHA_ARG(4)); } } return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pixel); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 5, framebuf_pixel); static mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args_in) { (void)n_args; @@ -393,11 +526,11 @@ static mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args_in) { mp_int_t args[4]; // x, y, w, col framebuf_args(args_in, args, 4); - fill_rect(self, args[0], args[1], args[2], 1, args[3]); + fill_rect(self, args[0], args[1], args[2], 1, args[3], FRAMEBUF_GET_ALPHA_ARG(5)); return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hline); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 6, framebuf_hline); static mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args_in) { (void)n_args; @@ -406,29 +539,97 @@ static mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args_in) { mp_int_t args[4]; // x, y, h, col framebuf_args(args_in, args, 4); - fill_rect(self, args[0], args[1], 1, args[2], args[3]); + fill_rect(self, args[0], args[1], 1, args[2], args[3], FRAMEBUF_GET_ALPHA_ARG(5)); return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vline); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 6, framebuf_vline); static mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); mp_int_t args[5]; // x, y, w, h, col framebuf_args(args_in, args, 5); + mp_int_t alpha = FRAMEBUF_GET_ALPHA_ARG(7); if (n_args > 6 && mp_obj_is_true(args_in[6])) { - fill_rect(self, args[0], args[1], args[2], args[3], args[4]); + fill_rect(self, args[0], args[1], args[2], args[3], args[4], alpha); } else { - fill_rect(self, args[0], args[1], args[2], 1, args[4]); - fill_rect(self, args[0], args[1] + args[3] - 1, args[2], 1, args[4]); - fill_rect(self, args[0], args[1], 1, args[3], args[4]); - fill_rect(self, args[0] + args[2] - 1, args[1], 1, args[3], args[4]); + fill_rect(self, args[0], args[1], args[2], 1, args[4], alpha); + fill_rect(self, args[0], args[1] + args[3] - 1, args[2], 1, args[4], alpha); + fill_rect(self, args[0], args[1] + 1, 1, args[3] - 2, args[4], alpha); + fill_rect(self, args[0] + args[2] - 1, args[1] + 1, 1, args[3] - 2, args[4], alpha); } return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 7, framebuf_rect); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 8, framebuf_rect); + +#if MICROPY_PY_FRAMEBUF_ALPHA +static void line(const mp_obj_framebuf_t *fb, mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, mp_int_t col, mp_int_t alpha, bool draw_last) { + // This implements Wu's antialiased line algorithm in 8-bit fixed-point. + // See https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm + + setpixel_checked(fb, x1, y1, col, 1, alpha); + if (x1 == x2 && y1 == y2) { + // nothing more to do + return; + } + if (draw_last) { + setpixel_checked(fb, x2, y2, col, 1, alpha); + } + + mp_int_t dx = x2 - x1; + mp_int_t dy = y2 - y1; + if (dx + dy < 0) { + // swap ends + mp_int_t temp; + dx = -dx; + dy = -dy; + temp = x1; + x1 = x2; + x2 = temp; + temp = y1; + y1 = y2; + y2 = temp; + } + + bool steep; + if (dy > dx) { + // swap x and y + mp_int_t temp; + temp = x1; + x1 = y1; + y1 = temp; + temp = dx; + dx = dy; + dy = temp; + steep = true; + } else { + steep = false; + } + + // Fixed point with 12 bits of fractional part. + // dx != 0 is guaranteed + mp_int_t gradient = ((dy * (1 << 12)) / dx); + + mp_int_t y_intercept = (y1 * (1 << 12)) + gradient; + if (steep) { + for (mp_int_t x = x1 + 1; x < x1 + dx; ++x) { + setpixel_checked(fb, y_intercept >> 12, x, col, 1, alpha_mult(0xFF - ((y_intercept >> 4) & 0xff), alpha)); + setpixel_checked(fb, (y_intercept >> 12) + 1, x, col, 1, alpha_mult((y_intercept >> 4) & 0xff, alpha)); + y_intercept += gradient; + } + } else { + for (mp_int_t x = x1 + 1; x < x1 + dx; ++x) { + setpixel_checked(fb, x, y_intercept >> 12, col, 1, alpha_mult(0xFF - ((y_intercept >> 4) & 0xff), alpha)); + setpixel_checked(fb, x, (y_intercept >> 12) + 1, col, 1, alpha_mult((y_intercept >> 4) & 0xff, alpha)); + y_intercept += gradient; + } + } +} +#else // MICROPY_PY_FRAMEBUF_ALPHA +static void line(const mp_obj_framebuf_t *fb, mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, mp_int_t col, mp_int_t alpha, bool draw_last) { + // This implements Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + (void)draw_last; -static void line(const mp_obj_framebuf_t *fb, mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, mp_int_t col) { mp_int_t dx = x2 - x1; mp_int_t sx; if (dx > 0) { @@ -468,11 +669,11 @@ static void line(const mp_obj_framebuf_t *fb, mp_int_t x1, mp_int_t y1, mp_int_t for (mp_int_t i = 0; i < dx; ++i) { if (steep) { if (0 <= y1 && y1 < fb->width && 0 <= x1 && x1 < fb->height) { - setpixel(fb, y1, x1, col); + setpixel(fb, y1, x1, col, alpha); } } else { if (0 <= x1 && x1 < fb->width && 0 <= y1 && y1 < fb->height) { - setpixel(fb, x1, y1, col); + setpixel(fb, x1, y1, col, alpha); } } while (e >= 0) { @@ -483,8 +684,9 @@ static void line(const mp_obj_framebuf_t *fb, mp_int_t x1, mp_int_t y1, mp_int_t e += 2 * dy; } - setpixel_checked(fb, x2, y2, col, 1); + setpixel_checked(fb, x2, y2, col, 1, alpha); } +#endif // MICROPY_PY_FRAMEBUF_ALPHA static mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args_in) { (void)n_args; @@ -493,11 +695,11 @@ static mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args_in) { mp_int_t args[5]; // x1, y1, x2, y2, col framebuf_args(args_in, args, 5); - line(self, args[0], args[1], args[2], args[3], args[4]); + line(self, args[0], args[1], args[2], args[3], args[4], FRAMEBUF_GET_ALPHA_ARG(6), true); return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 7, framebuf_line); // Q2 Q1 // Q3 Q4 @@ -508,25 +710,41 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_lin #define ELLIPSE_MASK_Q3 (0x04) #define ELLIPSE_MASK_Q4 (0x08) -static void draw_ellipse_points(const mp_obj_framebuf_t *fb, mp_int_t cx, mp_int_t cy, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask) { +static void draw_ellipse_points(const mp_obj_framebuf_t *fb, mp_int_t cx, mp_int_t cy, mp_int_t x, mp_int_t y, mp_int_t col, mp_int_t mask, mp_int_t alpha) { + // Care needs to be taken to avoid drawing the same pixel twice when using transparency. if (mask & ELLIPSE_MASK_FILL) { - if (mask & ELLIPSE_MASK_Q1) { - fill_rect(fb, cx, cy - y, x + 1, 1, col); - } - if (mask & ELLIPSE_MASK_Q2) { - fill_rect(fb, cx - x, cy - y, x + 1, 1, col); - } - if (mask & ELLIPSE_MASK_Q3) { - fill_rect(fb, cx - x, cy + y, x + 1, 1, col); - } - if (mask & ELLIPSE_MASK_Q4) { - fill_rect(fb, cx, cy + y, x + 1, 1, col); + if (y == 0 && (mask & ELLIPSE_MASK_ALL)) { + // on y-axis, draw one hline + mp_int_t x_min = (mask & (ELLIPSE_MASK_Q2 | ELLIPSE_MASK_Q3)) ? -x : 0; + mp_int_t x_max = (mask & (ELLIPSE_MASK_Q1 | ELLIPSE_MASK_Q4)) ? x : 0; + fill_rect(fb, cx + x_min, cy, x_max - x_min + 1, 1, col, alpha); + } else { + if (mask & (ELLIPSE_MASK_Q1 | ELLIPSE_MASK_Q2)) { + // draw one hline above + mp_int_t x_min = (mask & ELLIPSE_MASK_Q2) ? -x : 0; + mp_int_t x_max = (mask & ELLIPSE_MASK_Q1) ? x : 0; + fill_rect(fb, cx + x_min, cy - y, x_max - x_min + 1, 1, col, alpha); + } + if (mask & (ELLIPSE_MASK_Q3 | ELLIPSE_MASK_Q4)) { + // draw one hline below + mp_int_t x_min = (mask & ELLIPSE_MASK_Q3) ? -x : 0; + mp_int_t x_max = (mask & ELLIPSE_MASK_Q4) ? x : 0; + fill_rect(fb, cx + x_min, cy + y, x_max - x_min + 1, 1, col, alpha); + } } } else { - setpixel_checked(fb, cx + x, cy - y, col, mask & ELLIPSE_MASK_Q1); - setpixel_checked(fb, cx - x, cy - y, col, mask & ELLIPSE_MASK_Q2); - setpixel_checked(fb, cx - x, cy + y, col, mask & ELLIPSE_MASK_Q3); - setpixel_checked(fb, cx + x, cy + y, col, mask & ELLIPSE_MASK_Q4); + if (y == 0) { + setpixel_checked(fb, cx + x, cy, col, mask & (ELLIPSE_MASK_Q1 | ELLIPSE_MASK_Q4), alpha); + setpixel_checked(fb, cx - x, cy, col, mask & (ELLIPSE_MASK_Q2 | ELLIPSE_MASK_Q3), alpha); + } else if (x == 0) { + setpixel_checked(fb, cx, cy - y, col, mask & (ELLIPSE_MASK_Q1 | ELLIPSE_MASK_Q2), alpha); + setpixel_checked(fb, cx, cy + y, col, mask & (ELLIPSE_MASK_Q3 | ELLIPSE_MASK_Q4), alpha); + } else { + setpixel_checked(fb, cx + x, cy - y, col, mask & ELLIPSE_MASK_Q1, alpha); + setpixel_checked(fb, cx - x, cy - y, col, mask & ELLIPSE_MASK_Q2, alpha); + setpixel_checked(fb, cx - x, cy + y, col, mask & ELLIPSE_MASK_Q3, alpha); + setpixel_checked(fb, cx + x, cy + y, col, mask & ELLIPSE_MASK_Q4, alpha); + } } } @@ -540,8 +758,13 @@ static mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) { } else { mask |= ELLIPSE_MASK_ALL; } + mp_int_t alpha = FRAMEBUF_GET_ALPHA_ARG(8); + if (alpha <= 0) { + // nothing to do + return mp_const_none; + } if (args[2] == 0 && args[3] == 0) { - setpixel_checked(self, args[0], args[1], args[4], mask & ELLIPSE_MASK_ALL); + setpixel_checked(self, args[0], args[1], args[4], mask & ELLIPSE_MASK_ALL, alpha); return mp_const_none; } mp_int_t two_asquare = 2 * args[2] * args[2]; @@ -553,8 +776,12 @@ static mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) { mp_int_t ellipse_error = 0; mp_int_t stoppingx = two_bsquare * args[2]; mp_int_t stoppingy = 0; + mp_int_t last_drawn_x = -1; + mp_int_t last_drawn_y = -1; while (stoppingx >= stoppingy) { // 1st set of points, y' > -1 - draw_ellipse_points(self, args[0], args[1], x, y, args[4], mask); + draw_ellipse_points(self, args[0], args[1], x, y, args[4], mask, alpha); + last_drawn_x = x; + last_drawn_y = y; y += 1; stoppingy += two_asquare; ellipse_error += ychange; @@ -575,12 +802,18 @@ static mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) { stoppingx = 0; stoppingy = two_asquare * args[3]; while (stoppingx <= stoppingy) { // 2nd set of points, y' < -1 - draw_ellipse_points(self, args[0], args[1], x, y, args[4], mask); + if (!(mask & ELLIPSE_MASK_FILL) && (y != last_drawn_y || x != last_drawn_x)) { + draw_ellipse_points(self, args[0], args[1], x, y, args[4], mask, alpha); + } x += 1; stoppingx += two_bsquare; ellipse_error += xchange; xchange += two_bsquare; if ((2 * ellipse_error + ychange) > 0) { + if ((mask & ELLIPSE_MASK_FILL) && y != last_drawn_y) { + // moving to new scanline, draw line *once* + draw_ellipse_points(self, args[0], args[1], x - 1, y, args[4], mask, alpha); + } y -= 1; stoppingy -= two_asquare; ellipse_error += ychange; @@ -589,7 +822,7 @@ static mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) { } return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_ellipse_obj, 6, 8, framebuf_ellipse); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_ellipse_obj, 6, 9, framebuf_ellipse); #if MICROPY_PY_ARRAY @@ -597,6 +830,279 @@ static mp_int_t poly_int(mp_buffer_info_t *bufinfo, size_t index) { return mp_obj_get_int(mp_binary_get_val_array(bufinfo->typecode, bufinfo->buf, index)); } +#if MICROPY_PY_FRAMEBUF_ALPHA + +static inline uint32_t popcount(uint32_t x) { + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + return (x * 0x01010101) >> 24; +} + +typedef struct edge { + mp_int_t y1; + mp_int_t y2; + mp_int_t x1; + mp_int_t slope; +} edge; + +static void insert_edge(edge *edge_table, int n_edges, mp_int_t py1, mp_int_t py2, mp_int_t px1, mp_int_t slope) { + edge e = { + py1, + py2, + px1 + (slope >> 2), // bump to first sub-scanline intersection (increment by a quarter of the slope) + slope, + }; + edge current; + // simple linear ordered insertion + for (int i = 0; i < n_edges; ++i) { + current = edge_table[i]; + if (e.y1 <= current.y1) { + edge_table[i] = e; + e = current; + } + } + edge_table[n_edges] = e; +} + +typedef struct node { + mp_int_t x; + uint32_t mask; +} node; + +static int insert_node(node *node_table, int n_nodes, mp_int_t x, uint32_t mask) { + node n = {x, mask}; + node current; + // simple linear ordered insertion + for (int i = 0; i < n_nodes; ++i) { + current = node_table[i]; + if (n.x == current.x) { + n.mask = n.mask ^ current.mask; + node_table[i] = n; + return 0; + } else if (n.x < current.x) { + node_table[i] = n; + n = current; + } + } + node_table[n_nodes] = n; + return 1; +} + +static mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { + mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); + + mp_int_t x = mp_obj_get_int(args_in[1]); + mp_int_t y = mp_obj_get_int(args_in[2]); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args_in[3], &bufinfo, MP_BUFFER_READ); + // If an odd number of values was given, this rounds down to multiple of two. + int n_poly = bufinfo.len / (mp_binary_get_size('@', bufinfo.typecode, NULL) * 2); + + if (n_poly == 0) { + // Nothing to do. + return mp_const_none; + } + + mp_int_t col = mp_obj_get_int(args_in[4]); + bool fill = n_args > 5 && mp_obj_is_true(args_in[5]); + mp_int_t alpha = FRAMEBUF_GET_ALPHA_ARG(6); + if (alpha <= 0) { + // Nothing to do. + return mp_const_none; + } + + if (fill) { + // This implements an integer version of the A-buffer algorithm for antialiased polygon fill. + + // We compute two scanlines per row, one at -0.25 and one at +0.25 from + // the pixel center (where the integer coordinates are). Each scanline + // samples at the 0.25 multiples. + // + // +---+---+ -0.5 + // X-X-X-X-| + // +---+---+ 0 + // X-X-X-X-| + // +---+---+ +0.5 + // -0.5 0 +0.5 + // + // Where an edge intersects a scanline, we round and set a bit mask of all + // bits to the right of it, and xor that with the mask from the previous edges. + // + // When we move to the next pixel we copy the last bit on each scanline + // and multiply by 0b1111 to extend it to the entire row, and use that as + // the initial mask for that pixel. + // + // Original paper: https://dl.acm.org/doi/pdf/10.1145/964965.808585 + // Explanation in the context of embedded systems: https://aykevl.nl/2024/02/tinygl-polygon/ + // We don't use a lookup table. + + // Increase alpha for mono buffers to get sharp corners. + if (self->format == FRAMEBUF_MHLSB || self->format == FRAMEBUF_MHMSB || self->format == FRAMEBUF_MVLSB) { + alpha *= 2; + } + + // Build an ordered table of edges and data + // The table consists of entries (y_min, y_max, x_min, 1/slope) and is ordered by y_min. + // The value of 1/slope is stored with 12 bits of fixed precision. + // Horizontal lines are ignored. + + edge edge_table[n_poly]; + int n_edges = 0; + mp_int_t px1 = x + poly_int(&bufinfo, 2 * n_poly - 2); + mp_int_t py1 = y + poly_int(&bufinfo, 2 * n_poly - 1); + mp_int_t y_start = py1; + mp_int_t y_end = py1 + 1; + for (int i = 0; i < n_poly; ++i) { + mp_int_t px2 = x + poly_int(&bufinfo, 2 * i); + mp_int_t py2 = y + poly_int(&bufinfo, 2 * i + 1); + + // track the min and max extent of the polygon + y_start = MIN(y_start, py2); + y_end = MAX(y_end, py2 + 1); + + if (py1 < py2) { + // going up + if (py1 <= self->height || py2 >= 0) { + // intersects buffer vertically + insert_edge(edge_table, n_edges, py1, py2, px1 * (1 << 12), ((px2 - px1) * (1 << 12)) / (py2 - py1)); + ++n_edges; + } + } else if (py1 > py2) { + // going down + if (py2 <= self->height || py1 >= 0) { + // intersects buffer vertically + insert_edge(edge_table, n_edges, py2, py1, px2 * (1 << 12), ((px2 - px1) * (1 << 12)) / (py2 - py1)); + ++n_edges; + } + } // ... and ignore horizontal edges + + px1 = px2; + py1 = py2; + } + if (n_edges == 0) { + // No non-horizontal edges: nothing to draw. + return mp_const_none; + } + y_start = MAX(0, y_start); + y_end = MIN(self->height, y_end); + + // Track which edges are can possibly intersect subsample scanlines. + int last_edge_index = 0; + + for (mp_int_t row = y_start; row < y_end; row++) { + // Add any new edges that may intersect the subsample lines to those we consider. + while (last_edge_index < n_edges && edge_table[last_edge_index].y1 <= row) { + ++last_edge_index; + } + + // Build an ordered table of intersection locations and masks on subsample scanlines. + // The table is ordered by pixel column and holds the mask for that pixel. + int n_nodes = 0; + node nodes[2 * last_edge_index]; + + for (int line = 0; line < 2; ++line) { + // For each subsample line... + // Get y-value with 2 bits of fixed precision + mp_int_t y1 = (line == 0) ? ((row << 2) - 1) : ((row << 2) + 1); + for (int i = 0; i < last_edge_index; ++i) { + // For each edge... + edge *e = &(edge_table[i]); + if ((e->y2 * (1 << 2)) < y1) { + // Edge is below subsample line, ignore. + continue; + } else if ((e->y1 * (1 << 2)) > y1) { + // Edge above subsample line (can happen for lower subsample line at start of edge). + continue; + } + // Find pixel and sub-pixel offsets. + // We adjust x so integer coordinates are in the center of each pixel and intersections + // with subsample pixels round to nearest quarter. This makes the antialiased values + // symmetric when given a symmetric shape. + mp_int_t x_adjusted = e->x1 + (1 << 11) + (1 << 9); + mp_int_t column; + // We need integer floor division here, as remainder matters. + if (x_adjusted > 0) { + column = x_adjusted >> 12; + } else { + // avoid undefined behaviour of shifting negatives. + column = ~((~x_adjusted) >> 12); + } + if (column >= self->width) { + // Outside of buffer width: don't care about these points for this row, + // but need to bump the x-value in case line eventually comes inside the buffer. + e->x1 += (e->slope >> 1); + continue; + } + mp_int_t subpixel_offset = (x_adjusted - (column * (1 << 12))) >> 10; + + // Compute mask for subpixel scanline. + uint32_t mask = ((1 << (4 - subpixel_offset)) - 1) << (line << 2); + + // Insert the node, xor-ing the mask if there is a column match, otherwise sorting. + n_nodes += insert_node(nodes, n_nodes, column, mask); + + // Bump edge x value to next sub-scanline (increments by half the slope). + e->x1 += (e->slope >> 1); + } + } + if (!n_nodes) { + // No intersections we care about, go to next row. + continue; + } + + // Now draw the pixels by running through the intersection nodes. + uint32_t mask = 0; + node current; + for (int i = 0; i < n_nodes; ++i) { + current = nodes[i]; + + // Update the mask. + mask ^= current.mask; + + if (current.x >= 0) { + // The pixel is inside the buffer, so draw the pixel. + // The alpha of pixel is scaled by the number of bits in the mask (0-8, inclusive), + // So we multiply popcount by 255/9 with one bit of fixed point precision. + setpixel(self, current.x, row, col, alpha_mult((popcount(mask) * 0b1001001) >> 1, alpha)); + } + + // Extend mask by last bits of each subscanline. + mask = (mask & 0b00010001) * 0b1111; + + if (mask) { + // Fill with a run of pixels with same mask - can be fast. + // Width is either distance to next node, or to width of buffer if no more nodes. + mp_int_t width; + if (i + 1 < n_nodes) { + width = nodes[i + 1].x - current.x - 1; + } else { + width = self->width - current.x - 1; + } + // Use fill_rect as it accounts for rectangles wider than buffer. + // See above for discussion of alpha computation. + fill_rect(self, current.x + 1, row, width, 1, col, alpha_mult((popcount(mask) * 0b1001001) >> 1, alpha)); + } + } + } + } else { + // Outline only. + mp_int_t px1 = poly_int(&bufinfo, 0); + mp_int_t py1 = poly_int(&bufinfo, 1); + int i = n_poly * 2 - 1; + do { + mp_int_t py2 = poly_int(&bufinfo, i--); + mp_int_t px2 = poly_int(&bufinfo, i--); + line(self, x + px1, y + py1, x + px2, y + py2, col, alpha, false); + px1 = px2; + py1 = py2; + } while (i >= 0); + } + + return mp_const_none; +} +#else // MICROPY_PY_FRAMEBUF_ALPHA static mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]); @@ -614,6 +1120,7 @@ static mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { mp_int_t col = mp_obj_get_int(args_in[4]); bool fill = n_args > 5 && mp_obj_is_true(args_in[5]); + mp_int_t alpha = FRAMEBUF_GET_ALPHA_ARG(6); if (fill) { // This implements an integer version of http://alienryderflex.com/polygon_fill/ @@ -652,14 +1159,14 @@ static mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { } else if (row == MAX(py1, py2)) { // At local-minima, try and manually fill in the pixels that get missed above. if (py1 < py2) { - setpixel_checked(self, x + px2, y + py2, col, 1); + setpixel_checked(self, x + px2, y + py2, col, 1, alpha); } else if (py2 < py1) { - setpixel_checked(self, x + px1, y + py1, col, 1); + setpixel_checked(self, x + px1, y + py1, col, 1, alpha); } else { // Even though this is a hline and would be faster to // use fill_rect, use line() because it handles x2 < // x1. - line(self, x + px1, y + py1, x + px2, y + py2, col); + line(self, x + px1, y + py1, x + px2, y + py2, col, alpha, true); } } @@ -688,7 +1195,7 @@ static mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { // Fill between each pair of nodes. for (i = 0; i < n_nodes; i += 2) { - fill_rect(self, x + nodes[i], y + row, (nodes[i + 1] - nodes[i]) + 1, 1, col); + fill_rect(self, x + nodes[i], y + row, (nodes[i + 1] - nodes[i]) + 1, 1, col, alpha); } } } else { @@ -699,7 +1206,7 @@ static mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { do { mp_int_t py2 = poly_int(&bufinfo, i--); mp_int_t px2 = poly_int(&bufinfo, i--); - line(self, x + px1, y + py1, x + px2, y + py2, col); + line(self, x + px1, y + py1, x + px2, y + py2, col, alpha, true); px1 = px2; py1 = py2; } while (i >= 0); @@ -707,7 +1214,8 @@ static mp_obj_t framebuf_poly(size_t n_args, const mp_obj_t *args_in) { return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_poly_obj, 5, 6, framebuf_poly); +#endif // MICROPY_PY_FRAMEBUF_ALPHA +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_poly_obj, 5, 7, framebuf_poly); #endif // MICROPY_PY_ARRAY @@ -735,6 +1243,7 @@ static mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) { mp_int_t x = mp_obj_get_int(args_in[2]); mp_int_t y = mp_obj_get_int(args_in[3]); + // Key and palette argument handling. mp_int_t key = -1; if (n_args > 4) { key = mp_obj_get_int(args_in[4]); @@ -763,6 +1272,46 @@ static mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) { int x0end = MIN(self->width, x + source.width); int y0end = MIN(self->height, y + source.height); + mp_int_t alpha = 0xFF; + mp_int_t alpha_mul = 0; + mp_obj_framebuf_t mask; + if (n_args > 6 && args_in[6] != mp_const_none) { + if (mp_obj_get_type(args_in[6]) == &mp_type_int) { + alpha = FRAMEBUF_GET_ALPHA_ARG(6); + if (alpha <= 0) { + // nothing to do + return mp_const_none; + } + } else { + get_readonly_framebuffer(args_in[6], &mask); + if (mask.width != source.width || mask.height != source.height) { + // mask and source must be the same shape + mp_raise_ValueError(MP_ERROR_TEXT("Mask and source different sizes.")); + } + switch (mask.format) { + case FRAMEBUF_MVLSB: + case FRAMEBUF_MHLSB: + case FRAMEBUF_MHMSB: + alpha_mul = 0xff; + break; + #if MICROPY_PY_FRAMEBUF_ALPHA + case FRAMEBUF_GS8: + alpha_mul = 0x1; + break; + case FRAMEBUF_GS4_HMSB: + alpha_mul = 0x10001; + break; + case FRAMEBUF_GS2_HMSB: + alpha_mul = 0x01010101; + break; + #endif // MICROPY_PY_FRAMEBUF_ALPHA + default: + // other formats can't easily be converted to alpha + mp_raise_ValueError(MP_ERROR_TEXT("invalid mask format")); + } + } + } + for (; y0 < y0end; ++y0) { int cx1 = x1; for (int cx0 = x0; cx0 < x0end; ++cx0) { @@ -770,8 +1319,11 @@ static mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) { if (palette.buf) { col = getpixel(&palette, col, 0); } - if (col != (uint32_t)key) { - setpixel(self, cx0, y0, col); + if (alpha_mul) { + alpha = getpixel(&mask, cx1, y1) * alpha_mul; + } + if (col != (uint32_t)key && alpha) { + setpixel(self, cx0, y0, col, alpha); } ++cx1; } @@ -779,7 +1331,7 @@ static mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) { } return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 6, framebuf_blit); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 7, framebuf_blit); static mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) { mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in); @@ -819,7 +1371,7 @@ static mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ys } for (; y != yend; y += dy) { for (unsigned x = sx; x != xend; x += dx) { - setpixel(self, x, y, getpixel(self, x - xstep, y - ystep)); + setpixel(self, x, y, getpixel(self, x - xstep, y - ystep), 0xFF); } } return mp_const_none; @@ -836,6 +1388,11 @@ static mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args_in) { if (n_args >= 5) { col = mp_obj_get_int(args_in[4]); } + mp_int_t alpha = FRAMEBUF_GET_ALPHA_ARG(5); + if (alpha <= 0) { + // nothing to do + return mp_const_none; + } // loop over chars for (; *str; ++str) { @@ -853,7 +1410,7 @@ static mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args_in) { for (int y = y0; vline_data; vline_data >>= 1, y++) { // scan over vertical column if (vline_data & 1) { // only draw if pixel set if (0 <= y && y < self->height) { // clip y - setpixel(self, x0, y, col); + setpixel(self, x0, y, col, alpha); } } } @@ -862,7 +1419,7 @@ static mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args_in) { } return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 5, framebuf_text); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 6, framebuf_text); #if !MICROPY_ENABLE_DYNRUNTIME static const mp_rom_map_elem_t framebuf_locals_dict_table[] = { @@ -909,11 +1466,20 @@ static const mp_rom_map_elem_t framebuf_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) }, { MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) }, { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) }, + { MP_ROM_QSTR(MP_QSTR_RGB565_BS), MP_ROM_INT(FRAMEBUF_RGB565_BS) }, + #if MP_ENDIANNESS_LITTLE + { MP_ROM_QSTR(MP_QSTR_RGB565_LE), MP_ROM_INT(FRAMEBUF_RGB565) }, + { MP_ROM_QSTR(MP_QSTR_RGB565_BE), MP_ROM_INT(FRAMEBUF_RGB565_NN) }, + #else // MP_ENDIANNESS_LITTLE + { MP_ROM_QSTR(MP_QSTR_RGB565_LE), MP_ROM_INT(FRAMEBUF_RGB565_NN) }, + { MP_ROM_QSTR(MP_QSTR_RGB565_BE), MP_ROM_INT(FRAMEBUF_RGB565) }, + #endif // MP_ENDIANNESS_LITTLE { MP_ROM_QSTR(MP_QSTR_GS2_HMSB), MP_ROM_INT(FRAMEBUF_GS2_HMSB) }, { MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) }, { MP_ROM_QSTR(MP_QSTR_GS8), MP_ROM_INT(FRAMEBUF_GS8) }, { MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) }, { MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) }, + { MP_ROM_QSTR(MP_QSTR_ALPHA), MP_ROM_INT(MICROPY_PY_FRAMEBUF_ALPHA) }, }; static MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table); diff --git a/py/mpconfig.h b/py/mpconfig.h index 97c40389b32f0..4d84dc2ff81b4 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -2111,6 +2111,11 @@ typedef time_t mp_timestamp_t; #define MICROPY_PY_FRAMEBUF (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif +// Whether to support alpha blending in framebuf module +#ifndef MICROPY_PY_FRAMEBUF_ALPHA +#define MICROPY_PY_FRAMEBUF_ALPHA (MICROPY_PY_FRAMEBUF && MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + #ifndef MICROPY_PY_BTREE #define MICROPY_PY_BTREE (0) #endif diff --git a/tests/extmod/framebuf1.py b/tests/extmod/framebuf1.py index f5e92579f2fd7..bb1a5b0713abd 100644 --- a/tests/extmod/framebuf1.py +++ b/tests/extmod/framebuf1.py @@ -70,7 +70,7 @@ # line steep negative gradient fbuf.fill(0) - fbuf.line(3, 3, 2, 1, 1) + fbuf.line(3, 3, 2, 0, 1) print("line", buf) # scroll diff --git a/tests/extmod/framebuf1.py.exp b/tests/extmod/framebuf1.py.exp index 4f18e48eca6f1..d26263184675c 100644 --- a/tests/extmod/framebuf1.py.exp +++ b/tests/extmod/framebuf1.py.exp @@ -10,7 +10,7 @@ vline bytearray(b'\x00\xff\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x rect bytearray(b'\x00\x0e\n\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') fill_rect bytearray(b'\x00\x0e\x0e\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') line bytearray(b'\x00\x02\x04\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -line bytearray(b'\x00\x00\x06\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +line bytearray(b'\x00\x00\x03\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @@ -32,7 +32,7 @@ vline bytearray(b'@@@@@@@@@@@@@@@@') rect bytearray(b'\x00pPp\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') fill_rect bytearray(b'\x00ppp\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') line bytearray(b'\x00@ \x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -line bytearray(b'\x00 \x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +line bytearray(b' \x10\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00') @@ -54,7 +54,7 @@ vline bytearray(b'\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x rect bytearray(b'\x00\x0e\n\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') fill_rect bytearray(b'\x00\x0e\x0e\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') line bytearray(b'\x00\x02\x04\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -line bytearray(b'\x00\x04\x04\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +line bytearray(b'\x04\x04\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00') diff --git a/tests/extmod/framebuf16.py b/tests/extmod/framebuf16.py index 9f373c331e51f..18643ad59892c 100644 --- a/tests/extmod/framebuf16.py +++ b/tests/extmod/framebuf16.py @@ -4,11 +4,6 @@ print("SKIP") raise SystemExit -# This test and its .exp file is based on a little-endian architecture. -if sys.byteorder != "little": - print("SKIP") - raise SystemExit - def printbuf(): print("--8<--") @@ -17,50 +12,55 @@ def printbuf(): print("-->8--") -w = 4 -h = 5 -buf = bytearray(w * h * 2) -fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.RGB565) +for format in [framebuf.RGB565_LE, framebuf.RGB565_BE]: + w = 4 + h = 5 + buf = bytearray(w * h * 2) + fbuf = framebuf.FrameBuffer(buf, w, h, format) + + # fill + fbuf.fill(0xFFFF) + printbuf() + fbuf.fill(0x0000) + printbuf() -# fill -fbuf.fill(0xFFFF) -printbuf() -fbuf.fill(0x0000) -printbuf() + # put pixel + fbuf.pixel(0, 0, 0xEEEE) + fbuf.pixel(3, 0, 0xEE00) + fbuf.pixel(0, 4, 0x00EE) + fbuf.pixel(3, 4, 0x0EE0) + printbuf() -# put pixel -fbuf.pixel(0, 0, 0xEEEE) -fbuf.pixel(3, 0, 0xEE00) -fbuf.pixel(0, 4, 0x00EE) -fbuf.pixel(3, 4, 0x0EE0) -printbuf() + # get pixel + print(fbuf.pixel(0, 4), fbuf.pixel(1, 1), fbuf.pixel(3, 4)) -# get pixel -print(fbuf.pixel(0, 4), fbuf.pixel(1, 1)) + # scroll + fbuf.fill(0x0000) + fbuf.pixel(2, 2, 0xFFFF) + printbuf() + fbuf.scroll(0, 1) + printbuf() + fbuf.scroll(1, 0) + printbuf() + fbuf.scroll(-1, -2) + printbuf() -# scroll -fbuf.fill(0x0000) -fbuf.pixel(2, 2, 0xFFFF) -printbuf() -fbuf.scroll(0, 1) -printbuf() -fbuf.scroll(1, 0) -printbuf() -fbuf.scroll(-1, -2) -printbuf() + w2 = 2 + h2 = 3 + buf2 = bytearray(w2 * h2 * 2) + fbuf2 = framebuf.FrameBuffer(buf2, w2, h2, format) -w2 = 2 -h2 = 3 -buf2 = bytearray(w2 * h2 * 2) -fbuf2 = framebuf.FrameBuffer(buf2, w2, h2, framebuf.RGB565) + fbuf2.fill(0x0000) + fbuf2.pixel(0, 0, 0x0EE0) + fbuf2.pixel(0, 2, 0xEE00) + fbuf2.pixel(1, 0, 0x00EE) + fbuf2.pixel(1, 2, 0xE00E) + fbuf.fill(0xFFFF) + fbuf.blit(fbuf2, 3, 3, 0x0000) + fbuf.blit(fbuf2, -1, -1, 0x0000) + fbuf.blit(fbuf2, 16, 16, 0x0000) + printbuf() -fbuf2.fill(0x0000) -fbuf2.pixel(0, 0, 0x0EE0) -fbuf2.pixel(0, 2, 0xEE00) -fbuf2.pixel(1, 0, 0x00EE) -fbuf2.pixel(1, 2, 0xE00E) -fbuf.fill(0xFFFF) -fbuf.blit(fbuf2, 3, 3, 0x0000) -fbuf.blit(fbuf2, -1, -1, 0x0000) -fbuf.blit(fbuf2, 16, 16, 0x0000) -printbuf() + # check behavior of fill + fbuf.fill(0x00EE) + printbuf() diff --git a/tests/extmod/framebuf16.py.exp b/tests/extmod/framebuf16.py.exp index c41dc19d07140..3792270da1f5e 100644 --- a/tests/extmod/framebuf16.py.exp +++ b/tests/extmod/framebuf16.py.exp @@ -19,7 +19,7 @@ bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\xee\x00\x00\x00\x00\x00\xe0\x0e') -->8-- -238 0 +238 0 3808 --8<-- bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') @@ -55,3 +55,74 @@ bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') bytearray(b'\xff\xff\xff\xff\xff\xff\xe0\x0e') bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') -->8-- +--8<-- +bytearray(b'\xee\x00\xee\x00\xee\x00\xee\x00') +bytearray(b'\xee\x00\xee\x00\xee\x00\xee\x00') +bytearray(b'\xee\x00\xee\x00\xee\x00\xee\x00') +bytearray(b'\xee\x00\xee\x00\xee\x00\xee\x00') +bytearray(b'\xee\x00\xee\x00\xee\x00\xee\x00') +-->8-- +--8<-- +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +-->8-- +--8<-- +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +-->8-- +--8<-- +bytearray(b'\xee\xee\x00\x00\x00\x00\xee\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\xee\x00\x00\x00\x00\x0e\xe0') +-->8-- +238 0 3808 +--8<-- +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\xff\xff\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +-->8-- +--8<-- +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\xff\xff\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +-->8-- +--8<-- +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\xff\xff') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +-->8-- +--8<-- +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\xff\xff\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\xff\xff') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') +-->8-- +--8<-- +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +bytearray(b'\xe0\x0e\xff\xff\xff\xff\xff\xff') +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +bytearray(b'\xff\xff\xff\xff\xff\xff\x0e\xe0') +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff') +-->8-- +--8<-- +bytearray(b'\x00\xee\x00\xee\x00\xee\x00\xee') +bytearray(b'\x00\xee\x00\xee\x00\xee\x00\xee') +bytearray(b'\x00\xee\x00\xee\x00\xee\x00\xee') +bytearray(b'\x00\xee\x00\xee\x00\xee\x00\xee') +bytearray(b'\x00\xee\x00\xee\x00\xee\x00\xee') +-->8-- diff --git a/tests/extmod/framebuf_alpha.py b/tests/extmod/framebuf_alpha.py new file mode 100644 index 0000000000000..445cebde7f522 --- /dev/null +++ b/tests/extmod/framebuf_alpha.py @@ -0,0 +1,287 @@ +# Test FrameBuffer.blit method. + +import sys + +try: + import framebuf +except ImportError: + print("SKIP") + raise SystemExit + +if not framebuf.ALPHA: + print("SKIP") + raise SystemExit + + +def printbuf(bpp=1): + print("--8<--") + for y in range(h): + for x in range(w * bpp): + print("%02x" % buf[(x + y * w * bpp)], end="") + print() + print("-->8--") + + +w = 5 +h = 4 +buf = bytearray(w * h) +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) + +fbuf2 = framebuf.FrameBuffer(bytearray(4), 2, 2, framebuf.GS8) +fbuf2.fill(0x7F) + +# set pixel at various locations with alpha. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.pixel(x, y, 0x7F, 0x7F) + printbuf() + +# check that alpha 0x01 gives *something* for color 0x80 or more +fbuf.fill(0) +fbuf.pixel(0, 0, 0x80, 0x01) +printbuf() + +# rect at various locations with alpha. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.fill_rect(x, y, 2, 2, 0x7F, 0x7F) + printbuf() + +# hline at various locations with alpha. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.hline(x, y, 2, 0x7F, 0x7F) + printbuf() + +# vline at various locations with alpha. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.vline(x, y, 2, 0x7F, 0x7F) + printbuf() + +# unfilled rect at various locations with alpha. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.rect(x, y, 3, 3, 0x7F, False, 0x7F) + printbuf() + +# steep antialiased line. +fbuf.fill(0) +fbuf.line(1, 1, 2, 3, 0xFF) +printbuf() + +# shallow antialiased line. +fbuf.fill(0) +fbuf.line(1, 1, 3, 2, 0xFF) +printbuf() + +# steep antialiased line with alpha. +fbuf.fill(0) +fbuf.line(1, 1, 2, 3, 0xFF, 0x7F) +printbuf() + +# shallow antialiased line with alpha. +fbuf.fill(0) +fbuf.line(1, 1, 3, 2, 0xFF, 0x7F) +printbuf() + +# Blit another FrameBuffer, at various locations with alpha. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.blit(fbuf2, x, y, -1, None, 0x7F) + printbuf() + +# Blit another FrameBuffer with 0 alpha (test no-op branch). +fbuf.fill(0) +fbuf.blit(fbuf2, 1, 1, -1, None, 0x00) +printbuf() + +# Blit another FrameBuffer, with alpha mask. +alphas = [[0, 0x3F], [0x7F, 0xFF]] +for bpp, format in [ + (8, framebuf.GS8), + (4, framebuf.GS4_HMSB), + (2, framebuf.GS2_HMSB), + (1, framebuf.MONO_HLSB), +]: + mask = framebuf.FrameBuffer(bytearray(4), 2, 2, format) + for x in [0, 1]: + for y in [0, 1]: + mask.pixel(x, y, alphas[x][y] >> (8 - bpp)) + + fbuf.fill(0) + fbuf.blit(fbuf2, 1, 1, -1, None, mask) + printbuf() + +# Blit another FrameBuffer, with alpha mask, non-black background. +alphas = [[0, 0x3F], [0x7F, 0xFF]] +for bpp, format in [ + (8, framebuf.GS8), + (4, framebuf.GS4_HMSB), + (2, framebuf.GS2_HMSB), + (1, framebuf.MONO_HLSB), +]: + mask = framebuf.FrameBuffer(bytearray(4), 2, 2, format) + for x in [0, 1]: + for y in [0, 1]: + mask.pixel(x, y, alphas[x][y] >> (8 - bpp)) + + fbuf.fill(0xEF) + fbuf.blit(fbuf2, 1, 1, -1, None, mask) + printbuf() + +# Try to blit with wrong-shaped mask (ValueError). +alphas = [[0, 0x3F], [0x7F, 0xFF]] +mask = framebuf.FrameBuffer(bytearray(6), 3, 2, framebuf.GS8) +for x in [0, 1]: + for y in [0, 1]: + mask.pixel(x, y, alphas[x][y] >> (8 - bpp)) +fbuf.fill(0x00) +try: + fbuf.blit(fbuf2, 1, 1, -1, None, mask) +except ValueError as exc: + print(exc) +except Exception as exc: + print("Unexpected error:", exc) +else: + print("No Error") + +# Try to blit with color mask (ValueError). +mask = framebuf.FrameBuffer(bytearray(8), 2, 2, framebuf.RGB565) +fbuf.fill(0x00) +try: + fbuf.blit(fbuf2, 1, 1, -1, None, mask) +except ValueError as exc: + print(exc) +except Exception as exc: + print("Unexpected error:", exc) +else: + print("No Error") + +# text at various locations with alpha. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.text("x", x, y, 0x7F, 0x7F) + printbuf() + +# drawing with alpha 0 does nothing +fbuf.fill(0) + +fbuf.pixel(1, 1, 0x7F, 0) +fbuf.hline(1, 1, 2, 0x7F, 0) +fbuf.vline(1, 1, 2, 0x7F, 0) +fbuf.line(1, 1, 2, 2, 0x7F, 0) +fbuf.rect(1, 1, 2, 2, 0x7F, True, 0) +fbuf.rect(1, 1, 2, 2, 0x7F, False, 0) +fbuf.ellipse(1, 1, 2, 2, 0x7F, True, 0xF, 0) +fbuf.text("x", 1, 1, 0x7F, 0) + +printbuf() + +# Ellipse +w = 30 +h = 30 +buf = bytearray(w * h) +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) + +# Outline +fbuf.fill(0) +fbuf.ellipse(15, 15, 12, 6, 0x7F, False, 0b1111, 0x7F) +printbuf() + +# Fill +fbuf.fill(0) +fbuf.ellipse(15, 15, 6, 12, 0xAA, True, 0b1111, 0x7F) +printbuf() + +# Circle which might double-draw +# Outline +fbuf.fill(0) +fbuf.ellipse(15, 15, 6, 6, 0x7F, False, 0b1111, 0x7F) +printbuf() + +# Fill +fbuf.fill(0) +fbuf.ellipse(15, 15, 6, 6, 0xAA, True, 0b1111, 0x7F) +printbuf() + +# Now in color +for format in [framebuf.RGB565_LE, framebuf.RGB565_BE]: + w = 5 + h = 4 + buf = bytearray(2 * w * h) + fbuf = framebuf.FrameBuffer(buf, w, h, format) + + # set pixel at various locations with alpha. + fbuf.fill(0) + for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.pixel(x, y, 0b1111101111100000, 0x7F) + printbuf(2) + + fbuf2 = framebuf.FrameBuffer(bytearray(8), 2, 2, format) + fbuf2.fill(0b1111101111100000) + + # Blit a color FrameBuffer, at various locations with alpha. + for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.blit(fbuf2, x, y, -1, None, 0x7F) + printbuf(2) + + # Blit a color FrameBuffer, with alpha mask. + alphas = [[0, 0x3F], [0x7F, 0xFF]] + for bpp, format in [ + (8, framebuf.GS8), + (4, framebuf.GS4_HMSB), + (2, framebuf.GS2_HMSB), + (1, framebuf.MONO_HLSB), + ]: + mask = framebuf.FrameBuffer(bytearray(4), 2, 2, format) + for x in [0, 1]: + for y in [0, 1]: + mask.pixel(x, y, alphas[x][y] >> (8 - bpp)) + + fbuf.fill(0) + fbuf.blit(fbuf2, 1, 1, -1, None, mask) + printbuf(2) + + # Blit a color FrameBuffer, with alpha mask, non-black background. + alphas = [[0, 0x3F], [0x7F, 0xFF]] + for bpp, format in [ + (8, framebuf.GS8), + (4, framebuf.GS4_HMSB), + (2, framebuf.GS2_HMSB), + (1, framebuf.MONO_HLSB), + ]: + mask = framebuf.FrameBuffer(bytearray(4), 2, 2, format) + for x in [0, 1]: + for y in [0, 1]: + mask.pixel(x, y, alphas[x][y] >> (8 - bpp)) + + fbuf.fill(0b00000_111111_00000) + fbuf.blit(fbuf2, 1, 1, -1, None, mask) + printbuf(2) + +# Basic tests of native and "byte-swapped" formats. +# Ensure order in output is little-endian, then big-endian +if sys.byteorder == "big": + formats = [framebuf.RGB565_BS, framebuf.RGB565] +else: + formats = [framebuf.RGB565, framebuf.RGB565_BS] + +for format in formats: + w = 5 + h = 4 + buf = bytearray(2 * w * h) + fbuf = framebuf.FrameBuffer(buf, w, h, format) + + if format == framebuf.RGB565_BS: + # Python provides byte-swapped color values. + col = 0b11100000_11111011 + else: + col = 0b11111011_11100000 + + # set pixel at various locations with alpha. + fbuf.fill(0) + for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.pixel(x, y, col, 0x7F) + printbuf(2) diff --git a/tests/extmod/framebuf_alpha.py.exp b/tests/extmod/framebuf_alpha.py.exp new file mode 100644 index 0000000000000..eda56564c1a6f --- /dev/null +++ b/tests/extmod/framebuf_alpha.py.exp @@ -0,0 +1,556 @@ +--8<-- +0000000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +3f00000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +003f000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +000000003f +-->8-- +--8<-- +0100000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +3f00000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +3f3f000000 +3f3f000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +003f3f0000 +003f3f0000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +000000003f +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +3f3f000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +003f3f0000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +000000003f +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +3f00000000 +3f00000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +003f000000 +003f000000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +000000003f +-->8-- +--8<-- +003f000000 +3f3f000000 +0000000000 +0000000000 +-->8-- +--8<-- +3f3f3f0000 +3f003f0000 +3f3f3f0000 +0000000000 +-->8-- +--8<-- +0000000000 +003f3f3f00 +003f003f00 +003f3f3f00 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +000000003f +-->8-- +--8<-- +0000000000 +00ff000000 +007f800000 +0000ff0000 +-->8-- +--8<-- +0000000000 +00ff7f0000 +000080ff00 +0000000000 +-->8-- +--8<-- +0000000000 +007f000000 +003f400000 +00007f0000 +-->8-- +--8<-- +0000000000 +007f3f0000 +0000407f00 +0000000000 +-->8-- +--8<-- +3f00000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +3f3f000000 +3f3f000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +003f3f0000 +003f3f0000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +000000003f +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +00003f0000 +001f7f0000 +0000000000 +-->8-- +--8<-- +0000000000 +00007f0000 +007f7f0000 +0000000000 +-->8-- +--8<-- +0000000000 +00007f0000 +00007f0000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +00007f0000 +0000000000 +-->8-- +--8<-- +efefefefef +efefb7efef +efd37fefef +efefefefef +-->8-- +--8<-- +efefefefef +efef7fefef +ef7f7fefef +efefefefef +-->8-- +--8<-- +efefefefef +efef7fefef +efef7fefef +efefefefef +-->8-- +--8<-- +efefefefef +efefefefef +efef7fefef +efefefefef +-->8-- +Mask and source different sizes. +invalid mask format +--8<-- +0000000000 +3f3f00003f +003f3f3f3f +00003f3f00 +-->8-- +--8<-- +0000000000 +0000000000 +003f3f0000 +00003f3f3f +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +00003f3f00 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +00000000000000000000003f3f3f3f3f3f3f3f3f00000000000000000000 +00000000000000003f3f3f0000000000000000003f3f3f00000000000000 +0000000000003f3f0000000000000000000000000000003f3f0000000000 +00000000003f000000000000000000000000000000000000003f00000000 +000000003f0000000000000000000000000000000000000000003f000000 +0000003f00000000000000000000000000000000000000000000003f0000 +0000003f00000000000000000000000000000000000000000000003f0000 +0000003f00000000000000000000000000000000000000000000003f0000 +000000003f0000000000000000000000000000000000000000003f000000 +00000000003f000000000000000000000000000000000000003f00000000 +0000000000003f3f0000000000000000000000000000003f3f0000000000 +00000000000000003f3f3f0000000000000000003f3f3f00000000000000 +00000000000000000000003f3f3f3f3f3f3f3f3f00000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000055555500000000000000000000000000 +000000000000000000000000005555555555000000000000000000000000 +000000000000000000000000555555555555550000000000000000000000 +000000000000000000000055555555555555555500000000000000000000 +000000000000000000000055555555555555555500000000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000000055555555555555555500000000000000000000 +000000000000000000000055555555555555555500000000000000000000 +000000000000000000000000555555555555550000000000000000000000 +000000000000000000000000005555555555000000000000000000000000 +000000000000000000000000000055555500000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000003f3f3f3f3f000000000000000000000000 +0000000000000000000000003f00000000003f0000000000000000000000 +00000000000000000000003f000000000000003f00000000000000000000 +000000000000000000003f0000000000000000003f000000000000000000 +0000000000000000003f00000000000000000000003f0000000000000000 +0000000000000000003f00000000000000000000003f0000000000000000 +0000000000000000003f00000000000000000000003f0000000000000000 +0000000000000000003f00000000000000000000003f0000000000000000 +0000000000000000003f00000000000000000000003f0000000000000000 +000000000000000000003f0000000000000000003f000000000000000000 +00000000000000000000003f000000000000003f00000000000000000000 +0000000000000000000000003f00000000003f0000000000000000000000 +000000000000000000000000003f3f3f3f3f000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000005555555555000000000000000000000000 +000000000000000000000000555555555555550000000000000000000000 +000000000000000000000055555555555555555500000000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000555555555555555555555555550000000000000000 +000000000000000000005555555555555555555555000000000000000000 +000000000000000000000055555555555555555500000000000000000000 +000000000000000000000000555555555555550000000000000000000000 +000000000000000000000000005555555555000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000 +-->8-- +--8<-- +e0790000000000000000 +0000e079000000000000 +00000000000000000000 +0000000000000000e079 +-->8-- +--8<-- +e0790000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +-->8-- +--8<-- +e079e079000000000000 +e079e079000000000000 +00000000000000000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +0000e079e07900000000 +0000e079e07900000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000000000000000 +00000000000000000000 +0000000000000000e079 +-->8-- +--8<-- +00000000000000000000 +00000000e07900000000 +00000041e0fb00000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000e0fb00000000 +0000e0fbe0fb00000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000e0fb00000000 +00000000e0fb00000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000000000000000 +00000000e0fb00000000 +00000000000000000000 +-->8-- +--8<-- +e007e007e007e007e007 +e007e007e07de007e007 +e007e046e0fbe007e007 +e007e007e007e007e007 +-->8-- +--8<-- +e007e007e007e007e007 +e007e007e0fbe007e007 +e007e0fbe0fbe007e007 +e007e007e007e007e007 +-->8-- +--8<-- +e007e007e007e007e007 +e007e007e0fbe007e007 +e007e007e0fbe007e007 +e007e007e007e007e007 +-->8-- +--8<-- +e007e007e007e007e007 +e007e007e007e007e007 +e007e007e0fbe007e007 +e007e007e007e007e007 +-->8-- +--8<-- +79e00000000000000000 +000079e0000000000000 +00000000000000000000 +000000000000000079e0 +-->8-- +--8<-- +79e00000000000000000 +00000000000000000000 +00000000000000000000 +00000000000000000000 +-->8-- +--8<-- +79e079e0000000000000 +79e079e0000000000000 +00000000000000000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +000079e079e000000000 +000079e079e000000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000000000000000 +00000000000000000000 +000000000000000079e0 +-->8-- +--8<-- +00000000000000000000 +0000000079e000000000 +00004100fbe000000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000fbe000000000 +0000fbe0fbe000000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000fbe000000000 +00000000fbe000000000 +00000000000000000000 +-->8-- +--8<-- +00000000000000000000 +00000000000000000000 +00000000fbe000000000 +00000000000000000000 +-->8-- +--8<-- +07e007e007e007e007e0 +07e007e07de007e007e0 +07e046e0fbe007e007e0 +07e007e007e007e007e0 +-->8-- +--8<-- +07e007e007e007e007e0 +07e007e0fbe007e007e0 +07e0fbe0fbe007e007e0 +07e007e007e007e007e0 +-->8-- +--8<-- +07e007e007e007e007e0 +07e007e0fbe007e007e0 +07e007e0fbe007e007e0 +07e007e007e007e007e0 +-->8-- +--8<-- +07e007e007e007e007e0 +07e007e007e007e007e0 +07e007e0fbe007e007e0 +07e007e007e007e007e0 +-->8-- +--8<-- +e0790000000000000000 +0000e079000000000000 +00000000000000000000 +0000000000000000e079 +-->8-- +--8<-- +79e00000000000000000 +000079e0000000000000 +00000000000000000000 +000000000000000079e0 +-->8-- diff --git a/tests/extmod/framebuf_blit.py b/tests/extmod/framebuf_blit.py index b1d98b330a838..b85ffbb0570a0 100644 --- a/tests/extmod/framebuf_blit.py +++ b/tests/extmod/framebuf_blit.py @@ -49,6 +49,16 @@ def printbuf(): fbuf.blit(image, 1, 1, -1, palette) printbuf() +# Blit with a mono mask +mask = framebuf.FrameBuffer(bytearray(4), 2, 2, framebuf.MONO_HLSB) +for x in [0, 1]: + for y in [0, 1]: + mask.pixel(x, y, (x + y) % 2) + +fbuf.fill(0) +fbuf.blit(fbuf2, 1, 1, -1, None, mask) +printbuf() + # Not enough elements in the tuple. try: fbuf.blit((0, 0, 0), 0, 0) diff --git a/tests/extmod/framebuf_blit.py.exp b/tests/extmod/framebuf_blit.py.exp index e340f1990c783..aa3dcdfd11df5 100644 --- a/tests/extmod/framebuf_blit.py.exp +++ b/tests/extmod/framebuf_blit.py.exp @@ -40,6 +40,12 @@ ffff000000 00a2a10000 0000000000 -->8-- +--8<-- +0000000000 +0000ff0000 +00ff000000 +0000000000 +-->8-- ValueError ValueError ValueError diff --git a/tests/extmod/framebuf_polygon.py b/tests/extmod/framebuf_polygon.py index da05be2c4db52..80712e04de7f2 100644 --- a/tests/extmod/framebuf_polygon.py +++ b/tests/extmod/framebuf_polygon.py @@ -11,6 +11,11 @@ print("SKIP") raise SystemExit +if framebuf.ALPHA: + # This tests non-alpha version + print("SKIP") + raise SystemExit + def print_buffer(buffer, width, height): for row in range(height): diff --git a/tests/extmod/framebuf_polygon_alpha.py b/tests/extmod/framebuf_polygon_alpha.py new file mode 100644 index 0000000000000..66be270e1af95 --- /dev/null +++ b/tests/extmod/framebuf_polygon_alpha.py @@ -0,0 +1,396 @@ +try: + import framebuf + from array import array +except ImportError: + print("SKIP") + raise SystemExit + +# TODO: poly needs functions that aren't in dynruntime.h yet. +if not hasattr(framebuf.FrameBuffer, "poly"): + print("SKIP") + raise SystemExit + +if not framebuf.ALPHA: + # Testing for alpha and antialiased drawing + print("SKIP") + raise SystemExit + + +def print_buffer(buffer, width, height): + for row in range(height): + for col in range(width): + val = buffer[(row * width) + col] + print(" {:02x}".format(val) if val else " ··", end="") + print() + + +def print_buffer_mono(fbuf, width, height): + for row in range(height): + for col in range(width): + val = fbuf.pixel(col, row) + print(" **" if val else " ..", end="") + print() + + +def print_buffer_gs2(fbuf, width, height): + for row in range(height): + for col in range(width): + val = fbuf.pixel(col, row) + print(" {:02b}".format(val) if val else " ..", end="") + print() + + +buf = bytearray(70 * 70) + +w = 30 +h = 25 +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) +col = 0xFF +col_fill = 0x99 + +# This describes a arbitrary polygon (this happens to be a concave polygon in +# the shape of an upper-case letter 'M'). +poly = array( + "h", + ( + 0, + 20, + 3, + 20, + 3, + 10, + 6, + 17, + 9, + 10, + 9, + 20, + 12, + 20, + 12, + 3, + 9, + 3, + 6, + 10, + 3, + 3, + 0, + 3, + ), +) +# This describes the same polygon, but the points are in reverse order +# (it shouldn't matter if the polygon has clockwise or anti-clockwise +# winding). Also defined as a bytes instead of array. +poly_reversed = bytes( + ( + 0, + 3, + 3, + 3, + 6, + 10, + 9, + 3, + 12, + 3, + 12, + 20, + 9, + 20, + 9, + 10, + 6, + 17, + 3, + 10, + 3, + 20, + 0, + 20, + ) +) + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col) +fbuf.poly(15, -2, poly_reversed, col) +print_buffer(buf, w, h) +print() + +# Same but filled. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col_fill, True) +fbuf.poly(15, -2, poly_reversed, col_fill, True) +print_buffer(buf, w, h) +print() + +# Draw the fill then the outline to ensure that no fill goes outside the outline. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col_fill, True) +fbuf.poly(0, 0, poly, col) +fbuf.poly(15, -2, poly, col_fill, True) +fbuf.poly(15, -2, poly, col) +print_buffer(buf, w, h) +print() + +# Draw the outline then the fill to ensure the fill completely covers the outline. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col) +fbuf.poly(0, 0, poly, col_fill, True) +fbuf.poly(15, -2, poly, col) +fbuf.poly(15, -2, poly, col_fill, True) +print_buffer(buf, w, h) +print() + +# Draw polygons that will go out of bounds at each of the edges. +for x, y in ( + ( + -8, + -8, + ), + ( + 24, + -6, + ), + ( + 20, + 12, + ), + ( + -2, + 10, + ), +): + fbuf.fill(0) + fbuf.poly(x, y, poly, col) + print_buffer(buf, w, h) + print() + fbuf.fill(0) + fbuf.poly(x, y, poly_reversed, col, True) + print_buffer(buf, w, h) + print() + +# Edge cases: These two lists describe self-intersecting polygons +poly_hourglass = array("h", (0, 0, 9, 0, 0, 19, 9, 19)) +poly_star = array("h", (7, 0, 3, 18, 14, 5, 0, 5, 11, 18)) + +# As before, fill then outline. +fbuf.fill(0) +fbuf.poly(0, 2, poly_hourglass, col_fill, True) +fbuf.poly(0, 2, poly_hourglass, col) +fbuf.poly(12, 2, poly_star, col_fill, True) +fbuf.poly(12, 2, poly_star, col) +print_buffer(buf, w, h) +print() + +# Outline then fill. +fbuf.fill(0) +fbuf.poly(0, 2, poly_hourglass, col) +fbuf.poly(0, 2, poly_hourglass, col_fill, True) +fbuf.poly(12, 2, poly_star, col) +fbuf.poly(12, 2, poly_star, col_fill, True) +print_buffer(buf, w, h) +print() + +# Edge cases: These are "degenerate" polygons. +poly_empty = array("h") # Will draw nothing at all. +poly_one = array("h", (20, 20)) # Will draw a single point. +poly_two = array("h", (10, 10, 5, 5)) # Will draw a single line. +poly_wrong_length = array("h", (2, 2, 4)) # Will round down to one point. +poly_all_horizontal = array("h", [20, 10, 15, 10, 20, 10]) # horizontal, empty interior +poly_offscreen_left = array("h", [-5, 5, -5, 10, -10, 10, -10, 5]) # nothing to draw +poly_offscreen_right = array("h", [35, 5, 35, 10, 40, 10, 40, 5]) # nothing to draw +poly_offscreen_top = array("h", [5, -5, 5, -10, 10, -10, 10, -5]) # nothing to draw +poly_offscreen_bottom = array("h", [5, 40, 5, 45, 10, 45, 10, 40]) # nothing to draw + +fbuf.fill(0) +fbuf.poly(0, 0, poly_empty, col) +fbuf.poly(0, 0, poly_one, col) +fbuf.poly(0, 0, poly_two, col) +fbuf.poly(0, 0, poly_wrong_length, col) +fbuf.poly(0, 0, poly_all_horizontal, col) +fbuf.poly(0, 0, poly_offscreen_left, col) +fbuf.poly(0, 0, poly_offscreen_right, col) +fbuf.poly(0, 0, poly_offscreen_top, col) +fbuf.poly(0, 0, poly_offscreen_bottom, col) +print_buffer(buf, w, h) +print() + +fbuf.fill(0) +fbuf.poly(0, 0, poly_empty, col, True) +fbuf.poly(0, 0, poly_one, col, True) +fbuf.poly(0, 0, poly_two, col, True) +fbuf.poly(0, 0, poly_wrong_length, col, True) +fbuf.poly(0, 0, poly_all_horizontal, col, True) +fbuf.poly(0, 0, poly_offscreen_left, col, True) +fbuf.poly(0, 0, poly_offscreen_right, col, True) +fbuf.poly(0, 0, poly_offscreen_top, col, True) +fbuf.poly(0, 0, poly_offscreen_bottom, col, True) +print_buffer(buf, w, h) +print() + +# A shape with a horizontal overhang. +poly_overhang = array("h", (0, 0, 0, 5, 5, 5, 5, 10, 10, 10, 10, 0)) + +fbuf.fill(0) +fbuf.poly(0, 0, poly_overhang, col) +fbuf.poly(0, 0, poly_overhang, col_fill, True) +print_buffer(buf, w, h) +print() + +fbuf.fill(0) +fbuf.poly(0, 0, poly_overhang, col_fill, True) +fbuf.poly(0, 0, poly_overhang, col) +print_buffer(buf, w, h) +print() + +# Triangles +w = 70 +h = 70 +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) +t1 = array("h", [40, 0, 20, 68, 62, 40]) +t2 = array("h", [40, 0, 0, 16, 20, 68]) + +fbuf.fill(0) +fbuf.poly(0, 0, t1, 0xFF, False) +fbuf.poly(0, 0, t2, 0xFF, False) +print_buffer(buf, w, h) + +fbuf.fill(0) +fbuf.poly(0, 0, t1, 0xFF, True) +fbuf.poly(0, 0, t2, 0xFF, True) +print_buffer(buf, w, h) + +# Now with alpha +w = 30 +h = 25 +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) +col = 0xFF +col_fill = 0x99 + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, False, 0x7F) +fbuf.poly(15, -2, poly_reversed, col, False, 0x7F) +print_buffer(buf, w, h) +print() + +# Same but filled. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col_fill, True, 0x7F) +fbuf.poly(15, -2, poly_reversed, col_fill, True, 0x7F) +print_buffer(buf, w, h) +print() + +# Draw the fill then the outline to ensure that no fill goes outside the outline. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col_fill, True, 0x7F) +fbuf.poly(0, 0, poly, col, False, 0x7F) +fbuf.poly(15, -2, poly, col_fill, True, 0x7F) +fbuf.poly(15, -2, poly, col, False, 0x7F) +print_buffer(buf, w, h) +print() + +# Draw the outline then the fill to ensure the fill completely covers the outline. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, False, 0x7F) +fbuf.poly(0, 0, poly, col_fill, True, 0x7F) +fbuf.poly(15, -2, poly, col, False, 0x7F) +fbuf.poly(15, -2, poly, col_fill, True, 0x7F) +print_buffer(buf, w, h) +print() + +# Draw with alpha 0. +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, False, 0) +fbuf.poly(15, -2, poly_reversed, col, False, 0) +print_buffer(buf, w, h) +print() + +# Test 1-bit cases +w = 30 +h = 25 +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.MONO_HLSB) +col = 1 +col_fill = 1 + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, False) +fbuf.poly(15, -2, poly_reversed, col, False) +print_buffer_mono(fbuf, w, h) +print() + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, True) +fbuf.poly(15, -2, poly_reversed, col, True) +print_buffer_mono(fbuf, w, h) +print() + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, True) +fbuf.poly(0, 0, poly, col, False) +fbuf.poly(15, -2, poly_reversed, col, True) +fbuf.poly(15, -2, poly_reversed, col, False) +print_buffer_mono(fbuf, w, h) +print() + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, False) +fbuf.poly(0, 0, poly, col, True) +fbuf.poly(15, -2, poly_reversed, col, False) +fbuf.poly(15, -2, poly_reversed, col, True) +print_buffer_mono(fbuf, w, h) +print() + +fbuf.fill(0) +fbuf.poly(0, 0, poly_empty, col) +fbuf.poly(0, 0, poly_one, col) +fbuf.poly(0, 0, poly_two, col) +fbuf.poly(0, 0, poly_wrong_length, col) +print_buffer_mono(fbuf, w, h) +print() + + +# Test 2-bit cases +w = 30 +h = 25 +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS2_HMSB) +col = 0b11 +col_fill = 0b11 + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, False) +fbuf.poly(15, -2, poly_reversed, col, False) +print_buffer_gs2(fbuf, w, h) +print() + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, True) +fbuf.poly(15, -2, poly_reversed, col, True) +print_buffer_gs2(fbuf, w, h) +print() + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, True) +fbuf.poly(0, 0, poly, col, False) +fbuf.poly(15, -2, poly_reversed, col, True) +fbuf.poly(15, -2, poly_reversed, col, False) +print_buffer_gs2(fbuf, w, h) +print() + +# Draw the line polygon (at the origin) and the reversed-order polygon (offset). +fbuf.fill(0) +fbuf.poly(0, 0, poly, col, False) +fbuf.poly(0, 0, poly, col, True) +fbuf.poly(15, -2, poly_reversed, col, False) +fbuf.poly(15, -2, poly_reversed, col, True) +print_buffer_gs2(fbuf, w, h) +print() diff --git a/tests/extmod/framebuf_polygon_alpha.py.exp b/tests/extmod/framebuf_polygon_alpha.py.exp new file mode 100644 index 0000000000000..378839f455452 --- /dev/null +++ b/tests/extmod/framebuf_polygon_alpha.py.exp @@ -0,0 +1,972 @@ + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· 92 6d ·· ·· ·· 6d 92 ·· ·· ff ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ff ·· ·· 24 db ·· ·· ·· db 24 ·· ·· ff ·· ·· + ff ·· ·· 92 6d ·· ·· ·· 6d 92 ·· ·· ff ·· ·· ff ·· ·· ·· b6 49 ·· 49 b6 ·· ·· ·· ff ·· ·· + ff ·· ·· 24 db ·· ·· ·· db 24 ·· ·· ff ·· ·· ff ·· ·· ·· 49 b6 ·· b6 49 ·· ·· ·· ff ·· ·· + ff ·· ·· ·· b6 49 ·· 49 b6 ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· db 43 db ·· ·· ·· ·· ff ·· ·· + ff ·· ·· ·· 49 b6 ·· b6 49 ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· 6d d0 6d ·· ·· ·· ·· ff ·· ·· + ff ·· ·· ·· ·· db 43 db ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ·· ·· 6d d0 6d ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff 6d ·· ·· ·· 6d ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff db ·· ·· ·· db ff ·· ·· ff ·· ·· + ff ·· ·· ff 6d ·· ·· ·· 6d ff ·· ·· ff ·· ·· ff ·· ·· ff b6 49 ·· 49 b6 ff ·· ·· ff ·· ·· + ff ·· ·· ff db ·· ·· ·· db ff ·· ·· ff ·· ·· ff ·· ·· ff 49 b6 ·· b6 49 ff ·· ·· ff ·· ·· + ff ·· ·· ff b6 49 ·· 49 b6 ff ·· ·· ff ·· ·· ff ·· ·· ff ·· db 43 db ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff 49 b6 ·· b6 49 ff ·· ·· ff ·· ·· ff ·· ·· ff ·· 6d d0 6d ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· db 43 db ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· 6d d0 6d ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ff ·· ·· ff ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 2c 58 58 2c ·· ·· ·· ·· ·· 2c 58 58 2c ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 58 99 99 99 ·· ·· ·· ·· ·· 99 99 99 58 ·· ·· + 2c 58 58 2c ·· ·· ·· ·· ·· 2c 58 58 2c ·· ·· 58 99 99 99 41 ·· ·· ·· 41 99 99 99 58 ·· ·· + 58 99 99 99 ·· ·· ·· ·· ·· 99 99 99 58 ·· ·· 58 99 99 99 99 ·· ·· ·· 99 99 99 99 58 ·· ·· + 58 99 99 99 41 ·· ·· ·· 41 99 99 99 58 ·· ·· 58 99 99 99 99 16 ·· 16 99 99 99 99 58 ·· ·· + 58 99 99 99 99 ·· ·· ·· 99 99 99 99 58 ·· ·· 58 99 99 99 99 6d ·· 6d 99 99 99 99 58 ·· ·· + 58 99 99 99 99 16 ·· 16 99 99 99 99 58 ·· ·· 58 99 99 99 99 99 2c 99 99 99 99 99 58 ·· ·· + 58 99 99 99 99 6d ·· 6d 99 99 99 99 58 ·· ·· 58 99 99 99 99 99 99 99 99 99 99 99 58 ·· ·· + 58 99 99 99 99 99 2c 99 99 99 99 99 58 ·· ·· 58 99 99 6d 99 99 99 99 99 6d 99 99 58 ·· ·· + 58 99 99 99 99 99 99 99 99 99 99 99 58 ·· ·· 58 99 99 58 6d 99 99 99 6d 58 99 99 58 ·· ·· + 58 99 99 6d 99 99 99 99 99 6d 99 99 58 ·· ·· 58 99 99 58 16 99 99 99 16 58 99 99 58 ·· ·· + 58 99 99 58 6d 99 99 99 6d 58 99 99 58 ·· ·· 58 99 99 58 ·· 99 99 99 ·· 58 99 99 58 ·· ·· + 58 99 99 58 16 99 99 99 16 58 99 99 58 ·· ·· 58 99 99 58 ·· 41 99 41 ·· 58 99 99 58 ·· ·· + 58 99 99 58 ·· 99 99 99 ·· 58 99 99 58 ·· ·· 58 99 99 58 ·· ·· 83 ·· ·· 58 99 99 58 ·· ·· + 58 99 99 58 ·· 41 99 41 ·· 58 99 99 58 ·· ·· 58 99 99 58 ·· ·· ·· ·· ·· 58 99 99 58 ·· ·· + 58 99 99 58 ·· ·· 83 ·· ·· 58 99 99 58 ·· ·· 58 99 99 58 ·· ·· ·· ·· ·· 58 99 99 58 ·· ·· + 58 99 99 58 ·· ·· ·· ·· ·· 58 99 99 58 ·· ·· 58 99 99 58 ·· ·· ·· ·· ·· 58 99 99 58 ·· ·· + 58 99 99 58 ·· ·· ·· ·· ·· 58 99 99 58 ·· ·· 2c 58 58 2c ·· ·· ·· ·· ·· 2c 58 58 2c ·· ·· + 58 99 99 58 ·· ·· ·· ·· ·· 58 99 99 58 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 2c 58 58 2c ·· ·· ·· ·· ·· 2c 58 58 2c ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 99 99 d3 6d ·· ·· ·· 6d d3 99 99 ff ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ff 99 99 a7 e4 ·· ·· ·· e4 a7 99 99 ff ·· ·· + ff 99 99 d3 6d ·· ·· ·· 6d d3 99 99 ff ·· ·· ff 99 99 99 e2 49 ·· 49 e2 99 99 99 ff ·· ·· + ff 99 99 a7 e4 ·· ·· ·· e4 a7 99 99 ff ·· ·· ff 99 99 99 b6 bc ·· bc b6 99 99 99 ff ·· ·· + ff 99 99 99 e2 49 ·· 49 e2 99 99 99 ff ·· ·· ff 99 99 99 99 ea 43 ea 99 99 99 99 ff ·· ·· + ff 99 99 99 b6 bc ·· bc b6 99 99 99 ff ·· ·· ff 99 99 99 99 c5 d9 c5 99 99 99 99 ff ·· ·· + ff 99 99 99 99 ea 43 ea 99 99 99 99 ff ·· ·· ff 99 99 ff 99 99 ff 99 99 ff 99 99 ff ·· ·· + ff 99 99 99 99 c5 d9 c5 99 99 99 99 ff ·· ·· ff 99 99 ff c5 99 99 99 c5 ff 99 99 ff ·· ·· + ff 99 99 ff 99 99 ff 99 99 ff 99 99 ff ·· ·· ff 99 99 ff ea 99 99 99 ea ff 99 99 ff ·· ·· + ff 99 99 ff c5 99 99 99 c5 ff 99 99 ff ·· ·· ff 99 99 ff bc b6 99 b6 bc ff 99 99 ff ·· ·· + ff 99 99 ff ea 99 99 99 ea ff 99 99 ff ·· ·· ff 99 99 ff 49 e2 99 e2 49 ff 99 99 ff ·· ·· + ff 99 99 ff bc b6 99 b6 bc ff 99 99 ff ·· ·· ff 99 99 ff ·· e4 b3 e4 ·· ff 99 99 ff ·· ·· + ff 99 99 ff 49 e2 99 e2 49 ff 99 99 ff ·· ·· ff 99 99 ff ·· 6d e8 6d ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· e4 b3 e4 ·· ff 99 99 ff ·· ·· ff 99 99 ff ·· ·· ff ·· ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· 6d e8 6d ·· ff 99 99 ff ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· ·· ff ·· ·· ff 99 99 ff ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· + ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ff 99 99 ff ·· ·· ·· ·· ·· ff 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· e2 c5 c5 e2 ·· ·· ·· ·· ·· e2 c5 c5 e2 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c5 99 99 99 6d ·· ·· ·· 6d 99 99 99 c5 ·· ·· + e2 c5 c5 e2 ·· ·· ·· ·· ·· e2 c5 c5 e2 ·· ·· c5 99 99 99 be ·· ·· ·· be 99 99 99 c5 ·· ·· + c5 99 99 99 6d ·· ·· ·· 6d 99 99 99 c5 ·· ·· c5 99 99 99 99 49 ·· 49 99 99 99 99 c5 ·· ·· + c5 99 99 99 be ·· ·· ·· be 99 99 99 c5 ·· ·· c5 99 99 99 99 b2 ·· b2 99 99 99 99 c5 ·· ·· + c5 99 99 99 99 49 ·· 49 99 99 99 99 c5 ·· ·· c5 99 99 99 99 ac 43 ac 99 99 99 99 c5 ·· ·· + c5 99 99 99 99 b2 ·· b2 99 99 99 99 c5 ·· ·· c5 99 99 99 99 99 c0 99 99 99 99 99 c5 ·· ·· + c5 99 99 99 99 ac 43 ac 99 99 99 99 c5 ·· ·· c5 99 99 99 99 99 99 99 99 99 99 99 c5 ·· ·· + c5 99 99 99 99 99 c0 99 99 99 99 99 c5 ·· ·· c5 99 99 b6 99 99 99 99 99 b6 99 99 c5 ·· ·· + c5 99 99 99 99 99 99 99 99 99 99 99 c5 ·· ·· c5 99 99 c5 ac 99 99 99 ac c5 99 99 c5 ·· ·· + c5 99 99 b6 99 99 99 99 99 b6 99 99 c5 ·· ·· c5 99 99 c5 b2 99 99 99 b2 c5 99 99 c5 ·· ·· + c5 99 99 c5 ac 99 99 99 ac c5 99 99 c5 ·· ·· c5 99 99 c5 49 99 99 99 49 c5 99 99 c5 ·· ·· + c5 99 99 c5 b2 99 99 99 b2 c5 99 99 c5 ·· ·· c5 99 99 c5 ·· be 99 be ·· c5 99 99 c5 ·· ·· + c5 99 99 c5 49 99 99 99 49 c5 99 99 c5 ·· ·· c5 99 99 c5 ·· 6d a0 6d ·· c5 99 99 c5 ·· ·· + c5 99 99 c5 ·· be 99 be ·· c5 99 99 c5 ·· ·· c5 99 99 c5 ·· ·· ff ·· ·· c5 99 99 c5 ·· ·· + c5 99 99 c5 ·· 6d a0 6d ·· c5 99 99 c5 ·· ·· c5 99 99 c5 ·· ·· ·· ·· ·· c5 99 99 c5 ·· ·· + c5 99 99 c5 ·· ·· ff ·· ·· c5 99 99 c5 ·· ·· c5 99 99 c5 ·· ·· ·· ·· ·· c5 99 99 c5 ·· ·· + c5 99 99 c5 ·· ·· ·· ·· ·· c5 99 99 c5 ·· ·· e2 c5 c5 e2 ·· ·· ·· ·· ·· e2 c5 c5 e2 ·· ·· + c5 99 99 c5 ·· ·· ·· ·· ·· c5 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + e2 c5 c5 e2 ·· ·· ·· ·· ·· e2 c5 c5 e2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 6d ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + db ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + b6 ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 49 ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· b6 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 24 ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + db ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff b6 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + b6 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 24 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 49 92 92 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· b6 49 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· 49 b6 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· db + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· 6d + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff 6d ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff db ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff b6 49 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff 49 b6 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· db + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· 6d + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff b6 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff 24 ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff b6 ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff b6 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff b6 ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 b6 ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 24 ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 ·· 6d + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 92 92 49 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· 92 6d ·· ·· ·· 6d 92 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· 24 db ·· ·· ·· db 24 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· b6 49 ·· 49 b6 ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· 49 b6 ·· b6 49 ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· db 43 db ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· 6d d0 6d ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff 6d ·· ·· ·· 6d ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ff db ·· ·· ·· db ff + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 92 92 49 ·· ·· ·· ·· ·· 49 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ·· ·· ·· ·· ·· ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff 6d ·· ·· ·· 6d ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ·· ·· ·· ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff 24 ·· 24 ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff b6 ·· b6 ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff 49 ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff b6 ff ff ff ff ff b6 + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff 92 b6 ff ff ff b6 92 + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ·· ·· ·· ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 92 6d ·· ·· ·· 6d 92 ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 24 db ·· ·· ·· db 24 ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· b6 49 ·· 49 b6 ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· 49 b6 ·· b6 49 ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· db 43 db ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 6d d0 6d ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff ·· ·· ff ·· ·· ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff 6d ·· ·· ·· 6d ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff db ·· ·· ·· db ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff b6 49 ·· 49 b6 ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ff 49 b6 ·· b6 49 ff ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 92 49 ·· ·· ·· ·· ·· 49 92 92 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ·· ·· ·· ·· ·· ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff 6d ·· ·· ·· 6d ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ·· ·· ·· ff ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff 24 ·· 24 ff ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff b6 ·· b6 ff ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff 49 ff ff ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff b6 ff ff ff ff ff b6 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 92 b6 ff ff ff b6 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 92 24 ff ff ff 24 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 92 ·· ff ff ff ·· 92 ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 90 c9 99 99 99 99 99 99 c9 90 ·· ·· ·· ·· ·· ·· ·· ·· 38 f7 38 ·· ·· ·· ·· ·· ·· ·· ·· ·· + 0d f8 99 99 99 99 99 99 f8 0d ·· ·· ·· ·· ·· ·· ·· ·· 71 eb 71 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 9d c4 99 99 99 99 c4 9d ·· ·· ·· ·· ·· ·· ·· ·· ·· b1 d2 b1 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 1a f0 99 99 99 99 f0 1b ·· ·· ·· ·· ·· ·· ·· ·· ·· ea ae ea ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· a9 bf 99 99 bf a9 ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· + ·· ·· 28 e8 99 99 e8 28 ·· ·· ·· ·· 27 e9 99 99 99 bb b1 ·· b1 bb 99 99 99 e9 27 ·· ·· ·· + ·· ·· ·· b6 b9 b9 b6 ·· ·· ·· ·· ·· ·· 4e d9 99 99 d2 71 ·· 71 d2 99 99 d9 4e ·· ·· ·· ·· + ·· ·· ·· 35 e1 e0 36 ·· ·· ·· ·· ·· ·· ·· 82 d0 99 e3 39 ·· 38 e4 99 d0 82 ·· ·· ·· ·· ·· + ·· ·· ·· ·· d2 d2 ·· ·· ·· ·· ·· ·· ·· ·· ·· a5 c0 ff ·· ·· ·· ff c0 a5 ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· d2 d2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· da db ·· ·· ·· db d9 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 35 e1 e1 35 ·· ·· ·· ·· ·· ·· ·· ·· ·· 71 fa 13 ·· 13 f9 71 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· b5 b9 b9 b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· b1 c0 f2 ·· f2 c0 b1 ·· ·· ·· ·· ·· ·· ·· + ·· ·· 28 e8 99 99 e8 28 ·· ·· ·· ·· ·· ·· ·· ·· ea a4 b1 f6 b1 a4 ea ·· ·· ·· ·· ·· ·· ·· + ·· ·· a9 bf 99 99 bf a9 ·· ·· ·· ·· ·· ·· ·· 1c ef 99 d8 9e d8 99 ef 1c ·· ·· ·· ·· ·· ·· + ·· 1a f0 99 99 99 99 f0 1a ·· ·· ·· ·· ·· ·· 55 dd c8 94 ·· 94 c8 dd 55 ·· ·· ·· ·· ·· ·· + ·· 9c c4 99 99 99 99 c4 9d ·· ·· ·· ·· ·· ·· 8d d8 be ·· ·· ·· be d7 8e ·· ·· ·· ·· ·· ·· + 0d f8 99 99 99 99 99 99 f8 0d ·· ·· ·· ·· ·· d7 e9 ·· ·· ·· ·· ·· e9 d7 ·· ·· ·· ·· ·· ·· + 90 c9 99 99 99 99 99 99 c9 90 ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + e2 c5 c5 c5 c5 c5 c5 c5 c5 e2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 89 99 99 99 99 99 99 99 99 89 ·· ·· ·· ·· ·· ·· ·· ·· 38 c0 38 ·· ·· ·· ·· ·· ·· ·· ·· ·· + 0d b2 99 99 99 99 99 99 b2 0d ·· ·· ·· ·· ·· ·· ·· ·· 71 99 71 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 95 99 99 99 99 99 99 95 ·· ·· ·· ·· ·· ·· ·· ·· ·· a8 99 a8 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 1a af 99 99 99 99 ae 1b ·· ·· ·· ·· ·· ·· ·· ·· ·· c3 99 c3 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· a0 99 99 99 99 a0 ·· ·· ·· ·· f1 c5 c5 c5 c5 c5 d3 c5 d3 c5 c5 c5 c5 c5 f1 ·· ·· ·· + ·· ·· 28 ab 99 99 ab 28 ·· ·· ·· ·· 27 ab 99 99 99 99 a8 ·· a8 99 99 99 99 ab 27 ·· ·· ·· + ·· ·· ·· ac 99 99 ac ·· ·· ·· ·· ·· ·· 4e 9c 99 99 99 71 ·· 71 99 99 99 9c 4e ·· ·· ·· ·· + ·· ·· ·· 35 a7 a7 36 ·· ·· ·· ·· ·· ·· ·· 7b 99 99 9f 39 ·· 38 9f 99 99 7b ·· ·· ·· ·· ·· + ·· ·· ·· ·· c7 c7 ·· ·· ·· ·· ·· ·· ·· ·· ·· 9d 99 c5 ·· ·· ·· c5 99 9d ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· c7 c7 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c2 c3 ·· ·· ·· c3 c2 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 35 a7 a7 35 ·· ·· ·· ·· ·· ·· ·· ·· ·· 71 c2 13 ·· 13 c2 71 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ab 99 99 ac ·· ·· ·· ·· ·· ·· ·· ·· ·· a8 99 bc ·· bc 99 a8 ·· ·· ·· ·· ·· ·· ·· + ·· ·· 28 ab 99 99 ab 28 ·· ·· ·· ·· ·· ·· ·· ·· c3 99 99 bf 99 99 c3 ·· ·· ·· ·· ·· ·· ·· + ·· ·· a0 99 99 99 99 a0 ·· ·· ·· ·· ·· ·· ·· 1c ae 99 99 9e 99 99 ae 1c ·· ·· ·· ·· ·· ·· + ·· 1a af 99 99 99 99 af 1a ·· ·· ·· ·· ·· ·· 55 99 99 8d ·· 8d 99 99 55 ·· ·· ·· ·· ·· ·· + ·· 94 99 99 99 99 99 99 95 ·· ·· ·· ·· ·· ·· 8d 99 aa ·· ·· ·· aa 99 8e ·· ·· ·· ·· ·· ·· + 0d b2 99 99 99 99 99 99 b2 0d ·· ·· ·· ·· ·· bf c2 ·· ·· ·· ·· ·· c2 bf ·· ·· ·· ·· ·· ·· + 89 99 99 99 99 99 99 99 99 89 ·· ·· ·· ·· ·· f1 ·· ·· ·· ·· ·· ·· ·· f1 ·· ·· ·· ·· ·· ·· + e2 c5 c5 c5 c5 c5 c5 c5 c5 e2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + e2 c5 c5 c5 c5 c5 c5 c5 c5 c5 e2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + c5 99 99 99 99 99 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + c5 99 99 99 99 99 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + c5 99 99 99 99 99 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + c5 99 99 99 99 99 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + e2 c5 c5 c5 c5 a7 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· c5 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· c5 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· c5 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· c5 99 99 99 99 c5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· e2 c5 c5 c5 c5 e2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 99 99 99 99 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff ff ff ff ff ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff 99 99 99 99 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 32 98 ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 65 cb cd b3 f3 8c ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 32 98 ff 9a 34 ·· d4 a7 e6 19 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 65 cb cd 67 ·· ·· ·· ·· fb 38 59 a6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 32 98 ff 9a 34 ·· ·· ·· ·· ·· 50 f7 ·· ·· cc 33 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 65 cc cd 67 ·· ·· ·· ·· ·· ·· ·· ·· b8 c7 ·· ·· 40 bf ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 32 98 ff 9a 33 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· f1 6a ·· ·· ·· b3 4c ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 65 cc cd 67 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 1b fe ·· ·· ·· ·· 26 d9 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 32 99 ff 9a 33 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 93 e0 ·· ·· ·· ·· ·· 99 66 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 65 cc cd 66 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· df 94 ·· ·· ·· ·· ·· 0d f2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 32 99 ff 9a 33 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· fe 1d ·· ·· ·· ·· ·· ·· 80 7f ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 66 cc cd 66 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 68 f1 ·· ·· ·· ·· ·· ·· ·· ·· f3 0c ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· 32 99 ff 99 33 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c6 b9 ·· ·· ·· ·· ·· ·· ·· ·· 66 99 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· 66 cc cd 66 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· f7 52 ·· ·· ·· ·· ·· ·· ·· ·· ·· da 25 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 33 99 ff 99 33 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 37 fc ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 4d b2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 66 cc cc 66 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a6 d5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c0 3f ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ff 99 33 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· e8 81 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 33 cc ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 9d 62 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a7 58 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 3b c4 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 7f ea ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 1a e5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· d8 27 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· d3 a8 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 8d 72 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 76 89 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· fb 3a ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 13 ec ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 50 f7 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 74 8b ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· b1 4e ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b6 c7 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· e7 18 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· 4e b1 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· f0 6b ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 5a a5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ec 13 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 19 fe ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· cd 32 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 8a 75 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 93 e0 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 41 be ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 27 d8 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· df 96 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b4 4b ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· c5 3a ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· fe 1f ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 27 d8 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· 62 9d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 67 f2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 9a 65 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c6 b9 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 0e f1 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 9d 62 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· f7 54 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 81 7e ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 3b c4 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 35 fc ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· f4 0b ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· d8 27 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a4 d5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 67 98 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· 76 89 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· e8 81 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· db 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· 14 eb ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 02 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 4e b1 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· b1 4e ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 7d ea ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c1 3e ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· 4f b0 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· d2 a9 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 34 cb ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ec 13 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· fb 3a ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a8 57 ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· 8a 75 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 4f f8 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 1b e4 ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· 27 d8 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b5 c8 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 8e 71 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· c5 3a ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· f0 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 53 ff ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· 63 9c ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 19 fe ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a8 ac ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 e1 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 53 fe 57 ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 9e 61 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· de 97 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ac 01 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 3b c4 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· fe 21 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 53 fe 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· d9 26 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 67 f2 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ac 01 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 76 89 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c5 ba ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 53 fe 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 14 eb ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· f6 55 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ac 01 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b1 4e ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 33 fc ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 54 fe 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 4f b0 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a4 d5 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ab 01 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ed 12 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· e8 83 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 54 fe 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 8a 75 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 04 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ab 01 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 28 d7 ·· ·· ·· ·· ·· ·· ·· ·· ·· 7c eb ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 54 fe 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c5 3a ·· ·· ·· ·· ·· ·· ·· ·· d2 a9 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ab 01 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 63 9c ·· ·· ·· ·· ·· ·· ·· ·· fb 3c ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 54 ff 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ·· ·· ·· ·· ·· ·· ·· 4d f8 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ab ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 9e 61 ·· ·· ·· ·· ·· ·· b4 c9 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 54 ff 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 3c c3 ·· ·· ·· ·· ·· ·· f0 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· a9 ab ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· d9 26 ·· ·· ·· ·· 17 fe ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 54 ff 56 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 77 88 ·· ·· ·· ·· 90 e1 ·· ·· ·· ·· ·· ·· ·· ·· ·· aa ab ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 14 eb ·· ·· ·· ·· dd 98 ·· ·· ·· ·· ·· ·· ·· 54 ff 55 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b2 4d ·· ·· ·· fe 21 ·· ·· ·· ·· ·· ·· aa ab ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 4f b0 ·· ·· 65 f2 ·· ·· ·· ·· ·· 54 ff 55 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ed 12 ·· c4 bb ·· ·· ·· ·· aa ab ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 8a 75 ·· f6 57 ·· ·· 55 ff 55 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 28 d7 33 fc ·· ·· aa aa ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· c6 b8 d6 55 ff 55 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 63 f6 d6 aa ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff 55 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 63 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 b6 ff e5 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 b6 ff ff ff ff ff d5 ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff d5 ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· 49 b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· 49 b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff db ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 49 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· db ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· 6d ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 92 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 6d ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· 49 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· db ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· 6d ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 24 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff db ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· 6d ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 6d ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· db ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 6d ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b6 ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 6d ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b6 ff ff ff ff ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 6d ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 92 ff ff ff ff ff ff ff ff d5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 24 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· db ff ff ff ff ff ff e5 ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 6d ff ff ff ff ff ff d0 ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b6 ff ff ff ff ff ff ff ff ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 24 ff ff ff ff d5 ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ff ff ff ff e5 ff ff ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 6d ff ff ff ff ff ff ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 24 ff ff d5 ff ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· b6 ff d5 ff ff ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 6d ff ff ff b6 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· e0 ff 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 49 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 7f 7f 7f 7f ·· ·· ·· ·· ·· 7f 7f 7f 7f ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 7f ·· ·· 49 36 ·· ·· ·· 36 49 ·· ·· 7f ·· ·· + 7f 7f 7f 7f ·· ·· ·· ·· ·· 7f 7f 7f 7f ·· ·· 7f ·· ·· 12 6d ·· ·· ·· 6d 12 ·· ·· 7f ·· ·· + 7f ·· ·· 49 36 ·· ·· ·· 36 49 ·· ·· 7f ·· ·· 7f ·· ·· ·· 5b 24 ·· 24 5b ·· ·· ·· 7f ·· ·· + 7f ·· ·· 12 6d ·· ·· ·· 6d 12 ·· ·· 7f ·· ·· 7f ·· ·· ·· 24 5b ·· 5b 24 ·· ·· ·· 7f ·· ·· + 7f ·· ·· ·· 5b 24 ·· 24 5b ·· ·· ·· 7f ·· ·· 7f ·· ·· ·· ·· 6d 23 6d ·· ·· ·· ·· 7f ·· ·· + 7f ·· ·· ·· 24 5b ·· 5b 24 ·· ·· ·· 7f ·· ·· 7f ·· ·· ·· ·· 36 7d 36 ·· ·· ·· ·· 7f ·· ·· + 7f ·· ·· ·· ·· 6d 23 6d ·· ·· ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· + 7f ·· ·· ·· ·· 36 7d 36 ·· ·· ·· ·· 7f ·· ·· 7f ·· ·· a4 36 ·· ·· ·· 36 a4 ·· ·· 7f ·· ·· + 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 88 6d ·· ·· ·· 6d 88 ·· ·· 7f ·· ·· + 7f ·· ·· a4 36 ·· ·· ·· 36 a4 ·· ·· 7f ·· ·· 7f ·· ·· 7f 5b 24 ·· 24 5b 7f ·· ·· 7f ·· ·· + 7f ·· ·· 88 6d ·· ·· ·· 6d 88 ·· ·· 7f ·· ·· 7f ·· ·· 7f 24 5b ·· 5b 24 7f ·· ·· 7f ·· ·· + 7f ·· ·· 7f 5b 24 ·· 24 5b 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· 6d 23 6d ·· 7f ·· ·· 7f ·· ·· + 7f ·· ·· 7f 24 5b ·· 5b 24 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· 36 7d 36 ·· 7f ·· ·· 7f ·· ·· + 7f ·· ·· 7f ·· 6d 23 6d ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· + 7f ·· ·· 7f ·· 36 7d 36 ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· ·· ·· ·· 7f ·· ·· 7f ·· ·· + 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· 7f ·· ·· ·· ·· ·· 7f ·· ·· 7f ·· ·· + 7f ·· ·· 7f ·· ·· ·· ·· ·· 7f ·· ·· 7f ·· ·· 7f 7f 7f 7f ·· ·· ·· ·· ·· 7f 7f 7f 7f ·· ·· + 7f ·· ·· 7f ·· ·· ·· ·· ·· 7f ·· ·· 7f ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 7f 7f 7f 7f ·· ·· ·· ·· ·· 7f 7f 7f 7f ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 16 2c 2c 16 ·· ·· ·· ·· ·· 16 2c 2c 16 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 2c 57 57 4c ·· ·· ·· ·· ·· 4c 57 57 2c ·· ·· + 16 2c 2c 16 ·· ·· ·· ·· ·· 16 2c 2c 16 ·· ·· 2c 57 57 57 20 ·· ·· ·· 20 57 57 57 2c ·· ·· + 2c 57 57 4c ·· ·· ·· ·· ·· 4c 57 57 2c ·· ·· 2c 57 57 57 4c ·· ·· ·· 4c 57 57 57 2c ·· ·· + 2c 57 57 57 20 ·· ·· ·· 20 57 57 57 2c ·· ·· 2c 57 57 57 57 0b ·· 0b 57 57 57 57 2c ·· ·· + 2c 57 57 57 4c ·· ·· ·· 4c 57 57 57 2c ·· ·· 2c 57 57 57 57 37 ·· 37 57 57 57 57 2c ·· ·· + 2c 57 57 57 57 0b ·· 0b 57 57 57 57 2c ·· ·· 2c 57 57 57 57 57 16 57 57 57 57 57 2c ·· ·· + 2c 57 57 57 57 37 ·· 37 57 57 57 57 2c ·· ·· 2c 57 57 57 57 57 57 57 57 57 57 57 2c ·· ·· + 2c 57 57 57 57 57 16 57 57 57 57 57 2c ·· ·· 2c 57 57 37 57 57 57 57 57 37 57 57 2c ·· ·· + 2c 57 57 57 57 57 57 57 57 57 57 57 2c ·· ·· 2c 57 57 2c 37 57 57 57 37 2c 57 57 2c ·· ·· + 2c 57 57 37 57 57 57 57 57 37 57 57 2c ·· ·· 2c 57 57 2c 0b 57 57 57 0b 2c 57 57 2c ·· ·· + 2c 57 57 2c 37 57 57 57 37 2c 57 57 2c ·· ·· 2c 57 57 2c ·· 4c 57 4c ·· 2c 57 57 2c ·· ·· + 2c 57 57 2c 0b 57 57 57 0b 2c 57 57 2c ·· ·· 2c 57 57 2c ·· 20 57 20 ·· 2c 57 57 2c ·· ·· + 2c 57 57 2c ·· 4c 57 4c ·· 2c 57 57 2c ·· ·· 2c 57 57 2c ·· ·· 41 ·· ·· 2c 57 57 2c ·· ·· + 2c 57 57 2c ·· 20 57 20 ·· 2c 57 57 2c ·· ·· 2c 57 57 2c ·· ·· ·· ·· ·· 2c 57 57 2c ·· ·· + 2c 57 57 2c ·· ·· 41 ·· ·· 2c 57 57 2c ·· ·· 2c 57 57 2c ·· ·· ·· ·· ·· 2c 57 57 2c ·· ·· + 2c 57 57 2c ·· ·· ·· ·· ·· 2c 57 57 2c ·· ·· 2c 57 57 2c ·· ·· ·· ·· ·· 2c 57 57 2c ·· ·· + 2c 57 57 2c ·· ·· ·· ·· ·· 2c 57 57 2c ·· ·· 16 2c 2c 16 ·· ·· ·· ·· ·· 16 2c 2c 16 ·· ·· + 2c 57 57 2c ·· ·· ·· ·· ·· 2c 57 57 2c ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 16 2c 2c 16 ·· ·· ·· ·· ·· 16 2c 2c 16 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 8a 95 95 8a ·· ·· ·· ·· ·· 8a 95 95 8a ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 95 57 57 7f 36 ·· ·· ·· 36 7f 57 57 95 ·· ·· + 8a 95 95 8a ·· ·· ·· ·· ·· 8a 95 95 8a ·· ·· 95 57 57 63 7f ·· ·· ·· 7f 63 57 57 95 ·· ·· + 95 57 57 7f 36 ·· ·· ·· 36 7f 57 57 95 ·· ·· 95 57 57 57 8c 24 ·· 24 8c 57 57 57 95 ·· ·· + 95 57 57 63 7f ·· ·· ·· 7f 63 57 57 95 ·· ·· 95 57 57 57 6f 62 ·· 62 6f 57 57 57 95 ·· ·· + 95 57 57 57 8c 24 ·· 24 8c 57 57 57 95 ·· ·· 95 57 57 57 57 8c 23 8c 57 57 57 57 95 ·· ·· + 95 57 57 57 6f 62 ·· 62 6f 57 57 57 95 ·· ·· 95 57 57 57 57 7b 89 7b 57 57 57 57 95 ·· ·· + 95 57 57 57 57 8c 23 8c 57 57 57 57 95 ·· ·· 95 57 57 ab 57 57 ab 57 57 ab 57 57 95 ·· ·· + 95 57 57 57 57 7b 89 7b 57 57 57 57 95 ·· ·· 95 57 57 b7 7b 57 57 57 7b b8 57 57 95 ·· ·· + 95 57 57 ab 57 57 ab 57 57 ab 57 57 95 ·· ·· 95 57 57 9d 8c 57 57 57 8c 9c 57 57 95 ·· ·· + 95 57 57 b7 7b 57 57 57 7b b8 57 57 95 ·· ·· 95 57 57 95 62 6f 57 6f 62 95 57 57 95 ·· ·· + 95 57 57 9d 8c 57 57 57 8c 9c 57 57 95 ·· ·· 95 57 57 95 24 8c 57 8c 24 95 57 57 95 ·· ·· + 95 57 57 95 62 6f 57 6f 62 95 57 57 95 ·· ·· 95 57 57 95 ·· 7f 6e 7f ·· 95 57 57 95 ·· ·· + 95 57 57 95 24 8c 57 8c 24 95 57 57 95 ·· ·· 95 57 57 95 ·· 36 9e 36 ·· 95 57 57 95 ·· ·· + 95 57 57 95 ·· 7f 6e 7f ·· 95 57 57 95 ·· ·· 95 57 57 95 ·· ·· 7f ·· ·· 95 57 57 95 ·· ·· + 95 57 57 95 ·· 36 9e 36 ·· 95 57 57 95 ·· ·· 95 57 57 95 ·· ·· ·· ·· ·· 95 57 57 95 ·· ·· + 95 57 57 95 ·· ·· 7f ·· ·· 95 57 57 95 ·· ·· 95 57 57 95 ·· ·· ·· ·· ·· 95 57 57 95 ·· ·· + 95 57 57 95 ·· ·· ·· ·· ·· 95 57 57 95 ·· ·· 8a 95 95 8a ·· ·· ·· ·· ·· 8a 95 95 8a ·· ·· + 95 57 57 95 ·· ·· ·· ·· ·· 95 57 57 95 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 8a 95 95 8a ·· ·· ·· ·· ·· 8a 95 95 8a ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 83 87 87 83 ·· ·· ·· ·· ·· 83 87 87 83 ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· 87 57 57 71 36 ·· ·· ·· 36 71 57 57 87 ·· ·· + 83 87 87 83 ·· ·· ·· ·· ·· 83 87 87 83 ·· ·· 87 57 57 5f 76 ·· ·· ·· 76 5f 57 57 87 ·· ·· + 87 57 57 71 36 ·· ·· ·· 36 71 57 57 87 ·· ·· 87 57 57 57 7a 24 ·· 24 7a 57 57 57 87 ·· ·· + 87 57 57 5f 76 ·· ·· ·· 76 5f 57 57 87 ·· ·· 87 57 57 57 67 60 ·· 60 67 57 57 57 87 ·· ·· + 87 57 57 57 7a 24 ·· 24 7a 57 57 57 87 ·· ·· 87 57 57 57 57 7d 23 7d 57 57 57 57 87 ·· ·· + 87 57 57 57 67 60 ·· 60 67 57 57 57 87 ·· ·· 87 57 57 57 57 6e 81 6e 57 57 57 57 87 ·· ·· + 87 57 57 57 57 7d 23 7d 57 57 57 57 87 ·· ·· 87 57 57 8e 57 57 8e 57 57 8e 57 57 87 ·· ·· + 87 57 57 57 57 6e 81 6e 57 57 57 57 87 ·· ·· 87 57 57 a0 6e 57 57 57 6e a0 57 57 87 ·· ·· + 87 57 57 8e 57 57 8e 57 57 8e 57 57 87 ·· ·· 87 57 57 8d 7d 57 57 57 7d 8d 57 57 87 ·· ·· + 87 57 57 a0 6e 57 57 57 6e a0 57 57 87 ·· ·· 87 57 57 87 60 67 57 67 60 87 57 57 87 ·· ·· + 87 57 57 8d 7d 57 57 57 7d 8d 57 57 87 ·· ·· 87 57 57 87 24 7a 57 7a 24 87 57 57 87 ·· ·· + 87 57 57 87 60 67 57 67 60 87 57 57 87 ·· ·· 87 57 57 87 ·· 76 66 76 ·· 87 57 57 87 ·· ·· + 87 57 57 87 24 7a 57 7a 24 87 57 57 87 ·· ·· 87 57 57 87 ·· 36 89 36 ·· 87 57 57 87 ·· ·· + 87 57 57 87 ·· 76 66 76 ·· 87 57 57 87 ·· ·· 87 57 57 87 ·· ·· 7f ·· ·· 87 57 57 87 ·· ·· + 87 57 57 87 ·· 36 89 36 ·· 87 57 57 87 ·· ·· 87 57 57 87 ·· ·· ·· ·· ·· 87 57 57 87 ·· ·· + 87 57 57 87 ·· ·· 7f ·· ·· 87 57 57 87 ·· ·· 87 57 57 87 ·· ·· ·· ·· ·· 87 57 57 87 ·· ·· + 87 57 57 87 ·· ·· ·· ·· ·· 87 57 57 87 ·· ·· 83 87 87 83 ·· ·· ·· ·· ·· 83 87 87 83 ·· ·· + 87 57 57 87 ·· ·· ·· ·· ·· 87 57 57 87 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + 83 87 87 83 ·· ·· ·· ·· ·· 83 87 87 83 ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· ·· + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** .. .. .. ** .. .. .. ** .. .. .. ** .. .. + ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. ** .. .. .. ** .. .. .. ** .. .. .. ** .. .. + ** .. .. .. ** .. .. .. ** .. .. .. ** .. .. ** .. .. .. .. ** .. ** .. .. .. .. ** .. .. + ** .. .. .. ** .. .. .. ** .. .. .. ** .. .. ** .. .. .. .. ** .. ** .. .. .. .. ** .. .. + ** .. .. .. .. ** .. ** .. .. .. .. ** .. .. ** .. .. .. .. .. ** .. .. .. .. .. ** .. .. + ** .. .. .. .. ** .. ** .. .. .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. + ** .. .. .. .. .. ** .. .. .. .. .. ** .. .. ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. + ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** ** .. .. .. ** ** .. .. ** .. .. + ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. ** .. .. ** ** .. .. .. ** ** .. .. ** .. .. + ** .. .. ** ** .. .. .. ** ** .. .. ** .. .. ** .. .. ** .. ** .. ** .. ** .. .. ** .. .. + ** .. .. ** ** .. .. .. ** ** .. .. ** .. .. ** .. .. ** .. ** .. ** .. ** .. .. ** .. .. + ** .. .. ** .. ** .. ** .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. + ** .. .. ** .. ** .. ** .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. + ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. + ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. + ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** .. .. ** .. .. .. .. .. ** .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. + ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. + ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. + ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. + ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. + ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. + ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. + ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. + ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. + ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. + ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. + ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. + ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. + ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. + ** ** ** ** ** .. .. .. ** ** ** ** ** .. .. ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. + ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** .. ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. + ** ** ** ** ** ** ** ** ** ** ** ** ** .. .. ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. + ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. + ** ** ** ** .. ** ** ** .. ** ** ** ** .. .. ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. + ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. ** .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + ** ** ** ** .. .. .. .. .. ** ** ** ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. ** .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ** .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 11 .. .. 10 01 .. .. .. 01 10 .. .. 11 .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. 11 .. .. .. 11 .. .. .. 11 .. .. .. 11 .. .. + 11 .. .. 10 01 .. .. .. 01 10 .. .. 11 .. .. 11 .. .. .. 10 01 .. 01 10 .. .. .. 11 .. .. + 11 .. .. .. 11 .. .. .. 11 .. .. .. 11 .. .. 11 .. .. .. 01 10 .. 10 01 .. .. .. 11 .. .. + 11 .. .. .. 10 01 .. 01 10 .. .. .. 11 .. .. 11 .. .. .. .. 11 .. 11 .. .. .. .. 11 .. .. + 11 .. .. .. 01 10 .. 10 01 .. .. .. 11 .. .. 11 .. .. .. .. 01 11 01 .. .. .. .. 11 .. .. + 11 .. .. .. .. 11 .. 11 .. .. .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. + 11 .. .. .. .. 01 11 01 .. .. .. .. 11 .. .. 11 .. .. 11 01 .. .. .. 01 11 .. .. 11 .. .. + 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 11 .. .. .. 11 11 .. .. 11 .. .. + 11 .. .. 11 01 .. .. .. 01 11 .. .. 11 .. .. 11 .. .. 11 10 01 .. 01 10 11 .. .. 11 .. .. + 11 .. .. 11 11 .. .. .. 11 11 .. .. 11 .. .. 11 .. .. 11 01 10 .. 10 01 11 .. .. 11 .. .. + 11 .. .. 11 10 01 .. 01 10 11 .. .. 11 .. .. 11 .. .. 11 .. 11 .. 11 .. 11 .. .. 11 .. .. + 11 .. .. 11 01 10 .. 10 01 11 .. .. 11 .. .. 11 .. .. 11 .. 01 11 01 .. 11 .. .. 11 .. .. + 11 .. .. 11 .. 11 .. 11 .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. + 11 .. .. 11 .. 01 11 01 .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. .. .. .. 11 .. .. 11 .. .. + 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. 11 .. .. .. .. .. 11 .. .. 11 .. .. + 11 .. .. 11 .. .. .. .. .. 11 .. .. 11 .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + 11 .. .. 11 .. .. .. .. .. 11 .. .. 11 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 01 10 10 01 .. .. .. .. .. 01 10 10 01 .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 10 11 11 11 .. .. .. .. .. 11 11 11 10 .. .. + 01 10 10 01 .. .. .. .. .. 01 10 10 01 .. .. 10 11 11 11 01 .. .. .. 01 11 11 11 10 .. .. + 10 11 11 11 .. .. .. .. .. 11 11 11 10 .. .. 10 11 11 11 11 .. .. .. 11 11 11 11 10 .. .. + 10 11 11 11 01 .. .. .. 01 11 11 11 10 .. .. 10 11 11 11 11 .. .. .. 11 11 11 11 10 .. .. + 10 11 11 11 11 .. .. .. 11 11 11 11 10 .. .. 10 11 11 11 11 10 .. 10 11 11 11 11 10 .. .. + 10 11 11 11 11 .. .. .. 11 11 11 11 10 .. .. 10 11 11 11 11 11 01 11 11 11 11 11 10 .. .. + 10 11 11 11 11 10 .. 10 11 11 11 11 10 .. .. 10 11 11 11 11 11 11 11 11 11 11 11 10 .. .. + 10 11 11 11 11 11 01 11 11 11 11 11 10 .. .. 10 11 11 10 11 11 11 11 11 10 11 11 10 .. .. + 10 11 11 11 11 11 11 11 11 11 11 11 10 .. .. 10 11 11 10 10 11 11 11 10 10 11 11 10 .. .. + 10 11 11 10 11 11 11 11 11 10 11 11 10 .. .. 10 11 11 10 .. 11 11 11 .. 10 11 11 10 .. .. + 10 11 11 10 10 11 11 11 10 10 11 11 10 .. .. 10 11 11 10 .. 11 11 11 .. 10 11 11 10 .. .. + 10 11 11 10 .. 11 11 11 .. 10 11 11 10 .. .. 10 11 11 10 .. 01 11 01 .. 10 11 11 10 .. .. + 10 11 11 10 .. 11 11 11 .. 10 11 11 10 .. .. 10 11 11 10 .. .. 11 .. .. 10 11 11 10 .. .. + 10 11 11 10 .. 01 11 01 .. 10 11 11 10 .. .. 10 11 11 10 .. .. .. .. .. 10 11 11 10 .. .. + 10 11 11 10 .. .. 11 .. .. 10 11 11 10 .. .. 10 11 11 10 .. .. .. .. .. 10 11 11 10 .. .. + 10 11 11 10 .. .. .. .. .. 10 11 11 10 .. .. 10 11 11 10 .. .. .. .. .. 10 11 11 10 .. .. + 10 11 11 10 .. .. .. .. .. 10 11 11 10 .. .. 01 10 10 01 .. .. .. .. .. 01 10 10 01 .. .. + 10 11 11 10 .. .. .. .. .. 10 11 11 10 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + 01 10 10 01 .. .. .. .. .. 01 10 10 01 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 11 11 11 11 01 .. .. .. 01 11 11 11 11 .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. 11 11 11 11 11 .. .. .. 11 11 11 11 11 .. .. + 11 11 11 11 01 .. .. .. 01 11 11 11 11 .. .. 11 11 11 11 11 01 .. 01 11 11 11 11 11 .. .. + 11 11 11 11 11 .. .. .. 11 11 11 11 11 .. .. 11 11 11 11 11 10 .. 10 11 11 11 11 11 .. .. + 11 11 11 11 11 01 .. 01 11 11 11 11 11 .. .. 11 11 11 11 11 11 .. 11 11 11 11 11 11 .. .. + 11 11 11 11 11 10 .. 10 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 .. 11 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 10 11 11 11 10 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 01 11 11 11 01 11 11 11 11 .. .. + 11 11 11 11 10 11 11 11 10 11 11 11 11 .. .. 11 11 11 11 .. 11 11 11 .. 11 11 11 11 .. .. + 11 11 11 11 01 11 11 11 01 11 11 11 11 .. .. 11 11 11 11 .. 01 11 01 .. 11 11 11 11 .. .. + 11 11 11 11 .. 11 11 11 .. 11 11 11 11 .. .. 11 11 11 11 .. .. 11 .. .. 11 11 11 11 .. .. + 11 11 11 11 .. 01 11 01 .. 11 11 11 11 .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + 11 11 11 11 .. .. 11 .. .. 11 11 11 11 .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 11 11 11 11 01 .. .. .. 01 11 11 11 11 .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. 11 11 11 11 11 .. .. .. 11 11 11 11 11 .. .. + 11 11 11 11 01 .. .. .. 01 11 11 11 11 .. .. 11 11 11 11 11 01 .. 01 11 11 11 11 11 .. .. + 11 11 11 11 11 .. .. .. 11 11 11 11 11 .. .. 11 11 11 11 11 10 .. 10 11 11 11 11 11 .. .. + 11 11 11 11 11 01 .. 01 11 11 11 11 11 .. .. 11 11 11 11 11 11 .. 11 11 11 11 11 11 .. .. + 11 11 11 11 11 10 .. 10 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 .. 11 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 10 11 11 11 10 11 11 11 11 .. .. + 11 11 11 11 11 11 11 11 11 11 11 11 11 .. .. 11 11 11 11 01 11 11 11 01 11 11 11 11 .. .. + 11 11 11 11 10 11 11 11 10 11 11 11 11 .. .. 11 11 11 11 .. 11 11 11 .. 11 11 11 11 .. .. + 11 11 11 11 01 11 11 11 01 11 11 11 11 .. .. 11 11 11 11 .. 01 11 01 .. 11 11 11 11 .. .. + 11 11 11 11 .. 11 11 11 .. 11 11 11 11 .. .. 11 11 11 11 .. .. 11 .. .. 11 11 11 11 .. .. + 11 11 11 11 .. 01 11 01 .. 11 11 11 11 .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + 11 11 11 11 .. .. 11 .. .. 11 11 11 11 .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + 11 11 11 11 .. .. .. .. .. 11 11 11 11 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. +