libheif-1.17.6/examples/000775 001750 001750 00000000000 14540541203 016124 5ustar00farindkfarindk000000 000000 libheif-1.17.6/examples/encoder.cc000664 001750 001750 00000006302 14540541202 020052 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". This file is part of convert, an example application using libheif. MIT License Copyright (c) 2018 struktur AG, Joachim Bauch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include "encoder.h" static const char kMetadataTypeExif[] = "Exif"; // static bool Encoder::HasExifMetaData(const struct heif_image_handle* handle) { heif_item_id metadata_id; int count = heif_image_handle_get_list_of_metadata_block_IDs(handle, kMetadataTypeExif, &metadata_id, 1); return count > 0; } // static uint8_t* Encoder::GetExifMetaData(const struct heif_image_handle* handle, size_t* size) { heif_item_id metadata_id; int count = heif_image_handle_get_list_of_metadata_block_IDs(handle, kMetadataTypeExif, &metadata_id, 1); for (int i = 0; i < count; i++) { size_t datasize = heif_image_handle_get_metadata_size(handle, metadata_id); uint8_t* data = static_cast(malloc(datasize)); if (!data) { continue; } heif_error error = heif_image_handle_get_metadata(handle, metadata_id, data); if (error.code != heif_error_Ok) { free(data); continue; } *size = datasize; return data; } return nullptr; } std::vector Encoder::get_xmp_metadata(const struct heif_image_handle* handle) { std::vector xmp; heif_item_id metadata_ids[16]; int count = heif_image_handle_get_list_of_metadata_block_IDs(handle, nullptr, metadata_ids, 16); for (int i = 0; i < count; i++) { if (strcmp(heif_image_handle_get_metadata_type(handle, metadata_ids[i]), "mime") == 0 && strcmp(heif_image_handle_get_metadata_content_type(handle, metadata_ids[i]), "application/rdf+xml") == 0) { size_t datasize = heif_image_handle_get_metadata_size(handle, metadata_ids[i]); xmp.resize(datasize); heif_error error = heif_image_handle_get_metadata(handle, metadata_ids[i], xmp.data()); if (error.code != heif_error_Ok) { // TODO: return error return {}; } return xmp; } } return {}; } libheif-1.17.6/examples/decoder_jpeg.cc000664 001750 001750 00000037013 14540541202 021050 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include "decoder_jpeg.h" #include "libheif/exif.h" extern "C" { // Prevent duplicate definition for libjpeg-turbo v2.0 // Note: these 'undef's are only a workaround for a libjpeg-turbo-v2.0 bug and // should be removed again later. Bug has been fixed in libjpeg-turbo-v2.0.1. #include #if defined(LIBJPEG_TURBO_VERSION_NUMBER) && LIBJPEG_TURBO_VERSION_NUMBER == 2000000 #undef HAVE_STDDEF_H #undef HAVE_STDLIB_H #endif #include } #define JPEG_EXIF_MARKER (JPEG_APP0+1) /* JPEG marker code for EXIF */ #define JPEG_EXIF_MARKER_LEN 6 // "Exif/0/0" #define JPEG_XMP_MARKER (JPEG_APP0+1) /* JPEG marker code for XMP */ #define JPEG_XMP_MARKER_ID "http://ns.adobe.com/xap/1.0/" #define JPEG_ICC_MARKER (JPEG_APP0+2) /* JPEG marker code for ICC */ #define JPEG_ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ static bool JPEGMarkerIsIcc(jpeg_saved_marker_ptr marker) { return marker->marker == JPEG_ICC_MARKER && marker->data_length >= JPEG_ICC_OVERHEAD_LEN && /* verify the identifying string */ GETJOCTET(marker->data[0]) == 0x49 && GETJOCTET(marker->data[1]) == 0x43 && GETJOCTET(marker->data[2]) == 0x43 && GETJOCTET(marker->data[3]) == 0x5F && GETJOCTET(marker->data[4]) == 0x50 && GETJOCTET(marker->data[5]) == 0x52 && GETJOCTET(marker->data[6]) == 0x4F && GETJOCTET(marker->data[7]) == 0x46 && GETJOCTET(marker->data[8]) == 0x49 && GETJOCTET(marker->data[9]) == 0x4C && GETJOCTET(marker->data[10]) == 0x45 && GETJOCTET(marker->data[11]) == 0x0; } bool ReadICCProfileFromJPEG(j_decompress_ptr cinfo, JOCTET** icc_data_ptr, unsigned int* icc_data_len) { jpeg_saved_marker_ptr marker; int num_markers = 0; int seq_no; JOCTET* icc_data; unsigned int total_length; #define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */ char marker_present[MAX_SEQ_NO + 1]; /* 1 if marker found */ unsigned int data_length[MAX_SEQ_NO + 1]; /* size of profile data in marker */ unsigned int data_offset[MAX_SEQ_NO + 1]; /* offset for data in marker */ *icc_data_ptr = NULL; /* avoid confusion if FALSE return */ *icc_data_len = 0; /* This first pass over the saved markers discovers whether there are * any ICC markers and verifies the consistency of the marker numbering. */ for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) marker_present[seq_no] = 0; for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { if (JPEGMarkerIsIcc(marker)) { if (num_markers == 0) num_markers = GETJOCTET(marker->data[13]); else if (num_markers != GETJOCTET(marker->data[13])) return FALSE; /* inconsistent num_markers fields */ seq_no = GETJOCTET(marker->data[12]); if (seq_no <= 0 || seq_no > num_markers) return FALSE; /* bogus sequence number */ if (marker_present[seq_no]) return FALSE; /* duplicate sequence numbers */ marker_present[seq_no] = 1; data_length[seq_no] = marker->data_length - JPEG_ICC_OVERHEAD_LEN; } } if (num_markers == 0) return FALSE; /* Check for missing markers, count total space needed, * compute offset of each marker's part of the data. */ total_length = 0; for (seq_no = 1; seq_no <= num_markers; seq_no++) { if (marker_present[seq_no] == 0) return FALSE; /* missing sequence number */ data_offset[seq_no] = total_length; total_length += data_length[seq_no]; } if (total_length <= 0) return FALSE; /* found only empty markers? */ /* Allocate space for assembled data */ icc_data = (JOCTET*) malloc(total_length * sizeof(JOCTET)); if (icc_data == NULL) return FALSE; /* oops, out of memory */ /* and fill it in */ for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { if (JPEGMarkerIsIcc(marker)) { JOCTET FAR* src_ptr; JOCTET* dst_ptr; unsigned int length; seq_no = GETJOCTET(marker->data[12]); dst_ptr = icc_data + data_offset[seq_no]; src_ptr = marker->data + JPEG_ICC_OVERHEAD_LEN; length = data_length[seq_no]; while (length--) { *dst_ptr++ = *src_ptr++; } } } *icc_data_ptr = icc_data; *icc_data_len = total_length; return TRUE; } static bool JPEGMarkerIsXMP(jpeg_saved_marker_ptr marker) { return marker->marker == JPEG_XMP_MARKER && marker->data_length >= strlen(JPEG_XMP_MARKER_ID) + 1 && strncmp((const char*) (marker->data), JPEG_XMP_MARKER_ID, strlen(JPEG_XMP_MARKER_ID)) == 0; } bool ReadXMPFromJPEG(j_decompress_ptr cinfo, std::vector& xmpData) { jpeg_saved_marker_ptr marker; for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { if (JPEGMarkerIsXMP(marker)) { int length = (int) (marker->data_length - (strlen(JPEG_XMP_MARKER_ID) + 1)); xmpData.resize(length); memcpy(xmpData.data(), marker->data + strlen(JPEG_XMP_MARKER_ID) + 1, length); return true; } } return false; } static bool JPEGMarkerIsEXIF(jpeg_saved_marker_ptr marker) { return marker->marker == JPEG_EXIF_MARKER && marker->data_length >= JPEG_EXIF_MARKER_LEN && GETJOCTET(marker->data[0]) == 'E' && GETJOCTET(marker->data[1]) == 'x' && GETJOCTET(marker->data[2]) == 'i' && GETJOCTET(marker->data[3]) == 'f' && GETJOCTET(marker->data[4]) == 0 && GETJOCTET(marker->data[5]) == 0; } bool ReadEXIFFromJPEG(j_decompress_ptr cinfo, std::vector& exifData) { jpeg_saved_marker_ptr marker; for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { if (JPEGMarkerIsEXIF(marker)) { int length = (int) (marker->data_length - JPEG_EXIF_MARKER_LEN); exifData.resize(length); memcpy(exifData.data(), marker->data + JPEG_EXIF_MARKER_LEN, length); return true; } } return false; } #if JPEG_LIB_VERSION < 70 #define DCT_h_scaled_size DCT_scaled_size #define DCT_v_scaled_size DCT_scaled_size #endif InputImage loadJPEG(const char* filename) { InputImage img; struct heif_image* image = nullptr; // ### Code copied from LibVideoGfx and slightly modified to use HeifPixelImage struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; // to store embedded icc profile uint32_t iccLen; uint8_t* iccBuffer = NULL; std::vector xmpData; std::vector exifData; // open input file FILE* infile; if ((infile = fopen(filename, "rb")) == NULL) { std::cerr << "Can't open " << filename << "\n"; exit(1); } // initialize decompressor jpeg_create_decompress(&cinfo); cinfo.err = jpeg_std_error(&jerr); jpeg_stdio_src(&cinfo, infile); /* Adding this part to prepare for icc profile reading. */ jpeg_save_markers(&cinfo, JPEG_ICC_MARKER, 0xFFFF); jpeg_save_markers(&cinfo, JPEG_XMP_MARKER, 0xFFFF); jpeg_save_markers(&cinfo, JPEG_EXIF_MARKER, 0xFFFF); jpeg_read_header(&cinfo, TRUE); bool embeddedIccFlag = ReadICCProfileFromJPEG(&cinfo, &iccBuffer, &iccLen); bool embeddedXMPFlag = ReadXMPFromJPEG(&cinfo, xmpData); if (embeddedXMPFlag) { img.xmp = xmpData; } bool embeddedEXIFFlag = ReadEXIFFromJPEG(&cinfo, exifData); if (embeddedEXIFFlag) { img.exif = exifData; img.orientation = (heif_orientation) read_exif_orientation_tag(exifData.data(), (int) exifData.size()); } if (cinfo.jpeg_color_space == JCS_GRAYSCALE) { cinfo.out_color_space = JCS_GRAYSCALE; jpeg_start_decompress(&cinfo); JSAMPARRAY buffer; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width * cinfo.output_components, 1); // create destination image struct heif_error err = heif_image_create(cinfo.output_width, cinfo.output_height, heif_colorspace_monochrome, heif_chroma_monochrome, &image); (void) err; // TODO: handle error heif_image_add_plane(image, heif_channel_Y, cinfo.output_width, cinfo.output_height, 8); int y_stride; uint8_t* py = heif_image_get_plane(image, heif_channel_Y, &y_stride); // read the image while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); memcpy(py + (cinfo.output_scanline - 1) * y_stride, *buffer, cinfo.output_width); } } else if (cinfo.jpeg_color_space == JCS_YCbCr) { cinfo.out_color_space = JCS_YCbCr; bool read_raw = false; heif_chroma output_chroma = heif_chroma_420; if (cinfo.comp_info[1].h_samp_factor == 1 && cinfo.comp_info[1].v_samp_factor == 1 && cinfo.comp_info[2].h_samp_factor == 1 && cinfo.comp_info[2].v_samp_factor == 1) { if (cinfo.comp_info[0].h_samp_factor == 1 && cinfo.comp_info[0].v_samp_factor == 1) { output_chroma = heif_chroma_444; read_raw = true; } else if (cinfo.comp_info[0].h_samp_factor == 2 && cinfo.comp_info[0].v_samp_factor == 1) { output_chroma = heif_chroma_422; read_raw = true; } else if (cinfo.comp_info[0].h_samp_factor == 2 && cinfo.comp_info[0].v_samp_factor == 2) { output_chroma = heif_chroma_420; read_raw = true; } } int cw=0,ch=0; switch (output_chroma) { case heif_chroma_420: cw = (cinfo.image_width + 1) / 2; ch = (cinfo.image_height + 1) / 2; break; case heif_chroma_422: cw = (cinfo.image_width + 1) / 2; ch = cinfo.image_height; break; case heif_chroma_444: cw = cinfo.image_width; ch = cinfo.image_height; break; default: assert(false); } //read_raw = false; cinfo.raw_data_out = boolean(read_raw); jpeg_start_decompress(&cinfo); // create destination image struct heif_error err = heif_image_create(cinfo.output_width, cinfo.output_height, heif_colorspace_YCbCr, output_chroma, &image); (void) err; heif_image_add_plane(image, heif_channel_Y, cinfo.output_width, cinfo.output_height, 8); heif_image_add_plane(image, heif_channel_Cb, cw, ch, 8); heif_image_add_plane(image, heif_channel_Cr, cw, ch, 8); int stride[3]; uint8_t* p[3]; p[0] = heif_image_get_plane(image, heif_channel_Y, &stride[0]); p[1] = heif_image_get_plane(image, heif_channel_Cb, &stride[1]); p[2] = heif_image_get_plane(image, heif_channel_Cr, &stride[2]); // read the image if (read_raw) { // adapted from https://github.com/AOMediaCodec/libavif/blob/430ea2df584dcb95ff1632c17643ebbbb2f3bc81/apps/shared/avifjpeg.c JSAMPIMAGE buffer; buffer = (JSAMPIMAGE)(cinfo.mem->alloc_small)((j_common_ptr)&cinfo, JPOOL_IMAGE, sizeof(JSAMPARRAY) * cinfo.num_components); // lines of output image to be read per jpeg_read_raw_data call int readLines = 0; // lines of samples to be read per call (for each channel) int linesPerCall[3] = { 0, 0, 0 }; // expected count of sample lines (for each channel) int targetRead[3] = { 0, 0, 0 }; for (int i = 0; i < cinfo.num_components; ++i) { jpeg_component_info * comp = &cinfo.comp_info[i]; linesPerCall[i] = comp->v_samp_factor * comp->DCT_v_scaled_size; targetRead[i] = comp->downsampled_height; buffer[i] = (cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, comp->width_in_blocks * comp->DCT_h_scaled_size, linesPerCall[i]); readLines = std::max(readLines, linesPerCall[i]); } // count of already-read lines (for each channel) int alreadyRead[3] = { 0, 0, 0 }; int width[3] = { (int)cinfo.output_width, cw, cw}; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_raw_data(&cinfo, buffer, readLines); int workComponents = 3; for (int i = 0; i < workComponents; ++i) { int linesRead = std::min(targetRead[i] - alreadyRead[i], linesPerCall[i]); int targetChannel = i; // Note: might have to be remapped when we want support other colorspaces for (int j = 0; j < linesRead; ++j) { memcpy(p[targetChannel] + stride[targetChannel] * (alreadyRead[i] + j), buffer[i][j], width[targetChannel]); } alreadyRead[i] += linesPerCall[i]; } } } else { JSAMPARRAY buffer; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width * cinfo.output_components, 1); while (cinfo.output_scanline < cinfo.output_height) { JOCTET* bufp; (void) jpeg_read_scanlines(&cinfo, buffer, 1); bufp = buffer[0]; int y = cinfo.output_scanline - 1; for (unsigned int x = 0; x < cinfo.output_width; x += 2) { p[0][y * stride[0] + x] = *bufp++; p[1][y / 2 * stride[1] + x / 2] = *bufp++; p[2][y / 2 * stride[2] + x / 2] = *bufp++; if (x + 1 < cinfo.output_width) { p[0][y * stride[0] + x + 1] = *bufp++; } bufp += 2; } if (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); bufp = buffer[0]; y = cinfo.output_scanline - 1; for (unsigned int x = 0; x < cinfo.output_width; x++) { p[0][y * stride[0] + x] = *bufp++; bufp += 2; } } } } } else { // TODO: error, unsupported JPEG colorspace } if (embeddedIccFlag && iccLen > 0) { heif_image_set_raw_color_profile(image, "prof", iccBuffer, (size_t) iccLen); } // cleanup free(iccBuffer); jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(infile); img.image = std::shared_ptr(image, [](heif_image* img) { heif_image_release(img); }); return img; } libheif-1.17.6/examples/example.avif000664 001750 001750 00000335704 14540541202 020441 0ustar00farindkfarindk000000 000000 ftypavifavifmif1meta@hdlrpictlibheif (1.9.1) / Rav1e encoderpitm"ilocD@#iinfinfeav01Yiprp;ipcocolrnclx av1C ispe ipmamdat qP (g`[> qAX"}EEP;4Y8WVz՞>4B&L,]F` Gxи ioS2sEJ/ p2V=вXs 4E. ?Y(bY|A]oĦ#IG] pr&jQV!6/[?jI$(%xDQzd5!xkS+ QV9of5R\or+Qt/UsyygЂ!{1YdY3Φ璙hWXsxmZXK%wcLjTH&A@f(X 0IicgtR9k1 ;l!t jYimՐL9=C=jq )wk 3.![Dl"NmM)#JJDbdM*K'lA(|"\k7-$"Bc+=PgBmPu-;t'#O11pVn7+wbQkn!eO8ic+}Z j.MEWqƄ|{4'D#H(`bd?wO>zЂyLBJ#&+z&&op%XmaT7` ȗhX[?̛ٸWLV\ o3a?j],5% Gw 1K͉ G;p>p|.u$5;9D1@*RUo( <s=.cY5qqn`?(i7M93QP4&X΄]YrR'h%=c-."j]:'c"M9gƬ ek#3-'dؒZg"~c%Ar6~`qs\/-z?:0\jstCTZz ;e4F[(\U%L zOr_=vs) #V00hɈk:R pysk4Jsp~gnHRM_+ <5Opx(-cn_ͨbP-f$qiVk8!fI;Ezp(r-'Dt-.فB uȟ1ݟ/M5`0Z&=< Y똇6jy˳,2g #Z#s;4%ѕi@TGRRЂ*2m *[ߐGAc kיD%$٦VdKЙs$pL4 Gƪ~>J7 ~Lԅ,#DOɄh@q%axxM(.s:M#ʔ3bLɔ?$'v,q65ش Lү|GF ;Qg3DGRO35.3}!g5r=@'Ϡ|frL|w]9+*1JDD%{t0|tr %9$Ҷ~RFo Z3d5QlU`Rxl:]a$LI^i-gKJRttTNC'E̺, |!HWV]P)"k!,ԏ,3RJoSYG&0oZ]=Ѱ- t%Y(nwjK^+r.z.SpϱjԽwB=1""鲯lERN`͹pȝ ^2?<O NJس _'F ,هͦA='-l&QT^ցog nm`SAy:3u"pf7PjE8^3%* a?$4ܢq'7壌iTjGx#;##_dȭAd$CN٣7Q_qT:$sLF6qA HA'2=Or 2"1V5OɸFo~p='lK0m R(Itc+,TSlk {x~nthjQΪJ`c7VY[{ 1W>{2<6w3GkިjE;叵ٺ2Pа*h.MAS4'G;bcp9J? t[\ Bz ;ݯ?ߧh\y:ɋM3n]%{+f |y}'v0#ocRb8M Q/FdOmZC{v;S{+ ! M$J,s' .ܣ4(CI/4=^gB.qslt:Qi7"Ph8ryg2i1%vC{宭PaLtEBX &({LN޼-Jaq/ F.6)J32Й!) @d5{Σ 8]##UBqǚCw p<_1M BnVHKs.5W$>%6~ZPI?NsS Y 8$,fk]r:Wzzm$C1VidArh1G+_ay [Io\F߸ r M׌SNԖ5\6p k@5PeT>ٝ$A !UZp5/TWeL˴ɸ<$/}|kK 9ptO]e 7[1m} A92FB1)|0=㱄ړC]7Ϡ_ia]&*6n͡YU E l)b9VY2&O]{ԬstD -6{75'+VYk of d?;cp[Ĭҧ7(?~6Yk+@:`(f2qǝ/4#IRvpB+L%p =i7C Éh27]Tr\Yȁ~}`΃%MJXA njJ} uL@xMZd9a_᧏xn9P2ۋf52M* &cرȕa'z 1 [ғCnRGTMsY{ T_$f툭.: ԴD1ًձ<])V;W "/>*YR!0ėjr8BddkG Цۭy@'=q.D=%і!ݼ*&Ł%~|σ{b]K/22.y1s{&(*)~mMD6zRp\H,}<٨L2Zo={$ #7Ū-AE: 'bPE{-`q`ub@o^ȏ<ǂ '# >vq{?RA"$#P_Ek:p {fHpXFADz[GQLbPɪ/S+iAiflH) ,5mJ&,Q4Fnha܉ki~CA IDO|tV+%7T_OMer7=.Rd$6qXfAb$rDXdƭҺ7urZWع"=^քʰE2&p W _bɫ} ZJeaE؊Ihaq7ձQ"Gy%RnwL~:DvE>"'=lւnutt%1!&-}'=m0;cXnMEn |1_ůI 30Vޔ>D_1k#}D٭$5Q)<@G5*bϯ5AJΠ!7>*c A{˗ =mA}5l?D08bP'JBL >jālU% }#]E-X<sr? lst-?%j3{1#LIA"ָtBEw9xRsIύ#,&_EɹS6V0s0$s8UsT(~IX_m6ve lBi>NjՔ-9yyM|)/ /&/4J]r^6Lfi Vc\2I} Y-H(E8Px+A>Ҳ:ʶC9d^vc[V;.!'6>ol+(ֈ-+𕲧DA8CIUꍕyzq@YlJhdg.{Y"I<ZD 'F8(Z-~@׆mQ PapDxR˘e\[[g,hWXsw@h+SZe#lp:qU%CiR,=D?.FXќ7H5lt8lNw6}|"b`լh>-p2c1?|cK( {)R/?qWPVNV qCCm)[/Ηvmӎ<[43K Sc='I[%EfiV{ ,'ɥYj?FA'!]h>or~ZbSBNXO B)נbyd.Z,c % <>o}sDp _š0㥴 LG+PG^&)ǡ&unXhaԧ%_m/V@LM SNGu)D@x0 R*BT88 i oÕaka`+KI\'2NMiɇVXNS);La)P-FG)[K~ܚʄT=P kYtob<]˔`vϸ~댻QD**^wh #Y$^+~Z3F3M@ /~(8c! |]aRcMcq8S fT~ux45 :`M%4zDGL=5e b٥@6CYb*Ұ"/V!fQmFݎ?@N#jK:$!4:L@ZKLoBIGBzlUk3Ӿhux"u +斄Zwyq bqgG7K^9j(JAt,S75BMc nT9 'uv43!䇌;>۷Ap$%wk,?l_n3XSnI|T:f&) H yRz0Q[Wm:5d:ٖFp>=sE;&ouB}EkmO7ё܇K)߅W<jǯ?槬{Wu:[2'Nntlh.$5_js\9^ xީ;'cQm"̃C={4+<3)FɓJKĚ`#e^2Y73)9ҝ5n:KuA$"CW~oH",:~Q(]Ǔcڎl&8xWÅb4RȮS ސnRem8 dRУAK7m*luwa'g^{IR3\sMKjJ(nrmʚ*zqZi5،oZ(/d8bzAW)6Aܒَ괵=ؔm#v8׼')i BNlu%l00yAPɄ2L|i]fL(a*V=R=4(^b<v#x~F/]n."s8m4|I1,a(_@>s+o >q:I_ &CK6h3-㡌DL}aCRG sqyvBs8+l- [\tN̡݉@E GR,bJMSTZhm˫[<0Llq1􃈍BiCWSr·$Ej*m_ĸGn9^Bu(B~ۃ$30z!?/N։iyx݇Ġ,:SDvrk0i^>,(nZ}j+:)S[M>WQM'QWZ81jR2q`n`R:Є#I258Aח,vɮ͜:ZI3)!#M .MˣLfJG@tg'Iuw1='[v?KB"k2mJžj'ȆoX2Qr: VM{6^iKe~Х b4>^BI@dӒ*G-vW4z>ń؃T p?< zk]hϭqwR-bt^|ԁǽC?8ZsFAw0iMj9.tUD;͋AW\CK3Ap:r}NŽ\=cOh%dy|V@gDG-{'+fcDt*mi.1Ӳ~Og-k4X}Xmr>8.M)mP#]d#cWk:YЎL.u=Ѯ1PUɠ'_kezfz9OW2#*D[ ?I8Nn'2}0U9>(i<[t(0k:{#7¡q뮛R#pHF+`@O:Qxa^<`UBسBq7%7Q`o7;WX;Sjx6x]X u4 AG]\qD@#ls]8?+;J5VB8_\P+"VEW 9 r8I2FIwCp6#*˗ 1Fd䴧%~cR_AruY"M@w\5H3E,U۾Nb~ꀎ%׵`H[sZ㫇).j5y|J9pcݍ%`قX"ysk1A7_g:uy{%_Ѻg5B#їfqF\dwl9&F + m1RWlSI)+U~51#}kX!EO%!wI 2B~}" K'[㛺6 tt`pUaV ёx{HJ@7R(io? =5ϩ7}&20}E|"Q[T# 븍nTTY\OL, BNsx!O \)`ԂF4_EҼ Fd-@]ؖiZKd&/qE2]GYsZg6{! e,,Nu}!Ke(ɣ_p\ׄ2nFN'|f.PjQ6bٱӒ/EK٩'VP8NrN?>\=Y1:OQHb0[X$4MIlj/ 9IcUܲ!.ܨr`~ b"o7 A0Ⱥ|Qcs†@xf$zkk{| =is0qO3GÉDWU45;)+-Wac5[3_0&MRII5Aw.鋳 N ė O(=g"% S4[njylÐdSftr։ro`A +H:QQ.;&D?rT<+J@iۓ+[0䒌[."`sjW;؃ VVʑI.㭃cZ}Wt!Z4h$ThU*4vduȦNhdO'aD ˿=(vkmڰӚA9]!"Hz4n-Lt%܀iF -[!}O(?Hƒcv!ӭUrs'/|;I]8Azrg<9xf5 |k]rWXp7(]M=ܫJALB,#Gkl*F{#nnw VQ2Pe7/s2Ol]1Mt 3o@!{E/н'B}x8xI`JpK0*mw!4YIcɁ/9uy-l3f_}$dᕧl>tiFj+oh9 p8”e[.@+.wU>WR8T4Fyr=uA:zy`r4ʀع׭H9EjMO1]l*0t-FZ~zv^ e:FzZ].A-SMyɜثI|Y})dbX:I ms~ᏁL&vWB#e*=- _v;ĄzI- _Z^a]F `j6}KvޖlZٙ}7=7hE7o1jr/q+& c%50JNe$TMݕlQihakikhZ{.5{ny#UBE"W7@p/AoPe&6 [# /'`BNy 뾟Lէ@ 6h%A+W+ci~9a(RpƦ.}HQ%V<4_[YF/>}8r 4FFA-lKD m[ jH6 !ocm36/Z9>N|dnUh ' {5wbas.OTl5@L [jJ9C6#Ei+ZʁVMz;i'YP>A/ K@duj&;X@ҵ$z ?˧+=dpՖT`PC#/# Tfd ϤJQeurj-78'DL}5 ji g9XLR#R."ΝU^5ǖX?f%ft5OsBΞ2gA۩qE_L&%JʀT" 2<;O b7Rcwl& Zq-l0OO/O')uE9_ yL D~uo|ξvt#"mGh)Nr͎G͟<* 2Lyxiӵ@(WeGtj ! ? _nI ^HYN{$觎U[ξPVjPPr/:!Ļ{ʲ&DjH tGK,X[ck[R \CSU_ͦȥ(XLw)VIZDsR(Mr͍a}Т])*8V9X|"svy&߰8 dB1 nͷEB N0Pt*Sl Aﴤ#9!;3Dn>:4xq]Zl%Rֽ(9|Z-l%C뀸KWPOuv0 yRAUPMl~G$ՌjOg9T:,m}RaɌ&KŎ3F]Ghsot][{*ڸ(+򇴙IH B3IHY{bX6[ x?(P 0Ś]E$*Sas;{ [!jBd^|Zˍ߂TAzzzuUMoj ` hT`D-A0NC(ÕbM1e6d>+ᚴJvٚm,=EFu%tfk=NI_CQfds_E17C@W?PudP$Z̔}2 -*\z`ci <g.'6$ !n\'ryUiN6п Pt#uuùdL$'p IE 2aId.)c#BW ^/fV'Y_DĠHYąv۰"$mk _נ򻸫`Zzš r>^b]zw0 ڌLCOa) Y$~*l 0#&`:^#tmsq v@rff/쾡n&74)⩓4M#{N[ʅ\ks1{DQU >2+ 5ŸDk8rQ2 sȃC|= )Z?TF-ÙHh8;d!P@rHLډ9e֮<[}\݃,piJngDYLVg;ݛަI˕ڱ}`͠-]4>Ntf&U ChS:aCd"$ȩexJA9zsA%NU<Ч_v|ht2tؽ`l-اH|-^@ͫ=715B _LdFyϏ m)x1j8 ]M8Y:Ʒ7\3!8xTg$5 )B]eLS1窠Zx޴YH̡ž88Z2a9 X)Q7Lp!jg"EK|}Ibc& f;o"H=٥#،d/xOZcpۆ#̝óg TX m <ϸ%BS64!޽YK'Q;3QZ WФxX :i> ~۫C-ߞHdʲ@+$QB{ZuHBh/Yvzg*鋙qPY1 9Dbd)vy+>AQV@'B;d9q8QVI\`r<[b.BSR i3KטAĩq3L,n@zǣ}jG.Oۈ9B3z*6]!|NlǼ-Qg/uU>BOH'z@NAc v:%KȢUKܿNVU)djQ v7A3 @4BGx\zoZP1ڛƢOv&+ɋ5ʣSȐQm×(Xw4-67&˘JfG:@QtJFmu\4fYs 2mba\ȇYbha1jK,hp|wk&AQw~sq[j6(E&ӶxԘ] "ipZO1,Pz8}zgdy*C"*ʟEQB㰻Gm@ꐍ$Fq3='[]qɟ i̵5n~cyG NGi7lSMPC=e0T,izF KpQn=*в%Wp>ܳb|r,DߚȜI8KZQڱ?>I/6dThpC^N&JCylI*E!Jˏ)&pQLm\-5]h!Z,=eXr]ajێ汮_w>̽s?̥:srRs55p#u! nAx@ &vm*M ѽXq]>5>>ր+M1^4Lv?ǻoe %5A' CB. _ԁ_H7~Gy}Q=bԯz:hFFYv[$S(quKDr.эOXz3dGNz܍@^b}%Ξ/qu>Z_u\M= ;Qy̭Tu4j!:YA YH{e*9ZQ<%Mva~/eIA0e]I&m*?E^,bS?鐞   7C+|Za;RA'$N9pLQ1IW%`fX*zHmQu>!be[@@9m\uP{mKd_zbs83`YqPy6IDYoE U_ÍtW$!vj#lp(Wr=DN}h/W9h@aߒU5'ui"ފM0D`H 498']~B6Z%ي$ isnZ>jq HtJ#TeCq17ˈK.B@)yh&i ciaUz%Mȅ,rvq\Hin`o4E[,?^+]zo2Z׮!Rm9`/y 7Aٓh].zWP9sh=VcKbCn /R/>ˉ*pgCJ `Ʃ%QPd)kQNzOdƑSx,{ʴP٤d5+ҺzeYQ2;żdiv. ^*gG\)E[y}@ڭ&+ƤҤ&^\$%Eɧ $48 I<oV3Fgo| N~Qv/ٸp{WmnrfwZ9e\ve` 0;4@LWsxmnI-;. :cmk]Tޔx\zoJ`R603pzFA)3D7+"hA'< ԞyE];=9tbN |.,s,tE8>Lځ!|f-%ܓ? yԛhlE2~~V (=[V^ SFJ v [h_>} qjQpzeDˍË`UKi)Bi0swbE# ӬT[竇b7 CIfîk(k A,c8ގeYME&5QnU"Ą nR%^=dvQ1byʆpmm"Y[8#U=gDU +*}כg>_AKх`_ov+>^N墕Mko!OQtoxD~Bo5ߺJg(v· ~0ls# d.'gu(KKSzP[ٯsEh#GXG>a7讜Kb).ϵuBb&^Υڢ|VayekqKRjl߰iUkԧ,N$ {&3*h#1ihM^ԈZ K+k0{E :aQ4{Mc7+@vHyR;bW8q{zW%߲^x%XS9P'ϰ~%4.WoIW WC&4 N)Pa&z5+}Cѽ^i)@k7k/@Af!T+~\Xzn?:k2V zm+B%df4 f8m7slQ6ۍabȊ@fkBtzx6(tKhtkmʀZ+?5"M񚘌lCU+ډU[Uhmo\aٝs@6b]FE{]Kn(sD*g(yIh)29_K%vE4|jXqhٙ&>!\8i͌9<Zd΃7pL @!,0HA8xn{G"oB#{hӄ]d}hf8b5U-&p"A*2SxENˏSI|XTKq2n5"۟uKFÃ"9cZ(Y UKbFmn tKZ?+_Ƃv+q_B1DFA#::mnP{nU~tY`ȥd ‚G)f$uߏu>riō)=j(!]t_=WaY#-ajUt/)lc}$w1Ӄ9_\|ey 5^þBkg3=2YӁE uFtm2/ ( $˶bMDk9ʚmvU%zUdjaկ>FY"#E"XޢMߌHH *dV9>J)u~dtɘ,F}E:-+;#IG$L|*_ÿ^cy[Kd^F𼹏6 ^^ItO4H[ ]L;>#nb} 6 $Փ_֘Z9Ꞁ*% WXqv{O <2#4"x{-i{|.E~$|ԗ&RV; IRWa`Fgt|?'M0Ym X*qH>"z漁9)FJ^OXE7,uEsdQ ƖDZ:^G=BCv\YYZkǑOTa;-QrvNGI&tfҷ0e ζmJu1]WF=w)׋- vq2hT~&\5]OɽG-3p1RڬGI|խZWRbX=Wşt8SbL_ R]_iɓbLc]Bf3ɞqD/S+.Ȋt͹,JN(454| )6{hg\o\IHQ`mZ< o:2bu|QEUD"O9U"!*SLƈoj#3M]ueWyRۜѕ*y*gbFd\U^@cb/L>T:\\.^/7E,HpޓrXeC<3sP:kNM+HB5ͬZew' ¤bpF&/nNCu)L?Muk!q452DВget])VrtJ{LŮE"G@+ߒ&Fo*V`ɕZ>~b]0ygBb3O~ps$uuWiaYOBds1%Sp(3㊪\E|ꀸ tA@pqtYyFvvTVC\I2o.{*.hqrLp۴Xw6P8P0 WipgEkw"%(>!)@P*k&YJ^K++Jc4+j@#l!A^ey"=ϫ5^ x`dbF -jÅQ}IRV va;m-mDձIbGӻ/G~I+"PW`)M XuU(l0J 9I){V PMXrR0Uʤ7a3_)_yCVgU$o&4٫gRs΅KEB*H~.hݷNX^Ա.&_ ?Ll/&sݰnn{e-"vB>(%EKja}L:Kv_I֚o27}m AC`ky`zصP 3﵇3CO^`n`9I',xr7Xd{+J!rӉ=%|8馅[B< c^L!h/Ը}s(X!~ónMϥ]L|ΪfHt -9P@Ӳ S ~ksT^*=gqTOV/n$ɬn%Yy:Imt9qfB'_C99'ʔix5x]~ 3HM{pyy2ݮXD; 9.C|+)y ?;\L~Ea,ArLJ yv?0@s?A*gF?LBv}lxjq_7#.+v }\k(̱x8C y: _t7paRGPۃ1_ZދQ݂4{ѝչ>E4;gǚ"ϼx )Lr{_^3.aZBts-k0_)ڣ>ZɈD{{/_S"5q=bɽHLQ^g;i5٥ S'~z}j(%u[$𑢊5,0 QVyh:f=1':Xϱ!Nb 3)gd4/FdߝVz-y}BaPYTޯA =FX 3im}*{ohօ|ȟ4aPLf) t@&v"kŒaq%\FWo[XH1Gt@14BPCwJ*XzaPmDҭ9,D׬pBE$P,`u6_% tР8lOW8([Ȫi>r~ecB9dUp›]Ϝ}u$xU8ԉ{(hW򨷓)?GpS?P!!Z* oEe('|ٖnN6Ml6:'3B/%"tPٱ>W8G;Ln63E<4v pNyy=U8QdS޺4 Ǯ|fu2UQ(!P -^u1$ Ӓ%TE4_{ߌ_b /3I|c)A?iXϾyL\Ur>#{ȇ)C6XOBB՞=kC d[\^T#H(IUS E%È kVl5vkŴԑ"P)+A'L\PB^UJ: 2t(CRzkbga#uGL \3ɜdk槃ah4XBryYWE?NF 7ҭX- q{+)lͳ8s\fg'Y][WEIħp:4"&BI!o҅a@sXchE‹3{-,m$ݞ) {EDR_aH=[lfr5XkrP|08l<hcgca0n/(*Ir+s0' v),`^eQŀ_pV)gɉ-m1>ڑ88TL.'֑4;ks3t gӽؼ/ Ӈh${ _'t`r& .,J,lBбbud掉ӵ;V-8?^ӏ~E\)0GӢ6чL-]@Χ(V)` io)5T,ЯZymp3j_P4e|/ NF-p!x}}gzO LxcPiVXqan Q3!6Q[l9i?SN46(yy[ KyMF_W~NzNGOW:lQ&M}GB,L$ZYme|#tZovp 5mت_BJH. jtyUy+|Ĉ}Yk\t4!$x|q;u> ~qt.S9& zZ?$8u2ӈe@RP#^^w?JbPx?G8fl)@{_Vm2S S&^ӣo[y| h0u~=S {Yb2xW@ŧR~S5Wa\Iʛ\ xRL23O쒮ګ Zm9۝ 8ЧdFnW(~.!)Ves wf {RqgOeQߦ="nЍqp6OtYW&(Z3F4 S$(ԟ}zW!V3 bz9]ڗ] 9"> w&Cׁ%P'5`'sUg)!`GU3A<Ť|@`ۜ]=4}{|Iq_/c6e|#IJFmdTVp=I?P :5 k_ES.bp^[{OrZ.[rF@!s.c(Oh^#\W< uB|ID% 9,m`z5 BB]H@yhP&4Lq#'آa; 2+O x{\ͿnfVнK=c xqRm[)>aZQ'i8ucp]=WӟќF}g)rVf/x '̈*]ҌǓ$i=>f07LR؏wFC,89flz^!Y0)/;ؤgGDò1_@ЭrDv};7*][5ҋH .J^]4t}KgΪǘ[ jp^9 {`w+FIfVЕgVyV'd2(iҲy)Od N\Xz d?]~вE,8*IE@S kaj`fgʴ+Kj3ZqcP:t8Ivt3o pC cݝ\Нիr3d}g!Y\=͸y,{zbŸﰤNf*.RLeL& N_*PSn_Ǹ@6A>4Z`>~y͏ Κ+r< ~ dVWPb뾃lMZ6il9M:M_ܒVĢ|S8`r׌֊o(t(Pr beXO puZZ#t=agR#3A;g_sEr=YG" Ȣbs_j:{c޻{av;Eő^RPiiVt[t\dHWN7Z ]d%E̳qWFJWI+]`뵨?v/.ȯW3J .Z_ Ϥş|- v-Cm #IUZqI^ǠKvt ,/X%H&nk0EmHw8ZOdn>nQ.Iq-3*y_3'UoFQ'w`NfsNGPƇ!I 1'u֎B,NkQ@ |-aP f -Nh.b*EXfkU;INv1( ʫ~fpR:&)ڍ9J5}>InfxGy1w{*yߊ5D 씭NLmBG?6 wpB?NTbcF*y3'78ABf>zsá&7>⪲8("N3`ts}g:݉N\nқ)jl2mԑyݗ4լYI^Fh6خ5_!+njcѬ;wCw*I ;h=,\:N" 1WnVu h$MG#CY߁rߪ\KkyvVxEiUW4O`s N!yq|͜Yh:CH" F+תrrI`qn_7q+v"Ӥq]\Qa҈ٽCc [;j/?Nbzsos[eGA/&v֖cJ_ȽTʙ/YY2XOmEi `CbDA=j^R!.ijDž,.%iGImt󊜞h^Zݏ+ia2^ҒC8YmљКg.:-7/L:hvˇ#BcP| }(Qg;P]?WYY"BxʚˮEדagZLj2Cv+*Sjwcey^0ކNV 4rZ{IPL*P dep,Bp\{Q ]!})ODznݜ׭p[֏"H坦&`r8olӺP#YZYmw c` ![$p# ,_XYmG`M e\ၕIаt.>8[C/3-UԚ$ ̙ec6e:H# }',:EЬhOH #p"RľJ{KH`(? {4f12\m,Wuxu=X:E$DS|:#Z*/c< aQ_ϙOr1REd7ߑċ}+_ιj/]`|v.k`?}  ߜ| K.cr*:,Ʌ/=.*V\@Ow([&$:b6PS8fx9W]36VRի_Mv }+%50ԝgW1LS*˹? ?e5[=ވ, H37mn[|e w_j|qD\yoLC±bJsiUADTesm==rHN& _"'0`1td#'@An<rUS도%^u>3|q2Q&?A ӂZRrj8D$o l,̆sNZ?GӯY/o` V:t*Z2a5 d*,IZ݃QLiM9tL3iomȟ]Cxa\z~yԳJ "'w|S^TϠsPHԯd_?8Bm]N#w;2Q]0Y]nd=׊̑̐y2 .qz&Uhyu'ٷn:ى^2.;zWZp[ۿdMJMd= f9v ,pEOb9U&S}$_d\Q )Jl <-X$ؖPooYI{iS#}Jk1mx CFT+A8Qd`f)#+:vm+0DN_}Ir."r# 饋:p>9Βd{4=Y)#z*V][aԆNy΃8/cShI0@Cܹ`:Q՜o鰒2seԃ'lBX`r,XV8>KAۢ-?Gª¦å3]Rg =찅<<85ٌ.}SȹVgN3 V8i{8We ϚBt~sG ӓ c+v;~fnYW u)׵ZAh{+i@0̺RrS c[Յ=”"bM5JܵH1 +g.ܟ376ta7b+ZS* }P`׌k\􏦰0rd@~P+e|X&ѕQ7VGp8Lb}wJ2%UL (mcOfǩlC싴EtAB(^ 1kNtq%T雖1oMK¤lAزzSd`i;*yPR*Δu%,g;= ^]Frux  H)3&tX_ $W=,8 U*s:u?WdH;XD. Tx<tt?ރh*C+Q?֩h,.[Lyx EeaA(. pD;,S@4߲ r@M)5*Γ̥zisɑFe{]SRymA%#Ls&eB49y؀ԾOh>Gs6쿥Nņ 'Iv h0$g7/&8ftdP_ӭؾE_UMsHx=:&<"L*nH++zQsVn3ӣNMSɉa@gۚ73#g\X5?#9N<-Ţԫ@qP;FsI4pfl02AsK׿ 0d0@S1LO=Gxh_L@y:#B|/q%956KеD77  9$`ݮ1H@"%qAw 8%5e{R=m6)2H!ljew0wCx.u,1h2AT[R&XrQsdL;w=1M+} skj|dIH}ٌ >rN+4珺X%uȷ>rf|g$Ԩ*`WvB)E,a{%SIMʸ@;u]nD|J6&"cuG9yp:LB @$@*]3v_chS։^ؖgU/uQbg/gS_֥*_N?M\eBn ڤ+qHdhmAj樨L MEOO[}ۙ.GiЩDõʌ$ P"q:f0]Ӊz›\Hkx`T M}EJ5IIפ5'7K 9My'V4gl$pMETyp"+M EMqߥ P]i~#l kDߏ_"-K^CxBVQ ,$4eGbna-bs.(sc7f3ǯ[|֢TyOIwA+)Q:cX =3o`;$6Nz?{k ۃhK.b;1Ҧcml ՟0CϖSd*W(Wz匩ka+ZɀKtJs܋N8!)FjP]RmLKI#=ttI{`ȳ( 4"'{ 75+ә áshs29uhpBДv^so↱^|P nH0ݪЀKe8L)T'rvQsj~ 2)c /#Hk.~%qil&.__(%Qf]Jp29>eJG$A1&\3A tgCz,moǼ z bTY%~.iPz8f__kLٍA׷Czsb'*nj.ۍň5[*"SdntYJ^IZ&А }iO{FͰ6[|~\tY%," ކN|Ln΀|Mvk[R< I98ؤ3҈ Z^?ZgAu _،v@۸>Q'Ԙ.*DW<);*m|R#[$kT'`~L|Yi) Ⱥ9<@m5 dEz׿~M m":ΣN r5&ǟKRcxxbZ7\9"ZW@9V_b t|gȢb9؝8h@^TZO n3s1Q`~+AJ#gAny\:sw\al݉VD kAcjX@Kle)֤| :SHi?ǞJ{|TU+x d8 <]+d ~qUvǫ<3fi &.݀y;LTXg81x\bQ#GEY l|EX+ýp5݁k=<&mpqloüuV8#9v?`o1I{˟Bã㻴F~}PqP!&H3#ϝ=zP%"ߜFlTRTRɲs*<b}F[۬zfvU9]dM0>4?T zq ty1aك {`& ZDVP\hMDs;gY,; t?WL~wy9R tl̴veTR\+y Hn|hߍLxDqC^W4""T?Lzw515]nA978kL 4y\٤a]qj9$:UI;siG[8fV9 pe3s>-k&l nTê+Eek3, &]OTPnFCljMnZ4y43F <*S.e솳.=ٱ8:Rq|4le Xe cfp0&USRS$0`6e~^WpqP.܁5q dӸo{SfPFQ`b~uW* Ҳ4K0k,rQ sGb\T';2:͛՟fǕy*cϻ'i[L}x߬gA\ܳi?[:wH*@J5յvN3=\s?v?\= ^Hy;gO721zyxOEHK6z Z6aTdAۼvgp~d[%UdSe^# $Yu9@/?Q3&̇r2;۔,z|$Ql0:!h*ˁ=xX\oؕ  ,ْ/$V" "wFQe9cXJs;3Weio҅lHXw>C%q? B! ~$@h, d;`Ro)$sLl >>˅F%wfcikHǹ?,p/6"FA9pT4J{|,UśY M_j.,Į5(DU: =@Ȃ cӐ*wW_ uJdUft= WJ"$5B7:/C6 g1g_2VblnY 3Ɋo>jfx)|ἫՈn#^DyCgcyt7AR !z!e(L=6/ڴ 6=ˁ ]0|h_8?Ŀ)rU΍yo5tS1b vr\PѐoSh{|H7e"G͕]kMzEI}5Q _ׄE ݷ @dgxqWV4L)z)Xk1?}Ld׈/H=8N,k2&-]v=pYxD 5wsjZ2 tRU9*55kzMhK?\q <;:g >"U<ޠ*j:gw \ܤ݈H>l8FC4.vUb_+"T Ҭ?[qFT0ioMT{+쫷Q C/h 3&2ҿ3 SrhfQWGd<{~Mmw^WxO?C҇bD,럆vc0H>i{0J1n"ho5#( Le8[N왡Ol/jE@y=͘ p|aG jBy " ׎ȴ,0v_7e.p3|iu)hMӸ [̙j2J|t:vKg9G8?uGdY3F.ç+ +Ø^wk.X*ψ_ 98;Op 5%}v Tŗuy}+z*3iBAXᘓKwL(E0AWUFd7V.QxTFR&8NE=^5.Ʊ˖c$\ m$s~%@va%B-V>e~!Y -]+ ixZj jɩQQ#n} r)( ຶ :Mc ~B'nG那귶,T`I% Q: =Ja}LxU+ ϝ4/OVZ|J ,_4geg\龧ސ懀^ʍ?&D,c~zaE΋x\rw$݅(A) shCzp.f k"WJb/GCE,G:Fsp˹/В#7H-Ѩjkq}[798Cu]7p vEfB}߁'= ֭;cT]7m~H\TUm!Mql-Ƹ9VҨ\8aǞ 1Dk[oYdrEǴY*^ Ǧ @WW&2h/,BcYDTa2mw˜Gj89 3r)h(b,$w(97`a-* |9#q";sp WZ) 2b|鶲1 ]Cd8U+ZS~@Vsr~:Tlv5-+ sl2t4J w{]F\.rǑ ySÓVV J԰oil+`@ޡ\ndp EdjA(!@r(2ZxJĻz2!,"֩rϾfF$'rQud qpڰV 4|ikMp۪&f魉[<#HIeN]qNjoQ"(Ie ! C#uH\/O3voR2&:Z6`Jcevkbk`(# OV(gk eA6  $Z}#r/Ɍw [6. alpCP{^$)$n*؈{ s*cƷ4!Bt2!1HxHg:z28JJғ>=nOG 1ŹdӦs2A|8/_}81XΦ@/Mq{=:|#Q9kgGo 4'& gaS)xdhMrgĸti422f!ER<%]Ra} !ЏXh7 |=w16*pZغQ X!U+iQ@D5t'\|޳)9Rɴ)"//Nq 4&έR5o.,|8r<^vakэӶ3BNh@u9$r/>xd raN9+b,;l7ǜ\ ;̿A ]SJ-y,xUk WXjEt._{ap7؉.ƥm܈%f#@:$M': "$&"D<4 +@Z84偖ޅLiF$,20t|)r`TfNtb^ ڭvhRbFh1_j3H3-Ii,)cl!η'gb~Xr`Z7-PCp&;0=*4N?I&+fTbHU˨{ QVh@,¡pqsMU61xC#&/nZL=x4 A\/t㿍W<CM߀sbr~s gM[㥠ԸrDs)W\:j,RKJk)5abvcl>1=si R8:l%5YQKNB^{v?O# $}D~Pq:Esa- ?&1uBʹϬ]$ `4p|#P}HsKMl`-`}km( cRKHuFh.d{x>84d"x>c87_̖ 1U;@m\m:J]vMyZAHaO> ;KqT&C/䘂f#98 Fŝ &$pdm௳cq` `--#`kOz'NZs7wtDU^p[=(k-Ql1X F kK=-Q<`32xTd] -6fR3nvs!x)!.Ej[߫B m`{iNpȜ}!FX~jԦ넓oP($*S,U1>f Y'qJ/BLUI&T}uCOħ{ܳ/DF>^F+Q :vzU!$ >/flFOB#y^.*eZkH%X,Y @  #MfJ?"'Q, )'>RiivnK׶Ж!3Aٳ;0Eßk L9aIBOU\q3\_㱚g1󁚢*PR3&Ysx@QI'⪹وvGjݭ桤JC2.,;;-5uCC"˘X(V]@tR:md&ϲd $KGA_;f]vKݽhP">8̶/iet)> JGkHTG#o~e00k wl$9ZYoyaz`T-:d ٬ǂ]z.[ﱚs:MXwpBoSJ i H]ds ~b򍨒β)u\%Z/1t~-{6P3f)&0>b NEJc{hZy'wӦ38bsW}1sO(45ڰ2W:ǹ=Y}BODp3&<N|CBI'nyԻn'@w h| pRXYfpԶƐQP,k\",hbHn !l23 ]a0[鱿w`~+64 gA 3 ˺}=X0|mu؊@M.F6V )?ҭQHz82;KyL6.h[_9o ztYUt矝[NhMEW@$Æ˂7j_eCB*8  +%qM!qN G.vU |520S%ٜ_ ] Q(7Ih?22ّxFZ.]AedjƦƃr'!+Y}wotkpꝴHyH$hU6InΚHauA20s M{ǖZ.yi-FhRlColl]o`T9>i#4zdz$ Hf~^!A KJj}yIokҏqB5pHk|\+3&A [btԀk60o&IMWў/2)+g-g oD3 >4[[_$_OE /#K} rt8ӭfYa 8)*jTsME;tPXkδ2"߀.\hHZUBP)[bz; ":㉰nn5׼-]O]Ihbu԰&茳E~y<'ːRXgƮ\>c 'A4r$oTuF#{zb8%W2Ђ_&Z  ף T`n$ Za*~3n, u "~73Z4jEE$rXni>o~,.7߉:E2Ln\.ɤ}PR (&1Ӝ".QD'@uU/sz.OFfprpUdM2;MtrA|qP *v=f.Mo5ji Y*9-b בIލˉ \!@oe!4"`_..An^'t(냩$?|mU&DLДJ8fMDKZ>$jȕI0QEaUF أ3ǟ"R W"r Trgek n߾|ڢEk1C^#~08$m@h儲m{KVTRi.->#[LN};)_]-s#Pb}sqpd# yq\(o#$ı|0*PȔ b{2ӇPtva$ a%8X&}a_:.j@|;:Vq]V159%t' LRb'd&O@l`|֟'7Fwɧ"vaF)oZ&!دߦ.^h/+RQdL-'GfdԒHƿО .ZO Yֵ@U%hIHv7ac>Bue9-t􅜧V-E.ߝ/Utu,mOhd1 a7saT-L%b@slqgѷ2ËnlkP'8/ =p]JILc{s˦3{( jĭ8Ř#Fx~=AGѭ&}?}Q$_+?" 7Hhykl{T, 3)': Ln(JEIHKdɭZPX1r$Qʟ>τHr ԍ  *x/ 91pңl*(Ք_ Dws?' z2S1o տy1[V?{-Wf #)ɳ84a1NO XXߩUgcvO6\D jFx.8LA|wd/geA1i|JZQcȑ6j`'aCFϝ5Yte|PiW}2~% uzSި6Hzŀ!(=8Yah8L f[(i !6,_ - nB*Z*|YzB){Ȝ+J=PCX-}fwA11"t4yk.)&H_B}s;ŨA|ku-eTg[XEnrD aIOTq$-X9thIfVMo2Uk%jɭE70i6bkJ:O)D Vt:F}eEW ^ɞ6ogEk}a]9&>K&i#b3$,Myg zd̡1 Rc{46RN35 ٴ׌Mb4gaW](^td`P%;oߛ2U޹}l8!`<y2G}Wj ȶem0wĆLV edC *W^zuŏOorR hfqTUݴSGǃ|( :STrp{;V -#y:Y|VϮT||^n|aٔ$u $T=ě`ojdqv.ol$ȿ`hZJCdx ϡךDd(QbI>QM?͒O |dj\&g腨&?tPl̛IFx7%L{!^X!M)eOӇ@xX߁@ }&=;!p+D݁=f݋e*=w"Gl'N+"N~7ռXSf2!cfqgAG!VX h^ʧ- MO :^e,湢v`{>UV@o<BBZr/KBˑ< ۵l>?.I7SϞ$>)XƙsӘS%o Cн@S%5cM-MR--Jʪ-|ܱ6-S X. u,u5rjiQ)9cz4nJ{/XilW]2I '$~JS|1dvc1aOX`jy)Vi3FϜl6*^ B?`Hz%:UpzK0Qnzk5nvs0Dn04lTO:ɐőSbAٮ"?ĻK0(c '\&K h $ϳ%+=J;arF/!,v/}';8Щ;cI@7:qi9\|:]yO,1&#&[#Ͳ9K?ҹK~$E0-^*NaJ=6քygɉoQ/uDTI蒲е;{pB66?HSJ26BtF `](~i-J@/4 %j BD؍ʣF$>Q4u_\yTD?/oU~X%~oDE3Evy7&*P( g rJSΩB|3bxm ;`GϘgy"(*#2C#FNKTߔP'ٙ!Aט܈Ud oy=G\!jMmj醎NS(T:PZG$gxbK{Էqt ufV N T"SW۠ ߙ,IU(lL8vnOR& ],2&rgl-{]HF>׹TQ̄[ UmXx=&j7ގ,L5ZhDhvSt^=0>byHS/ D4=m(X*IY$rL@ ^F*_);a|Pa誽1 ޘ":V^׀a QERn|?s3iX\Jrѡv`6tw&1H!\-4=ؙ_WC Hc'UZ,TP[Y7u0?$Lj3c]Hi#{>VtH`蚒2֫OR.ZP/<&vIzoDoQd3}jڪQZuzrUR'lssIjx?=|JI=@CBVF7stR) k{fRkFM-*e#<~D#VʂX罺@s`z`U+Ù;+ǧ|*5^ʼnU=8ؾ!"u^Mw%<@̡|{Mg%3XY}pEHyLa$B@ *?}E[#q^i^xSPv n K}jESd9| +oSH\(Mu̒PaeA/FJ㉪h:|D$!*7g>bm#nT>j?s6jGϮmx2.p$rtYWhaZ 4=ua2th_z5Iter6d=^x^aJJ1##->fX&xɰ- Qٝ8%HQx5UͭF4e,.n[^W @Z^64퉬D}s$ %Q)l CP>ABv`=\FlȫCBkKV^*U +/Pdoɗ!5u/Pq,=yNN-tȸ^OwU|Ֆd(. ;40(O3|+ RElPt+/p6xRqxx-QZRa<2}Rc}jk3DK08st,DEvRq8ڤ10`Q9JiRfYy͙( EnkR[Ḹ rHs?>EiIqj\*B3ua9 ^'RnulNO|v.)4Pu\qpdC_Hzܘǎ,,Nj5s @ :9dogV:WpIZ6:P?a 8A \;ͤDXYHZÚͼD9MvnαEae-֭N*&݀םvD"X VΈ C/~X_gurܬM|LFD5onm <KS7^Z!LO]JMPa5&f6IoI$)$o/ :zETǚ rW ujq{Y1Z$|[B{=ZIMPz}V6;FJ>i(@m ؘ Khk @{+1?5ކZWaTBש]ܭujqvEi$!ϔAkE-kXz1\pؘ}B|NM>la|I Ac.m%SA4=vą{w}Ŷ2Y.ղ}4ޥsKգI_OQ.vg_ E §E:ʄZ,B|IpwND;&sEʸȊ ^e\) B#3 FUB5Y81]Lٕx0bUU$ ē3$ˤH  <өCve*s?OR8a^ ]Cـg#ȁP ܣ̻ѕS/,^ʖ΃t~}^nVgB-09uY5 >/،\(Y{s1Ab1.OBBX7ZIحȃnު> "~{'HCB>&`! mp%_$x&32F[Y"?R-E1ԛ 2QEeX365e ƖAaz-2\::c)\E""mw2###=J ְ\aLF~ɘf8&&􁧳=rП4o׌ aMUэHptL5— BTJ-yo\hݓw7D0 E.p<8OHxc4HLfYWXp^|(FS}錗7f.ӻ89V~5RK#PyIrA-A0-!]e!ѩ]c6&'8G#HL FR.2  `WG+,qiѸ}~oIY_"6Y*nlA!Fb`mY}g.{U~yަxL976g-Eք;Dp!}56a&\gړ!aLm eHV.+rx!_n4srdbY 'oh|!_v,7#l"5J0T1$.?GZV 8a/Ԩ1y[?h#T?`zP2@84/)ZB Dd e2.YaՉ_dl@%DaxGΓ$` PE~ƆWBqmrg!p$ɖvf^Mrnn k%Aŋ[}f@=ڮXS=ҟᙱ3v''}{=zoMoXQ4JyڋE/}{ "qZ39xAa,+ёr L1\&U8@7~(8 1#-/ Ho\x9l,1'kAJy'ڽ?^ݮ/TZgͺ#OӪͤւkƇOVK/w{ :]c01 uӎB VaL715Afa Uf[(|gNPηUxxΠ1xnͼ`8[dꜩ6wxulIaǵLMuON>Zno =:FR\,ɸ^s6pr Ú@YAj;Y\1uW05䜮{},ZL,m*Mͤ`Sg u Hק ~E(ElM~L4Z O9WR2/՝.?Z+Mah/e<%!lE%$dPظj4W;uҙ"рhŶMpp3NK~q /"ZE+W)&vy:y*U1C1=oYxyd;^ٸ [*}v Ww? 1]5F FvWM<.4"\ |,umv *).KfbYj4lݪfdX975(A3OPr2KM`߁n-1aN.4|/O{!'y#lA2*+ww"X&ts(ٴ(Fu|8\^+T4M[@1CHyF,PxlgUi8CCҘeh׹ߧO}O&[kCuW 2(x0'N<%kRWZB dPQ?ia4ByۗFUy(9U#@]R 1?׹yf0K5kTl#вMz;{i4ΟE+C^N&]seȓI 70`߬AxyKg۱g84_c@keŹaT:UKpb9Ӈ6nSb|Y/nٗ\~H$}'%Vΰ;,/># ^QkXfix]2Ced* 0p&khe'6b,4<HPBLxոfRUǦ8\;NDJK X* \+-qSёO}-ol  UE-NAa߹`G4JrGY5xgAmncgPeeЊTG 2OGr55dk[(A/?U2@㲄p㾩 ﻸҷm4\Nξ5AUۄgR`nix9qXf>"yNAmҜ^is ?5_$h/ 5fִgϩ6&`f/vdko@js&4Vӂz9ފ*{Pu4 ּN&-|7$]ԁFHaxڋZ EX9`g6Ӎ}%i6T퀏TaYJ'Krm)'{Ir\O09&x0A:ѿ~KY4۔Ne'gۡ4{m?ZZl[g-d%e-9,xF6k&PgxfydB\i-S<0?bZ Y6p .څA ]|$|p6 pAs+ItV5Z܍M!=JH~Hn Oj7UJԴЄ2I9j*ywȇdU3Nw bVZO5ЍiUd?lƅBmi~4R8ed <:=eBF\M*< ¿1"2(Q#uc IF}ac>|,^P?9|?E;؜D kK;UM9;)QGY$J$ EorM2f>GɠdV|Х <3Bf?°* U8*5-m]:ÔqK`}pmT  lZir'gڿδ[{/lKql3x*+y~a}0,얄;y-v$̢`XK e9^qCy '}kӜٽ3r0>!-PTek u;vV~WٵgPspN@nXzE&$-v_0p2O\y( nM>p5JHyZ)f.gghtJa[L#Kf ;SoeKc?Inam :uƛ|zhIco,X]/Sj>LD!uM. Idz(L;ihS2B&d,"2l&q*T6:7Kk`d-YKdQѮ"$CIپq~$z K]xoo2f|qdH Cc j#xF*z; aw@dťMi1 `vnk<䃴ʳ)PߙqV϶X%W?KI+;䍌J&eېfwܭƮZA 73Ӊ l,(~c :r:ؗ8&ӱ׬0t^hxW,HOvn]SwhW#i9m&H)% 1'Eۋs eh"3 ҽ0Ã`AI};yc:~ȉJuيoQUdb `7Thg1"u-LJ9VzMqTe --J㠓[&C)fqaaa8lU,av_rQiTrFjE9lcwAD;2?KlxN+\:)λȍ|b."z4~>~mt*rٷXbfH"#`oۭ@|,͏2K@r%cZSkBTPYf~vqf~uFϡ' *JWy T+w+C\\4b̅qgͿsԗ're ;Jo";g푯E|nݘ iv?tgtD6X_{I\i<mdߏtGmOM54DVxcHc>eyOG~E-6"30.fbAkZ&̹QXw 4ĶfT |i'A{1)J3Ơ#dawkBPXLZ. zNY:U&i#׸ty_1-HeB9XH;Ҝ^>Mfwf.kc0+ (ӓ #п2Xf*!8WBҾؐ:,儍KW_ vl pz 5P@r{CL}KUnx,)QdP"(We~g09kLԱu )b tq%Gα󾏤> x5`x6`AD~/q&<bdwΖۑ'KnI.P q!̢*L0x]8=P;#_@cE&QRU -kఉa"*Fa5noq J &"nkn`/x.mnU1$)KXCu#z(jO]<ZPhmIr!a. |Ұn(z˲e_RaȚ[B[BQwLn!-9g؜;:vB)a i>l6K_NA5Zۨ%SKӡuOC8m)yg馘f+&]HVFq%@:2F\gdz|H]H.M41%ο@i2ttEkQOU?'r0Mq+=h+@KsgG=Gm2q;> N|jĭ'!2!OAY{Ve@ʽZyMy 2Zg2&svZqj;SSU'J?fI~l@]=y ?Hmx= =86~u-?r6*7a!!,QwM̴qa5'Lc-u< 5%k9d|aMB?h=NrzG d!? ;T䇘ؘ.z"e϶| /lS ~p>GVH^]Ngb}(FnW]d oX O,HB_|6Q44y;=⭄/j|mͯXMP܍my lW?7Gc;5TT uyC_"cMIHRp;o{(oS:$r޳~@DL oN_b3 I3%E㐚9oȅR=te`6>D K &ԚHz9hM[>}1eM5WC ܿxXF!{c?%_jφNgL$jӢ2V#5w:,ohɺ,w&AHՐI Z, 2k}2Bm '~ZK.ҁY_2qz$G/vwHpa5-W1vf[1BJ`ncv?"8Fd [r-ua/6xnZ3dqƤ+B8ݬrM["1?Q+ oUWNWn*i[dy?0>+š]=xoͫ $+k  skԕecd^n'oUZ>{G/ joQ9N3Rg,nvydE@yƌBdEDgT^Di@jl 09Q`:)U)5+&AAMV50T/aY/L_ {|m 2ܿ7(vqP7%WHF ?X䌂VΚQl}ʡcxքM+U3o?QmNVnr32&A-lBMPGJԷNXm_.@5Jk3lq #&VV> \\yMu7S]t|sI t2d4Ju[] %䱌xPa9=Kѻ^ mVfg!/JeQoWƫe=!h-ˍvc)655-Yu~^? ۬:REkEapX'yrs.,89o>ϻ"[q<:cDU[I~^=ӪvJRHx+5ϕ̼p LjX3'dgz;t^@Ͻ%s>$f5aEK w U7Ƿg= [<7ؤB́&[AȩW!79!Jl 4'e#&;_zkTNKd*vJDjb*%mT*RoY 1}T #>ECK qdoUJ} HD?9I?'^>z JUvltdnU4!ST&n} _ܙ6h;N 8(sl/{(! u}R,xo$6bdU"56 ƳZ;b^'c5mKZp1h~2G>Do/TS!`|E $yuyʓ#Sճ5-d=c+rP- >2yf"VxmU(Jby=_ |#[Ͻ9u2P"ev`*q /rbr&*]IRCç bqY3{P>b3gy{z+f'5S^+̪e6Wѫ7 )W5s6V8^?ۯD ijyt!JN U n5vc}٭8!Z HV` 7̥3'g/6hj0sE37hn9WP7f?gPm~JXv~&0=ޛ(=cks*l 5{V=Mcdnƺ3r(O&^T9qI,_ױ!†Ĉq/h>DBCIwcERU vAdpf$hnPl2T2s]?Nt ob:O8Z]1GMjz\CEBY\N0Nuˑ P :^;E Th(֠QϩIz`9qsyKc d eK|L7y!]qOf± WD\ 1@3()ĞmW΋c9tަ'f4JM;lᴂgK+lIFJ' ~b= @$](2(&"[}>ݝg ]{_2jRLj;b)t ~14岭 GN {W}Tm6f%UlЪJy4,& ХnI*>WgբrNCߓ dMWSJŞFJa9y[gP cNo:o4V?;Csӊ1+u/(]k[4CeD^ê# LY7u:RZLGiYH_\fJD>cAgtY_1*$Zu'xY q]a,w{|T$Ӡl71%Dh`QIS&5ComVp D,O(rufP)/[C='yޕQ~dgO3gU\@4XN[㿜,eF~EÓڜh{Dd@7RN TY߃"R|w`!/=@d/eى"m1fPr\iQ_<~Dp|[:ML?MEe{th֧⧥ (F$zxt4h]e0n U蟋Tv?,W $}4P+xDޫNsi|Lsc6⹋/j1SѶ%͚;Tl\"} M?<Z7I ك(zyUp i#/R sז~2$+ EQ#W[eY_cǐ E("4-i5gGGYmxD`lvȵoPְ5-2[.l@GJ Mc5S@8xPSpshuN>^*FTa9_r#Nkv#oЕoJ>zNq 1!/5>.3e`6/+\OHbu>?أ^'֠MsMl;"Jc!\VRcyR0<.>wpǁćٙXJbpa8ڊVo3m[E(X1L=U/"dc\R4'3qk}psX{>#cgf$ T p\鲍mJeOF>2(fqQwsKz~lzct_<Q29Z gɜ JCg 6&qrv؏Lǵ!۱TkEBދ]RV+CNK5֐(ޞroV_gwp@cpܚ>yšo,ӴCܥC*, 2C?ie%3)uC#Qr@9ԞIadcٌGd'ƆPyXpL>/\2Iyִ?zQ׉@9G@֨mRlO(^4*kx*"RB쬞+ ޹[ P"X yCHsOVN'#v5t7jsLZSӉ4(UztgA$K`LD8<|w٭w1ԥ/DK`f~L,o\\t@FjzoAU@i>'Oabj2祧ۿb2v8.X0st&Z9|D܉#kɫcP$P>'{*cEKG~uL遾Y\S3Iz[ٿYҽs)}4s25ɺ_:=,E}d&cc竼[7*"ĭ/hM/~R,3\ *-L})ZdRћ*r LniDut5^_nB ]s>E*O-Du\ö/-&Y9/6BG;+O笥Rl(A"SO.]r68-eeoR!}ܡq>B@@y:!-6#6>4hsSJ9*j+vtO\5VFr#.?{P\M8_tV,ԐE~ b-τ z;[xu: Na:ė@SAʽFy0& ?C bWȧBuɯ9nѼ#^ ^˜ ,=#g>=`ה+aVUs\9ɸU1̽1UAp ԛ[J>hm(> H (SjdW9-8NSUKK_}ӄj3i9n>p(_n/˦h 2Ws3 y}/,(d<(<ճqdٱ:wz1)j5)ݡ=4أ6EEאa-J3OL <\ 1jP}!NVǯ5>Oi\d/pv?SA>FZ Lۜ;eLuq24‘YCKZ WLFbՃкLfK'ɆOo-guZ."+CɴN#FM)a</0k$~ dy6"; F428=oZ ?vG?/nZۻt '|zɎ Y{l %ؙ9N-1)-FFA i#e'&d uKdm1ڝO͌VǼ#J:ʃ~$ŵOwPeb8+B+WWi<),DGQ}!m$uhq)~V`of(V` (<&hI?ŕ%kgN^L]J#Qɪk9ל4&/o0HD~kv=HՈ'^r1d2BfO$Z^V./ DLkbxe/F$YR+Ă/ .N}\ǧԉڻiS܌$'o %«MR(--+ZSOnByYh&W1~ :yR 6Ly,I9{G wf_ ߉庙y6fHsjZq{ϰ^܄,rqV:=;e8+ErN *:x=m4!]Zʋ::9ЯR*0vYQ+VK5;Z˵3@ŴAN@Ӝ9K7NW{wuث©:zadGEggd^4U8+ ()~8P\#v'AJ׮&xoEt 6wn9 i&N},4r cXy7(Jn ԧ*TAu !}]ϣ(4(}?aP Rٰ+Mdi 1v]zO_x*y1UIv'b>9J&V&cG*"X(gy~ԗ*W*VTG }he`]*a t`ݪ3AfM>5sH (b}Ve~,]Z&o+H(918A-ձ3UMӘMc^$FѤ *?r&A0\ĂP^X~AbW~PA nZof qUэso/*̻"caߔTRgڻTlhKN 1DŽ)M0Qi o1;*mjappc/™hj脓ZQ_?T+tiV ww: j-꭬~* /K\iT) ܑ!7]\{T<\(,|E47򘎺}dU5*_rAgX|kz-pꁻ y?b"r{>-#%[+0׫r5x̞ɖWN\^0Po t!u)"VTcc!N̓ȷ'J-cCRzKMK8J x١2bH3[܃H=MN&VPƥX:QBnӱÜ 唕dX W.th8zpv͆\|)G鈬sy *[80g+][Q1gļە LL?6گsLP;$ށጨ'NSPL/y'ml/ ҈‰E(69̂i>${a-J0 x׺ɓnsAgej)88#Ksb!R/sAx Ձs @օص+MsEp,ٿwo޸I5ttDZ9Zq/G[gsh̲ѹ'3=-'?LYF`DOd~UUq4|D2ЍfFz%wrqM3L){,[OѲO^q5zӦԄ(IƳ⮌̻&Pg:xLhA ;oW)>yV^-Q4`tMESF==PEa|mED.`ힱwLQ<ˋmVɮv0Xa>-@Gok# x ]8=#VyԀr`Hge.#.XDIKusj1 ] <2G}l9RDh̛%9Ǒ[~%qO\[G Mh^5x*oÃd9KK{܀\Os|D 'p (~&V_R]ḷ]E!>7@ \L۶ ҋnD^DuԽ[bTIŪʘ.ec, IiV^@3r7'COD<j^(RVm@?.mޅM:(&[>3.mqtV3x< !+H,b);IAgdz0ꗚH㼍?RhBHtV^<  *o%10H!ʐQOuj.`G60 ة>.4@GxR|E 8c$A&1XZo8TH> }0SCwԨ?aym>XN@I>pS੪Gc4^PF. *QrVx/ӭtLLTH d%], OܽxaioQ_}N27Uqrm)AF/URHxiСgo$S{kAX(7N*Z~pZI18ɀU!(7 %tPڃP?',?Zo_k hVPV ZC0C pEt(.ۭiJ1Pƀꇥ@ Ef/% d)jG\;,o$_a"f>JndK |^|_~NTV'*TMQ XnTKo%TD:Է zCY>  Uj,|iF[6@:BƛZ+kٹ"ЀYPD`BHZ\0;ƴv2h16+C4հ)$sՆ_:6o}L߫ޮ]|RBcYPOJ!.l.l1 ݄zc#@S2_zF_Mt`> КZآL7 PNv_.eĄ %olL\p`/h?#"7E;!$V+DK/qJR2WO''Xnmbxb QyTJ3Ȓ@8 q !zt%+=`:#*'LLۖv NLg=5kZZ:rtʅZ $ 3=YYNq v(VBͤPWD?^ɀܲn9N `GMσc>L|FqlI'kz1uZ|TKLұok=_fO'uvJ{MtY6u 6#8Œm~WC5 , 6^Fѷ7"V I6CSn,Ҿ2J\_j$3BXNa7QX2EkR:h]AbfAl $c,1rq4" BukbH KӚBIe%UM]kP Tqxo*ҽ=Ԉ%ZEcO>EQ׏o7VEY$ B }o 50,n}͉NqdIKHp%1>;?3bY םˤig. Gt&hM!JG(s4:B ?#+@~ ; e|]΂tޅXnbVIAy_ ~L湵KnJ@#[-{"GR.IL`wmgē8̚:c1T4rP^gr"g|ASKRz0poRAi?WT닒Nk,$8J'V<{?,ﺰ"`N/>B%Vh94h& 銹 ȭ65@l"P l(24\,yl&Q`j9<:w0bSft-̀h#;2׃gP}-!19#ڲVe8xlY. beS9OyISLX-)jItÕЅt}FϡD< f傔H^0#˭$ӰIJ[:{kt!&^jjͨv<DBLg#2yJRff)85 VpV`I#EK`T=uƥgI.|/[L(}oKG]4SuqOGIPڑU A-MqL{r35a?RX/Y6w4j}1U'c\`,dX55# FH+U[8,rO^)_WS+z bBJL]'hɖ,b%V{H62 |C 5fƃ䄭u91%WC6J#B4rλʷtW?z% VF\WRkũՈJ8g=N$iedR?~AÒmV-ju&zy[IUʎ3Y"Pqadحyަ}U0YDYjՕ"t[4UՒ½5>ڒ,|Vu^.I5˫.*tɏSԞ)c!F; E;( 4ѳ#dPDz-'7²DAYc2_J$V4[@kZ`/[A9QC*VpYM4 pWF%-<~_w/=x̘9]{Mp-]hqGxP|-g̮EdK3L8ς@l#U}0z6oi5vy2>. tmi7K V8VA_:t}|4v&إ-\)U 6+lO=uOg2O4'pm-KooE&P\8'\U:J+ow~ U/'7[fwEZFEOEg"ܬXvp/jRbšr\6Zfʞ\ K`nW9|7,}HrSD|'jK)6lCq7*¼ 4 ="C9@$!lx9b17c$ƇATϗu((q')Dayq b큍j.Ƭ$J i\"~T\H#ƢBx"JZs6h08>G)~ 8Dlo J1wfR%4[-?DX:;PЂ [)D89@ĉ"s4sĺ`x2UɥAzUXcZ۔.Z/Y4|.0n!dL!H)s-yJ̩6ҡ `p2`UŜC;^,9b"8Eր^p>zN{ߖЅXH_[ɬLQ>_鈒 dvs.±[8g'g梐\aJ F6~piY8er <*ևՊUOx  { JSN2C)5dJ0 Fo cҵRsUx5GHD[=dM[@}}j|,EJf[ϔ~˻Mb~n~C{̅ȗjjMtV}NOfRkv**epڑvvn)HтiPX&I153綯R8}k͸to6Cwn9tBGrQU3L6 ,.KkF;K44U&uS7ugY[WJs eAy F t$] H&|w=589^VZ竲ȷRpn^$,k=9zkUl^r>I_ !1Uffo[TIZ' AO^i kU:iuKj)4c9;<߫(G?ҕO'0a*"f|~?>`r( s8 ~M m:)Srf̥ydJ> R3!؅ddeOb-c v!fx׆nOosE&F#.]& /]h~1WtCy8K"Dque;lr^ ғ$sh5\O /ME,BDymhĘ| &'ku)d/de"~q/T;7q_#4J=_g .hGq;#P L>[F@cn&I.c3hQ|\ fK4%eN9ӍJT}b[HM^ǟDSB·b~a%Aqy^|Ԧ&wp `;wz xlS_.$ќ|qaP |t{9}<L O=#/3>R1 J6=V4G*o@'+ۇ" @PR`zR5{]6]]VnJ`Hӄ!"jl%I>U.;B"8okBkn'p6I_^Wa! ?LQ8h'8Nl<Eꏘ}'t"+m8&Y;pIryuY5)a.7yQ @6$nZY&pA/0> &dKÒ@ 8,tn:c%.fܾCrF#\;ˍ'`p n2%s.t?wep"?O2f${$R~I2>]򳌂#P! A88-> Q-L sV`p_IbZ>kF;F F>kD$bݵK>vV%?`ǥ[oq:M[Fӓ"{.]|hAt]ȳld"J\`ۘ8O*7Gі'{ !+xY[-nڻ_OGEsp 8bo8ՐiK)D.2\# Υe<'/hfS{0/3ɍb׉fn ol*l G]4CmN@q%H$y+5NHxv#Ln?WS[9~֚gw uU2&6iʩyg40ߧLy[c+Jc$,tI/zt t{owST^44yZ ȚaITAd-H덌j"_kA޺mju$]rLXϤ_[KB/HZ0[xYjRL?zv?Y{<YXt>v|ѐ(,(l94A]Ӭ)n76Y:1U㕇eQ }z%Y\/7c4> QquBΧt_Bx qu] *RqZElΛ8^i/غMe5-kGA4Y_(Z _e$OQPYjԶj0O_utvV%\\Vb{*&׀g]4vYbh1E4ƹWpo&fUlDʐW+E$nS*B݌=P@֫5xo,:jqݘyfRp[*?amĖ`A@%R|Zէ|/r} ݅)p^n3Mxr~v.h~@Ti lK6-'&Eַb;Ilyvr۽ Trl'=5ܱr81m ]Zokwb[h*EzXovH8*YDқf\\{ |'(*pKpUKI^BhX t,vfݟ1nL ЍT"KU (8#ZQU+f+dHcVHA_܁-1`9_Q|\{iNjK 'T'zGUFmYsHܢxctv 7WM.wgy, `ydA5 ͯl=DCLXUL,BϮN)#Z5Z>px7y"5Wb۽@a0"a0Q]5KNS3QheRmIӝi zHg5'{II遭Sg]/8D M|ɲ㪀jaW]GNw˵>:=][|_22+-&׋2?pس)nj6=ӕg@ %Tq5g6bBFNxN%h2;[Q}#18'⾻!c ߼*&&סgo&40jHYJ?tKNC<_C$[uKIrnX 3Ǹ![p$S,6?'W@c;AvAlK*ύE'٪f6Q%e9 }拓ͅV5?*m!9e}~ƓâV,ղx0]h>x+ϧ'ֱ\)bKK{J`gR<[Or%S̈<ѸDr:=F)7qV5F&xGQk]] 4>V@> ɿnm/9h M9xh̼\5M9i< ҇GپD7s!#(I3`;EբS(q*)ZG|h6i'&nVWp3 yJY!C՛!Z5b䑩oLP#(RPS>_l8L(3'd}q [77؄tAj,QI(`:#dC{~8;\'"CH04R]x$ڜ#&D˚BE;. l.1y{ \W ` n&hgx\-T pNir3n P[ ̺,/Г'֕R tGWl3>0[0Dq5֩{b }@$0H1ni[+DcMd~sDyrVMQd!U;2 w 4gZKZ[v} E=x_n1ē#-͒nP|F WH86vl %k9QmaɚEO΁N?~ V&7]kAۥ3&6*Ea)F?IO.49O"S0@ 5OGzIDk>AV@c#4ܢY9=?$;ٖb%DŖut~̼~%yU"58NfZ9 Gu xG{ AZ&an!cӣT]h\[h#}NXw%ڭ{Mc#t1(lZЫ?a Qz'iOkoHi`Ih$^o.#8xs) z8/nqlҒEƩrgv?23OL*~g_  wAMe3]=@I%Zz׹PG>>4?`\#,R'F"{^".G/yq$yb!Gouٕ2lNST9⬎!2+Om4-]MjA!ˆP-΢\ՀSV'E@2y6FQ;@8c H˱'"a<79Ga-">s$W:o}H&u@ w8M|N%bJr7*n:>ib5{4R{mA#m.kqJ`RV*g&kMc8TPZ ]TPߘ `G%.|T,(ؙ@Ů~8GcIi|3ʓk]nQeS0!"0ݣ? ?_hIEG>AXop|0(ëmﶸi\,ed Q|j=BYk%g'-xEDܲ[!^G>g' Od:gнٺtG È}/oO/zkTR*!8>nJL,E-E0k!'L..(j/>at G, 7C˺=k=uΪTSCB.`ͅ?Xi|^s</7pn"Tn3qCRu8V7iѺ'O(;#̙ms /b|C]Ֆ U0J&ْhy1څ7 X&9'eXN?68FCĖj~qEH>±9BPI$uz&-zO)'܎o/%Ph|Ϲy!jLӿ E]L!C&I%ׄ2IQgTl]t?l*'t``ךԮj` sy[KCy>H </Ijq~*n㥽M} ψDˑZy귄4G]K:'J@t`4>~5G$aIP(qnp]^H {GPE+YC5?")aX`%pGA>Z{u@~xu R`9|z3.ɼM{3>sb%Ŭ^LJ$Cyqg#JZDUau쐕P%HQߐ؇Ʌ]=C4\ oTfÄtpjõN!n"( wGx(<_=X3Wŋ-AnTCvK:q(S R6E\l6lx‹$e׽{tqx-u5Z Ɏ"Aͱk!'=jvQew7W׬֩B\ء[)]PptZ#B+UuyO]sE8j%Na|E#Pe'MֽhԺj>U:)'/h*:{< uVk:<|&?h4aհ 4FVzuu:) 8pPq3Ql %Gږ%7Umd=vYQRis׊H5.;E-pWw$=tiņ͕g\Uf OOŎ4Ð߱z׍c^bG>g*Ar<Եa0sPf* J!lv&VI#{yo}䀧[qKu4* L'$Tsb=C7}e vh8=18屮jqǫcc6 Κʌ PK[> oOj@_ic(d0f_)\Rˁ.+OFiUmGTN%X q` GAdI&vǣ6~yîn?y3O>HpytMqmH[ gr9ɶdE ]ҲK @zWvP!FWlf+sC#|3ݪBM%Fk$s \@!{jsVh{}'\п&qCKi,o 7"*+Y s۳S->v+q1i.[5s^M9Y,]}x4綁^w#JX@5&^R+Y4HA A1p"H #|!=bj\w؁fU6 Ci~dA1l#r=1XɀLZD0l4CdoqkNg>,mȁ~s=+":I鼈C1O'~SgYwiFV?j,a!&5 p0[UqR:Eγxzϼf32΀!bbBlc6m&D`,e  /M~P9gXW+ibXFD L,3-A8;R _q)쪧B39?[B+d˘&!~O7rm _$Ln\xt;A*Ys>h$:h鹑ߺ -ѽ H={#vMH(UBR/j!J34}"w LU=[pBm-s t p =m(C{2f.ee!{7 vTuXq5RUe {|NL%u, %8qs4]Z18gCJ."GfSץ̽lϽÃ< U7Pt|>L`& -2sVTĥtY&L˛+魕 &YTKLH4sΗ> E{ F ͘,"'k;N؃ӹ}8!Z{ٵ!H떐p n^>7_8?U1i{ O*T|0 &:k>ZFn=3 }3왅W[AGc܁ڻA{` ~׬4"T$/h6B̖}5{;R3 P8_!} ~P8hQ2{9`xAF8JcJ.~ 2շl~PI#-Uz,.Ih66ytƼQG^=9>.6:C8<(2OWcV'M6.0sI Ogtnĥqat>KDtjUH1Na)[4O(r<Ĥ-6jAeX_I휁\`IHa5$`J,[ cV͑eO5R (7 qHFO.0j;*}ne>c] ր2( ~H#\kTKRgfvQW~ԱrTnE=[%*}M%@q}Qr'5ֺ!s5ߋ8Jb D'qW S:[5d\v6at%w1"C0>)ʀ7y*QKd> IEKƤ؁#cdݛ(Q π,6oAd07X͘@W,h&Zvs- [ftV+9O(sOe2q^땵OO'-y9bp;'|Cp+ovq̖ws4{j } Z_o #@\_mSd]o.yF AIéK<1i)y-b5Q$$S\mw e?-t[kZ8>m@!a)eV^%O"*$Q-&0u@3L|`h4{Uq?%L&GF0ˮ[ӜK@4*?ZdyVi~5Ь4a`zIy"WNCW'i5LyB1a.ՃzY}PZ͟V'x8\?>[.!SzRSg{2?,/ SڎmҍuQCEۿ Ă 9-3 L2 |V I?Z#üs0}ڎwdBXZ|&_> D_X6 Z7CkH <9 W56 L0Abr8FgV3U[[Fk5UڴxF` BN&L+t9rZ ,]c O-v|v5ډc.9mKFZW/#ϚfUp} .BЪhJ z& #sStl\p5`O]YC -KPuiz^xTY׏4r "p´ׂfCa6U<lԴg2&%]J%/ru0+~!谚zN,`9\O TPo%rϲ_܃ 92`&5»'"$7VєV9Km\MRD s>rՄ.%?Uy7 ɘOƆaQVW( <=~@s"CJ#mf'$o z[c|ce?l<&V~^Ta^k1/`>H>Z;:!Q++MGMtٱ_*`!maeFv5 {FR8X0+,Z8fd6/}U>0EIH Tr»OhZqq5EY2#>@V]cs/mr*Nvc}8;SL0=*-e#hIFΆ7Tb="X4Z $Op  /6DT%V rLd_7p,V)Ri)yΗn . i%sB2gƿ+]}B͸^a^݉~/%hLb'"sgŬ,\:`/ )Z\:ҘZD oL ~KI.jIv6lÔBl CgHZ͇&7FY۱y|cم\#h<A;zc%o&)TJ2 y=}٫gM ;x~ K Ǭ.ܥ&I 9ΚƜzLnx\ʎW:i%̈Z"n07zԸdFH KRg&o$Ṅ.(đ139upC\zU x':z@׻ u%GmJJ@9\cbaeՆ6\ȋA@Fc} B3Y; ZkEQȘWvh<ĭP VgbFb~8ܧ2ȘW$֛sU)6"."tͮ vpP巒%X*J! ~0?dnqm$hhN\l/|QzF5{wT[Q]R?gCԃf iCζ8]rEaMPWk*Lcz5#Ҧq_4ѕ Y5⇱H$-o!vw!q>sݴ 5Ų?Fȅfm"7ϐ[?geI;SH@N-h#SCko݀sjאKۨx zGK?:Z@:.V#ÜTr?;Ȯca܉|#V|d/-~UQZR#{p*E;u 9&5d@?!<@ǿNkũ&̼Fz"0i<"8rq w-wZ>r:`J+X_z~va?O+𘑩>h~~0(ɪ=$.z ƅ9 Koy,lρЈB+;6=B |d9wd Vip1^ ! DNbDBWwF 14OA̔o'xx0d%KcK2gRiS'jCԝ7J Lkwa=`BHu _aEhwxLSW/gW= ȭ`QG n7\uxG'^]:K)?>(q&6t?@# zjkD3h, Nlaz][R79O[<В hE?@jo SRN;-/gB`],8=E*q4(2TQ.NZn(&6}̝-*q/5-/0AL9UȹC8mbD2 NViV<0eˁCjzܶ+ #~WojFhܕ_T @:=4Kl.ts5#o&0 :4YO{؋+#RuupՕ(_%YM% LwT^ j:ˊӻlOGomQ ǃU f. tDm c=s Wk3zQ>. 6'1o5+'gOZ 緔6Dwm,c#ְa)Uw}[*CHM"'-)S(8 yȤtPjֿ=vN?F\Ub t[jKʮDP'#)cu>O?wr9f/0\L:Bg<3٫3GȃUÎf.͚a@~vN5C^C. 8޹朲skfsG6ҖlT.^' )ۡ8@qQ!50  I9-ˆ_B*9ܓ=9SAa6_ z s}I +VB"vTQ1> ddOsq[ VxN4Um)QqxjM|ۛ+gHWzo&D# V!EMߨ_/3 \5.Ł8{79t8R TŃw$`K00r ѓGԓX+ [PVܢ|:!mh핞;N]_ ũn [fknh]I0WRAQ=쫝nx9,rz%:y~; 7Y9I[" s `jÏJi0Vr!#f=ޗtP<{(;:ّQ(64={>6 +CT#f=.;`mQR\y&pWï}PS˜<ӪNf;2P;;S!Og8|pS~nKkR8赇.7mf^d+^ 8Dg5>F$ch-zn@8Ƞt1*Z=quTEo`}\v¦8mZܢBv99?#!n3=JY]U7hM>X=n$FB>]2 XE[b 1J cQ)8G"gq\FSDu~ZGW:ɔ渭89 |gCAV-f5+TKj|mѽNAYJUW}zuP.}m#Qʚ{dd8s J@h{KFA\I75Ot|Gx8x_:dXԳ=B)bm& l8ʸ(k1 hkoJ<(eCIV)o3MD- Si3?cl4g;qǪ(087#l-fwJ@ \z <~Q 'e@Ь(jAE 7ku9 be8FY )]TR}Em[$[1z'R8< g(mhyo.R&II˹um]y.q~c< =$_ U3 (Z)o$1n; Sg,B홡\9'h. ` jEzHTtۙ[SPt&:W7aLk7S[_|̈4F# ^&`im GFϋ˼if(dzKsgEP(<ƃ/V@,6UpuBͿe&a%!8'DeLCm e_P7i]ڻ-"ݕ=ORE0S"zoDe!nI홵ky55X|dz0[ԒUFC :(y\x ׇRAk̎ L;MMڟ(7H7s uoWk JMKFm'^Kb+HGarЖ]ΐbyJ"DթUSĸؘ+"?-=ɨ >\ 3BDeDGSojF"L]'^Hfϼ[PSN*rpcdVe h'RS_t}5[>vGWdw`] aB8>ݝ@|+rLIgnDG=U\.hY SC |~s`!n/ZThěxʶ*$L*KXṱ# }(`$6^ 72v;W?nltsX32臘97& X1b#om&׉͊z.诞6&밁ۿv=rWf[a$_q8Cf*,,vI^PMZhmuHi%`@"I_{^<c°K ͋O^ptl+I M$ !zEдb!l)ЌO`p8C~]~kY}a0vB|fZh>"4 "˕2 F{TCka^PW,zkz:}9psBqdX{rW1xƺT2q -k"0cC z qꂦ.Ȅ+6 L%h=Pj/ssqy6N2lULeAǴ ^U^TrF%&kJ@fƦ_,Xg~'yxa66 µяIܞSnhU#.RNжv9ĽI,{DX"? JhWBQLIs$5$9e x(S2ƁF U$`IGj@6N7H+ G\?5`UF;aȄ2tXr/H%y8&+mt7puҝ<$u&u '5nnI@ mD9zwkY=Y|,+4ĪT8$@]QMҵgB߽{2i]3ؾ*Gþ#z!wwan\^b"spW g h{\#K~F.ūC0*X'_6Lڞ?n)σ:(e$/[^j [Q%qR%ߧ_L6F)`@bE/x Gi䦝 7dq4NF3b6֞ ~PQ (+r^vǹg>;@(`>HƸl1$wdz| $$܀$WEPІ 焃KT1'0绛xYM`N?MK*2S\uaܦ3"+QTrq,yR[MNR!Kt<̴l'ŬœG+>N!|b$v[:߀m_Zz^Le,4YB {0_ی97Gd#Wǎrx۞5䖊 z; ^3I0}'/0FB>$a7(Vf"'|Kigls  `",p[)oaly q|} ˢJǃgviab0CB/'>&j(*l_|I)~D<*6W' ^$Cp` ˡ߬Ľ %tPV)NK09>-h2 КX\ʼ\l^JdR4BD9#"7sE?28 u9ju)*#VT$[}zdc(ɛH^[[ب//*M%#x"T̒ϺrKUEdDvưy|xţmS໹"i/4n<^͘T⩁m#-#Qqe%S1 ^ƗG?:F =K3g]dRBGZ K1U2X~+^պvISGlpSE_u񡫀 <@Ғ*t+i܃ѱ+=/Q;K+7Hd'f9U1]gw*\WY\#֏A4;"gKѧ69T+Vfߵ`=Nr(4SJ0 ,RПgރ's܌ſe\Mw m-@/-7F Vb 6}6sVo^nQu!.]tב92&­Lzm^7HrV4ۻ&!{\1G5\eʍaGsNwzG.^bOS|29.DS[ \5I^k.V`-.v)pob2]Iۀ&xcʚ=([hE/'] ? 9!ܖαOXmlJ q@Yn7];" /6E0Hf>Z{s.[[-aqNC%'-xLf攖W5zxC{"By).6r3 n mf "y?GpjHk꺱Dӄ á|uU0P l@SKbr1lQ 5y~ :ߒճ 4Q*KhImĀ0auMEZ!'i1L\{x,+&g;No(0s>ztkG(`RiRI]Pp=q+3u?q9cM8T'QUJUuU6 1Zb1u0^_i*Ii~ߎ^4pVr>>$,j:o|+hqܭn(&6#!_fRhB Q5jnLx~ ;:lBϯ]kRz+|pgjb6Fs/Gƪ4PW v K.Tb99p\{}]U63=$(!r1j7/ċ8Eп:C0_orM (T/v]sO0|$5?3-*=+3uľsv0BʢL~E+gWi0?M IL1aE|]D\_XK+'J#ZsCgID 5v y<,eƨg!{cCNcϴM2 xs< i9O*>_SgF!2h%= Sow-VAp|pw@,1GkYt`BCk 1eMG=IdP#-SgxN":RՂjXTCb9z^e@ "oEMIU /l#Ǝ?ت~≔rBϭpY <(!a.q[Z fR/U;T1`:%j|éW@iDaS֮'## c4:T&#&ȁٰgtm*qi_IS·MHxWP8R(zx 8:V!)q<Os 0`J ~( eœ8}dFocݛ!q B'@ו8|F ytwOeИ֝AS:CuNw+N#c0m ).WWfBY&eYl+6^>B#Ȭ4нzPu.5Z2chYWjhm3$5 uڔmZv£=!eC+!5K(6j(ETu3TuFEڈ6-$$1 k2|GyWݷijbH3eWHӼuaa/B Q0F\,ݽikuUJ3dohM`(Ar['#.G(',@.b- @۶Z`bbwEn'Cq%HAvyI*\a{[KC~ tr(_ct{:= DN^ ;WJ6v;HC4[5\XFF1d iފ7qF %|YfʱSᇦU`TC?YL9t!L4[įSf7\E3OL20co,!s7'cTW#Kb'dKQ-q˧hhEPŁlN%bΫ"i"9oX{p䐴1GZqOY Pht}tau@[5eX% W0M72"ĜA`hU`1R/(0  P* \az͏-! }σLWk(h/8EA?ޅf\MmwgCt ]֕9H6l;U'K#WEv 0*F&hv)0,XM f<9-[8lHN.G%OrTBלWTA]R6(V4Y +evVܨrpbk:mAwa?CE|=H j3RӞZ '"M+cT?8+6!خ;y XFlS)n{XQz& 1ED<Xv hTǫGbQ+P8J7/S}YLl bobqz$RPpȼ--3sӛ~A,̪pKă/XaAf6YVsXdc4wKPμkU[ Ջx s-$/khtХ FYw$A;|׉M1$21M[4V_i.u/P'5%!C.7_!zH_Rb1=NF3 SLBLrPbYY:LaR_rmta`SKt8h̍\F_!-l0U7P][ґees:eum:,>("_KIMԓ;vJw/>Mɶe8;V'%>̿˜'>8IU>٭8T[fRj UqT|18>hSQ?1H.a7+{0@c܊K6'8ԸPSU'k2[71jԢ36I".|XXȮhRk,2O>T@z(#[Ε0{uW1;Ctj?\Ou+Tܐ7{ #frGDwƇy%> r dٛ?hwR96͓hqƖ7Tp{K\ˆCKp߫1aFS1y|,Yو)$|}פ6p/: WԸbz~[Fۭ'=Q? ?Htܲ>$#FJW~|x,UO-+Q6I Dauhpaz |DTBwz+ nTpl홇îPp$vN.0\lp tN|Y) \q%nqa[+1~ӌGH;S[} ޳\:>ulpUr5=;U}ZH0#'tկ:bDoNrdWNY_Ԣ.E [\,IJ$',N4 .=sBڄZ@߇`& x=iG,_lCGN_'yEp%sֵLZWh[T~x}m7A#YɕYP J2o,03\KM'Yj Ml_nO %|e'2#Zjx¡>&1J Of10@=?d?sPZBfdzY O$ǘ"D=״vpA\}_ӯM0%ꇂZG>!?/Ogg[+#|mHz͚#U} v{N*E$o#8"9C'ͪW ׅhCU"OW y4Cr^Moדm|շ]P]pϺ#@ dn^H0` /ѵz.䠄vXg 7:Bi"q&&sQ@ Rn4m|'ݩY3g:RfW: "ȱD;Ͱ3hl(<:!掛B8qa8Ij`:mce,?@;A٦b6\جQWe4* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "encoder_png.h" #include "libheif/exif.h" PngEncoder::PngEncoder() = default; bool PngEncoder::Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) { png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png_ptr) { fprintf(stderr, "libpng initialization failed (1)\n"); return false; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, nullptr); fprintf(stderr, "libpng initialization failed (2)\n"); return false; } if (m_compression_level != -1) { png_set_compression_level(png_ptr, m_compression_level); } FILE* fp = fopen(filename.c_str(), "wb"); if (!fp) { fprintf(stderr, "Can't open %s: %s\n", filename.c_str(), strerror(errno)); png_destroy_write_struct(&png_ptr, &info_ptr); return false; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); fprintf(stderr, "Error while encoding image\n"); return false; } png_init_io(png_ptr, fp); bool withAlpha = (heif_image_get_chroma_format(image) == heif_chroma_interleaved_RGBA || heif_image_get_chroma_format(image) == heif_chroma_interleaved_RRGGBBAA_BE); int width = heif_image_get_width(image, heif_channel_interleaved); int height = heif_image_get_height(image, heif_channel_interleaved); int bitDepth; int input_bpp = heif_image_get_bits_per_pixel_range(image, heif_channel_interleaved); if (input_bpp > 8) { bitDepth = 16; } else { bitDepth = 8; } const int colorType = withAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB; png_set_IHDR(png_ptr, info_ptr, width, height, bitDepth, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); // --- write ICC profile size_t profile_size = heif_image_handle_get_raw_color_profile_size(handle); if (profile_size > 0) { uint8_t* profile_data = static_cast(malloc(profile_size)); heif_image_handle_get_raw_color_profile(handle, profile_data); char profile_name[] = "unknown"; png_set_iCCP(png_ptr, info_ptr, profile_name, PNG_COMPRESSION_TYPE_BASE, #if PNG_LIBPNG_VER < 10500 (png_charp)profile_data, #else (png_const_bytep) profile_data, #endif (png_uint_32) profile_size); free(profile_data); } // --- write EXIF metadata #ifdef PNG_eXIf_SUPPORTED size_t exifsize = 0; uint8_t* exifdata = GetExifMetaData(handle, &exifsize); if (exifdata) { if (exifsize > 4) { uint32_t skip = (exifdata[0]<<24) | (exifdata[1]<<16) | (exifdata[2]<<8) | exifdata[3]; if (skip < (exifsize - 4)) { skip += 4; uint8_t* ptr = exifdata + skip; size_t size = exifsize - skip; // libheif by default normalizes the image orientation, so that we have to set the EXIF Orientation to "Horizontal (normal)" modify_exif_orientation_tag_if_it_exists(ptr, (int)size, 1); png_set_eXIf_1(png_ptr, info_ptr, (png_uint_32)size, ptr); } } free(exifdata); } #endif // --- write XMP metadata #ifdef PNG_iTXt_SUPPORTED // spec: https://raw.githubusercontent.com/adobe/xmp-docs/master/XMPSpecifications/XMPSpecificationPart3.pdf std::vector xmp = get_xmp_metadata(handle); if (!xmp.empty()) { // make sure that XMP string is always null terminated. if (xmp.back() != 0) { xmp.push_back(0); } // compute XMP string length size_t text_length = 0; while (xmp[text_length] != 0) { text_length++; } png_text xmp_text{}; // important to zero-initialize the structure so that the remaining fields are NULL ! xmp_text.compression = PNG_ITXT_COMPRESSION_NONE; xmp_text.key = (char*) "XML:com.adobe.xmp"; xmp_text.text = (char*) xmp.data(); xmp_text.text_length = 0; // should be 0 for ITXT according the libpng documentation xmp_text.itxt_length = text_length; png_set_text(png_ptr, info_ptr, &xmp_text, 1); } #endif png_write_info(png_ptr, info_ptr); uint8_t** row_pointers = new uint8_t* [height]; int stride_rgb; const uint8_t* row_rgb = heif_image_get_plane_readonly(image, heif_channel_interleaved, &stride_rgb); for (int y = 0; y < height; ++y) { row_pointers[y] = const_cast(&row_rgb[y * stride_rgb]); } if (bitDepth == 16) { // shift image data to full 16bit range int shift = 16 - input_bpp; if (shift > 0) { for (int y = 0; y < height; ++y) { for (int x = 0; x < stride_rgb; x += 2) { uint8_t* p = (&row_pointers[y][x]); int v = (p[0] << 8) | p[1]; v = (v << shift) | (v >> (16 - shift)); p[0] = (uint8_t) (v >> 8); p[1] = (uint8_t) (v & 0xFF); } } } } png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, nullptr); png_destroy_write_struct(&png_ptr, &info_ptr); delete[] row_pointers; fclose(fp); return true; } libheif-1.17.6/examples/heif-test.go000664 001750 001750 00000011327 14540541202 020346 0ustar00farindkfarindk000000 000000 /* Simple GO interface test program MIT License Copyright (c) 2018 Dirk Farin 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. */ package main import ( "bytes" "fmt" "image" _ "image/jpeg" "image/png" "io/ioutil" "os" "path/filepath" "github.com/strukturag/libheif/go/heif" ) // ================================================== // TEST // ================================================== func savePNG(img image.Image, filename string) { var out bytes.Buffer if err := png.Encode(&out, img); err != nil { fmt.Printf("Could not encode image as PNG: %s\n", err) } else { if err := ioutil.WriteFile(filename, out.Bytes(), 0644); err != nil { fmt.Printf("Could not save PNG image as %s: %s\n", filename, err) } else { fmt.Printf("Written to %s\n", filename) } } } func testHeifHighlevel(filename string) { fmt.Printf("Performing highlevel conversion of %s\n", filename) file, err := os.Open(filename) if err != nil { fmt.Printf("Could not read file %s: %s\n", filename, err) return } defer file.Close() img, magic, err := image.Decode(file) if err != nil { fmt.Printf("Could not decode image: %s\n", err) return } fmt.Printf("Decoded image of type %s: %s\n", magic, img.Bounds()) ext := filepath.Ext(filename) outFilename := filename[0:len(filename)-len(ext)] + "_highlevel.png" savePNG(img, outFilename) } func testHeifLowlevel(filename string) { fmt.Printf("Performing lowlevel conversion of %s\n", filename) c, err := heif.NewContext() if err != nil { fmt.Printf("Could not create context: %s\n", err) return } if err := c.ReadFromFile(filename); err != nil { fmt.Printf("Could not read file %s: %s\n", filename, err) return } nImages := c.GetNumberOfTopLevelImages() fmt.Printf("Number of top level images: %v\n", nImages) ids := c.GetListOfTopLevelImageIDs() fmt.Printf("List of top level image IDs: %#v\n", ids) if pID, err := c.GetPrimaryImageID(); err != nil { fmt.Printf("Could not get primary image id: %s\n", err) } else { fmt.Printf("Primary image: %v\n", pID) } handle, err := c.GetPrimaryImageHandle() if err != nil { fmt.Printf("Could not get primary image: %s\n", err) return } fmt.Printf("Image size: %v × %v\n", handle.GetWidth(), handle.GetHeight()) img, err := handle.DecodeImage(heif.ColorspaceUndefined, heif.ChromaUndefined, nil) if err != nil { fmt.Printf("Could not decode image: %s\n", err) } else if i, err := img.GetImage(); err != nil { fmt.Printf("Could not get image: %s\n", err) } else { fmt.Printf("Rectangle: %v\n", i.Bounds()) ext := filepath.Ext(filename) outFilename := filename[0:len(filename)-len(ext)] + "_lowlevel.png" savePNG(i, outFilename) } } func testHeifEncode(filename string) { file, err := os.Open(filename) if err != nil { fmt.Printf("failed to open file %v\n", file) return } defer file.Close() i, _, err := image.Decode(file) if err != nil { fmt.Printf("failed to decode image: %v\n", err) return } const quality = 100 ctx, err := heif.EncodeFromImage(i, heif.CompressionHEVC, quality, heif.LosslessModeEnabled, heif.LoggingLevelFull) if err != nil { fmt.Printf("failed to heif encode image: %v\n", err) return } ext := filepath.Ext(filename) out := filename[0:len(filename)-len(ext)] + "_encoded.heif" if err := ctx.WriteToFile(out); err != nil { fmt.Printf("failed to write to file: %v\n", err) return } fmt.Printf("Written to %s\n", out) } func main() { fmt.Printf("libheif version: %v\n", heif.GetVersion()) if len(os.Args) < 2 { fmt.Printf("USAGE: %s \n", os.Args[0]) return } filename := os.Args[1] testHeifLowlevel(filename) fmt.Println() testHeifHighlevel(filename) fmt.Println() testHeifEncode(filename) fmt.Println("Done.") } libheif-1.17.6/examples/heif_test.cc000664 001750 001750 00000011710 14540541202 020404 0ustar00farindkfarindk000000 000000 /* libheif example application "heif-test". MIT License Copyright (c) 2017 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #if defined(HAVE_UNISTD_H) #include #else #define STDOUT_FILENO 1 #endif #include #include #include #include #include #include #include "common.h" static struct option long_options[] = { //{"write-raw", required_argument, 0, 'w' }, //{"output", required_argument, 0, 'o' }, {(char* const) "decode-img", required_argument, 0, 'd'}, {(char* const) "metadata", required_argument, 0, 'm'}, {(char* const) "version", required_argument, 0, 'v'}, {0, 0, 0, 0} }; void show_help(const char* argv0) { fprintf(stderr, " heif-test libheif version: %s\n", heif_get_version()); fprintf(stderr, "------------------------------------\n"); fprintf(stderr, "usage: heif-test [options] image.heic\n"); fprintf(stderr, "\n"); fprintf(stderr, "options:\n"); fprintf(stderr, " -d, --decode-img ID decode image and output raw pixel data of all planes\n"); fprintf(stderr, " -m, --metadata ID output metadata\n"); fprintf(stderr, " -h, --help show help\n"); fprintf(stderr, " -v, --version show version\n"); } std::pair parse_id_pair(const std::string& s) { std::string::size_type p = s.find_first_of(':'); if (p == std::string::npos) { fprintf(stderr, "id pair has to be in this format: 'ID:ID'\n"); exit(1); } std::pair pair; pair.first = atoi(s.substr(0, p).c_str()); pair.second = atoi(s.substr(p + 1).c_str()); return pair; } int main(int argc, char** argv) { std::vector image_IDs; std::vector> metadata_IDs; // first: image, second: metadata while (true) { int option_index = 0; int c = getopt_long(argc, argv, "d:m:hv", long_options, &option_index); if (c == -1) break; switch (c) { case 'd': image_IDs.push_back(atoi(optarg)); break; case 'm': metadata_IDs.push_back(parse_id_pair(optarg)); break; case 'h': show_help(argv[0]); return 0; case 'v': show_version(); return 0; } } if (optind != argc - 1) { show_help(argv[0]); return 0; } const char* input_filename = argv[optind]; // ============================================================================== try { heif::Context ctx; ctx.read_from_file(input_filename); // --- dump images for (auto id : image_IDs) { heif::ImageHandle handle = ctx.get_image_handle(id); heif::Image img = handle.decode_image(heif_colorspace_undefined, heif_chroma_undefined); std::vector channel_candidates{ heif_channel_Y, heif_channel_Cb, heif_channel_Cr, heif_channel_R, heif_channel_G, heif_channel_B, heif_channel_Alpha, heif_channel_interleaved }; for (heif_channel channel : channel_candidates) { if (img.has_channel(channel)) { int width = img.get_width(channel); int height = img.get_height(channel); int bytes = (img.get_bits_per_pixel(channel) + 7) / 8; int stride; const uint8_t* p = img.get_plane(channel, &stride); for (int y = 0; y < height; y++) { fwrite(p + y * stride, width, bytes, stdout); } } } } // --- dump metadata for (auto idpair : metadata_IDs) { heif::ImageHandle handle = ctx.get_image_handle(idpair.first); std::vector data = handle.get_metadata(idpair.second); fwrite(data.data(), data.size(), 1, stdout); } } catch (const heif::Error& err) { std::cerr << err.get_message() << "\n"; } return 0; } libheif-1.17.6/examples/decoder.h000664 001750 001750 00000002721 14540541202 017703 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef LIBHEIF_DECODER_H #define LIBHEIF_DECODER_H #include "libheif/heif.h" #include #include struct InputImage { std::shared_ptr image; std::vector xmp; std::vector exif; heif_orientation orientation = heif_orientation_normal; }; #endif //LIBHEIF_DECODER_H libheif-1.17.6/examples/example.heic000664 001750 001750 00002572442 14540541202 020430 0ustar00farindkfarindk000000 000000 ftypmif1mif1heichevcmeta!hdlrpictpitmN$XilocD@N$N%M_N&{  N' pViinfinfeN$hvc1HEVC ImageinfeN%hvc1HEVC ImageinfeN&hvc1HEVC ImageinfeN'hvc1HEVC Image(irefthmbN%N$thmbN'N&Riprp&ipco~hvcC`x @ `x@!0B`x5Yfb&d "Drb@ispeV}hvcC`< @ `<@!/B`<  yfb&d "Drb@ispe@~hvcC`x @ `x@!0B`x5Yfb&d "Drb@}hvcC`< @ `<@!/B`<  yfb&d "Drb@$ipmaN$N%N&N'mdatN, GۻUNx265 (build 79) - 1.9:[Linux][GCC 5.3.1][64 bit] 8bit+10bit+12bit - H.265/HEVC codec - Copyright 2013-2015 (c) Multicoreware Inc - http://x265.org - options: 1280x856 fps=25/1 bitdepth=8 wpp ctu=64 min-cu-size=8 max-tu-size=32 tu-intra-depth=2 tu-inter-depth=2 me=3 subme=3 merange=57 rect amp max-merge=3 temporal-mvp no-early-skip rdpenalty=0 no-tskip no-tskip-fast strong-intra-smoothing no-lossless no-cu-lossless no-constrained-intra no-fast-intra open-gop no-temporal-layers interlace=0 keyint=250 min-keyint=25 scenecut=40 rc-lookahead=30 lookahead-slices=4 bframes=8 bframe-bias=0 b-adapt=2 ref=4 limit-refs=2 limit-modes weightp weightb aq-mode=1 qg-size=32 aq-strength=1.00 cbqpoffs=0 crqpoffs=0 rd=6 psy-rd=2.00 rdoq-level=2 psy-rdoq=1.00 signhide deblock sao no-sao-non-deblock b-pyramid cutree no-intra-refresh rc=crf crf=12.0 qcomp=0.60 qpmin=0 qpmax=51 qpstep=4 ipratio=1.40 pbratio=1.30& Iܝ0_I^H^ IĒa ̾w2tܒ>Q085u]7W=vS{y9QM QnbyAAj[Mbag~),U&6rQeטkh'y P1͡+:uSSܭK(f7"9BG[[ӣb}ō.}E Xh\ " pJ# Cm|WN8A<;$?M ^ء R}fx|V%9֞#._W-$b~K^:&=*L7284ץ![fH=dXC v '/:j?6yka5DLwCB0TZ98#6d{O^HL"[dP0BlI9& yt9:Ϫ3;z4Q+~Z0^yƂPu qԜ]XCo(B` ZSlEV$y&00ML^frid)(*6tvi6-+Zv_%|?^xO^~2t+1ѐԤ@$n!-W($>[TelwKNRÆӟyIK8tbْ9yn,Dncfvy|Zb}'q1~XydHlumuz@B 0k҂#oE[6.i񸋿1Cp352"+UL4d.9?Dqb"Xb~+E@oZ<~`& H2/ %xb,cM)'E.,fG/zcاʙ2Ue^n!kF41}j~a=5nYs ^iQQ/2f%=/}Fg: -} ė&] Wk(D`NHpsvD}!!HBsvUU +G3~RW4>ȅcn!@#Oo iA37RPQ<̇q5|!KlBp6XLK$nbv2S!:~>,;WAl[ެvV~ .IJWLH-2%%Z&9V š\A9Я\u/P(t ʥ67hRn Oޭ𤮊;_'㲋`&J"*'T?){䏈ΧӬX BގO`!nŀN\+`j}%PK6>1o xf7]MԡJBQF++,]y-@J4Վ)(b)Q6]ta4d5Pg]`!.eNݦ? +O$֞aP_@H'7vAHD81*YOۖ[qP`j#y%K&.YPfډ$ H0_$MQ5 )/K#&d} |"58XA ۣcL鑆Xk,!{52pdWo!LcV^Sݺlu]P\="[0 K&KzLtPpJXyxP5g P=z+̉b`YSuPf{eA-Hi!l!BpٺjZfkMduMKjmGojɜg$jNӷkA"ZTfUs~ɷܧ:T.y/Wrn=smFMfVWEGdU \z/#!9vKGVԠC7Sa.NobBI`)1V0}-\I ;[ufuk/uXTYu56|բRqÊ&mcX][ox@uxQxeuplJtS(d ҏ*xv$@90¤m^Bn4&̛#~Ae=d{h& K}T0t[)Mҝ1nYvj"HLKs:Mn rhc`iVz}4HҲwLuD=Kqo㥬kϯ5gr pT0EҁZ*"Q:Q%Md|H6eDQ:cKR,${cҙyHX2.>n0ּ<`Tfsέ sumH}/>mz)e"BV~:zC![o[)萺3:a298_T94ΒAlH1I$zmuaqmQ:2u.f5.K"=/8Zvʃ]UuoYl.-%5{ñt]MF8[)ۂ\k3>ӏUͅcQ~lդ%.=oYH גwu*{_ |%U:"@a3.z~t#;?>WVc$n(7g9=-OzM6QH>5/9m < q2޸|*x>]nMV: ㇾljx7\P,nwOB9m)r>1cYDG 9ezGfU =&zUXCNA|>A $[ٌuWȍag6~~*՜B47AF&قZ(bn鮗yK  ĴeO3ǀ,) w ztœ9@Ri27`5(-c_f&x&=s_rՂ^ɑvdDm?qG(#6N&IInh=_Gg7K)$#+vVyx':{DQ= ᳰfg'LҨ%2Cjy9eQu>9mlaAICTyzCE)畫sSHkbTس>Ts$uH(f?Ro3E?.;VEޤ^bNK=ML̶ V5JDuBrwdw;09=3RxFoVg3Ϲzyr@e_lOL 58eL'TP4.Jl^LqFE*A{a: 0 Sab\je֡ =SܵqM#z`аghMɱM}$^Em?:Vk08jw6{r4Iu!-fVַ.d+Ļ^]VV 32[ǜp2Eg˄C2KEߣsky"*u(_n^9= ]{Y㎴x6Aza*|&տ^Nˌ@O%-lU9ņvre oUΥk jmqcg}\e X cH4Z=8w6'wb( - 8^ڏ24RP zqHZGzh "d2ܷ dC[42R16 8M]Ϩ wJAi$"aSGμN$%xqĦRWr/kh^CQ7r zWn\˖~G##2i:@l1_ԧIBB|MB*0'/82E`2H-٢rɋp(miĉ@/): trAt8TM`uf=nqhvH XHTA, VLg@ )"V'879qR \e1Ҩ6QPfe ݸ)|ރ^SӘyCP1/RY>sZ'2V8R/f:n6P)>c(US΋y_} >}/ %~ cSI9˵߽R' [J&P! NC "nIxcU_sg㊊TμbHDIՋW%>E Q{!h;:enef ĕ7m*_|,Pނzi8牳\<.ɣ vi(H7z8ţ]Ky8 :z"`:?YuU-tB(?>CSH Q)`6R,D3?o0tj`_y4R`| .?T%XTJJ,Rv_?495#?]m!С:зĖ99㍅SQ0KKl/rąBY 却 &^\rQom)y+ewWl_?H {#r%9OB Kf&2`]UJZO轅ز$;fĊZCj,gM'YV" 75Ij26w9k*tmRjd+i$ȕI AKEZ?SsquP+6c!V^pq WXHR.9,MyQ@:dy凡6:fwJv_ڨ I8D1uV@űIZYzI{ͽ"{\M X*X !6{ԍf PGREDo)P=\4 LwM7G>i[i!| 0O^^"ǜ )ku>b+ӓG?/)ӣL]<'ê!ꜧULա {wԜ{qe C/c ; m k"7Iæ4r6~a!s1v/˺R@IFT+jG)}Γ{B02M( ]x`T %)/Lp/xWHMxd6}TG-N[iq Oe .&G쯛s~4'&+x:B_J1\w*=B<JgXMԿ=~hvʰ:RNˀA09/ i%*}Sj3~ڡ,ى)ԫ[.ܣR#΃&95-%d+\e$?/q6`/M\\]6)oߓ̨{|,ps>"WٌlYɾ^k}h{v0RH(|g'&Ly-֘öO|ɾLT(;>XEE=q76.3KI+(jm)!i a9(Ȋ}tuL6 O>;<Ӏ^6&E J%1R灑ڀVؠP vYXT&%+ggL}?$]@,IpQ+ŗtGk%F^z-FnmML8A f^+ UY`X#V7')s`N[]yKvt0UOYą!XaBBu"aWٻY G bbPwxo~\b5d\8m0B@K* 2EФHATRi+cN. >E&*z&S;CpW k86 ,õxy1~qc;T3EYT9+AogTTjytMȧ &|) Xh9PpR{bT6)\غ8,[*㙠 ԋ֩`+)Spdhװگaq) n% uԓd=z1vaq n`zj/8~nQ 9kӝ=;0Q8}V.MjowuGRWQI6R G~{O)}[PFytU/4F)w9܍2aߗL.0wg}yO j"敗H{>Q, u7:2iLindεCkUtWHDpu RuѕʱI{s6B7C CJa@ґQ~frB 5iJrcs0B[F <5`=Z^ULi)w[Vǝ S+53(uX4p6#u=1N~i,Y$PQG};Vn=eHrUhrw*P"?M+$Hvl5LJ,D"iKGP)X$fCP{1K\A4z;"d_bǀ1Ȼ&سȌEMgL":o{0jMz)[O#j+9I`@* EP` #k0'u*7:a\rQV%6+ Y聩J#I>T&|z+bW?z v@2M!Xs xՂm$3*D=$shӿP;lMٟ{elX4Ű|sc l,<4+5mg\X%[cXTE;&;˫Xh)]q;+SoM;L@Pjˉw ku,;wyܼd9ʬC$hBSM`:H?/PT"no4 qPڔb-C=8͍ekagvZj |]k3JLu.N"+GEC/XWIV3y}o5 )PʎwF>Ɵ,t̵6`ctC[)sBXPCPTahzGuжU=O/˧BJ-CX1TzIӾ&5+TV.VU|=:3dgw#O"l!r[1m/J,N8 h@Y^&[}g]4jX958gw@'*q)^MXp4gOYR>h Z#"`bc͞D^y ų +d>F1ހt ?)8o #Eu. .5 ^jBשּׂR|:&v$ yﮯjx2tgՐ$ ,$.RFY+[k%>޵V"@Fbt+Xq(vO8v<ȡ1qq t]O>^BM҅x)MKy[ `[BO G s@=բY?:j}S1@Yf!<t>O$Fh`PP n0->thLZ@#Jkm`"H&;Y Q} &TJNG[!{Jo'n|k&a+O랧gA&>ČWE%)h/R,E^Kx7C h 5 U̧ śu.GH ׺:?I8u|Zd+ 4/9m`#!S],۳Djw/&f|*d- }5K6XL|s]cA5Za,60q@|E+. n*\dn御Z=*}8rZ0 :, j60UY> @?QV5Ӿֹ,Z9}< RqB+'k[G.3Ppi6i Ex쑐Mݺ΄;j|K]ϧS2u5NY<9wOe+ u,,9i}IR@J_#H %vsC!/̥ŏlm]-<`W93?-#xBfE[q,cZje:3LS!Ƭzi!߰{.n ~,b\ʹk+cX- ״#M6m6IUP޾E"YD=0T~_ ]Q^pBڹ9BiVZ4* RzO-^_:,8aܡUi2#j p9Έ p2<%=I5\e9FNLʶlz鶛aOS ,-oqF6w~2L%2t7:r &L)i+!l4,(>vJeReJ^GWHn/uxH';A:t@: r|Ĩ%ᒈ=P >L=ǻwJcJ>|NXF`2@YN!ƹ@ziE挀MvMc;k<9"b{PO+UP%Sk\+Ľ'/NVz,DOEpdGRܲepq-k@2)CZ~ (u"Gj5\AAJ516l>ҟ$YI&)fSo [qDI: ̃6BaeTZ} X^%M7|D & Yt\[P_:NI@فί^ "v#choTj7SR%@F@%F[:}{SgT2gjQ#PTl'=ʺ#.DiGwIx&o Ab1o r(Q &w+O sZ\ڷYc—|70R 5z.AO<L}3PH gf/Tyj\ZE2f9@.:ؒmrJTTFsVsߡh-.COGD=Vs}g\C`)IkA}W'??%tMgxpR!S2Ӟύ}C$1X{I3Oű-ziX W7>zvQ'k,N/n)nFo+29`~?*|KR̰O$YlM61ddnpchU`(]q'R2.t?{LDA7apں_pB6BSe8L4Hrq̕9[^0$+s2W3 wy4?vU(|4qE"8̟(Bu=i}CEV# qs\Wʺ>PS=y@ JbV!B2bH3?yUkT#l']չ/$PME,,!Z  ]=w8όt/54MIvtha9ҹ $󃜶DRa+@zuNM@8ܽʑsvZΜ&.5#gۛDEuMJ+6V*V4{ѝJ"S'HTS{m8g ޾%QC Xվq& kV Aڡ]bl3aF&t0Z7B߻|&mx'.NUu_@dmvx/d6m;QGc ;e޳IS6p uM8TҕۼՌI̜2ŵb2M.E8H d(4`1}eH| \ 8K|E~^d_ $&ܠ; ;20˲몮3 2HtԲZ_ +,RFVUГa bDNչ׺>%+wkq@C﫢<Ȝ/'ar)ryg<Q{aQl777 35^2ˀpz&`LpL*ϛ,l 3ǼDx cӋZ%B֟z^XZ$мh@X>u彍[8\8*\kq(%Ġ@*dy+00]nJ[]k4ٸ2cxq F~BT5ǑW%k!x`̈́~AZ;+c6i+ؐA| OQJar,i KI$d02*4U{knZQGM`$k(#HR:Y9JTYY-(@ɋ!n1Zs$r'갫vSoɼ < BD|K`.:zg u!#xGh Zw8ztL=ü#BM89 3.X#Kk?P9kn+fX7b8#C[kM+t~7>sJ<  hr:}o~nZ;1hxN1 }(l -&$V۪GJAcfLdTs|Q;ʲ?NHp]™s$y/"v71h 5K7ވX`_CB@ZMbPD)J7xX+;;\iӸ\js6huj+̄ݭ6=2 #s'ӂ:şħcCB5*sRhr/c N 4e,Ee%A;dk'w>Vhz[R.`:^q̅Ļe&UӴP 9O *ow(5)@b(sjZHLA(P{Gկ uI-#SNb'b>>^en妲xխ%AzVh Jm|0wEcv§s[NF$Ru̓"joQP} ˙wP:joK K;-dl;~|Njx\׵3maP"ҼhP:;]PD8_IJ _ـ[_O.$ZTiX{F"-8`:7Fpl0 5Q2g$\4oLrk gLM98J$ (9*7f{tYKI.z ([0EHԐ K  E3gd5XBGb0-CնS[ +)C' 6tqGLLE!޲iF2$z,ό)޼x\Jp"RKs۷ }ꟛ~Q9GUđ3Yx ajƲR h:> e <6>])]ΣMu-rFn?OgQ]7xJ,L W ~ˉf|$jޓGJ!MJ5sa8NiPNΎKCّS {=IO E*;mJ"uq9yM k +C뫫pe@ y%nִEѹ,] ju9,|P-5H,]/#Lh{Oq[ɥNO*yx:)uF }}ܻ & cN:4}kLE[1WyiI :ۂ&g& ImkNQKCM$ùXOMSD@p6R 懴|%0$;Ȃ Qvq9` d򜗤>}O -#[pr OMT>H&6v7 Z 46b/d] M9!IC,!:ӌoZz9QsPi6\M/fH,/?6 ^ $e5=} yq쏯n̈s&v.8UPH̻@ۈ`up6qW̪O`;Ւμ96m8)T煩kpuܙ*4,Lgwڳ|@MF%#Rxk]\>ʜ5 R]RAwI类VOœ{r0uNέΪM#A |RpE4xiy[/!dm%9a\Q!WX* \R"kej44|HKXq+9좰o`r0Kz\R5h)%ͷ_c G?p4DZ"b7w_bH7:cs]G秚>w3=xsiWWf翬E"Ux _I/Yp}usqխWz]aCX;Xwyy#׹/πaw{81 wq ٤QvGJۛX5!{b<힄zFءGpٳt ɫ2%"\)҄`4naU[Je;}Æ_ibԞ\Ŗ!f QX78բS HЬnꤔ SBWYAu=f7i *SE3S9<#.xF 5ta)M颳MUxk?I`wGȎ["# =.!(t/ų0ɑd+G-,>,-2ذ][0pBZ.z_ ׬nJr^Jg>~XΚZ#$yo3xnxA|$H A*$7=Qz4A&VtWJ?FŠkE īǺ㫸 *<䤴V@uV@W-Ң(5?*\cv sy){.,vX{ʖ~UP*pjzEƓޙ}4)G ~#zVc?wp]m"ptP}U[bdtՄfS-[a#u}38侙@" 5AtEf f 8Et1+}%)~0.MaV/]su%7<&̇&+ 5""4Ýp1=ͳc-. M唵EBE_(/kGW@4->ƗKI6M9Tӧ6iX!vpTa7OSiZ0{2]T1 k$~V lB(=N9.xUTyS2#zi+Uoׅ,ZSBJ$Fw <}׉#yƺ,FbPGc@ay$oHͷ2/]uq80O]i)V8 (;`G jv8O** 5>.$;9!J񠌮%|4 Ko\x։oi@.ebt_LB]@Ơ?m~jlABQO@v)?'nGouv2Ób&,Lu fgݖKoMZ=QxЯ-L I; rX3&xGhPnODGJWNA7 9/P3Fٿeo9oX[dȂ~O1fZ;'3iTXπ([}*ǑT罇tY{Bh ɶ] y(TIhьR{3N}+Փ/zph)|uhe=짚]pOh']NW{]gn}I 00EY?h`SH[IWO?Ё: 8]㸤OPVfb[QvLGt{kBjKJ#*;@nCB4gȴ &=?H~b@ sU5|%_f/+V9t@?@A{ ǁ`!-k6[u3HRZͺr28Wx"kZA#O фYh:9AGϣ0y𔫪~p#Yðu_}6D]UYoz°<΃v;6j"}n0S9 uՁFMN,ǻ6pn_%CXDzNխKYHaw"'k]U f[}KYSm e|iiqs/olG¨yRx<:7XfcpL޳?ӷvݽ?L|^2KQpy2kE`gD3گs(.Haw0w WӠW2p.FlDڌR} 3bɊLt]GJB:+_/fOL֗R˟0Zvk)-Lɇ_ۏAYJw 7t"\*)^ 7 k`yzw Ŷm[ɮnqȦ0 Sab/46l;|Xҥ嶬mh1æaj!c%sGtڂ& S4h^QQmKQ k}vB6+,Br,lcN) g(ځ r]^|zoʵK16'H}FA_!9 $[ZpA $G8!F4do(49e[?GM4\V c:;DMRt2?**6L%f@􄣸dln%GT-SU|P(HМVNA@eٖ(*3u[Iqt#ƶ$Wۻw !~b eno<`8oSnFgY0ݡ<JD׫_DtVNUX_ u圍rO?*,#=E4 Hޝ`鵉W۵:2ur`p$d|EهyBqSJ@M<"Fv:'iǯ^ QE z5ˎI4|lɢ̸Nz9^gRl2[}9y8ku Zet= tUz&9}3qGOYseV(}3jl?}:YA[(Uʛ8mYE5x ɢdO@U<,̻} hX2]D0A}o~K_O >ԓìLpЊu#PؿH&ߊ7QB0Qݘ#+:D66N3҂7 =*t#<7xaߺ&6_ l8_%0+q]Zfz"#3^aѫ;km۳(NFPeSeQ_[_|ԗ-ѬhV/Oa$Dw10#lŸZ$n4+5$IڨR~ U܆!UpԬ;[NZ5ޒvJ\S?w`/9 tYO1ꄑ&<,!uS&77E%z-T4Y|gYVyٝovA.[B)GY*N-݂a]lS39,;җ!|!a'dM(0êmųV/:G~v:m O3+ }Nvǟ䥆IMce8'ٞ' jVzG6 oya{O'tgҧy}?iL?F0-g6]PHy1=?n2ebFyzR 6K͊`b8^b Wܓ5B%jp|!}t% 𷒜z/{p"K3(G{btwzrdZJz0 ,_9sm0Mñ^m<|>'fQ)w7vDRlO^hAxWբUuJ-;En?hحH9UhsPG+um卫pqXzT溗Ϻᵑm^BI=~U?lXyȌ¼yilw}ЯNmtf@60|j΀ G[ _p V;;fwtq=b`nR\nG#3cHX ,Hs`/j 8\; a~~>\xD# -EQjeJѲoP J /?4Vm pGob}Z)_ Yejv7{{ 3Ġ]7[IuT;aWh THBgԟ[Ě;|u﬉E7ꆤDᘋ)6q6W3О}CnJpLa/F qχ"7?b;EV ~ o&#i嚂ĚyϢFxDB4[C jےmK@yNG֤2Hq%ti^ښgH6TbI۬buq;FCZE4>=jhR.*+; a"7=yմ_d|dWtIX7NFO'6|na@8WO{ ud)x`ҽK&$H7I=5TG,[Hi~Ao,1_թ-{V{=1, &It JJ9fLմNv&jV;=|ϭ{GmBرihl`:ڿQW2Rf uE^Vt 1^(wg5ͭʒP)2x_ONܲ2(s ,Ba7^c?/r6!ܘ9P4XE 6nIFh*;[1+5$޴%Ц^엞ْ+̉} h4<80'NU*Qgv8ģ~m`7xn @FcvUDC4=.PN3UcHGZ_P 6-⫺ԐAZl沤Y| Gjf'so }fڻ7z>">bH]ٰꄉ `"{KT#v[B;|⩪bʘ`Hw:+XZzWS>IDg=S\ :<$Gx|t=/5t)[w'ߥ%ƅO ?}{'8'0WVh +׌VB5/.I.x3SiYMDQyjb5# ""o+i9ŋ(vx"?H;T,!!t^Fs%7pϱx Z h 6Jbjy 1ba <XSdC/<45ß/JH6 ~g[{ l]s$kB~xQJ*'˽mr 0Y?LKOs|-rGɴP6t>I>m#'%++R&{5:AB\=K62{RH/PMT:mG/؀Ȃ]z}5eܩMM /!ls*SJ8vNmv.g6:IdEUK: C[ZR쏀.g σ'K+ )My4ˏHkbLQZ =QM) P&̾wGxNmro4l.2ð8 | ae wbĠ ^^Rsl,c=bxQM#Q[޹,Ϻ(m2dhWeδ7>p\,wg0w я#"<{kiY{S M@~+GJ]ob rPG&UF{k`Z݂& 3VoMk|͈s 7%%5BJΨWϹP%6!KQv]8l v:.#SQypAқ3&Ci }F8)+s>Q\}ljË-)TbSP>¨y4Q(ȳI 8am6CAyxdW2J&)D=3){>uj8F0&BB:( PXx y ;wR;VJc󠂰rG2!~]jxL!`䃝@;C[-?0JmrJ`N8}9DZ׉! KO_7^2:||u DKM|T٪'5^}E27 ,TN YV-LJR{2gC مJ[ǙaPW܌,7dQEt1# Nay4w5y!O0?T7.l_]&AI'h˿Fw9%!5W -9S?qaom ?+{_҅Ry2Ġ*8hD|I6t{KM9*=~KTG3ٰPEa֤Nuݺɑ9%o q+JQEbWb)`-6.a<ƴ%B3=F_c2PѮexs*(KL etr/cZTwjgwD5x/ۅۢ NU| ;>0mJ"_`ԀZҾ+IT᫔#Gҳ+|RNUEoeKj p2ZË5dy;`*1`qzEj>@lMޏ|F'Krr# e /,h_ʁ\u&z;(ZDz!-ב,ؗTwfi'9iZ .nв ڠFR]& [ `r@[CC(1XV+_ݖKG (PĔ a,y73?QMb s UZ($xC; ❾ le?Ĥw{Vysy o<2-?n ^v a={m'7F0z ,?\.~&!!"'G_F7}W|t)z Է0uǝ 1}e ^'Gpú~2/Z:\6fNNh+n.IDq.'<; U >B+e*FHŶw\hA /RwwYƻT|JS|6.bfFR:l//CUHXK=Gt!2GV%8ht_Q7t9pJ59,ZJ-kW\ ƍz޹rM]JR772)[,H-[2|T [K>T+G/XUՋ|!_V 0w_'(.-[J5Ż( D ܳGОnjKf˳ P̾}M@#ĬuQ!R Vd3r@FҷZLD]PAװc _fARW(}wx3R+|5\4u 4~|qY'זzj4ql'GBy*IJ,1k'G ~XnEŢٞ͋j4=]r'b}FL_?^-7LmdP!YiThZv,'תRAIQӄأ-M(+^v\)xŷ)CNa&k8@qf+G<^[96Q6!a 2f7豘P3\OvX"C'Sy<)ӪڙyVM]`psOpѳouޗVSUlLLu}᥋'6I3؎sG$ t[zf*@,1=yKE(l['Uqep Gpoawƶhj'-6DFYbxAE0$4ZZ'KLG\9&;P ޱ_щ.2=yv,C;[%Loӟb{-2?/9KE׻pL|W9ebja*HզKo'K#3I>5Wߗ?T!/3WU4EbDK|#Jҩ1+M'ש,8͋a|u!J|k3C͍ ̦ǃ}\!*4z\)HۗqXfIC7"=mhy%ʌP>tڃ@8CuIY[42/,u'+B&ʸBXk ps]6E~Dש[dddBWޮ 0s8s}!8pTN'`HS qys6q~?*Ɂׁqd&1ј`\DNhq>Oꦪձ֑ң0,in\tsrxxS.z2ƋVO܎kWNj{w4Dh^ǝs8'_v5<R ukz[ND"ZlQv"PZ_j@{eQuM,AA <(ة`jڔuw{P!M[e9Ixlt1Gl]uxzKYUY(o!H$2c"M\/_ɹΰϒ'Eywɍ #3ue X\ B{Sk,}-"D]A~=hKuCW&g,%Z_ܪN Ke0Ѩ_UuI1e5Y{Y ~ɜNU v1v(|څ͙2j,Pw/:zfr՝`69 xR`?ؿcRj>x JjVʉ9:ύ|ETK~ 1\E? eÆ_$ow[@ܒ -Q hy mO} ,$F*ӌ-[i]/E:ep&Jx koyqUuS"oR\}*89E `_ !YZfexü{ K߹a tɬVmC3^߁q1 t"(R-qU`l&UcQlxtt53<*&1ti(뼃 cfE{PD ǟoS68 B>8_)fѺ*[䨍-% 2ȢS{)X1oq+?~rd'?n[8FHB9! ]5T=K4A}<򻒦`1 T6 ih@;fS ry xɖY0(PEc)p<ƿtEqglUGoM93@n/^=~h@31XAw Q2=ȝa\ [zDpA2w5 z3x!݇..؂V!Ϳ#l'0R#1c)Qk0L⻒݇G^`X.T6zSkC8orqvRc> I]rs?vϹ`-#%@nW@S}o8Q[U#bj`T-Lu_v`V#M4\0g?孤0ⴹ$s{9Pk^cKZ|F0`=ǐymjxn̽&SNZE,Z9Y +\u-U Hц^eH:|z2M}wy {?e$7szjbļeRL"_cPZrqWjKL _qP4o^!Qɸ! = ԯG"ƊG Ā RD,foFm<`$EXh@jv|lixgBU=(g6zI?fꇬ&Uk%=s5c 9a"Yo"M$' ʂc/#h'a[m7!W K/ P>$D;,qS4>8n]&lRy\CQlNb~H+cɮ;.C7~dR*E[k %¼ɰ]ia]YNn6$t ~ RžF|_I5vXoL3|@P!Ԗ|[ ]F@m qdo(n377XV[<;•l].c鮥E+Y[{ M`O;JCxQwB4sw d@7vجwGS)obfT?L}03L/:UA8Q] vpv EZ% vbGV~TlU֏ 91]9r}mVѺ؄VI_+1歙A!J??}K}!ҋ hҒ-/l uw55p'2vf+$Wc,ދzOyزQj|ӽJJҼ2s;ŲX'3̱3ֹגP5_AȋIy7s:tg>2 ;Lf |9X.p23I8]3?_,fY!`{xق75kT >B@>u"_i?F4{G[FuY yک,oLu`objG< lRHLj (&*XMV_kYX>Bd!V|-V cך7.L-8S^~^Z))HQզJ2f<6A"cy1L#nY\5^wDHwl)dXٙT!& L0*/=19,qY=C,q9g8̟N;b{{ühR\?78jUQ'{x[+XM^b07k5'5fH3CĖp܏"I*7"09=x4 ^dJM>䉄[ !HR vx)Ǣ,ضഋ1ųCqD/`!Aa]f7ZصyտǹT!0a 'R̭,6PIY\j#~$XͯneP^m;ycYL͂#"yhe1=1BNIJ{\*;o,KM,&~6 GǰVy vےƹ Apr5%-cJjWUcS 3bLeó\p(t݄aˡLIj:eOoU,) {X-n$KpU`U,C9^8qR-.*I,eH鍜!TꆝZFŔ+`N/f+m%jh`7nhT Q/LjUcuI 2z,ENA`~q<4OlCVepkwp7};m@jo8j8$IЧ JYNM?RS+atM &jz!D?z|O/$ #zSl@ .kJÀjy-C4gbQ%ĩ_h!Q2͍8\xT4#):y%頲c,^~z\Np1(O*W8`s/!*‹ޖ43?a]!X."%KrK^qY5\PxQJaD/hE QhbO"M'G)ND܀e0p˚$qB q2% 2`JMSiy$ Tɣf3Y8o+չ<:B֞@au֙=S^?*N+Oi *Q41?.4%6 s(c1oQwM7SuT7[840"VS;N@W$&m#7(+Gu=d~XKk!0 +lOޝ$i8qE_,!GFvp ax#<#RDO6X0ۑ!ؐ`F`^o6<)ݮf;EJqGȼvRq}Cl'k<lz샱OIho)aꅶD#"5*Кc!1x6s!GĞJ ٕ?kƺXrԜ /N< 67~LUe&w˕K !Lud:Xq,GAL)ٟ+*ゎg+N ;qV9 l+_FkVB-s{0voS5L~$Xsl;ˍpwĒT1#+][b{~ۇUXNF;`V-Y%' FŬjn' cŽ D\`ϪȤ g Z3G= N4DڶgU=OGU16g^.րʹ/qT[f&m(a$T* ^{}O5z)rЧ'0F;+Ji6\|ҩVz^-VsXZHwD ql1\(NkQ MFZUo N=7QWLOhzcӾ{IvCxfrT{ꛇJgw!@oN)c4ź^!bkQ Ȅezd/Չ!ʼ ?'mI/+.\]Jv&ȱ f"Pףs!!3z3=uaޔ͐9@vw! },# "dݮ=oB'J5E:Bu[vxZ!)t=ݼBf؄=gmdӽ`EkDE_TxpTx+̗u\YBO2?3Yb+4\!JXv;7,/EmS#Y?T]"i5D~>QH2LJS!,G#VjvtQ/߉0qv;zCmqÑ}5@SPH炽g @r<%_ihmbav cCM&O m$ QYx wqda>.Xe@^R9bD|ZX748PZŕ=j֐kL@/ > >imfLt^%ޛ,ŎAkBN9*a hI+֐=x-pT}-lzu_}TRE o? ˪L s\\.TMV%%߰VsN$~O8jq7ήyFF9]xߊ€/ WieLAyУIb[CORciC5tvĹvX7Ťr2BEdubV8X#*ZcQrE Oдl"Րm=şV&svcgB7g߶I+NR=p;ϋ&aR m.& "L3}CO!i`R7T7OwsJ`PҦm½g2/gZEB]'}13ɬ Jiҵ۝M2&1njq'Q&Y+5{$,A #%LOM2.&1k.:5ixu: yB脭ϳDŽ4/ud"^p3s˷:×8uT2A~[DM?l3G#cP+$#[Dݬw悶Q5rPmaA@G3$X]LB",+c@)97٩4 -~`~%Ʀ6WK-#}zfNj VF>eT#era}00DclD!E֥i@~o`}r,ᓷrL%f#\ d3x=w{r>lewq"Us-n. k(+< ޞ%c*fIʀ A4ahq3Ma{5KoJΰn7(S.4w? )/ 5&cՍh2OB~BQmEzrȤξҵ殻: XF\zaStz8;9OFDd[ 5R5(o RfxD#9nL7zxl##@ #9z C!4K-ʣ` И; Ǫ0ߖT `RjEap_D;4)*֭g uq[/./jjww}eiQr޺w(@;SYN~,CZUKHV((024/{ŷ6 "I(թ:\*vRR>y{@1w^ 쬚t qZє$@{2*L h9G"(`0$]#Pr )W7i2NXVbHP;L[e-bO2/F,GśZX8ehِOÅ`$&XȝrA^y`kg3O/ĞLfh0 (yfVɞُϗN 7:l3PVv kۉq)&nӥ¯:mA$,DTZS{HUq&4\.ѭרKLzU/Ą~'.եolmw΢>mp*^wWVxza6#$@'_:$F:!b9~LXiQi֛)LUЈ;D vU!]0P@5&kD"¯c/IF0 @ 'f2zI'r"& $p)n^;1t,þ7AZn쉃uމ桋 SGl{}qrcQSNƑ n4@P(+$%xK&v[:φ P`X۫ & ٫e Hɩq7]t˕YқɊ ¶m*,@nWg5qk oB1w'o ٖ~ܨK7d͏!+%"`kjcJu3ܼFɻLGbMq[d&ڤq@}ir&Ol!$D],MQ(j\7{}{H8ba"&jia3|4W#K,;otOVMmiJQlYK3쭝1}n^spN*xۍqkW\X= g!l̫Tmv5{]bj6\78T+"Xָ ,q%'.șz@Lj'&{)׻GSeSݒQH; Ϳ _Gn٫;l,a!,DI(Wm*[?4qh2Q+.dk>r`<gG\:up9ydՓ jIn0kPu=zÕq>yqӏl Pȁ -a?f/RCZHj4x@5re,(/FP:͚ B9Dbǒ5owz gu"k0x 2 W*Ic5w7#=|k/F84%}¬e^?EF^멋Sx+4˱:耉S$|XO޶t5>|m[F֎cIDŶ#Shfao^}BIl-y]k"5cA-/qxL.zmW ǾQ1qX1 Y!i%PU]-?QV- T{='mD#cq!a+.ydHu Ȯga1~HTyr١>ǰV`볳 ߿m#84KO<~LYk32:2hE{-6.$ J{ۺ8\nI+H>VVQ -w$ HpSEׂ$/w~>S\ь_|hTh4Ř-7Lo)ȸ-Q5_rП'9"q/C v5/7C,*I+X\n3,wE$ɩ>*߬z}([;:1c+&A*֣JN7yV@)c"̹orfġgǯ4q_9Qnxn^Өy$*Q˄"ˬsb5Gg| mz. t (d ; xhNʕk rɱ͌mg c@LfbFU<*O y~䠳5C^JUiC[?yiǜДVHrkɼ5S'ysu76spO81˸&*d(Cͽ?"vbg y(oI`vYXLRŠ/1f^tۗ QH8+ڽĘ}y8ʺAQnHZ=EKJR&:}GKbv/tˌkG]v(Rkj oha8|@XX!B0oSaVKn*o*̴zV"6ӿ2Ψk>i| Ww,΀C,ߘ..H `.vs.Zv1skfî0ԜIڰ4ZD=υtwȬjFSnJ̋;OK4oo;]j7aN-[2 +݊MÆ( 2QxlBHy%þ㤰]A_UCn~ Ïmw.-/(l5)Ѓ^  eJ;Z Pٯ-B/I({^NZwH\iEW1Թ.56f2TfC+W>j@ 'q ẖet8ti~8{߉1"wƺid&rVZ U蒁3?.u֏2Az(x hH\Hʃ`I_3bL.bJu~x&'lϳNoD |Z@3+ o6w`;HwQS(YV"Dk*?R*RV1^ gWȿgK  RA!S֏7'Y?J!t*DUQf?{4pUs./a*aVwEK&"$']˕:oer\F{g3m!'lU4I(fvmof0r4V|Fw2K]2&A&rHŦ*BS}4hܪvWlZqb&bglv)dTÔb^,^eQx+*Ua* Uwcpc-tD+ى;*`P Q|}nj2v^AaM"s=M4r bfՄC_wSY8a)*wu_ *(XW"JPSifJm16.Et,c1y3leD\{Ujv=~&&XfOę/@ÞzapV ܹA@f41.ߘ|$ȁK%1nc$ĵ.Ŏdss/MN&+ fuFz"ONF(Bh+.-`bUтQ;X 6nJUO N@Jn4Z:T`e%~@1pm<9O;lחgAz }QDp~uE;Ml$KBQ}#'~ L ;-fzdw.AedU}{,Z&! 2>OP,{deTL+@-yUy."#dup_ 1aZ1 k6{h,U++MYjL)5>o2ҷw5@QQߜ!G[9L¢=絟&`\ \LRhUo|>|&xWh2z"PET>~L4D-> xv"lkl ă*Y`e, .Vhޑa 0ˑ^F;. cg)qcqmga[hsAe Hz%h Fa‡abJK?+ObeiK8TI kz1pg|KA5bE6 %v3O>~OUZ>^& K4lSx]j. dAVr<=Xv^Oz9ޘ1t+[ xI m5Kl%v~/~9a|ȳMь=:|(ڈSE!@JκWZP0%הRtX)x7a;ݎd`E35a[i 3N^8$<T`M^Qd| D#I|ECcU_ N7iW+ekRժN_ zvt1` VLJ$Xtq5k+IDߴ,FaϑOJX\2Ԁ9XVƞ~&y2Ȏ[zCC.1"gk}UC{ygBaf'E=+Mxi)=bFS+aM?<Q߱GvY57Wac-rVԹ,Q@T~W*wW'I.*Zc^?EmLZI֪PA`o^iqbfJMwcu Y_xI҅k,I,jU+:8@+21&}@+}h&+ Dt9sZk,ͻ4Zhʻ<*;|Ved8C4@WNV,Mh *^Kl 3$<{[?^HqlBru%7-i=\wPMuꥶt>2x~J(2g=+U*b S"(l~p"8 dxKvX,~!|8/!BŮT}]Lmf0Nu_XS=u :a;f+0 $]8!9QDrSu2k&kU^j``Aggy/~TDB/m$v)l[#[)vzC|;4;ȧYnvHK<( LZs!yV)=UQ5#Լ~-!8>!qG~6U4F7nXKX%H?"kЍHw9ELt,~=VYڧ P\kB/n{mC`Jyug$p.tim_}ҡho&b(VC7Fv3/kr Z2 5[˼"Q(' BbQ?OګTy{5{VAP# n6œg7d).y8ġM\ɜz)K^voXSq3ݍ{Ft!T,wv|pbں|Ll3ln{Ά\QF":X9 l;Ó`n׃„ )#{&ZOYX6,ZHߣ AӊC +Jڒi'ul$11Kf߸yO2{mu\_o] SӅ~85^W. |F2.T05wo)#(dӹ A I$ wftA (+oj~3 5UՌkILm!D--Zrͪd5GؑrzN3+;wJF=|o'0"TW0a< HWP*~&E5 OENEʰ+EoэUzfR( Y5Lp4JJOjyk@,BPl4i ыkځ${2hɒP#V-0%˄[]D#L[turٍ~\slPbvUV?WNZ>i144GvywbƁ>X`K[{"WZ Ւ(X``v'}Wvf$)Xz!yucau9tAodA ..Y7Iid:{c^E7W rJF4FiH"BSٵkia^zX;[JYkR9uy_ λ/Kɷo lٲ-MRdl7>p f%o%Bށ\}t"=  3'V%ɷ!oR]-6ü%nT{yLSMT7%^V 0aW0g<&Yw>c'j5|J>D|53  _e ܲj4:'pi$$`9A _'J69␦TzקԋSy֑S3t] j%ĵX~%dF4hL1 ,݋PA~R M3sm ҫጳpf[F  UzfU.dᏛ1ƎT^xNO4 i Uf1㎋z/J{C\bݙrR֣?˃Yhgx.2eZM~fT` $rh]ўԊZ/SI }ϫPcG"=X 5[#wMa& si)1o9 g/˓ViI[:j\$m`y:'3wRL fuA:z >`]DuqO xP&,k:Lx|raK|ccׇG>ȏ+Jb%}ϻ-`:tUBB*]hʳx\ik(_*\ (4V*,0u_Þ,jCO|3镺azK3Û#ѶpUשee`֬tDՉ@uuVk?z| 6lEPX.pk%XV`l΋\hMv^V37*e5h pL"/qR5y }u(CE:VZ!1H$4N w$ro4vIv#a\o(YF&Ow5x\Zf)e#̕aKXgú'dx0T?)䧎kv<+.iIlxٙ5[ GFBWlثFѷ ;^{ x@a,*:W,OfE(৅,w} B9`B /؜w;#6@QjΆ^ozk- fYb&yyXD\ױ}P6AVuȄ!p9=5l٭KTFj(Wũ \bxiCĹ5 g:7Â{-:NC'(ssRtܻ \CPRmcEmƠ@ucPP*X$:4T+xD-_y~)_u=C~:־>Hϒw(xtuKk3EyҚ %s`A[r9JDGԨvpmjbk^P,5Ow>Cxb&$ .2_}{cEOB14%_" |b7*_av0U<%i;xSjSfG@QHh  wGg<Ș物yvd`?Q"ѮX=gۆL] /^$,{_9I9;lXIuږlAÃp̹h0":4iTaN$J& ͸(8Ǚt>FSJB]9F%惼-x;Gc.>ѭ D|Y޻ZU~N~uIq),`kz9pLZ_[D,.\`WOƫpW)R|a'7$'. +A6 $KsQaI.Kf PriD{3 ^?tQ CR$` FjY 4F"P$KɅW7R)%rΧ^<׻=k *HfQqFK:DVQ.#\Obz OZ+GG͓>Qb(ρ0ڃ[Rٜ&:K"Gh[cg6I3IZ+aj*f5(KQpa:]l[gY]'!3%~TgO1JD}+}ΈZ7"}7 i?ƟfsYbYU#.Q{G[W7sgG.XXzۂہXe=(-Ѓ)|kk~5VO-#Pz<%V~x`$'mw\fpXZ1#:qN(D9&0|gv7A` I&**3g?KM(zJ`$\}tzg4\vj/}oqux5-빁(‰^҃ӶJ_>E]=‰ }ɛmMUI26-eݾ /f Hэ [gpU6OT^'DԚtB@O6ehL5g|/Mno: l{Z1UZujW%fdc# Vl΅&B I O49{],$qe}r\,ӪAAn8]yC8h[)ѽՈ!䂂~IvXLP*UC77h\-pG[Bu%>.yg3V#pǑj~ w4hӷU U/ 2Gɡć)&*-\6xC >ǂDY߭)dȦ"܊[j| 3 x-+S:_ )!VsP xOG`ZֿDza淚hY(,3y@;s+]tddp]Y>#j&mRԊ/yRfcfoW-Ep +rnv+ŸSתh3>{4ba!nH{k$$?Ar W7 f0RTA -ny$4Q.KM.K:PS.S@~H^c 27LIz"(r059xHY7=+Ϳ@&~,'A~TXu>~6*zx*[k"GrTZןS y~-\;U #:?Qb?wGE0ZV ȴ($jL'y\ NCbEc5wX.Y'6wq/ɼZo<}h=Z}= 祅8korBq!O5^7& ~eӆDJEWlfs/O;!iAV 4F`C<1<:+ ƭq v.ez 9j[ޱ?$DSeڑߠ h۠MX.;GL^M6f'DvJݨỊ- fb)wH;D t[}ڧ҇6el@L6,q@9XqN0'+Ub"iHFv@AkD1&7bbGÙF %W[*0n\""tqfk$_)Zm|\%$ w9,8UdOTqh O=PsÌ`kHDn`iL"e1L_ fжgLT6%R(T%Flς2 xCdM+UF1up8%x\g!OHrbwK")F$8(U,(BjyU7G]!RDW`fz:AWex@ ,P{O3"oj}I0p7bO&@Cbݽ' }?>@yiclɀ4ʧ{{VotGێ2!Y@0Me= qK0$˨+㚒"Qs\2W !@֤oQLk͚3 %\O -OB1\<H!Z\{(bú](ּ@Q+ۆH KtC[Ȇ M ^+,pp1o_=ia@kٕEZrqhk I쌶^k졜.F#sqۗ~db-É UQWv֣cE'ۣ`$5q2l]r*5g6[Ċ|9rijÏ;h+NWh|ww1]J'Џ)8TvѦVx`dzE,;2*>ڃ|1?5iF,~A l 6W:y쒹Nˆ|RDO!0]{9QZHӬoގngx<h~d,9n#㏰O&NbKqzH%Rm&^聳qx֕nr9jE=`Lb9cYcJ}?'uäWh7]|aS\(`:im#3XX2 ڎ?߄m-ηBwrJ7Dyv{'l G޷zDN'e234i-0AvhӶsxp\Lόҽ0A9{酚:?.񯩲-EJ;SHҊufӹ.8U(t[v25ӯFަ\;QqC])ЏTAIt[\YVv[!I4v !W,`=YKv=RmH$?)S'z Ju}%2x*J K&+rD@V 1mY@FC2A6"SG!V@W)._!ci}<Q YToB%-:I'PK> ]dfbNo?:@A sӬ$?i[Xn%E!5# ~=0 6PJ٥!I&@OOpcۦ=_ڲ_ȻpRxO8D5ߪ eg6]I^fg$]e;v÷d7O緱rIq-XgZ=}@=H2 }CMST2@J'A~0neT[n2z[صs KiѐZЫY^M,_s0JZ%iOLEnM)yRцf-0š{ ͼm{ܞ ddEB2D>/Crݣ)jvlZ>2fzM@!7?X({ i5=s3\#͑Sd YNT؂8LN4g? e {9_X#YkOu0ZqU5'E`%4؋xX\/ޣMwb3;F{IE}O'UC85~U…:.+D(mֳ빚\-Wc9p ׄ  mW$8:ɰR$~GRBȲ`I!>Lu2y08Mޕ5<҄st0/ ׬z8bQ$9#*4ɡ j N~y$.M , Pukt0Om(u_ӹG8d[]w0܇\+ʗ){9Hb{keWj 4ëzB-4G5VDԫZ[Qޯ? ,Y)"ERݵ,Ol9V}JЭ~  Ut!MvhEֵ#HH0'Ϊ]}Azw7USaB52^ 0ФSbTrBj# fj_F̛y& C+"ە;۬ L$hW av #O t2Oc}%,`~R{,Ĥ1 YF]V90UxC)Kj&|Z0)H^|O_-n'>`8(';v-F <| pfBy]} kpĬx n=*S\5}FoZ$P-๧Ngt&{dh%'O )Oדu oBWˉ U(ͳvh!"!K +^,Ƀ?q9)[ anwBE0CnA厴Wq5eg+ c陻&`?p©>XrO~W7|k4 " ElWV(1Յ4B*MT%i0ԗ4 'm8S\LZv5rOQ\坢󀍋mj2D-GŔ= 5O AKR Zj,תlRs m-88EO*A4 XD"wf˪3?Ea1irBǾ=c.%Wz rWc02+ZGU}LxiD(*:bZ}5/pCzwZ*8@>)r-G=6!So" 5}z]0,ۆ%4+ف5uUMs o QYŽ Im۶R'MOш˜bߕՕQ0ź!l OF׶]Ghmm2c&&[6 ⪠bUNFHv*~: >rFrBa@}bY N֌T*" ˸,0RvOaׇE%< vC!s{y@C 1f,S6}z$Yw̯v1'erB6&iۀ @67i"j/J0ya1kI3`//E#9ƫB <Ǔyė;mrzOdPS9цƒa(ϗ2d.t[F .+*\/Xi~k^GIˑ"b?߃wKv)%10/)bcT861<j/X/b{jyޮ!OߒkN(= \|Kv)Bs^ ԬӒ GY_9gx4N@Yܴe1t҃; Dc\Nisָ'`͕S}z-q~3A ?UÚמyf{@OG휵S"E'-!R2L_dt7I~ˀ#&ԉDLFĥmB8ԤH5Ǧ`#q|}B͘f8PɖQGlNM/̱ӁD"OOncţ>5ՙ9D1o(OuzW"8;X߾JDl;pNmYwy#c91NQvwٙ 6@ʮí6~drF ORKh:EC Hآ xr_NC%r!p[` :ZZH`Mq=#+??Zuu:S+ί< <'є9!F+7le a2]d&A`ióDPg0+PoKh`q0n}~t.d r"9,hz9 _[! FQC|7]Gx'0<4"fCJ]2YrpqZ@OJ!se! J*=2-$/|dn(ny0rLa?W$t*y@MB\-rG=*UCO4+G>ŬCG~gf Z⽏‘hYvCB0F5p쟞P#h a~*ngC4$L)~$†K5yzr|&K*xIz[;Q~§ &Y ى\}\w7 )KvB1"H Ǯ $y~n_CH8{[yxzy~BS۹K@s%+_A@~8 * 8L,15&>rOdR<KZI:{˘>$%>ϯܡIтX\INDjzi< >7JrTCyǯ6)bmu;ع82ԡ1$mFӐ7qm[ձR F rpYbPg2@+l"_$"qelK| "x賺OJng9<^A\<*|kS⤸3E>%Kf5HF/H - 6`fK7Zß o߻.%ԇNp<,m`g,zυX'!Ok)6lH{l6=+/ĝ'EuqOJZc>VA^'@%\,`Cي "Sn`5!a{LڀO8li}R%U %KNRU9C+C#)SEdacQϽcE8(Q[=ïX*F^9.^q$ d$`|KI6vO%#H*7 +7?BGlb5QtE(zP?GgR(N ;XxisFռ#S,֎#g(ۻv2a#Ogڞ id-CsQ_!q$aFݵ_PnـTN5ai > ^5y37z6TTWp;UR/,9߇I9_`J21$1 *Wmj.:7+^'-ׂ9b◻-)sQHf5[$ɖnWhf,W~RU2Gn@soUa~fw3DW?aW/xscsؼ@-^4.=B?=1Cir1Rۑ\ )h#Mc]CC7_s6]XRѪvHD{oט ya/<׎M::s< 4 ?$rI7Q˥_H/eѫ=bn,mvЌ}Q]f;7ΫHk~G-&Ԗ1b-oj9yo~ n#Q8~%QJ.K@!Jw\ƬPV ^WַtH7sR0?h@8j'RZ/TBrWRx4_1ao+T."%]su(pc^X (@9sd,/d.OdɃWdfIOFZ$S(qv.P\zF5u+*؋}tҌu[UL2&[ #xRyiaB& pFq;W0X ) ~M g) `lduToj?ea&-< oZD(H[=&lMA}Aq.7TNl, }EMyPf=c#/ wAzki/֧Hs4&KPy!wo[͚o1dDu{>ah}66tbU3CޱH3!oo3@j.'nFHg 3ԥƜY\ l*)ҡ2p q offy H$=xj>׵"Xmt?8;bRڽۚ 6sy{K8֊uOrbL*SXCA < =nq 'E)?7L}Avg*qfd ge*%CЗȃcyG<'uS)q֯nV ۺ2-("PjV3<@p$ܗ QYP+8w cyuH8*DRRk7D m[Û]7-ٹ,b_,YQ(<;Q72t-t+Wxgj GY,[.Vh n!ףּs}]$DF7]2)ٯK4>%>|7_PfAi oSW.)wQoɕo[]`*Tځ 壆&G'z]#ZV[ӛdɮ gG| fg ȭ7"KG9@}tr0 qj)X78Zb})dXyU>PR⺂5;"(qrNmvddcʿ.9;Ld>V4^D&b?X@{K`xkpoU'zI|esc&}iZeGq;C?ZhYۑAm.o>@Arz'+|*:i$ &Q}x^^}{GOT= 8\n=Ƭm*S޲*MT,΃][긩xJK¼=Tlȿ@k94d Ѡ5kGu67 2fZa[Yhw:W<@׻,IA` f7(o]Ct:ZVFDqŝ(Aq+:]Q]W)9p>;ccqA/ܜ4o8_Өq}P.~VgW*[d DfS~dv&a4"NMq'<"9% k2H d#i }; Zm)8:s\RG  "6( R Vٺb?BVAnהWR)6`K(ةP,J> 703 [:X2 !b'BtX4`j@huX6m~|1=`Ul.C]Qe{[œ!-mŒ63]Mn2i#+H(T.J_ya1cmhmOoA;a3>"E̡LOxJ05>2r,"a(7ܔfvd]S>j,W;'^cY+{,YsuX0e= %CexZ5FDtS,2 ج]?T IW${'P34M9N]_r >ab-8 " ?w_܊dPѓઋi\x!&UT? GO`hJAᖨx#^?,jaxC_8QKC'PPJ{x w!]1ҿ< Pn@eQh`l塜ln_I~Lΐ 5Q) "{rqW.5 |J{CPw%D_ ;^@a뇠_̏^I#eJ)ئ9 Jˋӛ[R6f٫1 pg~Mh 05Spvr(+A1!U]rPX| lϹRmF[LY:ۧӊݹmKmU>*֮-T/hiyzl[`hq֫*QG NZ&MdP$é4HWIQR׋f;wm6\\cgt&/DS%^@g4ͪvQBb@YQ7:qn8-R57$?C PBu8p'#:(P,?%?dNwڗn<ȿCH &Zw0['OfNAA9ҩ; 6WiC8Qҁ7_76icju4KsWstNR\܊Z.1??"EY_k2}]*\UUk:v=+ Jc Zzc'$e\Ӭ7ڕVdƤOo ]ṵ;'> X$1)}F{kjD=C-5WOאzVK퓈O0DWx_ՄԖ㈃|;1S5~!}W7M)-Nx$AYX&lrNokg>קxV~2_3cI@h&Ude ;\KS%:!yl5X $at;O{RTcܧu0UQPLIi8|F2Po0(qaQ){TՏ($"WfanGQazS@ÉVe"<"SO*cvN͒ isT(f;?6{&H@Q}t}^ (CX@;EvQlQDs IZCy͍ʹ![~&Q_8ZF^CHwAd[ MI0Zr 5Z0"=%@Bcز UDi2aH(dr-7,zUFp2Ys)ClErְ3hmUQ(]X>Fm2u+Tc6S5!Q{7O~ZI2Dic+H&g/1z.9tÙq[vbsZ-LS-YK1lUݶg!rI)|1dE *<,%U0A(T)TiYl.yޡ +.\Li9q9/zWFGE\*OsbƄd\6tdhZe6&nLWig̩TzI1ar,TRΩ!s6wfLY/g|YRI0R{rv(Dkn0^ V`[U>Z ::S`GXS0j7|M|:A|>U~&q)ӄ[jC(p2R#${yc$*r;KD1 ";ᘸѝHlqtw2#ض͟2Zbm@C "yC4{;krψɪ?ICRTl){wY;-A=y6Đ;Fw.9áըi/VT[uiq%'LFEOPnPI9&(ÆJ 60wžq ʩʅ9̼&I?g370R sfZ*Kmf][%%dqP.YOݓnE~6s)#e>䧔^|싗6)$ DIq΍~#)ulSyeZHET)BQ[@q;ÁiV54BG R\ڗyn)]rމH}hH_.i:z>UYB 99W)8K߁i|Gc^ݿSN4}Я韕)=mӌ$"=8p*$Ŀ+T=B%_0w²dN Iu5ϯU9"U)+e! +ڠN 2-OG"%Z;F"r2J9YRiG=kGV: ˾j_ z*w ve=MT-@!/8x!yLqHe9&'lXr(tTȮk=tp?i1Vc:@]AQ2Yj}=oa6C$^ "x.k+<ґIt. 7a]޽%:)n0nd/? jh24r#6"HyLr9SJ(MWx_Ʀ뜄g3QkUZـ@5d~=w[IRcjx:9 8E8GB[%0T ~9۽J*pw_;&J Ȳ#$\F.ZJӀYŘϟ p0Xv~CwVCҚЭjdFŷud^sWe~'㐱h>Lzٝ!OS4ΊZր^XFThC/<1KYwˏ Jïz-뎸a+.>֕z s 3U9)1`h`[ݻprӚa ;~D'Sig.k!1]a'O_  z1f_u (ͪ9 uXw{:!:)|qGbQEf"QV$'ٚ>#؛?D!fkפ %p M&$lΊ)Z9 ,}VXc3ݫGx@ 󷠗YOB7qJ'#9>„:Wy30!DȀflSH-]W4)SI  \{8gNhHU oi"j3૟dbqMge*fXe]GOv3J Di"[ft%dftrE[x#5;$ _KFcVH F~أG3Q M 6uUyҹ@#-xGH}>ZM˖dH|]]$Oi+γ.yn`X:V^bD&ӿA~ X̔%Q%S/K bGD {z, m̏~csF$2e)$܆Yy[ݺdA{$4#߲j:Ç?g#vl'ڎ=|IE!OޖKG9X*`wU-f%:cO?>E="wIEP%p܅!UM:%JoPT*KJF5` s,`!^rbߊhw-IJ@LMMVf.XWRJcuGo}L$wL\ɰ{e:lmKs-=ڢ Q@n#}GwEieUy;>ȍͺCh0́\O՝!`0?'*i?-3ǡ^S_ULG%JxV DҊ$`;fDjֱ3N!_Baju"7VCg=`D35!Ϳ끥cE 5!!a 3e%}s;c8_8TSb݋ьT_X*&{JFӇ]Ae˪ *}r`,\=Fka A~a!4??r8š~>ǨmH4Jṛxnxm6|֧ Y!C8FhR|oEuU[D۱\T {=3*~!"Xd$nzv&jE`\ t6Q^,r?֪*+m[&aLG8W71PΜ#i|aka%Xb4S+]|' d MYJ~6]=M&'&lK(M%bXNs,`6vN>BقV⹣H'OaƓX1۶s-&}} zDé92Q/^wage*GL"!%kqڹ^*j)vĎ.LiJu^cG dç?} ~D )KidœIjzzܭXY@Ƞ}:a8M4;a _(@l(-5c[.X Y` 6|D$!T ̋䈄2FGVi} ؟x#. #AYU^2+twIBrA.lkV En5ۣs4ӇN9-emcdV1g) AFj~s˃&6g|_Xj@gD&@B2͞w1-@N’$Ux(=k_6k/^ӛh{Mt"ф&4>zM{] v4>^a2_l4%QWKr~~4y [%.orݻЌobz.1Hwf_$k1<.. ˶OHXn$DƯ^QcFU:y60ڲLȓeaNa zRK?zcd.o]Q+%-\iȮI⛄syf10hy (?+{d}A0E@^u֮?|lKiW8]S8 S(ƲaZ}JmP=<ǑS;jN^Y"^T6zV!GnO U bu@ygD|s|Ք?H/ LuT{ Q3x$--~D[{]PF+- CyL 7s:) /'% >?6Ai C21b+%ϸ7l+Pg~!|јON![ u{cpMkwʌS.0#esUF` ȴO:5,Lf 3 Jgk5m!RSru1ش7ܠQa2z*>v%iNnXaO !WqI$Ahˀ*O WD`mvCjW%P*2rRT,$M+qYDCbίYWkj.ڝJEAm(w-,i`"> kzo Qs!E}tqQ])*L~R%lyE5t3`# e(H5.\5D]IJbNMDxh$]YGEȚ&N^:!1peV^\'e"/,ۊtg^S'E9 墮ZT] .=e /ieH_uacR}1gjbRCb9Fbc1E-;qY7$"Xd;kQfghwPYwMsLzU,:W0tB賜5A("+V 5փ0)~~[j| .m HԷ5A(1gEt!,ؖM{0~.X@ 2CI۱|2w~wT$$Sየ9G { oZ^3lzoB*)6*j[Fc dUe{lYa*~lU/l8hlπ3tz]e3XFuo'Jfг?'ř~Ǧ[{keo.F*?|='I[.$v2Ȁo }? Xyڠ@ThW%5RҰ5;XVKWjBܻ&jxpcUwdu-Em4$RO6 &ga4n~$x6s[';jx&  VqS9EA E3阴wuFA7u37-2M'LڛXCO}%;^QpQ2fA[yjQP}!k=lt7 %PI,u}ƈÎ!Ĺ/%W]#+{Ԧ [)=9 nk CӾP@T5ye)Ri>jfre5*jan:nZVN":ƤY)īVi(Ǎ˹It_5-ܠ*҃Ï ĻAl"qlSl4c՗c6*$<< ]!W@}hw>R.U :v}5f ^>ph `? do#&5/,\r+FvRg~ !?r дjIN /͵g}(Ű*\XN|GpYC}I-2Ug)Sh5kH(`tἦpُDƪ> ,zase43V7MaR23ӈHdm.m-Prf3~GЋD4iB\׹3)bzX~F7~ɚ^nd~ͦ5'j H{k|ԷĮ XE| ư왎QM.IFtJŦ:w[#AiSR<'~ ,ersN|$ <{ ܅~Q(Yr@&|sЊQPz40qE7+C=avWq*K&01n8C"Z:kdt8*ڳJq(bCiKŏ/7qL*Ww'1(zdp2T%e}YmO VA~+|M$wMy+k**z {h DKp/$niKzCCKC]+$=xVBCxz+;,E05YW&식Rzֵ`4*V':K:H'+vz/E/_<0`VUք}G\2y: !p{lk6$.[ *MxNh|x*.YX>-ϡ^Y ²V67O, 1B%3:R06Cw{X׸!QbXT\/Q W{Ztj.+Fza<*LlABEA:V) NakwsoJYM-EfP*$$ʧĶ[ ), g+E9UЖ)]s/ ~ag@(a8nMS_R{?/̧u4 ?LPNjBDPw8n*ZxWr>4\m{Nj´.?z-(ʞ8\z$ck{f])LW"Z^&X]:-ڳg-ܡݧMNC{iՖ"GԥzB$I񊓾+,'kz PJܮFN_pOv3w vTpt3jhL2рĴru:6^C{l["e_=uE*<73~l\wU1^1|\ L<\@<с,eZW,ut0(g' @^b_W-HL;\K]R:FI9z^9G@d`Ni6 ɴ;e+ E+5@os^{Kl?ʧӌG^oa]dO#OR ~NF[s}7*ڤzJa؍F0U.KmH`uWzy<_|ƶ*ƉBiSmSH *6ȁd#N9KN|I:#G .fb 2- lk&'܇xIunjxj^ HYa̮zŢڦ!A c*^>07H`n$KTtЁUNzf!=f@:%69.:x۔Bwcmߟ;7W3gl{T.*#ُ-MLJ&$d5d!eFhym03c6nv߇Z\+zȒ&|q%2O9ɢad NB&ԣ9h5ݛUژX:qY8cD/jb@ÁDP(Ro+G˘p;g)ږ.l ox;_Pqǀ2eq62*X}̌f0X~l,L`8 E#{FDJ)PCD.4ﰹa0s0!O7sT Pv}79X$>TVdF,覴}4b5`{Uc3^cL5,MbdԘ6Dł_zf52hz"_*!b$s/F_B9/mūsGfxhBγU`dmo rLVE<,+* 5τ_&~68 ګd6byҖ)j1X\.v}^;袡\rB6'G#!zp.bK<ݹA_)(@Lw0&Mo-+ mH. S8 IJW^7\ڋ\d;vJb|%Ex$*NЃc•= J^0 `Hs!(I[έAidfZM;]%kU ^oQBeMbN3ծ^Qh= 6Ki Z㪔_ bwϣjG^f'?bv6S'K8k銉| '$;{C&4t&Id tƭ[^mavR2~ͷVG>H]qc`h=; pg%`b6,it%W7tLcDˉGdJ4|z9;qTLM(Bi_l]] \ ~}D.C/aͶFVczV 9A^;K*~lFʭUDxT<2'Mx#F&t0`Y{+}:)I s> V|S@AwUmL6'~,`Ds2z%Wuy48%2f5 ;In.t k3(|o mA9d$t ܱY i/Q+#|jyx" `hf֏V昒nZYWnY@[|n㲫YIbZ ! >j R|ŘL2ccjfN 9'%I^>y%(Euyܳ9vlҘVza]TG+y&̾E^v8.Cjf/ԛd!~{%67BSB{I}EdUʒcg7t]a:\zbZܻCR#xgh* ǻ`Y>7(aFbddUr 1ӐL?ϻ(s[lHA1|!,"]f.q8PM!/,zGɍkZ9[dcHrt}'R۷1>lvjC9tw@oآzVOJъlٲx6lT.tY)I^5[ۖ2cb܈*'} >*ѕշXKUkcǖ3d;kߊS 9O r{~7=tl~ wqFv=*?a}IVN4P9=qdUZz8$i0a;=v${m\.sܱvˢ N# qwC!e( Y{Ą绺yַTV9G(7\&l#fNߨTS,n^qVg~UatnfsdLyh~>LGMAVUvȷK FK_9ϙ_80@!Ve'gߒ5%gB1C!$ ֜?$׼,\̢fӰmAXjlӡ> Uf- pd8uF?zOK0{Tje㾕Q'Xydue!h.%7֊尷w8W43TwoTZT< iWk*C@`b1ed (sfՙH.Vdа {1)%?'5dE-_Y,*M_!5ث HYvls(Rv(Sߞi֛Գ$Kާ`ϵQ NL=}~&VUIX6dX&%h҃F>?pcmTvM#48@:B=\Y79Dlq3k$ m-:ѪxVu~+ 3uAI)ްZsv1FymqǞ'jykӕ]Q4`}fhc($<@r &g$wļU )+msIݾ˔@X,B{&č;Bic9^ e-g_Qb$(S7?aB5 / .g!raOgħ󚌞4axɾ\BKWp ]{Wk}[6LCWl(KoNC XHZGWA"OviK<44)?RJ}CXCᢏڥ1Nw<,q/OO|7]s."O+ө‚Р %͔9xN\:l~*Nc_$G[ܙs\pu|-*K? b.{jJxD3No*uZ] u?fiH{FdIhs\3}-7eפ뒱>E$exRp͌1h!I^3"hQ7nr.8/؞^~EӴð.NT7qBh_iuBj'<{sjS3o}_ު:fGԗHFR[MqqxzpT]G1 #NP xGS& 44;}HRPQIK{~Ez C1> WNg͒-[nc,_ Al:>nbSs|@,ÆA"f6, !x%of0U#ę!nBR9,@[2ơOzFNQ +W|r(f"] ,KZ'5uwMmP-D\03U4î(ॊ%k Ԡ m }G/KiQF)-࿁4ڇZ:YH ?nu;ߕeWHZs='\3c9 \HÇIC:Ŗ&_""Ȝ4/=C?';z>cRd^Q9"%Fz0Ł/-yQbm`:w2Y7&J>i|' îsuindMJ&TRFC4njp3u6֜q^uiIMG0P j/TLqAaVS6 62xKѓ{ɗ Uh>W%r&q*(@]S ^e/?4zCxvwS^tˋglut&d"JV4ejQtalK,͍7"c~9,B)z2 V & ~ ެrƛ N ۡi _ꩶuYfً>Nr%v- HGD?*S"*ٿXl8!oZ %hыgZV ބN3l-iP(WtQ(Xf!JnR ;N c|BAE$O{Y nz_?{5`$PiZּf$2̖1B^r93a8EL:/ 9ܠܺG[3 akl]Jn>7bXĶb tVvkVSisSxY һLxު !|P^:;VjGǞ8b1*VC0Jeԏr݄R}T25 )N !Y7 :,kDc] m+N}GyL;)PZ)Z?Zm%fjI7R l n3(IDŽKj BMXtI̾( i̾7=쾏ob79e0/AllNǹcFDxMt\ 9|9,z+ k4 0of?cH@M +Uq@eRΌMKk]N>('Z*} [* e/} SDpEy@ ž@+iH=.Q{ɒGO$ }2 `▵ݜ͊26 hJs]U,x:9?hk'ݒƫqvu&g _X?NuJ:6dž]/A-Do ,Q>k68@N~8~T6 *0bK:B64v~DqY2&1>.6j z&Y 0<|C^ZR}iE-՗½S2SĪo-]5~VWЏosm(kO09гc UX>Ca/{SXKH$jN- #*rL!\P:KDn0ֺzZljB`N].>gjhJRD>,Ιvqphl@< i`ݡq;Ԛ4ȴ<&HȲn!ݟ$M 7$l-LeݼO@R4š,WaZXx {)S)~<te(>.nU;>Hq#wÐ⩾g'>^3Gf8-YOjGǵ@"0A;/%Ƣ+^hCyƐ~X {0$>)7Bj󆻕}4S6%6|Ӟ1?lS%ӳ16Ꮉ~N=OA3Vz}az\M4}lYhXFZGCgc3mtyoZp5Hb8F_E죪<%֏{auܢhT𧍝/%ywfաٳF@Nf'p[16P[ wsaj\BPlI*䬃l kV:$S/!X,U28C>C;D+UpsPýSF<3*E<-:'qE C1J:kMg^نZݻûL*l ̤$]%(4V۠v"KbOT}H":;L ᖭ*ٯJ0V}|A1ذ 1~Z?,N6qZFFI 'Md B*IuKDWf0ƄZZ bY'%c 5ȏg2>pnpZ=rvq{lPjP/6M:yhԯ. ϕkv eWMV 0C3s$$|Hک3?rON$)ŧKu׾Ih$ݣp〹-q5(pRTwg$2N0#rLЉ$ϊt'ca]/j`,9 +sχ{沚-JJC7fp3S(,YF؆iK:D'˭9Ø6ah+g2MHsF0‹G)_ݎ,htp5~6|*Wd 2QcNk!yq('-A.-zILd\4Ft6!\$BaFu+Q`FxJ_# 2Ob5d˪x VKB-HEm 9 uKkvBE&j̐s@@Z+ *%I7ԲvQ"9=Sݦ( N0 n ?)*8Nit9>thn%I)ϸM6_aL3Zne2 AmO LtG)̽qw%Ȇ\YU5L%xs\!2|@ ӑ{He`Uq0P`q6Ini*!Yf➎OlTGtg,=e僔Mzo^A)Tk}Q4A$S|(m*,G7%!KX^,IgMjAWƈ:&|GvN]"& 6ɅH Jj<;aˤQʗ(\E|q aѐ(Dryͤ?ð M#Dȟix$IRŹֳ[[/u7d"k[Tl sR%9v kE%)6E y}K u*Jۄ:<>3^륕8%VGY_%v'cG[[1 ȫԱaV­]*c!qIFj{IPt_fgВ9䆬 ¯S\KZS,jh ϧ _ƤDr a3!@#=9r ()O y2UI(ku/ƛ9ĎI/;g͏ҼRF{ "UovD ѐƙ]RdR 5GÜ;v$@wxpN| {UhgqtQnmxxXqL_kt0NE kRS'$jtҵ)-h*o~Yy}#$ϦѿfXd02z˗|-H >%=7@F$C)+Hx\ū'Uk^H:qH4|ݿ)dB=mџXӈM98Nk'СS?4d^֣UI]*TbB#:*&re!Z,a4` 6"XRh 2DPk>{AMΗC:&19mOd 29z_8-aȎ1GİP=aPhO$-;v`"JԾJR쓢̭vG61uD2-]-;ME>e>QDbVNDߗ昤]bwBO 烈ZĀJBugUt%85;>LPziϧ| )[% ]XXuǓ¿c'(߇"3Xmo,]`A(6:zs:ɐّ﫺@s zc٭ ;9ݕi Pztx 2jc= /cb'YRԝɐ"tZe9znڟ df/J@6>:`*]\Hs,qBwΆWvqG:?ɂ0 E &RI_9ٶKrqn_m󯮁[ŏUBK;q}MstX4$rWQtwVc"/aex], kXrIO^G<Ƈth*" wXޝZ`h@i 'ߍ HЂoH|Mǃy<5Ԭ*0I1z+R)@f> $A-2P/*T)/ܥ >TtŸg}#hAT ՏQh``c;,`HF|`r%DX׏d\@YD==H¥'ZdЪ}1$ƞZ⣐GnNj2=w& 8.B5;j53>6u<N;mc,&*7+v wYHDas4<5q"C2\nf/oX]BxW$ԏ zNkITN8qHί90W츏`?pk ~76(S :ۘ) :a_Fށ#֐nRL[']>@LX˳P}Dõs5i4ҷJ9@̇u)[~8=W-󐀺 |sQ!pnBO̶Bꎉ,<̃x.:A44Em^K>624VjP  hm,#ly0b /cx!@0aD1V`އq: MF0L; Qf0t"2.yt+y&W2 BORkS⮓+p׭@O:h%B,+)Pi; jVcgo:Dmعs |~E[I>~ ġ1zz5Rth9"l ^xm{`+ V`:62^:YdaW: 3iaR3T[mNa{ĩ<;s1|0vkj58rv[MZR H1|a.d.Lp~Jm 3zx?lf1tN ~3*~qu'Qyu/3Si?.x|*$rѓhם]ܴICў5 d+UaJ`˝LL. E$8h帩 Bmf='Xl'7V[WBk_1)7wQ8ރ`B"tVA-CAsMb(׌T ->GRU,d27Si\J CQ(8Iעִ%wP~?UTc ].\}*0QݞAۜUb8vu A1Kiͫ09Uuj~~yկ=L4&krdnxհMe,mz lvh`ϧ hՉxϘ,maaOJ촗Z/>wu1N,,(=z/y|d/Ztvhڰkvzʯ\9'!n+ cBcD69.3dOw@걣!37pKt<|aJod1ߥj/GtpHoU"&ښY 8*^pF!M숦3GKfOI"2q Twh(h 6O Jc? < s3`Y+-x)Bt J8GhЯ LxF W^t^iKX#A)e2%GNn~+Br=xcx"@(:(q*WllV_j#:[ Ȝ+yS7+C{]Qx!!nIߧM_>e=`[U̔c/[ӽ i/Yɬ+]aZw_jF,OUa3Koq[ֳd>?m(«#OWRCXq—mYWrfkB'8U~$`r)^niFwǕsasT X{5Px֪͋lsz#뗁-`z<ҌaP/#V؏{GaWg=Qc&SXsF rGcq!gz jwG@,Րuй|B~WuhS"~@^)gM9%PA E0lV/LpH Z1'O?'Db곒).DY~ j!uy?/$J3ou;`X@K6PHOgmh}{22>Y81O2cJ!z둴bCv ~yOXxp!{m}[ts0IxVvHHdW-="C'?6>d3 8R!&c i=Ի.;pm9NfeN-ߖ7J"{6V kH1֞P6OlJ;B ~+(uTU+8m|m3;93<[SxKXp؏UzJ^;ʦFx %'vUy⑻e(>4_.W `zPs]iC-:ý&ں~].N~bBfe PkBCUdjB]nӆyD&-bjؒU (`?zkE~%PjCv&x?7mG"W^*D.F]6g{#}tpw LwJzn%̵@~q~G ԕ@Qu M+R^d}ɾ=TڭƮ$].a 1xu\ْfcC;ܤ΢@`^iFu;)>MU~Ah ֳu{~/g)1Tp?wg[\b1sc%NQ1IÁT\,lSKWpy/@ X& 9bS}q1Hgn}}lWg /"L7DOmV:u,L&Db7Fj]i{㣼e]VҜvm&*WjXDJ+Z@A?fzۜ+oCؓó6FdV6yb0D";1T$ϫ߫uw7cl' H(y;}tJ6sSeT_f4@6",pGIy^s631*',3r`I\DY\T%jTŕ%uIh+mƨAVZ#I+xύ@:8 {;z[ަK˿c%}@;IBT>&J9\cxd* +םij\/cʥA?)YhTAd=ldUĽ}ޚK8+(݊Cby1wa<DŽ%_ㅵN׺Yy$;p.B{CfTA``Pm!rk}}Uz͆c{PД.)Ejasܩe1; eW͘X *,rꏂAr&22/m2# I ڿp]Z `RK?<:=6tt qS8V>/ 7@%02I*9@/'b|߾)0QQh#VZ77-L@{=E=t45] 6'ĕN>_(]n_ 57n?9=<)aIEOh}^dRd| pZ* bqbTd!)^^Wl">|ˍR#5)Cgͳ)raj{L@ᬮ/Mź`Z-CίhR56l(YQ)eY,_lv!J8A.w>g6^cv[2q.a'7Up<Nu5q[˘ kWu҃X R( !&'vؖ0-k8n׉nudZH4ˡ I&-ު"K w0ixLxWS+/+\ k RCW ~ *RƓqnB ݺim57CO:wh2EnE"b.3ӌŤ\D2R1kv}6s9@ڳk7D`MX" >#C!LdɆ<*H:O)FRۉWN>'bMg65jtK$RbLJ0ތ[\. V$+L8>ō> /ADtSQz'rn~,GDsKe)+Pn*ɩ\5} ?_X ?F 6G%˜SrL'|jARM#A?t6Rt}lA*)B+7YXVޅdI5`s7ͷ!̈́LNHR_F(Oe1)wJgGf*c'-xX螡/ۧ(PtzPdI9foIXzyHtx/a!@BZn.Š~Q"aBK5w߸/㳕$A w{+ n7zoĎtojFV{&+N,Txtnڞvn̎ ~yDcdAR({%߮fC(DZqQkbk I#@ԝ0`VwPٯ=^-uZ)6~8(0i=э]Zr ^MfJUϔZ6qTMfr3jʷ}8 3$7C3 <0JC:o@)>ynzg3^éD,3zb==(\'Җ֔aCa&F ɥab9xs#$)gBѺ +w#|pT'ew e*|mZ~?ne 07VvTp-s|P \Td ,Ew}cʁ 1^6rԲhT6Ѱfإ _eT.Se` efJ:X[ɠ@ZbQM.dh1ڛcU6807'{Àr`oOa<-U>ۖU ~"@}rT$7}K+as)BD ɝU):` ϒJ᠚+Kp֘U|^GЇ|9@QaGEH8z*?Q~)P xW$-w!֧GIw'?:jV<^X|5fxTA_XJƳ4Kt3z!(3S>]h$fx]%so|:H ' d[q+Lٴ݈Lt"^,+Z¨EŤ-}}E L(u+e1xDO*`3fY-6%aB͇`D/ost O1C2 c)14lKV"}ws%،/N *>al=hykxR8G"MJӶdHRT]I/+DS\L]+p "j jrxt63xIPnmj)6MT7 Q ob8:*4> aUc6I^,346Uo=_ tg@͸Ɯ4ԌoC-.{—JFW$Y~Q^ku"~쨦BGecAZ:o7k49)=Mn v';>o*D1 U~YZ}, e쾋[-S^;mmZm\b'Ó[b$L{"aܒˆM풇@e<'t*J`GlȾ*&̭6kH+Lr=P)仠-Q'|.XK[kR# / 0\y x0&dcAG!}$;|$}kA_1%O fBwcVxYD(cLTNAkseT\nmʧ\웻&5(y (חlI  z>7|zŵa2-rҭW݋'>.(Yy$4UuP4vv?L*r"N^A+-{]">pL<.}.ǿarN8Bin=і7CғT{ޛ,lFjȴ =^>;~=cW{oaaK dlu,mMZ~*K?yi  ǼH\gQeK:āL"፺\iXh)*#>ݺQs?2mDآJW8j,*h+gf,OeB"I+Lj@L8PEµcbHf=tdyBЇOxm.Xg;gyPc(ʢ]:X7-K}Gup81}yݑRQ‹B5hY>z ? H嗚9**_>BvCw|Wmaҹ4q\EeLw5UrÓ"nGRS?j7Mtn|~c7:3J$xVJ{r6Et2"3t͟]0Qg-USbg"<6`qz(o2J/|W[ ~+>sumҰ@.ɱ@l߸ު'Ӑ{.o=y \N)K? ;1gZtI4(+AL1vRfn gl0.Sx:-+ZۙT'<:px ʆ_ 86pK1KP;DdD}1>?cܺΘ&de8z/䅫-) r˴coc el((8OHhkӖ_]0ԕS- UmjŗM|=+յjp4xY/oD. d/R,h%ְ] skCiߘ^GUѹ wO*ӨvdLKMWA] 1#sPhQs9^6)vlt~RAG dp#?3qb͒N^ɡ鉄rin,:['Zy(@#!T'?܉S***g4 U9_Tz ,P= ֵY2vlD_ckxS8b,d.Xv],grvw~.ꃨ J/nf"*<4}Ln!'>2΄$Y65 x\r)e,ghoSQ \Y AAqGEjM* wZel_[=cџTXcэE<{e薩U=apk\H;'Re*\$?2џlX;'S|]2L4JbR|)Rs- r`E GRI XҕZ7F`g&ƺܢ']r)_+l0#쫰u1 e: J?pdSIG)3\9斔c('sf2AV-J^ xfbŋe=F2CM*pS9yN< !: *1O X>(i#Ur@:2I+w)Ot:WI緜6#<Ky~4h32>DJ4u n8e;_ bSOץWZ_N5b,ӑ k'B"I9!eF k S BrNF .)42#&&{P e5o7L](7Az$UtJDgMQnG56$0[_XB"ѱMSĀpfqy\sB)bIKHVۉhq9fWjȌ}Wy[ht82$۪ͩ jW*&9oK}Gdt ݍ I1R\  h|1n9WCV! zeJ$LRx[TtJɧG؅|㙘  r"Z@iL^U 9>-vw98ly0#vvf/\գ6af2:.<iC3gQ ,=$ W!_lE@ =]RO:!*&gpcJK/r< ~˗,4-?]XfTB#MةƠo("RMR<$~_B~b@;LGϱS ]Tfy+\9\|\SYzFn c$y2}ڗ_9뾯sZdm2*OkA/iCkÌ F*c 'BMU.l(@9Iv*vO?QvLc=% yϼIY>iB`ըZT!LnHNU=k^jg ohSLG']fhD It#L'dlL0!׷g%SPƿK6ӞN*z >YjgT|&6r*kߢj'n$rEMV]J_zݚ zEz&3S2G*3ƙ} UӈHooFQ2X5u5#ƳO60}.[ۘU2mws_Eelo#O/ڻjd5י2=cFSݦLd̊9&Aŋ=}zrAmbEg8nqm-NJ~?ݯ;{B2?b z0f2OrzN>[6d*⒭x(,P)xyBYkzpڰwϝ IL I [8:q_Λ3ʯb)2BrbaE"9aM)3/ua)Y/db}9>ȉ4(`}5Pd֫Ghnru-bH#*(28Iɛao7dw5iAmu۳Y>Z+ALHsGΜluk{k19fAEAD@/ѯQ kY.lm[GJn7<]g"}9͑'j ^$1"tVeUD,HoG aAĆfԉetr3@hyO?*)uJD@ (4gJhyS~`a(5V&!&aQ oX/u7J`jL@Rڝ +ű}oOԒLI_s:aPɮt Yے1m0XȇUxIcZ J%n  IwcakUcE˘;h[F] "2pwQ/!pzh4AY1LzN[7϶gdKh[ ,\֋Y+M1\pM|~lDf h$dbYK-0׋}Vwպu=lşO#R-8X\i_yN;&}a1$zM_f(` o0BeX@]bAջtX-s؋ŔƸDɧM ~ }7 h⽽&~-OEgY.ctiU|rPYHe(l_\rQ`h"7*W!jq3{3T}6sTmo&]$9iD{H}?u[_h|cB6ц!SQR]'$\u9*Γ&c ;Wʝ:|h{Ѽʹ&ÇNρDpNvpCQ}  Д>~Uwp7u9Ib"ް~(")˥ڔYf!}_sk+iJ 5?qjo1:6Ǧq`~ʵ]RmatȪLz9['4+TR|s.OO7.Ev󝟵+_ ֕JXs3M˭Ok2QE~xu,&w|ŢZpgȎg1خTPf(E+]wܾ6Gnd]C(M" Cfx3WTVs1f w_ƾĀA;I㈦L Wfҽ ATBfLT0Xl}ձdm|&z -Vj{N⯧Ařw#$݇K4XzcT<˶o10.5:.ZPFD+vS7}h@̿-L{PvbK} v]ڌLŤ>3Х!F#f.%xl޹zSEfiYtkk{^ -&‚?2 NaU:XA5c֍Etk<[)'jRzF|f![wD9p/˺+Ҽ9y h]O5I,82e;5R<ޡ! Hܼut7(̶$'?n4ջ=Maޒ}-@\[Ia/g@/oAjt ǜ?PE{O' m:cE~Gc_Wż \{'=Ab.&xfJ#̅+o/]h2nBTٷvl{facve/:U+%XǺn9Qʋ,Q=W3#ۙ=+mƶ|)qM Tx#7CN%ddU#/oKʧ޺~=i_$hT>4(LOI'3u [pL]|"R0!uΜ-dv]p89~Ϸ6,gLràS_y(J|JAM*N,NN'T3c ۓ%M]:)CrJqz quOD[E يyV_aőpfh%G T:L6U 9oݬPMgACLN)Rm2>.q{P*տ!\"<NLO q.>]# o♡tm -BʼؿҾ(*v7,6?"{]|Db귀(G)ONXWJ[).Kf/p;LH\Br̹|hKtKVؓ}yj; )ƕMK{VߛOA›ߍҥGvEdCg2DOnj*]a!V|pSkY C7*zyUUz8w HFmפ' [a ߕ>&⢗mnTE/sd TLWxJl=zAǙ C.$*,libOeu 5Fn&%==| {0S1V.)fkaO]t.IJ'@ts8Ue|GbT*!rj@wJ2F$F(7;]+SS"#wDDO"6W?7Ɵ+ڎ 8iS3sZ䔳L0DC >)՚δ"aF##'nBU -.ˍ2E6J<%=R `d^]uG(Y0x'%wPPWIP&q=#C_}N1^'=#\v Yhp$tO([PJ2#+7ԳCו\z>fʎxojq0)T@a4݀RccCfvJ7ڸ;+^"6ҽP@G­'%n-Up:`n8; u2W>᭛2[nRrTie% { *E%Z.W ou_"},SɐoĖWe juL1AJBWG mgmISHIc.7zLe~1b覲Jw'@&hIZ cq6Y,@'BhQ0pۧǂv^|K9@;w: ;& ɲv %f%g3b=0| #QGMI]Mj EnpsnUz4 ;6-w_B 0p"4&cU n +j7_U9}pdԄ!vˮ>P"VHnY &8ҙ ?b=#`uzi^(-ʆ/[uRXjx:鲆\QiCy)g T„nIYvK9bK?/ۋtyp܍023M@YHjxgL$ ֙t-;44؉9؝\t\oL&ޔwkBކi;ey().y3~uav8DkS^Z; .E%Id<+rʆnvEV%ASh Af=T3lq*6X]qp**;4d :Q/(\upԂ\?Ţ 0ukꎶ:}y /|xq- Yg'_,k}(*"&5`$lăwiPքL7|!iUF@DVg_ -aѳ λI[¦nԱK ^ꉷ{m6%x?blg3|j9hʀbofZ<[^ v,`s * L1H{™: 2+.^0q#"z}g%Fl(1P>/2+u5FH[nb䉤7S&3,I+$@%Wgܬ.Gb:azAW|'\LBU_ySBP5RR 'f> /eԱ/ ln;c7p`gtVjI )h6a-Թ O KXV^B)3' XdF)u2(8/u{p@|ÚŐZ`NЫ X@HeX(׭&(wN!6կ_t]0UJu1QttSɯ0c`1{\:zoaswI|bnv%i7&xv|ˑ5९NvJx.ĢFz̺YϐVۑEQ (r៿ DOX_ =rƨzN4pQP1ik"`t*ZOX☌0q_B޿crV^.'x;09b$,E'],fI`Q~@=Gc#;ǃ3ƼAĈ^%i`Ըڧ=?kRye }KQMӀD&&+.]7\+.Vӽ jP )\ Q޳z2,; sYc˼U^NIo䱱C3 LOz,f\jUQӦ#JuXU,U1G @שK E/>{]'|2_AzsW 6"]݊ؑyG{/1lr d_G rI܆Z}K:j`0ᜉTPd"o' +}!Ĩdվ^šCi2 ?(2woe.N|+3u;1g%pNM >0X$]pM(7:XRMvmEy ]\2'.o1(L`Lt7'B^qˮ~*drl,&<4d9mJoXe)1ȫ BG u?S8^:ff/.㊋jGF1=ec^4io~{3RZu@DPa8dTوCH -󮗬'vEyƗ| c_"gU::0g=,H`d9:-f&iWmDR DP9%`RL6Oɺ݃{igTHb)iV;$3g=;]u#)͘`bNkX׾o٫t| KATp5$߼ğйQrѹ0^Ѷ2exoq~"XCU])ce>13#(;'̡gk=7J ć)NV}( L3# !멾:u۞NmBG}|LSXrVIhwRrK0P-|1bfR N %4Ý+}>:P$kv0xA=V7;A^-)yTRKe%ŠJ`xS &I{!%d Ӳ|:l/YjTL *|>j>AFh`)S1d3Wm'i9 ]䓍Js~Mwf$VeEorR]+s_a.c?Ѓ&@ؕў˴e5ҍCqv/y)ekEZXvNg-M q)N˾/hD#2J+E/Lѵ ͏H-n/NAζy.}16\udýҾ5$L2hAZ*i/"Ąqt^̊xٲ Q[v'tpW}wZCxQYDرl鶮eE|-=m`ğ_P7 rJ[zW >fv5}*bWzh)%9I[''`9uPsBO')槤c-/?|>/3WE3G_|-8A/cG3"]WQX>,jEmKSS\LEWl{ V۱\^m3PV$ 'Ρ1RhTKqz8J';A,)x=(|֞'7"=AEI+G^OW}֧*lRwmf.LͦθLӣ=e HxT 9tGJ cL:W"+gDE&CE &krMn]\4qNN"A۪Bľ>4.}fKgأCOe?i!S{ g6c}aY6@3쒙 I{BM"+-h$4HX0mMMآ.QԪwSTJT- n/wyOt0pS88h/L.U=0k4LLo$E潴*0]bxe,(^,x%|`]1O<8[ՏҜ)DhӬ;B??۱%^r|e,n]څ="Etβz{냵W$aln6z3wQSfb`Cj^pY,aƷ= G]moN{koihs>̺ Sӌˠ:֐~]PL]3T w1SL`AO!v1"5U*Dp%C-K1 TgnY5q܈TsG J$ _9XMľ]G0Q"Df6xgoAJ: }&d0^7}o2 5NjZ݄.$cAXìod5h- oOx:!w Tu -dQ@m1}יDAm9$fW`)9<-.FE\>O5v*J|䐲89旼|uZ  %'6cWOK ,#T(ƶ#R\[ҚS3dhHbNӤsgsי[Arӝs=\c95xtqH" K! RE)(P$I^hn>eZ"Nc1//cM"BXHWfF.N5Эdؑ׺2zv&FfHTN?IѺ LbPdSqs7暷Pۍ",jb͑eڼGxއz~ǦP$Fwk6D@/b%ƒ>UN'=rpAYS DD2M/MV/jg2fƘ5{B/S<\Έ:}<2_NŸ%1^kzi֒U⦹ 4H)\򬕽o)Oܳ-uu.zq}ߙlދq)=뇊0`g;))GKow|9" hTRB,53 ntK!;c'F&"#=(T)WM2U6q¸XeK&Ϛ{3ɟZb4#}|5bϘKe!cC7Қ; +wƚ""^6ő/Seg 7w.@ b źttHJ/;ܗZr|1ėև9clZv3'Qα\OQF@8TS !͍YXJ$qxN#|е;tN8`aƯ E#j #I/(G%[ TeF,T!ӘXzΠ:pQ]^4.?OHUINf l49%L<48|c38}wFp@Ya%8P>*u{|aa)oSjFhGmɽz.0b<׺ zvMiQeI4`Y"7j\h=&'>l4qυY]=M4+h~9)ܤIqx&.`ߘ Ӟ>P_x6>͞%fe˴+M1;dÆm2FA刑Sen)tZ:-\h1b+%גK)\/=N |mshbDo܎1̵[B{ْ3ˈ|w֣@a,rrpoȩ{e7%x9ШY>H5~bɃsw=TS~PKc8IYtgtzqG b7%{ >wBB) (s7LW3A>mfNóicTE/T/C0Fܯ]rZ&yc ux1؊rkmM:e9 o- H|{ͼh=g6')kC ̉(lٗOIVcɮ1hv`vE^OUkK<39r+ã̦ sr *ڮ> ~H=N!~+6Uxzb$Ԏ+Y=К HhyD7%quh曢(sSjB).6ueoʧANgq<_J$Bˀe!e.7l[G@Ўz8ׅd'R4GT7‹].-c9Af[Ul۰-d6 iʒ;IӀ"sF0<L;؍*Z&a\.~PP5^w# :`.I֏ c: 2SQ&ft%r ZKcͶM.UL\)8I-֛DOt /VjnBpZVp yzp8ɦ֢*b[npd8^3?eswp0F`%T:Ar+:=ay^'-鷻IN69Z{&#j c;Ђ^D@)9ۨ!)Rڻ{& )c~b*Ku@xTM*5!$& Eco " 9UƃڔįB!{Ȁ(T/f #I^+<>;CGYnKF`dMS7qou0xrw-M@7 1M?%}؟0*,7m*=0U%k$oF ƽ3Gb@(NJxOG&ʂsBOm=oAH n~fm`~A7l/~d͘-(hbEO NmUP̱/*ǽ_bynv0(kgoƊ4[ՙw+S$vY@z@''~RZa4d* u5ҸUcf~%. BI4F^0qvmAOJ-9H\'R7* YUjc] 67O<`цli  lb҇x9 夣P{Sw^U(n4dq_[WWu]sh_i}E Q+0w vi3Y]a cԟ(Y%xĀIb ?Z &/ _2h0I<+;^<-T^tX6vpHܤ4|IXi) KInj%o\))pkKʧT>銠0VP <9-eS^,~zE idajuK1dy"NؒوvCP9<gΈr˷]I')(u-ϳBD^\{΄ _+"[[x:<ǂ[LIejÁ| KIt(wAs9Yi-j GJE ulw]%m( ^!`f6 C'_nBغdFh3Z 8Xɜiؑ: 7y}y@I}ivS7&d{mZ`ܒ[JuVBQ3LEIH:ި#g y ,+)mYڠt?ch]Γ1-|rl9d,dRJUCxOWg&0\E>ɛ%F+x^*C~BgNh1+YM iOwDŽo!̝ PܧrF:*zeV^4F.]ZͮQ\gEQ;b2t|)2Y``&:0ued2E,yQrq 5PraUjZuRvks!= AݗPuQn-BSL+A%.%| Q),dT3Ot́$ZAR[l=UaF2@ rz[K!*w=5 [Zs/m=EMCe/량Zy10vQk_F:/DQܺ3V|M[!VSj&ɺxgMIXL_R-LAƸZ&ͿafI` Aɺ@\\$JkgXt}4)xRޜ,,sjoH>);FVMo[I%Khe*6Fc6ArĞGtVF=:2mfdXz匘]!^NnJV=W-?P\𪿴\^qB 2 W%fM3:M-NiMHAhpBb|`-o{T(,DOcM;4 +$603ޫhs2c!S&&kel0ĝ%XFsnPZrεb ׁ?&yMhB!xa`Bbfު;WcW"b\OrAҸϮ{O.\9aI CExBvWQI,yغ@>lQ7׌x$rrהWT>WҿH)O74b55wSaWY<R/\'e.p-cP͓2AtE0/=:1 ͩs1jo!eA77drc {bɃ.O9`%,MRiXR|W)hω zwU=$b.V[V k م vI B=5YII8V39!jF^r0XN 2dA8>XhîD :+5p*Ϸ"giuɧd6Klk4MV :,Ew8?q$gljSG}gT\n_>jA5 S1F{R bXOh]Z`# ⱏڂ겵)*YFꗳlE? !.|Oƫ5 Z>6vfMT&!|[uZqO퇬S\. 1)(I4I&ՙP3p2 nɒObLZ&E:s2SdD''PXzO_ n0 ˵{J3ImC̀>1[6VgMR\yp;#OM#_ӏg'no ( +8wRzYS @|Ȳ3M[LM ]5>F4) j_a]3+$M\a!_pNW0rYU%Yn2e2#XTcXJMI[KQjZ E]_ LmqF߫QqG ׏4^W@槴fJ .znCj95Q4 ?-}Aӽ~t4Džw! 0wݟ9Gi0?,|*ݙe#&rt8ѩq5˻"؃CmQ[gs>t&Ծ*as/Ɵph5bߜ*ix>=z`2#" 2?1\UK$#]7̳Ij(!'+ɿ?8|@y.ijQທW Q5ɽ0饙R97IMGP)E>K d`S'tf\_Fy.F-nUHdR`~xtbp+Ev伳,aoe5W+5$ą#]t٦ } c)-[s8 eD k),qĚ:a4Թ + -=^c^QU8m!f]ႶOFܝtHЅA:iaƋӶAk(D-Tz 9%MsI偹 = ,.6{;9ڼ}B;fjmJ7W/w Yl7$B.ҺA: էϙ5^Eg ut߃zxf5ͣ [[U 6U| Nm}.(JUhGc7D$\o~6\)Deu*eDâW,JNFo"F&{D7d:D FD?7 I۳lK-GZ'wvPl u[nռq&V[R煬H`Ùʊg =0eaJVf1f4aʇn'lfzȆ(DhKKR b: dbׇ%2'MX7ϣ#dKb'7)1Y)l%0&/ga+!KIh(Y7瞧 ʎw58iti31bLBN!G7*c^&9A @g|n|7=xT418w3oBgJ[޴}*_ w T`Y}t~e9cgKQ煗;=[UAC)#)6n#y 櫔99cK"bV]K[*탿!/,W#,]K>Rwv)6L;٩=i Pn/,'(aWSiɘ Lݠf5M CD!2tQ"q @N H>fxXj✍ErS |7H_plj[1ɠ4ԋN1_rgg2('07@-a0b;wBJG)I>})SE{}>b'F J9}2/C{8mЉz姛~a[6m98'?:ͧU_BWm)Ļq^t8N@N4Ls] b`1=TH o/ag7(]_0 z: {L63ssԇ8Y ; +^vQ Rΰ48=n^Ȟgɵ7+22pGׂ$bH 9EԸ,C?Y^7Ǒ* Ao;YwZ)Sl ~HE*wB xYve^ՍO{%(L7H5r#8ߨ 2a#L ZZ&mz<\9Yivv@UPɤ7!FV nS`RBPƩw$0;Lخ34+ܠ Eo2|ISHOdE/eAx(4%1?V ˏ:(yhosHC~`¢rK-,WY'Cc&S{v;& q1$ǩeŃm!£x/\ 67ri$DT(ZY%ZbnR?l7u.SAbKۋ ^'-aK姵G< 6Mٞ-f5YGF>d;Y9ʨ/׼ŠM(!75ys&63iqᘼn)H+$,t80h׆4}IE%xӹj{ kY6 0FQ:xx '[Y/Fb$^j xZ%

Ӑ֣yW+$=l>쟺T"Jqjr[Bc wjw&һR/"W1H}Ϥ &w1^>;ׇ@ "%"y6YE/mI KM`hHOc=y[I;BBz{2XJ}Γb ?O wi@E^7nJHTȝXe3Hw˘#wp~mje2>=;Y>P .fڶ_'tƔ?Zzܑݴs;g$rХt nl:$̵2~3P$-ohhj@ >?m"xϦu@UUї5/}>Q6ԏ"IxIvR r^ 4E? WGY'o?̎DAX9Wu=a*yu5QlA=3QU{p7yUĬZR:Y9+Ms g.,1G#h'8¤pL)#%Suyi_1&<~H|U& ]T u=-܃UC?١~6z·ڂEc*nCUê$B (H?2٢)XZ% 2O?=K)Sh/E;æ\NJKM\80Nk=nCR}Wޝautev-_'&j>PثD(='dpĪu8yi&M_6`ea4l6f Q}@oJ279vEiS/=|@rME,jP8Kc]n͞ɒҵvܤK8ꑤHGaux?ĿiD.PlM2XM{di d`ǥ&7B<"#4Xuݥ^ReYw.OC.ω^^TqJb K,ӚzZ^JlJMԝ?W7]\pRtӁunlw>gyV5_4k^buӥb T?*H?we1aCT\CD$.!,ӎY,nAqcR']ӭ{Ebfi݈쬮LZv/|`q \fW^x)Hѩ??Nh O_΅WZf׶V/Y4-ג/.|JHNßh$Wt@#,0rp(-N._mi7\xfx]Q - 5m$\Q' ث^ܘ¤jb3и:,2Z_ 5 ;rO#nW`.+#q0^Ci˭7Ytl*m7%3F r_,P)XOF ʈ{ hbx\x.AAkeaso:+8xI̞_[OД22M9!f-T́[2HMK$j$7v{G'=(_EG=z×YL+5G3E+<[|]EfCb6 25L$9zK- _#6]Q$bxm:DOtݍu UHƂ$md^]1šSn&tBpYXKY7.[ll:I:ST2V*޻\ۄ,:!0a Y!^/DH!2̓Ϣ l5|ʊ]6Ц̉ٓ@<DcËl_H[]f/y- MdEݡR!ӑ h)Īha\ZMD_-"2Ƶl LF;cfQzZeD@bQrͺ.7xu7۟ _7v>\Lkhz6װfSɂ~GG%edO 6ct8C,h%E_:8kܾjx9jj"[òQ ])B>5:}s̙xUmY xX":?-x "0Qnʶb3B~BޔN]ShUn9Al~C,Dt UI 1{ҩ6LzZJ$R%ZkxӃ 򂭯B4sLԋ-t`˅'PLXڣa]=Y~Ɂ-d%u-K﹡oRj~|OxKOб8D4g֫Zś&9|[|[,(2hHwфZ P8/NSڔw^ Dvfj9|U3Y+Ɩcżt4~XDV;CN#فAl J#v PK2C_yχb5yAt0_s杙`!;,MMIP8[OEY)aڠKoxg3E]5`h?z& Gޱ5olK|<򙕒:y~M>騉eA$=61/>1UݺܮWM d>]HN=ۉVS!Z3YޭeB{Q}Y -⸄Z)] 濏2-C\v ~ ߑ b{0pّ )Tc`KAMQ˼)W+o*GG)eN_ EfyqS NkywpC­U~\EmNN0|^wn;v!I2%#L jF>FXݧ!7o(Q*w6#$VuO#3~P65DRHD&Q8B>fxɷo[50C _E>E`v- uKFe4,1'%DN:ϚƦWG V(X bVJԮLt\I?$t6"{&Ov{ubp^MS-J8]*dʹQބa`&-[--F[dfK$ÉZҋqHίB98ɉN-TyH9z('2\8ֈtt=Աd$Y $M6H{4u$0jtK<^_%G&+,Оr<$`͓Al_7PkfGa{Ԝ*o 2-w>?Ddhs_BKݔI8"55E[TODC2duA%$ps{8i8ƚJK#'Ȅ=xcAMȍ%'<HUFha#Q!$Yx0-b= |P[o~\Gs<+u,qA [b6 jm*<8?DuO啍#?kK++"BnHt <1bc3Dz80ߌNIش(%"\mP7gP'drqj~ه?Fbx?).t aN L:h͛:bB<֣+'sWMc$?Y:SY5ZfZ `Y$(Åq26nnJVV1ńGmw%i'-\6.g"旱ڨhts7T@X̎+'dȴ:d]CI*oQ O#eZCd6Lݧz-b55i<*$ tUh,ܵY-}&fx\<T -gdeqƣ?g璭~'b+&Q;4 r:?EȭPhmHWcĎ$/ b323ykABu >+T>p-(#^{!W+nd)cvZ59:-:~N[D^u%=t{쪕MvIeN.ߚN(\{Aë Iog:|M I)И-xX!+8Xm5|j„ l}7{¥Pc9{U P`WdcQZ[yoMrS`:nZ"L<9i`Ĉp5ˣiQIadkTRfNkqRxHPĊt [vEd+xPM TQ!5[ 'R Qd'/17 W؝'GeVp@`H{A;A&;IKyް[y)l,Sٟ>WUaANç_=Ƹkks˹jX! jIOo[)4=p3 pY՞jLSL嘡&E9DzcUPs@}&o 8&\,[K׊cY9BVٻ=m N %*kǷi!+58E]<0xq;؄IOG_)/K1n v&nmhCJZk(4w;Y) Nhݽ8o)Te-cR)9o'w_Fۋ^*DwŐZWϐ duޠLADJFPl==b%ǭ_՜Y~KX:oEҠ`4&|xAejP0Bb"ՐMb"=i#f4cANhfco=aRۄ_kWW$,D#\#ه:h@@ɫϰ4{G˜H&X3 Q4;޴[KK0FYf}?l_"s*Ѭg N+=BQWLsLȵo[ JyFyU徳#0:Cy+,g Jny8LyHCiw>Z{9}zP̐ZA_2RT(IIiTJe2661r{hxq bO f*h%6 )~7EѨ:"kAF_| v|DbU2h<,m5cӥTG RiȹF)bb*N–G]lX5#}ZI BYoRrx  𢓃٨$>{hп"vLb,2d3Eؔ#7)hb K'Fթ+mQ}HȊYV;"{*<4,^;^bP Pp# m!a7^F1^l}3) +9ADr00] ^iDʅӈM#h7'(FzaĠ:~>{i~,-{,ʖb+\ͣ3(F*G/] oZ7DU3Zt4Z*,rdٛ᪈OɪCP{uY4:%V{ɕޜ0ydBdj ;)AR|\KY8;0&*D|ގГlqEHIwHHH[PsǮ˂¹{g\-1hb3|@ ]4}BA5@|0 (N@A^ʊcJ)p(I9%EzU%"4Fp0;:2ːO  'I޺rPg_y@ǽ O6Qz}NzV;> h+FJ^q17gCA#M.KTd7aSٝ}^Ma˱? oo>R3C {.փ,bp3wܴpl>THkoIz湹c;Wۄf'^ŋ‰D'F/YMC,e1(;߂ɀ.PگYVr:Ig$.e/-u0`55mQP9Sn4H{< oCpz3>ӲӕEYVHvMv`i,q^zrf!bw =!?ګ fɦwa#rjpz-SP0Rˍ7\F77aM` Vyvk[MGBJn'37_3q12PM F.1 j[d`rSE"'El\CqE'M1}ϴYXj[ 6Kr-`0;%Аɘ-@c̾{Sb߅\3+RM;-Dug7}:]&:=vFl6ww#޾g8%QDJOPlp9)(4y,ޜN~Z->Z,lť,_Άh â?o7mBݱgÊ]\ʬ;-z}C>TRUD\aǴ$Gbc. \AơM8;lܤڟ[Lq8j?[LB3H6%\Y%gzPKB^|fU]s6NW):i_ϥ Ȁy{ຬ?e L@2+8QO59d⻍3C7ɘ&{潤XX~+x5 GP$ZH, Hqڐ{Y%[Z,xU\(&pJd=$4!l4?5 7\RU*ͦ.&I*!#.GK-!߅ l,C1jEa&<wu7c4iQh ̄L^Ħ B5Z>,;oKR4=MAl.^7 ajs~cւn~״*95| cr_K^Drj7F5(V&!N.rfShFX ƾGzpE JhV1*ʶrfZ2yj2oIvgG*k󅨵`BiM@brw Yo+(s1}d9P`5?r5)"f6~sI4i4-VNr+g!g0ydI>gYq}7_84mˍo@bz&e4wxZO%h?D`ťޘ7mH ?X L{Kr @O{T/bNPCVGG-f" _Ub:?/LA#lO29/ONեN#&U,h[ꖖ,ڷ=7_ x=<,1]sB A=&]oYZAn o\ t1cyC,,N½R+UV+#(]Jrۄ>oLUT ^[;Jg!ِmI yE^n=-LX7)eU[p^U  -nGXZ)SA=N2uD@O>euoHJ<ƀwq҆T4_9Zy_2آ*>T3+vMG[~"edkxɚe+s.7`r EvI@bIwehL=߶[Pa Reuzb9#B|aR9S J {uzOh/X)A'ިȺ'&ZN:2ޒ7&c;3`X`v 򽺟C4Q'-]RK0@ zEF4?p׫Q/p},gWnW:H ?j0t#DחŴg_%Sj \1e\lv>2Τ:pў9ZC-z=]x{N<*Q^/qXn=œg$hTzFnؤ qڣ4 8jM`9f7c AEP_q.*&Weq) +Q{k/5uDηಕ٦q-.7CZlIЯ: 6Y9ߕ}l]{vk8'd0 hņi9xpkg\V0$G͐!ؙqqJmD-i+JOrZz?&rr  n& aV(PWg*5s*;dt^!xȋ:tW o c"2h9gV]SDp1{|H.OXTL# Bh'*ྀx?+zo3V*/:eELiIσ>7xP.2'0j5Sh0\@]+#BB7“%丙[t]x!c6T0~RKF`NZyч(r--2jmxlUc[ < ɳ@Q/(xiSs~)l%ܑm{&v!V?\YĻ6<&M-;X\9[dQv#\soP>9WÜN< Iޕb%:CdQ >HBմ `Aƫ\@M(ӷxM zc*Fa_):xwLGP8(%K_ĕ#'iN#wNi8ց#vM0}g&"j< rY(KQ弹4h :X]G7q?(:hʜ#3n59x3Əض?BW4JH€ʬ$NMlyuKsdbmJ3xXطV!bEΘw.v4LE[56e|4(rLb=EB=Tsl:bSy9j\&x&Ù.#b']%o8[ezIMQ7rt-Y}XΞK k:. KǏx t`2L.Gd>ޯŸQ} 9wRχa\P?;JS7䧍pWe YCtGXWz`Yǁt2c\4eQ)> f(?IitNdNi?DbF \|QRg ީxJ{8Ҭڕ"/xn/BVܝOk{HC4zk.-&QDnbD?u#NT>E0Kr#ML&&ЂVw##y!CS7{9sbH ÒҐ_,wL` )  w9Ƙ,Ll7KWٸ}ip9C6ML+; }-}u#PG7nm^|p4"O>|3]ir͉P;Z abhzU`FY\HmWI)9/f^.Xm'?Fw=޽73͒|=RK +(.o.LoʒɹvS~g2\@cq;5_Eۊ߰lsAЮ@-ÄmSϣSyѷdc`gVZգu73$3x=&oNO9Li|gyb'$&xA| ӯ$ kRUHftԗq>=&8hW=l./:kl-ɽw͉16E{IkrJ5Fm2EرPLb_#'gVWMn=(Dw ӫ? j 2j/%{`pݱ>25ӣ^jZH4^&; ͳ 4NT % *°?ȴڛɁL.M p l ]*LuK]v5r7DMήnh U˺h*G00鈓|Ebޒ~iƦʘv-z lP=-qQ!5 S6i8Ц~\\n%Ez RM&rJD!S>P?6vpCM-*ܷR0`+G3֬ޡ3Zw{ 2*Yb~ )cWzKQ]w.a-4R'}& kfheȇCgtxwrvj"n)Vʁi_Μ{tnfhawk/:•}9^P7DE| (CiGvo{l偕;#j ~g)8.$n:.:!*KwJ#,(R Hx hx?^I`w;?k;GUZI/>^#f=ִm5O"nDd'3bQY6|`Cz@p°!n%&(\SʄLmi"yRE@s _%2oiCmR}>Rx$/Z],6zEx9v)xރ[38J#hxfk^E)ԴJo"^x,~ hWkJ^Tƶ_A5{$CsSt.QI7^iV(9$х{ɽo/A/csՋגr*t5rR\{T]m=o8!;Qx'ӂ؂φNDYn<*Myѝ&#9hͧ;RRH5QJ b$ 6g\㑉oG;S m׈]ˑ1B]mA ej f{QG+T\˵iֈCOa `W:mZ,āI+kJe?U^K4w#`NGHOiڋFؿQh@^zp?瓳^ gA*ݹt!ۗ_d-t)f H~T,MxS>!`oH,Lzr{%|WlMx\8T'[RmހaH?\iI)6M}tKήYibc|J>THp-5fQjzF 'B[5 &h[DhZ{#3lf@(Q_Au8~MeعE>Hi1(o^XT/RMF5Qsx)}S<]/V9KG'D{XtEE9P $$#eцHf}=v9hҮ$lbiՑ0;嵫 '3M۰ALK"#'9 t܄7Cs.Dɱ)pB,1q43JXr0!6GaL+F)H\O{TWph5~4O U8{upCV{9 `h!hDRY;Tb{ j!CWґӍB3KKqBOrK"A@ٍBB7r}b tY9)ؑD%&t~9:5(Oۘa `5h!xxf+MI6MkM4A}nF4qbҗj%kao ̯<__]$QAXI3rJ_|Y.u+ݤ$jC6`[K:Bht4{\\ zZDDln|芨G?!'>G?q0|Td6z =䭫r* 'z^bXampnfRNj@?k5U]$F6UGmi*'/Pwګ,A,h.(AE^7MToiI/ kkuz 3j&mi ӆ^vpWEǻ͏D= +4A&mo5x |bO& .8*J :NB'.òb]^pe ƻ?΃+»0z|+PNQc\\uݤ9|c&P-{jR$LρE()P &tyݡ r04ܜ0мbmiZnLa.c,7A7d@$xInDTIASBh;8M-6) ͼ zJ.!~BDL޼_q?{ukOA ;X{`Bii+E: )ۋKXMVÝnJ~mrwB6e{D݆cS%iVteZrl$Q&lm7vX˥K` L٤413a;;\NMPaF "kIJ1V)iʓTM̦Sa/BLao6z򊀓$zj2,Whnj0BcrC2cKτ?Ϯ}!>iW-ݧ-USx1U0%(+S@^?A'{#}kw#'O[r9E.'I\FiDf[},eLDhlq5 eUa! egAq &pHs< ߖ=jS.hkh̸ki[DžMQ3&ȰH"R1L03y&)hoһ>}uWO^@##ZۍUSMNAm@ߎ71L53L+8Ȱ sIMS,yf$l͝GL3n hɲ:'æ[[ OUeG7} p*zmfʰ`ϴڹ3(pCLj gֽRV› œ;.TɾtIy4H۝AN.hp}nka -jjA9MjZz[ҕd-,p t~D[0P7Q&ahfMfCK$z@!fرdq 6oxw- Ghw󪑎OKf(kIGbSήJb oJ&i`m/*TDo5հ^kϥBV}X:f\J)/,Ʃ㵥7E|),Y#Z4yI/3ijbW L![VL</H\wٹfoc6=Q &,˧~GdZF=It`m) p T%:cF~OakW9xEi7GC3Mo\xR\$:$,9yWR؀a-`#TJoR)'Dv#7O󗄾~n]t8U+直`~:ڹ! !Z_L%vl 00 X# LB=fF9~+IqAU}?Zf7O ZIXzCe~g4E]~Y MEhXܕ䲼Iˁ|b*lV]BU%U7f@"VTó\B(q-yl:z7dqBn( kdkǃ[K$,.5/\hT:@TYӃZ&gUXz( |4Zke`f:]EI@B*e2zl`h&'08nT)v >:RɈ| @CIe'( )ߜr*=F"H:M1uouh#`l>\̱(Y7l &' [$W|#߸sJKDW9ԣݤ,-7/7B[v?{Zլ&r܃.>r:DMU}Cz5k~"kTjQ<0!3K)1ײVUA2fyL Lcuf́Dxֈ g(=Ep&<2B{$zGPRƱ_-0jnym3h4_Ok',강ZY-S M@bZjTgpaioT#&RC/)l%Dת3P~WErV(] ؂qЖ.ĠEи6n)ӕթ4`A⟩҇TL-؞G3!垓 NԞu4gP)8r|+y]ϰ^>Y՚),:1Gh+k! /~6i$L҆z5"-Zru"\ȂpmT1vIIs!du  4c`;V9:3+EW9`1'LP2{c!e&c1}KxYe:q !*NY4,zTs NJ4#jK󴩪HH!94kyn lu6/H9ъ)̇>9`f?Dnf{ !q~رF '.*3qU2l$C?avކ)wQTĶ?%~BB)]AԈG%Dm2_ *nFg\sn@ɽzj?)$ƀWNXn!K Π7kL,e#k͈8,. K٬W 6СƢ@EKe @ʢR*lh@xut6^:%F"$;ibVh"Å}zohbl^SNs9amf~7לaZZB#p27;'ǟrA_h WAE? 1_OO ڼ*gDfue7X%E%W}F'WCcq2w }ZkT̩E{RdI1OxuO^^/7Hvk !Nu&FLmi4uureŏ~@Fm\UkvVbUqWQ3Fw~wj!nV(܁t!/t~=I09qr̽#[hWUW#2}OMxGvFBh{~n*0f-c.BN؇4ΰnFG@:(9`XW=fہmss5@}V=SڒMb.1*"߆ӷ 9 1lKRP>n qO 1Z(S<|7O E%t]NW'Qq{efwV<cQs$ wwd"gA\ cUնd| tSTY,^Mܖ =3[6~3f!PN ,<m *\“w2Se@8!q q@k1OGFnփY]x\IqF/UKߘp6J-~*rOf*L˭Q=G?0ŞшUN@d^ 7$Vc }n̏bvf>[`rvxz"@9RVȥ;սWWEFE\jѸ#"~Z; K]$~2mi`o׿e2xBs7'L+s5L_M_Yvwj!;_tp5 ۡKTa2V :I\4D fуydCbHbLS4"kKvsWʷZWT"4=o;LFv%ĽslNb?G5ՔOv8Im-uXJ[PsrqpU"♜ _px[P.lF Di?/QEi-g giնl']2KR?g@>)9Rv(sjEuf6caX7-&Fؓ&`&vՂ 5X,hgg*Σ1(TK3>UM 6}N䵷THe庸n.~Sw˵>Ֆ"XZ*}7q|^i9Qx$%fƪ\W/XBhJ{vȷ& ܹ|'Ö[K*3Xj-kR .$-a&,NbFu (i~Ցe.D0lM64lSrM. 9/(3z[>47(^xAz!or6QI?ˬgt|C] j',kJ/&̡8ZFHQ$UX1ǁ_aX|+DzD9> _IvE XQܪU\WG̴0DhYM:SᛷYY+TԉiAJQ9Jg ]UUK,æޤ|-sTR)y<!eedK;j0 #t p;i)bϒۅV;Byv_hDM4ub0W~s)ړOAhU/; sJG:#uhŠd[&$U>8j# s@x唋;wl}t& pg|njh0Lܖ L (MMz܊Kcl1! 75\<dT ړ$46(^POw"!2*vudقݳP#&B9 C% v d%IF芈ƈL*8T-y(b4r fO9DNm4=U8p1dݹu[C5@@ǩ۩bĥ6UtLc:f؄S` ONtVӐ["dU2<=' D%+<Gt{? jI༌'0ǪMIOʺݨ Uifdi=w?2}aHqdex»C:lشu|ZxVsګLpnb~3 +1ucxKf(:}Ҽ :"|k- ?iWhӃ0vc 4b BO4qlJZ`x~QI!,O,hO*HHTH8|JU BΡGa hNZG) XWa+z=v9Xjićꩀ-;1cldOМ +xqhI\Aٍ;seFX2Xv rxG-S10&w+wÖ Q/1HU1;9aF=ig Aʴ-H5}r *rR{Aseu(+Xu32=cƒ3HgsQ*qLj̄=sӻh=?eb3;T)'20V(|wQ`g,8..~YeB^[⁋w\#4N-B; fWUi@藺T.~\M65XR;qn̜hA>甒/#a8E7&9}+8,(ȯ7fU;8heNNBr)|c)ظ{X&;E-L4oIx0tԵm)K$n,e )jO8! /BW-l[6Q>9EceT)1';;8t=6*d 4EZ%6ǘ}4=BkrcXSY4nvk-B,mFe 0oѯ-ד Tg}nh\"3W*E%HBGf(hhT,#*f1 w(Jm4^}\0 u*6XP)o:P'H0kmQ~1#Ě=*DJ8prB}iVE)hd-!IF-jc7߽x]g46D:oiv$$Ob/ܢ-L<!??9Th;?G#(Urcu`$Z}]W-%.1 IfFHjb4ɽqNe}ֽ\Hߕơ~דk⊖23 d ,&44?9-@Tvꉅ 盂ܼ$k^W_4mtLMw?7O8*sX7 SLpw!!PWK8HT]HzR^b[ZrY3NM3CY%q5{$BeX͟AIofkJ[ހTw|llρ.!0֪YŃT$poa|[ _!H^+r% a|e` 7hreN0Cdtll{1| @ .`(ei؆rȰ .$ Ř]z3tymAS*-qW4/`SL|H z'c1}30BGlsù+ )gpm%%|1@̻)ڕpW){ 2 }B*J8F3$Jh% ceM;Nîc;?:cXQ!kc}/ <>FZ|_qe^Fbf~vj0Hj;-mrœ6XbGZxIs]LM^;,,VTIܫy+ VG{yaSfJOs;mC|.ambY=l9:`EL橵3bܞVh>!:9Sb l ;a]%Yu)TI\ hēXԎW:O6Xg݅'Z, '$BI Y`\T ^V5;(Ov[g9{Q >xN9+ZK)5KE5aFw@w  (2i]X9`irz4{08y&m| D4|9Zb!.%as",f$p'9k_肋5/!NdIHLN8G$[1#6,†Wݥy,nqBܣ=y26nZ-W(3*”S(ܶ[2.r.֮=@Z2U#w e?t]ӖOIdTxĂV6C=B Sׄk">!<;*X vARJsQW8b}kTK2z}"~(l= j>{C:"8V *WSJ.,pbb  ѐE{o;-cuweDIxQIh{(Ulcw'0d?9@ D<@8૱(SxbtVegp6[=Up-lB*?G_~wgP͘|>1,I&:H>D!\jPCp?o1ZKڽ1L @/?슯k::'c&Y ,e0Fv86u )u|<͔܀ ?_(PiLh @2Oˆ})#>6/ zk2qZd j(b~\tw|J?ЫӋg\XG_![6 7PU.Nhj`7T$pBx_ZF瑕 ~ |8"/\\#&m .Jr;uF];w}*f.kI&Ux ;$N%El dt|I8!sMd[-%T`otFD|+!]Y` ?}š6}Q[Ei'Co.Q2g<45¼f%JtJ8 To8w9L]cTV[Fr_@C=6iapg834aq9SDi3QGBgێ 1 "x_ϟdFShkA|Z@\#|u. rӤ莛[N:%e (dw>pg6l3i<=B 8~]uY1ujTB#oZWpHȴ ? ('Ó)z>,MWy}9TVǹU񒘺06Z;z f q!}`=?G?]:y5I4#+V5]S{j&z\(|̅^b!l{}'ybcHhԣq" e^I}r8)1Oɾ{c.Q7Da<6|cTꆐB ԊҫWQM6JUT!ԡU!&,Z-ةtȿc?#/@xA16ȼΝ(t䨣ǿW&XY*QP }~|QӹDTI@s8쉡G?LNtgkBl{sGJQb(>qSU8T,Y5!;h0%j\V،o~}[y}b՜zX'xdK,KsxsMXL(d e:y_aY|`,@=(1} A滉,8>e )RF|[rL$j6I/{P0-3!Rz*^2kH&ihhh>E9V]Qq%*G 1ݬ&qcp?9BqRϋB&ȳ4="Gƅ-J[:MX@R7t#4{ew A޸4y0fc|2}SD؂ S^Y@U#6$|2TJ}a$_ok̄vn[9'U,?w @r@C3}6QXŎI؁{Lv^F/qh}ي h& %CXjC=pY6X^&'_#D?E+iA A"`>h* }\6ՈΊFyAF.}q^yNoУ"DFzh^Tf[WZZYYow&WƳV`9 'ҶT|aAmvw|MWQ@cV'8JU=3s"ϑ 36pJ_Nc:1Wyk+²c"Rk̩S!kIM_ϟ>0rɇ!IF|r Ү@Jx8džVyqRj{z}im6pn%-шďmW-ډ-dzBO\1 {Tp\WJ/\rJר'C(jƼkgZ/~F7Ӑ?coc14h~yLvt6s:6y'࡭}WrhYƻkD( Pe4.dy[4ѵn8-?֊9Ih)^IgV_zRUv E67ɳS@-TX㇬eyl#pw1J9cOp:$yb9cȈEh`VGǸhN~!$vp^%Ng JJ1n:L&Fby1 0hv@|Ĩ|1x#%fut\phXwpUV hrm}Y_j}T:HA{-\)e<Ì_y5cђယQ2֑ق䤉rj;8Tt5h]R= 5@7:9Lm|LYsUeunPz4sr^-] u{Qq7  d}^cz}'39eo $=6Fu DJ+A= T;j* SwFvʔ-)o)7`=MuC nUS>;Эo_4xKcP9Q \}|kOaR~'0ݍ?! xTLy #ƙVF䊌gpBچROqT0P@on.ʚ )w}l:o*v&Of?7#0Wd^¡Ż2}RtVɉlFaIj6Dq"l7G";C4gun M1Vw k_tjB®b`-P)J/GXbҘt`(C*C"[UwAj#:Kwh7Ad,`8$EnyS$&֭5Xx aytx+;@Ԡd+%d"Ey@Li)!j9Ɇ^|"z˄C)]>CJ6 G%2YZY'` :nP;|Eqsj[j%8G@F+z9c:p&H w=^٣a4m_7yL r#0]1ɢh >I>i2ي/Jt#}dΛ~#q¡h'b#;jڹqjљaCr 6*<&͇4f@i j\ew+@H&k)ŁX>;6m PgѴqX8C( pe1>ړ!Giپ} 6"ˢUeSEi|'^ IGZ\2`gh\#"hTc֠1a"hܝB6i yQf@u[?{rCw=V57`^0,tO@tgHrIv-q*?Qahѳ29wD=iǦYât?/Bsv-hi:b5u1 Ikĩ@v*:)j K4?`VzA.gqU% NнrT#%߳٥VH0}̴qGo5Rw8'5j"@7Q͕] EK/x!L0¸g;p>ccS0v0+mž^ Bde#^&-ޚNZR>ppBE_{Q`T7g$=_i|ztd"Y 6?Tt5qJ *rm#:LaIRe_+0_RY>) A+8ǶQi>,ߐ j@P’q:"xN\qYҀ5w"`iv!Δ YS%-xCI  n@챦0rzF{Qda2YэZ:BM0d:c-d ,Gd%R\ (<YW/6M P!S\/g XhFg1# eF.A[@W!u K<4#3'`a6*2B 'b 45oq3Fە2ݲX$u]v^h?S.@v%s֐e;{Ru&~L<\ӆ}94D7T9'y"#Jd5& Z+K"h${*%у0zzi55ra R`P]Wbވo|oǛ\zqoeNI9qy?{Z&W$35!#n$ps벓S@>K!>2K ]N Z{gEh} w QZrQ?է\ ,941ȳ}kdm Ij,bjVaABY *@|pTWr1o*FfQ 8ݽ{Iژ<7D/crcF;ϥ2TΚﲢ5XS+jp;%Tz8Yj(Mٔ(ٜnLgnNC;)W+| 1 řPGSZuK%W`Wx U]]щn-S' z5KnȮDQ];4ƍ/&}W^QmV-{,!/!場A(bv{?pZΰ8yRx o[{2 v́Ne( WpMŌyi{є*_Jr zC{ }@ \i"*0Hdȼcw{h{ (zպeiF_cQ0jMO`\l<`/vvJh+qjPVJ᪘U!Ug ,yvb3tӊA$;¨a|:@QQb1 ,,4HssBNa%LC~Hj~[@.i&A1N9ne8iAj:&#TN IB-H%\|\"e' u/\3pX NkKʘӋM* C1@)prC:RGTvIW2n>GcJ_( w_K5@ $̸^,E2LSZ8'ay߽`勓Y3r&Lgv 32C.HùR Gn)1CGdsW<[X L"n;P[ rЏLwE2zLƒ$Mmľ07I<,N>Aי 3[x1Kցa$K4PѭiC,}o,l_[ndVʥR+&H`˭.I5do\(/kjεΓ~7Q|R ̉DohFjA!gL.:.~#+[*x{u'uKHX >R7yKlwɍ"(xȖ_NI;͡&^{pjwbE sAּV5sp7\c8^*fNfZat425T|x1jw~ʁ|XH{73Pyr$Ā0GYv?Zf~D{\xDCQto4&}ɟiJq9&WӦDq[,=vC SG8B}WiUQ6@VKK|~wV8 *ز_s<4JjK05NE+eOϬ- ×֙Z/z֐bX3SdV}[W'&Veݫ TmhWlD7]<^;^f%"[ Nt`4'(,| ܕmmL1KZp绾v +3GǷ2(? @8,^SS>b=>{&&dS).W mND +H`o3rVHW@lX!W rg.x\Ȁ񂑘N_ *kϨlaopUnCzQÒ-z7x'9j,Bl!bL_\j`>"͸VxBLfXܙ^"J)YTWgǩg {4̬F)2 ͖ou+1}[.gHH$|h9g^mCk(:-X,Pv Wt(1Y aٽd*e cšuz(QKۅC6]kH,Bu=Ϊ,]9x@»W =^i _ZIw<k.RtZqVH s$!恟Go;u$4ЙCzjg֨&A^i؀ԁjΣ7|[b<(] )&"~J,#Z$@,ɷolC~p̈́n N&cHpQnc(sVY+ uC}t")yQЅ"Z{)q@Hnpl{GBذ&0JYc Q|OŒ?,s^:eOl_ًQw:>E]+mt@#ppւ˄,Nӭ0J¼j5Y="Uw/_p@ +R:mӾB Jw3D2%J"!o:bƹ+AfHxiФQmUAǜg$,}C q/ج='AHL^<~I#ǂD,+Rek=4jm6zv 5Ug}vGt<{1 tVU+2P~EIwy{ah -SlC eG"*ٞ8W%2@vXF MJf?%+=vVgG͍ >~Ndxφ%qJTCn@*Si`\q$.- ̇d=:l (}h*_#m]宼k3ݑthᖁi7P|'O*1G})J|@*-K(a4˝CU& +"gp!vMd$ڔ\at)0*ǜ_k&! )P/BVP9܂;A2ަ3Ҹrظ3!sOb^Ej< OT o,GԼ /L/N3sC`¶}wbSφn ES"ϣ}Cr Us5 Go|}E+kLMeS߉Z9^*@d5y gU X]M4~i^zLq}/xy2(mZy9Р~mNiF3"Z'^*{28耡!'6cjS2K[d @F gU.n/kk)^\ /z5\C](bC{scvgONq*ͤ*׿t_֮-Iɕ&Ib3;*ڳ9KZzBt35}29zctF=Xzvƒ79 @v߬9lXS;T va72j(D|sĪt4qȑG6h zw 4S_[! yHEIM_0{kv >˽&QƏT77;`!-a`=7aUjNVs|ڛ)4x#^[Qg1vrnFLLytn9iwG0<%Va>=uBW^9Gg}t`$ ^3$>~B\cy4EhH HWn|kdcŧBe:HG2uVaQ=%Կ ;OȤՂ|R BP(6({ Vv|iiM)O"tv+cQqS֢3AUk\wb#y s &Gnܔ9,%ud U>{7ltSB չ$1^D:s GR,AP~WUl,yܷ%]b|Pg%wTLsY/}#`G;-ɓC5_6 Qti5uv]U\⢱u3ߕ8^ʃ 99"v! YB0 q- EeSwx7@%8_B/B'2.4}u'i+".-obs 4rRx$;kSbOk a$UlV0ڜGtd9SyqQ^!no'jQ3%K30qV &úxIVpTA)DI؎d$WVšs=8/T3C51ft7˄AOҺٜ!0qHȡ?kd.bai}AwCq;Y`6'\!6,+ 3̯0@aۧrXShpV|YMqV|wܰv 3#1/'V({BytFufFO86A; VSSiuXtYߎآbĺ0Sf.wĤqsƲediaVCw!{S)GJZUl`gj1UV*@yDB)P@7뽺B/}֊ 8 0CG.JTxĬ*x.5Y씙ƓP }rIG| 2{!ŗW{x#/Q+p>ES=E5_b8n>iT!֏C?R!AoyQ-@P1 .#==A;4|nCdn3JJAx>َw[_c0ry:`Z( iӊ`'ZV7pB܁SB'W*:Iv@$!] \";X Б8:Ş}lXʛ,ŎYȄG.S$kO{8.1.51-A#]{Mx%x7m]h^!;{C [lop:hZ)R)bWc.skK܆;)HG(]Uxw fU!ݫ Q-!'Lbk2a|$;B4>?$1YWCq0͸XPm/XAtWUxLGh|2%s(a Al{-u'0ERE;spu0Y|ye:8\>(3K{!÷{&8e02e._O]v <=8`۷&0qˌv܆|8aiH/m{ç I C LxϹP iXI>@,l5Ѫs|&B! ej& >.Z§S;AH>Ke )~1V7|l⤼u9G:7dġ(QnD־HnS;ȴ&[-64U G]zd ލy:БYȌ\kFo7.+]^5@ŷ.&;e K4F$JA=І;­Z(V2Z{z5h[å.@T LWDN;MB8db92zTmA}΄LW>>2-LqL?m[I0+!S~ k"_ Ϲ*|BMg2$:Kp>Dl7? ,x؎>h0Os[ CAXCA[j0P r3/P#̥r˵ ">ͺQKǺYl馥l 9Z jr,O */(KS:_  5׆6WTqU>9x9Ɍlf&48DJ̼0HQv:s xe90t04#Zr ??(벖LM9 XP*J+>aNUnB6Sy?EUBRѦxCY=Q"KO0M/ G ؿ8?-_dc+빋@H?8qhOx _ϺV$8{AD4\_2eW9; vKmm_:ʴ~ L9ɐЧԺ`[9ر]5|E@'R.?5]rLxd:ƾf8l1,*|آAʙ;D7J2A@&I2_/rQ'607,J3 p65&9z>YVEC[[';v%!a)6h] qگeF2+~:UuB!S\ۜGVHlIYRCP%aƔP+O8`ߩ6p[TF %\g]}K;b(r2[?5+|+dWH2ua)Avf:f+wU\[+,+Tqe.iB?KiLumajf=bI\>::X5.W0gvr[2)Χu /6HAIJu. JqthRZK8ҕ>ι6l>gyrIQI]C$2cOM:u ;,ƯяCfB3fiSDɿC[ 9lws;ԔXw ̀f l]қ_<9E[$ m3Ex=P}K#K8jfZdր _'[ f~-I(*Hto{ci1{ ! _xԔU{+r*Íj>ҀP3iFF}3+~?j*͡NA 姡F(]W?3uZm]&߸8/&%o[( Czu۲^л q:y8@j͎O p S+82I^d 6U7!ĽZnpx?n9Yb աnz yt6٦(1)m R "Aȝ/&L{h{zOT_ˠZlS\gIƒM[T7O6G. M|Tpυ1jfn70nh/ôQtvHj "3|R@g>A3/}ˁrn.6wY&3!BT2%SR/nU'^p,p5b X%;_s- #"_oW<| cԄQI }8}e'I(\Tβ% wO;z G0pqx}.nf//]UyG,/ʦpsj|Ԝu MIv-AקD 9ֹBrl18wfBnXGGdʮD*=yNds4ZYaŢ[!>C(C- Iڹm[:2DDU} L( s/[DΗ@ĶmjC{!i,`7skv1o!\?i Wv)Id|4;ﯨ3 pT[FNr}}9{GTs@T3a!@_Ü~7άD BϭU |21#`)a|*[ɯe;xC?Ol"_q  e_8^%h;f> gE`n@P\ڌ5 `7XSqb%:{>i"Sn[@"; 1CPv,ec :r iØ [{8x3GE{Eğj?֍'%b܉:f`Ņwg:TdpUhZ2f ĕ3|yl09kI-]q `:Uۊ:i,li►z_/{\@pS! #F0=T egm!+ @ĤP`b">.c*7-EJOM4˝1ģmFF[?l=aD_C-sTS,B7M3zI*P- 'x.Ἦ' ˆ{(누Ԗ\]jC׹bjb ~N@&Z$Oqׁ"Mn>oLJ$xЃ\cn2QfHX1T6lC\rÅBJ"'Rl=iN5j>jT+!'Ҳ_⣛!/5a REĨmfrW2;o_zJ4ܢZ BYZM hɹeC `Sjn\WV,lRv%Odoּ$@W3C[P6*/j%JF re>SyvN{`ڋ>s,B~aM:C. 1Um 5zぴ0J]NjYh0T9ilgr DyrdD{xfXTH쐹q"76)v̓rM%!frAO"=w ^ELSE ʎD`{@k1S%쭀6t 0a!k> ϵ s`;JNS~;@bA n "4OJibH$UER4Ϻz*+o9RPNm-b0sK+%p2 HQzB>!ne'l]m` .d̊_u;f^A/DcǺSu%ݪZ/t}GAe dV b8Zak\߁%gT)+8l^YG7]a'jp1Ffv߆&tX#&%˵ׅs?>X?}A%⢰٬<'-ulft@qLhPN<PI-!ݠ.cOهQZFĦw]Q!wi/AWx8?^εu}Ø<_FS\Z{loN2S˚DܶqHXߗ*8T5]C ڋЇ W5d#_K[r2gE2JEph+a{ymx,ê"Ƭ}k' /#sJ-];(d>I T,NIlH-lymT]Ŷ$1#Yjņ|?X HO:t5)i}2+)Q.=7GMݯ<Q\eOD;ϴQ?H#&QrPd!>|DF{E%ތ\9Zoc7d 5)Aaw#3>5%2*~z_9Wܢkc: (\wV|4vጲv΃YIqWRDxiaчl[kԤu<9Wsu|wZqC8GM0UߛOH^6;aI|pُMT5/<&tzo}He"Q+ up'DMPIG?t{'ɰ̀ͅCۙIa?s:*4A{ 'ߴ*S?6_b͇Oq"\ْb Y@BW9gR1C"b-FHXw04{bbF7Y? *YN:۲WYFڶⷆ>@>\[9zDܣȷB~|]m͖(.w\ CR`N&mcUp09J5j>»&6Od{AAixi`<҆K2SR 7N*wL 6BFg)c>9MKG<%grl%!;8l49"{4im.c)N2Tto@A|S萍( )u'3` u4EU|1%Oz)e~ Wg)hZIU(r ǿ{e:Z>xm1ڏ:. JWyaMĦ Q!ض1 ,~ɂ1m$ӱNXI<}')Kb.NB;*|n %٦*pLNfWpИTcfovB7͞"bsfz_w68;q7˖K͈STbb[dQQ3 nfnf_? 0#QYֿ@ib;~;q 6Kph5nݕ%gBCy%.2T'uڿ`{JߤZb7؊a| l+ͷs^u N0n#7 g+%G qsmBD*nQΥfH_&lDܻ{8ނn*yj&zDH(lϼ9q꘠G.4Xj `X{".rޯy'HRW` h), Z@nAހ7.Uۚ(EpxL8X/l%re |ʈ&S6QU]Sn-2寵w8T/8]Kf0wr2w7nb$L{.Xޣ>n~*´ ̯(|ysFϺ(=xqy߫y"Tr9M e{Kd!2wX6-R-@ PU; e#BO Q1Z' U놏t:UFTP0;$dW z٥۫y='c_ݞlvzE?j\N^bZU=Oy;LIG"(`:lP } m*(Uw׀C =p o}[0S 6nb3l.o; JYQSU|PwÝI҅W8tyX+_̪*<:f Vդ/J7,r>[ |74B PQ{ +lF[@fⱯ,e1]E={}Y1l'1ZH}%ɽU% vP0;oF(]5ܦѣY= Fߝ>Ų8͖T~~pv(ςZ) ı&EuTBeLze4 015FM ^3\~;fLX*:QwZZ]˖2NݑF ACNF! >MW>;cO;+KBt ՜1Ton- Xd0zQ>,mܾ3?jl!RjI~G}>J|1j|%wƖN'(0p%@vOr˥Uu. #Ǵ8Fى!h8_ @(m*j}K!7|Ǝ𲫕 ͗oӞYֿQHTO/j߼X wjxŬ,FMw&ZL2`Z4HjAX&Fܜ#,icx֞G{ zeGp;-b\ M )E}bmwf^~gob*Ln*` &piMZ(]@s#oH."h>w ,N|k 0;.ڽ,i=e|F ukm*Xxch rT1)A+g埖ɆgTp<ɊV6)-,LxP>:LP<6͝<4bݧ#Z *)T́KĞ3z)EKkÐ\؁>h-qU.N(}sF$.b-(ǜrlÉ`Qā반~Qjy<{DA掼:"1ƗSYc 9-J@E`ҔAu3ԹSlm kVZ+[xI:IэGqԁ}K°jWGUuʜn).VmU:ɚ>7ۯ#(ĭzMM'~@vT@Ըb+ɕiQmbhS*@M7FW Ԕ{|e= 0ZnPZS`0~~q+13. oQ -_?)6 m [<,9$=kPR+?k0]Wv¢> dF܊ Y}nR hrns:mA1:\a  <`Q3&7G^U2-HBnYf [K_Һ4fAdQ yL(M]!vzM9)<1^#i]ac5-B# G9+@O0ԁ0V?}2 EfK;ܱӻaC:+C]Miǧ]e]dMftW2a~-:xݞq06o"\*%'g w=]LjYQm56?YAPJ:q @d:iLUk?GE`&0?p pgF(AQ٪Igacn&4͹ IYZEK@vx9 ~?k$z95|E?{:bhl"-{fEb&R/ݾpWE(D7A%W@A=9XnD^\XDN>Yxۯi/GާyI,֪\{ڋk.0?{ ՚SY%e8÷'E7t31Ҁ+zR#KzeQ764[P d{kP +O~L&JvbRo8+9Àbe;B;!f #Յ?O&1,[W`L$P4wՑtMm%ʭzq Ʃ SAԴLK~=YnR-F!:u5Sb 'F4ڋJHQmh,S`4 {WlpI3hج{ſ 2HYJ pRZ_N^.b  VʽeV;ʂ+ *l:-OSdȅIZKE]`F M3rw)~ItWgFv<ĪphTpBa +g oJ-!2# CM IDB7[ƞ)3o-WYK>,[CnChCslTBf,(  yc痯R!c1!oBT0(:? u+La)yOޤ'ǮlXPQ5 J@s3Yڝd] s_w ԃ5hOSj<{p&pa.o%F;C0;ƒgpd\q9T;pM0O sb|1<〢Oɤp0i~axD?3v(YB%sD ae}lW@[Ks=*b )G,`Lqй o(+B9RI,akO(-ВA3CZw]1[ZVqAm~Jz*qJNgIėQ?[{B1` Q꒽b4쌪7x43ӡpO8A؈<@P$Y΋[ڋNaUAJn5{|RQWeܝ⩓| ǩqDw#Z;+$PCRe>DrߊLJ/<灾~f9UmVGvGM jW>)O29 VnPut)W^%?RYH ^i93fOY?㦤'o)1DFk%_6br4`Lp S!VyISxݳÿ^?^,TekV|I TA"3@ XVv"fLΕof<=A(#*)&5ג(3I{vH9oAL(mB~ -y7 lW<|El }~KXY6{0HiA/i1NҜrݓAدa-JLڐյ3sPف\) r(޹dhY0'CFIobU^Хty;xzDMVj>[5AKym:06f;ϰoT@TeUۗ3(7^j72g ߟ{ ^.C>AT z5_P)%jDAxVڔ \ ,~rq͇_z T:;0y+M{S}.Uza#rָY5j L#Ϻ,tZPhlF֛cciuPB:Rc >@jD]B;[LhµwnZTXkwsr>#WղZ)P 6vRbqi,h%zl%F-ENr@jI%W_Gޫ%ίt:[#*v@9躾| VJ[CjE𩻴8uMsw>-DvH+PZS/gՂ. bU,/Ax~zfdv2k9OC]W*ѻbM%NF;Lg`ŵC-rV=-nIBAY% SAq&JlO;7dMd|}-c-gh%nB!wPldEq{14?/nFhN6(<Нˤiڸ T%6N Kqx~c@Vol|n!DZ0l@G.42 Ujtq UoB[f\Ő_* BI j99t*7s.qz*[F x6 ڤp"gi lIm?N쾓"2ӉAsW7̯ۘ/-]_͞oC_AKn0c6dgB@Np23>*{tT6"W+9}&B1~"^E2<.L02˟ƴo-)m{I=YfockSNᮥJs'q*+a[҆e@ܤeޱ ʻ),Ps3{kZ!p{Odom~t3`N}[g `$7A%M5hD 2>e!~fSڟd֮ | fqF-yEa$4XzY!=ku ˑj}\b{J|ZjޅrȔ WuICk+v= :ֻ-^V}7*S<]RD~/HbGUq|z#wŝmi M_ّܘ*H3w^R+LSK)=0 qypǸ ƠZ$x̆NOpMH82j@3+dd$^ pI_ay) Jq/3F~!vivýAmV~oаYfUQEy¨Om.P+]eHdXNa"ٜ k)01 H SLzT9]xwOT~XL<(EM+53|WTFj ʗ^]r~; *yqGlιrZ'@ө_o5Rӽk"~9X69w2<ˈ^H.#`S3:gALf !y8+ZfkɛOIo93'R{aMQ깢e,mł\Y| p`kv hX@㼄o8($T+h ڝe@H+r6: o+6u fpQ&z}Vx`n Q00]װpw /FGF Bp|fpf~5WkC"MIVFcj0D?@/z=/sϨ~2-7/=s:85,IZW[ЫtWM8}a .TgR𞵉eoYjQ57  c'at !ZdjL?[?J]˅Yƻ So۠Z2>G$.ş +ʐouʖ#nVQl9kBځZ+@hqF,pƫuf]Mr1ƽMPr PU_1VۭSحZ 5yz\G'#IX* Rq I:v(9 ^~4^˙<$1q94^8jxu~M:J"%G}ӉVIHײ$%nkXgMm6{~{t|15s).1JȚvF9BAv .5gw:vtdʻoN^ʱ |*4oY& <~phɟ{%ӆefH9\cZWt bڸfρBuo hU[TcEoX}gG`aB0( 36G-*|Vۻ}.=?Yu&9y& G׃Y/Ǿ=gïgYPeq&bVyy ls鏟"y]ɼ(}b`r= vOvseÊ n[u'W߃lgTӼUH\8R-9[x˩W{ !eo$OϧԻUrq%+P- ֧ÒAS1{x?Fp.0[Fv嵳#&S/'ϯnHXFxH:GGVhKr(rGXWo)(Y7Fh2^3)xV}\b }!w;J= ( ċu xf(s4$vtSL*]TlmV/j)AѴa䡤 2%MS2zj>5bQGԟ>Q/Zsx| 21ndd>C|/2zYW~dv6H J[ [],A@ZO?rp2FnD;ή[gKv[ϫ>A+ f6 .":%[YY638Z2AmAu0xܰm^S {,-ἯT3My1(GJYNjdZPp0#%$&C1W7nX̮TI,-ԂH'1rqhqѻkHR"fmϲ,[(A-Žl}Mc` Ʀ;38󇷑JZj:hv^<@7o ~ ld+M? y$75m2S6oebc0W`.Un$E y;Óxo)!sN=>6E^[H{y1J}O< (-RG ]~i1,MC/H9|7p;#VT`$ޠ8Չ1:a~D!80l*LzD(4f7ї ~8e插 O)`)Ƣыx,ñ2[; 2B uR ZC)ƥu>j_}qul N0 s4"yEzTꞬ{s4a'"5mXxK3$􎰼]\J熴,D(!sX=tq/SG`gWF9 '\LYIV  6yx[Яe~W gWZ D̶6ĈZt@Bl<3CW ; 1y@la_w1vp|/K48;YX6HڰnwoBƆY%@h2t_& ;i܏܄c[W7#>q˟i1rR}XĽiƽ3S| ^]6tn=E?mv?Lu%]8 GixW#d_a8,Wljg[Ub-Sq vota-ӝ,AFFnؙ*m'{ĭiuCU퀴`#˥M4c`BLo =) y7t?cQZJH6A6e8@ƥw,PxAa^F~O[9֬gʑ͂a0h5֭@-6`UGD>D G9B_ؕai92 U"\e]u+P۴zpD|agCB`5Ȩt> QH}>\d#׀_UcKs j9[4,y!ʍ%OUiXϼ.Eμu1*=&Zh<1t46PT^#.(d`zIi䩆hjQsFҢf0a^!k6슙ov|CXC|/wYYu@PZڽg_ ”o1X;(pC3{l~!ayNA P"xCE'xeou1z`OHݥ |O*ծh;?N%U3 }z֕`yOqznZ0(u*&H0uDJdVf&?G\<i '0 4<9&R!G+/1Y*eQHJP-92P>þd_.'I3;@n$fsǺDaZA+u̓yӆne(ʛ5ڧP>:Lts^&gq^A\jHh*n^*^f> g KCe>?gyZ=[5 +XhF^>L<$3._T+MSZp0A 8db#9Uf 'nT*n݁B%Q9P-r*8 (WHji(e[e5.do!F~n` % >iAz1t\q? #7 6mۈBg L#x 8NdK8u ;85=,ދFƑ?Ү\W^'NrEmN_VN~(\aN)=@UeX2Ս483\xc3 E,I:ze@>O얙@$4mC7xG2,o=mT:c5]^buAl$/a ˏJC80FW (ґ[Kp@ HĀ慲!§G hp=W{T>\)}<~tDmWORn3-e5S (LZXp.MBkڀ ƫ y~͚]Gwa4AÃ~v4+0pv>ߏjǖ2(]Ĵug-KV#iP>%Ewvazd0Kb +g1.ut<7 9xo8{wUd83y  // 7% yhj L5Y&" Ҝ/f{*p+tu/XH33XoGV-V̒CX-_[㼞Z5A@d V98Kr# &>q*XX9W){+Vbd~]V \fBNC's5YaRYɆodTE7Dy@Db1ftrBHF%aPEmMfH}i~N|qA$Aތ?q踔Ȕa?h JRvޟ玽7?:?ʲ/e3ʮ%|Ƕ4`a=Hr.n0QzUh~R֬6x;N;d,(d荁,/Yv9%RىF'oL~ 55TX aKYR>`;{e-oLٿ7 |`$>"r ߺJ!]f@!K@Q9ӳC!Z|RXEJ~[>w9<4mi]Į.JiwJ(Fitrm|Q*oǁľ1?+^ϭFTn8΀W#BN<) RNz < (Bfg}HAMV#\9yH?-C"Aq!!y'kZ0x({rq6wŐ:p,?/BYQ\}dRK)J`L;{/޼gFiz? Zנޫd>kJ <6~V,盛̦ƹ3%@2;/kSUvV@rsBbH_1tl:z"lh}[W@*^UJǴ|r%'tnBXDY=qF/Tb+K҄ ˭7–R(\d+=9dދi1G7L| 6u͝.C:t{+~h eZHLM; ];*[|pkhRyMAH䚎ؑJ=iC3n- tWrhvDqK.(~<G_w[`Nsie/c2 a$ʦӯyWdĄmz/uxܰWWz7JƑ)}֝`17ĵ'r<-yC`lNrSyX.7?kk™1XP:={%W V af-Fov0b׻oz6 af0[jv/H]n9dZ}pS8B/4\%iY xFB+KL&bf@N╷B|iM:=W)ctM"QYVw* Qtn0Pd"G>KܹJ{Q| D(H ~`߅ ل526ZP\כJ!$m= T~"1MO02Y%lA?FZNʅk͌)~02ʔudD?2^-O0-~-u$4_֪)\% ng$e,&8W nB=AϖF+S>U yQ۵< Em/yͤQ*vgt+E+3!!gmbb D i KR`R$o:Uht*p`V^keO43mehʰ/yԶ\)~ygQ"igh9pSi,ij^ԟ? tdYZɬ<"e3zԒvDwsg+bRY$4{3^Jlp:) }^zqf)).;EݷO$thڶKѼtmҟ:#<ɑ~EF8<@Ƴ c WvngًXGRڐ'|mhݿYJYen|&X"Ie0,%Lz&eW2? #p8Fd+}% lUc|bEϜ暃Hijy J>_Nt<-pDKX,%`m#gb/ě =nJ(&NhaG3\1-%`*8ip% h^Ǒj⣔="O+1'${h"/;S%.Z~߉E )W)٧#xfțn>>PJiFF;C< یKJ\Cy9ʂDFCDO #'3ᡐ~/o&xCm685)} DeeYlyf"jB#UvX}AZ RvbV#(73j85( 8 NRıٕ\U >DZh[uEUwg<5<6ie2Z97| PHrTqXjt !JYs+?|?`1˚Aqpm9\0 fadt}*-Yࣂ|ƔJ}A/Q"qnQ/kRj$EIж{/cA">]9ks>+16j*.YݸK=Rc|IL%DgGx ؞A&pGa˺n)غ TΛE3Hu312u7'g@1s㟪Lx&%d5%n@~7ծ̈cw2KK9tp<dWy'hR1Y{}/*7߫J/W*ƴGgiVX , .iJP_c '}Fw'`GgCµt 1^>DKe*]q{Bתi7)+3 A]CJ !! ˼SΛ $|c 8?c$k¢㨭(.7ʋbfZV՛0(8aE2XqaYp^Π&́(4FQQJ]MV/mL'?{KߺS̡Y._ Cx #{IaUqs&K+m2_7JJ?跓0N{eff]vQ"TOqCU biV6bzMweQbtij]f rc̫e#sor19.v8cCŞWƈ}8L<0#h~!b%D;R(3 i`~B%691Yi IN|2tg/8Ji;+P ޫPcB (PC{o<} $i/Lmm*q uh]߫).pިb8LOq8rNhF4;lXڀOsPv`,*Q0{ߕ]kK[d~ROSH4M4qRPraQZè\_S)LM`lu| OWQ9b^?(h/H3)J<50P*='ׂ<pP kIga¿.n,~mp 1.ofҩ%ݗ  [UYuU 6Э"߲ {ܧ}'^D|A0޿ [f+l&rľ0+3Cr,#ͤ+WgB.3[{s▎ij6>|Z,3ӏlng'.ӎp>5ɨK1!f43n(1Ҹ^X[f\1/o@]NHk&L`acZ-`dwjm#Ho^yog2b{Gݚv8{-jd<{-31p!|d$ {{tV? nRG\`ݰ*\y|)e9}T"cҦ3ڬpdjBF;[p!•]S7p>Q9{ԙUY] 088ѣJ[HgfM b,Z8u5֜Gį]e`v*w`z}#F+Z߼gaJSEJ[*s,j#]cE,U?u YE@hNR<! <1#$c~E$lBC6$Ĉ]_iN^mtUt_3bk)1:x >?&eZ=Efr!C\TXYů/bzM8(R|Nt$a Iv`B+csXaػyAYYuk+3/N/h΢&Ԝ{2I rիnx=M'4~1wBVkP9fJڔwQ_4s3xDAU}{OQ9o,P6ΫSg#*%v {rŬ% Qxv_ &96Ŏ^, :;!KZ-I98hAy JueDDf#²Ft _Cӭ?3h4p۠6 2@f#KLa7K}:NkijHZB?suv&zc\ir]ux]l3v)k$HSve#VUʏ+7PtYDJZ !sZ77:v>J7&SBCO 6 <̊٘gS`R3}kg)B]RhÜ|"\aj;!yvii\<c+ml@rtc'+&F)\/3*umtΣĪUպxޛ_C:|pV9DP=g&&AOP;ZZ{^ך viQdgCC=}/p=83=>c* 9)h0M03KZ2P{Itgܝ:XPq(!r}G< Ɖ@iE_,u]K~q뭥X@"|~ ^h+ƂuaBf[&2#Ҋ!?ʯN9"!&8[l)Dτ^=I)vWc\ wD67b6)P6|],%t\EbMm&h~(͊:&s;% Xq0*6zG *͉fKN̛^D2ɕmf$Wg{]7mV٫cu6$Poe%э<ބ>;'o%hC&jqgtG]D#c)bq[3b&1wAWmO©ۃ`bz_ylZ K3Uo.s?vǤ#@carQ)SiD֐R?5l}6\XE<_pZAyF)FLntO.N!l/h%phKێ;^5k[ŧUa+=j"cK>~g`D4sCY3!ͧVA;VW0C}v'C(q˃po>~8/ٺvp˃^9\-#nt_ZA yy% s+韼^685 hq\uBl !=9EcKj>޲o^%hn!S틡.:zXA䍠{K]Vv)PT^铔y㩷/ 26eO WOB(/'_ъ &RZ&LLJ"pbwÁ'*,xWsCjj3D Vaquxp'w6*4tO񽞤=$vQuix@@XR\tN%ob'f|#lFWt~GGHI_\MFňbyfi{r%UH"QfuR2d4G_.ܦ+.n<^ˮNm(&I2~V;"qD &P3,+ *l5C ^,-g_CdVMނХ+Cz ,za9px/ Wt$ki=s CZL!B܆Kr9tl~>%01I:.%ْR*Ζ:l`IcXH,c$7Eӆ)X<񒖊yӎ_+C!i((M@Bǭ}Ro؈?hIGCݏVk6.}֍8+>&'q%ɺ}μh`f17+; r)a4]OiyuT"%8f5I3'};$o$$|D|"zou)Kƹn^j{/+0C^k0_4WG,o5G|2)AkuO5h}^_ZOOF,{'NJHJl%Km3#fԧfkNl . a=׿NVUo[(d23*}QrR`ygqƪXćew'YoУ.*=ß:p)|hv6\.wKFwoYwnYNq4=CX?0CDyyWXwSPdZԃiՓmw/vͭݎJ ӅPƊ/x\s諒/Ci1g irTxYuҿyRM;tpkL yUV_ ٤EAm hn|ϱvu9?l῜/8f%VT!M.Yhub܈d1_l:얎h+1"iVѥW t_E}$Ǧ:6Ub#1Zg`֡TCQ6x73U)c m[ʺU־#0?&XT˞J=#@>e`>SHh(Ť `[1o;il@CzuK؛n=]7qT69hF K'0 a"duE|̯|'+0O`;c1xAls饅g-6tXXLJHIhPw ln;I9u=]u ̟J /o3֒/r/|Y.iCˁsCpi59vkht c([, 9m~"kN$R+iԾTuB=Ī_Z_\8"=/|ޕ!k{ g$¤x@p~^m%G&`|L ;疙]p=Vw=OpW[-"xi0 8<.f^9K%s*s:3^RN:tV6_Rͮ9cpN}5Z4wp~iG)F@ r!OcLWcҸMRsv ~|-bDК1#n,8oMq( &ă\5"4u3~`?;\G?l M0qv7Wu;b Ʋ*cң +j!w tAcYt (C_g.he|ӓZ:2$:2r7T Jha5!7 t#iU?f'N:. EL_L%_PCrKwG8M^J9 75x5 +7T?l:͢Gb@nN qSw'PG~2DŽF^~CVXZt{&3i y2Y-uԃXUrs ݄Ss1/3at_4/9Y< 8C4i}@$؇'cz %Q_U1&cśG݉-(m'mc ]x;mضb+%ƪ0:J w1SY6t" ֹąB4{VK-C4tOq^)?oǮab_a1)+1M>lMsO?U@NnV[A(фT2~iue3av 5xӕD<oB[fPiQGbtD/-DZfKVWU,L'汲ƕWf2>%a0:5r`W =ȽҭڱtSef0ZZɊ`v_YTqў\B͏ג;Qq(.&U}rcv'ψy90Ab1~ >) ,n0!^IMp32\V aLvo=HG[0\nj_#t9/ Ni\h)@ma$^9g鰮ެN`ނuy ]Vr^ᄓ7Q6 k^)! 7(KC#:Ҋ"v 1$ض) ΍*Ė(uuȺCoj:L$׆b(1X JjuSSG}|3 e0ёϣ@ޡb\^ac _) $N#Emۄ6B Fz^ #e<$bw R-[۽WxE1֣E_ĿA#E ,v|~Cdt /Zh|<hwAV)_У uZƏWLHڇ7q8sNjMKB;  lS:ce>J&'3ni$Kݔ4h4@ ܒ麚y_maEt 4\\n{yAt%%[e7'&AYrOQ_gv{M˓ߑLUK;`KŪ$vDVY:)F 7w ϕZ~kт"J]Fjfw 7 )AuS<v;}Y|5DINdOkV苵fUDʎF8hsLC17{sq#7HWn՝H}qWo<"3DYdy "vrG rsfr'%k3PaO>ơѡ Q*j0uÞ8F% @ɸ{s֑+{fɤƻlnu:QܖYȻY~Uy% UT)aUivyms',@EJB@5D$NR%81e<+rB)H{s|wNy x>OC([T[ /V+`f%'In 0{|m%d|B<H/!טۻ:ɐӢB;Ȉnw )ݳ#Li"i.L#L8u3CM:>N],o&fQ dd Fu,3hXrH앀=`6Y'Oo򚼍WI/I.g GʻzĵbH4A D4Bw+=}/ʊ,^kfj.y"yK"jah>ZѻFw*Oϒ6o73aS?t<ԈGcl@;$JeTY^C")/L`YKT,r':*kUL--+\]SLfuϬf:T/[|R9.9VN@//(g#f HoH"Lǔx.3C]Ec{*4Bj0 S@XGɲk /sMȍ atX[d2<Y8ST=P=?e56ٲ@s\nMKGqH1+WX0hastH I^tߡ!$: Z9Tcc;65Pi{H~{S/ۅP7zfG^FgP_q.R&Y;3#Ja-]x~|9J 8@G61i&7h'7hdfb=%|f c6r)RU TC܏lyD ^/}wB7@hT,ܛV8؀c=&׆Yoǧ*[+*@zg'2,TRyzvn e;=yo.N+Me yvX˴6+tM :%Z):@egYn;Yrt:[7q,PTZ; A~;/SRr3E$9,xMBxS(Yq1ttxCyG%osj4u^1;ELMNpVB^ťu͔%ʪ=rYDughAJ L^cH 7kQO*5{E+2S;.pv> 4@+EXUJ'S k!~޼'Y`*w e̒_ѣpDhPPRsk$pfǚt2a!.jt~Cz} fBSG- [)i"9{G)-]_9e{i.̇lS4 \{0pkʀ$+:J,^P$X9yO2on 0EKKLoDbl¿ϢgF~p=Z@IR߫7YÚFj5B:31_ 69\.G2cakd‹7>0Y9G|Wٟ}$s#-(`e2qi^T:c{)@dQ!kבYc Q#$oGwLtv"(>:dQU#v;K龷jz@^V駣/&HNOyԲXꇖ󏌩Cv3 Y#HܩIf9 ȷO7K&>k,öD K7]B^,\J܃h4iKn&T8> dLD`*9G?C~q:Gn]g C` x7+g3oȏw{&ץnuGA3f \,a`bE%i>5&# xb ::rD*U_c!Ԩ ${62Tp,mзXڱ}b5wHe-a|wTj $>*fQ/z'{.1k ꊤUGFhy?4k}4YD3gS_ |RmV1u}Y{zSp.eGa -kRa]1ʋS,5zx^>w(6?@ n_p}2--,szT=lFv=1x g5v E 3}g}k;p7RB%*k1GDl$S=O=UX%@ULa,$vf$R yݸE=Q?qXflj~ _1 _$0M!J+ q5h vZ!B׳5@*jzFp?d1 |$lKKXaNƲ|r: sls_Y"Sx2،74ѫb$pgI<"-hkKokQ z<HW;j*d;Fŧ(Rq$ѝnF{ɹ$C5C\aD~|x'I!M#:-;,- 6_u9%3DCy-k'9Asf2)B+s)/{Qsy]9[L*+\r|b&$!jʩ6 3ko:CDsq֎+F't#hϛEEz@nRTϢpcǷI _nbzV@vH?:⪶gi==u#Y؅p@ 9][4(\κM?A"Tِf]Y0C쏨F*dszӾhY|]tE7lv>Sb}ѧO!ZȂ?ߤSG ?z"_[(y  ѭx}5w53'<{9?l+8Eߖm*3GVM|Ԇߵ`{GK_&F \,!Qʼno`ƓÉ ,Z1Zoq-t2\1S4*dj徭E/ B #gc-?{@VN|RW\T >0B#(ncW" HlPm6 RJ8;&7~K #hZAgZe}{Gq$V5s=E(XtT<5U)e~ ſ[]JΒfMN"ͨ Vs _Wa'ذTM)Gs˕Q' 7 ܓS uV0KX-y풅;Y77.%[^4/InSpgaڐ~B.Q;v>{Bׇ̼4 T`4jHx ˱S 9Cl txiQx1k3 BȔ^1"BMmCb9P! @#\G]U|E ѽٚUsp"'2d޷ 7P]=Bon3L1o %Pe՞23;ƛ55yz*nӥOOWRޗ Ow zC Sm:UR:Aoֻp!h2K,˨1:KB`¯?D2Tۢ埳@{7GUIYwtP.\^bOb T07IdfG @zo#~-G1~ҠD9eSJUYKyX$)]OgsWp'0.z/(c~MW!}0yYHQۘT&бF*HvF މC$qBfM7[ '+VyJpTܱS ??aqlNhJ&caKM[BO\+p30Ž(t :2Z­>9Ô!K7I6eTאՇ{;X7hSsI+h٪hMyг-prmz@bjm"hoհrvԫ .YB-WrnIanraxNK4ϑNݜZPk-QE{"xʠ!j\##!;2[cS[O:ħ6e63 鱗c)@u{:xw#J]\`Z`! #ra<h )(}Db:/ܞ^ֿ4QxpQiKaLf?sr"g5V.eu'+\CPZtcw`eY&͉cb (i̱vE:GR`V@|م3rT73{DK wN^`aΙd<*YpP g@qŝ$W@k89YX4HP f7@?#u~_JEwUUT^*`J:ƨsݓvU%8'ĴVY/3djCd#@ocde+q cE(mjExPT7[L6skztbv'&%J@T#ʰM[QDqA{_t2_`xDlQ}Y) 3ӫ}<;IRpxU@EXXE#vֶG4lhVM l6AXË0׃P IvFX% K[u,Wc?8J_)5⟋bαtC]BLYiWJ#DAgnFڎq-ȅkr@FU^"%s9mׇjȳ' qQT5uU6r,L# ]'uV'fKϴa_ aT+0^ +B5ɔ 6`%ċ}ȵ(MX(-;mtmyy]`gJ}.W1 { \DhD=y+tu#͔lVTw-&G@_ 'h ԋqJ>Q89bRlL(e+ۗ-}ƪg.O);({3571e®n:? ! WRX|D*Zj# Eը)+6uuܣj@ƙK'e0cBϚU)^]K4cݵ6K?z2`da;MSW4ݤɑS-ki\z1;uc +B H(8׏O"X] Шc^wS>oT6PmF@FIa??Fq ]i_Aփ@;`2ϊ 9).h݀Y\MmY4Q<9J +=ł8r1­Y$@BՎvɗ$dPrprю=.׻Qw%?S]T$n1Ԅ=:WD ^އܬӚ%'>O?,#@ҹ=.IO Z^}2_T7zO#7a#+p/)QBrQ.tfPVxoHfLJK9BSi>{Yה؜@%*ɚ^dAJΉ|G_ԒѢ .P5F+N0Ң [ĊP.([1 b7J -8'pOۧJb2ǫp%Y_kl]wVc5xx/Rⷯ=Rb GSPh츊kJ8O\uvRx_Z# Mg[9V@,y}#4%5 /~Cd 䢡#K. ǹ8zn726I9nN /]rd$v!C'0%AKkL+# |xo]'"QKB`K;`1Ǜ>SGcQJWA6 ރݤKAt!E4zQ&A5Yh|qrWNFDuX7bˉ7|(++1+ڬ!ɨJاQaϽ%Bhfa6~Q{w4#%WI!"JfKDݾXe(tjvΆqOpJ :_ř:_GꅘWa_ڞGy4n:K_mnj]S~SfMߺHQ لFq#S9< l4}R7{’UI ){ڠ()Hf y]w-l?wMV KrXldиENʮ!uw6Z,zya ?n;e;D^DwI(^T覫H@bKwƉ2ˋ3 68dFcY!^7\_C{ M1W).x@{bzr>ބ[@)=W%kjs Ų-4\ثf~I[PXq½ Jx=ّ3xfQ {Yp=?MQW:S- r̃!2o9=fWXd"IE1lWo>U3)G۰k?ɝ+Tcyk薫~%iq@]P k!bM>_R`"j׎SōEQ`+4+X;+AtVCEUDDQx3U8tA,`BHceO!;fW1ťlte;#^n*Q?` +,&) YPC K-Fmbf<s\r/3 p?IjZ! uڽz51&`tܟLr~^;$et2F%RM3XuGs436ğN / vGF#o^a qQrhyPg̋*K/ip4N* Q&$jCQ6;}X+iXfou][*w|p}̯Lؿ.T>{/b ]zsE8Qp)3H e9\~oMSϨ6ɍgL*y'$fw]c2PǠa+ciLYo|ڔ 5D<\Nuy>ll"a>!phdcGxh0FdZt^"X8wzi2[UTܣXgNT~}񥒽h \ z>ߟa偧F߻JJҍy,1$ [_@p4 "t}QPƴڧۃVotӶM|<qNI]ap:?~œB d($+*jc늽17cQk[O\9ZⓇK>pI̮}313<<[v ɑ:NxKM׼iE0ӬqZ|DD/H&krUZ,*Y;g{1Se|ԋ%S=@ 4 TQ&1zJ˯i ͞U#0VE-c [D[{ۂdB>wLM+T#R\tk謟DIWܾKgknR[2e$$7.cL0VvbhnM?~&.@.!T(x݈3V= .c[trdxPU=0FV&cwF9E? ZTCӮ9 byh5KZw lD*ǡ{6(Eh/wyT;-},2“sQG\N3;z5^u\N\֐40 JSÝEp?[~#םcɨ֢=өݍ@Y̌2%މ.~vMHN!Zlm> ml:`C[!"q֘\ཱི >;q90?{ܛ| y25sgRz0[.,)yA={hsDb ҂v7I%LLIr4D}5Tx-O sFȷ\6cHVp㌥BG562#wj*L 劤Jx)Wv_!k\p;ug}Vv2mo>1o<+]%TrK'VWڸ҈J8CrKZ#BՐzf]5dqW-h5!ЍsQH[9 {U=4wDi`j@S3bproҽΜ̌Uħ&+7̶JC N<:U5~_T 6Nn}2ƌx{w+4+wNx1A4Tx4|qKks@!.T]p`QN.vb j*T]1٧E39O?g]i`M~O4W2ѹ :R$"~QH'ZQ}!#!)`-ahƙI!kKPܢNt +A=EX}7fEyKD"aG(KYUJf!>p p vu9+\&6|0WЪ?1xKϽN"CVHڎO` ӹ]rWz*R-DAd߮pQv{3đ=j ؜w"?Εp}Y09 `^ŭ`ft=7iu6]}~\Qa:LN ;lzY ;nkaX\8:]WÝBUS.HpRqкW9iw^Ǿqa+U|'5èqז0(bЬ#џ 7Ƥq&2pT܈Hɠd]]~A=K,xΓC_fuS$Dbb3WP0=}(UeƍyX C"2`+^lt,Cb";wӢ8v!_ysJ\t:Ѣ')Ϊb\-_3TQVм}Ae֞_>%x na)OzmF(exvŽPh BRt)k6v~F?ȵ2ZĹtj+c~.O#)llPLK:a|q|u"Ń5/Z|6y'4q_OUsO ùcdr5]h(YvWL$szxlM{k;3]iK?w:*׸rO HҒPn~luptѴu4Afu;O_](An;Ѱ+GC#_(ոR\t‘Ę܌3U'I$IpH>_FJZz7ZW/TT3ƻ1)>w :dA&i&M6\QAGe|7 pK^X;RmI:_zZ E4r; _Grz>bF9xi"($ii"K!nJ{l"%&kUP "WB+.G# `քEZJ1e(Ϡ^p,Vk .EM$r`ͩe5kdA}S Z9a{w<ƙ h 0դCVH9 KT@U tF\>zFO9>eƗ?* t5F !ӹ1@0-^_.^p<0, PW'{U5H}2<0k"x8VR_ލp28 ?g *J(t zW>)zt/*ҀڞڸhG,J'h!q !65?\@̵ءٜ(bqy = h~6%#haGj:VwQ"$ hG#w?sX݃4~Gu_ |MJ6'FZamԣ/-4gr) =9bK](:B{w30I0ŧ)ySlBHN.ۏdG"~3*9%ýV Laq_Ǒ7"8et8F2sґ|`_ מp=Ĝͺj> H.)|퀛%hyb ᔛUb&≋=gf"x(OZ3NX$G>`4vz!l]~q0D -ϛXs}6x5@mSҢ7CeFHsQ8 WAki^FE[eH"f6s-0v )9"8Iw2'R5`iHUgbvJIGtPJ\! `Kz tXҾɴe{Zة^#ћ0p[Oj×Pam5ub];sI-?:9, ϣ;hI 4)b/8Vwjup*b8O97<ҍFyHey#Pty8 CjrL}9Gl%)؏)Ӱ]N188 9]goa0s ضHZ .\.ӍWAٷl8RROXK=L*!`|5UlahT)CN?KI00{/m`wa3񎻆‰:\N$Dp?cAg[_aCwFy^a|q7tPUa 9"mZekPYo5(fD . , 21.©yE| )DJ+D7Z%;N*9D_@jV%Rx]}o]KUi'aijI'K)q+U7.dm?&~`K ֖6fsaiҾ%fԑ 11e\Qyc[HoioėHrǺI륁1d[uSZ5IfSzc&zbTҖ&t-F2A0jHnt`s(LϚ&Qu%Ɇ>XvWߺp93遌;۬N!LrndRbTpgzff_mBI$ :E[ K•0?ז^]A~[sw$qu1U6o4WYfo<{6L񨞸vh׿%mLP:5;T^h\Cg;Nj#'+ Cj"U9&H̗6sA%)u KiBIWm{?l6p]FжM7)l ت_26 -YAY㰬W8^zQo&Z!TLNNm x.exzQ71N+c+v#!Hš {W8asVU45ŴP4]ÚGFzlolR|{ѴyC+=@ 򸫻Z`CKX2DHaE '_L lKs?\HR,Ko搛Wyoٱ-R8x %[1{%`jo3FfBxs m ITG3dLGW@17f $7*]4Es(zּǍ_c#O#׳7ػkğ@v~;5rA)Nzi׃YX:y3\3/)oyUARD}YNY$՟֪td5 A@ˎ|SsϚW0!e(GnFYgV=R}Z E.$DDxc~)DjQ_*q\E32~S6ϨuXI^W3OTF%0I#jj/yUY'DYPa6o/Vȹ&*SĦa:L!H$< GNm(M+:X0Ucԑʱ.4l3o'z&J5QDԔo:i8!di.W6f3a s94nxQ_BU#2y6.4܎rT/ZZfb\fpX$S};D#Z.`G_c $Ӛ̳mZ[$FQ|BkCK*D 32joчP`dzr3 =1 㕔_MOtf-jp,¾Ƙq;̑b*cbZ1i؈I@Tz1 fI_VO҃J>l6,DGWEhfWW=-'fz)gB^ɏJuu%Q?! nR1 g>Ej[ yMD LI#7TrDmVؗBE=(CXՔ.,N̍۟ 6c n`7e{Ggۆ2oM.L'cV͈$@>OѨ<Մ6 4A- >|Kp\4>* QxO,{j:eUK>*c/<=ʋ)^QЁchJ1p]hI^ Ƭ3jA8ny:WIK)α,H(dI ^(وШxEZu{x#/KÝƨvڞ<.¦ Uӕ|4+~BS!C9O~(IWs r)3@X1YĦ9tr@e8q2H.@|vĦ2 M |pIW6k8'@q 7p2j*O#Mȫ$cH "ke)q01~v4H|^bA/(*R}GfS146 :`G萍lk).P8u~F?o!;p~)# ɹ[t%ؕ/ xؒbN<⑚JWﺶo4>(DXImVJم<-2:70Lр_$m_d[ep"6e<-? 6=J?v|eo:-HoMwu_ɺwIZ9+-٥ j7ʇTR$M'J4! glk;O!)J"GiΝÑ}GTMl5^<$> ]_w0%-knXK"ũkR9mHjLw%/k]2td/ݿ_UV;vX\cP*@+a/L!aׇmABPGu,^{ 5zPn=\xV_jkfT Dj +f3û ©NިHu 'RAδ|0Cumjy]@>Z,x;uj;4wrf7&m^$̰(YRn7M?_-E^v^#A;xJZ{ydu|AATUw'Hl5kQ,3LƣZ0P, O:^ ec:8Z"/bP\8҇[v9tD̂n[0v#tD[JD%YHL6\aඹ^R~jb1b(﷎ʌi˙\=ʬKO'-[bIXբ\ Lŕɞ +4-_E7g!;U@=[!O7lN95=)Ŝ<}y C+r-ɰ3Sp$~e.TV\r1.H)Y]Asڽ1ISwsSʯe+~M,\aŔE򵷭ݥX ̃޺R}r815g2cChƯk!blZ]vw-Tl ;Qd]Sch /[{>,tqfMӂB)iD͇ͨ7c< ;c=-G $^hK$ \!Yv@ܽsȏ|+c&f aYlh&z@ \z댻KPY0ҡ' JmnĚrzIdĠZ)4?{hܛw6hTIҲ8< w>Y]0  TT|'k e~ ܕ~OU^X̲/J—:#\ PKf^ҏ.p߂^~ vn4-T9aek52)\d+"ZXxUۊ\¼oMqD3Y=9V=~w/%mA+# mk)? ᬺ0+)Ԛbw`2&jv*̒ť)B> WsJέUQZf')r/9$2ܼhFryXN` Ċ6CsL/arM )?IlNGHGp~Pk*7B,)S(Ksu)U(Ԕd } nWU\fz-V8wUwN˫0xƭ Oq :b-S igMv $l&Q/ߌg/`;ױ  Ǎ0V RVDZJr;4&VV / #]ϙ| S~eS9mf!t$dS}̶P&4"jz;N8BPJzd +i(#Gß|g;sDڴșl*jĸE\ʘ7p?3^@;e{ +ykpW 3rT`"9[\Ɵ@f= .8e1[[ e .\w34kf.;J 1,~ ~oLJ/u K`b||`Ʒb]?%cOxTyZ(UI{CUWdEXN,,*4tPm~+F[8 MGtSk1xRCޔ l*α rNZpuъ([Ta~Mq#pv{:Gst@(fluVV m;鎸h:w869+fHNCsY8WZػ7 =D 0}Ty=ؼrĈ}n< %xDrhWodCƙ `^rz׷ڛX݀z@τ@keLiIk?6w!`-oҫ4AoZ3${R_313@<7'5-[x]g֯n&* kM2Lĉ/Q5Ok9#fn }ŒIc^S()j W& H FXGChP* 6e!Z#YH܀}⤇A7+3çj.Ev.?A|VqLl}L!s-xPs_6UR&ve]&I=24jKw<٥(Yj"}24rKitn~ZLs^$j'^6}y]R33uyVDm0wU$Y9 @.dPO_7g>)INTͦ89Վs.myYf%mKm7F T>u}e> {eGRn`H>m邰$)7~`! Ӗe^YI>eOI} k'#Rvh?; *i{D{b{ `7u0>W^vIpz',GR#XP]E<Ik[@yd4iZR1!ĵbvڜ(ˁ3yKjǜ7[2ZwW5YmYC3J 7*;P0b/tE|R;@NS`e'h/p~ͦb(0)dvO7lψHqj A0W+w:}.tQ5uTmOz)ל<_Pq?UIlwo1]t_i4t0gՃʠ^ś!Ee 7}y^:+I.I[ZN~yPT6f42]xpTYupz-tB #*Sf#4MMjjJ=PrkDGʄs鑯(bӲ>G<,7vj#  uÎA zPjph0_(R,HQ׊OȎT -%Fu PfT/4I0̰xj!rIpie]/G8I.?fxxF[h_>8ɳ+focl8]e N P0|jĺƉYAX\9J] H_߲xPΒ0hi>C_~Uy60N) 3}m4U-ڐ͸]THhZDWRL)^ ب?dU*˔E"$fGB䓚YRgѥPe)uPM>JQJgץ]Vw:vm!5_4eYNA`>S'T'+^5ao(J U"S( H!13tkuk~#\V|*nV/05S1ڕx|.ߎq  #s^+D˾kl5lk/#.In $6ѹH䳣w(cvUz[;nyfe EZu(Ħڎ?us:q)hR4r@AG55|_ָ];K*1*|?ׂibXXz.ڱHP^aNQ5gw_d/A;h`l}QМPu͖D  ?<`VDG`B<(73*PWwQ`R<8^Y[7k ж@Q9ۊ2,'|T㿓& kx]9k &<}O[gb[bdn?9-LߩO}XLWtl tu{kӜGZG$@v67uDžv+s,ռ;R@9h8K*:jxϐcsӊއNZ@idRh]ȩF|O< \_P.l/(f @Z) J pG;R9w(F߃C8D+ -snr#|Q,™˻(NAI_M+>i[cRĴ/ee. %껪󝋲[\L&Lꋋ; N>c}!|z,N ʚA*K|O.)$ۤLaTIfp LQHwӓ7I; `Y D ү2}>3rb68-$:1:S!_O#m] \ \ $S.Q3Z^ oaM+qB!|ckWZ#8HaQŝk&{+9ǡ;iLV ^gQsTQKa4 xQc X8ubS.@RvCwJӊaK\DrZe˾Jv#vvg 1pOf 6lizYܩREĴ}JWhj1S]~Q @ W%hcmx{#3#2nEoƙ'F 6܏I!IC)aG%|_EqUENvKvt8x cv_:nQ0:0pGfYKs2ӽ+,h0YDw(to 9^~XZ){'w0s4뼃/hܐMQԂA5 Us8ȈF}3Ё;*!Aޗdb0 D?%T. O 1tI8]$3/%=Ne@޲z%z9D M!ihJOpp-xjŗ&wuzR"t UhWKo`fV'@IĥxC%}H # IRHO  ){tlNp[EEuG'1Sm39j ,%Baeapdгv+]fnip5>U#…NPN\r۫:^lCg}՟;m+l ( $&Sq%BbѮ< V? ">=&kN-~Hmw`,i!\ D&b:V;veZ1)=DλW[{!͎y3|BnOLcܬ$+n{3j YhS#|1O)nC]Z3bhfnԣi)26<nI(恹\r0+2+9f Օ*maڌZ.!@!ZLWWEW/'cLY r!JrhW,[gTXYn=i᲌p0rgI҆Yۚ!=inf\oÏ-<4(K"G^" ×sʲXJx "AX}玌Iե^SɀX&=QY֧g} "{ LdR5bϟX7Dvb́1w{-A0э(Ѝo䌩3(YV l]mEWyĥ1aJE7`ۛ1h0Mdf<2dZƍlҌh)2O.1q|U͇` Ю/zO趞$:M*`1cWYe@4]ࡢ^\~;3aXDL]isz`=7ǢKjS5D\C 2j`SJ3 '[Q?GM|1j+e Z)kD#@ +D  "Ϸwn>x?G6+.GTn,5K=N!2]iTTjxdQ#uK yJE1%719ј;URG3m^ΎBpk Ƅ}7yS5K@A.xr2oǻ% kv) Pgh g4eZvf]+:|xc4ܫښ*rN&YBobh i\W"mft)JE[1(0ǝXF9X"|p%+{:4{:Md!Mb= Ľ}QazpvkOȄn%5D>:5-*Z2qGRXnBͰX/,w<fYVcrvaB%&ԙu4TٺG+,?mM@f /\u?w+\1x$ǦIQU! @iRV5Vx)#GpKc}cApɲV *KH'8~</yTIBNFDl/mvnKݥvDfj´ {c*|/%CYoW|V̒ Bg oܠ-B#Y16Xwq aq݁q!q'nZxW!Gd}ܕ!4|C\6*-F: ~18nkAAEwegՑu)'v3KcXW}+Ygs*WwJd?&פlO'#_$ 1;\t!y퀌ڸur H Þ!_{tta^]Uݸs=|ئ1TaA;FoRy%hOgN:U!lm0XPJZCKOx*q vf-PK9A* ^‹ج2GZ6 g`^ <~Ow vw|]BϞ誱Rݞ@COr<66JDa\DNElF-z D#AǁWFHz]QH6:;|H /9-VRl2Xe\W-|b'W4 !R{L譍7k^ ,P\7}oMMaVLL"ݐҚ9^Ci)[5(OkX dD9 0 L_?"bbA&[lW}_Wfu@ .~+SwÆV 2#W@ c1t9˃Lj(|~b3N`aH)k޵oʚ(~V|@ cܬq%u2\wHF w!(z Mσ^ocPs9UKl}R5zsm!S0 c8HTg` m⮫y~nIAm6b,eAn|W n.}tT>2`K7E=ހ+(%+,OsTowlxޚm /}{s*lHc?/H"xs{=Kau.ZQ^d=g"M$3&>2,ddzIy.m3fԍ C<'Jp!1swEq1`[' ݞ| q*m-ښ>lT>Ѝ{.)ʀApϥgTח~)׻ѕ!n=|n7=\U.GҧW%Jdtҍ`#hٹ L(rzGWx$a]6\䵿s Yj^.v!)HJO ! mjͨlz7'b^| C|Sq mAw~xK&jrZ 6-K&˒{Z W5Q/jۭ t 54NFi3K h74!7F7/>4~e3K 3yX%01%P7p1)/m4uk؛8kQKoC;iT´[4"g #O@B#=^ (^ @O9/n(lԫ2˧צ>C'LumeYĚi`8$O(G'EF΃k=8mb> 9.;xW@Xchn_J@Dz1tڦ(E pc'<Is=%7Ce0q"߀J\a/lФs)D`ikFm(C{3|G7vi'ޚ1}STV~6Y& 7My3lPU*0ËÕ+5#LF*3PT8U@"rp2WYu߁k0S>ˆ}Ve1Dn WǍ@-tf$5?0J#h-xވ:ħ)SsBϳyj?,XH})cI } i_bk]k7f19X^\fB&?Oget(lumeb/'*,Af,.?!3)r*R6HWʝ݋sŴNm>D#YWgE~Moq>^$-CM\-K&j8J:I"YOAuJ]5!Q{U\lu=,>Ó Ķ?69Sz*qqѹ 42~I'""24 ^EXka镆;,Bb" ӃŔ8y2ކ{ >6e"lM ,~~d,Ww7WO_Ϩȕ%5b&[s. Ռ(s}P2'(I >w qG}_ƞ)DL8`?hLQc-; 'Yα8.n/bD:{eʀ꺎jkKCֿԙ?"Oֶ5r"o42h.pٚl od9 RfF y73Yt9rP |meV2BɞXa۳$ 9N!;SٔM]h|syyyPZcbcUu8-+\pcB"CEWw1NujBIL0;z#y2~%l췐xP<:UeR6js喿 gQx~lFTމP?/L=A~6Z9%*Bmd=gEE,s⍲(KB1VOÆ:g`V0xh`WvZ, -iEkĕ7Z$#ݧ>I{?pua 4ѧe ~T#'W.ܞA `6'VOޘjh_}s5w6یQt#@ ~sbڙD zm/Bފ_G,ه ] *'BPF ,o̫0mnM(Ir 7d߆"A-;6sy"@(C)8^@(}PvsFe<7xԠ[SGbSk8ZhwďbjRkգ[VMBes8IwAn \l\]aPE(+֣}AzZG=>[we RȊS?h4,=i{\SH,SׅsCT(OA?#b72JKu:0򒩜Y{=~5?ض4$pVm#';񚻉Sߎ"㭬{"Fنsݽ' Dgg-Rp{A߬>{wH9 Ti_Q Tޣe eRr(Ȭِ3||גsu#b5gm\2WJuvu 栳4Z ߥN`Ep?Fɯ.xV/F(vaMEsqDny*Eס^ ql;:g}6 { !Js,ǁAC`'{t ? ء0^> PWx?I*<\p: 4ĐEM pEu8ɰMh QsvW3ui(H#]U]ABu.>QR)ld!Pݎ9H*ֲ [wP"O',yZ ֛}u)% {z3-_](-ZnMkS%>y%Wrm9yK'~p\ඏ1MPyY6wrVsk 5 ceVDdzK$'S0!.]+NH=V2oVkdn ^ )š\0Է8oN@ =A2Lq<zpF]@@P4V1dPhd# /NG-5O7I>-QdcNy ,K<^%;$ԧ$4Spܼ{1+n&Uw \ZD.N4;E ) ]PiO+CyݚƭVœr%pθ;V =A\9 Uopr.g"+y~\ˌ lZ]x{RX@}砸!Rp4,˕_IBky%À٭c;X*4W!R )$g3ݤNmOO`Et9y kq-th5]$x|M ʢN(#Hz9&~?X/8,%E-ʄXs<>Rhf\Q-n<ML sg ȅG<*}o҄}FL!7m;t͛ɂ).xh CwDK(JЈ01^pn}ȁ-ͩ$nTl1ʤ:ټ)/Re%089 P,eВ>a8𼑓;f|q@(rVNv I E9x%ol3<9@\U w"Ng?Yھ5q4KOUXdDOgȣKt6`Á_0LvUB^|s2%(]+ ;E8l[B"Dπ;|Wou~Tib ۜfZҞo`+{mΈ@O5SIupvVVYSEy Sx]̈́vLÜ&ژ+pqa8BZhu)T #n晣,`]fՊ#wWܤDgrRO Fv]n2 у%GZItg 9a]bLK^z+=[ `MK7AT:OxU0RkE &)w%87Uzn?;9!cN+"<)LSwlȭ 3e^j(|1C SA0ҢLAa\h5ᅄ~ e'·=~+B_݉; d&z0IUY8`{75[G> 'ޖA>JрQPo]"e07}BSp|OC!san|6Xo~DQzlZ๫:cΠ盲VeOSjt٭>)X\}*^p*6 Җ͈㛵ϑ8jm]̌Z|Ia^.طZYqN7#[1~w~@{!^N/ u%z9?JQ;tr?~-Wd"Ο.juAu;J_3InZ"JQ9eV8u-dx4\̫tHĹ$7-.=t2nk`~bYBmөЪŠLa(t3Yf8 Pv Vz]e g0zTO$up4,TH:#Po7@AS6ÙNfI̓0vvdi_p%|hP3' LP6'rX>^7Yo _*G[v12&}ke,fnnRV 5R3ܬ'ypvDI%Wx5 }{h)! ,E4Hzu}pƽaxjS9=c; BBe4r-PG>Ӡ;lamo. Y _v#8]/u;CIGz#[şb-?1j&LhMv(Pc51=G]3{RXm+0w@ jP0fFYzC q18iL1@4+ī7H:\&ƐjrDqWΡݷc5XW64UלLi`>@.(\xyHY|U߄sd:CI`B̚{ 娓1c2cvXHdy - ^h&>w~o*/>yn~!cr|I6[H4RA[7L$PXNȚWn|m!Ӑc ,&yo2#f Vv-WߎasFĹzY;0><(u0o`=W1EC؏n> 2Bfv1amL7 Y(v?kI(;qztf7 =ifQ4qTb,bPNr8]9i6`Qlq\}FtPX(Jĩ9~0= 487peLDSV΄R~ mxn c H[#UTedڣTAi2Am}!d\ FtQ-^g>k}x^BdXP{yK(Is^QyE/ '6m.[:t.}q_vzEd_' #NFi}{42-Ǭ{\_;3?u -@=$P]PDtU )qA"hCmٺvtWTy؄+oR2D1等fկw"QVCꜘڽ;dH:EH?I9JcaYyX ΋4tw-Má8lb눉_%pB馧%y0g9p1'o@s@NeCt8>ѕ''GٻFyRm%$,Z*2oNh 0QVIDAkoxk޸W!sSp,ĕyK6߭,XWtC|Ԝ<"ג@wv xǢxHLDr;|}2^ f.'N[=-".Cԫ9fu%IfVe^^P5DFʪlY}SZhVV]^2~1+ϭQXU)!ج+ܙ+O`$r=AC!ܾ!AgwGSg%(#yeNL>c[{c躄e"/,s t  Tz={請KY3*y٧!F./j0y,Ĺ)yE bzZo$qW>x g1  ɜ9:=,H~|\&:xSje;O(AOXHy8G!J`%hRq7_iއS.gBI9b"d꠩W/~<3s> $qW( Y5)Fׁ8a$b!?r{)r j29q0 BCOkZ(ʞkv~nFܬă t#gчNVa}Op)tylcП>R|ñCzy,`A]} ҸnF3ŵ_/{Gű>rکE21 `9%Ti}N+~ Ia0 /c 2'vLLZHmֲs髗4j5۔M[&},/i#Sڎ sQ$nXgGĎV6 K$8u9kr'.1M<G=uXI}~%Q NxK#eqXAUQ"rSZӿtWڌ Dl /j%XsR dFtvv$2/qqC2 fHֽN(d@Ƃ91YE>vւ6וAKLEZ۰оKbdRehlLj:Y+ٸDc;c3jI|$oK8{#RMykLq-1 7܉K̙"=dσh 6woN@pHPhAn;0t#|p Hi҂ָ\AXyUie&(&[2gd Ku)[QO {7|^$R_5D ծ lhKsPX >^_Zbl?} J(Po4Hl% x= O%8^Tv22iӽ  9|G0yu-OE!L{;/qЃt) [e8Rr@tgr ``^+kߢ߿2-g{_(9M̱ ]#T:}s5`}8ңOss03k xR!@#N֊R1H49G z\iΊ)5LPm\eN'(Y#(6}܆<;V}Nb`Tȇ]ߴԺ~tI• v? 2І$j,mGG/Q|"W]gCvGޜ|۷Wa2G,n}D"~;*骇U7ۀ(_Lzh퍻^kwnr%j职E9$yo);VbM>[ECVGS]!QgzfLZ ӭ*qߤ.bر*9SQhv'$Nu 3hѝ GmީԄ *,^Og9d[-בJB=ML~n 5unj$1ؓn4<mvK.OkmW5X gWfQgY"cG18g6&}ƿ*ΐZ$NF"H_#(t|m$gДxm;)C,6Pǩkؕgԏ5qs65%sC rL>cw |S`wٴrm:Vh-c$ V`l<5 _Iuyx+B:|_B8I6,R 2ER&Ґd~'0bkeyCs͐I_iWm)j]KI%'ׇ`N6R]G2 egеG`G܋ʧ%I2D|OB7^!P*. iϦP%-mv1Ve ז9h#jL 3i`kʧ^ضc.S/ -5~=YX=|-v8dX?)ٟ[:])xܻ٩&#VL_݆56<$:AFHgPVɓE cы'"$1w5d/, w yMpV(y;|_yaR;ȵ"IR, m Y|Tjem]=L6=D,mL5QlJ_G}ʄpׂ d/Zl9lޘ ,wD3\ZU$ PbE4#tCڢ!\=G7ʷ(KB ?-坯]< y #uӔ߶XNHhm|V~X9Ї,lA}.8Ʌ":^aeXA❦b^'O{Zlߙ:Ȍ:FR_rZkv[K}yw}si x=TN}+4FE@iLٯ̱jͶd1T(*؇ ~%"5o(y=c̝ލ&1IWx{ŽY~L`qQTX[Y:a!1e6|l1U7-sLH ]p!zR|v;o< w Qd,9l'&*94?kz%sU,6ѻ;V7!9ܻ o·W,~;3*C3xh(3 n9n9%Kx(4&:^UTq_o^%V"-"H0R֏F9k/_Z錉ĮZ ۋhU|sࡁؼ]QK69آiG~X,҈{J]ͭǎFVa#DfF }1(Ni *i> ٻhQFWM/RٜoFW(F8n yqJ?AH\N.jM[yaXz-}*P>MTk<s8hBʇoO7Pto şT̂+j5D@~h|cg̨+yBl;yח?L i.k=)wQ&23{JW~%H|2{f2z税dj@IS9*4vjѽnv?BFy);Dk2Aj? Ve "8.CgM3wMa|mIE:&JAݟHh%4#ih'΃΋( 1_g%'w·U(gͅ6QGņm.fI~=tTcܝ -s豴P.'3N=F힋{)U|(FQ3j* ccPʼU%ʳF-n$S n7=)d7%wS2<;1DQe9* ] ݗ;ΟJ"2&LeR` SC ?iį{g@e΁Zz\ʟTɣVH"v[rGDèe>-)ST=dyz Mc^‹7hVuϑ.b"b3J n*=goo^ɑN7JCPFJ+U*,(X-3 Y~^;fNFdL>?Π+ŵ;~tD/-ϔ5gٍY`X@^G"l[h'WEz€ wgC00gwA#gGpxZ[;<΀'睎dt95 [w|6foDQ6n4?j->XiC1LrZ+T8B4TR*cLcԳ1Jk_Uʪ?F+iKmmչp\:t*9\-IC7, N'!𪸬DT6K`u[N7.`D]f8e O~ h&`q pIf O2̀lV i_Eڲ:oY.\%*Ͱg&@/_2m(Tl׉gkPvs/`mYXqaUUgۉpT1yb`:" ]ʈ~D* 9Igp!}rhqNl~ϘvHbmcݲ?Nҧ0EQ~:|}")nVunYֽn /"Xo9g,@Y~DxtyJO"?~ZvG䩪[u<~5Ȅ~wan=[/Dbm:5TLJ<](25hccW(~>+g.k_*YQsbi\Ǣm֣-6*F$ A [2Gn /]Du- }j4n}/ϭ.vmu +H.)by,Ic)&`ֈx5ády/f{^u-w#oͬ$ [ aБ/}%KYs(#'4Bf H%]5g3WO,L#Gr`ѴV@d4_98>PYN~Z@ Ey Dá \dT}%  ,&?.fXgty6MIU^EXkpb1ďu- I7(ibΙLUE\+j2r5; k*j|5n {V E[ a}|gֽg-/s!8!q^_~ CM0#]&YzqIHBx\8j֘,PaFBg21 j:I`$:&l`߼ZDNC",T0Rdp| a]I͂b֤}oc &5%4AiYJGq^Cp*Ň*£u)\ϻrSEd,9Wzam0ԝJ)1<vAP(hDBޗXU_c2IhKpYS00BF\L oZ5" ?5} YRfT߸܌l``K~9O/e&WP\o:t}е19CYj!)zEX-iDwlfŠK@/qRxDo?n*#bN4{; * n=P#ӑJv7e#2ްbHCY5'Inq]f MRTvƊaԞ5x[m f^زrh:n'\w ,}w7^ݩ";*/(x5&}s"yX),P2;Կ ]Dm g PW#^ʙ4 AQlt&Ț.mRGh Z>@)ճ$5I ۲XT[Qkѕ@P#!>VxS:8+bHE,6>no]VW3fѿq2;> Wҿ׮C,.W 833rL^O N4?j,'ca; J;US7O-',ٴZ+|Jm*)Z(0RH)ƘEsYw|st ɨzM%yVW iU @÷]PdzLh?ϵ.[d*V ̱T <ȢVjzHkVr V$H5]c5 S^.Gh B-@2eW: "FRq͙>hd`.w_gZaj\M0A]XzzG!4!q!c9UNC( /2aYgS>N4CQ>wyvxxYJa%hW dxL'/JVTtůlV_~o;!YW8fQS۹L#uҚZ5ՉVgv}*%߽LԸ&IeqN)[Ŝ)ǵh H4%2TFEtH*Y\}#_Gk,aE k XrpyxrT znO:Hl L_Vxlf/DϴV#uY pn:IeSÙ7Ps^GŌئD؟[6Ґqn.4Uͻ"LmIɺ*2x,p}kLvRu/k+&.T%|#VEJSo'8PRCoS H7j&h>XvRh#l{~ԓJ Ik"I=TZCYa^\6$znJBi&*=N*6H)Ւy>"^⫄ae#yJ23Pp!{Ayc' ~Ţ1 p9''&D|JWw`+?(Yk*+7 *<s]*9 wb;7 x~:a05fKb` X |ݢ* 9q},-QԈ~>4 uP"~Z"Y)q Ƿu/nE >ggV(R`'} q(Ի}) 8 PȒE-lV s`3t5s];M665 ihWx"blX8Sy^YFf_@(N_urXN; Lhkm+j^T0IwҬ/eMDļߵ$ٻ#9RŒQsXؐAje94vY5zĽ?u ;*t@ng'_zukfK%YebAB$!Exʘr}.!2cȷ a6p-l(L#_Y~i& 4HtGp^җ6cscޒRq1=8ɜ->`9m1[($O9~3oZ$^r- Թˑޡ3YGnƧnZDkɨ D3h#|AC~CXv;F9rk:pOB/V¬|RxT Hي竓j!D噠~cr.(JX&SXVx!d w )p#L3*-Z-?BsN=` &m9G!IJ0_{2Z sUWP#Ht݇l y[wS՘ٗ'cblԶEm՗/.N[2F$Rc.aKGң\'o,ĄESEC6]rX(VBhYg@k|_B^ᛌF_R ݋yBet_I!?gHIs٢(|[^o*Lv7)l`2ͧKϼPJҭHv%(4ޣ}${M AN׳j_n[/ c=o`!q`%6a\&-~2O|}*a"-eìzGa\tڼ2GlhVݰ\']ΰ}'E =̶A)d}%^c̟RW1[Q5azJ#YwUlu8#J%U(0Nq^`E@ލy!:ǴOXRV\>#G;9 ,w)Ub!OՎЙ3>Oh=;ZeQECw / L+w. ]a=Oy8AJræKy zjn=] :AS >EʉV֘&jPm}. WDr吰6="7gmx( XP?:""7\6L!`i<tHRL-YƢo)f]00$(N_0 DyX­:+92[hu?{;(ϨeN9X.CcpsJz ֒`h$l9kxiU"A!;!Nܾ9*>P&P˦&o%x}vQ5!Ŋ&`Xeyrj #Gk֝Bt"؁sCyW6vеKR4{\ v&M.4pr!ZυűllQ.HDZj%gɁwS 'ZqĹJ VעE66a`R#_敇BKuHTAޣ$()s%10(nP$kFA#Xj\W{yDo{"yŴNWP/RsYɕv#;tE}\z;[*4PvExK* 9kn, wP0",Ģ$chs#%bTBO2)-Ԃ9 Fm̱`* ZV{Dj"dx$%p Jnhfrd26dY2xx*{4Bdu޷٨ŹirmYoGղYU& (^C3[m0ScH ]-ֱTk־3t-yDM1FIe L4glr]ldZ/e)lܝhrGH, r={!9(~TP'8ˌ>2bDPupp8?X1mV1VUoW_mW)yQ 4]L'{;#\ 6 չ hS{^ s {;>Oy&aUI3^hȈܸEˢG$q\,9C8T#fb՟OHǐں \lܲW{)51Lj`,ъQNjwîl1e2Jf՚r,:bk I3}/!!2 gB@ͱ67nK }*& Fm*PӥQ34$942E&?*:übq}SzYdžc),#s Kцl#ARȓأhʵZ=LY+; ŅW76+zA}F3eic%wEzT#΁ `zk< cۂ@72OXς@ӜwrzGڨtH_npFU-ճU9y 17["V*fEv;vg_6.Cau>;9'9=ITaWDTm LLfZj^uAMg/9 IDvq97C_!@[~Y׎ $Obn;t{G AOW%G2N9 O[۴GoQǚMɲ!V0rǽa>ZLE! PTPPYA"Hj*=pja+‰0 )x ѧO ޼EyPGYߛVЄ_#AGqvI 3c%V zEIb`N-^pêur-6}tdPǘ_S# QûFcnCGW} v{f|F^( px@B mXxM!34X0(3MLY.77y)d7.Po8ftRc}bs,1pܝA ZRVY L`=+TQ4HHхƙF`7vGě~xxeDlͣiFş8Iځ7y" ܕk:@%Ikdp|K }N VPL+Ke%.hR6a^Sge?7/Mv]0-v'si&,@zW']vֈ UƖʓm+Qegd A TNԶ"xi%ͳ EEtjG6alxz9Umgke]!iIE K.@5C&4@)U~Qu)}CH%+$1'Imwmx1˒:)N7 bnQ(fj*l-'DAWA82C]O}-F> ;Pֿ_!J0&ȿsWx.cM^KY[ʙ81O^T2 A,*VZN3O]V_^A@)f)Թϊue&D?֔2o`ZB{GJ$IBr& ClP}j@"H>YK= Hjʛ} Oݑ#2 K;rm5BA('fm(f ~籱ه]N\~naa$0@v%88]V^vIb_TlY]дg([T&G sO=O"{43^K:a| W,oB9İb7s VBҠ+,Za\ѐQH{YdD@Yi|taAk)L;4 w07j< Lg7u]vm7DtԻ 8lk_Elbpg F+mf ŹoHjP?f=>6!OqM] ,ݸݱ=Q4>l*F܇B$znϓ f'XJĚxPEqI341CQjw&ƕlh K%"hY2IF3# >׫N+{G }7C$aKWe?1z7z'ø*JS D.f mߴz8@{xo3dӄ~28zo[[Ln9Pp Dz8 !`A* {Ms|=@o} Vb{"׳Ckv5Ty]'5x:yw$9a2{b ZqS׆%RR%wwU0UAM4·QYwg#<|ei C]|#}!|LNP$ބw3at_JHh\ '"{J}[Qj܃4AWB*vj>,I RaE:w Y<_3gݑ:(3%r7c #B#0/jz~Ʌn&XMAsI<q1z"}9Պε"ufdCbɨɮ"x 4F Dً#Xëw@"Ԗn[`l)칠sT]i3 ],q!oLHݺ`*?"Rw + 4 ^͕\_ߚP?jCZ?-^{`JWIOیNNC*-01 n^S+PH߳zeUџ>."w 3m[w9G vtue1`\(Bӽa*.z'3n2 1юP& DtȞӫjq愡KUһ253aWGb#kem3ҋ3Ĕ(tsrđ?Կj&~&K-?Lm@d0WZ_;6 ^f%<.a}P }F?v*k".!źNǗԪ Yw,#Hlt M+y2R :tA #AZnAWmM&f!^< $"iȨk+W зuot f} ;Q6ד,,6:ܝYo @D~H-e˝@4,aTQ.S5.vk|F) =td'|ϛl!7ԀٞN=z[zq%.|WtJД[xgJװIfe!uάJǎD}ku L9@Jd&j<-]JFdu3NC7J[[3,|Ei {a&וU4(s!&~ص}4${~Qb{*-^g{'*{{s6ƃ35Ss5^hN*rU=XKӇhmD@"$%(j=9Ԅa>!S{?T?@O"&GllAY][%42!N6Zctes akf@JƓ W!)ks Կ E!Ko DDw[?4S;p*-8+v}??nX}&\2M1*f 0q_>72ZpNJuw+ëb…!&)nxBH1K@X{r]<n2DNow (R9PrB*jUB#VsIn O~fНwOrˈ,,3osXָn j= n!Kї$8?{~{*40u{7b[Z<򢏣ڜZ$ЏH |oX[Lnu-5郙#llt>R<REDu~8lQPÌk`Fb*PeBU!1qc`۩3Tt냶KvnSYVṶuH{v gY\-irZJ:%(l9_tJy 4@wh4O4U|@cU[lp=vQ4 ꞒS7n2R ckob~ɐgtNvHyO6JF'@)(3Q@\d QHhx{%7:H=0/3!cskhT5 |p ҂uQý$=*dRQyN<jg&Zպ\Do~'[UP:9#]pߗcMz?uSv4w"9G QvR rh|rڟ;c! B# (8X>xȷgK($yex=G6 EX}>gg6yW`ɜIW \rԒ“Y8߀M ,\ dQ""JQ g&@Ktl FI7JF)Y#F8ǔ+oSYBoPoRfVTs\9ɬ>N# +؅uifUaXP X+7KHEI |RwU>' Xԋ{tp~]" >bWJ̾fz#ЭLGhWC~ h #RP9c"o*#:7`(AonEA^d8IvڈܦT_}>zƲd]4hQ_  Q]v2=^ANolk}"Bit^pQ7~\Fw83Y~F=\q4JPH-wQϚ  cRNyEtQN@߭6_s|+)F(ػ/^NzЈ ir+k[bɚ:sw6yд 7K6/[f]iNv޽ԋsϯi48,GȪ{T%vD=ox`< …FWSWMJޠyxjU;)8|$86JstmEj.i֑ ^"1 dɁ(|r؛gufc7fRյ Sv 3.eZtByBbg/V yL}k&{GW?#)BAM$"c+z 0ww,ex,Eƈ\AD`9+S>2L!!sG#W[YԐpQ!>>6nH"uT< Mm5i05cyFjұ(ۺBtVod,T79t;0A+$񏃔 |@.!'F]9ܟ?ز^E+?%hqμЈN(yfo4Uj!q~[i'uSbAӔ1uqHfze~hmv"#1jKϺ/w8]C=kfq8RIG`ˍ^eHDb'Mo-Gf'/X~"FNĥBŠ%iBg^bkUT}d :ͱ~doF.huԨY9fg<4/"7#a|*{MY@OI1P?\-y Дzرx;e-zZ9rOEF%:=3sHr4h  *.0%G^x.]{Kn魐rcBe/Q AV=y||:EI@IP/chYcpQw CWe^=[e]T`yKL6'e MJ#4έRj#HtN\}hn;Z?Z3)4*ORK ʅhwZm]6~K1xP=F)<0bfL; [QJo-s9j6`ߠHo |ov V홛:VI%ӧwaܛ( cE蚜>Tŕ['b\CTu|B|e65QMmm_Oo ̙'Ѝt\["<)pgNB`E k%MK> i7i,n_5ILסF`=kaIhtYd3U $/AAEJF10*a.KZ&_{ ʥ~NfB2"PoNL`.UYsh=3A9Xqa5Jo.^=DJTW.Foٻr%z,-1R{ݵHvs8Ā@JxrM6C B02F_')7+Ö;oASd*h,'Gd8cYYq̹b0~/"ygU*N)|C{\V[e"ӈ*iDh:D!p蓺yҁYi]M9ݏsssU!Dr Yba_4P J'N$)=D9߬3XGvǣRO~SDy?ٜo;e ؄Gd="1‰NPY;X &CP)?OQk$- a2'Yee<0!AX ?P"` -$NJ 0֓[ܿa^i`>Kؼ%:e%,O-軯OhȽwewho'@2$rI(jYО=[m˒^,"f_ ^oY{ t9J C;mYIeV)uKnyS[i̦+OY?#TΓCb3)bzOT2Ws'>,(l7L:4ҟN\*mk.siT#XX"E>as_.9-هxj1_/HNGReP&O%%5W] cUt~(ReE'u[tr2\ N3kfCN2((Ց@4BS&u7_Mv#R+l1 4lf:tlh\!^!ݴ>~nZyfmN a a!ZNj-!.HW~ +XhhHpN&uO`liDY%ƓZIBWXQ׋d5CR8/-$fT]Hgbƥ[IՄÅ ީ1%20^ljb !Јu5i#C8YdpKe#z/X`XfKfqYo:즭-&NP3ݪz@ &2W|(6[Cѿ+k*=.].]-쀟ԟpHO0SF}q*?Ho;4gUu]ôؐ;DNy(IX ?˻63j-Vvϔ a<'9|$![2ﴯUg7Gq!UlEI&+,^ <|gNJm,7*ōc6։;6=)k΢|s5Xˆ6pȇmY>gYKW5nT(x0r$!l\RI{wqFSQ$95E,xxwG8akvXȰuO>S@ jNHyթc KҚ"="5a` =[P 8 Q?8pd%Mo)s$7n3XD4kMk"d(S OD H,btN"civNr=]"mH6ǡa!"++ ]~[zhLkN`pVT47F*ض^Q<Ӆ4@qqa]r {E| @Fn±dhz¡G ;zn[ ͡%UeѲwxoMx&.<QHVo,hv4|镍. L`,7ި׬?7%%=|oU~ i(7ȱ-V¹2 O+GzКNg4 K# w8jvk)GژF_vlW${pO1s\# ڌHea"GN" ɹ'oA}N|P#q@lֆ OS:&CeF.IEK+ݟ:[O{v6/4r[-q9KInFQIsk1:h?O-q#_ǴS$ȪS"yi ==`C $屺y\#+23?aJu;c|i2ʗB=PXJq1]L~P)N!32L&l2 Sr8KCBD Gg+&%lzJ vUSM# cKnQ/>bF]ZBrr,ԐBM9YJa˒vݗ dž@kmu+˧5\^ 6¨7voYŧ[d3M#7{ߝ^D}Pk\\<"$RL$zEwv^IzQF1##ϐ5&s3Y Hk)Ŏd-bo)E7ʫ2xrtmQ1iv_bk>ta*^6]4G״I r5 C}A?gҍMm %U(߲zKZ|Q%K#fc1֌] 1+:D-#[i2y_Giz6sznm@(Gl҃5. ' z=r;6MCx}:pX j9ui_e?+pQ)?Zgj#SzÐYqF$ΩZܥf"?Di.fz>Up¼"MW m![3?L"(?cހJhO5=w܅(//rX&UgF!%6 |ZDi"J4ΏpzlPpPkcF$ cz5dg@Cd[cg%1] ,ֺ~ -HQx-ʝ8#=vf\c٭lv=g>`(fYlϠ<H&7厞'II?"|.QߴdgC!`oye^iR@J\:T@Ri `PHw:h(ivM@T2EoC ;=['7+p&= j] LL_'oeS asNP664Y3nlDj=ٝ~RU>Œɨy"h\ p ^ ql"[ sueA2ݞ':JAnVxg<!^0FFqD5y1>e hͯxK)Rt M~XQQdGF!-nʑٌQEoZzOB1^9k/s8s|pu=.KRu|H824DS!O>pwR7:cyJ97`Dp@_dk LOD@ +,=~Oinf1^@!څ QIIelUd#kCvz˻{z.)&4kK2+יd$ 52z%ql9!Ux0\TK#%j[CG.'ͥD:Dw 'p^sd1u@q&y7 :@A(rΓƈ\3ΞՏUضE:VMR8 KHX\!Ҝ퐾Ctȓ<#2;q?!tTTȨ!ƀ\H91L -7/vrkG"+@My=A~s$ف0oc5pea}!0'x&:wJT$Y5%Q echփ :`z)'6=BYkAZYv!xmjm? J)@t&'>~$£ h>gʵn[JQ0)9ƞsE΅TMWOdC{/?埨s>v20ߎ77%ъW`N3E\ R%&5py~]@wxKiŴ`QOC]Z93_>32;]<\pi%չbfCU`=fҠf5q!#q5nqȿyQtYޑ< i+J]_mާ,=\D,jLN_F Beܧ}Gs8 Y/v,^DOèD AsnQg9y[!]}$/IzCZI3(e1,lb=[?^=2HrljāBSQfFiYsIoNu(,Rzv\Wd<1邺lG^b5FҥIF\ME pRrn;N"~8P]+){'͌`|4?PE *^ [=9^-Lu0 Wh ]|3(l?s=E\ 1~;G91[*ƠN2*Ը w..UcsO,B4YlmeSED ExH3!.͎&f0K吵7H9sx9%"]"͎TR#gf8GGeL 8ۇ:%?z:ݦ=kC,Z"q(qs f~4Pvu [t~K@wA)q )̵u2{*=v1*sБy2Yd{o^vT] ˞jz̪g:.8!׬k~=׮/0RT&^ ~X|e"; Ea: lK>pe;| !QUUf|OƐ$-&(GՑđK ) q tVV{LuZƦ(:M'_A2&64z`[%!xcqdBCt.r"3ivax*Zx˒i~}Q i>U{Nj܅öVna.8&iH  x`>h Ɖ\bL Di{U-Q e [5xqtI@$`k})=obcЩ!X=x>rw`N[@ǍGՙ 0h$KUqrzЭ92ăCp(JxƷ[bC0^7ai *\Ͷ\Ja g!WdB.Ɇg[7!Y{'l\A?ۙa=QO i:C\| XʃR8E oq ?6PhXܟzq "L,<Tb-}TnghB]p ;;f)6Dh̓Ҽ<0]R+z:ן:ڳ|5zKav>YE.0 Y'8{0}[{Vx| KWZ  `|͡}Q@!_sSI'5h@R#7žTM22^CiIm- tiaC](E/㶣0Bx)h V77(I6ql^{ǟrtEs6LOwRѶwǠVtT:_&B&ЦYcwɲWCq*Wv\AƥoPWN햜STU8 pҝ8c`PB5XA*}rP a,PZi@r|=wˏ`0JšMQkۂT%Ơ?5['W fM,trM<-VK\nÛ) {%)'lE+R ~Q懧cS񢺜"GםGֶm;/Tc(xgAvvH ]ҏzzuvŬGgbӶ)'-d,F>dS/h7s!G<:wdP'!ksPkx9_9̽kvcan4G9f@恾G1ON^E-OW;Ix{[yYףF+9E=9\Tʍ4}-g@F qMscݎ&m/׽ؿYhY< hCR=(fž]aYm:gb].S%9]]мW2LR)HbAY_Pj3Fz+4D9R?3[pGs?>FQ*YZ!Le,^6SJ1>uL&Z( J $N#!Hmg`z|[ 4+-ɅB* TcgX+缛ʙPjԲHr'^@=|%1NK4/MC% Tb&I7!LV`n3NnEewI^Ue~mE;w os\ka~Ҽd I}håyvboi! ²"d J/=?FPaPlwdc 3|L4Wh-UJ=o*=~;Ud}ki7FU\Q9} +4|wKGogcb&ČvP1ԷNL7 - }M-K賑 -rs(@+NZ}Ji[+EĔI;5܊,ǔ]=Ҹ6f0Q-a_-eW5CtNjgC%bdOjQ:]0`Ĵ6~c7@}'q֥Iq n/j-GJEo/0`Ӻ+*/ wtNA4%7gqȧ D"W?  ?ꍱW I2ٜyeF״{k tpo.@#ܒGd{P@>3O5jW{ie|M5),{8A΢/&b[*[wRIz7UsDNl<:z(=S#UesQu$ĂQnw\{j?ڮ^)9 q;A׳kVYgyp W$" ?4ll{kut݊wT<匁O"]llP$K)Sv ; M{Yrp*-ºlڈ`DB=Qp{Ga,##L<A*Xd!61ָE ie=̚uRAUq!M w0FS` R,[ۚ7KƯzx<ަiٹNY0P5X\l!x"Nt%;{> F/X'`Aj綪Fm%0}`ߵ}H:z kܱoNcƱVю*|LvTw`UҭS\Qt5@O/ٯSC+a8bpX́S:@h^4 uzeMi^#c0fvRTxg=cJ.%!0eL;xN$ pMt:hKֳ: j}&V*Vlw?( Qs1oH1FO9u\{_ֹw,E92m7 +4v{_*4'TG:E;`z;4;`xkV0RN~B6J l8Ex2Y8f?olJ()WL" r#%ǟqshGkg74Hl*4!~emH}?v' 蹴7!4)-9rcLS&Q3yF>Iw7640ܛ:~c?3[x}‡ݐQƼC$;1+7ެj^b(H ~wo7hW+4jn)ؿH[G#=a %'˔Vw R+uhiVDՋkVQF] '-23 B"0& IQ,"׭x+P)<ipi"{\i%RHqh%<Ǯ~igZm! _mw,9EfK2#5s-ӱӚTP'~=(^|ScO|y%XgSuyWh߾_p'Mׁ¾wAKgufW+hEg$&8rc*^Ma{8xWἹpxCNѥw_QTɞ\|4P{YЦGB:,-C!zݹXe{%kuF襝P2qG^$ X휣gQn`Qx9d'.]% b&i“O()hlp!bAX !:`+Gq/v;]. > 9^~:_ /4% q^(JR֭؏Y|q&WP !x?#eM9DT)o,K-^x{@[ʂ@7Ic)b%2J?v b'-lR$^wa+eY)p #凖Qƅ`P(DZn?}+0L6 <>OTA;WU*dAJG~$t@4Мlڀ88G%NZE/3`c!D/z.ņ5]ƅD? djByvN[B>kGXTOvmK{O-+J{&ĔSC)vrU@\` )ujcM 7K3uȰ'Xwk8KӥUֵ\I<"ejJzW͍rN;Z\UCϑ0Ȝ~N~WWC4iX )/HCHry[Q[FbcR#Nh.m:pYIR"nw:W*=iH7j; ~^b0u&6fogRMT@SuVQ16?@imʃ6 J p];+S7-?jDֳpA`btofM}͊HuIkK:R$5G>Q׵:\;Qm鷙At =EASO2F:g ѹw.?L_cVjfi~t6:;ĐF>G`*b\ݺ Ѫbّ럋]_ 8db5nFrl{VKgW*;$uoѐi՚8X 촠8.ZL(RYC%>kiW[<'KVI֙oZ:=*7]荰zt>c˟o)v.X8=S֭jrQY~uIpl=Ś$)Um8P Xutv4H _";Y\ c# IlĎxKB"t[|oŸ0 qxk@mp;=QӭGh8H7";)2Wl8 CYWw';~ezZ (5ΫӬ%ߒsJڗ"S}0\ |] `Ї͊BXT(w9df$,1!lG&yգXt=䩧 -a@SP"N0P9F++( Ɍ&42*=}XG#~y1R!)>TB )`_+gGen1c@äHM^x(VqFDw d^/d{6D[>Xg7vi:f4,ظ@~e:E"շkr2]/idžz4ǾQ4ͪV!~wgHo>|0ҒRkRo; T]/HbyKsU%CArW Lv54,e_j/1$O蜋Mc$ "|VqOx]Y@n3Z%!9y3'ķ$6h>-_˦PM[eQLql2XZ/2Dp YwSOi?#;ZO YD oK[|5u>q݁ѽCIqE{yD s8x?rAw0ّ0YRxsm , >G%zoSȁ5qՀD!?|Ø6͙xl.-R<u WDYtRO(vl;f'/DSY7KRc?:F ]qHpi6reIV{_9hiG6qeX2 siiX0sc,DCjƧEm*3JZn5d+0~Cen/ .p|3KHT數۠!JxN359|Kge,܃F&)*}6-ӑDJ8+aP%}{7 ~Ưu,uT(;}v4 Hnt@u,uJ݇c*&٥tﺛmнц/+ˡ5, /}=Eýt*bH6ߕx,A&΍Jmb6Uz2|깸|S:tHif\?[{v]nNKb'_7.*$QXޔ|A і8xJ$VB+GA BHWuR .K1EHw$Cw~@7̡/VgD(˙4З:UU 0|{8K-3c꠼ɸI/kUIcD=0)YHe 8sg)0k, o|=* ~~_e_ub8ح T/@yɽPlIRvveg%$w i=y`:jC.֠(b0,ZSrcTq{wc6c$>%]}kޜ`yBf`Rۆ|d*eLA!Lc3w9GL%rYv%xN##>w$l}4LNZ$:s$Q˼:96e=EZ*)U9/}!aS Ҋ"A+Ph8 $rRoSNG|"wמ#oo6Ʒw H#& kux^q_˔&U;oI'菸$FMOVfXh߭tLe!⪇UDq.b"Xg:a1]kN5̱zҾLIʬ]R$&bv(>x,Q܈P^XY9g] } !T!: t/o3' &dvݼ''t[u2xJMC;DncD3^b ]+r>8=7|X/7 .OΪMPXW|%aRkC9]2ww5xfyl-kEt0„b EU4(.s`z׳hiYvyHxiIػ~wpĜLƸd<%cJd G$ H :RlP@;#'"yt76f:X"| xz;@B˫ȘL6b8LnpD[Yڼw { #=-KyB̑>I I~PZ7Dsn@pص44<6^qbJ( r+A8ӏ6u#BKS𧌰^Tt·W $S5^ _( .12hCϛ6B#K.;j>nV)U?MO =r|X hԴa\#nx='z>f\4sm9Z7BvV@Bg&3?U ֟T}SS-MLp­K0 +>eGhs['güK3}kvGF1hTs8&3S]MvѴ;~;7VkCXqcX+H1@To!U V9̸l~XJ(a[X},jT,^QMnn3l*Dl^DO3( ~eTLH9]8[$xLM;zZ5@8q9đm.W] 4w+=NmPI L5䒼z<'x,Yɦ *>!"tN N6L;R-P!_v[96pβ1vm][f ,ɳ2) lumo./%Cwܯz2wHGҨ@^kB9_vk:)0`0Ȁ@8UV5, D}1KzE*Pɓ|-$eF  [wZm3l]49E͈^7ǐd{SBa9חV_-7~FYUKsP@ 0P?0=ijH |5aޯD X@-pʶū ׉ 9gIl?^*Tq orie'tF;͆)Kym&.죢1Sʀ rx+tS^rV_z"uMC|6 t_NJ6T $Pf[-3Wq7WV.xj*k+9}zFN4MrNDX'8geqNh#S%2@gjgE xFSڶy顋힞f ˊ.|L.m$xfu1!Kb#A컴Tß t7g,,8x*Mb2:YʨD53l\j=HBPGfy -IO\,㎂ΰuPIdq +k̀Ӧ KP+Z ?uˣ6IC Z mtC.HHNB!v|졺}jn7_2Åz!4U) `y]3\K t)p.A/e+3r0 79+26ߝ8.kG]Mol*g 2 Co!c;aޔe8 wdNmI0HAnqjM.8]xHE|YXf=}2ʈ]yD[c` v!Yxh 0)vw$)/Hmkro2t 7i%3lISVʬj=- }m']GDv(`#aV$P:pIež} y6ULSKq f;ڟ1c* KVaIICeW)),=_Uwê)~! ٟY[ LZ,a񚎙&rq;ۣisgǺXEov7"Öр=1pN+x,s,b-_謭@DXLS gGW}) [vY7 / V^ۉFf @ ^}>$Jtzjk4J>CLtw%_*W>0[J|' 5PH.oa^dQX]瑃ڤD!~i^:] FLVUOWYxFdӂ N6O'i&,t/@f!@6l1ZuUqvځ)B3WRJ1QJj#W9G;@{,-&~35S./R6]8xPfjL%jB}4([Qwq*Qz0T$NA80T2hq_a5C93A1)lgZba>B* lי`̀{핝ڜu@7 ~jp6K[?g!W)l>࢙&no6;XFykG3jF=Kv-uW JR_</_;2hQ<oM͉APL|m^Lg25ƳevHƒWkh wR\p#)*"@5wC;i mĪ l'U@{&Z](j|Y,mО9 ޟP﫴%90B ͝ixayq93daDÒPh lS/]7 MvOc[EuT\fE 8C, mu(B2T5ET @OMd{nyXaò?]MtA_~rdD|(K#6F )s>TΎc:j5ᅕ:IJfʜ"Ѻi׮fw+9p=S5y#-kJl:25E`qn%oڬ_>at$ϥ XGGIkA4!1aJ-0j6+=6 ۺaz`SEWט1wˇ;E.bb۵_)&xx~{SޫTW9ZMo\yI&.V(OXC_S_ TdH۶v;;4ډ_J$0>5&&pPAdX,sC!}/te~É?&#edO9j-Ԟ'.wߑ<c }YIeZCW 7>H}ye[!D ǻh!1㣰Y\p_1\$V;Dq*_Yi"w"͎O!}eM` \NT6i @д/3.JbT-DOĂu4+)00Ѥ Bud w6ld2Y/.?6Bˍ.(Ҍv8Հ:#ؙzõ92pxZ)BrڲIhFLsWzW]$$:LHD?6;)t㚑oqK:x=hϊ e}Yq fB4!یu S,pzEفQ`9M&Q T8ʢ>vD6ٸ{Ԟ}=L2tE]YWu~`{s$+H51mC@14B_p/ի53 t/f.ɶ/M1ck\mؖ9މ^ةp ^џj/. W.ûd6Ҥw,xob|r9M#x] (Q)EceX Sg?\ޯg&q I(gM,[2>^ ۄi\#Q@wПm ~/ҝOԢBxZ]|z9AM}M}hW7Fg_춚yk(EܷɩIU>tP6SHifj g= +K)!ؒ dاP1,R{dC=${+`cά*׉W~  K̇a"l5rh5ĽfhH^-~,3QyeRd)Lt^.L{CP+Dc4'^ou}j*5"qaܜ{emNʭW4ewrK{UCFrCIK0d6zpz9\|b{KyOh߽M6ƋӅW qb#5R*H@Gͥl(_Q&7sEmW?~>!L!PG׃ IG,tJXõ.ΜOUBIz=|e ?O5|=:J[$%e,$Ʈ0V=Cߦ^-[tɣolpԙ1JRGDFX~ii3 ~##eB,uR8ԇ4wTPx4:?-pz=tqs>1F$:k6IF{-t(:9 _ x/zEH7525r1IyӤs!f Yl2 *R 2!Y0* <X[pؖX^2 pnź LvO"t M% "4"P-|Hٳ`Y!r2-&I.~󮘦[LJМԗDE̪AD(7UKx("67tE҆UҮ(Qo-2UVKh98x#N`N8qvs!{DhbN׶{ڽnxp1J뫈˥B[(<I~t2.K 7>JZ{AmTCDOGq~"Du !RLcﴰ(J;b9j'IiɂL,kO*8y"1jP/ IpG$F?%behCF i$#1-'\d03VNyc]l(Á@AQ })@%9bGX%CB:;Xdo2 S+[=9tpzB{^s&A}`{NYx0'd5tnueխޞcx(7R3F=Q{j~-YeRnT"ʽDMHJJ*_5vUzc[&d"/jxG2h6$s/^RSJ|`1}nő(w`ݭZu݀hVB7oИf %*c*|3ua# Kn/ /jF6fK$@smٰ8"8D~!tuBmJ>dNuwi2a/PT4VW"_Yg9b-黊%FVp{ꔉG)6ϛQ!GFx\L)EoAo_OG/!|*`|W`# U}\pgF 06@Gc2(!BU—v%e)uP/<-߾FeY܎-ddU_/3 ~Rx} ~'"ӝ)gkru@m6ߗ4fs5u!W_c ū|a'w5Xv ZJvEKxevVp@e9`Y\Y迢.O\eoN(%W h: 6Z(|t_$\I"yu "lL4Z[sEre: [Tgf-莙| b`y=Wf|T}j[|+ZnVf$88EO "Έ~6rQc|Ku^W!סBF$K\)L,K1j3Ke-SA\y&L./aXD{Ao挘ƌ`6ng}L #ٿ5d2iRIO0Gp1=vWž!MΜN#=.arE}ho:F Օ^ UR['] [.zZ.kRY,8NEע`hPDAqՆ ''ցy@JlLvJӈc{v ;#l[W!͹7# #S 呥81'N ՁᎉpY.MHxD䭙 u cƼ.*=3[Z~%ʒdsR)ƛ?mc[h/[n;w辙//ͦ{xԙ)*Js__!ְy<D{"k%Cl#NZū\wS|z-qz%we@(ӣRdd_ AxڇBwZo:'{\)<>,9alXYTbu^"vT -3|MT Q9(rͫ>wZXu(-Ј}_1Gøq/q R:yl"]2K>.z'Y !; Y`es,L4owH&AʺPn{*`NC!wHnS ;jbA |Y9Dw=stH$+[_Q!Mi2`McWk1 gz%e̾#)cur95$t&?(2^i15Eڦ12V}ǐ8tCiqbs  }ۡ%(ӣ開~Ι̪:HR(@j`-BH3bRƚ0)qT꾱t$yn #+<̩leS~ @z~PUt6 ;NC=\jt$}Bcn<dm·ouSٞ y|47ƬV[N4+DUJ:F4Llx|ZODz$!@Z>%`n؟QZM B2 N oA*<.*)pb4[rM_h^$KBQ $B>Vv!!#2NGD'#׃Fꦭ A暫2V~񧪢Uؔ7_!oLF˛ BioOVFo&1mfV6O8/ʇ*ׅˁ D**4Qޫt 3+=攋3~I1C\! c*7mbA6gQE28ǒ1)*ΛHEtK\ΏGRF,C-f5ˏ cA=r }`D<~xYjVEQܜnaTnrQ}Oﰵwȹ lCZL4f}1^=P&KYR4|+H`n]ˤ@\aI/[=LHL?ԙ|ZmU[{9yv9IU7aZYuds }uOowD3w wJJ|8vGdAp.6XSkrv6J{HвNh1xl+=Q*w7ko,"--jfl;6GV(7 P߲R>9GpWwf`121W\c Օ], P[myļmk|/DgMDxn2Hd^[{;sJ,#viu3 >GM~~C; jQz;݃zν*tustCKؿ n\hcҊnisKWo rMNU8BhRЩ;pUrmܵ"0ǃ[g2 ,dSW^wqzQ'NZ#!vୟr(P;4Z&h]~ J)'.a'Fc%TX/~<ouLw[r܆sګmϾj?:6)ƽȐW3innCAA- fe:5"m) [tǰ@\*pc@L`f5Tբ^olnʽO[A))X5M6`Wos6$x)h'FIԂSn̿ڀ(z{tlt(DlQWw$40h*|b UA/~ʲ-648#٭lEfn9J*Tr}BJ߃a 6z5h0ZP*Gڵc* -.Au Aɠih1ʣo 6zKWd,Mq3^],S}/0mQ`{jXs'$^쏷7;%]ŲOQ/^ _kհ-1%]D)s aK55F} N@f ZBX;šb pOUa*Oaii5 Ԗ bE@>]nﳑoKs Đ{5 {s! 1$Vq `46c45ҘXH6{5nhHf/l{\2 [/9!!d#D&` V/6)mr0i yjnoŴ;>i֏ǟ9!X`NPSX;#`kBzXPrY>/* O/<8JxP17a&1]xphmUG[2v*đݫL^ў536Ց{ !Rj;~'J1v Nҧslx1^-AQ4w bsj!|8BT-"ps l$LWѢH}/iŪ}gD |Z 9`e'\%J /#1\Bu:H#.w@sϺ){BhdA pQ/,+g-.zQTmBLL̼^UV.py,Km[T6k64sl=)U+u夆Ɲq_ ٧!}p/ZNHw*H6Gߧz MHO2h6E ȐcQ`<[Ki*pMM +D5o7jmxG4<.WsQ|%)6'^g -!)`Sm՛[RimTlu7aXuzW:jT+-k6ŝSqmF`[=ׯͰv\,MI`[`P}#cHYXʿ5| odX: TɡwebF= oB4K0swȰovEo}@|:u|43db?͒RAz3 mǓI-, ZQ7uOϡTpQ[2WWDboEJB8Se׀\ZZ"{o/DbISdXa ϡ,,Z0;Tj&υ!RL{SIscDZ E`N$C Z2iv@#"}wLgS3#=g,"3JRbHmK)0tJ BշhI&wkUIc4gggvƓ/Ѕ۹W34n1䧫,4 h7ݾ7cdǴ(ydEd)5 E{q-ƕ5;0Jq}9]'8NmPq\b#*HY kbTve۝ cr ̜fc'?B3Q$\"!5w]"^&?@'tQJe\xDѬOdy='\+|[ s$?K:Gm\X[u<^D_lO`[oa3 Xb4GC 'q#Hyb#Bi~gΕq eP}YDHJTO>@xQTFueS\@ao\;w?= P"c7};jkjuVwKG\{ XǧtyGI,H28 iI)&UeM^oGh=t_,Olv#h Ŗ"VB/*U$u~]~]n&RMwfq<|'toP Xw"]Ksmp&qTWb ˈ"0K]X@mcUwhse/vÓ{ǻYrvjĒM{]ՄAG1?1JXEZʳ#?֧t;,I705KÝتːWf煎c $/^sIBGFMɒQcr8385<ˣV8H~ֳ!XIA*G;<.I#,j _21Lx~@ǀ~&:YVi)c 1!myv9}R͢5O2 sëkF2 Ds-m!8q2ZsAg(R5o]"_(Dm(rX{>ΠOOWyTtxy{k{YxOHC: 38_;-@SyUL h4qw)O@0l ܉^>6CZʱeI5;"ޟM#OM&-KQ]+,꨽Bsi<0pSCN7b,@u2Ҕ VI]m{hϗ΃y[tmW~S{Ά?+/lIeZd]*{H4 \Ac!;ڰw3N_[ 8i0"!na\9bY2unqQ8*Z㯡A;橛L"ZGʬ۾Z|.˙enN6V]\ڿ[^kDbv#> v+?1Գʹ)Mn{om|k:Zٖ0@2'˕"$춐QaBnPk\9 d˃Tƥ`qxѧ9b q8jL4W<"r1K~4$}Fh,RE QoX*}D6 !φ>@T]$hSK]hoAM1.( 6Ój4!'׍U}T)hP 5𩉷+ǹЋdY#ʨ3\ۗ(jaq"6zY%sƂlgjɋ/:5ߣ y<͔ ?f9SC<*d.cvP0xhFZp(cBS#j)Kr`h`A脴 eKWpSA( S-z>#@]D\nhR1k&vBt)ԟgRY?1O/#?J0u^FMmc-QH=doՔmwfrWn8e\m" ۢsDh i=2"-M7e6;9GŕgMXhi%S#e|*ZqECSXUcd\;4,X[@inV~劓> cʢlSn>\1Pu(L탮2Ufj4`}!fUv[mbYFN65(ED֖n\.qCsI1ձCIJAݓɆWzT2kiV2pDzրTK hW3#pgW lSE!j61]MӸ$/V|zX QVfؼ}$HXe^w ƾ, X8Fn=)ӽsu6S'l!ʹ(FMB|0}Ҥb]BK:F쁒)F*rTQL5.(,U*q쎘%Cby."y6rQgZ, _Tvw5|bɶJɫ.֭7e$ώHWE% m-#$ -lL2YKdU-T3sy/:18d~j;]'YX@)3X-ߧxa?LJp( vYd@F1C{t!԰{P_Ahv>ϲۄ& /oo3k{V|,vhck DQmդz q@M| `+ߣbbqNRȤx]4 ׸qz.T 0y$v HI'ayT8< (C9r[Bڽz tE``<>˨Bs™P4h5QB:T\ M=׭hɁ7NaxHPUAe#5D=|6P%w" hD~ ЗK~51Dl4K~ 4QZ 1TS`x2Ua2dMʈg<%h2;Ej.p]<]_zȡwZ-+k|XXlԉO7Nz[OC|USirtKbEL k\şg=ҤWmGo|"*<*ybOY)~'5jYl?8oMYƚ cKɟA.-$ZuaTo29n[u<x[X gA/7^}Z [&c=> F̏^^ "ۯ9˓%u׷2,LނZfa!(id=_XcǡU3gMSIa-D ˜q(^{_Ly:ߞWr3g׮Cʾ?cHN5w= 43,L|SǺ &CѻĂ3UZn{xdH"ޜ2s*y8JR~'<&𠜑aYݲk0{Nv#Nׅ\T 9dzG`i.E̬%Pna4e5d#+~GscX VpyI !Mq5ctd$}7)fNJȘjHmdzE̐+Stew@@u XA M=vH ^Z.Ť _C ~-x-5bw`$P#EFMOSԼiye9kATx (nϼ+~R<]=@ի8`CI 7_CmuD W0nƱ0)73'bG5SܠBU-ѴZGң [bAo*Mq:,NOOp=D9Xzx3uI*u(]PqPOY_wuNѴ6B3aә{W%SG(ڧ2]魁V_γZB/~[r&/ԬlƷgZXhG٪,&s&$&j^MnW 3]\'iuxx 7ia#lڬ'p_&sgCW8p̓¯a& V­@y< J@sڂ_ oQYiJv.O<OS+xo&hŵC`AB\E31%B0=HxLv%m$L(9DsZa\'xTH[™qHS]:l-1^uZr,܎Շ-1|VKvrEP2^2u˜N\78ZDWWES/MVhOPa"c x˗(wlzLhJ(ZHSt-{ YYE WZ]5dō#3gu\-?Uq;|)}x%z6 &ٟ0@ʁH#j l2wݳl]HtDx7!u fǶC me)xTj)Te=<,I3 Rd!(&B 3 _nrunpsZD;u_|nCDߌ 3 b tKnbn@"OC=~yiiͅ4T=L #Ժ%45gaJ"{F30L60ƧъDk01l_bsu"l!}N&H5|{lr;m$D=( _-lF1J5!@n5a!^ QRQ\o z񅎺vh^y]ݫuriXB-'$:rHhy [!,-6YyP <=ODQpA./uM_zF;PuɽhLk>wX*%iA=,5˔Uۢpbӹ+0c{bx`,4Qţ4QKnh G5>CJ7ԠzI؂I!rlV#W7 K*0WJc]jBc.Q>KU"4iO:_!Ģ<{.'3Z}4?UkLF4c GC!vϖ4~d%|㐊dlGZϽmeаH,v\ :bbA Ai8t*jÞx[ kP j"ڀ3  $R| ML,Xbg5y_u]59 '|\տqN`v`[Q2biKۂJ"J1Pnv ̌]0c|sAtɒWU|~i't42+Zj8U :V!*hpF{R'+K_z[dB.[h6u.̝YNwyNi6=uAy 0yh[ن8{ 11`GlKhg"1{ˡ+s|]6o؈R4BlrAv-E!fai?@FG1:l膆G]&uWo%mN2PAW5(yJ}h9bf\tf_,@&6L(_y(yQ;S[i6AU|Rž!tZxlcb?` >@Dt얱aJF4xp;G;_j^*}r+( lJDHe*qTL<`fߕFw 6ho'bFё7`:u;, D3_pf%, uFsXlģ'; 43uO$r{:NcI\0b3煨Vv$0?Z5hBc*[xdct<-OVL$4 v;)$%Kq;u*T~8<eWEQפzGeVƚTe@: N'!Oiu@i0O[\{}~I$iq? V6+Q5 x 'QJ_cB="HFLa%^Cm=gU `!s#ӟIAӻv p".NiyAO 6iU~7ܲ5 d|-R mQ"}s~Ε_NwmajIF͆s*FG3 X/ 2y/jjZ[gJ0\ԌE)i&_'.eGZ]m M^<3 OgYoDWx!Iʨj 0: ,`nFf:ZApL_J)mI,NQKKaLfo*QQSM66-3(;;@G(\X*s ]$j`͡he~d%Seb:s60Ud/xS (VcT>&!Qݒ궢D})3weA\σ#g=u$ n9 VZvI68hPa~. 1Yal|@=Wtny~{PSpAOl_4Fݶti1/Qz՚y5ZxD@j9}|\WO?CJ%Xaq 9;)ڬSQA!?L9u_8DO{xpь^@dXԇؙo5щ%_~\๐!6y׀|vjnyH7/ơYE#͋ !m8FX^:ϱnG8=0rH AdtOPdčnt']J 9w^C l2MN k``JɷL))UkWg:sTG EΤP1,TfwG36G)NA-|P$d/EktP*E/1d׎۵@&2!i?L ty}Ä[,Ѥ!|nЎńx?|]I xztwR6_ ]W6A3z^oQ_N ףBܲbJiF̧}oh2 3}&fځ3KK=oՁPhѺKu U&Ԕ= koK )px{QT-v[%ޯکmpfWQ)ӶFLx]~PNH{Rw$X<`'xՠx]rZE͌3dfJ<;sH$Ȼ@+s>EPTq^N%SW=DeW i'Yw=KKGlW.QgHw_LqCEp0uNa,'XBn]VFv/ke0ጷAW 8L'>\\fvP`<9'ZJ;GzqZA;ׯﲀ1MKRm)$Pl'.8ܫ /<V8lئ `]O; Kw݁PA3qx0DkW5X~# I⦥|<oG3N7F:gV"jҢct8>~x<|e F z4熐jٽ@e޺Zo UŪiSUT9Xu$r[K/)4 |pAHT*w+{U .WpF}ʅI8$vFLΞY,%(OpvHlRջaoܐkB <ޜܦgiF*>DFe2 G670x\a?-`t5sX`<10ܛnO4^@:oaK&ʳu蟵#0;-ц{ud?pz-K=d]OmSjIKcv?.N lP,ZZ@HVvAʛB>! Hb!#Y H2(>S/+YƇusp2}OPK}khTD&ݭf8-ϭtD*,HX7]'TM~iD'UT&nځ}<2lSMRf K̇ڹ=ψTsnh]lE wéY$.HM@4r40WZ'>aaGQ#"\}S/.GSIMX4zD|N|Y(IJc~ $`cާ1N-9:AF΃` ӄu/@-:,{R`q&vg+|cEY']8HfCiV>(#1) Od ^T&t$xT]Y&`"} 'w/AQ}ͧ( ^)͙̉*<׀\.(1[x_{O@R*\7>/{q\DM;0eS atDU>dSV{KEsLJZ~Y hSqR]PgųINh~/c R92 NN&`=+bA)iT:أ*ezIuu[:uӖdd)RM>hh{7tuME9҂6MDfЀ$) }Rf<+狕a6#oŴ%vx^7/c-UǙ2 0iqD ֛am4tkIED~A26 W19|вbگɝtXՏ<*Kpt#4XwK:|Eˠt6\ $5_ impns .+$GMk TP&2Yyx &OI{ic,n`JPfw/RjE;Agä2r'KyYa`E5ëvPZo8!98#s<Y+GDkOo)W$VB^l)~4@S(ZX-~ΧCH`lS.7V|H銔 铤֮_DS8:!φsb_fFM.ܵ#U>h˩8&:K,wvY/i.Rk-=K\*2* N --&)-th٘(({kjdۯ.K/n!Gz~wD6SMƋu[4Io[(pK{CLF0/P%Ϙ&92D*ѥꛫ_Y&nq=q.:"YF^w~]Pl(Ѯ>8lSί˂#DkW}*M'^=#ybX)cG0|C ;GCM(!iY}k)M#֢b z}/*qq%g!qwxK-/ 'Ywv銕J`&3TP)ى͔Qfm|}2z ZX&3h#G j1-/,&6vHFo' +|!=SbEM}ZU%:2vH1ЯouB'qɮBtj[|A^Lb4cc̟\[Nm1@u7.}*Jw5" (*VLr G*5dEqӾ`moT{"28hW^Yt\9]:?]>µSϓHYC u6@mKC9à i6 ij7.Ђgխ(DG7cc3B2j &+r;ElW`u")@tJ)c[+>!ZZ~=Q* >ԏt V%,o~d.(%7=|s-ሡ@oF 74 nWZJXLTHmʴ 3،./*<9. [vpFl_|BO_-iSVr&$^adhf;>^$Z!Ǫ t_R5hl k&F"ep/#oVN٨o +!\7`Evѽ)ZWH.ĥF]MGڹlD($@+߯TC7RM>/(?Ěyi b~`o6g^'X+>>׺pS}sxW+,D~&=vE9w (I?逘4bVdXY#hb 0V׳`V4p| But96ouHl΋ zVsY!:+Mp%0ܡMH~iͪf5#P\L/`XZAkma<|3:G$}X6k/4) SFJvyݽ`d\z+LB̀ ;:ُi:4ςm?snjC4k J+Ts/1N>GukW͜gB0Eg=N-ˬFkv}~e]9 IFt M *_KͨTzyΝyfݺ{R["ۍᲥw i?;8oj{ p8J>۸kXbF9<_WQ 6+geν.ƞ lhO nz٠Pnfyva,KwAov6jM;FD]S eS$أRZ$Kl`"ZDHo}~d%EޟмsO n&$ 3b|]`n"x]%i'ã CM o虜+,r{LehԦ9>x|i+;l Abo:\fo 0 8ZH'KG!݆ၥ9;H7ZQ)>_g>cG$!zN&0N~%WMpdZ$nk`bRew9Քvk9C6'N? 7 Q|ل7T L "ECeE|ݤo>QP6Rr웘8Q',^25n huuuaH{s1^V ʵ'v w@FcI꧉`)^qv;4u{'6j"̙] yq^u;Auf3 <;VF#aU-6ةB#oD._#'0 gwqy ¸@%H@JTDGX&[[%u],OÑBvqcGǘ^7 0Xgvv\G*c))eUAFbތ/IqXrMڑ@T͘ QQxzNv)|:1pL V_Z~OEjF.Ͷ,u*< I/$$D p2usޥqNuz;Q9&r&ua~5;*jͰ'(o@ ;MּB~@."[QanB,f2HyhFPEr]$8{t;Mը(C[0i4R+ڞKZ噦$(=mYe>pIX̑ `I.sDh>(m0zpA U֠"qiu>x Gr|Z@n\b&@Y|!q֧*u=WD3IΓ~Nɤ,h ^1&%4#t&/zޛ-߽ڋy=*AQVBLЊrdzdl@ƣm1*7N->D7\QS'f}<(jL@<,]|\Z)@oDA{cx_v8ǝ=v esވƩ:t\.Ps:aѦCdJo!܁ r8DS<jI);VDžV>L{|~_ovy=˖a%Kz@eC fݩjjԽ qzc`K0" ÑPfrCuӅDUUJιT(}/!q]];_ r6VC!mGE4'O. )'ttp}ii5t%ݑ`x_@΂#x+$)'UG@R-srIA+.&P|76EtHxv:re_Xh0J|,JUʹhE`yI>ArfUU#  ?6YQIuP=)4HJUF`#bV) DI6uޔrDQt{2./dDg{4P}& *3جJ?CncMc-ȑ@W<_⼳Br8k{:Bm![}g]YHmN2vlN+KC֫Sףh^^_Y1(* 4՜+jcqd BQ gSJ[E-Y=RB4W λFߕdY=s>`Gi8C]3ebofFjL$lZ%Y@3?Z(`pNܥZ:'[S C0e!,86q#[oɳZVDqdԷPFAX&59O;q b蹪_058AҋW)<;W4'CҎ/jiob?Qꍸ_~,%\} | ,IZ '=SH 3ϋS ΰ0E :lw/m3BVùl7+i<;u^l\VQpa; _p]wkHo\SM5Xs.}p\I1Y ->SOg`}a_cL[QmN\xa1 wGKT첕ѺíF?$EaN^D'UH\r2*F(EM"y\Ttr{G=ăv=nom%~A'iw j7/. ɪ(kIXnJ⇿%NA#htwݴ7ӳE-pB JS7;<+= -|_~҆DcXw:6U|0kITlk415FCkj:~D\.\( FH;aW*3[8!uDzx A v9ь Q{̭hvmm@9ыJp5D.K$Bf=-A'&B)ܗG* d1d o52C*?c "rU|gCD W@P-yoV훙]ղ[J]94k>X3'ש+f3L$Mo]64-P8e1B $u3!tD r H/7qߕ~LL]NJYLj0yEhr c{G872C=WjhVZ`dF٩L{z'\Gf>x.p Fd@|5 EGTE)@y%7vY8\qov۸ǴfDa!<v3o2Gr.{r>0D Ky,uN|N")6 YHqަ'qJe!}VZݻ;wq]R\ عŪ9LOH_Kv QyEuZoI%yaf W{q9&ؙY[DĤTb~s[!:EZ/)G?͐@uK7@s # H@߯fc;5chӁ5XafgV`i}<`1 ^<"بЬH|8!?9](XW/cK nOnM~9s1-(cRwe^-<@ofJwUp꩚ ۋ?]9{ =b?ҥXc_BގDE mFW^EUvkȪh8*"3qחzSqBWdKO3& @Zj"b;6b݇ʧ'rH'5?P!ͩI1`=?TJߧ_.{<`Tg$[&y QEns޳a6Mmr۩γ*Xqe }mg.o ٰV5Z{S;@1Jt4≕BtW 3~4>+_V#7,kv}У]rPP] yG#;!@7vx?rB6\FY7ͧz($(*2RAăS߅y0P!:0;*:Xvb:fP[۳WC{Vݺ9 CZ=H_S(?竨H6Z)ͦt\1ԛt6^0l2a+ (/u5T2SIɔk¸ۅwUC.3—/y0١?8vYR2c5+ml;ߩ ~cۋ#:r<5X4RLU/$/8] QkD##KJRޝ:~\ZƘWݪ)S0rḦ]^~Fp ~LW }hJ!OfO}7/?Df K[)EWe12Tc ԯ KjxD|'T"8tx,g\ "5ʆ4%Gw|9@؄vd66ߞZ'VDtݲG7VcsT\ !%Fs\`(('G5)KZ~w\v m37wh4ԣJ| 屶 GZ#ftQG/ ă??E@`w2mHS)o]c{(3G$zDBDí\ eQODpjEH3t8a%!}nv;Xʦ1coU k%/z%!Rf Jjim˽ngrV?]bka9:nHObe|2P4iZx/qVb:p2j,6$5k/CTJtì|cPENNfQD{.I7m UKBJ!\6C/m#d^qJi2(Sqt}LB jO=OqD @Yh>Jab%t:j㣵FRP8V$8f /ocų^kWE?fۋgiB[?Dr?+m κ毰cȣeڪqCJiߴ$`z駘jAjbbVgD܂,V<֏ 'dEiqGƫw Ǿp 2tV'Զ a$R bqtޮDuٽ:mR;&&orW$06s%HIS55Iq汻%V14M&ue ^OT6ILR\$4Վװ(ZBOdm_dA>Xo&0bXӾݑagzhxbss+xD*U mZ(^GEJ )L\\ /]R8;.u?'Eq}ѵӎʓ)?$aЌ4h,"ely?"`V5|H.00F7,xhr 8;1^8ߔ5Y]szfi|kwVlޖۚ$+A)#;6xv!}۪ʜT]d# a#Ĕcn(2P`Жu5>gpU3ǡ$86_gڧՈet侺l #Z&-Km:J{Zmp!RX5͟(SI/_tDxr81I3X}e(784 BْNoUu-tk~5{VR@ 1%?as-@F[c,rC P,v O8z`ZD6sIzq_'A] b_3nQw|BQRMd2vdvvPdUT wr:+$cKg2jǪVCIՙOJbU* Wr}k Al~d|Nw喃:X cǜ@`]V>JFiO,dR\`d ̽n/= |3h#~J:FL}3T:byfTz1X(֗.O=7F>Qb,!ı> ]\ye?~a9?*Z婛.ybaZcC4 )Hc|t^F+cnbk`H샩 |XLG.7e> DBE00*peMwPĢAi%. /Oօvm@r]q@Doo׶nS.r@>FC=ρ ˉ*2*K$jgZQV*&!1g ͫ+,.ݥހ>}TzCqG1$y"̍zMNh|&^LX}-sǶIxUN0Q &<:r8W}7*‡֋z#%8ƪ0GRPSK'ψm ^ tiuyB..?0ftyO ctHMV%^$*EghEbͭ[0Y3E]6oc@V=ҧR0j'O*&3YIA;^( Q]o7c !ȓDxLI3C*i{^-gSQFZH*L,kC \{&hݖ-=A&kzdf"hI ?T"7Wp^R=O}!:;ȯ'9FVO+3i<̽`w[ MD)}?c 뷉UJ@rG&t.E$ ]3XhȚbLDQ.$#bDFȴ)rj΂&sWNѵS=f1{asVzBHw4ol8a)GEY&+5Ph :Dn:xF\5-DL[G/*\l@~$3Ȋbz; dCN琡 gFBѫ+j} k t Rv"h *3,S75YxETN=WYqr_ }p1F$Jc&Mܓ+U1 4_&?z e:/Ag/N⸹"TJ,pVܛAO`?(Fy"jIчD6`Qt@8ץ ;7Lr҃`}j (Ǡo4"N1p.{L~C C#3k+ΔI9'4lI7^Ź `SB6_1fаՉ8;ѳ|S[eI{{ ?*$3F 3[W?w$(o2(7G6B(ۮ2FpIX)9C2?h+ é5psotZ[AVE?J̅O)cۄG*z ԪȚX{;0f:ܻۨ)XƠT'qV\p~뫑SDZ_~_$%\H=FhD_8 /HL)83tjF)c2ՙϘUu5 (F:=(={,>,]Giie(gwp./rHԈa݇ŮO=uG!䒤@dQSY`[|"Z@K(>Jc&ƈN@Ɏzުt=BzU0ANEfZN$Nڞe>jCY!=9ب-I ;EZ3vtorpgdJpx;߭CMw3ϋlw=$\ W΁ΦWDS `<+݀pa2A#+5 eY@ޯ oiPӓ˶ɢ[TANڋͅq`v,/%(H=&ftiȿx^CfxQ JңTPG̀hL|X,I7|r5TOo P,orW6 L V-zg+ :#2=4VUX  hVAba,m|T&c{mexz!Jy'{~M`zk?Hǻy8@u+b/LyNpVy崽IX+ }>-,;jH|Hy?y|6SRW .L)߮X+B.l]P_K^T_lPi LKd?gGvpk»x|'y~d>#@fN6a Y b(}&JտŘ%J.Y>9)Q /fr11  `|h0@AZ']s'68N!`N{ V}qg% CP.BKBtof-a/Q}PH>9N|,Hsy .릉zcU8;PTL̻_ѕmP2ޑbu&!!z'u`-fY NXf~p>uG-Ac&۬5nF ?ׅqnpӔArVV"TދN S*+kH4wXCXmx/Ix8#h|TY|\ QաTo oFٹ{քG>>>9" neO>ve;Zl>$n}II__ȪY۴i+(*IJ| / 6ST}wLgiaۦ=b; SJYFwh3) Wo,ʫަ+ PI=3p 0Wˡm [~)ݗ/"^%\͐?a; "k_m9n?[:dƎt(o Cmuη!"ZIěڬWם{Wތ˫XS#-fg4pM{kGDr,ts<zi ^뻑d2m.,e3fV_d![AN)unDkBՐs Ir1Z2y7o!n{cU1;0D jAAUEsڶF厎j$-u1IG%'Qdڞog$@djRtv>lx:uTiRۚd_::֊jGrM+@ݩF9+݌f_ZK{4 z^rAUS2$EB9zrQ^xun0ndS}7},;&VCme=-k-Y40'aߎ1q+Q 5,qpT|Z4Yp/|]kn_>X#<r,{u=WC̝H;~M]NxmPhaO҅ 3v[5KKr5={Y7 :rH.}`K % (%z0{aQ\_49M0g -j`pq!.zJY}< X>qڷ}DUM)6hl)&M+">1-kf~OuT&;ʼ KՈF5X%EzeѤl3`dA5*06_ ,s&'R&&\:F;p z"deqOAeF,s'4nuFSfXNxh^Olw~drTAdža&,;*mJA&_̔\( !Κ59ۉntSN(ߨ|7K D&>[v*tu@_]mׂ A)PLqNoͶ/xro 4tlQY''VkgHw Ů_rR]ՊW3`AA]_N 4Շx+}4R pm*(vv|'_=ݴ҃!G `Tn%nenBӱܼ^/B~3CP  bqMo #d `o%e|rsҲd3X{~OحNf<.s7=&%ѺŶH@ $R!.RWK^"ܧ)|u*Dݜ},Un˨s ekwN:,!7u0l˓Axю'7#V0H CCZݸDlx2e+ǽzv8A ZŲB̹B>HW: ݯܺy2x@Yz;P <[Zƥj2)fF5_bfJi`Z2 c.!x%k,9b3pUHMp>pi06,c?$j$4sG/Q+Aاo,L &WSp DU`{igkucOz\,zۖCqP$yx6ayQ_-6`@ ٔ[0D.Lb'c_f5i+ XiQ@P7&!,p[ U^F:d饮AR_"HpTX‘(]p? agbPv,.Βl V q)7T)7'wT95\\f#\AWl[۴#sl v ؀9Nj}xPD(cNwB#krƙA(eKՒxCww)'\x0 <V -sWQ$# +9yAm`j5:/rFFmN AVZu `'^1՛Hls72 [zW "װph"t% -1(97S:ۻ8 B{{2Ƀ7 ܰf%Wz,lxSzLb_,+y8gP+NIZso+z+Lho3U2J *h8Q%TQ m :w4"=?BRsmwێPN<2RLi@0;|Xs.Ð\S V_cij< 3gYbH\\dx(h\ձ~JkĨDzJ)liKYY($wt63,`h@HO ×}k# eSԓvr9Ux-IC %fksl)X?qӔi ~CA&&xi-7CP X8V! @#aTh.ۿht65y:zJ="0v:[B_A9 .F._["乣VFkؾo"zeתU XA63m8@[֟$Ō /`6X'h zlxbKQs5x@)ݙYH1-_ ׵Zq:⪆O@o/,avvo PƋXmiY%"@I)B``==:][]E!àz1KC$$eTF}80 J ?\ջ-L-NfttU4E 9LgqE`[&¨qH&`R aVNRет^r4Mu7쨄+qn+W5R] 9Wa {O _^KU#CRo,6 _z,~q'|6Y+*h` o56.qP/ l8#U|{&[*xJCm:b*h_kSˮgՖV7n\VL*XE_Eئ b-% Jfɵceg;EJW\K.1q ct*V&T4hY @xkdf 6S9P2L$n1~eRs2$qrt'؆]5E4ѿB;A߄$'ʠJw\YE?ru`];%4sqs^`9@SvZ) .46}Tj+1I/A⽊iFPY}AE58 \H^ط$O jx0Aߚ $Y0uRk*fnTnlϳaM]Se$l;P?*xQRh+([ɶ~TFA&jH)kE;ݧ$ ),?bu@P.mJFiT}[r[$_H:cEA]H|̐l-&_ЄmpX?,WT٩LZ(AcG 99xLoQ~CKW @<$3{PΚM ٝKe'2~iK, Oc#;4pi@H&mU%۪T;H"w$ W6농θ(4j rw2Ζ** @Rl䀳pmbTsfhz|'Y6Vu8 ^oKJDHwͶ 9p]y>[JY*G=U%|n`A gdõZgRhЄj,}1eױe!c_)kDF$ RI'9*O76572bIA`ݍ)Ikh7yIaI 6ѡDT/}ozoK*ȑ3LbIMO~KGCZ״* ^TA؟Fm0v  b0D%9*f=kdO 5i#A,e=NꐡmH,:;YvN9 ɺ.R-|R abȞ, {ik@ts =iw"yWTœڶL&ZрЌ4O`HKkf0C= 9|MXM]nf«xР%}M QϫImMEFokzj.xO' vQuЗKA23skU(^3EP%ްMN/sXWjZ*4;ۉ+=  V턫~{V0[lÔFT3mZ^|->eNSw̴~Kr>5P'\5T|Q B֨78JTǬX-J0hOTZw741kGȈ]rAW' 7Ӡ6鱰?|j*tL@$:f+R[!/U+[2w@R4Ϸs @]wAդX52)r[z+KB;'^% -m8A ! %w0;Yѧ~ћ83Gg<:{Swk|%]g_.mJ^]1"hj7x?“~[F/fуx`SY=#MKlJXS7UWK#[5mJ.G1A' 1 Iw_:05)2[W"<2hS@[OSa$KMۗvw< AaY2^mD[c4`NZR5<?!.]^:|#4 ]y,+iم<;{x .0q\oCAVrR^Y!Qk*O^}3l:?ǎG.򹀎:{(1}j>OM2>}%g? j4I8n "Tze߄=!.:2 hnUEQ'Momcrw|K5YQ` }hz1 Q6p8rG`Qʓrk֎"EŬug^d`zp5Eȇbl]jeªFӫLF"qxuO S6ȝ M2OdF>PH9$P_mdatN, GۻUNx265 (build 79) - 1.9:[Linux][GCC 5.3.1][64 bit] 8bit+10bit+12bit - H.265/HEVC codec - Copyright 2013-2015 (c) Multicoreware Inc - http://x265.org - options: 320x216 fps=25/1 bitdepth=8 wpp ctu=64 min-cu-size=8 max-tu-size=32 tu-intra-depth=2 tu-inter-depth=2 me=3 subme=3 merange=57 rect amp max-merge=3 temporal-mvp no-early-skip rdpenalty=0 no-tskip no-tskip-fast strong-intra-smoothing no-lossless no-cu-lossless no-constrained-intra no-fast-intra open-gop no-temporal-layers interlace=0 keyint=250 min-keyint=25 scenecut=40 rc-lookahead=30 lookahead-slices=0 bframes=8 bframe-bias=0 b-adapt=2 ref=4 limit-refs=2 limit-modes weightp weightb aq-mode=1 qg-size=32 aq-strength=1.00 cbqpoffs=0 crqpoffs=0 rd=6 psy-rd=2.00 rdoq-level=2 psy-rdoq=1.00 signhide deblock sao no-sao-non-deblock b-pyramid cutree no-intra-refresh rc=crf crf=12.0 qcomp=0.60 qpmin=0 qpmax=51 qpstep=4 ipratio=1.40 pbratio=1.30\&& 8ˀFXPީ]cO# -Y`x[Ln Cاr5-}ږ.C&^7J=cwroʮ" #9;o c 6E!WL0}8v¸D*NJ_#EmOZ4SYtpj4s:zTe,HJEåQowz!'ԁ-( I 8F +b6 kXVu4YxICS-ںc䝔?/$τr7H:6rXe!+j޺R*cK.qH[& v0Na+ 彖7$\Ft0NݜH9 ֪mBn ? /Z[Bpjw&gihqn˱]p߿DX=,)"m}ڒ꜠&H`Xd snGq9X+$i@ލәhUβliM6Ϥ`@'(鄍FMU$ ڳy{^ A 0ԊDՏMzܘsUjWPs)5-}"&^F/Rb(^MaؘqXlRof)"6nt12{%:4=$Ҿ;.N2iCn'tH@t-R |ov#!R0_&CdӔJrp_\o( гn]5,ZNh- W2nUbw['p j {tM6W-4/+Ner&ʍ3g0=13PLQ;뷗6 $dSR 7`LK GJLAL模$h)n ̅{pA:m &b3|tBv!b``?`ˆ~M?J}+躋$de!}\KiT䬣zR׫OrT)nL9Oa WDR^F"m nM!Tc7F Qa_&C/zQn_y^ػXc祇' `K7,DW_LM$WE̼ Lۿ^P)=rg/6RERLt'G=,G(jo1duR荎zʾ5^y' c w'8qFo3nwɏ'9%դ;gxs~0~Bi['R:ϧHtMM^6OLw׍j4pfiBGӈ%9'F̎)Zna=t`1s40,Y]}bB޾(:X &:1B`aԡrQRM_O7etCNj\oK{#Kn7$7$w "2K {sC(Itϰ ?f)xw ;bb5C(f9%e\ƯɬvobJ HY҈F.IJS2F!ֵ>0r#^^@K֌{jDvHhO)Bq;#!a/4 S}+Y,E{w6PxJ5-vdZfR"btBoKrAc W WĭZxǥ4 V.Um Hk62L~pΊY@G<ѨS_1vIj*Ec1֑59@:>VZ%Z+G#ɝTم4AjSpOTێS'֗r䔿NEr#PRy:Ω(XU/XIgOUؠrn ';X o2i Tx.`dvC7Cf WyL`!QQc KQ}.eχNaRQBy$c-a 1Agu+;0]d\E$35j5@[}#eyQ Hnl3-$me?T:25CO+3AA:: !+ f}*7(6Lq@yMW;>\eUϟ#(cDʗumzh*{Y4jAj_ܘ|YЍᰜuڊ8ﲞaJ4TE6av.qe`* ͨ)09;U!-um3:w s~l=7tˑCE'ZNʕ]O,:6qGwEfMnK/A_H=3]33==fÚTKcFe=%KD(P=>a// C#DrIk_n@/NfS |Z%[L9|--vFlOdᥘ4C([`,N(x7s;)E7gRfVZQWL n09X2aנo 7(l/c5d0,-Ģ](;f[@ #Xy C)uX] to )˰ݘ*UpIKu_1U#}- V4Pau[UԞ=lO`0G et"y eE5nhǙ1rU 4ŒJo/B[R"%Z((Ah%cu尀 ~'槖af[ٙ]gό8|8 7P>9|C uZK<׊]{bO,YAaΐسe5<۵5qچ[' *7>DYrVq-ӈF<")ȽpZ+bY_mB8,օx@L<zY0Nex}EON`/-!Bم$+`X~ttC>ag$i2i,AD0\|, S[4Rl R@t6wy4(o˨tͱ3gk[xi@e`ATư6:ϔI_YEF S)K1E׳DIQSӂ=N];ACם PD|CzKB; +~F> zX!qYN؟ϕn;bBGyCWpO.ΤHo?GDrVlmzi56Ƿ@9,YRcϘ;g|l!:@9ƴTL[M6,='Âe(ё4ghI;JY ,"Gf^YPGl|;8`iU|4&"pKZV<% 0[/B:!InyZ /BC嘿A/3؅AkmweR6 ;K2g@'\9U'H9Et˅_+xaYoZ+Rݳk٨tYUa-]T9*E{j9ھJOo|qV3HBXlwщkg4`Q'dΗ2GW*bOtH=1'8/B$lK;&olt{c_, }RhDM,GxجdW`UNR cQ^,.x˥h<gPET4-\rSd+6"s :2 1d9%b:/"M @ uj(QʔFR6㼟C:tXp!v:C %b592@ur9xLoPg;XUkPcRhr0E`t8}4 w{0XY?0jK*)kW vfS-ѱ](ԐZ @XĮbTtr*5V"E}T %SOl>xmk+ou\2= ҉mT5GvriT9q確htr yE??ji<$2&8g3б 0mK#9@ؐQm} ݓ+^ -hHac=ekmhMS"MדC|`7 IN~ ' cFck3Ǡ}{ R xB2`쏗~r:$B?I Nd¨ 8K,!M&OI@qnb$s-</'ߺ?+^YXĥxxy!#N FїQVq+ r_Q { >\^XACAo䥒kT̅j6ctG3# %ĉw[ /m(eoJ8OHrJxc(Hpn ̺0Y3FScwŊ˵J'ij4z%iR\dO]ZE1J "pF-6PK.\, P wgA`&\ S8 h+tQZv ~sJ(mY$HN~C\^ ]m4ٯpڭk#wXٕFudz :P[Ai}2vɌF72 }ĖpV묔:y0;7"5Θ l3\2׶Vt{hW ®r3Wsnwm }uUOD%4 ONm*gʋwqagIw( Lԧ2j C@Oc=8F!ҶV3!tObyeˤNMi4=3 )^ ͺsyfdʉh8[h/=zʑ{ 7{T׭u ThI397(j q.]j=` wشQ-6kb[͞B6 Un8МNfW 6bƚ=b&'2UtU?aIxD"Z=4qyt{%#}{ HHrWXyɚ`}N)Bt-Od=:/k%zYUuZ3*L]i[_p78Zv4s\\\{|s0d;I7K`[s8weEh>UVF&)dX~ m^&]JhT@99pkqb$8mY=uXbA¶l.]0D;YK*p_}#W(mJnӸPrtp(HՠAR6J .j5JX:E(PIȌ< '_\ W|^X8' _0\(P5C閭Ap_xydCz#^zz8R C}K\ E]̖VHp;+*8?#jka(٧P .4?_%Ti{tʺIU\x`9!/-mCP/ @x8Tl ԇUNt@{]xtLl<''V`56> vI=V-w0ت~?77>W~섪`PL.d$ mMK00ѣp$Cyc1$k[d"Y>xSKuϋk _`}Q=!en+S̘+37UK U>Aw2F ~Z21(jV, (ds(eiR] zrM~w"C6>x:u^lbr- N|W&;DyE-A݁@kv+BԛWYNt8u:(Pi/S,}ߣ([П~fφ qƁU=f|? rZ-ɣG~l.A%^`Oܙ*j Sg/a tlPmlbgBH:Na2}hkVUYPnp#V?Oөt o ;÷.\/McA-.^_F!%Wq`;_swCf=# >{6.j ,1*Qey)(a#eMBtĸl`q `@+NѠ9|-a~ gؒTNy&AG@/,yQ7n`Ni.HW;]@᥶ 5\rZP)S*#xgHzu++p- + @snNx-@KT`Bxd#I)}C|2++ 4*PW~ХБv騴Z4IU0IɢXpu4"G|Ȅ4p{ oױQ^ȍxce56Ak3Y?yJLؽP>xN它mQH.nh/jnQvN16>MCil$uQ$%u@_$:2}/^έ<Qw»Px12)B &| lEڌ I7 Zd}>~V@tn۩fRCjr~/kcaǖD0.ue¢7 v֒[/0K_"hd,i;d*P;Y/F_:~!9S3{O/w9w'r@ykw_TT)sK#N՘+66"sYxo`%oHǑg0[eݕPku+88wن"zEB"q|I7EmIŚ/hoC2߽߾d30v=gzhKw~;t,Idaބ\m[doDs._GBTx|VU_/<17=ğVdRxõl$[FQE@feޣ]z |9q)49Rږ;r3j6J_@J<;픷+)fKZ(pVԆFq@~,Gb^PHiJk6N7kz $}[j)~VkZbm}><$RZ>b|b?`V)V9As>^ҋN`ˡoo#*`y0K&\b';_wGU\T` 4.ICPe5Ī]⧁wZDA|g]RG4sQJ{4g+;{_dw8hGMĢK"[9?'i7 Y,l,A C@ ?sɈaR څmALIl'5| r45HFҕD'ԐM; 96LUSLt{cƃOX 5]A?L>j[6[؀ h, *'gMEߩȄQ^Ÿ] (P0zu%V84MK. #Gm_۽%f3=2FsOI\hb.!,րeh2388Mhjѕ0lavKLXL~֣lHx7@.;Ìy@3zz%r@[_P IL_0srgacjܐ,O4R<OJ5'<.B{})چۑ+|4tUN  EFٓ2-wۚӄN /0%O96P-ʿCYmlty~%g.`l.%a~MՍTeayoڈ6`ȏoyHXǙwkf6MޫŷNh76Ƹa5ZB/1^ |U~\pce` FMwI&|nKEkEN%i"!h[~;llTYN؋߇zf)fj(?lE %x,[XHXTV2W$UZpjw̷O~$$׌qOgJFdw\Qj L}܈AKVZKkMAel: )DyFaSDYS %4|nonzF OR4Cn)-[8oUXgbՇX mp=s7RMJLeBӀbn>(^>Kh+QzcxHn&% -d-LYsGm)C  ƚ7ͺeg mf<.6LսrC}c8U*hX"Լ+c( F")QJyc[C2XG+925Q\7Rm34VPjυAƯ~м>m8 X#H{7f/EL[J^*! Kf+*|f\(%NT3o:?M؝Czo'L(4ÄTdp84,9mzk<o ZJ9w+=NOueja$|1lS\uܵz-}}[nׇ;5r߶i۠(*DVdQf=]t>1Xt2h(kY%.`V|9#By BZ "f&"kM^<9ݨQ{μc"2]0 0fbZrK?> f* uQ\jQ=NVrq+mix~ѝHz:kiV1zǪ[GB1 &[#DZl"UP}#3zibakam{*i]sQThaC0Ɩ+Xԫh#-~ã#'YƿEfycKȨ̇/i7DÒDE[󦹌 8%v){vB^p稑eƄdY]k.?TQp` [N?ԁMC%6:i&*;mĔn8jO]͋V/jz(eG#5O]DoEmsQ󌅁),p4Spqf/|;P{;=>ü8D۠&_4 py@SQG5x ÌI.yzгF]Մ"$e͌ #١3肋tz-D^eD^k\8Om#y !O!nhX,n6E}suX*ӥ1NKFu<,FltpX `=^gΛE% #w񝳒("}2z-?Jl\ɉX\!eWpρ"9Ena(쪕1f?cyM䐎}?D(nfd$.%@\3dRj-+Aim7K0K,WebSXDfk$cO6n#pG7ۻI2yxCht'&{ DCLjl|N,\ZXS CT+g7^ѧ(UnkQ.T@o\+^ٱ$;!v,3՜S#'pbH&0>ϚDV~~,h+bsgN'뤫CY~gr\dTµi9-L~B\Wxl~ bxp' OnЖ`9G Gm99sw.s'X7ZD KT[`*fЂQ߂WMzNUC5S*jeLg|8s?{ɪM%9\2vg`y+0)k oD|So6ɽveJ*A7X2!g- v%yX5ϪpF]pšL2jK SE=.ю=Ց85l+]@LdvҺ&hxZU|70GIBԴ6Bh ,\YgKR.)m%T}`ơF,rilZMAx;(5i, =Qzvt<۞Rv-I6?O'UD?|aRd ]i^8 ܅<7xSәrVxToW\"G([?:IF"#w6N>x59nVh5R(}rQڠoV99\Q=0Ch@y CJ"j:D7Ļf푇Y!?*!!ܔ<O?MM` J'zO+q0OW B*-X$kdkT^/M_ \1dUQ@H2{k'0|ZS8s%#Q20c9dbۆiU*3oY7TUmC;f+(Y%0 tV9+\WE%2b) O!1…0auŋc~]Nva/p .1-b]A8E Upl27Z8sۨY1M˵gǂtBaKF^SJQFBPȣoƯ@ ɣIխ yO3eBBRZ` PQk5uIXo.;a @h&)^Rg&yt@aþ'ȊR~6phea yr{k+gOUشʴ_:9m.oi3OBz7Yn\Ђ__=9cy|doYx8J3~EItm X)x߷ dΨު]$rcK.+K^Aj ǫI?"mcJA84e,OOj:BfDx͜„Jhb;`2łsh\(%#L 哨ksF>s Rk!݇/W.a++Љ ,!%Y`&:(;? *o_Փ'#n*n e5cZ{!D}@AH{G\F'U7=O.}tԌEN@:!RwҼ^/sFXy?R<W!gF ) $ގrRKjX*>Q 0<1: ՞FT߬EiuK ?(['eQ ̚϶ڇ~D%ڗrN DAWG푯*;/xMg('ƻ'sr!&4no}laqD110K]Y % z* rsF\bF5㒂W/C:ɋ>n ^(vsph6;CT = l|̬ΊQdeg|rFCt2Mh) )ǵԝ. >YvO*0ZJ0R3ARtʶ'PܧkzڱRY&NE+"H՗Ls&/4hulal呋YVï'^5zVڅ=Q7,h18KGOϒ;aZ%) OGb[xF~KqCn>gSUd,&'`C#5z3TI!# TM^ ,-Lg&aD8O bt>y?a!gj6;?-)T<9铋':$dX1Xç]Yi/-JB+9򴘛z w bϻ=fIƎ[]g[>9(dr}1S֖Z7(`*7 f-/_k#(Y29I7'O=6 pUo:0xd'Tz;-CDw@I Fn2ΩB*Ah5l2u 0vDk̨(”IcE 8/tG{l`/e(PfM*aĺBff zr&?M_,w>`P7R֬K`~"| sXtHgZT&b'tXNb21*J&*i1V_\Y/,m2%膻 kpyywb&H3;SiJndq/`G zD K!;|~骔l~b /AHz.Vدh9KdH &yzbe(фV3z_Ɗs-} $%r~=ɞNWĢiIf`9xYA??]l ƈX\JV|F$M>1?gP[fS_"{Kp7D ONrHDم]=ڸMlp?.u;NkX6ɸdGd K9"" /wSf!\C)fmzl6%k &zLzhZzh\׀%2 8vԟvzwj%ɺ}<82mQZ61i3G,5s;Zt3bqCGRH߬Aq ={k2xPnMf9W<_9i%N-2z]7k=D!={?[m| o X!{<_3^g<+kOI R~!iY]2cf`~>!Dv/bP¿+sH>W ﲚaҙ_7GT q?RxX?gyoIPs>&" .q s>¹W9(,.C.TvMg\͊* qEd5ux1iS^; [bb)㞋-5zdC1_?&V9T}!ct҄d?VSM{,T0:vB)b;ԅ!$K^a<i(aW3g|ԥ )UGB#ԋhD~Pu(3։KT.9`\!K?OU Ǟb-/0kݞ! y$FJ/+z ?S>$؀xxSҝ `C&CC'cq1~c͘+6@*aR0nmǙO0彚vbՓH5]Cyv*EelIi;U=hСܐ܀Z5½oAY&q89Qv_`J&IQY1il _ 9+.Hʺno v)^|KqWV2~of┶ӟZgt>Y֯>:7wJ`ltXO2Hӛyuc-ԣu ]4QwAp:ޙBܑb7+=@r ~)2H@TWS298NBG!5LiiQBs?)?˜b/ۘ6V;4*|Uv}0j@[TK`՛ӛm^Or&~Oԝc}r}$4 |(ՠ\,hlbdƿl`!E%L\EH4D=5~bj;+}B ͨ35?Ctg>š먈PROP) tߺl,}لsAOrh-̇{iZ3TP] a7BuGeQL@[K?o؞:<]UE^aer[5E7)3ҵ&QP~%J{q`fxyzn@g"eĄB1abz)DpygPGCY a qB@Pł?l{;$.kmR[ʱq {\kǫST񩿯=pa9`j\XuT‰>c1B>.,%?Eum˨թ&Yg82$&Uqϔj)S'~fO@ռ=3zA=#C+ew ᕷ/!'F,-cedA]bK/%8Sd@1v}$LgIj=W/ጎpQTCqn zJak$Z q; @χVu>yK{9Detޯ: H#h2VeJ۸Ѿ}R+?㵍L h%8C=Ge h^bQ.ϣQ,~\K"GB4+G2WO{;gVrtT@^:>៕%Sm-^RT\ 0tJr\42C~\7zBt=+a&mLZʑQ<%°{đFy ĭj!rbŸrRL2d[~tddګ J y0ikQҡ盡,RzVJcbE~H:_|<.,#0̏pMsب d &u?wX6M#{|rƲ.D.3@ R ޱAW{kuN.*~'EBoz zEs͋^ A ey9¹FeLu%VvJhw.o]&2 4!Y9̱$vs'{lV&AYQÄv"eZ}`z 1^{tsCIp0ٽGwF/A.=A4t^D RF\3fO04y_F fZ=ҭߖ5w65F @C*<8Tvl*)wZ)nA.8M?d3 ?q|p:x^a N*i`]ZHǽ~^agNxeZDrfFӏsrPA Fq+i{d]mRIjlhMJ%G_< NaD;v?*Ax%!jnM'vx4S%;OlImfJ~ODLax7 |\a[ 8^M8[Z[3!anpY4J2gR<vM醦fe\6"$)֋Q!߾0?H -Yɒ&g|Z<|GVkw.vpm6L[\?y X:hGhDNO bwoBo !UkU4rݧb?G}f [Yam"nv2纱:[:w,^!b;^I﷽MH^ ĝ<,J_Xk"Vx8gpjŽlDUYPɱ-PwYSR{:ⅉ86ha[;IOqJUVZhsI^]$"q #;1_Z}5grD}PAIFta~J((5礲>g?JL,G]M3VgZxLoFԵf@gAh-g"`ߗqt:x.Sc1^Mf(1eIiX x:%FhoC< &E.Q],X!S? 3R7q E@]m 7::n,mKy*a{#o<>tUwPy/mk`gΕ/OpC,x%f"yGʒGAnIڜT-iF~45 :/Gd؜틼#9!54YթDn8:uEip2:Eߙ4 &75CUR|j_鐲Ħ;WV]N(sey?4΋&3[|sa;ITqTɿbkg2 L(` rCrBM|W~C]sSќUadeJWsftD36 .L/̪ \p |V)=dZ(AoqvMstcdpM4+Lkˋ)Oo+"X/Nb)=e'1}23V͐,E}'@ʰ9]-({AN#`xݸ>aZ풲y")*]ߨ/WD]lNo] FoSM|4m!ؾ0d=H V2í),|Tle:ېb1p^MP޴tYR)2La}.-I{W3p {do8KӼ}4Ю<C)+Blj@v5~9d:grC*V-<<b}nWdw}$|tLL !z?Z A"Z "(D{]2Gk0vr`q[ͳRE ^1sE+)-3'F HPZ9$OPmg#'}؆C t;MiHwX'[r< HԦRU:YkOWzEZv\>c U& zX&*H Ej'V{_ . N(ЁeI%Ƚ`YPfT\%KVBGC^VXTQ1{`ԙdreܧL8KXo-µqqrpD7dAs~y K30P#ᖏ)S҅4rniEݪ: 42/aa!(5ӫJ2i4WE80'Цqqzg]އ dWp!9r]tV?x!,dݴKmss&}>8|4 <aAبFM)ǖ9cna4bBeA480 Z"ioZIB\X>|3|C _xz.Q|٩ۯ0|<'[(eF<^dWŖ~! ڢGtHW@" )vQ2CɈoQ 3oNztO<iKO锷:\؎=fbpDHi叇7Ȓ KAEכzka @if4%o ԱHQ}Zdqj) V€}XIυ(+B<ܷ[J'g: R3xP)p qJ,pr/P$ū3%gP!y4r߯&FiJ htbKCDDZVk_aFr0 AI YӎZ}] $ T >q /ʁ )R,nJu#'Z@D1UG}h6<: vD1Km|;,ķIj&/{ KRJ|X:!p)&\!rɦ6a{Iws+z5͓4[;#@7xЛr$]ik#;e Rtz8HPV/B9-w)XBOR5@Q;E b4*3 Ax J6A 2Aͬ954Z:Ao)֝~znx3-u/C'=/ Rs3Sqg#?|+?̿WS[5;Ջ, _#3۫6iU̡P7ݶEN2q|V tZvRڢ`<}dVO %U3eߩ_hdVa'<O<<Pw̉A %Ó*s &xuW4 Er(\05%1񴗚2y/Ų$[Q QSDxCA ')u|lv6XzŐD$UX={&(z2"ޚN|')0zxdUe@*tYU3[^W-Гy Eҁ  etH"i B J}-W{d&ŀ#nju5k;Hyg?QIsgLkBEǾ6O ,sm^|# e JR=-*nj*︷%O|yӽQe sМ+{>"L)[B\ &mL>jb%=yW+c`^upI+5.ȏFV+rWƓ,5qK9_?3+ Gc_,pj%u<`T]+:h})dVKy"7;χ oxCnd⏪O 9`É(zBKm1ER:';u:x(|vF`Um7h,/sHJyl`ss1_QL`3a $|<.^F < <4SvrH}Obq]OQER(Y~sbR/4C.UgU)\Ud$=_e>0 mdatN, GۻUNx265 (build 79) - 1.9:[Linux][GCC 5.3.1][64 bit] 8bit+10bit+12bit - H.265/HEVC codec - Copyright 2013-2015 (c) Multicoreware Inc - http://x265.org - options: 1280x856 fps=25/1 bitdepth=8 wpp ctu=64 min-cu-size=8 max-tu-size=32 tu-intra-depth=2 tu-inter-depth=2 me=3 subme=3 merange=57 rect amp max-merge=3 temporal-mvp no-early-skip rdpenalty=0 no-tskip no-tskip-fast strong-intra-smoothing no-lossless no-cu-lossless no-constrained-intra no-fast-intra open-gop no-temporal-layers interlace=0 keyint=250 min-keyint=25 scenecut=40 rc-lookahead=30 lookahead-slices=4 bframes=8 bframe-bias=0 b-adapt=2 ref=4 limit-refs=2 limit-modes weightp weightb aq-mode=1 qg-size=32 aq-strength=1.00 cbqpoffs=0 crqpoffs=0 rd=6 psy-rd=2.00 rdoq-level=2 psy-rdoq=1.00 signhide deblock sao no-sao-non-deblock b-pyramid cutree no-intra-refresh rc=crf crf=12.0 qcomp=0.60 qpmin=0 qpmax=51 qpstep=4 ipratio=1.40 pbratio=1.30& u` *׊* `r/DmX[7yoS'=ӯ~Bb觻> #CpLJ$Cي[ٰ̒ Nsɋ >h`w~T)L{l}kc6=5b6.W=OVhmYý9i@.kU6g8?o$r/P אj哓' x_\r#fNi@(DZ 8.\j36 լNshque3!>$gۥ9zRȏ5٩i+,^ J+F[`p4 )8@&wh1= -l;2Vw1mRlǭ*&"4nVs"Kn3KeDq^`gS%ast~2ܸV(uUhGN.h"gퟄ$ٵBH&f;8i V^;P|k~7Aoݺrp2O:0@]1RJ^CAPФѺVRC'YP7*oʉd\<ڣ}^ sYeעkkCce*1&nsnaÂsGkZr L_Piu#&\8 0`С<]Wvp3*r,+ɞc"PJ1.| $d+IkUD:3=ylZe#=r}e>v9cvψlqyW,ܲ6]7T޻!Rʙ!\)eؤc[<L' mcAH2;gUq/̈́flgN@ 7幒lY+sd=IH#zGcګ0B$D&M: ȟg6YTBBk;#)3r^Q ϙ#gB%K9UPt&})h~DDz Ibc9m_) ;dhɚDLm3-T= ;x̋,oWYRp.4YN n)iI: m\;B\~t%ݹv*v>.׆ICHNVʉz5>qi;O[4mO-x` q*acشCkVio/5M+6%O2on(E6J!(kQA'p“[КV:vӪ=g*+aѤ EDa ӄwZ#'4qWAҷur{.P&'9.cAMOpZJOdپS=$krVߞ'Ψm:ISz,ذ>P!TKo<:܀)aw|`[)i<}S9s>Eރx[ٗ /=,i<ʾ S)xCzͺ)h\j')k*GP=8}+@h'kOu:^ /(x37.r~Cr5xMʖBr^ze8Ѓͪ^EPUPqp `?4a\3V( 914zxpo/ʳH}ULy+ha@Pc=)S]*Ly2]uUx ̻X[)](-8oO''H_=: Aeiw;loRyd"_y7-z[¿O͑-%Lӱ>'/|7|l`~|ZʥofNm=RSX%E&W%yag77~*PXOiv=jm„&Îs`L3IWif?1Y*yGVinr/f_!$]`GJ\^><\J{ @($WKr-"viId>S V.^)D}T&2'9^s 7=ѿIĹXM2#A2^[OdbJZ`X~&h3o"ږVtALG:-,1 褮 0d*GץAġAћO2{JكǩSUuú7< RZꗪ-i@1~Q^ſ$yTqE{@Yr3y1 @U-dazoY=!&+Aj1t&˽hkXV퐴DKoP3#`|'g.w{ԊLLSKhz`r{[9"]AsƾV!Ofj=̲ʎB@"$(;ް-DsNS[u|KMQv΃9."+q, I_Z|Rr&Rlg[$ +'jŅ-7GL$hKr$BW VsPq1{HNoϺnc|흃+ye:=vfi8̧((CM'\Ŝ'BJ[gkl;{&nP9ګs460_NYSYɹUc`YMbf4ڋ? >-E<`f\l(PWѬ= =Ư_+YLHm**$mPbM2jťH{ ˞)/M7H^ѪgF7P+ۙ'?)õdݜηF6 vx%b }XK^^zh*b/6u~ɧa!zmR' ,K,xCtEwQwVCL 35^3-᧗:TMvtNwK&H9ɇB<|֝~pD 8ԍϣd8ueBwqT]2Mq= 0@? 'U81nMX{ ;0]e񸊓z#ntJѽ2?%)X9z xDhf _J]zuĮ7\1pM@ӄGmPgu>Àv֚zmg[-l*|alpKk x`'ML `jsj 'aR[0` ~wy ?3[47`+m-gv4:&ߩZn=N珓Ӗ C?A)P'ZVKu#Qm=O-L)k19/^kGk( 0d!Zvg`͝u]6Z×B@tw{_,V]WFU\F=~'X߻_,($i_b>h=SUsI|yK9~f:oq` Hv EsiAt}=::K-n+MVI-γ/l 8G^V&Jg/jѨ/'u"n{Bd/U^r^Jr>Q9'U(Q!:'XC~;bf%f/_,8+A ɨ x̔(67YLA߽nk+LKLɕ㥙(/s 0Xi’rFV]tM֮hӮUd̝j'ILLC7DyT(s!T׏s%D'/ 36!ɃDss-\[uʨq/]O,M*5|$3aҭIJ6ca> t+8x2 f7maPH4t*LT\prbgn wlF^5n~SGZ!I+b22^ʧ#70 d[J'$+{W4%[1v;Oհ*2XEs ݀͡izPv[硙}EV];a0v*$mlϤv"^ l[n2* cn.6'F@_ p'|Jk,@ە GO( kX}{ӹ] K<9q0kd˱ìx.b:~'>)@yT6!=M@n8|ap(e]M sDo֮Ut6$nhX3w ~gf8;x>$ECFɘg2? QVSLplNJ' 3 Z IOg5h_Tldwl-<H=\hL| @_ UW5vPa nw˪,Tߡ9B7i-F[.lw }j5`$hzSF;x`K7{Hx-?.]QF0.bYmU|}c:ۍ^3{HVkŚiڬ4R6y"JN"Qen8. mqwwhjp s!LH0kޔbYƕ0ǣBeW2 0,|TUGƥsA(\)u>[aI80檶`ٻbV|cn/1P4 /ؗc z.0KurnwZD@w&-½LFͳ$KA[!ȱ_vY*lg6!3w9 mWNgZq^Ϫ ~GBӔl/f>b{L^aĸpmPs8!J&zI+ 5b޹[Ѐq Ww㿞qDA=iajagOlvn$ơSXudr9s(BZ1Dh![{%"Qqf~~>LLj.1ranL?sݡeNmj;W*\6Q'e!%&4y(f{1t|ʯ1 Q$ BS%/76/ф=o@?\b t#粒Ƚ4$(mo0to9AUVN'wT(eE!sN)@|}cz5OC߾iM $ U8v Ar7f4Fl6t>^9%5KٴZ'’}볎zJN'3V[g7{wC HmX/(U&m2 ~> twrcfZsjGxV̜˅3*`' ? 0]R)}hi'1_81I:T国LaL>AHV#Y`3A\Oy_M(bI¿#b$qX-57a}nkƑGkHaEwʾbZO|WjDRIq΁[bú1ciP@H3i/,)ZU_W_!ih-m }xHcP3×&[OUdCFNK!p6a|:⏴c}Wi'v(1Kd1,nL}:{A*藳ԒVz'bkAG[q*X_t끟s̿HLUx奊ȿ[x9fL> ؆sM?ٵB;H~>Pm20^1%`HݚP Cky#r-Bzi }!ig!uva.46p(%Q"r8渀I18݁PIK¡]aGsNZ3hV2g)-|49;$ Fs]$Yc8~UTK6f՚ =g~14<$IN 4m6zM9栂}cZ2C/gnaNjnT;Si*BVǢMj?mKj؏SuTd3d,v@}3Ut 2ܛ@ڇkf:t'OVh?XͱmT 6 ;ucF*O%;HkLNwn]RDgܼfQ絊>䩌>4c(\mPӒ _nGik=AR{}'G"<4 oC3y5)eõb1&8f5أ*(?K\(u-}fxrPi:dVV vOǡf'#GZL(xW :KA4/WZڅhep4 JTij(N4TVaeĪ")¯m~Nw[@>\T!rslڕ[l#̳O?6Q|Q>V!6pf:S]&(-5 W(A\|b )3)^,w!2Xjld~]Nz_Wv_K>rXŏ Y5՟.XBD8kp? ﱘޛƴ͑# Q%SQo~Y/s5Xz*^ $铯߄ke񌢘#Ouؽ&Ob߮ Z Ɋ3-IT_F-<Ԥe(o[y.wLLKKi>yO n\S1fDaN'y7W?(MLEP:Xī9A@"cRYҼRߐH![QЂ` +_кUy)G මsx ʈuP*_W[ۙ1^+AtM>HV?G.&M~N&잃CT\Ě6xBۏ}+|miǁ_+\"c#[eAs] 嗗tBIE]NZv(p"2Ľ"iݪٿz07t) 4ud|_(qu~aҀ H$%Feȭ%"UAEk݀Y:lKB[ %Z1sŸ҂0UpGֱ՛B[]x~̈́3"m>Hc䤥oPJ*֬kK$.=Cw֮kԚKŔaK?EJYWAp?;,dԶ^H2Hmhx*8ɰm$Ƕϕ}npq(n9_eIhO6teHfT0&zA]Tˌ\ ζGm"vլ 6gXKRAw=iC)b*YvzD5E]9oPP%B<56 gǧPۢxG@1ԪNBoKI:RuƦw_|_ٳY4!ge9(wu,pu[U F]\pR35̙n-մ?tpWow&,F4쮷ecl̓WR]e5e?•?8Bv4lR Y3R/ㄑY!HU~^D⚷KsC݀T, n3cp9T/ eEydN,@eQ xu{=90+uTDMd@78fjt39o範QYYfpo>}1a=7ܜZYfּc]YCĿIBcϏ"] s5J#W B܍>ϔB0k8y_Xɱ. .yH(k RU`n-x,U1GhWk=Y:G(UZ@j@\ J=1J}IXq¡[;2+u4EC8H7/Vw?PB/c+1XDq0,v`>8+vr5֙ z`!]ie -j&GZ`߰Z$p)iM ~Dz 6#P ==&;nJ^lC((h^DY:Wӻfױz ߱ڷ0^iMrB'K&wkk=:M݁S#b^sIf]U㤸>{,NoKk{:ئՔU}掕QԷ=s]e^T̑.y6d!ym U _쿠8~#Vg|Dq'OaҫKu')UD\1;L-qOvLak^ 5l)^ZZg%X;yNps IeCa:|nb~[73F e _ WUAe!Ár9cg)nr΋VPF:ex??D4dhV jÅ;fLxR\*ؒx59_2]Hj$HQPc/=i?83ˏQ3+ {!-(sqKЅcMHbþÙ[m!&e$]?k+KGN5H%R|Npq^=Vd]RPd'`k5eLn]k7F^̏U<̅X#u!i%TPL.:lOZܲ4iX֊KVAO?ޜꩆ`qjS١RgX\{PƊe7wI#\ eSm_{hhN0PڏbdIP."b1 )QwcG z1)jj$4x_}ȗ @aTևS~/|6G *=Ep vVYhk1"; EU#Ūieuh/mG$){`w%1"bYb [烫Ƅ'D[z/E%`BQ)ٖ4zC}TZD;IY*eL8- H۫%WHM>)KP'cK 2LC@%p׹f/Ҵy0 :8=Uel4:5_VvBwŐ] ?$6{sQt(UNl׽A¿iո> lzτ8mf\C`?̞ox]XUf另߬Tүm@Fd zuhQ^ttG=*OPBJ9o$?7vE?/Uq,݉%񝪡(2(VbLRJGZs +wEց{$j  CPpN[]Ϲ&_oz{Uip7ouni/ ThsFyCL~lHjZLeáEӁ%/iWN }נ}MOLF&DÃ(re}t]J"qøJ%mhCzm5xC/EcJUZHpث'y+Yzjъisdo1+JS2D@H(Fj+G **Z؋&5*E78y%Ϲl.0!kpb<<>I+Ep@wzoQ:LCGe3sD'wMJ*9ep6 0Lb$ YC+Q-. hYH&Ex˵ pЖ[ەDy7K@B,[6MJZ[sNbǾ' cM/٤CxӅRHTkJ˻2<1vteIў}ОA,7 UL.1Y WJ0!RlcmnRDe.Qaj캅&wG?S˅Jڰ&+RO0)NB,pM-MejHx8BbOJ'Яf@ bwS xAPfG?uW9I~S~߱B>y)8-,8h S1*~,=+ـgNTu "9br6iFX6|^뛿6웢A3;% \<8oz5dLpHCCa'A.[]yllQ=z~m+ʍL{UbrxDvۏܶUd^'> c"JCt?AiM!j>R€"_Ջ\knJ2j|1} q<:뷃 =. V WqSy|%C}= BT0RJ#,G06wu" ŅHt:o֡)kٺv3\Oב~~Sl98Ζ.ER;vfrWR/54C0?3gM =[b'j}j.C{Uye󱝱euٶ!~sC4 ()'eL}4Hc 2"Aɍ n:3!% yg 9~j tOW2j_+5/֠ مgvYPgα,_0ݲј>ֳ0)&{gB-mxqXW*<0:FeqcM&nFgT`&\aR=$Yَ#CCGjwVRI0-F/K/' Gc)c E|V:̮CdTm<)' 7|Jq2Š) Z+DL9(VZ sg@ZsU*RX{MlKoa&L:e 8;j9=켳ynnnZS(Eq {G=JV6qv."ІN1~Q*'~Tzs4z:ON%擬0ɣ,R:s!nԸQ^Tf˖4BtRmS ^vs BIAP[ h6G"؄aQfŽ]}"]pq'%bjfjUܐ;)nց(nq"F2#]Op{48-39{$ v*xɛ;\v<;j;֡J(R͘dG$S?/JJ2c N|MjkԄZi܎=JzeK_j T\vn1hLAv@$oKe]&&nBB l_PuuhK&D.U;)ѣ+yaXw_չ ; P"^J1^/:LZUۥOM0atr4r7qZ!@646@I0יTJHA9ǜkAJT"3|طI͘nUIbҏVfu qבW8ZUiom%j~՟>pgRNWMY`':%G{#x߆gWɯ Z9Y>$뛠_:7 @n`g9] -q~LUKظHW`)|WE^Ҟrn˨A/^(N u }iu_Qӂ}!Ԑ44:v',Iߡr {8I8waΖ2k:/a\$ ,Q:>Xdw3Uqq83~k_"W p\|͠cVʥ%]Wf|pEXv{%? )Gm'!) gw/Z+uCa`ܡUv70\Na֛Y [t%hd޳{ ܚY 'qJH%r+ث l亢`uUY[Vn1ux~Rx`gܬMf\!I8h&VPc%E7ݨrarzЮ#%/3O5m KVt ;lA1l"چW`9'.Nh f&d(4Mʎ 5#E&.8V߿RYF$ 4kғ48Oa"4*b5ŭRtzmjoS. Z/ɄtFoDE`偸yJB'*4 zfoUQL6q1JCAtȋZ @5tӔ_`S7OA'VQU V$-'E ef?Q*H >6qo`Bj]XUShcuOnrSB,sFm=#M:c[+1r E%{z`mͩUa_\P5VEr[uDY  n7=xCo0Y[aZ::Q91lbCtoONt% 9j* R+ 4p鉤?9O69PθW12mR'6U`b$PBD?ɝ!kk':At YŘNvQԨk2*(KNQ4Fm X'lLmgȄ{4kGaSc:؎,NKNhH2PG9].))Kkݒ'DT;_(H]!/L7eWoP]8~VoguY>'IҞg-Gl- Kp8yaKz_昣~_^BQ]eOݑ,w"x|k`<ēQ1ZQYXfݍ e)h8ώ-YzΜZ GN w;X uIAkX;5pP4SdPZk6+LzGiUZ Ĵi[/}Ǿt@N窝3)Zr6%[:*7i/%¸@;[c<1[AE2djZN%1=X͠r!'\:HIZL \f$?5`* hq#2@m%gό"rX yR #V"`IBb&wNd=*{mެCu 0l2B۔Nǜ- qexWqLQ4|="2ń] D8vƽDEVn#1ߘ6z,k:q h脍 O~=BCfVC "LiuOqwϿp>dRG-8% 8Yh!GT֚6!fѸ-FJ'׎/S~=ʉu ^` 9"gw=,{?I&+I(::oy_ _eL.񞾐hE̍PYM %CI5{u|fdV{ 0\z#k[||1(>W >RqA/Oru\f2^\3f¨l p7F=$o)?brTB.6[Ze`/'?~p sqh|>\' 1Gv_X`=pY2R:ګ9]s,A@UE) *:jdQښ?@wk@% fmvĆ{K[ &~!tcY]G>[֞dzc6;xBr؋sXhPvU|,B V]ckUx嬲M.jI;s\<-#./}=,.ht[n{yF[GzjQӺTU¡T#ڑW9%cu 54+,k'x_^@\c0Ln#uj4~@q)yx],5WOn-<λl,wW;38Q XBWPZX)=|Y'u5ffF A[Kudvr!9ђV/ iPRb*km61Bxj BelX ߢDoEʌk-_T QsFbaĭ]5l8)LxrSǾzP?$ ttv1c6Ǔc&ı0]E/mL֭o#g򸩔 Ob&GxA% )K8r_ 6a` 0GN)T @t˞v&p@~1  G#-g _{WFB5%:D u<\MVPsÙ~h21[ȂdͤMV5'/#iL2rD봶HLkC"]փ+MQ4,`xHX_"e{Z&z@'Qj !J9t T;᧻k60z󣐁͎`.]QV|r]vAm.׏)rdHHW[Q uVH5Eah+:;F-D+\b4 sL-iHH3 .>8NsΩpQdW~pY=p(Ǯ b1pM7zg+HRVaC}^8.--Y=:(oܗ^Sr©Lqל_(喺_%cڀpl4(K7 1U߶;5/{louFg`<%düKWQE}gDlGj5Fh( MT @ƭO Se~4[QXRIY e Yۋ]T07B9|uǫtFUs` sf}U]5/^_hwFݥ^U4YӦHJB/FҜaDzwb 7ىa+,І".cr,@#y=?'Q;`@Iиc@)IBjE69]Rs-- eT54ၱ D j0!j<%2@Ɏ֒b̬N0i*dja:__|8ň;v81 C]j=Y oiwIv~R30@XsN:Q>5$.<DW 8FV0W_P5ЮѶ(]79m*( &, K$#oEPH5|Dh749HinԳc&& _wblhg R;HI^QYA2Hs3/Պyq4t5tBa91'y(Ы 0V`~:X/ >Y^487Y :R]HZ$)m|ʠ$"-؉sM"'>|@!˜_Jf"(*Uzu!Ԋ`CnQP6 yx⡑*N֋R@.oܯ|ŵ<4b@Nb4;w{&yĝA(kllg#C#lmGpY 4JچJ=H_Dﺱ_eA7C&v sigFȎB59/|T~SK;,=ktBCD?zxt/8³iPTFj˕fr` V5 ٞ~B츑ǢU 5](; ώכL𐧁kyN v^Y23Aj^PǸ~XM}&cxB )I^һo,?(ҎpMdބ t8"m$ټ (0}6t(J5<',S/%-J"lA";;ȋ NKu]!ZuP~&X4洁bs/pe .TS!!M"@ڋ c} *_D(DSwAsa(;l"ZW-dW~Q22P/U=;VTDϋXȝ2Qo.ŕ rRI3h= acgK5, X ^ 4iKMejTy! 1(R+c#q] 4\3sR4\{ S^}]M~q;117) ÊE;# 9.oX'[9Xk# &4۹ /Ed S):<O ,Tx!yLJKni{ddH:wP,Z4bb\\#-^!`!Ё4bVg0 =ρTCn@G&1[֫ w(\e%Lb 4]He .$aٜQAzGꡔN01&2m{r}^D_ mpBe46AӀ旵X]=r7jh$#eypE{o:Nm`l@0݋†p)>zB7gf5!XF,w{T- !.:ʺyaX s¼`"!C cܴ^&,~ F;PY9ei٦>2"1uYeWqF WCq 5~mq^g5J4h}*wd<6w9Š`4gYrg9_6yf_#ނ2ε5^?=!J ѣ1|H/D0 ci7F b N'FwW9+뻕*@MZB"ƃZa<@W1QVJzc!&;ȟO LcNmDE\MuUMKӍ~FgΩ32P=sBiyOnk;^(އ:d r:$tXt=\w4SuOLudBx m}\P2Kr7Yq 6+g{ 7F_孮;")6M$򇪂DrY5,{6g/#St]<W_/=m3PREH Z*g|D34} {9Z?eh/}t]}h6)]/эMPCWOpckeJ̈7sr`reJ/G0fiC 3+(`7Vvuo`KmS7n39B#^:H'"ϼLLw?-մ L{ MwZ*$*K6W-X[6%6w+u ]Z ;-XqSmQ#g.=Ŝ3w֦]kM*FީqVBxQDbmvz- >j ozHN oL2FM>k:swF[A >$˸W][־s2֓䣾CHоJJ<^5QxX}J?HZC" ]#"u=N0!%l?*.͑{;VK”Oyjsqf`bɀ4lnAl}R&O7Cx_sڔ$_gfձ4BkT&@l]c`_)QfjY0/rTo'7~zlٰ˘tچ7"l;evZ'j"> g ,z ndt{7#>DJj5[+ PꦫUM+obN(7)^}%y4 {QNf?$f`jO%b{t{f7Ӯ4!.%bvFg#9A'\Mܼv4χ! ~h:MŜ!i4I_K/$S+ ƥs)CЕfXlMi>)c)J+ş)IJū7}mɶzrZ;ƸRQnP] <l!=7яEcGQ NrFɢJD X9xA~ÄHI*=a: j^4TY h kIyYBJ>{3#Symm^B.vzH@L)?Jˠ߉2嬽8K Zw/% :I:t*(/]-hIDap.3ܞ%-܋@p\^*}bygWco!8 3Q寝<)RCA6i"Eg{%+h|Dd|X#,hA?""Bugrz+}1JqfprcʢZ iwuFF %[!y뱩2RhT ܩ@pދxY_*ňEQwOCUFE`Nы ݰ-ǐIG:e `q;ت`vsWӴ 9낐[Og ϴ4G_r!y#H!4,)");ic3-:>s tU!"`;QlJׄ.g*9-k3e (r$'4"l?no&;{.W3dǻ %N;E(@j$+`y]*W ,$?Cdzr#gn)$iq?z/]q|. W *fC4O#Krę̐U&w2.P5c˲p` ZBɷJ'npU„3/R{%&XC!\*e5z&g.6@SՊkJ'|W/#2' 7`p1bd{慗=jrHb=}oƠO=M VFֶAѥ3s눗V7wgN;6d~Q1E -eh<&?qe`X:=QFy1"=7QlkBC K5J@_6eŨd)[AzP݆̏ڛ!:M1 D F#= ww#e x]F([܌k$%jZ|vwg7l+}D>؊Kp*L^>IrX\gM09zpkͫ;<,#Y;k}= uҷ#V Ad*J,aȩrS@ȶ]`BNiYRڦU9+g$rˢ A D&xPs9Wa. )Vd{]C[_rѸϝaQlZ Qpef"[ڙ>5?yQm?񫋦x(5DG؍=MNO| YSi,hRXhFP%ƙ" .k*x#] k [i4ҷVsR :֍zYGlc9>=S!NOBtGLG\9Clֶd$&ѧ}ka,%ϊ֧BV9q\eku1jBT5tZ#!]e/}50SW;Qs,:P~bz I} d$)g!@÷al]*ΘUHC+(xm7r`T` luޟF F5AO!=u r<3RF2{ɴV%2Qӯ@C]NEe# ☽Vp4I_&SmT@cA%De@'_U3 O)3*Dx*#2Q՜ޣ^lOk ,uv+ֱw0AӶ2ArAS`Jm߹ʁ~*0% d6u7t0s@_=v !iqc#]sˏl^Z ׯwu q-|}ܲ]5E|6J ZEWU\c5|+1tE{f"rėg.h/*uAsoOKUt$K h+51y،\ݽizkG/oE\,@A>^ l _JA0d.V;B¶my$: A-kk`>гNE#©I.X䴭IA%>~gIVfgϹ~xReYfBxk(YVڋ,{zdi{pZ=׼Z3gb΃g,lvL^ztg 뽋m|Mg"vηZoXѱv<>y-0bk4H |гlķ1>[ +Y90z]^nN4JeCg[ٓ~3@;Mre*vHLpL4ͭjx`O9 Vjuw)"6"5T"ԗ%B/bA)Ǹcjbޫ?ES\+H? u,3 nVz@Lwf =X[3AU^(Z\_VwNeG7+G ~(:PT yzJU%rIBTB4="_w5M 6",&X2J 0R$]55M ulEz \&-?tZkBl=d~Ԗze0pH^]';_Elm,]1YP y683#e+:_n 'ʿ:0K)%MrԴw8mz Ƕk.8·w(H>ZًM@;Tu@`M7n*Uێ"u`Q)V:N;?;||1Z] xH9!丱`Fۡ\&%oΏ 7,3f{IM`В#޾|'i[ZD?B"2*اjD`s$WcD 2L;H[8 #2+7In_׽f{*nX*[fڟVs G6%Y֟ "T1Z-,.* p,/z~ |J 1dmsM0L^+Bac WcaVƫ}3%uJi%֒<ؼޛ ۸ɧsPhKP{>“/&5Jh+!U AiHG[FnKNz)fG]vr>vz یmi҅ܕ=0#UuE O$D@A\`$RH)$'?wP8 F ~͟ϗ_tY/k2KJRK5KC ӥ{yƒ-F2AzƔDB_6oQ)s55wJ$F@f'kijܴg |̔*ӬK60]}2TIVr^\M@qWdУzSncO$@gP֝fW\U]28 X6i13LG>G]Z}[?1}\ѝ6\;7Q8u/̵h0pkd'Ia(_K%ʂ`x]Z燵e\r^bw#f=0?1JVz#@C"ą_Q]P{"xc3JBx( ^?"khD̵瀚ɒczVwC±SM}XkcQ <]\-$XH0!8ګc 1ѹ&] fk}o qZoUX v}e'cܕ<CP$-{ }S)]&ÿ:[6:ͥZ*{ j1E&qزRqdw!X[TC3LK@WlrkKiUCMiX DPWTmAMu$ B>8Nud/1 {7,C=9δ@Sџر9$v5M^>@dfk ME ι|{(+#tCpV!^ j FNSRnǶa9q6算 %yKf\GuProĉuV{K'b'b/|~ m'DzxݝKXH (vk;зT0Vra#7ǰ\~u:ݪ]k5'!7*'gaOi{v!wihB oA**ÐGeXף 60U[nz>NW&\K?A>ϡ:P=?Lvh}w٘LGT lKrFC"|3-qY+zBfCk"HjyTI̚ 1xp\f#>ng=Jtx~f''tK # =jWc ,C~Gerˊ<EԌ^2.oHXXpb MTfS= -j-Sp q:/-89n\}[PGTpUEwXw&>fda}ui*BCQ# 5,m2n=^Erpp-(,>76!tP̕6 0P,JfG.Ջ]iyCޚ_(15C8md~БAx/{_XHIoϏ_`7C9U R.VO]W{uYr3(گ˼AdhBa*粤.[Ń޶xBN_sp^9U }`dΚ6Q*OXݲH@h318\#zl=l,/1jfX<'X7a[( jE$iHVe%{@Mw#ɒ"ϣ!z9(lRUzaٗ{BSa\n3dЀvGv9siDW^C2^gϷd>t! hD>0skKEGZC>'bm6rU `x{C9aBŁ 0t7LՄV pNP4v9H u@g'V":0a22 C?d/TSKXBkl`|n>O}I8B7 |BVb s,@O]dRطݤSU~yKb'_ٴ|_IX"!X*p$<71778cZq0Q0- I5j4ܫ0htFZ1f}YĂ {r 90Nxo[coh }t1j;6Ys3S (O -xI!.˓j1Gʑ(P͟;풺 \#0tyIMBu+["8xZh o1dX'Vlǫr 5Z6PZmE.,&. 3165n9L kAAmt,5 L[TqmD4B-&E〉mX Qo; 6Zru"#l^Sy׳wW}Tmp{9ZXIAT2}I8F 5k TDyRVʒ]b8@rXajk8Srb\/V*p zN r7Lj.DZ=>3vsפ;\5Ցw.-\0^Zc2[rFC"6)AC%z4L2e{+K@H.XVХ@%BocWx) 5xB3_٧滔^BGs)N2`i *HR뒤{^܈l/x5b{L;4R@VѬf)7g6QQ r?. -[F-ͯa'G 7ZsO%qa.ж]BxRH}7N⽃bNց{0UB.ņ4Xa{+ ƓЎA2gg>=JV"'2a=n݊9[K.v7q׺e^K("yޝzD]J b" !|*BP #{*Zn|J9. Jf 4A/A[QɞuZ7HbNQNj9$^.C2 6Pu_K~ &Fpi uě/`MJ1im1?coݎ٣.XE4zx_7YŰ3OkZP׵uJO[7!B ۓ+ &Z_4J&rjJ+p{}0 X19Qi]ߏ^SYb*`g~3v8X-' " C`SoOFS'׷>Eؚ檡(nn"ˤpB{0(GO4[.Xf}2KG1N5Iy*nK"V ,Y:QLx}@rp"X`:{03)xE!:BRͫITPY9& FUI h"ǙyXݷ0ɛ@ XXׄ9M!m;K@Ilg!}]I%gZB0 L %h~YOOܡt'?PC=^kt gb( 7WÊV]V\PUYq aq\g`#<\ Ju0C#՚L35GWnu,Q:H65yE)R,&@%{ z̬HsKaH`Y}Kh iDMMFCWR, . ONp֫gdم4|cvwRyhoWϋ(u|rEA2\S\"QGͩ81\ T?lfΉ&td+ CsSvyVLip9Qtt U[Ӕ !A^,d0+~ahqA]>K_"i)k}P@Cs44*Z˓;2[$ZVJqze# k^5ѣfGZkLk}6>c5r( Qx4-B:3܎FoI6a7pθ{!FO´&KN-k{Kƶh.[QI :jsB  粍OvJ-΂ܘם-gHkMry).{h6Vrɱ"in"[EPo>mMɅbnu'BĶ/o)X@:xSU j,T ̼[MII0eR ğE4%RX( Nk u2 :?Alg}~ӥ ws1v/!_umYha65ʃYk䱬@/cr U!8x{od^R~It Oon.-/}g;hQ}rH ȸ;9ʏRD>T\&2u8āhgrx&JTV&i?hbW3CݏE2䅨cp b&BA. \e\C =l'lr(cMog1yyefۻ+SpX16ɯcp^1gQ2_%o|U񩑲*$B1[P@݇2@]j,xe>NaA0|IXфgj=!y+;ԽTέ|5%sRKUŷ͓ݬl\Ζb[O % ICyIdAPvDn+ BKv'a;pUkoaEHO'c0Q>8ПrXXs.]'˸QW6:iEZf`|& D3.NR) vi/R##BܸPL`E<# ,Ee26l$v/]zou I3JHxWo޸K bo1n`ϑ9Pz&MsG) _vb{=RsbH G9v^SMϱ6ٴbF@%h8$EkBc1P"3gz,iءnHfP93U`o =QhIN.Qj=/9OZX풺@]O?IlM,VP~ǘ󟕥@M>*p^#ɽw)'([=ߣz!u1 !d(YϾ+v NW #&|N32hA%#~)TcLCtīVg)۸&?H}P&`8p_-{d?\Qz/a_M.ʝ􃟣>L閞-mԻ`ʎm?8-m.T5֊Ug ʪcARbZ !Ywp9nn!FPTf=CʯbThj=v'Kc7ab2+ {mzÜLױe4>z H!O* /@1;̟gt`]9xGZѪbK:f;cn^h'hRz ȼqlX 8fS>V!cVuQ%_Aw{O kk75{%e2h{獂Y\|Ɏ@(W%j\y "e͈K3|ۉ/Tw&X|5#0'o8a/Hf_2?L._r>tw*=äJYRqUY4hs_q,&ޔWLĈ!ִRtg͛A" 3 \:(2m,v0zi:gcwǺIC=UϪbthA}Iu)tHfdF 6aqrJ'GWٸet`cjl{>]7LqT-jSc~`l`C^ /$^ˈ!ipPpjrGɗGe"fT"3J: 9O\p݀ &}?~€ tL80B]e@(Mˌ0@^ $M:_=hVF&د[K{4rh b z`\)s8b8|96>U'&>ݫ3O9C-k}6hDei𬕐qo`x6}aGyDs "CfXSDi˞pF]3z 71fT\yhH6ΔkD$0qaO#U{D:G9U II̅DH~@EjyDa7'*D|"zS|_]5;VY*[H1_Aӱa+?ɖ%qU+Q/6'T.[EM4!#%;BTrFLq18vCRv-Q"c`dQ K*w)Kf'tp>=Ej4Q$G;y'6gJT)NQ _)̤6,߉^e6&> Va872"/X5o|Daf-.4eNT|=^q8(x2yYt')be!TFIC(K`MDMmT=өyJ#p$tŵ!ʪ(A~e@pC \c~.5:(F`I4tNc)}om?̳GI7F;<ܭj|bv_H4mfvݝoxNH f(=| h Lk+lwrG]g~W GnEcU~ ?$aZIw=rtB<%κa"٢]3nVm⯕q>@QIۡ(t/a!4<}ѻJMۆIzy-9J,+nvO-1/נY猪=O` ?;_PusYC@(Ee"x'`mBB-aO6}*"ZY#$cGp0l{xGոm-]K6[!_G}stB$ 6Ҭt`d!h9LU>iƔlQɶz(ČFO j՛*&5mڈS Ӣ~;ft8(SЩ4G.TWBK祑_&M~BG"ThE7P/CS{f4\CW9iL6.[iGm&[++g2AlN+ySVlr]yJ!)bBA͌jgXlֆ:0p9coy/Y ׅ=X&삫@*o9=tiFE\U!^P "F~5eڷ% Hjn4$I&,l?0{Mp4)gA߈M %vQsO?{UّDJ0T.=@ f{$*ѐ;) QCpV:ˤ]k6̷"!kT4U\GzihAi)śve=g, )S4phUS>HF$$GQQ1z.~b˧T5-AC tN=_|eҢ΂XAzHe-XQ})kȜ[.r> aXB\2=Y|,ӟJWQ`ʐ IzHb^Q9VNsg`W(XGLkxCP'(y|}vAԷ-A9BNYȍ\#\ JZ略cp ֈS3}~`=_Ouݕ]:E]0Cz:;&)YIDܥѳ#:h&imOxuTx,޴{' CD>S5Dbf<!_c=1pv̌Z:+$C[ tԏ,~Y*LJ Db;5~mݧMXb9လ4FNW{_׃z`U#lMO{;w*;6Gw.t:%Jݛp1s4jc_KQQ"Suvcx~T# ȻkqiC e=& Rmv׾~w!+l沙сމ`N(3Zg +[U y{OIr Kk).j3?&,#1ք U8 {d5)8e:(q8 -tETGzfj.PR푡i8}M 4ᕣY"ߣZws/18s;PYE9q-q|U3Y)Sݱ+ wԁ?Adp!M8vc^.R9h}S7-p0H\ \W=3( lybnH8czʢ咋#dL'^,{~ }K d͔mFX~<(ܪJ+yOSTYa0!.Qj,%x3ߎE;{͒#Yyd3b$IPCۼ)+r(_d4G@{s,Y `%p<}XsUDq- ,h8e0 \}309!Xmس4'3*X3)I;;űzXil+%S9 /VR|^Y12Ƕ8A Hʶ;o6|:Q©ߩ9Nro醨 %[06E2]bv'h{6d+p!>?gz_}a IX3q0Ȯiu; w 3Yݺ6L No^'[f$Zs"LW,t̝Ԍd>+E}Ema.~" 9"vbsp(.~@O{D&gC BhnF<"t %+w_!T%!F&uoFa(3"{·Z*;kv28b<*oX"-HlP[%Cjr\(Q1$!H( Ҫ<}ǂmHcD۲e3&ҢiƙP (]G^s ң̥rR>2XMv0 թPgP~ Q=.uO@8رcaUӗY8֡n҈CKs+u_CBbz7EQLnC/C-`J̈́ϟc+CF*`d`Š<bL2p?Bp%MF.xŜޱW `P) .;`6`GvH’keR>U,CsOEebGjbK3PQO<ݫRVYu0!`q3N W>z,͛6nŏ1ڹ .^K_] rAL#U3VdV8@<(.<<}=Ł(N,e<{VZTym'@ /oٲq.!]Bw>!R6PL(~D|XLu?_|Oj?kmNVnit^1Ě J7'3}(?9-=}GY$ L"j y9$ [,sS6$l/liF5xR6KׁWK] J*a!{PrA/NFe4UWυՇ<^/(<-tqoңuX "|1([3&6NAvE-;6\4-sWxiE~5t0`o/?t^}+}OyUOmbƽ^O6f}CG3[ 7jK7}7lʗ}3dsE{pnb,Sbr=9[u>BWnw.Ulj ,JI[m;uO_ QTWfn=_~`/:~kUEzݕDBѼXF t\L<0,W5 (Vٔ 9H0@Vk[;O1OTt:zL)~q_|P,w ܺ5y"EOmԇcņH,Ee,t{N\aq ]7GcD&3긬u뉀Mud(X! D0ƃ|"on=Qx-bWbY=x xG=չHu,<%:9oO\zKӐ#(de jѝ (/r?վ-pfGn !>3B&et$%{4$CD-\m֘6fr: U,k\oITˑՅ™ΕUمw<08waqQv2XCw=:x*ݢOMJ$2_P5&s`\WB2y/MKYKUPU~MnΫ א0 ޾RX}aZƢ af>Q?UzO?z۝L $%u'F2e*0E-F2dY^x' M~[@<|P' a2nN]~6PޱL1 ,DOۏs!\1fy!uܰBG߁PjebdtTx[4,WlS:zߝՖۜ;kW Wd9]L;Wf?wUTsm =LOxf)LN[&{ 6WgvHrr~4[ S-T@Qghͪ4b| Y%fR|b8LqfǗмb5w=Ǎ:4CnEk8 dc- ؝8%$%&KQF#Dڀ>3 'K"MǮ*;'LwV2hnbXŠ`; ܂br|wOO|"]1CV\L닿iSN:xv7 #oײJ 6ݿ4m:o0?{m\^&}0?YKM"yBR9t؊ir9[ez]KiH›obbB > !Am-{E^k2ٺ6 )mNNˤ35,Hm0[O{S$ dy VW׮g֐q&tB.jŲX-ㅕT39)AC'/M1l#.bh, 6ZcR5NYZo?ȃ=~f1MeMQ֐^ס)0usB"pH@ bu@LHZYEjS^ \ Sݸ`pبK 5\ g("#h0ن|pcgyr% /eU!χ!g14 b.ź`G=.X\ѭS>BE%/ ƕ|qZyI 3A[@F \%G+I-ސϿ6i(V늞UDGu׳ٓ՜Gn%JYIWnQb^0vث75xɮv=?_VE{VSp'P>s ]Qo~x-}SŎ)QP&<)-X ARs.77uㅰG ɡQ"pSLޯtBw"+>_~ ޲wVYyDёEjG%L=f=FSO; 鵡42SOь;U+H<,7WJg$tKu=`q20eOr&r$pNUTސ5],~ |y]q=xRMM[4-I//XvJO^ EԳ`,osݤ/ $SEBT(OкnOvǒp/cޙa8}f3 6 -cgXBJ h-~}6^0@q-A*t:P]qDlfrGtwh {f6%0,jCArd?5[w"`YR]@5cA>i r%T/U~F[s*.p" m/~Y l}*AbW1Hm2K}#?#߁DŽ^QSm̻$PÞ,%ЩZ^k Iɣm&X̢hg蚑9,S~ U0 5!Js>EͶ-fy|| UEvCV(sY1_^ӟ!7CGaYhG†Gri ek۔ad!] 2"|nJ[Lf րpI/:tZj^m3ebk./jfxWr*D ֮ ȮSQUu%s*χ=x GQM,,u5*_KKtY#g= %ImppRKaMD-N_l n&Z6vVdN@0 ׆p 1f Oa% &=mN_k+BXǥJsdn{&8/(ʰߜ7v]>} r BP{T%[(/'!BN? )9E&䂷&u) Fs38IKdxQ)ưY&[(.TZVFoBc\kT) 'xZFfQbP0?2l{&03u_#[4 *VW6%ǽ߰w"|%O qQS0Iآ([ d,01BU5g֪2kD</_ .*ӲzLW_3zeF0%@^~ & 8`(D&uX7vM8ԸFSW|/b[db{yɨ>$'~݁@;]vp؊%$qLKlG0˶荛C7ۂ!}6*stF ](Uvj<'I{ԁdpӑi!ʛqJY%x},C}M\z[6 y]q΍G'Z5i(-02\:i{u 8*'UiB/ nfyP z=LceHG%~cɮǠ ps>_8o1 Z!~V8ƚ pe6y:G"%U& Lڽ=Y*Rt%(g"n,H]5Jӱ'8= 5-굡ՙ;N]4Fyma_eC&!y/,\~ޥf7hV8"kn߷[.̭Gv44Lm!9MU2Hۮ/0얃 zY3\vϨI湡2$R?Ylp*tWZuӸޤ׻0x] D —e/Q`l:[?p) Z>s'DaB2R$A`,mqv5\x'|ĘIG"bPB/&jN3[O@; GvYk-@ʊ&^*GIHRGf7iR"6YJ<71b%P4r!)_hs3T H!E!p(<Ιnc|\x?"@m]73 -qZ?wc2-n-oMa_ ^ h$37\Y+90JAv>I xmډQ&:RDG&DoP.sJQnK%*e+(d ->gG΄S | r)ȍ*JPތ}Q[@H #FssMpPߍOdcq[#֎\pEpAս8`)CͶ@-ha!BJAZ}3ΪA /W6sn5%MDP1o+zm^sW dj'$*$e :'![NMɲ1}ѢiN?5VČ: 5C Hi*͗6a^Hef#nZ.Z5s~ -~~Jڂ}@*,pi?L.!R z>h2:LJ< _StxtCJob]4ftE#XPBraYX޻Ҍf䌤z qwo/>=cls.[:})kȨÌnV&uhN HwF#HJ]腉r+6p 5K/?xa = 9>oRc;YÎ 0V0lđwf_,a}eE1j oI:0Ju%Y~+$J.:־iR4o #,~'kNxnW~]I[ϫǷq( UtH3$p!mN^B@T~N`"kE{ `txdJİ qT!xw ݢ~=6%N a<1ygw1PסO%k[r: hԺ=:8+kw_w{ih+z,8uAY IRj/f% 8^_;#n]G4bJh9+ Z PSq0av}4רEgj5?_0I֬%iJb!_Pvoc&DyG^\FMҲ|#CT=&G(XeWzzx,qVT9.$ii^Fkl٣ޑza7%uD֔h*ya,Gjq%ܝ2 'C $8.%Nد7H uc/gWb[3iy8ffC:eomÆ(&X;'=oSeێ7KOmAncS#6zoX2DJ >/: < 9T^9r7#C͹Ю}҄j;>!j\⧲x• BpoVU]Xx6ˉU/ύA(}xwEDGPh8TmS-jMuK2׉=XuN?GW1Ć<:[ߖg<4i<~쬷AJ㉦V1*")WX1chP盟cPt{l̬p1>`C`$ˤ)T IBsǗMa EQ.Sl}X2_UCb";]I=j"X &p3H㡢,VWa!@:醎CRODq`N<iڭ+)uv~K>(!0 #}CA\wNl!*哣$gk?}\vko#ʀ*:fГ/j=Wud k-+out|i^gcQQ?t"lWVr;Ns^W6CvE#llx蜔FLP}}S".DzÆ/LM-@y>*̩`)1\sNĤI< 6FyOJc OI%2b<ԍ50߇k s>NR+N2S6+ yj~ R9wjܪW`Wa ئT=w[2W8m?ʓO o1T7#~=oqfy-Nq9q8À7d!Pg؈KC-'#"G 2|*dzc<DiBdbB3`ܪP@28kذ'Ƥ:TY$W֚y龰OܾN S>+LSW*jK2@]:bO\xg4,CӽQG7ԕCH#*W0hԉ mQ N tU*$]sprm_SNsxD5ɡUؕI.bUfg(Ki?_*N26;gAY>Bb`P>.TЍ QE7Wb 05/O{ť h&HvNb9} tv{ZA0w -ˈ sEuBaE :pJKH(mО+93GXK(~ 9ש9֢K)s%_9e "Ǝ4ۣ*zBɇgnjE^ 27.NCj1t4wG5tcJp!]'l۟6v{Vk Gta-M"G ͑ϯguTi&2!{V<~_iw ێKM\Xg12hhC-.J;MLIqS݆^KҒgr8xj9+F*;\h*|pcT[a_Z}[%D'@n(7l-ohVBZnO[#0a&!A$X< Y" APNLZl>D[qmȿvEm3:5Bl0ؽ{CE=\Vnl2 ݃?̔5ty=~c搼XqӃ!$q>|p=lC5䰪g 4oKV>Jz|YS &Itci1}նZ@$=? /PawK{ݹf{8~6`lCzu2\ڬ-BdS$j+p;bPZcΐ|jJaA%t LZ|܁)MQ2ք퀬iq]x'DCȅ981pؐ?e͊x1/va,^ʝk|o=#m[\oqE;)~>a)O, MQ'Vi4LQTB?dzrw:apIAu6jV78(3CBܻ19y[%^-p vK6-n3ޑʄ9PUa&کáB\MC]M9qDt+J@˄ŽU]w^lw< }{sjO*(Ct#'5y;U6Tڦ<86R;n ǎ:> Ö+jAb^mF[$gqvL :qXĺ~>bWB,= 3uc1,)%56/)uc4}'uړDƾ=q?"LF眾BwUtݗ#'4=d ڬߏJct/CU8f7|M;ޓer>v5skA!Gb~/o*wq9XtWcTu\Nt'P~8DaqUhL ŝn^XwJ bFu7u?(BaH96M! P_x_pyjjs!IR5k. ?ӴUKnekt(iǍΦ Ti@r7MU![D<~@wi2ǒ#[|׼ `` <lނ_~VFbKf4ɻ~,JINTW~ȑ3nKr6jSw P3f $kt,3mwQ;/QxC'8ms3 y)@vH]4g0ݒ6SPtcH LD!uKYs|xW+f݀ʲ!˲ B(|;$*.:Н?OiR9IL&@,M }2`2;-~g|z@P M[6 ңUfZgpÊU`#N>ƶQ>FA[uܾnRR-s,e[ixpkb{+vD-(B7ƪߺY"rbPd k e^Ay\GLZVXP6r i xh'1TSvz3eI>Dhcf5PmoRMc4'SVh3CY?Y+1b=;qMm=Ř|vüg<~:=v!DG2R e:<'1r3!,Ok>qi0w:RR8PeȞyIY)ll ta*&/ÀbR1DM3+|{lW 14-.̒1###qi ._P*#h_=U! ?F'hxA]75ҧ搵~EО#$;"hx;qȚꊳcbE 9YK7cW&Y0bOn~w]c(KlehF rO ]Mv/qaKHvVrޞCe[5} f;Nʘ &Sɋ6U06a8b ƲMP麕.1onR/sQ5Lqbe9+le¥ N9ik+EXE6.yQ-?WNaONIkJ4"/I/JkSK-hr<ݼCl`"4u9 wgRf s|:lFXحuN~ظfq)7y>݇!RN!uV^6K+@-dǐB-q fX%T(4_J o)-e:YOq"YCDcфunxQvXG3Gц9q`C?7 O!v~s'}^/xΓ|jDT R+$e;` 8/${E" |D)ũbvu\ Q/Ӭ_H L8E6(YyҖI\4Ъ[JpZhaG?KFz7H~!~]Xpr`{}a_@0r-SjuK|e^.<+nO9l*b/=۰~?Dڣf1mfdF.^ۦ}KD<[B)_~(BQDTͯM>:냬'T+n\O"Tם>>dN 5 .ϩ{UHWDF ;?!ܫS}"v) s{7̗I9 logJ Dv}zwM˝/ذzϊNs^Y>ZSMHÔz3svyzNl.2cXB{l6t,n~P}~ө5x10 Fj5>B,3Ff +-Ga$e(tѐ+8Al~wyWRBĽ5\MkD/%UŁlOL2B0~ufǽbQ#U:3Bt&R*9Ƅ9%.|DvL8iuTN*}/z+QQ 4e.  1xsU@YaWG5l@9BvO 鮇M1o}a zZH}*BvF% ٕ5p>ƴx -Êo0E*V73V\M6{hS\?_4]Thf5@w1GJIvhNW7δtaΓ b깹jQ\L}$[ :L/ @=a!Vqd[%9 x/VjHU.%~m0-N+ v~Țcu[ ê쭁A"bM5o=ZW<:b/]J6XVAb3cԀJYI@ŮJng*hg/ qwipyR{kO'Z B ׬KE#Ċ}4Aӆ¿3lABW9˘Nّ X߱zh@zW;d?QՑ1 wCQgvtݐ!^`۶J_z8`'|%!gIJuRHtazoE@'fs.ݺgDR ;:Is8$!;w0SCr9SdPX)"XUCcʈk /@3Q#l,+SsڅZP峆s2e4dG"poͬ:5ablL1@_Kđ2́u0ʸR^*t5;fmw2dkCC5rp~$4~Lڧ3(*C97!2nbAt*0whL ":Ѷ}!O twn i12ٛ[|T`Ņɠ#Uh0ZU}bS,9 xe3=]0:ӡve?4AMW͐Nš\c(,P= e#F Ў<cj m]ǃѝsg^@ (ڸig .7.`c8{R0e\c(]cǀnVڈe9@d~Hs7?6\%jzwDۨ\G Bۉ} |d#B= XnS,D7b=<8(3vh3 U5 VsS0"qk%!o ކ 9?"܋ iNTsDB_䧆g#2\< n"0|pz[ôI A ժ0tayRHW>|n_yk׭B/[\c|]g1 9J-~%\ԯ0Z@eC)?XD,Jp_^/cEODVd}}q$f=bqc@3 $E?< Ȑ@V|jyG~|c sog8qSH: ^{*9ihC8ǭR +C5h{CWژe6thZވaubG=ڡ3kuI5ID|nLH>ʈpSǪY&`H) M ?K *c}RjFfHSGHB=v3Ji!(/vkAKRy2XdpN_qE{Jv-#`^)"ƋEGP+U*JQ&jZ31O c+]Pp~_B$o!%٢HZ@SӇk֕,lrmba[L=wjFh@v0/y-F?٧t$E <d,i.t&Hփ6zLJ֏`NP$*eRcnz J$CS7KTΓeyڸUf8X;*&j!)9z8Ol5w(wz~湜L*:vnIL[Zx&{F7=% (+鞼l-M5\ ez_3>0KSH8,sLJVw7}@~٣dR%~_gT(kk1H%ʸCFO*6ҥK[jDv3_weޚG@Zn/&K#B-z$C^S6<%Hk&/Aw؞,$V& @7Y=]?,DԳiu" a稱8E~!evh(kCSe% O@QdC+ W;\ɡCeS*eD9[-c߂"wx@7-ױ~Y+p ]y3q-wX'c{@==JP5=8ԣO­hĩCk!& 3̀p؀bO5U3ɂKR0kFYy7È}apx*弗 e p5oarT]`5(<達%y49baibVS]u₞cG ̑2WCiXDYȌЮt YOI&M46Goq cw#]Ѝ\U[x1!oHWAg ;wЇյ6px a7z7آ)W'Y-p`Kf83?vRN,̄B@G\~x_ݛ/_sȡ8A-w0c=@s:M#(mLJڐ1@*՗ 'CnN]GJV1 Nh%z@5Hdy4Q͹Sܧ.4.qdV7$X* 6}@a#TM8|DS;A{ark7Qa[_YkQ⇁y>aMZhc"Eզ6eQ2OW~Fxnuifky1i e G;8".$VQ{cu`vd*BfP&kQߔJa_.Ur(7k_& BFǔW! iuK֘pVSW|tjH}ۤ$'oRKֳAOҙ[fD%8yeq|[>rMaKӛS6435$g_p~#[B@BJ0&jI@dDDq,F`p9RG<:O7pSʎ<ݵ W3K ckVB+v!պ:pqiG dV$e ~HfL7k-u`pyuw:%9(4}PivmipB?noр.z~ы c(qBHXV]YuE_r$?m*91}>_1~2Pŏ UI vmاW="Y]EYv` c4u= eHÀ뼕1#Fp-B zVӈѶgjd N rX 6DO  ^0+[{?G=/崓PJm8cgm&w2W_POQVQ#"HxlBJn%/ d8|Z= Y5)W$3?s2&ږ3v@ɑ39Z JB쐆$JCp T^T ҂p~Ap*(N 8!=)h#ZA DG9,+v_wC z_8B/N3~ACRW4$;3+`^ҫ{.*hh=H}f~NjEz)09!^T. ۡe6|l~}` <&~TԨэ/>=+FL濩*Ns>R>}Џ[ʯԝ98YeKF4\~n3BnuN71j\ zR(ܶ=9 I(ҡE:΍ViV JZ{`'-S6tFTӅw]g41^ !YF̜h3`9ԧ>LNK(6L>DHLjA&b+dtҧ5 3GQG||`ʉľ-AZUktGȾwDADSpGͯ.TS|yZ/`˷S!="JU8c>fF休%Y8"B{GPǵn[xt%jk4ϸ_̫zjM~c @hiHwlʊ10<N'/cڄ/ L9]f>SźGmh fF0Iq(K^_?ljsz/Dt1)ݢJdh 1Aۚ0`ÌH߭\ߠ^Lf^3;%>izf/ |~~2IXk {y%'rtNf ͷc?XHjn&Ynt *|iڡu`-|VN 1*/sa!F.ZZ6۟yC]v;Qj2&H eUVc Ewjlj*t.+8q!zMeׅO<Sn6դgNԼ=>'3% `JOC59mCodeyf~T~N;r&g-BO3N=:eu.YTJ8+-b҈R+/nٞCșrl>1 exT~,sb_8Iڕ}F0YrG_>AWgp=|xJ`z.ηnx.\# -[fzD8Y8u- 6qy>__E&SSl?eL@~Pэ?W&iq2i=^icz$Rq 9`@ pKD'B!l)6 #::$5dxTĊzFÑs& F]п]lnsV(K~]9Ę~@⍭`mpV~ˡ e:PBT)ۭ4]Q:0+ݼ }P|UdmB8>(s~o a9o[} 7u4Cʀ$0QB9eeX wGq$ l8D;Nбq eGuMSg'rGԂS̟ZW XNfrY˾^.IB bsj{YR'"lq]Nǧ2?KhS=d|lгv1=a47Y?g_tV:|*+/dB<'K_u#wDë'JRߟa!+cy]eOCj/ .Edtmh\sN4_&o7ȅD{+@ve%J*,= mh ~rϨ׏bsY0JB1)>Om<_dZh2ço%t9mQ(E%P/ES hf +҅Tx_Hsv~άѽN&=!'37hk7 -\QW[e'>ў"m3:mo`\"M/x7 7 !D2AoN\ 1۶-ms`"!_i`NݚQxL5+8(j>L;Sd@"g\p˵;Rx 2[iG bz5Ơ;jd&}|͹d0` J9HGi1C%ϚpA S2̜tp4£%9N7o4nkOc5,PDH,]%Q I_ ?N؊e!ڊgGI)A_v8KzfY!\-sDqe373.~mvzLOr91jD*qR#V$U+Me}'q~S&!-G),AbxEʫu.zzr49}F{{˜ r!ǞDޡXCYPzt4t"K|u|BZ t]}[PEɎpw0Z'sہ{!P{5jDK;w/f<"Gs/G% fOra-t6n`?w5=o#D5 IP,dPIУ=o~}; KfqV%0LPe@ ..0Sp!FM5C(4DPƥe< {e(C}82 鎺.>`-L3&^e c$])5 SaP+::l^ 9h Ϯű5^cܖr4NhLdz*i_CFe" m[1y5kk~JL?N)U0oГcp6n՞ <vrW6ܔ˄7"(^FpW|6PH-@yrRPbO Id(4pgԍܻVvAJJek!+ ̟ H;6^lcfo.L~!_ ח9_c8F5o6!M-xԁdXcFqArkX͈N=ZѰʦ>駱 =葢{\AF #rNVEY{9y0bȜĞbϽ?r "Gyl!Qn7 C)-VUg{R5:\M)41DaZ?v sҬoHa5܏4x&9[kE JVjWbϘġxcN u{vε#Xkq< /aTogkF^5$rI.^ЙL/MZ,b Yʎw Z> <'YP{ 79Ǯ>@`k+lc<2ν?"B1w V=caODCս6:_G< jf3q.BeυGQ Z1I>\5%0߮ ӧXjž?zc!-A$jSqjg,}f6Xc{HJ |_ΪTS6t'9/9U[ی`O=&S#A9@8<[ar afbǎ-!:9ebI?,ē  r&ѺΪ-Mⷝ 2Ym369wE'a@GIMzNbl<# 򿆬Jcu\n4<Թ68T"Z>s|m~ u,vR+D RAN}2a/nGa \1*^O|8Z+_46p' Mד%62ٹzݳ3+_F*WG?U薎 Z, 'mİA@@pNl#}[ Iwµ ^p-*{ӖYD,[C8eч٭iڌ]isx&ma2C%V \RE)iÊ΀z9p6X\Ho w2N[M.& -B"e ;G@/;k";+AV,e폑|HWNpW}PC bPib7g϶ŲYJ7 ywF>ܗ'ZkE0@|?/zֱT_E>{ zt2u:UXw`$IV&g8,(keC B*蜕̙E!CQҌ_id?+LjuLclq 2Q7momo,Þ>>j"4iXpq , ^ޅpz@gC?.0nF.o c;|Dtq=@*U6CK8xcE#&3I}2ρ(2@Vga.y.)R9ii!<,TlT@!08 `NAi( 2 Y|ynS$߼t4H+%$s/oB㊔Xڲ^%R(e.DFB^LCv 冯0I$tpBN\ꐵБb(D24̓cX,UPyN6Gbul)kc]Wg_v[AJ5!n)CFWx"oGLEbpu^6+9KyDqPf3u3W5i*JL$+t VR=-~Z%=\/߷Fnmw M!$~5Ԥ)7'Y0ШC= ruFR /rU7޴knd{{i+pq=L]X:׆qb?KbIy"!%c 7 f>,I7ɒ[m) r$n4qDM/Sʠ9ü1ѸжlKQخ&r"|e/YS/0M杪j##;Aj3Mʼ4@T4q1"b7A}VE=WHp2w~SU]z]{LD42[R mc! t-Bl{(> B$Q<=[ed$xt9(`v|z RnK[?+,53;oԑUXvH̽mVm^u;sʈ~NI]`vrjK" uWs:oؓ;v"KlZߑblӈ%FW07͑k~ިFˑ&,p񣂊?-6; YME\#nNYc-fpjWR< .`ÛP%HRhWdf`Lὠ5/&9 z J΄OȌL).N?(8ugc:SQ=\ӱ:rS;sSxn$,o_1+fލEXRU=Ia1Tp+~qpD)tOǼ(+=ER˵ڪ|+kO#pHPګ+Zȏ*JVሟBgA J>=גOka}751RX1n2`ADXʜ B%CK?Wعb̃ϞmVb μeN Pl)808eĨRt*/.=0kS9[p 'f;~ >`}ѐ"yqnz&/B:ytbs-1k: ϵN f J5.TWN_6p~[a_ѬXȾbeT;!%bZ>mZTqj@Zclí)U4S[QHhkg@V :C.X^ XiCl 5 m_a:p1'J}qg=Pd0ڋ3{>V\F5oDFe?§Ӕ+#eҏv#'^1L0FY%w l<wHrq)"zt*/޼?v&*7D#"wP$u1HWˮ]9N Ƶ(T@CY֜/ u0y72ww#j"^R- _EFؼěqac2vDB0F ߓbH%U(njŤlB"Í^i)pH.瓀l^(tn>q?7~XFdfd96Ns O ;ܓ:/P+`|z zc 2%3Ց986NeA[A&zLg/=eZ;1JB!XE/)eIFl,͓'~&A@p(kQ_ LMOX1ҝ;LjOͽ~z$mⱤ@J\2=qkƋD I?}*wG{1) mP H, b}Fzo- b 4|T FƩV&{7Y~fYS73/W O6IYNjf/k̷aC'>(U'bI 9t7/Txq mA4߃#Y;P n]jT2rB};b؀/&/V=(={75%\NKyMH8MtQJ֤N6OVMd%\98wNas=xuird@W5>i?:B!~=zGj@*ap$l@ Lsvn/vvӖ^=xWlڥg"D>,a<REpWEt(^''CKeaSt8^ZGҚfJyS$aFOg:J+c{AlZ=wg'lUd+5x/B3k$MphD6[qbEEſ; Cl֩ʸ3nDGY"Rt_^Zgi(ybQ/` E7]kߧ> W :&C;Zpyv+FUΉyĆ樂9oҒ<ܣ,r#:hѦ{WRbwkUZJďPx'L[ @6#0{Sع䜶E-~ F-+\'gP<ʩ[ouyTTn^=*-ƜtˊIX{Ϫl kh\纂4ZYhZzUEVi;p.#'S»_ro~]`_ɽcRCn3?Um'v^}p*db_@KWu{X@êR^Rge c% %:Qua$qh4w=uyNZʨ*YyhW ?@s ."y }7zfDn,m$W@*dhsIPGZnhj@mڦCXd*z;ihA&QefopF ,V;,Wwf'eʻ?dzH w׃j>h)X+7ag3m,?Vm)$hы|;ZCY~|5ZWEz<%g\ &SPWoWNot+|k#ழۯd?uN3͖#Ay6i{RCp.'U\Ox4[0>wM&6*~:#81q_H}Blm}xCLdnSVI?:Wӥ:|ˬ6ԟ*=q-I^.YmV&%З gfopF3jV_+Mek`x-sh ԃʯ6E'F]KqwHǟ_| a99P?3$Pw,̟4m3ڮQ r4MfPq@G^ESԤ2P5c$gd GŽϴ{҉0BOeIơeͰ[?a-,EhߔH74fHsоk!A)+rdDjۇkڿK/2z띁;?z\@Lӵ߉p|U-[ w K (:`Rhcݗ4NEmO\ܵZSߧlYs lJ;azWgK]biT-+qk$$olM+o# qPy|_liL湵wJ?g̒7W#fs|"{y~^+\;0)BnH~A5yQG̍X(*QpǼ 47W .B?E{),#|44]#DW;dџh<[*|IA,LR-Y<1(ҕr2K)뭳YLˋ>1,ZĆ<ӆQV])xH"&qg%>N1|D4ܤk6=XgPhFk5*WQ?0mz-K.8pc>킥L3uf@D'ۉC"(_~o﹑{2"EDV&+b[38Ivv7d?Gz߭Hj6?2ýS .\L¥lJ=%}?J.m['}J-oݰ=lk(җg B"= i0qO-y֘a>@-yl:fjx ʔ8,%36Oe؁VTaa,8ʜzN0#b4K&%ݪ9~R [ҟIKCx#EX@gLI fN䩨rُ= "CTgoAn{yUpM4P}T̷t^p@v8:W *:G:e(psY/|PmOƕg>e]Gݿ1􁍏p2,$F-#hXj?T_x VԥmƇmfC~@ǯp}H)D='`%>jB{g3/Zv'I՟Q ]..\27sym͹U|#~jSs]— ++2:i!jꛂd۴=Kӑ?/}K}:ס:ț7i'l](x_#~_`z0ÕUfCr1.E.8کc]*LyzxkzOўWM" n!X[ntkȦ?YAeaZ5!%M/H"HrQ"ܺngS:\gMC}?/J|o˔y=@j&{]>Iꬵ:ۭ5.n[G/Մ"TB_5}H5%!ŷR9<"[`@XG Kwt {+l'hIF5 u~ja_(5>+4C^_kg3 woIGu?#GxJ ]=m9/b%Iӕ;W5TJ#]dt~΍0xud5CÙVUKUBpf~r'ew[ Voo^J A=z}XjCNrS ݠ4K͟GǭKv_ Tt=p^huзsHgUVuȶG B{E;QR%^񓖐ODPmƖ@b^ 69 @"P}CoG+O)v`\ SI!7 \yS2Ę1\8H;jlap.JER63<b^!*3ΡfYl7]1[u`*IsΎSAGߠ`w5A1i3.9)XAH,cz3Ûꗗ]2q~#M8$\߽c{ ùO_.tl{VV3㽶m{ʾFGG.bZ-OW<Gm0p2w\-а7 FBk{X (WxTh3.yw͵("Ϊno+!?P3BE^ SZ+yۂ?*',7F-%V|b "`:R@>Uä.J򇞫k*99mix-hipxɪy4S۶̓ҬG8@Rz?Ql{@k5$ $it:Es3 ^e"UGQm#uNaiteoH<(_D$V#[$2!w@<"q[ XYΘm!MW{Rt 1Z:j\ji-ѝ %tMIY=@Ӟטs{0s*zٻk(M`fĈzhS޳[:)Ҷ|Aӌ'50VF3YZߔܦcHߢ#v:)yfgpYɠ-kI% a,=d[#"͜@S(h.i7OygcQ:k"_l;3|0heyf֬aMe !F =W|Nq4(h}4)ٿMxIͪCb,?I^7W4RƎ"lٲѠߕW鐄_}+P̳ʗ4+7\鼛? CԲQ2 ~8/#Tu=:U氢C[ _/zϭH~WQm Nd~ UH#v*uxo Gy&0ҔMѦAeT.HҺg DI-MMA,~M[l(J\+u1.cT|nxW0&0pc]I 6U/ diPjfO .M XfyjvDg[U ̼#sI!DHticDNvTDwȖrD?5CԷuas:fѳ?No:ԡWqmn?ecłvg pK)#!Uy.M|)\S8;4!?ڤdn.wW>𒞟ip\ya:D;Z i=sXIQ=WUdZ_ ;rP rk+!%R`YY=)vΨ`ɠǿiD HOhgSތoSXɿ\}ICo>J^ؽ,L*a5fR) Ô2uRcYp8OO+O=+rtJLED-M?{&ӡ? [RNe83SĠy~/lqX-j]{] p$AN h.R- ~0ui١8}n\& wRyRwԏ̱}]+$vEO^d)5_Q%G9=?^ Кpj@e;6V;}QJۈBMP [PN G۲OJE4aQ}y󝵍v*h gQppIb/ lA }r'@~;O9>sy/WǞP ZՏ 1Nj1ѱivPOpT{4 *3F4B"ivTO6/!WC<@fa.(n M+K"O@WY` -Zp2M -?F?s G fhg(` zwR+פSF2#y8R=|AG'RIIeh+ !\86D@>h:PȋÝV9 ],|7*+HE"u։&iI^\h_kg8;p[ "HgR-5(pgkkQHcK(1};Qt ̅aQO/b6t3w}ֵ2:b}?r7Wjb GR&Rs#nJ+4MA?K0< Yi+H`kF <1rӏ#%69<~1+؁pݖtRM!j,qGy)k!44D5i[Ic:JRCW]uoT r1. 7.wtkNQ&k_2̛!;aa!_7vD!Ѽ '}APmDwAx|x?gYdqbU ! ,B:H?钭p(MyÜJ+~ 8EdHmZZgI-GdNy=xΔŢa mkG^;o}[#q;P\*[ Sf˧:{96 `)=f{NݝZ@XV!Oԓ%N8q^;Z&rmj-q>޿qx-/9rvP͈e:U*uzE_E/6V*w3PVAtS }/J"+H'"yXh+́Xdž*Y4! "T-~\yM kŘr.@&ZJN|_ɔHqcSHe@-@5l -A Y.r??nL]7G@'mB)Rs|)lbH>[=p-)bť%=Ti̩}A9=9饘2.*/`yj@:,:oۍJrY/su#'׷D& mҒno i_[ηtvQȋbI5BY+S_$Zm#ײ˜*UZQ{^t V" Ԧ2f` y:>,Ɉ`puw9ӎJz~`HY$W%MLhs=5$ k%(ܟ_V3F/p9}X,l3 b ~Xwk~CĂ \}$I~4%!LŨ91R8cm[Aa[;z`H+$煡6ܺBj{6u ^xA} 4Ŕܧhe}d,84:٦eŏPՔ=ޓfFJMӘauW v`]p=PXTKeް$ऱr] Gɂ"n.˻ID=U/DhIk ۼUۢ!P!*caˠrƴݨ,mg|xʫJpZ[m_ǵʏ(LMmlRn5C/:e SK@5<  ?,Sf1Ecj4"CZqOb]µJ3#{y<Tn%Xb(DpWeR'p0dL32߿;ݢsz4?{e3q CVI|jAj܁mLҧ;v((=u?'h8=(2PRxDm@{kTmOfO^omPt+>Ѕ=DdoTZbh7i~/Q&4"Nd ʔW=yet қ'7d 7ᡆ\%nou!s@ ܩ呲-od`|'Z-IaPn l%q=Ӱs5'}9j{ Qmer0:*gK \ tfh^%Щ8h[ `tGpb{bjO[o+޴t4h)mՍF[/ $A.uMK$mFA$B/ wӴÒ#O(Ås'+NPW>^_TO:#+KF˞oaU<b6S"͗ϧV轄kvwj] O^(w9(qSٽ yQ~DCF1e-,M3$=:^ : O|66"+5׾nY5O%\TU_ifSj{U*ضYE1>>03#jd͵Osg.֚狦c^Bdao'DH61؀?吴lRTZBcY\c]?3YDJ Hr5 zޟp}NBA ( 'J1]g vB6i/qX[҇3Wi1D&={c<-٢e *!Y2679eqb>et<i+)]z<&Qw_56 ɕ3llIK rlu;Әc&{E%ٽt7_i1u'OUڂ?wʙ.p?98ԓe@k %~܈}c-`9۾+5R]*Iquol`HCJye62$SGoqe x}2G~܂m~ kCo =n¯c{UC , a& 5pOl}Ȼemw<)-qF(%bBu= at&t؀Jz&xZ ai-eŨ\ 7,2B%az"GW)ExScL]3( 5ƀs24t9d8 ,0jwLP ʇzyx75wFY,CG6c'~Θ3$~+E;jPR?YK}n VuǷF6N lЊuXA2R):۸$޽CPzi7Ag2g]ۘ~,@ҡM) Y^fbh#)dĺP`4@WPdߊ2&sdؒ\%1sAWK.zxIzѺqqjZA8\P:'/mK\ ! nղK!-F*O@;RQkGeEdiP'Xx߯<5"J,|?a譵'B{7t c S7R5U|rAbt_cg0`9c)\{H/o"I]tNJoʺSxmbp" q#2Vi^1;qʳ">~'L̹9.Vmb4w~ӷM9""E: ٠4 ,?A#x_D,zt!~GUQ 'e~c xq/ ;䳂{}T*z qFJivH6O!.~xuV(h`^ T9ɝiUŭ{|x_,rgh,|~!hc6&!!|!>rx&9C j>k]km g?ӉM=T(Jfcecs!B A!@fcxB`(?u jӉs_&uad& ş C!_ƚ o`οI!5*U0~uUF.061kKՔW$ީ ay˧kǬ*z~{ ꙡ}w֜>FVЦ~<gM;g@Pܼ>Y F]إbr}_3@Rk;9(Em{l\xp xԹT^{^~Qfo8lE~B!vw+~6[_*׭eF-ZllTyDv΋'ӲK[Z6:@ )L>\ѶK!Yd tUJ*ֺ4 \7&-]>IH+SCɎx= 3 xmY' !Jj2]~ xSA:杧oյRaC3))5Ņ8<^c4 N%0aK gY?iF0 RxRr0mj{ hK1smKة4?UVKm,> j<Jw U3F¯ >\2T"k STNJĢM '#TgaLBxa6}R+e$3sL"܌z#R0ڇgJ hCGrm25ӫf+1ӎ 6l@0;t/o)z=AT3{K xq.~EV<&Rs-# M6Cr-Uz?oMZ3qWK):H`Hi#O]ْ&e#_ z""/J"}NG{Iz(6<ӲBtI n>=Y<&gn 3\ "2;a$:ƪ@ $w=3c; l QҊc w|͑E~ +/5 _q44o{ny!y>3cMejyȮ tr㝢JZEƼnĠf;< eM0?ٳ]ɇFLp;4ڂ7  Z3=b@HFM]yh-*(%:s=;U( 9z\HYdieBN,ح@>mk/)9k_o QC*v<~ DꌞǺJS ˆVyk ;2wo*g]Rsk&) p+#U٣O(+((O[B [|b+mTqg]jbΘPehFȷfaߚd &ɒ̎r"sѐT| %?$fFj3^^{ + j{{ȏ 7:T`1¢(Lhٱ)Yt}#0EXcĘ(3ʎ 3>g-@ I=u q/>42s 'Qh?S\hnLr@=doRWzrlhUmOW#nj vL a"{:'HkOrRGl8w`JKX;m=Tp-qlߴksO i7loU)لfـj7ո>r$"9RaUdVdc:q<oCIדrf!@ͪ:X8pK?Ė0֯ի2ky(ݧpSMQz^9xXӬZQŊMM{!-yQ) Ь\ ѩnw7Y(\pf.w#v_r嚜h3, LNJN8s`1y5bj{u;xsYfWm^Q}W"Q/$dT" ƾ[lӃ60X#,J3[+;]m„LwFxgC(U8_h(Dt?6hs(@YsCLk*Թx_bbL4|Si ֚[gӞdͩ@_RėV2\`猡`'# >!!/.Ozĵ<}Mok "C~sIVKeWXИثsˋ>6{nfM2<_쾐{9}s]`/dq"w] $nϰn 9]mљP4K/ڐ>/Jz;@ vTnGH"cRsÒ "S8߃ʞ,2$C;H:uZFȂ᫭ηk4n .l.tQ > "E}\'HL!P|.%kqW;k56ki ARyv) >Ex!({M" z|N7i8H%BdR%:?߾tYQ!>XgUЋ[[W7ǞSXקi˞ m0{bnC'0*2K(-5G=t3 TD+UB}H }UN 1vS`<DX{!Qb$8g;eX֩gfhg2kl$O.FX݈"4bL`{QA$COj ;^~2`iZl{^@4qh=TEΈ B y9LEjtpk4rO$@CF|l4 U| I~ŷ? )kJ. _s#ʱk8>IT7 &+3œfGos!`ri&aNu">H+ψ$ jn~o(J}MwLM#C2r}Sm L=!6mTy8h:sf 8Cxn\\Uʛ6㏁|)}?X ^a,2c@_h4% +G$vMhߪ7T>FN 7]bFfURbes΋K;N R~(IU(>[IPbK#=. f3>nLT{|.1,=etm;ȗ;XAJQmsŮXɯQ\_:!].C]2/HBZ5_eBi`"ڽ&RX D9K?xQ/vIx1gyZ=l]f- ܥDKAC%[OFrhQgcQɎˆt3*Bs 1B:lJDGvN-S Cɑ Q?Aya\ [1#nSU ӄ,K]\@꭛HD`qJOJSw6N`f.iAT9չP#uR.o<'1 !B 8P/Z@O\&j&A7ϔw]~1Su jxt2y|Y MfGw7+Zqb~3($5f\Um f9~THJML2|LW+W˫T A جX>Xo[|EQmFȂ3hB <@wڗJ "D Ķybivw,,Racimam P=RCGG@[ĶE{/A(5Ip+fer U5hW6*#Ϻgv*8x+Lk f^EW9CP؆=\ Zdʷp=L8tK㦧imh6> 0Xa( !`~&oQ3ץ|rySUyNQ2 [Iޝ!GCDح"&L1'"#־st-Qr|uLaWABǜb_$x&0 =,͊ʼ*+8dR_Qn.ŜRI퓝G#N{_WzOwq&lg&D9*1>#7e+äoPn`S& eJaDdhw8һuh43ɬ>^fK*C(!,q0$ZǮ"# B-)͇1yl\nisEA1ͺ[p-0Ζ-nY$@~5P}rrXWk?l)8M'tLXJMPG,_xճi3U|,yoˇto% Q6=7aty]|dB* ji Y2 -k2SYNzYu.!bv\G߃dAj~׭N~LTOv凋ruJ N>懐\s i"1H13I)/bPz dZctuc&OF P TGE|&/h5Wmwo0`| 8X)r"= #p63y#[ S%l㿒=`zrW|NO`'ED~h OCя|_&!Z=JCo Z>%H5%+d/Eș%.{U9bpM{\.1˞(J j46C+q KXW'A΢w>)->[WBsR[PrQ2Pzr̎DQ!$aP[~ K^A-[d?XRT\/1rl\ J%1(B?1`.ߪ:dbvXD(w6I͉GC3< +[{Xefv*, )]NӊVWDx5GmX,7sS>o/`ϥAW´du.JH5 X›[N ;'GTNZ+= "ɟ)x%Iʻ;^UoÎ,כm&Ap0$eh=M; P.5AvP1 )":exo  u,3%Zc )*PuȜxgklةǯhW0w2q i]Kv+-yԺx@W[l:%A ڜG'YH~@Ί-[h۴̞uQSR`uAɎ1|([*nڜ:~alCS橼3o 5{-NUq me*7T)fQpG_4! P^ſxv!c֜g5I[ .lm0ޞx:ww9&xX:úluWߛW<V8@6=4w'r`,s0O1qցazWԌ{Ū.FtU+ЛL`Sfb!MiC> ŨN iO6 aEm' WԌ M6(m4$^cvB}J'٧+B{L=2d5id!M(_ṰAR Q*WAYqŚLK@%M%B>? ZjUjO~P*ERf(%O.yy6gU`dpXkoF叟M nH>/]7OZT0*so߽j \qY VMY>RWjG޳rO-y$U6ll1J[&uSɍl@_,Z> \]pq;I# *ɮ0֧!z lWڒ 'hA{eI0S35BmJA2K0>?`1ׄrh=E"NnX)yljxzF7>L?7귝L@E[Rz\fl[BfUqV*K9,io몴rTR&z+ U*#ٯoYRSߕYO, w Y#7 q 1//Gn:$$H>(mRLSI{jmM {O" @,^gD.{9-5ڥ%tLƳg~RD?=:|h e )@}(Z]/te vYj+mh -鰿! HS7r) tҝ;=*L%^ PgCq;.:Tp>Q=-Jc*(eyDFHL`S66=8yo*%@<۠n)1]q@x”OiOk(^[ sш\VNTƤ s%0̏7^ ^94_># |"|>ܞZC'^ۓ9. d϶tM-NB/>sxwԵB1]o̬t%$l|)?H2_!_[]z-39/~"efH5ج?$I)0%.W2PXw^'艮V?ªoPJ]u'{7""I=YMp*P yh o{p6{Ia^B:Ʋ9dL,q:l@I#$wdr^ @ qӠHh䶭ͳFg=cФd;0Q +nK6[s3IIXBüNlYBHX!9 40Uds*hiNƠu푻`L1RLD(d AInmQ>(ublQ5OT'k *K 0I>84,崔VB dz?T+ȫ/xG QV? R_xh%'8^8Λ㔮` n'Y0)yBD!,+M3o3'[~}'&4Uu%0LAHy @n*7-̏s͒0T@9%6y.b QinH<>_u>l2BKM ^N2 uS/['6|E1t2AxmՔ}e[H{>09B:PS7A+B!K#$#k!w\RG^=Q-uK0(X eis[S-#{ j*t̫6dREdzzdUE]Y[XO, |!U5z"4zЉӷzӤq}7/Th@c\cX=cׯ5Ôtʙ5_!dU xFHnWyauʬwK+h2oҾƦ RA?W <ssCdu$UTsj\fCa%ҍRJD:m$d(}krɖb kG>^& 5x7(c-~!7?|[e Yckz k\^v&8 :\JjN$y%1#ۉ!r.鎡)~i7z$ ]<&{3}ȆK?d"ZhcvK>NX{#۶ HX{@e 7Wc$Q[CM_'ƪuA&}5Ž]QY8TᎰb8Z) #{݂^݅(32Oj/I udVĐ7A8'MzؾA&,BdwE;*mL7ق͓Dž@ Ӗ5-ԋÞ,R|dهUaQ{6d@=H_Hqs`[IoC.vEz/x_J4%)I" z^̱;~%"f4SoG 4GQF7V-Ѥfؙ9W3=»2ۥ/?jnhmּZf67/&lZu)A鄑3b<$Y]D+[KFگ&IoMnyZȴ1J@NӜa.s"9 -.Swԏrnt?Ч3L3l 0[dj@TpJ;;N+K!ֹI~&B-Ahcz[2rN&XCVt")aoﯬ2%~ [G@CuJD =*GWRijHh,L/gJ<OsxJ(+#1h^YիTboIbX8Jx.+~33 Uzcl Ncr3g/ ʵ/>i^UFoKV\->Ma64NB0TV.HE,w>tqhĂ~[cjt/ϔ%]Zc8 _:c >ڧ^J:zwY/IzHrV(mlOރ˯JL1 σV| ;1FBWb` 7^KkBWFiWpѸvD@VOS-"9~7v[v yB06tZ̃ iwZ'| U# )سEs#iKC&kʗd&oJ3zz%&4CN=$p,$ JQ:uE-KuIG2&'ZYf%ؽRԡ7[n$T[ t|ֺeP[6A}]~6qHoOYS#@lMk'|{Mׂx>)[kEVs/d\frCls:qt]fMXF^c|oZQo*ݭ@T!a2Y{S gxk߆%L@wJ"r.s=rc*'cxqJsPԏew xχe =N݌&4(3g&,c=&oqJOnHOXEC+(LFtww~/rH4 m@?0~@ ÔjR4{Q'dpNH:]=>tRLkbl65um\AK7Qgm1e~u>VV+ލ}d)nNRKHkv%c=zhsЭ Ko=nH5(|%u\;UQN%qe:GP QDĒ >t#xn 4YQoQCX/o1j po7ɉI Qg6sc{oވ-[lZKq.eҩpoثM<čd@dMN?ȑ0)e ;tFVDjKEe&l">QJWU:}N䣖wuP|&W= ahOc{j!Tt6GLL`2 +=ӍܚPzv-4hK&3~It/6-iR~FoP;^vbMլlr"bq [;f,kə~9%:\Rj<;$zI*o==|)pӛi8 lF"ÅEfwޣԯEwG#r9gTD} {rdmmQeE6Iol7E25ovH1 @]!QJD*d8\3}&lđ,CP7v.%o҂U5xÚNrthtvXaemY G.$hl1]`5)I2S:/5=ˠN o*m;4]YA^=n#fNN/ C&a0ޢȀ"bLn!A6ȹn`0єFU =opM^QK]ou@Q(3 @U-z%P] nNlhJZī."vx\X/4Jl-UԲLS~k:DaH΍iW?@]j JS9IHeT&Asm+ |L):(D\$m zȐbg]uʠ2`= ve lm"&n*WXHRՐr!LJR֜Y+l)HG@H obTLo`ɉi,'jšq*R7QqGT85_$v)Dd3sbn;6ytc.עQ"@Y9YAw8k0ncõE{ J?A5>\ Uy$JqfR'@q!Rl6B^bc@ f`;:./ܥBxY#DofjfANЇs-'heͥRuT5l HvIfQ:i׭T1ׅԄH#!2* N`ط(fm̈rDOfYdICo޻ fdd z0|Rί֡BGixV6cpd*-/5`))i)@l-򰆏wJw( JԒG;KA=gmsr40?~hU%$,Tyyk3*},V^Ab"njAc;0^fK}$j#de/ŏh@+nMz͌bKm|IߍIﱅE@Pr}wC}~>hZlHqv MkuP)0pc#H 9+h^͛qӠ#kɳ[F$# ve)Qз~_ݥ2# .bP`GU4 ?ZH2)Wc?qTIqc߾i~룻@`kEvfHz܊înuJK_KH ʩڸgOp2d㔘yVLmI2ܭ46qq5Fv%8Yhx{,Y%܁o(\ \&w1giUrTw<F;:=Fw_;S9If[ReZ9s%o'|PmO zhcjAᜆ,SuwJVu咍=lJ%y7l= ܠ)}GKomAj~H5hn 3RK(郧BS X_vH;ٵB@8^=$OZxTFb@e)y\RMv( /2+r|cԛ➶,UuMxw|1}fW`*$b5x _눟/@`&8;T}47o]Om&=WS+:IPǖd4L4E 3{b0w0w/c3aA^[UWh*N\Y^i$g[T.:0SP88 ?kmT, cruxIWFcssG5{Qm $c  \*4t7VֈZc/Hp~mQ|MGvXC5E DhouK Ι)1q7#D_ig7}f0x*`Ouldߡd{Z~#*;~x _]Kz7x4}ibB޳5Π}{o=+ <ʨQDU E`Q3!1tTnv8na%.U\F "˻Hzc時`xͲElb]x+4s~o66ّ(݁YX'iIVt*զ#M6 a2bIłP{ld|D _5QWCUT2\Tf3EC]lق72NDtYHO=(g>=59SHvPajNS#o0j8Mծ1x|  &AI ߊ糊B7{,0tkD`J<%Ta٨ǹ4 DGX-,a[E1|E5cU(!¸dm@^{Cن@n ` Bw[%whpQ߬Xps[!,9rlǏ~|{ɪJg$ڞyWYp'sRQXqy7G8":}?z2N+tS|nƌms3I Sf6sS-2YG];9csSY[}*1MxNfQ` CZ،SEM'[Ȝ?Kuߴ<6*COmb4UwSHEE_eN] u -\Y9SrVGQKfLUZ])%)2~" \֡iCz'f:L)C{qpe PVO4265t\Ԁ[6ΫΘQ#G7ssfPb _IN\φ+=Kԅ{+'3F'؍>a?ӦaiW 20nlRU<=U}xL)E W< V(zkA:0D1IK̄/Ei!@I.wӻrZ\:isAI> 8IscZŦbqp㆚kH;s Na-b/ݨ&\D29e.' 6p X(hTیqrڦYb1JتD @fhd,.@Q5,t]}grULq_]U+akhQ;r,bԤ+HKN ýpruM F1*td.2ɽKNÎL sʌ5718 <:*U[w u2 bYMJ bM ~9^m&vʛ掳!#ewKYR 0r֪ݺXz0$%HwoC_[0ŸvTd&TKY/Eys+k-;Ԯ⊾'{)ߵֵE"Z>ߴ.hbl'X}hL~GITs5ĚdÏS݄EbgWIGp<i^:Hp~?\zẁjOVҢ/k羪&7 ,vy{CEol/L+ D7ZHdMA?|[:C9~'vVnӹ^I/QH]N:sE/T&x/*sVH6EMRO^ Ővn@fm\A׆ \(ٍ_L zρzІIN-y4>-*Ռ1҉o&(ewg|^JJ ;+ y{lǶgǍ <G d{AJ<j(j1ʐ-Q4MNF%K{.X|ub@F4/zn^r EI(U'$SaLUh+=m0 1Cc"- Lx+3:3 p._3p"J~ қ z[dAɁdfWdMڥ}x8*sB >Du"ί=PGyʷhA`j{iHoQ'\͇{xZzݿ9Sj^hG?Dfvs 1V\lt|/}Ҧ^<ͬ"x\|eob@,Sv26hNsr]U%w|kB@g'h1\|sG4!@a1f$ӕQKh ~ӖS9@Lvʅ9_BdNVچ5~@D{V!p!QbVkGm?!v]`L231cot58UЗ1&W^UjSO3]Aa}6oZK>I~8n1jY㊦]QuTGڅgJIS2P]AUMYP|N cn=?MyD }AA6P}XLJ`;{_<>c+7ٮU\ בInd/~@LH]~v&MT<BOKK#̋o!8Ωx~ȇy)B~#ok@q1˥$jۨ`KAIx%hRQPICmBek;ue]3[c`Cț6SSLECAqy*^^Mp(F"{Sx: x;ZxT9PlS1FIKV@kWJmH`ȍpSKB} tlQe d٪^3g 9l11ne??WQ&^HÃ:OpnQvntmXtlq6Bhi ²ՠJ/ai&~~Q؏+B Kر B.ZSUr)s$#0~/Ƚ:|߻tKjÙ$⹄$(DmWҤlrJڔg-Cd+ Z:Rb\b [il,'X`{:Zpφm9eoQ[[6pRa=]7 4j34ZUM$Ēᆰ[Ȧ>@wΧpP) +0>;2 ט*݄ (y1qJt{|k{qaםORڤ AHRŀ ߦՁ6bIƄsΦ8j?lN$"vrowYs[ Sm~MbcR=UN@Uύ>\s'9Uz8{L_Q6)ӱ0=p8fT4~m8DܓZ'1v{bk\1)C{DIdl{$I%YS hj8Sj> TF{sfqriҒ43D~631a[ߢi{h0^kژҀ/GuqQ޿EC#p;\j괞r%!Y-1:vN5Cu'_Ayg诿q3i2cbE3k';`<|( QAi NAbb#Q&R{*" (28R!|)tEvtgNE*)[׭w.@Plsa2g=x{==" ]Vpt1x,Wsa-›QZBN7A1v.[3m-) kمHS$ 堚.44,s #gg(O(1Y= p&lO&Z&(NxG> KDM9asi2"pKWaJ^ұp yflXď&-w4 T!ɮo*i+,${ hWW `lKeJ8O3A'mWnt v;4q Tz0 #-%3L(+u/p.9<@@w!nEC}'H.^ w{:.ړ(&鎘/rO,FT|~^ØWn9@2ڼ,gqdMx!$^@ {5_BR>fr߆BQy]" yd`.Id1 $4%*nVD+2k=/kd.xHBAi#G0{\N d%绳8c.Mhvf\NH bT+Z "lӇU~761ݣ5@  ?lm t<-f~y5#YBc60d,d uj/-$)0 `]ƯDΚla"uf1/MqHL iBO~; !WP2"@ʺ+2"z=xl]WʒS#Vn>|lB3`TΨ9:=@pΊB\)CLqK bw\?&D},7ZnO%3,);sc2@|T:wHuvrP<5UFKH]`P+{OWd>5;C$ϧ5q_C*=u/0iݸfO K&͏˔7@_d+#J`f?fs(crm B]m?XOc Ս&/1I[59 _}8zj;ci P!R)(զYΊby8%|jh ̆#o~$P^4 X:^FѸpwp./!!QfZʨU0RC:}/#w^&uΒؒȗ)ݐaCHZؕX-"+{w(_la.Y {A#9Ǎ| Lt獣 +{&wͥ/S?YqHͪuY4hM;AaFN<+(X/fn7rô6~"% \C|Pqz)w8kesPW\8ûnjmk+ۆB[ Q_y |q}>Y_%5 d a/. *~ꇏD=,ݔ\+mb:Щ66^"u"q>0dph}rk`nPf[kN#h>P[[.Qd9 ^Rfwh`X> nqdHgЭf-r.nb݂'Dw?d=/]qKƜ%LֆʽA}dF7"aMg@L ho1ZCq+tQpZ!s+{tQ9D"wctgړeDIȽcns v`w_ *帙̌|kV'2trmc_p1FW6SY (41TEMԠ.?*>m@)>Z3MD]]ip > -_2Μ>Mo%7. -J L3-ޑf~Vl+.phZYzZXf^'̜p![gnD5Q,dO1b&uA!hK{=y "%R%Xُ򓯙u҅bӦN0v 5jx\Lsrn B&߄Yf*W"Kx+22$ONC5}%tu% 75HΉf* ɲS+F$`"cufVb éj q|֟M #Y][ mBR狃cwL4,l|Bu3_vT|6̠Qݩ?!쩡Y&<^](5rkTdd̢~r(Lϐ$oot:KቓҹЕXfC'#+R֎٢fÉvh2nM;4[zDѶ=iE<p\ qQf^\Χl^6) ~Q(Q LU7PW2B9ƀA cX"-zڭ2 [нZ_]"=xut ,`ZXVYQH kfP6X6 [$|s0Xye]H0] ॅ<2buƹ }9mX ~/*Ӽ[}qj88Oه0[xL١ o4,ۊT gLJ m^tTpH.HY0ţuC>MGxy̏]Tglf+|[4`b&|Vۅ̜ۓRwBm\,xODK:$1iOIL#"Vo?CQ뵭?>\($μnOñ~Vb \(|׵|rJg`w-}VZ  ȭc:wM,'E)`}5P?1&$zT ^~bHw"86_|&S=1d8FPkoN~Gnq!jsEȸ< q Wη:@2)n1o:e d2X,'@}/V;)bGzߝ;96B~lR qKhwXvpXb#ϯ!+FG(phdnt'xUr#:2-;İqnnrjuh#)3 _99UQziP30*Bbd^Sb)7ahRGO, W|7 ߕroG=a1]|Z(tc`&ď)xD}`mܰ?mNȣqO吖V 5v?/(~Q{J+)(@673o.3*渚{ ih@v w3>#>WX=pYr|>.d`H"iۿi aqӣ%hKĊ2_m4Ly9/L d6ch?Ƌs'Jу6N=8Im4bJ$f gH ~p..K- B (:LL\g6Vy7v$Kbr}vH-d%US-KXLG§OQƄ#&C|ܬ4#sbGX,Xs/njhVvBFw蕦ry$bO%9qZӲYk4:qO l{"t֊hs/ #D0Z2Iaop&yM%)w#o[J:D4\wBu-4W.]`$B3jnon,؍5Q8wz]̀YO\2kpP'ɝ푧]e i5^ρW8eG'x .x7ź?Hhֱ/0g7v{`-.Do35TqSeEgS _ԁLKO#$]1tg W2H&ړְvBZQ{)o<_!`C\-u1I)l>1zl{;8Y4/dyƣzXRpcԤ=UL{wen2)l43Dš\{_4hcP¬`bNjo̸V XdN5NiV.|QBf;X+.?o< 6VOQ<.Y'E+]#+V(_/&avQ!zgO|7eه+XHu0JŨ2  ֙NnJFmGL!e#k?măZcܒQ]ٗT_3 y:é5,h{O(MTëzVĵb=kKB1VR8O! xZm7vnYA$ h[ŐP >T羔9M:-b%IfkĬKgK$,=&Ei_lmH z;Z>RE<>䄔ܺM" #j/kp u<4jhXs9l{ JW~pZ9E!™+1Qۣ@ ]kĜ,{oq1Ys8Zd_7AܫF=ң癤o2-zc  9Q53Qۻd ^H'\y>R%Ή*70qeWk~Z[ʎ])O<0K:LΞI}jZiYi: 1TFCc O}]P>S.?x=ϏbUw)N>U3$@fJֺD&꟯%">> $18»G]x $Wma&eho.R 4Dߏayg("ov͘p7Yѝy6cz,_'Q UKB:u 3v) z" 5uoA0%_ wIL,M>7W/Ju0X裚yYڤ9GgNbj޴[{!j}ΝNGL ӝ]ܟJ\_3_&5凫WM;RВsHUKSM&3+z>`qbwpք[J #ޡnCOSi%̀B2 x=T2uy4:xg7?fa E+jE Tv2۫8zyY<aug2 I͉Cn&bH<;G F"HFB}*%\=oscű@UiKC{ϕPn6L>:eumDalOK)'%㊮/G:L:D}}w<!QB҇9@NO,@H`m+8ѝў2BT=namSکYP*j!ᑆ=T{ɟw-TJi3ozi%$*@HYQ - PU~8^OU!1G.ud*7Qk[*xZ9Ec_aXeW!5 qg=@֣R֐!乛HC;%/,.VNK`GA5uVe?کu81ѩFߝG2t>JE&~/{[eX#.ZuJRg&x2+-KС!{x]܋_ѹu F_- T^ޯErc~am~)O޺@!8T%li&M7|2t3u*A<4Drn2!P'~ ^&/:&%MQrM*H ggwg<]| z%*4,_ҽZـ1ZVs< vϸ֡B5nX=>b!I$u"\Bd?6G {g aHC)XJvAP[dk)9`'KR0=Y;z$ ~ F9$偺uybpIYE;As?1|.q 37~q)#*0ln~ps(B06_%$D'7r"pUpl; 3\b$,i(Yqh D,a[c_$bN4*[W )q|av,t;䗈@zf|bL|z)#tT62!+nL\ԪԟGBe108}A=o'PO_+s:1\u'y{2T  sLLPPVƔ<7G"ze _ 8H"V{2a,\otgH pO -읠)Nʲ'3i'#ЀIʈ0">v)KM7P:V/)V( }<5g Hc}A2ދ[P5N!`Mk&;`˃mv@{%r,A_dU,*VЊJf3*0xy7yjl;bLAg=efKAc}N:ѪeuĢ|Ih GjyEA} Z'ҽJJ-(;ٸGCsU9(Ųy3z\C>`:" E'd%nn_`l L,h\҇UQU'ɟ\TfMxGl,JH5C}y5;a|*vpb`$B u8y35̓;,D*ۋgoz~EhcW?Ɵ`ob9$#Ei'`t 1 Sh0#R$%.z4a\C;-0)Lrɇ 1 7jFM4G( d uZisoxCM p3ܙvW(HP!XS}@Z jwO3%$ZOkVg}ibf&q2Ը/-QW_Vz$AZ+pGRv,_n0fKJ#Ys˭?gCF `d0*V6(U.HUcA/X :M?w?ݏA] 5o3\&A'z`cƴ֣ [JOǎc"B([+beY;fյ(ssy"偒c# -8ő^%)X\m^.9HWR$Yz̛g(~{Z9֚X([|x&|78sM4FYա^t ( K;+9e/l+n6D}Z{lh:ȉ~TY%^ *Z]~a!1D*At7^) Jtp5GmpVZ]hPƴ_ST8eZ${BRz^ul O & a>x_N.4df?q8fLPշ~̷2"s pHY *'77:,qa-!/-GiVzȄOØ;>K-v y(XVHʦ&Vq_Jsۏ`z-'Y1 \@4wm^(LWd~`%aN1JIWh<3k%Gih~yJ0wsOi#dQDέрx&p=!xg02?T97(Ng" d| vIЇd-䦂;IxvHa5!4g)f6JI΍:hAy6 XfE+ŶG* ^\Hfz?D[m6B>ʡ)w^Ũ0ȣ(N y C]mԫj*NOӋ^4cxf7ѽV[kO8y>E N]gUǸ,X7fVtJ *diW̧&fm}8≧mxâ݆%C@'x^7VW@WwZ}y=$`nLxT(û^:޽ Fk7lHμvC(7rɘ8V[QQAɼD掗D.KOe.#wn >+MHQPb] 9M,X!aQ5P04y@7jl!ѮpaɵGJ!CnL0%D/lBز=qiqZeٛe20;: }~z#%kõEϴW3*V5 j_T߾`dp6N-cϹTG/fwY|ױ&3\yO׏V+l>+GVnm|b8B I^7D8d+3ɘ, ^ط&p,u96:R*`]exCH#<:eڴR~j;ݨ[@[alɃfOpF W'Pn*Fʨ'޶F)ШY1 YGs{H-`sʹ_E"A(i#%L* +@IE{cO$hzvVZNyXWY%޸ -W$FV6QFErw:_{u=)+֩_s"=I9IU<~^Z+ֳCxTB`3B}oPJ :4*BhC3hR 4w\/RgPOLGƤl7pAsX~_([Is, t'3r\Ie<2#-ThNX![ts~5r/l{ ɡ45q(AT9JhQgft[QxtPa|b /ukBiΤ@WF<[AnMΑGk3HmzwF_̯td}#Ⱦ0Pjh# 8vC£cgً,WG>$-\O(1i&V{yLO/Ӥn=ў}":_#a"yxx&&zPNٛՋ\8ZAOdk?T\R.W-+tLc2C+{R7k]I~>Fo)|+i /3X,&I=-VÔӑ#Ҽv?S lhkId_`";_m&}ї;tGrtgvܼcKG}a|Qs[:~VO𖥭4e=UO|ګ%;VtH C@t$@RB4uԨTyuޤ('s}a". ^0n|66Om918̆ޠ&? WA(i)n`tŜLSFG]DŞIW:2)*ؔޟ kO@jF!eǚ %*EO'$d_HڒN[d%xmIu34*D 0Ҙŝ6(K^i{k<]!H1N`ۈ®yRJ` ً`Sw2ڞ=m}LM$-,JlZ!ש𿜴 Eq" đ"7AJ/Y3dvmtⓏøq!gc.mԥ Iߕj]穵~nm0g\h-Ը.癐HF+&"#ӌ)PNQ_pcWl%h뱣e\SvF]t9젦F1jYf,lŦϋJ̀8-1 9]Q\[e&Hđ F0Q8L8j"8[Ł7Ӥ)^-K" [ *k\[F9J?Jت~w-l}s#%:\b`!Z^fa#狼^^Bٸ.gnqpŸnnKHhR\i[$!TY߶?̍!CAĮp> [!3-C/q}+I bfs֍*&0 3"wl7e/*?3&;,DV[nVV25V[?ކ ankk gUyM:oP#<#6P2C`WY#Qb 5t33~UI&tp-lLEck%>동OUw%Hݤ>naD`=,^UF oLK lNg!kw:b1\E{eJcYv\֝5ѓwζ/(J\Śd0M_TXٴ̡N+!V/ -YpH@^IgSƹ`rodnLX,j5)67 fr[e;OiOl`wK B;H oz@_OHqwx~3 W pql% >Zm-hg"D{jۭӸ8ARt͐[T+p_)\h-?3"?\ɫ6Y]v@F,p5y"}M(gu'z\ J)6bwK3^.T7"{!ܭ;mYM[(=UOBE`U2&!9iKHqŀsVU_;UE%kb `b! |އ{2Z Oq1;;~ԶGJK e"żV0)S@pϧVfM4at$-*bW6U\xw(VHӽ1c4-% f{Nԅ}r\rQORxe 8^u*p)q)5-rLC.{mN*[ ӟ1%Rh\ L'RRBq3=$vtbS"jB]G GK~XI*;턓wA Fѝݙ-l=zLuwӡs]tXjLE3wPPrK tD\Wzhp&:JU.w}ƮJPjۍSIsrcCMxt<Es%bm֮}`δqFbyy,({V"*sVC}羍;|)pݍM6u鮴Q5G+B]?gK!)jv{ F( En%/0Kol` %;yLq2(ޫDu_q(i he{sc@! <;H7DJM@N%kci@*2Z@䐓 m^llf]a'<<6k3qٞpZLSe㐖Lb&Jޘ+_^q<'ْPfM8TuX230]hm̾Nbv t~$HVX@$П-bqn[`N[Щ5*GYQK~x{)2PݫM2p#6̔#$&=*gpuu(C64 j-4k8cG݊Ȣ <5B9u6r#xfLÏ%*E0vS :A]r^m $ <)y'J= zA*jW(RY9R9eHhpO ,]ypnsLu P&yB $a^AAf">l~=2 NItD8z{xƒWeI[(1 :dRtӯ P)-t 㰣n[}I1RqINR|Sx":؅}t@}bƛŴxqArx^d fE E/?ɚcBjo0|iJa2%HAL67*\-6Xc{PݽOm`ps簟K /cOq93 ̇;DW0+2%'#y'C8/#}w^1p;n}njg}/  czD&~Oܿ܊-Eĺ#랩o& lqaj9XaP!&RN`QA4,3tPP,Ȧ%hQZ)EWN%Ϣ4қ&/uIc QٖqQH$i :]}!udWmq~̄hR=dۨOhW/i[NbB<ܙps/+=zbABn0IH.kVULg@\IP^B'um"^<+ =}(+G!Vo NAp9=Hk " AvUөN,kMΨ1A}sEjeto`-]/Hv-XkW|_ƒX=wEGoeesY׽.!n, Q?O LFCSznnp>?UǪX#]WmV{d'5ܝ*Zkv@' 'mC ov8׿v>*%&s8en7:'1(']<6ROȔ=O W Wus-+XO^v@,Õym`\ 2zW"8 !^?aC8dF" Y`%uyc[Z rBrサKjR&L:ȥ3N`LeS܁Uе3Pg0ZvFPVm*Ld`礹qlJ-_ɴLW4y254,,6-ybd[!WMpRGK,jg/GKpGg=*5WS}o:BT0cSJiaXiީ[8\{bTFM\UDYq5> T S0FESjS_w k4ҧ0`iiRVL6[L<&`,7 C&:|:wmWx *4 XP^M P=EE%P+LB)!zc+U /AH4e>xBuG'=mzB;k}޸[2X+Q+vpI`w|GiBT0}[etalAԉ*Ovy]`re4A>Q햋b!隸R x1 zq}khXN4*04MȅZY씖`>W@EiQU8?WcMWhsp=C}ׯ7%rbķ4?ʜm齝׍,d!YgQ`Ihtvdܿ.FZYK4Mo"UC)b0/R` 4ғFN@=Q1,WAťs'^9L#QwMȏi΢" ?9>L"T;tԉ}cQz!^)(d"&_cuρFa}q+F/AE U8nӳiZӴ֝F© zc]O,RxZ.PԮ[ dMZ9 [<ه,vOZX'TBo#XPNךUPDW 'ASq8޺&VȣKv&085'Gih s3EnhepA<*\pXUqn{ߢG-~Ȑx[O\uӮ z^D&wdP$P63]}$Q_ a¤N ok%L=nM4xйCՊS1]3JB@gj[6ܺ̽k. Q7S8g(.U+9`N.V-~nY-Yxp}= ǥZ{^!2#vkF"7L&K9]n^lhц,SdBwmGGi60kn&lKF:Iu|$Ve. /n޵I Z"L7GcVÖ {Aن%yy3Q*hVa @}.AqjYoo5$f`,1칍0g2SByÍ\`\+O3c:<(ta+~aW)q]6HzQC*ik eUQ|]0庶H͚Mt*iҏAB0^3b 6x4y]-u愭]mו=撚+|[ڼa?UhW=+@H"=.ɘfKoz݁hu2c˅L8/w1ר]95b󉲞m8VA+#ԑ-vPc@y-]KlIbevlcU-GC@ ?AH9U]!4 E2ݟ/" Cw_47`.qT^x4 Fϟ.{'q+ѣl(Ξcw ȧ%Ԣ3"=WwX2uhw`n՘9D]=} cRsK'L7h1`VkV6hPA'Mbe51\>^PXHy_HO-S7 pkō<ʘZ~ͦz=ã2͠Tx2q_#tpۄPw5ܵ2j!}ʇxyln^M{ .#8# |B}K'a/ sV%::I_\ʰ* ajIy˨$^ɠک$;@]#T/3:UCA~;4#iL6Oo}3c?vX_Cƨ>p=ORSc2=T1qB$ t{{0c7^ a=qWXQ:W@cAOudgG+ ٠jĝ-_8&dU\53%ai4:Oۉøғt߹CP b~L;0Ad֫Yv =𼥋Lr1)Et!8,#QZ݊m ~t s;X'"d)bTc%Z$Nhlu|od W#`9sR:QtIQIV:msN`144|tцb ='t sP'{3lo m%Y8XS"ۊ>jTUO`8S'1Uk.{WKd%{#we+.JdQ_qp:("szmszn+51LSpkD"jR/>n!ȺQyys:r<PemeXh7Ǜbxq\恒!aI+ܒ)\J(i sy2c?l&"b"*iPsl@r@ۺ4_)7T$Bc:PS lF yI!ŀa ^GTG(MeG77޻n#S2MKB٤Yoό6 (sZ6էO{$'pER屲?韢JYhqp"pc= = }P캘f}ʚP[⯏݃٬5Aug{C]v^]A*n@觃 >ÐNYgdܖ:_V=qE^*ji X(=:.j9 JNw ف©ROk0Eg bxb0x KFlQ2cHş&ic,G^Ӵj : ^ASI]s$hKlǯ>_RUi ; u Z7So#p1k:IQƥSv?FK`8~dt}#u=](}܄yQT~.5 3t̘z/'-">֬ǷO2hN*{dd JUBHOs>ORl|rv֜W c.I~Glw?1Uߏh@~Nw= &oʘ* w)ǂu&sr[9T N>/1iS2/s0Z[imlhe4]_һD鵭 x묲5?T;V 7>^5֨k C9¬(C i; N}#ݛ*B|۾jM]Ou",WmT1sqe@RaT5s/>x'x/D*)5ta 3>G..U!ݪ4ճ.^3@yovڏ[ `ss=E<Mc1spM\,ǗfŠ;J;"{*O!?ΐB8D:6idinH 5ŢVY5WQAlд:2C׻k P[a|m:+"j'T!o'%_$-asjҫ5+VIh7$N~Gw뒔(}F6Q걅,"[RZ2 ;@ִu6±AՌs˸zIQWDse ,/8*K/4׀&O =z{R(p̞!!.C݊lEOv[?nƅBXt_1ࡑ ON^£- <$Al{ rxbUo0df4iгV:E4y_'e_ Kƺ Ǧp`OZw.4-A)}߷-b3nLī_٭xBI ŦA p KuܹW55F4 74 vr8z]>:ŕG>lvV0q +L"L~J][l2*i$k/ŧp$čŎuQ N(e@$8xtYd? ٶ]ܽWEPtF/MV1S2AGYzlCzlmm6XȐZMᢨ6h+Ɔ%4zTa:RrM*F3S3!Q|aN]x` b8;iKFCr;+ū/\EQrc%tF;酫ɂ( 998m1+<P-Dقi*]ReB_g7 af!?|ޏgVsQ>ՕfޟɆygwtZ,%qh {,Wu\P[V8it惺=v1JԞsob-._n]o,4ߡl/]V $ua0^/Y5·i)%/ZwLI#)؝\X= )$H$Qvj)PKN{:`j.520щCҁV wU&@j!5E*4<_BRPj1X:[LbqjQ̺~(K'~<|RcQwWR; CI^ƺҦ+?T|@|rAiP JTK04|y͚`{ǕW}pGCmp"% (,5 ]zxǗQ.y:7rPnȬfK9XK$.G߻?葳BM?p&xFޘ -Jg6Tt*{B[vEL?o$Në>hQM20O5p6S)m[8Ȳpfy '[=cR9)*JJ̽ݦ+J?e<'Y%9{\fk=!C;Dh B ^k/&fAn*`A`3ɹ%^GuZ|J y-UD%>&굌 c]Ab0739 I'0;]Qřڥ#N-Z45E$f#<΢l^Q/)^BNYi1᧳0nEt +*ⶕ!o=t\$1m>bВl{`n`bh'-}x]6{+kԽDJ+r׶t0D7T<ȑ28Y)Tv@QFDBQ+CMW5pm%6K-{C~*<y3>E9{q}^6=gWK9yj#()9MʎA (;TLq'7>ZCK`8KT.5Al/q͌ؼ;w̑څw[}4KkxqU &j7SK5}bABsRX=G2r a.noWXa{m.AxT~emH9wԪFϩ} "+M@{Z9汦9g8ASrBS>O{}&oAC̖/`1\] Z`qj/z>ɨ24%jofQZ]pAE1rG J\=g$j P*谖F,#} `,mԑ3H/'  -F%bbd2~ƻ KС">{B^ǚF+%:Teҷ?FnekzqS-5h%bAXrHf24 .LIC#4#oDj] |$[NQк>ѧ:Ѓ2g;7J{@q7bmI/=fک W2o~ˑ[f?/;4e> F!:aFLD\{\ 5nńdF6. F7| (wK*8ps2m +eOUQ]>+%7>>ʦrlέ %cwSgC w.«RE+;!_ОEAZx;T.m𓮪-fʦ9쒕5t@9[ֈ;\z)&d﬜羐 m\7z\m%f;t2ɝ ǠюT~R"1kjh:-eqq WJќb3?LX DWԽ !Q77+}VSgmvƑZ!Ŭhߗ[Oivkąh6E:.&v!+_AT^}XP7iX/GϿ 6id1ܭn9Ph94;#)xFt?G- *Yɂ_Lx9u$N$^ gz ݾGy(*K=g,U\RXsyHt'ߣo߹Rgm-O5w(R~{-+QP,[Gͱe[ 9TyB:uS<' Ϊe#5ZNҟۏSZ-%I֠,CpݎV[N!BZqs_r[ucl<d>]aJO#r}*q>o3Hհ?ij-Yo{1ҝ# ГܽfjBˬod)ٵ&ll^{Zn^^R#+}PV8GWweOm9,kk<] C bRc6Q&]r :nEh! XOIB>Q]jgãc[.'cPIռ)  ?Q^ܬ̊/WT ̹j2X`ۅaՙb^zD7+PZ+`߂ޡ'n_1? 2 `a 1 aO)w>g[1uyi0>Q#9 O$as12=յKNe TM$D7crɛTCtHJ9dف7&L&-uI ) 9OtѳdFK,bÊnӲ>R0fN纱<n%^T3P!y myp4;9\7?k8O0Ǜ݁H݋d}Q.&9{_sf=78ï2MX(}F_O} ,{!J?o,Ye;1)MiqyLt5mDA'Vb@&|?AH`7+pA_k@f M%НL," {0J~?91;\ʠ^]޿>T,ܸSNꠕo)$ k}Ml(:rdm% j>tֲrMl)_+n%I1bm{ܤ=]6)^ ^.9p˵Cړ#P0_(nw7_.I7vOESCU3 ;,b5b]q!0X3/ȥxr萱Ql&aKϔ]+ÆHo!,T*$VpM7E):^mZ&6h+agR 6۞PF3WȬZH]`Q%B R{Vj<ί^y{⊣i(99giQ@iNn?ϗ$n.8Ð޻8yqC][/5˄ !̸`@5 _*M KH$e*]fFu> :˘ Uo; H( Dscne]ۋ۽f 厜Z|o Xðod#}ǚZ0LuP 2H wٵ5;-1֟\\c8G3D!Oq *j|Nep:g!*c qJZ(?  gM[Aȿ ~af㽤Z-'j4l7oA,o쑍ΡpnUf:MY_X 8>Kv\xJQZtZV̰lE߾lxwvd*ҝ+i 7AMF BI\d937б, ?FhN!kwEl$e8. /w)B><grs%BJsG7{!˵ Pw붍#|ȳ#qGР+%5 ?R  j] qEFcIu/=MK.pUio@KFy݉W[oУSo׫(I~J[/ʗ*EhЙY1D-$?"S K KAcfً#[/OsxpC>C,FOKnr Ј9粎~%Uj'b4[ T`:H[lPGd:ҭ$"-&[O(I_ !>_yaȨӴ6 kzŇ7nZB\09w:zې୓Y05dl$$rb&Th>]=| ,T@i>qm bk]-1o)ؘl_eL@ph'!SR$1|YmGw A>4.1dWF2~KfCG\9{a?]CѬKޒCFsOrcx F՘ߐT:ZkjX5mdM!䴚h:k=M^DmZ0ZkV_W  >g҉d3Vݙx>@{6 $otNC m‰ ÷ Z; }2Gؠ.SPOBcRٮwC笛FfE-1fIHXS˭+ZMaZ#ت##$p ' D;3:Yv8IQB,v"3V[r8 4y@"]R !w[_n8)~.9P2QW$=׭6c++ɍ-M퐄\|BS4.`²+gg.C;9u-._g, lw1bƙ&fۀPIЎoƕ<׆hF:ipdJ b<3:EjR2$mr²,Cb1ӆ (SFEoƅLJ.h y%q@fy7ӸQn+@Txe/|@gp}_;#fD-gȥD` "xY4y"nBYQ Zst2áVu@׻T/P˹~y$J&k04YP+k1Y<Yh!Y/og{ǺA .E.-`X$"e pԭCӆ!*md tiQZ_Ɽ=cuT?CZ6L51t!N&(ɞ)5)^)rL$9U8<"%KMtɓnWe+Cal0.lMZ =4S8:ldAJ&KnГkv6ؕ贞47Pؘ |Û-/czRQ"NĻ oR|f1vz5: Q,&߻< m f[lҎ8猜DpyVPPvZN &9xT!Hc4"?][D>;Җ]P%sݛ|%zUxywґ%SKuI-mjQ[_=+M\ qZ̸37m#T6L J&_!=;t l1dU\ 1/%dVA2"fr;T:"0X-.sS,pq=tr }kFOUTd:ӻid Ly36*+_i)_aSA^OU"syn!LCl)+-$cr(HQ ,@$w{`3khf.w`r*=vσ|&(h`Km8#X5R_ZӍ$aGEJ۫=KvP̰20U]v':ziNڬt,=?/^%Ĕ(Kn&jhQNv%WZF}hIƼ&7\8z\y23g&5Leԯ&',KLxknkbjv[G= T[ӒQ^H]'AP}Pk"dmc"^)>I#`:Mg+eCm.!\dp:t,Yc$Lz2Gaw5U1yX/46[CÆ`m~^SNҐ7RWVBͲG@[VO1\w"T֬##l_JczrͯLBEOĔ^({Y3B ?^ h4ܒD V`sI!TK#"leuEa>;8OVI ];2roV ~JQM6w0˘Y[xTX';\ɟ=0$u>Bq5ĚMUTahF6zKH\.U↑bB}Ͷ!3ildҩɪ{LZ{S;<0;=}O !ܵbMA+kb) 5gy`Fչ |\㉝!jlQ{NLkM[UtTW/J 1ћm*8%&ѹN|nl_9Ca3*7Zy-qaOF#ᑭI'񃍉ZJQΔW|u+Tl zX ` 0\>#V|4 "㬲Rȗ'\@jg~/TҟLq|.yBߑyg2MՀwpϔ0jcZqFV!PeDтKx6cURB)XF`(0~Rw?]Ogm"~2ds H EED o鮐( &v OՁh(NRW3]o}ǸvE7|j1JO쁦?hm%Q>0._.B Ph[2a*&C{F.f "!h߶.#Z{ Kͽ>cGƦR[͇y˾Kzq$LWPVFAx9.}$9{DH+?1aj7-N"Jw )d` U"1϶o5ж=H&>,o dP"՝J@>.sR slxfa(Y=)k]*Y6saP\[9IaRh\/Ԧ!t]Ce/7f0eg9 +e$F2^ zuqnD|A%`ld0#i%{x<\I d|`C'jD lo4z8] |TKq4B#+뮔KuW&Y"AaM,5.@SZg]Zj]9c~%Jj :``,0?@[9 VZ~Cߝ|"|{} څVgq  A[TН >r\ryoR=hjwL-,&[?/w1Ӥ 鿃d`{粊EA9rU ^ˀV۷WC{vpDc`1#у;jC>|7߬slQVE5V*k* ({,l`*Lahow5)y[?4ιd,(׌-nB*+eM d8{a6J@ _s>HN^%IZVlI]y\;3J?x%j8_{ ܍kSXP.5޴pϬi#a~CDǼԹj!OfNr}sb+=htU̴YUG8rD0Go2, 3#~PA?,r<4V ۔""~MA݉^#FZ kؿ>zMk?&JER{4pRaN6QJz\I>=_5Æшb'ⵂm+c:e#n2{)}xX%s*S㾔ۿ]hBՊhɚG̑zu?WkmTy8&f}ES2P6I:ЦACUJY A~3U4ErloNa?9A^mi0_6r&!xh@00t{IuYȊRCԖz̒'"$ר2?Vő=*n.MX>u< 6OH1D0VkU=)=+<>D3k3^0UvTKVX=tjI.F0AU!r}%oV>ʙgp xt+ ұɣ^揷01I<@j'6JhFLRgLj%W82;n$s=grJ;k.p8U0 :eޓ1_ x8ueS0~ 'g_zf'rO =) ?K.*+K$:aNNL:qYجu~,L9lS- 8֦& { /46Ge?t[$5cfǷ|T]]O&+ GAo;xvqzP,-|0o1,]@bf{5U1G ]I՟7AQN|'iX+C5F{!&@# 5;4CfWi&qz05C g6r>ʒje㣻Utn  !`})`ȌO@J9df4ӆ =0<*'Lʪ_?dE.|+ߞ k-RXuNt}kH,13dq b&K%95A.'ѭpd@:[x|?˅M!PBډCV3+ap X+ugh*z Ŏ`rg2>y!Th9 ?1&77&i۟GsiP ZJ ?]p $9%;tUFe$bGnAe# Hi7oUTZ #ځК:l9`Y!zt =X=řn!#Oc~_jQDO޾Ҕ?p^4}>&JSҀ{ua]O} `\^ ± Kׇ-Ld@괲ﬣITv'*c33>Rdq[xT@ LCFV'*8Jca>3V@`1/Xa'K\%<"1d/oAžqJٸ@vF frpp{HV3K>2Ktl+hoY>E"vR4a02X^~^WfXpшX{H$I1K[lUQTB(m<-_ʙ%ђvAt…~mG|eu+6`e9xa=2 nе@x&p,Z1L%& )P,'(m<1uX+"g};ì#w)IPS kWP{z,q[I.S9lI>~E{*C HLNX.IhH $>"5TTPUSަ-E(y͋h9؁ф]Ct|0\vwqqK1'5p-ş/CAHDB&(5nզBgUWh:*ygK 4633q<҉E}@ *–|(&H!u%ܹ؀٣~=WQ٫q0FAN"e|SᯠU19ͺzv  0 w$h3B[-eZ $"3Uo`miv}sKjxnVhzprYM0SiCKOpU]$ҳL\Ή쐞[nZ~9E=e }v:`X+{ P>+VK(v{PVǐݓe˟2hu.~(@CfJ٤9cB[1-@nD,WkzX_u-l=:{8<-Lm%U '|tZgBxjn.HAAR1Tfձ=4ߜK~B5Blۉ>6˂8 ciN$X8~7Fp;>=n ]-Rw5) fB޻S,yE6hD=T _7#4hi7k'> ʍSn̖Ȃ.D5]oU཯- UM[srCn anQ_ ]0|^J h7c-8 vzwKͫ ?!uAiyF޿%V@Nm"Y^,}>WLBH<;qtiqLP,3o vI3jF#\Z̾W )/#-wZ0H] MxQY!эshq51jUYZ'׫9 JK^C@љ-'>%yJkOÖƓty|=6!0Ĕ.h)đN0z_BKQz&fHP ϣ8+7d ^i=هNQ]:{x1>%08ynVpB]5J|`3 |)!$Z2_lJs[t+,V&ן7 \0}Okŕu=[gۏ$(4`mf=iscLJ6m-9rQ@; g>(oC%$fx[([[(e@9|rQ&j8> 9#7q_j3ZEtre">r6`f>S$:]an\i[˪Aǯ&#l]=UqC-c7<ّUitY +(9Oq0et/..ÕlCeBHQڡ4:\ԖQ'̈)Zhqw:-tߧ9]]GY /޼bd*⥱Ǯzquw.֧Ev!4Jr'kD5dmȗ,Qɶ gS՘K^e*^a!b0.}řZldB"  fC@ Xf+ym&]x! 6 ǎ_,m&MJXS mvM]@=V+^'i,bd$Y[Mzmd,v6x؁$3_4{P5U #L=@ӕ,\\|K0#/=ʯ F,|eZ N9 d7}N+}JNK㢞g/=f4q٧YHt!OfGR~Z+i/u_'sG5̤f?> ^B5VwxǜP2ibil佾>,8$Tqcdf0fȍw9um}QLR# J~qseYY9&HNzەC8;%f!6 {&7RRkKC_m dZ֝FbQ tѳoyqm|Y[Rφfԓ(@sRĤ&|xAMcԽp)K"B7`Pvo$:`ZN vO<s4ǀN-d:g18y5m0xfHm GY`'j2W.vh5LÇ陯N&[(JSf^Pn RCKHaW>!=֩xϳ˫#`YY1] ͿɺrR[Kx2B ςb򃡋&#t! r"$|%}*:8w7JPzꕹ.}j, ]п7`<1YO"EaTP4 ج:u( |MIp>39H6$Ub'!Z}GyjB`ۇ{CW|wLw~\2,9Nt vh++Qn]pp ."OxRgW|$`MzYA(Tُ;ik 'r N,Wxӻ^2Qp]HMV!>'vNcw=fF+kXza:r؊eb@EwW[HNXfAo+Mu 0(͕Tj~ttD뫁=(-98ݍh;Vu.с%LIU$&h;oQT $b3q.짳̥Kx'D~p8z tt~$428D?|,n<+$8O6nQ{|J+h1%ړRȬ+}*J@D(\~Ls58xGnR~C@ ]MItWQN36?mTxN`KXiЍ3W"ڵ@iG c/Rմ =\@ED[0 k}~jlJsQ݈EZq, 1$XEG7Ԭ>h.}A̠r@3ٱA;+N6f Cc *u]Rŧ0o(%{uujMPV8gZr7 }_@hs#r;W0b;kWĈt(v$'jf=S29_d~ h>8i 0xa[w?.3';r}9eS0~6ʏu (K~hf4,v᜴[ H4L|\@%$FDEzIbn`0~8qd_< r]C2b:#Tn[?xCڷ~r#ֵ,cDt``br@}:4xs飗S[D2ww'ևKSs3&CQrǔ3 "⟥b,HNE尼qf4 V Ҧ jq8~OH;Qq=qWJ zAT]1 s)qzZ~U'>H3xG=4\-+ۅ&)RHD +(`T< _hC1K{8Y 圤Eؔ-qv3xLP*l w~j̢9hGqL[*uFa&Yݙ-վRPgG^7-#,4 MVW&Ky-!XfG1> xŊ BPl%j5c7y!_"]k]h}歄'ϼآWBYHѼV~8(D1Ÿ'҇d;+ɂn!.NOJ8(MҀw+N19R9$WꈐT76u7ӷP (Y?׬9X kҌof {%YK6Sˎoq%9U9rM'%8h^eE)gJZ8f{r_L:\K#9>aKru%z&hmU9ؒtn47;%Jexh w,YĿ t!~K(ݞ49痁۫f \Jʁl gBv߰Ot̹KycnyЇtbcF>}P;(1k ]b6 "Aga1$FZ^|Ew$[迥udF {LQ=I8!hv7#}/3?՗nRpu$f1}n J%5>C$9݅Ƣ]'W ja] ًc{p?x50[T|WS,-D6GxBJPO~XI6X1esLRC?ߐ*˞Cv )2ৢԪn\8̥QĝB6;ng}Oq7)ſ~Yq VbZQx5#^ԨBOHOCa$PM;rkl@ݩVwow@?tF`yRffk (e§+hT]`"6sf@D[#X|B1?cԜ(07.ΗTNL|EV?0I-*ej,;tR#C#`h"_P</Q[D2 #X%.É]=a=:6>lxVڳ,wHn(2/ȿ +^:g4`߃N\l}TP˱x: ^pL U0+y+#x7?H+KDC5I$u]L$w>K\JzN3uGbiaF1i4wtl,XfF௡hG3,2<{%үZbK}{l*}E%r]5(zF̾}RfnRp $z23eYez'`:*m1Ƣ< roYY&ebh`(j7Ұ}}EL;\c,9U4eHO^|pA( JG&y%l\JmƋ EfbNѹf)4F?7 ]꿇^FdbMS˕L; ]ڦ_ugerf7X2ɥ9pNe8?Wp,͖OooFOk0EAD TFT&EnBצ. NT +Dz,I.LI!~!w#"eBlFKM|="Ŀz ,>x,W.UJ1Pو2t/Y7WA(@f_R%WOpP/aG")xVllA8%yLc hSDy:~lj.Ʊ*%lN ݿI_5PAs[S;g;K .CҰW0}/v(9f,Cx%bHKr@ {Ɛ侳HqJ_`J"cv PGQA<]DX2҉l:Ԗ'Qȑ8B%ιuK~6LDÅmډl70!%F2wjN+~+m-! L%P?jax|RpJ;/>+6Hy'WGDiREFEjGݲq|7P󪗻nDE5e^gs^D&$Y-1">g$9攝ҁYv@Tz&)aǮ~ %N+ۻo AR۷4'/t '*3*,@W¶Ƈ @vDPdw6``l>??e kx++dqPs{R> aeu{ge7ָX7;?PtqX:sDr8_G`yr'y^u_ro'b>ڮcK3z-oDW7ŲkIݛ4 83g;BVEb8@dRd&3_S#Y\(JuD*f2-rVI5it$k),)~A%D2z"I?Ʒ1{ҮЊQ(B՜k @uRu  DVw(*sC ]'Ȟ{r?9ρxнq]`Kʜ$vklX?DG=u C!{E~r vж:U qγBe0d02$#^s Ly)1;B٢}Qxk7Y(}fu+Կ`Ǒ=SMZO.K)GC}U f72:̌5Wm0pѕ(^`c 6ͺ*& +c范M.>Ƨa[!Hgv?2F?l]wdG8ƫic4m E"*ɤzdQLqt ct{:!-QwejV(ti̴ 5-u? i+lqYٱy'/^0 Z;J K&wEq ]QIRIjsqvÆYE4aE~V%G8bO;OܶLۜ!Swn5 #^P4F7cG\-MFycrwÑA0m~K!Yج^:3ԩBiz qWlvw$"8]c(#.ܺJX!ZX m[K؉Uϡ=Jא{\ךP"}>c׬lBs*vQ\8 t,ɳ"waz`LHx۞:`X.k)n)HEY֏" ?}2sְo;xo{m>!vr-no!uSd݃UTǔmdːSPL85'>V4$Ti)RRrWC;vLV0AR@R}[_^2gIΑ{,P{L*Ξڝ#% 1 t| d4AZ܌XJg2ho33w*îj&noJ׍"87¿rC͏vn_WSSd O$srkh_jz9np r/\;c.A(x'&%(AÞ2J?l3aGUOaQ h*|2zhBpz (uf(&?6~jAi0U n>CآnhK㓺@Yjԣ\~N%u<$$o*#3DaQ>ބK%A]$~h1l]NjѦ)E% [g4Qoqx]D~eb)\Ø2G>_7v5//|AQ&Q9_pSTVa`dU,kw 竽Q^2]YƏZ]oxg$kajHj&O wibA"Kɵebr-~ޅ3=>Bx]ff>swEL[*jŇyn8 n9IYl#<@ P`cq8 ?^S2IUKLyA H !=La 3֘OkEÞSKߡ]$PgE2W.ڛsхHg5Xs^"bR$/fDOTe xV$ȡ"l OIa3m₭`^GA9zN&]MInݒLETN^@P۴S|bl8uDm +_Z' X4bѷ?j~vgUŬ)n}oB-'cR ],4ɪ]-7ּOo*h\/8|M;h{[ 4ն$=Ee\% 1P%Y(4XF{5c0xUw'3p &-/?(μ~ʤI4^D 2%-ÿɶ0ڪg)[HNBT+~YL5Wlö_RMMfc~VěsUGs̐t1KGD1l@K%M ùfJɕ'?)  N|dT@,ƽȊ6AI(*mRr /M<8ޑջP{R4JdWDQT D龯ӅCf2}w^dYd^9Ir`йrrSq19PkyD`ʪgRySQmAw$r=@֛.PTba6ؘ󂪍9U"ܸXrb+%vhVx/gG,dmo1Hٿd5\4EPG=Oqn:&-܂)"k.x8a_L䞯UZ}b32WxdM<㉼-mcM~|&=\ *O1v̾sr6êysݽs vS7*EnL3"imK1+@: gx,@No/I T^O)Zb ߑjnpv%GPB(?iK9t^cg(IXU:d"!U<^`ίuޭHE C }g,[Z e{kr1)I\Or/ A N/VOvZpzXƱT%bK/䴵ĢgG1B] N#SN ]E%3T:b%a^<- C0qSW$Z&[AXc#&)MwܒJR1s3E7mqg?wzߙoap[ d%Jg=urYQOF/OjFŨ/wΣg@ӥńH=ʷlEbMjÛN{=(m-4V3DDlARu!hBQ,g,VOUqun=z;C"0*a>p-mě!:O wִA qzFP\V=.=u-8Q Y$K;=kal#} xN`4͡N.0 +w޵|3hU%~VIQZ(:η3=zn.!>>.݀d'CG'o&{> $3~8|9O1* *m3~AU=Bbb#FPyteXćFu}&~ SrjJUDA6w쥡\18, ufW9/uGGƢM'>P9iG=58w+#xM=Lٷጒ·ެ*HO Lc%HeVWNm+ do:4V%!+ пe_Jj D81C/[7ޡMdd6C@4vŋ0R@.)W C,Ӷ!j)t >WoCBj{yZ>-m]#`-d%2Van2Epޮ=7Hܸf@,h|Gp zkkx6ݕ=뺦& UrlnֱCW_%#X9 tq"Eƥ^GZN *o)b.Њ4>W iLXDTB G[0{AtP+-sŲbKڥ@6'-QQ}3IBkG?{2W݂6aI[pOݑ̉JL*ֿ88>PpDO8r:$`M~'U89#zE pf)wcސ m8>HezwPw9#Gp⫙ueqʗڀbV egw4ę?Mh)7=Z#a.+isQ[ S\hl\j:"AHkhS"l|[ebu K[."b6(s{4;h?pwYJn>K)/]q"WHE:xC%W)(,h6R |OvjjcBGK>S'ad"?*pïBCM1`v vj!(4 0tdg܀^s%:,r`UX ̦7P .Qhڇ3 @ ɺxJ 0$VᯫUNW\2<!ٸ3}XZS ~sDɓ-wvRAS t* UHs>>|^3 Nd:/UcۅaA[J*N|R)Ǘ hMoűfq.S:s%|}ՄPvq@蕯۸4?P96eOTV"v I(X~>ř~ z%.Pmo@:pGH!{"Y',%Ul0'C91!V䑕V/қtA׋Ł拌 Sq+#Տ]v"ٳց8ו̣6T82ϡ-R^xAI_u=lਆrqԞx&Z6xnsɁ4) N5ASn15?tJA */`jFۋ[[J%|vM$jء2Czrc$_BIYNj5S8}#Z aoMKPΝOiE,]~C6T!vN'n]F*À{N݅s|Y(Ÿ r,m &:@ij) HշꪽϷMPoω r|w]3I\$`OׂZN E$Ng-0ơNwteE̹l#dad'0ޡ€Г`-xYP×"o9AhKuϧ%%=.;hcQI|4pi9F]!!H|,'Vh* N1+W4+Tokˡ7EkavAO?Y87%Lriץ$%"ahS_Y 螈G=I4V[7C馜ܦ^Jtܬ ĘSXoR:*h Ct#}0ƓL_V!-,v=p-)c)\Usb0LrPIhQ=fn!R tl;.dhO&6R~e\5 6PMo<=T^ j)|5|\U(1`UJ%L)9ֽo(bk"&o_q}"d4ӦΕ=i [GRP*/qIV6uNe8=Dm=[ UͦCcbX\srq Lj[|5{zfk_4q~5ljv.B^H| ' I``ݹg4Ǐaѯb=/S9i^ 9"e3oc<H(k'S H-}} / lAFvϖuSU@3;9Fxj{M=Ї>\'p Y&n /"_"Uuew<8DA=/"}oD|A9`5tph N/ KCan!M<2G@%@ "w/L0f*s-fEZ$)'`wi9Uz{٦yvoN4_Lh /SYڻӝo߰W*כuGQ`~xpHH,-n"(]pLV%5Y 7PprUőDZI%*Ϥ&yy17lFx:^4v䠔_$z;/G;ՒjYA(sYeOaAn= dbe窞3G`P -E芰N:.ܚ`[.ؾrz/@YaS;|a6Uoxrg|S f3BV(Hi^1cOq/kt'nO·YtAF<Ewv^'^\+wڦن,6X5%͘lKIF~1hcP08<"ى{ 8GYȾ<}bFh *|$-E5q[_Ц9FYha&Eɀ˗Q^ͭɬ-eͮQor*_,6rGo%<ɿW" imPQI]סΐV7`}ڣ+{@pX}9(([f<~Y-:\NƁCX3^8 >w5 ְ1̯'-$! `焘]r69V(+<hiDouY[qՒgZG%Ʋ0n #4 $ ʑ`+\ Go3<ˣ*c 0a|MTTVaBKA^F4w|ӽLa_๬ʑ3&9.ڵJj?gQ3n2הv7<~*y\m#+r17P,hNg(*Š{(u|X}ao_We)ZXxʱ91>nm7=7uLMB@"~Qx|4l7zĈkX,f( #ue ݑ녯䋈 7}CVN<͗LJbMHZ#R6* 3*nC&hC)A I')f4Q,ghVVU-&]S̮HoxWE\H#x硴qH, 5?gj]XEaNZ4/.9܍ѝקsBJMe5YusJ-2qIэ faaB4T*',فpZ/@ADW穙ey(=tʄ0zHPң]:(=ڠyO P $?8VSHmdʽ[W[zUԙ.Tk4(gRSiy+ӝŷ}X-ncq^ d<ƿG@B9S^ժh}qe+ưi[" ~K~k$h}$[)Aƹ㜳x|]bǚ5[Viސ)€ 1S˼eUK ) n~4I7Gdf^w:5wSC=mRiCY O~9_vk#IKa;r/kw #-AC[iq.}? QuEU ~0 l2Zx*r'Km>h!qN 3ak5 T{̢j4؋T g>䙚NØzŀ4xZw_/~{tMy?[S-8[^kct(d]\^>J'D\q$jEDՠ cTZ$]ߖ"7,m5_02rZ!t|5!$ޓC͉b:=sɦ כ.Ϻs[[I!%zOA[R˧ ]2VTEoW)cЩP"$9V|[ʩXnC%//N@J͚3mdÛ&.J"GFl<܀.d$RokD9^=3-BqCfy`z zhķ'b( 5CO bV8ogn0tNه\JRw}A1 呱M*/Zpء!+]8$@N =-C,Cw62zp!"T>Wʃ>XMW\< P:q\*}èM/S;F^Asn *鐉 u^ᵽ,'`}dX'F4-@;|giݞՌq4ny/._xbԸ '#`lhoNӮu'@9IXUQ:qifzVtK2ai q)Pֆ EԒ%蒘8)!omPUn*hWQ.D#0oUQn-5ky9&|rNQ/KO^sp1`g5{*iP:Dք6#SNL"(סEP@ARk*PV ;=}b=9W745a9ʐi& Q%7`Սr[%5.ظWp7oy2xQU_ZGR_0IMB5F*eьfa}ЙƯdG#%$r ZXfaaw z'%TW?4 t9#X=Mvp?<ov3Ro$ln w%xbuombjl?+6e6;TPI,̆ɧv )X[zGKXtu,~3V1~WธTq:Y}Wm3VKq6P*\~o ƧRG I['u}Uڀ7bʆ(!pʓx0Cݘq$RMTT΋<ė0>Kk2c$bnxHYԬ,uwPդԬ}`yjɓ{).ڍ)U~:?tDB4VD|W[Ё6͔zIQzD;6h[]鏚nwG7?ݚR~y0)vm"uWMwŮ`i灨 N='Nӛ2#`FS$O?ZXm1T〛qu)3Usm:\ڙ|F &Wj'qkF]-slKVp&[3Yۉ(8=,$q鲨8@xl/  '$ d2,["EH06{E߄͹byŵP~),(߇p&҇3եs(ᓴNQCU/lKqX_3Q^IA{eFA&vc _oOaj@E*=z' L̍G0|]ćCD+GW H~:339-D%$&e.`Yo0B"f 7%:mz %FsRwl;;k[* lY¯pij02'ʿI&^|X﫮6%*: &=˼`w(9\YZr/QƐ6t$}0 7*; M UyVMSk n#cǡM϶~E֝"iG6j]u==o:`K׏q֥4}0^Dvo?fyiW#qrkfU3F : -]ٝ5a)CQ?8[4?8 @{nA2VeAL͓eu+Ę pZæ0Mxir:Bdkœa1;N.e;4{"CGQw[$.ԋŀ@o4"˵u:$w7)~T9r]VûAy)|ފLQuЁuTpZ6pChC|)+YHJ=b--O֌^P'L )#;?R/fJWGԪ2[˜exrK\P5f@ h'c%:`6k!tRKt=#<8 4;v8Rj $kp'!9Uu$:[v[1Sy\**(b$S-:6ΪaqSBDʔ6l.[).Mŕ۟!'~@AyQ!F56BAЭ@*(81͢Z752rXv"M!lM&)Behj*U5 !UsJ+])![$j #fS z񗶲Sz8 5_zn3v6(2ytEBPA0*Dl屬]Km8b\qCyd\vɤ؄Iႆ.b3Z%` LTp38Cť$wӚL5_=. 8)Vbnc7Q?%`7x3i-$4I ?Nd:FQ']킘q`w-ur/2)_'D]j(3Bf.2Zp Fqqeq"UUj8875Ba\} wя;6ҧsdAעyMŧ,'4N˓O_>ҴT!y:~cc')"N?&G*՞}1`␔d7@t~״啈QB8?/ YSVۉ w>׎;l= iOGIGސfU$^i{@՚4?/&dCEPVe4=~ 9tTҾy0(lNG-2e~9h3PwMIZW몠+qHt:z4yVo@P"KuQ|ETPyc+Y(7T{vc1aK=NTjatfۦݕr]` OaRRaO,1?u^ 0g4 h8 ]cc@c/\du`^*LXL["Ѧ5нd7nr3s2< Je?UlvGꤒD1U9.(]I[ F loѓA4CNJk&2P~ȿ8TTNMo=&0gm`S](WZEF-sۇ7폄wIaiɕ5>M=ީk*C v585f,K-gRi921^Ր!Gn~^#0Q^ -1$y6t ШoFKs~1y,E&]V\Se(\t>~0;5 SiН|axԂ? 2ۊH'MQkpɜ諐tǟ(ZQ]]qx@OzQ<0榁z_=8",-Qxw|d~,Q)ʙ i˨kM9x}Z?4ڕ޳`iqCC֭a-g#؊NmX*sޟ7V^!oik+a(#~ σFc( 4E$X.7T658;OӉQg̵+JFߎA@˵J6 ի [S3:Al-1/-cy*>{buAǎ濷(4tܩt'Cnr91 pc>XIeLkϷSg!oǿRvځ=uC!oѥI/%f!]nb3t9s.Y⦻KL! 7)< $!>p[I7_jXտcI C eVo?v~A0M QH)JQq"[- jbֲ&Vɯ e})@ QZvH‹I k{ 4'!f()K =k]MJGf 9 /Ixb4=^OW:,IV%yWJ݊ FJ4ZmS>Y %Bv5:.XL4m|Bv0PI%bƕpb2˕K r <+8>0/ Wt6M+'V0:+B6&ElH]n.'0"& sCc-3MA-#N'wd.+Jo=\ ! PGK<3Au N\$v~SctS

-duTJ1>zcvǰ-&HLKH'7Iuk.M%ٺc/Xqhld *AY,D]D}Q d9ݧڏ&]~{$/,w>_b[岰=7M" 0 CPy+puD٢n& & ㎝P\h`BKPkO7bv ~ n40pE85|]b7ыJdX,%mz3*U*KdUHl~߸F]/V[ᶠpRKfUuW8gB7]L+Y]/Q#`\5BߏkrA=[z®&~/BGK6NBEjr]w, R[opŧi1GHnt{]{00>?vtЬ)H;k <ɋ?rjfmN?]% j=q/o>Y/[h_{;2m9R装($$8z&FEn$+mV d !tI Gavӭ:9G"p tmP7ء ȈtUDx[_F[-7e@sD&o ,I|(%cy`e3m9)[woO &&%/1|̌K"@7UIdDKY߅g˲wjVi^dB[ECqWׂʀle>~FbyFkX䧾߮fm1c3)Tːqp- -mfˆ{de_x&ZQ. Eh')\gGݨ :婛 gt fκ-qTCi3˥*bf\;+iFv xMx eՐ'U<É(9iƴ-਋bÑEr_\`CSHVNIms3{ݾMf8,{jTn!,yfMwDhh+Ԣ&Z5s+꼔ieYOW-GVtթp(9s3{'Z#ko)m>$)Y-uNjY䍺&?s-5ݜ D1dtSiz]mް7yh|@mVdc J:v+I6תUhsCu}n }"Naw<'$5*EG;@;ua4!CwJ CIt7rgyIg!h~aܞX 91 @b7*6Ҫ=֛%RlQQ qu1 Jö. 2dm鰙[I$J 06ӟ#[p | ˭h!oI MdEwEۧ`1zlݮ̑=!B.H0ʋ9,(>g.iTC(cߒb~7i[cdo)ϲ7s1}NkJ(/x,LG>WC`bA*d_Ek5ڗ;נT~rZs)?2Vlo㣬:'qaqzܺ ]IBE>}y+čb2)1=|a`Uv^_pzrHCI; N2crN̓O=eb_Ln)0 Gʟ>(Nq#BMsQEd }F[ތùkws7y8wpD,q{wp"gZdH b钘JKʞ!*1_tCgQx ܪ0ZD޻l4_/c֪ "M2c)ԛQ,`[Z`[L4 Y76)OI@#4s&悪?V;UrZDd(yITpΫB$Eg WXUZon Cٍaȸ{]n<ɔPL,)iҿQ.ͺZ3~U't\߂ñirڍ=s?QO j`sˤN~I4#QQTqs_s&hW"\r[Uqf$} @_ԑwgj T "g 0 Mv? (eu?qpѣz䒺#73|/(&}ĩWR#X fy ڼ8LeQ௚ tp}6-ڶ=s3+PyAp5Y#V}ʪd5?EpWQ[6Fu`CV!ѯr=t5?a-ZR~oUwVj!#wc{Kh咙Ex^ !88WP=}L1| ,KEY ˓~be7fΪ_VnX2+n}6d7")FJ޴[bio.ZPUo;kՋ7?Uә:UD2&B/w_%C9#EWk{cZA?Ef: ݮpJ6H~{X$[_@rI%HnC&Ƈ]Z -[M>XQ6zkٳ̏FYJ&$UA pI _WtNɘKV$ͥl82mR$mcRpplA1o09Fr>W1 W°gv8W 5Y%e,=_l4!(ъNHφMnSbL8l|Q턈W+ ,]bG?L--ꀫCe0SB#0=1sk4SD8 i⼛/)E8'bP"=E3V<6q0,@OLKe{{ea;i+V$3kl~XqKUsAhvT::[ LrBlK1ͲM8 Z;(h**q+۽_"׃'@$*{uu /yE$J:1IśU}&DE̹FQ̓n#$)2G> R)dJ??+Nt=„3/ /Hn,{3 ?\UAG-xS1+%WP-nƁ©d1Z?Ko *\pj]9@ѭO {OoNS63Is]1X24Z]o眣8Ҍ4!oC:L&O\:: T(]s<Ͷ{BajF7yrH JC['Rxh}-<ٌ5y WrQE;Y~]g^0vWbxT̒k0R@UAW;ߍ~P~g|H(ZlVSHOEg"E`:yh^@1W"fH91t{3 i5Na1GK&~Vr|О;"f)'xuގy/ĭL DANW&{Nd$a/3?񋓼Q Ε7FLGU6#..Df[e |J&5@%@ {>/kd\*?SIJWÞ#z&^u?j;?A[I~;(CΝ1/ȍ>K#vڏvlf2\'+9Y¯<Êˈ^nn4Υog9[eþ?\ߊV{otyp,꼁oWfh/y|"BPV~pVg^ ' 1 % y_ꡐ 0y[m ྇BYgQFaxk)98: f? 2FjM) #~e CCa@t40Y+lCTL~)q&X p?Fb/5% C :!r:SB"zWa*^EԹ> @J[U nDdu1a4m*N.}fcܯ^15;Η<44NuQ9Ϝ8 cF_tƎ6bΈ!7TF0KnIr3KEm@LXyvFAe@#,a"S&M~ ,ܷ!2Qr:s``QV2XXҌV>k %TբKz OȰY;2Y?qb6w߻(%2Fn;佩{ѣ8)CHy)3'H )0Kj1Ug5ȐZ9& ~R%iuVE6>Zmj}%ݎvӃ< Fin@bJ#k'ً{֡JYXYHnPʒ]LE8WV}WOBAzaٖAXD 9O$Nuʾ;E&PZ).M) "aHps,sVD &+ɤG8aJ6k/$ڠc!0s+bZnA5U:}7oX:R3Oׅ;Y ņ5Wx8 *,Fg&E@֫?KXTro1?'A}5@Ckɒr1Ϧ-]uS@#WsKy2 )B)gJWZvk\ꖇHo+qK=zW}BbSZdC0Ih7 UXY(Dn @=jBz*8, 0ۑ %lfN tfυ/&aAIQe<ӝw7+WaxѬU'Y3UL{-pB64fNYˌ|$0V~4@r~YJ@z}MLh3*M/\[/A B;vţqqHt:Bt;U%1^sfW+Gcd|h^S+ Wv,FroĒ(/=W 1t m{dæIf#U.5z!ڰct -JKpH2csotnb&BۈY kgc~$/jW6t[Ő [u~fgb&f4ļ4t0vLP$&2n1gJ j#!:#^tKtPSAY~qz0&(r3iD ǟP5 Lɦ2C.ꆱ8NoV @ZdE>[rN| ЎnU%xDh[|چ&@e!RL8 0-Li-ǖ OF/7RP֠J\|4,vsXVqy&uN|bsɧ|tX^[3 o!KZCa]U陶RP3z(7B37JI0),_\ZLr$ͬSk1f{9C0;kz=>ZXü2(.Zo%gnDf +M }`G,l{ˡ%`Cf1Δ Ņ4)z%71EzaWmd 01ZG ej"A(e_elZ~2}|2Co}P0ae(3B=nǩ'u׭aZIec#ꋱ5gn{ TB&+;ȭz>\+S(4*C( O z-Fw,p'}50 EPzmḵzD"Q4I"蓮Dzڒ+rhi%u_9uO|QuȭJ |ԐU"`4 [O|GUhwOs:aR+R}+|~¶(d70BB?!/I"lg%2~[찾HW׺-`SYl\Ѱxݤ6F rwx'mifg(Ԥ>kXTP06Qk,'@7/1ɈP|4;ja||\ =\ta0?;]IRs*\*Skq 2:⎸?wEf4dc(\?r[ƭE HR cFߠ˽u3i -w/|#`uI4B3u0OV6 ?+[ND択J P;rv"p!]=dB&S7I"^e$ s_*m`yNVBEμ.` tuE6?4TN LkфԇMh;{<sEřdC0qo=Ncw~ZT 5T\,w~Z3 ,p/gc^=z N~4}L.vƵ kcQbF[R;vu+ስ(tEp A7#ABڔ$$ɇW P0PeUPlyCF ck.)m:S14$:lhF?lH r{OݐQ-=)uKzFZ[$ʛqk HƱs@Gt<@=ۂe)D̠i^wҦCXlP,m+Ĭ@5a.!2%Ҵ$Z'0'$1k]R'@ظ?zD>N*Fs=[20-ve9dݞ7Q>QٔC!_aкej`I"l0e^ȵ8;{;$xK)󙨱'~޼ܵHRá<`Tׁ257|#l&{bY$UyL'lwER7VJqƦhц@0ޕhy.e#k УBehSzvܦu *&i6td! q8Z<Ԟ8S;1,P~#Wַ^svEqqDVjZAz|k]g!~ܣKd}O>'yÖ(sYѓ7͑DqE $..<!;vD D@QxrSB—픳Rx|̦8N>=9Y%k3c>˲Ƿ'3ィv jluX e&dh ~ =m)}lbp˂A4OeQz;{n_ 56jLX0Jsч` w~lC2vٙGJGIz#JO#9!^ܣ'ZV@O c[xbS |9;^wP6 Z% |KxLhtxMt5BwdJA-W ٜG o[2 /+_DcsYz ?9fzR Pt]$|loԃ<%A 7x<=$RI"2_m ^,x X,+ ^tYu?;+@)efBW/-[g],ׯz]y}X<#gLb:g#^MU*Li9Ri§Q+d 1Ȱd1" orT.t:S7pW=p?ˆ?َ 82bxׯ<) 06XVMH5%DR̂mX̽AU%tihAb15*-EQM~6o܂pN+Ua'O /eKD5/ΎsSkڝ>9=ښs&>j/%A޸!3+biE^,N:RBH8~zMc-Ǭ=0[e:0 B&%d7~=ś0Hz/?c ZՒ+4ZHQJ6(>"?l9PMjS Xjy_n4G'/[h\Mge+MC+.A1szÀjf %4ռ(^7]_,d7F!ɣTuhBz<8AސKziּbMT~(} g ovX'(3VFEH1Z/2,X-8;,a)Bt蹅(%gKn^j0/CCBKpxEOͧrrn*'d?GR) X62MVru iT'cS*iP q7f Jh!:CP`n%h+y*$Pbk[WjX;<2o9ئzt?%)w*GԊ\="{*a; bA aϬ u Li.u4*PuTj:;^6(zܧޙK +hsJ4?X& f2B/]:zh]7T ׹nw1c:&K*Z$ݗmzpDK :M}yىIoX)[xߩ5~pVIY XH?flc{8JQ|8q&t"ghq z oƱ4V6X H twZ[RBafN!U PT_џdt;c&ev=:GnKG]]8L7%XyyI×BϛJ.w;;Ъ@3ewH<B.6D#lzYؒv]~ÏSWlXy)vj sg  Azul}{&Ud~roZ?SZ.[So&+^#T8yQM)qn 5ZE&N ;X܃@Ֆ.໓iUNfp jeKFv<>D]еaP)<<%.ATh#Dr :‚Wzu>[Qyks>eqČK}z2 n9=cG_rR5Yt;WŰ0H m`mUZB{qĠNO0WQUF}&L$#x 7 j;TjG/#:P=aFS7Em@0Kjdq2堛qrE|a?'.Yגw/F#md-<{cjUlh[w9>Tbmm>+s{J ݷԢ+D}NFQ!v~& r5"h,"_HƎm>]r;jH*ߛ 0Z`33wS zVŚ5QȀo/m1߂3`NǐfZC@p%ws턣.Hӓ4Yk NytFz[W# & :eA` zLTScEmAl1fr~NܙЩh(u,w7w ulؓJ6-R|"{"VAؤ2HM<=/|F }W0t6 RZKcG~.juE^~5 Cu@H&>+Sө$?t9g>=|u 0es{j0E   Dꗻ@#φ)}X[1s}9TFwrU+<)\Qj)0mYCO㏤d6@رG6"Ć^#K #5joCs # 7aɓ< Cb wY{acy. >mW'T憎 *$L䐍cu=VH5_>o2{ubul[Z9@)AK{L"J˂]<93Az= EgjD^6O-x`%FVײ]}z -ɳ{D$؄Ma7nܷR1hQ8KªT u<rA`|/,!;[1FtB2OUv[NS3t[%|Ngdj'#R4/sPVoLRzFΉ<РC?HifԺ/n#H#ea+sk4#te\8*~DdhJ̨m*N[5U%7 i3=Y6v_$"}TO˰/l& \j΂a AZ%ei=XKd g-7JØ6V-YFpedoɄce;VS:U:u'52ܽ&USnT[W6o(mspYiUD^U@Q~ԉ$F$gku4>O ׶<^jʼnU Vc*hc}/Yh˕ ;.*Lŭ"BZ+¨*.tR[յ ɹ*fkPF s#v$ }MDȐߛ(1jFl FbO[zݱR$IX%}NWzEϺCˀaY Y5tīI"_\q.T~X] @~cE/SVQn-$@6i@ZPuUOŽ&f8B 3o<ͩ 7kX ae_G]RlfevN5_X]FS3%=Vɓ5QptgSOsa#Pjscy[),K<#G8`nэ$H8/}Dy/ H}Gr4:üdOAn O1^D/aAJ1_ctQs0:NLCow|>GNYaOSYBW[LLQODZJ~Ent}t/?!kfR$8Н[C>jWϵeb-ۯR(p.hTsF%&.^#"Z;շK-2œ$giU^m>e^ NW(x/,kwn9pdyxlT׃;ghpw]AWrM}A^ ?W4"T8tw)h}^*}1X c!@&i~fSe87(N"E ܔɫ`I c|iw92:oݥ`HkJ˄0 y\+Xr+cL{:rN+fF ,t4]r2eQp$UM,I9kltbC"eWzP mMĻ3b2rZH=!}avrt @"EB&$iF1_x ;/ʸǓ(̔)gGɡc &Zd8Rȸ#2 pH"mE 8Z8:E|[ 1FHP; ,0؊vk UU`݌$WYƒlTP >hK!:b 6yIw.v\a{=P Bxl[):KR|Nj-- Yp٨Ղz F ՙs(<7' >M`D"0F@|kͶ)C kb[L#B] Q Wz!΅T~V c2ꦲ ׯHr)'ffG^ō@Gr Z>g4u|Vf$Zrɾ]FC 7r=s/j2LSMwƗ C Z ^uYIGJ3NiXγBjdk*7 Tn?r%ü-5羡 X*eI:ZPp#o)RWŨ$qZB_bv95e߆@F6͕Ö͗$ +.]o&=cZic3|s;v{?F%elpm~-.^̍\}5 '=UZkjSJ Y&Nm*\D@] *nRZ<+/> @IZ~jW OT2jP- u$4 $,2` wƕ't搂P4c'.Dad~! ֗>kI!+ bGH!`WiLOKVCuՒ9v}-C_~(Lp" ~} UpF˚ΔJy@8r6V I^'dʫ.xw# ~uXWu(PL9-ƢA>ZZ)Br/T>y>^/}RdSHS]2$ 6ʲ*4F;{89LgfF߮}}?g3فu0BVAc8T]l=<*X| I4W$5*2*R.̞ykXOw$."N3 r[0⏼?Bw g-I/5_WQk"qs^L\@Gt M p6=j&%d7X乸G;߷L;M[(L Fw;-E]* 4vϴ\3:rF(oO7rB@ۡf2 1&"XnXʦ.8[P=T lΑ8yQGߖC[!cCﻅb=A(b8v[FݗOceK vd *g&ER9Iu:{ s׸6y 6[Sq#H$˜y~Q5C!e;bOA-qHdy7晁nIٺfmMQ7"zoƧm;[pa;׆PN I"l@|9sMP9s9PR) eJp&C@voTmB,.U+vs[fM Ae ZYۘ%<K8:+=H!`1hДͨPi$($zhmLxж ޿ (%^̥pAWL"qS בהߕC5>g ZyZy>uVywoIOVd"8O6޾L=n˕a3^Z涆7#\|sc5(}NV =CK[xmw5YԕG EITpKa$𷟼^vefnPC3/?mV O 7~u)$( &Oa4pVbŁvm8sxu=`D'Gm/oFՐ"qs8K倀C[~\U^{dDOTa/ 'mw1`-4`=pe'1/r~-tIcp|uП9os_@h#M˘-pTlfST wL)}\.F"o%c/NETم/ʗwk6Xd<ҴVxf ebx/bR仓֖ltvelW̰VQ8 #tC/*;>%kpHX2"15 T]G;6E&H_,Ni#/ !yJ"6V6cFB$5)ڴ N+bny`y]v1tt^r)|,H˭SziqnMQVV,QsY}ޚxR )0F7i] r\QÑXB`m.^Pwab^?1GE`&@J7N(f$3*eBD(mB,T Ho| F 9vXPZ(/Nu 5lg5=j9jd'>E aRD +yE V#ÌV hp#WNH`ߟ)^Wx&(g?:{P?UTrf9 OпQ{lv NAo@&/N(odT?#ܬ pH-g~e>3?Pﱕ3q^xNTKIqKXU ϭa+`4U0SO-}g0Vd=ۑ\ p䴓Ӎ)LbI5W0à?F_5$E2cB E;Dgpo_k)κ 4JRi / 60{ kTDqHu_ʼ+V)74dʊ lٿΘr@6l;?0P mt|YGe X8ͷN=)B'/'RoϞ, ut{~boγȞR1? q1d]+BI#CF'v-IHۡ>G: J*ǂ2hlpP2\ZBe4l@a-;yXkY"$c^i\ xo般6Ĕ{8%8 &Dd e%3Mp6z$φS=2AױS!JZ#<@U5?NQqd/GB Vo/]'uҗG_U,MUnrQG&U6b3ңs1~ȖckmR(;s"uH敩GhN.,?:Gv@sVBOU=4}k^J ȲbLlxx՛>Dd^#%DJmʊ$/Y8231 X'* Bhr:0 SOc\N;\p,2m"jw2ӕ /7&L:H9+bU}&IO^fZ$)ɚKf?ӼIu4EW7!O0ҴU>6pBYD܆zxcQ7H`~P1qɆu;"ə-V/W^:TB#PB[X7#|>9$EK4G)ɢJ qeoƌ2`7Y3y GXG'np:I7HWfcvil'U֎KwN\e&4{?M„Ʋ JmrɅ8;BMh8C|0LKZBG{eJ>˜IGl;$rVӈPBpV[*w{KPۗyxyxC6M-v % &A{h@B#7ԜPtDsU$Vq+Zy,7:musxk&ȅ9lޕ_;zRh^ʠmvBz;DIqĜe"5!ĥP"8cu0ڳ $XF6<ƈL{zWf#?'o=g #1}N= @?$7̹&-Yz)xهЇkbM8RfT(_}]>M:[Fnh|T, @Gb؏¸qa Ap-͚+.viۺni:/L壕JE۟m2lgLs?c=ZsJ@F?ݥ"(Zum-Ӑ##!HC9}m۰SXe'~ȒreV2 MUrDBLWk;='&=-L$Y45]V3p;~ N fJ5A8fߤ誧M$Z|iLU`opS7`lekˆJr0;UJm??g5f*cJZ ;:]$HkuWGplrIH haQ#@.&6J~i gKkަJr9maxfP~mYCHi mBR_yׂ1&#,:\OJu-vF 8MBT .6f^sh " ]vQjm\4TctBjnBXQ,ЛH#NİTir186{ط ${@,nB=˄DIh 0c>"'^@!pnP,UCQrcb\gX0\#xa^aMMF&DUL+%V=$$z{n񷈬+rB;~W1GD&S2򁏊U,\<88\g;ʙ~rB;q/_$coA7XFe6[\DTS"^o'ԘʚZ 񷎀l:O^kvfu]bJŬ{ ҏ^a#. 4<luG mj4 _N {_zkا sX1=0k/zm\i]*}Q]䊮s`h3XfNkݝC`q됂e͟XWLcMa֩8whPxz.UsKp1Z]$j-$݃> (~J>:7% 뀣[:Sܩ解Je玍)J[ 6;О~Yh#fvz|ˡ~L<, S+F5bL{f=/,͊ݝ_gΤ!IY՟e9xv>G٤磞ʆ g/SN]/qSu.ff&ao&EtOf.ng0u-&V #t̬,{5IT kvuPwdZW!O הɠЊG;dI=Fsl&{0kE-G3ǤKj 7 y[dC =_*fDh9Zkp- ;Yz͹Ca|NdB"Wzl1(m`ׅs t T7WʌE2,_萐t'ҩ-6[4;^avmoR4r@|V?~b;i?p0_SNY+_]rC:EC? '  -[X(܈Tܳ1ǔ̠ͥ`DW`ǘl8co[*D*1 )8Q s-lFU ZՍ-y_FkRJn_7ɚ,E]ZGLA;J86;dQAv 4ݛ%vܲz[.i,UJӹʁ:ami:$ ,ABNRF[Fmr1?~~88t1q <i;2Q H1?#q{F[xV6k_j0 aŎ${$ٜ7bx.Vxx:FlԲt{sgy F}}5p+cx"AAGixvxrjҀ^i)&Ah9m룙[%_es@N^$o,eynlHN cH辳x+vS7u}P0 /s^p{y儴hv4"T6|R;?5JNk O$9<ӱ%%T˦$3_5oG#29}fdã0כK{ %gV_1L6(9U-ަG*L vOrv+>Wa&^]1JԐAL QiQ ~5pp8] 0/Rk-ɷ:H(y x1rfE%* C佘 ʢ5x@>)wAc(FΖQu7~R$I%x&2FXש62(~X:;fWF'>Ǘv$ֽN<ldG!,8 >3&gnN'ek]Ft*î!4f+03߭l($ 'Kz 8bm2*M\o-ߣ/jV;@EIȁxx|3Кm.>b^ TЛIOf  kA[Lfm}!:~U^hJ YwgC  v"$~* H%Y@P68bj! 2ZawpGާ'ƴBB V[OZf==$8އ^)mwV][4Qzꀠjꁏ⸅9Q`FQjEiWYIDqT+bZd-(fb1Vqn ?2DJ bu&/GL֟g*z씧ڽ.ERNGhusI%-ص~ߙ7ĹCGk"~5gWe/(D+]K.#JtYK >9n7ַ\)6$ #4Յ 40t,PkњN0PKˌx*R:,^Y N갚-^mo<HŦ6|h%OU|iwRMA6\>WõZ3%H("  Na|2ܐw*}AtQkۄ2Ln Ajx&ȑ,dhT׽"?Uw^I/U`Ru$+oF AS}쩂[O>k Fv_R\=V+?jG_h.DjD)04]'K]_O-˔%솫4Z"n1m" e]Iyɤ-#zIJ#ڃv8^6Ħy4PlށƜ M\7UbԄaƢ1zǠtvQdnL˴ >Ւ`pDlfP%uC pB[I9ct$ 'ޡb`еsh s(6(QM 1^kQP(8KKJ-&u@lP5Ǐuȼv(c7Q?ѳ$d:rTv'VSېTMDH(qtD^ Ndb[ |N@PNZIP燊!<>)"{9ͨ&81{8F4c`VUzT"] lj'@W8|-eKl DÌ/u)8IPB7lګ%h1v|'6_A [2,~&i >?MQu1C2 \X}tV0rAfFYhKUbvclל,pώOؽ^zW"ƒK=96-!8zgWDi~ a MCicLz G}ainnJrޕl.!kDI)PAJ5팮2 TaBU.!fGMHFXܥ_l-b5 teKt6oK QQ[ܹR\E'zx@׆ҹ5Gͫ]3cA^/l_4 RZe#lQH WijK"sߨE(a]$W)5Zw8|R(+M&0NDgEܿfE0~5=%= ?-)7ݙwɆI't13@0o+h^a\K "I먀|[ڏ6ѳz4O'n taW4,REO +ק2Ⅹjw ~w0o/&B[r iA/hS_>s[A~_e_Ia_ HZmb[)7tB҆I\i>Rhd|s'wgOG*2'fuT1p,Ǘ6M/a@{.G/Z4򧚔k'ky]4jwI:/ ^vp*65P&)LgN99xsNԍ<u1PS'u#g|(j 3%7vo[nbu"A/I[XЗv1xeVx+idF="O+q~7͛t"7!Mm#4_sQ|l7Qc7ÛF h+.ƣbӐaPxV_Ɇ6&iFΘCr49Q(,g.(-ߚ\ 5Q.**>C3]mk8qFnסΉ^ $+pMPFPy#i7F*Kv|B8DOӉ)JBg22ޚʷQ<[!&} mMloncp3(0(E;\{ 1$q-> MRCO*XwgZ{ sb gL<H~ߪ,w 4Q{{F 腜0: %~^ްğ#Շ) q uF äط5%rkvl.V`;{zQi[03P(1&eaf@}HfE'gԭr= tS^0 {=3H9AoUqS4@4`@Wyj2ᯥFt͆JD6慿Zw%h =:,QBpp-xETB<@÷<5Ua47{k9Iu8{]L '7G,Cn)dE߀ϩ${OΞ5ejc̯tK$}rRN18_Zcq: U5R-ylЍl>tu:;?0r rT }u1=oO M.:T+ɀk g|LuF3N+9R=g{X}h7)((!GjaIu2dqgu w:=S_|f=gA-'Dyt$V܍'3 "9Idl=?Q~tuV"7J[e%'ĂC;-Cm 5Q:Fӌ~su|>_\*0*qϯmN3qq/ "$.aޮݽet-ۇĊxh\.?hN-bF[_˔EORѢ$(B[$ۏ']"Y#,j\] +HGu]Bcb pD!WWDSevu|Œk9^%!UG?οQ}i-nUЁSX9%6m#h6grPC5ᒌ@Ā8p?&Bj(8?Հ1*Go(RVE២ҼE IFuPo%25aXzwT]"[oK/oר#AϓRNBJV,W\7w h=!yI~İ& [a5: :=uK]1( {I἞k @/RQ}lvrfBž_`ڗt>V֝c0EytPA#Ns_#.21 tȾCUˠˣg3)n<ӥi-CZƴ>t~h$UzȉO{{;_Bgo@inυ_2W-Bà-'Ho3쵸<*~*a n6֑S9'+ ,zp8ceǕ;kl? hcD P;pA;Mj+#98!+xq?I2;´ߺՅ;C&ɋe$gYsc Ƀ3,F d(>GѪ|{aΧ pcg}x0תvlG.H9*%`૳x؟uGG+X:OQ?_Ckg/i[n$ HnFVًқK*"UJ/y-^{ajXy" aJiNf\p`X#1Wޖ\L8Ff6ږӏiVӲ,,|MvS݇f)o KUi>tpXQ I~o* *OYVsv=@jJC5n3@0RMz+5F 0j@ , (' AΘa@jd\.3=p_I'֟vB+8">C2L !62,D9euۅH _St1e@K`;kur+(,Vb;gk]yim\%FWnjXSP~we}Y J?!661>;ԜHZxTES'_ÛiMF'Vd$?E[2~{J"p.TY9hK+bְ _y>uSYS&>!a}t/IghΙGOY!lqnBU5H*`гۤĶLv {1|}J>ռ.MMEM$_d<z^x}{;PكBp @ق_yWo ZnUp^Rl w5١HbjXLPt( qHWzZўa 1 !5*u*#cpc$Ã{m{_Y7tX'N,. uqGs#n`3˜nX4 -%_ c)v (BoV43 )dJ^}}^)gm %O,ק/)h.7R5-U5oh?I*}w).yE&ihYafbXPu>ٵKt^{6/ƁIc{/]';i 4ux};1`xGfu6AXK<DwB7U)"cNl9[E̍`:b'Kq>D=kA\L~SĄ'Zpf5>Fya\/\5`XRXL֢b3}n@c[CIdfW|*1"; h[SBF(T4S>sqX AQz/*5`zKQr;>YrX. ;4-%(X+-BaqC^-m{ڢml=̩2m=!5kVCN=޾$ǎ[g`|6`'ą41zjdoBv'h_̆ b!8ڙu\ǥ\K33 |?' wiaL& `A|Gk+.8 AAY?݅K^)7>0,W2r+׶S "'l"N1:Rck$7jZj$I{P5{@LrVpbRub^QAcbꙋ)+ԝW w=ȸ~'Bq; \A~oz{Ҫh ז,z]+̹88Z8VĵºBwdłR}>0vxn\ֆ2'x{#fBE$Q^V&ݬqc"\"27I_d2IY,Bt_qڧ9qhl)+4dNt>KF+3h*q`oa̯$qT R[.+4,|—RK4P3}!B<B@zH-OKEې=g ǶI>m{@XU&8d;3yI{6ŷzk4E(GNTs'| NE\81GKX,pk'#B\vՃ6}iݲEO ߅S1>b~ 1{-3Bf82]Zox))b cG!)8^{=A /^s[٫nd,C؍@}(d >uUw/n6zU쇴)8LfсoI:}_/m)gNJ`VOiNf4䑥{PIH= -Gzv񩇀Y]uM[3hN7q\#?r~:<<]7{$}ޥU%[jR[s,/.$'Xm=LoA5U06$.:3{l];ym"Vk3$.f4z l~M _+׵RnzpP8bff iE 'U߲3=Z}g5U{/~_Aꇁe>ީH !Ru)ybPjSi4/5 B2XsTg:nMS@kGMU/}]A،V yf~!+%aȾN4N!qB^u'NiS5T59U l:$DHmYv+A }R <2:\оC` ʽ9iDZk ~NR8r3+|S梨tI&b,eG\C/zCAMy[Wx0ۜn6sǙv&+;8pkK l-ɠQ̣z5)QVz<3w8{pH7e3C2ԲzIʅAJS~S:L\d.~⸽WTja2sgTgVc'_huFNxS̉vofҏ0%k| >zq>zxR\uIe ~6ofNp$N^@qAg$Z&#[;dF.Sbea(yq6DLK"O y8e|ߩ.DEgXA\1d6WZeDfqC_RMnͩ=\Qʱ( t PkN(בrVy9Н8ξ4; HﺈCgV* ICmVA'Ј ƚR?\vQ"L@1STr 64.b/ /}Կ練g$@^mEN㤕ÌOym=Ol׿\IUFA=gƽ?gB *aSwL;Z /.?FpnCuT6Jy7TX dE{'3[#$'a!7RjPeŋ1loueJJ0 ~V,H)E[ b1/PtN9\Q;<B+4v  Vkr1ƉW/k2CF5̻d-"1f"?/ mzr,梖-u8\|wC62 YYGb sd [K: 9u1'wb]f|ҡ:X(/ ) Gd,%r?o]%Cϒ qSZB $Гb%QydJnO*;i[kjwЦooʵǢͲ.&L P7ġg\z(,bBz'~9',]Pt#"X[o_#y䟿˴s Л't,e&3';Mr KRD#qmKlk %:/ԅB; ٛ䱬r7d=Y{~K  `y:9+DWV//k,qF6Z2Ail9n$my=Xrx&}&NCJieA{;3?A G1veE+SD^sELZM9 | \D5 {Ӊ{{ޚܲ8æ!]+YHj#䯳꣢Ч kd o̩Vl?gq6(Z#{yN: cB0|+%>cFz:gD"HٛQ&†a׏4n|3昪N9F\K`ՆoK\E~ ?D,Pn2Fz$DD5^1$9043O3yBqĈBB`IO5Y, L;{ ýZRc(y:ڭô8F;zc 9'qİN͘k٪Zy2P6OKS$edPb]~{:;vT_/wnU3r8w*P_|pbҙiAȬF}`س5*DE&TexWr.!.@G:!Gئ0Wy)xr'&1ӌ04F[ת 9[/30uƈXG?>,X@;IMw` ZMf|X(9_YD,N2IPFn G>:[L?#)&Ovaq`o,ןHdyX6+{-OkbN 7sD}zORV)?#qpYM]<`6 %$ݳk3+@ XL,n8Ҋ*v[Y]VH! Eq;uh7}￳UQ6)*y/`@+#JbÁ,l e:x<+@sZ ,?k%zH@S,hוM:2>D ƒ W I=00 W~/X,6Mg9 xwdOW@QS3燾+ 0p|7\2_;iDFYۯI11O<3<ϻfźbv}6NOw5bs;\TAn'_Ѷ^FZ cǴfr{(#eetL/Ty.&l -[fg! EbFb7 #_hTECSoqO$^{yl+?T.$U\ZڧrGhD,K!SY\8;|$Vu':9P0ΥI`0y&+pV`kη]+q8RdNfdwJg0 "Ё5䟦&馛;>כ`8|QyH"(Cfd=w.(ǿ vbq(V)\ gHԿ.N>cL!sD23HZޝpb^P-~4>W=Y}j<rd][}΂a 4t)=[@Rd 49 =]M q•NWyfrfO@2Hsxb+Nl%Z Wc9@0aE|7 52}4Y2O[8n1ciXC&Ľ+"QN|L{a@Y>?O 6'WCءΪ̦)#z!@lT= <bǶ:IL'΄][JҟkΤŢi{^OOe.7waH:R/nms v6'"~Gk D6j߈W+tr=x<XVZ97b z!p6朩onܘ mGQ +XY¢o lT$=YC}K!VW1O}JW4'L{J*V_(&qHGIYn c&OӗmB.=GC)J6俞j"Ufl`!4WyO$ 5sXd .RF0R7hje!\'~U/聪P*dL.{)yj4/1cl{BL8$<Rh&)U‰R:m<Ϝϒ?ta(,hQF8w+khܺ=Ds(4A#_NeS J9t]b[2 NC teLK? c[ L㪇B*s\fNWf7'kdpGztכGIc$وɻ2ܔl!m $bf&T`HUW f>NGD } ͣ{cR'P"TA qUPK?d}>wr ;wO% r`6DǹaL2O5pd&XvtLuOx; 6װwGGőjb][\(GufR8O&̳NϖvJTvA17hМiO/G#s,ZN|~^f{/V'#SPp&>6!YAk(T+gq0u 'd,RPڬĬ?ۻcUh2; 3 *럫 s㿥dp[HW| լNF>S"6c!͜[QAgiφ7cl9,-47r+)pa1(Y,ڱ0晁GFF7,M񎲰_{BUc6&|43J-TM#_}F)0_'oJhswyTÒ {srXY?ے &X0GEfxg|2F%0"S )qw}fRB01s$r=`*W,XfF}% rx s j"`%cF%U5!AIg*1Wby\_\e*Y- БmF%sѽ}| 4Vǡ0dF6\Y#!+*P h5u 'b3)F6㱛f7hR%BQieg\Zqz ] D.yxɹ.h%jnb>GgCׂEeuff^RoJcQq%k@Dži^U+nt\>ٟ4zu ɟ/rLnF)H!%}{jUY>1P܌*E yn~{@l'tZNtNB}Jʀ}5 )࿘oݘB-kA(a5Dv(xUx)|Hz>c'2q=qC^f)RN--nB5WՒvD&[)ZVT3,hY n|o4LL1klKNdΎr*+:^pt$%: 74.hʃI㲏/N0@E esRvӞ0R9LRvuQhGzMwT0σ2XZf[1xrhzxjœX7DB}/VEM-!ιA-@G8!:B￲)"H|f2T|bN.؆T5fZ܅s/gs>U^RYa|O/IujТF1YLbٛsըk!hXv/@P|J?5lռ)z'!=P*}G/Wx=4US!2y"=\4Ք]9ۯO^{0.Mfߜs2|jV0.> >lb^ta>Z'~Ǐ4rwٖ2"ѫ:dnV8e+z[kt(1\Y%=jc5`\z4yM &@ tjNo"mqu+A8dW m8F\Ti.Iw•)_ߓ0G-67$?3%%QB0Q Kz_? \fN鋤̣;0VpqItkMcGWy~g++2{5áJ):H` .1u"PsK?R6w ZT%hJ||,yq8Zs֪wE(Qi*_dӌq$,]Bڕ`Eh*|CZxRv5\=Xq %S @aφiG0#D ћHH\.4@SjnJڧ߷LV3]~o ǘf<)iӡg5dG2qHY2|ɏ]'03`K8$D*XZPWͶV'~pT@HQ&A6R2d8>Q b~͂Yo7Uj<2OAHC{¾oHX! ovˑx 9ED7'9:mG ulx*LRQx1KJ_>I74'XjWA9hQ'U "An\1cci݋7naQ{0^$SRZ.eRpfn6¡-/u;[w&sp1%ҳ¨pdȀ-JyE69{)AAe>x{)r|* `RU~pWU~}6Q,d½l9*v@)mHwL*69(Zb.3Hkrn~( * { Cv{6z I{Xx*U8W X׷>RyZO.: f/[|ʢG@:Gq%!fA"-|LaݷgfH|fT i vv/vS~Uu?bN-z-E_%/nK,WT8 wI"N_ꯞ*(7%wnkJ)mEZG6d#\C';1~kp@D`ay%>^qґJa9fAk6rvDڂq?GEY= 4oa4 ɋqG1JM#ȝ\l9*_S!@vrқ1 Ghq) m0$yæ`$hѨ #Z.)VXْz>D=:V(iAISFYóuP\X2ѭ@M?Pbۍ~oncL  ݕn&,l}A5rewv/H?u䚚#[퀁c6g n+3TL(tVew(0y(2VF2~.4qOD;̧.bڜ.l  h e%>c`dr{mT@GLȡ681BaBp?mf(^ 0xn ݙ72hcQ(Y:!;ƃ@֘CԴSCK;y#k#ʅArĒ~#Zgn-'RS'%4P-@s x&Eܚh4Y/7&H !ze}hŪe&zQ]|d]tQ^ s΢<2f6w>)džyMq2dem~v) T:!^!%^bm2zc8'%SlaYTK?GCxKC5 ;qzONMH_?ScLӽ$1B>㙅a4 YkT'5)<ɞ5+rۣ:kup6j3cKtoa^X[ 3M@=̮=}C۲\!`7isi+iw3zwCxB.Hr.D8X u@N^ v1=mW}ti?GN8$ڏ `!(;δGjL;3^d:JR\Z򿋁.bdT}Kcmn6^m!V)p#n?l{#V&,zf sU8//֐:U9eKeTIpDDOCSFrmW(z'2`pd(N;;ɞ K5!XÂa\%>&+lZ3d@ؚW qv"IUcjJ 58gE~xy\Qw46$Aկ2!r/8 e7S V.6ܢ+&1{Q0]AUڵ,jL$&ccM 2sz_'e8"oED8U!,?% d64a)wf(!4 }BM0pWe[G"MS Nc isUZRaDR$I\0Az6GV7$ g:?!]06[HztLWmWLEkz4W'8}w 8XnTn$~  %a62U =T^<]":2ꊜ׍oœ AiXy pL/ CzIdQ.XkZR |H(ܳ3ED pc^1jU[t:9΋ 5Z_3b{nHSk y$Mdng0}˯|0*]>[!8Qsjr+f%ƥ,͒XQQuPCʀҢT)޵}"#}Y|S8 V :y 5c;[ix;| &lsiuԍڇ\Ϣ0+nֹvQ~\=6v3| >5PԂV` ЯbiDF'@wf\ J4ìqݾ4GQmmyat:rYi:昩c"3ix~뉆ʼnh0$A9AAARVH}i]I'l}n$|  O m\|z,ͩлqLm:xwZ`z# i% T tѮrx4[D)L(yEx|Ȭ&6I Mg1"]rN|CՍ,-Ϣ\*HLLuN0Qܛ\9!H 0 ;#G(,(PV#ϦV>-Oş;?Ha2^mVF7Jk/+vW~qI̧&c;EbL'#}(eI 5r;As&4\2 A>MJ!8-ǁl^; GՁ/r_E{}M,ZPc3m.NxVGB_J) c#2!䠨82nkS߶+{*-$ywHSl1^<2klaeqįلAV+es҆f/pI,pKB2`큰LfcRgmeC̪֠繓j7ac<ɿgr"fsV4dzT $#ýr:ds2xߨy;bE]XӨft#`Q$LT1$k0w>vy$;~#t(6Ǜ%xEQF=ڼpL$<3)js@$%B>0č>:&AӹYA?VS=v1@?̨31ƉP_X|+YE/)W%Uo`N! 3}r=2!%EFyOPִ%6Jf5D pUTl#Rumd|5La$F65Y,q߭YcoeY^*'+ ?ofc5;I}jvM w1Q%[ձd8ïG%s|_O:zDfEzjss֪QN<뀏:wEϦ vt?)s]vPH5P)_F7u@. # < 3|$APՉ׫ >!^@xH28&^ g%i.K2)_QA+fs˓d%YE`:g}SVԤZQһܴg ڴ[V rF_gsGӓ?KсRųi%8Kbb45I?uTkh@ymW64f{I]IBf+]DSV)[+~],zd Vg_}x?~s~N6sղ [?k{G ەݽ'%( ϽV=4`p G (tM_Cw['uk4 $]mmg,^C;֎)v{3@Z q%@O'1Q`_/هJXO/ [RW :`fѹ CJ˟y:ӉgBrpZޛ p#*:N#Ԧp[8Q::;޸hqLY(Daa0v CGD7E. U:M/hjGpz ;e_sseZaX[`|Y.||9r7@ۡnsS.T W"fznVp\tFUJ.{*_&LIi6NШ"y|vz +7>X[u YŢhT y HB>?o}v`wޑ [AG11SH` KxtŨūρqT!?cAqԇ܍Y꾑ڂeVjQN:7d =0ǖRcc$HTh?zbqYqO4yۻAqeC dmj'_rb "}ȓ yv=q6E4bGyWn>>-8Hq]'xAt9̉l>ؕEWYuBT3gb| :&2F]RijX@oEdD:F 9ܘ&QhO<V?~;No!'%I'Bշ-$~5v1rɽܸȩJ~A8O-nPjgEل}2f?ueY$ G1|<sVL]݊KS6zd D[F-vB#UB!d %'` cЮK6eb5[jY8YLP׷_Ɵ/*zUxMv %jwLw~%q5Y("97B&3]'e&5!i66n śv},iR4R5_*:o\F9_h7zޒ:#3o[x)so$RA'f3L.nm=Z0m˸0:ul;ulbu"4fLQ¹fFY9k|"cz3A]1yu!CֿB䪱& GAkWDb7` -plաW{}&O>/Gg7 vŽR],,Ka]5FMZ3_ dĐlk*y}^tH㿈:¹mPJb}zz=dݻ,my6_sz3㣾J[Bbl C#D:ZNyASr~VPS쓏q@#B,r6}Po$%ۖ[[P[ nvs/&5 3;Δm{)3bWRՔ$IJ-/+, T\lC7&ϔP7j(<5VŀJ[bM0gg6R1Q}tYܩm{$ڹY# }z-`ku2[} qVkT%75 ےq\۾I>}M̈́|Y1Y^-52;l\l -F ;n}ĵ# ;i|+շ+ruT rCC"ZgfIK/cSl(T̐Nyes ɈG`"m[nBB 5Y+K.<` N=_v[}$s7+Bʵ)4U{جQlGsE"b!n|o[QՒYh( o,>oS~^o(jg=-x{+j̢.;goD`,<޾E$yF.mYzDu9tjH%uȕ 37lf#P_Z!AuoK ?gǀlQPWZ7FԈ.gbW 9, TTpҿ z>fJ=@-O߾F=>y: ѣE*dT:H|KL魴 NTZ(Q/ ɼ+z '\I` ]bi=.;+3jqJQ|HfQGrBzyOVT|b_q=Wr.3oTK4gK.Z,:Ye˅e3.K?Y'#,lOD/V\yMo7?liq>/{;˟`TO ҫv"eeZd5hCCMCȔR|Ԭ[fwf#cs]Sf&ڸN-0*?pj8S;̝D,SW|1@3@I@G%yTT!bh(.6 a:%kB1İUe\~PdCL,tDZPM_?|jzL)Dc44>gϕp$`#srU@ wu0M%YZtx1JwJ$9IMo]+~ 3&k"_RJW'oj#dez,̉Օ:#Mj|Bg~+ja߉+Z J!b>N7Έ2\oĈt#>dŖF;VOi_A/_rիAdAl茫`E&fjUx0L'&MT!^uY{-2+U~fN-}7BlG0TYsi9/.':^T4E/:Pެ _u,j>i?S0!EW8K,b(6gί?ۙGP m5G݀Eh0;ߵ1CNNmBNi9j@-o+ZhjǁUHI'3]O_E>ؿhf)ohˊ% 03['+"ߦ~k൶qB G\_jVY]O?u- o 1ީ*!J~m# 2/(4AH2s ǖhY\):N{+cu2#nHos1=^mLg6lD(jK|V̋, ]`-R'7KtKv/=`Άgυ;֘B[]ApU , M#\"!J$V WSd3_J;p9àR~Ϭg -*MgPKަ[NPė3=oQThZeh~%5,q laTDl\8֌98.w<(iSo=Ry]$:$$dtV8A-snۤ_99 8G:Dϴ~f[* ޙt[/eBJ2J+qhaXr)lv(1 U G7zH' 5H=}#HS:h?z5g͌&t%K-4"c2ULѬ[܆86q[$ɣb c􎊽X3 :? x!ZQ?i 0'Yͫw5jE=D@1t.A`[ #jzf-3èw124y {z հYZ1\|]e2ǗX^1 kę후N3j 9"~}o@h k ڣlG2w_bg7VJ u (72vweab1H7UO>Kt"wӶ4[VUFM>,ʺl (֣6 1- H9T!Ϙ < EBS"\ T]/ g U^D_ge)OчAW?c9L1 > mWGkxT;Heꩃݸ99'/{?fF$x3gO[XIœ 1d%Z~Psnڷ*$<]mKy RK/2mlj|dW+S_j/GDM ZQIոES}!#1,K8rCL4ڪ惴_LjV!VۚseEl&ݪDPpLKgc\~9Aast n>s>*tFؘw^/EqwYKV%v뿃 Tv 훓3?˲!wSɞ7'_Mvcڐ}癖 |;nw(_/C q﫶?̂$PD(6g a߫1X&H%92O19d wWd~_jq,O9fj:ez"16Cz^u7:Z// ytAF>^vP瘝cu?Y1_0b1 X6_I`{6yw)Ē2N(bhLv=*Mu'Xo o L~2"Op{'wjC^Db=N3` L(pd*oP>APܬ«- Dv#שA<' EF93%0#_%XƉ q& 0"54KE4*y>}qvcXXd97~0oͺ y)X3QwR0sZ/]r>#_E!.譑[TgVhufX;CӬ:4:Fxcy+Ԛ6Oh[PYK'Pj xmn=n˺ܻ5]-]( AS3Q% MBKbT&r8 &ÇJ˪{5+l*e~. _Z$3}IddюEr| Y"qe y jt8Q{GE؄tUhnk%rm~4a-$T ^ E}|k; R +TK꩞y:xDoZQ`,!~2֭Gϣ'س-ioDNaePԽRZʵ䯄GtD9c/4&>IPX =-3 Nꡞ2_/' t4xO/O\gcF*Pl($+2D!5l$Kf|~KT3h!Z @ͫy pfE$YJ].*'*ۀuetD}_n+\.* 1n}izNl.`WBwwgrŞHVx Sz(:,F'*(CDNܛMh_jȁL~deK1x[{*@P*BD&5RbrOs7pE+Չ|P JԱ 8>xv1Ut-8Xϛ N^}yd^gQZh8BI5Jo-iw@! +gk 4Zz?>#,- p#I]ۼ!;A&. @Ih'GxM aٱ3*9c_~EzYֿՒ-Y[S<ȹc1otJ[-Zǎu lB߁ׯ>{o~u `ώ }ges`JrIY7=To@{Fan C>AbxJUf"~{&'g7g6. >9:Q#Az+UsgS$SYf2C{}~XJXDJ·ݎf4?l)(-϶/;E2B~nRvûėJk7Tu&|# `@7[Jw6B`OdrЂC& -݋Àsudmnb 0hVÈIdFAKyP䏰 %;T~)BEG]t.ugw&cִbUZ{6_x2'N:hU0(H$[Ƨ7K'Շh*K݉"QkYt D=٫xEyEl@喴8n?ld88u+K'hlZw;St f!; YYBdriu'Clԭ;7%WY!&^~Ypmg;a).I0_}(51MD7tdڅ!Ú!m\}%FT!E 0|10! /|4]'<Īdzn0Ws Tq 1}pc!GJnWG$2(fě67FD@P86`q4D tҊ{-2;zurpQU&ܲT8^1qDEDDw5cbބ/'k)"/mȌ(8 Q<|gNjG2j.ؽF%*7+;&4RqeuMN T`8CH?Ng#t8eyxO_v#J aIC]GfB%"#C2'.zm?aO4L qR 8`r,dvQL^*Svb@':~F@eI> {x-z:eґce2( uEƦnvi vyӰOl<7(1Ca@󞪳#@v !co:X9R&~YIdj0r^0٘d&Ë%=w YD|TY#'1btǐcԗa]tx]o,X@u[qc5ɄVX>9MHa'JF9N">b۷j>$l8N6f$@1r݊G ;㲧@Uq=t8tm 1%!iaPט\FwVTR}y(NUL MAѩSH@0(Dr 0_!ĝٸT?6wZ|eKPi/p%qX4)>) s5 TCdXB6lV r )iMP{RU*AӯSݯ >1-94p\9,~Ƕ43di-—*ӁB ԓJwNpG2s('A^V{]tߒ{7u8Ĝut3]zk{w/?fjl2Lupv!jT2mYlMoSr:;pǏq4vCy̣Wvqd( 66^9{d?xU7}TVX (Ʋ-U1wZ[DA n Dփ+9D~Hi9bKVMPN(;DSLauwSKKcRq"A}jnfmA^s=<Ơ3/&cgx6&ft(zWءkNz\^*jWG;`wL] cJ\#TA^IOs]HʼyǸRqDPc3nT<0s_+1)DJp xkaPߎlAfn1$g WyBy4^HwKZi _$a{ju˪jVvKl%:iŮ_Ӟ;&;w_&ݑ7ED`}/ifoHKFhߤ; 6}hpNju3Ml ^Ql*A޵poVjSlݙUGb+ֲm +JQQGl{=?gu\w'ڒ~9KsdYHp-&nΗ+ZE4Z*y"SF&c|Fi HQF쵈{nMSb:Fd}^{¬`2PgM?P["z526{ h7f.G(us3 h??ϊnmu/'{Q|%bR/݀BG{6th#>lдVOFiؖ.бomڿ=7hH5q6e=|#{TЩxZ*M:Csi@G&UB vIg?j4:{3{(;+"\̈>VjnQU]QH_FS$m%B1Wa\ #z)8[AhG.P _[M!@79-lv7*HP8o8e?glo =8=il鹦"?/OyѨb ސiTIˌnas}˘Eو_o=<(ͯ'5;0RL3t0Wω#ːFԲ̭_ qKj;/ UHbg%QVl: "{pX¶on"qH7iD4K`a P ڗuT薨[*KDR\ZL4O.[<=h<[_ MY)qwJ>N1j{͌I6D;TGSwћa'F87f"\^n? ?'4Xɒ!c#UoA44W.Lu'@7I=7~U3P) ;?> _5vpgq.9!8qNv5wƳn'=i?Ɏ8w.\\; ^{qN, MSV 0a0{-dҸJ05~C'>4pqI|K{9sjjzu6c2+It?C_-S]8LCMdF'%_o@?sߜ5\Еvc%Z'] OQWTheTOjiU҇\BrM.jVp 0M*{n[yű) /GB$@-e*gx茟+{iYB!rvrEr"!Iq^m!;*`^oQ!0Ӻ z>fffZUz=Y;Ǥj.\im_Jv(~.;UJ MOxs>]- Vv)_U1]׃ߧ0XIBY#J3 ("33N< &iynA(.I^!Y^mxz_zBMQʅnxz>J:_QdU=?Tf&aXK!;حx;Rje[Y&Z<* 7w਀o7|v(sI9 VٽZQ߫mX,Nlp͝zo`Okj_ZO IIO]C^ @XiS陃ƭKNuGgb =0^Dny3GX:lrS㐏ddbEk ZzDp7%E9ap`b@g!,ҿcZŵF!, ipŽsD3xbz2"aL^2=RkiU]hőigaդ$QO@ [ duYq\Pt9LTJa99[d2#k!HH+_ԙW vDAp7'^!ܬ yj"]Ɖ&z*yjXs3WPyWng15Ѽ.s=Dcݣh] .|P:hɲ,Aeh01`Tz pďY~Hřg`5d0}~^RmZ0BF0H!Ls-R YêJW%;[X>sF= 6bi#@GsӸ m]O _KkNځ|!"%⥷sޗe!.Y:rRf.cрkٞEvbT-v(([RY(&ٗk ~ҳW~ ۔XŝQ`G/n,Z ;;*Lۤ^.&lgS佦yy/v9[9=3{o7W1] ؕ@4ςC8mǍa |^O}bN__"Nyaq 0oR\b)ol߷i}> !=`pKPG5nwwN"cۭKrC/Cy Vr38yO)bfO~|D/Y#Cv:7?aO襳IŒfC]'ΓU梌:p% `n8JF*/KċX"YGHjy3lqQґ ФCtJ$֠-}\X6H *YWjNX`FKנHk-%ε}ſgG$V %ehYQm5(ZjNa ub7>kɝ,EJ097rK8|CG+3-!D2q)7rqg;Z6@II_vVyQCTΙ]*#+yҜ]=5/ŀ&Nqo0Ƽ .I<`,i4Nfc"iTHé 6=w(3?TG7Q'p0䔈[/2݄`P_)gaj<\!^[>̆( !)&\vE}`zQ M{V qK~S4.y/}*O^hhWQ3,/ջ+S{-k7wrw,z*DS"\j._87ZQqY3T"0s!j[w[|Zx7XgizH3hQvClXu&\ж*ӹ$`8Һ$T^RG(ku" ) Or&2v_usL1[rN ݙ) ZI'%tYa7"ۗ^Jy_]GW8~s`SK{yRmk*VEeyўA~cJJFۥC-$sVc\MKUDR72P(wqbJ^9U/|8ŚR3"*v7Qs%hEg"gf Adh60V8k}D}k5ոklm'4weQ-lE}էsk.Ǡ@i4>kox/"p')kOKӒ|M@Ob#t@6wJ戾c~ɴ]r;e\i2fu|epY%9ww^duU,[K^Orp&D==G_}YD[Pc: S3؄ Shڍ(u,~ǑέAeq*b^/UEDaY;/!b*MN*Ƕ&jB<5vQ WEl ,ǹLDJpY,&9I5RHFe1nLqo!ْ|[A㜯P}AdGS_$jxFN/:7Iw+cx-/E%LҰYʱ]'hƝ$1D!g*UEh}r:b\*zo9"+T@eKX?q sDMpk*B#SRjo_=*Hd@GfhL> de&ړH (38˜D!֊P K)$5uw)iI+|.٭q ˝섛_P}%>nO  < ;7T0^7*wBC4\,M l@FY ҏ}-|B-,$؁kd']OtR-<-!>u%B|ˌ2q(;ъ'$e).` T`1+s%;؜q4r)V]vJ ΧlmT>rpw&$^7ɘ]Ҡj#- k J ԲBɟ3?vvEby/sKi?fu\x\(H&^MP98\*/9fCEҥ|{\@L04NYJ[@ {,&>DB|M4z<AHae^,k98129$pp<*؇-& USKGA$U\RT73D-+-q:O_S\o6ޝ =ԨS4"(k&k.:p(P$Ecz'Yފ(}?6vz|)*S@t隀 q,J@k@4fł O {g~߈dg^F[b B(8ݺ5)'3ݴO5lMj*oᴰpꨘ3τ8qQ ˏ6\H]hoַ3KOq $  ]*/`.cm& z;܃OSuR oBc%B%;co+;SlSӳ}+A{DApk(ݨ/P[oD:_#5 emǹ׳0-t/.)QxO/g?y9k ư0 x  CIbaGSp//5L8G&MWqϋm:*/6g]6JpŮ9Oړۺ@1%C_~>M~ɚq@cCT| ]ȥQ_\3:;?fmhF n5{By*np:8Ovc)TJX$$X"E,P,tĕ1g*JY% vMe+8r)S~َJ(z/ȩ^w&3up}'~}>1Bh̋ᶨa~#Fv,;' FլRZ`+ eV{}raFӚ( '6ap ك[A ˒e̗%K5!1h?}}(ŐgY@ D6  B/Z L7 %'<=EEMA=*CMzl1ۆ& lz>嫂m<_kl>#YHyUr_FKEHcR0JVcLc#8ǫDHV&dC]ms3RnFz (RځMI|y/yY+?>UٻL%Jٹg4) ˗z~Uq 'i`>J縴h"ZG\f]ciZ7@ֱ7ݩe?cP6 Tjq#\C%tB;5 `Q[(p ]J>ٝL FLnث?Eh3k+}7"[8h:PygFr!~Z+)W1-rbZl=գr3j%h|8_kn/U9XndE UE2mvPzosv_k;5vY5|&} ku X9Wߗ1 B~Tb0Na:B )yhY0MbǨS]O-\5 LE XkMѣw^֥81rÖAVys3QMaT39+:4ҞsAl0/Cn]~U#3R1=Oe9ˉ·)TA -b?^9,SFҫmH+$П9{FjfA2 ThF|29nj+mYfM%=W s;|W@L.Dүo-%YdiV/v HXO=g0bY(L!aq~VosܠH /nAcFEOt"NNQ+ژKcHsg @2qp]񀘩 H2KBc "(gtb`H''=/}Dfmn䔳+E"fkuM X0`G^Y;|@~Z~{6C)M,'._kRDbgNeG,H2W(z6[ ˷W#f; ]cf ,Ȩ˵pӰaf)Dxe2CQv_IIrp|+m0̵E5ǰ+Mh~&-SmMUfahESGdiҾơ*mUn@ >ԉ{5D.\{2_Zﻒj#5Pڃ˭Z)LnʳU2˹_iLN| Q?HE3wJ_a2?FWmoQq>{xLP*; Shʴ!Anջn2\h S mC@Ej*N@$x*Vԧn yԁo%8cB~NvPJE#)D12 8hQ(]w5eC=,)])݊)!ʶχ?k"}44 cf-z9I1tvl &.=P6~ivͷ.E 'vaZϡ}]L,Z1D.eA`c@T|4vݶYS?1E[6mb_g)=_;tשUbN1'&4Rs1J=eQ2!8Q&6IQ4nDžLZ3WS<ogQȬs{K]6gEk(cgFŻҍʴob$D"můL*e4G!d4.8,$@!Ҽ<Q %#1>N8D",&Ak0q3AhTjV4O?L=ݐ,Y)}L.5g%5b e. FF/T©rK//0nT9)`BJ2yⅷ~_8hiO2ak,NGN=}'gi ?ϏqTR(A}dz)v}[4{1qQZ@6cőU}4lfCc"0bH]5g]d 3>R#JRM;E/[Q69LzymɜVH=qt<~uFiDvdd)Kr d%M"1%!̩80/aG>Dd|C FLVցH]ECd=Q(gI*M‹_JB 3EbZ*X@q9-8RLj xU%ӕm.{g`C"QUr@ks/u~ L.TiYPjC ,]Q ,7aKeG2uVbx;#VΨ6m`g7Toliad3qBK\ msT\bi=9eW>kxRO7eredtC8ӎ_(bk!׀<'}ǫN˟~pwaMbjb#C  ܞLa =wqVҞЃ*mmy6a# kĚsGiqÃZTb1b%_ZouuCr ~UV/#1^Ӎij: E^6,  <:E]ԇxe2y}=cŭ[-XyAHAjbXt 5=^K[WI|=lMRbo8AÞ.۟o7y-$Jц{+qb`%P*Y?fdV.t 5Y7.bO;6&]r,LM9`ԼOe}RN/?dj G%B0h SQTrSNo,P2~U=_v3ϾV".a|cEl?q 4|Å`Rմw;$9BQdQ.n^89h͗ ˶wqkj&E.lW֬:;#ٺŘ% ׾[!G26M-#{E MZ{i@L%}!vL:ܠ,~G > UQvAQ,V5o/p*wTMnP en ǁk 3_+?:QFFDT%gF SD!m>-݄*EV!]Iyo?W ʩxI(ռ;/dȻHEha؝tg(/[A r^y2SQ @Wn{a +Y<d}rݔSpXJdYe*{Ň}{-T@ruN RX6Diي ^ %rVi@8̪$fib5Gg7N;4 S $01ڃ M.͗ն qטV^V )/LհA4S]68X=&ZYW#|nڨru衴AOOF>}H1Sp^6R!0W*|fPǻ',-1<4@z.N;kHd&x]nKX)D*~C K SIR& C\}nH7yVa_w5 |u)DY-C#tHchplEY1jL6*c=ÓKW ߵ3ghAWwxhIA{Ϻ V̺ӷNĬ:!Q'4CL"4߮rG5=Cp pifXn o .[x&}K PMt9DgִW!΁sv쭳@WC>%U㥛x *c%*ش溾$C>c^8)U"٭,!\0zɡ N NF|r}¨z>ЃluC!T{#_L|=# ׄTP $W.y7?Ewv!Dj|JgN'vWn +\3jDկMlB像t&z˔zp-aS6'v6 1̀Eo%N hqe}l[@GOMQ$1?g^:(eϑkMk`9X~_;h$/6s2f#VF^YJy`7m*R4yPԎMTYa{G NXv_?  Na L[~EϾCdt;3ܰX&|k%׺a>G2yj=# by#cB S[lc¹tYS2I*FoW"z,E*5EEK/P7Qj:v@16јJzkHۍF6[.eɘ-8/[YOλqUOv51M~}U_<5mgeCctxq^:Ͻ^׭)A)+Jc6h!`\ANczq:i:`jAxqGIv9z0+0'"4#QN&kt<3x<^@gGXY̴xq,,$.{l9HGb-߿^ W? &PrMɁT&F>ƈ1ԕOAMֳa:41?g18[c %Y<vz" i;䲁wCu Pf4aAd(ǣO7M$R/tȍLSF϶ }|;wh7ɹv zy`;>SY8֢vmYhRtg2!Mk{oRw^ LI8*_1auD~",'w-D v"hVS~Lh[׆jw'=T~X^ueۯv:p @*тnN0\UW1\Qquwc崮ds(00R3Z-#Dk[i-Q(aYd ύUR:3q~o7~R!gMn|uG`r?wne fGnρy>1{钕(KY65hquc]ȏ/n-K:ԙR#TM#Pd:ud-Op\Ol#gZߣh,w'qe{D:7%?q ў[dq_cDBs?`LY4VӋӭΙfWnd焤 K+:2kՐ-n1[IRZsbb:c(aF7=tfV &\}BP&Z?A_a 5v+l k? 5~{mh-kvbWBmҡC 'gݵGIpE %Q˿|M&X) &]m鼻|<-m)n.+yi"Nǧɼ]*Ą+&6^rWc̼-X(5Ol*iau222:Yd5M%q}jAQ6bmTcn(t|\G⁌?jB GT5RXXsގ 2CNkz4obUzԣ3͓rUqSƾ3P!Tn{sWtk- X{zhh8\˗jAƧ\֟#!O`[G|x>p썗ŏ\IO/NVnS t\%"k~Ʋ7ػ x' TɈMi_5^l'ZkDBtp0d:Bv^ĥ,Xp)N[冏?HnF6&K1nK_ћ9ͫoGTē䙝w@0+@[5y-rhY*0c"qzvm}\a6x zw[ !EЖ.J w8/WJyyDy)4ϥ\ EP")[yK8l*{ \obYLaTd;VK3Fl#S*OZoxlk_3xzK:x@aiaQA/!Y=!u w'J6(m5w51}htx[}ܱ[fx /ܴ˓ H 0(XMt)y:C'~wQ<ɷx&oby9D/moPjx1bX _mѷG,I`$wi>\i;[J裒[/ pJ}{ɨ2d'}V°DDѵFY =Z.z'fNp]eH;ۇXลH+THV ;**Fc3 e 7!CgW1=Zq*2R;,s'%𼤌%7p9g`H\}|8k4O:Ve @sB/R",} ߁cUadx(>K5@4=zط+~2fӛb]E$u]y& P|(93*s%BEh*;h? 2H[}ݹQڰr$R\29{ fEݞROxE,4Cﵨ+u*eY8xߊ=#"c⋡RHM`)l'npb(7+)տ{D{m[lW\f|l i6ou}e| -_3?Ff^w6eqĀ+F܈]{<'|VNR!4FP96#Kl#NM&Qc .؁gl)_t#A!S0{BKJLu1#C!8ͬр.Pn"ZLTlol\$,v&!o8;2\/bbL1mL>%ǒѤ7?^dQNaQi&}m2CM454r )X_}pz=575.{($WWL̥Z?.D Eq[Dhݝ8tn#?{^ˤ,"S]Mgl2 zgK!M_Sla==Ba4Q*Ѱ*w@0 dN'D.0^fAV5 ӧ2KaZyLwk5//]f-%8W裂| \ ^Pa\k-p_-9M}qLY}hq-Cv5'.~a_vX!S!IQe¦f5\ ը\* h`1:Ґ~@73>i*|_i+pf; z:R .X{HX`w I҅-7+CCXFk*H$q]eD8GfvJoux3櫗?Ô@1GWfx6Yu}17tі0_DA 9f= JŃgM5QܮNX=<|;ﴻGHΦ>g35-tAi:x"c(s0JvGΣjrp6f K_PݐH9-XvcMٴ+`Mfju`\c ;44 ̞ a\_!Q`iPɵ"Q/('.1D eU%q[x6`ͅ O^&Ά@!|z./o! @{.V? P l>qb$ؾ*@%2w2WO ٹMЩ1{BQ2(EDIZ;ñwKb]դdmQr 񌥱D+:ecϯ G` | ^{N WZZ;ʬC;9-O`t]OMimBg; 6=;z(G9 'JqL}F;E=RTXC]~pNL_@H\5}[XS12vSw&BKw v@:<VjQ勌D@4J.w ĝ}R$QCl=ڠv`+bO1 vIVAS{I#=ȓ.E=T P{W%O5:z V !Ekbz*gʚx]pc9o2%5Cշc-=d}UA<췐y, _4gؾoMyրgu ҏבGzӴ~W}E9}г,⫾4f Si%TA)Jd`7b[ ?ԂaNXtݍ?1>?XJ[.fYD:I!׎Z m:n:V}{bÚ<!P?#Faiѫngʘ82-+eZ88 ϭzh(sBD3/t^*D"L5& ]6BVZw6AX^ 'Mjf*jJ hzp3 a <I'Ni4̕DH6<|$D;U"Ny1%2&Y7cFW9hrBd(0W˭jHr)DKHBp7K72hͷhg ~] @܏7UeDVqEU[:]5aPsx;Wԣ^=Dϐ/S:BQ|!}{up!п+;\:y !xJ5+_[kt}Bw Bg^7SxH^~lf`V:2}+{&PHAyJӫw֌LyrU%›Q'T֋k¿cuo\{ʖum1J B䍟Pg7NBjGcf=v=*rZ0UPZIPO/ݹ !1l *2a$PERͰLT^oIȽC`y39xF =c#ɬ;TTe hISvJtŀjXю}3?;I[;xƬe?*CP$r -0aWV?LdSe;xr>Ʉ9Km&,f}PV#iu$m A(ȶb,VUZDWA&k#fCi>!0.'!MG?5PGIqA yO0#ȳ8|= 2m\$,$w8dw |)Pk[AS-MSA NCV$T>$ ΂m2U A| ģ8ܮ"kaAB)ؿ@Vb˸֘̿]^.i"O0cyÁ3k&=qo2Q dNA t7!gK`Gf0:1kA":peCrKD)W^O "ZF%3vީgP 1KIN=;$G̸[*#]JIW* FXvqj7&A'w@h>Di1UWK{+OGgrX Q2t(8b(!occҤ) `+/ldJPj@-\~{:rjgbk=t]oC1ܙWJѕiJ@mvq44,w)\TzKHrbƻ~yU2|Á#,8сAenf3dA El8D~RϔVԦH,NP+uO(LX"fc E4.1xL濼cLyˉP I[l;KegTv'-R5-pK3T׹>sF&sb-'~V;z3I ,A{.Ėfi\|d+D,NqPW_%&S ؏GuJT.܎toW 3s,9T&ܕ\GAJRc/*ux ߒUUFD٣7}*itq xx7tP$Bh1@ KaC!vC7s= І/J4.Q]IY+DP*}'1W͊d%^AG5<#1t4da<7s9)g#(a䰿o,ђ cP6ˡa]II;2zg\gۢ-裏O/9ȳ@6:4*_o㒎}r19s>{{srϲʊOZ-mX/:3HOx%W{տz8bf /('՘;[UBnψ!Н4QE{'Ox9+У@%kEF#Lp-|?)EdYۯ Ϥz=g6YkV]^az BDVg1cϑf0^sV꾚^dE`JD.LbQ1:{2]  pi ̖k>$LPW-{cV؋Q6):?B#HX7/|хJڅKPLb)Q,`DF$_r-Wjԭ!CfZS0iF}/D[]",Ϳo&*M #Kʈ>p$̸ƱD+v\Lz#E5mu/%>;bZ{Uߴbn['j f3h+1%E=b{EJ zׇ$fSM3:ߊ~S!Wr ώ[ߋx ڹd#9#l]`F;!<sC+M+A0G$i꺝\T+qT.>;JnL B^s(S6:CzfbHiRC)4xBsV&;&Ӝ|Pz.6{"dSOc!1K 'oů\7 FheNkLaU¶ǾoCY]ͱ'dg}^~ 0G;j癀9 bhq8.pFz5hN삽qS>q&Ou)xZ7sf ǻAVXuLQ{he7ה_d|o[G%~l]WvO8]( x|A1̱AT{eqTYo*9D1y璠2yQaR6nkm`oO3G;2AL6Ldd,iĜ:9)ж'ΌЗI7YDϝ( j2BAIy@3&g>WR!1pTz6linm>G|QɼvYhY|5vuLx!mHʁ Y<8^4 qq<<ً\keqg{Uz1ڸx韣8 $莤06/oscZ a~>K@㩴HqWl6t.%}Op_@Į b,!Ĝďh[k(:9~~BKaln5+Jp-_'eEU#y*x~nc:F+Vޤca>ECs]gCTƺӤۈH*,9͛xVhe*2i3yŠ2Lngi/L  N4idT 0dxmظ&Z]167hmxBT@^JH͙JV˭UڌM=XZT.-kfGQhlȾ,[ K$Ul^p: ڽ8%ٓ=)kL'Ҋ\Y`N}:`q* j:9|_emCDdKɷ0gsb#) qRRm*yc~Wߕ@ü,_#t<|$e8pp@s9̗aPHL&b@U1%V)ЇGR Zi^ "-+TSK״3X=?݀w< E 0)*n6GqJ\Np&DVDMq[kM9p:8%_ub6 lWzr$.M$"s- 6mg*Uv] P46A뻄a RԞ_])Kfdfe=0]$P +< `3 cwHjJng85Hũjr;'KA?*9 |g2Tu"r.DTyB ֩ckA>)4&a2-g'bʨ~1ruWRCXd9e |KFO|.$Gg7?P/=zIS:z 5 zH 2߉deC/Y^ R> `Vi!HZ:xA؟⍗.phUWԒRW[Pf|r2 qհ !Cylȩl"ں7n7NS!RV8hsF! 7U95'*}#}7#> 1D`iNR ]".!0qQڏB[ ۈwhcφfBƼqarg>JeLI.AC=2q|W<*9ӯ&Hux97,O$B2BI7 2R-rT" D*'sHlq# gȃ9F6U.i:uD2vP_m@gZbA4wITIE&SmGG?k#ZC@y$2;y[Ah, s` |r 6=LK.? 1ׄ!V,,a P nS0gFQF}M˔? N- n#kp9 U`s? ŃE=pv9ZR(*&2rĂs{w_{ +z0IטF-`t+9#\q}]v?9SB?ԯ%*k#w^(F%& ]& ,I H; a0M\!(#H"D9 2evY CۋbB&!4@-ةeeĤɠ{:O=ޏIkҖT]q s'K35%<:^]9\ ;g/H%}utA;7r>;/Vv8@,)+~yw2W;f]3R %`CuWdl g_#'ecة9y!1ʴ(B̿1Л! f7>yM#B_ f֘< wpk{h+Zqs[ͥB`>~)%'ƭs$kJgT#=2*^~󁺸 hemQ&h-gm¶LI1 |V.Ē.f Z /;HMhP:% xvzd̶ І(wbx]"''(TFj8?F{Rss$Ѡnڣ9.Y(v>-=1Xkt5*W>Z٥e4aoʧԭLAdQ H&K(cN ]NT&6LdKPȳ}P)V$dχhd;aqgõ ~lqvշְvW 5Lb9|Pq9{ scX!PT|d>EF7x%g$JE<' (Գt\=*ԐktI(xo+H3q5M&[}ePbZ@ciN9$ȨM{Px-xkjRs3dFz"~ g@d^q]yꈟ5gJ!ˍfI=WeTFl610v|d8ǥX@_WZcdD< m*u;Z#v|B3J0] ,ddkV Npc+Q{eG|Eip?x[9hub{r8d0ĴRgv~7a|vHAo&uk")M$BU4P2N#ƙ͋h%<}92T&PXHɕw d%p͹wwӪ6%ViPDFG)_:a~E`yB}؜+]9eEや ZMY Ix>PE/y}Ozܟy?4ʹE0YnہSp{+uV~% /Da4%1& ɶc0>?=KH ;)HsY-AsFk5$f~>9=39[q}ï+#L:H #>@|$^TkW(p4iad}1 Ffd~E ]ňp5%k*K]Sn"D_74nePH~wDuXQi>Q 45 wӫ MN󞮫S\k31*ykqOWr]9SMǶ*kӈoL&vx&B%Sh\@O" ӓ_JqtdI+/݁3Ih&RGfK_ p] T_f!Yha)͔9%T3vb:GPVvYsT:j#a4 k\qbj ]Lr 0μ 5̿4J/@A[JvIHhy?q9Ӷ$Φ?GjW[7>BruU=Iyb::u+IQ 7 /տ1Fէ܃2ߨGXHVQ@qMN`IJ4w O. ]g*l?_޼j{gvgpPd.t = "Xݰ1Q2@fX9m3mY$aU}"kt?ř-C)p_.TOE+>Z+5kEv%eT!r&4$$kG0lZѯak]QL֎ b{OU(Lڜ= ={㻎1eЯm]4ʄZ`d֥/67~-R{K=DZ|@6!:3)VFɵ6E{ݓ=DIiO'zudz '6Gbisɕ}a.F5Y(a^ԀnZr+As;`UW=pfZ,ƌEmhfk0[ʠ=e5j;yX\SqmX*wR2+ p,,{v Pd֠Vc2'mKqC)[[k[BUv 爖 cb}ARdOk{LlFG(F#"TOp}0U~ɋ~,!T{&+$ 䗲43p=P/oL!sgzT L}v~jk<IJ{O@`A\j-V3ET~YZaboڕ\J(Q<4ޔQ+Fk@a|=@DǕZAdiҋ5 fԳ| ]oݠǽHZ$fPS邛}kTa&Ut&h# /Vd7VBVBs8`TsU>ғKnPw1J23<#t͎/U UyPgE*Ypb[_*G=68!2+.|7Q$M?›;WwD;m~X.eT/%[PqPx5X?VbcLnܤeKUvUUmJ5`|b߾ڦ3:.CDh }Kh?%ssLB}:E2ѫ&vB(u: \qBsCХ~Ys۔s.፿0bQpU>M\q5\U݇R#Ľmw^S~aTV e;`$ϿMmN]M}m9wk)R_BuXePv>|*.}|Eܹ>P h4УN1A30Y q׺y~B27 n847o㛺zcЍY>[!gK=\ah\ lmagybL2cl`W# J ]!1v!;d8G izG֨4bKRHGkѪp | g( B{"w@ >'LjS&71WbE3 *Ţm(ϋ71)Fb+r~;K*``⣫V]\ZDK>-f[3S1J ynm: jRp"Ul S6aꦗE \E /*X W=Ub%-h]I(=IRen0;y]Ys{M7:z>W^a,UˢNçsWo0?R` WtX^)}=ɊMoƙ:l0dO탺?]ƴ؁悴L$<8ksg?klKԎ7ylTs_ӫFzdyb,|+ZB^)&oNmg$YͽoidBnE?v@B' cZLx{Gиp97T[Q l1[,28!a@-_W{saKK#u4+/e5O~La0= `*f*G*=|@*eX?O\?onV]E t慅O"P:/ט7xO$.4 +}}65WG2a;|/r 6YHp :&Xs_W?db8 Nn~4/ A80/tFtNg Re`?./9im,z"=@q`LŁu+\16Cl.Tm>mzwmpCs-dhzSI[K ]53[B|k 0Xl-~? 4}Sf19TOD]Dۊ ~+^rkY.tkr)k,Z0&1mѽC57=i(xS(VV ȧH`TTRu]A _%anI $uj`SATm1?>=>ZDɏRBݞqԭp|t,yx1]5];P.1x0MdKIr 'u6:z )ॳц9vKA&*9HjΧ(@t J[^h xiS+ k/zd?Ӯe6I{ĥ+,;ƁͲD'ݮ;C>ZOF֎8{[mmoӻ2@2X2ch#Pr$G-뉈Fl@Lq6R__ޫuh~9k<5$n)XKdgu K+gw u9Vȹ%l:%FkU]VAeJZ6w ƶ(Ќ|"Oi#,RuT Nޏ.1X+;DnP 9E-KaMYt-##PjH{w-^0k]P΄gqTG:~څ`xE0[!ٿ0XKzBяl>VνY 12XzCR\7*"txCh9+wX4/Cq`G9VmrDl#%2hh7"sԳdvK֖TGV작>/[J|a!!GIR525[qt ;eĆF}eKGbQ8x6-U _<5N rvw76x0{ݝƩbZ0ʐ" FͺB"pQeBg,ݑ||,^1^fS za0Q&w(S4w-'D@Jf/ߝv gE"cOܓ,!2+^Y%&WwIZr`'ί(w5㎌-z& :, > qn;z$`,fA5M ElV"X`A* ډ],+ot%#2r2ш_`3dm*Ep|4yCިOz%3TMڑ C(ioOM%\DޓȢ9=L `~dc ]4XX/hp'׌9;ƥ4fswӃ=I+-CV-e8OUΙG =ⓡ$d$(0_ |@ӰN bZWϛ;PZdOONҸ @%3O\d=@eiοӦtKƐ.rN#cL E}Rzt}8iT &B[X37O3n#dWȌ[C"EMky rObi?kN{)!3kNxsyFQn?u fʗnoebE^_E7!i=J K{'+| ǫjt;w {ٔ~D5ށRk:軐Pemk3T'+Ns=VAHBDx%;&= KC5 *޴H] )R v$R"]{<4t3Xx$0`&"0޸bHu-5qdʶdO"փ2*qc1B}{&X4S찞HY#r;+`J'DՎm1OyNn{^7Rdoh3ߑRr5mwo $[q2@|Z^qHA}[+}i5?vfc-ïA#姕8V̵D*|(HcS'[z` BlB 9\Q^N P~:<ŐAc%1˥a6Ѿ=30A"`y?U긓X v%rGȣ/Ekg:Χٺ>x^Wjr_jp2NNMD!˃3:RiP0(;Er'OgSx8XF;i6t]$ 08m}]41`EhRB9eJsLze`[Feݚq#nÌc&8Ul?ðieP^f<Зt6X't ǡ7[gs>>7MBʔmŭ24mѬ3dg ƍƖ47f8ɮ&"\麍vڦݵ,~dQ+`f`2哿]7YCnb#Ч=y=9Чg$SuӞYG6Uoômfns#է_'(^Φ"Wq6c CvlI+0_WayGk/f<|˜I31}F G;q]8X$ή$ɠo9bmskdzv͒DAS8fn>kyF p+}΂ .{J*Gu$y&6pI(wx J4BswNpAy",zO1w#E* }|򞰐DIzT,gJh4oП: r5#~n ۥ'ɝ]?&Wuvmf0bT3Vӣ0SZãYZS8f7c 8:6Y֋&e޽{ o0pq9=s`텴8`?ۖ^zk[x4# XO@" v Xu(uppY nZCm)RuG 5h={+ȝu9Oaރ]{û`-"*2#UVTAExܧ7`gaf'&B6?%s I):z%sε(,vIj ˱{IB-wٖ >(d2uCc[1 l ˥wRu\slKF?>=mj(3Vxy9A3zb~<9!]vVIЩz 8LVo*$c׫`W%'%d 71R;ɆC,ϛ-α1Y x VFQctn$1xd eg ,R~S+"3*GO1 s ưLgY+BJ'h'5ll3u `h:Mmv=gn|wϬ<7g?3א¸[#%v-!HRC7ȈC(O5ۚuObe#Ȱd ϝC.aI%EyGy:%'By{'8f**ơgRau]G/f/>ڻK$9:m9;*1C'_D夏-Rm:;vs舞!; 6~3qf̤F .s cD uV `p*!%d9Ϟn. 0mF2F#LۖQn’"+^tOclޔeY ;QCE o6+mUYދ-յOA rٯ 0"#ƻ6USJ콌KDMC C[nfw6}7і 4q 2#F0ޱ;gPw%[1ѫRx!-:2@ m0mAһ:&v`ejJ>w[,^Ez[WHOtV~=faZڟ}vVaV Q IՂֺE,+ᕫ(ʘeVvB*[m+pk5DŽ>; Gdlژf/CH4k,Ia#<Dg͍ ۰14 aaY/{n$CLl5d̾"j -:*Xp9YLJ#-WAEUGe-'AsT|,\Ȩ p/ zOsu|z8G(:u $>J. =5;+H` vlATOLVsR1n}#-W T ىgImȐ.BKC8D !fkR쪛Wfl=Z|MqaJq3 n6w|yDXlY G*#'Ir'H[j\Ϗ 02Y/I`th0UF^מFƣ Ҳbz@_;1,߮?=( 2HE9Nb9܅ ;)R3-:e}g.ٴǚx3 qeB84w m~?5W0IWD$!~Rt~I2d(@b9Gp5dFZMnu:G0\05`V)qOY=s8dz-N?.[*j;mHheD!OtVǷl5:ΣK 6D ]9TJ3IrH@oxHc˶Qx%\LQ7)Dy;xؗdѕJg=x6 .&J9TV 5Emt0ȸ1`cSo2YzL1bX6uc2&̹߻ޢqGBKt+V,5{;wm͂P5`h2j?t MeV2f9mÓ 8eA2W(4o+AF CM7Vi ye>/Уg&Plr[ $y@DSb%ze|bXBy_*=_7UH:Us0(@Bt(VӺZfDDhd$-} OlTD;ӱH DN+|̚#S2šH(=j;M*eWBuvI14/e_'y"[jx΀] ~x*" 喿"d ZGz"9uwL%KRTDaY0 Pq{-AA32LxM:YgyNv͒!7_QNC/ &qS {m+W@ 'b-3ԇxs[' URT]I&C Hv\w@> ܁.X6eփ05{L~L}#lXc]Hz@k$AO F '0,IylPهP3Gkos 2TQ{GW (d ʇĔ-$V)ɵ6 ~$SB媥_dXT04 PU |}k:Du-|l=,b/)ځoohBQ~=Y_7Z^12&9ZP nH TMƖVDl/[ti3:U0uQ.-G略! `mQ|p wÐ?`9[͡˃ [lkiDxN6 6IʹHLuMQ.ziy~^sb%|' Pm3ىL;<,/tŠKCN6Z\}(Vʃ9L%!9JckDw!YJ;tiKl52^Ik̕ a] /Ɗ7/Ki]ż/`DE4!(ˆՈRl q,hkk b+  dV>0Q`g)~Z)/ͬҀzU= pf#p*1Xz* O?>-/)Tvf&m /,[).pC0XnZ ^#νn+AZ\G\_Mr[GK!/`:$+yrR?sdVPu3\ȶ98ru^vVEMɾ,ɯ{h-LW]#"".M.ü9lٰ)QЊ;M9| YQ[}>JV7M j!)D}=גYU{zK4bxWj'g186^o-~U撞F%(y>eԤZᾯދ_=^.BݢFiNӵ?gܡeI ЯSEo6sڽ]% ̾W+wW_}"6b `JND>ifO7] կUWf^ 2d MWvP3kϮo مY|MbE=-2>|'?+^yc_€y+@El\Vڏó>aզueJeL?!/ /7PL+]GǤU.[za17p殑 ֦2CcpA;7/ c,ױ?}+|ǞvA̱8cZυB۴h`FǼR1o4ifX <1FĘB _8 ]Rc3uTHbWHЁ>?ZI{/ىZdJ&^QqdkUC$Lݯ8YC LAд}~GYt/+v3RNGC: ܂ fs=vJ|,~B!K9m9}7(Bٗ~=#EvQu jy8"Z--Ǎmrs#2b"&ryn )pkM1".rz'(t{F4}(0DCN氧*`HRs; q=BY_ 3y~}7YuBe#UYG]hN,N.cv Nl5sq(*;+Dr:7EqXV8hehX`š'.z}}NB;6zvd!^C'wcd` ~exK:`G}&܇)7/Rj6S@_̏ݞgn\ Qu(LD UT8LTlhxC[`#$:8KkmHsnW )͋9ckFcm;$b&% :#keh{`^=֎%IRA @ bcSNRC ۽w$~Upd)k97 v_ |g6/s/k:MBl 1#\% |mJ7KOj[$&YBJhT-dUk慃=+e./01q؍_+/G,mD`3aOe5!g$#Yp8f,KW$5-BWϻ*2|Tq.+~8rj<]X~8[_l'fE1n= ɮN3MHGo%9zC{!6GW\=tw1c\ib"а8~3Fo=nuAC}'U%#/䀁-DK妱 TS2=oز]c rFkda42:y^u㎮g&WJi)A3(Š|BPp{MΦSf;Ol7K翙ZnnZlgE{Q9wQq(ոiȅf/ȣa;g1]8*X1c?Q(Cu9|) 7urW1=zw3C1rxD%+J# m /g^{I٤PZۺSd^+/el  hH$u`.#҄%@cQV4n0sw&px&a  @;ɿpض4Y;(FT*(À6w7bȂFL;i; ӶtQ2IV% +U8!FC$<ݘzŪw?Kh d% \-ڍQvkU#tF}KkT2! K*`E*L+`0+ew.ѯ?Q{~,d5RzMk;S}Y7-Fr_ " v苄a(b5Tt!&ڞ\z_pW \?@3$7@,wti(o1/]t4+P' ܁8.@ l8x%j2_υQD+픠Ggr8hMyIF !z֋W{q`gpD#P=Ix=qj>Jm>;̰֐u>!fetcDk`EQ췌Ǚ1isFH i7ՠ.#QDw+VnAlTp1 Eex0[aݜĵ#7XeUt0aF`qE n"juI4.5h]%Y<˘d,:1ǁh=mHIt_b[1v1A (YYfQαEl+Q:Lm+ w#,45|WvOȅM&J bzztPO%|ɊG;ߡ+C5\~xDQta&=*êi?_=u0ޝ& ,@ blQKw)Gh-he[MQ 6L`#x'VTuZ;o2%#Lf;{pɸNwDC\kc|ϿPޱaqxIܕE+Obv?;f0Grk9TD> zQp.;Pg{ /H~i3uijvx՚jfWq (MsB("p3 RP{un̼)T {4I-@۾|qd|KĔ ls_iNXdǷbCOؔg:([^O8}o !(X!{_is?cO{O%tb[zoсpςDR 3x/6 E3; Y~=cdd'k#iƎJ; B@&bec~ࣵ7ݻJOZA&„C(mWe١CzS"G;D)OhR͞rO&2U\\&-&qّJP\*1h0 A 0D;!'0]rTmvir؊6bȤHckDY`] *9Ezڝ6(9ʦn*gL)mUee8ބ?łMʩ[&uD%oJӾ: r\B6^C \3?Lʶ0+8I\}BqŦe-.!EܮOIi߫zkQ?o -)X R*޻^-P 5ɔ S@-g=* tU (C,ԧ2|c:'pR@(*N cq(nlي`'SRŇM'5nP}Smu^mpXѐA鉽4?Z\ZǕk2w@ؕWczvT *_m7=-! ąE ` =DY4ʾe]OuB`=[%lD?Y2"{ԅ7\DCoܒ_ѠB5X4}O7W/}:*<)"&|sQ$F`Cf H?B垿kkwzF)`{X+Wi%ob//zV"t"~صŃ -Qp-3Lp +NFV$d9@oţL)( [R0s$F(KEv'qzFL'|IvGk`_jJs(a!꨿hڢf]4Wa֫ ڴNzI-T^\."R&06hF S$3T;;^jP(\:].K%"3^@+kR FW]A#v.u7Ps{ .qG%[9,3ÉVBU*fL̽VH'K tHzG#〯v'?oּYŠ1$>ѐ2J^;zQW|E5$Džf]❒y~)bC׮JլCq#y'i› Ś1 VqA!~kSvB'@=%7w1!39&K`UuQ-%i,L? E~&*aE%|/^u[ݬ#w8~N3VN 7KoG6 V TCZOlY"•gVťtPJ. 2bƺX1l!Z]8igCU?bTK('$J <樳@d4ŗc ؾCEuCd s~@UEb,$Xh|Pd@lC!2g;KTd͡~?bM Q ;9amWo7%o:)r` W89,)$Cvi{ 48KPh}"2[%Վ=C5e.jlNMʭg2/Wi?b8ppUN<Bt+&JZ7#M8UshCgjS/ﯥcBWMJ̝v)eؤ K&Cig0 :DxiɝLQ5/YB.][{^8zCAA^.+:chv8A1]װEF" o!Hh|U& H=Z{Ms`[AC'K IS"m-f$OT8cЭUR|zK b-Qﮁ1{L{X|TJZCaMC'%8 D,®*]c=-KMPQ`>2NSP3׆ ۸ǹ!嘹LZO/ ޷d1X@:/$IRHL-a M]]}$Wd)YwQ%dW+Q0jXۃΛuQV3H(PR zVv>-ܔ(X`WHEdB4WfJW𦗹\*[Y~ ImD b-`q00JPt= %+t˥l+zo.d2&o}H4ZeRJ_wJEŢ0Jq@3/BWrm0C ?B܎I +nm/k[>hfk@uH2ё7g \ɫf~JT Hv #!,GSpL{9TѾSRhזz|×a!ݥJ$Π00H*>sCh`a?j_Iy ?_9@l4ӫoKk!~U|_cuhHODL|F.r`u+jFFX[mI)!\oz%|~;Fd46 ǠOufh>㥝y@*Uْ)Ʒ3{uM 1Uَ i_Ö:AIqꠃZQ:ca ou'9GǖHwk_^OB-wY/?OM{e^=?q0H}T[9NH0g&Sȓl0c>G d"<'H nֺOz&RP2j4s:A~NGƏ]׵U7AݦaxɛKeqQ7NVo\*z`4Tv zoNs) e-4ͅĝ}j)jr1p:~utˡMV3]@yހgѕ>i"8CA)>i'-M׬↓cyS[cyۿ#~b;lw͉%rȌ ¥:zDǁYT#kyr0%X [M\_SZ0\!n%%"e! 7cdQ[,E*!A#Mfީ^*2J7@f\C9QbMkmK;㪰@q ]g'Wu$38h9P,-<"jSȰ>Ƭ*m(cnƶQ`4h52"'f" IJ/To|C^ʹDp$bBotmoQ^ [˶wcz M:ПFF=t&fG Buˈubl9rCtYaB߻*0pl޸г*EWPWۯ}+=aqI4 .1Y~9y\xZ܋[Qn,P? ?D8"G0.G̱s+PmU@m+ێn&uBb_3Ny~'j6g]rQ+ΞTAzm.b p H%BrzEbG"*r/MrxӀQJ~ 8kN?|+S+cȜ) x}* 78a1^pUڐ$yO:hQl4ii c,J ;(*nF']@}4Y[iwl[]]ql]!0'`pbZM̈tU C&qĪaGBK *nj"`zy¦m"P$ ys5@L47_pHE&U-?qXBǭg5 Π߀^13H^xܵp.wަkErU5'2˧lG醥Š\v裋2)9T]*$OqCq  't)*K*n8+L=37N}CQ,ڍ6|Ŋ GJn JNvѻ9؋>dncf&}b#B/#i/Ww (ꢶt$mһ(Sb"\ ,Sd ioC3PH7ל5[ m^ LJ0m"]0#qoI9N{7.u?~l Lh ky8ڶh94:"7Џ 1Q ՘yPwzCDцSV!T@q<<ɩZ:V[J?Na?ѽ)2D~*3.8lJ) WaIӿ[NWI:$Z%)fS)&G)=wp.RͲ^=A6'S'&Gw˭d&GFP;`FÄkŚ\Pğ4~[%puCVZWQ C&EIy8^۾ b_8rX+e[xbVSM^7C4"=#]Sv1ao~fP{3 o[=y(YbeࠝǘSOqAyȴA!Wn4/'7* DskBt8G^ d\ y 0uc=.vD \vff̨2hޱVy2(f$r-GvE-Y'[is1*o~O2zejaQvЌݶ){ny|N0+b|I氁`WtrSEmŲ=y JΎ3F]YRdJA0"D.-I̒$KFF*6828tE/ ?T7- ̨{:} %SEҳrd9vo'Cg\C3hKH,_y8R's9/\m'52'>0yڟP7yr@b R!)-u0_H,%.ޅ?E8#4BFm^}nO b?!λ<zੲCr] 8\5א>n?~c%,#~]muBC<˶U7wmR/4Աuct#Ąʌ3^Բo&&%6UG-#IB's{A0 1z+jeAw9ljk1{EsfBkJK?wR اD 1ڦ= _ɮ?ّӯ m 21k AX0=Ur/@@յ?ә0֥ WCX^>cyRt"xYkaV~iF z4ͅMi }4SR,TF-).$wgB7NV%N3E0 t[x Yw\Ӱo3Z:ښ\C#r||>'>7* u.ag00pbuM';˒b:$ ^!J?!CϮt"CW[d,G3rv tW)ɍLmq r. 4n0Iϲ8;ڳecy_b5v;-GҶ`ecmk}oB9+7fQi|N%FTYrq{})pSTj5۔Brciɀ.?E<8]h̕ﰾp$[};-(7ho=ˎ8i#׭S$[7WjNZvXۗ HVF/1Y)w_5 qo/HkQKaj 4FʹxI8KR"u3J ]DFb,TV =2(U?.'YѼҔhEc2'-ή x瞧^ց$~!]ŀz7PdŗDiM3z;u5)[" fk[L 1ݦNg4T}:s)2&"{̄0!MQ%"Pc|)s{';b_b qF.^U%#\%ݪoN^y2Kʋ`#Rǜ`$9- f#cę ϧĉRTȳ5x{NnFTuV.wl;HîPo*ҜkG#2握nzQjN3la0< Fpu:XIòx'YAR>H ecj ]J{ea*Rӯ!_m~TF5TDPn#roː{Ԭeuҝ}} E kFoݎsԽDӱ)G hrA类,KV]qw8Zݧv'wK~뻑* xr5Pk~O檧"R$-5tG@,no`5&{ǑD#A4 {f.#YGDd wy8e&4k/n_?LO6Wy\XjC!"wT͑}'Yұ݋jw}Zb?`|AH̱n6HSثg`I )1z NL@|8 P>m%hK\@L ~ٙl_J0-®ȳ0hcIs|@0eu>^>=4NWu-[ ѷǬ۳:.oˁbPſ+ڞ*f&jsGۃ)Z9kuJiE@G"`\k%6!fKv Y!̹kr琠[BI̶d#$nXJK@jf̮c`(*φ@.n$Dj8PxO=ŷ>g]^uLx{ +p,X]г] bqIۧ&aB &ƣ #R m^ ?Oxu'TC: JTu?\,a3NӍdTaՒbK7LL^`P~%B*Mm FP?V?FI#E$ٛaG=gvEP]ro惢tz0{UJw0\ !}naB kʟv-/[ {lEw%f-}2yսell1@LJ,<8$R:L'Rhj#5l "{Q[hw_A۪52sKŴUg,=o( GuqQ`=SC*sK7kg^*n޸Ek hߨlG:W]u ^ht¶-q}rq:P|D$M,](f"dK,'¥ԥi7$X?_2x,bi5J펕]Wf"G洡1_`vJɼvk;0%+&_(@|O^R2MGn47k{,wMG/jp[ ON_oq*R!#<ܿR$B^Ʋb3ēO$TI ,czBSb.}+sTzBM0v#hu-%b&.C2ͬCaRD{A>rt Ĭ%x7A188dcg1,%Z❳ W2`YA7{;yCWK'{{U<8tUl\Fm8.p.Y"^Ec4x"6|'t߆~)P0O~PCr_ >x!81j'-ywH;ap`++;E;P EA!pQ31 0m$3iJ*Tc3>]wݑVaؘd+aP%p|a z0xLҍy~U2OKVUTO[8Ebip,QPZ {T9yHWKR6>M~x ve% (ĥ\8*O۱>T~gfTQU$CW+!QpVO{uvhLVNAkү[lg˪Bo^a;%qJ?+7MRͫ؟|Pt.i {"|˻_mHb`͚?+r| xel3IӭWĊ@ `,Sj R4QsƦ\~ΖFzȀ 4/<{ ڏs5q_F^#*{C܏{y-[Ѷ^Cs]pFbx#UVN"sħTbv8;Z3T)v?Pq" j@p?AhriD㛭ҫ%L4u.9(OD\8xO0=1/@˴^$Gݱ~w;ӫFZ='hj3DX}"ԢԛoA8{id L/KZOwU_; +aS˰0(|mĜ=U8keZX{!k03&XCxz,tV-R 6ur!,)jA/(a3SBG2\\$\LX"l+>*"zwRl zS|1egi^<F97kѓ0倽 8s .=,lrKhv@ NTCW//uRI0$#aF:g]zۇ{)nfd1e2xp.CBKy5渚I7v{ilXYZ5 ;f޸g 2ZK0#2LxoWPq.C.@ 7BYD'>5ϟ~lՊM>f)B}Uro=s03̎Bw4%p: ,dA[.ԯbB# R×yǃd'ѐ2%vQ(PRȱQ > Oe\".ZRvV(**3{TCjifk5ʊ]!|6I< - y~+cɜo5/.&B-(^͊eyS|]5.#{JFV_(w!fJ~BN; Ӱ"grt[ٟcvjtw.^XV&AZ?%$+jx t:+{sUC{7Xz.hԸqr!&YH*^!dh"W2;(bd9_[NA Q*_6{uzG(D!l+묀>SяC[-d3v$HJ4Ѧ9t<2`y8y3?/ɂDH\mּo^f%@_&s*:=OU;]֢a\XWR*I[}t I+K˵L[ծ-\*9c/H|HIдzi}U1-l%NxЎW}`IXz3+X|S"4m lZ%%,+Jb5OЪ3#T\]>VanLE?鉁z#uMZzj#Ee{`/Vk>cLwgU 2#0aiGb769 ::;; *$/-AQ]U̙{YJT}*G317f$ ìi\k82iVz`qv@706SLwh7'io= Υvr4L{yNm+qb-b1OxneU(kWK뀃lȐKùZߺ˃Z:"8$6`yޕ϶S q1e'rYgN좄ks Zt-x$y)!hݬ^iHC^*Ph-y+ O{59݅d!U9ۓK3~O"2G[T͂ oW 4tJ =+~wBf X6 $,:8QCl]> 6+*#@2R 05~GLix `1򻿧,gΩP=M`'. V?|6c)U}i=NUƮ1&` !XڊEeUu#j ,5DqaH8h~L,.K <13;qetafzjװ욆6Gˮ>(,  U.lHC<)7-Sd0X:.-FA_+!]uj0 E76@c}t]!MCTZM55ino?|q@ԑ5kJ [vhCsFHH5)am9'8/ Qa ͓s%*I YA|`0'ފL)HC,e4 yj?Qs<)*-剸)߿L 5U?-Wj;K۸'fZ6|#;#WzR줋 dMj ^4_lJ9*}˓ \\G۝6%Iq*=0>Kҵa0T.9Q #*z6ͬ->o[,:o=JP̲9"kG'd}M:B|<|vo@^'0bk'Q^]qaR|fi-/}:&)!/χS/)HJ/ v@yjwbpeL&J$py-lYPj_9A|Ʃ]I‹x\|[)[ } f_s75 N"HW:]Dg]yᴷ"2  14XU mњ(^oy/ؤj_* R0f8_8#/( …x9Ukd؂՜Hc\]{K6!`+:,%n秖l&`8:.oCw (PPtRgg6>MJJ@Wu8~4y;FCnmoO֮`܅~ rQNQғK9Π17 ;f}Pyw5~on%LJ7[[ +]㡁Œ&ͧvLfHN`K Cx(*62~0{3jwob$) : v eAW^6<&<tS; ~ȼDH*=MqϻQEGI Cˋ^JwY"&6}YςK뻯|KqZ^;=8QK<>}M kkx<9DŽ0FGqf𨓲5cZ'].0]̒qPޓTqyf`C6K>m 5?-nB \. 1n̗B!BtCl* %qVVh;zWp8&=ZbQ&α r A^Q=igKq)P˱O@6;v(Jyy<"_Zd^~SfymQ3/0doX.SWXM5A R'4.39@2]Y bd9oXph+>!.gdפN4:GR$;O$N\Ϲ,6Õҗnw/6>ϿruxV T"}Kc.(3w,PYGS2V;Qp:o+c:a2ҾCc-3 Eܴ3C ^OUMLbgnNBrڿgB`U(e;*3gjw=0r{UVv֐ ڢ_^A@ko؋NFz,:J׏r|"@D 3(Z7E {)0#~P~dzB( ;>՟w-L]CUUg;?cu&+BQ#HF4Rh"O_EqO>i_! #( ,#}diLJnDtL>c\dvH=t1䁗5IX,?-^ |9͜os+"nR' k<ڐxֵ'aXgwa"I@0M(ԫ'a|#ֲs%Xj8;YыY.~!5hc:BVlfP$)d^1Ty凂&l]!1K4o(Wpn!(d7/ kZUlU Jae 5SSWEK(oٯy!/M6l,Sš~uq(oBAp g]7Q,FCwDCU]<ٗ%R}ԪҦN̖VVDUk)lGqxJ).dt)9fTh2m,"VÓX=N}z]CݙU*ö1ei+4IԘDˏ4Qy8\WQ~$%!KP P'RGn^1Y#_J!(k^tZj})4M&x[${BY9蠛h~[w4D$]'`D4}4:萟ՏPطaq,;kcsscIZ᧷"vX3dq>B^ցvgA{||x)Hsnd8D[b$e|Oq(7wb!&2gd㊁& N/*w&?&k,mWӁ7ʯopLE401;x֤bK)D4'3#Lmm;?ދ:ј{|1F)N:bgѪ`EgUC>@tU>c%^d^MU&m׹\"ڏ ö́Q?8n  ޞ!tCYC#!F8m<.Nr2M8Rڢ&f3c#E44}>ɒ{_+Pi"w~]Rab[߿.u eҩG̺>_T%ع: 9u443,Y)pzEӀ9q| q%ǩyJ+PCCLYdEÍEXe:§w0 D!-^UK~:q&ĔIxYRk7 {Y6A mR^ˡmF8+<$$ D΄)>1Fx"iEE?0_Z%,s#]aS߭JJ` 0Uۏ,MTZ gsn;>8ɝN?ǜElڵx0߱ ]laɕb,oumW*$٘ -ΩuE!?w< >$hr";AP8\Lԟd?&+&5k({5d۱449>#XDe,6XXQӎtyҶ?t1 p:6 6]ի=JRD++Uf\mK$nC8 !v7h_tGX4:V4WaF"S-css$d`8IYE>#xr 糄})eɔ,3G"œ-H#}E +9PjQ3v x&ڒv4ƽF wb[!aRűyuq.#WΛ5aD@}Sbt+r@-D1ч<~WDHyztnIEPZq˓-N;Xm2ί֖RnNF4\ yHn~΁._|>J.Z]τTչm-929b`*M̀"@KhmAf Z*9:??7~ݜA‚FऺeLDp@ʼgr_v/ b:pjz:%RmBbr k҅.v8[I+^pCm] p^ur5{Y)Iri:HDcmڥ<^/6畷Tۛ0soaDbr;kFA17UUu@eK}:?m4(˯2W_0veaj<@IG4Mq[Rݬ]E119VqjA] :TU7L9K6Z:-6V`뻗kl?Ѯ Q XAE*$bzIkg3]+׮Yv~. Ql?FS3ӔOs2D4]q h0!>rs3C߯l#5l2|쩱I-cM/*H.U <!:z XρP Jq4 o AjUɱ<yۇi{ 8$4oqrf3/?n^lbi5K]yH[7Uưl& AɁJ)2슟f˵~臂ОrvHT0ݮ*ڬ%&ʪ\X]! ٗV֎m1ւzfcE3nSv~oKJGjq V_^%M[%x=;l7Wc"ص s(iS0UVf2@D}k-c20lF'% ]ũC[w 73N5i6=F)*'V.ti!(_3EHd`{!q hfgOZ:e XmgDP["YM 1CD${?\]8Iaw!+ϯ=o$0+:-d?b^*g7O N? >6#YtR A^ԐOE:w` ^#?]┑$L4 &O7qDWzX:JykB^Ϲ"nl8@fzޣ_îg-NvkYkJ3 gM9ڀuQ4,w?8U<%nɿ_ͱ:B: #fp k{)U_H(.#t~JQ:dYl\$F@˔ jKeH3C' Lc~|MPg@s2W*H>,8{c0;P^ x1x]~9_Cӈ"Ʈ3Q+jrv MIx7eG˧+=܈{zv]nj`UpLL -.ˏhTrKӡܳ eH~zD uٜ֕T:^ƽO۲8 !M?.lԴ1!kpנL- cB+'A91EJ4M~D=D% %CV,yú*W EÞ k [LJ|m+cY1ZB ^ҹ5Z}XH$-|^kcZw]+7/~ au (h׽% _Hb_ T/(Ǣ%/︐YDg>hѾ?z`p)FH|`2^A|;<֠b"M3Ĕrzhm؊xef;0Ϊe4G -Y}Р3ɡضɉKak\_$"|[O>̥d19 q!oEv ~j^G tU%6͆(Bncf[66S|'C8cZz丂š/KbzP9|5h\G0NjzTϦ8Ȧ χ5!V#:/yB(%/YJ>U]4$U]%U)tR/)(:/{<'] WB CošWBb>+_Ns0{Er*%`}B6gE e;NsVIc;;7]Mڤ3G#!2 kZoEX/k $H'L,0?yn.\OgYRu0aAv^(%tj"([(K6B{Jγv=8ccY]-ٵҿKKGp%;909-5QGp?MЊrݟyn{z WφյFBgwo˞awLqP_=đx݃/JZ 4,3Ñ:_CWwk9# #9]+|iz|蘣><.T* %g%EXlX W{G&mWB&mN`M%Iv[ءl'|"{C ֛ύT~oyc<˟DV9W3O`KP]xɎYws]AAsfF-R gu{Ifœ)7(JVa4wJD7oޛB:0<լQU;f׈|7:ztV?79* 8VڸO&$+A&ꓥNqqS>>Sk8$Ts|\+lu֗MiXlJwe`㉬dzǐodP=}9"r4la8nj޹F/ Fm%r yNjzY Sp/w)׷::Zc3S˯ ;8#W"OWHD\w ;YI%+=df?HT ]ưG*҄BhZ h:mQbցK:˄)0 0A;` [XV%OOð}U3/FTc i =F07j|e'~y#Ճ"ʵ`j ' @i-]KƮ G )i GTN@泠Ȟ;ܑRWX p;,B@a7JξcV7#l$2KQIv[Mhc+[G$LRYo#pK%aU_߃7iۀ詿gaB>)``K2lr>d&ThcUaFGٕ)q@twh=Ypb#dȐ^(-6*rV*gģ==16EWR0| Op \m'^Em nn!?ia$22CAY߿Nnb#VFx,-wIiB"n^OҜsJyRbs+ =LNؔ)t]ݪW2tlfV:;]+!2Bam}q!.gy.܍M_mY>ldum؊=!i QP vƆ= Jfr86!$JWH=F3ȶ,:lp!DT\Ih("_ ߃FnnSz|{JOEr:@$|*![T~-Bɺy >7 s{95sJcp9A>su¸H߲gqolAKtIzzNZ ౅,S5-c&qG7`CSb}]g}HY$s}=a&W*gAHEPf9wm&L}rv9)z4A4qYhg=qh7 *Pn4Uq-r0E b|nL-@xSFg&d;a^ :1w_8kaN{]HV BOZ ._ĊUFٹ2UEE^i:+zdybi諼Bm- ZhSc $Ō5rh]#IBp le ɡȒh緞쐔#<`!ǞX`Η\)Y.j!Lm H{<7?H=A+(n mMbQ4&d֡G[P`KR 6!O{yY'zϨ u  )-l,U\>m uP~H#)0<^` \ɉ\xNrf(7Nb,m%~=\;!#q,!slQ`Cx]sgvdV}]XwDDg -55?Hfџq!af(yUڭB7_G{İM5DDѮU¶ ,K-L b"JGNτ΀&oljn/vt) a9r!Zn=$q@lՔ\0)YP&;j>h:_IQq5w[,U6’WZQCxpTCsG2HB'^=}tri{[$f#r];i0NB *A0bbP5_d'jK_$|V*AB%Ó_`Q]쮮b (띁-NZ q@0 j΋X6^@f+?v4TfIgj'Ug0,&X=/6Bx UH&9 ~ht}4/>H_&N[ж!cԭZLY)̌IҴL0UIJHL}^(xq]6 jv溥@>c[\jAlk:0u͟[.ΧF6w[TO*/ ~͗,s;gqw cf殕=&ʕ *X_ \ҏ#~p [j/Kgv5;ظ*nm].V4Wp2x}eNk_±cg&SzH/})ghbb9krqOi%y<9#ofFd^I^B4N0P~[Vut,xn;Ӑ[-ÛoR=fuIp7´`1L n}":yUr)hӏ$s+)9# l(B%}@;,D|*]HN {Ŗ|je_)׽K*{cz.lQıMat^LH~AmYaϧ…vCP9 v~]v LoF!r'Du:/orhb{K$se9{2ȶ)+83$LZ۶Ѡ 듳sr'SϮY '\ IfL4nw3FN*zG `ֹca&I<  P,3bV@9*W͡yadER }Jebkd{Wx8r_ԥV,Rꬮ ̽F* ӎ `_uf/=`򝲌6Y㆖lF[Yx^e?aB#!B7I{~$ᤁw YC'3T:4y_pon>BvN Ep]"wa@ݭL}"]%]izf♘̖E=c>!+*"5|nK$Onzn>zkx,L>CE!s"XthYSΓd֊ CcF<\dBf&`]KڃLW+onq?-(FOA ϻĴ"O1Z8<^:Ed%3Fvv=hu=nR3[1% QWURݻeG3ʒI@Tbpxi/”aTXt]IK*7vR!1{.\,A}&PfE~LwL e2 3 9jnH uQ~5yk Rř+p4:ad-r"fu<'{ОTT<ơ+L rfo&N*pt=PTVPCmy_[2O0p8>D,>T OԚ{A=yސt7^{VJY׫(ty)nf6g'_)J"A/?[C]P@)!c{_~,B.B ʼniyū͵e\w¸@;Ь4eb7 LH2[/i8'[UJ"ƥ<sA# 97r8ߣ_&JSUU (Hmq˖ƒo*opG/K Ok1HFݹs䭡 siJrq RPIg0OFVՎ:k~N{]IIs}q#2zkvFY4.Cô#W9DՒޔ$+0:~j֯Oƒ)3G߼Ccȉɫ_Q$:)=P֛w3[;aJkYR9H}PIQyMJӐGf`:la=yҎP1q; J"C;pJu_SB=j:V u[iH\)8&yƶiT ۃ  Bt1oѝj$k[pRXQmoOAL+ vlA̼/g5vܢ*3Sf5/YˏT\nS_uP3([\*x*oNljaפh\ՙz]tE)yW;;ʴB"+&Gx*o ů]XA,#gG-oZ2|lQ,I5jeDzޜMY Z"{g?_9v掇O#+ެAA-h<Ovy'auׅu,; 9hQпBAOuC@fɢ@d.1^%|>.n52:N.1}A^7! y1#wzC;@CuikwsC>z?%27ݵ q@03zaYHQʾ5I=C mQ#O6n@>/& PC**Z'CR\h <` OͼM-mg>)Fm7ne" d4&& p˽cB~/42jVoa@>elCj3%~w]2$ tYUO.fTxHRoB\ys :7eelYT8P|D5,2uQQ:Zyw4=Ӣ9С{*sj#vꞍQ{B0l18,VmI)^f*]'3|teU)yo1N!cykt ߀r.Z61f5y@qt5- IJ,_A%{^Ú&O7Aʡ擤rYځjb\6^T ;"-RC;o>I٘}yoh-K Jσ AC=4<+LI;ف;"0@R.C;n n uU|MeӨ/?Oʌ+ۈeW+Hq3;!k'2\oGn*l1XDM/\|!{AÛ'f 9YNL[&t^u7o@ C, U31w "YB뢽l/ui'ʟDwo ó äВ t;jH ;AC3ږ7obs.?ٶcSx0&@J9̾ tvǒh|nt} PAMl>OIg&Xe@]䨢>7unZpKp`.ʳ{.\%;-A1Xb'}ݴs!J}01Y¿^kLjո \J w>vC+!1"oɥ8ʉ>=r/T쌆/xU !_r==mʨhUްZMeg k&p-A-wܖt5WV}⊗ւGOl𿓻m@[E%2܍rL:FNV[锟'f! 7A_>&OR 6 l0pj"3%լգۆEZ'\lcUaH&~0*+.7*U'w7LwPlB$UF!Ug0+g&=wJ?j.æs̢dyoqj53[N7d^$ &l=ŋqj"Bor?}=xAڷм *ENrI2~Zcs٨iG,!N N1#ߤn -1ZofDÎ2^=(-ȀY! -4ՈXW4F*ԹQ Jef_x)ȏr H;F0َѢa6{G;gpؐI;Urb!m'%P+\?X6ʌ azRBXbُ}:WƗh,,4eчrmvl˒cJ@Nc(b:hl͞~9(6%g],JeYL( U_ Y3 QTmtJͩVއ j%aᳩ%>f^RZV1>?Av&6t`mȽ]}labڍ:k$ y R0f{uJ@ڕg[Uҽ n!9ME~}{(549okPYܲ4&fz) Pva۶_nbpƚY1>ye+[0J<boXll77Np}Z C.Іe-$~j+_y h߉9Xy{@2PAV|x@ycZpuAמ2F]%F@WKK&,0UV3&uSX=DT=okrQOoڵGhFg(!,jo.[0IY<}sqwzv?{0N*K{?L=~~Q[k[}FЖohW͌=^pjb>GК=b 0;oϜ\0zj8#X={r-MU(`PyJ|ẓ^ʳR4oJ}ꧺ 6 |]Ky;L;KMzbT2w; eUdZ'4o NZbt?{fȨu^g@1 hS45j8^1-SeүBQn`vDh7bӟ&eQ{k0@P;Gc,|[N>),Va%PΨ8:M};il-{]3'xkʹ}xsleX IY,*ɔx=/"PGUZ__Oy}3Det=`XLΉwĖ]aBIj6$鱧B"e\>5Eu[GM*SKLˀ0޷ޞIiy~MѪfLhR@-%Df˼y@~uGř >C\R]WX″]P^׼F도8&5(3+ pawSz }=00g{88n& mʢ_r*BɟSR+YJZ4vD#atCɻpdPZ .y@V0`Gg{؉%u◛ҋ:տMRՋY9foph=rFDH#N}O㛄s[ʧ\G {<0sK<ˮf؏%HmEYk SclAqƨ9c*>ڻ>lh!go-$n2^ R*(EȼM3rbyۉAvƥAH[뒝i+l-x~˷:p -8FڼkFei&ŞfiVr|/Y^ؘVPx/ԫ T>k0Vpv%fTSjiotMc`i-p^~Cئi,$vQc)#l -j *^a_Í xtc5u,i].VjP࠴ݸ Eaay4?у{A &u)Q> P25˗uǕ{j'4_ PUZ)ܲ z\Q%v>Ka~P^B#8q߰Or jHl<歑𶇴9 0G*&qe M7r>uLw AJY=]Cd? áw 'S(ζ5 ҳT Hf}!xL(J@xX;OFM< h΍L8dJfPCbܫL 4>н:=j -pu0ٯGvܕ 9`D%'K4]Bhdg7S\F^a`*& [ZH(D3 hZNtšݥA~2_2G?aa8x!E %)ۖdg.|p|\Ձ⦒ h`]68"Դ1Zyn4 iei):";޼ v1̫WMlG][I!:_uWy,2d7JqA `d#bpImSYDFX$TN|3\rA [x3%$SB@ƅvLoS6O~țV9#mGUYDDŽkZs%|7nTZep6:x`D)y֔WS9$~#ͲB\.6oI dذ?FZ], V>ww:ek")Z^bREncm,y*: I )9 $^+&|br/EN'ÒCgq'k^kZn&ͼXNL.LZr3 gG#, O (E h4'pc8(y<8+$^-(QtL5 ;.àacu8s|C D\SjNkiB{3_oPeTjq)`e}gc˚"s_ u9@閑?{zV)ۧZ%; gr9%Cych@(.w}yY ۔–CnX%dNo=zyK >В>aP!6|xg·cd>(C,cѩ{YNTxs۳i3gs`'C~8B7Z,Ka)HBw|"'<Eg^R4vz)Z@-d\WPFόKQ=~- _^ܐ[Q qv7;EN;,fă bC,ϓ <=0+j jr ƿUPp^mdatN, GۻUNx265 (build 79) - 1.9:[Linux][GCC 5.3.1][64 bit] 8bit+10bit+12bit - H.265/HEVC codec - Copyright 2013-2015 (c) Multicoreware Inc - http://x265.org - options: 320x216 fps=25/1 bitdepth=8 wpp ctu=64 min-cu-size=8 max-tu-size=32 tu-intra-depth=2 tu-inter-depth=2 me=3 subme=3 merange=57 rect amp max-merge=3 temporal-mvp no-early-skip rdpenalty=0 no-tskip no-tskip-fast strong-intra-smoothing no-lossless no-cu-lossless no-constrained-intra no-fast-intra open-gop no-temporal-layers interlace=0 keyint=250 min-keyint=25 scenecut=40 rc-lookahead=30 lookahead-slices=0 bframes=8 bframe-bias=0 b-adapt=2 ref=4 limit-refs=2 limit-modes weightp weightb aq-mode=1 qg-size=32 aq-strength=1.00 cbqpoffs=0 crqpoffs=0 rd=6 psy-rd=2.00 rdoq-level=2 psy-rdoq=1.00 signhide deblock sao no-sao-non-deblock b-pyramid cutree no-intra-refresh rc=crf crf=12.0 qcomp=0.60 qpmin=0 qpmax=51 qpstep=4 ipratio=1.40 pbratio=1.30l& :X{t7o*LSK✥7 Dvl*˪7CCJɬSU^I*ħkiɶQIc Q]ieAcAG9PZ@%χ-k(ϓ=U y+*l<:Ptiz1JҨfGf=úmi~dR CX$ \)Iә5.nj0\ˌvqGV'G`Hx.%8NDC"o=7SNyreiv_賭.cR 0K?ѭ+>c_JLAVB<99\A"HLiݶ-^Rp,rjt[Kцϡ.e\Bȅ]+K"[gW=`Lli^V[ө3t${i{e9$}P1&. nV1x‚OCW{4/ȅ WxZպ>R(um5ݬگ*~+jY!zk?w\cy tr'XPHP)䫫7w a|}6rd @1xBn\gHL_CL^||z U#?0x|m <e>Wͽ6#q'u\E}9w{;br*`{dNFmSf4<6U ڛ5sV1'$TKc.GγQ&Oi-C?#62yF1՜t 1vD͚~y%QlPI6Y![yNSI9 Ev>6dE.0խL+=C\b؂>*[OvOs<[chnZ2&XPs ǩ, vJѯG$/e>P2g@Ǣrہs=|iiE3% #e)7iF.pP~Ѕ/T hS*x n)œ%ԣ% ԣX"a?G O%(bз!Qm쯯TcT;|pI)<'Y( Zbv} 2= fV]::Z'k/u^iĵd+O$۔SJ[SZd]dJkQ;eQ)`:f+cx&Ԁi6^Lza]bݭE~%s/ո(+Osv gn8.cVd%+덱[f^Dɚ/sl>\* `$]N )ҵ)arX\dC翨brȮXI[Rl 0}8.BUؕ;"c[={r5G|0N_V/uRQqEgyhu (BufY,P\v N @*$1jOl 18:y0%? Ypڞ#wL45>HXtYiXGdNظ }2A6bۚT:y(NnJ$G6ϣI5 \a;~W՗6eDC3X3fu_O|Jz}+ ZYvjM{ׇ=F @:%kԥ布M [alJ}Qj6b: h2C)&e]<:BsVHU!0W:Ui4/RYum?1E^ W(N2UFBD:]U:y$\v&}S*S 7($s,/#/b+N{ǜi)IhftJsiD;U°s,hmw n"aHtsFw&5w ѾA $AfISAK; ɉǣה9Ttj,Z惩Ru7:MEBQ~X=ԀZLfka/4P.h0S!сmSm͠dSq4ҼxN!,*Z.t 6ce̗NV?:=} pqOe5`/;gfI ѽ^{&ͨ@ 4Ýzjю"݂&Ż?ae$"1u7lXuWՑ+>Ky]O+f!"We&GZT+\쒲jM~"f0U)[ nТf9t+^g!h8+^eȉ~W}X$8ğAgV',YS51A=Z 'N g&,1Qȟ̓)3Օ@jq[}@s^0TMS`Ɠj`\HTWC^=/[i1nMGDS[:i"*S$M޴>)LR~:2$NƝ%0R#hHYU7{A#m5Tgk:^-}hYueh`]L?yܴ34;TG{7M%}{nivg P!9nk3=Yc.\edR{_gM Lp.s#kvȂX75yA9F_cƄfLwC$;?]6KT\iGYRߤ}E[Oѵ=̀ փ蝱ĸpKVj|dPsWJ$ ]w;H $YUT;/( P \=]OMC xuLPX=$F2{ZwsF5ߠ"#sYyʡ|Z3@as:ъ(fvQ7@^?@3fzn ΋e7ιÊp-5Yq(hX>|6J͔&3NYZx, ;Ɠi!nZ$Kqx5}7xljOԎ̪3';Dj| $Z =le,jy&:tyUJe5=& ߥ?X5ɧbX8"F}>~~9Wh~dXwZ}}U(1@\8F&b)YYH4r+Nrw[b@R__8n 2z-Z>rA7_~V+}6Yo.dx(Pbtg!= m3H! `«e73S=2TUP N%Q~V BcvrmzbaOfw@{w>%&5W,* .]t׋t @Ր54geXݼY&ҍc>yz} l8gDs w1,J K!+N fkg~O`1 ח. [=7[N8̣9]`B]h$/R4E4)?A IX,svf+hJ RG5p$`o̽?'X3n߂q~ԢsSӚK0G/ouZd咣v '|^1:1=/ѺP-E>{ZÈ[țIgOru#c9K60k=R&LǦ= 4c;)Uȶ`*Rc_\CC@`Á Q`I&ۿYVf'Dȃzs<35UyKvbOTma)ÜM1/ y@d3n8)<?u #CKH:]c>27-Ӎ'?k'7H=ˋP:Tk]CCա=j4'YY,ɓHd(q}:1C/ r1%,w,AR#iї̪4*ohV~cT[j,yPlSB]{Hy"].xrxB e' ^&[p·VwZ'ԼOMMrdHЩ6Xa&|Q@]fgG\G+:|˽`IoK4^mП): Mg(,EcϙAKX _@PcE(}:̮W+@cRxh7o¦C^,ڎYpXDA?Ɏ;0;!K0K 5(dS>Ʊ""E!ۡ3zDf>82'͢ˢ/Dgu37plʭ6Ö4 ?ќ}a":>d-cuUىS\j-Rwm]۪nRc>DCy8}_,^ܳ<a?өJv{D/(rEqmI}O}¾qGtAI?ue3 yq*GP櫙|:zHoYALRu^3˶&A"^NR0w*]zڈ%OkPyh޲b[|3:, *ǩZ2͈$;  *1"776tbrISSD-.0/'ɇEξpQSjyGwiE- ֦Ks%lZyL%Ucz` tՖc;5sqk4{)ڊtϗl~g5Z7KjU4R`{2Up<_~] Q(2 9BR/Tߠ*Q*78#m{hv\ղ7nh޵ayuǎ'\'x!"e74D evQaH)T!(o\Iq:2gL7JA% JAԙz6E_ztl`)c^|MhO2 ahi}y|X`.ػ *# I^j9q L0:sSc2Ч: ax[w-Mum]Wߴ_0PN(1`0??*Ŭm 3?,"*|Dsԝvċo_MUj7WlFJ9lߺDNV}~% {RrQF O%#YpH͞ 0^a羹bE<KM|({!;2 hLJiO?H,bȬP5b}#)̿1?ڡXetzI@; D3:}t1AxeɄGXr^'=E$8Hws՘CIJm t9Qi;MDi!J=MuijX&D:G$iJ'jݒuk/=I~zaП]KZaFG.I%R{i d*Hdʐ7Ś91yO"1vƩC*{|EX}7Z'Urzd%w5({HةA,-(ԁ)U"=rUX`%@CH$3.~>Ui&2@jR0 |^Zƺn]M|[U%%G { Az!8`It"4ѠSvm|ƽӋmo!umτ]hR\y4[n=3#NIN EgN'm+!Vl)l:-O`7 'amw?@MCJ!HHjf@gÞknH!DP^P:+chɰ#ŭ1G_ԸƯ$++?ߌ.UWWMgnԔU , £5ܧ0'#پU_h~} ~rʕ^IzyᕺʻAuߟ*ZVdWdO'T 뛂HB|jU *H$jEK. U4tN}S# @jvWk'`]96Wb0ǜ9۲]6?D&Q_>$8W4 \ߪ̟E[PB BFGZ%UiyԼdJQF)<#d=Eah qb22/[J$cFŀV7>|m1@QǗʠobXef,c*mbV9#GڪL򭠅n Ι5cL'ifh`c| x`FEfH+߫Muݦ\8SQƌ"AnD= 5^)z& GKY `s*^M:a~ iԦQ2wkYkW*ǒ290/+Y%MEPo}gZ7 Yƣ$W׃*6Q8h6|K'X>2AJ,D=){GU<$u:d%8g޽$WΩ/"(_w06B,#f2+{ˢ4l*kYXMxE|p}ԢPR5ӑ|2 rj~Y:ގ'P4z75.3i%wd+YVC-#=%TIi4r5PEAzȁ$@8K <eN7k 9i$pqq_'gD*t:|{ARz}fk Wb)&b2,1$•p\{m[[b*€Le% `Ϗ9>MՖ?bLH$iQtŠ. ,ɤ,c{m xyN 'Bv1acM4?x7DDd CD/^t5T;W4'k-.ӘX4aBjl/oĠ SP~%q#HLNH OYxl*f63FmDP@$el؅|$ 'ꃟ%(m9RRS$\1vW͍v9?/6)˸d}5h`ͧ&rvT$NIȮFxjMAK*_EhɘoQpA>f5lA̞Z+ -wQJ9,It9 [ܰ8O`Vmr;:)l+v{){%+/4b"qvTd~?KdBsQɚ4|`)fիirle/4M#Uc;3XFV`OGCKtPIJ'>EZ$ 0$0^%ifl`Y^'vpgKJcct͂Nvd\ o{z|I$MK>]oA]FPCWu9(-Z.ȥ(v;gzy"ԼK ,.X3@o)|WP/q놏l.(# !q.(@9xȇf %OMjgy&\=b.E$tP#+ AnsiR@;5,lpT[?i&.xkc]ſQu2Kӂƺ'3TsoF#E8gaNsJksş@Aa-2ǘetS{pQHr8] Ȳs9 We돒 #Ӝ/i֫"A0I|8^/)c#nm4e9ʳ&&^GK7hrtσry?w (TO7p@cx?G5dvS}1D>.XZ 1XG5+Us]!a &Hm wOpaU5ct$tDkFOc6q󸩏MT_K]oYc2p7nW`(OW\qCG#rkE[ƫsx;P^iɐ͑h.p`Ci Prow:6DiYkX6L Q™ʎ<}K2uo,F3P,A:hw< '=/݅# 1+D>$=Iex>q{Xj'WEK$~/=%\'6Su@qsU䭋֣ śK|y͌Ehsc?>-^\`:y#ykdxޤ.a|ŞOg(<7njF:='#AA

0BE:y6#xȨulcyxw ]çEj GSKyXN(IkokNefkpdlMHAّ<{stDL]߁@j&)h7j|̷o ڲ*amοׯS"J -do`g>בzW/h.#5)?Behx檝*kf!:1#ֱre@ׄǮ2 TK͐ѥp|?9vaEb Ԗ&pY[ʀ'vQ,{ߠ\Z'syU  @GMA,.^VZ'sW𘦝N|;ꡡ&u= -)/q0ZF0 NǠ$?𵎍1bz%[Yںc 2a='b2Щ2ϐ޽X2ooɥɨJ6lB%؝(6Q:%(إ nb1' J cGF3t#;.B@&$mapJ)6y.;MsSKkVJ-mA+&ʺ1 VTrlHȌpǓ|w9QPwJ~E- ]r_MQfN&G?$s~.1L*B2w_p[xbPS9᮪#Ӽy#AoowNQ?X o.-{#GK[n=e"T`\U|t2(M,<1ʨQ"us/HV ÏۖR~Ѓ{`{oκR(s"_r-yKr8y3gQcs}ڝ!h*qN!'a!ҜYl*).pik{OyLojm0E*]xFU9˯`i8h:AHӹ.*ʀ4FzhG,؃fUwXE]74cFhOu}OjXh[ͽ{4?%PoO{jm xRܒ:ޝCwW1n;MÈ %*ʻԟK;+'E]Ҿʲч%"6m?*ǀ?캝ҳYmEQ"8m?=͉e[aړ{ GiB(#{aHٚUſ7?_\Q`™;nq3tbL\*GQT %0[@C a.[/R'[o%6% A4>`h%ܩ'V a,C`g'><:#|F[q:32M{+k . 6)'Z)翈Di#_uFX7y{8X*Uʕ/c (ϪM~x:`v#SfDw5GŁM5h!rSP!󻦲ᜥYj4L۪W++g^7B һlI |r%gLI!e81j{ ͇_Z.|Pg|5zjOLM I7#?W a7 ݈S8X+EֲN=FQ36NgK6-9p²LaákCxڶʡ&[-R8[6) +zczȩ ,ZXBBPwӦĉM;bܙ-<a#[xtb@=l4 -B@T1}\\9$|VD9L0̡rhn{{cyv;vZTuVWKzWF#XDQ^UhʳC\f+q{!ht\5UwU R1hCӊ{# y+&/&mR:o(zq1{^//l-XmN'F:UM9_c?3 ]l߷*f.|UFHKgKegJ$7J7'2 B>&dCG΀vk"u|0yRDEq^fnȅzà 6N s^d??o+{ļ$LN+Va>,Wu/&f%COLq jTR:^о 7`@& ] 5q٢ A=cr5n G'4ml} bG3}zV rT.YT{6_4hE2]>f0* aK {YCU/wG5D-7of?c=<#JǾՇOpR{w$R[?en!H)?,M+$_6]kG`B ƒ&[;na?ْ/˂qNAP0<7*mni:80%9Xtwgi|U wA׬8yB|uC:NMIDC,>Lf'?k:[nDv;$­dV(xٺ;}zЉ<|qjA{Ov&= *SO߉tW[ \bאot8o\8AA~ؖ.7ўgadݤBo%Ūy?*kp|U+E5n}Oo!6au,?F;_y/,=buRGßX9^|3cdE${“9-: g5>%~Z\us=۔'|6IzdNa78,zbVƽIDŧj$q4 $ч3d(,36tQwP EbF=$ᠧ53W틍i9i";Qx@m S.*2*'-/~%=̈́c@vV5d\]l2`՜R1tgP޲%*=GAq8=@ D:/]&LJpDЁOFwMQ6xsށBYN{߂HpwX<|6-0qADYLdž޶r=%,~kNW~&'ҒҘ}#tgkճ 6-}ٻ pq?aYEsnQ1NMDKuanV2"7dlV/D{?w|NQ!Ӕ16 ?.IuqS_/(vᲑ·[ XtOۗiQ eRNIƒU@& kCX:Ѭ5? cAU( _Pw?)j! D%`zJ7x~JvfL%N@BC/ ,F}ba>,P& g 䅟Ƃ9NY*L4F|TX_x?+:9~ ͭM=2Xd ќnGhtk}` l] vBBep;R'I0;Y}zuyzA`\8t1aYJZ)HB4} X|F*[HLJJy1#iZ|x%q*FVȦg 'ڷAI1 qXv{# 2IpZLI>厽Yjz7'|^?d )~W׵ ["$4, Sta՘t!E N,=9$Bū[\zo W!qF>o<\c%%wz D : 3;*Z :P1ck'w؏B0pg&7'NAU=u5Vhe50bѼ#-&0YAc H!vzA*}qG\u?З04,&#~ޕx.$Hc?pjt8 XQmð-O~$.$+lVa4isǮ51֗ꆊspRG ygHȏc~FrMhuYYkxIґ#(wrflbo QR+m*St WħWDP\iGzWf?Hy)@Kּ^~xX:F@,fLqW Uz;<0]WL}wr/(֗{zMkDJptiޣW4hV1OuwQ@zskؖrU)߿4:Yj,O _QצM]v Ak2$[bT?w< {.iŮz\0΁ ;p3GIJ_bր$3üC/ꇄqKDy"aگT{CPCaX+Ji_IZh$.L։JW5hOGŒ/ d #U3q$V/k-+˻<2qc'-jB$SxZ,XI%c$MjfOg/vO? \}ձ2hFKV,3DW3۠HjlN+dMb9c.v1"M6j_=z*jjfbCW% @o[}1A%༝ m)Y:ѵ>@ʮ 6OR wVg:KQQ*Zl*XGLR2z~슅H% iGUEqԣQFP (p*FWKXcه7߄-j̓LU9.J" Dcp~"Р m_ŜzQ蓁]oO9bﱟ"#!?AG-)j1+n~g&o0t!'{_? Y*xe +|?g2YFgR).[Ftm(G>kH0_4Gf'fz~WT[%36} aQ6 z3c1nsPU,$5RaxZ=HLjGOY]#* |+Bl!u70~7ٙ`b3SG@Is6*1{!<9hlt5tۋvGIzHAt fm.nG#SRUQ Q=^9(TK/A[H_Щd: ž kylgk~Nܤ}`jj'`?1ACڸt˖U Y/1R9цgiL$`&OΘBWC+p}x*';>HZ\$c1c#&S,b"2Kw8}@Oi&&(CwůpZ",dlPp۳v)ѫ:z.1X:o7whX7Td/I2VCnUIOc8^1ۺ.ͱqXD䠊ήY-6ʵHǩ`v<ͫ^&L2P y)Ս0Kyq-SeJhύ^'>ޓ9SNy6Y9Dzh+9ٴsS(0YmMr>8'c[(9[j(v8SMh46] .T?M"/}/l `ಉp,`qͺC!uς?LƨԹ掯rh?K%?ȏ9K^' T,.P[ Ib2l갷gpɎ`27 Փ &أrluؖMpb yJm{ZΡ6 01kGz' t{D !d95=Uu:.yUT5 ˱8|Yf&fb H "Zugpk0C(3||czm^:#hf<di-`)?<"9Ťقe|c޶og4ךB e>i$L'n%ZDĒRVC?zuOFcf& H$Ux~W7%)AXNɛPT".Bf?45?sѿSF^,u3V~bh )ay.Cub2e%d˅uE )$ ӕh5pmsdbe5nd A[U*ݩ&Z'2!zmWLbo AT hs1deI] hw l;!pN*#t i\7PĬ3W3M?sD1.' :&EztǍ$B=h[r=NC.C|AQI]`WSe띫&,!%Kf@QqgS|( T @M<HP! |ߺ;7)$5nB 6Kt5XX olfY"1PoF> f6AХth!ZT.i%m#Tє{D l %ttX,:uOAL۶־ jǝiHݽ3tO$kˬs"vq4%Mí;"0&ҡ)[W*)q6@(Mx3l_Iߨ?ؑ,= @Y9SνpBWK$<ն.I5Hw rSMyك]z}5"\o8[14SSNS3D*YܲZ ]>5=<$(w- AiON~L 2}=GjI:^QwҧE.~lmJ.dMM0<PH(g0UI+uHLJu^iË0aԳ!roYyi͊t!c.y+z£) PWm_UW8XuyHdfIP埈{G@ߦdIؓttyva8h,]HC;>`^4!#hƔlUw)N[W 1F8+yD-ɜKˎRL/X{" j B g2Olp2^p 6ej) bI1}~3~eda!@օ͐^R%ĈL9*o1P `V;\Ɍd~?!N<9jb5OG'eb2548tNE)Oª2HFP4{Q!dvf^Jk ^3A! Ĭa\+0x/Պ-̩2 >!i_!aeh`L ׻ۖ) qAy[ϙ~kf, @fӅ,HpQBw)K^1v.&.1H l(&(K,9 l̚ *X\8"${Ù-!,E|9cBБ\D@ZIKZHo $&?.myNCV Dž8ŕ]@~>0H*L qJؔX"ᎉx!c틛A:H(RQ\l lFՄkJG2 ~_*QGE 8V.G+ygX@`?}ZaTE̅ߍdHΫ<4)!5([Clmj>(vZm8I'Ueg8 w>[#v~HZ=b1:f>7lX)!+Mz --f}7z U@>xRPNYMW a.P.m/iFp>3{W];嵊'xį?zB}P3w! h~nWq1p&V(q]Wӷ;5 5(Xc;1+0ԝAάK\ _UҿhlC.:Sq2ʝvN ?wwV HULd-(Kt隢m}Xwݮkԫ(!ZR=iм4ԵOb >ev$'?3/hy~bZ"bϒs#K9NwJuWYX8Yڃml yEj$5)l#J{їXoMmq హV@V h]u_Q œ]´QQCBD6?C];ItdT`{%(“!l'"Ӑ;x3;bB ^įrvs\yRcX,oi+. &w/MMwi[n#% նbh& ~V%ЬcZ!T$񸪆YF^tulH-VTrMO)sTi dSu4_Zj=N>}YN٪DrlKP3P6e[*z {v@[䱏im{x(ӛTug#t*.s|lVac* NM{ROk۷uU_? i2>W*$b'v^uRkUI_>.LɮMqբPTοAMf~ɺsyg-p84Ѽ+CsWjJ),T39-3B;yHF(*WlG:b˚tFWq'|TdeXPq]VTB;`1%u_3XY{"F%w!EB}hUWk.ZΧ>+2v PܛW'u@}C Dm4}ZR+lK YP:98ɧ盦3ߣw<&׎`Xxr ΕґtTmծ(Z6LRxiL#G 3Y<ˑHHH7E\$'3kj /Wix23`Kݩb Ò@9K3ugHi|jU -jt:n2b "pgr /}w@* )y3c HL%6ԱxR,%? ȩs9Uw`CC*L 60] &99H`5* x29[(mR' ;Jk=#ۚΞүa-X҂8GfaR;zKzS[yFElMJ*n٦pX4(>'{YةGSZ:UoڝmXm;[g\ى1!XGA(e ڧP3MQ>sY(ɂp΄X7ƗF7df=%^5l"_D/ug:Se}V1bhP|v%LWcdsˑx%] q.ϟ[W=5t8 a<|z3EiFj&[+ 'w⸫ͬ:dͽ_nRud]tXŇ9> p}hh% C>WFA,7h=6$;1*N50:[b,f5)2Z}j0uBL $6|3NP#<#dˏ2H.T:}35͆:zA-E/, )B3wb7ֈ^k-bK_] <єJIus(9|,:I3,G9~nJfp h ƽz_ -՘KT}vS>_P/ԛbo9Ob.u\Ym@YoHI_oi_|VST(僇  R^9zE8Y ҀC?+@"/vV2DQGj(NB5ljǀ!Z\ph5eHj's `Bn#7G.O?A Ak_,]z.dž% JiZjKƸ%ǾIvM<ηAuwF՜D mdatNHW_0001libheif-1.17.6/examples/heif-convert.1000664 001750 001750 00000001622 14540541202 020577 0ustar00farindkfarindk000000 000000 .TH HEIF-THUMBNAILER 1 .SH NAME heif-convert \- convert HEIC/HEIF image .SH SYNOPSIS .B heif-convert [\fB\-q\fR \fIQUALITY\fR] .IR filename .IR output[.jpg|.png|.y4m] .SH DESCRIPTION .B heif-convert Convert HEIC/HEIF image to a different image format. .SH OPTIONS .TP .BR \-q\fR\ \fIQUALITY\fR Defines quality level between 0 and 100 for the generated output file. .SH EXIT STATUS .PP \fB0\fR .RS 4 Success .RE .PP \fB1\fR .RS 4 Failure (syntax or usage error; error while loading, converting or writing image). .RE .SH NOTES The available output formats depend on the libraries that were available at compile time. Supported are JPEG, PNG and Y4M, the file type is determined based on the extension of the output file. .SH BUGS Please reports bugs or issues at https://github.com/strukturag/libheif .SH AUTHORS Joachim Bauch, struktur AG .br Dirk Farin, struktur AG .SH COPYRIGHT Copyright \[co] 2017 struktur AG libheif-1.17.6/examples/heif_info.cc000664 001750 001750 00000060202 14540541202 020360 0ustar00farindkfarindk000000 000000 /* libheif example application "heif-info". MIT License Copyright (c) 2017 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #if defined(HAVE_UNISTD_H) #include #else #define STDOUT_FILENO 1 #endif #include #include #include #include #include #include #include #include #include #include "common.h" /* image: 20005 (1920x1080), primary thumbnail: 20010 (320x240) alpha channel: 20012 (1920x1080) metadata: Exif image: 1920x1080 (20005), primary thumbnail: 320x240 (20010) alpha channel: 1920x1080 (20012) info *file info -w 20012 -o out.265 *file info -d // dump */ static struct option long_options[] = { //{"write-raw", required_argument, 0, 'w' }, //{"output", required_argument, 0, 'o' }, {(char* const) "dump-boxes", no_argument, 0, 'd'}, {(char* const) "help", no_argument, 0, 'h'}, {(char* const) "version", no_argument, 0, 'v'}, {0, 0, 0, 0} }; const char* fourcc_to_string(uint32_t fourcc) { static char fcc[5]; fcc[0] = (char) ((fourcc >> 24) & 0xFF); fcc[1] = (char) ((fourcc >> 16) & 0xFF); fcc[2] = (char) ((fourcc >> 8) & 0xFF); fcc[3] = (char) ((fourcc >> 0) & 0xFF); fcc[4] = 0; return fcc; } void show_help(const char* argv0) { fprintf(stderr, " heif-info libheif version: %s\n", heif_get_version()); fprintf(stderr, "------------------------------------\n"); fprintf(stderr, "usage: heif-info [options] image.heic\n"); fprintf(stderr, "\n"); fprintf(stderr, "options:\n"); //fprintf(stderr," -w, --write-raw ID write raw compressed data of image 'ID'\n"); //fprintf(stderr," -o, --output NAME output file name for image selected by -w\n"); fprintf(stderr, " -d, --dump-boxes show a low-level dump of all MP4 file boxes\n"); fprintf(stderr, " -h, --help show help\n"); fprintf(stderr, " -v, --version show version\n"); } class LibHeifInitializer { public: LibHeifInitializer() { heif_init(nullptr); } ~LibHeifInitializer() { heif_deinit(); } }; int main(int argc, char** argv) { // This takes care of initializing libheif and also deinitializing it at the end to free all resources. LibHeifInitializer initializer; bool dump_boxes = false; bool write_raw_image = false; heif_item_id raw_image_id; std::string output_filename = "output.265"; while (true) { int option_index = 0; int c = getopt_long(argc, argv, "dhv", long_options, &option_index); if (c == -1) break; switch (c) { case 'd': dump_boxes = true; break; case 'h': show_help(argv[0]); return 0; case 'w': write_raw_image = true; raw_image_id = atoi(optarg); break; case 'o': output_filename = optarg; break; case 'v': show_version(); return 0; } } if (optind != argc - 1) { show_help(argv[0]); return 0; } (void) raw_image_id; (void) write_raw_image; const char* input_filename = argv[optind]; // ============================================================================== // show MIME type { const static int bufSize = 50; uint8_t buf[bufSize]; FILE* fh = fopen(input_filename, "rb"); if (fh) { std::cout << "MIME type: "; int n = (int) fread(buf, 1, bufSize, fh); const char* mime_type = heif_get_file_mime_type(buf, n); if (*mime_type == 0) { std::cout << "unknown\n"; } else { std::cout << mime_type << "\n"; } fclose(fh); char fourcc[5]; fourcc[4] = 0; heif_brand_to_fourcc(heif_read_main_brand(buf, bufSize), fourcc); std::cout << "main brand: " << fourcc << "\n"; heif_brand2* brands = nullptr; int nBrands = 0; struct heif_error err = heif_list_compatible_brands(buf, n, &brands, &nBrands); if (err.code) { std::cerr << "error reading brands: " << err.message << "\n"; } else { std::cout << "compatible brands: "; for (int i = 0; i < nBrands; i++) { heif_brand_to_fourcc(brands[i], fourcc); if (i > 0) { std::cout << ", "; } std::cout << fourcc; } std::cout << "\n"; heif_free_list_of_compatible_brands(brands); } } } // ============================================================================== std::shared_ptr ctx(heif_context_alloc(), [](heif_context* c) { heif_context_free(c); }); if (!ctx) { fprintf(stderr, "Could not create context object\n"); return 1; } struct heif_error err; err = heif_context_read_from_file(ctx.get(), input_filename, nullptr); if (dump_boxes) { heif_context_debug_dump_boxes_to_file(ctx.get(), STDOUT_FILENO); // dump to stdout return 0; } if (err.code != 0) { std::cerr << "Could not read HEIF/AVIF file: " << err.message << "\n"; return 1; } // ============================================================================== int numImages = heif_context_get_number_of_top_level_images(ctx.get()); std::vector IDs(numImages); heif_context_get_list_of_top_level_image_IDs(ctx.get(), IDs.data(), numImages); for (int i = 0; i < numImages; i++) { std::cout << "\n"; struct heif_image_handle* handle; struct heif_error err = heif_context_get_image_handle(ctx.get(), IDs[i], &handle); if (err.code) { std::cerr << err.message << "\n"; return 10; } int width = heif_image_handle_get_width(handle); int height = heif_image_handle_get_height(handle); int primary = heif_image_handle_is_primary_image(handle); printf("image: %dx%d (id=%d)%s\n", width, height, IDs[i], primary ? ", primary" : ""); heif_colorspace colorspace; heif_chroma chroma; err = heif_image_handle_get_preferred_decoding_colorspace(handle, &colorspace, &chroma); if (err.code) { std::cerr << err.message << "\n"; return 10; } printf(" colorspace: "); switch (colorspace) { case heif_colorspace_YCbCr: printf("YCbCr, "); break; case heif_colorspace_RGB: printf("RGB"); break; case heif_colorspace_monochrome: printf("monochrome"); break; default: printf("unknown"); break; } if (colorspace==heif_colorspace_YCbCr) { switch (chroma) { case heif_chroma_420: printf("4:2:0"); break; case heif_chroma_422: printf("4:2:2"); break; case heif_chroma_444: printf("4:4:4"); break; default: printf("unknown"); break; } } printf("\n"); // --- bit depth int luma_depth = heif_image_handle_get_luma_bits_per_pixel(handle); int chroma_depth = heif_image_handle_get_chroma_bits_per_pixel(handle); printf(" bit depth: "); if (chroma == heif_chroma_monochrome || luma_depth==chroma_depth) { printf("%d\n", luma_depth); } else { printf("%d,%d\n", luma_depth, chroma_depth); } // --- thumbnails int nThumbnails = heif_image_handle_get_number_of_thumbnails(handle); std::vector thumbnailIDs(nThumbnails); nThumbnails = heif_image_handle_get_list_of_thumbnail_IDs(handle, thumbnailIDs.data(), nThumbnails); for (int thumbnailIdx = 0; thumbnailIdx < nThumbnails; thumbnailIdx++) { heif_image_handle* thumbnail_handle; err = heif_image_handle_get_thumbnail(handle, thumbnailIDs[thumbnailIdx], &thumbnail_handle); if (err.code) { std::cerr << err.message << "\n"; return 10; } int th_width = heif_image_handle_get_width(thumbnail_handle); int th_height = heif_image_handle_get_height(thumbnail_handle); printf(" thumbnail: %dx%d\n", th_width, th_height); heif_image_handle_release(thumbnail_handle); } // --- color profile uint32_t profileType = heif_image_handle_get_color_profile_type(handle); printf(" color profile: %s\n", profileType ? fourcc_to_string(profileType) : "no"); // --- depth information bool has_depth = heif_image_handle_has_depth_image(handle); bool has_alpha = heif_image_handle_has_alpha_channel(handle); bool premultiplied_alpha = false; if (has_alpha) { premultiplied_alpha = heif_image_handle_is_premultiplied_alpha(handle); } printf(" alpha channel: %s %s\n", has_alpha ? "yes" : "no", premultiplied_alpha ? "(premultiplied)" : ""); printf(" depth channel: %s\n", has_depth ? "yes" : "no"); heif_item_id depth_id; int nDepthImages = heif_image_handle_get_list_of_depth_image_IDs(handle, &depth_id, 1); if (has_depth) { assert(nDepthImages == 1); } else { assert(nDepthImages == 0); } (void) nDepthImages; if (has_depth) { struct heif_image_handle* depth_handle; err = heif_image_handle_get_depth_image_handle(handle, depth_id, &depth_handle); if (err.code) { fprintf(stderr, "cannot get depth image: %s\n", err.message); return 1; } printf(" size: %dx%d\n", heif_image_handle_get_width(depth_handle), heif_image_handle_get_height(depth_handle)); int depth_luma_bpp = heif_image_handle_get_luma_bits_per_pixel(depth_handle); printf(" bits per pixel: %d\n", depth_luma_bpp); const struct heif_depth_representation_info* depth_info; if (heif_image_handle_get_depth_image_representation_info(handle, depth_id, &depth_info)) { printf(" z-near: "); if (depth_info->has_z_near) printf("%f\n", depth_info->z_near); else printf("undefined\n"); printf(" z-far: "); if (depth_info->has_z_far) printf("%f\n", depth_info->z_far); else printf("undefined\n"); printf(" d-min: "); if (depth_info->has_d_min) printf("%f\n", depth_info->d_min); else printf("undefined\n"); printf(" d-max: "); if (depth_info->has_d_max) printf("%f\n", depth_info->d_max); else printf("undefined\n"); printf(" representation: "); switch (depth_info->depth_representation_type) { case heif_depth_representation_type_uniform_inverse_Z: printf("inverse Z\n"); break; case heif_depth_representation_type_uniform_disparity: printf("uniform disparity\n"); break; case heif_depth_representation_type_uniform_Z: printf("uniform Z\n"); break; case heif_depth_representation_type_nonuniform_disparity: printf("non-uniform disparity\n"); break; default: printf("unknown\n"); } if (depth_info->has_d_min || depth_info->has_d_max) { printf(" disparity_reference_view: %d\n", depth_info->disparity_reference_view); } heif_depth_representation_info_free(depth_info); } heif_image_handle_release(depth_handle); } // --- metadata int numMetadata = heif_image_handle_get_number_of_metadata_blocks(handle, nullptr); printf("metadata:\n"); if (numMetadata > 0) { std::vector ids(numMetadata); heif_image_handle_get_list_of_metadata_block_IDs(handle, nullptr, ids.data(), numMetadata); for (int n = 0; n < numMetadata; n++) { std::string itemtype = heif_image_handle_get_metadata_type(handle, ids[n]); std::string contenttype = heif_image_handle_get_metadata_content_type(handle, ids[n]); std::string item_uri_type = heif_image_handle_get_metadata_item_uri_type(handle, ids[n]); std::string ID{"unknown"}; if (itemtype == "Exif") { ID = itemtype; } else if (itemtype == "uri ") { ID = itemtype + "/" + item_uri_type; } else if (contenttype == "application/rdf+xml") { ID = "XMP"; } else { ID = itemtype + "/" + contenttype; } printf(" %s: %zu bytes\n", ID.c_str(), heif_image_handle_get_metadata_size(handle, ids[n])); } } else { printf(" none\n"); } // --- transforms #define MAX_PROPERTIES 50 heif_property_id transforms[MAX_PROPERTIES]; int nTransforms = heif_item_get_transformation_properties(ctx.get(), IDs[i], transforms, MAX_PROPERTIES); printf("transformations:\n"); int image_width = heif_image_handle_get_ispe_width(handle); int image_height = heif_image_handle_get_ispe_height(handle); if (nTransforms) { for (int k = 0; k < nTransforms; k++) { switch (heif_item_get_property_type(ctx.get(), IDs[i], transforms[k])) { case heif_item_property_type_transform_mirror: printf(" mirror: %s\n", heif_item_get_property_transform_mirror(ctx.get(), IDs[i], transforms[k]) == heif_transform_mirror_direction_horizontal ? "horizontal" : "vertical"); break; case heif_item_property_type_transform_rotation: { int angle = heif_item_get_property_transform_rotation_ccw(ctx.get(), IDs[i], transforms[k]); printf(" angle (ccw): %d\n", angle); if (angle==90 || angle==270) { std::swap(image_width, image_height); } break; } case heif_item_property_type_transform_crop: { int left,top,right,bottom; heif_item_get_property_transform_crop_borders(ctx.get(), IDs[i], transforms[k], image_width, image_height, &left, &top, &right, &bottom); printf(" crop: left=%d top=%d right=%d bottom=%d\n", left,top,right,bottom); break; } default: assert(false); } } } else { printf(" none\n"); } // --- regions int numRegionItems = heif_image_handle_get_number_of_region_items(handle); printf("region annotations:\n"); if (numRegionItems > 0) { std::vector region_items(numRegionItems); heif_image_handle_get_list_of_region_item_ids(handle, region_items.data(), numRegionItems); for (heif_item_id region_item_id : region_items) { struct heif_region_item* region_item; err = heif_context_get_region_item(ctx.get(), region_item_id, ®ion_item); uint32_t reference_width, reference_height; heif_region_item_get_reference_size(region_item, &reference_width, &reference_height); int numRegions = heif_region_item_get_number_of_regions(region_item); printf(" id: %u, reference_width: %u, reference_height: %u, %d regions\n", region_item_id, reference_width, reference_height, numRegions); std::vector regions(numRegions); numRegions = heif_region_item_get_list_of_regions(region_item, regions.data(), numRegions); for (int j = 0; j < numRegions; j++) { printf(" region %d\n", j); heif_region_type type = heif_region_get_type(regions[j]); if (type == heif_region_type_point) { int32_t x; int32_t y; heif_region_get_point(regions[j], &x, &y); printf(" point [x=%i, y=%i]\n", x, y); } else if (type == heif_region_type_rectangle) { int32_t x; int32_t y; uint32_t w; uint32_t h; heif_region_get_rectangle(regions[j], &x, &y, &w, &h); printf(" rectangle [x=%i, y=%i, w=%u, h=%u]\n", x, y, w, h); } else if (type == heif_region_type_ellipse) { int32_t x; int32_t y; uint32_t rx; uint32_t ry; heif_region_get_ellipse(regions[j], &x, &y, &rx, &ry); printf(" ellipse [x=%i, y=%i, r_x=%u, r_y=%u]\n", x, y, rx, ry); } else if (type == heif_region_type_polygon) { int32_t numPoints = heif_region_get_polygon_num_points(regions[j]); std::vector pts(numPoints*2); heif_region_get_polygon_points(regions[j], pts.data()); printf(" polygon ["); for (int p=0;p pts(numPoints*2); heif_region_get_polyline_points(regions[j], pts.data()); printf(" polyline ["); for (int p=0;p mask_data(data_len); heif_region_get_inline_mask_data(regions[j], &x, &y, &w, &h, mask_data.data()); printf(" inline mask [x=%i, y=%i, w=%u, h=%u, data len=%zu]\n", x, y, w, h, mask_data.size()); } } heif_region_release_many(regions.data(), numRegions); heif_region_item_release(region_item); heif_property_id properties[MAX_PROPERTIES]; int nDescr = heif_item_get_properties_of_type(ctx.get(), region_item_id, heif_item_property_type_user_description, properties, MAX_PROPERTIES); for (int k = 0; k < nDescr; k++) { heif_property_user_description* udes; err = heif_item_get_property_user_description(ctx.get(), region_item_id, properties[k], &udes); if (err.code == 0) { printf(" user description:\n"); printf(" lang: %s\n", udes->lang); printf(" name: %s\n", udes->name); printf(" description: %s\n", udes->description); printf(" tags: %s\n", udes->tags); heif_property_user_description_release(udes); } } } } else { printf(" none\n"); } // --- properties printf("properties:\n"); // user descriptions heif_property_id propertyIds[MAX_PROPERTIES]; int count; count = heif_item_get_properties_of_type(ctx.get(), IDs[i], heif_item_property_type_user_description, propertyIds, MAX_PROPERTIES); if (count > 0) { for (int p = 0; p < count; p++) { struct heif_property_user_description* udes; err = heif_item_get_property_user_description(ctx.get(), IDs[i], propertyIds[p], &udes); if (err.code) { std::cerr << "Error reading udes " << IDs[i] << "/" << propertyIds[p] << "\n"; } else { printf(" user description:\n"); printf(" lang: %s\n", udes->lang); printf(" name: %s\n", udes->name); printf(" description: %s\n", udes->description); printf(" tags: %s\n", udes->tags); heif_property_user_description_release(udes); } } } struct heif_image* image; err = heif_decode_image(handle, &image, heif_colorspace_undefined, heif_chroma_undefined, nullptr); if (err.code) { heif_image_handle_release(handle); std::cerr << "Could not decode image " << err.message << "\n"; return 1; } if (image) { uint32_t aspect_h, aspect_v; heif_image_get_pixel_aspect_ratio(image, &aspect_h, &aspect_v); if (aspect_h != aspect_v) { std::cout << "pixel aspect ratio: " << aspect_h << "/" << aspect_v << "\n"; } if (heif_image_has_content_light_level(image)) { struct heif_content_light_level clli{}; heif_image_get_content_light_level(image, &clli); std::cout << "content light level (clli):\n" << " max content light level: " << clli.max_content_light_level << "\n" << " max pic average light level: " << clli.max_pic_average_light_level << "\n"; } if (heif_image_has_mastering_display_colour_volume(image)) { struct heif_mastering_display_colour_volume mdcv; heif_image_get_mastering_display_colour_volume(image, &mdcv); struct heif_decoded_mastering_display_colour_volume decoded_mdcv; err = heif_mastering_display_colour_volume_decode(&mdcv, &decoded_mdcv); std::cout << "mastering display color volume:\n" << " display_primaries (x,y): " << "(" << decoded_mdcv.display_primaries_x[0] << ";" << decoded_mdcv.display_primaries_y[0] << "), " << "(" << decoded_mdcv.display_primaries_x[1] << ";" << decoded_mdcv.display_primaries_y[1] << "), " << "(" << decoded_mdcv.display_primaries_x[2] << ";" << decoded_mdcv.display_primaries_y[2] << ")\n"; std::cout << " white point (x,y): (" << decoded_mdcv.white_point_x << ";" << decoded_mdcv.white_point_y << ")\n"; std::cout << " max display mastering luminance: " << decoded_mdcv.max_display_mastering_luminance << "\n"; std::cout << " min display mastering luminance: " << decoded_mdcv.min_display_mastering_luminance << "\n"; } } heif_image_release(image); heif_image_handle_release(handle); } #if 0 std::cout << "num images: " << heif_context_get_number_of_top_level_images(ctx.get()) << "\n"; struct heif_image_handle* handle; err = heif_context_get_primary_image_handle(ctx.get(), &handle); if (err.code != 0) { std::cerr << "Could not get primage image handle: " << err.message << "\n"; return 1; } struct heif_image* image; err = heif_decode_image(handle, &image, heif_colorspace_undefined, heif_chroma_undefined, NULL); if (err.code != 0) { heif_image_handle_release(handle); std::cerr << "Could not decode primage image: " << err.message << "\n"; return 1; } heif_image_release(image); heif_image_handle_release(handle); #endif return 0; } libheif-1.17.6/examples/encoder_png.h000664 001750 001750 00000004324 14540541202 020562 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". MIT License Copyright (c) 2017 struktur AG, Joachim Bauch Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef EXAMPLE_ENCODER_PNG_H #define EXAMPLE_ENCODER_PNG_H #include #include "encoder.h" class PngEncoder : public Encoder { public: PngEncoder(); // 0 = fastest compression // 9 = best compression // -1 = zlib default void set_compression_level(int level) { m_compression_level = level; } heif_colorspace colorspace(bool has_alpha) const override { return heif_colorspace_RGB; } heif_chroma chroma(bool has_alpha, int bit_depth) const override { if (bit_depth == 8) { if (has_alpha) return heif_chroma_interleaved_RGBA; else return heif_chroma_interleaved_RGB; } else { if (has_alpha) return heif_chroma_interleaved_RRGGBBAA_BE; else return heif_chroma_interleaved_RRGGBB_BE; } } bool Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) override; private: int m_compression_level = -1; }; #endif // EXAMPLE_ENCODER_PNG_H libheif-1.17.6/examples/heif-info.1000664 001750 001750 00000001223 14540541202 020047 0ustar00farindkfarindk000000 000000 .TH HEIF-INFO 1 .SH NAME heif-info \- show information on HEIC/HEIF file .SH SYNOPSIS .B heif-info [\fB\-d\fR|\fB--dump-boxes\fR] [\fB\-h\fR|\fB--help\fR] .IR filename .SH DESCRIPTION .B heif-info Show information on HEIC/HEIF file. .SH OPTIONS .TP .BR \-d ", " \-\-dump-boxes\fR Show a low-level dump of all MP4 file boxes. .TP .BR \-help ", " \-\-help\fR Show help. .SH EXIT STATUS .PP \fB0\fR .RS 4 Success .RE .PP \fB1\fR .RS 4 Failure (syntax or usage error; error while loading image). .RE .SH BUGS Please reports bugs or issues at https://github.com/strukturag/libheif .SH AUTHORS Dirk Farin, struktur AG .SH COPYRIGHT Copyright \[co] 2017 struktur AG libheif-1.17.6/examples/heif_thumbnailer.cc000664 001750 001750 00000013661 14540541202 021746 0ustar00farindkfarindk000000 000000 /* libheif thumbnailer for Gnome desktop. MIT License Copyright (c) 2018 Dirk Farin 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. */ #if defined(HAVE_UNISTD_H) # include #endif #include #include #include #include #include "encoder.h" #if HAVE_LIBPNG # include "encoder_png.h" #include "common.h" #endif #if defined(_MSC_VER) #include "getopt.h" #endif static int usage(const char* command) { fprintf(stderr, "usage: %s [-s size] [-p] \n", command); fprintf(stderr, " -p Render thumbnail from primary image, even if thumbnail is stored in image.\n"); return 1; } class LibHeifInitializer { public: LibHeifInitializer() { heif_init(nullptr); } ~LibHeifInitializer() { heif_deinit(); } }; int main(int argc, char** argv) { // This takes care of initializing libheif and also deinitializing it at the end to free all resources. LibHeifInitializer initializer; int opt; int size = 512; // default thumbnail size bool thumbnail_from_primary_image_only = false; while ((opt = getopt(argc, argv, "s:hpv")) != -1) { switch (opt) { case 's': size = atoi(optarg); break; case 'p': thumbnail_from_primary_image_only = true; break; case 'v': show_version(); return 0; case 'h': default: return usage(argv[0]); } } if (optind + 2 > argc) { // Need input and output filenames as additional arguments. return usage(argv[0]); } std::string input_filename(argv[optind++]); std::string output_filename(argv[optind++]); // --- read heif file std::shared_ptr context(heif_context_alloc(), [](heif_context* c) { heif_context_free(c); }); struct heif_error err; err = heif_context_read_from_file(context.get(), input_filename.c_str(), nullptr); if (err.code != 0) { std::cerr << "Could not read HEIF file: " << err.message << "\n"; return 1; } // --- get primary image struct heif_image_handle* image_handle = NULL; err = heif_context_get_primary_image_handle(context.get(), &image_handle); if (err.code) { std::cerr << "Could not read HEIF image : " << err.message << "\n"; return 1; } // --- if image has a thumbnail, use that instead if (!thumbnail_from_primary_image_only) { heif_item_id thumbnail_ID; int nThumbnails = heif_image_handle_get_list_of_thumbnail_IDs(image_handle, &thumbnail_ID, 1); if (nThumbnails > 0) { struct heif_image_handle* thumbnail_handle; err = heif_image_handle_get_thumbnail(image_handle, thumbnail_ID, &thumbnail_handle); if (err.code) { std::cerr << "Could not read HEIF image : " << err.message << "\n"; return 1; } // replace image handle with thumbnail handle heif_image_handle_release(image_handle); image_handle = thumbnail_handle; } } // --- decode the image (or its thumbnail) std::unique_ptr encoder(new PngEncoder()); struct heif_decoding_options* decode_options = heif_decoding_options_alloc(); encoder->UpdateDecodingOptions(image_handle, decode_options); decode_options->convert_hdr_to_8bit = true; int bit_depth = 8; struct heif_image* image = NULL; err = heif_decode_image(image_handle, &image, encoder->colorspace(false), encoder->chroma(false, bit_depth), decode_options); if (err.code) { std::cerr << "Could not decode HEIF image : " << err.message << "\n"; return 1; } assert(image); // --- compute output thumbnail size int input_width = heif_image_handle_get_width(image_handle); int input_height = heif_image_handle_get_height(image_handle); if (input_width > size || input_height > size) { int thumbnail_width; int thumbnail_height; if (input_width > input_height) { thumbnail_height = input_height * size / input_width; thumbnail_width = size; } else if (input_height > 0) { thumbnail_width = input_width * size / input_height; thumbnail_height = size; } else { thumbnail_width = thumbnail_height = 0; } // --- output thumbnail smaller than HEIF thumbnail -> scale down struct heif_image* scaled_image = NULL; err = heif_image_scale_image(image, &scaled_image, thumbnail_width, thumbnail_height, NULL); if (err.code) { std::cerr << "Could not scale image : " << err.message << "\n"; return 1; } heif_image_release(image); image = scaled_image; } // --- write thumbnail image to PNG bool written = encoder->Encode(image_handle, image, output_filename.c_str()); if (!written) { fprintf(stderr, "could not write image\n"); return 1; } heif_image_release(image); heif_image_handle_release(image_handle); return 0; } libheif-1.17.6/examples/demo.html000664 001750 001750 00000027063 14540541202 017745 0ustar00farindkfarindk000000 000000 libheif decoder demo

libheif decoder demo

Fork me on GitHub
Copyright © 2017-2018 by struktur AG
Loading, please wait...
libheif-1.17.6/examples/heif_convert.cc000664 001750 001750 00000056336 14540541202 021122 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". MIT License Copyright (c) 2017 struktur AG, Joachim Bauch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #if defined(HAVE_UNISTD_H) #include #endif #include #include #include #include #include #include #include #include #include "encoder.h" #if HAVE_LIBJPEG #include "encoder_jpeg.h" #endif #if HAVE_LIBPNG #include "encoder_png.h" #endif #include "encoder_y4m.h" #include "common.h" #if defined(_MSC_VER) #include "getopt.h" #endif #define UNUSED(x) (void)x static void show_help(const char* argv0) { std::cerr << " heif-convert libheif version: " << heif_get_version() << "\n" << "-------------------------------------------\n" "Usage: heif-convert [options] [output-image]\n" "\n" "The program determines the output file format from the output filename suffix.\n" "These suffixes are recognized: jpg, jpeg, png, y4m. If no output filename is specified, 'jpg' is used.\n" "\n" "Options:\n" " -h, --help show help\n" " -v, --version show version\n" " -q, --quality quality (for JPEG output)\n" " -o, --output FILENAME write output to FILENAME (optional)\n" " -d, --decoder ID use a specific decoder (see --list-decoders)\n" " --with-aux also write auxiliary images (e.g. depth images)\n" " --with-xmp write XMP metadata to file (output filename with .xmp suffix)\n" " --with-exif write EXIF metadata to file (output filename with .exif suffix)\n" " --skip-exif-offset skip EXIF metadata offset bytes\n" " --no-colons replace ':' characters in auxiliary image filenames with '_'\n" " --list-decoders list all available decoders (built-in and plugins)\n" " --quiet do not output status messages to console\n" " -C, --chroma-upsampling ALGO Force chroma upsampling algorithm (nn = nearest-neighbor / bilinear)\n" " --png-compression-level # Set to integer between 0 (fastest) and 9 (best). Use -1 for default.\n"; } class ContextReleaser { public: ContextReleaser(struct heif_context* ctx) : ctx_(ctx) {} ~ContextReleaser() { heif_context_free(ctx_); } private: struct heif_context* ctx_; }; int option_quiet = 0; int option_aux = 0; int option_no_colons = 0; int option_with_xmp = 0; int option_with_exif = 0; int option_skip_exif_offset = 0; int option_list_decoders = 0; int option_png_compression_level = -1; // use zlib default std::string output_filename; std::string chroma_upsampling; #define OPTION_PNG_COMPRESSION_LEVEL 1000 static struct option long_options[] = { {(char* const) "quality", required_argument, 0, 'q'}, {(char* const) "strict", no_argument, 0, 's'}, {(char* const) "decoder", required_argument, 0, 'd'}, {(char* const) "output", required_argument, 0, 'o'}, {(char* const) "quiet", no_argument, &option_quiet, 1}, {(char* const) "with-aux", no_argument, &option_aux, 1}, {(char* const) "with-xmp", no_argument, &option_with_xmp, 1}, {(char* const) "with-exif", no_argument, &option_with_exif, 1}, {(char* const) "skip-exif-offset", no_argument, &option_skip_exif_offset, 1}, {(char* const) "no-colons", no_argument, &option_no_colons, 1}, {(char* const) "list-decoders", no_argument, &option_list_decoders, 1}, {(char* const) "help", no_argument, 0, 'h'}, {(char* const) "chroma-upsampling", required_argument, 0, 'C'}, {(char* const) "png-compression-level", required_argument, 0, OPTION_PNG_COMPRESSION_LEVEL}, {(char* const) "version", no_argument, 0, 'v'} }; #define MAX_DECODERS 20 void list_decoders(heif_compression_format format) { const heif_decoder_descriptor* decoders[MAX_DECODERS]; int n = heif_get_decoder_descriptors(format, decoders, MAX_DECODERS); for (int i=0;i=1 ; i--) { if (!isdigit(s[i])) { return false; } } return true; } void show_png_compression_level_usage_warning() { fprintf(stderr, "Invalid PNG compression level. Has to be between 0 (fastest) and 9 (best).\n" "You can also use -1 to use the default compression level.\n"); } class LibHeifInitializer { public: LibHeifInitializer() { heif_init(nullptr); } ~LibHeifInitializer() { heif_deinit(); } }; int main(int argc, char** argv) { // This takes care of initializing libheif and also deinitializing it at the end to free all resources. LibHeifInitializer initializer; int quality = -1; // Use default quality. bool strict_decoding = false; const char* decoder_id = nullptr; UNUSED(quality); // The quality will only be used by encoders that support it. //while ((opt = getopt(argc, argv, "q:s")) != -1) { while (true) { int option_index = 0; int c = getopt_long(argc, argv, "hq:sd:C:vo:", long_options, &option_index); if (c == -1) { break; } switch (c) { case 'q': quality = atoi(optarg); break; case 'd': decoder_id = optarg; break; case 's': strict_decoding = true; break; case '?': std::cerr << "\n"; // fallthrough case 'h': show_help(argv[0]); return 0; case 'C': chroma_upsampling = optarg; if (chroma_upsampling != "nn" && chroma_upsampling != "nearest-neighbor" && chroma_upsampling != "bilinear") { fprintf(stderr, "Undefined chroma upsampling algorithm.\n"); exit(5); } if (chroma_upsampling == "nn") { // abbreviation chroma_upsampling = "nearest-neighbor"; } break; case OPTION_PNG_COMPRESSION_LEVEL: if (!is_integer_string(optarg)) { show_png_compression_level_usage_warning(); exit(5); } option_png_compression_level = std::stoi(optarg); if (option_png_compression_level < -1 || option_png_compression_level > 9) { show_png_compression_level_usage_warning(); exit(5); } break; case 'v': show_version(); return 0; case 'o': output_filename = optarg; break; } } if (option_list_decoders) { list_all_decoders(); return 0; } if (optind >= argc || optind + 2 < argc) { // Need at least input filename as additional argument, but not more as two filenames. show_help(argv[0]); return 5; } std::string input_filename(argv[optind++]); std::string output_filename_stem; std::string output_filename_suffix; if (output_filename.empty()) { if (optind == argc) { std::string input_stem; size_t dot_pos = input_filename.rfind('.'); if (dot_pos != std::string::npos) { input_stem = input_filename.substr(0, dot_pos); } else { input_stem = input_filename; } output_filename = input_stem + ".jpg"; } else if (optind == argc-1) { output_filename = argv[optind]; } else { assert(false); } } std::unique_ptr encoder; size_t dot_pos = output_filename.rfind('.'); if (dot_pos != std::string::npos) { output_filename_stem = output_filename.substr(0,dot_pos); std::string suffix_lowercase = output_filename.substr(dot_pos + 1); std::transform(suffix_lowercase.begin(), suffix_lowercase.end(), suffix_lowercase.begin(), ::tolower); output_filename_suffix = suffix_lowercase; if (suffix_lowercase == "jpg" || suffix_lowercase == "jpeg") { #if HAVE_LIBJPEG static const int kDefaultJpegQuality = 90; if (quality == -1) { quality = kDefaultJpegQuality; } encoder.reset(new JpegEncoder(quality)); #else fprintf(stderr, "JPEG support has not been compiled in.\n"); return 1; #endif // HAVE_LIBJPEG } if (suffix_lowercase == "png") { #if HAVE_LIBPNG auto pngEncoder = new PngEncoder(); pngEncoder->set_compression_level(option_png_compression_level); encoder.reset(pngEncoder); #else fprintf(stderr, "PNG support has not been compiled in.\n"); return 1; #endif // HAVE_LIBPNG } if (suffix_lowercase == "y4m") { encoder.reset(new Y4MEncoder()); } } else { output_filename_stem = output_filename; output_filename_suffix = "jpg"; } if (!encoder) { fprintf(stderr, "Unknown file type in %s\n", output_filename.c_str()); return 1; } // --- check whether input is a supported HEIF file // TODO: when we are reading from named pipes, we probably should not consume any bytes // just for file-type checking. // TODO: check, whether reading from named pipes works at all. std::ifstream istr(input_filename.c_str(), std::ios_base::binary); uint8_t magic[12]; istr.read((char*) magic, 12); if (heif_check_jpeg_filetype(magic, 12)) { fprintf(stderr, "Input file '%s' is a JPEG image\n", input_filename.c_str()); return 1; } enum heif_filetype_result filetype_check = heif_check_filetype(magic, 12); if (filetype_check == heif_filetype_no) { fprintf(stderr, "Input file is not an HEIF/AVIF file\n"); return 1; } if (filetype_check == heif_filetype_yes_unsupported) { fprintf(stderr, "Input file is an unsupported HEIF/AVIF file type\n"); return 1; } // --- read the HEIF file struct heif_context* ctx = heif_context_alloc(); if (!ctx) { fprintf(stderr, "Could not create context object\n"); return 1; } ContextReleaser cr(ctx); struct heif_error err; err = heif_context_read_from_file(ctx, input_filename.c_str(), nullptr); if (err.code != 0) { std::cerr << "Could not read HEIF/AVIF file: " << err.message << "\n"; return 1; } int num_images = heif_context_get_number_of_top_level_images(ctx); if (num_images == 0) { fprintf(stderr, "File doesn't contain any images\n"); return 1; } if (!option_quiet) { std::cout << "File contains " << num_images << " image" << (num_images>1 ? "s" : "") << "\n"; } std::vector image_IDs(num_images); num_images = heif_context_get_list_of_top_level_image_IDs(ctx, image_IDs.data(), num_images); std::string filename; size_t image_index = 1; // Image filenames are "1" based. for (int idx = 0; idx < num_images; ++idx) { std::string numbered_output_filename_stem; if (num_images > 1) { std::ostringstream s; s << output_filename_stem; s << "-" << image_index; numbered_output_filename_stem = s.str(); s << "." << output_filename_suffix; filename.assign(s.str()); } else { filename.assign(output_filename); numbered_output_filename_stem = output_filename_stem; } struct heif_image_handle* handle; err = heif_context_get_image_handle(ctx, image_IDs[idx], &handle); if (err.code) { std::cerr << "Could not read HEIF/AVIF image " << idx << ": " << err.message << "\n"; return 1; } int has_alpha = heif_image_handle_has_alpha_channel(handle); struct heif_decoding_options* decode_options = heif_decoding_options_alloc(); encoder->UpdateDecodingOptions(handle, decode_options); decode_options->strict_decoding = strict_decoding; decode_options->decoder_id = decoder_id; if (chroma_upsampling=="nearest-neighbor") { decode_options->color_conversion_options.preferred_chroma_upsampling_algorithm = heif_chroma_upsampling_nearest_neighbor; decode_options->color_conversion_options.only_use_preferred_chroma_algorithm = true; } else if (chroma_upsampling=="bilinear") { decode_options->color_conversion_options.preferred_chroma_upsampling_algorithm = heif_chroma_upsampling_bilinear; decode_options->color_conversion_options.only_use_preferred_chroma_algorithm = true; } int bit_depth = heif_image_handle_get_luma_bits_per_pixel(handle); if (bit_depth < 0) { heif_decoding_options_free(decode_options); heif_image_handle_release(handle); std::cerr << "Input image has undefined bit-depth\n"; return 1; } struct heif_image* image; err = heif_decode_image(handle, &image, encoder->colorspace(has_alpha), encoder->chroma(has_alpha, bit_depth), decode_options); heif_decoding_options_free(decode_options); if (err.code) { heif_image_handle_release(handle); std::cerr << "Could not decode image: " << idx << ": " << err.message << "\n"; return 1; } // show decoding warnings for (int i = 0;; i++) { int n = heif_image_get_decoding_warnings(image, i, &err, 1); if (n == 0) { break; } std::cerr << "Warning: " << err.message << "\n"; } if (image) { bool written = encoder->Encode(handle, image, filename); if (!written) { fprintf(stderr, "could not write image\n"); } else { if (!option_quiet) { std::cout << "Written to " << filename << "\n"; } } heif_image_release(image); if (option_aux) { int has_depth = heif_image_handle_has_depth_image(handle); if (has_depth) { heif_item_id depth_id; int nDepthImages = heif_image_handle_get_list_of_depth_image_IDs(handle, &depth_id, 1); assert(nDepthImages == 1); (void) nDepthImages; struct heif_image_handle* depth_handle; err = heif_image_handle_get_depth_image_handle(handle, depth_id, &depth_handle); if (err.code) { heif_image_handle_release(handle); std::cerr << "Could not read depth channel\n"; return 1; } int depth_bit_depth = heif_image_handle_get_luma_bits_per_pixel(depth_handle); struct heif_image* depth_image; err = heif_decode_image(depth_handle, &depth_image, encoder->colorspace(false), encoder->chroma(false, depth_bit_depth), nullptr); if (err.code) { heif_image_handle_release(depth_handle); heif_image_handle_release(handle); std::cerr << "Could not decode depth image: " << err.message << "\n"; return 1; } std::ostringstream s; s << numbered_output_filename_stem; s << "-depth."; s << output_filename_suffix; written = encoder->Encode(depth_handle, depth_image, s.str()); if (!written) { fprintf(stderr, "could not write depth image\n"); } else { if (!option_quiet) { std::cout << "Depth image written to " << s.str() << "\n"; } } heif_image_release(depth_image); heif_image_handle_release(depth_handle); } } // --- aux images if (option_aux) { int nAuxImages = heif_image_handle_get_number_of_auxiliary_images(handle, LIBHEIF_AUX_IMAGE_FILTER_OMIT_ALPHA | LIBHEIF_AUX_IMAGE_FILTER_OMIT_DEPTH); if (nAuxImages > 0) { std::vector auxIDs(nAuxImages); heif_image_handle_get_list_of_auxiliary_image_IDs(handle, LIBHEIF_AUX_IMAGE_FILTER_OMIT_ALPHA | LIBHEIF_AUX_IMAGE_FILTER_OMIT_DEPTH, auxIDs.data(), nAuxImages); for (heif_item_id auxId: auxIDs) { struct heif_image_handle* aux_handle; err = heif_image_handle_get_auxiliary_image_handle(handle, auxId, &aux_handle); if (err.code) { heif_image_handle_release(handle); std::cerr << "Could not read auxiliary image\n"; return 1; } int aux_bit_depth = heif_image_handle_get_luma_bits_per_pixel(aux_handle); struct heif_image* aux_image; err = heif_decode_image(aux_handle, &aux_image, encoder->colorspace(false), encoder->chroma(false, aux_bit_depth), nullptr); if (err.code) { heif_image_handle_release(aux_handle); heif_image_handle_release(handle); std::cerr << "Could not decode auxiliary image: " << err.message << "\n"; return 1; } const char* auxTypeC = nullptr; err = heif_image_handle_get_auxiliary_type(aux_handle, &auxTypeC); if (err.code) { heif_image_handle_release(aux_handle); heif_image_handle_release(handle); std::cerr << "Could not get type of auxiliary image: " << err.message << "\n"; return 1; } std::string auxType = std::string(auxTypeC); heif_image_handle_release_auxiliary_type(aux_handle, &auxTypeC); std::ostringstream s; s << numbered_output_filename_stem; s << "-" + auxType + "."; s << output_filename_suffix; std::string auxFilename = s.str(); if (option_no_colons) { std::replace(auxFilename.begin(), auxFilename.end(), ':', '_'); } written = encoder->Encode(aux_handle, aux_image, auxFilename); if (!written) { fprintf(stderr, "could not write auxiliary image\n"); } else { if (!option_quiet) { std::cout << "Auxiliary image written to " << auxFilename << "\n"; } } heif_image_release(aux_image); heif_image_handle_release(aux_handle); } } } // --- write metadata if (option_with_xmp || option_with_exif) { int numMetadata = heif_image_handle_get_number_of_metadata_blocks(handle, nullptr); if (numMetadata>0) { std::vector ids(numMetadata); heif_image_handle_get_list_of_metadata_block_IDs(handle, nullptr, ids.data(), numMetadata); for (int n = 0; n < numMetadata; n++) { // check whether metadata block is XMP std::string itemtype = heif_image_handle_get_metadata_type(handle, ids[n]); std::string contenttype = heif_image_handle_get_metadata_content_type(handle, ids[n]); if (option_with_xmp && contenttype == "application/rdf+xml") { // read XMP data to memory array size_t xmpSize = heif_image_handle_get_metadata_size(handle, ids[n]); std::vector xmp(xmpSize); err = heif_image_handle_get_metadata(handle, ids[n], xmp.data()); if (err.code) { heif_image_handle_release(handle); std::cerr << "Could not read XMP metadata: " << err.message << "\n"; return 1; } // write XMP data to file std::string xmp_filename = numbered_output_filename_stem + ".xmp"; std::ofstream ostr(xmp_filename.c_str()); ostr.write((char*)xmp.data(), xmpSize); } else if (option_with_exif && itemtype == "Exif") { // read EXIF data to memory array size_t exifSize = heif_image_handle_get_metadata_size(handle, ids[n]); std::vector exif(exifSize); err = heif_image_handle_get_metadata(handle, ids[n], exif.data()); if (err.code) { heif_image_handle_release(handle); std::cerr << "Could not read EXIF metadata: " << err.message << "\n"; return 1; } uint32_t offset = 0; if (option_skip_exif_offset) { if (exifSize<4) { heif_image_handle_release(handle); std::cerr << "Invalid EXIF metadata, it is too small.\n"; return 1; } offset = (exif[0]<<24) | (exif[1]<<16) | (exif[2]<<8) | exif[3]; offset += 4; if (offset >= exifSize) { heif_image_handle_release(handle); std::cerr << "Invalid EXIF metadata, offset out of range.\n"; return 1; } } // write EXIF data to file std::string exif_filename = numbered_output_filename_stem + ".exif"; std::ofstream ostr(exif_filename.c_str()); ostr.write((char*)exif.data() + offset, exifSize - offset); } } } } heif_image_handle_release(handle); } image_index++; } return 0; } libheif-1.17.6/examples/benchmark.cc000664 001750 001750 00000005567 14540541202 020401 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2022 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include "benchmark.h" #include "libheif/heif.h" #include double compute_psnr(heif_image* original_image, const std::string& encoded_file) { double psnr = 0.0; // read encoded image struct heif_context* ctx = nullptr; struct heif_image_handle* handle = nullptr; struct heif_image* image = nullptr; heif_error err{}; int orig_stride = 0; const uint8_t* orig_p = nullptr; int compressed_stride = 0; const uint8_t* compressed_p = nullptr; int w = 0, h = 0; double mse = 0.0; if (heif_image_get_colorspace(original_image) != heif_colorspace_YCbCr && heif_image_get_colorspace(original_image) != heif_colorspace_monochrome) { fprintf(stderr, "Benchmark can only be computed on YCbCr or monochrome images\n"); goto cleanup; } ctx = heif_context_alloc(); err = heif_context_read_from_file(ctx, encoded_file.c_str(), nullptr); if (err.code) { fprintf(stderr, "Error reading encoded file: %s\n", err.message); goto cleanup; } err = heif_context_get_primary_image_handle(ctx, &handle); if (err.code) { fprintf(stderr, "Error getting primary image handle: %s\n", err.message); goto cleanup; } err = heif_decode_image(handle, &image, heif_image_get_colorspace(original_image), heif_image_get_chroma_format(original_image), nullptr); if (err.code) { fprintf(stderr, "Error decoding image: %s\n", err.message); goto cleanup; } w = heif_image_get_width(original_image, heif_channel_Y); h = heif_image_get_height(original_image, heif_channel_Y); orig_p = heif_image_get_plane_readonly(original_image, heif_channel_Y, &orig_stride); compressed_p = heif_image_get_plane_readonly(image, heif_channel_Y, &compressed_stride); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int d = orig_p[y * orig_stride + x] - compressed_p[y * compressed_stride + x]; mse += d * d; } } mse /= w * h; psnr = 10 * log10(255.0 * 255.0 / mse); cleanup: heif_image_release(image); heif_image_handle_release(handle); heif_context_free(ctx); return psnr; } libheif-1.17.6/examples/decoder_y4m.cc000664 001750 001750 00000007264 14540541202 020641 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "decoder_y4m.h" #include #include #include #include InputImage loadY4M(const char* filename) { InputImage inputimage; struct heif_image* image = nullptr; // open input file std::ifstream istr(filename, std::ios_base::binary); if (istr.fail()) { std::cerr << "Can't open " << filename << "\n"; exit(1); } std::string header; getline(istr, header); if (header.find("YUV4MPEG2 ") != 0) { std::cerr << "Input is not a Y4M file.\n"; exit(1); } int w = -1; int h = -1; size_t pos = 0; for (;;) { pos = header.find(' ', pos + 1) + 1; if (pos == std::string::npos) { break; } size_t end = header.find_first_of(" \n", pos + 1); if (end == std::string::npos) { break; } if (end - pos <= 1) { std::cerr << "Header format error in Y4M file.\n"; exit(1); } char tag = header[pos]; std::string value = header.substr(pos + 1, end - pos - 1); if (tag == 'W') { w = atoi(value.c_str()); } else if (tag == 'H') { h = atoi(value.c_str()); } } std::string frameheader; getline(istr, frameheader); if (frameheader != "FRAME") { std::cerr << "Y4M misses the frame header.\n"; exit(1); } if (w < 0 || h < 0) { std::cerr << "Y4M has invalid frame size.\n"; exit(1); } struct heif_error err = heif_image_create(w, h, heif_colorspace_YCbCr, heif_chroma_420, &image); (void) err; // TODO: handle error heif_image_add_plane(image, heif_channel_Y, w, h, 8); heif_image_add_plane(image, heif_channel_Cb, (w + 1) / 2, (h + 1) / 2, 8); heif_image_add_plane(image, heif_channel_Cr, (w + 1) / 2, (h + 1) / 2, 8); int y_stride, cb_stride, cr_stride; uint8_t* py = heif_image_get_plane(image, heif_channel_Y, &y_stride); uint8_t* pcb = heif_image_get_plane(image, heif_channel_Cb, &cb_stride); uint8_t* pcr = heif_image_get_plane(image, heif_channel_Cr, &cr_stride); for (int y = 0; y < h; y++) { istr.read((char*) (py + y * y_stride), w); } for (int y = 0; y < (h + 1) / 2; y++) { istr.read((char*) (pcb + y * cb_stride), (w + 1) / 2); } for (int y = 0; y < (h + 1) / 2; y++) { istr.read((char*) (pcr + y * cr_stride), (w + 1) / 2); } inputimage.image = std::shared_ptr(image, [](heif_image* img) { heif_image_release(img); }); return inputimage; } libheif-1.17.6/examples/encoder_y4m.h000664 001750 001750 00000003532 14540541202 020507 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". MIT License Copyright (c) 2019 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef EXAMPLE_ENCODER_Y4M_H #define EXAMPLE_ENCODER_Y4M_H #include #include "encoder.h" class Y4MEncoder : public Encoder { public: Y4MEncoder(); heif_colorspace colorspace(bool has_alpha) const override { return heif_colorspace_YCbCr; } heif_chroma chroma(bool has_alpha, int bit_depth) const override { return heif_chroma_420; } void UpdateDecodingOptions(const struct heif_image_handle* handle, struct heif_decoding_options* options) const override; bool Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) override; private: }; #endif // EXAMPLE_ENCODER_Y4M_H libheif-1.17.6/examples/CMakeLists.txt000664 001750 001750 00000006467 14540541202 020700 0ustar00farindkfarindk000000 000000 # Needed to find libheif/heif_version.h while compiling the library include_directories(${libheif_BINARY_DIR} ${libheif_SOURCE_DIR}) if (MSVC) set(getopt_sources ../extra/getopt.c ../extra/getopt.h ../extra/getopt_long.c ) include_directories("../extra") endif () add_executable(heif-info ${getopt_sources} heif_info.cc common.cc common.h) target_link_libraries(heif-info heif) install(TARGETS heif-info RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES heif-info.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) add_executable(heif-convert ${getopt_sources} encoder.cc encoder.h encoder_y4m.cc encoder_y4m.h heif_convert.cc ../libheif/exif.cc ../libheif/exif.cc common.cc common.h) target_link_libraries(heif-convert PRIVATE heif) install(TARGETS heif-convert RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES heif-convert.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) add_executable(heif-enc ${getopt_sources} heif_enc.cc ../libheif/exif.cc ../libheif/exif.cc benchmark.h benchmark.cc encoder.cc decoder_y4m.cc decoder_y4m.h common.cc common.h) target_link_libraries(heif-enc PRIVATE heif) install(TARGETS heif-enc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES heif-enc.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) add_executable(heif-test ${getopt_sources} heif_test.cc common.cc common.h) target_link_libraries(heif-test heif) find_package(JPEG) if (TARGET JPEG::JPEG) add_definitions(-DHAVE_LIBJPEG=1) include(CheckCXXSourceCompiles) # this is needed for CheckCXXSourceCompiles set(CMAKE_REQUIRED_LIBRARIES ${JPEG_LIBRARIES}) set(CMAKE_REQUIRED_INCLUDES ${JPEG_INCLUDE_DIRS}) check_cxx_source_compiles(" #include #include #include int main() { jpeg_write_icc_profile(NULL, NULL, 0); return 0; } " HAVE_JPEG_WRITE_ICC_PROFILE) unset(CMAKE_REQUIRED_LIBRARIES) unset(CMAKE_REQUIRED_INCLUDES) if (HAVE_JPEG_WRITE_ICC_PROFILE) add_definitions(-DHAVE_JPEG_WRITE_ICC_PROFILE=1) endif () target_link_libraries(heif-convert PRIVATE JPEG::JPEG) target_link_libraries(heif-enc PRIVATE JPEG::JPEG) target_sources(heif-convert PRIVATE encoder_jpeg.cc encoder_jpeg.h) target_sources(heif-enc PRIVATE decoder.h decoder_jpeg.cc decoder_jpeg.h) endif () find_package(PNG) if (TARGET PNG::PNG) add_definitions(-DHAVE_LIBPNG=1) target_link_libraries(heif-convert PRIVATE PNG::PNG) target_link_libraries(heif-enc PRIVATE PNG::PNG) target_sources(heif-convert PRIVATE encoder_png.cc encoder_png.h) target_sources(heif-enc PRIVATE decoder_png.cc decoder_png.h) add_executable(heif-thumbnailer ${getopt_sources} encoder.cc encoder.h heif_thumbnailer.cc encoder_png.cc encoder_png.h ../libheif/exif.h ../libheif/exif.cc common.cc common.h) target_link_libraries(heif-thumbnailer heif PNG::PNG) install(TARGETS heif-thumbnailer RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES heif-thumbnailer.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) endif () libheif-1.17.6/examples/heif-thumbnailer.1000664 001750 001750 00000001340 14540541202 021426 0ustar00farindkfarindk000000 000000 .TH HEIF-THUMBNAILER 1 .SH NAME heif-thumbnailer \- create thumbnails from HEIC/HEIF files .SH SYNOPSIS .B heif-thumbnailer [\fB\-s\fR \fISIZE\fR] .IR filename .IR output .SH DESCRIPTION .B heif-thumbnailer Create thumbnail images from HEIC/HEIF files that can be used for example by Nautilus. .SH OPTIONS .TP .BR \-s\fR\ \fISIZE\fR Defines the maximum width and height of the thumbnail to generate. Default is 512 pixel. .SH EXIT STATUS .PP \fB0\fR .RS 4 Success .RE .PP \fB1\fR .RS 4 Failure (syntax or usage error; error while loading, converting or writing image). .RE .SH BUGS Please reports bugs or issues at https://github.com/strukturag/libheif .SH AUTHORS Dirk Farin, struktur AG .SH COPYRIGHT Copyright \[co] 2018 struktur AG libheif-1.17.6/examples/encoder_jpeg.cc000664 001750 001750 00000024202 14540541202 021056 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". MIT License Copyright (c) 2017 struktur AG, Joachim Bauch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "encoder_jpeg.h" #include "libheif/exif.h" #define JPEG_XMP_MARKER (JPEG_APP0+1) /* JPEG marker code for XMP */ #define JPEG_XMP_MARKER_ID "http://ns.adobe.com/xap/1.0/" JpegEncoder::JpegEncoder(int quality) : quality_(quality) { if (quality_ < 0 || quality_ > 100) { quality_ = kDefaultQuality; } } void JpegEncoder::UpdateDecodingOptions(const struct heif_image_handle* handle, struct heif_decoding_options* options) const { if (HasExifMetaData(handle)) { options->ignore_transformations = 0; } options->convert_hdr_to_8bit = 1; } // static void JpegEncoder::OnJpegError(j_common_ptr cinfo) { ErrorHandler* handler = reinterpret_cast(cinfo->err); longjmp(handler->setjmp_buffer, 1); } #define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ #if !defined(HAVE_JPEG_WRITE_ICC_PROFILE) #define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ #define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ #define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) /* * This routine writes the given ICC profile data into a JPEG file. It *must* * be called AFTER calling jpeg_start_compress() and BEFORE the first call to * jpeg_write_scanlines(). (This ordering ensures that the APP2 marker(s) will * appear after the SOI and JFIF or Adobe markers, but before all else.) */ /* This function is copied almost as is from libjpeg-turbo */ static void jpeg_write_icc_profile(j_compress_ptr cinfo, const JOCTET* icc_data_ptr, unsigned int icc_data_len) { unsigned int num_markers; /* total number of markers we'll write */ int cur_marker = 1; /* per spec, counting starts at 1 */ unsigned int length; /* number of bytes to write in this marker */ /* Calculate the number of markers we'll need, rounding up of course */ num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER; if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len) num_markers++; while (icc_data_len > 0) { /* length of profile to put in this marker */ length = icc_data_len; if (length > MAX_DATA_BYTES_IN_MARKER) length = MAX_DATA_BYTES_IN_MARKER; icc_data_len -= length; /* Write the JPEG marker header (APP2 code and marker length) */ jpeg_write_m_header(cinfo, ICC_MARKER, (unsigned int) (length + ICC_OVERHEAD_LEN)); /* Write the marker identifying string "ICC_PROFILE" (null-terminated). We * code it in this less-than-transparent way so that the code works even if * the local character set is not ASCII. */ jpeg_write_m_byte(cinfo, 0x49); jpeg_write_m_byte(cinfo, 0x43); jpeg_write_m_byte(cinfo, 0x43); jpeg_write_m_byte(cinfo, 0x5F); jpeg_write_m_byte(cinfo, 0x50); jpeg_write_m_byte(cinfo, 0x52); jpeg_write_m_byte(cinfo, 0x4F); jpeg_write_m_byte(cinfo, 0x46); jpeg_write_m_byte(cinfo, 0x49); jpeg_write_m_byte(cinfo, 0x4C); jpeg_write_m_byte(cinfo, 0x45); jpeg_write_m_byte(cinfo, 0x0); /* Add the sequencing info */ jpeg_write_m_byte(cinfo, cur_marker); jpeg_write_m_byte(cinfo, (int) num_markers); /* Add the profile data */ while (length--) { jpeg_write_m_byte(cinfo, *icc_data_ptr); icc_data_ptr++; } cur_marker++; } } #endif // !defined(HAVE_JPEG_WRITE_ICC_PROFILE) bool JpegEncoder::Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) { FILE* fp = fopen(filename.c_str(), "wb"); if (!fp) { fprintf(stderr, "Can't open %s: %s\n", filename.c_str(), strerror(errno)); return false; } struct jpeg_compress_struct cinfo; struct ErrorHandler jerr; cinfo.err = jpeg_std_error(reinterpret_cast(&jerr)); jerr.pub.error_exit = &JpegEncoder::OnJpegError; if (setjmp(jerr.setjmp_buffer)) { cinfo.err->output_message(reinterpret_cast(&cinfo)); jpeg_destroy_compress(&cinfo); fclose(fp); return false; } jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, fp); cinfo.image_width = heif_image_get_width(image, heif_channel_Y); cinfo.image_height = heif_image_get_height(image, heif_channel_Y); cinfo.input_components = 3; cinfo.in_color_space = JCS_YCbCr; jpeg_set_defaults(&cinfo); static const boolean kForceBaseline = TRUE; jpeg_set_quality(&cinfo, quality_, kForceBaseline); static const boolean kWriteAllTables = TRUE; jpeg_start_compress(&cinfo, kWriteAllTables); // --- Write EXIF size_t exifsize = 0; uint8_t* exifdata = GetExifMetaData(handle, &exifsize); if (exifdata) { if (exifsize > 4) { static const uint8_t kExifMarker = JPEG_APP0 + 1; uint32_t skip = (exifdata[0]<<24) | (exifdata[1]<<16) | (exifdata[2]<<8) | exifdata[3]; if (skip > (exifsize - 4)) { fprintf(stderr, "Invalid EXIF data (offset too large)\n"); return false; } skip += 4; uint8_t* ptr = exifdata + skip; size_t size = exifsize - skip; if (size > std::numeric_limits::max()) { fprintf(stderr, "EXIF larger than 4GB is not supported"); return false; } auto size32 = static_cast(size); // libheif by default normalizes the image orientation, so that we have to set the EXIF Orientation to "Horizontal (normal)" modify_exif_orientation_tag_if_it_exists(ptr, size32, 1); // We have to limit the size for the memcpy, otherwise GCC warns that we exceed the maximum size. if (size>0x1000000) { size = 0x1000000; } std::vector jpegExifMarkerData(6+size); memcpy(jpegExifMarkerData.data()+6, ptr, size); jpegExifMarkerData[0]='E'; jpegExifMarkerData[1]='x'; jpegExifMarkerData[2]='i'; jpegExifMarkerData[3]='f'; jpegExifMarkerData[4]=0; jpegExifMarkerData[5]=0; ptr = jpegExifMarkerData.data(); size = jpegExifMarkerData.size(); while (size > MAX_BYTES_IN_MARKER) { jpeg_write_marker(&cinfo, kExifMarker, ptr, static_cast(MAX_BYTES_IN_MARKER)); ptr += MAX_BYTES_IN_MARKER; size -= MAX_BYTES_IN_MARKER; } jpeg_write_marker(&cinfo, kExifMarker, ptr, static_cast(size)); } free(exifdata); } // --- Write XMP // spec: https://raw.githubusercontent.com/adobe/xmp-docs/master/XMPSpecifications/XMPSpecificationPart3.pdf auto xmp = get_xmp_metadata(handle); if (xmp.size() > 65502) { fprintf(stderr, "XMP data too large, ExtendedXMP is not supported yet.\n"); } else if (!xmp.empty()) { std::vector xmpWithId; xmpWithId.resize(xmp.size() + strlen(JPEG_XMP_MARKER_ID)+1); strcpy((char*)xmpWithId.data(), JPEG_XMP_MARKER_ID); memcpy(xmpWithId.data() + strlen(JPEG_XMP_MARKER_ID) + 1, xmp.data(), xmp.size()); jpeg_write_marker(&cinfo, JPEG_XMP_MARKER, xmpWithId.data(), static_cast(xmpWithId.size())); } // --- Write ICC size_t profile_size = heif_image_handle_get_raw_color_profile_size(handle); if (profile_size > 0) { uint8_t* profile_data = static_cast(malloc(profile_size)); heif_image_handle_get_raw_color_profile(handle, profile_data); jpeg_write_icc_profile(&cinfo, profile_data, (unsigned int) profile_size); free(profile_data); } if (heif_image_get_bits_per_pixel(image, heif_channel_Y) != 8) { fprintf(stderr, "JPEG writer cannot handle image with >8 bpp.\n"); return false; } int stride_y; const uint8_t* row_y = heif_image_get_plane_readonly(image, heif_channel_Y, &stride_y); int stride_u; const uint8_t* row_u = heif_image_get_plane_readonly(image, heif_channel_Cb, &stride_u); int stride_v; const uint8_t* row_v = heif_image_get_plane_readonly(image, heif_channel_Cr, &stride_v); JSAMPARRAY buffer = cinfo.mem->alloc_sarray( reinterpret_cast(&cinfo), JPOOL_IMAGE, cinfo.image_width * cinfo.input_components, 1); JSAMPROW row[1] = {buffer[0]}; while (cinfo.next_scanline < cinfo.image_height) { size_t offset_y = cinfo.next_scanline * stride_y; const uint8_t* start_y = &row_y[offset_y]; size_t offset_u = (cinfo.next_scanline / 2) * stride_u; const uint8_t* start_u = &row_u[offset_u]; size_t offset_v = (cinfo.next_scanline / 2) * stride_v; const uint8_t* start_v = &row_v[offset_v]; JOCTET* bufp = buffer[0]; for (JDIMENSION x = 0; x < cinfo.image_width; ++x) { *bufp++ = start_y[x]; *bufp++ = start_u[x / 2]; *bufp++ = start_v[x / 2]; } jpeg_write_scanlines(&cinfo, row, 1); } jpeg_finish_compress(&cinfo); fclose(fp); jpeg_destroy_compress(&cinfo); return true; } libheif-1.17.6/examples/decoder_y4m.h000664 001750 001750 00000002457 14540541202 020502 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef LIBHEIF_DECODER_Y4M_H #define LIBHEIF_DECODER_Y4M_H #include "decoder.h" InputImage loadY4M(const char* filename); #endif //LIBHEIF_DECODER_Y4M_H libheif-1.17.6/examples/common.h000664 001750 001750 00000002365 14540541202 017572 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef LIBHEIF_COMMON_H #define LIBHEIF_COMMON_H void show_version(); #endif //LIBHEIF_COMMON_H libheif-1.17.6/examples/decoder_png.cc000664 001750 001750 00000033247 14540541202 020714 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "decoder_png.h" #include "libheif/exif.h" extern "C" { #include } static void user_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { FILE* fh = (FILE*) png_get_io_ptr(png_ptr); size_t n = fread((char*) data, length, 1, fh); (void) n; } // user_read_data InputImage loadPNG(const char* filename, int output_bit_depth) { FILE* fh = fopen(filename, "rb"); if (!fh) { std::cerr << "Can't open " << filename << "\n"; exit(1); } InputImage input_image; // ### Code copied from LibVideoGfx and slightly modified to use HeifPixelImage struct heif_image* image = nullptr; png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; int compression_type; png_charp name; #if (PNG_LIBPNG_VER < 10500) png_charp png_profile_data; #else png_bytep png_profile_data; #endif uint8_t* profile_data = nullptr; png_uint_32 profile_length = 5; /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); assert(png_ptr != NULL); /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); assert(false); // , "could not create info_ptr"); } // if /* Set error handling if you are using the setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in the png_create_read_struct() earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); /* If we get here, we had a problem reading the file */ assert(false); // , "fatal error in png library"); } // if /* If you are using replacement read functions, instead of calling * png_init_io() here you would call: */ png_set_read_fn(png_ptr, (void*) fh, user_read_fn); /* where user_io_ptr is a structure you want available to the callbacks */ /* The call to png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). REQUIRED */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) { if (PNG_INFO_iCCP == png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &png_profile_data, &profile_length) && profile_length > 0) { profile_data = (uint8_t*) malloc(profile_length); if (profile_data) { memcpy(profile_data, png_profile_data, profile_length); } } } /**** Set up the data transformations you want. Note that these are all **** optional. Only call them if you want/need them. Many of the **** transformations only work on specific types of images, and many **** are mutually exclusive. ****/ // \TODO // /* Strip alpha bytes from the input data without combining with the // * background (not recommended). // */ // png_set_strip_alpha(png_ptr); /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ png_set_packing(png_ptr); /* Expand paletted colors into true RGB triplets */ if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); bit_depth = 8; } /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { png_set_expand_gray_1_2_4_to_8(png_ptr); bit_depth = 8; } /* Set the background color to draw transparent and alpha images over. * It is possible to set the red, green, and blue components directly * for paletted images instead of supplying a palette index. Note that * even if the PNG file supplies a background, you are not required to * use it - you should use the (solid) application background if it has one. */ #if 0 // \TODO 0 is index in color lookup table - correct? used already? png_color_16 my_background = {0, 255, 255, 255, 255}; png_color_16 *image_background; if (png_get_bKGD(png_ptr, info_ptr, &image_background)) png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); #endif /* Optional call to gamma correct and add the background to the palette * and update info structure. REQUIRED if you are expecting libpng to * update the palette for you (ie you selected such a transform above). */ png_read_update_info(png_ptr, info_ptr); /* Allocate the memory to hold the image using the fields of info_ptr. */ /* The easiest way to read the image: */ uint8_t** row_pointers = new png_bytep[height]; assert(row_pointers != NULL); for (uint32_t y = 0; y < height; y++) { row_pointers[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, info_ptr)); assert(row_pointers[y] != NULL); } // for /* Now it's time to read the image. One of these methods is REQUIRED */ png_read_image(png_ptr, row_pointers); /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); // --- read EXIF data #ifdef PNG_eXIf_SUPPORTED png_bytep exifPtr = nullptr; png_uint_32 exifSize = 0; if (png_get_eXIf_1(png_ptr, info_ptr, &exifSize, &exifPtr) == PNG_INFO_eXIf) { input_image.exif.resize(exifSize); memcpy(input_image.exif.data(), exifPtr, exifSize); // remove the EXIF orientation since it is informal only in PNG and we do not want to confuse with an orientation not matching irot/imir modify_exif_orientation_tag_if_it_exists(input_image.exif.data(), (int) input_image.exif.size(), 1); } #endif // --- read XMP data #ifdef PNG_iTXt_SUPPORTED png_textp textPtr = nullptr; const png_uint_32 nTextChunks = png_get_text(png_ptr, info_ptr, &textPtr, nullptr); for (png_uint_32 i = 0; i < nTextChunks; i++, textPtr++) { png_size_t textLength = textPtr->text_length; if ((textPtr->compression == PNG_ITXT_COMPRESSION_NONE) || (textPtr->compression == PNG_ITXT_COMPRESSION_zTXt)) { textLength = textPtr->itxt_length; } if (!strcmp(textPtr->key, "XML:com.adobe.xmp")) { if (textLength == 0) { // TODO: error } else { input_image.xmp.resize(textLength); memcpy(input_image.xmp.data(), textPtr->text, textLength); } } } #endif int band = png_get_channels(png_ptr, info_ptr); /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); struct heif_error err; bool has_alpha = (band == 2 || band == 4); if (band == 1 && bit_depth == 8) { err = heif_image_create((int) width, (int) height, heif_colorspace_monochrome, heif_chroma_monochrome, &image); (void) err; heif_image_add_plane(image, heif_channel_Y, (int) width, (int) height, 8); int y_stride; int a_stride; uint8_t* py = heif_image_get_plane(image, heif_channel_Y, &y_stride); uint8_t* pa = nullptr; if (has_alpha) { heif_image_add_plane(image, heif_channel_Alpha, (int) width, (int) height, 8); pa = heif_image_get_plane(image, heif_channel_Alpha, &a_stride); } for (uint32_t y = 0; y < height; y++) { uint8_t* p = row_pointers[y]; if (has_alpha) { for (uint32_t x = 0; x < width; x++) { py[y * y_stride + x] = *p++; pa[y * a_stride + x] = *p++; } } else { memcpy(&py[y * y_stride], p, width); } } } else if (band == 1) { assert(bit_depth > 8); err = heif_image_create((int) width, (int) height, heif_colorspace_monochrome, heif_chroma_monochrome, &image); (void) err; int bdShift = 16 - output_bit_depth; heif_image_add_plane(image, heif_channel_Y, (int) width, (int) height, output_bit_depth); int y_stride; int a_stride = 0; uint16_t* py = (uint16_t*) heif_image_get_plane(image, heif_channel_Y, &y_stride); uint16_t* pa = nullptr; if (has_alpha) { heif_image_add_plane(image, heif_channel_Alpha, (int) width, (int) height, output_bit_depth); pa = (uint16_t*) heif_image_get_plane(image, heif_channel_Alpha, &a_stride); } y_stride /= 2; a_stride /= 2; for (uint32_t y = 0; y < height; y++) { uint8_t* p = row_pointers[y]; if (has_alpha) { for (uint32_t x = 0; x < width; x++) { uint16_t vp = (uint16_t) (((p[0] << 8) | p[1]) >> bdShift); uint16_t va = (uint16_t) (((p[2] << 8) | p[3]) >> bdShift); py[x + y * y_stride] = vp; pa[x + y * y_stride] = va; p += 4; } } else { for (uint32_t x = 0; x < width; x++) { uint16_t vp = (uint16_t) (((p[0] << 8) | p[1]) >> bdShift); py[x + y * y_stride] = vp; p += 2; } } } } else if (bit_depth == 8) { err = heif_image_create((int) width, (int) height, heif_colorspace_RGB, has_alpha ? heif_chroma_interleaved_RGBA : heif_chroma_interleaved_RGB, &image); (void) err; heif_image_add_plane(image, heif_channel_interleaved, (int) width, (int) height, has_alpha ? 32 : 24); int stride; uint8_t* p = heif_image_get_plane(image, heif_channel_interleaved, &stride); for (uint32_t y = 0; y < height; y++) { if (has_alpha) { memcpy(p + y * stride, row_pointers[y], width * 4); } else { memcpy(p + y * stride, row_pointers[y], width * 3); } } } else { if (output_bit_depth == 8) { err = heif_image_create((int) width, (int) height, heif_colorspace_RGB, has_alpha ? heif_chroma_interleaved_RGBA : heif_chroma_interleaved_RGB, &image); } else { err = heif_image_create((int) width, (int) height, heif_colorspace_RGB, has_alpha ? heif_chroma_interleaved_RRGGBBAA_LE : heif_chroma_interleaved_RRGGBB_LE, &image); } (void) err; int bdShift = 16 - output_bit_depth; heif_image_add_plane(image, heif_channel_interleaved, (int) width, (int) height, output_bit_depth); int stride; uint8_t* p_out = (uint8_t*) heif_image_get_plane(image, heif_channel_interleaved, &stride); if (output_bit_depth==8) { // convert HDR to SDR for (uint32_t y = 0; y < height; y++) { uint8_t* p = row_pointers[y]; uint32_t nVal = (has_alpha ? 4 : 3) * width; for (uint32_t x = 0; x < nVal; x++) { p_out[x + y * stride] = p[0]; p+=2; } } } else { for (uint32_t y = 0; y < height; y++) { uint8_t* p = row_pointers[y]; uint32_t nVal = (has_alpha ? 4 : 3) * width; for (uint32_t x = 0; x < nVal; x++) { uint16_t v = (uint16_t) (((p[0] << 8) | p[1]) >> bdShift); p_out[2 * x + y * stride + 1] = (uint8_t) (v >> 8); p_out[2 * x + y * stride + 0] = (uint8_t) (v & 0xFF); p += 2; } } } } if (profile_data && profile_length > 0) { heif_image_set_raw_color_profile(image, "prof", profile_data, (size_t) profile_length); } free(profile_data); for (uint32_t y = 0; y < height; y++) { free(row_pointers[y]); } // for delete[] row_pointers; input_image.image = std::shared_ptr(image, [](heif_image* img) { heif_image_release(img); }); return input_image; } libheif-1.17.6/examples/benchmark.h000664 001750 001750 00000001745 14540541202 020235 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2022 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #ifndef LIBHEIF_BENCHMARK_H #define LIBHEIF_BENCHMARK_H #include #include struct heif_image; double compute_psnr(heif_image* original_image, const std::string& encoded_file); #endif //LIBHEIF_BENCHMARK_H libheif-1.17.6/examples/heif-enc.1000664 001750 001750 00000004535 14540541202 017672 0ustar00farindkfarindk000000 000000 .TH HEIF-ENC 1 .SH NAME heif-enc \- convert image to HEIC/HEIF .SH SYNOPSIS .B heif-enc [\fB\-h\fR|\fB--help\fR] [\fB\-q\fR \fIQUALITY\fR|\fB--quality\fR \fIQUALITY\fR] [\fB\-L\fR|\fB--lossless\fR] [\fB\-t\fR \fISIZE\fR|\fB--thumb\fR \fISIZE\fR] [\fB--no-alpha\fR] [\fB--no-thumb-alpha\fR] [\fB\-o\fR \fIFILENAME\fR|\fB--output\fR \fIFILENAME\fR] [\fB\-v\fR|\fB--verbose\fR] [\fB\-P\fR|\fB--params\fR] [\fB\-b\fR \fIDEPTH\fR] [\fB\-p\fR \fINAME\fR\fB=\fR\fIVALUE\fR] .IR filename[.jpg|.png|.y4m] .SH DESCRIPTION .B heif-enc Convert image to HEIC/HEIF. .SH OPTIONS .TP .BR \-q\fR\ \fIQUALITY\fR ", " \-\-quality\fR\ \fIQUALITY\fR Defines quality level between 0 and 100 for the generated output file. .TP .BR \-L ", "\-\-lossless\fR Generate lossless output (\fB-q\fR has no effect) .TP .BR \-t\fR\ \fISIZE\fR ", " \-\-thumb\fR\ \fISIZE\fR Generate thumbnail with maximum size \fISIZE\fR pixels (default: off). .TP .BR \-\-no-alpha\fR Do not save alpha channel. .TP .BR \-\-no-thumb-alpha\fR Do not save alpha channel in thumbnail image. .TP .BR \-o\fR\ \fIFILENAME\fR ", " \-\-output\fR\ \fIFILENAME\fR Output filename (optional). .TP .BR \-\-verbose\fR Enable logging output (more will increase logging level). .TP .BR \-P ", "\-\-params\fR Show all encoder parameters. .TP .BR \-b\fR\ \fIDEPTH\fR Bit-depth of generated HEIF file when using 16-bit PNG input (default: 10 bit). .TP .BR \-p\fR\ \fINAME\fR\fB=\fR\fIVALUE\fR Set additional encoder parameters. See \fBNOTES\fR below. .SH EXIT STATUS .PP \fB0\fR .RS 4 Success .RE .PP \fB1\fR .RS 4 Failure (syntax or usage error; error while loading, converting or writing image). .RE .SH NOTES The available input formats depend on the libraries that were available at compile time. Supported are JPEG, PNG and Y4M, the file type is determined based on the extension of the input file. When specifying multiple source images, they will all be saved into the same HEIF file. When using the x265 encoder, you may pass it any of its parameters by prefixing the parameter name with \fBx265:\fR. Hence, to set the \fBctu\fR parameter, you will have to set \fBx265:ctu\fR in libheif (e.g.: \fB-p x265:ctu=64\fR). Note that there is no checking for valid parameters when using the prefix. .SH BUGS Please reports bugs or issues at https://github.com/strukturag/libheif .SH AUTHORS Dirk Farin, struktur AG .SH COPYRIGHT Copyright \[co] 2017 struktur AG libheif-1.17.6/examples/heif_enc.cc000664 001750 001750 00000101524 14540541202 020175 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2017 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_LIBJPEG #include "decoder_jpeg.h" #endif #if HAVE_LIBPNG #include "decoder_png.h" #endif #include "decoder_y4m.h" #include #include "benchmark.h" #include "libheif/exif.h" #include "common.h" int master_alpha = 1; int thumb_alpha = 1; int list_encoders = 0; int two_colr_boxes = 0; int premultiplied_alpha = 0; int run_benchmark = 0; int metadata_compression = 0; const char* encoderId = nullptr; std::string chroma_downsampling; uint16_t nclx_colour_primaries = 1; uint16_t nclx_transfer_characteristic = 13; uint16_t nclx_matrix_coefficients = 6; int nclx_full_range = true; std::string property_pitm_description; // for benchmarking #if !defined(_MSC_VER) #define HAVE_GETTIMEOFDAY 1 // TODO: should be set by CMake #endif #if HAVE_GETTIMEOFDAY #include struct timeval time_encoding_start; struct timeval time_encoding_end; #endif const int OPTION_NCLX_MATRIX_COEFFICIENTS = 1000; const int OPTION_NCLX_COLOUR_PRIMARIES = 1001; const int OPTION_NCLX_TRANSFER_CHARACTERISTIC = 1002; const int OPTION_NCLX_FULL_RANGE_FLAG = 1003; const int OPTION_PLUGIN_DIRECTORY = 1004; const int OPTION_PITM_DESCRIPTION = 1005; const int OPTION_USE_JPEG_COMPRESSION = 1006; const int OPTION_USE_JPEG2000_COMPRESSION = 1007; const int OPTION_VERBOSE = 1008; static struct option long_options[] = { {(char* const) "help", no_argument, 0, 'h'}, {(char* const) "version", no_argument, 0, 'v'}, {(char* const) "quality", required_argument, 0, 'q'}, {(char* const) "output", required_argument, 0, 'o'}, {(char* const) "lossless", no_argument, 0, 'L'}, {(char* const) "thumb", required_argument, 0, 't'}, {(char* const) "verbose", no_argument, 0, OPTION_VERBOSE}, {(char* const) "params", no_argument, 0, 'P'}, {(char* const) "no-alpha", no_argument, &master_alpha, 0}, {(char* const) "no-thumb-alpha", no_argument, &thumb_alpha, 0}, {(char* const) "list-encoders", no_argument, &list_encoders, 1}, {(char* const) "encoder", required_argument, 0, 'e'}, {(char* const) "bit-depth", required_argument, 0, 'b'}, {(char* const) "even-size", no_argument, 0, 'E'}, {(char* const) "avif", no_argument, 0, 'A'}, {(char* const) "jpeg", no_argument, 0, OPTION_USE_JPEG_COMPRESSION}, {(char* const) "jpeg2000", no_argument, 0, OPTION_USE_JPEG2000_COMPRESSION}, #if WITH_UNCOMPRESSED_CODEC {(char* const) "uncompressed", no_argument, 0, 'U'}, #endif {(char* const) "matrix_coefficients", required_argument, 0, OPTION_NCLX_MATRIX_COEFFICIENTS}, {(char* const) "colour_primaries", required_argument, 0, OPTION_NCLX_COLOUR_PRIMARIES}, {(char* const) "transfer_characteristic", required_argument, 0, OPTION_NCLX_TRANSFER_CHARACTERISTIC}, {(char* const) "full_range_flag", required_argument, 0, OPTION_NCLX_FULL_RANGE_FLAG}, {(char* const) "enable-two-colr-boxes", no_argument, &two_colr_boxes, 1}, {(char* const) "premultiplied-alpha", no_argument, &premultiplied_alpha, 1}, {(char* const) "plugin-directory", required_argument, 0, OPTION_PLUGIN_DIRECTORY}, {(char* const) "benchmark", no_argument, &run_benchmark, 1}, {(char* const) "enable-metadata-compression", no_argument, &metadata_compression, 1}, {(char* const) "pitm-description", required_argument, 0, OPTION_PITM_DESCRIPTION}, {(char* const) "chroma-downsampling", required_argument, 0, 'C'}, {0, 0, 0, 0}, }; void show_help(const char* argv0) { std::cerr << " heif-enc libheif version: " << heif_get_version() << "\n" << "----------------------------------------\n" << "Usage: heif-enc [options] image.jpeg ...\n" << "\n" << "When specifying multiple source images, they will all be saved into the same HEIF/AVIF file.\n" << "\n" << "When using the x265 encoder, you may pass it any of its parameters by\n" << "prefixing the parameter name with 'x265:'. Hence, to set the 'ctu' parameter,\n" << "you will have to set 'x265:ctu' in libheif (e.g.: -p x265:ctu=64).\n" << "Note that there is no checking for valid parameters when using the prefix.\n" << "\n" << "Options:\n" << " -h, --help show help\n" << " -v, --version show version\n" << " -q, --quality set output quality (0-100) for lossy compression\n" << " -L, --lossless generate lossless output (-q has no effect)\n" << " -t, --thumb # generate thumbnail with maximum size # (default: off)\n" << " --no-alpha do not save alpha channel\n" << " --no-thumb-alpha do not save alpha channel in thumbnail image\n" << " -o, --output output filename (optional)\n" << " --verbose enable logging output (more will increase logging level)\n" << " -P, --params show all encoder parameters\n" << " -b, --bit-depth # bit-depth of generated HEIF/AVIF file when using 16-bit PNG input (default: 10 bit)\n" << " -p set encoder parameter (NAME=VALUE)\n" << " -A, --avif encode as AVIF (not needed if output filename with .avif suffix is provided)\n" << " --jpeg encode as JPEG\n" << " --jpeg2000 encode as JPEG 2000 (experimental)\n" #if WITH_UNCOMPRESSED_CODEC << " -U, --uncompressed encode as uncompressed image (according to ISO 23001-17) (EXPERIMENTAL)\n" #endif << " --list-encoders list all available encoders for all compression formats\n" << " -e, --encoder ID select encoder to use (the IDs can be listed with --list-encoders)\n" << " --plugin-directory DIR load all codec plugins in the directory\n" << " -E, --even-size [deprecated] crop images to even width and height (odd sizes are not decoded correctly by some software)\n" << " --matrix_coefficients nclx profile: color conversion matrix coefficients, default=6 (see h.273)\n" << " --colour_primaries nclx profile: color primaries (see h.273)\n" << " --transfer_characteristic nclx profile: transfer characteristics (see h.273)\n" << " --full_range_flag nclx profile: full range flag, default: 1\n" << " --enable-two-colr-boxes will write both an ICC and an nclx color profile if both are present\n" << " --premultiplied-alpha input image has premultiplied alpha\n" << " --enable-metadata-compression enable XMP metadata compression (experimental)\n" << " -C,--chroma-downsampling ALGO force chroma downsampling algorithm (nn = nearest-neighbor / average / sharp-yuv)\n" << " (sharp-yuv makes edges look sharper when using YUV420 with bilinear chroma upsampling)\n" << " --benchmark measure encoding time, PSNR, and output file size\n" << " --pitm-description TEXT (EXPERIMENTAL) set user description for primary image\n" << "\n" << "Note: to get lossless encoding, you need this set of options:\n" << " -L switch encoder to lossless mode\n" << " -p chroma=444 switch off chroma subsampling\n" << " --matrix_coefficients=0 encode in RGB color-space\n"; } #if !HAVE_LIBJPEG InputImage loadJPEG(const char* filename) { std::cerr << "Cannot load JPEG because libjpeg support was not compiled.\n"; exit(1); return {}; } #endif #if !HAVE_LIBPNG InputImage loadPNG(const char* filename, int output_bit_depth) { std::cerr << "Cannot load PNG because libpng support was not compiled.\n"; exit(1); return {}; } #endif void list_encoder_parameters(heif_encoder* encoder) { std::cerr << "Parameters for encoder `" << heif_encoder_get_name(encoder) << "`:\n"; const struct heif_encoder_parameter* const* params = heif_encoder_list_parameters(encoder); for (int i = 0; params[i]; i++) { const char* name = heif_encoder_parameter_get_name(params[i]); switch (heif_encoder_parameter_get_type(params[i])) { case heif_encoder_parameter_type_integer: { heif_error error; std::cerr << " " << name; if (heif_encoder_has_default(encoder, name)) { int value; error = heif_encoder_get_parameter_integer(encoder, name, &value); (void) error; std::cerr << ", default=" << value; } int have_minimum, have_maximum, minimum, maximum, num_valid_values; const int* valid_values = nullptr; error = heif_encoder_parameter_integer_valid_values(encoder, name, &have_minimum, &have_maximum, &minimum, &maximum, &num_valid_values, &valid_values); if (have_minimum || have_maximum) { // TODO: only one is set std::cerr << ", [" << minimum << ";" << maximum << "]"; } if (num_valid_values > 0) { std::cerr << ", {"; for (int p = 0; p < num_valid_values; p++) { if (p > 0) { std::cerr << ", "; } std::cerr << valid_values[p]; } std::cerr << "}"; } std::cerr << "\n"; } break; case heif_encoder_parameter_type_boolean: { heif_error error; std::cerr << " " << name; if (heif_encoder_has_default(encoder, name)) { int value; error = heif_encoder_get_parameter_boolean(encoder, name, &value); (void) error; std::cerr << ", default=" << (value ? "true" : "false"); } std::cerr << "\n"; } break; case heif_encoder_parameter_type_string: { heif_error error; std::cerr << " " << name; if (heif_encoder_has_default(encoder, name)) { const int value_size = 50; char value[value_size]; error = heif_encoder_get_parameter_string(encoder, name, value, value_size); (void) error; std::cerr << ", default=" << value; } const char* const* valid_options; error = heif_encoder_parameter_string_valid_values(encoder, name, &valid_options); if (valid_options) { std::cerr << ", { "; for (int k = 0; valid_options[k]; k++) { if (k > 0) { std::cerr << ","; } std::cerr << valid_options[k]; } std::cerr << " }"; } std::cerr << "\n"; } break; } } } void set_params(struct heif_encoder* encoder, const std::vector& params) { for (const std::string& p : params) { auto pos = p.find_first_of('='); if (pos == std::string::npos || pos == 0 || pos == p.size() - 1) { std::cerr << "Encoder parameter must be in the format 'name=value'\n"; exit(5); } std::string name = p.substr(0, pos); std::string value = p.substr(pos + 1); struct heif_error error = heif_encoder_set_parameter(encoder, name.c_str(), value.c_str()); if (error.code) { std::cerr << "Error: " << error.message << "\n"; exit(5); } } } static void show_list_of_encoders(const heif_encoder_descriptor* const* encoder_descriptors, int count) { for (int i = 0; i < count; i++) { std::cout << "- " << heif_encoder_descriptor_get_id_name(encoder_descriptors[i]) << " = " << heif_encoder_descriptor_get_name(encoder_descriptors[i]); if (i == 0) { std::cout << " [default]"; } std::cout << "\n"; } } static const char* get_compression_format_name(heif_compression_format format) { switch (format) { case heif_compression_AV1: return "AV1"; break; case heif_compression_HEVC: return "HEVC"; break; case heif_compression_JPEG: return "JPEG"; break; case heif_compression_JPEG2000: return "JPEG 2000"; break; case heif_compression_uncompressed: return "Uncompressed"; break; default: assert(false); return "unknown"; } } static void show_list_of_all_encoders() { for (auto compression_format : {heif_compression_HEVC, heif_compression_AV1, heif_compression_JPEG, heif_compression_JPEG2000 #if WITH_UNCOMPRESSED_CODEC , heif_compression_uncompressed #endif }) { switch (compression_format) { case heif_compression_AV1: std::cout << "AVIF"; break; case heif_compression_HEVC: std::cout << "HEIC"; break; case heif_compression_JPEG: std::cout << "JPEG"; break; case heif_compression_JPEG2000: std::cout << "JPEG 2000"; break; case heif_compression_uncompressed: std::cout << "Uncompressed"; break; default: assert(false); } std::cout << " encoders:\n"; #define MAX_ENCODERS 10 const heif_encoder_descriptor* encoder_descriptors[MAX_ENCODERS]; int count = heif_get_encoder_descriptors(compression_format, nullptr, encoder_descriptors, MAX_ENCODERS); #undef MAX_ENCODERS show_list_of_encoders(encoder_descriptors, count); } } bool ends_with(const std::string& str, const std::string& end) { if (str.length() < end.length()) { return false; } else { return str.compare(str.length() - end.length(), end.length(), end) == 0; } } heif_compression_format guess_compression_format_from_filename(const std::string& filename) { std::string filename_lowercase = filename; std::transform(filename_lowercase.begin(), filename_lowercase.end(), filename_lowercase.begin(), ::tolower); if (ends_with(filename_lowercase, ".avif")) { return heif_compression_AV1; } else if (ends_with(filename_lowercase, ".heic")) { return heif_compression_HEVC; } else if (ends_with(filename_lowercase, ".hej2")) { return heif_compression_JPEG2000; } else { return heif_compression_undefined; } } std::string suffix_for_compression_format(heif_compression_format format) { switch (format) { case heif_compression_AV1: return "avif"; case heif_compression_HEVC: return "heic"; case heif_compression_JPEG2000: return "hej2"; default: return "data"; } } class LibHeifInitializer { public: LibHeifInitializer() { heif_init(nullptr); } ~LibHeifInitializer() { heif_deinit(); } }; int main(int argc, char** argv) { // This takes care of initializing libheif and also deinitializing it at the end to free all resources. LibHeifInitializer initializer; int quality = 50; bool lossless = false; std::string output_filename; int logging_level = 0; bool option_show_parameters = false; int thumbnail_bbox_size = 0; int output_bit_depth = 10; bool force_enc_av1f = false; bool force_enc_uncompressed = false; bool force_enc_jpeg = false; bool force_enc_jpeg2000 = false; bool crop_to_even_size = false; std::vector raw_params; while (true) { int option_index = 0; int c = getopt_long(argc, argv, "hq:Lo:vPp:t:b:AEe:C:" #if WITH_UNCOMPRESSED_CODEC "U" #endif , long_options, &option_index); if (c == -1) break; switch (c) { case 'h': show_help(argv[0]); return 0; case 'v': show_version(); return 0; case 'q': quality = atoi(optarg); break; case 'L': lossless = true; break; case 'o': output_filename = optarg; break; case OPTION_VERBOSE: logging_level++; break; case 'P': option_show_parameters = true; break; case 'p': raw_params.push_back(optarg); break; case 't': thumbnail_bbox_size = atoi(optarg); break; case 'b': output_bit_depth = atoi(optarg); break; case 'A': force_enc_av1f = true; break; #if WITH_UNCOMPRESSED_CODEC case 'U': force_enc_uncompressed = true; break; #endif case 'E': crop_to_even_size = true; break; case 'e': encoderId = optarg; break; case OPTION_NCLX_MATRIX_COEFFICIENTS: nclx_matrix_coefficients = (uint16_t) strtoul(optarg, nullptr, 0); break; case OPTION_NCLX_COLOUR_PRIMARIES: nclx_colour_primaries = (uint16_t) strtoul(optarg, nullptr, 0); break; case OPTION_NCLX_TRANSFER_CHARACTERISTIC: nclx_transfer_characteristic = (uint16_t) strtoul(optarg, nullptr, 0); break; case OPTION_NCLX_FULL_RANGE_FLAG: nclx_full_range = atoi(optarg); break; case OPTION_PITM_DESCRIPTION: property_pitm_description = optarg; break; case OPTION_USE_JPEG_COMPRESSION: force_enc_jpeg = true; break; case OPTION_USE_JPEG2000_COMPRESSION: force_enc_jpeg2000 = true; break; case OPTION_PLUGIN_DIRECTORY: { int nPlugins; heif_error error = heif_load_plugins(optarg, nullptr, &nPlugins, 0); if (error.code) { std::cerr << "Error loading libheif plugins.\n"; return 1; } // Note: since we process the option within the loop, we can only consider the '-v' flags coming before the plugin loading option. if (logging_level > 0) { std::cout << nPlugins << " plugins loaded from directory " << optarg << "\n"; } break; } case 'C': chroma_downsampling = optarg; if (chroma_downsampling != "nn" && chroma_downsampling != "nearest-neighbor" && chroma_downsampling != "average" && chroma_downsampling != "sharp-yuv") { fprintf(stderr, "Undefined chroma downsampling algorithm.\n"); exit(5); } if (chroma_downsampling == "nn") { // abbreviation chroma_downsampling = "nearest-neighbor"; } #if !HAVE_LIBSHARPYUV if (chroma_downsampling == "sharp-yuv") { std::cerr << "Error: sharp-yuv chroma downsampling method has not been compiled into libheif.\n"; return 5; } #endif break; } } if (quality < 0 || quality > 100) { std::cerr << "Invalid quality factor. Must be between 0 and 100.\n"; return 5; } if ((force_enc_av1f ? 1 : 0) + (force_enc_uncompressed ? 1 : 0) + (force_enc_jpeg ? 1 : 0) + (force_enc_jpeg2000 ? 1 : 0) > 1) { std::cerr << "Choose at most one output compression format.\n"; } if (logging_level > 0) { logging_level += 2; if (logging_level > 4) { logging_level = 4; } } // ============================================================================== struct heif_encoder* encoder = nullptr; if (list_encoders) { show_list_of_all_encoders(); return 0; } if (optind > argc - 1) { show_help(argv[0]); return 0; } // If we were given a list of filenames and no '-o' option, check whether the last filename is the desired output filename. if (output_filename.empty() && argc>1) { if (guess_compression_format_from_filename(argv[argc-1]) != heif_compression_undefined) { output_filename = argv[argc-1]; argc--; } } // --- determine output compression format (from output filename or command line parameter) heif_compression_format compressionFormat; if (force_enc_av1f) { compressionFormat = heif_compression_AV1; } else if (force_enc_uncompressed) { compressionFormat = heif_compression_uncompressed; } else if (force_enc_jpeg) { compressionFormat = heif_compression_JPEG; } else if (force_enc_jpeg2000) { compressionFormat = heif_compression_JPEG2000; } else { compressionFormat = guess_compression_format_from_filename(output_filename); } if (compressionFormat == heif_compression_undefined) { compressionFormat = heif_compression_HEVC; } // --- select encoder std::shared_ptr context(heif_context_alloc(), [](heif_context* c) { heif_context_free(c); }); if (!context) { std::cerr << "Could not create context object\n"; return 1; } #define MAX_ENCODERS 10 const heif_encoder_descriptor* encoder_descriptors[MAX_ENCODERS]; int count = heif_get_encoder_descriptors(compressionFormat, nullptr, encoder_descriptors, MAX_ENCODERS); #undef MAX_ENCODERS const heif_encoder_descriptor* active_encoder_descriptor = nullptr; if (count > 0) { int idx = 0; if (encoderId != nullptr) { for (int i = 0; i <= count; i++) { if (i == count) { std::cerr << "Unknown encoder ID. Choose one from the list below.\n"; show_list_of_encoders(encoder_descriptors, count); return 5; } if (strcmp(encoderId, heif_encoder_descriptor_get_id_name(encoder_descriptors[i])) == 0) { idx = i; break; } } } heif_error error = heif_context_get_encoder(context.get(), encoder_descriptors[idx], &encoder); if (error.code) { std::cerr << error.message << "\n"; return 5; } active_encoder_descriptor = encoder_descriptors[idx]; } else { std::cerr << "No " << get_compression_format_name(compressionFormat) << " encoder available.\n"; return 5; } if (option_show_parameters) { list_encoder_parameters(encoder); return 0; } struct heif_error error; std::shared_ptr primary_image; for (; optind < argc; optind++) { std::string input_filename = argv[optind]; if (output_filename.empty()) { std::string filename_without_suffix; std::string::size_type dot_position = input_filename.find_last_of('.'); if (dot_position != std::string::npos) { filename_without_suffix = input_filename.substr(0, dot_position); } else { filename_without_suffix = input_filename; } std::string suffix = suffix_for_compression_format(compressionFormat); output_filename = filename_without_suffix + '.' + suffix; } // ============================================================================== // get file type from file name std::string suffix; auto suffix_pos = input_filename.find_last_of('.'); if (suffix_pos != std::string::npos) { suffix = input_filename.substr(suffix_pos + 1); std::transform(suffix.begin(), suffix.end(), suffix.begin(), ::tolower); } enum { PNG, JPEG, Y4M } filetype = JPEG; if (suffix == "png") { filetype = PNG; } else if (suffix == "y4m") { filetype = Y4M; } InputImage input_image; if (filetype == PNG) { input_image = loadPNG(input_filename.c_str(), output_bit_depth); } else if (filetype == Y4M) { input_image = loadY4M(input_filename.c_str()); } else { input_image = loadJPEG(input_filename.c_str()); } std::shared_ptr image = input_image.image; if (!primary_image) { primary_image = image; } #if HAVE_GETTIMEOFDAY if (run_benchmark) { gettimeofday(&time_encoding_start, nullptr); } #endif heif_color_profile_nclx nclx; error = heif_nclx_color_profile_set_matrix_coefficients(&nclx, nclx_matrix_coefficients); if (error.code) { std::cerr << "Invalid matrix coefficients specified.\n"; exit(5); } error = heif_nclx_color_profile_set_transfer_characteristics(&nclx, nclx_transfer_characteristic); if (error.code) { std::cerr << "Invalid transfer characteristics specified.\n"; exit(5); } error = heif_nclx_color_profile_set_color_primaries(&nclx, nclx_colour_primaries); if (error.code) { std::cerr << "Invalid color primaries specified.\n"; exit(5); } nclx.full_range_flag = (uint8_t) nclx_full_range; //heif_image_set_nclx_color_profile(image.get(), &nclx); if (lossless) { if (heif_encoder_descriptor_supports_lossless_compression(active_encoder_descriptor)) { heif_encoder_set_lossless(encoder, lossless); } else { std::cerr << "Warning: the selected encoder does not support lossless encoding. Encoding in lossy mode.\n"; } } heif_encoder_set_lossy_quality(encoder, quality); heif_encoder_set_logging_level(encoder, logging_level); set_params(encoder, raw_params); struct heif_encoding_options* options = heif_encoding_options_alloc(); options->save_alpha_channel = (uint8_t) master_alpha; options->save_two_colr_boxes_when_ICC_and_nclx_available = (uint8_t) two_colr_boxes; options->output_nclx_profile = &nclx; options->image_orientation = input_image.orientation; if (chroma_downsampling == "average") { options->color_conversion_options.preferred_chroma_downsampling_algorithm = heif_chroma_downsampling_average; options->color_conversion_options.only_use_preferred_chroma_algorithm = true; } else if (chroma_downsampling == "sharp-yuv") { options->color_conversion_options.preferred_chroma_downsampling_algorithm = heif_chroma_downsampling_sharp_yuv; options->color_conversion_options.only_use_preferred_chroma_algorithm = true; } else if (chroma_downsampling == "nearest-neighbor") { options->color_conversion_options.preferred_chroma_downsampling_algorithm = heif_chroma_downsampling_nearest_neighbor; options->color_conversion_options.only_use_preferred_chroma_algorithm = true; } if (crop_to_even_size) { if (heif_image_get_primary_width(image.get()) == 1 || heif_image_get_primary_height(image.get()) == 1) { std::cerr << "Image only has a size of 1 pixel width or height. Cannot crop to even size.\n"; return 1; } std::cerr << "Warning: option --even-size/-E is deprecated as it is not needed anymore.\n"; int right = heif_image_get_primary_width(image.get()) % 2; int bottom = heif_image_get_primary_height(image.get()) % 2; error = heif_image_crop(image.get(), 0, right, 0, bottom); if (error.code != 0) { heif_encoding_options_free(options); std::cerr << "Could not crop image: " << error.message << "\n"; return 1; } } if (premultiplied_alpha) { heif_image_set_premultiplied_alpha(image.get(), premultiplied_alpha); } struct heif_image_handle* handle; error = heif_context_encode_image(context.get(), image.get(), encoder, options, &handle); if (error.code != 0) { heif_encoding_options_free(options); std::cerr << "Could not encode HEIF/AVIF file: " << error.message << "\n"; return 1; } // write EXIF to HEIC if (!input_image.exif.empty()) { // Note: we do not modify the EXIF Orientation here because we want it to match the HEIF transforms. // TODO: is this a good choice? Or should we set it to 1 (normal) so that other, faulty software will not transform it once more? error = heif_context_add_exif_metadata(context.get(), handle, input_image.exif.data(), (int) input_image.exif.size()); if (error.code != 0) { heif_encoding_options_free(options); std::cerr << "Could not write EXIF metadata: " << error.message << "\n"; return 1; } } // write XMP to HEIC if (!input_image.xmp.empty()) { error = heif_context_add_XMP_metadata2(context.get(), handle, input_image.xmp.data(), (int) input_image.xmp.size(), metadata_compression ? heif_metadata_compression_deflate : heif_metadata_compression_off); if (error.code != 0) { heif_encoding_options_free(options); std::cerr << "Could not write XMP metadata: " << error.message << "\n"; return 1; } } if (thumbnail_bbox_size > 0) { // encode thumbnail struct heif_image_handle* thumbnail_handle; options->save_alpha_channel = master_alpha && thumb_alpha; error = heif_context_encode_thumbnail(context.get(), image.get(), handle, encoder, options, thumbnail_bbox_size, &thumbnail_handle); if (error.code) { heif_encoding_options_free(options); std::cerr << "Could not generate thumbnail: " << error.message << "\n"; return 5; } if (thumbnail_handle) { heif_image_handle_release(thumbnail_handle); } } #if HAVE_GETTIMEOFDAY if (run_benchmark) { gettimeofday(&time_encoding_end, nullptr); } #endif heif_image_handle_release(handle); heif_encoding_options_free(options); } heif_encoder_release(encoder); if (!property_pitm_description.empty()) { heif_image_handle* primary_image_handle; struct heif_error err = heif_context_get_primary_image_handle(context.get(), &primary_image_handle); if (err.code) { std::cerr << "No primary image set, cannot set user description\n"; return 5; } heif_item_id pitm_id = heif_image_handle_get_item_id(primary_image_handle); heif_property_user_description udes; udes.lang = nullptr; udes.name = nullptr; udes.tags = nullptr; udes.description = property_pitm_description.c_str(); err = heif_item_add_property_user_description(context.get(), pitm_id, &udes, nullptr); if (err.code) { std::cerr << "Cannot set user description\n"; return 5; } heif_image_handle_release(primary_image_handle); } error = heif_context_write_to_file(context.get(), output_filename.c_str()); if (error.code) { std::cerr << error.message << "\n"; return 5; } if (run_benchmark) { double psnr = compute_psnr(primary_image.get(), output_filename); std::cout << "PSNR: " << std::setprecision(2) << std::fixed << psnr << " "; #if HAVE_GETTIMEOFDAY double t = (double) (time_encoding_end.tv_sec - time_encoding_start.tv_sec) + (double) (time_encoding_end.tv_usec - time_encoding_start.tv_usec) / 1000000.0; std::cout << "time: " << std::setprecision(1) << std::fixed << t << " "; #endif std::ifstream istr(output_filename.c_str()); istr.seekg(0, std::ios_base::end); std::streamoff size = istr.tellg(); std::cout << "size: " << size << "\n"; } return 0; } libheif-1.17.6/examples/decoder_png.h000664 001750 001750 00000002505 14540541202 020547 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef LIBHEIF_DECODER_PNG_H #define LIBHEIF_DECODER_PNG_H #include "decoder.h" InputImage loadPNG(const char* filename, int output_bit_depth); #endif //LIBHEIF_DECODER_PNG_H libheif-1.17.6/examples/test_c_api.c000664 001750 001750 00000002577 14540541202 020414 0ustar00farindkfarindk000000 000000 /* Very simple test whether the header file compiler with a plain C compiler This file is part of libheif. It performs test calculations for CI checks. MIT License Copyright (c) 2018 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "libheif/heif.h" #include "libheif/heif_version.h" #include "libheif/heif_plugin.h" int main() { return 0; } libheif-1.17.6/examples/decoder_jpeg.h000664 001750 001750 00000002463 14540541202 020713 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef LIBHEIF_DECODER_JPEG_H #define LIBHEIF_DECODER_JPEG_H #include "decoder.h" InputImage loadJPEG(const char* filename); #endif //LIBHEIF_DECODER_JPEG_H libheif-1.17.6/examples/encoder.h000664 001750 001750 00000004245 14540541202 017720 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". MIT License Copyright (c) 2017 struktur AG, Joachim Bauch Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef EXAMPLE_ENCODER_H #define EXAMPLE_ENCODER_H #include #include #include #include class Encoder { public: virtual ~Encoder() = default; virtual heif_colorspace colorspace(bool has_alpha) const = 0; virtual heif_chroma chroma(bool has_alpha, int bit_depth) const = 0; virtual void UpdateDecodingOptions(const struct heif_image_handle* handle, struct heif_decoding_options* options) const { // Override if necessary. } virtual bool Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) = 0; protected: static bool HasExifMetaData(const struct heif_image_handle* handle); static uint8_t* GetExifMetaData(const struct heif_image_handle* handle, size_t* size); static std::vector get_xmp_metadata(const struct heif_image_handle* handle); }; #endif // EXAMPLE_ENCODER_H libheif-1.17.6/examples/COPYING000664 001750 001750 00000002052 14540541202 017155 0ustar00farindkfarindk000000 000000 MIT License 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. libheif-1.17.6/examples/encoder_y4m.cc000664 001750 001750 00000005272 14540541202 020650 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". MIT License Copyright (c) 2019 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "encoder_y4m.h" #include #include #include Y4MEncoder::Y4MEncoder() = default; void Y4MEncoder::UpdateDecodingOptions(const struct heif_image_handle* handle, struct heif_decoding_options* options) const { } bool Y4MEncoder::Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) { FILE* fp = fopen(filename.c_str(), "wb"); if (!fp) { fprintf(stderr, "Can't open %s: %s\n", filename.c_str(), strerror(errno)); return false; } int y_stride, cb_stride, cr_stride; const uint8_t* yp = heif_image_get_plane_readonly(image, heif_channel_Y, &y_stride); const uint8_t* cbp = heif_image_get_plane_readonly(image, heif_channel_Cb, &cb_stride); const uint8_t* crp = heif_image_get_plane_readonly(image, heif_channel_Cr, &cr_stride); assert(y_stride > 0); assert(cb_stride > 0); assert(cr_stride > 0); int yw = heif_image_get_width(image, heif_channel_Y); int yh = heif_image_get_height(image, heif_channel_Y); int cw = heif_image_get_width(image, heif_channel_Cb); int ch = heif_image_get_height(image, heif_channel_Cb); fprintf(fp, "YUV4MPEG2 W%d H%d F30:1\nFRAME\n", yw, yh); for (int y = 0; y < yh; y++) { fwrite(yp + y * y_stride, 1, yw, fp); } for (int y = 0; y < ch; y++) { fwrite(cbp + y * cb_stride, 1, cw, fp); } for (int y = 0; y < ch; y++) { fwrite(crp + y * cr_stride, 1, cw, fp); } fclose(fp); return true; } libheif-1.17.6/examples/common.cc000664 001750 001750 00000003160 14540541202 017722 0ustar00farindkfarindk000000 000000 /* libheif example application "heif". MIT License Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "common.h" #include "libheif/heif.h" #include void show_version() { std::cout << LIBHEIF_VERSION << '\n' << "libheif: " << heif_get_version() << '\n'; { auto paths = heif_get_plugin_directories(); for (int i=0;paths[i];i++) { std::cout << "plugin path: " << paths[i] << '\n'; } if (paths[0] == nullptr) { std::cout << "plugin path: plugins are disabled\n"; } heif_free_plugin_directories(paths); } } libheif-1.17.6/examples/encoder_jpeg.h000664 001750 001750 00000004364 14540541202 020727 0ustar00farindkfarindk000000 000000 /* libheif example application "convert". MIT License Copyright (c) 2017 struktur AG, Joachim Bauch Copyright (c) 2023 Dirk Farin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef EXAMPLE_ENCODER_JPEG_H #define EXAMPLE_ENCODER_JPEG_H #include #include #include #include #include #include "encoder.h" class JpegEncoder : public Encoder { public: JpegEncoder(int quality); heif_colorspace colorspace(bool has_alpha) const override { return heif_colorspace_YCbCr; } heif_chroma chroma(bool has_alpha, int bit_depth) const override { return heif_chroma_420; } void UpdateDecodingOptions(const struct heif_image_handle* handle, struct heif_decoding_options* options) const override; bool Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) override; private: static const int kDefaultQuality = 90; struct ErrorHandler { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; static void OnJpegError(j_common_ptr cinfo); int quality_; }; #endif // EXAMPLE_ENCODER_JPEG_H libheif-1.17.6/cmake/000775 001750 001750 00000000000 14540541203 015366 5ustar00farindkfarindk000000 000000 libheif-1.17.6/cmake/modules/000775 001750 001750 00000000000 14540541203 017036 5ustar00farindkfarindk000000 000000 libheif-1.17.6/cmake/modules/Findkvazaar.cmake000664 001750 001750 00000001611 14540541202 022276 0ustar00farindkfarindk000000 000000 include(LibFindMacros) include(CheckStructHasMember) libfind_pkg_check_modules(KVAZAAR_PKGCONF kvazaar) find_path(KVAZAAR_INCLUDE_DIR NAMES kvazaar.h HINTS ${KVAZAAR_PKGCONF_INCLUDE_DIRS} ${KVAZAAR_PKGCONF_INCLUDEDIR} PATH_SUFFIXES KVAZAAR kvazaar ) find_library(KVAZAAR_LIBRARY NAMES libkvazaar kvazaar kvazaar.dll HINTS ${KVAZAAR_PKGCONF_LIBRARY_DIRS} ${KVAZAAR_PKGCONF_LIBDIR} ) set(KVAZAAR_PROCESS_LIBS KVAZAAR_LIBRARY) set(KVAZAAR_PROCESS_INCLUDES KVAZAAR_INCLUDE_DIR) libfind_process(KVAZAAR) set(CMAKE_REQUIRED_INCLUDES ${KVAZAAR_INCLUDE_DIR}) CHECK_STRUCT_HAS_MEMBER("struct kvz_config" enable_logging_output kvazaar.h HAVE_KVAZAAR_ENABLE_LOGGING LANGUAGE CXX) unset(CMAKE_REQUIRED_INCLUDES) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(kvazaar REQUIRED_VARS KVAZAAR_INCLUDE_DIR KVAZAAR_LIBRARIES ) libheif-1.17.6/cmake/modules/FindSvtEnc.cmake000664 001750 001750 00000001166 14540541202 022046 0ustar00farindkfarindk000000 000000 include(LibFindMacros) libfind_pkg_check_modules(SvtEnc_PKGCONF SvtAv1Enc) find_path(SvtEnc_INCLUDE_DIR NAMES svt-av1/EbSvtAv1Enc.h HINTS ${SvtEnc_PKGCONF_INCLUDE_DIRS} ${SvtEnc_PKGCONF_INCLUDEDIR} PATH_SUFFIXES SvtEnc ) find_library(SvtEnc_LIBRARY NAMES SvtAv1Enc libSvtAv1Enc HINTS ${SvtEnc_PKGCONF_LIBRARY_DIRS} ${SvtEnc_PKGCONF_LIBDIR} ) set(SvtEnc_PROCESS_LIBS SvtEnc_LIBRARY) set(SvtEnc_PROCESS_INCLUDES SvtEnc_INCLUDE_DIR) libfind_process(SvtEnc) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(SvtEnc REQUIRED_VARS SvtEnc_INCLUDE_DIR SvtEnc_LIBRARIES ) libheif-1.17.6/cmake/modules/FindAOM.cmake000664 001750 001750 00000002051 14540541202 021252 0ustar00farindkfarindk000000 000000 include(LibFindMacros) include(CheckSymbolExists) libfind_pkg_check_modules(AOM_PKGCONF aom) find_path(AOM_INCLUDE_DIR NAMES aom/aom_decoder.h aom/aom_encoder.h HINTS ${AOM_PKGCONF_INCLUDE_DIRS} ${AOM_PKGCONF_INCLUDEDIR} PATH_SUFFIXES AOM ) list(APPEND CMAKE_REQUIRED_INCLUDES ${AOM_INCLUDE_DIR}) check_symbol_exists(AOM_USAGE_GOOD_QUALITY aom/aom_encoder.h aom_usage_flag_exists) unset(CMAKE_REQUIRED_INCLUDES) find_library(AOM_LIBRARY NAMES libaom aom HINTS ${AOM_PKGCONF_LIBRARY_DIRS} ${AOM_PKGCONF_LIBDIR} ) if(EXISTS "${AOM_INCLUDE_DIR}/aom/aom_decoder.h") set(AOM_DECODER_FOUND YES) else() set(AOM_DECODER_FOUND NO) endif() if((EXISTS "${AOM_INCLUDE_DIR}/aom/aom_encoder.h") AND "${aom_usage_flag_exists}") set(AOM_ENCODER_FOUND YES) else() set(AOM_ENCODER_FOUND NO) endif() set(AOM_PROCESS_LIBS AOM_LIBRARY) set(AOM_PROCESS_INCLUDES AOM_INCLUDE_DIR) libfind_process(AOM) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(AOM REQUIRED_VARS AOM_INCLUDE_DIR AOM_LIBRARIES ) libheif-1.17.6/cmake/modules/FindX265.cmake000664 001750 001750 00000001704 14540541202 021306 0ustar00farindkfarindk000000 000000 include(LibFindMacros) libfind_pkg_check_modules(X265_PKGCONF x265) find_path(X265_INCLUDE_DIR NAMES x265.h HINTS ${X265_PKGCONF_INCLUDE_DIRS} ${X265_PKGCONF_INCLUDEDIR} PATH_SUFFIXES X265 ) find_library(X265_LIBRARY NAMES libx265 x265 HINTS ${X265_PKGCONF_LIBRARY_DIRS} ${X265_PKGCONF_LIBDIR} ) set(X265_PROCESS_LIBS X265_LIBRARY) set(X265_PROCESS_INCLUDES X265_INCLUDE_DIR) libfind_process(X265) if(X265_INCLUDE_DIR) set(x265_config_file "${X265_INCLUDE_DIR}/x265_config.h") if(EXISTS ${x265_config_file}) file(STRINGS ${x265_config_file} TMP REGEX "#define X265_BUILD .*$") string(REGEX REPLACE "#define X265_BUILD" "" TMP ${TMP}) string(REGEX MATCHALL "[0-9.]+" X265_BUILD ${TMP}) endif() endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(X265 REQUIRED_VARS X265_INCLUDE_DIR X265_LIBRARIES VERSION_VAR X265_BUILD ) libheif-1.17.6/cmake/modules/FindRAV1E.cmake000664 001750 001750 00000001134 14540541202 021455 0ustar00farindkfarindk000000 000000 include(LibFindMacros) libfind_pkg_check_modules(RAV1E_PKGCONF rav1e) find_path(RAV1E_INCLUDE_DIR NAMES rav1e.h HINTS ${RAV1E_PKGCONF_INCLUDE_DIRS} ${RAV1E_PKGCONF_INCLUDEDIR} PATH_SUFFIXES RAV1E rav1e ) find_library(RAV1E_LIBRARY NAMES librav1e rav1e rav1e.dll HINTS ${RAV1E_PKGCONF_LIBRARY_DIRS} ${RAV1E_PKGCONF_LIBDIR} ) set(RAV1E_PROCESS_LIBS RAV1E_LIBRARY) set(RAV1E_PROCESS_INCLUDES RAV1E_INCLUDE_DIR) libfind_process(RAV1E) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(RAV1E REQUIRED_VARS RAV1E_INCLUDE_DIR RAV1E_LIBRARIES ) libheif-1.17.6/cmake/modules/LibFindMacros.cmake000664 001750 001750 00000025110 14540541202 022512 0ustar00farindkfarindk000000 000000 # Version 2.3 # Public Domain, originally written by Lasse Kärkkäinen # Maintained at https://github.com/Tronic/cmake-modules # Please send your improvements as pull requests on GitHub. # Find another package and make it a dependency of the current package. # This also automatically forwards the "REQUIRED" argument. # Usage: libfind_package( [extra args to find_package]) macro (libfind_package PREFIX PKG) set(${PREFIX}_args ${PKG} ${ARGN}) if (${PREFIX}_FIND_REQUIRED) set(${PREFIX}_args ${${PREFIX}_args} REQUIRED) endif() find_package(${${PREFIX}_args}) set(${PREFIX}_DEPENDENCIES ${${PREFIX}_DEPENDENCIES};${PKG}) unset(${PREFIX}_args) endmacro() # A simple wrapper to make pkg-config searches a bit easier. # Works the same as CMake's internal pkg_check_modules but is always quiet. macro (libfind_pkg_check_modules) find_package(PkgConfig QUIET) if (PKG_CONFIG_FOUND) pkg_check_modules(${ARGN} QUIET) endif() endmacro() # Avoid useless copy&pasta by doing what most simple libraries do anyway: # pkg-config, find headers, find library. # Usage: libfind_pkg_detect( FIND_PATH [other args] FIND_LIBRARY [other args]) # E.g. libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2) function (libfind_pkg_detect PREFIX) # Parse arguments set(argname pkgargs) foreach (i ${ARGN}) if ("${i}" STREQUAL "FIND_PATH") set(argname pathargs) elseif ("${i}" STREQUAL "FIND_LIBRARY") set(argname libraryargs) else() set(${argname} ${${argname}} ${i}) endif() endforeach() if (NOT pkgargs) message(FATAL_ERROR "libfind_pkg_detect requires at least a pkg_config package name to be passed.") endif() # Find library libfind_pkg_check_modules(${PREFIX}_PKGCONF ${pkgargs}) if (pathargs) find_path(${PREFIX}_INCLUDE_DIR NAMES ${pathargs} HINTS ${${PREFIX}_PKGCONF_INCLUDE_DIRS}) endif() if (libraryargs) find_library(${PREFIX}_LIBRARY NAMES ${libraryargs} HINTS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}) endif() # Read pkg-config version if (${PREFIX}_PKGCONF_VERSION) set(${PREFIX}_VERSION ${${PREFIX}_PKGCONF_VERSION} PARENT_SCOPE) endif() endfunction() # Extracts a version #define from a version.h file, output stored to _VERSION. # Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR) # Fourth argument "QUIET" may be used for silently testing different define names. # This function does nothing if the version variable is already defined. function (libfind_version_header PREFIX VERSION_H DEFINE_NAME) # Skip processing if we already have a version or if the include dir was not found if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR) return() endif() set(quiet ${${PREFIX}_FIND_QUIETLY}) # Process optional arguments foreach(arg ${ARGN}) if (arg STREQUAL "QUIET") set(quiet TRUE) else() message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.") endif() endforeach() # Read the header and parse for version number set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") if (NOT EXISTS ${filename}) if (NOT quiet) message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") endif() return() endif() file(READ "${filename}" header) string(REGEX REPLACE ".*#[ \t]*define[ \t]*${DEFINE_NAME}[ \t]*\"([^\n]*)\".*" "\\1" match "${header}") # No regex match? if (match STREQUAL header) if (NOT quiet) message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") endif() return() endif() # Export the version string set(${PREFIX}_VERSION "${match}" PARENT_SCOPE) endfunction() # Do the final processing once the paths have been detected. # If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain # all the variables, each of which contain one include directory. # Ditto for ${PREFIX}_PROCESS_LIBS and library files. # Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES. # Also handles errors in case library detection was required, etc. function (libfind_process PREFIX) # Skip processing if already processed during this configuration run if (${PREFIX}_FOUND) return() endif() set(found TRUE) # Start with the assumption that the package was found # Did we find any files? Did we miss includes? These are for formatting better error messages. set(some_files FALSE) set(missing_headers FALSE) # Shorthands for some variables that we need often set(quiet ${${PREFIX}_FIND_QUIETLY}) set(required ${${PREFIX}_FIND_REQUIRED}) set(exactver ${${PREFIX}_FIND_VERSION_EXACT}) set(findver "${${PREFIX}_FIND_VERSION}") set(version "${${PREFIX}_VERSION}") # Lists of config option names (all, includes, libs) unset(configopts) set(includeopts ${${PREFIX}_PROCESS_INCLUDES}) set(libraryopts ${${PREFIX}_PROCESS_LIBS}) # Process deps to add to foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES}) if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS) # The package seems to export option lists that we can use, woohoo! list(APPEND includeopts ${${i}_INCLUDE_OPTS}) list(APPEND libraryopts ${${i}_LIBRARY_OPTS}) else() # If plural forms don't exist or they equal singular forms if ((NOT DEFINED ${i}_INCLUDE_DIRS AND NOT DEFINED ${i}_LIBRARIES) OR (${i}_INCLUDE_DIR STREQUAL ${i}_INCLUDE_DIRS AND ${i}_LIBRARY STREQUAL ${i}_LIBRARIES)) # Singular forms can be used if (DEFINED ${i}_INCLUDE_DIR) list(APPEND includeopts ${i}_INCLUDE_DIR) endif() if (DEFINED ${i}_LIBRARY) list(APPEND libraryopts ${i}_LIBRARY) endif() else() # Oh no, we don't know the option names message(FATAL_ERROR "We couldn't determine config variable names for ${i} includes and libs. Aieeh!") endif() endif() endforeach() if (includeopts) list(REMOVE_DUPLICATES includeopts) endif() if (libraryopts) list(REMOVE_DUPLICATES libraryopts) endif() string(REGEX REPLACE ".*[ ;]([^ ;]*(_INCLUDE_DIRS|_LIBRARIES))" "\\1" tmp "${includeopts} ${libraryopts}") if (NOT tmp STREQUAL "${includeopts} ${libraryopts}") message(AUTHOR_WARNING "Plural form ${tmp} found in config options of ${PREFIX}. This works as before but is now deprecated. Please only use singular forms INCLUDE_DIR and LIBRARY, and update your find scripts for LibFindMacros > 2.0 automatic dependency system (most often you can simply remove the PROCESS variables entirely).") endif() # Include/library names separated by spaces (notice: not CMake lists) unset(includes) unset(libs) # Process all includes and set found false if any are missing foreach (i ${includeopts}) list(APPEND configopts ${i}) if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND") list(APPEND includes "${${i}}") else() set(found FALSE) set(missing_headers TRUE) endif() endforeach() # Process all libraries and set found false if any are missing foreach (i ${libraryopts}) list(APPEND configopts ${i}) if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND") list(APPEND libs "${${i}}") else() set (found FALSE) endif() endforeach() # Version checks if (found AND findver) if (NOT version) message(WARNING "The find module for ${PREFIX} does not provide version information, so we'll just assume that it is OK. Please fix the module or remove package version requirements to get rid of this warning.") elseif (version VERSION_LESS findver OR (exactver AND NOT version VERSION_EQUAL findver)) set(found FALSE) set(version_unsuitable TRUE) endif() endif() # If all-OK, hide all config options, export variables, print status and exit if (found) foreach (i ${configopts}) mark_as_advanced(${i}) endforeach() if (NOT quiet) message(STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}") if (LIBFIND_DEBUG) message(STATUS " ${PREFIX}_DEPENDENCIES=${${PREFIX}_DEPENDENCIES}") message(STATUS " ${PREFIX}_INCLUDE_OPTS=${includeopts}") message(STATUS " ${PREFIX}_INCLUDE_DIRS=${includes}") message(STATUS " ${PREFIX}_LIBRARY_OPTS=${libraryopts}") message(STATUS " ${PREFIX}_LIBRARIES=${libs}") endif() endif() set (${PREFIX}_INCLUDE_OPTS ${includeopts} PARENT_SCOPE) set (${PREFIX}_LIBRARY_OPTS ${libraryopts} PARENT_SCOPE) set (${PREFIX}_INCLUDE_DIRS ${includes} PARENT_SCOPE) set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE) set (${PREFIX}_FOUND TRUE PARENT_SCOPE) return() endif() # Format messages for debug info and the type of error set(vars "Relevant CMake configuration variables:\n") foreach (i ${configopts}) mark_as_advanced(CLEAR ${i}) set(val ${${i}}) if ("${val}" STREQUAL "${i}-NOTFOUND") set (val "") elseif (val AND NOT EXISTS ${val}) set (val "${val} (does not exist)") else() set(some_files TRUE) endif() set(vars "${vars} ${i}=${val}\n") endforeach() set(vars "${vars}You may use CMake GUI, cmake -D or ccmake to modify the values. Delete CMakeCache.txt to discard all values and force full re-detection if necessary.\n") if (version_unsuitable) set(msg "${PREFIX} ${${PREFIX}_VERSION} was found but") if (exactver) set(msg "${msg} only version ${findver} is acceptable.") else() set(msg "${msg} version ${findver} is the minimum requirement.") endif() else() if (missing_headers) set(msg "We could not find development headers for ${PREFIX}. Do you have the necessary dev package installed?") elseif (some_files) set(msg "We only found some files of ${PREFIX}, not all of them. Perhaps your installation is incomplete or maybe we just didn't look in the right place?") if(findver) set(msg "${msg} This could also be caused by incompatible version (if it helps, at least ${PREFIX} ${findver} should work).") endif() else() set(msg "We were unable to find package ${PREFIX}.") endif() endif() # Fatal error out if REQUIRED if (required) set(msg "REQUIRED PACKAGE NOT FOUND\n${msg} This package is REQUIRED and you need to install it or adjust CMake configuration in order to continue building ${CMAKE_PROJECT_NAME}.") message(FATAL_ERROR "${msg}\n${vars}") endif() # Otherwise just print a nasty warning if (NOT quiet) message(WARNING "WARNING: MISSING PACKAGE\n${msg} This package is NOT REQUIRED and you may ignore this warning but by doing so you may miss some functionality of ${CMAKE_PROJECT_NAME}. \n${vars}") endif() endfunction() libheif-1.17.6/cmake/modules/FindDAV1D.cmake000664 001750 001750 00000001122 14540541202 021433 0ustar00farindkfarindk000000 000000 include(LibFindMacros) libfind_pkg_check_modules(DAV1D_PKGCONF dav1d) find_path(DAV1D_INCLUDE_DIR NAMES dav1d/dav1d.h HINTS ${DAV1D_PKGCONF_INCLUDE_DIRS} ${DAV1D_PKGCONF_INCLUDEDIR} PATH_SUFFIXES DAV1D ) find_library(DAV1D_LIBRARY NAMES libdav1d dav1d HINTS ${DAV1D_PKGCONF_LIBRARY_DIRS} ${DAV1D_PKGCONF_LIBDIR} ) set(DAV1D_PROCESS_LIBS DAV1D_LIBRARY) set(DAV1D_PROCESS_INCLUDES DAV1D_INCLUDE_DIR) libfind_process(DAV1D) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DAV1D REQUIRED_VARS DAV1D_INCLUDE_DIR DAV1D_LIBRARIES ) libheif-1.17.6/cmake/modules/FindLIBDE265.cmake000664 001750 001750 00000002117 14540541202 021715 0ustar00farindkfarindk000000 000000 include(LibFindMacros) libfind_pkg_check_modules(LIBDE265_PKGCONF libde265) find_path(LIBDE265_INCLUDE_DIR NAMES libde265/de265.h HINTS ${LIBDE265_PKGCONF_INCLUDE_DIRS} ${LIBDE265_PKGCONF_INCLUDEDIR} PATH_SUFFIXES DE265 ) find_library(LIBDE265_LIBRARY NAMES libde265 de265 HINTS ${LIBDE265_PKGCONF_LIBRARY_DIRS} ${LIBDE265_PKGCONF_LIBDIR} ) set(LIBDE265_PROCESS_LIBS ${LIBDE265_LIBRARY}) set(LIBDE265_PROCESS_INCLUDES ${LIBDE265_INCLUDE_DIR}) libfind_process(LIBDE265) if(LIBDE265_INCLUDE_DIR) set(libde265_config_file "${LIBDE265_INCLUDE_DIR}/libde265/de265-version.h") if(EXISTS ${libde265_config_file}) file(STRINGS ${libde265_config_file} TMP REGEX "#define LIBDE265_VERSION .*$") string(REGEX REPLACE "#define LIBDE265_VERSION" "" TMP ${TMP}) string(REGEX MATCHALL "[0-9.]+" LIBDE265_VERSION ${TMP}) endif() endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LIBDE265 REQUIRED_VARS LIBDE265_INCLUDE_DIRS LIBDE265_LIBRARIES VERSION_VAR LIBDE265_VERSION ) libheif-1.17.6/cmake/modules/FindFFMPEG.cmake000664 001750 001750 00000014267 14540541202 021616 0ustar00farindkfarindk000000 000000 # Taken Oct.2023 from VTK (Visualization Toolkit) #[==[ Provides the following variables: * `FFMPEG_INCLUDE_DIRS`: Include directories necessary to use FFMPEG. * `FFMPEG_LIBRARIES`: Libraries necessary to use FFMPEG. Note that this only includes libraries for the components requested. * `FFMPEG_VERSION`: The version of FFMPEG found. The following components are supported: * `avcodec` * `avdevice` * `avfilter` * `avformat` * `avresample` * `avutil` * `swresample` * `swscale` For each component, the following are provided: * `FFMPEG__FOUND`: Libraries for the component. * `FFMPEG__INCLUDE_DIRS`: Include directories for the component. * `FFMPEG__LIBRARIES`: Libraries for the component. * `FFMPEG::`: A target to use with `target_link_libraries`. Note that only components requested with `COMPONENTS` or `OPTIONAL_COMPONENTS` are guaranteed to set these variables or provide targets. #]==] function (_ffmpeg_find component headername) find_path("FFMPEG_${component}_INCLUDE_DIR" NAMES "lib${component}/${headername}" PATHS "${FFMPEG_ROOT}/include" ~/Library/Frameworks /Library/Frameworks /usr/local/include /usr/include /sw/include # Fink /opt/local/include # DarwinPorts /opt/csw/include # Blastwave /opt/include /usr/freeware/include PATH_SUFFIXES ffmpeg DOC "FFMPEG's ${component} include directory") mark_as_advanced("FFMPEG_${component}_INCLUDE_DIR") # On Windows, static FFMPEG is sometimes built as `lib.a`. if (WIN32) list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".lib") list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "" "lib") endif () find_library("FFMPEG_${component}_LIBRARY" NAMES "${component}" PATHS "${FFMPEG_ROOT}/lib" ~/Library/Frameworks /Library/Frameworks /usr/local/lib /usr/local/lib64 /usr/lib /usr/lib64 /sw/lib /opt/local/lib /opt/csw/lib /opt/lib /usr/freeware/lib64 "${FFMPEG_ROOT}/bin" DOC "FFMPEG's ${component} library") mark_as_advanced("FFMPEG_${component}_LIBRARY") if (FFMPEG_${component}_LIBRARY AND FFMPEG_${component}_INCLUDE_DIR) set(_deps_found TRUE) set(_deps_link) foreach (_ffmpeg_dep IN LISTS ARGN) if (TARGET "FFMPEG::${_ffmpeg_dep}") list(APPEND _deps_link "FFMPEG::${_ffmpeg_dep}") else () set(_deps_found FALSE) endif () endforeach () if (_deps_found) if (NOT TARGET "FFMPEG::${component}") add_library("FFMPEG::${component}" UNKNOWN IMPORTED) set_target_properties("FFMPEG::${component}" PROPERTIES IMPORTED_LOCATION "${FFMPEG_${component}_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${FFMPEG_${component}_INCLUDE_DIR}" IMPORTED_LINK_INTERFACE_LIBRARIES "${_deps_link}") endif () set("FFMPEG_${component}_FOUND" 1 PARENT_SCOPE) set(version_header_path "${FFMPEG_${component}_INCLUDE_DIR}/lib${component}/version.h") if (EXISTS "${version_header_path}") string(TOUPPER "${component}" component_upper) file(STRINGS "${version_header_path}" version REGEX "#define *LIB${component_upper}_VERSION_(MAJOR|MINOR|MICRO) ") string(REGEX REPLACE ".*_MAJOR *\([0-9]*\).*" "\\1" major "${version}") string(REGEX REPLACE ".*_MINOR *\([0-9]*\).*" "\\1" minor "${version}") string(REGEX REPLACE ".*_MICRO *\([0-9]*\).*" "\\1" micro "${version}") if (NOT major STREQUAL "" AND NOT minor STREQUAL "" AND NOT micro STREQUAL "") set("FFMPEG_${component}_VERSION" "${major}.${minor}.${micro}" PARENT_SCOPE) endif () endif () else () set("FFMPEG_${component}_FOUND" 0 PARENT_SCOPE) set(what) if (NOT FFMPEG_${component}_LIBRARY) set(what "library") endif () if (NOT FFMPEG_${component}_INCLUDE_DIR) if (what) string(APPEND what " or headers") else () set(what "headers") endif () endif () set("FFMPEG_${component}_NOT_FOUND_MESSAGE" "Could not find the ${what} for ${component}." PARENT_SCOPE) endif () endif () endfunction () _ffmpeg_find(avutil avutil.h) _ffmpeg_find(avresample avresample.h avutil) _ffmpeg_find(swresample swresample.h avutil) _ffmpeg_find(swscale swscale.h avutil) _ffmpeg_find(avcodec avcodec.h avutil) _ffmpeg_find(avformat avformat.h avcodec avutil) _ffmpeg_find(avfilter avfilter.h avutil) _ffmpeg_find(avdevice avdevice.h avformat avutil) if (TARGET FFMPEG::avutil) set(_ffmpeg_version_header_path "${FFMPEG_avutil_INCLUDE_DIR}/libavutil/ffversion.h") if (EXISTS "${_ffmpeg_version_header_path}") file(STRINGS "${_ffmpeg_version_header_path}" _ffmpeg_version REGEX "FFMPEG_VERSION") string(REGEX REPLACE ".*\"n?\(.*\)\"" "\\1" FFMPEG_VERSION "${_ffmpeg_version}") unset(_ffmpeg_version) else () set(FFMPEG_VERSION FFMPEG_VERSION-NOTFOUND) endif () unset(_ffmpeg_version_header_path) endif () set(FFMPEG_INCLUDE_DIRS) set(FFMPEG_LIBRARIES) set(_ffmpeg_required_vars) foreach (_ffmpeg_component IN LISTS FFMPEG_FIND_COMPONENTS) if (TARGET "FFMPEG::${_ffmpeg_component}") set(FFMPEG_${_ffmpeg_component}_INCLUDE_DIRS "${FFMPEG_${_ffmpeg_component}_INCLUDE_DIR}") set(FFMPEG_${_ffmpeg_component}_LIBRARIES "${FFMPEG_${_ffmpeg_component}_LIBRARY}") list(APPEND FFMPEG_INCLUDE_DIRS "${FFMPEG_${_ffmpeg_component}_INCLUDE_DIRS}") list(APPEND FFMPEG_LIBRARIES "${FFMPEG_${_ffmpeg_component}_LIBRARIES}") if (FFMEG_FIND_REQUIRED_${_ffmpeg_component}) list(APPEND _ffmpeg_required_vars "FFMPEG_${_ffmpeg_required_vars}_INCLUDE_DIRS" "FFMPEG_${_ffmpeg_required_vars}_LIBRARIES") endif () endif () endforeach () unset(_ffmpeg_component) if (FFMPEG_INCLUDE_DIRS) list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS) endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(FFMPEG REQUIRED_VARS FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES ${_ffmpeg_required_vars} VERSION_VAR FFMPEG_VERSION HANDLE_COMPONENTS) unset(_ffmpeg_required_vars) libheif-1.17.6/cmake/modules/Findlibsharpyuv.cmake000664 001750 001750 00000001271 14540541202 023211 0ustar00farindkfarindk000000 000000 include(LibFindMacros) libfind_pkg_check_modules(LIBSHARPYUV_PKGCONF libsharpyuv) find_path(LIBSHARPYUV_INCLUDE_DIR NAMES sharpyuv/sharpyuv.h HINTS ${LIBSHARPYUV_PKGCONF_INCLUDE_DIRS} ${LIBSHARPYUV_PKGCONF_INCLUDEDIR} PATH_SUFFIXES LIBSHARPYUV ) find_library(LIBSHARPYUV_LIBRARY NAMES sharpyuv HINTS ${LIBSHARPYUV_PKGCONF_LIBRARY_DIRS} ${LIBSHARPYUV_PKGCONF_LIBDIR} ) set(LIBSHARPYUV_PROCESS_LIBS LIBSHARPYUV_LIBRARY) set(LIBSHARPYUV_PROCESS_INCLUDES LIBSHARPYUV_INCLUDE_DIR) libfind_process(LIBSHARPYUV) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(libsharpyuv REQUIRED_VARS LIBSHARPYUV_INCLUDE_DIR LIBSHARPYUV_LIBRARIES ) libheif-1.17.6/extra/000775 001750 001750 00000000000 14540541203 015431 5ustar00farindkfarindk000000 000000 libheif-1.17.6/extra/getopt.c000664 001750 001750 00000010603 14540541202 017076 0ustar00farindkfarindk000000 000000 /* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; #endif #include #include #include #include #define __P(x) x #define _DIAGASSERT(x) assert(x) #ifdef __weak_alias __weak_alias(getopt,_getopt); #endif #ifdef __cplusplus extern "C" { #endif int opterr = 1, /* if error message should be printed */ optind = 1, /* index into parent argv vector */ optopt, /* character checked for validity */ optreset; /* reset getopt */ char *optarg; /* argument associated with option */ static char * _progname __P((char *)); int getopt_internal __P((int, char * const *, const char *)); static char * _progname(char * nargv0) { char * tmp; _DIAGASSERT(nargv0 != NULL); tmp = strrchr(nargv0, '/'); if (tmp) tmp++; else tmp = nargv0; return(tmp); } #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" /* * getopt -- * Parse argc/argv argument vector. */ int getopt(int nargc, char * nargv[], const char *ostr) { static char *__progname = 0; static char *place = EMSG; /* option letter processing */ const char *oli; /* option letter list index */ __progname = __progname?__progname:_progname(*nargv); _DIAGASSERT(nargv != NULL); _DIAGASSERT(ostr != NULL); if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; return (-1); } if (place[1] && *++place == '-' /* found "--" */ && place[1] == '\0') { ++optind; place = EMSG; return (-1); } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr, optopt))) { /* * if the user didn't specify '-' as an option, * assume it means -1. */ if (optopt == (int)'-') return (-1); if (!*place) ++optind; if (opterr && *ostr != ':') (void)fprintf(stderr, "%s: illegal option -- %c\n", __progname, optopt); return (BADCH); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; } else { /* need an argument */ if (*place) /* no white space */ optarg = place; else if (nargc <= ++optind) { /* no arg */ place = EMSG; if (*ostr == ':') return (BADARG); if (opterr) (void)fprintf(stderr, "%s: option requires an argument -- %c\n", __progname, optopt); return (BADCH); } else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; } return (optopt); /* dump back option letter */ } #ifdef __cplusplus } #endif libheif-1.17.6/extra/getopt.h000664 001750 001750 00000004721 14540541202 017107 0ustar00farindkfarindk000000 000000 /* * Copyright (c) 1987, 1993, 1994, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __GETOPT_H__ #define __GETOPT_H__ #ifdef __cplusplus extern "C" { #endif extern int opterr; /* if error message should be printed */ extern int optind; /* index into parent argv vector */ extern int optopt; /* character checked for validity */ extern int optreset; /* reset getopt */ extern char *optarg; /* argument associated with option */ struct option { const char *name; int has_arg; int *flag; int val; }; #define no_argument 0 #define required_argument 1 #define optional_argument 2 int getopt(int, char**, char*); int getopt_long(int, char**, char*, struct option*, int*); #ifdef __cplusplus } #endif #endif /* __GETOPT_H__ */ libheif-1.17.6/extra/getopt_long.c000664 001750 001750 00000014403 14540541202 020117 0ustar00farindkfarindk000000 000000 /* * Copyright (c) 1987, 1993, 1994, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include "getopt.h" extern int opterr; /* if error message should be printed */ extern int optind; /* index into parent argv vector */ extern int optopt; /* character checked for validity */ extern int optreset; /* reset getopt */ extern char *optarg; /* argument associated with option */ #define __P(x) x #define _DIAGASSERT(x) assert(x) static char * __progname __P((char *)); int getopt_internal __P((int, char * const *, const char *)); static char * __progname(char * nargv0) { char * tmp; _DIAGASSERT(nargv0 != NULL); tmp = strrchr(nargv0, '/'); if (tmp) tmp++; else tmp = nargv0; return(tmp); } #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" /* * getopt -- * Parse argc/argv argument vector. */ int getopt_internal(int nargc, char * const* nargv, const char *ostr) { static char *place = EMSG; /* option letter processing */ const char *oli; /* option letter list index */ _DIAGASSERT(nargv != NULL); _DIAGASSERT(ostr != NULL); if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; return (-1); } if (place[1] && *++place == '-') { /* found "--" */ /* ++optind; */ place = EMSG; return (-2); } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr, optopt))) { /* * if the user didn't specify '-' as an option, * assume it means -1. */ if (optopt == (int)'-') return (-1); if (!*place) ++optind; if (opterr && *ostr != ':') (void)fprintf(stderr, "%s: illegal option -- %c\n", __progname(nargv[0]), optopt); return (BADCH); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; } else { /* need an argument */ if (*place) /* no white space */ optarg = place; else if (nargc <= ++optind) { /* no arg */ place = EMSG; if ((opterr) && (*ostr != ':')) (void)fprintf(stderr, "%s: option requires an argument -- %c\n", __progname(nargv[0]), optopt); return (BADARG); } else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; } return (optopt); /* dump back option letter */ } #if 0 /* * getopt -- * Parse argc/argv argument vector. */ int getopt2(int nargc, char * nargv, const char *ostr) { int retval; if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) { retval = -1; ++optind; } return(retval); } #endif /* * getopt_long -- * Parse argc/argv argument vector. */ int getopt_long(int nargc, char ** nargv, char * options, struct option * long_options, int * index) { int retval; _DIAGASSERT(nargv != NULL); _DIAGASSERT(options != NULL); _DIAGASSERT(long_options != NULL); /* index may be NULL */ if ((retval = getopt_internal(nargc, nargv, options)) == -2) { char *current_argv = nargv[optind++] + 2, *has_equal; int i, current_argv_len, match = -1; if (*current_argv == '\0') { return(-1); } if ((has_equal = strchr(current_argv, '=')) != NULL) { current_argv_len = has_equal - current_argv; has_equal++; } else current_argv_len = strlen(current_argv); for (i = 0; long_options[i].name; i++) { if (strncmp(current_argv, long_options[i].name, current_argv_len)) continue; if (strlen(long_options[i].name) == (unsigned)current_argv_len) { match = i; break; } if (match == -1) match = i; } if (match != -1) { if (long_options[match].has_arg == required_argument || long_options[match].has_arg == optional_argument) { if (has_equal) optarg = has_equal; else optarg = nargv[optind++]; } if ((long_options[match].has_arg == required_argument) && (optarg == NULL)) { /* * Missing argument, leading : * indicates no error should be generated */ if ((opterr) && (*options != ':')) (void)fprintf(stderr, "%s: option requires an argument -- %s\n", __progname(nargv[0]), current_argv); return (BADARG); } } else { /* No matching argument */ if ((opterr) && (*options != ':')) (void)fprintf(stderr, "%s: illegal option -- %s\n", __progname(nargv[0]), current_argv); return (BADCH); } if (long_options[match].flag) { *long_options[match].flag = long_options[match].val; retval = 0; } else retval = long_options[match].val; if (index) *index = match; } return(retval); } libheif-1.17.6/gdk-pixbuf/000775 001750 001750 00000000000 14540541203 016346 5ustar00farindkfarindk000000 000000 libheif-1.17.6/gdk-pixbuf/CMakeLists.txt000664 001750 001750 00000001460 14540541202 021106 0ustar00farindkfarindk000000 000000 if(UNIX OR MINGW) find_package(PkgConfig) pkg_check_modules(GDKPIXBUF2 gdk-pixbuf-2.0) if(GDKPIXBUF2_FOUND) execute_process( COMMAND ${PKG_CONFIG_EXECUTABLE} gdk-pixbuf-2.0 --variable gdk_pixbuf_moduledir --define-variable=prefix=${CMAKE_INSTALL_PREFIX} OUTPUT_VARIABLE GDKPIXBUF2_MODULE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) add_library(pixbufloader-heif MODULE pixbufloader-heif.c) target_include_directories(pixbufloader-heif PRIVATE ${GDKPIXBUF2_INCLUDE_DIRS} ${libheif_BINARY_DIR} ${libheif_SOURCE_DIR}) target_link_directories(pixbufloader-heif PRIVATE ${GDKPIXBUF2_LIBRARY_DIRS}) target_link_libraries(pixbufloader-heif PUBLIC ${GDKPIXBUF2_LIBRARIES} heif) install(TARGETS pixbufloader-heif DESTINATION ${GDKPIXBUF2_MODULE_DIR}) endif() endif() libheif-1.17.6/gdk-pixbuf/pixbufloader-heif.c000664 001750 001750 00000014322 14540541202 022110 0ustar00farindkfarindk000000 000000 /* * gdk-pixbuf loader module for libheif * Copyright (c) 2019 Oliver Giles * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #define GDK_PIXBUF_ENABLE_BACKEND #include #include G_MODULE_EXPORT void fill_vtable(GdkPixbufModule* module); G_MODULE_EXPORT void fill_info(GdkPixbufFormat* info); typedef struct { GdkPixbufModuleUpdatedFunc update_func; GdkPixbufModulePreparedFunc prepare_func; GdkPixbufModuleSizeFunc size_func; gpointer user_data; GByteArray* data; } HeifPixbufCtx; static gpointer begin_load(GdkPixbufModuleSizeFunc size_func, GdkPixbufModulePreparedFunc prepare_func, GdkPixbufModuleUpdatedFunc update_func, gpointer user_data, GError** error) { HeifPixbufCtx* hpc; hpc = g_new0(HeifPixbufCtx, 1); hpc->data = g_byte_array_new(); hpc->size_func = size_func; hpc->prepare_func = prepare_func; hpc->update_func = update_func; hpc->user_data = user_data; return hpc; } static void release_heif_image(guchar* pixels, gpointer data) { heif_image_release((struct heif_image*) data); } static gboolean stop_load(gpointer context, GError** error) { HeifPixbufCtx* hpc; struct heif_error err; struct heif_context* hc = NULL; struct heif_image_handle* hdl = NULL; struct heif_image* img = NULL; int width, height, stride; int requested_width, requested_height; const uint8_t* data; GdkPixbuf* pixbuf; gboolean result; result = FALSE; hpc = (HeifPixbufCtx*) context; err = heif_init(NULL); if (err.code != heif_error_Ok) { g_warning("%s", err.message); goto cleanup; } hc = heif_context_alloc(); if (!hc) { g_warning("cannot allocate heif_context"); goto cleanup; } err = heif_context_read_from_memory_without_copy(hc, hpc->data->data, hpc->data->len, NULL); if (err.code != heif_error_Ok) { g_warning("%s", err.message); goto cleanup; } err = heif_context_get_primary_image_handle(hc, &hdl); if (err.code != heif_error_Ok) { g_warning("%s", err.message); goto cleanup; } int has_alpha = heif_image_handle_has_alpha_channel(hdl); err = heif_decode_image(hdl, &img, heif_colorspace_RGB, has_alpha ? heif_chroma_interleaved_RGBA : heif_chroma_interleaved_RGB, NULL); if (err.code != heif_error_Ok) { g_warning("%s", err.message); goto cleanup; } width = heif_image_get_width(img, heif_channel_interleaved); height = heif_image_get_height(img, heif_channel_interleaved); requested_width = width; requested_height = height; if (hpc->size_func) { (*hpc->size_func)(&requested_width, &requested_height, hpc->user_data); } if (requested_width > 0 && requested_height > 0 && (width != requested_width || height != requested_height)) { struct heif_image* resized; heif_image_scale_image(img, &resized, requested_width, requested_height, NULL); heif_image_release(img); width = requested_width; height = requested_height; img = resized; } data = heif_image_get_plane_readonly(img, heif_channel_interleaved, &stride); pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, has_alpha, 8, width, height, stride, release_heif_image, img); size_t profile_size = heif_image_handle_get_raw_color_profile_size(hdl); if(profile_size) { guchar *profile_data = (guchar *)g_malloc0(profile_size); err = heif_image_handle_get_raw_color_profile(hdl, profile_data); if (err.code == heif_error_Ok) { gchar *profile_base64 = g_base64_encode(profile_data, profile_size); gdk_pixbuf_set_option(pixbuf, "icc-profile", profile_base64); g_free(profile_base64); } else { // Having no ICC profile is perfectly fine. Do not show any warning because of that. } g_free(profile_data); } if (hpc->prepare_func) { (*hpc->prepare_func)(pixbuf, NULL, hpc->user_data); } if (hpc->update_func != NULL) { (*hpc->update_func)(pixbuf, 0, 0, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), hpc->user_data); } g_clear_object(&pixbuf); result = TRUE; cleanup: if (img) { // Do not free the image here when we pass it to gdk-pixbuf, as its memory will still be used by gdk-pixbuf. if (!result) { heif_image_release(img); } } if (hdl) { heif_image_handle_release(hdl); } if (hc) { heif_context_free(hc); } g_byte_array_free(hpc->data, TRUE); g_free(hpc); heif_deinit(); return result; } static gboolean load_increment(gpointer context, const guchar* buf, guint size, GError** error) { HeifPixbufCtx* ctx = (HeifPixbufCtx*) context; g_byte_array_append(ctx->data, buf, size); return TRUE; } void fill_vtable(GdkPixbufModule* module) { module->begin_load = begin_load; module->stop_load = stop_load; module->load_increment = load_increment; } void fill_info(GdkPixbufFormat* info) { static GdkPixbufModulePattern signature[] = { {" ftyp", "xxxx ", 100}, {NULL, NULL, 0} }; static gchar* mime_types[] = { "image/heif", "image/heic", "image/avif", NULL }; static gchar* extensions[] = { "heif", "heic", "avif", NULL }; info->name = "heif/avif"; info->signature = signature; info->domain = "pixbufloader-heif"; info->description = "HEIF/AVIF Image"; info->mime_types = mime_types; info->extensions = extensions; info->flags = GDK_PIXBUF_FORMAT_THREADSAFE; info->disabled = FALSE; info->license = "LGPL3"; } libheif-1.17.6/post.js000664 001750 001750 00000011362 14540541202 015633 0ustar00farindkfarindk000000 000000 function StringToArrayBuffer(str) { var buf = new ArrayBuffer(str.length); var bufView = new Uint8Array(buf); for (var i=0, strLen=str.length; i * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include #include #include "libheif/bitstream.h" #include "libheif/color-conversion/colorconversion.h" #include "libheif/pixelimage.h" static bool is_valid_chroma(uint8_t chroma) { switch (chroma) { case heif_chroma_monochrome: case heif_chroma_420: case heif_chroma_422: case heif_chroma_444: case heif_chroma_interleaved_RGB: case heif_chroma_interleaved_RGBA: case heif_chroma_interleaved_RRGGBB_BE: case heif_chroma_interleaved_RRGGBBAA_BE: case heif_chroma_interleaved_RRGGBB_LE: case heif_chroma_interleaved_RRGGBBAA_LE: return true; default: return false; } } static bool is_valid_colorspace(uint8_t colorspace) { switch (colorspace) { case heif_colorspace_YCbCr: case heif_colorspace_RGB: case heif_colorspace_monochrome: return true; default: return false; } } static bool read_plane(BitstreamRange* range, std::shared_ptr image, heif_channel channel, int width, int height, int bit_depth) { if (width <= 0 || height <= 0) { return false; } if (std::numeric_limits::max()/width/height == 0) { return false; } if (!range->prepare_read(static_cast(width) * height)) { return false; } if (!image->add_plane(channel, width, height, bit_depth)) { return false; } int stride; uint8_t* plane = image->get_plane(channel, &stride); assert(stride >= width); auto stream = range->get_istream(); for (int y = 0; y < height; y++, plane += stride) { assert(stream->read(plane, width)); } return true; } static bool read_plane_interleaved(BitstreamRange* range, std::shared_ptr image, heif_channel channel, int width, int height, int bit_depth, int comps) { if (width <= 0 || height <= 0) { return false; } if (std::numeric_limits::max()/width/height/comps == 0) { return false; } if (!range->prepare_read(static_cast(width) * height * comps)) { return false; } if (!image->add_plane(channel, width, height, bit_depth)) { return false; } int stride; uint8_t* plane = image->get_plane(channel, &stride); assert(stride >= width * comps); auto stream = range->get_istream(); for (int y = 0; y < height; y++, plane += stride) { assert(stream->read(plane, width * comps)); } return true; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { auto reader = std::make_shared(data, size, false); BitstreamRange range(reader, size); int width; int height; int bit_depth; bool alpha; uint8_t in_chroma; uint8_t in_colorspace; uint8_t out_chroma; uint8_t out_colorspace; if (!range.prepare_read(10)) { return 0; } width = range.read16(); height = range.read16(); bit_depth = range.read8(); alpha = range.read8() == 1; in_chroma = range.read8(); in_colorspace = range.read8(); out_chroma = range.read8(); out_colorspace = range.read8(); // Width / height must be a multiple of 2. if (width == 0 || height == 0 || (width & 1) != 0 || (height & 1) != 0) { return 0; } switch (bit_depth) { case 8: break; default: // TODO: Add support for more color depths. return 0; } if (!is_valid_chroma(in_chroma) || !is_valid_colorspace(in_colorspace) || !is_valid_chroma(out_chroma) || !is_valid_colorspace(out_colorspace)) { return 0; } auto in_image = std::make_shared(); in_image->create(width, height, static_cast(in_colorspace), static_cast(in_chroma)); switch (in_colorspace) { case heif_colorspace_YCbCr: switch (in_chroma) { case heif_chroma_420: if (!read_plane(&range, in_image, heif_channel_Y, width, height, bit_depth)) { return 0; } if (!read_plane(&range, in_image, heif_channel_Cb, width / 2, height / 2, bit_depth)) { return 0; } if (!read_plane(&range, in_image, heif_channel_Cr, width / 2, height / 2, bit_depth)) { return 0; } break; case heif_chroma_422: if (!read_plane(&range, in_image, heif_channel_Y, width, height, bit_depth)) { return 0; } if (!read_plane(&range, in_image, heif_channel_Cb, width / 2, height, bit_depth)) { return 0; } if (!read_plane(&range, in_image, heif_channel_Cr, width / 2, height, bit_depth)) { return 0; } break; case heif_chroma_444: if (!read_plane(&range, in_image, heif_channel_Y, width, height, bit_depth)) { return 0; } if (!read_plane(&range, in_image, heif_channel_Cb, width, height, bit_depth)) { return 0; } if (!read_plane(&range, in_image, heif_channel_Cr, width, height, bit_depth)) { return 0; } break; default: return 0; } break; case heif_colorspace_RGB: switch (in_chroma) { case heif_chroma_interleaved_RGB: if (!read_plane_interleaved(&range, in_image, heif_channel_interleaved, width, height, bit_depth, 3)) { return 0; } break; case heif_chroma_interleaved_RGBA: if (!read_plane_interleaved(&range, in_image, heif_channel_interleaved, width, height, bit_depth, 4)) { return 0; } alpha = false; // Already part of interleaved data. break; default: // TODO: Support other RGB chromas. return 0; } break; case heif_colorspace_monochrome: if (in_chroma != heif_chroma_monochrome) { return 0; } if (!read_plane(&range, in_image, heif_channel_Y, width, height, bit_depth)) { return 0; } break; default: assert(false); } if (alpha) { if (!read_plane(&range, in_image, heif_channel_Alpha, width, height, bit_depth)) { return 0; } } // TODO: also fuzz these parameters. int output_bpp = 0; // Same as input. heif_encoding_options* options = heif_encoding_options_alloc(); auto out_image = convert_colorspace(in_image, static_cast(out_colorspace), static_cast(out_chroma), nullptr, output_bpp, options->color_conversion_options); heif_encoding_options_free(options); if (!out_image) { // Conversion is not supported. return 0; } assert(out_image->get_width() == width); assert(out_image->get_height() == height); assert(out_image->get_chroma_format() == static_cast(out_chroma)); assert(out_image->get_colorspace() == static_cast(out_colorspace)); return 0; } libheif-1.17.6/fuzzing/data/000775 001750 001750 00000000000 14540541203 016713 5ustar00farindkfarindk000000 000000 libheif-1.17.6/fuzzing/data/corpus/000775 001750 001750 00000000000 14540541203 020226 5ustar00farindkfarindk000000 000000 libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5720856641142784.heic000664 001750 001750 00000011462 14540541202 033302 0ustar00farindkfarindk000000 000000 ftyp heicmeta "hdlr pict $ pitm 1=iinf                                                 infe 1 grid  iprp Sipco0 C    0 =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCp< @ !(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0``XaN*H$ׯ pI<@|W$BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rL…A@@8@`"$ HH.T&ׯ pIipma4      !"#$%&'()*+,-./112 idat @iloc3!i0L   !h "/ " #$%m&4&'()X**+,-J../1f1-1 2!3"1I#5$5e6&7x'8?(9)9*+,<"c-<.=/>w0?>12Bg3libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5651556035198976.heic000664 001750 001750 00000011462 14540541202 033315 0ustar00farindkfarindk000000 000000 ftyp heicmeta * "hdlr pict $  ȹpitm 1=iinf  infe  hvc1              @              )  + idat                   infe 1 grid  iref 10   !"#$%&'()*+,-./0thmb21cdsc31 iprp Sipco0clapproBg3XYZ   acspAPPLAPP4-appl%M8 descecprtd#wtptrXYZgXYZbXYZrTRC cHad,bTRC gTRC desc Display P3textCopyright Apple Inc., 217XYZ QXYZ 10  Jipco XYWIZ(8 ȹparaffd Y [sf32 B&nChvcCpZ   pZp$BpZX>(4@|Q0h4 `i!qXBu|VCtcaBE  V 0`DŽ`XaN*H$|t(_* X"L I@I`rЎ ₁p2X3 DIa 8 L\!^O_%& _'?^yiׯ pI(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8dfnip'!PA CtcaBE  V 0``XaN*H$ׯ pI<@|W$BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rL…A@@8@`"$ HH.T&௓ pIipma4      !"#$%&'()*+,-./112 idat @ilocD3i0L   !h "/ " #$%m<4,&'()X**+,-J../1f1-1 6&7x'8?(9)9*<"c-<.=/>w012Bg3mdat, c(,VG2  libheif-1.17.6/fuzzing/data/corpus/github_47.heic000664 001750 001750 00000000020 14540541202 022643 0ustar00farindkfarindk000000 000000  libheif-1.17.6/fuzzing/data/corpus/github_15.heic000664 001750 001750 00000000020 14540541202 022636 0ustar00farindkfarindk000000 000000  libheif-1.17.6/fuzzing/data/corpus/github_367_2.heic000664 001750 001750 00000011462 14540541202 023165 0ustar00farindkfarindk000000 000000 ftypheic heicmeta "hdlr pict $ pitm 1=iinf      *               ine,hvc1infe-hvc0inge.hvc1 fe/hvc1ine0hvc1infe1gridinfe2b6c1infe3Exifirefldimg20 6 !"#$%&'()*+,,/0thmB21cdsc31 iprp Sipco0$olrprof$applmnrRGB-XYZ   ac))))))))))1111111111;'appl%M8 1infehvc1ininfehvc0Xnfe gTRC dcwc Display P4CopyriApple Inc., 2017XYZ QXHZ =XYZ J7 YZ (8 ȹparaff Y {sf16 B&nChvcCpZ @ pZp$BpZX@>(4@|Q3h4 `i!qXBu|VCtcaBE  V 0XaN*H$|t8_% X"L I@I` Exception/C3 DIa-hvc L\!^_O%& _'?^rׯ pI ipma4     exif:ResolutionUe !"#k$%&6()*+,-..012 idat @ilocD3i0  !h "/ "$%m&8&'()X**+,-J../#5f1-1 1!3"4N#5$5%6&7x'8?(9)9=*:+0ZIinfe idenExifMM* exif:XResolution libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5752063708495872.heic000664 001750 001750 00000040005 14540541202 033305 0ustar00farindkfarindk000000 000000 ftypheicmiheicmeta"hdlrpict$dinfdref url pitm2=iinf3infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infe hvc1infe hvc1infe hvc1infe hvc1infe hvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infe hvc1infe!hvc1infe"hvc1infe#hvc1infe$hvc1infe%hvc1infe&hvc1infe'hvc1infe(hvc1infe)hvc1infe*hvc1infe+hvc1infe,hvc1infe-hvc1infe.hvc1infe/hvc1infe0hvc1infe1gridinfe2hvc1infe3Exifirefldimg10  !"#$%&'()*+,-./0thmb31cdsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZgXYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$BpZX>(4@|Q0h4 `i!qXBu|VCtcaBE  V 0`DŽ`XaN*H$|t(_* X"L I@I`rю ₁p2%X3 DIa 8 L\!^O_%& _'?^yׯ pI(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0`DŽ`XaN*H$ׯ pIipma2      !"#$%&'()*+,-./012 idat @ilocD3i0L  !h "/ " #$%m&4&'()X**+,-J../0f?-1 2!3"4I#5$5%6&7x'8?(9)9*:+;[,<"-<.=/>w0?>12Bg3mdat,c(,VGjbɓfrICC>~0ZI 4p%2ftypʀTnK  ExifMM*  (12iAppleiPhone XHH11.22018:04:08 09:55:10 FN"'0221Vj ~    |9249240100 Т2j34$ 2017:04:08 09:55:10:08 09:55:10 o*C= 2Apple iOSMM  .  a             bplist00O              bplist00UflagsUvalueYmescaleUepoch[*;'-/8= ?9g heim-q750n  AppleiPhone X back dual camera 4mm f/1.8( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|7*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j pitmeV( WZ4Gtbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh<| @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1GjIJbɓf("b>~0Zz?"j 4R,%2ʀ ( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gj!bɓf("b>~0Zz?"j 4R%2 (PTnK2P|8< @ * j eV( WZ1Gj!bɓf("b>~0Zz?"j 4R%2 (PTnK2P|8*D* Dh< @ * j eV( WZ2Gjbɓf("b>~0Zz?"j 1R%2ʀ (PTnK2P|8*D* Dh< @ * j eV%2ʀ (PTnK2P|8*D*4O'Xln=Dh젰 @ *jSkY( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ6Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j \{n\bYmP}?x@ _8( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK3P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * jipmaeV( WZ0Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( bXYZrTRC ɣʡ2>~0Zz`(ޤ 4I%2-Kʀ(TnsK\@lP| `8'`"*DnDhD @9 *+"  bplist00O        K2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * hvc2 eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀѦ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R'2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|D8** Dh< auxC@ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P+|8*D* Dh< @ * j eV( WZGjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ *q֑߬o=@ @N( WZ1Gjbɓ?("b>~0Zz?"j 3R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ0Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * jeV( WZ1Gjbɓb>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ0Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|1*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gj!bɓf("b>~0Zz?"j 4R%2 (PTnK2P|8< @ * j eV( WZ1Gj!bɓf("b>~0Zz?"j 4R%2 (PTnK2P|8*D* Dh< @ * j eV( WZ2Gjbɓf("b>~0Zz?"j 1R%2ʀ (PTnK2P|8*D* Dh< @ * j eVK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ0Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * jeV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ0Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|1*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gj!bɓf("b>~0Zz?"j 4R%2 (PTnK2P|8< @ * j eV( WZ1Gj!bɓf("b>~0Zz?"j 4R%2 (PTnK2P|8*D* Dh< @ * j eV( WZ2Gjbɓf("b>~0Zz?"j 1R%2ʀ (PTnK2P|8*D* Dh< @ * j eVlibheif-1.17.6/fuzzing/data/corpus/github_138.heic000664 001750 001750 00000011462 14540541202 022740 0ustar00farindkfarindk000000 000000 ftypheicmif1heicmeta "hdlr pict $ pitm 1=iinf                                            (      infe 1 grid  iprp Sipco0 C    0 =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCp< @ !(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0``XaN*H$ׯ pI<@|W$BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rL…A@@8@`"$ HH.T&ׯ pIipma4      !"#$%&'()*+,-./112 idat @iloc3!i0L   !h "/ " #$%m&4&'()X**+,-J../1f1-1 2!3"1I#5$5e6&7x'8?(9)9*+,<"c-<.=/>w0?>12Bg3libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5120279175102464.heic000664 001750 001750 00000001461 14540541202 033262 0ustar00farindkfarindk000000 000000 ftyp mif1 %meta ! pitm 4iloc D@ E   8iinf infe  hvc1infe  hvc1diprpAipcouhvcC  @ (B   dI Dhe#c ' u  ipma  C   libheif-1.17.6/fuzzing/data/corpus/github_20.heic000664 001750 001750 00000060447 14540541202 022655 0ustar00farindkfarindk000000 000000 meta iprp  meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta iprp meta meta meta ipco meta ipco meta ipco meta meta ipco meta ipco meta ipco meta ipco meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Gipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~dmetaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&metaLipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&metapcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&ipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipco@d&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&ipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~d&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~dmetaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&metaLipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&ipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipco@d&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipcod&meta~Lipcod&meta~LipcoD&meta~Lipcod&meta~Lipcod&meta~Lipcod&meta~d&metaGipcod&meta~Lipcod&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&meta~Lipc`d&meta~Lipcod&meta~Lipca~d&metaGipcod&meta~&meta~Lipcod&meta~cod&meta~Lipcod&meta~Lipcod&meta~Lipco d&metameta~oD&metailibheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5662360964956160.heic000664 001750 001750 00000001075 14540541202 033305 0ustar00farindkfarindk000000 000000 ftyp heic%meta !hdlr pict pitm 4iloc  8iinf infe  hvc1infe  hvc1diprpAipcou  'auxC urn:mpeg:hevc:2015:auxid:1u  ipma   iref auxl libheif-1.17.6/fuzzing/data/corpus/github_367_1.heic000664 001750 001750 00000011462 14540541202 023164 0ustar00farindkfarindk000000 000000 ftypheicmif1heicmeta "hdlrpict$dinfdref@ url:pitm1=iinf3i~fe1inf~{vc1infmhvc1inhvc1inehvc1*ifehvc1infehvc1irfehvc1Qnd hvc1Tnfe hvc1in@e hvc1hnfe hvc1nf} hvc3inFehvc1infehvc1infehvc1infehvc1hvc1infhvc1infehvc1infehvc1Xnfevc1infehvc1Xnfehvc1in&e"hvc0fe hvc"wnfehvc(fehv1snfe]htW1infN|vc1nfehvc1infs hvc1inf!hvc1ife"hvc1infe#hvc1infe$hv@infe%hvc1infeh Snfe'hrZ1infe(hvc1ijfeHEIChvc1infe*hvc1infe+hsinfe,hvc1infe-hvc1inge.hvc1fe/hvc1inH0hvc1infe1gridinfe2hvc1infe3Exifirefldimg10 6 !"#$Y%&'()*+,,/0thmB21cdsc31 iprp Sipco0colrprof$applmntrRGB-XYZ   ac))))))))))11111111111-appl%M8date:moinfehvc1 idginfehvc2Xnfe gTR1 dcsc Display P2 CopyriApple Inc., 2017XYZ QXHZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcpZ @ pZp$BpZX>(@|Q3h4 `i!qXBu|VCtcaBE  V 0XaN*H$|t8_% X"L @I` Exception/C3 DIa-hvc L\!^_O%& _'?^rׯ pIipma4     exif:ResolutionUe !"#k$%&7()*+,-..012x idat @ilocD3i0 L  !h "/ " #($%m&4&'()X**+,-J../0f?-1 11"I4# 6$5%4&7x'8?9)9*:+;[,<"-<.=*@>w0?>1Bg3xda libheif-1.17.6/fuzzing/data/corpus/github_45.heic000664 001750 001750 00000015773 14540541202 022666 0ustar00farindkfarindk000000 000000 ftyp heicmeta "hdlr pict $ pitm 1=iinf  infe  hvc1                                              infe 1 grid  iref 10   !"#$%&'()*+,-./0thmb21cdsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZgXYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 217XYZ QXYZ =XYZ J XYWIZ(8 ȹparaffd Y [sf32 B&nChvcCpZ @ pZp$BpZX>(4@|Q0h4 `i!qXBu|VCtcaBE  V 0`DŽ`XaN*H$|t(_* X"L I@I`rЎ ₁p2X3 DIa 8 L\!^O_%& _'?^yׯ pI(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0``XaN*H$ׯ pI<@|W$BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rL…A@@8@`"$ HH.T&ׯ pIipma4      !"#$%&'()*+,-./112 idat @ilocD3i0L   !h "/ " #$%m&4&'()X**+,-J../1f1-1 2!3"4I#5$5e6&7x'8?(9)9*+,<"c-<.=/>w0?>12Bg3mdat,c(,VG2jbɓf(%B>~0ZI 4p%2ʀTnK  ExifMM*  (02iAppleiXhone XHH11.3201exif:ExposureBiasValFN"'0221Vj ~  $ispeispe irotpixi0colrprof$applGB XYX   acspAPPLAPPL-appl%M9 descecprtd#wtptrXYZgXYZbXYZrTRC chad,bTRC gtextCopyright Apple Inc., 2017XYZ QXYZ =XYZ J7 XYZ (8 ȹpara        bplist00O              bplist00UflagsUvalueYtimescaleUepoch[*;'-/8= ?9g -q750n  AppleiPhone X back dual camera 4mm f/1.8( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1@GjbɓʀK2P|8*Db>~0Zz?"j 4R%2ʀ (PTnD* Dh< @ * j eVlibheif-1.17.6/fuzzing/data/corpus/github_44.heic000664 001750 001750 00000011467 14540541202 022661 0ustar00farindkfarindk000000 000000 ftyp heicmeta "hdlr pict $ pitm 1=iinf                                                 e0jvc1infe1gridinfe2hvc1infe3Exifirefldimg10  !"#$%&'()*+,-./0thmb21cdsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZgXYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$BpZX>(4@|Q0h4 `i!qXBu|VCtcaBE  V 0`DŽ`XaN*H$|t(_* X"L I@I`rЎ ₁p2%X3 DIa 8 L\!^O_%& _'?^yׯ pI(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0`DŽ`XaN*H$ׯ pI<@|W$BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rL…A@@8@`"$ HH.T&ׯ pIipma4      !"#$%&'()*+,-./112 idat @ilocD3i0L   !h "/ " #$%m&4&'()X**+,-J../0f1-1 2!3"4I#5$5%6&7x'8?(9)9*+;[,<"-<.=/>w0?>12Bg3mdatlibheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-6045213633282048.heic000664 001750 001750 00000035224 14540541202 033267 0ustar00farindkfarindk000000 000000 ftypheicmif1heicmeta"hdlrpict$d$nfdref url pitm1=iinf3i~fe1inf~{vc1infmhvc1inhvc1inehvc1*ifehvc1infehvM1irfyhv1Qnd hvc1Tnfe hvc0in@e hvc1hnfe hvc1nf} hvc1inFehvc1infehvc1infehvc1infehvc1hvc1infehvc1infeJ7 XYZ hvc1ifehvc1infehvc1infehvc1infehvc0infe0hvc1infehvc1HEIChvc1infec5infehvc1infe:hvcinfe hvc1infe!hvc2infe"hv1infe#xvc1Tnfe$hvc1infe%hwc1[nfe&hvc1info'hvc1infe@(hvc1infe)hvc1fe!*hvc1inf +hvc1infa,hvc1infe(hvc1ine.hvc1ie/h1InfeJ0hvc1infe1gridinfe2iprpvlinfe3Exififrelidgm10 j !"#$%&'()*+,-svg:0thmb"1cdsc31 iprp Sipco0coOrprof$applmitrRGB XYZ   acsPpAPLAPPL-ap l%M4 desecprtd#wtptrXYZgXYZObXYZrTRC chad,bTRC gTRC desc Display P3textyoroCight Apple Inc., 2/1CXY; QXYZ =XYZ J7 XYZ (8 ȹpar2ff Y [sf16 B&nChvcCpZ @ pZp$BpZX>(3@|Q0h4 `i!qXBu|VdCtcaBE V 0`DŽ+`XaN*H$|t(_* X"L I@I~rю ₁p2%X3 DIa 8 L\!^O_%& M_'yׯ pI(4@|VCⰄB' P((z"U #1D@8@`"$ HTH&.t(_* X"L I@Io3…A@@5@`$a HTH1ׯ pIipma2      !"#$%&'()*+,-./112 idat @ilocD3i01L !h "/ " #!$%m&4&'()X**,-J../0f1-1 2!3"4I#5$5%6&7x'8?(9)9*:+;[,<"-<.=/>w0?>12Bg3mdat#,c(,VGjbɓf(%BZI 4p%2ѫTnV  ExifMM* (__________T______________0fim_________________________________________________________________________________________________________________________________pPiCenUdef_____________________________________________________________________________________________@`$a HTH1ׯ pIipma2      !"#$%&'()*+,-+,-./012 ida@ilocD3i0LA  !h "/ "%m&4&'()X**,ot ipc../@ftypheicmif1heicmeta"hdlrpict$dinfdref url pitm1=iinf3i~fe1inQ~{vc1infmhvc1inhvc1inehvc1*ifeinfehvc1Xnvehvc1in&t"hvc0fe hvc"wnfehvc(fehv1snfe]htW1infNnfehvc1infs hvc1infhvc1ife"hvc1infe#h1infe$hvinf%hvc1infeinfe1Snfe'hvZ1infeL/Rifrelidgm10Wheicinfe2iovlinfe3Exififrelidgm10 CB\i|adifnt$&i3fWWWExif @ Wheicinfe2iovlinfe3Exififrelidgm10 CB\i|adifnt$&i3fWWWExif @ ifrelidgm10 CB\i|adifnt$&i3fWWWExif @ 0Fcc0,0'pR$˄?#m3 dJf<$<Rp'!PA C^O_%& ׯ pI(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0`DŽ`XaN*H$ׯ pI<@2BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rJ…A@@8@`"$ HH.T&ׯ pIipma4      !"#$%&'()*+,-./112 idat @ilocD3i0L   !ho "/ " #$%m&4&'()X**+,-J../0f1-1 2!3"4I#5$5%6&7x'8?(9)9*+;[,<"-<.=/>w0?>12Bg3mdatʀTn~K  ExifMM*  (02iAppleiPho XHH11.3201exif:ExposureBiasValFN"f$aYX   acspAPPLAPPL-appl%M9TRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZ QXYZ =XYZ J4 XYZ (8 ȹparaff Yftyp heicmeta "hdlr pict $ pitm 1=iinf          vc0infe1gridinfe2hvc1infe3Exifirefldimg10  !"#$%&',-./0thmb 2c1dsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 vc1infe1gridinfe2hvc1infe3Exifirefldimg10  !"#$%&',-./0thmb 2c1dsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZ{XYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$B0?>ǀ eV( WZGjbɓb>~ʀ (P;2 Dh< @pZp$Bplibheif-1.17.6/fuzzing/data/corpus/region-mask-missing-refs.heic000664 001750 001750 00000002327 14540541202 025703 0ustar00farindkfarindk000000 000000 ftypheic heicmeta ! pitm Xiloc D@     biinf infe  iovlinfe  rgan  iprpzipcou  ' u  u  ' u  &ipma     6iref mask  libheif-1.17.6/fuzzing/data/corpus/github_48.heic000664 001750 001750 00000016276 14540541202 022670 0ustar00farindkfarindk000000 000000 ftyp heicmeta "hdlr pict $ pitm 1=iinf   infe  iovl                                             vc1infe1gridinfe2hvc1infe3Exifirefldimg10  !"#$%&',-./0thmb 2c1dsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZ{XYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$BpZX>(4@|Q0h4 `i!qXBu|VCtcaBE  V 0`DŽ`XaN*H$|t(_* X"L I@I`rЎ ₁p2%X3 DIa 8 L\!^O_%& _'?^yޯ pI(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0`DŽ`XaN*H$ׯ pI<@|W$BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rJ…A@@8@`"$ HH.T&ׯ pIipma4      !"#$%&'()*+,-./112 idat @ilocD3i0L   !ho "/ " #$%m&4&'()X**+,-J../0f1-1 2!3"4I#5$5%6&7x'8?(9)9*+;[,<"-<.=/>w0?>12Bg3mdatʀTnK  ExifMM*  (02iAppleiPho XHH11.3201exif:ExposureBiasValFN"f$aYX   acspAPPLAPPL-appl%M9TRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCp< @ p(4@|VCⰄB' g((z"U #1       bplist00O                bplist00UflagsUvalueYtimescaleUepoch[*;'-/8=??9g -q750n  AppleiPhone X back dual camera 4mm f/1.8( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTn./0f1-1 2!3"4I#5$6&7x'8?(9)9*+;[,<"-<=/>w0?>ǀ eV( WZ1Gjbɓf("b>~ʀ (P;K2 Dh< @pZp$Bplibheif-1.17.6/fuzzing/data/corpus/uaf_heif_context.h_117_1.heic000664 001750 001750 00000001110 14540541202 025420 0ustar00farindkfarindk000000 000000 ftypmif1heicmif1meta!hdlrpictpitm4ilocD@77 Liinfinfehvc1HEVC Imageinfehvc1HEVC ImageirefauxlwJiprp'ipcolhvcC`x@ `x$B`x-$m٢DispexhvcC`x@ `x@+B`x-Yة$!Dwى'auxCurn:mpeg:hevc:2015:auxid:1ipmaddatYG$libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5686319331672064.heic000664 001750 001750 00000001753 14540541202 033304 0ustar00farindkfarindk000000 000000 ftyp heicmeta !hdlr pict pitm Xiloc @ biinf infe  hvc1 infe  hvc1infe  hvc1iprpzipcou  ' u  u  'auxC urn:mpeg:hevc:2015:auxid:1u  &ipma     6iref  auxl thmb libheif-1.17.6/fuzzing/data/corpus/github_49.heic000664 001750 001750 00000000020 14540541202 022645 0ustar00farindkfarindk000000 000000  libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5671864958976000.heic000664 001750 001750 00000000763 14540541202 033317 0ustar00farindkfarindk000000 000000 ftypheicmif2heic.meta!hdlrpict@pitm"ilocD@N#iinfinfehvc1iprpipcouhvcCp  p@!(Bp I)liloc@"Dr"@ispe@@ipmamdat$=1metafehvc1iprpip`i+lxmdta&b4heic.miinfew_*nf0w_libheif-1.17.6/fuzzing/data/corpus/colors-with-alpha-thumbnail.heic000664 001750 001750 00000004014 14540541202 026374 0ustar00farindkfarindk000000 000000 ftypheicmif1heicmeta!hdlrpictpitmXilocD@yPbiinfinfehvc1infehvc1infehvc1infehvc1iprpzipcouhvcCp @ p@!(Bp$%I)l@"Dr"@ispeHH'auxCurn:mpeg:hevc:2015:auxid:1uhvcCp @ p@!(Bp$%I)l@"Dr"@ispeHHuhvcCp @ p@!(Bp I)l@"Dr"@ispe@@'auxCurn:mpeg:hevc:2015:auxid:1uhvcCp @ p@!(Bp I)l@"Dr"@ispe@@&ipma 6irefauxlauxlthmb!mdat&Vxpdڮa:b꫍y9g ^%*"ISL)7}0\]/h~!kXr /bR箨cPߒhh$ ͩy, ]Mwwo>tZ_5BYbɜ, ! 1*LW,29?zV3(I`*#CwyD9&4L{#u&|ө'[Hٖ{6`PxtlKVJHѪ#Si5V»[֗뎗҅ľ3{@A8.zwPIčlX&q, P>3KiQ2OۚVUٗ% AwQ]g+E "Y 85t)7Z(V ln[v1J4}naҤֻ~u<DpA/1Q4aAY@Gej-ۊٵFZonbqzpPWp%|fZn?&|6zm ߃bpBӭK&ScX>c$3̄!jơ4l`w+ݴ(RII UvY9IA_iO3>W0^JW.ZFoz>MjWp%;GNop)n 'M8 (ơԍZc e@H&swy%M%7vg7g3b-&Slibheif-1.17.6/fuzzing/data/corpus/colors-no-alpha.heic000664 001750 001750 00000000763 14540541202 024063 0ustar00farindkfarindk000000 000000 ftypheicmif1heic.meta!hdlrpictpitm"ilocD@N#iinfinfehvc1iprpipcouhvcCp @ p@!(Bp I)l@"Dr"@ispe@@ipmamdat&uͬ|rAb9[@us`i+l$\g o;/M˞%V2LUqÆU{T}sE ))dMXXNzpSe,ӽ1t 3r؍[75w_libheif-1.17.6/fuzzing/data/corpus/colors-no-alpha-thumbnail.heic000664 001750 001750 00000002077 14540541202 026044 0ustar00farindkfarindk000000 000000 ftypheicmif1heicmeta!hdlrpictpitm4ilocD@;X8iinfinfehvc1infehvc1,⓺ͻP̟*=Gb͇ VN13P\Ƒ4ܝdܲ*P$ARv}gwPO!^J&|Z&)/84QVpɇq=r"ܩuYo ɵNVL5W sfJ3{ BrcŲR q3gOkwRvfݥlVbP.dz;'⏷>7:ϼ-~7kX1ƒL^wK)tIams^ yj"\<6|Z"=F2O'glibheif-1.17.6/fuzzing/data/corpus/hbo_heif_context.h_126_1.heic000664 001750 001750 00000001110 14540541202 025415 0ustar00farindkfarindk000000 000000 ftypmif1heicmif1meta!hdlrpictpitm4ilocD@77 Liinfinfe hvc1HEVC Imageinfehvc1HEVC ImageirefauxlJiprp'ipcolhvcC`x@ `x$B`x-$m٢DispexhvcC`x@ `x@+B`x-Yة$!Dwى'auxCurn:mpeg:hevc:2015:auxid:2ipmamdatYG$libheif-1.17.6/fuzzing/data/corpus/j2k-siz-segment-undersized.heic000664 001750 001750 00000003120 14540541202 026156 0ustar00farindkfarindk000000 000000 ftypheic heicmeta ! pitm Xiloc D@   y  biinf infe  j2k1   iprpzipcou  ' u  u  ' u  &ipma     6 p fuzzing/data/corpus/clusterfuzz-testcase-minimized-color-conversion-fuzzer-6275694804467712000664 001750 001750 00000014734 14540541202 034713 0ustar00farindkfarindk000000 000000 libheif-1.17.6(B,!C Y . ]  . ]  . ] d]  . ]  . ] 2+Y . ]  . ]  . ] . ] ]  . ] 2+ . ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] 2+Y . ]  . ]  . ]  . ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] 2+Y . ]  . ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] . ] ]  . ] 2+ . ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] ]  . ] 2+Y .] 2+Y . ]  . ]  . ] 2+Y . ]  . ]  . ]  ]  . ]  . ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] 2+Y . ]  . ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] 2+Y . ]  . ]  . ]  . ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] ]  . ] 2+Y . ] 2+Y . ]  . ]  . ] 2+Y . ]  . ]  . ] 2+Y . ]  . ]  . ] libheif-1.17.6/fuzzing/data/corpus/clap-overflow-divide-zero.heic000664 001750 001750 00000011462 14540541202 026062 0ustar00farindkfarindk000000 000000 ftypheic heicmeta "hdlr pict $ pitm 1=iinf      *     -9 |;            ine,hvc3866556109892352999vc0inge.hvc1 fe/hvc1ine0hvc1infe1gridinfe1infe3Exifirefc1021 iprp Sipco0$olrprof$applmnrRGB-XYZ   ac))))))))))1111111111;'appl%M8 1infehvc1ininfehvc0Xnfe gTRC dcwc Display P4CopyriApple Inc., 9069XYZ QXHZ =XYZ J7 YZ (8 ȹparaff Y {sf16 B&nChvcCpZ @ pZp$BpZX@>(4@|Q3h4 `i!qXBu|VCtcaBE  V 0XaN*H$|t8_% X"L I@I` Exception/C3 DIa-hvc L\!^_O%& _'?^r @:f< 8p'!PA C^O_%& ׯ pIipma4     |exif:ResolutionUe !"#k$%&6()*+,-..012 ydat @ilocD3i0?"fbNSM |`-7 vlbӞ^$e SX97<2 #l7RwN#OJhC9 ,)#v&@'Iz1K2}nSнkT: χOPUBpF&ɩz>A-ick voB>_lrlmNLE{KH]s ) 9/?Q#)^ږ 0lCqՈTrߘI͌%% rʱ=K9X,#~֬$C]s*NFe F9ɫlibheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-4616081830051840.heic000664 001750 001750 00000036660 14540541202 033272 0ustar00farindkfarindk000000 000000 ftyp mif1 meta " $ pitm =iinf                                infe hvc1       'profinfe@(hvc1infe)hvc1infe(*hvc1infe +hvc1infa,hvc1infe-hvc1iovl.hvc1inavis/h1Infe0hvc1infe1gridinfe2iovlinfe3Exifirefldimg10  !"#$%&'()*+,-./thmbclap1cdsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZ-gXYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZ QXY=XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$BpZX>(4@|Q0h48 `i!qXBu|VCtcaBE  V imir`XaN*H$|t(_* X"L I@I`rю ₁p2%X3 DIa 8 L\!^O_%& _'?^yׯ pI4|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0`DŽ`XaN*H$ׯ pIipma2      !"#$%&'()*+,-./112 idat @ilocD3i0L  !h "/ " #$%m&4&'()X**+,-J..1/0f1-1 2!3"4I#5$5%6&7x'8?(9)9*:+;[,<"-<.=/>w0?>12Bg3mdat,c(,VGjbɓf(%B>~0ZI 4p%2ʀTnK  ExifMM*  (12H11.32018:04:08 09:55:10 FN"'0221Vpple Inc., 2017XYZ QXYZ c HTH&.ׯ pIipma1     9 !"#$%&'()*+,-./113 idat @ilocD3i1L  !h "/ " #$%m&4&'()X**+,iauauuuidxC '0221Vj ~  #1D@8) #3 /A7XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf44 B&cf< qavifpicthv0Apitm4ilocD@EAipcouhvcCpnfinfe\gridinfep@!(msf2p@"infer"@isxecoriloc?auauuuidxChevc HTH&.ׯ pIipma1     9 !"#$%&'()*+,-./113 idat @ilocD3i1L  !h "/ " #$%m&4&'()X *+,iauauuuidxC 0iinfauauuuidxC '0221Vj ~  #1D@8) #3 /A7XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf44 B&heimuauuuidxC 0iinfpitm4ilocD@EAipcouhvcCpnfin'0221Vj ~  #1D@8) #3 /A7XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf44 B&cf< qavifpicthv0Apitm4ilocD@EAipcouhvcCpnfinfe\gridinfep@!(msfinfer"@isxecoriloc?iauauuuidxChevc HTH&.ׯ pIipma1    9 !"#$%&'()*+,-./1L  !h "/ " #$%m&4&'()X**+,iauauuuidxC 0iinf 0iinf,iauauuuidxC '0221Vj ~  #1D@8) #3 /A7XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf44 B&auauuuidxC '0221Vj ~  #1D@8) #3 /A7XYZ QXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf44 B&heisuauuuidxC 0iinfpitm4ilocD@EAipcouhvcCpnfinfe\gridinfep@!(msf2p@"infer"@isxecoriloc?iauauuuidxChevc HTH&.ׯ pIipma1    9 !"#$%&'()*+,-./113 idat @ilocD3i1L  !h "/ " #$%m&4&'()X**+,iauauuuidxC 0iinf 0iinfiinfpitm4ilocD@EAipcouhvcCpnfinfe\gridinfep@!(msf2p@"infer"@isxecoriloc?iauauuuidxChevc HTH&.ׯ pIipma1    9 !"#$%&'()*+,-./1L  !h "/ " #$%m&4&'()X**+,iauauuuidxC 0iinf 0iinf9 !"#$&'()*+,-./113 idat @ilocD3i1L  !h "/ " #$%m&4&'()X**+,iauauuuidxC 0iinf 0iinfiinfpitm4ilocD@EAipcouhvcCpnfinfe\gridinfep@!(msf2p@"infer"@isxecoriloc?iauauuuidxChevc HTH&.ׯ pIipma1    9 !"#$%&'()*+,-./1L  !h "/ " #$%m&4&'()X**+,iauauuuidxC 0iinf 0iinflibheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5643900194127872.heic000664 001750 001750 00000002167 14540541202 033302 0ustar00farindkfarindk000000 000000 ftypirfeif,heic.meta~!hdlrDpgopict%spitm`"ilocD@HN#iinf}infe,hvc1iprpipcouhvcCrÁidatmjqmeta$ @ ,aC(BT $LJI*m_@@"Dz"@ivc0$ipma iQatmdat$pmdat&,heic.meta~!hdlrDpgopict%spitm`"ilocD@HN#iinf}infe,hvc1iprpipcouhvcCrÁidatmjqmeta$ @ ,aC(BT $LJI*m_@@"Dz"@ivc0$ipma iQatmdat$pmdat&=]ispecofipmhvcC ai2ArauxCBYkh,md1=]ispecofipmhvcC ai2ArauxCBYkh,md1'libheif-1.17.6/fuzzing/data/corpus/colors-with-alpha.heic000664 001750 001750 00000001461 14540541202 024416 0ustar00farindkfarindk000000 000000 ftypheicmif1heic%meta!hdlrpictpitm4ilocD@EG8iinfinfehvc1infehvc1diprpAipcouhvcCp @ p@!(Bp I)l@"Dr"@ispe@@'auxCurn:mpeg:hevc:2015:auxid:1uhvcCp @ p@!(Bp I)l@"Dr"@ispe@@ipmairefauxlmdatC& k8S}̆v$1"i˱"sZ6*w׮Ĺq0cMS&uͬ|rAb9[@us`i+l$\g o;/M˞%V2LUqÆU{T}sE ))dMXXNzpSe,ӽ1t 3r؍[75w_libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5757633845264384.heic000664 001750 001750 00000001505 14540541202 033311 0ustar00farindkfarindk000000 000000 ftyp heic%meta !hdlr pict pitm 4iloc D@ E  8iinf infe  hvc1infe  hvc1diprpAipcouhvcC   (B   I D"  ' uhvcC   (   ipma  C   libheif-1.17.6/fuzzing/data/corpus/github_46_1.heic000664 001750 001750 00000011527 14540541202 023100 0ustar00farindkfarindk000000 000000 ftypheicmif1heicmeta"hdlrpict$dindref url pitm2=iinf3infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infe hvc1infe!hvc1anfe"hvc1infeh#vc1infe$hvc1infe%hvc1infe&hvc1infe'hvc1infe(hvc1infe)hvc1infe*hvc1infe+hvc1infe,hvc1infe-hvc1infe.hvc1infe/hvc1infe0hvc1infe1gridinfe2hvc1inoe3Exifirefldimg10  !"#$%&'()*+,-./0thmb21cdsc31 iprp Sipco0colrprof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZgXYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZfQXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$BpZX>(4@|Q0h4 `i!qXBu|VCtcaBE  V `DŽ`XaN*H$|t(_* X"L I@I`rю ₁p4%X3 DIa 8 L\!^O_%& _'?^yׯ pI(6@|VCⰄB' P((z"U #1>@8) #3 /AdJf< 8p'!PA CtcaBE  V 0`DŽ`XaN*H$ׯ pIipma2      !"#HEI$%&'()*+,-./012 idat @ilocD3i0L  !h "/ " #$%m&4&'()X**+,-J../0f1--appl%M8 descecprtd#wtptrXYZgXYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 2017XYZfQXYZ =XYZ J7 XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$BpZilibheif-1.17.6/fuzzing/data/corpus/github_50.heic000664 001750 001750 00000015767 14540541202 022665 0ustar00farindkfarindk000000 000000 ftyp heicmeta "hdlr pict $ pitm 1=iinf  infe  iovl                  hvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infehvc1infe hvc1infe!hvc1infe"hvc1infe#hvc1infe$hvc1infe%hvc1infe&hvc1infe'hvc1infe(hvc1infe)hvc1infe*hvc1infe+hvc1infe,hvc1infe-hvc1infe.hvc1infe/hvc1infe0jvc1infe1gridinfe2hvc1infe3Exifirefldimg10  !"#$%&'()*+,-./0thmb21cdsc31 iprp Sipco0prof$applmntrRGB XYZ   acspAPPLAPPL-appl%M8 descecprtd#wtptrXYZgXYZbXYZrTRC chad,bTRC gTRC desc Display P3textCopyright Apple Inc., 217XYZ QXYZ =XYZ J XYZ (8 ȹparaff Y [sf32 B&nChvcCpZ @ pZp$BpZX>(4@|Q0h4 `i!qXBu|VCtcaBE  V 0`DŽ`XaN*H$|t(_* X"L I@I`rЎ ₁p2X3 DIa 8 L\!^O_%& _'?^yׯ pI(4@|VCⰄB' P((z"U #1D@8) #3 /AdJf< 8p'!PA CtcaBE  V 0`DŽ`XaN*H$ׯ pI<@|W$BG+\`!L…A@@8@`"$ HTH&.t(_* X"L I@I`rL…A@@8@`"$ HH.T&ׯ pIipma4      !"#$%&'()*+,-./112 idat @ilocD3i0L   !h "/ " #$%m&4&'()X**+,-J../0f1-1 2!3"4I#5$5%6&7x'8?(9)9*]+;[,<"-<.=/>w0?>12Bg3mdat,c(,VG2jbɓf(%B>~0ZI 4p%2ʀTnK  ExifMM*  (02]iAppleiPhone XHH11.3201exif:ExposureBiasValFN"'0221Vj ~  $ispeispe irotpixi0colrprof$applGB XYX   acspAPPLAPPL-appl%M9d escecprtd#wtptrXYZgXYZtextCopyright Apple Inc., 2017XYZ QXYZ =XYZ J7 XYZ (8 ȹpara        bplist00O            8*D* Dh< @ * j eV( WZ("b>~0Zz?"j 4%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?"j 4R%2ʀ (PTnK2P|8*D* Dh< @ * j eV( WZ1Gjbɓf("b>~0Zz?4libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5724458239655936.heic000664 001750 001750 00000000763 14540541202 033321 0ustar00farindkfarindk000000 000000 ftyp heic.meta !hdlr pict pitm "iloc D@ N#iinf infe  hvc1iprpipcouhvcC   (B   imir Dr"  ipma  & u ͬ!| r Ab5[ s `i u\ a oNpSe,ӽ t 3r{ u d}s . e i libheif-1.17.6/fuzzing/data/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5718632116518912.heic000664 001750 001750 00000000763 14540541202 033300 0ustar00farindkfarindk000000 000000 ftyp heic.meta !hdlr pict pitm "iloc D@ N#iinf infe  hvc1iprpipcouhvcC   (B   & ꮖ D"  ipma   libheif-1.17.6/fuzzing/data/corpus/github_46_2.heic000664 001750 001750 00000001020 14540541202 023064 0ustar00farindkfarindk000000 000000 iprpiprp libheif-1.17.6/fuzzing/data/dictionary.txt000664 001750 001750 00000000520 14540541202 021615 0ustar00farindkfarindk000000 000000 "auxC" "auxl" "av1C" "avif" "cdsc" "clap" "colr" "dimg" "dinf" "dref" "ftyp" "grpl" "hdlr" "heic" "heix" "hevc" "hevx" "heim" "heis" "hevm" "hevs" "hvcC" "idat" "iinf" "iloc" "imir" "infe" "ipco" "ipma" "iprp" "iref" "irot" "ispe" "mdat" "meta" "mif1" "mime" "msf1" "nclx" "pict" "pitm" "pixi" "prof" "rICC" "thmb" "uri " "url " "uuid" libheif-1.17.6/fuzzing/CMakeLists.txt000664 001750 001750 00000000734 14540541202 020545 0ustar00farindkfarindk000000 000000 include_directories(${libheif_BINARY_DIR} ${libheif_SOURCE_DIR}) add_executable(box_fuzzer box_fuzzer.cc) target_link_libraries(box_fuzzer PRIVATE heif) add_executable(color_conversion_fuzzer color_conversion_fuzzer.cc) target_link_libraries(color_conversion_fuzzer PRIVATE heif) add_executable(encoder_fuzzer encoder_fuzzer.cc) target_link_libraries(encoder_fuzzer PRIVATE heif) add_executable(file_fuzzer file_fuzzer.cc) target_link_libraries(file_fuzzer PRIVATE heif) libheif-1.17.6/fuzzing/box_fuzzer.cc000664 001750 001750 00000002472 14540541202 020512 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2017 struktur AG, Joachim Bauch * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include #include "libheif/box.h" #include "libheif/bitstream.h" #include "libheif/logging.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { auto reader = std::make_shared(data, size, false); BitstreamRange range(reader, size); for (;;) { std::shared_ptr box; Error error = Box::read(range, &box); if (error != Error::Ok || range.error()) { break; } box->get_type(); box->get_type_string(); Indent indent; box->dump(indent); } return 0; } libheif-1.17.6/fuzzing/file_fuzzer.cc000664 001750 001750 00000012560 14540541202 020640 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2017 struktur AG, Joachim Bauch * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include #include #include #include "libheif/heif.h" static const enum heif_colorspace kFuzzColorSpace = heif_colorspace_YCbCr; static const enum heif_chroma kFuzzChroma = heif_chroma_420; static void TestDecodeImage(struct heif_context* ctx, const struct heif_image_handle* handle, size_t filesize) { struct heif_image* image = nullptr; struct heif_error err; bool primary = heif_image_handle_is_primary_image(handle); (void) primary; int width = heif_image_handle_get_width(handle); int height = heif_image_handle_get_height(handle); assert(width >= 0); assert(height >= 0); int metadata_count = heif_image_handle_get_number_of_metadata_blocks(handle, nullptr); assert(metadata_count >= 0); assert(static_cast(metadata_count) < filesize / sizeof(heif_item_id)); heif_item_id* metadata_ids = static_cast(malloc(metadata_count * sizeof(heif_item_id))); assert(metadata_ids); int metadata_ids_count = heif_image_handle_get_list_of_metadata_block_IDs(handle, nullptr, metadata_ids, metadata_count); assert(metadata_count == metadata_ids_count); for (int i = 0; i < metadata_count; i++) { heif_image_handle_get_metadata_type(handle, metadata_ids[i]); heif_image_handle_get_metadata_content_type(handle, metadata_ids[i]); size_t metadata_size = heif_image_handle_get_metadata_size(handle, metadata_ids[i]); assert(metadata_size < filesize); uint8_t* metadata_data = static_cast(malloc(metadata_size)); assert(metadata_data); heif_image_handle_get_metadata(handle, metadata_ids[i], metadata_data); free(metadata_data); } free(metadata_ids); err = heif_decode_image(handle, &image, kFuzzColorSpace, kFuzzChroma, nullptr); if (err.code != heif_error_Ok) { heif_image_release(image); return; } assert(heif_image_get_colorspace(image) == kFuzzColorSpace); assert(heif_image_get_chroma_format(image) == kFuzzChroma); // TODO(fancycode): Should we also check the planes? heif_image_release(image); } static int clip_int(size_t size) { return size > INT_MAX ? INT_MAX : static_cast(size); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { struct heif_context* ctx; struct heif_error err; struct heif_image_handle* primary_handle = nullptr; int images_count; heif_item_id* image_IDs = NULL; bool explicit_init = size == 0 || data[size - 1] & 1; if (explicit_init) { heif_init(nullptr); } heif_check_filetype(data, clip_int(size)); heif_main_brand(data, clip_int(size)); heif_get_file_mime_type(data, clip_int(size)); ctx = heif_context_alloc(); assert(ctx); err = heif_context_read_from_memory(ctx, data, size, nullptr); if (err.code != heif_error_Ok) { // Not a valid HEIF file passed (which is most likely while fuzzing). goto quit; } err = heif_context_get_primary_image_handle(ctx, &primary_handle); if (err.code == heif_error_Ok) { assert(heif_image_handle_is_primary_image(primary_handle)); TestDecodeImage(ctx, primary_handle, size); heif_image_handle_release(primary_handle); primary_handle = nullptr; } images_count = heif_context_get_number_of_top_level_images(ctx); if (!images_count) { // File doesn't contain any images. goto quit; } image_IDs = (heif_item_id*) malloc(images_count * sizeof(heif_item_id)); assert(image_IDs); images_count = heif_context_get_list_of_top_level_image_IDs(ctx, image_IDs, images_count); if (!images_count) { // Could not get list of image ids. goto quit; } for (int i = 0; i < images_count; ++i) { struct heif_image_handle* image_handle = nullptr; err = heif_context_get_image_handle(ctx, image_IDs[i], &image_handle); if (err.code != heif_error_Ok) { heif_image_handle_release(image_handle); // Ignore, we are only interested in crashes here. continue; } TestDecodeImage(ctx, image_handle, size); int num_thumbnails = heif_image_handle_get_number_of_thumbnails(image_handle); for (int t = 0; t < num_thumbnails; ++t) { struct heif_image_handle* thumbnail_handle = nullptr; heif_image_handle_get_thumbnail(image_handle, t, &thumbnail_handle); if (thumbnail_handle) { TestDecodeImage(ctx, thumbnail_handle, size); heif_image_handle_release(thumbnail_handle); } } heif_image_handle_release(image_handle); } quit: heif_image_handle_release(primary_handle); heif_context_free(ctx); free(image_IDs); if (explicit_init) { heif_deinit(); } return 0; } libheif-1.17.6/fuzzing/encoder_fuzzer.cc000664 001750 001750 00000012434 14540541202 021340 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2018 struktur AG, Joachim Bauch * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include #include #include #include #include "libheif/heif.h" static void generate_plane(int width, int height, uint8_t* output, int stride) { // TODO(fancycode): Fill with random data. if (width == stride) { memset(output, 0, width * height); } else { for (int y = 0; y < height; y++) { memset(output, 0, width); output += stride; } } } static size_t create_image(const uint8_t* data, size_t size, struct heif_image** image) { if (size < 2) { return 0; } int width = data[0] + 16; int height = data[1] + 16; data += 2; size -= 2; // TODO(fancycode): Get colorspace/chroma from fuzzing input. heif_colorspace colorspace = heif_colorspace_YCbCr; heif_chroma chroma = heif_chroma_420; struct heif_error err = heif_image_create(width, height, colorspace, chroma, image); if (err.code != heif_error_Ok) { return 0; } int chroma_width = (width+1)/2; int chroma_height = (height+1)/2; err = heif_image_add_plane(*image, heif_channel_Y, width, height, 8); assert(err.code == heif_error_Ok); err = heif_image_add_plane(*image, heif_channel_Cb, chroma_width, chroma_height, 8); assert(err.code == heif_error_Ok); err = heif_image_add_plane(*image, heif_channel_Cr, chroma_width, chroma_height, 8); assert(err.code == heif_error_Ok); int stride; uint8_t* plane; plane = heif_image_get_plane(*image, heif_channel_Y, &stride); generate_plane(width, height, plane, stride); plane = heif_image_get_plane(*image, heif_channel_Cb, &stride); generate_plane(chroma_width, chroma_height, plane, stride); plane = heif_image_get_plane(*image, heif_channel_Cr, &stride); generate_plane(chroma_width, chroma_height, plane, stride); return 2; } class MemoryWriter { public: MemoryWriter() : data_(nullptr), size_(0), capacity_(0) {} ~MemoryWriter() { free(data_); } const uint8_t* data() const { return data_; } size_t size() const { return size_; } void write(const void* data, size_t size) { if (capacity_ - size_ < size) { size_t new_capacity = capacity_ + size; uint8_t* new_data = static_cast(malloc(new_capacity)); assert(new_data); if (data_) { memcpy(new_data, data_, size_); free(data_); } data_ = new_data; capacity_ = new_capacity; } memcpy(&data_[size_], data, size); size_ += size; } public: uint8_t* data_; size_t size_; size_t capacity_; }; static struct heif_error writer_write(struct heif_context* ctx, const void* data, size_t size, void* userdata) { MemoryWriter* writer = static_cast(userdata); writer->write(data, size); struct heif_error err{heif_error_Ok, heif_suberror_Unspecified, nullptr}; return err; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { struct heif_error err; std::shared_ptr context(heif_context_alloc(), [](heif_context* c) { heif_context_free(c); }); assert(context); if (size < 2) { return 0; } int quality = (data[0] & 0x7F) % 101; bool lossless = (data[1] & 0x80); bool use_avif = (data[1] & 0x40); data += 2; size -= 2; static const size_t kMaxEncoders = 5; const heif_encoder_descriptor* encoder_descriptors[kMaxEncoders]; int count = heif_get_encoder_descriptors(use_avif ? heif_compression_AV1 : heif_compression_HEVC, nullptr, encoder_descriptors, kMaxEncoders); assert(count >= 0); if (count == 0) { return 0; } heif_encoder* encoder; err = heif_context_get_encoder(context.get(), encoder_descriptors[0], &encoder); if (err.code != heif_error_Ok) { return 0; } heif_encoder_set_lossy_quality(encoder, quality); heif_encoder_set_lossless(encoder, lossless); struct heif_image* image = nullptr; size_t read = create_image(data, size, &image); assert(read <= size); if (!read) { heif_image_release(image); heif_encoder_release(encoder); return 0; } data += read; size -= read; struct heif_image_handle* img; err = heif_context_encode_image(context.get(), image, encoder, nullptr, &img); heif_image_release(image); heif_encoder_release(encoder); heif_image_handle_release(img); if (err.code != heif_error_Ok) { return 0; } MemoryWriter writer; struct heif_writer w; w.writer_api_version = 1; w.write = writer_write; heif_context_write(context.get(), &w, &writer); assert(writer.size() > 0); return 0; } libheif-1.17.6/libheif.pc.in000664 001750 001750 00000001376 14540541202 016647 0ustar00farindkfarindk000000 000000 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ # Contrary to older versions of libheif (<= 1.14.2), the available-codec-variables are now all set to 'yes' # as since 1.14.0, codecs can be dynamically loaded at runtime and it is not possible anymore to determine # the available codecs at compile-time. You'll get an unknown codec error at runtime if you try to use an # unavailable codec. builtin_h265_decoder=yes builtin_h265_encoder=yes builtin_avif_decoder=yes builtin_avif_encoder=yes Name: libheif Description: HEIF image codec. URL: https://github.com/strukturag/libheif Version: @PROJECT_VERSION@ Requires: Requires.private: @REQUIRES_PRIVATE@ Libs: -L${libdir} -lheif Libs.private: @LIBS_PRIVATE@ Cflags: -I${includedir} libheif-1.17.6/CPPLINT.cfg000664 001750 001750 00000000062 14540541202 016075 0ustar00farindkfarindk000000 000000 set noparent filter=-,+build/include_what_you_use libheif-1.17.6/gnome/000775 001750 001750 00000000000 14540541203 015413 5ustar00farindkfarindk000000 000000 libheif-1.17.6/gnome/heif.thumbnailer000664 001750 001750 00000000157 14540541202 020564 0ustar00farindkfarindk000000 000000 [Thumbnailer Entry] TryExec=heif-thumbnailer Exec=heif-thumbnailer -s %s %i %o MimeType=image/heif;image/avif; libheif-1.17.6/gnome/CMakeLists.txt000664 001750 001750 00000000170 14540541202 020150 0ustar00farindkfarindk000000 000000 if(TARGET heif-thumbnailer) install(FILES heif.thumbnailer DESTINATION ${CMAKE_INSTALL_DATADIR}/thumbnailers) endif() libheif-1.17.6/CMakeLists.txt000664 001750 001750 00000030313 14540541202 017045 0ustar00farindkfarindk000000 000000 cmake_minimum_required (VERSION 3.16.3) # Oldest Ubuntu LTS (20.04 currently) project(libheif LANGUAGES C CXX VERSION 1.17.6) # compatibility_version is never allowed to be decreased for any specific SONAME. # Libtool in the libheif-1.15.1 release had set it to 17.0.0, so we have to use this for the v1.x.y versions. # With v2.0.0, we can reset this to more closely follow the real version name, i.e. "2.0.0". # CMake 3.17.0 added "MACHO_COMPATIBILITY_VERSION", but we are currently stuck at cmake 3.16.3. set(MACOS_COMPATIBLE_VERSION "17.0.0") # https://cmake.org/cmake/help/v3.1/policy/CMP0054.html cmake_policy(VERSION 3.0...3.22) include(GNUInstallDirs) # The version number. set (PACKAGE_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) # Check for unistd.h include (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) if (HAVE_UNISTD_H) add_definitions(-DHAVE_UNISTD_H) endif() if(NOT MSVC) add_definitions(-Wall) add_definitions(-Werror) add_definitions(-Wsign-compare) add_definitions(-Wconversion) add_definitions(-Wno-sign-conversion) add_definitions(-Wno-error=conversion) add_definitions(-Wno-error=unused-parameter) add_definitions(-Wno-error=deprecated-declarations) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_definitions(-Wno-error=tautological-compare) add_definitions(-Wno-error=tautological-constant-out-of-range-compare) endif () endif() set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Create the compile command database for clang by default set(CMAKE_EXPORT_COMPILE_COMMANDS ON) option(BUILD_SHARED_LIBS "Build shared libraries" ON) include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG(-Wno-error=potentially-evaluated-expression has_potentially_evaluated_expression) if (has_potentially_evaluated_expression) add_definitions(-Wno-error=potentially-evaluated-expression) endif() LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") # --- codec plugins option(ENABLE_PLUGIN_LOADING "Support loading of plugins" ON) set(PLUGIN_DIRECTORY "${CMAKE_INSTALL_FULL_LIBDIR}/libheif" CACHE STRING "Plugin install directory") if (ENABLE_PLUGIN_LOADING) set(PLUGIN_LOADING_SUPPORTED_AND_ENABLED TRUE) install(DIRECTORY DESTINATION ${PLUGIN_DIRECTORY} DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) endif() macro(plugin_option optionVariableName displayName defaultEnabled defaultPlugin) option(WITH_${optionVariableName} "Build ${displayName}" ${defaultEnabled}) option(WITH_${optionVariableName}_PLUGIN "Build ${displayName} as a plugin" ${defaultPlugin}) endmacro() macro(plugin_compilation_info optionVariableName detectionVariable displayName) if (${detectionVariable}_FOUND AND WITH_${optionVariableName}_PLUGIN AND PLUGIN_LOADING_SUPPORTED_AND_ENABLED) set(msg "+ separate plugin") elseif (${detectionVariable}_FOUND) set(msg "+ built-in") elseif (WITH_${optionVariableName}) set(msg "- not found") else() set(msg "- disabled") endif () string(LENGTH "${displayName}" len) math(EXPR fill "29 - ${len}") string(SUBSTRING " " 0 ${fill} filler) message("${displayName}${filler}: ${msg}") unset(msg) endmacro() # libde265 plugin_option(LIBDE265 "libde265 HEVC decoder" ON OFF) if (WITH_LIBDE265) find_package(LIBDE265) endif() # x265 plugin_option(X265 "x265 HEVC encoder" ON OFF) if (WITH_X265) find_package(X265) endif() # kvazaar plugin_option(KVAZAAR "kvazaar HEVC encoder" OFF OFF) if (WITH_KVAZAAR) find_package(kvazaar) if ("${HAVE_KVAZAAR_ENABLE_LOGGING}") add_definitions(-DHAVE_KVAZAAR_ENABLE_LOGGING=1) else () add_definitions(-DHAVE_KVAZAAR_ENABLE_LOGGING=0) endif () endif () # dav1d plugin_option(DAV1D "Dav1d AV1 decoder" OFF ON) if (WITH_DAV1D) find_package(DAV1D) endif() # aom plugin_option(AOM_DECODER "AOM AV1 decoder" ON OFF) plugin_option(AOM_ENCODER "AOM AV1 encoder" ON OFF) if (WITH_AOM_ENCODER OR WITH_AOM_DECODER) find_package(AOM) endif() # svt plugin_option(SvtEnc "SVT AV1 encoder" OFF ON) if (WITH_SvtEnc) find_package(SvtEnc) endif() # rav1e plugin_option(RAV1E "Rav1e AV1 encoder" OFF ON) if (WITH_RAV1E) find_package(RAV1E) endif() # jpeg plugin_option(JPEG_DECODER "JPEG decoder" OFF OFF) plugin_option(JPEG_ENCODER "JPEG encoder" OFF OFF) if (WITH_JPEG_ENCODER OR WITH_JPEG_DECODER) find_package(JPEG) endif() # openjpeg plugin_option(OpenJPEG_ENCODER "OpenJPEG J2K encoder" OFF ON) plugin_option(OpenJPEG_DECODER "OpenJPEG J2K decoder" OFF ON) if (WITH_OpenJPEG_ENCODER OR WITH_OpenJPEG_DECODER) find_package(OpenJPEG) endif() # ffmpeg plugin_option(FFMPEG_DECODER "FFMPEG HEVC decoder (HW accelerated)" OFF OFF) if (WITH_FFMPEG_DECODER) find_package(FFMPEG COMPONENTS avcodec) endif () # uncompressed option(WITH_UNCOMPRESSED_CODEC " Support internal ISO/IEC 23001-17 uncompressed codec (experimental) " OFF) # --- show codec compilation summary message("=== Summary of compiled codecs ===") plugin_compilation_info(LIBDE265 LIBDE265 "libde265 HEVC decoder") plugin_compilation_info(FFMPEG_DECODER FFMPEG_avcodec "FFMPEG HEVC decoder (HW acc)") plugin_compilation_info(X265 X265 "x265 HEVC encoder") plugin_compilation_info(KVAZAAR KVAZAAR "Kvazaar HEVC encoder") plugin_compilation_info(AOM_DECODER AOM_DECODER "AOM AV1 decoder") plugin_compilation_info(AOM_ENCODER AOM_ENCODER "AOM AV1 encoder") plugin_compilation_info(DAV1D DAV1D "Dav1d AV1 decoder") plugin_compilation_info(SvtEnc SvtEnc "SVT AV1 encoder") plugin_compilation_info(RAV1E RAV1E "Rav1e AV1 encoder") plugin_compilation_info(JPEG_DECODER JPEG "JPEG decoder") plugin_compilation_info(JPEG_ENCODER JPEG "JPEG encoder") plugin_compilation_info(OpenJPEG_DECODER OpenJPEG "OpenJPEG J2K decoder") plugin_compilation_info(OpenJPEG_ENCODER OpenJPEG "OpenJPEG J2K encoder") # --- Libsharpyuv color space transforms option(WITH_LIBSHARPYUV "Build libsharpyuv" ON) if (WITH_LIBSHARPYUV) find_package(libsharpyuv) endif () if (LIBSHARPYUV_FOUND) message("libsharpyuv: found") elseif (WITH_${variableName}) message("libsharpyuv: not found") else() message("libsharpyuv: disabled") endif () # --- Create libheif pkgconfig file set(prefix ${CMAKE_INSTALL_PREFIX}) set(exec_prefix "\${prefix}") if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") set(libdir "${CMAKE_INSTALL_LIBDIR}") else() set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") endif() if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") set(includedir "${CMAKE_INSTALL_INCLUDEDIR}") else() set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") endif() if (LIBDE265_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_LIBDE265_PLUGIN)) list(APPEND REQUIRES_PRIVATE "libde265") endif() if (X265_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_X265_PLUGIN)) list(APPEND REQUIRES_PRIVATE "x265") endif() if ((AOM_DECODER_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_AOM_DECODER_PLUGIN)) OR (AOM_ENCODER_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_AOM_ENCODER_PLUGIN))) list(APPEND REQUIRES_PRIVATE "aom") endif() if (FFMPEG_DECODER_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_FFMPEG_DECODER_PLUGIN)) list(APPEND REQUIRES_PRIVATE "ffmpeg") endif() if (DAV1D_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_DAV1D_PLUGIN)) list(APPEND REQUIRES_PRIVATE "dav1d") endif() if (RAV1E_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_RAV1E_PLUGIN)) list(APPEND REQUIRES_PRIVATE "rav1e") endif() if (SvtEnc_FOUND AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_SvtEnc_PLUGIN)) list(APPEND REQUIRES_PRIVATE "SvtAv1Enc") endif() if (JPEG_FOUND AND ((WITH_JPEG_DECODER AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_JPEG_DECODER_PLUGIN)) OR (WITH_JPEG_ENCODER AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_JPEG_ENCODER_PLUGIN)))) list(APPEND REQUIRES_PRIVATE "libjpeg") endif() if (OpenJPEG_FOUND AND ((WITH_OpenJPEG_DECODER AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_OpenJPEG_DECODER_PLUGIN)) OR (WITH_OpenJPEG_ENCODER AND NOT (PLUGIN_LOADING_SUPPORTED_AND_ENABLED AND WITH_OpenJPEG_ENCODER_PLUGIN)))) list(APPEND REQUIRES_PRIVATE "libopenjp2") endif() if (LIBSHARPYUV_FOUND) list(APPEND REQUIRES_PRIVATE "libsharpyuv") endif() if (WITH_DEFLATE_HEADER_COMPRESSION) list(APPEND REQUIRES_PRIVATE "zlib") endif() list(JOIN REQUIRES_PRIVATE " " REQUIRES_PRIVATE) include(CheckCXXSymbolExists) check_cxx_symbol_exists(_LIBCPP_VERSION cstdlib HAVE_LIBCPP) if(HAVE_LIBCPP) set(LIBS_PRIVATE "-lc++") else() set(LIBS_PRIVATE "-lstdc++") endif() configure_file(libheif.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libheif.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libheif.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) # --- option(WITH_EXAMPLES "Build examples" ON) option(WITH_GDK_PIXBUF "Build gdk-pixbuf plugin" ON) option(WITH_REDUCED_VISIBILITY "Reduced symbol visibility in library" ON) option(WITH_DEFLATE_HEADER_COMPRESSION OFF) option(ENABLE_MULTITHREADING_SUPPORT "Switch off for platforms without multithreading support" ON) option(ENABLE_PARALLEL_TILE_DECODING "Will launch multiple decoders to decode tiles in parallel (requires ENABLE_MULTITHREADING_SUPPORT)" ON) if (WITH_REDUCED_VISIBILITY) set(CMAKE_CXX_VISIBILITY_PRESET hidden) else () set(CMAKE_CXX_VISIBILITY_PRESET default) endif () if(WITH_EXAMPLES) add_subdirectory (examples) endif() # --- API documentation # check if Doxygen is installed find_package(Doxygen) if (DOXYGEN_FOUND) # set input and output files set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/libheif/Doxyfile.in) set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) # request to configure the file configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) message("Doxygen build started") # note the option ALL which allows to build the docs together with the application add_custom_target( doc_doxygen ALL COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM ) else (DOXYGEN_FOUND) message("Doxygen tool needs to be installed to generate the API documentation") endif (DOXYGEN_FOUND) # --- Testing option(BUILD_TESTING "" ON) include(CTest) if(BUILD_TESTING) # TODO: fix tests on windows. add_subdirectory (tests) endif() # --- Fuzzing option(WITH_FUZZERS "Build the fuzzers (and no other executables)" OFF) set(FUZZING_C_COMPILER "clang" CACHE STRING "C compiler to use for fuzzing") set(FUZZING_CXX_COMPILER "clang++" CACHE STRING "C++ compiler to use for fuzzing") set(FUZZING_COMPILE_OPTIONS "-fsanitize=fuzzer,address,shift,integer -fno-sanitize-recover=shift,integer" CACHE STRING "Compiler options for fuzzing") set(FUZZING_LINKER_OPTIONS "" CACHE STRING "Additional linking options for fuzzing") if (WITH_FUZZERS) set(CMAKE_C_COMPILER ${FUZZING_C_COMPILER}) set(CMAKE_CXX_COMPILER ${FUZZING_CXX_COMPILER}) message("Using compiler: ${CMAKE_CXX_COMPILER}") separate_arguments(FUZZING_COMPILE_OPTIONS UNIX_COMMAND "${FUZZING_COMPILE_OPTIONS}") separate_arguments(FUZZING_LINKER UNIX_COMMAND "${FUZZING_LINKER_OPTIONS}") add_compile_options(${FUZZING_COMPILE_OPTIONS}) add_link_options(${FUZZING_COMPILE_OPTIONS} ${FUZZING_LINKER_OPTIONS}) add_subdirectory(fuzzing) endif() if (CMAKE_CXX_COMPILER MATCHES "clang\\+\\+$") add_compile_options(-Wno-tautological-constant-out-of-range-compare) endif() add_subdirectory (libheif) if (WITH_GDK_PIXBUF) add_subdirectory (gdk-pixbuf) endif() add_subdirectory (gnome) # --- packaging (source code) set(CPACK_VERBATIM_VARIABLES YES) set(CPACK_SOURCE_GENERATOR TGZ) set(CPACK_SOURCE_PACKAGE_FILE_NAME libheif-${PACKAGE_VERSION}) set(CPACK_SOURCE_IGNORE_FILES /.git/ /.github/ /.gitignore$ /build/ /cmake-build.*/ /.deps/ /.idea/ /.clang-tidy ~$ /third-party/.*/ # only exclude the sub-directories, but keep the *.cmd files /Testing/ /logos/ /Makefile$ /libtool$ /libheif.pc$ stamp-h1$ ) include(CPack) libheif-1.17.6/CMakePresets.json000664 001750 001750 00000010510 14540541202 017523 0ustar00farindkfarindk000000 000000 { "version": 3, "cmakeMinimumRequired": { "major": 3, "minor": 0, "patch": 0 }, "configurePresets": [ { "name": "default", "displayName": "Default Config", "description": "Default building parameters", "cacheVariables": { "WITH_AOM_DECODER" : "ON", "WITH_AOM_DECODER_PLUGIN" : "ON", "WITH_AOM_ENCODER" : "ON", "WITH_AOM_ENCODER_PLUGIN" : "ON", "WITH_DAV1D" : "ON", "WITH_DAV1D_PLUGIN" : "ON", "WITH_LIBDE265" : "ON", "WITH_LIBDE265_PLUGIN" : "ON", "WITH_RAV1E" : "ON", "WITH_RAV1E_PLUGIN" : "ON", "WITH_SvtEnc" : "ON", "WITH_SvtEnc_PLUGIN" : "ON", "WITH_X265" : "ON", "WITH_X265_PLUGIN" : "ON", "WITH_JPEG_DECODER" : "ON", "WITH_JPEG_DECODER_PLUGIN" : "ON", "WITH_JPEG_ENCODER" : "ON", "WITH_JPEG_ENCODER_PLUGIN" : "ON", "WITH_UNCOMPRESSED_CODEC" : "ON", "WITH_KVAZAAR" : "ON", "WITH_KVAZAAR_PLUGIN" : "ON", "WITH_OpenJPEG_DECODER" : "ON", "WITH_OpenJPEG_DECODER_PLUGIN" : "ON", "WITH_OpenJPEG_ENCODER" : "ON", "WITH_OpenJPEG_ENCODER_PLUGIN" : "ON", "WITH_FFMPEG_DECODER" : "ON", "WITH_FFMPEG_DECODER_PLUGIN" : "ON" } }, { "name": "develop", "inherits": "default", "displayName": "development", "description": "Enable all experimental features. Do not use plugins, compile everything built-in.", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "BUILD_SHARED_LIBS": "ON", "BUILD_TESTING" : "ON", "ENABLE_PLUGIN_LOADING" : "OFF", "WITH_AOM_DECODER" : "ON", "WITH_AOM_ENCODER" : "ON", "WITH_DAV1D" : "ON", "WITH_LIBDE265" : "ON", "WITH_RAV1E" : "ON", "WITH_SvtEnc" : "ON", "WITH_X265" : "ON", "WITH_JPEG_DECODER" : "ON", "WITH_JPEG_ENCODER" : "ON", "WITH_UNCOMPRESSED_CODEC" : "ON", "WITH_KVAZAAR" : "ON", "WITH_OpenJPEG_DECODER" : "ON", "WITH_OpenJPEG_ENCODER" : "ON", "WITH_FFMPEG_DECODER" : "ON", "WITH_REDUCED_VISIBILITY" : "OFF", "WITH_DEFLATE_HEADER_COMPRESSION" : "ON", "WITH_LIBSHARPYUV" : "ON", "WITH_EXAMPLES": "ON", "WITH_FUZZERS": "OFF" } }, { "name": "release", "inherits": "default", "displayName": "Standard release build", "description": "Recommended parameters for a release build.", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "BUILD_SHARED_LIBS": "ON", "BUILD_TESTING" : "OFF", "WITH_REDUCED_VISIBILITY" : "ON", "WITH_DEFLATE_HEADER_COMPRESSION" : "ON", "WITH_LIBSHARPYUV" : "ON", "WITH_EXAMPLES": "ON", "WITH_FUZZERS": "OFF" } }, { "name": "release-noplugins", "inherits": "release", "displayName": "Release build without plugins", "description": "Release without plugins with minimal configuration for HEIC and AVIF.", "cacheVariables": { "ENABLE_PLUGIN_LOADING" : "OFF", "WITH_LIBDE265" : "ON", "WITH_X265" : "ON", "WITH_AOM_DECODER" : "ON", "WITH_AOM_ENCODER" : "ON", "WITH_DAV1D" : "OFF", "WITH_RAV1E" : "OFF", "WITH_SvtEnc" : "OFF", "WITH_JPEG_DECODER" : "OFF", "WITH_JPEG_ENCODER" : "OFF", "WITH_UNCOMPRESSED_CODEC" : "OFF", "WITH_KVAZAAR" : "OFF", "WITH_OpenJPEG_DECODER" : "OFF", "WITH_OpenJPEG_ENCODER" : "OFF", "WITH_FFMPEG_DECODER" : "OFF" } }, { "name": "testing", "inherits": "default", "displayName": "Tests", "description": "For running the tests", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "ENABLE_PLUGIN_LOADING" : "OFF", "BUILD_TESTING" : "ON", "WITH_REDUCED_VISIBILITY" : "OFF" } }, { "name": "fuzzing", "inherits": "default", "displayName": "Fuzzing", "description": "For running the fuzzers", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "BUILD_SHARED_LIBS": "OFF", "BUILD_TESTING" : "OFF", "WITH_FUZZERS" : "ON", "WITH_EXAMPLES" : "OFF", "ENABLE_PLUGIN_LOADING" : "OFF", "WITH_DEFLATE_HEADER_COMPRESSION" : "ON", "WITH_LIBSHARPYUV" : "ON", "WITH_REDUCED_VISIBILITY" : "OFF" } } ] } libheif-1.17.6/build-emscripten.sh000775 001750 001750 00000011321 14540541202 020110 0ustar00farindkfarindk000000 000000 #!/bin/bash set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" if [[ $# -ne 1 ]] ; then echo "Usage: $0 SRCDIR" echo echo "It is recommended to build in a separate directory." echo "Then specify this directory as an argument to this script." echo "Example:" echo " mkdir buildjs" echo " cd buildjs" echo " USE_WASM=0 ../build-emscripten.sh .." echo echo "This should generate a libheif.js and (optionally, without the USE_WASM=0) a libheif.wasm" exit 5 fi SRCDIR=$1 CORES="${CORES:-`nproc --all`}" ENABLE_LIBDE265="${ENABLE_LIBDE265:-1}" LIBDE265_VERSION="${LIBDE265_VERSION:-1.0.12}" ENABLE_AOM="${ENABLE_AOM:-0}" AOM_VERSION="${AOM_VERSION:-3.6.1}" STANDALONE="${STANDALONE:-0}" DEBUG="${DEBUG:-0}" USE_WASM="${USE_WASM:-1}" echo "Build using ${CORES} CPU cores" LIBRARY_LINKER_FLAGS="" LIBRARY_INCLUDE_FLAGS="" CONFIGURE_ARGS_LIBDE265="" if [ "$ENABLE_LIBDE265" = "1" ]; then [ -s "libde265-${LIBDE265_VERSION}.tar.gz" ] || curl \ -L \ -o libde265-${LIBDE265_VERSION}.tar.gz \ https://github.com/strukturag/libde265/releases/download/v${LIBDE265_VERSION}/libde265-${LIBDE265_VERSION}.tar.gz if [ ! -s "libde265-${LIBDE265_VERSION}/libde265/.libs/libde265.a" ]; then tar xf libde265-${LIBDE265_VERSION}.tar.gz cd libde265-${LIBDE265_VERSION} [ -x configure ] || ./autogen.sh CXXFLAGS=-O3 emconfigure ./configure --enable-static --disable-shared --disable-sse --disable-dec265 --disable-sherlock265 emmake make -j${CORES} cd .. fi CONFIGURE_ARGS_LIBDE265="-DLIBDE265_INCLUDE_DIR=${DIR}/libde265-${LIBDE265_VERSION} -DLIBDE265_LIBRARY=-L${DIR}/libde265-${LIBDE265_VERSION}/libde265/.libs" LIBRARY_LINKER_FLAGS="$LIBRARY_LINKER_FLAGS -lde265" LIBRARY_INCLUDE_FLAGS="$LIBRARY_INCLUDE_FLAGS -L${DIR}/libde265-${LIBDE265_VERSION}/libde265/.libs" fi CONFIGURE_ARGS_AOM="" if [ "$ENABLE_AOM" = "1" ]; then [ -s "aom-${AOM_VERSION}.tar.gz" ] || curl \ -L \ -o aom-${AOM_VERSION}.tar.gz \ "https://aomedia.googlesource.com/aom/+archive/v${AOM_VERSION}.tar.gz" if [ ! -s "aom-${AOM_VERSION}/libaom.a" ]; then mkdir -p aom-${AOM_VERSION}/aom-source tar xf aom-${AOM_VERSION}.tar.gz -C aom-${AOM_VERSION}/aom-source cd aom-${AOM_VERSION} emcmake cmake aom-source \ -DENABLE_CCACHE=1 \ -DAOM_TARGET_CPU=generic \ -DENABLE_DOCS=0 \ -DENABLE_TESTS=0 \ -DENABLE_EXAMPLES=0 \ -DENABLE_TESTDATA=0 \ -DENABLE_TOOLS=0 \ -DCONFIG_MULTITHREAD=0 \ -DCONFIG_RUNTIME_CPU_DETECT=0 \ -DBUILD_SHARED_LIBS=0 \ -DCMAKE_BUILD_TYPE=Release emmake make -j${CORES} cd .. fi CONFIGURE_ARGS_AOM="-DAOM_INCLUDE_DIR=${DIR}/aom-${AOM_VERSION}/aom-source -DAOM_LIBRARY=-L${DIR}/aom-${AOM_VERSION}" LIBRARY_LINKER_FLAGS="$LIBRARY_LINKER_FLAGS -laom" LIBRARY_INCLUDE_FLAGS="$LIBRARY_INCLUDE_FLAGS -L${DIR}/aom-${AOM_VERSION}" fi EXTRA_EXE_LINKER_FLAGS="-lembind" EXTRA_COMPILER_FLAGS="" if [ "$STANDALONE" = "1" ]; then EXTRA_EXE_LINKER_FLAGS="" EXTRA_COMPILER_FLAGS="-D__EMSCRIPTEN_STANDALONE_WASM__=1" fi CONFIGURE_ARGS="-DENABLE_MULTITHREADING_SUPPORT=OFF -DWITH_GDK_PIXBUF=OFF -DWITH_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DENABLE_PLUGIN_LOADING=OFF" emcmake cmake ${SRCDIR} $CONFIGURE_ARGS \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_FLAGS="${EXTRA_COMPILER_FLAGS}" \ -DCMAKE_CXX_FLAGS="${EXTRA_COMPILER_FLAGS}" \ -DCMAKE_EXE_LINKER_FLAGS="${LIBRARY_LINKER_FLAGS} ${EXTRA_EXE_LINKER_FLAGS}" \ $CONFIGURE_ARGS_LIBDE265 \ $CONFIGURE_ARGS_AOM VERBOSE=1 emmake make -j${CORES} LIBHEIFA="libheif/libheif.a" EXPORTED_FUNCTIONS=$($EMSDK/upstream/bin/llvm-nm $LIBHEIFA --format=just-symbols | grep "^heif_\|^de265_\|^aom_" | grep "[^:]$" | sed 's/^/_/' | paste -sd "," -) echo "Running Emscripten..." BUILD_FLAGS="-lembind -o libheif.js --post-js ${SRCDIR}/post.js -sWASM=$USE_WASM" RELEASE_BUILD_FLAGS="-O3" if [ "$STANDALONE" = "1" ]; then # Note: this intentionally overwrites the BUILD_FLAGS set above echo "Building in standalone (non-web) build mode" BUILD_FLAGS="-sSTANDALONE_WASM -sWASM -o libheif.wasm --no-entry" fi if [ "$DEBUG" = "1" ]; then echo "Building in debug mode" RELEASE_BUILD_FLAGS="--profile -g" fi emcc -Wl,--whole-archive "$LIBHEIFA" -Wl,--no-whole-archive \ -sEXPORTED_FUNCTIONS="$EXPORTED_FUNCTIONS,_free,_malloc,_memcpy" \ -sMODULARIZE \ -sEXPORT_NAME="libheif" \ -sWASM_ASYNC_COMPILATION=0 \ -sALLOW_MEMORY_GROWTH \ --memory-init-file 0 \ -std=c++11 \ $LIBRARY_INCLUDE_FLAGS \ $LIBRARY_LINKER_FLAGS \ $BUILD_FLAGS \ $RELEASE_BUILD_FLAGS libheif-1.17.6/appveyor.yml000664 001750 001750 00000001411 14540541202 016672 0ustar00farindkfarindk000000 000000 # stats available at # https://ci.appveyor.com/project/strukturag/libheif image: Visual Studio 2019 configuration: Release cache: c:\tools\vcpkg\installed\ matrix: allow_failures: - arch: arm64 # libde265 currently doesn't support arm64 on vcpkg environment: matrix: - arch: x64 - arch: arm64 install: - vcpkg install libde265:%arch%-windows - vcpkg install x265:%arch%-windows - vcpkg install dav1d:%arch%-windows - cd c:\tools\vcpkg - vcpkg integrate install - cd %APPVEYOR_BUILD_FOLDER% before_build: - mkdir build - cd build - cmake .. -A %arch% -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake build: verbosity: normal artifacts: - path: build - path: build\**\Release\*.exe - path: build\**\Release\*.dll libheif-1.17.6/third-party/000775 001750 001750 00000000000 14540541203 016555 5ustar00farindkfarindk000000 000000 libheif-1.17.6/third-party/libsharpyuv.cmd000664 001750 001750 00000001711 14540541202 021611 0ustar00farindkfarindk000000 000000 : # This install script was originally taken from libavif but might have been modified. : # If you want to enable the libsharpyuv decoder, please check that the WITH_LIBSHARPYUV CMake variable is set correctly. : # You will also have to set the PKG_CONFIG_PATH to "third-party/libwebp/build/dist/lib/pkgconfig" so that the local libsharpyuv library is found. : # The odd choice of comment style in this file is to try to share this script between *nix and win32. : # meson and ninja must be in your PATH. : # If you're running this on Windows, be sure you've already run this (from your VC2019 install dir): : # "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" git clone --single-branch https://chromium.googlesource.com/webm/libwebp cd libwebp mkdir build cd build cmake -G Ninja -DCMAKE_INSTALL_PREFIX="$(pwd)/dist" -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release .. ninja sharpyuv ninja install cd ../.. libheif-1.17.6/third-party/dav1d.cmd000664 001750 001750 00000002045 14540541202 020241 0ustar00farindkfarindk000000 000000 : # This install script was originally taken from libavif but might have been modified. : # If you want to enable the DAV1D decoder, please check that the WITH_DAV1D CMake variable is set correctly. : # You will also have to set the PKG_CONFIG_PATH to "third-party/dav1d/dist/lib/x86_64-linux-gnu/pkgconfig" so that the local DAV1D library is found. : # The odd choice of comment style in this file is to try to share this script between *nix and win32. : # meson and ninja must be in your PATH. : # If you're running this on Windows, be sure you've already run this (from your VC2019 install dir): : # "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" git clone -b 1.0.0 --depth 1 https://code.videolan.org/videolan/dav1d.git cd dav1d : # macOS might require: -Dc_args=-fno-stack-check : # Build with asan: -Db_sanitize=address : # Build with ubsan: -Db_sanitize=undefined meson build --default-library=static --buildtype release --prefix "$(pwd)/dist" $@ ninja -C build ninja -C build install cd .. libheif-1.17.6/third-party/rav1e.cmd000664 001750 001750 00000002114 14540541202 020255 0ustar00farindkfarindk000000 000000 : # This install script was originally taken from libavif but might have been modified. : # If you want to enable the RAV1E encoder, please check that the WITH_RAV1E CMake variable is set correctly. : # You will also have to set the PKG_CONFIG_PATH to "third-party/rav1e/dist/lib/pkgconfig" so that the local RAV1E library is found. : # The odd choice of comment style in this file is to try to share this script between *nix and win32. : # cargo must be in your PATH. (use rustup or brew to install) : # If you're running this on Windows targeting Rust's windows-msvc, be sure you've already run this (from your VC2017 install dir): : # "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat" : # : # Also, the error that "The target windows-msvc is not supported yet" can safely be ignored provided that rav1e/target/release : # contains rav1e.h and rav1e.lib. git clone -b 0.5 --depth 1 https://github.com/xiph/rav1e.git cd rav1e cargo install cargo-c cargo cinstall --crt-static --release --prefix="$(pwd)/dist" --library-type=staticlib cd .. libheif-1.17.6/third-party/aom.cmd000664 001750 001750 00000001765 14540541202 020026 0ustar00farindkfarindk000000 000000 : # This install script was originally taken from libavif but might have been modified. : # If you want to enable the AOM encoder, please check that the WITH_AOM CMake variable is set correctly. : # You will also have to set the PKG_CONFIG_PATH to "third-party/aom/dist/lib/pkgconfig" so that the local AOM library is found. : # The odd choice of comment style in this file is to try to share this script between *nix and win32. : # cmake and ninja must be in your PATH. : # If you're running this on Windows, be sure you've already run this (from your VC2019 install dir): : # "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" git clone -b v3.5.0 --depth 1 https://aomedia.googlesource.com/aom cd aom cmake -S . -B build.libavif -G Ninja -DCMAKE_INSTALL_PREFIX="$(pwd)/dist" -DCMAKE_BUILD_TYPE=Release -DENABLE_DOCS=0 -DENABLE_EXAMPLES=0 -DENABLE_TESTDATA=0 -DENABLE_TESTS=0 -DENABLE_TOOLS=0 ninja -C build.libavif ninja -C build.libavif install cd .. libheif-1.17.6/third-party/svt.cmd000664 001750 001750 00000001204 14540541202 020052 0ustar00farindkfarindk000000 000000 : # This install script was originally taken from libavif but might have been modified. : # cmake and ninja must be in your PATH for compiling. : # If you want to enable the SVT-AV1 encoder, please check that the WITH_SvtEnc and WITH_SvtEnc_BUILTIN CMake variables are set correctly. : # You will also have to set the PKG_CONFIG_PATH to "third-party/SVT-AV1/Build/linux/Release" so that the local SVT-AV1 library is found. git clone -b v1.2.1 --depth 1 https://gitlab.com/AOMediaCodec/SVT-AV1.git cd SVT-AV1 cd Build/linux ./build.sh release static no-dec no-apps cd ../.. mkdir -p include/svt-av1 cp Source/API/*.h include/svt-av1 cd .. libheif-1.17.6/libheif/000775 001750 001750 00000000000 14540541203 015710 5ustar00farindkfarindk000000 000000 libheif-1.17.6/libheif/metadata_compression.h000664 001750 001750 00000002106 14540541202 022260 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2022 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #ifndef LIBHEIF_METADATA_COMPRESSION_H #define LIBHEIF_METADATA_COMPRESSION_H #include #include #if WITH_DEFLATE_HEADER_COMPRESSION std::vector deflate(const uint8_t* input, int size); std::vector inflate(const std::vector&); #endif #endif //LIBHEIF_METADATA_COMPRESSION_H libheif-1.17.6/libheif/heif_properties.cc000664 001750 001750 00000022206 14540541202 021407 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2017 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include "libheif/heif_properties.h" #include "context.h" #include "api_structs.h" #include "file.h" #include #include #include #include int heif_item_get_properties_of_type(const struct heif_context* context, heif_item_id id, heif_item_property_type type, heif_property_id* out_list, int count) { auto file = context->context->get_heif_file(); std::vector> properties; Error err = file->get_properties(id, properties); if (err) { // We do not pass the error, because a missing ipco should have been detected already when reading the file. return 0; } int out_idx = 0; int property_id = 1; for (const auto& property : properties) { bool match; if (type == heif_item_property_type_invalid) { match = true; } else { match = (property->get_short_type() == type); } if (match) { if (out_list && out_idx < count) { out_list[out_idx] = property_id; out_idx++; } else if (!out_list) { out_idx++; } } property_id++; } return out_idx; } int heif_item_get_transformation_properties(const struct heif_context* context, heif_item_id id, heif_property_id* out_list, int count) { auto file = context->context->get_heif_file(); std::vector> properties; Error err = file->get_properties(id, properties); if (err) { // We do not pass the error, because a missing ipco should have been detected already when reading the file. return 0; } int out_idx = 0; int property_id = 1; for (const auto& property : properties) { bool match = (property->get_short_type() == fourcc("imir") || property->get_short_type() == fourcc("irot") || property->get_short_type() == fourcc("clap")); if (match) { if (out_list && out_idx < count) { out_list[out_idx] = property_id; out_idx++; } else if (!out_list) { out_idx++; } } property_id++; } return out_idx; } enum heif_item_property_type heif_item_get_property_type(const struct heif_context* context, heif_item_id id, heif_property_id propertyId) { auto file = context->context->get_heif_file(); std::vector> properties; Error err = file->get_properties(id, properties); if (err) { // We do not pass the error, because a missing ipco should have been detected already when reading the file. return heif_item_property_type_invalid; } if (propertyId - 1 < 0 || propertyId - 1 >= properties.size()) { return heif_item_property_type_invalid; } auto property = properties[propertyId - 1]; return (enum heif_item_property_type) property->get_short_type(); } static char* create_c_string_copy(const std::string s) { char* copy = new char[s.length() + 1]; strcpy(copy, s.data()); return copy; } struct heif_error heif_item_get_property_user_description(const struct heif_context* context, heif_item_id itemId, heif_property_id propertyId, struct heif_property_user_description** out) { if (!out) { return {heif_error_Usage_error, heif_suberror_Invalid_parameter_value, "NULL passed"}; } auto file = context->context->get_heif_file(); std::vector> properties; Error err = file->get_properties(itemId, properties); if (err) { return err.error_struct(context->context.get()); } if (propertyId - 1 < 0 || propertyId - 1 >= properties.size()) { return {heif_error_Usage_error, heif_suberror_Invalid_property, "property index out of range"}; } auto udes = std::dynamic_pointer_cast(properties[propertyId - 1]); if (!udes) { return {heif_error_Usage_error, heif_suberror_Invalid_property, "wrong property type"}; } auto* udes_c = new heif_property_user_description(); udes_c->version = 1; udes_c->lang = create_c_string_copy(udes->get_lang()); udes_c->name = create_c_string_copy(udes->get_name()); udes_c->description = create_c_string_copy(udes->get_description()); udes_c->tags = create_c_string_copy(udes->get_tags()); *out = udes_c; return heif_error_success; } LIBHEIF_API struct heif_error heif_item_add_property_user_description(const struct heif_context* context, heif_item_id itemId, const struct heif_property_user_description* description, heif_property_id* out_propertyId) { if (!context || !description) { return {heif_error_Usage_error, heif_suberror_Null_pointer_argument, "NULL passed"}; } auto udes = std::make_shared(); udes->set_lang(description->lang ? description->lang : ""); udes->set_name(description->name ? description->name : ""); udes->set_description(description->description ? description->description : ""); udes->set_tags(description->tags ? description->tags : ""); heif_property_id id = context->context->add_property(itemId, udes, false); if (out_propertyId) { *out_propertyId = id; } return heif_error_success; } enum heif_transform_mirror_direction heif_item_get_property_transform_mirror(const struct heif_context* context, heif_item_id itemId, heif_property_id propertyId) { auto file = context->context->get_heif_file(); std::vector> properties; Error err = file->get_properties(itemId, properties); if (err) { return heif_transform_mirror_direction_invalid; } if (propertyId - 1 < 0 || propertyId - 1 >= properties.size()) { return heif_transform_mirror_direction_invalid; } auto imir = std::dynamic_pointer_cast(properties[propertyId - 1]); if (!imir) { return heif_transform_mirror_direction_invalid; } return imir->get_mirror_direction(); } int heif_item_get_property_transform_rotation_ccw(const struct heif_context* context, heif_item_id itemId, heif_property_id propertyId) { auto file = context->context->get_heif_file(); std::vector> properties; Error err = file->get_properties(itemId, properties); if (err) { return -1; } if (propertyId - 1 < 0 || propertyId - 1 >= properties.size()) { return -1; } auto irot = std::dynamic_pointer_cast(properties[propertyId - 1]); if (!irot) { return -1; } return irot->get_rotation(); } void heif_item_get_property_transform_crop_borders(const struct heif_context* context, heif_item_id itemId, heif_property_id propertyId, int image_width, int image_height, int* left, int* top, int* right, int* bottom) { auto file = context->context->get_heif_file(); std::vector> properties; Error err = file->get_properties(itemId, properties); if (err) { return; } if (propertyId - 1 < 0 || propertyId - 1 >= properties.size()) { return; } auto clap = std::dynamic_pointer_cast(properties[propertyId - 1]); if (!clap) { return; } if (left) *left = clap->left_rounded(image_width); if (right) *right = image_width - 1 - clap->right_rounded(image_width); if (top) *top = clap->top_rounded(image_height); if (bottom) *bottom = image_height - 1 - clap->bottom_rounded(image_height); } void heif_property_user_description_release(struct heif_property_user_description* udes) { if (udes == nullptr) { return; } delete[] udes->lang; delete[] udes->name; delete[] udes->description; delete[] udes->tags; delete udes; } libheif-1.17.6/libheif/heif_regions.h000664 001750 001750 00000115226 14540541202 020530 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2023 Dirk Farin * Copyright (c) 2023 Brad Hards * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #ifndef LIBHEIF_HEIF_REGIONS_H #define LIBHEIF_HEIF_REGIONS_H #include "libheif/heif.h" #ifdef __cplusplus extern "C" { #endif // --- region items and annotations // See ISO/IEC 23008-12:2022 Section 6.10 "Region items and region annotations" struct heif_region_item; /** * Region type. * * Each region item will contain zero or more regions, which may have different geometry or * mask representations. */ enum heif_region_type { /** * Point gemetry. * * The region is represented by a single point. */ heif_region_type_point = 0, /** * Rectangle geometry. * * The region is represented by a top left position, and a size defined * by a width and height. All of the interior points and the edge are * part of the region. */ heif_region_type_rectangle = 1, /** * Ellipse geometry. * * The region is represented by a centre point, and radii in the X and * Y directions. All of the interior points and the edge are part of the * region. */ heif_region_type_ellipse = 2, /** * Polygon geometry. * * The region is represented by a sequence of points, which is considered * implicitly closed. All of the interior points and the edge are part * of the region. */ heif_region_type_polygon = 3, /** * Reference mask. * * The region geometry is described by the pixels in another image item, * which has a item reference of type `mask` from the region item to the * image item containing the mask. * * The image item containing the mask is one of: * * - a mask item (see ISO/IEC 23008-12:2022 Section 6.10.2), or a derived * image from a mask item * * - an image item in monochrome format (4:0:0 chroma) * * - an image item in colour format with luma and chroma planes (e.g. 4:2:0) * * If the pixel value is equal to the minimum sample value (e.g. 0 for unsigned * integer), the pixel is not part of the region. If the pixel value is equal * to the maximum sample value (e.g. 255 for 8 bit unsigned integer), the pixel * is part of the region. If the pixel value is between the minimum sample value * and maximum sample value, the pixel value represents an (application defined) * probability that the pixel is part of the region, where higher pixel values * correspond to higher probability values. */ heif_region_type_referenced_mask = 4, /** * Inline mask. * * The region geometry is described by a sequence of bits stored in inline * in the region, one bit per pixel. If the bit value is `1`, the pixel is * part of the region. If the bit value is `0`, the pixel is not part of the * region. */ heif_region_type_inline_mask = 5, /** * Polyline geometry. * * The region is represented by a sequence of points, which are not * considered to form a closed surface. Only the edge is part of the region. */ heif_region_type_polyline = 6 }; struct heif_region; /** * Get the number of region items that are attached to an image. * * @param image_handle the image handle for the image to query. * @return the number of region items, which can be zero. */ LIBHEIF_API int heif_image_handle_get_number_of_region_items(const struct heif_image_handle* image_handle); /** * Get the region item identifiers for the region items attached to an image. * * Possible usage (in C++): * @code * int numRegionItems = heif_image_handle_get_number_of_region_items(handle); * if (numRegionItems > 0) { * std::vector region_item_ids(numRegionItems); * heif_image_handle_get_list_of_region_item_ids(handle, region_item_ids.data(), numRegionItems); * // use region item ids * } * @endcode * * @param image_handle the image handle for the parent image to query * @param region_item_ids_array array to put the item identifiers into * @param max_count the maximum number of region identifiers * @return the number of region item identifiers that were returned. */ LIBHEIF_API int heif_image_handle_get_list_of_region_item_ids(const struct heif_image_handle* image_handle, heif_item_id* region_item_ids_array, int max_count); /** * Get the region item. * * Caller is responsible for release of the output heif_region_item with heif_region_item_release(). * * @param context the context to get the region item from, usually from a file operation * @param region_item_id the identifier for the region item * @param out pointer to pointer to the resulting region item * @return heif_error_ok on success, or an error value indicating the problem */ LIBHEIF_API struct heif_error heif_context_get_region_item(const struct heif_context* context, heif_item_id region_item_id, struct heif_region_item** out); /** * Get the item identifier for a region item. * * @param region_item the region item to query * @return the region item identifier (or -1 if the region_item is null) */ LIBHEIF_API heif_item_id heif_region_item_get_id(struct heif_region_item* region_item); /** * Release a region item. * * This should be called on items from heif_context_get_region_item(). * * @param region_item the item to release. */ LIBHEIF_API void heif_region_item_release(struct heif_region_item* region_item); /** * Get the reference size for a region item. * * The reference size specifies the coordinate space used for the region items. * When the reference size does not match the image size, the regions need to be * scaled to correspond. * * @param out_width the return value for the reference width (before any transformation) * @param out_height the return value for the reference height (before any transformation) */ LIBHEIF_API void heif_region_item_get_reference_size(struct heif_region_item*, uint32_t* out_width, uint32_t* out_height); /** * Get the number of regions within a region item. * * @param region_item the region item to query. * @return the number of regions */ LIBHEIF_API int heif_region_item_get_number_of_regions(const struct heif_region_item* region_item); /** * Get the regions that are part of a region item. * * Caller is responsible for releasing the returned `heif_region` objects, using heif_region_release() * on each region, or heif_region_release_many() on the returned array. * * Possible usage (in C++): * @code * int num_regions = heif_image_handle_get_number_of_regions(region_item); * if (num_regions > 0) { * std::vector regions(num_regions); * int n = heif_region_item_get_list_of_regions(region_item, regions.data(), (int)regions.size()); * // use regions * heif_region_release_many(regions.data(), n); * } * @endcode * * @param region_item the region_item to query * @param out_regions_array array to put the region pointers into * @param max_count the maximum number of regions, which needs to correspond to the size of the out_regions_array * @return the number of regions that were returned. */ LIBHEIF_API int heif_region_item_get_list_of_regions(const struct heif_region_item* region_item, struct heif_region** out_regions_array, int max_count); /** * Release a region. * * This should be called on regions from heif_region_item_get_list_of_regions(). * * @param region the region to release. * * \sa heif_region_release_many() to release the whole list */ LIBHEIF_API void heif_region_release(const struct heif_region* region); /** * Release a list of regions. * * This should be called on the list of regions from heif_region_item_get_list_of_regions(). * * @param regions_array the regions to release. * @param num_items the number of items in the array * * \sa heif_region_release() to release a single region */ LIBHEIF_API void heif_region_release_many(const struct heif_region* const* regions_array, int num_items); /** * Get the region type for a specified region. * * @param region the region to query * @return the corresponding region type as an enumeration value */ LIBHEIF_API enum heif_region_type heif_region_get_type(const struct heif_region* region); // When querying the region geometry, there is a version without and a version with "_transformed" suffix. // The version without returns the coordinates in the reference coordinate space. // The version with "_transformed" suffix give the coordinates in pixels after all transformative properties have been applied. /** * Get the values for a point region. * * This returns the coordinates in the reference coordinate space (from the parent region item). * * @param region the region to query, which must be of type #heif_region_type_point. * @param out_x the X coordinate, where 0 is the left-most column. * @param out_y the Y coordinate, where 0 is the top-most row. * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_point_transformed() for a version in pixels after all transformative properties have been applied. */ LIBHEIF_API struct heif_error heif_region_get_point(const struct heif_region* region, int32_t* out_x, int32_t* out_y); /** * Get the transformed values for a point region. * * This returns the coordinates in pixels after all transformative properties have been applied. * * @param region the region to query, which must be of type #heif_region_type_point. * @param image_id the identifier for the image to transform / scale the region to * @param out_x the X coordinate, where 0 is the left-most column. * @param out_y the Y coordinate, where 0 is the top-most row. * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_point() for a version that returns the values in the reference coordinate space. */ LIBHEIF_API struct heif_error heif_region_get_point_transformed(const struct heif_region* region, heif_item_id image_id, double* out_x, double* out_y); /** * Get the values for a rectangle region. * * This returns the values in the reference coordinate space (from the parent region item). * The rectangle is represented by a top left corner position, and a size defined * by a width and height. All of the interior points and the edge are * part of the region. * * @param region the region to query, which must be of type #heif_region_type_rectangle. * @param out_x the X coordinate for the top left corner, where 0 is the left-most column. * @param out_y the Y coordinate for the top left corner, where 0 is the top-most row. * @param out_width the width of the rectangle * @param out_height the height of the rectangle * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_rectangle_transformed() for a version in pixels after all transformative properties have been applied. */ LIBHEIF_API struct heif_error heif_region_get_rectangle(const struct heif_region* region, int32_t* out_x, int32_t* out_y, uint32_t* out_width, uint32_t* out_height); /** * Get the transformed values for a rectangle region. * * This returns the coordinates in pixels after all transformative properties have been applied. * The rectangle is represented by a top left corner position, and a size defined * by a width and height. All of the interior points and the edge are * part of the region. * * @param region the region to query, which must be of type #heif_region_type_rectangle. * @param image_id the identifier for the image to transform / scale the region to * @param out_x the X coordinate for the top left corner, where 0 is the left-most column. * @param out_y the Y coordinate for the top left corner, where 0 is the top-most row. * @param out_width the width of the rectangle * @param out_height the height of the rectangle * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_rectangle() for a version that returns the values in the reference coordinate space. */ LIBHEIF_API struct heif_error heif_region_get_rectangle_transformed(const struct heif_region* region, heif_item_id image_id, double* out_x, double* out_y, double* out_width, double* out_height); /** * Get the values for an ellipse region. * * This returns the values in the reference coordinate space (from the parent region item). * The ellipse is represented by a centre position, and a size defined * by radii in the X and Y directions. All of the interior points and the edge are * part of the region. * * @param region the region to query, which must be of type #heif_region_type_ellipse. * @param out_x the X coordinate for the centre point, where 0 is the left-most column. * @param out_y the Y coordinate for the centre point, where 0 is the top-most row. * @param out_radius_x the radius value in the X direction. * @param out_radius_y the radius value in the Y direction * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_ellipse_transformed() for a version in pixels after all transformative properties have been applied. */ LIBHEIF_API struct heif_error heif_region_get_ellipse(const struct heif_region* region, int32_t* out_x, int32_t* out_y, uint32_t* out_radius_x, uint32_t* out_radius_y); /** * Get the transformed values for an ellipse region. * * This returns the coordinates in pixels after all transformative properties have been applied. * The ellipse is represented by a centre position, and a size defined * by radii in the X and Y directions. All of the interior points and the edge are * part of the region. * * @param region the region to query, which must be of type #heif_region_type_ellipse. * @param image_id the identifier for the image to transform / scale the region to * @param out_x the X coordinate for the centre point, where 0 is the left-most column. * @param out_y the Y coordinate for the centre point, where 0 is the top-most row. * @param out_radius_x the radius value in the X direction. * @param out_radius_y the radius value in the Y direction * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_ellipse() for a version that returns the values in the reference coordinate space. */ LIBHEIF_API struct heif_error heif_region_get_ellipse_transformed(const struct heif_region* region, heif_item_id image_id, double* out_x, double* out_y, double* out_radius_x, double* out_radius_y); /** * Get the number of points in a polygon. * * @param region the region to query, which must be of type #heif_region_type_polygon * @return the number of points, or -1 on error. */ LIBHEIF_API int heif_region_get_polygon_num_points(const struct heif_region* region); /** * Get the points in a polygon region. * * This returns the values in the reference coordinate space (from the parent region item). * * A polygon is a sequence of points that form a closed shape. The first point does * not need to be repeated as the last point. All of the interior points and the edge are * part of the region. * The points are returned as pairs of X,Y coordinates, in the order X1, * Y1, X2, Y2, ..., Xn, Yn. * * @param region the region to equery, which must be of type #heif_region_type_polygon * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points * in the polygon. * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_polygon_points_transformed() for a version in pixels after all transformative properties have been applied. */ LIBHEIF_API struct heif_error heif_region_get_polygon_points(const struct heif_region* region, int32_t* out_pts_array); /** * Get the transformed points in a polygon region. * * This returns the coordinates in pixels after all transformative properties have been applied. * * A polygon is a sequence of points that form a closed shape. The first point does * not need to be repeated as the last point. All of the interior points and the edge are * part of the region. * The points are returned as pairs of X,Y coordinates, in the order X1, * Y1, X2, Y2, ..., Xn, Yn. * * @param region the region to equery, which must be of type #heif_region_type_polygon * @param image_id the identifier for the image to transform / scale the region to * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points * in the polygon. * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_polygon_points() for a version that returns the values in the reference coordinate space. */ LIBHEIF_API struct heif_error heif_region_get_polygon_points_transformed(const struct heif_region* region, heif_item_id image_id, double* out_pts_array); /** * Get the number of points in a polyline. * * @param region the region to query, which must be of type #heif_region_type_polyline * @return the number of points, or -1 on error. */ LIBHEIF_API int heif_region_get_polyline_num_points(const struct heif_region* region); /** * Get the points in a polyline region. * * This returns the values in the reference coordinate space (from the parent region item). * * A polyline is a sequence of points that does not form a closed shape. Even if the * polyline is closed, the only points that are part of the region are those that * intersect (even minimally) a one-pixel line drawn along the polyline. * The points are provided as pairs of X,Y coordinates, in the order X1, * Y1, X2, Y2, ..., Xn, Yn. * * Possible usage (in C++): * @code * int num_polyline_points = heif_region_get_polyline_num_points(region); * if (num_polyline_points > 0) { * std::vector polyline(num_polyline_points * 2); * heif_region_get_polyline_points(region, polyline.data()); * // do something with points ... * } * @endcode * * @param region the region to equery, which must be of type #heif_region_type_polyline * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points * in the polyline. * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_polyline_points_transformed() for a version in pixels after all transformative properties have been applied. */ LIBHEIF_API struct heif_error heif_region_get_polyline_points(const struct heif_region* region, int32_t* out_pts_array); /** * Get the transformed points in a polyline region. * * This returns the coordinates in pixels after all transformative properties have been applied. * * A polyline is a sequence of points that does not form a closed shape. Even if the * polyline is closed, the only points that are part of the region are those that * intersect (even minimally) a one-pixel line drawn along the polyline. * The points are provided as pairs of X,Y coordinates, in the order X1, * Y1, X2, Y2, ..., Xn, Yn. * * @param region the region to query, which must be of type #heif_region_type_polyline * @param image_id the identifier for the image to transform / scale the region to * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points * in the polyline. * @return heif_error_ok on success, or an error value indicating the problem on failure * * \sa heif_region_get_polyline_points() for a version that returns the values in the reference coordinate space. */ LIBHEIF_API struct heif_error heif_region_get_polyline_points_transformed(const struct heif_region* region, heif_item_id image_id, double* out_pts_array); /** * Get a referenced item mask region. * * This returns the values in the reference coordinate space (from the parent region item). * The mask location is represented by a top left corner position, and a size defined * by a width and height. The value of each sample in that mask identifies whether the * corresponding pixel is part of the region. * * The mask is provided as an image in another item. The image item containing the mask * is one of: * * - a mask item (see ISO/IEC 23008-12:2022 Section 6.10.2), or a derived * image from a mask item * * - an image item in monochrome format (4:0:0 chroma) * * - an image item in colour format with luma and chroma planes (e.g. 4:2:0) * * If the pixel value is equal to the minimum sample value (e.g. 0 for unsigned * integer), the pixel is not part of the region. If the pixel value is equal * to the maximum sample value (e.g. 255 for 8 bit unsigned integer), the pixel * is part of the region. If the pixel value is between the minimum sample value * and maximum sample value, the pixel value represents an (application defined) * probability that the pixel is part of the region, where higher pixel values * correspond to higher probability values. * * @param region the region to query, which must be of type #heif_region_type_referenced_mask. * @param out_x the X coordinate for the top left corner, where 0 is the left-most column. * @param out_y the Y coordinate for the top left corner, where 0 is the top-most row. * @param out_width the width of the mask region * @param out_height the height of the mask region * @param out_mask_item_id the item identifier for the image that provides the mask. * @return heif_error_ok on success, or an error value indicating the problem on failure */ LIBHEIF_API struct heif_error heif_region_get_referenced_mask_ID(const struct heif_region* region, int32_t* out_x, int32_t* out_y, uint32_t* out_width, uint32_t* out_height, heif_item_id *out_mask_item_id); /** * Get the length of the data in an inline mask region. * * @param region the region to query, which must be of type #heif_region_type_inline_mask. * @return the number of bytes in the mask data, or 0 on error. */ LIBHEIF_API size_t heif_region_get_inline_mask_data_len(const struct heif_region* region); /** * Get data for an inline mask region. * * This returns the values in the reference coordinate space (from the parent region item). * The mask location is represented by a top left corner position, and a size defined * by a width and height. * * The mask is held as inline data on the region, one bit per pixel, most significant * bit first pixel, no padding. If the bit value is `1`, the corresponding pixel is * part of the region. If the bit value is `0`, the corresponding pixel is not part of the * region. * * Possible usage (in C++): * @code * long unsigned int data_len = heif_region_get_inline_mask_data_len(region); * int32_t x, y; * uint32_t width, height; * std::vector mask_data(data_len); * err = heif_region_get_inline_mask(region, &x, &y, &width, &height, mask_data.data()); * @endcode * * @param region the region to query, which must be of type #heif_region_type_inline_mask. * @param out_x the X coordinate for the top left corner, where 0 is the left-most column. * @param out_y the Y coordinate for the top left corner, where 0 is the top-most row. * @param out_width the width of the mask region * @param out_height the height of the mask region * @param out_mask_data the location to return the mask data * @return heif_error_ok on success, or an error value indicating the problem on failure */ LIBHEIF_API struct heif_error heif_region_get_inline_mask_data(const struct heif_region* region, int32_t* out_x, int32_t* out_y, uint32_t* out_width, uint32_t* out_height, uint8_t* out_mask_data); /** * Get a mask region image. * * This returns the values in the reference coordinate space (from the parent region item). * The mask location is represented by a top left corner position, and a size defined * by a width and height. * * This function works when the passed region is either a heif_region_type_referenced_mask or * a heif_region_type_inline_mask. * The returned image is a monochrome image where each pixel represents the (scaled) probability * of the pixel being part of the mask. * * If the region type is an inline mask, which always holds a binary mask, this function * converts the binary inline mask to an 8-bit monochrome image with the values '0' and '255'. * The pixel value is set to `255` where the pixel is part of the region, and `0` where the * pixel is not part of the region. * * @param region the region to query, which must be of type #heif_region_type_inline_mask. * @param out_x the X coordinate for the top left corner, where 0 is the left-most column. * @param out_y the Y coordinate for the top left corner, where 0 is the top-most row. * @param out_width the width of the mask region * @param out_height the height of the mask region * @param out_mask_image the returned mask image * @return heif_error_ok on success, or an error value indicating the problem on failure * * \note the caller is responsible for releasing the mask image */ LIBHEIF_API struct heif_error heif_region_get_mask_image(const struct heif_region* region, int32_t* out_x, int32_t* out_y, uint32_t* out_width, uint32_t* out_height, struct heif_image** out_mask_image); // --- adding region items /** * Add a region item to an image. * * The region item is a collection of regions (point, polyline, polygon, rectangle, ellipse or mask) * along with a reference size (width and height) that forms the coordinate basis for the regions. * * The concept is to add the region item, then add one or more regions to the region item. * * @param image_handle the image to attach the region item to. * @param reference_width the width of the reference size. * @param reference_height the height of the reference size. * @param out_region_item the resulting region item * @return heif_error_ok on success, or an error indicating the problem on failure */ LIBHEIF_API struct heif_error heif_image_handle_add_region_item(struct heif_image_handle* image_handle, uint32_t reference_width, uint32_t reference_height, struct heif_region_item** out_region_item); /** * Add a point region to the region item. * * @param region_item the region item that holds this point region * @param x the x value for the point location * @param y the y value for the point location * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error indicating the problem on failure * * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. */ LIBHEIF_API struct heif_error heif_region_item_add_region_point(struct heif_region_item* region_item, int32_t x, int32_t y, struct heif_region** out_region); /** * Add a rectangle region to the region item. * * @param region_item the region item that holds this rectangle region * @param x the x value for the top-left corner of this rectangle region * @param y the y value for the top-left corner of this rectangle region * @param width the width of this rectangle region * @param height the height of this rectangle region * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error indicating the problem on failure * * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. */ LIBHEIF_API struct heif_error heif_region_item_add_region_rectangle(struct heif_region_item* region_item, int32_t x, int32_t y, uint32_t width, uint32_t height, struct heif_region** out_region); /** * Add a ellipse region to the region item. * * @param region_item the region item that holds this ellipse region * @param x the x value for the centre of this ellipse region * @param y the y value for the centre of this ellipse region * @param radius_x the radius of the ellipse in the X (horizontal) direction * @param radius_y the radius of the ellipse in the Y (vertical) direction * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error indicating the problem on failure * * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. */ LIBHEIF_API struct heif_error heif_region_item_add_region_ellipse(struct heif_region_item* region_item, int32_t x, int32_t y, uint32_t radius_x, uint32_t radius_y, struct heif_region** out_region); /** * Add a polygon region to the region item. * * A polygon is a sequence of points that form a closed shape. The first point does * not need to be repeated as the last point. * The points are provided as pairs of X,Y coordinates, in the order X1, * Y1, X2, Y2, ..., Xn, Yn. * * @param region_item the region item that holds this polygon region * @param pts_array the array of points in X,Y order (see above) * @param nPoints the number of points * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error indicating the problem on failure * * @note `nPoints` is the number of points, not the number of elements in the array * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. */ LIBHEIF_API struct heif_error heif_region_item_add_region_polygon(struct heif_region_item* region_item, const int32_t* pts_array, int nPoints, struct heif_region** out_region); /** * Add a polyline region to the region item. * * A polyline is a sequence of points that does not form a closed shape. Even if the * polyline is closed, the only points that are part of the region are those that * intersect (even minimally) a one-pixel line drawn along the polyline. * The points are provided as pairs of X,Y coordinates, in the order X1, * Y1, X2, Y2, ..., Xn, Yn. * * @param region_item the region item that holds this polyline region * @param pts_array the array of points in X,Y order (see above) * @param nPoints the number of points * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error indicating the problem on failure * * @note `nPoints` is the number of points, not the number of elements in the array * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. */ LIBHEIF_API struct heif_error heif_region_item_add_region_polyline(struct heif_region_item* region_item, const int32_t* pts_array, int nPoints, struct heif_region** out_region); /** * Add a referenced mask region to the region item. * * The region geometry is described by the pixels in another image item, * which has a item reference of type `mask` from the region item to the * image item containing the mask. * * The image item containing the mask is one of: * * - a mask item (see ISO/IEC 23008-12:2022 Section 6.10.2), or a derived * image from a mask item * * - an image item in monochrome format (4:0:0 chroma) * * - an image item in colour format with luma and chroma planes (e.g. 4:2:0) * * If the pixel value is equal to the minimum sample value (e.g. 0 for unsigned * integer), the pixel is not part of the region. If the pixel value is equal * to the maximum sample value (e.g. 255 for 8 bit unsigned integer), the pixel * is part of the region. If the pixel value is between the minimum sample value * and maximum sample value, the pixel value represents an (application defined) * probability that the pixel is part of the region, where higher pixel values * correspond to higher probability values. * * @param region_item the region item that holds this mask region * @param x the x value for the top-left corner of this mask region * @param y the y value for the top-left corner of this mask region * @param width the width of this mask region * @param height the height of this mask region * @param mask_item_id the item identifier for the mask that is referenced * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error indicating the problem on failure * * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. */ LIBHEIF_API struct heif_error heif_region_item_add_region_referenced_mask(struct heif_region_item* region_item, int32_t x, int32_t y, uint32_t width, uint32_t height, heif_item_id mask_item_id, struct heif_region** out_region); /** * Add an inline mask region to the region item. * * The region geometry is described by a top left corner position, and a size defined * by a width and height. * * The mask is held as inline data on the region, one bit per pixel, most significant * bit first pixel, no padding. If the bit value is `1`, the corresponding pixel is * part of the region. If the bit value is `0`, the corresponding pixel is not part of the * region. * * @param region_item the region item that holds this mask region * @param x the x value for the top-left corner of this mask region * @param y the y value for the top-left corner of this mask region * @param width the width of this mask region * @param height the height of this mask region * @param mask_data the location to return the mask data * @param mask_data_len the length of the mask data, in bytes * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error value indicating the problem on failure */ LIBHEIF_API struct heif_error heif_region_item_add_region_inline_mask_data(struct heif_region_item* region_item, int32_t x, int32_t y, uint32_t width, uint32_t height, const uint8_t* mask_data, size_t mask_data_len, struct heif_region** out_region); /** * Add an inline mask region image to the region item. * * The region geometry is described by a top left corner position, and a size defined * by a width and height. * * The mask data is held as inline data on the region, one bit per pixel. The provided * image is converted to inline data, where any pixel with a value >= 0x80 becomes part of the * mask region. If the image width is less that the specified width, it is expanded * to match the width of the region (zero fill on the right). If the image height is * less than the specified height, it is expanded to match the height of the region * (zero fill on the bottom). If the image width or height is greater than the * width or height (correspondingly) of the region, the image is cropped. * * @param region_item the region item that holds this mask region * @param x the x value for the top-left corner of this mask region * @param y the y value for the top-left corner of this mask region * @param width the width of this mask region * @param height the height of this mask region * @param image the image to convert to an inline mask * @param out_region pointer to pointer to the returned region (optional, see below) * @return heif_error_ok on success, or an error value indicating the problem on failure */ LIBHEIF_API struct heif_error heif_region_item_add_region_inline_mask(struct heif_region_item* region_item, int32_t x, int32_t y, uint32_t width, uint32_t height, struct heif_image* image, struct heif_region** out_region); #ifdef __cplusplus } #endif #endif libheif-1.17.6/libheif/hevc.h000664 001750 001750 00000006220 14540541202 017005 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2017 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #ifndef HEIF_HEVC_H #define HEIF_HEVC_H #include "heif.h" #include "box.h" #include "error.h" #include #include #include class Box_hvcC : public Box { public: Box_hvcC() { set_short_type(fourcc("hvcC")); } struct configuration { uint8_t configuration_version; uint8_t general_profile_space; bool general_tier_flag; uint8_t general_profile_idc; uint32_t general_profile_compatibility_flags; static const int NUM_CONSTRAINT_INDICATOR_FLAGS = 48; std::bitset general_constraint_indicator_flags; uint8_t general_level_idc; uint16_t min_spatial_segmentation_idc; uint8_t parallelism_type; uint8_t chroma_format; uint8_t bit_depth_luma; uint8_t bit_depth_chroma; uint16_t avg_frame_rate; uint8_t constant_frame_rate; uint8_t num_temporal_layers; uint8_t temporal_id_nested; }; std::string dump(Indent&) const override; bool get_headers(std::vector* dest) const; void set_configuration(const configuration& config) { m_configuration = config; } const configuration& get_configuration() const { return m_configuration; } void append_nal_data(const std::vector& nal); void append_nal_data(const uint8_t* data, size_t size); Error write(StreamWriter& writer) const override; protected: Error parse(BitstreamRange& range) override; private: struct NalArray { uint8_t m_array_completeness; uint8_t m_NAL_unit_type; std::vector > m_nal_units; }; configuration m_configuration; uint8_t m_length_size = 4; // default: 4 bytes for NAL unit lengths std::vector m_nal_array; }; class SEIMessage { public: virtual ~SEIMessage() = default; }; class SEIMessage_depth_representation_info : public SEIMessage, public heif_depth_representation_info { public: }; Error decode_hevc_aux_sei_messages(const std::vector& data, std::vector>& msgs); Error parse_sps_for_hvcC_configuration(const uint8_t* sps, size_t size, Box_hvcC::configuration* inout_config, int* width, int* height); #endif libheif-1.17.6/libheif/plugins_unix.cc000664 001750 001750 00000005441 14540541202 020746 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2023 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include "plugins_unix.h" #include "heif_plugin.h" #include #include #include #ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE #endif #include std::vector get_plugin_directories_from_environment_variable_unix() { char* path_variable = getenv("LIBHEIF_PLUGIN_PATH"); if (path_variable == nullptr) { return {}; } // --- split LIBHEIF_PLUGIN_PATH value at ':' into separate directories std::vector plugin_paths; std::istringstream paths(path_variable); std::string dir; while (getline(paths, dir, ':')) { plugin_paths.push_back(dir); } return plugin_paths; } std::vector list_all_potential_plugins_in_directory_unix(const char* directory) { std::vector result; DIR* dir = opendir(directory); if (dir == nullptr) { return {}; // TODO: return error_cannot_read_plugin_directory; } struct dirent* d; for (;;) { d = readdir(dir); if (d == nullptr) { break; } bool correct_filetype = true; #ifdef DT_REG correct_filetype = (d->d_type == DT_REG || d->d_type == DT_LNK || d->d_type == DT_UNKNOWN); #endif if (correct_filetype && strlen(d->d_name) > 3 && strcmp(d->d_name + strlen(d->d_name) - 3, ".so") == 0) { std::string filename = directory; filename += '/'; filename += d->d_name; //printf("load %s\n", filename.c_str()); result.push_back(filename); } } closedir(dir); return result; } heif_error PluginLibrary_Unix::load_from_file(const char* filename) { m_library_handle = dlopen(filename, RTLD_LAZY); if (!m_library_handle) { fprintf(stderr, "dlopen: %s\n", dlerror()); return error_dlopen; } m_plugin_info = (heif_plugin_info*) dlsym(m_library_handle, "plugin_info"); if (!m_plugin_info) { fprintf(stderr, "dlsym: %s\n", dlerror()); return error_dlopen; } return heif_error_ok; } void PluginLibrary_Unix::release() { if (m_library_handle) { dlclose(m_library_handle); m_library_handle = nullptr; } } libheif-1.17.6/libheif/pixelimage.cc000664 001750 001750 00000063574 14540541202 020361 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2017 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include "pixelimage.h" #include "common_utils.h" #include #include #include heif_chroma chroma_from_subsampling(int h, int v) { if (h == 2 && v == 2) { return heif_chroma_420; } else if (h == 2 && v == 1) { return heif_chroma_422; } else if (h == 1 && v == 1) { return heif_chroma_444; } else { assert(false); return heif_chroma_undefined; } } HeifPixelImage::~HeifPixelImage() { for (auto& iter : m_planes) { delete[] iter.second.allocated_mem; } } int num_interleaved_pixels_per_plane(heif_chroma chroma) { switch (chroma) { case heif_chroma_undefined: case heif_chroma_monochrome: case heif_chroma_420: case heif_chroma_422: case heif_chroma_444: return 1; case heif_chroma_interleaved_RGB: case heif_chroma_interleaved_RRGGBB_BE: case heif_chroma_interleaved_RRGGBB_LE: return 3; case heif_chroma_interleaved_RGBA: case heif_chroma_interleaved_RRGGBBAA_BE: case heif_chroma_interleaved_RRGGBBAA_LE: return 4; } assert(false); return 0; } bool is_integer_multiple_of_chroma_size(int width, int height, heif_chroma chroma) { switch (chroma) { case heif_chroma_444: case heif_chroma_monochrome: return true; case heif_chroma_422: return (width & 1) == 0; case heif_chroma_420: return (width & 1) == 0 && (height & 1) == 0; default: assert(false); return false; } } std::vector get_valid_chroma_values_for_colorspace(heif_colorspace colorspace) { switch (colorspace) { case heif_colorspace_YCbCr: return {heif_chroma_420, heif_chroma_422, heif_chroma_444}; case heif_colorspace_RGB: return {heif_chroma_444, heif_chroma_interleaved_RGB, heif_chroma_interleaved_RGBA, heif_chroma_interleaved_RRGGBB_BE, heif_chroma_interleaved_RRGGBBAA_BE, heif_chroma_interleaved_RRGGBB_LE, heif_chroma_interleaved_RRGGBBAA_LE}; case heif_colorspace_monochrome: return {heif_chroma_monochrome}; default: return {}; } } void HeifPixelImage::create(int width, int height, heif_colorspace colorspace, heif_chroma chroma) { m_width = width; m_height = height; m_colorspace = colorspace; m_chroma = chroma; } static uint32_t rounded_size(uint32_t s) { s = (s + 1U) & ~1U; if (s < 64) { s = 64; } return s; } bool HeifPixelImage::add_plane(heif_channel channel, int width, int height, int bit_depth) { ImagePlane plane; if (plane.alloc(width, height, bit_depth, m_chroma)) { m_planes.insert(std::make_pair(channel, plane)); return true; } else { return false; } } bool HeifPixelImage::ImagePlane::alloc(int width, int height, int bit_depth, heif_chroma chroma) { assert(width >= 0); assert(height >= 0); assert(bit_depth >= 1); assert(bit_depth <= 32); // use 16 byte alignment uint16_t alignment = 16; // must be power of two m_width = width; m_height = height; m_mem_width = rounded_size(width); m_mem_height = rounded_size(height); // for backwards compatibility, allow for 24/32 bits for RGB/RGBA interleaved chromas if (chroma == heif_chroma_interleaved_RGB && bit_depth == 24) { bit_depth = 8; } if (chroma == heif_chroma_interleaved_RGBA && bit_depth == 32) { bit_depth = 8; } assert(m_bit_depth <= 16); m_bit_depth = static_cast(bit_depth); int bytes_per_component = (m_bit_depth + 7) / 8; int bytes_per_pixel = num_interleaved_pixels_per_plane(chroma) * bytes_per_component; stride = m_mem_width * bytes_per_pixel; stride = (stride + alignment - 1U) & ~(alignment - 1U); try { allocated_mem = new uint8_t[m_mem_height * stride + alignment - 1]; mem = allocated_mem; // shift beginning of image data to aligned memory position auto mem_start_addr = (uint64_t) mem; auto mem_start_offset = (mem_start_addr & (alignment - 1U)); if (mem_start_offset != 0) { mem += alignment - mem_start_offset; } return true; } catch (const std::bad_alloc& excpt) { return false; } } bool HeifPixelImage::extend_padding_to_size(int width, int height) { for (auto& planeIter : m_planes) { auto* plane = &planeIter.second; int subsampled_width, subsampled_height; get_subsampled_size(width, height, planeIter.first, m_chroma, &subsampled_width, &subsampled_height); int old_width = plane->m_width; int old_height = plane->m_height; if (plane->m_mem_width < subsampled_width || plane->m_mem_height < subsampled_height) { ImagePlane newPlane; if (!newPlane.alloc(subsampled_width, subsampled_height, plane->m_bit_depth, m_chroma)) { return false; } // copy the visible part of the old plane into the new plane for (int y = 0; y < plane->m_height; y++) { memcpy(&newPlane.mem[y * newPlane.stride], &plane->mem[y * plane->stride], plane->m_width); } planeIter.second = newPlane; plane = &planeIter.second; } // extend plane size int bytes_per_pixel = (plane->m_bit_depth + 7) / 8; for (int y = 0; y < old_height; y++) { for (int x = old_width; x < subsampled_width; x++) { memcpy(&plane->mem[y * plane->stride + x * bytes_per_pixel], &plane->mem[y * plane->stride + (plane->m_width - 1) * bytes_per_pixel], bytes_per_pixel); } } for (int y = old_height; y < subsampled_height; y++) { memcpy(&plane->mem[y * plane->stride], &plane->mem[(plane->m_height - 1) * plane->stride], subsampled_width * bytes_per_pixel); } } // don't modify the logical image size return true; } bool HeifPixelImage::has_channel(heif_channel channel) const { return (m_planes.find(channel) != m_planes.end()); } bool HeifPixelImage::has_alpha() const { return has_channel(heif_channel_Alpha) || get_chroma_format() == heif_chroma_interleaved_RGBA || get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_BE || get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_LE; } int HeifPixelImage::get_width(enum heif_channel channel) const { auto iter = m_planes.find(channel); if (iter == m_planes.end()) { return -1; } return iter->second.m_width; } int HeifPixelImage::get_height(enum heif_channel channel) const { auto iter = m_planes.find(channel); if (iter == m_planes.end()) { return -1; } return iter->second.m_height; } std::set HeifPixelImage::get_channel_set() const { std::set channels; for (const auto& plane : m_planes) { channels.insert(plane.first); } return channels; } uint8_t HeifPixelImage::get_storage_bits_per_pixel(enum heif_channel channel) const { if (channel == heif_channel_interleaved) { auto chroma = get_chroma_format(); switch (chroma) { case heif_chroma_interleaved_RGB: return 24; case heif_chroma_interleaved_RGBA: return 32; case heif_chroma_interleaved_RRGGBB_BE: case heif_chroma_interleaved_RRGGBB_LE: return 48; case heif_chroma_interleaved_RRGGBBAA_BE: case heif_chroma_interleaved_RRGGBBAA_LE: return 64; default: return -1; // invalid channel/chroma specification } } else { uint32_t bpp = (get_bits_per_pixel(channel) + 7U) & ~7U; assert(bpp <= 255); return static_cast(bpp); } } uint8_t HeifPixelImage::get_bits_per_pixel(enum heif_channel channel) const { auto iter = m_planes.find(channel); if (iter == m_planes.end()) { return -1; } return iter->second.m_bit_depth; } uint8_t* HeifPixelImage::get_plane(enum heif_channel channel, int* out_stride) { auto iter = m_planes.find(channel); if (iter == m_planes.end()) { return nullptr; } if (out_stride) { *out_stride = iter->second.stride; } return iter->second.mem; } const uint8_t* HeifPixelImage::get_plane(enum heif_channel channel, int* out_stride) const { auto iter = m_planes.find(channel); if (iter == m_planes.end()) { return nullptr; } if (out_stride) { *out_stride = iter->second.stride; } return iter->second.mem; } void HeifPixelImage::copy_new_plane_from(const std::shared_ptr& src_image, heif_channel src_channel, heif_channel dst_channel) { int width = src_image->get_width(src_channel); int height = src_image->get_height(src_channel); assert(!has_channel(dst_channel)); add_plane(dst_channel, width, height, src_image->get_bits_per_pixel(src_channel)); uint8_t* dst; int dst_stride = 0; const uint8_t* src; int src_stride = 0; src = src_image->get_plane(src_channel, &src_stride); dst = get_plane(dst_channel, &dst_stride); int bpl = width * (src_image->get_storage_bits_per_pixel(src_channel) / 8); for (int y = 0; y < height; y++) { memcpy(dst + y * dst_stride, src + y * src_stride, bpl); } } void HeifPixelImage::fill_new_plane(heif_channel dst_channel, uint16_t value, int width, int height, int bpp) { add_plane(dst_channel, width, height, bpp); int num_interleaved = num_interleaved_pixels_per_plane(m_chroma); if (bpp == 8) { uint8_t* dst; int dst_stride = 0; dst = get_plane(dst_channel, &dst_stride); int width_bytes = width * num_interleaved; for (int y = 0; y < height; y++) { memset(dst + y * dst_stride, value, width_bytes); } } else { uint16_t* dst; int dst_stride = 0; dst = (uint16_t*) get_plane(dst_channel, &dst_stride); dst_stride /= 2; for (int y = 0; y < height; y++) { for (int x = 0; x < width * num_interleaved; x++) { dst[y * dst_stride + x] = value; } } } } void HeifPixelImage::transfer_plane_from_image_as(const std::shared_ptr& source, heif_channel src_channel, heif_channel dst_channel) { // TODO: check that dst_channel does not exist yet ImagePlane plane = source->m_planes[src_channel]; source->m_planes.erase(src_channel); m_planes.insert(std::make_pair(dst_channel, plane)); } bool is_chroma_with_alpha(heif_chroma chroma) { switch (chroma) { case heif_chroma_undefined: case heif_chroma_monochrome: case heif_chroma_420: case heif_chroma_422: case heif_chroma_444: case heif_chroma_interleaved_RGB: case heif_chroma_interleaved_RRGGBB_BE: case heif_chroma_interleaved_RRGGBB_LE: return false; case heif_chroma_interleaved_RGBA: case heif_chroma_interleaved_RRGGBBAA_BE: case heif_chroma_interleaved_RRGGBBAA_LE: return true; } assert(false); return false; } Error HeifPixelImage::rotate_ccw(int angle_degrees, std::shared_ptr& out_img) { // --- create output image (or simply reuse existing image) if (angle_degrees == 0) { out_img = shared_from_this(); return Error::Ok; } int out_width = m_width; int out_height = m_height; if (angle_degrees == 90 || angle_degrees == 270) { std::swap(out_width, out_height); } out_img = std::make_shared(); out_img->create(out_width, out_height, m_colorspace, m_chroma); // --- rotate all channels for (const auto& plane_pair : m_planes) { heif_channel channel = plane_pair.first; const ImagePlane& plane = plane_pair.second; /* if (plane.bit_depth != 8) { return Error(heif_error_Unsupported_feature, heif_suberror_Unspecified, "Can currently only rotate images with 8 bits per pixel"); } */ int out_plane_width = plane.m_width; int out_plane_height = plane.m_height; if (angle_degrees == 90 || angle_degrees == 270) { std::swap(out_plane_width, out_plane_height); } out_img->add_plane(channel, out_plane_width, out_plane_height, plane.m_bit_depth); int w = plane.m_width; int h = plane.m_height; int in_stride = plane.stride; const uint8_t* in_data = plane.mem; int out_stride = 0; uint8_t* out_data = out_img->get_plane(channel, &out_stride); if (plane.m_bit_depth == 8) { if (angle_degrees == 270) { for (int x = 0; x < h; x++) for (int y = 0; y < w; y++) { out_data[y * out_stride + x] = in_data[(h - 1 - x) * in_stride + y]; } } else if (angle_degrees == 180) { for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { out_data[y * out_stride + x] = in_data[(h - 1 - y) * in_stride + (w - 1 - x)]; } } else if (angle_degrees == 90) { for (int x = 0; x < h; x++) for (int y = 0; y < w; y++) { out_data[y * out_stride + x] = in_data[x * in_stride + (w - 1 - y)]; } } } else { // 16 bit (TODO: unchecked code) if (angle_degrees == 270) { for (int x = 0; x < h; x++) for (int y = 0; y < w; y++) { out_data[y * out_stride + 2 * x] = in_data[(h - 1 - x) * in_stride + 2 * y]; out_data[y * out_stride + 2 * x + 1] = in_data[(h - 1 - x) * in_stride + 2 * y + 1]; } } else if (angle_degrees == 180) { for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { out_data[y * out_stride + 2 * x] = in_data[(h - 1 - y) * in_stride + 2 * (w - 1 - x)]; out_data[y * out_stride + 2 * x + 1] = in_data[(h - 1 - y) * in_stride + 2 * (w - 1 - x) + 1]; } } else if (angle_degrees == 90) { for (int x = 0; x < h; x++) for (int y = 0; y < w; y++) { out_data[y * out_stride + 2 * x] = in_data[x * in_stride + 2 * (w - 1 - y)]; out_data[y * out_stride + 2 * x + 1] = in_data[x * in_stride + 2 * (w - 1 - y) + 1]; } } } } // --- pass the color profiles to the new image out_img->set_color_profile_nclx(get_color_profile_nclx()); out_img->set_color_profile_icc(get_color_profile_icc()); return Error::Ok; } Error HeifPixelImage::mirror_inplace(heif_transform_mirror_direction direction) { for (auto& plane_pair : m_planes) { ImagePlane& plane = plane_pair.second; if (plane.m_bit_depth != 8) { return Error(heif_error_Unsupported_feature, heif_suberror_Unspecified, "Can currently only mirror images with 8 bits per pixel"); } int w = plane.m_width; int h = plane.m_height; int stride = plane.stride; uint8_t* data = plane.mem; if (direction == heif_transform_mirror_direction_horizontal) { for (int y = 0; y < h; y++) { for (int x = 0; x < w / 2; x++) std::swap(data[y * stride + x], data[y * stride + w - 1 - x]); } } else { for (int y = 0; y < h / 2; y++) { for (int x = 0; x < w; x++) std::swap(data[y * stride + x], data[(h - 1 - y) * stride + x]); } } } return Error::Ok; } Error HeifPixelImage::crop(int left, int right, int top, int bottom, std::shared_ptr& out_img) const { out_img = std::make_shared(); out_img->create(right - left + 1, bottom - top + 1, m_colorspace, m_chroma); // --- crop all channels for (const auto& plane_pair : m_planes) { heif_channel channel = plane_pair.first; const ImagePlane& plane = plane_pair.second; if (false && plane.m_bit_depth != 8) { return Error(heif_error_Unsupported_feature, heif_suberror_Unspecified, "Can currently only crop images with 8 bits per pixel"); } int w = plane.m_width; int h = plane.m_height; int plane_left = left * w / m_width; int plane_right = right * w / m_width; int plane_top = top * h / m_height; int plane_bottom = bottom * h / m_height; out_img->add_plane(channel, plane_right - plane_left + 1, plane_bottom - plane_top + 1, plane.m_bit_depth); int in_stride = plane.stride; const uint8_t* in_data = plane.mem; int out_stride = 0; uint8_t* out_data = out_img->get_plane(channel, &out_stride); if (plane.m_bit_depth == 8) { for (int y = plane_top; y <= plane_bottom; y++) { memcpy(&out_data[(y - plane_top) * out_stride], &in_data[y * in_stride + plane_left], plane_right - plane_left + 1); } } else { for (int y = plane_top; y <= plane_bottom; y++) { memcpy(&out_data[(y - plane_top) * out_stride], &in_data[y * in_stride + plane_left * 2], (plane_right - plane_left + 1) * 2); } } } // --- pass the color profiles to the new image out_img->set_color_profile_nclx(get_color_profile_nclx()); out_img->set_color_profile_icc(get_color_profile_icc()); return Error::Ok; } Error HeifPixelImage::fill_RGB_16bit(uint16_t r, uint16_t g, uint16_t b, uint16_t a) { for (const auto& channel : {heif_channel_R, heif_channel_G, heif_channel_B, heif_channel_Alpha}) { const auto plane_iter = m_planes.find(channel); if (plane_iter == m_planes.end()) { // alpha channel is optional, R,G,B is required if (channel == heif_channel_Alpha) { continue; } return Error(heif_error_Usage_error, heif_suberror_Nonexisting_image_channel_referenced); } ImagePlane& plane = plane_iter->second; if (plane.m_bit_depth != 8) { return Error(heif_error_Unsupported_feature, heif_suberror_Unspecified, "Can currently only fill images with 8 bits per pixel"); } int h = plane.m_height; int stride = plane.stride; uint8_t* data = plane.mem; uint16_t val16; switch (channel) { case heif_channel_R: val16 = r; break; case heif_channel_G: val16 = g; break; case heif_channel_B: val16 = b; break; case heif_channel_Alpha: val16 = a; break; default: // initialization only to avoid warning of uninitialized variable. val16 = 0; // Should already be detected by the check above ("m_planes.find"). assert(false); } auto val8 = static_cast(val16 >> 8U); memset(data, val8, stride * h); } return Error::Ok; } Error HeifPixelImage::overlay(std::shared_ptr& overlay, int dx, int dy) { std::set channels = overlay->get_channel_set(); bool has_alpha = overlay->has_channel(heif_channel_Alpha); //bool has_alpha_me = has_channel(heif_channel_Alpha); int alpha_stride = 0; uint8_t* alpha_p; alpha_p = overlay->get_plane(heif_channel_Alpha, &alpha_stride); for (heif_channel channel : channels) { if (!has_channel(channel)) { continue; } int in_stride = 0; const uint8_t* in_p; int out_stride = 0; uint8_t* out_p; in_p = overlay->get_plane(channel, &in_stride); out_p = get_plane(channel, &out_stride); int in_w = overlay->get_width(channel); int in_h = overlay->get_height(channel); assert(in_w >= 0); assert(in_h >= 0); int out_w = get_width(channel); int out_h = get_height(channel); assert(out_w >= 0); assert(out_h >= 0); // overlay image extends past the right border -> cut width for copy if (dx + in_w > out_w) { in_w = out_w - dx; } // overlay image extends past the bottom border -> cut height for copy if (dy + in_h > out_h) { in_h = out_h - dy; } // overlay image completely outside right or bottom border -> do not copy if (in_w < 0 || in_h < 0) { return Error(heif_error_Invalid_input, heif_suberror_Overlay_image_outside_of_canvas, "Overlay image outside of right or bottom canvas border"); } // calculate top-left point where to start copying in source and destination int in_x0 = 0; int in_y0 = 0; int out_x0 = dx; int out_y0 = dy; // overlay image started outside of left border // -> move start into the image and start at left output column if (dx < 0) { in_x0 = -dx; out_x0 = 0; } // overlay image started outside of top border // -> move start into the image and start at top output row if (dy < 0) { in_y0 = -dy; out_y0 = 0; } // if overlay image is completely outside at left border, do not copy anything. if (in_w <= in_x0 || in_h <= in_y0) { return Error(heif_error_Invalid_input, heif_suberror_Overlay_image_outside_of_canvas, "Overlay image outside of left or top canvas border"); } for (int y = in_y0; y < in_h; y++) { if (!has_alpha) { memcpy(out_p + out_x0 + (out_y0 + y - in_y0) * out_stride, in_p + in_x0 + y * in_stride, in_w - in_x0); } else { for (int x = in_x0; x < in_w; x++) { uint8_t* outptr = &out_p[out_x0 + (out_y0 + y - in_y0) * out_stride + x]; uint8_t in_val = in_p[in_x0 + y * in_stride + x]; uint8_t alpha_val = alpha_p[in_x0 + y * in_stride + x]; *outptr = (uint8_t) ((in_val * alpha_val + *outptr * (255 - alpha_val)) / 255); } } } } return Error::Ok; } Error HeifPixelImage::scale_nearest_neighbor(std::shared_ptr& out_img, int width, int height) const { out_img = std::make_shared(); out_img->create(width, height, m_colorspace, m_chroma); // --- create output image with scaled planes if (has_channel(heif_channel_interleaved)) { out_img->add_plane(heif_channel_interleaved, width, height, get_bits_per_pixel(heif_channel_interleaved)); } else { if (get_colorspace() == heif_colorspace_RGB) { if (!has_channel(heif_channel_R) || !has_channel(heif_channel_G) || !has_channel(heif_channel_B)) { return Error(heif_error_Invalid_input, heif_suberror_Unspecified, "RGB input without R,G,B, planes"); } out_img->add_plane(heif_channel_R, width, height, get_bits_per_pixel(heif_channel_R)); out_img->add_plane(heif_channel_G, width, height, get_bits_per_pixel(heif_channel_G)); out_img->add_plane(heif_channel_B, width, height, get_bits_per_pixel(heif_channel_B)); } else if (get_colorspace() == heif_colorspace_monochrome) { if (!has_channel(heif_channel_Y)) { return Error(heif_error_Invalid_input, heif_suberror_Unspecified, "monochrome input with no Y plane"); } out_img->add_plane(heif_channel_Y, width, height, get_bits_per_pixel(heif_channel_Y)); } else if (get_colorspace() == heif_colorspace_YCbCr) { if (!has_channel(heif_channel_Y) || !has_channel(heif_channel_Cb) || !has_channel(heif_channel_Cr)) { return Error(heif_error_Invalid_input, heif_suberror_Unspecified, "YCbCr image without Y,Cb,Cr planes"); } int cw, ch; get_subsampled_size(width, height, heif_channel_Cb, get_chroma_format(), &cw, &ch); out_img->add_plane(heif_channel_Y, width, height, get_bits_per_pixel(heif_channel_Y)); out_img->add_plane(heif_channel_Cb, cw, ch, get_bits_per_pixel(heif_channel_Cb)); out_img->add_plane(heif_channel_Cr, cw, ch, get_bits_per_pixel(heif_channel_Cr)); } else { return Error(heif_error_Invalid_input, heif_suberror_Unspecified, "unknown color configuration"); } if (has_channel(heif_channel_Alpha)) { out_img->add_plane(heif_channel_Alpha, width, height, get_bits_per_pixel(heif_channel_Alpha)); } } // --- scale all channels for (const auto& plane_pair : m_planes) { heif_channel channel = plane_pair.first; const ImagePlane& plane = plane_pair.second; const int bpp = get_storage_bits_per_pixel(channel) / 8; if (!out_img->has_channel(channel)) { return Error(heif_error_Invalid_input, heif_suberror_Unspecified, "scaling input has extra color plane"); } int out_w = out_img->get_width(channel); int out_h = out_img->get_height(channel); int in_stride = plane.stride; const uint8_t* in_data = plane.mem; int out_stride = 0; uint8_t* out_data = out_img->get_plane(channel, &out_stride); for (int y = 0; y < out_h; y++) { int iy = y * m_height / height; if (bpp == 1) { for (int x = 0; x < out_w; x++) { int ix = x * m_width / width; out_data[y * out_stride + x] = in_data[iy * in_stride + ix]; } } else { for (int x = 0; x < out_w; x++) { int ix = x * m_width / width; for (int b = 0; b < bpp; b++) { out_data[y * out_stride + bpp * x + b] = in_data[iy * in_stride + bpp * ix + b]; } } } } } return Error::Ok; } void HeifPixelImage::debug_dump() const { auto channels = get_channel_set(); for (auto c : channels) { int stride = 0; const uint8_t* p = get_plane(c, &stride); for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { printf("%02x ", p[y * stride + x]); } printf("\n"); } } } libheif-1.17.6/libheif/heif_plugin.cc000664 001750 001750 00000002722 14540541202 020512 0ustar00farindkfarindk000000 000000 /* * HEIF codec. * Copyright (c) 2017 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #include "heif.h" #include "heif_plugin.h" // needed to avoid 'unresolved symbols' on Visual Studio compiler struct heif_error heif_error_ok = {heif_error_Ok, heif_suberror_Unspecified, "Success"}; struct heif_error heif_error_unsupported_parameter = {heif_error_Usage_error, heif_suberror_Unsupported_parameter, "Unsupported encoder parameter"}; struct heif_error heif_error_invalid_parameter_value = {heif_error_Usage_error, heif_suberror_Invalid_parameter_value, "Invalid parameter value"}; libheif-1.17.6/libheif/mask_image.h000664 001750 001750 00000005054 14540541202 020161 0ustar00farindkfarindk000000 000000 /* * HEIF mask image codec. * * Copyright (c) 2023 Dirk Farin * Copyright (c) 2023 Brad Hards * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #ifndef LIBHEIF_MASK_IMAGE_H #define LIBHEIF_MASK_IMAGE_H #include "box.h" #include "bitstream.h" #include "pixelimage.h" #include "file.h" #include "context.h" #include #include #include /** * Mask Configuration Property (mskC). * * Each mask image item (mski) shall have an associated MaskConfigurationProperty * that provides information required to generate the mask of the associated mask * item. */ class Box_mskC : public FullBox { public: Box_mskC() { set_short_type(fourcc("mskC")); } std::string dump(Indent&) const override; Error write(StreamWriter& writer) const override; uint8_t get_bits_per_pixel() const { return m_bits_per_pixel; } void set_bits_per_pixel(uint8_t bits_per_pixel) { m_bits_per_pixel = bits_per_pixel; } protected: Error parse(BitstreamRange& range) override; private: uint8_t m_bits_per_pixel; }; class MaskImageCodec { public: static Error decode_mask_image(const std::shared_ptr& heif_file, heif_item_id ID, std::shared_ptr& img, uint32_t maximum_image_width_limit, uint32_t maximum_image_height_limit, const std::vector& data); static Error encode_mask_image(const std::shared_ptr& heif_file, const std::shared_ptr& src_image, void* encoder_struct, const struct heif_encoding_options& options, std::shared_ptr& out_image); }; #endif //LIBHEIF_MASK_IMAGE_H libheif-1.17.6/libheif/vvc.h000664 001750 001750 00000004615 14540541202 016664 0ustar00farindkfarindk000000 000000 /* * HEIF VVC codec. * Copyright (c) 2023 Dirk Farin * * This file is part of libheif. * * libheif is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libheif is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libheif. If not, see . */ #ifndef LIBHEIF_VVC_H #define LIBHEIF_VVC_H #include "box.h" #include #include class Box_vvcC : public Box { public: Box_vvcC() { set_short_type(fourcc("vvcC")); } struct configuration { uint8_t configurationVersion = 1; uint16_t avgFrameRate_times_256; uint8_t constantFrameRate; uint8_t numTemporalLayers; uint8_t lengthSize; bool ptl_present_flag; //if (ptl_present_flag) { // VvcPTLRecord(numTemporalLayers) track_ptl; // uint16_t output_layer_set_idx; //} bool chroma_format_present_flag; uint8_t chroma_format_idc; bool bit_depth_present_flag; uint8_t bit_depth; uint8_t numOfArrays; #if 0 for (j=0; j < numOfArrays; j++) { unsigned int(1) array_completeness; bit(1) reserved = 0; unsigned int(6) NAL_unit_type; unsigned int(16) numNalus; for (i=0; i< numNalus; i++) { unsigned int(16) nalUnitLength; bit(8*nalUnitLength) nalUnit; } } #endif }; std::string dump(Indent&) const override; bool get_headers(std::vector* dest) const { *dest = m_config_NALs; return true; } void set_configuration(const configuration& config) { m_configuration = config; } const configuration& get_configuration() const { return m_configuration; } //void append_nal_data(const std::vector& nal); //void append_nal_data(const uint8_t* data, size_t size); Error write(StreamWriter& writer) const override; protected: Error parse(BitstreamRange& range) override; private: configuration m_configuration; std::vector m_config_NALs; }; #endif // LIBHEIF_VVC_H libheif-1.17.6/libheif/Doxyfile.in000664 001750 001750 00000343456 14540541202 020041 0ustar00farindkfarindk000000 000000 # Doxyfile 1.9.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the configuration # file that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "libheif" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/apidoc/ # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all generated output in the proper direction. # Possible values are: None, LTR, RTL and Context. # The default value is: None. OUTPUT_TEXT_DIRECTION = None # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = YES # If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line # such as # /*************** # as being the beginning of a Javadoc-style comment "banner". If set to NO, the # Javadoc-style will behave just like regular comments and it will not be # interpreted by doxygen. # The default value is: NO. JAVADOC_BANNER = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # By default Python docstrings are displayed as preformatted text and doxygen's # special commands cannot be used. By setting PYTHON_DOCSTRING to NO the # doxygen's special commands can be used and the contents of the docstring # documentation blocks is shown as doxygen documentation. # The default value is: YES. PYTHON_DOCSTRING = YES # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines (in the resulting output). You can put ^^ in the value part of an # alias to insert a newline as if a physical newline was in the original file. # When you need a literal { or } or , in the value part of an alias you have to # escape them by means of a backslash (\), this can lead to conflicts with the # commands \{ and \} for these it is advised to use the version @{ and @} or use # a double escape (\\{ and \\}) ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice # sources only. Doxygen will then generate output that is more tailored for that # language. For instance, namespaces will be presented as modules, types will be # separated into more groups, etc. # The default value is: NO. OPTIMIZE_OUTPUT_SLICE = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, # Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the # default for Fortran type files). For instance to make doxygen treat .inc files # as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. When specifying no_extension you should add # * to the FILE_PATTERNS. # # Note see also the list of default file extension mappings. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 5 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 # The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use # during processing. When set to 0 doxygen will based this on the number of # cores available in the system. You can set it explicitly to a value larger # than 0 to get more control over the balance between CPU load and processing # speed. At this moment only the input processing can be done using multiple # threads. Since this is still an experimental feature the default is set to 1, # which efficively disables parallel processing. Please report any issues you # encounter. Generating dot graphs in parallel is controlled by the # DOT_NUM_THREADS setting. # Minimum value: 0, maximum value: 32, default value: 1. NUM_PROC_THREADS = 1 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. EXTRACT_PRIV_VIRTUAL = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If this flag is set to YES, the name of an unnamed parameter in a declaration # will be determined by the corresponding definition. By default unnamed # parameters remain unnamed in the output. # The default value is: YES. RESOLVE_UNNAMED_PARAMS = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # declarations. If set to NO, these declarations will be included in the # documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # With the correct setting of option CASE_SENSE_NAMES doxygen will better be # able to match the capabilities of the underlying filesystem. In case the # filesystem is case sensitive (i.e. it supports files in the same directory # whose names only differ in casing), the option must be set to YES to properly # deal with such files in case they appear in the input. For filesystems that # are not case sensitive the option should be be set to NO to properly deal with # output files written for symbols that only differ in casing, such as for two # classes, one named CLASS and the other named Class, and to also support # references to files without having to specify the exact matching casing. On # Windows (including Cygwin) and MacOS, users should typically set this option # to NO, whereas on Linux or other Unix flavors it should typically be set to # YES. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. If # EXTRACT_ALL is set to YES then this flag will automatically be disabled. # The default value is: NO. WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS # then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but # at the end of the doxygen process doxygen will return with a non-zero status. # Possible values are: NO, YES and FAIL_ON_WARNINGS. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = @CMAKE_CURRENT_SOURCE_DIR@/libheif/heif.h \ @CMAKE_CURRENT_SOURCE_DIR@/libheif/heif_regions.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: # https://www.gnu.org/software/libiconv/) for the list of possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # Note the list of default checked file patterns might differ from the list of # default file extension mappings. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), # *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl, # *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.idl \ *.ddl \ *.odl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.cs \ *.d \ *.php \ *.php4 \ *.php5 \ *.phtml \ *.inc \ *.m \ *.markdown \ *.md \ *.mm \ *.dox \ *.py \ *.pyw \ *.f90 \ *.f95 \ *.f03 \ *.f08 \ *.f18 \ *.f \ *.for \ *.vhd \ *.vhdl \ *.ucf \ *.qsf \ *.ice # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: # http://clang.llvm.org/) for more accurate parsing at the cost of reduced # performance. This can be particularly helpful with template rich C++ code for # which doxygen's built-in parser lacks the necessary type information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to # YES then doxygen will add the directory of each input to the include path. # The default value is: YES. CLANG_ADD_INC_PATHS = YES # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = # If clang assisted parsing is enabled you can provide the clang parser with the # path to the directory containing a file called compile_commands.json. This # file is the compilation database (see: # http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the # options used when the source files were built. This is equivalent to # specifying the -p option to a clang tool, such as clang-check. These options # will then be passed to the parser. Any options specified with CLANG_OPTIONS # will be added as well. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. CLANG_DATABASE_PATH = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML # page. Disable this option to support browsers that do not have JavaScript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_MENUS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: # https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To # create a documentation set, doxygen will generate a Makefile in the HTML # output directory. Running make will produce the docset in that directory and # running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy # genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: # https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location (absolute path # including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to # run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg # tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see # https://inkscape.org) to generate formulas as SVG images instead of PNGs for # the HTML output. These images will generally look nicer at scaled resolutions. # Possible values are: png (the default) and svg (looks nicer but requires the # pdf2svg or inkscape tool). # The default value is: png. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FORMULA_FORMAT = png # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands # to create new LaTeX commands to be used in formulas as building blocks. See # the section "Including formulas" for details. FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from https://www.mathjax.org before deployment. # The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: # http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /