diff --git a/internal/c/libqb.cpp b/internal/c/libqb.cpp index 61fe3bd26..608200808 100644 --- a/internal/c/libqb.cpp +++ b/internal/c/libqb.cpp @@ -41,6 +41,10 @@ #include "shell.h" #include "thread.h" +// These are here because they are used in func__loadfont() +#include +#include + int32 disableEvents = 0; // Global console vvalues @@ -3563,7 +3567,7 @@ void convert_text_to_utf16(int32 fonthandle, void *buf, int32 size) { unicode16_buf = (uint16 *)malloc(unicode16_buf_size); } // convert text - if ((fontflags[fonthandle] & 32) && (fonthandle != NULL)) { // unicode font + if ((fontflags[fonthandle] & FONT_LOAD_UNICODE) && (fonthandle != NULL)) { // unicode font if (size == 1) size = 4; convert_unicode(32, buf, size, 16, unicode16_buf); @@ -11202,7 +11206,7 @@ void printchr(int32 character) { x = im->cursor_x - 1; y = (im->cursor_y - 1) * fontheight[f]; h = fontheight[f]; - if ((fontflags[f] & 32) == 0) + if ((fontflags[f] & FONT_LOAD_UNICODE) == 0) character &= 255; // unicodefontsupport // if (mode==1) img[i].print_mode=3;//fill @@ -11212,7 +11216,7 @@ void printchr(int32 character) { if (f >= 32) { // custom font // 8-bit / alpha-disabled 32-bit / dont-blend(alpha may still be applied) - if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & 8)) { + if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & FONT_LOAD_DONTBLEND)) { // render character static int32 ok; @@ -11408,7 +11412,7 @@ int32_t chrwidth(uint32_t character) { // Custom font // a740g: No need to render just to find the pixel length - if ((fontflags[f] & 32)) { // UNICODE character + if ((fontflags[f] & FONT_LOAD_UNICODE)) { // UNICODE character w = FontPrintWidthUTF32(font[f], (uint32_t *)&character, 1); } else { // ASCII character character &= 255; @@ -11684,7 +11688,7 @@ void qbs_print(qbs *str, int32 finish_on_new_line) { character = str->chr[i]; - if (fontflags[write_page->font] & 32) { // unicode font + if (fontflags[write_page->font] & FONT_LOAD_UNICODE) { // unicode font if (i > (str->len - 4)) break; // not enough data for a utf32 encoding character = *((int32 *)(&str->chr[i])); @@ -20141,7 +20145,7 @@ void sub__printstring(float x, float y, qbs *text, int32 i, int32 passed) { if (f >= 32) { // custom font // 8-bit / alpha-disabled 32-bit / dont-blend(alpha may still be applied) - if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & 8)) { + if ((im->bytes_per_pixel == 1) || ((im->bytes_per_pixel == 4) && (im->alpha_disabled)) || (fontflags[f] & FONT_LOAD_DONTBLEND)) { // render character static int32 ok; @@ -20376,18 +20380,14 @@ int32 func__printwidth(qbs *text, int32 screenhandle, int32 passed) { } /// @brief f = _LOADFONT(ttf_filename$, height[, "monospace,dontblend,unicode,memory"][, index]) -/// @param f The font file path name or a font memory buffer when loading from memory +/// @param qbsFileName The font file path name or a font memory buffer when loading from memory /// @param size The font height in pixels -/// @param requirements This can be monospace, dontblend, unicode, memory +/// @param qbsRequirements This can be monospace, dontblend, unicode, memory /// @param font_index The index of the font to load from a font collection /// @param passed Which optional arguments were passed /// @return Returns a valid handle on success or zero on failure -int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t font_index, int32_t passed) { - // Some QB strings that we'll need - static qbs *fileNameZ = nullptr; - static qbs *reqs = nullptr; - - if (is_error_pending() || !file_name->len) +int32_t func__loadfont(const qbs *qbsFileName, int32_t size, const qbs *qbsRequirements, int32_t font_index, int32_t passed) { + if (is_error_pending() || !qbsFileName->len) return INVALID_FONT_HANDLE; // return invalid handle for any garbage input // validate size @@ -20396,12 +20396,6 @@ int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t return INVALID_FONT_HANDLE; } - if (!fileNameZ) - fileNameZ = qbs_new(0, 0); - - if (!reqs) - reqs = qbs_new(0, 0); - auto isLoadFromMemory = false; // should the font be loaded from memory? int32_t options = 0; // font flags that we'll prepare and save to fontflags[] @@ -20411,29 +20405,35 @@ int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t // 8 dontblend (blending is the default in 32-bit alpha-enabled modes) // 16 monospace // 32 unicode - if ((passed & 1) && requirements->len) { - FONT_DEBUG_PRINT("Parsing requirements"); + if ((passed & 1) && qbsRequirements->len) { + std::string requirements(reinterpret_cast(qbsRequirements->chr), qbsRequirements->len); + std::transform(requirements.begin(), requirements.end(), requirements.begin(), [](unsigned char c) { return std::toupper(c); }); - qbs_set(reqs, qbs_ucase(requirements)); // Convert tmp str to perm str + FONT_DEBUG_PRINT("Parsing requirements string: %s", requirements.c_str()); - if (func_instr(1, reqs, qbs_new_txt("DONTBLEND"), 1)) { + if (requirements.find("DONTBLEND") != std::string::npos) { options |= FONT_LOAD_DONTBLEND; - FONT_DEBUG_PRINT("DONTBLEND requested"); + FONT_DEBUG_PRINT("No alpha blending requested"); } - if (func_instr(1, reqs, qbs_new_txt("MONOSPACE"), 1)) { + if (requirements.find("MONOSPACE") != std::string::npos) { options |= FONT_LOAD_MONOSPACE; - FONT_DEBUG_PRINT("MONOSPACE requested"); + FONT_DEBUG_PRINT("Monospaced font requested"); } - if (func_instr(1, reqs, qbs_new_txt("UNICODE"), 1)) { + if (requirements.find("UNICODE") != std::string::npos) { options |= FONT_LOAD_UNICODE; - FONT_DEBUG_PRINT("UNICODE requested"); + FONT_DEBUG_PRINT("Unicode requested"); } - if (func_instr(1, reqs, qbs_new_txt("MEMORY"), 1)) { + if (requirements.find("MEMORY") != std::string::npos) { isLoadFromMemory = true; - FONT_DEBUG_PRINT("MEMORY requested"); + FONT_DEBUG_PRINT("Loading from memory requested"); + } + + if (requirements.find("AUTOMONO") != std::string::npos) { + options |= FONT_LOAD_AUTOMONO; + FONT_DEBUG_PRINT("Automatic monospacing requested"); } } @@ -20449,13 +20449,13 @@ int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t int32_t bytes; if (isLoadFromMemory) { - content = file_name->chr; // we should not free this!!! - bytes = file_name->len; + content = qbsFileName->chr; // we should not free this!!! + bytes = qbsFileName->len; FONT_DEBUG_PRINT("Loading font from memory. Size = %i", bytes); } else { - qbs_set(fileNameZ, qbs_add(file_name, qbs_new_txt_len("\0", 1))); // s1 = filename + CHR$(0) - content = FontLoadFileToMemory(filepath_fix_directory(fileNameZ), &bytes); // this we must free!!! - FONT_DEBUG_PRINT("Loading font from file %s", fileNameZ->chr); + std::string fileName(reinterpret_cast(qbsFileName->chr), qbsFileName->len); + content = FontLoadFileToMemory(filepath_fix_directory(fileName), &bytes); // this we must free!!! + FONT_DEBUG_PRINT("Loading font from file %s", fileName.c_str()); } if (!content) @@ -20489,9 +20489,9 @@ got_font_index: return INVALID_FONT_HANDLE; font[i] = h; + fontflags[i] = options; fontheight[i] = size; fontwidth[i] = FontWidth(h); - fontflags[i] = options; return i; } @@ -20537,8 +20537,8 @@ void sub__font(int32 f, int32 i, int32 passed) { return; } - if (im->text && ((fontflags[f] & 16) == 0)) { // fontflags[f] & 16 is the bit which we set for MONOSPACE fonts. If it's a SCREEN 0 screen, and the font - error(5);// isn't monospaced, toss and error and return. + if (im->text && ((fontflags[f] & FONT_LOAD_MONOSPACE) == 0)) { // fontflags[f] & 16 is the bit which we set for MONOSPACE fonts. If it's a SCREEN 0 screen, and the font + error(5); // isn't monospaced, toss an error and return. return; } // note: font changes to text screen mode images requires: @@ -29585,18 +29585,18 @@ int main(int argc, char *argv[]) { fontheight[8] = 8; fontheight[14] = 14; fontheight[16] = 16; - fontflags[8] = 16; - fontflags[14] = 16; - fontflags[16] = 16; // monospace flag + fontflags[8] = FONT_LOAD_MONOSPACE; + fontflags[14] = FONT_LOAD_MONOSPACE; + fontflags[16] = FONT_LOAD_MONOSPACE; // monospace flag fontwidth[8 + 1] = 8 * 2; fontwidth[14 + 1] = 8 * 2; fontwidth[16 + 1] = 8 * 2; fontheight[8 + 1] = 8; fontheight[14 + 1] = 14; fontheight[16 + 1] = 16; - fontflags[8 + 1] = 16; - fontflags[14 + 1] = 16; - fontflags[16 + 1] = 16; // monospace flag + fontflags[8 + 1] = FONT_LOAD_MONOSPACE; + fontflags[14 + 1] = FONT_LOAD_MONOSPACE; + fontflags[16 + 1] = FONT_LOAD_MONOSPACE; // monospace flag memset(img, 0, IMG_BUFFERSIZE * sizeof(img_struct)); x = newimg(); // reserve index 0 diff --git a/internal/c/libqb/include/font.h b/internal/c/libqb/include/font.h index f96c343f7..cb6a8fb39 100644 --- a/internal/c/libqb/include/font.h +++ b/internal/c/libqb/include/font.h @@ -19,11 +19,11 @@ FONT_DEBUG_PRINT("Condition (%s) failed", #_exp_) #else # ifdef _MSC_VER -# define FONT_DEBUG_PRINT(_fmt_, ...) // Don't do anything in release builds +# define FONT_DEBUG_PRINT(_fmt_, ...) // Don't do anything in release builds # else # define FONT_DEBUG_PRINT(_fmt_, _args_...) // Don't do anything in release builds # endif -# define FONT_DEBUG_CHECK(_exp_) // Don't do anything in release builds +# define FONT_DEBUG_CHECK(_exp_) // Don't do anything in release builds #endif #define INVALID_FONT_HANDLE 0 @@ -32,6 +32,7 @@ #define FONT_LOAD_DONTBLEND 8 #define FONT_LOAD_MONOSPACE 16 #define FONT_LOAD_UNICODE 32 +#define FONT_LOAD_AUTOMONO 64 // Font render options #define FONT_RENDER_MONOCHROME 1 @@ -41,7 +42,7 @@ struct qbs; extern uint16_t codepage437_to_unicode16[]; uint8_t *FontLoadFileToMemory(const char *file_path_name, int32_t *out_bytes); -int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t options); +int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t &options); void FontFree(int32_t fh); int32_t FontWidth(int32_t fh); bool FontRenderTextUTF32(int32_t fh, const uint32_t *codepoint, int32_t codepoints, int32_t options, uint8_t **out_data, int32_t *out_x, int32_t *out_y); diff --git a/internal/c/parts/video/font/font.cpp b/internal/c/parts/video/font/font.cpp index 1671590be..3949e9ddb 100644 --- a/internal/c/parts/video/font/font.cpp +++ b/internal/c/parts/video/font/font.cpp @@ -6,6 +6,7 @@ #define FONT_DEBUG 0 #include "font.h" #include "../../../libqb.h" +#include "error_handle.h" #include "gui.h" #include "image.h" #include "libqb-common.h" @@ -22,12 +23,14 @@ extern "C" { // Note: QB64 expects invalid font handles to be zero #define IS_VALID_FONT_HANDLE(_h_) ((_h_) > INVALID_FONT_HANDLE && (_h_) < fontManager.fonts.size() && fontManager.fonts[_h_]->isUsed) -#define IS_VALID_QB64_FONT_HANDLE(_h_) ((_h_) == 8 || (_h_) == 14 || (_h_) == 16 || ((_h_) >= 32 && (_h_) <= lastfont && font[_h_])) +#define IS_VALID_QB64_FONT_HANDLE(_h_) ((_h_) <= lastfont && ((fontwidth[_h_] && fontheight[_h_]) || ((_h_) >= 32 && font[_h_]))) #define IS_VALID_UTF_ENCODING(_e_) ((_e_) == 0 || (_e_) == 8 || (_e_) == 16 || (_e_) == 32) // These are from libqb.cpp extern const img_struct *write_page; extern const int32_t *font; +extern const int32_t *fontwidth; +extern const int32_t *fontheight; extern const int32_t *fontflags; extern const int32_t lastfont; extern const uint8_t charset8x8[256][8][8]; @@ -244,7 +247,7 @@ struct FontManager { // First get all needed glyph metrics bmp->size.x = parentFont->face->glyph->bitmap.width; // get the width of the bitmap bmp->size.y = parentFont->face->glyph->bitmap.rows; // get the height of the bitmap - bmp->advanceWidth = parentFont->face->glyph->advance.x / 64; // get the advance width of the glyph + bmp->advanceWidth = parentFont->face->glyph->advance.x >> 6; // get the advance width of the glyph bmp->bearing.x = parentFont->face->glyph->bitmap_left; // get the bitmap left side bearing bmp->bearing.y = parentFont->face->glyph->bitmap_top; // get the bitmap top side bearing @@ -292,7 +295,7 @@ struct FontManager { if (parentFont->face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { for (FT_Pos y = 0; y < bmp->size.y; y++, src += parentFont->face->glyph->bitmap.pitch, dst += bmp->size.x) { for (FT_Pos x = 0; x < bmp->size.x; x++) { - dst[x] = (((src[x / 8]) >> (7 - (x & 7))) & 1) * 255; // this looks at each bit and then sets the pixel + dst[x] = (((src[x >> 3]) >> (7 - (x & 7))) & 1) * 255; // this looks at each bit and then sets the pixel } } } else if (parentFont->face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) { @@ -488,7 +491,7 @@ struct FontManager { if (hasKerning && previousGlyph && glyph) { FT_Vector delta; FT_Get_Kerning(face, previousGlyph->index, glyph->index, FT_KERNING_DEFAULT, &delta); - width += delta.x / 64; + width += delta.x >> 6; } width += glyph->bitmap->advanceWidth; // add advance width @@ -775,9 +778,9 @@ uint8_t *FontLoadFileToMemory(const char *file_path_name, int32_t *out_bytes) { /// @param content_bytes The length of the data in bytes /// @param default_pixel_height The maximum rendering height of the font /// @param which_font The font index in a font collection (< 0 means default) -/// @param options 16=monospace (all old flags are ignored like it always was since forever) +/// @param options [IN/OUT] 16=monospace (all old flags are ignored like it always was since forever) /// @return A valid font handle (> 0) or 0 on failure -int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t options) { +int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t &options) { libqb_mutex_guard lock(fontManager.m); // Allocate a font handle @@ -816,12 +819,25 @@ int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t } fontManager.fonts[h]->defaultHeight = default_pixel_height; // save default pixel height - fontManager.fonts[h]->baseline = - (FT_Pos)qbr((((double)fontManager.fonts[h]->face->size->metrics.ascender / 64.0) / ((double)fontManager.fonts[h]->face->size->metrics.height / 64.0)) * - (double)default_pixel_height); - fontManager.fonts[h]->options = options; // save the options for use later - if ((options & FONT_LOAD_MONOSPACE) || FT_IS_FIXED_WIDTH(fontManager.fonts[h]->face)) { + // Calculate the baseline using font metrics only if it is scalable + if (FT_IS_SCALABLE(fontManager.fonts[h]->face)) + fontManager.fonts[h]->baseline = FT_MulDiv(FT_MulFix(fontManager.fonts[h]->face->ascender, fontManager.fonts[h]->face->size->metrics.y_scale), + default_pixel_height, fontManager.fonts[h]->face->size->metrics.height); + + FONT_DEBUG_PRINT("Font baseline = %d", fontManager.fonts[h]->baseline); + + FONT_DEBUG_PRINT("AUTOMONO requested: %s", (options & FONT_LOAD_AUTOMONO) ? "yes" : "no"); + + // Check if automatic fixed width font detection was requested + if ((options & FONT_LOAD_AUTOMONO) && FT_IS_FIXED_WIDTH(fontManager.fonts[h]->face)) { + FONT_DEBUG_PRINT("Fixed-width font detected. Setting MONOSPACE flag"); + + // Force set monospace flag and pass it upstream if the font is fixed width + options |= FONT_LOAD_MONOSPACE; + } + + if (options & FONT_LOAD_MONOSPACE) { const FT_ULong testCP = 'W'; // since W is usually the widest // Load using monochrome rendering @@ -835,12 +851,22 @@ int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t if (fontManager.fonts[h]->face->glyph) { fontManager.fonts[h]->monospaceWidth = - std::max(fontManager.fonts[h]->face->glyph->advance.x / 64, (FT_Pos)fontManager.fonts[h]->face->glyph->bitmap.width); // save the max width + std::max(fontManager.fonts[h]->face->glyph->advance.x >> 6, fontManager.fonts[h]->face->glyph->bitmap.width); // save the max width FONT_DEBUG_PRINT("Monospace font (width = %li) requested", fontManager.fonts[h]->monospaceWidth); + + // Set the baseline to bitmap_top if the font is not scalable + if (!FT_IS_SCALABLE(fontManager.fonts[h]->face)) + fontManager.fonts[h]->baseline = fontManager.fonts[h]->face->glyph->bitmap_top; // for bitmap fonts bitmap_top is the same for all glyph bitmaps } + + // Clear the monospace flag is we failed to get the monospace width + if (!fontManager.fonts[h]->monospaceWidth) + options &= ~FONT_LOAD_MONOSPACE; } + fontManager.fonts[h]->options = options; // save the options for use later + FONT_DEBUG_PRINT("Font (height = %i, index = %i) successfully initialized", default_pixel_height, which_font); return h; } @@ -965,7 +991,7 @@ bool FontRenderTextUTF32(int32_t fh, const uint32_t *codepoint, int32_t codepoin if (hasKerning && previousGlyph && glyph) { FT_Vector delta; FT_Get_Kerning(fnt->face, previousGlyph->index, glyph->index, FT_KERNING_DEFAULT, &delta); - penX += delta.x / 64; + penX += delta.x >> 6; } glyph->RenderBitmap(outBuf, strPixSize.x, strPixSize.y, penX + glyph->bitmap->bearing.x, fnt->baseline - glyph->bitmap->bearing.y); @@ -1033,7 +1059,7 @@ qbs *func__md5(qbs *text) { int32_t func__UFontHeight(int32_t qb64_fh, int32_t passed) { libqb_mutex_guard lock(fontManager.m); - if (new_error) + if (is_error_pending()) return 0; if (passed) { @@ -1046,9 +1072,8 @@ int32_t func__UFontHeight(int32_t qb64_fh, int32_t passed) { qb64_fh = write_page->font; // else get the current write page font handle } - // For built-in fonts return the handle value (which is = font height) if (qb64_fh < 32) - return qb64_fh; + return fontheight[qb64_fh]; FONT_DEBUG_CHECK(IS_VALID_FONT_HANDLE(font[qb64_fh])); @@ -1057,7 +1082,7 @@ int32_t func__UFontHeight(int32_t qb64_fh, int32_t passed) { auto face = fnt->face; if (FT_IS_SCALABLE(face)) - return (float)(face->ascender - face->descender) / (float)face->units_per_EM * (float)fnt->defaultHeight; + return (((FT_Pos)face->ascender - (FT_Pos)face->descender) * fnt->defaultHeight) / (FT_Pos)face->units_per_EM; return fnt->defaultHeight; } @@ -1071,7 +1096,7 @@ int32_t func__UFontHeight(int32_t qb64_fh, int32_t passed) { int32_t func__UPrintWidth(const qbs *text, int32_t utf_encoding, int32_t qb64_fh, int32_t passed) { libqb_mutex_guard lock(fontManager.m); - if (new_error || !text->len) + if (is_error_pending() || !text->len) return 0; // Check UTF argument @@ -1123,7 +1148,7 @@ int32_t func__UPrintWidth(const qbs *text, int32_t utf_encoding, int32_t qb64_fh } if (qb64_fh < 32) - return codepoints * 8; // VGA ROM fonts are 8 pixels wide + return (int32_t)(codepoints * fontwidth[qb64_fh]); FONT_DEBUG_CHECK(IS_VALID_FONT_HANDLE(font[qb64_fh])); @@ -1137,7 +1162,7 @@ int32_t func__UPrintWidth(const qbs *text, int32_t utf_encoding, int32_t qb64_fh int32_t func__ULineSpacing(int32_t qb64_fh, int32_t passed) { libqb_mutex_guard lock(fontManager.m); - if (new_error) + if (is_error_pending()) return 0; if (passed) { @@ -1150,9 +1175,8 @@ int32_t func__ULineSpacing(int32_t qb64_fh, int32_t passed) { qb64_fh = write_page->font; // else get the current write page font handle } - // For built-in fonts return the handle value (which is = font height) if (qb64_fh < 32) - return qb64_fh; + return fontheight[qb64_fh]; FONT_DEBUG_CHECK(IS_VALID_FONT_HANDLE(font[qb64_fh])); @@ -1160,7 +1184,7 @@ int32_t func__ULineSpacing(int32_t qb64_fh, int32_t passed) { auto face = fnt->face; if (FT_IS_SCALABLE(face)) - return ((float)(face->height) / (float)face->units_per_EM * (float)fnt->defaultHeight) + 2.0f; + return ((FT_Pos)face->height * fnt->defaultHeight) / (FT_Pos)face->units_per_EM; return fnt->defaultHeight; } @@ -1176,7 +1200,7 @@ int32_t func__ULineSpacing(int32_t qb64_fh, int32_t passed) { void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_t max_width, int32_t utf_encoding, int32_t qb64_fh, int32_t passed) { libqb_mutex_guard lock(fontManager.m); - if (new_error || !text->len) + if (is_error_pending() || !text->len) return; // Check if we are in text mode and generate an error if we are @@ -1252,21 +1276,28 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_ FontManager::Font *fnt = nullptr; FT_Face face = nullptr; + FT_Vector strPixSize, pen; - FT_Vector strPixSize; if (qb64_fh < 32) { strPixSize.x = codepoints * 8; strPixSize.y = qb64_fh; + pen.x = pen.y = 0; FONT_DEBUG_PRINT("Using built-in font %i", qb64_fh); } else { FONT_DEBUG_CHECK(IS_VALID_FONT_HANDLE(font[qb64_fh])); fnt = fontManager.fonts[font[qb64_fh]]; face = fnt->face; strPixSize.x = fnt->GetStringPixelWidth(str32, codepoints); - if (FT_IS_SCALABLE(face)) - strPixSize.y = (float)(face->ascender - face->descender) / (float)face->units_per_EM * (float)fnt->defaultHeight; - else + pen.x = 0; + if (FT_IS_SCALABLE(face)) { + strPixSize.y = (((FT_Pos)face->ascender - (FT_Pos)face->descender) * fnt->defaultHeight) / (FT_Pos)face->units_per_EM; + pen.y = ((FT_Pos)face->ascender * fnt->defaultHeight) / (FT_Pos)face->units_per_EM; + } else { strPixSize.y = fnt->defaultHeight; + pen.y = fnt->baseline; + } + + FONT_DEBUG_PRINT("pen.y = %i", pen.y); FONT_DEBUG_PRINT("Using custom font. Scalable = %i", FT_IS_SCALABLE(face)); } @@ -1281,12 +1312,11 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_ auto isMonochrome = (write_page->bytes_per_pixel == 1) || ((write_page->bytes_per_pixel == 4) && (write_page->alpha_disabled)) || (fontflags[qb64_fh] & FONT_LOAD_DONTBLEND); // do we need to do monochrome rendering? - FT_Vector pen = {0, 0}; // set to buffer start if (qb64_fh < 32) { + // Render using a built-in font FONT_DEBUG_PRINT("Rendering using built-in font"); - // Render using a built-in font FT_Vector draw, pixmap; uint8_t const *builtinFont = nullptr; @@ -1320,15 +1350,8 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_ pen.x += 8; } } else { - FONT_DEBUG_PRINT("Rendering using TrueType font"); - // Render using custom font - if (FT_IS_SCALABLE(face)) - pen.y = (float)face->ascender / (float)face->units_per_EM * (float)fnt->defaultHeight; - else - pen.y = face->glyph->bitmap_top; // for bitmap fonts bitmap_top is the same for all glyph bitmaps - - FONT_DEBUG_PRINT("pen.y = %i", pen.y); + FONT_DEBUG_PRINT("Rendering using TrueType font"); if (fnt->monospaceWidth) { // Monospace rendering @@ -1365,7 +1388,7 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_ if (hasKerning && previousGlyph && glyph) { FT_Vector delta; FT_Get_Kerning(fnt->face, previousGlyph->index, glyph->index, FT_KERNING_DEFAULT, &delta); - pen.x += delta.x / 64; + pen.x += delta.x >> 6; } glyph->RenderBitmap(drawBuf, strPixSize.x, strPixSize.y, pen.x + glyph->bitmap->bearing.x, pen.y - glyph->bitmap->bearing.y); @@ -1496,7 +1519,7 @@ void sub__UPrintString(int32_t start_x, int32_t start_y, const qbs *text, int32_ int32_t func__UCharPos(const qbs *text, void *arr, int32_t utf_encoding, int32_t qb64_fh, int32_t passed) { libqb_mutex_guard lock(fontManager.m); - if (new_error || !text->len) + if (is_error_pending() || !text->len) return 0; // Check if have an array to work with @@ -1556,7 +1579,7 @@ int32_t func__UCharPos(const qbs *text, void *arr, int32_t utf_encoding, int32_t // Simply return the codepoint count if we do not have any array if (!arr || !codepoints) - return codepoints; + return (int32_t)codepoints; auto element = (uint32_t *)((byte_element_struct *)arr)->offset; auto elements = ((byte_element_struct *)arr)->length / sizeof(uint32_t); @@ -1607,7 +1630,7 @@ int32_t func__UCharPos(const qbs *text, void *arr, int32_t utf_encoding, int32_t if (hasKerning && previousGlyph && glyph) { FT_Vector delta; FT_Get_Kerning(fnt->face, previousGlyph->index, glyph->index, FT_KERNING_DEFAULT, &delta); - penX += delta.x / 64; + penX += delta.x >> 6; } penX += glyph->bitmap->advanceWidth; // add advance width @@ -1620,5 +1643,5 @@ int32_t func__UCharPos(const qbs *text, void *arr, int32_t utf_encoding, int32_t element[codepoints] = penX; } - return codepoints; + return (int32_t)codepoints; } diff --git a/internal/c/parts/video/font/stub_font.cpp b/internal/c/parts/video/font/stub_font.cpp index 31f739fda..3ad891d02 100644 --- a/internal/c/parts/video/font/stub_font.cpp +++ b/internal/c/parts/video/font/stub_font.cpp @@ -8,7 +8,7 @@ uint8_t *FontLoadFileToMemory(const char *file_path_name, int32_t *out_bytes) { return nullptr; } -int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t options) { +int32_t FontLoad(const uint8_t *content_original, int32_t content_bytes, int32_t default_pixel_height, int32_t which_font, int32_t &options) { (void)content_original; (void)content_bytes; (void)default_pixel_height; diff --git a/internal/c/qbx.cpp b/internal/c/qbx.cpp index ca9de8d6e..1d40e301a 100755 --- a/internal/c/qbx.cpp +++ b/internal/c/qbx.cpp @@ -410,7 +410,7 @@ extern void sub__copypalette(int32 i, int32 i2, int32 passed); extern void sub__printstring(float x, float y, qbs *text, int32 i, int32 passed); extern int32 func__printwidth(qbs *text, int32 i, int32 passed); -extern int32_t func__loadfont(qbs *file_name, int32_t size, qbs *requirements, int32_t font_index, int32_t passed); +extern int32_t func__loadfont(const qbs *qbsFileName, int32_t size, const qbs *qbsRequirements, int32_t font_index, int32_t passed); extern void sub__font(int32 f, int32 i, int32 passed); extern int32 func__fontwidth(int32 f, int32 passed); extern int32 func__fontheight(int32 f, int32 passed); diff --git a/tests/compile_tests/font/.gitignore b/tests/compile_tests/font/.gitignore index 4d7f4de59..33f955687 100644 --- a/tests/compile_tests/font/.gitignore +++ b/tests/compile_tests/font/.gitignore @@ -1 +1,3 @@ -!slick.ttf +!LiberationMono-Regular.ttf +!LiberationSans-Regular.ttf +!LiberationSerif-Regular.ttf diff --git a/tests/compile_tests/font/LiberationMono-Regular.ttf b/tests/compile_tests/font/LiberationMono-Regular.ttf new file mode 100644 index 000000000..e774859cb Binary files /dev/null and b/tests/compile_tests/font/LiberationMono-Regular.ttf differ diff --git a/tests/compile_tests/font/LiberationSans-Regular.ttf b/tests/compile_tests/font/LiberationSans-Regular.ttf new file mode 100644 index 000000000..e6339859d Binary files /dev/null and b/tests/compile_tests/font/LiberationSans-Regular.ttf differ diff --git a/tests/compile_tests/font/LiberationSerif-Regular.ttf b/tests/compile_tests/font/LiberationSerif-Regular.ttf new file mode 100644 index 000000000..5e5550c0a Binary files /dev/null and b/tests/compile_tests/font/LiberationSerif-Regular.ttf differ diff --git a/tests/compile_tests/font/slick.ttf b/tests/compile_tests/font/slick.ttf deleted file mode 100644 index 9d03461b6..000000000 Binary files a/tests/compile_tests/font/slick.ttf and /dev/null differ diff --git a/tests/compile_tests/font/test.bas b/tests/compile_tests/font/test.bas index 987d1fe20..4ab92a161 100644 --- a/tests/compile_tests/font/test.bas +++ b/tests/compile_tests/font/test.bas @@ -2,44 +2,768 @@ OPTION _EXPLICIT $CONSOLE:ONLY CHDIR _STARTDIR$ -DIM fh AS LONG +CONST FONT_FILE_1 = "LiberationSans-Regular.ttf" +CONST FONT_FILE_2 = "LiberationSerif-Regular.ttf" +CONST FONT_FILE_3 = "LiberationMono-Regular.ttf" +CONST FONT_SIZE_1 = 12 +CONST FONT_SIZE_2 = 16 +CONST FONT_SIZE_3 = 22 +CONST FONT_OPTION_1 = "" +CONST FONT_OPTION_2 = "monospace" +CONST FONT_OPTION_3 = "automono" +CONST SAMPLE_TEXT_1 = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ 0123456789~`!@#$%^&*()_-+={[}]|\:;<,>.?/'" + CHR$(34) +CONST SAMPLE_TEXT_2 = CHR$(34) + "0123456789~`!@#$%^&*()_-+={[}]|\:;<,>.?/' aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ" +CONST TEST_IMAGE_FORMAT = "bmp" +CONST TEST_IMAGE_01 = "test01" +CONST TEST_IMAGE_02 = "test02" +CONST TEST_IMAGE_03 = "test03" +CONST TEST_IMAGE_04 = "test04" +CONST TEST_IMAGE_05 = "test05" +CONST TEST_IMAGE_06 = "test06" +CONST TEST_IMAGE_07 = "test07" +CONST TEST_IMAGE_08 = "test08" +CONST TEST_IMAGE_09 = "test09" +CONST TEST_IMAGE_10 = "test10" +CONST TEST_IMAGE_11 = "test11" +CONST TEST_IMAGE_12 = "test12" +CONST TEST_IMAGE_13 = "test13" +CONST TEST_IMAGE_14 = "test14" +CONST TEST_IMAGE_15 = "test15" -PRINT "Loading font using filename..."; -fh = _LOADFONT("slick.ttf", 10) +SetFontTest -IF fh > 0 THEN - PRINT "done." - PRINT "Font height ="; _FONTHEIGHT(fh) - _FREEFONT fh -ELSE - PRINT "failed!" -END IF +DoFontBuiltIn TEST_IMAGE_01, TEST_IMAGE_02, TEST_IMAGE_03 +DoFontMemory FONT_SIZE_1, FONT_OPTION_1, TEST_IMAGE_04 +DoFontMemory FONT_SIZE_2, FONT_OPTION_2, TEST_IMAGE_05 +DoFontMemory FONT_SIZE_3, FONT_OPTION_3, TEST_IMAGE_06 -PRINT "Loading font from memory..."; -fh = _LOADFONT(LoadFileFromDisk("slick.ttf"), 20, "memory") +DoFontFile FONT_FILE_1, FONT_SIZE_1, FONT_OPTION_1, TEST_IMAGE_07 +DoFontFile FONT_FILE_1, FONT_SIZE_2, FONT_OPTION_2, TEST_IMAGE_08 +DoFontFile FONT_FILE_1, FONT_SIZE_3, FONT_OPTION_3, TEST_IMAGE_09 -IF fh > 0 THEN - PRINT "done." - PRINT "Font height ="; _FONTHEIGHT(fh) - _FREEFONT fh -ELSE - PRINT "failed!" -END IF +DoFontFile FONT_FILE_2, FONT_SIZE_1, FONT_OPTION_1, TEST_IMAGE_10 +DoFontFile FONT_FILE_2, FONT_SIZE_2, FONT_OPTION_2, TEST_IMAGE_11 +DoFontFile FONT_FILE_2, FONT_SIZE_3, FONT_OPTION_3, TEST_IMAGE_12 +DoFontFile FONT_FILE_3, FONT_SIZE_1, FONT_OPTION_1, TEST_IMAGE_13 +DoFontFile FONT_FILE_3, FONT_SIZE_2, FONT_OPTION_2, TEST_IMAGE_14 +DoFontFile FONT_FILE_3, FONT_SIZE_3, FONT_OPTION_3, TEST_IMAGE_15 SYSTEM -' Loads a whole file from disk into memory -FUNCTION LoadFileFromDisk$ (path AS STRING) - IF _FILEEXISTS(path) THEN - DIM AS LONG fh: fh = FREEFILE - OPEN path FOR BINARY ACCESS READ AS fh +SUB PrintFontDetails (handle AS LONG, testFileName AS STRING) + DIM image AS LONG: image = _NEWIMAGE(320, 200, 32) + _DEST image + _FONT handle - LoadFileFromDisk = INPUT$(LOF(fh), fh) + DIM fWidth AS LONG: fWidth = _FONTWIDTH(handle) + DIM fheight AS LONG: fheight = _FONTHEIGHT(handle) + DIM ufHeight AS LONG: ufHeight = _UFONTHEIGHT(handle) + DIM uLineSpacing AS LONG: uLineSpacing = _ULINESPACING(handle) + DIM strPxWidth AS LONG: strPxWidth = _PRINTWIDTH(SAMPLE_TEXT_1, image) + DIM uStrPxWidth AS LONG: uStrPxWidth = _UPRINTWIDTH(SAMPLE_TEXT_1, , handle) - CLOSE fh + _FONT 16 + _DEST _CONSOLE + + PRINT "_FONTWIDTH ="; fWidth + PRINT "_FONTHEIGHT ="; fheight + PRINT "_UFONTHEIGHT ="; ufHeight + PRINT "_ULINESPACING ="; uLineSpacing + PRINT "_PRINTWIDTH ="; strPxWidth + PRINT "_UPRINTWIDTH ="; uStrPxWidth + PRINT "_UCHARPOS ="; _UCHARPOS(SAMPLE_TEXT_1, , , handle) + PRINT + + _FREEIMAGE image + + image = _NEWIMAGE(strPxWidth, fheight, 32) + _DEST image + _FONT handle + COLOR _RGB32(255) + _PRINTSTRING (0, 0), SAMPLE_TEXT_1, image + '_SAVEIMAGE testFileName, image, TEST_IMAGE_FORMAT + + _FONT 16 + _DEST _CONSOLE + + AssertImage2 image, testFileName + "." + TEST_IMAGE_FORMAT + + _FREEIMAGE image + + image = _NEWIMAGE(uStrPxWidth, uLineSpacing * 2, 32) + _DEST image + _FONT handle + COLOR _RGB32(255) + _UPRINTSTRING (0, 0), SAMPLE_TEXT_1 + _UPRINTSTRING (0, uLineSpacing), SAMPLE_TEXT_2 + '_SAVEIMAGE testFileName + "u", image, TEST_IMAGE_FORMAT + + _FONT 16 + _DEST _CONSOLE + + AssertImage2 image, testFileName + "u." + TEST_IMAGE_FORMAT + + _FREEIMAGE image + + PRINT +END SUB + + +SUB DoFontFile (fileName AS STRING, size AS LONG, options AS STRING, testFileName AS STRING) + PRINT "Loading font "; fileName; " ("; options; ") ... "; + + DIM fh AS LONG: fh = _LOADFONT(fileName, size, options) + + IF fh > 0 THEN + PRINT "done." + + PrintFontDetails fh, testFileName + + _FREEFONT fh + ELSE + PRINT "failed!" END IF +END SUB + + +SUB DoFontMemory (size AS LONG, options AS STRING, testFileName AS STRING) + PRINT "Loading font from memory ("; options; ") ... "; + DIM fh AS LONG: fh = _LOADFONT(GetFontBinary, size, "memory," + options) + + IF fh > 0 THEN + PRINT "done." + + PrintFontDetails fh, testFileName + + _FREEFONT fh + ELSE + PRINT "failed!" + END IF +END SUB + + +SUB DoFontBuiltIn (testFileName1 AS STRING, testFileName2 AS STRING, testFileName3 AS STRING) + PRINT "Built-in font 8." + PrintFontDetails 8, testFileName1 + + PRINT "Built-in font 14." + PrintFontDetails 14, testFileName2 + + PRINT "Built-in font 16." + PrintFontDetails 16, testFileName3 +END SUB + + +SUB SetFontTest + DIM image AS LONG: image = _NEWIMAGE(320, 200, 32) + _DEST image + + _ECHO "Current font:" + STR$(_FONT) + + _ECHO "Changing font to 14" + _FONT 14 + + _ECHO "New font:" + STR$(_FONT) + _ECHO "" + + _DEST _CONSOLE + _FREEIMAGE image +END SUB + + +FUNCTION GetFontBinary$ + RESTORE Data_Script_ttf_118784 + + GetFontBinary = Base64_LoadResourceData + + Data_Script_ttf_118784: + DATA 118784,69760,-1 + DATA eNpcj1N4NEkYRs9XzdhOKpWerG3btjUdO722bdu4WkZr27Zu17Zre/DzlHmeFwGqOAmHZKvNt9iSGrkSxAUad9ptpVXP/faYW0BeALK943ESvLRiCOoskNt6 + DATA jzjMeG+2HA6SBVYcSAbHNznKXgH1R0GwzWB8aAJUA/8A4eDY0QNtcyucAN0rI3e8NtQf9+kr/1ge5CJgzaF0o2ot/2WQ9YHuofHDjrph+W1mINgf/P3HJnvj + DATA 4T/eXQHc5cFZeTw+KlFHhiFIO2Am4vH+p69/436oeAD8x5LJQw/7suro1aDtGQiHk0P6E7vZEUuDShtZBLGWKgQop4BCELkivycgV3IBQfGkm5VYHzgi2AZV + DATA OA/e+PcNKDn6v+P//Sr8HGER5EoW5iMOzbdD/Tr7m7+hW2Z/+/dtv37BHIreU/3tH179oKr1fzUlIQAv/7LTDQCvRAcMp643ws+Dd4EQRQHH3U0uwgPvGm81 + DATA kM7C6LzJgAIUvhO4+Lg3wT07Y7alyG67b2bYGP5W+SxpIrWygUsBSGQFwCDbTb2w697TIhfs82BISK+ZkszmZsrJJFP1WxgztXR2wJyzx95Taol4SrbozfRM + DATA qczmsyWljlputqw619c0pv0+M+7SwRa7bp7uuWq5B8SePuWeP+2xOaAAB6jHQfKjmyaCLBvjYYASKmjhBNlaTpBL5F/VotZSz6tPnSe0o8t0p95E76VjPapP + DATA 1z+betNqtInMkmZls67Z3NzZFXUtGanIj6qi2qg10tFy0dZRNupf4qXfnv5bWQuAUEEDhptk29Twj2pODc+pD1KD0qVa6431njqrR/RJ+idTZ5pNuzF5wzqL + DATA GWoWMvTlDaQGQdlf7e/2R/uGfd0+Yv+nZRzU41rAKHomZxDbtm3btm3bttHYtu0qtlWPatvt3LzB9VqffuxthVPAMf8u/Z36qwnrhLXBamG5sGRYBAaHeYFJ + DATA Q7ujXdDOaCe0PdoMrYdWRV2gPFFuyGxkBjIBGY+MQIYiPZG6SDGk8N1NwkN41WX7/0/eX/ABRBVyBy8VlALfQvmhMdDrMClYFmwKhoEj4HLwGjgGkYxPg99A + DATA oEuwRShIWEXESeRDNEn0gViROJ74DcksqTfpD7IQshfk+RTSFDuUZZS3qSSpTqjtaIhp8mjQtK607+gK6UnosxiIGEoZNRm3mMyZjpk5mY2YG5mPWSAs4iwT + DATA rJysRWxsbCXsdOyVHFwcJRzPOaM4F7nKuQW4k7l/8hTwfOX1473L58u3zW/HvydgI3BLUEcwURAlpHJppTC18BORSlFT0W4xc7FycT3xDQkhCV8JX0kNyWjJ + DATA m1ICUiPSstKu0hiZbJlBmeey8rLlsh/lDuXnFNYVNZSIlc6Vx1XaVDPVfNUt1J9qdGg6a/FpfdP20N7S0dRZ1nXTY9ar0ifSrzQQM7huSG7YY2Rs9M6418TH + DATA lNA0y4zCbM7c3oLAYt8y10rD6rN1qg25TYOtrO1tO2O7WXtp+zkHc0chx04naqcaZ2HnaRdmlz5XO1ec25x7vAeLR6uns5eg1773qI+vr7LvE79Yv1/+zQEy + DATA ASuB+oEfg0qDdYN/htSGmoQRhzWFh0SQRWxEmkeRR/VHp8YwxqBii+Ls4hHxCwmWieSJk0ndyZ4pTqlkqU1pImn16QTp+RmEGfGZeJn+mTNZ+lm47LzsLzk3 + DATA cyPySPNG82nylwrECy4KNQoxRXpF34tdij+XDJaalpGULV0pKCctr6mgrMirpKlsrpKr2q+urJGpeVEbVydXt1ff0qDccK8xoImxaa7ZvvlxS0erZiuyLald + DATA oH2pw6XjU+fNrtJu+e5HPe297n1sfZj+gYH4QZ7Bs6HZ4agRgRHUaPOY8tj98aQJxomzyfwpoWmpGdjM6KzObN7s0uzPOeU5r7m+udfzKvNFC/QLO4t2i++u + DATA tl8LuE52HXnj6GbgEnype1l8eWnFcpV79Xytd91yQ2nj92bnlvlW6tbQ1v1t4m3l7eLtezuiO1W79Luqu9V7yXtzex/22fbvH0QfvDl0OMw9nDn8eUR/5Hd0 + DATA /Zj/uP34w4nESdhJ+8nWad2Z7tkThAgQDvxL8GIAALQDOsA0CBNsHwiGugLRCBBogGYCOpC7ECbwFECBpzgZKA+EDvoOKMXLwP0CW4BBPAFAAlTDuUO/AXmg + DATA GlAKlQRooMaANVQZiIZaATrQcKAI3AbuX+49/yCkGoAtSYJgTnf1w9q2bXzjjG/b9n862wicbdu2bdu2/fqqYmfWiImMzBrWFJJ1izoMGfKsGY9j+D2n0ts4 + DATA jWbgIn8amuk7W0QdqKZd0WAGopBGoYDmII2eQqupsHeoC+xXenb8IvreXkKz7Ov+iJ1rrsZck4YY9dg7mc+jf+3j+hks1Y/jELKYT7cg5j8WNdRlQ3QZZpK2 + DATA X+hFnPsdqNPz7JFUiJsoPX6H8xD2pmKk0mrk67uQQVEU8Tuy9Bz7Bq1FFvVbq/ZCgsqIn6//YZ2CTN9RUHQQYzL2pDZ+/y78zM6YohsxTn2AMHVjGY1Bqk9h + DATA d32ffYFakKT77d+6BW0qAqtb7EFkcYgql9ojQX+Bs02hfZFORSddg7AqxUd0LQbobOT7/sL5dCTeM1k40byB833XAOZH3K9n4niu+8dcyxP11Thbh3CuOpX/ + DATA 6Wd7l/kaSepV/K46cLJOxr/6P7xhCrmvX+JVQWAY8rj2fqn71uAP2BbuRaP0YWNIHzYG9yrB68PmoNPxNPO+0otNIL1ItOfTAnuW1H1r8M1FKvciXfqwMaQP + DATA G4NWItvrwxb4CRcKSy82hvSCOm0+Ccv/liN9E5YceA71A9h5WywzKnPCnCAstZH8tsHZXizzTGu3zTLrPG9xl63UWP5zS45/ohrsc15sHrVf0fFIkB1RO8cv + DATA lT2RWRXIvvDMpq5j+4uwvh+ZpoL5G2S619Olj1LLLfh0jBKWnko9N2f/apzjS0C17J/swDq2h3mx7KTsxTb5cXTxzvhlb/XfOEWY47kyK9KvHbHZD63Csuuy + DATA bzJf0ltv52XvNmd9T/wgmXHfAmR4eajE+LnqdYzUQ1CoHkKZcz/7V4IzWB2MMr0E+/G+zTBT7SfiU+IV3gyIT4lXiCeJL4gfiSd479X9yBFP8PLbnL18fYSb + DATA A8fhbjXbmcCYr2YjqD9xZum3nPn6NtZf4hbGMfoQfOY7AMuD+/HO5/DuFyPC70iifxAKXOfk+e5AE8cJJhdjTCnOMp3YjXfhUHMd0kwYPXSNLTF1CIkHm4vR + DATA wxzj+yuVQoFvOXvef/ZlM8E+C2AYHoeGQ0EAd5oMVzsYYZa4WmGImeZqjSx61dWEGXSzqw0m0Jmu9vH5mKv9KCHv2QDPjXJ1EBP0l64eoPZyznf1QMxy9nf1 + DATA IMxxilw92JmGVa4ewgquHgHJoQ0RPvqQhKV8hNGIENo5jrBewmhHF3Mvn23l67nYDVkoQhufD2MaR73oQYRVIasWVvugHiE0Y5p7RxdzI8c9HDWjic9EWTex + DATA DrGOoA3/c1LWam7FQBg9j6IqHFOZKsxMvdYMFz7rGl8+cAKrZTRr5ieNNLT7FW8JfKC2Nkd+S45wj8B3uxNTawJdWj5DpizjzdRE1kQ9RQ5YuLJhqo5AlPcR + DATA n/zc8IBwrXw2/rfQHXMTqVRUEmnRp6L4X5XsnrvasDOBfzVPqFiJPVRH7iRQmOiUFYWOKzYE+pgcSyLJBA9YsiIxYWd/Q8R8CLkjQsYfeHRRp9WLTJOcKmpw + DATA b6xe2DvSZXA1UbsDO32U/6ci6bVWTzKPMXafmsMGcyP5eShTsOsYi25eUlm1dnZOQ7xJOjdFlbrihDNi9d9doe/hf58FCffHLufciTJDsRbu+/kuEgUmiJrN + DATA ZM+QlKnRkdX22JH+nTV9bWlo8eboFHquIn0mfMnmL/AVJwATonXBBJqPzguiKMF7IFwZ9T6fGTI208jy1DPeoUPvNEXHejPu/8zyeqIv7LeqR4cuvWMrx3vF + DATA pWbnzI6ZuLu36HM7w7h3fh52XOY2uJ3fVipLprR2t/M78z2RQvyflFlXettGEF6wqbqqC3Iy5ESVS7rbKq4Ay+c8uRtIXhZq58gzTjOQcoDcLP6HAOHe2PDP + DATA 7D91Z6HC1ldybsGjEWPpWMidspjn0UncEQ8Kkv+eS23jL6n1/46a3PTTiOT586gpT2KfZFfRbhyTTPWTY9mCCERyQ8ENMGAe0SmlaUIy/Txy0JCuTSu6p+ie + DATA 810cx76YdhwXsRG8YmWCA2ngbfQdSiN8EclE2D4zngldIIsna+BVLdYIISv9I/H6h67XkVqhg0vOGrV1R/2UEzouYhtf8xPyUcM4olTXOenBtm6zer0vXgLc + DATA sOI5Qm3hn8oC4CCWaZVeQpqG1JEJDSaV9aDIK5sCzqbxId4iExwjFhi19SBNCXlIY6fJCDDGfmGP90iOEW+IKEMn/xx+qCszZo574oViHp15nodQHZm0man3 + DATA X0eGHDyez8x4JkhdNlFp+y3kNmWl3v4uY9pCP+MoZJSqaeD1ImJ6AJHl6sma32yCNmNlui3TOx2ZtURD+pAWJ7us/2f8XOmr2YVxemiFzO6It3BjFPWi5vX1 + DATA pUuW7iJ2Ry5bI9XcH/YRrktoFv81+ug94t3skreArK5YekDDDwmgpcluR67a7tKDjsx9ZRWNPAJj3mYVs7hOXRrqnKH6Z2k65CEnh+JxcDbneQvzCLBgERZ7 + DATA iJeuwrx9knaZ6EEKL4vlKjyN1knqHIBE4nRwnryIzqtUI/+8ulFbjYOASSZDTMCIzAMn9RC77XRk88NSDd0xSy1Mjp9HEBIf2OmYgpYgLg4lD9Bmhp8B0sZl + DATA 5MtR4YrVF0Nw2rP6eoI39LBLCHmq9yo+cSB8bsYfPGIPlrQcInjaKMrhB6hyWdXImwOsDXio/rXLK6rXzCpFb8zrqEsPGJNdKZVw9qF5jXVIzz78a7qYmqKf + DATA rKOzWgQLxw11em9CAeOe+5apq5UPcBYfxN1sxptvd2StVD//WH3tU/ZXOb8h5EI+BzjL2Pe5rlzB3v/+DT1hur35ObkK3LSiY7JhZaH91by2rSy2U+Sug4Ea + DATA v+Rgq7oyA+pmOU1o/3jaGCPc5d3C2x82m8QN5denbvhrg4YUMRKIzTjQH216My4SYavzIC3Ada19XO6Wltvkol7e/bTCllbYRw9okMJbYbNjZal00FZBfCA7 + DATA QmtAHTVT4RqErpXlkn0dQs6+AZSzbwLl1FtWVkrqbQg59Q5QTr0LlFPvWVktqfch5NRdoJy6B5RT9y0+Doo7nOyXtzCDR/Ed0P+n5jRHX/kWCt89eJX3LNaD + DATA dQQAFACw/Hd2bdu2bdv7b1FnikQikpGKdGQiG7nIRyGKUYpyVCQkpaRlZOXkFRSVlFVUqVajVp16DRo1adaiVZt2HTp16dajV59+AwYNGTZi1JhxEyb/FzJr + DATA zrwFi5YsW7FqzboNm7Zs27Frz74Dh44cO3HqzLkLl65cu3Hrzr0Hj548e/HqzbsPXwTBA6wYBgAA0btocWbbtm3b/rZt28ZQ27ZtpbZtpm7fCyCQIAbTi1LK + DATA mEI7+yinnhq6MIDeXks1GyihhROcpI4OKpnFFo7TlYGc5hRn6MkQFjCPoQQTQiOhLCKM+SxkGYtZwlL2E85KlrOCYURwjCbWsIrVRHKQw1QRTRQxxBFLPN1J + DATA IIlEkkkhjVTSyeAAmWSTRQ555DKeHhSQTyFFHOIIE73O673BG73Jm7nEZW/xVm/zdq6Id3ind6l3e4/3ep/3+4AP+pAP+4iP+hhnOefjPuGTPuXTPuOzPufz + DATA vuCLvuTLvuKrvsZ51vq6b/imb/m27/iu7/m+H/ihH/mxn/gpO9jpZ37uF37pV37tN37rd37vD/7oT/7McEb4i7/6m7/7h3/6l38bYCAXuMgudhtksCGGGma4 + DATA EUYaZbQxxhpnvAkmmmSyKaaaZjqTzDDTLLPZw176mmOueeZbwDq2s5FNbGYb69nKfxZaZLElllpmuRVWWmW1NdZaZ70NNtpksy222sZIRjGWccxmNGOYQzEz + DATA qWAQc5nKNCbbTi3d6KQ///IPR+lDM//TjwZaaWOCHXYynRnXXKWyLnTb54EAgEsF+1vTPUuZxGUc84Se66XuUkdy4tHTf6nv/s1NkN9Z65EzckbX6/UG2kRb + DATA aBvtoF20h/bRAdjooF20h/bRATic8OFBSBsbLkA2fLPqUzHh4cM4jI364AIMxlJb6Q7vkfoOZB5Xxts4FVIqk1bkKWQTKY4lt8Akqy9SPsWGCmRTaKg8lWle + DATA SJ1CPsUxFMimUFF5gjkZKiRDzfNa4SmszmV8OAg8hOQQLEidXR6XFm/ClnbZgy1THW0V0x6+xE00yJawifbwJc6swcJyVdD7YEV67PO4uqZTffw5hFYpEwmz + DATA 1ZJthHSpYpGnuqGfi8iBbeCCIk9pk21firIHu4R8A/mXNN/Q/EvIN57i1IRFZUJ+hQvHILuChWPP+dXOmVBYd4iES89jemK30NdC31va19K+t9DXAneQlXiC + DATA O3J1Cbm6e1otpdXuoUzqKd0fX2OaPdgDvEbn4Q+4lQPZA2zlPOUHq01Ydsfn+cOfDR098Qd83Q4Mnsi0XyR+IfFPHrNX2PXXU3nNv3V/TyEfTv1XuVDe6h3d + DATA PCGH/7KcSCXJnjujG9N6E22hQ3QENqboDGzX0QbY6aI9sFtHG+gQHbGn0Irs8r6AJ1jqy3P2tNXKqkQnZ1//IvYCH/zxlKbOxgHZo/Du/7ko/C+Ggv/v2O+y + DATA czNIAWtkACVfAd7GlbU9d2Y0YzEzs4UWS7ZkWWbGOMbEiUMOo9Mwp2FsQ6WkyabM3cIWsszMzKXl/beQtttm8t87Y1lJvu4HT/1Y5MZz3vuec94D47Lnc04B + DATA hosDGk8ilQbpVCqdittjWo2KogFNUTTltGOaGHw3rdHEY+lUwumgacrh8Xi96E34P3i8Hgf6QZr2pBLwKXxGaeErSqX5fI9RDVJZv1cZrCX3DWlojZr5fC7s + DATA UUfqPnocuK0VA6Ge9urdPYuaI2qBUOdpTwcVzmWvrp2h54sVKv9Q0yz/0ha7uUwUbzDXkvTgsst1crmiZay1iQy9vLNBEahVJmpaPnr2s4eySj/YKq4Jz1h5 + DATA z6muRB8lUmTn5DacuDjPJSLUZoHGWOMdX5t+6nDSZNRX9Vx69/z+pNiiR2hcuv4O8TClwLRI+RREALOYBXxMC7RkWaCgIgAGcIDhSQzHUxgAQuAkns4GgCOZ + DATA UCqg/amYBmFF0TiBMMAhitx7ahVEzwM2RReOrM1X29J+mbN8KHtsv0QpUP/aYNZ4B6sNNdHw/DzYffjzIATE982Ul5WVyWKZAyuZD5hzrqw6yLxQ2Z5V2ERi + DATA W649kxDoMRwYyb2kjToLr7YCXq1CrwOY06Gr0FcIBeiaKXjNEgIADKR5OElgWBhnr9bjRRc2fWnccVH2//A+/o5YSYulkuiwJRNUeExWTdydrGByn/QuuVer + DATA 9C2eF7lo4vPLFBadyWVpbFuy4BPfhGgvv36V9xylxJqgQpxb8Dc3A6y5rbmttaWhLp/LVibjFeGA3+N22EwGvVYpFwlpCmsCTQpoV1guFRGkmIDHQUILfXxA + DATA 00KHRIjzeBTAvIIynKIkDlyGo10wJw/azXMkoXVKJwHN4p7a4UM6pY2ni0+UqVQMHhVReoK+U04nXXxCUMq0k8Z/bzdKBt5ZZa5U18EnzAdVtkr/+y3Mv9Hj + DATA e8e1fUsln/od9/D7kLUy9oWev6GH76wKplre6BFY1LV+IGW+1mGZehrw2XP4H9jv4PNV6YChnMlNPykP2HJ/QN+Yr03is/7wBwxgk8y/yIdpL1TRMwqynu5C + DATA TcDv9ei0EhEOaIhNlgY4lcviPBAFBI+wYxiFpSFzeTjgJTGSIDOQvwgljKKEDozHI9BzghARzjJEENZ2itawJjsgKdKIFKwzq1VaDctx+LkEh46P+DLNGzUN + DATA P0bhIRHGvR6EKeSSNp0iBb5VuurmS60j6+PmiDpzjIf3Ht8QmN1qa7W21SZX311vcAW9VFmZxLHBXmZRe13d/D5jV17ti7TOdPd3Tf64YYHOFqJFRpfKOXxs + DATA /He71h5Vu9Kq5MHtXQO16fWXxjbEF6V3fmFXZEHZyfkKmTHhyM0Jr7d2tBsq+OqWzk1BqVETWj9nbH7VvjvuPPL9Jg0xuBXjYXfDXb01lAZTwGonibXCOmSo + DATA YGlv87j7Z7SNtI+0NtdUV4TdSU/SYlKrRAIciCC6MQEgMZwiccg6CCy/jOKjZzwegCgSAAC4AgXgGiN8RQOWfRQE1cVyLpXG0imWSzQgFDBwcijFUYiV4LxY + DATA GmGHQqgEhxETeBJ5fPpTdBbpW3/iVNfitKmCeDDZvyQ696Vr5/9+aMX6cVfbrv1PP1Olsma6mfcSVTPtAh4tzyeSMZUfn1RZq3qiSye5jyOLV195+eafSGSc + DATA 5k53Fbmzeo0tuP3NaxbmL/ivfHZ78+GHz124O7l99dLZoH35fZG8V2p1186MLP3iNSyxfc3SMWcn96mzY+XNn6NqtfH6VfIopYLV3cKCZniwt7umOp2qCAV8 + DATA FrNaKRETQACRbW4COAB2DI09+SAJGQu/4hhOwq84RvLgVxxVtQRycR/al0S8LSuDHCYIyHkvRtMi2ilAHEaZiYIIQbJOh2AEmXqKoemUF5KXAzeO3kCU9qKo + DATA h3CeIq/HWzqBkjPAHybeOXrpxEynQim1+qLtIanJEdi0Orhg3DY2bG/G8R61Xij3x7XhAW/fmDUZdPdMEm01xz/zwpz256rTy1zCYO+axrMPPjzcOrFgVsLv + DATA kT+V1fDsi++ZtTzRn5S7+SqlxGSI40SiN772ti3lEp+1oX2OjoKLiGGBUlsm7anXJ3GpNLMxtnpR74pfPlKlCe32r96zcYmnf0Hv5OaNtwXL8/w5Y06IPMoR + DATA +FY2R5gLAoBxmYGAaAsxlBhw8D+kBdD9fwj0GMB+z5SRP6atmIv7fVoN5gIu9vfhAAMoDgHu97FegLIkTJdylXYqqjhQ5JApFOyFkI/6g31u34mnN4UXNteO + DATA KkUCXdPswS5zTc3SI53HP/UkbbWpnDUm5+Hr2Ou3M79mvvyPVx+tFpm1fFV2ycnBV2DtmgTqdxdd2YUWnK8nmTLCB6/MwV2ZWoU5gOMTkCAcSS7iKRXyhHcK + DATA lZgF12pkOM4Kmov+UK/b9/t7v9dUM1spEmpvuiimjLuoHwMfLG6/+7crDxeKlzTwKnM38y3mr9wlAXgOJHGNUmMZLIO0hr+cX4ZlQAZpDVfUgWO4TowTAMPt + DATA 6BvAMeQTAEekx3E5cJIIRg/NcdPhhZeKDoyC18txN51CsVqLqMxxmAUcvYBPie+e2BOfbFb4+NVOXyLc50r57KZU3y6rvt4htaljoahY7mrrsPCljhnNiUUT + DATA IYeZXEe3RdZUVJpo2eJszuRtc/iMyUpLLjc41hXSeWPGupDy3km7zOEUueX+JSc8bRq+x74A+f8x7F2oVf6CWbF8QQEwo16tlEuFfB6BWYGVRvZiBI5BMz0k + DATA wHkAmYtcnCBQGIXejh5dyF63IymfStd2uYcNpnI7l5ztcvgdX1rBnGvU+D2gGdeVO6JgZ0bjCzPP67zvZsDOqEPrw0GzR1feyJyrcGrLmefD2nLIjWvMb8Au + DATA 4MHUmPZ5iRhiDS9JwNICm2IFjNaIFckEihuc0JPgezuy6sgsn0Rp6J6ZUbjduQ6GsQe1sbHWmgaduyas0wR2TczuQQg8hpsIJf5DTIz5EfvKeJgYiBD7dOxi + DATA OrQcfkPWIjdB1iJlqeQsnTLw9Upzwgy+GzTH3bgpWO6swcv9zhr4s9Hr74CNwIdJMemnKR4oCzyHrhrAfyB1iwRt58SmMY/EZuYWQQlxmAv3mc5DH1FCHMTC + DATA /4ADcg/AcooTCpi6Y4mumxgb9xnr5kXa5c6P08zP4i6Lez8leLg5uNgbXWvIftiA9PV+mAeuQ8WnwfxYuiABmMNu0ImFmAZoePBXQaITOLBDegPEcpRLpzhA + DATA ghuEnCcZSSYUqSKrKRzFKi7kEzDGa2J5Ep4U+NI9F2esOTvyxe/9qlYjblp7evhz4LEdG0/uX7hERtWtWzQxb6TT0ib4wsv2TSD34c97Hvtpy+6HmHfe/3nP + DATA o+S7D734+HWMufra2LLs4qMPvDD7z0cRi6+/TzRBvWDHfC/qtGIRDtABGvjIKe0oXcGzQ7UBvGr2ahFh0yxeCvgfim5TGYU7EglB42/Y0qJLya/ZenbbglaB + DATA 0tba7GiYbE6pQqS9siP8L5neqDKBTYdw44WZOkoiVMfMtpipcpFOGZh/90s/WHHtFcQtNUS1DmbXNmykoIMauqmhLpUMBmxWqUTAp3lYG2hD+bWqFuA0vFAe + DATA iZJpkg8wmsRomGABjSP+keS0KCwDNF3UMyLAykJ3jMuNHlTglUxJpTinKKpDtWr6sxLxUNxJpeCLWB4n1sON7uqFTc/O6Y76lOVmk8jkXn2g47e3x1eNmoZH + DATA rIWIylk7K6P02KpnJtf/YY+v448bNn/2nmznghrnrJW9ccfHa1v08UqDTCc2ycQWx9A9Z9t+eaTx9MYdbmHc2z2rX8WXuywZhymzZ/H8IXtLLjLr2J//sW3e + DATA XTv7HDRBlKkNaoRZP8RsEcSsC+stKLo6W1vyOVTO6nViEfROiFY6ADCWiwCdbJIGGA9gSIBQgEfFMQCmVDM8bIoikfogSRHJKWh05HkcAfM/4KKZlnYlJUix + DATA uoWTKTIn+L43Kpt9Z25/18b57m6EzUhG5XXVzq7c/Oc95W0/72kbsAkc+ZHMpqMne5vC6aGo2u028hUCoWH5hHfGCnyGpSkqMw7mjz7XNRz39g1P4WPSJ/Yt + DATA XTjibMtFhk/+7TsdbsOka/byhYP2po7a2a3VTWp3wKlwZOxic0NyDeBBxNZdf58MQsRqsPaCrDqbjPu8ZqNKIRGSBIrg8RiO8zADhAW3YxSkGAV9ASJNoJwF + DATA 9TFG4KjQ8EGYIGQ4LsJZYQxUxFTZ7PU4kQcjMNiUlWbJ5vXAZ4obVDCNOg8o+rBvkZJ93nKX1KEyRcI5sWSyakufz+ULDn4ms6zdJ7MTmr0XNGQi42pw5bp8 + DATA K6Le4T1bQ3USrUJeqEwTH6xg/h+hlZeHZSQNfjL+Hbc32zHnizKNR5+sDb4Loh+6TKn1Ow7f2fRks4Y/+XB7/2DAX1SzP4dRrA9bVNB0tDfW56urKsNBrwfW + DATA CUoUNpG3tfQAPo2hWsGO0RSfovlJqGwpPgYpROIkD3URCBIn4mUAeRyEBcU5iJgExTyACIV8j5OzJcbcRBUacQvCMe2DFM39AHxHUSRaLIU6M3FO0iEOIp0A + DATA Xl/xqXWB2f39R84+emyoO5FsiyntUmNww/y5g5XpheZCY605JVW4tH4Sd+1s0MjFpprawLpjDQml06m1pOxq76r+8MJhzVzi29Uu3+BTFx64vHh1f8ea7nyN + DATA WKcLNlRvXTB6+MCG06YyZ9ySEhkjTkMHoJ/sCSlDUr5OIOPL5HhdvNcmVIpFOs/6F1F2OAxxPQNxrcBqsUJBUqhJJ8Mhl9Og59Ool+G3AZKHPBIByENUAmAK + DATA Mxa/UhlLcamvlCIQcBxsyCVZGpXyIouKgvW5eKnAop5yFVafGXj+hZ1N+VSis9rv1h/yjS9eONc3MzDneHTlRPnASPft23+x50KlSGKt6ezdEZJIpfbtW750 + DATA 71vA8u/vtd3b2fDN3h4R3+MIOUUNo7ZwcvaOtjOPrfOIA/6xyw8f29Hd0Q3ef2V31pDr2vCF/Ly8NtaH2PUTtPdKYVgE8xUEVotBr1GJRUgTavlTEYm7r62c + DATA ANMtqLQnj9fgqWKO4UzlYghnJjx61moVwuGPYvmc/T33HC64X/50piOvC9l0Nk3cOfbspsgAFAyqiKEl9timdaFxktb2FUac9//zr6t++ExPutctFIu0UWtd + DATA Bw7UYqdarBXatMmGlY1/ff5LC379ab84aNahjdB58BwXwzxpwMqxFOZ/sSKsVtI8lCuNPqOEQEUel9txVOF5S8kSsMdRqr846QoPScbzsgyn2Wiq0RLFQg6d + DATA pxf/7eqdmx98cqThZw2dR/bueOWJ+bOYTR1Xs6mZXZX5OmPTWxPO3jpjttqAP/PSsQeWLVjau+SzhwLmr3/lG4f34/jiOWeZZ15YvfvD22uq+FR9y4LZZ0LM + DATA V7q/uj8qMxkqOxtXOxHei+DW93KWmwXYdVFFI1WVkUK0EA7ZbVqNXErz2JxRDiieCuAU9PmiYqfQ3XqoWUADHq+UMwAo5Qy6qNQ4p6aoKSYqKa5FICtVZSrU + DATA W0SHDKbr2xhydNkes0ETa4worPIgKRIqTQe2bWurfeLo/PKRV9Yea7qw1dsGLK+deHns8hg+0Ne/JSgRS8xLR3ob9Mmm9rZaXUpp01b3WfjyixeBpLrN7h14 + DATA FDi+vjmsrUmM38NX8BkJ88TP+nxO3pbe235cv7hOn/F3LKnZC9IIm8L1d3Av3JuWYTaoG7UafhmnG2+q9yiP9yYxit3aHd1nz2sjxV5oiDl5Y18U303oNRXL + DATA SnL12lO3dkORhseD7FV4MMuLVotSwS9DnJOiS0yj42AvhvjEi/kkdQ+OOPKaaFEwh5gX/ova/y+X9fH6T5L/AM4tZ5KHyLugro4i9S8SYkqgRBdnRcUOsOOA + DATA i2UeVIVy2hc9uMhipQwAVx57AexAgBQ5Fkxfa8G/5ZQI9QXdx7/orSY2KMm7qgo2Zhkzrgro+WoJuBJJ2cCfBcj8U+At8jwpgNWHEYsXFFIJwDRKiVFq4OoQ + DATA FF31PMhXAtWb5RgARc0tmWpxT5VYXD1y8ytyESqxPn4VVV1EQ+k5WVbh1PiiDo0fZ1ZPP0WkOI0NkefIeyEakZvRsPCQ2fb/UBGxchr9TgC4w9NCUGhAfSGY + DATA xl+8lnJKRLqCjvD2Vn98UDkEoQCnwQUIhUAlYeohFIxWAJG4CGNTP/TjAJbFagqSdCIUtFs5MY9Q8BX1HoZB88mbdR5J8tBzHk/EY1MMBv0QNfVuEHrcKXHs + DATA KvaN2F5pkWlOLrqBT5u89kR/6tefbVvcpA2ZVcrQoE+iT8XXPn9waOC72x7t1zp/yvIuUUsXKgLgvCG74baJimfO7mtoc5vSeX+12iVzmbX+zTsT62bO3P3a + DATA +bFtS6yVFzkiZiPhxCCMxAuZq7SOtxbrx+ahvc6Cbu7Y0EBnR0tzvjoR95dbLTqNREQAIbS8oRXqlfkzqwiMD6MXiQGabazDSgDKFhr1OOFRUYCHY2zqxQmC + DATA LRpwnMMHPbhQIANFQYKcyWmjSYKNUnb4ZlEDy9mAxgbOYvpFmNxYIcHDnXJPGqYtwoOUISd2lCk6oia/FK3tP5kzHtr/N+bq15m/d+lyhcNA8OgL7l+su/rR + DATA 6BfvOvmvd4AYND51edGeXzROFHQJ/tINgcFOc02gbV5m8vVsLCCyV8i8yu3WqibteHX9IreobvuDWhNIV+SWXOkPJL67acOWh5nLy37+udYLtRL7zLSlu/th + DATA EALWd988cOD+M8xH6icf/W2rFg6m+qzlD1aqnLamr9y9f6W3b/2EkJBJrG7m+uCnwMjhtrXPVVWuBovjD6P7hfvgxCML2deCzcT6Cqr2NqQdKzPJRNjvcogE + DATA JM6HJ5HqBQTeCjBCDSiMgGIaNT15yTJAQEpSBKSnjysyuZ4zzdVoiJDuhJLr2nFJFMlAyE6a4vT0tByiIKapOFc7o5+lijphuvtJoP8RfVEE/OE/df5rp9eW + DATA 3zKvvb9gF5H8dS01NWtqcq6aXODyE8e7n3g4rrBo9Pc7ZWLN6jJca0hua1BaK10Sg0AtcVuahvaHZF9/9pzJlrdZq77/rYDvtf1oONVc2PJ2Z84vt/ICQ91r + DATA v8kXWizGCqkASH9+Ir1BbW9vYjoWAw3tjshd1F+fqxHSIsoYrNZlNvrt+JCWHOi/v6NhS4r5XoHtLIxCv/42RDaFNcH8rGhsyGVTCZfTZNSopZIyGmXnyiCA + DATA WKHMjHpNSYwAkLTQw6E8BzTLaRwCjHIyW9PxAD7l62WswoLoKaYoSdGlqpcjLYTafUNZB2t7hCQ6jel2s5eiVqtJn3/8IXNNtbZKdXTktSeu7POt2ZRZNcsQ + DATA TKi6FpwExuQzL2Um1i97pLeXTM/e0nD4+Dde7CDx5q1709tJYo3DW/HIqcyF3+8Evte9JmXE8scXZDsPf22/W6hV+eqVWnld8yILryo66/KpE7fPcO06vW1h + DATA pz6B91050tCaCi/dtzkoJvEgBliF9iuIVgZLFUTIELNRLiujUA/GgQGIDyBQI6OkrgnEPU6usE0YZVqhLEW4ouNyhQjnqzQ93WrX3lB7zAPCI7u+/MXPHOlt + DATA XJZvsldGFG7Z5ax21om7jo8vpMAcx5x+f8NSm1phbU9tf/tUfCm4bAYBIHjnzKnx/s13HOtzKXQKb15027ZIePy+k7/6w6uePzTpdWrngN5mcFT6MrpMNj2J + DATA skwD9DUbtDGH4nxVpiLs9dhtahW/jIvzkAM4geI8kmnxm84egJvjfJo7+mI8IiS4WsX1mG6hQDplQxSQETiP9aMZ/Gx4yQmVNViflFpUz++Pq/j9izfu2rrS + DATA N/qlhjsXVcyplUfSmphA+Pw5kHi/88R3rzAfPXJsVc/A32rf2A38f7bxKKlIb2L+yWw4sz4gs3ubF+041ffcU/+v26iUOyoFJnU0VKjw9jfv+wPzU+avzPXb + DATA B2obke0wzpBPQtt7sa6CrLYmFHA5LWYVO2mhUYRJAZzLs0iAJ6dHLAT8isMDLw0HCaIERdn/brAS404bAcCF8lvnKBKcC/ewwa9c8Ll7Z7kVapkjBOcoErMj + DATA sXYyNKH3T64KNRRsEX2sPbHt+L+Gbe6qFmdjaI1XFO6fbDr70FMDjYtrFlZGFT7DyCVesv+ZxZuyI0m5q2xqcsKLdEZWrkoaK0K2aIen0lZXU2MsnM9uXTra + DATA akzRcFiy8eTtk4FZg00rtu7oSPGUMrfFrSpsQMjlr39IfgiR68BWFEwAa2muq63OZtKJeDDgdmo1IiGJYx2gA00CW+sdOJ/0AR6/CWACGKh5fAGfJ4CBBcJK + DATA QFhh5uSxmRMTACF8S4Ch51ybjav62T4IByxqdcBQfIMvKSX49FAG8g/lQPQ5+3EKAc2J/3iM9S1Y1BNcqUdcgWlubKV+XWbjVoXbIlBLj50RamRqvUDjNERa + DATA U3MG+7y3JeI+QFgCYalNUh+eeeWR/t9tzvrlSkuZy5x9YbfdMmtsfkFfhePHAQ/ggoGPBl8O0mKBMiycAPcTFCXmqzx2qUn3MPCupe32TqlJatVFtwybEkqR + DATA RWLij9aqA6L6FcwLUpXCuxbaPQEZ+UeIaxvWWVA0N9UWYJkd87i5uIOicxwykcQBmcRIHn7zpO/mQEQDbGrSR//vAhE1PfIL49yPotfTM7/i/zQBhEe3fx1G + DATA pp6mZflGR2VE7pFdzmlm3XHvyYWLKMFKz+qF7i4cT2nidpmmqhFO93JOhc+V9diblwgrF16pf+hIbCH4lAVFq3+d+4Ro9cBdb/39qz9q0ad8I+OtJqFIXqEv + DATA CJQEyRerZveZC3jtxEtN+mwaonX9xevv8z4F0RqHmk0zOjxzRk9XW2tlOh71uk1GfhnXYWoqRHAk1CjUYiqDVpTRSfgaNd8Qapwy44GpFuUNL7jeLp/TDXyW + DATA fA4av5l5XDxDXWvUMSgGP04xIPFQ7MlB36dLOwE4149CH5Uq+VSa+PuWv26/8EJ9i8Jt5qulF54tk6hMQoPSOX8fz+fssEIK03el8tX6BVqBTGpL/vLPgfQs + DATA tbg5bMmQloi1Ric1CtRadbx+c3mgXO8SCtQTDa2LyiXlOvx3QinT8LlmPSSnKiRcC36Hk5RC6pJbTeDCE7gqIA/6PZVuMUHp8qbuZQ2nHjZcBupj/VrfnNvu + DATA 6H8EYkSWeQPKMM587qQhJVbw1MO58lGrqfZ2FEev//n6h/i3KCW69+lFk1EmpSlUpiixYpEGii6MiiRvCm0BJRFintQ0YEQJ2LInnl5ULvQ5260T/Ky3b9VM + DATA Zw9OLnnw99V1rJvO2oFLQfz9Rje67KFqr8QsV4UHTjP3XPvWGzVa1vswDDAXr32fWACvyYuFCgK3E+59iIV8EjVXMHZQRqC269SUkHUYGcE1VxJpF1AoOb+4 + DATA tRdN4MWcxVz0Ag3Q/HJrVLL3m6pohTIU7lqQntw2Flg8tuDSX5iPzx2Ia2kGs0iW4+XgafDbK/3Wb6pUMmdrviqq9EoVof4zzIvMZebTTPA7G418iOKnIJuj + DATA bL+0o6ABWG9Pocbvs1nNJrmM4mF9oA+p3nB7TAzzD7CjNESQWHIq91CAxxM66DKcwxy/Qe3GihNjKK7wEnnRIUjwWw2kaK4jXyr8UTuZ7cFD/sZS5PcUZlPj + DATA PXP7GizZieZv/Unqtgq1Mu7EmmM2t9Rpj1Wb0/DeiKa5Vu/bE1srFhnLlBJDb60mkJ/Y13JHS751vHPGonr/ncGgKhLuXJBa/mX7td/lSJFAGRBNn63HppI6 + DATA Uy6DkifU6+LtF5iHVq9+ZebGwpGjCa9Yp6KFTmP6ruPb1yYWx2KVx9bt6FZDBH8Ko+cuSoPlYPRUASwe85cb9GqVTAInxjmQQ/EzCp0bAFQtoDItyTbeiTg7 + DATA VsXjaBOFS+QQSxKwlGWLNQcB+TktXbmGO1Q0xZIMoZnHPzG8Jog9+w4+eP7k94G2vGPQ1liu8SedPY/c27grW22XWDQDyxe0Dk3kb79/TWfTbY093hqk9Db1 + DATA j/KOMJ9hZjGrtrfqSL0+NS+lUfHVWrFeaFSHzRXiMEgD25dfuVy9d3x4/YVH54fUeoW3RtC+ZM2PIA7e61fpA5BJo1gzwmFwoL2tqtLrRg1ebBSMIhwC9WYZ + DATA AY21o4kNpBeV5EQdtByFQXaqheM3kWi6AlUoUMVD4MgPZEjxoZgG8OLmB5R8nA6cLgNonEjV4Bj3GiZgFEW5Yoqm9AaHoXp/tzm/YHZ05NRrb39xRq/FGPc2 + DATA LF+yc145w1yc19zXZBXx8/HY3NXVO57+fENd3aDOF1cGFWXa1BVFMrVmA1D+LVrnkTo1ipOJARnla/FJDcJvNoc98nK7vXHzbrABCDe9cTszwKSYM031oBZ4 + DATA j374Xvbbn2pn3MyvGmNBhYWQu707Pr3qL6D/O63lFTKeSGyJWXLHr11l+keX/+41wLTJ5GJbfYIZfpD5/d21rajMwlC6vf4eFafUWD3mLQgyaZtFpSAJFGVg + DATA XsdRG5oAKLwAbi5LICS1Km59Q55IQ1ymFSCJ8EJoqdAOBSzrlQquz1bal0TEIiuAp7ZnZMhcJRW/fKLBQIaabUJnfmjJpsKxrQ0KlcwsVJnl3nKb5/TWWhmt + DATA lpeP9xnj1XOz6w766Am4vZja+ZttHwDp/s0K5uq1v33wK0urYez5X73zj5/PeIEi9aaG9W+ev3Bv870jM2aAFqB5+Lyd9ngkdp+j9pkr31n6w3/vVrHbsFd5 + DATA syC/VNBVggWBy2E0KKA+QXYbYDwqyZDpCbWI28NQprjq2gZpgBfVL6TbVH9W4eU6GLeR9ZMX5nz790A2w0I3b7o051vfemHZCqCv4em1kbPnju+KHvMYjuy8 + DATA 79RS8PWNgH/15z2Pvz94nfng6s+6H9+wGfz97Udm2xrmXf7pJOj91bknL72LctRnoGJ9D15zNVZbkGQz4RDS+kjpU8gbNIBHwKhAABgeeEloAA8DvFuL3ek1 + DATA tVRxx0lZrHXRRhRxU7V7c2BVw3e4rhb1y+P1DrlZevYz2UXN+lS51GFS7Hjn/Km9oQ1bc5s6VRG/zJ0YWJ3d+PevFHbx961/6aHTBrFoZO9hmSEsXIErHwa2 + DATA RqVcbCmXZkLMheB9d95zZ1hm0UXrlCi5VFW4xfpsbMHdsisntrXU4a9BU+5jzvO+Ci1vhb0UDYbBx9aG+hrYT0GdLZkEByivJOI3zXGh/STGQyoTo5AQL7+x + DATA w1dGc/uiKDTyaIcnT5VkpLq0ozRdz9jYJFLKIazwmV5jAl/b5LeYGhdsv+PI9oqJR3ec2D97rsacItTywEC7qSa37OzoF38B6AFLdsGelpMHB+ae3ry/2SJU + DATA 8QVGs7H65RObV+UOC4Q5u8mW23Txi0ve/Ppv92/7/JceG6nIFSitS+pJhsY/uPr7LzSd/Wjote9++bn2c02GytGOsKRMRndVaVPxjhHPMOTHV6//gYdDlNqx + DATA poKkBoYbq0UqoSmOH5EWLc6mDR6ixg1pg4Rf8RuFRGlUARJ2iMgndD20CKGURgMBCBNeqLZLeblEqSmliDooZAXz4QOPRNOxsKKuZyPQZB7/XO3u5+79SVW8 + DATA Z8kMc15J64w1Z2a3VupCapdB5kj+8BdcOXPmxdwExzCjPGqM/+TyE+TLX1tgjuqVrQ0TFiqfXPbgVy4dq46MHP+SnCcBtog6Jox3zY3NizRWahOSa693IDGF + DATA SCd9BLgaEOny0eDOzhOmw3eg2FcBs+18SgVjX3VBlK0M+K0WtYpH8lDfAJKJoxOBUisSKSUliGGlJgnyJuX0PqwHSpSS09zU9IQf37pbW5qApT7m95q68ip/ + DATA xNUzXudtmpfbdvWQv6u1foaiJiBzyjsy1dTgiUn/SJsVLtM2Vm6571RPIQ73Z8HtU1uvt82NzJv83P3Hdy339jck5h3etXaxia+UOX0mvq9r5iO9tenbLi7b + DATA EJ+f2PT5vdGlQ80zRvJwZxahsOP6hzwx5E0May3IImG0Y4z6xQI+t2UcVaMOigkQqPpAkZEAyLkwgoeVwgsF2PgynW0xrk6dJgVkxf9Q2ZIPdu6a0OnX/eRf + DATA 8qRdqOEbTmxsGe/v9v03BSyvTs2vHWQ2XisMwHNWuCjZGDjzLmh99ZMLVQxdL4z7d0NbG7FcQZavTiXKvRqVUECRXL/EpQAAKVNAohNOclbxAOcdBCeneFO9 + DATA b7b0KZ5uKk1j7GEmE0olR4PEDXmPwNVcSzudxoqagsBJutnfKFCPFSabDekm2WLmym/PRqRHv5+DZZDIZkgsTCuczkr3uZMte39UU7MZUOWqtpjCr55z4Cyg + DATA 5ro0Qzm/0ZzbMPZB4jzj2+6zeraDHvD6iQaHQFVms4m0apl99vbTM5hnmS9MSOeA9nkrfg8+anbBjFr+PLOWaYN4NF3/gHeWaoUeUFUQ1dXCS1RIRIIy5AEe + DATA JyC53hEJ8UAOIHb8lzjBJZOp9o/TwTGasxARvNgx4lY7uORygygH3HL5EY27MDMyb1y4YRHMjqHFry/b02MKur2WBldLi6laHCwceaf1sVF3Vm2Veec1qAOd + DATA 2y7MYH54MDwUK29oPjS+7OkvfXv8m6dSyoqVLZDvwYHaFfm9jefOtVxc3RBs6rgPUAPfeLa5allKnZM6y63Vz3/zC8/3Ma8dis/Li3KIFWGoNr8JWTEH6yko + DATA BvrbWqpz4ZBWo5ChTXukNVOjXpyHiIGjaS7bugCodYFaOzdNjni80j44t02FCPI/4pPGQGlICalRmvcixIpLMeR0wECNfTBPtbBJG/5voRMtAQWQGRqQeALK + DATA oMD59UZNmci4fO/+HdGVbapsrn2+UxSesWbfma6LJ/bWVg7P6P5yp9qc8fc//J8RzYeewklAtvlpPl9tkYg8P2b2rj8Y08R6jlxZ/s9fPDRpicSernr1jz/7 + DATA 6uNHY0sXjxx+8xez51/HViEFE4fedxDiXIvVou3Q6ixql+u1NA+rBbXI/7xxuxStzKA8hZMQ8iQBpriGFggAdcNtHjaCKsLJ7sHiyQQ390AYIlBRfcj5Gtdt + DATA A7QCRenppgUxi3l71Zo7n15UpSsUXOc7PnObVycI2Or65EKBSvzS1WeExvKkKqwgDJq66k8xHx4d3mutckl1sCsxUi3A8cfue0kZt8r2dl/52tNgRnltc6ux + DATA UiE3NB5YcMdeAEBfOU7DRWYrJRa5orcxD36eWbHKgFS3ZiDPbhc5r32fd4qNRXGYfap8XqNeKCAA8j2rm52PkmAq3RQ3XpAelZVC0E3xhCY4giDB7YKf/M8h + DATA CRC3BJam3L/LB5Zt3td0+oAhJtCpgOq9luom1ULmK78+HfukwATom8PK7ovXmpd+5YtPn83cpgvKyibA5/Yef6nybqZyt8/s2QRmgNdP1n9SdILceAvm4m/A + DATA XJyD6gUeXLnX6bBa9BBsmkewPhjUAIIXB4DGkYghaG7JjEZjHQCfcbEaL62PumGVy6rxG9YxgZImuYB909IMwgND7S53sZfzObdG3/nkE3d19s90is3akR1d + DATA F0HDP/YxH39lmcWU8Ju7vna2emk4l9NVtm3vY+p7X6y/AvDm3rQuUm5wBCVNfpXGrIk2VR9+aPYrYAKA+HxPhXt1mJjapvEa8i1r75jJVI58c1O/k88XG5oi + DATA 7HbyZTJGWzEnFnjRbkUDW9SFMkHqgzSGs7HXM90kxYujcqCCRRGbg8AN63OIEBjyA/QOeIh5f25CrNfgc/3a7Z8zC/XusCFmlJnPMAcVzspeh5D5Q7XVqjAV + DATA CtQf1+SMQpNUCGmedXYzAx9disxzmw3oZg24NUwI4PVJ4PaHoIz4hK1hgEAH8GLiEEhMQwhcq8yMTGBJDArBH1XMD8Nr6ct+nTMZ/uDQbBQR9sJ/8aVPtjiD + DATA caZ6ppMOhhctTthjGrZiATeOH2DFiaGIid7BpYDPWnztfs5iky/KWQw2QItnesTUH6HFcnOh8KF1bc4kQBYLVdBi8Bg5G1lsRLf2PIB/lUxCH1XAvqBMKijj + DATA NoGVCtY92X2FzA33B3JSGaBDABp2iQOEJT6nxC4Cd4kiERGYEOl8VRLmJ/gvVWK+To7/W6W6RsnlZhWOul6om0Z8fL3n/7Y7DtjtjLiba8Qy/643RnzkPSlD + DATA RYy5HPOa4mTUZ06ieNNOjoOlVDOmxPTPy6VlNDo9ETZlghg42fNj1amKWy6bWj4ECb7ZoU/MdA3i5nRzQklTxoc0PQ0pmzIXnVyfsVZq+Wjx5vrvyBFSCF0y + DATA i2ZRqWQo4LQjPV3UVikboIhYuZwAaGsKUGj4BK+LR6FlW65tTQKCkKAkyp53qXlVUlvemxYIplo0Wvghtz/Am9pJSBfvnCKaakNZGK/nzK+1SgWzD6W3jtpq + DATA KWr+6OHDb7c1JivNadlHNH7tJ53Zge3jVjWZVDTPGe40VwPBLBOM07V2bYfXlqj6bIspHho79uxj9y+cWLVKXW65xmxX6DYuuPPDrq4GmzAxsqXlbohB7/Wr + DATA xJ+pM5gLi2P5gszjDgXdcU/cYYNqmp1GepRotm/nFqZIcqqikDhQvx4HOGczV1KgZKYs9d5RIVXybpb0xdvIWENVvXKjfPXtDmGz35wk9F59vb1yML1yw1NV + DATA yvTYtsY7Dh7q7gS6sfFTcbmne2BslrsXmKqWLk+BAXD/X/o1gfENRzq/OnR6f2z8xZpXX7qwMzTW3+/p3/mPrkcaCksOtl78A7rmHLTvIXjGETRpRXuwTrtR + DATA L5OUUeyktTTXIXA0XsTxGxddb560KvNEaQm6lMRTXAnObcWxA0bu0wIen7m+8cSFy1k14TJW5xvtZiFh0dYSeFf/rH3pSJ23fs0SW7lDmzzwuU8ND4HhwSfu + DATA 3l0xf0/FhvneIY89KFZrG0bzYwd/+vJArEefsBuylbtnz8JwtB3Oi8ITi2IFOIExxGMAq6qMFeKFcNAGNzLlUoqHRUEUTWHqjIAmUiIcQwmIJMh0GcBoHo3x + DATA khhNcwmaI+9099rBB1wfEi9NYFg3Le3BlKJXTMsdNlc1o4Y1N2CBp1yis4ysUA9nl+T1mbLeqvWrn0mrUnB54I6/NT855PY1OIU267Brli3dHA0ZPcJroxO3 + DATA H05DSreOj3aba76JdIfOkFuiDm+LL70/++wLl48mVszF+5cFvTD/dP11BfPnJS+9v0+koPLf+P57kNbJkU0Np5jXUKppgid/CZ68GwtjbQUFLHLD3rDTbjLq + DATA NGiuh/w74geAh+oFHgHpnGTXwPE46uqXaIDjpcKZvpEGEoLbT7n15Ln1R0TzDjLWv6bu+B2PVarwCCTDsUskLpG7GiZXeqMuo2X7h3cOL8C7loz3xR7asgaM + DATA DV44fXts2dHInlWjLfoYLsk0GnMN2mjAmPRuH1qA//jE1kfl65Z/FeWgnzFvkZ2QAzXYYEFWk88ko5GAz2rWacpoZFdNBeChBhIPR80AxO0kVmw4U1QKFcQ4 + DATA 4BbeeTxonmd6fQw9uFARQKMTVtKO4oyXs/rmHdhi/2lqS97pddAEjupnX017g7NrsVdPRZxNbXxjNN1Usfi+yQM1ydpec5klraELQ20azdjojIIhm9mxeKiv + DATA d2Ek9Jlfq7d98YcbQZnJJ7T4FC6lqf/5x++p2r516cre+jalWKPwN2nUfV+rbmW+IFHKvWt5fOa3zC+Yd2fPROfdce1nZC8phMZUod5IOhUKKuQiIadOfWII + DATA xE3VUCmSlZqnU51Gd4niNm2q1FFHYyiKdQP0Jl6qeKbIjt9x7qWHqlTxoQ0Nx4AuJ1KJDN6AKipKu089xbzTvDis8M5eFL7yhoXiq7o6ULBy8MyVs2bNaPnl + DATA 689WP/vp+/dHl+wRG0UGicis37COKb/21n1+sUioVzllWf9T+OGzc2NKf3ru7vYHz5rM6crxXYgL16EKtUEuNGPtaO4Ad7Yg9fzlqBuCNYNmpEMrHAAyGnEB + DATA TxebjKjgK4UADg6Kc3pu+iLFUfO76PelUTYb2XFEcPaNYpdcfWt/IY3mMIb0sRn3V9lTamsyqvCoy185l9EL4ey0itR5dHW2eVqp7oUBS814dyRk9OtjTUHU + DATA XRjJL6o3ZNuWW4muhxf9YGXrZMCplNo80mAv2IV3//JJGPvnbT7e/Y1h5p2wwvrP2fp0Mr5pfEFyyYXOlAsOSX1qXWrJmsfeLLQhXmSuX8VP897EpDB1xwoy + DATA uSwBJ1RQyiflSQEfZQED1zZHOKA6DpSyGhJuGHvkpTKEKE6PufXKUpWCbJ8GAu/K5NOqgF0fmVmhihpfM/hyCyfhlkzUnKxSClUC2P3K3Tlmz9UFA0Hyt2ba + DATA oIstisusIol9Ts1HTzpCkaYx+9i6HbXbj46YyyS0ExYfnSNvNR86Vx/UYDhz/tqP8DHWpiDmKYjkMoNeFpQHBeysVcHaQwDEba74Iv6DHQS3sM0N09jx65Qt + DATA uLZ0+eqI8VcHV2793JnLsnjIeOrisZ6ERSUwa6O3XjfDdP6AOcUsYj76do62qjxlEZABKtD8/dvDGs6EKbbyIVvrsQauns6kAn6NqozG6kE9il3+uB0neMQ0 + DATA W2H4gmxFp3NrSU2xN9wR/w1LiallOFhflrq7XMCeOi/4Bv7b1/YnnTlDKBOWO4sM9ZtSpNajq7WNKQR/mmzyScX5oawmmqpc86F1RnedEw369Qq7oZYPnprX + DATA cyCTv5Wg87fe2fODYeZaWD1rsqnaapJ6XTK5c+ey2NyR2xfOhQnLYvAG1WjDrxby806IiBUpaItZDy9TUIbOUXfTcnjpDhKyuJIPrS3aSuA3+d9ca9TT/2kT + DATA vxV5miPlPLSBdazR6oX5ut5lz637EC8Dpn5NcPk9Ly5iljIPLuT8hv2N+PWrVBLG0VXYJDaK9ozWrF60cNZId1dbS3MjvLOgwmYVCrBVYBXaM0qvW5skBCi2 + DATA CDAKE6D8woNf8TIhzpVAMPng+JTGwL18Gr8hwiCFeNPpIZOSiVuqfopKl3a3aPhDpZvAbw06KGQXkxL7VVx3hs0EZSyZpoiqqrvXJUamA5LGo9BlbrOw/jia + DATA UHpUFnm5knzR3RnoPtpfEN7Z17a6uVEXb0npW6cB1GeCuWqZzZc6stTXWGWNK02xCrk3YDvSXgVNhCFrT93aG2OWK3MQeAeKLqCSOzs6u90DXt7fA8P27FBL + DATA zaOOL86bkTDoor1dl5ckiyFMZ6h68o6D6xxNdu+nD1cvYP9Bmdhcu6YJlD8wzLwJkFRFZ0WG4Fn1YrUo9jc11tbkc7Eoe0K9oBfFfncp4Jd6wrdGfB57HpQU + DATA /x+Og91KQO+XzueTIj8bFwm9da1/5uVPxjomdyvNNrGqjFzlbOoMDi9qMqRbkrr2FIcyiv+tSY0DZoANUZgC/gc4O0wBGXV3sH/EnDPo4ucfX5Z+qMPBwqjR + DATA JedMPrkh2MzlghaoCf8B8VJibjRDddh1WoWcT98yQ5X81xlqyuMp7hrQVPGuLA2X/b0JNvtvjuCB7lX1d9z33Va4Mr161dmOO9dtcOK+WcP9baZqPKSo7e/v + DATA Wr7l4cfvP5JY/fyelx87fjxn8YAv3Xu4u2bxgbaL21ZaRNkF++CZrr32fdIIrzKE5dG9ZtmqWDQURPNermrx2wHJwwBB4vYbpDt7pPBsp5puGCbjImSaQpFw + DATA enaKjiYVxm9QNaUKzaagVMUWLrLoI3yGqcZnr6i08C3de5NySCuNSUeaka/IXaRA9NSrj1WpUrM2N5y4jqVCsXmsaGdrtTlS5o/9r4ZdGZm39gHwxucbt20d + DATA dislcG9FrVF63Z3pD5/JI8ETWwy+c2SynZXtt7f0VC/cgxFYP7R/DrQ/iGUhAl0FVThUnUsmQtlwNggrdK2G667F8lELK1ztaLJDwKoGKfdpTUMDkiwW5ajj + DATA LZsKO8VDRC1WnO1la6Zrc+VN9Y0N3FTIAChvtzRVmMwpPkGJJTbdI6OqsJYWahoS6jCJH6jtrZxc/VhamRzd1HAC4EzTxL5DXC0z3GXO43U4IPbl1OVmodRR + DATA XpdiVjJvtz/YurjexFfoDNmVd4Dsma2JxUUd+PGuUkFzkvk9/jaBqlkz5O95iEwC7UbHY3Du5UZ3UrO70XoAzbVPL3hypSwAiM6l3egUarUqkh5vacmBTZXa + DATA ok9rOAC4gTrBBoO0DhcLv01YVHxgUAdG4woPUBoMZBmu43l3b3UtzBNSqb1CLNTYqwcrzi8Iyg3xuNdt9JrA1ccjqqKfunr6upvlTr5a1faXDnXzQKU+w1ea + DATA e2p+wFybDLiVyDodvId9AbSuElmXTpZ79Vo052KtQ2KVwAASAlOHKrn5RjVkXbqow24YbSYTpRUhZDR3AyW78VEaaOqMKn+4vFGf8shcLmPlxjnLHzk1oyGX + DATA SukMMhhiOmNKryuZN9QU4iv272rPP21NKry+xT6pSGzuqXf33L9/9ehEa7aju8Iv5HljqbDMLpe5lnR0dAUW3jXh7s0noHUFeHZenhaeXRfaNEMVm9fltMH9 + DATA cCWfxhIgwUcVqQhQ7CniBCrW4eVhNKrZkM08kkulNA2Q1aVEGivdfass3t4Tv2E4A+VOBL5Sq+xOGlezLo6PmlXG3lmzLwbi314nIJRSp6t7eViTcklsojZd + DATA 3lOprGS+XtawzjbUkvICymu3ViWyJx7D/QILX20Sm685ZRIxXEw2XAQAqPc+zXx9m9NrcVugnRGYk1bAU2yeykkN2apoxOlQyGhesR5xiwBGsFtQBNrrTvLY + DATA Jhpqh9/QeuBNtR5KEyTqRt3t9dwiE2h6KnqV7oXAp5IT8XftQFVXwVE94+6t4QW9W30ic9iYWmwU2UVQx86Ly+wGv75R57YqKvJtPZ52548ltno4XZC+q+SF + DATA A5mvaAezHkuqa/63v3/Q07fMPnPJ2tzGtwJKJe3khgI98yfzlxKdjRltsG08sSgPNsgDUonVyhB7QvIOK+J2NTz9jyEqSajXBcl4wGeGK5so76hwzkUBKAZv + DATA grtt9j/YyZnEtdHQZzd12DqkpqAxPt8gcgjNusi8uNzmStmyNbUP3THTLafLxFZ1ebA35onkl98584UX9ozbR1aszU6+4SuZMnbb7oY9JytmfXXd/sKSJnRr + DATA tNNdkfnBN166P7sT2dEMu0+vQzva4fRV0txYnY1UuJ0KOcBQZnK1mXDuj2QgY4gkCabra9zLK805SPZAp1LRzcYhwY40PBppcMaWpoo32yqHjADCeyxCn2oo + DATA rjG57dDiiazSba0wp2slY/c8sluqcaUHCdwt8q7PyOpG+uDIulbjdHePOyVV83c1n9v9O9FtVI9JV7s5+drhlV6zdgqD2ZO7mw49NMP21V8AjVMgx4m4tV3f + DATA 8/dTEx5RRd+K/J6FT/RBVFb4LiNUtgO4wv84rGy+B3kfgMhUwTm9JJOKRUIBq1kh4+7d81T69EKSHU6TEBuSSOIlbLAbsUlzmhV5bBoajEyG0KARD3xRyl2w + DATA tLmhjkF4ENS6QIVVbNFUX142SJO1uQaViCQIAd++9txAPmOtUhJ8/fn34h5n7bCXXVQeyXXcuWG7xioW6H3y6P7z717qqUqYktlaz6LK9PNLczKLlUeIGpl3 + DATA MvH1PxTJeOqhXDmoeAlecNW1n5Lroa2tSEW1Npd7LWaOzYZa7p5RjtO3Vi3p/73votzMzUCL/RakKov3jzX9ZweurGt2DAd+LrZDBy63aj67pn9N4Y6dUXNs + DATA dDy0tzXv6TI7W8byt83eOv7f+bEr1x1Y2Q2OKaAfm1tqrv2C+X8PPNx4r5BUWIxGdY1/+6ndk/9wVszdEJuDQcX2l+tvE/dBPDJYDs7jZbmqirDf53HbrYIy + DATA bpKQMQGcXYevBIAiUDMWJ0g8yeZqLI6hW+eoOEYBggJxLhqW4nsxf0G7ufsw4HdueJTi5AoCKFYaDpZcyel48+FjcxIVOpUqaL7ymtmf0FY6OhdU3dVwb6No + DATA 6IRbNzFocFb6ll0q6MNqP9yM7d/bc/4zTQTAL2aSkT6lXiOeuUAs1Kli8E95Zo5X3l5QlkvJtjazXS12yPiKMqMy0LVqS+2ee/cgtbEYzgIX01YsiuahAKsI + DATA edywI62TSVA/GqEQRPYCnO08AnYhAT3jsfu/nqlFBApg6NHFK86JSovRKDIgvygC4nQgO3EefIryGnIEEPrK3FhyVCzga+3PTFiUjlRf89LT6rKRWEtG49/C + DATA /HZTflO2jbn81Iaru/fPOKYiy50yNy4Ezv6OQ78e7tLxRenhIwOPMlJB9IHV55hfbB4IonbpdeYyQDM/JeZ6XiaheWgOpb1lwIXdMN8i5MW0JS/KD/ASCPpi + DATA YQKUe5MuSIvXGf+1SGOovFdvoUdyFeGK8ibUzdsG52nb4G8Ko43JoN9pVylk0xtxAaTuAIFP4Ydx+HHAebDiGjV84OAj4EhTmVa4IT9QIeeEaCKM2KhavL+S + DATA kBDcle4Z2dQV2AIcm2o2ZtvumkJRoLH/ZrXU4o3aW5ZAFJkfpEH2UfAvFhzgReA8teG9PSUgxUxF9ea181wQSHhJ2wFD/oR4FF5THjWl4KPXAfvv6F4vrk/t + DATA wgF3LzNrEEFMoUkgGvAgTYip4anCkye4v3OGOJ7HY6j5zi0yshSg7jYRjkxbYPTO4fqkPjuvzhCoMNnNpL2y3T/r1GBDQp8dLyRUXgUuMrX2dzUaMq5kjaHG + DATA Za6YpzDf8Ia70lFnZ3uGTJSQkfdiUsyJJWFXxqRUCPgEQBHOWUxuMKylWAJw2JfujOeom0qjVDW9S0ek2HtYUcFRFDQK8NPQOji1mfpbAptTiyIK8+iI3i7j + DATA hZuj4ftIzyo6El48dQe/l0mNLjJ6WxmGeWnzxUtVLXWtZwDcO8fuvv4e8VtKDyNPd0GG/vINUpQS6AFc5EmHoUOZ0SXbp2cAOIVUZhJD+oubA1DU1LBLXlqm + DATA LN1Qh1AvDjic3O0Lae5PP5RWU2j0cWkuRpjqu2duiUh6D66vkbqMweOX5JUaV9BDlFVfuXf+4YZ2Z8P2Jl2i40C2shBzuSjcoimQ0fzYgZ/V3bOwpUYaNOU9 + DATA 23cMKGSi+Avdb///5r4DsK3qbPucO7WtLWtvyZK3pqcs7733SGI7Tpy9yGYmhDACYYW9KbuUWaCUUrpbKP1K9+IrLdA96KQsK/8990qWJVu24zj9v0UsxbF8 + DATA 3/Oc97znHc8D4etHIybe5KsOpb39xrJn1w/0uFxupkRWj7zvG0xMspmxQD9YB45HTRCsWzM02NHW0hSpDPptTIQtkwoFPAr0w34xY5FxFySBncAwcgBCgQoK + DATA IWEFNI/PQzQ4GCkgMUEQ8EUQkHzA+ScBJAXoKx4vPn0oS5xtBGRv20Lh7AvcLkSmo2nugE7cqVgi4tT5e3SeUS4Xd7jJM86J4XS8w8Ptgi4Xuxx+H/ankiqz + DATA pfuaIw9Vi2w6Ktfd/q0LNheuG73TM9Gt83uc3efVtCmVOeXdZqk8zxjpevLpi247URPeUFFrLUPDDg9WqCaP3jfqaKvV5NPilrqZH/qGciV6m7sF2wcf7KzP + DATA 7+7I8nT3G0uYLVF7nUdg1BbvH7C3K/yl+2i52mrPkvFkIgx74oI17Rddf/NIjoKdhJg+mue9JLb5PYw5S+1RAT92SoLJJfqaXLSn1oBm4tvkWhABXWAqKm9r + DATA qYlWlue4rBa9jk9zPWstNrMKp/FAQRaOWkEwgI5KjMDCbPEy3iAeZFAaAjhA11MWuuxMKGpo5whb0B8OPtfb4E7sNnS7Ze3O/TeEDMrO8c9WtehEo3DiCgzn + DATA hNncPsC+MPathhZrlkbnUmWV5mUbvA5r/S6bWmqv0uM8afSGKqMh0NBSkO8a2uU74vGJhIWkgK9U2LNiJ0dq2/cUSCiBMlTWdrhAClWFni6XxmLR9FZabV3P + DATA XBG9fGTnEEOlTGjtE31qk0Xvr7Iy86KRLb2HvvhUON9lOepV0jIDPH7L+IlvVfaVqgpHr/tKNeC4rximYgOD/fVRCwbWjvV21FSHgkWFebluu9GgU0sRmyEB + DATA 1mHrJIiBtwJSPMgAns/j07wg4FF8HuUXQm6SH2IeESHGASJ5YsmxBJDPTwyS0QkGXpLjckLh6ex905f6woW72Gu2LUlRqQknutskJGNOn595n8M7XUQzV1R8 + DATA QBOK/UYplium3A6SdvxTTjH3Us9axOPxPvu1e6CoWHKodsSroeXWLJux4ehQU6kqN2vv408P9hcVyFw4X2Goubrzi3u1ynaF77bCsEikzc+Hl0DVPkl5QVWL + DATA 0RE5j2cXaJgbLOwKJr76FcSuneSRQpWpVFtee97tg59+8afQ90C3NkuY7VHI1RVXr3379xhUddmEhNHWABGaf81EBHewEYEb+NlpDC0KDNAJYQVcaY1liWQn + DATA HV2zWQt8th8IV80LEWQLvAfvSAkbUl6QP429+Q0uhMAeY0OI4Y9enPcW+m0FsWbih9Q1oAmMgO6opLWlqtJfnOtRq2iSQpjodWAkDiBEBWOcIAkc7TJIkGj4 + DATA nO2NQM+yYLiDMOFMaQxnx2nU6WTLSdKRxCOyVxxua6mUgE3PcP+G85QoQYNd6a4I7Lr/eG9rIFwdEvLFWdZtJTJjXk27tX3DxhsbasoOf/bxsbaW9vU+nVdZ + DATA dEuudWqkvBQWbpt+Qx4pU3jsJba6toDf4o/snXzisqKNzdVrRyurScKvG6jWhk3ZuZds2rQjcv2NV+3ao7vpJ3eXHNgxfMm20XXZHoda6tp3cKi7Y8e+mZ/e + DATA eMX0xAbSqgsc2r234qC0oeGyDROTyKrdxAt4F/kOyAJmoHxOpxXwMV7uCxACIAR2uEDNjUh7jfNTymwxXspL4hdGWqfxz9bXClNfAoCDu0+/TX2GcgMl8DAr + DATA Ox7V5XqHBjraaqtRncbLSLg77XqtQsanEYtKBNA8gkcTQQEk+DyC7wcU4NEUD60tH5AYH83eJLPgstQsOA8xRbukidkSGZdysrjxJDdZMJDwlGxKKo0gisNI + DATA 2gB04h9DMBndd//kG3+E7s+/dPjAN9/4U+ynn5fUVh1/68uf/tT4xJHjv/rKY/ePT+IO27aeZ8/PG35y00WRi8cM/lxrc1Nedo74QK6ko7PvYL5YKnNENm/S + DATA v/cvKPvL95+sOv7852I//ff//uSS48/D3295uf7Uzi1Pf/abv7r+1K4tTz0be7WiqSyvMHfwJJR+Y2++KtdW9fDu3Al9XpjfvM5i7Bg99o3K8UZdcECDVvvn + DATA WANxjPwlyAFhMBRVez3FRZ6wN8x1jHH9+CiDV2aBNJEvw9imT0gDGoIgCQnmTwIdVzwKi/cIoq8SBRm2TZCa36Wf7BuL4HO7xlI6bJT49WWuIF/eWzrmVxbw + DATA ew4V7+gxlNO+7i1lF/40UlHo0/kk/0vHevr27CwhCqQlra31ujK8sl+r6Ag5FKrCtbLyh6O6fHff/9x5Yn/uyOSk3K6Ple+89OnHX6uxCIt6dlQe/zXAwNXg + DATA feKvhBWoQC4ojjJ9yRDYrepcTa5YCFRQhfyIRk9i6PrPEvuXcMT+EpBkaSJhAgUsSxIMWRd8l/iRtjr2AhTKZGKjucQa+2N+wA+/rIzJFnybsJpbik/Hfiy3 + DATA ZfMVVugoqg6boVy84JvIad0NjpJW3MDyXYkgYNoKScTxhDy3EZU/S9IcHZ6keJolvUWJVZx1ZEHFO/Vqjxv/uZ8UKj3u/AoDdnHArs3HMK/MECsosJpK4NcB + DATA Ab4Ifku+RMnZ6b1NYBu4MGphnDvYtnXrlonxjvaGemZu1mM1q9xqt0gAlFCJItX+Uiigpgcwgo9ZN0MBtAAaJ3EaOWcKJ1HCQIBTAj8Q8HEBs535BM4n/DxI + DATA oNyCXwQxIUeikTNnEogLT51xcKWwE7hn82ycT2bmpRBBLIs8Jmscb2piUxD0bCCbMmJlwpSJUNflpsJFfhv20x2vNd2+YfKBx77yj9tv3zD+0GNvDN12bJu7 + DATA e+uOF//91Ge2bt9QM1yRa7XqfE00YZA/4hZJxbUXGbT5tJrpg/F51j847Wivq9+skNm8gWxllqM9wMzaWfT6KyD8bWfjrf9+9fmnt+64+ZZ/v/rCU9t2XFo0 + DATA eKDxxgdf2nfoy6988tL+Q78LaxVbLz84ri9WYqR4TZ1kozFkFZYGRVkGQiTQ5OYpCnS60HR3a7tJba5oEvM0OoHGHrbVdmt2X4awchVxDz5EjgAZuvcLKJy9 + DATA 9y986WM5kdmu1jiXFFtjucoYDmCSEltFY99UeNvhPuJ1t6VcgOXmOGshhAROI8/yNn4YP8B27BpBKCpXKiDQZiuMSqOAB+RQjnaWYe4wFxGv5JKokhtnJ7QE + DATA A8HZI1alZJczMb2FwT/F/lMXPPDwcyFFjX/vPW2VJRJva42xWoUf/pDPb78hdOjKYndh843Bg1Pbpz7fUOhdE/sNu+MBcZQsA2aQD5qiOqsFghynJd+al8qR + DATA jToN07ixeRwZFPCgdsIkKQb7my7Bkk2mELhhmzJxZsNXknRusC4jgfaz6Cv0Vxy7G/xf/FV2eq4+Ki0r8RU5HSpllkQkINi7cj6AGEiyEAM2BM5HwRy7xjlz + DATA aIi5MSLIBb5ccm7uEOp89uGUGCnZNkXBvSX+q6fqhMZ13bmhjTVFKqdMrTSJjYLykZL793rX1iuDAUWOQamUurUG/cjYhhvu7a5s2l1/ee1ObI+xTKDSj0xl + DATA GQQ8MV+ozLJFewYKLt8e2LuhQ0PpVbm5g9kCvUFk5nkObR+aHKr5yo37CkdzBwEEd8Jf4d9iLFEHOqLyCFNd9XpMRoMeZQ44vsgAgDiFZvZJnKRQKh+HJEtJ + DATA hZGs8gGIuxaSjK+vkLTT83gyfWqKq1dwfoXm2IeXIKWjsC9t3HPo0Z2NUV3xtnyVuqa1sqxAJGw3FEurRpz9JU1FcreLsUe1S6T15Y4fvaW1ZqwJ/2lkx6GN + DATA 22sqOkpsUWdeMK+7p32gMYvgmyo8EkWxvWtTRalWkZsX1GgZg6hl9qmNOcMt1dMHJloBmtclJrDbqE6WpxyDc3nKIUWx90euJkFTUOcu4as0BadKBdVBa/NV + DATA O4k9WZhIp8q75vs5NK9g43V7UR7vOaaG/XVCCCpQ/RrlQvO8VosuG7FxJlgRfGVujMIwCHABhCyZGoZjrKkxjOuvBhBjB7MS9Wuu48lN4ax9k81ONJf+TK98 + DATA pbeg0xhsHy7yW/jNjuwCwvLOYNU2d9AcEq99trpuz5rRd7OsbNHrExorYtswJsZrzFmKih8Lyl6LfZHpaSqBP8Pkr009qvHoPxe78a76S7ffA08p8lCla+b9 + DATA /WrTgIPp16116rpyCntbumK/RRApO32Qeo06AtpBF2iLShnOokhhAduDncXNagY6O4ISgp3zRZqROIEONwhxkvUkBADx/lRkCwwC9CcbKRHobOIYNdjLvV2C + DATA M2ZI4yCmEhw7zCE2S/VkTVSD7RhimIBuNeHcOSwc299nqVLoTHa9pWko4lO7rnv7igcurK2oa91SrC3UiJ2KIqUsXxJtqy71ZxdfOTjQdOTZbf8LyT/uN1ki + DATA ZXzflUPrB2AYQseUWao+BXdD9b5/du/4VBGPKt7+3OhDMxf/7frqsrVDnYNMC4BUK8+tC+l50R03PjT4uHHj+h/cecmUtR6Hulx3Kxn7T2xN7OPYnz5PVglQ + DATA avd9LAurxOuBlMEmn5eKzbRTGN6ZwlSKydNIQAEEN8QC8F3QDLTA+5xERBIYCnwwtmyz8MlGINQF3KjGkOLFUGAA2xo14ai2JMdS3V+oy80Wmb1OsX5jv1nt + DATA 9Ln6b95gb9HnF1hJnNR7s31on30Cf4GXUCLgADkv6LUSMTedohWk8tQDEEIDmxh3YlC2RAmISyhEyHCyEkhj8BJ7pWFsyFblHtuiC+fzpPpAU4O1oipri1uo + DATA cRXrAkfhfwzZMu29Lw186ppOJel0C3l8tb/MFAq3qYMTey+pPC/2B4TVH2ENhIaJ8BXADkqjEpXSaFDaVXbEmk2izG+yb5qA8dEmAs6fbYrTHM8p11FO9n6U + DATA CNjV2KU1x7a4ezGsufHARVe9Ul+Y41g/FftrY/vePEWWQNne0FCtLSGwcZ3N3nrtDTddv3b9vbsevvmii23j13xzcKfSW9y7M3LiE4CBveCPxI8J1VIxOZr8 + DATA YaNxCErYvlDIsWKgHeSECdfLhuGQsi74LnZCWw2bYu/Hg2+oZoLvWJVy5p8Lvv1HU2txDOZy0XfsTRR9x/4qXvBNgIMfMrOs9dReIActSP89mr1xaniova2h + DATA vqY64C/Ms1nVrMIRusO290O+oCzXixM8BcRQehAKYBjwBbiAj1LypAAn/YCHBuKRIwEURlKcH8EAgSF2SoFAaIsPu/IT4kfM4sDZPDZ0xsndw2wLXLJxNKxG + DATA 5dbkZmP/y0TDGAvKcGgpnGLtjBaF24jtPdawvqhV5Zzx4dMdxQPRQlkOJh3bxexxvyZY5KgdFhi2W2trXKQgN6T2tVmzvbm+hmv2ZTvV+uDHLy2FdQ9St6j2 + DATA E32/3M2IW1iqPja+zpPZNQGPxPT4j57QyaQ5m69uPXGJIAsjnrhDoldILLbOpwh9kcZD0VjsgxKRtsjZDFuW3jBo3f5Jb2XXbQCcD7ZFdXt2bUArx7DOl4Rz + DATA 3Dar2aiZ1aZqmYACoQISGGYFAiFPKOAFAZ+xHR9DdQiaz9FcCoUsE05cPYnrXLLFe5lInOv7FWRYtrOPxc58BbEHVhy9feI486W0rDDgg5XLWc8uZh9uZ9ez + DATA CVwDropaLr/sogvP2zO9ccPU2rHBga6O+toow9eY2I9ZzKpONkMBXuLFCFoBMRJtRwkMA7EIF4nRdhSIcIFfCAU8kYDHbEu+iMdPSgzwAU3waYjN3Z0ikQQt + DATA vUQitFHcJhWd2SZls0lsrJa2Re02tEVXIzh9et427uv2NCW3cbhAWYi2cXZRzfZqN5kVKbZ2FOloWzSf2cRM12vZJ8fPPLydj4Xv8FO2tXsL2tZi8eN3S7xa + DATA RUja96SiPEtsJXnspo54O/HclQfIGKBjF+OfJ+5kuakb5nNTFwFAYAQrP4naEP1c0/ECdV3UxhfPdYGQb7ajKcGXjwydFmaEUcV3Vo6OWwXskTOjqMb+tQKK + DATA aoBznMj0d1lO5A1gPJo9sW54cD4zMjqZomnMyAK+IAz4GD+8TI5k3jnjSEYDzsnRWI161TmTsUu9mzbtwU3BiFtg3mZbbQpl7G/O6obBkKUs7/oxY2JVPkP/ + DATA KL4qw1H10AJrIkB1jbQ1OYPloM/ZcoDEfZJ1UhS1+stx/q5mvkJdsNamEEeCNfK2VV+Qv3vYC+/AmnAOTXWP9cTX5EvxNdkF1kTVI8MLr0lV6poMQL75/8g2 + DATA mfX1HDG0CePu+y7X6q9Q3tF98gKrSBfq8u0+ILbXCPRya77YZtsytdprhW/d4eWJ+KpCmcvcuFussJVUm0tLlAolr4tbNUpKf4Fdtf3gUNQxOLBn945tmzZO + DATA jK8ZHdg/uH/+GkpRFL4wC7wICoCEL5CwgZw4C+NjQsQw/P9tRRW2+D/kipHoS3pue/vqb72vFFPh3PGpvqjFHsmXa83i7ABBrZ+a7o+YbZEcqbZw1bfi25vX + DATA uIbaHG5llqqIkdoaGGS/zu4AgGBXl6IfjPvJfWAsmr1r5/i6hc+vitQ1FcClNyV27p3lUhXUVV9BvHuxkuyq70568RIvu4bkw/RL8TU8D2yLGnZu3zQ9sW6h + DATA Mw/VjJqYdeTP35tAAESYQJSyHVHdl48KCUL439yWIFVcmCLjwR9XdVp9Z/vC/vMHzTUjkyfv8ssKYj8RF/nl7ka/N3/V9+JmvybbP7l/cO0O19YtDp7LFO3Y + DATA XBkdrkE9alPM3ep+SgE2g8NgZzR7357tW4cG+/sqyoK+XI/NyvHfo33YOQABvQVC/m6IwQaIkwRqpychRqL0BkHiqH4PAYlDErBKwyj9zmMlxpnVTL6gINvH + DATA x1+KGH8eLX6Ipf1CHTrJVUc8NYllRyvP1qJ96jTKfKfLzo7jhnxhTh+Lphfm0G++5sKtcxj0Tdl5zcp/xX5/ZcQb6T/ILnqpxukNPa2vcESbclSaSz96dfAH + DATA lUf/crFrDrf+zC1K0/HfbthIv/ycqzO8y7EI1353if9Ikmp/37i3PSr909ay/l1o2VUyvbsfOgi08EUypqvuNbhvuqC6ttiVRsF/iIi9fvxxoR5ibdOfuqsY + DATA AAjWxAKsVkUnaIxK62oqGWX4vFwbU9kVC2k0d49jGIFD66xsBUVQJQtoV5DcWtFcojXocsnloTNVsED3Yfu89Ozxxp3nibqPPLxmmaoWNxEUXj4vmSso+jks + DATA h6Z/f6tx2UIXcPjWtOQvxik/MLepbjDBnEXKNaP9van6D3x0j4rrP/BoXhigrNsZKkEIVl0JAk+7P62KMgSWcmVaPZ0I+OjcyxJn8+/QP2Jt3h+V96VZnIdu + DATA SZzFV2Js/qobG0u7Ha2KsQVpF6JVNPdj6VehuM1/xdp8GxiOygf659u8irN5D6TN/0dAnvH2syorMJzxwrN6a4E5Ml91AI5WhXTRD7I7YTcYiiq3bR0bne9/ + DATA KriV4cH/E9tBvkT8uyqL8/piIe8q7pUvLdHPiLGaFp8wJ4QFFKHurDwmruWkLUhUpOS6wHGIh+eLXJDLEblIz4QtIXqBK1Kc9DI0MKhgivdFz4N/jv4Reh7E + DATA 7mGPPw3L7pHhQYjlPEh6DmmpBxGmOcDlPEpovmdjn+fb7POUg4KowOlIPo/BCnHzWS1ORg+0xNNhX8joXJbznE8t5jXQExMy+kF2BaMgH7Ge5nqTmNQS8GyW + DATA cYndvdSy/nqxjbucZ29bYkdCUBJXKmthPKYOgrraaKSsxF+c47aYdUz5nlNwR/eWECBwPk6wStI4H/h5AgzQiSmCpJdk7RP3niJqzvy6HdGxU8sTL0NMDW6u + DATA Qcyf1L3DlXmGgPOvx93kMpXMxPbDF5YaA8ZrL8wxbUIqaDUR/KEcr72KF/vOd4zL1TSb+BsMEm67uRSDAqUEaaJNHgYAY1UqNjO5tVowBTqiuvq68XVjIwN9 + DATA nR2tzXVT9VMJ3Qpku7y4bgUNScAnSFaWi2IMSGAUKqGkyFmQZy9ngS+RFzs7vYuHlsqBrYogBvl+psQXzill0N9le23DaE4dzTok9DLYOXVEdBcGBCDCGZUz + DATA qOUrZ6QfK8tX0sB5KSfM8oQ18EhqPYR93kvoH3HPi5iZvbNPyzIzL/6g5PIfNP3YOYMHBWkn0DIftSr9EOKe9sb409aAMBMl5M59WnsOJMyrt7QZD6XlPzv2 + DATA dMbzaZlWeDHzEcXZ4x36C6w9mgDDqOjJiXtpX2F+TpOnKWEd5GmK57kYwLqYVbHVUm5l+SaDjUs5kWVariiTlyBYu/2MfjC+axpBKCqpqfYVz/UTFhKu1tZZ + DATA 4qg/k63048VO/WXapX/xgx+C12AekUOMACOaf9Yx/d5owoWdf9Zk8QCB2qQhjE+ywCSzWJLvGroCCAsQMg/IaYQjy0DI9kphsthPlAW6gBUSUGXtKFTFvgKz + DATA DYVavz4Wi72nbys0YF+CzDSkyRr7E/MNpjxV7KuxnxiKDUYoi71nZL5Afs93eoC8gnqZVfKvA21RSWkJo6jnMBtRbzpav5BahBGgOuzHScKCYVyDCoBhRK9T + DATA Aggiuarp/M3M2elCwRuL53CII+GgaaSwinpJkoOlMD7xxFEo4XESi5Ab0OAgsfGpLbX3Pfij7Xt9vvyyfn1uo9/dfSnNu/jiV7797f7mCoNIafGaePjlcjVa + DATA 2J0UJtbZuiL2Q2i5N1OEKXaZPRY7XPbwy/BeKPrFW6MFwminS1dUnLvm4Mex07GZ2Ol7HzcMeLKdFh4lIJh1nflpJN8RuCT2tBYt9kf/M1kz81RFrARgnIoI + DATA cybWg37QElV2dzY3pmqJsDp3rJZIIvdG0OFFVUXoVVMVUaQdoGehMtKZeqCuhuYI8ZeU8zZhyx+xtqyNypvSLInyOx7OkksbkVo1I8rTDuezMGJj2mG9Omb8 + DATA a9pZnmLJcdAYlbc0z7dkPmfJBkib/5uQzJwPOwu78jIGAqtiYXLTYnECZ+sHWdRuAA1R5fi6rs75PsDL2ZsH/4vQXepwPAuTQ+Nip+XqmJ1YKq/F6aZwHgPd + DATA R5oak9op7H2E004BJCTDmQRUqNURUEkP4c9eUAWvTPcWq6SwQu5eIAN1N5OP6aSU6MxHDDm+IofdoFPIeRTGMeR4IECEkMiUiC2QQI2IcU3BuEHnaX4lxpKT + DATA 2ZqE3hFrYsZOUoqcHW9GrJG445/PFLSVHh8OKqksLkdjazMH9j7d11epzfeVanhZH1523q6Zx/73qhPrHDk1jXyyBT5STtxcd3eeyCKcm5jJG4+YCIrv8D5Y + DATA 1kJtGj4Nng7K12+49mCORAZh7F0AT98W+z3RQd0CWkEUsSrVRIsLcz12a5YYtMJWGs3eJerCFETUNYArDnNy3kkua5YQyBZkad3l8llhBiKFBzEYSPAn+n1J + DATA /kTkAtmsNs7lrrKGytvqLNGmqdHwvtue7q4ItI+2B+zBSl0k6t92+ZHmikJ3cY6+uKVJz3fqyy9Ym8P878TxDb09NYe36qOa2O8rVef9+qNjkAcNEHuk4sjm + DATA tu9dvqm7a2iCIUz0rLt6g7O9KlhT57F7IvaoT+6vcLTddtmhy0p2lJ/45M1nYo/F/joT+01YzQM4p+BBNbIKHp1gXVTZ3lpXm6rjgXxabYqOB83DeTQeTNfz + DATA 4PHEtsyiHvyzE/VYSKRkpUIfGC9N3GQFyh/EhfP0UBLW7GSt2YqqhZHKVFuy1cJUW+J0eNnCKLyztGHaIN5K7QfPTxvgW4H9sB/Om/lL2C/A2q8fVbj7eqNV + DATA 89EYnWvBCkibeXBpM64mFJP9BJwtkTURN+qKAZnzpQuUuTaRTr/vBw1RJq4hnFVMVJMb7VqBZfEXHyngiQTqfL77sdIaJojJ/tUQE8IQxMG4he+gxKyFx8CB + DATA qKWyYmiwr6ejrbGhtrpirHIs1doS1E+zmIYPXyjGaBx1zaDRAzR1ImBALlzEDwjOzvhLtSSuGNT3LpkwWcFS5G5e4x5sdSazJ+hrLnuCVuJa8p24rxhF9dSB + DATA /ob6+WivWMT+XKfSOXMYS4SVK7Y1nr9YTLkSQ1cuEUEScd+yPW7vYbAtmt3f29HeWJ/uo1GWr21RzIME4gWC+JyV+NwBfvFmvxV7nKvYnr7RiZN3+eRcT5/C + DATA hXr6VmJ8Raa2PeRv3qdwQgjCSMcZ7IwaWltaelp76mrLS0MBH1MFMxk0agVSmWFn3Fr9AOODjigG+Q6IQ5sVw3ACzTUj0sagUIDx+azWJoXF6VHnvOJBDEv2 + DATA gnHQX1xnyB10u+evgxqmL8GsHhFRN7X+02WKpBaR1Fm3d6eL0yJ6atQipaTrbym7OGUJ7PWf/HYe/r+webzX9/DhPfhPAgvLFV2YWwGz/V/uMs+xvnGm5bGE + DATA 4f1D+2pOwu8kFY1AZSzA6nTVIhUbAJg/md5WxNDgdpqNHCNBIUDCIKgPEhFUEYg1FZQkeTHYYUEKGRTOlhbJ9IY4thy2fCEv+FhFshnO4xLrw1t3ksvV9bqI + DATA P3j73B44rc/bZzF/+ldL6nwdAjinXkU1supVNWA0qna7opFwKFXDCvnXyriGFSsHCYJpWlaApsU2XkZBK/6ZCVrhC0SxZyRyRaZHrssVvcJumh+vsjb6BtXJ + DATA 2igCuqNKt6u4KNVCCDfBhIUAFU4zD53RMrwzs4w7LTY9I6vckBaPLtsqf04PQlmbEJAKsDZpAkMIN40Nft983JRxVimElJmGC5hm1UCjyBhvnpGR9JlizGVb + DATA C34vY2RJsHaLku/EsdQB+pDlmptKS+ZbLsRZLuHWUw0FYcIFCc8KUEvFLmdkO2hZLGBZvgGXqBpxWluVrNcqBRUoWxEOFuQ7bLpsmgRO6KRZJQeCxEgCQzSe + DATA Yhur44CjE5DVNEgj/l9KZUuxkPTnLYtpbR1Oc0AvLS61RY7Pczvxp/wQ+R1OUQyCHHfyGTlFMQIjwtyzkSnPRiz72fA0j7L4cynSXMgSz4W/kO452KfCA6zn + DATA qAKlaO0ilV5P6tqZXZAwkxA93NktXGafsPhj3p7JCSzxvMSdGbc+wNknP4/d+0FQD4Lo2aNVRYWpz65HgZkwAdgVLuoSu3qJRYb3LLaNlzKBZcksdTtTIcCo + DATA W0E5aAM9UWljA8MS6ivIMxuZ6i8f2aCs2KlH0NZAElZACpVTcQIPx9EOkVwbmYzGKCopq8iGsyl68JyygQZFZBTi0ePIebmMI9rHifkSCZYosariEgGEW6Xz + DATA t07sr7/hoV0N7YODx2+4qWmtxobtPiXR9ztq1ypz+TJlTUWbRtnWU6DwttT6Y78iLugf7S8tL+ppa2+x1ZDOiee/+OWXHr0uuKtr4J7bH3ts2/66oksOhwvc + DATA bQZ7v67Y09oqztZn5Rz1+Biv7yzM5lOCmS/eO7WGoQqt7Q+PnV93PK6URtxPiUE32AO2RB29PRDs2L5l09TkmrHhwZ49vXvS9bgQY0IkoccF+EIJRmPzkw/i + DATA RYS6eOdAqGvJvo1VUfKK7VkqQ7GKWl/w/EyZC5zTAGM1pdEpVRmVoDMqoQSGvLcbkb+RBOBOqIyyYNTyZMEWyvwuSyoMvph2Vi2tHYY/kn5ccc9L5FGd7PMG + DATA UXdYjjvxtMnusIxPSS7zKdNOq+U9YV7aqbX0E8LT6QdX/AmnqQD7hFWovoZOrrkr6uDOLfSgZ7+cmU6u5T3yzzKdYEs/O/ZuxkOMs8EzlJi1QQPoj+rcrprq + DATA SEVJqJjRoXE1uBsS9kD5IX9K6xefT7IhK0kKM6OdXp55lsxvLstK3Uu5imUYayBz7hLZ6iHynfiOqEedX+i8n4sYC3fan+22WOK8X541sF8uduwvwxSbluSR + DATA vhf8nbiZeBNkASPIR9xnMqnDnq2SGmUGAZ/jPgMQcH1TBISsJVwETGjloj8c5HzC6zQyT5BC70K5sH8VlwYVHq3c1hLUBDWwbg6jp1StVVhbguqQRpHTF8T/ + DATA qaNUCs+oP0svEBl7S381y+o5815xlH1X31+qyuOr0NM0nm4jAsR9wA18IApao5JgINfrtJtm+8KCbF9YpR8jCXPmtjDJgm1hSWa3hDYTTXOMi2wtOS7DBrnU + DATA m0apmcUDRWNTZO0EhvX2Xn7DXd68njIb6ghzdtYSWM+Rd9oO2IxKdxZqCHsJfloZHRjsMtdiDeLI6EC7oQrDj1rePNZyoO/TDz36yKZdwoO6LF1RkXek7+SD + DATA j8Q+GjFRXluTwcKDHdh3+MyStzxwlWUHgUBw/wU6zWvB2CUAYJwyG9UIGsEo6IlmQzA82NWZrs8mQMyUnD5bolLKT+i0saniuWJtWEKsjV5FsbYFDsyzFHC7 + DATA IO0kPVtBN3Jg3jmbsG4nY91B0IQU/lqa023L9tckbIvTYd6iAnjU6tk0/Xg+S3vG/pN2cJ+tQfHPpB/rnD1PUQHGnhOgE6F1fF1b60JoLeQs2jRbSeVnNutq + DATA QzVTMHCWBh7LFCWcraGJGxaJIZDFf0C+wyJ4GrQim09O9HQvZPNczuazluYqeecYxktOQ56l1R9d7Jw9a8url7x/s6p6VCdoBsMoTm9rTSjrsXE6p6zHRusL + DATA yOuRqymvl+4uVkNuDwun+YzV0t8jLpjnO053M+zLJupmkA+iSEG5siLgRwrKKmVcQdkMWdlgiMFw8oxfSEGZRmYtQgBMNInJwwo5UiCLS8zToTmilDY5Gvud + DATA K6Ecq7u4VG+XV+r5wt33eIeeqVbkhD1SF6F2aKos4Z7w1u2fCctDa86vu+FDX75IpB9PSCivGRv/WuzGcj0/IHVnvwvfuQ4aMdvpy91ZWbbxXceavjhww4Hc + DATA /heqnn767uPFm+BrJwaKZK6EinJk4zGAs2i6h3yHRdNmFONOre/rTSCKjXE5RHGR7rmG1FKR8GpADP/DYht41fD2m8U3MseF9mt6hOXsmUasgRvHx4aXYA1M + DATA Y+vhAwHGR5pj/99o6uZrGaw6M8+DaeIIq86uFEoXW8BBKdNHsY4cYfso2lGPVltDzVI9WukdFDTg4TSSzTlnnSvzjY83raxTYm+ajVfSIFGQbkYO4xQ/zoy5 + DATA G2yJGrZt3bhhPCMrVUMqzkVQIBSEZ9EuBItSxWH/DfI/LiOaVJmcFchffUKqKd+mAUtTwBPUEZIs29Yea3W2wCql3YNDq05J9a7EqK9c2+C10L4ytd+pCxSr + DATA BYLK7TvjO+EK8s/sThgEG6PZPd1MfL1gP1HDsvqJ2Oz1uWyhzbhEK90cWCDjSqykJ/RDidFQETe2xufU+xPGBtjpnhhNllMKsA5sA1NR9eTEQF9by3x2zIZN + DATA EMfG4/tkDYRkF6QhmTwXSNTe7ufP3SY04CFnlMPtl1U9FWhkd7QOKBCcyw+WtnvOaoto1cX18ryQ0lsglhjKcazEWDO8zsL32uun96bsm7evWOnmcPvVhfIs + DATA T4W57iAtsXidLarCXl3ndNG61vx7sWjKjkFxeDhGEyOEEFSBbmatlG2ttdWlTJ0kz4tiJ7GQOyGaPJCHNxXrcIpXrsQwmoYAI5iF4pE8dqFoHkkjppi4cgyP + DATA N2dX0PS8k2K+jRfdHolajpJGcr7zWr6wn6Yakxmc39hp4GfcGuz2cVlCn4/Vpu+R2F8iSZt1bChc06YZt+ryF94RyjFDewFPl3sjvCV1bwAMTDJR0Q76R6AE + DATA NKGqS3kZ6sUy6mXxWVtWuDicYEpLJ0lLtFFw88hhueKM6dHQ96QPv0xC4dVHvrZMarR/nPJvIZrSZ10eMMJcKPjnzcsmRisP7yU/PX8Sroq5e59PdbIsIw1R + DATA Kaq7ul2sToqER9FoNjPev4QRGCSCrCgj7k+aSZLKREQjMy2/zw39bfqlrxZbbqPbFa98angIezm9i2l4cMlOt6NrxvCvpl/f4lg5wmKlF1Sj+1sqVnJLIWle + DATA Hl7os8FL5un/M0YO/mHm2b+VYIhyZp7149DUQwUYNLWA9qi8uSkYmIsnHqoBFbOdX2cCKt4KQJUxQ3aG8MKpTCmxZeKMeCRj5ovFG/EL+omEb6qt+e/7pvQL + DATA 8pkj7C8p192VeabXjLQu25e8zHJYwp8g30l4pvKy+Z4pDT+o9201PVO6ac4UOjkphlkuXvLS7vWcV3qBfpFByQiojUq6OlNRkt/Gzh7+V/wSCp7d6D+uhJo1 + DATA Zx3um+gVoOcGmd5HiDUWicImlMkdI1FdsfXtYrFByZP7u8OHa1eGp6soKSOz6/Qrs5gGSr6Up8suGNxdKhULtdmF4RxVvjaOMOI1imIQ1gbaUN9ROsICNRBQ + DATA 0JoBZ6vorFzuAizVpuxfn/lh+NkCrcgokItNHnGWubdUmUs9crFV77LpJ5d7LP6PQiDIDrc6hgIKOotnt9RtX7NJby3SFlhZ7eE6Bou1DBYrwFpks77espLC + DATA ArfLalEp+TzWZl2QQDajCAoVNgGGgyBg9Q39yb5U9sKQajNkIvns1QrDJdgyObmWBmUvv7xg83VKc14tItt67nK/cplEXXjFEuD8c/VvjkLvHywkhfi3Yu/F + DATA Dty8b7n8XeQfl8YoDvqYfMcJ6mZQDKJgAExHDX4fBO1tZaW+qD9akGcx6bSyLIoExbAY3Zhr9ZDGQyIM0JiVBxFvIR8CmqQBGQQ0zeVYufvxbKXEJoAUNfsK + DATA stdlZ6oScJIx0qdh1mj21obRiWtaijCwFMYb7ZgFmW0Lo4hC1XD55oi2hNddtm/X02Elm37+c+MTQ05PnV1oMQ87xizhxuJ8vUs4Mzp92YkwEZQ3s3lpwqQ1 + DATA D4spk1Dd2JQjyrYEau3trzG3ZG+2rmKzquBC/5Z7y595/oFrAtvHsb6teW6xrqHjT9tjf9j84n+Oi+RU5NU3/s1cCNg0dewd/DSpkVvXTJTVm8JeidR0eO1w + DATA hyGCsJ3gnBODFtCDKqlNDSgCZHQDbRo1jwRiKOIjhHNKQknNGYjqqZC9FBPEXIbOpAIpPUfEl6tJwZXifTeijsN2IM65mStWjGyKZY5DpHMzH50FiAGGEEqu + DATA ZxBaB3rBwaitoR7hs763gWH8LSsJ+PJzc1xWYxyldbAOzUZ26KEQb2ZQKsSQ0CcVFkEg5AsBP0hDEsGWJJAxhcIkYPn8JGDFUCCYA1jB4oBFuHS7uJ7YcKJq + DATA QtPhELsMdgbFqoUwnAmuVcXe3O7rs1TyAv+/KvT5Xga6/PJIibUy39nr/uJC6M2A1J9eAyFBZmkdUjdxu7WUAa36BMQcNnPJnw/PPLCpch5w4wy//6FHQDdY + DATA j3LIk2ND/RmZrDNwyNKAR7FJ5P8imyxMTyuvDrlvTJ2WZF5Fztj35uee2VkNCTnCzmpEuRmXqtJg5hmX9JkoCtCAYsXYV2v8J82wZzrbEptOM+DyRzIa0u3D + DATA oZM0szzr21Fed9P05MTYaDrzN5vX5RAqgDw+LxPXMR/QFJve/W+SUWdO9a4KYHMzpn1XEbl3ZUi9JxAcJv/MIrgFTKJuzfq6qkhpSfr8GlsjXBjFPEABHsVq + DATA bKPeC8HqzWtlNP4Zgdqd0cjLR7csY0Y9oSbwRILZfmz0/z6z/epTd284V1zdr6YlAuITqeQ7c6ctS0syT1umoRUZeNWmLeVnMwxXuTrDbwCCnhhNPEEpwAbE + DATA PDM2OtCP6mflpW6nSpmoEtQaIEWi0gCGVOUpgqSCgOIRFFLDpAne3AoBQSQIilILBPxMBQK2m2oxxAWXj1+ago+klgxclsr1L65vfy0T8pYAb26usar9+ynF + DATA g/aJguH29e1bvnXnIsAbWhrB4Rxlge4BgIGGGI1/ihCCclDHrIC6sqKirrIu6M/1mE16rVIhEmLsGlRHIUYDCPBCSKIeC4wmaIzNItDIA5Ao8oUgB7WwJYeX + DATA cDx1eImM3wKSznA+SBNjXukrlQwT/sew7vyCKZoavvrNlotHbc0Y/sVnZlKw6g6EvppYCEPt8DqzwGWpgp44dnlYbv7UC7fe9eGg0WSuv+jFfTvwuXh167w3 + DATA H59r8cnCYfwXcQAnIgM1/SLoBuchZYrNmxZQptgAKRr5Tez/iN/El8orrI4n/dISKYZV9K1XLplw4CKEQxQVjxD6o0oUIcz3tqVRCCjkcbFz63HdmVNjZ+R8 + DATA w5nzYst1xP9ZJDGGgWkG4RfQP2JstgFx0nR2NDZUR5kH8LmcXKaW5aRphTwz4AHenNIHiREk6wxwVjE8LXGbzCDwl5e4pRJIZ8zGfmviNUrYuNX0khWmaSi8 + DATA 5qJvMRncroatkXpbKdPfJ32gQj12w53Xb9hICXa4dm1wdmBYSO23StVl9ZqCgQq73OMod1kbNwtLN7xc+/DVvg34e5mrTp8yoXzu329dIJ/74G2/+8s3ftCk + DATA DXlGJpoNQpGsUBsVKHCCL1au6TFGserpFxu05eE9lHtRxZW2mZ8QU1QAuEAZ6AOtUWlvT1UkHMrPk7OMKTSqQokBhhPQWg5JMwUR/yFK5kDWPROZvbEz6Tgs + DATA mlDSJaPcDOVK9B9iyW7MsGuJ6S3shltffLhM6R86UHcSZleIlCKdO1dZLAo7Tz0Z+2fjpgK5e83Ggpd/Y6L4yo62vj5Xn400lo6N9TbBH2eqTP383Wcqn3n2 + DATA 3suLN18q1ot0EpFRe+C8WM7M7+7yikVCrdIuLfc+iZ24Zdyn8IbHj7Y+dIvBGC6dOIL9PPO0Mofwl5jbXQvYCDZEdRPjoyP9fe1t6TgXoehDCPkC/jyQCwAP + DATA CFDq4b8P98x3i1XBO2HMfOlYBbyT92a+07Fov538M4v2AeSxu7uYXri6yook4vnIY8cRP4tzGpCQJtlsBHLZ5wj3Ge1+FsB/O6OxV4x8XaYLH4t74m36CQb3 + DATA I6AvquzvW8izl6zQq/NWFebpBcvV8eXvpF5cVgPPr6ff8lgUd5PvsChuAXVRSX1dEr8Uqvam45ckFwEtfRagTbfiWSD1gxTTrRida+fPbEzPvEe8zerjjIO1 + DATA UfXoyHxPLEA5nHRI8mkezecFl4SmDfB4Ut4qu2E5ZYtfEF2cMBGqDK0KSD8dLVHa6nKlfKMid32tyVe1GjCdKdDqNFJHS7ktV2W1iHTVox2NFQmsUltYrHaB + DATA jqi0taWyIjW+CCXQSpGQMXNwDmrF58bVghAqgbBsFWq2Xo9+xllA92/pFl0pevEfLmRF7PQLp/9DfoqJmCfABUiZduOG0eH+3q6OlubSsL/Y7TTo+TyMU6aN + DATA FmGAQO2/mHUSCsxAgAvCqIpB8WjEtAwoAiSZltEsGNcNnHzBXbD5XLlIiG6KLhuNzYGygr32sTMlCR5mzvBcoRN1qobjhU/EcKFRJ/4CS1y8/XMmzUJhRcbw + DATA Gv/L+X+66J7na5vkTiNflXXPMzyJ0iDUKezrj5Mee5vZ76Po20KRSu2URiDNsgR//ofc8JhK3FhgKiFMReYqhgVboNKo/LWHc3JztA6hQDVd17wxR5KTvStj + DATA yI29JcyK1b3SqKXFAmW+cA98CyMoeZZDZjbAez7DskF7XaVOMU5lRwydW+tOPaJ7AKpO9mk86/bf0PcoIhPkuXMVBVjslet1IbGcZFgvckbNhurL6snNi0Ti + DATA 2OkYc3aa6W+BBjAOhtFc37q1aK+UhIJ+jztbLeCDBtiA/FSpFfFmWxu5WUqMDifYStjuYj6cpSVPJyZh7/3ICaURkwAFWq3krFTcK6GL+0KEJIzfXGSoUui4 + DATA 9pWSuTQkcmiqFjbmm8sIR9DSZfRkaV4YMEYnOovy9V5dUWPeHA6S7ebPZorT8Y5H/tKSwjvixW6Hr/epc3fd+kj/d+tG5eb31mjDQf+hiang5nvaQyzdiCo7 + DATA tHn3p38bbcHvyhius7uLKqAUYB+4GByOmi46fOjAzu2bp6cm167p6mhqiFZVlAd8nhy0x1BFtq8M0oQRiuj9fRgQAcgDhBXwUMQuCAIBn/k/PwUJMaRFBMcb + DATA AwBPlL7rElVaYXJpMm60IsQZT1GJ3Na8XUeHrBEs7vpMeHx4wk0tvfUg2qssc0/mrWaXSYZyS90Sh6b2lw4sfdvp/gpl+RpPuFBZgOE+a0VpnkZV3CCWVuQq + DATA M+++2EvMTi1bM/DVw9pFttuucFBA8jVSj8RjfCCatvN2HpTdfAoN2hV23oLhpCgvX5GHUfv9i+0/+A3dZ3DeWgDg6dPMXrNQN4MRsC5qgKC7q62lubGyvDDf + DATA 47ZbjXq1ilnGETiC7mflQcgH0MrpWvIBD/B5aGaZghiNYxB4hBCAeCAgQYEAWlTBXCKgNB4gFB8kKuyJEjvFVdg5onuaWuYe1IVP9t47u9NUObfc6NA/kaVS + DATA 5Pv7pDQpZNxgGZH1M6ZguX2bMrvWMKTNyn5+wFTF7Tytr4HdeSMRtPNatpmZDZZK7APDGLxoL80W3WF/jrdLnbupmWCL7lhj23c6/xJcfMvFtSgJPf0FYAHV + DATA oCWabbNWVqATKw/1OVTbqjmNRuTTvBQkAA8nuBsvzcdwSOLo6xXpVC5Fl7SkGCfsWYrdZDnKje5MwlZxJrdLKDHLBNMXNbldEKRywSSZzURcZzlPiBFYOhtM + DATA guxMkEJ2Ri2fwW4JQy3BdvaXpcy0FOGZJBMDDKdj+jY9wmDHh3Rmi3Pdjrk6szggII6ssUJdz/ntAEthIjetAWA5EDg/vfTPrXw+2xkR5jj8QkV56Rx+6DzH + DATA WE2Ms+Oym/+Qi69n7Ptpz7jU+snSn4/b8wJWH7gClEelYQbRud6Eqi56OjsFCZJAUctZbvLMCZOl1Gj/mDErspxF9WTMMHGru4XtGqgGtagvrqI8FCwqnMs+ + DATA iXIgTkCB+G6eu415K+ZqzGiKxRf8oYyGWIqd8s1MWSAYeydGY69RChAERVGB28XNYyFdOpOSZjVUkwXVpOILt23xBaesAuHMWEBwaEktixa5O3ZlZS0AAXz8 + DATA 9u+XRWyHc0QpRc/eHf4NLXK3aMGlPxF7fOY379fZ9Wt2Whh0f4d5tkfJ34Is0AwqohI0dVaQl+uxmgUsa5GrskiKE8wj4nA2Rw5ItJNzuKwBhBJoX4iGCfWB + DATA ZlxfboiMWrh0iU0mMyfKYn2saM/O+Qst0MmyTLIfpxoqx1ZH/DI1vfTRP+yXbfhooRWvMvGkFvFjR1NHzdbFFcF/RT+RUNDO9a6WgvaZSS1jT52xtnJ/6sNz + DATA WsoYTQiBE+RGJRAkdy06dVTcLiVSdim+7F26+FZcYsMhO8+8QeGUgrFzEyiLShvqSpl+8ry4teO8vQADBBbEIWdxEiZMjm75UspOLvNodEC5gktZcW9FsEQ1 + DATA F8cSzbVLnZeDbqiG6p9fUCw59pqyuFCRX9AxFd574drcTWun7v9j7JNbr/Br6GWs0syTJsk2LAc+BX/5cp/5NaVSam+OlBUr3Fny/L6bYy/EHog9G8v7zkE9 + DATA HxCgZOYHxCPs/kSscZOgLqprbJBJGQ6tycbJaFXA581hWCWCsqCAL0AWIyHalnwKQ9dlgocl6NKQxWhaSi+4V/EVEcmif5UQrUOuWsGaOP4vsY6UTfzOYkjB + DATA fpgC9F9cueOCV25+QOrP15+672RXwKQUMPQc6Rv74yeWOMrtqd8fi7V/L3YqtjH28esVtFnp4hXBEqiEjW9cluD6BFjsPobDJUL/iFX5LUEqv057tkYiFrJ8 + DATA dA5O5RfxzkKAA1T2BiDeM8PmT6U4G6kuE26Zy7Cx+5aDNOJAxqRPDCwXYXzxYjmc2AMzP8CFVABoQQjkRyV6ncOuC+lD2RoCRxbRAAjMEKLxZYIjjmWNgJxh + DATA 5qonzcKGXBg2MJYpYXL3lTuejb3bMYRgceP9J3rjsCAHMyVC/tD+9dipmadmGizschfCeqiFra/vTSw3us99auY9sphSgB6wCaxBWvPrJ/v7uruiVV6PxWw0 + DATA yKQUCXpgjxDdm1t9YhwQ7M0Z4IiplQ95EKXTuVYUig17aHRxSXarc4l0HutRleiJCzDUVIIlbMN5LgmWDhKK5uh80tl1aTVzsVGjrbhAMp34rtxoqL9jvKfO + DATA VD7d+O3fZznNQo2Uc2qNPoszy271VRrDXUOWhnGz+x/TFxRu1PMUEl13tTo3Mn286YamSPNEe+/GWu8nR9MTwDfm5SmLCtqnQtu+Zp15q4IQCRS5yfjCZVFm + DATA 2UMOnYJk2kn8rffEHt6166X+g9Grrwm4xdlKWmjXh2+79qI9gU0+X+nJ8y7uVM3sWyAxjFbkNFPb4FM3g1owDPpRvNnX21BfWV4SyvWqlTwa1MJaFG+G/VYk + DATA zIFKQjiigMYZQLJ1TQrQVDCRKwQQc0MUgyaOC7aryobPS2Ak84XM34USduXcHGt19Wy2CeXXFzQ/9st3Lg/aK3T5JQUyuyrnpVtLtMJGryFEaFzZ1Za1csHv + DATA 9zZ4ssSRoXJ1cah094fm3s4aO8ojaeVWXfXMC+km58MnJ7uuKIkk0hdHsM6fP8HkB9dfcGPX94ZjMwWqsb0NlWZDltshldkv2eobH7lsw7hITpl07jyVPybL + DATA YGGUK1IQQtAKOkB3NLutDYK2jjYmL1heluNWyHk00vhDNi4uhhRei2piaJ6IYlBPgSCNlP4A6Z/l2liAdY1ikY673RJ8cbbozJaGyjD+jFbuMtZfNNAQ8mbp + DATA Q81lxeVsWkiGeKBVfJYHWu6QqLQi26/21iUsGyzd+29Tbwdr2Zl34WucMfKaxsbzuyfv2RXJxPLcVNfcahkb3l9fPmvR7b4NQ0c2rGMsCgcwxLz9Y8Zyv2VO + DATA hwrQBvoQNqsifub81WlVSqmEzwMVsILVaiAhznYAkzSim4EA1YAgOjD8aCiO1bkAIN6+JrQRMMnJYENqhyFn3A0gjU02bZHkzkY8YAuW4wKhNJ4B/NLjVz50 + DATA 9/VvQE1O26ClPkftDdq7Hr2z/kh5pVViUg9sm2oemo5cdu/u9ob99V3uKjSteahvtDqNbIC8Ova52Fhs50XN2YRWG5oMqZV8lUasFepVBcZCcQEMQ8vXXnqg + DATA 8tjE8L57Hlufr9LK3VWC1s27f/DxfCVNUMncJu+hfwDMoBAEoiKb1WTUMisv4KHTxMKxQqOSJAbR2Sqczw0WQgBSJMsxWGouEaQZYcxs0LywT8Ov8hqDhMVv + DATA ec0dT89viGDtaU9a0z20swkTwa57mU02edkDYzNfv9nE5QCzqQNpD4PQwHiqI5SaQUMPWBvNRpNP8/GAYrIIh4eFoQB4GI3x6CA/HRKJeI1/lrhY0FetEByf + DATA vJHupFYOjw8uyOCf/jnzHnYjcwKYQRCURyVFhUmUUGymAYUbAINJtz8HJcjrSwk7FYcK8u4JqOBYClSwhewybi529T1r4DejXLMtZL/qwCxe3OmPXtO99bPn + DATA fYjxoKFPnbftjhc2xrbEHtoQB8zMRws/HfIhlIC+FaGG8yHNTf93fEh4odnNFWLlvfljmysHC1xwbBMD1SwLO4eVfBSvz/UnWgLOQiXFkRBLowMuZIlF0IHd + DATA Mf9xFwUIceGCj8QhhDxIqUEWaAMDUabrtramrMTrcTosJm22tE3WRpFs15EKEmzqCdIQ0EFAY5DG/AAjINcxDQmcwQiEsy3TJEQPz2IknRT7bDBDjGmYi1tf + DATA EXNxU+VNhGOnV4QWrLCyzi8zi8SWiarsQrEOXzFUOFTgP2VRUYQy7Z6cuagwssqGSfmQ9CNmSWQkL8HIGIuj4kFrRFNkVLsHK3VVxfmLAgIjcK26cGu53MIY + DATA oaK1JAAARFhgz5hBxOgIQUd7fS2zMGxFL0vCo8AgHGQ7fUiIQTkkcQwVbiHgQbYjG8NZ3ToM6dZBgOEQQ5Nbyfqe0EYlhf/YQjodZ5ZnPoReDBDslZW9kbhZ + DATA 54kMtjA88Et3b6/y95lMUXcTRZfU7im7+GAGcBQWqj1FmNQqLdIp7bKwvaaVarrqriseTYMKefUvLzn+Jq4vCpQQJBV7a/OCENFX5LYfhzifklIys8crtymx + DATA 78ALHrx2Pl4gyzbyKHU38CCuEavFoNNqpFlCAZ9HkRzXCOeLAQTJIwfHE4GvOKEBCGYlADnvwTZCsahh/xfH5lU95SH4wsXZHp+z7Qf76mt7r5JoGlzH1s/C + DATA R1tS8utm8gfZXR6VU5Ejk+UVlNFV3b/bGzsv9sb5HGp0ZVuin8W+8G+AAffpf1N+JjqtBb2gICpqqC8JW0xKOXdT1+WKuEw1wj0OUcICQtR3xBVfNEr2auqS + DATA BcI0hs/OSBBoCREelGxyAkVerJjhHFJW9GjpURdRCF3VXSNDxrIs8eevq9MR+Y0WoT0ytPlQ9OQFdXKl1ChUGmXuHIvrpguqpTSj1z7Ro/dXjpefd6WHhoq0 + DATA uGzaanOFLvnfCz+AWZcflsfen/nzB78wNevWPveLf/71p73PU4TWULfvt3ffc2fjnSO9vbAJqh+520q7XBIrw0D29Mvf2fL9j44qKXJ+NMpq6UxSnew0XxN3 + DATA 10xXz2HZ08HcphTeIko51DlQyknX5FoVYZztabxZqymD41iAW8s98x7lp1Tsrb4kKkF2TqCTQlnLBDrjNk4CNBHQkWeJ0kyX9rOC6swf02PCVcHqzPGFY0eA + DATA MTeOfELI4HUa9HBM6fMRy2opJAwJeJCG6HaRCbSJWwZ9DpC7oMFXBb4zz6cbfhUB/NHnFzI/51876RcZDG8AvqhodGSufzUNQoxgUYydGx+rWHoi7WygvGaJ + DATA SbRVATb57tKsN5xX/i5FsUwCHcgrb5peyCsXrYcYnXQZbDiziG8+JwjHM0+orQrOhzJOrq2mwy5cjPUJAiVTpbNQKtAE8qKCpobCfIddyCdQTBEpUaMOZitk + DATA a07c9RvDpFw1NDwf23IFqiy55oAbzcjOncfEkWklONeyY+bQW30NQq/MmmVwa3zh12q1BC3JYfArd0/06AJlgdjHscHf3lmko/mjN9afnPiSP0tq3jPQYa1F + DATA OyCSAtH6i//6zNOPt983Cr8Ixy66rFxXpkxg9Iux2E0zptj42w6BTmTb1nTjcx/BVy+fevSw+Zdv/OEAA3YUQc+8wfrfDnTXbG+rrfYXu5xKBXvXjPdyI1Ow + DATA yEuagrtRzEKtaDGsoYwWenTGHjTXYp8ErJpJEJiWAJG1cjB06+ev2mLLFWbVbdu6aazTWBGeC0S3U+82RJfGykX3vc7EmS+9fDLHIuJ7Dt3z+a98efCFkfIk + DATA 6ND00S7mpvoYPQKUwA1KkQZaia8g12HT6+RxdjoH2puA7ftJ9roL56taKUIcN7BFo6Ywippl4Iu3ucvdnBrj/O6f/UTt3nvWvf4rKO010Y2H7l/37W8/v3U7 + DATA 1FaRWk3RLbdee6T4pEt39SV3ndoCLel0J986CPnv/7Tr8f8Mno598P5POh8/cBj+5R+PrrHUTT7w472w+xe3PnH/v/BjaQ1BCe23veQIq+UVRs+NOp4SSl5p + DATA z322al7prOzL1Hxzpj3tMhS7huc/KbvC36e/y65wLaiLyiOVJWFfsdeTWGUeio9pSFIkSlMhdbfF1po6g7XO3AG0/EXH3srYDrTM5fdl5jJHKLiL/DOLgmpk + DATA m0RnVAIJrG1YqyT7os5e2jGzXZYFDPibjCZZBkYcGblRCBYrP6d/yGIFqblGETuCJ6eirbItp9xTPhcxNpqkcJTsXxWvgO5HRWF02HDpB5K9MEUw7vUZ4eVD + DATA K7oW1eZIRBK+TD12cEOsi32nLkdMi0PM62XCBociHVNUXVORL8FpXNK1YUM/xr5VNVZuLBKwb4C4KuC9VCuLoTLQCUKIdzjHna4KuApimbN3dPSemjlpcGLe + DATA O8tTBlS2lguUmoKdLSqRTKiM2HjeSHushXtzV6tSKBfKq9g3l4EnpQNDVtn8cAEyFI/hImppby7j3tzyUH5B8k0UGQZOv09/l1KAdrABrGfm3oa7O9tb62rR + DATA rnPaZVmoKw/dfuolEIcdkMDHIUkAyKcIVLMncQJlw9Dkmx9QfJzi+3kwmcVhBxgA24WcNo6Fqk2sbc+Q7CSVckLBgjVBAaqYJVvHT73+2vNbH91Ue9+DP9q+ + DATA 95sbn/k2wxCxOcIwRChyWMaTO9Y45SqZFZFMZBkQyUTBxuyWqy/aylJMBC+49q/XmI8j7O6kCF9R19feLFzf79/tEt9w54GX4e1Q9Iu3RguuuGL5jCfdJf4j + DATA CVoJkriBAfPMT3c31MHCTb1NiF6i6EF0LhQyVQwlIQT5oAo0gemorjoabapuqij3Fed5nQ6rGXH+oXk4IVqPOgmG8wAkEGEEziN5XFqSRxJ+AR/j8RJLwJXs + DATA 2YgdAPZiOvsC2PmJ9UjyoSxGI+ECafifZZXAfvfAK282+Atzd++5tf2xG11PvpiRRGL0jpg/Hf74ZXFWiVvv/+zRF584eV2FqXvwkYUJJDrgHWmAh4oEMQp2 + DATA +hunf01iTL6uFYyC9qi0ox1VD82mLAlNcXOEwSYNxhUOMQqlnyAg5xSBCOb//CkNSMlUbsBqi99xwrM5XK55hPkypEbNlqg8X4Cl9qKE5cmiAFucx+Yl9mIf + DATA PvhocdhXIK/pOgjVJY+/Un30s3f+qMzftbnXGFHQ2fqqm9c0l2bnqxw6qS34/Z+xnXNZN79QMd2oDeVk2fSyYr3/Rw98xpGW5CM+/80pY7FW0Vw3baIiwa0P + DATA ff3+k5VFI9d+VUZKoKVI5RP6O8Z9k0X1pZqAZObdNraRTrgdy3oUOuoUMrEpUpx3Sft1hhM3YMcXyPQZmQzvH6hOEAB1iGsbbedcr9tpMWdJWK5tLSSwBIsy + DATA DlB9DQ2fpQb0ROKIDjFxvMudvMWwjSOaRBSvnjtugLPLkM5yH87GxMLXcZOSD3Wq3FG/3AUVOh3Bw7JJ99ELHBsieFaWtVAsVDPhfOHdU3kynd+PCdNSdmwk + DATA D99/vEiZiOIdXT2djTI7X6Vs+WObqnGgVFvCVxi7qr4Xm9mb61QQm+drln2D6X/CKAWDwQkwiPjMUlGIzurKOAozAJAmKIKmgmlATPTb8FcTjRkSeKsFyU8+ + DATA Sk8qrR4oP6IXnoM9MvMefjchZHDZAhqj0vq6uchEPqCQQ+YsKCmCJChyPjhRJ46UtNMrQWimYvhKYLox3YZnDNOZ0wuZKu4vs+kXGaxuB91R6frJdH9Zug5i + DATA FItW7P+jz1yaOmr1IPvzJbJ2q+hVNyyZumO9LNFLWYAOdCIFjY72hvqaaHmZ16NSsgoaUghBgKtSEhAVqIMJ5oFkCMAyenGFFHpOdi0ltwZWgvD3zy/IFpkE + DATA cpHBK866sMZDPXWASaXZ9V2fdK4A58SzQQVfoA21OvrDcl5kS82uiQ0GSyGTM+v6mHemkAcAQxEV8R2ueocYMBCnX64X6WGRBMuAAQFXIeHoinDUBIKKkMkx + DATA BADSiP4TNP5sM3eyuzRZoOU6HELISGzAilDMGi7xV+l1vU/43YaOiNJb5OiaqHE3TFZc+P5V3o7m2l55Va7ULmsrqaQGr9vrHWkxN1ua60vPv+tUV9TvdnTi + DATA 4nQFm8vaD+VlMUms/eNFk3tfuffaI9vcfXWByRNH9mwy8BVSu8fA93T0P9pdHd5/39YD/vWBQ186VrxlqLF3JFLIVxGfn69lk336P/gHVCcoBc3ohK8oDwdz + DATA 3FqNUEARcTUNjDEcwJErQIZL6m9CNNcyR00jHG98T5oP2SNZ3UagC3DlcJTXTBot/ZjP1iu9BTn12pBL6nDoSw+u2/boqd66ilAoWydlcm7tPoXbEYzoqqL+ + DATA 7ZcfaY1gE2kn/FPmoNzt2eTJEomNXbXOrnsv3zU63Vze1lnoFZJuX6hAapVJHZvb2jpyN9w27eyOBAh+2hGfQNavWGStBU1RSVNjKrJ8cWTVQdK8PHTxVgdd + DATA mfvfV4oz7IsZO+LPEnFkIHObPIs9AlIBUMruXWlPd6QyiT50MuWVsVRjy4IgfTYQzNx1f6ZgfDNTH/4KUPnXjFwFEBTGAsR6SgmGQDQqammOVAb8DjtNkshq + DATA FjOGbAUgujcSkMDRUY6AiM7wEGOuxDnObVxyLsAiONc/Hx+5C6lWAlj0l/BYZY65pr9Ql6sVmr1Osb5guiTfpGLgdiYo3T5ND92xwd6izy+wkjip92b7PG0O + DATA TUfkYKuOwVfTGaNz3+WbpwCAIDsWwKcIIWgHkagcAObP9mhVcaHdZjLQJM3moiH6vhS2VzaFxA0tsMctmdl6K0EirKzMsVQjk2WLWJPVTBl4y8RfWeEkb+j2 + DATA uZbS+vJGTI5uTXj5uLt5vbOT83ykmqvYIs83OpLm+QYhJFnvh/13z9WlVUtW7AEHl4gIz/bkvW3JMJDzhyyPaCno5zSLUs/i/FaIkdA66wlRWny13eGS4jpn + DATA 6g+vyliKXYFDVC6us7ONuZWLKQXwgSYwElUiZbCiAuZW6DKbEG8OxzAcUSGBHQPEAfKOaCINzrZ7ABIAnIxTtBDsPmd1d5L9HmwXKMvPgc9eZrjbDJunpLir + DATA EHcX5PLtfh+VoYXmofYj09na8370d1nQKlTzddcdbJro6/TsD/g9EDflFmRZJLUF/S8/2vfW4XKvTGHiOT7B5/WR16j41YOxgzPRAVoskDso6Vp4879g8xdo + DATA q7U9y5Blzi4+f9gQUIhMEgN/tPqDOxbu0aCZ+7Sb1LD36XVonqu+jp3X97gddos2W6Xg0yAAA0KU1xBBir1ZY3hYAAFqEKKTM10UheBIEhgLSJpOjMfOoUaD + DATA XGsflyNOeEp/sjGU9vsQ0w3zXVY70hlBRlx4cGjUqNR3j625L9f/+nkCXJFld3RuK1CHHBKLqCU74ipVlMa+xas7zzLUFHLHfOmmg5Tbai4LlF/3acwrMPFV + DATA BrFxxi6ViJlEr+4+CKHq2FOxb11od5ucphksQ2fRxac/JDsYT+kDfaAvKm9pTsUbygOVNUCCnsUcbgU0QYcTwFsEcNBOrwhrziWd5AqAF3tsCf94hjj8cBm3 + DATA 4nEm/kbzDAiT/ahrqzo6H5EClO+NI5KH88IsLPkJWGaEI7TzVohExUIN7tj5Z4DEP8/veD8DKOKXLdz/DlksIu/XCNZEs+trWbYqP6skZFYps8R8GoPs/vXi + DATA GKCKIY38H6oU0BBJ2AOaj2BIsmcI1/HMWI/HWI+Tiub6vJOQpGbFgDCKmoPOUDihG7QETlkUmvU1ys1MtT2/fs3V5zfG4XjpZrN58NdyRGD05+GhRXGJYNe/ + DATA 7ne1GEtHFHtr5gptHH4DsGF8K0bKWakgWPy1hXGI7OY+/T7r+5rAZNSEPF+0EikI+wqZngw76lQTixisNcEmMWKj1kAegdIJBIkEmDAhBoRBPsQFEAM4azQe + DATA D+1jBhMEwUBOKFwEctxpjBAXXgp9Ts7YjOU5GCZ9n717nd5Y4tdLZPbM0KuHeqS2dHxfFQvBWbzthToK01i0RYWFEwsD77MUa1r8a6Ms/AAGPEx0eDv9BVAP + DATA NoL1UUtjw+TE2rGhge6u9taGjY0bGU3yQI5brURRC87ypJXLIUQ2gwQKCYMMnoCI5olYAiOhGKMJVrKG83zknE40EcY1n6X3kIXCNGCDwmBAwXZGzR2uR85S + DATA pVKypcIwmBUdx5ZkgiLoRtRFtja6t1EXbpBuir38y1uKsq55o4LhLxNZdIENYbndXuq89fqmYz+oqjoMqRxli0/uVa274pbYyaXojyA17lAPVXj1xooDaz8I + DATA 3B3zXOQxuy6CXfDd6+psAiXPwuS7VFLrmotu6o09E/vydNY62Dq5/Vfw40YH03CY81xsT6yFeGsRHqkixlu+RYlBI9gEtkQdzU0QTK0fXzsy1NvT2d60qXlT + DATA Q115WXGR3SaX0iRohI1ZKBYSoVPIKoYAR1IBQWY9JFhcIR6IRMndT7JTq2iJ5oyt8lIIL5CGGDWXDMHtSl0XdPQoudpiPPmbFMdecnXwv2gGyjqitsre2y8o + DATA mOq+wCMyFuhDm/Qiq4gZZp/0S606r7Y+22mWF0Zaulyt9h9KLLXM8mT9S0EW5JbEDEut0Nc1g+UuU6hj/etvXOnq2Wrt37yn4uDvchUK2s4tTdf6vZH7A+31 + DATA JZq8lonAxgg8IMvNkpjNMfzSfFmbmSAyMVgldswIqAeDoCWqHOhqa07dJXyUqUzdJUhzjKB5mTYGtWobY35z2NnshHRxrFUBPulPb7Hi8H4fOcLgfRh0ouhg + DATA qKejNR3jKDoo5DDOT2AcGRZnDbsgqKlVBPU8y54limf+lmbdswYtnW7YWbR+l0HrBOiLZiOtnK7OpsZUxKJIIoAQm1Qki+OWD/47Dn0RqquzALArc+Pbqrjw + DATA X2fqi+MQ/Rr5ZwbR68EwYqNcu2ZosKe7pTkd1SIu5kWoFiY9N4j77UUcNr162MYzW/8sQd6VcQXOFu349zN24eFx1L/EoL6fsf9ANHsdY/3uBXEfYnBPI09N + DATA AxohngcEBE+AjkyaRrEfn8LOKfLls7bnmEFJ1vxcT5VKeRbgv3T/+YPmmpHJk3f5ZQWxn4iL/HJ3o9+bvzrQ3+jXZPsn9w+u3eHausXBc5miHZsro8M1yPoI + DATA +9up7Qz2B8EGjot1Yt3IcG8G9JdnRD8QCFDUAng88TkPWhZfh7PcBjS7FqMTJ+/yybm1ULjQWpz1JvhzpmVI7IEfgnowDLaArqhhdKSxYWTL6JaG4cbh+fsg + DATA L+7/eXycJujZE+AcxyuKpdpWz2IDRJdqY12dnfDMsrpcuV3xHaoVNIIxsBu0clzgLc0LRTm53I7gQRqnw7OxzrmOcLBlNMee5T6wLrdr9qw3xlfOoKcWgukY + DATA Tf6UUjAr0xKVD/S1tVRVVjCr4nHrdVwHexGJiiQwXiTBIIm6kADquwY5OISQI59I6higZbGubFOkTNrTmegh8b9dcma7gd1GVca87ANuIeKLrIQJmTuPtdr1 + DATA 0orxfyOzh2rK9QrF+BaLOUJLrLkJFsmiMQBBUYwmthNCsAZ0IMv2dqMzuKjQzLKHIssGtAzKlRBDrOoYSqjiSB0wOEsmmkR9UpiRyiTM6DqrHZC0OfbTNEpN + DATA a81UQbRvRZgXaIrk+sobUrhJO6YKx9rEbdWT/7MyeGvKQkpZyaUAAwVMN/hrTF/DOnAYjEaVU+sH+lqaKisK8jVquVQi4qokVaNujCSgdZwVX8N5c6S+SEiQ + DATA nGJdkgJCiPqPkl3gnLx4ksIvbLdxBuash+pMiXbvMIBzUl4UntToQHXU+NEqIZLOijF95g4IOKnc0KApcEb7iyYnhAc2MoMK+Zve3XpplyHP6TbVOZqaDJWi + DATA zTAKS4YGJK5cRZ7A/q16NU+k33bs8ouLd7Qoyyta19tFBb27j9/ccd91x6pLh3s7v9aO12ZskFAZS7x9jzz11dcnXjsVUhTuaGIqgXkD1dsjx+pvvbXpvl2R + DATA /CcxAhItXprPV5kkItcPY8f2XelT+7qufnnbez97eK+pyPdU2Rfe/sk3Hr/Gt2XTyInf/mzN+tNgJ1WwWOdEI3NSv0sFQCtboZVPre/qbGTY3lA/v1wGAdol + DATA BS0GDMegtQ1SZsZikEJLiEMMDxJwVkQFc5NwVvuHYC2MdkCoAJu7AbgOcEW8MYLjtVxgkdgJPBmzRJm7KaDwDpPQoxzyqw1OqzG7aLpc4TQXGsPVkrV3PHo0 + DATA S+0ID+KYU+TeVyKtGelhzu9qtd3ZOWGXlK0/0njr0bdE++EfMjVYUF2G7OrDwXdO7HAbNfa4H9p7tOGqh3st3/gZVNsFMgz3m1u1XX85Ne0SFfZsj1y64TM9 + DATA Ortzu+eBV1+8t/wiyLTvP05sy6wQAewzb5CnmL1TD8ZBJCppaS4vYzy+Vijg9JZynMgDWRsSLUEENyDBCXEk5zy5u0C6F6dxDuaobONAxl7yIFhkH+Bp7ryh + DATA 4qOcga2HjzfcdIXOJ8hWQuW/myoblBtiX3/zJt9CxwH218w9QXSqUz9630zjlq9/5albSvZn50l50/CVY9e+WHp7rPSox+g6BHvhu9fXLnQ2kH9ajEMTlM38 + DATA mNjHYLwZrEezgpMTHe3NjTluk1Gaxc4KVkMIoLUFEmZu0gdDTb2pzGdsW9ryvTpFYxgnsDvL1cL8S/SNaF0yo7ohs3svrWm0Def+VGxl3HuOWf3F3X27ozdc + DATA Umz0jU7kH2uOuDqM9qa1kf1rLsDezYTricV8vaOiM3dHJzwpZ3y9salq5mexvz34SP2dQkJu0utVVd6LTh3d+1d74fgB3zpyIiOwAR5H9oPs/XcDqIxKx9d1 + DATA dSbRTSMGMQ7dFFwM2tTqQBukC3CnvT57gBOKFPLcGC/l5aph/PJUGbLCeapkp3/HRPmvxtkR26NKpLqZ47bbzAxrlVBAk1x2uFgNcdIPIY2YiggeS5pPc6T5 + DATA XA1vNuGGwdlw0qlERmbO3iSbbhgqaCJ++1KzeZuk2QHy8844DTSWTov4ilOtbX/iM7e19/XbxUbNyMUd98G6vx6PffL1rSZDwGvs+OYtlVsKKiqyS1su6onV + DATA dr9Q+zLEGrvD2UU5OiKtj9WWJ2nwKtVGdXFD5YmH17wEpyH0r3cVOncV4CqxXSXWCN26SNOeG/pjpSOvHeqz8/liXUMRZUrvX8VP//H0PwiM6gQlyH5oFoMh + DATA PCgrLPB6XE6rWcCLz2IYIMaKYZVCSLERIx0GBI7hBBZkBwRQZxyFAzThhiRd/FwImSzbJXpmKDuyHafBw3oOxkmwzgHZ05duUGRPuy29vfW3j5xcFyjMVirz + DATA jC+/Y/QGNKW29qmy2+rurBcNXefMnh7U2Us9W++PagtUXobdqe9Y192fa0AV2cfS+lzvKwkW9Si0anH/lFiYrfSt37e35NrSy6KKnCyipcVoVYltUr6cp1fk + DATA duw8v/rSOy/F8D+m9bkm8fdEAn+NDSvDH7bK+Evb8GeFv3Upe3ul6KtMI4nn0IffRb6TRF9jw5LoWxR4LB3HaqIvzZGuHH3/SbHhmWOP6E1zfQnkvcjYbi3o + DATA jir7ehdCXrALErwE+vD/kvdbehjlrPD4+SW6aVaIUHJm6S5DzmP6KYrF7BAYjcp7e+ZjtroD4vRc3BL/ZdxmbkFcOYQvzdiLuAJX+u9F2V9iF878mniCugV0 + DATA gOGosrkpUuEvNhv1WoVMyOfR3B27EkAI7JBg1ft5gEeDICAgul6jTBGPplgRLIBBSACIviQZyGNuliueu0LEwysW5TjG3r8SCWk2SaRAdk5wDSaZBpGV54wE + DATA s3O+NIWtr26v1VVSZFldYddI5+AFpRd8+sqB1lBhKKfn1jsHFbJsjdVkNst8lsrmex7ec/EldUHSZaiqKXNZcbzkPBkt1bd3NUb1IfxxPiP+Fi0hSGHsjdi9 + DATA sWdHv14RqGgqzvU8hk3Cqe4qmicUuZxFOTKrGr790pENXbt50vBkzlieS2Eunl6Xo7QERw/VHWewOsXkKu5nYqPN4DC4CuyP6i68YN+e7VuHBvv7KsqCvlyP + DATA zapUSMQ4RFWBvgEI6C0Q8ndDDDZAnGQwK6SF6N5LQowxKvMOiRNBAURc3JAEyLospyMP0jQ7yB5/kWR4FCAzL3taPZFUsttImqK5N1wcT42CpuLsR2H2uqFB + DATA Pyh1Kt7psrMU6yFfGBHKzp8joumpV+4cc8pVUhsaa5cY0Vh7/rS2+ZoLubH2wIXX/n3YYsrOa1b+K/b7KyPeCEMmbxUR/FKN0xt6Wl/hiDblqDSXfvTq4A8q + DATA j/7lYlf9pipmYl7uYSbmZ25Rmo7/dsNG+uXnXJ3hXQ7YlM5oHVzW8Pvd5fvGvcxc9p+2lvXv8srMpEqmd/dDByE0mfRFsiqz5TW4b7qgurbYlTZcf4iIvX78 + DATA caEeYm3Tn7qrGI6lR3sEKGPm5ymqE4RBM+gBkwwiTK0t/X0tPa09dbXlpUzXVjFzQzRo1ApWVRZ1bHX5AcYHHVEM8h0QhzYrhuEIGIABBnIKOBYUCbA4hwGF + DATA xe+Qc17xINeaSbKI4FpYFxuhZw6NoNvNXhYTO4zlQFCjaxH72hXfcbOz9c60EJFonFr/6TJFcrpe6qzbu9PFTdc/NWqRUtL1t5RdPGqppqj1oydO/KOlPmiv + DATA /+S37eUDF02YVURQ3rhuuN1YiX9h83iv7+HDe2Kd6cSFPwksPHt/YW4FzPZ/ucvsz1978plP37theudO40zLY1M3ftjRUWcR+of21ZyE34mP4/95obmpmffQ + DATA ZAriLEQ6v329c2fyWJ3fxExeYmyAG87NND7Ajeiu1vTUghO7Kx0bkKT3FJ/lmMAn5Rn6jLNn3mOnVUpBJ5p3bmmeO6fHzjsnpgISxswwGMAZ82ymAzIoUp/h + DATA XMB16ZY782mAmXsWMhaM3TnzA/geYysDMEcFEAmxGqABZ2wkns0QSaEdQ9t4UUWVjQsLpxDCJfVRIFAQe7F3WP0XzXNI9AVjPl4QF30BBdiiOi/wx5kyQZk1 + DATA W9BnthNbUPkN6IH6WbUKMp8olEFgQqPCgHvczCEVzM8YGhEXLhLoQDBEXIn9jula0QN7VKBWSbNQ3ztiuZMBDCE3Ue2KW3wRfbqnMjZ+ELdk1JgDJ4gX4BfJ + DATA d0AWkD0r4DNP/Tz3wHAhabUDKXcY4hfpNxIoJi7CS6jtIAsYgScq0GrkMmH8eTSzz5P0U2KcVf0CizYCYM9nKOUTT2cqxSO7xmhsGkwzdi1+IVuFSl84SwAF + DATA Oc8JsDDgjinXrKga+sNBLlToYkmO/D6asXIuV6ZKVPJ8PRsDuxpdyrzWr6eUm/p2bR61NdvLbkW/y37iJfxySgwsIIB0Kg3M5UIuRTc0YIEW5H10ACMojLNO + DATA XNqEXXSSNY9iqebOh5dqziRezdRcCTAgISZwJ9UKlMAD5M9p1Bhkdttz7EbjQLB0jRrTLbfKTFx+JlXi0+8wdRof0QRqkJJ3eVkogDRv3U6b1WxkgCJHvSpC + DATA xMAgw9gTkUZjInwM8IOAz8P4PD9jTIltzmhIXFkYS1EWdrklOLfQyIexTffIQ6f023PqzwsQcipC+M4Dpyw1zd2F0+f5XXbF218JKS1jOdFuX5On894rax68 + DATA fhcTatoMxqr9u4uz5nBsX6nAJ3nKvm+9+lLTvV5XtWA3/OAGLNtpUbeUym18KkuUJa5vNJTzYrGPukKhWdrt78JtAYCDUebu/zr9BAiBBjCAprW6u+rrGCa4 + DATA gMNu4FjaaXZaKw/SEMZv/QBDEg5BgKpY0I8u/hSkk7MzgB2doSiSsQ9Hh8Bn8/+hZNk2LlLE4Y5egLVCzZkSadFzYEV1A4pK9yS7VITHO/GwsapSU6a8ZuSd + DATA z7x83LP7UMnOMV1eQNkxdT3UB59+sWR639ZHu7uJ8Jrz605c++oLbQTWeMGx8EUEvtvmLnwUq0rxRqdK7vnVJdDzrtugKDK9/bz0khPfvNwp1Cg9tQqNrKZx + DATA o4ksKx574NR1l/U6jtx04YZ2bQDrefnquuZQwZbjh/PEBJZHDKYlqHDQzVh5B3UzcAA/qAX1UbnLGanMz3P6XX6bJVst4KHdm6uAOOo8BiQIc0OFBBF3cKiM + DATA juMJJTyMG+QMhFKkZNCNJaUE6HaRbJwb4KJcZbrxumV62a7LbMJGrzGIa93aWmvpYHjHgSfLFOG1F9bfcOVVne0we+3EKb/M1TmwdszZjdtSc/OGsi3bQnAA + DATA 3vtHRnFm4sDV7d8Yuuly38QLVV948Z5L8tf29bn6Lvlrx6N10c1XNt/3a2L9vJw7qGP2pYXLeSLu+saGMkZB0e2yWlRKPo/jrqcICk0ToSA1CADEAPSn4Iyd + DATA geVwxoVTHMwS/QG4BFMpfRFiPtzCIQuCmzShZ5dunl5+ecHm65TmvNpglkn53OV+Jb9v08EjF+zwjH617saNheuqZUVhtU8gfO5WGPhP+3X/83Ls40dP7uwa + DATA wG9JMdOfq39zFHr/YCGZrag1xN6LHbh5X67U6m7cePGpns8++bdOvUJmKxUYVMX50UJ3X+PxX8d+HPtT7PRlA9X1lHderhP0MTYrZrBUDKKgC2yNGvw+CFpb + DATA ykp9UX+0IM9iQtxlFAmKYTHyaY16SOMhEQZQypjgEagriSZpQAYBO09E02zlKF0NyyaAFDX7CnKdBHMJhOeeaT5NHIZx90ZT3MlH+ubcsqTzakmFquHyzYwH + DATA 43WX7dv1dFgZYjboDX9ufGLI6amzCy3mYceYJdxYnK93CWdGpy87ESaC8uaJ0U5jFQykmPg19UDEm62r2KwquNC/5d7yZ55/4JrA9nGsb2uem0nIdfxpe+wP + DATA m1/8z3GRnIq8+sa/metTcORQ3anYO0TnfExGGL3kDxlMtoExsBdNIg0ONDXWVDMabuGAHykqatQiIYGBNtiG7rUdtTaMT3ggyW+AQIBbgZAShgHJF/BJQXCW + DATA 94gGfJLmQ8wDBFDEvIWCUE9cd4HHWDqhw8pnDxIuSzdHiEIRl9hDnnCJeS6am1TkCqny9Oz9y8aq3LU7tOeVHLyAI+U5ebNQLVVpBWq7rqg5tG6wx73ImJex + DATA /PmjVtPY2vVRbRmWlbIE2LUouSMY+Hjw83kcDc80vBenKDFf6WKoj7Mfge49C89+qXJFtdtjz2cp5e49hCYd79jpn8R+R7TT/wOqQCdYi2Y7qyIlQTSBaDZm + DATA q3lsj1ddISSRKUmUwYM0GoQncNQkA0iKBBSaPwyhQU+28YIxO0kSKGAjCM51oD8cyPI0QrOCtiUsHcERrNVzevQS8WTCwkq7O57ym5fh91S11tk7Nrm1VJG9 + DATA oYWvLw43FG66a+8VVcHqbiPPFFbT0aEWtXrtaG9UV15y8aahnu4NRfmfwzek2PVN1YVf+f5ByDN4hCaP3KEw9D33+B1lF12wZUd3bYtCrJZ7G9Sqnm9WNse+ + DATA LFHI3HtIfuyXsZ/F/rWmn35rfo2TmbGjr2CwPQq2ctzkGzcMDiDf4XaqETHRKBxluclrjVIckJAbkuXBhBmRw+VOJs434Bg2p6FdSc1e/uXycJjCcQxZTYq8 + DATA MQIzxBLRUYRAKJ5z6aBpDA9VYSBR/8dRjMSlo9MLUDSl1dl0lZd3GiNTa4pHTr3zj6/0dpv0fnfdts2XTObEYvdNNvY0mEX8iN83vqvy4qe+VFdTM5jt8Svy + DATA 5DxN6GV5MLT7AFT8ubjGlWVXy68PDEgpT5MnSyf8QapPaSxwyXKs1vrDR+EBKDz0m8tiA7FQ7OaGWlgN3dd8+O/y1z/VGnPGflHvy5ObcJnTffGzO/8I+77T + DATA nFMoJUVik89Uce3M+7G+0W1vvQNjLVKZ2FIbiA0/FPvV7dXNQlpEkW+mxwmIO54Kku+AnWAvOMbNQV580e5dGzeMjXR2tDQ11peVFhWyLPI74U52DvK8PUHk + DATA TKxAACggQFAnmf/zA6FQaOOJMK75l8AxDIv7d8zNp7lVS6rmLEEpz7qaxHIhQV3mm5I1mPRYFu0htElSfzKSvQsFFL5geL5TKiu7/bzAyMJU8wGFS2mS5SiI + DATA F5ztuZ3X9EWFN/a07Gqsz/Y3hbTNc8LgvIpKqcUTunqLp77M7FcYfIUyd67l6tYyCLEvpqws3vHIpTV7luKedw64yb/kDlvLh5qqHrN9ZbI3oMsu7u54YHPw + DATA nvbZKPqJG648z9ZgdT97onKK/YFSsbF6dwPMeXA49lvIGP2h+Xvwc8z58m9mD1aCdtAUlTJ8RiUFDCe9yYjy5zTafWrIKoNykQ8kIeIbhYgMjkwPsmd7xkJo + DATA Z6UQuqF1wudF2clUnYp9z45GWdM918+vrbXJjFm3fK58I8fXZpBf/M+7Tx3LP3BBxaF2ZZFX6gwM7Co/+JevR4/wj+978eGbdGLRCPa5FCsfOyHVIS42xSPQ + DATA Uo+42HKySvJj9+TddeMdNxYw5bHiGgWS9S0rdIq15b6p26UvX3dhUw32DlmbvitO72F46/XMrsgHEdCB8m7NTeVlvuL8PMTJzKPYvJsVEiSAOIGo8yjWS6XQ + DATA ssYLNiJkMilnsjCFYuZZu8X77UJJn5SMpS3yRItSkA2m0w32MdZrqPJYC0tNfFPnsaCM2aFqQzZhRPiVOQiB6MkvfLpMGRo7XHfdaRDK902yQQwbVcN9KVZb + DATA lxV7u+8LBY4Sqbv6QfibL9VfeMGwUyFxmoUqtcLtbA9/+HTkmWfvvdy3CX7n6r2tbBhzWVNX5YZLsRNpUOOYs9bTTyQ42Tra/w9wsqWbbsVMMc+k2O1seWF+ + DATA lga6OCPbFPlOgpGtrjadkS2d/2X1GdnSjHXGpC+xFButgOhlzzxMdTDe600GUz5QA7qi8sqK+UwboSSzyzln2UiPDoh9Z07mkmKkMyTQgKVpwMFAFPEYUJMs + DATA V+9QNBup7C7Ml1GSYHDhYTwcCybZMtDQ1DmgzEg/d8+It+X8FCudAVEG0ZeGoUTn+3fBOrCTiejVWzevn0jvfUf2icZ73wGfxw8vv/kd+y81vyvRC3d8G2vU + DATA 56rl/Xbvpk17cFMw4haYt9nOVZs7+ayzumEwZCnLu37MCGY72xtBK7NKrVH5mtG+3vTO9uJ4ZzugaEhTMJjoa2fAKrad++Z29u+V7PomVmEV2tpf5Rtt2kC/ + DATA YxAzhhsDCnqVutnJoofVXXUhi6KieO++EnOphp8yAbITDEaVkxMLTYCUx3fBCqY/+Od0A6R3RZyrDXBDWv/DOdsCn03vc0jsgk6W474acdzP3QMo7vQk9sBS + DATA gx3UamI/vZV1FXBfkdaYsEq4xy+f15mAx3H/IIv7i8FIVH340JbNC50AFXHs8+GZef9zD/4l+uLP1WYgNi3WLH/OdsZrizfP49w+Id9h98lWpCW0ccNAf/p5 + DATA 4U3slfg2odm85znfLEsu1VlvHuyvi63Kau2kvy2+CImpKJYxpB95q+7O5sbUyREPNzkCKJIK/1cGo9JjpLOeFsHrU8KhVRsP2TU3/EnMPDWCZrAG3f1Gh3u6 + DATA 5848ubmZJ0CQgCQAugGKbed+7Gl+vLMqA09fS4t4VmvOiXLOC3kABM9gBnI/9n0gBl7UFcQjgRiKUEtFNoBsA4Ur3vWHof9C4OA6F9B1WWPlpuX/VGoMGAlv + DATA niHgxAx5OfYqLMdrrwIQfB4z8Miz+9n/RD+bejrP6E/92VBHnMQOU3cDNdNJJBLgMNFJBMMg0UnE6R4mdKyKkF9SqzG7bXtJjbGwytrE+DRM6e3zyYhfdq0/ + DATA 0NdRpwtpxOq8gZqKboQbN3Ecu5y6GSiYT5CIsfmfwF6PXYmGL67dC75Y10Rgilzmp2Y37kKfQ3zKOPtTS73rD/Z21CG706cJOA2VQMX8dKmEptifzkmCQ8j+ + DATA 9HAAZb98CdfJftJt2brEz7U1lueyn8S3l3rRT57zBACDDuIkEWbsIwdOkBOVKxUQ6LIVTqWTJoEcytGukeAQPQ2JEXjCZMj2nLloSmNi0G+d9w7u2Xd836gX + DATA g+rCozaBSmxqjdWlv0OcvPaao3vQr3JwoxH9cmkvAQZziIeJcuqFRX8/9Jshi+AwbhI4S8+QSA5a577jRu/g30j8NkVjQjn7+905+87FVj56h3qB+4VUBYNb + DATA WOMlXu7bbOB+P7Q+2H+gEiiBF5iiAifTfaGUCwWo40mEwZTfikzDAOsdFlg8+KjdkQQGWkBp7NcLLOh/RB4WLslFheQCawzBs6dfJZSUDOSCiqgEAOZPhpkR + DATA 9ZohtnOXAQLIgzjiWQAQgwBNKKBz3g84kgXWJaK2KDXn2+ScgBjTtcse8sm+kLjePIYx/33W7cmusTbb7+1y+AaeVEi0AntLpTZMUflbQpM0vTZyXGe+aH+T + DATA tSncPLC7+fu7If8qsVduruZJOhqOVAZkMldNyyM8odzXlKPl9Y3G7j0NjhdvAhBcHn+WMtARlQQDxUUuJ9KsoymEhBITmqMSYChxRSCuWIgCF5wt5+Jo5ILA + DATA AOGfQ+DOyX7MauczkQnzSEs83+yXKN3FmgSO/CDbUndRSJ+d+XH11vrp4ARNeiNfv2VPTq3DogjBP2f3yrNJEfaV9ROZH3543ZcEQnXA6wwLY1dfmNvc1Rd6 + DATA CEDwG/hV7A38EZAFsp4Vor69zyJvk9q1x1X2sXVDUyPW2kBOx8TNIWUu/CBX4LTW37fOVHGeZ88aFNcXn/4n+Rr0gCxgBoVA9YLLqVZRJM70AmIQi/9Ux+wp + DATA iDYS5VrqNXGXzqh2D1bqI8UF6yMzj3GvdFWJV8m/KyltLZdbRGJLRWtJQKDNW/QloMHtp9/n/Y5So3IA8IEGMAI2g4NgR7Rg65axUadDLtuze8vBrQfXT45u + DATA Hts8MtTV0VBXUZaX6/A5fQa9zC63o45EOUJLFiQkEKMQGjw8SImhUEAJGQDNbcGzyURSXID8Oaq/zUa5DrZDLAy4/DANKTyZRU8Ywe3jIluuiwcmz5j4ZnfO + DATA fyflX1hT//3nOjeWiXG7t297weTMJTfuDk84Wva3bPRvXWNvPW//vdW1NTaJOzfPK3WQcqUx0Jw3uenpMqXB35i7dvrlT34+7y38kTn/ZGZozgt/2GLsUhCv + DATA lu/Xua76JPRT7G6rtfHEnVcNuRRWW/PVt564bsfVV+zqUPJtZe1561/45KeBQ5smBywNtwcPT48PWOpvTXud8t1zvwYQXA3ex/5GWIEKONHZLxYCFVShs19B + DATA crEaBLCEjdGAHU+4dhImUu0QwQ6GsJ9oq2MvQKFMJjaaS6yxP+YH/PDLSsJqbik+Hfux3JbNV1iho6g6bIZyMTo+94I/Yj8lVAt+Loq1Wd9dglq4IPu5YXTA + DATA OWFiX7G/AKSu0VbDptj78Y+FauZjY1XKP5pai2Mwl/vU2JvoU2N/ZT+17PS/iPOpvQx2tc8JeFysIErECiKuzTiEoDWLLIqG77VtzsZznM3ri1pVrhmz2+8w + DATA OclN5fvdxXssVR/r0c/dw9zj+ikFmAKT0eyJccRZ2lxdVVnK1NrsVr1WrRTyUU9RjRhSEIM8kBS2QFamAKRYoVgAeHyApqZSXCSfL0BfCwQiAZfDDgfnZK5n + DATA v5wdj5rlgkHwtVFsRY5tK+LOYHv6a7a8wqWjVLO9CFAArxQRKLcdEck38jH0VWDvT37wjUtbqns764MeZ0GVrvTkDfUn1mmU9nJfc3bp+tFbQzKJRuVIvMpa + DATA axtvaXT2W1Ryc7Ro599P+bfAB4x8gZlNfDc2CQx8JfMF9L7y0mjn7n3n7fK6I84Ka0tt61DLLW9BlA+POiwlrYmvftOkU7mNtVqLzlbqCar95eG9AINd2C9Y + DATA ddAoY33eczXDGiEmZiMktnsiMaeHev6QmTiRKOY5VeiJORtwN2F6tpKP7mAwgIyJBl4S9JfcdyXaTinmx5JXXuqirOY19c7efpumNmp7KVs8eJlZz5OLbTBb + DATA t21jbdv1Qp3TqpDoQsxF2VFsd9582ce3frxx4kVvibbAUjZZliez5m2qszT3lKry7z//UpENe/NXV32YV9r4w2tDB/Q8Ye3GKNxdINttql0f+fR0llHi8v3g + DATA q/n+Mmf05Outx7xamYGgrUf33f1mYS3Tv/IB9uANQhVG1GkLIYTY1ti+cTmvSqXKH/giLMbkCKlTAFBjjLW6AfWsEUIxGjO1xht31OwokBqRg3O+1MkiSoH2 + DATA Gmu0ENdSGi+0oZgTdfpIXZwir0qqMGHYTDAW3m/kSYT6cHf+xjpBNkZcfF7h5rXXQMOa6Vcf/k+rtryg7WSdrnA4f6JUp9dJ5Z6uWDgYbmptMUbrIsdff/34 + DATA 0dcrxsT5+WNaj1fqcbuybJASbz+/85kffumB9zu0Eydjfxj5yVc6jhwqlfIYXFo88hxHlU9VkG8qH9hxtOVhqPpBxyOPPPB+7LexHw6uN6ETtoSp6N5EHQZ5 + DATA oBJUAcELVZFQvtKEMzhB9+94oSzl3JahyYpk/ZV9D/rQxXL2SJDCMP6SU6OwlxwoEuAEr7lI4a0NbLn48PCF6x+OfXvbhcf6x4b6r73pkRu7s2e+d+imy5r1 + DATA vca1OzYMWxuwExj+8RXfmDSGrzcWyKw8mdR5YNre0rM79q+PY3+LFd1fsnbTS19//pkdu/u0n0y++c1327CLciQ1u27qez72LbyLQlkLNQCkm3gDyIGKwb1S + DATA wQcM7v3IdxXBCIbmIyCDabsbwsNTUizXNuKVCRQW+Ia8MmTpi03HDIVqM/5BuByjRdr6T3TOvJwd+MWfHAEQ3HZ6gPgagxE9gxEyi8GIJixDtwsrci8ydj8E + DATA wzIr99VtRG9nIfZusyw7VDilI2ZuQX8c7CYf8JQERbK8j3hlDlO2rpv83kc56CuEwYbTNcSHlAIxtD/Ls0FmFYogsjP3ERy4SIg8GeRec2hD34HdEIv1HwuX + DATA FuLYDoXFYY0cmnkBvsg3z/wR+97xbB5fqw52fPKVaKkWuxtuPf/rhTmlZaQgYuRlYTPH5NlFRTP7bSK92SZ1lHm9+eh3uQR7hNiPlwMxelYAxWn32q/Xq70u + DATA fKhE7SnAHim2aTxYoV2Tw3Y7vk910/eDHJDHWD/Xo7RhYnYoJt4Cxw1iK2Ao2d8J2edgMzu4L0jBit71hjy3odGUr42GtRHyCJ7vzpPmykiBMDv/kydpmUBr + DATA 0hRqKGwbhLixN4vUuc2GVlvQJBbqzDP9VE2Do1WR3+5dV/1RgKcWqL0CGm/BIML7Dvg5Mp+wAS1wAT+D98Icm0EMEN5RoXjuuMfsmQHV8SK7jaJogjsRXJyQ + DATA 3ulPH2wLTj+23dmydujgQxfe/cSVXc1rhmOftawZatCV+7uba80zp9Aflih6S18GP/dwl6m0KKdj//UTY488MtS1l/kTYu6Q3VBx2G8rcV7kt5Y42nLCzGsA + DATA Tw/EdjO8jZeDemYNZEGEN7Z9nfEt8gieYeiX2YI4d9mZbZMIhOL7lOraIKHM9b2t9RHDD+sau8eCu4+cX+0nLNnhcKnbguGRXjH793URfZ32/vGeNfFvsOnK + DATA yphxYFoz0ObyRLZe+8AQ9uMfvPLELeEDk+3beVLfkL0nz6mwhLp7XJ7SqeO39fx0aOb7sfdQrpH9hqI+e0ee24d2527wMckjjgM36GTwUVhL6xl8yF0RPDk6 + DATA FMF8bLu+DQ01IavT1JLfcI0Bt5W05I7eOFwb1JZP1uhyCw1WI2EtbfWOnRqsC2jLJ6IBpVsuXub3Qb6hua+jXlfiCFbpqhzGwkm5cc4bzlJbjRW+tfT3AAhO + DATA gS3E3eRVIMysoksIxYksgJXLw7E5aTu3ufxha3yXMY+oRCkfmvYnvpvoQbstZpjMd7UP+qPCKx9Be/CXd8QOoz/hyycb1q81tMlNdW+z3/fx7djBQrvac3t9 + DATA YItR3yd/q9im9mKn2f++vbGsIHe3rmgH+obTAAM7ACAuIQeBAliZVbFogRCL/56QC2nZiDYMQwrut4n/mkR9XnimCfu2XSLKjmZ/8rPuSvyAQoE+/pMvoF+K + DATA HCyLWmJbYxPKXC1fJYEvF4Us8A+Cj8uQs2C9BsDAfgCIY+TI7GcLARb3NpALa9moloYUmfLZn8kLYy/MhLiPxt3dlZ8wgysHkp8N1cxnw5vgPcxnC5SSWC3z + DATA 2TGN4LLkRwOMnVYppxRADtTorFBTWeizkQ+A8WiahmgX8fFtMhn8lLiwUAw/JZPF1rBfXRV7OPYF2IW9qtfmGLAvKpUzNYaIaaZaqcR+jVXP/HXmJeRJe2be + DATA g3ecvh+omPXPQpHFgnOWr6UPTsZ4C86MQtS/TA9TNzNrNhHV7di+aXp83QjDJ93eWl1VVuIr5vqYRYjrrwjycAryeZiVhPGMg5B5yS8hIKDYlAobXeM8Hg6B + DATA i/kCjysDoD8d9GwDMzvKjuaqiIztyxgTNzoztjejLapm8xWcWCyNLIB+soVkm3OY1uZaW6clUuAQ26TFb1C2BXqbh1tzm/T/gb3awpK6wo23pvxdUXudte5E + DATA t66CJMtO3nyZoX4g/3NFpT7N3bHvxP7edWhb/udQ2/P3DkCaFAnFIqO6Jk+1aaG+5//ZH/t4CDMLep944Prw/rS/3PzUnr8SWpknXELwiJhr3bsP9lcyfJon + DATA mjGRIfZ2rPF7/czqfD/2O9LPrM4QUmuBoLuzvhYxiPqK8rzMbJgKDMEhAeKIKIQ8goYkszaJ5nI0RwFK4m3lScURgKbDkC4djV7QtIgTq+KOY4ViIR6IWcaC + DATA hP1xinYgP0LRKd21dtvc7lqcXRjvkLh/6FSBpcCkzpHn22u33vLDY48+NlDrD1eXuy0CnkKocGz7ya0Fboj//sZBU2llXm6eQOep2LA3V2opLNGU9N35s/sm + DATA evRRTex3lSrtSaiD/84SSQVKZ1GewmWBbz84vaXngrV9wzlWfxZPLjSGe47Fbtt2UWH74B8br7ojmqe25Rc1rLWu2Xn+xeVXlXh9M2/HXr8/rOYxtn2dsW0z + DATA dTOqCiLb1tVUR8vLggFPjsNmNauVoBW2ItuWl0IUVeBoQAU1fnO9UARrW5Liml4pxKhLpQ6ZoabEpGXDbNiLzJo4PrkiVPqgXVie6E/EU2k7kDUdQ+J9lzSU + DATA 5ttE0aOVDR27N1Rd+sRMn9lUZL5o+5xe44onszuUjddcXrZtpLON4+qoLRoZaDp2KGHHr8NX3pfKRMKyGrMCwj/eFNp1SfElpx5fE7s+9u2LZ2fwxp+Ef2/6 + DATA 0/92bxx6IPZTkVKRy0CV5MVOx/LfQhYE/w+EOVz2 END FUNCTION +'$INCLUDE:'../utilities/imageassert.bm' +'$INCLUDE:'../utilities/base64.bm' diff --git a/tests/compile_tests/font/test.lnx.license b/tests/compile_tests/font/test.lnx.license index 1ba6e125a..8071b2021 100644 --- a/tests/compile_tests/font/test.lnx.license +++ b/tests/compile_tests/font/test.lnx.license @@ -57,6 +57,405 @@ Thanks for contributions, bug corrections & thorough testing to: - Paul Rouget */ -------------------------------------------------------------------------------- +License of stb_image: + +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +License of nanosvg: + +Copyright (c) 2013-14 Mikko Mononen memon@inside.org + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +-------------------------------------------------------------------------------- +License of dr_pcx: + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +-------------------------------------------------------------------------------- +License of qoi: + +MIT License + +Copyright (c) 2022 Dominic Szablewski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +-------------------------------------------------------------------------------- +License of stb_image_write: + +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +License of HQx: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-------------------------------------------------------------------------------- +License of MMPX: + +Copyright 2020 Morgan McGuire & Mara Gagiu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- +License of Super-xBR: + +Copyright (c) 2016 Hyllian - sergiogdb@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- License of FreeType: The FreeType Project LICENSE @@ -229,6 +628,31 @@ Legal Terms --- end of FTL.TXT --- -------------------------------------------------------------------------------- +License of miniz: + +Copyright 2013-2014 RAD Game Tools and Valve Software +Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- License of FreeGLUT: Freeglut Copyright diff --git a/tests/compile_tests/font/test.osx.license b/tests/compile_tests/font/test.osx.license index 2c8ce7ea0..ef25e97b4 100644 --- a/tests/compile_tests/font/test.osx.license +++ b/tests/compile_tests/font/test.osx.license @@ -57,6 +57,405 @@ Thanks for contributions, bug corrections & thorough testing to: - Paul Rouget */ -------------------------------------------------------------------------------- +License of stb_image: + +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +License of nanosvg: + +Copyright (c) 2013-14 Mikko Mononen memon@inside.org + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +-------------------------------------------------------------------------------- +License of dr_pcx: + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +-------------------------------------------------------------------------------- +License of qoi: + +MIT License + +Copyright (c) 2022 Dominic Szablewski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +-------------------------------------------------------------------------------- +License of stb_image_write: + +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +License of HQx: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-------------------------------------------------------------------------------- +License of MMPX: + +Copyright 2020 Morgan McGuire & Mara Gagiu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- +License of Super-xBR: + +Copyright (c) 2016 Hyllian - sergiogdb@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- License of FreeType: The FreeType Project LICENSE @@ -228,3 +627,28 @@ Legal Terms --- end of FTL.TXT --- +-------------------------------------------------------------------------------- +License of miniz: + +Copyright 2013-2014 RAD Game Tools and Valve Software +Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tests/compile_tests/font/test.output b/tests/compile_tests/font/test.output index 758cd070c..dc896f5bb 100644 --- a/tests/compile_tests/font/test.output +++ b/tests/compile_tests/font/test.output @@ -1,4 +1,184 @@ -Loading font using filename...done. -Font height = 10 -Loading font from memory...done. -Font height = 20 +Current font: 16 +Changing font to 14 +New font: 14 + +Built-in font 8. +_FONTWIDTH = 8 +_FONTHEIGHT = 8 +_UFONTHEIGHT = 8 +_ULINESPACING = 8 +_PRINTWIDTH = 760 +_UPRINTWIDTH = 760 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Built-in font 14. +_FONTWIDTH = 8 +_FONTHEIGHT = 14 +_UFONTHEIGHT = 14 +_ULINESPACING = 14 +_PRINTWIDTH = 760 +_UPRINTWIDTH = 760 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Built-in font 16. +_FONTWIDTH = 8 +_FONTHEIGHT = 16 +_UFONTHEIGHT = 16 +_ULINESPACING = 16 +_PRINTWIDTH = 760 +_UPRINTWIDTH = 760 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font from memory () ... done. +_FONTWIDTH = 0 +_FONTHEIGHT = 12 +_UFONTHEIGHT = 15 +_ULINESPACING = 15 +_PRINTWIDTH = 597 +_UPRINTWIDTH = 597 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font from memory (monospace) ... done. +_FONTWIDTH = 16 +_FONTHEIGHT = 16 +_UFONTHEIGHT = 20 +_ULINESPACING = 20 +_PRINTWIDTH = 1520 +_UPRINTWIDTH = 1520 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font from memory (automono) ... done. +_FONTWIDTH = 0 +_FONTHEIGHT = 22 +_UFONTHEIGHT = 27 +_ULINESPACING = 27 +_PRINTWIDTH = 1088 +_UPRINTWIDTH = 1088 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationSans-Regular.ttf () ... done. +_FONTWIDTH = 0 +_FONTHEIGHT = 12 +_UFONTHEIGHT = 13 +_ULINESPACING = 13 +_PRINTWIDTH = 606 +_UPRINTWIDTH = 606 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationSans-Regular.ttf (monospace) ... done. +_FONTWIDTH = 15 +_FONTHEIGHT = 16 +_UFONTHEIGHT = 17 +_ULINESPACING = 18 +_PRINTWIDTH = 1425 +_UPRINTWIDTH = 1425 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationSans-Regular.ttf (automono) ... done. +_FONTWIDTH = 0 +_FONTHEIGHT = 22 +_UFONTHEIGHT = 24 +_ULINESPACING = 25 +_PRINTWIDTH = 1094 +_UPRINTWIDTH = 1094 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationSerif-Regular.ttf () ... done. +_FONTWIDTH = 0 +_FONTHEIGHT = 12 +_UFONTHEIGHT = 13 +_ULINESPACING = 13 +_PRINTWIDTH = 583 +_UPRINTWIDTH = 583 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationSerif-Regular.ttf (monospace) ... done. +_FONTWIDTH = 15 +_FONTHEIGHT = 16 +_UFONTHEIGHT = 17 +_ULINESPACING = 18 +_PRINTWIDTH = 1425 +_UPRINTWIDTH = 1425 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationSerif-Regular.ttf (automono) ... done. +_FONTWIDTH = 0 +_FONTHEIGHT = 22 +_UFONTHEIGHT = 24 +_ULINESPACING = 25 +_PRINTWIDTH = 1063 +_UPRINTWIDTH = 1063 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationMono-Regular.ttf () ... done. +_FONTWIDTH = 0 +_FONTHEIGHT = 12 +_UFONTHEIGHT = 13 +_ULINESPACING = 13 +_PRINTWIDTH = 665 +_UPRINTWIDTH = 665 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationMono-Regular.ttf (monospace) ... done. +_FONTWIDTH = 10 +_FONTHEIGHT = 16 +_UFONTHEIGHT = 18 +_ULINESPACING = 18 +_PRINTWIDTH = 950 +_UPRINTWIDTH = 950 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + +Loading font LiberationMono-Regular.ttf (automono) ... done. +_FONTWIDTH = 13 +_FONTHEIGHT = 22 +_UFONTHEIGHT = 24 +_ULINESPACING = 24 +_PRINTWIDTH = 1235 +_UPRINTWIDTH = 1235 +_UCHARPOS = 95 + +Success, images are identical! +Success, images are identical! + diff --git a/tests/compile_tests/font/test.win.license b/tests/compile_tests/font/test.win.license index c74ae27b5..84189c2b1 100644 --- a/tests/compile_tests/font/test.win.license +++ b/tests/compile_tests/font/test.win.license @@ -57,6 +57,405 @@ Thanks for contributions, bug corrections & thorough testing to: - Paul Rouget */ -------------------------------------------------------------------------------- +License of stb_image: + +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +License of nanosvg: + +Copyright (c) 2013-14 Mikko Mononen memon@inside.org + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +-------------------------------------------------------------------------------- +License of dr_pcx: + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +-------------------------------------------------------------------------------- +License of qoi: + +MIT License + +Copyright (c) 2022 Dominic Szablewski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +-------------------------------------------------------------------------------- +License of stb_image_write: + +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +License of HQx: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-------------------------------------------------------------------------------- +License of MMPX: + +Copyright 2020 Morgan McGuire & Mara Gagiu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- +License of Super-xBR: + +Copyright (c) 2016 Hyllian - sergiogdb@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- License of FreeType: The FreeType Project LICENSE @@ -229,6 +628,31 @@ Legal Terms --- end of FTL.TXT --- -------------------------------------------------------------------------------- +License of miniz: + +Copyright 2013-2014 RAD Game Tools and Valve Software +Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------- License of MinGW-w64 base runtime: MinGW-w64 runtime licensing diff --git a/tests/compile_tests/font/test01.bmp b/tests/compile_tests/font/test01.bmp new file mode 100644 index 000000000..acff32873 Binary files /dev/null and b/tests/compile_tests/font/test01.bmp differ diff --git a/tests/compile_tests/font/test01u.bmp b/tests/compile_tests/font/test01u.bmp new file mode 100644 index 000000000..102a484a5 Binary files /dev/null and b/tests/compile_tests/font/test01u.bmp differ diff --git a/tests/compile_tests/font/test02.bmp b/tests/compile_tests/font/test02.bmp new file mode 100644 index 000000000..6708c1511 Binary files /dev/null and b/tests/compile_tests/font/test02.bmp differ diff --git a/tests/compile_tests/font/test02u.bmp b/tests/compile_tests/font/test02u.bmp new file mode 100644 index 000000000..e7d5dbed4 Binary files /dev/null and b/tests/compile_tests/font/test02u.bmp differ diff --git a/tests/compile_tests/font/test03.bmp b/tests/compile_tests/font/test03.bmp new file mode 100644 index 000000000..5b346c72f Binary files /dev/null and b/tests/compile_tests/font/test03.bmp differ diff --git a/tests/compile_tests/font/test03u.bmp b/tests/compile_tests/font/test03u.bmp new file mode 100644 index 000000000..f4ef5857b Binary files /dev/null and b/tests/compile_tests/font/test03u.bmp differ diff --git a/tests/compile_tests/font/test04.bmp b/tests/compile_tests/font/test04.bmp new file mode 100644 index 000000000..4c5b95173 Binary files /dev/null and b/tests/compile_tests/font/test04.bmp differ diff --git a/tests/compile_tests/font/test04u.bmp b/tests/compile_tests/font/test04u.bmp new file mode 100644 index 000000000..64997cc82 Binary files /dev/null and b/tests/compile_tests/font/test04u.bmp differ diff --git a/tests/compile_tests/font/test05.bmp b/tests/compile_tests/font/test05.bmp new file mode 100644 index 000000000..4edabf954 Binary files /dev/null and b/tests/compile_tests/font/test05.bmp differ diff --git a/tests/compile_tests/font/test05u.bmp b/tests/compile_tests/font/test05u.bmp new file mode 100644 index 000000000..24cb2cf5c Binary files /dev/null and b/tests/compile_tests/font/test05u.bmp differ diff --git a/tests/compile_tests/font/test06.bmp b/tests/compile_tests/font/test06.bmp new file mode 100644 index 000000000..727e40cf8 Binary files /dev/null and b/tests/compile_tests/font/test06.bmp differ diff --git a/tests/compile_tests/font/test06u.bmp b/tests/compile_tests/font/test06u.bmp new file mode 100644 index 000000000..acea7a8ef Binary files /dev/null and b/tests/compile_tests/font/test06u.bmp differ diff --git a/tests/compile_tests/font/test07.bmp b/tests/compile_tests/font/test07.bmp new file mode 100644 index 000000000..48b758f4a Binary files /dev/null and b/tests/compile_tests/font/test07.bmp differ diff --git a/tests/compile_tests/font/test07u.bmp b/tests/compile_tests/font/test07u.bmp new file mode 100644 index 000000000..117f55966 Binary files /dev/null and b/tests/compile_tests/font/test07u.bmp differ diff --git a/tests/compile_tests/font/test08.bmp b/tests/compile_tests/font/test08.bmp new file mode 100644 index 000000000..04183f0c2 Binary files /dev/null and b/tests/compile_tests/font/test08.bmp differ diff --git a/tests/compile_tests/font/test08u.bmp b/tests/compile_tests/font/test08u.bmp new file mode 100644 index 000000000..5b27e58f9 Binary files /dev/null and b/tests/compile_tests/font/test08u.bmp differ diff --git a/tests/compile_tests/font/test09.bmp b/tests/compile_tests/font/test09.bmp new file mode 100644 index 000000000..e5701753e Binary files /dev/null and b/tests/compile_tests/font/test09.bmp differ diff --git a/tests/compile_tests/font/test09u.bmp b/tests/compile_tests/font/test09u.bmp new file mode 100644 index 000000000..435f6329d Binary files /dev/null and b/tests/compile_tests/font/test09u.bmp differ diff --git a/tests/compile_tests/font/test10.bmp b/tests/compile_tests/font/test10.bmp new file mode 100644 index 000000000..b18c7e3e9 Binary files /dev/null and b/tests/compile_tests/font/test10.bmp differ diff --git a/tests/compile_tests/font/test10u.bmp b/tests/compile_tests/font/test10u.bmp new file mode 100644 index 000000000..5be7d9f69 Binary files /dev/null and b/tests/compile_tests/font/test10u.bmp differ diff --git a/tests/compile_tests/font/test11.bmp b/tests/compile_tests/font/test11.bmp new file mode 100644 index 000000000..1c1ebe710 Binary files /dev/null and b/tests/compile_tests/font/test11.bmp differ diff --git a/tests/compile_tests/font/test11u.bmp b/tests/compile_tests/font/test11u.bmp new file mode 100644 index 000000000..5aa82207d Binary files /dev/null and b/tests/compile_tests/font/test11u.bmp differ diff --git a/tests/compile_tests/font/test12.bmp b/tests/compile_tests/font/test12.bmp new file mode 100644 index 000000000..2e28d8c6f Binary files /dev/null and b/tests/compile_tests/font/test12.bmp differ diff --git a/tests/compile_tests/font/test12u.bmp b/tests/compile_tests/font/test12u.bmp new file mode 100644 index 000000000..b4a52e4d7 Binary files /dev/null and b/tests/compile_tests/font/test12u.bmp differ diff --git a/tests/compile_tests/font/test13.bmp b/tests/compile_tests/font/test13.bmp new file mode 100644 index 000000000..46e81883c Binary files /dev/null and b/tests/compile_tests/font/test13.bmp differ diff --git a/tests/compile_tests/font/test13u.bmp b/tests/compile_tests/font/test13u.bmp new file mode 100644 index 000000000..1c17ec9f0 Binary files /dev/null and b/tests/compile_tests/font/test13u.bmp differ diff --git a/tests/compile_tests/font/test14.bmp b/tests/compile_tests/font/test14.bmp new file mode 100644 index 000000000..329332537 Binary files /dev/null and b/tests/compile_tests/font/test14.bmp differ diff --git a/tests/compile_tests/font/test14u.bmp b/tests/compile_tests/font/test14u.bmp new file mode 100644 index 000000000..00bf15fa8 Binary files /dev/null and b/tests/compile_tests/font/test14u.bmp differ diff --git a/tests/compile_tests/font/test15.bmp b/tests/compile_tests/font/test15.bmp new file mode 100644 index 000000000..18988f186 Binary files /dev/null and b/tests/compile_tests/font/test15.bmp differ diff --git a/tests/compile_tests/font/test15u.bmp b/tests/compile_tests/font/test15u.bmp new file mode 100644 index 000000000..19a9133d6 Binary files /dev/null and b/tests/compile_tests/font/test15u.bmp differ diff --git a/tests/compile_tests/utilities/base64.bm b/tests/compile_tests/utilities/base64.bm new file mode 100644 index 000000000..4d8e7a44b --- /dev/null +++ b/tests/compile_tests/utilities/base64.bm @@ -0,0 +1,146 @@ +'----------------------------------------------------------------------------------------------------------------------- +' Base64 Encoder and Decoder library +' a740g +'----------------------------------------------------------------------------------------------------------------------- + +' Converts a normal string or binary data to a base64 string +Function Base64_Encode$ (s As String) + Const BASE64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + + Dim srcSize As _Unsigned Long: srcSize = Len(s) + Dim srcSize3rem As _Unsigned Long: srcSize3rem = srcSize Mod 3 + Dim srcSize3mul As _Unsigned Long: srcSize3mul = srcSize - srcSize3rem + Dim buffer As String: buffer = Space$(((srcSize + 2) \ 3) * 4) ' preallocate complete buffer + Dim j As _Unsigned Long: j = 1 + + Dim i As _Unsigned Long: For i = 1 To srcSize3mul Step 3 + Dim char1 As _Unsigned _Byte: char1 = Asc(s, i) + Dim char2 As _Unsigned _Byte: char2 = Asc(s, i + 1) + Dim char3 As _Unsigned _Byte: char3 = Asc(s, i + 2) + + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShR(char1, 2))) + j = j + 1 + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL((char1 And 3), 4) Or _ShR(char2, 4))) + j = j + 1 + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL((char2 And 15), 2) Or _ShR(char3, 6))) + j = j + 1 + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (char3 And 63)) + j = j + 1 + Next i + + ' Add padding + If srcSize3rem > 0 Then + char1 = Asc(s, i) + + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShR(char1, 2))) + j = j + 1 + + If srcSize3rem = 1 Then + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL(char1 And 3, 4))) + j = j + 1 + Asc(buffer, j) = 61 ' "=" + j = j + 1 + Asc(buffer, j) = 61 ' "=" + Else ' srcSize3rem = 2 + char2 = Asc(s, i + 1) + + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL((char1 And 3), 4) Or _ShR(char2, 4))) + j = j + 1 + Asc(buffer, j) = Asc(BASE64_CHARACTERS, 1 + (_ShL(char2 And 15, 2))) + j = j + 1 + Asc(buffer, j) = 61 ' "=" + End If + End If + + Base64_Encode = buffer +End Function + + +' Converts a base64 string to a normal string or binary data +Function Base64_Decode$ (s As String) + Dim srcSize As _Unsigned Long: srcSize = Len(s) + Dim buffer As String: buffer = Space$((srcSize \ 4) * 3) ' preallocate complete buffer + Dim j As _Unsigned Long: j = 1 + Dim As _Unsigned _Byte index, char1, char2, char3, char4 + + Dim i As _Unsigned Long: For i = 1 To srcSize Step 4 + index = Asc(s, i): GoSub find_index: char1 = index + index = Asc(s, i + 1): GoSub find_index: char2 = index + index = Asc(s, i + 2): GoSub find_index: char3 = index + index = Asc(s, i + 3): GoSub find_index: char4 = index + + Asc(buffer, j) = _ShL(char1, 2) Or _ShR(char2, 4) + j = j + 1 + Asc(buffer, j) = _ShL(char2 And 15, 4) Or _ShR(char3, 2) + j = j + 1 + Asc(buffer, j) = _ShL(char3 And 3, 6) Or char4 + j = j + 1 + Next i + + ' Remove padding + If Right$(s, 2) = "==" Then + buffer = Left$(buffer, Len(buffer) - 2) + ElseIf Right$(s, 1) = "=" Then + buffer = Left$(buffer, Len(buffer) - 1) + End If + + Base64_Decode = buffer + Exit Function + + find_index: + If index >= 65 And index <= 90 Then + index = index - 65 + ElseIf index >= 97 And index <= 122 Then + index = index - 97 + 26 + ElseIf index >= 48 And index <= 57 Then + index = index - 48 + 52 + ElseIf index = 43 Then + index = 62 + ElseIf index = 47 Then + index = 63 + End If + Return +End Function + + +' This function loads a resource directly from a string variable or constant (like the ones made by Bin2Data) +Function Base64_LoadResourceString$ (src As String, ogSize As _Unsigned Long, isComp As _Byte) + ' Decode the data + Dim buffer As String: buffer = Base64_Decode(src) + + ' Expand the data if needed + If isComp Then buffer = _Inflate$(buffer, ogSize) + + Base64_LoadResourceString = buffer +End Function + + +' Loads a binary file encoded with Bin2Data +' Usage: +' 1. Encode the binary file with Bin2Data +' 2. Include the file or it's contents +' 3. Load the file like so: +' Restore label_generated_by_bin2data +' Dim buffer As String +' buffer = Base64_LoadResourceData ' buffer will now hold the contents of the file +Function Base64_LoadResourceData$ + Dim ogSize As _Unsigned Long, resize As _Unsigned Long, isComp As _Byte + Read ogSize, resize, isComp ' read the header + + Dim buffer As String: buffer = Space$(resize) ' preallocate complete buffer + + ' Read the whole resource data + Dim i As _Unsigned Long: Do While i < resize + Dim chunk As String: Read chunk + Mid$(buffer, i + 1) = chunk + i = i + Len(chunk) + Loop + + ' Decode the data + buffer = Base64_Decode(buffer) + + ' Expand the data if needed + If isComp Then buffer = _Inflate$(buffer, ogSize) + + Base64_LoadResourceData = buffer +End Function diff --git a/tests/compile_tests/utilities/imageassert.bm b/tests/compile_tests/utilities/imageassert.bm index c3e3b0786..8d12e8604 100644 --- a/tests/compile_tests/utilities/imageassert.bm +++ b/tests/compile_tests/utilities/imageassert.bm @@ -6,106 +6,190 @@ ' We then load the expected image as a 32-bit image, compare file sizes, ' width/height, and each pixel. ' -SUB AssertImage(originalActualImage As Long, expectedFileName As String) - Dim actualImage As Long - Dim ResultsDir As String, TestPrefix As String +SUB AssertImage (originalActualImage AS LONG, expectedFileName AS STRING) + DIM actualImage AS LONG + DIM ResultsDir AS STRING, TestPrefix AS STRING - ResultsDir = Command$(1) - TestPrefix = Command$(2) + ResultsDir = COMMAND$(1) + TestPrefix = COMMAND$(2) ' Make sure the test result will be seen - _Dest _Console + _DEST _CONSOLE ' Convert to 32-bit for comparisons - actualImage = _NewImage(_Width(originalActualImage), _Height(originalActualImage), 32) + actualImage = _NEWIMAGE(_WIDTH(originalActualImage), _HEIGHT(originalActualImage), 32) _PUTIMAGE , originalActualImage, actualImage 'First save the result SaveImage actualImage, ResultsDir + "/" + TestPrefix + "_result.bmp" 'Compare both images, print whether they are identical - Dim expectedImage As Long + DIM expectedImage AS LONG expectedImage = _LOADIMAGE(expectedFileName, 32) - If _Width(actualImage) <> _Width(expectedImage) Then - Print "Failure! Image width differs, actual:"; _Width(actualImage);", Expected:"; _Width(expectedImage) - GoTo freeImages - End If + IF _WIDTH(actualImage) <> _WIDTH(expectedImage) THEN + PRINT "Failure! Image width differs, actual:"; _WIDTH(actualImage); ", Expected:"; _WIDTH(expectedImage) + GOTO freeImages + END IF - If _Height(actualImage) <> _Height(expectedImage) Then - Print "Failure! Image height differs, actual:"; _Height(actualImage);", Expected:"; _Height(expectedImage) - GoTo freeImages - End If + IF _HEIGHT(actualImage) <> _HEIGHT(expectedImage) THEN + PRINT "Failure! Image height differs, actual:"; _HEIGHT(actualImage); ", Expected:"; _HEIGHT(expectedImage) + GOTO freeImages + END IF - Dim actual As _Mem, expected As _Mem + DIM actual AS _MEM, expected AS _MEM actual = _MEMIMAGE(actualImage) expected = _MEMIMAGE(expectedImage) IF actual.SIZE <> expected.SIZE THEN - Print "Failure! Image sizes differ, Actual:"; actual.SIZE; ", Expected:"; expected.SIZE - GoTo freeImages + PRINT "Failure! Image sizes differ, Actual:"; actual.SIZE; ", Expected:"; expected.SIZE + GOTO freeImages END IF - w& = _Width(expectedImage) - h& = _Height(expectedImage) + DIM w&: w& = _WIDTH(expectedImage) + DIM h&: h& = _HEIGHT(expectedImage) - For x& = 0 to w& - 1 - For y& = 0 to h& - 1 + DIM x&, y&, actualPixel&, expectedPixel&, pixelOffset AS _OFFSET + FOR x& = 0 TO w& - 1 + FOR y& = 0 TO h& - 1 pixelOffset = (y& * w& + x&) * 4 - actualPixel& = _MemGet(actual, actual.OFFSET + pixelOffset, LONG) - expectedPixel& = _MemGet(expected, expected.OFFSET + pixelOffset, LONG) + actualPixel& = _MEMGET(actual, actual.OFFSET + pixelOffset, LONG) + expectedPixel& = _MEMGET(expected, expected.OFFSET + pixelOffset, LONG) - If actualPixel& <> expectedPixel& Then - Print "Failure! Image pixels at ("; x&; ","; y&; ") differ, actual: 0x"; HEX$(actualPixel&);", expected: 0x"; HEX$(expectedPixel&) - GoTo freeImages - End If - Next - Next + IF actualPixel& <> expectedPixel& THEN + PRINT "Failure! Image pixels at ("; x&; ","; y&; ") differ, actual: 0x"; HEX$(actualPixel&); ", expected: 0x"; HEX$(expectedPixel&) + GOTO freeImages + END IF + NEXT + NEXT PRINT "Success, images are identical!" -freeImages: + freeImages: _MEMFREE actual _MEMFREE expected - _FreeImage actualImage + _FREEIMAGE actualImage END SUB ' From the QB64-PE Wiki: https://qb64phoenix.com/qb64wiki/index.php/SAVEIMAGE -Sub SaveImage (image As Long, filename As String) - bytesperpixel& = _PixelSize(image&) - If bytesperpixel& = 0 Then Print "Text modes unsupported!": End - If bytesperpixel& = 1 Then bpp& = 8 Else bpp& = 24 - x& = _Width(image&) - y& = _Height(image&) - b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + String$(16, 0) 'partial BMP header info(???? to be filled later) - If bytesperpixel& = 1 Then - For c& = 0 To 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0)) - cv& = _PaletteColor(c&, image&) ' color attribute to read. - b$ = b$ + Chr$(_Blue32(cv&)) + Chr$(_Green32(cv&)) + Chr$(_Red32(cv&)) + Chr$(0) 'spacer byte - Next - End If - Mid$(b$, 11, 4) = MKL$(Len(b$)) ' image pixel data offset(BMP header) - lastsource& = _Source - _Source image& - If ((x& * 3) Mod 4) Then padder$ = String$(4 - ((x& * 3) Mod 4), 0) - For py& = y& - 1 To 0 Step -1 ' read JPG image pixel color data +SUB SaveImage (image AS LONG, filename AS STRING) + DIM bytesperpixel&, bpp& + bytesperpixel& = _PIXELSIZE(image&) + IF bytesperpixel& = 0 THEN PRINT "Text modes unsupported!": END + IF bytesperpixel& = 1 THEN bpp& = 8 ELSE bpp& = 24 + DIM x&: x& = _WIDTH(image&) + DIM y&: y& = _HEIGHT(image&) + DIM b$: b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later) + DIM c&, cv& + IF bytesperpixel& = 1 THEN + FOR c& = 0 TO 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0)) + cv& = _PALETTECOLOR(c&, image&) ' color attribute to read. + b$ = b$ + CHR$(_BLUE32(cv&)) + CHR$(_GREEN32(cv&)) + CHR$(_RED32(cv&)) + CHR$(0) 'spacer byte + NEXT + END IF + MID$(b$, 11, 4) = MKL$(LEN(b$)) ' image pixel data offset(BMP header) + DIM lastsource&: lastsource& = _SOURCE + _SOURCE image& + DIM padder$ + IF ((x& * 3) MOD 4) THEN padder$ = STRING$(4 - ((x& * 3) MOD 4), 0) + DIM px&, py&, r$, d$ + FOR py& = y& - 1 TO 0 STEP -1 ' read JPG image pixel color data r$ = "" - For px& = 0 To x& - 1 - c& = Point(px&, py&) 'POINT 32 bit values are large LONG values - If bytesperpixel& = 1 Then r$ = r$ + Chr$(c&) Else r$ = r$ + Left$(MKL$(c&), 3) - Next px& + FOR px& = 0 TO x& - 1 + c& = POINT(px&, py&) 'POINT 32 bit values are large LONG values + IF bytesperpixel& = 1 THEN r$ = r$ + CHR$(c&) ELSE r$ = r$ + LEFT$(MKL$(c&), 3) + NEXT px& d$ = d$ + r$ + padder$ - Next py& - _Source lastsource& - Mid$(b$, 35, 4) = MKL$(Len(d$)) ' image size(BMP header) + NEXT py& + _SOURCE lastsource& + MID$(b$, 35, 4) = MKL$(LEN(d$)) ' image size(BMP header) b$ = b$ + d$ ' total file data bytes to create file - Mid$(b$, 3, 4) = MKL$(Len(b$)) ' size of data file(BMP header) - If LCase$(Right$(filename$, 4)) <> ".bmp" Then ext$ = ".bmp" - f& = FreeFile - Open filename$ + ext$ For Output As #f&: Close #f& ' erases an existing file - Open filename$ + ext$ For Binary As #f& - Put #f&, , b$ - Close #f& -End Sub + MID$(b$, 3, 4) = MKL$(LEN(b$)) ' size of data file(BMP header) + DIM ext$ + IF LCASE$(RIGHT$(filename$, 4)) <> ".bmp" THEN ext$ = ".bmp" + DIM f&: f& = FREEFILE + OPEN filename$ + ext$ FOR OUTPUT AS #f&: CLOSE #f& ' erases an existing file + OPEN filename$ + ext$ FOR BINARY AS #f& + PUT #f&, , b$ + CLOSE #f& +END SUB + + +FUNCTION GetColorDelta~& (color1 AS _UNSIGNED LONG, color2 AS _UNSIGNED LONG) + GetColorDelta = ABS(_RED32(color1) - _RED32(color2)) + ABS(_GREEN32(color1) - _GREEN32(color2)) + ABS(_BLUE32(color1) - _BLUE32(color2)) + ABS(_ALPHA32(color1) - _ALPHA32(color2)) +END FUNCTION + + +' Same as AssertImage() but is a bit more forgiving +SUB AssertImage2 (originalActualImage AS LONG, expectedFileName AS STRING) + CONST TOLERANCE_LIMIT = 4 + + DIM actualImage AS LONG + DIM ResultsDir AS STRING, TestPrefix AS STRING + + ResultsDir = COMMAND$(1) + TestPrefix = COMMAND$(2) + + ' Make sure the test result will be seen + _DEST _CONSOLE + + ' Convert to 32-bit for comparisons + actualImage = _NEWIMAGE(_WIDTH(originalActualImage), _HEIGHT(originalActualImage), 32) + _PUTIMAGE , originalActualImage, actualImage + + 'First save the result + IF LEN(ResultsDir) THEN _SAVEIMAGE ResultsDir + "/" + TestPrefix + "_" + expectedFileName + "_result.bmp", actualImage + + 'Compare both images, print whether they are identical + DIM expectedImage AS LONG + expectedImage = _LOADIMAGE(expectedFileName, 32) + + DIM actual AS _MEM, expected AS _MEM + + IF _WIDTH(actualImage) <> _WIDTH(expectedImage) THEN + PRINT "Failure! Image width differs, actual:"; _WIDTH(actualImage); ", Expected:"; _WIDTH(expectedImage) + GOTO freeImages + END IF + + IF _HEIGHT(actualImage) <> _HEIGHT(expectedImage) THEN + PRINT "Failure! Image height differs, actual:"; _HEIGHT(actualImage); ", Expected:"; _HEIGHT(expectedImage) + GOTO freeImages + END IF + + actual = _MEMIMAGE(actualImage) + expected = _MEMIMAGE(expectedImage) + + IF actual.SIZE <> expected.SIZE THEN + PRINT "Failure! Image sizes differ, Actual:"; actual.SIZE; ", Expected:"; expected.SIZE + GOTO freeImages + END IF + + DIM w&: w& = _WIDTH(expectedImage) + DIM h&: h& = _HEIGHT(expectedImage) + + DIM x&, y&, pixelOffset AS _OFFSET + DIM AS _UNSIGNED LONG actualPixel, expectedPixel + + FOR x& = 0 TO w& - 1 + FOR y& = 0 TO h& - 1 + pixelOffset = (y& * w& + x&) * 4 + + actualPixel = _MEMGET(actual, actual.OFFSET + pixelOffset, _UNSIGNED LONG) + expectedPixel = _MEMGET(expected, expected.OFFSET + pixelOffset, _UNSIGNED LONG) + + IF actualPixel <> expectedPixel _ANDALSO GetColorDelta(actualPixel, expectedPixel) > TOLERANCE_LIMIT THEN + PRINT "Failure! Image pixels at ("; x&; ","; y&; ") differ, actual: 0x"; HEX$(actualPixel); ", expected: 0x"; HEX$(expectedPixel) + GOTO freeImages + END IF + NEXT + NEXT + + PRINT "Success, images are identical!" + + freeImages: + _MEMFREE actual + _MEMFREE expected + _FREEIMAGE actualImage +END SUB