fotoxx-12.01.2/0000775000175000017500000000000011701011017011633 5ustar micomicofotoxx-12.01.2/fotoxx-12.01.2.spec0000644000175000017500000000262211701011017014635 0ustar micomico# RPM spec file for fotoxx # ufraw, exiftool, xdg-open: needed for execution but not for build. Name: fotoxx Version: 12.01.2 Release: 1 Summary: photo editor and collection manager Vendor: kornelix Packager: kornelix2@googlemail.com License: GPL3 Group: Graphics/Photography Source: %{name}-%{version}.tar.gz URL: http://kornelix.squarespace.com/%{name} %description Navigate your image collection using a thumbnail browser. View and edit images. Convert RAW files to TIFF and edit with 16-bit color. Edit a selected area or object within an image. Edit using movable curves with fast full-screen feedback. Adjust brightness, color, contrast, gamma. Perform tone mapping, trim, rescale, rotate, warp, sharpen, blur. Reduce noise, fix red-eyes, erase power lines, fix perspective. Make composite images: HDR, HDF, stack, and panorama. Annotate images. Make artful transforms. Do a slide show. Create named collections. Burn a CD or DVD. Edit tags, comments, captions, dates and star-ratings. Search images using these criteria plus directory and file names. %prep %setup -q %build make %install make install PREFIX=$RPM_BUILD_ROOT/usr %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) /usr/bin/%{name} /usr/share/%{name} /usr/share/doc/%{name} /usr/share/applications/kornelix-%{name}.desktop /usr/share/man/man1/%{name}.1.gz fotoxx-12.01.2/Makefile0000644000175000017500000000462511701011017013300 0ustar micomico# fotoxx makefile VERSION = 12.01.2.cc # defaults for parameters that may be pre-defined CXXFLAGS ?= -O3 -g -Wall LDFLAGS ?= -O3 -g -Wall -rdynamic PREFIX ?= /usr # target install directories BINDIR = $(PREFIX)/bin SHAREDIR = $(PREFIX)/share/fotoxx ICONDIR = $(SHAREDIR)/icons LOCALESDIR = $(SHAREDIR)/locales DOCDIR = $(PREFIX)/share/doc/fotoxx MANDIR = $(PREFIX)/share/man/man1 MENUFILE = $(PREFIX)/share/applications/kornelix-fotoxx.desktop CFLAGS = $(CXXFLAGS) -c `pkg-config --cflags gtk+-2.0` LIBS = `pkg-config --libs gtk+-2.0` fotoxx: fotoxx.o f.file.o f.tools.o f.select.o f.info.o f.retouch.o \ f.transform.o f.art.o f.comp.o f.navi.o zfuncs.o $(CXX) $(LDFLAGS) -o fotoxx fotoxx.o f.file.o f.tools.o f.select.o f.info.o \ f.retouch.o f.transform.o f.art.o f.comp.o f.navi.o zfuncs.o \ $(LIBS) -ltiff @ ./dependencies.sh fotoxx.o: fotoxx-$(VERSION) fotoxx.h $(CXX) $(CFLAGS) -o fotoxx.o fotoxx-$(VERSION) f.file.o: f.file.cc fotoxx.h $(CXX) $(CFLAGS) f.file.cc f.tools.o: f.tools.cc fotoxx.h $(CXX) $(CFLAGS) f.tools.cc f.select.o: f.select.cc fotoxx.h $(CXX) $(CFLAGS) f.select.cc f.info.o: f.info.cc fotoxx.h $(CXX) $(CFLAGS) f.info.cc f.retouch.o: f.retouch.cc fotoxx.h $(CXX) $(CFLAGS) f.retouch.cc f.transform.o: f.transform.cc fotoxx.h $(CXX) $(CFLAGS) f.transform.cc f.art.o: f.art.cc fotoxx.h $(CXX) $(CFLAGS) f.art.cc f.comp.o: f.comp.cc fotoxx.h $(CXX) $(CFLAGS) f.comp.cc f.navi.o: f.navi.cc fotoxx.h $(CXX) $(CFLAGS) f.navi.cc zfuncs.o: zfuncs.cc $(CXX) $(CFLAGS) zfuncs.cc -D PREFIX=\"$(PREFIX)\" install: fotoxx mkdir -p $(DESTDIR)$(BINDIR) mkdir -p $(DESTDIR)$(ICONDIR) mkdir -p $(DESTDIR)$(LOCALESDIR) mkdir -p $(DESTDIR)$(DOCDIR) mkdir -p $(DESTDIR)$(MANDIR) mkdir -p $(DESTDIR)$(PREFIX)/share/applications cp -f fotoxx $(DESTDIR)$(BINDIR) cp -f icons/* $(DESTDIR)$(ICONDIR) cp -f locales/* $(DESTDIR)$(LOCALESDIR) cp -f -R doc/* $(DESTDIR)$(DOCDIR) # man page cp -f doc/fotoxx.man fotoxx.1 gzip -f -9 fotoxx.1 cp fotoxx.1.gz $(DESTDIR)$(MANDIR) rm -f fotoxx.1.gz # menu (desktop) file cp -f desktop $(DESTDIR)$(MENUFILE) xdg-desktop-menu install $(DESTDIR)$(MENUFILE) uninstall: rm -f $(DESTDIR)$(BINDIR)/fotoxx rm -R -f $(DESTDIR)$(SHAREDIR) rm -R -f $(DESTDIR)$(DOCDIR) rm -f $(DESTDIR)$(MANDIR)/fotoxx.1.gz xdg-desktop-menu uninstall $(DESTDIR)$(MENUFILE) rm -f $(DESTDIR)$(MENUFILE) clean: rm -f fotoxx rm -f *.o fotoxx-12.01.2/f.navi.cc0000664000175000017500000021311711701011017013330 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image edit - functions for navigation of image files **************************************************************************/ GtkWidget *wing = 0, *vboxx, *scrwing, *layout; // image gallery and drawing windows GtkWidget *pwing = 0; // parent window GtkAdjustment *scrollbar; GdkGC *gdkgc2 = 0; // graphics context namespace image_navi { #define thumbnail_cachesize 10000 // max thumbnails cached in memory #define imagetypes ".jpeg .jpg .png .tif .tiff .bmp .gif .svg .xpm" // supported image file types #define TEXTWIN GTK_TEXT_WINDOW_TEXT // GDK window of GTK text view #define NODITHER GDK_RGB_DITHER_NONE #define SCROLLWIN GTK_SCROLLED_WINDOW #define NEVER GTK_POLICY_NEVER #define ALWAYS GTK_POLICY_ALWAYS #define interp GDK_INTERP_BILINEAR #define colorspace GDK_COLORSPACE_RGB int thumbfilesize = 256; // default thumbnail image size #define thumbxx 6 // thumbx array size int thumbx[6] = { 512, 360, 256, 180, 128, 90 }; // thumbnail image step sizes char *galleryname = 0; // image directory or file list name int gallerytype = 0; // 1/2/3 = directory/file-list/metadata int nfiles = 0; // total file count (incl. subdirks) int nimages = 0; // image file count char **flist = 0; // image file list char **mdlist = 0; // corresp. metadata typedef void ufunc(int Nth, int button); // callback function for clicked image ufunc *userfunc; int xwinW = 1000, xwinH = 700; // gallery window initial size int xwinX, xwinY; // gallery window initial position int thumbsize = thumbfilesize; // thumbnail image <= thumbnail file int thumbW, thumbH; // gallery window thumbnail cell size int xrows, xcols; // gallery window thumbnail rows, cols int margin = 5; // cell margin from left and top edge int genthumbs = 0; // count newly generated thumbnails int scrollposn; // gallery window scroll position int maxscroll; // max. scroll position int fpresent = 0; // force gallery window to z-top int targposn = 0; // scroll-to file position (Nth) // private functions int gallery_paint(GtkWidget *, GdkEventExpose *); // gallery window paint function int gallery_paint_metadata(GdkEventExpose *expose); // "" for metadata report void draw_text(GtkWidget *win, char *text, int x, int y, int ww); // draw text in gallery window void gallery_destroy(); // gallery window destroy event function void menufuncx(GtkWidget *win, cchar *menu); // function for gallery window buttons void mouse_xevent(GtkWidget *, GdkEventButton *, void *); // gallery window mouse event function int KBxpress(GtkWidget *, GdkEventKey *, void *); // gallery window key press event func. int KBxrelease(GtkWidget *, GdkEventKey *, void *); // gallery window key release event char * image_navigate(cchar *filez, cchar *action, int Nth = 0); // image file list setup and navigate int image_fcomp(cchar *file1, cchar *file2); // file name compare (special sort) } /************************************************************************** public function to create/update image gallery (thumbnail window) // overhauled Make window scrolling window of thumbnails for a list of files Handle window buttons (up row, down page, open file, etc.) Call ufunc() when thumbnail image is clicked char * image_gallery(cchar *filez, cchar *action, int Nth, void ufunc(int Nth, int button), GtkWidget *parent) filez: image file or directory of image files or file with list of image files action: init: filez = initial file or directory initF: filez = file with list of image files to use sort: sort the file list, directories first, ignore case insert: insert filez into file list at position Nth (0 to last+1) delete: delete Nth file in list find: return Nth file (0 base) or null if Nth > last paint1: create or refresh gallery window, anchor = Nth file paint2: refresh gallery window if present, anchor = Nth file close close gallery window Nth: file to return (action = find) or file to scroll-to (action = paint) void ufunc(int Nth, int button): - returns Nth of clicked thumbnail (0 to last) - returns -1 if gallery window is closed - returns -2 if key F1 is pressed (for context help) - button is mouse button used on clicked thumbnail parent: optional parent window if present, gallery window will overlay the parent window (window placement can be undone by the user) Returned values: Nth: filespec, others: null The returned file belongs to caller and is subject for zfree(). ***************************************************************************/ char * image_gallery(cchar *filez, cchar *action, int Nth, void ufunc(int Nth, int button), GtkWidget *parent) { using namespace image_navi; GtkWidget *tbarx; zthreadcrash(); // thread usage not allowed if (ufunc) userfunc = ufunc; // save callback function if (parent) pwing = parent; // save parent window if (strstr("init initF sort insert delete find",action)) return image_navigate(filez,action,Nth); // create or navigate image file list if (strEqu(action,"close")) { if (wing) gtk_widget_destroy(wing); return 0; } if (! strnEqu(action,"paint",5)) // must be paint1 or paint2 zappcrash("image_gallery action: %s",action); if (strEqu(action,"paint2") && ! wing) return 0; // refresh but window not active if (strEqu(action,"paint1")) fpresent++; // bring window to z-top if (Nth >= 0) targposn = Nth; // scroll-to file position else if (filez) targposn = image_gallery_position(filez,0); // or use filez if present if (targposn > nfiles-1) targposn = nfiles-1; // (-1 for no change) if (wing) { // repaint existing gallery window gallery_paint(0,0); return 0; } wing = gtk_window_new(GTK_WINDOW_TOPLEVEL); // create new gallery window if (pwing) { gtk_window_get_size(GTK_WINDOW(pwing),&xwinW,&xwinH); // overlay parent window gtk_window_get_position(GTK_WINDOW(pwing),&xwinX,&xwinY); gtk_window_set_default_size(GTK_WINDOW(wing),xwinW,xwinH); gtk_window_move(GTK_WINDOW(wing),xwinX,xwinY); } else { gtk_window_set_default_size(GTK_WINDOW(wing),xwinW,xwinH+56); // + toolbar size to stop shrinkage gtk_window_set_position(GTK_WINDOW(wing),GTK_WIN_POS_MOUSE); } vboxx = gtk_vbox_new(0,0); // vertical packing box gtk_container_add(GTK_CONTAINER(wing),vboxx); // add to main window tbarx = create_toolbar(vboxx,24); // add toolbar and buttons gtk_toolbar_set_style(GTK_TOOLBAR(tbarx),GTK_TOOLBAR_BOTH); add_toolbar_button(tbarx, ZTX("bigger"), ZTX("increase thumbnail size"), "gtk-zoom-in", menufuncx); add_toolbar_button(tbarx, ZTX("smaller"), ZTX("reduce thumbnail size"), "gtk-zoom-out", menufuncx); add_toolbar_button(tbarx, ZTX("parent"), ZTX("parent directory"), "folder.png", menufuncx); add_toolbar_button(tbarx, ZTX("first page"), ZTX("jump to first file"), "first-page.png", menufuncx); add_toolbar_button(tbarx, ZTX("prev page"), ZTX("previous page"), "prev-page.png", menufuncx); add_toolbar_button(tbarx, ZTX("prev row"), ZTX("previous row"), "prev-row.png", menufuncx); add_toolbar_button(tbarx, ZTX("next row"), ZTX("next row"), "next-row.png", menufuncx); add_toolbar_button(tbarx, ZTX("next page"), ZTX("ttip::next page"), "next-page.png", menufuncx); add_toolbar_button(tbarx, ZTX("last page"), ZTX("jump to last file"), "last-page.png", menufuncx); add_toolbar_button(tbarx, ZTX("close"), ZTX("close image gallery"), "gtk-close", menufuncx); gtk_toolbar_set_style(GTK_TOOLBAR(tbarx),GTK_TOOLBAR_BOTH); // set toolbar style v.12.01 if (strEqu(tbar_style,"icons")) gtk_toolbar_set_style(GTK_TOOLBAR(tbarx),GTK_TOOLBAR_ICONS); if (strEqu(tbar_style,"text")) gtk_toolbar_set_style(GTK_TOOLBAR(tbarx),GTK_TOOLBAR_TEXT); scrwing = gtk_scrolled_window_new(0,0); // create scrolled window gtk_container_add(GTK_CONTAINER(vboxx),scrwing); // add to main window layout = gtk_layout_new(0,0); // create drawing window gtk_layout_set_size(GTK_LAYOUT(layout),xwinW,xwinH); // initial size v.12.01 gtk_container_add(GTK_CONTAINER(scrwing),layout); // add to scrolled window gtk_scrolled_window_set_policy(SCROLLWIN(scrwing),NEVER,ALWAYS); // vertical scroll bar scrollbar = gtk_layout_get_vadjustment(GTK_LAYOUT(layout)); G_SIGNAL(wing,"destroy",gallery_destroy,0); // connect window events G_SIGNAL(layout,"expose-event",gallery_paint,0); gtk_widget_add_events(layout,GDK_BUTTON_PRESS_MASK); // connect mouse events G_SIGNAL(layout,"button-press-event",mouse_xevent,0); G_SIGNAL(wing,"key-press-event",KBxpress,0); // connect KB events G_SIGNAL(wing,"key-release-event",KBxrelease,0); gtk_widget_show_all(wing); // show all widgets gdkgc2 = gdk_gc_new(layout->window); // initz. graphics context gallery_paint(0,0); // repaint gtk_window_present(GTK_WINDOW(wing)); // bring gallery window to top zmainloop(); return 0; } // expose event private function // paint gallery window - draw all thumbnail images that can fit int image_navi::gallery_paint(GtkWidget *, GdkEventExpose *expose) { using namespace image_navi; GdkPixbuf *pxbT; GdkRectangle rect; int ii, nrows, row1, row2; int currscrollposn; int layoutW, layoutH; int expy1, expy2, row, col; int thumx, thumy, orgx, orgy, ww, hh; int stat, popup = 0; char *pp, *fname; char wintitle[200]; char filep0; if (gallerytype == 3) { stat = gallery_paint_metadata(expose); // v.12.01 return stat; } xwinW = layout->allocation.width; // curr. gallery window size xwinH = layout->allocation.height; thumbW = thumbsize + 10; // thumbnail cell size thumbH = thumbsize + 30; if (! thumbsize) { thumbW = 400; // zero, list view thumbH = 20; } xrows = int(0.2 + 1.0 * xwinH / thumbH); // get thumbnail rows and cols that xcols = int(0.3 + 1.0 * xwinW / thumbW); // (almost) fit in window if (xrows < 1) xrows = 1; if (xcols < 1) xcols = 1; nrows = (nfiles+xcols-1) / xcols; // thumbnail rows, 1 or more if (nrows < 1) nrows = 1; // bugfix layoutW = xcols * thumbW + margin + 10; // layout size for entire file list layoutH = (nrows+1) * thumbH + margin; // last row + 1 if (layoutH < xwinH) layoutH = xwinH; // bugfix gtk_layout_set_size(GTK_LAYOUT(layout),layoutW,layoutH); maxscroll = layoutH - xwinH; // scroll to end of layout if (maxscroll < 0) maxscroll = 0; gtk_adjustment_set_step_increment(scrollbar,thumbH); // scrollbar works in row steps gtk_adjustment_set_page_increment(scrollbar,thumbH * xrows); // and in page steps currscrollposn = gtk_adjustment_get_value(scrollbar); // current scroll position scrollposn = currscrollposn; if (targposn >= 0) { scrollposn = targposn / xcols * thumbH; // set initial scroll position from if (scrollposn > maxscroll) scrollposn = maxscroll; // target file position if defined, scrollposn = scrollposn / thumbH * thumbH; // then disable it for local control } // of scrolling from gallery window targposn = -1; if (scrollposn > maxscroll) scrollposn = maxscroll; // bugfix if (scrollposn != currscrollposn) gtk_adjustment_set_value(scrollbar,scrollposn); // will cause re-entrance if (! expose) // initial window or navigation button { snprintf(wintitle,199,"%s %d files",galleryname,nfiles); // window title: gallery name and file count gtk_window_set_title(GTK_WINDOW(wing),wintitle); gdk_window_invalidate_rect(wing->window,0,1); // will cause re-entrance if (fpresent) gtk_window_present(GTK_WINDOW(wing)); // bring window to top zmainloop(); fpresent = 0; return 0; } rect = expose->area; // exposed area to refresh expy1 = rect.y; expy2 = expy1 + rect.height; row1 = expy1 / thumbH; row2 = expy2 / thumbH; ii = row1 * xcols; // 1st image file in top row if (ii >= nfiles) return 1; for (row = row1; row <= row2; row++) // draw file thumbnails for (col = 0; col < xcols; col++) { if (genthumbs == 1 && ! popup) { // inform user of delay write_popup_text("open","please wait",200,10,wing); write_popup_text("write","\n generating thumbnails"); // 1st pass gtk bug, no text //// genthumbs = 2; popup = 1; } if (genthumbs < 5) zmainloop(); // mysterious, necessary //// thumx = col * thumbW + margin; // upper left corner in window space thumy = row * thumbH + margin; filep0 = *flist[ii]; *flist[ii] = '/'; // get filespec, replace ! with / if (thumy < expy2 && thumy+14 > expy1) { // if in exposed area, pp = (char *) strrchr(flist[ii],'/'); // draw file name if (pp) fname = pp + 1; else fname = flist[ii]; draw_text(layout,fname,thumx,thumy,thumbW-5); } if (thumbsize) // zero >> list view pxbT = image_thumbnail(flist[ii],thumbsize); // get thumbnail else pxbT = 0; *flist[ii] = filep0; // restore posn. 0 bugfix v.12.01 if (pxbT) { thumy = thumy + 16; // thumbnail 16 pixels down from text orgx = 0; orgy = 0; ww = gdk_pixbuf_get_width(pxbT); hh = gdk_pixbuf_get_height(pxbT); if (thumy < expy1) { orgy = orgy + (expy1 - thumy); hh = hh - (expy1 - thumy); } if (thumy + orgy + hh > expy2) hh = hh - (thumy + orgy + hh - expy2); if (orgy >= 0 && hh > 0) gdk_draw_pixbuf(GTK_LAYOUT(layout)->bin_window,0,pxbT, orgx,orgy,thumx+orgx,thumy+orgy,ww,hh,NODITHER,0,0); g_object_unref(pxbT); } if (++ii == nfiles) goto thumbsdone; // EOL } thumbsdone: if (popup) { write_popup_text("close"); genthumbs = 0; } return 1; } // expose event private function for metadata gallery report // paint gallery window - draw all thumbnail images that can fit int image_navi::gallery_paint_metadata(GdkEventExpose *expose) // v.12.01 { using namespace image_navi; GdkPixbuf *pxbT; GdkRectangle rect; int ii, nrows, row1, row2; int currscrollposn; int layoutW, layoutH; int expy1, expy2, row, col; int thumx, thumy, orgx, orgy, ww, hh; int popup = 0, textww; char wintitle[200]; xwinW = layout->allocation.width; // curr. gallery window size xwinH = layout->allocation.height; if (thumbsize < 64) thumbsize = 64; thumbW = thumbsize + 10; // thumbnail layout size thumbH = thumbsize + 20; xrows = int(0.2 + 1.0 * xwinH / thumbH); // get thumbnail rows fitting in window if (xrows < 1) xrows = 1; xcols = 1; // force cols = 1 nrows = nfiles; // thumbnail rows layoutW = xwinW; // layout size for entire file list if (layoutW < 800) layoutW = 800; layoutH = (nrows+1) * thumbH + margin; // last row + 1 if (layoutH < xwinH) layoutH = xwinH; gtk_layout_set_size(GTK_LAYOUT(layout),layoutW,layoutH); textww = layoutW - thumbW - 2 * margin; // space for text right of thumbnail maxscroll = layoutH - xwinH; // scroll to end of layout if (maxscroll < 0) maxscroll = 0; gtk_adjustment_set_step_increment(scrollbar,thumbH); // scrollbar works in row steps gtk_adjustment_set_page_increment(scrollbar,thumbH * xrows); // and in page steps currscrollposn = gtk_adjustment_get_value(scrollbar); // current scroll position scrollposn = currscrollposn; if (targposn >= 0) { scrollposn = targposn / xcols * thumbH; // set initial scroll position from if (scrollposn > maxscroll) scrollposn = maxscroll; // target file position if defined, scrollposn = scrollposn / thumbH * thumbH; // then disable it for local control } // of scrolling from gallery window targposn = -1; if (scrollposn > maxscroll) scrollposn = maxscroll; if (scrollposn != currscrollposn) gtk_adjustment_set_value(scrollbar,scrollposn); // will cause re-entrance if (! expose) // initial window or navigation button { snprintf(wintitle,199,"%s %d files",galleryname,nfiles); // window title: gallery name and file count gtk_window_set_title(GTK_WINDOW(wing),wintitle); gdk_window_invalidate_rect(wing->window,0,1); // will cause re-entrance if (fpresent) gtk_window_present(GTK_WINDOW(wing)); // bring window to top zmainloop(); fpresent = 0; return 0; } rect = expose->area; // exposed area to refresh expy1 = rect.y; expy2 = expy1 + rect.height; row1 = expy1 / thumbH; row2 = expy2 / thumbH; ii = row1 * xcols; // 1st image file in top row if (ii >= nfiles) return 1; for (row = row1; row <= row2; row++) // draw file thumbnails for (col = 0; col < xcols; col++) { if (genthumbs == 1 && ! popup) { // inform user of delay write_popup_text("open","please wait",200,10,wing); write_popup_text("write","\n generating thumbnails"); // 1st pass gtk bug, no text //// genthumbs = 2; popup = 1; } if (genthumbs < 5) zmainloop(); // mysterious, necessary //// thumx = col * thumbW + margin; // upper left corner in window space thumy = row * thumbH + margin; pxbT = image_thumbnail(flist[ii],thumbsize); // get thumbnail if (pxbT) { orgx = 0; orgy = 0; ww = gdk_pixbuf_get_width(pxbT); hh = gdk_pixbuf_get_height(pxbT); if (thumy < expy1) { // position in layout orgy = orgy + (expy1 - thumy); hh = hh - (expy1 - thumy); } if (thumy + orgy + hh > expy2) hh = hh - (thumy + orgy + hh - expy2); if (orgy >= 0 && hh > 0) // write in layout gdk_draw_pixbuf(GTK_LAYOUT(layout)->bin_window,0,pxbT, orgx,orgy,thumx+orgx,thumy+orgy,ww,hh,NODITHER,0,0); g_object_unref(pxbT); } draw_text(layout,flist[ii],thumbW+margin,thumy,textww); // write filespec to right of thumbnail if (mdlist && mdlist[ii]) // write metadata if present draw_text(layout,mdlist[ii],thumbW+margin,thumy+20,textww); if (++ii == nfiles) goto thumbsdone; // EOL } thumbsdone: if (popup) { write_popup_text("close"); genthumbs = 0; } return 1; } // private function // write text for thumbnail limited by width of thumbnail void image_navi::draw_text(GtkWidget *win, char *text, int x, int y, int ww) { using namespace image_navi; static PangoFontDescription *pfont = 0; static PangoLayout *playout = 0; int nn; static int thumbsize2 = 0; static char thumbfont[12] = ""; if (thumbsize != thumbsize2) { // scale file name font to thumbnail size thumbsize2 = thumbsize; nn = 7 + thumbsize / 128; // font size from 7 to 10 if (thumbsize == 0) nn = 9; // list view, use 9 sprintf(thumbfont,"sans %d",nn); pfont = pango_font_description_from_string(thumbfont); playout = gtk_widget_create_pango_layout(win,0); pango_layout_set_font_description(playout,pfont); } pango_layout_set_width(playout,ww*PANGO_SCALE); // limit width to avail. space v.12.01 pango_layout_set_ellipsize(playout,PANGO_ELLIPSIZE_END); pango_layout_set_text(playout,text,-1); gdk_draw_layout(GTK_LAYOUT(win)->bin_window,gdkgc2,x,y,playout); return; } // private function // gallery window destroy event - mark window not active. void image_navi::gallery_destroy() { using namespace image_navi; wing = 0; // no window if (userfunc) userfunc(-1,0); // tell caller return; } // private function - menu function for gallery window // - scroll window as requested // - jump to new file or folder as requested void image_navi::menufuncx(GtkWidget *win, cchar *menu) { using namespace image_navi; int ii, yn, Gwarn, scrollp; char *filez, *pp; if (strEqu(menu,ZTX("close"))) { // close image gallery window gtk_widget_destroy(wing); // destroy event function calls userfunc(-1) return; } if (strEqu(menu,ZTX("bigger"))) { // next bigger thumbnail size for (ii = 0; ii < thumbxx; ii++) if (thumbsize == thumbx[ii]) break; if (ii == 0) return; thumbsize = thumbx[ii-1]; targposn = scrollposn / thumbH * xcols; // keep top row position gallery_paint(0,0); return; } if (strEqu(menu,ZTX("smaller"))) { // next smaller for (ii = 0; ii < thumbxx; ii++) if (thumbsize == thumbx[ii]) break; if (ii >= thumbxx-1) thumbsize = 0; // no thumbs, list view else thumbsize = thumbx[ii+1]; if (thumbsize <= 128 && gallerytype == 3) // min. size for metadata report v.12.01 thumbsize = 128; targposn = scrollposn / thumbH * xcols; // keep top row position gallery_paint(0,0); return; } scrollp = scrollposn; if (strEqu(menu,ZTX("parent"))) { Gwarn = 0; if (image_navi::gallerytype > 1) Gwarn = 1; // warn if discarding search or pp = image_navi::galleryname; // collection type gallery if (pp && strEqu(pp,"Recent Files")) Gwarn = 0; // v.12.01 if (Gwarn) { // if gallery not from a directory, yn = zmessageYN(wing,Bdiscard,image_navi::galleryname); // warn user, gallery will be discarded if (! yn) return; // do not discard } if (galleryname && gallerytype == 1) filez = strdupz(galleryname,0,"image_navi"); else filez = strdupz(curr_dirk,0,"image_navi"); // v.12.01 pp = strrchr(filez,'/'); // go up to '/' and stop if (pp && pp > filez) *pp = 0; else filez = strdupz("/",0,"image_navi"); // v.12.01 image_navigate(filez,"init"); // get new file list gallery_paint(0,0); zfree(filez); scrollp = 0; } if (strEqu(menu,ZTX("prev row"))) scrollp -= thumbH; if (strEqu(menu,ZTX("next row"))) scrollp += thumbH; if (strEqu(menu,ZTX("prev page"))) scrollp -= thumbH * xrows; if (strEqu(menu,ZTX("next page"))) scrollp += thumbH * xrows; if (strEqu(menu,ZTX("first page"))) scrollp = 0; if (strEqu(menu,ZTX("last page"))) scrollp = maxscroll; if (scrollp < 0) scrollp = 0; // enforce limits if (scrollp > maxscroll) scrollp = maxscroll; scrollp = scrollp / thumbH * thumbH; // align top row if (scrollp != scrollposn) gtk_adjustment_set_value(scrollbar,scrollp); return; } // private function // mouse event function for gallery window - get selected thumbnail and file // user function receives clicked file, which is subject for zfree() void image_navi::mouse_xevent(GtkWidget *, GdkEventButton *event, void *) { using namespace image_navi; int mousex, mousey, mousebutt; int row, col, nrows, ii, err; char *filez; struct stat statb; if (! nfiles) return; // empty window mousex = int(event->x); mousey = int(event->y); mousebutt = event->button; row = (mousey - margin) / thumbH; // find selected row, col col = (mousex - margin) / thumbW; nrows = 1 + (nfiles-1) / xcols; // total thumbnail rows, 1 or more if (col < 0 || col >= xcols) return; if (row < 0 || row >= nrows) return; ii = xcols * row + col; if (ii >= nfiles) return; filez = strdupz(flist[ii],0,"image_navi"); // selected file *filez = '/'; err = stat(filez,&statb); if (err) { // file is gone? zfree(filez); return; } if (S_ISDIR(statb.st_mode)) { // if directory, go there image_navigate(filez,"init"); gallery_paint(0,0); zfree(filez); return; } if (userfunc) userfunc(ii,mousebutt); // clicked file position to user return; } // private function // KB event function - respond to keyboard navigation keys // key definitions: /usr/include/gtk-2.0/gdk/gdkkeysyms.h int image_navi::KBxpress(GtkWidget *win, GdkEventKey *event, void *) // prevent propagation of key-press { // events to toolbar buttons return 1; } int image_navi::KBxrelease(GtkWidget *win, GdkEventKey *event, void *) { using namespace image_navi; int KBkey; KBkey = event->keyval; if (KBkey == GDK_plus) menufuncx(win,ZTX("bigger")); // +/- = bigger/smaller thumbnails if (KBkey == GDK_equal) menufuncx(win,ZTX("bigger")); if (KBkey == GDK_minus) menufuncx(win,ZTX("smaller")); if (KBkey == GDK_KP_Add) menufuncx(win,ZTX("bigger")); // keypad +/- also if (KBkey == GDK_KP_Subtract) menufuncx(win,ZTX("smaller")); if (KBkey == GDK_Left) menufuncx(win,ZTX("prev page")); // left arrow = previous page if (KBkey == GDK_Right) menufuncx(win,ZTX("next page")); // right arrow = next page if (KBkey == GDK_Up) menufuncx(win,ZTX("prev row")); // up arrow = previous row if (KBkey == GDK_Down) menufuncx(win,ZTX("next row")); // down arrow = next row if (KBkey == GDK_Home) menufuncx(win,ZTX("first page")); // keys added if (KBkey == GDK_End) menufuncx(win,ZTX("last page")); if (KBkey == GDK_Page_Up) menufuncx(win,ZTX("prev page")); if (KBkey == GDK_Page_Down) menufuncx(win,ZTX("next page")); if (KBkey == GDK_Escape) gtk_widget_destroy(win); // Escape = cancel gallery window if (KBkey == GDK_F1) showz_userguide(zfuncs::F1_help_topic); return 1; } // Public function - get file position in file list. // If Nth position matches file, this is returned. // Otherwise the file is searched from position 0. // Position 0-last is returned if found, or -1 if not. int image_gallery_position(cchar *file, int Nth) { using namespace image_navi; int ii; if (! nfiles) return -1; if (Nth >= 0 && Nth < nfiles) ii = Nth; else ii = 0; if (strEqu(file+1,flist[ii]+1)) return ii; // 1st flist[ii] char. may be ! for (ii = 0; ii < nfiles; ii++) if (strEqu(file+1,flist[ii]+1)) break; if (ii < nfiles) return ii; return -1; } // public function // determine if a file is a directory or a supported image file type // return: 0 = error, 1 = directory, 2 = image file, 3 = other int image_file_type(cchar *file) { using namespace image_navi; int err, cc; cchar *pp; struct stat statbuf; if (! file) return 0; err = stat(file,&statbuf); if (err) return 0; if (S_ISDIR(statbuf.st_mode)) { // directory cc = strlen(file); if (cc > 12) { pp = file + cc - 12; if (strEqu(pp,"/.thumbnails")) return 3; // .thumbnails } return 1; } if (S_ISREG(statbuf.st_mode)) { // reg. file pp = strrchr(file,'.'); if (! pp) return 3; pp = strcasestr(imagetypes,pp); // supported image type if (pp) return 2; } return 3; } // Public function // Get thumbnail filespec for the given image file. // If missing or stale, add or update in /.thumbnails directory. // Returned filespec is subject for zfree(). // Use 4 threads to build missing thumbnails asynchrounously // (and hopefully ahead of need). namespace image_thumbs { char * image_thumbfile_1x(char *imagefile); void * image_thumbfile_thread(void *arg); int image_thumbfile_lock(char *imagefile, int lock); char *imagefilex; char *thumbfilex; char *directoryx; char **filelistx; int Nfilesx; int indexx; int busythreads; int stopthreads; char *lockfiles[5]; mutex filelock = PTHREAD_MUTEX_INITIALIZER; mutex thumblock = PTHREAD_MUTEX_INITIALIZER; } char * image_thumbfile(char *imagefile) { using namespace image_thumbs; char *thumbfile, *directory; char *pfile, *bfile, *buff; cchar *findcommand = "find \"%s\" -maxdepth 1"; struct stat statf, statb; int err, ftyp, contx = 0; zthreadcrash(); // thread usage not allowed err = stat(imagefile,&statf); if (err) return 0; if (! S_ISREG(statf.st_mode)) return 0; // not a regular file if (image_file_type(imagefile) != 2) return 0; // unsupported image type pfile = strrchr(imagefile,'/'); // get .../filename.xxx if (! pfile) return 0; if (pfile > imagefile+12 && strnEqu(pfile-12,"/.thumbnails/",13)) { // .../.thumbnails/filename.xxx ?? thumbfile = strdupz(imagefile,0,"image_thumbfile"); // yes, a thumbnail file return thumbfile; // return same file } thumbfile = strdupz(imagefile,20,"image_thumbfile"); // construct thumbnail file bfile = thumbfile + (pfile - imagefile); // .../.thumbnails/filename.xxx.png strcpy(bfile,"/.thumbnails"); bfile += 12; strcpy(bfile,pfile); strcat(bfile,".png"); err = stat(thumbfile,&statb); // thumbnail file exists ?? if (! err) { // yes if (statb.st_mtime >= statf.st_mtime) return thumbfile; // up to date, return it zfree(thumbfile); thumbfile = image_thumbfile_1x(imagefile); // refresh stale thumbnail return thumbfile; // return it } zfree(thumbfile); directory = strdupz(imagefile,0,"image_thumbfile"); // thumbnail does not exist pfile = strrchr(directory,'/'); pfile[1] = 0; // image directory/ if (! directoryx) directoryx = directory; // first use else if (strNeq(directoryx,directory)) { // new directory to search stopthreads = 1; while (busythreads) zsleep(0.001); // stop prior search if any zfree(directoryx); directoryx = directory; // directory for new search } else zfree(directory); // no change imagefilex = imagefile; // target thumbnail to get while (busythreads) { // if ongoing search, request thumbnail if (! imagefilex) return thumbfilex; // from existing search threads zsleep(0.001); // (this can fail rarely) } if (filelistx) // set up empty file list for (int ii = 0; ii < Nfilesx; ii++) zfree(filelistx[ii]); else filelistx = (char **) zmalloc(MAXIMAGES * sizeof(char *),"image_thumbfile"); Nfilesx = 0; while ((buff = command_output(contx,findcommand,directoryx))) // search image file directory { if (Nfilesx == MAXIMAGES) { // no room zmessageACK(0,Btoomanyfiles,MAXIMAGES); break; } ftyp = image_file_type(buff); if (ftyp == 2) { // supported image file type filelistx[Nfilesx] = buff; // add to file list Nfilesx++; } else zfree(buff); } busythreads = 4; // start search threads for this directory stopthreads = 0; indexx = -1; for (int ii = 0; ii < 4; ii++) start_detached_thread(image_thumbfile_thread,0); while (busythreads) { // return as soon as target thumbnail if (! imagefilex) return thumbfilex; // has been generated zsleep(0.001); } if (! imagefilex) return thumbfilex; printf("image_thumbfile failed %s \n",imagefile); // failure return 0; } // private function // four threads each processing 1/4 of the entries in filelistx void * image_thumbs::image_thumbfile_thread(void *arg) { using namespace image_thumbs; int ii; char *thumbfile; while (indexx < Nfilesx) { if (imagefilex) { // if thumbnail request is waiting mutex_lock(&thumblock); // take care of it first if (imagefilex) thumbfilex = image_thumbfile_1x(imagefilex); imagefilex = 0; mutex_unlock(&thumblock); } if (stopthreads) break; // stop before done ii = zadd_locked(indexx,+1); // get next file from list if (ii >= Nfilesx) break; thumbfile = image_thumbfile_1x(filelistx[ii]); // make thumbnail file if needed if (thumbfile) zfree(thumbfile); } zadd_locked(busythreads,-1); // decrement busy count pthread_exit(0); // "return" cannot be used here } // Private function to create a single thumbnail file. // Get thumbnail file for the given image file. // If missing or stale, add or update in /.thumbnails directory. // Returned filespec is subject for zfree(). char * image_thumbs::image_thumbfile_1x(char *imagefile) { using namespace image_thumbs; GdkPixbuf *thumbpxb; GError *gerror = 0; char *pfile, *bfile, *thumbfile; int err, sizew, sizeh; struct stat statf, statb; err = stat(imagefile,&statf); if (err) return 0; if (! S_ISREG(statf.st_mode)) return 0; // not a regular file if (image_file_type(imagefile) != 2) return 0; // unsupported image type pfile = strrchr(imagefile,'/'); // get .../filename.xxx if (! pfile) return 0; if (pfile > imagefile+12 && strnEqu(pfile-12,"/.thumbnails/",13)) { // .../.thumbnails/filename.xxx ?? thumbfile = strdupz(imagefile,0,"image_thumbfile"); // yes, a thumbnail file return thumbfile; // return same file } thumbfile = strdupz(imagefile,20,"image_thumbfile"); // construct thumbnail file bfile = thumbfile + (pfile - imagefile); // .../.thumbnails/filename.xxx.png strcpy(bfile,"/.thumbnails"); bfile += 12; strcpy(bfile,pfile); strcat(bfile,".png"); while (! image_thumbfile_lock(imagefile,1)) zsleep(0.001); // lock file for me err = stat(thumbfile,&statb); // thumbnail file exists ?? if (err || (statb.st_mtime < statf.st_mtime)) { // does not exist or stale *bfile = 0; err = stat(thumbfile,&statb); if (err) err = mkdir(thumbfile,0751); // create .thumbnails directory if (err) { image_thumbfile_lock(imagefile,0); return 0; } *bfile = *pfile; sizew = sizeh = image_navi::thumbfilesize; // create thumbnail pixbuf thumbpxb = gdk_pixbuf_new_from_file_at_size(imagefile,sizew,sizeh,&gerror); if (! thumbpxb) { printf("gdk_pixbuf_new error: %s \n",gerror->message); // diagnose error image_thumbfile_lock(imagefile,0); return 0; } gdk_pixbuf_save(thumbpxb,thumbfile,"png",&gerror,null); // save in /.thumbnails/ directory g_object_unref(thumbpxb); image_navi::genthumbs++; // count generated thumbnails } image_thumbfile_lock(imagefile,0); // return thumbfile return thumbfile; } // prevent interference from multiple threads working on the same image file int image_thumbs::image_thumbfile_lock(char *imagefile, int lock) { using namespace image_thumbs; int ii, jj = -1; mutex_lock(&filelock); if (lock) // lock file if possible { for (ii = 0; ii < 5; ii++) { if (! lockfiles[ii]) jj = ii; // remember 1st empty slot else if (strEqu(lockfiles[ii],imagefile)) { mutex_unlock(&filelock); // file is already locked return 0; } } if (jj < 0) zappcrash("image_thumbfile_lock > 5"); lockfiles[jj] = imagefile; // lock the file mutex_unlock(&filelock); return 1; } else // unlock file { for (ii = 0; ii < 5; ii++) { if (! lockfiles[ii]) continue; if (strEqu(lockfiles[ii],imagefile)) { lockfiles[ii] = 0; mutex_unlock(&filelock); return 1; } } zappcrash("image_thumbfile_lock gone"); return 0; } } // Public function // Get thumbnail image for given image file, from .thumbnails directory. // Add thumbnail file if missing, or update it if older than image file. // Returned thumbnail belongs to caller: g_object_unref() is necessary. GdkPixbuf * image_thumbnail(char *fpath, int size) { using namespace zfuncs; using namespace image_navi; GdkPixbuf *thumbpxb; GError *gerror = 0; int ii, err; char *bpath; time_t mtime; struct stat statf; const int cachesize = thumbnail_cachesize; // shorthand static int nextcache, ftf = 1; static int sizecache[cachesize]; static time_t mtimecache[cachesize]; static char *fpathcache[cachesize]; static GdkPixbuf *pixbufcache[cachesize]; zthreadcrash(); // thread usage not allowed if (ftf) { // first call for (ii = 0; ii < cachesize; ii++) fpathcache[ii] = 0; // clear cache ftf = 0; } err = stat(fpath,&statf); // fpath status info if (err) return 0; if (S_ISDIR(statf.st_mode)) { // if directory, return folder image bpath = zmalloc(500); strncatv(bpath,499,zicondir,"/folder256.png",null); thumbpxb = gdk_pixbuf_new_from_file_at_size(bpath,size,size,&gerror); zfree(bpath); return thumbpxb; } mtime = statf.st_mtime; // last modification time if (! size) size = thumbfilesize; // default thumb size for (ii = nextcache; ii >= 0; ii--) // get cached pixbuf if found if (fpathcache[ii] && strEqu(fpath,fpathcache[ii]) && sizecache[ii] == size && mtime == mtimecache[ii]) break; // check mtime (bugfix) if (ii >= 0) { thumbpxb = gdk_pixbuf_copy(pixbufcache[ii]); return thumbpxb; } for (ii = cachesize-1; ii > nextcache; ii--) // continue search if (fpathcache[ii] && strEqu(fpath,fpathcache[ii]) && sizecache[ii] == size && mtime == mtimecache[ii]) break; if (ii > nextcache) { thumbpxb = gdk_pixbuf_copy(pixbufcache[ii]); return thumbpxb; } if (size > thumbfilesize) { // support huge thumbnails thumbpxb = gdk_pixbuf_new_from_file_at_size(fpath,size,size,&gerror); goto addcache; } bpath = image_thumbfile(fpath); // get thumbnail file if (! bpath) return 0; thumbpxb = gdk_pixbuf_new_from_file_at_size(bpath,size,size,&gerror); // get thumbnail zfree(bpath); goto addcache; addcache: nextcache++; // next cache slot (oldest) if (nextcache == cachesize) nextcache = 0; ii = nextcache; if (fpathcache[ii]) { // free prior occupant zfree(fpathcache[ii]); g_object_unref(pixbufcache[ii]); } fpathcache[ii] = strdupz(fpath,0,"thumbnail_cache"); // add new occupant pixbufcache[ii] = gdk_pixbuf_copy(thumbpxb); // this memory is not tracked sizecache[ii] = size; mtimecache[ii] = mtime; return thumbpxb; // return pixbuf to caller } /************************************************************************** private function - manage list of image files within a directory get an image file in the same directory as given file or directory char * image_navi::image_navigate(cchar *filez, cchar *action, int Nth) action: init: file list = directories and image files in directory filez initF: file list = filez = list of image files to use (cchar **) sort: sort the file list, directories first, ignore case insert: insert filez into file list at position Nth (0 to last+1) delete: delete Nth file in list find: returns Nth file (0 base) or null if Nth > last Nth: file to return for action = find Returned values: find: filespec, else null The returned file belongs to caller and is subject for zfree(). ***************************************************************************/ char * image_navi::image_navigate(cchar *filez, cchar *action, int Nth) { using namespace image_navi; char *buff; cchar *findcommand = "find \"%s\" -maxdepth 1"; char *pp, *file2; int err, ii, cc, ftyp, contx = 0, fposn; FILE *fid; struct stat statbuf; if (! strstr("init initF sort insert delete find",action)) zappcrash("image_navigate %s",action); if (strnEqu(action,"init",4)) // init or initF { if (flist) { for (ii = 0; ii < nfiles; ii++) zfree(flist[ii]); // free prior file list zfree(flist); } if (mdlist) { // clear prior metadata if any for (ii = 0; ii < nfiles; ii++) if (mdlist[ii]) zfree(mdlist[ii]); zfree(mdlist); mdlist = 0; } cc = MAXIMAGES * sizeof(char *); flist = (char **) zmalloc(cc,"image_navi"); // list of file pointers nfiles = nimages = 0; // no files fposn = 0; gallerytype = 0; // v.12.01 } if (strEqu(action,"init")) // initialize from given directory { if (! filez) return 0; // should not happen if (galleryname) zfree(galleryname); galleryname = strdupz(filez,0,"image_navi"); gallerytype = 1; // gallery type = directory err = stat(galleryname,&statbuf); if (err) { pp = (char *) strrchr(galleryname,'/'); // bad file, check directory part if (! pp) return 0; pp[1] = 0; err = stat(galleryname,&statbuf); if (err) return 0; // give up, empty file list } if (S_ISREG(statbuf.st_mode)) { // if a file, get directory part pp = (char *) strrchr(galleryname,'/'); if (! pp) return 0; pp[1] = 0; } while ((buff = command_output(contx,findcommand,galleryname))) // find all files { if (strEqu(buff,galleryname)) { // skip self directory zfree(buff); continue; } if (nfiles == MAXIMAGES) { // message, not crash zmessageACK(0,Btoomanyfiles,MAXIMAGES); break; } ftyp = image_file_type(buff); if (ftyp == 1) { // subdirectory flist[nfiles] = buff; // add to file list flist[nfiles][0] = '!'; // if directory, make it sort first nfiles++; } else if (ftyp == 2) { // supported image file type flist[nfiles] = buff; // add to file list nfiles++; nimages++; } else { zfree(buff); // (.thumbnails not ftyp 1) continue; } } if (nfiles > 1) HeapSort(flist,nfiles,image_fcomp); // Heap Sort - pointers to strings return 0; } if (strEqu(action,"initF")) // initialize from given list { if (galleryname) zfree(galleryname); galleryname = strdupz(filez,0,"image_navi"); gallerytype = 2; // gallery type = file list fid = fopen(galleryname,"r"); // open file if (! fid) return 0; buff = zmalloc(maxfcc); while (true) // read list of files { if (nfiles == MAXIMAGES) { zmessageACK(0,Btoomanyfiles,MAXIMAGES); break; } pp = fgets_trim(buff,maxfcc-1,fid,1); if (! pp) break; err = stat(pp,&statbuf); // check file exists if (err) continue; flist[nfiles] = strdupz(buff,0,"image_navi"); // add files to memory list nfiles++; nimages++; } fclose(fid); zfree(buff); // sort removed return 0; } if (strEqu(action,"sort")) // sort the list from initF { if (gallerytype == 3) return 0; // v.12.01 if (nfiles < 2) return 0; HeapSort(flist,nfiles,image_fcomp); // Heap Sort - pointers to strings return 0; } if (strEqu(action,"insert")) // insert new file into list { if (gallerytype == 3) return 0; // metadata report v.12.01 fposn = Nth; // file position from caller if (fposn < 0) fposn = 0; // limit to allowed range if (fposn > nfiles) fposn = nfiles; if (nfiles == MAXIMAGES-1) { // no room zmessageACK(0,Btoomanyfiles,MAXIMAGES); return 0; } for (ii = nfiles; ii > fposn; ii--) // create hole is list flist[ii] = flist[ii-1]; flist[fposn] = strdupz(filez,0,"image_navi"); // put new file in hole nfiles++; nimages++; // bugfix } if (strEqu(action,"delete")) // delete file from list { if (gallerytype == 3) return 0; // metadata report v.12.01 fposn = Nth; // file position from caller must be OK if (fposn < 0 || fposn > nfiles-1) return 0; nfiles--; if (*flist[fposn] != '!') nimages--; // not a directory v.12.01 zfree(flist[fposn]); // remove file from list for (ii = fposn; ii < nfiles; ii++) { // close the hole if (nfiles < 0) printf("meaningless reference %d",ii); // stop g++ optimization bug //// flist[ii] = flist[ii+1]; } } if (strEqu(action,"find")) { fposn = Nth; // file position from caller must be OK if (fposn < 0 || fposn > nfiles-1) return 0; file2 = strdupz(flist[fposn],0,"image_navi"); // get Nth file file2[0] = '/'; // restore initial '/' err = stat(file2,&statbuf); if (! err) return file2; zfree(file2); } return 0; } // private function for special file name compare // directories sort first and upper/lower case is ignored int image_navi::image_fcomp(cchar *file1, cchar *file2) { int nn; nn = strcasecmp(file1,file2); // compare ignoring case if (nn != 0) return nn; nn = strcmp(file1,file2); // if equal, do normal compare return nn; } /**************************************************************************/ // Select files from the image gallery window, return list of files selected. // The dialog shows the list of files selected and can be edited. // The returned file list belongs to caller and is subject for zfree(). // The file list EOL is marked with null. // The image_gallery() callback function is changed and must be restored by caller. int imgl_showthumb(); void imgl_insert_file(cchar *imagefile); void imgl_gallery_file(int Nth, int button); GtkWidget *imgl_drawarea = 0; GtkWidget *imgl_files = 0; cchar *imgl_font = "Monospace 8"; zdialog *imgl_zd = 0; int imgl_fontheight = 14; int imgl_cursorpos = 0; char ** image_gallery_getfiles(char *startdir, GtkWidget *parent) { int imgl_dialog_event(zdialog *zd, cchar *event); int imgl_mouseclick(GtkWidget *, GdkEventButton *event, void *); PangoLanguage *plang; PangoFontDescription *pfontdesc; PangoContext *pcontext; PangoFont *pfont; PangoFontMetrics *pmetrics; GdkCursor *cursor; GdkWindow *gdkwin; GtkTextBuffer *textBuff; GtkTextIter iter1, iter2; int fontascent, fontdescent; int line, nlines, ii; char *imagefile, **filelist; zthreadcrash(); // thread usage not allowed image_gallery(startdir,"paint1",0,imgl_gallery_file,parent); // activate image gallery window imgl_zd = zdialog_new(ZTX("Select Files"),wing,ZTX("done"),ZTX("cancel"),null); zdialog_add_widget(imgl_zd,"hbox","hb1","dialog",0,"expand|space=5"); zdialog_add_widget(imgl_zd,"frame","fr11","hb1",0,"expand"); zdialog_add_widget(imgl_zd,"scrwin","scrwin","fr11",0,"expand"); zdialog_add_widget(imgl_zd,"edit","files","scrwin"); zdialog_add_widget(imgl_zd,"vbox","vb12","hb1"); zdialog_add_widget(imgl_zd,"frame","fr12","vb12"); zdialog_add_widget(imgl_zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(imgl_zd,"button","delete","hb2",ZTX("delete"),"space=8"); zdialog_add_widget(imgl_zd,"button","insert","hb2",ZTX("insert"),"space=8"); zdialog_add_widget(imgl_zd,"button","addall","hb2",ZTX("add all"),"space=30"); GtkWidget *textbox = zdialog_widget(imgl_zd,"files"); // disable text wrap gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textbox),GTK_WRAP_NONE); GtkWidget *frame = zdialog_widget(imgl_zd,"fr12"); // drawing area for thumbnail image imgl_drawarea = gtk_drawing_area_new(); gtk_widget_set_size_request(imgl_drawarea,256,258); // increased gtk_container_add(GTK_CONTAINER(frame),imgl_drawarea); imgl_files = zdialog_widget(imgl_zd,"files"); // activate mouse-clicks for gtk_widget_add_events(imgl_files,GDK_BUTTON_PRESS_MASK); // file list widget G_SIGNAL(imgl_files,"button-press-event",imgl_mouseclick,0); pfontdesc = pango_font_description_from_string(imgl_font); // set default font for files window gtk_widget_modify_font(imgl_files,pfontdesc); plang = pango_language_get_default(); // get font metrics (what a mess) pcontext = gtk_widget_get_pango_context(imgl_files); pfont = pango_context_load_font(pcontext,pfontdesc); pmetrics = pango_font_get_metrics(pfont,plang); fontascent = pango_font_metrics_get_ascent(pmetrics) / PANGO_SCALE; fontdescent = pango_font_metrics_get_descent(pmetrics) / PANGO_SCALE; imgl_fontheight = fontascent + fontdescent; // effective line height zdialog_resize(imgl_zd,600,0); // start dialog zdialog_run(imgl_zd,imgl_dialog_event); cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW); // arrow cursor for file list widget gdkwin = gtk_text_view_get_window(GTK_TEXT_VIEW(imgl_files),TEXTWIN); // (must be done after window realized) gdk_window_set_cursor(gdkwin,cursor); imgl_cursorpos = 0; zdialog_wait(imgl_zd); // wait for completion if (imgl_zd->zstat != 1) { // cancelled zdialog_free(imgl_zd); // kill dialog image_gallery(0,"close"); // close image gallery window return 0; } textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imgl_files)); nlines = gtk_text_buffer_get_line_count(textBuff); filelist = (char **) zmalloc((nlines+1) * sizeof(char *),"imgl.getfiles"); for (ii = line = 0; line < nlines; line++) // get list of files from dialog { gtk_text_buffer_get_iter_at_line(textBuff,&iter1,line); // iter at line start iter2 = iter1; gtk_text_iter_forward_to_line_end(&iter2); imagefile = gtk_text_buffer_get_text(textBuff,&iter1,&iter2,0); // get line of text if (imagefile && *imagefile == '/') { filelist[ii] = strdupz(imagefile,0,"imgl.getfiles"); // >> next file in list free(imagefile); ii++; } } filelist[ii] = 0; // mark EOL zdialog_free(imgl_zd); // kill dialog image_gallery(0,"close"); // close image gallery window if (! ii) { zfree(filelist); // file list is empty return 0; } return filelist; // return file list } // imgl dialog event function int imgl_dialog_event(zdialog *zd, cchar *event) { GtkTextBuffer *textBuff; GtkTextIter iter1, iter2; char *ftemp; static char *imagefile = 0; int line, posn; if (strEqu(event,"delete")) // delete file at cursor position { if (imagefile) zfree(imagefile); imagefile = 0; textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imgl_files)); line = imgl_cursorpos; gtk_text_buffer_get_iter_at_line(textBuff,&iter1,line); // iter at line start iter2 = iter1; gtk_text_iter_forward_to_line_end(&iter2); // iter at line end ftemp = gtk_text_buffer_get_text(textBuff,&iter1,&iter2,0); // get selected file if (! ftemp || *ftemp != '/') { if (ftemp) free(ftemp); return 0; } imagefile = strdupz(ftemp,0,"imgl.getfiles"); // save deleted file for poss. insert free(ftemp); gtk_text_buffer_delete(textBuff,&iter1,&iter2); // delete file text gtk_text_buffer_get_iter_at_line(textBuff,&iter2,line+1); gtk_text_buffer_delete(textBuff,&iter1,&iter2); // delete empty line (\n) imgl_showthumb(); // thumbnail = next file } if (strEqu(event,"insert")) // insert last deleted file { // at current cursor position if (! imagefile) return 0; imgl_insert_file(imagefile); zfree(imagefile); imagefile = 0; } if (strEqu(event,"addall")) // insert all files in image gallery { textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imgl_files)); posn = 0; while (true) { imagefile = image_gallery(0,"find",posn); // get first or next file if (! imagefile) break; posn++; gtk_text_buffer_get_iter_at_line(textBuff,&iter1,imgl_cursorpos); gtk_text_buffer_insert(textBuff,&iter1,"\n",1); // insert new blank line gtk_text_buffer_get_iter_at_line(textBuff,&iter1,imgl_cursorpos); gtk_text_buffer_insert(textBuff,&iter1,imagefile,-1); // insert image file zfree(imagefile); imgl_cursorpos++; // advance cursor position } } return 0; } // add image file to list at current cursor position, set thumbnail = file void imgl_insert_file(cchar *imagefile) { GtkTextIter iter; GtkTextBuffer *textBuff; textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imgl_files)); gtk_text_buffer_get_iter_at_line(textBuff,&iter,imgl_cursorpos); gtk_text_buffer_insert(textBuff,&iter,"\n",1); // insert new blank line gtk_text_buffer_get_iter_at_line(textBuff,&iter,imgl_cursorpos); gtk_text_buffer_insert(textBuff,&iter,imagefile,-1); // insert image file imgl_showthumb(); // update thumbnail imgl_cursorpos++; // advance cursor position return; } // called from image gallery window when a thumbnail is clicked // add image file to list at current cursor position, set thumbnail = file void imgl_gallery_file(int Nth, int button) { int ftyp; char *imagefile; if (Nth == -2) { showz_userguide(zfuncs::F1_help_topic); // F1 context help return; } imagefile = image_gallery(0,"find",Nth); // get file at clicked position if (! imagefile) return; ftyp = image_file_type(imagefile); // ignore directories if (ftyp == 2) imgl_insert_file(imagefile); // insert file at current position zfree(imagefile); return; } // process mouse click in files window: // set new cursor position and set thumbnail = clicked file int imgl_mouseclick(GtkWidget *, GdkEventButton *event, void *) { int mpy; GtkWidget *scrollwin; GtkAdjustment *scrolladj; double scrollpos; if (event->type != GDK_BUTTON_PRESS) return 0; mpy = int(event->y); scrollwin = zdialog_widget(imgl_zd,"scrwin"); // window scroll position scrolladj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrollwin)); scrollpos = gtk_adjustment_get_value(scrolladj); imgl_cursorpos = (mpy + scrollpos) / imgl_fontheight; // line selected imgl_showthumb(); // show thumbnail image return 0; } // show thumbnail for file at current cursor position int imgl_showthumb() { int line; char *imagefile; GtkTextBuffer *textBuff; GtkTextIter iter1, iter2; GdkPixbuf *thumbnail = 0; gdk_window_clear(imgl_drawarea->window); line = imgl_cursorpos; textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imgl_files)); gtk_text_buffer_get_iter_at_line(textBuff,&iter1,line); // iter at line start iter2 = iter1; gtk_text_iter_forward_to_line_end(&iter2); // iter at line end imagefile = gtk_text_buffer_get_text(textBuff,&iter1,&iter2,0); // get selected file if (*imagefile != '/') { free(imagefile); return 0; } thumbnail = image_thumbnail(imagefile,256); // get thumbnail free(imagefile); if (thumbnail) { gdk_draw_pixbuf(imgl_drawarea->window,0,thumbnail,0,0,0,0,-1,-1,NODITHER,0,0); g_object_unref(thumbnail); } return 0; } fotoxx-12.01.2/f.comp.cc0000644000175000017500000074770211701011017013343 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image edit functions - composite functions ***************************************************************************/ // File scope variables and functions for composite images // used by HDR, HDF, STP, STN, Panorama. int cimNF; // image count, <= 10 char *cimFile[10]; // image files PXM *cimPXMf[10]; // original images PXM *cimPXMs[10]; // alignment images, scaled and curved (pano) PXM *cimPXMw[10]; // alignment images, warped struct cimoffs { // image alignment offsets double xf, yf, tf; // x, y, theta offsets double wx[4], wy[4]; // x/y corner warps, 0=NW, 1=NE, 2=SE, 3=SW }; cimoffs cimOffs[10]; // image alignment data in E3 output image double cimScale; // alignment image size relative to full image double cimBlend; // image blend width at overlap, pixels (pano) double cimSearchRange; // alignment search range, pixels double cimSearchStep; // alignment search step, vpixels double cimWarpRange; // alignment corner warp range, pixels double cimWarpStep; // alignment corner warp step, vpixels double cimSampSize; // pixel sample size int cimOv1xlo, cimOv1xhi, cimOv1ylo, cimOv1yhi; // rectangle enclosing overlap area, int cimOv2xlo, cimOv2xhi, cimOv2ylo, cimOv2yhi; // image 1 and image2 coordinates double cimRGBmf1[3][65536]; // RGB matching factors for pixel comparisons: double cimRGBmf2[3][65536]; // cimRGBmf1[*][pix1[*]] == cimRGBmf2[*][pix2[*]] char *cimRedpix = 0; // maps high-contrast pixels for alignment int cimRedImage; // which image has red pixels int cimNsearch; // alignment search counter int cimShowIm1, cimShowIm2; // two images for cim_show_images() int cimShowAll; // if > 0, show all images int cimShrink; // image shrinkage from pano image curving int cimPano; // pano mode flag for cim_align_image() int cimPanoV; // vertical pano flag int cim_load_files(); // load and check selected files void cim_scale_image(int im, PXM **); // scale image, 1.0 to cimScale (normally < 1) double cim_get_overlap(int im1, int im2, PXM **); // get overlap area for images (horiz or vert) void cim_match_colors(int im1, int im2, PXM **); // match image RGB levels >> match data void cim_adjust_colors(PXM *pxm, int fwhich); // adjust RGB levels from match data void cim_get_redpix(int im1); // find high-contrast pixels in overlap area void cim_curve_image(int im); // curve cimPXMs[im] using lens parameters void cim_curve_Vimage(int im); // vertical pano version void cim_warp_image(int im); // warp image corners: cimPXMs[im] >> cimPXMw[im] void cim_warp_image_pano(int im, int fblend); // pano version, all / left side / blend stripe void cim_warp_image_Vpano(int im, int fblend); // vertical pans version: bottom side corners void cim_align_image(int im1, int im2); // align image im2 to im1, modify im2 offsets double cim_match_images(int im1, int im2); // compute match for overlapped images void cim_show_images(int fnew, int fblend); // combine images >> E3pxm16 >> main window void cim_show_Vimages(int fnew, int fblend); // vertical pano version void cim_trim(); // cut-off edges where all images do not overlap void cim_dump_offsets(cchar *text); // diagnostic tool // load image file into pixmaps cimPXMf[*] and check for errors // returns 0 if error int cim_load_files() // v.10.7 { PXM *pxm; for (int imx = 0; imx < cimNF; imx++) { PXM_free(cimPXMf[imx]); pxm = f_load(cimFile[imx],16); // will diagnose errors if (! pxm) return 0; cimPXMf[imx] = pxm; PXM_fixblue(pxm); // blue=0 >> blue=2 for vpixel() v.11.07 } return 1; } // scale image from full size) to cimScale (normally < 1.0) void cim_scale_image(int im, PXM** pxmout) // v.10.7 { int ww, hh; ww = cimScale * cimPXMf[im]->ww; hh = cimScale * cimPXMf[im]->hh; PXM_free(pxmout[im]); pxmout[im] = PXM_rescale(cimPXMf[im],ww,hh); PXM_fixblue(pxmout[im]); // blue=0 >> blue=2 for vpixel() v.11.07 return; } // get overlap area for a pair of images im1 and im2 // outputs are coordinates of overlap area in im1 and in im2 // returns overlap width as fraction of image width <= 1.0 double cim_get_overlap(int im1, int im2, PXM **pxmx) // v.11.04 { double x1, y1, t1, x2, y2, t2; double xoff, yoff, toff, costf, sintf; int ww1, ww2, hh1, hh2, pxM; PXM *pxm1, *pxm2; x1 = cimOffs[im1].xf; // im1, im2 absolute offsets y1 = cimOffs[im1].yf; t1 = cimOffs[im1].tf; x2 = cimOffs[im2].xf; y2 = cimOffs[im2].yf; t2 = cimOffs[im2].tf; xoff = (x2 - x1) * cos(t1) + (y2 - y1) * sin(t1); // offset of im2 relative to im1 yoff = (y2 - y1) * cos(t1) - (x2 - x1) * sin(t1); toff = t2 - t1; costf = cos(toff); sintf = sin(toff); pxm1 = pxmx[im1]; pxm2 = pxmx[im2]; ww1 = pxm1->ww; hh1 = pxm1->hh; ww2 = pxm2->ww; hh2 = pxm2->hh; cimOv1xlo = 0; // lowest x overlap if (xoff > 0) cimOv1xlo = xoff; cimOv1xhi = ww1-1; // highest x overlap if (cimOv1xhi > xoff + ww2-1) cimOv1xhi = xoff + ww2-1; cimOv1ylo = 0; // lowest y overlap if (yoff > 0) cimOv1ylo = yoff; cimOv1yhi = hh1-1; // highest y overlap if (cimOv1yhi > yoff + hh2-1) cimOv1yhi = yoff + hh2-1; if (toff < 0) cimOv1xlo -= toff * (cimOv1yhi - cimOv1ylo); // reduce for theta offset if (toff < 0) cimOv1yhi += toff * (cimOv1xhi - cimOv1xlo); if (toff > 0) cimOv1xhi -= toff * (cimOv1yhi - cimOv1ylo); if (toff > 0) cimOv1ylo += toff * (cimOv1xhi - cimOv1xlo); cimOv1xlo += cimShrink + 3; // account for void areas from cimOv1xhi += - cimShrink - 3; // image shrinkage from cimOv1ylo += cimShrink + 3; // cim_curve_image() cimOv1yhi += - cimShrink - 3; // v.11.04 if (cimPanoV) { if (cimBlend && cimBlend < (cimOv1yhi - cimOv1ylo)) { // reduce y range to cimBlend v.11.04 pxM = (cimOv1yhi + cimOv1ylo) / 2; cimOv1ylo = pxM - cimBlend / 2; cimOv1yhi = pxM + cimBlend / 2; } } else { if (cimBlend && cimBlend < (cimOv1xhi - cimOv1xlo)) { // reduce x range to cimBlend pxM = (cimOv1xhi + cimOv1xlo) / 2; cimOv1xlo = pxM - cimBlend / 2; cimOv1xhi = pxM + cimBlend / 2; } } cimOv2xlo = costf * (cimOv1xlo - xoff) + sintf * (cimOv1ylo - yoff); // overlap area in im2 coordinates cimOv2xhi = costf * (cimOv1xhi - xoff) + sintf * (cimOv1yhi - yoff); cimOv2ylo = costf * (cimOv1ylo - yoff) + sintf * (cimOv1xlo - xoff); cimOv2yhi = costf * (cimOv1yhi - yoff) + sintf * (cimOv1xhi - xoff); if (cimOv1xlo < 0) cimOv1xlo = 0; // take care of limits if (cimOv1ylo < 0) cimOv1ylo = 0; if (cimOv2xlo < 0) cimOv2xlo = 0; if (cimOv2ylo < 0) cimOv2ylo = 0; if (cimOv1xhi > ww1-1) cimOv1xhi = ww1-1; if (cimOv1yhi > hh1-1) cimOv1yhi = hh1-1; if (cimOv2xhi > ww2-1) cimOv2xhi = ww2-1; if (cimOv2yhi > hh2-1) cimOv2yhi = hh2-1; if (cimPanoV) return 1.0 * (cimOv1yhi - cimOv1ylo) / hh1; // return overlap height <= 1.0 v.11.04 else return 1.0 * (cimOv1xhi - cimOv1xlo) / ww1; // return overlap width <= 1.0 v.11.03 } // Get the RGB brightness distribution in the overlap area for each image. // Compute matching factors to compare pixels within the overlap area. // compare cimRGBmf1[rgb][pix1[rgb]] to cimRGBmf2[rgb][pix2[rgb]] void cim_match_colors(int im1, int im2, PXM **pxmx) // v.10.7 { double Bratios1[3][256]; // image2/image1 brightness ratio per color per level double Bratios2[3][256]; // image1/image2 brightness ratio per color per level uint16 *pix1, vpix2[3]; int vstat2, px1, py1; int ii, jj, rgb; int npix, npix1, npix2, npix3; int brdist1[3][256], brdist2[3][256]; double x1, y1, t1, x2, y2, t2; double xoff, yoff, toff, costf, sintf; double px2, py2; double brlev1[3][256], brlev2[3][256]; double a1, a2, b1, b2, bratio = 1; double r256 = 1.0 / 256.0; PXM *pxm1, *pxm2; pxm1 = pxmx[im1]; pxm2 = pxmx[im2]; x1 = cimOffs[im1].xf; // im1, im2 absolute offsets y1 = cimOffs[im1].yf; t1 = cimOffs[im1].tf; x2 = cimOffs[im2].xf; y2 = cimOffs[im2].yf; t2 = cimOffs[im2].tf; xoff = (x2 - x1) * cos(t1) + (y2 - y1) * sin(t1); // offset of im2 relative to im1 yoff = (y2 - y1) * cos(t1) - (x2 - x1) * sin(t1); toff = t2 - t1; costf = cos(toff); sintf = sin(toff); for (rgb = 0; rgb < 3; rgb++) // clear distributions for (ii = 0; ii < 256; ii++) brdist1[rgb][ii] = brdist2[rgb][ii] = 0; npix = 0; for (py1 = cimOv1ylo; py1 < cimOv1yhi; py1++) // loop overlapped rows for (px1 = cimOv1xlo; px1 < cimOv1xhi; px1++) // loop overlapped columns { pix1 = PXMpix(pxm1,px1,py1); // image1 pixel if (! pix1[2]) continue; // ignore void pixels px2 = costf * (px1 - xoff) + sintf * (py1 - yoff); // corresponding image2 pixel py2 = costf * (py1 - yoff) - sintf * (px1 - xoff); vstat2 = vpixel(pxm2,px2,py2,vpix2); if (! vstat2) continue; // does not exist ++npix; // count overlapping pixels for (rgb = 0; rgb < 3; rgb++) // accumulate distributions { // by color in 256 bins ++brdist1[rgb][int(r256*pix1[rgb])]; ++brdist2[rgb][int(r256*vpix2[rgb])]; } } npix1 = npix / 256; // 1/256th of total pixels for (rgb = 0; rgb < 3; rgb++) // get brlev1[rgb][N] = mean bright for (ii = jj = 0; jj < 256; jj++) // for Nth group of image1 pixels { // for color rgb brlev1[rgb][jj] = 0; npix2 = npix1; // 1/256th of total pixels while (npix2 > 0 && ii < 256) // next 1/256th group from distr, { npix3 = brdist1[rgb][ii]; if (npix3 == 0) { ++ii; continue; } if (npix3 > npix2) npix3 = npix2; brlev1[rgb][jj] += ii * npix3; // brightness * (pixels with) brdist1[rgb][ii] -= npix3; npix2 -= npix3; } brlev1[rgb][jj] = brlev1[rgb][jj] / npix1; // mean brightness for group, 0-255 } for (rgb = 0; rgb < 3; rgb++) // do same for image2 for (ii = jj = 0; jj < 256; jj++) { brlev2[rgb][jj] = 0; npix2 = npix1; while (npix2 > 0 && ii < 256) { npix3 = brdist2[rgb][ii]; if (npix3 == 0) { ++ii; continue; } if (npix3 > npix2) npix3 = npix2; brlev2[rgb][jj] += ii * npix3; brdist2[rgb][ii] -= npix3; npix2 -= npix3; } brlev2[rgb][jj] = brlev2[rgb][jj] / npix1; } for (rgb = 0; rgb < 3; rgb++) // color for (ii = jj = 0; ii < 256; ii++) // brlev1 brightness, 0 to 255 { if (ii == 0) bratio = 1; while (ii > brlev2[rgb][jj] && jj < 256) ++jj; // find matching brlev2 brightness a2 = brlev2[rgb][jj]; // next higher value b2 = brlev1[rgb][jj]; if (a2 > 0 && b2 > 0) { if (jj > 0) { a1 = brlev2[rgb][jj-1]; // next lower value b1 = brlev1[rgb][jj-1]; } else a1 = b1 = 0; if (ii == 0) bratio = b2 / a2; else bratio = (b1 + (ii-a1)/(a2-a1) * (b2-b1)) / ii; // interpolate } if (bratio < 0.2) bratio = 0.2; // contain outliers if (bratio > 5) bratio = 5; Bratios2[rgb][ii] = bratio; } for (rgb = 0; rgb < 3; rgb++) // color for (ii = jj = 0; ii < 256; ii++) // brlev2 brightness, 0 to 255 { if (ii == 0) bratio = 1; while (ii > brlev1[rgb][jj] && jj < 256) ++jj; // find matching brlev1 brightness a2 = brlev1[rgb][jj]; // next higher value b2 = brlev2[rgb][jj]; if (a2 > 0 && b2 > 0) { if (jj > 0) { a1 = brlev1[rgb][jj-1]; // next lower value b1 = brlev2[rgb][jj-1]; } else a1 = b1 = 0; if (ii == 0) bratio = b2 / a2; else bratio = (b1 + (ii-a1)/(a2-a1) * (b2-b1)) / ii; // interpolate } if (bratio < 0.2) bratio = 0.2; // contain outliers if (bratio > 5) bratio = 5; Bratios1[rgb][ii] = bratio; } for (ii = 0; ii < 65536; ii++) // convert brightness ratios into { // conversion factors jj = ii / 256; for (rgb = 0; rgb < 3; rgb++) { cimRGBmf1[rgb][ii] = sqrt(Bratios1[rgb][jj]) * ii; // use sqrt(ratio) so that adjustment cimRGBmf2[rgb][ii] = sqrt(Bratios2[rgb][jj]) * ii; // can be applied to both images } } return; } // Use color match data from cim_match_colors() to // modify images so the colors match. void cim_adjust_colors(PXM *pxm, int fwhich) // v.10.7 { int ww, hh, px, py; int red, green, blue, max; uint16 *pix; double f1; ww = pxm->ww; hh = pxm->hh; for (py = 0; py < hh; py++) for (px = 0; px < ww; px++) { pix = PXMpix(pxm,px,py); red = pix[0]; green = pix[1]; blue = pix[2]; if (! blue) continue; if (fwhich == 1) { red = cimRGBmf1[0][red]; green = cimRGBmf1[1][green]; blue = cimRGBmf1[2][blue]; } if (fwhich == 2) { red = cimRGBmf2[0][red]; green = cimRGBmf2[1][green]; blue = cimRGBmf2[2][blue]; } if (red > 65535 || green > 65535 || blue > 65535) { max = red; if (green > max) max = green; if (blue > max) max = blue; f1 = 65535.0 / max; red = red * f1; green = green * f1; blue = blue * f1; } if (! blue) blue = 1; // avoid 0 v.10.7 pix[0] = red; pix[1] = green; pix[2] = blue; } return; } // find pixels of greatest contrast within overlap area // flag high-contrast pixels to use in each image compare region void cim_get_redpix(int im1) // v.10.7 { int ww, hh, samp, xzone, yzone; int pxL, pxH, pyL, pyH; int px, py, ii, jj, npix; int red1, green1, blue1, red2, green2, blue2, tcon; int ov1xlo, ov1xhi, ov1ylo, ov1yhi; int Hdist[256], Vdist[256], Hmin, Vmin; double s8 = 1.0 / 770.0; double zsamp[16] = { 4,6,6,4,6,9,9,6,6,9,9,6,4,6,6,4 }; // % sample per zone, sum = 100 uchar *Hcon, *Vcon; uint16 *pix1, *pix2; PXM *pxm; pxm = cimPXMs[im1]; // v.11.04 ww = pxm->ww; hh = pxm->hh; if (cimRedpix) zfree(cimRedpix); // clear prior cimRedpix = zmalloc(ww*hh,"cimRedpix"); memset(cimRedpix,0,ww*hh); cimRedImage = im1; // image with red pixels ov1xlo = cimOv1xlo + cimSearchRange; // stay within x/y search range ov1xhi = cimOv1xhi - cimSearchRange; // so that red pixels persist ov1ylo = cimOv1ylo + cimSearchRange; // over offset changes ov1yhi = cimOv1yhi - cimSearchRange; for (yzone = 0; yzone < 4; yzone++) // loop 16 zones v.10.8 for (xzone = 0; xzone < 4; xzone++) { pxL = ov1xlo + 0.25 * xzone * (ov1xhi - ov1xlo); // px and py zone limits pxH = ov1xlo + 0.25 * (xzone+1) * (ov1xhi - ov1xlo); pyL = ov1ylo + 0.25 * yzone * (ov1yhi - ov1ylo); pyH = ov1ylo + 0.25 * (yzone+1) * (ov1yhi - ov1ylo); npix = (pxH - pxL) * (pyH - pyL); // zone pixels Hcon = (uchar *) zmalloc(npix,"cimRedpix"); // horizontal pixel contrast 0-255 Vcon = (uchar *) zmalloc(npix,"cimRedpix"); // vertical pixel contrast 0-255 ii = 4 * yzone + xzone; samp = cimSampSize * 0.01 * zsamp[ii]; // sample size for zone if (samp > 0.1 * npix) samp = 0.1 * npix; // limit to 10% of zone pixels for (py = pyL; py < pyH; py++) // scan image pixels in zone for (px = pxL; px < pxH; px++) { ii = (py-pyL) * (pxH-pxL) + (px-pxL); Hcon[ii] = Vcon[ii] = 0; // horiz. = vert. contrast = 0 if (py < 8 || py > hh-9) continue; // keep away from image edges if (px < 8 || px > ww-9) continue; pix1 = PXMpix(pxm,px,py-6); // verify not near void areas if (! pix1[2]) continue; pix1 = PXMpix(pxm,px+6,py); if (! pix1[2]) continue; pix1 = PXMpix(pxm,px,py+6); if (! pix1[2]) continue; pix1 = PXMpix(pxm,px-6,py); if (! pix1[2]) continue; pix1 = PXMpix(pxm,px,py); // candidate red pixel red1 = pix1[0]; green1 = pix1[1]; blue1 = pix1[2]; pix2 = PXMpix(pxm,px+2,py); // 2 pixels to right red2 = pix2[0]; green2 = pix2[1]; blue2 = pix2[2]; tcon = abs(red1-red2) + abs(green1-green2) + abs(blue1-blue2); // horizontal contrast Hcon[ii] = int(tcon * s8); // scale 0 - 255 pix2 = PXMpix(pxm,px,py+2); // 2 pixels below red2 = pix2[0]; green2 = pix2[1]; blue2 = pix2[2]; tcon = abs(red1-red2) + abs(green1-green2) + abs(blue1-blue2); // vertical contrast Vcon[ii] = int(tcon * s8); } for (ii = 0; ii < 256; ii++) Hdist[ii] = Vdist[ii] = 0; // clear contrast distributions for (py = pyL; py < pyH; py++) // scan image pixels for (px = pxL; px < pxH; px++) { // build contrast distributions ii = (py-pyL) * (pxH-pxL) + (px-pxL); ++Hdist[Hcon[ii]]; ++Vdist[Vcon[ii]]; } for (npix = 0, ii = 255; ii > 0; ii--) // find minimum contrast needed to get { // enough pixels for sample size npix += Hdist[ii]; // (horizontal contrast pixels) if (npix > samp) break; } Hmin = ii; for (npix = 0, ii = 255; ii > 0; ii--) // (verticle contrast pixels) { npix += Vdist[ii]; if (npix > samp) break; } Vmin = ii; for (py = pyL; py < pyH; py++) // scan zone pixels for (px = pxL; px < pxH; px++) { ii = (py-pyL) * (pxH-pxL) + (px-pxL); jj = py * ww + px; if (Hcon[ii] > Hmin) cimRedpix[jj] = 1; // flag pixels above min. contrast if (Vcon[ii] > Vmin) cimRedpix[jj] = 1; } zfree(Hcon); zfree(Vcon); for (py = pyL; py < pyH; py++) // scan zone pixels for (px = pxL; px < pxH; px++) { ii = (py-pyL) * (pxH-pxL) + (px-pxL); jj = py * ww + px; if (! cimRedpix[jj]) continue; npix = cimRedpix[jj-1] + cimRedpix[jj+1]; // eliminate flagged pixels with no npix += cimRedpix[jj-ww] + cimRedpix[jj+ww]; // neighboring flagged pixels npix += cimRedpix[jj-ww-1] + cimRedpix[jj+ww-1]; // v.11.03 npix += cimRedpix[jj-ww+1] + cimRedpix[jj+ww+1]; if (npix < 2) cimRedpix[jj] = 0; } for (py = pyL; py < pyH; py++) // scan zone pixels for (px = pxL; px < pxH; px++) { ii = (py-pyL) * (pxH-pxL) + (px-pxL); jj = py * ww + px; if (cimRedpix[jj] == 1) { // flag horizontal group of 3 cimRedpix[jj+1] = 2; cimRedpix[jj+2] = 2; cimRedpix[jj+ww] = 2; // and vertical group of 3 cimRedpix[jj+2*ww] = 2; } } } return; } // curve image based on lens parameters (pano) // replaces cimPXMs[im] with curved version void cim_curve_image(int im) // overhauled v.11.03 { int px, py, ww, hh, vstat; double ww2, hh2; double dx, dy; double F = lens_mm; // lens focal length, 35mm equivalent double S = 35.0; // corresponding image width double R1, R2, G, T, bow; PXM *pxmin, *pxmout; uint16 vpix[3], *pix; pxmin = cimPXMs[im]; // input and output image ww = pxmin->ww; // 200 hh = pxmin->hh; ww2 = 0.5 * ww; // 100 hh2 = 0.5 * hh; if (hh > ww) S = S * ww / hh; // vertical format F = F / S; // 28 / 35 // scale to image dimensions S = ww2; // 100 F = F * ww; // 160 R1 = F; // cylinder tangent to image plane bow = -lens_bow * 0.01 / hh2 / hh2; // lens bow % to fraction if (hh > ww) bow = -lens_bow * 0.01 / ww2 / ww2; pxmout = PXM_make(ww,hh,16); // temp. output PXM for (py = 0; py < hh; py++) // cylindrical projection v.11.03 for (px = 0; px < ww; px++) { dx = px - ww2; dy = py - hh2; T = dx / R1; dx = F * tan(T); R2 = sqrt(dx * dx + F * F); G = R1 - R2; dy = (dy * R2) / (R2 + G); dx += bow * dx * dy * dy; // barrel distortion dx += ww2; dy += hh2; vstat = vpixel(pxmin,dx,dy,vpix); // input virtual pixel pix = PXMpix(pxmout,px,py); // output real pixel if (vstat) { pix[0] = vpix[0]; pix[1] = vpix[1]; pix[2] = vpix[2]; } else pix[0] = pix[1] = pix[2] = 0; // voided pixels are (0,0,0) } for (px = 1; px < ww2; px++) { // compute image shrinkage pix = PXMpix(pxmout,px,hh/2); if (pix[2]) break; } cimShrink = px-1; // = 0 if no curvature PXM_free(pxmin); // replace input with output PXM cimPXMs[im] = pxmout; return; } // version for vertical panorama void cim_curve_Vimage(int im) // v.11.04 { int px, py, ww, hh, vstat; double ww2, hh2; double dx, dy; double F = lens_mm; // lens focal length, 35mm equivalent double S = 35.0; // corresponding image width double R1, R2, G, T, bow; PXM *pxmin, *pxmout; uint16 vpix[3], *pix; pxmin = cimPXMs[im]; // input and output image ww = pxmin->ww; // 200 hh = pxmin->hh; ww2 = 0.5 * ww; // 100 hh2 = 0.5 * hh; if (hh > ww) S = S * ww / hh; // vertical format F = F / S; // 28 / 35 // scale to image dimensions S = ww2; // 100 F = F * ww; // 160 R1 = F; // cylinder tangent to image plane bow = -lens_bow * 0.01 / hh2 / hh2; // lens bow % to fraction if (hh > ww) bow = -lens_bow * 0.01 / ww2 / ww2; pxmout = PXM_make(ww,hh,16); // temp. output PXM for (py = 0; py < hh; py++) // cylindrical projection v.11.03 for (px = 0; px < ww; px++) { dx = px - ww2; dy = py - hh2; T = dy / R1; dy = F * tan(T); R2 = sqrt(dy * dy + F * F); G = R1 - R2; dx = (dx * R2) / (R2 + G); dy += bow * dy * dx * dx; // barrel distortion dx += ww2; dy += hh2; vstat = vpixel(pxmin,dx,dy,vpix); // input virtual pixel pix = PXMpix(pxmout,px,py); // output real pixel if (vstat) { pix[0] = vpix[0]; pix[1] = vpix[1]; pix[2] = vpix[2]; } else pix[0] = pix[1] = pix[2] = 0; // voided pixels are (0,0,0) } for (py = 1; py < hh2; py++) { // compute image shrinkage pix = PXMpix(pxmout,ww/2,py); if (pix[2]) break; } cimShrink = py-1; // = 0 if no curvature PXM_free(pxmin); // replace input with output PXM cimPXMs[im] = pxmout; return; } // Warp 4 image corners according to cimOffs[im].wx[ii] and .wy[ii] // corner = 0 = NW, 1 = NE, 2 = SE, 3 = SW // 4 corners move by these pixel amounts and center does not move. // input: cimPXMs[im] (flat or curved) output: cimPXMw[im] namespace cim_warp_image_names { PXM *pxmin, *pxmout; double ww, hh, wwi, hhi; double wx0, wy0, wx1, wy1, wx2, wy2, wx3, wy3; } void cim_warp_image(int im) // caller function v.10.8 { using namespace cim_warp_image_names; void * cim_warp_image_wthread(void *arg); pxmin = cimPXMs[im]; // input and output pixmaps pxmout = cimPXMw[im]; PXM_free(pxmout); // v.11.04 pxmout = PXM_copy(pxmin); cimPXMw[im] = pxmout; ww = pxmin->ww; hh = pxmin->hh; wwi = 1.0 / ww; hhi = 1.0 / hh; wx0 = cimOffs[im].wx[0]; // corner warps wy0 = cimOffs[im].wy[0]; wx1 = cimOffs[im].wx[1]; wy1 = cimOffs[im].wy[1]; wx2 = cimOffs[im].wx[2]; wy2 = cimOffs[im].wy[2]; wx3 = cimOffs[im].wx[3]; wy3 = cimOffs[im].wy[3]; for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(cim_warp_image_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion return; } void * cim_warp_image_wthread(void *arg) // worker thread function v.10.8 { using namespace cim_warp_image_names; int index = *((int *) arg); int pxm, pym, vstat; uint16 vpix[3], *pixm; double px, py, dx, dy, coeff; for (pym = index; pym < hh; pym += Nwt) // loop all pixels for this thread for (pxm = 0; pxm < ww; pxm++) { dx = dy = 0.0; coeff = (1.0 - pym * hhi - pxm * wwi); // corner 0 NW if (coeff > 0) { dx += coeff * wx0; dy += coeff * wy0; } coeff = (1.0 - pym * hhi - (ww - pxm) * wwi); // corner 1 NE if (coeff > 0) { dx += coeff * wx1; dy += coeff * wy1; } coeff = (1.0 - (hh - pym) * hhi - (ww - pxm) * wwi); // corner 2 SE if (coeff > 0) { dx += coeff * wx2; dy += coeff * wy2; } coeff = (1.0 - (hh - pym) * hhi - pxm * wwi); // corner 3 SW if (coeff > 0) { dx += coeff * wx3; dy += coeff * wy3; } px = pxm + dx; // source pixel location py = pym + dy; vstat = vpixel(pxmin,px,py,vpix); // input virtual pixel pixm = PXMpix(pxmout,pxm,pym); // output real pixel if (vstat) { pixm[0] = vpix[0]; pixm[1] = vpix[1]; pixm[2] = vpix[2]; } else pixm[0] = pixm[1] = pixm[2] = 0; } exit_wthread(); return 0; // not executed, avoid gcc warning } // warp image for pano, left side corners only, reduced warp range // input: cimPXMs[im] (curved) // output: cimPXMw[im] (warped) // fblend: 0 = process entire image // 1 = process left half only // 2 = process blend stripe only void cim_warp_image_pano(int im, int fblend) // v.10.8 { int ww, hh, ww2, hh2, pxL, pxH; int pxm, pym, vstat; uint16 vpix[3], *pixm; double ww2i, hh2i, pxs, pys, xdisp, ydisp; double wx0, wy0, wx3, wy3; PXM *pxmin, *pxmout; pxmin = cimPXMs[im]; // input and output pixmaps pxmout = cimPXMw[im]; PXM_free(pxmout); // v.11.04 pxmout = PXM_copy(pxmin); cimPXMw[im] = pxmout; ww = pxmin->ww; hh = pxmin->hh; ww2 = ww / 2; hh2 = hh / 2; ww2i = 1.0 / ww2; // v.10.8 hh2i = 1.0 / hh2; wx0 = cimOffs[im].wx[0]; // NW corner warp wy0 = cimOffs[im].wy[0]; wx3 = cimOffs[im].wx[3]; // SW corner warp wy3 = cimOffs[im].wy[3]; pxL = 0; // entire image v.10.8 pxH = ww; if (fblend == 1) // left half pxH = ww2; if (fblend == 2) { pxL = cimOv2xlo; // limit to overlap/blend width pxH = cimOv2xhi; } for (pym = 0; pym < hh; pym++) // loop all output pixels for (pxm = pxL; pxm < pxH; pxm++) { pixm = PXMpix(pxmout,pxm,pym); // output pixel xdisp = (pxm - ww2) * ww2i; // -1 ... 0 ... +1 ydisp = (pym - hh2) * hh2i; // v.11.04 if (xdisp > 0) { // right half, no warp pxs = pxm; pys = pym; } else if (ydisp < 0) { // use NW corner warp pxs = pxm + wx0 * xdisp * ydisp; pys = pym + wy0 * xdisp * ydisp; } else { // use SW corner warp pxs = pxm + wx3 * xdisp * ydisp; pys = pym + wy3 * xdisp * ydisp; } vstat = vpixel(pxmin,pxs,pys,vpix); // input virtual pixel if (vstat) { pixm[0] = vpix[0]; pixm[1] = vpix[1]; pixm[2] = vpix[2]; } else pixm[0] = pixm[1] = pixm[2] = 0; } for (pxm = 1; pxm < ww2; pxm++) { // compute image shrinkage pixm = PXMpix(pxmout,pxm,hh2); // used by cim_get_overlap() if (pixm[2]) break; } cimShrink = pxm-1; return; } // vertical pano version - warp top side corners (NW, NE) void cim_warp_image_Vpano(int im, int fblend) // v.11.04 { int ww, hh, ww2, hh2, pyL, pyH; int pxm, pym, vstat; uint16 vpix[3], *pixm; double ww2i, hh2i, pxs, pys, xdisp, ydisp; double wx0, wy0, wx1, wy1; PXM *pxmin, *pxmout; pxmin = cimPXMs[im]; // input and output pixmaps pxmout = cimPXMw[im]; PXM_free(pxmout); // v.11.04 pxmout = PXM_copy(pxmin); cimPXMw[im] = pxmout; ww = pxmin->ww; hh = pxmin->hh; ww2 = ww / 2; hh2 = hh / 2; ww2i = 1.0 / ww2; // v.10.8 hh2i = 1.0 / hh2; wx0 = cimOffs[im].wx[0]; // NW corner warp wy0 = cimOffs[im].wy[0]; wx1 = cimOffs[im].wx[1]; // NE corner warp wy1 = cimOffs[im].wy[1]; pyL = 0; // entire image v.10.8 pyH = hh; if (fblend == 1) // top half pyH = hh2; if (fblend == 2) { pyL = cimOv2ylo; // limit to overlap/blend width pyH = cimOv2yhi; } for (pym = pyL; pym < pyH; pym++) // loop all output pixels for (pxm = 0; pxm < ww; pxm++) { pixm = PXMpix(pxmout,pxm,pym); // output pixel xdisp = (pxm - ww2) * ww2i; // -1 ... 0 ... +1 ydisp = (pym - hh2) * hh2i; if (ydisp > 0) { // bottom half, no warp pxs = pxm; pys = pym; } else if (xdisp < 0) { // use NW corner warp pxs = pxm + wx0 * xdisp * ydisp; pys = pym + wy0 * xdisp * ydisp; } else { // use NE corner warp pxs = pxm + wx1 * xdisp * ydisp; pys = pym + wy1 * xdisp * ydisp; } vstat = vpixel(pxmin,pxs,pys,vpix); // input virtual pixel if (vstat) { pixm[0] = vpix[0]; pixm[1] = vpix[1]; pixm[2] = vpix[2]; } else pixm[0] = pixm[1] = pixm[2] = 0; } for (pym = 1; pym < hh2; pym++) { // compute image shrinkage pixm = PXMpix(pxmout,ww2,pym); // used by cim_get_overlap() if (pixm[2]) break; } cimShrink = pym-1; return; } // fine-align a pair of images im1 and im2 // cimPXMs[im2] is aligned with cimPXMs[im1] // inputs are cimOffs[im1] and cimOffs[im2] (x/y/t and corner offsets) // output is adjusted offsets and corner warp values for im2 only // (im1 is used as-is without corner warps) void cim_align_image(int im1, int im2) // speedup v.11.03 { int ii, corner1, cornerstep, cornerN, pass; double xyrange, xystep, trange, tstep, wrange, wstep; double xfL, xfH, yfL, yfH, tfL, tfH; double wxL, wxH, wyL, wyH; double match, matchB; cimoffs offsets0, offsetsB; offsets0 = cimOffs[im2]; // initial offsets offsetsB = offsets0; // = best offsets so far matchB = cim_match_images(im1,im2); // = best image match level if (cimPanoV) cim_show_Vimages(0,0); // v.11.04 else cim_show_images(0,0); // show with 50/50 blend for (pass = 1; pass <=2; pass++) // main pass and 2nd pass v.10.8 { xyrange = cimSearchRange; // x/y search range and step xystep = cimSearchStep; trange = xyrange / (cimOv1yhi - cimOv1ylo); // angle range, radians tstep = trange * xystep / xyrange; if (pass == 2) { xyrange = 0.5 * xyrange; // 2nd pass, reduce range and step xystep = 0.5 * xystep; // v.11.04 trange = 0.5 * trange; tstep = 0.5 * tstep; } // search x/y/t range for best match xfL = cimOffs[im2].xf - xyrange; xfH = cimOffs[im2].xf + xyrange + 0.5 * xystep; yfL = cimOffs[im2].yf - xyrange; yfH = cimOffs[im2].yf + xyrange + 0.5 * xystep; tfL = cimOffs[im2].tf - trange; tfH = cimOffs[im2].tf + trange + 0.5 * tstep; for (cimOffs[im2].xf = xfL; cimOffs[im2].xf < xfH; cimOffs[im2].xf += xystep) for (cimOffs[im2].yf = yfL; cimOffs[im2].yf < yfH; cimOffs[im2].yf += xystep) for (cimOffs[im2].tf = tfL; cimOffs[im2].tf < tfH; cimOffs[im2].tf += tstep) { match = cim_match_images(im1,im2); // get match level if (sigdiff(match,matchB,0.00001) > 0) { matchB = match; // save best match offsetsB = cimOffs[im2]; } sprintf(SB_text,"align: %d match: %.5f",cimNsearch++,matchB); // update status bar zmainloop(); // v.11.11.1 } cimOffs[im2] = offsetsB; // restore best match if (cimPanoV) cim_show_Vimages(0,0); // v.11.04 else cim_show_images(0,0); // warp corners and search for best match wrange = cimWarpRange; // corner warp range and step wstep = cimWarpStep; if (! wrange) continue; if (pass == 2) { // 2nd pass, 1/4 range and 1/2 step wrange = wrange / 4; wstep = wstep / 2; } corner1 = 0; // process all 4 corners cornerN = 3; cornerstep = 1; if (cimPano) { corner1 = 0; // left side corners 0, 3 cornerN = 3; cornerstep = 3; } if (cimPanoV) { corner1 = 0; // top side corners 0, 1 v.11.04 cornerN = 1; cornerstep = 1; } matchB = cim_match_images(im1,im2); // initial image match level for (ii = corner1; ii <= cornerN; ii += cornerstep) // modify one corner at a time { wxL = cimOffs[im2].wx[ii] - wrange; wxH = cimOffs[im2].wx[ii] + wrange + 0.5 * wstep; wyL = cimOffs[im2].wy[ii] - wrange; wyH = cimOffs[im2].wy[ii] + wrange + 0.5 * wstep; for (cimOffs[im2].wx[ii] = wxL; cimOffs[im2].wx[ii] < wxH; cimOffs[im2].wx[ii] += wstep) for (cimOffs[im2].wy[ii] = wyL; cimOffs[im2].wy[ii] < wyH; cimOffs[im2].wy[ii] += wstep) { match = cim_match_images(im1,im2); // get match level if (sigdiff(match,matchB,0.00001) > 0) { matchB = match; // save best match offsetsB = cimOffs[im2]; } sprintf(SB_text,"warp: %d match: %.5f",cimNsearch++,matchB); zmainloop(); // v.11.11.1 } cimOffs[im2] = offsetsB; // restore best match } if (cimPano) cim_warp_image_pano(im2,1); // apply corner warps v.11.04 else if (cimPanoV) cim_warp_image_Vpano(im2,1); else cim_warp_image(im2); if (cimPanoV) cim_show_Vimages(0,0); // v.11.04 else cim_show_images(0,0); } return; } // Compare 2 pixels using precalculated brightness ratios // 1.0 = perfect match 0 = total mismatch (black/white) inline double cim_match_pixels(uint16 *pix1, uint16 *pix2) // v.10.7 { double red1, green1, blue1, red2, green2, blue2; double reddiff, greendiff, bluediff, match; double ff = 1.0 / 65536.0; red1 = pix1[0]; green1 = pix1[1]; blue1 = pix1[2]; red2 = pix2[0]; green2 = pix2[1]; blue2 = pix2[2]; reddiff = ff * fabs(red1-red2); // 0 = perfect match greendiff = ff * fabs(green1-green2); // 1 = total mismatch bluediff = ff * fabs(blue1-blue2); match = (1.0 - reddiff) * (1.0 - greendiff) * (1.0 - bluediff); // 1 = perfect match return match; } // Compare two images in overlapping areas. // Use the high-contrast pixels from cim_get_redpix() // return: 1 = perfect match, 0 = total mismatch (black/white) // cimPXMs[im1] is matched to cimPXMs[im2] + virtual warps double cim_match_images(int im1, int im2) // v.11.03 { uint16 *pix1, vpix2[3]; int ww, hh, ww2, hh2; int px1, py1, ii, vstat; double wwi, hhi, ww2i, hh2i, xdisp, ydisp; double wx0, wy0, wx1, wy1, wx2, wy2, wx3, wy3; double dx, dy, px2, py2; double x1, y1, t1, x2, y2, t2; double xoff, yoff, toff, costf, sintf, coeff; double match, cmatch, maxcmatch; PXM *pxm1, *pxm2; x1 = cimOffs[im1].xf; // im1, im2 absolute offsets y1 = cimOffs[im1].yf; t1 = cimOffs[im1].tf; x2 = cimOffs[im2].xf; y2 = cimOffs[im2].yf; t2 = cimOffs[im2].tf; xoff = (x2 - x1) * cos(t1) + (y2 - y1) * sin(t1); // offset of im2 relative to im1 yoff = (y2 - y1) * cos(t1) - (x2 - x1) * sin(t1); toff = t2 - t1; costf = cos(toff); sintf = sin(toff); wx0 = cimOffs[im2].wx[0]; // im2 corner warps wy0 = cimOffs[im2].wy[0]; wx1 = cimOffs[im2].wx[1]; wy1 = cimOffs[im2].wy[1]; wx2 = cimOffs[im2].wx[2]; wy2 = cimOffs[im2].wy[2]; wx3 = cimOffs[im2].wx[3]; wy3 = cimOffs[im2].wy[3]; pxm1 = cimPXMs[im1]; // base image pxm2 = cimPXMs[im2]; // comparison image (virtual warps) ww = pxm1->ww; hh = pxm1->hh; ww2 = ww / 2; hh2 = hh / 2; wwi = 1.0 / ww; hhi = 1.0 / hh; ww2i = 1.0 / ww2; hh2i = 1.0 / hh2; cmatch = 0; maxcmatch = 1; if (cimPano) { for (py1 = cimOv1ylo; py1 < cimOv1yhi; py1++) // loop overlapping pixels for (px1 = cimOv1xlo; px1 < cimOv1xhi; px1++) { ii = py1 * ww + px1; // skip low-contrast pixels if (! cimRedpix[ii]) continue; pix1 = PXMpix(pxm1,px1,py1); // image1 pixel if (! pix1[2]) continue; // ignore void pixels px2 = costf * (px1 - xoff) + sintf * (py1 - yoff); // corresponding image2 pixel py2 = costf * (py1 - yoff) - sintf * (px1 - xoff); dx = dy = 0.0; // corner warp xdisp = (px2 - ww2) * ww2i; // -1 ... 0 ... +1 ydisp = (py2 - hh2) * hh2i; // v.11.04 if (xdisp > 0) // right half, no warp dx = dy = 0; else if (ydisp < 0) { // use NW corner warp dx = wx0 * xdisp * ydisp; dy = wy0 * xdisp * ydisp; } else { // use SW corner warp dx = wx3 * xdisp * ydisp; dy = wy3 * xdisp * ydisp; } px2 += dx; // source pixel location py2 += dy; // after corner warps vstat = vpixel(pxm2,px2,py2,vpix2); if (! vstat) continue; match = cim_match_pixels(pix1,vpix2); // compare brightness adjusted cmatch += match; // accumulate total match maxcmatch += 1.0; } } else if (cimPanoV) { for (py1 = cimOv1ylo; py1 < cimOv1yhi; py1++) // loop overlapping pixels for (px1 = cimOv1xlo; px1 < cimOv1xhi; px1++) { ii = py1 * ww + px1; // skip low-contrast pixels if (! cimRedpix[ii]) continue; pix1 = PXMpix(pxm1,px1,py1); // image1 pixel if (! pix1[2]) continue; // ignore void pixels px2 = costf * (px1 - xoff) + sintf * (py1 - yoff); // corresponding image2 pixel py2 = costf * (py1 - yoff) - sintf * (px1 - xoff); dx = dy = 0.0; // corner warp xdisp = (px2 - ww2) * ww2i; // -1 ... 0 ... +1 ydisp = (py2 - hh2) * hh2i; if (ydisp > 0) // bottom half, no warp dx = dy = 0; else if (xdisp < 0) { // use NW corner warp dx = wx0 * xdisp * ydisp; dy = wy0 * xdisp * ydisp; } else { // use NE corner warp dx = wx1 * xdisp * ydisp; dy = wy1 * xdisp * ydisp; } px2 += dx; // source pixel location py2 += dy; // after corner warps vstat = vpixel(pxm2,px2,py2,vpix2); if (! vstat) continue; match = cim_match_pixels(pix1,vpix2); // compare brightness adjusted cmatch += match; // accumulate total match maxcmatch += 1.0; } } else { for (py1 = cimOv1ylo; py1 < cimOv1yhi; py1++) // loop overlapping pixels for (px1 = cimOv1xlo; px1 < cimOv1xhi; px1++) { ii = py1 * ww + px1; // skip low-contrast pixels if (! cimRedpix[ii]) continue; pix1 = PXMpix(pxm1,px1,py1); // image1 pixel if (! pix1[2]) continue; // ignore void pixels px2 = costf * (px1 - xoff) + sintf * (py1 - yoff); // corresponding image2 pixel py2 = costf * (py1 - yoff) - sintf * (px1 - xoff); dx = dy = 0.0; // corner warp coeff = (1.0 - py2 * hhi - px2 * wwi); // corner 0 NW if (coeff > 0) { dx += coeff * wx0; dy += coeff * wy0; } coeff = (1.0 - py2 * hhi - (ww - px2) * wwi); // corner 1 NE if (coeff > 0) { dx += coeff * wx1; dy += coeff * wy1; } coeff = (1.0 - (hh - py2) * hhi - (ww - px2) * wwi); // corner 2 SE if (coeff > 0) { dx += coeff * wx2; dy += coeff * wy2; } coeff = (1.0 - (hh - py2) * hhi - px2 * wwi); // corner 3 SW if (coeff > 0) { dx += coeff * wx3; dy += coeff * wy3; } px2 += dx; // source pixel location py2 += dy; // after corner warps vstat = vpixel(pxm2,px2,py2,vpix2); if (! vstat) continue; match = cim_match_pixels(pix1,vpix2); // compare brightness adjusted cmatch += match; // accumulate total match maxcmatch += 1.0; } } return cmatch / maxcmatch; } // combine and show all images // fnew >> make new E3 output image and adjust x and y offsets // cimPXMw[*] >> E3pxm16 >> main window // fblend: 0 > 50/50 blend, 1 > gradual blend namespace cim_show_images_names { int im1, im2, iminc, fblendd; int wwlo[10], wwhi[10]; int hhlo[10], hhhi[10]; double costf[10], sintf[10]; } void cim_show_images(int fnew, int fblend) // v.10.7 { using namespace cim_show_images_names; void * cim_show_images_wthread(void *arg); int imx, pxr, pyr, ii, px3, py3; int ww, hh, wwmin, wwmax, hhmin, hhmax, bmid; double xf, yf, tf; uint16 *pix3; mutex_lock(&Fpixmap_lock); // stop window updates fblendd = fblend; // blend 50/50 or gradual ramp im1 = cimShowIm1; // two images to show im2 = cimShowIm2; iminc = im2 - im1; // v.10.9 if (cimShowAll) { // show all images v.10.9 im1 = 0; im2 = cimNF-1; iminc = 1; } for (imx = 0; imx < cimNF; imx++) { // pre-calculate costf[imx] = cos(cimOffs[imx].tf); sintf[imx] = sin(cimOffs[imx].tf); } if (fnew) PXM_free(E3pxm16); // force new output pixmap if (! E3pxm16) // allocate output pixmap { wwmin = hhmin = 9999; // initial values wwmax = cimPXMw[im2]->ww; hhmax = cimPXMw[im2]->hh; for (imx = im1; imx <= im2; imx += iminc) // find min and max ww and hh extents { xf = cimOffs[imx].xf; yf = cimOffs[imx].yf; tf = cimOffs[imx].tf; ww = cimPXMw[imx]->ww; hh = cimPXMw[imx]->hh; if (xf < wwmin) wwmin = xf; if (xf - tf * hh < wwmin) wwmin = xf + tf * hh; if (xf + ww > wwmax) wwmax = xf + ww; if (xf + ww - tf * hh > wwmax) wwmax = xf + ww - tf * hh; if (yf < hhmin) hhmin = yf; if (yf + tf * ww < hhmin) hhmin = yf + tf * ww; if (yf + hh > hhmax) hhmax = yf + hh; if (yf + hh + tf * ww > hhmax) hhmax = yf + hh + tf * ww; } for (imx = im1; imx <= im2; imx += iminc) { // align to top and left edges cimOffs[imx].xf -= wwmin; cimOffs[imx].yf -= hhmin; } wwmax = wwmax - wwmin; hhmax = hhmax - hhmin; wwmin = hhmin = 0; if (cimPano) { for (imx = im1; imx <= im2; imx += iminc) // deliberate margins v.11.03 cimOffs[imx].yf += 10; hhmax += 20; } if (cimPanoV) { for (imx = im1; imx <= im2; imx += iminc) // deliberate margins v.11.04 cimOffs[imx].xf += 10; wwmax += 20; } E3pxm16 = PXM_make(wwmax,hhmax,16); // allocate output image E3ww = wwmax; E3hh = hhmax; } for (imx = im1; imx <= im2; imx += iminc) // get ww range of each image { ww = cimPXMw[imx]->ww; hh = cimPXMw[imx]->hh; tf = cimOffs[imx].tf; wwlo[imx] = cimOffs[imx].xf; wwhi[imx] = wwlo[imx] + ww; wwlo[imx] -= 0.5 * tf * hh; // use midpoint of sloping edges wwhi[imx] -= 0.5 * tf * hh; } if (cimBlend) { // blend width active for (imx = im1; imx <= im2-1; imx += iminc) // reduce for blend width { if (wwhi[imx] - wwlo[imx+1] > cimBlend) { bmid = (wwhi[imx] + wwlo[imx+1]) / 2; wwlo[imx+1] = bmid - cimBlend / 2; wwhi[imx] = bmid + cimBlend / 2; } } } for (ii = 0; ii < Nwt; ii++) // start worker threads v.10.7 start_wthread(cim_show_images_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion if (cimRedpix) { imx = cimRedImage; // paint red pixels for current image ww = cimPXMw[imx]->ww; // being aligned hh = cimPXMw[imx]->hh; for (ii = 0; ii < ww * hh; ii++) { if (cimRedpix[ii]) { pyr = ii / ww; // red pixel pxr = ii - pyr * ww; px3 = cimOffs[imx].xf + pxr * costf[imx] - pyr * sintf[imx] + 0.5; py3 = cimOffs[imx].yf + pyr * costf[imx] + pxr * sintf[imx] + 0.5; pix3 = PXMpix(E3pxm16,px3,py3); pix3[0] = 65535; pix3[1] = pix3[2] = 1; } } } mutex_unlock(&Fpixmap_lock); mwpaint2(); // update window zmainloop(); // v.11.11.1 return; } void * cim_show_images_wthread(void *arg) // working thread v.10.7 { using namespace cim_show_images_names; int index = *((int *) (arg)); int imx, imy; int px3, py3; int vstat, vstat1, vstat2; int red1, green1, blue1; int red2, green2, blue2; int red3, green3, blue3; double f1, f2, px, py; uint16 vpix[3], *pix3; red1 = green1 = blue1 = 0; f1 = f2 = 0.5; // to use if no fblend flag for (py3 = index; py3 < E3hh; py3 += Nwt) // loop E3 rows for (px3 = 0; px3 < E3ww; px3++) // loop E3 columns { vstat1 = vstat2 = 0; for (imx = imy = im1; imx <= im2; imx += iminc) // find which images overlap this pixel { if (px3 < wwlo[imx] || px3 > wwhi[imx]) continue; px = costf[imx] * (px3 - cimOffs[imx].xf) + sintf[imx] * (py3 - cimOffs[imx].yf); py = costf[imx] * (py3 - cimOffs[imx].yf) - sintf[imx] * (px3 - cimOffs[imx].xf); vstat = vpixel(cimPXMw[imx],px,py,vpix); if (! vstat) continue; if (! vstat1) { // first overlapping image vstat1 = 1; imy = imx; red1 = vpix[0]; green1 = vpix[1]; blue1 = vpix[2]; } else { // second image vstat2 = 1; red2 = vpix[0]; green2 = vpix[1]; blue2 = vpix[2]; break; } } imx = imy; // first of 1 or 2 overlapping images if (vstat1) { if (! vstat2) { red3 = red1; // use image1 pixel green3 = green1; blue3 = blue1; } else { // use blended image1 + image2 pixels if (fblendd) { f1 = wwhi[imx] - px3; // gradual blend f2 = px3 - wwlo[imx+1]; f1 = f1 / (f1 + f2); f2 = 1.0 - f1; } red3 = f1 * red1 + f2 * red2 + 0.5; green3 = f1 * green1 + f2 * green2 + 0.5; blue3 = f1 * blue1 + f2 * blue2 + 0.5; } } else red3 = green3 = blue3 = 0; // no overlapping image, use black pixel pix3 = PXMpix(E3pxm16,px3,py3); // output pixel pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } exit_wthread(); return 0; // not executed, avoid gcc warning } // version for vertical panorama void cim_show_Vimages(int fnew, int fblend) // v.11.04 { using namespace cim_show_images_names; void * cim_show_Vimages_wthread(void *arg); int imx, pxr, pyr, ii, px3, py3; int ww, hh, wwmin, wwmax, hhmin, hhmax, bmid; double xf, yf, tf; uint16 *pix3; mutex_lock(&Fpixmap_lock); // stop window updates fblendd = fblend; // blend 50/50 or gradual ramp im1 = 0; // show all images (pano) im2 = cimNF-1; for (imx = 0; imx < cimNF; imx++) { // pre-calculate costf[imx] = cos(cimOffs[imx].tf); sintf[imx] = sin(cimOffs[imx].tf); } if (fnew) PXM_free(E3pxm16); // force new output pixmap if (! E3pxm16) // allocate output pixmap { wwmin = hhmin = 9999; wwmax = hhmax = 0; for (imx = im1; imx <= im2; imx++) // find min and max ww and hh extents { xf = cimOffs[imx].xf; yf = cimOffs[imx].yf; tf = cimOffs[imx].tf; ww = cimPXMw[imx]->ww; hh = cimPXMw[imx]->hh; if (xf < wwmin) wwmin = xf; if (xf - tf * hh < wwmin) wwmin = xf + tf * hh; if (xf + ww > wwmax) wwmax = xf + ww; if (xf + ww - tf * hh > wwmax) wwmax = xf + ww - tf * hh; if (yf < hhmin) hhmin = yf; if (yf + tf * ww < hhmin) hhmin = yf + tf * ww; if (yf + hh > hhmax) hhmax = yf + hh; if (yf + hh + tf * ww > hhmax) hhmax = yf + hh + tf * ww; } for (imx = im1; imx <= im2; imx++) { // align to top and left edges cimOffs[imx].xf -= wwmin; cimOffs[imx].yf -= hhmin; } wwmax = wwmax - wwmin; hhmax = hhmax - hhmin; wwmin = hhmin = 0; for (imx = im1; imx <= im2; imx++) // deliberate margins cimOffs[imx].xf += 10; wwmax += 20; E3pxm16 = PXM_make(wwmax,hhmax,16); // allocate output image E3ww = wwmax; E3hh = hhmax; } for (imx = im1; imx <= im2; imx++) // get hh range of each image { ww = cimPXMw[imx]->ww; hh = cimPXMw[imx]->hh; tf = cimOffs[imx].tf; hhlo[imx] = cimOffs[imx].yf; hhhi[imx] = hhlo[imx] + hh; hhlo[imx] += 0.5 * tf * ww; // use midpoint of sloping edges hhhi[imx] += 0.5 * tf * ww; } if (cimBlend) { // blend width active for (imx = im1; imx <= im2-1; imx++) // reduce for blend width { if (hhhi[imx] - hhlo[imx+1] > cimBlend) { bmid = (hhhi[imx] + hhlo[imx+1]) / 2; hhlo[imx+1] = bmid - cimBlend / 2; hhhi[imx] = bmid + cimBlend / 2; } } } for (ii = 0; ii < Nwt; ii++) // start worker threads v.10.7 start_wthread(cim_show_Vimages_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion if (cimRedpix) { imx = cimRedImage; // paint red pixels for current image ww = cimPXMw[imx]->ww; // being aligned hh = cimPXMw[imx]->hh; for (ii = 0; ii < ww * hh; ii++) { if (cimRedpix[ii]) { pyr = ii / ww; // red pixel pxr = ii - pyr * ww; px3 = cimOffs[imx].xf + pxr * costf[imx] - pyr * sintf[imx] + 0.5; py3 = cimOffs[imx].yf + pyr * costf[imx] + pxr * sintf[imx] + 0.5; pix3 = PXMpix(E3pxm16,px3,py3); pix3[0] = 65535; pix3[1] = pix3[2] = 1; } } } mutex_unlock(&Fpixmap_lock); mwpaint2(); // update window zmainloop(); // v.11.11.1 return; } void * cim_show_Vimages_wthread(void *arg) // working thread v.11.04 { using namespace cim_show_images_names; int index = *((int *) (arg)); int imx, imy; int px3, py3; int vstat, vstat1, vstat2; int red1, green1, blue1; int red2, green2, blue2; int red3, green3, blue3; double f1, f2, px, py; uint16 vpix[3], *pix3; red1 = green1 = blue1 = 0; f1 = f2 = 0.5; // to use if no fblend flag for (py3 = index; py3 < E3hh; py3 += Nwt) // loop E3 rows for (px3 = 0; px3 < E3ww; px3++) // loop E3 columns { vstat1 = vstat2 = 0; for (imx = imy = im1; imx <= im2; imx++) // find which images overlap this pixel { if (py3 < hhlo[imx] || py3 > hhhi[imx]) continue; px = costf[imx] * (px3 - cimOffs[imx].xf) + sintf[imx] * (py3 - cimOffs[imx].yf); py = costf[imx] * (py3 - cimOffs[imx].yf) - sintf[imx] * (px3 - cimOffs[imx].xf); vstat = vpixel(cimPXMw[imx],px,py,vpix); if (! vstat) continue; if (! vstat1) { // first overlapping image vstat1 = 1; imy = imx; red1 = vpix[0]; green1 = vpix[1]; blue1 = vpix[2]; } else { // second image vstat2 = 1; red2 = vpix[0]; green2 = vpix[1]; blue2 = vpix[2]; break; } } imx = imy; // first of 1 or 2 overlapping images if (vstat1) { if (! vstat2) { red3 = red1; // use image1 pixel green3 = green1; blue3 = blue1; } else { // use blended image1 + image2 pixels if (fblendd) { f1 = hhhi[imx] - py3; // gradual blend f2 = py3 - hhlo[imx+1]; f1 = f1 / (f1 + f2); f2 = 1.0 - f1; } red3 = f1 * red1 + f2 * red2 + 0.5; green3 = f1 * green1 + f2 * green2 + 0.5; blue3 = f1 * blue1 + f2 * blue2 + 0.5; } } else red3 = green3 = blue3 = 0; // no overlapping image, use black pixel pix3 = PXMpix(E3pxm16,px3,py3); // output pixel pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } exit_wthread(); return 0; // not executed, avoid gcc warning } // cut-off edges of output image where all input images do not overlap // (HDR HDF Stack) void cim_trim() // v.10.9 { int edgex[8] = { 0, 1, 2, 2, 2, 1, 0, 0 }; // 4 corners and 4 midpoints of rectangle int edgey[8] = { 0, 0, 0, 1, 2, 2, 2, 1 }; // 0 and 2 mark corners, 1 marks midpoints int edgewx[4] = { +1, -1, -1, +1 }; int edgewy[4] = { +1, +1, -1, -1 }; int imx, ii, jj, ww, hh, px3, py3, px9, py9; int wwmin, wwmax, hhmin, hhmax; double xf, yf, tf, sintf, costf, px, py, wx, wy; uint16 *pix3, *pix9; wwmin = hhmin = 0; wwmax = E3ww; hhmax = E3hh; for (imx = 0; imx < cimNF; imx++) // loop all images { ww = cimPXMw[imx]->ww; // image size hh = cimPXMw[imx]->hh; xf = cimOffs[imx].xf; // alignment offsets yf = cimOffs[imx].yf; tf = cimOffs[imx].tf; sintf = sin(tf); costf = cos(tf); for (ii = 0; ii < 8; ii++) // 8 points around image rectangle { px = ww * edgex[ii] / 2; // coordinates before warping py = hh * edgey[ii] / 2; if (edgex[ii] != 1 && edgey[ii] != 1) { // if a corner jj = ii / 2; wx = cimOffs[imx].wx[jj]; // corner warp wy = cimOffs[imx].wy[jj]; if (edgewx[jj] > 0 && wx < 0) px -= wx; // if warp direction inwards, if (edgewx[jj] < 0 && wx > 0) px -= wx; // reduce px/py by warp if (edgewy[jj] > 0 && wy < 0) py -= wy; if (edgewy[jj] < 0 && wy > 0) py -= wy; } px3 = xf + px * costf - py * sintf; // map px/py to output image px3/py3 py3 = yf + py * costf + px * sintf; if (edgex[ii] != 1) { if (px3 < ww/2 && px3 > wwmin) wwmin = px3; // remember px3/py3 extremes if (px3 > ww/2 && px3 < wwmax) wwmax = px3; } if (edgey[ii] != 1) { if (py3 < hh/2 && py3 > hhmin) hhmin = py3; if (py3 > hh/2 && py3 < hhmax) hhmax = py3; } } } wwmin += 2; // compensate rounding wwmax -= 2; hhmin += 2; hhmax -= 2; ww = wwmax - wwmin; // new image size hh = hhmax - hhmin; if (ww < 0.7 * E3ww) return; // sanity check if (hh < 0.7 * E3hh) return; E9pxm16 = PXM_make(ww,hh,16); for (py3 = hhmin; py3 < hhmax; py3++) // E9 = trimmed E3 for (px3 = wwmin; px3 < wwmax; px3++) { px9 = px3 - wwmin; py9 = py3 - hhmin; pix3 = PXMpix(E3pxm16,px3,py3); pix9 = PXMpix(E9pxm16,px9,py9); pix9[0] = pix3[0]; pix9[1] = pix3[1]; pix9[2] = pix3[2]; } PXM_free(E3pxm16); // E3 = E9 E3pxm16 = E9pxm16; E9pxm16 = 0; E3ww = ww; E3hh = hh; return; } // dump offsets to stdout - diagnostic tool void cim_dump_offsets(cchar *text) { printf("\n offsets: %s \n",text); for (int imx = 0; imx < cimNF; imx++) { printf(" imx %d x/y/t: %.1f %.1f %.4f w0: %.1f %.1f w1: %.1f %.1f w2: %.1f %.1f w3: %.1f %.1f \n", imx, cimOffs[imx].xf, cimOffs[imx].yf, cimOffs[imx].tf, cimOffs[imx].wx[0], cimOffs[imx].wy[0], cimOffs[imx].wx[1], cimOffs[imx].wy[1], cimOffs[imx].wx[2], cimOffs[imx].wy[2], cimOffs[imx].wx[3], cimOffs[imx].wy[3]); } return; } /************************************************************************** Make an HDR (high dynamic range) image from several images of the same subject with different exposure levels. The composite image has better visibility of detail in both the brightest and darkest areas. ***************************************************************************/ int HDRstat; // 1 = OK, 0 = failed or canceled double HDRinitAlignSize = 160; // initial align image size double HDRimageIncrease = 1.6; // image size increase per align cycle double HDRsampSize = 6000; // pixel sample size 11.03 double HDRinitSearchRange = 8.0; // initial search range, +/- pixels double HDRinitSearchStep = 1.0; // initial search step, pixels double HDRinitWarpRange = 3.0; // initial corner warp range, +/- pixels double HDRinitWarpStep = 0.67; // initial corner warp step, pixels double HDRsearchRange = 2.0; // normal search range, +/- pixels double HDRsearchStep = 0.67; // normal search step, pixels double HDRwarpRange = 2.0; // normal corner warp range, +/- pixels double HDRwarpStep = 0.67; // normal corner warp step, pixels float *HDRbright = 0; // maps brightness per pixel zdialog *HDRzd = 0; // tweak dialog double HDR_respfac[10][1000]; // contribution / image / pixel brightness void * HDR_align_thread(void *); // align 2 images void HDR_brightness(); // compute pixel brightness levels void HDR_tweak(); // adjust image contribution curves void * HDR_combine_thread(void *); // combine images per contribution curves editfunc EFhdr; // edit function data // menu function void m_HDR(GtkWidget *, cchar *) // v.10.7 { char **flist, *ftemp; int imx, jj, err, px, py, ww, hh; double diffw, diffh; double fbright[10], btemp; double pixsum, fnorm = 3.0 / 65536.0; uint16 *pixel; PXM *pxmtemp; zfuncs::F1_help_topic = "HDR"; // help topic if (mod_keep()) return; // warn unsaved changes if (! menulock(1)) return; // test menu lock v.11.07 menulock(0); for (imx = 0; imx < 10; imx++) { // clear all file and PXM data cimFile[imx] = 0; cimPXMf[imx] = cimPXMs[imx] = cimPXMw[imx] = 0; } cimNF = 0; HDRbright = 0; flist = zgetfileN(ZTX("Select 2 to 9 files"),"openN",curr_file); // select images to combine if (! flist) return; for (imx = 0; flist[imx]; imx++); // count selected files if (imx < 2 || imx > 9) { zmessageACK(mWin,ZTX("Select 2 to 9 files")); goto cleanup; } cimNF = imx; // file count for (imx = 0; imx < cimNF; imx++) cimFile[imx] = strdupz(flist[imx],0,"HDR"); // set up file list if (! cim_load_files()) goto cleanup; // load and check all files ww = cimPXMf[0]->ww; hh = cimPXMf[0]->hh; for (imx = 1; imx < cimNF; imx++) // check image compatibility { diffw = abs(ww - cimPXMf[imx]->ww); diffw = diffw / ww; diffh = abs(hh - cimPXMf[imx]->hh); diffh = diffh / hh; if (diffw > 0.02 || diffh > 0.02) { zmessageACK(mWin,ZTX("Images are not all the same size")); goto cleanup; } } free_resources(); // ready to commit err = f_open(cimFile[0],0); // curr_file = 1st file in list if (err) goto cleanup; EFhdr.funcname = "HDR"; if (! edit_setup(EFhdr)) goto cleanup; // setup edit (will lock) for (imx = 0; imx < cimNF; imx++) // compute image brightness levels { pixsum = 0; for (py = 0; py < Fhh; py++) for (px = 0; px < Fww; px++) { pixel = PXMpix(cimPXMf[imx],px,py); pixsum += fnorm * (pixel[0] + pixel[1] + pixel[2]); } fbright[imx] = pixsum / (Fww * Fhh); } for (imx = 0; imx < cimNF; imx++) // sort file and pixmap lists for (jj = imx+1; jj < cimNF; jj++) // by decreasing brightness { if (fbright[jj] > fbright[imx]) { // bubble sort btemp = fbright[jj]; fbright[jj] = fbright[imx]; fbright[imx] = btemp; ftemp = cimFile[jj]; cimFile[jj] = cimFile[imx]; cimFile[imx] = ftemp; pxmtemp = cimPXMf[jj]; cimPXMf[jj] = cimPXMf[imx]; cimPXMf[imx] = pxmtemp; } } start_thread(HDR_align_thread,0); // align each pair of images wrapup_thread(0); // wait for completion if (HDRstat != 1) goto cancel; HDR_brightness(); // compute pixel brightness levels if (HDRstat != 1) goto cancel; HDR_tweak(); // combine images based on user inputs if (HDRstat != 1) goto cancel; CEF->Fmod = 1; // done edit_done(EFhdr); goto cleanup; cancel: edit_cancel(EFhdr); cleanup: if (flist) { for (imx = 0; flist[imx]; imx++) // free file list zfree(flist[imx]); zfree(flist); } for (imx = 0; imx < cimNF; imx++) { // free cim file and PXM data if (cimFile[imx]) zfree(cimFile[imx]); if (cimPXMf[imx]) PXM_free(cimPXMf[imx]); if (cimPXMs[imx]) PXM_free(cimPXMs[imx]); if (cimPXMw[imx]) PXM_free(cimPXMw[imx]); } if (HDRbright) zfree(HDRbright); *SB_text = 0; return; } // HDR align each pair of input images, output combined image to E3pxm16 // cimPXMf[*] original image // cimPXMs[*] scaled and color adjusted for pixel comparisons // cimPXMw[*] warped for display void * HDR_align_thread(void *) // v.10.7 { int imx, im1, im2, ww, hh, ii, nn; double R, maxtf, mintf, midtf; double xoff, yoff, toff, dxoff, dyoff; cimoffs offsets[10]; // x/y/t offsets after alignment Fzoom = 0; // fit to window if big Fblowup = 1; // scale up to window if small Ffuncbusy++; // v.11.01 cimShrink = 0; // no warp shrinkage (pano) cimPano = cimPanoV = 0; // no pano mode for (imx = 0; imx < cimNF; imx++) // bugfix v.10.8 memset(&offsets[imx],0,sizeof(cimoffs)); for (im1 = 0; im1 < cimNF-1; im1++) // loop each pair of images { im2 = im1 + 1; memset(&cimOffs[im1],0,sizeof(cimoffs)); // initial image offsets = 0 memset(&cimOffs[im2],0,sizeof(cimoffs)); ww = cimPXMf[im1]->ww; // image dimensions hh = cimPXMf[im1]->hh; nn = ww; // use larger of ww, hh if (hh > ww) nn = hh; cimScale = HDRinitAlignSize / nn; // initial align image size if (cimScale > 1.0) cimScale = 1.0; cimBlend = 0; // no blend width (use all) cim_get_overlap(im1,im2,cimPXMf); // get overlap area cim_match_colors(im1,im2,cimPXMf); // get color matching factors cimSearchRange = HDRinitSearchRange; // initial align search range cimSearchStep = HDRinitSearchStep; // initial align search step cimWarpRange = HDRinitWarpRange; // initial align corner warp range cimWarpStep = HDRinitWarpStep; // initial align corner warp step cimSampSize = HDRsampSize; // pixel sample size for align/compare cimNsearch = 0; // reset align search counter while (true) // loop, increasing image size { cim_scale_image(im1,cimPXMs); // scale images to cimScale cim_scale_image(im2,cimPXMs); cim_adjust_colors(cimPXMs[im1],1); // apply color adjustments cim_adjust_colors(cimPXMs[im2],2); cim_warp_image(im1); // make warped images to show cim_warp_image(im2); cimShowIm1 = im1; // show two images with 50/50 blend cimShowIm2 = im2; cimShowAll = 0; cim_show_images(1,0); // (x/y offsets can change) cim_get_overlap(im1,im2,cimPXMs); // get overlap area v.11.04 cim_get_redpix(im1); // get high-contrast pixels cim_align_image(im1,im2); // align im2 to im1 zfree(cimRedpix); // clear red pixels cimRedpix = 0; if (cimScale == 1.0) break; // done R = HDRimageIncrease; // next larger image size cimScale = cimScale * R; if (cimScale > 0.85) { // if close to end, jump to end R = R / cimScale; cimScale = 1.0; } cimOffs[im1].xf *= R; // scale offsets for larger image cimOffs[im1].yf *= R; cimOffs[im2].xf *= R; cimOffs[im2].yf *= R; for (ii = 0; ii < 4; ii++) { cimOffs[im1].wx[ii] *= R; cimOffs[im1].wy[ii] *= R; cimOffs[im2].wx[ii] *= R; cimOffs[im2].wy[ii] *= R; } cimSearchRange = HDRsearchRange; // align search range cimSearchStep = HDRsearchStep; // align search step size cimWarpRange = HDRwarpRange; // align corner warp range cimWarpStep = HDRwarpStep; // align corner warp step size } offsets[im2].xf = cimOffs[im2].xf - cimOffs[im1].xf; // save im2 offsets from im1 offsets[im2].yf = cimOffs[im2].yf - cimOffs[im1].yf; offsets[im2].tf = cimOffs[im2].tf - cimOffs[im1].tf; for (ii = 0; ii < 4; ii++) { offsets[im2].wx[ii] = cimOffs[im2].wx[ii] - cimOffs[im1].wx[ii]; offsets[im2].wy[ii] = cimOffs[im2].wy[ii] - cimOffs[im1].wy[ii]; } } for (imx = 0; imx < cimNF; imx++) // offsets[*] >> cimOffs[*] cimOffs[imx] = offsets[imx]; cimOffs[0].xf = cimOffs[0].yf = cimOffs[0].tf = 0; // image 0 at (0,0,0) for (im1 = 0; im1 < cimNF-1; im1++) // absolute offsets for image 1 to last { im2 = im1 + 1; cimOffs[im2].xf += cimOffs[im1].xf; // x/y/t offsets are additive cimOffs[im2].yf += cimOffs[im1].yf; cimOffs[im2].tf += cimOffs[im1].tf; for (ii = 0; ii < 4; ii++) { // corner warps are additive cimOffs[im2].wx[ii] += cimOffs[im1].wx[ii]; cimOffs[im2].wy[ii] += cimOffs[im1].wy[ii]; } } for (imx = 1; imx < cimNF; imx++) // re-warp to absolute v.10.8 cim_warp_image(imx); toff = cimOffs[0].tf; // balance +/- thetas maxtf = mintf = toff; for (imx = 1; imx < cimNF; imx++) { toff = cimOffs[imx].tf; if (toff > maxtf) maxtf = toff; if (toff < mintf) mintf = toff; } midtf = 0.5 * (maxtf + mintf); for (imx = 0; imx < cimNF; imx++) cimOffs[imx].tf -= midtf; for (im1 = 0; im1 < cimNF-1; im1++) // adjust x/y offsets for images after im1 for (im2 = im1+1; im2 < cimNF; im2++) // due to im1 theta offset { toff = cimOffs[im1].tf; xoff = cimOffs[im2].xf - cimOffs[im1].xf; yoff = cimOffs[im2].yf - cimOffs[im1].yf; dxoff = yoff * sin(toff); dyoff = xoff * sin(toff); cimOffs[im2].xf -= dxoff; cimOffs[im2].yf += dyoff; } Fzoom = Fblowup = 0; Ffuncbusy--; HDRstat = 1; thread_exit(); return 0; // not executed } // Compute mean image pixel brightness levels. // (basis for setting image contributions per brightness level) void HDR_brightness() // v.10.7 { int px3, py3, ww, hh, imx, kk, vstat; double px, py, red, green, blue; double bright, maxbright, minbright; double xoff, yoff, sintf[10], costf[10]; double norm, fnorm = 1.0 / 65536.0; uint16 vpix[3], *pix3; cimScale = 1.0; for (imx = 0; imx < cimNF; imx++) // replace alignment images { // (color adjusted for pixel matching) PXM_free(cimPXMs[imx]); // with the original images cimPXMs[imx] = PXM_copy(cimPXMf[imx]); cim_warp_image(imx); // re-apply warps } for (imx = 0; imx < cimNF; imx++) // pre-calculate trig functions { sintf[imx] = sin(cimOffs[imx].tf); costf[imx] = cos(cimOffs[imx].tf); } ww = E3pxm16->ww; hh = E3pxm16->hh; HDRbright = (float *) zmalloc(ww*hh*sizeof(int),"HDR"); // get memory for brightness array minbright = 1.0; maxbright = 0.0; for (py3 = 0; py3 < hh; py3++) // step through all output pixels for (px3 = 0; px3 < ww; px3++) { red = green = blue = 0; vstat = 0; for (imx = 0; imx < cimNF; imx++) // step through all input images { xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); // image N pixel, after offsets py = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat = vpixel(cimPXMw[imx],px,py,vpix); if (! vstat) break; red += fnorm * vpix[0]; // sum input pixels green += fnorm * vpix[1]; blue += fnorm * vpix[2]; } if (! vstat) { // pixel outside some image pix3 = PXMpix(E3pxm16,px3,py3); // output pixel = black pix3[0] = pix3[1] = pix3[2] = 0; kk = py3 * ww + px3; HDRbright[kk] = 0; continue; } bright = (red + green + blue) / (3 * cimNF); // mean pixel brightness, 0.0 to 1.0 kk = py3 * ww + px3; HDRbright[kk] = bright; if (bright > maxbright) maxbright = bright; if (bright < minbright) minbright = bright; pix3 = PXMpix(E3pxm16,px3,py3); // output pixel pix3[0] = red * 65535.0 / cimNF; pix3[1] = green * 65535.0 / cimNF; pix3[2] = blue * 65535.0 / cimNF; } norm = 0.999 / (maxbright - minbright); // normalize to range 0.0 to 0.999 for (int ii = 0; ii < ww * hh; ii++) HDRbright[ii] = (HDRbright[ii] - minbright) * norm; mwpaint2(); // update window return; } // Dialog for user to control the contributions of each input image // while watching the output image which is updated in real time. void HDR_tweak() // v.10.7 { int HDR_tweak_event(zdialog *zd, cchar *event); void HDR_curvedit(int); int imx; double cww = 1.0 / (cimNF-1); HDRzd = zdialog_new(ZTX("Adjust Image Contributions"),mWin,Bdone,Bcancel,null); zdialog_add_widget(HDRzd,"frame","brframe","dialog",0,"expand|space=2"); zdialog_add_widget(HDRzd,"hbox","hb1","dialog",0); zdialog_add_widget(HDRzd,"label","lab11","hb1",ZTX("dark pixels"),"space=3"); zdialog_add_widget(HDRzd,"label","lab12","hb1",0,"expand"); zdialog_add_widget(HDRzd,"label","lab13","hb1",ZTX("light pixels"),"space=3"); zdialog_add_widget(HDRzd,"hbox","hb2","dialog",0,"space=3"); zdialog_add_widget(HDRzd,"label","labf1","hb2",ZTX("file:"),"space=3"); zdialog_add_widget(HDRzd,"label","labf2","hb2","*"); zdialog_add_widget(HDRzd,"hbox","hbcf","dialog",0,"space=5"); zdialog_add_widget(HDRzd,"label","labcf","hbcf",Bcurvefile,"space=5"); zdialog_add_widget(HDRzd,"button","load","hbcf",Bopen,"space=5"); zdialog_add_widget(HDRzd,"button","save","hbcf",Bsave,"space=5"); GtkWidget *brframe = zdialog_widget(HDRzd,"brframe"); // set up curve edit spldat *sd = splcurve_init(brframe,HDR_curvedit); // v.11.01 EFhdr.curves = sd; sd->Nspc = cimNF; // no. curves = no. files for (imx = 0; imx < cimNF; imx++) // set up initial response curve { // anchor points sd->vert[imx] = 0; sd->nap[imx] = 2; sd->apx[imx][0] = 0.01; // flatter curves, v.9.3 sd->apx[imx][1] = 0.99; sd->apy[imx][0] = 0.9 - imx * 0.8 * cww; sd->apy[imx][1] = 0.1 + imx * 0.8 * cww; splcurve_generate(sd,imx); } start_thread(HDR_combine_thread,0); // start working thread signal_thread(); zdialog_resize(HDRzd,400,360); zdialog_run(HDRzd,HDR_tweak_event,"-10/20"); // run dialog v.11.07 zdialog_wait(HDRzd); // wait for completion return; } // dialog event and completion callback function int HDR_tweak_event(zdialog *zd, cchar *event) { spldat *sd = EFhdr.curves; if (strEqu(event,"load")) { // load saved curve v.11.02 splcurve_load(sd); zdialog_stuff(HDRzd,"labf2","*"); signal_thread(); return 0; } if (strEqu(event,"save")) { // save curve to file v.11.02 splcurve_save(sd); return 0; } if (zd->zstat) // dialog complete { wrapup_thread(8); if (zd->zstat == 1) HDRstat = 1; else HDRstat = 0; zdialog_free(HDRzd); if (HDRstat == 1) cim_trim(); // cut-off edges v.10.9 } return 1; } // this function is called when a curve is edited void HDR_curvedit(int spc) { cchar *pp; pp = strrchr(cimFile[spc],'/'); zdialog_stuff(HDRzd,"labf2",pp+1); signal_thread(); return; } // Combine all input images >> E3pxm16 based on image response curves. void * HDR_combine_thread(void *) { void * HDR_combine_wthread(void *arg); int imx, ii, kk; double xlo, xhi, xval, yval, sumrf; spldat *sd = EFhdr.curves; while (true) { thread_idle_loop(); // wait for work or exit request for (imx = 0; imx < cimNF; imx++) // loop input images { ii = sd->nap[imx]; // get low and high anchor points xlo = sd->apx[imx][0]; // for image response curve xhi = sd->apx[imx][ii-1]; if (xlo < 0.02) xlo = 0; // snap-to scale end points if (xhi > 0.98) xhi = 1; for (ii = 0; ii < 1000; ii++) // loop all brightness levels { HDR_respfac[imx][ii] = 0; xval = 0.001 * ii; if (xval < xlo || xval > xhi) continue; // no influence for brightness level kk = 1000 * xval; // speedup v.11.06 yval = sd->yval[imx][kk]; HDR_respfac[imx][ii] = yval; // = contribution of this input image } } for (ii = 0; ii < 1000; ii++) // normalize the factors so that { // they sum to 1.0 sumrf = 0; for (imx = 0; imx < cimNF; imx++) sumrf += HDR_respfac[imx][ii]; if (! sumrf) continue; for (imx = 0; imx < cimNF; imx++) HDR_respfac[imx][ii] = HDR_respfac[imx][ii] / sumrf; } mutex_lock(&Fpixmap_lock); // stop window updates for (ii = 0; ii < Nwt; ii++) // start worker threads v.10.7 start_wthread(HDR_combine_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion mutex_unlock(&Fpixmap_lock); mwpaint2(); // update window } return 0; // not executed } void * HDR_combine_wthread(void *arg) // working thread { int index = *((int *) (arg)); int imx, ww, hh, ii, px3, py3, vstat; double sintf[10], costf[10], xoff, yoff; double px, py, red, green, blue, bright, factor; uint16 vpix[3], *pix3; for (imx = 0; imx < cimNF; imx++) // pre-calculate trig functions { sintf[imx] = sin(cimOffs[imx].tf); costf[imx] = cos(cimOffs[imx].tf); } ww = E3pxm16->ww; hh = E3pxm16->hh; for (py3 = index; py3 < hh; py3 += Nwt) // step through all output pixels for (px3 = 0; px3 < ww; px3++) { ii = py3 * ww + px3; bright = HDRbright[ii]; // mean brightness, 0.0 to 1.0 ii = 1000 * bright; red = green = blue = 0; for (imx = 0; imx < cimNF; imx++) // loop input images { factor = HDR_respfac[imx][ii]; // image contribution to this pixel if (! factor) continue; // none xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); // input virtual pixel mapping to py = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); // this output pixel vstat = vpixel(cimPXMw[imx],px,py,vpix); // get input pixel if (! vstat) continue; red += factor * vpix[0]; // accumulate brightness contribution green += factor * vpix[1]; blue += factor * vpix[2]; } pix3 = PXMpix(E3pxm16,px3,py3); // output pixel pix3[0] = red; // = sum of input pixel contributions pix3[1] = green; pix3[2] = blue; } exit_wthread(); return 0; // not executed } /************************************************************************** Make an HDF (high depth of field) image from several images of the same subject with different focus settings. Combine the images and allow the user to "paint" the output composite image using the mouse and choosing the sharpest input image for each area of the output image. The result is an image with a depth of field that exceeds the camera capability. The images are aligned at the center, but small differences in camera position (hand-held photos) will cause parallax errors that prevent perfect alignment of the images. Also, the images with nearer focus will be slightly larger than those with farther focus. These problems can be compensated by dragging and warping the images using the mouse. v.10.7 **************************************************************************/ int HDFstat; // 1 = OK, 0 = failed or canceled double HDFinitAlignSize = 160; // initial align image size double HDFimageIncrease = 1.6; // image size increase per align cycle double HDFsampSize = 6000; // pixel sample size double HDFinitSearchRange = 8.0; // initial search range, +/- pixels double HDFinitSearchStep = 1.0; // initial search step, pixels double HDFinitWarpRange = 4.0; // initial corner warp range double HDFinitWarpStep = 1.0; // initial corner warp step double HDFsearchRange = 2.0; // normal search range double HDFsearchStep = 1.0; // normal search step double HDFwarpRange = 1.0; // normal corner warp range v.11.03 double HDFwarpStep = 0.67; // normal corner warp step void * HDF_align_thread(void *); void HDF_tweak(); void HDF_mousefunc(); void * HDF_combine_thread(void *); editfunc EFhdf; // edit function data // menu function void m_HDF(GtkWidget *, cchar *) // v.10.7 { char **flist; int imx, err, ww, hh; double diffw, diffh; zfuncs::F1_help_topic = "HDF"; // help topic if (mod_keep()) return; // warn unsaved changes if (! menulock(1)) return; // test menu lock v.11.07 menulock(0); for (imx = 0; imx < 10; imx++) { // clear all file and PXM data cimFile[imx] = 0; cimPXMf[imx] = cimPXMs[imx] = cimPXMw[imx] = 0; } cimNF = 0; flist = zgetfileN(ZTX("Select 2 to 9 files"),"openN",curr_file); // select images to combine if (! flist) return; for (imx = 0; flist[imx]; imx++); // count selected files if (imx < 2 || imx > 9) { zmessageACK(mWin,ZTX("Select 2 to 9 files")); goto cleanup; } cimNF = imx; // file count for (imx = 0; imx < cimNF; imx++) cimFile[imx] = strdupz(flist[imx],0,"HDF"); // set up file list if (! cim_load_files()) goto cleanup; // load and check all files ww = cimPXMf[0]->ww; hh = cimPXMf[0]->hh; for (imx = 1; imx < cimNF; imx++) // check image compatibility { diffw = abs(ww - cimPXMf[imx]->ww); diffw = diffw / ww; diffh = abs(hh - cimPXMf[imx]->hh); diffh = diffh / hh; if (diffw > 0.02 || diffh > 0.02) { zmessageACK(mWin,ZTX("Images are not all the same size")); goto cleanup; } } free_resources(); // ready to commit err = f_open(cimFile[0],0); // curr_file = 1st file in list if (err) goto cleanup; EFhdf.funcname = "HDF"; if (! edit_setup(EFhdf)) goto cleanup; // setup edit (will lock) start_thread(HDF_align_thread,0); // align each pair of images wrapup_thread(0); // wait for completion if (HDFstat != 1) goto cancel; HDF_tweak(); // combine images based on user inputs if (HDFstat != 1) goto cancel; CEF->Fmod = 1; // done edit_done(EFhdf); goto cleanup; cancel: edit_cancel(EFhdf); cleanup: if (flist) { for (imx = 0; flist[imx]; imx++) // free file list zfree(flist[imx]); zfree(flist); } for (imx = 0; imx < cimNF; imx++) { // free cim file and PXM data if (cimFile[imx]) zfree(cimFile[imx]); if (cimPXMf[imx]) PXM_free(cimPXMf[imx]); if (cimPXMs[imx]) PXM_free(cimPXMs[imx]); if (cimPXMw[imx]) PXM_free(cimPXMw[imx]); } *SB_text = 0; return; } // HDF align each pair of input images, output combined image to E3pxm16 // cimPXMf[*] original image // cimPXMs[*] scaled and color adjusted for pixel comparisons // cimPXMw[*] warped for display void * HDF_align_thread(void *) // v.10.7 { int imx, im1, im2, ww, hh, ii, nn; double R, maxtf, mintf, midtf; double xoff, yoff, toff, dxoff, dyoff; cimoffs offsets[10]; // x/y/t offsets after alignment Fzoom = 0; // fit to window if big Fblowup = 1; // scale up to window if small Ffuncbusy++; // v.11.01 cimShrink = 0; // no warp shrinkage (pano) cimPano = cimPanoV = 0; // no pano mode for (imx = 0; imx < cimNF; imx++) // bugfix v.10.8 memset(&offsets[imx],0,sizeof(cimoffs)); for (im1 = 0; im1 < cimNF-1; im1++) // loop each pair of images { im2 = im1 + 1; memset(&cimOffs[im1],0,sizeof(cimoffs)); // initial image offsets = 0 memset(&cimOffs[im2],0,sizeof(cimoffs)); ww = cimPXMf[im1]->ww; // image dimensions hh = cimPXMf[im1]->hh; nn = ww; // use larger of ww, hh if (hh > ww) nn = hh; cimScale = HDFinitAlignSize / nn; // initial align image size if (cimScale > 1.0) cimScale = 1.0; cimBlend = 0; // no blend width (use all) cim_get_overlap(im1,im2,cimPXMf); // get overlap area cim_match_colors(im1,im2,cimPXMf); // get color matching factors cimSearchRange = HDFinitSearchRange; // initial align search range cimSearchStep = HDFinitSearchStep; // initial align search step cimWarpRange = HDFinitWarpRange; // initial align corner warp range cimWarpStep = HDFinitWarpStep; // initial align corner warp step cimSampSize = HDFsampSize; // pixel sample size for align/compare cimNsearch = 0; // reset align search counter while (true) // loop, increasing image size { cim_scale_image(im1,cimPXMs); // scale images to cimScale cim_scale_image(im2,cimPXMs); cim_adjust_colors(cimPXMs[im1],1); // apply color adjustments cim_adjust_colors(cimPXMs[im2],2); cim_warp_image(im1); // warp images for show cim_warp_image(im2); cimShowIm1 = im1; // show these two images cimShowIm2 = im2; // with 50/50 blend cimShowAll = 0; cim_show_images(1,0); // (y offset can change) cim_get_overlap(im1,im2,cimPXMs); // get overlap area v.11.04 cim_get_redpix(im1); // get high-contrast pixels cim_align_image(im1,im2); // align im2 to im1 zfree(cimRedpix); // clear red pixels cimRedpix = 0; if (cimScale == 1.0) break; // done R = HDFimageIncrease; // next larger image size cimScale = cimScale * R; if (cimScale > 0.85) { // if close to end, jump to end R = R / cimScale; cimScale = 1.0; } cimOffs[im1].xf *= R; // scale offsets for larger image cimOffs[im1].yf *= R; cimOffs[im2].xf *= R; cimOffs[im2].yf *= R; for (ii = 0; ii < 4; ii++) { cimOffs[im1].wx[ii] *= R; cimOffs[im1].wy[ii] *= R; cimOffs[im2].wx[ii] *= R; cimOffs[im2].wy[ii] *= R; } cimSearchRange = HDFsearchRange; // align search range cimSearchStep = HDFsearchStep; // align search step size cimWarpRange = HDFwarpRange; // align corner warp range cimWarpStep = HDFwarpStep; // align corner warp step size } offsets[im2].xf = cimOffs[im2].xf - cimOffs[im1].xf; // save im2 offsets from im1 offsets[im2].yf = cimOffs[im2].yf - cimOffs[im1].yf; offsets[im2].tf = cimOffs[im2].tf - cimOffs[im1].tf; for (ii = 0; ii < 4; ii++) { offsets[im2].wx[ii] = cimOffs[im2].wx[ii] - cimOffs[im1].wx[ii]; offsets[im2].wy[ii] = cimOffs[im2].wy[ii] - cimOffs[im1].wy[ii]; } } for (imx = 0; imx < cimNF; imx++) // offsets[*] >> cimOffs[*] cimOffs[imx] = offsets[imx]; cimOffs[0].xf = cimOffs[0].yf = cimOffs[0].tf = 0; // image 0 at (0,0,0) for (im1 = 0; im1 < cimNF-1; im1++) // absolute offsets for image 1 to last { im2 = im1 + 1; cimOffs[im2].xf += cimOffs[im1].xf; // x/y/t offsets are additive cimOffs[im2].yf += cimOffs[im1].yf; cimOffs[im2].tf += cimOffs[im1].tf; for (ii = 0; ii < 4; ii++) { // corner warps are additive cimOffs[im2].wx[ii] += cimOffs[im1].wx[ii]; cimOffs[im2].wy[ii] += cimOffs[im1].wy[ii]; } } for (imx = 1; imx < cimNF; imx++) // re-warp to absolute v.10.8 cim_warp_image(imx); toff = cimOffs[0].tf; // balance +/- thetas maxtf = mintf = toff; for (imx = 1; imx < cimNF; imx++) { toff = cimOffs[imx].tf; if (toff > maxtf) maxtf = toff; if (toff < mintf) mintf = toff; } midtf = 0.5 * (maxtf + mintf); for (imx = 0; imx < cimNF; imx++) cimOffs[imx].tf -= midtf; for (im1 = 0; im1 < cimNF-1; im1++) // adjust x/y offsets for images after im1 for (im2 = im1+1; im2 < cimNF; im2++) // due to im1 theta offset { toff = cimOffs[im1].tf; xoff = cimOffs[im2].xf - cimOffs[im1].xf; yoff = cimOffs[im2].yf - cimOffs[im1].yf; dxoff = yoff * sin(toff); dyoff = xoff * sin(toff); cimOffs[im2].xf -= dxoff; cimOffs[im2].yf += dyoff; } for (imx = 0; imx < cimNF; imx++) // use final warped images as basis { // for manual align adjustments PXM_free(cimPXMs[imx]); // bugfix v.11.04 cimPXMs[imx] = PXM_copy(cimPXMw[imx]); } Fzoom = Fblowup = 0; Ffuncbusy--; HDFstat = 1; thread_exit(); return 0; // not executed } // paint and warp output image zdialog *HDFzd = 0; // paint dialog int HDFmode; // mode: paint or warp int HDFimage; // current image (0 based) int HDFradius; // paint mode radius char *HDFpixmap = 0; // map input image per output pixel float *HDFwarpx[10], *HDFwarpy[10]; // warp memory, pixel displacements void HDF_tweak() // v.10.7 { char imageN[8] = "imageN", labN[4] = "0"; int cc, imx, ww, hh; int HDF_tweak_dialog_event(zdialog *zd, cchar *event); // image (o) 1 (o) 2 (o) 3 ... // (o) paint radius [___] // (o) warp [__] HDFzd = zdialog_new(ZTX("Paint and Warp Image"),mWin,Bdone,Bcancel,null); zdialog_add_widget(HDFzd,"hbox","hbim","dialog",0,"space=3"); zdialog_add_widget(HDFzd,"label","labim","hbim",ZTX("image"),"space=5"); zdialog_add_widget(HDFzd,"hbox","hbpw","dialog",0,"space=3"); zdialog_add_widget(HDFzd,"vbox","vbpw1","hbpw",0,"homog|space=5"); zdialog_add_widget(HDFzd,"vbox","vbpw2","hbpw",0,"homog|space=5"); zdialog_add_widget(HDFzd,"radio","paint","vbpw1",ZTX("paint")); zdialog_add_widget(HDFzd,"radio","warp","vbpw1",ZTX("warp")); zdialog_add_widget(HDFzd,"hbox","hbp","vbpw2"); zdialog_add_widget(HDFzd,"label","labpr","hbp",Bradius,"space=5"); zdialog_add_widget(HDFzd,"spin","radius","hbp","1|400|1|100"); zdialog_add_widget(HDFzd,"label","space","vbpw2"); for (imx = 0; imx < cimNF; imx++) { // add radio button for each image imageN[5] = '1' + imx; labN[0] = '1' + imx; zdialog_add_widget(HDFzd,"radio",imageN,"hbim",labN); } zdialog_stuff(HDFzd,"paint",1); // paint button on zdialog_stuff(HDFzd,"warp",0); // warp button off zdialog_stuff(HDFzd,"image1",1); // initial image = 1st HDFmode = 0; // start in paint mode HDFimage = 0; // initial image HDFradius = 100; // paint radius takeMouse(HDFzd,HDF_mousefunc,0); // connect mouse function v.10.12 cc = E3ww * E3hh; // allocate pixel map HDFpixmap = zmalloc(cc,"HDF"); memset(HDFpixmap,cimNF,cc); // initial state, blend all images for (imx = 0; imx < cimNF; imx++) { // allocate warp memory ww = cimPXMw[imx]->ww; hh = cimPXMw[imx]->hh; HDFwarpx[imx] = (float *) zmalloc(ww * hh * sizeof(float),"HDF"); HDFwarpy[imx] = (float *) zmalloc(ww * hh * sizeof(float),"HDF"); } start_thread(HDF_combine_thread,0); // start working thread signal_thread(); zdialog_resize(HDFzd,250,0); // stretch a bit v.11.07 zdialog_run(HDFzd,HDF_tweak_dialog_event,"-10/20"); // run dialog, parallel v.11.07 zdialog_wait(HDFzd); // wait for completion return; } // dialog event and completion callback function int HDF_tweak_dialog_event(zdialog *zd, cchar *event) // v.10.7 { int imx, nn; if (zd->zstat) // dialog finish { freeMouse(); // disconnect mouse function v.10.12 signal_thread(); wrapup_thread(8); if (zd->zstat == 1) HDFstat = 1; else HDFstat = 0; if (HDFstat == 1) cim_trim(); // cut-off edges v.10.9 zdialog_free(HDFzd); HDFmode = 0; zfree(HDFpixmap); // free pixel map for (imx = 0; imx < cimNF; imx++) { zfree(HDFwarpx[imx]); // free warp memory zfree(HDFwarpy[imx]); } } if (strEqu(event,"paint")) { // set paint mode zdialog_fetch(zd,"paint",nn); if (! nn) return 1; HDFmode = 0; gdk_window_set_cursor(drWin->window,0); // no drag cursor v.11.03 } if (strEqu(event,"warp")) { // set warp mode zdialog_fetch(zd,"warp",nn); if (! nn) return 1; HDFmode = 1; paint_toparc(2); // stop brush outline gdk_window_set_cursor(drWin->window,dragcursor); // set drag cursor v.11.03 } if (strnEqu(event,"image",5)) { // image radio button nn = event[5] - '0'; // 1 to cimNF if (nn > 0 && nn <= cimNF) HDFimage = nn - 1; // 0 to cimNF-1 signal_thread(); } if (strEqu(event,"radius")) // change paint radius zdialog_fetch(zd,"radius",HDFradius); if (strEqu(event,"focus")) { // toggle mouse capture v.10.12 takeMouse(zd,HDF_mousefunc,0); // connect mouse function if (HDFmode == 1) gdk_window_set_cursor(drWin->window,dragcursor); // warp mode, drag cursor v.11.03 signal_thread(); } return 1; } // HDF dialog mouse function // paint: during drag, selected image >> HDFpixmap (within paint radius) >> E3 // warp: for selected image, cimPXMs >> warp >> cimPXMw >> E3 void HDF_mousefunc() // v.10.7 { uint16 vpix1[3], *pix2, *pix3; int imx, radius, radius2, vstat1; int mx, my, dx, dy, px3, py3; char imageN[8] = "imageN"; double px1, py1; double xoff, yoff, sintf[10], costf[10]; int ii, px, py, ww, hh; double mag, dispx, dispy, d1, d2; PXM *pxm1, *pxm2; if (HDFmode == 0) goto paint; if (HDFmode == 1) goto warp; return; paint: radius = HDFradius; // paintbrush radius radius2 = radius * radius; toparcx = Mxposn - radius; // paintbrush outline circle toparcy = Myposn - radius; toparcw = toparch = 2 * radius; Ftoparc = 1; paint_toparc(3); if (LMclick || RMclick) { // mouse click LMclick = RMclick = 0; return; // ignore v.10.8 } else if (Mxdrag || Mydrag) { // drag in progress mx = Mxdrag; my = Mydrag; } else return; if (mx < 0 || mx > E3ww-1 || my < 0 || my > E3hh-1) // mouse outside image area return; for (imx = 0; imx < cimNF; imx++) // pre-calculate trig funcs { sintf[imx] = sin(cimOffs[imx].tf); costf[imx] = cos(cimOffs[imx].tf); } for (dy = -radius; dy <= radius; dy++) // loop pixels around mouse for (dx = -radius; dx <= radius; dx++) { if (dx*dx + dy*dy > radius2) continue; // outside radius px3 = mx + dx; // output pixel py3 = my + dy; if (px3 < 0 || px3 > E3ww-1) continue; // outside image if (py3 < 0 || py3 > E3hh-1) continue; pix3 = PXMpix(E3pxm16,px3,py3); // output pixel imx = py3 * E3ww + px3; // update pixmap to selected image HDFpixmap[imx] = HDFimage; imx = HDFimage; xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px1 = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); // input virtual pixel py1 = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat1 = vpixel(cimPXMw[imx],px1,py1,vpix1); if (vstat1) { pix3[0] = vpix1[0]; pix3[1] = vpix1[1]; pix3[2] = vpix1[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } mx = mx - radius - 1; // update window v.10.12 my = my - radius - 1; ww = 2 * radius + 3; paint_toparc(2); mwpaint3(mx,my,ww,ww); Ftoparc = 1; paint_toparc(3); return; warp: if (LMclick || RMclick) { // mouse click LMclick = RMclick = 0; // ignore v.10.8 return; } else if (Mxdrag || Mydrag) { // drag in progress mx = Mxdrag; my = Mydrag; } else return; if (mx < 0 || mx > E3ww-1 || my < 0 || my > E3hh-1) // mouse outside image area return; imx = my * E3ww + mx; // if pixel has been painted, imx = HDFpixmap[imx]; // select corresp. image to warp if (imx == cimNF) return; // else no action v.10.8 if (imx != HDFimage) { HDFimage = imx; // update selected image and imageN[5] = '1' + imx; // dialog radio button zdialog_stuff(HDFzd,imageN,1); } pxm1 = cimPXMs[imx]; // input image pxm2 = cimPXMw[imx]; // output image ww = pxm2->ww; hh = pxm2->hh; mx = Mxdown; // drag origin, image coordinates my = Mydown; dx = Mxdrag - Mxdown; // drag increment dy = Mydrag - Mydown; Mxdown = Mxdrag; // next drag origin Mydown = Mydrag; d1 = ww * ww + hh * hh; for (py = 0; py < hh; py++) // process all output pixels for (px = 0; px < ww; px++) { d2 = (px-mx)*(px-mx) + (py-my)*(py-my); mag = (1.0 - d2 / d1); mag = mag * mag * mag * mag; mag = mag * mag * mag * mag; mag = mag * mag * mag * mag; dispx = -dx * mag; // displacement = drag * mag dispy = -dy * mag; ii = py * ww + px; HDFwarpx[imx][ii] += dispx; // add this drag to prior sum HDFwarpy[imx][ii] += dispy; dispx = HDFwarpx[imx][ii]; dispy = HDFwarpy[imx][ii]; vstat1 = vpixel(pxm1,px+dispx,py+dispy,vpix1); // input virtual pixel pix2 = PXMpix(pxm2,px,py); // output pixel if (vstat1) { pix2[0] = vpix1[0]; pix2[1] = vpix1[1]; pix2[2] = vpix1[2]; } else pix2[0] = pix2[1] = pix2[2] = 0; } signal_thread(); // combine images >> E3 >> main window return; } // Combine images in E3pxm16 (not reallocated). Update main window. void * HDF_combine_thread(void *) // v.10.7 { void * HDF_combine_wthread(void *); while (true) { thread_idle_loop(); // wait for work or exit request mutex_lock(&Fpixmap_lock); // stop window updates for (int ii = 0; ii < Nwt; ii++) // start worker threads v.10.7 start_wthread(HDF_combine_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion mutex_unlock(&Fpixmap_lock); // update window mwpaint2(); } return 0; // not executed } void * HDF_combine_wthread(void *arg) // worker thread { int index = *((int *) (arg)); // no more paint and warp modes v.10.8 int px3, py3, vstat1; int imx, red, green, blue; double px, py; double xoff, yoff, sintf[10], costf[10]; uint16 vpix1[3], *pix3; for (imx = 0; imx < cimNF; imx++) // pre-calculate trig funcs { sintf[imx] = sin(cimOffs[imx].tf); costf[imx] = cos(cimOffs[imx].tf); } for (py3 = index+1; py3 < E3hh-1; py3 += Nwt) // step through output pixels for (px3 = 1; px3 < E3ww-1; px3++) { pix3 = PXMpix(E3pxm16,px3,py3); imx = py3 * E3ww + px3; imx = HDFpixmap[imx]; if (imx < cimNF) // specific image maps to pixel { xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); py = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat1 = vpixel(cimPXMw[imx],px,py,vpix1); // corresp. input vpixel if (vstat1) { pix3[0] = vpix1[0]; pix3[1] = vpix1[1]; pix3[2] = vpix1[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } else // use blend of all images { red = green = blue = 0; for (imx = 0; imx < cimNF; imx++) { xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); py = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat1 = vpixel(cimPXMw[imx],px,py,vpix1); if (vstat1) { red += vpix1[0]; green += vpix1[1]; blue += vpix1[2]; } } pix3[0] = red / cimNF; pix3[1] = green / cimNF; pix3[2] = blue / cimNF; } } exit_wthread(); return 0; // not executed, avoid gcc warning } /************************************************************************** Stack/Paint function Combine multiple images of one subject taken at different times from (almost) the same camera position. Align the images and allow the user to choose which input image to use for each area of the output image, by "painting" with the mouse. Use this to remove tourists and cars that move in and out of a scene being photographed. **************************************************************************/ int STPstat; // 1 = OK, 0 = failed or canceled double STPinitAlignSize = 160; // initial align image size double STPimageIncrease = 1.6; // image size increase per align cycle double STPsampSize = 10000; // pixel sample size v.11.03 double STPinitSearchRange = 5.0; // initial search range, +/- pixels double STPinitSearchStep = 1.0; // initial search step, pixels double STPinitWarpRange = 2.0; // initial corner warp range double STPinitWarpStep = 1.0; // initial corner warp step double STPsearchRange = 2.0; // normal search range double STPsearchStep = 1.0; // normal search step double STPwarpRange = 1.0; // normal corner warp range double STPwarpStep = 0.67; // normal corner warp step void * STP_align_thread(void *); void STP_tweak(); void STP_mousefunc(); void * STP_combine_thread(void *); editfunc EFstp; // edit function data // menu function void m_STP(GtkWidget *, cchar *) // v.11.02 { char **flist; int imx, err, ww, hh; double diffw, diffh; zfuncs::F1_help_topic = "stack_paint"; // help topic if (mod_keep()) return; // warn unsaved changes if (! menulock(1)) return; // test menu lock v.11.07 menulock(0); for (imx = 0; imx < 10; imx++) { // clear all file and PXM data cimFile[imx] = 0; cimPXMf[imx] = cimPXMs[imx] = cimPXMw[imx] = 0; } cimNF = 0; flist = zgetfileN(ZTX("Select 2 to 9 files"),"openN",curr_file); // select images to combine if (! flist) return; for (imx = 0; flist[imx]; imx++); // count selected files if (imx < 2 || imx > 9) { zmessageACK(mWin,ZTX("Select 2 to 9 files")); goto cleanup; } cimNF = imx; // file count for (imx = 0; imx < cimNF; imx++) cimFile[imx] = strdupz(flist[imx],0,"STP"); // set up file list if (! cim_load_files()) goto cleanup; // load and check all files ww = cimPXMf[0]->ww; hh = cimPXMf[0]->hh; for (imx = 1; imx < cimNF; imx++) // check image compatibility { diffw = abs(ww - cimPXMf[imx]->ww); diffw = diffw / ww; diffh = abs(hh - cimPXMf[imx]->hh); diffh = diffh / hh; if (diffw > 0.02 || diffh > 0.02) { zmessageACK(mWin,ZTX("Images are not all the same size")); goto cleanup; } } free_resources(); // ready to commit err = f_open(cimFile[0],0); // curr_file = 1st file in list if (err) goto cleanup; EFstp.funcname = "stack-paint"; if (! edit_setup(EFstp)) goto cleanup; // setup edit (will lock) start_thread(STP_align_thread,0); // align each pair of images wrapup_thread(0); // wait for completion if (STPstat != 1) goto cancel; STP_tweak(); // combine images based on user inputs if (STPstat != 1) goto cancel; CEF->Fmod = 1; // done edit_done(EFstp); goto cleanup; cancel: edit_cancel(EFstp); cleanup: if (flist) { for (imx = 0; flist[imx]; imx++) // free file list zfree(flist[imx]); zfree(flist); } for (imx = 0; imx < cimNF; imx++) { // free cim file and PXM data if (cimFile[imx]) zfree(cimFile[imx]); if (cimPXMf[imx]) PXM_free(cimPXMf[imx]); if (cimPXMs[imx]) PXM_free(cimPXMs[imx]); if (cimPXMw[imx]) PXM_free(cimPXMw[imx]); } *SB_text = 0; return; } // align each pair of input images, output combined image to E3pxm16 // cimPXMf[*] original image // cimPXMs[*] scaled and color adjusted for pixel comparisons // cimPXMw[*] warped for display void * STP_align_thread(void *) // v.11.02 { int imx, im1, im2, ww, hh, ii, nn; double R, maxtf, mintf, midtf; double xoff, yoff, toff, dxoff, dyoff; cimoffs offsets[10]; // x/y/t offsets after alignment Fzoom = 0; // fit to window if big Fblowup = 1; // scale up to window if small Ffuncbusy++; cimShrink = 0; // no warp shrinkage (pano) cimPano = cimPanoV = 0; // no pano mode for (imx = 0; imx < cimNF; imx++) memset(&offsets[imx],0,sizeof(cimoffs)); for (im1 = 0; im1 < cimNF-1; im1++) // loop each pair of images { im2 = im1 + 1; memset(&cimOffs[im1],0,sizeof(cimoffs)); // initial image offsets = 0 memset(&cimOffs[im2],0,sizeof(cimoffs)); ww = cimPXMf[im1]->ww; // image dimensions hh = cimPXMf[im1]->hh; nn = ww; // use larger of ww, hh if (hh > ww) nn = hh; cimScale = STPinitAlignSize / nn; // initial align image size if (cimScale > 1.0) cimScale = 1.0; cimBlend = 0; // no blend width (use all) cim_get_overlap(im1,im2,cimPXMf); // get overlap area cim_match_colors(im1,im2,cimPXMf); // get color matching factors cimSearchRange = STPinitSearchRange; // initial align search range cimSearchStep = STPinitSearchStep; // initial align search step cimWarpRange = STPinitWarpRange; // initial align corner warp range cimWarpStep = STPinitWarpStep; // initial align corner warp step cimSampSize = STPsampSize; // pixel sample size for align/compare cimNsearch = 0; // reset align search counter while (true) // loop, increasing image size { cim_scale_image(im1,cimPXMs); // scale images to cimScale cim_scale_image(im2,cimPXMs); cim_adjust_colors(cimPXMs[im1],1); // apply color adjustments cim_adjust_colors(cimPXMs[im2],2); cim_warp_image(im1); // warp images for show cim_warp_image(im2); cimShowIm1 = im1; // show these two images cimShowIm2 = im2; // with 50/50 blend cimShowAll = 0; cim_show_images(1,0); // (y offset can change) cim_get_overlap(im1,im2,cimPXMs); // get overlap area v.11.04 cim_get_redpix(im1); // get high-contrast pixels cim_align_image(im1,im2); // align im2 to im1 zfree(cimRedpix); // clear red pixels cimRedpix = 0; if (cimScale == 1.0) break; // done R = STPimageIncrease; // next larger image size cimScale = cimScale * R; if (cimScale > 0.85) { // if close to end, jump to end R = R / cimScale; cimScale = 1.0; } cimOffs[im1].xf *= R; // scale offsets for larger image cimOffs[im1].yf *= R; cimOffs[im2].xf *= R; cimOffs[im2].yf *= R; for (ii = 0; ii < 4; ii++) { cimOffs[im1].wx[ii] *= R; cimOffs[im1].wy[ii] *= R; cimOffs[im2].wx[ii] *= R; cimOffs[im2].wy[ii] *= R; } cimSearchRange = STPsearchRange; // align search range cimSearchStep = STPsearchStep; // align search step size cimWarpRange = STPwarpRange; // align corner warp range cimWarpStep = STPwarpStep; // align corner warp step size } offsets[im2].xf = cimOffs[im2].xf - cimOffs[im1].xf; // save im2 offsets from im1 offsets[im2].yf = cimOffs[im2].yf - cimOffs[im1].yf; offsets[im2].tf = cimOffs[im2].tf - cimOffs[im1].tf; for (ii = 0; ii < 4; ii++) { offsets[im2].wx[ii] = cimOffs[im2].wx[ii] - cimOffs[im1].wx[ii]; offsets[im2].wy[ii] = cimOffs[im2].wy[ii] - cimOffs[im1].wy[ii]; } } for (imx = 0; imx < cimNF; imx++) // offsets[*] >> cimOffs[*] cimOffs[imx] = offsets[imx]; cimOffs[0].xf = cimOffs[0].yf = cimOffs[0].tf = 0; // image 0 at (0,0,0) for (im1 = 0; im1 < cimNF-1; im1++) // absolute offsets for image 1 to last { im2 = im1 + 1; cimOffs[im2].xf += cimOffs[im1].xf; // x/y/t offsets are additive cimOffs[im2].yf += cimOffs[im1].yf; cimOffs[im2].tf += cimOffs[im1].tf; for (ii = 0; ii < 4; ii++) { // corner warps are additive cimOffs[im2].wx[ii] += cimOffs[im1].wx[ii]; cimOffs[im2].wy[ii] += cimOffs[im1].wy[ii]; } } for (imx = 1; imx < cimNF; imx++) // re-warp to absolute cim_warp_image(imx); toff = cimOffs[0].tf; // balance +/- thetas maxtf = mintf = toff; for (imx = 1; imx < cimNF; imx++) { toff = cimOffs[imx].tf; if (toff > maxtf) maxtf = toff; if (toff < mintf) mintf = toff; } midtf = 0.5 * (maxtf + mintf); for (imx = 0; imx < cimNF; imx++) cimOffs[imx].tf -= midtf; for (im1 = 0; im1 < cimNF-1; im1++) // adjust x/y offsets for images after im1 for (im2 = im1+1; im2 < cimNF; im2++) // due to im1 theta offset { toff = cimOffs[im1].tf; xoff = cimOffs[im2].xf - cimOffs[im1].xf; yoff = cimOffs[im2].yf - cimOffs[im1].yf; dxoff = yoff * sin(toff); dyoff = xoff * sin(toff); cimOffs[im2].xf -= dxoff; cimOffs[im2].yf += dyoff; } Fzoom = Fblowup = 0; Ffuncbusy--; STPstat = 1; thread_exit(); return 0; // not executed } // paint output image zdialog *STPzd = 0; // paint dialog int STPimage; // current image (0 based) int STPradius; // paint mode radius char *STPpixmap = 0; // map input image per output pixel void STP_tweak() // v.11.02 { char imageN[8] = "imageN", labN[4] = "0"; int cc, imx; int STP_tweak_dialog_event(zdialog *zd, cchar *event); // image (o) 1 (o) 2 (o) 3 ... // radius [___] STPzd = zdialog_new(ZTX("Select and Paint Image"),mWin,Bdone,Bcancel,null); zdialog_add_widget(STPzd,"hbox","hbim","dialog",0,"space=3"); zdialog_add_widget(STPzd,"label","labim","hbim",ZTX("image"),"space=5"); zdialog_add_widget(STPzd,"hbox","hbmr","dialog",0,"space=3"); zdialog_add_widget(STPzd,"label","labr","hbmr",Bradius,"space=5"); zdialog_add_widget(STPzd,"spin","radius","hbmr","1|400|1|100"); for (imx = 0; imx < cimNF; imx++) { // add radio button for each image imageN[5] = '1' + imx; labN[0] = '1' + imx; zdialog_add_widget(STPzd,"radio",imageN,"hbim",labN); } zdialog_stuff(STPzd,"image1",1); // initial image = 1st STPimage = 0; // initial image STPradius = 100; // paint radius takeMouse(STPzd,STP_mousefunc,0); // connect mouse function cc = E3ww * E3hh; // allocate pixel map STPpixmap = zmalloc(cc,"STP"); memset(STPpixmap,cimNF,cc); // initial state, blend all images start_thread(STP_combine_thread,0); // start working thread signal_thread(); zdialog_run(STPzd,STP_tweak_dialog_event,"-10/20"); // run dialog, parallel v.11.07 zdialog_wait(STPzd); // wait for completion return; } // dialog event and completion callback function int STP_tweak_dialog_event(zdialog *zd, cchar *event) // v.11.02 { int nn; if (zd->zstat) // dialog finish { freeMouse(); // disconnect mouse function signal_thread(); wrapup_thread(8); if (zd->zstat == 1) STPstat = 1; else STPstat = 0; if (STPstat == 1) cim_trim(); // cut-off edges zdialog_free(STPzd); zfree(STPpixmap); // free pixel map } if (strnEqu(event,"image",5)) { // image radio button nn = event[5] - '0'; // 1 to cimNF if (nn > 0 && nn <= cimNF) STPimage = nn - 1; // 0 to cimNF-1 signal_thread(); } if (strEqu(event,"radius")) // change paint radius zdialog_fetch(zd,"radius",STPradius); if (strEqu(event,"focus")) { // toggle mouse capture v.12.01 takeMouse(zd,STP_mousefunc,0); // connect mouse function signal_thread(); } return 1; } // STP dialog mouse function // paint: during drag, selected image >> STPpixmap (within paint radius) >> E3 // warp: for selected image, cimPXMs >> warp >> cimPXMw >> E3 void STP_mousefunc() // v.11.02 { uint16 vpix1[3], *pix3; int imx, radius, radius2, vstat1; int mx, my, dx, dy, px3, py3, ww; double px1, py1; double xoff, yoff, sintf[10], costf[10]; radius = STPradius; // paintbrush radius radius2 = radius * radius; toparcx = Mxposn - radius; // paintbrush outline circle toparcy = Myposn - radius; toparcw = toparch = 2 * radius; Ftoparc = 1; paint_toparc(3); if (LMclick || RMclick) { // mouse click LMclick = RMclick = 0; return; // ignore } else if (Mxdrag || Mydrag) { // drag in progress mx = Mxdrag; my = Mydrag; } else return; if (mx < 0 || mx > E3ww-1 || my < 0 || my > E3hh-1) // mouse outside image area return; for (imx = 0; imx < cimNF; imx++) // pre-calculate trig funcs { sintf[imx] = sin(cimOffs[imx].tf); costf[imx] = cos(cimOffs[imx].tf); } for (dy = -radius; dy <= radius; dy++) // loop pixels around mouse for (dx = -radius; dx <= radius; dx++) { if (dx*dx + dy*dy > radius2) continue; // outside radius px3 = mx + dx; // output pixel py3 = my + dy; if (px3 < 0 || px3 > E3ww-1) continue; // outside image if (py3 < 0 || py3 > E3hh-1) continue; pix3 = PXMpix(E3pxm16,px3,py3); // output pixel imx = py3 * E3ww + px3; // update pixmap to selected image STPpixmap[imx] = STPimage; imx = STPimage; xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px1 = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); // input virtual pixel py1 = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat1 = vpixel(cimPXMw[imx],px1,py1,vpix1); if (vstat1) { pix3[0] = vpix1[0]; pix3[1] = vpix1[1]; pix3[2] = vpix1[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } mx = mx - radius - 1; // update window my = my - radius - 1; ww = 2 * radius + 3; paint_toparc(2); mwpaint3(mx,my,ww,ww); Ftoparc = 1; paint_toparc(3); return; } // Combine images in E3pxm16 (not reallocated). Update main window. void * STP_combine_thread(void *) // v.11.02 { void * STP_combine_wthread(void *); while (true) { thread_idle_loop(); // wait for work or exit request mutex_lock(&Fpixmap_lock); // stop window updates for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(STP_combine_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion mutex_unlock(&Fpixmap_lock); // update window mwpaint2(); } return 0; // not executed } void * STP_combine_wthread(void *arg) // worker thread { int index = *((int *) (arg)); int px3, py3, vstat1; int imx, red, green, blue; double px, py; double xoff, yoff, sintf[10], costf[10]; uint16 vpix1[3], *pix3; for (imx = 0; imx < cimNF; imx++) // pre-calculate trig funcs { sintf[imx] = sin(cimOffs[imx].tf); costf[imx] = cos(cimOffs[imx].tf); } for (py3 = index+1; py3 < E3hh-1; py3 += Nwt) // step through output pixels for (px3 = 1; px3 < E3ww-1; px3++) { pix3 = PXMpix(E3pxm16,px3,py3); imx = py3 * E3ww + px3; imx = STPpixmap[imx]; if (imx < cimNF) // specific image maps to pixel { xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); py = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat1 = vpixel(cimPXMw[imx],px,py,vpix1); // corresp. input vpixel if (vstat1) { pix3[0] = vpix1[0]; pix3[1] = vpix1[1]; pix3[2] = vpix1[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } else // use blend of all images { red = green = blue = 0; for (imx = 0; imx < cimNF; imx++) { xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); py = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat1 = vpixel(cimPXMw[imx],px,py,vpix1); if (vstat1) { red += vpix1[0]; green += vpix1[1]; blue += vpix1[2]; } } pix3[0] = red / cimNF; pix3[1] = green / cimNF; pix3[2] = blue / cimNF; } } exit_wthread(); return 0; // not executed, avoid gcc warning } /************************************************************************** Stack/Noise function Combine multiple photos of the same subject and average the pixels for noise reduction. **************************************************************************/ double STN_initAlignSize = 160; // initial align image size double STN_imageIncrease = 1.6; // image size increase per align cycle double STN_sampSize = 6000; // pixel sample size double STN_initSearchRange = 5.0; // initial search range, +/- pixels double STN_initSearchStep = 1.0; // initial search step, pixels double STN_initWarpRange = 2.0; // initial corner warp range double STN_initWarpStep = 1.0; // initial corner warp step double STN_searchRange = 2.0; // normal search range double STN_searchStep = 1.0; // normal search step double STN_warpRange = 1.0; // normal corner warp range double STN_warpStep = 0.67; // normal corner warp step int STN_stat; // 1 = OK, 0 = failed or canceled int STN_average = 1, STN_median = 0; // use average/median of input pixels int STN_exlow = 0, STN_exhigh = 0; // exclude low/high pixel void * STN_align_thread(void *); void STN_tweak(); void * STN_combine_thread(void *); editfunc EFstn; // edit function data // menu function void m_STN(GtkWidget *, cchar *) // new v.10.9 { char **flist; int imx, err, ww, hh; double diffw, diffh; zfuncs::F1_help_topic = "stack_noise"; // help topic if (mod_keep()) return; // warn unsaved changes if (! menulock(1)) return; // test menu lock v.11.07 menulock(0); for (imx = 0; imx < 10; imx++) { // clear all file and PXM data cimFile[imx] = 0; cimPXMf[imx] = cimPXMs[imx] = cimPXMw[imx] = 0; } cimNF = 0; flist = zgetfileN(ZTX("Select 2 to 9 files"),"openN",curr_file); // select images to combine if (! flist) return; for (imx = 0; flist[imx]; imx++); // count selected files if (imx < 2 || imx > 9) { zmessageACK(mWin,ZTX("Select 2 to 9 files")); goto cleanup; } cimNF = imx; // file count for (imx = 0; imx < cimNF; imx++) cimFile[imx] = strdupz(flist[imx],0,"STN"); // set up file list if (! cim_load_files()) goto cleanup; // load and check all files ww = cimPXMf[0]->ww; hh = cimPXMf[0]->hh; for (imx = 1; imx < cimNF; imx++) // check image compatibility { diffw = abs(ww - cimPXMf[imx]->ww); diffw = diffw / ww; diffh = abs(hh - cimPXMf[imx]->hh); diffh = diffh / hh; if (diffw > 0.02 || diffh > 0.02) { zmessageACK(mWin,ZTX("Images are not all the same size")); goto cleanup; } } free_resources(); // ready to commit err = f_open(cimFile[0],0); // curr_file = 1st file in list if (err) goto cleanup; EFstn.funcname = "stack-noise"; if (! edit_setup(EFstn)) goto cleanup; // setup edit (will lock) start_thread(STN_align_thread,0); // align each pair of images wrapup_thread(0); // wait for completion if (STN_stat != 1) goto cancel; STN_tweak(); // combine images based on user inputs if (STN_stat != 1) goto cancel; CEF->Fmod = 1; // done edit_done(EFstn); goto cleanup; cancel: edit_cancel(EFstn); cleanup: if (flist) { for (imx = 0; flist[imx]; imx++) // free file list zfree(flist[imx]); zfree(flist); } for (imx = 0; imx < cimNF; imx++) { // free cim file and PXM data if (cimFile[imx]) zfree(cimFile[imx]); if (cimPXMf[imx]) PXM_free(cimPXMf[imx]); if (cimPXMs[imx]) PXM_free(cimPXMs[imx]); if (cimPXMw[imx]) PXM_free(cimPXMw[imx]); } *SB_text = 0; return; } // align each image 2nd-last to 1st image // cimPXMf[*] original image // cimPXMs[*] scaled and color adjusted for pixel comparisons // cimPXMw[*] warped for display void * STN_align_thread(void *) // v.10.9 { int imx, im1, im2, ww, hh, ii, nn; double R, maxtf, mintf, midtf; double xoff, yoff, toff, dxoff, dyoff; Fzoom = 0; // fit to window if big Fblowup = 1; // scale up to window if small Ffuncbusy++; // v.11.01 cimShrink = 0; // no warp shrinkage (pano) cimPano = cimPanoV = 0; // no pano mode for (imx = 1; imx < cimNF; imx++) // loop 2nd to last image { im1 = 0; // images to align im2 = imx; memset(&cimOffs[im1],0,sizeof(cimoffs)); // initial image offsets = 0 memset(&cimOffs[im2],0,sizeof(cimoffs)); ww = cimPXMf[im1]->ww; // image dimensions hh = cimPXMf[im1]->hh; nn = ww; // use larger of ww, hh if (hh > ww) nn = hh; cimScale = STN_initAlignSize / nn; // initial align image size if (cimScale > 1.0) cimScale = 1.0; cimBlend = 0; // no blend width (use all) cim_get_overlap(im1,im2,cimPXMf); // get overlap area cim_match_colors(im1,im2,cimPXMf); // get color matching factors cimSearchRange = STN_initSearchRange; // initial align search range cimSearchStep = STN_initSearchStep; // initial align search step cimWarpRange = STN_initWarpRange; // initial align corner warp range cimWarpStep = STN_initWarpStep; // initial align corner warp step cimSampSize = STN_sampSize; // pixel sample size for align/compare cimNsearch = 0; // reset align search counter while (true) // loop, increasing image size { cim_scale_image(im1,cimPXMs); // scale images to cimScale cim_scale_image(im2,cimPXMs); cim_adjust_colors(cimPXMs[im1],1); // apply color adjustments cim_adjust_colors(cimPXMs[im2],2); cim_warp_image(im1); // warp images for show cim_warp_image(im2); cimShowIm1 = im1; // show these two images cimShowIm2 = im2; // with 50/50 blend cimShowAll = 0; cim_show_images(1,0); // (y offset can change) cim_get_overlap(im1,im2,cimPXMs); // get overlap area v.11.04 cim_get_redpix(im1); // get high-contrast pixels cim_align_image(im1,im2); // align im2 to im1 zfree(cimRedpix); // clear red pixels cimRedpix = 0; if (cimScale == 1.0) break; // done R = STN_imageIncrease; // next larger image size cimScale = cimScale * R; if (cimScale > 0.85) { // if close to end, jump to end R = R / cimScale; cimScale = 1.0; } cimOffs[im1].xf *= R; // scale offsets for larger image cimOffs[im1].yf *= R; cimOffs[im2].xf *= R; cimOffs[im2].yf *= R; for (ii = 0; ii < 4; ii++) { cimOffs[im1].wx[ii] *= R; cimOffs[im1].wy[ii] *= R; cimOffs[im2].wx[ii] *= R; cimOffs[im2].wy[ii] *= R; } cimSearchRange = STN_searchRange; // align search range cimSearchStep = STN_searchStep; // align search step size cimWarpRange = STN_warpRange; // align corner warp range cimWarpStep = STN_warpStep; // align corner warp step size } } toff = cimOffs[0].tf; // balance +/- thetas maxtf = mintf = toff; for (imx = 1; imx < cimNF; imx++) { toff = cimOffs[imx].tf; if (toff > maxtf) maxtf = toff; if (toff < mintf) mintf = toff; } midtf = 0.5 * (maxtf + mintf); for (imx = 0; imx < cimNF; imx++) cimOffs[imx].tf -= midtf; for (im1 = 0; im1 < cimNF-1; im1++) // adjust x/y offsets for images after im1 for (im2 = im1+1; im2 < cimNF; im2++) // due to im1 theta offset { toff = cimOffs[im1].tf; xoff = cimOffs[im2].xf - cimOffs[im1].xf; yoff = cimOffs[im2].yf - cimOffs[im1].yf; dxoff = yoff * sin(toff); dyoff = xoff * sin(toff); cimOffs[im2].xf -= dxoff; cimOffs[im2].yf += dyoff; } Fzoom = Fblowup = 0; Ffuncbusy--; STN_stat = 1; thread_exit(); return 0; // not executed } // change pixel combination according to user input void STN_tweak() // v.10.9 { zdialog *zd; int STN_tweak_dialog_event(zdialog *zd, cchar *event); // Adjust Pixel Composition // // (o) use average (o) use median // [x] omit lowest value // [x] omit highest value zd = zdialog_new(ZTX("Adjust Pixel Composition"),mWin,Bdone,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"radio","average","hb1","use average","space=3"); zdialog_add_widget(zd,"radio","median","hb1","use median","space=3"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=3"); zdialog_add_widget(zd,"check","exlow","hb2","omit low pixel","space=3"); zdialog_add_widget(zd,"check","exhigh","hb2","omit high pixel","space=3"); zdialog_stuff(zd,"average",1); // default = average zdialog_stuff(zd,"median",0); zdialog_stuff(zd,"exlow",0); zdialog_stuff(zd,"exhigh",0); STN_average = 1; STN_median = 0; STN_exlow = 0; STN_exhigh = 0; start_thread(STN_combine_thread,0); // start working thread signal_thread(); zdialog_resize(zd,250,0); zdialog_run(zd,STN_tweak_dialog_event,"-10/20"); // run dialog, parallel v.11.07 zdialog_wait(zd); // wait for completion return; } // dialog event and completion callback function int STN_tweak_dialog_event(zdialog *zd, cchar *event) // v.10.9 { if (zd->zstat) { // dialog finish if (zd->zstat == 1) STN_stat = 1; else STN_stat = 0; wrapup_thread(8); zdialog_free(zd); if (STN_stat == 1) cim_trim(); // trim edges v.10.9 } if (strEqu(event,"average")) { zdialog_fetch(zd,"average",STN_average); signal_thread(); } if (strEqu(event,"median")) { zdialog_fetch(zd,"median",STN_median); signal_thread(); } if (strEqu(event,"exlow")) { zdialog_fetch(zd,"exlow",STN_exlow); signal_thread(); } if (strEqu(event,"exhigh")) { zdialog_fetch(zd,"exhigh",STN_exhigh); signal_thread(); } return 1; } // compute mean/median mix for each output pixel and update E3 image void * STN_combine_thread(void *) // v.10.9 { void * STN_combine_wthread(void *arg); // worker thread while (true) { thread_idle_loop(); // wait for work or exit request for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(STN_combine_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed } // worker thread void * STN_combine_wthread(void *arg) // v.10.9 { int index = *((int *) arg); int imx, vstat, px3, py3; int red, green, blue; int ii, ns, ns1, ns2; int Rlist[10], Glist[10], Blist[10]; double px, py; double xoff, yoff, sintf[10], costf[10]; uint16 *pix3, vpix[3]; // input layers 0 1 2 3 4 5 6 7 8 9 10 int nsx[11][2] = { {0,0}, {0,0}, {0,1}, {1,1}, {1,2}, {2,2}, {2,3}, {2,4}, {2,5}, {3,5}, {3,6} }; for (imx = 0; imx < cimNF; imx++) // pre-calculate trig funcs { sintf[imx] = sin(cimOffs[imx].tf); costf[imx] = cos(cimOffs[imx].tf); } for (py3 = index+1; py3 < E3hh-1; py3 += Nwt) // step through output pixels for (px3 = 1; px3 < E3ww-1; px3++) { for (imx = ns = 0; imx < cimNF; imx++) // get aligned input pixels { xoff = cimOffs[imx].xf; yoff = cimOffs[imx].yf; px = costf[imx] * (px3 - xoff) + sintf[imx] * (py3 - yoff); py = costf[imx] * (py3 - yoff) - sintf[imx] * (px3 - xoff); vstat = vpixel(cimPXMw[imx],px,py,vpix); if (vstat) { Rlist[ns] = vpix[0]; // add pixel RGB values to list Glist[ns] = vpix[1]; Blist[ns] = vpix[2]; ns++; } } if (! ns) continue; if (STN_exlow || STN_exhigh || STN_median) { // RGB values must be sorted HeapSort(Rlist,ns); HeapSort(Glist,ns); HeapSort(Blist,ns); } red = green = blue = 0; if (STN_average) // average the input pixels { ns1 = 0; // low and high RGB values ns2 = ns - 1; if (STN_exlow) { // exclude low ns1++; if (ns1 > ns2) ns1--; } if (STN_exhigh) { // exclude high ns2--; if (ns1 > ns2) ns2++; } for (ii = ns1; ii <= ns2; ii++) // sum remaining RGB levels { red += Rlist[ii]; green += Glist[ii]; blue += Blist[ii]; } ns = ns2 - ns1 + 1; // sample count red = red / ns; // output RGB = average green = green / ns; blue = blue / ns; } if (STN_median) // use median input pixels { ns1 = nsx[ns][0]; // middle group of pixels ns2 = nsx[ns][1]; for (ii = ns1; ii <= ns2; ii++) { red += Rlist[ii]; green += Glist[ii]; blue += Blist[ii]; } ns = ns2 - ns1 + 1; // sample count red = red / ns; // output RGB = average green = green / ns; blue = blue / ns; } pix3 = PXMpix(E3pxm16,px3,py3); // output pixel pix3[0] = red; pix3[1] = green; pix3[2] = blue; } exit_wthread(); return 0; // not executed } /************************************************************************** Panorama function: join 2, 3, or 4 images. ***************************************************************************/ int panStat; // 1 = OK zdialog *panozd = 0; // pre-align dialog double panPreAlignSize = 1000; // pre-align image size (ww) double panInitAlignSize = 200; // initial align image size double panImageIncrease = 1.6; // image size increase per align cycle double panSampSize = 10000; // pixel sample size double panPreAlignBlend = 0.30; // pre-align blend width * ww double panInitBlend = 0.20; // initial blend width during auto-align double panFinalBlend = 0.08; // final blend width * ww double panBlendDecrease = 0.8; // blend width reduction per align cycle double panInitSearchRange = 5.0; // initial search range, +/- pixels double panInitSearchStep = 0.7; // initial search step, pixels double panInitWarpRange = 4.0; // initial corner warp range, +/- pixels double panInitWarpStep = 1.0; // initial corner warp step, pixels double panSearchRange = 3.0; // normal search range, +/- pixels double panSearchStep = 1.0; // normal search step, pixels double panWarpRange = 2.0; // normal corner warp range, +/- pixels double panWarpStep = 1.0; // normal corner warp step, pixels void pano_prealign(); // manual pre-align void pano_align(); // auto fine-align void pano_tweak(); // user color tweak editfunc EFpano; // edit function data // menu function void m_pano(GtkWidget *, cchar *) // v.10.7 { int imx, err; char **flist = 0; zfuncs::F1_help_topic = "panorama"; // help topic if (mod_keep()) return; // warn unsaved changes if (! menulock(1)) return; // test menu lock v.11.07 menulock(0); for (imx = 0; imx < 10; imx++) { // clear all file and PXM data cimFile[imx] = 0; cimPXMf[imx] = cimPXMs[imx] = cimPXMw[imx] = 0; } cimNF = 0; flist = zgetfileN(ZTX("Select 2 to 4 files"),"openN",curr_file); // select images to combine if (! flist) return; for (imx = 0; flist[imx]; imx++); // count selected files if (imx < 2 || imx > 4) { zmessageACK(mWin,ZTX("Select 2 to 4 files")); goto cleanup; } cimNF = imx; // file count for (imx = 0; imx < cimNF; imx++) cimFile[imx] = strdupz(flist[imx],0,"pano"); // set up file list if (! cim_load_files()) goto cleanup; // load and check all files free_resources(); // ready to commit err = f_open(cimFile[0],0); // curr_file = 1st file in list if (err) goto cleanup; EFpano.funcname = "pano"; if (! edit_setup(EFpano)) goto cleanup; // setup edit (will lock) cimShowAll = 1; // for cim_show_images(), show all v.10.9 cimShrink = 0; // no warp shrinkage v.11.04 cimPano = 1; // horizontal pano mode v.11.04 cimPanoV = 0; pano_prealign(); // manual pre-alignment if (panStat != 1) goto cancel; pano_align(); // auto full alignment if (panStat != 1) goto cancel; pano_tweak(); // manual color adjustment if (panStat != 1) goto cancel; CEF->Fmod = 1; // done edit_done(EFpano); goto cleanup; cancel: // failed or canceled edit_cancel(EFpano); cleanup: if (flist) { for (imx = 0; flist[imx]; imx++) // free file list zfree(flist[imx]); zfree(flist); } for (imx = 0; imx < cimNF; imx++) { // free cim file and PXM data if (cimFile[imx]) zfree(cimFile[imx]); if (cimPXMf[imx]) PXM_free(cimPXMf[imx]); if (cimPXMs[imx]) PXM_free(cimPXMs[imx]); if (cimPXMw[imx]) PXM_free(cimPXMw[imx]); } *SB_text = 0; return; } // perform manual pre-align of all images // returns alignment data in cimOffs[*] // lens_mm and lens_bow may also be altered void pano_prealign() // v.10.7 { int pano_prealign_event(zdialog *zd, cchar *event); // dialog event function void * pano_prealign_thread(void *); // working thread int imx, ww, err = 0; cchar *exifkey = { exif_focal_length_key }; cchar *lensource; char **pp = 0; cchar *align_mess = ZTX("Drag images into rough alignment.\n" "To rotate, drag from lower edge."); cchar *search_mess = ZTX("Search for lens mm and bow"); lens_bow = lens_settings[1]; // no EXIF for this v.12.01 pp = info_get(curr_file,&exifkey,1); // get lens mm from EXIF if available if (pp && *pp) { err = convSD(*pp, lens_mm, 20, 1000); lensource = "(EXIF)"; // lens mm from EXIF } if (! pp || ! *pp || err) { // not available lens_mm = lens_settings[0]; // v.12.01 lensource = "(settings)"; // lens mm from user settings } for (imx = 0; imx < 10; imx++) // set all alignment offsets = 0 memset(&cimOffs[imx],0,sizeof(cimoffs)); for (imx = ww = 0; imx < cimNF; imx++) // sum image widths ww += cimPXMf[imx]->ww; cimScale = 1.4 * panPreAlignSize / ww; // set alignment image scale if (cimScale > 1.0) cimScale = 1.0; // (* 0.7 after overlaps) for (imx = 0; imx < cimNF; imx++) // scale images > cimPXMs[*] cim_scale_image(imx,cimPXMs); for (imx = 0; imx < cimNF; imx++) { // curve images, cimPXMs[*] replaced cim_curve_image(imx); cimPXMw[imx] = PXM_copy(cimPXMs[imx]); // copy to cimPXMw[*] for display } cimOffs[0].xf = cimOffs[0].yf = 0; // first image at (0,0) for (imx = 1; imx < cimNF; imx++) // position images with 30% overlap { // in horizontal row cimOffs[imx].xf = cimOffs[imx-1].xf + 0.7 * cimPXMw[imx-1]->ww; cimOffs[imx].yf = cimOffs[imx-1].yf; } Fzoom = 0; // scale image to fit window Fblowup = 1; // magnify small image to window size cimBlend = panPreAlignBlend * cimPXMw[1]->ww; // overlap in align window cim_show_images(1,0); // combine and show images in main window panozd = zdialog_new(ZTX("Pre-align Images"),mWin,Bproceed,Bcancel,null); // start pre-align dialog zdialog_add_widget(panozd,"label","lab1","dialog",align_mess,"space=5"); zdialog_add_widget(panozd,"hbox","hb1","dialog",0,"space=2"); zdialog_add_widget(panozd,"spin","spmm","hb1","20|999|0.1|35","space=5"); // [ 35 ] lens mm (source) zdialog_add_widget(panozd,"label","labmm","hb1",ZTX("lens mm")); // [ 0.3 ] lens bow zdialog_add_widget(panozd,"label","labsorc","hb1","","space=5"); // [resize] resize window zdialog_add_widget(panozd,"hbox","hb2","dialog",0,"space=2"); // [search] search lens mm and bow zdialog_add_widget(panozd,"spin","spbow","hb2","-9|9|0.01|0","space=5"); zdialog_add_widget(panozd,"label","labbow","hb2",ZTX("lens bow")); zdialog_add_widget(panozd,"hbox","hb3","dialog",0,"space=2"); zdialog_add_widget(panozd,"button","resize","hb3",ZTX("Resize"),"space=5"); zdialog_add_widget(panozd,"label","labsiz","hb3",ZTX("resize window"),"space=5"); zdialog_add_widget(panozd,"hbox","hb4","dialog",0,"space=2"); zdialog_add_widget(panozd,"button","search","hb4",Bsearch,"space=5"); zdialog_add_widget(panozd,"label","labsearch","hb4",search_mess,"space=5"); zdialog_stuff(panozd,"spmm",lens_mm); // stuff lens data zdialog_stuff(panozd,"spbow",lens_bow); zdialog_stuff(panozd,"labsorc",lensource); // show source of lens data panStat = -1; // busy status gdk_window_set_cursor(drWin->window,dragcursor); // set drag cursor v.11.03 zdialog_run(panozd,pano_prealign_event,"-10/20"); // start dialog v.11.07 start_thread(pano_prealign_thread,0); // start working thread zdialog_wait(panozd); // wait for dialog completion gdk_window_set_cursor(drWin->window,0); // restore normal cursor v.11.03 Fzoom = Fblowup = 0; return; } // pre-align dialog event function int pano_prealign_event(zdialog *zd, cchar *event) // v.10.7 { int imx; double overlap; if (strstr("spmm spbow",event)) { zdialog_fetch(zd,"spmm",lens_mm); // get revised lens data zdialog_fetch(zd,"spbow",lens_bow); } if (strEqu(event,"resize")) // allocate new E3 image cim_show_images(1,0); if (strEqu(event,"search")) { // search for optimal lens parms if (cimNF != 2) zmessageACK(mWin,ZTX("use two images only")); else panStat = 2; // tell thread to search return 0; } if (zd->zstat) // dialog complete { if (zd->zstat == 1) // proceed panStat = 1; else // cancel or other panStat = 0; zdialog_free(panozd); // kill dialog wrapup_thread(0); // wait for thread if (! panStat) return 0; // canceled for (imx = 0; imx < cimNF-1; imx++) // check for enough overlap { overlap = cim_get_overlap(imx,imx+1,cimPXMs); // v.11.04 if (overlap < panFinalBlend) { // v.11.09 zmessageACK(mWin,ZTX("Too little overlap, cannot align")); panStat = 0; return 0; } } } return 0; } // pre-align working thread // convert mouse and KB events into image movements // overhauled v.11.02 void * pano_prealign_thread(void *) { void pano_autolens(); cimoffs offstemp; PXM *pxmtemp; char *ftemp; int im1, im2, imm, imx; int mx0, my0, mx, my; // mouse drag origin, position int xoff, yoff, lox, hix; int sepx, minsep; int ww, hh, rotate, midx; double lens_mm0, lens_bow0; double dx, dy, t1, t2, dt; imm = ww = hh = rotate = xoff = yoff = 0; // stop compiler warnings lens_mm0 = lens_mm; // to detect changes lens_bow0 = lens_bow; mx0 = my0 = 0; // no drag in progress Mcapture = KBcapture = 1; // capture mouse drag and KB keys cimBlend = 0; // full blend during pre-align while (true) // loop and align until done { zsleep(0.05); // logic simplified if (panStat == 2) { // dialog search button panStat = -1; // back to busy status pano_autolens(); } if (panStat != -1) break; // quit signal from dialog if (lens_mm != lens_mm0 || lens_bow != lens_bow0) { // change in lens parameters lens_mm0 = lens_mm; lens_bow0 = lens_bow; for (imx = 0; imx < cimNF; imx++) { // re-curve images cim_scale_image(imx,cimPXMs); cim_curve_image(imx); PXM_free(cimPXMw[imx]); cimPXMw[imx] = PXM_copy(cimPXMs[imx]); } cim_show_images(1,0); // combine and show images continue; } if (KBkey) { // KB input if (KBkey == GDK_Left) cimOffs[imm].xf -= 0.5; // tweak alignment offsets if (KBkey == GDK_Right) cimOffs[imm].xf += 0.5; if (KBkey == GDK_Up) cimOffs[imm].yf -= 0.5; if (KBkey == GDK_Down) cimOffs[imm].yf += 0.5; if (KBkey == GDK_r) cimOffs[imm].tf += 0.0005; if (KBkey == GDK_l) cimOffs[imm].tf -= 0.0005; KBkey = 0; cim_show_images(0,0); // combine and show images continue; } if (! Mxdrag && ! Mydrag) // no drag underway mx0 = my0 = 0; // reset drag origin if (Mxdrag || Mydrag) // mouse drag underway { mx = Mxdrag; // mouse position in image my = Mydrag; if (! mx0 && ! my0) // new drag { mx0 = mx; // set drag origin my0 = my; minsep = 9999; for (imx = 0; imx < cimNF; imx++) // find image with midpoint { // closest to mouse x lox = cimOffs[imx].xf; hix = lox + cimPXMw[imx]->ww; midx = (lox + hix) / 2; sepx = abs(midx - mx0); if (sepx < minsep) { minsep = sepx; imm = imx; // image to drag or rotate } } xoff = cimOffs[imm].xf; yoff = cimOffs[imm].yf; ww = cimPXMw[imm]->ww; hh = cimPXMw[imm]->hh; rotate = 0; // if drag at bottom edge, if (my0 > yoff + 0.85 * hh) rotate = 1; // set rotate flag v.11.04 } if (mx != mx0 || my != my0) // drag is progressing { dx = mx - mx0; // mouse movement dy = my - my0; if (rotate && my0 > yoff && my > yoff) // rotation { if (imm > 0) { lox = cimOffs[imm].xf; // if there is an image to the left, hix = cimOffs[imm-1].xf + cimPXMw[imm-1]->ww; // midx = midpoint of overlap midx = (lox + hix) / 2; } else midx = 0; // this is the leftmost image t1 = atan(1.0 * (mx0-xoff) / (my0-yoff)); t2 = atan(1.0 * (mx-xoff) / (my-yoff)); dt = t1 - t2; // angle change dx = dt * (hh/2 + yoff); // pivot = middle of overlap on left dy = -dt * (midx-xoff); } else dt = 0; // x/y drag cimOffs[imm].xf += dx; // update image cimOffs[imm].yf += dy; cimOffs[imm].tf += dt; xoff = cimOffs[imm].xf; // v.11.04 yoff = cimOffs[imm].yf; cim_show_images(0,0); // show combined images mx0 = mx; // next drag origin = current mouse my0 = my; } } for (im1 = 0; im1 < cimNF-1; im1++) // track image order changes { im2 = im1 + 1; if (cimOffs[im2].xf < cimOffs[im1].xf) { ftemp = cimFile[im2]; // switch filespecs cimFile[im2] = cimFile[im1]; cimFile[im1] = ftemp; pxmtemp = cimPXMf[im2]; // switch images cimPXMf[im2] = cimPXMf[im1]; cimPXMf[im1] = pxmtemp; pxmtemp = cimPXMs[im2]; // scaled images cimPXMs[im2] = cimPXMs[im1]; cimPXMs[im1] = pxmtemp; pxmtemp = cimPXMw[im2]; // warped images cimPXMw[im2] = cimPXMw[im1]; cimPXMw[im1] = pxmtemp; offstemp = cimOffs[im2]; // offsets cimOffs[im2] = cimOffs[im1]; cimOffs[im1] = offstemp; if (imm == im1) imm = im2; // current drag image else if (imm == im2) imm = im1; break; } } } KBcapture = Mcapture = 0; thread_exit(); return 0; // not executed, stop g++ warning } // optimize lens parameters // inputs and outputs: // pre-aligned images cimPXMw[0] and [1] // offsets in cimOffs[0] and [1] // lens_mm, lens_bow void pano_autolens() // v.10.7 { double mm_range, bow_range, xf_range, yf_range, tf_range; double squeeze, xf_rfinal, rnum, matchB, matchlev; double overlap, lens_mmB, lens_bowB; int imx, randcount = 0; cimoffs offsetsB; overlap = cim_get_overlap(0,1,cimPXMs); // v.11.04 if (overlap < 0.1) { threadmessage = ZTX("Too little overlap, cannot align"); return; } Ffuncbusy++; // v.11.01 cimSampSize = 2000; // v.11.03 cimNsearch = 0; mm_range = 0.1 * lens_mm; // set initial search ranges v.11.03 bow_range = 0.3 * lens_bow; if (bow_range < 0.5) bow_range = 0.5; xf_range = 7; yf_range = 7; tf_range = 0.01; xf_rfinal = 0.3; // final xf range - when to quit cim_match_colors(0,1,cimPXMw); // adjust colors for image matching cim_adjust_colors(cimPXMs[0],1); cim_adjust_colors(cimPXMw[0],1); cim_adjust_colors(cimPXMs[1],2); cim_adjust_colors(cimPXMw[1],2); lens_mmB = lens_mm; // starting point lens_bowB = lens_bow; offsetsB = cimOffs[1]; cimSearchRange = 7; matchB = 0; while (true) { srand48(time(0) + randcount++); lens_mm = lens_mmB + mm_range * (drand48() - 0.5); // new random lens factors lens_bow = lens_bowB + bow_range * (drand48() - 0.5); // within search range for (imx = 0; imx <= 1; imx++) { // re-curve images cim_scale_image(imx,cimPXMs); cim_curve_image(imx); PXM_free(cimPXMw[imx]); cimPXMw[imx] = PXM_copy(cimPXMs[imx]); } cim_get_redpix(0); // get high-contrast pixels v.11.03 cim_show_images(0,0); // combine and show images squeeze = 0.97; // search range reduction v.10.7 for (int ii = 0; ii < 1000; ii++) // loop random x/y/t alignments { rnum = drand48(); if (rnum < 0.33) // random change some alignment offset cimOffs[1].xf = offsetsB.xf + xf_range * (drand48() - 0.5); else if (rnum < 0.67) cimOffs[1].yf = offsetsB.yf + yf_range * (drand48() - 0.5); else cimOffs[1].tf = offsetsB.tf + tf_range * (drand48() - 0.5); matchlev = cim_match_images(0,1); // test quality of image alignment sprintf(SB_text,"align: %d match: %.5f lens: %.1f %.2f", // update status bar ++cimNsearch, matchB, lens_mmB, lens_bowB); zmainloop(); // v.11.11.1 if (sigdiff(matchlev,matchB,0.00001) > 0) { matchB = matchlev; // save new best fit lens_mmB = lens_mm; // alignment is better lens_bowB = lens_bow; offsetsB = cimOffs[1]; cim_show_images(0,0); squeeze = 1; // keep same search range as long break; // as improvements are found } if (panStat != -1) goto done; // user kill } if (xf_range < xf_rfinal) goto done; // finished sprintf(SB_text,"align: %d match: %.5f lens: %.1f %.2f", // update status bar cimNsearch, matchB, lens_mmB, lens_bowB); zmainloop(); // v.11.11.1 mm_range = squeeze * mm_range; // reduce search range if no if (mm_range < 0.02 * lens_mmB) mm_range = 0.02 * lens_mmB; // improvements were found bow_range = squeeze * bow_range; if (bow_range < 0.1 * lens_bowB) bow_range = 0.1 * lens_bowB; if (bow_range < 0.2) bow_range = 0.2; xf_range = squeeze * xf_range; yf_range = squeeze * yf_range; tf_range = squeeze * tf_range; } done: zfree(cimRedpix); cimRedpix = 0; lens_mm = lens_mmB; // save best lens params found lens_bow = lens_bowB; if (panStat == -1 && panozd) { // unless killed zdialog_stuff(panozd,"spmm",lens_mm); zdialog_stuff(panozd,"spbow",lens_bow); } cimSampSize = panSampSize; // restore Ffuncbusy--; cim_show_images(1,0); // images are left color-matched return; } // fine-alignment // start with very small image size // search around offset values for best match // increase image size and loop until full-size void pano_align() // v.10.7 { int imx, im1, im2, ww; double R, dx, dy, dt; double overlap; cimoffs offsets0; Fzoom = 0; // scale E3 to fit window Fblowup = 1; // magnify small image to window size Ffuncbusy++; // v.11.01 for (imx = 0; imx < cimNF; imx++) { cimOffs[imx].xf = cimOffs[imx].xf / cimScale; // scale x/y offsets for full-size images cimOffs[imx].yf = cimOffs[imx].yf / cimScale; } cimScale = 1.0; // full-size for (imx = 0; imx < cimNF; imx++) { PXM_free(cimPXMs[imx]); cimPXMs[imx] = PXM_copy(cimPXMf[imx]); // copy full-size images cim_curve_image(imx); // curve them } cimBlend = 0.3 * cimPXMs[0]->ww; cim_get_overlap(0,1,cimPXMs); // match images 0 & 1 in overlap area cim_match_colors(0,1,cimPXMs); cim_adjust_colors(cimPXMf[0],1); // image 0 << profile 1 cim_adjust_colors(cimPXMf[1],2); // image 1 << profile 2 if (cimNF > 2) { cimBlend = 0.3 * cimPXMs[1]->ww; cim_get_overlap(1,2,cimPXMs); cim_match_colors(1,2,cimPXMs); cim_adjust_colors(cimPXMf[0],1); cim_adjust_colors(cimPXMf[1],1); cim_adjust_colors(cimPXMf[2],2); } if (cimNF > 3) { cimBlend = 0.3 * cimPXMs[2]->ww; cim_get_overlap(2,3,cimPXMs); cim_match_colors(2,3,cimPXMs); cim_adjust_colors(cimPXMf[0],1); cim_adjust_colors(cimPXMf[1],1); cim_adjust_colors(cimPXMf[2],1); cim_adjust_colors(cimPXMf[3],2); } cimScale = panInitAlignSize / cimPXMf[1]->hh; // initial align image scale if (cimScale > 1.0) cimScale = 1.0; for (imx = 0; imx < cimNF; imx++) { // scale offsets for image scale cimOffs[imx].xf = cimOffs[imx].xf * cimScale; cimOffs[imx].yf = cimOffs[imx].yf * cimScale; } cimSearchRange = panInitSearchRange; // initial align search range cimSearchStep = panInitSearchStep; // initial align search step cimWarpRange = panInitWarpRange; // initial align corner warp range cimWarpStep = panInitWarpStep; // initial align corner warp step ww = cimPXMf[0]->ww * cimScale; // initial align image width cimBlend = ww * panInitBlend; // initial align blend width cimSampSize = panSampSize; // pixel sample size for align/compare cimNsearch = 0; // reset align search counter while (true) // loop, increasing image size { for (imx = 0; imx < cimNF; imx++) { // prepare images cim_scale_image(imx,cimPXMs); // scale to new size cim_curve_image(imx); // curve based on lens params cim_warp_image_pano(imx,1); // apply corner warps } cim_show_images(1,0); // show with 50/50 blend in overlaps for (im1 = 0; im1 < cimNF-1; im1++) // fine-align each image with left neighbor { im2 = im1 + 1; offsets0 = cimOffs[im2]; // save initial alignment offsets overlap = cim_get_overlap(im1,im2,cimPXMs); // get overlap area v.11.04 if (overlap < panFinalBlend-2) { zmessageACK(mWin,ZTX("Too little overlap, cannot align")); // v.11.03 goto fail; } cim_get_redpix(im1); // get high-contrast pixels cim_align_image(im1,im2); // search for best offsets and warps zfree(cimRedpix); // clear red pixels cimRedpix = 0; dx = cimOffs[im2].xf - offsets0.xf; // changes from initial offsets dy = cimOffs[im2].yf - offsets0.yf; dt = cimOffs[im2].tf - offsets0.tf; for (imx = im2+1; imx < cimNF; imx++) // propagate to following images { cimOffs[imx].xf += dx; cimOffs[imx].yf += dy; cimOffs[imx].tf += dt; ww = cimOffs[imx].xf - cimOffs[im2].xf; cimOffs[imx].yf += ww * dt; } } if (cimScale == 1.0) goto success; // done R = panImageIncrease; // next larger image size cimScale = cimScale * R; if (cimScale > 0.85) { // if close to end, jump to end R = R / cimScale; cimScale = 1.0; } for (imx = 0; imx < cimNF; imx++) // scale offsets for new size { cimOffs[imx].xf *= R; cimOffs[imx].yf *= R; for (int ii = 0; ii < 4; ii++) { cimOffs[imx].wx[ii] *= R; cimOffs[imx].wy[ii] *= R; } } cimSearchRange = panSearchRange; // align search range cimSearchStep = panSearchStep; // align search step size cimWarpRange = panWarpRange; // align corner warp range cimWarpStep = panWarpStep; // align corner warp step size cimBlend = cimBlend * panBlendDecrease * R; // blend width, reduced ww = cimPXMf[0]->ww * cimScale; if (cimBlend < panFinalBlend * ww) cimBlend = panFinalBlend * ww; // stay above minimum } success: panStat = 1; goto align_done; fail: panStat = 0; align_done: cimBlend = 1; // tiny blend (increase in tweak if wanted) Fzoom = Fblowup = 0; Ffuncbusy--; cim_show_images(0,0); return; } // get user inputs for RGB changes and blend width, update cimPXMw[*] void pano_tweak() // v.10.7 { int pano_tweak_event(zdialog *zd, cchar *event); // dialog event function cchar *tweaktitle = ZTX("Match Brightness and Color"); char imageN[8] = "imageN"; int imx; cimBlend = 1; // init. blend width panozd = zdialog_new(tweaktitle,mWin,Bdone,Bcancel,null); zdialog_add_widget(panozd,"hbox","hbim","dialog",0,"space=5"); zdialog_add_widget(panozd,"label","labim","hbim",ZTX("image"),"space=5"); // image (o) (o) (o) (o) zdialog_add_widget(panozd,"hbox","hbc1","dialog",0,"homog"); // zdialog_add_widget(panozd,"label","labred","hbc1",Bred); // red green blue zdialog_add_widget(panozd,"label","labgreen","hbc1",Bgreen); // [_____] [_____] [_____] zdialog_add_widget(panozd,"label","labblue","hbc1",Bblue); // zdialog_add_widget(panozd,"hbox","hbc2","dialog",0,"homog"); // brightness [___] [apply] zdialog_add_widget(panozd,"spin","red","hbc2","50|200|0.1|100","space=5"); // zdialog_add_widget(panozd,"spin","green","hbc2","50|200|0.1|100","space=5"); // -------------------------- zdialog_add_widget(panozd,"spin","blue","hbc2","50|200|0.1|100","space=5"); // zdialog_add_widget(panozd,"hbox","hbbri","dialog",0,"space=5"); // [auto color] [file color] zdialog_add_widget(panozd,"label","labbr","hbbri",Bbrightness,"space=5"); // zdialog_add_widget(panozd,"spin","bright","hbbri","50|200|0.1|100"); // -------------------------- zdialog_add_widget(panozd,"button","brapp","hbbri",Bapply,"space=10"); // zdialog_add_widget(panozd,"hsep","hsep","dialog",0,"space=5"); // blend width [___] [apply] zdialog_add_widget(panozd,"hbox","hbc3","dialog",0,"space=5"); // zdialog_add_widget(panozd,"button","auto","hbc3",ZTX("auto color"),"space=5"); // [done] [cancel] zdialog_add_widget(panozd,"button","file","hbc3",ZTX("file color"),"space=5"); zdialog_add_widget(panozd,"hsep","hsep","dialog",0,"space=5"); zdialog_add_widget(panozd,"hbox","hbblen","dialog",0); zdialog_add_widget(panozd,"label","labbl","hbblen",Bblendwidth,"space=5"); zdialog_add_widget(panozd,"spin","blend","hbblen","1|300|1|1"); zdialog_add_widget(panozd,"button","blapp","hbblen",Bapply,"space=15"); for (imx = 0; imx < cimNF; imx++) { // add radio button per image imageN[5] = '0' + imx; zdialog_add_widget(panozd,"radio",imageN,"hbim",0,"space=5"); } zdialog_stuff(panozd,"image0",1); // pre-select 1st image zdialog_resize(panozd,300,0); panStat = -1; // busy status zdialog_run(panozd,pano_tweak_event,"-10/20"); // run dialog, parallel v.11.07 zdialog_wait(panozd); // wait for dialog completion return; } // dialog event function int pano_tweak_event(zdialog *zd, cchar *event) // v.10.7 { char imageN[8] = "imageN"; double red, green, blue, bright, bright2; double red1, green1, blue1; int nn, im0, imx, im1, im2, ww, hh, px, py; uint16 *pixel; if (zd->zstat) // dialog complete { if (zd->zstat == 1) panStat = 1; // done if (zd->zstat == 2) panStat = 0; // cancel zdialog_free(panozd); // kill dialog return 0; } for (im0 = 0; im0 < cimNF; im0++) { // get which image is selected imageN[5] = '0' + im0; // by the radio buttons zdialog_fetch(zd,imageN,nn); if (nn) break; } if (im0 == cimNF) return 1; zdialog_fetch(zd,"red",red); // get color adjustments zdialog_fetch(zd,"green",green); zdialog_fetch(zd,"blue",blue); zdialog_fetch(zd,"bright",bright); // brightness adjustment bright2 = (red + green + blue) / 3; // RGB brightness bright = bright / bright2; // bright setpoint / RGB brightness red = red * bright; // adjust RGB brightness green = green * bright; blue = blue * bright; bright = (red + green + blue) / 3; zdialog_stuff(zd,"red",red); // force back into consistency zdialog_stuff(zd,"green",green); zdialog_stuff(zd,"blue",blue); zdialog_stuff(zd,"bright",bright); if (strEqu(event,"brapp")) // apply color & brightness changes { red = red / 100; // normalize 0.5 ... 2.0 green = green / 100; blue = blue / 100; cim_warp_image_pano(im0,0); // refresh cimPXMw from cimPXMs ww = cimPXMw[im0]->ww; hh = cimPXMw[im0]->hh; for (py = 0; py < hh; py++) // loop all image pixels for (px = 0; px < ww; px++) { pixel = PXMpix(cimPXMw[im0],px,py); red1 = red * pixel[0]; // apply color factors green1 = green * pixel[1]; blue1 = blue * pixel[2]; if (! blue1) continue; if (red1 > 65535 || green1 > 65535 || blue1 > 65535) { bright = red1; // avoid overflow if (green1 > bright) bright = green1; if (blue1 > bright) bright = blue1; bright = 65535.0 / bright; red1 = red1 * bright; green1 = green1 * bright; blue1 = blue1 * bright; } if (blue1 < 1) blue1 = 1; // avoid 0 v.10.7 pixel[0] = red1; pixel[1] = green1; pixel[2] = blue1; } cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); // v.11.04 cim_show_images(0,0); // combine and show with 50/50 blend } if (strEqu(event,"auto")) // auto match color of selected image { for (im1 = im0; im1 < cimNF-1; im1++) // from selected image to last image { im2 = im1 + 1; cimBlend = 0.3 * cimPXMw[im2]->ww; cim_get_overlap(im1,im2,cimPXMw); // match images in overlap area cim_match_colors(im1,im2,cimPXMw); cim_adjust_colors(cimPXMw[im1],1); // image im1 << profile 1 cim_adjust_colors(cimPXMw[im2],2); // image im2 << profile 2 for (imx = im1-1; imx >= im0; imx--) cim_adjust_colors(cimPXMw[imx],1); cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); // v.11.04 cim_show_images(0,0); } for (im1 = im0-1; im1 >= 0; im1--) // from selected image to 1st image { im2 = im1 + 1; cimBlend = 0.3 * cimPXMw[im2]->ww; cim_get_overlap(im1,im2,cimPXMw); // match images in overlap area cim_match_colors(im1,im2,cimPXMw); cim_adjust_colors(cimPXMw[im1],1); // image im1 << profile 1 cim_adjust_colors(cimPXMw[im2],2); // image im2 << profile 2 for (imx = im2+1; imx < cimNF; imx++) cim_adjust_colors(cimPXMw[imx],2); cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); // v.11.04 cim_show_images(0,0); } } if (strEqu(event,"file")) // use original file colors { if (! cim_load_files()) return 1; for (imx = 0; imx < cimNF; imx++) { PXM_free(cimPXMs[imx]); cimPXMs[imx] = PXM_copy(cimPXMf[imx]); cim_curve_image(imx); // curve and warp cim_warp_image_pano(imx,0); } cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); // v.11.04 cim_show_images(0,0); } if (strEqu(event,"blapp")) // apply new blend width { zdialog_fetch(zd,"blend",cimBlend); // can be zero cim_show_images(0,1); // show with gradual blend } return 1; } /************************************************************************** Vertical Panorama function: join 2, 3, or 4 images. ***************************************************************************/ void vpano_prealign(); // manual pre-align void vpano_align(); // auto fine-align void vpano_tweak(); // user color tweak editfunc EFvpano; // edit function data // menu function void m_vpano(GtkWidget *, cchar *) // v.11.04 { int imx, err; char **flist = 0; zfuncs::F1_help_topic = "panorama"; // help topic if (mod_keep()) return; // warn unsaved changes if (! menulock(1)) return; // test menu lock v.11.07 menulock(0); for (imx = 0; imx < 10; imx++) { // clear all file and PXM data cimFile[imx] = 0; cimPXMf[imx] = cimPXMs[imx] = cimPXMw[imx] = 0; } cimNF = 0; flist = zgetfileN(ZTX("Select 2 to 4 files"),"openN",curr_file); // select images to combine if (! flist) return; for (imx = 0; flist[imx]; imx++); // count selected files if (imx < 2 || imx > 4) { zmessageACK(mWin,ZTX("Select 2 to 4 files")); goto cleanup; } cimNF = imx; // file count for (imx = 0; imx < cimNF; imx++) cimFile[imx] = strdupz(flist[imx],0,"pano"); // set up file list if (! cim_load_files()) goto cleanup; // load and check all files free_resources(); // ready to commit err = f_open(cimFile[0],0); // curr_file = 1st file in list if (err) goto cleanup; EFvpano.funcname = "vpano"; if (! edit_setup(EFvpano)) goto cleanup; // setup edit (will lock) cimShowAll = 1; // for cim_show_images(), show all cimShrink = 0; // no warp shrinkage v.11.04 cimPano = 0; // vertical pano mode v.11.04 cimPanoV = 1; vpano_prealign(); // manual pre-alignment if (panStat != 1) goto cancel; vpano_align(); // auto full alignment if (panStat != 1) goto cancel; vpano_tweak(); // manual color adjustment if (panStat != 1) goto cancel; CEF->Fmod = 1; // done edit_done(EFvpano); goto cleanup; cancel: // failed or canceled edit_cancel(EFvpano); cleanup: if (flist) { for (imx = 0; flist[imx]; imx++) // free file list zfree(flist[imx]); zfree(flist); } for (imx = 0; imx < cimNF; imx++) { // free cim file and PXM data if (cimFile[imx]) zfree(cimFile[imx]); if (cimPXMf[imx]) PXM_free(cimPXMf[imx]); if (cimPXMs[imx]) PXM_free(cimPXMs[imx]); if (cimPXMw[imx]) PXM_free(cimPXMw[imx]); } *SB_text = 0; return; } // perform manual pre-align of all images // returns alignment data in cimOffs[*] // lens_mm and lens_bow may also be altered void vpano_prealign() { int vpano_prealign_event(zdialog *zd, cchar *event); // dialog event function void * vpano_prealign_thread(void *); // working thread int imx, hh, err = 0; cchar *exifkey = { exif_focal_length_key }; cchar *lensource; char **pp = 0; cchar *align_mess = ZTX("Drag images into rough alignment.\n" "To rotate, drag from right edge."); lens_bow = lens_settings[1]; // no EXIF for this pp = info_get(curr_file,&exifkey,1); // get lens mm from EXIF if available if (pp && *pp) { err = convSD(*pp, lens_mm, 20, 1000); lensource = "(EXIF)"; // lens mm from EXIF } if (! pp || ! *pp || err) { // not available lens_mm = lens_settings[0]; lensource = "(settings)"; // lens mm from user settings } for (imx = 0; imx < 10; imx++) // set all alignment offsets = 0 memset(&cimOffs[imx],0,sizeof(cimoffs)); for (imx = hh = 0; imx < cimNF; imx++) // sum image heights hh += cimPXMf[imx]->hh; cimScale = 1.4 * panPreAlignSize / hh; // set alignment image scale if (cimScale > 1.0) cimScale = 1.0; // (* 0.7 after overlaps) for (imx = 0; imx < cimNF; imx++) // scale images > cimPXMs[*] cim_scale_image(imx,cimPXMs); for (imx = 0; imx < cimNF; imx++) { // curve images, cimPXMs[*] replaced cim_curve_Vimage(imx); cimPXMw[imx] = PXM_copy(cimPXMs[imx]); // copy to cimPXMw[*] for display } cimOffs[0].xf = cimOffs[0].yf = 0; // first image at (0,0) for (imx = 1; imx < cimNF; imx++) // position images with 30% overlap { // in vertical row cimOffs[imx].yf = cimOffs[imx-1].yf + 0.7 * cimPXMw[imx-1]->hh; cimOffs[imx].xf = cimOffs[imx-1].xf; } Fzoom = 0; // scale image to fit window Fblowup = 1; // magnify small image to window size cimBlend = panPreAlignBlend * cimPXMw[1]->hh; // overlap in align window cim_show_Vimages(1,0); // combine and show images in main window panozd = zdialog_new(ZTX("Pre-align Images"),mWin,Bproceed,Bcancel,null); // start pre-align dialog zdialog_add_widget(panozd,"label","lab1","dialog",align_mess,"space=5"); zdialog_add_widget(panozd,"hbox","hb1","dialog",0,"space=2"); zdialog_add_widget(panozd,"spin","spmm","hb1","20|999|0.1|35","space=5"); // [ 35 ] lens mm (source) zdialog_add_widget(panozd,"label","labmm","hb1",ZTX("lens mm")); // [ 0.3 ] lens bow zdialog_add_widget(panozd,"label","labsorc","hb1","","space=5"); // [resize] resize window zdialog_add_widget(panozd,"hbox","hb2","dialog",0,"space=2"); zdialog_add_widget(panozd,"spin","spbow","hb2","-9|9|0.01|0","space=5"); zdialog_add_widget(panozd,"label","labbow","hb2",ZTX("lens bow")); zdialog_add_widget(panozd,"hbox","hb3","dialog",0,"space=2"); zdialog_add_widget(panozd,"button","resize","hb3",ZTX("Resize"),"space=5"); zdialog_add_widget(panozd,"label","labsiz","hb3",ZTX("resize window"),"space=5"); zdialog_stuff(panozd,"spmm",lens_mm); // stuff lens data zdialog_stuff(panozd,"spbow",lens_bow); zdialog_stuff(panozd,"labsorc",lensource); // show source of lens data panStat = -1; // busy status gdk_window_set_cursor(drWin->window,dragcursor); // set drag cursor zdialog_run(panozd,vpano_prealign_event,"-10/20"); // start dialog v.11.07 start_thread(vpano_prealign_thread,0); // start working thread zdialog_wait(panozd); // wait for dialog completion gdk_window_set_cursor(drWin->window,0); // restore normal cursor Fzoom = Fblowup = 0; return; } // pre-align dialog event function int vpano_prealign_event(zdialog *zd, cchar *event) { int imx; double overlap; if (strstr("spmm spbow",event)) { zdialog_fetch(zd,"spmm",lens_mm); // get revised lens data zdialog_fetch(zd,"spbow",lens_bow); } if (strEqu(event,"resize")) // allocate new E3 image cim_show_Vimages(1,0); if (zd->zstat) // dialog complete { if (zd->zstat == 1) // proceed panStat = 1; else // cancel or other panStat = 0; zdialog_free(panozd); // kill dialog wrapup_thread(0); // wait for thread if (! panStat) return 0; // canceled for (imx = 0; imx < cimNF-1; imx++) // check for enough overlap { overlap = cim_get_overlap(imx,imx+1,cimPXMs); // v.11.04 if (overlap < panFinalBlend) { // v.11.09 zmessageACK(mWin,ZTX("Too little overlap, cannot align")); panStat = 0; return 0; } } } return 0; } // pre-align working thread // convert mouse and KB events into image movements // overhauled void * vpano_prealign_thread(void *) { cimoffs offstemp; PXM *pxmtemp; char *ftemp; int im1, im2, imm, imx; int mx0, my0, mx, my; // mouse drag origin, position int xoff, yoff, loy, hiy; int sepy, minsep; int ww, hh, rotate, midy; double lens_mm0, lens_bow0; double dx, dy, t1, t2, dt; imm = ww = hh = rotate = xoff = yoff = 0; // stop compiler warnings lens_mm0 = lens_mm; // to detect changes lens_bow0 = lens_bow; mx0 = my0 = 0; // no drag in progress Mcapture = KBcapture = 1; // capture mouse drag and KB keys cimBlend = 0; // full blend during pre-align while (true) // loop and align until done { zsleep(0.05); // logic simplified if (panStat != -1) break; // quit signal from dialog if (lens_mm != lens_mm0 || lens_bow != lens_bow0) { // change in lens parameters lens_mm0 = lens_mm; lens_bow0 = lens_bow; for (imx = 0; imx < cimNF; imx++) { // re-curve images cim_scale_image(imx,cimPXMs); cim_curve_Vimage(imx); PXM_free(cimPXMw[imx]); cimPXMw[imx] = PXM_copy(cimPXMs[imx]); } cim_show_Vimages(1,0); // combine and show images continue; } if (KBkey) { // KB input if (KBkey == GDK_Left) cimOffs[imm].xf -= 0.5; // tweak alignment offsets if (KBkey == GDK_Right) cimOffs[imm].xf += 0.5; if (KBkey == GDK_Up) cimOffs[imm].yf -= 0.5; if (KBkey == GDK_Down) cimOffs[imm].yf += 0.5; if (KBkey == GDK_r) cimOffs[imm].tf += 0.0005; if (KBkey == GDK_l) cimOffs[imm].tf -= 0.0005; KBkey = 0; cim_show_Vimages(0,0); // combine and show images continue; } if (! Mxdrag && ! Mydrag) // no drag underway mx0 = my0 = 0; // reset drag origin if (Mxdrag || Mydrag) // mouse drag underway { mx = Mxdrag; // mouse position in image my = Mydrag; if (! mx0 && ! my0) // new drag { mx0 = mx; // set drag origin my0 = my; minsep = 9999; for (imx = 0; imx < cimNF; imx++) // find image with midpoint { // closest to mouse y loy = cimOffs[imx].yf; hiy = loy + cimPXMw[imx]->hh; midy = (loy + hiy) / 2; sepy = abs(midy - my0); if (sepy < minsep) { minsep = sepy; imm = imx; // image to drag or rotate } } xoff = cimOffs[imm].xf; yoff = cimOffs[imm].yf; ww = cimPXMw[imm]->ww; hh = cimPXMw[imm]->hh; rotate = 0; // if drag at right edge, if (mx0 > xoff + 0.85 * ww) rotate = 1; // set rotate flag } if (mx != mx0 || my != my0) // drag is progressing { dx = mx - mx0; // mouse movement dy = my - my0; if (rotate && my0 > yoff && my > yoff) // rotation { if (imm > 0) { loy = cimOffs[imm].yf; // if there is an image above, hiy = cimOffs[imm-1].yf + cimPXMw[imm-1]->hh; // midy = midpoint of overlap midy = (loy + hiy) / 2; } else midy = 0; // this is the topmist image t1 = atan(1.0 * (my0-yoff) / (mx0-xoff)); t2 = atan(1.0 * (my-yoff) / (mx-xoff)); dt = t2 - t1; // angle change dy = - dt * ww / 2; // pivot = middle of overlap above dx = dt * (midy-yoff); } else dt = 0; // x/y drag cimOffs[imm].xf += dx; // update image cimOffs[imm].yf += dy; cimOffs[imm].tf += dt; xoff = cimOffs[imm].xf; // v.11.04 yoff = cimOffs[imm].yf; cim_show_Vimages(0,0); // show combined images mx0 = mx; // next drag origin = current mouse my0 = my; } } for (im1 = 0; im1 < cimNF-1; im1++) // track image order changes { im2 = im1 + 1; if (cimOffs[im2].yf < cimOffs[im1].yf) { ftemp = cimFile[im2]; // switch filespecs cimFile[im2] = cimFile[im1]; cimFile[im1] = ftemp; pxmtemp = cimPXMf[im2]; // switch images cimPXMf[im2] = cimPXMf[im1]; cimPXMf[im1] = pxmtemp; pxmtemp = cimPXMs[im2]; // scaled images cimPXMs[im2] = cimPXMs[im1]; cimPXMs[im1] = pxmtemp; pxmtemp = cimPXMw[im2]; // warped images cimPXMw[im2] = cimPXMw[im1]; cimPXMw[im1] = pxmtemp; offstemp = cimOffs[im2]; // offsets cimOffs[im2] = cimOffs[im1]; cimOffs[im1] = offstemp; if (imm == im1) imm = im2; // current drag image else if (imm == im2) imm = im1; break; } } } KBcapture = Mcapture = 0; thread_exit(); return 0; // not executed, stop g++ warning } // fine-alignment // start with very small image size // search around offset values for best match // increase image size and loop until full-size void vpano_align() { int imx, im1, im2, ww, hh; double R, dx, dy, dt; double overlap; cimoffs offsets0; Fzoom = 0; // scale E3 to fit window Fblowup = 1; // magnify small image to window size Ffuncbusy++; for (imx = 0; imx < cimNF; imx++) { cimOffs[imx].xf = cimOffs[imx].xf / cimScale; // scale x/y offsets for full-size images cimOffs[imx].yf = cimOffs[imx].yf / cimScale; } cimScale = 1.0; // full-size for (imx = 0; imx < cimNF; imx++) { PXM_free(cimPXMs[imx]); cimPXMs[imx] = PXM_copy(cimPXMf[imx]); // copy full-size images cim_curve_Vimage(imx); // curve them } cimBlend = 0.3 * cimPXMs[0]->hh; cim_get_overlap(0,1,cimPXMs); // match images 0 & 1 in overlap area cim_match_colors(0,1,cimPXMs); cim_adjust_colors(cimPXMf[0],1); // image 0 << profile 1 cim_adjust_colors(cimPXMf[1],2); // image 1 << profile 2 if (cimNF > 2) { cimBlend = 0.3 * cimPXMs[1]->hh; cim_get_overlap(1,2,cimPXMs); cim_match_colors(1,2,cimPXMs); cim_adjust_colors(cimPXMf[0],1); cim_adjust_colors(cimPXMf[1],1); cim_adjust_colors(cimPXMf[2],2); } if (cimNF > 3) { cimBlend = 0.3 * cimPXMs[2]->hh; cim_get_overlap(2,3,cimPXMs); cim_match_colors(2,3,cimPXMs); cim_adjust_colors(cimPXMf[0],1); cim_adjust_colors(cimPXMf[1],1); cim_adjust_colors(cimPXMf[2],1); cim_adjust_colors(cimPXMf[3],2); } cimScale = panInitAlignSize / cimPXMf[1]->hh; // initial align image scale if (cimScale > 1.0) cimScale = 1.0; for (imx = 0; imx < cimNF; imx++) { // scale offsets for image scale cimOffs[imx].xf = cimOffs[imx].xf * cimScale; cimOffs[imx].yf = cimOffs[imx].yf * cimScale; } cimSearchRange = panInitSearchRange; // initial align search range cimSearchStep = panInitSearchStep; // initial align search step cimWarpRange = panInitWarpRange; // initial align corner warp range cimWarpStep = panInitWarpStep; // initial align corner warp step hh = cimPXMf[0]->hh * cimScale; // initial align image width cimBlend = hh * panInitBlend; // initial align blend width cimSampSize = panSampSize; // pixel sample size for align/compare cimNsearch = 0; // reset align search counter while (true) // loop, increasing image size { for (imx = 0; imx < cimNF; imx++) { // prepare images cim_scale_image(imx,cimPXMs); // scale to new size cim_curve_Vimage(imx); // curve based on lens params cim_warp_image_Vpano(imx,1); // apply corner warps } cim_show_Vimages(1,0); // show with 50/50 blend in overlaps for (im1 = 0; im1 < cimNF-1; im1++) // fine-align each image with top neighbor { im2 = im1 + 1; offsets0 = cimOffs[im2]; // save initial alignment offsets overlap = cim_get_overlap(im1,im2,cimPXMs); // get overlap area v.11.04 if (overlap < panFinalBlend-2) { zmessageACK(mWin,ZTX("Too little overlap, cannot align")); goto fail; } cim_get_redpix(im1); // get high-contrast pixels cim_align_image(im1,im2); // search for best offsets and warps zfree(cimRedpix); // clear red pixels cimRedpix = 0; dx = cimOffs[im2].xf - offsets0.xf; // changes from initial offsets dy = cimOffs[im2].yf - offsets0.yf; dt = cimOffs[im2].tf - offsets0.tf; for (imx = im2+1; imx < cimNF; imx++) // propagate to following images { cimOffs[imx].xf += dx; cimOffs[imx].yf += dy; cimOffs[imx].tf += dt; ww = cimOffs[imx].xf - cimOffs[im2].xf; cimOffs[imx].yf += ww * dt; } } if (cimScale == 1.0) goto success; // done R = panImageIncrease; // next larger image size cimScale = cimScale * R; if (cimScale > 0.85) { // if close to end, jump to end R = R / cimScale; cimScale = 1.0; } for (imx = 0; imx < cimNF; imx++) // scale offsets for new size { cimOffs[imx].xf *= R; cimOffs[imx].yf *= R; for (int ii = 0; ii < 4; ii++) { cimOffs[imx].wx[ii] *= R; cimOffs[imx].wy[ii] *= R; } } cimSearchRange = panSearchRange; // align search range cimSearchStep = panSearchStep; // align search step size cimWarpRange = panWarpRange; // align corner warp range cimWarpStep = panWarpStep; // align corner warp step size cimBlend = cimBlend * panBlendDecrease * R; // blend width, reduced hh = cimPXMf[0]->hh * cimScale; if (cimBlend < panFinalBlend * hh) cimBlend = panFinalBlend * hh; // stay above minimum } success: panStat = 1; goto align_done; fail: panStat = 0; align_done: Fzoom = Fblowup = 0; Ffuncbusy--; cimBlend = 1; // tiny blend (increase in tweak if wanted) cim_show_Vimages(0,0); return; } // get user inputs for RGB changes and blend width, update cimPXMw[*] void vpano_tweak() { int vpano_tweak_event(zdialog *zd, cchar *event); // dialog event function cchar *tweaktitle = ZTX("Match Brightness and Color"); char imageN[8] = "imageN"; int imx; cimBlend = 1; // init. blend width panozd = zdialog_new(tweaktitle,mWin,Bdone,Bcancel,null); zdialog_add_widget(panozd,"hbox","hbim","dialog",0,"space=5"); zdialog_add_widget(panozd,"label","labim","hbim",ZTX("image"),"space=5"); // image (o) (o) (o) (o) zdialog_add_widget(panozd,"hbox","hbc1","dialog",0,"homog"); // zdialog_add_widget(panozd,"label","labred","hbc1",Bred); // red green blue zdialog_add_widget(panozd,"label","labgreen","hbc1",Bgreen); // [_____] [_____] [_____] zdialog_add_widget(panozd,"label","labblue","hbc1",Bblue); // zdialog_add_widget(panozd,"hbox","hbc2","dialog",0,"homog"); // brightness [___] [apply] zdialog_add_widget(panozd,"spin","red","hbc2","50|200|0.1|100","space=5"); // zdialog_add_widget(panozd,"spin","green","hbc2","50|200|0.1|100","space=5"); // -------------------------- zdialog_add_widget(panozd,"spin","blue","hbc2","50|200|0.1|100","space=5"); // zdialog_add_widget(panozd,"hbox","hbbri","dialog",0,"space=5"); // [auto color] [file color] zdialog_add_widget(panozd,"label","labbr","hbbri",Bbrightness,"space=5"); // zdialog_add_widget(panozd,"spin","bright","hbbri","50|200|0.1|100"); // -------------------------- zdialog_add_widget(panozd,"button","brapp","hbbri",Bapply,"space=10"); // zdialog_add_widget(panozd,"hsep","hsep","dialog",0,"space=5"); // blend width [___] [apply] zdialog_add_widget(panozd,"hbox","hbc3","dialog",0,"space=5"); // zdialog_add_widget(panozd,"button","auto","hbc3",ZTX("auto color"),"space=5"); // [done] [cancel] zdialog_add_widget(panozd,"button","file","hbc3",ZTX("file color"),"space=5"); zdialog_add_widget(panozd,"hsep","hsep","dialog",0,"space=5"); zdialog_add_widget(panozd,"hbox","hbblen","dialog",0); zdialog_add_widget(panozd,"label","labbl","hbblen",Bblendwidth,"space=5"); zdialog_add_widget(panozd,"spin","blend","hbblen","1|300|1|1"); zdialog_add_widget(panozd,"button","blapp","hbblen",Bapply,"space=15"); for (imx = 0; imx < cimNF; imx++) { // add radio button per image imageN[5] = '0' + imx; zdialog_add_widget(panozd,"radio",imageN,"hbim",0,"space=5"); } zdialog_stuff(panozd,"image0",1); // pre-select 1st image zdialog_resize(panozd,300,0); panStat = -1; // busy status zdialog_run(panozd,vpano_tweak_event,"-10/20"); // run dialog, parallel v.11.07 zdialog_wait(panozd); // wait for dialog completion return; } // dialog event function int vpano_tweak_event(zdialog *zd, cchar *event) { char imageN[8] = "imageN"; double red, green, blue, bright, bright2; double red1, green1, blue1; int nn, im0, imx, im1, im2, ww, hh, px, py; uint16 *pixel; if (zd->zstat) // dialog complete { if (zd->zstat == 1) panStat = 1; // done if (zd->zstat == 2) panStat = 0; // cancel zdialog_free(panozd); // kill dialog return 0; } for (im0 = 0; im0 < cimNF; im0++) { // get which image is selected imageN[5] = '0' + im0; // by the radio buttons zdialog_fetch(zd,imageN,nn); if (nn) break; } if (im0 == cimNF) return 1; zdialog_fetch(zd,"red",red); // get color adjustments zdialog_fetch(zd,"green",green); zdialog_fetch(zd,"blue",blue); zdialog_fetch(zd,"bright",bright); // brightness adjustment bright2 = (red + green + blue) / 3; // RGB brightness bright = bright / bright2; // bright setpoint / RGB brightness red = red * bright; // adjust RGB brightness green = green * bright; blue = blue * bright; bright = (red + green + blue) / 3; zdialog_stuff(zd,"red",red); // force back into consistency zdialog_stuff(zd,"green",green); zdialog_stuff(zd,"blue",blue); zdialog_stuff(zd,"bright",bright); if (strEqu(event,"brapp")) // apply color & brightness changes { red = red / 100; // normalize 0.5 ... 2.0 green = green / 100; blue = blue / 100; cim_warp_image_Vpano(im0,0); // refresh cimPXMw from cimPXMs ww = cimPXMw[im0]->ww; hh = cimPXMw[im0]->hh; for (py = 0; py < hh; py++) // loop all image pixels for (px = 0; px < ww; px++) { pixel = PXMpix(cimPXMw[im0],px,py); red1 = red * pixel[0]; // apply color factors green1 = green * pixel[1]; blue1 = blue * pixel[2]; if (! blue1) continue; if (red1 > 65535 || green1 > 65535 || blue1 > 65535) { bright = red1; // avoid overflow if (green1 > bright) bright = green1; if (blue1 > bright) bright = blue1; bright = 65535.0 / bright; red1 = red1 * bright; green1 = green1 * bright; blue1 = blue1 * bright; } if (blue1 < 1) blue1 = 1; // avoid 0 pixel[0] = red1; pixel[1] = green1; pixel[2] = blue1; } cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); cim_show_Vimages(0,0); // combine and show with 50/50 blend } if (strEqu(event,"auto")) // auto match color of selected image { for (im1 = im0; im1 < cimNF-1; im1++) // from selected image to last image { im2 = im1 + 1; cimBlend = 0.3 * cimPXMw[im2]->hh; cim_get_overlap(im1,im2,cimPXMw); // match images in overlap area cim_match_colors(im1,im2,cimPXMw); cim_adjust_colors(cimPXMw[im1],1); // image im1 << profile 1 cim_adjust_colors(cimPXMw[im2],2); // image im2 << profile 2 for (imx = im1-1; imx >= im0; imx--) cim_adjust_colors(cimPXMw[imx],1); cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); cim_show_Vimages(0,0); } for (im1 = im0-1; im1 >= 0; im1--) // from selected image to 1st image { im2 = im1 + 1; cimBlend = 0.3 * cimPXMw[im2]->hh; cim_get_overlap(im1,im2,cimPXMw); // match images in overlap area cim_match_colors(im1,im2,cimPXMw); cim_adjust_colors(cimPXMw[im1],1); // image im1 << profile 1 cim_adjust_colors(cimPXMw[im2],2); // image im2 << profile 2 for (imx = im2+1; imx < cimNF; imx++) cim_adjust_colors(cimPXMw[imx],2); cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); cim_show_Vimages(0,0); } } if (strEqu(event,"file")) // use original file colors { if (! cim_load_files()) return 1; for (imx = 0; imx < cimNF; imx++) { PXM_free(cimPXMs[imx]); cimPXMs[imx] = PXM_copy(cimPXMf[imx]); cim_curve_Vimage(imx); // curve and warp cim_warp_image_Vpano(imx,0); } cimBlend = 1; zdialog_stuff(zd,"blend",cimBlend); cim_show_Vimages(0,0); } if (strEqu(event,"blapp")) // apply new blend width { zdialog_fetch(zd,"blend",cimBlend); // can be zero cim_show_Vimages(0,1); // show with gradual blend } return 1; } fotoxx-12.01.2/fotoxx-12.01.2.cc0000644000175000017500000061526011701011017014300 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX // disable extern declarations #include "fotoxx.h" char *initial_file = 0; // initial file on command line // fotoxx main program int main(int argc, char *argv[]) { char lang[8] = "", *pp; int err; struct stat statb; int Fclone=0, cloxx=0, cloyy=0, cloww=0, clohh=0; GdkScreen *screen; int Fsyncfiles = 0; int Ftranslate = 0; if (argc > 1 && strEqu(argv[1],"-v")) { printf(fversion "\n"); // print version and exit return 0; } // initialize externals to default values // (saved parameters will override) Ffirsttime = 1; // first time startup v.11.11 maxcolor = 0xffff; for (int ii = 0; ii < 8; ii++) wtnx[ii] = ii; strcpy(jpeg_quality,def_jpeg_quality); mwgeom[0] = mwgeom[1] = 100; // default main window geometry v.11.07 mwgeom[2] = 700; mwgeom[3] = 500; Mscale = 1.0; trimsize[0] = 1600; trimsize[1] = 1000; editresize[0] = 1600; editresize[1] = 1200; batchresize[0] = 1600; batchresize[1] = 1200; emailsize[0] = 1000; emailsize[1] = 800; lens_mm = lens_settings[0] = 35; // pano lens parameters v.12.01 lens_bow = lens_settings[1] = 0; gridcount[0] = gridcount[1] = 5; // set default grid line counts sa_pixRGB = &green; ss_funcs[0] = 1; fsync_lock = "fotoxx_syncfiles"; // file sync lock file v.11.12 tbar_style = "both"; // default toolbar style v.12.01 startdisplay = "blank"; // start with blank window v.12.01 Fwarnoverwrite = 1; // warn original file overwrite v.12.01 // command line args gtk_init(&argc,&argv); // initz. GTK & strip GTK command line params for (int ii = 1; ii < argc; ii++) // command line parameters { pp = argv[ii]; if (strcmpv(pp,"-debug","-d",null)) // -debug Fdebug = 1; else if (strcmpv(pp,"-lang","-l",null) && argc > ii+1) // -lang lc_RC (language/region code) strncpy0(lang,argv[++ii],7); else if (strcmpv(pp,"-clone1","-c1",null)) // -clone1 (clone1/2 not user options) Fclone = 1; else if (strcmpv(pp,"-clone2","-c2",null)) { // -clone2 xpos ypos v.11.07 Fclone = 2; cloxx = atoi(argv[ii+1]); // window position and size cloyy = atoi(argv[ii+2]); // passed from parent instance cloww = atoi(argv[ii+3]); clohh = atoi(argv[ii+4]); ii += 4; } else if (strcmpv(pp,"-slideshow","-ss",null) && argc > ii+1) // -slideshow /image/file.jpg v.11.04 SS_imagefile = strdupz(argv[++ii]); else if (strcmpv(pp,"-music","-m",null) && argc > ii+1) // -music /music/file.ogg v.11.04 SS_musicfile = strdupz(argv[++ii]); else if (strcmpv(pp,"-recent","-r",null)) // recent files gallery v.11.07 Frecent = 1; else if (strcmpv(pp,"-previous","-prev","-p",null)) // open previous file v.11.07 Fprev = 1; else if (strcmpv(pp,"-blank","-b",null)) // start with blank window v.12.01 Fblank = 1; else if (strcmpv(pp,"-syncfiles",null)) { // spawned sync files process v.11.11 Fsyncfiles = 1; pp = argv[++ii]; if (strEqu(pp,"auto")) Fautosync = 1; // set auto or manual sync if (strEqu(pp,"manual")) Fmansync = 1; } else if (strcmpv(pp,"-translate","-t",null)) // start online translation v.11.12 Ftranslate = 1; else initial_file = strdupz(pp); // must be initial file or directory } zinitapp("fotoxx",null); // get app directories ZTXinit(lang); // setup locale and translations // get files in user directory /home//.fotoxx/* *topdirk_file = 0; strncatv(topdirk_file,199,get_zuserdir(),"/top_directory",null); // top_directory *search_index_file = 0; strncatv(search_index_file,199,get_zuserdir(),"/search_index",null); // search_index *tags_defined_file = 0; strncatv(tags_defined_file,199,get_zuserdir(),"/tags_defined",null); // tags_defined *recentfiles_file = 0; strncatv(recentfiles_file,199,get_zuserdir(),"/recent_files",null); // recent_files *saved_areas_dirk = 0; strncatv(saved_areas_dirk,199,get_zuserdir(),"/saved_areas/",null); // saved_areas/ err = stat(saved_areas_dirk,&statb); if (err) mkdir(saved_areas_dirk,0750); *collections_dirk = 0; strncatv(collections_dirk,199,get_zuserdir(),"/collections/",null); // collections/ err = stat(collections_dirk,&statb); if (err) mkdir(collections_dirk,0750); *saved_curves_dirk = 0; strncatv(saved_curves_dirk,199,get_zuserdir(),"/saved_curves/",null); // saved_curves/ err = stat(saved_curves_dirk,&statb); if (err) mkdir(saved_curves_dirk,0750); *annotations_dirk = 0; strncatv(annotations_dirk,199,get_zuserdir(),"/annotations/",null); // annotations/ err = stat(annotations_dirk,&statb); if (err) mkdir(annotations_dirk,0750); load_params(); // restore parameters from last session if (Fsyncfiles) { // this is the spawned sync process v.11.11 gtk_init_add((GtkFunction) syncfiles_func,0); // do the sync function only gtk_main(); return 0; } if (! Fsyncfiles && ! Fclone) { // this is the user GUI process printf("spawn sync files subprocess \n"); err = system("fotoxx -syncfiles auto &"); // spawn process for sync files if (err) { printf("error: %s \n",wstrerror(err)); // quit if failed return 1; } } mWin = gtk_window_new(GTK_WINDOW_TOPLEVEL); // create main window gtk_window_set_title(MWIN,fversion); mVbox = gtk_vbox_new(0,0); // add vert. packing box gtk_container_add(GTK_CONTAINER(mWin),mVbox); mMbar = create_menubar(mVbox); // add menus / sub-menus if (Ftranslate) { // start online translation v.11.12 zfuncs::F1_help_topic = "translate"; ZTX_translation_start(mWin); } GtkWidget *mFile = add_menubar_item(mMbar,ZTX("File"),topmenufunc); add_submenu_item(mFile, ZTX("Image Gallery"), m_gallery); add_submenu_item(mFile, ZTX("Clone 50/50"), m_clone1); add_submenu_item(mFile, ZTX("Clone Overlay"), m_clone2); add_submenu_item(mFile, ZTX("Open Image File"), m_open); add_submenu_item(mFile, ZTX("Open in New Window"), m_open_newin); add_submenu_item(mFile, ZTX("Open Previous File"), m_previous); add_submenu_item(mFile, ZTX("Open Recent File"), m_recent); add_submenu_item(mFile, ZTX("Save to Same File"), m_save); add_submenu_item(mFile, ZTX("Save to New Version"), m_savevers); add_submenu_item(mFile, ZTX("Save to New File"), m_saveas); add_submenu_item(mFile, ZTX("Create Blank Image"), m_create); add_submenu_item(mFile, ZTX("Trash Image File"), m_trash); add_submenu_item(mFile, ZTX("Rename Image File"), m_rename); add_submenu_item(mFile, ZTX("Batch Rename Files"), m_batchrename); add_submenu_item(mFile, ZTX("Print Image File"), m_print); add_submenu_item(mFile, ZTX("Quit fotoxx"), m_quit); GtkWidget *mTools = add_menubar_item(mMbar,ZTX("Tools"),topmenufunc); add_submenu_item(mTools, ZTX("Manage Collections"), m_manage_collections); add_submenu_item(mTools, ZTX("Move Collections"), m_move_collections); add_submenu_item(mTools, ZTX("Batch Convert"), m_batchconvert); add_submenu_item(mTools, ZTX("Convert RAW files"), m_conv_raw); add_submenu_item(mTools, ZTX("Slide Show"), m_slideshow); add_submenu_item(mTools, ZTX("Synchronize Files"), m_syncfiles); add_submenu_item(mTools, ZTX("Show RGB"), m_show_RGB); add_submenu_item(mTools, ZTX("Grid Lines"), m_gridlines); add_submenu_item(mTools, ZTX("Burn Images to CD/DVD"), m_burn); add_submenu_item(mTools, ZTX("E-mail Images"), m_email); add_submenu_item(mTools, ZTX("Check Monitor"), m_moncheck); add_submenu_item(mTools, ZTX("Monitor Gamma"), m_mongamma); add_submenu_item(mTools, ZTX("Brightness Distribution"), m_histogram); add_submenu_item(mTools, ZTX("Change Language"), m_lang); add_submenu_item(mTools, "Edit Translations", m_translate); add_submenu_item(mTools, ZTX("Menu and Launcher"), m_menu_launcher); add_submenu_item(mTools, ZTX("User Settings"), m_settings); add_submenu_item(mTools, ZTX("Memory Usage"), m_memory_usage); GtkWidget *mInfo = add_menubar_item(mMbar,"Info",topmenufunc); add_submenu_item(mInfo, ZTX("Edit Caption/Comments"), m_edit_cctext); add_submenu_item(mInfo, ZTX("Edit Tags"), m_edit_tags); add_submenu_item(mInfo, ZTX("Manage Tags"), m_manage_tags); add_submenu_item(mInfo, ZTX("Batch Add Tags"), m_batchAddTags); add_submenu_item(mInfo, ZTX("Batch Delete Tag"), m_batchDelTag); add_submenu_item(mInfo, ZTX("View Info (short)"), m_info_view_short); add_submenu_item(mInfo, ZTX("View Info (long)"), m_info_view_long); add_submenu_item(mInfo, ZTX("Edit Info"), m_info_edit); add_submenu_item(mInfo, ZTX("Delete Info"), m_info_delete); add_submenu_item(mInfo, ZTX("Search Images"), m_search_images); add_submenu_item(mInfo, ZTX("Search Metadata"), m_search_metadata); GtkWidget *mSelect = add_menubar_item(mMbar,ZTX("Select"),topmenufunc); add_submenu_item(mSelect, ZTX("Select"), m_select); add_submenu_item(mSelect, ZTX("Show"), m_select_show); add_submenu_item(mSelect, ZTX("Hide"), m_select_hide); add_submenu_item(mSelect, ZTX("Enable"), m_select_enable); add_submenu_item(mSelect, ZTX("Disable"), m_select_disable); add_submenu_item(mSelect, ZTX("Invert"), m_select_invert); add_submenu_item(mSelect, ZTX("Unselect"), m_select_unselect); add_submenu_item(mSelect, ZTX("Copy"), m_select_copy); add_submenu_item(mSelect, ZTX("Paste"), m_select_paste); add_submenu_item(mSelect, ZTX("Open"), m_select_open); add_submenu_item(mSelect, ZTX("Save"), m_select_save); add_submenu_item(mSelect, ZTX("Select Whole Image"), m_select_whole_image); add_submenu_item(mSelect, ZTX("Select and Edit"), m_select_edit); GtkWidget *mTransf = add_menubar_item(mMbar,ZTX("Transform"),topmenufunc); add_submenu_item(mTransf, ZTX("Rotate Image"), m_rotate); add_submenu_item(mTransf, ZTX("Trim Image"), m_trim); add_submenu_item(mTransf, ZTX("Auto-Trim Image"), m_autotrim); add_submenu_item(mTransf, ZTX("Resize Image"), m_resize); add_submenu_item(mTransf, ZTX("Annotate Image"), m_annotate); add_submenu_item(mTransf, ZTX("Flip Image"), m_flip); add_submenu_item(mTransf, ZTX("Make Negative"), m_negate); add_submenu_item(mTransf, ZTX("Unbend Image"), m_unbend); add_submenu_item(mTransf, ZTX("Keystone Correction"), m_keystone); add_submenu_item(mTransf, ZTX("Warp Image (area)"), m_warp_area); add_submenu_item(mTransf, ZTX("Warp Image (curved)"), m_warp_curved); add_submenu_item(mTransf, ZTX("Warp Image (linear)"), m_warp_linear); add_submenu_item(mTransf, ZTX("Warp Image (affine)"), m_warp_affine); GtkWidget *mRetouch = add_menubar_item(mMbar,ZTX("Retouch"),topmenufunc); add_submenu_item(mRetouch, ZTX("Brightness/Color"), m_tune); add_submenu_item(mRetouch, ZTX("Gamma Curves"), m_gamma); add_submenu_item(mRetouch, ZTX("Expand Brightness"), m_xbrange); add_submenu_item(mRetouch, ZTX("Flatten Brightness"), m_flatten); add_submenu_item(mRetouch, ZTX("Brightness Ramp"), m_brightramp); add_submenu_item(mRetouch, ZTX("Tone Mapping"), m_tonemap); add_submenu_item(mRetouch, ZTX("White Balance"), m_whitebal); add_submenu_item(mRetouch, ZTX("Match Colors"), m_match_color); add_submenu_item(mRetouch, "DRGB", m_DRGB); add_submenu_item(mRetouch, ZTX("Revise RGB"), m_revise_RGB); add_submenu_item(mRetouch, ZTX("Red Eyes"), m_redeye); add_submenu_item(mRetouch, ZTX("Blur Image"), m_blur); add_submenu_item(mRetouch, ZTX("Sharpen Image"), m_sharpen); add_submenu_item(mRetouch, ZTX("Reduce Noise"), m_denoise); add_submenu_item(mRetouch, ZTX("Smart Erase"), m_smart_erase); add_submenu_item(mRetouch, ZTX("Remove Dust"), m_dust); add_submenu_item(mRetouch, ZTX("Fix Stuck Pixels"), m_stuckpix); add_submenu_item(mRetouch, ZTX("Edit Pixels"), m_pixedit); GtkWidget *mArt = add_menubar_item(mMbar,ZTX("Art"),topmenufunc); add_submenu_item(mArt, ZTX("Color Depth"), m_colordep); add_submenu_item(mArt, ZTX("Drawing"), m_draw); add_submenu_item(mArt, ZTX("Outlines"), m_outlines); add_submenu_item(mArt, ZTX("Embossing"), m_emboss); add_submenu_item(mArt, ZTX("Tiles"), m_tiles); add_submenu_item(mArt, ZTX("Dots"), m_dots); add_submenu_item(mArt, ZTX("Painting"), m_painting); GtkWidget *mComb = add_menubar_item(mMbar,ZTX("Combine"),topmenufunc); add_submenu_item(mComb, ZTX("High Dynamic Range"), m_HDR); add_submenu_item(mComb, ZTX("High Depth of Field"), m_HDF); add_submenu_item(mComb, ZTX("Stack / Paint"), m_STP); add_submenu_item(mComb, ZTX("Stack / Noise"), m_STN); add_submenu_item(mComb, ZTX("Panorama"), m_pano); add_submenu_item(mComb, ZTX("Vertical Panorama"), m_vpano); GtkWidget *mPlugins = add_menubar_item(mMbar,"Plugins",topmenufunc); // build plugin menu v.11.03 add_submenu_item(mPlugins,ZTX("Edit Plugins"),m_edit_plugins); for (int ii = 0; ii < Nplugins; ii++) { pp = strstr(plugins[ii]," = "); if (! pp) continue; *pp = 0; add_submenu_item(mPlugins,plugins[ii],m_run_plugin); *pp = ' '; } GtkWidget *mHelp = add_menubar_item(mMbar,ZTX("Help"),topmenufunc); add_submenu_item(mHelp, ZTX("About"), m_help); add_submenu_item(mHelp, ZTX("User Guide"), m_help); add_submenu_item(mHelp, ZTX("User Guide Changes"), m_help); add_submenu_item(mHelp, ZTX("Edit Functions Summary"), m_help); add_submenu_item(mHelp, ZTX("Change Log"), m_help); add_submenu_item(mHelp, ZTX("Translations"), m_help); add_submenu_item(mHelp, ZTX("Home Page"), m_help); add_submenu_item(mHelp, "README", m_help); mTbar = create_toolbar(mVbox); // toolbar buttons add_toolbar_button(mTbar, ZTX("Gallery"), ZTX("Image Gallery"), "gallery.png", m_gallery); add_toolbar_button(mTbar, ZTX("Open"), ZTX("Open Image File"), "open.png", m_open); add_toolbar_button(mTbar, ZTX("Prev"), ZTX("Open Previous File"), "prev.png", m_prev); add_toolbar_button(mTbar, ZTX("Next"), ZTX("Open Next File"), "next.png", m_next); add_toolbar_button(mTbar, "Zoom+", ZTX("Zoom-in (bigger)"), "zoom+.png", m_zoom); add_toolbar_button(mTbar, "Zoom-", ZTX("Zoom-out (smaller)"), "zoom-.png", m_zoom); add_toolbar_button(mTbar, ZTX("Undo"), ZTX("Undo One Edit"), "undo.png", m_undo); add_toolbar_button(mTbar, ZTX("Redo"), ZTX("Redo One Edit"), "redo.png", m_redo); add_toolbar_button(mTbar, "separator", null, null, null); add_toolbar_button(mTbar, "separator", null, null, null); add_toolbar_button(mTbar, ZTX("Save"), ZTX("Save to Same File"), "save.png", m_save); add_toolbar_button(mTbar, ZTX("Save+V"), ZTX("Save to New Version"), "save+V.png", m_savevers); add_toolbar_button(mTbar, ZTX("Save+F"), ZTX("Save to New File"), "save+F.png", m_saveas); add_toolbar_button(mTbar, ZTX("Trash"), ZTX("Move Image to Trash"), "trash.png", m_trash); add_toolbar_button(mTbar, "separator", null, null, null); add_toolbar_button(mTbar, "separator", null, null, null); add_toolbar_button(mTbar, ZTX("Quit"), ZTX("Quit fotoxx"), "quit.png", m_quit); add_toolbar_button(mTbar, ZTX("Help"), ZTX("Fotoxx Essentials"), "help.png", m_help); if (strEqu(tbar_style,"icons")) // set toolbar style v.12.01 gtk_toolbar_set_style(GTK_TOOLBAR(mTbar),GTK_TOOLBAR_ICONS); else if (strEqu(tbar_style,"text")) gtk_toolbar_set_style(GTK_TOOLBAR(mTbar),GTK_TOOLBAR_TEXT); else gtk_toolbar_set_style(GTK_TOOLBAR(mTbar),GTK_TOOLBAR_BOTH); drWin = gtk_drawing_area_new(); // add drawing window gtk_box_pack_start(GTK_BOX(mVbox),drWin,1,1,0); STbar = create_stbar(mVbox); // add status bar G_SIGNAL(mWin,"delete_event",delete_event,0); // connect signals G_SIGNAL(mWin,"destroy",destroy_event,0); G_SIGNAL(drWin,"expose-event",mwpaint1,0); gtk_widget_add_events(drWin,GDK_BUTTON_PRESS_MASK); // connect mouse events gtk_widget_add_events(drWin,GDK_BUTTON_RELEASE_MASK); gtk_widget_add_events(drWin,GDK_BUTTON_MOTION_MASK); // motion with button pressed gtk_widget_add_events(drWin,GDK_POINTER_MOTION_MASK); // pointer motion gtk_widget_add_events(drWin,GDK_SCROLL_MASK); // scroll wheel v.12.01 G_SIGNAL(drWin,"button-press-event",mouse_event,0); G_SIGNAL(drWin,"button-release-event",mouse_event,0); G_SIGNAL(drWin,"motion-notify-event",mouse_event,0); G_SIGNAL(drWin,"scroll-event",mouse_event,0); G_SIGNAL(mWin,"key-press-event",KBpress,0); // connect KB events G_SIGNAL(mWin,"key-release-event",KBrelease,0); drag_drop_connect(drWin,m_open_drag); // connect drag-drop event gtk_window_move(MWIN,mwgeom[0],mwgeom[1]); // main window geometry gtk_window_set_default_size(MWIN,mwgeom[2],mwgeom[3]); // (defaults or last session params) gtk_widget_show_all(mWin); // show all widgets if (Fclone == 1) { // clone1: left half of desktop screen = gdk_screen_get_default(); cloww = gdk_screen_get_width(screen); clohh = gdk_screen_get_height(screen); cloww = cloww / 2 - 20; clohh = clohh - 50; gtk_window_move(MWIN,10,10); // v.11.07 gtk_window_resize(MWIN,cloww,clohh); } if (Fclone == 2) { // clone2: open new window v.11.07 gtk_window_move(MWIN,cloxx+20,cloyy+30); // slightly offset from old window gtk_window_resize(MWIN,cloww,clohh); } gdkgc = gdk_gc_new(drWin->window); // initz. graphics context black.red = black.green = black.blue = 0; // set up colors white.red = white.green = white.blue = maxcolor; lgray.red = lgray.green = lgray.blue = 0.9 * maxcolor; dgray.red = dgray.green = dgray.blue = 0.5 * maxcolor; red.red = maxcolor; red.green = red.blue = 0; green.green = maxcolor; green.red = green.blue = 0; colormap = gtk_widget_get_colormap(drWin); gdk_rgb_find_color(colormap,&black); gdk_rgb_find_color(colormap,&white); gdk_rgb_find_color(colormap,&lgray); gdk_rgb_find_color(colormap,&dgray); gdk_rgb_find_color(colormap,&red); gdk_rgb_find_color(colormap,&green); gdk_gc_set_foreground(gdkgc,&black); gdk_gc_set_background(gdkgc,&lgray); gdk_window_set_background(drWin->window,&lgray); // v.11.01 fg_color = black; gdk_gc_set_line_attributes(gdkgc,1,LINEATTRIBUTES); arrowcursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW); // cursor for selection dragcursor = gdk_cursor_new(GDK_CROSSHAIR); // cursor for dragging drawcursor = gdk_cursor_new(GDK_PENCIL); // cursor for drawing lines gtk_init_add((GtkFunction) gtkinitfunc,0); // set initz. call from gtk_main() gtk_main(); // start processing window events return 0; } /**************************************************************************/ // initial function called from gtk_main() at startup int gtkinitfunc(void *data) { int err, flag, npid; int ftype, fdirk = 0; char procfile[20], *ppv; cchar *pp, *pp2; struct stat statb; menulock(1); // block menus until initz. done v.11.04 snprintf(PIDstring,11,"%06d",getpid()); // get process PID 6-digits v.11.12 printf(fversion "\n"); // print Fotoxx version printf("install location: %s \n",get_zprefix()); // install location printf("last Fotoxx session: %s \n",last_session); // last session exit time printf("top image directory: %s \n",topdirk); if (Ffirsttime) { // first time startup v.11.11 printf("%s \n",ZTX("first time startup")); zmessageACK(mWin,"User Guide is available in Help menu"); // inform user of user guide Ffirsttime = 0; save_params(); } Nwt = sysconf(_SC_NPROCESSORS_ONLN); // get SMP CPU count if (Nwt <= 0) Nwt = 1; if (Nwt > max_threads) Nwt = max_threads; // compile time limit printf("using %d threads \n",Nwt); err = system("which exiftool"); // check for exiftool v.11.05 if (! err) Fexiftool = 1; err = system("which xdg-open"); // check for xdg-open if (! err) Fxdgopen = 1; err = system("which ufraw-batch"); // check for ufraw-batch if (! err) Fufraw = 1; undo_files = zmalloc(200); *undo_files = 0; // look for orphaned undo files strncatv(undo_files,199,get_zuserdir(),"/*_undo_*",null); // /home/user/.fotoxx/*_undo_* flag = 1; while ((pp = SearchWild(undo_files,flag))) { pp2 = strstr(pp,".fotoxx/"); if (! pp2) continue; npid = atoi(pp2+8); // pid of file owner snprintf(procfile,19,"/proc/%d",npid); err = stat(procfile,&statb); if (! err) continue; // pid is active, keep file printf("orphaned undo file deleted: %s \n",pp); err = remove(pp); // delete file v.11.03 } *undo_files = 0; // setup undo filespec template strncatv(undo_files,199,get_zuserdir(),"/",PIDstring,"_undo_nn",null); // /home/user/.fotoxx/pppppp_undo_nn editlog = pvlist_create(maxedits); // history log of image edits done for (int ii = 0; ii < maxedits; ii++) // pre-load all pvlist entries v.10.2 pvlist_append(editlog,"nothing"); mutex_init(&Fpixmap_lock,0); // setup lock for edit pixmaps zdialog_positions("load"); // load saved dialog positions v.11.07 // set up current file and directory from saved parameters or command line if (topdirk) curr_dirk = strdupz(topdirk); // use top directory if defined v.11.07 else { ppv = getcwd(command,ccc); // or use current directory v.11.09 if (ppv) curr_dirk = strdupz(ppv); } if (initial_file) { // from command line or previous session ppv = realpath(initial_file,0); // prepend directory if needed if (ppv) { zfree(initial_file); initial_file = strdupz(ppv); free(ppv); } else { printf("invalid file: %s \n",initial_file); // invalid file path zfree(initial_file); initial_file = 0; } } if (initial_file) { ftype = image_file_type(initial_file); if (ftype == 0) { // non-existent file printf("invalid file: %s \n",initial_file); zfree(initial_file); initial_file = 0; } else if (ftype == 1) { // is a directory if (curr_dirk) zfree(curr_dirk); curr_dirk = initial_file; initial_file = 0; fdirk = 1; } else if (ftype == 2) { // supported image file type if (curr_dirk) zfree(curr_dirk); curr_dirk = strdupz(initial_file); // set current directory from file ppv = strrchr(curr_dirk,'/'); if (ppv) *ppv = 0; } else { printf("unsupported file type: %s \n",initial_file); // unsupported file type zfree(initial_file); initial_file = 0; } } if (curr_dirk) err = chdir(curr_dirk); // set current directory menulock(0); // enable menus v.11.04 g_timeout_add(200,gtimefunc,0); // start periodic function (200 ms) v.11.06 if (SS_imagefile) { // start slide show if wanted v.11.04 f_open(SS_imagefile,1); if (SS_musicfile) { sprintf(command,"xdg-open \"%s\" ",SS_musicfile); // start music if wanted printf("command: %s \n",command); err = system(command); } m_slideshow(0,0); return 0; } if (initial_file) // open initial file f_open(initial_file,1); else if (fdirk) { // open gallery for initial directory image_navi::thumbsize = 128; m_gallery(0,0); // v.11.08 } else if (Fprev) // start with previous file v.11.08 m_previous(0,0); else if (Frecent) { image_navi::thumbsize = 180; // start with gallery of recent files m_recent(0,0); // v.11.07 } else if (Fblank) return 0; // start with blank window v.12.01 else if (strEqu(startdisplay,"recent")) { image_navi::thumbsize = 180; // start with gallery of recent files m_recent(0,0); // v.11.07 } else if (strEqu(startdisplay,"prev")) { // from user settings v.12.01 m_previous(0,0); } else if (strEqu(startdisplay,"dirk")) { // v.12.01 if (! startdirk || *startdirk != '/') return 0; if (curr_dirk) zfree(curr_dirk); curr_dirk = strdupz(startdirk); err = chdir(curr_dirk); image_navi::thumbsize = 128; m_gallery(0,0); } else if (strEqu(startdisplay,"file")) { // v.12.01 f_open(startfile,1); } return 0; // start with blank window } /**************************************************************************/ // Periodic function // Avoid any thread usage of gtk/gdk functions. int gtimefunc(void *arg) { static zdialog *zdmessage = 0; int syncfd; if (Wrepaint) { // window update needed Wrepaint = 0; mwpaint1(); } update_statusbar(); // update every cycle v.11.03 if (Fslideshow) slideshow_next("timer"); // show next image if time is up if (Ffuncbusy) paint_text(Dww/2-50,Dhh-20,"BUSY","monospace 10"); // write BUSY on window v.11.07 if (threadmessage && ! zdmessage) // display message for thread process zdmessage = zmessage_post(mWin,0,threadmessage); // (avoid use of GTK in threads) v.11.03 if (zdmessage && ! threadmessage) // message terminated by thread zdialog_free(zdmessage); if (zdmessage && zdmessage->sentinel != zdsentinel) { // popup window closed by user zdmessage = 0; threadmessage = 0; } syncfd = global_lock(fsync_lock); // check for sync files process if (syncfd >= 0) { // not busy global_unlock(syncfd); if (Fsyncbusy) threadmessage = 0; // it was busy, now done v.11.11 Fsyncbusy = 0; } else Fsyncbusy = 1; // sync files still busy return 1; } /**************************************************************************/ // update status bar with image data and status // called from timer function void update_statusbar() { static double time1 = 0, time2, cpu1 = 0, cpu2, cpuload; char text1[300], text2[100]; int ww, hh, scale, bpc, done; double file_MB = 1.0 / mega * curr_file_size; *text1 = *text2 = 0; time2 = get_seconds(); // compute process cpu load if (time2 - time1 > 1.0) { // at 1 second intervals cpu2 = jobtime(); // v.11.09 cpuload = 100.0 * (cpu2 - cpu1) / (time2 - time1); time1 = time2; cpu1 = cpu2; } sprintf(text1,"CPU %03.0f%c",cpuload,'%'); // CPU 023% if (curr_file) // v.11.04 { if (E3pxm16) { ww = E3ww; hh = E3hh; bpc = 16; } else if (Fpxm16) { ww = Fww; hh = Fhh; bpc = 16; } else { ww = Fww; hh = Fhh; bpc = curr_file_bpc; } snprintf(text2,99," %dx%dx%d",ww,hh,bpc); // 2345x1234x16 (preview) 1.56MB 45% strcat(text1,text2); if (Fpreview) strcat(text1," (preview)"); sprintf(text2," %.2fMB",file_MB); strcat(text1,text2); scale = Mscale * 100 + 0.5; sprintf(text2," %d%c",scale,'%'); strcat(text1,text2); if (Pundo) { // edit undo stack depth snprintf(text2,99," edits: %d",Pundo); strcat(text1,text2); } } if (Fmenulock) strcat(text1," menu locked"); if (Fsyncbusy) strcat(text1," file sync busy"); // v.11.11 if (Factivearea) strcat(text1," area active"); // v.11.01 if (zfuncs::zdialog_busy) strcat(text1," dialog open"); // v.11.11 if (SB_goal) { // progress monitor v.9.6 done = 100.0 * SB_done / SB_goal; // v.11.06 snprintf(text2,99," progress %d%c",done,'%'); strcat(text1,text2); } if (*SB_text) { // application text v.10.7 strcat(text1," "); strcat(text1,SB_text); } stbar_message(STbar,text1); // write to status bar return; } /**************************************************************************/ // functions for main window event signals int delete_event() // main window closed { printf("main window delete event \n"); if (mod_keep()) return 1; // allow user bailout Fshutdown++; // shutdown in progress save_params(); // save parameters for next session zdialog_positions("save"); // save dialog positions too v.11.07 free_resources(); // delete undo files return 0; } void destroy_event() // main window destroyed { printf("main window destroy event \n"); Fshutdown++; // shutdown in progress free_resources(); // delete undo files v.12.01 exit(1); // instead of gtk_main_quit(); return; } // process top-level menu entry void topmenufunc(GtkWidget *, cchar *menu) { topmenu = (char *) menu; // remember top-level menu in case return; // this is needed somewhere } /**************************************************************************/ // Paint window when created, exposed, resized, or modified (edited). // This is a full window update. May NOT be called from threads. int mwpaint1() { GdkRectangle wrect; int incrx, incry; // mouse drag static int pincrx = 0, pincry = 0; // prior mouse drag static int pdww = 0, pdhh = 0; // prior window size static int piorgx = 0, piorgy = 0; // prior image origin in window static double pscale = 1; // prior scale double wscale, hscale; int refresh = 0; // flag, image refesh needed int mousex, mousey; // mouse position after zoom PXM *pxmtemp; if (Fshutdown) return 1; // shutdown underway if (! Fpxm8) { gdk_window_clear(drWin->window); // no image v.11.12 return 1; } Dww = drWin->allocation.width; // (new) drawing window size Dhh = drWin->allocation.height; if (Dww < 20 || Dhh < 20) return 1; // too small if (mutex_trylock(&Fpixmap_lock) != 0) { // lock pixmaps Wrepaint++; // cannot, come back later return 1; } if (Frefresh) { // image was updated refresh++; Frefresh = 0; } if (Dww != pdww || Dhh != pdhh) { // window size changed refresh++; // image refresh needed pdww = Dww; pdhh = Dhh; } if (E3pxm16) { // get image size Iww = E3ww; Ihh = E3hh; // edit in progress } else { Iww = Fww; // no edit Ihh = Fhh; } if (Fzoom == 0) { // scale to fit window wscale = 1.0 * Dww / Iww; hscale = 1.0 * Dhh / Ihh; if (wscale < hscale) Mscale = wscale; // use greatest ww/hh ratio else Mscale = hscale; if (Iww < Dww && Ihh < Dhh && ! Fblowup) Mscale = 1.0; // small image 1x unless Fblowup zoomx = zoomy = 0; } else Mscale = Fzoom; // scale to Fzoom level if (Mscale != pscale) refresh++; // scale changed, image refresh needed if (Mscale > pscale) { // zoom increased Iorgx += iww * 0.5 * (1.0 - pscale / Mscale); // keep current image center Iorgy += ihh * 0.5 * (1.0 - pscale / Mscale); } pscale = Mscale; iww = Dww / Mscale; // image space fitting in window if (iww > Iww) iww = Iww; ihh = Dhh / Mscale; if (ihh > Ihh) ihh = Ihh; if (zoomx || zoomy) { // req. zoom center Iorgx = zoomx - 0.5 * iww; // corresp. image origin Iorgy = zoomy - 0.5 * ihh; ///zoomx = zoomy = 0; // v.12.01 } if ((Mxdrag || Mydrag) && Fmousemain) { // scroll via mouse drag v.12.01 incrx = (Mxdrag - Mxdown) * 1.3 * Iww / iww; // scale incry = (Mydrag - Mydown) * 1.3 * Ihh / ihh; if (pincrx > 0 && incrx < 0) incrx = 0; // stop bounce at extremes if (pincrx < 0 && incrx > 0) incrx = 0; pincrx = incrx; if (pincry > 0 && incry < 0) incry = 0; if (pincry < 0 && incry > 0) incry = 0; pincry = incry; Iorgx += incrx; // new image origin after scroll Iorgy += incry; Mxdown = Mxdrag + incrx; // new drag origin Mydown = Mydrag + incry; Mxdrag = Mydrag = 0; zoomx = zoomy = 0; // no zoom target v.12.01 } if (iww == Iww) { // scaled image <= window width Iorgx = 0; // center image in window Dorgx = 0.5 * (Dww - Iww * Mscale); } else Dorgx = 0; // image > window, use entire window if (ihh == Ihh) { // same for image height Iorgy = 0; Dorgy = 0.5 * (Dhh - Ihh * Mscale); } else Dorgy = 0; if (Iorgx + iww > Iww) Iorgx = Iww - iww; // set limits if (Iorgy + ihh > Ihh) Iorgy = Ihh - ihh; if (Iorgx < 0) Iorgx = 0; if (Iorgy < 0) Iorgy = 0; if (Iorgx != piorgx || Iorgy != piorgy) { // image origin changed refresh++; // image refresh needed piorgx = Iorgx; piorgy = Iorgy; } if (refresh) // image refresh is needed { if (E3pxm16) { // edit in progress PXM_free(Dpxm16); Dpxm16 = PXM_copy_area(E3pxm16,Iorgx,Iorgy,iww,ihh); // copy E3 image area, PXM-16 pxmtemp = PXM_convbpc(Dpxm16); // convert to PXM-8 } else pxmtemp = PXM_copy_area(Fpxm8,Iorgx,Iorgy,iww,ihh); // no edit, copy PXM-8 image area dww = iww * Mscale; // scale to window dhh = ihh * Mscale; PXM_free(Dpxm8); Dpxm8 = PXM_rescale(pxmtemp,dww,dhh); PXM_free(pxmtemp); } if (zoomx || zoomy) { // zoom target v.12.01 mousex = (zoomx - Iorgx) * Mscale + Dorgx; mousey = (zoomy - Iorgy) * Mscale + Dorgy; gdk_window_move_pointer(drWin->window,mousex,mousey); // pointer follows target } wrect.x = wrect.y = 0; // stop flicker wrect.width = Dww; wrect.height = Dhh; gdk_window_begin_paint_rect(drWin->window,&wrect); gdk_draw_rgb_image(drWin->window, gdkgc, Dorgx, Dorgy, dww, dhh, // draw scaled image to window NODITHER, (uint8 *) Dpxm8->bmp, dww*3); if (Ntoplines) paint_toplines(1); // draw line overlays if (Ftoparc) paint_toparc(1); // draw arc overlay if (Fgrid) paint_gridlines(); // draw grid lines if (Ntoptext) paint_toptext(); // draw text strings v.11.07 if (Ntopcircles) paint_topcircles(); // draw red circles v.11.12 if (Fshowarea && ! Fpreview) sa_show(1); // draw select area outline gdk_window_end_paint(drWin->window); // release all window updates zoomx = zoomy = 0; // reset zoom targetv.12.01 v.12.01 mutex_unlock(&Fpixmap_lock); // unlock pixmaps Wpainted++; // notify edit function of repaint histogram_paint(); // update brightness histogram if exists return 1; } /**************************************************************************/ // Cause (modified) output image to get repainted soon. // The entire image is repainted (that part within the window). // MAY be called from threads. void mwpaint2() { Frefresh++; Wrepaint++; // req. repaint by periodic function return; } // Repaint a rectangular part of the image being edited. // px3, py3, ww3, hh3: modified area within E3pxm16 to be repainted // Dpxm16: 1x copy of E3pxm16 area currently visible in main window // px2, py2, ww2, hh2: E3pxm16 area copied into Dpxm16 // Dpxm8: window image, Dpxm16 scaled to window, converted to 8 bits // May NOT be called from threads. void mwpaint3(int px3, int py3, int ww3, int hh3) // overhauled v.10.11 { int px2, py2, ww2, hh2, dx, dy; uint16 *pix2, *pix3; uint8 *pxm8area; if (! Dpxm16) zappcrash("mwpaint3() no Dpxm16"); // v.10.12 px2 = px3 - Iorgx; // map modified area into Dpxm16 py2 = py3 - Iorgy; ww2 = ww3; hh2 = hh3; if (px2 < 0) { // if beyond Dpxm16 edge, reduce px3 -= px2; ww2 += px2; px2 = 0; } if (px2 + ww2 > iww) ww2 = iww - px2; if (py2 < 0) { py3 -= py2; hh2 += py2; py2 = 0; } if (py2 + hh2 > ihh) hh2 = ihh - py2; if (ww2 <= 0 || hh2 <= 0) return; // completely off Dpxm16 image for (dy = 0; dy < hh2; dy++) // copy pixels from E3pxm16 to Dpxm16 for (dx = 0; dx < ww2; dx++) { pix3 = PXMpix(E3pxm16,px3+dx,py3+dy); pix2 = PXMpix(Dpxm16,px2+dx,py2+dy); pix2[0] = pix3[0]; pix2[1] = pix3[1]; pix2[2] = pix3[2]; } PXM_update(Dpxm16,Dpxm8,px2,py2,ww2,hh2); // copy/rescale Dpxm16 area into Dpxm8 area px2 = px2 * Mscale - 1; // Dpxm8 area impacted v.10.12 py2 = py2 * Mscale - 1; ww2 = ww2 * Mscale + 1 / Mscale + 2; hh2 = hh2 * Mscale + 1 / Mscale + 2; if (px2 < 0) px2 = 0; // stay within image edge if (py2 < 0) py2 = 0; if (px2 + ww2 > dww) ww2 = dww - px2; if (py2 + hh2 > dhh) hh2 = dhh - py2; if (ww2 <= 0 || hh2 <= 0) return; // completely off Dpxm8 image pxm8area = (uint8 *) Dpxm8->bmp + 3 * (dww * py2 + px2); // origin of area to copy gdk_draw_rgb_image(drWin->window, gdkgc, px2 + Dorgx, py2 + Dorgy, // copy into window ww2, hh2, NODITHER, pxm8area, dww*3); if (Fshowarea && ! Fpreview) sa_show(1); // draw select area outline v.12.01 return; } /**************************************************************************/ // mouse event function - capture buttons and drag movements void mouse_event(GtkWidget *, GdkEventButton *event, void *) { void mouse_convert(int &xpos, int &ypos); static int bdtime = 0, butime = 0, mbusy = 0; int button, time, type, scroll; type = event->type; button = event->button; // button, 1/2/3 = left/center/right time = event->time; Mxposn = event->x; // mouse position in window Myposn = event->y; scroll = ((GdkEventScroll *) event)->direction; // scroll wheel event mouse_convert(Mxposn,Myposn); // convert to image space if (type == GDK_SCROLL) { // scroll wheel = zoom v.12.01 zoomx = Mxposn; // zoom center = mouse position (doriano) zoomy = Myposn; if (scroll == GDK_SCROLL_UP) m_zoom(null,"in"); if (scroll == GDK_SCROLL_DOWN) m_zoom(null,"out"); return; } if (type == GDK_MOTION_NOTIFY) { if (mbusy) return; // discard excess motion events mbusy++; zmainloop(); mbusy = 0; } if (type == GDK_BUTTON_PRESS) { // button down bdtime = time; // time of button down Mxdown = Mxposn; // position at button down time Mydown = Myposn; if (button) { Mdrag++; // possible drag start Mbutton = button; } Mxdrag = Mydrag = 0; } if (type == GDK_BUTTON_RELEASE) { // button up Mxclick = Myclick = 0; // reset click status butime = time; // time of button up if (butime - bdtime < 400) // less than 0.4 secs down if (Mxposn == Mxdown && Myposn == Mydown) { // and not moving if (Mbutton == 1) LMclick++; // left mouse click if (Mbutton == 3) RMclick++; // right mouse click Mxclick = Mxdown; // click = button down position Myclick = Mydown; } if (button == 2) { // center button click v.12.01 zoomx = Mxposn; // re-center at mouse (doriano) zoomy = Myposn; mwpaint2(); } Mxdown = Mydown = Mxdrag = Mydrag = Mdrag = Mbutton = 0; // forget buttons and drag } if (type == GDK_MOTION_NOTIFY && Mdrag) { // drag underway Mxdrag = Mxposn; Mydrag = Myposn; } Fmousemain = 1; // mouse acts on main window v.12.01 if (Mcapture) Fmousemain = 0; if (mouseCBfunc) Fmousemain = 0; if (KBcontrolkey) Fmousemain = 1; // Ctrl key >> mouse acts on main window if (mouseCBfunc && ! Fmousemain) { // pass to handler function if (mbusy) return; mbusy++; // stop re-entrance v.10.8 (* mouseCBfunc)(); mbusy = 0; return; } if (LMclick && Fmousemain) { // left click = zoom request LMclick = 0; zoomx = Mxclick; // zoom center = mouse zoomy = Myclick; m_zoom(null,"in"); } if (RMclick && Fmousemain) { // right click RMclick = 0; if (Fzoom) { zoomx = zoomy = 0; // reset zoom to fit window m_zoom(null,"fit"); } else if (edit_coll_name && curr_file) // pass file to edit collection edit_coll_popmenu(null,curr_file); // v.11.11 } if ((Mxdrag || Mydrag) && Fmousemain) mwpaint1(); // drag = scroll return; } // convert mouse position from window space to image space void mouse_convert(int &xpos, int &ypos) { xpos = (xpos - Dorgx) / Mscale + Iorgx + 0.5; ypos = (ypos - Dorgy) / Mscale + Iorgy + 0.5; if (xpos < 0) xpos = 0; // if outside image put at edge if (ypos < 0) ypos = 0; if (E3pxm16) { if (xpos >= E3ww) xpos = E3ww-1; if (ypos >= E3hh) ypos = E3hh-1; } else { if (xpos >= Fww) xpos = Fww-1; if (ypos >= Fhh) ypos = Fhh-1; } return; } /**************************************************************************/ // keyboard event function - some toolbar buttons have KB equivalents // GDK key symbols: /usr/include/gtk-2.0/gdk/gdkkeysyms.h int KBpress(GtkWidget *win, GdkEventKey *event, void *) // prevent propagation of key-press { // events to toolbar buttons KBkey = event->keyval; if (KBkey == GDK_Control_L || KBkey == GDK_Control_R) // Ctrl key is pressed v.11.07 KBcontrolkey = 1; if (KBkey == GDK_Shift_L || KBkey == GDK_Shift_R) // Shift key is pressed v.11.07 KBshiftkey = 1; if (KBkey == GDK_a || KBkey == GDK_A) // 'A' key is pressed v.11.11 KB_A_key = 1; // (undo/redo --> undo/redo ALL) return 1; } int KBrelease(GtkWidget *win, GdkEventKey *event, void *) { int angle = 0; PXM *pxm; KBkey = event->keyval; if (KBcapture) return 1; // let function handle it if (KBkey == GDK_Control_L || // Ctrl key released v.11.07 KBkey == GDK_Control_R) KBcontrolkey = 0; if (KBkey == GDK_Shift_L || // Shift key released v.11.07 KBkey == GDK_Shift_R) KBshiftkey = 0; if (KBkey == GDK_a || // 'A' key is released v.11.11 KBkey == GDK_A) KB_A_key = 0; if (KBcontrolkey) { if (KBkey == GDK_s) m_save(0,0); // Ctrl-* shortcuts if (KBkey == GDK_S) m_saveas(0,0); if (KBkey == GDK_v) m_savevers(0,0); if (KBkey == GDK_V) m_savevers(0,0); if (KBkey == GDK_q) m_quit(0,0); if (KBkey == GDK_Q) m_quit(0,0); } if (KBkey == GDK_G || KBkey == GDK_g) // toggle grid lines v.11.11 toggle_grid(2); if (Fslideshow) { // v.11.10 if (KBkey == GDK_Left) slideshow_next("prev"); // arrow keys = prev/next image if (KBkey == GDK_Right) slideshow_next("next"); if (KBkey == GDK_space) slideshow_next("pause"); // spacebar = pause/resume if (KBkey == GDK_Escape) m_slideshow(0,0); // escape = exit slideshow } else { if (KBkey == GDK_Left) m_prev(0,0); // arrow keys = prev/next image if (KBkey == GDK_Right) m_next(0,0); } if (KBkey == GDK_plus) m_zoom(null,"in"); // + key >> zoom in if (KBkey == GDK_minus) m_zoom(null,"fit"); // - key >> fit to window if (KBkey == GDK_equal) m_zoom(null,"in"); // = key: same as + if (KBkey == GDK_KP_Add) m_zoom(null,"in"); // keypad + if (KBkey == GDK_KP_Subtract) m_zoom(null,"fit"); // keypad - if (KBkey == GDK_Delete) m_trash(0,0); // delete >> trash if (KBkey == GDK_F1) // F1 >> user guide showz_userguide(zfuncs::F1_help_topic); // show topic if there, or page 1 if (! E1pxm16) { // if no edit in progress, if (KBkey == GDK_R || KBkey == GDK_r) angle = 90; // allow manual rotations if (KBkey == GDK_L || KBkey == GDK_l) angle = -90; if (angle) { mutex_lock(&Fpixmap_lock); // v.10.5 pxm = PXM_rotate(Fpxm8,angle); PXM_free(Fpxm8); Fpxm8 = pxm; Fww = pxm->ww; Fhh = pxm->hh; mutex_unlock(&Fpixmap_lock); mwpaint2(); m_save(0,"nowarn"); // auto save uprighted image v.10.12 } } if (KBcontrolkey && KBkey == GDK_m) { // zmalloc() activity log KBzmalloclog = 1 - KBzmalloclog; // Ctrl+M = toggle on/off if (KBzmalloclog) zmalloc_log(999999); else zmalloc_log(0); zmalloc_report(); // v.10.8 } if (KBkey == GDK_T || KBkey == GDK_t) m_trim(0,0); // Key T = Trim function v.10.3.1 if (KBkey == GDK_B || KBkey == GDK_b) m_tune(0,0); // Key B = brightness/color v.10.3.1 if (KBkey == GDK_N || KBkey == GDK_n) m_rename(0,0); // Key N = rename file v.11.11 if (KBkey == GDK_z || KBkey == GDK_Z) { // Z key if (! KBcontrolkey) m_zoom(null,"100"); // if no CTRL, toggle zoom 1x else { // if CTRL, v.11.11 if (KBshiftkey) m_redo(0,0); // with shift: redo edit else m_undo(0,0); // without shift: undo edit } } KBkey = 0; return 1; } /**************************************************************************/ // paint a grid of horizontal and vertical lines void paint_gridlines() // revised v.10.10.2 { int px, py, stepx, stepy, startx, starty; if (! Fpxm8) return; // no image if (! Fgrid) return; // grid lines off v.11.11 stepx = gridspace[0]; // space between grid lines stepy = gridspace[1]; if (gridcount[0]) stepx = dww / (1 + gridcount[0]); // if line counts specified, v.10.11 if (gridcount[1]) stepy = dhh / ( 1 + gridcount[1]); // set spacing accordingly startx = stepx * gridoffset[0] / 100; // variable offsets v.11.11 if (startx < 0) startx += stepx; starty = stepy * gridoffset[1] / 100; if (starty < 0) starty += stepy; gdk_gc_set_foreground(gdkgc,&white); // white lines if (gridon[0] && stepx) for (px = Dorgx+startx; px < Dorgx+dww; px += stepx) gdk_draw_line(drWin->window,gdkgc,px,Dorgy,px,Dorgy+dhh); if (gridon[1] && stepy) for (py = Dorgy+starty; py < Dorgy+dhh; py += stepy) gdk_draw_line(drWin->window,gdkgc,Dorgx,py,Dorgx+dww,py); gdk_gc_set_foreground(gdkgc,&black); // adjacent black lines fg_color = black; // v.10.12 if (gridon[0] && stepx) for (px = Dorgx+startx+1; px < Dorgx+dww; px += stepx) gdk_draw_line(drWin->window,gdkgc,px,Dorgy,px,Dorgy+dhh); if (gridon[1] && stepy) for (py = Dorgy+starty+1; py < Dorgy+dhh; py += stepy) gdk_draw_line(drWin->window,gdkgc,Dorgx,py,Dorgx+dww,py); return; } /**************************************************************************/ // refresh overlay lines on top of image // arg = 1: paint lines only (because window repainted) // 2: erase lines and forget them // 3: erase old lines, paint new lines, save new in old void paint_toplines(int arg) { int ii; if (arg == 2 || arg == 3) // erase old lines for (ii = 0; ii < Nptoplines; ii++) erase_line(ptoplinex1[ii],ptopliney1[ii],ptoplinex2[ii],ptopliney2[ii]); if (arg == 1 || arg == 3) // draw new lines for (ii = 0; ii < Ntoplines; ii++) draw_line(toplinex1[ii],topliney1[ii],toplinex2[ii],topliney2[ii]); if (arg == 2) { Nptoplines = Ntoplines = 0; // forget lines return; } for (ii = 0; ii < Ntoplines; ii++) // save for future erase { ptoplinex1[ii] = toplinex1[ii]; ptopliney1[ii] = topliney1[ii]; ptoplinex2[ii] = toplinex2[ii]; ptopliney2[ii] = topliney2[ii]; } Nptoplines = Ntoplines; return; } /**************************************************************************/ // refresh overlay arc (circle/ellipse) on top of image // arg = 1: paint arc only (because window repainted) // 2: erase arc and forget it // 3: erase old arc, paint new arc, save new in old void paint_toparc(int arg) { int arcx, arcy, arcw, arch; if (ptoparc && (arg == 2 || arg == 3)) { // erase old arc arcx = (ptoparcx-Iorgx) * Mscale + Dorgx + 0.5; // image to window space arcy = (ptoparcy-Iorgy) * Mscale + Dorgy + 0.5; arcw = ptoparcw * Mscale; arch = ptoparch * Mscale; gdk_gc_set_function(gdkgc,GDK_INVERT); // invert pixels gdk_draw_arc(drWin->window,gdkgc,0,arcx,arcy,arcw,arch,0,64*360); // draw arc gdk_gc_set_function(gdkgc,GDK_COPY); } if (Ftoparc && (arg == 1 || arg == 3)) { // draw new arc arcx = (toparcx-Iorgx) * Mscale + Dorgx + 0.5; // image to window space arcy = (toparcy-Iorgy) * Mscale + Dorgy + 0.5; arcw = toparcw * Mscale; arch = toparch * Mscale; gdk_gc_set_function(gdkgc,GDK_INVERT); // invert pixels gdk_draw_arc(drWin->window,gdkgc,0,arcx,arcy,arcw,arch,0,64*360); // draw arc gdk_gc_set_function(gdkgc,GDK_COPY); } if (arg == 2) { Ftoparc = ptoparc = 0; // forget arcs return; } ptoparc = Ftoparc; // save for future erase ptoparcx = toparcx; ptoparcy = toparcy; ptoparcw = toparcw; ptoparch = toparch; return; } /**************************************************************************/ // draw dotted line. coordinates are in image space. void draw_line(int ix1, int iy1, int ix2, int iy2) { void draw_line_pixel(double pxm, double pym); double x1, y1, x2, y2; double pxm, pym, slope; x1 = Mscale * (ix1-Iorgx); // image to window space y1 = Mscale * (iy1-Iorgy); x2 = Mscale * (ix2-Iorgx); y2 = Mscale * (iy2-Iorgy); if (abs(y2 - y1) > abs(x2 - x1)) { slope = 1.0 * (x2 - x1) / (y2 - y1); if (y2 > y1) { for (pym = y1; pym <= y2; pym++) { pxm = round(x1 + slope * (pym - y1)); draw_line_pixel(pxm,pym); } } else { for (pym = y1; pym >= y2; pym--) { pxm = round(x1 + slope * (pym - y1)); draw_line_pixel(pxm,pym); } } } else { slope = 1.0 * (y2 - y1) / (x2 - x1); if (x2 > x1) { for (pxm = x1; pxm <= x2; pxm++) { pym = round(y1 + slope * (pxm - x1)); draw_line_pixel(pxm,pym); } } else { for (pxm = x1; pxm >= x2; pxm--) { pym = round(y1 + slope * (pxm - x1)); draw_line_pixel(pxm,pym); } } } gdk_gc_set_foreground(gdkgc,&black); fg_color = black; return; } void draw_line_pixel(double px, double py) { int pxn, pyn; static int flip = 0; pxn = px; pyn = py; if (pxn < 0 || pxn > dww-1) return; if (pyn < 0 || pyn > dhh-1) return; if (++flip > 4) flip = -5; // black/white line v.10.10 if (flip < 0) gdk_gc_set_foreground(gdkgc,&black); else gdk_gc_set_foreground(gdkgc,&white); gdk_draw_point(drWin->window, gdkgc, pxn + Dorgx, pyn + Dorgy); return; } // erase line. refresh line path from Dpxm8 pixels. void erase_line(int ix1, int iy1, int ix2, int iy2) { void erase_line_pixel(double pxm, double pym); double x1, y1, x2, y2; double pxm, pym, slope; if (! Dpxm8) zappcrash("Dpxm8 = 0"); // v.10.3 x1 = Mscale * (ix1-Iorgx); y1 = Mscale * (iy1-Iorgy); x2 = Mscale * (ix2-Iorgx); y2 = Mscale * (iy2-Iorgy); if (abs(y2 - y1) > abs(x2 - x1)) { slope = 1.0 * (x2 - x1) / (y2 - y1); if (y2 > y1) { for (pym = y1; pym <= y2; pym++) { pxm = x1 + slope * (pym - y1); erase_line_pixel(pxm,pym); } } else { for (pym = y1; pym >= y2; pym--) { pxm = x1 + slope * (pym - y1); erase_line_pixel(pxm,pym); } } } else { slope = 1.0 * (y2 - y1) / (x2 - x1); if (x2 > x1) { for (pxm = x1; pxm <= x2; pxm++) { pym = y1 + slope * (pxm - x1); erase_line_pixel(pxm,pym); } } else { for (pxm = x1; pxm >= x2; pxm--) { pym = y1 + slope * (pxm - x1); erase_line_pixel(pxm,pym); } } } return; } void erase_line_pixel(double px, double py) { int pxn, pyn; pxn = px; pyn = py; if (pxn < 0 || pxn > dww-1) return; if (pyn < 0 || pyn > dhh-1) return; uint8 *pixel = (uint8 *) Dpxm8->bmp + (pyn * dww + pxn) * 3; gdk_draw_rgb_image(drWin->window, gdkgc, pxn + Dorgx, pyn + Dorgy, 1, 1, NODITHER, pixel, dww * 3); return; } // draw one pixel using given color, R/G/B = red/green/black void draw_pixel(int px, int py, GdkColor *color) // v.10.12 { int qx, qy; static int pqx, pqy; qx = Mscale * (px-Iorgx) + 0.5; // image to window space qy = Mscale * (py-Iorgy) + 0.5; if (qx == pqx && qy == pqy) return; // avoid redundant points v.9.7 pqx = qx; pqy = qy; qx = qx + Dorgx; // image origin in drawing window qy = qy + Dorgy; if (qx < 0 || qx > Dww-1) return; // bugfix v.11.03.1 if (qy < 0 || qy > Dhh-1) return; if (color != &fg_color) { fg_color = *color; gdk_gc_set_foreground(gdkgc,&fg_color); } gdk_draw_point(drWin->window,gdkgc,qx,qy); // draw pixel return; } // draw a fat pixel using given color, R/G/B = red/green/black void draw_fat_pixel(int px, int py, GdkColor *color) // speedup v.11.04 { int qx, qy; static int pqx, pqy; qx = Mscale * (px-Iorgx) + 0.5; // image to window space qy = Mscale * (py-Iorgy) + 0.5; if (qx == pqx && qy == pqy) return; // avoid redundant points v.9.7 pqx = qx; pqy = qy; qx = qx + Dorgx; // image origin in drawing window qy = qy + Dorgy; if (qx < 0 || qy < 0) return; if (color != &fg_color) { fg_color = *color; gdk_gc_set_foreground(gdkgc,&fg_color); } if (qx < Dww-1 && qy < Dhh-1 && Mscale > 1.0) gdk_draw_rectangle(drWin->window,gdkgc,0,qx,qy,2,2); // draw fat pixel 2x2 else if (qx < Dww && qy < Dhh) gdk_draw_point(drWin->window,gdkgc,qx,qy); // on edge, draw pixel return; } /**************************************************************************/ // maintain a set of text strings written whenever the window is painted // add a new text string to the list // multiple text strings can be added with the same ID // px and py are image coordinates void add_toptext(int ID, int px, int py, cchar *text, cchar *font) // new v.11.07 { if (Ntoptext == maxtoptext) { printf("maxtoptext exceeded \n"); return; } int ii = Ntoptext++; toptext[ii].ID = ID; toptext[ii].px = px; toptext[ii].py = py; toptext[ii].text = text; toptext[ii].font = font; return; } // delete text strings having the given ID from the list void erase_toptext(int ID) // new v.11.07 { int ii, jj; for (ii = jj = 0; ii < Ntoptext; ii++) { if (toptext[ii].ID == ID) continue; else toptext[jj++] = toptext[ii]; } Ntoptext = jj; return; } // paint current text strings on window whenever it is repainted // called from mwpaint() void paint_toptext() // new v.11.07 { int ii, px, py; for (ii = 0; ii < Ntoptext; ii++) { px = toptext[ii].px; py = toptext[ii].py; px = Mscale * (px - Iorgx) + Dorgx; // image to window space py = Mscale * (py - Iorgy) + Dorgy; paint_text(px,py,toptext[ii].text,toptext[ii].font); } return; } // paint text on window, black on white background // px and py are window coordinates void paint_text(int px, int py, cchar *text, cchar *font) // new v.11.07 { static PangoFontDescription *pangofont = null; static PangoLayout *pangolayout = null; static char priorfont[40] = ""; if (strNeq(font,priorfont)) { // change font strncpy0(priorfont,font,40); if (pangofont) pango_font_description_free(pangofont); if (pangolayout) g_object_unref(pangolayout); pangofont = pango_font_description_from_string(font); pangolayout = gtk_widget_create_pango_layout(drWin,0); pango_layout_set_font_description(pangolayout,pangofont); } pango_layout_set_text(pangolayout,text,-1); gdk_draw_layout_with_colors(drWin->window,gdkgc,px,py,pangolayout,&black,&white); return; } /**************************************************************************/ // maintain a set of circles written whenever the window is painted void add_topcircle(int px, int py, int radius, int color) { if (Ntopcircles == maxtopcircles) { printf("maxtopcircles exceeded \n"); return; } int ii = Ntopcircles++; topcircles[ii].px = px; topcircles[ii].py = py; topcircles[ii].radius = radius; topcircles[ii].color = color; return; } void erase_topcircles() { Ntopcircles = 0; return; } void paint_topcircles() { int ii, px, py, rad, color; for (ii = 0; ii < Ntopcircles; ii++) { px = (topcircles[ii].px - Iorgx) * Mscale + Dorgx + 0.5; // image to window space py = (topcircles[ii].py - Iorgy) * Mscale + Dorgy + 0.5; rad = topcircles[ii].radius; // radius is window space color = topcircles[ii].color; // 1/2/3 = white/black/red px -= rad ; // NW corner of enclosing square py -= rad ; rad = 2 * rad; // size of enclosing square if (color == 1) gdk_gc_set_foreground(gdkgc,&white); // set foreground color else if (color == 2) gdk_gc_set_foreground(gdkgc,&black); else gdk_gc_set_foreground(gdkgc,&red); gdk_draw_arc(drWin->window,gdkgc,0,px,py,rad,rad,0,64*360); // draw 360 deg. arc } return; } /************************************************************************** spline curve setup and edit functions Support multiple frames with curves in parallel // v.11.01 (edit curve(s) and image mask curve) Usage: Add frame widget to dialog or zdialog. Set up drawing in frame: sd = curve_init(frame, callback_func) Initialize no. of curves in frame (1-10): sd->Nspc = n Initialize vert/horz flag for curve spc: sd->vert[spc] = hv Initialize anchor points for curve spc: sd->nap[spc], sd->apx[spc][xx], sd->apy[spc][yy] Generate data for curve spc: splcurve_generate(sd,spc) Curves will now be shown and edited inside the frame when window is realized. The callback_func(spc) will be called when curve spc is edited. Change curve in program: set anchor points, call splcurve_generate(sd,spc) Get y-value (0-1) for curve spc and given x-value (0-1): yval = splcurve_yval(sd,spc,xval) If faster access to curve is needed (no interpolation): kk = 1000 * xval; if (kk > 999) kk = 999; yval = sd->yval[spc][kk]; ***/ // initialize for spline curve editing // initial anchor points are pre-loaded into spldat before window is realized spldat * splcurve_init(GtkWidget *frame, void func(int spc)) { int cc = sizeof(spldat); // allocate spc curve data area spldat * sd = (spldat *) zmalloc(cc,"curvedat"); memset(sd,0,cc); sd->drawarea = gtk_drawing_area_new(); // drawing area for curves gtk_container_add(GTK_CONTAINER(frame),sd->drawarea); sd->spcfunc = func; // user callback function gtk_widget_add_events(sd->drawarea,GDK_BUTTON_PRESS_MASK); // connect mouse events to drawing area gtk_widget_add_events(sd->drawarea,GDK_BUTTON_RELEASE_MASK); gtk_widget_add_events(sd->drawarea,GDK_BUTTON1_MOTION_MASK); G_SIGNAL(sd->drawarea,"motion-notify-event",splcurve_adjust,sd); G_SIGNAL(sd->drawarea,"button-press-event",splcurve_adjust,sd); G_SIGNAL(sd->drawarea,"expose-event",splcurve_draw,sd); return sd; } // modify anchor points in curve using mouse int splcurve_adjust(void *, GdkEventButton *event, spldat *sd) { int ww, hh, kk; int mx, my, button, evtype; static int spc, ap, mbusy = 0, Fdrag = 0; // drag continuation logic v.9.7 int minspc, minap; double mxval, myval, cxval, cyval; double dist2, mindist2 = 0; mx = event->x; // mouse position in drawing area my = event->y; evtype = event->type; button = event->button; if (evtype == GDK_MOTION_NOTIFY) { if (mbusy) return 0; // discard excess motion events v.11.01 mbusy++; zmainloop(); mbusy = 0; } if (evtype == GDK_BUTTON_RELEASE) { Fdrag = 0; return 0; } ww = sd->drawarea->allocation.width; // drawing area size hh = sd->drawarea->allocation.height; if (mx < 0) mx = 0; // limit edge excursions if (mx > ww) mx = ww; if (my < 0) my = 0; if (my > hh) my = hh; if (evtype == GDK_BUTTON_PRESS) Fdrag = 0; // left or right click if (Fdrag) // continuation of drag { if (sd->vert[spc]) { mxval = 1.0 * my / hh; // mouse position in curve space myval = 1.0 * mx / ww; } else { mxval = 1.0 * mx / ww; myval = 1.0 * (hh - my) / hh; } if (ap < sd->nap[spc]-1 && sd->apx[spc][ap+1] - mxval < 0.05) // disallow < 0.05 from next return 0; if (ap > 0 && mxval - sd->apx[spc][ap-1] < 0.05) return 0; // or prior anchor point } else // mouse click or new drag begin { minspc = minap = -1; // find closest curve/anchor point mindist2 = 999999; for (spc = 0; spc < sd->Nspc; spc++) // loop curves { if (sd->vert[spc]) { mxval = 1.0 * my / hh; // mouse position in curve space myval = 1.0 * mx / ww; } else { mxval = 1.0 * mx / ww; myval = 1.0 * (hh - my) / hh; } for (ap = 0; ap < sd->nap[spc]; ap++) // loop anchor points { cxval = sd->apx[spc][ap]; cyval = sd->apy[spc][ap]; dist2 = (mxval-cxval)*(mxval-cxval) + (myval-cyval)*(myval-cyval); if (dist2 < mindist2) { mindist2 = dist2; // remember closest anchor point minspc = spc; minap = ap; } } } if (minspc < 0) return 0; // impossible spc = minspc; ap = minap; } if (evtype == GDK_BUTTON_PRESS && button == 3) // right click, remove anchor point { if (sqrt(mindist2) > 0.05) return 0; // not close enough if (sd->nap[spc] < 3) return 0; // < 2 anchor points would remain sd->nap[spc]--; // decr. before loop v.11.11 for (kk = ap; kk < sd->nap[spc]; kk++) { if (! kk) printf("meaningless reference %d",kk); // stop gcc optimization bug v.11.11 ///// sd->apx[spc][kk] = sd->apx[spc][kk+1]; sd->apy[spc][kk] = sd->apy[spc][kk+1]; } splcurve_generate(sd,spc); // regenerate data for modified curve splcurve_draw(0,0,sd); // regen and redraw all curves sd->spcfunc(spc); // call user function return 0; } if (! Fdrag) // new drag or left click { if (sd->vert[spc]) { mxval = 1.0 * my / hh; // mouse position in curve space myval = 1.0 * mx / ww; } else { mxval = 1.0 * mx / ww; myval = 1.0 * (hh - my) / hh; } if (sqrt(mindist2) < 0.05) // existing point close enough, { // move this anchor point to mouse if (ap < sd->nap[spc]-1 && sd->apx[spc][ap+1] - mxval < 0.05) return 0; // disallow < 0.05 from next if (ap > 0 && mxval - sd->apx[spc][ap-1] < 0.05) return 0; // or prior anchor point } else // none close, add new anchor point { minspc = -1; // find closest curve to mouse mindist2 = 999999; for (spc = 0; spc < sd->Nspc; spc++) // loop curves { if (sd->vert[spc]) { mxval = 1.0 * my / hh; // mouse position in curve space myval = 1.0 * mx / ww; } else { mxval = 1.0 * mx / ww; myval = 1.0 * (hh - my) / hh; } cyval = splcurve_yval(sd,spc,mxval); dist2 = fabs(myval - cyval); if (dist2 < mindist2) { mindist2 = dist2; // remember closest curve minspc = spc; } } if (minspc < 0) return 0; // impossible if (mindist2 > 0.05) return 0; // not close enough to any curve spc = minspc; if (sd->nap[spc] > 49) { zmessageACK(mWin,ZTX("Exceed 50 anchor points")); return 0; } if (sd->vert[spc]) { mxval = 1.0 * my / hh; // mouse position in curve space myval = 1.0 * mx / ww; } else { mxval = 1.0 * mx / ww; myval = 1.0 * (hh - my) / hh; } for (ap = 0; ap < sd->nap[spc]; ap++) // find anchor point with next higher x if (mxval <= sd->apx[spc][ap]) break; // (ap may come out 0 or nap) if (ap < sd->nap[spc] && sd->apx[spc][ap] - mxval < 0.05) // disallow < 0.05 from next return 0; // or prior anchor point if (ap > 0 && mxval - sd->apx[spc][ap-1] < 0.05) return 0; for (kk = sd->nap[spc]; kk > ap; kk--) { // make hole for new point sd->apx[spc][kk] = sd->apx[spc][kk-1]; sd->apy[spc][kk] = sd->apy[spc][kk-1]; } sd->nap[spc]++; // up point count } } sd->apx[spc][ap] = mxval; // new or moved anchor point sd->apy[spc][ap] = myval; // at mouse position splcurve_generate(sd,spc); // regenerate data for modified curve splcurve_draw(0,0,sd); // regen and redraw all curves sd->spcfunc(spc); // call user function if (evtype == GDK_MOTION_NOTIFY) Fdrag = 1; // remember drag is underway return 0; } // for expose event or when a curve is changed // draw all curves based on current anchor points int splcurve_draw(void *, void *, spldat *sd) { int ww, hh, px, py, qx, qy, spc, ap; double xval, yval; ww = sd->drawarea->allocation.width; // drawing area size hh = sd->drawarea->allocation.height; if (ww < 50 || hh < 50) return 0; gdk_window_clear(sd->drawarea->window); // clear window gdk_gc_set_foreground(gdkgc,&dgray); for (int ii = 0; ii < sd->Nscale; ii++) // draw y-scale lines if any v.11.07 { px = ww * sd->xscale[0][ii] + 0.5; // any line, not only horizontal v.11.10 py = hh - hh * sd->yscale[0][ii] + 0.5; qx = ww * sd->xscale[1][ii] + 0.5; qy = hh - hh * sd->yscale[1][ii] + 0.5; gdk_draw_line(sd->drawarea->window,gdkgc,px,py,qx,qy); } gdk_gc_set_foreground(gdkgc,&black); fg_color = black; for (spc = 0; spc < sd->Nspc; spc++) { if (sd->vert[spc]) // vert. curve { for (py = 0; py < hh; py++) // generate all points for curve { xval = 1.0 * py / hh; // remove anchor point limits v.10.9 yval = splcurve_yval(sd,spc,xval); px = ww * yval + 0.49; // "almost" round - erratic floating point gdk_draw_point(sd->drawarea->window,gdkgc,px,py); // causes "bumps" in a flat curve } for (ap = 0; ap < sd->nap[spc]; ap++) // draw boxes at anchor points { xval = sd->apx[spc][ap]; yval = sd->apy[spc][ap]; px = ww * yval; py = hh * xval; for (qx = -2; qx < 3; qx++) for (qy = -2; qy < 3; qy++) { if (px+qx < 0 || px+qx >= ww) continue; if (py+qy < 0 || py+qy >= hh) continue; gdk_draw_point(sd->drawarea->window,gdkgc,px+qx,py+qy); } } } else // horz. curve { for (px = 0; px < ww; px++) // generate all points for curve { xval = 1.0 * px / ww; // remove anchor point limits v.10.9 yval = splcurve_yval(sd,spc,xval); py = hh - hh * yval + 0.49; // almost round - erratic FP in Intel CPUs gdk_draw_point(sd->drawarea->window,gdkgc,px,py); // causes "bumps" in a flat curve } for (ap = 0; ap < sd->nap[spc]; ap++) // draw boxes at anchor points { xval = sd->apx[spc][ap]; yval = sd->apy[spc][ap]; px = ww * xval; py = hh - hh * yval; for (qx = -2; qx < 3; qx++) for (qy = -2; qy < 3; qy++) { if (px+qx < 0 || px+qx >= ww) continue; if (py+qy < 0 || py+qy >= hh) continue; gdk_draw_point(sd->drawarea->window,gdkgc,px+qx,py+qy); } } } } return 0; } // generate all curve data points when anchor points are modified int splcurve_generate(spldat *sd, int spc) { int kk, kklo, kkhi; double xval, yvalx; spline1(sd->nap[spc],sd->apx[spc],sd->apy[spc]); // compute curve fitting anchor points kklo = 1000 * sd->apx[spc][0] - 30; // xval range = anchor point range if (kklo < 0) kklo = 0; // + 0.03 extra below/above v.9.5 kkhi = 1000 * sd->apx[spc][sd->nap[spc]-1] + 30; if (kkhi > 1000) kkhi = 1000; for (kk = 0; kk < 1000; kk++) // generate all points for curve { xval = 0.001 * kk; // remove anchor point limits v.10.9 yvalx = spline2(xval); if (yvalx < 0) yvalx = 0; // yval < 0 not allowed, > 1 OK v.9.5 sd->yval[spc][kk] = yvalx; } return 0; } // Retrieve curve data using interpolation of saved table of values double splcurve_yval(spldat *sd, int spc, double xval) { int ii; double x1, x2, y1, y2, y3; if (xval <= 0) return sd->yval[spc][0]; if (xval >= 0.999) return sd->yval[spc][999]; x2 = 1000.0 * xval; ii = x2; x1 = ii; y1 = sd->yval[spc][ii]; y2 = sd->yval[spc][ii+1]; y3 = y1 + (y2 - y1) * (x2 - x1); return y3; } // load curve data from a file // returns 0 if fail (invalid file data), sd not modified // returns 1 if succcess, sd is initialized from file data int splcurve_load(spldat *sd) // v.11.02 { char *pfile; int nn, ii, jj; FILE *fid = 0; int Nspc, vert[10], nap[10]; double apx[10][50], apy[10][50]; zfuncs::F1_help_topic = "curve_edit"; pfile = zgetfile1(ZTX("load curve from a file"),"open",saved_curves_dirk); if (! pfile) return 0; fid = fopen(pfile,"r"); zfree(pfile); if (! fid) goto fail; nn = fscanf(fid,"%d ",&Nspc); // no. of curves if (nn != 1) goto fail; if (Nspc < 1 || Nspc > 10) goto fail; if (Nspc != sd->Nspc) goto fail2; for (ii = 0; ii < Nspc; ii++) // loop each curve { nn = fscanf(fid,"%d %d ",&vert[ii],&nap[ii]); // vertical flag, no. anchor points if (nn != 2) goto fail; if (vert[ii] < 0 || vert[ii] > 1) goto fail; if (nap[ii] < 2 || nap[ii] > 50) goto fail; for (jj = 0; jj < nap[ii]; jj++) // anchor point values { nn = fscanf(fid,"%lf/%lf ",&apx[ii][jj],&apy[ii][jj]); if (nn != 2) goto fail; if (apx[ii][jj] < 0 || apx[ii][jj] > 1) goto fail; if (apy[ii][jj] < 0 || apy[ii][jj] > 1) goto fail; } } fclose(fid); sd->Nspc = Nspc; // copy curve data to caller's arg for (ii = 0; ii < Nspc; ii++) { sd->vert[ii] = vert[ii]; sd->nap[ii] = nap[ii]; for (jj = 0; jj < nap[ii]; jj++) { sd->apx[ii][jj] = apx[ii][jj]; sd->apy[ii][jj] = apy[ii][jj]; } } for (ii = 0; ii < Nspc; ii++) // generate curve data from anchor points splcurve_generate(sd,ii); if (sd->drawarea) splcurve_draw(0,0,sd); // regen and redraw all curves return 1; fail: if (fid) fclose(fid); zmessageACK(mWin,ZTX("curve file is invalid")); return 0; fail2: if (fid) fclose(fid); zmessageACK(mWin,ZTX("curve file has different no. of curves")); return 0; } // save curve data to a file int splcurve_save(spldat *sd) // v.11.02 { char *pfile, *pp; int ii, jj; FILE *fid; zfuncs::F1_help_topic = "curve_edit"; pp = zgetfile1(ZTX("save curve to a file"),"save",saved_curves_dirk); if (! pp) return 0; pfile = strdupz(pp,8); zfree(pp); pp = strrchr(pfile,'/'); // force .curve extension if (pp) pp = strrchr(pp,'.'); if (pp) strcpy(pp,".curve"); else strcat(pfile,".curve"); fid = fopen(pfile,"w"); zfree(pfile); if (! fid) return 0; fprintf(fid,"%d \n",sd->Nspc); // no. of curves for (ii = 0; ii < sd->Nspc; ii++) // loop each curve { fprintf(fid,"%d %d \n",sd->vert[ii],sd->nap[ii]); // vertical flag, no. anchor points for (jj = 0; jj < sd->nap[ii]; jj++) // anchor point values fprintf(fid,"%.4f/%.4f ",sd->apx[ii][jj],sd->apy[ii][jj]); fprintf(fid,"\n"); } fclose(fid); return 0; } /************************************************************************** zdialog mouse capture and release ***************************************************************************/ void takeMouse(zdialog *zd, CBfunc func, GdkCursor *cursor) // capture mouse for dialog v.11.03 { freeMouse(); mouseCBfunc = func; Mcapture = 1; gdk_window_set_cursor(drWin->window,cursor); // v.11.03 return; } void freeMouse() // free mouse for main window v.10.12 { mouseCBfunc = 0; Mcapture = 0; paint_toparc(2); // remove mouse circle v.11.04 gdk_window_set_cursor(drWin->window,0); // set normal cursor v.11.03 return; } /************************************************************************** edit transaction and thread support functions edit transaction management edit_setup() start new edit - copy E3 > E1 edit_cancel() cancel edit - E1 > E3, delete E1 edit_done() commit edit - add to undo stack edit_undo() undo edit - E1 > E3 edit_redo() redo edit - run thread again edit_fullsize() convert preview to full-size pixmaps main level thread management start_thread(func,arg) start thread running signal_thread() signal thread that work is pending wait_thread_idle() wait for pending work complete wrapup_thread(command) wait for exit or command thread exit thread function thread_idle_loop() wait for pending work, exit if commanded thread_exit() exit thread unconditionally thread_status (thread ownership 0 no thread is running 1 thread is running and idle (no work) 2 thread is working 0 thread has exited thread_command (main program ownership) 0 idle, no work pending 8 exit when pending work is done 9 exit now, unconditionally thread_pend work requested counter thread_done work done counter thread_hiwater high water mark edit_action done/cancel/undo/redo in progress ***************************************************************************/ int thread_command = 0, thread_status = 0; int thread_pend = 0, thread_done = 0, thread_hiwater = 0; int edit_action = 0; /************************************************************************** Setup for a new edit transaction Create E1 (edit input) and E3 (edit output) pixmaps from previous edit output (Fpxm16) or image file (new Fpxm16). Fprev 0 edit full-size image 1 edit preview image unless select area exists Farea 0 select_area is invalid and will be deleted (e.g. rotate) 1 select_area not used but remains valid (e.g. red-eye) 2 select_area can be used and remains valid (e.g. flatten) ***************************************************************************/ int edit_setup(editfunc &EF) // support parallel edits v.11.07 { int yn; PXM *pxmtemp = 0; if (! curr_file) return 0; // no image file if (is_syncbusy()) return 0; // must wait for file sync v.11.11 if (! Fpxm16) { // no 16-bit image from prior edit pxmtemp = f_load(curr_file,16); // check that file can be loaded if (! pxmtemp) { printf("f_load (16) failed: %s \n",curr_file); return 0; } } if (CEF) { // prior edit function active v.11.07 if (&EF == CEF) return 0; // 2nd instance of one function if (EF.Fpara && CEF->Fpara) // check if parallel edits are OK edit_suspend(); // suspend prior edit else { zmessageACK(mWin,ZTX("cannot parallel edit")); return 0; } } else { // if this is 1st active edit if (! menulock(1)) return 0; // test menu lock is allowed menulock(0); // but don't lock yet v.11.07 } if (! Fexiftool && ! Fexifwarned) { zmessageACK(mWin,ZTX("exiftool is not installed \n" // warn if starting to edit "edited images will lose EXIF data")); // and exiftool is missing Fexifwarned = 1; } if (Pundo > maxedits-2) { // undo capacity reached zmessageACK(mWin,ZTX("Too many edits, please save image")); return 0; } if (EF.Farea == 0 && sa_stat) { // select area will be lost, warn user yn = zmessageYN(mWin,ZTX("Select area cannot be kept.\n" "Continue?")); if (! yn) return 0; sa_unselect(); // unselect area zdialog_free(zdsela); } if (EF.Farea == 2 && sa_stat && ! Factivearea) { // select area exists and can be used, yn = zmessageYN(mWin,ZTX("Select area not active.\n" // but not active, ask user "Continue?")); if (! yn) return 0; } if (! menulock(1)) return 0; // can now commit, lock menu v.11.07 Fpreview = 0; // use preview image if supported if (EF.Fprev && ! (EF.Farea == 2 && Factivearea)) { // and select area will not be used Fpreview = 1; // use preview image (smaller) sa_show(0); // hide area if present curr_image_time = get_seconds(); // mark time of file load v.11.07 if (Fzoom) { Fzoom = 0; // bugfix, mwpaint() req. v.11.01 mwpaint1(); } } mutex_lock(&Fpixmap_lock); // lock pixmaps if (! Fpxm16) Fpxm16 = pxmtemp; // create Fpxm16 if not already PXM_fixblue(Fpxm16); // blue=0 >> blue=2 for vpixel() v.11.07 if (Fpreview) // edit pixmaps are window-size E1pxm16 = PXM_rescale(Fpxm16,dww,dhh); // E1pxm16 = Fpxm16 scaled to window else E1pxm16 = PXM_copy(Fpxm16); // edit pixmaps are full-size E3pxm16 = PXM_copy(E1pxm16); // E1 >> E3 E1ww = E3ww = E1pxm16->ww; // E1 and E3 pixmap dimensions E1hh = E3hh = E1pxm16->hh; mutex_unlock(&Fpixmap_lock); if (Pundo == 0) save_undo("initial"); // initial image >> undo stack CEF = &EF; // set current edit function CEF->Fmod = 0; // image not modified yet thread_command = thread_status = 0; // no thread running thread_pend = thread_done = thread_hiwater = 0; // no work pending or done if (EF.threadfunc) start_thread(EF.threadfunc,0); // start edit thread Frefresh++; mwpaint1(); // mwpaint1() not mwpaint2() return 1; } /**************************************************************************/ // suspend a parallel edit function so it can be resumed // edit dialog and curve edit are left active // logically the equivalent of edit_done() void edit_suspend() { wait_thread_idle(); // wait for thread to finish if (Fpreview && CEF->Fmod) { // preview image was edited Fzoom = 0; edit_fullsize(); // update full image } wrapup_thread(8); // tell thread to finish and exit mutex_lock(&Fpixmap_lock); // lock pixmaps if (CEF->Fmod) { // image was modified Fmodified++; // overall mod counter PXM_free(Fpxm16); Fpxm16 = E3pxm16; // E3 >> Fpxm16 v.11.07 E3pxm16 = 0; PXM_free(Fpxm8); Fpxm8 = PXM_convbpc(Fpxm16); // Fpxm16 >> Fpxm8 Fww = Fpxm8->ww; Fhh = Fpxm8->hh; Pundo++; // save next undo state Pumax = Pundo; save_undo(CEF->funcname); } PXM_free(E1pxm16); // free edit pixmaps PXM_free(E3pxm16); PXM_free(ERpxm16); // free redo copy E1ww = E3ww = ERww = 0; mutex_unlock(&Fpixmap_lock); CEF = 0; // no current edit func menulock(0); mwpaint2(); return; } /**************************************************************************/ // process edit cancel void edit_cancel(editfunc &EF) { if (edit_action) return; edit_action++; // stop reentry if (&EF == CEF) // current edit is canceled v.11.07 wrapup_thread(9); // tell thread to quit, wait if (EF.mousefunc == mouseCBfunc) // if my mouse, free mouse freeMouse(); if (EF.zd) zdialog_free(EF.zd); // kill dialog if (EF.curves) zfree(EF.curves); // free curves data EF.zd = 0; EF.curves = 0; if (&EF != CEF) { // inactive edit canceled v.11.07 edit_action = 0; return; } mutex_lock(&Fpixmap_lock); PXM_free(E1pxm16); // free edit pixmaps E1, E3 PXM_free(E3pxm16); PXM_free(ERpxm16); // free redo copy v.10.3 E1ww = E3ww = ERww = 0; mutex_unlock(&Fpixmap_lock); if (Fpreview) curr_image_time = get_seconds(); // mark time of file load v.11.07 Fzoom = 0; // v.11.07 CEF = 0; // no current edit func Fpreview = 0; // no preview mode menulock(0); // unlock menu mwpaint2(); // refresh window edit_action = 0; return; } /**************************************************************************/ // process edit dialog [done] // E3pxm16 >> Fpxm16 >> Fpxm8 void edit_done(editfunc &EF) { if (edit_action) return; edit_action++; // stop reentry if (&EF == CEF) { // current edit is done v.11.07 wait_thread_idle(); // wait for thread to finish if (Fpreview && CEF->Fmod) { // preview image was edited Fzoom = 0; edit_fullsize(); // update full image } wrapup_thread(8); // tell thread to finish and exit } if (EF.mousefunc == mouseCBfunc) // if my mouse, free mouse freeMouse(); if (EF.zd) zdialog_free(EF.zd); // kill dialog if (EF.curves) zfree(EF.curves); // free curves data EF.zd = 0; EF.curves = 0; if (&EF != CEF) { // inactive edit is done v.11.07 edit_action = 0; return; } mutex_lock(&Fpixmap_lock); if (CEF->Fmod) { // image was modified Fmodified++; // overall mod counter PXM_free(Fpxm16); Fpxm16 = E3pxm16; // E3 >> Fpxm16 v.11.07 E3pxm16 = 0; PXM_free(Fpxm8); Fpxm8 = PXM_convbpc(Fpxm16); // Fpxm16 >> Fpxm8 Fww = Fpxm8->ww; Fhh = Fpxm8->hh; Pundo++; Pumax = Pundo; save_undo(CEF->funcname); // save next undo state } PXM_free(E1pxm16); // free edit pixmaps PXM_free(E3pxm16); PXM_free(ERpxm16); // free redo copy v.10.3 E1ww = E3ww = ERww = 0; mutex_unlock(&Fpixmap_lock); CEF = 0; // no current edit func Fpreview = 0; // no preview mode menulock(0); // unlock menu mwpaint2(); // update window edit_action = 0; return; } /**************************************************************************/ // Setup for edit dialog event or curve edit. // Call this function before performing any image edit // (switch current edit function to caller's edit function). void edit_takeover(editfunc &EF) // v.11.07 { static int busy = 0; if (busy++) return; // KB key bounce if (CEF && &EF != CEF) { // edit function changed edit_setup(EF); // close old and setup new edit if (EF.zd) zdialog_send_event(EF.zd,"reset"); // reset dialog controls v.11.08 freeMouse(); // free mouse from old dialog v.11.08 } busy = 0; return; } /**************************************************************************/ // edit undo, redo, reset functions // these apply within an active edit function void edit_undo() { if (thread_status == 2) return; // thread busy if (! CEF->Fmod) return; // not modified if (edit_action) return; edit_action++; // stop reentry mutex_lock(&Fpixmap_lock); PXM_free(ERpxm16); // E3 >> redo copy ERpxm16 = E3pxm16; ERww = E3ww; ERhh = E3hh; E3pxm16 = PXM_copy(E1pxm16); // E1 >> E3 E3ww = E1ww; E3hh = E1hh; mutex_unlock(&Fpixmap_lock); CEF->Fmod = 0; // reset image modified status mwpaint2(); // refresh window edit_action = 0; return; } void edit_redo() { if (thread_status == 2) return; // thread busy if (! ERpxm16) return; // no prior undo if (edit_action) return; edit_action++; // stop reentry mutex_lock(&Fpixmap_lock); PXM_free(E3pxm16); // redo copy >> E3 E3pxm16 = ERpxm16; E3ww = ERww; E3hh = ERhh; ERpxm16 = 0; mutex_unlock(&Fpixmap_lock); CEF->Fmod = 1; // image modified Fmodified++; // overall mod counter mwpaint2(); edit_action = 0; return; } void edit_reset() { if (thread_status == 2) return; // thread busy if (! CEF->Fmod) return; // not modified if (edit_action) return; edit_action++; // stop reentry mutex_lock(&Fpixmap_lock); PXM_free(ERpxm16); // delete redo copy PXM_free(E3pxm16); E3pxm16 = PXM_copy(E1pxm16); // E1 >> E3 E3ww = E1ww; E3hh = E1hh; mutex_unlock(&Fpixmap_lock); CEF->Fmod = 0; // reset image modified status mwpaint2(); // refresh window edit_action = 0; return; } void edit_zapredo() { PXM_free(ERpxm16); // no redo copy return; } /**************************************************************************/ // Convert from preview mode (window-size pixmaps) to full-size pixmaps. // Can only be used when edit function is in an edit thread with idle_loop // This function is called directly from some edit functions void edit_fullsize() { mutex_lock(&Fpixmap_lock); PXM_free(E1pxm16); // free preview pixmaps PXM_free(E3pxm16); E1pxm16 = PXM_copy(Fpxm16); // make full-size pixmaps E3pxm16 = PXM_copy(Fpxm16); E1ww = E3ww = Fww; E1hh = E3hh = Fhh; mutex_unlock(&Fpixmap_lock); Fpreview = 0; Fzoom = 0; // v.11.07 curr_image_time = get_seconds(); // mark time of file load v.11.07 if (! CEF->Fmod) return; // no change signal_thread(); // signal thread, repeat edit wait_thread_idle(); return; } /************************************************************************** undo / redo toolbar buttons ***************************************************************************/ // [undo] menu function - reinstate previous edit in undo/redo stack void m_undo(GtkWidget *, cchar *) { if (CEF) { // undo active edit edit_undo(); // v.11.08 return; } if (Pundo == 0) return; // undo past edit if (! menulock(1)) return; Pundo--; if (KB_A_key) Pundo = 0; // if KB 'A' key, undo all v.11.11 load_undo(); Fmodified = Pundo; // v.11.08 menulock(0); return; } // [redo] menu function - reinstate next edit in undo/redo stack void m_redo(GtkWidget *, cchar *) { if (CEF) { // redo active edit edit_redo(); // v.11.08 return; } if (Pundo == Pumax) return; if (! menulock(1)) return; Pundo++; if (KB_A_key) Pundo = Pumax; // if KB 'A' key, redo all v.11.11 load_undo(); Fmodified = Pundo; // v.11.08 menulock(0); return; } // undo all edits of the current image // (discard modifications) void undo_all() // v.11.04 { if (! menulock(1)) return; Pundo = 0; // v.11.08 load_undo(); Fmodified = 0; // v.11.07 menulock(0); return; } // Save Fpxm16 to undo/redo file stack // stack position = Pundo void save_undo(cchar *funcname) { char *pp, buff[24]; int fid, cc, cc2; pp = strstr(undo_files,"_undo_"); if (! pp) zappcrash("undo/redo stack corrupted 1"); snprintf(pp+6,3,"%02d",Pundo); fid = open(undo_files,O_WRONLY|O_CREAT|O_TRUNC,0640); if (! fid) zappcrash("undo/redo stack corrupted 2"); snprintf(buff,24," %05d %05d fotoxx ",Fww,Fhh); cc = write(fid,buff,20); if (cc != 20) zappcrash("undo/redo stack corrupted 3"); cc = Fww * Fhh * 6; cc2 = write(fid,Fpxm16->bmp,cc); if (cc2 != cc) zappcrash("undo/redo stack corrupted 4"); close(fid); pvlist_replace(editlog,Pundo,funcname); // save log of edits done return; } // Load Fpxm16 from undo/redo file stack // stack position = Pundo void load_undo() { char *pp, buff[24], fotoxx[8]; int fid, ww, hh, cc, cc2; pp = strstr(undo_files,"_undo_"); if (! pp) zappcrash("undo/redo stack corrupted 1"); snprintf(pp+6,3,"%02d",Pundo); fid = open(undo_files,O_RDONLY); if (! fid) zappcrash("undo/redo stack corrupted 2"); *fotoxx = 0; cc = read(fid,buff,20); sscanf(buff," %d %d %8s ",&ww, &hh, fotoxx); if (! strEqu(fotoxx,"fotoxx")) zappcrash("undo/redo stack corrupted 4"); mutex_lock(&Fpixmap_lock); PXM_free(Fpxm16); Fpxm16 = PXM_make(ww,hh,16); cc = ww * hh * 6; cc2 = read(fid,Fpxm16->bmp,cc); if (cc2 != cc) zappcrash("undo/redo stack corrupted 5"); close(fid); PXM_free(Fpxm8); Fpxm8 = PXM_convbpc(Fpxm16); Fww = ww; Fhh = hh; if (sa_fww != Fww || sa_fhh != Fhh) // disable area if image size changes sa_disable(); // bugfix v.11.08 mutex_unlock(&Fpixmap_lock); mwpaint2(); return; } /**************************************************************************/ // ask user if modified image should be kept or discarded // returns: 0 = mods discarded, 1 = do not discard mods int mod_keep() { int keep = 0, choice = 0; cchar *title = ZTX("Discard edits?"); cchar *message = ZTX("This action will discard current edits.\n" // more clarity v.11.10 "Continue to discard edits.\n" "Go Back to keep edits."); cchar *continu = ZTX("Continue"); cchar *goback = ZTX("Go Back"); if (Fsaved < Pundo) keep = 1; // curr. edits not saved if (keep == 0) return 0; // no mods choice = zdialog_choose(title,mWin,message,continu,goback,null); if (choice == 2) return 1; // keep mods undo_all(); // discard mods return 0; } /**************************************************************************/ // menu lock/unlock - some functions must not run concurrently // returns 1 if success, else 0 int menulock(int lock) { if (! lock && ! Fmenulock) zappcrash("menu lock error"); if (lock && Fmenulock) { zmessageACK(mWin,ZTX("prior function still active")); // v.11.06 return 0; } if (lock) Fmenulock++; else Fmenulock--; return 1; } /**************************************************************************/ // check if Fsyncbusy is active, return 0 if not, // otherwise message user and return 1 int is_syncbusy() { if (! Fsyncbusy) return 0; threadmessage = "Synchronize files is running. Edits are blocked. \n" "You can still navigate and view images normally."; return 1; } /**************************************************************************/ // start thread that does the edit work void start_thread(threadfunc func, void *arg) { thread_status = 1; // thread is running thread_command = thread_pend = thread_done = thread_hiwater = 0; // nothing pending start_detached_thread(func,arg); return; } // signal thread that work is pending void signal_thread() { edit_zapredo(); // reset redo copy if (thread_status > 0) thread_pend++; return; } // wait for edit thread to complete pending work and become idle void wait_thread_idle() { while (thread_status && thread_pend > thread_done) { zmainloop(); zsleep(0.01); } return; } // wait for thread exit or command thread exit // command = 0 wait for normal completion // 8 finish pending work and exit // 9 quit, exit now void wrapup_thread(int command) { thread_command = command; // tell thread to quit or finish while (thread_status > 0) // wait for thread to finish { // pending work and exit zmainloop(); zsleep(0.01); } return; } // called only from edit threads // idle loop - wait for work request or exit command void thread_idle_loop() { if (thread_status == 2) Ffuncbusy--; // v.11.05 thread_status = 1; // status = idle thread_done = thread_hiwater; // work done = high-water mark while (true) { if (thread_command == 9) thread_exit(); // quit now command if (thread_command == 8) // finish work and exit if (thread_pend <= thread_done) thread_exit(); if (thread_pend > thread_done) break; // wait for work request zsleep(0.01); } thread_hiwater = thread_pend; // set high-water mark thread_status = 2; // thread is working Ffuncbusy++; // v.11.05 return; // perform edit } // exit thread unconditionally, called only from edit threads void thread_exit() { if (thread_status == 2) Ffuncbusy--; // v.11.05 thread_pend = thread_done = thread_hiwater = 0; thread_status = 0; pthread_exit(0); // "return" cannot be used here } /**************************************************************************/ // edit support functions for working threads (per processor core) void start_wthread(threadfunc func, void *arg) // start and increment busy count { zadd_locked(wthreads_busy,+1); zadd_locked(Ffuncbusy,+1); // v.11.01 start_detached_thread(func,arg); return; } void exit_wthread() // decrement busy count and exit { zadd_locked(Ffuncbusy,-1); // v.11.01 zadd_locked(wthreads_busy,-1); pthread_exit(0); // "return" cannot be used here v.9.4 } void wait_wthreads() // wait for all working threads done { // caller can be main() or a thread while (wthreads_busy) { zsleep(0.01); zmainloop(); // v.11.11.1 } return; } /************************************************************************** other support functions ***************************************************************************/ // help menu function void m_help(GtkWidget *, cchar *menu) { if (strEqu(menu,ZTX("About"))) zmessageACK(mWin,"%s \n%s \n%s \n%s \n%s \n%s", fversion,flicense,fhomepage,fcontact,fcredits,ftranslators); if (strEqu(menu,ZTX("User Guide"))) showz_userguide(); if (strEqu(menu,ZTX("User Guide Changes"))) showz_userguide("changes"); if (strEqu(menu,ZTX("Help"))) // toolbar button showz_userguide(zfuncs::F1_help_topic); // show topic if there, or page 1 if (strEqu(menu,"README")) showz_readme(); if (strEqu(menu,ZTX("Edit Functions Summary"))) // v.11.11 showz_doctext("edit-menus"); if (strEqu(menu,ZTX("Change Log"))) showz_changelog(); if (strEqu(menu,ZTX("Translations"))) showz_translations(); if (strEqu(menu,ZTX("Home Page"))) showz_html(fhomepage); return; } /**************************************************************************/ // table for loading and saving adjustable parameters between sessions typedef struct { char name[20]; char type[12]; int count; void *location; } param; #define Nparms 33 param paramTab[Nparms] = { // name type count location { "fotoxx version", "char", 1, &pversion }, { "last session", "char", 1, &last_session }, { "first time", "int", 1, &Ffirsttime }, { "new files found", "int", 1, &newfiles }, { "window geometry", "int", 4, &mwgeom }, { "toolbar style", "char", 1, &tbar_style }, { "warn overwrite", "int", 1, &Fwarnoverwrite }, { "zoom ratio", "char", 1, &zoomratio }, { "startup display", "char", 1, &startdisplay }, { "start image file", "char", 1, &startfile }, { "start directory", "char", 1, &startdirk }, { "lens mm and bow", "double", 2, &lens_settings }, { "trim size", "int", 2, &trimsize }, { "trim buttons", "char", 6, &trimbuttons }, { "trim ratios", "char", 6, &trimratios }, { "edit resize", "int", 2, &editresize }, { "batch resize", "int", 2, &batchresize }, { "e-mail resize", "int", 2, &emailsize }, { "annotate font", "char", 1, &annotate_font }, { "annotate text", "char", 1, &annotate_text }, { "annotate color", "char", 3, &annotate_color }, { "annotate trans", "int", 3, &annotate_trans }, { "annotate outline", "int", 1, &annotate_outline }, { "annotate angle", "double", 1, &annotate_angle }, { "grid spacing", "int", 2, &gridspace }, { "grid counts", "int", 2, &gridcount }, { "rotate grid", "int", 8, &rotate_grid }, { "unbend grid", "int", 8, &unbend_grid }, { "warp-curved grid", "int", 8, &warpC_grid }, { "warp-linear grid", "int", 8, &warpL_grid }, { "warp-affine grid", "int", 8, &warpF_grid }, { "slideshow trans", "int", SSNF, &ss_funcs }, { "slideshow music", "char", 1, &ss_musicfile } }; // save parameters to file /home//.fotoxx/parameters void save_params() // new v.10.9 { FILE *fid; char buff[1050], text[1000]; // limit for character data cc char *pp, *name, *type; int count; void *location; char **charloc; int *intloc; double *doubleloc; time_t currtime; pversion = strdupz(fversion); // this fotoxx version v.11.10 currtime = time(0); last_session = ctime(&currtime) + 4; // fotoxx session exit time v.11.11 if (last_session[4] == ' ') last_session[4] = '0'; // format mmm dd hh:mm:ss yyyy pp = strchr(last_session,'\n'); if (pp) *pp = 0; snprintf(buff,199,"%s/parameters",get_zuserdir()); // open output file fid = fopen(buff,"w"); if (! fid) return; for (int ii = 0; ii < Nparms; ii++) // write table of state data { name = paramTab[ii].name; type = paramTab[ii].type; count = paramTab[ii].count; location = paramTab[ii].location; charloc = (char **) location; intloc = (int *) location; doubleloc = (double *) location; fprintf(fid,"%-20s %-8s %02d ",name,type,count); // write parm name, type, count for (int kk = 0; kk < count; kk++) // write "value" "value" ... { if (strEqu(type,"char")) { if (! *charloc) printf("bad param data %s %d \n",name,kk); // bugfix v.10.11.1 if (! *charloc) break; repl_1str(*charloc++,text,"\n","\\n"); // replace newlines with "\n" v.10.11 fprintf(fid," \"%s\"",text); } if (strEqu(type,"int")) fprintf(fid," \"%d\"",*intloc++); if (strEqu(type,"double")) fprintf(fid," \"%.2f\"",*doubleloc++); } fprintf(fid,"\n"); // write EOR } fprintf(fid,"\n"); fclose(fid); // close file fid = fopen(recentfiles_file,"w"); // recent files file if (! fid) return; for (int ii = 0; ii < Nrecentfiles; ii++) // save list of recent files if (recentfiles[ii]) fprintf(fid,"%s \n",recentfiles[ii]); fclose(fid); snprintf(buff,199,"%s/plugins",get_zuserdir()); // open file for plugins v.11.03 fid = fopen(buff,"w"); if (! fid) return; for (int ii = 0; ii < Nplugins; ii++) // save plugins if (plugins[ii]) fprintf(fid,"%s \n",plugins[ii]); fclose(fid); return; } // load parameters from file /home//.fotoxx/parameters void load_params() // new v.10.9 { FILE *fid; int ii, err, cc, pcount, Idata; double Rdata; char buff[1000], text[1000], *pp; char name[20], type[12], count[8], data[1000]; void *location; char **charloc; int *intloc; double *doubleloc; struct stat statb; for (ii = 0; ii < Nparms; ii++) // set string parameters to "undefined" { // v.10.11 if (strNeq(paramTab[ii].type,"char")) continue; charloc = (char **) paramTab[ii].location; pcount = paramTab[ii].count; for (int jj = 0; jj < pcount; jj++) *charloc++ = strdupz("undefined",20); } snprintf(buff,499,"%s/parameters",get_zuserdir()); // open parameters file fid = fopen(buff,"r"); if (! fid) return; // none, defaults are used while (true) // read parameters { pp = fgets_trim(buff,999,fid,1); if (! pp) break; if (*pp == '#') continue; // comment v.10.10 if (strlen(pp) < 40) continue; // rubbish v.10.10 err = 0; strncpy0(name,pp,20); // parm name strTrim2(name); strncpy0(type,pp+22,8); // parm type strTrim2(type); strncpy0(count,pp+32,4); // parm count strTrim2(count); err = convSI(count,pcount); strncpy0(data,pp+38,1000); // parm value(s) strTrim2(data); for (ii = 0; ii < Nparms; ii++) // match file record to param table { if (strNeq(name,paramTab[ii].name)) continue; // parm name if (strNeq(type,paramTab[ii].type)) continue; // parm type if (paramTab[ii].count != pcount) continue; // parm count location = paramTab[ii].location; charloc = (char **) location; intloc = (int *) location; doubleloc = (double *) location; for (int kk = 1; kk <= pcount; kk++) { pp = (char *) strField(data,' ',kk); if (! pp) break; if (strEqu(type,"char")) { repl_1str(pp,text,"\\n","\n"); // replace "\n" with real newlines v.10.11 *charloc++ = strdupz(text,0,"parameters"); // v.11.04 } if (strEqu(type,"int")) { err = convSI(pp,Idata); if (err) continue; *intloc++ = Idata; } if (strEqu(type,"double")) { err = convSD(pp,Rdata); if (err) continue; *doubleloc++ = Rdata; } } } } fclose(fid); if (strNeq(pversion,fversion)) // fotoxx version change v.11.10 printf("new Fotoxx version %s %s \n",pversion,fversion); topdirk = 0; fid = fopen(topdirk_file,"r"); // set top directory from v.11.11 if (fid) { // from top directory file pp = fgets_trim(buff,499,fid,1); if (pp && *pp == '/') topdirk = strdupz(buff,0,"top_dirk"); fclose(fid); } if (topdirk) { // v.11.12.1 err = stat(topdirk,&statb); if (! err && S_ISDIR(statb.st_mode)) { cc = strlen(topdirk); // remove trailing '/' if present if (topdirk[cc-1] == '/') topdirk[cc-1] = 0; // v.11.12 } else topdirk = 0; // v.11.12.1 } for (ii = 0; ii < Nrecentfiles; ii++) // recent image file list = empty recentfiles[ii] = 0; fid = fopen(recentfiles_file,"r"); // open recent files file if (fid) { for (ii = 0; ii < Nrecentfiles; ii++) // read list of recent files { pp = fgets_trim(buff,499,fid,1); if (! pp) break; if (*pp == '/') recentfiles[ii] = strdupz(buff,0,"recentfile"); else ii--; // v.11.11 } fclose(fid); } for (ii = 0; ii < maxplugins; ii++) // plugins list = empty v.11.03 plugins[ii] = 0; plugins[0] = strdupz("Gimp = gimp"); // if empty, default Gimp plugin Nplugins = 1; snprintf(buff,499,"%s/plugins",get_zuserdir()); // open plugins file v.11.03 fid = fopen(buff,"r"); if (fid) { for (ii = 0; ii < maxplugins; ii++) // read list of plugins { pp = fgets_trim(buff,499,fid,1); if (! pp) break; plugins[ii] = strdupz(buff,0,"plugins"); } fclose(fid); Nplugins = ii; } return; } /**************************************************************************/ // Compute the mean brightness of all pixel neighborhoods, // new v.9.6 // using a Guassian or a flat distribution for the weightings. // If a select area is active, only inside pixels are calculated. // The flat method is 10-100x faster. int brhood_radius; double brhood_kernel[200][200]; // up to radius = 99 float *brhood_brightness = 0; // neighborhood brightness per pixel char brhood_method; // g = gaussian, f = flat distribution void brhood_calc(int radius, char method) { void * brhood_wthread(void *arg); int rad, rad2, dx, dy, cc, ii; double kern; brhood_radius = radius; brhood_method = method; if (brhood_method == 'g') // compute Gaussian kernel { // (not currently used v.11.02) rad = brhood_radius; rad2 = rad * rad; for (dy = -rad; dy <= rad; dy++) for (dx = -rad; dx <= rad; dx++) { if (dx*dx + dy*dy <= rad2) // cells within radius kern = exp( - (dx*dx + dy*dy) / rad2); else kern = 0; // outside radius brhood_kernel[dy+rad][dx+rad] = kern; } } if (brhood_brightness) zfree(brhood_brightness); // allocate memory for pixel map cc = E1ww * E1hh * sizeof(float); brhood_brightness = (float *) zmalloc(cc,"brhood"); memset(brhood_brightness,0,cc); if (Factivearea) SB_goal = sa_Npixel; // set up progress tracking else SB_goal = E1ww * E1hh; SB_done = 0; // v.11.06 for (ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(brhood_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion SB_goal = 0; return; } // worker thread function void * brhood_wthread(void *arg) { int index = *((int *) arg); int rad = brhood_radius; int ii, px, py, qx, qy, Fstart; double kern, bsum, bsamp, bmean; uint16 *pixel; if (brhood_method == 'g') // use round gaussian distribution { for (py = index; py < E1hh; py += Nwt) for (px = 0; px < E1ww; px++) { if (Factivearea && sa_mode != 7) { // select area, not whole image v.11.02 ii = py * E1ww + px; // use only inside pixels if (! sa_pixmap[ii]) continue; } bsum = bsamp = 0; for (qy = py-rad; qy <= py+rad; qy++) // computed weighted sum of brightness for (qx = px-rad; qx <= px+rad; qx++) // for pixels in neighborhood { if (qy < 0 || qy > E1hh-1) continue; if (qx < 0 || qx > E1ww-1) continue; kern = brhood_kernel[qy+rad-py][qx+rad-px]; pixel = PXMpix(E1pxm16,qx,qy); bsum += pixbright(pixel) * kern; // sum brightness * weight bsamp += kern; // sum weights } bmean = bsum / bsamp; // mean brightness ii = py * E1ww + px; brhood_brightness[ii] = bmean; // pixel value SB_done++; // track progress v.11.06 if (drandz() < 0.0001) zsleep(0.001); // trigger sorry kernel scheduler } } if (brhood_method == 'f') // use square flat distribution { Fstart = 1; bsum = bsamp = 0; for (py = index; py < E1hh; py += Nwt) for (px = 0; px < E1ww; px++) { if (Factivearea && sa_mode != 7) { // select area, not whole image v.11.02 ii = py * E1ww + px; // compute only inside pixels if (! sa_pixmap[ii]) { Fstart = 1; continue; } } if (px == 0) Fstart = 1; if (Fstart) { Fstart = 0; bsum = bsamp = 0; for (qy = py-rad; qy <= py+rad; qy++) // add up all columns for (qx = px-rad; qx <= px+rad; qx++) { if (qy < 0 || qy > E1hh-1) continue; if (qx < 0 || qx > E1ww-1) continue; pixel = PXMpix(E1pxm16,qx,qy); bsum += pixbright(pixel); bsamp += 1; } } else { qx = px-rad-1; // subtract first-1 column if (qx >= 0) { for (qy = py-rad; qy <= py+rad; qy++) { if (qy < 0 || qy > E1hh-1) continue; pixel = PXMpix(E1pxm16,qx,qy); bsum -= pixbright(pixel); bsamp -= 1; } } qx = px+rad; // add last column if (qx < E1ww) { for (qy = py-rad; qy <= py+rad; qy++) { if (qy < 0 || qy > E1hh-1) continue; pixel = PXMpix(E1pxm16,qx,qy); bsum += pixbright(pixel); bsamp += 1; } } } bmean = bsum / bsamp; // mean brightness ii = py * E1ww + px; brhood_brightness[ii] = bmean; SB_done++; // track progress v.11.06 if (drandz() < 0.0001) zsleep(0.001); // trigger sorry kernel scheduler } } exit_wthread(); return 0; // not executed, avoid gcc warning } // get the neighborhood brightness for given pixel float get_brhood(int px, int py) { int ii = py * E1ww + px; return brhood_brightness[ii]; } /**************************************************************************/ // free all resources associated with the current image file void free_resources(int fkeepundo) { char *pp; int err; mutex_lock(&Fpixmap_lock); // lock pixmaps if (! fkeepundo) { strcpy(command,"rm -f "); // delete all undo files strcat(command,undo_files); pp = strstr(command,"_undo_"); // /home/user/.fotoxx/pppppp_undo_* strcpy(pp + 6,"*"); err = system(command); if (err) printf("error: %s \n",wstrerror(err)); Fmodified = Pundo = Pumax = Fsaved = 0; // reset undo/redo stack } if (Fshutdown) { // stop here if shutdown mode mutex_unlock(&Fpixmap_lock); return; } Ntoplines = Nptoplines; // no image overlay lines freeMouse(); // free mouse v.11.04 if (curr_file) { sa_unselect(); // unselect select area zdialog_free(zdsela); // kill dialogs if active zfree(curr_file); // free image file curr_file = 0; SB_goal = 0; // v.9.2 *SB_text = 0; // v.10.7 } if (brhood_brightness) zfree(brhood_brightness); // free brightness map v.9.6 brhood_brightness = 0; PXM_free(Fpxm8); PXM_free(Dpxm8); PXM_free(Fpxm16); PXM_free(E1pxm16); PXM_free(E3pxm16); PXM_free(ERpxm16); // v.10.3 Fww = E1ww = E3ww = Dww = 0; // make unusable (crash) mutex_unlock(&Fpixmap_lock); return; } // Get a virtual pixel at location (px,py) (real) in an PXM-16 pixmap. // Get the overlapping real pixels and build a composite. int vpixel(PXM *pxm, double px, double py, uint16 *vpix) { int ww, hh, px0, py0; uint16 *ppix, *pix0, *pix1, *pix2, *pix3; double f0, f1, f2, f3; double red, green, blue; ww = pxm->ww; hh = pxm->hh; ppix = (uint16 *) pxm->bmp; px0 = px; // pixel containing (px,py) py0 = py; if (px0 < 1 || py0 < 1) return 0; // void edge pixels if (px0 > ww-3 || py0 > hh-3) return 0; pix0 = ppix + (py0 * ww + px0) * 3; // 4 pixels based at (px0,py0) pix1 = pix0 + ww * 3; pix2 = pix0 + 3; pix3 = pix0 + ww * 3 + 3; f0 = (px0+1 - px) * (py0+1 - py); // overlap of (px,py) f1 = (px0+1 - px) * (py - py0); // in each of the 4 pixels f2 = (px - px0) * (py0+1 - py); f3 = (px - px0) * (py - py0); red = f0 * pix0[0] + f1 * pix1[0] + f2 * pix2[0] + f3 * pix3[0]; // sum the weighted inputs green = f0 * pix0[1] + f1 * pix1[1] + f2 * pix2[1] + f3 * pix3[1]; blue = f0 * pix0[2] + f1 * pix1[2] + f2 * pix2[2] + f3 * pix3[2]; vpix[0] = red; vpix[1] = green; vpix[2] = blue; if (blue < 1) { // v.10.7 if (blue < 0.9) return 0; // near edge or voided area vpix[2] = 1; // avoid 0.999 to integer 0 } return 1; } // compare two doubles for significant difference // return: 0 difference not significant // +1 d1 > d2 // -1 d1 < d2 int sigdiff(double d1, double d2, double signf) { double diff = fabs(d1-d2); if (diff == 0.0) return 0; diff = diff / (fabs(d1) + fabs(d2)); if (diff < signf) return 0; if (d1 > d2) return 1; else return -1; } /************************************************************************** file read and write utilities PXM pixmap <--> file on disk ***************************************************************************/ // Load an image file into an PXM pixmap of 8 or 16 bits/color // Also sets the following file scope variables: // f_load_type = "jpg" "tif" "png" or "other" // f_load_bpc = disk file bits per color = 1/8/16 // f_load_size = disk file size PXM * f_load(cchar *filespec, int bpc) // use pixbuf or tiff library v.9.8 { int err; cchar *pext; PXM *pxm1, *pxm2; struct stat fstat; if (bpc != 8 && bpc != 16) // requested bpc must be 8 or 16 zappcrash("image_load bpc: %d",bpc); err = stat(filespec,&fstat); if (err) return 0; // file not found if (! S_ISREG(fstat.st_mode)) return 0; // not a regular file if (image_file_type(filespec) != 2) return 0; // not a supported image type f_load_size = fstat.st_size; // disk file bytes pext = strrchr(filespec,'/'); if (! pext) pext = filespec; if (pext > filespec+12 && strnEqu(pext-12,"/.thumbnails/",13)) { // refuse thumbnail files v.10.0 zmessageACK(mWin,ZTX("cannot open thumbnail file")); return 0; } pext = strrchr(pext,'.'); if (! pext) pext = ""; if (strstr(".jpg .jpeg .JPG .JPEG",pext)) strcpy(f_load_type,"jpg"); else if (strstr(".tif .tiff .TIF .TIFF",pext)) strcpy(f_load_type,"tif"); else if (strstr(".png .PNG",pext)) strcpy(f_load_type,"png"); else strcpy(f_load_type,"other"); if (strEqu(f_load_type,"tif")) // use tiff lib to read tiff file pxm1 = TIFFread(filespec); else pxm1 = PXBread(filespec); // use pixbuf lib for others if (! pxm1) return 0; // both set f_load_bpc = file bpc if (pxm1->bpc != bpc) { pxm2 = PXM_convbpc(pxm1); // convert to requested bpc PXM_free(pxm1); // 8 <--> 16 pxm1 = pxm2; } // auto upright image removed v.10.12 return pxm1; } /**************************************************************************/ // save current image to specified disk file (same or new). // set f_save_type, f_save_bpc, f_save_size // update search index file // return 0 if OK, else +N int f_save(char *outfile, cchar *type, int bpc) // use pixbuf or tiff library v.9.8 { PXM *pxm16; cchar *exifkey[2] = { exif_orientation_key, iptc_editlog_key }; cchar *exifdata[2]; char **ppv, funcslist[1000]; char *pp, *tempfile, *pext; int nkeys, err = 1, cc1, cc2; struct stat fstat; if ((bpc != 8 && bpc != 16) || ! strstr("jpg tif png",type)) // check args zappcrash("f_save: %s %d",type,bpc); Ffuncbusy++; // v.11.01 pext = strrchr(outfile,'/'); // force compatible file extension if (pext) pext = strrchr(pext,'.'); // if not already if (! pext) pext = outfile + strlen(outfile); if (strEqu(type,"jpg") && ! strstr(".jpg .JPG .jpeg .JPEG",pext)) strcpy(pext,".jpg"); if (strEqu(type,"png") && ! strstr(".png .PNG",pext)) strcpy(pext,".png"); if (strEqu(type,"tif") && ! strstr(".tif .TIF .tiff .TIFF",pext)) strcpy(pext,".tif"); tempfile = strdupz(get_zuserdir(),24,"f_save"); // use temp output file strcat(tempfile,"/temp_"); // ~/.fotoxx/temp_ppppp.ext strcat(tempfile,PIDstring); strcat(tempfile,"."); strcat(tempfile,type); if (strEqu(type,"png")) { // save as PNG file (bpc = 8 always) if (Fpxm16) err = PXBwrite(Fpxm16,tempfile); else err = PXBwrite(Fpxm8,tempfile); bpc = 8; } else if (strEqu(type,"tif")) { // save as tiff file if (bpc == 8) { if (Fpxm16) { PXM_free(Fpxm8); // bugfix v.10.8 Fpxm8 = PXM_convbpc(Fpxm16); } err = TIFFwrite(Fpxm8,tempfile); } else if (bpc == 16) { if (Fpxm16) err = TIFFwrite(Fpxm16,tempfile); // edit file exists, use it else { if (curr_file_bpc == 16) pxm16 = TIFFread(curr_file); // use original 16 bpc file else pxm16 = PXM_convbpc(Fpxm8); // or convert 8 to 16 bpc if (! pxm16) err = 1; else { err = TIFFwrite(pxm16,tempfile); PXM_free(pxm16); } } } } else { // save as JPEG file (bpc = 8 always) if (Fpxm16) err = PXBwrite(Fpxm16,tempfile); else err = PXBwrite(Fpxm8,tempfile); bpc = 8; } if (err) { remove(tempfile); // failure, clean up v.11.02 zfree(tempfile); Ffuncbusy--; return 1; } exifdata[0] = ""; // EXIF orientation = upright nkeys = 1; // remove old width, height v.10.8 if (Pundo > 0) // if edits were made, { // update relevant EXIF key v.10.2 *funcslist = 0; ppv = info_get(curr_file,&exifkey[1],1); // get existing list of edits if (ppv[0]) { strncpy0(funcslist,ppv[0],998); zfree(ppv[0]); } cc1 = strlen(funcslist); // add blank if (cc1 && funcslist[cc1-1] != ' ') { strcpy(funcslist+cc1," "); cc1++; } for (int ii = 1; ii <= Pundo; ii++) // append new list of edits { // (omit index 0 = initial) pp = pvlist_get(editlog,ii); cc2 = strlen(pp); if (cc1 + cc2 > 998) break; strcpy(funcslist+cc1,pp); strcpy(funcslist+cc1+cc2," "); cc1 += cc2 + 1; } exifdata[1] = funcslist; // IPTC edit history key, fotoxx edits done nkeys = 2; } err = stat(curr_file,&fstat); if (! err && S_ISREG(fstat.st_mode)) { // if current file exists, v.11.05 err = info_copy(curr_file,tempfile,exifkey,exifdata,nkeys); // copy all EXIF/IPTC data to if (err) zmessageACK(mWin,"Unable to copy EXIF/IPTC"); // temp file with above revisions } snprintf(command,ccc,"cp -f \"%s\" \"%s\" ",tempfile,outfile); // copy temp file to output file err = system(command); if (err) zmessageACK(mWin,"Unable to save image: %s",wstrerror(err)); remove(tempfile); // delete temp file v.11.02 zfree(tempfile); save_fileinfo(outfile); // save tag changes if any if (! curr_file || strNeq(outfile,curr_file)) // if save to new file, v.11.08 update_search_index(outfile); // update search index file Fsaved = Pundo; // update which mods are saved to disk add_recent_file(outfile); // first in recent files list strcpy(f_save_type,type); // update f_save_xxx data f_save_bpc = bpc; err = stat(outfile,&fstat); if (err) { Ffuncbusy--; return 1; } f_save_size = fstat.st_size; Ffuncbusy--; mwpaint2(); // v.11.03 return 0; } /**************************************************************************/ // intercept TIFF warning messages (many) // new v.9.8 void tiffwarninghandler(cchar *module, cchar *format, va_list ap) { return; // stop flood of crap char message[200]; vsnprintf(message,199,format,ap); printf("TIFF warning: %s %s \n",module,message); return; } // Read from TIFF file using TIFF library. // Use native TIFF file bits/pixel. PXM * TIFFread(cchar *filespec) // overhauled v.10.8.1 { static int ftf = 1; TIFF *tiff; PXM *pxm; char *tiffbuff; uint8 *tiff8, *pxm8; uint16 *tiff16, *pxm16; uint16 bpc, nch, fmt; int ww, hh, rps, stb, nst; // int not uint v.11.03 int tiffstat, row, col, strip, cc; if (ftf) { TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages ftf = 0; } tiff = TIFFOpen(filespec,"r"); if (! tiff) { zmessageACK(mWin,ZTX("TIFF open failure")); return 0; } TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &ww); // width TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &hh); // height TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bpc); // bits per color, 1/8/16 TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &nch); // no. channels (colors), 1/3/4 TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rps); // rows per strip TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &fmt); // data format stb = TIFFStripSize(tiff); // strip size nst = TIFFNumberOfStrips(tiff); // number of strips // printf("ww %d hh %d nch %d bpc %d rps %d stb %d nst %d fmt %d \n",ww,hh,nch,bpc,rps,stb,nst,fmt); if (! (bpc <= 8 || bpc == 16)) { // check for supported bits/color zmessageACK(mWin,ZTX("TIFF bits/color=%d not supported"),bpc); TIFFClose(tiff); return 0; } f_load_bpc = bpc; // for f_load(), file bpc 1/8/16 v.10.12 if (bpc <= 8) // use universal TIFF reader { // if bits/color <= 8 tiffbuff = zmalloc(ww*hh*4,"tiffbuff"); tiffstat = TIFFReadRGBAImage(tiff, ww, hh, (uint *) tiffbuff, 0); TIFFClose(tiff); if (tiffstat != 1) { zmessageACK(mWin,ZTX("TIFF read failure")); zfree(tiffbuff); return 0; } pxm = PXM_make(ww,hh,8); tiff8 = (uint8 *) tiffbuff; for (row = 0; row < hh; row++) // convert RGBA to RGB { pxm8 = (uint8 *) pxm->bmp; pxm8 += (hh-1 - row) * ww * 3; for (col = 0; col < ww; col++) { pxm8[0] = tiff8[0]; pxm8[1] = tiff8[1]; pxm8[2] = tiff8[2]; pxm8 += 3; tiff8 += 4; } } zfree(tiffbuff); return pxm; } // 16 bits per color stb += 1000000; // reduce risk of crash v.10.8.2 tiffbuff = zmalloc(stb,"tiffbuff"); // read encoded strips pxm = PXM_make(ww,hh,16); for (strip = 0; strip < nst; strip++) { cc = TIFFReadEncodedStrip(tiff,strip,tiffbuff,stb); if (cc < 0) { zmessageACK(mWin,ZTX("TIFF read failure")); TIFFClose(tiff); zfree(tiffbuff); PXM_free(pxm); return 0; } if (cc == 0) break; tiff16 = (uint16 *) tiffbuff; pxm16 = (uint16 *) pxm->bmp; row = strip * rps; pxm16 += row * ww * 3; while (cc >= 6) // bugfix v.11.03 { pxm16[0] = tiff16[0]; pxm16[1] = tiff16[1]; pxm16[2] = tiff16[2]; pxm16 += 3; tiff16 += nch; cc -= nch * 2; } } TIFFClose(tiff); zfree(tiffbuff); return pxm; } // Write to TIFF file using TIFF library. // File bpc is taken from PXM (8 or 16). // returns 0 if OK, +N if error. int TIFFwrite(PXM *pxm, cchar *filespec) // new v.9.8 { static int ftf = 1; TIFF *tiff; uint8 *tiff8, *pxm8; uint16 *tiff16, *pxm16; int tiffstat = 0; int ww, hh, row, col, rowcc; // int not uint v.11.03 int bpc, nch, pm = 2, pc = 1, comp = 5; char *tiffbuff; if (ftf) { TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages ftf = 0; } tiff = TIFFOpen(filespec,"w"); if (! tiff) { zmessageACK(mWin,ZTX("TIFF open failure")); return 1; } ww = pxm->ww; hh = pxm->hh; bpc = pxm->bpc; nch = 3; // alpha channel removed TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, ww); TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bpc); TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, nch); TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, pm); // RGB TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, pc); TIFFSetField(tiff, TIFFTAG_COMPRESSION, comp); // LZW rowcc = TIFFScanlineSize(tiff); tiffbuff = (char*) zmalloc(rowcc,"tiffbuff"); for (row = 0; row < hh; row++) { if (bpc == 8) { tiff8 = (uint8 *) tiffbuff; pxm8 = (uint8 *) pxm->bmp + row * ww * 3; for (col = 0; col < ww; col++) { tiff8[0] = pxm8[0]; tiff8[1] = pxm8[1]; tiff8[2] = pxm8[2]; pxm8 += 3; tiff8 += nch; } } if (bpc == 16) { tiff16 = (uint16 *) tiffbuff; pxm16 = (uint16 *) pxm->bmp + row * ww * 3; for (col = 0; col < ww; col++) { tiff16[0] = pxm16[0]; tiff16[1] = pxm16[1]; tiff16[2] = pxm16[2]; pxm16 += 3; tiff16 += nch; } } tiffstat = TIFFWriteScanline(tiff,tiffbuff,row,0); if (tiffstat != 1) break; } TIFFClose(tiff); zfree(tiffbuff); if (tiffstat == 1) return 0; zmessageACK(mWin,ZTX("TIFF write failure")); return 2; } /**************************************************************************/ // Read from jpeg/png file using pixbuf library. bpc = 8. PXM * PXBread(cchar *filespec) // new v.9.8 { GError *gerror = 0; PXB *pxb; PXM *pxm; int ww, hh, px, py, nch, rowst; uint8 *bmp1, *bmp2, *pix1, *pix2; pxb = gdk_pixbuf_new_from_file(filespec,&gerror); if (! pxb) { printf("%s \n",gerror->message); // v.10.8 zmessageACK(mWin,ZTX("file type not supported")); return 0; } ww = gdk_pixbuf_get_width(pxb); hh = gdk_pixbuf_get_height(pxb); nch = gdk_pixbuf_get_n_channels(pxb); rowst = gdk_pixbuf_get_rowstride(pxb); bmp1 = gdk_pixbuf_get_pixels(pxb); pxm = PXM_make(ww,hh,8); bmp2 = (uint8 *) pxm->bmp; for (py = 0; py < hh; py++) { pix1 = bmp1 + rowst * py; pix2 = bmp2 + py * ww * 3; for (px = 0; px < ww; px++) { pix2[0] = pix1[0]; pix2[1] = pix1[1]; pix2[2] = pix1[2]; pix1 += nch; pix2 += 3; } } f_load_bpc = 8; // file bits per color for f_load() g_object_unref(pxb); // (any value on disk becomes 8) return pxm; } // Write to jpeg/png file using pixbuf library. bpc = 8. // returns 0 if OK, +N if error. int PXBwrite(PXM *pxm, cchar *filespec) // new v.9.8 { int ww, hh, bpc, px, py, rowst; uint8 *bmp8, *pix8, *bmp2, *pix2; uint16 *bmp16, *pix16; PXB *pxb; cchar *pext; GError *gerror = 0; int pxbstat; ww = pxm->ww; hh = pxm->hh; bpc = pxm->bpc; pxb = gdk_pixbuf_new(RGBCOLOR,0,8,ww,hh); if (! pxb) zappcrash("pixbuf allocation failure"); bmp8 = (uint8 *) pxm->bmp; bmp16 = (uint16 *) pxm->bmp; bmp2 = gdk_pixbuf_get_pixels(pxb); rowst = gdk_pixbuf_get_rowstride(pxb); if (bpc == 8) { for (py = 0; py < hh; py++) { pix8 = bmp8 + py * ww * 3; pix2 = bmp2 + rowst * py; for (px = 0; px < ww; px++) { pix2[0] = pix8[0]; pix2[1] = pix8[1]; pix2[2] = pix8[2]; pix2 += 3; pix8 += 3; } } } if (bpc == 16) { for (py = 0; py < hh; py++) { pix16 = bmp16 + py * ww * 3; pix2 = bmp2 + rowst * py; for (px = 0; px < ww; px++) { pix2[0] = pix16[0] >> 8; pix2[1] = pix16[1] >> 8; pix2[2] = pix16[2] >> 8; pix2 += 3; pix16 += 3; } } } pext = strrchr(filespec,'/'); if (! pext) pext = filespec; pext = strrchr(pext,'.'); if (! pext) pext = ""; if (strstr(".png .PNG",pext)) pxbstat = gdk_pixbuf_save(pxb,filespec,"png",&gerror,null); else pxbstat = gdk_pixbuf_save(pxb,filespec,"jpeg",&gerror,"quality",jpeg_quality,null); g_object_unref(pxb); if (pxbstat) return 0; printf("%s \n",gerror->message); // v.10.8 zmessageACK(mWin,ZTX("pixbuf write failure")); return 1; } /************************************************************************** PXM pixmap conversion and rescale functions ***************************************************************************/ // initialize PXM pixmap - allocate memory PXM * PXM_make(int ww, int hh, int bpc) { if (ww < 1 || hh < 1 || (bpc != 8 && bpc != 16)) zappcrash("PXM_make() %d %d %d",ww,hh,bpc); PXM *pxm = (PXM *) zmalloc(sizeof(PXM),"PXM"); pxm->ww = ww; pxm->hh = hh; pxm->bpc = bpc; if (bpc == 8) pxm->bmp = zmalloc(ww*hh*3,"PXM.bmp"); if (bpc == 16) pxm->bmp = zmalloc(ww*hh*6,"PXM.bmp"); strcpy(pxm->wmi,"rgbrgb"); return pxm; } // free PXM pixmap void PXM_free(PXM *&pxm) { if (! pxm) return; if (! strEqu(pxm->wmi,"rgbrgb")) zappcrash("PXM_free(), bad PXM"); strcpy(pxm->wmi,"xxxxxx"); zfree(pxm->bmp); zfree(pxm); pxm = 0; // v.11.01 return; } // create a copy of an PXM pixmap PXM * PXM_copy(PXM *pxm1) { int cc; PXM *pxm2; pxm2 = PXM_make(pxm1->ww, pxm1->hh, pxm1->bpc); cc = pxm1->ww * pxm1->hh * (pxm1->bpc / 8 * 3); memcpy(pxm2->bmp,pxm1->bmp,cc); return pxm2; } // create a copy of an PXM area PXM * PXM_copy_area(PXM *pxm1, int orgx, int orgy, int ww2, int hh2) { uint8 *bmp1, *pix1, *bmp2, *pix2; uint16 *bmp3, *pix3, *bmp4, *pix4; PXM *pxm2 = 0; int ww1, bpc, px1, py1, px2, py2; ww1 = pxm1->ww; bpc = pxm1->bpc; if (bpc == 8) { pxm2 = PXM_make(ww2,hh2,8); bmp1 = (uint8 *) pxm1->bmp; bmp2 = (uint8 *) pxm2->bmp; for (py1 = orgy, py2 = 0; py2 < hh2; py1++, py2++) { for (px1 = orgx, px2 = 0; px2 < ww2; px1++, px2++) { pix1 = bmp1 + (py1 * ww1 + px1) * 3; pix2 = bmp2 + (py2 * ww2 + px2) * 3; pix2[0] = pix1[0]; pix2[1] = pix1[1]; pix2[2] = pix1[2]; pix1 += 3; pix2 += 3; } } } if (bpc == 16) { pxm2 = PXM_make(ww2,hh2,16); bmp3 = (uint16 *) pxm1->bmp; bmp4 = (uint16 *) pxm2->bmp; for (py1 = orgy, py2 = 0; py2 < hh2; py1++, py2++) { for (px1 = orgx, px2 = 0; px2 < ww2; px1++, px2++) { pix3 = bmp3 + (py1 * ww1 + px1) * 3; pix4 = bmp4 + (py2 * ww2 + px2) * 3; pix4[0] = pix3[0]; pix4[1] = pix3[1]; pix4[2] = pix3[2]; pix3 += 3; pix4 += 3; } } } return pxm2; } // convert PXM pixmap from 8/16 to 16/8 bits per color PXM * PXM_convbpc(PXM *pxm1) { uint8 *bmp8, *pix8; uint16 *bmp16, *pix16; PXM *pxm2 = 0; int ww, hh, bpc, px, py; ww = pxm1->ww; hh = pxm1->hh; bpc = pxm1->bpc; if (bpc == 8) // 8 > 16 { pxm2 = PXM_make(ww,hh,16); bmp8 = (uint8 *) pxm1->bmp; bmp16 = (uint16 *) pxm2->bmp; for (py = 0; py < hh; py++) { pix8 = bmp8 + py * ww * 3; pix16 = bmp16 + py * ww * 3; for (px = 0; px < ww; px++) { pix16[0] = pix8[0] << 8; pix16[1] = pix8[1] << 8; pix16[2] = pix8[2] << 8; pix8 += 3; pix16 += 3; } } } if (bpc == 16) // 16 > 8 { pxm2 = PXM_make(ww,hh,8); bmp8 = (uint8 *) pxm2->bmp; bmp16 = (uint16 *) pxm1->bmp; for (py = 0; py < hh; py++) { pix8 = bmp8 + py * ww * 3; pix16 = bmp16 + py * ww * 3; for (px = 0; px < ww; px++) { pix8[0] = pix16[0] >> 8; pix8[1] = pix16[1] >> 8; pix8[2] = pix16[2] >> 8; pix8 += 3; pix16 += 3; } } } return pxm2; } // replace blue = 0 pixels with blue = 2 in a 16-bit pixmap // (blue = 0 reserved for pixels voided by warp or overlay offsets) // all callers of vpixel() need to do this // needs about 0.013 seconds for 10 megapixel image and 3.3 GHz processor void PXM_fixblue(PXM *pxm) // v.11.07 { int size; uint16 *pixel, *pixel0, *pixelN; size = pxm->ww * pxm->hh * 3; pixel0 = (uint16 *) pxm->bmp + 2; pixelN = (uint16 *) pixel0 + size; for (pixel = pixel0; pixel < pixelN; pixel += 3) // +3 is +6 bytes if (! *pixel) *pixel = 2; return; } // rescale PXM pixmap to size ww2 x hh2 PXM * PXM_rescale(PXM *pxm1, int ww2, int hh2) { void bmp8_rescale(uint8*, uint8*, int, int, int, int); void bmp16_rescale(uint16*, uint16*, int, int, int, int); PXM *pxm2; int ww1, hh1, bpc; uint8 *bmp1, *bmp2; uint16 *bmp3, *bmp4; ww1 = pxm1->ww; hh1 = pxm1->hh; bpc = pxm1->bpc; pxm2 = PXM_make(ww2,hh2,bpc); if (bpc == 8) { bmp1 = (uint8 *) pxm1->bmp; bmp2 = (uint8 *) pxm2->bmp; bmp8_rescale(bmp1,bmp2,ww1,hh1,ww2,hh2); } if (bpc == 16) { bmp3 = (uint16 *) pxm1->bmp; bmp4 = (uint16 *) pxm2->bmp; bmp16_rescale(bmp3,bmp4,ww1,hh1,ww2,hh2); } return pxm2; } /************************************************************************** Rescale 8 bpc image (3 x 8 bits per color) to new width and height. The scale ratios may be different for width and height. Method: The input and output images are overlayed, stretching or shrinking the output pixels as needed. The contribution of each input pixel overlapping an output pixel is proportional to the area of the output pixel covered by the input pixel. The contributions of all overlaping input pixels are added. The work is spread among Nwt threads to reduce the elapsed time on modern computers having multiple SMP processors. Example: if the output image is 40% of the input image, then: outpix[0,0] = 0.16 * inpix[0,0] + 0.16 * inpix[1,0] + 0.08 * inpix[2,0] + 0.16 * inpix[0,1] + 0.16 * inpix[1,1] + 0.08 * inpix[2,1] + 0.08 * inpix[0,2] + 0.08 * inpix[1,2] + 0.04 * inpix[2,2] *********/ namespace bmp8rescale { // data for threads uint8 *pixmap1; uint8 *pixmap2; int ww1; int hh1; int ww2; int hh2; int *px1L; int *py1L; double *pxmap; double *pymap; int maxmapx; int maxmapy; int busy[max_threads]; } void bmp8_rescale(uint8 *pixmap1x, uint8 *pixmap2x, int ww1x, int hh1x, int ww2x, int hh2x) { using namespace bmp8rescale; void * bmp8_rescale_thread(void *arg); int px1, py1, px2, py2; int pxl, pyl, pxm, pym, ii; double scalex, scaley; double px1a, py1a, px1b, py1b; double fx, fy; pixmap1 = pixmap1x; pixmap2 = pixmap2x; ww1 = ww1x; hh1 = hh1x; ww2 = ww2x; hh2 = hh2x; memset(pixmap2, 0, ww2 * hh2 * 3 * sizeof(uint8)); // clear output pixmap scalex = 1.0 * ww1 / ww2; // compute x and y scales scaley = 1.0 * hh1 / hh2; if (scalex <= 1) maxmapx = 2; // compute max input pixels else maxmapx = scalex + 2; // mapping into output pixels maxmapx += 1; // for both dimensions if (scaley <= 1) maxmapy = 2; // (pixels may not be square) else maxmapy = scaley + 2; maxmapy += 1; pymap = (double *) zmalloc(hh2 * maxmapy * sizeof(double)); // maps overlap of < maxmap input pxmap = (double *) zmalloc(ww2 * maxmapx * sizeof(double)); // pixels per output pixel py1L = (int *) zmalloc(hh2 * sizeof(int)); // maps first (lowest) input pixel px1L = (int *) zmalloc(ww2 * sizeof(int)); // per output pixel for (py2 = 0; py2 < hh2; py2++) // loop output y-pixels { py1a = py2 * scaley; // corresponding input y-pixels py1b = py1a + scaley; if (py1b >= hh1) py1b = hh1 - 0.001; // fix precision limitation pyl = py1a; py1L[py2] = pyl; // 1st overlapping input pixel for (py1 = pyl, pym = 0; py1 < py1b; py1++, pym++) // loop overlapping input pixels { if (py1 < py1a) { // compute amount of overlap if (py1+1 < py1b) fy = py1+1 - py1a; // 0.0 to 1.0 else fy = scaley; } else if (py1+1 > py1b) fy = py1b - py1; else fy = 1; ii = py2 * maxmapy + pym; // save it pymap[ii] = 0.9999 * fy / scaley; } ii = py2 * maxmapy + pym; // set an end marker after pymap[ii] = -1; // last overlapping pixel } for (px2 = 0; px2 < ww2; px2++) // do same for x-pixels { px1a = px2 * scalex; px1b = px1a + scalex; if (px1b >= ww1) px1b = ww1 - 0.001; pxl = px1a; px1L[px2] = pxl; for (px1 = pxl, pxm = 0; px1 < px1b; px1++, pxm++) { if (px1 < px1a) { if (px1+1 < px1b) fx = px1+1 - px1a; else fx = scalex; } else if (px1+1 > px1b) fx = px1b - px1; else fx = 1; ii = px2 * maxmapx + pxm; pxmap[ii] = 0.9999 * fx / scalex; } ii = px2 * maxmapx + pxm; pxmap[ii] = -1; } for (ii = 0; ii < Nwt; ii++) { // start working threads busy[ii] = 1; start_detached_thread(bmp8_rescale_thread,&wtnx[ii]); } for (ii = 0; ii < Nwt; ii++) // wait for all done while (busy[ii]) zsleep(0.004); zfree(px1L); zfree(py1L); zfree(pxmap); zfree(pymap); return; } void * bmp8_rescale_thread(void *arg) // worker thread function { using namespace bmp8rescale; int index = *((int *) arg); int px1, py1, px2, py2; int pxl, pyl, pxm, pym, ii; uint8 *pixel1, *pixel2; double fx, fy, ftot; double red, green, blue; for (py2 = index; py2 < hh2; py2 += Nwt) // loop output y-pixels { pyl = py1L[py2]; // corresp. 1st input y-pixel for (px2 = 0; px2 < ww2; px2++) // loop output x-pixels { pxl = px1L[px2]; // corresp. 1st input x-pixel red = green = blue = 0; // initz. output pixel for (py1 = pyl, pym = 0; ; py1++, pym++) // loop overlapping input y-pixels { ii = py2 * maxmapy + pym; // get y-overlap fy = pymap[ii]; if (fy < 0) break; // no more pixels for (px1 = pxl, pxm = 0; ; px1++, pxm++) // loop overlapping input x-pixels { ii = px2 * maxmapx + pxm; // get x-overlap fx = pxmap[ii]; if (fx < 0) break; // no more pixels ftot = fx * fy; // area overlap = x * y overlap pixel1 = pixmap1 + (py1 * ww1 + px1) * 3; red += pixel1[0] * ftot; // add input pixel * overlap green += pixel1[1] * ftot; blue += pixel1[2] * ftot; } pixel2 = pixmap2 + (py2 * ww2 + px2) * 3; // save output pixel pixel2[0] = red; pixel2[1] = green; pixel2[2] = blue; } } } busy[index] = 0; return 0; } /************************************************************************** Rescale 16 bpc image (3 x 16 bits per color) to new width and height. Identical to bmp8_rescale except for the following: uint8 >> uint16 xxx8 >> xxx16 *******/ namespace bmp16rescale { // data for threads uint16 *pixmap1; uint16 *pixmap2; int ww1; int hh1; int ww2; int hh2; int *px1L; int *py1L; double *pxmap; double *pymap; int maxmapx; int maxmapy; int busy[max_threads]; } void bmp16_rescale(uint16 *pixmap1x, uint16 *pixmap2x, int ww1x, int hh1x, int ww2x, int hh2x) { using namespace bmp16rescale; void * bmp16_rescale_thread(void *arg); int px1, py1, px2, py2; int pxl, pyl, pxm, pym, ii; double scalex, scaley; double px1a, py1a, px1b, py1b; double fx, fy; pixmap1 = pixmap1x; pixmap2 = pixmap2x; ww1 = ww1x; hh1 = hh1x; ww2 = ww2x; hh2 = hh2x; memset(pixmap2, 0, ww2 * hh2 * 3 * sizeof(uint16)); // clear output pixmap scalex = 1.0 * ww1 / ww2; // compute x and y scales scaley = 1.0 * hh1 / hh2; if (scalex <= 1) maxmapx = 2; // compute max input pixels else maxmapx = scalex + 2; // mapping into output pixels maxmapx += 1; // for both dimensions if (scaley <= 1) maxmapy = 2; // (pixels may not be square) else maxmapy = scaley + 2; maxmapy += 1; pymap = (double *) zmalloc(hh2 * maxmapy * sizeof(double)); // maps overlap of < maxmap input pxmap = (double *) zmalloc(ww2 * maxmapx * sizeof(double)); // pixels per output pixel py1L = (int *) zmalloc(hh2 * sizeof(int)); // maps first (lowest) input pixel px1L = (int *) zmalloc(ww2 * sizeof(int)); // per output pixel for (py2 = 0; py2 < hh2; py2++) // loop output y-pixels { py1a = py2 * scaley; // corresponding input y-pixels py1b = py1a + scaley; if (py1b >= hh1) py1b = hh1 - 0.001; // fix precision limitation pyl = py1a; py1L[py2] = pyl; // 1st overlapping input pixel for (py1 = pyl, pym = 0; py1 < py1b; py1++, pym++) // loop overlapping input pixels { if (py1 < py1a) { // compute amount of overlap if (py1+1 < py1b) fy = py1+1 - py1a; // 0.0 to 1.0 else fy = scaley; } else if (py1+1 > py1b) fy = py1b - py1; else fy = 1; ii = py2 * maxmapy + pym; // save it pymap[ii] = 0.9999 * fy / scaley; } ii = py2 * maxmapy + pym; // set an end marker after pymap[ii] = -1; // last overlapping pixel } for (px2 = 0; px2 < ww2; px2++) // do same for x-pixels { px1a = px2 * scalex; px1b = px1a + scalex; if (px1b >= ww1) px1b = ww1 - 0.001; pxl = px1a; px1L[px2] = pxl; for (px1 = pxl, pxm = 0; px1 < px1b; px1++, pxm++) { if (px1 < px1a) { if (px1+1 < px1b) fx = px1+1 - px1a; else fx = scalex; } else if (px1+1 > px1b) fx = px1b - px1; else fx = 1; ii = px2 * maxmapx + pxm; pxmap[ii] = 0.9999 * fx / scalex; } ii = px2 * maxmapx + pxm; pxmap[ii] = -1; } for (ii = 0; ii < Nwt; ii++) { // start working threads busy[ii] = 1; start_detached_thread(bmp16_rescale_thread,&wtnx[ii]); } for (ii = 0; ii < Nwt; ii++) // wait for all done while (busy[ii]) zsleep(0.004); zfree(px1L); zfree(py1L); zfree(pxmap); zfree(pymap); return; } void * bmp16_rescale_thread(void *arg) // worker thread function { using namespace bmp16rescale; int index = *((int *) arg); int px1, py1, px2, py2; int pxl, pyl, pxm, pym, ii; uint16 *pixel1, *pixel2; double fx, fy, ftot; double red, green, blue; for (py2 = index; py2 < hh2; py2 += Nwt) // loop output y-pixels { pyl = py1L[py2]; // corresp. 1st input y-pixel for (px2 = 0; px2 < ww2; px2++) // loop output x-pixels { pxl = px1L[px2]; // corresp. 1st input x-pixel red = green = blue = 0; // initz. output pixel for (py1 = pyl, pym = 0; ; py1++, pym++) // loop overlapping input y-pixels { ii = py2 * maxmapy + pym; // get y-overlap fy = pymap[ii]; if (fy < 0) break; // no more pixels for (px1 = pxl, pxm = 0; ; px1++, pxm++) // loop overlapping input x-pixels { ii = px2 * maxmapx + pxm; // get x-overlap fx = pxmap[ii]; if (fx < 0) break; // no more pixels ftot = fx * fy; // area overlap = x * y overlap pixel1 = pixmap1 + (py1 * ww1 + px1) * 3; red += pixel1[0] * ftot; // add input pixel * overlap green += pixel1[1] * ftot; blue += pixel1[2] * ftot; } pixel2 = pixmap2 + (py2 * ww2 + px2) * 3; // save output pixel pixel2[0] = red; pixel2[1] = green; pixel2[2] = blue; } } } busy[index] = 0; return 0; } // Copy and rescale a modified area within a PXM-16 image into the // corresponding area of a PXM-8 image previously rescaled from the // PXM-16 image. Keep the same mapping of input to output pixels, so // that the modified area fits seamlessly into the PXM-8 image. Used // when a section of an image is edited and the window image is updated. // // pxm1 PXM-16 image with changed area to rescale and copy // pxm2 existing rescaled PXM-8 copy of pxm1 // org1x, org1y pxm1 origin of area to copy (top left corner) // ww1a, hh1a width and height of area to copy // new v.10.11 void PXM_update(PXM *pxm1, PXM *pxm2, int org1x, int org1y, int ww1a, int hh1a) { uint16 *bmp1, *pix1; uint8 *bmp2, *pix2; int ww1, hh1, ww2, hh2; int px1, py1, px2, py2; int pxl, pyl, pxm, pym, ii; int *px1L, *py1L; int maxmapx, maxmapy; int org2x, end2x, org2y, end2y; float scalex, scaley; float px1a, py1a, px1b, py1b; float fx, fy, ftot; float red, green, blue; float *pxmap, *pymap; bmp1 = (uint16 *) pxm1->bmp; bmp2 = (uint8 *) pxm2->bmp; ww1 = pxm1->ww; hh1 = pxm1->hh; ww2 = pxm2->ww; hh2 = pxm2->hh; scalex = 1.0 * ww1 / ww2; // compute x and y scales scaley = 1.0 * hh1 / hh2; if (scalex <= 1) maxmapx = 2; // compute max input pixels else maxmapx = scalex + 2; // mapping into output pixels maxmapx += 1; // for both dimensions if (scaley <= 1) maxmapy = 2; // (pixels may not be square) else maxmapy = scaley + 2; maxmapy += 1; pymap = (float *) zmalloc(hh2 * maxmapy * sizeof(float)); // maps overlap of < maxmap input pxmap = (float *) zmalloc(ww2 * maxmapx * sizeof(float)); // pixels per output pixel py1L = (int *) zmalloc(hh2 * sizeof(int)); // maps first (lowest) input pixel px1L = (int *) zmalloc(ww2 * sizeof(int)); // per output pixel for (py2 = 0; py2 < hh2; py2++) // loop output y-pixels { py1a = py2 * scaley; // corresponding input y-pixels py1b = py1a + scaley; if (py1b >= hh1) py1b = hh1 - 0.001; // fix precision limitation pyl = py1a; py1L[py2] = pyl; // 1st overlapping input pixel for (py1 = pyl, pym = 0; py1 < py1b; py1++, pym++) // loop overlapping input pixels { if (py1 < py1a) { // compute amount of overlap if (py1+1 < py1b) fy = py1+1 - py1a; // 0.0 to 1.0 else fy = scaley; } else if (py1+1 > py1b) fy = py1b - py1; else fy = 1; ii = py2 * maxmapy + pym; // save it pymap[ii] = 0.9999 * fy / scaley; } ii = py2 * maxmapy + pym; // set an end marker after pymap[ii] = -1; // last overlapping pixel } for (px2 = 0; px2 < ww2; px2++) // do same for x-pixels { px1a = px2 * scalex; px1b = px1a + scalex; if (px1b >= ww1) px1b = ww1 - 0.001; pxl = px1a; px1L[px2] = pxl; for (px1 = pxl, pxm = 0; px1 < px1b; px1++, pxm++) { if (px1 < px1a) { if (px1+1 < px1b) fx = px1+1 - px1a; else fx = scalex; } else if (px1+1 > px1b) fx = px1b - px1; else fx = 1; ii = px2 * maxmapx + pxm; pxmap[ii] = 0.9999 * fx / scalex; } ii = px2 * maxmapx + pxm; pxmap[ii] = -1; } org2x = org1x / scalex; // compute output image rectangle end2x = (org1x + ww1a) / scalex + 1; // containing any part of input area if (org2x < 0) org2x = 0; // revised v.10.12 if (end2x > ww2) end2x = ww2; org2y = org1y / scaley; end2y = (org1y + hh1a) / scaley + 1; if (org2y < 0) org2y = 0; if (end2y > hh2) end2y = hh2; for (py2 = org2y; py2 < end2y; py2++) // loop output y-pixels { pyl = py1L[py2]; // corresp. 1st input y-pixel for (px2 = org2x; px2 < end2x; px2++) // loop output x-pixels { pxl = px1L[px2]; // corresp. 1st input x-pixel red = green = blue = 0; // initz. output pixel for (py1 = pyl, pym = 0; ; py1++, pym++) // loop overlapping input y-pixels { ii = py2 * maxmapy + pym; // get y-overlap fy = pymap[ii]; if (fy < 0) break; // no more pixels for (px1 = pxl, pxm = 0; ; px1++, pxm++) // loop overlapping input x-pixels { ii = px2 * maxmapx + pxm; // get x-overlap fx = pxmap[ii]; if (fx < 0) break; // no more pixels ftot = fx * fy; // area overlap = x * y overlap pix1 = bmp1 + (py1 * ww1 + px1) * 3; red += pix1[0] * ftot; // add input pixel * overlap green += pix1[1] * ftot; blue += pix1[2] * ftot; } pix2 = bmp2 + (py2 * ww2 + px2) * 3; // save output pixel pix2[0] = int(red) >> 8; pix2[1] = int(green) >> 8; pix2[2] = int(blue) >> 8; } } } zfree(px1L); zfree(py1L); zfree(pxmap); zfree(pymap); return; } // rotate PXM pixmap through given angle in degrees (+ = clockwise) PXM * PXM_rotate(PXM *pxm1, double angle) { PXM * PXM_rotate8(PXM *, double); PXM * PXM_rotate16(PXM *, double); PXM *pxm2 = 0; int bpc; bpc = pxm1->bpc; if (bpc == 8) pxm2 = PXM_rotate8(pxm1,angle); if (bpc == 16) pxm2 = PXM_rotate16(pxm1,angle); return pxm2; } /************************************************************************** PXM *pxm2 = PXM_rotate8(PXM *pxm1, double angle) Rotate PXM-8 pixmap through an arbitrary angle (degrees). The returned image has the same size as the original, but the pixmap size is increased to accomodate the rotated image. (e.g. a 100x100 image rotated 45 deg. needs a 142x142 pixmap). The parameters ww and hh are the dimensions of the input pixmap, and are updated to the dimensions of the output pixmap. The space added around the rotated image is black (RGB 0,0,0). Angle is in degrees. Positive direction is clockwise. Speed is about 3 million pixels/sec/thread for a 2.4 GHz CPU. Loss of resolution is less than 1 pixel. Work is divided among Nwt threads to gain speed. v.9.3: affine transform instead of trig functions, for speed ***************************************************************************/ namespace rotpxm8 { int busy = 0; uint8 *pixmap1; uint8 *pixmap2; int ww1; int hh1; int ww2; int hh2; double angle; } PXM * PXM_rotate8(PXM *pxm1, double anglex) { using namespace rotpxm8; void *PXM_rotate8_thread(void *); int cc, ii; PXM *pxm2; ww1 = pxm1->ww; hh1 = pxm1->hh; pixmap1 = (uint8 *) pxm1->bmp; angle = anglex; while (angle < -180) angle += 360; // normalize, -180 to +180 while (angle > 180) angle -= 360; angle = angle * pi / 180; // radians, -pi to +pi if (fabs(angle) < 0.001) { // angle = 0 within my precision pxm2 = PXM_make(ww1,hh1,8); // return a copy of the input pixmap2 = (uint8 *) pxm2->bmp; cc = ww1 * hh1 * 3 * sizeof(uint8); memcpy(pixmap2,pixmap1,cc); return pxm2; } ww2 = ww1*fabs(cos(angle)) + hh1*fabs(sin(angle)); // rectangle containing rotated image hh2 = ww1*fabs(sin(angle)) + hh1*fabs(cos(angle)); pxm2 = PXM_make(ww2,hh2,8); pixmap2 = (uint8 *) pxm2->bmp; for (ii = 0; ii < Nwt; ii++) // start worker threads start_detached_thread(PXM_rotate8_thread,&wtnx[ii]); zadd_locked(busy,+Nwt); while (busy) zsleep(0.004); // wait for completion return pxm2; } void * PXM_rotate8_thread(void *arg) { using namespace rotpxm8; int index = *((int *) (arg)); int px2, py2, px0, py0; uint8 *pix0, *pix1, *pix2, *pix3; double px1, py1; double f0, f1, f2, f3, red, green, blue; double a, b, d, e, ww15, hh15, ww25, hh25; ww15 = 0.5 * ww1; hh15 = 0.5 * hh1; ww25 = 0.5 * ww2; hh25 = 0.5 * hh2; a = cos(angle); b = sin(angle); d = - sin(angle); e = cos(angle); for (py2 = index; py2 < hh2; py2 += Nwt) // loop through output pixels for (px2 = 0; px2 < ww2; px2++) // outer loop y { px1 = a * (px2 - ww25) + b * (py2 - hh25) + ww15; // (px1,py1) = corresponding v.9.3 py1 = d * (px2 - ww25) + e * (py2 - hh25) + hh15; // point within input pixels px0 = px1; // pixel containing (px1,py1) py0 = py1; if (px1 < 0 || px0 >= ww1-1 || py1 < 0 || py0 >= hh1-1) { // if outside input pixel array pix2 = pixmap2 + (py2 * ww2 + px2) * 3; // output is black pix2[0] = pix2[1] = pix2[2] = 0; continue; } pix0 = pixmap1 + (py0 * ww1 + px0) * 3; // 4 input pixels based at (px0,py0) pix1 = pix0 + ww1 * 3; pix2 = pix0 + 3; pix3 = pix1 + 3; f0 = (px0+1 - px1) * (py0+1 - py1); // overlap of (px1,py1) f1 = (px0+1 - px1) * (py1 - py0); // in each of the 4 pixels f2 = (px1 - px0) * (py0+1 - py1); f3 = (px1 - px0) * (py1 - py0); red = f0 * pix0[0] + f1 * pix1[0] + f2 * pix2[0] + f3 * pix3[0]; // sum the weighted inputs green = f0 * pix0[1] + f1 * pix1[1] + f2 * pix2[1] + f3 * pix3[1]; blue = f0 * pix0[2] + f1 * pix1[2] + f2 * pix2[2] + f3 * pix3[2]; pix2 = pixmap2 + (py2 * ww2 + px2) * 3; // output pixel pix2[0] = red; pix2[1] = green; pix2[2] = blue; } zadd_locked(busy,-1); return 0; } /************************************************************************** PXM *pxm2 = PXM_rotate16(PXM *pxm1, double angle) Rotate PXM-16 pixmap through an arbitrary angle (degrees). Identical to PXM_rotate8() except for: uint8 >> uint16 rotpxm8 >> rotpxm16 8 >> 16 **********/ namespace rotpxm16 { int busy = 0; uint16 *pixmap1; uint16 *pixmap2; int ww1; int hh1; int ww2; int hh2; double angle; } PXM * PXM_rotate16(PXM *pxm1, double anglex) { using namespace rotpxm16; void *PXM_rotate16_thread(void *); int cc, ii; PXM *pxm2; ww1 = pxm1->ww; hh1 = pxm1->hh; pixmap1 = (uint16 *) pxm1->bmp; angle = anglex; while (angle < -180) angle += 360; // normalize, -180 to +180 while (angle > 180) angle -= 360; angle = angle * pi / 180; // radians, -pi to +pi if (fabs(angle) < 0.001) { // angle = 0 within my precision pxm2 = PXM_make(ww1,hh1,16); // return a copy of the input pixmap2 = (uint16 *) pxm2->bmp; cc = ww1 * hh1 * 3 * sizeof(uint16); memcpy(pixmap2,pixmap1,cc); return pxm2; } ww2 = ww1*fabs(cos(angle)) + hh1*fabs(sin(angle)); // rectangle containing rotated image hh2 = ww1*fabs(sin(angle)) + hh1*fabs(cos(angle)); pxm2 = PXM_make(ww2,hh2,16); pixmap2 = (uint16 *) pxm2->bmp; for (ii = 0; ii < Nwt; ii++) // start worker threads start_detached_thread(PXM_rotate16_thread,&wtnx[ii]); zadd_locked(busy,+Nwt); while (busy) zsleep(0.004); // wait for completion return pxm2; } void * PXM_rotate16_thread(void *arg) { using namespace rotpxm16; int index = *((int *) (arg)); int px2, py2, px0, py0; uint16 *pix0, *pix1, *pix2, *pix3; double px1, py1; double f0, f1, f2, f3, red, green, blue; double a, b, d, e, ww15, hh15, ww25, hh25; ww15 = 0.5 * ww1; hh15 = 0.5 * hh1; ww25 = 0.5 * ww2; hh25 = 0.5 * hh2; a = cos(angle); b = sin(angle); d = - sin(angle); e = cos(angle); for (py2 = index; py2 < hh2; py2 += Nwt) // loop through output pixels for (px2 = 0; px2 < ww2; px2++) // outer loop y { px1 = a * (px2 - ww25) + b * (py2 - hh25) + ww15; // (px1,py1) = corresponding v.9.3 py1 = d * (px2 - ww25) + e * (py2 - hh25) + hh15; // point within input pixels px0 = px1; // pixel containing (px1,py1) py0 = py1; if (px1 < 0 || px0 >= ww1-1 || py1 < 0 || py0 >= hh1-1) { // if outside input pixel array pix2 = pixmap2 + (py2 * ww2 + px2) * 3; // output is black pix2[0] = pix2[1] = pix2[2] = 0; continue; } pix0 = pixmap1 + (py0 * ww1 + px0) * 3; // 4 input pixels based at (px0,py0) pix1 = pix0 + ww1 * 3; pix2 = pix0 + 3; pix3 = pix1 + 3; f0 = (px0+1 - px1) * (py0+1 - py1); // overlap of (px1,py1) f1 = (px0+1 - px1) * (py1 - py0); // in each of the 4 pixels f2 = (px1 - px0) * (py0+1 - py1); f3 = (px1 - px0) * (py1 - py0); red = f0 * pix0[0] + f1 * pix1[0] + f2 * pix2[0] + f3 * pix3[0]; // sum the weighted inputs green = f0 * pix0[1] + f1 * pix1[1] + f2 * pix2[1] + f3 * pix3[1]; blue = f0 * pix0[2] + f1 * pix1[2] + f2 * pix2[2] + f3 * pix3[2]; pix2 = pixmap2 + (py2 * ww2 + px2) * 3; // output pixel pix2[0] = red; pix2[1] = green; pix2[2] = blue; } zadd_locked(busy,-1); return 0; } fotoxx-12.01.2/f.select.cc0000644000175000017500000033535611701011017013662 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image editor - select area functions Select an area within the current image. Subsequent edit functions are carried out within the area. Otherwise, edit functions apply to the entire image. sa_stat 0/1/2/3 = none/edit/pause/complete sa_mode is current area selection method: 1 select rectangle by drag or clicks 2 select ellipse by drag 3 freehand draw by drag 4 follow edge indicated by clicks 5 select pixels by mouse (radius, color, range, firewall) 6 unused v.11.12 7 select whole image ***************************************************************************/ // user select area dialog // line drawing and selection by color range are combined // v.9.7 void m_select(GtkWidget *, cchar *) // menu function { int select_dialog_event(zdialog *, cchar *event); // dialog event and completion funcs cchar *title = ZTX("Select Area for Edits"); cchar *helptext = ZTX("Press F1 for help"); zdialog *zd; zfuncs::F1_help_topic = "select_area"; if (! curr_file) return; // no image if (zdsela) return; // already active if (CEF && CEF->Farea != 2) { // active edit function zmessageACK(mWin,ZTX("Select Area not supported \n" // v.11.08 "by this edit function")); return; } if (Fpreview) edit_fullsize(); // use full-size image if (! Fpxm16) { // create Fpxm16 if not already mutex_lock(&Fpixmap_lock); Fpxm16 = f_load(curr_file,16); mutex_unlock(&Fpixmap_lock); if (! Fpxm16) return; } /*** v.11.12 ____________________________________________________ | Press F1 for help | | [x] select rectangle [x] select ellipse | | [x] draw: freehand [x] draw: follow edge | | [x] select by mouse mouse radius [___] | | [x] match mouse color [___] | | search range [__] [x] firewall | | Blend Width [__] | | | | [Show] [Hide] [Color] [Finish] [Unfinish] | | [Enable] [Disable] [Invert] [Unselect] [Done] | |____________________________________________________| ***/ zdsela = zdialog_new(title,mWin,null); zd = zdsela; zdialog_add_widget(zd,"label","labhelp","dialog",helptext); zdialog_add_widget(zd,"hbox","hbshape","dialog"); zdialog_add_widget(zd,"vbox","vbsh1","hbshape"); zdialog_add_widget(zd,"label","space","hbshape",0,"space=10"); zdialog_add_widget(zd,"vbox","vbsh2","hbshape"); zdialog_add_widget(zd,"check","ckrect","vbsh1",ZTX("rectangle")); zdialog_add_widget(zd,"check","ckelips","vbsh2",ZTX("ellipse")); zdialog_add_widget(zd,"hbox","hbdraw","dialog"); zdialog_add_widget(zd,"vbox","vbdr1","hbdraw",0,"homog"); zdialog_add_widget(zd,"label","space","hbdraw",0,"space=10"); zdialog_add_widget(zd,"vbox","vbdr2","hbdraw",0,"homog"); zdialog_add_widget(zd,"check","ckdraw","vbdr1",ZTX("draw: freehand")); zdialog_add_widget(zd,"check","ckfollow","vbdr2",ZTX("draw: follow edge")); zdialog_add_widget(zd,"hbox","hbm1","dialog"); zdialog_add_widget(zd,"check","ckmouse","hbm1",ZTX("select by mouse")); zdialog_add_widget(zd,"label","space","hbm1",0,"space=10"); zdialog_add_widget(zd,"label","labmr","hbm1",ZTX("mouse radius")); zdialog_add_widget(zd,"spin","mouserad","hbm1","1|300|1|20","space=5"); zdialog_add_widget(zd,"hbox","hbm2","dialog"); zdialog_add_widget(zd,"label","space","hbm2",0,"space=10"); zdialog_add_widget(zd,"check","matchcolor","hbm2",ZTX("match mouse color")); zdialog_add_widget(zd,"spin","colormatch","hbm2","0|100|1|90","space=10"); zdialog_add_widget(zd,"hbox","hbm3","dialog"); zdialog_add_widget(zd,"label","space","hbm3",0,"space=10"); zdialog_add_widget(zd,"label","labsr","hbm3",ZTX("search range"),"space=5"); zdialog_add_widget(zd,"spin","searchrange","hbm3","1|20|1|3"); zdialog_add_widget(zd,"check","firewall","hbm3",ZTX("firewall"),"space=10"); zdialog_add_widget(zd,"hbox","hbbwfw","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labblend","hbbwfw",Bblendwidth,"space=5"); zdialog_add_widget(zd,"spin","blendwidth","hbbwfw","0|500|1|0"); zdialog_add_widget(zd,"hbox","hbb2","dialog",0,"space=5"); zdialog_add_widget(zd,"button","show","hbb2",Bshow); zdialog_add_widget(zd,"button","hide","hbb2",Bhide); zdialog_add_widget(zd,"button","color","hbb2",Bcolor); zdialog_add_widget(zd,"button","finish","hbb2",Bfinish); zdialog_add_widget(zd,"button","unfinish","hbb2",Bunfinish); zdialog_add_widget(zd,"hbox","hbb3","dialog",0,"space=3"); zdialog_add_widget(zd,"button","enable","hbb3",Benable); zdialog_add_widget(zd,"button","disable","hbb3",Bdisable); zdialog_add_widget(zd,"button","invert","hbb3",Binvert); zdialog_add_widget(zd,"button","unselect","hbb3",Bunselect); zdialog_add_widget(zd,"button","done","hbb3",Bdone); zdialog_help(zd,"select_area"); // v.11.08 zdialog_run(zd,select_dialog_event,"save"); // run dialog - parallel v.11.07 sa_mouseradius = 20; // initial values matching dialog sa_colormatch = 90; sa_matchcolor = 0; sa_searchrange = 3; sa_blend = 0; sa_firewall = 0; sa_mode = 0; zdialog_stuff(zd,"ckrect",0); zdialog_stuff(zd,"ckelips",0); zdialog_stuff(zd,"ckdraw",0); zdialog_stuff(zd,"ckfollow",0); zdialog_stuff(zd,"ckmouse",0); sa_show(1); // show existing area, if any return; } // dialog event and completion callback function int select_dialog_event(zdialog *zd, cchar *event) { struct { cchar *event; int stat; } eventab[20] = { // dialog events and corresp. { "ckrect", 1 }, // edit status change { "ckelips", 1 }, { "ckdraw", 1 }, { "ckfollow", 1 }, { "ckmouse", 1 }, { "mouserad", 0 }, { "matchcolor", 0 }, { "colormatch", 0 }, { "searchrange", 0 }, { "firewall", 0 }, { "blendwidth", 0 }, { "show", 0 }, { "hide", 0 }, { "color", 0 }, { "finish", 2 }, { "unfinish", 2 }, { "enable", 0 }, { "disable", 2 }, { "invert", 0 }, { "unselect", 2 } }; int Nevents = 20, ii, jj, kk, cc; if (strEqu(event,"done") || zd->zstat) // done or cancel { freeMouse(); // disconnect mouse function v.10.12 zdialog_free(zdsela); // kill dialog return 0; } if (CEF && CEF->Farea != 2) { // select area not supported v.11.08 printf("select area ignored \n"); return 0; } for (ii = 0; ii < Nevents; ii++) if (strEqu(event,eventab[ii].event)) break; if (ii == Nevents) return 0; if (sa_fww != Fww || sa_fhh != Fhh) // area not valid for image, delete it sa_unselect(); // bugfix v.11.08 if (! sa_stat) { // no area, create one v.11.07 cc = Fww * Fhh * sizeof(uint16); // allocate sa_pixmap[] for new area sa_pixmap = (uint16 *) zmalloc(cc,"sa_select"); // maps pixels in area memset(sa_pixmap,0,cc); sa_currseq = sa_Ncurrseq = 0; // reset selection sequence sa_Npixel = sa_blend = sa_calced = Factivearea = 0; sa_fww = Fww; // valid image size for area v.11.08 sa_fhh = Fhh; sa_stat = 1; // status = edit zdialog_stuff(zd,"blendwidth",0); // init. blend width = 0 } if (ii < 5) // one of the edit mode checkboxes { for (jj = 0; jj < 5; jj++) { if (jj == ii) { zdialog_fetch(zd,eventab[ii].event,kk); // toggle checkbox on/off if (kk) { // on: set edit mode sa_mode = jj+1; sa_stat = 1; sa_Npixel = sa_blend = sa_calced = Factivearea = 0; zdialog_stuff(zd,"blendwidth",0); sa_show(1); } else { // off: no edit mode, edit paused sa_mode = 0; sa_stat = 2; } } else zdialog_stuff(zd,eventab[jj].event,0); // all other checkboxes off } } if (eventab[ii].stat == 2) { for (jj = 0; jj < 5; jj++) // no edit mode active zdialog_stuff(zd,eventab[jj].event,0); // all checkboxes off sa_stat = 2; // edit is paused } if (strEqu(event,"mouserad")) // mouse selection radius zdialog_fetch(zd,"mouserad",sa_mouseradius); if (strEqu(event,"matchcolor")) // "" color match enable v.11.12 zdialog_fetch(zdsela,"matchcolor",sa_matchcolor); if (strEqu(event,"colormatch")) // "" color match limit, 0 - 99.9 zdialog_fetch(zdsela,"colormatch",sa_colormatch); if (strEqu(event,"searchrange")) // "" "" search range, x radius v.11.12 zdialog_fetch(zdsela,"searchrange",sa_searchrange); if (strEqu(event,"firewall")) // "" color match firewall on/off v.10.11 zdialog_fetch(zdsela,"firewall",sa_firewall); if (strEqu(event,"show")) sa_show(1); // show area if (strEqu(event,"hide")) sa_show(0); // hide area if (strEqu(event,"finish")) sa_finish(); // finish (finalize) area if (strEqu(event,"unfinish")) sa_unfinish(); // unfinish area v.11.07 if (strEqu(event,"unselect")) sa_unselect(); // unselect area if (strEqu(event,"enable")) sa_enable(); // enable area if (strEqu(event,"disable")) sa_disable(); // disable area if (strEqu(event,"invert")) sa_invert(); // invert area if (strEqu(event,"color")) { // change show area color if (sa_pixRGB == &red) sa_pixRGB = &green; else if (sa_pixRGB == &green) sa_pixRGB = &black; else sa_pixRGB = &red; sa_show(1); } if (strEqu(event,"blendwidth") && Factivearea) { // blend width changed sa_edgecalc(); // do edge calc. if not already if (sa_calced && CEF && CEF->zd) { // edit is active zdialog_fetch(zd,"blendwidth",sa_blend); // update sa_blend zdialog_send_event(CEF->zd,event); // notify edit dialog } } // "ignore once" logic removed v.11.01 if (sa_stat == 1) // active edit mode { if (sa_mode == 1) takeMouse(zd,sa_geom_mousefunc,dragcursor); // rectangle v.11.03 if (sa_mode == 2) takeMouse(zd,sa_geom_mousefunc,dragcursor); // ellipse if (sa_mode == 3) takeMouse(zd,sa_draw_mousefunc,drawcursor); // freehand draw if (sa_mode == 4) takeMouse(zd,sa_draw_mousefunc,drawcursor); // follow edge if (sa_mode == 5) takeMouse(zd,sa_mouse_mousefunc,0); // mouse select if (sa_mode < 3) sa_geom1 = sa_geom2 = 0; // new rectangle or ellipse if (sa_mode < 5) paint_toparc(2); // erase radius circle } else { // edit paused or done freeMouse(); // disconnect mouse gdk_window_set_cursor(drWin->window,null); // normal cursor v.12.01 } return 0; } // select area mouse function - select a rectangle or ellipse void sa_geom_mousefunc() // new v.11.03 { static int mx1, my1, mx2, my2; static int mdx0, mdy0; if (sa_stat != 1) return; // area gone? v.11.07 if (sa_currseq > sa_maxseq-2) { zmessageACK(mWin,ZTX("exceed %d edits"),sa_maxseq); // cannot continue return; } if (RMclick) // right mouse click { RMclick = 0; sa_unselect_pixels(); // remove latest selection sa_geom1 = sa_geom2 = 0; mwpaint2(); return; } if (! Mxdrag && ! Mydrag) return; // v.11.04 if (Mxdown != mdx0 || Mydown != mdy0) { // new drag initiated mdx0 = Mxdown; mdy0 = Mydown; mx1 = mdx0; // drag start, one corner my1 = mdy0; sa_geom1 = 1; sa_geom2 = 0; return; } if (sa_geom2) sa_unselect_pixels(); // remove prior selection mx2 = Mxdrag; // drag continues, 2nd corner my2 = Mydrag; sa_geom2 = 1; sa_nextseq(); // next sequence number if (sa_mode == 1) // draw rectangle { sa_draw_line(mx1,my1,mx2,my1); sa_draw_line(mx2,my1,mx2,my2); sa_draw_line(mx2,my2,mx1,my2); sa_draw_line(mx1,my2,mx1,my1); } if (sa_mode == 2) // draw ellipse { double a, b, a2, b2; double x, y, x2, y2, cx, cy; int px, py; a = abs(mx2 - mx1); // ellipse constants from v.11.04 b = abs(my2 - my1); // enclosing rectangle a2 = a * a; b2 = b * b; cx = mx1; // center at drag origin v.11.04 cy = my1; for (y = -b; y < b; y++) // step through y values { y2 = y * y; x2 = a2 * (1 - y2 / b2); x = sqrt(x2); // corresp. x values, + and - py = y + cy; px = cx - x + 0.5; sa_draw1pix(px,py); // draw 2 points on ellipse px = cx + x + 0.5; sa_draw1pix(px,py); } for (x = -a; x < a; x++) // step through x values { x2 = x * x; y2 = b2 * (1 - x2 / a2); y = sqrt(y2); // corresp. y values, + and - px = cx + x; py = cy - y + 0.5; sa_draw1pix(px,py); // draw 2 points on ellipse py = cy + y + 0.5; sa_draw1pix(px,py); } } mwpaint2(); return; } // select area mouse function - freehand draw and follow edge void sa_draw_mousefunc() { void sa_follow_edge(int mx1, int my1, int mx2, int my2); int mx1, my1, mx2, my2; int npdist, npx, npy; int ii, click, newseq, thresh; static int drag = 0, mdx0, mdy0, mdx1, mdy1; if (sa_stat != 1) return; // area gone? v.11.07 sa_thresh = 4.0 / Mscale + 1; // mouse pixel distance threshold click = newseq = 0; if (LMclick || Mxdrag || Mydrag) // left mouse click or mouse drag { if (LMclick) // left mouse click { LMclick = 0; mx1 = mx2 = Mxclick; // click position my1 = my2 = Myclick; newseq++; click++; drag = 0; } else // drag motion { if (Mxdown != mdx0 || Mydown != mdy0) { // new drag initiated mdx0 = mdx1 = Mxdown; mdy0 = mdy1 = Mydown; newseq++; } mx1 = mdx1; // drag start my1 = mdy1; mx2 = Mxdrag; // drag position my2 = Mydrag; mdx1 = mx2; // next drag start mdy1 = my2; drag++; click = 0; } if (Mbutton == 3) // right mouse >> erase { while (true) { thresh = sa_thresh; npdist = sa_nearpix(mx2,my2,thresh,npx,npy); if (! npdist) break; ii = npy * Fww + npx; sa_pixmap[ii] = 0; } mwpaint2(); return; } if (sa_currseq > sa_maxseq-2) { zmessageACK(mWin,ZTX("exceed %d edits"),sa_maxseq); // cannot continue return; } if (sa_currseq == 0 && newseq) // 1st pixel(s) of 1st sequence { sa_nextseq(); // set next (1st) sequence no. v.10.8 sa_draw_line(mx1,my1,mx2,my2); // draw initial pixel or line sa_endpx[sa_currseq] = mx2; sa_endpy[sa_currseq] = my2; return; } if (click) { mx1 = sa_endpx[sa_currseq]; // prior sequence end pixel my1 = sa_endpy[sa_currseq]; // (before this click) } if (drag) { if (newseq) thresh = 2 * sa_thresh; // new drag threshold else thresh = 5 * sa_thresh; // continuation drag threshold npx = sa_endpx[sa_currseq]; // distance from prior end pixel npy = sa_endpy[sa_currseq]; // (before this drag) if (abs(mx1-npx) < thresh && abs(my1-npy) < thresh) { mx1 = sa_endpx[sa_currseq]; // if < threshold, connect this my1 = sa_endpy[sa_currseq]; // drag to prior drag or click } } if (newseq || drag > 50) { sa_nextseq(); // set next sequence no. v.10.8 drag = 1; // drag length within sequence } if (sa_mode == 4) sa_follow_edge(mx1,my1,mx2,my2); // follow edge or draw line else sa_draw_line(mx1,my1,mx2,my2); // from end pixel to mouse sa_endpx[sa_currseq] = mx2; // set end pixel for this sequence sa_endpy[sa_currseq] = my2; } else if (RMclick) // right mouse click { RMclick = 0; sa_unselect_pixels(); // remove latest selection v.10.8 mwpaint2(); } return; } // Find the nearest drawn pixel within a radius of a given pixel. // Returns distance to pixel, or zero if nothing found. // Returns 1 for adjacent or diagonally adjacent pixel. int sa_nearpix(int mx, int my, int rad2, int &npx, int &npy) { int ii, rad, qx, qy, dx, dy; int mindist, dist; npx = npy = 0; mindist = (rad2+1) * (rad2+1); for (rad = 1; rad <= rad2; rad++) // seek neighbors within range { if (rad * rad > mindist) break; // can stop searching now for (qx = mx-rad; qx <= mx+rad; qx++) // search within rad for (qy = my-rad; qy <= my+rad; qy++) { if (qx != mx-rad && qx != mx+rad && // exclude within rad-1 qy != my-rad && qy != my+rad) continue; // (already searched) if (qx < 0 || qx > Fww-1) continue; if (qy < 0 || qy > Fhh-1) continue; ii = qy * Fww + qx; if (! sa_pixmap[ii]) continue; dx = (mx - qx) * (mx - qx); // found pixel dy = (my - qy) * (my - qy); dist = dx + dy; // distance**2 if (dist < mindist) { mindist = dist; npx = qx; // save nearest pixel found npy = qy; } } } if (npx + npy) return sqrt(mindist) + 0.5; return 0; } // draw a line between two given pixels // add all in-line pixels to sa_pixmap[] void sa_draw_line(int px1, int py1, int px2, int py2) { void sa_draw1pix(int px, int py); int pxm, pym; double slope; if (sa_stat != 1) return; // area gone? v.11.07 if (px1 == px2 && py1 == py2) { // only one pixel sa_draw1pix(px1,py1); return; } if (abs(py2 - py1) > abs(px2 - px1)) { slope = 1.0 * (px2 - px1) / (py2 - py1); if (py2 > py1) { for (pym = py1; pym <= py2; pym++) { pxm = round(px1 + slope * (pym - py1)); sa_draw1pix(pxm,pym); } } else { for (pym = py1; pym >= py2; pym--) { pxm = round(px1 + slope * (pym - py1)); sa_draw1pix(pxm,pym); } } } else { slope = 1.0 * (py2 - py1) / (px2 - px1); if (px2 > px1) { for (pxm = px1; pxm <= px2; pxm++) { pym = round(py1 + slope * (pxm - px1)); sa_draw1pix(pxm,pym); } } else { for (pxm = px1; pxm >= px2; pxm--) { pym = round(py1 + slope * (pxm - px1)); sa_draw1pix(pxm,pym); } } } return; } // draw one pixel only if not already drawn void sa_draw1pix(int px, int py) { if (px < 0 || px > Fww-1) return; // bugfix v.11.03.1 if (py < 0 || py > Fhh-1) return; int ii = Fww * py + px; if (sa_pixmap[ii]) return; // map to curr. selection sequence sa_pixmap[ii] = sa_currseq; sa_Ncurrseq++; // v.10.8 draw_fat_pixel(px,py,sa_pixRGB); // v.11.04 return; } // Find series of edge pixels from px1/py1 to px2/py2 and connect them together. void sa_follow_edge(int px1, int py1, int px2, int py2) // v.10.8 { double sa_get_contrast(int px, int py); double px3, py3, px4, py4, px5, py5, px6, py6; double dx, dy, dist, contrast, maxcontrast; if (sa_stat != 1) return; // area gone? v.11.07 px3 = px1; // p3 progresses from p1 to p2 py3 = py1; while (true) { dx = px2 - px3; dy = py2 - py3; dist = sqrt(dx * dx + dy * dy); // last segment if (dist < 3) break; px4 = px3 + dx / dist; // p4 = p3 moved toward p2 py4 = py3 + dy / dist; maxcontrast = 0; px6 = px4; py6 = py4; for (int ii = -2; ii <= +2; ii++) // p5 points are in a line through p4 { // and perpendicular to p4 - p2 px5 = px4 + ii * dy / dist; py5 = py4 - ii * dx / dist; contrast = sa_get_contrast(px5,py5); contrast *= (7 - abs(ii)); // favor points closer together v.10.9 if (contrast > maxcontrast) { px6 = px5; // p6 = highest contrast point in p5 py6 = py5; maxcontrast = contrast; } } sa_draw_line(px3,py3,px6,py6); // draw p3 to p6 px3 = px6; // next p3 py3 = py6; } sa_draw_line(px3,py3,px2,py2); return; } // Find max. contrast between neighbors on opposite sides of given pixel double sa_get_contrast(int px, int py) // v.10.8 { int map[4][2] = { {1, 0}, {1, 1}, {0, 1}, {-1, 1} }; int ii, qx, qy; uint16 *pix1, *pix2; double red, green, blue; double contrast, maxcontrast = 0; double f65k = 1.0 / 65535.0; if (px < 1 || px > Fww-2) return 0; // avoid edge pixels if (py < 1 || py > Fhh-2) return 0; for (ii = 0; ii < 4; ii++) // compare pixels around target { // e.g. (px-1,py) to (px+1,py) qx = map[ii][0]; qy = map[ii][1]; pix1 = PXMpix(Fpxm16,px+qx,py+qy); pix2 = PXMpix(Fpxm16,px-qx,py-qy); red = f65k * abs(pix1[0] - pix2[0]); green = f65k * abs(pix1[1] - pix2[1]); blue = f65k * abs(pix1[2] - pix2[2]); contrast = (1.0 - red) * (1.0 - green) * (1.0 - blue); // no contrast = 1.0 contrast = 1.0 - contrast; // max. contrast = 1.0 if (contrast > maxcontrast) maxcontrast = contrast; } return maxcontrast; } // mouse function - select area by mouse and matching color range // if left click or drag, find and select matching pixels // if right click, unselect last selection // if right drag, find and unselect matching pixels void sa_mouse_mousefunc() // revised v.11.12 { void sa_find_color_pixels(int select); static int mxdown, mydown, drag = 0; if (sa_stat != 1) return; // area gone? v.11.07 sa_radius = sa_mouseradius; // mouse radius sa_radius2 = sa_radius * sa_radius; // squared sa_radius3 = sa_radius * sa_searchrange; // search range (* mouse radius) sa_radius3 = sa_radius3 * sa_radius3; // squared toparcx = Mxposn - sa_radius; // draw radius outline circle toparcy = Myposn - sa_radius; toparcw = toparch = 2 * sa_radius; Ftoparc = 1; paint_toparc(3); if (RMclick) { // right mouse click RMclick = 0; sa_unselect_pixels(); // remove latest selection v.10.8 mwpaint2(); return; } if ((Mxdrag || Mydrag) && Mbutton == 3) { // right drag, find and unselect pixels sa_mousex = Mxdrag; sa_mousey = Mydrag; Mxdrag = Mydrag = 0; sa_find_color_pixels(0); mwpaint2(); return; } sa_mousex = sa_mousey = 0; if (LMclick) { // left mouse click sa_mousex = Mxclick; sa_mousey = Myclick; LMclick = 0; sa_nextseq(); // set next sequence no. v.10.8 drag = 1; // reset drag counter } if ((Mxdrag || Mydrag) && Mbutton == 1) { // left drag, select matching colors sa_mousex = Mxdrag; sa_mousey = Mydrag; Mxdrag = Mydrag = 0; if (Mxdown != mxdown || Mydown != mydown) { // detect if new drag started mxdown = Mxdown; mydown = Mydown; sa_nextseq(); // set next sequence no. v.10.8 drag = 1; // reset drag counter } else if (++drag > 30) { // limit work per sequence no. sa_nextseq(); // set next sequence no. v.10.8 drag = 1; // reset drag counter } } if (sa_mousex || sa_mousey) { sa_find_color_pixels(1); // find and select pixels mwpaint2(); } return; } // find all contiguous pixels within the specified range of colors to match // select or unselect the matching pixels void sa_find_color_pixels(int select) // revised v.11.12 { int ii, kk, cc, px, py, rx, ry, rad2; int ppx, ppy, npx, npy; uint16 *matchpix; double match1, match2, ff = 1.0 / 65536.0; double dred, dgreen, dblue; char direc; px = sa_mousex; py = sa_mousey; if (px < 0 || px > Fww-1) return; // mouse outside image if (py < 0 || py > Fhh-1) return; sa_Ncurrseq = 0; // count newly selected pixels for (rx = -sa_radius; rx <= sa_radius; rx++) // loop every pixel in radius of mouse for (ry = -sa_radius; ry <= sa_radius; ry++) // v.11.12 { rad2 = rx * rx + ry * ry; if (rad2 > sa_radius2) continue; // outside radius px = sa_mousex + rx; py = sa_mousey + ry; if (px < 0 || px > Fww-1) continue; // off the image edge if (py < 0 || py > Fhh-1) continue; ii = Fww * py + px; if (select) { // select pixel if (sa_pixmap[ii]) continue; sa_pixmap[ii] = sa_currseq; // map pixel to current sequence sa_Ncurrseq++; // current sequence pixel count } else sa_pixmap[ii] = 0; // unselect } if (! sa_matchcolor) return; // no color matching, done v.11.12 match1 = 0.01 * sa_colormatch; // color match level, 0.01 to 1.0 sa_Nmatch = 0; // match color count for (rx = -sa_radius; rx <= sa_radius; rx++) // loop every pixel in radius of mouse for (ry = -sa_radius; ry <= sa_radius; ry++) { rad2 = rx * rx + ry * ry; if (rad2 > sa_radius2) continue; // outside radius px = sa_mousex + rx; py = sa_mousey + ry; if (px < 0 || px > Fww-1) continue; // off the image edge if (py < 0 || py > Fhh-1) continue; matchpix = PXMpix(Fpxm16,px,py); // get color at mouse position for (ii = 0; ii < sa_Nmatch; ii++) // see if color is already included { dred = ff * abs(sa_matchRGB[ii][0] - matchpix[0]); // 0 = perfect match dgreen = ff * abs(sa_matchRGB[ii][1] - matchpix[1]); dblue = ff * abs(sa_matchRGB[ii][2] - matchpix[2]); match2 = (1.0 - dred) * (1.0 - dgreen) * (1.0 - dblue); // 1 = perfect match if (match2 >= match1) break; // matches close enough } if (ii == sa_Nmatch) { // no close match sa_matchRGB[ii][0] = matchpix[0]; // add new match color to list sa_matchRGB[ii][1] = matchpix[1]; sa_matchRGB[ii][2] = matchpix[2]; sa_Nmatch++; if (sa_Nmatch == 1000) goto startsearch; // capacity limit } } startsearch: if (sa_stackdirec) zfree(sa_stackdirec); // get memory if (sa_stackii) zfree(sa_stackii); if (sa_pixselc) zfree(sa_pixselc); cc = Fww * Fhh; sa_stackdirec = zmalloc(cc,"sa_color"); sa_stackii = (int *) zmalloc(4*cc,"sa_color"); sa_maxstack = cc; sa_Nstack = 0; sa_pixselc = zmalloc(cc,"sa_color"); memset(sa_pixselc,0,cc); px = sa_mousex; // pixel at mouse py = sa_mousey; ii = Fww * py + px; sa_pixselc[ii] = 1; // pixel is in current selection if (! sa_pixmap[ii]) { // if selected for the first time, v.10.12 sa_pixmap[ii] = sa_currseq; // map pixel to current sequence sa_Ncurrseq++; // current sequence pixel count } sa_stackii[0] = ii; // put 1st pixel into stack sa_stackdirec[0] = 'a'; // direction = ahead v.11.04 sa_Nstack = 1; // stack count while (sa_Nstack) { kk = sa_Nstack - 1; // get last pixel in stack ii = sa_stackii[kk]; direc = sa_stackdirec[kk]; py = ii / Fww; // reconstruct px, py px = ii - Fww * py; if (direc == 'x') { // no neighbors left to check sa_Nstack--; continue; } if (sa_Nstack > 1) { ii = sa_Nstack - 2; // get prior pixel in stack ii = sa_stackii[ii]; ppy = ii / Fww; ppx = ii - ppy * Fww; } else { ppx = px - 1; // if only one, assume prior = left ppy = py; } if (direc == 'a') { // next ahead pixel v.11.04 npx = px + px - ppx; npy = py + py - ppy; sa_stackdirec[kk] = 'r'; // next search direction } else if (direc == 'r') { // next right pixel v.11.04 npx = px + py - ppy; npy = py + px - ppx; sa_stackdirec[kk] = 'l'; } else { /* direc = 'l' */ // next left pixel v.11.04 npx = px + ppy - py; npy = py + ppx - px; sa_stackdirec[kk] = 'x'; } if (npx < 0 || npx > Fww-1) continue; // pixel off the edge v.11.04 if (npy < 0 || npy > Fhh-1) continue; rx = npx - Mxposn; // limit search to ry = npy - Myposn; // mouse radius * search range rad2 = rx * rx + ry * ry; if (rad2 > sa_radius3) continue; // v.11.12 ii = npy * Fww + npx; if (sa_pixselc[ii]) continue; // already in current selection if (select && sa_firewall && sa_pixmap[ii]) // aleady selected, firewall mode if (rad2 > sa_radius2) continue; // and pixel outside mouse radius matchpix = PXMpix(Fpxm16,npx,npy); for (kk = 0; kk < sa_Nmatch; kk++) { // compare pixel RGB to match colors dred = ff * abs(sa_matchRGB[kk][0] - matchpix[0]); // v.10.8 dgreen = ff * abs(sa_matchRGB[kk][1] - matchpix[1]); dblue = ff * abs(sa_matchRGB[kk][2] - matchpix[2]); match2 = (1.0 - dred) * (1.0 - dgreen) * (1.0 - dblue); // 1 = perfect match if (match2 >= match1) break; // within range } if (kk == sa_Nmatch) continue; // not within range of any color sa_pixselc[ii] = 1; // map pixel to current selection if (select) { // select mode if (! sa_pixmap[ii]) { // if selected for the first time, sa_pixmap[ii] = sa_currseq; // map pixel to current sequence sa_Ncurrseq++; // current sequence pixel count } } else sa_pixmap[ii] = 0; // unselect mode v.11.12 if (sa_Nstack == sa_maxstack) continue; // stack is full kk = sa_Nstack++; // push pixel into stack sa_stackii[kk] = ii; sa_stackdirec[kk] = 'a'; // direction = ahead v.11.04 } return; } // set next sequence number for pixels about to be selected void sa_nextseq() // v.10.8 { if (sa_Ncurrseq > 0) sa_currseq++; // increase only if some pixels mapped if (sa_currseq < sa_initseq) sa_currseq = sa_initseq; // start at initial value sa_Ncurrseq = 0; return; } // un-select all pixels mapped to current sequence number // reduce sequence number and set pixel count = 1 void sa_unselect_pixels() { if (sa_stat != 1) return; // area gone? v.11.07 if (! sa_currseq) return; // no pixels mapped for (int ii = 0; ii < Fww * Fhh; ii++) if (sa_pixmap[ii] == sa_currseq) sa_pixmap[ii] = 0; // unmap current selection if (sa_currseq > sa_initseq) { // reduce sequence no. v.10.8 sa_currseq--; sa_Ncurrseq = 1; // unknown but > 0 } else sa_Ncurrseq = 0; // initial sequence no. reached return; } // Finish select area - map pixels enclosed by edge pixels // into sa_pixmap[ii]: 0/1/2 = outside/edge/inside (ii=py*Fww+px) // total count = sa_Npixel zdialog *safinzd = 0; void sa_finish() // overhauled v.11.02 { void sa_finish_mousefunc(); int sa_finish_dialog_event(zdialog *, cchar *event); cchar *fmess = ZTX("Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help."); GtkWidget *pwin = zdialog_widget(zdsela,"dialog"); int ii, cc, px, py; if (! sa_stat) return; // no area? v.11.07 if (sa_fww != Fww || sa_fhh != Fhh) return; // area not valid for image v.11.08 if (sa_mode == 7) return; // a whole image area sa_Npixel = Factivearea = 0; // area disabled, unfinished sa_finOK = sa_finhole = 0; // count areas OK and with holes sa_show(1); // show outline sa_minx = Fww; sa_maxx = 0; sa_miny = Fhh; sa_maxy = 0; for (ii = 0; ii < Fww * Fhh; ii++) // get enclosing rectangle { // for selected area(s) if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - Fww * py; if (px >= sa_maxx) sa_maxx = px+1; // like Fww, sa_maxx = last + 1 if (px < sa_minx) sa_minx = px; if (py >= sa_maxy) sa_maxy = py+1; if (py < sa_miny) sa_miny = py; } sa_map_pixels(); // map edge and interior pixels if (sa_Npixel < 10) return; // ridiculous sa_minx -= 10; // add margins where possible if (sa_minx < 0) sa_minx = 0; sa_maxx += 10; if (sa_maxx > Fww) sa_maxx = Fww; sa_miny -= 10; if (sa_miny < 0) sa_miny = 0; sa_maxy += 10; if (sa_maxy > Fhh) sa_maxy = Fhh; for (py = sa_miny; py < sa_maxy; py++) // loop pixels in rectangle v.10.12 for (px = sa_minx; px < sa_maxx; px++) { ii = Fww * py + px; // eliminate interior pixels if (sa_pixmap[ii] == 2) sa_pixmap[ii] = 0; // from prior finish functions } cc = (sa_maxx-sa_minx) * (sa_maxy-sa_miny); // allocate stack memory if (sa_stackdirec) zfree(sa_stackdirec); sa_stackdirec = zmalloc(cc,"sa_finish"); if (sa_stackii) zfree(sa_stackii); sa_stackii = (int *) zmalloc(cc * 4,"sa_finish"); sa_maxstack = cc; safinzd = zdialog_new(ZTX("finish area"),pwin,Bdone,Bcancel,null); // dialog for user to click inside zdialog_add_widget(safinzd,"label","fmess","dialog",fmess,"space=5"); // each enclosed area zdialog_add_widget(safinzd,"hbox","hbstat","dialog"); zdialog_add_widget(safinzd,"label","labstat","hbstat","status:","space=5"); zdialog_add_widget(safinzd,"label","statmess","hbstat",0); takeMouse(safinzd,sa_finish_mousefunc,dragcursor); // connect mouse function v.11.03 zdialog_run(safinzd,sa_finish_dialog_event,"save"); // run dialog, parallel v.11.07 zdialog_wait(safinzd); return; } // mouse function - get user clicks and perform pixel searches void sa_finish_mousefunc() // overhauled v.11.02 { int px, py, ii, kk; int ppx, ppy, npx, npy; int finhole = 0; char direc; if (! LMclick) return; LMclick = 0; if (! sa_stat) return; // area gone? v.11.07 ii = Fww * Myclick + Mxclick; // seed pixel from mouse click if (sa_pixmap[ii] == 1) return; // ignore if edge pixel v.11.07 sa_pixmap[ii] = 2; // map the pixel, inside area sa_stackii[0] = ii; // put seed pixel into stack sa_stackdirec[0] = 'a'; // direction = ahead v.11.04 sa_Nstack = 1; // stack count zdialog_stuff(safinzd,"statmess",ZTX("searching")); zmainloop(); zsleep(0.2); Ffuncbusy++; while (sa_Nstack) // find all pixels outside enclosed area(s) { kk = sa_Nstack - 1; // get last pixel in stack ii = sa_stackii[kk]; direc = sa_stackdirec[kk]; py = ii / Fww; // reconstruct px, py px = ii - Fww * py; if (px < sa_minx || px >= sa_maxx || py < sa_miny || py >= sa_maxy) // moved v.11.08 { finhole++; // ran off the edge, seed pixel was break; // not inside area or area has a hole } if (direc == 'x') { // no neighbors left to check sa_Nstack--; continue; } if (sa_Nstack > 1) { ii = sa_Nstack - 2; // get prior pixel in stack ii = sa_stackii[ii]; ppy = ii / Fww; ppx = ii - ppy * Fww; } else { ppx = px - 1; // if only one, assume prior = left ppy = py; } if (direc == 'a') { // next ahead pixel v.11.04 npx = px + px - ppx; npy = py + py - ppy; sa_stackdirec[kk] = 'r'; // next search direction } else if (direc == 'r') { // next right pixel v.11.04 npx = px + py - ppy; npy = py + px - ppx; sa_stackdirec[kk] = 'l'; } else { /* direc = 'l' */ // next left pixel v.11.04 npx = px + ppy - py; npy = py + ppx - px; sa_stackdirec[kk] = 'x'; } if (npx < 0 || npx > Fww-1) continue; // next pixel off the image edge if (npy < 0 || npy > Fhh-1) continue; // bugfix v.11.04 ii = npy * Fww + npx; if (sa_pixmap[ii]) continue; // pixel already mapped sa_pixmap[ii] = 2; // map the pixel, inside area kk = sa_Nstack++; // put pixel into stack sa_stackii[kk] = ii; sa_stackdirec[kk] = 'a'; // direction = ahead v.11.04 draw_pixel(npx,npy,sa_pixRGB); // color mapped pixels zmainloop(10); // let window update v.11.07 } Ffuncbusy--; if (finhole) { // this area has a hole zdialog_stuff(safinzd,"statmess",ZTX("outline has a gap")); sa_finhole++; } else { zdialog_stuff(safinzd,"statmess",ZTX("success")); // all pixels found and mapped sa_finOK++; } return; } // dialog event and completion callback function int sa_finish_dialog_event(zdialog *zd, cchar *event) { int zstat; zstat = zd->zstat; if (! zstat) return 0; freeMouse(); // disconnect mouse zdialog_free(safinzd); // kill dialog if (! sa_stat) return 0; // area gone? v.11.07 if (zstat != 1 || sa_finOK == 0 || sa_finhole) { // user cancel or pixel search failure sa_unfinish(); // unmap interior pixels, set edit mode return 0; // v.11.07 } sa_map_pixels(); // count pixels, map interior pixels sa_stat = 3; // area is finished Factivearea = 1; // area is active by default areanumber++; // next sequential number sa_calced = sa_blend = 0; // edge calculation is missing if (zdsela) zdialog_stuff(zdsela,"blendwidth",0); // v.11.12 mwpaint2(); return 0; } // Finish select area automatically when the // interior selected pixels are already known. void sa_finish_auto() { int ii, px, py; if (! sa_stat) return; // no area? v.11.07 if (sa_fww != Fww || sa_fhh != Fhh) return; // area not valid for image v.11.08 sa_Npixel = Factivearea = 0; // area disabled, unfinished sa_minx = Fww; sa_maxx = 0; sa_miny = Fhh; sa_maxy = 0; for (ii = 0; ii < Fww * Fhh; ii++) // get enclosing rectangle { // for selected area if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - Fww * py; if (px >= sa_maxx) sa_maxx = px+1; // like Fww, sa_maxx = last + 1 if (px < sa_minx) sa_minx = px; if (py >= sa_maxy) sa_maxy = py+1; if (py < sa_miny) sa_miny = py; } sa_minx -= 10; // add margins where possible if (sa_minx < 0) sa_minx = 0; sa_maxx += 10; if (sa_maxx > Fww) sa_maxx = Fww; sa_miny -= 10; if (sa_miny < 0) sa_miny = 0; sa_maxy += 10; if (sa_maxy > Fhh) sa_maxy = Fhh; sa_map_pixels(); // count pixels, map interior pixels sa_stat = 3; // area is finished Factivearea = 1; // area is active by default areanumber++; // next sequential number sa_calced = sa_blend = 0; // edge calculation is missing mwpaint2(); return; } // private function // map edge and interior pixels (sa_pixmap[*] = 1 or 2) // set sa_Npixel = total pixel count void sa_map_pixels() // v.11.07 { int npix, px, py, ii, kk; if (! sa_stat) return; // no area? npix = 0; for (py = sa_miny; py < sa_maxy; py++) // find edge pixels for (px = sa_minx; px < sa_maxx; px++) { ii = py * Fww + px; if (! sa_pixmap[ii]) continue; npix++; if (px == 0 || px == Fww-1 || py == 0 || py == Fhh-1) // edge of image goto edgepix; if (! sa_pixmap[ii-1] || ! sa_pixmap[ii+1]) goto edgepix; // check 8 neighbor pixels kk = ii - Fww; if (! sa_pixmap[kk] || ! sa_pixmap[kk-1] || ! sa_pixmap[kk+1]) goto edgepix; kk = ii + Fww; if (! sa_pixmap[kk] || ! sa_pixmap[kk-1] || ! sa_pixmap[kk+1]) goto edgepix; sa_pixmap[ii] = 2; // interior pixel continue; edgepix: sa_pixmap[ii] = 1; // edge pixel } sa_Npixel = npix; // total pixel count return; } // unfinish an area - unmap interior pixels and put back in edit mode void sa_unfinish() // v.11.07 { int px, py, ii; if (! sa_stat) return; // no area? for (py = sa_miny; py < sa_maxy; py++) // loop pixels in rectangle for (px = sa_minx; px < sa_maxx; px++) { ii = py * Fww + px; // clear interior pixels found if (sa_pixmap[ii] == 2) sa_pixmap[ii] = 0; // by finish search function } sa_stat = 1; // resume edit mode Factivearea = 0; sa_calced = sa_blend = 0; if (zdsela) zdialog_stuff(zdsela,"blendwidth",0); // v.11.12 mwpaint2(); return; } // menu function for show, hide, enable, disable, invert, unselect // (also implemented as buttons in select area dialog) void m_select_show(GtkWidget *, cchar *menu) { zfuncs::F1_help_topic = "area_show_hide"; sa_show(1); return; } void m_select_hide(GtkWidget *, cchar *menu) { zfuncs::F1_help_topic = "area_show_hide"; sa_show(0); return; } void m_select_enable(GtkWidget *, cchar *menu) { zfuncs::F1_help_topic = "area_enable_disable"; sa_enable(); return; } void m_select_disable(GtkWidget *, cchar *menu) { zfuncs::F1_help_topic = "area_enable_disable"; sa_disable(); return; } void m_select_invert(GtkWidget *, cchar *menu) { zfuncs::F1_help_topic = "area_invert"; sa_invert(); return; } void m_select_unselect(GtkWidget *, cchar *menu) // delete the area { zfuncs::F1_help_topic = "area_unselect"; sa_unselect(); return; } // show or hide outline of select area // also called from mwpaint1() if Fshowarea = 1 void sa_show(int flag) { int px, py, ii, kk; if (! sa_stat) return; // no area if (sa_fww != Fww || sa_fhh != Fhh) return; // area not valid for image if (sa_mode == 7) return; // a whole image area if (Fpreview) return; // preview mode, area ignored Fshowarea = flag; // flag for mwpaint1() if (! flag) { mwpaint2(); // erase area outline v.10.8 return; } for (py = 0; py < Fhh; py++) // find pixels in area bugfix v.10.9 for (px = 0; px < Fww; px++) { ii = py * Fww + px; if (! sa_pixmap[ii]) continue; // outside of area if (px == 0 || px == Fww-1 || py == 0 || py == Fhh-1) // edge of image goto edgepix; if (! sa_pixmap[ii-1] || ! sa_pixmap[ii+1]) goto edgepix; // check 8 neighbor pixels kk = ii - Fww; if (! sa_pixmap[kk] || ! sa_pixmap[kk-1] || ! sa_pixmap[kk+1]) goto edgepix; kk = ii + Fww; if (! sa_pixmap[kk] || ! sa_pixmap[kk-1] || ! sa_pixmap[kk+1]) goto edgepix; continue; edgepix: draw_fat_pixel(px,py,sa_pixRGB); // draw fat pixels v.11.04 } return; } // enable select area that was disabled void sa_enable() { if (sa_fww != Fww || sa_fhh != Fhh) return; // area not valid for image v.11.08 if (sa_stat != 3) { zmessageACK(mWin,ZTX("the area is not finished")); // v.11.08 return; // v.11.06.1 } Factivearea = 1; areanumber++; // next sequential number sa_show(1); // v.10.11 return; } // disable select area void sa_disable() { Factivearea = 0; // v.9.7 sa_show(0); // v.10.11 return; } // invert a selected area void sa_invert() { int ii, jj, px, py, npix; if (sa_fww != Fww || sa_fhh != Fhh) return; // area not valid for image v.11.08 if (sa_stat != 3) { // v.11.06.1 zmessageACK(mWin,ZTX("the area is not finished")); return; } if (sa_mode == 7) return; // a whole image area npix = 0; for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; jj = sa_pixmap[ii]; // 0/1/2+ = outside/edge/inside if (px == 0 || px == Fww-1 || py == 0 || py == Fhh-1) // pixel on image edge v.10.12 { if (jj == 0) { sa_pixmap[ii] = 1; // outside pixel >> edge pixel npix++; // count } else sa_pixmap[ii] = 0; // edge pixel >> outside continue; } if (jj > 1) sa_pixmap[ii] = 0; // inside pixel (2+) >> outside (0) else { sa_pixmap[ii] = 2 - jj; // edge/outside (1/0) >> edge/inside (1/2) npix++; // count } } sa_Npixel = npix; // new select area pixel count sa_calced = sa_blend = 0; // edge calculation missing if (zdsela) zdialog_stuff(zdsela,"blendwidth",0); // reset blend width v.11.01 sa_minx = Fww; // new enclosing rectangle bugfix v.11.01 sa_maxx = 0; sa_miny = Fhh; sa_maxy = 0; for (ii = 0; ii < Fww * Fhh; ii++) { if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - Fww * py; if (px >= sa_maxx) sa_maxx = px + 1; if (px < sa_minx) sa_minx = px; if (py >= sa_maxy) sa_maxy = py + 1; if (py < sa_miny) sa_miny = py; } return; } // unselect current area (delete the area) void sa_unselect() { sa_stat = sa_Npixel = sa_blend = sa_calced = Factivearea = 0; sa_currseq = sa_Ncurrseq = 0; sa_fww = sa_fhh = 0; // v.11.08 if (sa_pixmap) zfree(sa_pixmap); if (sa_stackii) zfree(sa_stackii); if (sa_stackdirec) zfree(sa_stackdirec); if (sa_pixselc) zfree(sa_pixselc); sa_pixmap = 0; sa_stackii = 0; sa_stackdirec = 0; sa_pixselc = 0; mwpaint2(); return; } // compute distance from all pixels in area to nearest edge // output: sa_pixmap[*] = 0/1/2+ = outside, edge, inside distance from edge namespace sa_edgecalc_names { uint16 *sa_edgepx, *sa_edgepy, *sa_edgedist; int sa_Nedge; } void sa_edgecalc() { using namespace sa_edgecalc_names; int edgecalc_dialog_event(zdialog*, cchar *event); void * edgecalc_thread(void *); int ii, nn, cc, px, py; zdialog *zd = 0; cchar *zectext = ZTX("Edge calculation in progress"); if (! sa_stat) return; // area gone? v.11.07 if (sa_mode == 7) return; // a whole image area if (sa_calced) return; // done already if (! Factivearea) sa_finish(); // finish if needed if (! Factivearea) return; // no finished area zd = zdialog_new(ZTX("Area Edge Calc"),mWin,Bcancel,null); // start dialog for user cancel zdialog_add_widget(zd,"label","lab1","dialog",zectext,"space=10"); zdialog_run(zd,edgecalc_dialog_event); Fkillfunc = 0; cc = Fww * Fhh * sizeof(uint16); // allocate memory for calculations sa_edgedist = (uint16 *) zmalloc(cc,"sa_edgecalc"); memset(sa_edgedist,0,cc); for (ii = nn = 0; ii < Fww * Fhh; ii++) // count edge pixels in select area if (sa_pixmap[ii] == 1) nn++; cc = nn * sizeof(uint16); sa_edgepx = (uint16 *) zmalloc(cc,"sa_edgecalc"); // allocate memory sa_edgepy = (uint16 *) zmalloc(cc,"sa_edgecalc"); for (ii = nn = 0; ii < Fww * Fhh; ii++) // build list of edge pixels { // v.9.6 if (sa_pixmap[ii] != 1) continue; py = ii / Fww; px = ii - py * Fww; if (px < 3 || px > Fww-4) continue; // omit pixels < 3 from image edge if (py < 3 || py > Fhh-4) continue; sa_edgepx[nn] = px; sa_edgepy[nn] = py; nn++; } sa_Nedge = nn; SB_goal = sa_Npixel; SB_done = 0; for (ii = 0; ii < Nwt; ii++) // start worker threads to calculate start_wthread(edgecalc_thread,&wtnx[ii]); // sa_pixmap[] edge distances wait_wthreads(); // wait for completion SB_goal = 0; if (! Fkillfunc) { // v.11.07 for (ii = 0; ii < Fww * Fhh; ii++) // copy data from sa_edgedist[] { // to sa_pixmap[] if (sa_pixmap[ii] < 2) continue; // skip outside and edge pixels sa_pixmap[ii] = sa_edgedist[ii]; // interior pixel edge distance } } zdialog_free(zd); // kill dialog zfree(sa_edgedist); // free memory zfree(sa_edgepx); zfree(sa_edgepy); if (Fkillfunc) { Fkillfunc = 0; sa_calced = 0; if (zdsela) zdialog_stuff(zdsela,"blendwidth",0); // reset blend width v.11.01 } sa_calced = 1; // edge calculation available mwpaint2(); return; } // dialog event and completion callback function int edgecalc_dialog_event(zdialog *zd, cchar *event) // respond to user cancel { if (! zd->zstat) return 0; Fkillfunc = 1; printf("edge calc killed \n"); return 0; } void * edgecalc_thread(void *arg) // worker thread function { // new algorithm v.11.05 using namespace sa_edgecalc_names; void edgecalc_f1(int px, int py); int index = *((int *) (arg)); int midx, midy, radx, rady, rad; int ii, px, py; midx = (sa_maxx + sa_minx) / 2; midy = (sa_maxy + sa_miny) / 2; radx = (sa_maxx - sa_minx) / 2 + 1; rady = (sa_maxy - sa_miny) / 2 + 1; px = midx; // center of enclosing rectangle py = midy; ii = py * Fww + px; if (sa_pixmap[ii]) edgecalc_f1(px,py); // do center pixel first for (rad = 1; rad < radx || rad < rady; rad++) // expanding square from the center { for (px = midx-rad; px <= midx+rad; px += 2 * rad) // process edges only, interior already done for (py = midy-rad+index; py <= midy+rad; py += Nwt) { if (px < 0 || px > Fww-1) continue; if (py < 0 || py > Fhh-1) continue; ii = py * Fww + px; if (! sa_pixmap[ii]) continue; if (sa_edgedist[ii]) continue; edgecalc_f1(px,py); if (Fkillfunc) exit_wthread(); } for (py = midy-rad; py <= midy+rad; py += 2 * rad) for (px = midx-rad+index; px <= midx+rad; px += Nwt) { if (px < 0 || px > Fww-1) continue; if (py < 0 || py > Fhh-1) continue; ii = py * Fww + px; if (! sa_pixmap[ii]) continue; if (sa_edgedist[ii]) continue; edgecalc_f1(px,py); if (Fkillfunc) exit_wthread(); } } exit_wthread(); return 0; // not executed, stop gcc warning } // Find the nearest edge pixel for a given pixel. // For all pixels in a line from the given pixel to the edge pixel, // the same edge pixel is used to compute edge distance. void edgecalc_f1(int px1, int py1) { using namespace sa_edgecalc_names; int ii, px2, py2, mindist; uint dist2, mindist2; int epx, epy, pxm, pym, dx, dy, inc; double slope; mindist = 9999; mindist2 = mindist * mindist; epx = epy = 0; for (ii = 0; ii < sa_Nedge; ii++) // loop all edge pixels { px2 = sa_edgepx[ii]; py2 = sa_edgepy[ii]; dx = px2 - px1; dy = py2 - py1; dist2 = dx*dx + dy*dy; // avoid sqrt() if (dist2 < mindist2) { mindist2 = dist2; // remember minimum epx = px2; // remember nearest edge pixel mindist = sqrt(dist2); epy = py2; } } if (abs(epy - py1) > abs(epx - px1)) { // find all pixels along a line slope = 1.0 * (epx - px1) / (epy - py1); // to the edge pixel if (epy > py1) inc = 1; else inc = -1; for (pym = py1; pym != epy; pym += inc) { pxm = px1 + slope * (pym - py1); ii = pym * Fww + pxm; if (sa_edgedist[ii]) break; dx = epx - pxm; // calculate distance to edge dy = epy - pym; dist2 = sqrt(dx*dx + dy*dy) + 2; sa_edgedist[ii] = dist2; // save SB_done++; // track progress v.11.06 } } else { slope = 1.0 * (epy - py1) / (epx - px1); if (epx > px1) inc = 1; else inc = -1; for (pxm = px1; pxm != epx; pxm += inc) { pym = py1 + slope * (pxm - px1); ii = pym * Fww + pxm; if (sa_edgedist[ii]) break; dx = epx - pxm; dy = epy - pym; dist2 = sqrt(dx*dx + dy*dy) + 2; sa_edgedist[ii] = dist2; SB_done++; } } return; } /************************************************************************** select area copy and paste menu functions ***************************************************************************/ PXM *sacp_image16 = 0; // select area pixmap image PXM *sacp_info16 = 0; // opacity and edge distance int sacp_ww, sacp_hh; // original dimensions PXM *sacpR_image16 = 0; // resized/rotated image PXM *sacpR_info16 = 0; // resized/rotated info int sacpR_ww, sacpR_hh; // resized/rotated dimensions double sacp_resize; // size, 1.0 = original size double sacp_angle; // angle of rotation, -180 to +180 int sacp_orgx, sacp_orgy; // origin in target image double sacp_blend; // edge blend with target image // copy selected area, save in memory void m_select_copy(GtkWidget *, cchar *menu) // overhauled v.11.02 { int ii, px, py; int pxmin, pxmax, pymin, pymax; uint16 *pix1, *pix2; if (menu) zfuncs::F1_help_topic = "area_copy_paste"; if (sa_mode == 7) return; // a whole image area v.11.01 if (! Factivearea) sa_finish(); // finish area if not already if (! Factivearea) return; sa_edgecalc(); // do edge calc if not already sa_show(0); pxmin = Fww; pxmax = 0; pymin = Fhh; pymax = 0; for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { // v.9.6 if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - py * Fww; if (px > pxmax) pxmax = px; // find enclosing rectangle if (px < pxmin) pxmin = px; if (py > pymax) pymax = py; if (py < pymin) pymin = py; } PXM_free(sacp_image16); // free prior if any PXM_free(sacp_info16); PXM_free(sacpR_image16); PXM_free(sacpR_info16); sacp_ww = pxmax - pxmin + 1; // new area image PXM sacp_hh = pymax - pymin + 1; sacp_image16 = PXM_make(sacp_ww,sacp_hh,16); sacp_info16 = PXM_make(sacp_ww,sacp_hh,16); // new info PXM for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { if (! sa_pixmap[ii]) continue; // 0/1/2+ = outside/edge/inside edge distance py = ii / Fww; px = ii - py * Fww; pix1 = PXMpix(Fpxm16,px,py); // copy pixels into image PXM px = px - pxmin; py = py - pymin; pix2 = PXMpix(sacp_image16,px,py); pix2[0] = pix1[0]; pix2[1] = pix1[1]; pix2[2] = pix1[2]; pix2 = PXMpix(sacp_info16,px,py); // build info PXM v.11.02 pix2[0] = 65535; // opacity pix2[1] = sa_pixmap[ii]; // edge distance pix2[2] = 0; } return; } // paste selected area into current image // this is an edit function - select area image is copied into main image int sacp_porg = 0; // pasted area is present int sacp_porgx, sacp_porgy; // pasted area origin in image int sacp_pww, sacp_phh; // pasted area dimensions editfunc EFpaste; void m_select_paste(GtkWidget *, cchar *menu) // menu function { int select_paste_dialog_event(zdialog *, cchar *event); void select_paste_mousefunc(); cchar *dragmess = ZTX("position with mouse click/drag"); if (menu) zfuncs::F1_help_topic = "area_copy_paste"; if (! sacp_image16) return; // nothing to paste sa_unselect(); // unselect area if present EFpaste.funcname = "paste"; if (! edit_setup(EFpaste)) return; // setup edit for paste sacp_resize = 1.0; // size = 1x sacp_blend = 1; // edge blend = 1 sacp_angle = 0; // angle = 0 PXM_free(sacpR_image16); // free prior if any PXM_free(sacpR_info16); sacpR_ww = sacp_ww; // setup resized paste image sacpR_hh = sacp_hh; // (initially 1x, 0 rotation) sacpR_image16 = PXM_copy(sacp_image16); sacpR_info16 = PXM_copy(sacp_info16); sacp_porg = 0; // no image paste location yet CEF->zd = zdialog_new(ZTX("Paste Image"),mWin,Bdone,Bcancel,null); zdialog_add_widget(CEF->zd,"hbox","hb0","dialog",0,"space=8"); zdialog_add_widget(CEF->zd,"label","lab1","hb0",dragmess,"space=8"); zdialog_add_widget(CEF->zd,"hbox","hbres","dialog",0,"space=5"); zdialog_add_widget(CEF->zd,"label","labres","hbres","resize"); zdialog_add_widget(CEF->zd,"button","+.1%","hbres","+.1%"); zdialog_add_widget(CEF->zd,"button","+1%","hbres","+1%"); zdialog_add_widget(CEF->zd,"button","+10%","hbres","+10%"); zdialog_add_widget(CEF->zd,"button","-.1%","hbres","-.1%"); zdialog_add_widget(CEF->zd,"button","-1%","hbres","-1%"); zdialog_add_widget(CEF->zd,"button","-10%","hbres","-10%"); zdialog_add_widget(CEF->zd,"hbox","hbang","dialog",0,"space=5"); // rotation v.11.02 zdialog_add_widget(CEF->zd,"label","labang","hbang",ZTX("angle")); zdialog_add_widget(CEF->zd,"button","+.1°","hbang","+.1°"); zdialog_add_widget(CEF->zd,"button","+1°","hbang","+1°"); zdialog_add_widget(CEF->zd,"button","+10°","hbang","+10°"); zdialog_add_widget(CEF->zd,"button","-.1°","hbang","-.1°"); zdialog_add_widget(CEF->zd,"button","-1°","hbang","-1°"); zdialog_add_widget(CEF->zd,"button","-10°","hbang","-10°"); zdialog_add_widget(CEF->zd,"hbox","hbbl","dialog",0,"space=5"); zdialog_add_widget(CEF->zd,"label","lab2","hbbl","edge blend"); zdialog_add_widget(CEF->zd,"hscale","blend","hbbl","0|20|0.3|0","expand"); // v.11.06 zdialog_help(CEF->zd,"area_copy_paste"); // zdialog help topic v.11.08 zdialog_run(CEF->zd,select_paste_dialog_event,"80/20"); // v.11.07 takeMouse(CEF->zd,select_paste_mousefunc,0); // connect mouse function return; } // Dialog event and completion callback function // Get dialog values and convert image. When done, commit edited image // (with pasted area) and set up a new select area for the pasted area, // allowing further editing of the area. int select_paste_dialog_event(zdialog *zd, cchar *event) { void select_paste_mousefunc(); void select_paste_pixmap(); void select_paste_makearea(); int ww, hh; PXM *pxm_temp; if (zd->zstat) // dialog completed { freeMouse(); // disconnect mouse if (zd->zstat != 1 || ! sacp_porg) { // cancel paste edit_cancel(EFpaste); // cancel edit, restore image sa_unselect(); return 0; } edit_done(EFpaste); // commit the edit (pasted image) select_paste_makearea(); // make equivalent select area PXM_free(sacpR_image16); // free memory PXM_free(sacpR_info16); return 0; } if (strEqu(event,"focus")) // toggle mouse capture v.12.01 takeMouse(zd,select_paste_mousefunc,0); if (strstr(event,"%") || strstr(event,"°")) // new size or angle { if (strEqu(event,"+.1%")) sacp_resize *= 1.001; if (strEqu(event,"+1%")) sacp_resize *= 1.01; if (strEqu(event,"+10%")) sacp_resize *= 1.10; if (strEqu(event,"-.1%")) sacp_resize *= 0.999001; if (strEqu(event,"-1%")) sacp_resize *= 0.990099; if (strEqu(event,"-10%")) sacp_resize *= 0.909091; // -10% is really 1.0/1.10 if (strEqu(event,"+.1°")) sacp_angle += 0.1; // rotation v.11.02 if (strEqu(event,"+1°")) sacp_angle += 1.0; if (strEqu(event,"+10°")) sacp_angle += 10.0; if (strEqu(event,"-.1°")) sacp_angle -= 0.1; if (strEqu(event,"-1°")) sacp_angle -= 1.0; if (strEqu(event,"-10°")) sacp_angle -= 10.0; PXM_free(sacpR_image16); // free prior if any PXM_free(sacpR_info16); ww = sacp_resize * sacp_ww; // new size hh = sacp_resize * sacp_hh; pxm_temp = PXM_rescale(sacp_image16,ww,hh); // resized area image sacpR_image16 = PXM_rotate(pxm_temp,sacp_angle); // rotated area image PXM_free(pxm_temp); pxm_temp = PXM_rescale(sacp_info16,ww,hh); // resized area info sacpR_info16 = PXM_rotate(pxm_temp,sacp_angle); // rotated/resized area info PXM_free(pxm_temp); sacpR_ww = sacpR_image16->ww; // size after resize/rotate sacpR_hh = sacpR_image16->hh; select_paste_pixmap(); // copy onto target image } if (strEqu(event,"blend") && sacp_porg) { zdialog_fetch(zd,"blend",sacp_blend); // new edge blend distance select_paste_pixmap(); // copy onto target image } CEF->Fmod = 1; // image is modified mwpaint2(); return 0; } // convert the pasted image area into an equivalent select area by mouse void select_paste_makearea() { int cc, ii; int px1, py1, px2, py2; uint16 *pix2; sa_unselect(); // unselect old area cc = Fww * Fhh * sizeof(uint16); sa_pixmap = (uint16 *) zmalloc(cc,"sa_paste"); // pixel map for new area memset(sa_pixmap,0,cc); for (py1 = 0; py1 < sacpR_hh; py1++) // map non-transparent pixels for (px1 = 0; px1 < sacpR_ww; px1++) // into sa_pixmap[] { pix2 = PXMpix(sacpR_info16,px1,py1); // opacity and edge distance if (pix2[0] == 0) continue; // transparent px2 = px1 + sacp_orgx; py2 = py1 + sacp_orgy; if (px2 < 0 || px2 > Fww-1) continue; // parts may be beyond edges if (py2 < 0 || py2 > Fhh-1) continue; ii = py2 * Fww + px2; sa_pixmap[ii] = 1; } sa_stat = 1; sa_mode = 5; // equivalent select/mouse area sa_fww = Fww; // v.11.08 sa_fhh = Fhh; sa_finish_auto(); // v.11.04 sa_show(1); return; } // mouse function - follow mouse drags and move pasted area accordingly void select_paste_mousefunc() { void select_paste_pixmap(); int mx1, my1, mx2, my2; static int mdx0, mdy0, mdx1, mdy1; if (LMclick) { // left mouse click LMclick = 0; sacp_orgx = Mxclick - sacpR_ww / 2; // position image at mouse v.10.11 sacp_orgy = Myclick - sacpR_hh / 2; select_paste_pixmap(); CEF->Fmod = 1; // image is modified } if (! sacp_porg) return; // no select area paste yet if (Mxposn < sacp_orgx || Mxposn > sacp_orgx + sacpR_ww || // mouse outside select area Myposn < sacp_orgy || Myposn > sacp_orgy + sacpR_hh) gdk_window_set_cursor(drWin->window,0); // set normal cursor v.11.03 else gdk_window_set_cursor(drWin->window,dragcursor); // set drag cursor v.11.03 if (Mxdrag + Mydrag == 0) return; // no drag underway if (Mxdown != mdx0 || Mydown != mdy0) { // new drag initiated mdx0 = mdx1 = Mxdown; mdy0 = mdy1 = Mydown; } mx1 = mdx1; // drag start my1 = mdy1; mx2 = Mxdrag; // drag position my2 = Mydrag; mdx1 = mx2; // next drag start mdy1 = my2; sacp_orgx += (mx2 - mx1); // move position of select area sacp_orgy += (my2 - my1); // by mouse drag amount select_paste_pixmap(); // re-copy area to new position CEF->Fmod = 1; // image is modified return; } // copy select area into edit image, starting at sacp_orgx/y void select_paste_pixmap() // overhauled v.11.02 { int px1, py1, px3, py3, opac, dist; uint16 *pix1, *pix3; double f1, f2; if (sacp_porg) // prior area overlap rectangle { for (py1 = 0; py1 < sacp_phh; py1++) // restore original image pixels v.10.11 for (px1 = 0; px1 < sacp_pww; px1++) { px3 = px1 + sacp_porgx; py3 = py1 + sacp_porgy; if (px3 < 0 || px3 >= E3ww) continue; // parts may be beyond edges if (py3 < 0 || py3 >= E3hh) continue; pix1 = PXMpix(E1pxm16,px3,py3); pix3 = PXMpix(E3pxm16,px3,py3); pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } for (py1 = 0; py1 < sacpR_hh; py1++) // copy paste area pixels to new for (px1 = 0; px1 < sacpR_ww; px1++) // image overlap rectangle { pix1 = PXMpix(sacpR_info16,px1,py1); // opacity and edge distance opac = pix1[0]; dist = pix1[1]; if (opac == 0) continue; // skip transparent pixel px3 = px1 + sacp_orgx; py3 = py1 + sacp_orgy; if (px3 < 0 || px3 >= E3ww) continue; // parts may be beyond edges if (py3 < 0 || py3 >= E3hh) continue; pix1 = PXMpix(sacpR_image16,px1,py1); // paste image pixel pix3 = PXMpix(E3pxm16,px3,py3); // target image pixel if (dist > sacp_blend) f1 = 1.0; // minor bugfix v.11.06 else f1 = 1.0 * dist / sacp_blend; // opacity reduction from edge blend f1 = f1 * opac / 65535.0; // opacity reduction from resize/rescale f2 = 1.0 - f1; pix3[0] = f1 * pix1[0] + f2 * pix3[0]; // blend paste and target images pix3[1] = f1 * pix1[1] + f2 * pix3[1]; pix3[2] = f1 * pix1[2] + f2 * pix3[2]; } mwpaint3(sacp_porgx,sacp_porgy,sacp_pww,sacp_phh); // update window for old overlap area mwpaint3(sacp_orgx,sacp_orgy,sacpR_ww,sacpR_hh); // update window for new overlap area sacp_porgx = sacp_orgx; // remember location for next call sacp_porgy = sacp_orgy; sacp_pww = sacpR_ww; sacp_phh = sacpR_hh; sacp_porg = 1; return; } /************************************************************************** select area load from file and save to file functions v.9.9 ***************************************************************************/ // Load a select area from a disk file and paste into current image. void m_select_open(GtkWidget *, cchar *) { char *pfile1, *pfile2, *pp; zfuncs::F1_help_topic = "area_open_save"; // v.10.8 pp = zgetfile1(ZTX("load select area from a file"),"open",saved_areas_dirk); if (! pp) return; pfile1 = strdupz(pp,8,"select_open"); zfree(pp); pp = strrchr(pfile1,'/'); if (pp) pp = strrchr(pp,'.'); if (pp) strcpy(pp,".tiff"); else strcat(pfile1,".tiff"); pfile2 = strdupz(pfile1,0,"select_open"); pp = strrchr(pfile2,'.'); strcpy(pp,".info"); PXM_free(sacp_image16); // free prior if any PXM_free(sacp_info16); sacp_image16 = TIFFread(pfile1); // .tiff file --> image PXM if (! sacp_image16) goto fail; sacp_info16 = TIFFread(pfile2); // .info file --> info PXM if (! sacp_info16) goto fail; zfree(pfile1); zfree(pfile2); sacp_ww = sacp_image16->ww; // paste into current image sacp_hh = sacp_image16->hh; m_select_paste(0,0); return; fail: zfree(pfile1); zfree(pfile2); zmessageACK(mWin,ZTX("cannot open .tiff and .info files")); return; } // save a select area as a disk file void m_select_save(GtkWidget *, cchar *) { char *pfile1, *pfile2, *pp; zfuncs::F1_help_topic = "area_open_save"; // v.10.11 if (sa_mode == 7) return; // a whole image area v.11.01 if (! Factivearea) sa_finish(); // finish select area if not already if (! Factivearea) return; // v.11.06.1 m_select_copy(0,0); // copy select area to memory if (! sacp_image16) return; pp = zgetfile1(ZTX("save select area to a file"),"save",saved_areas_dirk); if (! pp) return; pfile1 = strdupz(pp,8,"select_save"); zfree(pp); pp = strrchr(pfile1,'/'); if (pp) pp = strrchr(pp,'.'); if (pp) strcpy(pp,".tiff"); else strcat(pfile1,".tiff"); pfile2 = strdupz(pfile1,0,"select_save"); pp = strrchr(pfile2,'.'); strcpy(pp,".info"); TIFFwrite(sacp_image16,pfile1); // image PXM --> .tiff file TIFFwrite(sacp_info16,pfile2); // info PXM --> .info file return; } /**************************************************************************/ // Select the whole image as an area. // Set "edge distance" 1 to 255 from pixel or RGB color brightness. // Set "blend width" to 255 // Edit function coefficient = edge distance / blend width. spldat * select_whole_image_curve; void m_select_whole_image(GtkWidget *, cchar *) // new v.11.01 { int select_whole_image_event(zdialog *, cchar *event); // dialog event and completion func void select_whole_image_curve_update(int spc); // curve update callback function cchar *title = ZTX("Select Whole Image"); cchar *legend = ZTX("Edit Function Amplifier"); zfuncs::F1_help_topic = "select_whole_image"; if (! curr_file) return; // no image if (zdsela) return; // select dialog already active if (Fpreview) edit_fullsize(); // use full-size image /*** Edit Function Amplifier ------------------------------------------ | | | | | curve drawing area | | | | | ------------------------------------------ darker areas lighter areas [+++] [---] [+ -] [- +] [+-+] [-+-] (o) Brightness (o) Red (o) Green (o) Blue Curve File: [ Open ] [ Save ] [ Done ] ***/ zdsela = zdialog_new(title,mWin,Bdone,null); zdialog_add_widget(zdsela,"label","labt","dialog",legend); zdialog_add_widget(zdsela,"frame","fr1","dialog",0,"expand"); zdialog_add_widget(zdsela,"hbox","hba","dialog"); zdialog_add_widget(zdsela,"label","labda","hba",Bdarker,"space=5"); zdialog_add_widget(zdsela,"label","space","hba",0,"expand"); zdialog_add_widget(zdsela,"label","labba","hba",Blighter,"space=5"); zdialog_add_widget(zdsela,"hbox","hbb","dialog",0,"space=5"); zdialog_add_widget(zdsela,"button","b +++","hbb","+++"); zdialog_add_widget(zdsela,"button","b ---","hbb","‒ ‒ ‒"); zdialog_add_widget(zdsela,"button","b +-", "hbb"," + ‒ "); zdialog_add_widget(zdsela,"button","b -+", "hbb"," ‒ + "); zdialog_add_widget(zdsela,"button","b +-+","hbb","+ ‒ +"); zdialog_add_widget(zdsela,"button","b -+-","hbb","‒ + ‒"); zdialog_add_widget(zdsela,"hbox","hbbr","dialog",0,"space=5"); zdialog_add_widget(zdsela,"radio","bright","hbbr",Bbrightness,"space=5"); zdialog_add_widget(zdsela,"radio","red","hbbr",Bred,"space=5"); zdialog_add_widget(zdsela,"radio","green","hbbr",Bgreen,"space=5"); zdialog_add_widget(zdsela,"radio","blue","hbbr",Bblue,"space=5"); zdialog_add_widget(zdsela,"hbox","hbcf","dialog",0,"space=5"); zdialog_add_widget(zdsela,"label","labcf","hbcf",Bcurvefile,"space=5"); zdialog_add_widget(zdsela,"button","load","hbcf",Bopen,"space=5"); zdialog_add_widget(zdsela,"button","save","hbcf",Bsave,"space=5"); GtkWidget *frame = zdialog_widget(zdsela,"fr1"); // setup for curve editing spldat *sd = splcurve_init(frame,select_whole_image_curve_update); // v.11.01 select_whole_image_curve = sd; sd->Nspc = 1; sd->vert[0] = 0; sd->nap[0] = 3; // initial curve anchor points sd->apx[0][0] = 0.01; sd->apy[0][0] = 0.5; sd->apx[0][1] = 0.50; sd->apy[0][1] = 0.5; sd->apx[0][2] = 0.99; sd->apy[0][2] = 0.5; splcurve_generate(sd,0); // generate curve data zdialog_stuff(zdsela,"bright",1); zdialog_stuff(zdsela,"red",0); zdialog_stuff(zdsela,"green",0); zdialog_stuff(zdsela,"blue",0); sa_unselect(); // unselect current area if any zdialog_resize(zdsela,0,360); zdialog_help(zdsela,"select_whole_image"); // zdialog help topic v.11.08 zdialog_run(zdsela,select_whole_image_event,"80/20"); // run dialog - parallel v.11.07 select_whole_image_event(zdsela,"init"); // initialize default params return; } // dialog event and completion function int select_whole_image_event(zdialog *zd, cchar *event) { int ii, kk, cc, base, pixbright, pixdist; double px, py, xval, yval; uint8 *pixel; spldat *sd = select_whole_image_curve; if (zd->zstat) { // done, kill dialog zdialog_free(zdsela); zfree(sd); // free curve edit memory return 0; } if (! sa_stat) // if no area exists { cc = Fww * Fhh * sizeof(uint16); // allocate sa_pixmap[] for new area sa_pixmap = (uint16 *) zmalloc(cc,"sa_select_image"); sa_minx = 0; // enclosing rectangle sa_maxx = Fww; sa_miny = 0; sa_maxy = Fhh; sa_Npixel = Fww * Fhh; sa_stat = 3; // area status = complete sa_mode = 7; // area mode = whole image sa_calced = 1; // edge calculation complete sa_blend = 255; // "blend width" = 255 sa_fww = Fww; // valid image dimensions v.11.08 sa_fhh = Fhh; Factivearea = 1; // area is active areanumber++; // next sequential number } if (strEqu(event,"load")) { // load saved curve v.11.02 splcurve_load(sd); if (CEF && CEF->zd) zdialog_send_event(CEF->zd,"blendwidth"); // notify edit dialog return 0; } if (strEqu(event,"save")) { // save curve to file v.11.02 splcurve_save(sd); return 0; } base = 0; zdialog_fetch(zd,"bright",ii); // set brightness or color to be used if (ii) base = 1; zdialog_fetch(zd,"red",ii); if (ii) base = 2; zdialog_fetch(zd,"green",ii); if (ii) base = 3; zdialog_fetch(zd,"blue",ii); if (ii) base = 4; if (! base) return 0; if (strnEqu(event,"b ",2)) { // button to move entire curve for (ii = 0; ii < sd->nap[0]; ii++) { px = sd->apx[0][ii]; py = sd->apy[0][ii]; if (strEqu(event,"b +++")) py += 0.1; if (strEqu(event,"b ---")) py -= 0.1; if (strEqu(event,"b +-")) py += 0.1 - 0.2 * px; if (strEqu(event,"b -+")) py -= 0.1 - 0.2 * px; if (strEqu(event,"b +-+")) py -= 0.05 - 0.2 * fabs(px-0.5); if (strEqu(event,"b -+-")) py += 0.05 - 0.2 * fabs(px-0.5); if (py > 1) py = 1; if (py < 0) py = 0; sd->apy[0][ii] = py; } } splcurve_generate(sd,0); // regenerate the curve splcurve_draw(0,0,sd); pixel = (uint8 *) Fpxm8->bmp; for (ii = 0; ii < Fww * Fhh; ii++) // loop all pixels { pixbright = pixel[0] + pixel[1] + pixel[2] + 1; // brightness of pixel, 1 - 766 if (base == 1) pixbright = pixbright / 3; // brightness, 0 - 255 bugfix v.11.01.2 else if (base == 2) pixbright = 255 * pixel[0] / pixbright; // red part: 0 - 255 = 100% red else if (base == 3) pixbright = 255 * pixel[1] / pixbright; // green part else if (base == 4) pixbright = 255 * pixel[2] / pixbright; // blue part xval = pixbright / 256.0; // curve x-value, 0 to 0.999 kk = 1000 * xval; // speedup v.11.06 if (kk > 999) kk = 999; yval = sd->yval[0][kk]; pixdist = 255 * yval; // pixel "edge distance" 0 to 255 sa_pixmap[ii] = pixdist | 1; // avoid 0 (pixel outside area) pixel += 3; } if (CEF && CEF->zd) zdialog_send_event(CEF->zd,"blendwidth"); // notify edit dialog return 0; } // this function is called when curve is edited using mouse void select_whole_image_curve_update(int) { select_whole_image_event(zdsela,"edit"); return; } /**************************************************************************/ // Select area and edit in parallel // Current edit function is applied to areas painted with the mouse. // Mouse can be weak or strong, and edits are applied incrementally. // method: // entire image is a select area with all pixel edge distance = 0 (outside area) // blendwidth = 10000 // pixels painted with mouse have increasing edge distance to amplify edits int select_edit_radius; int select_edit_cpower; int select_edit_epower; void m_select_edit(GtkWidget *, cchar *) // menu function v.11.02 { int select_edit_dialog_event(zdialog *, cchar *event); // dialog event function void select_edit_mousefunc(); // mouse function cchar *title = ZTX("Select Area for Edits"); cchar *helptext1 = ZTX("Press F1 for help"); cchar *helptext2 = ZTX("Edit function must be active"); int cc; zfuncs::F1_help_topic = "select_edit"; if (! curr_file) return; // no image if (zdsela) return; // select area already active if (Fpreview) edit_fullsize(); // use full-size image if (! Fpxm16) { // create Fpxm16 if not already mutex_lock(&Fpixmap_lock); Fpxm16 = f_load(curr_file,16); mutex_unlock(&Fpixmap_lock); if (! Fpxm16) return; } /*** ____________________________________________ | Press F1 for help | | Edit Function must be active | | mouse radius [___|v] | | power: center [___|v] edge [___|v] | | [reset area] | | [done] | |____________________________________________| ***/ zdsela = zdialog_new(title,mWin,Bdone,null); zdialog_add_widget(zdsela,"label","labhelp1","dialog",helptext1,"space=5"); zdialog_add_widget(zdsela,"label","labhelp2","dialog",helptext2); zdialog_add_widget(zdsela,"label","labspace","dialog"); zdialog_add_widget(zdsela,"hbox","hbr","dialog",0,"space=3"); zdialog_add_widget(zdsela,"label","labr","hbr",ZTX("mouse radius"),"space=5"); zdialog_add_widget(zdsela,"spin","radius","hbr","2|500|1|50"); zdialog_add_widget(zdsela,"hbox","hbt","dialog",0,"space=3"); zdialog_add_widget(zdsela,"label","labtc","hbt",ZTX("power: center"),"space=5"); zdialog_add_widget(zdsela,"spin","center","hbt","0|100|1|50"); zdialog_add_widget(zdsela,"label","labte","hbt",ZTX("edge"),"space=5"); zdialog_add_widget(zdsela,"spin","edge","hbt","0|100|1|0"); zdialog_add_widget(zdsela,"hbox","hbr","dialog",0,"space=5"); zdialog_add_widget(zdsela,"button","reset","hbr",ZTX("reset area"),"space=5"); select_edit_radius = 50; select_edit_cpower = 50; select_edit_epower = 0; sa_unselect(); // unselect current area if any cc = Fww * Fhh * sizeof(uint16); // allocate sa_pixmap[] for new area sa_pixmap = (uint16 *) zmalloc(cc,"sa_select_edit"); memset(sa_pixmap,0,cc); // edge distance = 0 for all pixels sa_minx = 0; // enclosing rectangle sa_maxx = Fww; sa_miny = 0; sa_maxy = Fhh; sa_Npixel = Fww * Fhh; sa_stat = 3; // area status = complete sa_mode = 7; // area mode = whole image sa_calced = 1; // edge calculation complete sa_blend = 10000; // "blend width" sa_fww = Fww; // valid image dimensions v.11.08 sa_fhh = Fhh; Factivearea = 1; // area is active areanumber++; // next sequential number zdialog_help(zdsela,"select_edit"); // zdialog help topic v.11.08 zdialog_run(zdsela,select_edit_dialog_event,"80/20"); // run dialog - parallel v.11.07 return; } // tailor whole image area to increase edit power for pixels within the mouse radius // sa_pixmap[*] = 0 = never touched by mouse // = 1 = minimum edit power (barely painted) // = sa_blend = maximum edit power (edit fully applied) int select_edit_dialog_event(zdialog *zd, cchar *event) { void select_edit_mousefunc(); // mouse function int cc; if (! Factivearea) return 1; // area gone v.11.06.1 if (zd->zstat) // done or cancel { freeMouse(); // disconnect mouse function zdialog_free(zdsela); // kill dialog sa_unselect(); // unselect area return 0; } if (strEqu(event,"focus")) { // toggle mouse capture v.12.01 if (CEF) takeMouse(zd,select_edit_mousefunc,0); else freeMouse(); // disconnect mouse } if (strEqu(event,"radius")) zdialog_fetch(zd,"radius",select_edit_radius); // set mouse radius if (strEqu(event,"center")) zdialog_fetch(zd,"center",select_edit_cpower); // set mouse center power if (strEqu(event,"edge")) zdialog_fetch(zd,"edge",select_edit_epower); // set mouse edge power if (strEqu(event,"reset")) { sa_unselect(); // unselect current area if any cc = Fww * Fhh * sizeof(uint16); // allocate sa_pixmap[] for new area sa_pixmap = (uint16 *) zmalloc(cc,"sa_select_edit"); memset(sa_pixmap,0,cc); // edge distance = 0 for all pixels sa_minx = 0; // enclosing rectangle sa_maxx = Fww; sa_miny = 0; sa_maxy = Fhh; sa_Npixel = Fww * Fhh; sa_stat = 3; // area status = complete sa_mode = 7; // area mode = whole image sa_calced = 1; // edge calculation complete sa_blend = 10000; // "blend width" sa_fww = Fww; // valid image dimensions v.11.08 sa_fhh = Fhh; Factivearea = 1; // area is active areanumber++; // next sequential number } return 1; } // mouse function - adjust edit strength for areas within mouse radius // "edge distance" is increased for more strength, decreased for less void select_edit_mousefunc() { int ii, cc, px, py, rx, ry; int radius, radius2, cpower, epower; double rad, rad2, power; // v.11.06 if (! CEF) { // no active edit freeMouse(); return; } if (! sa_stat) // area gone? v.11.07 { cc = Fww * Fhh * sizeof(uint16); // allocate sa_pixmap[] for new area sa_pixmap = (uint16 *) zmalloc(cc,"sa_select_edit"); memset(sa_pixmap,0,cc); // clear to zeros sa_minx = 0; // enclosing rectangle sa_maxx = Fww; sa_miny = 0; sa_maxy = Fhh; sa_Npixel = Fww * Fhh; sa_stat = 3; // area status = complete sa_mode = 7; // area mode = whole image sa_calced = 1; // edge calculation complete sa_blend = 10000; // "blend width" sa_fww = Fww; // valid image dimensions v.11.08 sa_fhh = Fhh; Factivearea = 1; // area is active areanumber++; // next sequential number } radius = select_edit_radius; // pixel selection radius radius2 = radius * radius; cpower = select_edit_cpower; epower = select_edit_epower; toparcx = Mxposn - radius; // draw mouse outline circle toparcy = Myposn - radius; toparcw = toparch = 2 * radius; Ftoparc = 1; paint_toparc(3); if (LMclick || RMclick) // mouse click LMclick = RMclick = 0; if (Mbutton != 1 && Mbutton != 3) // button released return; for (rx = -radius; rx <= radius; rx++) // loop every pixel in radius for (ry = -radius; ry <= radius; ry++) { rad2 = rx * rx + ry * ry; if (rad2 > radius2) continue; // outside radius px = Mxposn + rx; py = Myposn + ry; if (px < 0 || px > Fww-1) continue; // off the image edge if (py < 0 || py > Fhh-1) continue; ii = Fww * py + px; rad = sqrt(rad2); power = cpower + rad / radius * (epower - cpower); // power at pixel radius v.11.06 if (Mbutton == 1) // left mouse button { // increase edit power sa_pixmap[ii] += power; if (sa_pixmap[ii] > sa_blend) sa_pixmap[ii] = sa_blend; } if (Mbutton == 3) // right mouse button { // weaken edit power if (sa_pixmap[ii] <= power) sa_pixmap[ii] = 0; else sa_pixmap[ii] -= power; } } sa_minx = Mxposn - radius; // set temp. smaller area around mouse if (sa_minx < 0) sa_minx = 0; // speedup v.11.06 sa_maxx = Mxposn + radius; if (sa_maxx > Fww) sa_maxx = Fww; sa_miny = Myposn - radius; if (sa_miny < 0) sa_miny = 0; sa_maxy = Myposn + radius; if (sa_maxy > Fhh) sa_maxy = Fhh; sa_Npixel = (sa_maxx - sa_minx) * (sa_maxy - sa_miny); paint_toparc(2); // remove mouse outline zdialog_send_event(CEF->zd,"blendwidth"); // notify edit dialog Ftoparc = 1; // restore mouse outline paint_toparc(3); sa_minx = 0; // restore whole image area v.11.06 sa_maxx = Fww; sa_miny = 0; sa_maxy = Fhh; sa_Npixel = Fww * Fhh; return; } fotoxx-12.01.2/f.art.cc0000644000175000017500000020502411701011017013155 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image edit - arty transformation functions ***************************************************************************/ // image color-depth reduction int colordep_depth = 16; // bits per RGB color editfunc EFcolordep; void m_colordep(GtkWidget *, cchar *) { int colordep_dialog_event(zdialog *zd, cchar *event); void * colordep_thread(void *); cchar *colmess = ZTX("Set color depth to 1-16 bits"); zfuncs::F1_help_topic = "color_depth"; // v.10.8 EFcolordep.funcname = "color-depth"; EFcolordep.Fprev = 1; // use preview EFcolordep.Farea = 2; // select area usable EFcolordep.threadfunc = colordep_thread; // thread function if (! edit_setup(EFcolordep)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Set Color Depth"),mWin,Bdone,Bcancel,null); EFcolordep.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",colmess,"space=5"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"spin","colors","hb1","1|16|1|16","space=5"); zdialog_help(zd,"color_depth"); // zdialog help topic v.11.08 zdialog_run(zd,colordep_dialog_event,"-10/20"); // run dialog, parallel v.11.07 colordep_depth = 16; return; } // dialog event and completion callback function int colordep_dialog_event(zdialog *zd, cchar *event) { if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFcolordep); else edit_cancel(EFcolordep); return 0; } if (strEqu(event,"undo")) edit_undo(); // v.10.2 if (strEqu(event,"redo")) edit_redo(); // v.10.3 if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strEqu(event,"colors")) { zdialog_fetch(zd,"colors",colordep_depth); signal_thread(); } return 0; } // image color depth thread function void * colordep_thread(void *) { int ii, px, py, rgb, dist = 0; uint16 m1, m2, val1, val3; uint16 *pix1, *pix3; double fmag, f1, f2; while (true) { thread_idle_loop(); // wait for work or exit request m1 = 0xFFFF << (16 - colordep_depth); // 5 > 1111100000000000 m2 = 0x8000 >> colordep_depth; // 5 > 0000010000000000 fmag = 65535.0 / m1; for (py = 0; py < E3hh; py++) for (px = 0; px < E3ww; px++) { if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // outside pixel } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel for (rgb = 0; rgb < 3; rgb++) { val1 = pix1[rgb]; if (val1 < m1) val3 = (val1 + m2) & m1; else val3 = m1; val3 = uint(val3 * fmag); if (Factivearea && dist < sa_blend) { // select area is active, f2 = 1.0 * dist / sa_blend; // blend changes over sa_blend f1 = 1.0 - f2; val3 = int(f1 * val1 + f2 * val3); } pix3[rgb] = val3; } } CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } /**************************************************************************/ // convert image to simulate a drawing int draw_contrast; int draw_threshold; int draw_pixcon; int draw_reverse; double draw_trfunc[256]; double draw_pixcon3; uint8 *draw_pixcon_map = 0; editfunc EFdraw; void m_draw(GtkWidget *, cchar *) { int draw_dialog_event(zdialog* zd, cchar *event); void * draw_thread(void *); cchar *title = ZTX("Simulate Drawing"); uint16 *pix1, *pix2; int ii, px, py, qx, qy; int red, green, blue, con, maxcon; zfuncs::F1_help_topic = "drawing"; // v.10.8 EFdraw.funcname = "drawing"; EFdraw.Farea = 2; // select area usable EFdraw.threadfunc = draw_thread; // thread function if (! edit_setup(EFdraw)) return; // setup edit draw_pixcon_map = (uint8 *) zmalloc(E1ww*E1hh,"draw"); // set up pixel contrast map memset(draw_pixcon_map,0,E1ww*E1hh); for (py = 1; py < E1hh-1; py++) // scan image pixels for (px = 1; px < E1ww-1; px++) { pix1 = PXMpix(E1pxm16,px,py); // pixel at (px,py) red = pix1[0]; // pixel RGB levels green = pix1[1]; blue = pix1[2]; maxcon = 0; for (qy = py-1; qy < py+2; qy++) // loop 3x3 block of neighbor for (qx = px-1; qx < px+2; qx++) // pixels around pix1 { pix2 = PXMpix(E1pxm16,qx,qy); // find max. contrast with con = abs(red-pix2[0]) + abs(green-pix2[1]) + abs(blue-pix2[2]); // neighbor pixel if (con > maxcon) maxcon = con; } ii = py * E1ww + px; draw_pixcon_map[ii] = (maxcon/3) >> 8; // contrast for (px,py) 0-255 } zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); EFdraw.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"homog"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"homog|expand"); zdialog_add_widget(zd,"label","lab1","vb1",ZTX("contrast")); zdialog_add_widget(zd,"label","lab2","vb1",Bthresh); zdialog_add_widget(zd,"label","lab3","vb1",ZTX("outlines")); zdialog_add_widget(zd,"hscale","contrast","vb2","0|100|1|0","expand"); zdialog_add_widget(zd,"hscale","threshold","vb2","0|100|1|0","expand"); zdialog_add_widget(zd,"hscale","pixcon","vb2","0|255|1|0","expand"); zdialog_add_widget(zd,"hbox","hb4","dialog"); zdialog_add_widget(zd,"radio","pencil","hb4",ZTX("pencil"),"space=10"); zdialog_add_widget(zd,"radio","chalk","hb4",ZTX("chalk"),"space=10"); zdialog_resize(zd,300,0); zdialog_help(zd,"drawing"); // zdialog help topic v.11.08 zdialog_run(zd,draw_dialog_event,"-10/20"); // run dialog, parallel v.11.07 return; } // dialog event and completion callback function int draw_dialog_event(zdialog *zd, cchar *event) // draw dialog event function { if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFdraw); else edit_cancel(EFdraw); zfree(draw_pixcon_map); return 0; } if (strEqu(event,"undo")) edit_undo(); // v.10.2 if (strEqu(event,"redo")) edit_redo(); // v.10.3 if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strcmpv(event,"contrast","threshold","pixcon","chalk",null)) { zdialog_fetch(zd,"contrast",draw_contrast); // get slider values zdialog_fetch(zd,"threshold",draw_threshold); zdialog_fetch(zd,"pixcon",draw_pixcon); zdialog_fetch(zd,"chalk",draw_reverse); signal_thread(); // trigger update thread } return 1; } // thread function - use multiple working threads void * draw_thread(void *) { void * draw_wthread(void *arg); int ii; double threshold, contrast, trf; while (true) { thread_idle_loop(); // wait for work or exit request threshold = 0.01 * draw_threshold; // range 0 to 1 contrast = 0.01 * draw_contrast; // range 0 to 1 for (ii = 0; ii < 256; ii++) // brightness transfer function { trf = 1.0 - 0.003906 * (256 - ii) * contrast; // ramp-up from 0-1 to 1 if (ii < 256 * threshold) trf = 0; // 0 if below threshold draw_trfunc[ii] = trf; } for (ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(draw_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * draw_wthread(void *arg) // worker thread function { void draw_1pix(int px, int py); int index = *((int *) (arg)); int px, py; double pixcon; pixcon = draw_pixcon / 255.0; // 0-1 linear ramp draw_pixcon3 = 255 * pixcon * pixcon * pixcon; // 0-255 cubic ramp for (py = index+1; py < E1hh-1; py += Nwt) // process all pixels for (px = 1; px < E1ww-1; px++) draw_1pix(px,py); exit_wthread(); return 0; // not executed, avoid gcc warning } void draw_1pix(int px, int py) // process one pixel { uint16 *pix1, *pix3; int ii, dist = 0; int bright1, bright2; int red1, green1, blue1; int red3, green3, blue3; double dold, dnew; double pixcon = draw_pixcon3; if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) return; // outside pixel } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel red1 = pix1[0]; green1 = pix1[1]; blue1 = pix1[2]; bright1 = ((red1 + green1 + blue1) / 3) >> 8; // old brightness 0-255 bright2 = bright1 * draw_trfunc[bright1]; // new brightness 0-255 ii = py * E1ww + px; if (draw_pixcon_map[ii] < pixcon) bright2 = 255; if (pixcon > 1 && bright2 > draw_threshold) bright2 = 255; // empirical !!! if (draw_reverse) bright2 = 255 - bright2; // negate if "chalk" red3 = green3 = blue3 = bright2 << 8; // gray scale, new brightness if (Factivearea && dist < sa_blend) { // select area is active, dnew = 1.0 * dist / sa_blend; dold = 1.0 - dnew; red3 = dnew * red3 + dold * red1; green3 = dnew * green3 + dold * green1; blue3 = dnew * blue3 + dold * blue1; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; return; } /**************************************************************************/ // make an image outline drawing from edge pixels // superimpose outlines and image and vary brightness of each double outlines_olth, outlines_olww, outlines_imbr; editfunc EFoutlines; void m_outlines(GtkWidget *, cchar *) { int outlines_dialog_event(zdialog* zd, cchar *event); void * outlines_thread(void *); cchar *title = ZTX("Add Image Outlines"); zfuncs::F1_help_topic = "outlines"; EFoutlines.funcname = "outlines"; EFoutlines.Farea = 2; // select area usable EFoutlines.threadfunc = outlines_thread; // thread function if (! edit_setup(EFoutlines)) return; // setup edit zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); EFoutlines.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab1","hb1",ZTX("outline threshold"),"space=5"); zdialog_add_widget(zd,"hscale","olth","hb1","0|100|1|90","expand|space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab2","hb2",ZTX("outline width"),"space=5"); zdialog_add_widget(zd,"hscale","olww","hb2","0|100|1|50","expand|space=5"); zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab3","hb3",ZTX("image brightness"),"space=5"); zdialog_add_widget(zd,"hscale","imbr","hb3","0|100|1|10","expand|space=5"); outlines_olth = 90; outlines_olww = 50; outlines_imbr = 10; zdialog_resize(zd,300,0); zdialog_help(zd,"outlines"); // zdialog help topic v.11.08 zdialog_run(zd,outlines_dialog_event,"-10/20"); // run dialog, parallel v.11.07 signal_thread(); return; } // dialog event and completion callback function int outlines_dialog_event(zdialog *zd, cchar *event) // dialog event function { if (zd->zstat) { if (zd->zstat == 1) edit_done(EFoutlines); // done else edit_cancel(EFoutlines); // cancel or destroy PXM_free(E8pxm16); PXM_free(E9pxm16); return 0; } if (strEqu(event,"olth")) { zdialog_fetch(zd,"olth",outlines_olth); // get outline threshold 0-100 signal_thread(); } if (strEqu(event,"olww")) { zdialog_fetch(zd,"olww",outlines_olww); // get outline width 0-100 signal_thread(); } if (strEqu(event,"imbr")) { zdialog_fetch(zd,"imbr",outlines_imbr); // get image brightness 0-100 signal_thread(); } if (strEqu(event,"undo")) edit_undo(); if (strEqu(event,"redo")) edit_redo(); if (strEqu(event,"blendwidth")) signal_thread(); return 1; } // thread function to update image void * outlines_thread(void *) { void * outlines_wthread(void *arg); int px, py, ww, hh; double olww, red3, green3, blue3; double red3h, red3v, green3h, green3v, blue3h, blue3v; uint16 *pix8, *pix9; uint16 *pixa, *pixb, *pixc, *pixd, *pixe, *pixf, *pixg, *pixh; while (true) { thread_idle_loop(); // wait for work or exit request olww = 0.01 * outlines_olww; // outline width, 0 - 1.0 olww = 1.0 - olww; // 1.0 - 0 olww = 0.8 * olww + 0.2; // 1.0 - 0.2 ww = Fww * olww + 0.5; // create smaller outline image hh = Fhh * olww + 0.5; if (! E9pxm16 || ww != E9pxm16->ww) // initial or changed outline brightness { PXM_free(E8pxm16); PXM_free(E9pxm16); E8pxm16 = PXM_rescale(E1pxm16,ww,hh); E9pxm16 = PXM_copy(E8pxm16); for (py = 1; py < hh-1; py++) for (px = 1; px < ww-1; px++) { pix8 = PXMpix(E8pxm16,px,py); // input pixel pix9 = PXMpix(E9pxm16,px,py); // output pixel pixa = pix8-3*ww-3; // 8 neighboring pixels are used pixb = pix8-3*ww; // to get edge brightness using pixc = pix8-3*ww+3; // a Sobel filter pixd = pix8-3; pixe = pix8+3; pixf = pix8+3*ww-3; pixg = pix8+3*ww; pixh = pix8+3*ww+3; red3h = -pixa[0] -2 * pixb[0] -pixc[0] + pixf[0] + 2 * pixg[0] + pixh[0]; red3v = -pixa[0] -2 * pixd[0] -pixf[0] + pixc[0] + 2 * pixe[0] + pixh[0]; green3h = -pixa[1] -2 * pixb[1] -pixc[1] + pixf[1] + 2 * pixg[1] + pixh[1]; green3v = -pixa[1] -2 * pixd[1] -pixf[1] + pixc[1] + 2 * pixe[1] + pixh[1]; blue3h = -pixa[2] -2 * pixb[2] -pixc[2] + pixf[2] + 2 * pixg[2] + pixh[2]; blue3v = -pixa[2] -2 * pixd[2] -pixf[2] + pixc[2] + 2 * pixe[2] + pixh[2]; red3 = (abs(red3h) + abs(red3v)) / 2; // average vertical and horizontal brightness green3 = (abs(green3h) + abs(green3v)) / 2; blue3 = (abs(blue3h) + abs(blue3v)) / 2; if (red3 > 65535) red3 = 65535; if (green3 > 65535) green3 = 65535; if (blue3 > 65535) blue3 = 65535; pix9[0] = red3; pix9[1] = green3; pix9[2] = blue3; } } PXM_free(E8pxm16); // scale back to full-size E8pxm16 = PXM_rescale(E9pxm16,Fww,Fhh); for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(outlines_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * outlines_wthread(void *arg) // worker thread function { int index = *((int *) arg); int px, py, ii, dist = 0; double olth, imbr, br8, dold, dnew; double red1, green1, blue1, red3, green3, blue3; uint16 *pix1, *pix8, *pix3; olth = 0.01 * outlines_olth; // outline threshold, 0 - 1.0 olth = 1.0 - olth; // 1.0 - 0 imbr = 0.01 * outlines_imbr; // image brightness, 0 - 1.0 for (py = index+1; py < Fhh-1; py += Nwt) for (px = 1; px < Fww-1; px++) { if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // pixel outside area } pix1 = PXMpix(E1pxm16,px,py); // input image pixel pix8 = PXMpix(E8pxm16,px,py); // input outline pixel pix3 = PXMpix(E3pxm16,px,py); // output image pixel red1 = pix1[0]; // input image pixel green1 = pix1[1]; blue1 = pix1[2]; br8 = pixbright(pix8); // outline brightness br8 = br8 / 65536.0; // scale 0 - 1.0 if (br8 > olth) { // > threshold, use outline pixel red3 = pix8[0]; green3 = pix8[1]; blue3 = pix8[2]; } else { // use image pixel dimmed by user control red3 = red1 * imbr; green3 = green1 * imbr; blue3 = blue1 * imbr; } if (Factivearea && dist < sa_blend) { // select area is active, dnew = 1.0 * dist / sa_blend; // blend changes over sa_blend dold = 1.0 - dnew; red3 = dnew * red3 + dold * red1; green3 = dnew * green3 + dold * green1; blue3 = dnew * blue3 + dold * blue1; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } exit_wthread(); return 0; // not executed, stop gcc warning } /**************************************************************************/ // convert image to simulate an embossing int emboss_radius, emboss_color; double emboss_depth; double emboss_kernel[20][20]; // support radius <= 9 editfunc EFemboss; void m_emboss(GtkWidget *, cchar *) { int emboss_dialog_event(zdialog* zd, cchar *event); void * emboss_thread(void *); cchar *title = ZTX("Simulate Embossing"); zfuncs::F1_help_topic = "embossing"; // v.10.8 EFemboss.funcname = "emboss"; EFemboss.Farea = 2; // select area usable EFemboss.threadfunc = emboss_thread; // thread function if (! edit_setup(EFemboss)) return; // setup edit zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); EFemboss.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"label","lab1","hb1",Bradius,"space=5"); zdialog_add_widget(zd,"spin","radius","hb1","0|9|1|0"); zdialog_add_widget(zd,"label","lab2","hb1",ZTX("depth"),"space=5"); zdialog_add_widget(zd,"spin","depth","hb1","0|99|1|0"); zdialog_add_widget(zd,"check","color","hb1",ZTX("color"),"space=8"); zdialog_help(zd,"embossing"); // zdialog help topic v.11.08 zdialog_run(zd,emboss_dialog_event,"-10/20"); // run dialog, parallel v.11.07 return; } // dialog event and completion callback function int emboss_dialog_event(zdialog *zd, cchar *event) // emboss dialog event function { if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFemboss); else edit_cancel(EFemboss); return 0; } if (strEqu(event,"undo")) edit_undo(); // v.10.2 if (strEqu(event,"redo")) edit_redo(); // v.10.3 if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strcmpv(event,"radius","depth","color",null)) { zdialog_fetch(zd,"radius",emboss_radius); // get user inputs zdialog_fetch(zd,"depth",emboss_depth); zdialog_fetch(zd,"color",emboss_color); signal_thread(); // trigger update thread } return 1; } // thread function - use multiple working threads void * emboss_thread(void *) { void * emboss_wthread(void *arg); int ii, dx, dy, rad; double depth, kern, coeff; while (true) { thread_idle_loop(); // wait for work or exit request rad = emboss_radius; depth = emboss_depth; coeff = 0.1 * depth / (rad * rad + 1); for (dy = -rad; dy <= rad; dy++) // build kernel with radius and depth for (dx = -rad; dx <= rad; dx++) { kern = coeff * (dx + dy); emboss_kernel[dx+rad][dy+rad] = kern; } emboss_kernel[rad][rad] = 1; // kernel center cell = 1 for (ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(emboss_wthread,&wtnx[ii]); wait_wthreads(); // wait for comletion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * emboss_wthread(void *arg) // worker thread function { void emboss_1pix(int px, int py); int index = *((int *) (arg)); int px, py; for (py = index; py < E1hh; py += Nwt) // process all pixels for (px = 0; px < E1ww; px++) emboss_1pix(px,py); exit_wthread(); return 0; // not executed, avoid gcc warning } void emboss_1pix(int px, int py) // process one pixel { int ii, dist = 0; int bright1, bright3; int rgb, dx, dy, rad; uint16 *pix1, *pix3, *pixN; double sumpix, kern, dold, dnew; if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) return; // outside pixel } rad = emboss_radius; if (px < rad || py < rad) return; if (px > E3ww-rad-1 || py > E3hh-rad-1) return; pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel if (emboss_color) { for (rgb = 0; rgb < 3; rgb++) { sumpix = 0; for (dy = -rad; dy <= rad; dy++) // loop surrounding block of pixels for (dx = -rad; dx <= rad; dx++) { pixN = pix1 + (dy * E1ww + dx) * 3; kern = emboss_kernel[dx+rad][dy+rad]; sumpix += kern * pixN[rgb]; bright1 = pix1[rgb]; bright3 = sumpix; if (bright3 < 0) bright3 = 0; if (bright3 > 65535) bright3 = 65535; if (Factivearea && dist < sa_blend) { // select area is active, dnew = 1.0 * dist / sa_blend; // blend changes over sa_blend dold = 1.0 - dnew; bright3 = dnew * bright3 + dold * bright1; } pix3[rgb] = bright3; } } } else // use gray scale { sumpix = 0; for (dy = -rad; dy <= rad; dy++) // loop surrounding block of pixels for (dx = -rad; dx <= rad; dx++) { pixN = pix1 + (dy * E1ww + dx) * 3; kern = emboss_kernel[dx+rad][dy+rad]; sumpix += kern * (pixN[0] + pixN[1] + pixN[2]); } bright1 = 0.3333 * (pix1[0] + pix1[1] + pix1[2]); bright3 = 0.3333 * sumpix; if (bright3 < 0) bright3 = 0; if (bright3 > 65535) bright3 = 65535; if (Factivearea && dist < sa_blend) { // select area is active, dnew = 1.0 * dist / sa_blend; // blend changes over sa_blend dold = 1.0 - dnew; bright3 = dnew * bright3 + dold * bright1; } pix3[0] = pix3[1] = pix3[2] = bright3; } return; } /**************************************************************************/ // convert image to simulate square tiles int tile_size, tile_gap; uint16 *tile_pixmap = 0; editfunc EFtiles; void m_tiles(GtkWidget *, cchar *) { int tiles_dialog_event(zdialog *zd, cchar *event); void * tiles_thread(void *); zfuncs::F1_help_topic = "tiles"; // v.10.8 EFtiles.funcname = "tiles"; EFtiles.Farea = 2; // select area usable EFtiles.threadfunc = tiles_thread; // thread function if (! edit_setup(EFtiles)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Simulate Tiles"),mWin,Bdone,Bcancel,null); EFtiles.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labt","hb1",ZTX("tile size"),"space=5"); zdialog_add_widget(zd,"spin","size","hb1","1|99|1|5","space=5"); zdialog_add_widget(zd,"button","apply","hb1",Bapply,"space=10"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labg","hb2",ZTX("tile gap"),"space=5"); zdialog_add_widget(zd,"spin","gap","hb2","0|9|1|1","space=5"); zdialog_help(zd,"tiles"); // zdialog help topic v.11.08 zdialog_run(zd,tiles_dialog_event,"-10/20"); // run dialog, parallel v.11.07 tile_size = 5; tile_gap = 1; tile_pixmap = (uint16 *) zmalloc(E1ww*E1hh*6,"tiles"); // set up pixel color map memset(tile_pixmap,0,E1ww*E1hh*6); return; } // dialog event and completion callback function int tiles_dialog_event(zdialog * zd, cchar *event) { if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFtiles); else edit_cancel(EFtiles); zfree(tile_pixmap); return 0; } if (strEqu(event,"undo")) edit_undo(); // v.10.2 if (strEqu(event,"redo")) edit_redo(); // v.10.3 if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strNeq(event,"apply")) return 0; zdialog_fetch(zd,"size",tile_size); // get tile size zdialog_fetch(zd,"gap",tile_gap); // get tile gap if (tile_size < 2) { edit_reset(); // restore original image return 0; } signal_thread(); // trigger working thread return 1; } // image tiles thread function void * tiles_thread(void *) { int sg, gg; int sumpix, red, green, blue; int ii, jj, px, py, qx, qy, dist; double dnew, dold; uint16 *pix1, *pix3; while (true) { thread_idle_loop(); // wait for work or exit request sg = tile_size + tile_gap; gg = tile_gap; for (py = 0; py < E1hh; py += sg) // initz. pixel color map for for (px = 0; px < E1ww; px += sg) // given pixel size { sumpix = red = green = blue = 0; for (qy = py + gg; qy < py + sg; qy++) // get mean color for pixel block for (qx = px + gg; qx < px + sg; qx++) { if (qy > E1hh-1 || qx > E1ww-1) continue; pix1 = PXMpix(E1pxm16,qx,qy); red += pix1[0]; green += pix1[1]; blue += pix1[2]; sumpix++; } if (sumpix) { red = (red / sumpix); green = (green / sumpix); blue = (blue / sumpix); } for (qy = py; qy < py + sg; qy++) // set color for pixels in block for (qx = px; qx < px + sg; qx++) { if (qy > E1hh-1 || qx > E1ww-1) continue; jj = (qy * E1ww + qx) * 3; if (qx-px < gg || qy-py < gg) { tile_pixmap[jj] = tile_pixmap[jj+1] = tile_pixmap[jj+2] = 0; continue; } tile_pixmap[jj] = red; tile_pixmap[jj+1] = green; tile_pixmap[jj+2] = blue; } } if (Factivearea) // process selected area { for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { // v.9.6 if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - py * Fww; dist = sa_pixmap[ii]; // distance from edge pix3 = PXMpix(E3pxm16,px,py); jj = (py * E3ww + px) * 3; if (dist >= sa_blend) { // blend changes over sa_blend v.10.2 pix3[0] = tile_pixmap[jj]; pix3[1] = tile_pixmap[jj+1]; // apply block color to member pixels pix3[2] = tile_pixmap[jj+2]; } else { dnew = 1.0 * dist / sa_blend; dold = 1.0 - dnew; pix1 = PXMpix(E1pxm16,px,py); pix3[0] = dnew * tile_pixmap[jj] + dold * pix1[0]; pix3[1] = dnew * tile_pixmap[jj+1] + dold * pix1[1]; pix3[2] = dnew * tile_pixmap[jj+2] + dold * pix1[2]; } } } else // process entire image { for (py = 0; py < E3hh-1; py++) // loop all image pixels for (px = 0; px < E3ww-1; px++) { pix3 = PXMpix(E3pxm16,px,py); // target pixel jj = (py * E3ww + px) * 3; // color map for (px,py) pix3[0] = tile_pixmap[jj]; pix3[1] = tile_pixmap[jj+1]; pix3[2] = tile_pixmap[jj+2]; } } CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } /**************************************************************************/ // convert image to dot grid (like Roy Lichtenstein) int dot_size; // tile size enclosing dots editfunc EFdots; void m_dots(GtkWidget *, cchar *) // v.11.01 { int dots_dialog_event(zdialog *zd, cchar *event); void * dots_thread(void *); zfuncs::F1_help_topic = "dot_matrix"; EFdots.funcname = "dots"; EFdots.Farea = 2; // select area usable EFdots.threadfunc = dots_thread; // thread function if (! edit_setup(EFdots)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Convert Image to Dots"),mWin,Bdone,Bcancel,null); EFdots.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labt","hb1",ZTX("dot size"),"space=5"); zdialog_add_widget(zd,"spin","size","hb1","3|99|1|9","space=5"); zdialog_add_widget(zd,"button","apply","hb1",Bapply,"space=10"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_help(zd,"dot_matrix"); // zdialog help topic v.11.08 zdialog_run(zd,dots_dialog_event,"-10/20"); // run dialog, parallel v.11.07 dot_size = 9; return; } // dialog event and completion callback function int dots_dialog_event(zdialog * zd, cchar *event) { if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFdots); else edit_cancel(EFdots); return 0; } if (strEqu(event,"undo")) edit_undo(); if (strEqu(event,"redo")) edit_redo(); if (strEqu(event,"blendwidth")) signal_thread(); if (strNeq(event,"apply")) return 0; // wait for [apply] zdialog_fetch(zd,"size",dot_size); // get dot size signal_thread(); // trigger working thread return 1; } // image dots thread function void * dots_thread(void *) { int ds, sumpix, red, green, blue; int cc, maxrgb, ii, dist, shift1, shift2; int px, py, px1, px2, py1, py2; int qx, qy, qx1, qx2, qy1, qy2; uint16 *pix1, *pix3; double relmax, radius, radius2a, radius2b, f1, f2; double f64K = 1.0 / 65536.0; double fpi = 1.0 / 3.14159; double dcx, dcy, qcx, qcy, qdist2; while (true) { thread_idle_loop(); // wait for work or exit request mutex_lock(&Fpixmap_lock); ds = dot_size; // dot size and tile size cc = E3ww * E3hh * 6; // clear output image to black memset(E3pxm16->bmp,0,cc); px1 = 0; // limits for tiles px2 = Fww - ds; py1 = 0; py2 = Fhh - ds; if (Factivearea) { // reduce for active area px1 = sa_minx; px2 = sa_maxx; py1 = sa_miny; py2 = sa_maxy; if (px2 > Fww - ds) px2 = Fww - ds; if (py2 > Fhh - ds) py2 = Fhh - ds; } shift1 = 0; for (py = py1; py < py2; py += ds) // loop all tiles in input image { shift1 = 1 - shift1; // offset alternate rows v.11.02 shift2 = 0.5 * shift1 * ds; for (px = px1 + shift2; px < px2; px += ds) { sumpix = red = green = blue = 0; for (qy = py; qy < py + ds; qy++) // loop all pixels in tile for (qx = px; qx < px + ds; qx++) // get mean RGB levels for tile { pix1 = PXMpix(E1pxm16,qx,qy); red += pix1[0]; green += pix1[1]; blue += pix1[2]; sumpix++; } red = (red / sumpix); // mean RGB levels, 0 to 64K green = (green / sumpix); blue = (blue / sumpix); maxrgb = red; // max. mean RGB level, 0 to 64K if (green > maxrgb) maxrgb = green; if (blue > maxrgb) maxrgb = blue; relmax = f64K * maxrgb; // max. RGB as 0 to 0.999 radius = ds * sqrt(fpi * relmax); // radius of dot with maximized color radius = radius * 0.9; // deliberate reduction v.11.05 if (radius < 0.5) continue; red = 65535.0 * red / maxrgb; // dot color, maximized green = 65535.0 * green / maxrgb; blue = 65535.0 * blue / maxrgb; dcx = px + 0.5 * ds; // center of dot / tile dcy = py + 0.5 * ds; qx1 = dcx - radius; // pixels within dot radius of center qx2 = dcx + radius; qy1 = dcy - radius; qy2 = dcy + radius; radius2a = (radius + 0.5) * (radius + 0.5); radius2b = (radius - 0.5) * (radius - 0.5); for (qy = qy1; qy <= qy2; qy++) // loop all pixels within dot radius for (qx = qx1; qx <= qx2; qx++) { qcx = qx + 0.5; // center of pixel qcy = qy + 0.5; qdist2 = (qcx-dcx)*(qcx-dcx) + (qcy-dcy)*(qcy-dcy); // pixel distance**2 from center of dot if (qdist2 > radius2a) f1 = 0.0; // pixel outside dot, no color else if (qdist2 < radius2b) f1 = 1.0; // pixel inside dot, full color else f1 = 1.0 - sqrt(qdist2) + radius - 0.5; // pixel straddles edge, some color pix3 = PXMpix(E3pxm16,qx,qy); pix3[0] = f1 * red; pix3[1] = f1 * green; pix3[2] = f1 * blue; } } } if (Factivearea) // select area active { pix1 = (uint16 *) E1pxm16->bmp; pix3 = (uint16 *) E3pxm16->bmp; for (ii = 0; ii < Fww * Fhh; ii++) // loop all pixels { dist = sa_pixmap[ii]; if (dist == 0) memmove(pix3,pix1,6); // pixel outside area, output pixel = input else if (dist < sa_blend) { f1 = 1.0 * dist / sa_blend; // pixel in blend region f2 = 1.0 - f1; pix3[0] = f1 * pix3[0] + f2 * pix1[0]; // output pixel is mix of input and output pix3[1] = f1 * pix3[1] + f2 * pix1[1]; pix3[2] = f1 * pix3[2] + f2 * pix1[2]; } pix1 += 3; pix3 += 3; } } mutex_unlock(&Fpixmap_lock); CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } /**************************************************************************/ // convert image to simulate a painting // processing a 10 megapixel image needs 140 MB of main memory namespace painting_names { editfunc EFpainting; int color_depth; int group_area; double color_match; int borders; typedef struct { int16 px, py; char direc; } spixstack; int Nstack; spixstack *pixstack; // pixel group search memory int *pixgroup; // maps (px,py) to pixel group no. int *groupcount; // count of pixels in each group int group; char direc; uint16 gcolor[3]; } void m_painting(GtkWidget *, cchar *) { using namespace painting_names; int painting_dialog_event(zdialog *zd, cchar *event); void * painting_thread(void *); zfuncs::F1_help_topic = "painting"; // v.10.8 EFpainting.funcname = "painting"; EFpainting.Farea = 2; // select area usable EFpainting.threadfunc = painting_thread; // thread function if (! edit_setup(EFpainting)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Simulate Painting"),mWin,Bdone,Bcancel,null); EFpainting.zd = zd; zdialog_add_widget(zd,"hbox","hbcd","dialog",0,"space=1"); zdialog_add_widget(zd,"label","lab1","hbcd",ZTX("color depth"),"space=5"); zdialog_add_widget(zd,"spin","colordepth","hbcd","1|5|1|3","space=5"); zdialog_add_widget(zd,"hbox","hbts","dialog",0,"space=1"); zdialog_add_widget(zd,"label","labts","hbts",ZTX("patch area goal"),"space=5"); zdialog_add_widget(zd,"spin","grouparea","hbts","0|9999|10|1000","space=5"); zdialog_add_widget(zd,"hbox","hbcm","dialog",0,"space=1"); zdialog_add_widget(zd,"label","labcm","hbcm",ZTX("req. color match"),"space=5"); zdialog_add_widget(zd,"spin","colormatch","hbcm","0|99|1|50","space=5"); zdialog_add_widget(zd,"hbox","hbbd","dialog",0,"space=1"); zdialog_add_widget(zd,"label","labbd","hbbd",ZTX("borders"),"space=5"); zdialog_add_widget(zd,"check","borders","hbbd",0,"space=2"); zdialog_add_widget(zd,"button","apply","hbbd",Bapply,"space=10"); zdialog_help(zd,"painting"); // zdialog help topic v.11.08 zdialog_run(zd,painting_dialog_event,"-10/20"); // run dialog, parallel v.11.07 return; } // dialog event and completion callback function int painting_dialog_event(zdialog *zd, cchar *event) { using namespace painting_names; if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFpainting); else edit_cancel(EFpainting); return 0; } if (strEqu(event,"undo")) edit_undo(); // v.10.2 if (strEqu(event,"redo")) edit_redo(); // v.10.3 if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strEqu(event,"apply")) { // apply user settings zdialog_fetch(zd,"colordepth",color_depth); // color depth zdialog_fetch(zd,"grouparea",group_area); // target group area (pixels) zdialog_fetch(zd,"colormatch",color_match); // req. color match to combine groups zdialog_fetch(zd,"borders",borders); // borders wanted color_match = 0.01 * color_match; // scale 0 to 1 signal_thread(); // do the work wait_thread_idle(); } return 0; } // painting thread function void * painting_thread(void *) { void painting_colordepth(); void painting_pixgroups(); void painting_mergegroups(); void painting_paintborders(); void painting_blend(); while (true) { thread_idle_loop(); // wait for work or exit request painting_colordepth(); // set new color depth painting_pixgroups(); // group pixel patches of a color painting_mergegroups(); // merge smaller into larger groups painting_paintborders(); // add borders around groups painting_blend(); // blend edges of selected area CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } // set the specified color depth, 1-5 bits/color void painting_colordepth() { using namespace painting_names; int ii, px, py, rgb; double fmag; uint16 m1, m2, val1, val3; uint16 *pix1, *pix3; m1 = 0xFFFF << (16 - color_depth); // 5 > 1111100000000000 m2 = 0x8000 >> color_depth; // 5 > 0000010000000000 fmag = 65535.0 / m1; // full brightness range if (Factivearea) // process select area { for (ii = 0; ii < Fww * Fhh; ii++) { // v.9.6 if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - py * Fww; pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel for (rgb = 0; rgb < 3; rgb++) { val1 = pix1[rgb]; if (val1 < m1) val3 = (val1 + m2) & m1; else val3 = m1; val3 = uint(val3 * fmag); pix3[rgb] = val3; } } } else // process entire image { for (py = 0; py < E3hh; py++) // loop all pixels for (px = 0; px < E3ww; px++) { pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel for (rgb = 0; rgb < 3; rgb++) { val1 = pix1[rgb]; if (val1 < m1) val3 = (val1 + m2) & m1; else val3 = m1; val3 = uint(val3 * fmag); pix3[rgb] = val3; } } } return; } // find all groups of contiguous pixels with the same color void painting_pixgroups() { using namespace painting_names; void painting_pushpix(int px, int py); int cc1, cc2; int ii, kk, px, py; int ppx, ppy, npx, npy; uint16 *pix3; cc1 = E3ww * E3hh; cc2 = cc1 * sizeof(int); pixgroup = (int *) zmalloc(cc2,"painting"); // maps pixel to assigned group memset(pixgroup,0,cc2); if (Factivearea) cc1 = sa_Npixel; cc2 = cc1 * sizeof(spixstack); pixstack = (spixstack *) zmalloc(cc2,"painting"); // memory stack for pixel search memset(pixstack,0,cc2); cc2 = cc1 * sizeof(int); groupcount = (int *) zmalloc(cc2,"painting"); // counts pixels per group memset(groupcount,0,cc2); group = 0; for (py = 0; py < E3hh; py++) // loop all pixels for (px = 0; px < E3ww; px++) { kk = py * E3ww + px; if (Factivearea && ! sa_pixmap[kk]) continue; if (pixgroup[kk]) continue; // already assigned to group pixgroup[kk] = ++group; // assign next group ++groupcount[group]; pix3 = PXMpix(E3pxm16,px,py); gcolor[0] = pix3[0]; gcolor[1] = pix3[1]; gcolor[2] = pix3[2]; pixstack[0].px = px; // put pixel into stack with pixstack[0].py = py; // direction = ahead v.11.04 pixstack[0].direc = 'a'; Nstack = 1; while (Nstack) // overhauled v.11.02 { kk = Nstack - 1; // get last pixel in stack px = pixstack[kk].px; py = pixstack[kk].py; direc = pixstack[kk].direc; if (direc == 'x') { Nstack--; continue; } if (Nstack > 1) { ii = Nstack - 2; // get prior pixel in stack ppx = pixstack[ii].px; ppy = pixstack[ii].py; } else { ppx = px - 1; // if only one, assume prior = left ppy = py; } if (direc == 'a') { // next ahead pixel v.11.04 npx = px + px - ppx; npy = py + py - ppy; pixstack[kk].direc = 'r'; // next search direction } else if (direc == 'r') { // next right pixel v.11.04 npx = px + py - ppy; npy = py + px - ppx; pixstack[kk].direc = 'l'; } else { /* direc = 'l' */ // next left pixel v.11.04 npx = px + ppy - py; npy = py + ppx - px; pixstack[kk].direc = 'x'; } if (npx < 0 || npx > E3ww-1) continue; // pixel off the edge v.11.04 if (npy < 0 || npy > E3hh-1) continue; kk = npy * E3ww + npx; if (Factivearea && ! sa_pixmap[kk]) continue; // pixel outside area if (pixgroup[kk]) continue; // pixel already assigned pix3 = PXMpix(E3pxm16,npx,npy); if (pix3[0] != gcolor[0] || pix3[1] != gcolor[1] // not same color as group || pix3[2] != gcolor[2]) continue; pixgroup[kk] = group; // assign pixel to group ++groupcount[group]; kk = Nstack++; // put pixel into stack pixstack[kk].px = npx; pixstack[kk].py = npy; pixstack[kk].direc = 'a'; // direction = ahead v.11.04 } } return; } // merge small pixel groups into adjacent larger groups with best color match void painting_mergegroups() { using namespace painting_names; int ii, jj, kk, px, py, npx, npy; int nccc, mcount, group2; double ff = 1.0 / 65536.0; double fred, fgreen, fblue, match; int nnpx[4] = { 0, -1, +1, 0 }; int nnpy[4] = { -1, 0, 0, +1 }; uint16 *pix3, *pixN; typedef struct { int group; double match; uint16 pixM[3]; } snewgroup; snewgroup *newgroup; nccc = (group + 1) * sizeof(snewgroup); newgroup = (snewgroup *) zmalloc(nccc,"painting"); if (Factivearea) // process select area { while (true) { memset(newgroup,0,nccc); for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { // v.9.6 if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - py * Fww; kk = E3ww * py + px; // get assigned group group = pixgroup[kk]; if (groupcount[group] >= group_area) continue; // group count large enough pix3 = PXMpix(E3pxm16,px,py); for (jj = 0; jj < 4; jj++) // get 4 neighbor pixels { npx = px + nnpx[jj]; npy = py + nnpy[jj]; if (npx < 0 || npx >= E3ww) continue; // off the edge if (npy < 0 || npy >= E3hh) continue; kk = E3ww * npy + npx; if (! sa_pixmap[kk]) continue; // pixel outside area if (pixgroup[kk] == group) continue; // already in same group pixN = PXMpix(E3pxm16,npx,npy); // match color of group neighbor fred = ff * abs(pix3[0] - pixN[0]); // to color of group fgreen = ff * abs(pix3[1] - pixN[1]); fblue = ff * abs(pix3[2] - pixN[2]); match = (1.0 - fred) * (1.0 - fgreen) * (1.0 - fblue); // color match, 0 to 1.0 if (match < color_match) continue; if (match > newgroup[group].match) { newgroup[group].match = match; // remember best match newgroup[group].group = pixgroup[kk]; // and corresp. group no. newgroup[group].pixM[0] = pixN[0]; // and corresp. new color newgroup[group].pixM[1] = pixN[1]; newgroup[group].pixM[2] = pixN[2]; } } } mcount = 0; for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { // v.9.6 if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - py * Fww; kk = E3ww * py + px; group = pixgroup[kk]; // test for new group assignment group2 = newgroup[group].group; if (! group2) continue; if (groupcount[group] > groupcount[group2]) continue; // accept only bigger new group pixgroup[kk] = group2; // make new group assignment --groupcount[group]; ++groupcount[group2]; pix3 = PXMpix(E3pxm16,px,py); // make new color assignment pix3[0] = newgroup[group].pixM[0]; pix3[1] = newgroup[group].pixM[1]; pix3[2] = newgroup[group].pixM[2]; mcount++; } if (mcount == 0) break; } } else // process entire image { while (true) { memset(newgroup,0,nccc); for (py = 0; py < E3hh; py++) // loop all pixels for (px = 0; px < E3ww; px++) { kk = E3ww * py + px; // get assigned group group = pixgroup[kk]; if (groupcount[group] >= group_area) continue; // group count large enough pix3 = PXMpix(E3pxm16,px,py); for (jj = 0; jj < 4; jj++) // get 4 neighbor pixels { npx = px + nnpx[jj]; npy = py + nnpy[jj]; if (npx < 0 || npx >= E3ww) continue; // off the edge if (npy < 0 || npy >= E3hh) continue; kk = E3ww * npy + npx; if (pixgroup[kk] == group) continue; // in same group pixN = PXMpix(E3pxm16,npx,npy); // match color of group neighbor fred = ff * abs(pix3[0] - pixN[0]); // to color of group fgreen = ff * abs(pix3[1] - pixN[1]); fblue = ff * abs(pix3[2] - pixN[2]); match = (1.0 - fred) * (1.0 - fgreen) * (1.0 - fblue); // color match, 0 to 1.0 if (match < color_match) continue; if (match > newgroup[group].match) { newgroup[group].match = match; // remember best match newgroup[group].group = pixgroup[kk]; // and corresp. group no. newgroup[group].pixM[0] = pixN[0]; // and corresp. new color newgroup[group].pixM[1] = pixN[1]; newgroup[group].pixM[2] = pixN[2]; } } } mcount = 0; for (py = 0; py < E3hh; py++) // loop all pixels for (px = 0; px < E3ww; px++) { kk = E3ww * py + px; group = pixgroup[kk]; // test for new group assignment group2 = newgroup[group].group; if (! group2) continue; if (groupcount[group] > groupcount[group2]) continue; // accept only bigger new group pixgroup[kk] = group2; // make new group assignment --groupcount[group]; ++groupcount[group2]; pix3 = PXMpix(E3pxm16,px,py); // make new color assignment pix3[0] = newgroup[group].pixM[0]; pix3[1] = newgroup[group].pixM[1]; pix3[2] = newgroup[group].pixM[2]; mcount++; } if (mcount == 0) break; } } zfree(pixgroup); zfree(pixstack); zfree(groupcount); zfree(newgroup); return; } // paint borders between the groups of contiguous pixels void painting_paintborders() { using namespace painting_names; int ii, kk, px, py, cc; uint16 *pix3, *pixL, *pixA; if (! borders) return; cc = E3ww * E3hh; char * pixblack = zmalloc(cc,"painting"); memset(pixblack,0,cc); if (Factivearea) { for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { // v.9.6 if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - py * Fww; if (px < 1 || py < 1) continue; pix3 = PXMpix(E3pxm16,px,py); pixL = PXMpix(E3pxm16,px-1,py); pixA = PXMpix(E3pxm16,px,py-1); if (pix3[0] != pixL[0] || pix3[1] != pixL[1] || pix3[2] != pixL[2]) { kk = ii - 1; if (pixblack[kk]) continue; kk += 1; pixblack[kk] = 1; continue; } if (pix3[0] != pixA[0] || pix3[1] != pixA[1] || pix3[2] != pixA[2]) { kk = ii - E3ww; if (pixblack[kk]) continue; kk += E3ww; pixblack[kk] = 1; } } for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { // v.9.6 if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - py * Fww; if (px < 1 || py < 1) continue; if (! pixblack[ii]) continue; pix3 = PXMpix(E3pxm16,px,py); pix3[0] = pix3[1] = pix3[2] = 0; } } else { for (py = 1; py < E3hh; py++) // loop all pixels for (px = 1; px < E3ww; px++) // omit top and left { pix3 = PXMpix(E3pxm16,px,py); // output pixel pixL = PXMpix(E3pxm16,px-1,py); // pixel to left pixA = PXMpix(E3pxm16,px,py-1); // pixel above if (pix3[0] != pixL[0] || pix3[1] != pixL[1] || pix3[2] != pixL[2]) { kk = E3ww * py + px-1; // have horiz. transition if (pixblack[kk]) continue; kk += 1; pixblack[kk] = 1; continue; } if (pix3[0] != pixA[0] || pix3[1] != pixA[1] || pix3[2] != pixA[2]) { kk = E3ww * (py-1) + px; // have vertical transition if (pixblack[kk]) continue; kk += E3ww; pixblack[kk] = 1; } } for (py = 1; py < E3hh; py++) for (px = 1; px < E3ww; px++) { kk = E3ww * py + px; if (! pixblack[kk]) continue; pix3 = PXMpix(E3pxm16,px,py); pix3[0] = pix3[1] = pix3[2] = 0; } } zfree(pixblack); return; } // blend edges of selected area void painting_blend() { int ii, px, py, dist; uint16 *pix1, *pix3; double f1, f2; if (Factivearea && sa_blend > 0) { for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { // v.9.6 dist = sa_pixmap[ii]; if (! dist || dist >= sa_blend) continue; py = ii / Fww; px = ii - py * Fww; pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel f2 = 1.0 * dist / sa_blend; // changes over distance sa_blend f1 = 1.0 - f2; pix3[0] = int(f1 * pix1[0] + f2 * pix3[0]); pix3[1] = int(f1 * pix1[1] + f2 * pix3[1]); pix3[2] = int(f1 * pix1[2] + f2 * pix3[2]); } } return; } fotoxx-12.01.2/f.retouch.cc0000644000175000017500000102577111701011017014052 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image edit - retouch functions ***************************************************************************/ // brightness / color / contrast adjustment void tune_curve_update(int spc); // curve update callback function void tune_update_image(); // process all pixels void tune_update_pixel(int px, int py); // process one pixel void *tune_thread(void *); // thread process for all pixels int tune_spc; // current spline curve 1-5 int tune_spc_moved[6]; // tracks which curves changed double tune_pow[10000]; // pow(2,x) for x = -5.0 to +5.0 int tune_ftf = 1; editfunc EFtune; void m_tune(GtkWidget *, cchar *) // menu function { int tune_dialog_event(zdialog *zd, cchar *event); cchar *title = ZTX("Adjust Brightness and Color"); zfuncs::F1_help_topic = "tune"; // v.10.8 EFtune.funcname = "bright-color"; EFtune.Fprev = 1; // use preview EFtune.Farea = 2; // select area usable EFtune.Fpara = 1; // parallel edit OK EFtune.threadfunc = tune_thread; if (! edit_setup(EFtune)) return; // setup edit if (tune_ftf) { tune_ftf = 0; // pre-compute pow(2,x) for (int ii = 0; ii < 10000; ii++) // for x = -5.0 to +4.999 tune_pow[ii] = pow(2,(ii/1000.0 - 5.0)); } /*** Adjust Brightness and Color ____________________________________________ | | | | | curve drawing area | | | | | |____________________________________________| darker areas lighter areas [+++] [---] [+ -] [- +] [+-+] [-+-] [x] small-steps Curve File: [ Open ] [ Save ] (o) brightness [reset 1] [reset all] (o) color saturation [histogram] (o) red (o) green (o) blue [done] [cancel] ***/ zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); EFtune.zd = zd; zdialog_add_widget(zd,"frame","fr1","dialog",0,"expand"); zdialog_add_widget(zd,"hbox","hba","dialog"); zdialog_add_widget(zd,"label","labda","hba",Bdarker,"space=5"); zdialog_add_widget(zd,"label","space","hba",0,"expand"); zdialog_add_widget(zd,"label","labba","hba",Blighter,"space=5"); zdialog_add_widget(zd,"hbox","hbb","dialog",0,"space=5"); zdialog_add_widget(zd,"button","b +++","hbb","+++"); zdialog_add_widget(zd,"button","b ---","hbb","‒ ‒ ‒"); zdialog_add_widget(zd,"button","b +-", "hbb"," + ‒ "); zdialog_add_widget(zd,"button","b -+", "hbb"," ‒ + "); zdialog_add_widget(zd,"button","b +-+","hbb","+ ‒ +"); zdialog_add_widget(zd,"button","b -+-","hbb","‒ + ‒"); zdialog_add_widget(zd,"hbox","hbcf","dialog",0,"space=5"); zdialog_add_widget(zd,"check","smallstep","hbcf",ZTX("small-steps")); zdialog_add_widget(zd,"label","labcf","hbcf",Bcurvefile,"space=5"); zdialog_add_widget(zd,"button","load","hbcf",Bopen); zdialog_add_widget(zd,"button","save","hbcf",Bsave,"space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog"); zdialog_add_widget(zd,"vbox","vb21","hb2"); zdialog_add_widget(zd,"vbox","vb22","hb2"); zdialog_add_widget(zd,"radio","radbri","vb21",Bbrightness); zdialog_add_widget(zd,"radio","radsat","vb21",ZTX("color saturation")); zdialog_add_widget(zd,"radio","radR","vb21",Bred); zdialog_add_widget(zd,"radio","radG","vb21",Bgreen); zdialog_add_widget(zd,"radio","radB","vb21",Bblue); zdialog_add_widget(zd,"hbox","hbrs","vb22",0,"space=5"); zdialog_add_widget(zd,"label","space","hbrs",0,"space=10"); zdialog_add_widget(zd,"button","reset1","hbrs",ZTX(" reset 1 ")); zdialog_add_widget(zd,"button","resetA","hbrs",ZTX("reset all")); zdialog_add_widget(zd,"hbox","hbhist","vb22",0,"space=6"); zdialog_add_widget(zd,"label","space","hbhist",0,"space=10"); zdialog_add_widget(zd,"button","histo","hbhist",Bhistogram); GtkWidget *frame = zdialog_widget(zd,"fr1"); // setup for curve editing spldat *sd = splcurve_init(frame,tune_curve_update); // v.11.01 EFtune.curves = sd; sd->Nscale = 3; // y-scale lines at 1.0 EV intervals sd->xscale[0][0] = 0.00; // x and y values v.11.10 sd->yscale[0][0] = 0.25; sd->xscale[1][0] = 1.00; sd->yscale[1][0] = 0.25; sd->xscale[0][1] = 0.00; sd->yscale[0][1] = 0.50; sd->xscale[1][1] = 1.00; sd->yscale[1][1] = 0.50; sd->xscale[0][2] = 0.00; sd->yscale[0][2] = 0.75; sd->xscale[1][2] = 1.00; sd->yscale[1][2] = 0.75; for (int spc = 0; spc < 6; spc++) // setup 6 spline curves { // no. 0 is active curve sd->vert[spc] = 0; // all curves are horizontal sd->nap[spc] = 3; // curves 1-6 are copied to 0 when active sd->apx[spc][0] = 0.01; sd->apy[spc][0] = 0.5; sd->apx[spc][1] = 0.5; sd->apy[spc][1] = 0.5; sd->apx[spc][2] = 0.99; sd->apy[spc][2] = 0.5; splcurve_generate(sd,spc); tune_spc_moved[spc] = 0; } sd->Nspc = 1; // only one at a time is active tune_spc = 1; // default curve = brightness zdialog_stuff(zd,"radbri",1); // stuff default selection zdialog_resize(zd,0,500); zdialog_help(zd,"tune"); // zdialog help topic v.11.08 zdialog_run(zd,tune_dialog_event,"save"); // run dialog - parallel v.11.07 return; } // dialog event and completion callback function int tune_dialog_event(zdialog *zd, cchar *event) { int Fupdate = 0; int ii, jj, nn; static int smallstep = 0; double step, step2, step4; double px, py; spldat *sd = EFtune.curves; spldat sdtemp; if (zd->zstat) { if (zd->zstat == 1) edit_done(EFtune); // done else edit_cancel(EFtune); // cancel or destroy return 0; } edit_takeover(EFtune); // set my edit function if (strEqu(event,"reset")) // reset dialog controls v.11.08 event = "resetA"; if (strEqu(event,"blendwidth")) tune_update_image(); // v.10.3 if (strEqu(event,"histo")) m_histogram(0,0); // popup brightness histogram if (strnEqu(event,"rad",3)) { // new choice of curve ii = strcmpv(event,"radbri","radsat","radR","radG","radB",null); tune_spc = ii; sd->nap[0] = sd->nap[ii]; // copy active curve to curve 0 for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[0][jj] = sd->apx[ii][jj]; sd->apy[0][jj] = sd->apy[ii][jj]; } Fupdate++; } if (strEqu(event,"smallstep")) // toggle [+++] etc. step size zdialog_fetch(zd,"smallstep",smallstep); ii = tune_spc; // current active curve if (strnEqu(event,"b ",2)) { // button [+++] etc. - move entire curve for (jj = 0; jj < sd->nap[ii]; jj++) { px = sd->apx[0][jj]; py = sd->apy[0][jj]; step = 0.025; // 1/40 if (smallstep) step = step * 0.3333; step2 = 2 * step; step4 = 4 * step; if (strEqu(event,"b +++")) py += step; // range is 40 steps v.11.07 if (strEqu(event,"b ---")) py -= step; // = -2.0 to +2.0 EV if (strEqu(event,"b +-")) py += step - step2 * px; // normal steps are 0.1 EV or 0.03 OD if (strEqu(event,"b -+")) py -= step - step2 * px; // small steps are 1/3 as big if (strEqu(event,"b +-+")) py -= step - step4 * fabs(px-0.5); if (strEqu(event,"b -+-")) py += step - step4 * fabs(px-0.5); if (py > 1) py = 1; if (py < 0) py = 0; sd->apy[0][jj] = py; } tune_spc_moved[ii] = 1; Fupdate++; } if (strEqu(event,"reset1")) { // reset current curve sd->nap[0] = 3; sd->apx[0][0] = 0.01; // 3 anchor points, flatline sd->apy[0][0] = 0.5; sd->apx[0][1] = 0.5; sd->apy[0][1] = 0.5; sd->apx[0][2] = 0.99; sd->apy[0][2] = 0.5; Fupdate++; tune_spc_moved[ii] = 0; } if (strEqu(event,"resetA")) { for (jj = 0; jj < 6; jj++) { // reset all curves sd->nap[jj] = 3; sd->apx[jj][0] = 0.01; sd->apy[jj][0] = 0.5; sd->apx[jj][1] = 0.5; sd->apy[jj][1] = 0.5; sd->apx[jj][2] = 0.99; sd->apy[jj][2] = 0.5; splcurve_generate(sd,jj); // regenerate all tune_spc_moved[jj] = 0; } Fupdate++; } if (strEqu(event,"load")) // load 5 saved curves v.11.02 { sdtemp.Nspc = 5; sdtemp.drawarea = 0; nn = splcurve_load(&sdtemp); if (nn != 1) return 0; for (ii = 0; ii < 5; ii++) { for (jj = 0; jj < sdtemp.nap[ii]; jj++) { sd->apx[ii+1][jj] = sdtemp.apx[ii][jj]; sd->apy[ii+1][jj] = sdtemp.apy[ii][jj]; } splcurve_generate(sd,ii+1); tune_spc_moved[ii+1] = 1; } ii = tune_spc; sd->nap[0] = sd->nap[ii]; // copy active curve to curve 0 for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[0][jj] = sd->apx[ii][jj]; sd->apy[0][jj] = sd->apy[ii][jj]; } Fupdate++; } if (strEqu(event,"save")) // save 5 curves to file v.11.02 { sdtemp.Nspc = 5; for (ii = 0; ii < 5; ii++) { sdtemp.nap[ii] = sd->nap[ii+1]; for (jj = 0; jj < sd->nap[ii+1]; jj++) { sdtemp.apx[ii][jj] = sd->apx[ii+1][jj]; sdtemp.apy[ii][jj] = sd->apy[ii+1][jj]; } } splcurve_save(&sdtemp); } if (Fupdate) // curve has changed { splcurve_generate(sd,0); // regenerate curve 0 ii = tune_spc; // active curve sd->nap[ii] = sd->nap[0]; // copy curve 0 to active curve for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[ii][jj] = sd->apx[0][jj]; sd->apy[ii][jj] = sd->apy[0][jj]; } for (jj = 0; jj < 1000; jj++) sd->yval[ii][jj] = sd->yval[0][jj]; splcurve_draw(0,0,sd); // draw curve tune_update_image(); // trigger image update } return 1; } // this function is called when curve 0 is edited using mouse void tune_curve_update(int) { int ii = tune_spc, jj; spldat *sd = EFtune.curves; edit_takeover(EFtune); // set my edit function sd->nap[ii] = sd->nap[0]; // copy curve 0 to current curve for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[ii][jj] = sd->apx[0][jj]; sd->apy[ii][jj] = sd->apy[0][jj]; } for (jj = 0; jj < 1000; jj++) sd->yval[ii][jj] = sd->yval[0][jj]; tune_spc_moved[ii] = 1; tune_update_image(); // update image return; } // Update image based on latest settings of all dialog controls. void tune_update_image() // v.11.06 { int px, py, ww, hh; if (Factivearea && sa_Npixel < 200000) // if relatively small area, { // process in main() thread v.11.06 for (py = sa_miny; py < sa_maxy; py++) for (px = sa_minx; px < sa_maxx; px++) tune_update_pixel(px,py); px = sa_minx; // direct window update py = sa_miny; ww = sa_maxx - sa_minx; hh = sa_maxy - sa_miny; mwpaint3(px,py,ww,hh); // speedup v.11.06 CEF->Fmod = 1; } else signal_thread(); // else use thread process return; } // Update image based on latest settings of all dialog controls. void * tune_thread(void *) { void * tune_wthread(void *arg); while (true) { thread_idle_loop(); // wait for work or exit request for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(tune_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * tune_wthread(void *arg) // worker thread function { int px, py; int index = *((int *) arg); for (py = index; py < E1hh; py += Nwt) for (px = 0; px < E1ww; px++) tune_update_pixel(px,py); exit_wthread(); return 0; // not executed, avoid gcc warning } void tune_update_pixel(int px, int py) // process one pixel { int ii, kk, dist = 0; uint16 *pix1, *pix3; double red1, green1, blue1, red3, green3, blue3; double xval, brmax, brmean, brout, brightness; spldat *sd = EFtune.curves; if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) return; // pixel outside area } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel red1 = red3 = pix1[0]; // input and output RGB values green1 = green3 = pix1[1]; blue1 = blue3 = pix1[2]; brightness = 0.25 * red3 + 0.65 * green3 + 0.10 * blue3; // perceived brightness v.10.9 xval = brightness / 65536.0; // curve x-value, 0 to 0.999 /* ------------------------------------------------------------------------ brightness adjustment brightness curve values: 0 = dark 0.5 = normal, unchanged 1.0 = 200% brightness, clipped */ if (tune_spc_moved[1]) // curve has been edited { kk = 1000 * xval; // x-value speedup v.11.06 if (kk > 999) kk = 999; brout = sd->yval[1][kk]; // y-value, 0 to 1.0 brout = 4 * brout - 2; // F-stops, -2 to +2 v.11.07 brout = tune_pow[int(1000*brout+5000.5)]; // 0.25 to 4.0 brmax = red3; // brmax = brightest color if (green3 > brmax) brmax = green3; if (blue3 > brmax) brmax = blue3; red3 = red3 * brout; // apply to all colors green3 = green3 * brout; // remove limit check v.10.9 blue3 = blue3 * brout; // (result is better) } /* ------------------------------------------------------------------------ color saturation curve values: 0 = no color saturation (gray scale) 0.5 = normal (initial unmodified RGB) 1.0 = max. color saturation 0.5 >> 0: move all RGB values to their mean: (R+G+B)/3 0.5 >> 1.0: increase RGB spread to 2x original level */ if (tune_spc_moved[2]) // curve has been edited { kk = 1000 * xval; // speedup v.11.06 if (kk > 999) kk = 999; brout = sd->yval[2][kk]; // saturation factor, 0 - 1 brout = 2.0 * brout - 1.0; // -1.0 .. +1.0 brmean = 0.333 * (red3 + green3 + blue3); red3 = red3 + brout * (red3 - brmean); // simplified v.10.9 green3 = green3 + brout * (green3 - brmean); blue3 = blue3 + brout * (blue3 - brmean); if (red3 < 0) red3 = 0; if (green3 < 0) green3 = 0; if (blue3 < 0) blue3 = 0; } /* ------------------------------------------------------------------------ color balance curve values: 0 = 0.5 * original color 0.5 = unmodified 1.0 = 1.5 * original color, clipped */ if (tune_spc_moved[3]) { // curve has been edited kk = 1000 * xval; // speedup v.11.06 if (kk > 999) kk = 999; brout = sd->yval[3][kk]; // 0 to 1.0 brout = 4 * brout - 2; // F-stops, -2 to +2 v.11.07 brout = tune_pow[int(1000*brout+5000.5)]; // 0.25 to 4.0 red3 = red3 * brout; } if (tune_spc_moved[4]) { kk = 1000 * xval; if (kk > 999) kk = 999; brout = sd->yval[4][kk]; brout = 4 * brout - 2; brout = tune_pow[int(1000*brout+5000.5)]; green3 = green3 * brout; } if (tune_spc_moved[5]) { kk = 1000 * xval; if (kk > 999) kk = 999; brout = sd->yval[5][kk]; brout = 4 * brout - 2; brout = tune_pow[int(1000*brout+5000.5)]; blue3 = blue3 * brout; } // if working within a select area, blend changes over distance from edge double dold, dnew; if (Factivearea && dist < sa_blend) { dnew = 1.0 * dist / sa_blend; dold = 1.0 - dnew; red3 = dnew * red3 + dold * red1; green3 = dnew * green3 + dold * green1; blue3 = dnew * blue3 + dold * blue1; } // prevent overflow and set output RGB values double cmax; cmax = red3; // detect overflow v.11.07 if (green3 > cmax) cmax = green3; if (blue3 > cmax) cmax = blue3; if (cmax > 65535) { // stop overflow red3 = red3 * 65535 / cmax; green3 = green3 * 65535 / cmax; blue3 = blue3 * 65535 / cmax; } pix3[0] = int(red3); pix3[1] = int(green3); pix3[2] = int(blue3); return; } /**************************************************************************/ // adjust image gamma using classic gamma curve editfunc EFgamma; int gamma_spc; // current spline curve void m_gamma(GtkWidget *, cchar *) // new v.11.10 { int gamma_dialog_event(zdialog* zd, cchar *event); void gamma_curvedit(int spc); void * gamma_thread(void *); zfuncs::F1_help_topic = "gamma_curve"; EFgamma.funcname = "gamma"; EFgamma.Fprev = 1; // use preview EFgamma.Farea = 2; // select area usable EFgamma.Fpara = 1; // parallel edit OK EFgamma.threadfunc = gamma_thread; if (! edit_setup(EFgamma)) return; // setup edit /*** _________________________________________ | | // 5 curves are maintained: | | // curve 0: current display curve | | // 1: curve for all colors | | // 2,3,4: red, green, blue | curve edit area | | | | | | | |_________________________________________| (o) all (o) red (o) green (o) blue // colors: all, red, green, blue Curve File: [Open] [Save] [histogram] [Done] [Cancel] ***/ zdialog *zd = zdialog_new(ZTX("adjust image gamma"),mWin,Bdone,Bcancel,null); EFgamma.zd = zd; zdialog_add_widget(zd,"frame","frame","dialog",0,"expand"); zdialog_add_widget(zd,"hbox","hbrgb","dialog",0,"space=3"); zdialog_add_widget(zd,"radio","all","hbrgb",Ball,"space=5"); zdialog_add_widget(zd,"radio","red","hbrgb",Bred,"space=5"); zdialog_add_widget(zd,"radio","green","hbrgb",Bgreen,"space=5"); zdialog_add_widget(zd,"radio","blue","hbrgb",Bblue,"space=5"); zdialog_add_widget(zd,"hbox","hbcf","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labcf","hbcf",Bcurvefile,"space=5"); zdialog_add_widget(zd,"button","load","hbcf",Bopen); zdialog_add_widget(zd,"button","save","hbcf",Bsave,"space=3"); zdialog_add_widget(zd,"button","hist","hbcf",Bhistogram,"space=15"); GtkWidget *frame = zdialog_widget(zd,"frame"); spldat *sd = splcurve_init(frame,gamma_curvedit); EFgamma.curves = sd; sd->Nscale = 1; // diagonal fixed line for neutral curve sd->xscale[0][0] = 0.00; sd->yscale[0][0] = 0.00; sd->xscale[1][0] = 1.00; sd->yscale[1][0] = 1.00; for (int ii = 0; ii < 5; ii++) // loop curves 0-4 { sd->nap[ii] = 3; // initial curves are flat sd->vert[ii] = 0; sd->apx[ii][0] = sd->apy[ii][0] = 0.01; sd->apx[ii][1] = sd->apy[ii][1] = 0.50; sd->apx[ii][2] = sd->apy[ii][2] = 0.99; splcurve_generate(sd,ii); } sd->Nspc = 1; // only curve 0 is shown gamma_spc = 1; // current active curve: 1 (all) zdialog_stuff(zd,"all",1); // stuff default selection, all zdialog_resize(zd,260,300); zdialog_help(zd,"gamma_curve"); // zdialog help topic zdialog_run(zd,gamma_dialog_event,"save"); // run dialog - parallel return; } // dialog event and completion callback function int gamma_dialog_event(zdialog *zd, cchar *event) { spldat *sd = EFgamma.curves; int ii, jj, nn, Fupdate = 0; spldat sdtemp; if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFgamma); else edit_cancel(EFgamma); return 1; } edit_takeover(EFgamma); // set my edit function if (strEqu(event,"blendwidth")) signal_thread(); // adjust area edge blending if (strEqu(event,"hist")) m_histogram(0,0); // show brightness distribution if (strstr("all red green blue",event)) { // new choice of curve zdialog_fetch(zd,event,ii); if (! ii) return 0; // ignore button OFF events ii = strcmpv(event,"all","red","green","blue",null); gamma_spc = ii; // 1, 2, 3, 4 sd->nap[0] = sd->nap[ii]; // copy active curve ii to curve 0 for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[0][jj] = sd->apx[ii][jj]; sd->apy[0][jj] = sd->apy[ii][jj]; } Fupdate++; } if (strEqu(event,"load")) // load 4 saved curves from file { sdtemp.Nspc = 4; sdtemp.drawarea = 0; nn = splcurve_load(&sdtemp); if (nn != 1) return 0; for (ii = 0; ii < 4; ii++) { // load curves 0-3 to curves 1-4 sd->vert[ii+1] = sdtemp.vert[ii]; sd->nap[ii+1] = sdtemp.nap[ii]; for (jj = 0; jj < sdtemp.nap[ii]; jj++) { sd->apx[ii+1][jj] = sdtemp.apx[ii][jj]; sd->apy[ii+1][jj] = sdtemp.apy[ii][jj]; } splcurve_generate(sd,ii+1); } ii = gamma_spc; // current active curve, 1-4 sd->nap[0] = sd->nap[ii]; // copy active curve to curve 0 for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[0][jj] = sd->apx[ii][jj]; sd->apy[0][jj] = sd->apy[ii][jj]; } Fupdate++; } if (strEqu(event,"save")) // save 4 curves to a file { sdtemp.Nspc = 4; for (ii = 0; ii < 4; ii++) { sdtemp.vert[ii] = sd->vert[ii+1]; sdtemp.nap[ii] = sd->nap[ii+1]; for (jj = 0; jj < sd->nap[ii+1]; jj++) { sdtemp.apx[ii][jj] = sd->apx[ii+1][jj]; sdtemp.apy[ii][jj] = sd->apy[ii+1][jj]; } } splcurve_save(&sdtemp); } if (Fupdate) // curve has changed { splcurve_generate(sd,0); // regenerate curve 0 ii = gamma_spc; // active curve 1-4 sd->nap[ii] = sd->nap[0]; // copy curve 0 to active curve for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[ii][jj] = sd->apx[0][jj]; sd->apy[ii][jj] = sd->apy[0][jj]; } for (jj = 0; jj < 1000; jj++) sd->yval[ii][jj] = sd->yval[0][jj]; splcurve_draw(0,0,sd); // draw curve signal_thread(); // trigger image update } return 1; } // this function is called when a curve is edited void gamma_curvedit(int spc) { int ii = gamma_spc, jj; spldat *sd = EFgamma.curves; // active curve, 1-4 edit_takeover(EFgamma); // set my edit function sd->nap[ii] = sd->nap[0]; // copy curve 0 to active curve for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[ii][jj] = sd->apx[0][jj]; sd->apy[ii][jj] = sd->apy[0][jj]; } for (jj = 0; jj < 1000; jj++) sd->yval[ii][jj] = sd->yval[0][jj]; if (gamma_spc == 1) { // "all" curve (1) was edited for (ii = 2; ii < 5; ii++) { // fix R/G/B curves (2-4) to match sd->nap[ii] = sd->nap[1]; for (jj = 0; jj < sd->nap[1]; jj++) { sd->apx[ii][jj] = sd->apx[1][jj]; sd->apy[ii][jj] = sd->apy[1][jj]; } for (jj = 0; jj < 1000; jj++) sd->yval[ii][jj] = sd->yval[1][jj]; } } signal_thread(); return; } // gamma thread function void * gamma_thread(void *arg) { void * gamma_wthread(void *); while (true) { thread_idle_loop(); // wait for work or exit request for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(gamma_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion mwpaint2(); // update window CEF->Fmod = 1; // image3 modified } return 0; // not executed, stop g++ warning } void * gamma_wthread(void *arg) // worker thread function { int index = *((int *) arg); int ii, dist = 0, px3, py3; uint16 *pix1, *pix3; double red1, green1, blue1, maxrgb; double red3, green3, blue3; double coeff = 1000.0 / 65536.0; double dold, dnew; spldat *sd = EFgamma.curves; for (py3 = index; py3 < E3hh; py3 += Nwt) // loop output pixels for (px3 = 0; px3 < E3ww; px3++) { if (Factivearea) { // select area active ii = py3 * E3ww + px3; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // pixel outside area } pix1 = PXMpix(E1pxm16,px3,py3); // input pixel pix3 = PXMpix(E3pxm16,px3,py3); // output pixel red1 = pix1[0]; // input RGB brightness, 0-65535 green1 = pix1[1]; blue1 = pix1[2]; ii = coeff * red1; // range 0-999 for gamma curve index red3 = 65535.0 * sd->yval[2][ii]; // output RGB brightness, 0-65535 ii = coeff * green1; green3 = 65535.0 * sd->yval[3][ii]; ii = coeff * blue1; blue3 = 65535.0 * sd->yval[4][ii]; maxrgb = red3; if (green3 > maxrgb) maxrgb = green3; if (blue3 > maxrgb) maxrgb = blue3; if (maxrgb > 65535) { // stop overflow red3 = red3 * 65535 / maxrgb; green3 = green3 * 65535 / maxrgb; blue3 = blue3 * 65535 / maxrgb; } if (Factivearea && dist < sa_blend) { // blend changes over blendwidth dnew = 1.0 * dist / sa_blend; dold = 1.0 - dnew; red3 = dnew * red3 + dold * red1; green3 = dnew * green3 + dold * green1; blue3 = dnew * blue3 + dold * blue1; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } exit_wthread(); return 0; // not executed, avoid gcc warning } /**************************************************************************/ // Clip pixels outside the given low/high range and expand the remaining // brightness range back to the full range of 0 to 65535. double xbrangeD, xbrangeB; editfunc EFxbrange; void m_xbrange(GtkWidget *, cchar *) // new v.10.1 { int xbrange_dialog_event(zdialog *zd, cchar *event); void * xbrange_thread(void *); cchar *title = ZTX("Expand Brightness Range"); cchar *labD = ZTX("dark pixels"); cchar *labB = ZTX("bright pixels"); zfuncs::F1_help_topic = "expand_brightness"; // v.10.8 EFxbrange.funcname = "bright-range"; EFxbrange.Fprev = 1; // use preview EFxbrange.Farea = 2; // select area usable EFxbrange.Fpara = 1; // parallel edit OK EFxbrange.threadfunc = xbrange_thread; // thread function if (! edit_setup(EFxbrange)) return; // setup edit zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); // revised v.11.01 EFxbrange.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"expand"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"homog|expand"); zdialog_add_widget(zd,"vbox","vb3","hb1",0,"homog|space=8"); zdialog_add_widget(zd,"label","labD","vb1",labD); zdialog_add_widget(zd,"label","labB","vb1",labB); zdialog_add_widget(zd,"hscale","clipD","vb2","0|99|0.5|0"); zdialog_add_widget(zd,"hscale","clipB","vb2","0|99|0.5|0"); zdialog_add_widget(zd,"label","darkval","vb3"); zdialog_add_widget(zd,"label","briteval","vb3"); zdialog_resize(zd,300,0); zdialog_help(zd,"expand_brightness"); // zdialog help topic v.11.08 zdialog_run(zd,xbrange_dialog_event,"save"); // run dialog - parallel v.11.07 m_histogram(0,0); // show brightness distribution v.11.02 xbrangeD = xbrangeB = 0; // initial clip = 0 return; } // dialog event and completion callback function int xbrange_dialog_event(zdialog *zd, cchar *event) { char text[8]; if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFxbrange); else edit_cancel(EFxbrange); histogram_destroy(); // v.11.02 return 1; } edit_takeover(EFxbrange); // set my edit function if (strEqu(event,"reset")) { // reset dialog controls v.11.08 zdialog_stuff(zd,"clipD",0); zdialog_stuff(zd,"clipB",0); } if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strEqu(event,"clipD")) { zdialog_fetch(zd,"clipD",xbrangeD); signal_thread(); } if (strEqu(event,"clipB")) { zdialog_fetch(zd,"clipB",xbrangeB); signal_thread(); } sprintf(text,"%.0f",xbrangeD); // numeric feedback v.11.07 zdialog_stuff(zd,"darkval",text); sprintf(text,"%.0f",xbrangeB); zdialog_stuff(zd,"briteval",text); return 0; } // thread function void * xbrange_thread(void *) { int ii, px, py, dist = 0; double dark, bright, b1, b3, bf, f1, f2; double red1, green1, blue1, red3, green3, blue3; uint16 *pix1, *pix3; while (true) { thread_idle_loop(); // wait for work or exit request dark = 0.01 * xbrangeD * 65536; // clipping brightness levels bright = (1.0 - 0.01 * xbrangeB) * 65536; for (py = 0; py < E3hh; py++) // loop all image pixels for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; if (Factivearea) { // select area active bugfix v.9.9 dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // pixel is outside area } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel b1 = pixbright(pix1); if (b1 < dark) // clip dark pixels b3 = 0; else if (b1 > bright) // clip bright pixels b3 = bright; else b3 = b1; if (b3 > dark) b3 = b3 - dark; // expand the rest b3 = b3 * (65535.0 / (bright - dark)); bf = b3 / (b1 + 1); // brightness ratio red1 = pix1[0]; // input RGB v.11.08 green1 = pix1[1]; blue1 = pix1[2]; red3 = bf * red1; // output RGB green3 = bf * green1; blue3 = bf * blue1; if (red3 > 65535) red3 = 65535; if (green3 > 65535) green3 = 65535; if (blue3 > 65535) blue3 = 65535; if (Factivearea && dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; red3 = f1 * red3 + f2 * red1; green3 = f1 * green3 + f2 * green1; blue3 = f1 * blue3 + f2 * blue1; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } CEF->Fmod = 1; mwpaint2(); } return 0; // not executed, stop g++ warning } /**************************************************************************/ // flatten brightness distribution double flatten_value = 0; // flatten value, 0 - 100% double flatten_brdist[65536]; void flatten_update_image(); void flatten_distribution(); // compute brightness distribution void flatten_pixel(int px, int py); // compute new pixel brightness editfunc EFflatten; void m_flatten(GtkWidget *, cchar *) { int flatten_dialog_event(zdialog* zd, cchar *event); void * flatten_thread(void *); cchar *title = ZTX("Flatten Brightness Distribution"); zfuncs::F1_help_topic = "flatten"; EFflatten.funcname = "flatten"; EFflatten.Fprev = 1; // preview EFflatten.Farea = 2; // select area usable EFflatten.Fpara = 1; // parallel edit OK EFflatten.threadfunc = flatten_thread; if (! edit_setup(EFflatten)) return; // setup edit zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); EFflatten.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=15"); zdialog_add_widget(zd,"label","labfd","hb1",ZTX("Flatten"),"space=5"); zdialog_add_widget(zd,"hscale","flatten","hb1","0|100|1|0","expand"); zdialog_add_widget(zd,"label","value","hb1",0,"space=5"); zdialog_help(zd,"flatten"); // v.11.08 zdialog_resize(zd,300,0); zdialog_run(zd,flatten_dialog_event,"save"); // run dialog - parallel v.11.07 flatten_value = 0; return; } // dialog event and completion callback function int flatten_dialog_event(zdialog *zd, cchar *event) // flatten dialog event function { char text[8]; if (zd->zstat) { if (zd->zstat == 1) edit_done(EFflatten); // done else edit_cancel(EFflatten); // cancel or destroy return 0; } edit_takeover(EFflatten); // set my edit function if (strEqu(event,"blendwidth")) flatten_update_image(); // v.11.06 if (strEqu(event,"flatten")) { zdialog_fetch(zd,"flatten",flatten_value); // get slider value sprintf(text,"%.0f",flatten_value); // numeric feedback v.11.07 zdialog_stuff(zd,"value",text); flatten_update_image(); // trigger update thread } return 1; } // Update image based on select area and dialog controls void flatten_update_image() // v.11.06 { int px, py, ww, hh; if (Factivearea && sa_Npixel < 200000) // if relatively small area, { // process in main() thread v.11.06 flatten_distribution(); for (py = sa_miny; py < sa_maxy; py++) for (px = sa_minx; px < sa_maxx; px++) flatten_pixel(px,py); px = sa_minx; // direct window update py = sa_miny; ww = sa_maxx - sa_minx; hh = sa_maxy - sa_miny; mwpaint3(px,py,ww,hh); // speedup v.11.06 CEF->Fmod = 1; } else signal_thread(); // use thread process return; } // thread function - use multiple working threads void * flatten_thread(void *) { void * flatten_wthread(void *arg); while (true) { thread_idle_loop(); // wait for work or exit request flatten_distribution(); for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(flatten_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * flatten_wthread(void *arg) // worker thread function { int index = *((int *) (arg)); int px, py; for (py = index; py < E1hh; py += Nwt) // flatten brightness distribution for (px = 0; px < E1ww; px++) flatten_pixel(px,py); exit_wthread(); return 0; // not executed, avoid gcc warning } // compute brightness distribution for image or selected area void flatten_distribution() { int px, py, ii, npix; int ww = E1ww, hh = E1hh; double bright1; uint16 *pix1; for (ii = 0; ii < 65536; ii++) // clear brightness distribution data flatten_brdist[ii] = 0; if (Factivearea) // process selected area { for (ii = npix = 0; ii < ww * hh; ii++) { if (! sa_pixmap[ii]) continue; py = ii / ww; px = ii - py * ww; pix1 = PXMpix(E1pxm16,px,py); bright1 = pixbright(pix1); flatten_brdist[int(bright1)]++; npix++; } for (ii = 1; ii < 65536; ii++) // cumulative brightness distribution flatten_brdist[ii] += flatten_brdist[ii-1]; // 0 ... npix for (ii = 0; ii < 65536; ii++) flatten_brdist[ii] = flatten_brdist[ii] // multiplier per brightness level / npix * 65536.0 / (ii + 1); } else // process whole image { for (py = 0; py < hh; py++) // compute brightness distribution for (px = 0; px < ww; px++) { pix1 = PXMpix(E1pxm16,px,py); bright1 = pixbright(pix1); flatten_brdist[int(bright1)]++; } for (ii = 1; ii < 65536; ii++) // cumulative brightness distribution flatten_brdist[ii] += flatten_brdist[ii-1]; // 0 ... (ww * hh) for (ii = 0; ii < 65536; ii++) flatten_brdist[ii] = flatten_brdist[ii] // multiplier per brightness level / (ww * hh) * 65536.0 / (ii + 1); } return; } // compute new brightness for one pixel void flatten_pixel(int px, int py) { int ii, dist = 0; uint16 *pix1, *pix3; double fold, fnew, dold, dnew, cmax; double red1, green1, blue1, red3, green3, blue3; double bright1, bright2; if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) return; // outside pixel } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel fnew = 0.01 * flatten_value; // 0.0 - 1.0 how much to flatten fold = 1.0 - fnew; // 1.0 - 0.0 how much to retain red1 = pix1[0]; green1 = pix1[1]; blue1 = pix1[2]; bright1 = 0.25 * red1 + 0.65 * green1 + 0.10 * blue1; // input brightness bright2 = flatten_brdist[int(bright1)]; // output brightness adjustment red3 = bright2 * red1; // flattened brightness green3 = bright2 * green1; blue3 = bright2 * blue1; red3 = fnew * red3 + fold * red1; // blend new and old brightness green3 = fnew * green3 + fold * green1; blue3 = fnew * blue3 + fold * blue1; if (Factivearea && dist < sa_blend) { // select area is active, dnew = 1.0 * dist / sa_blend; // blend changes over sa_blend dold = 1.0 - dnew; red3 = dnew * red3 + dold * red1; green3 = dnew * green3 + dold * green1; blue3 = dnew * blue3 + dold * blue1; } cmax = red3; // stop overflow, keep color balance if (green3 > cmax) cmax = green3; if (blue3 > cmax) cmax = blue3; if (cmax > 65535) { cmax = 65535 / cmax; red3 = red3 * cmax; green3 = green3 * cmax; blue3 = blue3 * cmax; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; return; } /**************************************************************************/ // ramp brightness across image, vertical and horizontal gradients editfunc EFbrramp; int brramp_spc; // current spline curves (2 at a time) void m_brightramp(GtkWidget *, cchar *) // upgrade for 4 colors v.11.07 { int brramp_dialog_event(zdialog* zd, cchar *event); void brramp_curvedit(int spc); void * brramp_thread(void *); void brramp_init(); zfuncs::F1_help_topic = "brightness_ramp"; EFbrramp.funcname = "bright-ramp"; EFbrramp.Fprev = 1; // use preview EFbrramp.Farea = 2; // select area usable EFbrramp.Fpara = 1; // parallel edit OK EFbrramp.threadfunc = brramp_thread; if (! edit_setup(EFbrramp)) return; // setup edit /*** _________________________________________ | | | | | curve edit area | | | | | |_________________________________________| (o) all (o) red (o) green (o) blue // colors: all, red, green, blue Curve File: [Open] [Save] // each has vert. and horiz. curve [Done] [Cancel] ***/ zdialog *zd = zdialog_new(ZTX("Ramp brightness across image"),mWin,Bdone,Bcancel,null); EFbrramp.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5|expand"); zdialog_add_widget(zd,"vbox","vb1","hb1"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"expand"); zdialog_add_widget(zd,"label","lmax","vb1","+","space=3"); zdialog_add_widget(zd,"label","lspace","vb1",0,"expand"); zdialog_add_widget(zd,"label","lmin","vb1","‒","space=3"); zdialog_add_widget(zd,"label","lspace","vb1"); zdialog_add_widget(zd,"frame","frame","vb2",0,"expand"); zdialog_add_widget(zd,"hbox","hb2","vb2"); zdialog_add_widget(zd,"label","lmin","hb2","‒","space=3"); zdialog_add_widget(zd,"label","lspace","hb2",0,"expand"); zdialog_add_widget(zd,"label","lmax","hb2","+","space=3"); zdialog_add_widget(zd,"hbox","hbrgb","dialog",0,"space=3"); zdialog_add_widget(zd,"radio","all","hbrgb",Ball,"space=5"); zdialog_add_widget(zd,"radio","red","hbrgb",Bred,"space=5"); zdialog_add_widget(zd,"radio","green","hbrgb",Bgreen,"space=5"); zdialog_add_widget(zd,"radio","blue","hbrgb",Bblue,"space=5"); zdialog_add_widget(zd,"hbox","hbcf","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labcf","hbcf",Bcurvefile,"space=8"); zdialog_add_widget(zd,"button","load","hbcf",Bopen,"space=5"); zdialog_add_widget(zd,"button","save","hbcf",Bsave,"space=5"); GtkWidget *frame = zdialog_widget(zd,"frame"); spldat *sd = splcurve_init(frame,brramp_curvedit); // v.11.01 EFbrramp.curves = sd; brramp_init(); // set up initial flat curves sd->Nspc = 2; // only curves 0-1 are shown brramp_spc = 2; // current curves: all (2-3) zdialog_stuff(zd,"all",1); // stuff default selection, all zdialog_resize(zd,260,350); zdialog_help(zd,"brightness_ramp"); // zdialog help topic v.11.08 zdialog_run(zd,brramp_dialog_event,"save"); // run dialog - parallel v.11.07 return; } // initialize all curves to flat void brramp_init() { spldat *sd = EFbrramp.curves; for (int ii = 0; ii < 10; ii++) // loop curves: current (0-1), all (2-3), { // red (4-5), green (6-7), blue (8-9) sd->nap[ii] = 2; // horizontal curve ii sd->vert[ii] = 0; sd->apx[ii][0] = 0.01; sd->apx[ii][1] = 0.99; sd->apy[ii][0] = sd->apy[ii][1] = 0.5; splcurve_generate(sd,ii); ii++; sd->nap[ii] = 2; // vertical curve ii+1 sd->vert[ii] = 1; sd->apx[ii][0] = 0.01; sd->apx[ii][1] = 0.99; sd->apy[ii][0] = sd->apy[ii][1] = 0.5; splcurve_generate(sd,ii); } return; } // dialog event and completion callback function int brramp_dialog_event(zdialog *zd, cchar *event) { spldat *sd = EFbrramp.curves; int ii, jj, nn, Fupdate = 0; spldat sdtemp; if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFbrramp); else edit_cancel(EFbrramp); return 1; } edit_takeover(EFbrramp); // set my edit function if (strEqu(event,"reset")) { // reset dialog controls v.11.08 brramp_init(); Fupdate++; } if (strEqu(event,"blendwidth")) signal_thread(); if (strstr("all red green blue",event)) { // new choice of curve zdialog_fetch(zd,event,ii); if (! ii) return 0; // ignore button OFF events ii = strcmpv(event,"all","red","green","blue",null); brramp_spc = ii = 2 * ii; // 2, 4, 6, 8 sd->nap[0] = sd->nap[ii]; // copy active curves ii/ii+1 to curves 0/1 sd->nap[1] = sd->nap[ii+1]; for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[0][jj] = sd->apx[ii][jj]; sd->apy[0][jj] = sd->apy[ii][jj]; } for (jj = 0; jj < sd->nap[1]; jj++) { sd->apx[1][jj] = sd->apx[ii+1][jj]; sd->apy[1][jj] = sd->apy[ii+1][jj]; } Fupdate++; } if (strEqu(event,"load")) // load 8 saved curves from file { sdtemp.Nspc = 8; sdtemp.drawarea = 0; nn = splcurve_load(&sdtemp); if (nn != 1) return 0; for (ii = 0; ii < 8; ii++) { // load curves 0-7 to curves 2-9 sd->vert[ii+2] = sdtemp.vert[ii]; sd->nap[ii+2] = sdtemp.nap[ii]; for (jj = 0; jj < sdtemp.nap[ii]; jj++) { sd->apx[ii+2][jj] = sdtemp.apx[ii][jj]; sd->apy[ii+2][jj] = sdtemp.apy[ii][jj]; } splcurve_generate(sd,ii+2); } ii = brramp_spc; // current active curves: 2, 4, 6, 8 sd->nap[0] = sd->nap[ii]; // copy 2 active curves to curves 0-1 for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[0][jj] = sd->apx[ii][jj]; sd->apy[0][jj] = sd->apy[ii][jj]; } sd->nap[1] = sd->nap[ii+1]; for (jj = 0; jj < sd->nap[1]; jj++) { sd->apx[1][jj] = sd->apx[ii+1][jj]; sd->apy[1][jj] = sd->apy[ii+1][jj]; } Fupdate++; } if (strEqu(event,"save")) // save 8 curves to file { sdtemp.Nspc = 8; for (ii = 0; ii < 8; ii++) { sdtemp.vert[ii] = sd->vert[ii+2]; sdtemp.nap[ii] = sd->nap[ii+2]; for (jj = 0; jj < sd->nap[ii+2]; jj++) { sdtemp.apx[ii][jj] = sd->apx[ii+2][jj]; sdtemp.apy[ii][jj] = sd->apy[ii+2][jj]; } } splcurve_save(&sdtemp); } if (Fupdate) // curve has changed { splcurve_generate(sd,0); // regenerate curves 0-1 splcurve_generate(sd,1); ii = brramp_spc; // active curves sd->nap[ii] = sd->nap[0]; // copy curves 0-1 to active curves for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[ii][jj] = sd->apx[0][jj]; sd->apy[ii][jj] = sd->apy[0][jj]; } sd->nap[ii+1] = sd->nap[1]; for (jj = 0; jj < sd->nap[1]; jj++) { sd->apx[ii+1][jj] = sd->apx[1][jj]; sd->apy[ii+1][jj] = sd->apy[1][jj]; } for (jj = 0; jj < 1000; jj++) { sd->yval[ii][jj] = sd->yval[0][jj]; sd->yval[ii+1][jj] = sd->yval[1][jj]; } splcurve_draw(0,0,sd); // draw curves signal_thread(); // trigger image update } return 1; } // this function is called when a curve is edited void brramp_curvedit(int spc) { int ii = brramp_spc, jj; spldat *sd = EFbrramp.curves; // active curves: 2, 4, 6, 8 (and +1) edit_takeover(EFbrramp); // set my edit function sd->nap[ii] = sd->nap[0]; // copy curves 0-1 to active curves for (jj = 0; jj < sd->nap[0]; jj++) { sd->apx[ii][jj] = sd->apx[0][jj]; sd->apy[ii][jj] = sd->apy[0][jj]; } sd->nap[ii+1] = sd->nap[1]; for (jj = 0; jj < sd->nap[1]; jj++) { sd->apx[ii+1][jj] = sd->apx[1][jj]; sd->apy[ii+1][jj] = sd->apy[1][jj]; } for (jj = 0; jj < 1000; jj++) { sd->yval[ii][jj] = sd->yval[0][jj]; sd->yval[ii+1][jj] = sd->yval[1][jj]; } if (brramp_spc == 2) { // "all" curve was edited for (ii = 4; ii < 10; ii += 2) { // fix R/G/B curves to match sd->nap[ii] = sd->nap[2]; for (jj = 0; jj < sd->nap[2]; jj++) { sd->apx[ii][jj] = sd->apx[2][jj]; sd->apy[ii][jj] = sd->apy[2][jj]; } for (jj = 0; jj < 1000; jj++) sd->yval[ii][jj] = sd->yval[2][jj]; } for (ii = 5; ii < 10; ii += 2) { sd->nap[ii] = sd->nap[3]; for (jj = 0; jj < sd->nap[3]; jj++) { sd->apx[ii][jj] = sd->apx[3][jj]; sd->apy[ii][jj] = sd->apy[3][jj]; } for (jj = 0; jj < 1000; jj++) sd->yval[ii][jj] = sd->yval[3][jj]; } } signal_thread(); return; } // brramp thread function void * brramp_thread(void *arg) { void * brramp_wthread(void *); while (true) { thread_idle_loop(); // wait for work or exit request for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(brramp_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion mwpaint2(); // update window CEF->Fmod = 1; // image3 modified } return 0; // not executed, stop g++ warning } void * brramp_wthread(void *arg) // worker thread function { int index = *((int *) arg); int ii, jj, kk, dist = 0, px3, py3; uint16 *pix1, *pix3; double red1, green1, blue1, maxrgb; double red3, green3, blue3; double dispx, dispy; double hramp[3], vramp[3], tramp[3]; double spanw, spanh, dold, dnew; spldat *sd = EFbrramp.curves; if (Factivearea) { // if select area active, ramp spanw = sa_maxx - sa_minx; // brightness over enclosing rectangle spanh = sa_maxy - sa_miny; } else { spanw = E3ww; // else over entire image spanh = E3hh; } for (py3 = index; py3 < E3hh; py3 += Nwt) // loop output pixels for (px3 = 0; px3 < E3ww; px3++) { if (Factivearea) { // select area active v.10.1 ii = py3 * E3ww + px3; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // pixel outside area dispx = (px3 - sa_minx) / spanw; dispy = (py3 - sa_miny) / spanh; } else { dispx = px3 / spanw; // left > right = 0 to 1 dispy = py3 / spanh; // top > bottom = 0 to 1 } kk = 1000 * dispx; // conv. dispx 0-1 to 0-1000 if (kk > 999) kk = 999; for (ii = 0, jj = 4; ii < 3; ii++, jj+=2) // horz. curves for dispx and R/G/B hramp[ii] = sd->yval[jj][kk] - 0.5; // scale to -0.5 to +0.5 kk = 1000 * dispy; // conv. dispy if (kk > 999) kk = 999; for (ii = 0, jj = 5; ii < 3; ii++, jj+=2) // vert. curves vramp[ii] = sd->yval[jj][kk] - 0.5; for (ii = 0; ii < 3; ii++) // total R/G/B change tramp[ii] = 1.0 + hramp[ii] + vramp[ii]; // scale to 0.0 to 2.0 pix1 = PXMpix(E1pxm16,px3,py3); // input pixel red1 = pix1[0]; green1 = pix1[1]; blue1 = pix1[2]; red3 = red1 * tramp[0]; // change R/G/B green3 = green1 * tramp[1]; blue3 = blue1 * tramp[2]; maxrgb = red3; if (green3 > maxrgb) maxrgb = green3; if (blue3 > maxrgb) maxrgb = blue3; if (maxrgb > 65535) { // stop overflow red3 = red3 * 65535 / maxrgb; green3 = green3 * 65535 / maxrgb; blue3 = blue3 * 65535 / maxrgb; } if (Factivearea && dist < sa_blend) { // blend changes over blendwidth v.10.1 dnew = 1.0 * dist / sa_blend; dold = 1.0 - dnew; red3 = dnew * red3 + dold * red1; green3 = dnew * green3 + dold * green1; blue3 = dnew * blue3 + dold * blue1; } pix3 = PXMpix(E3pxm16,px3,py3); // output pixel pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } exit_wthread(); return 0; // not executed, avoid gcc warning } /************************************************************************** Image Tone Mapping function enhance local contrast as opposed to overall contrast methodology: get brightness gradients for each pixel in 4 directions: SE SW NE NW amplify gradients using the edit curve (x-axis range 0-max. gradient) integrate 4 new brightness surfaces from the amplified gradients: - pixel brightness = prior pixel brightness + amplified gradient - the Amplify control varies amplification from zero to overamplified new pixel brightness = average from 4 calculated brightness surfaces ***************************************************************************/ float *Tmap_brmap1; float *Tmap_brmap3[4]; int Tmap_contrast99; double Tmap_amplify; editfunc EFtonemap; void m_tonemap(GtkWidget *, cchar *) // new v.9.8 { int Tmap_dialog_event(zdialog *zd, cchar *event); void Tmap_curvedit(int); void * Tmap_thread(void *); zfuncs::F1_help_topic = "tone_mapping"; // v.10.8 int ii, cc, px, py; uint16 *pix1; cchar *title = ZTX("Tone Mapping"); int jj, sum, limit, condist[100]; EFtonemap.funcname = "tonemap"; EFtonemap.Farea = 2; // select area usable EFtonemap.Fpara = 1; // parallel edit OK EFtonemap.threadfunc = Tmap_thread; if (! edit_setup(EFtonemap)) return; // setup: no preview, select area OK /*** _____________________________ | | | | | curve drawing area | | | |_____________________________| low contrast high Amplify ========[]========= Curve File: [ Open ] [ Save ] ***/ zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); EFtonemap.zd = zd; zdialog_add_widget(zd,"frame","frame","dialog",0,"expand"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labcL","hb1",ZTX("low"),"space=4"); zdialog_add_widget(zd,"label","labcM","hb1",ZTX("contrast"),"expand"); zdialog_add_widget(zd,"label","labcH","hb1",ZTX("high"),"space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labcon","hb2",ZTX("Amplify"),"space=5"); zdialog_add_widget(zd,"hscale","amplify","hb2","0|1|0.01|0","expand"); zdialog_add_widget(zd,"label","ampval","hb2",0,"space=5"); zdialog_add_widget(zd,"hbox","hbcf","dialog",0,"space=8"); zdialog_add_widget(zd,"label","labcf","hbcf",Bcurvefile,"space=5"); zdialog_add_widget(zd,"button","load","hbcf",Bopen,"space=5"); zdialog_add_widget(zd,"button","save","hbcf",Bsave,"space=5"); GtkWidget *frame = zdialog_widget(zd,"frame"); // set up curve edit spldat *sd = splcurve_init(frame,Tmap_curvedit); // v.11.01 EFtonemap.curves = sd; sd->Nspc = 1; sd->vert[0] = 0; sd->nap[0] = 3; // initial curve anchor points sd->apx[0][0] = 0.01; sd->apy[0][0] = 0.2; sd->apx[0][1] = 0.50; sd->apy[0][1] = 0.4; sd->apx[0][2] = 0.99; sd->apy[0][2] = 0.0; splcurve_generate(sd,0); // generate curve data cc = Fww * Fhh * sizeof(float); // allocate brightness map memory Tmap_brmap1 = (float *) zmalloc(cc,"tonemap"); for (ii = 0; ii < 4; ii++) Tmap_brmap3[ii] = (float *) zmalloc(cc,"tonemap"); for (py = 0; py < Fhh; py++) // map initial image brightness for (px = 0; px < Fww; px++) { ii = py * Fww + px; pix1 = PXMpix(E1pxm16,px,py); Tmap_brmap1[ii] = pixbright(pix1); } for (ii = 0; ii < 100; ii++) condist[ii] = 0; for (py = 1; py < Fhh; py++) // map contrast distribution for (px = 1; px < Fww; px++) { ii = py * Fww + px; jj = 0.00152 * fabsf(Tmap_brmap1[ii] - Tmap_brmap1[ii-1]); // contrast, ranged 0 - 99 condist[jj]++; jj = 0.00152 * fabsf(Tmap_brmap1[ii] - Tmap_brmap1[ii-Fww]); condist[jj]++; } sum = 0; limit = 0.99 * 2 * (Fww-1) * (Fhh-1); // find 99th percentile contrast for (ii = 0; ii < 100; ii++) { sum += condist[ii]; if (sum > limit) break; } Tmap_contrast99 = 65535.0 * ii / 100.0; // 0 to 65535 if (Tmap_contrast99 < 1000) Tmap_contrast99 = 1000; // rescale low-contrast image v.10.9 zdialog_resize(zd,300,300); zdialog_help(zd,"tone_mapping"); // zdialog help topic v.11.08 zdialog_run(zd,Tmap_dialog_event,"save"); // run dialog - parallel v.11.07 Tmap_amplify = 0; return; } // dialog event and completion callback function int Tmap_dialog_event(zdialog *zd, cchar *event) { spldat *sd = EFtonemap.curves; char text[8]; if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFtonemap); else edit_cancel(EFtonemap); zfree(Tmap_brmap1); // free memory for (int ii = 0; ii < 4; ii++) zfree(Tmap_brmap3[ii]); return 1; } edit_takeover(EFtonemap); // set my edit function if (strEqu(event,"reset")) // reset dialog controls v.11.08 zdialog_stuff(zd,"amplify",0); if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strEqu(event,"amplify")) { // slider value zdialog_fetch(zd,"amplify",Tmap_amplify); sprintf(text,"%.2f",Tmap_amplify); // numeric feedback v.11.07 zdialog_stuff(zd,"ampval",text); signal_thread(); // trigger update thread } if (strEqu(event,"load")) { // load saved curve v.11.02 splcurve_load(sd); signal_thread(); return 0; } if (strEqu(event,"save")) { // save curve to file v.11.02 splcurve_save(sd); return 0; } return 0; } // this function is called when the curve is edited void Tmap_curvedit(int) { edit_takeover(EFtonemap); // set my edit function signal_thread(); return; } // thread function void * Tmap_thread(void *) { void * Tmap_wthread1(void *arg); void * Tmap_wthread2(void *arg); int ii; while (true) { thread_idle_loop(); // wait for work or exit request for (ii = 0; ii < 4; ii++) // start working threads1 (must be 4) start_wthread(Tmap_wthread1,&wtnx[ii]); wait_wthreads(); // wait for completion for (ii = 0; ii < Nwt; ii++) // start working threads2 start_wthread(Tmap_wthread2,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); } return 0; // not executed, stop g++ warning } // working threads void * Tmap_wthread1(void *arg) // hardened v.9.9 { int ii, kk, bii, pii, dist = 0; int px, px1, px2, pxinc; int py, py1, py2, pyinc; float b1, b3, xval, yval, grad; float amplify, contrast99; spldat *sd = EFtonemap.curves; contrast99 = Tmap_contrast99; // 99th percentile contrast contrast99 = 1.0 / contrast99; // inverted amplify = pow(Tmap_amplify,0.2); // get amplification, 0 to 1 v.11.02 bii = *((int *) arg); if (bii == 0) { // direction SE px1 = 1; px2 = E3ww; pxinc = 1; py1 = 1; py2 = E3hh; pyinc = 1; pii = - 1 - E3ww; } else if (bii == 1) { // direction SW px1 = E3ww-2; px2 = 0; pxinc = -1; py1 = 1; py2 = E3hh; pyinc = 1; pii = + 1 - E3ww; } else if (bii == 2) { // direction NE px1 = 1; px2 = E3ww; pxinc = 1; py1 = E3hh-2; py2 = 0; pyinc = -1; pii = - 1 + E3ww; } else { /* bii == 3 */ // direction NW px1 = E3ww-2; px2 = 0; pxinc = -1; py1 = E3hh-2; py2 = 0; pyinc = -1; pii = + 1 + E3ww; } for (ii = 0; ii < E3ww * E3hh; ii++) // initial brightness map Tmap_brmap3[bii][ii] = Tmap_brmap1[ii]; for (py = py1; py != py2; py += pyinc) // loop all image pixels for (px = px1; px != px2; px += pxinc) { ii = py * E3ww + px; if (Factivearea) { // select area active dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // outside pixel } b1 = Tmap_brmap1[ii]; // this pixel brightness grad = b1 - Tmap_brmap1[ii+pii]; // - prior pixel --> gradient xval = fabsf(grad) * contrast99; // gradient scaled 0 to 1+ kk = 1000.0 * xval; if (kk > 999) kk = 999; // speedup v.11.06 yval = 1.0 + 5.0 * sd->yval[0][kk]; grad = grad * yval; // magnified gradient b3 = Tmap_brmap3[bii][ii+pii] + grad; // pixel brightness = prior + gradient b3 = (1.0 - amplify) * b1 + amplify * b3; // constrain: push b3 toward b1 v.11.02 if (b3 > 65535) b3 = 65535; // constrain if (b3 < 10) b3 = 10; Tmap_brmap3[bii][ii] = b3; // new pixel brightness } exit_wthread(); return 0; // not executed, avoid gcc warning } void * Tmap_wthread2(void *arg) // speedup v.10.2 { uint16 *pix1, *pix3; int index, ii, px, py, dist = 0; float b1, b3, bf, f1, f2; float red1, green1, blue1, red3, green3, blue3; index = *((int *) arg); for (py = index; py < E3hh; py += Nwt) // loop all image pixels for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; if (Factivearea) { // select area active bugfix v.9.9 dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // pixel is outside area } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel b1 = Tmap_brmap1[ii]; // initial pixel brightness b3 = Tmap_brmap3[0][ii] + Tmap_brmap3[1][ii] // new brightness = average of four + Tmap_brmap3[2][ii] + Tmap_brmap3[3][ii]; // calculated brightness surfaces bf = 0.25 * b3 / (b1 + 1); // brightness ratio red1 = pix1[0]; // input RGB green1 = pix1[1]; blue1 = pix1[2]; red3 = bf * red1; // output RGB if (red3 > 65535) red3 = 65535; green3 = bf * green1; if (green3 > 65535) green3 = 65535; blue3 = bf * blue1; if (blue3 > 65535) blue3 = 65535; if (Factivearea && dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; red3 = f1 * red3 + f2 * red1; green3 = f1 * green3 + f2 * green1; blue3 = f1 * blue3 + f2 * blue1; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } exit_wthread(); return 0; // not executed, stop g++ warning } /**************************************************************************/ // adjust white balance void whitebal_mousefunc(); double whitebal_red, whitebal_green, whitebal_blue; editfunc EFwhitebal; void m_whitebal(GtkWidget *, cchar *) { int whitebal_dialog_event(zdialog *zd, cchar *event); void * whitebal_thread(void *); cchar *wbtitle = ZTX("Adjust White Balance"); cchar *wbhelp = ZTX("Click white or gray image location"); zfuncs::F1_help_topic = "white_balance"; // v.10.8 EFwhitebal.funcname = "white-balance"; EFwhitebal.Fprev = 1; // use preview EFwhitebal.Farea = 2; // select area usable EFwhitebal.Fpara = 1; // parallel edits OK EFwhitebal.threadfunc = whitebal_thread; // thread function EFwhitebal.mousefunc = whitebal_mousefunc; // mouse function if (! edit_setup(EFwhitebal)) return; // setup edit: preview zdialog *zd = zdialog_new(wbtitle,mWin,Bdone,Bcancel,null); EFwhitebal.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"label","labwbh","hb1",wbhelp,"space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labpix","hb2","pixel:"); zdialog_add_widget(zd,"label","pixel","hb2","0000 0000"); zdialog_add_widget(zd,"label","labrgb","hb2"," RGB:"); zdialog_add_widget(zd,"label","rgb","hb2","000 000 000"); zdialog_help(zd,"white_balance"); // zdialog help topic v.11.08 zdialog_run(zd,whitebal_dialog_event,"save"); // run dialog - parallel v.11.07 whitebal_red = whitebal_green = whitebal_blue = 1.0; takeMouse(zd,whitebal_mousefunc,dragcursor); // connect mouse function v.11.03 return; } // dialog event and completion callback function int whitebal_dialog_event(zdialog *zd, cchar *event) // dialog event function v.10.2 { if (zd->zstat) { if (zd->zstat == 1) edit_done(EFwhitebal); // done else edit_cancel(EFwhitebal); // cancel or destroy return 0; } edit_takeover(EFwhitebal); // set my edit function if (strEqu(event,"focus")) // toggle mouse capture v.12.01 takeMouse(zd,whitebal_mousefunc,dragcursor); // connect mouse function if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 return 1; } void whitebal_mousefunc() // mouse function { int px, py, dx, dy; double red, green, blue, rgbmean; char work[40]; uint16 *ppix16; zdialog *zd = EFwhitebal.zd; if (! LMclick) return; edit_takeover(EFwhitebal); // set my edit function LMclick = 0; px = Mxclick; // mouse click position py = Myclick; if (px < 2) px = 2; // pull back from edge if (px > E3ww-3) px = E3ww-3; if (py < 2) py = 2; if (py > E3hh-3) py = E3hh-3; red = green = blue = 0; for (dy = -2; dy <= 2; dy++) // 5x5 block around mouse position for (dx = -2; dx <= 2; dx++) { ppix16 = PXMpix(E1pxm16,px+dx,py+dy); // input image red += ppix16[0]; green += ppix16[1]; blue += ppix16[2]; } red = red / 25.0; // mean RGB levels green = green / 25.0; blue = blue / 25.0; rgbmean = (red + green + blue) / 3.0; whitebal_red = rgbmean / red; whitebal_green = rgbmean / green; whitebal_blue = rgbmean / blue; signal_thread(); // trigger image update snprintf(work,40,"%d %d",px,py); zdialog_stuff(zd,"pixel",work); snprintf(work,40,"%7.3f %7.3f %7.3f",red/256,green/256,blue/256); zdialog_stuff(zd,"rgb",work); return; } // Update image based on neutral pixel that was clicked void * whitebal_thread(void *) { void * whitebal_wthread(void *arg); while (true) { thread_idle_loop(); // wait for work or exit request for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(whitebal_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * whitebal_wthread(void *arg) // worker thread function { int index = *((int *) arg); int px, py, ii, dist = 0; uint16 *pix1, *pix3; double red1, green1, blue1; double red3, green3, blue3; double brmax, dold, dnew; for (py = index; py < E1hh; py += Nwt) for (px = 0; px < E1ww; px++) { if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // pixel outside area } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel red1 = pix1[0]; green1 = pix1[1]; blue1 = pix1[2]; red3 = whitebal_red * red1; // change color ratios green3 = whitebal_green * green1; blue3 = whitebal_blue * blue1; if (Factivearea && dist < sa_blend) { // select area is active, dnew = 1.0 * dist / sa_blend; // blend changes over sa_blend dold = 1.0 - dnew; red3 = dnew * red3 + dold * red1; green3 = dnew * green3 + dold * green1; blue3 = dnew * blue3 + dold * blue1; } brmax = red3; // brmax = brightest color if (green3 > brmax) brmax = green3; if (blue3 > brmax) brmax = blue3; if (brmax > 65535) { // if overflow, reduce brmax = 65535 / brmax; red3 = red3 * brmax; green3 = green3 * brmax; blue3 = blue3 * brmax; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; } exit_wthread(); return 0; // not executed, stop gcc warning } /**************************************************************************/ // match_color edit function // Adjust colors of image 2 to match the colors of image 1 // using small selected areas in each image as the match standard. void * match_color_thread(void *); void match_color_mousefunc(); int match_color_RGB1[3]; // image 1 base colors to match int match_color_RGB2[3]; // image 2 target colors to match int match_color_radius = 10; // mouse radius int match_color_mode = 0; editfunc EFmatchcolor; void m_match_color(GtkWidget *, const char *) // new v.11.07 { int match_color_dialog_event(zdialog* zd, const char *event); cchar *title = ZTX("Color Match Images"); zfuncs::F1_help_topic = "match_colors"; if (is_syncbusy()) return; // must wait for file sync v.11.11 if (! menulock(1)) return; // test menu lock menulock(0); /* Color Match Images 1 [ 10 ] mouse radius for color sample 2 [Open] image for source color 3 click on image to get source color 4 [Open] image for target color 5 click on image to set target color [done] [cancel] */ zdialog *zd = zdialog_new(title,mWin,Bdone,Bcancel,null); // match_color dialog zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=2"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"homog|space=3"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"homog|space=3"); zdialog_add_widget(zd,"label","labn1","vb1","1"); zdialog_add_widget(zd,"label","labn2","vb1","2"); zdialog_add_widget(zd,"label","labn3","vb1","3"); zdialog_add_widget(zd,"label","labn4","vb1","4"); zdialog_add_widget(zd,"label","labn5","vb1","5"); zdialog_add_widget(zd,"hbox","hbrad","vb2"); zdialog_add_widget(zd,"spin","radius","hbrad","1|20|1|10","space=5"); zdialog_add_widget(zd,"label","labrad","hbrad",ZTX("mouse radius for color sample")); zdialog_add_widget(zd,"hbox","hbop1","vb2"); zdialog_add_widget(zd,"button","open1","hbop1",ZTX("Open"),"space=5"); zdialog_add_widget(zd,"label","labop1","hbop1",ZTX("image for source color")); zdialog_add_widget(zd,"hbox","hbclik1","vb2"); zdialog_add_widget(zd,"label","labclik1","hbclik1",ZTX("click on image to get source color")); zdialog_add_widget(zd,"hbox","hbop2","vb2"); zdialog_add_widget(zd,"button","open2","hbop2",ZTX("Open"),"space=5"); zdialog_add_widget(zd,"label","labop2","hbop2",ZTX("image to set matching color")); zdialog_add_widget(zd,"hbox","hbclik2","vb2"); zdialog_add_widget(zd,"label","labclik2","hbclik2",ZTX("click on image to set matching color")); zdialog_stuff(zd,"radius",match_color_radius); // remember last radius zdialog_help(zd,"match_colors"); // zdialog help topic v.11.08 zdialog_run(zd,match_color_dialog_event); // run dialog - parallel EFmatchcolor.funcname = "match-color"; EFmatchcolor.Farea = 1; // select area ignored EFmatchcolor.threadfunc = match_color_thread; EFmatchcolor.mousefunc = match_color_mousefunc; match_color_mode = 0; if (curr_file) { match_color_mode = 1; // image 1 ready to click takeMouse(zd,match_color_mousefunc,0); // connect mouse function } return; } // match_color dialog event and completion function int match_color_dialog_event(zdialog *zd, const char *event) // match_color dialog event function { int err; if (zd->zstat) // end dialog { if (match_color_mode == 4) { // edit was started if (zd->zstat == 1) edit_done(EFmatchcolor); else edit_cancel(EFmatchcolor); } freeMouse(); zdialog_free(zd); match_color_mode = 0; return 1; } if (match_color_mode == 4) // if prior edit, cancel it edit_cancel(EFmatchcolor); if (strEqu(event,"radius")) // set new mouse radius zdialog_fetch(zd,"radius",match_color_radius); if (strEqu(event,"open1")) // get image 1 for color source { match_color_mode = 0; err = f_open(null,0,0); if (! err) match_color_mode = 1; // image 1 ready to click } if (strEqu(event,"open2")) // get image 2 to set matching color { if (match_color_mode < 2) { zmessageACK(mWin,ZTX("select source image color first")); // check that RGB1 has been set return 1; } match_color_mode = 2; err = f_open(null,0,0); if (err) return 1; match_color_mode = 3; // image 2 ready to click } takeMouse(zd,match_color_mousefunc,0); // reconnect mouse function return 1; } // mouse function - click on image and get colors to match void match_color_mousefunc() { void match_color_getRGB(int px, int py, int RGB[3]); int px, py; zdialog *zd = EFmatchcolor.zd; if (match_color_mode < 1) return; // no image available yet toparcx = Mxposn - match_color_radius; // mouse outline circle toparcy = Myposn - match_color_radius; toparcw = toparch = 2 * match_color_radius; Ftoparc = 1; paint_toparc(3); if (LMclick) { LMclick = 0; px = Mxclick; py = Myclick; if (match_color_mode == 1 || match_color_mode == 2) // image 1 ready to click { match_color_getRGB(px,py,match_color_RGB1); // get RGB1 color match_color_mode = 2; return; } if (match_color_mode == 3 || match_color_mode == 4) // image 2 ready to click { match_color_getRGB(px,py,match_color_RGB2); // get RGB2 color if (match_color_mode == 4) { edit_cancel(EFmatchcolor); // if prior edit, cancel it takeMouse(zd,match_color_mousefunc,0); // reconnect mouse function match_color_mode = 3; } if (! edit_setup(EFmatchcolor)) return; // setup edit - thread will launch match_color_mode = 4; // edit waiting for cancel or done signal_thread(); // update the target image return; } } return; } // get the RGB averages for pixels within mouse radius void match_color_getRGB(int px, int py, int RGB[3]) { int rad1 = match_color_radius; int rad2 = rad1 * rad1; int rad, npix, qx, qy; int red, green, blue; uint16 *pix1; PXM *pxm; pxm = f_load(curr_file,16); if (! pxm) return; npix = 0; red = green = blue = 0; for (qy = py-rad1; qy <= py+rad1; qy++) for (qx = px-rad1; qx <= px+rad1; qx++) { if (qx < 0 || qx > Fww-1) continue; if (qy < 0 || qy > Fhh-1) continue; rad = (qx-px) * (qx-px) + (qy-py) * (qy-py); if (rad > rad2) continue; pix1 = PXMpix(pxm,qx,qy); red += pix1[0]; green += pix1[1]; blue += pix1[2]; npix++; } RGB[0] = red / npix; RGB[1] = green / npix; RGB[2] = blue / npix; PXM_free(pxm); return; } // thread function - start multiple working threads void * match_color_thread(void *) { void * match_color_wthread(void *arg); // worker thread while (true) { thread_idle_loop(); // wait for work or exit request for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(match_color_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, avoid warning } void * match_color_wthread(void *arg) // worker thread function { int index = *((int *) (arg)); int px, py; uint16 *pix3; double Rred, Rgreen, Rblue; double red, green, blue, cmax; Rred = 1.0 * match_color_RGB1[0] / match_color_RGB2[0]; // color adjustment ratios Rgreen = 1.0 * match_color_RGB1[1] / match_color_RGB2[1]; Rblue = 1.0 * match_color_RGB1[2] / match_color_RGB2[2]; for (py = index; py < E3hh; py += Nwt) // loop all image pixels for (px = 0; px < E3ww; px++) { pix3 = PXMpix(E3pxm16,px,py); red = pix3[0] * Rred; // adjust colors green = pix3[1] * Rgreen; blue = pix3[2] * Rblue; cmax = red; // check for overflow if (green > cmax) cmax = green; if (blue > cmax) cmax = blue; if (cmax > 65535) { // fix overflow red = red * 65535 / cmax; green = green * 65535 / cmax; blue = blue * 65535 / cmax; } pix3[0] = red; pix3[1] = green; pix3[2] = blue; } exit_wthread(); return 0; // not executed, avoid gcc warning } /**************************************************************************/ // DRGB menu function // Adjust Density (Brightness) and RGB levels using 0.01 OD units editfunc EFdrgb; // edit function data int DRGBinputs[8]; int DRGBbias = 0; char *DRGB_file = 0; void m_DRGB(GtkWidget *, const char *) // new v.11.08 { int DRGB_dialog_event(zdialog *zd, cchar *event); void * DRGB_thread(void *); zfuncs::F1_help_topic = "DRGB"; EFdrgb.funcname = "DRGB"; // function name EFdrgb.Fprev = 1; // use preview EFdrgb.Farea = 2; // select area usable EFdrgb.Fpara = 1; // parallel edit OK EFdrgb.threadfunc = DRGB_thread; // thread function if (! edit_setup(EFdrgb)) return; // setup edit /*** _________________________________________________ | | | [reset] [x] Add standard bias | | +Brightness -Density [__|v] Contrast [__|v] | | +Red -Cyan [__|v] Red [__|v] | | +Green -Magenta [__|v] Green [__|v] | | +Blue -Yellow [__|v] Blue [__|x] | | | | [open] [save] [done] [cancel] | |_________________________________________________| ***/ zdialog *zd = zdialog_new("DRGB",mWin,Bopen,Bsave,Bdone,Bcancel,null); // new dialog zdialog_help(zd,"DRGB"); // add help topic to zdialog EFdrgb.zd = zd; // add dialog to edit function zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"button","reset","hb1",Breset,"space=10"); zdialog_add_widget(zd,"check","bias","hb1",ZTX("Add standard bias"),"space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog"); zdialog_add_widget(zd,"vbox","vb1","hb2",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb2","hb2",0,"homog|space=5"); zdialog_add_widget(zd,"label","space","hb2",0,"space=8"); zdialog_add_widget(zd,"vbox","vb3","hb2",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb4","hb2",0,"homog|space=5"); zdialog_add_widget(zd,"button","buBriteDens","vb1",ZTX("+Brightness -Density")); zdialog_add_widget(zd,"button","buRedDens","vb1",ZTX("+Red -Cyan")); zdialog_add_widget(zd,"button","buGreenDens","vb1",ZTX("+Green -Magenta")); zdialog_add_widget(zd,"button","buBlueDens","vb1",ZTX("+Blue -Yellow")); zdialog_add_widget(zd,"spin","spBriteDens","vb2","-99|+99|1|0"); zdialog_add_widget(zd,"spin","spRedDens","vb2","-99|+99|1|0"); zdialog_add_widget(zd,"spin","spGreenDens","vb2","-99|+99|1|0"); zdialog_add_widget(zd,"spin","spBlueDens","vb2","-99|+99|1|0"); zdialog_add_widget(zd,"button","buContrast","vb3",ZTX("Contrast")); zdialog_add_widget(zd,"button","buRedCon","vb3",ZTX("Red")); zdialog_add_widget(zd,"button","buGreenCon","vb3",ZTX("Green")); zdialog_add_widget(zd,"button","buBlueCon","vb3",ZTX("Blue")); zdialog_add_widget(zd,"spin","spContrast","vb4","-99|+99|1|0"); zdialog_add_widget(zd,"spin","spRedCon","vb4","-99|+99|1|0"); zdialog_add_widget(zd,"spin","spGreenCon","vb4","-99|+99|1|0"); zdialog_add_widget(zd,"spin","spBlueCon","vb4","-99|+99|1|0"); if (! DRGB_file) { // default file DRGB_file = zmalloc(200); // /home//.fotoxx/DRGB_parameters snprintf(DRGB_file,200,"%s/DRGB_parameters",get_zuserdir()); } zdialog_run(zd,DRGB_dialog_event,"save"); // run dialog - parallel return; } // DRGB dialog event and completion function int DRGB_dialog_event(zdialog *zd, cchar *event) // DRGB dialog event function { void DRGB_open(); void DRGB_save(); int bias; if (zd->zstat) { if (zd->zstat == 1) { // open file zd->zstat = 0; // keep dialog active DRGB_open(); // read file zdialog_stuff(zd,"bias",DRGBbias); // set all data zdialog_stuff(zd,"spBriteDens",DRGBinputs[0]); zdialog_stuff(zd,"spRedDens",DRGBinputs[1]); zdialog_stuff(zd,"spGreenDens",DRGBinputs[2]); zdialog_stuff(zd,"spBlueDens",DRGBinputs[3]); zdialog_stuff(zd,"spContrast",DRGBinputs[4]); zdialog_stuff(zd,"spRedCon",DRGBinputs[5]); zdialog_stuff(zd,"spGreenCon",DRGBinputs[6]); zdialog_stuff(zd,"spBlueCon",DRGBinputs[7]); } else if (zd->zstat == 2) { // save file zd->zstat = 0; // keep dialog active DRGB_save(); // write file } else if (zd->zstat == 3) edit_done(EFdrgb); // done else edit_cancel(EFdrgb); // cancel or destroy return 0; } edit_takeover(EFdrgb); // set parallel edit function if (strEqu(event,"bias")) // bias was changed { zdialog_fetch(zd,"bias",bias); if (bias != DRGBbias) { if (bias) { // off to on DRGBinputs[0] += 72; DRGBinputs[2] += 32; DRGBinputs[3] += 32; zdialog_set_limits(zd,"spBriteDens",-27,+171); zdialog_set_limits(zd,"spGreenDens",-67,+131); zdialog_set_limits(zd,"spBlueDens",-67,+131); } else { // on to off DRGBinputs[0] -= 72; DRGBinputs[2] -= 32; DRGBinputs[3] -= 32; zdialog_set_limits(zd,"spBriteDens",-99,+99); zdialog_set_limits(zd,"spGreenDens",-99,+99); zdialog_set_limits(zd,"spBlueDens",-99,+99); } zdialog_stuff(zd,"spBriteDens",DRGBinputs[0]); zdialog_stuff(zd,"spGreenDens",DRGBinputs[2]); zdialog_stuff(zd,"spBlueDens",DRGBinputs[3]); } DRGBbias = bias; return 1; } if (strEqu(event,"reset")) // reset dialog controls { DRGBinputs[0] = DRGBbias * 72; DRGBinputs[1] = DRGBbias * 0; DRGBinputs[2] = DRGBbias * 32; DRGBinputs[3] = DRGBbias * 32; DRGBinputs[4] = 0; DRGBinputs[5] = 0; DRGBinputs[6] = 0; DRGBinputs[7] = 0; zdialog_stuff(zd,"spBriteDens",DRGBinputs[0]); zdialog_stuff(zd,"spRedDens",DRGBinputs[1]); zdialog_stuff(zd,"spGreenDens",DRGBinputs[2]); zdialog_stuff(zd,"spBlueDens",DRGBinputs[3]); zdialog_stuff(zd,"spContrast",DRGBinputs[4]); zdialog_stuff(zd,"spRedCon",DRGBinputs[5]); zdialog_stuff(zd,"spGreenCon",DRGBinputs[6]); zdialog_stuff(zd,"spBlueCon",DRGBinputs[7]); } zdialog_fetch(zd,"spBriteDens",DRGBinputs[0]); // get all inputs zdialog_fetch(zd,"spRedDens",DRGBinputs[1]); zdialog_fetch(zd,"spGreenDens",DRGBinputs[2]); zdialog_fetch(zd,"spBlueDens",DRGBinputs[3]); zdialog_fetch(zd,"spContrast",DRGBinputs[4]); zdialog_fetch(zd,"spRedCon",DRGBinputs[5]); zdialog_fetch(zd,"spGreenCon",DRGBinputs[6]); zdialog_fetch(zd,"spBlueCon",DRGBinputs[7]); signal_thread(); // trigger update thread wait_thread_idle(); // wait until done (optional) return 1; } // load DRGB parameters from a previously saved file void DRGB_open() { int DRGB_open_dialog_event(zdialog *zd, cchar *event); zdialog *zd; zd = zdialog_new(ZTX("Load DRGB parameters"),mWin,Bopen,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"label","lab1","hb1",ZTX("File:"),"space=3"); zdialog_add_widget(zd,"entry","file","hb1",0,"expand|scc=40"); zdialog_add_widget(zd,"button","browse","hb1",Bbrowse,"space=5"); zdialog_stuff(zd,"file",DRGB_file); zdialog_run(zd,DRGB_open_dialog_event); zdialog_wait(zd); return; } int DRGB_open_dialog_event(zdialog *zd, cchar *event) { char *pp, file[200]; FILE *fid = 0; int zstat, nn; if (strEqu(event,"browse")) { pp = zgetfile1(ZTX("DRGB parameters file"),"open",DRGB_file); if (! pp) return 0; zdialog_stuff(zd,"file",pp); zfree(pp); } zstat = zd->zstat; // completion button if (zstat) { if (zstat == 1) // open { zdialog_fetch(zd,"file",file,200); // get file from dialog if (DRGB_file) zfree(DRGB_file); DRGB_file = strdupz(file); fid = fopen(file,"r"); // open file if (! fid) { zmessageACK(mWin,ZTX("file not found")); return 1; } nn = fscanf(fid,"DRGB parameters"); // read header nn = fscanf(fid,"%4d %4d %4d %4d %4d %4d %4d %4d %4d", // read data &DRGBbias, &DRGBinputs[0], &DRGBinputs[1], &DRGBinputs[2], &DRGBinputs[3], &DRGBinputs[4], &DRGBinputs[5], &DRGBinputs[6], &DRGBinputs[7]); if (nn != 9) zmessageACK(mWin,"file format error"); fclose(fid); zdialog_free(zd); } else zdialog_free(zd); // cancel or [x] } return 1; } // save DRGB parameters to a file void DRGB_save() { int DRGB_save_dialog_event(zdialog *zd, cchar *event); zdialog *zd; zd = zdialog_new(ZTX("Save DRGB parameters"),mWin,Bsave,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"label","lab1","hb1",ZTX("File:"),"space=3"); zdialog_add_widget(zd,"entry","file","hb1",0,"expand|scc=40"); zdialog_add_widget(zd,"button","browse","hb1",Bbrowse,"space=5"); zdialog_stuff(zd,"file",DRGB_file); zdialog_run(zd,DRGB_save_dialog_event); zdialog_wait(zd); return; } int DRGB_save_dialog_event(zdialog *zd, cchar *event) { char *pp, file[200]; FILE *fid = 0; int zstat; if (strEqu(event,"browse")) { pp = zgetfile1(ZTX("DRGB parameters file"),"save",DRGB_file); if (! pp) return 0; zdialog_stuff(zd,"file",pp); zfree(pp); } zstat = zd->zstat; // completion button if (zstat) { if (zstat == 1) // save { zdialog_fetch(zd,"file",file,200); // get file from dialog if (DRGB_file) zfree(DRGB_file); DRGB_file = strdupz(file); fid = fopen(file,"w"); // open file if (! fid) { zmessageACK(mWin,strerror(errno)); return 1; } fprintf(fid,"DRGB parameters \n"); // write headers fprintf(fid,"%4d %4d %4d %4d %4d %4d %4d %4d %4d ", // write data DRGBbias, DRGBinputs[0], DRGBinputs[1], DRGBinputs[2], DRGBinputs[3], DRGBinputs[4], DRGBinputs[5], DRGBinputs[6], DRGBinputs[7]); fprintf(fid,"\n"); fclose(fid); zdialog_free(zd); } else zdialog_free(zd); // cancel or [x] } return 1; } // thread function - multiple working threads to update image void * DRGB_thread(void *) { void * DRGB_wthread(void *arg); // worker thread while (true) { thread_idle_loop(); // wait for work or exit request if (Factivearea) SB_goal = sa_Npixel; // set up progress monitor else SB_goal = E3ww * E3hh; SB_done = 0; for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(DRGB_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion SB_goal = SB_done = 0; CEF->Fmod = 1; // image modified mwpaint2(); // update window } return 0; // not executed, stop warning } void * DRGB_wthread(void *arg) // worker thread function { double Du, Ru, Gu, Bu, Rd, Gd, Bd; double con, conR, conG, conB; double R1, G1, B1, R3, G3, B3; int index = *((int *) (arg)); int px, py, ii, dist = 0; uint16 *pix1, *pix3; double cmax, F, f1, f2; double c1 = 100.0 / 65536.0; double c2 = 2.0 + log10(1.0/c1); double c3 = 1.0 / 65536.0; #define ODfunc(rgb) (2.0 - log10(c1 * rgb)) // RGB units (1-65536) to OD units #define RGBfunc(od) (pow(10,(c2 - od))) // OD units to RGB units Du = -0.01 * DRGBinputs[0]; // convert inputs from cc to OD units Ru = -0.01 * DRGBinputs[1]; // range is -0.99 to +0.99 Gu = -0.01 * DRGBinputs[2]; Bu = -0.01 * DRGBinputs[3]; if (DRGBbias) { // remove bias Du += 0.72; Gu += 0.32; Bu += 0.32; } con = -0.01 * DRGBinputs[4]; conR = -0.01 * DRGBinputs[5]; conG = -0.01 * DRGBinputs[6]; conB = -0.01 * DRGBinputs[7]; for (py = index; py < E3hh; py += Nwt) // loop all image pixels for (px = 0; px < E3ww; px++) { if (Factivearea) { // select area active ii = py * E3ww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // outside area } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel R1 = pix1[0] + 1; // input RGB values, 0-65535 G1 = pix1[1] + 1; // (avoid 0) B1 = pix1[2] + 1; Rd = ODfunc(R1); // convert to OD units Gd = ODfunc(G1); Bd = ODfunc(B1); Rd += Du + Ru; // add user OD increments Gd += Du + Gu; Bd += Du + Bu; if (con) { // overall contrast Rd += con * c3 * (R1-32768); Gd += con * c3 * (G1-32768); Bd += con * c3 * (B1-32768); } if (conR) // single color contrast Rd += conR * c3 * (R1-32768); if (conG) Gd += conG * c3 * (G1-32768); if (conB) Bd += conB * c3 * (B1-32768); R3 = RGBfunc(Rd); // convert back to RGB units G3 = RGBfunc(Gd); B3 = RGBfunc(Bd); if (R3 < 0) R3 = 0; // stop underflow if (G3 < 0) G3 = 0; if (B3 < 0) B3 = 0; if (R3 > 65535 || G3 > 65535 || B3 > 65535) { // stop overflow cmax = R3; if (G3 > cmax) cmax = G3; if (B3 > cmax) cmax = B3; F = 65535 / cmax; R3 *= F; G3 *= F; B3 *= F; } if (Factivearea && dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; R3 = f1 * R3 + f2 * R1; G3 = f1 * G3 + f2 * G1; B3 = f1 * B3 + f2 * B1; } pix3[0] = R3; // output RGB values pix3[1] = G3; pix3[2] = B3; } exit_wthread(); return 0; // not executed, avoid gcc warning } /**************************************************************************/ // Show RGB values for 1-9 pixels selected with mouse-clicks. // Revise RGB values for the selected points and then revise all other // pixels to match, using a distance-weighted average of the selected pixels. void RGBR_dialog(); void RGBR_mousefunc(); void RGBR_stuff(); void * RGBR_thread(void *); zdialog *RGBRzd; int RGBRpixel[9][2]; // last 9 pixel locations clicked double RGBRval1[9][3]; // original RGB values, 0 to 255.9 double RGBRval3[9][3]; // revised RGB values, 0 to 255.9 int RGBRmetric = 1; // 1/2/3 = /RGB/EV/OD int RGBRdelta = 0; // flag, delta mode int RGBRrestart; // flag, restart dialog int RGBRnpix; // no. of selected pixels double RGBRtime; // last click time int RGBRblend; // blend factor, 10 to 1000 editfunc EFrgbrevise; // edit function parameters #define RGB2EV(rgb) (log2(rgb)-7) // RGB 0.1 to 255.9 >> EV -10 to +1 #define EV2RGB(ev) (pow(2,ev+7)) // inverse #define RGB2OD(rgb) (2-log10(100*rgb/256)) // RGB 0.1 to 255.9 >> OD 3.4 to 0.000017 #define OD2RGB(od) (pow(10,2.40824-od)) // inverse void m_revise_RGB(GtkWidget *, cchar *menu) // new v.11.07 { int RGBR_event(zdialog *zd, cchar *event); GtkWidget *widget; cchar *limits; zdialog *zd; cchar *mess = ZTX("Click image to select pixels."); PangoFontDescription *widgetfont; widgetfont = pango_font_description_from_string("Monospace 8"); // small monospace font for widgets zfuncs::F1_help_topic = "revise_RGB"; EFrgbrevise.funcname = "revise_RGB"; // setup edit function EFrgbrevise.threadfunc = RGBR_thread; EFrgbrevise.mousefunc = RGBR_mousefunc; EFrgbrevise.Farea = 1; if (! edit_setup(EFrgbrevise)) return; RGBRblend = 20; // default slider value RGBRnpix = 0; // no pixels selected yet /*** Click image to select pixels. [x] delta Metric: (o) RGB (o) EV (o) OD Pixel Red Green Blue A xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] // spin buttons for RGB/EV/OD values B xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] C xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] D xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] E xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] F xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] G xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] H xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] I xxxx xxxx [xxxx|v] [xxxx|v] [xxxx|v] Blend ==============[]================ [reset] [done] [cancel] ***/ restart: zd = zdialog_new(ZTX("Revise RGB"),mWin,Breset,Bdone,Bcancel,null); EFrgbrevise.zd = zd; RGBRzd = zd; zdialog_add_widget(zd,"hbox","hbmess","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labmess","hbmess",mess,"space=5"); zdialog_add_widget(zd,"hbox","hbmym","dialog"); zdialog_add_widget(zd,"check","delta","hbmym","delta","space=5"); zdialog_stuff(zd,"delta",RGBRdelta); zdialog_add_widget(zd,"hbox","hbmetr","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labmetr","hbmetr",ZTX("Metric:"),"space=5"); zdialog_add_widget(zd,"radio","radRGB","hbmetr","RGB","space=3"); zdialog_add_widget(zd,"radio","radEV","hbmetr","EV","space=3"); zdialog_add_widget(zd,"radio","radOD","hbmetr","OD","space=3"); if (RGBRmetric == 1) zdialog_stuff(zd,"radRGB",1); // set current metric if (RGBRmetric == 2) zdialog_stuff(zd,"radEV",1); if (RGBRmetric == 3) zdialog_stuff(zd,"radOD",1); zdialog_add_widget(zd,"hbox","hbdata","dialog"); zdialog_add_widget(zd,"vbox","vbpix","hbdata",0,"space=3|homog"); // vbox for pixel locations zdialog_add_widget(zd,"hbox","hbpix","vbpix"); zdialog_add_widget(zd,"label","labpix","hbpix","Pixel"); // header char hbpixx[8] = "hbpixx", pixx[8] = "pixx"; for (int ii = 1; ii < 10; ii++) { // add labels for pixel locations hbpixx[5] = '0' + ii; pixx[3] = '0' + ii; zdialog_add_widget(zd,"hbox",hbpixx,"vbpix"); // add hbox "hbpix1" to "hbpix9" zdialog_add_widget(zd,"label",pixx,hbpixx); // add label "pix1" to "pix9" widget = zdialog_widget(zd,pixx); gtk_widget_modify_font(widget,widgetfont); // use monofont } if (RGBRmetric == 1) limits = "-255.9|255.9|0.1|0.0"; // metric = RGB else if (RGBRmetric == 2) limits = "-8|8|0.01|0.0"; // EV else limits = "-3|3|0.002|0.0"; // OD zdialog_add_widget(zd,"vbox","vbdat","hbdata",0,"space=3|homog"); // vbox for pixel RGB values zdialog_add_widget(zd,"hbox","hbrgb","vbdat",0,"homog"); zdialog_add_widget(zd,"label","labr","hbrgb",Bred); // v.11.08 zdialog_add_widget(zd,"label","labg","hbrgb",Bgreen); zdialog_add_widget(zd,"label","labb","hbrgb",Bblue); char hbdatx[8] = "hbdatx", redx[8] = "redx", greenx[8] = "greenx", bluex[8] = "bluex"; for (int ii = 1; ii < 10; ii++) { hbdatx[5] = '0' + ii; redx[3] = '0' + ii; greenx[5] = '0' + ii; bluex[4] = '0' + ii; zdialog_add_widget(zd,"hbox",hbdatx,"vbdat"); // add hbox "hbdat1" to "hbdat9" zdialog_add_widget(zd,"spin",redx,hbdatx,limits,"space=3"); // add spin buttons for "red1" to "red9" etc. zdialog_add_widget(zd,"spin",greenx,hbdatx,limits,"space=3"); zdialog_add_widget(zd,"spin",bluex,hbdatx,limits,"space=3"); widget = zdialog_widget(zd,redx); gtk_widget_modify_font(widget,widgetfont); // use monofont widget = zdialog_widget(zd,greenx); gtk_widget_modify_font(widget,widgetfont); widget = zdialog_widget(zd,bluex); gtk_widget_modify_font(widget,widgetfont); } zdialog_add_widget(zd,"hbox","hbsoft","dialog","space=5"); zdialog_add_widget(zd,"label","labsoft","hbsoft",ZTX("Blend"),"space=3"); zdialog_add_widget(zd,"hscale","blend","hbsoft","0|100|1|20","space=5|expand"); zdialog_add_widget(zd,"label","softval","hbsoft","20"); RGBR_stuff(); // stuff current pixels (if restart) takeMouse(zd,RGBR_mousefunc,dragcursor); // connect mouse function zdialog_help(zd,"revise_RGB"); // zdialog help topic v.11.08 zdialog_run(zd,RGBR_event,"save"); // run dialog zdialog_wait(zd); // wait for completion if (RGBRrestart) goto restart; // restart dialog return; } // dialog event function int RGBR_event(zdialog *zd, cchar *event) { int button; int ii, jj; char text[8]; double val1, val3; if (zd->zstat) { if (zd->zstat == 1) { // Reset zd->zstat = 0; // keep dialog active RGBRnpix = 0; // no pixels selected yet RGBR_stuff(); // clear dialog edit_reset(); // reset edits v.11.08 return 0; } else if (zd->zstat == 2) // Done edit_done(EFrgbrevise); else edit_cancel(EFrgbrevise); // Cancel or [x] freeMouse(); // disconnect mouse function zdialog_free(zd); // kill dialog RGBRzd = 0; RGBRrestart = 0; erase_toptext(101); // erase pixel labels from image return 1; } if (strEqu(event,"focus")) // toggle mouse capture takeMouse(zd,RGBR_mousefunc,dragcursor); // connect mouse function if (strEqu(event,"blend")) { // new blend factor zdialog_fetch(zd,"blend",RGBRblend); sprintf(text,"%d",RGBRblend); // numeric feedback zdialog_stuff(zd,"softval",text); signal_thread(); return 1; } if (strnEqu(event,"rad",3)) // metric was changed { if (strEqu(event,"radRGB")) { // RGB zdialog_fetch(zd,event,button); if (button) RGBRmetric = 1; } if (strEqu(event,"radEV")) { // EV zdialog_fetch(zd,event,button); if (button) RGBRmetric = 2; } if (strEqu(event,"radOD")) { // OD zdialog_fetch(zd,event,button); if (button) RGBRmetric = 3; } if (button) { freeMouse(); // restart dialog with new limits zdialog_free(zd); RGBRzd = 0; RGBRrestart = 1; } return 1; } if (strEqu(event,"delta")) { // change absolute/delta mode zdialog_fetch(zd,"delta",RGBRdelta); freeMouse(); // restart dialog with new limits zdialog_free(zd); RGBRzd = 0; RGBRrestart = 1; return 1; } ii = -1; // no RGB change yet if (strnEqu(event,"red",3)) { // red1 - red9 was changed ii = event[3] - '1'; // pixel index 0-8 jj = 0; // color = red } if (strnEqu(event,"green",5)) { // green1 - green9 ii = event[5] - '1'; jj = 1; } if (strnEqu(event,"blue",4)) { // blue1 - blue9 ii = event[4] - '1'; jj = 2; } if (ii >= 0 && ii < 9) // RGB value was revised { /* static int ignore = 0; if (ignore) { ignore = 0; return 1; } ignore = 1; */ val1 = RGBRval1[ii][jj]; // original pixel RGB value if (RGBRmetric == 2) val1 = RGB2EV(val1); // convert to EV or OD units if (RGBRmetric == 3) val1 = RGB2OD(val1); zdialog_fetch(zd,event,val3); // revised RGB/EV/OD value from dialog if (RGBRdelta) val3 += val1; // if delta mode, make absolute if (RGBRmetric == 2) val3 = EV2RGB(val3); // convert EV/OD to RGB value if (RGBRmetric == 3) val3 = OD2RGB(val3); if (fabs(RGBRval3[ii][jj] - val3) < 0.001) return 1; // ignore re-entry after change if (val3 < 0.1) val3 = 0.1; // limit RGB within 0.1 to 255.9 if (val3 > 255.9) val3 = 255.9; RGBRval3[ii][jj] = val3; // new RGB value for pixel if (RGBRmetric == 2) val3 = RGB2EV(val3); // convert RGB to EV/OD units if (RGBRmetric == 3) val3 = RGB2OD(val3); if (RGBRdelta) val3 -= val1; // absolute back to relative zdialog_stuff(zd,event,val3); // limited value back to dialog signal_thread(); // signal thread to update image } return 1; } // mouse function void RGBR_mousefunc() // mouse function { int ii; uint16 *pix3; if (! LMclick) return; LMclick = RMclick = 0; RGBRtime = get_seconds(); // mark time of pixel click if (RGBRnpix == 9) { // if table is full (9 entries) v.11.08 for (ii = 1; ii < 9; ii++) { // move positions 1-8 up RGBRpixel[ii-1][0] = RGBRpixel[ii][0]; // to fill positions 0-7 RGBRpixel[ii-1][1] = RGBRpixel[ii][1]; } RGBRnpix = 8; // count is now 8 entries } ii = RGBRnpix; // next table position to fill RGBRpixel[ii][0] = Mxclick; // newest pixel RGBRpixel[ii][1] = Myclick; pix3 = PXMpix(E3pxm16,Mxclick,Myclick); // get initial RGB values from RGBRval1[ii][0] = RGBRval3[ii][0] = pix3[0] / 256.0; // modified image E3 RGBRval1[ii][1] = RGBRval3[ii][1] = pix3[1] / 256.0; RGBRval1[ii][2] = RGBRval3[ii][2] = pix3[2] / 256.0; RGBRnpix++; // up pixel count RGBR_stuff(); // stuff pixels and values into dialog return; } // stuff dialog with current pixels and their RGB/EV/OD values void RGBR_stuff() { static char lab1[9][4] = { "A", "B", "C", "D", "E", "F", "G", "H", "I" }; static char lab2[9][4] = { " A ", " B ", " C ", " D ", " E ", " F ", " G ", " H ", " I " }; int px, py; double red1, green1, blue1, red3, green3, blue3; char text[100], pixx[8] = "pixx"; char redx[8] = "redx", greenx[8] = "greenx", bluex[8] = "bluex"; zdialog *zd = RGBRzd; erase_toptext(101); // erase prior labels from image for (int ii = 0; ii < 9; ii++) // loop slots 0-8 { pixx[3] = '1' + ii; // widget names "pix1" ... "pix9" redx[3] = '1' + ii; // widget names "red1" ... "red9" greenx[5] = '1' + ii; bluex[4] = '1' + ii; px = RGBRpixel[ii][0]; // next pixel to report py = RGBRpixel[ii][1]; if (ii >= RGBRnpix) { // > last pixel selected zdialog_stuff(zd,pixx,""); zdialog_stuff(zd,redx,0); // blank pixel and zero values zdialog_stuff(zd,greenx,0); zdialog_stuff(zd,bluex,0); continue; } sprintf(text,"%s %4d %4d",lab1[ii],px,py); // format pixel "A nnnn nnnn" zdialog_stuff(zd,pixx,text); // pixel >> widget add_toptext(101,px,py,lab2[ii],"Sans 8"); // paint label on image at pixel red1 = RGBRval1[ii][0]; // original RGB values for pixel green1 = RGBRval1[ii][1]; blue1 = RGBRval1[ii][2]; red3 = RGBRval3[ii][0]; // revised RGB values green3 = RGBRval3[ii][1]; blue3 = RGBRval3[ii][2]; if (RGBRmetric == 2) { // convert to EV units if needed red1 = RGB2EV(red1); green1 = RGB2EV(green1); blue1 = RGB2EV(blue1); red3 = RGB2EV(red3); green3 = RGB2EV(green3); blue3 = RGB2EV(blue3); } if (RGBRmetric == 3) { // or OD units red1 = RGB2OD(red1); green1 = RGB2OD(green1); blue1 = RGB2OD(blue1); red3 = RGB2OD(red3); green3 = RGB2OD(green3); blue3 = RGB2OD(blue3); } if (RGBRdelta) { // dialog is delta mode red3 -= red1; green3 -= green1; blue3 -= blue1; } zdialog_stuff(zd,redx,red3); zdialog_stuff(zd,greenx,green3); zdialog_stuff(zd,bluex,blue3); } mwpaint2(); // refresh window return; } // thread function - multiple working threads to update image void * RGBR_thread(void *) { void * RGBR_wthread(void *arg); // worker thread while (true) { thread_idle_loop(); // wait for work or exit request zsleep(0.3); // more time for dialog controls if (RGBRnpix < 1) continue; // must have 1+ pixels in table for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(RGBR_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion CEF->Fmod = 1; // image modified mwpaint2(); // update window } return 0; // not executed, stop warning } void * RGBR_wthread(void *arg) // worker thread function { int index = *((int *) (arg)); int px1, py1, px2, py2, ii; uint16 *pix1, *pix3; double dist[9], weight[9], sumdist; double blend, delta, red, green, blue, max; blend = Fww; if (Fhh > Fww) blend = Fhh; blend = blend * blend; blend = 0.0001 * RGBRblend * RGBRblend * blend + 100; // 100 to (image size)**2 v.11.08 for (py1 = index; py1 < E3hh; py1 += Nwt) // loop all image pixels for (px1 = 0; px1 < E3ww; px1++) { for (sumdist = ii = 0; ii < RGBRnpix; ii++) // compute weight of each revision point { px2 = RGBRpixel[ii][0]; py2 = RGBRpixel[ii][1]; dist[ii] = (px1-px2)*(px1-px2) + (py1-py2)*(py1-py2); // distance (px1,py1) to (px2,py2) dist[ii] = 1.0 / (dist[ii] + blend); // blend reduces peaks at revision points sumdist += dist[ii]; // sum inverse distances } for (ii = 0; ii < RGBRnpix; ii++) // weight of each point weight[ii] = dist[ii] / sumdist; pix1 = PXMpix(E1pxm16,px1,py1); // input pixel pix3 = PXMpix(E3pxm16,px1,py1); // output pixel red = pix1[0]; green = pix1[1]; blue = pix1[2]; for (ii = 0; ii < RGBRnpix; ii++) { // apply weighted color changes delta = RGBRval3[ii][0] - RGBRval1[ii][0]; // to each color red += weight[ii] * 256 * delta; delta = RGBRval3[ii][1] - RGBRval1[ii][1]; green += weight[ii] * 256 * delta; delta = RGBRval3[ii][2] - RGBRval1[ii][2]; blue += weight[ii] * 256 * delta; } max = red; if (green > max) max = green; if (blue > max) max = blue; if (max > 65535) { // stop overflow/underflow red = red * 65535 / max; green = green * 65535 / max; blue = blue * 65535 / max; } if (red < 0) red = 0; if (green < 0) green = 0; if (blue < 0) blue = 0; pix3[0] = red; pix3[1] = green; pix3[2] = blue; } exit_wthread(); return 0; // not executed, avoid gcc warning } /**************************************************************************/ // red eye removal function struct sredmem { // red-eye struct in memory char type, space[3]; int cx, cy, ww, hh, rad, clicks; double thresh, tstep; }; sredmem redmem[100]; // store up to 100 red-eyes int Nredmem = 0, maxredmem = 100; void redeye_mousefunc(); editfunc EFredeye; void m_redeye(GtkWidget *, cchar *) { int redeye_dialog_event(zdialog *zd, cchar *event); cchar *redeye_message = ZTX( "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye."); zfuncs::F1_help_topic = "red_eye"; // v.10.8 EFredeye.funcname = "redeye"; EFredeye.Farea = 1; // select area ignored EFredeye.mousefunc = redeye_mousefunc; if (! edit_setup(EFredeye)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Red Eye Reduction"),mWin,Bdone,Bcancel,null); EFredeye.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",redeye_message); zdialog_help(zd,"red_eye"); // zdialog help topic v.11.08 zdialog_run(zd,redeye_dialog_event,"save"); // run dialog - parallel v.11.07 Nredmem = 0; takeMouse(zd,redeye_mousefunc,dragcursor); // connect mouse function v.11.03 return; } // dialog event and completion callback function int redeye_dialog_event(zdialog *zd, cchar *event) { if (zd->zstat) { if (Nredmem > 0) CEF->Fmod = 1; Ftoparc = ptoparc = 0; if (zd->zstat == 1) edit_done(EFredeye); else edit_cancel(EFredeye); return 0; } if (strEqu(event,"focus")) // toggle mouse capture v.10.12 takeMouse(zd,redeye_mousefunc,dragcursor); // connect mouse function return 0; } // mouse functions to define, darken, and undo red-eyes int redeye_createF(int px, int py); // create 1-click red-eye (type F) int redeye_createR(int px, int py, int ww, int hh); // create robust red-eye (type R) void redeye_darken(int ii); // darken red-eye void redeye_distr(int ii); // build pixel redness distribution int redeye_find(int px, int py); // find red-eye at mouse position void redeye_remove(int ii); // remove red-eye at mouse position int redeye_radlim(int cx, int cy); // compute red-eye radius limit void redeye_mousefunc() { int ii, px, py, ww, hh; if (Nredmem == maxredmem) { zmessageACK(mWin,"%d red-eye limit reached",maxredmem); // too many red-eyes return; } if (LMclick) // left mouse click { LMclick = 0; px = Mxclick; // click position py = Myclick; if (px < 0 || px > E3ww-1 || py < 0 || py > E3hh-1) return; // outside image area ii = redeye_find(px,py); // find existing red-eye if (ii < 0) ii = redeye_createF(px,py); // or create new type F redeye_darken(ii); // darken red-eye } if (RMclick) // right mouse click { RMclick = 0; px = Mxclick; // click position py = Myclick; ii = redeye_find(px,py); // find red-eye if (ii >= 0) redeye_remove(ii); // if found, remove } if (Mxdrag || Mydrag) // mouse drag underway { px = Mxdown; // initial position py = Mydown; ww = Mxdrag - Mxdown; // increment hh = Mydrag - Mydown; if (ww < 2 && hh < 2) return; if (ww < 2) ww = 2; if (hh < 2) hh = 2; if (px < 1) px = 1; // keep within image area if (py < 1) py = 1; if (px + ww > E3ww-1) ww = E3ww-1 - px; if (py + hh > E3hh-1) hh = E3hh-1 - py; ii = redeye_find(px,py); // find existing red-eye if (ii >= 0) redeye_remove(ii); // remove it ii = redeye_createR(px,py,ww,hh); // create new red-eye type R } mwpaint2(); return; } // create type F redeye (1-click automatic) int redeye_createF(int cx, int cy) { int cx0, cy0, cx1, cy1, px, py, rad, radlim; int loops, ii; int Tnpix, Rnpix, R2npix; double rd, rcx, rcy, redpart; double Tsum, Rsum, R2sum, Tavg, Ravg, R2avg; double sumx, sumy, sumr; uint16 *ppix; cx0 = cx; cy0 = cy; for (loops = 0; loops < 8; loops++) { cx1 = cx; cy1 = cy; radlim = redeye_radlim(cx,cy); // radius limit (image edge) Tsum = Tavg = Ravg = Tnpix = 0; for (rad = 0; rad < radlim-2; rad++) // find red-eye radius from (cx,cy) { Rsum = Rnpix = 0; R2sum = R2npix = 0; for (py = cy-rad-2; py <= cy+rad+2; py++) for (px = cx-rad-2; px <= cx+rad+2; px++) { rd = sqrt((px-cx)*(px-cx) + (py-cy)*(py-cy)); ppix = PXMpix(E3pxm16,px,py); redpart = pixred(ppix); if (rd <= rad + 0.5 && rd > rad - 0.5) { // accum. redness at rad Rsum += redpart; Rnpix++; } else if (rd <= rad + 2.5 && rd > rad + 1.5) { // accum. redness at rad+2 R2sum += redpart; R2npix++; } } Tsum += Rsum; Tnpix += Rnpix; Tavg = Tsum / Tnpix; // avg. redness over 0-rad Ravg = Rsum / Rnpix; // avg. redness at rad R2avg = R2sum / R2npix; // avg. redness at rad+2 if (R2avg > Ravg || Ravg > Tavg) continue; if ((Ravg - R2avg) < 0.2 * (Tavg - Ravg)) break; // 0.1 --> 0.2 } sumx = sumy = sumr = 0; rad = int(1.2 * rad + 1); if (rad > radlim) rad = radlim; for (py = cy-rad; py <= cy+rad; py++) // compute center of gravity for for (px = cx-rad; px <= cx+rad; px++) // pixels within rad of (cx,cy) { rd = sqrt((px-cx)*(px-cx) + (py-cy)*(py-cy)); if (rd > rad + 0.5) continue; ppix = PXMpix(E3pxm16,px,py); redpart = pixred(ppix); // weight by redness sumx += redpart * (px - cx); sumy += redpart * (py - cy); sumr += redpart; } rcx = cx + 1.0 * sumx / sumr; // new center of red-eye rcy = cy + 1.0 * sumy / sumr; if (fabs(cx0 - rcx) > 0.6 * rad) break; // give up if big movement if (fabs(cy0 - rcy) > 0.6 * rad) break; cx = int(rcx + 0.5); cy = int(rcy + 0.5); if (cx == cx1 && cy == cy1) break; // done if no change } radlim = redeye_radlim(cx,cy); if (rad > radlim) rad = radlim; ii = Nredmem++; // add red-eye to memory redmem[ii].type = 'F'; redmem[ii].cx = cx; redmem[ii].cy = cy; redmem[ii].rad = rad; redmem[ii].clicks = 0; redmem[ii].thresh = 0; return ii; } // create type R red-eye (drag an ellipse over red-eye area) int redeye_createR(int cx, int cy, int ww, int hh) { int rad, radlim; Ftoparc = 1; // paint ellipse over image toparcx = cx - ww; toparcy = cy - hh; toparcw = 2 * ww; toparch = 2 * hh; if (ww > hh) rad = ww; else rad = hh; radlim = redeye_radlim(cx,cy); if (rad > radlim) rad = radlim; int ii = Nredmem++; // add red-eye to memory redmem[ii].type = 'R'; redmem[ii].cx = cx; redmem[ii].cy = cy; redmem[ii].ww = 2 * ww; redmem[ii].hh = 2 * hh; redmem[ii].rad = rad; redmem[ii].clicks = 0; redmem[ii].thresh = 0; return ii; } // darken a red-eye and increase click count void redeye_darken(int ii) { int cx, cy, ww, hh, px, py, rad, clicks; double rd, thresh, tstep; char type; uint16 *ppix; type = redmem[ii].type; cx = redmem[ii].cx; cy = redmem[ii].cy; ww = redmem[ii].ww; hh = redmem[ii].hh; rad = redmem[ii].rad; thresh = redmem[ii].thresh; tstep = redmem[ii].tstep; clicks = redmem[ii].clicks++; if (thresh == 0) // 1st click { redeye_distr(ii); // get pixel redness distribution thresh = redmem[ii].thresh; // initial redness threshhold tstep = redmem[ii].tstep; // redness step size Ftoparc = 0; } tstep = (thresh - tstep) / thresh; // convert to reduction factor thresh = thresh * pow(tstep,clicks); // reduce threshhold by total clicks for (py = cy-rad; py <= cy+rad; py++) // darken pixels over threshhold for (px = cx-rad; px <= cx+rad; px++) { if (type == 'R') { if (px < cx - ww/2) continue; if (px > cx + ww/2) continue; if (py < cy - hh/2) continue; if (py > cy + hh/2) continue; } rd = sqrt((px-cx)*(px-cx) + (py-cy)*(py-cy)); if (rd > rad + 0.5) continue; ppix = PXMpix(E3pxm16,px,py); // set redness = threshhold if (pixred(ppix) > thresh) ppix[0] = int(thresh * (0.65 * ppix[1] + 0.10 * ppix[2] + 1) / (25 - 0.25 * thresh)); } return; } // Build a distribution of redness for a red-eye. Use this information // to set initial threshhold and step size for stepwise darkening. void redeye_distr(int ii) { int cx, cy, ww, hh, rad, px, py; int bin, npix, dbins[20], bsum, blim; double rd, maxred, minred, redpart, dbase, dstep; char type; uint16 *ppix; type = redmem[ii].type; cx = redmem[ii].cx; cy = redmem[ii].cy; ww = redmem[ii].ww; hh = redmem[ii].hh; rad = redmem[ii].rad; maxred = 0; minred = 100; for (py = cy-rad; py <= cy+rad; py++) for (px = cx-rad; px <= cx+rad; px++) { if (type == 'R') { if (px < cx - ww/2) continue; if (px > cx + ww/2) continue; if (py < cy - hh/2) continue; if (py > cy + hh/2) continue; } rd = sqrt((px-cx)*(px-cx) + (py-cy)*(py-cy)); if (rd > rad + 0.5) continue; ppix = PXMpix(E3pxm16,px,py); redpart = pixred(ppix); if (redpart > maxred) maxred = redpart; if (redpart < minred) minred = redpart; } dbase = minred; dstep = (maxred - minred) / 19.99; for (bin = 0; bin < 20; bin++) dbins[bin] = 0; npix = 0; for (py = cy-rad; py <= cy+rad; py++) for (px = cx-rad; px <= cx+rad; px++) { if (type == 'R') { if (px < cx - ww/2) continue; if (px > cx + ww/2) continue; if (py < cy - hh/2) continue; if (py > cy + hh/2) continue; } rd = sqrt((px-cx)*(px-cx) + (py-cy)*(py-cy)); if (rd > rad + 0.5) continue; ppix = PXMpix(E3pxm16,px,py); redpart = pixred(ppix); bin = int((redpart - dbase) / dstep); ++dbins[bin]; ++npix; } bsum = 0; blim = int(0.5 * npix); for (bin = 0; bin < 20; bin++) // find redness level for 50% of { // pixels within red-eye radius bsum += dbins[bin]; if (bsum > blim) break; } redmem[ii].thresh = dbase + dstep * bin; // initial redness threshhold redmem[ii].tstep = dstep; // redness step (5% of range) return; } // find a red-eye (nearly) overlapping the mouse click position int redeye_find(int cx, int cy) { for (int ii = 0; ii < Nredmem; ii++) { if (cx > redmem[ii].cx - 2 * redmem[ii].rad && cx < redmem[ii].cx + 2 * redmem[ii].rad && cy > redmem[ii].cy - 2 * redmem[ii].rad && cy < redmem[ii].cy + 2 * redmem[ii].rad) return ii; // found } return -1; // not found } // remove a red-eye from memory void redeye_remove(int ii) { int cx, cy, rad, px, py; uint16 *pix1, *pix3; cx = redmem[ii].cx; cy = redmem[ii].cy; rad = redmem[ii].rad; for (px = cx-rad; px <= cx+rad; px++) for (py = cy-rad; py <= cy+rad; py++) { pix1 = PXMpix(E1pxm16,px,py); pix3 = PXMpix(E3pxm16,px,py); pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } for (ii++; ii < Nredmem; ii++) redmem[ii-1] = redmem[ii]; Nredmem--; Ftoparc = 0; return; } // compute red-eye radius limit: smaller of 100 and nearest image edge int redeye_radlim(int cx, int cy) { int radlim = 100; if (cx < 100) radlim = cx; if (E3ww-1 - cx < 100) radlim = E3ww-1 - cx; if (cy < 100) radlim = cy; if (E3hh-1 - cy < 100) radlim = E3hh-1 - cy; return radlim; } /**************************************************************************/ // image blur function // radius steps of 0.5 v.9.2 double blur_radius; double blur_weight[101][101]; // up to blur radius = 99 v.9.2 int blur_Npixels, blur_pixdone; int blur_cancel; editfunc EFblur; void m_blur(GtkWidget *, cchar *) { int blur_dialog_event(zdialog *zd, cchar *event); void * blur_thread(void *); zfuncs::F1_help_topic = "blur"; // v.10.8 EFblur.funcname = "blur"; EFblur.Farea = 2; // select area usable EFblur.threadfunc = blur_thread; // thread function if (! edit_setup(EFblur)) return; // setup edit blur_radius = 0.5; blur_cancel = 0; zdialog *zd = zdialog_new(ZTX("Set Blur Radius"),mWin,Bdone,Bcancel,null); EFblur.zd = zd; zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=10"); zdialog_add_widget(zd,"label","labrad","hb2",Bradius,"space=5"); zdialog_add_widget(zd,"spin","radius","hb2","0|99|0.5|0.5","space=5"); zdialog_add_widget(zd,"button","apply","hb2",Bapply,"space=5"); zdialog_help(zd,"blur"); // zdialog help topic v.11.08 zdialog_run(zd,blur_dialog_event,"save"); // run dialog - parallel v.11.07 return; } // dialog event and completion callback function int blur_dialog_event(zdialog * zd, cchar *event) { if (zd->zstat) { if (zd->zstat == 1) edit_done(EFblur); // done else { blur_cancel = 1; // v.11.09 edit_cancel(EFblur); // cancel or destroy } return 1; } if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strEqu(event,"apply")) { zdialog_fetch(zd,"radius",blur_radius); // get blur radius if (blur_radius == 0) edit_reset(); else signal_thread(); // trigger working thread } return 1; } // image blur thread function void * blur_thread(void *) { void * blur_wthread(void *arg); int dx, dy; double rad, rad2; double m, d, w, sum; while (true) { thread_idle_loop(); // wait for work or exit request rad = blur_radius - 0.2; // v.9.2 rad2 = rad * rad; for (dx = 0; dx <= rad+1; dx++) // clear weights array for (dy = 0; dy <= rad+1; dy++) blur_weight[dx][dy] = 0; for (dx = -rad-1; dx <= rad+1; dx++) // blur_weight[dx][dy] = no. of pixels for (dy = -rad-1; dy <= rad+1; dy++) // at distance (dx,dy) from center ++blur_weight[abs(dx)][abs(dy)]; m = sqrt(rad2 + rad2); // corner pixel distance from center sum = 0; for (dx = 0; dx <= rad+1; dx++) // compute weight of pixel for (dy = 0; dy <= rad+1; dy++) // at distance dx, dy { d = sqrt(dx*dx + dy*dy); w = (m + 1.2 - d) / m; // v.9.2 w = w * w; sum += blur_weight[dx][dy] * w; blur_weight[dx][dy] = w; } for (dx = 0; dx <= rad+1; dx++) // make weights add up to 1.0 for (dy = 0; dy <= rad+1; dy++) blur_weight[dx][dy] = blur_weight[dx][dy] / sum; if (Factivearea) SB_goal = sa_Npixel; else SB_goal = E3ww * E3hh; SB_done = 0; // v.11.06 for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(blur_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion SB_goal = 0; CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * blur_wthread(void *arg) // worker thread function { int index = *((int *) arg); int px, py, ii, dist = 0; int jj, dx, dy, adx, ady, rad; double red, green, blue; double weight1, weight2, f1, f2; uint16 *pix1, *pix3, *pixN; for (py = index; py < E3hh-1; py += Nwt) // loop all image pixels for (px = 0; px < E3ww-1; px++) { if (blur_cancel) exit_wthread(); // v.11.09 if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // outside pixel } pix1 = PXMpix(E1pxm16,px,py); // source pixel pix3 = PXMpix(E3pxm16,px,py); // target pixel rad = blur_radius; red = green = blue = 0; weight2 = 0.0; if (Factivearea) // select area active { for (dy = -rad-1; dy <= rad+1; dy++) // loop neighbor pixels within radius for (dx = -rad-1; dx <= rad+1; dx++) { if (px+dx < 0 || px+dx > E3ww-1) continue; // omit pixels off edge if (py+dy < 0 || py+dy > E3hh-1) continue; jj = (py+dy) * E3ww + (px+dx); if (! sa_pixmap[jj]) continue; // omit pixels outside area adx = abs(dx); ady = abs(dy); pixN = pix1 + (dy * E3ww + dx) * 3; weight1 = blur_weight[adx][ady]; // weight at distance (dx,dy) weight2 += weight1; red += pixN[0] * weight1; // accumulate contributions green += pixN[1] * weight1; blue += pixN[2] * weight1; } red = red / weight2; // weighted average green = green / weight2; blue = blue / weight2; if (dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; red = f1 * red + f2 * pix1[0]; green = f1 * green + f2 * pix1[1]; blue = f1 * blue + f2 * pix1[2]; } pix3[0] = int(red); pix3[1] = int(green); pix3[2] = int(blue); } else { for (dy = -rad-1; dy <= rad+1; dy++) // loop neighbor pixels within radius for (dx = -rad-1; dx <= rad+1; dx++) { if (px+dx < 0 || px+dx > E3ww-1) continue; // omit pixels off edge if (py+dy < 0 || py+dy > E3hh-1) continue; adx = abs(dx); ady = abs(dy); pixN = pix1 + (dy * E3ww + dx) * 3; weight1 = blur_weight[adx][ady]; // weight at distance (dx,dy) weight2 += weight1; red += pixN[0] * weight1; // accumulate contributions green += pixN[1] * weight1; blue += pixN[2] * weight1; } red = red / weight2; // weighted average green = green / weight2; blue = blue / weight2; pix3[0] = red; pix3[1] = green; pix3[2] = blue; } SB_done++; // track progress v.10.6 } exit_wthread(); return 0; // not executed, avoid gcc warning } /**************************************************************************/ // image sharpening function int sharp_ED_cycles; int sharp_ED_reduce; int sharp_ED_thresh; int sharp_UM_radius; int sharp_UM_amount; int sharp_UM_thresh; int sharp_UM_Fcalc; int sharp_GR_amount; int sharp_GR_thresh; char sharp_function[4]; editfunc EFsharp; void m_sharpen(GtkWidget *, cchar *) { int sharp_dialog_event(zdialog *zd, cchar *event); void * sharp_thread(void *); zfuncs::F1_help_topic = "sharpen"; // v.10.8 EFsharp.funcname = "sharpen"; EFsharp.Farea = 2; // select area usable EFsharp.threadfunc = sharp_thread; // thread function if (! edit_setup(EFsharp)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Sharpen Image"),mWin,Bdone,Bcancel,null); EFsharp.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vb11","hb1",0,"space=5"); zdialog_add_widget(zd,"vbox","vb12","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb13","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"button","ED","vb11",ZTX("edge detection"),"space=5"); zdialog_add_widget(zd,"label","lab11","vb12",ZTX("cycles")); zdialog_add_widget(zd,"label","lab12","vb12",ZTX("reduce")); zdialog_add_widget(zd,"label","lab13","vb12",Bthresh); zdialog_add_widget(zd,"spin","cyclesED","vb13","1|30|1|10"); zdialog_add_widget(zd,"spin","reduceED","vb13","50|95|1|80"); zdialog_add_widget(zd,"spin","threshED","vb13","1|99|1|1"); zdialog_add_widget(zd,"hsep","sep2","dialog"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vb21","hb2",0,"space=5"); zdialog_add_widget(zd,"vbox","vb22","hb2",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb23","hb2",0,"homog|space=5"); zdialog_add_widget(zd,"button","UM","vb21",ZTX("unsharp mask"),"space=5"); zdialog_add_widget(zd,"label","lab21","vb22",Bradius); zdialog_add_widget(zd,"label","lab22","vb22",Bamount); zdialog_add_widget(zd,"label","lab23","vb22",Bthresh); zdialog_add_widget(zd,"spin","radiusUM","vb23","1|20|1|2"); zdialog_add_widget(zd,"spin","amountUM","vb23","0|200|1|100"); zdialog_add_widget(zd,"spin","threshUM","vb23","0|100|1|0"); zdialog_add_widget(zd,"hsep","sep3","dialog"); zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vb31","hb3",0,"space=5"); zdialog_add_widget(zd,"vbox","vb32","hb3",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb33","hb3",0,"homog|space=5"); zdialog_add_widget(zd,"button","GR","vb31",ZTX("brightness gradient"),"space=5"); zdialog_add_widget(zd,"label","lab32","vb32",Bamount); zdialog_add_widget(zd,"label","lab33","vb32",Bthresh); zdialog_add_widget(zd,"spin","amountGR","vb33","0|400|1|100"); zdialog_add_widget(zd,"spin","threshGR","vb33","0|100|1|0"); zdialog_help(zd,"sharpen"); // zdialog help topic v.11.08 zdialog_run(zd,sharp_dialog_event,"save"); // run dialog - parallel v.11.07 *sharp_function = 0; sharp_UM_Fcalc = 1; return; } // dialog event and completion callback function int sharp_dialog_event(zdialog *zd, cchar *event) { if (zd->zstat) { if (zd->zstat == 1) edit_done(EFsharp); else edit_cancel(EFsharp); return 0; } if (strEqu(event,"blendwidth")) signal_thread(); // v.10.3 if (strEqu(event,"radiusUM")) sharp_UM_Fcalc = 1; // must recalculate if (strcmpv(event,"ED","UM","GR",null)) { edit_reset(); // restore original image zdialog_fetch(zd,"cyclesED",sharp_ED_cycles); // get all input values zdialog_fetch(zd,"reduceED",sharp_ED_reduce); zdialog_fetch(zd,"threshED",sharp_ED_thresh); zdialog_fetch(zd,"radiusUM",sharp_UM_radius); zdialog_fetch(zd,"amountUM",sharp_UM_amount); zdialog_fetch(zd,"threshUM",sharp_UM_thresh); zdialog_fetch(zd,"amountGR",sharp_GR_amount); zdialog_fetch(zd,"threshGR",sharp_GR_thresh); strcpy(sharp_function,event); // pass to working thread signal_thread(); } return 0; } // sharpen image thread function void * sharp_thread(void *) { int sharp_ED(); int sharp_UM(); int sharp_GR(); while (true) { thread_idle_loop(); // wait for work or exit request if (strEqu(sharp_function,"ED")) sharp_ED(); // do requested function if (strEqu(sharp_function,"UM")) sharp_UM(); if (strEqu(sharp_function,"GR")) sharp_GR(); CEF->Fmod = 1; mwpaint2(); } return 0; // not executed, stop g++ warning } // image sharpen function by edge detection and compression int sharp_ED() { void sharp_pixel_ED(int px, int py, int thresh); int sharp_thresh1 = 100; // initial threshold double sharp_thresh2 = 0.01 * sharp_ED_reduce; // decline rate int px, py, thresh, cycles; thresh = sharp_thresh1; if (Factivearea) SB_goal = sa_Npixel; // v.9.6 else SB_goal = E3ww * E3hh; SB_goal *= sharp_ED_cycles; SB_done = 0; // v.11.06 for (cycles = 0; cycles < sharp_ED_cycles; cycles++) { if (cycles > 0) thresh = int(thresh * sharp_thresh2); for (py = 2; py < E3hh-2; py++) for (px = 2; px < E3ww-2; px++) // loop all pixels { sharp_pixel_ED(px,py,thresh); SB_done++; // track progress v.10.6 } } SB_goal = 0; return 1; } void sharp_pixel_ED(int px, int py, int thresh) { uint16 *pix1, *pix1u, *pix1d; uint16 *pix3, *pix3u, *pix3d, *pix3uu, *pix3dd; int ii, dist = 0; int dd, rgb, pthresh; int dx[4] = { -1, 0, 1, 1 }; // 4 directions: NW N NE E int dy[4] = { -1, -1, -1, 0 }; int pv2, pv2u, pv2d, pv2uu, pv2dd, pvdiff; double f1, f2; if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) return; // outside pixel } pthresh = sharp_ED_thresh; // pthresh = larger if (thresh > pthresh) pthresh = thresh; pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel for (dd = 0; dd < 4; dd++) // 4 directions { pix3u = pix3 + (dy[dd] * E3ww + dx[dd]) * 3; // upstream pixel pix3d = pix3 - (dy[dd] * E3ww - dx[dd]) * 3; // downstream pixel for (rgb = 0; rgb < 3; rgb++) // loop 3 RGB colors { pv2 = pix3[rgb]; pv2u = pix3u[rgb]; // brightness difference pv2d = pix3d[rgb]; // across target pixel pvdiff = pv2d - pv2u; if (pvdiff < 0) pvdiff = -pvdiff; if (pvdiff < 256 * pthresh) continue; // brightness slope < threshold if (pv2u < pv2 && pv2 < pv2d) // slope up, monotone { pix3uu = pix3u + (dy[dd] * E3ww + dx[dd]) * 3; // upstream of upstream pixel pix3dd = pix3d - (dy[dd] * E3ww - dx[dd]) * 3; // downstream of downstream pv2uu = pix3uu[rgb]; pv2dd = pix3dd[rgb]; if (pv2uu >= pv2u) { // shift focus of changes to pix3u = pix3; // avoid up/down/up jaggies pv2u = pv2; } if (pv2dd <= pv2d) { pix3d = pix3; pv2d = pv2; } if (pv2u > 256) pv2u -= 256; if (pv2d < 65279) pv2d += 256; } else if (pv2u > pv2 && pv2 > pv2d) // slope down, monotone { pix3uu = pix3u + (dy[dd] * E3ww + dx[dd]) * 3; pix3dd = pix3d - (dy[dd] * E3ww - dx[dd]) * 3; pv2uu = pix3uu[rgb]; pv2dd = pix3dd[rgb]; if (pv2uu <= pv2u) { pix3u = pix3; pv2u = pv2; } if (pv2dd >= pv2d) { pix3d = pix3; pv2d = pv2; } if (pv2d > 256) pv2d -= 256; if (pv2u < 65279) pv2u += 256; } else continue; // slope too small if (Factivearea && dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; pix1u = pix1 + (dy[dd] * E1ww + dx[dd]) * 3; // upstream input pixel pix1d = pix1 - (dy[dd] * E1ww - dx[dd]) * 3; // downstream input pixel pv2u = int(f1 * pv2u + f2 * pix1u[rgb]); pv2d = int(f1 * pv2d + f2 * pix1d[rgb]); } pix3u[rgb] = pv2u; // modified brightness values pix3d[rgb] = pv2d; // >> image3 pixel } } return; } // image sharpen function using unsharp mask int sharp_UM() { void * sharp_UM_wthread(void *arg); int ii; if (sharp_UM_Fcalc) { // speedup v.9.6 sharp_UM_Fcalc = 0; brhood_calc(sharp_UM_radius,'f'); } if (Factivearea) SB_goal = sa_Npixel; // v.9.6 else SB_goal = E3ww * E3hh; SB_done = 0; // v.11.06 for (ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(sharp_UM_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion SB_goal = 0; return 1; } void * sharp_UM_wthread(void *arg) // worker thread function { void sharp_pixel_UM(int px, int py, int index); int index = *((int *) arg); int px, py; for (py = index; py < E3hh; py += Nwt) // loop all image3 pixels for (px = 0; px < E3ww; px++) sharp_pixel_UM(px,py,index); exit_wthread(); return 0; // not executed, avoid gcc warning } void sharp_pixel_UM(int px, int py, int index) // process one pixel { // revised v.9.6 int ii, dist = 0; double amount, thresh, bright; double mean, incr, ratio, f1, f2; double red1, green1, blue1, red3, green3, blue3; uint16 *pix1, *pix3; if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) return; // outside pixel } amount = 0.01 * sharp_UM_amount; // 0.0 to 2.0 thresh = 100 * sharp_UM_thresh; // 0 to 10K (64K max. possible) pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel bright = pixbright(pix1); if (bright < 100) return; // effectively black mean = get_brhood(px,py); incr = (bright - mean); if (fabs(incr) < thresh) return; // omit low-contrast pixels incr = incr * amount; // 0.0 to 2.0 if (bright + incr > 65535) incr = 65535 - bright; ratio = (bright + incr) / bright; if (ratio < 0) ratio = 0; // v.11.08 red1 = pix1[0]; // input RGB green1 = pix1[1]; blue1 = pix1[2]; red3 = ratio * red1; // output RGB if (red3 > 65535) red3 = 65535; green3 = ratio * green1; if (green3 > 65535) green3 = 65535; blue3 = ratio * blue1; if (blue3 > 65535) blue3 = 65535; if (Factivearea && dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; red3 = f1 * red3 + f2 * red1; green3 = f1 * green3 + f2 * green1; blue3 = f1 * blue3 + f2 * blue1; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; SB_done++; // track progress v.10.6 return; } // sharpen image by increasing brightness gradient // new v.9.8 int sharp_GR() { uint16 *pix1, *pix3; int ii, px, py, dist = 0; double amount, thresh; double b1, b1x, b1y, b3x, b3y, b3, bf, f1, f2; double red1, green1, blue1, red3, green3, blue3; amount = 1 + 0.01 * sharp_GR_amount; // 1.0 - 5.0 thresh = 655.35 * sharp_GR_thresh; // 0 - 64K if (Factivearea) SB_goal = sa_Npixel; else SB_goal = E3ww * E3hh; SB_done = 0; // v.11.06 for (py = 1; py < E1hh; py++) // loop all image pixels for (px = 1; px < E1ww; px++) { if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // pixel is outside area } pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel b1 = pixbright(pix1); // pixel brightness, 0 - 64K b1x = b1 - pixbright(pix1 - 3); // brightness gradient (x,y) b1y = b1 - pixbright(pix1 - 3 * E1ww); if (abs(b1x + b1y) < thresh) // moderate brightness change for f1 = abs(b1x + b1y) / thresh; // pixels below threshold gradient else f1 = 1.0; // v.10.9 f2 = 1.0 - f1; b1x = b1x * amount; // amplified gradient b1y = b1y * amount; b3x = pixbright(pix1 - 3) + b1x; // + prior pixel brightness b3y = pixbright(pix1 - 3 * E3ww) + b1y; // = new brightness b3 = 0.5 * (b3x + b3y); b3 = f1 * b3 + f2 * b1; // possibly moderated v.10.9 bf = b3 / b1; // ratio of brightness change if (bf < 0) bf = 0; if (bf > 4) bf = 4; red1 = pix1[0]; // input RGB green1 = pix1[1]; blue1 = pix1[2]; red3 = bf * red1; // output RGB if (red3 > 65535) red3 = 65535; green3 = bf * green1; if (green3 > 65535) green3 = 65535; blue3 = bf * blue1; if (blue3 > 65535) blue3 = 65535; if (Factivearea && dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; red3 = f1 * red3 + f2 * red1; green3 = f1 * green3 + f2 * green1; blue3 = f1 * blue3 + f2 * blue1; } pix3[0] = red3; pix3[1] = green3; pix3[2] = blue3; SB_done++; // track progress v.10.6 } SB_goal = 0; return 1; } /**************************************************************************/ // image noise reduction int denoise_method = 5; // default algorithm int denoise_radius = 4; editfunc EFdenoise; void m_denoise(GtkWidget *, cchar *) { int denoise_dialog_event(zdialog *zd, cchar *event); // dialog event function void * denoise_thread(void *); cchar *denoise_message = ZTX(" Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over."); zfuncs::F1_help_topic = "reduce_noise"; // v.10.8 EFdenoise.funcname = "denoise"; EFdenoise.Farea = 2; // select area usable EFdenoise.threadfunc = denoise_thread; // thread function if (! edit_setup(EFdenoise)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Noise Reduction"),mWin,Bdone,Bcancel,null); EFdenoise.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",denoise_message,"space=5"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labalg","hb1",ZTX("algorithm"),"space=5"); zdialog_add_widget(zd,"combo","method","hb1",0,"space=5|expand"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labrad","hb2",Bradius,"space=5"); zdialog_add_widget(zd,"spin","radius","hb2","1|9|1|4","space=5"); zdialog_add_widget(zd,"button","reduce","hb2",Breduce,"space=5"); zdialog_cb_app(zd,"method",ZTX("flatten outliers by color (1)")); zdialog_cb_app(zd,"method",ZTX("flatten outliers by color (2)")); zdialog_cb_app(zd,"method",ZTX("set median brightness by color")); zdialog_cb_app(zd,"method",ZTX("top hat filter by color")); zdialog_stuff(zd,"method",ZTX("top hat filter by color")); // default zdialog_help(zd,"reduce_noise"); // zdialog help topic v.11.08 zdialog_run(zd,denoise_dialog_event,"save"); // run dialog - parallel v.11.07 return; } // dialog event and completion callback function int denoise_dialog_event(zdialog * zd, cchar *event) { char method[40]; if (zd->zstat) { if (zd->zstat == 1) edit_done(EFdenoise); else edit_cancel(EFdenoise); return 0; } if (strEqu(event,"blendwidth")) signal_thread(); // trigger update thread if (strEqu(event,"radius")) zdialog_fetch(zd,"radius",denoise_radius); if (strEqu(event,"method")) { zdialog_fetch(zd,"method",method,39); if (strEqu(method,"flatten outliers by color (1)")) { denoise_method = 1; denoise_radius = 1; } if (strEqu(method,"flatten outliers by color (2)")) { denoise_method = 2; denoise_radius = 3; } if (strEqu(method,"set median brightness by color")) { denoise_method = 4; denoise_radius = 2; } if (strEqu(method,"top hat filter by color")) { denoise_method = 5; denoise_radius = 4; } zdialog_stuff(zd,"radius",denoise_radius); } if (strEqu(event,"reduce")) signal_thread(); // trigger update thread return 1; } // image noise reduction thread void * denoise_thread(void *) { void * denoise_wthread(void *arg); int ii; while (true) { thread_idle_loop(); // wait for work or exit request E9pxm16 = PXM_copy(E3pxm16); // image3 is reference source // image9 will be modified if (Factivearea) SB_goal = sa_Npixel; else SB_goal = E3ww * E3hh; SB_done = 0; // v.11.06 for (ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(denoise_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion SB_goal = 0; mutex_lock(&Fpixmap_lock); PXM_free(E3pxm16); // image9 >> image3 E3pxm16 = E9pxm16; E9pxm16 = 0; mutex_unlock(&Fpixmap_lock); CEF->Fmod = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * denoise_wthread(void *arg) // worker thread function { void denoise_func1(uint16 *pix3, uint16 *pix9); void denoise_func2(uint16 *pix3, uint16 *pix9); void denoise_func4(uint16 *pix3, uint16 *pix9); void denoise_func5(uint16 *pix3, uint16 *pix9); int index = *((int *) arg); int ii, px, py, rad, dist = 0; double f1, f2; uint16 *pix1, *pix3, *pix9; rad = denoise_radius; for (py = index+rad; py < E3hh-rad; py += Nwt) // loop all image3 pixels for (px = rad; px < E3ww-rad; px++) { if (Factivearea) { // select area active ii = py * Fww + px; dist = sa_pixmap[ii]; // distance from edge if (! dist) continue; // outside pixel } pix3 = PXMpix(E3pxm16,px,py); // source pixel pix9 = PXMpix(E9pxm16,px,py); // target pixel if (denoise_method == 1) denoise_func1(pix3,pix9); if (denoise_method == 2) denoise_func2(pix3,pix9); if (denoise_method == 4) denoise_func4(pix3,pix9); if (denoise_method == 5) denoise_func5(pix3,pix9); if (Factivearea && dist < sa_blend) { // select area is active, f1 = 1.0 * dist / sa_blend; // blend changes over sa_blend f2 = 1.0 - f1; pix1 = PXMpix(E1pxm16,px,py); // source pixel pix9[0] = int(f1 * pix9[0] + f2 * pix1[0]); pix9[1] = int(f1 * pix9[1] + f2 * pix1[1]); pix9[2] = int(f1 * pix9[2] + f2 * pix1[2]); } SB_done++; // track progress v.10.6 } exit_wthread(); return 0; // not executed, avoid gcc warning } // flatten outliers within radius, by color // an outlier is the max or min value within a radius void denoise_func1(uint16 *pix3, uint16 *pix9) { int dy, dx, rad; int min0, min1, min2, max0, max1, max2; uint16 *pixN; min0 = min1 = min2 = 65535; max0 = max1 = max2 = 0; rad = denoise_radius; for (dy = -rad; dy <= rad; dy++) // loop surrounding pixels for (dx = -rad; dx <= rad; dx++) { if (dy == 0 && dx == 0) continue; // skip self pixN = pix3 + (dy * E3ww + dx) * 3; if (pixN[0] < min0) min0 = pixN[0]; // find min and max per color if (pixN[0] > max0) max0 = pixN[0]; if (pixN[1] < min1) min1 = pixN[1]; if (pixN[1] > max1) max1 = pixN[1]; if (pixN[2] < min2) min2 = pixN[2]; if (pixN[2] > max2) max2 = pixN[2]; } if (pix3[0] <= min0 && min0 < 65279) pix9[0] = min0 + 256; // if outlier, flatten a little if (pix3[0] >= max0 && max0 > 256) pix9[0] = max0 - 256; if (pix3[1] <= min1 && min1 < 65279) pix9[1] = min1 + 256; if (pix3[1] >= max1 && max1 > 256) pix9[1] = max1 - 256; if (pix3[2] <= min2 && min2 < 65279) pix9[2] = min2 + 256; if (pix3[2] >= max2 && max2 > 256) pix9[2] = max2 - 256; return; } // flatten outliers // An outlier pixel has an RGB value outside one sigma of // the mean for all pixels within a given radius of the pixel. void denoise_func2(uint16 *pix3, uint16 *pix9) { int rgb, dy, dx, rad, nn; double nn1, val, sum, sum2, mean, variance, sigma; uint16 *pixN; rad = denoise_radius; nn = (rad * 2 + 1); nn = nn * nn - 1; nn1 = 1.0 / nn; for (rgb = 0; rgb < 3; rgb++) // loop RGB color { sum = sum2 = 0; for (dy = -rad; dy <= rad; dy++) // loop surrounding pixels for (dx = -rad; dx <= rad; dx++) { if (dy == 0 && dx == 0) continue; // skip self pixN = pix3 + (dy * E3ww + dx) * 3; val = pixN[rgb]; sum += val; sum2 += val * val; } mean = nn1 * sum; variance = nn1 * (sum2 - 2.0 * mean * sum) + mean * mean; sigma = sqrt(variance); val = pix3[rgb]; if (val > mean + sigma) { // move value to mean +/- sigma val = mean + sigma; pix9[rgb] = val; } else if (val < mean - sigma) { val = mean - sigma; pix9[rgb] = val; } } return; } // use median brightness for pixels within radius void denoise_func4(uint16 *pix3, uint16 *pix9) { int dy, dx, rad; int ns, rgb, bsortN[400]; uint16 *pixN; rad = denoise_radius; for (rgb = 0; rgb < 3; rgb++) // loop all RGB colors { ns = 0; for (dy = -rad; dy <= rad; dy++) // loop surrounding pixels for (dx = -rad; dx <= rad; dx++) // get brightness values { pixN = pix3 + (dy * E3ww + dx) * 3; bsortN[ns] = pixN[rgb]; ns++; } HeapSort(bsortN,ns); pix9[rgb] = bsortN[ns/2]; // median brightness of ns pixels } return; } // modified top hat filter: execute with increasing radius from 1 to limit // detect outlier by comparing with pixels in outer radius void denoise_func5(uint16 *pix3, uint16 *pix9) { int dy, dx, rad; int min0, min1, min2, max0, max1, max2; uint16 *pixN; for (rad = 1; rad <= denoise_radius; rad++) for (int loops = 0; loops < 2; loops++) { min0 = min1 = min2 = 65535; max0 = max1 = max2 = 0; for (dy = -rad; dy <= rad; dy++) // loop all pixels within rad for (dx = -rad; dx <= rad; dx++) { if (dx > -rad && dx < rad) continue; // skip inner pixels if (dy > -rad && dy < rad) continue; pixN = pix3 + (dy * E3ww + dx) * 3; if (pixN[0] < min0) min0 = pixN[0]; // find min and max per color if (pixN[0] > max0) max0 = pixN[0]; // among outermost pixels if (pixN[1] < min1) min1 = pixN[1]; if (pixN[1] > max1) max1 = pixN[1]; if (pixN[2] < min2) min2 = pixN[2]; if (pixN[2] > max2) max2 = pixN[2]; } if (pix3[0] < min0 && pix9[0] < 65279) pix9[0] += 256; // if central pixel is outlier, if (pix3[0] > max0 && pix9[0] > 256) pix9[0] -= 256; // moderate its values if (pix3[1] < min1 && pix9[1] < 65279) pix9[1] += 256; if (pix3[1] > max1 && pix9[1] > 256) pix9[1] -= 256; if (pix3[2] < min2 && pix9[2] < 65279) pix9[2] += 256; if (pix3[2] > max2 && pix9[2] > 256) pix9[2] -= 256; } return; } /**************************************************************************/ // Smart Erase menu function - Replace pixels inside a select area // with a reflection of pixels outside the area. editfunc EFerase; void m_smart_erase(GtkWidget *, const char *) // overhauled v.11.04 { int smart_erase_dialog_event(zdialog* zd, const char *event); int cc; cchar *erase_message = ZTX("1. Drag mouse to select. \n" "2. Erase. 3. Repeat. "); zfuncs::F1_help_topic = "smart_erase"; EFerase.funcname = "smart-erase"; EFerase.Farea = 0; // select area deleted EFerase.mousefunc = sa_mouse_mousefunc; // mouse function (use select area) v.11.12 if (! edit_setup(EFerase)) return; // setup edit /* ______________________________ | | | 1. Drag mouse to select. | | 2. Erase. 3. Repeat. | | | | Radius [10|v] Blur [0.5|v] | | [New Area] [Erase] [Undo] | | | | [Done] | |______________________________| */ zdialog *zd = zdialog_new(ZTX("Smart Erase"),mWin,Bdone,null); EFerase.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",erase_message,"space=8"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labr","hb2",ZTX("Radius"),"space=5"); zdialog_add_widget(zd,"spin","radius","hb2","1|20|1|5"); zdialog_add_widget(zd,"label","labb","hb2",ZTX("Blur"),"space=5"); zdialog_add_widget(zd,"spin","blur","hb2","0|9|0.5|0.5"); zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zd,"button","newarea","hb3",ZTX("New Area"),"space=10"); zdialog_add_widget(zd,"button","erase","hb3",Berase,"space=10"); zdialog_add_widget(zd,"button","undo1","hb3",Bundo,"space=5"); zdialog_help(zd,"smart_erase"); // zdialog help topic v.11.08 zdialog_run(zd,smart_erase_dialog_event,"save"); // run dialog - parallel v.11.07 sa_unselect(); // unselect area if any v.11.06.1 cc = Fww * Fhh * sizeof(uint16); // create new area sa_pixmap = (uint16 *) zmalloc(cc,"smart_erase"); memset(sa_pixmap,0,cc); sa_mode = 5; // mode = select by mouse sa_stat = 1; // status = active edit sa_fww = Fww; // v.11.08 sa_fhh = Fhh; sa_matchcolor = 0; // no color matching v.11.12 sa_searchrange = 1; // search within mouse radius v.11.12 sa_show(1); sa_mouseradius = 5; // initial mouse select radius return; } // dialog event and completion function int smart_erase_dialog_event(zdialog *zd, const char *event) // overhauled v.11.04 { void smart_erase_func(int mode); void smart_erase_blur(double radius); double radius; int cc; if (zd->zstat) { sa_unselect(); if (zd->zstat == 1) edit_done(EFerase); else edit_cancel(EFerase); return 0; } if (strEqu(event,"focus")) { // toggle mouse capture sa_stat = 1; // status = active edit takeMouse(zd,sa_mouse_mousefunc,0); // use select area by mouse function sa_show(1); } if (strEqu(event,"newarea")) { sa_unselect(); cc = Fww * Fhh * sizeof(uint16); // create new area sa_pixmap = (uint16 *) zmalloc(cc,"smart_erase"); memset(sa_pixmap,0,cc); sa_mode = 5; // mode = select by mouse sa_stat = 1; // status = active edit sa_fww = Fww; // v.11.08 sa_fhh = Fhh; sa_show(1); } if (strEqu(event,"radius")) zdialog_fetch(zd,"radius",sa_mouseradius); if (strEqu(event,"erase")) { // do smart erase sa_finish_auto(); // finish the area smart_erase_func(1); zdialog_fetch(zd,"blur",radius); // add optional blur if (radius > 0) smart_erase_blur(radius); sa_show(0); freeMouse(); // disconnect mouse } if (strEqu(event,"undo1")) // dialog undo, undo last erase smart_erase_func(2); return 0; } // erase the area or restore last erased area void smart_erase_func(int mode) { int px, py, npx, npy; int qx, qy, sx, sy, tx, ty; int ii, rad, inc, cc; int dist2, mindist2; double slope; char *pmap; uint16 *pix1, *pix3; if (! Factivearea) return; // nothing selected v.11.05 for (py = sa_miny; py < sa_maxy; py++) // loop all pixels in area for (px = sa_minx; px < sa_maxx; px++) { ii = py * Fww + px; if (! sa_pixmap[ii]) continue; // pixel not selected pix1 = PXMpix(E1pxm16,px,py); // input pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel pix3[0] = pix1[0]; // restore pixels inside area pix3[1] = pix1[1]; pix3[2] = pix1[2]; } mwpaint2(); // update window if (mode == 2) return; // mode = undo, done cc = Fww * Fhh; // allocate pixel done map pmap = (char *) zmalloc(cc,"smart_erase"); memset(pmap,0,cc); for (py = sa_miny; py < sa_maxy; py++) // loop all pixels in area for (px = sa_minx; px < sa_maxx; px++) { ii = py * Fww + px; if (! sa_pixmap[ii]) continue; // pixel not selected if (pmap[ii]) continue; // pixel already done mindist2 = 999999; // find nearest edge npx = npy = 0; for (rad = 1; rad < 50; rad++) // 50 pixel limit v.11.05 { for (qx = px-rad; qx <= px+rad; qx++) // search within rad v.11.05 for (qy = py-rad; qy <= py+rad; qy++) { if (qx < 0 || qx >= Fww) continue; // off image edge modified v.11.09 if (qy < 0 || qy >= Fhh) continue; ii = qy * Fww + qx; if (sa_pixmap[ii]) continue; // within selected area dist2 = (px-qx) * (px-qx) + (py-qy) * (py-qy); // distance**2 to edge pixel if (dist2 < mindist2) { mindist2 = dist2; npx = qx; // save nearest edge pixel found npy = qy; } } if (rad * rad >= mindist2) break; // can quit now } if (! npx && ! npy) continue; // edge not found, should not happen qx = npx; // nearest edge pixel qy = npy; if (abs(qy - py) > abs(qx - px)) { // qx/qy = near edge from px/py slope = 1.0 * (qx - px) / (qy - py); if (qy > py) inc = 1; else inc = -1; for (sy = py; sy != qy; sy += inc) // line from px/py to qx/qy v.11.06 { sx = px + slope * (sy - py); ii = sy * Fww + sx; if (pmap[ii]) continue; // v.11.06 pmap[ii] = 1; tx = qx + (qx - sx); // tx/ty = parallel line from qx/qy ty = qy + (qy - sy); // modified v.11.09 if (tx < 0) tx = 0; if (tx > Fww-1) tx = Fww-1; if (ty < 0) ty = 0; if (ty > Fhh-1) ty = Fhh-1; pix1 = PXMpix(E3pxm16,tx,ty); // copy pixel from tx/ty to sx/sy pix3 = PXMpix(E3pxm16,sx,sy); pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } else { slope = 1.0 * (qy - py) / (qx - px); if (qx > px) inc = 1; else inc = -1; for (sx = px; sx != qx; sx += inc) { sy = py + slope * (sx - px); ii = sy * Fww + sx; if (pmap[ii]) continue; pmap[ii] = 1; tx = qx + (qx - sx); ty = qy + (qy - sy); if (tx < 0) tx = 0; if (tx > Fww-1) tx = Fww-1; if (ty < 0) ty = 0; if (ty > Fhh-1) ty = Fhh-1; pix1 = PXMpix(E3pxm16,tx,ty); pix3 = PXMpix(E3pxm16,sx,sy); pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } } zfree(pmap); // free memory CEF->Fmod = 1; mwpaint2(); // update window return; } // add blur to the erased area to help mask the side-effects int smart_erase_blur(double radius) { int ii, px, py, dx, dy, adx, ady; double blur_weight[10][10]; // up to blur radius = 9 double rad, rad2; double m, d, w, sum; double red, green, blue; double weight1, weight2; uint16 *pix9, *pix3, *pixN; if (! Factivearea) return 0; rad = radius - 0.2; rad2 = rad * rad; for (dx = 0; dx <= rad+1; dx++) // clear weights array for (dy = 0; dy <= rad+1; dy++) blur_weight[dx][dy] = 0; for (dx = -rad-1; dx <= rad+1; dx++) // blur_weight[dx][dy] = no. of pixels for (dy = -rad-1; dy <= rad+1; dy++) // at distance (dx,dy) from center ++blur_weight[abs(dx)][abs(dy)]; m = sqrt(rad2 + rad2); // corner pixel distance from center sum = 0; for (dx = 0; dx <= rad+1; dx++) // compute weight of pixel for (dy = 0; dy <= rad+1; dy++) // at distance dx, dy { d = sqrt(dx*dx + dy*dy); w = (m + 1.2 - d) / m; w = w * w; sum += blur_weight[dx][dy] * w; blur_weight[dx][dy] = w; } for (dx = 0; dx <= rad+1; dx++) // make weights add up to 1.0 for (dy = 0; dy <= rad+1; dy++) blur_weight[dx][dy] = blur_weight[dx][dy] / sum; E9pxm16 = PXM_copy(E3pxm16); // copy edited image for (py = sa_miny; py < sa_maxy; py++) // loop all pixels in area for (px = sa_minx; px < sa_maxx; px++) { ii = py * Fww + px; if (! sa_pixmap[ii]) continue; // pixel not in area pix9 = PXMpix(E9pxm16,px,py); // source pixel pix3 = PXMpix(E3pxm16,px,py); // target pixel rad = radius; red = green = blue = 0; weight2 = 0.0; for (dy = -rad-1; dy <= rad+1; dy++) // loop neighbor pixels within radius for (dx = -rad-1; dx <= rad+1; dx++) { if (px+dx < 0 || px+dx >= E3ww) continue; // omit pixels off edge if (py+dy < 0 || py+dy >= E3hh) continue; adx = abs(dx); ady = abs(dy); pixN = pix9 + (dy * E3ww + dx) * 3; weight1 = blur_weight[adx][ady]; // weight at distance (dx,dy) weight2 += weight1; red += pixN[0] * weight1; // accumulate contributions green += pixN[1] * weight1; blue += pixN[2] * weight1; } red = red / weight2; // weighted average green = green / weight2; blue = blue / weight2; pix3[0] = int(red); pix3[1] = int(green); pix3[2] = int(blue); } PXM_free(E9pxm16); CEF->Fmod = 1; mwpaint2(); // update window return 0; } /**************************************************************************/ // find and remove "dust" from an image (e.g. from a scanned dusty slide) // dust is defined as small dark areas surrounded by brighter areas // image 1 original with prior edits // image 3 accumulated dust removals that have been comitted // image 9 comitted dust removals + pending removal (work in process) namespace dust_names { editfunc EFdust; int spotspann; // max. dustspot spann, pixels int spotspann2; // spotspann **2 double brightness; // brightness limit, 0 to 1 = white double contrast; // min. contrast, 0 to 1 = black/white int *pixgroup; // maps (px,py) to pixel group no. int Fred; // red pixels are on int Nstack; struct spixstack { uint16 px, py; // pixel group search stack uint16 direc; } *pixstack; #define maxgroups 1000000 int Ngroups; int groupcount[maxgroups]; // count of pixels in each group double groupbright[maxgroups]; // int edgecount[maxgroups]; // group edge pixel count double edgebright[maxgroups]; // group edge pixel brightness sum typedef struct { uint16 px1, py1, px2, py2; // pixel group extreme pixels int spann2; // spann from px1/py1 to px2/py2 } sgroupspann; sgroupspann groupspann[maxgroups]; } void m_dust(GtkWidget *, const char *) // new v.11.05 { using namespace dust_names; int dust_dialog_event(zdialog *zd, cchar *event); void * dust_thread(void *); zfuncs::F1_help_topic = "remove_dust"; // v.11.05.1 EFdust.funcname = "dust"; EFdust.Farea = 2; // select area usable EFdust.threadfunc = dust_thread; // thread function if (! edit_setup(EFdust)) return; // setup edit E9pxm16 = PXM_copy(E3pxm16); // image 9 = copy of image3 Fred = 0; int cc = Fww * Fhh * sizeof(int); pixgroup = (int *) zmalloc(cc,"erase_dust"); // maps pixels to assigned groups cc = Fww * Fhh * sizeof(spixstack); pixstack = (spixstack *) zmalloc(cc,"erase_dust"); // pixel group search stack /*** Remove Dust spot size limit =========[]=========== max. brightness =============[]======= min. contrast ========[]============ [erase] [red] [undo last] [apply] [Done] [Cancel] ***/ zdialog *zd = zdialog_new(ZTX("Remove Dust"),mWin,Bdone,Bcancel,null); EFdust.zd = zd; zdialog_add_widget(zd,"hbox","hbssl","dialog",0,"space=1"); zdialog_add_widget(zd,"label","labssl","hbssl",ZTX("spot size limit"),"space=5"); zdialog_add_widget(zd,"hscale","spotspann","hbssl","1|50|1|20","space=5|expand"); zdialog_add_widget(zd,"hbox","hbmb","dialog",0,"space=1"); zdialog_add_widget(zd,"label","labmb","hbmb",ZTX("max. brightness"),"space=5"); zdialog_add_widget(zd,"hscale","brightness","hbmb","1|999|1|700","space=5|expand"); zdialog_add_widget(zd,"hbox","hbmc","dialog",0,"space=1"); zdialog_add_widget(zd,"label","labmb","hbmc",ZTX("min. contrast"),"space=5"); zdialog_add_widget(zd,"hscale","contrast","hbmc","1|500|1|50","space=5|expand"); zdialog_add_widget(zd,"hbox","hbbutts","dialog",0,"space=5"); zdialog_add_widget(zd,"button","erase","hbbutts",Berase,"space=5"); zdialog_add_widget(zd,"button","red","hbbutts",Bred,"space=5"); zdialog_add_widget(zd,"button","undo1","hbbutts",Bundolast,"space=5"); zdialog_add_widget(zd,"button","apply","hbbutts",Bapply,"space=5"); zdialog_fetch(zd,"spotspann",spotspann); // max. dustspot spann (pixels) spotspann2 = spotspann * spotspann; zdialog_fetch(zd,"brightness",brightness); // max. dustspot brightness brightness = 0.001 * brightness; // scale 0 to 1 = white zdialog_fetch(zd,"contrast",contrast); // min. dustspot contrast contrast = 0.001 * contrast; // scale 0 to 1 = black/white zdialog_resize(zd,300,0); zdialog_help(zd,"remove_dust"); // zdialog help topic v.11.08 zdialog_run(zd,dust_dialog_event,"save"); // run dialog - parallel v.11.07 signal_thread(); return; } // dialog event and completion callback function int dust_dialog_event(zdialog *zd, cchar *event) { using namespace dust_names; void dust_erase(); if (zd->zstat) // dialog complete { if (zd->zstat == 1) { // done, use committed changes mutex_lock(&Fpixmap_lock); PXM_free(E3pxm16); E3pxm16 = E9pxm16; // image 3 = image 9 E9pxm16 = 0; mutex_unlock(&Fpixmap_lock); edit_done(EFdust); } else { // cancel, discard changes PXM_free(E9pxm16); edit_cancel(EFdust); } zfree(pixgroup); // free memory zfree(pixstack); return 0; } if (strEqu(event,"spotspann") || strEqu(event,"brightness") || strEqu(event,"contrast") || strEqu(event,"red")) { zdialog_fetch(zd,"spotspann",spotspann); // max. dustspot spann (pixels) spotspann2 = spotspann * spotspann; zdialog_fetch(zd,"brightness",brightness); // max. dustspot brightness brightness = 0.001 * brightness; // scale 0 to 1 = white zdialog_fetch(zd,"contrast",contrast); // min. dustspot contrast contrast = 0.001 * contrast; // scale 0 to 1 = black/white signal_thread(); // do the work } if (strEqu(event,"erase")) dust_erase(); if (strEqu(event,"blendwidth")) dust_erase(); if (strEqu(event,"undo1")) { mutex_lock(&Fpixmap_lock); // image 3 = copy of image 9 PXM_free(E3pxm16); E3pxm16 = PXM_copy(E9pxm16); mutex_unlock(&Fpixmap_lock); Fred = 0; mwpaint2(); } if (strEqu(event,"apply")) { if (Fred) dust_erase(); PXM_free(E9pxm16); // image 9 = copy of image 3 E9pxm16 = PXM_copy(E3pxm16); CEF->Fmod = 1; } return 0; } // dust find thread function - find the dust particles and mark them void * dust_thread(void *) { using namespace dust_names; int xspann, yspann, spann2; int group, cc, ii, kk, Nremoved; int px, py, dx, dy, ppx, ppy, npx, npy; double gbright, pbright, pcontrast; double ff = 1.0 / 65536.0; uint16 direc, *pix3; while (true) { thread_idle_loop(); // wait for work or exit request mutex_lock(&Fpixmap_lock); // image 3 = copy of image 9 PXM_free(E3pxm16); E3pxm16 = PXM_copy(E9pxm16); mutex_unlock(&Fpixmap_lock); mwpaint2(); cc = Fww * Fhh * sizeof(int); // clear group arrays memset(pixgroup,0,cc); cc = maxgroups * sizeof(int); memset(groupcount,0,cc); memset(edgecount,0,cc); cc = maxgroups * sizeof(double); memset(groupbright,0,cc); memset(edgebright,0,cc); cc = maxgroups * sizeof(sgroupspann); memset(groupspann,0,cc); group = 0; for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; if (Factivearea && ! sa_pixmap[ii]) continue; // not in active area if (pixgroup[ii]) continue; // already assigned to a group pix3 = PXMpix(E3pxm16,px,py); // get pixel brightness gbright = ff * pixbright(pix3); // 0 to 1.0 = white if (gbright > brightness) continue; // ignore bright pixel if (group == maxgroups-1) break; // too many groups, make no more pixgroup[ii] = ++group; // assign next group groupcount[group] = 1; groupbright[group] = gbright; pixstack[0].px = px; // put pixel into stack with pixstack[0].py = py; // direction = ahead pixstack[0].direc = 0; Nstack = 1; while (Nstack) { kk = Nstack - 1; // get last pixel in stack px = pixstack[kk].px; py = pixstack[kk].py; direc = pixstack[kk].direc; // next search direction if (direc == 'x') { Nstack--; // none left continue; } if (Nstack > 1) { ii = Nstack - 2; // get prior pixel in stack ppx = pixstack[ii].px; ppy = pixstack[ii].py; } else { ppx = px - 1; // if only one, assume prior = left ppy = py; } dx = px - ppx; // vector from prior to this pixel dy = py - ppy; switch (direc) { case 0: npx = px + dx; npy = py + dy; pixstack[kk].direc = 1; break; case 1: npx = px + dy; npy = py + dx; pixstack[kk].direc = 3; break; case 2: npx = px - dx; // back to prior pixel npy = py - dy; // (this path never taken) zappcrash("stack search bug"); break; case 3: npx = px - dy; npy = py - dx; pixstack[kk].direc = 4; break; case 4: npx = px - dx; npy = py + dy; pixstack[kk].direc = 5; break; case 5: npx = px - dy; npy = py + dx; pixstack[kk].direc = 6; break; case 6: npx = px + dx; npy = py - dy; pixstack[kk].direc = 7; break; case 7: npx = px + dy; npy = py - dx; pixstack[kk].direc = 'x'; break; default: npx = npy = 0; zappcrash("stack search bug"); } if (npx < 0 || npx > Fww-1) continue; // pixel off the edge if (npy < 0 || npy > Fhh-1) continue; ii = npy * Fww + npx; if (pixgroup[ii]) continue; // pixel already assigned if (Factivearea && ! sa_pixmap[ii]) continue; // pixel outside area pix3 = PXMpix(E3pxm16,npx,npy); // pixel brightness pbright = ff * pixbright(pix3); if (pbright > brightness) continue; // brighter than limit pixgroup[ii] = group; // assign pixel to group ++groupcount[group]; // count pixels in group groupbright[group] += pbright; // sum brightness for group kk = Nstack++; // put pixel into stack pixstack[kk].px = npx; pixstack[kk].py = npy; pixstack[kk].direc = 0; // search direction } } Ngroups = group; // group numbers are 1-Ngroups Nremoved = 0; for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; group = pixgroup[ii]; if (! group) continue; if (groupspann[group].px1 == 0) { // first pixel found in this group groupspann[group].px1 = px; // group px1/py1 = this pixel groupspann[group].py1 = py; continue; } xspann = groupspann[group].px1 - px; // spann from group px1/py1 to this pixel yspann = groupspann[group].py1 - py; spann2 = xspann * xspann + yspann * yspann; if (spann2 > groupspann[group].spann2) { groupspann[group].spann2 = spann2; // if greater, group px2/py2 = this pixel groupspann[group].px2 = px; groupspann[group].py2 = py; } } for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; group = pixgroup[ii]; if (! group) continue; if (groupspann[group].spann2 > spotspann2) continue; xspann = groupspann[group].px2 - px; // spann from this pixel to group px2/py2 yspann = groupspann[group].py2 - py; spann2 = xspann * xspann + yspann * yspann; if (spann2 > groupspann[group].spann2) { groupspann[group].spann2 = spann2; // if greater, group px1/py1 = this pixel groupspann[group].px1 = px; groupspann[group].py1 = py; } } for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; // eliminate group if spann > limit group = pixgroup[ii]; if (! group) continue; if (! groupcount[group]) pixgroup[ii] = 0; else if (groupspann[group].spann2 > spotspann2) { pixgroup[ii] = 0; groupcount[group] = 0; Nremoved++; } } for (py = 1; py < Fhh-1; py++) // loop all pixels except image edges for (px = 1; px < Fww-1; px++) { ii = py * Fww + px; group = pixgroup[ii]; if (group) continue; // find pixels bordering group pixels pix3 = PXMpix(E3pxm16,px,py); pbright = ff * pixbright(pix3); group = pixgroup[ii-Fww-1]; if (group) { ++edgecount[group]; // accumulate pixel count and edgebright[group] += pbright; // bordering the groups } group = pixgroup[ii-Fww]; if (group) { ++edgecount[group]; edgebright[group] += pbright; } group = pixgroup[ii-Fww+1]; if (group) { ++edgecount[group]; edgebright[group] += pbright; } group = pixgroup[ii-1]; if (group) { ++edgecount[group]; edgebright[group] += pbright; } group = pixgroup[ii+1]; if (group) { ++edgecount[group]; edgebright[group] += pbright; } group = pixgroup[ii+Fww-1]; if (group) { ++edgecount[group]; edgebright[group] += pbright; } group = pixgroup[ii+Fww]; if (group) { ++edgecount[group]; edgebright[group] += pbright; } group = pixgroup[ii+Fww+1]; if (group) { ++edgecount[group]; edgebright[group] += pbright; } } for (group = 1; group <= Ngroups; group++) // compute group pixel and edge pixel { // mean brightness if (groupcount[group] && edgecount[group]) { edgebright[group] = edgebright[group] / edgecount[group]; groupbright[group] = groupbright[group] / groupcount[group]; pcontrast = edgebright[group] - groupbright[group]; // edge - group contrast if (pcontrast < contrast) { groupcount[group] = 0; Nremoved++; } } } for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; // eliminate group if low contrast group = pixgroup[ii]; if (! group) continue; if (! groupcount[group]) pixgroup[ii] = 0; } for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; if (! pixgroup[ii]) continue; // not a dust pixel pix3 = PXMpix(E3pxm16,px,py); // paint it red pix3[0] = 65535; pix3[1] = pix3[2] = 0; } Fred = 1; mwpaint2(); // update window } return 0; // not executed, stop g++ warning } // erase the selected dust areas void dust_erase() { using namespace dust_names; int cc, ii, px, py, inc; int qx, qy, npx, npy; int sx, sy, tx, ty; int rad, dist, dist2, mindist2; double slope, f1, f2; uint16 *pix1, *pix3; char *pmap; Ffuncbusy++; mutex_lock(&Fpixmap_lock); // image 3 = copy of image 9 PXM_free(E3pxm16); E3pxm16 = PXM_copy(E9pxm16); mutex_unlock(&Fpixmap_lock); cc = Fww * Fhh; // allocate pixel done map pmap = (char *) zmalloc(cc,"erase_dust"); memset(pmap,0,cc); for (py = 0; py < Fhh; py++) // loop all pixels for (px = 0; px < Fww; px++) { ii = py * Fww + px; if (! pixgroup[ii]) continue; // not a dust pixel if (pmap[ii]) continue; // skip pixels already done mindist2 = 999999; npx = npy = 0; for (rad = 1; rad < 10; rad++) // find nearest edge (10 pixel limit) { for (qx = px-rad; qx <= px+rad; qx++) // search within rad for (qy = py-rad; qy <= py+rad; qy++) { if (qx < 0 || qx >= Fww) continue; // off image edge modified v.11.09 if (qy < 0 || qy >= Fhh) continue; ii = qy * Fww + qx; if (pixgroup[ii]) continue; // within dust area dist2 = (px-qx) * (px-qx) + (py-qy) * (py-qy); // distance**2 to edge pixel if (dist2 < mindist2) { mindist2 = dist2; npx = qx; // save nearest pixel found npy = qy; } } if (rad * rad >= mindist2) break; // can quit now } if (! npx && ! npy) continue; // should not happen qx = npx; // nearest edge pixel qy = npy; if (abs(qy - py) > abs(qx - px)) { // qx/qy = near edge from px/py slope = 1.0 * (qx - px) / (qy - py); if (qy > py) inc = 1; else inc = -1; for (sy = py; sy != qy+inc; sy += inc) // line from px/py to qx/qy { sx = px + slope * (sy - py); ii = sy * Fww + sx; if (pmap[ii]) continue; // v.11.06 pmap[ii] = 1; tx = qx + (qx - sx); // tx/ty = parallel line from qx/qy ty = qy + (qy - sy); // modified v.11.09 if (tx < 0) tx = 0; if (tx > Fww-1) tx = Fww-1; if (ty < 0) ty = 0; if (ty > Fhh-1) ty = Fhh-1; pix1 = PXMpix(E3pxm16,tx,ty); // copy pixel from tx/ty to sx/sy pix3 = PXMpix(E3pxm16,sx,sy); pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } else { slope = 1.0 * (qy - py) / (qx - px); if (qx > px) inc = 1; else inc = -1; for (sx = px; sx != qx+inc; sx += inc) { sy = py + slope * (sx - px); ii = sy * Fww + sx; if (pmap[ii]) continue; pmap[ii] = 1; tx = qx + (qx - sx); ty = qy + (qy - sy); if (tx < 0) tx = 0; if (tx > Fww-1) tx = Fww-1; if (ty < 0) ty = 0; if (ty > Fhh-1) ty = Fhh-1; pix1 = PXMpix(E3pxm16,tx,ty); pix3 = PXMpix(E3pxm16,sx,sy); pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } } zfree(pmap); if (Factivearea) // area edge blending { for (ii = 0; ii < Fww * Fhh; ii++) // find pixels in select area { dist = sa_pixmap[ii]; if (! dist || dist >= sa_blend) continue; py = ii / Fww; px = ii - py * Fww; pix1 = PXMpix(E1pxm16,px,py); // input pixel, unchanged image pix3 = PXMpix(E3pxm16,px,py); // output pixel, changed image f2 = 1.0 * dist / sa_blend; // changes over distance sa_blend f1 = 1.0 - f2; pix3[0] = f1 * pix1[0] + f2 * pix3[0]; // blend the pixels pix3[1] = f1 * pix1[1] + f2 * pix3[1]; pix3[2] = f1 * pix1[2] + f2 * pix3[2]; } } Fred = 0; Ffuncbusy--; mwpaint2(); // update window return; } /**************************************************************************/ // Find and fix stuck pixels (always bright or dark) from camera sensor defects. namespace stuckpix { editfunc EFstuckpix; int stuckpix_1x1, stuckpix_2x2, stuckpix_3x3; // pixel blocks to search int stuckpix_color; // 1/2/3 = white/black/red circles cchar *stuckpix_mode; // find or fix double stuckpix_threshcon; // min. contrast threshold char *stuckpix_file = 0; // file for saved bad pixels struct badpix_t { // memory for bad pixels int px, py; // location (NW corner of block) int size; // size: 1/2/3 = 1x1/2x2/3x3 block double pcon; // contrast with surrounding pixels int rgb[3]; // surrounding pixel mean RGB }; badpix_t badpix[50]; int maxbad = 50, Nbad; } void m_stuckpix(GtkWidget *, cchar *menu) // new v.11.12 { using namespace stuckpix; int stuckpix_dialog_event(zdialog *zd, cchar *event); void * stuckpix_thread(void *); zdialog *zd; zfuncs::F1_help_topic = "stuck_pixels"; EFstuckpix.funcname = "stuckpix"; // function name EFstuckpix.threadfunc = stuckpix_thread; // thread function if (! edit_setup(EFstuckpix)) return; // setup edit /*** pixel group [x] 1x1 [x] 2x2 [x] 3x3 circle color (o) white (o) black (o) red contrast =========[]==================== [open] [save] [apply] [cancel] ***/ zd = zdialog_new(ZTX("Fix Stuck Pixels"),mWin,Bopen,Bsave,Bapply,Bcancel,null); EFstuckpix.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"space=5|homog"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"space=5|expand|homog"); zdialog_add_widget(zd,"label","labgroup","vb1",ZTX("pixel group")); zdialog_add_widget(zd,"label","labcolor","vb1",ZTX("circle color")); zdialog_add_widget(zd,"label","labcont","vb1",ZTX("contrast")); zdialog_add_widget(zd,"hbox","hbgroup","vb2"); zdialog_add_widget(zd,"check","1x1","hbgroup","1x1","space=3"); zdialog_add_widget(zd,"check","2x2","hbgroup","2x2","space=3"); zdialog_add_widget(zd,"check","3x3","hbgroup","3x3","space=3"); zdialog_add_widget(zd,"hbox","hbcolor","vb2"); zdialog_add_widget(zd,"radio","white","hbcolor",Bwhite,"space=5"); zdialog_add_widget(zd,"radio","black","hbcolor",Bblack,"space=5"); zdialog_add_widget(zd,"radio","red","hbcolor",Bred,"space=5"); zdialog_add_widget(zd,"hscale","contrast","vb2","0.1|1.0|0.001|0.5","expand"); zdialog_stuff(zd,"1x1",1); // initz. dialog controls zdialog_stuff(zd,"2x2",1); zdialog_stuff(zd,"3x3",1); zdialog_stuff(zd,"white",0); zdialog_stuff(zd,"black",0); zdialog_stuff(zd,"red",1); stuckpix_1x1 = stuckpix_2x2 = stuckpix_3x3 = 1; // corresp. data values stuckpix_color = 3; stuckpix_threshcon = 0.5; if (! stuckpix_file) { // default file stuckpix_file = zmalloc(200); // /home//.fotoxx/stuck-pixels snprintf(stuckpix_file,200,"%s/stuck-pixels",get_zuserdir()); } zdialog_help(zd,"stuck_pixels"); zdialog_run(zd,stuckpix_dialog_event,"save"); // run dialog stuckpix_mode = "find"; signal_thread(); // find and show the bad pixels wait_thread_idle(); return; } // dialog event function int stuckpix_dialog_event(zdialog *zd, cchar *event) { using namespace stuckpix; void stuckpix_open(); void stuckpix_save(); int color; if (zd->zstat) // completion button { if (zd->zstat == 1) { // open file zd->zstat = 0; // keep dialog active stuckpix_open(); } else if (zd->zstat == 2) { // save file zd->zstat = 0; // keep dialog active stuckpix_save(); } else if (zd->zstat == 3) { // apply stuckpix_mode = "apply"; signal_thread(); // fix the bad pixels wait_thread_idle(); edit_done(EFstuckpix); erase_topcircles(); } else { // cancel edit_cancel(EFstuckpix); erase_topcircles(); } mwpaint2(); // update main window return 0; } zdialog_fetch(zd,"1x1",stuckpix_1x1); // get dialog inputs zdialog_fetch(zd,"2x2",stuckpix_2x2); zdialog_fetch(zd,"3x3",stuckpix_3x3); zdialog_fetch(zd,"white",color); if (color) stuckpix_color = 1; zdialog_fetch(zd,"black",color); if (color) stuckpix_color = 2; zdialog_fetch(zd,"red",color); if (color) stuckpix_color = 3; zdialog_fetch(zd,"contrast",stuckpix_threshcon); stuckpix_mode = "find"; signal_thread(); // find and show bad pixels wait_thread_idle(); return 0; } // load bad pixel list from a previously saved file void stuckpix_open() { using namespace stuckpix; int stuckpix_open_dialog_event(zdialog *zd, cchar *event); zdialog *zd; zd = zdialog_new(ZTX("Load Stuck Pixels"),mWin,Bopen,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"label","lab1","hb1",ZTX("File:"),"space=3"); zdialog_add_widget(zd,"entry","file","hb1",0,"expand|scc=40"); zdialog_add_widget(zd,"button","browse","hb1",Bbrowse,"space=5"); zdialog_stuff(zd,"file",stuckpix_file); zdialog_run(zd,stuckpix_open_dialog_event); zdialog_wait(zd); return; } int stuckpix_open_dialog_event(zdialog *zd, cchar *event) { using namespace stuckpix; char *pp, file[200]; FILE *fid = 0; int zstat, nn, ii, px, py, size; if (strEqu(event,"browse")) { pp = zgetfile1(ZTX("Stuck Pixels file"),"open",stuckpix_file); if (! pp) return 0; zdialog_stuff(zd,"file",pp); zfree(pp); } zstat = zd->zstat; // completion button if (zstat) { if (zstat == 1) // open { zdialog_fetch(zd,"file",file,200); // get file from dialog if (stuckpix_file) zfree(stuckpix_file); stuckpix_file = strdupz(file); fid = fopen(file,"r"); // open file if (! fid) { zmessageACK(mWin,ZTX("file not found")); return 1; } nn = fscanf(fid,"stuck pixels px py size"); // read headers for (ii = 0; ii < maxbad; ii++) { nn = fscanf(fid," %5d %5d %5d ",&px,&py,&size); // read bad pixels data if (nn == EOF) break; if (nn != 3) break; badpix[ii].px = px; badpix[ii].py = py; badpix[ii].size = size; badpix[ii].pcon = 0; } Nbad = ii; fclose(fid); zdialog_free(zd); if (! Nbad || nn != EOF) zmessageACK(mWin,ZTX("file format error")); stuckpix_mode = "file"; // process pixels signal_thread(); wait_thread_idle(); } else { // cancel or [x] zdialog_free(zd); return 1; } } return 1; } // save bad pixel list to a file or add them to a previous file void stuckpix_save() { using namespace stuckpix; int stuckpix_save_dialog_event(zdialog *zd, cchar *event); zdialog *zd; if (Nbad == 0) { zmessageACK(mWin,ZTX("there are zero stuck pixels")); return; } zd = zdialog_new(ZTX("Save Stuck Pixels"),mWin,Bsave,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"label","lab1","hb1",ZTX("File:"),"space=3"); zdialog_add_widget(zd,"entry","file","hb1",0,"expand|scc=40"); zdialog_add_widget(zd,"button","browse","hb1",Bbrowse,"space=5"); zdialog_stuff(zd,"file",stuckpix_file); zdialog_run(zd,stuckpix_save_dialog_event); zdialog_wait(zd); return; } int stuckpix_save_dialog_event(zdialog *zd, cchar *event) { using namespace stuckpix; char *pp, file[200]; FILE *fid = 0; int zstat, ii, px, py, size; if (strEqu(event,"browse")) { pp = zgetfile1(ZTX("Stuck Pixels file"),"save",stuckpix_file); if (! pp) return 0; zdialog_stuff(zd,"file",pp); zfree(pp); } zstat = zd->zstat; // completion button if (zstat) { if (zstat == 1) // save { zdialog_fetch(zd,"file",file,200); // get file from dialog if (stuckpix_file) zfree(stuckpix_file); stuckpix_file = strdupz(file); fid = fopen(file,"w"); // open file if (! fid) { zmessageACK(mWin,strerror(errno)); return 1; } fprintf(fid,"stuck pixels \n"); // write headers fprintf(fid," px py size \n"); for (ii = 0; ii < Nbad; ii++) // write bad pixel data { px = badpix[ii].px; py = badpix[ii].py; size = badpix[ii].size; fprintf(fid," %5d %5d %5d \n",px,py,size); } fclose(fid); zdialog_free(zd); } else { // cancel or [x] zdialog_free(zd); return 1; } } return 1; } // perform the fix function // find pixel groups with contrast exceeding the limit // replace these pixels with surrounding ones void * stuckpix_thread(void *) { using namespace stuckpix; void stuckpix_pixelblock(int px, int py, int size, int rgb[3]); void stuckpix_surroundings(int px, int py, int size, int rgb[3]); double stuckpix_getcon(int rgbA[3], int rgbB[3]); void stuckpix_insert(int px, int py, int size, double pcon, int rgb[3]); void stuckpix_show(); int px, py, qx, qy, ii, size; int rgbA[3], rgbB[3]; double threshcon, pcon; uint16 *ppix; while (true) { thread_idle_loop(); if (strEqu(stuckpix_mode,"find")) // find bad pixels in image { threshcon = stuckpix_threshcon; // threshold contrast, 0.1 to 1.0 Nbad = 0; // count bad pixels found if (stuckpix_3x3) // find 3x3 pixel groups FIRST { for (py = 2; py < E3hh-5; py++) for (px = 2; px < E3ww-5; px++) { stuckpix_pixelblock(px,py,3,rgbA); // get mean RGB for 3x3 pixel block stuckpix_surroundings(px,py,3,rgbB); // get surrounding pixels mean RGB pcon = stuckpix_getcon(rgbA,rgbB); // contrast with surrounding if (pcon > threshcon) stuckpix_insert(px,py,3,pcon,rgbB); // if > threshold, add to table if (Nbad == maxbad) goto findquit; } } if (stuckpix_2x2) // find 2x2 pixel groups { for (py = 2; py < E3hh-4; py++) for (px = 2; px < E3ww-4; px++) { stuckpix_pixelblock(px,py,2,rgbA); // get mean RGB for 2x2 pixel block stuckpix_surroundings(px,py,2,rgbB); // get surrounding pixels mean RGB pcon = stuckpix_getcon(rgbA,rgbB); // contrast with surrounding if (pcon > threshcon) stuckpix_insert(px,py,2,pcon,rgbB); // if > threshold, add to table if (Nbad == maxbad) goto findquit; } } if (stuckpix_1x1) // find 1x1 pixel groups LAST { for (py = 2; py < E3hh-3; py++) for (px = 2; px < E3ww-3; px++) { stuckpix_pixelblock(px,py,1,rgbA); // get mean RGB for 1x1 pixel block stuckpix_surroundings(px,py,1,rgbB); // get surrounding pixels mean RGB pcon = stuckpix_getcon(rgbA,rgbB); // contrast with surrounding if (pcon > threshcon) stuckpix_insert(px,py,1,pcon,rgbB); // if > threshold, add to table if (Nbad == maxbad) goto findquit; } } findquit: stuckpix_show(); // show the bad pixels found } if (strEqu(stuckpix_mode,"file")) // process bad pixels read from a file { for (ii = 0; ii < Nbad; ii++) { px = badpix[ii].px; py = badpix[ii].py; size = badpix[ii].size; stuckpix_pixelblock(px,py,size,rgbA); stuckpix_surroundings(px,py,size,rgbB); pcon = stuckpix_getcon(rgbA,rgbB); badpix[ii].pcon = pcon; badpix[ii].rgb[0] = rgbB[0]; badpix[ii].rgb[1] = rgbB[1]; badpix[ii].rgb[2] = rgbB[2]; } stuckpix_show(); // show the bad pixels read } if (strEqu(stuckpix_mode,"apply")) // replace the bad pixels { for (ii = 0; ii < Nbad; ii++) // loop pixel groups found { px = badpix[ii].px; py = badpix[ii].py; size = badpix[ii].size; if (! size) continue; if (size == 1) // 1x1 pixel group { ppix = PXMpix(E3pxm16,px,py); // replace pixel group ppix[0] = badpix[ii].rgb[0]; ppix[1] = badpix[ii].rgb[1]; ppix[2] = badpix[ii].rgb[2]; } if (size == 2) // 2x2 pixel group { for (qy = py; qy < py+2; qy++) // replace pixel group for (qx = px; qx < px+2; qx++) { ppix = PXMpix(E3pxm16,qx,qy); ppix[0] = badpix[ii].rgb[0]; ppix[1] = badpix[ii].rgb[1]; ppix[2] = badpix[ii].rgb[2]; } } if (size == 3) // 3x3 pixel group { for (qy = py; qy < py+3; qy++) // replace pixel group for (qx = px; qx < px+3; qx++) { ppix = PXMpix(E3pxm16,qx,qy); ppix[0] = badpix[ii].rgb[0]; ppix[1] = badpix[ii].rgb[1]; ppix[2] = badpix[ii].rgb[2]; } } } EFstuckpix.Fmod++; // image modified mwpaint2(); // update window } } return 0; } // get the mean RGB values for a block of (defective) pixels void stuckpix_pixelblock(int px, int py, int size, int rgb[3]) { uint16 *ppix; ppix = PXMpix(E3pxm16,px,py); // block of pixels if (size == 1) // 1x1 block, 1 pixel { rgb[0] = ppix[0]; rgb[1] = ppix[1]; rgb[2] = ppix[2]; } if (size == 2) // 2x2 block, 4 pixels { rgb[0] = (ppix[0] + ppix[3] + ppix[E3ww*3] + ppix[E3ww*3+3]) / 4; rgb[1] = (ppix[1] + ppix[4] + ppix[E3ww*3+1] + ppix[E3ww*3+4]) / 4; rgb[2] = (ppix[2] + ppix[5] + ppix[E3ww*3+2] + ppix[E3ww*3+5]) / 4; } if (size == 3) // 3x3 block, 9 pixels { rgb[0] = (ppix[0] + ppix[3] + ppix[6] + ppix[E3ww*3] + ppix[E3ww*3+3] + ppix[E3ww*3+6] + ppix[E3ww*6] + ppix[E3ww*6+3] + ppix[E3ww*6+6]) / 9; rgb[1] = (ppix[1] + ppix[4] + ppix[7] + ppix[E3ww*3+1] + ppix[E3ww*3+4] + ppix[E3ww*3+7] + ppix[E3ww*6+1] + ppix[E3ww*6+4] + ppix[E3ww*6+7]) / 9; rgb[2] = (ppix[2] + ppix[5] + ppix[8] + ppix[E3ww*3+2] + ppix[E3ww*3+5] + ppix[E3ww*3+8] + ppix[E3ww*6+2] + ppix[E3ww*6+5] + ppix[E3ww*6+8]) / 9; } return; } // get the mean RGB values for pixels surrounding a given pixel block void stuckpix_surroundings(int px, int py, int size, int rgb[3]) { int qx, qy, ii; int red, green, blue; uint16 *ppix; int n8x[8] = { -1, 0, 1,-1, 1,-1, 0, 1 }; // 8 neighbors of 1x1 group at [0,0] int n8y[8] = { -1,-1,-1, 0, 0, 1, 1, 1 }; int n12x[12] = { -1, 0, 1, 2,-1, 2,-1, 2,-1, 0, 1, 2 }; // 12 neighbors of 2x2 group at [0,0] int n12y[12] = { -1,-1,-1,-1, 0, 0, 1, 1, 2, 2, 2, 2 }; int n16x[16] = { -1, 0, 1, 2, 3,-1, 3,-1, 3,-1, 3,-1, 0, 1, 2, 3 }; // 16 neighbors of 3x3 group at [0,0] int n16y[16] = { -1,-1,-1,-1,-1, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3 }; red = green = blue = 0; if (size == 1) { for (ii = 0; ii < 8; ii++) // surrounding 8 pixels { qx = px + n8x[ii]; qy = py + n8y[ii]; ppix = PXMpix(E3pxm16,qx,qy); red += ppix[0]; green += ppix[1]; blue += ppix[2]; } red = red / 8; // average surrounding pixels green = green / 8; blue = blue / 8; } if (size == 2) { for (ii = 0; ii < 12; ii++) // surrounding 12 pixels { qx = px + n12x[ii]; qy = py + n12y[ii]; ppix = PXMpix(E3pxm16,qx,qy); red += ppix[0]; green += ppix[1]; blue += ppix[2]; } red = red / 12; // average surrounding pixels green = green / 12; blue = blue / 12; } if (size == 3) { for (ii = 0; ii < 16; ii++) // surrounding 16 pixels { qx = px + n16x[ii]; qy = py + n16y[ii]; ppix = PXMpix(E3pxm16,qx,qy); red += ppix[0]; green += ppix[1]; blue += ppix[2]; } red = red / 16; // average surrounding pixels green = green / 16; blue = blue / 16; } rgb[0] = red; rgb[1] = green; rgb[2] = blue; return; } // draw circles around the bad pixels void stuckpix_show() { using namespace stuckpix; int ii, px, py, size, rad; erase_topcircles(); // erase prior circles for (ii = 0; ii < Nbad; ii++) // write circles around bad pixels { px = badpix[ii].px; py = badpix[ii].py; size = badpix[ii].size; if (! size) continue; rad = 8 + 2 * size; px += size / 2; py += size / 2; add_topcircle(px,py,rad,stuckpix_color); } mwpaint2(); // update window return; } // compare two pixels and return contrast // 0 = no contrast, 1 = max. contrast (black:white) double stuckpix_getcon(int rgbA[3], int rgbB[3]) { double ff = 1.0 / 65536.0; double Rdiff, Gdiff, Bdiff, match; Rdiff = ff * abs(rgbA[0] - rgbB[0]); // 0 = perfect match Gdiff = ff * abs(rgbA[1] - rgbB[1]); // 1 = total mismatch Bdiff = ff * abs(rgbA[2] - rgbB[2]); match = (1.0 - Rdiff) * (1.0 - Gdiff) * (1.0 - Bdiff); // 1 = perfect match return (1.0 - match); } // Insert a new bad pixel block into the bad pixel table. // If the new entry touches on a previous entry, // then remove the entry with lesser contrast. void stuckpix_insert(int px, int py, int size, double pcon, int rgb[3]) { using namespace stuckpix; int ii, px1, py1, px2, py2, px3, py3, px4, py4; px1 = px - 1; // "touch" periphery py1 = py - 1; px2 = px + size + 1; py2 = py + size + 1; for (ii = 0; ii < Nbad; ii++) // loop badpix table { if (badpix[ii].size == 0) continue; // skip deleted entry px3 = badpix[ii].px; py3 = badpix[ii].py; px4 = px3 + badpix[ii].size - 1; py4 = py3 + badpix[ii].size - 1; if ((px1 >= px3 && px1 <= px4 && py1 >= py3 && py1 <= py4) || // test if old entry touches new (px2 >= px3 && px2 <= px4 && py2 >= py3 && py2 <= py4) || (px1 >= px3 && px1 <= px4 && py2 >= py3 && py2 <= py4) || (px2 >= px3 && px2 <= px4 && py1 >= py3 && py1 <= py4) || (px3 >= px1 && px3 <= px2 && py3 >= py1 && py3 <= py2) || (px4 >= px1 && px4 <= px2 && py4 >= py1 && py4 <= py2) || (px3 >= px1 && px3 <= px2 && py4 >= py1 && py4 <= py2) || (px4 >= px1 && px4 <= px2 && py3 >= py1 && py3 <= py2)) { if (size < badpix[ii].size && // if new touches a larger block, pcon < 2.0 * badpix[ii].pcon) return; // keep only if contrast much greater if (pcon < 1.0 * badpix[ii].pcon) return; // keep only if contrast is greater badpix[ii].size = 0; // delete old entry } } for (ii = 0; ii < Nbad; ii++) // loop badpix table if (badpix[ii].size == 0) break; // find first empty slot or last + 1 if (ii == maxbad) return; // table full badpix[ii].px = px; // replace overlapping entry badpix[ii].py = py; // or add to end of table badpix[ii].size = size; badpix[ii].pcon = pcon; badpix[ii].rgb[0] = rgb[0]; badpix[ii].rgb[1] = rgb[1]; badpix[ii].rgb[2] = rgb[2]; if (ii == Nbad) Nbad++; // incr. count if added to end if (Nbad == maxbad) printf("exceed %d bad pixels \n",maxbad); // report one time only return; } /**************************************************************************/ // pixel edit function - edit individual pixels #define pixed_undomaxmem (1000 * mega) // pixel edit max. memory v.11.04 #define pixed_undomaxpix (mega) // pixel edit max. pixel blocks void pixed_mousefunc(); void pixed_dopixels(int px, int py); void pixed_undo1(); void pixed_freeundo(); int pixed_RGB[3]; int pixed_mode; int pixed_radius; double pixed_kernel[200][200]; // radius <= 99 int pixed_undototpix = 0; // total undo pixel blocks int pixed_undototmem = 0; // total undo memory allocated int pixed_undoseq = 0; // undo sequence no. char pixed_undomemmessage[100]; // translated undo memory message typedef struct { // pixel block before edit int seq; // undo sequence no. uint16 npix; // no. pixels in this block uint16 px, py; // center pixel (radius org.) uint16 radius; // radius of pixel block uint16 pixel[][3]; // array of pixel[npix][3] } pixed_savepix; pixed_savepix **pixed_undopixmem = 0; // array of *pixed_savepix editfunc EFpixed; void m_pixedit(GtkWidget *, cchar *) { int pixed_dialog_event(zdialog* zd, cchar *event); char undomemmessage[100]; zfuncs::F1_help_topic = "edit_pixels"; // v.10.8 EFpixed.funcname = "pixel-edit"; EFpixed.Farea = 1; // select area ignored EFpixed.Fpara = 1; // parallel edit OK EFpixed.mousefunc = pixed_mousefunc; // mouse function if (! edit_setup(EFpixed)) return; // setup edit strncpy0(pixed_undomemmessage,ZTX("Undo Memory %d%c"),99); // translate undo memory message zdialog *zd = zdialog_new(ZTX("Edit Pixels"),mWin,Bdone,Bcancel,null); EFpixed.zd = zd; zdialog_add_widget(zd,"hbox","hbc","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labc","hbc",ZTX("color"),"space=8"); zdialog_add_widget(zd,"colorbutt","color","hbc","100|100|100"); zdialog_add_widget(zd,"label","space","hbc",0,"space=10"); zdialog_add_widget(zd,"radio","radio1","hbc",ZTX("pick"),"space=3"); zdialog_add_widget(zd,"radio","radio2","hbc",ZTX("paint"),"space=3"); zdialog_add_widget(zd,"radio","radio3","hbc",ZTX("erase"),"space=3"); zdialog_add_widget(zd,"hbox","hbbri","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vbbr1","hbbri",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vbbr2","hbbri",0,"homog|space=5"); zdialog_add_widget(zd,"label","space","hbbri",0,"space=10"); zdialog_add_widget(zd,"vbox","vbbr3","hbbri",0,"homog|space=3"); zdialog_add_widget(zd,"hbox","hbrad","vbbr1",0,"space=3"); zdialog_add_widget(zd,"label","space","hbrad",0,"expand"); zdialog_add_widget(zd,"label","labbr","hbrad",ZTX("paintbrush radius")); zdialog_add_widget(zd,"label","labtc","vbbr1",ZTX("transparency center")); zdialog_add_widget(zd,"label","labte","vbbr1",ZTX("transparency edge")); zdialog_add_widget(zd,"spin","radius","vbbr2","1|99|1|5"); zdialog_add_widget(zd,"spin","trcent","vbbr2","0|100|0.1|95"); // smaller steps v.11.10 zdialog_add_widget(zd,"spin","tredge","vbbr2","0|100|0.1|100"); zdialog_add_widget(zd,"button","undlast","vbbr3",Bundolast); zdialog_add_widget(zd,"button","undall","vbbr3",Bundoall); zdialog_add_widget(zd,"hbox","hb4","dialog"); zdialog_add_widget(zd,"label","labmem","hb4"); zdialog_help(zd,"edit_pixels"); // zdialog help topic v.11.08 zdialog_run(zd,pixed_dialog_event,"save"); // run dialog, parallel v.11.07 zdialog_send_event(zd,"radius"); // get kernel initialized snprintf(undomemmessage,99,pixed_undomemmessage,0,'%'); // stuff undo memory status zdialog_stuff(zd,"labmem",undomemmessage); pixed_RGB[0] = pixed_RGB[1] = pixed_RGB[2] = 100; // initialize color pixed_mode = 1; // mode = pick color pixed_undopixmem = 0; // no undo data pixed_undototpix = 0; pixed_undototmem = 0; pixed_undoseq = 0; takeMouse(zd,pixed_mousefunc,drawcursor); // connect mouse function v.11.03 return; } // dialog event and completion callback function int pixed_dialog_event(zdialog *zd, cchar *event) // pixedit dialog event function { char color[20]; cchar *pp; int radius, dx, dy, brad; double rad, kern, trcent, tredge; if (zd->zstat) { if (zd->zstat == 1) edit_done(EFpixed); // done else edit_cancel(EFpixed); // cancel or destroy pixed_freeundo(); // free undo memory return 0; } edit_takeover(EFpixed); // set my edit function paint_toparc(2); // v.11.04 if (strEqu(event,"focus")) // toggle mouse capture v.12.01 takeMouse(zd,pixed_mousefunc,drawcursor); zdialog_fetch(zd,"radio1",brad); // pick if (brad) pixed_mode = 1; zdialog_fetch(zd,"radio2",brad); // paint if (brad) pixed_mode = 2; zdialog_fetch(zd,"radio3",brad); // erase if (brad) pixed_mode = 3; if (strEqu(event,"color")) { zdialog_fetch(zd,"color",color,19); // get color from color wheel pp = strField(color,"|",1); if (pp) pixed_RGB[0] = atoi(pp); pp = strField(color,"|",2); if (pp) pixed_RGB[1] = atoi(pp); pp = strField(color,"|",3); if (pp) pixed_RGB[2] = atoi(pp); } if (strstr("radius trcent tredge",event)) // get new brush attributes { zdialog_fetch(zd,"radius",radius); // radius zdialog_fetch(zd,"trcent",trcent); // center transparency zdialog_fetch(zd,"tredge",tredge); // edge transparency pixed_radius = radius; trcent = 0.01 * trcent; // scale 0 ... 1 tredge = 0.01 * tredge; tredge = (1 - trcent) * (1 - tredge); tredge = 1 - tredge; trcent = sqrt(trcent); // speed up the curve tredge = sqrt(tredge); for (dy = -radius; dy <= radius; dy++) // build kernel for (dx = -radius; dx <= radius; dx++) { rad = sqrt(dx*dx + dy*dy); kern = (radius - rad) / radius; // 1 ... 0 kern = kern * (trcent - tredge) + tredge; // trcent ... tredge if (rad > radius) kern = 1; if (kern < 0) kern = 0; if (kern > 1) kern = 1; pixed_kernel[dx+radius][dy+radius] = kern; } } if (strEqu(event,"undlast")) // undo last edit (click or drag) pixed_undo1(); if (strEqu(event,"undall")) { // undo all edits edit_reset(); // v.10.3 pixed_freeundo(); } return 1; } // pixel edit mouse function void pixed_mousefunc() { static int pmxdown = 0, pmydown = 0; int px, py; char color[20]; uint16 *ppix3; zdialog *zd = EFpixed.zd; edit_takeover(EFpixed); // set my edit function if (LMclick) // left mouse click { LMclick = 0; px = Mxclick; py = Myclick; if (pixed_mode == 1) // pick new color from image { ppix3 = PXMpix(E3pxm16,px,py); pixed_RGB[0] = ppix3[0] / 256; pixed_RGB[1] = ppix3[1] / 256; pixed_RGB[2] = ppix3[2] / 256; snprintf(color,19,"%d|%d|%d",pixed_RGB[0],pixed_RGB[1],pixed_RGB[2]); if (zd) zdialog_stuff(zd,"color",color); } else { // paint or erase pixed_undoseq++; // new undo seq. no. paint_toparc(2); pixed_dopixels(px,py); // do 1 block of pixels } } if (RMclick) { RMclick = 0; paint_toparc(2); pixed_undo1(); // undo last paint v.10.11 } if (Mxdrag || Mydrag) // drag in progress { px = Mxdrag; py = Mydrag; Mxdrag = Mydrag = 0; if (Mxdown != pmxdown || Mydown != pmydown) { // new drag pixed_undoseq++; // new undo seq. no. pmxdown = Mxdown; pmydown = Mydown; } paint_toparc(2); pixed_dopixels(px,py); // do 1 block of pixels } toparcx = Mxposn - pixed_radius; // define brush outline circle toparcy = Myposn - pixed_radius; toparcw = toparch = 2 * pixed_radius; if (pixed_mode == 1) Ftoparc = 0; else Ftoparc = 1; if (Ftoparc) paint_toparc(3); return; } // paint or erase 1 block of pixels within radius of px, py void pixed_dopixels(int px, int py) { void pixed_saveundo(int px, int py); uint16 *ppix1, *ppix3; int radius, dx, dy, qx, qy, ii, ww, dist; int red, green, blue; double kern; edit_zapredo(); // delete redo copy v.10.3 pixed_saveundo(px,py); // save pixels for poss. undo v.10.12.1 red = 256 * pixed_RGB[0]; green = 256 * pixed_RGB[1]; blue = 256 * pixed_RGB[2]; radius = pixed_radius; for (dy = -radius; dy <= radius; dy++) // loop surrounding block of pixels for (dx = -radius; dx <= radius; dx++) { qx = px + dx; qy = py + dy; if (qx < 0 || qx > E3ww-1) continue; if (qy < 0 || qy > E3hh-1) continue; if (Factivearea) { // select area active v.10.11 ii = qy * E3ww + qx; dist = sa_pixmap[ii]; if (! dist) continue; // pixel is outside area } kern = pixed_kernel[dx+radius][dy+radius]; ppix1 = PXMpix(E1pxm16,qx,qy); // original image pixel ppix3 = PXMpix(E3pxm16,qx,qy); // edited image pixel if (pixed_mode == 2) // color pixels transparently { ppix3[0] = (1.0 - kern) * red + kern * ppix3[0]; ppix3[1] = (1.0 - kern) * green + kern * ppix3[1]; ppix3[2] = (1.0 - kern) * blue + kern * ppix3[2]; CEF->Fmod = 1; } if (pixed_mode == 3) // restore org. pixels transparently { ppix3[0] = (1.0 - kern) * ppix1[0] + kern * ppix3[0]; ppix3[1] = (1.0 - kern) * ppix1[1] + kern * ppix3[1]; ppix3[2] = (1.0 - kern) * ppix1[2] + kern * ppix3[2]; } } px = px - radius - 1; py = py - radius - 1; ww = 2 * radius + 3; mwpaint3(px,py,ww,ww); // v.10.11 return; } // save 1 block of pixels for possible undo void pixed_saveundo(int px, int py) { int npix, radius, dx, dy; uint16 *ppix3; pixed_savepix *ppixsave1; char undomemmessage[100]; int mempercent; static int ppercent = 0; zdialog *zd = EFpixed.zd; if (! pixed_undopixmem) // first call { pixed_undopixmem = (pixed_savepix **) zmalloc(pixed_undomaxpix * sizeof(void *),"pixed"); pixed_undototpix = 0; pixed_undototmem = 0; } if (pixed_undototmem > pixed_undomaxmem) { zmessageACK(mWin,ZTX("Undo memory limit has been reached. \n" "Save work with [done], then resume editing.")); Mdrag = 0; return; } radius = pixed_radius; npix = 0; for (dy = -radius; dy <= radius; dy++) // count pixels in block for (dx = -radius; dx <= radius; dx++) { if (px + dx < 0 || px + dx > E3ww-1) continue; if (py + dy < 0 || py + dy > E3hh-1) continue; npix++; } ppixsave1 = (pixed_savepix *) zmalloc(npix*6+12,"pixed"); // allocate memory for block pixed_undopixmem[pixed_undototpix] = ppixsave1; pixed_undototpix += 1; pixed_undototmem += npix * 6 + 12; ppixsave1->seq = pixed_undoseq; // save pixel block poop ppixsave1->npix = npix; ppixsave1->px = px; ppixsave1->py = py; ppixsave1->radius = radius; npix = 0; for (dy = -radius; dy <= radius; dy++) // save pixels in block for (dx = -radius; dx <= radius; dx++) { if (px + dx < 0 || px + dx > E3ww-1) continue; if (py + dy < 0 || py + dy > E3hh-1) continue; ppix3 = PXMpix(E3pxm16,(px+dx),(py+dy)); // edited image pixel ppixsave1->pixel[npix][0] = ppix3[0]; ppixsave1->pixel[npix][1] = ppix3[1]; ppixsave1->pixel[npix][2] = ppix3[2]; npix++; } mempercent = int(100.0 * pixed_undototmem / pixed_undomaxmem); // update undo memory status if (mempercent != ppercent) { ppercent = mempercent; snprintf(undomemmessage,99,pixed_undomemmessage,mempercent,'%'); zdialog_stuff(zd,"labmem",undomemmessage); } return; } // undo last undo sequence number void pixed_undo1() { int pindex, npix, radius, mempercent; int ww, px, py, dx, dy; uint16 *ppix3; pixed_savepix *ppixsave1; char undomemmessage[100]; zdialog *zd = EFpixed.zd; pindex = pixed_undototpix; while (pindex > 0) { --pindex; ppixsave1 = pixed_undopixmem[pindex]; if (ppixsave1->seq != pixed_undoseq) break; px = ppixsave1->px; py = ppixsave1->py; radius = ppixsave1->radius; npix = 0; for (dy = -radius; dy <= radius; dy++) for (dx = -radius; dx <= radius; dx++) { if (px + dx < 0 || px + dx > E3ww-1) continue; if (py + dy < 0 || py + dy > E3hh-1) continue; ppix3 = PXMpix(E3pxm16,(px+dx),(py+dy)); ppix3[0] = ppixsave1->pixel[npix][0]; ppix3[1] = ppixsave1->pixel[npix][1]; ppix3[2] = ppixsave1->pixel[npix][2]; npix++; } px = px - radius - 1; // v.10.12 py = py - radius - 1; ww = 2 * radius + 3; mwpaint3(px,py,ww,ww); npix = ppixsave1->npix; zfree(ppixsave1); pixed_undopixmem[pindex] = 0; pixed_undototmem -= (npix * 6 + 12); --pixed_undototpix; } if (pixed_undoseq > 0) --pixed_undoseq; mempercent = int(100.0 * pixed_undototmem / pixed_undomaxmem); // update undo memory status snprintf(undomemmessage,99,pixed_undomemmessage,mempercent,'%'); zdialog_stuff(zd,"labmem",undomemmessage); return; } // free all undo memory void pixed_freeundo() { int pindex; pixed_savepix *ppixsave1; char undomemmessage[100]; zdialog *zd = EFpixed.zd; pindex = pixed_undototpix; while (pindex > 0) { --pindex; ppixsave1 = pixed_undopixmem[pindex]; zfree(ppixsave1); } if (pixed_undopixmem) zfree(pixed_undopixmem); pixed_undopixmem = 0; pixed_undoseq = 0; pixed_undototpix = 0; pixed_undototmem = 0; if (zd) { snprintf(undomemmessage,99,pixed_undomemmessage,0,'%'); // undo memory = 0% zdialog_stuff(zd,"labmem",undomemmessage); } return; } fotoxx-12.01.2/desktop0000644000175000017500000000043411701011017013226 0ustar micomico[Desktop Entry] Name=fotoxx GenericName=Photo Editor Comment=Edit photos and manage collections Categories=Graphics;Photography; Type=Application Terminal=false MimeType=image/bmp;image/gif;image/tiff;image/jpeg;image/png; Exec=/usr/bin/fotoxx Icon=/usr/share/fotoxx/icons/fotoxx.png fotoxx-12.01.2/f.file.cc0000664000175000017500000021004711701011017013311 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // disable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image edit - file menu functions ***************************************************************************/ // display image gallery (thumbnails) in a separate window void m_gallery(GtkWidget *, cchar *) { zfuncs::F1_help_topic = "navigation"; if (curr_file) image_gallery(0,"paint1",curr_file_posn,m_gallery2,mWin); // overlay main window v.10.9 else { char *pp = getcwd(command,ccc); // v.11.09 if (pp) { image_gallery(pp,"init",0,m_gallery2,mWin); // use current directory v.11.04 image_gallery(0,"paint1"); } curr_file_posn = 0; // v.11.05 } return; } // clicked thumbnail will call this function void m_gallery2(int Nth, int button) { char *file; zfuncs::F1_help_topic = "navigation"; // v.11.08 if (Nth == -1) return; // gallery window closed file = image_gallery(0,"find",Nth); if (! file) return; if (edit_coll_name && button == 3) // right-click, pass to edit collection { // v.11.11 edit_coll_popmenu(null,file); zfree(file); return; } f_open(file,1,Nth); // clicked file = current file zfree(file); gtk_window_present(MWIN); // bring main window to front v.10.12 return; } /**************************************************************************/ // start a new parallel instance of fotoxx // move my window to right half of desktop // start new instance to open in left half void m_clone1(GtkWidget *, cchar *) { GdkScreen *screen; int ww, hh, err; zfuncs::F1_help_topic = "clone"; // v.10.8 screen = gdk_screen_get_default(); // get desktop screen size ww = gdk_screen_get_width(screen); hh = gdk_screen_get_height(screen); ww = ww / 2 - 20; hh = hh - 50; gdk_window_move_resize(mWin->window,ww+20,10,ww,hh); // move my window to right half snprintf(command,ccc,"fotoxx -clone1 -lang %s",zfuncs::zlang); // start new instance if (curr_file) strncatv(command,ccc," \"",curr_file,"\"",null); strcat(command," &"); err = system(command); if (err) printf("error: %s \n",wstrerror(err)); return; } // start a new parallel instance of fotoxx // new window is slightly down and right from old window void m_clone2(GtkWidget *, cchar *) // new v.11.07 { int xx, yy, ww, hh, err; zfuncs::F1_help_topic = "clone"; gtk_window_get_position(MWIN,&xx,&yy); // get window position and size gtk_window_get_size(MWIN,&ww,&hh); snprintf(command,ccc,"fotoxx -clone2 %d %d %d %d -lang %s",xx,yy,ww,hh,zfuncs::zlang); if (curr_file) strncatv(command,ccc," \"",curr_file,"\"",null); strcat(command," &"); // start new instance and pass err = system(command); // my window posn and size if (err) printf("error: %s \n",wstrerror(err)); return; } /**************************************************************************/ // open file menu function void m_open(GtkWidget *, cchar *) { zfuncs::F1_help_topic = "open_image_file"; f_open(null,1); return; } /**************************************************************************/ // open drag-drop file void m_open_drag(int x, int y, char *file) { zfuncs::F1_help_topic = "open_image_file"; f_open(file,1); return; } /**************************************************************************/ // open a new file in a new parallel instance of fotoxx // new window is slightly down and right from old window void m_open_newin(GtkWidget *, cchar *) // new v.11.07 { int xx, yy, ww, hh, err; char *file; zfuncs::F1_help_topic = "open_image_file"; file = zgetfile1(ZTX("Open Image File"),"open",curr_file); // dialog to get filespec if (! file) return; // canceled if (image_file_type(file) != 2) return; // not a supported image file v.11.05 gtk_window_get_position(MWIN,&xx,&yy); // get window position and size gtk_window_get_size(MWIN,&ww,&hh); snprintf(command,ccc,"fotoxx -c2 %d %d %d %d -l %s",xx,yy,ww,hh,zfuncs::zlang); strncatv(command,ccc," \"",file,"\"",null); strcat(command," &"); // start new instance and pass err = system(command); // my window posn and size if (err) printf("error: %s \n",wstrerror(err)); return; } /**************************************************************************/ // open the previous file opened (not the same as toolbar [prev] button) // repeated use will cycle back and forth between two most recent files void m_previous(GtkWidget *, cchar *) { int ii, jj, err; zfuncs::F1_help_topic = "open_previous_file"; if (! menulock(1)) return; // v.11.11 menulock(0); if (mod_keep()) return; // v.11.06 if (curr_file) jj = 1; // 2nd most recent file v.11.08 else jj = 0; // no current file, use most recent for (ii = jj; ii < Nrecentfiles; ii++) { if (! recentfiles[ii]) continue; // bugfix v.12.01 err = f_open(recentfiles[ii],1); // get first one that is still there if (! err) return; } return; } /**************************************************************************/ // open an image file from the list of recent image files void m_recent(GtkWidget *, cchar *) // overhauled v.11.01 { void recentfile2(int Nth, int button); int ii, jj, typ; FILE *fid; zfuncs::F1_help_topic = "open_recent_file"; if (! menulock(1)) return; menulock(0); if (mod_keep()) return; // v.11.11 fid = fopen(recentfiles_file,"w"); // revalidate list of recent files if (! fid) return; // and update disk file for (ii = jj = 0; ii < Nrecentfiles; ii++) { if (! recentfiles[ii]) continue; // improved v.11.11 typ = image_file_type(recentfiles[ii]); if (typ != 2) { zfree(recentfiles[ii]); recentfiles[ii] = 0; continue; } if (jj < ii) { recentfiles[jj] = recentfiles[ii]; recentfiles[ii] = 0; // bugfix v.11.11.1 } fprintf(fid,"%s \n",recentfiles[jj]); jj++; } fclose(fid); if (! jj) return; // no files found image_gallery(recentfiles_file,"initF",0,recentfile2,mWin); // generate gallery of recent files if (image_navi::galleryname) zfree(image_navi::galleryname); image_navi::galleryname = strdupz("Recent Files",0,"recent files"); // v.12.01 image_gallery(0,"paint1",0); // show new image gallery window return; } // clicked thumbnail will call this function void recentfile2(int Nth, int button) { char *file; if (Nth == -1) { // gallery window cancelled if (curr_file) image_gallery(curr_file,"init"); // reset gallery from current file v.11.05 return; } file = image_gallery(0,"find",Nth); if (! file) return; image_gallery(file,"init"); // initz. gallery from chosen file v.11.05 image_gallery(0,"close"); // close the gallery f_open(file,1); // open the file zfree(file); return; } // add a file to the list of recent files void add_recent_file(cchar *file) { int ii; for (ii = 0; ii < Nrecentfiles-1 && recentfiles[ii]; ii++) // find file in recent list if (strEqu(file,recentfiles[ii])) break; // (or find last entry in list) if (recentfiles[ii]) zfree(recentfiles[ii]); // free this slot in list for (; ii > 0; ii--) recentfiles[ii] = recentfiles[ii-1]; // move list UP to fill hole recentfiles[0] = strdupz(file); // current file >> first in list return; } /**************************************************************************/ // Open a file and initialize PXM bitmap. // If flock and menu is locked, do nothing and return. // Otherwise open the file and display in main window. // If Nth matches the file position in current file set, curr_file_posn // will be set to Nth, otherwise it is searched and set correctly // (a file can be present multiple times in a collection set). // If fkeepundo is ON, the edit undo image stack is not purged: current // edits are kept after opening the new file (used by m_saveas()). // Returns: 0 = OK, +N = error. int f_open(cchar *filespec, int flock, int Nth, int fkeepundo) { PXM *temp8; int err, cc, yn, fposn, nfiles, nimages; char *pp, *file, *rawfile, titlebar[250]; char fname[100], fdirk[100]; int Gwarn = 0, Gnew = 0; if (flock && Fmenulock) { zmessageACK(mWin,ZTX("prior function still active")); // v.11.06 return 1; } if (mod_keep()) return 2; // unsaved edits if (image_navi::gallerytype > 1) Gwarn = 1; // warn if discarding search or pp = image_navi::galleryname; // collection type gallery if (pp && strEqu(pp,"Recent Files")) Gwarn = 0; if (filespec) file = strdupz(filespec,0,"f_open"); // use passed filespec else { if (Gwarn) { // warn user, gallery will be discarded yn = zmessageYN(mWin,Bdiscard,image_navi::galleryname); if (! yn) return 6; // do not discard v.11.09 Gnew = 1; // flag, new gallery needed } pp = curr_file; if (! pp) pp = curr_dirk; file = zgetfile1(ZTX("Open Image File"),"open",pp); // dialog to get filespec if (! file) return 3; // canceled } if (image_file_type(file) != 2) // not a supported image file type { pp = strrchr(file,'.'); if (! pp || strlen(pp) != 4 || ! strcasestr(RAWfiles,pp)) { // check if a RAW file extension zfree(file); // v.11.09 return 3; // no } rawfile = file; // v.11.09 file = strdupz(rawfile,5,"f_open"); // filename.raw >> filename.tiff pp = file + (pp - rawfile); strcpy(pp,".tiff"); snprintf(command,ccc,"ufraw-batch --wb=camera --out-type=tiff " // convert RAW file to tiff-16 v.11.09 "--out-depth=16 --overwrite " "--output=\"%s\" \"%s\" ",file,rawfile); err = system(command); if (err) { zmessageACK(mWin,wstrerror(err)); // failed, clean up zfree(file); zfree(rawfile); return 3; } zfree(rawfile); // tiff file will be opened } temp8 = f_load(file,8); // load image as PXM-8 pixmap if (! temp8) { zfree(file); // bad image return 5; } // menulock() removed v.11.11 free_resources(fkeepundo); // free resources for old image file if (curr_file) zfree(curr_file); // current image filespec curr_file = strdupz(file,8,"curr_file"); zfree(file); if (curr_dirk) zfree(curr_dirk); // set current directory curr_dirk = strdupz(curr_file,0,"curr_dirk"); // for new current file pp = strrchr(curr_dirk,'/'); *pp = 0; err = chdir(curr_dirk); Fpxm8 = temp8; // pixmap for current image Fww = Fpxm8->ww; Fhh = Fpxm8->hh; strcpy(curr_file_type,f_load_type); // set curr_file_xxx from f_load_xxx curr_file_bpc = f_load_bpc; curr_file_size = f_load_size; fposn = image_gallery_position(curr_file,Nth); // file position in gallery list if (fposn < 0 || Gnew) { // not there or break current gallery v.11.09 image_gallery(curr_file,"init",0,m_gallery2); // generate new gallery list v.12.01 fposn = image_gallery_position(curr_file,0); // position and count in gallery list image_gallery(0,"paint2",fposn); // refresh gallery window if active v.11.07 } nfiles = image_navi::nfiles; // total gallery files (incl. directories) nimages = image_navi::nimages; // total image files v.11.05 curr_file_posn = fposn; // keep track of file position curr_file_count = image_navi::nimages; // and image gallery count add_recent_file(curr_file); // first in recent files list Fzoom = 0; // zoom level = fit window zoomx = zoomy = 0; // no zoom center pp = (char *) strrchr(curr_file,'/'); strncpy0(fname,pp+1,99); // file name cc = pp - curr_file; if (cc < 99) strncpy0(fdirk,curr_file,cc+2); // get dirk/path/ if short enough else { strncpy(fdirk,curr_file,96); // or use /dirk/path... strcpy(fdirk+95,"..."); } fposn = fposn + 1 - nfiles + nimages; // position among images, 1-based snprintf(titlebar,250,"%s %d/%d %s %s", // window title bar fversion,fposn,curr_file_count,fname,fdirk); gtk_window_set_title(MWIN,titlebar); mwpaint1(); // immediate paint v.11.11 gtk_window_present(MWIN); // bring main window to front v.11.04 zmainloop(); if (zdrename) m_rename(0,0); // update active rename dialog if (zdexifview) info_view(0); // " EXIF/IPTC view window v.10.2 if (zdexifedit) m_info_edit(0,0); // " EXIF/IPTC edit window v.10.11 if (zdedittags) m_edit_tags(0,0); // " edit tags dialog if (zdeditcctext) m_edit_cctext(0,0); // " edit comments dialog v.10.10 curr_image_time = get_seconds(); // mark time of file load v.11.07 return 0; } /**************************************************************************/ // open previous or next file in current gallery list void m_prev(GtkWidget *, cchar *menu) { int err, Nth; if (menu) zfuncs::F1_help_topic = "open_image_file"; if (Fmenulock) return; if (mod_keep()) return; if (! curr_file) return; for (Nth = curr_file_posn-1; Nth >= 0; Nth--) // v.11.05 { char *pp = image_gallery(0,"find",Nth); if (! pp) continue; err = f_open(pp,1,Nth); zfree(pp); if (! err) break; } return; } void m_next(GtkWidget *, cchar *menu) { int err, Nth; int nfiles = image_navi::nfiles; if (menu) zfuncs::F1_help_topic = "open_image_file"; if (Fmenulock) return; if (mod_keep()) return; if (! curr_file) return; for (Nth = curr_file_posn+1; Nth < nfiles; Nth++) // v.11.05 { char *pp = image_gallery(0,"find",Nth); if (! pp) continue; err = f_open(pp,1,Nth); zfree(pp); if (! err) break; } return; } /**************************************************************************/ // save (modified) image to same file void m_save(GtkWidget *, cchar *menu) { int Fwarn = 1, zstat, suppress; char *pp; zdialog *zd; cchar *warn_message = ZTX("Overwrite original file?"); cchar *suppress_message = ZTX("Do not warn again"); if (! curr_file) return; if (is_syncbusy()) return; // v.11.11 if (menu && strNeq(menu,"nowarn")) // don't change help topic v.11.11 zfuncs::F1_help_topic = "save_file"; if (Fwarnoverwrite) { // warn if overwrite original v.11.10 pp = strrchr(curr_file,'/'); if (! pp) return; pp = strstr(pp,".v"); // look for version notation .vNN if (pp && pp[2] >= '0' && pp[2] <= '9' && pp[3] >= '0' && pp[3] <= '9') Fwarn = 0; // found, file not original if (Fwarn && ! (menu && strEqu(menu,"nowarn"))) { // no warn if KB rotate save v.11.11 zd = zdialog_new(ZTX("Warning"),mWin,Bproceed,Bcancel,null); zdialog_add_widget(zd,"label","lab1","dialog",warn_message,"space=5"); zdialog_add_widget(zd,"check","suppress","dialog",suppress_message,"space=5"); zdialog_run(zd); zstat = zdialog_wait(zd); zdialog_fetch(zd,"suppress",suppress); zdialog_free(zd); if (suppress) { Fwarnoverwrite = 0; save_params(); } if (zstat != 1) return; } } strcpy(jpeg_quality,def_jpeg_quality); // default jpeg save quality if (strEqu(curr_file_type,"other")) // if gif, bmp, etc. use jpg v.11.03 strcpy(curr_file_type,"jpg"); f_save(curr_file,curr_file_type,curr_file_bpc); // save file strcpy(curr_file_type,f_save_type); // update curr_file_xxx from f_save_xxx curr_file_size = f_save_size; return; } /**************************************************************************/ // save (modified) image to new version of same file // - no confirmation of overwrite. void m_savevers(GtkWidget *, cchar *) // new v.11.07 { char *outfile, *pext, *pvers; cchar *delim; int ii, err, nvers; struct stat fstat; if (! curr_file) return; if (is_syncbusy()) return; // v.11.11 zfuncs::F1_help_topic = "save_file"; strcpy(jpeg_quality,def_jpeg_quality); // default jpeg save quality outfile = strdupz(curr_file,12,"curr_file"); // output file name TBD pext = strrchr(outfile,'/'); // find file .ext if (pext) pext = strrchr(pext,'.'); if (pext && strlen(pext) > 5) pext = 0; if (! pext) pext = outfile + strlen(outfile); // unknown, none pvers = pext - 4; // find curr. version: filename.vNN.ext if (! strnEqu(pvers,".v",2)) nvers = 0; else { err = convSI(pvers+2,nvers,1,98,&delim); // convert NN to number 1-98 if (err > 1) nvers = 0; // conversion error if (delim != pext) nvers = 0; // check format is .vNN } if (nvers == 0) { // no version in file name pvers = pext; pext += 4; memmove(pext,pvers,6); // make space for .vNN before .ext strncpy(pvers,".vNN",4); } for (ii = 98; ii > nvers; ii--) // look for higher file versions { pvers[2] = ii/10 + '0'; // build filename.vNN.ext pvers[3] = ii - 10 * (ii/10) + '0'; err = stat(outfile,&fstat); if (! err) break; } ii++; // use next version 1-99 nvers = ii; pvers[2] = ii/10 + '0'; // build filename.vNN.ext pvers[3] = ii - 10 * (ii/10) + '0'; f_save(outfile,curr_file_type,curr_file_bpc); // save file (fails at 99 versions) load_fileinfo(outfile); // update search index file update_search_index(outfile); image_gallery(outfile,"init"); // update gallery image_gallery(outfile,"paint2",-1); // refresh gallery window if active f_open(outfile,1,0,1); // new version = current file v.11.11.1 zfree(outfile); return; } /**************************************************************************/ // save (modified) image to new file // confirm if overwrite existing file GtkWidget *saveas_fchooser; void m_saveas(GtkWidget *, cchar *menu) { void saveas_radiobutt(void *, int button); void saveas_kbkey(void *, GdkEventKey *event); GtkWidget *fdialog, *hbox; GtkWidget *tiff8, *tiff16, *jpeg, *png, *jqlab, *jqval; GtkWidget *makecurrent; char *outfile = 0, *outfile2 = 0, *pext; int ii, err, yn, bpc, status, mkcurr = 0; struct stat fstat; cchar *type; cchar *exts = ".jpg.JPG.jpeg.JPEG.tif.TIF.tiff.TIFF.png.PNG"; if (! curr_file) return; if (is_syncbusy()) return; // v.11.11 if (menu) zfuncs::F1_help_topic = "save_file"; fdialog = gtk_dialog_new_with_buttons(ZTX("Save File"), // build file save dialog MWIN, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, null); gtk_window_set_default_size(GTK_WINDOW(fdialog),600,500); saveas_fchooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_SAVE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(fdialog)->vbox),saveas_fchooser); // set_filename() should select the file but does nothing GTK bug ? v.10.9.1 ///// // set_current_name() puts file name in input box, but does not select the file gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(saveas_fchooser),curr_file); char *fname = strrchr(curr_file,'/') + 1; gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(saveas_fchooser),fname); hbox = gtk_hbox_new(0,0); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(fdialog)->vbox),hbox); gtk_box_set_child_packing(GTK_BOX(GTK_DIALOG(fdialog)->vbox),hbox,0,0,10,GTK_PACK_END); tiff8 = gtk_radio_button_new_with_label(null,"tiff-8"); tiff16 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(tiff8),"tiff-16"); png = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(tiff8),"png"); jpeg = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(tiff8),"jpeg"); jqlab = gtk_label_new(ZTX("quality")); jqval = gtk_entry_new(); makecurrent = gtk_check_button_new_with_label(ZTX("make current")); gtk_entry_set_width_chars(GTK_ENTRY(jqval),2); gtk_box_pack_start(GTK_BOX(hbox),tiff8,0,0,5); // (o) tiff8 (o) tiff16 (o) png gtk_box_pack_start(GTK_BOX(hbox),tiff16,0,0,5); gtk_box_pack_start(GTK_BOX(hbox),png,0,0,5); gtk_box_pack_start(GTK_BOX(hbox),jpeg,0,0,5); // (o) jpeg jpeg quality [__] gtk_box_pack_start(GTK_BOX(hbox),jqlab,0,0,0); gtk_box_pack_start(GTK_BOX(hbox),jqval,0,0,3); gtk_box_pack_end(GTK_BOX(hbox),makecurrent,0,0,3); // [x] make current G_SIGNAL(tiff8,"pressed",saveas_radiobutt,0); // connect file type radio buttons G_SIGNAL(tiff16,"pressed",saveas_radiobutt,1); // to handler function G_SIGNAL(png,"pressed",saveas_radiobutt,2); G_SIGNAL(jpeg,"pressed",saveas_radiobutt,3); G_SIGNAL(fdialog,"key-release-event",saveas_kbkey,0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(jpeg),1); // set default file type = jpeg gtk_entry_set_text(GTK_ENTRY(jqval),def_jpeg_quality); // default jpeg save quality if (strEqu(curr_file_type,"png")) // default matches file type gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(png),1); // if png or tiff if (strEqu(curr_file_type,"tiff")) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tiff8),1); if (curr_file_bpc == 16) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tiff16),1); dialog_run: gtk_widget_show_all(fdialog); // run dialog status = gtk_dialog_run(GTK_DIALOG(fdialog)); if (status != GTK_RESPONSE_ACCEPT) { // user cancelled gtk_widget_destroy(fdialog); return; } outfile2 = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(saveas_fchooser)); if (! outfile2) goto dialog_run; outfile = strdupz(outfile2,12,"curr_file"); // add space for possible .vNN and .ext g_free(outfile2); type = "jpg"; // default output type bpc = 8; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(png))) type = "png"; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tiff8))) type = "tif"; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tiff16))) { type = "tif"; bpc = 16; } if (strEqu(type,"jpg")) { // set jpeg save quality ii = atoi(gtk_entry_get_text(GTK_ENTRY(jqval))); if (ii < 1 || ii > 100) { zmessageACK(mWin,ZTX("jpeg quality must be 1-100")); goto dialog_run; } sprintf(jpeg_quality,"%d",ii); } pext = strrchr(outfile,'/'); // locate file .ext if (pext) pext = strrchr(pext,'.'); if (pext && ! strstr(exts,pext)) pext = 0; // keep .ext and append new v.10.12.1 if (! pext) { pext = outfile + strlen(outfile); // missing, add one strcpy(pext,"."); strcpy(pext+1,type); } if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(makecurrent))) // make saved file the current file? mkcurr = 1; gtk_widget_destroy(fdialog); // kill dialog /// gtk bug, can crash err = stat(outfile,&fstat); // check if file exists if (! err) { yn = zmessageYN(mWin,ZTX("Overwrite file? \n %s"),outfile); // confirm overwrite if (! yn) { zfree(outfile); return; } } f_save(outfile,type,bpc); // save the file load_fileinfo(outfile); // update search index file v.11.07 update_search_index(outfile); if (mkcurr) // use the saved file as new current file f_open(outfile,1,0,1); // and retain edit history v.11.07 else if (samedirk(outfile,curr_file)) { // if same directory, update gallery image_gallery(outfile,"init"); // add new file to gallery image_gallery(0,"paint2",curr_file_posn); // refresh if active, keep position } zfree(outfile); return; } // set dialog file type from user selection of file type radio button void saveas_radiobutt(void *, int button) // v.9.4 { cchar *filetypes[4] = { ".tif", ".tif", ".png", ".jpg" }; // v.10.9 char *filespec; char *filename, *pp; filespec = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(saveas_fchooser)); if (! filespec) return; filename = strrchr(filespec,'/'); if (! filename) return; filename = strdupz(filename+1,6,"saveas"); pp = strrchr(filename,'.'); if (! pp || strlen(pp) > 5) pp = filename + strlen(filename); // bugfix v.10.9.1 strcpy(pp,filetypes[button]); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(saveas_fchooser),filename); gtk_widget_show_all(saveas_fchooser); zfree(filename); g_free(filespec); // bugfix, leak v.10.9.1 return; } // response function for KB key release void saveas_kbkey(void *, GdkEventKey *event) // v.10.5 { if (event->keyval == GDK_F1) showz_userguide(zfuncs::F1_help_topic); return; } /**************************************************************************/ // set new image zoom level or magnification // zoom: "in" zoom in in steps // "out" zoom out in steps // "fit" zoom out to fit window // "100" toggle 100% and fit window void m_zoom(GtkWidget *, cchar *zoom) { int iww, ihh, Dww, Dhh; double scalew, scaleh, fitscale, fzoom2; static double ratio = 0; if (! ratio) { if (! zoomratio || strEqu(zoomratio,"undefined")) // bugfix 12.01.1 zoomratio = strdupz("1.4142136"); convSD(zoomratio,ratio); if (ratio < 1.1 || ratio > 2.0) ratio = 1.4142136; } Dww = drWin->allocation.width; // drawing window size Dhh = drWin->allocation.height; if (E3pxm16) { // bugfix iww = E3ww; ihh = E3hh; } else { iww = Fww; ihh = Fhh; } if (iww > Dww || ihh > Dhh) { // get window fit scale scalew = 1.0 * Dww / iww; scaleh = 1.0 * Dhh / ihh; if (scalew < scaleh) fitscale = scalew; else fitscale = scaleh; // window/image, < 1.0 } else fitscale = 1.0; // if image < window use 100% if (strEqu(zoom,"Zoom+")) zoom = "in"; // toolbar button, + = zoom in if (strEqu(zoom,"Zoom-")) zoom = "fit"; // - = fit window if (strstr("in out",zoom)) // zoom in or out { convSD(zoomratio,ratio); // zoom ratio, string to double if (! Fzoom) Fzoom = fitscale; // current zoom scale for (fzoom2 = 0.125; fzoom2 < 4.0; fzoom2 *= ratio) // find nearest natural ratio if (Fzoom < fzoom2 * sqrt(ratio)) break; if (strEqu(zoom,"out")) ratio = 1.0 / ratio; // zoom out, make image smaller Fzoom = fzoom2 * ratio; if (Fzoom > 0.124 && Fzoom < 0.126) Fzoom = 0.125; if (Fzoom > 0.24 && Fzoom < 0.26) Fzoom = 0.25; if (Fzoom > 0.49 && Fzoom < 0.51) Fzoom = 0.50; if (Fzoom > 0.99 && Fzoom < 1.01) Fzoom = 1.00; if (Fzoom > 1.99 && Fzoom < 2.01) Fzoom = 2.00; if (Fzoom > 3.99) Fzoom = 4.0; if (Fzoom < fitscale) Fzoom = 0; // image < window } if (strEqu(zoom,"fit")) Fzoom = 0; // zoom to fit window if (strEqu(zoom,"100")) { if (Fzoom != 0) Fzoom = 0; // toggle 100% and fit window else Fzoom = 1; } if (! Fzoom) zoomx = zoomy = 0; // no req. zoom center mwpaint2(); // refresh window curr_image_time = get_seconds(); // mark time of image change v.11.07 return; } /**************************************************************************/ // create a new blank image with desired background color void m_create(GtkWidget *, cchar *) // v.11.01 { int create_dialog_event(zdialog *zd, cchar *event); zdialog *zd; int zstat; char *prev_file = 0; zfuncs::F1_help_topic = "create"; if (is_syncbusy()) return; // v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // lock menus if (curr_file) prev_file = strdupz(curr_file); // file name [___________________________] .jpg // v.11.05 // width [____] height [____] (pixels) // color [____] zd = zdialog_new(ZTX("Create Blank Image"),mWin,Bdone,Bcancel,null); zdialog_add_widget(zd,"hbox","hbf","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labf","hbf",ZTX("file name"),"space=3"); zdialog_add_widget(zd,"entry","file","hbf","no-name","space=3|expand"); zdialog_add_widget(zd,"label","ftype","hbf",".jpg "); zdialog_add_widget(zd,"hbox","hbz","dialog",0,"space=5"); zdialog_add_widget(zd,"label","space","hbz",0,"space=3"); zdialog_add_widget(zd,"label","labw","hbz",ZTX("width")); zdialog_add_widget(zd,"spin","width","hbz","100|9999|1|1600"); zdialog_add_widget(zd,"label","space","hbz",0,"space=5"); zdialog_add_widget(zd,"label","labh","hbz",ZTX("height")); zdialog_add_widget(zd,"spin","height","hbz","100|9999|1|1000"); zdialog_add_widget(zd,"label","space","hbz",0,"space=3"); zdialog_add_widget(zd,"label","labp","hbz","(pixels) "); zdialog_add_widget(zd,"hbox","hbc","dialog",0,"space=5"); zdialog_add_widget(zd,"label","space","hbc",0,"space=3"); zdialog_add_widget(zd,"label","labc","hbc",ZTX("color")); zdialog_add_widget(zd,"colorbutt","color","hbc","200|200|200"); create_dialog_event(zd,"init"); zdialog_help(zd,"create"); // zdialog help topic v.11.08 zdialog_run(zd,create_dialog_event); zstat = zdialog_wait(zd); zdialog_free(zd); if (zstat != 1) { // cancel if (prev_file) { f_open(prev_file,0); // back to previous file zfree(prev_file); mwpaint2(); } } menulock(0); return; } // dialog event and completion function int create_dialog_event(zdialog *zd, cchar *event) // overhauled v.11.05 { char color[20], fname[100], *filespec; cchar *pp; int fncc, ww, hh, err; static int red, green, blue; uint8 *pixel; struct stat statb; if (zd->zstat != 1) return 0; // [done] zdialog_fetch(zd,"file",fname,100); // get new file name strTrim2(fname); if (*fname <= ' ') strcpy(fname,"no-name"); fncc = strlen(fname); filespec = strdupz(curr_dirk,fncc+8,"create"); // make full filespec strcat(filespec,"/"); strcat(filespec,fname); strcat(filespec,".jpg"); err = stat(filespec,&statb); // make sure it does not exist if (! err) { zmessageACK(mWin,"file already exists"); zfree(filespec); zd->zstat = 0; // keep dialog alive return 0; } if (curr_file) zfree(curr_file); // stop copy of metadata from old file curr_file = 0; // bugfix v.11.08 zdialog_fetch(zd,"width",ww); // get image dimensions zdialog_fetch(zd,"height",hh); zdialog_fetch(zd,"color",color,19); // get image color pp = strField(color,"|",1); if (pp) red = atoi(pp); pp = strField(color,"|",2); if (pp) green = atoi(pp); pp = strField(color,"|",3); if (pp) blue = atoi(pp); mutex_lock(&Fpixmap_lock); // lock pixmaps PXM_free(Fpxm8); // create new PXM image Fpxm8 = PXM_make(ww,hh,8); Fww = Fpxm8->ww; Fhh = Fpxm8->hh; pixel = (uint8 *) Fpxm8->bmp; for (int ii = 0; ii < ww * hh * 3; ii += 3) { pixel[ii] = red; pixel[ii+1] = green; pixel[ii+2] = blue; } mutex_unlock(&Fpixmap_lock); strcpy(jpeg_quality,def_jpeg_quality); err = f_save(filespec,"jpg",8); // save to disk if (err) { zmessageACK(mWin,"cannot save file"); zfree(filespec); return 0; } f_open(filespec,0); // make it the current file zfree(filespec); return 0; } /**************************************************************************/ // Delete image file - move curr_file to trash. // Use new Linux standard trash function. // v.10.8 // If not available, revert to Desktop folder for fotoxx trash. void m_trash(GtkWidget *, cchar *) { int err, yn; char *pp, trashdir[200]; struct stat trstat; static int gstat, trashworks = 1; // assume it works until otherwise GError *gerror = 0; GFile *gfile = 0; cchar *gerrmess = ZTX("Linux standard trash is not supported. \n" "Desktop trash folder will be created."); zfuncs::F1_help_topic = "trash"; // v.10.8 if (! curr_file) return; // nothing to trash if (is_syncbusy()) return; // v.11.11 if (! menulock(1)) return; // check lock but leave unlocked menulock(0); err = stat(curr_file,&trstat); // get file status if (err) { zmessLogACK(mWin,strerror(errno)); return; } if (! (trstat.st_mode & S_IWUSR)) { // check permission yn = zmessageYN(mWin,ZTX("Move read-only file to trash?")); if (! yn) return; trstat.st_mode |= S_IWUSR; chmod(curr_file,trstat.st_mode); } if (trashworks) // try Linux standard trash { gfile = g_file_new_for_path(curr_file); gstat = g_file_trash(gfile,0,&gerror); if (! gstat) { printf("no standard trash: %s \n",gerror->message); zmessageACK(mWin,gerrmess); trashworks = 0; // did not work } } if (! trashworks) { snprintf(trashdir,199,"%s/%s",getenv("HOME"),ftrash); // use fotoxx trash filespec trstat.st_mode = 0; err = stat(trashdir,&trstat); if (! S_ISDIR(trstat.st_mode)) { err = mkdir(trashdir,0750); // v.11.03 if (err) { zmessLogACK(mWin,ZTX("Cannot create trash folder: %s"),wstrerror(errno)); return; } } snprintf(command,ccc,"cp \"%s\" \"%s\" ",curr_file,trashdir); // copy image file to trash err = system(command); if (err) { zmessLogACK(mWin,ZTX("error: %s"),wstrerror(err)); return; } err = remove(curr_file); // remove original file v.11.03 if (err) { zmessLogACK(mWin,ZTX("error: %s"),wstrerror(errno)); return; } } delete_search_index(curr_file); // delete in search index file image_gallery(0,"delete",curr_file_posn); // delete in gallery list pp = image_gallery(0,"find",curr_file_posn); // open next file (now current position) if (! pp) pp = image_gallery(0,"find",curr_file_posn-1); // no next, get prev. if poss. v.11.12 if (! pp) { free_resources(0); // leave screen blank v.11.12 mwpaint2(); } else { f_open(pp,1); // open next/prev file zfree(pp); image_gallery(0,"paint2",curr_file_posn); // refresh gallery window if active v.11.07 } return; } /**************************************************************************/ // rename menu function // activate rename dialog, stuff data from current file // dialog remains active when new file is opened char rename_old[100] = ""; char rename_new[100] = ""; void m_rename(GtkWidget *, cchar *menu) { int rename_dialog_event(zdialog *zd, cchar *event); char *pdir, *pfile, *pext; if (menu) zfuncs::F1_help_topic = "rename"; if (! curr_file) return; if (is_syncbusy()) return; // v.11.11 if (! zdrename) // restart dialog { zdrename = zdialog_new(ZTX("Rename Image File"),mWin,Bcancel,null); zdialog_add_widget(zdrename,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zdrename,"vbox","vb1","hb1",0,"homog|space=5"); zdialog_add_widget(zdrename,"vbox","vb2","hb1",0,"homog|expand"); zdialog_add_widget(zdrename,"button","Bold","vb1",ZTX("old name")); zdialog_add_widget(zdrename,"button","Bnew","vb1",ZTX("rename to")); zdialog_add_widget(zdrename,"button","Bprev","vb1",ZTX("previous")); zdialog_add_widget(zdrename,"hbox","hb21","vb2",0); // [ old name ] [ oldname ] zdialog_add_widget(zdrename,"hbox","hb22","vb2",0); // [ new name ] [ newname ] [+1] zdialog_add_widget(zdrename,"hbox","hb23","vb2",0); // [ previous ] [ prevname ] zdialog_add_widget(zdrename,"label","Lold","hb21"); zdialog_add_widget(zdrename,"entry","Enew","hb22",0,"expand|scc=30"); zdialog_add_widget(zdrename,"button","B+1","hb22"," +1 ","space=5"); zdialog_add_widget(zdrename,"label","Lprev","hb23"); zdialog_help(zdrename,"rename"); // zdialog help topic v.11.08 zdialog_run(zdrename,rename_dialog_event); // run dialog } parsefile(curr_file,&pdir,&pfile,&pext); strncpy0(rename_old,pfile,99); strncpy0(rename_new,pfile,99); zdialog_stuff(zdrename,"Lold",rename_old); // current file name zdialog_stuff(zdrename,"Enew",rename_new); // entered file name return; } // dialog event and completion callback function int rename_dialog_event(zdialog *zd, cchar *event) { char *pp, *pdir, *pfile, *pext, *pnew, *pold; int nseq, digits, ccp, ccn, ccx, err; struct stat statb; if (zd->zstat) { // complete zdialog_free(zdrename); // kill dialog return 0; } if (strEqu(event,"Bold")) // reset to current file name zdialog_stuff(zd,"Enew",rename_old); if (strEqu(event,"Bprev")) { // previous name >> new name zdialog_fetch(zd,"Lprev",rename_new,99); zdialog_stuff(zd,"Enew",rename_new); } if (strEqu(event,"B+1")) // increment sequence number { zdialog_fetch(zd,"Enew",rename_new,94); // get entered filename pp = rename_new + strlen(rename_new); digits = 0; while (pp[-1] >= '0' && pp[-1] <= '9') { pp--; // look for NNN in filenameNNN digits++; } nseq = 1 + atoi(pp); // NNN + 1 if (nseq > 9999) nseq = 0; if (digits < 2) digits = 2; // keep digit count if enough if (nseq > 99 && digits < 3) digits = 3; // use leading zeros if (nseq > 999 && digits < 4) digits = 4; snprintf(pp,digits+1,"%0*d",digits,nseq); zdialog_stuff(zd,"Enew",rename_new); } if (strEqu(event,"Bnew")) // [rename to] button { if (is_syncbusy()) return 0; // v.11.11 if (! menulock(1)) return 0; // check lock but leave unlocked menulock(0); parsefile(curr_file,&pdir,&pfile,&pext); // existing /directories/file.ext zdialog_fetch(zd,"Enew",rename_new,94); // new file name from user ccp = strlen(pdir); // length of /directories/ ccn = strlen(rename_new); // length of file if (pext) ccx = strlen(pext); // length of .ext else ccx = 0; pnew = zmalloc(ccp + ccn + ccx + 1,"rename"); // put it all together strncpy(pnew,curr_file,ccp); // /directories/file.ext strcpy(pnew+ccp,rename_new); if (ccx) strcpy(pnew+ccp+ccn,pext); err = stat(pnew,&statb); // check if new name exists if (! err) { zmessageACK(mWin,ZTX("The target file already exists")); zfree(pnew); return 0; } snprintf(command,ccc,"cp -p \"%s\" \"%s\"",curr_file,pnew); // copy to new file -p v.10.3 err = system(command); if (err) { zmessageACK(mWin,ZTX("Rename failed: \n %s"),wstrerror(err)); printf("command: %s \n",command); zfree(pnew); return 0; } zdialog_stuff(zd,"Lprev",rename_new); // set previous name in dialog load_fileinfo(pnew); // update search index file update_search_index(pnew); pold = strdupz(curr_file,0,"curr_file"); // save file name to be deleted delete_search_index(pold); // delete in search index v.9.7 err = remove(pold); // delete file v.11.03 err = f_open(pnew,1); // no automatic "next" v.11.08 image_gallery(curr_file,"init"); // update gallery v.11.05 image_gallery(0,"paint2",curr_file_posn); // refresh gallery window if active zfree(pnew); zfree(pold); } return 0; } /**************************************************************************/ // menu function - batch rename files char **batchrename_filelist = 0; int batchrename_filecount = 0; void m_batchrename(GtkWidget *, cchar *) // new v.9.7 { int batchrename_dialog_event(zdialog *zd, cchar *event); zdialog *zd; if (zdrename) return; // interactive rename is active if (is_syncbusy()) return; // v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // lock menus v.10.8 zfuncs::F1_help_topic = "batch_rename"; // v.10.8 zd = zdialog_new(ZTX("Batch Rename"),mWin,Bproceed,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"button","files","hb1",Bselectfiles,"space=10"); zdialog_add_widget(zd,"label","labcount","hb1",ZTX("%d files selected"),"space=10"); zdialog_add_widget(zd,"hbox","hb2","dialog","space=5"); zdialog_add_widget(zd,"label","lab2","hb2",ZTX("new base name"),"space=10"); zdialog_add_widget(zd,"entry","basename","hb2"); zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab31","hb3",ZTX("starting sequence"),"space=10"); zdialog_add_widget(zd,"entry","sequence","hb3","100","scc=5"); zdialog_add_widget(zd,"label","lab32","hb3",ZTX("increment"),"space=10"); zdialog_add_widget(zd,"entry","increment","hb3","01","scc=3"); batchrename_filelist = 0; batchrename_filecount = 0; zdialog_help(zd,"batch_rename"); // zdialog help topic v.11.08 zdialog_run(zd,batchrename_dialog_event); // run dialog zdialog_wait(zd); // wait for completion zdialog_free(zd); menulock(0); return; } // dialog event and completion callback function int batchrename_dialog_event(zdialog *zd, cchar *event) { char **flist = batchrename_filelist, countmess[50]; cchar *selectmess = ZTX("select files to rename"); int ii, err, cc, ccp, ccn, ccx; int sequence, increment, adder; char basename[100], filename[120], *oldfile, *newfile; char *pdir, *pfile, *pext; cchar *errmess = ZTX("base name / sequence / increment not reasonable"); struct stat statb; if (strEqu(event,"files")) // select images to rename { if (flist) { // free prior list for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); } flist = zgetfileN(selectmess,"openN",curr_file); // get file list from user batchrename_filelist = flist; if (flist) // count files in list for (ii = 0; flist[ii]; ii++); else ii = 0; batchrename_filecount = ii; snprintf(countmess,50,ZTX("%d files selected"),batchrename_filecount); zdialog_stuff(zd,"labcount",countmess); } if (! zd->zstat) return 0; // dialog active if (zd->zstat != 1) goto cleanup; // dialog canceled if (! batchrename_filecount) goto cleanup; // no files selected zdialog_fetch(zd,"basename",basename,99); zdialog_fetch(zd,"sequence",sequence); zdialog_fetch(zd,"increment",increment); if (strlen(basename) < 1 || sequence < 1 || increment < 1) { zd->zstat = 0; // keep dialog alive bugfix v.10.7 zmessageACK(mWin,errmess); return 0; } write_popup_text("open","Renaming files",500,200,mWin); // status monitor popup window v.10.3 for (ii = 0; flist[ii]; ii++) { oldfile = flist[ii]; parsefile(oldfile,&pdir,&pfile,&pext); ccp = strlen(pdir); if (pext) ccx = strlen(pext); else ccx = 0; adder = sequence + ii * increment; snprintf(filename,119,"%s%d",basename,adder); // removed "-" between v.10.7 ccn = strlen(filename); newfile = zmalloc(ccp + ccn + ccx + 1,"rename"); // construct /path/filename.ext strcpy(newfile,pdir); strcpy(newfile+ccp,filename); if (ccx) strcpy(newfile+ccp+ccn,pext); err = stat(newfile,&statb); if (! err) { snprintf(command,ccc,"%s %s",ZTX("new file already exists:"),newfile); write_popup_text("write",command); zfree(newfile); break; } cc = snprintf(command,ccc,"cp -p \"%s\" \"%s\"",oldfile,newfile); // copy to new file -p v.10.3 if (cc >= maxfcc*2) { snprintf(command,ccc,"%s %s",ZTX("filespec too long:"),oldfile); write_popup_text("write",command); zfree(newfile); break; } write_popup_text("write",command); // report progress zmainloop(); err = system(command); if (err) { snprintf(command,ccc,"%s %s",ZTX("Rename failed:"),wstrerror(err)); write_popup_text("write",command); zfree(newfile); break; } load_fileinfo(newfile); // update search index file update_search_index(newfile); zfree(newfile); err = remove(oldfile); // delete old file v.11.03 delete_search_index(oldfile); // remove from search index zmainloop(); } write_popup_text("write","COMPLETED"); write_popup_text("close",0); image_gallery(curr_file,"init"); // update gallery file list image_gallery(0,"paint2",curr_file_posn); // refresh gallery window if active cleanup: if (batchrename_filecount) { for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); batchrename_filecount = 0; // bugfix v.12.01 } return 0; } /**************************************************************************/ // print current image file double print_size[2] = { 29.7, 21.0 }; // default A4 landscape double print_margins[4] = { 0.5, 0.5, 0.5, 0.5 }; // top, bottom, left, right void m_print(GtkWidget *, cchar *) // use GTK print v.9.4 { PXM * print_addgrid(PXM *printimage); // v.11.01 int err; char *printfile; PXM *printimage, *pxmtemp; zfuncs::F1_help_topic = "print"; if (! curr_file) return; // no image file printfile = strdupz(get_zuserdir(),20,"printfile"); // make temp print file: strcat(printfile,"/printfile.tif"); // ~/.fotoxx/printfile.tif v.11.03 if (Fpxm16) printimage = PXM_convbpc(Fpxm16); else printimage = PXM_copy(Fpxm8); pxmtemp = print_addgrid(printimage); // add grid lines if wanted v.11.01 if (pxmtemp) { PXM_free(printimage); printimage = pxmtemp; } err = PXBwrite(printimage,printfile); PXM_free(printimage); if (err) { zfree(printfile); // v.10.3 return; } print_image_paper_setup(mWin); // new v.11.10 print_image_margins_setup(mWin); print_image_file(printfile); zfree(printfile); return; } // add grid lines to print image if wanted PXM * print_addgrid(PXM *printimage) // v.11.01 { PXM *temp8; uint8 *pixel; int px, py, ww, hh, row; int startx, starty, stepx, stepy; if (! Fgrid) return 0; // grid lines off temp8 = f_load(curr_file,8); if (! temp8) return 0; ww = temp8->ww; hh = temp8->hh; row = ww * 3; stepx = gridspace[0]; // space between grid lines stepy = gridspace[1]; stepx = stepx / Mscale; // window scale to image scale stepy = stepy / Mscale; if (gridcount[0]) stepx = ww / (1 + gridcount[0]); // if line counts specified, if (gridcount[1]) stepy = hh / ( 1 + gridcount[1]); // set spacing accordingly startx = stepx * gridoffset[0] / 100; // variable offsets v.11.11 if (startx < 0) startx += stepx; starty = stepy * gridoffset[1] / 100; if (starty < 0) starty += stepy; if (gridon[0]) { for (px = startx; px < ww-1; px += stepx) for (py = 0; py < hh; py++) { pixel = PXMpix8(temp8,px,py); // adjoining white and black lines pixel[0] = pixel[1] = pixel[2] = 255; pixel[3] = pixel[4] = pixel[5] = 0; } } if (gridon[1]) { for (py = starty; py < hh-1; py += stepy) for (px = 0; px < ww; px++) { pixel = PXMpix8(temp8,px,py); pixel[0] = pixel[1] = pixel[2] = 255; pixel[row] = pixel[row+1] = pixel[row+2] = 0; } } return temp8; } /**************************************************************************/ // normal quit menu function void m_quit(GtkWidget *, cchar *) { if (mod_keep()) return; // unsaved edits printf("quit \n"); Fshutdown++; // bugfix v.10.11 for (int ii = 0; ii < 100; ii++) // wait if something running if (Ffuncbusy) { // v.11.01 zmainloop(); zsleep(0.01); } if (Ffuncbusy) printf("busy function killed"); // v.11.05 gtk_window_get_position(MWIN,&mwgeom[0],&mwgeom[1]); // get last window position v.11.07 gtk_window_get_size(MWIN,&mwgeom[2],&mwgeom[3]); // and size for next session save_params(); // save state for next session zdialog_positions("save"); // save dialog positions too v.11.07 free_resources(); // delete temp files if (KBzmalloclog) zmalloc_report(); // report memory v.10.8 fflush(null); // flush stdout, stderr v.11.05 gtk_main_quit(); // gone forever return; } /************************************************************************** plugin menu functions **************************************************************************/ // process plugin menu selection // execute correspinding command using current image file editfunc EFplugin; void m_run_plugin(GtkWidget *, cchar *menu) // v.11.03 { int ii, jj, err; char *pp = 0, pluginfile[200]; PXM *pxmtemp; zfuncs::F1_help_topic = "plugins"; for (ii = 0; ii < Nplugins; ii++) // search plugins for menu name { pp = strstr(plugins[ii]," = "); if (! pp) continue; *pp = 0; jj = strEqu(plugins[ii],menu); *pp = ' '; if (jj) break; } if (ii == Nplugins) { zmessageACK(mWin,"plugin menu not found %s",menu); return; } pp += 3; if (strlen(pp) < 3) { zmessageACK(mWin,"no plugin command"); return; } strncpy0(command,pp,ccc); // corresp. command strTrim2(command); EFplugin.funcname = menu; if (! edit_setup(EFplugin)) return; // setup edit snprintf(pluginfile,199,"%s/plugfile.tif",get_zuserdir()); // /home/user/.fotoxx/plugfile.tif TIFFwrite(E1pxm16,pluginfile); // E1 >> plugin_file strcat(command," "); // construct: command /.../plugin_file & strcat(command,pluginfile); printf("plugin: %s \n",command); err = system(command); // execute plugin command if (err) { zmessageACK(mWin,"plugin command error"); edit_cancel(EFplugin); return; } pxmtemp = TIFFread(pluginfile); // read command output file if (! pxmtemp) { zmessageACK(mWin,"plugin failed"); edit_cancel(EFplugin); return; } PXM_free(E3pxm16); // plugin_file >> E3 if (pxmtemp->bpc == 16) E3pxm16 = pxmtemp; else { E3pxm16 = PXM_convbpc(pxmtemp); PXM_free(pxmtemp); } EFplugin.Fmod = 1; // assume image was modified edit_done(EFplugin); return; } // edit plugins menu void m_edit_plugins(GtkWidget *, cchar *) // v.11.03 { int edit_plugins_event(zdialog *zd, cchar *event); int ii; char *pp; zdialog *zd; zfuncs::F1_help_topic = "plugins"; zd = zdialog_new("Edit Plugins",mWin,ZTX("Add"),ZTX("Remove"),Bdone,null); zdialog_add_widget(zd,"hbox","hbm","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labm","hbm",ZTX("menu name"),"space=5"); zdialog_add_widget(zd,"comboE","menu","hbm",0,"space=5"); zdialog_add_widget(zd,"hbox","hbc","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labc","hbc","command","space=5"); zdialog_add_widget(zd,"entry","command","hbc",0,"space=5|expand"); for (ii = 0; ii < Nplugins; ii++) // stuff combo box with available { // plugin menu names pp = strstr(plugins[ii]," = "); if (! pp) continue; *pp = 0; zdialog_cb_app(zd,"menu",plugins[ii]); *pp = ' '; } zdialog_help(zd,"plugins"); // zdialog help topic v.11.08 zdialog_run(zd,edit_plugins_event); return; } // dialog event function int edit_plugins_event(zdialog *zd, cchar *event) { int ii, jj, cc, zstat; char menu[40], *pp = 0; zdialog_fetch(zd,"menu",menu,40); // selected menu zdialog_fetch(zd,"command",command,ccc); if (strEqu(event,"menu")) { for (ii = 0; ii < Nplugins; ii++) { pp = strstr(plugins[ii]," = "); // find corresp. plugin record if (! pp) continue; *pp = 0; jj = strEqu(plugins[ii],menu); *pp = ' '; if (jj) break; } if (ii == Nplugins) return 0; pp += 3; if (strlen(pp) < 3) return 0; strncpy0(command,pp,ccc); zdialog_stuff(zd,"command",command); // stuff corresp. command in dialog return 0; } zstat = zd->zstat; if (! zstat) return 0; if (zstat == 1) // add new plugin { if (strlen(menu) < 3 || strlen(command) < 3) return 0; if (Nplugins == maxplugins) { zmessageACK(mWin,"too many plugins"); return 0; } ii = Nplugins; // add plugin record cc = strlen(menu) + strlen(command) + 5; plugins[ii] = zmalloc(cc,"plugins"); // format: menu = command strcpy(plugins[ii],menu); strcat(plugins[ii]," = "); strcat(plugins[ii],command); Nplugins++; zmessageACK(mWin,ZTX("Restart Fotoxx to update plugin menu")); } if (zstat == 2) // remove current plugin { for (ii = 0; ii < Nplugins; ii++) { pp = strstr(plugins[ii]," = "); // find corresp. plugin record if (! pp) continue; *pp = 0; jj = strEqu(plugins[ii],menu); *pp = ' '; if (jj) break; } if (ii == Nplugins) return 0; Nplugins--; // remove plugin record for (jj = ii; jj < Nplugins; jj++) plugins[jj] = plugins[jj+1]; zmessageACK(mWin,ZTX("Restart Fotoxx to update plugin menu")); } if (zstat == 3) { // done zdialog_free(zd); return 0; } return 0; } fotoxx-12.01.2/zfuncs.h0000644000175000017500000012065711701011017013325 0ustar micomico/************************************************************************** zfuncs.h include file for zfuncs functions Copyright 2006 2007 2008 2009 2010 2011 Michael Cornelison source URL: kornelix.squarespace.com contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***************************************************************************/ // zfuncs.h version v.5.0 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define int8 char // number types #define int16 short #define int32 long #define int64 long long #define uint8 unsigned char #define uint16 unsigned short #define uint32 unsigned long #define uint64 unsigned long long #define dub double #define uchar unsigned char #define cchar const char #define wstrerror(err) strerror(WEXITSTATUS(err)) // get text status for child process #define mutex pthread_mutex_t // abbreviations #define mutex_init pthread_mutex_init #define mutex_lock pthread_mutex_lock #define mutex_trylock pthread_mutex_trylock #define mutex_unlock pthread_mutex_unlock #define mutex_destroy pthread_mutex_destroy #define maxfcc 1000 // max. file pathname cc tolerated #define null NULL #define true 1 #define false 0 // system functions ====================================================== void apppause(); // output message and wait for user void apppause(cchar * pMess, ... ); // same, works like printf void zappcrash(cchar *pMessage, ...); // crash with popup message in text window void catch_signals(); // catch signals and do backtrace dump void beroot(int argc = 0, char *argv[] = 0); // restart image as root if password OK double get_seconds(); // seconds since 2000.01.01 void start_timer(double &time0); // start a timer double get_timer(double &time0); // get elapsed time in seconds void start_CPUtimer(double &time0); // start a process CPU timer double get_CPUtimer(double &time0); // get elapsed CPU time, seconds double CPUtime(); // get elapsed process CPU time for main() double CPUtime2(); // " include all threads double jobtime(); // " include all threads + subprocesses int parseprocfile(cchar *pfile, cchar *pname, double *value, ...); // get data from /proc file int parseprocrec(char *prec, int field, double *value, ...); // get data from /proc file record void zsleep(double dsecs); // sleep specified seconds int global_lock(cchar *lockname); // obtain exclusive lock, multi-process int global_unlock(int fd); // release the lock void start_detached_thread(void * tfunc(void *), void * arg); // start detached thread function void synch_threads(int NT = 0); // synchronize NT threads int zget_locked(int ¶m); // lock and get multi-thread parameter void zput_locked(int ¶m, int value); // put and unlock multi-thread parameter int zadd_locked(int ¶m, int incr); // increment multi-thread parameter void gate_threads_enter(); // allow only one thread at a time within void gate_threads_leave(); // the time betwen enter() and leave() char * zmalloc(size_t bytes, cchar *tag = 0); // malloc() with auto crash and log option void zfree(void *buff); // free() with log option void zmalloc_log(int count); // turn zmalloc() log on/off v.3.5 void zmalloc_report(); // print total memory allocated v.3.5 char * command_output(int &contx, cchar *command, ...); // get shell command output v.2.3 int command_status(int contx); // get exit status of command int signalProc(cchar * pname, cchar * signal); // pause/resume/kill subprocess int runroot(cchar *sucomm, cchar *command); // run command as root via su or sudo int checkinstall(cchar *prog, ...); // check if programs are installed char * fgets_trim(char * buff, int maxcc, FILE *, int bf = 0); // fgets + trim trailing \n \r (blanks) int samedirk(cchar *file1, cchar *file2); // returns 1 if files in same directory int parsefile(cchar *path, char **dir, char **file, char **ext); // parse a filespec // measure CPU time spent in a function or code block within a function extern volatile double cpu_profile_timer; // internal data tables extern volatile double cpu_profile_table[100]; extern volatile double cpu_profile_elapsed; void cpu_profile_init(); // initialize at start of test void cpu_profile_report(); // report CPU time per function inline void cpu_profile_enter(int fnum) // at entry to measured code block { cpu_profile_timer = cpu_profile_elapsed; } inline void cpu_profile_exit(int fnum) // at exit from measured code block { cpu_profile_table[fnum] += cpu_profile_elapsed - cpu_profile_timer; } // string macros and functions =========================================== #define strEqu(str1,str2) (! strcmp((str1),(str2))) // TRUE if strings compare equal #define strcaseEqu(str1,str2) (! strcasecmp((str1),(str2))) // TRUE if strings equal, ignoring case #define strNeq(str1,str2) (strcmp((str1),(str2))) // TRUE if strings compare not-equal #define strnEqu(str1,str2,cc) (! strncmp((str1),(str2),(cc))) // TRUE if strings[cc] compare equal #define strncaseEqu(str1,str2,cc) (! strncasecmp((str1),(str2),(cc))) // TRUE if strings[cc] equal, ignoring case #define strnNeq(str1,str2,cc) (strncmp((str1),(str2),(cc))) // TRUE if strings[cc] compare not-equal cchar * strField(cchar *string, cchar *delims, int Nth); // get Nth delimited field in string cchar * strField(cchar *string, cchar delim, int Nth); // get Nth delimited field in string int strParms(int &bf, cchar *inp, char *pname, int maxcc, double &pval); // parse string: name1=val1 | name2 ... int strHash(cchar *string, int max); // string --> random int 0 to max-1 cchar * strHash2(cchar *string, int outcc); // string --> random printable string int strncpy0(char *dest, cchar *source, uint cc); // strncpy, insure null, return 0 if fit void strnPad(char *dest, cchar *source, int cc); // strncpy with blank padding to cc int strTrim(char *dest, cchar *source); // remove trailing blanks int strTrim(char *string); // remove trailing blanks int strTrim2(char *dest, cchar *source); // remove leading and trailing blanks int strTrim2(char *string); // remove leading and trailing blanks int strCompress(char *dest, cchar *source); // remove all blanks incl. imbedded int strCompress(char *string); // remove all blanks int strncatv(char *dest, int maxcc, cchar *source, ...); // catenate strings (last = 0L) int strcmpv(cchar *string, ...); // compare to N strings, return 1-N or 0 void strToUpper(char *dest, cchar *source); // move and conv. string to upper case void strToUpper(char *string); // conv. string to upper case void strToLower(char *dest, cchar *source); // move and conv. string to lower case void strToLower(char *string); // conv. string to lower case int repl_1str(cchar *strin, char *strout, cchar *ssin, cchar *ssout); // copy string and replace 1 substring int repl_Nstrs(cchar *strin, char *strout, ...); // copy string and replace N substrings void strncpyx(char *out, cchar *in, int ccin); // conv. string to hex format void StripZeros(char *pNum); // 1.230000E+12 --> 1.23E+12 int blank_null(cchar *string); // test for blank/null string char * strdupz(cchar *string, int more = 0, cchar *tag = 0); // duplicate string in nonvolatile memory int strdupz(cchar *source, char *&dest, int more = 0, cchar *tag = 0); // same + dest zmalloc if null or too short int clean_escapes(char *string); // replace \x escapes with real characters int utf8len(cchar *utf8string); // get graphic cc for UTF8 string v.2.3 int utf8substring(char *utf8out, cchar *utf8in, int pos, int cc); // get graphic substring from UTF8 string int utf8_check(cchar *string); // check utf8 string for encoding errors int utf8_position(cchar *utf8in, int Nth); // get byte position of Nth graphic char. // bitmap functions ====================================================== struct bitmap { int nbits; // declare bitmap: bitmap *bmap uchar *bits; }; bitmap * bitmap_new(int nbits); // create and initialize all bits to zero void bitmap_set(bitmap *bm, int bit, bool value); // set a bit true or false bool bitmap_get(bitmap *bm, int bit); // get a bit value, true or false void bitmap_delete(bitmap *bm); // delete bitmap, release memory // variable string list functions ======================================== struct pvlist { int max; // max. entries int act; // actual entries char **list; // entries }; pvlist * pvlist_create(int max); // create pvlist void pvlist_free(pvlist *pv); // free pvlist int pvlist_append(pvlist *pv, cchar *entry, int unique = 0); // append new entry (opt. if unique) int pvlist_prepend(pvlist *pv, cchar *entry, int unique = 0); // prepend new entry (opt. if unique) int pvlist_find(pvlist *pv, cchar *entry); // find entry by name int pvlist_remove(pvlist *pv, cchar *entry); // remove entry by name int pvlist_remove(pvlist *pv, int Nth); // remove entry by number (0...) int pvlist_count(pvlist *pv); // return entry count int pvlist_replace(pvlist *pv, int Nth, cchar *entry); // replace Nth entry (0...) char * pvlist_get(pvlist *pv, int Nth); // return Nth entry (0...) int pvlist_sort(pvlist *pv); // sort list, ascending // number conversion ===================================================== int convSI (cchar *inp, int &inum, cchar **delm = 0); // string to int int convSI (cchar *inp, int &inum, int low, int hi, cchar **delm = 0); // (with low/high limit checking) int convSD (cchar *inp, dub &dnum, cchar **delm = 0); // string to double int convSD (cchar *inp, dub &dnum, dub low, dub hi, cchar **delm = 0); // (with low/high limit checking) int convIS (int iin, char *outp, int *cc = 0); // int to string, returned cc int convDS (dub din, int prec, char *outp, int *cc = 0); // double to string, precision, ret. cc char * formatKBMB(double fnum, int prec); // format nnn B, nn.n KB, n.nn MB, etc. // wildcard functions ==================================================== int MatchWild(cchar * wildstr, cchar * str); // wildcard string match (0) cchar * SearchWild(cchar *wpath, int &flag); // wildcard file search // search and sort functions ============================================= int bsearch(int seekint, int nn, int list[]); // binary search sorted list[nn] int bsearch(char *seekrec, char *allrecs, int recl, int nrecs); // binary search sorted records typedef int HeapSortUcomp(cchar * rec1, cchar * rec2); // return -1/0/+1 if rec1 rec2 void HeapSort(int vv[], int nn); // Heap Sort - integer void HeapSort(float vv[], int nn); // Heap Sort - float void HeapSort(double vv[], int nn); // Heap Sort - double void HeapSort(char * vv[], int nn); // Heap Sort - char *, ascending order void HeapSort(char * vv[], int nn, HeapSortUcomp); // Heap Sort - char *, user-defined order void HeapSort(char * recs, int RL, int NR, HeapSortUcomp); // Heap Sort - records, user-defined order int MemSort(char * RECS, int RL, int NR, int KEYS[][3], int NK); // memory sort, records with multiple keys // random number functions =============================================== int lrandz(int64 * seed); // returns 0 to 0x7fffffff int lrandz(); // built-in seed double drandz(int64 * seed); // returns 0.0 to 0.99999... double drandz(); // built-in seed // spline curve-fitting functions ======================================== v.2.11 void spline1(int nn, double *dx, double *dy); // define a curve using nn data points double spline2(double x); // return y-value for given x-value /**************************************************************************/ // application initialization and administration #define ZTXmaxent 2000 // max. translation strings #define ZTXmaxcc 4000 // max. cc per string int zinitapp(cchar *appname, ...); // initz. app directories and files v.4.1 cchar * get_zprefix(); // get /usr or /usr/local ... v.4.1 cchar * get_zuserdir(); // get /home/user/.appname/ cchar * get_zdatadir(); // get install directory cchar * get_zdocdir(); // get document directory v.3.8 void showz_userguide(cchar *context = 0); // show user guide in new process void showz_readme(); // show README file in popup window void showz_changelog(); // show changelog file in popup window void showz_translations(); // show TRANSLATIONS file in popup window void showz_doctext(cchar *file); // show text file (or .gz) in a popup window void zmake_menu_launcher(cchar *command, cchar *cats, cchar *generic); // add desktop menu and launcher v.4.1 void showz_html(cchar *url); // show html via preferred browser v.2.18 /************************************************************************** GTK utility functions ***************************************************************************/ void zmainloop(int skip = 0); // do main loop, process menu events void zthreadcrash(); // crash if thread is not main() thread // text window print and read utilities void wprintx(GtkWidget *Win, int line, cchar *mess, cchar *font = 0); // write text to line, optional font void wprintf(GtkWidget *Win, int line, cchar *mess, ...); // "printf" version void wprintf(GtkWidget *Win, cchar *mess, ... ); // "printf" to next line, scroll up void wscroll(GtkWidget *mLog, int line); // scroll window to put line on screen void wclear(GtkWidget *Win); // clear window void wclear(GtkWidget *Win, int line); // clear from line to end char * wscanf(GtkWidget *Win, int &ftf); // get text lines from edit widget int wfiledump(GtkWidget *Win, char *filespec); // dump text window to file void wfilesave(GtkWidget *Win); // wfiledump() via file-chooser dialog void wprintp(GtkWidget *Win); // print text window to default printer /**************************************************************************/ // functions to simplify building menus, tool bars, status bars #define G_SIGNAL(window,event,func,arg) \ g_signal_connect(G_OBJECT(window),event,G_CALLBACK(func),(void *) arg) #define zdcbmax 100 // max. combo box drop-down list typedef void mtFunc(GtkWidget *, cchar *mname); // menu or button response function GtkWidget * create_menubar(GtkWidget *vbox); // create menubar in packing box GtkWidget * add_menubar_item(GtkWidget *mbar, cchar *mname, mtFunc func = 0); // add menu item to menubar GtkWidget * add_submenu_item(GtkWidget *mitem, cchar *label, mtFunc func = 0); // add submenu item to menu item GtkWidget * create_popmenu(); // create an empty popup menu GtkWidget * add_popmenu_item(GtkWidget *popmenu, cchar *mname, mtFunc func); // add menu item to popup menu void popup_menu(GtkWidget *popmenu); // pop-up menu at current mouse position GtkWidget * create_toolbar(GtkWidget *vbox, int iconsize = 24, int vert = 0); // horiz. toolbar in packing box (vert.) GtkWidget * add_toolbar_button(GtkWidget *tbar, cchar *label, cchar *tip, // add button with stock (gtk-quit) cchar *icon, mtFunc func); // or custom icon (iconfile.png) GtkWidget * create_stbar(GtkWidget *vbox); // create status bar in packing box int stbar_message(GtkWidget *stbar, cchar *message); // display message in status bar /**************************************************************************/ // functions to implement GTK dialogs with less complexity // widget types: dialog, hbox, vbox, hsep, vsep, frame, scrwin, label, entry, edit, radio, // check, button, togbutt, spin, combo, comboE, hscale, vscale, colorbutt #define zdmaxwidgets 300 #define zdmaxbutts 10 #define zdsentinel 2138687954 struct zwidget { cchar *type; // dialog, hbox, vbox, label, entry ... cchar *name; // widget name cchar *pname; // parent (container) name char *data; // widget data, initial / returned pvlist *cblist; // combo box drop-down list int scc; // entry widget: text cc width int homog; // hbox/vbox: equal spacing flag int expand; // expandable flag int space; // extra padding space (pixels) int wrap; // wrap mode for edit widget GtkWidget *widget; // GTK widget pointer }; struct zdialog { int sentinel; // validity sintenel void *eventCB; // widget event user callback function int zstat; // dialog status (from completion button) int disabled; // widget signals/events are disabled int saveposn; // save and recall window position each use cchar *help_topic; // optional help topic GtkWidget *parent; // parent window or null GtkWidget *compbutt[zdmaxbutts]; // dialog completion buttons zwidget widget[zdmaxwidgets]; // dialog widgets (EOF = type = 0) }; zdialog *zdialog_new(cchar *title, GtkWidget *parent, ...); // create a zdialog with opt. buttons int zdialog_add_widget(zdialog *zd, // add widget to zdialog cchar *type, cchar *name, cchar *pname, // required args cchar *data = 0, int scc = 0, int homog = 0, // optional args int expand = 0, int space = 0, int wrap = 0); int zdialog_add_widget(zdialog *zd, // add widget to zdialog cchar *type, cchar *name, cchar *pname, // (alternative form) cchar *data, cchar *options); // "scc=nn|homog|expand|space=nn|wrap" GtkWidget * zdialog_widget(zdialog *zd, cchar *name); // GTK widget from zdialog widget name int zdialog_set_group(zdialog *zd, cchar *radio1, ...); // set group ID for set of radio buttons int zdialog_resize(zdialog *zd, int width, int height); // set size > widget sizes int zdialog_put_data(zdialog *zd, cchar *name, cchar *data); // put data in widget (entry, spin ...) cchar * zdialog_get_data(zdialog *zd, cchar *name); // get widget data int zdialog_set_limits(zdialog *zd, cchar *name, double min, double max); // set new widget limits (spin, scale) void zdialog_help(zdialog *zd, cchar *help_topic); // set help topic for zdialog typedef int zdialog_event(zdialog *zd, cchar *name); // widget event callback function int zdialog_run(zdialog *zd, zdialog_event = 0, cchar *posn = 0); // run dialog, handle events int zdialog_send_event(zdialog *zd, cchar *event); // send an event to an active dialog v.2.17 int zdialog_send_response(zdialog *zd, int zstat); // complete a dialog, set status v.2.23 int zdialog_destroy(zdialog *zd); // destroy dialog (caller responsibility) int zdialog_free(zdialog *&zd); // free zdialog memory int zdialog_wait(zdialog *zd); // wait for dialog status or be destroyed int zdialog_goto(zdialog *zd, cchar *name); // put cursor at named widget v.2.23 void zdialog_set_cursor(zdialog *zd, GdkCursor *cursor); // set cursor for dialog window int zdialog_stuff(zdialog *zd, cchar *name, cchar *data); // stuff string data into widget int zdialog_stuff(zdialog *zd, cchar *name, int data); // stuff int data int zdialog_stuff(zdialog *zd, cchar *name, double data); // stuff double data int zdialog_fetch(zdialog *zd, cchar *name, char *data, int maxcc); // get string data from widget int zdialog_fetch(zdialog *zd, cchar *name, int &data); // get int data int zdialog_fetch(zdialog *zd, cchar *name, double &data); // get double data int zdialog_fetch(zdialog *zd, cchar *name, float &data); // get float data int zdialog_cb_app(zdialog *zd, cchar *name, cchar *data); // append entry to combo drop down list int zdialog_cb_prep(zdialog *zd, cchar *name, cchar *data); // prepend entry to combo drop down list char * zdialog_cb_get(zdialog *zd, cchar *name, int Nth); // get combo drop down list Nth entry int zdialog_cb_delete(zdialog *zd, cchar *name, cchar *data); // delete combo drop down list entry v.2.4 int zdialog_cb_clear(zdialog *zd, cchar *name); // clear all combo box entries v.2.4 int zdialog_cb_popup(zdialog *zd, cchar *name); // show all combo box list entries v.3.8 int zdialog_positions(cchar *action); // load or save zdialog window positions void zdialog_set_position(zdialog *zd, cchar *posn); // set initial/new zdialog window position void zdialog_save_position(zdialog *zd); // save zdialog window position /**************************************************************************/ // translation functions void ZTXinit(cchar *lang); // setup for message translation cchar *ZTX(cchar *english); // get translation for English message void ZTX_translation_start(GtkWidget *parent); // start online translation // write text to popup window, shell command to popup window int write_popup_text(cchar *action, cchar *text = 0, int ww = 0, int hh = 0, GtkWidget *parent = 0); int popup_command(cchar *command, int ww = 400, int hh = 300, GtkWidget *parent = 0); // popup message dialogs void zmessageACK(GtkWidget *parent, cchar *pMess, ... ); // display message, wait for OK void zmessLogACK(GtkWidget *parent, cchar *pMess, ... ); // same, with log to STDOUT int zmessageYN(GtkWidget *parent, cchar *pMess, ... ); // display message, wait for YES or NO void zmessage_help(GtkWidget *parent, cchar *topic, cchar *mess, ...); // message box, [help] > user guide topic zdialog * zmessage_post(GtkWidget *parent, int secs, cchar *mess, ...); // display message until timeout or cancel char * zdialog_text(GtkWidget *parent, cchar * title, cchar * initext); // get short text input from user int zdialog_choose(cchar *title, GtkWidget *parent, cchar *mess, ...); // show message and return choice button // file chooser dialogs for one file or multiple files char * zgetfile1(cchar *title, cchar *action, cchar *file, cchar *butt = 0); char ** zgetfileN(cchar *title, cchar *action, cchar *file, cchar *butt = 0); // print image file void print_image_paper_setup(GtkWidget *parent); // paper setup for printing an image file void print_image_margins_setup(GtkWidget *parent); // setup print margins void print_image_file(cchar *imagefile); // print the image file // drag and drop functions typedef void drag_drop_func(int x, int y, char *text); // user function, get drag_drop text v.2.19 void drag_drop_connect(GtkWidget *window, drag_drop_func); // connect window to user function // miscellaneous GDK/GTK functions GdkPixbuf * get_thumbnail(char *fpath, int size); // get sized thumbnail for image file GdkCursor * zmakecursor(cchar *iconfile); // make a cursor from an image file v.3.7 int gdk_window_move_pointer(GdkWindow *, int px, int py); // move the mouse pointer to px, py GdkPixbuf * gdk_pixbuf_rotate(GdkPixbuf *, double deg, int alfa = 0); // rotate pixbuf through any angle /**************************************************************************/ // parameter management functions int initParmlist(int max); // initz. parameter list int initz_userParms(); // load or initialize user parms int loadParms(cchar * filename); // load parameters from a file int loadParms(); // + user file select dialog int saveParms(cchar * filename); // save parameters to a file int saveParms(); // + user file select dialog int setParm(cchar * parmname, double parmval); // set parameter value double getParm(cchar * parmname); // get parameter value char * getParm(int Nth); // get Nth parameter name (0-based) int listParms(GtkWidget *textWin); // list all parameters in given window int editParms(GtkWidget *textWin = 0, int addp = 0); // parameter editor /************************************************************************** C++ classes ***************************************************************************/ // dynamic string class ================================================== class xstring { static int tcount; // total xstring count static int tmem; // total memory used int wmi; // internal ID int xcc; // actual cc (excl. NULL) int xmem; // memory allocated cc char * xpp; // memory pointer public: xstring(int cc = 0); // default constructor xstring(cchar * ); // string constructor xstring(const xstring &); // copy constructor ~xstring(); // destructor operator cchar * () const { return xpp; } // conversion operator (cchar *) xstring operator= (const xstring &); // operator = xstring operator= (cchar *); // operator = friend xstring operator+ (const xstring &, const xstring &); // operator + friend xstring operator+ (const xstring &, cchar *); // operator + friend xstring operator+ (cchar *, const xstring &); // operator + void insert(int pos, cchar * string, int cc = 0); // insert substring at position (expand) void overlay(int pos, cchar * string, int cc = 0); // overlay substring (possibly expand) static void getStats(int & tcount2, int & tmem2); // get statistics void validate() const; // verify integrity int getcc() const { return xcc; } // return string length }; // vector (array) of xstring ============================================= class Vxstring { int nd; // count xstring * pdata; // xstring[nd] public: Vxstring(int = 0); // constructor ~Vxstring(); // destructor Vxstring(const Vxstring &); // copy constructor Vxstring operator= (const Vxstring &); // operator = xstring & operator[] (int); // operator [] const xstring & operator[] (int) const; // operator [] (const) int search(cchar * string); // find element in unsorted Vxstring int bsearch(cchar * string); // find element in sorted Vxstring int sort(int nkeys, int keys[][3]); // sort by designated subfields int sort(int pos = 0, int cc = 0); // sort by 1 subfield (cc 0 = all) int getCount() const { return nd; } // get current count }; // hash table class ====================================================== class HashTab { static int trys1; // insert trys static int trys2; // find/delete trys int cap; // table capacity int count; // strings contained int cc; // string length char * table; // table[cc][cap] public: HashTab(int cc, int cap); // constructor ~HashTab(); // destructor int Add(cchar * string); // add a new string int Del(cchar * string); // delete a string int Find(cchar * string); // find a string int GetCount() { return count; }; // get string count int GetNext(int & first, char * string); // get first/next string int Dump(); // dump hash table }; // Queue class, FIFO, LIFO or mixed ====================================== class Queue { char wmi[8]; Vxstring * vd; // vector of xstrings mutex qmutex; // for multi-thread access int qcap; // queue capacity int qcount; // curr. queue count int ent1; // first entry pointer int entN; // last entry pointer char * lastent; // last entry retrieved int lcc; // last entry cc private: void lock(); // auto locking and unlocking void unlock(); // (for multi-thread access) public: Queue(int cap); // create queue with capacity ~Queue(); // destroy queue int getCount(); // get current entry count int push(const xstring * entry, double secs); // add new entry with max. wait time xstring * pop1(); // get 1st entry (oldest) xstring * popN(); // get Nth entry (newest) }; /* ======================================================================= Tree class - sparse array indexed by names or numbers - every element of a Tree is a Tree put(): cc is data length to store get(): cc is max. data length to retrieve actual length is returned, = 0 if not found nn is array count for nodes[] arguments */ class Tree { int wmi; // for ID checking char *tname; // tree name int tmem; // tree data memory void *tdata; // tree data[tmem] int nsub; // no. sub-nodes (Trees) Tree **psub; // pointer to sub-nodes public: Tree(cchar * name); // create Tree ~Tree(); // destroy Tree int put(void * data, int cc, char * nodes[], int nn); // put data by node names[] int put(void * data, int cc, int nodes[], int nn); // put data by node numbers[] int get(void * data, int cc, char * nodes[], int nn); // get data by node names[] int get(void * data, int cc, int nodes[], int nn); // get data by node numbers[] void stats(int nnodes[], int ndata[]); // get nodes and data per level void dump(int level = 0); // diagnostic private: Tree * find(char * nodes[], int nn); // find a sub-node by names[] Tree * find(int nodes[], int nn); // find a sub-node by numbers[] Tree * make(char * nodes[], int nn); // find/create a sub-node by names[] Tree * make(int nodes[], int nn); // find/create a sub-node by numbers[] }; fotoxx-12.01.2/debian-control0000644000175000017500000000234711701011017014462 0ustar micomicoPackage: fotoxx Version: 12.01.2 Architecture: amd64 Section: graphics Installed-Size: 2900 Maintainer: Mike Cornelison Depends: libgtk2.0-0 (>= 2.20.1), libatk1.0-0 (>= 1.30.0), libglib2.0-0 (>= 2.24.1), libpango1.0-0 (>= 1.28.0), libcairo2 (>= 1.8.10), libfreetype6 (>= 2.3.11), libfontconfig1 (>= 2.8.0), libc6 (>= 2.11.1), libtiff4 (>= 3.9.2), libstdc++6 (>= 4.4.3), libgcc1 (>= 1:4.4.3), xdg-utils (>= 1.0.2), libimage-exiftool-perl (>= 7.89), ufraw (>= 0.16) Description: photo editor and collection manager Navigate your image collection using a thumbnail browser. View and edit images. Convert RAW files to TIFF and edit with 16-bit color. Edit a selected area or object within an image. Edit using movable curves with fast full-screen feedback. Adjust brightness, color, contrast, gamma. Perform tone mapping, trim, rescale, rotate, warp, sharpen, blur. Reduce noise, fix red-eyes, erase power lines, fix perspective. Make composite images: HDR, HDF, stack, and panorama. Annotate images. Make artful transforms. Do a slide show. Create named collections. Burn a CD or DVD. Edit tags, comments, captions, dates and star-ratings. Search images using these criteria plus directory and file names. fotoxx-12.01.2/f.tools.cc0000644000175000017500000042542311701011017013536 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image edit - Tools menu functions ***************************************************************************/ // Manage Collections void m_manage_collections(GtkWidget *, cchar *) // v.11.11 { int manage_coll_dialog_event(zdialog *zd, cchar *event); // manage collectiond dialog event func zdialog *zd; cchar *helptext = ZTX("When editing a collection, right-click \n" "an image or thumbnail to add or remove."); zfuncs::F1_help_topic = "manage_collections"; if (mod_keep()) return; // unsaved edits /*** __________________________________________ | | | Manage Collections | | | | When editing a collection, right-click | | an image or thumbnail to add or remove. | | | | [New] Start a new collection | | [Edit] Edit a collection | | [View] View a collection | | [Delete] Delete a collection | | | | Editing: | | Action: xxxxxxxxxxxxxx | | | | [Done] | |__________________________________________| ***/ zd = zdialog_new(ZTX("Manage Collections"),mWin,Bdone,null); zd_edit_coll = zd; zdialog_add_widget(zd,"label","labhelp","dialog",helptext,"space=5"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"button","new","vb1",Bnew); zdialog_add_widget(zd,"button","edit","vb1",Bedit); zdialog_add_widget(zd,"button","view","vb1",Bview); zdialog_add_widget(zd,"button","delete","vb1",Bdelete); zdialog_add_widget(zd,"hbox","hbnew","vb2"); zdialog_add_widget(zd,"label","labnew","hbnew",ZTX("Start new collection")); zdialog_add_widget(zd,"hbox","hbedit","vb2"); zdialog_add_widget(zd,"label","labedit","hbedit",ZTX("Edit a collection")); zdialog_add_widget(zd,"hbox","hbview","vb2"); zdialog_add_widget(zd,"label","labview","hbview",ZTX("View a collection")); zdialog_add_widget(zd,"hbox","hbdel","vb2"); zdialog_add_widget(zd,"label","labdel","hbdel",ZTX("Delete a collection")); zdialog_add_widget(zd,"hsep","sep","dialog",0,"space=3"); zdialog_add_widget(zd,"hbox","hbedit","dialog"); zdialog_add_widget(zd,"label","labedit","hbedit",ZTX("Editing:"),"space=3"); zdialog_add_widget(zd,"label","editcoll","hbedit",0,"space=3"); zdialog_add_widget(zd,"hbox","hbact","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labact","hbact",ZTX("Action:"),"space=3"); zdialog_add_widget(zd,"label","lastact","hbact",0,"space=3"); zdialog_help(zd,"manage_collections"); zdialog_resize(zd,300,0); zdialog_run(zd,manage_coll_dialog_event); zdialog_wait(zd); zdialog_free(zd); zd_edit_coll = 0; if (edit_coll_name) zfree(edit_coll_name); // no collection for editing edit_coll_name = 0; return; } // manage collections dialog event and completion function int manage_coll_dialog_event(zdialog *zd, cchar *event) // v.11.11 { int err; FILE *fid; char *pp; struct stat statb; if (strEqu(event,"new")) // start a new collection for editing { if (edit_coll_name) { // no current collection zfree(edit_coll_name); edit_coll_name = 0; } if (edit_coll_file) zfree(edit_coll_file); edit_coll_file = zgetfile1(ZTX("New Collection"),"save",collections_dirk); if (! edit_coll_file) return 0; fid = fopen(edit_coll_file,"w"); // open collection file if (! fid) return 0; fprintf(fid,"Fotoxx Collection \n"); // write one record fclose(fid); pp = strrchr(edit_coll_file,'/'); // file name = collection name edit_coll_name = strdupz(pp+1); // set current edit collection zdialog_stuff(zd,"editcoll",edit_coll_name); return 0; } if (strEqu(event,"edit")) // choose a collection for editing { if (edit_coll_name) { // no current collection zfree(edit_coll_name); edit_coll_name = 0; } if (edit_coll_file) zfree(edit_coll_file); edit_coll_file = zgetfile1(ZTX("Edit Collection"),"open",collections_dirk); if (! edit_coll_file) return 0; err = stat(edit_coll_file,&statb); if (err) return 0; pp = strrchr(edit_coll_file,'/'); // file name = collection name edit_coll_name = strdupz(pp+1); // set current edit collection zdialog_stuff(zd,"editcoll",edit_coll_name); return 0; } if (strEqu(event,"view")) // choose a collection for viewing { if (edit_coll_file) zfree(edit_coll_file); edit_coll_file = zgetfile1(ZTX("View Collection"),"open",collections_dirk); if (! edit_coll_file) return 0; err = stat(edit_coll_file,&statb); if (err) return 0; image_gallery(edit_coll_file,"initF",0,m_gallery2,mWin); // generate gallery of files in coll. if (edit_coll_memberfile) zfree(edit_coll_memberfile); edit_coll_memberfile = image_gallery(0,"find",0); // top of list if (! edit_coll_memberfile) return 0; f_open(edit_coll_memberfile,1); // open first file zmainloop(); image_gallery(0,"paint1"); // show new image gallery window return 0; } if (strEqu(event,"delete")) // choose collection to delete { if (edit_coll_file) zfree(edit_coll_file); edit_coll_file = zgetfile1(ZTX("Delete Collection"),"open",collections_dirk); if (! edit_coll_file) return 0; if (! zmessageYN(mWin,ZTX("delete %s ?"),edit_coll_file)) return 0; remove(edit_coll_file); // delete it return 0; } return 0; } // Popup menu for editing a collection. // This function is called when a thumbnail is right-clicked. void edit_coll_popmenu(GtkWidget *, char *file) { void edit_coll_popfunc(GtkWidget *, cchar *menu); GtkWidget *popmenu; static char addmenuitem[200]; if (! edit_coll_name) return; // no edit in progress, do nothing if (edit_coll_memberfile) zfree(edit_coll_memberfile); // save clicked thumbnail file edit_coll_memberfile = strdupz(file,0,"edit_coll"); popmenu = create_popmenu(); // create popup menu snprintf(addmenuitem,200,ZTX("add image to collection: %s"),edit_coll_name); add_popmenu_item(popmenu,addmenuitem,edit_coll_popfunc); add_popmenu_item(popmenu,ZTX("remove image from collection"),edit_coll_popfunc); add_popmenu_item(popmenu,ZTX("remove and save image"),edit_coll_popfunc); add_popmenu_item(popmenu,ZTX("insert saved images here"),edit_coll_popfunc); popup_menu(popmenu); return; } // Response function for the edit collections popup menu void edit_coll_popfunc(GtkWidget *, cchar *menu) { int ii, found = 0; FILE *fidr, *fidw; char collfile[maxfcc], buff[maxfcc]; char *filename, tempfile[200]; static char *saved_files[100]; static int Nsaved = 0; if (! edit_coll_name) return; // no edit in progress, do nothing if (! edit_coll_memberfile) return; // no member file for action if (! zd_edit_coll) return; strcpy(collfile,collections_dirk); // edit collection full path strcat(collfile,edit_coll_name); strcpy(tempfile,collections_dirk); // temp file for copying strcat(tempfile,"tempfile"); if (strnEqu(menu,ZTX("add image to collection"),23)) { fidw = fopen(collfile,"a"); // append new file at end of list if (! fidw) return; fprintf(fidw,"%s\n",edit_coll_memberfile); fclose(fidw); filename = strrchr(edit_coll_memberfile,'/') + 1; // notify in dialog window sprintf(buff,"Add: %s",filename); zdialog_stuff(zd_edit_coll,"lastact",buff); return; } if (strEqu(menu,ZTX("remove image from collection")) || strEqu(menu,ZTX("remove and save image"))) { fidr = fopen(collfile,"r"); // copy collection file and omit if (! fidr) return; // the image file being removed fidw =fopen(tempfile,"w"); if (! fidw) return; while (true) { filename = fgets_trim(buff,maxfcc,fidr); if (! filename) break; if (strEqu(filename,edit_coll_memberfile)) { found = 1; continue; } fprintf(fidw,"%s\n",filename); } fclose(fidr); fclose(fidw); rename(tempfile,collfile); filename = strrchr(edit_coll_memberfile,'/') + 1; // notify in dialog window if (found) sprintf(buff,"Removed: %s",filename); else sprintf(buff,"Not found: %s",filename); zdialog_stuff(zd_edit_coll,"lastact",buff); if (found && strEqu(menu,ZTX("remove and save image"))) // add file to list of saved files { if (Nsaved > 99) { zmessageACK(mWin,ZTX("too many saved files")); return; } saved_files[Nsaved] = strdupz(edit_coll_memberfile,0,"edit_coll"); Nsaved++; } if (strEqu(collfile,image_navi::galleryname)) { image_gallery(collfile,"initF",0,m_gallery2,mWin); // update gallery window image_gallery(0,"paint2",-1); } return; } if (strEqu(menu,ZTX("insert saved images here"))) { if (! Nsaved) return; if (strNeq(collfile,image_navi::galleryname)) return; // gallery not the edit collection fidr = fopen(collfile,"r"); // copy collection file and insert if (! fidr) return; // the saved image files fidw =fopen(tempfile,"w"); if (! fidw) return; while (true) { filename = fgets_trim(buff,maxfcc,fidr); if (! filename) break; fprintf(fidw,"%s\n",filename); if (strNeq(filename,edit_coll_memberfile)) continue; for (ii = 0; ii < Nsaved; ii++) { fprintf(fidw,"%s\n",saved_files[ii]); zfree(saved_files[ii]); } } fclose(fidr); fclose(fidw); rename(tempfile,collfile); sprintf(buff,"inserted %d files",Nsaved); zdialog_stuff(zd_edit_coll,"lastact",buff); Nsaved = 0; image_gallery(collfile,"initF",0,m_gallery2,mWin); // update gallery window image_gallery(0,"paint2",-1); return; } } /**************************************************************************/ // Change the top directory for all image collections. // This facilitates changing the Fotoxx top image directory // without having to re-create all collections. void m_move_collections(GtkWidget *, cchar *) { zdialog *zd; char *pp, oldtop[200], newtop[200]; char command[200], buffr[maxfcc], buffw[maxfcc]; char collfile[200], tempfile[200]; int zstat, contx = 0, err; FILE *fidr, *fidw; zfuncs::F1_help_topic = "move_collections"; if (mod_keep()) return; // unsaved edits zd = zdialog_new(ZTX("Move Collections"),mWin,Bapply,Bcancel,null); zdialog_add_widget(zd,"hbox","hbold","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labold","hbold",ZTX("old top directory"),"space=5"); zdialog_add_widget(zd,"entry","oldtop","hbold",0,"scc=30"); zdialog_add_widget(zd,"hbox","hbnew","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labnew","hbnew",ZTX("new top directory"),"space=5"); zdialog_add_widget(zd,"entry","newtop","hbnew",0,"scc=30"); zdialog_stuff(zd,"oldtop",topdirk); zdialog_stuff(zd,"newtop",topdirk); zdialog_help(zd,"move_collections"); zdialog_run(zd); zstat = zdialog_wait(zd); if (zstat != 1) { zdialog_free(zd); return; } zdialog_fetch(zd,"oldtop",oldtop,200); // old and new top directory paths zdialog_fetch(zd,"newtop",newtop,200); zdialog_free(zd); snprintf(tempfile,200,"%s/move-collection",get_zuserdir()); snprintf(command,200,"find -L %s -type f",collections_dirk); // find all collections printf("%s \n",command); while ((pp = command_output(contx,command,null))) // loop all collections { printf("%s \n",pp); strncpy0(collfile,pp,200); zfree(pp); fidr = fopen(collfile,"r"); // open collection and temp files if (! fidr) break; fidw = fopen(tempfile,"w"); if (! fidw) break; while ((pp = fgets(buffr,maxfcc,fidr))) // loop collection recs { repl_1str(buffr,buffw,oldtop,newtop); // replace top directory path err = fputs(buffw,fidw); if (err < 0) break; } err = fclose(fidr); err = fclose(fidw); if (err) break; err = rename(tempfile,collfile); // replace collection with temp file if (err) break; } if (err) { err = errno; printf("%s \n %s \n",collfile,strerror(err)); zmessageACK(mWin,"%s \n %s",collfile,strerror(err)); } else zmessageACK(mWin,ZTX("completed")); return; } /**************************************************************************/ // Batch file convert - change format (file type), resize, export void m_batchconvert(GtkWidget *, cchar *) // new v.10.8 { int batchconvert_dialog_event(zdialog *zd, cchar *event); zfuncs::F1_help_topic = "batch_convert"; // v.10.8 if (is_syncbusy()) return; // must wait for file sync v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // lock menus /*** Batch Convert/Resize/Export [select files] N files selected new max. width [____] height [____] new file type (o) same (o) JPG (o) PNG (o) TIF (o) replace originals [x] remove EXIF (o) export to location [browse] [_________________________________] [proceed] [cancel] ***/ zdialog *zd = zdialog_new(ZTX("Batch Convert/Resize/Export"),mWin,Bproceed,Bcancel,null); zdialog_add_widget(zd,"hbox","hbf","dialog",0,"space=5"); zdialog_add_widget(zd,"button","files","hbf",Bselectfiles,"space=5"); zdialog_add_widget(zd,"label","fcount","hbf","0 files selected","space=10"); zdialog_add_widget(zd,"hbox","hbwh","dialog"); zdialog_add_widget(zd,"label","labw","hbwh",ZTX("new max. width"),"space=5"); zdialog_add_widget(zd,"entry","maxw","hbwh","1000","scc=5"); zdialog_add_widget(zd,"label","space","hbwh",0,"space=5"); zdialog_add_widget(zd,"label","labh","hbwh",ZTX("height"),"space=5"); zdialog_add_widget(zd,"entry","maxh","hbwh","700","scc=5"); zdialog_add_widget(zd,"hbox","hbtyp","dialog",0,"space=4"); zdialog_add_widget(zd,"label","labtyp","hbtyp",ZTX("new file type"),"space=5"); zdialog_add_widget(zd,"radio","same","hbtyp",ZTX("same"),"space=6"); zdialog_add_widget(zd,"radio","jpg","hbtyp","JPG","space=6"); zdialog_add_widget(zd,"radio","png","hbtyp","PNG","space=6"); zdialog_add_widget(zd,"radio","tif","hbtyp","TIF","space=6"); zdialog_add_widget(zd,"hbox","hbrep","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vbrep1","hbrep",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vbrep2","hbrep",0,"homog|space=5"); zdialog_add_widget(zd,"radio","replace","vbrep1",ZTX("replace originals")); zdialog_add_widget(zd,"radio","export","vbrep1",ZTX("export to location")); zdialog_add_widget(zd,"check","noexif","vbrep2",ZTX("remove EXIF")); zdialog_add_widget(zd,"hbox","hbloc","dialog",0,"space=3|expand"); zdialog_add_widget(zd,"button","browse","hbloc",Bbrowse,"space=5"); zdialog_add_widget(zd,"entry","location","hbloc",0,"scc=30|expand"); zdialog_stuff(zd,"same",1); // defaults: zdialog_stuff(zd,"replace",0); // same file type, export, no EXIF zdialog_stuff(zd,"export",1); zdialog_stuff(zd,"noexif",1); zdialog_stuff(zd,"maxw",batchresize[0]); // v.10.9 zdialog_stuff(zd,"maxh",batchresize[1]); zdialog_help(zd,"batch_convert"); // zdialog help topic v.11.08 zdialog_run(zd,batchconvert_dialog_event,"parent"); // run dialog v.11.07 zdialog_wait(zd); // wait for completion menulock(0); return; } // dialog event and completion callback function int batchconvert_dialog_event(zdialog *zd, cchar *event) { static char **flist = 0; char countmess[50]; int Freplace, maxw, maxh, Fnoexif, yn; int ii, err, lcc, fcc, ww, hh, fposn; char location[maxfcc], *pp, *ploc, *pfile; cchar *pext, *ptype; char *oldfile, *newfile, *tempfile; double scale, wscale, hscale; PXM *pxmout; struct stat statb; if (strEqu(event,"files")) // select images to convert { if (flist) { // free prior list for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); } flist = image_gallery_getfiles(0,mWin); // get list of files to convert v.10.9 if (flist) // count files selected for (ii = 0; flist[ii]; ii++); else ii = 0; snprintf(countmess,50,ZTX("%d files selected"),ii); // update dialog zdialog_stuff(zd,"fcount",countmess); } if (strEqu(event,"browse")) { ploc = zgetfile1(ZTX("Select directory"),"folder",curr_dirk); // get directory v.10.9 if (! ploc) return 0; zdialog_stuff(zd,"location",ploc); zfree(ploc); zdialog_stuff(zd,"export",1); } if (! zd->zstat) return 0; // dialog still busy if (zd->zstat != 1) goto cleanup; // dialog canceled if (! flist) { // no files selected zd->zstat = 0; // keep dialog active return 0; } zdialog_fetch(zd,"maxw",maxw); // new max width zdialog_fetch(zd,"maxh",maxh); // new max height zdialog_fetch(zd,"replace",Freplace); // replace originals y/n zdialog_fetch(zd,"noexif",Fnoexif); // copy EXIF/IPTC y/n zdialog_fetch(zd,"same",ii); // get new file type v.11.12 if (ii) ptype = 0; zdialog_fetch(zd,"jpg",ii); if (ii) ptype = ".jpg"; zdialog_fetch(zd,"png",ii); if (ii) ptype = ".png"; zdialog_fetch(zd,"tif",ii); if (ii) ptype = ".tif"; zdialog_fetch(zd,"location",location,maxfcc); // output location (Freplace = 0) strTrim2(location,location); // trim leading and trailing blanks if (Freplace) { yn = zmessageYN(mWin,ZTX("replace original files? (max. %d x %d)"),maxw,maxh); if (! yn) { zd->zstat = 0; return 0; } } else { yn = zmessageYN(mWin,ZTX("copy files? (max. %d x %d) \n" " to location %s"),maxw,maxh,location); if (! yn) { zd->zstat = 0; return 0; } } if (! Freplace) { err = stat(location,&statb); if (err || ! S_ISDIR(statb.st_mode)) { zmessageACK(mWin,ZTX("location is not a valid directory")); zd->zstat = 0; return 0; } } if (maxw < 20 || maxh < 20) { zmessageACK(mWin,ZTX("max. size %d x %d is not reasonable"),maxw,maxh); zd->zstat = 0; return 0; } write_popup_text("open","Processing files",500,200,mWin); // status monitor popup window lcc = strlen(location); if (! Freplace && location[lcc-1] == '/') lcc--; // remove trailing '/' for (ii = 0; flist[ii]; ii++) // loop selected files { oldfile = flist[ii]; if (Freplace) newfile = strdupz(oldfile,8,"batchconvert"); // new file = old file else { pfile = strrchr(oldfile,'/'); if (! pfile) continue; fcc = strlen(pfile); newfile = strdupz(location,fcc+9,"batchconvert"); strcpy(newfile+lcc,pfile); // new file at location } pp = strrchr(newfile,'/'); // find existing file .ext pp = strrchr(pp,'.'); if (! pp) pp = pp + strlen(pp); if (strlen(pp) > 5) pp = pp + strlen(pp); pext = 0; if (ptype) pext = ptype; // new .ext from user else { if (strstr(".JPG .jpg .JPEG .jpeg",pp)) pext = ".jpg"; // new .ext from existing .ext if (strstr(".PNG .png",pp)) pext = ".png"; if (strstr(".TIF .TIFF .tif .tiff",pp)) pext = ".tif"; } if (! pext) pext = ".jpg"; strcpy(pp,pext); // set new file .ext write_popup_text("write",newfile); // report progress zmainloop(); if (! Freplace) { err = stat(newfile,&statb); // if export, check if file exists if (! err) { write_popup_text("write",ZTX("*** file already exists")); zfree(newfile); continue; } } err = f_open(oldfile,0); // open old file if (err) { write_popup_text("write",ZTX("*** file type not supported")); zfree(newfile); continue; } wscale = hscale = 1.0; if (Fww > maxw) wscale = 1.0 * maxw / Fww; // compute new size if (Fhh > maxh) hscale = 1.0 * maxh / Fhh; if (wscale < hscale) scale = wscale; else scale = hscale; ww = Fww * scale; hh = Fhh * scale; pxmout = PXM_rescale(Fpxm8,ww,hh); // rescale file tempfile = strdupz(newfile,12,"batchconvert"); // temp file needed for EXIF/IPTC copy pp = strrchr(tempfile,'.'); strcpy(pp,"-temp"); strcpy(pp+5,pext); if (strstr(".jpg .png",pext)) // write rescaled file to temp file PXBwrite(pxmout,tempfile); else TIFFwrite(pxmout,tempfile); if (! Fnoexif) // copy EXIF/IPTC if requested v.11.12 info_copy(oldfile,tempfile,0,0,0); snprintf(command,ccc,"cp -p \"%s\" \"%s\" ",tempfile,newfile); // copy tempfile to newfile err = system(command); if (err) write_popup_text("write",wstrerror(err)); remove(tempfile); // remove tempfile if (Freplace && ! err && strNeq(oldfile,newfile)) // remove oldfile if not remove(oldfile); // already replaced zfree(newfile); zfree(tempfile); PXM_free(pxmout); } write_popup_text("write","COMPLETED"); batchresize[0] = maxw; // save preferred size v.10.9 batchresize[1] = maxh; cleanup: if (flist) { // free memory for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); flist = 0; } zdialog_free(zd); // kill dialog image_gallery(curr_file,"init"); // generate new gallery list v.11.12 fposn = image_gallery_position(curr_file,0); image_gallery(0,"paint2",fposn); // refresh gallery window if active return 0; } /**************************************************************************/ // open a single RAW file or convert multiple RAW files to tiff void m_conv_raw(GtkWidget *, cchar *menu) // simplified v.11.08 { char **raw_files; char *rawfile, *outfile, *pp; int ii, bpc, err, filecount; cchar *ftype; zfuncs::F1_help_topic = "convert_RAW"; if (! Fufraw) { zmessageACK(mWin,ZTX("Program ufraw-batch is required")); return; } if (is_syncbusy()) return; // must wait for file sync v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; if (strEqu(menu,"Open RAW File")) // convert one file v.11.08 { rawfile = zgetfile1(ZTX("Open RAW File"),"open",curr_dirk); if (! rawfile) { menulock(0); return; } raw_files = (char **) zmalloc(2 * sizeof(char *),"conv-RAW"); raw_files[0] = rawfile; raw_files[1] = 0; ftype = "tiff"; // default tiff/16 format v.11.12 bpc = 16; } else // convert multiple files { raw_files = zgetfileN(ZTX("Select RAW files to convert"),"openN",curr_dirk); if (! raw_files) { menulock(0); return; } ii = zdialog_choose(0,mWin,ZTX("Choose file type"), // set file type v.11.12 "JPG", "PNG", "TIFF-8", "TIFF-16", null); if (ii == 1) ftype = "jpg"; if (ii == 2) ftype = "png"; if (ii == 3) ftype = "tif"; if (ii == 4) ftype = "tiff"; bpc = 8; if (ii == 4) bpc = 16; } for (ii = 0; raw_files[ii]; ii++); // count selected files filecount = ii; write_popup_text("open","Converting RAW files",500,200,mWin); // status monitor popup window write_popup_text("write","converting ..."); for (ii = 0; ii < filecount; ii++) { rawfile = raw_files[ii]; outfile = strdupz(rawfile,5,"raw_out"); pp = strrchr(rawfile,'.'); pp = outfile + (pp - rawfile); pp[0] = '.'; strcpy(pp+1,ftype); // v.11.12 write_popup_text("write",rawfile); // write output to log window snprintf(command,ccc,"ufraw-batch --wb=camera --out-type=%s --out-depth=%d" " --overwrite --output=\"%s\" \"%s\" ", ftype, bpc, outfile, rawfile); err = system(command); if (err) { write_popup_text("write",wstrerror(err)); zfree(outfile); continue; } f_open(outfile,0); // open converted file in main window zfree(outfile); zmainloop(); } write_popup_text("write","COMPLETED"); write_popup_text("close",0); image_gallery(curr_file,"init"); // update gallery file list image_gallery(0,"paint2",curr_file_posn); // refresh gallery window if active for (ii = 0; raw_files[ii]; ii++) // free memory zfree(raw_files[ii]); zfree(raw_files); menulock(0); return; } /**************************************************************************/ // enter or leave slideshow mode int ss_interval = 3; // slide show interval int ss_timer = 0; // slide show timer int ss_latest = 0; // show only latest revision files char *ss_oldfile, *ss_newfile; // image files for transition PXM *ss_pxmold, *ss_pxmnew, *ss_pxmmix; // pixmap images: old, new, mixed int ss_ww, ss_hh; // full screen window size int ss_busy = 0; // transition underway int ss_escape = 0; // user pressed Escape key int ss_paused = 0; // user pressed P key (pause/resume) void ss_instant(); // transition functions void ss_fadein(); void ss_rollright(); void ss_rolldown(); void ss_shiftleft(); void ss_venetian(); void ss_grate(); void ss_rectangle(); void ss_ellipse(); void ss_radar(); void ss_jaws(); char * ss_prev(int posn); char * ss_next(int posn); char * ss_prev_latest(int posn); char * ss_next_latest(int posn); char * ss_basename(char *file); struct ss_table_t { cchar *name; cchar *vbox; void (*func)(); }; ss_table_t ss_table[SSNF] = // image transition types { { "arrow keys", "vb41", null }, // name, zdialog parent, function { "instant", "vb41", ss_instant }, { "fade-in", "vb41", ss_fadein }, { "roll-right", "vb41", ss_rollright }, { "roll-down", "vb42", ss_rolldown }, { "shift-left", "vb42", ss_shiftleft }, { "venetian", "vb42", ss_venetian }, { "grate", "vb42", ss_grate }, { "rectangle", "vb43", ss_rectangle }, { "ellipse", "vb43", ss_ellipse }, { "radar", "vb43", ss_radar }, { "jaws", "vb43", ss_jaws } }; void m_slideshow(GtkWidget *, cchar *) { int slideshow_dialog_event(zdialog *zd, cchar *event); zdialog *zd; int zstat, secs, err, ii; cchar *esc_message = ZTX("Press ESC to exit slide show"); cchar *latest_message = ZTX("show only latest file versions"); zfuncs::F1_help_topic = "slide_show"; // v.10.8 ss_table[0].name = ZTX("arrow keys"); // use translated names ss_table[1].name = ZTX("instant"); ss_table[2].name = ZTX("fade-in"); ss_table[3].name = ZTX("roll-right"); ss_table[4].name = ZTX("roll-down"); ss_table[5].name = ZTX("shift-left"); ss_table[6].name = ZTX("venetian"); ss_table[7].name = ZTX("grate"); ss_table[8].name = ZTX("rectangle"); ss_table[9].name = ZTX("ellipse"); ss_table[10].name = ZTX("radar"); ss_table[11].name = ZTX("jaws"); if (! Fslideshow) // start slide show { if (! curr_file) return; if (! menulock(1)) return; zd = zdialog_new(ZTX("Slide Show"),mWin,Bproceed,Bcancel,null); // user dialog zdialog_add_widget(zd,"hbox","hbesc","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labesc","hbesc",esc_message,"space=3"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labsecs","hb1",ZTX("seconds"),"space=3"); zdialog_add_widget(zd,"entry","secs","hb1","3","scc=5"); zdialog_add_widget(zd,"check","latest","hb1",latest_message,"space=8"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=3"); zdialog_add_widget(zd,"label","lab21","hb2",ZTX("music file"),"space=3"); zdialog_add_widget(zd,"entry","musicfile","hb2",0,"scc=30|space=5"); zdialog_add_widget(zd,"button","browse","hb2",Bbrowse,"space=5"); zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=3"); zdialog_add_widget(zd,"label","lab3","hb3",ZTX("transitions"),"space=3"); zdialog_add_widget(zd,"hbox","hb4","dialog"); zdialog_add_widget(zd,"vbox","vb41","hb4",0,"space=8"); zdialog_add_widget(zd,"vbox","vb42","hb4",0,"space=8"); zdialog_add_widget(zd,"vbox","vb43","hb4",0,"space=8"); for (ii = 0; ii < SSNF; ii++) { // add transition check boxes zdialog_add_widget(zd,"check",ss_table[ii].name, ss_table[ii].vbox,ss_table[ii].name); if (ss_funcs[ii]) zdialog_stuff(zd,ss_table[ii].name,1); // restore user preferences } if (ss_interval < 9999) zdialog_stuff(zd,"secs",ss_interval); // stuff last time interval zdialog_stuff(zd,"musicfile",ss_musicfile); // stuff last music file zdialog_help(zd,"slide_show"); // zdialog help topic v.11.08 zdialog_run(zd,slideshow_dialog_event); // run dialog zstat = zdialog_wait(zd); // wait for completion if (zstat != 1) { // cancel zdialog_free(zd); menulock(0); return; } zdialog_fetch(zd,"secs",secs); // get interval, seconds zdialog_fetch(zd,"latest",ss_latest); // get "latest files only" option for (ii = 0; ii < SSNF; ii++) // get selected transition types zdialog_fetch(zd,ss_table[ii].name,ss_funcs[ii]); // v.11.08 for (ii = 1; ii < SSNF; ii++) // check selections if (ss_funcs[ii]) break; if (ii < SSNF) ss_funcs[0] = 0; // if some, remove arrow keys else ss_funcs[0] = 1; // if none, default arrow keys char *pp = zmalloc(500,"musicfile"); zdialog_fetch(zd,"musicfile",pp,499); // get music file ss_musicfile = pp; zdialog_free(zd); ss_interval = secs; // interval between slides if (ss_funcs[0]) ss_interval = 9999; // if manual transition, huge interval ss_paused = 0; // not paused v.11.10 if (ss_musicfile && *ss_musicfile && strNeq(ss_musicfile,"undefined")) { // if music file present, start it up sprintf(command,"xdg-open \"%s\" ",ss_musicfile); // v.11.04 printf("command: %s \n",command); err = system(command); if (err) printf("error: %s \n",wstrerror(err)); } gtk_widget_hide_all(GTK_WIDGET(mMbar)); // enter slide show mode gtk_widget_hide_all(GTK_WIDGET(mTbar)); // (full screen, no extras) gtk_widget_hide_all(GTK_WIDGET(STbar)); gdk_window_set_background(drWin->window,&black); // black background v.11.10 gtk_window_maximize(MWIN); // avoid gtk_window_fullscreen() zmainloop(); // must wait for update v.11.10 gtk_window_get_size(MWIN,&ss_ww,&ss_hh); ss_pxmold = PXM_make(ss_ww,ss_hh,8); // make 3 screen-size pixmaps ss_pxmnew = PXM_make(ss_ww,ss_hh,8); ss_pxmmix = PXM_make(ss_ww,ss_hh,8); ss_newfile = strdupz(curr_file); // start with current image ss_oldfile = 0; ss_timer = get_seconds() + ss_interval; // set timer for first call to Fslideshow = 1; // ss_slideshow_next() } else // leave slide show mode { if (ss_busy) { ss_escape = 1; // wait for transition done return; } ss_escape = 0; Fslideshow = 0; gdk_window_set_background(drWin->window,&lgray); // restore background v.11.10 gtk_window_unmaximize(MWIN); // restore old window size v.11.10 gtk_widget_show_all(GTK_WIDGET(mMbar)); gtk_widget_show_all(GTK_WIDGET(mTbar)); gtk_widget_show_all(GTK_WIDGET(STbar)); if (ss_newfile) zfree(ss_newfile); // free memory if (ss_oldfile) zfree(ss_oldfile); ss_newfile = ss_oldfile = 0; PXM_free(ss_pxmold); PXM_free(ss_pxmnew); PXM_free(ss_pxmmix); menulock(0); } Fblowup = Fslideshow; Fzoom = 0; // fit image to window mwpaint2(); return; } // dialog event function - file chooser for music file int slideshow_dialog_event(zdialog *zd, cchar *event) // v.11.04 { char *pp; if (! strEqu(event,"browse")) return 0; pp = zgetfile1(ZTX("Select music file or playlist"),"open",ss_musicfile); if (! pp) return 0; zdialog_stuff(zd,"musicfile",pp); zfree(pp); return 0; } // Show next slide if time is up or user navigates with arrow keys. // Called by timer function and by keyboard function if Fslideshow is set. void slideshow_next(cchar *mode) // new v.11.01 { void ss_loadimage(char *file, PXM *pxmout); double secs; char *pp = 0; int Fkey = 0, cp, ii; static int last_transition = 0; if (strEqu(mode,"pause")) // toggle slide show paused status ss_paused = 1 - ss_paused; // (spacebar) v.11.10 if (ss_busy) return; // come back later if (ss_escape) { // user pressed escape key m_slideshow(0,0); // exit slide show return; } if (strEqu(mode,"timer")) { // timer trigger if (ss_paused) return; secs = get_seconds(); if (secs < ss_timer) return; mode = "next"; // time for next image Fkey = 0; } else Fkey = 1; // keyboard trigger cp = curr_file_posn; if (ss_latest) { // get prev/next image file, if (strEqu(mode,"prev")) // latest version v.11.10 pp = ss_prev_latest(cp); if (strEqu(mode,"next")) pp = ss_next_latest(cp); } else { // get prev or next image file if (strEqu(mode,"prev")) pp = ss_prev(cp); if (strEqu(mode,"next")) pp = ss_next(cp); } if (! pp) return; // there is none ss_busy++; if (ss_oldfile) zfree(ss_oldfile); ss_oldfile = ss_newfile; ss_newfile = pp; ss_loadimage(ss_oldfile,ss_pxmold); ss_loadimage(ss_newfile,ss_pxmnew); mutex_lock(&Fpixmap_lock); // block other window updates if (Fkey) ss_instant(); // KB input, do instant transition else // use next selected transition type { // v.11.08 ii = last_transition; // start with last transition type + 1 if (++ii > SSNF-1) ii = 1; // 1st is omitted (arrow keys) while (! ss_funcs[ii]) // infinite loop if none selected if (++ii > SSNF-1) ii = 1; // bugfix v.11.09.1 last_transition = ii; // next transition if (ii > 0) ss_table[ii].func(); // do image transition } mutex_unlock(&Fpixmap_lock); zmainloop(); // catch-up anynch window updates? f_open(ss_newfile,0); // sync all image data if (zdeditcctext) m_edit_cctext(0,0); // edit caption and comments dialog secs = get_seconds(); // set time for next image ss_timer = secs + ss_interval + 0.5; ss_busy = 0; return; } // get previous file before current file char * ss_prev(int cp) { char *pp; int ii; for (ii = cp-1; ii >= 0; ii--) { pp = image_gallery(0,"find",ii); if (pp) return pp; } return 0; } // get next file after current file char * ss_next(int cp) { char *pp; int ii; int nfiles = image_navi::nfiles; for (ii = cp+1; ii < nfiles; ii++) { pp = image_gallery(0,"find",ii); if (pp) return pp; } return 0; } // get previous file, latest version, before current file char * ss_prev_latest(int cp) // new v.11.10 { char *pp, *name1, *name2; int ii; pp = image_gallery(0,"find",cp); if (! pp) return 0; name1 = ss_basename(pp); zfree(pp); for (ii = cp-1; ii >= 0; ii--) { pp = image_gallery(0,"find",ii); if (! pp) { zfree(name1); return 0; } name2 = ss_basename(pp); if (strEqu(name1,name2)) { zfree(name2); zfree(pp); } else { zfree(name1); zfree(name2); return pp; } } return 0; } // get next file, latest version, after current file char * ss_next_latest(int cp) // new v.11.10 { char *pp1, *pp2, *name1, *name2; int ii; int nfiles = image_navi::nfiles; pp1 = image_gallery(0,"find",cp+1); if (! pp1) return 0; name1 = ss_basename(pp1); for (ii = cp+2; ii < nfiles; ii++) { pp2 = image_gallery(0,"find",ii); if (! pp2) { zfree(name1); return pp1; } name2 = ss_basename(pp2); if (strEqu(name1,name2)) { zfree(pp1); zfree(name2); pp1 = pp2; } else { zfree(pp2); zfree(name1); zfree(name2); return pp1; } } return 0; } // extract base name from image file name // base name is file name without directory, version, extension char * ss_basename(char *file) // v.11.10 { char *pp1, *pp2, *pp3; pp1 = strrchr(file,'/'); // skip over directory if present if (pp1) file = pp1 + 1; pp1 = strdupz(file,0,"ss.basename"); pp2 = strrchr(pp1,'.'); // look for .ext if (! pp2) return pp1; *pp2 = 0; // strip it off pp3 = pp2 - 4; if (! strnEqu(pp3,".v",2)) return pp1; // look for version .v00 to .v99 if (pp3[2] < '0' || pp3[2] > '9') return pp1; if (pp3[3] < '0' || pp3[3] > '9') return pp1; *pp3 = 0; // strip it off return pp1; } // load image and rescale to fit in given pixmap = window size void ss_loadimage(char *file, PXM *pxmout) // new v.11.01 { int cc, fww, fhh, px, py, orgx, orgy; PXM *pxmtemp1, *pxmtemp2; double wscale, hscale, scale; uint8 *pix1, *pix2; cc = ss_ww * ss_hh * 3; // clear output pixmap black v.11.10 memset(pxmout->bmp,0,cc); pxmtemp1 = f_load(file,8); // load image file into 1x pixmap if (! pxmtemp1) return; fww = pxmtemp1->ww; // image size fhh = pxmtemp1->hh; wscale = 1.0 * ss_ww / fww; // find scale to fit in window hscale = 1.0 * ss_hh / fhh; if (wscale < hscale) scale = wscale; // use greatest ww/hh ratio else scale = hscale; fww = fww * scale; fhh = fhh * scale; pxmtemp2 = PXM_rescale(pxmtemp1,fww,fhh); // rescale image to fit window orgx = 0.5 * (ss_ww - fww); // origin of image in window orgy = 0.5 * (ss_hh - fhh); for (py = 0; py < fhh; py++) for (px = 0; px < fww; px++) { pix1 = PXMpix8(pxmtemp2,px,py); pix2 = PXMpix8(pxmout,px+orgx,py+orgy); pix2[0] = pix1[0]; pix2[1] = pix1[1]; pix2[2] = pix1[2]; } PXM_free(pxmtemp1); PXM_free(pxmtemp2); return; } // instant transition (for use with keyboard arrow keys) void ss_instant() // new v.11.01 { uint8 *pix3; pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww*3); return; } // fade-out / fade-in transition void ss_fadein() // new v.11.01 { int ii, jj, kk, px, py; double newpart, oldpart; uint8 *pix1, *pix2, *pix3; PXM_free(ss_pxmmix); ss_pxmmix = PXM_copy(ss_pxmold); for (ii = 0; ii <= 100; ii += 10) { newpart = 0.01 * ii; oldpart = 1.0 - newpart; for (jj = 0; jj < 2; jj++) // four passes, each modifies 25% for (kk = 0; kk < 2; kk++) // of the pixels (visually smoother) { for (py = jj; py < ss_hh; py += 2) for (px = kk; px < ss_ww; px += 2) { pix1 = PXMpix8(ss_pxmold,px,py); pix2 = PXMpix8(ss_pxmnew,px,py); pix3 = PXMpix8(ss_pxmmix,px,py); pix3[0] = newpart * pix2[0] + oldpart * pix1[0]; pix3[1] = newpart * pix2[1] + oldpart * pix1[1]; pix3[2] = newpart * pix2[2] + oldpart * pix1[2]; } pix3 = PXMpix8(ss_pxmmix,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww*3); } } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww*3); return; } // new image rolls over prior image from left to right void ss_rollright() // new v.11.01 { int px, py; uint8 *pix1, *pix3; double delay = 0.5 / ss_ww; // v.11.04 PXM_free(ss_pxmmix); ss_pxmmix = PXM_copy(ss_pxmold); for (px = 0; px < ss_ww; px++) { pix1 = PXMpix8(ss_pxmnew,px,0); pix3 = PXMpix8(ss_pxmmix,px,0); for (py = 0; py < ss_hh; py++) { memmove(pix3,pix1,3); pix1 += ss_ww * 3; pix3 += ss_ww * 3; } pix3 = PXMpix8(ss_pxmmix,px,0); gdk_draw_rgb_image(drWin->window, gdkgc, px, 0, 1, ss_hh, NODITHER, pix3, ss_ww*3); zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww*3); return; } // new image rolls over prior image from top down void ss_rolldown() // new v.11.01 { int py; uint8 *pix3; double delay = 0.5 / ss_hh; for (py = 0; py < ss_hh; py++) { pix3 = PXMpix8(ss_pxmnew,0,py); gdk_draw_rgb_image(drWin->window, gdkgc, 0, py, ss_ww, 1, NODITHER, pix3, ss_ww*3); zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww*3); return; } // shift prior image to the left as next image shifts-in from the right // (this one flickers annoingly and cannot be fixed) void ss_shiftleft() // new v.11.01 { int px, Nsteps = 50; uint8 *pix1, *pix3; for (px = 0; px < ss_ww; px += ss_ww / Nsteps) { pix1 = PXMpix8(ss_pxmold,px,0); pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww - px, ss_hh, NODITHER, pix1, ss_ww * 3); gdk_draw_rgb_image(drWin->window, gdkgc, ss_ww - px, 0, px, ss_hh, NODITHER, pix3, ss_ww * 3); zsleep(0.01); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww * 3); return; } // new image opens up in horizontal rows like venetian blinds void ss_venetian() // new v.11.01 { int py1, py2; uint8 *pix3; int louver, Nlouvers = 20; int louversize = ss_hh / Nlouvers; double delay = 1.0 / louversize; for (py1 = 0; py1 < louversize; py1++) // y-row within each louver { for (louver = 0; louver < Nlouvers; louver++) // louver, first to last { py2 = py1 + louver * louversize; if (py2 >= ss_hh) break; pix3 = PXMpix8(ss_pxmnew,0,py2); gdk_draw_rgb_image(drWin->window, gdkgc, 0, py2, ss_ww, 1, NODITHER, pix3, ss_ww*3); } zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww * 3); return; } // a grate opens up to show new image void ss_grate() // new v.11.01 { int px1, px2, py1, py2; uint8 *pix3; int row, col, Nrow, Ncol; // rows and columns int boxww, boxhh; double delay; Ncol = 20; // 20 columns boxww = boxhh = ss_ww / Ncol; // square boxes Nrow = ss_hh / boxhh; // corresp. rows Ncol++; // round up Nrow++; delay = 1.0 / boxhh; for (py1 = 0; py1 < boxhh; py1++) { for (row = 0; row < Nrow; row++) { py2 = py1 + row * boxhh; if (py2 >= ss_hh) break; pix3 = PXMpix8(ss_pxmnew,0,py2); gdk_draw_rgb_image(drWin->window, gdkgc, 0, py2, ss_ww, 1, NODITHER, pix3, ss_ww*3); } px1 = py1; for (col = 0; col < Ncol; col++) { px2 = px1 + col * boxww; if (px2 >= ss_ww) break; pix3 = PXMpix8(ss_pxmnew,px2,0); gdk_draw_rgb_image(drWin->window, gdkgc, px2, 0, 1, ss_hh, NODITHER, pix3, ss_ww*3); } zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww * 3); return; } // A hole opens up from the center and expands outward void ss_rectangle() // new v.11.01 { int px1, py1, px2, py2, px3, py3; int ww1, hh1, ww2, hh2; uint8 *pix3; int step, Nsteps = 100; double delay = 1.0 / Nsteps; for (step = 1; step < Nsteps; step++) { ww1 = ss_ww * step / Nsteps; hh1 = ww1 * ss_hh / ss_ww; ww2 = ss_ww / Nsteps / 2; hh2 = ss_hh / Nsteps / 2; px1 = (ss_ww - ww1) / 2; py1 = (ss_hh - hh1) / 2; px2 = px1 + ww1 - ww2; py2 = py1; px3 = px1; py3 = py1 + hh1 - hh2; pix3 = PXMpix8(ss_pxmnew,px1,py1); gdk_draw_rgb_image(drWin->window, gdkgc, px1, py1, ww1+1, hh2+1, NODITHER, pix3, ss_ww*3); pix3 = PXMpix8(ss_pxmnew,px2,py2); gdk_draw_rgb_image(drWin->window, gdkgc, px2, py2, ww2+1, hh1+1, NODITHER, pix3, ss_ww*3); pix3 = PXMpix8(ss_pxmnew,px3,py3); gdk_draw_rgb_image(drWin->window, gdkgc, px3, py3, ww1+1, hh2+1, NODITHER, pix3, ss_ww*3); pix3 = PXMpix8(ss_pxmnew,px1,py1); gdk_draw_rgb_image(drWin->window, gdkgc, px1, py1, ww2+1, hh1+1, NODITHER, pix3, ss_ww*3); zmainloop(); zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww * 3); return; } // An ellipse opens up from the center and expands outward void ss_ellipse() // new v.11.03 { uint8 *pix3; int step, Nsteps = 100; int px1, py1, ww; double delay = 1.0 / Nsteps; double a, b, a2, b2, px, py, px2, py2; double ww2 = ss_ww / 2, hh2 = ss_hh / 2; for (step = 1; step < 1.3 * Nsteps; step++) { a = ww2 * step / Nsteps; // ellipse a and b constants b = a * ss_hh / ss_ww; // from tiny to >> image size a2 = a * a; b2 = b * b; for (py = -b; py <= +b; py += 3) // py from top of ellipse to bottom { while (py < -(hh2-2)) py += 3; if (py > hh2-2) break; py2 = py * py; px2 = a2 * (1.0 - py2 / b2); // corresponding px value, px = sqrt(px2); // (+/- from center of ellipse) if (px > ww2) px = ww2; ww = 2 * px; // length of line thru ellipse px1 = ww2 - px; // relocate origin py1 = py + hh2; pix3 = PXMpix8(ss_pxmnew,px1,py1); gdk_draw_rgb_image(drWin->window, gdkgc, px1, py1, ww, 3, NODITHER, pix3, ss_ww*3); } zmainloop(); zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww * 3); return; } // New image sweeps into view like a circular radar image void ss_radar() // new v.11.08 { int px = 0, py = 0, Npx, Npy, Np = 12; // smaller values make compiz jerky *** double R, Rmax, T, Tmax, dT, delay; double cosT, sinT; double ww2 = ss_ww / 2, hh2 = ss_hh / 2; uint8 *pix3; Rmax = sqrt(ww2 * ww2 + hh2 * hh2); Tmax = pi; dT = 0.6 * asin(Np / Rmax); delay = dT / Tmax; // 1 sec. + CPU time if (delay < 0.001) delay = 0.001; for (T = 0; T < Tmax; T += dT) { cosT = cos(T); sinT = sin(T); for (R = -Rmax; R < Rmax; R += Np) // v.11.09 { px = ww2 + R * cosT; py = hh2 - R * sinT; if (px < -Np) continue; if (py < -Np) continue; if (px > ss_ww-1) continue; if (py > ss_hh-1) continue; Npx = Npy = Np; // do the last piece too v.11.10 if (px < 0) px = 0; if (py < 0) py = 0; if (px + Npx > ss_ww-1) Npx = ss_ww-1 - px; if (py + Npy > ss_hh-1) Npy = ss_hh-1 - py; pix3 = PXMpix8(ss_pxmnew,px,py); gdk_draw_rgb_image(drWin->window, gdkgc, px, py, Npx, Npy, NODITHER, pix3, ss_ww*3); } zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww * 3); return; } // New image closes in from top and bottom with jagged teeth void ss_jaws() // new v.11.08 { int nteeth = 20, Np = 6; int tbase1, tbase2, twidth, tlength, tooth, tpos; int ii, px, py, ww, ww2; double delay = 2.0 * Np / ss_hh; // 1 sec. + CPU time uint8 *pix3; twidth = ss_ww / nteeth; tlength = twidth; for (ii = 0; ii < ss_hh/2 - tlength/2; ii += Np) { tbase1 = ii; // tooth base from top to middle tbase2 = ss_hh - tbase1 - 1; // tooth base from bottom to middle for (tooth = 0; tooth <= nteeth; tooth++) // tooth first to last + 1 { for (tpos = 0; tpos < tlength; tpos += Np) // tooth position from base to point { ww = twidth * (tlength - tpos) / tlength; // tooth width at scan line if (ww < 2) break; py = tbase1 + tpos; // top teeth scan line y px = twidth / 2 + tooth * twidth - ww / 2; // scan line x to x + ww if (px < ss_ww) { pix3 = PXMpix8(ss_pxmnew,px,py); ww2 = ww; if (px + ww2 > ss_ww) ww2 = ss_ww - px; gdk_draw_rgb_image(drWin->window, gdkgc, px, py, ww2, Np, NODITHER, pix3, ss_ww*3); } py = tbase2 - tpos; // bottom teeth scan line y px = tooth * twidth - ww / 2; // scan line x to x + ww if (tooth == 0) { px = 0; // leftmost tooth is half ww = ww / 2; } if (px < ss_ww) { pix3 = PXMpix8(ss_pxmnew,px,py); ww2 = ww; if (px + ww2 > ss_ww) ww2 = ss_ww - px; gdk_draw_rgb_image(drWin->window, gdkgc, px, py, ww2, Np, NODITHER, pix3, ss_ww*3); } } } zmainloop(); zsleep(delay); } pix3 = PXMpix8(ss_pxmnew,0,0); gdk_draw_rgb_image(drWin->window, gdkgc, 0, 0, ss_ww, ss_hh, NODITHER, pix3, ss_ww * 3); return; } /**************************************************************************/ // menu function, start synchronize files process manually void m_syncfiles(GtkWidget *, cchar *) // v.11.11 { int err, syncfd; if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // edit function busy syncfd = global_lock(fsync_lock); // check if sync files running if (syncfd >= 0) global_unlock(syncfd); else { zmessageACK(mWin,ZTX("Sync Files is already running")); // yes, do nothing menulock(0); return; } printf("spawn sync files subprocess \n"); err = system("fotoxx -syncfiles manual &"); // spawn file sync process if (err) zmessageACK(mWin,"error: %s \n",wstrerror(err)); menulock(0); return; } /**************************************************************************/ // Synchronize files when fotoxx is installed for the first time or // when new image files have been created or moved outside fotoxx. // This is a spawned process running parallel to the user GUI process. // The main window with menus and toolbar is not available. struct tag_index_rec { char *file; // image filespec char *tags; // image tags char *comms; // image comments char *capt; // image caption char imagedate[12], filedate[16]; // image date, file date char stars; // image rating, '0' to '5' char update; // flag, update is needed }; tag_index_rec *xrec_old, *xrec_new; int syncfiles_func(void *) // v.11.11 { int syncfiles_dialog_event(zdialog *zd, cchar *event); char * syncfiles_find(char *imagedirk, int &Finit); int syncfiles_index_compare(cchar *rec1, cchar *rec2); int filesync_thumbfile(char *imagefile); int contx, syncfd, dosync, yn, err; cchar *Fsyncreason, *ppc; char *pp, text[200]; char *filespec, *thumbfile, *subdirk; char imagefile[maxfcc], logrec[200]; zdialog *zd; int zstat, fcount, flag; int cc, fcc, dcc, Finit; FILE *fid; struct stat statb; cchar *sync_message = ZTX("Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs."); cchar *exifkeys[5] = { exif_date_key, iptc_tags_key, iptc_rating_key, exif_comment_key, iptc_caption_key }; zfuncs::F1_help_topic = "sync_files"; printf("enter sync files process %d %d \n",Fautosync,Fmansync); syncfd = global_lock(fsync_lock); // obtain sync files lock if (syncfd < 0) { zmessage_post(0,5,"Sync Files is already running"); gtk_main_quit(); return 0; } err = system("which exiftool > /dev/null"); if (err) { // exiftool is required zmessageACK(0,Bexiftoolmissing); gtk_main_quit(); return 0; } dosync = 0; Fsyncreason = "none"; if (topdirk) { // v.11.12.1 err = stat(topdirk,&statb); if (err || ! S_ISDIR(statb.st_mode)) topdirk = 0; } if (! topdirk) { // reasons for sync files Fsyncreason = ZTX("no top image directory is defined"); dosync = 2; } else { printf("top image directory: %s \n",topdirk); err = stat(topdirk,&statb); if (err) Fsyncreason = ZTX("top image directory is invalid"); if (err) dosync = 2; } err = stat(search_index_file,&statb); if (err) Fsyncreason = ZTX("no search index file is present"); if (err) dosync = 2; if (! dosync) // check for new image files v.11.11 { // since last session or sync sprintf(command,"find -L \"%s\" -type d -newermt \"%s\" ", topdirk,last_session); // use directory mod time v.11.11.1 printf("%s \n",command); contx = 0; while ((pp = command_output(contx,command,null))) { newfiles++; // add to possible prior session count zfree(pp); } if (newfiles) { strncpy0(text,ZTX("new/modified files are present"),199); // v.11.11.1 Fsyncreason = text; dosync = 1; } } if (dosync) printf("%s \n",Fsyncreason); else printf("%s \n",ZTX("no new files found")); if (! dosync && Fautosync) { // no need to sync and not manual req. gtk_main_quit(); return 0; } if (dosync < 2 && ! Fmansync) // dialog not required, not manual req. goto start_sync; // do auto sync // user dialog to request sync files and supply top image directory sync_dialog: zd = zdialog_new(ZTX("Synchronize Files"),mWin,Bproceed,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); zdialog_add_widget(zd,"label","lab1","hb1",ZTX("Top Image Directory:")); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=3"); zdialog_add_widget(zd,"entry","topdirk","hb2","??","scc=40|space=5"); zdialog_add_widget(zd,"button","browse","hb2",Bbrowse,"space=5"); if (strNeq(Fsyncreason,"none")) { // show reason for file sync zdialog_add_widget(zd,"label","labwhy1","dialog",Fsyncreason,"space=3"); zdialog_add_widget(zd,"label","labwhy2","dialog",sync_message,"space=3"); } if (topdirk) zdialog_stuff(zd,"topdirk",topdirk); // v.11.12.1 zdialog_help(zd,"sync_files"); zdialog_run(zd,syncfiles_dialog_event); zstat = zdialog_wait(zd); if (zstat != 1) { // dialog canceled zdialog_free(zd); if (dosync < 2) { // file sync is optional gtk_main_quit(); return 0; } yn = zmessageYN(0,ZTX("file sync is necessary.\n" "cancel anyway?")); // v.12.01 if (! yn) goto sync_dialog; gtk_main_quit(); return 0; } pp = zmalloc(200); zdialog_fetch(zd,"topdirk",pp,200); // get top directory zdialog_free(zd); err = stat(pp,&statb); // check for validity if (err || ! S_ISDIR(statb.st_mode)) { zmessageACK(mWin,ZTX("top directory is invalid")); zfree(pp); goto sync_dialog; } if (topdirk) zfree(topdirk); topdirk = strdupz(pp,0,"topdirk"); zfree(pp); cc = strlen(topdirk); // remove trailing '/' if present if (topdirk[cc-1] == '/') topdirk[cc-1] = 0; // v.11.12 fid = fopen(topdirk_file,"w"); // write top directory file if (fid) { fprintf(fid,"%s\n",topdirk); fclose(fid); } start_sync: // look for orphan thumbnail files and delete them write_popup_text("open","Synchronize Files",500,300); // popup window for log data write_popup_text("write","deleting orphan thumbnails"); snprintf(command,ccc,"%s*.thumbnails/*.png",topdirk); // find all /topdirk/.thumbnails/*.png fcount = 0; flag = 1; while ((thumbfile = (char *) SearchWild(command,flag))) // next thumbnail file { pp = strrchr(thumbfile,'/'); if (strnNeq(pp-12,"/.thumbnails/",13)) continue; fcc = strlen(pp) - 4; if (strNeq(pp+fcc,".png")) continue; strncpy0(imagefile,thumbfile,maxfcc); // construct matching image file dcc = pp - 12 - thumbfile; if (dcc + fcc >= maxfcc) continue; memmove(imagefile+dcc,pp,fcc); imagefile[dcc+fcc] = 0; err = stat(imagefile,&statb); // look for image file if (! err) continue; // found, keep thumbnail *pp = '/'; remove(thumbfile); // not found, delete thumbnail fcount++; // count thumbnails deleted snprintf(logrec,199,"delete thumbnail: %s",thumbfile); write_popup_text("write",logrec); } snprintf(logrec,199,"deleted %d orphan thumbnails",fcount); write_popup_text("write",logrec); // look for image files without thumbnails and create the thumbnails snprintf(logrec,199,"creating missing and update stale thumbnails"); write_popup_text("write",logrec); snprintf(command,ccc,"find \"%s\" -type d",topdirk); // find directories under top directory contx = 0; fcount = 0; while ((subdirk = command_output(contx,command))) { pp = strrchr(subdirk,'/'); if (pp && strEqu(pp,"/.thumbnails")) { // /.../.thumbnails/ directory zfree(subdirk); continue; // skip } Finit = 1; filespec = syncfiles_find(subdirk,Finit); // get first image file while (filespec) // loop all image files { if (image_file_type(filespec) == 2) { if (filesync_thumbfile(filespec)) { snprintf(logrec,199,"create thumbnail: %s",filespec); write_popup_text("write",logrec); fcount++; // count thumbnails created v.11.11 } } zfree(filespec); filespec = syncfiles_find(subdirk,Finit); // next image file } zfree(subdirk); } snprintf(logrec,199,"created %d thumbnails",fcount); write_popup_text("write",logrec); // Rebuild search index file. // Process all image files within given top-level directory. // Works incrementally and is very fast after the first run. snprintf(logrec,199,"rebuild search index"); write_popup_text("write",logrec); char **ppv, tagsbuff[tagrecl]; char *imagedate, *imagetags, *imagestars, *imagecomms, *imagecapt; int Nold, Nnew, orec, nrec, comp; int pcache, Ncache, nrec2; char **ppcache; cchar *Fcache[50]; struct tm bdt; fcount = MAXIMAGES; // max. image files supported v.12.01 xrec_old = (tag_index_rec *) zmalloc(fcount * sizeof(tag_index_rec),"sync"); xrec_new = (tag_index_rec *) zmalloc(fcount * sizeof(tag_index_rec),"sync"); // read current search index file and build "old list" of tags orec = Nold = 0; fid = 0; fid = fopen(search_index_file,"r"); if (fid) { while (true) // read current search index records { pp = fgets_trim(tagsbuff,tagrecl,fid); // next record if (! pp) break; if (strnEqu(pp,"file: ",6)) // start new file entry { if (++Nold == fcount) zappcrash("too many image files"); orec = Nold - 1; xrec_old[orec].file = strdupz(pp+6,0,"xrec_old.file"); xrec_old[orec].imagedate[0] = 0; xrec_old[orec].filedate[0] = 0; xrec_old[orec].tags = 0; xrec_old[orec].stars = '0'; xrec_old[orec].comms = 0; xrec_old[orec].capt = 0; xrec_old[orec].update = '0'; } if (strnEqu(pp,"date: ",6)) { ppc = strField(pp,' ',2); if (ppc) strncpy0(xrec_old[orec].imagedate,ppc,12); ppc = strField(pp,' ',3); if (ppc) strncpy0(xrec_old[orec].filedate,ppc,16); } if (strnEqu(pp,"tags: ",6)) xrec_old[orec].tags = strdupz(pp+6,0,"sync"); if (strnEqu(pp,"stars: ",7)) xrec_old[orec].stars = *(pp+7); if (strnEqu(pp,"comms: ",7)) xrec_old[orec].comms = strdupz(pp+7,0,"sync"); if (strnEqu(pp,"capt: ",6)) xrec_old[orec].capt = strdupz(pp+6,0,"sync"); // v.10.12 } fclose(fid); } snprintf(logrec,199,"%d current index records found",Nold); write_popup_text("write",logrec); // find all image files and create "new list" with no tags snprintf(logrec,199,"find all image files and build index records"); write_popup_text("write",logrec); snprintf(command,ccc,"find \"%s\" -type d",topdirk); // find directories under top directory contx = 0; Nnew = nrec = 0; while ((subdirk = command_output(contx,command))) { pp = strrchr(subdirk,'/'); if (pp && strEqu(pp,"/.thumbnails")) // skip ./thumbnails directories { zfree(subdirk); continue; } Finit = 1; filespec = syncfiles_find(subdirk,Finit); // get first image file while (filespec) // loop all image files { if (image_file_type(filespec) == 2) // construct new tag record { err = stat(filespec,&statb); if (err) continue; if (++Nnew == fcount) zappcrash("too many image files"); nrec = Nnew - 1; xrec_new[nrec].file = strdupz(filespec,0,"sync"); // image filespec xrec_new[nrec].imagedate[0] = 0; // image date = empty gmtime_r(&statb.st_mtime,&bdt); // file date = yyyymmddhhmmss snprintf(xrec_new[nrec].filedate,16,"%04d%02d%02d%02d%02d%02d", bdt.tm_year + 1900, bdt.tm_mon + 1, bdt.tm_mday, bdt.tm_hour, bdt.tm_min, bdt.tm_sec); xrec_new[nrec].tags = 0; // tags = empty xrec_new[nrec].stars = '0'; // stars = '0' xrec_new[nrec].comms = 0; // comments = empty xrec_new[nrec].capt = 0; // caption = empty v.10.12 } zfree(filespec); filespec = syncfiles_find(subdirk,Finit); // next image file } zfree(subdirk); } snprintf(logrec,199,"found %d image files",Nnew); write_popup_text("write",logrec); // merge and compare lists // if filespecs match and have the same date, then old tags are OK snprintf(logrec,199,"merging old and new index records"); write_popup_text("write",logrec); HeapSort((char *) xrec_old,sizeof(tag_index_rec),Nold,syncfiles_index_compare); HeapSort((char *) xrec_new,sizeof(tag_index_rec),Nnew,syncfiles_index_compare); for (orec = nrec = 0; nrec < Nnew; ) { xrec_new[nrec].update = '1'; // assume update is needed if (orec == Nold) comp = +1; else comp = strcmp(xrec_old[orec].file, xrec_new[nrec].file); // compare filespecs if (comp > 0) nrec++; else if (comp < 0) orec++; else // matching filespecs { if (strEqu(xrec_new[nrec].filedate, xrec_old[orec].filedate)) // and matching file dates { // copy data from old to new strncpy0(xrec_new[nrec].imagedate,xrec_old[orec].imagedate,12); xrec_new[nrec].tags = xrec_old[orec].tags; xrec_old[orec].tags = 0; xrec_new[nrec].stars = xrec_old[orec].stars; xrec_new[nrec].comms = xrec_old[orec].comms; xrec_old[orec].comms = 0; xrec_new[nrec].capt = xrec_old[orec].capt; xrec_old[orec].capt = 0; xrec_new[nrec].update = '0'; // update is not needed } nrec++; orec++; } } for (orec = 0; orec < Nold; orec++) // release old list memory { zfree(xrec_old[orec].file); if (xrec_old[orec].tags) zfree(xrec_old[orec].tags); if (xrec_old[orec].capt) zfree(xrec_old[orec].capt); // memory leak v.11.09 if (xrec_old[orec].comms) zfree(xrec_old[orec].comms); } zfree(xrec_old); xrec_old = 0; // process entries needing update in new index list // get updated metadata from image file EXIF/IPTC data snprintf(logrec,199,"updating index records"); write_popup_text("write",logrec); Ncache = 0; // cache empty pcache = 0; ppcache = 0; for (fcount = nrec = 0; nrec < Nnew; nrec++) { if (xrec_new[nrec].update == '0') continue; // no update needed fcount++; // running count of updates if (! Ncache) // cache empty v.12.01 { for (nrec2 = nrec; Ncache < 50 && nrec2 < Nnew; nrec2++) { if (xrec_new[nrec2].update != '0') { // add next 50 files to cache Fcache[Ncache] = xrec_new[nrec2].file; Ncache++; } } ppcache = info_getN(Fcache,Ncache,exifkeys,5); // get metadata for cached files pcache = 0; // 1st cache position } ppv = ppcache + 5 * pcache; // get key values for next file Ncache--; // index to next cache data pcache++; imagedate = ppv[0]; imagetags = ppv[1]; imagestars = ppv[2]; imagecomms = ppv[3]; imagecapt = ppv[4]; if (imagedate && strlen(imagedate) > 3) { // image date v.11.10 if (strlen(imagedate) > 9) imagedate[10] = 0; // truncate to yyyy:mm:dd strcpy(xrec_new[nrec].imagedate,imagedate); } else strcpy(xrec_new[nrec].imagedate,"null"); if (imagetags && strlen(imagetags)) // image tags xrec_new[nrec].tags = strdupz(imagetags,0,"sync"); else xrec_new[nrec].tags = strdupz("null"tagdelim2,0,"sync"); // v.11.02 if (imagestars && strlen(imagestars)) // image rating xrec_new[nrec].stars = *imagestars; if (imagecomms && strlen(imagecomms)) // image comments xrec_new[nrec].comms = strdupz(imagecomms,0,"sync"); else xrec_new[nrec].comms = strdupz("null",0,"sync"); if (imagecapt && strlen(imagecapt)) // image caption v.10.12 xrec_new[nrec].capt = strdupz(imagecapt,0,"sync"); else xrec_new[nrec].capt = strdupz("null",0,"sync"); if (imagedate) zfree(imagedate); if (imagetags) zfree(imagetags); if (imagestars) zfree(imagestars); if (imagecomms) zfree(imagecomms); if (imagecapt) zfree(imagecapt); snprintf(logrec,199,"update index: %s",xrec_new[nrec].file); write_popup_text("write",logrec); } fid = fopen(search_index_file,"w"); // write new search index file if (! fid) zappcrash("cannot write tags file"); // with merged data for (nrec = 0; nrec < Nnew; nrec++) { fprintf(fid,"file: %s""\n",xrec_new[nrec].file); fprintf(fid,"date: %s %s""\n",xrec_new[nrec].imagedate, xrec_new[nrec].filedate); fprintf(fid,"tags: %s""\n",xrec_new[nrec].tags); fprintf(fid,"stars: %c""\n",xrec_new[nrec].stars); fprintf(fid,"comms: %s""\n",xrec_new[nrec].comms); fprintf(fid,"capt: %s""\n",xrec_new[nrec].capt); fprintf(fid,"\n"); } fclose(fid); for (nrec = 0; nrec < Nnew; nrec++) // release new list memory { zfree(xrec_new[nrec].file); if (xrec_new[nrec].tags) zfree(xrec_new[nrec].tags); if (xrec_new[nrec].capt) zfree(xrec_new[nrec].capt); // memory leak v.11.09 if (xrec_new[nrec].comms) zfree(xrec_new[nrec].comms); } zfree(xrec_new); xrec_new = 0; snprintf(logrec,199,"%d image files updated",fcount); write_popup_text("write",logrec); write_popup_text("write","COMPLETED"); printf("sync files subprocess completed \n"); global_unlock(syncfd); // release file sync lock while (zfuncs::open_popup_windows) { // wait for popup window to be closed zmainloop(); zsleep(0.1); } gtk_main_quit(); // gone forever return 0; } // dialog event function - file chooser for top image directory int syncfiles_dialog_event(zdialog *zd, cchar *event) { char *pp; if (! strEqu(event,"browse")) return 0; pp = zgetfile1(ZTX("Select top image directory"),"folder",topdirk); // get topmost directory if (! pp) return 0; zdialog_stuff(zd,"topdirk",pp); zfree(pp); return 0; } // find image files in a directory, return one per call // v.11.11 char * syncfiles_find(char *imagedirk, int &Finit) { char *file; cchar *findcommand = "find \"%s\" -maxdepth 1 -type f"; static int contx, ftyp; if (Finit) { Finit = 0; contx = 0; } while ((file = command_output(contx,findcommand,imagedirk))) // find next file in directory { if (! file) return 0; // EOL ftyp = image_file_type(file); if (ftyp == 2) return file; // supported image file type zfree(file); continue; } return 0; } // Find the thumbnail file for the given image file. // If missing or stale, add or update in /.thumbnails directory. // Returns 0 if thumbnail file was OK, 1 if it was created. int filesync_thumbfile(char *imagefile) // v.11.11 { GdkPixbuf *thumbpxb; GError *gerror = 0; char *pfile, *bfile, *thumbfile; int err, sizew, sizeh; struct stat statf, statb; err = stat(imagefile,&statf); // stat the image file if (err) return 0; pfile = strrchr(imagefile,'/'); // get .../filename.xxx if (! pfile) return 0; thumbfile = strdupz(imagefile,20,"image_thumbfile"); // construct thumbnail file bfile = thumbfile + (pfile - imagefile); // .../.thumbnails/filename.xxx.png strcpy(bfile,"/.thumbnails"); bfile += 12; strcpy(bfile,pfile); strcat(bfile,".png"); err = stat(thumbfile,&statb); // stat the thumbnail file if (! err && statb.st_mtime >= statf.st_mtime) return 0; // found and up to date *bfile = 0; err = stat(thumbfile,&statb); if (err) err = mkdir(thumbfile,0751); // create .thumbnails directory if (err) return 0; *bfile = *pfile; sizew = sizeh = image_navi::thumbfilesize; // create thumbnail pixbuf thumbpxb = gdk_pixbuf_new_from_file_at_size(imagefile,sizew,sizeh,&gerror); if (! thumbpxb) { printf("gdk_pixbuf_new error: %s \n",gerror->message); // diagnose error v.3.3 return 0; } gdk_pixbuf_save(thumbpxb,thumbfile,"png",&gerror,null); // save in /.thumbnails/ directory g_object_unref(thumbpxb); return 1; } // sort compare function - compare tag record filespecs and return // <0 | 0 | >0 for file1 < | == | > file2 int syncfiles_index_compare(cchar *rec1, cchar *rec2) { char * file1 = ((tag_index_rec *) rec1)->file; char * file2 = ((tag_index_rec *) rec2)->file; return strcmp(file1,file2); } /**************************************************************************/ // Show RGB values for 1-5 pixels selected with mouse-clicks. void show_RGB_mousefunc(); int show_RGB_timefunc(void *); zdialog *RGBSzd; int RGBSpixel[5][2]; // last 0-5 pixels clicked int RGBSnpix; // count of pixels double RGBStime; // last click time int RGBSmetric = 1; // 1/2/3 = /RGB/EV/OD int RGBSdelta = 0; // abs/delta mode int RGBSlabels = 0; // pixel labels on/off void m_show_RGB(GtkWidget *, cchar *menu) // rewritten v.11.07 { int show_RGB_event(zdialog *zd, cchar *event); PangoFontDescription *pfontdesc; GtkWidget *widget; cchar *mess = ZTX("Click image to select pixels."); cchar *header = " Pixel Red Green Blue"; zfuncs::F1_help_topic = "show_RGB"; if (! Fpxm8) return; // no image file RGBSnpix = 0; // no pixels yet pfontdesc = pango_font_description_from_string("Monospace 9"); // monospace font /*** Click image to select pixels. [x] delta [x] labels Metric: (o) RGB (o) EV (o) OD Pixel Red Green Blue A xxxx xxxx xxxxx xxxxx xxxxx B xxxx xxxx xxxxx xxxxx xxxxx C xxxx xxxx xxxxx xxxxx xxxxx D xxxx xxxx xxxxx xxxxx xxxxx E xxxx xxxx xxxxx xxxxx xxxxx [done] ***/ if (RGBSzd) zdialog_free(RGBSzd); // delete previous if any zdialog *zd = zdialog_new(ZTX("Show RGB"),mWin,Bdone,null); RGBSzd = zd; zdialog_add_widget(zd,"hbox","hbmess","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labmess","hbmess",mess,"space=5"); zdialog_add_widget(zd,"hbox","hbmym","dialog"); zdialog_add_widget(zd,"check","delta","hbmym","delta","space=8"); zdialog_add_widget(zd,"check","labels","hbmym","labels","space=8"); if (RGBSdelta) zdialog_stuff(zd,"delta",1); // abs/delta mode v.11.08 zdialog_add_widget(zd,"hbox","hbmetr","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labmetr","hbmetr","Metric:","space=5"); zdialog_add_widget(zd,"radio","radRGB","hbmetr","RGB","space=3"); zdialog_add_widget(zd,"radio","radEV","hbmetr","EV","space=3"); zdialog_add_widget(zd,"radio","radOD","hbmetr","OD","space=3"); if (RGBSmetric == 1) zdialog_stuff(zd,"radRGB",1); // get which metric to use if (RGBSmetric == 2) zdialog_stuff(zd,"radEV",1); if (RGBSmetric == 3) zdialog_stuff(zd,"radOD",1); zdialog_add_widget(zd,"vbox","vbdat","dialog"); // vbox for current pixel values zdialog_add_widget(zd,"hbox","hbpix","vbdat"); zdialog_add_widget(zd,"label","labheader","hbpix",header); // Pixel Red Green Blue zdialog_add_widget(zd,"hbox","hb1","vbdat"); zdialog_add_widget(zd,"label","pix1","hb1"); // A xxxx yyyy rrr.r ggg.g bbb.b zdialog_add_widget(zd,"hbox","hb2","vbdat"); zdialog_add_widget(zd,"label","pix2","hb2"); zdialog_add_widget(zd,"hbox","hb3","vbdat"); zdialog_add_widget(zd,"label","pix3","hb3"); zdialog_add_widget(zd,"hbox","hb4","vbdat"); zdialog_add_widget(zd,"label","pix4","hb4"); zdialog_add_widget(zd,"hbox","hb5","vbdat"); zdialog_add_widget(zd,"label","pix5","hb5"); widget = zdialog_widget(zd,"labheader"); gtk_widget_modify_font(widget,pfontdesc); // use monospace font widget = zdialog_widget(zd,"pix1"); gtk_widget_modify_font(widget,pfontdesc); widget = zdialog_widget(zd,"pix2"); gtk_widget_modify_font(widget,pfontdesc); widget = zdialog_widget(zd,"pix3"); gtk_widget_modify_font(widget,pfontdesc); widget = zdialog_widget(zd,"pix4"); gtk_widget_modify_font(widget,pfontdesc); widget = zdialog_widget(zd,"pix5"); gtk_widget_modify_font(widget,pfontdesc); zdialog_help(zd,"show_RGB"); // zdialog help topic v.11.08 zdialog_run(zd,show_RGB_event,"save"); // run dialog takeMouse(zd,show_RGB_mousefunc,dragcursor); // connect mouse function g_timeout_add(300,show_RGB_timefunc,0); // start timer function, 300 ms return; } // dialog event function int show_RGB_event(zdialog *zd, cchar *event) { int button, ii, px, py; static char label[5][4] = { " A ", " B ", " C ", " D ", " E " }; if (zd->zstat) { freeMouse(); // disconnect mouse function zdialog_free(RGBSzd); // kill dialog RGBSzd = 0; erase_toptext(102); mwpaint2(); } if (strEqu(event,"focus")) // toggle mouse capture takeMouse(zd,show_RGB_mousefunc,dragcursor); // connect mouse function if (strEqu(event,"delta")) { // set absolute/delta mode zdialog_fetch(zd,"delta",RGBSdelta); if (RGBSdelta && ! E3pxm16) { RGBSdelta = 0; // block delta mode if no edit underway zdialog_stuff(zd,"delta",0); // v.11.09 } } if (strEqu(event,"labels")) { // get labels on/off v.11.09 zdialog_fetch(zd,"labels",RGBSlabels); erase_toptext(102); if (RGBSlabels) { // labels off to labels on for (ii = 0; ii < RGBSnpix; ii++) // show pixel labels on image { // v.11.08 px = RGBSpixel[ii][0]; py = RGBSpixel[ii][1]; add_toptext(102,px,py,label[ii],"Sans 8"); } } mwpaint2(); } if (strEqu(event,"radRGB")) { // metric = RGB zdialog_fetch(zd,event,button); if (button) RGBSmetric = 1; } if (strEqu(event,"radEV")) { // metric = EV zdialog_fetch(zd,event,button); if (button) RGBSmetric = 2; } if (strEqu(event,"radOD")) { // metric = OD zdialog_fetch(zd,event,button); if (button) RGBSmetric = 3; } return 0; } // mouse function void show_RGB_mousefunc() // mouse function { int ii, px, py; static char label[5][4] = { " A ", " B ", " C ", " D ", " E " }; if (! LMclick) return; LMclick = 0; RGBStime = get_seconds(); // mark time of pixel click if (RGBSnpix == 5) { // if all 5 positions filled, for (ii = 1; ii < 5; ii++) { // remove first (oldest) and RGBSpixel[ii-1][0] = RGBSpixel[ii][0]; // push the rest back RGBSpixel[ii-1][1] = RGBSpixel[ii][1]; } RGBSnpix = 4; // position for newest } ii = RGBSnpix; // next position to fill RGBSpixel[ii][0] = Mxclick; // save newest pixel RGBSpixel[ii][1] = Myclick; RGBSnpix++; erase_toptext(102); if (RGBSlabels) { // v.11.09 for (ii = 0; ii < RGBSnpix; ii++) // show pixel labels on image { // v.11.08 px = RGBSpixel[ii][0]; py = RGBSpixel[ii][1]; add_toptext(102,px,py,label[ii],"Sans 8"); } } mwpaint2(); return; } // timer function - continuously display RGB values for selected pixels int show_RGB_timefunc(void *arg) // up to 5 pixels, live update { int ii, px, py, delta; double red1, green1, blue1; double red3, green3, blue3; char text[100], pixx[8] = "pixx"; uint8 *ppix8; uint16 *ppix16a, *ppix16b; double c1 = 100.0 / 256.0; #define ODfunc(rgb) (2.0 - log10(c1 * rgb)) // RGB units (1-256) to OD units #define EVfunc(rgb) (log2(rgb) - 7) // RGB units to EV (128 == 0 EV) if (! RGBSzd) return 1; // user quit, stop timer if (! RGBSnpix) return 1; // no pixels clicked yet if (RGBSdelta && E3pxm16) delta = 1; // delta mode only if edit underway else delta = 0; // v.11.08 red1 = green1 = blue1 = 0; if (curr_image_time > RGBStime) { // image time later than click time RGBSnpix = 0; // data is no longer valid erase_toptext(102); mwpaint2(); } for (ii = 0; ii < 5; ii++) // loop positons 0 to 4 { pixx[3] = '1' + ii; // widget names "pix1" ... "pix5" px = RGBSpixel[ii][0]; // next pixel to report py = RGBSpixel[ii][1]; if (ii >= RGBSnpix) { // no pixel there yet zdialog_stuff(RGBSzd,pixx,""); // blank report line continue; } if (E3pxm16) { // use current image being edited if (px < 0 || px > E3ww-1 || // outside image area py < 0 || py > E3hh-1) return 1; ppix16a = PXMpix(E3pxm16,px,py); red3 = ppix16a[0] / 256.0; // "after" image E3 green3 = ppix16a[1] / 256.0; blue3 = ppix16a[2] / 256.0; if (delta) { // delta RGB for ongoing edited image ppix16b = PXMpix(E1pxm16,px,py); // "before" image E1 red1 = ppix16b[0] / 256.0; // v.11.08 green1 = ppix16b[1] / 256.0; blue1 = ppix16b[2] / 256.0; } } else if (Fpxm16) { // use finished edited image if (px < 0 || px > Fww-1 || py < 0 || py > Fhh-1) return 1; ppix16a = PXMpix(Fpxm16,px,py); red3 = ppix16a[0] / 256.0; green3 = ppix16a[1] / 256.0; blue3 = ppix16a[2] / 256.0; } else { // use 8 bpc image if (px < 0 || px > Fww-1 || py < 0 || py > Fhh-1) return 1; ppix8 = (uint8 *) Fpxm8->bmp + (py * Fww + px) * 3; red3 = ppix8[0]; green3 = ppix8[1]; blue3 = ppix8[2]; } sprintf(text," %c %4d %4d ",'A'+ii,px,py); // format pixel " A xxxx yyyy" if (RGBSmetric == 1) { // output RGB values if (delta) { red3 -= red1; // delta RGB green3 -= green1; blue3 -= blue1; } sprintf(text+12," %6.2f %6.2f %6.2f ",red3,green3,blue3); // xxx.xx } if (RGBSmetric == 2) { // output EV values v.11.08 red3 = EVfunc(red3); green3 = EVfunc(green3); blue3 = EVfunc(blue3); if (delta) { red3 -= EVfunc(red1); // delta EV green3 -= EVfunc(green1); blue3 -= EVfunc(blue1); } sprintf(text+12," %6.3f %6.3f %6.3f ",red3,green3,blue3); // x.xxx } if (RGBSmetric == 3) { // output OD values v.11.08 red3 = ODfunc(red3); green3 = ODfunc(green3); blue3 = ODfunc(blue3); if (delta) { red3 -= ODfunc(red1); // delta OD green3 -= ODfunc(green1); blue3 -= ODfunc(blue1); } sprintf(text+12," %6.3f %6.3f %6.3f ",red3,green3,blue3); // x.xxx } zdialog_stuff(RGBSzd,pixx,text); // pixel and RGB values >> label } return 1; } /**************************************************************************/ // setup x and y grid lines - count/spacing, enable/disable, offsets void m_gridlines(GtkWidget *, cchar *) { int gridlines_dialog_event(zdialog *zd, cchar *event); zdialog *zd; zfuncs::F1_help_topic = "grid_lines"; // v.10.8 zd = zdialog_new(ZTX("Grid Lines"),mWin,Bdone,Bcancel,null); zdialog_add_widget(zd,"hbox","hb0","dialog",0,"space=10"); zdialog_add_widget(zd,"vbox","vb1","hb0",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb2","hb0",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vbspace","hb0",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb3","hb0",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb4","hb0",0,"homog|space=5"); zdialog_add_widget(zd,"label","lab1x","vb1",ZTX("x-spacing")); zdialog_add_widget(zd,"label","lab2x","vb1",ZTX("x-count")); zdialog_add_widget(zd,"label","lab4x","vb1",ZTX("x-enable")); zdialog_add_widget(zd,"spin","spacex","vb2","10|200|1|50"); zdialog_add_widget(zd,"spin","countx","vb2","0|100|1|0"); zdialog_add_widget(zd,"check","enablex","vb2",0); zdialog_add_widget(zd,"label","lab1y","vb3",ZTX("y-spacing")); zdialog_add_widget(zd,"label","lab2y","vb3",ZTX("y-count")); zdialog_add_widget(zd,"label","lab4y","vb3",ZTX("y-enable")); zdialog_add_widget(zd,"spin","spacey","vb4","10|200|1|50"); zdialog_add_widget(zd,"spin","county","vb4","0|100|1|0"); zdialog_add_widget(zd,"check","enabley","vb4",0); zdialog_add_widget(zd,"hbox","hboffx","dialog"); zdialog_add_widget(zd,"label","lab3x","hboffx",ZTX("x-offset"),"space=7"); zdialog_add_widget(zd,"hscale","offsetx","hboffx","-100|100|1|0","expand"); zdialog_add_widget(zd,"hbox","hboffy","dialog"); zdialog_add_widget(zd,"label","lab3y","hboffy",ZTX("y-offset"),"space=7"); zdialog_add_widget(zd,"hscale","offsety","hboffy","-100|100|1|0","expand"); zdialog_stuff(zd,"spacex",gridspace[0]); zdialog_stuff(zd,"spacey",gridspace[1]); zdialog_stuff(zd,"countx",gridcount[0]); zdialog_stuff(zd,"county",gridcount[1]); zdialog_stuff(zd,"offsetx",gridoffset[0]); zdialog_stuff(zd,"offsety",gridoffset[1]); zdialog_stuff(zd,"enablex",gridon[0]); zdialog_stuff(zd,"enabley",gridon[1]); if (gridon[0] || gridon[1]) Fgrid = 1; mwpaint2(); zdialog_help(zd,"grid_lines"); // zdialog help topic v.11.08 zdialog_run(zd,gridlines_dialog_event); zdialog_wait(zd); return; } // dialog event function int gridlines_dialog_event(zdialog *zd, cchar *event) { int zstat; if (zd->zstat) { zstat = zd->zstat; if (zstat != 1) Fgrid = gridon[0] = gridon[1] = 0; // cancel, grid lines off v.11.11 zdialog_free(zd); mwpaint2(); return 0; } if (strEqu(event,"enablex")) // x/y grid enable or disable zdialog_fetch(zd,"enablex",gridon[0]); if (strEqu(event,"enabley")) zdialog_fetch(zd,"enabley",gridon[1]); if (strEqu(event,"spacex")) // x/y grid spacing (if counts == 0) zdialog_fetch(zd,"spacex",gridspace[0]); if (strEqu(event,"spacey")) zdialog_fetch(zd,"spacey",gridspace[1]); if (strEqu(event,"countx")) // x/y grid line counts zdialog_fetch(zd,"countx",gridcount[0]); if (strEqu(event,"county")) zdialog_fetch(zd,"county",gridcount[1]); if (strEqu(event,"offsetx")) // x/y grid starting offsets zdialog_fetch(zd,"offsetx",gridoffset[0]); if (strEqu(event,"offsety")) zdialog_fetch(zd,"offsety",gridoffset[1]); if (gridon[0] || gridon[1]) Fgrid = 1; // if either grid enabled, show grid else Fgrid = 0; mwpaint2(); return 0; } // load or save grid settings from or to external int array void load_grid(int *griddata) // v.11.11 { Fgrid = griddata[0]; gridon[0] = griddata[1]; gridon[1] = griddata[2]; gridspace[0] = griddata[3]; gridspace[1] = griddata[4]; gridcount[0] = griddata[5]; gridcount[1] = griddata[6]; if (! gridcount[0] && ! gridspace[0]) gridcount[0] = 5; // if never set, use 5 lines if (! gridcount[1] && ! gridspace[1]) gridcount[1] = 5; mwpaint2(); return; } void save_grid(int *griddata) { griddata[0] = Fgrid; griddata[1] = gridon[0]; griddata[2] = gridon[1]; griddata[3] = gridspace[0]; griddata[4] = gridspace[1]; griddata[5] = gridcount[0]; griddata[6] = gridcount[1]; return; } // toggle grid lines on or off // action: 0 = off, 1 = on, 2 = toggle: on > off, off > on void toggle_grid(int action) // v.11.11 { if (action == 0) Fgrid = 0; // grid off if (action == 1) Fgrid = 1; // grid on if (action == 2) Fgrid = 1 - Fgrid; // toggle grid if (Fgrid && ! gridon[0] && ! gridon[1]) // if grid on and x/y both off, gridon[0] = gridon[1] = 1; // set both grids on mwpaint2(); return; } /**************************************************************************/ // burn images to CD/DVD void m_burn(GtkWidget *, cchar *) { int ii, cc, err; char **filelist, *imagefile, *bcommand; if (is_syncbusy()) return; // must wait for file sync v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // lock menus zfuncs::F1_help_topic = "burn"; // v.10.8 filelist = image_gallery_getfiles(0,mWin); // get list of files to burn v.10.9 if (! filelist) { menulock(0); return; } cc = 0; for (ii = 0; filelist[ii]; ii++) // get memory for brasero command line cc += strlen(filelist[ii]) + 4; bcommand = zmalloc(cc+20,"brasero"); strcpy(bcommand,"brasero"); cc = strlen(bcommand); for (ii = 0; filelist[ii]; ii++) // copy files to command line { imagefile = filelist[ii]; strcpy(bcommand+cc," \""); cc += 2; strcpy(bcommand+cc,imagefile); cc += strlen(imagefile); strcpy(bcommand+cc,"\""); cc += 1; zfree(imagefile); } zfree(filelist); strcat(bcommand," &"); // brasero command in background err = system(bcommand); if (err) zmessageACK(mWin,"error: %s",wstrerror(err)); zfree(bcommand); menulock(0); return; } /**************************************************************************/ // menu function // resize selected images and send to preferred e-mail program void m_email(GtkWidget *, cchar *) // new v.10.10 { int email_dialog_event(zdialog *zd, cchar *event); zdialog *zd; // email dialog zfuncs::F1_help_topic = "e-mail"; if (is_syncbusy()) return; // must wait for file sync v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // lock menus // [select files] N files selected // max. width [____] // max. height [____] // // [proceed] [cancel] zd = zdialog_new(ZTX("E-mail Images"),mWin,Bproceed,Bcancel,null); zdialog_add_widget(zd,"hbox","hbf","dialog",0,"space=5"); zdialog_add_widget(zd,"button","files","hbf",Bselectfiles,"space=5"); zdialog_add_widget(zd,"label","fcount","hbf",ZTX("0 files selected"),"space=10"); zdialog_add_widget(zd,"hbox","hbwh","dialog","space=10"); zdialog_add_widget(zd,"vbox","vbwh1","hbwh",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vbwh2","hbwh",0,"homog|space=5"); zdialog_add_widget(zd,"label","labw","vbwh1",ZTX("max. width")); zdialog_add_widget(zd,"label","labh","vbwh1",ZTX("max. height")); zdialog_add_widget(zd,"entry","maxw","vbwh2","1000","scc=5"); zdialog_add_widget(zd,"entry","maxh","vbwh2","700","scc=5"); zdialog_stuff(zd,"maxw",emailsize[0]); zdialog_stuff(zd,"maxh",emailsize[1]); zdialog_help(zd,"e-mail"); // zdialog help topic v.11.08 zdialog_run(zd,email_dialog_event); // run dialog zdialog_wait(zd); // wait for completion menulock(0); return; } // dialog event and completion callback function int email_dialog_event(zdialog *zd, cchar *event) { static char **flist = 0; char countmess[50], tempdir[100], sequence[8]; int maxw, maxh, err, fcc, ww, hh; int ii, jj, kk; char *pfile, *pext, *oldfile, *newfile; double scale, wscale, hscale; PXM *pxmin, *pxmout; if (strEqu(event,"files")) // select images to resize { if (flist) { // free prior list for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); } flist = image_gallery_getfiles(0,mWin); // get list of files to resize v.10.9 if (flist) // count files selected for (ii = 0; flist[ii]; ii++); else ii = 0; snprintf(countmess,50,ZTX("%d files selected"),ii); // update dialog zdialog_stuff(zd,"fcount",countmess); } if (! zd->zstat) return 0; // dialog still busy if (zd->zstat != 1) goto cleanup; // dialog canceled if (! flist) { // no files selected zd->zstat = 0; // keep dialog active return 0; } zdialog_fetch(zd,"maxw",maxw); // new max width zdialog_fetch(zd,"maxh",maxh); // new max height if (maxw < 20 || maxh < 20) { zmessageACK(mWin,ZTX("max. size %d x %d is not reasonable"),maxw,maxh); zd->zstat = 0; return 0; } *tempdir = 0; // temp dirk: /tmp//fotoxx/email strncatv(tempdir,99,"/tmp/",getenv("USER"),"/fotoxx/email",null); // v.11.09 sprintf(command,"mkdir -p %s",tempdir); // (re)create directory err = system(command); if (err) { zmessageACK(mWin,"%s",strerror(err)); goto cleanup; } sprintf(command,"rm -f %s/*.jpg",tempdir); // purge prior file list err = system(command); write_popup_text("open","preparing files",500,200,mWin); // status monitor popup window strcpy(command,"xdg-email"); // e-mail command: xdg-email for (ii = 0; flist[ii]; ii++) // loop selected files { oldfile = flist[ii]; pfile = strrchr(oldfile,'/'); // /filename.ext if (! pfile) continue; fcc = strlen(pfile); newfile = strdupz(tempdir,fcc+10,"email"); // add extra space for .nn and .ext strcat(newfile,pfile); // /tmp//fotoxx/filename.ext pfile = strrchr(newfile,'/'); for (jj = kk = 1; pfile[jj]; jj++, kk++) // remove special characters { // (xdg-email substitutes %nn pfile[kk] = pfile[jj]; // and thunderbird falls over) if (pfile[jj] < 0) continue; // UTF-8 multibyte characters OK if (pfile[jj] == '.') continue; // periods OK if (pfile[jj] >= 'a' && pfile[jj] <= 'z') continue; // keep a-z, A-Z, 0-9 if (pfile[jj] >= 'A' && pfile[jj] <= 'Z') continue; if (pfile[jj] >= '0' && pfile[jj] <= '9') continue; kk--; // omit others } pfile[kk] = 0; pext = strrchr(pfile,'.'); // find .ext if there is one if (! pext) pext = pfile + strlen(pfile); if (strlen(pext) > 5) pext = pext + strlen(pext); sprintf(sequence,"-%d",ii+1); // replace with sequence number strcpy(pext,sequence); // filename-nn pext = pext + strlen(pext); // add .jpg extension strcpy(pext,".jpg"); // filename-nn.jpg write_popup_text("write",newfile); // log progress zmainloop(); pxmin = f_load(oldfile,8); // load image as PXM-8 pixmap if (! pxmin) { printf("f_load error: %s \n",oldfile); continue; } ww = pxmin->ww; hh = pxmin->hh; wscale = hscale = 1.0; if (ww > maxw) wscale = 1.0 * maxw / ww; // compute new size if (hh > maxh) hscale = 1.0 * maxh / hh; if (wscale < hscale) scale = wscale; else scale = hscale; ww = ww * scale; hh = hh * scale; pxmout = PXM_rescale(pxmin,ww,hh); // rescale file PXBwrite(pxmout,newfile); // write to new file PXM_free(pxmin); PXM_free(pxmout); err = strncatv(command,1990," --attach ","\"",newfile,"\"",null); // --attach /tmp//fotoxx/file.jpg zfree(newfile); if (err) { zmessageACK(mWin,ZTX("too many files")); goto cleanup; } } write_popup_text("write","COMPLETED"); write_popup_text("close",0); emailsize[0] = maxw; // save preferred size emailsize[1] = maxh; strcat(command," &"); // wait for email completion printf("system: %s \n",command); err = system(command); cleanup: if (flist) { // free memory for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); flist = 0; } zdialog_free(zd); // kill dialog return 0; } /**************************************************************************/ // monitor test function void m_moncheck(GtkWidget *, cchar *) { uint8 *pixel; int red, green, blue; int row, col, row1, row2; int ww = 800, hh = 500; zdialog *zd; cchar *message = ZTX("Brightness should show a gradual ramp \n" "extending all the way to the edges."); zfuncs::F1_help_topic = "check_monitor"; if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; mutex_lock(&Fpixmap_lock); PXM_free(Fpxm8); Fpxm8 = PXM_make(ww,hh,8); Fww = ww; Fhh = hh; curr_file_bpc = 8; curr_file_size = 0; for (red = 0; red <= 1; red++) // 8 RGB combinations for (green = 0; green <= 1; green++) for (blue = 0; blue <= 1; blue++) { row1 = 4 * red + 2 * green + blue; // row 0 to 7 row1 = row1 * hh / 8; // stripe, 1/8 of image row2 = row1 + hh / 8; for (row = row1; row < row2; row++) for (col = 0; col < ww; col++) { pixel = PXMpix8(Fpxm8,col,row); pixel[0] = red * 256 * col / ww; pixel[1] = green * 256 * col / ww; pixel[2] = blue * 256 * col / ww; } } Fzoom = 0; // scale to window gtk_window_set_title(MWIN,"monitor check"); mutex_unlock(&Fpixmap_lock); mwpaint2(); // repaint window curr_image_time = get_seconds(); // mark time of image change v.11.07 zd = zdialog_new(ZTX("Monitor Check"),mWin,Bdone,null); // start user dialog v.11.04 zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab1","hb1",message,"space=5"); zdialog_resize(zd,200,0); zdialog_help(zd,"check_monitor"); // zdialog help topic v.11.08 zdialog_run(zd); zdialog_wait(zd); // wait for dialog complete zdialog_free(zd); f_open(curr_file,0); // back to current file v.11.04 menulock(0); return; } /**************************************************************************/ // adjust monitor gamma void m_mongamma(GtkWidget *, cchar *) // revised v.11.04 { int mongamma_event(zdialog *zd, cchar *event); char gammachart[200]; zdialog *zd; cchar *permit = "Chart image courtesy of Norman Koren"; cchar *website1 = "http://www.normankoren.com"; cchar *website2 = "http://www.imatest.org"; PXM *pxmtemp; zfuncs::F1_help_topic = "monitor_gamma"; if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; snprintf(gammachart,200,"%s/images/gammachart.png",get_zdocdir()); // gamma chart .png file pxmtemp = PXBread(gammachart); if (! pxmtemp) { zmessageACK(mWin,"gamma chart is missing"); menulock(0); return; } mutex_lock(&Fpixmap_lock); // curr. image = gamma chart PXM_free(Fpxm8); Fpxm8 = pxmtemp; Fww = Fpxm8->ww; Fhh = Fpxm8->hh; curr_file_bpc = 8; curr_file_size = 0; Fzoom = 1; // scale 100% (required) gtk_window_set_title(MWIN,"adjust gamma chart"); mutex_unlock(&Fpixmap_lock); mwpaint2(); // repaint window curr_image_time = get_seconds(); // mark time of image change v.11.07 zd = zdialog_new(ZTX("Monitor Gamma"),mWin,Bdone,null); // start user dialog zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=8"); zdialog_add_widget(zd,"label","labgamma","hb1","gamma","space=5"); zdialog_add_widget(zd,"hscale","gamma","hb1","0.6|1.4|0.02|1.0","expand"); zdialog_add_widget(zd,"hbox","hb2","dialog"); zdialog_add_widget(zd,"label","permit","hb2",permit,"space=5"); zdialog_add_widget(zd,"hbox","hb3","dialog"); zdialog_add_widget(zd,"link","web1","hb3",website1); zdialog_add_widget(zd,"hbox","hb4","dialog"); zdialog_add_widget(zd,"link","web2","hb4",website2); zdialog_resize(zd,200,0); zdialog_help(zd,"monitor_gamma"); // zdialog help topic v.11.08 zdialog_run(zd,mongamma_event); zdialog_wait(zd); // wait for dialog complete zdialog_free(zd); f_open(curr_file,0); // back to current file v.11.04 menulock(0); return; } // dialog event function int mongamma_event(zdialog *zd, cchar *event) { int err; double gamma; if (strEqu(event,"gamma")) { zdialog_fetch(zd,"gamma",gamma); sprintf(command,"xgamma -quiet -gamma %.2f",gamma); err = system(command); if (err) zmessageACK(mWin,"error: %s",wstrerror(err)); } return 0; } /**************************************************************************/ // create or update brightness histogram graph GtkWidget *winhisto = 0; // brightness histogram window GtkWidget *winhistoH = 0; // histogram drawing area GtkWidget *winhistoB = 0; // brightness band underneath void m_histogram(GtkWidget *, cchar *menu) // menu function { if (menu) zfuncs::F1_help_topic = "brightness_dist"; if (! Dpxm8) return; if (winhisto) { // window already present histogram_paint(); return; } winhisto = gtk_window_new(GTK_WINDOW_TOPLEVEL); // create histogram window gtk_window_set_title(GTK_WINDOW(winhisto),ZTX("Brightness Distribution")); gtk_window_set_transient_for(GTK_WINDOW(winhisto),MWIN); gtk_window_set_default_size(GTK_WINDOW(winhisto),300,200); GtkWidget * vbox = gtk_vbox_new(0,3); gtk_container_add(GTK_CONTAINER(winhisto),vbox); winhistoH = gtk_drawing_area_new(); // histogram drawing area gtk_box_pack_start(GTK_BOX(vbox),winhistoH,1,1,3); winhistoB = gtk_drawing_area_new(); // brightness scale under histogram gtk_box_pack_start(GTK_BOX(vbox),winhistoB,0,0,0); // (progresses from black to white) gtk_widget_set_size_request(winhistoB,300,12); // v.9.3 G_SIGNAL(winhisto,"destroy",histogram_destroy,0); G_SIGNAL(winhistoH,"expose-event",histogram_paint,0); G_SIGNAL(winhistoB,"expose-event",histogram_paint,0); gtk_widget_show_all(winhisto); return; } void histogram_paint() // paint graph window { GdkGC *gdkgc = 0; // GDK graphics context GdkColor color; GdkColormap *colormap = 0; int brdist[40], bin, nbins = 40; // increased v.9.3 int dist_maxbin = 0; int winww, winhh; int px, py, ww, hh, orgx, orgy; uint8 *pix8; uint16 *pix16; double bright; if (! winhisto) return; if (! Dpxm8) return; gdkgc = gdk_gc_new(winhistoH->window); // use separate graphics context colormap = gtk_widget_get_colormap(winhistoH); for (bin = 0; bin < nbins; bin++) // clear brightness distribution brdist[bin] = 0; mutex_lock(&Fpixmap_lock); if (Factivearea && E3pxm16) // compute brightness distribution { // for selected area being edited for (int ii = 0; ii < Fww * Fhh; ii++) { if (! sa_pixmap[ii]) continue; py = ii / Fww; px = ii - Fww * py; pix16 = PXMpix(E3pxm16,px,py); bright = 0.003906 * pixbright(pix16); // 0 to 255 brdist[int(bright / 256 * nbins)]++; // 0 to nbins } } else { for (py = 0; py < dhh; py++) // compute brightness distribution for (px = 0; px < dww; px++) // for image in visible window { pix8 = (uint8 *) Dpxm8->bmp + (py * dww + px) * 3; bright = pixbright(pix8); // 0 to 255 brdist[int(bright / 256 * nbins)]++; // 0 to nbins } } for (bin = 0; bin < nbins; bin++) // find max. bin if (brdist[bin] > dist_maxbin) dist_maxbin = brdist[bin]; mutex_unlock(&Fpixmap_lock); gdk_window_clear(winhistoH->window); winww = winhistoH->allocation.width; // drawing window size winhh = winhistoH->allocation.height; ww = winww / nbins; // bin width bin = -1; color.red = 10000; // a pleasing color color.green = 25000; color.blue = 40000; gdk_rgb_find_color(colormap,&color); gdk_gc_set_foreground(gdkgc,&color); for (px = 0; px < winww; px++) // draw each bin { if (px * nbins / winww > bin) { bin++; hh = 0.9 * winhh * brdist[bin] / dist_maxbin; orgx = px; orgy = winhh - hh; gdk_draw_rectangle(winhistoH->window,gdkgc,1,orgx,orgy,ww+1,hh); } } hh = winhistoB->allocation.height; for (px = 0; px < winww; px++) // draw brightness scale underneath { // v.9.3 color.red = color.green = color.blue = 65536 * px / winww; gdk_rgb_find_color(colormap,&color); gdk_gc_set_foreground(gdkgc,&color); gdk_draw_line(winhistoB->window,gdkgc,px,0,px,hh-1); } return; } void histogram_destroy() // delete window { if (winhisto) gtk_widget_destroy(winhisto); winhisto = 0; return; } /**************************************************************************/ // set GUI language void m_lang(GtkWidget *, cchar *) // overhauled v.10.1 { zdialog *zd; int ii, cc, err, val, zstat; char lang1[8], *pp; cchar *langs[12] = { "en English", "de German", "es Spanish", // english first "fr French", "gl Galacian", "it Italian", "nl Dutch", "pt Portuguese", "ru_RU Russian", "sv Swedish", "zh_CN Chinese", null }; cchar *title = ZTX("Available Translations"); zfuncs::F1_help_topic = "language"; // v.10.8 zd = zdialog_new(ZTX("Set Language"),mWin,Bdone,Bcancel,null); zdialog_add_widget(zd,"label","title","dialog",title,"space=10"); zdialog_add_widget(zd,"hbox","hb1","dialog"); zdialog_add_widget(zd,"vbox","vb1","hb1"); for (ii = 0; langs[ii]; ii++) // make radio button per language zdialog_add_widget(zd,"radio",langs[ii],"vb1",langs[ii]); cc = strlen(zfuncs::zlang); // current language for (ii = 0; langs[ii]; ii++) // match on lc_RC if (strnEqu(zfuncs::zlang,langs[ii],cc)) break; if (! langs[ii]) for (ii = 0; langs[ii]; ii++) // failed, match on lc alone if (strnEqu(zfuncs::zlang,langs[ii],2)) break; if (! langs[ii]) ii = 0; // failed, default english zdialog_stuff(zd,langs[ii],1); zdialog_resize(zd,200,0); zdialog_help(zd,"language"); // zdialog help topic v.11.08 zdialog_run(zd); // run dialog zstat = zdialog_wait(zd); for (ii = 0; langs[ii]; ii++) { // get active radio button zdialog_fetch(zd,langs[ii],val); if (val) break; } zdialog_free(zd); // kill dialog if (zstat != 1) return; // user cancel if (! val) return; // no selection strncpy0(lang1,langs[ii],8); pp = strchr(lang1,' '); // isolate lc_RC part *pp = 0; sprintf(command,"fotoxx -l %s -p &",lang1); // start new fotoxx with language err = system(command); if (err) printf("error: %s \n",wstrerror(err)); m_quit(0,0); // exit return; } /**************************************************************************/ // edit translations while running the application interactively void m_translate(GtkWidget *, cchar *) // new v.11.06 { zfuncs::F1_help_topic = "translate"; ZTX_translation_start(mWin); return; } /**************************************************************************/ // create desktop icon / launcher void m_menu_launcher(GtkWidget *, cchar *) // v.11.08 { char *command; zfuncs::F1_help_topic = "menu_launcher"; command = zdialog_text(mWin,ZTX("Make Launcher"),"fotoxx -recent"); if (! command || ! *command) return; // bugfix v.11.09 zmake_menu_launcher(command,"Graphics","Image Editor"); return; } /**************************************************************************/ // user settings dialog void m_settings(GtkWidget *, cchar *) // v.12.01 { int settings_dialog_event(zdialog *zd, cchar *event); zdialog *zd; cchar *zooms[4] = { "1.1892071", "1.2599211", "1.4142136", "2.0" }; double fzoom; /*** Startup Display (o) Recent Files Gallery (o) Previous Image Viewed (o) Blank Window (o) Directory Gallery [__________________________] [browse] (o) Image File [__________________________] [browse] Toolbar Style (o) Text (o) Icons (o) Both Warn Overwrite [x] Panorama Params Lens mm [__|v] lens bow [__|v] Zoom Ratio [___] [done] ***/ zfuncs::F1_help_topic = "user_settings"; zd = zdialog_new(ZTX("Settings"),mWin,Bdone,null); zdialog_add_widget(zd,"hbox","space","dialog",0,"space=5"); zdialog_add_widget(zd,"hbox","hbdisp","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vbdisp1","hbdisp",0,"space=5"); zdialog_add_widget(zd,"label","labdisp","vbdisp1",ZTX("Startup Display")); zdialog_add_widget(zd,"vbox","vbdisp2","hbdisp",0,"expand"); zdialog_add_widget(zd,"radio","recent","vbdisp2",ZTX("Recent Files Gallery")); zdialog_add_widget(zd,"radio","prev","vbdisp2",ZTX("Previous Image Viewed")); zdialog_add_widget(zd,"radio","blank","vbdisp2",ZTX("Blank Window")); zdialog_add_widget(zd,"radio","dirk","vbdisp2",ZTX("Directory Gallery")); zdialog_add_widget(zd,"hbox","hbstdirk","vbdisp2"); zdialog_add_widget(zd,"entry","stdirk","hbstdirk",0,"expand|space=5"); zdialog_add_widget(zd,"button","stdbrowse","hbstdirk",Bbrowse); zdialog_add_widget(zd,"radio","file","vbdisp2",ZTX("Image File")); zdialog_add_widget(zd,"hbox","hbstfile","vbdisp2"); zdialog_add_widget(zd,"entry","stfile","hbstfile",0,"expand|space=5"); zdialog_add_widget(zd,"button","stfbrowse","hbstfile",Bbrowse); zdialog_add_widget(zd,"hbox","hbtbs","dialog",0,"space=2"); zdialog_add_widget(zd,"label","labtbs","hbtbs",ZTX("Toolbar Style"),"space=5"); zdialog_add_widget(zd,"radio","text","hbtbs",ZTX("Text"),"space=5"); zdialog_add_widget(zd,"radio","icons","hbtbs",ZTX("Icons"),"space=5"); zdialog_add_widget(zd,"radio","both","hbtbs",ZTX("Both"),"space=5"); zdialog_add_widget(zd,"hbox","hbwarn","dialog",0,"space=2"); zdialog_add_widget(zd,"label","labwarn","hbwarn",ZTX("Warn Overwrite"),"space=5"); zdialog_add_widget(zd,"check","warn","hbwarn",0); zdialog_add_widget(zd,"hbox","hbpano","dialog",0,"space=2"); zdialog_add_widget(zd,"label","labpano","hbpano","Panorama","space=5"); zdialog_add_widget(zd,"label","space","hbpano",0,"space=5"); zdialog_add_widget(zd,"label","labmm","hbpano","lens mm","space=3"); zdialog_add_widget(zd,"spin","lensmm","hbpano","20|999|0.1|30"); zdialog_add_widget(zd,"label","space","hbpano",0,"space=5"); zdialog_add_widget(zd,"label","labow","hbpano","lens bow","space=3"); zdialog_add_widget(zd,"spin","lensbow","hbpano","-9.99|9.99|0.01|0"); zdialog_add_widget(zd,"hbox","hbzoom","dialog",0,"space=2"); zdialog_add_widget(zd,"label","labzoom","hbzoom","Zoom Ratio","space=5"); zdialog_add_widget(zd,"combo","zoom","hbzoom",0,"scc=8|space=5"); zdialog_stuff(zd,"stdirk",startdirk); // stuff present settings into dialog zdialog_stuff(zd,"stfile",startfile); zdialog_stuff(zd,"recent",0); zdialog_stuff(zd,"prev",0); zdialog_stuff(zd,"blank",0); zdialog_stuff(zd,"dirk",0); zdialog_stuff(zd,"file",0); zdialog_stuff(zd,startdisplay,1); zdialog_stuff(zd,"icons",0); zdialog_stuff(zd,"text",0); zdialog_stuff(zd,"both",0); zdialog_stuff(zd,tbar_style,1); zdialog_stuff(zd,"warn",Fwarnoverwrite); zdialog_stuff(zd,"lensmm",lens_settings[0]); zdialog_stuff(zd,"lensbow",lens_settings[1]); zdialog_cb_app(zd,"zoom",zooms[0]); // 4 zooms = 2x zdialog_cb_app(zd,"zoom",zooms[1]); // 3 zooms = 2x zdialog_cb_app(zd,"zoom",zooms[2]); // 2 zooms = 2x zdialog_cb_app(zd,"zoom",zooms[3]); // 1 zoom = 2x convSD(zoomratio,fzoom); if (fzoom < 1.2) zdialog_stuff(zd,"zoom",zooms[0]); else if (fzoom < 1.3) zdialog_stuff(zd,"zoom",zooms[1]); else if (fzoom < 1.5) zdialog_stuff(zd,"zoom",zooms[2]); else zdialog_stuff(zd,"zoom",zooms[3]); zdialog_help(zd,"user_settings"); zdialog_resize(zd,450,0); zdialog_run(zd,settings_dialog_event); // run dialog and wait for completion zdialog_wait(zd); zdialog_free(zd); return; } // settings dialog event function int settings_dialog_event(zdialog *zd, cchar *event) { int nn; char *pp, temp[200]; if (zd->zstat && zd->zstat != 1) return 0; // cancel if (zd->zstat == 1) // done, check inputs are valid { zdialog_fetch(zd,"stdirk",temp,200); // startup directory if (*temp > ' ' && image_file_type(temp) != 1) { zmessageACK(mWin,ZTX("startup directory is invalid")); zd->zstat = 0; return 0; } else { if (startdirk) zfree(startdirk); startdirk = strdupz(temp,0,"settings"); } zdialog_fetch(zd,"stfile",temp,200); // startup file if (*temp > ' ' && image_file_type(temp) != 2) { zmessageACK(mWin,ZTX("startup file is invalid")); zd->zstat = 0; return 0; } else { if (startfile) zfree(startfile); startfile = strdupz(temp,0,"settings"); } zdialog_fetch(zd,"recent",nn); // startup display if (nn) startdisplay = "recent"; zdialog_fetch(zd,"prev",nn); if (nn) startdisplay = "prev"; zdialog_fetch(zd,"blank",nn); if (nn) startdisplay = "blank"; zdialog_fetch(zd,"dirk",nn); if (nn) startdisplay = "dirk"; zdialog_fetch(zd,"file",nn); if (nn) startdisplay = "file"; zdialog_fetch(zd,"text",nn); // toolbar style if (nn) { tbar_style = "text"; gtk_toolbar_set_style(GTK_TOOLBAR(mTbar),GTK_TOOLBAR_TEXT); } zdialog_fetch(zd,"icons",nn); if (nn) { tbar_style = "icons"; gtk_toolbar_set_style(GTK_TOOLBAR(mTbar),GTK_TOOLBAR_ICONS); } zdialog_fetch(zd,"both",nn); if (nn) { tbar_style = "both"; gtk_toolbar_set_style(GTK_TOOLBAR(mTbar),GTK_TOOLBAR_BOTH); } zdialog_fetch(zd,"warn",Fwarnoverwrite); // warn overwrite option zdialog_fetch(zd,"lensmm",lens_settings[0]); // pano lens parameters zdialog_fetch(zd,"lensbow",lens_settings[1]); zdialog_fetch(zd,"zoom",temp,20); // zoom ratio zfree((char *) zoomratio); zoomratio = strdupz(temp); save_params(); return 0; } if (strEqu(event,"stdbrowse")) { // startup directory browse zdialog_fetch(zd,"stdirk",temp,200); pp = zgetfile1(ZTX("Select startup directory"),"folder",temp); if (! pp) return 0; zdialog_stuff(zd,"stdirk",pp); zfree(pp); } if (strEqu(event,"stfbrowse")) { // startup file browse zdialog_fetch(zd,"stfile",temp,200); pp = zgetfile1(ZTX("Select startup image file"),"open",temp); if (! pp) return 0; zdialog_stuff(zd,"stfile",pp); zfree(pp); } return 0; } /**************************************************************************/ // dump memory usage by category to STDOUT void m_memory_usage(GtkWidget *, cchar *) { zfuncs::F1_help_topic = "memory_usage"; zmalloc_report(); return; } fotoxx-12.01.2/zfuncs.cc0000664000175000017500000105434011701011017013461 0ustar micomico/************************************************************************** zfuncs.cpp collection of Linux and GDK/GTK utility functions Copyright 2006 2007 2008 2009 2010 2011 2012 Michael Cornelison source URL: kornelix.squarespace.com contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***************************************************************************/ // zfuncs.cpp version v.5.0 #include "zfuncs.h" /************************************************************************** system-level utility functions ***************************************************************************/ // Pause and wait for user KB input void apppause() { printf("*** pause, press return to continue: "); getchar(); return; } // Output a message to stdout and wait for user ACK. // Works like printf. void apppause(cchar *pMess, ... ) { va_list arglist; char message[200]; va_start(arglist,pMess); vsnprintf(message,200,pMess,arglist); va_end(arglist); printf("pause: %s \n",message); printf("*** press return to continue: "); getchar(); return; } /**************************************************************************/ // crash with error message and traceback dump in popup window // works like printf void zappcrash(cchar *pMess, ... ) { va_list arglist; FILE *fid1, *fid2; int ii, cc, err, nstack = 50; char message[200]; void *stacklist[50]; char **stackents; char progexe[300], command[300], buff[300], hexaddr[20]; char *pp1, *pp2, *plim, *pfunc; va_start(arglist,pMess); vsnprintf(message,200,pMess,arglist); va_end(arglist); printf("zappcrash: \n %s \n",message); // output message to stdout nstack = backtrace(stacklist,nstack); // get traceback data stackents = backtrace_symbols(stacklist,nstack); for (ii = 0; ii < nstack; ii++) // output backtrace to stdout printf(" %s \n",stackents[ii]); fid1 = fopen("zappcrash","w"); // text file for backtrace fprintf(fid1,"zappcrash: \n %s \n",message); // output message to text file cc = readlink("/proc/self/exe",progexe,300); // get own program path if (cc <= 0) { printf("cannot get /proc/self/exe \n"); // v.4.6 abort(); } progexe[cc] = 0; for (ii = 0; ii < nstack; ii++) // output backtrace to text file { pfunc = 0; plim = stackents[ii] + strlen(stackents[ii]); pp1 = strstr(stackents[ii],"[0x"); // look for hex address [0x.....] if (pp1) pp2 = strchr(pp1,']'); if (pp1 && pp2 && pp2 < plim) { *pp2 = 0; strncpy0(hexaddr,pp1+1,20); snprintf(command,300,"addr2line -e %s %s",progexe,hexaddr); // convert to source program fid2 = popen(command,"r"); // and line number pfunc = fgets(buff,300,fid2); pclose(fid2); if (pfunc) pfunc = strrchr(pfunc,'/'); // remove directories if (pfunc) pfunc++; } fprintf(fid1," %s %s \n",stackents[ii],pfunc); // write to text file } fclose(fid1); err = system("xdg-open zappcrash"); // display in editor if (err) printf("xdg-open failure \n"); abort(); } /**************************************************************************/ // application initialization function to catch segfaults void catch_signals() { void sighandler(int signal); struct sigaction sigact; sigact.sa_handler = sighandler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGSEGV,&sigact,0); return; } // catch segfaults and produce backtrace dumps on-screen void sighandler(int signal) { zappcrash("segment fault"); return; } /**************************************************************************/ // This function will restart the current program with root privileges, // if the correct (sudo) password is given. It does not return. void beroot(int argc, char *argv[]) { int cc1, cc2, ii, err; char command[1000]; if (getuid() == 0) return; // already root v.4.9 strcpy(command,"which gksu > /dev/null 2>&1"); // Debian err = system(command); strcpy(command,"gksu "); if (err) { strcpy(command,"which beesu > /dev/null 2>&1"); // Fedora, just to be different err = system(command); // v.4.7 strcpy(command,"beesu "); } if (err) { printf("cannot find gksu or beesu \n"); abort(); } cc1 = strlen(command); // gksu (or) beesu cc2 = readlink("/proc/self/exe",command+cc1,990); if (cc2 <= 0) { printf("cannot get /proc/self/exe \n"); // v.4.6 abort(); } command[cc1+cc2] = 0; // gksu or beesu for (ii = 0; ii < argc; ii++) // append command line parameters strncatv(command,990," ",argv[ii],null); strcat(command," &"); // return immediately printf("%s \n",command); err = system(command); exit(0); } /**************************************************************************/ // get time in real seconds (since 2000.01.01 00:00:00) double get_seconds() { timeval time1; gettimeofday(&time1,0); return time1.tv_sec + 0.000001 * time1.tv_usec - 946684800.0; } /**************************************************************************/ // start a timer or get elapsed time with millisecond resolution. void start_timer(double &time0) { timeval timev; gettimeofday(&timev,0); time0 = timev.tv_sec + 0.000001 * timev.tv_usec; return; } double get_timer(double &time0) { timeval timev; double time; gettimeofday(&timev,0); time = timev.tv_sec + 0.000001 * timev.tv_usec; return time - time0; } /**************************************************************************/ // start a process CPU timer or get elapsed process CPU time // returns seconds with millisecond resolution void start_CPUtimer(double &time0) { time0 = CPUtime(); return; } double get_CPUtimer(double &time0) { return CPUtime() - time0; } /**************************************************************************/ // get elapsed CPU time used by current process // returns seconds with millisecond resolution double CPUtime() { clock_t ctime = clock(); double dtime = ctime / 1000000.0; return dtime; } /**************************************************************************/ // Get elapsed CPU time used by current process, including all threads. // Returns seconds with millisecond resolution. double CPUtime2() // new v.4.7 { struct rusage usage; double utime, stime; int err; err = getrusage(RUSAGE_SELF,&usage); if (err) return 0.0; utime = usage.ru_utime.tv_sec + 0.000001 * usage.ru_utime.tv_usec; stime = usage.ru_stime.tv_sec + 0.000001 * usage.ru_stime.tv_usec; return utime + stime; } /**************************************************************************/ // get elapsed process time for my process, // including threads and child processes. double jobtime() // new v.4.7 { double jiffy = 1.0 / sysconf(_SC_CLK_TCK); // "jiffy" time slice = 1.0 / HZ char buff[200]; double cpu1, cpu2, cpu3, cpu4; FILE *fid; char *pp; fid = fopen("/proc/self/stat","r"); if (! fid) return 0; pp = fgets(buff,200,fid); fclose(fid); if (! pp) return 0; parseprocrec(pp,14,&cpu1,15,&cpu2,16,&cpu3,17,&cpu4,null); return (cpu1 + cpu2 + cpu3 + cpu4) * jiffy; } /**************************************************************************/ // Read and parse /proc file with records formatted "parmname xxxxxxx" // Find all requested parameters and return their numeric values int parseprocfile(cchar *pfile, cchar *pname, double *value, ...) // EOL = 0 { FILE *fid; va_list arglist; char buff[1000]; const char *pnames[20]; double *values[20]; int ii, fcc, wanted, found; pnames[0] = pname; // 1st parameter values[0] = value; *value = 0; va_start(arglist,value); for (ii = 1; ii < 20; ii++) // get all parameters { pnames[ii] = va_arg(arglist,char *); if (! pnames[ii]) break; values[ii] = va_arg(arglist,double *); *values[ii] = 0; // initialize to zero } va_end(arglist); if (ii == 20) zappcrash("parseProcFile, too many fields"); wanted = ii; found = 0; fid = fopen(pfile,"r"); // open /proc/xxx file if (! fid) return 0; while ((fgets(buff,999,fid))) // read record, "parmname nnnnn" { for (ii = 0; ii < wanted; ii++) { // look for my fields fcc = strlen(pnames[ii]); if (strnEqu(buff,pnames[ii],fcc)) { *values[ii] = atof(buff+fcc); // return value found++; break; } } if (found == wanted) break; // stop when all found } fclose(fid); return found; } // Parse /proc record of the type "xxx xxxxx xxxxx xxxxxxxx xxx" // Return numeric values for requested fields (starting with 1) int parseprocrec(char *prec, int field, double *value, ...) // EOL = 0 { va_list arglist; int xfield = 1, found = 0; va_start(arglist,value); while (*prec == ' ') prec++; // skip leading blanks while (field > 0) { while (xfield < field) // skip to next wanted field { prec = strchr(prec,' '); // find next blank if (! prec) break; while (*prec == ' ') prec++; // skip multiple blanks xfield++; } if (! prec) break; *value = atof(prec); // convert, return double found++; field = va_arg(arglist,int); // next field number value = va_arg(arglist,double *); // next output double * } while (field > 0) { *value = 0; // zero values not found field = va_arg(arglist,int); value = va_arg(arglist,double *); } va_end(arglist); return found; } /**************************************************************************/ // sleep for specified time in seconds (double) // signals can cause early return void zsleep(double dsecs) { unsigned isecs, nsecs; timespec tsecs; if (dsecs == 0.0) return; isecs = unsigned(dsecs); nsecs = unsigned(1000000000.0 * (dsecs - isecs)); tsecs.tv_sec = isecs; tsecs.tv_nsec = nsecs; nanosleep(&tsecs,null); return; } /**************************************************************************/ // Lock or unlock a multi-process multi-thread resource. // Only one process/thread may posess a given lock. // A reboot or process exit or crash releases the lock. // global_lock() returns fd > 0 if success, -1 otherwise. // To unlock, call global_unlock(fd). int global_lock(cchar *lockname) // v.4.7 { int err, fd; char lockfile[100]; strcpy(lockfile,"/tmp/global_lock_"); strcat(lockfile,lockname); fd = open(lockfile,O_RDWR|O_CREAT,0666); // open or create the lock file if (fd < 0) { printf("global_lock(), %s \n",strerror(errno)); return -1; } err = flock(fd,LOCK_EX|LOCK_NB); // request exclusive non-blocking lock if (err) { close(fd); return -1; } return fd + 1; // return value is >= 1 } int global_unlock(int fd) { int err = close(fd - 1); if (err < 0) return -1; else return 1; } /**************************************************************************/ // start a detached thread using a simplified protocol void start_detached_thread(void * threadfunc(void *), void * arg) { pthread_t ptid; pthread_attr_t ptattr; int pterr; pthread_attr_init(&ptattr); pthread_attr_setdetachstate(&ptattr,PTHREAD_CREATE_DETACHED); pterr = pthread_create(&ptid,&ptattr,threadfunc,arg); if (pterr) zappcrash("start_detached_thread() failure"); return; } /**************************************************************************/ // Synchronize execution of multiple threads. // Simultaneously resume NT calling threads. // from main(): synch_threads(NT) /* setup to synch NT threads */ // from each thread: synch_threads() /* suspend, resume simultaneously */ void synch_threads(int NT) { static pthread_barrier_t barrier; static int bflag = 0; if (NT) { // main(), initialize if (bflag) pthread_barrier_destroy(&barrier); pthread_barrier_init(&barrier,null,NT); bflag = 1; return; } pthread_barrier_wait(&barrier); // thread(), wait for NT threads return; // unblock } /**************************************************************************/ // safely access parameters from multiple threads // limitation: one lock for any number of parameters mutex zget_lock = PTHREAD_MUTEX_INITIALIZER; int zget_locked(int ¶m) // lock and return parameter { mutex_lock(&zget_lock); return param; } void zput_locked(int ¶m, int value) // set and unlock parameter { param = value; mutex_unlock(&zget_lock); return; } int zadd_locked(int ¶m, int incr) // lock, increment, unlock, return { int retval; mutex_lock(&zget_lock); retval = param + incr; param = retval; mutex_unlock(&zget_lock); return retval; } /**************************************************************************/ // Allow only one thread at a time through a function that is otherwise // not thread-safe. Function must call these functions at entry and exit. mutex gate_threads_mutex = PTHREAD_MUTEX_INITIALIZER; void gate_threads_enter() { mutex_lock(&gate_threads_mutex); return; } void gate_threads_leave() { mutex_unlock(&gate_threads_mutex); return; } /**************************************************************************/ // malloc() and free() wrappers with auto crash on failure and log option. // overflow sentinel is placed after end of allocated memory // zmalloc() and zfree() calls are logged if log count > 0 // benchmark zmalloc() + zfree(): average 0.22 microseconds on 2.67 GHz CPU #define zmalloc_add 32 uint zmalloc_tot = 0; int zmalloc_logcount = 0; // set to +N to log next N calls void zmalloc_tabulate(cchar *tag, int bytes); // private function char * zmalloc(size_t bytes, cchar *tag) // optional tag { void *maddr = malloc(bytes + zmalloc_add); if (! maddr) zappcrash("Memory request for %zu bytes failed. \n" "Application will now terminate.",bytes); unsigned *pbytes = (unsigned *) maddr; // 0..3 caller bytes char *psen1 = (char *) maddr + 4; // 4..7 sentinel "sen1" char *ptag = (char *) maddr + 8; // 8..27 tag, < 20 chars. char *puser = (char *) maddr + 28; // 28..B+27 user data, B chars. char *psen2 = (char *) puser + bytes; // B+28..B+31 sentinel "sen2" if (bytes <= 0) zappcrash("zmalloc bytes %d",bytes); *pbytes = bytes; strncpy(psen1,"sen1",4); if (! tag) tag = "notag"; strncpy0(ptag,tag,20); memset(puser,0,bytes); // clear user space to zeros strncpy(psen2,"sen2",4); zmalloc_tot += bytes; zmalloc_tabulate(ptag,bytes); // track usage by tag if (zmalloc_logcount) { printf("zmalloc %-20s loc: %p bytes: %zu total: %u \n",ptag,puser,bytes,zmalloc_tot); zmalloc_logcount--; } return puser; } // free memory allocated by zmalloc(). checks for overflow. void zfree(void *puser) { if (! puser) zappcrash("zfree: null address"); void *maddr = (char *) puser - 28; unsigned *pbytes = (unsigned *) maddr; char *psen1 = (char *) maddr + 4; char *ptag = (char *) maddr + 8; size_t bytes = *pbytes; char *psen2 = (char *) puser + bytes; if (strncmp("sen1",psen1,4)) // check sentinels zappcrash("zfree: invalid address %p",puser); if (strncmp("sen2",psen2,4)) zappcrash("zfree: buffer overflow |%s|%s|",ptag,puser); *psen1 = *psen2 = 0; // destroy sentinels zmalloc_tot -= bytes; zmalloc_tabulate(ptag,-bytes); // track usage by tag if (zmalloc_logcount) { printf("zfree %-20s loc: %p bytes: %zu total: %u \n",ptag,puser,bytes,zmalloc_tot); zmalloc_logcount--; } free(maddr); return; } // turn logging flag on for specified log count, or off if count = 0; void zmalloc_log(int count) { zmalloc_logcount = count; return; } // private function. track how much memory is in use, per tag. // real tag capacity is about 80% of nominal 1000 HashTab *zmalloc_hashtab = 0; uint zmalloc_count[1000], zmalloc_bytes[1000]; void zmalloc_tabulate(cchar *ptag, int bytes) { int ii; if (! zmalloc_hashtab) { zmalloc_hashtab = new HashTab(20,1000); memset(zmalloc_count, 0, 1000 * sizeof(uint)); memset(zmalloc_bytes, 0, 1000 * sizeof(uint)); } ii = zmalloc_hashtab->Find(ptag); if (ii < 0) ii = zmalloc_hashtab->Add(ptag); if (ii < 0) zappcrash("zmalloc hash table full"); zmalloc_bytes[ii] += bytes; if (bytes > 0) ++zmalloc_count[ii]; else --zmalloc_count[ii]; return; } // report total memory allocated per tag - leak detection utility void zmalloc_report() { int count, ii, first = 1; uint bytes; char tag[20]; printf("\n zmalloc total memory: %u \n",zmalloc_tot); while (true) { ii = zmalloc_hashtab->GetNext(first,tag); if (ii < 0) break; ii = zmalloc_hashtab->Find(tag); if (ii < 0) zappcrash("zmalloc hash table bug: %s",tag); bytes = zmalloc_bytes[ii]; count = zmalloc_count[ii]; if (bytes) printf(" %-20s %8d %d \n",tag,count,bytes); } return; } /**************************************************************************/ // Run a shell command and get its outputs one record at a time. // Start a new command with contx = 0. Do not change contx. // NULL return means no more output. // Get command exit status: err = command_status(contx) // Caller owns returned strings which are candidates for zfree() // FILE * CO_contx[10] = { 0,0,0,0,0,0,0,0,0,0 }; int CO_status[10]; char * command_output(int &contx, cchar *command, ...) // simplify, allow parallel usage { FILE *fid; va_list arglist; char buff[10000], *prec; if (contx == 0) // start new command { for (contx = 1; contx < 10; contx++) if (CO_contx[contx] == 0) break; if (contx == 10) zappcrash("command_output(), parallel usage > 9"); va_start(arglist,command); // format command vsnprintf(buff,9999,command,arglist); va_end(arglist); fid = popen(buff,"r"); // execute command, output to FID if (fid == 0) { CO_status[contx] = errno; // failed to start return 0; } CO_contx[contx] = fid + 1000; CO_status[contx] = -1; // mark context busy } fid = CO_contx[contx] - 1000; prec = fgets_trim(buff,9999,fid,1); // next output, less trailing \n if (prec) return strdupz(prec,0,"command_output"); // return output to caller CO_status[contx] = pclose(fid); // EOF, set status CO_contx[contx] = 0; // mark context free return 0; } int command_status(int contx) // get command exit status { int err = CO_status[contx]; return WEXITSTATUS(err); // special BS for subprocess } /**************************************************************************/ // signal a subprocess to pause, resume, or terminate // return: 0: OK +-N: error int signalProc(cchar *pname, cchar *signal) { pid_t pid; FILE *fid; char buff[100], *pp; int err, nsignal = 0; sprintf(buff,"ps -C %s h o pid",pname); fid = popen(buff,"r"); // popen() instead of system() if (! fid) return 2; pp = fgets(buff,100,fid); pclose(fid); if (! pp) return 4; pid = atoi(buff); if (! pid) return 5; if (strEqu(signal,"pause")) nsignal = SIGSTOP; if (strEqu(signal,"resume")) nsignal = SIGCONT; if (strEqu(signal,"kill")) nsignal = SIGKILL; err = kill(pid,nsignal); return err; } /**************************************************************************/ // run a command or program as root user // sucomm: root user access command, "su" or "sudo" // command: shell command or filespec of the program to start // returns 0 if successfully started, else returns an error code int runroot(cchar *sucomm, cchar *command) { char xtcommand[500]; int err; if (strcmp(sucomm,"sudo") == 0) { snprintf(xtcommand,499,"xterm -geometry 40x3 -e sudo -S %s",command); err = system(xtcommand); return err; } if (strcmp(sucomm,"su") == 0) { snprintf(xtcommand,499,"xterm -geometry 40x3 -e su -c %s",command); err = system(xtcommand); return err; } return -1; } /**************************************************************************/ // Check if a list of programs are all installed // If any are missing, pop-up a window of missing programs // Returns the number of missing programs (zero if none). int checkinstall(cchar *prog1, ...) // null terminated list { va_list arglist; char *buff, errmessage[200] = "missing programs:\n"; cchar *prog, *pp, *missprogs[20]; int contx, found, Nmiss = 0; va_start(arglist,prog1); prog = prog1; while (prog) { contx = 0; found = 0; while (true) { buff = command_output(contx,"whereis %s",prog); if (! buff) break; pp = strchr(buff,':'); if (pp) pp = strchr(pp,'/'); if (pp) found = 1; zfree(buff); continue; } if (! found) { if (Nmiss == 20) break; missprogs[Nmiss] = prog; Nmiss++; } prog = va_arg(arglist,cchar *); } va_end(arglist); if (Nmiss) { for (int ii = 0; ii < Nmiss; ii++) strncatv(errmessage,199,missprogs[ii]," ",null); zmessageACK(null,errmessage); } return Nmiss; } /**************************************************************************/ // fgets() with additional feature: trailing \n \r are removed. // optional bf flag: true if trailing blanks are to be removed. // trailing null character is assured. char * fgets_trim(char *buff, int maxcc, FILE *fid, int bf) { int cc; char *pp; pp = fgets(buff,maxcc,fid); if (! pp) return pp; cc = strlen(buff); if (bf) while (cc && buff[cc-1] > 0 && buff[cc-1] <= ' ') --cc; else while (cc && buff[cc-1] > 0 && buff[cc-1] < ' ') --cc; buff[cc] = 0; return pp; } /**************************************************************************/ // return true if both files are in the same directory // both files may be files or directories int samedirk(cchar *file1, cchar *file2) { int cc1, cc2; cchar *pp1, *pp2; if (! file1 || ! file2) return 0; pp1 = strrchr(file1,'/'); pp2 = strrchr(file2,'/'); if (! pp1 && ! pp2) return 1; if (pp1 && ! pp2) return 0; if (! pp1 && pp2) return 0; cc1 = pp1 - file1; cc2 = pp2 - file2; if (cc1 != cc2) return 0; if (strncmp(file1,file2,cc1) == 0) return 1; return 0; } /************************************************************************** Parse a pathname (filespec) and return its components. Returned strings are allocated in static memory (no zfree needed). Missing components are returned as null pointers. input ppath outputs /name1/name2/ directory /name1/name2/ with no file /name1/name2 directory /name1/name2/ if name2 a directory, otherwise directory /name1/ and file name2 /name1/name2.xxx if .xxx < 8 chars, returns file name2 and ext .xxx, otherwise returns file name2.xxx and no ext returns 0 if no error, else 1 ***************************************************************************/ int parsefile(cchar *ppath, char **pdirk, char **pfile, char **pext) { struct stat statb; static char dirk[1000], file[200], ext[8]; char *pp; int err, cc1, cc2; *pdirk = *pfile = *pext = null; cc1 = strlen(ppath); if (cc1 > 999) return 1; // ppath too long strcpy(dirk,ppath); *pdirk = dirk; err = stat(dirk,&statb); // have directory only if (! err && S_ISDIR(statb.st_mode)) return 0; pp = (char *) strrchr(dirk,'/'); if (! pp) return 1; // illegal pp++; cc2 = pp - dirk; if (cc2 < 2 || cc2 == cc1) return 0; // have /xxxx or /xxxx/ if (strlen(pp) > 199) return 1; // filename too long strcpy(file,pp); // file part *pfile = file; *pp = 0; // remove from dirk part pp = (char *) strrchr(file,'.'); if (! pp || strlen(pp) > 7) return 0; // file part, no .ext strcpy(ext,pp); // .ext part *pext = ext; *pp = 0; // remove from file part return 0; } /************************************************************************** utility to measure CPU time spent in various functions or code blocks cpu_profile_init() initialize at start of test cpu_profile_report() report CPU time per function cpu_profile_enter(fnum) at entry to a function // inline, defined in zfuncs.h cpu_profile_exit(fnum) at exit from a function // inline, defined in zfuncs.h ***************************************************************************/ volatile double cpu_profile_table[100]; volatile double cpu_profile_timer; volatile double cpu_profile_elapsed; volatile int cpu_profile_kill = 0; void cpu_profile_init() { void * cpu_profile_timekeeper(void *); for (int ii = 0; ii < 99; ii++) cpu_profile_table[ii] = 0; cpu_profile_elapsed = 0; start_detached_thread(cpu_profile_timekeeper,null); } void cpu_profile_report() { cpu_profile_kill++; printf("elapsed: %.2f \n",cpu_profile_elapsed); for (int ii = 0; ii < 100; ii++) { double dtime = cpu_profile_table[ii]; if (dtime) printf("cpu profile func: %d time: %.2f \n",ii,dtime); } } void * cpu_profile_timekeeper(void *) { timeval time0, time1; gettimeofday(&time0,0); while (true) { gettimeofday(&time1,0); cpu_profile_elapsed = time1.tv_sec - time0.tv_sec + 0.000001 * (time1.tv_usec - time0.tv_usec); zsleep(0.001); if (cpu_profile_kill) break; } cpu_profile_kill = 0; pthread_exit(0); } /************************************************************************** strField() cchar * strField(cchar *string, cchar *delim, int Nth) Get the Nth field in input string, which contains at least N fields delimited by the character(s) in delim (e.g. blank, comma). Returns a pointer to the found field (actually a pointer to a copy of the found field, with a null terminator appended). If a delimiter is immediately followed by another delimiter, it is considered a field with zero length, and the string "" is returned. Leading blanks in a field are omitted from the returned field. A field with only blanks is returned as a single blank. The last field may be terminated by null or a delimiter. Characters within quotes (") are treated as data within a field, i.e. blanks and delimiters are not processed as such. The quotes are removed from the returned field. If there are less than N fields, a null pointer is returned. The last 100 fields are saved and recycled in a circular manner. The caller does not have to free memory. If more memory depth is needed, caller must copy the returned data elsewhere. The input string must be < 1000 characters. The output string may be modified if the length is not increased. Example: input string: ,a,bb, cc, ,dd"ee,ff"ggg, (first and last characters are comma) delimiter: comma Nth returned string 1: (null string) 2: a 3: bb 4: cc 5: (one blank) 6: ddee,ffggg 7: (null pointer >> no more fields) ***************************************************************************/ cchar * strField(cchar *string, cchar *delim, int Nth) { static int ftf = 1, nret = 0; static char *retf[100]; char *pf1, pf2[1000]; cchar quote = '"'; int ii, nf, fcc = 0; static char blankstring[2], nullstring[1]; gate_threads_enter(); // allow one thread at a time v.4.7 if (ftf) // overall first call { ftf = 0; for (ii = 0; ii < 100; ii++) retf[ii] = 0; strcpy(blankstring," "); *nullstring = 0; } if (strlen(string) > 999) { gate_threads_leave(); return 0; } if (Nth < 1) { gate_threads_leave(); return 0; } pf1 = (char *) string - 1; // start parse nf = 0; while (nf < Nth) { pf1++; // start field nf++; fcc = 0; while (*pf1 == ' ') pf1++; // skip leading blanks while (true) { if (*pf1 == quote) { // pass chars between single quotes pf1++; // (but without the quotes) while (*pf1 && *pf1 != quote) pf2[fcc++] = *pf1++; if (*pf1 == quote) pf1++; } else if (strchr(delim,*pf1) || *pf1 == 0) break; // found delimiter or null else pf2[fcc++] = *pf1++; // pass normal character } if (*pf1 == 0) break; } if (nf < Nth) { gate_threads_leave(); return 0; } // no Nth field if (fcc == 0) { // empty field if (*string && pf1[-1] == ' ' && !strchr(delim,' ')) // all blanks and blank not delim. { gate_threads_leave(); return blankstring; } // return one blank if (*pf1 == 0) { gate_threads_leave(); return 0; } // no field gate_threads_leave(); return nullstring; // return null string } if (++nret == 100) nret = 0; // use next return slot if (retf[nret]) zfree(retf[nret]); retf[nret] = zmalloc(fcc+2,"strField"); strncpy0(retf[nret],pf2,fcc+1); gate_threads_leave(); return retf[nret]; } cchar * strField(cchar *string, cchar delim, int Nth) // alternative with one delimiter { char delims[2] = "x"; *delims = delim; return strField(string,delims,Nth); } /************************************************************************** stat = strParms(begin, input, pname, maxcc, pval) Parse an input string with parameter names and values: "pname1=pval1 | pname2 | pname3=pval3 | pname4 ..." begin int & must be 1 to start new string, is modified input cchar * input string pname char * output parameter name maxcc int max. length for pname, including null pval double & output parameter value stat int status: 0=OK, -1=EOL, 1=parse error Each call returns the next pname and pval. A pname with no pval is assigned a value of 1 (present). Input format: pname1 | pname2=pval2 | pname3 ... null Leading blanks are ignored, and pnames may have imbedded blanks. pvals must convert to double using convSD (accepts decimal point or comma) ***/ int strParms(int &begin, cchar *input, char *pname, int maxcc, double &pval) { static int ii, beginx = 3579246; cchar *pnamex, *delim; int cc, err; if (begin == 1) { // start new string begin = ++beginx; ii = 0; } if (begin != beginx) zappcrash("strParms call error"); // thread safe, not reentrant *pname = 0; // initz. outputs to nothing pval = 0; while (input[ii] == ' ') ii++; // skip leading blanks if (input[ii] == 0) return -1; // no more data pnamex = input + ii; // next pname for (cc = 0; ; cc++) { // look for delimiter if (pnamex[cc] == '=') break; if (pnamex[cc] == '|') break; if (pnamex[cc] == 0) break; } if (cc == 0) return 1; // err: 2 delimiters if (cc >= maxcc) return 1; // err: pname too big strncpy0(pname,pnamex,cc+1); // pname >> caller strTrim(pname); // remove trailing blanks if (pnamex[cc] == 0) { // pname + null ii += cc; // position for next call pval = 1.0; // pval = 1 >> caller return 0; } if (pnamex[cc] == '|') { // pname + | ii += cc + 1; // position for next call pval = 1.0; // pval = 1 >> caller return 0; } ii += cc + 1; // pname = pval err = convSD(input + ii, pval, &delim); // parse pval (was strtod() if (err > 1) return 1; while (*delim == ' ') delim++; // skip poss. trailing blanks if (*delim && *delim != '|') return 1; // err: delimiter not | or null ii = delim - input; if (*delim) ii++; // position for next call return 0; } /**************************************************************************/ // Produce random value from hashed input string. // Output range is 0 to max-1. int strHash(cchar *string, int max) { uint hash = 1; uchar byte; while ((byte = *string++)) { hash *= byte; hash = hash ^ (hash >> 7); hash = hash & 0x00FFFFFF; } hash = hash % max; return hash; } /**************************************************************************/ // Hash an input string into a random printable (a-z) output string. // Returns outcc character random printable string in static memory. // Every output character is randomized from the entire input string. cchar * strHash2(cchar *instring, int outcc) { int incc, ii, jj, rani = 0; int64 seed = 13579; static char outstring[40]; incc = strlen(instring); if (outcc > 39) zappcrash("strHash2() outcc > 39"); for (ii = 0; ii < outcc; ii++) { for (jj = 0; jj < incc; jj++) { seed = seed + instring[jj]; rani = lrandz(&seed); } outstring[ii] = 'a' + rani % 26; } outstring[ii] = 0; return outstring; } /**************************************************************************/ // Copy string with specified max. length (including null terminator). // truncate if needed. null terminator is always supplied. int strncpy0(char *dest, cchar *source, uint cc) { strncpy(dest,source,cc); dest[cc-1] = 0; if (strlen(source) >= cc) return 1; // truncated else return 0; } /**************************************************************************/ // Copy string with blank pad to specified length. No null. void strnPad(char *dest, cchar *source, int cc) { strncpy(dest,source,cc); int ii = strlen(source); for (int jj = ii; jj < cc; jj++) dest[jj] = ' '; } /**************************************************************************/ // Remove trailing blanks from a string. Returns remaining length. int strTrim(char *dest, cchar *source) { if (dest != source) strcpy(dest,source); return strTrim(dest); } int strTrim(char *dest) { int ii = strlen(dest); while (ii && (dest[ii-1] == ' ')) dest[--ii] = 0; return ii; } /**************************************************************************/ // Remove leading and trailing blanks from a string. // Returns remaining length, possibly zero. int strTrim2(char *dest, cchar *source) { cchar *pp1, *pp2; int cc; pp1 = source; pp2 = source + strlen(source) - 1; while (*pp1 == ' ') pp1++; while (*pp2 == ' ' && pp2 > pp1) pp2--; cc = pp2 - pp1 + 1; memmove(dest,pp1,cc); dest[cc] = 0; return cc; } int strTrim2(char *string) { return strTrim2(string,(cchar *) string); } /**************************************************************************/ // Remove all blanks from a string. Returns remaining length. int strCompress(char *dest, cchar *source) { if (dest != source) strcpy(dest,source); return strCompress(dest); } int strCompress(char *string) { int ii, jj; for (ii = jj = 0; string[ii]; ii++) { if (string[ii] != ' ') { string[jj] = string[ii]; jj++; } } string[jj] = 0; return jj; } /**************************************************************************/ // Concatenate multiple strings, staying within a specified overall length. // The destination string is also the first source string. // Null marks the end of the source strings (omission --> crash). // Output is truncated to fit within the specified length. // A final null is assured and is included in the length. // Returns 0 if OK, 1 if truncation was needed. int strncatv(char *dest, int maxcc, cchar *source, ...) { cchar *ps; va_list arglist; maxcc = maxcc - strlen(dest) - 1; if (maxcc < 0) return 1; va_start(arglist,source); ps = source; while (ps) { strncat(dest,ps,maxcc); maxcc = maxcc - strlen(ps); if (maxcc < 0) break; ps = va_arg(arglist,cchar *); } va_end(arglist); if (maxcc < 0) return 1; return 0; } /**************************************************************************/ // Match 1st string to N additional strings. // Return matching string number 1 to N or 0 if no match. // Supply a null argument for end of list. int strcmpv(cchar *string, ...) { int match = 0; char *stringN; va_list arglist; va_start(arglist,string); while (1) { stringN = va_arg(arglist, char *); if (stringN == null) { va_end(arglist); return 0; } match++; if (strcmp(string,stringN) == 0) { va_end(arglist); return match; } } } /**************************************************************************/ // convert string to upper case void strToUpper(char *string) { int ii; char jj; const int delta = 'A' - 'a'; for (ii = 0; (jj = string[ii]); ii++) if ((jj >= 'a') && (jj <= 'z')) string[ii] += delta; } void strToUpper(char *dest, cchar *source) { strcpy(dest,source); strToUpper(dest); } /**************************************************************************/ // convert string to lower case void strToLower(char *string) { int ii; char jj; const int delta = 'a' - 'A'; for (ii = 0; (jj = string[ii]); ii++) if ((jj >= 'A') && (jj <= 'Z')) string[ii] += delta; } void strToLower(char *dest, cchar *source) { strcpy(dest,source); strToLower(dest); } /**************************************************************************/ // copy string strin to strout, replacing every occurrence // of the substring ssin with the substring ssout int repl_1str(cchar *strin, char *strout, cchar *ssin, cchar *ssout) { int ccc, cc1, cc2, nfound; cchar *ppp; cc1 = strlen(ssin); cc2 = strlen(ssout); nfound = 0; while ((ppp = strstr(strin,ssin))) { nfound++; ccc = ppp - strin; strncpy(strout,strin,ccc); strout += ccc; strin += ccc; strncpy(strout,ssout,cc2); strin += cc1; strout += cc2; } strcpy(strout,strin); return nfound; } /**************************************************************************/ // like repl_1str, but multiple pairs of substrings are processed // (... ssin1, ssout1, ssin2, ssout2, ... null) int repl_Nstrs(cchar *strin, char *strout, ...) { va_list arglist; cchar *ssin, *ssout; char ftemp[maxfcc]; int ftf, nfound; ftf = 1; nfound = 0; va_start(arglist,strout); while (true) { ssin = va_arg(arglist, char *); if (! ssin) break; ssout = va_arg(arglist, char *); if (ftf) { ftf = 0; nfound += repl_1str(strin,strout,ssin,ssout); } else { strcpy(ftemp,strout); nfound += repl_1str(ftemp,strout,ssin,ssout); } } va_end(arglist); return nfound; } /**************************************************************************/ // Copy and convert string to hex string. // Each input character 'A' >> 3 output characters "41 " void strncpyx(char *out, cchar *in, int ccin) { int ii, jj, c1, c2; char cx[] = "0123456789ABCDEF"; if (! ccin) ccin = strlen(in); for (ii = 0, jj = 0; ii < ccin; ii++, jj += 3) { c1 = (uchar) in[ii] >> 4; c2 = in[ii] & 15; out[jj] = cx[c1]; out[jj+1] = cx[c2]; out[jj+2] = ' '; } out[jj] = 0; return; } /**************************************************************************/ // Strip trailing zeros from ascii floating numbers // (e.g. 1.230000e+02 --> 1.23e+02) void StripZeros(char *pNum) { int ii, ll; int pp, k1, k2; char work[20]; ll = strlen(pNum); if (ll >= 20) return; for (ii = 0; ii < ll; ii++) { if (pNum[ii] == '.') { pp = ii; k1 = k2 = 0; for (++ii; ii < ll; ii++) { if (pNum[ii] == '0') { if (! k1) k1 = k2 = ii; else k2 = ii; continue; } if ((pNum[ii] >= '1') && (pNum[ii] <= '9')) { k1 = 0; continue; } break; } if (! k1) return; if (k1 == pp + 1) k1++; if (k2 < k1) return; strcpy(work,pNum); strcpy(work+k1,pNum+k2+1); strcpy(pNum,work); return; } } } /**************************************************************************/ // test for blank/null string int blank_null(cchar *string) { if (! string) return 1; // null string if (! *string) return 2; // zero length string int cc = strlen(string); for (int ii = 0; ii < cc; ii++) if (string[ii] != ' ') return 0; // non-blank string return 3; // blank string } /**************************************************************************/ // make a copy of a string in heap memory and allocate more space // returned string is subject for zfree(); char * strdupz(cchar *string, int more, cchar *tag) { char *pp = zmalloc(strlen(string)+1+more,tag); strcpy(pp,string); return pp; } // copy into existing 'zmalloc' string if present and long enough // else free memory and allocate a longer one // destination string is subject for zfree() int strdupz(cchar *source, char *&zdest, int more, cchar *tag) { int ccs, ccd; ccs = strlen(source); if (! zdest) zdest = zmalloc(ccs+1+more,tag); ccd = (int) *(zdest-8); if (ccd < ccs+1) { zfree(zdest); zdest = zmalloc(ccs+1+more,tag); } strcpy(zdest,source); return ccs; } /**************************************************************************/ // clean \x escape sequences and replace them with the escaped character // \n >> newline \" >> doublequote \\ >> backslash etc. // see $ man ascii for the complete list int clean_escapes(char *string) { char *pp1 = string, *pp2 = string, *pp; char char1; char escapes[] = "abtnvfr"; int count = 0; while (true) { char1 = *pp1++; if (char1 == 0) { *pp2 = 0; return count; } else if (char1 == '\\') { char1 = *pp1++; pp = strchr(escapes,char1); if (pp) char1 = pp - escapes + 7; count++; } *pp2++ = char1; } } /**************************************************************************/ // Compute the graphic character count for a UTF8 character string. // Depends on UTF8 rules: // - ascii characters are positive (actually 0x00 to 0x7F) // - 1st byte of multibyte sequence is negative (actually 0xC0 to 0xFD) // - subsequent bytes are negative and < 0xC0 (actually 0x80 to 0xBF) int utf8len(cchar *utf8string) { int ii, cc; char xlimit = 0xC0; for (ii = cc = 0; utf8string[ii]; ii++) { if (utf8string[ii] < 0) // multibyte character while (utf8string[ii+1] < xlimit) ii++; // skip extra bytes cc++; } return cc; } /**************************************************************************/ // Extract a UTF8 substring with a specified count of graphic characters. // utf8in input UTF8 string // utf8out output UTF8 string, which must be long enough // pos initial graphic character position to get (0 = first) // cc max. count of graphic characters to get // returns number of graphic characters extracted, <= cc // Output string is null terminated after last extracted character. int utf8substring(char *utf8out, cchar *utf8in, int pos, int cc) { int ii, jj, kk, posx, ccx; char xlimit = 0xC0; for (ii = posx = 0; posx < pos && utf8in[ii]; ii++) { if (utf8in[ii] < 0) while (utf8in[ii+1] < xlimit) ii++; posx++; } jj = ii; for (ccx = 0; ccx < cc && utf8in[jj]; jj++) { if (utf8in[jj] < 0) while (utf8in[jj+1] < xlimit) jj++; ccx++; } kk = jj - ii; strncpy(utf8out,utf8in+ii,kk); utf8out[kk] = 0; return ccx; } /**************************************************************************/ // check a string for valid utf8 encoding // returns: 0 = OK, 1 = bad string int utf8_check(cchar *string) { cchar *pp; unsigned char ch1, ch2, nch; for (pp = string; *pp; pp++) { ch1 = *pp; if (ch1 < 0x7F) continue; if (ch1 > 0xBF && ch1 < 0xE0) nch = 1; else if (ch1 < 0xF0) nch = 2; else if (ch1 < 0xF8) nch = 3; else if (ch1 < 0xFC) nch = 4; else if (ch1 < 0xFE) nch = 5; else return 1; while (nch) { pp++; ch2 = *pp; if (ch2 < 0x80 || ch2 > 0xBF) return 1; nch--; } } return 0; } /**************************************************************************/ // Find the Nth graphic character position within a UTF8 string // utf8in input UTF8 string // Nth graphic character position, zero based // returns starting character (byte) position of Nth graphic character int utf8_position(cchar *utf8in, int Nth) { int ii, posx; char xlimit = 0xC0; for (ii = posx = 0; posx < Nth && utf8in[ii]; ii++) { if (utf8in[ii] < 0) while (utf8in[ii+1] < xlimit) ii++; posx++; } return ii; } /************************************************************************** bitmap functions ***************************************************************************/ // create a new bitmap with specified bit length. // initially all bits are false. bitmap * bitmap_new(int nbits) { int cc, ii; bitmap *bm; bm = (bitmap *) zmalloc(sizeof(bitmap),"bitmap"); bm->nbits = nbits; cc = (nbits + 7) / 8; bm->bits = (uchar *) zmalloc(cc,"bitmap"); for (ii = 0; ii < cc; ii++) bm->bits[ii] = 0; return bm; } // set bit in bitmap to true or false void bitmap_set(bitmap *bm, int bit, bool value) { int ii, jj; uchar bit1; if (bit >= bm->nbits) zappcrash("bitmap, bit %d too big",bit); ii = bit / 8; jj = bit % 8; bit1 = 0x80 >> jj; if (value) bm->bits[ii] = bm->bits[ii] | bit1; else { bit1 = bit1 ^ 0xff; bm->bits[ii] = bm->bits[ii] & bit1; } return; } // fetch bitmap bit, return true or false bool bitmap_get(bitmap *bm, int bit) { int ii, jj; uchar bit1; ii = bit / 8; jj = bit % 8; bit1 = bm->bits[ii] << jj; if (bit1 < 127) return false; else return true; } // delete bitmap void bitmap_delete(bitmap *bm) { zfree(bm->bits); zfree(bm); return; } /************************************************************************** variable string list functions - array / list of strings ***************************************************************************/ // create new variable list with specified capacity pvlist * pvlist_create(int max) { pvlist *pv; pv = (pvlist *) zmalloc(sizeof(pvlist),"pvlist"); pv->max = max; pv->act = 0; pv->list = (char **) zmalloc(max * sizeof(char *),"pvlist"); return pv; } // free memory for variable list void pvlist_free(pvlist *pv) { int ii; for (ii = 0; ii < pv->act; ii++) zfree(pv->list[ii]); zfree(pv->list); zfree(pv); } // append new entry to end of list (optional if unique) // if list if full, first entry is removed and rest are packed down // return: N >= 0: new entry added at position N // N = -1: not unique, not added int pvlist_append(pvlist *pv, cchar *entry, int unique) { int ii; if (unique && pvlist_find(pv,entry) >= 0) return -1; // not unique if (pv->act == pv->max) pvlist_remove(pv,0); // if list full, remove 1st entry ii = pv->act; pv->list[ii] = strdupz(entry,0,"pvlist"); // add to end of list pv->act++; return ii; } // prepend new entry to list (optional if unique) // prior list entries are pushed down to make room // if list is full, last entry is removed first // return: N = 0: new entry added at position 0 // N = -1: not unique, not added int pvlist_prepend(pvlist *pv, cchar *entry, int unique) { int ii; if (unique && pvlist_find(pv,entry) >= 0) return -1; // not unique if (pv->act == pv->max) pvlist_remove(pv,pv->act-1); // if list full, remove last entry for (ii = pv->act; ii > 0; ii--) // push all list entries down pv->list[ii] = pv->list[ii-1]; pv->list[0] = strdupz(entry,0,"pvlist"); // add to start of list pv->act++; return 0; } // find list entry by name, return -1 if not found int pvlist_find(pvlist *pv, cchar *entry) { int ii; for (ii = 0; ii < pv->act; ii++) if (strEqu(entry,pv->list[ii])) break; if (ii < pv->act) return ii; return -1; } // remove an entry by name and repack list int pvlist_remove(pvlist *pv, cchar *entry) { int ii; ii = pvlist_find(pv,entry); if (ii < 0) return -1; pvlist_remove(pv,ii); return ii; } // remove an entry by number and repack list int pvlist_remove(pvlist *pv, int ii) { if (ii < 0 || ii >= pv->act) return -1; zfree(pv->list[ii]); for (ii++; ii < pv->act; ii++) { if (! pv->act) printf("meaningless reference %d",ii); // stop g++ optimization bug //// pv->list[ii-1] = pv->list[ii]; } pv->act--; return 0; } // return entry count int pvlist_count(pvlist *pv) { return pv->act; } // replace Nth entry with new one int pvlist_replace(pvlist * pv, int ii, cchar *entry) { if (ii < 0 || ii >= pv->act) return -1; zfree(pv->list[ii]); pv->list[ii] = strdupz(entry,0,"pvlist"); return 0; } // return Nth entry or null char * pvlist_get(pvlist *pv, int Nth) { if (Nth >= pv->act) return 0; return pv->list[Nth]; } // sort list in ascending order int pvlist_sort(pvlist *pv) { HeapSort(pv->list,pv->act); return 0; } /************************************************************************** Conversion Utilities convSI(string, inum, delim) string to int convSI(string, inum, low, high, delim) string to int with range check convSD(string, dnum, delim) string to double convSD(string, dnum, low, high, delim) string to double with range check convIS(inum, string, cc) int to string with returned cc convDS(fnum, digits, string, cc) double to string with specified digits of precision and returned cc string input (cchar *) or output (char *) inum input (int) or output (int &) dnum input (double) or output (double &) delim optional returned delimiter (null or cchar **) low, high input range check (int or double) cc output string length (int &) digits input digits of precision (int) to be used for output string NOTE: decimal point may be comma or period. 1000's separators must NOT be present. function status returned: 0 normal conversion, no invalid digits, blank/null termination 1 successful converstion, but trailing non-numeric found 2 conversion OK, but outside specified limits 3 null or blank string, converted to zero 4 conversion error, invalid data in string overlapping statuses have following precedence: 4 3 2 1 0 ***************************************************************************/ #define max10 (0x7fffffff / 10) // Convert string to integer int convSI(cchar *string, int &inum, cchar **delim) { char ch; int sign = 0, digits = 0, tnb = 0; cchar *pch = string; inum = 0; while ((ch = *pch) == ' ') pch++; // skip leading blanks if (ch == '-') sign = -1; // process leading +/- sign if (ch == '+') sign = 1; // (at most one sign character) if (sign) pch++; while ((*pch >= '0') && (*pch <= '9')) // process digits 0 - 9 { if (inum > max10) goto conv_err; // value too big inum = 10 * inum + *pch - '0'; digits++; pch++; } if (delim) *delim = pch; // terminating delimiter if (*pch && (*pch != ' ')) tnb++; // not null or blank if (! digits) // no digits found { if (tnb) return 4; // non-numeric (invalid) string else return 3; // null or blank string } if (sign == -1) inum = -inum; // negate if - sign if (! tnb) return 0; // no trailing non-numerics else return 1; // trailing non-numerics conv_err: inum = 0; return 4; } int convSI(cchar *string, int & inum, int lolim, int hilim, cchar **delim) { int stat = convSI(string,inum,delim); if (stat > 2) return stat; // invalid or null/blank if (inum < lolim) return 2; // return 2 if out of limits if (inum > hilim) return 2; // (has precedence over status 1) return stat; // limits OK, return 0 or 1 } // Convert string to double. int convSD(cchar *string, double &dnum, cchar **delim) { char ch; int ii, sign = 0, digits = 0, ndec = 0; int exp = 0, esign = 0, edigits = 0, tnb = 0; cchar *pch = string; static int first = 1; static double decimals[21], exponents[74]; if (first) // first-time called { first = 0; // pre-calculate constants for (ii = 1; ii <= 20; ii++) decimals[ii] = pow(10.0,-ii); for (ii = -36; ii <= 36; ii++) exponents[ii+37] = pow(10.0,ii); } dnum = 0.0; while ((ch = *pch) == ' ') pch++; // skip leading blanks if (ch == '-') sign = -1; // process leading +/- sign if (ch == '+') sign = 1; // (at most one sign character) if (sign) pch++; get_digits: while ((*pch >= '0') && (*pch <= '9')) // process digits 0 - 9 { dnum = 10.0 * dnum + (*pch - '0'); pch++; digits++; if (ndec) ndec++; } if ((*pch == '.') || (*pch == ',')) // process decimal point { // (allow comma or period) if (ndec) goto conv_err; ndec++; pch++; goto get_digits; } if ((*pch == 'e') || (*pch == 'E')) // process optional exponent { pch++; if (*pch == '+') esign = 1; // optional +/- sign if (*pch == '-') esign = -1; if (esign) pch++; if ((*pch < '0') || (*pch > '9')) goto conv_err; // 1st digit exp = *pch - '0'; edigits++; pch++; if ((*pch >= '0') && (*pch <= '9')) // optional 2nd digit { exp = 10 * exp + (*pch - '0'); edigits++; pch++; } if ((exp < -36) || (exp > 36)) goto conv_err; // exponent too big } if (delim) *delim = pch; // terminating delimiter if (*pch && (*pch != ' ')) tnb++; // not null or blank if (!(digits + edigits)) // no digits found { if (tnb) return 4; // non-numeric (invalid) string else return 3; // null or blank string } if (ndec > 1) dnum = dnum * decimals[ndec-1]; // compensate for decimal places if (sign == -1) dnum = - dnum; // negate if negative if (exp) { if (esign == -1) exp = -exp; // process exponent dnum = dnum * exponents[exp+37]; } if (! tnb) return 0; // no trailing non-numerics else return 1; // trailing non-numerics conv_err: dnum = 0.0; return 4; } int convSD(cchar *string, double &dnum, double lolim, double hilim, cchar **delim) { int stat = convSD(string,dnum,delim); if (stat > 2) return stat; // invalid or null/blank if (dnum < lolim) return 2; // return 2 if out of limits if (dnum > hilim) return 2; // (has precedence over status 1) return stat; // limits OK, return 0 or 1 } // Convert int to string with returned length. int convIS(int inum, char *string, int *cc) { int ccc; ccc = sprintf(string,"%d",inum); if (cc) *cc = ccc; return 0; } // Convert double to string with specified digits of precision. // Shortest length format (f/e) will be used. // Output length is returned in optional argument cc. int convDS(double dnum, int digits, char *string, int *cc) { char *pstr; sprintf(string,"%.*g",digits,dnum); pstr = strstr(string,"e+"); // 1.23e+12 > 1.23e12 if (pstr) strcpy(pstr+1,pstr+2); pstr = strstr(string,"e0"); // 1.23e02 > 1.23e2 if (pstr) strcpy(pstr+1,pstr+2); pstr = strstr(string,"e0"); if (pstr) strcpy(pstr+1,pstr+2); pstr = strstr(string,"e-0"); // 1.23e-02 > 1.23e-2 if (pstr) strcpy(pstr+2,pstr+3); pstr = strstr(string,"e-0"); if (pstr) strcpy(pstr+2,pstr+3); if (cc) *cc = strlen(string); return 0; } // format a number as "123 B" or "12.3 KB" or "1.23 MB" etc. // prec is the desired digits of precision to output. // WARNING: only the last 100 conversions remain available in memory. char * formatKBMB(double fnum, int prec) { #define kilo 1000 #define mega (kilo*kilo) #define giga (kilo*kilo*kilo) cchar *units; static char *output[100]; static int ftf = 1, ii; double gnum; if (ftf) { // keep last 100 conversions ftf = 0; // v.4.7 for (ii = 0; ii < 100; ii++) output[ii] = (char *) zmalloc(20); } gnum = fabs(fnum); if (gnum > giga) { fnum = fnum / giga; units = "GB"; } else if (gnum > mega) { fnum = fnum / mega; units = "MB"; } else if (gnum > kilo) { fnum = fnum / kilo; units = "KB"; } else units = "B "; gnum = fabs(fnum); if (prec == 2 && gnum >= 99.5) prec++; // avoid e+nn formats if (prec == 3 && gnum >= 999.5) prec++; if (prec == 4 && gnum >= 9999.5) prec++; if (prec == 5 && gnum >= 99999.5) prec++; if (prec == 6 && gnum >= 999999.5) prec++; if (++ii > 99) ii = 0; snprintf(output[ii],20,"%.*g %s",prec,fnum,units); return output[ii]; } /************************************************************************** Wildcard string match Match candidate string to wildcard string containing any number of '*' or '?' wildcard characters. '*' matches any number of characters, including zero characters. '?' matches any one character. Returns 0 if match, 1 if no match. ***/ int MatchWild(cchar *pWild, cchar *pString) { int ii, star; new_segment: star = 0; while (pWild[0] == '*') { star = 1; pWild++; } test_match: for (ii = 0; pWild[ii] && (pWild[ii] != '*'); ii++) { if (pWild[ii] != pString[ii]) { if (! pString[ii]) return 1; if (pWild[ii] == '?') continue; if (! star) return 1; pString++; goto test_match; } } if (pWild[ii] == '*') { pString += ii; pWild += ii; goto new_segment; } if (! pString[ii]) return 0; if (ii && pWild[ii-1] == '*') return 0; if (! star) return 1; pString++; goto test_match; } /************************************************************************** SearchWild - wildcard file search Find all files with total /pathname/filename matching a pattern, which may have any number of the wildcard characters '*' and '?' in either or both the pathname and filename. cchar * SearchWild(cchar *wfilespec, int &flag) inputs: flag = 1 to start a new search flag = 2 abort a running search *** do not modify flag within a search *** wfilespec = filespec to search with optional wildcards e.g. "/name1/na*me2/nam??e3/name4*.ext?" return: a pointer to one matching file is returned per call, or null when there are no more matching files. The search may be aborted before completion, but make a final call with flag = 2 to clean up temp file. A new search with flag = 1 will also finish the cleanup. NOT THREAD SAFE - do not use in parallel threads shell find command is used for the initial search because this is much faster than recursive use of readdir() (why?). (#) is used in place of (*) in comments below to prevent compiler from interpreting (#/) as end of comments GNU find peculiarities: find /path/# omits "." files find /path/ includes "." files find /path/# recurses directories under /path/ find /path/#.txt does not recurse directories find /path/#/ finds all files under /path/ find /path/#/# finds files >= 1 directory level under /path/ find /path/xxx# never finds anything SearchWild uses simpler and more intuitive matching: '/' and '.' are matched by '#' /path/#.txt finds all .txt files under /path/ at any directory level ***/ cchar * SearchWild(cchar *wpath, int &uflag) // use popen() instead of scratch file { static FILE *fid = 0; static char matchfile[maxfcc]; char searchpath[maxfcc]; char command[maxfcc]; int cc, err; char *pp; if ((uflag == 1) || (uflag == 2)) { // first call or stop flag if (fid) { pclose(fid); // if file open, close it fid = 0; } } if (uflag == 2) return 0; // kill flag, done if (uflag == 1) // first call flag { cc = strlen(wpath); if (cc == 0) return 0; if (cc > maxfcc-20) zappcrash("SearchWild: wpath > maxfcc"); pp = (char *) wpath; repl_Nstrs(pp,searchpath,"$","\\$","\"","\\\"",null); // init. search path, escape $ and " pp = strchr(searchpath,'*'); if (pp) { // not efficient but foolproof while ((*pp != '/') && (pp > searchpath)) pp--; // /aaa/bbb/cc*cc... >>> /aaa/bbb/ if (pp > searchpath) *(pp+1) = 0; } sprintf(command,"find \"%s\" -type f -or -type l",searchpath); // find files (ordinary, symlink) fid = popen(command,"r"); if (! fid) zappcrash(strerror(errno)); uflag = 763568954; // begin search } if (uflag != 763568954) zappcrash("SearchWild, uflag invalid"); while (true) { pp = fgets(matchfile,maxfcc-2,fid); // next matching file if (! pp) { pclose(fid); // no more fid = 0; return 0; } cc = strlen(matchfile); // get rid of trailing \n matchfile[cc-1] = 0; err = MatchWild(wpath,matchfile); // wildcard match? if (err) continue; // no return matchfile; // return file } } /**************************************************************************/ // perform a binary search on sorted list of integers // return matching element or -1 if not found int bsearch(int seekint, int nn, int list[]) { int ii, jj, kk, rkk; ii = nn / 2; // next element to search jj = (ii + 1) / 2; // next increment nn--; // last element rkk = 0; while (true) { kk = list[ii] - seekint; // check element if (kk > 0) { ii -= jj; // too high, go down if (ii < 0) return -1; } else if (kk < 0) { ii += jj; // too low, go up if (ii > nn) return -1; } else if (kk == 0) return ii; // matched jj = jj / 2; // reduce increment if (jj == 0) { jj = 1; // step by 1 element if (! rkk) rkk = kk; // save direction else { if (rkk > 0) { if (kk < 0) return -1; } // if change direction, fail else if (kk > 0) return -1; } } } } // perform a binary search on sorted set of records in memory // return matching record number (0 based) or -1 if not found int bsearch(char *seekrec, char *allrecs, int recl, int nrecs) { int ii, jj, kk, rkk; ii = nrecs / 2; // next element to search jj = (ii + 1) / 2; // next increment nrecs--; // last element rkk = 0; while (true) { kk = strcmp(allrecs+ii*recl,seekrec); // compare member rec to seek rec if (kk > 0) { ii -= jj; // too high, go down in set if (ii < 0) return -1; } else if (kk < 0) { ii += jj; // too low, go up in set if (ii > nrecs) return -1; } else if (kk == 0) return ii; // matched jj = jj / 2; // reduce increment if (jj == 0) { jj = 1; // step by 1 element if (! rkk) rkk = kk; // save direction else { if (rkk > 0) { if (kk < 0) return -1; } // if change direction, fail else if (kk > 0) return -1; } } } } /************************************************************************** heap sort functions ***************************************************************************/ #define SWAP(x,y) (temp = (x), (x) = (y), (y) = temp) // heapsort for array of integers static void adjust(int vv[], int n1, int n2) { int *bb, jj, kk, temp; bb = vv - 1; jj = n1; kk = n1 * 2; while (kk <= n2) { if (kk < n2 && bb[kk] < bb[kk+1]) kk++; if (bb[jj] < bb[kk]) SWAP(bb[jj],bb[kk]); jj = kk; kk *= 2; } } void HeapSort(int vv[], int nn) { int *bb, jj, temp; for (jj = nn/2; jj > 0; jj--) adjust(vv,jj,nn); bb = vv - 1; for (jj = nn-1; jj > 0; jj--) { SWAP(bb[1], bb[jj+1]); adjust(vv,1,jj); } } // heapsort for array of floats static void adjust(float vv[], int n1, int n2) { float *bb, temp; int jj, kk; bb = vv - 1; jj = n1; kk = n1 * 2; while (kk <= n2) { if (kk < n2 && bb[kk] < bb[kk+1]) kk++; if (bb[jj] < bb[kk]) SWAP(bb[jj],bb[kk]); jj = kk; kk *= 2; } } void HeapSort(float vv[], int nn) { float *bb, temp; int jj; for (jj = nn/2; jj > 0; jj--) adjust(vv,jj,nn); bb = vv - 1; for (jj = nn-1; jj > 0; jj--) { SWAP(bb[1], bb[jj+1]); adjust(vv,1,jj); } } // heapsort for array of doubles static void adjust(double vv[], int n1, int n2) { double *bb, temp; int jj, kk; bb = vv - 1; jj = n1; kk = n1 * 2; while (kk <= n2) { if (kk < n2 && bb[kk] < bb[kk+1]) kk++; if (bb[jj] < bb[kk]) SWAP(bb[jj],bb[kk]); jj = kk; kk *= 2; } } void HeapSort(double vv[], int nn) { double *bb, temp; int jj; for (jj = nn/2; jj > 0; jj--) adjust(vv,jj,nn); bb = vv - 1; for (jj = nn-1; jj > 0; jj--) { SWAP(bb[1], bb[jj+1]); adjust(vv,1,jj); } } // heapsort array of pointers to strings in ascending order of strings // pointers are sorted, strings are not changed. static void adjust(char *vv[], int n1, int n2) { char **bb, *temp; int jj, kk; bb = vv - 1; jj = n1; kk = n1 * 2; while (kk <= n2) { if (kk < n2 && strcmp(bb[kk],bb[kk+1]) < 0) kk++; if (strcmp(bb[jj],bb[kk]) < 0) SWAP(bb[jj],bb[kk]); jj = kk; kk *= 2; } } void HeapSort(char *vv[], int nn) { char **bb, *temp; int jj; for (jj = nn/2; jj > 0; jj--) adjust(vv,jj,nn); bb = vv; for (jj = nn-1; jj > 0; jj--) { SWAP(bb[0], bb[jj]); adjust(vv,1,jj); } } // heapsort array of pointers to strings in user-defined order. // pointers are sorted, strings are not changed. static void adjust(char *vv[], int n1, int n2, HeapSortUcomp fcomp) { char **bb, *temp; int jj, kk; bb = vv - 1; jj = n1; kk = n1 * 2; while (kk <= n2) { if (kk < n2 && fcomp(bb[kk],bb[kk+1]) < 0) kk++; if (fcomp(bb[jj],bb[kk]) < 0) SWAP(bb[jj],bb[kk]); jj = kk; kk *= 2; } } void HeapSort(char *vv[], int nn, HeapSortUcomp fcomp) { char **bb, *temp; int jj; for (jj = nn/2; jj > 0; jj--) adjust(vv,jj,nn,fcomp); bb = vv; for (jj = nn-1; jj > 0; jj--) { SWAP(bb[0], bb[jj]); adjust(vv,1,jj,fcomp); } } // heapsort for array of strings or records, // using caller-supplied record compare function. // HeapSortUcomp returns [ -1 0 +1 ] for rec1 [ < = > ] rec2 // method: build array of pointers and sort these, then // use this sorted array to re-order the records at the end. static int *vv1, *vv2; static void adjust(char *recs, int RL, int n1, int n2, HeapSortUcomp fcomp) { int *bb, jj, kk, temp; char *rec1, *rec2; bb = vv1 - 1; jj = n1; kk = n1 * 2; while (kk <= n2) { rec1 = recs + RL * bb[kk]; rec2 = recs + RL * bb[kk+1]; if (kk < n2 && fcomp(rec1,rec2) < 0) kk++; rec1 = recs + RL * bb[jj]; rec2 = recs + RL * bb[kk]; if (fcomp(rec1,rec2) < 0) SWAP(bb[jj],bb[kk]); jj = kk; kk *= 2; } } void HeapSort(char *recs, int RL, int NR, HeapSortUcomp fcomp) { int *bb, jj, kk, temp, flag; char *vvrec; vv1 = new int[NR]; for (jj = 0; jj < NR; jj++) vv1[jj] = jj; for (jj = NR/2; jj > 0; jj--) adjust(recs,RL,jj,NR,fcomp); bb = vv1 - 1; for (jj = NR-1; jj > 0; jj--) { SWAP(bb[1], bb[jj+1]); adjust(recs,RL,1,jj,fcomp); } vv2 = new int[NR]; for (jj = 0; jj < NR; jj++) vv2[vv1[jj]] = jj; vvrec = new char[RL]; flag = 1; while (flag) { flag = 0; for (jj = 0; jj < NR; jj++) { kk = vv2[jj]; if (kk == jj) continue; memmove(vvrec,recs+jj*RL,RL); memmove(recs+jj*RL,recs+kk*RL,RL); memmove(recs+kk*RL,vvrec,RL); SWAP(vv2[jj],vv2[kk]); flag = 1; } } delete vv1; delete vv2; delete vvrec; } /************************************************************************** int MemSort (char *RECS, int RL, int NR, int KEYS[][3], int NK) RECS is an array of records, to be sorted in-place. (record length = RL, record count = NR) KEYS[NK,3] is an integer array defined as follows: [N,0] starting position of Nth key field in RECS [N,1] length of Nth key field in RECS [N,2] type of sort for Nth key: 1 = char ascending 2 = char descending 3 = int*4 ascending (int, long) 4 = int*4 descending 5 = float*4 ascending (float) 6 = float*4 descending 7 = float*8 ascending (double) 8 = float*8 descending ***/ int MemSortComp(cchar *rec1, cchar *rec2); int MemSortKeys[10][3], MemSortNK; int MemSort(char *RECS, int RL, int NR, int KEYS[][3], int NK) { int ii; if (NR < 2) return 1; if (NK > 10) zappcrash("MemSort, bad NK"); if (NK < 1) zappcrash("MemSort, bad NK"); MemSortNK = NK; for (ii = 0; ii < NK; ii++) { MemSortKeys[ii][0] = KEYS[ii][0]; MemSortKeys[ii][1] = KEYS[ii][1]; MemSortKeys[ii][2] = KEYS[ii][2]; } HeapSort(RECS,RL,NR,MemSortComp); return 1; } int MemSortComp(cchar *rec1, cchar *rec2) { int ii, stat, kpos, ktype, kleng; int inum1, inum2; float rnum1, rnum2; double dnum1, dnum2; cchar *p1, *p2; for (ii = 0; ii < MemSortNK; ii++) // loop each key { kpos = MemSortKeys[ii][0]; // relative position kleng = MemSortKeys[ii][1]; // length ktype = MemSortKeys[ii][2]; // type p1 = rec1 + kpos; // absolute position p2 = rec2 + kpos; switch (ktype) { case 1: // char ascending stat = strncmp(p1,p2,kleng); // compare 2 key values if (stat) return stat; // + if rec1 > rec2, - if < break; // 2 keys are equal, check next key case 2: // char descending stat = strncmp(p1,p2,kleng); if (stat) return -stat; break; case 3: // int ascending memmove(&inum1,p1,4); memmove(&inum2,p2,4); if (inum1 > inum2) return 1; if (inum1 < inum2) return -1; break; case 4: // int descending memmove(&inum1,p1,4); memmove(&inum2,p2,4); if (inum1 > inum2) return -1; if (inum1 < inum2) return 1; break; case 5: // float ascending memmove(&rnum1,p1,4); memmove(&rnum2,p2,4); if (rnum1 > rnum2) return 1; if (rnum1 < rnum2) return -1; break; case 6: // float descending memmove(&rnum1,p1,4); memmove(&rnum2,p2,4); if (rnum1 > rnum2) return -1; if (rnum1 < rnum2) return 1; break; case 7: // double ascending memmove(&dnum1,p1,8); memmove(&dnum2,p2,8); if (dnum1 > dnum2) return 1; if (dnum1 < dnum2) return -1; break; case 8: // double descending memmove(&dnum1,p1,8); memmove(&dnum2,p2,8); if (dnum1 > dnum2) return -1; if (dnum1 < dnum2) return 1; break; default: // key type not 1-8 zappcrash("MemSort, bad KEYS sort type"); } } return 0; // records match on all keys } /**************************************************************************/ // random number generators with explicit context // and improved randomness over a small series int lrandz(int64 *seed) // returns 0 to 0x7fffffff { *seed = *seed ^ (*seed << 17); *seed = *seed ^ (*seed << 20); return nrand48((unsigned int16 *) seed); } int lrandz() { static int64 seed = 12345678; return lrandz(&seed); } double drandz(int64 *seed) // returns 0.0 to 0.99999... { *seed = *seed ^ (*seed << 17); *seed = *seed ^ (*seed << 20); return erand48((unsigned int16 *) seed); } double drandz() { static int64 seed = 23459876; return drandz(&seed); } /************************************************************************** spline1: define a curve using a set of data points (x and y values) spline2: for a given x-value, return a y-value fitting the curve For spline1, the no. of curve-defining points must be < 100. For spline2, the given x-value must be within the range defined in spline1. ***/ namespace splinedata { int nn; double px1[100], py1[100], py2[100]; } void spline1(int dnn, double *dx1, double *dy1) { using namespace splinedata; double sig, p, u[100]; int ii; nn = dnn; if (nn > 100) zappcrash("spline1(), > 100 data points"); for (ii = 0; ii < nn; ii++) { px1[ii] = dx1[ii]; py1[ii] = dy1[ii]; if (ii && px1[ii] <= px1[ii-1]) zappcrash("spline1(), x-value not increasing"); } py2[0] = u[0] = 0; for (ii = 1; ii < nn-1; ii++) { sig = (px1[ii] - px1[ii-1]) / (px1[ii+1] - px1[ii-1]); p = sig * py2[ii-1] + 2; py2[ii] = (sig - 1) / p; u[ii] = (6 * ((py1[ii+1] - py1[ii]) / (px1[ii+1] - px1[ii]) - (py1[ii] - py1[ii-1]) / (px1[ii] - px1[ii-1])) / (px1[ii+1] - px1[ii-1]) - sig * u[ii-1]) / p; } py2[nn-1] = 0; for (ii = nn-2; ii >= 0; ii--) py2[ii] = py2[ii] * py2[ii+1] + u[ii]; return; } double spline2(double x) { using namespace splinedata; int kk, klo = 0, khi = nn-1; double h, a, b, y; while (khi - klo > 1) { kk = (khi + klo) / 2; if (px1[kk] > x) khi = kk; else klo = kk; } h = px1[khi] - px1[klo]; a = (px1[khi] - x) / h; b = (x - px1[klo]) / h; y = a * py1[klo] + b * py1[khi] + ((a*a*a - a) * py2[klo] + (b*b*b - b) * py2[khi]) * (h*h) / 6; return y; } /************************************************************************** Initialize application files according to following conventions: // new version v.4.1 + binary executable is at: /prefix/bin/appname // = PREFIX/bin/appname + other application directories are derived as follows: /prefix/share/appname/data/ desktop, parameters, etc. /prefix/share/doc/appname/ README, CHANGES, user guide /prefix/share/appname/icons/ icon files .png /prefix/share/appname/locales/ translations: appname-de.po etc. /home/user/.appname/ parameters etc. are copied here zprefix install location has /bin and /share subtrees zdatadir installed data files .desktop, parameters, etc. zdocdir user documentation README, changelog, user guide zicondir icons icon files .png zlocalesdir translation files appname-de.po, etc. zuserdir /home/user/.appname log file, user parameters ***/ namespace zfuncs { char zappname[20]; char zprefix[200], zdatadir[200], zdocdir[200]; // app directories char zicondir[200], zlocalesdir[200], zuserdir[200]; char zlang[8] = "en"; // "lc" or "lc_RC" char JPGquality[4] = "85"; // JPG file save quality cchar *F1_help_topic = 0; // current F1 help topic int open_popup_windows = 0; // open popup window count pthread_t tid_main = 0; // main thread ID v.4.8 } cchar * get_zprefix() { return zfuncs::zprefix; } // /usr or /home/ cchar * get_zuserdir() { return zfuncs::zuserdir; } // /home/user/.appname cchar * get_zdatadir() { return zfuncs::zdatadir; } // parameters, icons cchar * get_zdocdir() { return zfuncs::zdocdir; } // documentation files cchar * get_zicondir() { return zfuncs::zicondir; } // icon files cchar * get_zlocalesdir() { return zfuncs::zlocalesdir; } // translation files int zinitapp(cchar *appname, ...) { using namespace zfuncs; char work[200]; char logfile[200], oldlog[200]; cchar *appfile; int secs, err; time_t Tnow; char *chTnow; struct stat statdat; va_list arglist; FILE *fid; catch_signals(); // catch segfault, do backtrace strcpy(zappname,appname); // save app name #ifndef PREFIX // install location v.4.7 #define PREFIX "/usr" #endif strncpy0(work,PREFIX,199); // /usr or /home/ v.4.6 strcpy(zprefix,work); // /prefix strncatv(zdatadir,199,work,"/share/",zappname,"/data",null); // /prefix/share/appname/data strncatv(zicondir,199,work,"/share/",zappname,"/icons",null); // /prefix/share/appname/icons strncatv(zlocalesdir,199,work,"/share/",zappname,"/locales",null); // /prefix/share/appname/locales strncatv(zdocdir,199,work,"/share/doc/",zappname,null); // /prefix/share/doc/appname snprintf(zuserdir,199,"%s/.%s",getenv("HOME"),zappname); // /home/user/.appname/ v.4.3 err = stat(zuserdir,&statdat); // does it exist already? if (err) { err = mkdir(zuserdir,0750); // no, create and initialize if (err) zappcrash("cannot create %s",zuserdir); va_start(arglist,appname); // copy req. application files while (true) { // from install directory to appfile = va_arg(arglist, cchar *); // to /home/user/.appname/ if (! appfile) break; snprintf(work,199,"cp %s/%s %s",zdatadir,appfile,zuserdir); err = system(work); if (err) printf("%s %s \n",work,wstrerror(err)); // v.4.0 do not crash } va_end(arglist); } tid_main = pthread_self(); // v.4.8 Tnow = time(0); chTnow = ctime(&Tnow); chTnow[19] = 0; if (! isatty(1)) { // not attached to a terminal v.4.1 snprintf(logfile,199,"%s/%s.log",zuserdir,zappname); snprintf(oldlog,199,"%s/%s.log.old",zuserdir,zappname); err = stat(logfile,&statdat); if (! err) { secs = Tnow - statdat.st_mtime; // if log file age > 1 hour v.5.0 if (secs > 3600) rename(logfile,oldlog); // rename to *.old } fid = freopen(logfile,"a",stdout); // redirect output to log file fid = freopen(logfile,"a",stderr); // /home/user/.appname/appname.log if (! fid) printf("cannot redirect stdout and stderr \n"); } printf("=========== %s %s \n",zappname,chTnow); return 1; } /**************************************************************************/ // Display help file in a separate process so application is not blocked. // help file: /zdocdir/userguide-lc_RC.html (or) *-lc.html (or) *-en.html // context: optional arg. show file starting at internal link = context // look for user guide file in /usr/share/doc/appname/ // and in /usr/share/doc/appname/extras/ // distros are different v.4.7 void showz_userguide(cchar *context) { using namespace zfuncs; int err; char docfile[200], url[200], lang[4]; snprintf(docfile,199,"%s/userguide-%s.html",zdocdir,zlang); // look for userguide-lc_RC.html err = access(docfile,R_OK); if (! err) goto add_context; snprintf(docfile,199,"%s/extras/userguide-%s.html",zdocdir,zlang); err = access(docfile,R_OK); if (! err) goto add_context; strncpy0(lang,zlang,3); snprintf(docfile,199,"%s/userguide-%s.html",zdocdir,lang); // look for userguide-lc.html err = access(docfile,R_OK); if (! err) goto add_context; snprintf(docfile,199,"%s/extras/userguide-%s.html",zdocdir,lang); err = access(docfile,R_OK); if (! err) goto add_context; snprintf(docfile,199,"%s/userguide-en.html",zdocdir); // look for userguide-en.html err = access(docfile,R_OK); if (! err) goto add_context; snprintf(docfile,199,"%s/extras/userguide-en.html",zdocdir); err = access(docfile,R_OK); if (! err) goto add_context; zmessageACK(null,ZTX("help file not found: %s"),docfile); // give up return; add_context: if (context && *context) strncatv(docfile,199,"#",context,null); // file://.../userguide-xx.html#context snprintf(url,199,"file://%s",docfile); showz_html(url); return; } /**************************************************************************/ // display various admin text files in a popup window // v.4.2 void showz_readme() { showz_doctext("README"); return; } void showz_changelog() { showz_doctext("changelog"); // renamed v.4.7 return; } void showz_translations() { showz_doctext("translations"); // renamed v.4.7 return; } // find and show a text in a popup window // the text file may also be a compressed .gz file // look for: /usr/share/doc/appname/file.gz // v.4.7 // /usr/share/doc/appname/file // distros do it differently // /usr/share/doc/appname/extras/file.gz // /usr/share/doc/appname/extras/file void showz_doctext(const char *file) // v.4.2 { using namespace zfuncs; struct stat statb; char buff1[200], buff2[220]; cchar *command; int err; command = "zcat"; snprintf(buff1,199,"%s/%s.gz",zdocdir,file); // look for .../appname/file.gz err = stat(buff1,&statb); if (! err) goto showit; command = "cat"; snprintf(buff1,199,"%s/%s",zdocdir,file); // look for .../appname/file err = stat(buff1,&statb); if (! err) goto showit; command = "zcat"; snprintf(buff1,199,"%s/extras/%s.gz",zdocdir,file); // look for .../appname/extras/file.gz err = stat(buff1,&statb); if (! err) goto showit; command = "cat"; snprintf(buff1,199,"%s/extras/%s",zdocdir,file); // look for .../appname/extras/file err = stat(buff1,&statb); if (! err) goto showit; command = "echo file not found:"; snprintf(buff1,199,"%s/%s",zdocdir,file); showit: snprintf(buff2,219,"%s %s",command,buff1); popup_command(buff2,600,400); return; } /**************************************************************************/ // create a desktop icon / launcher with icon // v.4.5 // target system needs to be LSB compliant void zmake_menu_launcher(cchar *command, cchar *categories, cchar *genericname) { using namespace zfuncs; char appname[20], dtfile[200], work[200]; cchar *pp; FILE *fid; int err; pp = strField(command,' ',1); if (! pp) pp = "?"; strncpy0(appname,pp,20); snprintf(dtfile,199,"%s/Desktop/kornelix-%s.desktop",getenv("HOME"),appname); fid = fopen(dtfile,"w"); if (! fid) { zmessageACK(null,ZTX("error: %s"),strerror(errno)); return; } fputs("[Desktop Entry]\n",fid); // [Desktop Entry] snprintf(work,199,"Name=%s\n",appname); // Name=appname fputs(work,fid); snprintf(work,199,"Categories=%s\n",categories); // Categories=Cat1;Cat2; ... fputs(work,fid); snprintf(work,199,"GenericName=%s\n",genericname); // GenericName=generic app name fputs(work,fid); fputs("Type=Application\n",fid); // Type=Application fputs("Terminal=false\n",fid); // Terminal=false snprintf(work,199,"Exec=%s/bin/%s\n",zprefix,command); // Exec=/usr/bin/appname -options fputs(work,fid); snprintf(work,199,"Icon=%s/%s.png\n",zicondir,appname); // Icon=/usr/share/appname/icons/appname.png fputs(work,fid); fclose(fid); snprintf(work,199,"chmod 0750 %s",dtfile); // make executable err = system(work); if (err) zmessLogACK(null,"error: %s",wstrerror(err)); snprintf(work,199,"xdg-desktop-menu install %s",dtfile); // add menu entry err = system(work); if (err) zmessLogACK(null,"error: %s",wstrerror(err)); return; } // show a local or remote html file using the user's preferred browser // to show a local file starting at an internal live link location: // url = "file://directory/.../filename#livelink void showz_html(cchar *url) { char command[500]; static char prog[20]; static int ftf = 1, err; if (ftf) { ftf = 0; strcpy(prog,"xdg-open"); err = system("xdg-open --version"); if (err) { strcpy(prog,"firefox"); err = system("firefox -v"); if (err) *prog = 0; } } if (! *prog) { zmessLogACK(null,"no xdg-open or firefox, cannot show document"); return; } snprintf(command,499,"%s %s &",prog,url); printf(" %s \n",command); // v.4.1 err = system(command); return; } /************************************************************************** GTK utility functions **************************************************************************/ // Iterate main loop every "skip" calls void zmainloop(int skip) { static int xskip = 0; if (skip) { if (++xskip < skip) return; xskip = 0; } if (! pthread_equal(pthread_self(),zfuncs::tid_main)) return; // thread caller, do nothing v.5.0 gdk_flush(); // v.5.0 while (gtk_events_pending()) gtk_main_iteration(); // main() caller OK return; } /**************************************************************************/ // crash if current execution is not the main() thread void zthreadcrash() { if (pthread_equal(pthread_self(),zfuncs::tid_main)) return; // v.4.8 zappcrash("forbidden function called from thread"); return; } /**************************************************************************/ // write message to text view window // line: +N existing lines from top (replace) // -N existing lines from bottom (replace) // 0 next line (add new line at bottom) // scroll logic assumes only one \n per message void wprintx(GtkWidget *mLog, int line, cchar *message, cchar *font) { GtkTextMark *endMark; GtkTextBuffer *textBuff; GtkTextIter iter1, iter2; GtkTextTag *fontag = 0; int nlines, scroll = 0; if (! mLog) { // if no GUI use STDOUT printf("%s",message); return; } zthreadcrash(); textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mLog)); endMark = gtk_text_buffer_get_mark(textBuff,"wpxend"); // get my end mark if (! endMark) { gtk_text_buffer_get_end_iter(textBuff,&iter1); // new buffer, set my end mark endMark = gtk_text_buffer_create_mark(textBuff,"wpxend",&iter1,0); } nlines = gtk_text_buffer_get_line_count(textBuff); // lines now in buffer if (line == 0) scroll++; // auto scroll is on if (line < 0) { line = nlines + line + 1; // last lines: -1, -2 ... if (line < 1) line = 1; // above top, use line 1 } if (line > nlines) line = 0; // below bottom, treat as append if (line == 0) gtk_text_buffer_get_end_iter(textBuff,&iter1); // append new line if (line > 0) { gtk_text_buffer_get_iter_at_line(textBuff,&iter1,line-1); // old line start if (line < nlines) gtk_text_buffer_get_iter_at_line(textBuff,&iter2,line); // old line end if (line == nlines) // or buffer end gtk_text_buffer_get_end_iter(textBuff,&iter2); gtk_text_buffer_delete(textBuff,&iter1,&iter2); // delete old line } if (font) { // insert new line with caller font fontag = gtk_text_buffer_create_tag(textBuff,0,"font",font,0); // fontag is textBuff specific gtk_text_buffer_insert_with_tags(textBuff,&iter1,message,-1,fontag,null); } else // insert new line with default font gtk_text_buffer_insert(textBuff,&iter1,message,-1); if (scroll) // scroll line into view gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(mLog),endMark,0,0,1,1); zmainloop(); // v.4.8 return; } void wprintf(GtkWidget *mLog, int line, cchar *mess, ... ) // "printf" version { va_list arglist; char message[1000]; va_start(arglist,mess); vsnprintf(message,999,mess,arglist); va_end(arglist); wprintx(mLog,line,message); return; } void wprintf(GtkWidget *mLog, cchar *mess, ... ) // "printf", scrolling output { va_list arglist; char message[1000]; va_start(arglist,mess); vsnprintf(message,999,mess,arglist); // stop overflow, remove warning va_end(arglist); wprintx(mLog,0,message); return; } /**************************************************************************/ // scroll a text view window to put a given line on screen // 1st line = 1. for last line use line = 0. void wscroll(GtkWidget *mLog, int line) { GtkTextBuffer *textbuff; GtkTextIter iter; GtkTextMark *mark; if (! mLog) return; textbuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mLog)); if (line <= 0) line = gtk_text_buffer_get_line_count(textbuff); line = line - 1; gtk_text_buffer_get_iter_at_line(textbuff,&iter,line); mark = gtk_text_buffer_create_mark(textbuff,0,&iter,0); // bugfix, gtk_text_view_scroll_to_iter() gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(mLog),mark,0,0,1,1); // fails with no error v.4.0 return; } /**************************************************************************/ // clear a text view window and get a new buffer (a kind of defrag) void wclear(GtkWidget *mLog) { GtkTextBuffer *buff; if (! mLog) return; buff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mLog)); gtk_text_buffer_set_text(buff,"",-1); return; } // clear a text view window from designated line to end of buffer void wclear(GtkWidget *mLog, int line) { GtkTextBuffer *textBuff; GtkTextIter iter1, iter2; if (! mLog) return; textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mLog)); gtk_text_buffer_get_iter_at_line(textBuff,&iter1,line-1); // iter at line start gtk_text_buffer_get_end_iter(textBuff,&iter2); gtk_text_buffer_delete(textBuff,&iter1,&iter2); // delete existing line return; } /**************************************************************************/ // get text records from a text view window, one per call // removes trailing new line characters ( \n ) char * wscanf(GtkWidget *mLog, int & ftf) { GtkTextBuffer *textBuff; GtkTextIter iter1, iter2; static char *precs = 0, *prec1, *pret; static int cc; if (! mLog) return 0; if (ftf) { // get all window text ftf = 0; if (precs) g_free(precs); // free prior memory if there textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mLog)); // get all text gtk_text_buffer_get_bounds(textBuff,&iter1,&iter2); precs = gtk_text_buffer_get_text(textBuff,&iter1,&iter2,0); prec1 = precs; // 1st record } if (! precs || (*prec1 == 0)) // no more records { if (precs) g_free(precs); precs = 0; return 0; } cc = 0; while ((prec1[cc] != 0) && (prec1[cc] != '\n')) cc++; // scan for terminator pret = prec1; prec1 = prec1 + cc; // next record if (*prec1 == '\n') prec1++; pret[cc] = 0; // replace \n with 0 return pret; } /**************************************************************************/ // dump text window into file // return: 0: OK +N: error int wfiledump_maxcc = 0; int wfiledump(GtkWidget *mLog, char *filespec) { FILE *fid; char *prec; int ftf, err, cc; if (! mLog) return 0; fid = fopen(filespec,"w"); // open file if (! fid) { zmessageACK(null,ZTX("cannot open file %s"),filespec); return 1; } wfiledump_maxcc = 0; ftf = 1; while (true) { prec = wscanf(mLog,ftf); // get text line if (! prec) break; fprintf(fid,"%s\n",prec); // output with \n cc = strlen(prec); if (cc > wfiledump_maxcc) wfiledump_maxcc = cc; } err = fclose(fid); // close file if (err) { zmessageACK(null,"file close error"); return 2; } else return 0; } /**************************************************************************/ // save text window to file, via file chooser dialog void wfilesave(GtkWidget *mLog) { int err; char *file; if (! mLog) return; file = zgetfile1(ZTX("save screen to file"),"save","screen-save.txt"); if (! file) return; err = wfiledump(mLog,file); if (err) zmessageACK(null,"save screen failed (%d)",err); zfree(file); return; } /**************************************************************************/ // print text window to default printer // use landscape mode if max. print line > A4 width void wprintp(GtkWidget *mLog) { int pid, err; char tempfile[50], command[200]; if (! mLog) return; pid = getpid(); snprintf(tempfile,49,"/tmp/wprintp-%d",pid); err = wfiledump(mLog,tempfile); if (err) return; if (wfiledump_maxcc < 97) snprintf(command,199,"lp -o %s -o %s -o %s -o %s -o %s -o %s %s", "cpi=14","lpi=8","page-left=50","page-top=50", "page-right=40","page-bottom=40",tempfile); else snprintf(command,199,"lp -o %s -o %s -o %s -o %s -o %s -o %s -o %s %s", "landscape","cpi=14","lpi=8","page-left=50","page-top=50", "page-right=40","page-bottom=40",tempfile); err = system(command); if (err) zmessLogACK(null,"print error %s",wstrerror(err)); return; } /************************************************************************** simplified GTK menu bar, tool bar, status bar functions ***************************************************************************/ int tbIconSize = 24; // valid during toolbar construction GtkTooltips *tbTooltips = 0; // one instance for all toolbars // create menu bar and add to vertical packing box GtkWidget * create_menubar(GtkWidget *vbox) // icon size removed { GtkWidget *wmbar; wmbar = gtk_menu_bar_new(); gtk_box_pack_start(GTK_BOX(vbox),wmbar,0,0,0); return wmbar; } // add menu item to menu bar GtkWidget * add_menubar_item(GtkWidget *wmbar, cchar *mname, mtFunc func) { GtkWidget *wmitem; wmitem = gtk_menu_item_new_with_label(mname); gtk_menu_shell_append(GTK_MENU_SHELL(wmbar),wmitem); if (func) G_SIGNAL(wmitem,"activate",func,mname); return wmitem; } // create a popup menu // v.4.7 GtkWidget * create_popmenu() { GtkWidget *popmenu; popmenu = gtk_menu_new(); return popmenu; } // add a menu item to a popup menu // v.4.7 GtkWidget * add_popmenu_item(GtkWidget *popmenu, cchar *mname, mtFunc func) { GtkWidget *wmitem; wmitem = gtk_menu_item_new_with_label(mname); gtk_menu_shell_append(GTK_MENU_SHELL(popmenu),wmitem); if (func) G_SIGNAL(wmitem,"activate",func,mname); return wmitem; } // pop-up the menu at current mouse position // v.4.7 void popup_menu(GtkWidget *popmenu) { gtk_menu_popup(GTK_MENU(popmenu),0,0,0,0,0,gtk_get_current_event_time()); gtk_widget_show_all(popmenu); return; } // add submenu item to menu item, optional response function GtkWidget * add_submenu_item(GtkWidget *wmitem, cchar *mlab, mtFunc func) { GtkWidget *wmsub, *wmsubitem; GtkWidget *wicon = 0; wmsub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(wmitem)); if (wmsub == null) { wmsub = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(wmitem),wmsub); } if (strEqu(mlab,"separator")) wmsubitem = gtk_separator_menu_item_new(); else { if (wicon) { wmsubitem = gtk_image_menu_item_new_with_label(mlab); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(wmsubitem),wicon); } else wmsubitem = gtk_menu_item_new_with_label(mlab); } gtk_menu_shell_append(GTK_MENU_SHELL(wmsub),wmsubitem); if (func) G_SIGNAL(wmsubitem,"activate",func,mlab); return wmsubitem; } // create toolbar and add to vertical packing box GtkWidget * create_toolbar(GtkWidget *vbox, int iconsize, int vert) { using namespace zfuncs; GtkWidget *wtbar; wtbar = gtk_toolbar_new(); if (vert) gtk_toolbar_set_orientation(GTK_TOOLBAR(wtbar),GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(vbox),wtbar,0,0,0); tbIconSize = iconsize; if (! tbTooltips) tbTooltips = gtk_tooltips_new(); return wtbar; } // add toolbar button with stock icon ("gtk-quit") or custom icon ("iconfile.png") GtkWidget * add_toolbar_button(GtkWidget *wtbar, cchar *blab, cchar *btip, cchar *icon, mtFunc func) { using namespace zfuncs; GtkToolItem *tbutton; GError *gerror = 0; GdkPixbuf *pixbuf; GtkWidget *wicon = 0; char iconpath[200]; if (blab && strEqu(blab,"separator")) { // v.4.3 tbutton = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(wtbar),GTK_TOOL_ITEM(tbutton),-1); return (GtkWidget *) tbutton; } if (icon == null || *icon == 0) tbutton = gtk_tool_button_new(0,0); else if (strnEqu(icon,"gtk-",4)) tbutton = gtk_tool_button_new_from_stock(icon); else { *iconpath = 0; strncatv(iconpath,199,zicondir,"/",icon,null); pixbuf = gdk_pixbuf_new_from_file_at_scale(iconpath,tbIconSize,tbIconSize,1,&gerror); if (pixbuf) wicon = gtk_image_new_from_pixbuf(pixbuf); if (wicon) tbutton = gtk_tool_button_new(wicon,0); else tbutton = gtk_tool_button_new_from_stock("gtk-missing-image"); } if (blab) gtk_tool_button_set_label(GTK_TOOL_BUTTON(tbutton),blab); if (btip) gtk_tool_item_set_tooltip(tbutton,tbTooltips,btip,""); gtk_tool_item_set_homogeneous(tbutton,0); gtk_toolbar_insert(GTK_TOOLBAR(wtbar),GTK_TOOL_ITEM(tbutton),-1); if (func) G_SIGNAL(tbutton,"clicked",func,blab); return (GtkWidget *) tbutton; } // create a status bar and add to the start of a packing box GtkWidget * create_stbar(GtkWidget *pbox) { GtkWidget *stbar; static PangoFontDescription *fontdesc; stbar = gtk_statusbar_new(); fontdesc = pango_font_description_from_string("Monospace 9"); gtk_widget_modify_font(stbar,fontdesc); // *** GTK does not work *** gtk_box_pack_start(GTK_BOX(pbox),stbar,0,0,0); gtk_widget_show(stbar); return stbar; } // display message in status bar int stbar_message(GtkWidget *wstbar, cchar *message) { static int ctx = -1; if (ctx == -1) ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(wstbar),"all"); gtk_statusbar_pop(GTK_STATUSBAR(wstbar),ctx); gtk_statusbar_push(GTK_STATUSBAR(wstbar),ctx,message); return 0; } /************************************************************************** simplified GTK dialog functions ***************************************************************************/ // counter, keeps track of open or pending zdialogs namespace zfuncs { int zdialog_busy; } // private functions for widget events and dialog completion int zdialog_widget_event(GtkWidget *, zdialog *zd); int zdialog_response_event(GtkWidget *, int zstat, zdialog *zd); // create a new zdialog dialog // optional arguments: up to zdmaxbutts button labels followed by null // returned dialog status: +N = button N (1 to zdmaxbutts) // <0 = [x] button or other GTK destroy action // v.3.5 overhaul: // build own completion buttons, replacing the fat GTK standard buttons // completion buttons are also events like other widgets // get rid of separate dialog completion function // all dialogs run parallel, use zdialog_wait() if needed zdialog * zdialog_new(cchar *title, GtkWidget *parent, ...) // parent added { zdialog *zd; GtkWidget *dialog, *hbox, *butt, *hsep; cchar *bulab[zdmaxbutts]; int cc, ii, nbu; va_list arglist; va_start(arglist,parent); for (nbu = 0; nbu < zdmaxbutts; nbu++) // get completion buttons { bulab[nbu] = va_arg(arglist, cchar *); if (! bulab[nbu]) break; } va_end(arglist); if (! title) title = " "; // v.5.0 dialog = gtk_dialog_new(); // attributes optional gtk_window_set_title(GTK_WINDOW(dialog),title); gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox),2); gtk_dialog_set_has_separator(GTK_DIALOG(dialog),0); cc = sizeof(zdialog); // allocate zdialog zd = (zdialog *) zmalloc(cc,"zdialog"); if (parent) { // v.4.4 zd->parent = parent; gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent)); } if (nbu) { // there are some completion buttons hbox = gtk_hbox_new(0,0); gtk_box_pack_end(GTK_BOX(GTK_DIALOG(dialog)->vbox),hbox,0,0,0); // add hbox for buttons at dialog bottom hsep = gtk_hseparator_new(); // add separator line gtk_box_pack_end(GTK_BOX(GTK_DIALOG(dialog)->vbox),hsep,0,0,5); for (ii = nbu-1; ii >= 0; ii--) { // add buttons to hbox butt = gtk_button_new_with_label(bulab[ii]); // reverse order nbu-1...0 gtk_box_pack_end(GTK_BOX(hbox),butt,0,0,5); G_SIGNAL(butt,"clicked",zdialog_widget_event,zd); // connect to event function zd->compbutt[ii] = butt; // save button widgets } } zd->sentinel = zdsentinel; // validity sentinel zd->eventCB = 0; // no user event callback function zd->zstat = 0; // no zdialog status zd->disabled = 1; // widget signals disabled zd->saveposn = 0; // position not saved v.4.4 zd->help_topic = 0; // no help topic v.4.5 zd->widget[0].type = "dialog"; // set up 1st widget = dialog zd->widget[0].name = "dialog"; zd->widget[0].pname = 0; zd->widget[0].data = strdupz(title,0,"zdialog"); zd->widget[0].cblist = 0; zd->widget[0].widget = dialog; zd->widget[1].type = 0; // eof - no contained widgets yet return zd; } // add widget to existing zdialog int zdialog_add_widget ( zdialog *zd, cchar *type, cchar *name, cchar *pname, // mandatory args cchar *data, int scc, int homog, int expand, int space, int wrap) // optional args (default = 0) { GtkWidget *widget = 0, *pwidget = 0; GtkTextBuffer *editBuff = 0; GdkColor gdkcolor; cchar *pp, *ptype = 0; char vdata[30]; double min, max, step, val; int iiw, iip, kk, err; static PangoFontDescription *monofont = 0; if (! zd) zappcrash("zdialog null pointer"); // detect destroyed dialog if (zd->sentinel != zdsentinel) zappcrash("zdialog invalid"); for (iiw = 1; zd->widget[iiw].type; iiw++); // find next avail. slot if (iiw > zdmaxwidgets-2) zappcrash("too many widgets: %d",iiw); zd->widget[iiw].type = strdupz(type,0,"zdialog"); // initz. widget struct zd->widget[iiw].name = strdupz(name,0,"zdialog"); // all strings in nonvolatile mem zd->widget[iiw].pname = strdupz(pname,0,"zdialog"); zd->widget[iiw].data = 0; zd->widget[iiw].cblist = 0; zd->widget[iiw].scc = scc; zd->widget[iiw].homog = homog; zd->widget[iiw].expand = expand; zd->widget[iiw].space = space; zd->widget[iiw].wrap = wrap; zd->widget[iiw].widget = 0; zd->widget[iiw+1].type = 0; // new EOF marker if (strcmpv(type,"dialog","hbox","vbox","hsep","vsep","frame","scrwin", "label","link","entry","edit","button","togbutt","check","combo", "comboE","radio","spin","hscale","vscale","colorbutt", null) == 0) zappcrash("zdialog, bad widget type: %s",type); for (iip = iiw-1; iip >= 0; iip--) // find parent (container) widget if (strEqu(pname,zd->widget[iip].name)) break; if (iip < 0) zappcrash("zdialog, no parent for widget: %s",name); pwidget = zd->widget[iip].widget; // parent widget, type ptype = zd->widget[iip].type; if (strcmpv(ptype,"dialog","hbox","vbox","frame","scrwin",null) == 0) zappcrash("zdialog, bad widget parent type: %s",ptype); if (! monofont) monofont = pango_font_description_from_string("Monospace"); if (strEqu(type,"hbox")) widget = gtk_hbox_new(homog,space); // expandable container boxes if (strEqu(type,"vbox")) widget = gtk_vbox_new(homog,space); if (strEqu(type,"hsep")) widget = gtk_hseparator_new(); // horiz. & vert. separators if (strEqu(type,"vsep")) widget = gtk_vseparator_new(); if (strEqu(type,"frame")) { // frame around contained widgets widget = gtk_frame_new(data); gtk_frame_set_shadow_type(GTK_FRAME(widget),GTK_SHADOW_IN); } if (strEqu(type,"scrwin")) { // scrolled window container widget = gtk_scrolled_window_new(0,0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget), GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); } if (strEqu(type,"label")) widget = gtk_label_new(data); // label (static text) if (strEqu(type,"link")) { // label is clickable v.4.0 widget = gtk_link_button_new(data); G_SIGNAL(widget,"clicked",zdialog_widget_event,zd); } if (strEqu(type,"entry")) { // 1-line text entry widget = gtk_entry_new(); if (data) gtk_entry_set_text(GTK_ENTRY(widget),data); if (scc) gtk_entry_set_width_chars(GTK_ENTRY(widget),scc); gtk_widget_modify_font(widget,monofont); G_SIGNAL(widget,"changed",zdialog_widget_event,zd); } if (strEqu(type,"edit")) { // multiline edit box widget = gtk_text_view_new(); editBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); if (data) gtk_text_buffer_set_text(editBuff,data,-1); gtk_text_view_set_editable(GTK_TEXT_VIEW(widget),1); if (wrap) gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(widget),GTK_WRAP_WORD); // v.4.3 gtk_widget_modify_font(widget,monofont); G_SIGNAL(editBuff,"changed",zdialog_widget_event,zd); // buffer signals, not widget } if (strEqu(type,"button")) { // button widget = gtk_button_new_with_label(data); G_SIGNAL(widget,"clicked",zdialog_widget_event,zd); } if (strEqu(type,"togbutt")) { // toggle button widget = gtk_toggle_button_new_with_label(data); G_SIGNAL(widget,"toggled",zdialog_widget_event,zd); } if (strEqu(type,"check")) { // checkbox if (data) widget = gtk_check_button_new_with_label(data); else widget = gtk_check_button_new(); G_SIGNAL(widget,"toggled",zdialog_widget_event,zd); } if (strEqu(type,"combo")) { // combo box widget = gtk_combo_box_new_text(); zd->widget[iiw].cblist = pvlist_create(zdcbmax); // for drop-down list if (! blank_null(data)) { pvlist_append(zd->widget[iiw].cblist,data); // add data to drop-down list gtk_combo_box_append_text(GTK_COMBO_BOX(widget),data); gtk_combo_box_set_active(GTK_COMBO_BOX(widget),0); } gtk_widget_modify_font(widget,monofont); G_SIGNAL(widget,"changed",zdialog_widget_event,zd); } if (strEqu(type,"comboE")) { // combo box with entry box widget = gtk_combo_box_entry_new_text(); zd->widget[iiw].cblist = pvlist_create(zdcbmax); // for drop-down list if (! blank_null(data)) { gtk_entry_set_text(GTK_ENTRY(GTK_BIN(widget)->child),data); // entry = initial data pvlist_append(zd->widget[iiw].cblist,data); // add data to drop-down list gtk_combo_box_append_text(GTK_COMBO_BOX(widget),data); } gtk_widget_modify_font(widget,monofont); G_SIGNAL(widget,"changed",zdialog_widget_event,zd); } if (strEqu(type,"radio")) { // radio button for (kk = iip+1; kk <= iiw; kk++) if (strEqu(zd->widget[kk].pname,pname) && // find first radio button strEqu(zd->widget[kk].type,"radio")) break; // with same container if (kk == iiw) widget = gtk_radio_button_new_with_label(null,data); // this one is first else widget = gtk_radio_button_new_with_label_from_widget // not first, add to group (GTK_RADIO_BUTTON(zd->widget[kk].widget),data); G_SIGNAL(widget,"toggled",zdialog_widget_event,zd); } if (strcmpv(type,"spin","hscale","vscale",null)) { // spin button or sliding scale pp = strField(data,'|',1); err = convSD(pp,min); // locale fix pp = strField(data,'|',2); err += convSD(pp,max); pp = strField(data,'|',3); err += convSD(pp,step); pp = strField(data,'|',4); err += convSD(pp,val); if (err) { min = 0; max = 100; step = 1; val = 50; } if (*type == 's') { widget = gtk_spin_button_new_with_range(min,max,step); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),val); } if (*type == 'h') { widget = gtk_hscale_new_with_range(min,max,step); gtk_range_set_value(GTK_RANGE(widget),val); gtk_scale_set_draw_value(GTK_SCALE(widget),0); } if (*type == 'v') { widget = gtk_vscale_new_with_range(min,max,step); gtk_range_set_value(GTK_RANGE(widget),val); gtk_scale_set_draw_value(GTK_SCALE(widget),0); } G_SIGNAL(widget,"value-changed",zdialog_widget_event,zd); sprintf(vdata,"%g",val); data = vdata; } if (strEqu(type,"colorbutt")) { // color edit button if (! data) data = "0|0|0"; // data format: "nnn|nnn|nnn" = RGB pp = strField(data,'|',1); gdkcolor.red = 256 * atoi(pp); pp = strField(data,'|',2); gdkcolor.green = 256 * atoi(pp); pp = strField(data,'|',3); gdkcolor.blue = 256 * atoi(pp); widget = gtk_color_button_new_with_color(&gdkcolor); G_SIGNAL(widget,"color-set",zdialog_widget_event,zd); } // all widget types come here zd->widget[iiw].widget = widget; // set widget in zdialog if (strEqu(ptype,"hbox") || strEqu(ptype,"vbox")) // add to hbox/vbox gtk_box_pack_start(GTK_BOX(pwidget),widget,expand,expand,space); if (strEqu(ptype,"frame")) // add to frame gtk_container_add(GTK_CONTAINER(pwidget),widget); if (strEqu(ptype,"scrwin")) // add to scroll window gtk_container_add(GTK_CONTAINER(pwidget),widget); if (strEqu(ptype,"dialog")) // add to dialog box gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pwidget)->vbox), widget,expand,expand,space); if (data) zd->widget[iiw].data = strdupz(data,0,"zdialog"); // use heap memory return 0; } // add widget to existing zdialog - alternative form (clearer and easier code) // options: "scc=nn | homog | expand | space=nn | wrap" (all optional, any order) int zdialog_add_widget(zdialog *zd, cchar *type, cchar *name, cchar *parent, cchar *data, cchar *options) { int stat, scc = 0, homog = 0, expand = 0, space = 0, wrap = 0, begin = 1; char pname[8]; double pval; while (true) { stat = strParms(begin,options,pname,8,pval); if (stat == -1) break; if (stat == 1) zappcrash("bad zdialog options: %s",options); if (strEqu(pname,"scc")) scc = (int(pval)); else if (strEqu(pname,"homog")) homog = 1; else if (strEqu(pname,"expand")) expand = 1; else if (strEqu(pname,"space")) space = (int(pval)); else if (strEqu(pname,"wrap")) wrap = 1; else zappcrash("bad zdialog options: %s",options); } stat = zdialog_add_widget(zd,type,name,parent,data,scc,homog,expand,space,wrap); return stat; } // get GTK widget from zdialog and widget name GtkWidget * zdialog_widget(zdialog *zd, cchar *name) { if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; for (int ii = 0; zd->widget[ii].type; ii++) // v.4.4 if (strEqu(zd->widget[ii].name,name)) return zd->widget[ii].widget; return 0; } // set a common group for a set of radio buttons int zdialog_set_group(zdialog *zd, cchar *radio1, ...) // (GTK, this does not work) { va_list arglist; cchar *radio2; GtkWidget *gwidget, *widget; GSList *glist; gwidget = zdialog_widget(zd,radio1); glist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(gwidget)); if (! glist) zappcrash("no radio button group"); va_start(arglist,radio1); while (true) { radio2 = va_arg(arglist,cchar *); if (! radio2) break; widget = zdialog_widget(zd,radio2); gtk_radio_button_set_group(GTK_RADIO_BUTTON(widget),glist); } va_end(arglist); return 0; } // resize dialog to a size greater than initial size // (as determined by the included widgets) int zdialog_resize(zdialog *zd, int width, int height) { if (! zd) zappcrash("zdialog null pointer"); // detect destroyed dialog if (zd->sentinel != zdsentinel) zappcrash("zdialog invalid"); GtkWidget *window = zd->widget[0].widget; gtk_window_set_default_size(GTK_WINDOW(window),width,height); return 1; } // put data into a zdialog widget int zdialog_put_data(zdialog *zd, cchar *name, cchar *data) { GtkWidget *widget; GtkTextBuffer *textBuff; GdkColor gdkcolor; int iiw, nn, kk; cchar *type, *pp; char *wdata; double val; if (! zd || zd->sentinel != zdsentinel) { // detect destroyed dialog printf("zdialog_put_data(%s,%s), zdialog invalid \n",name,data); return 0; } for (iiw = 1; zd->widget[iiw].type; iiw++) // find widget if (strEqu(zd->widget[iiw].name,name)) break; if (! zd->widget[iiw].type) { printf("zdialog_put_data(%s), widget invalid \n",name); // v.4.4 return 0; } type = zd->widget[iiw].type; widget = zd->widget[iiw].widget; wdata = zd->widget[iiw].data; if (wdata) zfree(wdata); // free prior data memory zd->widget[iiw].data = 0; if (data) { wdata = strdupz(data,0,"zdialog"); // set new data for widget zd->widget[iiw].data = wdata; if (utf8_check(wdata)) printf("zdialog: bad UTF8 encoding %s \n",wdata); } zd->disabled++; // disable for widget stuffing if (strEqu(type,"label")) gtk_label_set_text(GTK_LABEL(widget),data); if (strEqu(type,"link")) gtk_label_set_text(GTK_LABEL(widget),data); if (strEqu(type,"entry")) gtk_entry_set_text(GTK_ENTRY(widget),data); if (strEqu(type,"button")) // change button label gtk_button_set_label(GTK_BUTTON(widget),data); if (strEqu(type,"edit")) { textBuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); gtk_text_buffer_set_text(textBuff,data,-1); } if (strcmpv(type,"togbutt","check","radio",null)) { if (! data) kk = nn = 0; else kk = convSI(data,nn); if (kk != 0) nn = 0; // data not integer, force zero if (nn <= 0) nn = 0; else nn = 1; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),nn); // set gtk widget value } if (strEqu(type,"spin")) { kk = convSD(data,val); if (kk != 0) val = 0.0; gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),val); } if (strEqu(type,"colorbutt")) { // color button pp = strField(data,'|',1); if (pp) gdkcolor.red = 256 * atoi(pp); // bugfix pp = strField(data,'|',2); if (pp) gdkcolor.green = 256 * atoi(pp); pp = strField(data,'|',3); if (pp) gdkcolor.blue = 256 * atoi(pp); gtk_color_button_set_color(GTK_COLOR_BUTTON(widget),&gdkcolor); } if (strcmpv(type,"hscale","vscale",null)) { kk = convSD(data,val); if (kk != 0) val = 0.0; gtk_range_set_value(GTK_RANGE(widget),val); } if (strEqu(type,"combo")) { if (! blank_null(data)) { kk = pvlist_prepend(zd->widget[iiw].cblist,data,1); // add to drop-down list if (kk == 0) // (only if unique) gtk_combo_box_prepend_text(GTK_COMBO_BOX(widget),data); kk = pvlist_find(zd->widget[iiw].cblist,data); gtk_combo_box_set_active(GTK_COMBO_BOX(widget),kk); // make the active entry } else gtk_combo_box_set_active(GTK_COMBO_BOX(widget),-1); // make no active entry } if (strEqu(type,"comboE")) { if (! blank_null(data)) { kk = pvlist_prepend(zd->widget[iiw].cblist,data,1); // add to drop-down list if (kk == 0) // (only if unique) gtk_combo_box_prepend_text(GTK_COMBO_BOX(widget),data); gtk_entry_set_text(GTK_ENTRY(GTK_BIN(widget)->child),data); // stuff entry box with new data } else gtk_entry_set_text(GTK_ENTRY(GTK_BIN(widget)->child),""); // stuff entry box with nothing } zd->disabled--; // re-enable dialog return iiw; } // get data from a dialog widget based on its name cchar * zdialog_get_data(zdialog *zd, cchar *name) { if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; for (int ii = 1; zd->widget[ii].type; ii++) if (strEqu(zd->widget[ii].name,name)) return zd->widget[ii].data; return 0; } // set new limits for a numeric data entry widget (spin, hscale, vscale) int zdialog_set_limits(zdialog *zd, cchar *name, double min, double max) // new v.4.4 { GtkWidget *widget; cchar *type; int iiw; if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; for (iiw = 1; zd->widget[iiw].type; iiw++) if (strEqu(name,zd->widget[iiw].name)) break; if (! zd->widget[iiw].type) { printf("zdialog_stuff_limits, %s not found \n",name); return 0; } widget = zd->widget[iiw].widget; type = zd->widget[iiw].type; if (*type == 's') gtk_spin_button_set_range(GTK_SPIN_BUTTON(widget),min,max); if (*type == 'h' || *type == 'v') gtk_range_set_range(GTK_RANGE(widget),min,max); return 1; } // put help topic into dialog void zdialog_help(zdialog *zd, cchar *help_topic) { zd->help_topic = help_topic; return; } // run the dialog and send events to the event function // evfunc: int func(zdialog *zd, cchar *event) // posn: optional dialog box position (see zdialog_set_position) int zdialog_run(zdialog *zd, zdialog_event evfunc, cchar *posn) // v.4.4 { int zdialog_KBpress(GtkWidget *, GdkEventKey *event, zdialog *zd); int zdialog_KBrelease(GtkWidget *, GdkEventKey *event, zdialog *zd); int zdialog_focus_event_signal(GtkWidget *, GdkEvent *event, zdialog *zd); int ii; GtkWidget *widget, *dialog; if (! zd) zappcrash("zdialog null pointer"); // detect destroyed dialog if (zd->sentinel != zdsentinel) zappcrash("zdialog invalid"); dialog = zd->widget[0].widget; if (posn) zdialog_set_position(zd,posn); // v.4.4 for (ii = 1; zd->widget[ii].type; ii++) // *** stop auto-selection { // (GTK "feature") if (strEqu(zd->widget[ii].type,"entry")) { widget = zd->widget[ii].widget; gtk_editable_set_position(GTK_EDITABLE(widget),-1); break; } if (strEqu(zd->widget[ii].type,"comboE")) { // also combo edit box widget = zd->widget[ii].widget; gtk_editable_set_position(GTK_EDITABLE(GTK_BIN(widget)->child),-1); break; } } if (evfunc) zd->eventCB = (void *) evfunc; // link to dialog event callback dialog = zd->widget[0].widget; gtk_widget_show_all(dialog); // activate dialog gtk_window_present(GTK_WINDOW(dialog)); if (! zd->parent) // if no parent, force to top gtk_window_set_keep_above(GTK_WINDOW(dialog),1); // v.4.9 G_SIGNAL(dialog,"focus-in-event",zdialog_focus_event_signal,zd); // connect focus event function v.5.0 G_SIGNAL(dialog,"key-press-event",zdialog_KBpress,zd); // connect key press event function G_SIGNAL(dialog,"key-release-event",zdialog_KBrelease,zd); // connect key release event function G_SIGNAL(dialog,"response",zdialog_response_event,zd); // connect dialog response function zd->disabled = 0; // enable widget events v.4.7 zfuncs::zdialog_busy++; // count open zdialogs v.4.7 return 0; // return now, dialog is non-modal } // zdialog event handler - private function called for dialog events. // Updates data in zdialog, calls user callback function (if present). int zdialog_widget_event(GtkWidget *widget, zdialog *zd) { zdialog_event *evfunc = 0; // dialog event callback function GtkTextView *textView = 0; GtkTextBuffer *textBuff = 0; GtkTextIter iter1, iter2; GdkColor gdkcolor; static GtkWidget *lastwidget = 0; int ii, nn; cchar *wname, *type, *wdata; char sdata[20]; double dval; static int cbadded = 0; if (! zd) return 1; // detect destroyed dialog v.5.0 if (zd->sentinel != zdsentinel) return 1; for (ii = 0; ii < zdmaxbutts; ii++) // check completion buttons if (zd->compbutt[ii] == widget) break; if (ii < zdmaxbutts) { zd->zstat = ii+1; // zdialog status = button no. if (zd->eventCB) { evfunc = (zdialog_event *) zd->eventCB; // do callback function evfunc(zd,"zstat"); } return 1; // v.5.0 } for (ii = 1; zd->widget[ii].type; ii++) // find widget in zdialog if (zd->widget[ii].widget == widget) goto found_widget; for (ii = 1; zd->widget[ii].type; ii++) { // failed, test if buffer if (strEqu(zd->widget[ii].type,"edit")) { // of text view widget textView = GTK_TEXT_VIEW(zd->widget[ii].widget); textBuff = gtk_text_view_get_buffer(textView); if (widget == (GtkWidget *) textBuff) goto found_widget; } } printf("zdialog event %s, ignored \n",zd->widget[ii].name); // not found, ignore event v.4.7 return 1; found_widget: if (zd->disabled) return 1; // stop re-entrance from own updates zd->disabled = 1; // (zdialog_put_data()) wname = zd->widget[ii].name; type = zd->widget[ii].type; wdata = 0; if (strEqu(type,"button")) wdata = "clicked"; if (strEqu(type,"entry")) wdata = gtk_entry_get_text(GTK_ENTRY(widget)); if (strEqu(type,"edit")) { gtk_text_buffer_get_bounds(textBuff,&iter1,&iter2); wdata = gtk_text_buffer_get_text(textBuff,&iter1,&iter2,0); } if (strcmpv(type,"radio","check","togbutt",null)) { nn = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if (nn == 0) wdata = "0"; else wdata = "1"; } if (strEqu(type,"combo")) wdata = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); if (strEqu(type,"comboE")) { if (widget == lastwidget && cbadded) { pvlist_remove(zd->widget[ii].cblist,0); // detect multiple edits (keystrokes) gtk_combo_box_remove_text(GTK_COMBO_BOX(widget),0); // and replace prior entry with new } wdata = gtk_entry_get_text(GTK_ENTRY(GTK_BIN(widget)->child)); cbadded = 0; if (! blank_null(wdata)) { nn = pvlist_prepend(zd->widget[ii].cblist,wdata,1); // add entry to drop-down list if (nn == 0) { // (only if unique) gtk_combo_box_prepend_text(GTK_COMBO_BOX(widget),wdata); cbadded = 1; } } } if (strEqu(type,"spin")) { dval = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); sprintf(sdata,"%g",dval); wdata = sdata; } if (strEqu(type,"colorbutt")) // color button { gtk_color_button_get_color(GTK_COLOR_BUTTON(widget),&gdkcolor); sprintf(sdata,"%d|%d|%d",gdkcolor.red/256,gdkcolor.green/256,gdkcolor.blue/256); wdata = sdata; } if (strcmpv(type,"hscale","vscale",null)) { dval = gtk_range_get_value(GTK_RANGE(widget)); sprintf(sdata,"%g",dval); wdata = sdata; } // all widgets come here if (zd->widget[ii].data) zfree(zd->widget[ii].data); // clear prior data zd->widget[ii].data = 0; if (wdata) zd->widget[ii].data = strdupz(wdata,0,"zdialog"); // set new data lastwidget = widget; // remember last widget updated if (zd->eventCB) { evfunc = (zdialog_event *) zd->eventCB; // do user callback function evfunc(zd,wname); } zd->disabled = 0; // re-enable widgets return 1; // v.5.0 } // zdialog response handler for "focus-in-event" signal // v.5.0 int zdialog_focus_event_signal(GtkWidget *, GdkEvent *event, zdialog *zd) { if (zd->zstat) return 0; // already complete if (zd->help_topic) zfuncs::F1_help_topic = zd->help_topic; // set help topic zdialog_send_event(zd,"focus"); // notify dialog event function return 0; // must be 0 } // zdialog response handler for keyboard events int zdialog_KBpress(GtkWidget *, GdkEventKey *event, zdialog *zd) // prevent KB key press from being { // sent to toolbar buttons return 0; // must be 0 } int zdialog_KBrelease(GtkWidget *, GdkEventKey *kbevent, zdialog *zd) { zdialog_event *evfunc = 0; // dialog event callback function int KBkey = kbevent->keyval; char event[8]; if (KBkey == GDK_F1) { showz_userguide(zfuncs::F1_help_topic); // context help return 1; } if (zd->eventCB) { evfunc = (zdialog_event *) zd->eventCB; // do user callback function v.4.7 strcpy(event,"KB x"); // with event = "KB x" event[3] = KBkey; // (x = key now released) evfunc(zd,event); return 1; } return 0; } // zdialog response handler - private function called when dialog is completed. // called when dialog is canceled via [x] button or destroyed by GTK (zstat < 0). int zdialog_response_event(GtkWidget *, int zstat, zdialog *zd) { zdialog_event *evfunc = 0; // dialog event callback function if (! zd) return 1; // detect destroyed dialog v.4.9 if (zd->sentinel != zdsentinel) return 1; if (zd->zstat) return 1; // already complete if (zstat > -1) zstat = -1; // insure cancel status v.5.0 zd->zstat = zstat; // set zdialog status if (zd->eventCB) { evfunc = (zdialog_event *) zd->eventCB; // do callback function evfunc(zd,"zstat"); // (should do zfree()) } return 1; // v.5.0 } // send an event to an active dialog int zdialog_send_event(zdialog *zd, cchar *event) { zdialog_event * evfunc = 0; // dialog event callback function if (zd && zd->sentinel == zdsentinel) { // check dialog is active evfunc = (zdialog_event *) zd->eventCB; if (evfunc) evfunc(zd,event); // call dialog event function } return 1; } // Complete a dialog and give it a status, without user action. // Dialog event function will be called, zdialog_wait() will return. // returns: 0 = no active dialog, 1 = OK int zdialog_send_response(zdialog *zd, int zstat) { zdialog_event *evfunc = 0; // dialog event callback function if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; zd->zstat = zstat; // set status if (zd->eventCB) { evfunc = (zdialog_event *) zd->eventCB; // do callback function evfunc(zd,"zstat"); } return 1; } // Destroy the zdialog - must be done by zdialog_run() caller // (else dialog continues active even after completion button). // Data in widgets remains valid until zdialog_free() is called. int zdialog_destroy(zdialog *zd) { using namespace zfuncs; if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; if (zd->zstat < 0) { // destroyed by [x] button or GTK zd->widget[0].widget = 0; // assume GTK dialog is gone zdialog_busy--; // v.4.7 } if (zd->widget[0].widget) { // multiple destroys OK if (zd->saveposn) zdialog_save_position(zd); // save position for next use v.4.7 gtk_widget_destroy(zd->widget[0].widget); // destroy GTK dialog zdialog_busy--; // v.4.7 zd->widget[0].widget = 0; } if (! zd->zstat) zd->zstat = -1; // status = destroyed return 1; } // free zdialog memory (destroy first, if not already) int zdialog_free(zdialog *&zd) // reference { if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; zdialog_destroy(zd); // destroy GTK dialog if there zd->sentinel = 0; // mark invalid zfree(zd->widget[0].data); // bugfix memory leak for (int ii = 1; zd->widget[ii].type; ii++) // loop through widgets { if (strcmpv(zd->widget[ii].type,"combo","comboE",null)) // bugfix, free combo list pvlist_free(zd->widget[ii].cblist); zfree((char *) zd->widget[ii].type); // free strings zfree((char *) zd->widget[ii].name); zfree((char *) zd->widget[ii].pname); if (zd->widget[ii].data) zfree(zd->widget[ii].data); // free data } zfree(zd); // free zdialog memory zd = 0; // clear pointer return 1; } // wait for a zdialog to have a completion status or be destroyed // returns completion status or -1 if destroyed int zdialog_wait(zdialog *zd) { while (true) { zmainloop(); if (! zd) return -1; // dialog destroyed if (zd->sentinel != zdsentinel) return -1; if (zd->zstat) return zd->zstat; zsleep(0.01); } } // put cursor at named widget int zdialog_goto(zdialog *zd, cchar *name) { GtkWidget *widget; if (zd->sentinel != zdsentinel) return 0; widget = zdialog_widget(zd, name); if (! widget) return 0; gtk_editable_select_region(GTK_EDITABLE(widget),0,-1); // focus on widget gtk_widget_grab_focus(widget); return 1; } // set cursor for zdialog (e.g. busy cursor) void zdialog_set_cursor(zdialog *zd, GdkCursor *cursor) { GtkWidget *dialog; if (zd->sentinel != zdsentinel) return; dialog = zd->widget[0].widget; if (! dialog) return; gdk_window_set_cursor(dialog->window,cursor); return; } // convenience functions for stuffing and retrieving widget data int zdialog_stuff(zdialog *zd, cchar *name, cchar *data) // stuff a string { zdialog_put_data(zd, name, data); return 1; } int zdialog_stuff(zdialog *zd, cchar *name, int idata) // stuff an integer { char string[16]; sprintf(string,"%d",idata); zdialog_put_data(zd,name,string); return 1; } int zdialog_stuff(zdialog *zd, cchar *name, double ddata) // stuff a double { char string[32]; snprintf(string,31,"%g",ddata); // outputs decimal point or comma zdialog_put_data(zd,name,string); // (per locale) return 1; } int zdialog_fetch(zdialog *zd, cchar *name, char *data, int maxcc) // fetch string data { cchar *zdata; zdata = zdialog_get_data(zd,name); if (! zdata) { *data = 0; return 0; } return strncpy0(data,zdata,maxcc); // 0 = OK, 1 = truncation } int zdialog_fetch(zdialog *zd, cchar *name, int &idata) // fetch an integer { cchar *zdata; zdata = zdialog_get_data(zd,name); if (! zdata) { idata = 0; return 0; } idata = atoi(zdata); return 1; } int zdialog_fetch(zdialog *zd, cchar *name, double &ddata) // fetch a double { int stat; cchar *zdata; zdata = zdialog_get_data(zd,name); if (! zdata) { ddata = 0; return 0; } stat = convSD(zdata,ddata); // period or comma decimal point OK if (stat < 4) return 1; return 0; } int zdialog_fetch(zdialog *zd, cchar *name, float &fdata) // fetch a float { int stat; cchar *zdata; double ddata; zdata = zdialog_get_data(zd,name); if (! zdata) { fdata = 0; return 0; } stat = convSD(zdata,ddata); // period or comma decimal point OK fdata = ddata; if (stat < 4) return 1; return 0; } // append new item to combo box list without changing entry box int zdialog_cb_app(zdialog *zd, cchar *name, cchar *data) { int ii, nn; if (! zd) zappcrash("zdialog null pointer"); // detect destroyed dialog if (zd->sentinel != zdsentinel) zappcrash("zdialog invalid"); if (blank_null(data)) return 0; // find widget for (ii = 1; zd->widget[ii].type; ii++) if (strEqu(zd->widget[ii].name,name)) break; if (! zd->widget[ii].type) return 0; // not found if (! strcmpv(zd->widget[ii].type,"combo","comboE",null)) return 0; // not combo box nn = pvlist_append(zd->widget[ii].cblist,data,1); // append unique if (nn >= 0) gtk_combo_box_append_text(GTK_COMBO_BOX(zd->widget[ii].widget),data); return 1; } // prepend new item to combo box list without changing entry box int zdialog_cb_prep(zdialog *zd, cchar *name, cchar *data) { int ii, nn; if (! zd) zappcrash("zdialog null pointer"); // detect destroyed dialog if (zd->sentinel != zdsentinel) zappcrash("zdialog invalid"); if (blank_null(data)) return 0; // find widget for (ii = 1; zd->widget[ii].type; ii++) if (strEqu(zd->widget[ii].name,name)) break; if (! zd->widget[ii].type) return 0; // not found if (! strcmpv(zd->widget[ii].type,"combo","comboE",null)) return 0; // not combo box nn = pvlist_prepend(zd->widget[ii].cblist,data,1); // append unique if (nn == 0) gtk_combo_box_prepend_text(GTK_COMBO_BOX(zd->widget[ii].widget),data); return 1; } // get combo box drop-down list entry char * zdialog_cb_get(zdialog *zd, cchar *name, int Nth) { int ii; if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; for (ii = 1; zd->widget[ii].type; ii++) // find widget if (strEqu(zd->widget[ii].name,name)) break; if (! zd->widget[ii].type) return 0; // not found if (! strcmpv(zd->widget[ii].type,"combo","comboE",null)) return 0; // not combo box return pvlist_get(zd->widget[ii].cblist,Nth); } // delete entry by name from combo drop down list int zdialog_cb_delete(zdialog *zd, cchar *name, cchar *data) { int ii, nn; if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; for (ii = 1; zd->widget[ii].type; ii++) // find widget if (strEqu(zd->widget[ii].name,name)) break; if (! zd->widget[ii].type) return 0; // not found if (! strcmpv(zd->widget[ii].type,"combo","comboE",null)) return 0; // not combo box nn = pvlist_find(zd->widget[ii].cblist,data); // find entry by name if (nn < 0) return -1; pvlist_remove(zd->widget[ii].cblist,nn); // remove from memory list gtk_combo_box_remove_text(GTK_COMBO_BOX(zd->widget[ii].widget),nn); // and from widget gtk_combo_box_set_active(GTK_COMBO_BOX(zd->widget[ii].widget),-1); // set no active entry return 0; } // delete all entries from combo drop down list int zdialog_cb_clear(zdialog *zd, cchar *name) { int ii, jj, nn; if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; for (ii = 1; zd->widget[ii].type; ii++) // find widget if (strEqu(zd->widget[ii].name,name)) break; if (! zd->widget[ii].type) return 0; // not found if (! strcmpv(zd->widget[ii].type,"combo","comboE",null)) return 0; // not combo box nn = pvlist_count(zd->widget[ii].cblist); // entry count for (jj = nn-1; jj >= 0; jj--) { pvlist_remove(zd->widget[ii].cblist,jj); // remove from memory list gtk_combo_box_remove_text(GTK_COMBO_BOX(zd->widget[ii].widget),jj); // remove from widget } gtk_combo_box_set_active(GTK_COMBO_BOX(zd->widget[ii].widget),-1); // set no active entry if (strEqu(zd->widget[ii].type,"comboE")) // stuff entry box with nothing gtk_entry_set_text(GTK_ENTRY(GTK_BIN(zd->widget[ii].widget)->child),""); return 0; } // make a combo box drop down to show all entries int zdialog_cb_popup(zdialog *zd, cchar *name) { int ii; if (! zd) return 0; // detect destroyed dialog if (zd->sentinel != zdsentinel) return 0; for (ii = 1; zd->widget[ii].type; ii++) // find widget if (strEqu(zd->widget[ii].name,name)) break; if (! zd->widget[ii].type) return 0; // not found if (! strcmpv(zd->widget[ii].type,"combo","comboE",null)) return 0; // not combo box gtk_combo_box_popup(GTK_COMBO_BOX(zd->widget[ii].widget)); return 0; } /**************************************************************************/ // functions to save and recall zdialog window positions namespace zdposn_names { struct zdposn_t { float xpos, ypos; // window position WRT parent or desktop char wintitle[64]; // window title (ID) } zdposn[200]; // space for 200 windows int Nzdposn; // no. in use int Nzdpmax = 200; // table size } // Load zdialog positions table from its file (application startup) // or save zdialog positions table to its file (application exit). // Action is "load" or "save". Number of table entries is returned. int zdialog_positions(cchar *action) // new v.4.4 { using namespace zdposn_names; char posfile[200], buff[100], wintitle[64], *pp; float xpos, ypos; int nn, ii; FILE *fid; snprintf(posfile,199,"%s/zdialog_positions",get_zuserdir()); // /home//.appname/zdialog_positions if (strEqu(action,"load")) // load dialog positions table from file { fid = fopen(posfile,"r"); if (! fid) { Nzdposn = 0; return 0; } for (nn = 0; nn < Nzdpmax; nn++) { pp = fgets(buff,100,fid); if (! pp) break; if (strlen(pp) < 64) continue; strncpy0(wintitle,buff,64); strTrim(wintitle); if (strlen(wintitle) < 3) continue; ii = sscanf(buff + 64," %f %f ",&xpos,&ypos); if (ii != 2) continue; strcpy(zdposn[nn].wintitle,wintitle); zdposn[nn].xpos = xpos; zdposn[nn].ypos = ypos; } fclose(fid); Nzdposn = nn; return Nzdposn; } if (strEqu(action,"save")) // save dialog positions table to file { fid = fopen(posfile,"w"); if (! fid) { printf("cannot write zdialog_positions file \n"); return 0; } for (nn = 0; nn < Nzdposn; nn++) fprintf(fid,"%-64s %0.1f %0.1f \n",zdposn[nn].wintitle, zdposn[nn].xpos, zdposn[nn].ypos); fclose(fid); return Nzdposn; } printf("zdialog_positions bad action: %s \n",action); return 0; } // Set the initial or new zdialog window position from "posn" // null: window manager decides // "mouse" put dialog at mouse position // "desktop" center dialog in desktop window // "parent" center dialog in parent window // "save" use the same position last set by the user // "nn/nn" put NW corner of dialog in parent window at % size // (e.g. "50/50" puts NW corner at center of parent) void zdialog_set_position(zdialog *zd, cchar *posn) // new v.4.4 { using namespace zdposn_names; int ii, ppx, ppy, zdpx, zdpy, pww, phh; float xpos, ypos; char wintitle[64], *pp; GtkWidget *parent, *dialog; parent = zd->parent; dialog = zd->widget[0].widget; if (strEqu(posn,"mouse")) { gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_MOUSE); return; } if (strEqu(posn,"desktop")) { gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER); return; } if (strEqu(posn,"parent")) { gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER_ON_PARENT); return; } if (! parent) { // no parent window ppx = ppy = 0; // use desktop pww = gdk_screen_width(); phh = gdk_screen_height(); } else { gtk_window_get_position(GTK_WINDOW(parent),&ppx,&ppy); // parent window NW corner gtk_window_get_size(GTK_WINDOW(parent),&pww,&phh); // parent window size } if (strEqu(posn,"save")) // use last saved window position { zd->saveposn = 1; // set flag for zdialog_free() pp = (char *) gtk_window_get_title(GTK_WINDOW(dialog)); // get window title, used as ID if (! pp) return; if (strlen(pp) < 2) return; strncpy0(wintitle,pp,64); // window title, < 64 chars. for (ii = 0; ii < Nzdposn; ii++) // search table for title if (strEqu(wintitle,zdposn[ii].wintitle)) break; if (ii == Nzdposn) return; // not found - zdialog_free() will add zdpx = ppx + 0.01 * zdposn[ii].xpos * pww; // position for dialog window zdpy = ppy + 0.01 * zdposn[ii].ypos * phh; gtk_window_move(GTK_WINDOW(dialog),zdpx,zdpy); return; } else // "nn/nn" // position from caller { ii = sscanf(posn,"%f/%f",&xpos,&ypos); // parse "nn/nn" if (ii != 2) return; zdpx = ppx + 0.01 * xpos * pww; // position for dialog window zdpy = ppy + 0.01 * ypos * phh; gtk_window_move(GTK_WINDOW(dialog),zdpx,zdpy); return; } } // If the dialog window position is "save" then save // its position WRT parent or desktop for next use. void zdialog_save_position(zdialog *zd) // new v.4.4 { using namespace zdposn_names; int ii, ppx, ppy, pww, phh, zdpx, zdpy; float xpos, ypos; char wintitle[64], *pp; GtkWidget *parent, *dialog; dialog = zd->widget[0].widget; if (! dialog) return; // destroyed v.4.7 parent = zd->parent; // parent window if (! parent) { // no parent window ppx = ppy = 0; // use desktop pww = gdk_screen_width(); phh = gdk_screen_height(); } else { gtk_window_get_position(GTK_WINDOW(parent),&ppx,&ppy); // parent window NW corner gtk_window_get_size(GTK_WINDOW(parent),&pww,&phh); // parent window size } gtk_window_get_position(GTK_WINDOW(dialog),&zdpx,&zdpy); // dialog window NW corner xpos = 100.0 * (zdpx - ppx) / pww; // dialog window relative position ypos = 100.0 * (zdpy - ppy) / phh; // (as percent of parent size) pp = (char *) gtk_window_get_title(GTK_WINDOW(dialog)); if (! pp) return; if (strlen(pp) < 2) return; strncpy0(wintitle,pp,64); // window title, < 64 chars. for (ii = 0; ii < Nzdposn; ii++) // search table for window if (strEqu(wintitle,zdposn[ii].wintitle)) break; if (ii == Nzdposn) { // not found if (ii == Nzdpmax) return; // table full strcpy(zdposn[ii].wintitle,wintitle); // add window to table Nzdposn++; } zdposn[ii].xpos = xpos; // save window position zdposn[ii].ypos = ypos; return; } /************************************************************************** Translation Functions Translation files are standard .po files as used in the Gnu gettext system. However the .po files are used directly, and there is no need to merge and compile them into a binary format (.mo files). Initialize: int ZTXinit(cchar *lang) lang is "lc" or "lc_RC" or null (current locale will be used) Translate a text string: cchar *translation = ZTX(cchar *english) english: text string which may have printf formats (%d %s ...) translation: the returned equivalent translation If the user language is English or if no translation is found, the input string is returned, else the translated string. A text string may have a context part "context::string", where "context" is any string < 30 characters and "string" is the English text or the translation text. The context part "context::" is removed in the returned string. This is to handle the case where a single English string may need multiple translations, depending on context. The English string may be present multiple times in a .po file, each one marked with a different context and having a different translation. Context is optional in translation strings. example: program code: printf(ZTX("answer: %d %s \n next line"), 123, "qwerty"); A German .po file (appname-de.po) would have the following: msgid "" "answer: %d %s \n" " next line" msgstr "" "Antwort: %d %s \n" " nächste Zeile" ***/ namespace ZTXnames // remove GOFUNC usage becasue of { // GCC optimization errors FILE *fidr, *fidw; char buff[ZTXmaxcc], *ppq1, *ppq2; char *porec, *wporec; char Etext[ZTXmaxcc], Ttext[ZTXmaxcc]; // .po text: "line 1 %s \n" "line 2" char **etext, **ttext; // arrays, english and translations char **estring, **tstring; // merged, un-quoted, un-escaped int Ntext = 0; // array counts int Ftranslate = 0; // 0/1/2 = translate none/all/missing zdialog *zddump; // dialog for editing translations GtkWidget *trwin; // text window within dialog void ZTXgettext(char *text); char *ZTXmergetext(cchar *text); void ZTX_translation_dump(int index); void ZTX_translation_update(); void ZTXgettext2(char *text); void ZTXwritetext(cchar *header, char *text); } // read and process .po file at application startup // prepare english strings and translations for quick access void ZTXinit(cchar *lang) // initialize translations v.5.0 { using namespace zfuncs; using namespace ZTXnames; int ii, err; char *pp, pofile[200]; char lc[4], lc_RC[8]; // language (de), * + region (de_AT) struct stat statb; if (Ntext) { // free prior translation for (ii = 0; ii < Ntext; ii++) { zfree(etext[ii]); zfree(ttext[ii]); zfree(estring[ii]); zfree(tstring[ii]); } zfree(etext); zfree(ttext); zfree(estring); zfree(tstring); Ntext = 0; } etext = (char **) zmalloc(ZTXmaxent * sizeof(char *),"ZTX"); // english text and translations ttext = (char **) zmalloc(ZTXmaxent * sizeof(char *),"ZTX"); // (segmented, quoted, escaped) estring = (char **) zmalloc(ZTXmaxent * sizeof(char *),"ZTX"); // english strings and translations tstring = (char **) zmalloc(ZTXmaxent * sizeof(char *),"ZTX"); // (merged, un-quoted, un-escaped) if (lang && *lang) strncpy0(zlang,lang,6); // use language from caller else { // help Linux chaos pp = getenv("LANG"); // use $LANG if defined if (! pp) pp = getenv("LANGUAGE"); // use $LANGUAGE if defined if (! pp) pp = setlocale(LC_MESSAGES,""); // use locale if defined if (pp) strncpy0(zlang,pp,6); // "lc_RC" language/region code else strcpy(zlang,"en"); // use English } if (*zlang < 'a') strcpy(zlang,"en"); // use English if garbage printf("language: %s \n",zlang); if (strnEqu(zlang,"en",2)) return; // English, do nothing v.4.3 strncpy0(lc,zlang,3); // language code alone, e.g. "de" strncpy0(lc_RC,zlang,6); // + opt. region code, "de" or "de_AT" snprintf(pofile,199,"%s/locales/%s-%s.po",zuserdir,zappname,lc_RC); // look for user custom .po file err = stat(pofile,&statb); // (a translation project is underway) if (err) { snprintf(pofile,199,"%s/locales/%s-%s.po",zuserdir,zappname,lc); err = stat(pofile,&statb); } if (err) { // look for normal installed .po file snprintf(pofile,199,"%s/%s-%s.po",zlocalesdir,zappname,lc_RC); err = stat(pofile,&statb); if (err) { snprintf(pofile,199,"%s/%s-%s.po",zlocalesdir,zappname,lc); // default to lc only v.5.0 err = stat(pofile,&statb); } } if (! err) printf("using translation file: %s \n",pofile); else { printf("no translation file found for %s \n",lc_RC); return; } fidr = fopen(pofile,"r"); // open .po file if (! fidr) { printf("cannot open translation file: %s \n",pofile); return; } porec = 0; // no .po record yet *Etext = *Ttext = 0; // no text yet while (true) { if (! porec) porec = fgets_trim(buff,ZTXmaxcc,fidr); // get next .po record if (! porec) break; // EOF if (blank_null(porec)) { // blank record porec = 0; continue; } if (*porec == '#') { // comment porec = 0; continue; } if (strnEqu(porec,"msgid",5)) // start new english string { if (*Etext) { // two in a row printf("no translation: %s \n",Etext); *Etext = 0; } if (*Ttext) { printf("orphan translation: %s \n",Ttext); *Ttext = 0; } porec += 5; // get segmented text string ZTXgettext(Etext); // "segment1 %s \n" "segment2" ... } else if (strnEqu(porec,"msgstr",6)) // start new translation { porec += 6; // get segmented string ZTXgettext(Ttext); if (! *Etext) { printf("orphan translation: %s \n",Ttext); *Ttext = 0; continue; } if (strlen(Ttext) < 3) { // translation is "" printf("no translation: %s \n",Etext); strcpy(Ttext,Etext); // substitute english text } } else { printf("unrecognized .po record: %s \n",porec); porec = 0; continue; } if (*Etext && *Ttext) // have an english/translation pair { etext[Ntext] = strdupz(Etext,0,"ZTX"); // add to translation tables ttext[Ntext] = strdupz(Ttext,0,"ZTX"); *Etext = *Ttext = 0; Ntext++; if (Ntext == ZTXmaxent) // cannot continue zappcrash("more than %d translations",ZTXmaxent); } } fclose(fidr); printf(".po file has %d entries \n",Ntext); for (ii = 0; ii < Ntext; ii++) { pp = ZTXmergetext(etext[ii]); // merge segmented text strings estring[ii] = strdupz(pp,0,"ZTX"); pp = ZTXmergetext(ttext[ii]); tstring[ii] = strdupz(pp,0,"ZTX"); } return; } // private function // read and combine multiple 'msgid' or 'msgstr' quoted strings // output is one string with one or more quoted segments: // "text line 1 %s \n" "text line 2" ... // each segment comes from a different line in the input .po file void ZTXnames::ZTXgettext(char *pstring) // v.4.3 { using namespace ZTXnames; int cc, scc = 0; while (true) // join multiple quoted strings { while (*porec && *porec != '"') porec++; // find opening string quote if (! *porec) { porec = fgets_trim(buff,ZTXmaxcc,fidr); // get next .po record if (! porec) return; if (strnEqu(porec,"msgid",5)) return; // end of this string if (strnEqu(porec,"msgstr",6)) return; } ppq1 = porec; // opening quote ppq2 = ppq1 + 1; while ((*ppq2 && *ppq2 != '"') || // find closing (non-escaped) quote (*ppq2 == '"' && *(ppq2-1) == '\\')) ppq2++; if (! *ppq2) return; cc = ppq2 - ppq1 + 1; // min. case is "" if (cc + 1 + scc >= ZTXmaxcc) printf("string is too long %s \n",pstring); else { strncpy0(pstring+scc,ppq1,cc+1); // accum. substrings, minus quotes scc += cc; } porec = ppq2 + 1; } return; } // private function // convert quoted string segments into binary form that // matches the compiled string in the source program // (remove quotes, merge strings, un-escape \n \" etc.) char * ZTXnames::ZTXmergetext(cchar *dirtystring) // v.4.3 { static char cleanstring[ZTXmaxcc]; int ii, jj; strncpy0(cleanstring,dirtystring,ZTXmaxcc); clean_escapes(cleanstring); for (ii = jj = 0; cleanstring[ii]; ii++) if (cleanstring[ii] != '"') cleanstring[jj++] = cleanstring[ii]; cleanstring[jj] = 0; return cleanstring; } // Translate the input english string or return the input string. // Look for "context::string" and return "string" only if context found. // This function may need a few microseconds if thousands of strings must be searched. cchar * ZTX(cchar *english) { using namespace ZTXnames; cchar *pp, *pp2; int ii; if (! english) return "null"; // v.4.3 for (ii = 0; ii < Ntext; ii++) // find translation v.4.3 if (strEqu(english,estring[ii])) break; if (ii < Ntext) pp = tstring[ii]; else pp = english; if (Ftranslate) { if (ii < Ntext) ZTX_translation_dump(ii); // output translation else printf("message not in .po: %s \n",english); } for (pp2 = pp; *pp2 && pp2 < pp+30; pp2++) // remove context if present if (*pp2 == ':' && *(pp2+1) == ':') return pp2+2; return pp; } /************************************************************************** Online Translation Utility If the application menu "Translate" is selected, the function ZTX_translation_start() is called and the user dialog is used to set translation mode ON or OFF. If ON, the .po translation file is copied from the install location to a user location (if not already there) where it will be modified. This user .po file will be used for translations going forward. Run the application to be translated in the usual manner. Select each menu or toolbar function needing translation. The related english text strings and current translations are dumped into a text edit window. The user can edit the translations while using the application and therefore more easily understand the complete context. Whenever the application calls ZTX() to get a translation, the function ZTX_translation_dump() is called to add the english text and the current translation to the text edit window. ______________________________________________________ | | | msgid "English text with formats %d %d ... " | | msgstr "Deutscher Text mit Formats %d %s ... " | | ... | | [apply] [cancel] | |______________________________________________________| As the application is exercised (menus and dialogs), all english text and current translations are added to the window. Where no translation is available, the english text is repeated as the translation. The user may edit the window to update the translations. When done, using the [apply] button updates the translation .po file in the user location. ***************************************************************************/ // This function is called from the application menu "Translate". // Set translation mode ON or OFF (zfuncs::Ftranslate). If ON and no // .po translation file is found in /home//.appname/locales/, // then it is copied from the installed .po file to provide a starting // point for changes. A text edit window is opened to display the // english strings and their current translations, if any, and for // input of the revised translations. void ZTX_translation_start(GtkWidget *parent) // new v.4.3 { using namespace zfuncs; using namespace ZTXnames; int ZTX_translation_event(zdialog *zd, cchar *event); zdialog *zd; int err, tron, trmissing; char *pp, command[400]; char pofile1[200], pofile2[200]; struct stat statb; if (strnEqu(zlang,"en",2)) { // locale cannot be english zmessageACK(0,"cannot translate locale %s",zlang); return; } if (Ftranslate) return; // already active v.5.0 Ftranslate = 1; /* ___________________________________________ | | | Translation mode: (o) ON (o) OFF | | [x] Show missing translations only | | | | [apply] [cancel] | |___________________________________________| */ zd = zdialog_new("Translation Mode",parent,"apply","cancel",null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","labm","hb1","Translation mode:","space=5"); zdialog_add_widget(zd,"radio","tron","hb1","ON","space=5"); zdialog_add_widget(zd,"radio","troff","hb1","OFF","space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"check","trmissing","hb2","Show missing translations only"); zdialog_stuff(zd,"tron",1); zdialog_stuff(zd,"troff",0); zdialog_stuff(zd,"trmissing",1); zdialog_run(zd); // run dialog zdialog_wait(zd); if (zd->zstat == 1) { // [apply] zdialog_fetch(zd,"tron",tron); zdialog_fetch(zd,"trmissing",trmissing); if (tron) Ftranslate = 1; // dump all translations if (tron && trmissing) Ftranslate = 2; // dump only missing translations } else Ftranslate = 0; // v.5.0 zdialog_free(zd); if (Ftranslate) // start or continue translation mode { snprintf(pofile1,199,"%s/%s-%s.po",zlocalesdir,zappname,zlang); // installed .po file for lc_RC snprintf(pofile2,199,"%s/locales/%s-%s.po",zuserdir,zappname,zlang); // user .po file for new translations err = stat(pofile2,&statb); // look for user .po file if (err) { err = stat(pofile1,&statb); // look for installed .po file if (err) printf("No .po file found %s \n",pofile1); else { pp = strrchr(pofile2,'/'); // create /locales if needed *pp = 0; // bugfix v.5.0 mkdir(pofile2,0754); *pp = '/'; snprintf(command,399,"cp -R %s %s",pofile1,pofile2); // copy installed .po file to user err = system(command); if (! err) printf(".po file copied from %s to %s \n",pofile1,pofile2); else printf("cannot copy .po file from %s to %s \n",pofile1,pofile2); } } ZTXinit(zlang); // re-initialize translations zddump = zdialog_new("Translations",parent,"apply","cancel",null); // create dialog for translation edits zdialog_add_widget(zddump,"scrwin","scrwin","dialog",0,"expand"); zdialog_add_widget(zddump,"edit","edit","scrwin"); zdialog_resize(zddump,600,400); zdialog_run(zddump,ZTX_translation_event); trwin = zdialog_widget(zddump,"edit"); // text edit window in dialog } return; } // dialog event and completion function int ZTX_translation_event(zdialog *zd, cchar *event) // v.4.3 { using namespace ZTXnames; if (! zd->zstat) return 1; // wait for [apply] or [cancel] if (zd->zstat == 1) // [apply] ZTX_translation_update(); // update user .po file Ftranslate = 0; zdialog_free(zd); // kill edit window zddump = 0; trwin = 0; return 1; } // This function is called from ZTX() for every translation. // Add the english text and current translation to the text edit window. void ZTXnames::ZTX_translation_dump(int index) // new v.4.3 { using namespace zfuncs; using namespace ZTXnames; char outstring[ZTXmaxcc]; char *pp1, *pp2; int cc; if (strEqu(zlang,"en")) return; if (! zddump) return; // no translation edit window if (! Ftranslate) return; // translate mode OFF if (Ftranslate == 2 && // only missing translations wanted strNeq(etext[index],ttext[index])) return; // and this translation not missing strcpy(outstring,"msgid "); // msgid "english line 1 %s \n" pp1 = etext[index]; // "english line 2" // ... while (*pp1) { while (*pp1 && *pp1 != '"') pp1++; pp2 = pp1 + 1; while (*pp1 && *pp2 && *pp2 != '"') pp2++; if (*pp1 && *pp2) { cc = strlen(outstring); strncpy0(outstring+cc,pp1,pp2-pp1+2); wprintf(trwin,"%s\n",outstring); *outstring = 0; pp1 = pp2 + 1; } } strcpy(outstring,"msgstr "); // msgstr "translation line 1 %s \n" pp1 = ttext[index]; // "translation line 2" // ... while (*pp1) { while (*pp1 && *pp1 != '"') pp1++; pp2 = pp1 + 1; while (*pp1 && *pp2 && *pp2 != '"') pp2++; if (*pp1 && *pp2) { cc = strlen(outstring); strncpy0(outstring+cc,pp1,pp2-pp1+2); wprintf(trwin,"%s\n",outstring); *outstring = 0; pp1 = pp2 + 1; } } wprintf(trwin,"\n"); // blank line between pairs return; } // merge translation edit window with user .po file and clear the window void ZTXnames::ZTX_translation_update() // modified v.5.0 { using namespace zfuncs; using namespace ZTXnames; int ii, err, ftf, Nupd; char pofile1[200], pofile2[200]; char Fused[ZTXmaxent]; ftf = 1; wporec = 0; *Etext = *Ttext = 0; Nupd = 0; while (true) // scan translation edit window { if (! wporec) wporec = wscanf(trwin,ftf); if (! wporec) break; // EOF if (blank_null(wporec)) { // blank record wporec = 0; continue; } if (strnEqu(wporec,"msgid",5)) // start new english string { if (*Etext) { // two in a row printf("no translation: %s \n",Etext); *Etext = 0; } if (*Ttext) { // should not happen printf("orphan translation: %s \n",Ttext); *Ttext = 0; } wporec += 5; // get segmented text string ZTXgettext2(Etext); // "segment1 %s \n" "segment2" ... } else if (strnEqu(wporec,"msgstr",6)) // start new translation { wporec += 6; // get segmented string ZTXgettext2(Ttext); if (! *Ttext) { if (*Etext) printf("no translation: %s \n",Etext); *Etext = 0; } else if (! *Etext) { // orphan or redundant translation printf("orphan translation: %s \n",Ttext); *Ttext = 0; } } else { printf("unrecognized record: %s \n",wporec); wporec = 0; continue; } if (*Etext && *Ttext) // have an english/translation pair { for (ii = 0; ii < Ntext; ii++) // find existing (prior) entry if (strEqu(Etext,etext[ii])) break; // in translation tables if (ii == Ntext) printf("English changed, translation ignored: %s \n",Etext); else if (strNeq(Ttext,ttext[ii])) { // translation was updated zfree(ttext[ii]); ttext[ii] = strdupz(Ttext,0,"ZTX"); Nupd++; } *Etext = *Ttext = 0; } } printf("%d new translations found \n",Nupd); if (! Nupd) return; // nothing new memset(Fused,0,ZTXmaxent); // clear 'english text used' flags snprintf(pofile1,199,"%s/locales/%s-%s.po",zuserdir,zappname,zlang); // user .po file for new translations fidr = fopen(pofile1,"r"); // open .po file for read if (! fidr) { printf("cannot read translation file: %s \n",pofile1); return; } strcpy(pofile2,pofile1); // open .po.new file for write strcat(pofile2,".new"); fidw = fopen(pofile2,"w"); if (! fidw) { printf("cannot write updated translation file: %s \n",pofile2); fclose(fidr); return; } Nupd = 0; // count updates to .po file porec = 0; *Etext = *Ttext = 0; while (true) // loop each .po record { if (! porec) porec = fgets_trim(buff,ZTXmaxcc,fidr); // next record if (! porec) break; // EOF if (strnEqu(porec,"msgid",5)) { // msgid: "english 1 %s \n" "english 2" ... porec += 5; ZTXgettext(Etext); // aggregate strings } else if (strnEqu(porec,"msgstr",6)) { // msgstr: "translation %s \n" ... porec += 6; ZTXgettext(Ttext); // aggregate strings } else { fprintf(fidw,"%s\n",porec); // other record, copy to output porec = 0; continue; } if (*Etext && *Ttext) // have an english/translation pair { for (ii = 0; ii < Ntext; ii++) // find matching english in if (strEqu(Etext,etext[ii])) break; // existing translations if (ii < Ntext && ! Fused[ii]) { if (strNeq(etext[ii],ttext[ii]) && strNeq(Ttext,ttext[ii])) { // log translation added or updated printf("changed: %s \n %s \n", // v.5.0 etext[ii], ttext[ii]); strcpy(Ttext,ttext[ii]); // substitute new translation Nupd++; // actual .po updates made } Fused[ii] = 1; // mark english string as used } ZTXwritetext("msgid",Etext); // output msgid: strings ZTXwritetext("msgstr",Ttext); // and msgstr: strings *Etext = *Ttext = 0; } } fclose(fidr); fclose(fidw); if (Nupd) { // rename *.po.new to *.po err = rename(pofile2,pofile1); if (err) printf("cannot rename %s to *.po",pofile2); } else remove(pofile2); // no changes, delete *.po.new ZTXinit(zlang); // put translations in use return; } // private function // read and combine multiple 'msgid' or 'msgstr' quoted strings // output is one string with one or more quoted segments: // "text line 1 %s \n" "text line 2" ... // each segment comes from a different line in the translation edit window void ZTXnames::ZTXgettext2(char *pstring) // v.4.3 { using namespace ZTXnames; int cc, scc = 0, ftf = 0; while (true) // join multiple quoted strings { while (*wporec && *wporec != '"') wporec++; // find opening string quote if (! *wporec) { wporec = wscanf(trwin,ftf); if (! wporec) return; if (blank_null(wporec)) continue; // bugfix v.5.0 if (strnEqu(wporec,"msgid",5)) return; // end of this string if (strnEqu(wporec,"msgstr",6)) return; } ppq1 = wporec; // opening quote ppq2 = ppq1 + 1; while ((*ppq2 && *ppq2 != '"') || // find closing (non-escaped) quote (*ppq2 == '"' && *(ppq2-1) == '\\')) ppq2++; if (! *ppq2) { wporec = 0; return; } cc = ppq2 - ppq1 + 1; // min. case is "" if (cc + 1 + scc >= ZTXmaxcc) printf("string is too long: %s \n",pstring); else { strncpy0(pstring+scc,ppq1,cc+1); // accum. substrings, minus quotes scc += cc; } wporec = ppq2 + 1; } return; } // private function // write quoted seqmented string to output .po file, 1 record per segment // msgid "english string segment 1 %s \n" // "english string segment 2 \n" // ... void ZTXnames::ZTXwritetext(cchar *header, char *text) { char *pp1, *pp2; int cc, ftf; char segment[ZTXmaxcc]; ftf = 1; pp1 = text; while (true) { while (*pp1 && *pp1 != '"') pp1++; // opening quote if (! *pp1) break; pp2 = pp1 + 1; while ((*pp2 && *pp2 != '"') || // find closing (non-escaped) quote (*pp2 == '"' && *(pp2-1) == '\\')) pp2++; if (! *pp2) break; cc = pp2 - pp1 + 1; if (cc >= ZTXmaxcc) cc = ZTXmaxcc - 1; strncpy0(segment,pp1,cc+1); if (ftf) fprintf(fidw,"%s %s\n",header,segment); else fprintf(fidw,"%s\n",segment); ftf = 0; pp1 = pp2 + 1; } return; } /**************************************************************************/ // Output text to a popup window. action: open, write, top, close // Window is left on screen until user destroys it with [x] button // or caller closes it with "close" action. int write_popup_text(cchar *action, cchar *text, int ww, int hh, GtkWidget *parent) { static GtkWidget *mWin = 0, *mVbox, *mScroll; static GtkWidget *mLog = 0; static PangoFontDescription *monofont = 0; if (! monofont) monofont = pango_font_description_from_string("monospace 9"); if (strEqu(action,"open")) { if (mWin) gtk_widget_destroy(mWin); // only one at a time if (! ww) ww = 400; if (! hh) hh = 300; mWin = gtk_window_new(GTK_WINDOW_TOPLEVEL); // create main window gtk_window_set_title(GTK_WINDOW(mWin),text); gtk_window_set_default_size(GTK_WINDOW(mWin),ww,hh); if (parent) // parent added gtk_window_set_transient_for(GTK_WINDOW(mWin),GTK_WINDOW(parent)); if (parent) gtk_window_set_position(GTK_WINDOW(mWin),GTK_WIN_POS_CENTER_ON_PARENT); else gtk_window_set_position(GTK_WINDOW(mWin),GTK_WIN_POS_MOUSE); mVbox = gtk_vbox_new(0,0); // vertical packing box gtk_container_add(GTK_CONTAINER(mWin),mVbox); // add to main window mScroll = gtk_scrolled_window_new(0,0); // scrolled window gtk_box_pack_end(GTK_BOX(mVbox),mScroll,1,1,0); // add to main window mVbox gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(mScroll), GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); mLog = gtk_text_view_new(); // text edit window gtk_container_add(GTK_CONTAINER(mScroll),mLog); // add to scrolled window gtk_widget_modify_font(mLog,monofont); // set small monospaced font G_SIGNAL(mWin,"destroy",write_popup_text,"destroypop"); // connect window destroy event gtk_widget_show_all(mWin); // show window gtk_window_present(GTK_WINDOW(mWin)); if (! parent) gtk_window_set_keep_above(GTK_WINDOW(mWin),1); zfuncs::open_popup_windows++; // v.4.7 } if (strEqu(action,"write")) // add text to window if (mWin) wprintf(mLog," %s\n",text); if (strEqu(action,"top")) // scroll to top line v.4.0 if (mWin) wscroll(mLog,1); if (strEqu(action,"close")) { // close window if (mWin) gtk_widget_destroy(mWin); mWin = 0; } if (text && strEqu(text,"destroypop")) { // "destroy" signal from [x] zfuncs::open_popup_windows--; // v.4.7 mWin = 0; } zmainloop(); // v.4.7 return 0; } /**************************************************************************/ // execute a command and show the output in a scrolling popup window int popup_command(cchar *command, int ww, int hh, GtkWidget *parent) // use write_popup_text() { char *buff; int err, contx = 0; write_popup_text("open",command,ww,hh,parent); // bugfix while ((buff = command_output(contx,command))) { write_popup_text("write",buff); zfree(buff); } write_popup_text("top",0); // back to top of window v.4.0 err = command_status(contx); return err; } /**************************************************************************/ // display message box and wait for user acknowledgement void zmessageACK(GtkWidget *parent, cchar *pMess, ... ) { va_list arglist; char message[400]; zdialog *zd; GtkWidget *widget; va_start(arglist,pMess); vsnprintf(message,400,pMess,arglist); va_end(arglist); zd = zdialog_new("",parent," X ",null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab1","hb1",message,"space=5"); zdialog_resize(zd,200,0); widget = zdialog_widget(zd,"dialog"); // make modal v.4.4 gtk_window_set_modal(GTK_WINDOW(widget),1); zdialog_run(zd); zdialog_wait(zd); zdialog_free(zd); return; } /**************************************************************************/ // log error message to STDOUT as well as message box and user OK void zmessLogACK(GtkWidget *parent, cchar *pMess, ...) { va_list arglist; char message[200]; va_start(arglist,pMess); vsnprintf(message,200,pMess,arglist); va_end(arglist); printf("%s \n",message); zmessageACK(parent,message); return; } /**************************************************************************/ // display message box and wait for user Yes or No response int zmessageYN(GtkWidget *parent, cchar *pMess, ... ) { va_list arglist; char message[400]; zdialog *zd; int zstat; GtkWidget *widget; va_start(arglist,pMess); vsnprintf(message,400,pMess,arglist); va_end(arglist); zd = zdialog_new("message",parent,ZTX("Yes"),ZTX("No"),null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab1","hb1",message,"space=5"); zdialog_resize(zd,200,0); widget = zdialog_widget(zd,"dialog"); // make modal v.4.4 gtk_window_set_modal(GTK_WINDOW(widget),1); zdialog_run(zd); zstat = zdialog_wait(zd); zdialog_free(zd); if (zstat == 1) return 1; return 0; } /**************************************************************************/ // Display message box with message and button to display help topic char *zmessage_help_topic = 0; void zmessage_help(GtkWidget *parent, cchar *topic, cchar *pmess, ... ) { int zmessage_help_event(zdialog *zd, cchar *event); va_list arglist; char message[400]; zdialog *zd; va_start(arglist,pmess); vsnprintf(message,400,pmess,arglist); va_end(arglist); if (zmessage_help_topic) zfree(zmessage_help_topic); zmessage_help_topic = strdupz(topic,0,"zmessage_help"); zd = zdialog_new("context help",parent,"Help"," X ",null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab1","hb1",message,"space=5"); zdialog_resize(zd,200,0); zdialog_run(zd,zmessage_help_event); zdialog_wait(zd); zdialog_free(zd); return; } int zmessage_help_event(zdialog *zd, cchar *event) { if (zd->zstat == 1) { showz_userguide(zmessage_help_topic); zd->zstat = 0; } return 0; } /**************************************************************************/ // display message indefinitely until timeout or user cancel // or caller kills it with zdialog_free() zdialog * zmessage_post(GtkWidget *parent, int seconds, cchar *pMess, ... ) { int zmessage_post_timeout(zdialog *zd); int zmessage_post_event(zdialog *zd, cchar *event); va_list arglist; char message[400]; static zdialog *zd; va_start(arglist,pMess); vsnprintf(message,400,pMess,arglist); va_end(arglist); zd = zdialog_new("message",parent,ZTX("cancel"),null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab1","hb1",message,"space=5"); zdialog_run(zd,zmessage_post_event); if (seconds) // seconds added v.4.3 g_timeout_add_seconds(seconds,(GSourceFunc) zmessage_post_timeout,zd); return zd; } int zmessage_post_timeout(zdialog *zd) { if (zd && zd->zstat == 0) zdialog_free(zd); return 0; } int zmessage_post_event(zdialog *zd, cchar *event) { if (zd && zd->zstat) zdialog_free(zd); return 0; } /**************************************************************************/ // get text input from a popup dialog // returned text is subject for zfree() char * zdialog_text(GtkWidget *parent, cchar *title, cchar *inittext) { zdialog *zd; int zstat; char *text; GtkWidget *widget; zd = zdialog_new(title,parent,"OK",ZTX("cancel"),null); zdialog_add_widget(zd,"frame","fred","dialog"); zdialog_add_widget(zd,"edit","edit","fred"); if (inittext) zdialog_stuff(zd,"edit",inittext); zdialog_resize(zd,200,0); widget = zdialog_widget(zd,"dialog"); // make modal v.4.4 gtk_window_set_modal(GTK_WINDOW(widget),1); zdialog_run(zd); zstat = zdialog_wait(zd); if (zstat == 1) text = (char *) zdialog_get_data(zd,"edit"); else text = 0; if (text) text = strdupz(text,0,"zdialog_text"); zdialog_free(zd); return text; } /**************************************************************************/ // Display a dialog with a message and 1-5 choice buttons. // Returns choice 1-N corresponding to button selected. // Parent window may be NULL. // List of buttons must be NULL terminated. int zdialog_choose(cchar *title, GtkWidget *parent, cchar *message, ...) // new v.4.7 { zdialog *zd; va_list arglist; int ii, zstat, Nbutts; cchar *butts[6]; va_start(arglist,message); for (ii = 0; ii < 5; ii++) { butts[ii] = va_arg(arglist,cchar *); if (! butts[ii]) break; } Nbutts = ii; if (! Nbutts) zappcrash("zdialog_choose(), no buttons"); repeat: zd = zdialog_new(title,parent,butts[0],butts[1],butts[2],butts[3],butts[4],null); zdialog_add_widget(zd,"hbox","hbmess","dialog","space=5"); zdialog_add_widget(zd,"label","labmess","hbmess",message,"space=5"); zdialog_run(zd); zstat = zdialog_wait(zd); zdialog_free(zd); if (zstat < 1) goto repeat; return zstat; } /**************************************************************************/ // File chooser dialog for one or more files // // Action: "open" select an existing file // "openN" select multiple existing files // "save" select an existing or new file // "folder" select existing folder // "create folder" select existing or new folder // // buttx: "hidden" add button to toggle display of hidden files // "quality" add button to set JPG file save quality // optional, default = null // // Returns a list of filespecs terminated with null. // Memory for returned list and returned files are subjects for zfree(); // version to select only 1 file char * zgetfile1(cchar *title, cchar *action, cchar *initfile, cchar *buttx) { if (strEqu(action,"openN")) zappcrash("zgetfile1 called with openN"); char **flist = zgetfileN(title,action,initfile,buttx); if (! flist) return 0; char *file = *flist; zfree(flist); return file; } // select one or multiple files // overhauled char ** zgetfileN(cchar *title, cchar *action, cchar *initfile, cchar *buttx) { using namespace zfuncs; void zgetfile_preview(GtkWidget *dialog, GtkWidget *pvwidget); // private functions void zgetfile_KBkey(GtkWidget *dialog, GdkEventKey *event); void zgetfile_newfolder(GtkFileChooser *dialog, void *); GtkFileChooserAction fcact = GTK_FILE_CHOOSER_ACTION_OPEN; GtkWidget *dialog; GtkWidget *pvwidget = gtk_image_new(); GSList *gslist = 0; cchar *button1 = 0, *buttxx = 0; char *pdir, *pfile; int ii, err, NF, setfname = 0; int fcstat, bcode = 0, qnum, hide = 0; char *qual, *file1, *file2, **flist = 0; struct stat fstat; zthreadcrash(); // thread usage not allowed if (strEqu(action,"open")) { fcact = GTK_FILE_CHOOSER_ACTION_OPEN; button1 = ZTX("open"); } if (strEqu(action,"openN")) { fcact = GTK_FILE_CHOOSER_ACTION_OPEN; button1 = ZTX("choose"); } if (strEqu(action,"save")) { fcact = GTK_FILE_CHOOSER_ACTION_SAVE; button1 = ZTX("save"); setfname = 1; } if (strEqu(action,"folder")) { fcact = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; button1 = ZTX("open folder"); } if (strEqu(action,"create folder")) { fcact = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER; button1 = ZTX("create folder"); setfname = 1; } if (buttx) { if (strnEqu(buttx,"hidden",6)) { // generate text for translation buttxx = ZTX("hidden"); // bugfix v.4.4 bcode = 103; } if (strEqu(buttx,"quality")) { buttxx = ZTX("quality"); bcode = 104; } } dialog = gtk_file_chooser_dialog_new(title, null, fcact, // create file selection dialog button1, GTK_RESPONSE_ACCEPT, ZTX("cancel"), GTK_RESPONSE_CANCEL, buttxx, bcode, null); gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog),pvwidget); G_SIGNAL(dialog,"update-preview",zgetfile_preview,pvwidget); // create preview for selected file G_SIGNAL(dialog,"key-release-event",zgetfile_KBkey,0); // respond to F1 help key gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_MOUSE); // put dialog at mouse position gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog),0); // default: no show hidden if (strEqu(action,"save")) // overwrite confirmation gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog),1); if (strEqu(action,"openN")) gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),1); // select multiple files if (initfile) { // pre-select filespec err = stat(initfile,&fstat); if (err) { pdir = strdupz(initfile); // non-existent file pfile = strrchr(pdir,'/'); if (pfile && pfile > pdir) { *pfile++ = 0; // set folder name gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),pdir); } if (setfname) // set new file name v.4.7 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),pfile); zfree(pdir); } else if (S_ISREG(fstat.st_mode)) // select given file gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),initfile); else if (S_ISDIR(fstat.st_mode)) // select given folder gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),initfile); } gtk_widget_show_all(dialog); while (true) { fcstat = gtk_dialog_run(GTK_DIALOG(dialog)); // run dialog, get status button if (fcstat == 103) { // show/hide hidden files hide = gtk_file_chooser_get_show_hidden(GTK_FILE_CHOOSER(dialog)); hide = 1 - hide; gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog),hide); } else if (fcstat == 104) { // get JPG quality parameter while (true) { qual = zdialog_text(null,ZTX("JPG quality 0-100"),JPGquality); if (! qual) break; // cancel = no change err = convSI(qual,qnum,0,100); zfree(qual); if (err) continue; // enforce 0-100 snprintf(JPGquality,4,"%d",qnum); break; } } else break; // some other button } if (fcstat == GTK_RESPONSE_ACCEPT) { gslist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); if (! gslist) goto fcreturn; NF = g_slist_length(gslist); // no. selected files if (! NF) goto fcreturn; flist = (char **) zmalloc((NF+1)*sizeof(char *),"zgetfile"); // allocate returned list for (ii = 0; ii < NF; ii++) { // process selected files file1 = (char *) g_slist_nth_data(gslist,ii); if (strlen(file1) >= maxfcc) file1 = (char *) "ridiculously long filespec"; file2 = strdupz(file1,0,"zgetfile"); // re-allocate memory g_free(file1); flist[ii] = file2; } flist[ii] = 0; // EOL marker } fcreturn: if (gslist) g_slist_free(gslist); gtk_widget_destroy(dialog); return flist; } // zgetfile private function - get preview images for image files void zgetfile_preview(GtkWidget *dialog, GtkWidget *pvwidget) { using namespace zfuncs; GdkPixbuf *thumbnail; char *filename; filename = gtk_file_chooser_get_preview_filename(GTK_FILE_CHOOSER(dialog)); if (! filename) { gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(dialog),0); return; } thumbnail = get_thumbnail(filename,192); // use 192x192 pixels g_free(filename); if (thumbnail) { gtk_image_set_from_pixbuf(GTK_IMAGE(pvwidget),thumbnail); gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(dialog),1); g_object_unref(thumbnail); } else gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(dialog),0); return; } // zgetfile private function - respond to F1 key // zfuncs::F1_help_topic must be pre-loaded by caller if needed. void zgetfile_KBkey(GtkWidget *dialog, GdkEventKey *event) { int KBkey = event->keyval; if (KBkey == GDK_F1) showz_userguide(zfuncs::F1_help_topic); return; } /************************************************************************** Programs for printing an image file new v.4.7 HPLIP problem: Setting paper size was made less flexible. GtkPrintSettings paper size must agree with the one in the current printer setup. This can only be set in the printer setup dialog, not in the application. Also the print size (width, height) comes from the chosen paper size and cannot be changed in the application. Print margins can be changed to effect printing a smaller or shifted image on a larger paper size. print_image_paper_setup() Do a print paper format selection, after which the page width, height and orientation are available to the caller. Units are CM. (paper width and height are reversed for landscape orientation) print_image_margins_setup() Optionally set the print margins. If not done they are zero (or printer-dependent minimum). Afterwards the margins are available to the caller. Units are CM. print_image_file(cchar *imagefile) Print the image file on the printer and paper size determined by a prior call to print_image_paper_setup. ***************************************************************************/ namespace print_image { #define MM GTK_UNIT_MM #define PRINTOP GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG #define PORTRAIT GTK_PAGE_ORIENTATION_PORTRAIT #define LANDSCAPE GTK_PAGE_ORIENTATION_LANDSCAPE #define QUALITY GTK_PRINT_QUALITY_HIGH GtkPageSetup *priorpagesetup = 0; GtkPageSetup *pagesetup; GtkPrintSettings *printsettings = 0; GtkPrintOperation *printop; GtkPageOrientation orientation = PORTRAIT; GdkPixbuf *pixbuf; cchar *printer = 0; double width = 21.0, height = 29.7; // paper size, CM (default A4 portrait) double margins[4] = { 0, 0, 0, 0 }; // print margins, CM (default none) int landscape = 0; // true if landscape } void print_image_paper_setup(GtkWidget *parent) { using namespace print_image; char printsettingsfile[200], pagesetupfile[200]; snprintf(printsettingsfile,200,"%s/printsettings",get_zuserdir()); snprintf(pagesetupfile,200,"%s/pagesetup",get_zuserdir()); if (! printsettings) { // start with prior print settings printsettings = gtk_print_settings_new_from_file(printsettingsfile,0); if (! printsettings) printsettings = gtk_print_settings_new(); } if (! priorpagesetup) { // start with prior page setup priorpagesetup = gtk_page_setup_new_from_file(pagesetupfile,0); if (! priorpagesetup) priorpagesetup = gtk_page_setup_new(); } pagesetup = gtk_print_run_page_setup_dialog // select printer, paper size (GTK_WINDOW(parent),priorpagesetup,printsettings); // and orientation if (! pagesetup) return; g_object_unref(priorpagesetup); // save for next call priorpagesetup = pagesetup; width = gtk_page_setup_get_paper_width(pagesetup,MM); // save paper width, height height = gtk_page_setup_get_paper_height(pagesetup,MM); width = width / 10; // use cm units height = height / 10; orientation = gtk_print_settings_get_orientation(printsettings); // save orientation if (orientation == LANDSCAPE) landscape = 1; else landscape = 0; gtk_print_settings_set_quality(printsettings,QUALITY); // set high quality 300 dpi gtk_print_settings_set_resolution(printsettings,300); gtk_print_settings_to_file(printsettings,printsettingsfile,0); // save print settings to file gtk_page_setup_to_file(pagesetup,pagesetupfile,0); // save print settings to file return; } void print_image_margins_setup(GtkWidget *parent) { using namespace print_image; zdialog *zd; int zstat; zd = zdialog_new(ZTX("margins"),parent,ZTX("done"),ZTX("cancel"),0); // build dialog zdialog_add_widget(zd,"hbox","hbmlab","dialog",0,"homog"); // top bottom left right zdialog_add_widget(zd,"vbox","vbmarg","hbmlab",0,"space=3"); // margins [___] [___] [___] [___] zdialog_add_widget(zd,"vbox","vbtop","hbmlab",0,"space=3"); zdialog_add_widget(zd,"vbox","vbbottom","hbmlab",0,"space=3"); zdialog_add_widget(zd,"vbox","vbleft","hbmlab",0,"space=3"); zdialog_add_widget(zd,"vbox","vbright","hbmlab",0,"space=3"); zdialog_add_widget(zd,"label","space","vbmarg"," "); zdialog_add_widget(zd,"label","labtop","vbtop",ZTX("top")); zdialog_add_widget(zd,"label","labbot","vbbottom",ZTX("bottom")); zdialog_add_widget(zd,"label","lableft","vbleft",ZTX("left")); zdialog_add_widget(zd,"label","labright","vbright",ZTX("right")); zdialog_add_widget(zd,"label","labmarg","vbmarg",ZTX("margins"),"space=3"); zdialog_add_widget(zd,"spin","mtop","vbtop","0|3|0.1|0"); zdialog_add_widget(zd,"spin","mbottom","vbbottom","0|3|0.1|0"); zdialog_add_widget(zd,"spin","mleft","vbleft","0|3|0.1|0"); zdialog_add_widget(zd,"spin","mright","vbright","0|3|0.1|0"); zdialog_stuff(zd,"mtop",margins[0]); // stuff prior print margins zdialog_stuff(zd,"mbottom",margins[1]); zdialog_stuff(zd,"mleft",margins[2]); zdialog_stuff(zd,"mright",margins[3]); zdialog_run(zd); // run dialog zstat = zdialog_wait(zd); // wait for completion if (zstat != 1) { // user canceled zdialog_free(zd); return; } zdialog_fetch(zd,"mtop",margins[0]); // set print margins zdialog_fetch(zd,"mbottom",margins[1]); zdialog_fetch(zd,"mleft",margins[2]); zdialog_fetch(zd,"mright",margins[3]); zdialog_free(zd); // kill dialog gtk_page_setup_set_top_margin(pagesetup,10*margins[0],MM); // set page margins, mm units gtk_page_setup_set_bottom_margin(pagesetup,10*margins[1],MM); gtk_page_setup_set_left_margin(pagesetup,10*margins[2],MM); gtk_page_setup_set_right_margin(pagesetup,10*margins[3],MM); return; } void print_image_file(cchar *imagefile) { using namespace print_image; void print_image_page(GtkPrintOperation *, GtkPrintContext *, int page); GtkPrintOperationResult printstat; GError *gerror = 0; pixbuf = gdk_pixbuf_new_from_file(imagefile,&gerror); // read image file if (! pixbuf) { zmessageACK(null,gerror->message); return; } printop = gtk_print_operation_new(); // print operation gtk_print_operation_set_default_page_setup(printop,pagesetup); gtk_print_operation_set_print_settings(printop,printsettings); gtk_print_operation_set_n_pages(printop,1); g_signal_connect(printop,"draw-page",G_CALLBACK(print_image_page),0); // start print printstat = gtk_print_operation_run(printop,PRINTOP,0,0); if (printstat == GTK_PRINT_OPERATION_RESULT_ERROR) { gtk_print_operation_get_error(printop,&gerror); zmessageACK(null,gerror->message); } g_object_unref(printop); return; } // draw the graphics for the print page // rescale with cairo: print resolution of 300 dpi is no longer ignored void print_image_page(GtkPrintOperation *printop, GtkPrintContext *printcontext, int page) { using namespace print_image; cairo_t *cairocontext; double iww, ihh, pww, phh, scale; pww = gtk_print_context_get_width(printcontext); // print context size phh = gtk_print_context_get_height(printcontext); iww = gdk_pixbuf_get_width(pixbuf); // image size ihh = gdk_pixbuf_get_height(pixbuf); scale = pww / iww; // rescale to fit page if (phh / ihh < scale) scale = phh / ihh; cairocontext = gtk_print_context_get_cairo_context(printcontext); // use cairo to rescale cairo_translate(cairocontext,0,0); cairo_scale(cairocontext,scale,scale); gdk_cairo_set_source_pixbuf(cairocontext,pixbuf,0,0); cairo_paint(cairocontext); return; } /**************************************************************************/ // connect a user callback function to a window drag-drop event void drag_drop_connect(GtkWidget *window, drag_drop_func *ufunc) { int drag_drop_connect2(GtkWidget *, void *, int, int, void *, int, int, void *); char string[] = "STRING"; GtkTargetEntry file_drop_target = { string, 0, 0 }; gtk_drag_dest_set(window, GTK_DEST_DEFAULT_ALL, &file_drop_target, 1, GDK_ACTION_COPY); G_SIGNAL(window, "drag-data-received", drag_drop_connect2, ufunc); gtk_drag_dest_add_uri_targets(window); // accept URI (file) drop return; } // private function // get dropped file, clean escapes, pass to user function // passed filespec is subject for zfree() int drag_drop_connect2(GtkWidget *, void *, int mpx, int mpy, void *sdata, int, int, void *ufunc) { char * drag_drop_unescape(cchar *escaped_string); drag_drop_func *ufunc2; char *text, *text2, *file, *file2; int cc; text = (char *) ((GtkSelectionData *) sdata)->data; ufunc2 = (drag_drop_func *) ufunc; if (strstr(text,"file://")) // text is a filespec { file = strdupz(text+7); // get rid of junk added by GTK cc = strlen(file); while (file[cc-1] < ' ') cc--; file[cc] = 0; file2 = drag_drop_unescape(file); // clean %xx escapes from Nautilus zfree(file); ufunc2(mpx,mpy,file2); // pass file to user function } else { text2 = strdupz(text,0,"drag_drop"); ufunc2(mpx,mpy,text2); } return 1; } // private function // Clean %xx escapes from strange Nautilus drag-drop file names char * drag_drop_unescape(cchar *inp) { int drag_drop_convhex(char ch); char inch, *out, *outp; int nib1, nib2; out = zmalloc(strlen(inp)+1,"drag_drop"); outp = out; while ((inch = *inp++)) { if (inch == '%') { nib1 = drag_drop_convhex(*inp++); nib2 = drag_drop_convhex(*inp++); *outp++ = nib1 << 4 | nib2; } else *outp++ = inch; } *outp = 0; return out; } // private function - convert character 0-F to number 0-15 int drag_drop_convhex(char ch) { if (ch >= '0' && ch <= '9') return ch - '0'; if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10; if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10; return ch; } /************************************************************************** Miscellaneous GDK/GTK functions ***************************************************************************/ // Get thumbnail image for given image file. // Returned thumbnail belongs to caller: g_object_unref() is necessary. GdkPixbuf * get_thumbnail(char *fpath, int size) // v.5.0 { using namespace zfuncs; GdkPixbuf *thumbpxb; GError *gerror = 0; int err; char *bpath; struct stat statf; zthreadcrash(); // thread usage not allowed err = stat(fpath,&statf); // fpath status info if (err) return 0; if (S_ISDIR(statf.st_mode)) { // if directory, return folder image bpath = zmalloc(500); strncatv(bpath,499,zicondir,"/folder256.png",null); thumbpxb = gdk_pixbuf_new_from_file_at_size(bpath,size,size,&gerror); zfree(bpath); return thumbpxb; } thumbpxb = gdk_pixbuf_new_from_file_at_size(fpath,size,size,&gerror); return thumbpxb; // return pixbuf to caller } // make a cursor from a graphic file in application's icon directory GdkCursor * zmakecursor(cchar *iconfile) { using namespace zfuncs; GError *gerror = 0; GdkPixbuf *pixbuf; GdkDisplay *display; GdkCursor *cursor = 0; char iconpath[200]; zthreadcrash(); // thread usage not allowed display = gdk_display_get_default(); *iconpath = 0; strncatv(iconpath,199,zicondir,"/",iconfile,null); pixbuf = gdk_pixbuf_new_from_file(iconpath,&gerror); if (pixbuf && display) cursor = gdk_cursor_new_from_pixbuf(display,pixbuf,0,0); else printf("%s \n",gerror->message); return cursor; } // move the mouse pointer to given position int gdk_window_move_pointer(GdkWindow *window, int px, int py) // v.5.0 { GdkDisplay *display; GdkScreen *screen; int rpx, rpy; display = gdk_drawable_get_display(GDK_DRAWABLE(window)); if (! display) return 0; screen = gdk_drawable_get_screen(GDK_DRAWABLE(window)); if (! screen) return 0; gdk_window_get_root_coords(window,px,py,&rpx,&rpy); gdk_display_warp_pointer(display,screen,rpx,rpy); return 1; } /************************************************************************** GdkPixbuf * gdk_pixbuf_rotate(GdkPixbuf *pixbuf, double angle, int acolor) Rotate a pixbuf through an arbitrary angle (degrees). The returned image has the same size as the original, but the pixbuf envelope is increased to accomodate the rotated original (e.g. a 100x100 pixbuf rotated 45 deg. needs a 142x142 pixbuf). Pixels added around the rotated image have all RGB values = acolor. Angle is in degrees. Positive direction is clockwise. Pixbuf must have 8 bits per channel and 3 or 4 channels. Loss of resolution is about 1/2 pixel. Speed is about 28 million pixels/sec. on my 3.3 GHz CPU. // v.5.0 (i.e. a 10 megapix image needs about 10/28 = 0.36 seconds) NULL is returned if the function fails for one of the following: - pixbuf not 8 bits/channel or < 3 channels - unable to create output pixbuf (lack of memory?) Algorithm: create output pixbuf big enough for rotated input pixbuf compute coefficients for affine transform loop all output pixels get next output pixel (px2,py2) convert to input pixel (px1,py1) using affine transform if outside of pixmap output pixel = black continue for 4 input pixels based at (px0,py0) = (int(px1),int(py1)) compute overlap (0 to 1) with (px1,py1) sum RGB values * overlap output aggregate RGB to pixel (px2,py2) ***/ GdkPixbuf * gdk_pixbuf_rotate(GdkPixbuf *pixbuf1, double angle, int acolor) { typedef unsigned char *pixel; // 3 RGB values, 0-255 each GdkPixbuf *pixbuf2; GdkColorspace color; int nch, nbits, alpha; int ww1, hh1, rs1, ww2, hh2, rs2; int px2, py2, px0, py0; pixel ppix1, ppix2, pix0, pix1, pix2, pix3; double px1, py1; double f0, f1, f2, f3, red, green, blue, tran = 0; double a, b, d, e, ww15, hh15, ww25, hh25; double pi = 3.141593; zthreadcrash(); // thread usage not allowed nch = gdk_pixbuf_get_n_channels(pixbuf1); nbits = gdk_pixbuf_get_bits_per_sample(pixbuf1); if (nch < 3) return 0; // must have 3+ channels (colors) if (nbits != 8) return 0; // must be 8 bits per channel color = gdk_pixbuf_get_colorspace(pixbuf1); // get input pixbuf1 attributes alpha = gdk_pixbuf_get_has_alpha(pixbuf1); ww1 = gdk_pixbuf_get_width(pixbuf1); hh1 = gdk_pixbuf_get_height(pixbuf1); rs1 = gdk_pixbuf_get_rowstride(pixbuf1); while (angle < -180) angle += 360; // normalize, -180 to +180 while (angle > 180) angle -= 360; angle = angle * pi / 180; // radians, -pi to +pi if (fabs(angle) < 0.001) { // bugfix 0.01 >> 0.001 pixbuf2 = gdk_pixbuf_copy(pixbuf1); // angle is zero within my precision return pixbuf2; } ww2 = int(ww1*fabs(cos(angle)) + hh1*fabs(sin(angle))); // rectangle containing rotated image hh2 = int(ww1*fabs(sin(angle)) + hh1*fabs(cos(angle))); pixbuf2 = gdk_pixbuf_new(color,alpha,nbits,ww2,hh2); // create output pixbuf2 if (! pixbuf2) return 0; rs2 = gdk_pixbuf_get_rowstride(pixbuf2); ppix1 = gdk_pixbuf_get_pixels(pixbuf1); // input pixel array ppix2 = gdk_pixbuf_get_pixels(pixbuf2); // output pixel array ww15 = 0.5 * ww1; hh15 = 0.5 * hh1; ww25 = 0.5 * ww2; hh25 = 0.5 * hh2; a = cos(angle); // affine transform coefficients b = sin(angle); d = - sin(angle); e = cos(angle); for (py2 = 0; py2 < hh2; py2++) // loop through output pixels for (px2 = 0; px2 < ww2; px2++) { px1 = a * (px2 - ww25) + b * (py2 - hh25) + ww15; // (px1,py1) = corresponding py1 = d * (px2 - ww25) + e * (py2 - hh25) + hh15; // point within input pixels px0 = int(px1); // pixel containing (px1,py1) py0 = int(py1); if (px1 < 0 || px0 >= ww1-1 || py1 < 0 || py0 >= hh1-1) { // if outside input pixel array pix2 = ppix2 + py2 * rs2 + px2 * nch; // output is acolor pix2[0] = pix2[1] = pix2[2] = acolor; continue; } pix0 = ppix1 + py0 * rs1 + px0 * nch; // 4 input pixels based at (px0,py0) pix1 = pix0 + rs1; pix2 = pix0 + nch; pix3 = pix0 + rs1 + nch; f0 = (px0+1 - px1) * (py0+1 - py1); // overlap of (px1,py1) f1 = (px0+1 - px1) * (py1 - py0); // in each of the 4 pixels f2 = (px1 - px0) * (py0+1 - py1); f3 = (px1 - px0) * (py1 - py0); red = f0 * pix0[0] + f1 * pix1[0] + f2 * pix2[0] + f3 * pix3[0]; // sum the weighted inputs green = f0 * pix0[1] + f1 * pix1[1] + f2 * pix2[1] + f3 * pix3[1]; blue = f0 * pix0[2] + f1 * pix1[2] + f2 * pix2[2] + f3 * pix3[2]; if (alpha) tran = f0 * pix0[3] + f1 * pix1[3] + f2 * pix2[3] + f3 * pix3[3]; // 4th color = alpha if (red == acolor && green == acolor && blue == acolor) { // avoid acolor in image if (blue == 0) blue = 1; else blue--; } pix2 = ppix2 + py2 * rs2 + px2 * nch; // output pixel pix2[0] = int(red); pix2[1] = int(green); pix2[2] = int(blue); if (alpha) pix2[3] = int(tran); // bugfix } return pixbuf2; } /************************************************************************** parameter management functions ***************************************************************************/ struct t_parmlist { // parameter list in memory int max; // max parameter count int count; // actual parameter count char **name; // pointer to names (list of char *) double *value; // pointer to values (list of double) } parmlist; int parmlistvalid = 0; // flag char zparmfile[maxfcc]; // last used parm file // initialize parameter list - must be called first int initParmlist(int max) { if (! parmlistvalid) { // start with default parms file strcpy(zparmfile,get_zuserdir()); strcat(zparmfile,"/parameters"); // /home/user/.appname/parameters } if (parmlistvalid) { // delete old parms delete [] parmlist.name; delete [] parmlist.value; } parmlist.max = max; parmlist.count = 0; char **names = new char*[max]; // allocate max pointers for names double *values = new double[max]; // allocate max doubles for values parmlist.name = names; parmlist.value = values; parmlistvalid = 1; return 0; } // Load user parameters if the file exists, else initialize the // user parameters file from default application parameters. int initz_userParms() { if (! parmlistvalid) zappcrash("parmlistvalid = 0"); int np = loadParms("parameters"); if (! np) { saveParms("parameters"); zmessageACK(null,ZTX("Initial parameters file created. \n" "Inspect and revise if necessary.")); } return np; } // load parameters from a file, with file selection dialog int loadParms() { char *pfile; int np; if (! parmlistvalid) zappcrash("parmlistvalid = 0"); pfile = zgetfile1(ZTX("load parameters from a file"),"open",zparmfile,"hidden"); if (! pfile) return 0; np = loadParms(pfile); zfree(pfile); return np; } // load parameters from a file // returns no. parameters loaded int loadParms(cchar *pfile) { FILE *fid; int Nth, np1, np2 = 0, err; char buff[100], *fgs, *pp; cchar *pname, *pvalue; double dvalue; if (! parmlistvalid) zappcrash("parmlistvalid = 0"); if (! pfile) pfile = zparmfile; if (*pfile != '/') { // if parm file name only, pp = (char *) strrchr(zparmfile,'/'); // make complete absolute path if (pp) strcpy(pp+1,pfile); // in same directory as prior pfile = zparmfile; } fid = fopen(pfile,"r"); if (! fid) return 0; // bad file strncpy0(zparmfile,pfile,maxfcc-1); // set current parm file while (true) // read file { fgs = fgets_trim(buff,99,fid,1); if (! fgs) break; // EOF pp = strchr(buff,'#'); // eliminate comments if (pp) *pp = 0; Nth = 1; // parse parm name, value pname = strField(buff,' ',Nth++); if (! pname) continue; pvalue = strField(buff,' ',Nth); if (! pvalue) continue; err = convSD(pvalue,dvalue); if (err) continue; np1 = setParm(pname,dvalue); // set the parameter if (! np1) continue; np2++; } fclose(fid); // close file return np2; // return parameter count } // save parameters to a file, with file selection dialog int saveParms() { char *pfile; int np; if (! parmlistvalid) zappcrash("parmlistvalid = 0"); pfile = zgetfile1(ZTX("save parameters to a file"),"save",zparmfile,"hidden"); if (! pfile) return 0; np = saveParms(pfile); zfree(pfile); return np; } // save parameters to a file int saveParms(cchar *pfile) { FILE *fid; int np; char *pp; if (! parmlistvalid) zappcrash("parmlistvalid = 0"); if (*pfile != '/') { // if parm file name only, pp = (char *) strrchr(zparmfile,'/'); // make complete absolute path if (pp) strcpy(pp+1,pfile); // in same directory as prior pfile = zparmfile; } fid = fopen(pfile,"w"); if (! fid) { zmessageACK(null,ZTX("cannot open file %s"),pfile); return 0; } strncpy0(zparmfile,pfile,999); for (np = 0; np < parmlist.count; np++) fprintf(fid," \"%s\" %.12g \n",parmlist.name[np],parmlist.value[np]); fclose(fid); return np; } // create a new paramater or change value of existing parameter int setParm(cchar *parmname, double parmval) { int ii, cc; char *ppname; if (! parmlistvalid) zappcrash("parmlistvalid = 0"); for (ii = 0; ii < parmlist.count; ii++) if (strEqu(parmlist.name[ii],parmname)) break; if (ii == parmlist.max) return 0; if (ii == parmlist.count) { parmlist.count++; cc = strlen(parmname); ppname = new char[cc+1]; strTrim(ppname,parmname); parmlist.name[ii] = ppname; } parmlist.value[ii] = parmval; return parmlist.count; } // get parameter value from parameter name double getParm(cchar *parmname) { if (! parmlistvalid) zappcrash("parmlistvalid = 0"); for (int ii = 0; ii < parmlist.count; ii++) { if (strNeq(parmlist.name[ii],parmname)) continue; return parmlist.value[ii]; } return NAN; } // get Nth parameter name (zero-based) char * getParm(int Nth) { if (! parmlistvalid) zappcrash("parmlistvalid = 0"); if (Nth >= parmlist.count) return null; return parmlist.name[Nth]; } // list parameters in supplied text entry window int listParms(GtkWidget *textWin) { int ii; cchar *pname; double pvalue; for (ii = 0; ii < parmlist.count; ii++) { pname = getParm(ii); pvalue = getParm(pname); wprintf(textWin," %s %.12g \n",pname,pvalue); } return parmlist.count; } // edit parameters with a GUI // textWin != null enables button to list parameters in window // addp != 0 enables button to add new parameters // return: 0 if cancel, else parameter count int editParms(GtkWidget *textWin, int addp) { GtkWidget *peDialog, *peLabel[100], *peEdit[100], *peHbox[100]; char ptemp[20], *pname; cchar *pchval; double pvalue; int ii, err, iie = -1, zstat, floaded = 0; int bcancel=1, bapply=2, bload=3, bsave=4, blist=5, baddp=6; if (! parmlistvalid) zappcrash("parmlistvalid = 0"); zthreadcrash(); // thread usage not allowed build_dialog: // build parameter edit dialog if (parmlist.count > 100) zappcrash("more than 100 parameters"); if (textWin && addp) peDialog = gtk_dialog_new_with_buttons (ZTX("edit parameters"), null, (GtkDialogFlags) 0, // non-modal bugfix v.4.3 ZTX("load\nfile"),bload, ZTX("save\nfile"),bsave, ZTX("list\nall"),blist, ZTX("add\nnew"),baddp, ZTX("cancel"),bcancel, ZTX("apply"),bapply, null); else if (textWin) peDialog = gtk_dialog_new_with_buttons (ZTX("edit parameters"), null, (GtkDialogFlags) 0, ZTX("load\nfile"),bload, ZTX("save\nfile"),bsave, ZTX("list\nall"),blist, ZTX("cancel"),bcancel, ZTX("apply"),bapply, null); else if (addp) peDialog = gtk_dialog_new_with_buttons (ZTX("edit parameters"), null, (GtkDialogFlags) 0, ZTX("load\nfile"),bload, ZTX("save\nfile"),bsave, ZTX("add\nnew"),baddp, ZTX("cancel"),bcancel, ZTX("apply"),bapply, null); else peDialog = gtk_dialog_new_with_buttons (ZTX("edit parameters"), null, (GtkDialogFlags) 0, ZTX("load\nfile"),bload, ZTX("save\nfile"),bsave, ZTX("cancel"),bcancel, ZTX("apply"),bapply, null); gtk_window_set_position(GTK_WINDOW(peDialog),GTK_WIN_POS_MOUSE); for (ii = 0; ii < parmlist.count; ii++) // labels and edit boxes side by side { // (parm names and parm values) peLabel[ii] = gtk_label_new(parmlist.name[ii]); gtk_misc_set_alignment(GTK_MISC(peLabel[ii]),1,0.5); gtk_label_set_width_chars(GTK_LABEL(peLabel[ii]),30); peEdit[ii] = gtk_entry_new(); gtk_entry_set_width_chars(GTK_ENTRY(peEdit[ii]),12); sprintf(ptemp,"%.12g",parmlist.value[ii]); gtk_entry_set_text(GTK_ENTRY(peEdit[ii]),ptemp); peHbox[ii] = gtk_hbox_new(0,0); gtk_box_pack_start(GTK_BOX(peHbox[ii]),peLabel[ii],0,0,5); gtk_box_pack_start(GTK_BOX(peHbox[ii]),peEdit[ii],0,0,5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(peDialog)->vbox),peHbox[ii],1,1,2); } run_dialog: // display dialog and get inputs if (iie > -1) { gtk_editable_select_region(GTK_EDITABLE(peEdit[iie]),0,-1); // focus on new or bad parameter gtk_widget_grab_focus(peEdit[iie]); iie = -1; } gtk_widget_show_all(peDialog); zstat = gtk_dialog_run(GTK_DIALOG(peDialog)); if (zstat <= bcancel) // kill, cancel { if (floaded) { zstat = zmessageYN(null,ZTX("apply?")); // if file loaded, clarify if (! zstat) { gtk_widget_destroy(peDialog); return 0; } zstat = bapply; } } if (zstat == bload) // load from file { loadParms(); gtk_widget_destroy(peDialog); floaded = 1; goto build_dialog; } for (ii = 0; ii < parmlist.count; ii++) // capture inputs and check if OK { pchval = gtk_entry_get_text(GTK_ENTRY(peEdit[ii])); err = convSD(pchval,pvalue); if (err && iie < 0) iie = ii; // remember 1st error } if (iie >= 0) goto run_dialog; // re-get bad input if (zstat == bapply) // apply new values { for (ii = 0; ii < parmlist.count; ii++) // capture inputs and save them { pchval = gtk_entry_get_text(GTK_ENTRY(peEdit[ii])); err = convSD(pchval,parmlist.value[ii]); } gtk_widget_destroy(peDialog); // done return parmlist.count; } if (zstat == bsave) // save to file { for (ii = 0; ii < parmlist.count; ii++) // apply new values { pchval = gtk_entry_get_text(GTK_ENTRY(peEdit[ii])); err = convSD(pchval,parmlist.value[ii]); } saveParms(); floaded = 0; goto run_dialog; } if (zstat == blist) // list parameters { listParms(textWin); goto run_dialog; } if (zstat == baddp) // add parameter bugfix v.4.3 { // main dialog must be non-modal pname = zdialog_text(null,ZTX("add parameter"),ZTX("(new parm name)")); if (! pname) goto run_dialog; setParm(pname,0.0); zfree(pname); floaded = 1; iie = parmlist.count - 1; // focus on new parm gtk_widget_destroy(peDialog); goto build_dialog; } gtk_widget_destroy(peDialog); // unknown status return 0; } /************************************************************************** xstring class (dynamic length string) ***************************************************************************/ #define wmiv 1648734981 int xstring::tcount = 0; // initz. static members int xstring::tmem = 0; xstring::xstring(int cc) // new xstring(cc) { wmi = wmiv; xmem = (cc & 0x7ffffff8) + 8; // mod 8 length xpp = new char[xmem]; // allocate if (! xpp) zappcrash("xstring NEW failure",null); tcount++; // incr. object count tmem += xmem; // incr. allocated memory xcc = 0; // string cc = 0 *xpp = 0; // string = null } xstring::xstring(cchar *string) // new xstring("initial string") { wmi = wmiv; xcc = 0; if (string) xcc = strlen(string); // string length xmem = (xcc & 0x7ffffff8) + 8; // mod 8 length xpp = new char[xmem]; // allocate if (! xpp) zappcrash("xstring NEW failure",null); tcount++; // incr. object count tmem += xmem; // incr. allocated memory *xpp = 0; if (xcc) strcpy(xpp,string); // copy string } xstring::xstring(const xstring & xstr) // new xstring2(xstring1) { wmi = wmiv; xmem = xstr.xmem; // allocate same length xcc = xstr.xcc; xpp = new char[xmem]; if (! xpp) zappcrash("xstring NEW failure",null); tcount++; // incr. object count tmem += xmem; // incr. allocated memory strcpy(xpp,xstr.xpp); // copy string } xstring::~xstring() // delete xstring { validate(); delete[] xpp; // release allocated memory xpp = 0; tcount--; // decr. object count tmem -= xmem; // decr. allocated memory if (tcount < 0) zappcrash("xstring count < 0",null); if (tmem < 0) zappcrash("xstring memory < 0",null); if (tcount == 0 && tmem > 0) zappcrash("xstring memory leak",null); } xstring xstring::operator= (const xstring & xstr) // xstring2 = xstring1 { validate(); xstr.validate(); if (this == &xstr) return *this; xcc = xstr.xcc; if (xmem < xcc+1) { delete[] xpp; // expand memory if needed tmem -= xmem; xmem = (xcc & 0x7ffffff8) + 8; // mod 8 length xpp = new char[xmem]; if (! xpp) zappcrash("xstring NEW failure",null); tmem += xmem; } strcpy(xpp,xstr.xpp); // copy string return *this; } xstring xstring::operator= (cchar *str) // xstring = "some string" { validate(); xcc = 0; *xpp = 0; if (str) xcc = strlen(str); if (xmem < xcc+1) { delete[] xpp; // expand memory if needed tmem -= xmem; xmem = (xcc & 0x7ffffff8) + 8; // mod 8 length xpp = new char[xmem]; if (! xpp) zappcrash("xstring NEW failure",null); tmem += xmem; } if (xcc) strcpy(xpp,str); // copy string return *this; } xstring operator+ (const xstring & x1, const xstring & x2) // xstring1 + xstring2 { x1.validate(); x2.validate(); xstring temp(x1.xcc + x2.xcc); // build temp xstring strcpy(temp.xpp,x1.xpp); // with both input strings strcpy(temp.xpp + x1.xcc, x2.xpp); temp.xcc = x1.xcc + x2.xcc; temp.validate(); return temp; } xstring operator+ (const xstring & x1, cchar *s2) // xstring + "some string" { x1.validate(); int cc2 = 0; if (s2) cc2 = strlen(s2); xstring temp(x1.xcc + cc2); // build temp xstring strcpy(temp.xpp,x1.xpp); // with both input strings if (s2) strcpy(temp.xpp + x1.xcc, s2); temp.xcc = x1.xcc + cc2; temp.validate(); return temp; } xstring operator+ (cchar *s1, const xstring & x2) // "some string" + xstring { x2.validate(); int cc1 = 0; if (s1) cc1 = strlen(s1); xstring temp(cc1 + x2.xcc); // build temp xstring if (s1) strcpy(temp.xpp,s1); // with both input strings strcpy(temp.xpp + cc1, x2.xpp); temp.xcc = cc1 + x2.xcc; temp.validate(); return temp; } void xstring::insert(int pos, cchar *string, int cc) // insert cc chars from string at pos { // pad if pos > xcc or cc > string validate(); int scc = strlen(string); if (! cc) cc = scc; int pad = pos - xcc; if (pad < 0) pad = 0; if (xmem < xcc + cc + pad + 1) // allocate more memory if needed { int newmem = xcc + cc + pad; newmem = (newmem & 0x7ffffff8) + 8; // mod 8 length char * xpp2 = new char[newmem]; if (! xpp2) zappcrash("xstring NEW failure",null); strcpy(xpp2,xpp); // copy to new space delete[] xpp; xpp = xpp2; tmem += newmem - xmem; xmem = newmem; } if (pad) memset(xpp+xcc,' ',pad); // add blanks up to pos for (int ii = xcc + pad; ii >= pos; ii--) // make hole for inserted string *(xpp+ii+cc) = *(xpp+ii); if (cc > scc) memset(xpp+pos+scc,' ',cc-scc); // blank pad if cc > string if (cc < scc) scc = cc; strncpy(xpp+pos,string,scc); // insert string, without null xcc += cc + pad; // set new length xpp[xcc] = 0; validate(); } void xstring::overlay(int pos, cchar *string, int cc) // overlay substring { validate(); int scc = strlen(string); if (! cc) cc = scc; if (xmem < pos + cc + 1) // allocate more memory if needed { int newmem = pos + cc; newmem = (newmem & 0x7ffffff8) + 8; // mod 8 length char * xpp2 = new char[newmem]; if (! xpp2) zappcrash("xstring NEW failure",null); strcpy(xpp2,xpp); // copy to new space delete[] xpp; xpp = xpp2; tmem += newmem - xmem; xmem = newmem; } if (pos > xcc) memset(xpp+xcc,' ',pos-xcc); // add blanks up to pos if (cc > scc) memset(xpp+pos+scc,' ',cc-scc); // blank pad if cc > string if (cc < scc) scc = cc; strncpy(xpp+pos,string,scc); // insert string, without null if (pos + cc > xcc) xcc = pos + cc; // set new length xpp[xcc] = 0; validate(); } void xstring::getStats(int & tcount2, int & tmem2) // get statistics { tcount2 = tcount; tmem2 = tmem; } void xstring::validate() const // validate integrity { if (wmi != wmiv) zappcrash("xstring bad wmi",null); if (xmem < xcc+1) zappcrash("xstring xmem < xcc+1",null); if (xcc != (int) strlen(xpp)) zappcrash("xstring xcc != strlen(xpp)",null); } /************************************************************************** Vxstring class (array or vector of xstring) ***************************************************************************/ Vxstring::Vxstring(int ii) // constructor { pdata = 0; nd = ii; if (nd) pdata = new xstring[nd]; if (nd && !pdata) zappcrash("Vxstring NEW fail",null); } Vxstring::~Vxstring() // destructor { if (nd) delete[] pdata; pdata = 0; nd = 0; } Vxstring::Vxstring(const Vxstring & pold) // copy constructor { pdata = 0; nd = pold.nd; // set size if (nd) pdata = new xstring[nd]; // allocate memory if (nd && !pdata) zappcrash("Vxstring NEW fail"); for (int ii = 0; ii < nd; ii++) pdata[ii] = pold[ii]; // copy defined elements } Vxstring Vxstring::operator= (const Vxstring & vdstr) // operator = { if (nd) delete[] pdata; // delete old memory pdata = 0; nd = vdstr.nd; if (nd) pdata = new xstring[nd]; // allocate new memory if (nd && !pdata) zappcrash("Vxstring NEW fail",null); for (int ii = 0; ii < nd; ii++) pdata[ii] = vdstr.pdata[ii]; // copy elements return *this; } xstring & Vxstring::operator[] (int ii) // operator [] { static xstring xnull(0); if (ii < nd) return pdata[ii]; // return reference zappcrash("Vxstring index invalid %d %d",nd,ii,null); return xnull; } const xstring & Vxstring::operator[] (int ii) const // operator [] { static xstring xnull(0); if (ii < nd) return pdata[ii]; // return reference zappcrash("Vxstring index invalid %d %d",nd,ii,null); return xnull; } int Vxstring::search(cchar *string) // find element in unsorted Vxstring { for (int ii = 0; ii < nd; ii++) if (strEqu(pdata[ii],string)) return ii; return -1; } int Vxstring::bsearch(cchar *string) // find element in sorted Vxstring { // (binary search) int nn, ii, jj, kk, rkk; nn = nd; if (! nn) return 0; // empty list ii = nn / 2; // next element to search jj = (ii + 1) / 2; // next increment nn--; // last element rkk = 0; while (1) { kk = strcmp(pdata[ii],string); // check element if (kk > 0) { ii -= jj; // too high, go down if (ii < 0) return -1; } else if (kk < 0) { ii += jj; // too low, go up if (ii > nn) return -1; } else if (kk == 0) return ii; // matched jj = jj / 2; // reduce increment if (jj == 0) { jj = 1; // step by 1 element if (! rkk) rkk = kk; // save direction else { if (rkk > 0) { if (kk < 0) return -1; } // if change direction, fail else if (kk > 0) return -1; } } } } static int VDsortKeys[10][3], VDsortNK; int Vxstring::sort(int NK, int keys[][3]) // sort elements by subfields { // key[ii][0] = position int NR, RL, ii; // [1] = length HeapSortUcomp VDsortComp; // [2] = 1/2 = ascending/desc. // = 3/4 = + ignore case NR = nd; if (NR < 2) return 1; RL = sizeof(xstring); if (NK < 1) zappcrash("Vxstring::sort, bad NK",null); if (NK > 10) zappcrash("Vxstring::sort, bad NK",null); VDsortNK = NK; for (ii = 0; ii < NK; ii++) { VDsortKeys[ii][0] = keys[ii][0]; VDsortKeys[ii][1] = keys[ii][1]; VDsortKeys[ii][2] = keys[ii][2]; } HeapSort((char *) pdata,RL,NR,VDsortComp); return 1; } int VDsortComp(cchar *r1, cchar *r2) { xstring *d1, *d2; cchar *p1, *p2; int ii, stat, kpos, ktype, kleng; d1 = (xstring *) r1; d2 = (xstring *) r2; p1 = *d1; p2 = *d2; for (ii = 0; ii < VDsortNK; ii++) // compare each key { kpos = VDsortKeys[ii][0]; kleng = VDsortKeys[ii][1]; ktype = VDsortKeys[ii][2]; if (ktype == 1) { stat = strncmp(p1+kpos,p2+kpos,kleng); if (stat) return stat; continue; } else if (ktype == 2) { stat = strncmp(p1+kpos,p2+kpos,kleng); if (stat) return -stat; continue; } else if (ktype == 3) { stat = strncasecmp(p1+kpos,p2+kpos,kleng); if (stat) return stat; continue; } else if (ktype == 4) { stat = strncasecmp(p1+kpos,p2+kpos,kleng); if (stat) return -stat; continue; } zappcrash("Vxstring::sort, bad KEYS sort type",null); } return 0; } int Vxstring::sort(int pos, int cc) // sort elements ascending { int key[3]; if (! cc) cc = 999999; key[0] = pos; key[1] = cc; key[2] = 1; sort(1,&key); return 1; } /************************************************************************** Hash Table class ***************************************************************************/ // static members (robust for tables up to 60% full) int HashTab::trys1 = 100; // Add() tries int HashTab::trys2 = 200; // Find() tries HashTab::HashTab(int _cc, int _cap) // constructor { cc = 4 * (_cc + 4) / 4; // + 1 + mod 4 length cap = _cap; int len = cc * cap; table = new char [len]; if (! table) zappcrash("HashTab() new %d fail",len,null); memset(table,0,len); } HashTab::~HashTab() // destructor { delete [] table; table = 0; } // Add a new string to table int HashTab::Add(cchar *string) { int pos, fpos, trys; pos = strHash(string,cap); // get random position pos = pos * cc; for (trys = 0, fpos = -1; trys < trys1; trys++, pos += cc) // find next free slot at/after position { if (pos >= cap * cc) pos = 0; // last position wraps to 1st if (! table[pos]) // empty slot: string not found { if (fpos != -1) pos = fpos; // use prior deleted slot if there strncpy(table+pos,string,cc); // insert new string table[pos+cc-1] = 0; // insure null terminator return (pos/cc); // return rel. table entry } if (table[pos] == -1) // deleted slot { if (fpos == -1) fpos = pos; // remember 1st one found continue; } if (strEqu(string,table+pos)) return -2; // string already present } return -3; // table full (trys1 exceeded) } // Delete a string from table int HashTab::Del(cchar *string) { int pos, trys; pos = strHash(string,cap); // get random position pos = pos * cc; for (trys = 0; trys < trys2; trys++, pos += cc) // search for string at/after position { if (pos >= cap * cc) pos = 0; // last position wraps to 1st if (! table[pos]) return -1; // empty slot, string not found if (strEqu(string,table+pos)) // string found { table[pos] = -1; // delete table entry return (pos/cc); // return rel. table entry } } zappcrash("HashTab::Del() bug",null); // exceed trys2, must not happen return 0; // (table too full to function) } // Find a table entry. int HashTab::Find(cchar *string) { int pos, trys; pos = strHash(string,cap); // get random position pos = pos * cc; for (trys = 0; trys < trys2; trys++, pos += cc) // search for string at/after position { if (pos >= cap * cc) pos = 0; // last position wraps to 1st if (! table[pos]) return -1; // empty slot, string not found if (strEqu(string,table+pos)) return (pos/cc); // string found, return rel. entry } zappcrash("HashTab::Find() bug",null); // cannot happen return 0; } // return first or next table entry int HashTab::GetNext(int & ftf, char *string) { static int pos; if (ftf) // initial call { pos = 0; ftf = 0; } while (pos < (cap * cc)) { if ((table[pos] == 0) || (table[pos] == -1)) // empty or deleted slot { pos += cc; continue; } strcpy(string,table+pos); // return string pos += cc; return 1; } return -4; // EOF } int HashTab::Dump() { int ii, pos; for (ii = 0; ii < cap; ii++) { pos = ii * cc; if (table[pos] && table[pos] != -1) printf("%d, %s \n", ii, table + pos); if (table[pos] == -1) printf("%d, deleted \n", pos); } return 1; } /************************************************************************** class for queue of dynamic strings ***************************************************************************/ Queue::Queue(int cap) // constructor { int err; err = mutex_init(&qmutex, 0); // create mutex = queue lock if (err) zappcrash("Queue(), mutex init fail",null); qcap = cap; // queue capacity ent1 = entN = qcount = 0; // state = empty vd = new Vxstring(qcap); // create vector of xstring's if (! vd) zappcrash("Queue(), NEW fail %d",cap,null); strcpy(wmi,"queue"); return; } Queue::~Queue() // destructor { if (strNeq(wmi,"queue")) zappcrash("~Queue wmi fail",null); wmi[0] = 0; mutex_destroy(&qmutex); // destroy mutex qcount = qcap = ent1 = entN = -1; delete vd; vd = 0; return; } void Queue::lock() // lock queue (private) { int err; err = mutex_lock(&qmutex); // reserve mutex or suspend if (err) zappcrash("Queue mutex lock fail",null); return; } void Queue::unlock() // unlock queue (private) { int err; err = mutex_unlock(&qmutex); // release mutex if (err) zappcrash("Queue mutex unlock fail",null); return; } int Queue::getCount() // get current entry count { if (strNeq(wmi,"queue")) zappcrash("Queue getCount wmi fail",null); return qcount; } int Queue::push(const xstring *newEnt, double wait) // add entry to queue, with max. wait { double elaps = 0.0; int count; if (strNeq(wmi,"queue")) zappcrash("Queue::push wmi fail",null); lock(); // lock queue while (qcount == qcap) { // queue full unlock(); // unlock queue if (elaps >= wait) return -1; // too long, return -1 status usleep(1000); // sleep in 1 millisec. steps elaps += 0.001; // until queue not full lock(); // lock queue } (* vd)[entN] = *newEnt; // copy new entry into queue entN++; // incr. end pointer if (entN == qcap) entN = 0; qcount++; // incr. queue count count = qcount; unlock(); // unlock queue return count; // return curr. queue count } xstring *Queue::pop1() // get 1st (oldest) entry and remove { xstring *entry; if (strNeq(wmi,"queue")) zappcrash("Queue::pop1 wmi fail",null); lock(); // lock queue if (qcount == 0) entry = 0; // queue empty else { entry = &(* vd)[ent1]; // get first entry ent1++; // index pointer to next if (ent1 == qcap) ent1 = 0; qcount--; // decr. queue count } unlock(); // unlock queue return entry; } xstring *Queue::popN() // get last (newest) entry and remove { xstring *entry; if (strNeq(wmi,"queue")) zappcrash("Queue::popN wmi fail",null); lock(); // lock queue if (qcount == 0) entry = 0; // queue empty else { if (entN == 0) entN = qcap; // index pointer to prior entN--; qcount--; // decr. queue count entry = &(* vd)[entN]; // get last entry } unlock(); // unlock queue return entry; } /************************************************************************** Tree class, tree-structured data storage without limits Store any amount of data at any depth within a tree-structure with named nodes. Data can be found using an ordered list of node names or node numbers. Node numbers are in the sequence added using put() with names, or the same as those numbers used in put() with numbers. Internal code conventions: - caller level is node 0, next level is node 1, etc. - node names and numbers in calls to get() and put() refer to next levels - number of levels = 1+nn, where nn is max. in calls to put(...nodes[], nn) ***************************************************************************/ #define wmid 1374602859 // integrity check key // constructor Tree::Tree(cchar *name) { wmi = wmid; tname = 0; tmem = 0; tdata = 0; nsub = 0; psub = 0; if (name) { int cc = strlen(name); tname = new char[cc+1]; if (! tname) zappcrash("Tree, no memory",null); strcpy(tname,name); } } // destructor Tree::~Tree() { if (wmi != wmid) zappcrash("not a Tree",null); if (tname) delete [] tname; tname = 0; if (tmem) free(tdata); tmem = 0; tdata = 0; for (int ii = 0; ii < nsub; ii++) delete psub[ii]; if (psub) free(psub); nsub = 0; psub = 0; } // put data by node names[] int Tree::put(void *data, int dd, char *nodes[], int nn) { Tree *tnode; if (wmi != wmid) zappcrash("not a Tree",null); tnode = make(nodes,nn); if (tnode->tdata) free(tnode->tdata); tnode->tdata = new char[dd]; if (! tnode->tdata) zappcrash("Tree, no memory",null); tnode->tmem = dd; memmove(tnode->tdata,data,dd); return 1; } // put data by node numbers[] int Tree::put(void *data, int dd, int nodes[], int nn) { Tree *tnode; if (wmi != wmid) zappcrash("not a Tree",null); tnode = make(nodes,nn); if (tnode->tdata) free(tnode->tdata); tnode->tdata = new char[dd]; if (! tnode->tdata) zappcrash("Tree, no memory",null); tnode->tmem = dd; memmove(tnode->tdata,data,dd); return 1; } // get data by node names[] int Tree::get(void *data, int dd, char *nodes[], int nn) { Tree *tnode = find(nodes,nn); if (! tnode) return 0; if (! tnode->tmem) return 0; if (dd > tnode->tmem) dd = tnode->tmem; memmove(data,tnode->tdata,dd); return dd; } // get data by node numbers[] int Tree::get(void *data, int dd, int nodes[], int nn) { Tree *tnode = find(nodes,nn); if (! tnode) return 0; if (! tnode->tmem) return 0; if (dd > tnode->tmem) dd = tnode->tmem; memmove(data,tnode->tdata,dd); return dd; } // find a given node by names[] Tree * Tree::find(char *nodes[], int nn) { int ii; for (ii = 0; ii < nsub; ii++) if (psub[ii]->tname && strEqu(nodes[0],psub[ii]->tname)) break; if (ii == nsub) return 0; if (nn == 1) return psub[ii]; return psub[ii]->find(&nodes[1],nn-1); } // find a given node by numbers[] Tree * Tree::find(int nodes[], int nn) { int ii = nodes[0]; if (ii >= nsub) return 0; if (! psub[ii]) return 0; if (nn == 1) return psub[ii]; return psub[ii]->find(&nodes[1],nn-1); } // find or create a given node by names[] Tree * Tree::make(char *nodes[], int nn) { int ii; Tree **psub2; for (ii = 0; ii < nsub; ii++) if (psub[ii]->tname && strEqu(nodes[0],psub[ii]->tname)) break; if (ii == nsub) { psub2 = new Tree * [nsub+1]; if (! psub2) zappcrash("Tree, no memory",null); for (ii = 0; ii < nsub; ii++) psub2[ii] = psub[ii]; delete [] psub; psub = psub2; nsub++; psub[ii] = new Tree(nodes[0]); if (! psub[ii]) zappcrash("Tree, no memory",null); } if (nn == 1) return psub[ii]; return psub[ii]->make(&nodes[1],nn-1); } // find or create a given node by numbers[] Tree * Tree::make(int nodes[], int nn) { Tree **psub2; int ii, jj; ii = nodes[0]; if ((ii < nsub) && psub[ii]) { if (nn == 1) return psub[ii]; return psub[ii]->make(&nodes[1],nn-1); } if (ii >= nsub) { psub2 = new Tree * [ii+1]; if (psub2 == null) zappcrash("Tree, no memory",null); for (jj = 0; jj < nsub; jj++) psub2[jj] = psub[jj]; for (jj = nsub; jj < ii; jj++) psub2[jj] = 0; delete [] psub; psub = psub2; nsub = ii + 1; } psub[ii] = new Tree("noname"); if (! psub[ii]) zappcrash("Tree, no memory",null); if (nn == 1) return psub[ii]; return psub[ii]->make(&nodes[1],nn-1); } // dump tree data to stdout (call with level 0) void Tree::dump(int level) { cchar *name; if (! tname) name = "noname"; else name = tname; printf("%*s level: %d name: %s subs: %d mem: %d \n", level*2,"",level,name,nsub,tmem); for (int ii = 0; ii < nsub; ii++) if (psub[ii]) psub[ii]->dump(level+1); } // get node counts and total data per level // level 0 + nn more levels, as given in calls to put(...nodes[],nn) // caller must initialize counters to zero void Tree::stats(int nn[], int nd[]) { nn[0] += 1; nd[0] += tmem; for (int ii = 0; ii < nsub; ii++) if (psub[ii]) psub[ii]->stats(&nn[1],&nd[1]); } fotoxx-12.01.2/fotoxx.h0000644000175000017500000017045111701011017013341 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #include #include "zfuncs.h" // Fotoxx definitions #define fversion "Fotoxx v.12.01.2" // this fotoxx version #define flicense "Free software - GNU General Public License v.3" #define fhomepage "http://kornelix.squarespace.com/fotoxx" #define ftranslators \ "Translators: Jie Luo, Justa, Peter Landgren, Alexander Krasnopolsky, \n" \ " Arthur Kalverboer, André Campos Rodovalho, Doriano Blengino" #define fcredits "Software used: GTK, libtiff, ufraw, exiftool" #define fcontact "Bug reports: kornelix2@gmail.com" // GTK definitions #define PXB GdkPixbuf #define TEXTWIN GTK_TEXT_WINDOW_TEXT // GDK window of GTK text view #define NODITHER GDK_RGB_DITHER_NONE #define ALWAYS GTK_POLICY_ALWAYS #define NEVER GTK_POLICY_NEVER #define RGBCOLOR GDK_COLORSPACE_RGB #define LINEATTRIBUTES GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER #define BILINEAR GDK_INTERP_BILINEAR #define HYPER GDK_INTERP_HYPER #define MWIN GTK_WINDOW(mWin) // EXIF/IPTC keys for embedded image data #define iptc_tags_key "Keywords" // tags (IPTC) #define iptc_rating_key "Rating" // star rating (IPTC) #define exif_date_key "DateTimeOriginal" // date/time (EXIF) #define exif_width_key "ImageWidth" // width, pixels (EXIF) #define exif_height_key "ImageHeight" // height, pixels (EXIF) #define exif_orientation_key "Orientation" // orientation (EXIF) #define iptc_editlog_key "EditStatus" // edits applied list (IPTC) #define exif_comment_key "UserComment" // user comments (EXIF) #define iptc_caption_key "Caption-Abstract" // image caption (IPTC) #define exif_focal_length_key "FocalLengthIn35mmFormat" // focal length (EXIF) // fotoxx definitions #define mega (1024 * 1024) #define ftrash "Desktop/fotoxx-trash" // special trash folder location #define def_jpeg_quality "90" // default jpeg quality (high) #define pi 3.141592654 #define PXMpix(pxm,px,py) ((uint16 *) pxm->bmp+((py)*(pxm->ww)+(px))*3) // return PXM pixel[3] at (px,py) (16-bit) #define PXMpix8(pxm,px,py) ((uint8 *) pxm->bmp+((py)*(pxm->ww)+(px))*3) // return PXM pixel[3] at (px,py) (8-bit) #define pixbright(pix) (0.25*(pix)[0]+0.65*(pix)[1]+0.10*(pix)[2]) // pixel brightness, 0-64K #define pixred(pix) (25 * pix[0] / (pixbright(pix)+1)) // pixel redness, 0-100% #define Nrecentfiles 100 // most recent image files #define max_threads 6 // max. working threads #define maxedits 100 // max. edits, undo/redo depth #define MAXIMAGES 100000 // max. image files supported #define maxtagcats 200 // max tag categories #define tagcc 50 // max cc for one tag or category ID #define tagFcc 1000 // max tag cc for one image file #define tagntc 1000 // max no. tags for one category #define tagGcc 50000 // max tag cc for one category #define tagTcc 50000 // max tag cc for all defined tags #define tagMcc 200 // max tag cc for batch add tags #define tagScc 200 // max tag cc for search tags #define tagRcc 200 // max tag cc for recent tags #define tagrecl 2000 // tag rec. cc (>maxfcc and >tagFcc) #define tagdelims ",;" // valid tag delimiters (; obsolete) v.11.02 #define tagdelim1 ',' // delimiter for new tags v.11.02 #define tagdelim2 ", " // delimiter + blank v.11.02 // camera RAW file extensions (also upper case will work) #define RAWfiles \ ".3fr .ari .arw .srf .sr2 .bay .crw .cr2 .cap .iiq .eip .dcs .dcr " \ ".drf .k25 .kdc .dng .erf .fff .mef .mos .mrw .nef .nrw .orf .pef " \ ".ptx .pxn .r3d .raf .raw .rw2 .raw .rwl .dng .rwz .srw .x3f " // externals from zfuncs module namespace zfuncs { extern char zlang[8]; // current language lc_RC extern cchar *F1_help_topic; // F1 context help topic extern char zicondir[200]; // where application icons live extern int zdialog_busy; // tracks open zdialog's extern int open_popup_windows; // tracks popup windows open } namespace image_navi { // image_gallery() data extern char *galleryname; // directory or file list name extern int gallerytype; // 1/2/3 = directory/file-list/metadata extern int nfiles, nimages; // file counts, total and images extern char **flist; // image file list extern char **mdlist; // metadata list extern int xwinW, xwinH; // image gallery window size extern int thumbfilesize; // thumbnail file image size extern int thumbsize; // curr. thumbnail display size extern int genthumbs; // counts thumbnails generated } #define ccc (maxfcc*2+200) // max. command line size EX char command[ccc]; // command, parameters, 2 filespecs EX char PIDstring[12]; // process PID as string EX int Nwt; // working threads to use EX int wtnx[8]; // internal thread IDs EX int wthreads_busy; // active thread count EX GtkWidget *mWin, *drWin, *mVbox; // main and drawing window EX GtkWidget *mMbar, *mTbar, *STbar; // menu bar, tool bar, status bar EX GdkGC *gdkgc; // GDK graphics context EX GdkColor black, white, red, green; EX GdkColor lgray, dgray; EX GdkColor fg_color; // current foreground color EX GdkColormap *colormap; EX uint maxcolor; EX GdkCursor *arrowcursor; // main window cursors EX GdkCursor *dragcursor; EX GdkCursor *drawcursor; EX int Fexiftool; // exiftool program available EX int Fexifwarned; // missing exiftool was warned EX int Fufraw; // ufraw-batch program is available EX int Fxdgopen; // xdg-open program available EX int Fshutdown; // app shutdown underway EX int Fdebug; // debug flag EX int Fkillfunc; // signal, kill running function EX int Ffuncbusy; // function is busy/working EX int Wrepaint; // request window paint EX int Wpainted; // window was repainted EX int Fmodified; // image was edited/modified EX int Fsaved; // image saved since last mod EX int Ftagschanged; // image tags changed and not saved EX int Fpreview; // use window image for edits EX int Fblowup; // zoom small images to window size EX int Fmenulock; // lock for some menu functions EX int Fslideshow; // slide show mode is active EX int Frecent; // start with recent files gallery EX int Fprev; // start with previous file EX int Fblank; // start with blank window EX int KBzmalloclog; // KB toggle for zmalloc reporting EX int Fautosync; // auto file sync is requested EX int Fmansync; // manual file sync is requested EX int Fsyncbusy; // file sync is busy/working EX cchar *fsync_lock; // synchronize files interlock v.11.11 EX char *topmenu; // latest top-menu selection EX cchar *threadmessage; // popup message from thread process EX char *SS_imagefile; // command line -slideshow parameter EX char *SS_musicfile; // command line -music parameter volatile // stop optimizer removing code v.11.03 EX int SB_goal, SB_done; // status bar progress tracking v.11.06 EX char SB_text[200]; // optional status bar application text EX char *topdirk; // user's top-level image directory EX char *curr_file, *curr_dirk; // current image file and directory EX char *recentfiles[Nrecentfiles]; // most recent image files opened EX char curr_file_type[8]; // jpg / tif / png / other EX int curr_file_bpc; // image file bits/color, 8/16 EX int curr_file_size; // image file size on disk EX int curr_file_posn; // position in current file set EX int curr_file_count; // count of images in current set EX double curr_image_time; // time current image opened v.11.07 EX char f_load_type[8]; // data returned by f_load() EX int f_load_bpc, f_load_size; EX char f_save_type[8]; // data returned by f_save() EX int f_save_bpc, f_save_size; EX char jpeg_quality[8]; // jpeg file save quality // files and directories in /home//.fotoxx/ EX char topdirk_file[200]; // top directory save file v.11.11 EX char tags_defined_file[200]; // tags defined file EX char search_index_file[200]; // search index file v.11.02 EX char recentfiles_file[200]; // file of recent image files v.11.09 EX char collections_dirk[200]; // directory for saved image collections EX char saved_areas_dirk[200]; // directory for saved select area files EX char saved_curves_dirk[200]; // directory for saved curve data EX char annotations_dirk[200]; // directory for annotation files // fotoxx PXM pixmaps typedef struct { // PXM pixmap char wmi[8]; int ww, hh, bpc; // width, height, bits per color void *bmp; // uint8*/uint16* (bpc=8/16) } PXM; EX PXM *Fpxm8; // input file pixmap, PXM-8 EX PXM *Fpxm16; // input file pixmap, PXM-16 EX PXM *E1pxm16; // edit pixmap, base image EX PXM *E3pxm16; // edit pixmap, edited image EX PXM *ERpxm16; // edit pixmap, undo/redo image EX PXM *E8pxm16; // scratch image for some functions EX PXM *E9pxm16; // scratch image for some functions EX PXM *Dpxm16; // drawing window pixmap, 1x 16-bits EX PXM *Dpxm8; // drawing window pixmap, Mscale 8-bits EX int Fww, Fhh; // input image dimensions EX int E1ww, E1hh, E3ww, E3hh; // edit image dimensions EX int ERww, ERhh; // undo/redo image dimensions EX int E9ww, E9hh; // scratch image dimensions EX int Dww, Dhh; // drawing window size EX mutex Fpixmap_lock; // lock for accessing PXM pixmaps EX int Frefresh; // full image refresh needed EX double Fzoom; // image zoom scale (0 = fit window) EX int zoomx, zoomy; // req. zoom center of window EX double Mscale; // scale factor, image to window EX int Iww, Ihh; // current image size at 1x EX int iww, ihh; // image area in drawing window at Mscale EX int dww, dhh; // drawing window image, iww * Mscale EX int Iorgx, Iorgy; // drawing window origin in image EX int Dorgx, Dorgy; // image origin in drawing window EX int Mbutton; // mouse button, 1/3 = left/right EX int LMclick, RMclick; // mouse left, right click EX int Mxclick, Myclick; // mouse click position EX int Mxposn, Myposn; // mouse move position EX int Mxdown, Mydown, Mxdrag, Mydrag; // mouse drag vector EX int Mdrag; // mouse drag underway EX int Mcapture; // mouse captured by edit function EX int Fmousemain; // flag, mouse acts on main window EX int KBcapture; // KB key captured by edit function EX int KBkey; // active keyboard key EX int KBcontrolkey; // keyboard key states, 1 = down EX int KBshiftkey; EX int KB_A_key; EX int Ntoplines, Nptoplines; // lines on top of image in window EX int toplinex1[4], topliney1[4], toplinex2[4], topliney2[4]; EX int ptoplinex1[4], ptopliney1[4], ptoplinex2[4], ptopliney2[4]; EX int Ftoparc, ptoparc; // arc (circle/ellipse) on top EX int toparcx,toparcy,toparcw,toparch; // of image in window EX int ptoparcx,ptoparcy,ptoparcw,ptoparch; struct toptext_t { // list of text straings that are int ID, px, py; // painted over image whenever cchar *text; // the main window is repainted cchar *font; }; #define maxtoptext 100 // max. text strings EX toptext_t toptext[100]; // text strings written on main window EX int Ntoptext; // current count struct topcircle_t { // list of red circles that are int px, py; // painted over image whenever int radius; // the main window is updated int color; // 1/2/3 = white/black/red }; #define maxtopcircles 100 // max. number of circles EX topcircle_t topcircles[100]; // circles written on main window EX int Ntopcircles; // current count // select area data #define sa_initseq 10 // initial sequence number (0/1/2 reserved) #define sa_maxseq 9999 // could go to 16 bits = 64K EX int sa_geom1, sa_geom2; EX uint16 sa_endpx[10000], sa_endpy[10000]; // last pixel drawn per seqence no. EX int sa_thresh; // mouse pixel distance threshold EX int sa_mouseradius; // mouse selection radius EX int sa_searchrange; // search range (* mouse radius) EX int sa_mousex, sa_mousey; // mouse position in image EX int sa_matchcolor; // search using color match Y/N EX double sa_colormatch; // color range to match (0.001 to 1.0) EX uint16 sa_matchRGB[1000][3]; // match colors, up to 1000 EX int sa_Nmatch; // count of match colors EX int sa_firewall; // selected pixels block propagation Y/N EX GdkColor *sa_pixRGB; // select area outline color EX int sa_radius, sa_radius2; // current mouse radius, radius **2 EX int sa_radius3; // search range **2 EX int sa_calced; // edge calculation done EX int sa_blend; // edge blend width EX int sa_minx, sa_maxx; // enclosing rectangle for area EX int sa_miny, sa_maxy; EX char *sa_stackdirec; // pixel search stack EX int *sa_stackii; EX int sa_maxstack; EX int sa_Nstack; EX int sa_stat; // 0/1/2/3 = none/edit/pause/complete EX int sa_mode; // 1-7 = curr. select area edit method EX int sa_finOK; // finish area - success EX int sa_finhole; // finish area - area has a hole EX int sa_currseq; // current select sequence no. EX int sa_Ncurrseq; // current sequence pixel count EX char *sa_pixselc; // maps pixels (re)selected in current cycle EX uint16 *sa_pixmap; // 0/1/2+ = outside/edge/inside (edge dist) EX int sa_Npixel; // total select_area pixel count EX int sa_fww, sa_fhh; // valid image dimensions for select area EX int Fshowarea; // show select area outline EX int Factivearea; // select area complete and enabled EX int areanumber; // increasing sequential number // spline curve data typedef void t_spcfunc(int spc); // callback function, spline curve edit typedef struct { // spline curve data GtkWidget *drawarea; // drawing area for spline curves t_spcfunc *spcfunc; // callback function when curve changed int Nspc; // number of active curves, 1-10 int vert[10]; // curve is vert. (1) or horz. (0) int nap[10]; // anchor points per curve double apx[10][50], apy[10][50]; // up to 50 anchor points per curve double yval[10][1000]; // y-values for x = 0 to 1 by 0.001 int Nscale; // no. of fixed scale lines, 0-10 double xscale[2][10]; // 2 x-values for end points double yscale[2][10]; // 2 y-values for end points v.11.10 } spldat; // edit collections data EX char *edit_coll_file; // current edit collection file EX char *edit_coll_name; // collection name = file name EX char *edit_coll_memberfile; // collection member image file EX zdialog *zd_edit_coll; // edit collections dialog // image edit function data typedef struct { // edit function data cchar *funcname; // function name, e.g. flatten int Fprev; // flag, use preview window int Farea; // select area: 0/1/2 = delete/ignore/usable int Fpara; // flag, parallel edit OK int Fmod; // flag, image modified by this func zdialog *zd; // edit dialog spldat *curves; // edit curve data void * (*threadfunc)(void *); // edit thread function void (*mousefunc)(); // edit mouse function } editfunc; EX editfunc *CEF; // current active edit function EX pvlist *editlog; // log of image edits done v.10.2 EX char *undo_files; // undo/redo stack, image files EX int Pundo; // undo/redo stack position EX int Pumax; // undo/redo stack depth #define maxplugins 100 EX int Nplugins; // plugin menu items EX char *plugins[100]; // The following are saved and restored across sessions. // They belong to different functions in different source modules. EX char *pversion; // prior fotoxx version EX char *last_session; // last fotoxx session exit time EX int Ffirsttime; // first time startup EX int newfiles; // new files found since last synch EX int mwgeom[4]; // main window position and size EX cchar *tbar_style; // toolbar style: icons/text/both EX cchar *startdisplay; // display: recent/prev/blank/file/dirk EX char *startdirk; // start directory (startdisplay=dirk) EX char *startfile; // start image file (startdisplay=file) EX int Fwarnoverwrite; // warn overwrite of original image EX double lens_mm, lens_bow; // pano lens mm and bow EX double lens_settings[2]; // " user settings if no EXIF data EX cchar *zoomratio; // zoom ratio, "1.xxxxxx" EX int trimsize[2]; // trim (crop) width, height EX char *trimbuttons[6]; // trim dialog button labels EX char *trimratios[6]; // corresponding aspect ratios EX int editresize[2]; // edit resize width, height EX int batchresize[2]; // batch resize width, height EX int emailsize[2]; // email resize width, height EX char *annotate_text; // annotation text EX char *annotate_font; // font and size, e.g. "Sans 20" EX char *annotate_color[3]; // text, background, text outline colors EX int annotate_trans[3]; // corresp. transparencies EX int annotate_outline; // text outline width, pixels EX double annotate_angle; // angle of text EX int Fgrid; // both grid lines on / off EX int gridon[2]; // x/y gridlines on / off EX int gridspace[2]; // x/y grid line spacing EX int gridcount[2]; // x/y grid line counts (alternative) EX int gridoffset[2]; // x/y grid line starting offsets EX int rotate_grid[8]; // rotate function grid status EX int unbend_grid[8]; // unbend function grid status EX int warpC_grid[8]; // warp image (curved) grid status EX int warpL_grid[8]; // warp image (linear) grid status EX int warpF_grid[8]; // warp image (affine) grid status #define SSNF 12 // no. slide show transition types EX int ss_funcs[SSNF]; // user preferred transitions EX char *ss_musicfile; // music file or playlist // dialogs with global visibility EX zdialog *zdedittags; // edit tags zdialog EX zdialog *zdexifview; // view EXIF/IPTC data EX zdialog *zdexifedit; // edit EXIF/IPTC data EX zdialog *zdeditcctext; // edit IPTC caption and EXIF user comments EX zdialog *zdrename; // rename file zdialog EX zdialog *zdsela; // select area dialog // GTK functions int main(int argc, char * argv[]); // main program int gtkinitfunc(void *data); // GTK initz. function int gtimefunc(void *arg); // periodic function void update_statusbar(); // update main window status bar int delete_event(); // window delete event function void destroy_event(); // window destroy event function void topmenufunc(GtkWidget *, cchar *menu); // top level menu function int mwpaint1(); // window repaint (expose event) void mwpaint2(); // window repaint (thread callable) void mwpaint3(int px, int py, int ww, int hh); // paint window area from image area void mouse_event(GtkWidget *, GdkEventButton *, void *); // mouse event function int KBpress(GtkWidget *, GdkEventKey *, void *); // KB key press event function int KBrelease(GtkWidget *, GdkEventKey *, void *); // KB key release event void paint_toplines(int arg); // paint lines on image void paint_toparc(int arg); // paint arc on image void paint_gridlines(); // paint grid lines on image void draw_line(int x1, int y1, int x2, int y2); // draw line, image space void erase_line(int x1, int y1, int x2, int y2); // erase line void draw_pixel(int px, int py, GdkColor *color); // draw one pixel using color void draw_fat_pixel(int px, int py, GdkColor *color); // draw one fat pixel using color void add_toptext(int ID, int px, int py, cchar *text, cchar *font); // paint text on window (image space) void erase_toptext(int ID); // remove all text strings with ID void paint_toptext(); // paint text strings when window repainted void paint_text(int px, int py, cchar *text, cchar *font); // paint text on window (window space) void add_topcircle(int px, int py, int radius, int color); // paint circles on window (image space) void erase_topcircles(); // remove all red circles void paint_topcircles(); // paint red circles when window repainted typedef void CBfunc(); // callback function type EX CBfunc *mouseCBfunc; // current mouse handler function void takeMouse(zdialog *zd, CBfunc func, GdkCursor *); // capture mouse for dialog v.11.03 void freeMouse(); // free mouse for main window // spline curve edit functions spldat * splcurve_init(GtkWidget *frame, void func(int spc)); // initialize spline curves int splcurve_adjust(void *, GdkEventButton *event, spldat *); // curve editing function int splcurve_draw(void *, void *, spldat *); // curve drawing function int splcurve_generate(spldat *, int spc); // generate data from anchor points double splcurve_yval(spldat *, int spc, double xval); // get curve y-value int splcurve_load(spldat *sd); // load curve from a file int splcurve_save(spldat *sd); // save curve to a file // file menu functions void m_gallery(GtkWidget *, cchar *); // show image gallery window void m_gallery2(int Nth, int button); // receives clicked files void m_clone1(GtkWidget *, cchar *); // start new fotoxx window (desktop 50/50) void m_clone2(GtkWidget *, cchar *); // start new fotoxx window (overlay prior) void m_open(GtkWidget *, cchar *); // open image file in same window void m_open_drag(int x, int y, char *file); // open drag-drop file void m_open_newin(GtkWidget *, cchar *); // open image file in new window void m_previous(GtkWidget *, cchar *); // open previously accessed file void m_recent(GtkWidget *, cchar *); // open recently accessed file void add_recent_file(cchar *file); // add file to recent file list int f_open(cchar *file, int flock, int Nth = 0, int fswitch = 0); // set new current file void m_prev(GtkWidget *, cchar *); // open previous file in gallery void m_next(GtkWidget *, cchar *); // open next file in gallery void m_save(GtkWidget *, cchar *); // save modified image to same file void m_savevers(GtkWidget *, cchar *); // save modified image to new file version void m_saveas(GtkWidget *, cchar *); // save modified image to another file void m_zoom(GtkWidget *, cchar *); // zoom image +/- void m_create(GtkWidget *, cchar *); // create new blank image file void m_trash(GtkWidget *, cchar *); // move image to trash void m_rename(GtkWidget *, cchar *); // rename file void m_batchrename(GtkWidget *, cchar *); // rename many files, base + sequence void m_print(GtkWidget *, cchar *); // print image file void m_quit(GtkWidget *, cchar *); // exit application // tools menu functions void m_manage_collections(GtkWidget *, cchar *); // create and edit image collections void m_move_collections(GtkWidget *, cchar *); // change top image directory void edit_coll_popmenu(GtkWidget *, char *file); // popup menu for editing collections void m_batchconvert(GtkWidget *, cchar *); // convert/resize/export multiple image files void m_conv_raw(GtkWidget *, cchar *); // convert RAW files to tiff void m_slideshow(GtkWidget *, cchar *); // enter or leave slideshow mode void slideshow_next(cchar *); // show prev/next image void m_syncfiles(GtkWidget *, cchar *); // rebuild thumbnails and search index int syncfiles_func(void *); // sync files function (in subprocess) void m_show_RGB(GtkWidget *, cchar *); // show RGB values at mouse click void m_gridlines(GtkWidget *, cchar *); // set up grid lines void load_grid(int *griddata); // load grid from saved state void save_grid(int *griddata); // save grid to saved state void toggle_grid(int action); // set grid off/on or toggle (0/1/2) void m_burn(GtkWidget *, cchar *); // burn selected images to CD/DVD void m_email(GtkWidget *, cchar *); // e-mail selected images void m_moncheck(GtkWidget *, cchar *); // check monitor brightness and color void m_mongamma(GtkWidget *, cchar *); // adjust monitor gamma void m_histogram(GtkWidget *, cchar *); // start brightness histogram void histogram_paint(); // update brightness histogram void histogram_destroy(); // remove histogram window void m_lang(GtkWidget *, cchar *); // change language void m_translate(GtkWidget *, cchar *); // edit translation void m_menu_launcher(GtkWidget *, cchar *); // make desktop menu entry and launcher void m_settings(GtkWidget *, cchar *); // user settings void m_memory_usage(GtkWidget *, cchar *); // report memory consumption by category // info menu functions (EXIF, IPTC, etc.) void m_edit_cctext(GtkWidget *, cchar *); // edit caption and user comments dialog void m_edit_tags(GtkWidget *, cchar *); // edit tags dialog void m_manage_tags(GtkWidget *, cchar *); // manage tags dialog void load_fileinfo(cchar *file); // EXIF/IPTC >> tags_date, _stars, _filetags void save_fileinfo(cchar *file); // tags_date, _stars, _filetags >> EXIF/IPTC void update_search_index(cchar *file); // update search index file void delete_search_index(cchar *file); // delete entry from search index file void m_batchAddTags(GtkWidget *, cchar *); // add tags to many files at once void m_batchDelTag(GtkWidget *, cchar *); // delete/replace a tag for many files void m_info_view_short(GtkWidget *, cchar *); // view selected EXIF/IPTC data void m_info_view_long(GtkWidget *, cchar *); // view all EXIF/IPTC data void info_view(int length); // view EXIF/IPTC data in popup window void m_info_edit(GtkWidget *, cchar *); // add or change EXIF/IPTC data void m_info_delete(GtkWidget *, cchar *); // delete EXIF/IPTC data char ** info_get(cchar *file, cchar **keys, int nkeys); // get EXIF/IPTC data for given key(s) char ** info_getN(cchar **files, int NF, cchar **keys, int NK); // " " data for given keys and files int info_put(cchar *file, cchar **keys, cchar **text, int nkeys); // put EXIF/IPTC data for given key(s) int info_copy(cchar *f1, cchar *f2, cchar **k, cchar **t, int nk); // copy EXIF/IPTC data from file to file void m_search_images(GtkWidget *, cchar *); // search tags, comments, captions, files void m_search_metadata(GtkWidget *, cchar *); // search and report image metadata // select area menu functions void m_select(GtkWidget *, cchar *); // select area within image void m_select_show(GtkWidget *, cchar *); // enable area for subsequent edits void m_select_hide(GtkWidget *, cchar *); // show area outline void m_select_enable(GtkWidget *, cchar *); // hide area outline void m_select_disable(GtkWidget *, cchar *); // disable area void m_select_invert(GtkWidget *, cchar *); // invert area void m_select_unselect(GtkWidget *, cchar *); // unselect area void m_select_copy(GtkWidget *, cchar *); // copy area, save in memory void m_select_paste(GtkWidget *, cchar *); // paste saved area into image void m_select_open(GtkWidget *, cchar *); // open an area file, save in memory void m_select_save(GtkWidget *, cchar *); // save area to a file void m_select_whole_image(GtkWidget *, cchar *); // select whole image area void m_select_edit(GtkWidget *, cchar *); // select and edit in parallel // functions for area selection using the mouse void sa_geom_mousefunc(); // select rectangle or ellipse void sa_draw_mousefunc(); // line drawing functions int sa_nearpix(int mx, int my, int rad, int &npx, int &npy); // find nearest line-end void sa_draw_line(int px1, int py1, int px2, int py2); // draw a connected line void sa_draw1pix(int px, int py); // draw one pixel if not already void sa_mouse_mousefunc(); // select by radius and color match void sa_nextseq(); // start next sequence number void sa_unselect_pixels(); // remove current selection // other select area functions void sa_finish(); // finish - map interior pixels void sa_finish_auto(); // finish - interior pixels already known void sa_map_pixels(); // map edge and interior pixels void sa_unfinish(); // set finished area back to edit mode void sa_show(int flag); // show or hide area void sa_enable(); // enable area void sa_disable(); // disable area void sa_invert(); // invert area void sa_unselect(); // unselect area void sa_edgecalc(); // calculate edge distances // image edit functions - transform menu void m_rotate(GtkWidget *, cchar *); // rotate image void m_trim(GtkWidget *, cchar *); // trim image void m_autotrim(GtkWidget *, cchar *); // autotrim image after rotate, warp void m_resize(GtkWidget *, cchar *); // resize image void m_annotate(GtkWidget *, cchar *); // annotate image void m_flip(GtkWidget *, cchar *); // flip horizontally or vertically void m_negate(GtkWidget *, cchar *); // B+W and color negatives void m_unbend(GtkWidget *, cchar *); // fix perspective problems void m_keystone(GtkWidget *, cchar *); // convert tetragon image to rectangle void m_warp_area(GtkWidget *, cchar *); // warp image within an area void m_warp_curved(GtkWidget *, cchar *); // warp image, curved transform void m_warp_linear(GtkWidget *, cchar *); // warp image, linear transform void m_warp_affine(GtkWidget *, cchar *); // warp image, affine transform // image edit functions - retouch menu void m_tune(GtkWidget *, cchar *); // brightness / color adjustments void m_gamma(GtkWidget *, cchar *); // gamma adjustments void m_xbrange(GtkWidget *, cchar *); // clip brightness, expand rest void m_flatten(GtkWidget *, cchar *); // flatten brightness distribution void m_brightramp(GtkWidget *, cchar *); // ramp brightness across image void m_tonemap(GtkWidget *, cchar *); // tone mapping void m_whitebal(GtkWidget *, cchar *); // adjust white balance void m_match_color(GtkWidget *, cchar *); // set image2 colors to match image1 void m_DRGB(GtkWidget *, cchar *); // brightness / color adjust with OD units void m_revise_RGB(GtkWidget *, cchar *); // revise RGB values void m_redeye(GtkWidget *, cchar *); // red-eye removal void m_blur(GtkWidget *, cchar *); // blur image void m_sharpen(GtkWidget *, cchar *); // sharpen image void m_denoise(GtkWidget *, cchar *); // image noise reduction void m_smart_erase(GtkWidget *, const char *); // smart erase object void m_dust(GtkWidget *, const char *); // remove dust void m_stuckpix(GtkWidget *, const char *); // fix stuck pixels void m_pixedit(GtkWidget *, cchar *); // edit pixels // image edit functions - art menu void m_colordep(GtkWidget *, cchar *); // set color depth 1-16 bits/color void m_draw(GtkWidget *, cchar *); // make simulated drawing void m_outlines(GtkWidget *, cchar *); // make an outline image void m_emboss(GtkWidget *, cchar *); // make simulated embossing void m_tiles(GtkWidget *, cchar *); // make simulated tiles (pixelate) void m_dots(GtkWidget *, cchar *); // convert image to dot matrix form void m_painting(GtkWidget *, cchar *); // make simulated painting // image edit functions - combine menu void m_HDR(GtkWidget *, cchar *); // make HDR composite image void m_HDF(GtkWidget *, cchar *); // make HDF composite image void m_STP(GtkWidget *, cchar *); // stack / paint image void m_STN(GtkWidget *, cchar *); // stack / noise reduction void m_pano(GtkWidget *, cchar *); // make panorama composite image void m_vpano(GtkWidget *, cchar *); // make vertical panorama // plugin functions // v.11.03 void m_run_plugin(GtkWidget *, cchar *); // perform a plugin edit function void m_edit_plugins(GtkWidget *, cchar *); // add and remove plugin functions // edit support functions int edit_setup(editfunc &EF); // start new edit transaction void edit_suspend(); // suspend edit function (parallel) void edit_cancel(editfunc &EF); // cancel edit void edit_done(editfunc &EF); // commit edit, add undo stack void edit_takeover(editfunc &EF); // set current (parallel) edit func void edit_undo(); // undo edit, back to org. image void edit_redo(); // redo the edit after undo void edit_reset(); // reset to initial status void edit_zapredo(); // clear image redo copy void edit_fullsize(); // convert to full-size pixmaps void m_undo(GtkWidget *, cchar *); // toolbar, undo one edit void m_redo(GtkWidget *, cchar *); // toolbar, redo one edit void undo_all(); // undo all edits of current image void save_undo(cchar *funcname); // undo/redo save function void load_undo(); // undo/redo read function int mod_keep(); // query keep/discard edited image int menulock(int lock); // lock/unlock menu for some funcs int is_syncbusy(); // check Fsyncbusy, message user to wait // thread support functions typedef void * threadfunc(void *); // edit thread function void start_thread(threadfunc func, void *arg); // start edit thread void signal_thread(); // signal thread, work is pending void wait_thread_idle(); // wait for work complete void wrapup_thread(int command); // wait for exit or command exit void thread_idle_loop(); // thread: wait for work or exit command void thread_exit(); // thread: exit unconditionally void start_wthread(threadfunc func, void *arg); // start working thread (per processor core) void exit_wthread(); // exit working thread void wait_wthreads(); // wait for working threads // other support functions void m_help(GtkWidget *, cchar *); // various help functions void load_params(); // load parameters from prior session void save_params(); // save parameters for next session void brhood_calc(int radius, char method); // compute neighborhood brightness float get_brhood(int px, int py); // get pixel neighborhood brightness void free_resources(int fkeepundo = 0); // free all allocated resources int vpixel(PXM *pxm, double px, double py, uint16 *vpix); // get virtual pixel at (px,py) int sigdiff(double d1, double d2, double signf); // test for significant difference // file load and save functions PXM * f_load(cchar *filespec, int bpc); // load a file into an PXM pixmap int f_save(char *outfile, cchar *type, int bpc); // save current image pixmap to a file PXM * TIFFread(cchar *filespec); // read TIFF file, native bpc int TIFFwrite(PXM *pxm, cchar *filespec); // write TIFF file, bpc from pxm PXM * PXBread(cchar *filespec); // read using pixbuf library, bpc = 8 int PXBwrite(PXM *pxm, cchar *filespec); // write using pixbuf library, bpc = 8 // PXM pixmap conversion functions PXM * PXM_make(int ww, int hh, int bpc); // initialize PXM pixmap void PXM_free(PXM *&pxm); // free PXM pixmap PXM * PXM_copy(PXM *pxm); // copy PXM pixmap PXM * PXM_copy_area(PXM *pxm, int orgx, int orgy, int ww, int hh); // copy section of PXM pixmap PXM * PXM_convbpc(PXM *pxm); // convert from 8/16 to 16/8 bpc void PXM_fixblue(PXM *pxm); // set blue = 0 pixels to blue = 2 PXM * PXM_rescale(PXM *pxm, int ww, int hh); // rescale PXM pixmap (ww/hh) void PXM_update(PXM *p16, PXM *p8, int orgx, int orgy, int ww, int hh); // copy section of PXM-16 into PXM-8 PXM * PXM_rotate(PXM *pxm, double angle); // rotate PXM pixmap // image navigation and thumbnail gallery functions // for functions returning char *, caller responsible for zfree() char * image_gallery(cchar *filez, cchar *action, int Nth = 0, // display image gallery window, navigate, void ufunc(int Nth, int butt) = 0, GtkWidget *parent = 0); // do callback for clicked thumbnails int image_gallery_position(cchar *file, int Nth); // get relative position of file in gallery int image_file_type(cchar *file); // determine if directory or image file type char * image_thumbfile(char *imagefile); // get thumbnail filespec, create if missing GdkPixbuf * image_thumbnail(char *imagefile, int size = 0); // get thumbnail pixbuf, create if missing char ** image_gallery_getfiles(char *startdir, GtkWidget *parent = 0); // select files from gallery window // translatable strings used in multiple dialogs #define Babsolute ZTX("absolute") #define Badd ZTX("Add") #define Baddall ZTX("Add All") #define Ball ZTX("All") #define Bamount ZTX("Amount") #define Bapply ZTX("Apply") #define Bblack ZTX("Black") #define Bblendwidth ZTX("Blend Width") #define Bblue ZTX("Blue") #define Bbrightness ZTX("Brightness") #define Bbrowse ZTX("Browse") #define Bcancel ZTX("Cancel") #define Bclear ZTX("Clear") #define Bcolor ZTX("Color") #define Bcommit ZTX("Commit") #define Bcopy ZTX("Copy") #define Bcurvefile ZTX("Curve File:") #define Bcut ZTX("Cut") #define Bdarker ZTX("Darker Areas") #define Bdelete ZTX("Delete") #define Bdisable ZTX("Disable") #define Bdiscard ZTX("Discard special gallery list? \n %s") #define Bdone ZTX("Done") #define Bedit ZTX("Edit") #define Benable ZTX("Enable") #define Berase ZTX("Erase") #define Bexiftoolmissing ZTX("package libimage-exiftool-perl is required") #define Bfetch ZTX("Fetch") #define Bfinish ZTX("Finish") #define Bfont ZTX("Font") #define Bgreen ZTX("Green") #define Bheight ZTX("Height") #define Bhistogram ZTX("histogram") #define Bhide ZTX("Hide") #define Binsert ZTX("Insert") #define Binvert ZTX("Invert") #define Blighter ZTX("Lighter Areas") #define Blimit ZTX("limit") #define Bnew ZTX("New") #define Bnext ZTX("Next") #define BOK ZTX("OK") #define Bopen ZTX("Open") #define Bopenrawfile ZTX("Open RAW File") #define Bpaste ZTX("Paste") #define Bpause ZTX("Pause") #define Bpercent ZTX("Percent") #define Bpresets ZTX("Presets") #define Bproceed ZTX("Proceed") #define Bradius ZTX("Radius") #define Brange ZTX("range") #define Bred ZTX("Red") #define Bredo ZTX("Redo") #define Breduce ZTX("Reduce") #define Bremove ZTX("Remove") #define Breset ZTX("Reset") #define Bsave ZTX("Save") #define Bsavetoedit ZTX("Unknown file type, save as tiff/jpeg/png to edit") #define Bsearch ZTX("Search") #define Bselect ZTX("Select") #define Bselectfiles ZTX("Select Files") #define Bshow ZTX("Show") #define Bstart ZTX("Start") #define Bthresh ZTX("Threshold") #define Btoomanyfiles ZTX("exceed %d files") #define Bundoall ZTX("Undo All") #define Bundolast ZTX("Undo Last") #define Bundo ZTX("Undo") #define Bunfinish ZTX("Unfinish") #define Bunselect ZTX("Unselect") #define Bview ZTX("View") #define Bwhite ZTX("White") #define Bwidth ZTX("Width") fotoxx-12.01.2/locales/0000755000175000017500000000000011701011017013253 5ustar micomicofotoxx-12.01.2/locales/fotoxx-en.po0000644000175000017500000014215511701011017015552 0ustar micomico# English translations for home package. # Copyright (C) 2011 THE home'S COPYRIGHT HOLDER # This file is distributed under the same license as the home package. # mico , 2011. # msgid "" msgstr "" "Project-Id-Version: home 2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 20:58+0100\n" "PO-Revision-Date: 2011-01-01 11:29+0100\n" "Last-Translator: mico \n" "Language-Team: English\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "Set color depth to 1-16 bits" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Set Color Depth" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Simulate Drawing" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "contrast" #: f.art.cc:215 msgid "outlines" msgstr "outlines" #: f.art.cc:220 msgid "pencil" msgstr "pencil" #: f.art.cc:221 msgid "chalk" msgstr "chalk" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "Add Image Outlines" #: f.art.cc:394 msgid "outline threshold" msgstr "outline threshold" #: f.art.cc:397 msgid "outline width" msgstr "outline width" #: f.art.cc:400 msgid "image brightness" msgstr "image brightness" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Simulate Embossing" #: f.art.cc:626 msgid "depth" msgstr "depth" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "color" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Simulate Tiles" #: f.art.cc:825 msgid "tile size" msgstr "tile size" #: f.art.cc:829 msgid "tile gap" msgstr "tile gap" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "Convert Image to Dots" #: f.art.cc:1007 msgid "dot size" msgstr "dot size" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Simulate Painting" #: f.art.cc:1226 msgid "color depth" msgstr "color depth" #: f.art.cc:1230 msgid "patch area goal" msgstr "patch area goal" #: f.art.cc:1234 msgid "req. color match" msgstr "req. color match" #: f.art.cc:1238 msgid "borders" msgstr "borders" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "Select 2 to 9 files" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Images are not all the same size" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "Adjust Image Contributions" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "dark pixels" #: f.comp.cc:2326 msgid "light pixels" msgstr "light pixels" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "file:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "Paint and Warp Image" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "image" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "paint" #: f.comp.cc:2851 msgid "warp" msgstr "warp" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "Select and Paint Image" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "Adjust Pixel Composition" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "Select 2 to 4 files" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "Search for lens mm and bow" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Pre-align Images" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "lens mm" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "lens bow" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "Resize" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "resize window" #: f.comp.cc:4457 msgid "use two images only" msgstr "use two images only" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Too little overlap, cannot align" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "Match Brightness and Color" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "auto color" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "file color" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Open Image File" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "prior function still active" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "Overwrite original file?" #: f.file.cc:504 msgid "Do not warn again" msgstr "Do not warn again" #: f.file.cc:520 msgid "Warning" msgstr "Warning" #: f.file.cc:643 msgid "Save File" msgstr "Save File" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "quality" #: f.file.cc:668 msgid "make current" msgstr "make current" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "jpeg quality must be 1-100" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Overwrite file? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "Create Blank Image" #: f.file.cc:905 msgid "file name" msgstr "file name" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "width" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "height" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "Move read-only file to trash?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "Cannot create trash folder: %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "error: %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Rename Image File" #: f.file.cc:1141 msgid "old name" msgstr "old name" #: f.file.cc:1142 msgid "rename to" msgstr "rename to" #: f.file.cc:1143 msgid "previous" msgstr "previous" #: f.file.cc:1229 msgid "The target file already exists" msgstr "The target file already exists" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" "Rename failed: \n" " %s" #: f.file.cc:1285 msgid "Batch Rename" msgstr "Batch Rename" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "%d files selected" #: f.file.cc:1290 msgid "new base name" msgstr "new base name" #: f.file.cc:1293 msgid "starting sequence" msgstr "starting sequence" #: f.file.cc:1295 msgid "increment" msgstr "increment" #: f.file.cc:1316 msgid "select files to rename" msgstr "select files to rename" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "base name / sequence / increment not reasonable" #: f.file.cc:1380 msgid "new file already exists:" msgstr "new file already exists:" #: f.file.cc:1388 msgid "filespec too long:" msgstr "filespec too long:" #: f.file.cc:1399 msgid "Rename failed:" msgstr "Rename failed:" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "Add" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "Remove" #: f.file.cc:1662 msgid "menu name" msgstr "menu name" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "Restart Fotoxx to update plugin menu" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "Edit Caption and Comments" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Edit Tags" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "image date (yyyymmdd)" #: f.info.cc:165 msgid "use last" msgstr "use last" #: f.info.cc:168 msgid "image stars" msgstr "image stars" #: f.info.cc:186 msgid "current tags" msgstr "current tags" #: f.info.cc:191 msgid "recent tags" msgstr "recent tags" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "defined tags" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "Manage Tags" #: f.info.cc:348 msgid "category" msgstr "category" #: f.info.cc:351 msgid "tag" msgstr "tag" #: f.info.cc:354 msgid "create" msgstr "create" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "delete" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "search index file error: %s" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "Batch Add Tags" #: f.info.cc:1354 msgid "tags to add" msgstr "tags to add" #: f.info.cc:1359 msgid "create tag" msgstr "create tag" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " too many tags" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "Batch Delete Tag" #: f.info.cc:1556 msgid "tag to remove" msgstr "tag to remove" #: f.info.cc:1560 msgid "optional replacement" msgstr "optional replacement" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "0 files selected" #: f.info.cc:1568 msgid "search all files" msgstr "search all files" #: f.info.cc:1653 msgid "no files selected" msgstr "no files selected" #: f.info.cc:1659 msgid "no tag specified" msgstr "no tag specified" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "specify tag" #: f.info.cc:1821 msgid "View Info" msgstr "View Info" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "Edit Info" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "Delete Info" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "All" #: f.info.cc:1990 msgid "One Key:" msgstr "One Key:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "Search Tags, Comments, File Names" #: f.info.cc:2350 msgid "date range" msgstr "date range" #: f.info.cc:2351 msgid "stars range" msgstr "stars range" #: f.info.cc:2352 msgid "search tags" msgstr "search tags" #: f.info.cc:2353 msgid "search text" msgstr "search text" #: f.info.cc:2354 msgid "file names" msgstr "file names" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "(yyyymmdd)" #: f.info.cc:2365 msgid "all/any" msgstr "all/any" #: f.info.cc:2702 msgid "No matching images found" msgstr "No matching images found" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "No search index file present" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "Additional Items for Report" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "bigger" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "increase thumbnail size" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "reduce thumbnail size" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "smaller" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "parent" #: f.navi.cc:190 msgid "parent directory" msgstr "parent directory" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "first page" #: f.navi.cc:191 msgid "jump to first file" msgstr "jump to first file" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "prev page" #: f.navi.cc:192 msgid "previous page" msgstr "previous page" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "prev row" #: f.navi.cc:193 msgid "previous row" msgstr "previous row" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "next row" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "next page" #: f.navi.cc:195 msgid "ttip::next page" msgstr "next page" #: f.navi.cc:196 msgid "jump to last file" msgstr "jump to last file" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "last page" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "close" #: f.navi.cc:197 msgid "close image gallery" msgstr "close image gallery" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "Select Files" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "cancel" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "done" #: f.navi.cc:1422 msgid "insert" msgstr "insert" #: f.navi.cc:1423 msgid "add all" msgstr "add all" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Adjust Brightness and Color" #: f.retouch.cc:110 msgid "small-steps" msgstr "small-steps" #: f.retouch.cc:119 msgid "color saturation" msgstr "color saturation" #: f.retouch.cc:126 msgid " reset 1 " msgstr " reset 1 " #: f.retouch.cc:127 msgid "reset all" msgstr "reset all" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "adjust image gamma" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "Expand Brightness Range" #: f.retouch.cc:887 msgid "bright pixels" msgstr "bright pixels" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Flatten Brightness Distribution" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Flatten" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "Ramp brightness across image" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "Tone Mapping" #: f.retouch.cc:1758 msgid "low" msgstr "low" #: f.retouch.cc:1760 msgid "high" msgstr "high" #: f.retouch.cc:1763 msgid "Amplify" msgstr "Amplify" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Adjust White Balance" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Click white or gray image location" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "Color Match Images" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "mouse radius for color sample" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Open" #: f.retouch.cc:2310 msgid "image for source color" msgstr "image for source color" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "click on image to get source color" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "image to set matching color" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "click on image to set matching color" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "select source image color first" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "Add standard bias" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "+Brightness -Density" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "+Red -Cyan" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "+Green -Magenta" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "+Blue -Yellow" #: f.retouch.cc:2599 msgid "Contrast" msgstr "Contrast" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Red" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Green" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Blue" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "Load DRGB parameters" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "File:" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "DRGB parameters file" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "file not found" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "Save DRGB parameters" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "Click image to select pixels." #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "Revise RGB" #: f.retouch.cc:3084 msgid "Metric:" msgstr "Metric:" #: f.retouch.cc:3139 msgid "Blend" msgstr "Blend" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Red Eye Reduction" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Set Blur Radius" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Sharpen Image" #: f.retouch.cc:4202 msgid "edge detection" msgstr "edge detection" #: f.retouch.cc:4203 msgid "cycles" msgstr "cycles" #: f.retouch.cc:4204 msgid "reduce" msgstr "reduce" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "unsharp mask" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "brightness gradient" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Noise Reduction" #: f.retouch.cc:4650 msgid "algorithm" msgstr "algorithm" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "flatten outliers by color (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "flatten outliers by color (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "set median brightness by color" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "top hat filter by color" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "Smart Erase" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Radius" #: f.retouch.cc:5005 msgid "Blur" msgstr "Blur" #: f.retouch.cc:5008 msgid "New Area" msgstr "New Area" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "Remove Dust" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "spot size limit" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "max. brightness" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "min. contrast" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "Fix Stuck Pixels" #: f.retouch.cc:5989 msgid "pixel group" msgstr "pixel group" #: f.retouch.cc:5990 msgid "circle color" msgstr "circle color" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "Load Stuck Pixels" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "Stuck Pixels file" #: f.retouch.cc:6164 msgid "file format error" msgstr "file format error" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "there are zero stuck pixels" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "Save Stuck Pixels" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Undo Memory %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Edit Pixels" #: f.retouch.cc:6695 msgid "pick" msgstr "pick" #: f.retouch.cc:6697 msgid "erase" msgstr "erase" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "paintbrush radius" #: f.retouch.cc:6706 msgid "transparency center" msgstr "transparency center" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "transparency edge" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Select Area for Edits" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "Press F1 for help" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" "Select Area not supported \n" "by this edit function" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "rectangle" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "ellipse" #: f.select.cc:110 msgid "draw: freehand" msgstr "draw: freehand" #: f.select.cc:111 msgid "draw: follow edge" msgstr "draw: follow edge" #: f.select.cc:114 msgid "select by mouse" msgstr "select by mouse" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "mouse radius" #: f.select.cc:120 msgid "match mouse color" msgstr "match mouse color" #: f.select.cc:124 msgid "search range" msgstr "search range" #: f.select.cc:126 msgid "firewall" msgstr "firewall" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "exceed %d edits" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." #: f.select.cc:1078 msgid "finish area" msgstr "finish area" #: f.select.cc:1113 msgid "searching" msgstr "searching" #: f.select.cc:1185 msgid "outline has a gap" msgstr "outline has a gap" #: f.select.cc:1189 msgid "success" msgstr "success" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "the area is not finished" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Edge calculation in progress" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Area Edge Calc" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "position with mouse click/drag" #: f.select.cc:1887 msgid "Paste Image" msgstr "Paste Image" #: f.select.cc:1901 msgid "angle" msgstr "angle" #: f.select.cc:2160 msgid "load select area from a file" msgstr "load select area from a file" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "cannot open .tiff and .info files" #: f.select.cc:2213 msgid "save select area to a file" msgstr "save select area to a file" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "Select Whole Image" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "Edit Function Amplifier" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "Edit function must be active" #: f.select.cc:2499 msgid "power: center" msgstr "power: center" #: f.select.cc:2501 msgid "edge" msgstr "edge" #: f.select.cc:2504 msgid "reset area" msgstr "reset area" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "Manage Collections" #: f.tools.cc:85 msgid "Start new collection" msgstr "Start new collection" #: f.tools.cc:87 msgid "Edit a collection" msgstr "Edit a collection" #: f.tools.cc:89 msgid "View a collection" msgstr "View a collection" #: f.tools.cc:91 msgid "Delete a collection" msgstr "Delete a collection" #: f.tools.cc:95 msgid "Editing:" msgstr "Editing:" #: f.tools.cc:99 msgid "Action:" msgstr "Action:" #: f.tools.cc:133 msgid "New Collection" msgstr "New Collection" #: f.tools.cc:156 msgid "Edit Collection" msgstr "Edit Collection" #: f.tools.cc:172 msgid "View Collection" msgstr "View Collection" #: f.tools.cc:193 msgid "Delete Collection" msgstr "Delete Collection" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "delete %s ?" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "add image to collection: %s" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "remove image from collection" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "remove and save image" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "insert saved images here" #: f.tools.cc:256 msgid "add image to collection" msgstr "add image to collection" #: f.tools.cc:301 msgid "too many saved files" msgstr "too many saved files" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "Move Collections" #: f.tools.cc:375 msgid "old top directory" msgstr "old top directory" #: f.tools.cc:378 msgid "new top directory" msgstr "new top directory" #: f.tools.cc:434 msgid "completed" msgstr "completed" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "Batch Convert/Resize/Export" #: f.tools.cc:474 msgid "new max. width" msgstr "new max. width" #: f.tools.cc:481 msgid "new file type" msgstr "new file type" #: f.tools.cc:482 msgid "same" msgstr "same" #: f.tools.cc:490 msgid "replace originals" msgstr "replace originals" #: f.tools.cc:491 msgid "export to location" msgstr "export to location" #: f.tools.cc:492 msgid "remove EXIF" msgstr "remove EXIF" #: f.tools.cc:549 msgid "Select directory" msgstr "Select directory" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "replace original files? (max. %d x %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "copy files? (max. %d x %d) \n" " to location %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "location is not a valid directory" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "max. size %d x %d is not reasonable" #: f.tools.cc:654 msgid "*** file already exists" msgstr "*** file already exists" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "*** file type not supported" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "Program ufraw-batch is required" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Open RAW File" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "Select RAW files to convert" #: f.tools.cc:769 msgid "Choose file type" msgstr "Choose file type" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "Press ESC to exit slide show" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "show only latest file versions" #: f.tools.cc:893 msgid "arrow keys" msgstr "arrow keys" #: f.tools.cc:894 msgid "instant" msgstr "instant" #: f.tools.cc:895 msgid "fade-in" msgstr "fade-in" #: f.tools.cc:896 msgid "roll-right" msgstr "roll-right" #: f.tools.cc:897 msgid "roll-down" msgstr "roll-down" #: f.tools.cc:898 msgid "shift-left" msgstr "shift-left" #: f.tools.cc:899 msgid "venetian" msgstr "venetian" #: f.tools.cc:900 msgid "grate" msgstr "grate" #: f.tools.cc:903 msgid "radar" msgstr "radar" #: f.tools.cc:904 msgid "jaws" msgstr "jaws" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Slide Show" #: f.tools.cc:915 msgid "seconds" msgstr "seconds" #: f.tools.cc:919 msgid "music file" msgstr "music file" #: f.tools.cc:923 msgid "transitions" msgstr "transitions" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "Select music file or playlist" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "Sync Files is already running" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "no top image directory is defined" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "top image directory is invalid" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "no search index file is present" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "new/modified files are present" #: f.tools.cc:1844 msgid "no new files found" msgstr "no new files found" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "Synchronize Files" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Top Image Directory:" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "file sync is necessary.\n" "cancel anyway?" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "top directory is invalid" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Select top image directory" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "Show RGB" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "Grid Lines" #: f.tools.cc:2728 msgid "x-spacing" msgstr "x-spacing" #: f.tools.cc:2729 msgid "x-count" msgstr "x-count" #: f.tools.cc:2730 msgid "x-enable" msgstr "x-enable" #: f.tools.cc:2736 msgid "y-spacing" msgstr "y-spacing" #: f.tools.cc:2737 msgid "y-count" msgstr "y-count" #: f.tools.cc:2738 msgid "y-enable" msgstr "y-enable" #: f.tools.cc:2745 msgid "x-offset" msgstr "x-offset" #: f.tools.cc:2749 msgid "y-offset" msgstr "y-offset" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "E-mail Images" #: f.tools.cc:2947 msgid "max. width" msgstr "max. width" #: f.tools.cc:2948 msgid "max. height" msgstr "max. height" #: f.tools.cc:3093 msgid "too many files" msgstr "too many files" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." #: f.tools.cc:3174 msgid "Monitor Check" msgstr "Monitor Check" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "Monitor Gamma" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "Brightness Distribution" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Available Translations" #: f.tools.cc:3436 msgid "Set Language" msgstr "Set Language" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "Make Launcher" #: f.tools.cc:3540 msgid "Settings" msgstr "Settings" #: f.tools.cc:3545 msgid "Startup Display" msgstr "Startup Display" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "Recent Files Gallery" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "Previous Image Viewed" #: f.tools.cc:3549 msgid "Blank Window" msgstr "Blank Window" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "Directory Gallery" #: f.tools.cc:3556 msgid "Image File" msgstr "Image File" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "Toolbar Style" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "Text" #: f.tools.cc:3564 msgid "Icons" msgstr "Icons" #: f.tools.cc:3565 msgid "Both" msgstr "Both" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "Warn Overwrite" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "startup directory is invalid" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "startup file is invalid" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "Select startup directory" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "Select startup image file" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "Use buttons or drag right edge with mouse" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Rotate Image" #: f.transform.cc:64 msgid "degrees" msgstr "degrees" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Trim" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "Grid" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Undo Trim" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "degrees: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "gold" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "Drag middle to move, drag corners to resize." #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Trim Image" #: f.transform.cc:348 msgid "customize" msgstr "customize" #: f.transform.cc:359 msgid "ratio" msgstr "ratio" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "Lock Ratio" #: f.transform.cc:368 msgid "invert" msgstr "invert" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "Trim Buttons" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "Lock aspect ratio" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Resize Image" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Prev" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" "Enter text, click/drag on image.\n" "Right click to remove" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "Annotate Image" #: f.transform.cc:1307 msgid "Size" msgstr "Size" #: f.transform.cc:1310 msgid "Angle" msgstr "Angle" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Color" #: f.transform.cc:1322 msgid "Transparency" msgstr "Transparency" #: f.transform.cc:1325 msgid "text" msgstr "text" #: f.transform.cc:1330 msgid "backing" msgstr "backing" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" "Outline\n" " Width" #: f.transform.cc:1335 msgid "outline" msgstr "outline" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "Annotation File:" #: f.transform.cc:1416 msgid "select font" msgstr "select font" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "Flip Image" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "horizontal" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "vertical" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "Make Negative" #: f.transform.cc:2158 msgid "black/white positive" msgstr "black/white positive" #: f.transform.cc:2159 msgid "black/white negative" msgstr "black/white negative" #: f.transform.cc:2160 msgid "color positive" msgstr "color positive" #: f.transform.cc:2161 msgid "color negative" msgstr "color negative" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Unbend Image" #: f.transform.cc:2282 msgid "linear" msgstr "linear" #: f.transform.cc:2285 msgid "curved" msgstr "curved" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "Keystone Correction" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "must have 4 corners" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "Warp Image (area)" #: f.transform.cc:2864 msgid "start warp" msgstr "start warp" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "no active Select Area" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "Warp Image (curved)" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "Warp Image (linear)" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "Warp Image (affine)" #: fotoxx-12.01.cc:185 msgid "File" msgstr "File" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "Image Gallery" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "Clone 50/50" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "Clone Overlay" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "Open in New Window" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Open Previous File" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "Open Recent File" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "Save to Same File" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "Save to New Version" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "Save to New File" #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "Trash Image File" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "Batch Rename Files" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Print Image File" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "Quit fotoxx" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "Tools" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "Batch Convert" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "Convert RAW files" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "Burn Images to CD/DVD" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Check Monitor" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Change Language" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "Menu and Launcher" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "User Settings" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "Memory Usage" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "Edit Caption/Comments" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "View Info (short)" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "View Info (long)" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "Search Images" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "Search Metadata" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "Select" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Show" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Hide" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "Enable" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "Disable" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Invert" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "Unselect" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "Copy" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "Paste" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Save" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "Select and Edit" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "Transform" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "Auto-Trim Image" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Retouch" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "Brightness/Color" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "Gamma Curves" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "Expand Brightness" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "Flatten Brightness" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "Brightness Ramp" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "White Balance" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "Match Colors" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Red Eyes" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Blur Image" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Reduce Noise" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Art" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Color Depth" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "Drawing" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "Outlines" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "Embossing" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "Tiles" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "Dots" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "Painting" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Combine" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "High Dynamic Range" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "High Depth of Field" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "Stack / Paint" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "Stack / Noise" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Panorama" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "Vertical Panorama" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "Edit Plugins" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Help" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "About" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "User Guide" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "User Guide Changes" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "Edit Functions Summary" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Change Log" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "Translations" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "Home Page" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "Gallery" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Next" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Open Next File" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Zoom-in (bigger)" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Zoom-out (smaller)" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Undo" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Undo One Edit" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Redo" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Redo One Edit" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "Save+V" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "Save+F" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "Move Image to Trash" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "Trash" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Quit" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "Fotoxx Essentials" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "first time startup" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "Exceed 50 anchor points" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "load curve from a file" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "curve file is invalid" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "curve file has different no. of curves" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "save curve to a file" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "cannot parallel edit" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "exiftool is not installed \n" "edited images will lose EXIF data" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "Too many edits, please save image" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Select area cannot be kept.\n" "Continue?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" "Select area not active.\n" "Continue?" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "Discard edits?" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "Continue" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "Go Back" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "cannot open thumbnail file" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "TIFF open failure" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF bits/color=%d not supported" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "TIFF read failure" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "TIFF write failure" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "file type not supported" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "pixbuf write failure" #: fotoxx.h:728 msgid "absolute" msgstr "absolute" #: fotoxx.h:730 msgid "Add All" msgstr "Add All" #: fotoxx.h:732 msgid "Amount" msgstr "Amount" #: fotoxx.h:733 msgid "Apply" msgstr "Apply" #: fotoxx.h:734 msgid "Black" msgstr "Black" #: fotoxx.h:735 msgid "Blend Width" msgstr "Blend Width" #: fotoxx.h:737 msgid "Brightness" msgstr "Brightness" #: fotoxx.h:738 msgid "Browse" msgstr "Browse" #: fotoxx.h:739 msgid "Cancel" msgstr "Cancel" #: fotoxx.h:740 msgid "Clear" msgstr "Clear" #: fotoxx.h:742 msgid "Commit" msgstr "Commit" #: fotoxx.h:744 msgid "Curve File:" msgstr "Curve File:" #: fotoxx.h:745 msgid "Cut" msgstr "Cut" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Darker Areas" #: fotoxx.h:747 msgid "Delete" msgstr "Delete" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" "Discard special gallery list? \n" " %s" #: fotoxx.h:750 msgid "Done" msgstr "Done" #: fotoxx.h:751 msgid "Edit" msgstr "Edit" #: fotoxx.h:753 msgid "Erase" msgstr "Erase" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "package libimage-exiftool-perl is required" #: fotoxx.h:755 msgid "Fetch" msgstr "Fetch" #: fotoxx.h:756 msgid "Finish" msgstr "Finish" #: fotoxx.h:757 msgid "Font" msgstr "Font" #: fotoxx.h:759 msgid "Height" msgstr "Height" #: fotoxx.h:760 msgid "histogram" msgstr "histogram" #: fotoxx.h:762 msgid "Insert" msgstr "Insert" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Lighter Areas" #: fotoxx.h:765 msgid "limit" msgstr "limit" #: fotoxx.h:766 msgid "New" msgstr "New" #: fotoxx.h:768 msgid "OK" msgstr "OK" #: fotoxx.h:772 msgid "Pause" msgstr "Pause" #: fotoxx.h:773 msgid "Percent" msgstr "Percent" #: fotoxx.h:774 msgid "Presets" msgstr "Presets" #: fotoxx.h:775 msgid "Proceed" msgstr "Proceed" #: fotoxx.h:777 msgid "range" msgstr "range" #: fotoxx.h:780 msgid "Reduce" msgstr "Reduce" #: fotoxx.h:782 msgid "Reset" msgstr "Reset" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Unknown file type, save as tiff/jpeg/png to edit" #: fotoxx.h:785 msgid "Search" msgstr "Search" #: fotoxx.h:789 msgid "Start" msgstr "Start" #: fotoxx.h:790 msgid "Threshold" msgstr "Threshold" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "exceed %d files" #: fotoxx.h:792 msgid "Undo All" msgstr "Undo All" #: fotoxx.h:793 msgid "Undo Last" msgstr "Undo Last" #: fotoxx.h:795 msgid "Unfinish" msgstr "Unfinish" #: fotoxx.h:797 msgid "View" msgstr "View" #: fotoxx.h:798 msgid "White" msgstr "White" #: fotoxx.h:799 msgid "Width" msgstr "Width" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "help file not found: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "cannot open file %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "save screen to file" #: zfuncs.cc:6222 msgid "No" msgstr "No" #: zfuncs.cc:6222 msgid "Yes" msgstr "Yes" #: zfuncs.cc:6447 msgid "open" msgstr "open" #: zfuncs.cc:6452 msgid "choose" msgstr "choose" #: zfuncs.cc:6457 msgid "save" msgstr "save" #: zfuncs.cc:6463 msgid "open folder" msgstr "open folder" #: zfuncs.cc:6468 msgid "create folder" msgstr "create folder" #: zfuncs.cc:6474 msgid "hidden" msgstr "hidden" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "JPG quality 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "margins" #: zfuncs.cc:6737 msgid "top" msgstr "top" #: zfuncs.cc:6738 msgid "bottom" msgstr "bottom" #: zfuncs.cc:6739 msgid "left" msgstr "left" #: zfuncs.cc:6740 msgid "right" msgstr "right" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Initial parameters file created. \n" "Inspect and revise if necessary." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "load parameters from a file" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "save parameters to a file" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "edit parameters" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "list\n" "all" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "load\n" "file" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "save\n" "file" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "add\n" "new" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "apply" #: zfuncs.cc:7479 msgid "apply?" msgstr "apply?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(new parm name)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "add parameter" fotoxx-12.01.2/locales/fotoxx-sv.po0000664000175000017500000017042611701011017015604 0ustar micomico# translation of fotoxx.po to svenska # Swedish translations for fotoxx package # Svenska översättningar för paket fotoxx. # Copyright (C) 2010 THE fotoxx'S COPYRIGHT HOLDER # This file is distributed under the same license as the fotoxx package. # # progdev , 2010. # Peter Landgren , 2010, 2011, 2012. msgid "" msgstr "" "Project-Id-Version: fotoxx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-01-04 02:54+0100\n" "PO-Revision-Date: 2012-01-02 15:40+0100\n" "Last-Translator: Peter Landgren \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Lokalize 1.0\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "Sätt färgdjup till 1-16 bitar" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Välj färgdjup" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Simulera ritning" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "kontrast" #: f.art.cc:215 msgid "outlines" msgstr "konturer" #: f.art.cc:220 msgid "pencil" msgstr "penna" #: f.art.cc:221 msgid "chalk" msgstr "krita" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "Lägg till bildkanter" #: f.art.cc:394 msgid "outline threshold" msgstr "konturtröskel" #: f.art.cc:397 msgid "outline width" msgstr "konturbredd" #: f.art.cc:400 msgid "image brightness" msgstr "bildljushet" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Simulera upphöjning" #: f.art.cc:626 msgid "depth" msgstr "djup" #: f.art.cc:628 f.file.cc:921 f.retouch.cc:6692 msgid "color" msgstr "färg" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Simulera plattor" #: f.art.cc:825 msgid "tile size" msgstr "plattstorlek" #: f.art.cc:829 msgid "tile gap" msgstr "gap mellan plattor" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "Omvandla bild till punkter" #: f.art.cc:1007 msgid "dot size" msgstr "punktstorlek" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Simulera mÃ¥lning" #: f.art.cc:1226 msgid "color depth" msgstr "färgdjup" #: f.art.cc:1230 msgid "patch area goal" msgstr "" #: f.art.cc:1234 msgid "req. color match" msgstr "beg. färgmatchning" #: f.art.cc:1238 msgid "borders" msgstr "kanter" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "Välj 2 till 9 filer" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Alla bilder har ej samma storlek" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "Justera bildbidrag" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "mörka pixlar" #: f.comp.cc:2326 msgid "light pixels" msgstr "ljusa pixlar" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "fil:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "MÃ¥la och vik ihop bild" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "bild" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "mÃ¥la" #: f.comp.cc:2851 msgid "warp" msgstr "vik ihop" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "Välj och färglägg bild" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "Justera pixelsammansättning" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "Välj 2 till 4 filer" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" "Drag bilder till grov passning\n" "Drag i underkant för rotera." #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "Sök efter lins och kräkning" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Rad upp bilder preliminärt" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "lins mm" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "linskurva" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "Ändra storlek" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "ändra fänsterstorlek" #: f.comp.cc:4457 msgid "use two images only" msgstr "använd bara tvÃ¥ bilder" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "För lite överlappning, kan ej rada upp" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "Matcha ljushet och färg" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "automatisk färg" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "filfärg" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" "Drag bilder till grov passninf.\n" "Rotera genom att dra frÃ¥n höger kant." #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.1.cc:188 fotoxx-12.01.1.cc:324 msgid "Open Image File" msgstr "Öppna bildfil" #: f.file.cc:321 fotoxx-12.01.1.cc:2861 msgid "prior function still active" msgstr "föregÃ¥ende funktion fortfarande aktiv" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "Skriva över originalfilen?" #: f.file.cc:504 msgid "Do not warn again" msgstr "Varna inte igen" #: f.file.cc:520 msgid "Warning" msgstr "Varning" #: f.file.cc:643 msgid "Save File" msgstr "Spara fil" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "kvalitet" #: f.file.cc:668 msgid "make current" msgstr "sätt aktuell" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "jpegkvalitete mÃ¥ste vara 1-100" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Skriva över fil? \n" " %s" #: f.file.cc:905 fotoxx-12.01.1.cc:195 msgid "Create Blank Image" msgstr "Skapa tom bild" #: f.file.cc:907 msgid "file name" msgstr "filnamn" #: f.file.cc:912 f.transform.cc:353 msgid "width" msgstr "bredd" #: f.file.cc:915 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "höjd" #: f.file.cc:1035 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "Linux standarpapperskorg stöds ej. \n" "En skrivbordspapperskorg kommer att skapas." #: f.file.cc:1053 msgid "Move read-only file to trash?" msgstr "Flytta skrivskyddd fil till Skräp?" #: f.file.cc:1079 #, c-format msgid "Cannot create trash folder: %s" msgstr "Kan ej skapa skräpmapp: %s" #: f.file.cc:1087 f.file.cc:1093 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "fel: %s" #: f.file.cc:1138 fotoxx-12.01.1.cc:197 msgid "Rename Image File" msgstr "Döp om bildfil" #: f.file.cc:1143 msgid "old name" msgstr "gammalt namn" #: f.file.cc:1144 msgid "rename to" msgstr "döp om till" #: f.file.cc:1145 msgid "previous" msgstr "föregÃ¥ende" #: f.file.cc:1231 msgid "The target file already exists" msgstr "MÃ¥lfilen finns redan" #: f.file.cc:1239 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" "Omdöpning misslyckades: \n" " %s" #: f.file.cc:1287 msgid "Batch Rename" msgstr "Massomdöpning" #: f.file.cc:1290 f.file.cc:1342 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "%d filer valda" #: f.file.cc:1292 msgid "new base name" msgstr "nytt basnamn" #: f.file.cc:1295 msgid "starting sequence" msgstr "begynnelsesekvens" #: f.file.cc:1297 msgid "increment" msgstr "steg" #: f.file.cc:1318 msgid "select files to rename" msgstr "välj filer för omdöpning" #: f.file.cc:1323 msgid "base name / sequence / increment not reasonable" msgstr "basnamn / sekvens / steg ej lämpliga" #: f.file.cc:1382 msgid "new file already exists:" msgstr "ny fil finns redan:" #: f.file.cc:1390 msgid "filespec too long:" msgstr "filspec för lÃ¥ng" #: f.file.cc:1401 msgid "Rename failed:" msgstr "Namnändring misslyckades:" #: f.file.cc:1662 fotoxx.h:729 msgid "Add" msgstr "Lägg till" #: f.file.cc:1662 fotoxx.h:781 msgid "Remove" msgstr "Tag bort" #: f.file.cc:1664 msgid "menu name" msgstr "menynamn" #: f.file.cc:1735 f.file.cc:1756 msgid "Restart Fotoxx to update plugin menu" msgstr "Starta om Fotoxx för att uppdatera insticksmenyn" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "Redigera beskrivning och kommentar" #: f.info.cc:156 fotoxx-12.01.1.cc:224 msgid "Edit Tags" msgstr "Redigera taggar" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "bilddatum (ååååmmdd)" #: f.info.cc:165 msgid "use last" msgstr "använd senaste" #: f.info.cc:168 msgid "image stars" msgstr "bildstjärnor" #: f.info.cc:186 msgid "current tags" msgstr "aktuella taggar" #: f.info.cc:191 msgid "recent tags" msgstr "gamla märken" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "definierade märken" #: f.info.cc:345 fotoxx-12.01.1.cc:225 msgid "Manage Tags" msgstr "Hantera flikar" #: f.info.cc:348 msgid "category" msgstr "kategori" #: f.info.cc:351 msgid "tag" msgstr "märke" #: f.info.cc:354 msgid "create" msgstr "skapa" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "tag bort" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "sökfilsindexfel: %s" #: f.info.cc:1351 fotoxx-12.01.1.cc:226 msgid "Batch Add Tags" msgstr "Masstillägg av taggar" #: f.info.cc:1354 msgid "tags to add" msgstr "taggar att lägga till" #: f.info.cc:1359 msgid "create tag" msgstr "skapa tagg" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " för mÃ¥nga märken" #: f.info.cc:1553 fotoxx-12.01.1.cc:227 msgid "Batch Delete Tag" msgstr "Borttagning av flagga satsvis" #: f.info.cc:1556 msgid "tag to remove" msgstr "flagga för borttagning" #: f.info.cc:1560 msgid "optional replacement" msgstr "valbar ersättning" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "Ingen fil vald" #: f.info.cc:1568 msgid "search all files" msgstr "leta i alla filer" #: f.info.cc:1653 msgid "no files selected" msgstr "inga filer valda" #: f.info.cc:1659 msgid "no tag specified" msgstr "inga flaggor beskrivna" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "beskriv flagga" #: f.info.cc:1821 msgid "View Info" msgstr "Visa information" #: f.info.cc:1889 fotoxx-12.01.1.cc:230 msgid "Edit Info" msgstr "Redigera info" #: f.info.cc:1987 fotoxx-12.01.1.cc:231 msgid "Delete Info" msgstr "Borttagningsinfo" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "Allt" #: f.info.cc:1990 msgid "One Key:" msgstr "One Key:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "Sök flaggor, kommentarer, filnamn" #: f.info.cc:2350 msgid "date range" msgstr "datumintervall" #: f.info.cc:2351 msgid "stars range" msgstr "stjärnomrÃ¥de" #: f.info.cc:2352 msgid "search tags" msgstr "sök taggar" #: f.info.cc:2353 msgid "search text" msgstr "sök text" #: f.info.cc:2354 msgid "file names" msgstr "filnamn" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "(yyyymmdd)" #: f.info.cc:2365 msgid "all/any" msgstr "alla/nÃ¥gon" #: f.info.cc:2702 msgid "No matching images found" msgstr "Inga matchande bilder hittade" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "Ingen indexsökfil rfinns" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "Ytterligare delar till rapport" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "större" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "öka miniatyrbildstorlek" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "minska miniatyrbildstorlek" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "mindre" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "förälder" #: f.navi.cc:190 msgid "parent directory" msgstr "föräldramapp" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "första sida" #: f.navi.cc:191 msgid "jump to first file" msgstr "hoppa till första fil" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "föregÃ¥ende sida" #: f.navi.cc:192 msgid "previous page" msgstr "föregÃ¥ende sida" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "föregÃ¥ende rad" #: f.navi.cc:193 msgid "previous row" msgstr "föregÃ¥ende rad" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "nästa rad" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "nästa sida" #: f.navi.cc:195 msgid "ttip::next page" msgstr "ttip::nästa sida" #: f.navi.cc:196 msgid "jump to last file" msgstr "hoppa till sista fil" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "sista sida" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "stäng" #: f.navi.cc:197 msgid "close image gallery" msgstr "stäng bildgalleri" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "Välj filer" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "avbryt" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "klart" #: f.navi.cc:1422 msgid "insert" msgstr "sätt in" #: f.navi.cc:1423 msgid "add all" msgstr "lägg till allt" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Justera ljus och färg" #: f.retouch.cc:110 msgid "small-steps" msgstr "smÃ¥steg" #: f.retouch.cc:119 msgid "color saturation" msgstr "färgmättnad" #: f.retouch.cc:126 msgid " reset 1 " msgstr " reset 1 " #: f.retouch.cc:127 msgid "reset all" msgstr "Ã¥terställ allt" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "justera bildens gamma" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "Expandera ljushetsomrÃ¥de" #: f.retouch.cc:887 msgid "bright pixels" msgstr "ljusa pixlar" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Platta till ljushetsfördelning" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Platta till" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "Rampa ljushet över bild" #: f.retouch.cc:1730 fotoxx-12.01.1.cc:271 msgid "Tone Mapping" msgstr "Tonavbildning" #: f.retouch.cc:1758 msgid "low" msgstr "lÃ¥g" #: f.retouch.cc:1760 msgid "high" msgstr "hög" #: f.retouch.cc:1763 msgid "Amplify" msgstr "Förstärk" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Justera vitbalans" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Klicka pÃ¥ vit- eller grÃ¥bildsplats" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "musradie för färgprov" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.1.cc:245 #: fotoxx-12.01.1.cc:324 fotoxx.h:769 msgid "Open" msgstr "Öppna" #: f.retouch.cc:2310 msgid "image for source color" msgstr "bild för källfärg" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "klicka pÃ¥ bilden för att fÃ¥ en källfärg" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "välj källbildsfärg först" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "Lägg till standardförskjutning" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "+Ljusstyrka -Täthet" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "+Röd -Cyan" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "+Grön -Magenta" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "+BlÃ¥ -Gul" #: f.retouch.cc:2599 msgid "Contrast" msgstr "Kontrast" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Röd" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Grön" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "BlÃ¥" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "Ladda DRGB-parametrrar" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "Fil:" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "DRGB-parameterfil" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "fil ej funnen" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "Spara DRGB-parameterar" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "Klicka pÃ¥ bild för att välja pixlar" #: f.retouch.cc:3072 fotoxx-12.01.1.cc:275 msgid "Revise RGB" msgstr "Revidera RGB" #: f.retouch.cc:3084 msgid "Metric:" msgstr "Metrisk:" #: f.retouch.cc:3139 msgid "Blend" msgstr "Ton" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Metod 1:\n" " Vänsterklicka pÃ¥ röd-öga för att göra mörkare.\n" "Metod 2:\n" " Drag ner och höger till att innesluta röd-öga.\n" " Vänsterklicka pÃ¥ röd-öga för att göra mörkare.\n" "Ã…ngra röd-öga:\n" " Högerklicka pÃ¥ röd-öga." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Rödögonminskning" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Välj suddradie" #: f.retouch.cc:4195 fotoxx-12.01.1.cc:278 msgid "Sharpen Image" msgstr "Gör bild skarpare" #: f.retouch.cc:4202 msgid "edge detection" msgstr "kantdetektion" #: f.retouch.cc:4203 msgid "cycles" msgstr "perioder" #: f.retouch.cc:4204 msgid "reduce" msgstr "minska" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "oskarp mask" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "ljushetsgradient" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Tryck minska-knappen för att\n" " minska brus i smÃ¥ steg.\n" " Använd Ã¥ngar för att börja om." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Brusminskning" #: f.retouch.cc:4650 msgid "algorithm" msgstr "algoritm" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "platta till \"uteliggare\" med färg (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "platta till \"uteliggare\" med färg (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "sätt medialjushet genom färg" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "top hat-filter med färg" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" "1. Drag mus för val. \n" "2. Radera. 3. Repetera. " #: f.retouch.cc:4998 fotoxx-12.01.1.cc:280 msgid "Smart Erase" msgstr "Fiffig radering" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Radie" #: f.retouch.cc:5005 msgid "Blur" msgstr "Göra suddigt" #: f.retouch.cc:5008 msgid "New Area" msgstr "Ny yta" #: f.retouch.cc:5379 fotoxx-12.01.1.cc:281 msgid "Remove Dust" msgstr "Tag bort damm" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "max. ljusstyrka" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "min. kontrast" #: f.retouch.cc:5983 fotoxx-12.01.1.cc:282 msgid "Fix Stuck Pixels" msgstr "Ordna fastnade pixlar" #: f.retouch.cc:5989 msgid "pixel group" msgstr "pixelgrupp" #: f.retouch.cc:5990 msgid "circle color" msgstr "cirkelfärg" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "Ladda fastnade pixlar" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "Fil med fastnade pixlar" #: f.retouch.cc:6164 msgid "file format error" msgstr "filformatfel" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "det finns inga fastnade pixlar" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "Spara fastnade pixlar" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Ã…ngra minne %d%c" #: f.retouch.cc:6688 fotoxx-12.01.1.cc:283 msgid "Edit Pixels" msgstr "Redigera pixlar" #: f.retouch.cc:6695 msgid "pick" msgstr "plocka" #: f.retouch.cc:6697 msgid "erase" msgstr "radera" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "mÃ¥larpenselradie" #: f.retouch.cc:6706 msgid "transparency center" msgstr "genomskinlighetscenter" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "genomskinlighetskant" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Ã…ngra minnesgräns har nÃ¥tts.\n" "Spara arbete med [gjort], fortsätt sedan redigering." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Välj omrÃ¥de till redigering" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "Tryck F1 efter hjälp" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" "Val av yta stöds ej\n" "av denna redigeringsfunktion" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "rektangel" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "ellips" #: f.select.cc:110 msgid "draw: freehand" msgstr "drag: frihand" #: f.select.cc:111 msgid "draw: follow edge" msgstr "drag: följ kant" #: f.select.cc:114 msgid "select by mouse" msgstr "välj med mus" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "musradie" #: f.select.cc:120 msgid "match mouse color" msgstr "matcha musfärg" #: f.select.cc:124 msgid "search range" msgstr "sökomrÃ¥de" #: f.select.cc:126 msgid "firewall" msgstr "brandvägg" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "överskrid %d redigeringar" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" "Klicka en gÃ¥ng innanför varje slutet omrÃ¥de\n" "(möjliga gap i kommer att hittas). \n" "Tryck F1 för hjälp." #: f.select.cc:1078 msgid "finish area" msgstr "avslutande omrÃ¥de" #: f.select.cc:1113 msgid "searching" msgstr "sökning" #: f.select.cc:1185 msgid "outline has a gap" msgstr "skissen har ett gap" #: f.select.cc:1189 msgid "success" msgstr "lyckades" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "omrÃ¥det är ej avslutat" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Kantberäkning pÃ¥gÃ¥r" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Ytkantsberäkning" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "positionera med musklick/drag" #: f.select.cc:1887 msgid "Paste Image" msgstr "Klistra in bild" #: f.select.cc:1901 msgid "angle" msgstr "vinkel" #: f.select.cc:2160 msgid "load select area from a file" msgstr "ladda valt omrÃ¥de frÃ¥n en fil" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "kan ej öppna .tiff- och .info-filer" #: f.select.cc:2213 msgid "save select area to a file" msgstr "spara valt omrÃ¥de till en fil" #: f.select.cc:2248 fotoxx-12.01.1.cc:247 msgid "Select Whole Image" msgstr "Välj hel bild" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "Redigera funktionsförstärkare" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "Redigeringsfunktionen mÃ¥ste vara aktiv§" #: f.select.cc:2499 msgid "power: center" msgstr "kraft: centrum" #: f.select.cc:2501 msgid "edge" msgstr "kant" #: f.select.cc:2504 msgid "reset area" msgstr "Ã¥terställ omrÃ¥de§" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" "Vid redigering av en samling, högerklicka \n" "pÃ¥ en bild eller miniatyr för att lägga till eller ta bort" #: f.tools.cc:70 fotoxx-12.01.1.cc:203 msgid "Manage Collections" msgstr "Hantera samlingar" #: f.tools.cc:85 msgid "Start new collection" msgstr "PÃ¥börja en ny samling" #: f.tools.cc:87 msgid "Edit a collection" msgstr "Redigera en samling" #: f.tools.cc:89 msgid "View a collection" msgstr "Visa en samling" #: f.tools.cc:91 msgid "Delete a collection" msgstr "Tag bort en samling" #: f.tools.cc:95 msgid "Editing:" msgstr "Redigering:" #: f.tools.cc:99 msgid "Action:" msgstr "Ã…tgärd:" #: f.tools.cc:133 msgid "New Collection" msgstr "Ny samling" #: f.tools.cc:156 msgid "Edit Collection" msgstr "Redigera samling" #: f.tools.cc:172 msgid "View Collection" msgstr "Visa samling" #: f.tools.cc:193 msgid "Delete Collection" msgstr "Tag bort samling" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "tag bort %s ?" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "lägg till bild till samlingen: %s" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "tag bort bild frÃ¥n samling" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "tag bort och spara bild" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "sätt in sparad bild här" #: f.tools.cc:256 msgid "add image to collection" msgstr "lägg till bild till samling" #: f.tools.cc:301 msgid "too many saved files" msgstr "för mÃ¥nga sparade filer" #: f.tools.cc:373 fotoxx-12.01.1.cc:204 msgid "Move Collections" msgstr "Flytta samling" #: f.tools.cc:375 msgid "old top directory" msgstr "gammal högsta mapp" #: f.tools.cc:378 msgid "new top directory" msgstr "ny högsta mapp" #: f.tools.cc:434 msgid "completed" msgstr "fullgjort" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "Satsvis konvertering/Storleksförändring/Export" #: f.tools.cc:474 msgid "new max. width" msgstr "ny max bredd" #: f.tools.cc:481 msgid "new file type" msgstr "ny filtyp" #: f.tools.cc:482 msgid "same" msgstr "samma" #: f.tools.cc:490 msgid "replace originals" msgstr "ersätta originalen" #: f.tools.cc:491 msgid "export to location" msgstr "exportera till plats" #: f.tools.cc:492 msgid "remove EXIF" msgstr "tag bort EXIF" #: f.tools.cc:549 msgid "Select directory" msgstr "Välj mapp" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "ersätta ursprungliga filer? max %d x %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "kopiera filer? (max %d x %d) \n" "till plats %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "platsen är inte en giltig mapp" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "max storlek %d x %d är inte förnuftig" #: f.tools.cc:654 msgid "*** file already exists" msgstr "*** filen finns redan" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "*** filtypen stöds ej" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "Programmet ufraw-batch krävs" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Öppna RAW-fil" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "Välj RAW-filer för omvandling" #: f.tools.cc:769 msgid "Choose file type" msgstr "Välj filtyp" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "Tryck ESC för att avsluta bildvisningen" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "visa bara senaste filversion" #: f.tools.cc:893 msgid "arrow keys" msgstr "pilknappar" #: f.tools.cc:894 msgid "instant" msgstr "direkt" #: f.tools.cc:895 msgid "fade-in" msgstr "intoning" #: f.tools.cc:896 msgid "roll-right" msgstr "högerrullning" #: f.tools.cc:897 msgid "roll-down" msgstr "nedrullning" #: f.tools.cc:898 msgid "shift-left" msgstr "shift-vänster§" #: f.tools.cc:899 msgid "venetian" msgstr "venetianskt" #: f.tools.cc:900 msgid "grate" msgstr "rutnät" #: f.tools.cc:903 msgid "radar" msgstr "radar" #: f.tools.cc:904 msgid "jaws" msgstr "" #: f.tools.cc:911 fotoxx-12.01.1.cc:207 msgid "Slide Show" msgstr "Bildvisning" #: f.tools.cc:915 msgid "seconds" msgstr "sekunder" #: f.tools.cc:919 msgid "music file" msgstr "musikfil" #: f.tools.cc:923 msgid "transitions" msgstr "övergÃ¥ngar" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "Välj musikfil eller spellista" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "Synkronisering av filer körs redan" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" "Kör Verktyg->Synkronisera filer sÃ¥ att gallerifönstren \n" "blir snabba och Sök Bilder kommer att fungera korrekt. Du kan se (ej " "redigera) bilder medan synkronisering körs." #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "ingen högsta bildmapp är definierad" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "högsta bildmapp är ogiltig" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "ingen indexsökfil finns" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "nya/ändrade filer finns" #: f.tools.cc:1844 msgid "no new files found" msgstr "inga nya filer hittade" #: f.tools.cc:1859 fotoxx-12.01.1.cc:208 msgid "Synchronize Files" msgstr "Synkronisera filer" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Översta bildmapp:" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" "filsynkronisering är nödvändigt.\n" "avbryta ändÃ¥?" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "högsta mapp är ogiltig" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Välj översta bildmapp" #: f.tools.cc:2429 fotoxx-12.01.1.cc:209 msgid "Show RGB" msgstr "Visa RGB" #: f.tools.cc:2719 fotoxx-12.01.1.cc:210 msgid "Grid Lines" msgstr "Rutnät" #: f.tools.cc:2728 msgid "x-spacing" msgstr "x-avstÃ¥nd" #: f.tools.cc:2729 msgid "x-count" msgstr "x-antal" #: f.tools.cc:2730 msgid "x-enable" msgstr "x-enable" #: f.tools.cc:2736 msgid "y-spacing" msgstr "y-avstÃ¥nd" #: f.tools.cc:2737 msgid "y-count" msgstr "y-antal" #: f.tools.cc:2738 msgid "y-enable" msgstr "y-enable" #: f.tools.cc:2745 msgid "x-offset" msgstr "x-förskjutning" #: f.tools.cc:2749 msgid "y-offset" msgstr "y-förskjutning" #: f.tools.cc:2940 fotoxx-12.01.1.cc:212 msgid "E-mail Images" msgstr "E-postbilder" #: f.tools.cc:2947 msgid "max. width" msgstr "max bredd" #: f.tools.cc:2948 msgid "max. height" msgstr "max höjd" #: f.tools.cc:3093 msgid "too many files" msgstr "för mÃ¥nga filer" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" "Ljusheten borde visa a gradvis ramp \n" "utvidgad hela vägen till kanterna." #: f.tools.cc:3174 msgid "Monitor Check" msgstr "Kontroll av bildskärm" #: f.tools.cc:3232 fotoxx-12.01.1.cc:214 msgid "Monitor Gamma" msgstr "Bildskärmsgamma" #: f.tools.cc:3294 fotoxx-12.01.1.cc:215 msgid "Brightness Distribution" msgstr "Ljushetsfördelning" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Tillgängliga översättningar" #: f.tools.cc:3436 msgid "Set Language" msgstr "Ställ in sprÃ¥k" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "" #: f.tools.cc:3540 msgid "Settings" msgstr "Inställningar" #: f.tools.cc:3545 msgid "Startup Display" msgstr "Uppstartskärm" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "Senaste filers galleri " #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "Senaste betraktade bild" #: f.tools.cc:3549 msgid "Blank Window" msgstr "Svart fönster" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "Mappgalleri" #: f.tools.cc:3556 msgid "Image File" msgstr "Bildfil" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "Stil pÃ¥ verktygsrad" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "Text" #: f.tools.cc:3564 msgid "Icons" msgstr "Ikoner" #: f.tools.cc:3565 msgid "Both" msgstr "Bägge" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "Varna vid överskrivning" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "uppstartmapp är ogiltig" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "uppstartfil är ogiltig" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "Välj uppstartmapp" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "Välj uppstartbildfil" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "Använd knappar eller dra höger kant med mus" #: f.transform.cc:60 fotoxx-12.01.1.cc:251 msgid "Rotate Image" msgstr "Rotera bild" #: f.transform.cc:64 msgid "degrees" msgstr "grader" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Trimma" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "Rutnät" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Ã…ngra trimning" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "grader: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "guld" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "Drag i mitten för att flytta, i hörnen för att ändra storlek." #: f.transform.cc:348 fotoxx-12.01.1.cc:252 msgid "Trim Image" msgstr "Trimma bild" #: f.transform.cc:348 msgid "customize" msgstr "anpassa" #: f.transform.cc:359 msgid "ratio" msgstr "förhÃ¥llande" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "LÃ¥s förhÃ¥llande" #: f.transform.cc:368 msgid "invert" msgstr "invertera" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "Trimningsknappar" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "LÃ¥s aspektförhÃ¥llande" #: f.transform.cc:1072 fotoxx-12.01.1.cc:254 msgid "Resize Image" msgstr "Ändra bildstorlek" #: f.transform.cc:1095 fotoxx-12.01.1.cc:325 msgid "Prev" msgstr "Föreg" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" "Skriv in text, klicka/drag i bild.\n" "Högerklicka för att ta bort." #: f.transform.cc:1294 fotoxx-12.01.1.cc:255 msgid "Annotate Image" msgstr "Kommentera bild" #: f.transform.cc:1307 msgid "Size" msgstr "Storlek" #: f.transform.cc:1310 msgid "Angle" msgstr "Vinkel" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Färg" #: f.transform.cc:1322 msgid "Transparency" msgstr "Transparans" #: f.transform.cc:1325 msgid "text" msgstr "text" #: f.transform.cc:1330 msgid "backing" msgstr "" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" "Kontur\n" " bredd" #: f.transform.cc:1335 msgid "outline" msgstr "skiss" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "Notisfil:" #: f.transform.cc:1416 msgid "select font" msgstr "välj typsnitt" #: f.transform.cc:2045 fotoxx-12.01.1.cc:256 msgid "Flip Image" msgstr "Vänd bild" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "horisontell" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "vertikal" #: f.transform.cc:2155 fotoxx-12.01.1.cc:257 msgid "Make Negative" msgstr "Gör negativ" #: f.transform.cc:2158 msgid "black/white positive" msgstr "svart-vit positiv" #: f.transform.cc:2159 msgid "black/white negative" msgstr "svart/vit negativ" #: f.transform.cc:2160 msgid "color positive" msgstr "färg positiv" #: f.transform.cc:2161 msgid "color negative" msgstr "färg negativ" #: f.transform.cc:2272 fotoxx-12.01.1.cc:258 msgid "Unbend Image" msgstr "Utsläta bild" #: f.transform.cc:2282 msgid "linear" msgstr "linjär" #: f.transform.cc:2285 msgid "curved" msgstr "böjd" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" "Klicka pÃ¥ de fyra hörnen i en tetragobyta. Tryck [tillämpa].\n" "Bilden kommer att förvrängas genom att göra tetragonen till en rektangel." #: f.transform.cc:2556 fotoxx-12.01.1.cc:259 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "mÃ¥ste ha fyra hörn" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" "Välj ett omrÃ¥de genom att välja en omrÃ¥desfunktion. \n" "Tryck [börja förvräng] och drag ytan med mus. \n" "Gör flera musdrag tills du när nöjd. \n" "När du är klar, välj ett annat omrÃ¥de eller tryck [klar]." #: f.transform.cc:2859 fotoxx-12.01.1.cc:260 msgid "Warp Image (area)" msgstr "Vik ihop bild (yta)" #: f.transform.cc:2864 msgid "start warp" msgstr "börja förvrängning" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "ingen aktiv utvald yta" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Drag i ett bildhörn med musen.\n" " Gör flera musdragningar tills du är nöjd.\n" " När du är klar, tryck [Avsluta]." #: f.transform.cc:3112 fotoxx-12.01.1.cc:261 msgid "Warp Image (curved)" msgstr "Vik ihop bild (kurva)" #: f.transform.cc:3375 fotoxx-12.01.1.cc:262 msgid "Warp Image (linear)" msgstr "Vik ihop bild (linjärt)" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Drag i ett bildhörn med musen.\n" " Gör flera musdragningar tills du är nöjd.\n" " När du är klar, tryck [Avsluta]." #: f.transform.cc:3639 fotoxx-12.01.1.cc:263 msgid "Warp Image (affine)" msgstr "Förvräng bild (affine)" #: fotoxx-12.01.1.cc:184 msgid "File" msgstr "Fil" #: fotoxx-12.01.1.cc:185 fotoxx-12.01.1.cc:323 msgid "Image Gallery" msgstr "Bildgalleri" #: fotoxx-12.01.1.cc:186 msgid "Clone 50/50" msgstr "Klona 50/50" #: fotoxx-12.01.1.cc:187 msgid "Clone Overlay" msgstr "Klona Overlay" #: fotoxx-12.01.1.cc:189 msgid "Open in New Window" msgstr "Öppna i nytt fönster" #: fotoxx-12.01.1.cc:190 fotoxx-12.01.1.cc:325 msgid "Open Previous File" msgstr "Öppna föregÃ¥ende fil" #: fotoxx-12.01.1.cc:191 msgid "Open Recent File" msgstr "Öppna senaste fil" #: fotoxx-12.01.1.cc:192 fotoxx-12.01.1.cc:333 msgid "Save to Same File" msgstr "Spara till samma fil" #: fotoxx-12.01.1.cc:193 fotoxx-12.01.1.cc:334 msgid "Save to New Version" msgstr "Spara till ny version" #: fotoxx-12.01.1.cc:194 fotoxx-12.01.1.cc:335 msgid "Save to New File" msgstr "Spara till ny fil" #: fotoxx-12.01.1.cc:196 msgid "Trash Image File" msgstr "Skräpbildfil" #: fotoxx-12.01.1.cc:198 msgid "Batch Rename Files" msgstr "Massomdöp filer" #: fotoxx-12.01.1.cc:199 msgid "Print Image File" msgstr "Skriv ut bildfil" #: fotoxx-12.01.1.cc:200 fotoxx-12.01.1.cc:339 msgid "Quit fotoxx" msgstr "Avsluta fotoxx" #: fotoxx-12.01.1.cc:202 msgid "Tools" msgstr "Verktyg" #: fotoxx-12.01.1.cc:205 msgid "Batch Convert" msgstr "Satsvis konvertering" #: fotoxx-12.01.1.cc:206 msgid "Convert RAW files" msgstr "Omvandla RAW-filer" #: fotoxx-12.01.1.cc:211 msgid "Burn Images to CD/DVD" msgstr "Bränn bilder till CD/DVD" #: fotoxx-12.01.1.cc:213 msgid "Check Monitor" msgstr "Kontrollera skärm" #: fotoxx-12.01.1.cc:216 msgid "Change Language" msgstr "Ändra sprÃ¥k" #: fotoxx-12.01.1.cc:218 msgid "Menu and Launcher" msgstr "Meny och startare" #: fotoxx-12.01.1.cc:219 msgid "User Settings" msgstr "Användarinställningar" #: fotoxx-12.01.1.cc:220 msgid "Memory Usage" msgstr "Minnesutnyttjande" #: fotoxx-12.01.1.cc:223 msgid "Edit Caption/Comments" msgstr "Redigera beskrivning/kommentarer" #: fotoxx-12.01.1.cc:228 msgid "View Info (short)" msgstr "Visa information (kort)" #: fotoxx-12.01.1.cc:229 msgid "View Info (long)" msgstr "Visa information (lÃ¥ngt)" #: fotoxx-12.01.1.cc:232 msgid "Search Images" msgstr "Bildsökning" #: fotoxx-12.01.1.cc:233 msgid "Search Metadata" msgstr "Sök metadata" #: fotoxx-12.01.1.cc:235 fotoxx-12.01.1.cc:236 fotoxx.h:786 msgid "Select" msgstr "Välj" #: fotoxx-12.01.1.cc:237 fotoxx.h:788 msgid "Show" msgstr "Visa" #: fotoxx-12.01.1.cc:238 fotoxx.h:761 msgid "Hide" msgstr "Göm" #: fotoxx-12.01.1.cc:239 fotoxx.h:752 msgid "Enable" msgstr "Koppla in" #: fotoxx-12.01.1.cc:240 fotoxx.h:748 msgid "Disable" msgstr "Koppla bort" #: fotoxx-12.01.1.cc:241 fotoxx.h:763 msgid "Invert" msgstr "Invertera" #: fotoxx-12.01.1.cc:242 fotoxx.h:796 msgid "Unselect" msgstr "Välj bort" #: fotoxx-12.01.1.cc:243 fotoxx.h:743 msgid "Copy" msgstr "Kopiera" #: fotoxx-12.01.1.cc:244 fotoxx.h:771 msgid "Paste" msgstr "Klistra in" #: fotoxx-12.01.1.cc:246 fotoxx-12.01.1.cc:333 fotoxx.h:783 msgid "Save" msgstr "Spara" #: fotoxx-12.01.1.cc:248 msgid "Select and Edit" msgstr "Välj och redigera" #: fotoxx-12.01.1.cc:250 msgid "Transform" msgstr "Omvandla" #: fotoxx-12.01.1.cc:253 msgid "Auto-Trim Image" msgstr "Trimma bild automatiskt" #: fotoxx-12.01.1.cc:265 msgid "Retouch" msgstr "Retuschera" #: fotoxx-12.01.1.cc:266 msgid "Brightness/Color" msgstr "Ljushet/färg" #: fotoxx-12.01.1.cc:267 msgid "Gamma Curves" msgstr "Gammakurvor" #: fotoxx-12.01.1.cc:268 msgid "Expand Brightness" msgstr "Expandera ljushet" #: fotoxx-12.01.1.cc:269 msgid "Flatten Brightness" msgstr "Platta till ljushet" #: fotoxx-12.01.1.cc:270 msgid "Brightness Ramp" msgstr "Ljushetsramp" #: fotoxx-12.01.1.cc:272 msgid "White Balance" msgstr "Vitbalans" #: fotoxx-12.01.1.cc:273 msgid "Match Colors" msgstr "Matchande färger" #: fotoxx-12.01.1.cc:276 msgid "Red Eyes" msgstr "Röda ögon" #: fotoxx-12.01.1.cc:277 msgid "Blur Image" msgstr "Gör bilden suddig" #: fotoxx-12.01.1.cc:279 msgid "Reduce Noise" msgstr "Minska brus" #: fotoxx-12.01.1.cc:285 msgid "Art" msgstr "Sort" #: fotoxx-12.01.1.cc:286 msgid "Color Depth" msgstr "Färgdjup" #: fotoxx-12.01.1.cc:287 msgid "Drawing" msgstr "Ritning" #: fotoxx-12.01.1.cc:288 msgid "Outlines" msgstr "Konturer" #: fotoxx-12.01.1.cc:289 msgid "Embossing" msgstr "Bosselera" #: fotoxx-12.01.1.cc:290 msgid "Tiles" msgstr "Plattor" #: fotoxx-12.01.1.cc:291 msgid "Dots" msgstr "Punkter" #: fotoxx-12.01.1.cc:292 msgid "Painting" msgstr "Färgläggning" #: fotoxx-12.01.1.cc:294 msgid "Combine" msgstr "Kombinera" #: fotoxx-12.01.1.cc:295 msgid "High Dynamic Range" msgstr "Stort dynamiskt omrÃ¥de" #: fotoxx-12.01.1.cc:296 msgid "High Depth of Field" msgstr "" #: fotoxx-12.01.1.cc:297 msgid "Stack / Paint" msgstr "Stack / färg" #: fotoxx-12.01.1.cc:298 msgid "Stack / Noise" msgstr "Stack / brus" #: fotoxx-12.01.1.cc:299 msgid "Panorama" msgstr "Panorama" #: fotoxx-12.01.1.cc:300 msgid "Vertical Panorama" msgstr "Vertikalt panorama" #: fotoxx-12.01.1.cc:303 msgid "Edit Plugins" msgstr "Redigera insticksprogram" #: fotoxx-12.01.1.cc:312 fotoxx-12.01.1.cc:340 fotoxx-12.01.1.cc:3025 msgid "Help" msgstr "Hjälp" #: fotoxx-12.01.1.cc:313 fotoxx-12.01.1.cc:3015 msgid "About" msgstr "Om" #: fotoxx-12.01.1.cc:314 fotoxx-12.01.1.cc:3019 msgid "User Guide" msgstr "Användarguide" #: fotoxx-12.01.1.cc:315 fotoxx-12.01.1.cc:3022 msgid "User Guide Changes" msgstr "Ändringar i användarhandbok" #: fotoxx-12.01.1.cc:316 fotoxx-12.01.1.cc:3031 msgid "Edit Functions Summary" msgstr "Sammanfattning av redigeringsfunktioner" #: fotoxx-12.01.1.cc:317 fotoxx-12.01.1.cc:3034 msgid "Change Log" msgstr "Ändringslogg" #: fotoxx-12.01.1.cc:318 fotoxx-12.01.1.cc:3037 msgid "Translations" msgstr "Översättningar" #: fotoxx-12.01.1.cc:319 fotoxx-12.01.1.cc:3040 msgid "Home Page" msgstr "Hemsida" #: fotoxx-12.01.1.cc:323 msgid "Gallery" msgstr "Galleri" #: fotoxx-12.01.1.cc:326 fotoxx.h:767 msgid "Next" msgstr "Nästa" #: fotoxx-12.01.1.cc:326 msgid "Open Next File" msgstr "Öppna nästa fil" #: fotoxx-12.01.1.cc:327 msgid "Zoom-in (bigger)" msgstr "Zooma in (större)" #: fotoxx-12.01.1.cc:328 msgid "Zoom-out (smaller)" msgstr "Zooma ut (mindre)" #: fotoxx-12.01.1.cc:329 fotoxx.h:794 msgid "Undo" msgstr "Ã…ngra" #: fotoxx-12.01.1.cc:329 msgid "Undo One Edit" msgstr "Ã…ngra en redigering" #: fotoxx-12.01.1.cc:330 fotoxx.h:779 msgid "Redo" msgstr "Gör om" #: fotoxx-12.01.1.cc:330 msgid "Redo One Edit" msgstr "Gör om en redigering" #: fotoxx-12.01.1.cc:334 msgid "Save+V" msgstr "Spara+V" #: fotoxx-12.01.1.cc:335 msgid "Save+F" msgstr "Spara+F" #: fotoxx-12.01.1.cc:336 msgid "Move Image to Trash" msgstr "Flytta bild till Skräp" #: fotoxx-12.01.1.cc:336 msgid "Trash" msgstr "Skräp" #: fotoxx-12.01.1.cc:339 msgid "Quit" msgstr "Avsluta" #: fotoxx-12.01.1.cc:340 msgid "Fotoxx Essentials" msgstr "Fotoxx Essentials" #: fotoxx-12.01.1.cc:447 msgid "first time startup" msgstr "första start" #: fotoxx-12.01.1.cc:1943 msgid "Exceed 50 anchor points" msgstr "Överskridit 50 ankarpunkter" #: fotoxx-12.01.1.cc:2128 msgid "load curve from a file" msgstr "ladda kurva frÃ¥n fil" #: fotoxx-12.01.1.cc:2181 msgid "curve file is invalid" msgstr "kurvfil är ogiltig" #: fotoxx-12.01.1.cc:2186 msgid "curve file has different no. of curves" msgstr "kurvfil har annorlunda antal kurvor" #: fotoxx-12.01.1.cc:2201 msgid "save curve to a file" msgstr "spara kurva till en fil" #: fotoxx-12.01.1.cc:2336 msgid "cannot parallel edit" msgstr "kan ej redigera i parallell" #: fotoxx-12.01.1.cc:2346 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "exif-verktyg är ej installerat\n" "redigerade bilder kommer att tappa EXIF-data" #: fotoxx-12.01.1.cc:2352 msgid "Too many edits, please save image" msgstr "För mÃ¥nga redigeringar, spara bilden" #: fotoxx-12.01.1.cc:2357 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Valt omrÃ¥de behÃ¥llas.\n" "Fortsätta?" #: fotoxx-12.01.1.cc:2365 msgid "" "Select area not active.\n" "Continue?" msgstr "" "Valt omrÃ¥de ej aktivt.\n" "Fortsätta?" #: fotoxx-12.01.1.cc:2836 msgid "Discard edits?" msgstr "Strunta i redigeringar?" #: fotoxx-12.01.1.cc:2837 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" "Denna Ã¥tgärd kommer att förkasta aktuella redigeringar.\n" "Fortsätt att förkasta redigeringar.\n" "GÃ¥ tillbaka för att behÃ¥lla redigeringar." #: fotoxx-12.01.1.cc:2840 msgid "Continue" msgstr "Fortsätt" #: fotoxx-12.01.1.cc:2841 msgid "Go Back" msgstr "GÃ¥ tillbaka" #: fotoxx-12.01.1.cc:3658 msgid "cannot open thumbnail file" msgstr "kan ej öppna miniatyrbildsfil" #: fotoxx-12.01.1.cc:3869 fotoxx-12.01.1.cc:3991 msgid "TIFF open failure" msgstr "Fel vid öppnande av TIFF" #: fotoxx-12.01.1.cc:3885 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF bits/color=%d stöds ej" #: fotoxx-12.01.1.cc:3900 fotoxx-12.01.1.cc:3938 msgid "TIFF read failure" msgstr "Fel vid läsning av TIFF" #: fotoxx-12.01.1.cc:4050 msgid "TIFF write failure" msgstr "Fel vid skrivning av TIFF" #: fotoxx-12.01.1.cc:4070 msgid "file type not supported" msgstr "filtyp stöds ej" #: fotoxx-12.01.1.cc:4177 msgid "pixbuf write failure" msgstr "pixbuf-skrivfel" #: fotoxx.h:728 msgid "absolute" msgstr "absolut" #: fotoxx.h:730 msgid "Add All" msgstr "Lägg till allt" #: fotoxx.h:732 msgid "Amount" msgstr "Mängd" #: fotoxx.h:733 msgid "Apply" msgstr "Tillämpa" #: fotoxx.h:734 msgid "Black" msgstr "Svart" #: fotoxx.h:735 msgid "Blend Width" msgstr "Bländaröppning" #: fotoxx.h:737 msgid "Brightness" msgstr "Ljushet" #: fotoxx.h:738 msgid "Browse" msgstr "Bläddra" #: fotoxx.h:739 msgid "Cancel" msgstr "Avbryt" #: fotoxx.h:740 msgid "Clear" msgstr "Rensa" #: fotoxx.h:742 msgid "Commit" msgstr "Delge" #: fotoxx.h:744 msgid "Curve File:" msgstr "Kurvfil:" #: fotoxx.h:745 msgid "Cut" msgstr "Beskär" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Mörkare omrÃ¥den" #: fotoxx.h:747 msgid "Delete" msgstr "Tag bort" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" "Förkasta särskild gallerilista?\n" " %s" #: fotoxx.h:750 msgid "Done" msgstr "Gjort" #: fotoxx.h:751 msgid "Edit" msgstr "Redigera" #: fotoxx.h:753 msgid "Erase" msgstr "Radera" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "paketet libimage-exiftool-perl krävs" #: fotoxx.h:755 msgid "Fetch" msgstr "Hämta" #: fotoxx.h:756 msgid "Finish" msgstr "Avsluta" #: fotoxx.h:757 msgid "Font" msgstr "Typsnitt" #: fotoxx.h:759 msgid "Height" msgstr "Höjd" #: fotoxx.h:760 msgid "histogram" msgstr "histogram" #: fotoxx.h:762 msgid "Insert" msgstr "Infoga" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Ljusare omrÃ¥den" #: fotoxx.h:765 msgid "limit" msgstr "gräns" #: fotoxx.h:766 msgid "New" msgstr "Ny" #: fotoxx.h:768 msgid "OK" msgstr "OK" #: fotoxx.h:772 msgid "Pause" msgstr "Paus" #: fotoxx.h:773 msgid "Percent" msgstr "Procent" #: fotoxx.h:774 msgid "Presets" msgstr "Förinställningar" #: fotoxx.h:775 msgid "Proceed" msgstr "Fortsätt" #: fotoxx.h:777 msgid "range" msgstr "omrÃ¥de" #: fotoxx.h:780 msgid "Reduce" msgstr "Minska" #: fotoxx.h:782 msgid "Reset" msgstr "Ã…terställ" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Okänd filtyp, spara som tiff/jpeg/png för att redigera" #: fotoxx.h:785 msgid "Search" msgstr "Sök" #: fotoxx.h:789 msgid "Start" msgstr "Start" #: fotoxx.h:790 msgid "Threshold" msgstr "Tröskel" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "överskred %d filer" #: fotoxx.h:792 msgid "Undo All" msgstr "Ã…ngra allt" #: fotoxx.h:793 msgid "Undo Last" msgstr "Ã…ngra sista" #: fotoxx.h:795 msgid "Unfinish" msgstr "Oavslutad" #: fotoxx.h:797 msgid "View" msgstr "Vy" #: fotoxx.h:798 msgid "White" msgstr "Vit" #: fotoxx.h:799 msgid "Width" msgstr "Bredd" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "hjälpfil ej hittad: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "kan ej öppna fil %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "spara skärmbild i fil" #: zfuncs.cc:6222 msgid "No" msgstr "Nej" #: zfuncs.cc:6222 msgid "Yes" msgstr "Ja" #: zfuncs.cc:6447 msgid "open" msgstr "öppna" #: zfuncs.cc:6452 msgid "choose" msgstr "välj" #: zfuncs.cc:6457 msgid "save" msgstr "spara" #: zfuncs.cc:6463 msgid "open folder" msgstr "öppna mapp" #: zfuncs.cc:6468 msgid "create folder" msgstr "skapa mapp" #: zfuncs.cc:6474 msgid "hidden" msgstr "gömd" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "JPG-kvalitet 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "marginaler" #: zfuncs.cc:6737 msgid "top" msgstr "topp" #: zfuncs.cc:6738 msgid "bottom" msgstr "botten" #: zfuncs.cc:6739 msgid "left" msgstr "vänster" #: zfuncs.cc:6740 msgid "right" msgstr "höger" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Startparameterfil skapad. \n" "Undersök och ändra vid behov." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "ladda parametrar frÃ¥n fil" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "spara parametrar i en fil" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "redigera parametrar" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "lista\n" "allt" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "ladda\n" "fil" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "spara\n" "fil" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "lägg till\n" "nytt" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "tillämpa" #: zfuncs.cc:7479 msgid "apply?" msgstr "tillämpa?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(nytt parameternamn)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "lägg till parameter" #~ msgid "Lens Parameters" #~ msgstr "Linsparametrar" #~ msgid "my mouse" #~ msgstr "min mus" #~ msgid "lens name" #~ msgstr "linsnamn" #~ msgid "select new file" #~ msgstr "välj ny fil" #~ msgid "Translate" #~ msgstr "Översätt" #~ msgid "" #~ "Run Tools > Synchronize Files so that gallery windows \n" #~ "will be fast and Search Images will work correctly." #~ msgstr "" #~ "Kör Verktyg->Synkronisera filer sÃ¥ att bildfönstren \n" #~ "blir snabba och bildsökning fungerar rätt." #~ msgid "full rebuild" #~ msgstr "total Ã¥terbildning" #~ msgid "incremental" #~ msgstr "stegvis" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "Omdöpning misslyckades \n" #~ " %s" #~ msgid "transition" #~ msgstr "övergÃ¥ng" #~ msgid "Discard modifications?" #~ msgstr "Kasta ändringar?" #~ msgid "Edit Comments" #~ msgstr "Redigera kommentarer" #~ msgid "Edit Caption" #~ msgstr "Redigera rubrik" #~ msgid "tags exceed %d characters" #~ msgstr "taggar överskrider %d tecken" #~ msgid "recently added" #~ msgstr "nyligen tillagd" #~ msgid "new file already exists: %s" #~ msgstr "ny fill finns redan: %s" #~ msgid "grid spacing" #~ msgstr "rutnätsavstÃ¥nd" #~ msgid "filespec too long: %s" #~ msgstr "filspecifikation för lÃ¥ng. %s" #~ msgid "assigned tags" #~ msgstr "tilldelade taggar" #~ msgid "Unable to save image: %s" #~ msgstr "Kan ej spara bild: %s" #~ msgid "Unable to copy EXIF data" #~ msgstr "Kan ej kopiera EXIT-data" #~ msgid "Total tags exceed %d characters" #~ msgstr "Total taggar överskreds med %d tecken" #~ msgid "Too many undo buffers, please save image" #~ msgstr "För mÃ¥nga Ã¥ngrabuffertar, spara bild" #~ msgid "Too many tags: %d" #~ msgstr "För mÃ¥nga taggar: %d" #~ msgid "Package exiftool is missing" #~ msgstr "Pakets exif-verktyg saknas" #~ msgid "Index Tags" #~ msgstr "Indextaggar" #~ msgid "" #~ "Drag middle to move \n" #~ "Drag corners to resize" #~ msgstr "" #~ "Drag i mitten för att flytta\n" #~ "Drag i hörn för att ändra storlek" #~ msgid "Convert Tags" #~ msgstr "Omvandla taggar" #~ msgid "Add or Remove Grid Lines" #~ msgstr "Lägg till eller ta bort rutnät" #~ msgid "" #~ "%s \n" #~ " tag limit exceeded" #~ msgstr "" #~ "%s \n" #~ " tag-gräns överskriden" #~ msgid "jpeg quality" #~ msgstr "jpegkvalitet" #~ msgid "Select between 2 and 10 files to combine" #~ msgstr "Välj mellan 2 och 10 filer att kombinera" #~ msgid "Current file must be included" #~ msgstr "Aktuell fil mÃ¥ste tas med" #~ msgid "Select image to combine" #~ msgstr "Välj bild att kombinera" #~ msgid "Select 2 to 10 files to combine" #~ msgstr "Välj2 till 20 filer att kombinera" #~ msgid "Retouch Image" #~ msgstr "Retuschera bild" #~ msgid "Package ufraw required for this function" #~ msgstr "Pakets ufraw behövs för denna funktion" #~ msgid "Merge the images together" #~ msgstr "SlÃ¥ samman bilder" #~ msgid "Match Images" #~ msgstr "Matcha bilder" #~ msgid "" #~ "Drag right image into rough alignment with left \n" #~ " to rotate, drag right edge up or down" #~ msgstr "" #~ "Drag högra bilden till grov inlinjering med vänstra\n" #~ " för att rotera, drag höger kant upp eller ner" #~ msgid "Auto-search lens mm and bow" #~ msgstr "Sök automatiskt lins mm och kurva" #~ msgid "Auto" #~ msgstr "Auto" #~ msgid "" #~ "\n" #~ " Match Brightness and Color" #~ msgstr "" #~ "\n" #~ " Matcha ljushet och färg" #~ msgid "select image files to add tags" #~ msgstr "välj bildfiler för tillägg av taggar" #~ msgid "select files" #~ msgstr "välj filer" #~ msgid "rename files" #~ msgstr "döp om fil" #~ msgid "freehand draw" #~ msgstr "frihandsritning" #~ msgid "follow edge" #~ msgstr "följ kant" #~ msgid "" #~ "exiftool missing, please install \n" #~ " package libimage-exiftool-perl" #~ msgstr "" #~ "exiftool saknas, installera \n" #~ " paketet libimage-exiftool-perl" #~ msgid "color range" #~ msgstr "färgomfÃ¥ng" #~ msgid "browse" #~ msgstr "bläddra" #~ msgid "add tags" #~ msgstr "lägg till taggar" #~ msgid "TIFF colors=%d depth=%d not supported" #~ msgstr "TIFF färger=%d djup=%d ej understött" #~ msgid "Fix Image Perspective" #~ msgstr "Ordna bildperspektiv" #~ msgid "" #~ "Convert tags to new standard now?\n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Omvandla taggar till ny standrad nu?\n" #~ "Är dina bildfiler säkerhetskopierade?" #~ msgid "Burn" #~ msgstr "Bränn" #~ msgid "color intensity" #~ msgstr "färgintensitet" #~ msgid "Read File" #~ msgstr "Läs fil" #~ msgid "" #~ "position image\n" #~ "with mouse drag" #~ msgstr "" #~ "placera bild\n" #~ "med musdragning" #~ msgid "Warp Image in Selected Area" #~ msgstr "Förvräng bild i valt omrÃ¥de" #~ msgid "Warp Image (curvy)" #~ msgstr "Förvräng bild (krokig)" #~ msgid "Warp Area" #~ msgstr "FörvrängningsomrÃ¥de" #~ msgid "" #~ " Pull on an image edge using the mouse. \n" #~ " Make multiple mouse pulls until satisfied. \n" #~ " When finished, press [done]." #~ msgstr "" #~ " Drag i en bildkant med musen.\n" #~ " Gör flera musdragningar till du är nöjd.\n" #~ " När du är klar tryck [Avsluta]." #~ msgid "comments" #~ msgstr "kommentarer" #~ msgid "Suspend" #~ msgstr "Avbryt" #~ msgid "Resume" #~ msgstr "Ã…teruppta" #~ msgid "/path*/file*" #~ msgstr "/sökväg*/fil*" #~ msgid "transparency" #~ msgstr "tramsparens" #~ msgid "match any tag" #~ msgstr "matcha nÃ¥gon tagg" #~ msgid "match all tags" #~ msgstr "matcha alla taggar" #~ msgid "foreground" #~ msgstr "förgrund" #~ msgid "background" #~ msgstr "bakgrund" #~ msgid "annotation file:" #~ msgstr "anteckningsfil:" #~ msgid "Tags" #~ msgstr "Taggar" #~ msgid "Set Tile and Gap Size" #~ msgstr "Välj storlek pÃ¥ ruta och mellanrum" #~ msgid "Search Tags" #~ msgstr "Sök taggar" #~ msgid "Edit User Comments" #~ msgstr "Redigera användarkommentarer" #~ msgid "Edit EXIF data" #~ msgstr "Redigera EXIF-data" #~ msgid "EXIF data" #~ msgstr "EXIF-data" #~ msgid "Delete EXIF data" #~ msgstr "Tag bort EXIF-data" #~ msgid "Basic EXIF data" #~ msgstr "Grundläggande EXIF-data" #~ msgid "All EXIF data" #~ msgstr "All EXIF-data" #~ msgid "tags index file error: %s" #~ msgstr "taggindexfilfel: %s" #~ msgid "save select area as a file" #~ msgstr "spara valt omrÃ¥de som en fil" #~ msgid "new tags index will now be created" #~ msgstr "nytt taggindex kommer nu att skapas" #~ msgid "manage tags" #~ msgstr "hantera märken" #~ msgid "color select firewall" #~ msgstr "färgvälj brandvägg" #~ msgid "cannot read .dist file" #~ msgstr "kan ej läsa .dist-fil" #~ msgid "brightness to clip (percent)" #~ msgstr "ljushet att klippa vid (procent)" #~ msgid "Use F1 for context help" #~ msgstr "Använd F1 för sammanhangshjälp" #~ msgid "Stack" #~ msgstr "Stack" #~ msgid "Rebuild Tags Index" #~ msgstr "Bygg om taggindex" #~ msgid "No tags index file" #~ msgstr "Ingen taggindexfil" #~ msgid "" #~ "New tags file already exists! \n" #~ "Proceed anyway?" #~ msgstr "" #~ "Ny flaggor finns redan!\n" #~ "Fortsätta ändÃ¥?" #~ msgid "HDR" #~ msgstr "HDR" #~ msgid "HDF" #~ msgstr "HDF" #~ msgid "" #~ "Convert tags to new standard now? \n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Omvandla flaggor till ny standard nu?\n" #~ "Är dina bildfiler säkerhetskopierade?" #~ msgid "Convert tags to new standard" #~ msgstr "Omvandla taggar till ny standard" #~ msgid "Convert Tags !!!" #~ msgstr "Omvandla taggar !!!" #~ msgid "Constrain" #~ msgstr "Begränsning" #~ msgid "Area" #~ msgstr "Yta" #~ msgid "target group area" #~ msgstr "mälgruppsomrÃ¥de" #~ msgid "vertical unbend" #~ msgstr "vertikal uträtning" #~ msgid "select by mouse:" #~ msgstr "välj med mus:" #~ msgid "select by color:" #~ msgstr "välj genom färg:" #~ msgid "press ESC to exit" #~ msgstr "tryck ESC för att avsluta" #~ msgid "horizontal unbend" #~ msgstr "horisontell utslätning" #~ msgid "Rebuild Thumbnails" #~ msgstr "Bygg om miniatyrbilder" #~ msgid "save collection" #~ msgstr "spara samling" #~ msgid "open collection" #~ msgstr "öppna samling" #~ msgid "area outline has a hole" #~ msgstr "omrÃ¥desbegränsning som ett hÃ¥l" #~ msgid "" #~ "Search all areas for edge and inside pixels. \n" #~ "Click inside each enclosed area in sequence." #~ msgstr "" #~ "Sök all ytor efter kant och insidespixlar.\n" #~ "Klicka pÃ¥ insida av varje inneslutet omrÃ¥de i följd." #~ msgid "Open Image Collection" #~ msgstr "Öppna bildsamling" #~ msgid "Make Image Collection" #~ msgstr "Skapa bildsamling" #~ msgid "Create Launcher" #~ msgstr "Skapa en startare" #~ msgid "make new version" #~ msgstr "gör en ny version" #~ msgid "click on window to show RGB" #~ msgstr "klicka pÃ¥ fönster för att visa RGB" #~ msgid "Save As" #~ msgstr "Spara som" #~ msgid "Clone fotoxx" #~ msgstr "Klona fotoxx" #~ msgid "random" #~ msgstr "slumpvis" #~ msgid "Whole Image" #~ msgstr "Hel bild" #~ msgid "Time Interval" #~ msgstr "Tidsintervall" #~ msgid "print" #~ msgstr "skriv" #~ msgid "printer ID" #~ msgstr "skrivar-ID" #~ msgid "paper format" #~ msgstr "pappersformat" #~ msgid "portrait" #~ msgstr "stÃ¥ende" #~ msgid "landscape" #~ msgstr "liggande" #~ msgid "paper format is crazy" #~ msgstr "galet pappersformat" #~ msgid "open a file" #~ msgstr "öppna en fil" #~ msgid "Select area first" #~ msgstr "Välj omrÃ¥de först" #~ msgid "new file already exists" #~ msgstr "nya filen finns redan" #~ msgid "copy EXIF" #~ msgstr "kopiera EXIF" #~ msgid "new max. height" #~ msgstr "ny max höjd" #~ msgid "Batch Resize" #~ msgstr "Ändra storlek satsvis" #~ msgid "Search results file error %s" #~ msgstr "Sök fel i resultat fil: %s" #~ msgid "match" #~ msgstr "matcha" #~ msgid "radius" #~ msgstr "radie" #~ msgid "select by color" #~ msgstr "välj genom färg" #~ msgid "Brightness Graph" #~ msgstr "Ljushetsdiagram" fotoxx-12.01.2/locales/fotoxx-pt.po0000664000175000017500000016606611701011017015604 0ustar micomico# Portuguese translations for home package. # Copyright (C) 2010 THE home'S COPYRIGHT HOLDER # This file is distributed under the same license as the home package. # mico , 2010. # msgid "" msgstr "" "Project-Id-Version: fotoxx-10.8\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:05+0100\n" "PO-Revision-Date: 2010-07-01 22:55+0200\n" "Last-Translator: André Campos Rodovalho \n" "Language-Team: Portuguese\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Portuguese\n" "X-Poedit-Country: Brazil\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "Configurar resolução de cor para 1-16 bits" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Configurar resolução de cor" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Simular Desenho" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "contraste" #: f.art.cc:215 msgid "outlines" msgstr "dispersão" #: f.art.cc:220 msgid "pencil" msgstr "caneta" #: f.art.cc:221 msgid "chalk" msgstr "giz" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "Adicionar contornos de imagem" #: f.art.cc:394 msgid "outline threshold" msgstr "limite de contorno" #: f.art.cc:397 msgid "outline width" msgstr "largura de contorno" #: f.art.cc:400 msgid "image brightness" msgstr "brilho de imagem" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Simular Gravação em relevo" #: f.art.cc:626 msgid "depth" msgstr "profundidade" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "cor" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Simular Ladrilho" #: f.art.cc:825 msgid "tile size" msgstr "tamanho do ladrilho" #: f.art.cc:829 msgid "tile gap" msgstr "espaçamento dos ladrilhos" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "Converter imagem para pontos" #: f.art.cc:1007 msgid "dot size" msgstr "tamanho do ponto" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Simular Pintura" #: f.art.cc:1226 msgid "color depth" msgstr "resolução de cor" #: f.art.cc:1230 msgid "patch area goal" msgstr "remendar área objetivo" #: f.art.cc:1234 msgid "req. color match" msgstr "correspondência de cores requeridas" #: f.art.cc:1238 msgid "borders" msgstr "bordas" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "Selecionar 2 a 9 arquivos" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Imagens não são todas do mesmo tamanho" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "Ajustar contribuição de imagem" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "pixels escuros" #: f.comp.cc:2326 msgid "light pixels" msgstr "pixels claros" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "arquivo:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "Pintar e distorcer imagem" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "imagem" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "pintar" #: f.comp.cc:2851 msgid "warp" msgstr "distorção" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "Selecionar e pintar imagem" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "Ajustar Composição do Pixel" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "Selecionar 2 a 4 arquivos" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" "Arraste as imagens para o alinhamento grosseiro.\n" "Para rotacionar, arraste da borda mais abaixo." #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "Procurar por mm e curvatura de lente" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Pré-alinhamento de imagens" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "mm de lente" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "curvatura de lente" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "Redimensionar" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "redimensionar janela" #: f.comp.cc:4457 msgid "use two images only" msgstr "use duas imagens apenas" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Baixa sobreposição, não é possível alinhar" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "Parear Brilho e Cor" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "cor automática" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "arquivo de cor" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" "Arraste as imagens para o alinhamento grosseiro.\n" "Para rotacionar, arraste pela borda a direita." #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Abrir arquivo" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "função prévia ainda ativada" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "" #: f.file.cc:504 msgid "Do not warn again" msgstr "" #: f.file.cc:520 msgid "Warning" msgstr "" #: f.file.cc:643 msgid "Save File" msgstr "Salvar arquivo" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "qualidade" #: f.file.cc:668 msgid "make current" msgstr "tornar atual" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "qualidade de jpeg deve estar entre 1-100" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Sobrescrever arquivo? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "Criar imagem em branco" #: f.file.cc:905 msgid "file name" msgstr "nome do arquvo" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "largura" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "altura" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "Lixeira padrão Linux não suportada. \n" "Uma pasta com lixeira será criada na Ãrea de Trabalho." #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "Mover arquivo de apenas leitura para lixeira?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "Não foi possível criar pasta lixeira: %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "erro: %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Renomear arquivo" #: f.file.cc:1141 msgid "old name" msgstr "nome antigo" #: f.file.cc:1142 msgid "rename to" msgstr "renomear para" #: f.file.cc:1143 msgid "previous" msgstr "anterior" #: f.file.cc:1229 msgid "The target file already exists" msgstr "Arquivo alvo já existente" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" #: f.file.cc:1285 msgid "Batch Rename" msgstr "Renomear vários" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "%d arquivos selecionados" #: f.file.cc:1290 msgid "new base name" msgstr "novo nome de base" #: f.file.cc:1293 msgid "starting sequence" msgstr "sequência inicial" #: f.file.cc:1295 msgid "increment" msgstr "incrementar" #: f.file.cc:1316 msgid "select files to rename" msgstr "selecionar arquivos para renomear" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "nome base / sequencia / incremento fixo" #: f.file.cc:1380 msgid "new file already exists:" msgstr "novo arquivo já existe:" #: f.file.cc:1388 msgid "filespec too long:" msgstr "caminho de arquivo muito longo:" #: f.file.cc:1399 msgid "Rename failed:" msgstr "Renomearação falhou:" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "Adicionar" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "Remover" #: f.file.cc:1662 msgid "menu name" msgstr "nome do menu" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "Reinicie o Fotoxx para atualizar o menu de plugin" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "Editar Legenda e Comentários" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Editar Etiquetas" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "data de imagem (AAAAmmDD)" #: f.info.cc:165 msgid "use last" msgstr "usar último" #: f.info.cc:168 msgid "image stars" msgstr "estrelas da imagem" #: f.info.cc:186 msgid "current tags" msgstr "etiquetas atuais" #: f.info.cc:191 msgid "recent tags" msgstr "etiquetas recentes" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "etiquetas definidas" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "Gerenciar Etiquetas" #: f.info.cc:348 msgid "category" msgstr "categoria" #: f.info.cc:351 msgid "tag" msgstr "etiqueta" #: f.info.cc:354 msgid "create" msgstr "criar" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "excluir" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "busca de arquivo índice erro: %s" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "Adicinar Etiquetas em vários" #: f.info.cc:1354 msgid "tags to add" msgstr "etiquetas a adicionar" #: f.info.cc:1359 msgid "create tag" msgstr "criar etiqueta" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " etiquetas demais" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "Adicionar várias Etiquetas" #: f.info.cc:1556 msgid "tag to remove" msgstr "etiquetas a remover" #: f.info.cc:1560 msgid "optional replacement" msgstr "substituição opcional" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "0 arquivos selecionados" #: f.info.cc:1568 msgid "search all files" msgstr "procurar todos arquivos" #: f.info.cc:1653 msgid "no files selected" msgstr "nenhum arquivo selecionado" #: f.info.cc:1659 msgid "no tag specified" msgstr "nenhuma etiqueta especificada" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "especificar etiqueta" #: f.info.cc:1821 msgid "View Info" msgstr "Ver Info" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "Editar Info" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "Excluir Info" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "Todos" #: f.info.cc:1990 msgid "One Key:" msgstr "Uma chave:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "Procurar Etiquetas, Comentários, Nome de arquivos" #: f.info.cc:2350 msgid "date range" msgstr "variação de data" #: f.info.cc:2351 msgid "stars range" msgstr "variação de estrelas" #: f.info.cc:2352 msgid "search tags" msgstr "procurar etiquetas" #: f.info.cc:2353 msgid "search text" msgstr "procurar texto" #: f.info.cc:2354 msgid "file names" msgstr "nome de arquivos" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "aaaammdd" #: f.info.cc:2365 msgid "all/any" msgstr "todos/qualquer" #: f.info.cc:2702 msgid "No matching images found" msgstr "Nenhuma imagem encontrada" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "Não há arquivo índice" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "maior" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "aumentar tamanho de miniaturas" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "reduzir tamanho de miniaturas" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "menor" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "anterior" #: f.navi.cc:190 msgid "parent directory" msgstr "pasta anterior" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "primeira página" #: f.navi.cc:191 msgid "jump to first file" msgstr "pular para primeiro arquivo" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "página ant." #: f.navi.cc:192 msgid "previous page" msgstr "página anterior" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "coluna ant." #: f.navi.cc:193 msgid "previous row" msgstr "coluna anterior" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "próxiuma coluna" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "próxima página" #: f.navi.cc:195 msgid "ttip::next page" msgstr "" #: f.navi.cc:196 msgid "jump to last file" msgstr "pular para último arquivo" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "última página" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "fechar" #: f.navi.cc:197 msgid "close image gallery" msgstr "fechar galeria de imagens" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "Selecionar arquivos" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "cancelar" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "pronto" #: f.navi.cc:1422 msgid "insert" msgstr "inserir" #: f.navi.cc:1423 msgid "add all" msgstr "adicionar todos" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Ajustar Brilho e Cor" #: f.retouch.cc:110 msgid "small-steps" msgstr "pouco-a-pouco" #: f.retouch.cc:119 msgid "color saturation" msgstr "saturação de cor" #: f.retouch.cc:126 msgid " reset 1 " msgstr "reconfigurar 1" #: f.retouch.cc:127 msgid "reset all" msgstr "reconfigurar tudo" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "Aumentar variação de Brilho" #: f.retouch.cc:887 msgid "bright pixels" msgstr "pixels brilhantes" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Reduzir distribuição de Brilho" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Abrandar" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "Curva de Brilho sobre a imagem" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "Mapa sonoro" #: f.retouch.cc:1758 msgid "low" msgstr "baixo" #: f.retouch.cc:1760 msgid "high" msgstr "alto" #: f.retouch.cc:1763 msgid "Amplify" msgstr "Ampliar" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Ajustar balanço de branco" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Clique em uma área branca ou cinza da imagem" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "Imagens para mesclagem de cor" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "raio do mouse para a amostra de cor" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Abrir" #: f.retouch.cc:2310 msgid "image for source color" msgstr "imagem para fonte de cor" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "clique na imagem para obter a cor fonte" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "imagem para mesclagem de cor" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "clique na imagem para aplicar mesclagem de cor" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "selecione imagem para fonte de cor primeiro" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Vermelho" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Verde" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Azul" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "Clique na imagem para selecionar pixels." #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "Revisar RGB" #: f.retouch.cc:3084 msgid "Metric:" msgstr "Métrica:" #: f.retouch.cc:3139 msgid "Blend" msgstr "Mistura" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Método 1:\n" " Clique com o botão esquerdo no olho vermelho a escurecer.\n" "Método 2:\n" " Arraste e solte com o botão direito enquadrando o olho vermelho.\n" " Clique com o botão esquerdo no olho vermelho a escurecer.\n" "Retornar ao olho vermelho:\n" " Clique com o botão direito no olho vermelho." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Redução de olhos vermelhos" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Configurar raio de desfoque" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Aguçar" #: f.retouch.cc:4202 msgid "edge detection" msgstr "detecção de borda" #: f.retouch.cc:4203 msgid "cycles" msgstr "ciclos" #: f.retouch.cc:4204 msgid "reduce" msgstr "reduzir" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "desaguçar máscara" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "gradiente de brilho" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Precione o botão de reduzir para \n" " reduzir o ruído pouco-a-pouco. \n" " Use desfazer para começar novamente." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Redução de ruído" #: f.retouch.cc:4650 msgid "algorithm" msgstr "algoritmo" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "aproximar dispersos por cor (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "aproximar dispersos por cor (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "configurar brilho mediano pela cor" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "filtro cartola por cor" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" "1. Arraste o mouse para selecionar. \n" "2. Apague. 3. Repita. " #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "Apagador inteligente" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Raio" #: f.retouch.cc:5005 msgid "Blur" msgstr "Desfoque" #: f.retouch.cc:5008 msgid "New Area" msgstr "Nova Ãrea" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "Remover Sujeira" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "limite de tamanho de mancha" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "brilho máximo" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "contraste mínimo" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "" #: f.retouch.cc:5989 msgid "pixel group" msgstr "" #: f.retouch.cc:5990 msgid "circle color" msgstr "" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "" #: f.retouch.cc:6164 msgid "file format error" msgstr "" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Desfazer memória %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Editar Pixels" #: f.retouch.cc:6695 msgid "pick" msgstr "capturar" #: f.retouch.cc:6697 msgid "erase" msgstr "apagar" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "raio do pincel" #: f.retouch.cc:6706 msgid "transparency center" msgstr "centro de transparência" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "borda de transparência" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Limite do histórico de modificações foi alcançado. \n" "Salve seu trabalho clicando [pronto], e continue a editar." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Selecionar área para edições" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "Pressione F1 para ajuda" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" "Seleção de Ãrea não suportada \n" "por esta função de edição" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "retângulo" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "elipse" #: f.select.cc:110 msgid "draw: freehand" msgstr "desenho: mão livre" #: f.select.cc:111 msgid "draw: follow edge" msgstr "desenho: seguir borda" #: f.select.cc:114 msgid "select by mouse" msgstr "seleção por mouse" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "raio do mouse" #: f.select.cc:120 msgid "match mouse color" msgstr "" #: f.select.cc:124 msgid "search range" msgstr "" #: f.select.cc:126 msgid "firewall" msgstr "firewall" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "excedeu %d edições" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" "Clique uma vez dentro de cada área inclusa \n" "(possíveis fendas no contorno serão encontradas). \n" "Pressione F1 para ajuda." #: f.select.cc:1078 msgid "finish area" msgstr "finalize a área" #: f.select.cc:1113 msgid "searching" msgstr "procurando" #: f.select.cc:1185 msgid "outline has a gap" msgstr "contorno tem uma fenda" #: f.select.cc:1189 msgid "success" msgstr "sucesso" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "a área não está finalizada" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Cálculo de borda em andamento" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Calc. área de borda" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "posicione o mouse clique/arraste" #: f.select.cc:1887 msgid "Paste Image" msgstr "Colar Imagem" #: f.select.cc:1901 msgid "angle" msgstr "ângulo" #: f.select.cc:2160 msgid "load select area from a file" msgstr "carregar selecionador de área de um arquivo" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "erro ao abrir arquivo .tiff e .info" #: f.select.cc:2213 msgid "save select area to a file" msgstr "salve a área selecionada em um arquivo" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "Selecionar toda imagem" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "Editar função Amplificador" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "alimentação: centro" #: f.select.cc:2501 msgid "edge" msgstr "borda" #: f.select.cc:2504 msgid "reset area" msgstr "redefinir área" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "" #: f.tools.cc:85 msgid "Start new collection" msgstr "" #: f.tools.cc:87 msgid "Edit a collection" msgstr "" #: f.tools.cc:89 msgid "View a collection" msgstr "" #: f.tools.cc:91 msgid "Delete a collection" msgstr "" #: f.tools.cc:95 msgid "Editing:" msgstr "" #: f.tools.cc:99 msgid "Action:" msgstr "" #: f.tools.cc:133 msgid "New Collection" msgstr "" #: f.tools.cc:156 msgid "Edit Collection" msgstr "Editar Coleção" #: f.tools.cc:172 msgid "View Collection" msgstr "" #: f.tools.cc:193 msgid "Delete Collection" msgstr "Excluir Coleção" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "" #: f.tools.cc:256 msgid "add image to collection" msgstr "" #: f.tools.cc:301 msgid "too many saved files" msgstr "" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "" #: f.tools.cc:375 msgid "old top directory" msgstr "" #: f.tools.cc:378 msgid "new top directory" msgstr "" #: f.tools.cc:434 msgid "completed" msgstr "completo" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "" #: f.tools.cc:474 msgid "new max. width" msgstr "nova largura máxima" #: f.tools.cc:481 msgid "new file type" msgstr "" #: f.tools.cc:482 msgid "same" msgstr "" #: f.tools.cc:490 msgid "replace originals" msgstr "substituir originais" #: f.tools.cc:491 msgid "export to location" msgstr "exportar para localização" #: f.tools.cc:492 msgid "remove EXIF" msgstr "" #: f.tools.cc:549 msgid "Select directory" msgstr "Selecionar pasta" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "substituir arquivos originais? (max. %d x %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "copiar arquivos? (max. %d x %d) \n" " para localização %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "localização não é uma pasta válida" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "tamanho max. %d x %d não é razoável" #: f.tools.cc:654 msgid "*** file already exists" msgstr "" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "Programa ufraw-batch é requerido" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Abrir arquivo RAW" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "Selecionar arquivos RAW para converter" #: f.tools.cc:769 msgid "Choose file type" msgstr "" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "Pressione ESC para sair da apresentação" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "" #: f.tools.cc:893 msgid "arrow keys" msgstr "botões de setas" #: f.tools.cc:894 msgid "instant" msgstr "imediato" #: f.tools.cc:895 msgid "fade-in" msgstr "esmaecer" #: f.tools.cc:896 msgid "roll-right" msgstr "rolar para direita" #: f.tools.cc:897 msgid "roll-down" msgstr "rolar para baixo" #: f.tools.cc:898 msgid "shift-left" msgstr "salto para esquerda" #: f.tools.cc:899 msgid "venetian" msgstr "veneziano" #: f.tools.cc:900 msgid "grate" msgstr "grade" #: f.tools.cc:903 msgid "radar" msgstr "radar" #: f.tools.cc:904 msgid "jaws" msgstr "maxilas" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Apresentação" #: f.tools.cc:915 msgid "seconds" msgstr "segundos" #: f.tools.cc:919 msgid "music file" msgstr "arquivo de música" #: f.tools.cc:923 msgid "transitions" msgstr "" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "Selecione arquivo de música ou lista de reprodução" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "" #: f.tools.cc:1844 msgid "no new files found" msgstr "" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "Sincronizar Arquivos" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Pasta raiz das imagens:" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Selecionar pasta raiz de imagens" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "Mostrar RGB" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "Linhas de grade" #: f.tools.cc:2728 msgid "x-spacing" msgstr "espaçamento-x" #: f.tools.cc:2729 msgid "x-count" msgstr "contagem-x" #: f.tools.cc:2730 msgid "x-enable" msgstr "" #: f.tools.cc:2736 msgid "y-spacing" msgstr "espaçamento-y" #: f.tools.cc:2737 msgid "y-count" msgstr "contagem-y" #: f.tools.cc:2738 msgid "y-enable" msgstr "" #: f.tools.cc:2745 msgid "x-offset" msgstr "" #: f.tools.cc:2749 msgid "y-offset" msgstr "" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "Imagens via e-mail" #: f.tools.cc:2947 msgid "max. width" msgstr "máx. largura" #: f.tools.cc:2948 msgid "max. height" msgstr "máx. altura" #: f.tools.cc:3093 msgid "too many files" msgstr "arquivos em excesso" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" "Brilho deveria mostrar uma inclinação gradual \n" "estendendo-se até as bordas." #: f.tools.cc:3174 msgid "Monitor Check" msgstr "Verificar Monitor" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "Monitor Gamma" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "Distribuição de Brilho" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Traduções disponíveis" #: f.tools.cc:3436 msgid "Set Language" msgstr "Configurar língua" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "Criar Atalho" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "Estilo da barra de ferramentas" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "Texto" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "Use os botões ou arrante a borda direita com o mouse" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Rotacioanar" #: f.transform.cc:64 msgid "degrees" msgstr "graus" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Aparar" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Desfazer recorte" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "graus: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "áurea" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "" "Arraste pelo centro para mover, arraste as estremidades para redimensionar." #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Recortar/Aparar bordas" #: f.transform.cc:348 msgid "customize" msgstr "customizar" #: f.transform.cc:359 msgid "ratio" msgstr "taxa" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "Travar taxa" #: f.transform.cc:368 msgid "invert" msgstr "inverter" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "Aparar rodapés" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "Manter proporção" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Redimensionar" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Anterior" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" "Insira um texto, clique/arraste na imagem.\n" "Clique com o botão direito para remover" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "Tomar nota" #: f.transform.cc:1307 msgid "Size" msgstr "Tamanho" #: f.transform.cc:1310 msgid "Angle" msgstr "Ângulo" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Cor" #: f.transform.cc:1322 msgid "Transparency" msgstr "Transparência" #: f.transform.cc:1325 msgid "text" msgstr "texto" #: f.transform.cc:1330 msgid "backing" msgstr "fundo" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" "Contorno\n" " Largura" #: f.transform.cc:1335 msgid "outline" msgstr "contorno" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "Arquivo de Comentário:" #: f.transform.cc:1416 msgid "select font" msgstr "selecionar fonte" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "Virar" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "horizontal" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "vertical" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "Fazer Negativo" #: f.transform.cc:2158 msgid "black/white positive" msgstr "preto/branco positivo" #: f.transform.cc:2159 msgid "black/white negative" msgstr "preto/branco negativo" #: f.transform.cc:2160 msgid "color positive" msgstr "cor positiva" #: f.transform.cc:2161 msgid "color negative" msgstr "cor negativa" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Desempenar" #: f.transform.cc:2282 msgid "linear" msgstr "linear" #: f.transform.cc:2285 msgid "curved" msgstr "curvo" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" " Selecione a área a distorcer usando a função de seleção. \n" " Precione [iniciar distorção] e puxe a área com o mouse. \n" " Faça vários ajustes até que esteja satisfeito. \n" " Quando terminar, selecione outra área e precione [pronto]." #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "Distorcer (área)" #: f.transform.cc:2864 msgid "start warp" msgstr "iniciar distorção" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Puxe uma posição da usando o mouse. \n" " Faça vários ajustes até que esteja satisfeito. \n" " Quando terminar, precione [pronto]." #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "Distorcer (curvo)" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "Distorcer (linear)" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Puxe um canto da imgem usando o mouse. \n" " Faça vários ajustes até que esteja satisfeito. \n" " Quando terminar, precione [pronto]." #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "Distorcer (afim)" #: fotoxx-12.01.cc:185 msgid "File" msgstr "Arquivo" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "Galeria de Imagens" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "Clonar 50/50" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "Clonar Sobreposta" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "Abrir em nova janela" # msgstr "Abrir próximo arquivo" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Abrir arquivo anterior" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "Abrir arquivo recente" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "Salvar no mesmo arquivo" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "Salvar nova versão" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "Salvar novo arquivo" #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "Mover arquivo para lixeira" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "Renomear vários arquivos" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Imprimir" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "Sair do fotoxx" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "Ferramentas" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "Converter arquivos RAW" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "Gravar imagens em CD/DVD" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Checar Monitor" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Trocar língua" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "Uso de memória" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "Editar Legendas/Comentários" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "Ver Info (curto)" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "Ver Info (longo)" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "Procurar Imagens" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "Selecionar" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Mostrar" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Ocultar" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "Habilitar" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "Desabilitar" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Inverter" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "Deselecionar" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "Copiar" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "Colar" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Salvar" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "Selecionar e Editar" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "Transformar" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Retocar" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "Brilho/Cor" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "Expandir Brilho" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "Reduzir Brilho" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "Curvas de brilho" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "Balanço de branco" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "Mesclar Cores" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Olhos vermelhos" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Embaçar" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Reduzir ruído" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Arte" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Resolução de cor" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "Desenho" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "Contornos" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "Alto-relevo" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "Ladrilhos" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "Pontos" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "Pintura" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Combinar" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "Grande Alcance Dinâmico (HDR)" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "Alta Profundidade de Campo (HDF)" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "Pilha / Pintura" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "Pilha / Ruído" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Panorama" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "Panorama Vertical" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "Editar Plugins" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Ajuda" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "Sobre" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "Guia de usuário" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Relatório de mudanças" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "Página na web" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "Galeria" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Próximo" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Abrir próximo arquivo" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Aproximar (aumentar)" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Distanciar (diminuir)" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Desfazer" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Desfazer uma edição" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Refazer" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Refazer uma edição" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "Salvar+V" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "Salvar+F" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "Mover para lixeira" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "Lixeira" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Sair" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "O básico do Fotoxx" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "Excedeu 50 pontos de ancoragem" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "carregar curva de arquivo" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "arquivo de curva inválido" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "arquivo de curva tem número de curvas diferente" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "salvar curva para arquivo" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "não se pode editar paralelamente" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "exiftool não está instalado \n" "imagens editadas perderão informações EXIF" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "Muitas edições, favor salvar imagem" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Ãrea selecionada não pode ser capturada.\n" "Continuar?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" "Ãrea selecionada não ativa.\n" "Continuar?" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "erro ao abrir miniatura de arquivo" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "TIFF, Erro ao abrir" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF bits/cor=%d não suportado" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "TIFF, Erro ao carregar" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "TIFF, Erro ao gravar" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "tipo de arquivo não suportado" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "escrita do pixbuf falhou" #: fotoxx.h:728 msgid "absolute" msgstr "" #: fotoxx.h:730 msgid "Add All" msgstr "Adicionar todos" #: fotoxx.h:732 msgid "Amount" msgstr "Quantidade" #: fotoxx.h:733 msgid "Apply" msgstr "Aplicar" #: fotoxx.h:734 msgid "Black" msgstr "" #: fotoxx.h:735 msgid "Blend Width" msgstr "Quantidade de mistura" #: fotoxx.h:737 msgid "Brightness" msgstr "Briho" #: fotoxx.h:738 msgid "Browse" msgstr "Procurar" #: fotoxx.h:739 msgid "Cancel" msgstr "Cancelar" #: fotoxx.h:740 msgid "Clear" msgstr "Limpar" #: fotoxx.h:742 msgid "Commit" msgstr "" #: fotoxx.h:744 msgid "Curve File:" msgstr "Arquivo de curva:" #: fotoxx.h:745 msgid "Cut" msgstr "" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Ãreas mais escuras" #: fotoxx.h:747 msgid "Delete" msgstr "Exlcuir" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" "Descartar lista de galleria especial? \n" " %s" #: fotoxx.h:750 msgid "Done" msgstr "Pronto" #: fotoxx.h:751 msgid "Edit" msgstr "Editar" #: fotoxx.h:753 msgid "Erase" msgstr "" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "pacote libimage-exiftool-perl requerido" #: fotoxx.h:755 msgid "Fetch" msgstr "Buscar" #: fotoxx.h:756 msgid "Finish" msgstr "Finalizar" #: fotoxx.h:757 msgid "Font" msgstr "Fonte" #: fotoxx.h:759 msgid "Height" msgstr "Altura" #: fotoxx.h:760 msgid "histogram" msgstr "histograma" #: fotoxx.h:762 msgid "Insert" msgstr "Inserir" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Ãreas mais claras" #: fotoxx.h:765 msgid "limit" msgstr "limite" #: fotoxx.h:766 msgid "New" msgstr "" #: fotoxx.h:768 msgid "OK" msgstr "OK" #: fotoxx.h:772 msgid "Pause" msgstr "Pausar" #: fotoxx.h:773 msgid "Percent" msgstr "Percentagem" #: fotoxx.h:774 msgid "Presets" msgstr "Predefinições" #: fotoxx.h:775 msgid "Proceed" msgstr "Continuar" #: fotoxx.h:777 msgid "range" msgstr "variação" #: fotoxx.h:780 msgid "Reduce" msgstr "Reduzir" #: fotoxx.h:782 msgid "Reset" msgstr "" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Tipo de arquivo desconhecido, Salvar como tiff/jpeg/png para editar" #: fotoxx.h:785 msgid "Search" msgstr "Buscar" #: fotoxx.h:789 msgid "Start" msgstr "Iniciar" #: fotoxx.h:790 msgid "Threshold" msgstr "Limiar" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "Desfazer tudo" #: fotoxx.h:793 msgid "Undo Last" msgstr "Desfazer último" #: fotoxx.h:795 msgid "Unfinish" msgstr "" #: fotoxx.h:797 msgid "View" msgstr "" #: fotoxx.h:798 msgid "White" msgstr "" #: fotoxx.h:799 msgid "Width" msgstr "Largura" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "arquivo de ajuda não encontrado: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "não foi possível abrir arquivo %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "salvar tela para arquivo" #: zfuncs.cc:6222 msgid "No" msgstr "Não" #: zfuncs.cc:6222 msgid "Yes" msgstr "Sim" #: zfuncs.cc:6447 msgid "open" msgstr "abrir" #: zfuncs.cc:6452 msgid "choose" msgstr "escolher" #: zfuncs.cc:6457 msgid "save" msgstr "salvar" #: zfuncs.cc:6463 msgid "open folder" msgstr "abrir pasta" #: zfuncs.cc:6468 msgid "create folder" msgstr "criar pasta" #: zfuncs.cc:6474 msgid "hidden" msgstr "oculto" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "Qualidade JPG 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "" #: zfuncs.cc:6737 msgid "top" msgstr "topo" #: zfuncs.cc:6738 msgid "bottom" msgstr "rodapé" #: zfuncs.cc:6739 msgid "left" msgstr "esquerda" #: zfuncs.cc:6740 msgid "right" msgstr "direita" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Arquivo de parâmetros iniciais criado. \n" "Inspecione e revise se necessário." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "carregar parâmetros de arquivo" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "salvar parâmetros para um arquivo" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "editar parâmetros" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "lista\n" "todos" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "carregar\n" "arquivo" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "salvar\n" "arquivo" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "adicionar\n" "novo" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "aplicar" #: zfuncs.cc:7479 msgid "apply?" msgstr "aplicar?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(novo nome de parâmetro)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "adicionar parâmetro" #~ msgid "Brightness Graph" #~ msgstr "Gráfico de Brilho" #~ msgid "Add Menu and Launcher" #~ msgstr "Adicionar Menu e Atalho" #~ msgid "Batch Resize/Export" #~ msgstr "Redimensionar/Exportar várias " #~ msgid "select by color" #~ msgstr "seleção por cor" #~ msgid "radius" #~ msgstr "raio" #~ msgid "match" #~ msgstr "equiparar" #~ msgid "Search results file error %s" #~ msgstr "Erro no arquivo de resultados de busca %s" #~ msgid "Batch Resize" #~ msgstr "Redimencionar vários" #~ msgid "new max. height" #~ msgstr "nova altura máxima" #~ msgid "copy EXIF" #~ msgstr "copiar info. EXIF" #~ msgid "new file already exists" #~ msgstr "novo arquivo já existe" #~ msgid "Select area first" #~ msgstr "Selecione a área primeiro" #~ msgid "open a file" #~ msgstr "abrir um arquivo" #~ msgid "paper format is crazy" #~ msgstr "formato do papel é louco" #~ msgid "margins:" #~ msgstr "margens:" #~ msgid "landscape" #~ msgstr "paisagem" #~ msgid "portrait" #~ msgstr "retrato" #~ msgid "paper format" #~ msgstr "formato do papel" #~ msgid "printer ID" #~ msgstr "ID de impressora" #~ msgid "print" #~ msgstr "imprimir" #~ msgid "" #~ "Discard current gallery list? \n" #~ " %s" #~ msgstr "" #~ "Discartar lista de galeria atual? \n" #~ " %s" #~ msgid "Edit Comments" #~ msgstr "Editar Comentários" #~ msgid "Edit Caption" #~ msgstr "Editar Legenda" #~ msgid "Auto-search lens mm and bow" #~ msgstr "Procura automática de mm e curvatura de lente" #~ msgid "Merge the images together" #~ msgstr "Mesclar imagens" #~ msgid "use two s only" #~ msgstr "usar duas imagens apenas" #~ msgid "tags index arquivo error: %s" #~ msgstr "erro no arquivo de índices: %s" #~ msgid "select image files to add tags" #~ msgstr "Selecionar arquivos de imagem para etiquetar" #~ msgid "select files" #~ msgstr "Selecionar arquivos" #~ msgid "rename files" #~ msgstr "renomear arquivos" #~ msgid "freehand draw" #~ msgstr "desenho a mão livre" #~ msgid "follow edge" #~ msgstr "seguir borda" #~ msgid "" #~ "exiftool missing, please install \n" #~ " package libimage-exiftool-perl" #~ msgstr "" #~ "exiftool faltando, favor instalar \n" #~ " pacote libimage-exiftool-perl" #~ msgid "color range" #~ msgstr "variação de cor" #~ msgid "browse" #~ msgstr "procurar" #~ msgid "base image" #~ msgstr "imagem base" #~ msgid "add tags" #~ msgstr "adicionar etiquetas" #~ msgid "TIFF colors=%d depth=%d not supported" #~ msgstr "TIFF, cores=%d e intensidade=%d não suportadas" #~ msgid "Read File" #~ msgstr "Ler arquivo" #~ msgid "Package ufraw required for this function" #~ msgstr "Pacote ufraw requerido para esta função" #~ msgid "Fix Image Perspective" #~ msgstr "Acertar perspectiva de imagem" #~ msgid "" #~ "Convert tags to new standard now?\n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Converter etiquetas para novo padrão agora?\n" #~ "Suas imagens possuem cópia de segurança?" #~ msgid "Burn" #~ msgstr "Gravar" #~ msgid "color intensity" #~ msgstr "Intensidade de cor" #~ msgid "Batch Delete Tags" #~ msgstr "Excluir várias etiquetas" #~ msgid "Clip Brightness" #~ msgstr "Limitar Brilho" #~ msgid "" #~ "position image\n" #~ "with mouse drag" #~ msgstr "" #~ "posicione a imagem\n" #~ "arrastando com o mouse" #~ msgid "Warp Image in Selected Area" #~ msgstr "Distorcer imagem em área selecionada" #~ msgid "Warp Image (curvy)" #~ msgstr "Distorcer (curvo)" #~ msgid "Warp Image" #~ msgstr "Distorcer imagem" #~ msgid "Warp Area" #~ msgstr "Distorcer área" #~ msgid "Open File" #~ msgstr "Abrir Arquivo" #~ msgid "" #~ " Pull on an image edge using the mouse. \n" #~ " Make multiple mouse pulls until satisfied. \n" #~ " When finished, press [done]." #~ msgstr "" #~ " Puxe uma borda da imagem usando o mouse \n" #~ " Faça vários ajustes até que esteja satisfeito. \n" #~ " Quando terminar, precione [pronto]." #~ msgid "match any tag" #~ msgstr "condizer com qualquer etiqueta" #~ msgid "match all tags" #~ msgstr "condizer com todas etiquetas" #~ msgid "comments" #~ msgstr "comentários" #~ msgid "Tags" #~ msgstr "Etiquetas" #~ msgid "Suspend" #~ msgstr "Suspender" #~ msgid "Set Tile and Gap Size" #~ msgstr "Configurar ladrilho e espaçamento" #~ msgid "Search Tags" #~ msgstr "Buscar etiquetas" #~ msgid "Resume" #~ msgstr "Retomar" #~ msgid "Edit User Comments" #~ msgstr "Editar Comentários de Usuário" #~ msgid "Edit EXIF data" #~ msgstr "Editar informações EXIF" #~ msgid "EXIF data" #~ msgstr "Informações EXIF" #~ msgid "Delete EXIF data" #~ msgstr "Excluir informações EXIF" #~ msgid "Basic EXIF data" #~ msgstr "Informações EXIF básicas" #~ msgid "All EXIF data" #~ msgstr "Toda informação EXIF" #~ msgid "/path*/file*" #~ msgstr "/caminho*/arquivo*" #~ msgid "transparency" #~ msgstr "transparência" #~ msgid "foreground" #~ msgstr "primeiro plano" #~ msgid "background" #~ msgstr "fundo" #~ msgid "annotation file:" #~ msgstr "arquivo de comentário:" #~ msgid "tags index file error: %s" #~ msgstr "erro no arquivo índice de etiquetas: %s" #~ msgid "save select area as a file" #~ msgstr "salvar selecionador de área em arquivo" #~ msgid "new tags index will now be created" #~ msgstr "novo índice de etiquetas será criado agora" #~ msgid "manage tags" #~ msgstr "gerenciar etiquetas" #~ msgid "color select firewall" #~ msgstr "selecionar cor do firewall" #~ msgid "cannot read .dist file" #~ msgstr "Erro ao ler arquivo .dist" #~ msgid "brightness to clip (percent)" #~ msgstr "Brilho a apagar (percentagem)" #~ msgid "Use F1 for context help" #~ msgstr "Use F1 para ajuda contextualizada" #~ msgid "Stack" #~ msgstr "Pilha" #~ msgid "Rebuild Tags Index" #~ msgstr "Reconstruir índice de etiquetas" #~ msgid "No tags index file" #~ msgstr "Nenhum arquivo índice de etiquetas" #~ msgid "" #~ "New tags file already exists! \n" #~ "Proceed anyway?" #~ msgstr "" #~ "Novo arquivo de etiquetas já existe! \n" #~ "Continuar assim mesmo?" #~ msgid "HDR" #~ msgstr "HDR" #~ msgid "HDF" #~ msgstr "HDF" #~ msgid "" #~ "Convert tags to new standard now? \n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Converter etiquetas para novo padrão agora? \n" #~ "Você possui cópia de segurança das imagens?" #~ msgid "Convert tags to new standard" #~ msgstr "Converter etiquetas para novo padrão" #~ msgid "Convert Tags !!!" #~ msgstr "Converter etiquetas!" #~ msgid "Constrain" #~ msgstr "Restrição" #~ msgid "Area" #~ msgstr "Ãrea" #~ msgid "target group area" #~ msgstr "área de grupo de destino" #~ msgid "vertical unbend" #~ msgstr "desempeno vertical" #~ msgid "select by mouse:" #~ msgstr "selecionar por mouse:" #~ msgid "select by color:" #~ msgstr "selecionar por cor:" #~ msgid "press ESC to exit" #~ msgstr "pressione ESC para sair" #~ msgid "horizontal unbend" #~ msgstr "desempeno horizontal" #~ msgid "Rebuild Thumbnails" #~ msgstr "Reconstruir miniaturas" #~ msgid "area outline has a hole" #~ msgstr "contorno de área tem uma falha" #~ msgid "" #~ "Search all areas for edge and inside pixels. \n" #~ "Click inside each enclosed area in sequence." #~ msgstr "" #~ "Procura de áreas contornadas e pixels internos. \n" #~ "Mantenha esta janela aberta, clique dentro de cada área enquadrada em " #~ "sequência." #~ msgid "Create Launcher" #~ msgstr "Criar atalho" #~ msgid "make new version" #~ msgstr "fazer nova versão" #~ msgid "click on window to show RGB" #~ msgstr "clique na janela para mostrar RGB" #~ msgid "Save As" #~ msgstr "Salvar como..." #~ msgid "Clone fotoxx" #~ msgstr "Clonar fotoxx" #~ msgid "Time Interval" #~ msgstr "Intervalo de tempo" #~ msgid "Discard modifications?" #~ msgstr "Discartar modificações?" #~ msgid "transition" #~ msgstr "transição" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "Renomeação falhou \n" #~ " %s" #~ msgid "incremental" #~ msgstr "incremental" #~ msgid "full rebuild" #~ msgstr "reconstruir tudo" #~ msgid "y-grid" #~ msgstr "grade-y" #~ msgid "x-grid" #~ msgstr "grade-x" #~ msgid "enable" #~ msgstr "habilitar" #~ msgid "" #~ "Click on image where new or saved \n" #~ "images are to be inserted (after)." #~ msgstr "" #~ "Clique na imagem na qual a imagem nova ou \n" #~ "salva serão inseridas (depois)." #~ msgid "" #~ "Click on images to remove and save, \n" #~ "then press [Paste] to insert them." #~ msgstr "" #~ "Clique em imagens para remover e salve, \n" #~ "depois pressione [Colar] para inseri-las." #~ msgid "Click on images to delete." #~ msgstr "Clique em imagens para excluir" #~ msgid "select image files" #~ msgstr "selecione arquivos de imagem" #~ msgid "" #~ "Select images to add, then \n" #~ "press [Paste] to insert them." #~ msgstr "" #~ "Selecione imagens para adicionar, depois \n" #~ "pressione [Colar] para inseri-las." #~ msgid "Insert new or saved images" #~ msgstr "Inserir salvas ou novas imagens" #~ msgid "Remove and save images" #~ msgstr "Remover e salvar imagens" #~ msgid "Delete images from collection" #~ msgstr "Excluir imagens da coleção" #~ msgid "Add new images to collection" #~ msgstr "Adicionar novas imagens à coleção" #~ msgid "Save Collection" #~ msgstr "Salvar coleção" #~ msgid "" #~ "Run Tools > Synchronize Files so that gallery windows \n" #~ "will be fast and Search Images will work correctly." #~ msgstr "" #~ "Acesse Ferramentas > Sincronizar Arquivos para as janelas \n" #~ "da galeria serem rápidas e a Procura de Imagens funcionar corretamente." #~ msgid "Translate" #~ msgstr "Traduzir" #~ msgid "Open Collection" #~ msgstr "Abrir Coleção" #~ msgid "Create Collection" #~ msgstr "Criar Coleção" #~ msgid "select new file" #~ msgstr "selecionar novo arquivo" #~ msgid "both" #~ msgstr "ambos" #~ msgid "icons" #~ msgstr "ícones" #~ msgid "lens name" #~ msgstr "nome da lente" #~ msgid "start edit function first" #~ msgstr "inicie a função de edição primeiro" #~ msgid "my mouse" #~ msgstr "meu mouse" #~ msgid "Lens Parameters" #~ msgstr "Parâmetros de lente" fotoxx-12.01.2/locales/fotoxx-zh_CN.po0000664000175000017500000015720311701011017016153 0ustar micomico# # <>, YEAR, 2010. # Jie , 2010. # msgid "" msgstr "" "Project-Id-Version: fotoxx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:05+0100\n" "PO-Revision-Date: 2010-09-08 19:28+1000\n" "Last-Translator: Jie \n" "Language-Team: Simplified Chinese <18n-translation@lists.linux.net.cn>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: UTF-8\n" "X-Poedit-Language: Simplified Chinese\n" "X-Poedit-Country: China PRC\n" "X-Poedit-SourceCharset: utf-8\n" "Plural-Forms: nplurals=1; plural=0\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "设置色深为 1-16bit" #: f.art.cc:57 msgid "Set Color Depth" msgstr "设置色深" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "绘图" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "对比度" #: f.art.cc:215 msgid "outlines" msgstr "轮廓" #: f.art.cc:220 msgid "pencil" msgstr "铅笔" #: f.art.cc:221 msgid "chalk" msgstr "粉笔" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "" #: f.art.cc:394 msgid "outline threshold" msgstr "" #: f.art.cc:397 msgid "outline width" msgstr "" #: f.art.cc:400 msgid "image brightness" msgstr "" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "浮雕" #: f.art.cc:626 msgid "depth" msgstr "宽度" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "色彩" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "图å—(马赛克)" #: f.art.cc:825 msgid "tile size" msgstr "图å—尺寸" #: f.art.cc:829 msgid "tile gap" msgstr "图å—è¾¹è·" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "" #: f.art.cc:1007 msgid "dot size" msgstr "" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "彩绘" #: f.art.cc:1226 msgid "color depth" msgstr "色深" #: f.art.cc:1230 msgid "patch area goal" msgstr "" #: f.art.cc:1234 msgid "req. color match" msgstr "需è¦è‰²å½©åŒ¹é…" #: f.art.cc:1238 msgid "borders" msgstr "边框" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "选择2到9个文件" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "图åƒä¸å…¨ä¸ºåŒæ ·å°ºå¯¸" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "调整图åƒè¾“出" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "æš— åƒç´ " #: f.comp.cc:2326 msgid "light pixels" msgstr "亮åƒç´ " #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "文件:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "涂画和扭曲图åƒ" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "图åƒ" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "绘制(黑白)" #: f.comp.cc:2851 msgid "warp" msgstr "扭曲" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "调整åƒç´ åˆæˆ" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "选择2到4个文件" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" "拖拽图åƒç²—略排布。\n" "拖动下进行旋转。" #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "æœç´¢" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "é¢„å¯¹é½ å›¾åƒ" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "镜头焦è·" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "镜头弓度" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "改å˜å°ºå¯¸" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "改å˜çª—å£å°ºå¯¸" #: f.comp.cc:4457 msgid "use two images only" msgstr "使用两个图åƒ" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "太多é‡å ï¼Œæ— æ³•对é½" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "匹é…亮度和色彩" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "自动上色" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "文件色彩" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "æ‰“å¼€å›¾åƒæ–‡ä»¶" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "" #: f.file.cc:504 msgid "Do not warn again" msgstr "" #: f.file.cc:520 msgid "Warning" msgstr "" #: f.file.cc:643 msgid "Save File" msgstr "ä¿å­˜æ–‡ä»¶" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "è´¨é‡" #: f.file.cc:668 msgid "make current" msgstr "" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "jpeg è´¨é‡å¿…须在 1-100 é—´" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "覆盖文件? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "" #: f.file.cc:905 msgid "file name" msgstr "" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "Linuxæ ‡å‡†å›žæ”¶ç«™ä»æœªæ”¯æŒã€‚\n" "将会建立桌é¢å›žæ”¶ç«™ã€‚" #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "移动åªè¯»å›¾ç‰‡åˆ°å¯å›žæ”¶æ–‡ä»¶å¤¹" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "无法创建å¯å›žæ”¶æ–‡ä»¶å¤¹ï¼š %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "错误:%s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "å›¾åƒæ–‡ä»¶æ”¹å" #: f.file.cc:1141 msgid "old name" msgstr "æ—§åç§°" #: f.file.cc:1142 msgid "rename to" msgstr "改å为" #: f.file.cc:1143 msgid "previous" msgstr "å‰ä¸€ä¸ª" #: f.file.cc:1229 msgid "The target file already exists" msgstr "目标文件已ç»å­˜åœ¨" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" #: f.file.cc:1285 msgid "Batch Rename" msgstr "批é‡é‡å‘½å" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "" #: f.file.cc:1290 msgid "new base name" msgstr "新基础åç§°" #: f.file.cc:1293 msgid "starting sequence" msgstr "开始顺åº" #: f.file.cc:1295 msgid "increment" msgstr "增é‡" #: f.file.cc:1316 msgid "select files to rename" msgstr "选择文件改å" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "基础åç§°/顺åº/å¢žé‡ ä¸å¯è¾¾æˆ" #: f.file.cc:1380 msgid "new file already exists:" msgstr "新文件已ç»å­˜åœ¨ï¼š" #: f.file.cc:1388 msgid "filespec too long:" msgstr "文件特性太长:" #: f.file.cc:1399 msgid "Rename failed:" msgstr "é‡å‘½å失败:" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "" #: f.file.cc:1662 msgid "menu name" msgstr "" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "修改标签" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "图片日期(年月日──yyyymmdd)" #: f.info.cc:165 msgid "use last" msgstr "最åŽä½¿ç”¨" #: f.info.cc:168 msgid "image stars" msgstr "图åƒç‚¹" #: f.info.cc:186 msgid "current tags" msgstr "当剿 ‡ç­¾" #: f.info.cc:191 msgid "recent tags" msgstr "最近的标签" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "定义的标签" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "" #: f.info.cc:348 msgid "category" msgstr "分类" #: f.info.cc:351 msgid "tag" msgstr "标签" #: f.info.cc:354 msgid "create" msgstr "创造" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "删除" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "æ‰¹é‡æ·»åŠ æ ‡ç­¾" #: f.info.cc:1354 msgid "tags to add" msgstr "è¦æ·»åŠ çš„æ ‡ç­¾" #: f.info.cc:1359 msgid "create tag" msgstr "创建标签" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " 太多标签" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "批é‡åˆ é™¤æ ‡ç­¾" #: f.info.cc:1556 msgid "tag to remove" msgstr "å°†è¦ç§»é™¤çš„æ ‡ç­¾" #: f.info.cc:1560 msgid "optional replacement" msgstr "å¯é€‰çš„æ›¿ä»£" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "" #: f.info.cc:1568 msgid "search all files" msgstr "æœç´¢å…¨éƒ¨æ–‡ä»¶" #: f.info.cc:1653 msgid "no files selected" msgstr "" #: f.info.cc:1659 msgid "no tag specified" msgstr "" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "" #: f.info.cc:1821 msgid "View Info" msgstr "" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "全部" #: f.info.cc:1990 msgid "One Key:" msgstr "一键:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "" #: f.info.cc:2350 msgid "date range" msgstr "日期范围" #: f.info.cc:2351 msgid "stars range" msgstr "点范围" #: f.info.cc:2352 msgid "search tags" msgstr "æœç´¢æ ‡ç­¾" #: f.info.cc:2353 msgid "search text" msgstr "" #: f.info.cc:2354 msgid "file names" msgstr "" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "" #: f.info.cc:2365 msgid "all/any" msgstr "" #: f.info.cc:2702 msgid "No matching images found" msgstr "未找到对应图片" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "放大" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "æå‡ç¼©ç•¥å›¾å°ºå¯¸" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "å‡å°ç¼©ç•¥å›¾å°ºå¯¸" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "缩å°" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "上级" #: f.navi.cc:190 msgid "parent directory" msgstr "上级目录" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "第一页" #: f.navi.cc:191 msgid "jump to first file" msgstr "跳至第一个文件" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "å‰ä¸€é¡µ" #: f.navi.cc:192 msgid "previous page" msgstr "å‰ä¸€é¡µ" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "å‰ä¸€è¡Œ" #: f.navi.cc:193 msgid "previous row" msgstr "å‰ä¸€è¡Œ" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "下一行" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "下一页" #: f.navi.cc:195 msgid "ttip::next page" msgstr "" #: f.navi.cc:196 msgid "jump to last file" msgstr "跳至最åŽä¸€ä¸ªæ–‡ä»¶" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "上一页" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "关闭" #: f.navi.cc:197 msgid "close image gallery" msgstr "å…³é—­å›¾åƒæµè§ˆ" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "选择文件" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "å–æ¶ˆ" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "完æˆ" #: f.navi.cc:1422 msgid "insert" msgstr "æ’å…¥" #: f.navi.cc:1423 msgid "add all" msgstr "添加全部" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "调节亮度和色彩" #: f.retouch.cc:110 msgid "small-steps" msgstr "" #: f.retouch.cc:119 msgid "color saturation" msgstr "色彩饱和度" #: f.retouch.cc:126 msgid " reset 1 " msgstr " é‡ç½® 1" #: f.retouch.cc:127 msgid "reset all" msgstr "全部é‡ç½®" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "扩展亮度范围" #: f.retouch.cc:887 msgid "bright pixels" msgstr "亮度åƒç´ " #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "使亮度平å‡åˆ†å¸ƒ" #: f.retouch.cc:1072 msgid "Flatten" msgstr "白平衡" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "全图光谱亮度" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "色调映射" #: f.retouch.cc:1758 msgid "low" msgstr "" #: f.retouch.cc:1760 msgid "high" msgstr "" #: f.retouch.cc:1763 msgid "Amplify" msgstr "" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "自动白平衡" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "点击白色或ç°è‰²å›¾åƒä½ç½®" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "打开" #: f.retouch.cc:2310 msgid "image for source color" msgstr "" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "红" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "绿" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "è“色" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "" #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "" #: f.retouch.cc:3084 msgid "Metric:" msgstr "" #: f.retouch.cc:3139 msgid "Blend" msgstr "" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "方法一:\n" " é¼ æ ‡å·¦é”®ç‚¹å‡»çº¢çœ¼ä½¿å…¶å˜æš—。\n" "方法二:\n" " 拖动包围红眼。\n" " é¼ æ ‡å·¦é”®ç‚¹å‡»çº¢çœ¼ä½¿å…¶å˜æš—。\n" "å–æ¶ˆï¼š\n" " é¼ æ ‡å³é”®ç‚¹å‡»ã€‚" #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "红眼å‡å¼±" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "设置模糊åŠå¾„" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "é”化图片" #: f.retouch.cc:4202 msgid "edge detection" msgstr "边缘探测" #: f.retouch.cc:4203 msgid "cycles" msgstr "周期" #: f.retouch.cc:4204 msgid "reduce" msgstr "å‡å°" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "模糊" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "亮度æ¸å˜" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " 按下“å‡å°‘â€æŒ‰é’® \n" " æ¥å‡å°‘噪点。 \n" " 按下“é‡ç½®â€é‡æ–°å¼€å§‹" #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "é™å™ª" #: f.retouch.cc:4650 msgid "algorithm" msgstr "算法" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "便®è‰²å½©(1) 平滑外部" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "便®è‰²å½©(2) 平滑外部" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "通过色彩设置居中亮度" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "根基色彩进行 Top Hat 滤波" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "åŠå¾„" #: f.retouch.cc:5005 msgid "Blur" msgstr "" #: f.retouch.cc:5008 msgid "New Area" msgstr "" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "" #: f.retouch.cc:5989 msgid "pixel group" msgstr "" #: f.retouch.cc:5990 msgid "circle color" msgstr "" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "" #: f.retouch.cc:6164 msgid "file format error" msgstr "" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "å–æ¶ˆè®°å¿† %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "绘画" #: f.retouch.cc:6695 msgid "pick" msgstr "抓å–" #: f.retouch.cc:6697 msgid "erase" msgstr "擦除" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "刷å­åŠå¾„" #: f.retouch.cc:6706 msgid "transparency center" msgstr "逿˜Žä¸­å¿ƒ" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "逿˜Žè¾¹ç¼˜" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "â€œå–æ¶ˆâ€çš„内存é™åˆ¶ï¼ˆ100MB)已ç»ç”¨å°½ã€‚\n" "按下[完æˆ]ä¿å­˜ï¼Œç„¶åŽç»§ç»­ç¼–辑。" #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "选择编辑区域" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "" #: f.select.cc:110 msgid "draw: freehand" msgstr "绘制:绘画" #: f.select.cc:111 msgid "draw: follow edge" msgstr "绘制:紧éšè¾¹ç¼˜" #: f.select.cc:114 msgid "select by mouse" msgstr "" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "" #: f.select.cc:120 msgid "match mouse color" msgstr "" #: f.select.cc:124 msgid "search range" msgstr "" #: f.select.cc:126 msgid "firewall" msgstr "" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "超出 %d 编辑" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" #: f.select.cc:1078 msgid "finish area" msgstr "结æŸåŒºåŸŸ" #: f.select.cc:1113 msgid "searching" msgstr "æœç´¢ä¸­" #: f.select.cc:1185 msgid "outline has a gap" msgstr "" #: f.select.cc:1189 msgid "success" msgstr "æˆåŠŸ" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "此区域未完æˆ" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "正在进行边缘计算" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "区域边缘计算" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "" #: f.select.cc:1887 msgid "Paste Image" msgstr "粘贴图åƒ" #: f.select.cc:1901 msgid "angle" msgstr "" #: f.select.cc:2160 msgid "load select area from a file" msgstr "读å–一个文件的选定区域" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "" #: f.select.cc:2213 msgid "save select area to a file" msgstr "" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "" #: f.select.cc:2501 msgid "edge" msgstr "" #: f.select.cc:2504 msgid "reset area" msgstr "" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "" #: f.tools.cc:85 msgid "Start new collection" msgstr "" #: f.tools.cc:87 msgid "Edit a collection" msgstr "" #: f.tools.cc:89 msgid "View a collection" msgstr "" #: f.tools.cc:91 msgid "Delete a collection" msgstr "" #: f.tools.cc:95 msgid "Editing:" msgstr "" #: f.tools.cc:99 msgid "Action:" msgstr "" #: f.tools.cc:133 msgid "New Collection" msgstr "" #: f.tools.cc:156 msgid "Edit Collection" msgstr "" #: f.tools.cc:172 msgid "View Collection" msgstr "" #: f.tools.cc:193 msgid "Delete Collection" msgstr "" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "" #: f.tools.cc:256 msgid "add image to collection" msgstr "" #: f.tools.cc:301 msgid "too many saved files" msgstr "" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "" #: f.tools.cc:375 msgid "old top directory" msgstr "" #: f.tools.cc:378 msgid "new top directory" msgstr "" #: f.tools.cc:434 msgid "completed" msgstr "已完æˆ" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "" #: f.tools.cc:474 msgid "new max. width" msgstr "新最大宽度" #: f.tools.cc:481 msgid "new file type" msgstr "" #: f.tools.cc:482 msgid "same" msgstr "" #: f.tools.cc:490 msgid "replace originals" msgstr "å–代原有的" #: f.tools.cc:491 msgid "export to location" msgstr "导出到" #: f.tools.cc:492 msgid "remove EXIF" msgstr "" #: f.tools.cc:549 msgid "Select directory" msgstr "选择路径" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "å–代原有文件? (max. %d x %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "å¤åˆ¶æ–‡ä»¶ï¼Ÿ(最多 %d x %d) \n" " 到 %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "ä¸å¯è¯†åˆ«çš„ä½ç½®" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "最大尺寸 %d x %d ä¸å¯èƒ½" #: f.tools.cc:654 msgid "*** file already exists" msgstr "" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "需è¦ç¨‹åº ufraw-batch" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "打开原始文件(RAW文件)" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "选择è¦è½¬åŒ–çš„RAW文件" #: f.tools.cc:769 msgid "Choose file type" msgstr "" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "" #: f.tools.cc:893 msgid "arrow keys" msgstr "" #: f.tools.cc:894 msgid "instant" msgstr "" #: f.tools.cc:895 msgid "fade-in" msgstr "" #: f.tools.cc:896 msgid "roll-right" msgstr "" #: f.tools.cc:897 msgid "roll-down" msgstr "" #: f.tools.cc:898 msgid "shift-left" msgstr "" #: f.tools.cc:899 msgid "venetian" msgstr "" #: f.tools.cc:900 msgid "grate" msgstr "" #: f.tools.cc:903 msgid "radar" msgstr "" #: f.tools.cc:904 msgid "jaws" msgstr "" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "演示" #: f.tools.cc:915 msgid "seconds" msgstr "ç§’" #: f.tools.cc:919 msgid "music file" msgstr "" #: f.tools.cc:923 msgid "transitions" msgstr "" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "" #: f.tools.cc:1844 msgid "no new files found" msgstr "" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "顶部图åƒè·¯å¾„:" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "选择顶部图åƒä½ç½®" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "显示RGB" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "网格线" #: f.tools.cc:2728 msgid "x-spacing" msgstr "" #: f.tools.cc:2729 msgid "x-count" msgstr "" #: f.tools.cc:2730 msgid "x-enable" msgstr "" #: f.tools.cc:2736 msgid "y-spacing" msgstr "" #: f.tools.cc:2737 msgid "y-count" msgstr "" #: f.tools.cc:2738 msgid "y-enable" msgstr "" #: f.tools.cc:2745 msgid "x-offset" msgstr "" #: f.tools.cc:2749 msgid "y-offset" msgstr "" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "" #: f.tools.cc:2947 msgid "max. width" msgstr "" #: f.tools.cc:2948 msgid "max. height" msgstr "" #: f.tools.cc:3093 msgid "too many files" msgstr "" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" #: f.tools.cc:3174 msgid "Monitor Check" msgstr "" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "亮度分布" #: f.tools.cc:3432 msgid "Available Translations" msgstr "å¯ç”¨ç¿»è¯‘" #: f.tools.cc:3436 msgid "Set Language" msgstr "设置语言" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "使用按钮或者鼠标拖到å³é¢è¾¹ç¼˜" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "旋转图åƒ" #: f.transform.cc:64 msgid "degrees" msgstr "角度" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "剪è£" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "" #: f.transform.cc:123 msgid "Undo Trim" msgstr "å–æ¶ˆå‰ªåˆ‡" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "角度: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "æ‹–åŠ¨ä¸­éƒ¨ç§»åŠ¨ï¼Œæ‹–åŠ¨è§’è½æ”¹å˜å°ºå¯¸ã€‚" #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "剪è£å›¾åƒ" #: f.transform.cc:348 msgid "customize" msgstr "" #: f.transform.cc:359 msgid "ratio" msgstr "" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "固定比例" #: f.transform.cc:368 msgid "invert" msgstr "å色" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "é”定长宽比例" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "改å˜å°ºå¯¸" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "上一张" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "" #: f.transform.cc:1307 msgid "Size" msgstr "尺寸" #: f.transform.cc:1310 msgid "Angle" msgstr "" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "颜色" #: f.transform.cc:1322 msgid "Transparency" msgstr "" #: f.transform.cc:1325 msgid "text" msgstr "" #: f.transform.cc:1330 msgid "backing" msgstr "" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" #: f.transform.cc:1335 msgid "outline" msgstr "" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "" #: f.transform.cc:1416 msgid "select font" msgstr "" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "翻转图åƒ" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "æ°´å¹³" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "垂直" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "å色" #: f.transform.cc:2158 msgid "black/white positive" msgstr "" #: f.transform.cc:2159 msgid "black/white negative" msgstr "" #: f.transform.cc:2160 msgid "color positive" msgstr "" #: f.transform.cc:2161 msgid "color negative" msgstr "" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "拉伸图åƒ" #: f.transform.cc:2282 msgid "linear" msgstr "" #: f.transform.cc:2285 msgid "curved" msgstr "" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" " 鼠标左键在图åƒä¸€è¾¹æŒ‰ä¸‹æ‰­æ›²å›¾åƒ \n" " çŸ¥é“æ»¡æ„ \n" " è¦ç»“æŸï¼ŒæŒ‰ä¸‹[完æˆ]" #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "" #: f.transform.cc:2864 msgid "start warp" msgstr "开始扭曲" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " 鼠标左键在图åƒä¸€è¾¹æŒ‰ä¸‹æ‰­æ›²å›¾åƒ \n" " çŸ¥é“æ»¡æ„ \n" " è¦ç»“æŸï¼ŒæŒ‰ä¸‹[完æˆ]" #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "扭曲图åƒ(affine)" #: fotoxx-12.01.cc:185 msgid "File" msgstr "文件" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "å›¾åƒæµè§ˆ" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "打开å‰ä¸€ä¸ªæ–‡ä»¶" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "打开最近的文件" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "ä¿å­˜åˆ°åŽŸæ–‡ä»¶" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "ä¿å­˜åˆ°æ–°æ–‡ä»¶" #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "丢入å¯å›žæ”¶æ–‡ä»¶å¤¹" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "批é‡é‡å‘½å文件" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "打å°å›¾åƒæ–‡ä»¶" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "退出 fotoxx" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "工具" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "转化RAW文件" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "刻录图片到CD/DVD" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "检查显示器" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "改å˜è¯­è¨€" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "选择" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "显示" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "éšè—" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "å¼€å¯" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "ç¦æ­¢" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "å色" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "å¤åˆ¶" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "粘贴" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "ä¿å­˜" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "å˜å½¢" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "修正" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "调节亮度和色彩" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "扩展亮度" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "白平衡" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "亮度光谱" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "白平衡" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "红眼" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "模糊图åƒ" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "å‡å°‘噪点" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "艺术" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "色深" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "接åˆ" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "全景" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "帮助" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "关于" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "用户指å—" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "å˜åЍ" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "主页" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "æµè§ˆ" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "下一张" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "打开下一个文件" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "拉近 (更大)" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "拉远 (更å°ï¼‰" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "å–æ¶ˆ" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "å–æ¶ˆä¸€æ¬¡ç¼–辑" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "é‡å¤" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "é‡å¤ä¸€æ¬¡ç¼–辑" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "移动图片到å¯å›žæ”¶æ–‡ä»¶å¤¹" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "å¯å›žæ”¶æ–‡ä»¶å¤¹" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "退出" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "Fotoxx基础" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "超出了 50 个锚点" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "exiftool未安装 \n" "修改图片会丢失EXIFæ•°æ®" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "编辑太多了,请ä¿å­˜å›¾ç‰‡" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "选择区域无法ä¿ç•™ã€‚\n" "ç»§ç»­å—?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" "é€‰æ‹©éžæ´»åŠ¨åŒºåŸŸã€‚\n" "继续?" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "无法打开缩略图" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "TIFFå¼€å¯å¤±è´¥" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF 色深(bits/color)=%d 䏿”¯æŒ" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "TIFF读å–失败" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "TIFF写错误" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "æ–‡ä»¶ç±»åž‹ä¸æ”¯æŒ" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "pixbuf 写入错误" #: fotoxx.h:728 msgid "absolute" msgstr "" #: fotoxx.h:730 msgid "Add All" msgstr "添加全部" #: fotoxx.h:732 msgid "Amount" msgstr "总数" #: fotoxx.h:733 msgid "Apply" msgstr "应用" #: fotoxx.h:734 msgid "Black" msgstr "" #: fotoxx.h:735 msgid "Blend Width" msgstr "æ··åˆå®½åº¦" #: fotoxx.h:737 msgid "Brightness" msgstr "亮度" #: fotoxx.h:738 msgid "Browse" msgstr "æµè§ˆ" #: fotoxx.h:739 msgid "Cancel" msgstr "å–æ¶ˆ" #: fotoxx.h:740 msgid "Clear" msgstr "清除" #: fotoxx.h:742 msgid "Commit" msgstr "" #: fotoxx.h:744 msgid "Curve File:" msgstr "" #: fotoxx.h:745 msgid "Cut" msgstr "" #: fotoxx.h:746 msgid "Darker Areas" msgstr "较暗区域" #: fotoxx.h:747 msgid "Delete" msgstr "删除" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" #: fotoxx.h:750 msgid "Done" msgstr "完æˆ" #: fotoxx.h:751 msgid "Edit" msgstr "修改" #: fotoxx.h:753 msgid "Erase" msgstr "" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "需è¦è½¯ä»¶åŒ… libimage-exiftool-perl " #: fotoxx.h:755 msgid "Fetch" msgstr "获å–" #: fotoxx.h:756 msgid "Finish" msgstr "完æˆ" #: fotoxx.h:757 msgid "Font" msgstr "" #: fotoxx.h:759 msgid "Height" msgstr "高度" #: fotoxx.h:760 msgid "histogram" msgstr "柱状图" #: fotoxx.h:762 msgid "Insert" msgstr "æ’å…¥" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "较亮区域" #: fotoxx.h:765 msgid "limit" msgstr "é™åˆ¶" #: fotoxx.h:766 msgid "New" msgstr "" #: fotoxx.h:768 msgid "OK" msgstr "确定" #: fotoxx.h:772 msgid "Pause" msgstr "æš‚åœ" #: fotoxx.h:773 msgid "Percent" msgstr "比例" #: fotoxx.h:774 msgid "Presets" msgstr "预设" #: fotoxx.h:775 msgid "Proceed" msgstr "进行" #: fotoxx.h:777 msgid "range" msgstr "范围" #: fotoxx.h:780 msgid "Reduce" msgstr "å‡å°" #: fotoxx.h:782 msgid "Reset" msgstr "" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "未知文件类型,ä¿å­˜ä¸º tiff/jpeg/png 编辑" #: fotoxx.h:785 msgid "Search" msgstr "æœç´¢" #: fotoxx.h:789 msgid "Start" msgstr "开始" #: fotoxx.h:790 msgid "Threshold" msgstr "门槛" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "å–æ¶ˆå…¨éƒ¨" #: fotoxx.h:793 msgid "Undo Last" msgstr "å–æ¶ˆä¸Šä¸€ä¸ª" #: fotoxx.h:795 msgid "Unfinish" msgstr "" #: fotoxx.h:797 msgid "View" msgstr "" #: fotoxx.h:798 msgid "White" msgstr "" #: fotoxx.h:799 msgid "Width" msgstr "宽度" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "没找到帮助文件: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "ä¸èƒ½æ‰“开文件 %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "ä¿å­˜å±å¹•到文件" #: zfuncs.cc:6222 msgid "No" msgstr "æ— " #: zfuncs.cc:6222 msgid "Yes" msgstr "是" #: zfuncs.cc:6447 msgid "open" msgstr "打开" #: zfuncs.cc:6452 msgid "choose" msgstr "选择\t" #: zfuncs.cc:6457 msgid "save" msgstr "ä¿å­˜" #: zfuncs.cc:6463 msgid "open folder" msgstr "打开文件夹" #: zfuncs.cc:6468 msgid "create folder" msgstr "创造文件夹" #: zfuncs.cc:6474 msgid "hidden" msgstr "éšè—çš„" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "JPG è´¨é‡ 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "" #: zfuncs.cc:6737 msgid "top" msgstr "" #: zfuncs.cc:6738 msgid "bottom" msgstr "" #: zfuncs.cc:6739 msgid "left" msgstr "" #: zfuncs.cc:6740 msgid "right" msgstr "" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "åˆå§‹åŒ–傿•°æ–‡ä»¶ã€‚ \n" "如必è¦ï¼Œè¯·æ£€æŸ¥ã€‚" #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "从一个文件读å–傿•°" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "ä¿å­˜å‚数到文件" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "ä¿®æ”¹å‚æ•°" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "列表\n" "全部" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "读å–\n" "文件" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "ä¿å­˜\n" "文件" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "添加\n" "æ–°" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "应用" #: zfuncs.cc:7479 msgid "apply?" msgstr "应用?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(æ–°å‚æ•°å)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "æ·»åŠ å‚æ•°" #~ msgid "Brightness Graph" #~ msgstr "亮度分布图" #~ msgid "radius" #~ msgstr "åŠå¾„" #~ msgid "match" #~ msgstr "对应" #~ msgid "Search results file error %s" #~ msgstr "æœç´¢ç»“果文件错误 %s" #~ msgid "Batch Resize" #~ msgstr "æ‰¹é‡æ”¹å˜å°ºå¯¸" #~ msgid "new max. height" #~ msgstr "新最大高度" #~ msgid "copy EXIF" #~ msgstr "å¤åˆ¶EXIF" #~ msgid "new file already exists" #~ msgstr "新文件已ç»å­˜åœ¨" #~ msgid "Select area first" #~ msgstr "首先选择区域" #~ msgid "close thumbnail window" #~ msgstr "关闭缩略图窗å£" #~ msgid "file" #~ msgstr "文件" #~ msgid "folder" #~ msgstr "文件夹" #~ msgid "jump to specific file" #~ msgstr "跳至指定文件" #, fuzzy #~ msgid "open a directory" #~ msgstr "跳至新目录" #~ msgid "select new folder" #~ msgstr "选择新文件夹" #~ msgid "xdg-utils package not installed" #~ msgstr "xdg-utils软件包没有安装" #~ msgid "open a file" #~ msgstr "打开一个文件" #~ msgid "paper format is crazy" #~ msgstr "疯狂的纸张格å¼" #~ msgid "landscape" #~ msgstr "æ°´å¹³" #~ msgid "portrait" #~ msgstr "垂直" #~ msgid "paper format" #~ msgstr "纸张格å¼" #~ msgid "printer ID" #~ msgstr "æ‰“å°æœºID" #~ msgid "print" #~ msgstr "打å°" #~ msgid "Time Interval" #~ msgstr "æ—¶é—´é—´éš”" #~ msgid "Clone fotoxx" #~ msgstr "å¤åˆ¶ä¸€ä¸ª fotoxx 窗å£" #~ msgid "Save As" #~ msgstr "ä¿å­˜ä¸º" #~ msgid "click on window to show RGB" #~ msgstr "ç‚¹å‡»çª—å£æ˜¾ç¤º RGB" #~ msgid "make new version" #~ msgstr "新版本" #~ msgid "Create Launcher" #~ msgstr "创建å¯åЍ噍" #~ msgid "" #~ "Search all areas for edge and inside pixels. \n" #~ "Click inside each enclosed area in sequence." #~ msgstr "" #~ "æœç´¢æ‰€æœ‰åŒºåŸŸè¾¹ç¼˜/和内部åƒç´ ã€‚\n" #~ "点击" #~ msgid "area outline has a hole" #~ msgstr "区域轮廓有一个洞" #~ msgid "Rebuild Thumbnails" #~ msgstr "é‡å»ºç¼©ç•¥å›¾" #~ msgid "horizontal unbend" #~ msgstr "水平拉伸" #~ msgid "press ESC to exit" #~ msgstr "按下ESC退出" #~ msgid "select by color:" #~ msgstr "æ ¹æ®è‰²å½©é€‰æ‹©" #~ msgid "select by mouse:" #~ msgstr "鼠标选择" #~ msgid "vertical unbend" #~ msgstr "垂直拉伸" #~ msgid "target group area" #~ msgstr "瞄准组区域" #~ msgid "Area" #~ msgstr "区域" #~ msgid "Constrain" #~ msgstr "强制" #~ msgid "Convert Tags !!!" #~ msgstr "è½¬æ¢æ ‡ç­¾ !!!" #~ msgid "Convert tags to new standard" #~ msgstr "将标签转化为新标准" #~ msgid "" #~ "Convert tags to new standard now? \n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "是å¦çŽ°åœ¨æŠŠæ ‡ç­¾è½¬åŒ–ä¸ºæ–°æ ‡å‡†ç±»åž‹ï¼Ÿ\n" #~ "您的图片已ç»å¤‡ä»½äº†å—?" #~ msgid "HDF" #~ msgstr "HDF" #~ msgid "HDR" #~ msgstr "HDR" #~ msgid "" #~ "New tags file already exists! \n" #~ "Proceed anyway?" #~ msgstr "" #~ "新标签文件已ç»å­˜åœ¨ï¼\n" #~ "ä»ç„¶ç»§ç»­å—?" #~ msgid "No tags index file" #~ msgstr "无标签索引文件" #~ msgid "Rebuild Tags Index" #~ msgstr "é‡å»ºæ ‡ç­¾ç´¢å¼•" #~ msgid "Stack" #~ msgstr "堆放" #~ msgid "Use F1 for context help" #~ msgstr "F1唤出帮助" #~ msgid "brightness to clip (percent)" #~ msgstr "亮度剪切(比例)" #~ msgid "cannot read .dist file" #~ msgstr "æ— æ³•è¯»å– .dist 文件" #~ msgid "manage tags" #~ msgstr "ç®¡ç†æ ‡ç­¾" #~ msgid "new tags index will now be created" #~ msgstr "将创建新的标签索引" #~ msgid "save select area as a file" #~ msgstr "选定区域ä¿å­˜ä¸ºæ–‡ä»¶" #~ msgid "tags index file error: %s" #~ msgstr "标签索引错误:%s" #~ msgid "/path*/file*" #~ msgstr "/path*/file*" #~ msgid "All EXIF data" #~ msgstr "全部Exifæ•°æ®" #~ msgid "Basic EXIF data" #~ msgstr "基本Exifæ•°æ®" #~ msgid "Delete EXIF data" #~ msgstr "删除 Exif æ•°æ®" #~ msgid "EXIF data" #~ msgstr "Exif æ•°æ®\t" #~ msgid "Edit EXIF data" #~ msgstr "修改 Exif æ•°æ®" #~ msgid "Resume" #~ msgstr "ç»§ç»­" #~ msgid "Search Tags" #~ msgstr "æœç´¢æ ‡ç­¾" #~ msgid "Set Tile and Gap Size" #~ msgstr "设置图å—和间è·å°ºå¯¸" #~ msgid "Suspend" #~ msgstr "æš‚åœ" #~ msgid "Tags" #~ msgstr "标签" #~ msgid "match all tags" #~ msgstr "对应全部标签" #~ msgid "match any tag" #~ msgstr "适åˆä»»æ„标签" #~ msgid "" #~ " Pull on an image edge using the mouse. \n" #~ " Make multiple mouse pulls until satisfied. \n" #~ " When finished, press [done]." #~ msgstr "" #~ " 鼠标左键在图åƒä¸€è¾¹æŒ‰ä¸‹æ‰­æ›²å›¾åƒ \n" #~ " çŸ¥é“æ»¡æ„ \n" #~ " è¦ç»“æŸï¼ŒæŒ‰ä¸‹[完æˆ]" #~ msgid "Open File" #~ msgstr "打开文件" #~ msgid "Warp Area" #~ msgstr "选定区域扭曲" #~ msgid "Warp Image" #~ msgstr "扭曲图åƒ" #~ msgid "Warp Image (curvy)" #~ msgstr "扭曲图åƒ(曲线)" #~ msgid "Warp Image in Selected Area" #~ msgstr "扭曲选中区域的图åƒ" #~ msgid "" #~ "position image\n" #~ "with mouse drag" #~ msgstr "" #~ "使用鼠标拖拽\n" #~ "确定图åƒä½ç½®" #~ msgid "Burn" #~ msgstr "刻录" #~ msgid "Fix Image Perspective" #~ msgstr "ä¿®å¤å›¾åƒé€è§†" #~ msgid "Read File" #~ msgstr "è¯»å–æ–‡ä»¶" #~ msgid "add tags" #~ msgstr "添加标签" #~ msgid "color intensity" #~ msgstr "色彩亮度" #~ msgid "color range" #~ msgstr "色彩范围" #~ msgid "freehand draw" #~ msgstr "自由绘画" #~ msgid "rename files" #~ msgstr "é‡å‘½å文件" #~ msgid "select image files to add tags" #~ msgstr "é€‰æ‹©è¦æ·»åŠ æ ‡ç­¾çš„æ–‡ä»¶" #~ msgid "" #~ "\n" #~ " Match Brightness and Color" #~ msgstr "" #~ "\n" #~ " 对应亮度和颜色" #~ msgid "Auto" #~ msgstr "自动" #~ msgid "" #~ "Drag right image into rough alignment with left \n" #~ " to rotate, drag right edge up or down" #~ msgstr "" #~ "æ‹–å³é¢çš„图片与左é¢çš„æˆä¸€æ¡çº¿\n" #~ "进行翻转,货到有边缘上部或下部" #~ msgid "Match Images" #~ msgstr "对应图åƒ" #~ msgid "Merge the images together" #~ msgstr "图片èžåˆåœ¨ä¸€èµ·" #~ msgid "Package ufraw required for this function" #~ msgstr "æ­¤åŠŸèƒ½éœ€è¦ ufraw 包" #~ msgid "Retouch Image" #~ msgstr "修饰图åƒ" #~ msgid "Current file must be included" #~ msgstr "å¿…é¡»åŒ…æ‹¬å½“å‰æ–‡ä»¶" #~ msgid "jpeg quality" #~ msgstr "jpeg è´¨é‡" #~ msgid "" #~ "\n" #~ " brightness \n" #~ " level" #~ msgstr "" #~ "\n" #~ " 亮度 \n" #~ " 级别" #~ msgid " color balance blue " #~ msgstr " 色彩平衡 è“" #~ msgid " color balance green " #~ msgstr " 色彩平衡 绿" #~ msgid "" #~ "%s \n" #~ " tag limit exceeded" #~ msgstr "" #~ "%s \n" #~ " 标签é™åˆ¶çªç ´" #~ msgid "2nd image not same size as 1st image" #~ msgstr "第二图åƒå’Œç¬¬ä¸€å›¾åƒå¤§å°ä¸åŒ" #~ msgid "Add or Remove Grid Lines" #~ msgstr "添加或者移除网格线" #~ msgid "Bend" #~ msgstr "扭曲" #, fuzzy #~ msgid "Blend Area Edges" #~ msgstr "åŠå¾„模糊" #~ msgid "Build Tags Index" #~ msgstr "建立标签索引" #~ msgid "Clear Select Area" #~ msgstr "清除选定区域" #~ msgid "Composite Images" #~ msgstr "åˆæˆå›¾åƒ" #~ msgid "Convert multiple RAWs" #~ msgstr "转化多个RAW文件" #~ msgid "" #~ "Convert raw file to 48-bit tiff format? \n" #~ " (this may take a while) " #~ msgstr "" #~ "转æ¢raw文件到48-bit tiffæ ¼å¼ï¼Ÿ\n" #~ " (这å¯èƒ½éœ€è¦è¾ƒé•¿ä¸€æ®µæ—¶é—´ï¼‰ " #, fuzzy #~ msgid "Delete Area" #~ msgstr "选择区域" #~ msgid "Dimensions" #~ msgstr "整体" #~ msgid "Distortion" #~ msgstr "å˜å½¢" #, fuzzy #~ msgid "" #~ "Drag and click to enclose an area.\n" #~ "Use right click to undo prior." #~ msgstr "" #~ "用鼠标拖拽点击一个区域。\n" #~ "é¼ æ ‡å³é”®ç‚¹å‡»å–消上一次" #~ msgid "" #~ "Drag middle to move \n" #~ "Drag corners to resize" #~ msgstr "" #~ "拖拽中部移动\n" #~ "æ‹–æ‹½è§’è½æ”¹å˜å°ºå¯¸" #~ msgid "Error Log" #~ msgstr "错误记录" #~ msgid "FREEIMAGE error: %s" #~ msgstr "FREEIMAGE 错误: %s" #~ msgid "FREEIMAGE unknown error" #~ msgstr "FREEIMAGE 未知错误" #, fuzzy #~ msgid "Flash" #~ msgstr "回收站" #, fuzzy #~ msgid "HDR Image Weights" #~ msgstr "HDR高度" #, fuzzy #~ msgid "Hide Area" #~ msgstr "选择区域" #, fuzzy #~ msgid "Image Weights per Brightness Level" #~ msgstr "" #~ "\n" #~ " æ¯ä¸ªäº®åº¦çº§åˆ«å›¾åƒå®½åº¦ \n" #~ msgid "Index" #~ msgstr "索引" #~ msgid "Index (thumbnails)" #~ msgstr "索引(缩略图)" #~ msgid "Index Tags" #~ msgstr "索引标签" #~ msgid "Index Tags and Thumbs" #~ msgstr "索引标签和缩略图" #, fuzzy #~ msgid "Input Images" #~ msgstr "输出图åƒ" #, fuzzy #~ msgid "Invert Area" #~ msgstr "å色" #~ msgid "Make HDF Image" #~ msgstr "制作HDF图åƒ(高动æ€èŒƒå›´æˆåƒ)" #~ msgid "Make HDR Image" #~ msgstr "制作HDR图åƒ(高动æ€èŒƒå›´æˆåƒ)" #, fuzzy #~ msgid "Output Image" #~ msgstr "输出图åƒ" #~ msgid "Paint Pixels" #~ msgstr "绘制åƒç´ " #~ msgid "Print" #~ msgstr "打å°" #~ msgid "RAW file template" #~ msgstr "RAW文件模æ¿" #~ msgid "README" #~ msgstr "介ç»" #~ msgid "Rotate" #~ msgstr "旋转" #~ msgid "Save Image as File" #~ msgstr "ä¿å­˜å›¾åƒæ–‡ä»¶åˆ°" #~ msgid "Sharp" #~ msgstr "é”化" #, fuzzy #~ msgid "Show Area" #~ msgstr "区域" #~ msgid "Simulate embossing" #~ msgstr "模拟浮雕效果" #~ msgid "Special Art Effects" #~ msgstr "艺术效果" #~ msgid "Thumbnail Index" #~ msgstr "缩略图索引一个ä½ç½®" #, fuzzy #~ msgid "Too many points" #~ msgstr "太多点" #~ msgid "Too many tags: %d" #~ msgstr "太多标签:%d" #~ msgid "Total tags exceed %d characters" #~ msgstr "全部标签超出 %d 字符。" #~ msgid "Tune Image" #~ msgstr "色彩调节" #, fuzzy #~ msgid "Unable to replace file" #~ msgstr "无法ä¿å­˜å›¾åƒ" #~ msgid "Warp Global" #~ msgstr "全局扭曲" #~ msgid "Zoom+" #~ msgstr "放大" #~ msgid "Zoom-" #~ msgstr "缩å°" #~ msgid "assigned tags" #~ msgstr "指定的标签" #~ msgid "blend" #~ msgstr "色带" #~ msgid "blur radius" #~ msgstr "åŠå¾„模糊" #~ msgid "" #~ "cannot create %s \n" #~ " %s" #~ msgstr "" #~ "无法创建 %s \n" #~ " %s" #~ msgid "click or drag trim margins" #~ msgstr "点击或者拖动剪è£ç•Œé™" #~ msgid "color balance" #~ msgstr "色彩平衡 " #~ msgid "computing" #~ msgstr "计算中" #~ msgid "exceed 100 anchor points" #~ msgstr "超出100个轴心点" #~ msgid "exiftool is required to create tags" #~ msgstr "需è¦exiftool创建标签" #~ msgid "exiftool is required to generate tags index" #~ msgstr "exiftool æ˜¯ç”Ÿæˆæ ‡ç­¾ç´¢å¼•必备的" #~ msgid "grid spacing" #~ msgstr "网格空间" #~ msgid "image format error: %s" #~ msgstr "å›¾åƒæ ¼å¼é”™è¯¯ï¼š %s" #~ msgid "image not 8 or 16 bits/color: %s" #~ msgstr "图åƒä¸æ˜¯8使ˆ–16ä½è‰²çš„: %s" #~ msgid "open RAW file" #~ msgstr "打开RAW文件" #~ msgid "open image file" #~ msgstr "æ‰“å¼€å›¾åƒæ–‡ä»¶" #~ msgid "quit" #~ msgstr "退出" #, fuzzy #~ msgid "radius limit" #~ msgstr "åŠå¾„" #~ msgid "recently added" #~ msgstr "最近添加" #~ msgid "red" #~ msgstr "红" #~ msgid "redo image changes" #~ msgstr "é‡å¤å›¾åƒæ”¹å˜" #~ msgid "resize image" #~ msgstr "改å˜å›¾åƒå¤§å°" #~ msgid "rotate image" #~ msgstr "旋转图åƒ" #, fuzzy #~ msgid "set blend radius" #~ msgstr "设定模糊åŠå¾„" #~ msgid "sharpen image" #~ msgstr "é”化图åƒ" #~ msgid "tags exceed %d characters" #~ msgstr "标签超出 %d 个字符" #~ msgid "toolbar::save" #~ msgstr "工具æ ::ä¿å­˜" #~ msgid "trim image" #~ msgstr "剪切图åƒ" #~ msgid "unbend panorama image" #~ msgstr "æ¾å¼›å…¨æ™¯å›¾ç‰‡" #~ msgid "unknown image format" #~ msgstr "æœªçŸ¥å›¾åƒæ ¼å¼" #~ msgid "Discard modifications?" #~ msgstr "放弃改动?" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "é‡å‘½å失败\n" #~ " %s" #~ msgid "incremental" #~ msgstr "增é‡" #~ msgid "full rebuild" #~ msgstr "完整é‡å»º" #~ msgid "Translate" #~ msgstr "翻译" #~ msgid "select new file" #~ msgstr "选择新文件" #~ msgid "lens name" #~ msgstr "镜é¢åç§°" #~ msgid "Lens Parameters" #~ msgstr "é•œå¤´å‚æ•°" fotoxx-12.01.2/locales/fotoxx-gl.po0000664000175000017500000016202411701011017015551 0ustar micomico# Galician translations for home package. # Copyright (C) 2008 THE home'S COPYRIGHT HOLDER # This file is distributed under the same license as the home package. # mico , 2008. # msgid "" msgstr "" "Project-Id-Version: fotoxx-6.9.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:05+0100\n" "PO-Revision-Date: 2009-11-04 23:34+0100\n" "Last-Translator: Miguel Anxo Bouzada \n" "Language-Team: GALPon MiniNo \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Galician\n" "X-Poedit-Country: SPAIN\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr " Establecer a profundidade de cor 1-16 bits" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Axustar a profundidade da cor" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Semellar un debuxo" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "Contraste" #: f.art.cc:215 msgid "outlines" msgstr "Bordos" #: f.art.cc:220 msgid "pencil" msgstr "Lapis" #: f.art.cc:221 msgid "chalk" msgstr "Xiz" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "" #: f.art.cc:394 msgid "outline threshold" msgstr "" #: f.art.cc:397 msgid "outline width" msgstr "" #: f.art.cc:400 msgid "image brightness" msgstr "" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Semellar un repuxado" #: f.art.cc:626 msgid "depth" msgstr "Profundidade" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "Cor" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Semellar un mosaicos" #: f.art.cc:825 msgid "tile size" msgstr "Tamaño do mosaico" #: f.art.cc:829 msgid "tile gap" msgstr "Separación do mosaico" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "" #: f.art.cc:1007 msgid "dot size" msgstr "" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Semellar unha pintura" #: f.art.cc:1226 msgid "color depth" msgstr "Profundidade da cor" #: f.art.cc:1230 msgid "patch area goal" msgstr "" #: f.art.cc:1234 msgid "req. color match" msgstr "Correspondencia de cor requerida" #: f.art.cc:1238 msgid "borders" msgstr "Bordos" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "" #: f.comp.cc:2326 msgid "light pixels" msgstr "" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "Ficheiro:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "Pintar" #: f.comp.cc:2851 msgid "warp" msgstr "" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Pre-aliñar imaxes" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "Lonxitude focal (mm)" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "Curvatura da lente" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "" #: f.comp.cc:4457 msgid "use two images only" msgstr "" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Solapamento moi pequeno, non se pode aliñar" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Abrir ficheiro de imaxe" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "" #: f.file.cc:504 msgid "Do not warn again" msgstr "" #: f.file.cc:520 msgid "Warning" msgstr "" #: f.file.cc:643 msgid "Save File" msgstr "Gardar o ficheiro" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "" #: f.file.cc:668 msgid "make current" msgstr "" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Sobrescribir ficheiro? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "" #: f.file.cc:905 msgid "file name" msgstr "" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "Enviar o ficheiro de só lectura ao lixo?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "Non se pode crear o cesto do lixo: %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "erro: %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Renomear ficheiro de imaxe" #: f.file.cc:1141 msgid "old name" msgstr "Nome antigo" #: f.file.cc:1142 msgid "rename to" msgstr "Renomear como" #: f.file.cc:1143 msgid "previous" msgstr "Anterior" #: f.file.cc:1229 msgid "The target file already exists" msgstr "O ficheiro de destino xa existe" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" #: f.file.cc:1285 msgid "Batch Rename" msgstr "" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "" #: f.file.cc:1290 msgid "new base name" msgstr "" #: f.file.cc:1293 msgid "starting sequence" msgstr "" #: f.file.cc:1295 msgid "increment" msgstr "" #: f.file.cc:1316 msgid "select files to rename" msgstr "" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "" #: f.file.cc:1380 msgid "new file already exists:" msgstr "" #: f.file.cc:1388 msgid "filespec too long:" msgstr "" #: f.file.cc:1399 msgid "Rename failed:" msgstr "" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "" #: f.file.cc:1662 msgid "menu name" msgstr "" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Editar etiquetas" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "Data da imaxe (aaaammdd)" #: f.info.cc:165 msgid "use last" msgstr "Usar o último" #: f.info.cc:168 msgid "image stars" msgstr "Imaxe estrela" #: f.info.cc:186 msgid "current tags" msgstr "Etiquetas actuais" #: f.info.cc:191 msgid "recent tags" msgstr "" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "" #: f.info.cc:348 msgid "category" msgstr "" #: f.info.cc:351 msgid "tag" msgstr "" #: f.info.cc:354 msgid "create" msgstr "" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "Borrar" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "" #: f.info.cc:1354 msgid "tags to add" msgstr "" #: f.info.cc:1359 msgid "create tag" msgstr "Crear etiqueta" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "" #: f.info.cc:1556 msgid "tag to remove" msgstr "" #: f.info.cc:1560 msgid "optional replacement" msgstr "" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "" #: f.info.cc:1568 msgid "search all files" msgstr "" #: f.info.cc:1653 msgid "no files selected" msgstr "" #: f.info.cc:1659 msgid "no tag specified" msgstr "" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "" #: f.info.cc:1821 msgid "View Info" msgstr "" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "" #: f.info.cc:1990 msgid "One Key:" msgstr "" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "" #: f.info.cc:2350 msgid "date range" msgstr "Formato da data" #: f.info.cc:2351 msgid "stars range" msgstr "Rango de estrelas" #: f.info.cc:2352 msgid "search tags" msgstr "Buscar" #: f.info.cc:2353 msgid "search text" msgstr "" #: f.info.cc:2354 msgid "file names" msgstr "" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "" #: f.info.cc:2365 msgid "all/any" msgstr "" #: f.info.cc:2702 msgid "No matching images found" msgstr "Non se atoparon imaxes" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "Maior" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "Aumentar o tamaño da miniatura" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "Reducir tamaño da miniatura" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "Menor" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "" #: f.navi.cc:190 msgid "parent directory" msgstr "" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "Primeira páxina" #: f.navi.cc:191 msgid "jump to first file" msgstr "Cambiar ao primeiro ficheiro" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "Páxina anterior" #: f.navi.cc:192 msgid "previous page" msgstr "Páxina anterior" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "fila anterior" #: f.navi.cc:193 msgid "previous row" msgstr "Fila anterior" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "Seguinte fila" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "Páxina seguinte" #: f.navi.cc:195 msgid "ttip::next page" msgstr "" #: f.navi.cc:196 msgid "jump to last file" msgstr "Cambiar ao último ficheiro" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "Última páxina" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "Pechar" #: f.navi.cc:197 msgid "close image gallery" msgstr "Pechar a galería de imaxes" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "Cancelar" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "" #: f.navi.cc:1422 msgid "insert" msgstr "Inserir" #: f.navi.cc:1423 msgid "add all" msgstr "" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Axustar brillo e cor" #: f.retouch.cc:110 msgid "small-steps" msgstr "" #: f.retouch.cc:119 msgid "color saturation" msgstr "Saturación da cor" #: f.retouch.cc:126 msgid " reset 1 " msgstr " Restablecer 1" #: f.retouch.cc:127 msgid "reset all" msgstr "Restablecer todo" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "" #: f.retouch.cc:887 msgid "bright pixels" msgstr "" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Distribuir o brillo uniformemente" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Aplanar" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "" #: f.retouch.cc:1758 msgid "low" msgstr "" #: f.retouch.cc:1760 msgid "high" msgstr "" #: f.retouch.cc:1763 msgid "Amplify" msgstr "" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Axustar o balance de branco" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Faga clic na ubicación da imaxe en branco ou gris" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Abrir" #: f.retouch.cc:2310 msgid "image for source color" msgstr "" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Vermello" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Verde" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Azul" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "" #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "" #: f.retouch.cc:3084 msgid "Metric:" msgstr "" #: f.retouch.cc:3139 msgid "Blend" msgstr "" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Método 1:\n" " Clic-esquerdo no ollo vermello pra escurecer.\n" "Método 2:\n" " Pica e arrastra a dereita para delimitar o ollo vermello.\n" " Clic-esquerdo para escurecer o ollo vermello.\n" "Desfacer ollos vermellos:\n" " Clic-dereito no ollo vermello." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Redución de ollos vermellos" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Definir o radio do desenfoque" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Enfocar a imaxe" #: f.retouch.cc:4202 msgid "edge detection" msgstr "Detección de bordos" #: f.retouch.cc:4203 msgid "cycles" msgstr "Ciclos" #: f.retouch.cc:4204 msgid "reduce" msgstr "Reducir" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "Máscara de desenfoque" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Prema o boton Reducir para \n" " reducir o ruido en pequenos pasos. \n" " Use Desfacer para comezar de novo." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Reducción de ruido" #: f.retouch.cc:4650 msgid "algorithm" msgstr "Algoritmo" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "Aplanar os valores extremos de cor (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "Aplanar os valores extremos de cor (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "Configurar a mediana de brillo por cor" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "Filtro de cor «sombreiro de copa (Top-hat)»" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Radio" #: f.retouch.cc:5005 msgid "Blur" msgstr "" #: f.retouch.cc:5008 msgid "New Area" msgstr "" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "" #: f.retouch.cc:5989 msgid "pixel group" msgstr "" #: f.retouch.cc:5990 msgid "circle color" msgstr "" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "" #: f.retouch.cc:6164 msgid "file format error" msgstr "" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Memoria de desfacer %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Editar píxeles" #: f.retouch.cc:6695 msgid "pick" msgstr "Recoller" #: f.retouch.cc:6697 msgid "erase" msgstr "Borrar" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "Radio do pincel" #: f.retouch.cc:6706 msgid "transparency center" msgstr "Centro da transparencia" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "Bordo da transparencia" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Acadouse o límite de memoria de desfacer. \n" "Garde o traballo con [Feito], e despois retome a edición." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "" #: f.select.cc:110 msgid "draw: freehand" msgstr "" #: f.select.cc:111 msgid "draw: follow edge" msgstr "" #: f.select.cc:114 msgid "select by mouse" msgstr "" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "" #: f.select.cc:120 msgid "match mouse color" msgstr "" #: f.select.cc:124 msgid "search range" msgstr "" #: f.select.cc:126 msgid "firewall" msgstr "" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" #: f.select.cc:1078 msgid "finish area" msgstr "" #: f.select.cc:1113 msgid "searching" msgstr "" #: f.select.cc:1185 msgid "outline has a gap" msgstr "" #: f.select.cc:1189 msgid "success" msgstr "" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Precisa calcular o bordo" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Calcular a área do bordo" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "" #: f.select.cc:1887 msgid "Paste Image" msgstr "" #: f.select.cc:1901 msgid "angle" msgstr "" #: f.select.cc:2160 msgid "load select area from a file" msgstr "" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "" #: f.select.cc:2213 msgid "save select area to a file" msgstr "" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "" #: f.select.cc:2501 msgid "edge" msgstr "" #: f.select.cc:2504 msgid "reset area" msgstr "" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "" #: f.tools.cc:85 msgid "Start new collection" msgstr "" #: f.tools.cc:87 msgid "Edit a collection" msgstr "" #: f.tools.cc:89 msgid "View a collection" msgstr "" #: f.tools.cc:91 msgid "Delete a collection" msgstr "" #: f.tools.cc:95 msgid "Editing:" msgstr "" #: f.tools.cc:99 msgid "Action:" msgstr "" #: f.tools.cc:133 msgid "New Collection" msgstr "" #: f.tools.cc:156 msgid "Edit Collection" msgstr "" #: f.tools.cc:172 msgid "View Collection" msgstr "" #: f.tools.cc:193 msgid "Delete Collection" msgstr "" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "" #: f.tools.cc:256 msgid "add image to collection" msgstr "" #: f.tools.cc:301 msgid "too many saved files" msgstr "" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "" #: f.tools.cc:375 msgid "old top directory" msgstr "" #: f.tools.cc:378 msgid "new top directory" msgstr "" #: f.tools.cc:434 msgid "completed" msgstr "" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "" #: f.tools.cc:474 msgid "new max. width" msgstr "" #: f.tools.cc:481 msgid "new file type" msgstr "" #: f.tools.cc:482 msgid "same" msgstr "" #: f.tools.cc:490 msgid "replace originals" msgstr "" #: f.tools.cc:491 msgid "export to location" msgstr "" #: f.tools.cc:492 msgid "remove EXIF" msgstr "" #: f.tools.cc:549 msgid "Select directory" msgstr "" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "" #: f.tools.cc:654 msgid "*** file already exists" msgstr "" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Abrir ficheiro RAW" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "" #: f.tools.cc:769 msgid "Choose file type" msgstr "" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "" #: f.tools.cc:893 msgid "arrow keys" msgstr "" #: f.tools.cc:894 msgid "instant" msgstr "" #: f.tools.cc:895 msgid "fade-in" msgstr "" #: f.tools.cc:896 msgid "roll-right" msgstr "" #: f.tools.cc:897 msgid "roll-down" msgstr "" #: f.tools.cc:898 msgid "shift-left" msgstr "" #: f.tools.cc:899 msgid "venetian" msgstr "" #: f.tools.cc:900 msgid "grate" msgstr "" #: f.tools.cc:903 msgid "radar" msgstr "" #: f.tools.cc:904 msgid "jaws" msgstr "" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Diaporama" #: f.tools.cc:915 msgid "seconds" msgstr "segundos" #: f.tools.cc:919 msgid "music file" msgstr "" #: f.tools.cc:923 msgid "transitions" msgstr "" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "" #: f.tools.cc:1844 msgid "no new files found" msgstr "" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Seleccionar o directório raíz de imaxes" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "Amosar RGB" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "" #: f.tools.cc:2728 msgid "x-spacing" msgstr "" #: f.tools.cc:2729 msgid "x-count" msgstr "" #: f.tools.cc:2730 msgid "x-enable" msgstr "" #: f.tools.cc:2736 msgid "y-spacing" msgstr "" #: f.tools.cc:2737 msgid "y-count" msgstr "" #: f.tools.cc:2738 msgid "y-enable" msgstr "" #: f.tools.cc:2745 msgid "x-offset" msgstr "" #: f.tools.cc:2749 msgid "y-offset" msgstr "" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "" #: f.tools.cc:2947 msgid "max. width" msgstr "" #: f.tools.cc:2948 msgid "max. height" msgstr "" #: f.tools.cc:3093 msgid "too many files" msgstr "" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" #: f.tools.cc:3174 msgid "Monitor Check" msgstr "" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "Distribuir o brillo" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Traducións dispoñibles" #: f.tools.cc:3436 msgid "Set Language" msgstr "Seleccionar o idioma" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "Utilice os botóns ou arrastre o bordo dereito co rato" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Xirar a imaxe" #: f.transform.cc:64 msgid "degrees" msgstr "Graos" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Recortar" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Desfacer recortar" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "Graos: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "" #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Recortar a imaxe" #: f.transform.cc:348 msgid "customize" msgstr "" #: f.transform.cc:359 msgid "ratio" msgstr "" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "Bloquear a relación" #: f.transform.cc:368 msgid "invert" msgstr "" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "Bloquear a relación de aspecto" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Redimensionar a imaxe" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Anterior" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "" #: f.transform.cc:1307 msgid "Size" msgstr "Tamaño" #: f.transform.cc:1310 msgid "Angle" msgstr "" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "" #: f.transform.cc:1322 msgid "Transparency" msgstr "" #: f.transform.cc:1325 msgid "text" msgstr "" #: f.transform.cc:1330 msgid "backing" msgstr "" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" #: f.transform.cc:1335 msgid "outline" msgstr "" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "" #: f.transform.cc:1416 msgid "select font" msgstr "" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "Horizontal" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "Vertical" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "" #: f.transform.cc:2158 msgid "black/white positive" msgstr "" #: f.transform.cc:2159 msgid "black/white negative" msgstr "" #: f.transform.cc:2160 msgid "color positive" msgstr "" #: f.transform.cc:2161 msgid "color negative" msgstr "" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Endereitar a imaxe" #: f.transform.cc:2282 msgid "linear" msgstr "" #: f.transform.cc:2285 msgid "curved" msgstr "" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" "Seleccione unha área para deformar utilizando o boton [Seleccionar]. \n" "Prema [Comezar deformación] e empuxe da área co rato. \n" "Facer varios empuxóns co rato até que quede satisfeito. \n" "Cando teña rematado, seleccione outra área ou prema [Feito]." #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "" #: f.transform.cc:2864 msgid "start warp" msgstr "Comezar deformación" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Tirar dun bordo da imaxe empregando o rato. \n" " Facer varios empuxóns co rato até que quede satisfeito. \n" " Cando teña rematado, seleccione outra área ou prema [Feito]." #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "" #: fotoxx-12.01.cc:185 msgid "File" msgstr "Ficheiro" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "Galería de imaxes" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Abrir o ficheiro anterior" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "Abrir ficheiro recente" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "Gardar no mesmo ficheiro" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "Gardar nun ficheiro novo" #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "Mover imaxe ao lixo" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Imprimir ficheiro de imaxe" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "Saír de Fotoxx" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "Ferramentas" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "Gravar imaxes nun CD/DVD" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Comprobar monitor" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Cambiar o idioma" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Amosar" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Agochar" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Inverter" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Gardar" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Retocar" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "Axustar brillo e cor" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "Distribuir o brillo uniformemente" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "Balance de branco" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Ollos vermellos" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Imaxe borrosa" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Redución de ruido" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Arte" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Profundidade da cor" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Combinar" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Panoramica" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Axuda" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "Acerca de..." #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "Guía do usuario" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Editar o rexistro" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "Páxina de inicio" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "Galería" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Seguinte" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Abrir o ficheiro seguinte" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Zoom ampliar" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Zoom reducir" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Desfacer" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Desfacer un paso" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Refacer" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Refacer un paso" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "Enviar a imaxe ao lixo" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "Lixo" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Sair" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "Excédense os 50 puntos de ancoraxe" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "O paquete «exiftool» non está instalado \n" "ao editar as imaxes perderánse os datos EXIF" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Non se pode conservar a selección de área.\n" "Continuar?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "" #: fotoxx.h:728 msgid "absolute" msgstr "" #: fotoxx.h:730 msgid "Add All" msgstr "Engadir todo" #: fotoxx.h:732 msgid "Amount" msgstr "" #: fotoxx.h:733 msgid "Apply" msgstr "Aplicar" #: fotoxx.h:734 msgid "Black" msgstr "" #: fotoxx.h:735 msgid "Blend Width" msgstr "Misturar por anchura" #: fotoxx.h:737 msgid "Brightness" msgstr "Brillo" #: fotoxx.h:738 msgid "Browse" msgstr "" #: fotoxx.h:739 msgid "Cancel" msgstr "Cancelar" #: fotoxx.h:740 msgid "Clear" msgstr "Limpar" #: fotoxx.h:742 msgid "Commit" msgstr "" #: fotoxx.h:744 msgid "Curve File:" msgstr "" #: fotoxx.h:745 msgid "Cut" msgstr "" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Escurecer áreas" #: fotoxx.h:747 msgid "Delete" msgstr "Borrar" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" #: fotoxx.h:750 msgid "Done" msgstr "Feito" #: fotoxx.h:751 msgid "Edit" msgstr "Editar" #: fotoxx.h:753 msgid "Erase" msgstr "" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "" #: fotoxx.h:755 msgid "Fetch" msgstr "" #: fotoxx.h:756 msgid "Finish" msgstr "Terminar" #: fotoxx.h:757 msgid "Font" msgstr "" #: fotoxx.h:759 msgid "Height" msgstr "Altura" #: fotoxx.h:760 msgid "histogram" msgstr "" #: fotoxx.h:762 msgid "Insert" msgstr "Inserir" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Iluminar áreas" #: fotoxx.h:765 msgid "limit" msgstr "" #: fotoxx.h:766 msgid "New" msgstr "" #: fotoxx.h:768 msgid "OK" msgstr "Conforme" #: fotoxx.h:772 msgid "Pause" msgstr "" #: fotoxx.h:773 msgid "Percent" msgstr "Porcentaxe" #: fotoxx.h:774 msgid "Presets" msgstr "Predefinidos" #: fotoxx.h:775 msgid "Proceed" msgstr "Proceder" #: fotoxx.h:777 msgid "range" msgstr "" #: fotoxx.h:780 msgid "Reduce" msgstr "Reducir" #: fotoxx.h:782 msgid "Reset" msgstr "" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Tipo de ficheiro descoñecido. gardeo como tiff/jpeg/png para editalo" #: fotoxx.h:785 msgid "Search" msgstr "Buscar" #: fotoxx.h:789 msgid "Start" msgstr "Comezar" #: fotoxx.h:790 msgid "Threshold" msgstr "" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "Desfacer todo" #: fotoxx.h:793 msgid "Undo Last" msgstr "Desfacer o último" #: fotoxx.h:795 msgid "Unfinish" msgstr "" #: fotoxx.h:797 msgid "View" msgstr "" #: fotoxx.h:798 msgid "White" msgstr "" #: fotoxx.h:799 msgid "Width" msgstr "Anchura" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "O ficheiro de axuda non se atopa: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "Non se pode abrir o ficheiro %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "Gardar pantalla nun ficheiro" #: zfuncs.cc:6222 msgid "No" msgstr "" #: zfuncs.cc:6222 msgid "Yes" msgstr "" #: zfuncs.cc:6447 msgid "open" msgstr "Abrir" #: zfuncs.cc:6452 msgid "choose" msgstr "" #: zfuncs.cc:6457 msgid "save" msgstr "Gardar" #: zfuncs.cc:6463 msgid "open folder" msgstr "Abrir cartafol" #: zfuncs.cc:6468 msgid "create folder" msgstr "Crear cartafol" #: zfuncs.cc:6474 msgid "hidden" msgstr "Agochar" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "Calidade de JPG 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "" #: zfuncs.cc:6737 msgid "top" msgstr "" #: zfuncs.cc:6738 msgid "bottom" msgstr "" #: zfuncs.cc:6739 msgid "left" msgstr "" #: zfuncs.cc:6740 msgid "right" msgstr "" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Parámetros iniciais creados. \n" "Revíseseos se o desexa." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "Cargar parámetros desde ficheiro" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "Gardar parámetros nun ficheiro" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "Editar parámetros" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "Listar\n" "todo" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "Cargar\n" "ficheiro" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "Gardar\n" "ficheiro" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "Engadir\n" "Novo" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "Aplicar" #: zfuncs.cc:7479 msgid "apply?" msgstr "Aplicar?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(Novo parámetro)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "Engadir parámetro" #~ msgid "Brightness Graph" #~ msgstr "Gráfica de brillo" #~ msgid "radius" #~ msgstr "Radio" #~ msgid "Search results file error %s" #~ msgstr "Erro nos resultados da busca %s" #~ msgid "Select area first" #~ msgstr "Debe seleccionar primeiro a área" #~ msgid "Translate" #~ msgstr "Traducións" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "Fallou o renomeado \n" #~ " %s" #~ msgid "Discard modifications?" #~ msgstr "Desbotar as modificacións?" #~ msgid "whiteness" #~ msgstr "Claridade" #~ msgid "unknown image format" #~ msgstr "Formato de imaxe descoñecido" #~ msgid "undo image changes" #~ msgstr "Desfacer os cambios na imaxe" #~ msgid "unbend panorama image" #~ msgstr "Corrixir perspectiva panorámica" #~ msgid "trim image" #~ msgstr "Recortar a imaxe" #~ msgid "toolbar::save" #~ msgstr "Gardar" #, fuzzy #~ msgid "this area cannot be processed" #~ msgstr "" #~ "Non se pode conservar a selección de área.\n" #~ "Continuar?" #~ msgid "tags exceed %d characters" #~ msgstr "As etiquetas do ficheiro exceden de %d caracteres" #~ msgid "sharpen image" #~ msgstr "Enfocar a imaxe" #~ msgid "set color intensity" #~ msgstr "Definir a intensidade da cor" #, fuzzy #~ msgid "set blend radius" #~ msgstr "Definir o radio do desenfoque" #~ msgid "set RGB spread" #~ msgstr "Establece o rango RGB" #~ msgid "rotate image" #~ msgstr "Xirar a imaxe" #~ msgid "resize image" #~ msgstr "Redimensionar a imaxe" #~ msgid "redo image changes" #~ msgstr "Refacer os cambios na imaxe" #~ msgid "red" #~ msgstr "Vermello" #~ msgid "recently added" #~ msgstr "Engadido recentemente" #, fuzzy #~ msgid "radius limit" #~ msgstr "Radio" #~ msgid "quit" #~ msgstr "Sair" #~ msgid "prior function still running" #~ msgstr "A función principal esta aínda traballando" #~ msgid "photo stars" #~ msgstr "Estrelas" #~ msgid "photo date (yyyymmdd)" #~ msgstr "Data da foto (aaaammdd)" #~ msgid "open new image file" #~ msgstr "Abrir unha nova imaxe" #~ msgid "open image file" #~ msgstr "Abrir ficheiro" #~ msgid "open RAW file" #~ msgstr "Abrir ficheiro en bruto" #~ msgid "kill running function" #~ msgstr "Pechar a función actual" #~ msgid "kill" #~ msgstr "Pechar" #~ msgid "input image 2" #~ msgstr "Elixir imaxe 2" #~ msgid "image not 8 or 16 bits/color: %s" #~ msgstr "A imaxe %s non ten 8 ou 16 bits/color" #~ msgid "image format error: %s" #~ msgstr "Erro no formato da imaxe: %s" #~ msgid "graph" #~ msgstr "gráfico" #~ msgid "" #~ "file cannot be read: \n" #~ " %s" #~ msgstr "" #~ "Non se pode ler o ficheiro: \n" #~ " %s" #~ msgid "exiv2 package is required" #~ msgstr "Precisase o paquete exiv2" #~ msgid "exiftool is required to generate tags index" #~ msgstr "Precisase «exiftool» para xerar o índice de etiquetas" #~ msgid "exiftool is required to create tags" #~ msgstr "Precisase «exiftool» para cear etiquetas" #, fuzzy #~ msgid "edge calculation missing" #~ msgstr "Precisa calcular o bordo" #~ msgid "defog" #~ msgstr "desembazar" #~ msgid "date range (yyyymmdd)" #~ msgstr "Formato da data (aaaammdd)" #~ msgid "computing" #~ msgstr "computing" #~ msgid "color balance" #~ msgstr "Balance da cor" #~ msgid "click or drag trim margins" #~ msgstr "Faga clic na imaxe ou arrastre o bordo" #~ msgid "" #~ "cannot create %s \n" #~ " %s" #~ msgstr "" #~ "Non se pode crear %s \n" #~ " %s" #~ msgid "brightness distribution" #~ msgstr "Distribuir o brillo" #~ msgid "blur radius" #~ msgstr "Radio de desenfoque" #~ msgid "blend" #~ msgstr "Mestura" #~ msgid "bigger image" #~ msgstr "Imaxe máis grande" #~ msgid "assigned tags" #~ msgstr "Etiquetas asignadas" #~ msgid "adjust brightness / whiteness" #~ msgstr "Axustar brillo / claridade" #~ msgid "Zoom-" #~ msgstr "Zoom-" #~ msgid "Zoom+" #~ msgstr "Zoom+" #~ msgid "Warp Global" #~ msgstr "Deformación da imaxe" #~ msgid "Warp" #~ msgstr "Deformar" #~ msgid "Unable to save image: %s" #~ msgstr "Non se pode gardar a imaxe: %s" #~ msgid "Unable to save image" #~ msgstr "Non se pode gardar a imaxe" #, fuzzy #~ msgid "Unable to replace file" #~ msgstr "Non se pode gardar a imaxe" #~ msgid "Unable to copy EXIF data" #~ msgstr "Non se poden copiar os datos EXIF" #~ msgid "Tune Image" #~ msgstr "Afinar a imaxe" #~ msgid "Total tags exceed %d characters" #~ msgstr "O número total de etiquetas excedeu en %d caracteres" #~ msgid "Too many undo buffers, please save image" #~ msgstr "Demasiados «desfacer» no bufer, garde a imaxe" #~ msgid "Too many tags: %d" #~ msgstr "Demasiadas etiquetas: %d" #~ msgid "Too many points" #~ msgstr "Demasiados puntos" #~ msgid "Thumbnail Index" #~ msgstr "Ãndice de miniaturas" #~ msgid "Special Art Effects" #~ msgstr "Efectos artísticos especiales" #~ msgid "Simulate embossing" #~ msgstr "Semellar un repuxado" #, fuzzy #~ msgid "Simulate Mosaic" #~ msgstr "Simular repuxado" #, fuzzy #~ msgid "Simulat Mosaic" #~ msgstr "Simular repuxado" #~ msgid "Show Area" #~ msgstr "Amosar área" #~ msgid "Sharp" #~ msgstr "Enfoque" #~ msgid "" #~ "Select area is not finished.\n" #~ "Continue without using it?" #~ msgstr "" #~ "Non se completou a selección de área.\n" #~ "Continuar sen usala?" #~ msgid "Select Area -mouse" #~ msgstr "Seleccionar área -rato" #~ msgid "Select Area -color" #~ msgstr "Seleccionar área -cor" #~ msgid "Save Image as File" #~ msgstr "Gardar a imaxe como ficheiro" #~ msgid "Rotate" #~ msgstr "Xirar" #~ msgid "RGB spread" #~ msgstr "Rango RGB" #~ msgid "RGB Spread" #~ msgstr "Rango RGB" #~ msgid "README" #~ msgstr "LEAME" #~ msgid "RAW file template" #~ msgstr "Plantilla de ficheiro RAW" #~ msgid "Print" #~ msgstr "Imprimir" #~ msgid "Paint Pixels" #~ msgstr "Pintar píxeles" #~ msgid "Package exiftool is missing" #~ msgstr "Non se atopa o paquete «exiftool»" #~ msgid "Output Image" #~ msgstr "Imaxe de saída" #, fuzzy #~ msgid "Outline Image Area for Following Edits" #~ msgstr "Ãrea da imaxe para ediciós seguintes" #~ msgid "No assigned tags index file" #~ msgstr "Etiquetas sen asignar ao ficheiro de índice" #~ msgid "Make HDR Image" #~ msgstr "Facer imaxe HDR" #~ msgid "Make HDF Image" #~ msgstr "Facer imaxe HDF" #~ msgid "" #~ "Left click/drag: add to selected area. \n" #~ "Right click: remove prior selection(s). \n" #~ "Color range: add more or less at once." #~ msgstr "" #~ "Facer clic no botón esquerdo e arrastrar: engadir á área seleccionada. \n" #~ "Facer clic no botón dereito: quitar a(s) selección(s) previa(s). \n" #~ "Gama de cores: engadir máis o menos de vez." #~ msgid "Invert Area" #~ msgstr "Inverter área" #~ msgid "Input Images" #~ msgstr "Imaxes de entrada" #~ msgid "Index Tags and Thumbs" #~ msgstr "Sincronizar etiquetas e miniaturas" #~ msgid "Index (thumbnails)" #~ msgstr "Ãndice (miniaturas)" #~ msgid "Index" #~ msgstr "Ãndice" #~ msgid "Image Weights per Brightness Level" #~ msgstr "Peso da imaxe por nivel de brillo" #~ msgid "Hide Area" #~ msgstr "Agochar área" #~ msgid "HDR Image Weights" #~ msgstr "Peso da imaxe HDR" #, fuzzy #~ msgid "FreeImage" #~ msgstr "Redimensionar a imaxe" #, fuzzy #~ msgid "Flash" #~ msgstr "Lixo" #~ msgid "FREEIMAGE unknown error" #~ msgstr "Erro descoñecido en FREEIMAGE" #~ msgid "FREEIMAGE error: %s" #~ msgstr "Erro en FREEIMAGE: %s" #~ msgid "Error Log" #~ msgstr "Rexistro de erros" #~ msgid "Edge Calc" #~ msgstr "Calcular o bordo" #~ msgid "" #~ "Drag middle to move \n" #~ "Drag corners to resize" #~ msgstr "" #~ "Arrastre desde o interior para mover \n" #~ "Arrastre os cantos para redimensionar" #, fuzzy #~ msgid "" #~ "Drag and click to enclose an area.\n" #~ "Use right click to undo prior." #~ msgstr "" #~ "Use o rato, arrastre e faga clic para pechar unha área \n" #~ "e o botón dereito para desfacer." #~ msgid "Distortion" #~ msgstr "Distorsión" #~ msgid "" #~ "Distance calculation needs a long time.\n" #~ " Do you want to continue?" #~ msgstr "" #~ "O cálculo da distancia necesita bastante tempo.\n" #~ " Desexa continuar?" #~ msgid "Dimensions" #~ msgstr "Dimensións" #~ msgid "Delete selected area?" #~ msgstr "Borrar a área seleccionada?" #~ msgid "Delete Area" #~ msgstr "Borar a área" #~ msgid "" #~ "Convert raw file to 48-bit tiff format? \n" #~ " (this may take a while) " #~ msgstr "" #~ "Converter ficheiros RAW a formato tiff de 48 bits?\n" #~ " (isto pode tardar un pouco)" #~ msgid "Convert multiple RAWs" #~ msgstr "Converter múltiples RAW" #~ msgid "Composite Images" #~ msgstr "Composición de imaxes" #~ msgid "Color Intensity" #~ msgstr "Intensidade da cor" #~ msgid "Clear Select Area" #~ msgstr "Limpar área seleccionada" #~ msgid "Build Tags Index" #~ msgstr "Construir índice de etiquetas" #~ msgid "Brightness/Whiteness" #~ msgstr "Axustar brillo / claridade" #~ msgid "Brightness/Contrast/Color" #~ msgstr "Brillo/Contraste/Cor" #, fuzzy #~ msgid "Blend Area Edges" #~ msgstr "Radio de desenfoque" #~ msgid "Bend" #~ msgstr "Mestura" #~ msgid "Assigned tags file error: %s" #~ msgstr "Erro ao asignar etiquetas de ficheiro: %s" #~ msgid "Adjust Saturation (RGB spread)" #~ msgstr "Ajuste de saturación (rango RGB)" #~ msgid "2nd image not same size as 1st image" #~ msgstr "A 2ª imaxe non ten o mesmo tamaño que a 1ª" #~ msgid "2nd file is not compatible with 1st" #~ msgstr "O segundo ficheiro non é compatible co primeiro" #~ msgid " color balance red " #~ msgstr " balance da cor vermello" #~ msgid " color balance green " #~ msgstr " balance da cor verde" #~ msgid " color balance blue " #~ msgstr " balance da cor azul" #~ msgid "" #~ " Set color depth to 1-8 bits per color. \n" #~ " Press [apply] to update the image." #~ msgstr "" #~ " Establece a profundidade de cor a 1-8 bits por cor, \n" #~ " despois prema [Aplicar] para actualizar a imaxe." #~ msgid " green" #~ msgstr " Verde" #~ msgid " blue" #~ msgstr " Azul" #~ msgid " adjust red" #~ msgstr " Axuste vermello" #~ msgid "" #~ " left: no color (grey) \n" #~ " middle: normal (unmodified) \n" #~ " right: maximum color" #~ msgstr "" #~ "esquerda: sen rango RGB (gris) \n" #~ " centro: normal (sen modificar) \n" #~ " dereita: rango máximo RGB" #~ msgid "" #~ " left: no RGB spread (gray) \n" #~ " middle: normal (unmodified) \n" #~ " right: maximum RGB spread" #~ msgstr "" #~ "esquerda: sen cor (gris) \n" #~ " centro: normal (sen modificar) \n" #~ " dereita: máximo cor" #~ msgid "" #~ "\n" #~ " brightness \n" #~ " level" #~ msgstr "" #~ "\n" #~ " Brillo \n" #~ " Nivel" #~ msgid "Select image to combine" #~ msgstr "Seleccionar unha imaxe para combinar" #~ msgid "Retouch Image" #~ msgstr "Retoque de imaxe" #~ msgid "Package ufraw required for this function" #~ msgstr "Precisase o aplicativo «ufraw» para esta función" #~ msgid "Merge the images together" #~ msgstr "Misturar as imaxes en conxunto" #~ msgid "Match Images" #~ msgstr "Ensamblar as imaxes" #~ msgid "" #~ "Drag right image into rough alignment with left \n" #~ " to rotate, drag right edge up or down" #~ msgstr "" #~ "Arrastre a imaxe dereita para aliñala coa da esquerda \n" #~ " para xirala, arrastre o bordo dereito cara arriba ou abaixo" #~ msgid "Auto-search lens mm and bow" #~ msgstr "Buscar automaticamente o lente (mm) e a curva" #~ msgid "Auto" #~ msgstr "Auto" #~ msgid "" #~ "\n" #~ " Match Brightness and Color" #~ msgstr "" #~ "\n" #~ " Ensamblar a luminosidade e a cor" #~ msgid "color range" #~ msgstr "Rango da cor" #~ msgid "add tags" #~ msgstr "Etiquetas asignadas" #~ msgid "Fix Image Perspective" #~ msgstr "Fixar a imaxe en perspectiva" #~ msgid "Burn" #~ msgstr "Gravar" #~ msgid "color intensity" #~ msgstr "Intensidade da cor" #~ msgid "Warp Image in Selected Area" #~ msgstr "Deformar imaxe na área seleccionada" #~ msgid "Warp Area" #~ msgstr "Deformación de área" #~ msgid "" #~ " Pull on an image edge using the mouse. \n" #~ " Make multiple mouse pulls until satisfied. \n" #~ " When finished, press [done]." #~ msgstr "" #~ " Tirar dun bordo da imaxe empregando o rato. \n" #~ " Facer varios empuxóns co rato até que quede satisfeito. \n" #~ " Cando teña rematado, seleccione outra área ou prema [Feito]." #~ msgid "match any tag" #~ msgstr "Elexir calquer etiqueta" #~ msgid "match all tags" #~ msgstr "Elexir todas as etiquetas" #~ msgid "Tags" #~ msgstr "Etiquetas" #~ msgid "Suspend" #~ msgstr "Suspender" #~ msgid "Set Tile and Gap Size" #~ msgstr "Axustar mosaico e tamaño da separación" #~ msgid "Search Tags" #~ msgstr "Buscar etiquetas" #~ msgid "Resume" #~ msgstr "Retomar" #~ msgid "Basic EXIF data" #~ msgstr "Datos EXIF básicos" #~ msgid "All EXIF data" #~ msgstr "Todos os datos EXIF" #~ msgid "/path*/file*" #~ msgstr "/ruta*/ficheiro*" #~ msgid "HDR" #~ msgstr "HDR" #~ msgid "HDF" #~ msgstr "HDF" #~ msgid "Area" #~ msgstr "Ãrea" #~ msgid "target group area" #~ msgstr "Ãrea do grupo de destino" #~ msgid "vertical unbend" #~ msgstr "Enderezamento vertical" #~ msgid "horizontal unbend" #~ msgstr "Enderezamento horizontal" #~ msgid "Create Launcher" #~ msgstr "Crear un lanzador" #~ msgid "Save As" #~ msgstr "Gardar como" #~ msgid "Clone fotoxx" #~ msgstr "Clonar Fotoxx" #~ msgid "Time Interval" #~ msgstr "Intervalo de tempo" #~ msgid "open a file" #~ msgstr "Abrir un ficheiro" #~ msgid "xdg-utils package not installed" #~ msgstr "O paquete «xdg-utils» non está instalado" #~ msgid "select new folder" #~ msgstr "Seleccionar novo cartafol" #~ msgid "open a directory" #~ msgstr "Abrir un novo directório" #~ msgid "jump to specific file" #~ msgstr "Cambia a un ficheiro específico" #~ msgid "folder" #~ msgstr "Cartafol" #~ msgid "file" #~ msgstr "Ficheiro" #~ msgid "close thumbnail window" #~ msgstr "Pechar Ãndice de miniaturas" #~ msgid "select new file" #~ msgstr "Seleccionar ficheiro novo" #~ msgid "lens name" #~ msgstr "Nome da lente" #~ msgid "Lens Parameters" #~ msgstr "Parámetros da óptica" fotoxx-12.01.2/locales/fotoxx-it.po0000664000175000017500000015063611701011017015571 0ustar micomico# translation of fotoxx.po to italian # Eugenio Baldi , 2009. # (revisione) Doriano Blengino , 2011 # #-#-#-#-# fotoxx.po (messages) #-#-#-#-# # Italian translations for home package. # Copyright (C) 2008 THE home'S COPYRIGHT HOLDER # This file is distributed under the same license as the home package. msgid "" msgstr "" "Project-Id-Version: fotoxx\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-01-04 02:54+0100\n" "PO-Revision-Date: 2010-06-03 16:14+0100\n" "Language-Team: italiano \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "Impostare la profondità del colore da 1 a 16 bit" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Imposta la profondità di colore" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Simula disegno" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "Contrasto" #: f.art.cc:215 msgid "outlines" msgstr "Contorni" #: f.art.cc:220 msgid "pencil" msgstr "Matita" #: f.art.cc:221 msgid "chalk" msgstr "Gessetto" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "Aggiunta contorni" #: f.art.cc:394 msgid "outline threshold" msgstr "Soglia del contorno" #: f.art.cc:397 msgid "outline width" msgstr "Spessore contorno" #: f.art.cc:400 msgid "image brightness" msgstr "Luminosità immagine" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Simula un bassorilievo" #: f.art.cc:626 msgid "depth" msgstr "Profondità" #: f.art.cc:628 f.file.cc:921 f.retouch.cc:6692 msgid "color" msgstr "Colore" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Simula un mosaico" #: f.art.cc:825 msgid "tile size" msgstr "Dimensione tessere" #: f.art.cc:829 msgid "tile gap" msgstr "Distanza fra tessere" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "Converti immagine in punti" #: f.art.cc:1007 msgid "dot size" msgstr "Dimensione punto" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Simula un dipinto" #: f.art.cc:1226 msgid "color depth" msgstr "Profondità di colore" #: f.art.cc:1230 msgid "patch area goal" msgstr "Fattore artistico" #: f.art.cc:1234 msgid "req. color match" msgstr "Precisione colori" #: f.art.cc:1238 msgid "borders" msgstr "Contorni" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "Selezionare da 2 a 9 file" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Le immagini non hanno la stessa dimensione" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "Regola contributi immagine" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "Pixel scuri" #: f.comp.cc:2326 msgid "light pixels" msgstr "Pixel luminosi" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "File:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "Dipingi e deforma immagine" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "immagine" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "Dipingi" #: f.comp.cc:2851 msgid "warp" msgstr "Deforma" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "Seleziona e dipingi" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "Regola la composizione dei pixel" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "Selezionare da 2 a 4 file" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" "Trascinare le immagini a un allineamento approssimativo.\n" "Per ruotarle, trascinare il bordo inferiore." #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "Ricerca per mm e curvatura lenti" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Pre-allineamento immagini" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "mm lente" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "curvatura lente" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "Ridimensiona" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "Ridimensiona finestra" #: f.comp.cc:4457 msgid "use two images only" msgstr "Utilizzare solo due immagini" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Troppo poca sovrapposizione, impossibile allineare" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "Allinea luminosità e colore" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "colore automatico" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "file colore" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" "Trascinare le immagini a un allineamento approssimativo.\n" "Per ruotarle, trascinare il bordo destro." #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.1.cc:188 fotoxx-12.01.1.cc:324 msgid "Open Image File" msgstr "Apri immagine" #: f.file.cc:321 fotoxx-12.01.1.cc:2861 msgid "prior function still active" msgstr "" "Una funzione interattiva è ancora in uso\n" "Terminare tale funzione e riprovare." #: f.file.cc:503 msgid "Overwrite original file?" msgstr "Sovrascrivere il file originale?" #: f.file.cc:504 msgid "Do not warn again" msgstr "Non chiedere di nuovo" #: f.file.cc:520 msgid "Warning" msgstr "Attenzione" #: f.file.cc:643 msgid "Save File" msgstr "Salva file" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "Qualità" #: f.file.cc:668 msgid "make current" msgstr "Rendi corrente" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "la qualità jpeg deve essere 1-100" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Sovrascrivere il file? \n" " %s" #: f.file.cc:905 fotoxx-12.01.1.cc:195 msgid "Create Blank Image" msgstr "Crea immagine vuota" #: f.file.cc:907 msgid "file name" msgstr "Nome file" #: f.file.cc:912 f.transform.cc:353 msgid "width" msgstr "larghezza" #: f.file.cc:915 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "altezza" #: f.file.cc:1035 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "Non è supportato il cestino strandard di Linux. \n" "Sarà creata una cartella/cestino dedicata." #: f.file.cc:1053 msgid "Move read-only file to trash?" msgstr "Spostare il file in sola lettura nel cestino ?" #: f.file.cc:1079 #, c-format msgid "Cannot create trash folder: %s" msgstr "Impossible creare il cestino: %s" #: f.file.cc:1087 f.file.cc:1093 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "errore: %s" #: f.file.cc:1138 fotoxx-12.01.1.cc:197 msgid "Rename Image File" msgstr "Rinomina immagine" #: f.file.cc:1143 msgid "old name" msgstr "Vecchio nome" #: f.file.cc:1144 msgid "rename to" msgstr "Rinominare in" #: f.file.cc:1145 msgid "previous" msgstr "Precedente" #: f.file.cc:1231 msgid "The target file already exists" msgstr "Il file di destinazione esiste già" #: f.file.cc:1239 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" "Rinominazione fallita: \n" " %s" #: f.file.cc:1287 msgid "Batch Rename" msgstr "Rinomina più immagini" #: f.file.cc:1290 f.file.cc:1342 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "%d file selezionati" #: f.file.cc:1292 msgid "new base name" msgstr "Nuovo nome" #: f.file.cc:1295 msgid "starting sequence" msgstr "inizio sequenza" #: f.file.cc:1297 msgid "increment" msgstr "incremento" #: f.file.cc:1318 msgid "select files to rename" msgstr "scegliere i file da rinominare" #: f.file.cc:1323 msgid "base name / sequence / increment not reasonable" msgstr "nome principale / sequenza / incremento non ragionevole" #: f.file.cc:1382 msgid "new file already exists:" msgstr "Nuovo file già esistente:" #: f.file.cc:1390 msgid "filespec too long:" msgstr "Nome file troppo lungo:" #: f.file.cc:1401 msgid "Rename failed:" msgstr "Rinominazione fallita:" #: f.file.cc:1662 fotoxx.h:729 msgid "Add" msgstr "Aggiungi" #: f.file.cc:1662 fotoxx.h:781 msgid "Remove" msgstr "Elimina" #: f.file.cc:1664 msgid "menu name" msgstr "Nome nel menù" #: f.file.cc:1735 f.file.cc:1756 msgid "Restart Fotoxx to update plugin menu" msgstr "Riavviare fotoxx per aggiornare il menù Plugins" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "Modifica titolo e commenti" #: f.info.cc:156 fotoxx-12.01.1.cc:224 msgid "Edit Tags" msgstr "Modifica etichette" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "Data immagine (aaaammgg)" #: f.info.cc:165 msgid "use last" msgstr "Utilizza ultima" #: f.info.cc:168 msgid "image stars" msgstr "Voto dell'immagine" #: f.info.cc:186 msgid "current tags" msgstr "Etichette attuali:" #: f.info.cc:191 msgid "recent tags" msgstr "Etichette recenti:" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "Etichette definite:" #: f.info.cc:345 fotoxx-12.01.1.cc:225 msgid "Manage Tags" msgstr "Gestione etichette" #: f.info.cc:348 msgid "category" msgstr "Categoria" #: f.info.cc:351 msgid "tag" msgstr "Etichetta" #: f.info.cc:354 msgid "create" msgstr "Crea" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "Elimina" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "Errore nel file indice di ricerca: %s" #: f.info.cc:1351 fotoxx-12.01.1.cc:226 msgid "Batch Add Tags" msgstr "Aggiungi etichette a più immagini" #: f.info.cc:1354 msgid "tags to add" msgstr "Etichette da aggiungere" #: f.info.cc:1359 msgid "create tag" msgstr "Crea etichetta" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " troppe etichette" #: f.info.cc:1553 fotoxx-12.01.1.cc:227 msgid "Batch Delete Tag" msgstr "Cancellazione in blocco di etichette" #: f.info.cc:1556 msgid "tag to remove" msgstr "Etichetta da rimuovere" #: f.info.cc:1560 msgid "optional replacement" msgstr "Sostituzione opzionale" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "0 file selezionati" #: f.info.cc:1568 msgid "search all files" msgstr "Cerca in tutti i file" #: f.info.cc:1653 msgid "no files selected" msgstr "Nessun file selezionato" #: f.info.cc:1659 msgid "no tag specified" msgstr "Nessuna etichetta specificata" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "Specificare etichetta" #: f.info.cc:1821 msgid "View Info" msgstr "Informazioni immagine" #: f.info.cc:1889 fotoxx-12.01.1.cc:230 msgid "Edit Info" msgstr "Modifica informazioni" #: f.info.cc:1987 fotoxx-12.01.1.cc:231 msgid "Delete Info" msgstr "Elimina informazioni" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "Tutto" #: f.info.cc:1990 msgid "One Key:" msgstr "Una chiave:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "Cerca in etichette, commenti e nomi file" #: f.info.cc:2350 msgid "date range" msgstr "Intervallo date: " #: f.info.cc:2351 msgid "stars range" msgstr "Voto da/a:" #: f.info.cc:2352 msgid "search tags" msgstr "Cerca etichette" #: f.info.cc:2353 msgid "search text" msgstr "Cerca testo" #: f.info.cc:2354 msgid "file names" msgstr "Nomi di file" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "(aaaammgg)" #: f.info.cc:2365 msgid "all/any" msgstr "Tutte/Qualsiasi" #: f.info.cc:2702 msgid "No matching images found" msgstr "Nessuna immagine soddisfa la ricerca" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "File per la ricerca indicizzata non esistente." #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "Aumenta" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "Aumenta la dimensione delle miniature" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "Riduci la dimensione delle miniature" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "Riduci" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "Superiore" #: f.navi.cc:190 msgid "parent directory" msgstr "Cartella superiore" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "Prima pagina" #: f.navi.cc:191 msgid "jump to first file" msgstr "Passa al primo file" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "Pagina prec." #: f.navi.cc:192 msgid "previous page" msgstr "Pagina precedente" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "Riga prec." #: f.navi.cc:193 msgid "previous row" msgstr "Riga precedente" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "Riga successiva" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "Pagina successiva" #: f.navi.cc:195 msgid "ttip::next page" msgstr "Pagina successiva" #: f.navi.cc:196 msgid "jump to last file" msgstr "Passa all'ultimo file" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "Ultima pagina" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "Chiudi" #: f.navi.cc:197 msgid "close image gallery" msgstr "Chiudi galleria immagini" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "Selezionare i file" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "Annulla" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "Fatto" #: f.navi.cc:1422 msgid "insert" msgstr "Inserisci" #: f.navi.cc:1423 msgid "add all" msgstr "Aggiungi tutti" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Regola luminosità e colore" #: f.retouch.cc:110 msgid "small-steps" msgstr "Controllo fine" #: f.retouch.cc:119 msgid "color saturation" msgstr "Saturazione" #: f.retouch.cc:126 msgid " reset 1 " msgstr "Azzera" #: f.retouch.cc:127 msgid "reset all" msgstr "Azzera tutte" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "Regola gamma" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "Espandi escursione di luminosità" #: f.retouch.cc:887 msgid "bright pixels" msgstr "Pixel chiari" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Distribuisci luminosità" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Quantità" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "Rampe di luce" #: f.retouch.cc:1730 fotoxx-12.01.1.cc:271 msgid "Tone Mapping" msgstr "Mappa tonalità" #: f.retouch.cc:1758 msgid "low" msgstr "basso" #: f.retouch.cc:1760 msgid "high" msgstr "alto" #: f.retouch.cc:1763 msgid "Amplify" msgstr "Amplificazione" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Bilanciamento del bianco" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Cliccare un punto [che dovrebbe essere] bianco o grigio" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "Trasfrisci colore" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "Raggio di prelievo del colore" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.1.cc:245 #: fotoxx-12.01.1.cc:324 fotoxx.h:769 msgid "Open" msgstr "Apri" #: f.retouch.cc:2310 msgid "image for source color" msgstr "l'immagine di riferimento" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "Cliccare nell'immagine per prelevare il colore" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "l'immagine a cui impostare il colore" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "Cliccare nell'immagine per allineare il colore" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "Selezionare prima l'immagine di riferimento" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Rosso" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Verde" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Blu" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "File:" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "File non trovato" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "Cliccare l'immagine per selezionare i pixel" #: f.retouch.cc:3072 fotoxx-12.01.1.cc:275 msgid "Revise RGB" msgstr "Edita RGB" #: f.retouch.cc:3084 msgid "Metric:" msgstr "Metrica" #: f.retouch.cc:3139 msgid "Blend" msgstr "Mescola" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Metodo 1:\n" " - Cliccare col pulsante sinistro sull'occhio rosso per scurirlo.\n" "Metodo 2:\n" " - Trascinare verso destra e in basso per circondare l'occhio rosso. \n" " - Cliccare col pulsante sinistro sull'occhio rosso per scurirlo. \n" "Per annullare:\n" " - Cliccare col pulsante destro sull'occhio rosso." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Riduzione occhi rossi" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Sfuocatura: imposta raggio" #: f.retouch.cc:4195 fotoxx-12.01.1.cc:278 msgid "Sharpen Image" msgstr "Contrasta" #: f.retouch.cc:4202 msgid "edge detection" msgstr "Riconoscimento dei bordi" #: f.retouch.cc:4203 msgid "cycles" msgstr "Cicli" #: f.retouch.cc:4204 msgid "reduce" msgstr "Riduci" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "Maschera di contrasto" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "Gradiente di luminosità" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Cliccare [Ridurre] per ridurre il disturbo \n" " a piccoli passi. \n" " Usare [Annulla] per ricominciare." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Riduzione disturbo" #: f.retouch.cc:4650 msgid "algorithm" msgstr "Algoritmo:" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "Appiattimento estremi per colore (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "Appiattimento estremi per colore (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "Impostazione luminosità media per colore" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "Filtro \"top hat\" per colore" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" "1. Trascinare per selezionare. \n" "2. Cancellare. 3. Ripetere. " #: f.retouch.cc:4998 fotoxx-12.01.1.cc:280 msgid "Smart Erase" msgstr "Cancellazione intelligente" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Raggio" #: f.retouch.cc:5005 msgid "Blur" msgstr "Sfuoca" #: f.retouch.cc:5008 msgid "New Area" msgstr "Nuova area" #: f.retouch.cc:5379 fotoxx-12.01.1.cc:281 msgid "Remove Dust" msgstr "Rimozione polvere" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "Raggio max della polvere" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "Luminosità massima" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "Contrasto minimo" #: f.retouch.cc:5983 fotoxx-12.01.1.cc:282 msgid "Fix Stuck Pixels" msgstr "Correggi pixel difettosi" #: f.retouch.cc:5989 msgid "pixel group" msgstr "Gruppo di pixel:" #: f.retouch.cc:5990 msgid "circle color" msgstr "Colore circolo:" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "Carica posizioni" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "File di posizioni dei pixel rovinati" #: f.retouch.cc:6164 msgid "file format error" msgstr "Formato file errato" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "Non ci sono pixel difettosi" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "Salva posizioni" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Memoria per Annulla %d%c" #: f.retouch.cc:6688 fotoxx-12.01.1.cc:283 msgid "Edit Pixels" msgstr "Modifica pixel" #: f.retouch.cc:6695 msgid "pick" msgstr "Seleziona" #: f.retouch.cc:6697 msgid "erase" msgstr "Cancella" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "Raggio del pennello:" #: f.retouch.cc:6706 msgid "transparency center" msgstr "Trasparenza al centro:" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "Trasparenza al bordo:" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Il limite della memoria per Annulla è stato raggiunto. \n" "Salvare il lavoro con [Fatto], e riprendere le modifiche." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Seleziona area per modifiche" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "Premere F1 per l'aiuto" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" "Questa funzione non supporta \n" "aree di selezione." #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "Rettangolo" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "Ellisse" #: f.select.cc:110 msgid "draw: freehand" msgstr "Disegno: mano libera" #: f.select.cc:111 msgid "draw: follow edge" msgstr "Disegno: segui bordi" #: f.select.cc:114 msgid "select by mouse" msgstr "Selezione col mouse: " #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "Raggio del mouse:" #: f.select.cc:120 msgid "match mouse color" msgstr "Corrispondenza colore:" #: f.select.cc:124 msgid "search range" msgstr "Distanza di ricerca:" #: f.select.cc:126 msgid "firewall" msgstr "confinamento" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "superate %d modifiche" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" "Cliccare ogni singola area chiusa: \n" "eventuali interruzioni nel contorno saranno rilevate. \n" "Premere F1 per l'aiuto" #: f.select.cc:1078 msgid "finish area" msgstr "Finisci area" #: f.select.cc:1113 msgid "searching" msgstr "in ricerca" #: f.select.cc:1185 msgid "outline has a gap" msgstr "il contorno è interrotto" #: f.select.cc:1189 msgid "success" msgstr "Successo" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "L'area non è chiusa" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Ricalcolo bordo in corso" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Calcolo area delimitata" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "posizione con clic o trascinamento" #: f.select.cc:1887 msgid "Paste Image" msgstr "Incolla immagine" #: f.select.cc:1901 msgid "angle" msgstr "angolo" #: f.select.cc:2160 msgid "load select area from a file" msgstr "carica l'area di selezione da file" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "impossibile aprire i file .tiff e .info" #: f.select.cc:2213 msgid "save select area to a file" msgstr "salva area in un file" #: f.select.cc:2248 fotoxx-12.01.1.cc:247 msgid "Select Whole Image" msgstr "Immagine intera" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "Regola amplificazione di funzione" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "Forza: centro:" #: f.select.cc:2501 msgid "edge" msgstr "bordo:" #: f.select.cc:2504 msgid "reset area" msgstr "Azzera area" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" "Nella gestione di collezioni, usare un clic destro \n" "su immagini e miniature per agguingere o eliminare." #: f.tools.cc:70 fotoxx-12.01.1.cc:203 msgid "Manage Collections" msgstr "Gestione collezioni" #: f.tools.cc:85 msgid "Start new collection" msgstr "Crea una collezione nuova" #: f.tools.cc:87 msgid "Edit a collection" msgstr "Modificare una collezione" #: f.tools.cc:89 msgid "View a collection" msgstr "Visualizzare una collezione" #: f.tools.cc:91 msgid "Delete a collection" msgstr "Eliminare un collezione" #: f.tools.cc:95 msgid "Editing:" msgstr "Modifica di:" #: f.tools.cc:99 msgid "Action:" msgstr "Azione:" #: f.tools.cc:133 msgid "New Collection" msgstr "Nuova collezione" #: f.tools.cc:156 msgid "Edit Collection" msgstr "Modifica collezione" #: f.tools.cc:172 msgid "View Collection" msgstr "Vista collezione" #: f.tools.cc:193 msgid "Delete Collection" msgstr "Elimina collezione" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "Eliminare %s?" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "Aggiungi immagine alla collezione %s" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "Rimuovi immagine dalla collezione" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "Rimuovi immagine e ricordala" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "Inserisci qui le immagini ricordate" #: f.tools.cc:256 msgid "add image to collection" msgstr "Aggiungi immagine alla collezione" #: f.tools.cc:301 msgid "too many saved files" msgstr "Troppi file da ricordare" #: f.tools.cc:373 fotoxx-12.01.1.cc:204 msgid "Move Collections" msgstr "Sposta collezioni" #: f.tools.cc:375 msgid "old top directory" msgstr "Vecchia cartella principale" #: f.tools.cc:378 msgid "new top directory" msgstr "Nuova cartella principale" #: f.tools.cc:434 msgid "completed" msgstr "Completato" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "Converti/ridimensiona/esporta in blocco" #: f.tools.cc:474 msgid "new max. width" msgstr "Nuova larghezza max:" #: f.tools.cc:481 msgid "new file type" msgstr "Nuovo tipo di file" #: f.tools.cc:482 msgid "same" msgstr "uguale" #: f.tools.cc:490 msgid "replace originals" msgstr "Sostituisci gli originali" #: f.tools.cc:491 msgid "export to location" msgstr "Esporta altrove" #: f.tools.cc:492 msgid "remove EXIF" msgstr "Elimina EXIF" #: f.tools.cc:549 msgid "Select directory" msgstr "Seleziona cartella" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "Sostituire i file originali? (max. %d x %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "Copiare i file? (max. %d x %d) \n" " nella posizione %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "La posizione non è una cartella valida" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "Dimensioni massime %d x %d non ragionevoli" #: f.tools.cc:654 msgid "*** file already exists" msgstr "*** file già esistente" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "*** tipo di file non gestito" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "E' richiesto il programma ufraw-batch" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Apri file RAW" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "Scegliere i file RAW da convertire" #: f.tools.cc:769 msgid "Choose file type" msgstr "Scegliere il tipo di file" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "Premere ESC per terminare lo slide show" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "Mostra solo le ultime versioni" #: f.tools.cc:893 msgid "arrow keys" msgstr "Manuale: tasti freccia" #: f.tools.cc:894 msgid "instant" msgstr "Istantanea" #: f.tools.cc:895 msgid "fade-in" msgstr "Dissolvenza" #: f.tools.cc:896 msgid "roll-right" msgstr "Tenda sx-dx" #: f.tools.cc:897 msgid "roll-down" msgstr "Tenda su-giù" #: f.tools.cc:898 msgid "shift-left" msgstr "Scorrimento a sinistra" #: f.tools.cc:899 msgid "venetian" msgstr "Veneziana" #: f.tools.cc:900 msgid "grate" msgstr "Quadrettoni" #: f.tools.cc:903 msgid "radar" msgstr "Radar" #: f.tools.cc:904 msgid "jaws" msgstr "Ganasce" #: f.tools.cc:911 fotoxx-12.01.1.cc:207 msgid "Slide Show" msgstr "Slideshow" #: f.tools.cc:915 msgid "seconds" msgstr "secondi" #: f.tools.cc:919 msgid "music file" msgstr "File musicale" #: f.tools.cc:923 msgid "transitions" msgstr "Transizioni" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "Selezionare file musicale o playlist" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "Sincronizzazione file già attiva" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" "Eseguire [Strumenti > Sincronizza file] affinché le gallerie \n" "di miniature siano veloci e la Ricerca immagini funzioni. \n" "Si possono vedere le immagini, ma non manipolare, mentre il processo gira." #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "Nessuna cartella d'immagini principale è definita" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "Cartella d'immagini principale non valida" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "Non esiste un file indice per la ricerca" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "Sono presenti file nuovi o modificati" #: f.tools.cc:1844 msgid "no new files found" msgstr "nessun nuovo file trovato" #: f.tools.cc:1859 fotoxx-12.01.1.cc:208 msgid "Synchronize Files" msgstr "Sincronizza file" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Cartella immagini principale:" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "La cartella principale non è valida" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Scegliere la cartella principale delle immagini" #: f.tools.cc:2429 fotoxx-12.01.1.cc:209 msgid "Show RGB" msgstr "Esplora componenti RGB" #: f.tools.cc:2719 fotoxx-12.01.1.cc:210 msgid "Grid Lines" msgstr "Linee griglia" #: f.tools.cc:2728 msgid "x-spacing" msgstr "Passo X:" #: f.tools.cc:2729 msgid "x-count" msgstr "Num. barre X:" #: f.tools.cc:2730 msgid "x-enable" msgstr "Abilita X:" #: f.tools.cc:2736 msgid "y-spacing" msgstr "Passo Y:" #: f.tools.cc:2737 msgid "y-count" msgstr "Num. righe Y:" #: f.tools.cc:2738 msgid "y-enable" msgstr "Abilita Y:" #: f.tools.cc:2745 msgid "x-offset" msgstr "Origine X:" #: f.tools.cc:2749 msgid "y-offset" msgstr "Origine Y:" #: f.tools.cc:2940 fotoxx-12.01.1.cc:212 msgid "E-mail Images" msgstr "Spedisci immagini via e-mail" #: f.tools.cc:2947 msgid "max. width" msgstr "Larghezza max:" #: f.tools.cc:2948 msgid "max. height" msgstr "Altezza max:" #: f.tools.cc:3093 msgid "too many files" msgstr "Troppi file" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" "Le barre dovrebbero mostrare una gradualità\n" "in tutta la loro estensione." #: f.tools.cc:3174 msgid "Monitor Check" msgstr "Verifica schermo" #: f.tools.cc:3232 fotoxx-12.01.1.cc:214 msgid "Monitor Gamma" msgstr "Gamma dello schermo" #: f.tools.cc:3294 fotoxx-12.01.1.cc:215 msgid "Brightness Distribution" msgstr "Distribuzione della luminosità" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Traduzioni disponibili" #: f.tools.cc:3436 msgid "Set Language" msgstr "Cambia lingua" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "Crea lanciatore" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "Stile barra strumenti" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "Testo" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "Usa i bottoni o trascina il margine destro con il mouse" #: f.transform.cc:60 fotoxx-12.01.1.cc:251 msgid "Rotate Image" msgstr "Ruota" #: f.transform.cc:64 msgid "degrees" msgstr "Gradi" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Ritaglia" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "Griglia" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Annulla ritaglio" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "Gradi : %.1f" #: f.transform.cc:286 msgid "gold" msgstr "Gold" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "Trascinare il centro per spostare, e i lati per ridimensionare." #: f.transform.cc:348 fotoxx-12.01.1.cc:252 msgid "Trim Image" msgstr "Ritaglia" #: f.transform.cc:348 msgid "customize" msgstr "Personalizza" #: f.transform.cc:359 msgid "ratio" msgstr "Rapporto:" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "Blocca proporzioni" #: f.transform.cc:368 msgid "invert" msgstr "Inverti" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "Pulsanti di taglio" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "Blocca proporzioni" #: f.transform.cc:1072 fotoxx-12.01.1.cc:254 msgid "Resize Image" msgstr "Ridimensiona" #: f.transform.cc:1095 fotoxx-12.01.1.cc:325 msgid "Prev" msgstr "Prec." #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" "Impostare il testo e cliccare/trascinare nell'immagine.\n" "Clic destro per rimuovere" #: f.transform.cc:1294 fotoxx-12.01.1.cc:255 msgid "Annotate Image" msgstr "Inserisci testo" #: f.transform.cc:1307 msgid "Size" msgstr "Dimensione:" #: f.transform.cc:1310 msgid "Angle" msgstr "Angolo:" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Colore:" #: f.transform.cc:1322 msgid "Transparency" msgstr "Trasparenza:" #: f.transform.cc:1325 msgid "text" msgstr "Testo" #: f.transform.cc:1330 msgid "backing" msgstr "Sfondo" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "Spessore contorno:" #: f.transform.cc:1335 msgid "outline" msgstr "Contorno" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "File annotazioni:" #: f.transform.cc:1416 msgid "select font" msgstr "Scegliere il font" #: f.transform.cc:2045 fotoxx-12.01.1.cc:256 msgid "Flip Image" msgstr "Rifletti/specchia" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "Orizzontale" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "Verticale" #: f.transform.cc:2155 fotoxx-12.01.1.cc:257 msgid "Make Negative" msgstr "Genera negativo" #: f.transform.cc:2158 msgid "black/white positive" msgstr "Bianco e nero, positivo" #: f.transform.cc:2159 msgid "black/white negative" msgstr "Bianco e nero, negativo" #: f.transform.cc:2160 msgid "color positive" msgstr "A colori, positivo" #: f.transform.cc:2161 msgid "color negative" msgstr "A colori, negativo" #: f.transform.cc:2272 fotoxx-12.01.1.cc:258 msgid "Unbend Image" msgstr "Correggi deformazioni obbiettivo" #: f.transform.cc:2282 msgid "linear" msgstr "Lineare" #: f.transform.cc:2285 msgid "curved" msgstr "Curvato" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" " Cliccare gli angoli di un'area trapezoidale; cliccare [Applica]. \n" " L'immagine si deformerà per trasformare il trapezio in un rettangolo." #: f.transform.cc:2556 fotoxx-12.01.1.cc:259 msgid "Keystone Correction" msgstr "Correzione quadrangolare" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "Occorrono 4 angoli." #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" "Selezionare un'area da deformare utilizzando la funzione del menu. \n" "Premere [Avvia deformazione] e trascinare con il mouse.\n" "Trascinare più volte se necessario.\n" "Quando terminato, selezionare un'altra zona o premere [Fatto]. " #: f.transform.cc:2859 fotoxx-12.01.1.cc:260 msgid "Warp Image (area)" msgstr "Deforma area" #: f.transform.cc:2864 msgid "start warp" msgstr "Avvia deformazione" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "Area di selezione non attiva" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Trascinare un punto dell'immagine con il mouse. \n" " Eseguire diversi trascinamenti fino al completamento. \n" " Quando finito, premere [Fatto]." #: f.transform.cc:3112 fotoxx-12.01.1.cc:261 msgid "Warp Image (curved)" msgstr "Deforma a curva" #: f.transform.cc:3375 fotoxx-12.01.1.cc:262 msgid "Warp Image (linear)" msgstr "Deforma a linea" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" "Trascinare angoli o lati dell'immagine con il mouse. \n" "Ripetere l'operazione se richiesto.\n" "Una volta finito, premere [Fatto]." #: f.transform.cc:3639 fotoxx-12.01.1.cc:263 msgid "Warp Image (affine)" msgstr "Deforma specularmente" #: fotoxx-12.01.1.cc:184 msgid "File" msgstr "File" #: fotoxx-12.01.1.cc:185 fotoxx-12.01.1.cc:323 msgid "Image Gallery" msgstr "Galleria immagini" #: fotoxx-12.01.1.cc:186 msgid "Clone 50/50" msgstr "Clona (50/50)" #: fotoxx-12.01.1.cc:187 msgid "Clone Overlay" msgstr "Clona (sovrapposta)" #: fotoxx-12.01.1.cc:189 msgid "Open in New Window" msgstr "Apri in nuova finestra" #: fotoxx-12.01.1.cc:190 fotoxx-12.01.1.cc:325 msgid "Open Previous File" msgstr "Apri l'immagine precedente" #: fotoxx-12.01.1.cc:191 msgid "Open Recent File" msgstr "Immagini recenti" #: fotoxx-12.01.1.cc:192 fotoxx-12.01.1.cc:333 msgid "Save to Same File" msgstr "Salva (sovrascrivi)" #: fotoxx-12.01.1.cc:193 fotoxx-12.01.1.cc:334 msgid "Save to New Version" msgstr "Salva con nuova versione" #: fotoxx-12.01.1.cc:194 fotoxx-12.01.1.cc:335 msgid "Save to New File" msgstr "Salva in un file nuovo" #: fotoxx-12.01.1.cc:196 msgid "Trash Image File" msgstr "Cestina l'immagine" #: fotoxx-12.01.1.cc:198 msgid "Batch Rename Files" msgstr "Rinomina più immagini" #: fotoxx-12.01.1.cc:199 msgid "Print Image File" msgstr "Stampa immagine" #: fotoxx-12.01.1.cc:200 fotoxx-12.01.1.cc:339 msgid "Quit fotoxx" msgstr "Termina Fotoxx" #: fotoxx-12.01.1.cc:202 msgid "Tools" msgstr "Strumenti" #: fotoxx-12.01.1.cc:205 msgid "Batch Convert" msgstr "Converti più immagini" #: fotoxx-12.01.1.cc:206 msgid "Convert RAW files" msgstr "Converti immagini RAW" #: fotoxx-12.01.1.cc:211 msgid "Burn Images to CD/DVD" msgstr "Masterizza immagini su CD/DVD" #: fotoxx-12.01.1.cc:213 msgid "Check Monitor" msgstr "Verifica schermo" #: fotoxx-12.01.1.cc:216 msgid "Change Language" msgstr "Cambia lingua del programma" #: fotoxx-12.01.1.cc:218 msgid "Menu and Launcher" msgstr "Crea menù/lanciatore" #: fotoxx-12.01.1.cc:219 msgid "User Settings" msgstr "" #: fotoxx-12.01.1.cc:220 msgid "Memory Usage" msgstr "Mostra uso memoria (in console)" #: fotoxx-12.01.1.cc:223 msgid "Edit Caption/Comments" msgstr "Modifica titolo/commenti" #: fotoxx-12.01.1.cc:228 msgid "View Info (short)" msgstr "Informazioni brevi" #: fotoxx-12.01.1.cc:229 msgid "View Info (long)" msgstr "Informazioni estese" #: fotoxx-12.01.1.cc:232 msgid "Search Images" msgstr "Ricerca immagini" #: fotoxx-12.01.1.cc:233 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.1.cc:235 fotoxx-12.01.1.cc:236 fotoxx.h:786 msgid "Select" msgstr "Seleziona" #: fotoxx-12.01.1.cc:237 fotoxx.h:788 msgid "Show" msgstr "Visualizza" #: fotoxx-12.01.1.cc:238 fotoxx.h:761 msgid "Hide" msgstr "Nascondi" #: fotoxx-12.01.1.cc:239 fotoxx.h:752 msgid "Enable" msgstr "Abilita" #: fotoxx-12.01.1.cc:240 fotoxx.h:748 msgid "Disable" msgstr "Disabilita" #: fotoxx-12.01.1.cc:241 fotoxx.h:763 msgid "Invert" msgstr "Inverti" #: fotoxx-12.01.1.cc:242 fotoxx.h:796 msgid "Unselect" msgstr "Deseleziona" #: fotoxx-12.01.1.cc:243 fotoxx.h:743 msgid "Copy" msgstr "Copia" #: fotoxx-12.01.1.cc:244 fotoxx.h:771 msgid "Paste" msgstr "Incolla" #: fotoxx-12.01.1.cc:246 fotoxx-12.01.1.cc:333 fotoxx.h:783 msgid "Save" msgstr "Salva" #: fotoxx-12.01.1.cc:248 msgid "Select and Edit" msgstr "Seleziona e modifica" #: fotoxx-12.01.1.cc:250 msgid "Transform" msgstr "Trasforma" #: fotoxx-12.01.1.cc:253 msgid "Auto-Trim Image" msgstr "Ritaglia automaticamente" #: fotoxx-12.01.1.cc:265 msgid "Retouch" msgstr "Ritocco" #: fotoxx-12.01.1.cc:266 msgid "Brightness/Color" msgstr "Luminosità e colore" #: fotoxx-12.01.1.cc:267 msgid "Gamma Curves" msgstr "Curve Gamma" #: fotoxx-12.01.1.cc:268 msgid "Expand Brightness" msgstr "Espandi luminosità" #: fotoxx-12.01.1.cc:269 msgid "Flatten Brightness" msgstr "Normalizza luminosità" #: fotoxx-12.01.1.cc:270 msgid "Brightness Ramp" msgstr "Rampe di luce/colore" #: fotoxx-12.01.1.cc:272 msgid "White Balance" msgstr "Bilanciamento del bianco" #: fotoxx-12.01.1.cc:273 msgid "Match Colors" msgstr "Trasferisci colore" #: fotoxx-12.01.1.cc:276 msgid "Red Eyes" msgstr "Rimuovi occhi rossi" #: fotoxx-12.01.1.cc:277 msgid "Blur Image" msgstr "Sfuoca" #: fotoxx-12.01.1.cc:279 msgid "Reduce Noise" msgstr "Riduci disturbo" #: fotoxx-12.01.1.cc:285 msgid "Art" msgstr "Arte" #: fotoxx-12.01.1.cc:286 msgid "Color Depth" msgstr "Profondità di colore" #: fotoxx-12.01.1.cc:287 msgid "Drawing" msgstr "Disegno" #: fotoxx-12.01.1.cc:288 msgid "Outlines" msgstr "Contorni" #: fotoxx-12.01.1.cc:289 msgid "Embossing" msgstr "Bassorilievo" #: fotoxx-12.01.1.cc:290 msgid "Tiles" msgstr "Mosaico" #: fotoxx-12.01.1.cc:291 msgid "Dots" msgstr "Puntinismo" #: fotoxx-12.01.1.cc:292 msgid "Painting" msgstr "Dipinto" #: fotoxx-12.01.1.cc:294 msgid "Combine" msgstr "Combina" #: fotoxx-12.01.1.cc:295 msgid "High Dynamic Range" msgstr "Combina immagini (alta dinamica - HDR)" #: fotoxx-12.01.1.cc:296 msgid "High Depth of Field" msgstr "Combina immagini (grande profondità - HDF)" #: fotoxx-12.01.1.cc:297 msgid "Stack / Paint" msgstr "Sovrapponi (interattivo con mouse)" #: fotoxx-12.01.1.cc:298 msgid "Stack / Noise" msgstr "Sovrapponi (rimozione disturbo)" #: fotoxx-12.01.1.cc:299 msgid "Panorama" msgstr "Crea un panorama" #: fotoxx-12.01.1.cc:300 msgid "Vertical Panorama" msgstr "Panorama verticale" #: fotoxx-12.01.1.cc:303 msgid "Edit Plugins" msgstr "Gestione plug-in" #: fotoxx-12.01.1.cc:312 fotoxx-12.01.1.cc:340 fotoxx-12.01.1.cc:3025 msgid "Help" msgstr "Aiuto" #: fotoxx-12.01.1.cc:313 fotoxx-12.01.1.cc:3015 msgid "About" msgstr "Info" #: fotoxx-12.01.1.cc:314 fotoxx-12.01.1.cc:3019 msgid "User Guide" msgstr "Guida utente" #: fotoxx-12.01.1.cc:315 fotoxx-12.01.1.cc:3022 msgid "User Guide Changes" msgstr "Cronistoria della guida utente" #: fotoxx-12.01.1.cc:316 fotoxx-12.01.1.cc:3031 msgid "Edit Functions Summary" msgstr "Sommario funzioni" #: fotoxx-12.01.1.cc:317 fotoxx-12.01.1.cc:3034 msgid "Change Log" msgstr "Cronistoria delle modifiche" #: fotoxx-12.01.1.cc:318 fotoxx-12.01.1.cc:3037 msgid "Translations" msgstr "Traduzioni" #: fotoxx-12.01.1.cc:319 fotoxx-12.01.1.cc:3040 msgid "Home Page" msgstr "Sito WEB" #: fotoxx-12.01.1.cc:323 msgid "Gallery" msgstr "Miniature" #: fotoxx-12.01.1.cc:326 fotoxx.h:767 msgid "Next" msgstr "Prossima" #: fotoxx-12.01.1.cc:326 msgid "Open Next File" msgstr "Apri l'immagine successiva" #: fotoxx-12.01.1.cc:327 msgid "Zoom-in (bigger)" msgstr "Ingrandisci" #: fotoxx-12.01.1.cc:328 msgid "Zoom-out (smaller)" msgstr "Riduci" #: fotoxx-12.01.1.cc:329 fotoxx.h:794 msgid "Undo" msgstr "Annulla" #: fotoxx-12.01.1.cc:329 msgid "Undo One Edit" msgstr "Annulla ultimo" #: fotoxx-12.01.1.cc:330 fotoxx.h:779 msgid "Redo" msgstr "Ripeti" #: fotoxx-12.01.1.cc:330 msgid "Redo One Edit" msgstr "Ripeti ultimo" #: fotoxx-12.01.1.cc:334 msgid "Save+V" msgstr "Salva+V" #: fotoxx-12.01.1.cc:335 msgid "Save+F" msgstr "Salva>N" #: fotoxx-12.01.1.cc:336 msgid "Move Image to Trash" msgstr "Cestina immagine" #: fotoxx-12.01.1.cc:336 msgid "Trash" msgstr "Cestina" #: fotoxx-12.01.1.cc:339 msgid "Quit" msgstr "Uscita" #: fotoxx-12.01.1.cc:340 msgid "Fotoxx Essentials" msgstr "Informazioni principali su Fotoxx" #: fotoxx-12.01.1.cc:447 msgid "first time startup" msgstr "Prima esecuzione" #: fotoxx-12.01.1.cc:1943 msgid "Exceed 50 anchor points" msgstr "Superati 50 punti di ancoraggio" #: fotoxx-12.01.1.cc:2128 msgid "load curve from a file" msgstr "carica curva da file" #: fotoxx-12.01.1.cc:2181 msgid "curve file is invalid" msgstr "File di curve non valido" #: fotoxx-12.01.1.cc:2186 msgid "curve file has different no. of curves" msgstr "Il file di curve ha un numero diverso di curve" #: fotoxx-12.01.1.cc:2201 msgid "save curve to a file" msgstr "salva curva in un file" #: fotoxx-12.01.1.cc:2336 msgid "cannot parallel edit" msgstr "Non si possono fare editazioni concorrenti" #: fotoxx-12.01.1.cc:2346 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "Il pacchetto exiftool non è installato.\n" "Le immagini modificate perderanno le informazioni Exif." #: fotoxx-12.01.1.cc:2352 msgid "Too many edits, please save image" msgstr "Troppe modifiche: salvare l'immagine" #: fotoxx-12.01.1.cc:2357 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "L'area selezionata non può essere mantenuta.\n" "Continuare?" #: fotoxx-12.01.1.cc:2365 msgid "" "Select area not active.\n" "Continue?" msgstr "" "Selezione di area non attiva.\n" "Continuare?" #: fotoxx-12.01.1.cc:2836 msgid "Discard edits?" msgstr "Scartare le modifiche?" #: fotoxx-12.01.1.cc:2837 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" "Questo annullerà le modifiche correnti.\n" "[Continua] per confermare la perdita,\n" "[Indietro] per rinunciare e mantenerle." #: fotoxx-12.01.1.cc:2840 msgid "Continue" msgstr "Continua" #: fotoxx-12.01.1.cc:2841 msgid "Go Back" msgstr "Indietro" #: fotoxx-12.01.1.cc:3658 msgid "cannot open thumbnail file" msgstr "Impossibile aprire il file delle anteprime" #: fotoxx-12.01.1.cc:3869 fotoxx-12.01.1.cc:3991 msgid "TIFF open failure" msgstr "Apertura TIFF fallita" #: fotoxx-12.01.1.cc:3885 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF bit/colore=%d non supportati" #: fotoxx-12.01.1.cc:3900 fotoxx-12.01.1.cc:3938 msgid "TIFF read failure" msgstr "Lettura TIFF fallita" #: fotoxx-12.01.1.cc:4050 msgid "TIFF write failure" msgstr "Scrittura TIFF fallita" #: fotoxx-12.01.1.cc:4070 msgid "file type not supported" msgstr "Tipo di file non supportato" #: fotoxx-12.01.1.cc:4177 msgid "pixbuf write failure" msgstr "Scrittura pixbuf fallita" #: fotoxx.h:728 msgid "absolute" msgstr "Assoluto" #: fotoxx.h:730 msgid "Add All" msgstr "Aggiungere tutto" #: fotoxx.h:732 msgid "Amount" msgstr "Quantità" #: fotoxx.h:733 msgid "Apply" msgstr "Applica" #: fotoxx.h:734 msgid "Black" msgstr "Nero" #: fotoxx.h:735 msgid "Blend Width" msgstr "Larghezza di sfumatura" #: fotoxx.h:737 msgid "Brightness" msgstr "Luminosità" #: fotoxx.h:738 msgid "Browse" msgstr "Sfoglia" #: fotoxx.h:739 msgid "Cancel" msgstr "Annulla" #: fotoxx.h:740 msgid "Clear" msgstr "Pulisci" #: fotoxx.h:742 msgid "Commit" msgstr "Esegui" #: fotoxx.h:744 msgid "Curve File:" msgstr "File di curve:" #: fotoxx.h:745 msgid "Cut" msgstr "Taglia" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Aree scure" #: fotoxx.h:747 msgid "Delete" msgstr "Elimina" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" "Annullare la lista della galleria speciale? \n" " %s" #: fotoxx.h:750 msgid "Done" msgstr "Fatto" #: fotoxx.h:751 msgid "Edit" msgstr "Modifica" #: fotoxx.h:753 msgid "Erase" msgstr "Esegui cancellatura" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "è necessario il pacchetto libimage-exiftool-perl" #: fotoxx.h:755 msgid "Fetch" msgstr "Prendi" #: fotoxx.h:756 msgid "Finish" msgstr "Termina" #: fotoxx.h:757 msgid "Font" msgstr "Font" #: fotoxx.h:759 msgid "Height" msgstr "Altezza" #: fotoxx.h:760 msgid "histogram" msgstr "Istogramma" #: fotoxx.h:762 msgid "Insert" msgstr "Incolla" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Aree luminose" #: fotoxx.h:765 msgid "limit" msgstr "limite" #: fotoxx.h:766 msgid "New" msgstr "Nuovo" #: fotoxx.h:768 msgid "OK" msgstr "Ok" #: fotoxx.h:772 msgid "Pause" msgstr "Sospendi" #: fotoxx.h:773 msgid "Percent" msgstr "Percentuale" #: fotoxx.h:774 msgid "Presets" msgstr "Fisse: " #: fotoxx.h:775 msgid "Proceed" msgstr "Prosegui" #: fotoxx.h:777 msgid "range" msgstr "intervallo" #: fotoxx.h:780 msgid "Reduce" msgstr "Ridurre" #: fotoxx.h:782 msgid "Reset" msgstr "Azzera" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Tipo di file sconosciuto. Salvarlo come TIFF/JPEG/PNG per modificarlo" #: fotoxx.h:785 msgid "Search" msgstr "Ricerca" #: fotoxx.h:789 msgid "Start" msgstr "Inizio" #: fotoxx.h:790 msgid "Threshold" msgstr "Soglia" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "Annulla tutto" #: fotoxx.h:793 msgid "Undo Last" msgstr "Annulla ultimo" #: fotoxx.h:795 msgid "Unfinish" msgstr "Ricomincia" #: fotoxx.h:797 msgid "View" msgstr "Vista" #: fotoxx.h:798 msgid "White" msgstr "Bianco" #: fotoxx.h:799 msgid "Width" msgstr "Larghezza" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "File di aiuto non trovato: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "non è possibile aprire il file %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "Salva schermo in un file" #: zfuncs.cc:6222 msgid "No" msgstr "No" #: zfuncs.cc:6222 msgid "Yes" msgstr "Si" #: zfuncs.cc:6447 msgid "open" msgstr "Apri" #: zfuncs.cc:6452 msgid "choose" msgstr "Scegli" #: zfuncs.cc:6457 msgid "save" msgstr "Salva" #: zfuncs.cc:6463 msgid "open folder" msgstr "Apri cartella" #: zfuncs.cc:6468 msgid "create folder" msgstr "Crea cartella" #: zfuncs.cc:6474 msgid "hidden" msgstr "Nascosto" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "Qualità JPG 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "Margini" #: zfuncs.cc:6737 msgid "top" msgstr "Alto" #: zfuncs.cc:6738 msgid "bottom" msgstr "Basso" #: zfuncs.cc:6739 msgid "left" msgstr "Sinistra" #: zfuncs.cc:6740 msgid "right" msgstr "Destra" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Il primo file di parametri è stato creato. \n" "Verificare e correggere se necessario." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "Carica i parametri da un file" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "Salva parametri in un file" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "Modifica parametri" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "elenca\n" "tutti" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "Carica\n" "file" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "Salva\n" "file" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "Aggiungi\n" "nuovo" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "Applica" #: zfuncs.cc:7479 msgid "apply?" msgstr "Applicare?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(nome nuovo parametro)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "Aggiungi parametro" #~ msgid "start edit function first" #~ msgstr "Richiamare prima una funzione di modifica (Ritocco, Trasforma...)" #~ msgid "file sync is mandatory" #~ msgstr "'Sincronizza file' è obbligatorio" #~ msgid "Lens Parameters" #~ msgstr "Parametri dell'obbiettivo" #~ msgid "lens name" #~ msgstr "Nome lente" #~ msgid "icons" #~ msgstr "Icone" #~ msgid "both" #~ msgstr "Entrambi" #~ msgid "my mouse" #~ msgstr "Abilita mouse" #~ msgid "select new file" #~ msgstr "Scegliere un nuovo file" fotoxx-12.01.2/locales/fotoxx-fr.po0000664000175000017500000014776311701011017015573 0ustar micomico# translation of fotoxx_merge.po to # mico , 2008. # Stanislas Zeller , 2008, 2009, 2010, 2011. # translation of fotoxx.po to # #-#-#-#-# fotoxx.po (messages) #-#-#-#-# # French translations for home package. # Copyright (C) 2008 THE home'S COPYRIGHT HOLDER # This file is distributed under the same license as the home package. msgid "" msgstr "" "Project-Id-Version: fotoxx_merge\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:05+0100\n" "PO-Revision-Date: 2011-01-05 17:07+0100\n" "Last-Translator: Stanislas Zeller \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: KBabel 1.11.4\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "" "Configurer la profondeur de \n" "couleurs de 1 à 16 bits." #: f.art.cc:57 msgid "Set Color Depth" msgstr "Configurer la profondeur de couleurs" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Simuler un dessin" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "Contraste" #: f.art.cc:215 msgid "outlines" msgstr "Contours" #: f.art.cc:220 msgid "pencil" msgstr "Crayon" #: f.art.cc:221 msgid "chalk" msgstr "Craie" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "" #: f.art.cc:394 msgid "outline threshold" msgstr "" #: f.art.cc:397 msgid "outline width" msgstr "" #: f.art.cc:400 msgid "image brightness" msgstr "" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Simuler un gaufrage" #: f.art.cc:626 msgid "depth" msgstr "Profondeur" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "Couleur" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Simuler des tuiles" #: f.art.cc:825 msgid "tile size" msgstr "Taille de la tuile" #: f.art.cc:829 msgid "tile gap" msgstr "Espace entre les tuiles" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "Convertir l'image en points" #: f.art.cc:1007 msgid "dot size" msgstr "Taille du point" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Simuler une peinture" #: f.art.cc:1226 msgid "color depth" msgstr "Profondeur de couleurs" #: f.art.cc:1230 msgid "patch area goal" msgstr "" #: f.art.cc:1234 msgid "req. color match" msgstr "Correspondance de couleurs requise" #: f.art.cc:1238 msgid "borders" msgstr "Contours" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "Sélectionner 2 à 9 fichiers" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Les images ne sont pas toutes de la même taille" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "Ajuster les recouvrements de l'image" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "Pixels sombres" #: f.comp.cc:2326 msgid "light pixels" msgstr "Pixels lumineux" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "Fichier : " #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "image" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "Peinture" #: f.comp.cc:2851 msgid "warp" msgstr "Déformer" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "Sélectionner 2 à 4 fichiers" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "Rechercher les valeurs « lens mm / bow »" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Images pré alignées" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "Longueur de la focale (lens_mm)" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "Courbe d'objectif (lens_bow)" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "Redimensionner" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "Redimensionner la fenêtre" #: f.comp.cc:4457 msgid "use two images only" msgstr "N'utilisez seulement que deux images" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Trop de chevauchements, impossible d'aligner." #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "Correspondance de la luminosité et de la couleur" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "Couleur auto." #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "Couleur du fichier" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Ouvrir une image" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "" #: f.file.cc:504 msgid "Do not warn again" msgstr "" #: f.file.cc:520 msgid "Warning" msgstr "" #: f.file.cc:643 msgid "Save File" msgstr "Enregistrer le fichier" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "Qualité" #: f.file.cc:668 msgid "make current" msgstr "" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "La qualité du JPEG doit être compris entre 1 et 100" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Écraser le fichier ? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "Créer une image vide" #: f.file.cc:905 msgid "file name" msgstr "" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "Largeur" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "Hauteur" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "La corbeille standard Linux n'est pas prise ne charge? \n" "Un dossier corbeille sera créé." #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "Déplacer le fichier en lecture-seule vers la corbeille ?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "Impossible de créer le dossier corbeille : %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "Erreur : %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Renommer l'image" #: f.file.cc:1141 msgid "old name" msgstr "Ancien nom" #: f.file.cc:1142 msgid "rename to" msgstr "Renommer en" #: f.file.cc:1143 msgid "previous" msgstr "Préc." #: f.file.cc:1229 msgid "The target file already exists" msgstr "Le fichier cible existe toujours" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" #: f.file.cc:1285 msgid "Batch Rename" msgstr "Renommer par lot" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "" #: f.file.cc:1290 msgid "new base name" msgstr "Nouveau nom" #: f.file.cc:1293 msgid "starting sequence" msgstr "Commence par" #: f.file.cc:1295 msgid "increment" msgstr "Incrémente de" #: f.file.cc:1316 msgid "select files to rename" msgstr "Sélectionner les fichiers à renommer" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "Une valeur est obligatoire" #: f.file.cc:1380 msgid "new file already exists:" msgstr "Un nouveau fichier existe toujours : " #: f.file.cc:1388 msgid "filespec too long:" msgstr "Le fichier « filespec » est trop long" #: f.file.cc:1399 msgid "Rename failed:" msgstr "Le renommage a échoué : " #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "" #: f.file.cc:1662 msgid "menu name" msgstr "" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Modifier les étiquettes" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "Date (aaaa-mm-jj)" #: f.info.cc:165 msgid "use last" msgstr "Dernière utilisation" #: f.info.cc:168 msgid "image stars" msgstr "Note de l'image" #: f.info.cc:186 msgid "current tags" msgstr "Étiquettes actuelles" #: f.info.cc:191 msgid "recent tags" msgstr "Étiquettes récentes" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "Définir les étiquettes" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "" #: f.info.cc:348 msgid "category" msgstr "Catégorie" #: f.info.cc:351 msgid "tag" msgstr "Étiquette" #: f.info.cc:354 msgid "create" msgstr "Créer" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "Supprimer" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "Ajouter des étiquettes par lot" #: f.info.cc:1354 msgid "tags to add" msgstr "Étiquettes à ajouter" #: f.info.cc:1359 msgid "create tag" msgstr "Créer une étiquette" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " trop d'étiquettes" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "Supprimer des étiquettes par lot" #: f.info.cc:1556 msgid "tag to remove" msgstr "Étiquette à supprimer" #: f.info.cc:1560 msgid "optional replacement" msgstr "Remplacement optionnel" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "" #: f.info.cc:1568 msgid "search all files" msgstr "Rechercher tous les fichiers" #: f.info.cc:1653 msgid "no files selected" msgstr "Aucun fichiers sélectionnés" #: f.info.cc:1659 msgid "no tag specified" msgstr "Aucune étiquettes spécifiées" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "Étiquette spécifique" #: f.info.cc:1821 msgid "View Info" msgstr "Afficher les informations" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "Modifier les informations" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "Supprimer les informations" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "Tout" #: f.info.cc:1990 msgid "One Key:" msgstr "Une touche : " #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "Rechercher les étiquettes, commentaires et noms de fichiers" #: f.info.cc:2350 msgid "date range" msgstr "Date entre : " #: f.info.cc:2351 msgid "stars range" msgstr "Note entre : " #: f.info.cc:2352 msgid "search tags" msgstr "Rechercher" #: f.info.cc:2353 msgid "search text" msgstr "Rechercher le texte" #: f.info.cc:2354 msgid "file names" msgstr "Noms des fichiers" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "" #: f.info.cc:2365 msgid "all/any" msgstr "" #: f.info.cc:2702 msgid "No matching images found" msgstr "Aucuns résultats pour cette recherche" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "Plus gros" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "Augmenter la taille des miniatures" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "Réduire la taille des miniatures" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "Plus petit" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "" #: f.navi.cc:190 msgid "parent directory" msgstr "" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "Première page" #: f.navi.cc:191 msgid "jump to first file" msgstr "Aller au premier fichier" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "Page précé." #: f.navi.cc:192 msgid "previous page" msgstr "Page précédente" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "Ligne précé." #: f.navi.cc:193 msgid "previous row" msgstr "Ligne précédente" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "Ligne suiv." #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "Page suiv." #: f.navi.cc:195 msgid "ttip::next page" msgstr "" #: f.navi.cc:196 msgid "jump to last file" msgstr "Aller au dernier fichier" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "Dernière page" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "Fermer" #: f.navi.cc:197 msgid "close image gallery" msgstr "Fermer la fenêtre des miniatures" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "Sélectionner les fichiers" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "Annuler" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "Terminé" #: f.navi.cc:1422 msgid "insert" msgstr "" #: f.navi.cc:1423 msgid "add all" msgstr "" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Ajuster la luminosité et la couleur" #: f.retouch.cc:110 msgid "small-steps" msgstr "" #: f.retouch.cc:119 msgid "color saturation" msgstr "Saturation des couleurs" #: f.retouch.cc:126 msgid " reset 1 " msgstr "Réinit. 1x" #: f.retouch.cc:127 msgid "reset all" msgstr "Tout réinitialiser" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "Améliorer la plage de luminosité" #: f.retouch.cc:887 msgid "bright pixels" msgstr "Pixels lumineux" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Distribution aplanie de la luminosité" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Aplanir" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "Corriger la luminosité dans des parties de l'image" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "Tone Mapping" #: f.retouch.cc:1758 msgid "low" msgstr "" #: f.retouch.cc:1760 msgid "high" msgstr "" #: f.retouch.cc:1763 msgid "Amplify" msgstr "" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Ajuster la balance des blancs" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Cliquez sur une couleur de l'image" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Ouvrir" #: f.retouch.cc:2310 msgid "image for source color" msgstr "" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Rouge" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Vert" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Bleu" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "" #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "" #: f.retouch.cc:3084 msgid "Metric:" msgstr "" #: f.retouch.cc:3139 msgid "Blend" msgstr "" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Méthode n°1 : \n" "- Faites un clic-gauche sur l'Å“il rouge pour l'assombrir. \n" "Méthode n°2 : \n" "- Tirer le pointeur en bas vers la droite pour l'enfermer. \n" "- Pour annuler : faite un clic-droit sur l'Å“il rouge." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Réduction des yeux rouges" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Configurer le radius flou" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Netteté" #: f.retouch.cc:4202 msgid "edge detection" msgstr "Détection des bords" #: f.retouch.cc:4203 msgid "cycles" msgstr "Cycles" #: f.retouch.cc:4204 msgid "reduce" msgstr "Réduire" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "Masque flou" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "Gradient de luminosité" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Appuyer sur [Réduire] pour atténuer \n" " le bruit par petites étapes. \n" " Utilisez [Undo] pour annuler." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Réduction du bruit" #: f.retouch.cc:4650 msgid "algorithm" msgstr "Algorithme" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "Aplanir les extrêmes par couleur (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "Aplanir les extrêmes par couleur (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "Ajuster la luminosité médiane par couleur" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "Filtre TopHat par couleur" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Radius" #: f.retouch.cc:5005 msgid "Blur" msgstr "" #: f.retouch.cc:5008 msgid "New Area" msgstr "" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "" #: f.retouch.cc:5989 msgid "pixel group" msgstr "" #: f.retouch.cc:5990 msgid "circle color" msgstr "" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "" #: f.retouch.cc:6164 msgid "file format error" msgstr "" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Annuler la mémoire %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Modifier les pixels" #: f.retouch.cc:6695 msgid "pick" msgstr "Sélection" #: f.retouch.cc:6697 msgid "erase" msgstr "Supprimer" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "Radius du pinceau" #: f.retouch.cc:6706 msgid "transparency center" msgstr "Centre de transparence" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "Bord de transparence" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "L'annulation de la limite de mémoire a été atteinte. \n" "Enregistrer votre création avec le bouton [Ok], et résumer \n" "ensuite la modification." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Sélectionner une zone à modifier" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "" #: f.select.cc:110 msgid "draw: freehand" msgstr "Dessiner : main levée" #: f.select.cc:111 msgid "draw: follow edge" msgstr "Dessiner : suivre les contours" #: f.select.cc:114 msgid "select by mouse" msgstr "" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "" #: f.select.cc:120 msgid "match mouse color" msgstr "" #: f.select.cc:124 msgid "search range" msgstr "" #: f.select.cc:126 msgid "firewall" msgstr "" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "Dépasse de %d modifications" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" #: f.select.cc:1078 msgid "finish area" msgstr "Cloturer la zone" #: f.select.cc:1113 msgid "searching" msgstr "Rechercher" #: f.select.cc:1185 msgid "outline has a gap" msgstr "" #: f.select.cc:1189 msgid "success" msgstr "Terminé avec succès" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "La zone n'est pas bouclée" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Calcul des bords en cours" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Calcul du bord de la zone" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "Position avec un clic / glisser" #: f.select.cc:1887 msgid "Paste Image" msgstr "Coller l'image" #: f.select.cc:1901 msgid "angle" msgstr "" #: f.select.cc:2160 msgid "load select area from a file" msgstr "Charger la zone sélectionnée à partir d'un fichier" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "" #: f.select.cc:2213 msgid "save select area to a file" msgstr "" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "Sélectionner toute l'image" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "Modifier l'amplitude" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "" #: f.select.cc:2501 msgid "edge" msgstr "" #: f.select.cc:2504 msgid "reset area" msgstr "" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "" #: f.tools.cc:85 msgid "Start new collection" msgstr "" #: f.tools.cc:87 msgid "Edit a collection" msgstr "" #: f.tools.cc:89 msgid "View a collection" msgstr "" #: f.tools.cc:91 msgid "Delete a collection" msgstr "" #: f.tools.cc:95 msgid "Editing:" msgstr "" #: f.tools.cc:99 msgid "Action:" msgstr "" #: f.tools.cc:133 msgid "New Collection" msgstr "" #: f.tools.cc:156 msgid "Edit Collection" msgstr "" #: f.tools.cc:172 msgid "View Collection" msgstr "" #: f.tools.cc:193 msgid "Delete Collection" msgstr "" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "" #: f.tools.cc:256 msgid "add image to collection" msgstr "" #: f.tools.cc:301 msgid "too many saved files" msgstr "" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "" #: f.tools.cc:375 msgid "old top directory" msgstr "" #: f.tools.cc:378 msgid "new top directory" msgstr "" #: f.tools.cc:434 msgid "completed" msgstr "Complété" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "" #: f.tools.cc:474 msgid "new max. width" msgstr "Nouvelle largeur max." #: f.tools.cc:481 msgid "new file type" msgstr "" #: f.tools.cc:482 msgid "same" msgstr "" #: f.tools.cc:490 msgid "replace originals" msgstr "Remplacer les originaux" #: f.tools.cc:491 msgid "export to location" msgstr "Exporter vers l'emplacement" #: f.tools.cc:492 msgid "remove EXIF" msgstr "" #: f.tools.cc:549 msgid "Select directory" msgstr "Sélectionner un dossier" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "Remplacer les fichiers originaux ? (max. %d x %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "Copier les fichiers ? (max. %d x %d) \n" "vers l'emplacement %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "L'emplacement n'est pas un dossier valable" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "La taille max. « %d x %d » est trop grande" #: f.tools.cc:654 msgid "*** file already exists" msgstr "" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "Le logiciel « ufraw-batch » est requis." #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Ouvrir une image RAW" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "Sélectionner des fichiers RAW à convertir" #: f.tools.cc:769 msgid "Choose file type" msgstr "" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "" #: f.tools.cc:893 msgid "arrow keys" msgstr "Touche « flèches »" #: f.tools.cc:894 msgid "instant" msgstr "" #: f.tools.cc:895 msgid "fade-in" msgstr "" #: f.tools.cc:896 msgid "roll-right" msgstr "" #: f.tools.cc:897 msgid "roll-down" msgstr "" #: f.tools.cc:898 msgid "shift-left" msgstr "" #: f.tools.cc:899 msgid "venetian" msgstr "Vénitien" #: f.tools.cc:900 msgid "grate" msgstr "" #: f.tools.cc:903 msgid "radar" msgstr "" #: f.tools.cc:904 msgid "jaws" msgstr "" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Diaporama" #: f.tools.cc:915 msgid "seconds" msgstr "Secondes" #: f.tools.cc:919 msgid "music file" msgstr "" #: f.tools.cc:923 msgid "transitions" msgstr "" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "" #: f.tools.cc:1844 msgid "no new files found" msgstr "" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Dossier d'images parent : " #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Sélectionner le dossier d'images racine" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "Afficher les couleurs RVB" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "Grille" #: f.tools.cc:2728 msgid "x-spacing" msgstr "" #: f.tools.cc:2729 msgid "x-count" msgstr "" #: f.tools.cc:2730 msgid "x-enable" msgstr "" #: f.tools.cc:2736 msgid "y-spacing" msgstr "" #: f.tools.cc:2737 msgid "y-count" msgstr "" #: f.tools.cc:2738 msgid "y-enable" msgstr "" #: f.tools.cc:2745 msgid "x-offset" msgstr "" #: f.tools.cc:2749 msgid "y-offset" msgstr "" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "Envoyer les images par adresse électronique" #: f.tools.cc:2947 msgid "max. width" msgstr "Largeur max." #: f.tools.cc:2948 msgid "max. height" msgstr "Hauteur max." #: f.tools.cc:3093 msgid "too many files" msgstr "Trop de fichiers" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" #: f.tools.cc:3174 msgid "Monitor Check" msgstr "" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "Distribution de la luminosité" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Traductions disponibles" #: f.tools.cc:3436 msgid "Set Language" msgstr "Changer de langue" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "Texte" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "Utilisez les boutons ou glissez le bord droit avec la souris" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Pivoter l'image" #: f.transform.cc:64 msgid "degrees" msgstr "Degrés" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Rogner" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Annuler Rogner" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "Degrés :  %.1f" #: f.transform.cc:286 msgid "gold" msgstr "" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "" "Glissez le centre pour déplacer, glissez les coins pour redimensionner." #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Rogner" #: f.transform.cc:348 msgid "customize" msgstr "Personnaliser" #: f.transform.cc:359 msgid "ratio" msgstr "" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "Verrouiller les proportions" #: f.transform.cc:368 msgid "invert" msgstr "inverser" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "Verrouiller les proportions" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Redimensionner l'image" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Préc." #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" "Saisissez du texte, cliquez et glissez sur l'image.\n" "Un clic-droit supprime le texte." #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "Annoter l'image" #: f.transform.cc:1307 msgid "Size" msgstr "Taille" #: f.transform.cc:1310 msgid "Angle" msgstr "Angle" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Couleur" #: f.transform.cc:1322 msgid "Transparency" msgstr "Transparence" #: f.transform.cc:1325 msgid "text" msgstr "" #: f.transform.cc:1330 msgid "backing" msgstr "" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" #: f.transform.cc:1335 msgid "outline" msgstr "" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "Annoter le fichier" #: f.transform.cc:1416 msgid "select font" msgstr "Sélectionner la police" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "Retourner l'image" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "Horizontal" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "Vertical" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "Négatif" #: f.transform.cc:2158 msgid "black/white positive" msgstr "" #: f.transform.cc:2159 msgid "black/white negative" msgstr "" #: f.transform.cc:2160 msgid "color positive" msgstr "" #: f.transform.cc:2161 msgid "color negative" msgstr "" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Redresser" #: f.transform.cc:2282 msgid "linear" msgstr "" #: f.transform.cc:2285 msgid "curved" msgstr "" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" "Sélectionner une zone à déformer en utilisant dans \n" "le menu Édition / Édition de la zone / Sélectionner une zone. \n" "Appuyer sur [Commencer] et étirez la zone avec la souris. \n" "Effectuez des déformations jusqu'à satisfaction. \n" "Ensuite, sélectionnez une autre zone ou cliquez sur [Ok]." #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "Déformer l'image (zone)" #: f.transform.cc:2864 msgid "start warp" msgstr "Commencer" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Tirez l'image en utilisant la souris. \n" " Effectuez plusieurs fois le processus \n" " jusqu'à satisfaction et cliquez sur [Ok] \n" " pour terminer." #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "Déformer l'image (courbé)" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "Déformer l'image (linéaire)" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" "Tirez un bord de l'image en utilisant la souris. \n" "Répétez plusieurs fois l'opération jusqu'à satisfaction. \n" "Une fois terminé, appuyez sur [Ok]." #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "Déformer l'image (affiné)" #: fotoxx-12.01.cc:185 msgid "File" msgstr "Fichier" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "Parcourir les miniatures" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Afficher l'image précédente" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "Ouvrir un fichier récent" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "Enregistrer" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "Enregistrer sous" #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "Supprimer l'image" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "Renommer des fichiers par lot" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Imprimer une image" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "Quitter Fotoxx" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "Outils" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "Convertir des fichiers RAW" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "Graver les images vers un CD / DVD" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Vérifier l'écran" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Changer de langue" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "Afficher les informations (résumé)" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "Afficher les informations (complet)" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "Rechercher des images" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "Sélectionner" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Afficher" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Cacher" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "Activer" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "Désactiver" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Inverser" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "Copier" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "Coller" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Enreg." #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "Transformer" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Retoucher" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "Luminosité et couleur" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "Améliorer la luminosité" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "Luminosité aplanie" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "Luminosité : correction" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "Balance des blancs" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Yeux rouges" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Flou" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Réduction du bruit" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Art" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Profondeur de couleurs" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "Dessin" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "Gaufrage" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "Tuiles" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "Points" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "Peinture" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Combiner" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Panorama" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Aide" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "à propos" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "Documentation" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Modifications" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "Site web" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "Miniatures" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Suiv." #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Afficher l'image suivante" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Agrandir" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Réduire" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Undo" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Annuler une modification" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Redo" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Rétablir une modification" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "Déplacer l'image vers la corbeille" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "Suppr." #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Quit." #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "Guide de l'utilisateur" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "Dépasse de 50 points d'ancrage" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "Le paquetage « exiftool » n'est pas installé \n" "Les images modifiées perdront leurs données Exif" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "Trop de modifications, veuillez enregistrer l'image" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Impossible de conserver la sélection de la zone.\n" "Voulez-vous continuer ?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" "La zone sélectionnée n'est \n" "pas active. Continuer ?" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "Impossible d'ouvrir le fichier de miniatures" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "Impossible d'ouvrir le fichier TIFF" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF bits/color=%d n'est pas pris en charge" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "Impossible de lire le fichier TIFF" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "Impossible d'écrire le fichier TIFF" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "Ce type de fichier n'est pas pris en charge" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "Échec d'écriture pixbuf" #: fotoxx.h:728 msgid "absolute" msgstr "" #: fotoxx.h:730 msgid "Add All" msgstr "Tout ajouter" #: fotoxx.h:732 msgid "Amount" msgstr "Quantité" #: fotoxx.h:733 msgid "Apply" msgstr "Appliquer" #: fotoxx.h:734 msgid "Black" msgstr "" #: fotoxx.h:735 msgid "Blend Width" msgstr "Largeur du mélange" #: fotoxx.h:737 msgid "Brightness" msgstr "Luminosité" #: fotoxx.h:738 msgid "Browse" msgstr "Naviguer" #: fotoxx.h:739 msgid "Cancel" msgstr "Annuler" #: fotoxx.h:740 msgid "Clear" msgstr "Effacer" #: fotoxx.h:742 msgid "Commit" msgstr "" #: fotoxx.h:744 msgid "Curve File:" msgstr "" #: fotoxx.h:745 msgid "Cut" msgstr "" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Zones sombres" #: fotoxx.h:747 msgid "Delete" msgstr "Supprimer" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" #: fotoxx.h:750 msgid "Done" msgstr "Ok" #: fotoxx.h:751 msgid "Edit" msgstr "Modifier" #: fotoxx.h:753 msgid "Erase" msgstr "" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "Le paquetage « libimage-exiftool-perl » est requis" #: fotoxx.h:755 msgid "Fetch" msgstr "Réception" #: fotoxx.h:756 msgid "Finish" msgstr "Terminer" #: fotoxx.h:757 msgid "Font" msgstr "Police" #: fotoxx.h:759 msgid "Height" msgstr "Hauteur" #: fotoxx.h:760 msgid "histogram" msgstr "Histogramme" #: fotoxx.h:762 msgid "Insert" msgstr "Insérer" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Zones lumineuses" #: fotoxx.h:765 msgid "limit" msgstr "Limiter" #: fotoxx.h:766 msgid "New" msgstr "" #: fotoxx.h:768 msgid "OK" msgstr "Ok" #: fotoxx.h:772 msgid "Pause" msgstr "Pause" #: fotoxx.h:773 msgid "Percent" msgstr "pourcentage" #: fotoxx.h:774 msgid "Presets" msgstr "Réglages" #: fotoxx.h:775 msgid "Proceed" msgstr "Traiter" #: fotoxx.h:777 msgid "range" msgstr "Plage" #: fotoxx.h:780 msgid "Reduce" msgstr "Réduire" #: fotoxx.h:782 msgid "Reset" msgstr "" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "" "Type de fichier inconnu. Enregistrez le au format TIFF/JPEG/PNG pour le " "modifier" #: fotoxx.h:785 msgid "Search" msgstr "Rechercher" #: fotoxx.h:789 msgid "Start" msgstr "Démarrer" #: fotoxx.h:790 msgid "Threshold" msgstr "Seuil" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "Tout annuler" #: fotoxx.h:793 msgid "Undo Last" msgstr "Annul. préc." #: fotoxx.h:795 msgid "Unfinish" msgstr "" #: fotoxx.h:797 msgid "View" msgstr "" #: fotoxx.h:798 msgid "White" msgstr "" #: fotoxx.h:799 msgid "Width" msgstr "Largeur" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "impossible de trouver le fichier d'aide : %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "Impossible d'ouvrir le fichier %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "Enregistrer l'écran dans un fichier" #: zfuncs.cc:6222 msgid "No" msgstr "" #: zfuncs.cc:6222 msgid "Yes" msgstr "" #: zfuncs.cc:6447 msgid "open" msgstr "Ouvrir" #: zfuncs.cc:6452 msgid "choose" msgstr "" #: zfuncs.cc:6457 msgid "save" msgstr "Enregistrer" #: zfuncs.cc:6463 msgid "open folder" msgstr "Ouvrir" #: zfuncs.cc:6468 msgid "create folder" msgstr "Créer un dossier" #: zfuncs.cc:6474 msgid "hidden" msgstr "Caché" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "Qualité JPG 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "" #: zfuncs.cc:6737 msgid "top" msgstr "" #: zfuncs.cc:6738 msgid "bottom" msgstr "" #: zfuncs.cc:6739 msgid "left" msgstr "" #: zfuncs.cc:6740 msgid "right" msgstr "" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Le fichier des paramètres initiaux a été crée. \n" "Vérifier et corriger si nécessaire." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "Charger les paramètres à partir d'un fichier" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "Enregistrer les paramètres dans un fichier" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "Éditer les paramètres" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "Lister\n" "Tous" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "Charger\n" "Fichier" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "Enreg.\n" "Fichier" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "Ajouter\n" "Nouveau" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "Appliquer" #: zfuncs.cc:7479 msgid "apply?" msgstr "Appliquer ?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(Nouveaux paramètres)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "Ajouter le paramètre" #~ msgid "Brightness Graph" #~ msgstr "Diagramme de luminosité" #~ msgid "radius" #~ msgstr "Radius" #~ msgid "match" #~ msgstr "Correspondance" #~ msgid "Search results file error %s" #~ msgstr "Erreur de fichier des résultats recherchés %s" #~ msgid "Batch Resize" #~ msgstr "Redimensionner par lot" #~ msgid "new max. height" #~ msgstr "Nouvelle hauteur max." #~ msgid "copy EXIF" #~ msgstr "Copier les données EXIF" #~ msgid "new file already exists" #~ msgstr "Un nouveau fichier existe toujours" #~ msgid "Select area first" #~ msgstr "Sélectionnez une zone en premier." #~ msgid "Translate" #~ msgstr "Traduire" #~ msgid "full rebuild" #~ msgstr "Reconstruction complète" #~ msgid "incremental" #~ msgstr "Incrémental" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "Le renommage a échoué \n" #~ " %s" #~ msgid "transition" #~ msgstr "Transition" #~ msgid "Discard modifications?" #~ msgstr "Annuler les modifications ?" #~ msgid "Edit Comments" #~ msgstr "Modifier les commentaires" #~ msgid "Edit Caption" #~ msgstr "Modifier la légende" #~ msgid "new tags index will now be created" #~ msgstr "" #~ "Le nouveau fichier d'indexation des étiquettes \n" #~ "va maintenant être créé." #~ msgid "cannot read .dist file" #~ msgstr "Impossible de lire le fichier .dist" #~ msgid "" #~ "New tags file already exists! \n" #~ "Proceed anyway?" #~ msgstr "" #~ "Le fichier des nouvelles étiquettes existe toujours ! \n" #~ "Voulez vous continuer le processus ?" #~ msgid "" #~ "Convert tags to new standard now? \n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Convertir maintenant les étiquettes vers le nouveau standard ? \n" #~ "Vos images sont-elles sauvegardées ?" #~ msgid "Convert tags to new standard" #~ msgstr "Convertir les étiquettes vers le nouveau standard" #~ msgid "Convert Tags !!!" #~ msgstr "Convertir les étiquettes !!!" #~ msgid "tags index file error: %s" #~ msgstr "" #~ "Le fichier d'indexation des étiquettes \n" #~ "retourne une erreur : %s" #~ msgid "save select area as a file" #~ msgstr "Enregistrer la zone sélectionnée en tant que fichier" #~ msgid "manage tags" #~ msgstr "Gérer les étiquettes" #~ msgid "brightness to clip (percent)" #~ msgstr "Luminosité à remplir (pourcentage)" #~ msgid "Use F1 for context help" #~ msgstr "Utiliser F1 pour l'aide contextuel" #~ msgid "Stack" #~ msgstr "Empiler" #~ msgid "Rebuild Tags Index" #~ msgstr "Reconstruire l'index des étiquettes" #~ msgid "No tags index file" #~ msgstr "Le fichier d'indexation des étiquettes n'existe pas." #~ msgid "HDR" #~ msgstr "HDR" #~ msgid "HDF" #~ msgstr "HDF" #~ msgid "Constrain" #~ msgstr "Contraindre" #~ msgid "Area" #~ msgstr "Zone" #~ msgid "target group area" #~ msgstr "Zone du groupe cible" #~ msgid "vertical unbend" #~ msgstr "Axe vertical" #~ msgid "select by mouse:" #~ msgstr "Sélection avec la souris : " #~ msgid "select by color:" #~ msgstr "Sélection par couleurs : " #~ msgid "press ESC to exit" #~ msgstr "Appuyer sur « Échap » pour quitter" #~ msgid "horizontal unbend" #~ msgstr "Axe horizontal" #~ msgid "Rebuild Thumbnails" #~ msgstr "Reconstruire les miniatures" #~ msgid "Font Colors" #~ msgstr "Couleur de la police" #~ msgid "area outline has a hole" #~ msgstr "Le contour de la zone a un trou" #~ msgid "Create Launcher" #~ msgstr "Créer un lanceur" #~ msgid "make new version" #~ msgstr "Créer une nouvelle version" #~ msgid "click on window to show RGB" #~ msgstr "Cliquez sur la fenêtre pour afficher les couleurs RVB" #~ msgid "Save As" #~ msgstr "Enreg. sous" #~ msgid "Clone fotoxx" #~ msgstr "Cloner Fotoxx" #~ msgid "random" #~ msgstr "Aléatoire" #~ msgid "Whole Image" #~ msgstr "Toute l'image" #~ msgid "Time Interval" #~ msgstr "Intervalle de temps" #~ msgid "print" #~ msgstr "Imprimer" #~ msgid "printer ID" #~ msgstr "ID de l'imprimante" #~ msgid "paper format" #~ msgstr "Format de papier" #~ msgid "portrait" #~ msgstr "Portrait" #~ msgid "landscape" #~ msgstr "Paysage" #~ msgid "paper format is crazy" #~ msgstr "Format de papier erroné" #~ msgid "open a file" #~ msgstr "Ouvrir un fichier" #~ msgid "select new folder" #~ msgstr "Sélectionner un nouveau dossier" #~ msgid "open a directory" #~ msgstr "Ouvrir un dossier" #~ msgid "folder" #~ msgstr "Dossier" #~ msgid "select new file" #~ msgstr "Sélectionner un nouveau fichier" #~ msgid "lens name" #~ msgstr "nom de la focale" #~ msgid "my mouse" #~ msgstr "Ma souris" #~ msgid "Lens Parameters" #~ msgstr "Configuration de l'objectif" fotoxx-12.01.2/locales/fotoxx-ru.po0000664000175000017500000016122411701011017015576 0ustar micomico# Russian translations for home package. # Copyright (C) 2010 by Redf # This file is distributed under the same license as the home package. # Redf , 2010. # msgid "" msgstr "" "Project-Id-Version: home 2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:05+0100\n" "PO-Revision-Date: 2010-05-12 10:15+0200\n" "Last-Translator: redf \n" "Language-Team: Russian\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr " УÑтановить глубину цвета в диапазоне от 1 до 16 бит " #: f.art.cc:57 msgid "Set Color Depth" msgstr "УÑтановка глубины цвета" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Имитировать риÑунок" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr " КонтраÑÑ‚" #: f.art.cc:215 msgid "outlines" msgstr "Контур" #: f.art.cc:220 msgid "pencil" msgstr "Карандаш" #: f.art.cc:221 msgid "chalk" msgstr "Мелок" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "" #: f.art.cc:394 msgid "outline threshold" msgstr "" #: f.art.cc:397 msgid "outline width" msgstr "" #: f.art.cc:400 msgid "image brightness" msgstr "" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Имитировать чеканку" #: f.art.cc:626 msgid "depth" msgstr "Глубина" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "Цвет" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Имитировать мозаику" #: f.art.cc:825 msgid "tile size" msgstr "Размер Ñлементов" #: f.art.cc:829 msgid "tile gap" msgstr "Промежутки" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "" #: f.art.cc:1007 msgid "dot size" msgstr "" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Имитировать живопиÑÑŒ" #: f.art.cc:1226 msgid "color depth" msgstr "Глубина цвета" #: f.art.cc:1230 msgid "patch area goal" msgstr "" #: f.art.cc:1234 msgid "req. color match" msgstr "Цвета" #: f.art.cc:1238 msgid "borders" msgstr " Рамки" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Bilder sind nicht gleich gross" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "Темные пикÑели" #: f.comp.cc:2326 msgid "light pixels" msgstr "Светлые пикÑелы" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "Файл:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "РиÑовать" #: f.comp.cc:2851 msgid "warp" msgstr "" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Предварительно выравненные" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "ФокуÑное раÑÑтоÑние, мм" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "Lens bow" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "" #: f.comp.cc:4457 msgid "use two images only" msgstr "" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Слишком маленькое наложение, выравнÑть не возможно" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Открыть" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "" #: f.file.cc:504 msgid "Do not warn again" msgstr "" #: f.file.cc:520 msgid "Warning" msgstr "" #: f.file.cc:643 msgid "Save File" msgstr "Сохранить в файл" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "" #: f.file.cc:668 msgid "make current" msgstr "" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "КачеÑтво jpeg должно быть от 1 до 100" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "ПерепиÑать файл? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "" #: f.file.cc:905 msgid "file name" msgstr "" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "ПеремеÑтить изображение в корзину?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "Ðе могу Ñоздать папку: %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "Ошибка: %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Переименовать" #: f.file.cc:1141 msgid "old name" msgstr "Старое имÑ" #: f.file.cc:1142 msgid "rename to" msgstr "Переименовать в" #: f.file.cc:1143 msgid "previous" msgstr "Предыдущий" #: f.file.cc:1229 msgid "The target file already exists" msgstr "Такой файл уже открыт" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" #: f.file.cc:1285 msgid "Batch Rename" msgstr "Групповое переименование" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "" #: f.file.cc:1290 msgid "new base name" msgstr "ПрефикÑ" #: f.file.cc:1293 msgid "starting sequence" msgstr "Ðачальный номер" #: f.file.cc:1295 msgid "increment" msgstr "Дополнительный номер" #: f.file.cc:1316 msgid "select files to rename" msgstr "Выберите файлы Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr " Ðеправильный Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ / начальный номер / дополнительный номер" #: f.file.cc:1380 msgid "new file already exists:" msgstr "Ðовый файл уже открыт:" #: f.file.cc:1388 msgid "filespec too long:" msgstr "Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ñлишком длинное:" #: f.file.cc:1399 msgid "Rename failed:" msgstr "Переименование оÑтановлено:" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "" #: f.file.cc:1662 msgid "menu name" msgstr "" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Редактировать теги" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "Дата (ггггммдд)" #: f.info.cc:165 msgid "use last" msgstr "ИÑпользовать поÑледний" #: f.info.cc:168 msgid "image stars" msgstr "Рейтинг" #: f.info.cc:186 msgid "current tags" msgstr "Текущий тег" #: f.info.cc:191 msgid "recent tags" msgstr "" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "" #: f.info.cc:348 msgid "category" msgstr "" #: f.info.cc:351 msgid "tag" msgstr "" #: f.info.cc:354 msgid "create" msgstr "" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "Групповое добавление тегов" #: f.info.cc:1354 msgid "tags to add" msgstr "Теги Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ" #: f.info.cc:1359 msgid "create tag" msgstr "Создать тег" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "" #: f.info.cc:1556 msgid "tag to remove" msgstr "" #: f.info.cc:1560 msgid "optional replacement" msgstr "" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "" #: f.info.cc:1568 msgid "search all files" msgstr "" #: f.info.cc:1653 msgid "no files selected" msgstr "" #: f.info.cc:1659 msgid "no tag specified" msgstr "" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "" #: f.info.cc:1821 msgid "View Info" msgstr "" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "Ð’Ñе" #: f.info.cc:1990 msgid "One Key:" msgstr "Один Key:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "" #: f.info.cc:2350 msgid "date range" msgstr "Диапазон дат" #: f.info.cc:2351 msgid "stars range" msgstr "Рейтинг" #: f.info.cc:2352 msgid "search tags" msgstr "ПоиÑк тегов" #: f.info.cc:2353 msgid "search text" msgstr "" #: f.info.cc:2354 msgid "file names" msgstr "" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "" #: f.info.cc:2365 msgid "all/any" msgstr "" #: f.info.cc:2702 msgid "No matching images found" msgstr "Ðет ÑÑответÑтвующих изображений" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "Увеличить" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "Увеличить" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "Уменьшить" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "Уменьшить" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "Ðаверх" #: f.navi.cc:190 msgid "parent directory" msgstr "Директорией выше" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "ÐŸÐµÑ€Ð²Ð°Ñ Ñтраница" #: f.navi.cc:191 msgid "jump to first file" msgstr "К первому файлу" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ñтраница" #: f.navi.cc:192 msgid "previous page" msgstr "ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ñтраница" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "Предыдущий Ñ€Ñд" #: f.navi.cc:193 msgid "previous row" msgstr "Предыдущий Ñ€Ñд" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "Следующий Ñ€Ñд" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ñтраница" #: f.navi.cc:195 msgid "ttip::next page" msgstr "" #: f.navi.cc:196 msgid "jump to last file" msgstr "К поÑледнему файлу" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "ПоÑледнÑÑ Ñтраница" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "Закрыть" #: f.navi.cc:197 msgid "close image gallery" msgstr "Закрыть галерею" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "Отменить" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "" #: f.navi.cc:1422 msgid "insert" msgstr "" #: f.navi.cc:1423 msgid "add all" msgstr "" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "ЯркоÑть и цветноÑть" #: f.retouch.cc:110 msgid "small-steps" msgstr "" #: f.retouch.cc:119 msgid "color saturation" msgstr "Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð½Ð°ÑыщенноÑть" #: f.retouch.cc:126 msgid " reset 1 " msgstr "СброÑить один" #: f.retouch.cc:127 msgid "reset all" msgstr "СброÑить вÑе" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "РаÑширение ÑркоÑти" #: f.retouch.cc:887 msgid "bright pixels" msgstr "Яркие пикÑели" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "ВыравнÑть ÑркоÑть" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Выравнивание" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "РаÑпределение ÑркоÑти вокруг изображениÑ" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "Тональное отображение" #: f.retouch.cc:1758 msgid "low" msgstr "" #: f.retouch.cc:1760 msgid "high" msgstr "" #: f.retouch.cc:1763 msgid "Amplify" msgstr "" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Кликните по белому или Ñерому" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Открыть" #: f.retouch.cc:2310 msgid "image for source color" msgstr "" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "КраÑный" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Зеленый" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Синий" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "" #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "" #: f.retouch.cc:3084 msgid "Metric:" msgstr "" #: f.retouch.cc:3139 msgid "Blend" msgstr "" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" " Метод 1:\n" " Кликните левой кнопкой мышки на краÑных глазах.\n" " Метод 2:\n" " Протащите курÑор вниз-вправо.\n" " Кликните левой кнопкой мышки на краÑных глазах.\n" " Отменить:\n" " Кликните правой кнопкой мышки на краÑных глазах." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Уменьшение Ñффекта краÑных глаз" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Размыть" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Увеличить резкоÑть" #: f.retouch.cc:4202 msgid "edge detection" msgstr "Обнаружение краÑ" #: f.retouch.cc:4203 msgid "cycles" msgstr "Циклы" #: f.retouch.cc:4204 msgid "reduce" msgstr "Уменьшить" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "МаÑка резкоÑти" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "Переход ÑркоÑти" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Ðажмите кнопку [Уменьшить] \n" " Ð´Ð»Ñ ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ ÑˆÑƒÐ¼Ð°." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Шумоподавление" #: f.retouch.cc:4650 msgid "algorithm" msgstr "Ðлгоритм" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "Flatten outliers by color (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "Flatten outliers by color (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "Set median brightness by color" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "Top hat аilter by color" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "РадиуÑ" #: f.retouch.cc:5005 msgid "Blur" msgstr "" #: f.retouch.cc:5008 msgid "New Area" msgstr "" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "" #: f.retouch.cc:5989 msgid "pixel group" msgstr "" #: f.retouch.cc:5990 msgid "circle color" msgstr "" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "" #: f.retouch.cc:6164 msgid "file format error" msgstr "" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "ПамÑть %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Редактировать изображение" #: f.retouch.cc:6695 msgid "pick" msgstr "Выбрать" #: f.retouch.cc:6697 msgid "erase" msgstr "Стереть" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "Ð Ð°Ð´Ð¸ÑƒÑ ÐºÐ¸Ñти" #: f.retouch.cc:6706 msgid "transparency center" msgstr "Центр" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "Край" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Превышен лимит памÑти (200 MB) \n" "Сохраните Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸ продолжайте" #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Выбрать облаÑть Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "" #: f.select.cc:110 msgid "draw: freehand" msgstr "" #: f.select.cc:111 msgid "draw: follow edge" msgstr "" #: f.select.cc:114 msgid "select by mouse" msgstr "" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "" #: f.select.cc:120 msgid "match mouse color" msgstr "" #: f.select.cc:124 msgid "search range" msgstr "" #: f.select.cc:126 msgid "firewall" msgstr "" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "%d превышений редактированиÑ" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" #: f.select.cc:1078 msgid "finish area" msgstr "ÐšÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть" #: f.select.cc:1113 msgid "searching" msgstr "ПоиÑк" #: f.select.cc:1185 msgid "outline has a gap" msgstr "" #: f.select.cc:1189 msgid "success" msgstr "Готово" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "ОблаÑть не выбрана" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "ВычиÑлÑем..." #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "РаÑчет облаÑти" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "" #: f.select.cc:1887 msgid "Paste Image" msgstr "Ð’Ñтавить изображение" #: f.select.cc:1901 msgid "angle" msgstr "" #: f.select.cc:2160 msgid "load select area from a file" msgstr "Загрузить выбранную облаÑть из файла" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "" #: f.select.cc:2213 msgid "save select area to a file" msgstr "" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "" #: f.select.cc:2501 msgid "edge" msgstr "" #: f.select.cc:2504 msgid "reset area" msgstr "" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "" #: f.tools.cc:85 msgid "Start new collection" msgstr "" #: f.tools.cc:87 msgid "Edit a collection" msgstr "" #: f.tools.cc:89 msgid "View a collection" msgstr "" #: f.tools.cc:91 msgid "Delete a collection" msgstr "" #: f.tools.cc:95 msgid "Editing:" msgstr "" #: f.tools.cc:99 msgid "Action:" msgstr "" #: f.tools.cc:133 msgid "New Collection" msgstr "" #: f.tools.cc:156 msgid "Edit Collection" msgstr "" #: f.tools.cc:172 msgid "View Collection" msgstr "" #: f.tools.cc:193 msgid "Delete Collection" msgstr "" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "" #: f.tools.cc:256 msgid "add image to collection" msgstr "" #: f.tools.cc:301 msgid "too many saved files" msgstr "" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "" #: f.tools.cc:375 msgid "old top directory" msgstr "" #: f.tools.cc:378 msgid "new top directory" msgstr "" #: f.tools.cc:434 msgid "completed" msgstr "Сделано" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "" #: f.tools.cc:474 msgid "new max. width" msgstr "" #: f.tools.cc:481 msgid "new file type" msgstr "" #: f.tools.cc:482 msgid "same" msgstr "" #: f.tools.cc:490 msgid "replace originals" msgstr "" #: f.tools.cc:491 msgid "export to location" msgstr "" #: f.tools.cc:492 msgid "remove EXIF" msgstr "" #: f.tools.cc:549 msgid "Select directory" msgstr "" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "" #: f.tools.cc:654 msgid "*** file already exists" msgstr "" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Открыть RAW-файл" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "Выбрать RAW-файлы Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ð¸Ð¸" #: f.tools.cc:769 msgid "Choose file type" msgstr "" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "" #: f.tools.cc:893 msgid "arrow keys" msgstr "" #: f.tools.cc:894 msgid "instant" msgstr "" #: f.tools.cc:895 msgid "fade-in" msgstr "" #: f.tools.cc:896 msgid "roll-right" msgstr "" #: f.tools.cc:897 msgid "roll-down" msgstr "" #: f.tools.cc:898 msgid "shift-left" msgstr "" #: f.tools.cc:899 msgid "venetian" msgstr "" #: f.tools.cc:900 msgid "grate" msgstr "" #: f.tools.cc:903 msgid "radar" msgstr "" #: f.tools.cc:904 msgid "jaws" msgstr "" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Слайд-шоу" #: f.tools.cc:915 msgid "seconds" msgstr "Секунд" #: f.tools.cc:919 msgid "music file" msgstr "" #: f.tools.cc:923 msgid "transitions" msgstr "" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "" #: f.tools.cc:1844 msgid "no new files found" msgstr "" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Папка Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñми" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Выбор папки" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "Показать RGB" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "Сетка" #: f.tools.cc:2728 msgid "x-spacing" msgstr "" #: f.tools.cc:2729 msgid "x-count" msgstr "" #: f.tools.cc:2730 msgid "x-enable" msgstr "" #: f.tools.cc:2736 msgid "y-spacing" msgstr "" #: f.tools.cc:2737 msgid "y-count" msgstr "" #: f.tools.cc:2738 msgid "y-enable" msgstr "" #: f.tools.cc:2745 msgid "x-offset" msgstr "" #: f.tools.cc:2749 msgid "y-offset" msgstr "" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "" #: f.tools.cc:2947 msgid "max. width" msgstr "" #: f.tools.cc:2948 msgid "max. height" msgstr "" #: f.tools.cc:3093 msgid "too many files" msgstr "" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" #: f.tools.cc:3174 msgid "Monitor Check" msgstr "" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "РаÑпределение ÑркоÑти" #: f.tools.cc:3432 msgid "Available Translations" msgstr "ДоÑтупен перевод" #: f.tools.cc:3436 msgid "Set Language" msgstr "УÑтановка Ñзыка" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr " ПользуйтеÑÑŒ кнопками или тащите мышью " #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Повернуть изображение" #: f.transform.cc:64 msgid "degrees" msgstr "ГрадуÑÑ‹" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Кадрировать" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Отменить" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "ГрадуÑÑ‹: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "" #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Кадрировать" #: f.transform.cc:348 msgid "customize" msgstr "" #: f.transform.cc:359 msgid "ratio" msgstr "" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "ФикÑировать Ñоотношение Ñторон" #: f.transform.cc:368 msgid "invert" msgstr "" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "ФикÑировать пропорции" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Изменить размер изображениÑ" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Предыдущий" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "" #: f.transform.cc:1307 msgid "Size" msgstr "" #: f.transform.cc:1310 msgid "Angle" msgstr "" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Цвет" #: f.transform.cc:1322 msgid "Transparency" msgstr "" #: f.transform.cc:1325 msgid "text" msgstr "" #: f.transform.cc:1330 msgid "backing" msgstr "" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" #: f.transform.cc:1335 msgid "outline" msgstr "" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "" #: f.transform.cc:1416 msgid "select font" msgstr "" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "Зеркальное изображение" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "Горизонталь" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "Вертикаль" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "" #: f.transform.cc:2158 msgid "black/white positive" msgstr "" #: f.transform.cc:2159 msgid "black/white negative" msgstr "" #: f.transform.cc:2160 msgid "color positive" msgstr "" #: f.transform.cc:2161 msgid "color negative" msgstr "" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Изогнуть" #: f.transform.cc:2282 msgid "linear" msgstr "" #: f.transform.cc:2285 msgid "curved" msgstr "" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" " Выберите облаÑть Ð´Ð»Ñ Ð´ÐµÑ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ \n" " Ðажмите [Деформировать] \n" " УправлÑйте процеÑÑом при помощи мышки \n" " Выберите новую облаÑть или нажмите [Применить]" #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "" #: f.transform.cc:2864 msgid "start warp" msgstr "Деформировать" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Корректируйте перÑпективу при помощи мышки \n" " По окончании нажмите [Применить]" #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "Корректировать перÑпективу (affine)" #: fotoxx-12.01.cc:185 msgid "File" msgstr "Файл" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "ГалереÑ" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Открыть предыдущий файл" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "Открыть поÑледний" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "Сохранить" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "Сохранить как..." #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "ПомеÑтить в корзину" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "Групповое переименование" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Печать" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "Выход из fotoxx" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "ИнÑтрументы" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "Конвертировать RAW-файлы" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "ЗапиÑать на CD/DVD" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Отображение цветов" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Изменить Ñзык" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "Выбрать" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Показать" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Скрыть" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "ДоÑтупно" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "Ðе доÑтупно" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Инвертировать" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "Копировать" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "Ð’Ñтавить" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Сохранить" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "Изменить" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Ретушировать" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "ЯркоÑть и цветноÑть" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "РаÑширение ÑркоÑти" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "ВыравнÑть ÑркоÑть" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "РаÑпределение ÑркоÑти" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Эффект краÑных глаза" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Размыть" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Уменьшить шум" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Эффекты" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Глубина цвета" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Комбинировать" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Панорама" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Помощь" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "О fotoxx" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "РуководÑтво пользователÑ" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Журнал изменений" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "ДомашнÑÑ Ñтраница" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "ГалереÑ" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Дальше" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Открыть Ñледующий файл" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Увеличить" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Уменьшить" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Отменить" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Отменить" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Применить" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Применить отмененное" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "ПеремеÑтить изображение в корзину" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "МуÑор" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Выход" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "ТребуетÑÑ Ð±Ð¾Ð»ÐµÐµ 50 точек" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "EXIFtool не уÑтановлен \n" "будут потерÑны данные EXIF" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "Слишком много изменений, пожалуйÑта Ñограните изображение" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть не Ñохранена.\n" "Продолжить?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" "Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть не активна.\n" "Продолжить?" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "не могу найти файл" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "TIFF ошибка открытиÑ" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "TIFF ошибка чтениÑ" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "TIFF ошибка запиÑи" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "Этот формат файлов не поддерживаетÑÑ" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "Pixbuf - ошибка запиÑи" #: fotoxx.h:728 msgid "absolute" msgstr "" #: fotoxx.h:730 msgid "Add All" msgstr "Добавить вÑе" #: fotoxx.h:732 msgid "Amount" msgstr "КоличеÑтво" #: fotoxx.h:733 msgid "Apply" msgstr "Применить" #: fotoxx.h:734 msgid "Black" msgstr "" #: fotoxx.h:735 msgid "Blend Width" msgstr "Ширина перекрытиÑ" #: fotoxx.h:737 msgid "Brightness" msgstr "ЯркоÑть" #: fotoxx.h:738 msgid "Browse" msgstr "" #: fotoxx.h:739 msgid "Cancel" msgstr "Отмена" #: fotoxx.h:740 msgid "Clear" msgstr "ОчиÑтить" #: fotoxx.h:742 msgid "Commit" msgstr "" #: fotoxx.h:744 msgid "Curve File:" msgstr "" #: fotoxx.h:745 msgid "Cut" msgstr "" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Темные облаÑти" #: fotoxx.h:747 msgid "Delete" msgstr "Удалить" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" #: fotoxx.h:750 msgid "Done" msgstr "Применить" #: fotoxx.h:751 msgid "Edit" msgstr "Редактировать" #: fotoxx.h:753 msgid "Erase" msgstr "" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "" #: fotoxx.h:755 msgid "Fetch" msgstr "Получить" #: fotoxx.h:756 msgid "Finish" msgstr "Финиш" #: fotoxx.h:757 msgid "Font" msgstr "" #: fotoxx.h:759 msgid "Height" msgstr "Ð’Ñ‹Ñота" #: fotoxx.h:760 msgid "histogram" msgstr "ГиÑтограмма" #: fotoxx.h:762 msgid "Insert" msgstr "Ð’Ñтавить" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Светлые облаÑти" #: fotoxx.h:765 msgid "limit" msgstr "Лимит" #: fotoxx.h:766 msgid "New" msgstr "" #: fotoxx.h:768 msgid "OK" msgstr "Ok" #: fotoxx.h:772 msgid "Pause" msgstr "Пауза" #: fotoxx.h:773 msgid "Percent" msgstr "%" #: fotoxx.h:774 msgid "Presets" msgstr "ПреÑеты" #: fotoxx.h:775 msgid "Proceed" msgstr "Ðачать" #: fotoxx.h:777 msgid "range" msgstr "РаÑÑтоÑние" #: fotoxx.h:780 msgid "Reduce" msgstr "Уменьшить" #: fotoxx.h:782 msgid "Reset" msgstr "" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "ÐеизвеÑтный тип файла, Ñохраните как tiff/jpeg/png Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ" #: fotoxx.h:785 msgid "Search" msgstr "ПоиÑк" #: fotoxx.h:789 msgid "Start" msgstr "Старт" #: fotoxx.h:790 msgid "Threshold" msgstr "Порог" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "Отменить вÑе" #: fotoxx.h:793 msgid "Undo Last" msgstr "Отменить поÑледнее" #: fotoxx.h:795 msgid "Unfinish" msgstr "" #: fotoxx.h:797 msgid "View" msgstr "" #: fotoxx.h:798 msgid "White" msgstr "" #: fotoxx.h:799 msgid "Width" msgstr "Ширина" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "Файл помощи %s не найден" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "Ðе могу открыть файл %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "Сохранить изображение в файл" #: zfuncs.cc:6222 msgid "No" msgstr "" #: zfuncs.cc:6222 msgid "Yes" msgstr "" #: zfuncs.cc:6447 msgid "open" msgstr "Открыть" #: zfuncs.cc:6452 msgid "choose" msgstr "" #: zfuncs.cc:6457 msgid "save" msgstr "Сохранить" #: zfuncs.cc:6463 msgid "open folder" msgstr "Открыть папку" #: zfuncs.cc:6468 msgid "create folder" msgstr "Создать папку" #: zfuncs.cc:6474 msgid "hidden" msgstr "Скрыть" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "КачеÑтво JPG 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "" #: zfuncs.cc:6737 msgid "top" msgstr "" #: zfuncs.cc:6738 msgid "bottom" msgstr "" #: zfuncs.cc:6739 msgid "left" msgstr "" #: zfuncs.cc:6740 msgid "right" msgstr "" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Файл параметров Ñоздан \n" "Проверьте при необходимоÑти" #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "Загрузить параметры из файла" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "Сохранить параметры в файл" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "Редактировать пареметры" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "Показать\n" "вÑе" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "Загрузить\n" "файл" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "Сохранить\n" "файл" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "Добавить\n" "новый" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "Применить" #: zfuncs.cc:7479 msgid "apply?" msgstr "Применить?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(новые параметры)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "Добавить параметр" #~ msgid "Brightness Graph" #~ msgstr "Диаграмма ÑркоÑти" #~ msgid "radius" #~ msgstr "РадиуÑ" #~ msgid "Search results file error %s" #~ msgstr "ПоиÑк ошибок %s" #~ msgid "Select area first" #~ msgstr "Сначала выберите облаÑть" #~ msgid "open a file" #~ msgstr "Открыть файл" #~ msgid "paper format is crazy" #~ msgstr "Ðевозможный формат печати" #~ msgid "landscape" #~ msgstr "Ландшафт" #~ msgid "portrait" #~ msgstr "Портрет" #~ msgid "paper format" #~ msgstr "Формат печати" #~ msgid "printer ID" #~ msgstr "ID принтера" #~ msgid "print" #~ msgstr "Печать" #~ msgid "Time Interval" #~ msgstr "Временной интервал" #~ msgid "Clone fotoxx" #~ msgstr "Клонировать fotoxx" #~ msgid "Save As" #~ msgstr "Сохранить как" #~ msgid "click on window to show RGB" #~ msgstr "Кликните по окну, чтобы увидеть RGB" #~ msgid "Create Launcher" #~ msgstr "Создать Ñтартовую иконку" #~ msgid "" #~ "Search all areas for edge and inside pixels. \n" #~ "Click inside each enclosed area in sequence." #~ msgstr "" #~ "ПоиÑк облаÑтей \n" #~ "Кликните вне облаÑти" #~ msgid "area outline has a hole" #~ msgstr "Ð’ облаÑти еÑть дыра" #~ msgid "horizontal unbend" #~ msgstr "По горизонтали" #~ msgid "vertical unbend" #~ msgstr "По вертикали" #~ msgid "target group area" #~ msgstr "ОблаÑть" #~ msgid "Area" #~ msgstr "ОблаÑть" #~ msgid "Constrain" #~ msgstr "Ограничение" #~ msgid "Convert Tags !!!" #~ msgstr "Конвертировать теги" #~ msgid "Convert tags to new standard" #~ msgstr "Конверировать теги по новому Ñтандарту" #~ msgid "HDF" #~ msgstr "HDF" #~ msgid "HDR" #~ msgstr "HDR" #~ msgid "No tags index file" #~ msgstr "Ðет индекÑного файла" #~ msgid "Rebuild Tags Index" #~ msgstr "ПереиндекÑировать теги" #~ msgid "Use F1 for context help" #~ msgstr "Получите помощь по F1" #~ msgid "brightness to clip (percent)" #~ msgstr "ЯркоÑть (%)" #~ msgid "cannot read .dist file" #~ msgstr "Ðе могу прочеÑть .dist-файл" #~ msgid "new tags index will now be created" #~ msgstr "Будет Ñоздан новый Ð¸Ð½Ð´ÐµÐºÑ Ñ‚ÐµÐ³Ð¾Ð²" #~ msgid "save select area as a file" #~ msgstr "Сохранить выбранную облаÑть как файл" #~ msgid "tags index file error: %s" #~ msgstr "Ошибка индекÑного файла тегов: %s" #~ msgid "/path*/file*" #~ msgstr "/путь*/файл*" #~ msgid "All EXIF data" #~ msgstr "Ð’Ñе EXIF-данные" #~ msgid "Basic EXIF data" #~ msgstr "ОÑновные EXIF-данные" #~ msgid "Delete EXIF data" #~ msgstr "Удалить EXIF-данные" #~ msgid "EXIF data" #~ msgstr "EXIF-данные" #~ msgid "Edit EXIF data" #~ msgstr "Редактировать EXIF-данные" #~ msgid "Resume" #~ msgstr "Продолжить" #~ msgid "Search Tags" #~ msgstr "ПоиÑк тегов" #~ msgid "Set Tile and Gap Size" #~ msgstr "Элементы и промежутки" #~ msgid "Suspend" #~ msgstr "ПриоÑтановить" #~ msgid "Tags" #~ msgstr "Теги" #~ msgid "match all tags" #~ msgstr "СоответÑтвие вÑех тегов" #~ msgid "match any tag" #~ msgstr "СоответÑтвие любого тега" #~ msgid "" #~ " Pull on an image edge using the mouse. \n" #~ " Make multiple mouse pulls until satisfied. \n" #~ " When finished, press [done]." #~ msgstr "" #~ " Корректируйте перÑпективу при помощи мышки \n" #~ " По окончании нажмите [Применить]" #~ msgid "Warp Area" #~ msgstr "Ð’Ñ‹Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð´ÐµÑ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ" #~ msgid "Warp Image (curvy)" #~ msgstr "Корректировать перÑпективу (kurvig)" #~ msgid "Warp Image in Selected Area" #~ msgstr "Деформировать изображение в выбранной облаÑти" #~ msgid "" #~ "position image\n" #~ "with mouse drag" #~ msgstr "" #~ "ПозициÑ\n" #~ "С мышкой" #~ msgid "Read File" #~ msgstr "Из файла" #~ msgid "color intensity" #~ msgstr "ИнтенÑивноÑть цвета" #~ msgid "Burn" #~ msgstr "Прожечь" #~ msgid "" #~ "Convert tags to new standard now?\n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Конвертировать теги в новый формат ÑейчаÑ?\n" #~ "Ð’Ñ‹ Ñделали резервные копии изображений?" #~ msgid "Fix Image Perspective" #~ msgstr "Корректировать перÑпективу" #~ msgid "TIFF colors=%d depth=%d not supported" #~ msgstr "TIFF цвета=%d глубина=%d не поддерживаетÑÑ" #~ msgid "add tags" #~ msgstr "Добавить теги" #~ msgid "browse" #~ msgstr "ПроÑмотр" #~ msgid "color range" #~ msgstr "По уровню цвета" #~ msgid "" #~ "exiftool missing, please install \n" #~ " package libimage-exiftool-perl" #~ msgstr "" #~ "EXIFtool не найден, пожалуйÑта, уÑтановите \n" #~ "libimage-exiftool-perl" #~ msgid "follow edge" #~ msgstr "По краю" #~ msgid "freehand draw" #~ msgstr "ÐŸÑ€Ð¾Ð¸Ð·Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть" #~ msgid "rename files" #~ msgstr "Переименовать файлы" #~ msgid "select files" #~ msgstr "Выберите файлы" #~ msgid "select image files to add tags" #~ msgstr "Выберите файлы изображений Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ‚ÐµÐ³Ð¾Ð²" #~ msgid "" #~ "\n" #~ " Match Brightness and Color" #~ msgstr "" #~ "\n" #~ " СоответÑтвие цвета и ÑркоÑти" #~ msgid "Auto" #~ msgstr "Ðвто" #~ msgid "Auto-search lens mm and bow" #~ msgstr "ÐвтоматичеÑкий поиÑк параметров объектива" #~ msgid "" #~ "Drag right image into rough alignment with left \n" #~ " to rotate, drag right edge up or down" #~ msgstr "" #~ "ТÑните правое изображение до ÑÐ¾Ð²Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñ Ð»ÐµÐ²Ñ‹Ð¼ \n" #~ "Ð”Ð»Ñ Ð¿Ð¾Ð²Ð¾Ñ€Ð¾Ñ‚Ð° Ñ‚Ñните правый край вверх или вниз" #~ msgid "Match Images" #~ msgstr "Bilder angleichen" #~ msgid "Merge the images together" #~ msgstr "Bilder miteinander verbinden" #~ msgid "Package ufraw required for this function" #~ msgstr "Ð”Ð»Ñ Ñтой функции требуетÑÑ Ð¿Ð°ÐºÐµÑ‚ ufraw" #~ msgid "Retouch Image" #~ msgstr "Ретушировать изображение" #~ msgid "Select 2 to 10 files to combine" #~ msgstr "Выбрать от 2 до 10 изображений" #~ msgid "Select image to combine" #~ msgstr "Выберите изображение" #~ msgid "Current file must be included" #~ msgstr "Файл должен быть включен" #~ msgid "Select between 2 and 10 files to combine" #~ msgstr "Выберите от 2 до 10 файлов" #~ msgid "jpeg quality" #~ msgstr "КачеÑтво jpeg" #~ msgid "" #~ "%s \n" #~ " tag limit exceeded" #~ msgstr "" #~ "%s \n" #~ " Превышен лимит тегов" #~ msgid "Add or Remove Grid Lines" #~ msgstr "Добавить или удалить Ñетку" #~ msgid "" #~ "Drag middle to move \n" #~ "Drag corners to resize" #~ msgstr "" #~ "ТÑните за Ñередину, чтобы перемеÑтить \n" #~ "ТÑните за краÑ, чтобы изменить размер" #~ msgid "Index Tags" #~ msgstr "ПереиндекÑировать теги" #~ msgid "Too many tags: %d" #~ msgstr "Слишком много тегов: %d" #~ msgid "Total tags exceed %d characters" #~ msgstr "Общее превышение %d Ñимволов" #~ msgid "Unable to copy EXIF data" #~ msgstr "Ðе могу Ñкопировать EXIF-данные" #~ msgid "Unable to save image: %s" #~ msgstr "Ðе могу Ñохранить изображение: %s" #~ msgid "assigned tags" #~ msgstr "Ðазначенные признаки" #~ msgid "grid spacing" #~ msgstr "Параметры Ñетки" #~ msgid "recently added" #~ msgstr "ПоÑледние добавленные" #~ msgid "tags exceed %d characters" #~ msgstr "Тег превыÑил %d Ñимволов" #~ msgid "Discard modifications?" #~ msgstr "Отменить модификации?" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "Переименование оÑтановлено \n" #~ " %s" #~ msgid "incremental" #~ msgstr "Ð˜Ð½ÐºÑ€ÐµÐ¼ÐµÐ½Ñ‚Ð½Ð°Ñ Ð¸Ð½Ð´ÐµÐºÑациÑ" #~ msgid "full rebuild" #~ msgstr "ÐŸÐ¾Ð»Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¸Ð½Ð´ÐµÐºÑациÑ" #~ msgid "Translate" #~ msgstr "Перевод" #~ msgid "select new file" #~ msgstr "Выбрть новый файл" #~ msgid "lens name" #~ msgstr "Объектив" #~ msgid "Lens Parameters" #~ msgstr "Параметры объектива" fotoxx-12.01.2/locales/fotoxx-de.po0000644000175000017500000015064711701011017015545 0ustar micomico# German translations for fotoxx package. # Copyright (C) 2009 THE fotoxx'S COPYRIGHT HOLDER # This file is distributed under the same license as the fotoxx package. # # msgid "" msgstr "" "Project-Id-Version: fotoxx 6.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:04+0100\n" "PO-Revision-Date: 2009-03-06 09:57+0100\n" "Language-Team: German\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "Farbtiefe auf 1-16 Bits festlegen" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Farbtiefe festlegen" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Zeichen Simulieren" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "Kontrast" #: f.art.cc:215 msgid "outlines" msgstr "Umrisse" #: f.art.cc:220 msgid "pencil" msgstr "Stift" #: f.art.cc:221 msgid "chalk" msgstr "Kreide" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "Bildumrisse addieren" #: f.art.cc:394 msgid "outline threshold" msgstr "Umriss-Grenzwert" #: f.art.cc:397 msgid "outline width" msgstr "Umrissbreite" #: f.art.cc:400 msgid "image brightness" msgstr "Bildhelligkeit" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Prägen Simulieren" #: f.art.cc:626 msgid "depth" msgstr "Tiefe" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "Farbe" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Kacheln Simulieren" #: f.art.cc:825 msgid "tile size" msgstr "Kachelgröße" #: f.art.cc:829 msgid "tile gap" msgstr "Spaltbreite" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "Bild in Rasterpunkte umwandeln" #: f.art.cc:1007 msgid "dot size" msgstr "Punktgroße" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Malen Simulieren" #: f.art.cc:1226 msgid "color depth" msgstr "Farbtiefe" #: f.art.cc:1230 msgid "patch area goal" msgstr "Fleckgröße Ziel" #: f.art.cc:1234 msgid "req. color match" msgstr "Farbeanpassung" #: f.art.cc:1238 msgid "borders" msgstr "Ränder" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "2-9 Dateien auswählen" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Bilder sind nicht gleich gross" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "Bild Beiträge einstellen" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "dunkele Pixel" #: f.comp.cc:2326 msgid "light pixels" msgstr "helle Pixel" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "Datei:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "Bild malen und krümmen" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "Bild" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "malen" #: f.comp.cc:2851 msgid "warp" msgstr "Krümmen" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "Bild auswählen und malen" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "Pixel Zusammensetzung einstellen" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "2-4 Dateien auswählen" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" "Bilder zur Grobabstimmung mit der Maus ziehen.\n" "Zum Drehen unteren Rand links/rechts ziehen" #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "Suche für Brennweite und Krümmung" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Bilder grob anpassen" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "Objektiv-Brennweite mm" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "Objektivkrümmung" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "Größe verändern" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "Fenstergröße ändern" #: f.comp.cc:4457 msgid "use two images only" msgstr "Zwei Bilder benutzen" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Unzureichende Überlappung, Ausrichtung nicht möglich" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "Helligkeit und Farbe anpassen" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "Auto-Farbe" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "Datei-Farbe" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" "Bilder zur Grobabstimmung mit der Maus ziehen.\n" "Zum Drehen, vom rechten Rand ziehen" #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Bilddatei öffnen" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "Vorherige Funktion noch aktiv" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "Originaldatei überschreiben?" #: f.file.cc:504 msgid "Do not warn again" msgstr "Nicht wieder warnen" #: f.file.cc:520 msgid "Warning" msgstr "Warnung" #: f.file.cc:643 msgid "Save File" msgstr "Datei speichern" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "Qualität" #: f.file.cc:668 msgid "make current" msgstr "aktuell machen" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "jpeg Qualität muss 1-100 sein" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Datei überschreiben? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "Leerbild erstellen" #: f.file.cc:905 msgid "file name" msgstr "Dateiname" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "Breite" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "Höhe" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "Linux Standard-Abfall nicht unterstützt. \n" "Desktop Abfall-Ordner wird erstellt." #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "Schreibgeschützte Datei in den Abfall?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "Kann Abfallkorb nicht erstellen: %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "Fehler: %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Bilddatei umbenennen" #: f.file.cc:1141 msgid "old name" msgstr "Vorheriger Name" #: f.file.cc:1142 msgid "rename to" msgstr "Umbenennen in" #: f.file.cc:1143 msgid "previous" msgstr "Vorheriges" #: f.file.cc:1229 msgid "The target file already exists" msgstr "Zieldatei existiert schon" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" "Umbenennen gescheitert: \n" " %s" #: f.file.cc:1285 msgid "Batch Rename" msgstr "Bilddateien umbenennen" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "%d Dateien ausgewählt" #: f.file.cc:1290 msgid "new base name" msgstr "neue Basisname" #: f.file.cc:1293 msgid "starting sequence" msgstr "Anfangs-Sequenznummer" #: f.file.cc:1295 msgid "increment" msgstr "Zuwachs" #: f.file.cc:1316 msgid "select files to rename" msgstr "Dateien zum Umbenennen auswählen" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "Basisname / Sequenz / Zuwachs nicht sinnvoll" #: f.file.cc:1380 msgid "new file already exists:" msgstr "Zieldatei existiert schon:" #: f.file.cc:1388 msgid "filespec too long:" msgstr "Dateiname zu lang:" #: f.file.cc:1399 msgid "Rename failed:" msgstr "Umbenennen gescheitert:" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "Addieren" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "Entfernen" #: f.file.cc:1662 msgid "menu name" msgstr "Menuname" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "Fotoxx neu starten um Menus zu aktualisieren" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "Titel und Kommentare bearbeiten" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Tags bearbeiten" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "Bilddatum (jjjjmmtt)" #: f.info.cc:165 msgid "use last" msgstr "Letztes" #: f.info.cc:168 msgid "image stars" msgstr "Bild-Sterne" #: f.info.cc:186 msgid "current tags" msgstr "Aktuelle Tags" #: f.info.cc:191 msgid "recent tags" msgstr "Kürzliche Tags" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "Definierte Tags" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "Tags verwalten" #: f.info.cc:348 msgid "category" msgstr "Gruppe" #: f.info.cc:351 msgid "tag" msgstr "Tag" #: f.info.cc:354 msgid "create" msgstr "Erstellen" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "Löschen" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "Fehler in Such-Index Datei: %s" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "Mehrere Tags zuweisen" #: f.info.cc:1354 msgid "tags to add" msgstr "Tags zum Zuweisen" #: f.info.cc:1359 msgid "create tag" msgstr "Tag erstellen" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " Zuviele Tags" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "Tag in Bilder löschen" #: f.info.cc:1556 msgid "tag to remove" msgstr "Tag zu entfernen" #: f.info.cc:1560 msgid "optional replacement" msgstr "Wahlersatz" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "0 Dateien ausgewählt" #: f.info.cc:1568 msgid "search all files" msgstr "Alle Dateien durchsuchen" #: f.info.cc:1653 msgid "no files selected" msgstr "Keine Dateien ausgewählt" #: f.info.cc:1659 msgid "no tag specified" msgstr "Kein Tag angegeben" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "Tag angeben" #: f.info.cc:1821 msgid "View Info" msgstr "Info ansehen" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "Info bearbeiten" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "Info löschen" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "Alles" #: f.info.cc:1990 msgid "One Key:" msgstr "Ein Key:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "Tags, Kommentare, Dateinamen durchsuchen" #: f.info.cc:2350 msgid "date range" msgstr "Datumsbereich" #: f.info.cc:2351 msgid "stars range" msgstr "Sterne-Wertebereich" #: f.info.cc:2352 msgid "search tags" msgstr "Such-Tags" #: f.info.cc:2353 msgid "search text" msgstr "Text durchsuchen" #: f.info.cc:2354 msgid "file names" msgstr "Dateinamen" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "(jjjjmmtt)" #: f.info.cc:2365 msgid "all/any" msgstr "alle/irgendeines" #: f.info.cc:2702 msgid "No matching images found" msgstr "Keine übereinstimmenden Bilder gefunden" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "Such-Index Datei fehlt" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "Zusätzliche Metadaten im Bericht" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "Größer" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "Thumbnails vergrößern" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "Thumbnails verkleinern" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "Kleiner" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "Stamm" #: f.navi.cc:190 msgid "parent directory" msgstr "Übergeordnetes Verzeichniss" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "Erste Seite" #: f.navi.cc:191 msgid "jump to first file" msgstr "Zur ersten Datei" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "Vorherige Seite" #: f.navi.cc:192 msgid "previous page" msgstr "Vorherige Seite" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "Vorherige Reihe" #: f.navi.cc:193 msgid "previous row" msgstr "Vorherige Reihe" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "Nächste Reihe" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "Nächste Seite" #: f.navi.cc:195 msgid "ttip::next page" msgstr "Nächste Seite" #: f.navi.cc:196 msgid "jump to last file" msgstr "Zur letzten Datei" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "Letzte Seite" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "Schließen" #: f.navi.cc:197 msgid "close image gallery" msgstr "Bildergalerie schließen" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "Dateien auswählen" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "Abbrechen" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "fertig" #: f.navi.cc:1422 msgid "insert" msgstr "hinzufügen" #: f.navi.cc:1423 msgid "add all" msgstr "Alle hinzufügen" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Helligkeit und Farbe abstimmen" #: f.retouch.cc:110 msgid "small-steps" msgstr "Kleinschritte" #: f.retouch.cc:119 msgid "color saturation" msgstr "Farbsättigung" #: f.retouch.cc:126 msgid " reset 1 " msgstr "1 zurücksetzen" #: f.retouch.cc:127 msgid "reset all" msgstr "Alle zurücksetzen" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "Bildgamma justieren" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "Helligkeitsbreite ausdehned" #: f.retouch.cc:887 msgid "bright pixels" msgstr "Helle Pixel" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Helligkeitsverteilung ausgleichen" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Ausgleichen" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "Helligkeit bereichsweise im Bild ändern" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "Tone Mapping" #: f.retouch.cc:1758 msgid "low" msgstr "niedrig" #: f.retouch.cc:1760 msgid "high" msgstr "hoch" #: f.retouch.cc:1763 msgid "Amplify" msgstr "Verstärken" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Weißabgleich abstimmen" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Weißen oder grauen Bildbereich anklicken" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "Bilderfarben anpassen" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "Mausradius für Farbauswahl" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Öffnen" #: f.retouch.cc:2310 msgid "image for source color" msgstr "Bild für Quellfarbe" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "Bild anklicken zur Quellfarbe bestimmen" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "Bild zur Abgleichfarbe festlegen" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "Bild anklicken zur Abgleichfarbe festlegen" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "Farbe vom Quellbild zuerst wählen" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "Normalabstand addieren" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "+Helligkeit -Dichte" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "+Rot -Zyan" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "+Grün -Magenta" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "+Blau -Gelb" #: f.retouch.cc:2599 msgid "Contrast" msgstr "Kontrast" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Rot" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Grün" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Blau" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "DRGB Parameter laden" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "Datei:" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "DRGB Parameter-Datei" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "Datei nicht gefunden" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "DRGB Parameter speichern" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "Bild anklicken zum Pixeln auswählen" #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "RGB revidieren" #: f.retouch.cc:3084 msgid "Metric:" msgstr "Einheit" #: f.retouch.cc:3139 msgid "Blend" msgstr "Beimischen" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Methode 1:\n" " Linksklick in das rote Auge zum Abdunkeln.\n" "Methode 2:\n" " Linke Maustaste gedrückt nach rechts unten ziehen zur Markierung des roten " "Auges.\n" " Linksklick in das rote Auge zum Abdunkeln.\n" "Zurücksetzen:\n" " Rechtsklick in das rote Auge." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Rote-Augen beseitigen" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Verwisch-Radius festlegen" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Bild schärfen" #: f.retouch.cc:4202 msgid "edge detection" msgstr "Kantenerkennung" #: f.retouch.cc:4203 msgid "cycles" msgstr "Zyklen" #: f.retouch.cc:4204 msgid "reduce" msgstr "Vermindern" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "Unscharf maskieren" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "Helligkeits-Gradient" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " [Vermindern] drücken zur \n" " schrittweisen Rauschreduzierung. \n" " [undo] zum Neustart." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Rauschverminderung" #: f.retouch.cc:4650 msgid "algorithm" msgstr "Algorithmus" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "Ausreißer nach Farbe mitteln (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "Ausreißer nach Farbe mitteln (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "Mittlere Helligkeit pro Farbe setzen" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "Tophat-Filter nach Farbe" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" "1. Zum Selektieren, Maus ziehen. \n" "2. Löschen. 3. Wiederholen. " #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "Smart löschen" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Radius" #: f.retouch.cc:5005 msgid "Blur" msgstr "Verwischen" #: f.retouch.cc:5008 msgid "New Area" msgstr "Neuer Ausschnitt" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "Staub entfernen" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "Fleckgrößen Limit" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "max. Helligkeit" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "Min. Kontrast" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "Festpixel reparieren" #: f.retouch.cc:5989 msgid "pixel group" msgstr "Pixelgruppe" #: f.retouch.cc:5990 msgid "circle color" msgstr "Kreisfarbe" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "Festpixel laden" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "Festpixel Datei" #: f.retouch.cc:6164 msgid "file format error" msgstr "Dateiformat Fehler" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "Keine Festpixel" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "Festpixel speichern" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Undo-Speicher %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Pixel bearbeiten" #: f.retouch.cc:6695 msgid "pick" msgstr "wählen" #: f.retouch.cc:6697 msgid "erase" msgstr "löschen" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "Pinsel-Radius" #: f.retouch.cc:6706 msgid "transparency center" msgstr "Transparenz Mitte" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "Transparenz Rand" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Undo Speicherkapazität erreicht. \n" "Arbeit mit [fertig] sichern, dann Fortfahren." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Ausschnitt für Bearbeitung auswählen" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "F1 für Hilfe drucken" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" "Ausschnitt nicht unterstützt \n" "von dieser Bearbeitungsfunktion" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "Rechteck" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "Ellipse" #: f.select.cc:110 msgid "draw: freehand" msgstr "Zeichnen: freihand" #: f.select.cc:111 msgid "draw: follow edge" msgstr "Zeichnen: Rand folgen" #: f.select.cc:114 msgid "select by mouse" msgstr "mit der Maus selektieren" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "Mausradius" #: f.select.cc:120 msgid "match mouse color" msgstr "Übereinstimmung der Mausfarbe" #: f.select.cc:124 msgid "search range" msgstr "Suchweite" #: f.select.cc:126 msgid "firewall" msgstr "Brandmauer" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "%d Edits überschritten" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" "Jeden umschlossen Ausschnitt einmal innen anklicken \n" "(mögliche Lücken im Rand werden gefunden). \n" "Für Hilfe F1 drucken." #: f.select.cc:1078 msgid "finish area" msgstr "Ausschnitt fertigstellen" #: f.select.cc:1113 msgid "searching" msgstr "wird gesucht" #: f.select.cc:1185 msgid "outline has a gap" msgstr "Umriss hat eine Lücke" #: f.select.cc:1189 msgid "success" msgstr "Erfolg" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "Der Ausschnitt ist nicht fertig" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Rand Berechnung in Arbeit" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Ausschnitt Randberechnung" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "Mit Maus klicken/ziehen positionieren" #: f.select.cc:1887 msgid "Paste Image" msgstr "Bild einfügen" #: f.select.cc:1901 msgid "angle" msgstr "Winkel" #: f.select.cc:2160 msgid "load select area from a file" msgstr "Auschnitt von Datei lesen" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "Kann .tiff und .info Dateien nicht öffnen" #: f.select.cc:2213 msgid "save select area to a file" msgstr "Ausschnitt in Datei speichern" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "Gesamtbild auswählen" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "Bearbeitungs-Verstärker" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "Erst Bearbeitungsfunktion aktivieren" #: f.select.cc:2499 msgid "power: center" msgstr "Stärke: Mitte" #: f.select.cc:2501 msgid "edge" msgstr "Rand" #: f.select.cc:2504 msgid "reset area" msgstr "zurücksetzen" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" "Beim Verarbeiten einer Sammlung, rechts anklicken \n" "um ein Bild oder Thumbnail zu addieren oder entfernen." #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "Sammlungen verwalten" #: f.tools.cc:85 msgid "Start new collection" msgstr "Neue Sammlung starten" #: f.tools.cc:87 msgid "Edit a collection" msgstr "Sammlung verarbeiten" #: f.tools.cc:89 msgid "View a collection" msgstr "Sammlung ansehen" #: f.tools.cc:91 msgid "Delete a collection" msgstr "Sammlung löschen" #: f.tools.cc:95 msgid "Editing:" msgstr "Verarbeiten:" #: f.tools.cc:99 msgid "Action:" msgstr "Vorgang:" #: f.tools.cc:133 msgid "New Collection" msgstr "Neue Sammlung" #: f.tools.cc:156 msgid "Edit Collection" msgstr "Sammlung bearbeiten" #: f.tools.cc:172 msgid "View Collection" msgstr "Sammlung ansehen" #: f.tools.cc:193 msgid "Delete Collection" msgstr "Sammlung löschen" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "%s löschen?" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "Bild in Sammlung: %s einfügen" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "Bild aus Sammlung entfernen" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "Bild entfernen und aufheben" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "Aufgehobene Bilder hier einfügen" #: f.tools.cc:256 msgid "add image to collection" msgstr "Bild in Sammlung einfügen" #: f.tools.cc:301 msgid "too many saved files" msgstr "Zu viele aufgehobene Dateien" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "Sammlungen versetzen" #: f.tools.cc:375 msgid "old top directory" msgstr "Altes oberstes Bild-Verzeichnis" #: f.tools.cc:378 msgid "new top directory" msgstr "Neues oberstes Bild-Verzeichnis" #: f.tools.cc:434 msgid "completed" msgstr "Fertig" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "Dateien konvertieren/skalieren/auslagern" #: f.tools.cc:474 msgid "new max. width" msgstr "Neu max. Breite" #: f.tools.cc:481 msgid "new file type" msgstr "Neue Dateityp" #: f.tools.cc:482 msgid "same" msgstr "Ebenso" #: f.tools.cc:490 msgid "replace originals" msgstr "Dateien überschreiben" #: f.tools.cc:491 msgid "export to location" msgstr "In Ordner auslagern" #: f.tools.cc:492 msgid "remove EXIF" msgstr "EXIF entfernen" #: f.tools.cc:549 msgid "Select directory" msgstr "Bildverzeichnis wählen" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "Originaldateien überschreiben? (max. %d %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "Dateien kopieren? (max. %d x %d) \n" " in Ordner %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "Kein gültiger Dateiordner" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "Max. größe %d x %d nicht sinnvoll" #: f.tools.cc:654 msgid "*** file already exists" msgstr "*** Datei existiert schon" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "*** Dateityp nicht unterstützt" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "Program ufraw-batch ist nötig" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "RAW-Datei öffnen" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "RAW Dateien zum konvertieren auswählen" #: f.tools.cc:769 msgid "Choose file type" msgstr "Dateityp wählen" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "ESC drücken um zu beenden" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "Nur neueste Dateiversionen zeigen" #: f.tools.cc:893 msgid "arrow keys" msgstr "Pfeiltasten" #: f.tools.cc:894 msgid "instant" msgstr "Sofortig" #: f.tools.cc:895 msgid "fade-in" msgstr "Einblenden" #: f.tools.cc:896 msgid "roll-right" msgstr "Nach rechts rollend" #: f.tools.cc:897 msgid "roll-down" msgstr "Nach unten rollend" #: f.tools.cc:898 msgid "shift-left" msgstr "Nach links verlagern" #: f.tools.cc:899 msgid "venetian" msgstr "Jalousie" #: f.tools.cc:900 msgid "grate" msgstr "Gitter" #: f.tools.cc:903 msgid "radar" msgstr "Radar" #: f.tools.cc:904 msgid "jaws" msgstr "Haifisch" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Dia-Show" #: f.tools.cc:915 msgid "seconds" msgstr "Sekunden" #: f.tools.cc:919 msgid "music file" msgstr "Musikdatei" #: f.tools.cc:923 msgid "transitions" msgstr "Übergänge" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "Musikdatei oder Playlist wählen" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "Datei Synchronisierung läuft schon" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" "Werkzeuge > Synchronisieren benutzen, damit Galleriefenster \n" "schnell erscheinen und Bild durchsuchen korrekt funktioniert. \n" "Sie können Bilder ansehen (nicht verarbeiten) während Synchronisierung." #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "Oberstes Bild-Verzeichnis nicht definiert" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "Oberstes Bild-Verzeichnis ist ungültig" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "Such-Index Datei fehlt" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "neue/geänderte Dateien gefunden" #: f.tools.cc:1844 msgid "no new files found" msgstr "Keine neue Dateien gefunden" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "Dateien synchronisieren" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Oberste Bild-Verzeichnis" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" "Sunchronisieren ist notwendig.\n" "Trotzdem abbrechen?" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "Oberstes-Bildverzeichnis ist ungültig" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Oberstes Bildverzeichnis wählen" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "RGB-Werte zeigen" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "Gitterlinien" #: f.tools.cc:2728 msgid "x-spacing" msgstr "x-Abstand" #: f.tools.cc:2729 msgid "x-count" msgstr "x-Anzahl" #: f.tools.cc:2730 msgid "x-enable" msgstr "x-aktivieren" #: f.tools.cc:2736 msgid "y-spacing" msgstr "y-Abstand" #: f.tools.cc:2737 msgid "y-count" msgstr "y-Anzahl" #: f.tools.cc:2738 msgid "y-enable" msgstr "y-aktivieren" #: f.tools.cc:2745 msgid "x-offset" msgstr "x-Verschiebung" #: f.tools.cc:2749 msgid "y-offset" msgstr "y-Verschiebung" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "Bilder E-mailen" #: f.tools.cc:2947 msgid "max. width" msgstr "max. Breite" #: f.tools.cc:2948 msgid "max. height" msgstr "max. Höhe" #: f.tools.cc:3093 msgid "too many files" msgstr "zu viele Dateien" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" "Helligkeit soll einen allmählichen Ansteig \n" "zeigen, auch ganz bis zu den Rändern." #: f.tools.cc:3174 msgid "Monitor Check" msgstr "Monitor Prüfung" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "Bildschirm-Gamma" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "Helligkeitsverteilung" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Vorhandene Übersetzungen" #: f.tools.cc:3436 msgid "Set Language" msgstr "Sprache wechseln" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "Start-Icon erzeugen" #: f.tools.cc:3540 msgid "Settings" msgstr "Einstellungen" #: f.tools.cc:3545 msgid "Startup Display" msgstr "Anfangsbild" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "Neueste Dateien Gallerie" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "Vorher gesehenes Bild" #: f.tools.cc:3549 msgid "Blank Window" msgstr "Leeres Bild" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "Verzeichnis Gallerie" #: f.tools.cc:3556 msgid "Image File" msgstr "Bild Datei" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "Symbolleiste-Stil" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "Text" #: f.tools.cc:3564 msgid "Icons" msgstr "Icons" #: f.tools.cc:3565 msgid "Both" msgstr "Beides" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "Überschreib Warnung" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "Anfangsverzeichnis ungültig" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "Anfangsdatei ungültig" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "Anfangsverzeichnis wählen" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "Anfangsbild wählen" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "" "Knöpfe benutzen oder \n" "rechten Rand mit der Maus ziehen" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Bild drehen" #: f.transform.cc:64 msgid "degrees" msgstr "Grad" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Schnitt" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "Gitter" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Undo Schnitt" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "Grad: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "Gold" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "Zum Bewegen mittig ziehen, Ecken um Größe zu verändern." #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Bild zuschneiden" #: f.transform.cc:348 msgid "customize" msgstr "Anpassen" #: f.transform.cc:359 msgid "ratio" msgstr "Verhältnis" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "Seitenverhältniss fixieren" #: f.transform.cc:368 msgid "invert" msgstr "Invert." #: f.transform.cc:890 msgid "Trim Buttons" msgstr "Schnitt-Knöpfe" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "Breite/Höhe-Verhältnis fixieren" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Bildgröße verändern" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Vorheriges" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" "Text eingeben, Bild mit der Maus klicken/ziehen.\n" "Zum Entfernen rechts klicken" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "Bild kommentieren" #: f.transform.cc:1307 msgid "Size" msgstr "Größe" #: f.transform.cc:1310 msgid "Angle" msgstr "Winkel" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Farbe" #: f.transform.cc:1322 msgid "Transparency" msgstr "Transparenz" #: f.transform.cc:1325 msgid "text" msgstr "Text" #: f.transform.cc:1330 msgid "backing" msgstr "Hinterfarbe" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" "Umriss\n" "Breite" #: f.transform.cc:1335 msgid "outline" msgstr "Umriss" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "Kommentardatei" #: f.transform.cc:1416 msgid "select font" msgstr "Font wählen" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "Bild spiegeln" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "Horizontal" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "Vertikal" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "Negativ erstellen" #: f.transform.cc:2158 msgid "black/white positive" msgstr "schwarzweiß Positiv" #: f.transform.cc:2159 msgid "black/white negative" msgstr "schwarzweiß Negativ" #: f.transform.cc:2160 msgid "color positive" msgstr "farbige Positiv" #: f.transform.cc:2161 msgid "color negative" msgstr "farbige Negativ" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Bild entkrümmen" #: f.transform.cc:2282 msgid "linear" msgstr "linear" #: f.transform.cc:2285 msgid "curved" msgstr "kurvig" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" " Die vier Ecken eines Tetragonalbereich anklicken. [Anwenden] drücken. \n" " Das Tetragon wird zu einem geraden Rechteck verzogen." #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "Schlussstein-Korrektur" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "Vier Ecken sind nötig" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" " Ausschnitt zum Krümmen wählen mittels Menü, Ausschnitt wählen. \n" " [Krümmen starten] drücken, Ausschnitt mit der Maus ziehen. \n" " Mehrmals ziehen/strecken bis zum erwünschten Ergebniss. \n" " Wenn fertig, anderen Ausschnitt wählen oder [Fertig] drücken." #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "Bild krümmen (Ausschnitt)" #: f.transform.cc:2864 msgid "start warp" msgstr "Krümmen starten" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "Ausschnit nicht aktiviert" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Bildstelle mit der Maus ziehen. \n" " Mehrmals ziehen bis zufriedenstellend. \n" " Wenn fertig, [Fertig] drücken." #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "Bild krümmen (kurvig)" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "Bild krümmen (linear)" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Bildecke mit der Maus ziehen. \n" " Mehrmals ziehen bis zufriedengestellt. \n" " Wenn fertig, [Fertig] drücken." #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "Bild krümmen (affine)" #: fotoxx-12.01.cc:185 msgid "File" msgstr "Datei" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "Bildergalerie" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "50/50 klonen" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "Überlagernd klonen" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "im neuen Fenster öffnen" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Vorherige Bilddatei öffnen" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "zuletzt benutzte Dateien" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "in gleicher Datei speichern" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "in neuer Version speichern" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "in neuer Datei speichern" #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "Bilddatei in den Abfall" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "Bilddateien umbenennen" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Bilddatei drucken" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "fotoxx beenden" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "Werkzeuge" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "Dateien konvertieren" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "RAW-Dateien konvertieren" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "Bilder auf CD/DVD brennen" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Monitor prüfen" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Sprache wechseln" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "Menu und Starter" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "Benutzereinstellungen" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "Speicherbelegung" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "Titel/Kommentare bearbeiten" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "Info ansehen (kurz)" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "Info ansehen (lang)" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "Bilddatei durchsuchen" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "Metadaten suchen" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "Auswählen" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Zeigen" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Ausblenden" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "Aktivieren" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "Ausschalten" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Invertieren" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "Deselektieren" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "Kopieren" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "Einfügen" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Speichern" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "Auswählen und bearbeiten" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "Umwandeln" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "Bild auto-zuschneiden" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Retuschieren" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "Helligkeit/Farbe" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "Gamma Kurven" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "Helligkeit ausdehnen" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "Helligkeit ausgleichen" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "Helligkeit rampen" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "Weißabgleich" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "Farben anpassen" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Rote Augen" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Bild verwischen" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Rauschen vermindern" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Kunst" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Farbtiefe" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "Zeichnung" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "Umrisse" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "Prägung" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "Kacheln" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "Rasterpunkte" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "Gemälde" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Verbund" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "Hoher Dynamikbereich" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "Hohe Schärfentiefe" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "Stapeln / malen" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "Stapeln / Rauschen" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Panorama" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "Vertikales Panorama" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "Plugins bearbeiten" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Hilfe" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "Über Fotoxx" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "Benutzeranleitung" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "Benutzeranleitung Änderungen" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "Verarbeitungsfunktionen Übersicht" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Änderungslog" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "Übersetzungen" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "Homepage" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "Galerie" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Nächstes" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Nächste Bilddatei öffnen" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Heranzoomen (größer)" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Herauszoomen (kleiner)" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Undo" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Eine Änderung rückgängig machen" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Redo" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Verworfene Änderung wieder anwenden" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "Speich.V" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "Speich.D" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "Bilddatei in den Abfall" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "Abfall" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Beenden" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "Fotoxx wichtig" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "Das erste Mal Start" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "50 Ankerpunkte überschritten" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "Kurven-Datei öffnen" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "Kurven-Datei ist ungültig" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "Datei Kurvenanzahl stimmt nicht" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "Kurven-Datei speichern" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "Kann nicht parallel laufen" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "EXIFTtool-Paket nicht installiert \n" "(bearbeitete Bilder verlieren ihre EXIF-Daten!)" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "Zuviele Änderungen, bitte Bild speichern" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Ausschnitt kann nicht behalten werden.\n" "Fortfahren?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" "Ausschnit nicht aktiviert.\n" "Fortfahren?" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "Änderungen verwerfen?" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" "Vorgang wird aktuelle Änderungen verwerfen.\n" "Fortfahren um diese zu verwerfen.\n" "Zurückgehen um diese zu behalten." #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "Fortfahren" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "Zurückgehen" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "Thumbnaildatei nicht lesbar" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "TIFF öffnen Fehler" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF Farbtiefe=%d nicht unterstützt" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "TIFF Lesefehler" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "TIFF Schreibfehler" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "Dateityp nicht unterstützt" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "Pixbuf Schreibfehler" #: fotoxx.h:728 msgid "absolute" msgstr "absolute" #: fotoxx.h:730 msgid "Add All" msgstr "Alle einfügen" #: fotoxx.h:732 msgid "Amount" msgstr "Wert" #: fotoxx.h:733 msgid "Apply" msgstr "Anwenden" #: fotoxx.h:734 msgid "Black" msgstr "Schwarz" #: fotoxx.h:735 msgid "Blend Width" msgstr "Mischbreite" #: fotoxx.h:737 msgid "Brightness" msgstr "Helligkeit" #: fotoxx.h:738 msgid "Browse" msgstr "Durchsuchen" #: fotoxx.h:739 msgid "Cancel" msgstr "Abbrechen" #: fotoxx.h:740 msgid "Clear" msgstr "Aufräumen" #: fotoxx.h:742 msgid "Commit" msgstr "Binden" #: fotoxx.h:744 msgid "Curve File:" msgstr "Kurven-Datei" #: fotoxx.h:745 msgid "Cut" msgstr "Ausschneiden" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Dunklere Bereiche" #: fotoxx.h:747 msgid "Delete" msgstr "Löschen" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" "Spezielle Bildliste abwerfen? \n" " %s" #: fotoxx.h:750 msgid "Done" msgstr "Fertig" #: fotoxx.h:751 msgid "Edit" msgstr "Bearbeiten" #: fotoxx.h:753 msgid "Erase" msgstr "Löschen" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "Packet libimage-exiftool-perl fehlt" #: fotoxx.h:755 msgid "Fetch" msgstr "Holen" #: fotoxx.h:756 msgid "Finish" msgstr "Fertigstellen" #: fotoxx.h:757 msgid "Font" msgstr "Font" #: fotoxx.h:759 msgid "Height" msgstr "Höhe" #: fotoxx.h:760 msgid "histogram" msgstr "Histogramm" #: fotoxx.h:762 msgid "Insert" msgstr "Einfügen" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Hellere Bereiche" #: fotoxx.h:765 msgid "limit" msgstr "Limit" #: fotoxx.h:766 msgid "New" msgstr "Neu" #: fotoxx.h:768 msgid "OK" msgstr "OK" #: fotoxx.h:772 msgid "Pause" msgstr "Unterbrechen" #: fotoxx.h:773 msgid "Percent" msgstr "Prozent" #: fotoxx.h:774 msgid "Presets" msgstr "Voreinstellungen" #: fotoxx.h:775 msgid "Proceed" msgstr "Weiter" #: fotoxx.h:777 msgid "range" msgstr "Wertbereich" #: fotoxx.h:780 msgid "Reduce" msgstr "Vermindern" #: fotoxx.h:782 msgid "Reset" msgstr "Zurücksetzen" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Dateityp unbekannt, zum bearbeiten als tiff/jpeg/png speichern" #: fotoxx.h:785 msgid "Search" msgstr "Durchsuchen" #: fotoxx.h:789 msgid "Start" msgstr "Starten" #: fotoxx.h:790 msgid "Threshold" msgstr "Schwelle" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "%d Dateien überschritten" #: fotoxx.h:792 msgid "Undo All" msgstr "Alles rückgängig" #: fotoxx.h:793 msgid "Undo Last" msgstr "Letztes rückgängig" #: fotoxx.h:795 msgid "Unfinish" msgstr "Unfertigstellen" #: fotoxx.h:797 msgid "View" msgstr "Ansehen" #: fotoxx.h:798 msgid "White" msgstr "Weiß" #: fotoxx.h:799 msgid "Width" msgstr "Breite" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "Hilfedatei nicht gefunden: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "Kann Datei nicht öffnen %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "Bildschirm in Datei speichern" #: zfuncs.cc:6222 msgid "No" msgstr "Nein" #: zfuncs.cc:6222 msgid "Yes" msgstr "Ja" #: zfuncs.cc:6447 msgid "open" msgstr "Öffnen" #: zfuncs.cc:6452 msgid "choose" msgstr "Wählen" #: zfuncs.cc:6457 msgid "save" msgstr "Speichern" #: zfuncs.cc:6463 msgid "open folder" msgstr "Verzeichnis öffnen" #: zfuncs.cc:6468 msgid "create folder" msgstr "Ordner erstellen" #: zfuncs.cc:6474 msgid "hidden" msgstr "Versteckt" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "JPG-Qualität 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "Ränder" #: zfuncs.cc:6737 msgid "top" msgstr "oben" #: zfuncs.cc:6738 msgid "bottom" msgstr "unten" #: zfuncs.cc:6739 msgid "left" msgstr "links" #: zfuncs.cc:6740 msgid "right" msgstr "rechts" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Anfangsparameter-Datei wurde angelegt. \n" "Bei Bedarf kontrollieren und berichtigen ." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "Parameter aus einer Datei laden" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "Parameter in Datei speichern" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "Parameter ändern" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "Auflisten\n" "Alle" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "Laden\n" "Datei" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "Speichern\n" "Datei" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "hinzufügen\n" "Neu" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "Anwenden" #: zfuncs.cc:7479 msgid "apply?" msgstr "Anwenden?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(neuer Parameter-Name)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "Parameter hinzufügen" #~ msgid "select new file" #~ msgstr "Neue Datei wählen" #~ msgid "Brightness Graph" #~ msgstr "Helligkeitsdiagramm" #~ msgid "Add Menu and Launcher" #~ msgstr "Menu und Starter addieren" #~ msgid "Batch Resize/Export" #~ msgstr "Dateiengrößen verändern/auslagern" #~ msgid "select by color" #~ msgstr "nach Farbe selektieren" #~ msgid "radius" #~ msgstr "Radius" #~ msgid "match" #~ msgstr "Übereinstimmung" #~ msgid "Batch Resize" #~ msgstr "Dateiengrößen verändern" #~ msgid "new max. height" #~ msgstr "Neu max. Höhe" #~ msgid "copy EXIF" #~ msgstr "EXIF kopieren" #~ msgid "new file already exists" #~ msgstr "Datei existiert schon" #~ msgid "Select area first" #~ msgstr "Zuerst Ausschnitt wählen" #~ msgid "Search results file error %s" #~ msgstr "Suchergebnis-Dateifehler %s" #~ msgid "my mouse" #~ msgstr "meine Maus" #~ msgid "both" #~ msgstr "Beide" #~ msgid "icons" #~ msgstr "Symbole" #~ msgid "lens name" #~ msgstr "Lens-Name" #~ msgid "Lens Parameters" #~ msgstr "Objektivparameter" #~ msgid "file sync is mandatory" #~ msgstr "Synchronisierung ist nötig" #~ msgid "start edit function first" #~ msgstr "Zuerst Bearbeitungsfunktion starten" fotoxx-12.01.2/locales/fotoxx-nl.po0000664000175000017500000017010411701011017015556 0ustar micomico# Translation of fotoxx.po to dutch (nl) # Translated by: Arthur Kalverboer , jun 2011. # msgid "" msgstr "" "Project-Id-Version: fotoxx 6.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:05+0100\n" "PO-Revision-Date: 2009-03-06 09:57+0100\n" "Last-Translator: Arthur\n" "Language-Team: Dutch\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "Instellen kleurdiepte op 1-16 bits" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Instellen kleurdiepte" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Tekenen nabootsen" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "contrast" #: f.art.cc:215 msgid "outlines" msgstr "contouren" #: f.art.cc:220 msgid "pencil" msgstr "potlood" #: f.art.cc:221 msgid "chalk" msgstr "krijt" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "Toevoegen afbeeldings contouren" #: f.art.cc:394 msgid "outline threshold" msgstr "contour drempel" #: f.art.cc:397 msgid "outline width" msgstr "contour breedte" #: f.art.cc:400 msgid "image brightness" msgstr "helderheid afbeelding" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Reliefdruk nabootsen" #: f.art.cc:626 msgid "depth" msgstr "diepte" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "kleur" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Tegels nabootsen" #: f.art.cc:825 msgid "tile size" msgstr "tegelgrootte" #: f.art.cc:829 msgid "tile gap" msgstr "voegbreedte" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "Converteer naar krantendruk" #: f.art.cc:1007 msgid "dot size" msgstr "stip grootte" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Verven nabootsen" #: f.art.cc:1226 msgid "color depth" msgstr "kleurdiepte" #: f.art.cc:1230 msgid "patch area goal" msgstr "" #: f.art.cc:1234 msgid "req. color match" msgstr "kleur aanpassing" #: f.art.cc:1238 msgid "borders" msgstr "randen" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "Selecteer 2 tot 9 bestanden" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "Afbeeldingen hebben niet dezelfde grootte" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "Instellen helderheidsbijdragen per afbeelding" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "donkere pixels" #: f.comp.cc:2326 msgid "light pixels" msgstr "heldere pixels" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "bestand:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "Verven en kromtrekken afbeelding" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "afbeelding" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "verven" #: f.comp.cc:2851 msgid "warp" msgstr "kromtrekken" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "Selecteer en verf afbeelding" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "Instellen Pixel Samenstelling" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "Selecteer 2 tot 4 bestanden" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" "Sleep afbeeldingen ruwweg aansluitend.\n" "Om te draaien, sleep de onderste rand." #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "Zoeken naar brandpuntsafstand en kromming" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Afbeelding globaal positioneren" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "brandpuntsafstand mm" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "lenskromming" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "Grootte wijzigen" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "venstergrootte wijzigen" #: f.comp.cc:4457 msgid "use two images only" msgstr "gebruik slechts twee afbeeldingen" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Te weinig overlap, uitlijnen niet mogelijk" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "Match helderheid en kleur" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "auto kleur" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "bestand kleur" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" "Sleep afbeeldingen ruwweg aansluitend.\n" "Om te draaien, sleep de rechter rand." #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Openen..." #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "vorige functie nog actief" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "" #: f.file.cc:504 msgid "Do not warn again" msgstr "" #: f.file.cc:520 msgid "Warning" msgstr "" #: f.file.cc:643 msgid "Save File" msgstr "Bestand opslaan" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "kwaliteit" #: f.file.cc:668 msgid "make current" msgstr "" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "jpeg kwaliteit moet 1-100 zijn" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "Bestand overschrijven? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "Lege afbeelding maken" #: f.file.cc:905 msgid "file name" msgstr "" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "breedte" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "hoogte" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" "Linux standaard prullenbak wordt niet ondersteund. \n" "Desktop prullenbak zal worden aangemaakt." #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "Alleen-lezen bestand naar prullenbak?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "Kan niet map voor prullenbak maken: %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "fout: %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Hernoemen bestand..." #: f.file.cc:1141 msgid "old name" msgstr "oude naam" #: f.file.cc:1142 msgid "rename to" msgstr "hernoemen naar" #: f.file.cc:1143 msgid "previous" msgstr "vorige" #: f.file.cc:1229 msgid "The target file already exists" msgstr "Doelbestand bestaat reeds" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" #: f.file.cc:1285 msgid "Batch Rename" msgstr "Batchgewijs hernoemen" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "" #: f.file.cc:1290 msgid "new base name" msgstr "nieuwe basisnaam" #: f.file.cc:1293 msgid "starting sequence" msgstr "start volgnummer" #: f.file.cc:1295 msgid "increment" msgstr "toename" #: f.file.cc:1316 msgid "select files to rename" msgstr "bestanden selecteren om te hernoemen" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "basisnaam / volgorde / toename niet zinvol" #: f.file.cc:1380 msgid "new file already exists:" msgstr "nieuw bestand bestaat reeds:" #: f.file.cc:1388 msgid "filespec too long:" msgstr "bestandsnaam te lang:" #: f.file.cc:1399 msgid "Rename failed:" msgstr "Hernoemen mislukt:" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "Toevoegen" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "Verwijderen" #: f.file.cc:1662 msgid "menu name" msgstr "" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "Herstart Fotoxx om plugin menu aan te passen" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Tags aanpassen" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "datum (jjjjmmdd)" #: f.info.cc:165 msgid "use last" msgstr "laatste gebruiken" #: f.info.cc:168 msgid "image stars" msgstr "afbeelding sterren" #: f.info.cc:186 msgid "current tags" msgstr "huidige tags" #: f.info.cc:191 msgid "recent tags" msgstr "recente tags" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "gedefineerde tags" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "Tags beheren" #: f.info.cc:348 msgid "category" msgstr "categorie" #: f.info.cc:351 msgid "tag" msgstr "tag" #: f.info.cc:354 msgid "create" msgstr "maken" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "verwijder" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "zoekindex bestandsfout: %s" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "Batchgewijs tags toevoegen" #: f.info.cc:1354 msgid "tags to add" msgstr "tags om toe te voegen" #: f.info.cc:1359 msgid "create tag" msgstr "tag maken" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" "%s \n" " te veel tags" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "Batchgewijs tags verwijderen" #: f.info.cc:1556 msgid "tag to remove" msgstr "tag om te verwijderen" #: f.info.cc:1560 msgid "optional replacement" msgstr "optionele herplaatsing" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "" #: f.info.cc:1568 msgid "search all files" msgstr "doorzoek alle bestanden" #: f.info.cc:1653 msgid "no files selected" msgstr "geen bestanden geselecteerd" #: f.info.cc:1659 msgid "no tag specified" msgstr "geen tag gespecificeerd" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "specificeer tag" #: f.info.cc:1821 msgid "View Info" msgstr "Tonen info" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "Info aanpassen" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "Info verwijderen" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "Alles" #: f.info.cc:1990 msgid "One Key:" msgstr "Sleutel:" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "Tags, commentaar, bestanden doorzoeken" #: f.info.cc:2350 msgid "date range" msgstr "datum van/tot" #: f.info.cc:2351 msgid "stars range" msgstr "sterren van/tot" #: f.info.cc:2352 msgid "search tags" msgstr "doorzoeken tags" #: f.info.cc:2353 msgid "search text" msgstr "doorzoeken tekst" #: f.info.cc:2354 msgid "file names" msgstr "bestandsnamen" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "" #: f.info.cc:2365 msgid "all/any" msgstr "" #: f.info.cc:2702 msgid "No matching images found" msgstr "Geen overeenkomende afbeeldingen gevonden" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "Zoekindex bestand niet aanwezig" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "groter" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "vergroten miniaturen" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "verkleinen miniaturen" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "kleiner" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "moeder" #: f.navi.cc:190 msgid "parent directory" msgstr "bovenliggende map" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "eerste pagina" #: f.navi.cc:191 msgid "jump to first file" msgstr "spring naar eerste bestand" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "vorige pagina" #: f.navi.cc:192 msgid "previous page" msgstr "vorige pagina" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "vorige rij" #: f.navi.cc:193 msgid "previous row" msgstr "vorige rij" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "volgende rij" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "volgende pagina" #: f.navi.cc:195 msgid "ttip::next page" msgstr "" #: f.navi.cc:196 msgid "jump to last file" msgstr "spring naar laatste bestand" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "laatste pagina" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "sluiten" #: f.navi.cc:197 msgid "close image gallery" msgstr "sluiten afbeeldingsgalerie" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "Selecteer bestanden" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "Annuleren" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "klaar" #: f.navi.cc:1422 msgid "insert" msgstr "invoegen" #: f.navi.cc:1423 msgid "add all" msgstr "alles toevoegen" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Instellen helderheid en kleur" #: f.retouch.cc:110 msgid "small-steps" msgstr "" #: f.retouch.cc:119 msgid "color saturation" msgstr "kleurverzadiging" #: f.retouch.cc:126 msgid " reset 1 " msgstr " herstel 1" #: f.retouch.cc:127 msgid "reset all" msgstr "alles terugzetten" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "Helderheidsbereik vergroten" #: f.retouch.cc:887 msgid "bright pixels" msgstr "lichte pixels" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Helderheidsverdeling afvlakken" #: f.retouch.cc:1072 msgid "Flatten" msgstr "afvlakken" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "Helderheidsverspreiding horizontaal/verticaal" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "Tone mapping instellen" #: f.retouch.cc:1758 msgid "low" msgstr "" #: f.retouch.cc:1760 msgid "high" msgstr "" #: f.retouch.cc:1763 msgid "Amplify" msgstr "Versterken" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Instellen witbalans" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Klik op een witte of grijze locatie in de afbeelding" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Openen" #: f.retouch.cc:2310 msgid "image for source color" msgstr "" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "rood" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "groen" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "blauw" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "" #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "" #: f.retouch.cc:3084 msgid "Metric:" msgstr "" #: f.retouch.cc:3139 msgid "Blend" msgstr "" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Methode 1:\n" " Linkerklik in het rode oog om te corrigeren.\n" "Methode 2:\n" " Sleep met de muis naar rechts om het rode oog te markeren.\n" " Linkerklik in het rode oog om te corrigeren.\n" "Ongedaan maken:\n" " Rechterklik in het rode oog." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Rode ogen correctie" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Instellen straal om te vervagen" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Afbeelding verscherpen" #: f.retouch.cc:4202 msgid "edge detection" msgstr "rand herkenning" #: f.retouch.cc:4203 msgid "cycles" msgstr "cycli" #: f.retouch.cc:4204 msgid "reduce" msgstr "verminderen" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "unsharp masking" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "helderheids gradient" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Druk [verminderen] om ruis in \n" " kleine stappen te verminderen. \n" " Druk [Annuleren] om ongedaan te maken." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Ruis vermindering" #: f.retouch.cc:4650 msgid "algorithm" msgstr "algoritme" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "afzonderlijk deel afvlakken met kleur (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "afzonderlijk deel afvlakken met kleur (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "instellen mediane helderheid per kleur" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "tophat filter voor kleur" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" "1. Sleep met de muis om uitsnede te definieren. \n" "2. Druk [verwijderen]. \n" "3. Herhaal met nieuwe uitsnede. " #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "Slim verwijderen" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "straal" #: f.retouch.cc:5005 msgid "Blur" msgstr "Vervagen" #: f.retouch.cc:5008 msgid "New Area" msgstr "Nieuwe uitsnede" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "Stofspikkels verwijderen" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "stip grootte limiet" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "max. helderheid" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "min. contrast" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "" #: f.retouch.cc:5989 msgid "pixel group" msgstr "" #: f.retouch.cc:5990 msgid "circle color" msgstr "" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "" #: f.retouch.cc:6164 msgid "file format error" msgstr "" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Geheugen voor ongedaan maken %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Verven met penseel" #: f.retouch.cc:6695 msgid "pick" msgstr "kiezen" #: f.retouch.cc:6697 msgid "erase" msgstr "verwijderen" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "straal penseelcirkel" #: f.retouch.cc:6706 msgid "transparency center" msgstr "doorzichtigheid midden" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "doorzichtigheid rand" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Ongedaan maken geheugen limiet bereikt. \n" "Bewerkingen opslaan met [Klaar], daarna doorgaan." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "Selecteer uitsnede om te bewerken" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "Druk F1 voor help" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "rechthoek" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "ellips" #: f.select.cc:110 msgid "draw: freehand" msgstr "teken: met de vrije hand" #: f.select.cc:111 msgid "draw: follow edge" msgstr "teken: volg rand" #: f.select.cc:114 msgid "select by mouse" msgstr "selecteer met muis" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "muis straal" #: f.select.cc:120 msgid "match mouse color" msgstr "" #: f.select.cc:124 msgid "search range" msgstr "" #: f.select.cc:126 msgid "firewall" msgstr "firewall" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "%d bewerkingen overschreden" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" "Klik eenmalig in elke uitsnede \n" "(mogelijke gaten in de contouren worden gevonden). \n" "Druk F1 voor help." #: f.select.cc:1078 msgid "finish area" msgstr "gereedmaken uitsnede" #: f.select.cc:1113 msgid "searching" msgstr "bezig met zoeken" #: f.select.cc:1185 msgid "outline has a gap" msgstr "contour heeft een gat" #: f.select.cc:1189 msgid "success" msgstr "succes" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "de uitsnede is niet gereed" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Berekening rand bezig" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Randberekening van uitsnede" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "positioneer met muis klik/sleep" #: f.select.cc:1887 msgid "Paste Image" msgstr "Afbeelding plakken" #: f.select.cc:1901 msgid "angle" msgstr "hoek" #: f.select.cc:2160 msgid "load select area from a file" msgstr "uitsnede-bestand laden" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "kan .tiff of .info bestanden niet openen" #: f.select.cc:2213 msgid "save select area to a file" msgstr "bewaar geselecteerde uitsnede in een bestand" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "Gehele afbeelding selecteren" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "Versterker functie wijzigen" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "" #: f.select.cc:2501 msgid "edge" msgstr "rand" #: f.select.cc:2504 msgid "reset area" msgstr "reset uitsnede" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "" #: f.tools.cc:85 msgid "Start new collection" msgstr "" #: f.tools.cc:87 msgid "Edit a collection" msgstr "" #: f.tools.cc:89 msgid "View a collection" msgstr "" #: f.tools.cc:91 msgid "Delete a collection" msgstr "" #: f.tools.cc:95 msgid "Editing:" msgstr "" #: f.tools.cc:99 msgid "Action:" msgstr "" #: f.tools.cc:133 msgid "New Collection" msgstr "" #: f.tools.cc:156 msgid "Edit Collection" msgstr "Verzameling aanpassen" #: f.tools.cc:172 msgid "View Collection" msgstr "" #: f.tools.cc:193 msgid "Delete Collection" msgstr "Verzameling verwijderen" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "" #: f.tools.cc:256 msgid "add image to collection" msgstr "" #: f.tools.cc:301 msgid "too many saved files" msgstr "" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "" #: f.tools.cc:375 msgid "old top directory" msgstr "" #: f.tools.cc:378 msgid "new top directory" msgstr "" #: f.tools.cc:434 msgid "completed" msgstr "Klaar" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "" #: f.tools.cc:474 msgid "new max. width" msgstr "nieuwe max. breedte" #: f.tools.cc:481 msgid "new file type" msgstr "" #: f.tools.cc:482 msgid "same" msgstr "" #: f.tools.cc:490 msgid "replace originals" msgstr "vervangen originelen" #: f.tools.cc:491 msgid "export to location" msgstr "exporteer naar locatie" #: f.tools.cc:492 msgid "remove EXIF" msgstr "" #: f.tools.cc:549 msgid "Select directory" msgstr "Selecteer map" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "vervangen originele bestanden? (max. %d x %d)" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" "copieer bestanden? (max. %d x %d) \n" " naar locatie %s" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "locatie is niet een geldige map" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "max. grootte %d x %d is niet logisch" #: f.tools.cc:654 msgid "*** file already exists" msgstr "" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "Programma ufraw-batch is vereist" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Open RAW bestand" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "Selecteer RAW bestanden om te converteren" #: f.tools.cc:769 msgid "Choose file type" msgstr "" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "Druk ESC om diashow te stoppen" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "" #: f.tools.cc:893 msgid "arrow keys" msgstr "pijltjes toetsen" #: f.tools.cc:894 msgid "instant" msgstr "" #: f.tools.cc:895 msgid "fade-in" msgstr "fade-in" #: f.tools.cc:896 msgid "roll-right" msgstr "" #: f.tools.cc:897 msgid "roll-down" msgstr "" #: f.tools.cc:898 msgid "shift-left" msgstr "schuif-links" #: f.tools.cc:899 msgid "venetian" msgstr "venetiaan" #: f.tools.cc:900 msgid "grate" msgstr "tralie" #: f.tools.cc:903 msgid "radar" msgstr "" #: f.tools.cc:904 msgid "jaws" msgstr "" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Diashow starten" #: f.tools.cc:915 msgid "seconds" msgstr "seconden" #: f.tools.cc:919 msgid "music file" msgstr "muziek bestand" #: f.tools.cc:923 msgid "transitions" msgstr "" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "Selecteer muziekbestand of speellijst" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "" #: f.tools.cc:1844 msgid "no new files found" msgstr "" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "Synchroniseren bestanden" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "Bovenliggende afbeeldingsmap" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Selecteer bovenliggende afbeeldingsmap" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "RGB waarden tonen" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "Raster instellen" #: f.tools.cc:2728 msgid "x-spacing" msgstr "" #: f.tools.cc:2729 msgid "x-count" msgstr "" #: f.tools.cc:2730 msgid "x-enable" msgstr "" #: f.tools.cc:2736 msgid "y-spacing" msgstr "" #: f.tools.cc:2737 msgid "y-count" msgstr "" #: f.tools.cc:2738 msgid "y-enable" msgstr "" #: f.tools.cc:2745 msgid "x-offset" msgstr "" #: f.tools.cc:2749 msgid "y-offset" msgstr "" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "E-mail afbeeldingen maken" #: f.tools.cc:2947 msgid "max. width" msgstr "max. breedte" #: f.tools.cc:2948 msgid "max. height" msgstr "max. hoogte" #: f.tools.cc:3093 msgid "too many files" msgstr "te veel bestanden" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" "Helderheid moet een geleidelijke verandering laten \n" "zien, zich geheel uitstrekkend naar de randen." #: f.tools.cc:3174 msgid "Monitor Check" msgstr "Monitorkleuren controleren" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "Gammawaarde monitor" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "Helderheidshistogram" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Beschikbare vertalingen" #: f.tools.cc:3436 msgid "Set Language" msgstr "Instellen taal" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "Toolbar stijl" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "Tekst" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "gebruik knoppen of sleep rechter rand met de muis" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Afbeelding draaien" #: f.transform.cc:64 msgid "degrees" msgstr "graden" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Bijsnijden" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Ongedaan maken bijsnijden" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "graden: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "Sleep het midden om te verplaatsen, sleep hoeken om te vergroten." #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Afbeelding bijsnijden" #: f.transform.cc:348 msgid "customize" msgstr "Aanpassen" #: f.transform.cc:359 msgid "ratio" msgstr "" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "verhoudingen behouden" #: f.transform.cc:368 msgid "invert" msgstr "omkeren" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "Bijsnijd knoppen" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "lengte:breedte verhouding behouden" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Afbeeldingsgrootte wijzigen" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Voorgaande" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" "Invoeren tekst, klik/sleep op afbeelding.\n" "Rechter klik om te verwijderen" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "Annotatie bij afbeelding" #: f.transform.cc:1307 msgid "Size" msgstr "Grootte" #: f.transform.cc:1310 msgid "Angle" msgstr "Hoek" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "Kleur" #: f.transform.cc:1322 msgid "Transparency" msgstr "Doorzichtigheid" #: f.transform.cc:1325 msgid "text" msgstr "tekst" #: f.transform.cc:1330 msgid "backing" msgstr "" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" "Contour\n" " Breedte" #: f.transform.cc:1335 msgid "outline" msgstr "" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "Annotatie bestand:" #: f.transform.cc:1416 msgid "select font" msgstr "selecteer font" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "Afbeelding spiegelen" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "horizontaal" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "verticaal" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "Maak negatief" #: f.transform.cc:2158 msgid "black/white positive" msgstr "" #: f.transform.cc:2159 msgid "black/white negative" msgstr "" #: f.transform.cc:2160 msgid "color positive" msgstr "" #: f.transform.cc:2161 msgid "color negative" msgstr "" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Afbeelding ontkrommen" #: f.transform.cc:2282 msgid "linear" msgstr "lineair" #: f.transform.cc:2285 msgid "curved" msgstr "gebogen" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" " Selecteer een uitsnede met menu-functie [Uitsnede selecteren]. \n" " Druk [start kromtrekken] en sleep uitsnede met de muis. \n" " Herhalen tot het gewenste resultaat. \n" " Indien gereed, een andere uitsnede selecteren of druk [Klaar]." #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "Afbeelding kromtrekken (uitsnede)" #: f.transform.cc:2864 msgid "start warp" msgstr "Start kromtrekken" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Sleep de plaats van een afbeelding met de muis. \n" " Herhalen tot het gewenste resultaat. \n" " Indien gereed, druk [Klaar]." #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "Afbeelding kromtrekken (gebogen)" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "Afbeelding kromtrekken (lineair)" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Sleep een hoek van de afbeelding. \n" " Herhalen tot het gewenste resultaat. \n" " Indien gereed, druk [Klaar]." #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "Afbeelding kromtrekken (affine)" #: fotoxx-12.01.cc:185 msgid "File" msgstr "Bestand" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "Afbeeldingsgalerie tonen" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Open voorgaand bestand" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "Onlangs geopend" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "Opslaan" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "Opslaan als ..." #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "Verwijderen" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "Batchgewijs hernoemen..." #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Afdrukken..." #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "Afsluiten" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "Gereedschap" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "RAW-bestanden converteren" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "Afbeelding op CD/DVD branden" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Monitorkleuren controleren" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Taal veranderen" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "Geheugengebruik" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "Tonen info (kort)" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "Tonen info (uitgebreid)" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "Afbeeldingen doorzoeken" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "Uitsnedes selecteren" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Tonen" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Verbergen" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "Uitsnede activeren" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "Uitsnede deactiveren" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Uitsnede inverteren" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "Uitsnede copieren" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "Uitsnede plakken" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Opslaan" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "Selecteren en aanpassen" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "Transformeren" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Retoucheren" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "Helderheid/Kleur instellen" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "Helderheidsbereik vergroten" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "Helderheidsverdeling afvlakken" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "Helderheidsverspreiding instellen" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "Witbalans instellen" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Rode ogen corrigeren" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Afbeelding vervagen" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Ruis verminderen" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Creatief" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Kleurdiepte instellen" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "Tekenen" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "Contouren" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "Reliefdruk" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "Tegels" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "Krantendruk" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "Verven" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Samenvoegen" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "Hoog dynamisch bereik (HDR)" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "Hoge scherptediepte (HDF)" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "Stapelen / Verven" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "Stapelen / Ruis verminderen" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Panorama maken" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "Verticaal panorama" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "Plugins aanpassen" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Help" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "Over fotoxx" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "Gebruikershandleiding" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Veranderingslogboek" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "Homepage" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "Galerie" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Volgende" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Open volgend bestand" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Zoom-in (groter)" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Zoom-uit (kleiner)" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Ongedaan maken" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Bewerkingsstap ongedaan maken" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Opnieuw" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Bewerkingsstap opnieuw uitvoeren" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "Afbeelding naar prullenbak" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "Opruimen" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Afsluiten" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "Fotoxx overzicht" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "50 ankerpunten overschreden" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "laad curve vanuit bestand" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "curve bestand is ongeldig" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "curve bestand heeft verschillend aantal curves" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "bewaar curve in een bestand" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "EXIFtool pakket niet geinstalleerd \n" "bewerkte afbeeldingen verliezen EXIF gegevens" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "Te veel aanpassingen, graag afbeelding opslaan" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "Uitsnede kan niet bewaard worden.\n" "Doorgaan?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" "Uitsnede niet actief.\n" "Doorgaan?" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "kan miniatuur bestand niet openen" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "TIFF open fout" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "TIFF bits/kleur=%d niet ondersteund" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "TIFF lees fout" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "TIFF schrijf fout" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "bestandstype niet ondersteund" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "pixbuf schrijf fout" #: fotoxx.h:728 msgid "absolute" msgstr "" #: fotoxx.h:730 msgid "Add All" msgstr "Alles toevoegen" #: fotoxx.h:732 msgid "Amount" msgstr "waarde" #: fotoxx.h:733 msgid "Apply" msgstr "Toepassen" #: fotoxx.h:734 msgid "Black" msgstr "" #: fotoxx.h:735 msgid "Blend Width" msgstr "Meng breedte" #: fotoxx.h:737 msgid "Brightness" msgstr "helderheid" #: fotoxx.h:738 msgid "Browse" msgstr "Zoeken" #: fotoxx.h:739 msgid "Cancel" msgstr "Annuleren" #: fotoxx.h:740 msgid "Clear" msgstr "Leegmaken" #: fotoxx.h:742 msgid "Commit" msgstr "" #: fotoxx.h:744 msgid "Curve File:" msgstr "Curve bestand:" #: fotoxx.h:745 msgid "Cut" msgstr "" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Donkere delen" #: fotoxx.h:747 msgid "Delete" msgstr "Uitsnede verwijderen" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" #: fotoxx.h:750 msgid "Done" msgstr "Klaar" #: fotoxx.h:751 msgid "Edit" msgstr "Bewerken" #: fotoxx.h:753 msgid "Erase" msgstr "" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "pakket libimage-exiftool-perl is vereist" #: fotoxx.h:755 msgid "Fetch" msgstr "Ophalen" #: fotoxx.h:756 msgid "Finish" msgstr "Gereed" #: fotoxx.h:757 msgid "Font" msgstr "Font" #: fotoxx.h:759 msgid "Height" msgstr "hoogte" #: fotoxx.h:760 msgid "histogram" msgstr "histogram" #: fotoxx.h:762 msgid "Insert" msgstr "Invoegen" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Lichtere delen" #: fotoxx.h:765 msgid "limit" msgstr "limiet" #: fotoxx.h:766 msgid "New" msgstr "" #: fotoxx.h:768 msgid "OK" msgstr "OK" #: fotoxx.h:772 msgid "Pause" msgstr "Pauze" #: fotoxx.h:773 msgid "Percent" msgstr "percentage" #: fotoxx.h:774 msgid "Presets" msgstr "verkleiningsfactor" #: fotoxx.h:775 msgid "Proceed" msgstr "Doorgaan" #: fotoxx.h:777 msgid "range" msgstr "bereik" #: fotoxx.h:780 msgid "Reduce" msgstr "verminderen" #: fotoxx.h:782 msgid "Reset" msgstr "" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Bestandstype onbekend, om te bewerken opslaan als tiff/jpeg/png" #: fotoxx.h:785 msgid "Search" msgstr "Zoeken" #: fotoxx.h:789 msgid "Start" msgstr "Starten" #: fotoxx.h:790 msgid "Threshold" msgstr "drempel" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "Alles ongedaan maken" #: fotoxx.h:793 msgid "Undo Last" msgstr "Laatste ongedaan maken" #: fotoxx.h:795 msgid "Unfinish" msgstr "" #: fotoxx.h:797 msgid "View" msgstr "" #: fotoxx.h:798 msgid "White" msgstr "" #: fotoxx.h:799 msgid "Width" msgstr "breedte" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "help bestand niet gevonden: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "kan bestand niet openen %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "schrijf scherm naar bestand" #: zfuncs.cc:6222 msgid "No" msgstr "Nee" #: zfuncs.cc:6222 msgid "Yes" msgstr "Ja" #: zfuncs.cc:6447 msgid "open" msgstr "Openen" #: zfuncs.cc:6452 msgid "choose" msgstr "Kies" #: zfuncs.cc:6457 msgid "save" msgstr "opslaan" #: zfuncs.cc:6463 msgid "open folder" msgstr "open map" #: zfuncs.cc:6468 msgid "create folder" msgstr "aanmaken map" #: zfuncs.cc:6474 msgid "hidden" msgstr "verborgen" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "JPG kwaliteit 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "" #: zfuncs.cc:6737 msgid "top" msgstr "" #: zfuncs.cc:6738 msgid "bottom" msgstr "" #: zfuncs.cc:6739 msgid "left" msgstr "" #: zfuncs.cc:6740 msgid "right" msgstr "" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Initieel parameter bestand wordt aangemaakt. \n" "Zo nodig controleren en verbeteren." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "laden parameters uit bestand" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "schrijf parameters naar bestand" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "aanpassen parameters" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "opsommen\n" "alle" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "laden\n" "bestand" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "opslaan\n" "bestand" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "toevoegen\n" "nieuw" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "toepassen" #: zfuncs.cc:7479 msgid "apply?" msgstr "toepassen?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(nieuwe parameter naam)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "toevoegen parameter" #~ msgid "Brightness Graph" #~ msgstr "Helderheidshistogram tonen" #~ msgid "Add Menu and Launcher" #~ msgstr "Toevoegen Menu en Start-icon" #~ msgid "Batch Resize/Export" #~ msgstr "Batchgewijs grootte wijzigen/exporteren" #~ msgid "select by color" #~ msgstr "selecteer met kleur" #~ msgid "radius" #~ msgstr "straal" #~ msgid "match" #~ msgstr "gelijkenis" #~ msgid "Search results file error %s" #~ msgstr "Zoekresultaten - bestandsfout %s" #~ msgid "Batch Resize" #~ msgstr "Batchgewijs grootte wijzigen" #~ msgid "new max. height" #~ msgstr "nieuwe max. hoogte" #~ msgid "copy EXIF" #~ msgstr "copieer EXIF" #~ msgid "new file already exists" #~ msgstr "nieuw bestand bestaat reeds" #~ msgid "Select area first" #~ msgstr "Eerst uitsnede selecteren" #~ msgid "open a file" #~ msgstr "open bestand" #~ msgid "paper format is crazy" #~ msgstr "papier formaat zinloos" #~ msgid "landscape" #~ msgstr "landscape" #~ msgid "portrait" #~ msgstr "portrait" #~ msgid "paper format" #~ msgstr "papier formaat" #~ msgid "printer ID" #~ msgstr "printer ID" #~ msgid "print" #~ msgstr "Afdrukken" #~ msgid "Time Interval" #~ msgstr "Tijdsinterval" #~ msgid "Whole Image" #~ msgstr "Gehele afbeelding" #~ msgid "random" #~ msgstr "lukraak" #~ msgid "" #~ "Click on images to remove and save, \n" #~ "then press [Insert] to insert them." #~ msgstr "" #~ "Klik op afbeeldingen om te verwijderen en te bewaren, \n" #~ "druk daarna [Invoegen] to insert them." #~ msgid "Clone fotoxx" #~ msgstr "fotoxx klonen" #~ msgid "Save As" #~ msgstr "Opslaan als ..." #~ msgid "" #~ "Select images to add, then \n" #~ "press [Insert] to insert them." #~ msgstr "" #~ "Selecteer afbeeldingen om toe te voegen, \n" #~ "druk daarna [Toevoegen] om ze toe te voegen." #~ msgid "click on window to show RGB" #~ msgstr "klik op venster om RGB waarden te tonen" #~ msgid "make new version" #~ msgstr "maak nieuwe versie" #~ msgid "white" #~ msgstr "wit" #~ msgid "black" #~ msgstr "zwart" #~ msgid "Create Launcher" #~ msgstr "Start-icon maken" #~ msgid "" #~ "Search all areas for edge and inside pixels. \n" #~ "Click inside each enclosed area in sequence." #~ msgstr "" #~ "Doorzoeken alle uitsnedes op randpixels en interne pixels. \n" #~ "Klik achtereenvolgens in elke uitsnede." #~ msgid "area outline has a hole" #~ msgstr "Contour van uitsnede heeft een gat" #~ msgid "Rebuild Thumbnails" #~ msgstr "Opbouwen miniaturen" #~ msgid "horizontal unbend" #~ msgstr "horizontaal ontkrommen" #~ msgid "press ESC to exit" #~ msgstr "druk ESC om af te sluiten" #~ msgid "select by color:" #~ msgstr "selecteer kleur" #~ msgid "select by mouse:" #~ msgstr "selecteer muis" #~ msgid "vertical unbend" #~ msgstr "verticaal ontkrommen" #~ msgid "target group area" #~ msgstr "drempel groepering uitsnedes" #~ msgid "Area" #~ msgstr "Uitsnede" #~ msgid "Constrain" #~ msgstr "beperken" #~ msgid "Convert Tags !!!" #~ msgstr "Tags converteren !!!" #~ msgid "Convert tags to new standard" #~ msgstr "Tags volgens nieuwe standaard converteren" #~ msgid "" #~ "Convert tags to new standard now? \n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Tags nu volgens nieuwe standaard converteren? \n" #~ "Heeft u een backup van uw afbeeldingen gemaakt?" #~ msgid "HDF" #~ msgstr "HDF afbeelding maken" #~ msgid "HDR" #~ msgstr "HDR afbeelding maken" #~ msgid "" #~ "New tags file already exists! \n" #~ "Proceed anyway?" #~ msgstr "" #~ "Nieuw tag bestand bestaat reeds! \n" #~ "Toch doorgaan?" #~ msgid "No tags index file" #~ msgstr "Geen tagindex bestand" #~ msgid "Rebuild Tags Index" #~ msgstr "Opbouwen tagindex" #~ msgid "Stack" #~ msgstr "Afbeeldingen stapelen" #~ msgid "Use F1 for context help" #~ msgstr "Druk op F1 voor context help" #~ msgid "brightness to clip (percent)" #~ msgstr "helderheidsbereik in procenten" #~ msgid "cannot read .dist file" #~ msgstr "kan .dist bestand niet lezen" #~ msgid "manage tags" #~ msgstr "beheren tags" #~ msgid "new tags index will now be created" #~ msgstr "nieuwe tagindex zal nu worden aangemaakt" #~ msgid "save select area as a file" #~ msgstr "uitsnede opslaan als bestand" #~ msgid "tags index file error: %s" #~ msgstr "tagindex bestandsfout: %s" #~ msgid "/path*/file*" #~ msgstr "/pad*/bestand*" #~ msgid "All EXIF data" #~ msgstr "EXIF gegevens tonen" #~ msgid "Basic EXIF data" #~ msgstr "EXIF basisgegevens tonen" #~ msgid "Delete EXIF data" #~ msgstr "EXIF gegevens verwijderen" #~ msgid "EXIF data" #~ msgstr "EXIF gegevens" #~ msgid "Edit EXIF data" #~ msgstr "EXIF gegevens aanpassen" #~ msgid "Resume" #~ msgstr "Hervatten" #~ msgid "Search Tags" #~ msgstr "Tags doorzoeken" #~ msgid "Set Tile and Gap Size" #~ msgstr "Instellen tegelparameters" #~ msgid "Suspend" #~ msgstr "Onderbreken" #~ msgid "Tags" #~ msgstr "Tags" #~ msgid "match all tags" #~ msgstr "overeenkomend met alle tags" #~ msgid "match any tag" #~ msgstr "overeenkomend met een tag" #~ msgid "" #~ " Pull on an image edge using the mouse. \n" #~ " Make multiple mouse pulls until satisfied. \n" #~ " When finished, press [done]." #~ msgstr "" #~ " Sleep een rand van de afbeelding. \n" #~ " Herhalen tot het gewenste resultaat. \n" #~ " Indien gereed, druk [Klaar]." #~ msgid "Open File" #~ msgstr "Open uitsnede-bestand" #~ msgid "Warp Area" #~ msgstr "Uitsnede kromtrekken" #~ msgid "Warp Image" #~ msgstr "Kromtrekken afbeelding" #~ msgid "Warp Image (curvy)" #~ msgstr "Afbeelding kromtrekken (curvy)" #~ msgid "Warp Image in Selected Area" #~ msgstr "Afbeelding kromtrekken in geselecteerde uitsnede" #~ msgid "" #~ "position image\n" #~ "with mouse drag" #~ msgstr "" #~ "afbeelding positioneren\n" #~ "door met muis te slepen" #~ msgid "transparent" #~ msgstr "doorzichtig" #~ msgid "Read File" #~ msgstr "Uitsnede-bestand laden" #~ msgid "color intensity" #~ msgstr "kleurintensiteit" #~ msgid "Burn" #~ msgstr "Branden" #~ msgid "" #~ "Convert tags to new standard now?\n" #~ "Are your image files backed-up?" #~ msgstr "" #~ "Tags nu naar nieuwe standaard converteren?\n" #~ "Heeft u een backup van uw afbeeldingen gemaakt?" #~ msgid "Fix Image Perspective" #~ msgstr "Perspectief corrigeren" #~ msgid "TIFF colors=%d depth=%d not supported" #~ msgstr "TIFF kleuren=%d diepte=%d niet ondersteund" #~ msgid "add tags" #~ msgstr "Tags toevoegen" #~ msgid "browse" #~ msgstr "doorzoeken" #~ msgid "color range" #~ msgstr "kleurbereik" #~ msgid "" #~ "exiftool missing, please install \n" #~ " package libimage-exiftool-perl" #~ msgstr "" #~ "Programma exiftool ontbreekt, graag pakket \n" #~ "libimage-exiftool-perl installeren" #~ msgid "follow edge" #~ msgstr "rand volgen" #~ msgid "freehand draw" #~ msgstr "vrij tekenen" #~ msgid "rename files" #~ msgstr "hernoemen bestanden" #~ msgid "select files" #~ msgstr "bestanden kiezen" #~ msgid "select image files to add tags" #~ msgstr "bestanden selecteren om tags toe te voegen" #~ msgid "" #~ "\n" #~ " Match Brightness and Color" #~ msgstr "" #~ "\n" #~ " Helderheid en kleur aanpassen" #~ msgid "Auto" #~ msgstr "Auto" #~ msgid "Auto-search lens mm and bow" #~ msgstr "auto zoeken brandpuntsafstand en lenskromming" #~ msgid "" #~ "Drag right image into rough alignment with left \n" #~ " to rotate, drag right edge up or down" #~ msgstr "" #~ "Sleep rechter afbeelding om te positioneren tov de linker afbeelding \n" #~ "Om te draaien de rechterrand met de muis op of neer slepen" #~ msgid "Match Images" #~ msgstr "Afbeeldingen gelijkend maken" #~ msgid "Merge the images together" #~ msgstr "afbeeldingen samenvoegen" #~ msgid "Package ufraw required for this function" #~ msgstr "Pakket ufraw nodig voor deze functie" #~ msgid "Retouch Image" #~ msgstr "Afbeelding retoucheren" #~ msgid "Select 2 to 10 files to combine" #~ msgstr "Selecteer 2-10 afbeeldingen om samen te voegen" #~ msgid "Select image to combine" #~ msgstr "Selecteer afbeelding om samen te voegen" #~ msgid "Current file must be included" #~ msgstr "Huidig bestand moet in selectie zijn opgenomen" #~ msgid "Select between 2 and 10 files to combine" #~ msgstr "Selecteer 2 tot 10 afbeeldingen om samen te voegen" #~ msgid "jpeg quality" #~ msgstr "jpeg kwaliteit" #~ msgid " Constraints" #~ msgstr "Beperkingen" #~ msgid "" #~ "%s \n" #~ " tag limit exceeded" #~ msgstr "" #~ "%s \n" #~ " Tag limiet overschreden" #~ msgid "Add or Remove Grid Lines" #~ msgstr "Rasterlijnen toevoegen of verwijderen" #~ msgid "Assigned tags file error: %s" #~ msgstr "Fout in toegewezen tagbestand %s" #~ msgid "Convert Tags" #~ msgstr "Tags converteren" #~ msgid "" #~ "Drag middle to move \n" #~ "Drag corners to resize" #~ msgstr "" #~ "Het midden slepen om te bewegen, \n" #~ "Hoeken slepen om grootte te wijzigen" #~ msgid "Index Tags" #~ msgstr "Tags indexeren" #~ msgid "Index Tags and Thumbs" #~ msgstr "Tags en Thumbs synchroniseren" #~ msgid "No assigned tags index file" #~ msgstr "Geen toegewezen tagindex bestand" #~ msgid "Package exiftool is missing" #~ msgstr "Pakket exiftool mist" #~ msgid "Tonemap: base" #~ msgstr "Tonemap: basis" #~ msgid "Tonemap: gradient" #~ msgstr "Tonemap: gradient" #~ msgid "Tonemap: local-1" #~ msgstr "Tonemap: lokal-1" #~ msgid "Tonemap: local-2" #~ msgstr "Tonemap: lokal-2" #~ msgid "Too many tags: %d" #~ msgstr "Te veel tags: %d" #~ msgid "Too many undo buffers, please save image" #~ msgstr "te veel undo-buffers, graag afbeelding opslaan" #~ msgid "Total tags exceed %d characters" #~ msgstr "Aantal tags overschrijdt %d karakters" #~ msgid "Unable to copy EXIF data" #~ msgstr "Kan EXIF gegevens niet copieren" #~ msgid "Unable to save image: %s" #~ msgstr "Kan afbeelding niet opslaan: %s" #~ msgid "Warp Image (curvey)" #~ msgstr "Afbeelding kromtrekken (curvy)" #~ msgid "assigned tags" #~ msgstr "toegewezen tags" #~ msgid "filespec too long: %s" #~ msgstr "bestandsnaam te lang: %s" #~ msgid "grid spacing" #~ msgstr "raster grootte" #~ msgid "new file already exists: %s" #~ msgstr "nieuw bestand bestaat reeds: %s" #~ msgid "recently added" #~ msgstr "pas toegevoegd" #~ msgid "tags exceed %d characters" #~ msgstr "tags overschrijden %d karakters" #~ msgid "" #~ "Discard current gallery list? \n" #~ " %s" #~ msgstr "" #~ "Vervangen huidige galerie lijst? \n" #~ " %s" #~ msgid "Edit Caption" #~ msgstr "Bijschrift aanpassen" #~ msgid "Edit Comments" #~ msgstr "Commentaar aanpassen" #~ msgid "Discard modifications?" #~ msgstr "Wijzigingen verwerpen?" #~ msgid "transition" #~ msgstr "overgang" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "Hernoemen mislukt \n" #~ " %s" #~ msgid "incremental" #~ msgstr "toenemend" #~ msgid "full rebuild" #~ msgstr "volledig herbouwen" #~ msgid "" #~ "Click on image where new or saved \n" #~ "images are to be inserted (after)." #~ msgstr "" #~ "Klik op de afbeelding waarna nieuwe of bewaarde \n" #~ "afbeeldingen moeten worden toegevoegd." #~ msgid "Click on images to delete." #~ msgstr "Klik op afbeeldingen om te verwijderen." #~ msgid "select image files" #~ msgstr "selecteer afbeeldingsbestanden" #~ msgid "Insert new or saved images" #~ msgstr "Invoegen nieuwe of bewaarde afbeeldingen" #~ msgid "Remove and save images" #~ msgstr "Verwijderen en bewaren afbeeldingen" #~ msgid "Delete images from collection" #~ msgstr "Afbeelding verwijderen uit verzameling" #~ msgid "Add new images to collection" #~ msgstr "Nieuwe afbeeldingen toevoegen aan verzameling" #~ msgid "Save Collection" #~ msgstr "Verzameling bewaren" #~ msgid "" #~ "Run Tools > Synchronize Files so that gallery windows \n" #~ "will be fast and Search Images will work correctly." #~ msgstr "" #~ "Kies Gereedschap > Synchroniseren bestanden zodat gallerie vensters \n" #~ "snel zijn en Doorzoeken afbeeldingen correct zal werken." #~ msgid "Translate" #~ msgstr "Vertaalinstructie" #~ msgid "Open Collection" #~ msgstr "Verzameling openen" #~ msgid "Create Collection" #~ msgstr "Verzameling maken" #~ msgid "select new file" #~ msgstr "selecteer nieuw bestand" #~ msgid "both" #~ msgstr "beide" #~ msgid "icons" #~ msgstr "icons" #~ msgid "lens name" #~ msgstr "lens naam" #~ msgid "start edit function first" #~ msgstr "start eerst edit functie" #~ msgid "Lens Parameters" #~ msgstr "Lens parameters instellen" fotoxx-12.01.2/locales/fotoxx-es.po0000664000175000017500000016211411701011017015556 0ustar micomico# Spanish translations for home package. # Copyright (C) 2008 THE home'S COPYRIGHT HOLDER # This file is distributed under the same license as the home package. # mico , 2008. # msgid "" msgstr "" "Project-Id-Version: fotoxx-6.9.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-12-31 21:05+0100\n" "PO-Revision-Date: 2009-11-04 23:35+0100\n" "Last-Translator: Miguel Anxo Bouzada \n" "Language-Team: GALPon MiniNo \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Spanish\n" "X-Poedit-Country: SPAIN\n" #: f.art.cc:47 msgid "Set color depth to 1-16 bits" msgstr "Establecer profundidad de color 1-16 bits" #: f.art.cc:57 msgid "Set Color Depth" msgstr "Ajustar la profundidad de color" #: f.art.cc:171 msgid "Simulate Drawing" msgstr "Simular un dibujo" #: f.art.cc:213 f.retouch.cc:1759 f.retouch.cc:5991 msgid "contrast" msgstr "Contraste" #: f.art.cc:215 msgid "outlines" msgstr "Contornos" #: f.art.cc:220 msgid "pencil" msgstr "Lapiz" #: f.art.cc:221 msgid "chalk" msgstr "Tiza" #: f.art.cc:381 msgid "Add Image Outlines" msgstr "" #: f.art.cc:394 msgid "outline threshold" msgstr "" #: f.art.cc:397 msgid "outline width" msgstr "" #: f.art.cc:400 msgid "image brightness" msgstr "" #: f.art.cc:611 msgid "Simulate Embossing" msgstr "Simular un repujado" #: f.art.cc:626 msgid "depth" msgstr "Profundidad" #: f.art.cc:628 f.file.cc:919 f.retouch.cc:6692 msgid "color" msgstr "Color" #: f.art.cc:821 msgid "Simulate Tiles" msgstr "Simular un mosaico" #: f.art.cc:825 msgid "tile size" msgstr "Tamaño del mosaico" #: f.art.cc:829 msgid "tile gap" msgstr "Separación do mosaico" #: f.art.cc:1003 msgid "Convert Image to Dots" msgstr "" #: f.art.cc:1007 msgid "dot size" msgstr "" #: f.art.cc:1222 msgid "Simulate Painting" msgstr "Simular una pintura" #: f.art.cc:1226 msgid "color depth" msgstr "Profundidad de color" #: f.art.cc:1230 msgid "patch area goal" msgstr "" #: f.art.cc:1234 msgid "req. color match" msgstr "Correspondencia de color requerida" #: f.art.cc:1238 msgid "borders" msgstr "Bordes" #: f.comp.cc:1956 f.comp.cc:1961 f.comp.cc:2582 f.comp.cc:2587 f.comp.cc:3266 #: f.comp.cc:3271 f.comp.cc:3816 f.comp.cc:3821 msgid "Select 2 to 9 files" msgstr "" #: f.comp.cc:1982 f.comp.cc:2608 f.comp.cc:3292 f.comp.cc:3842 msgid "Images are not all the same size" msgstr "" #: f.comp.cc:2321 msgid "Adjust Image Contributions" msgstr "" #: f.comp.cc:2324 f.retouch.cc:886 msgid "dark pixels" msgstr "" #: f.comp.cc:2326 msgid "light pixels" msgstr "" #: f.comp.cc:2328 f.info.cc:159 msgid "file:" msgstr "Archivo:" #: f.comp.cc:2843 msgid "Paint and Warp Image" msgstr "" #: f.comp.cc:2846 f.comp.cc:3520 f.comp.cc:4959 f.comp.cc:5705 msgid "image" msgstr "" #: f.comp.cc:2850 f.retouch.cc:6696 msgid "paint" msgstr "Pintar" #: f.comp.cc:2851 msgid "warp" msgstr "" #: f.comp.cc:3518 msgid "Select and Paint Image" msgstr "" #: f.comp.cc:4031 msgid "Adjust Pixel Composition" msgstr "" #: f.comp.cc:4283 f.comp.cc:4288 f.comp.cc:5173 f.comp.cc:5178 msgid "Select 2 to 4 files" msgstr "" #: f.comp.cc:4361 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from lower edge." msgstr "" #: f.comp.cc:4363 msgid "Search for lens mm and bow" msgstr "" #: f.comp.cc:4409 f.comp.cc:5298 msgid "Pre-align Images" msgstr "Pre-alinear imágenes" #: f.comp.cc:4413 f.comp.cc:5302 msgid "lens mm" msgstr "Longitud focal (mm)" #: f.comp.cc:4417 f.comp.cc:5306 msgid "lens bow" msgstr "Curvatura de la lente" #: f.comp.cc:4419 f.comp.cc:5308 msgid "Resize" msgstr "" #: f.comp.cc:4420 f.comp.cc:5309 msgid "resize window" msgstr "" #: f.comp.cc:4457 msgid "use two images only" msgstr "" #: f.comp.cc:4478 f.comp.cc:4676 f.comp.cc:4875 f.comp.cc:5357 f.comp.cc:5620 msgid "Too little overlap, cannot align" msgstr "Solapamiento demasiado pequeño, no puedo alinear" #: f.comp.cc:4950 f.comp.cc:5696 msgid "Match Brightness and Color" msgstr "" #: f.comp.cc:4974 f.comp.cc:5720 msgid "auto color" msgstr "" #: f.comp.cc:4975 f.comp.cc:5721 msgid "file color" msgstr "" #: f.comp.cc:5251 msgid "" "Drag images into rough alignment.\n" "To rotate, drag from right edge." msgstr "" #: f.file.cc:169 f.file.cc:341 fotoxx-12.01.cc:189 fotoxx-12.01.cc:325 msgid "Open Image File" msgstr "Abrir archivo de imagen" #: f.file.cc:321 fotoxx-12.01.cc:2862 msgid "prior function still active" msgstr "" #: f.file.cc:503 msgid "Overwrite original file?" msgstr "" #: f.file.cc:504 msgid "Do not warn again" msgstr "" #: f.file.cc:520 msgid "Warning" msgstr "" #: f.file.cc:643 msgid "Save File" msgstr "Guardar el archivo" #: f.file.cc:666 zfuncs.cc:6478 msgid "quality" msgstr "" #: f.file.cc:668 msgid "make current" msgstr "" #: f.file.cc:725 msgid "jpeg quality must be 1-100" msgstr "" #: f.file.cc:747 #, c-format msgid "" "Overwrite file? \n" " %s" msgstr "" "¿Sobreescribir archivo? \n" " %s" #: f.file.cc:903 fotoxx-12.01.cc:196 msgid "Create Blank Image" msgstr "" #: f.file.cc:905 msgid "file name" msgstr "" #: f.file.cc:910 f.transform.cc:353 msgid "width" msgstr "" #: f.file.cc:913 f.tools.cc:477 f.transform.cc:356 msgid "height" msgstr "" #: f.file.cc:1033 msgid "" "Linux standard trash is not supported. \n" "Desktop trash folder will be created." msgstr "" #: f.file.cc:1051 msgid "Move read-only file to trash?" msgstr "¿Enviar el fichero de solo lectura a la papelera?" #: f.file.cc:1077 #, c-format msgid "Cannot create trash folder: %s" msgstr "No se puede crear carpeta de papelera: %s" #: f.file.cc:1085 f.file.cc:1091 zfuncs.cc:3356 #, c-format msgid "error: %s" msgstr "error: %s" #: f.file.cc:1136 fotoxx-12.01.cc:198 msgid "Rename Image File" msgstr "Renombrar archivo de imagen" #: f.file.cc:1141 msgid "old name" msgstr "Nombre antiguo" #: f.file.cc:1142 msgid "rename to" msgstr "Renombrar como" #: f.file.cc:1143 msgid "previous" msgstr "Anterior" #: f.file.cc:1229 msgid "The target file already exists" msgstr "El archivo de destino ya existe" #: f.file.cc:1237 #, c-format msgid "" "Rename failed: \n" " %s" msgstr "" #: f.file.cc:1285 msgid "Batch Rename" msgstr "" #: f.file.cc:1288 f.file.cc:1340 f.info.cc:1519 f.info.cc:1773 f.tools.cc:543 #: f.tools.cc:2990 #, c-format msgid "%d files selected" msgstr "" #: f.file.cc:1290 msgid "new base name" msgstr "" #: f.file.cc:1293 msgid "starting sequence" msgstr "" #: f.file.cc:1295 msgid "increment" msgstr "" #: f.file.cc:1316 msgid "select files to rename" msgstr "" #: f.file.cc:1321 msgid "base name / sequence / increment not reasonable" msgstr "" #: f.file.cc:1380 msgid "new file already exists:" msgstr "" #: f.file.cc:1388 msgid "filespec too long:" msgstr "" #: f.file.cc:1399 msgid "Rename failed:" msgstr "" #: f.file.cc:1660 fotoxx.h:729 msgid "Add" msgstr "" #: f.file.cc:1660 fotoxx.h:781 msgid "Remove" msgstr "" #: f.file.cc:1662 msgid "menu name" msgstr "" #: f.file.cc:1733 f.file.cc:1754 msgid "Restart Fotoxx to update plugin menu" msgstr "" #: f.info.cc:70 msgid "Edit Caption and Comments" msgstr "" #: f.info.cc:156 fotoxx-12.01.cc:225 msgid "Edit Tags" msgstr "Editar etiquetas" #: f.info.cc:163 msgid "image date (yyyymmdd)" msgstr "Fecha de la imagen (aaaammdd)" #: f.info.cc:165 msgid "use last" msgstr "Usar el último" #: f.info.cc:168 msgid "image stars" msgstr "Imagen estrella" #: f.info.cc:186 msgid "current tags" msgstr "Etiquetas actuales" #: f.info.cc:191 msgid "recent tags" msgstr "" #: f.info.cc:196 f.info.cc:358 f.info.cc:1368 f.info.cc:2384 msgid "defined tags" msgstr "" #: f.info.cc:345 fotoxx-12.01.cc:226 msgid "Manage Tags" msgstr "" #: f.info.cc:348 msgid "category" msgstr "" #: f.info.cc:351 msgid "tag" msgstr "" #: f.info.cc:354 msgid "create" msgstr "" #: f.info.cc:355 f.navi.cc:1421 msgid "delete" msgstr "Borrar" #: f.info.cc:1235 f.info.cc:1319 #, c-format msgid "search index file error: %s" msgstr "" #: f.info.cc:1351 fotoxx-12.01.cc:227 msgid "Batch Add Tags" msgstr "" #: f.info.cc:1354 msgid "tags to add" msgstr "" #: f.info.cc:1359 msgid "create tag" msgstr "Crear etiqueta" #: f.info.cc:1415 f.info.cc:1608 #, c-format msgid "" "%s \n" " too many tags" msgstr "" #: f.info.cc:1553 fotoxx-12.01.cc:228 msgid "Batch Delete Tag" msgstr "" #: f.info.cc:1556 msgid "tag to remove" msgstr "" #: f.info.cc:1560 msgid "optional replacement" msgstr "" #: f.info.cc:1565 f.tools.cc:2943 msgid "0 files selected" msgstr "" #: f.info.cc:1568 msgid "search all files" msgstr "" #: f.info.cc:1653 msgid "no files selected" msgstr "" #: f.info.cc:1659 msgid "no tag specified" msgstr "" #: f.info.cc:1683 f.info.cc:1712 msgid "specify tag" msgstr "" #: f.info.cc:1821 msgid "View Info" msgstr "" #: f.info.cc:1889 fotoxx-12.01.cc:231 msgid "Edit Info" msgstr "" #: f.info.cc:1987 fotoxx-12.01.cc:232 msgid "Delete Info" msgstr "" #: f.info.cc:1989 fotoxx.h:731 msgid "All" msgstr "" #: f.info.cc:1990 msgid "One Key:" msgstr "" #: f.info.cc:2343 msgid "Search Tags, Comments, File Names" msgstr "" #: f.info.cc:2350 msgid "date range" msgstr "Rango de fechas" #: f.info.cc:2351 msgid "stars range" msgstr "Rango de estrellas" #: f.info.cc:2352 msgid "search tags" msgstr "Buscar etiquetas" #: f.info.cc:2353 msgid "search text" msgstr "" #: f.info.cc:2354 msgid "file names" msgstr "" #: f.info.cc:2359 msgid "(yyyymmdd)" msgstr "" #: f.info.cc:2365 msgid "all/any" msgstr "" #: f.info.cc:2702 msgid "No matching images found" msgstr "No se encontró ninguna imagen" #: f.info.cc:2706 f.info.cc:3059 msgid "No search index file present" msgstr "" #: f.info.cc:2777 msgid "Additional Items for Report" msgstr "" #: f.navi.cc:188 f.navi.cc:576 f.navi.cc:706 f.navi.cc:707 f.navi.cc:709 msgid "bigger" msgstr "Mayor" #: f.navi.cc:188 msgid "increase thumbnail size" msgstr "Aumentar tamaño de miniatura" #: f.navi.cc:189 msgid "reduce thumbnail size" msgstr "Reducir tamaño de la miniatura" #: f.navi.cc:189 f.navi.cc:586 f.navi.cc:708 f.navi.cc:710 msgid "smaller" msgstr "Menor" #: f.navi.cc:190 f.navi.cc:600 msgid "parent" msgstr "" #: f.navi.cc:190 msgid "parent directory" msgstr "" #: f.navi.cc:191 f.navi.cc:625 f.navi.cc:717 msgid "first page" msgstr "Primera página" #: f.navi.cc:191 msgid "jump to first file" msgstr "Cambiar al primer archivo" #: f.navi.cc:192 f.navi.cc:623 f.navi.cc:712 f.navi.cc:719 msgid "prev page" msgstr "Página anterior." #: f.navi.cc:192 msgid "previous page" msgstr "Página anterior" #: f.navi.cc:193 f.navi.cc:621 f.navi.cc:714 msgid "prev row" msgstr "Fila anterior." #: f.navi.cc:193 msgid "previous row" msgstr "Fila anterior" #: f.navi.cc:194 f.navi.cc:622 f.navi.cc:715 msgid "next row" msgstr "Siguiente fila" #: f.navi.cc:195 f.navi.cc:624 f.navi.cc:713 f.navi.cc:720 msgid "next page" msgstr "Página sig." #: f.navi.cc:195 msgid "ttip::next page" msgstr "" #: f.navi.cc:196 msgid "jump to last file" msgstr "Cambiar al último archivo" #: f.navi.cc:196 f.navi.cc:626 f.navi.cc:718 msgid "last page" msgstr "Última página" #: f.navi.cc:197 f.navi.cc:571 msgid "close" msgstr "Cerrar" #: f.navi.cc:197 msgid "close image gallery" msgstr "Cerrar la galería de imágenes" #: f.navi.cc:1413 fotoxx.h:787 msgid "Select Files" msgstr "" #: f.navi.cc:1413 zfuncs.cc:6296 zfuncs.cc:6332 zfuncs.cc:6485 zfuncs.cc:6728 #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "cancel" msgstr "Cancelar" #: f.navi.cc:1413 zfuncs.cc:6728 msgid "done" msgstr "" #: f.navi.cc:1422 msgid "insert" msgstr "Insertar" #: f.navi.cc:1423 msgid "add all" msgstr "" #: f.retouch.cc:55 msgid "Adjust Brightness and Color" msgstr "Ajustar brillo y color" #: f.retouch.cc:110 msgid "small-steps" msgstr "" #: f.retouch.cc:119 msgid "color saturation" msgstr "Saturación de color" #: f.retouch.cc:126 msgid " reset 1 " msgstr " Restablecer 1" #: f.retouch.cc:127 msgid "reset all" msgstr "Restablecer todo" #: f.retouch.cc:599 msgid "adjust image gamma" msgstr "" #: f.retouch.cc:885 msgid "Expand Brightness Range" msgstr "" #: f.retouch.cc:887 msgid "bright pixels" msgstr "" #: f.retouch.cc:1058 msgid "Flatten Brightness Distribution" msgstr "Distribución uniforme del brillo" #: f.retouch.cc:1072 msgid "Flatten" msgstr "Aplanar" #: f.retouch.cc:1334 msgid "Ramp brightness across image" msgstr "" #: f.retouch.cc:1730 fotoxx-12.01.cc:272 msgid "Tone Mapping" msgstr "" #: f.retouch.cc:1758 msgid "low" msgstr "" #: f.retouch.cc:1760 msgid "high" msgstr "" #: f.retouch.cc:1763 msgid "Amplify" msgstr "" #: f.retouch.cc:2069 msgid "Adjust White Balance" msgstr "Ajustar balance de blanco" #: f.retouch.cc:2070 msgid "Click white or gray image location" msgstr "Haga clic en la ubicación de la imagen en blanco o gris" #: f.retouch.cc:2278 msgid "Color Match Images" msgstr "" #: f.retouch.cc:2307 msgid "mouse radius for color sample" msgstr "" #: f.retouch.cc:2309 f.retouch.cc:2314 fotoxx-12.01.cc:246 fotoxx-12.01.cc:325 #: fotoxx.h:769 msgid "Open" msgstr "Abrir" #: f.retouch.cc:2310 msgid "image for source color" msgstr "" #: f.retouch.cc:2312 msgid "click on image to get source color" msgstr "" #: f.retouch.cc:2315 msgid "image to set matching color" msgstr "" #: f.retouch.cc:2317 msgid "click on image to set matching color" msgstr "" #: f.retouch.cc:2372 msgid "select source image color first" msgstr "" #: f.retouch.cc:2584 msgid "Add standard bias" msgstr "" #: f.retouch.cc:2591 msgid "+Brightness -Density" msgstr "" #: f.retouch.cc:2592 msgid "+Red -Cyan" msgstr "" #: f.retouch.cc:2593 msgid "+Green -Magenta" msgstr "" #: f.retouch.cc:2594 msgid "+Blue -Yellow" msgstr "" #: f.retouch.cc:2599 msgid "Contrast" msgstr "" #: f.retouch.cc:2600 fotoxx.h:778 msgid "Red" msgstr "Rojo" #: f.retouch.cc:2601 fotoxx.h:758 msgid "Green" msgstr "Verde" #: f.retouch.cc:2602 fotoxx.h:736 msgid "Blue" msgstr "Azul" #: f.retouch.cc:2730 msgid "Load DRGB parameters" msgstr "" #: f.retouch.cc:2732 f.retouch.cc:2804 f.retouch.cc:6102 f.retouch.cc:6198 msgid "File:" msgstr "" #: f.retouch.cc:2751 f.retouch.cc:2824 msgid "DRGB parameters file" msgstr "" #: f.retouch.cc:2769 f.retouch.cc:6142 msgid "file not found" msgstr "" #: f.retouch.cc:2802 msgid "Save DRGB parameters" msgstr "" #: f.retouch.cc:3034 f.tools.cc:2404 msgid "Click image to select pixels." msgstr "" #: f.retouch.cc:3072 fotoxx-12.01.cc:276 msgid "Revise RGB" msgstr "" #: f.retouch.cc:3084 msgid "Metric:" msgstr "" #: f.retouch.cc:3139 msgid "Blend" msgstr "" #: f.retouch.cc:3519 msgid "" "Method 1:\n" " Left-click on red-eye to darken.\n" "Method 2:\n" " Drag down and right to enclose red-eye.\n" " Left-click on red-eye to darken.\n" "Undo red-eye:\n" " Right-click on red-eye." msgstr "" "Método 1:\n" " Clic-izquierdo en el ojo rojo para oscurecer.\n" "Método 2:\n" " Pica y arrastra a la derecha para delimitar el ojo rojo.\n" " Clic-izquierdo para oscurecer el ojo rojo.\n" "Deshacer ojos rojos:\n" " Clic-derecho en el ojo rojo." #: f.retouch.cc:3534 msgid "Red Eye Reduction" msgstr "Reducción de ojos rojos" #: f.retouch.cc:3968 msgid "Set Blur Radius" msgstr "Establecer radio de desenfoque" #: f.retouch.cc:4195 fotoxx-12.01.cc:279 msgid "Sharpen Image" msgstr "Enfoque de imagen" #: f.retouch.cc:4202 msgid "edge detection" msgstr "Detección de borde" #: f.retouch.cc:4203 msgid "cycles" msgstr "Ciclos" #: f.retouch.cc:4204 msgid "reduce" msgstr "reducir" #: f.retouch.cc:4215 msgid "unsharp mask" msgstr "Máscara de desenfoque" #: f.retouch.cc:4228 msgid "brightness gradient" msgstr "" #: f.retouch.cc:4634 msgid "" " Press the reduce button to \n" " reduce noise in small steps. \n" " Use undo to start over." msgstr "" " Pulse el botón de reducción para \n" " reducir el ruido en pequeños pasos. \n" " Utilice Deshacer para empezar de nuevo." #: f.retouch.cc:4645 msgid "Noise Reduction" msgstr "Reducción de ruido" #: f.retouch.cc:4650 msgid "algorithm" msgstr "algoritmo" #: f.retouch.cc:4657 msgid "flatten outliers by color (1)" msgstr "Aplanar los valores extremos de color (1)" #: f.retouch.cc:4658 msgid "flatten outliers by color (2)" msgstr "Aplanar los valores extremos de color (2)" #: f.retouch.cc:4659 msgid "set median brightness by color" msgstr "Configurar la mediana de brillo por color" #: f.retouch.cc:4660 f.retouch.cc:4661 msgid "top hat filter by color" msgstr "Filtro de color «sombrero de copa (Top-hat)»" #: f.retouch.cc:4976 msgid "" "1. Drag mouse to select. \n" "2. Erase. 3. Repeat. " msgstr "" #: f.retouch.cc:4998 fotoxx-12.01.cc:281 msgid "Smart Erase" msgstr "" #: f.retouch.cc:5003 fotoxx.h:776 msgid "Radius" msgstr "Radio" #: f.retouch.cc:5005 msgid "Blur" msgstr "" #: f.retouch.cc:5008 msgid "New Area" msgstr "" #: f.retouch.cc:5379 fotoxx-12.01.cc:282 msgid "Remove Dust" msgstr "" #: f.retouch.cc:5383 msgid "spot size limit" msgstr "" #: f.retouch.cc:5386 msgid "max. brightness" msgstr "" #: f.retouch.cc:5389 msgid "min. contrast" msgstr "" #: f.retouch.cc:5983 fotoxx-12.01.cc:283 msgid "Fix Stuck Pixels" msgstr "" #: f.retouch.cc:5989 msgid "pixel group" msgstr "" #: f.retouch.cc:5990 msgid "circle color" msgstr "" #: f.retouch.cc:6100 msgid "Load Stuck Pixels" msgstr "" #: f.retouch.cc:6124 f.retouch.cc:6220 msgid "Stuck Pixels file" msgstr "" #: f.retouch.cc:6164 msgid "file format error" msgstr "" #: f.retouch.cc:6192 msgid "there are zero stuck pixels" msgstr "" #: f.retouch.cc:6196 msgid "Save Stuck Pixels" msgstr "" #: f.retouch.cc:6686 #, c-format msgid "Undo Memory %d%c" msgstr "Memoria de deshacer %d%c" #: f.retouch.cc:6688 fotoxx-12.01.cc:284 msgid "Edit Pixels" msgstr "Editar píxeles" #: f.retouch.cc:6695 msgid "pick" msgstr "Recoger" #: f.retouch.cc:6697 msgid "erase" msgstr "Borrar" #: f.retouch.cc:6705 msgid "paintbrush radius" msgstr "Radio del pincel" #: f.retouch.cc:6706 msgid "transparency center" msgstr "Centro de la transparencia" #: f.retouch.cc:6707 msgid "transparency edge" msgstr "Borde de la transparencia" #: f.retouch.cc:6972 msgid "" "Undo memory limit has been reached. \n" "Save work with [done], then resume editing." msgstr "" "Se alcanzó el límite de memoria de deshacer. \n" "Guarde el trabajo con [Hecho], y luego reanude la edición." #: f.select.cc:54 f.select.cc:2461 msgid "Select Area for Edits" msgstr "" #: f.select.cc:55 f.select.cc:2462 msgid "Press F1 for help" msgstr "" #: f.select.cc:64 msgid "" "Select Area not supported \n" "by this edit function" msgstr "" #: f.select.cc:103 f.tools.cc:901 msgid "rectangle" msgstr "" #: f.select.cc:104 f.tools.cc:902 msgid "ellipse" msgstr "" #: f.select.cc:110 msgid "draw: freehand" msgstr "" #: f.select.cc:111 msgid "draw: follow edge" msgstr "" #: f.select.cc:114 msgid "select by mouse" msgstr "" #: f.select.cc:116 f.select.cc:2496 msgid "mouse radius" msgstr "" #: f.select.cc:120 msgid "match mouse color" msgstr "" #: f.select.cc:124 msgid "search range" msgstr "" #: f.select.cc:126 msgid "firewall" msgstr "" #: f.select.cc:326 f.select.cc:467 #, c-format msgid "exceed %d edits" msgstr "" #: f.select.cc:1021 msgid "" "Click one time inside each enclosed area \n" "(possible gaps in the outline will be found). \n" "Press F1 for help." msgstr "" #: f.select.cc:1078 msgid "finish area" msgstr "" #: f.select.cc:1113 msgid "searching" msgstr "" #: f.select.cc:1185 msgid "outline has a gap" msgstr "" #: f.select.cc:1189 msgid "success" msgstr "" #: f.select.cc:1440 f.select.cc:1470 msgid "the area is not finished" msgstr "" #: f.select.cc:1563 msgid "Edge calculation in progress" msgstr "Necesita calcular el borde" #: f.select.cc:1572 msgid "Area Edge Calc" msgstr "Calcular el área de borde" #: f.select.cc:1863 msgid "position with mouse click/drag" msgstr "" #: f.select.cc:1887 msgid "Paste Image" msgstr "" #: f.select.cc:1901 msgid "angle" msgstr "" #: f.select.cc:2160 msgid "load select area from a file" msgstr "" #: f.select.cc:2194 msgid "cannot open .tiff and .info files" msgstr "" #: f.select.cc:2213 msgid "save select area to a file" msgstr "" #: f.select.cc:2248 fotoxx-12.01.cc:248 msgid "Select Whole Image" msgstr "" #: f.select.cc:2249 msgid "Edit Function Amplifier" msgstr "" #: f.select.cc:2463 msgid "Edit function must be active" msgstr "" #: f.select.cc:2499 msgid "power: center" msgstr "" #: f.select.cc:2501 msgid "edge" msgstr "" #: f.select.cc:2504 msgid "reset area" msgstr "" #: f.tools.cc:42 msgid "" "When editing a collection, right-click \n" "an image or thumbnail to add or remove." msgstr "" #: f.tools.cc:70 fotoxx-12.01.cc:204 msgid "Manage Collections" msgstr "" #: f.tools.cc:85 msgid "Start new collection" msgstr "" #: f.tools.cc:87 msgid "Edit a collection" msgstr "" #: f.tools.cc:89 msgid "View a collection" msgstr "" #: f.tools.cc:91 msgid "Delete a collection" msgstr "" #: f.tools.cc:95 msgid "Editing:" msgstr "" #: f.tools.cc:99 msgid "Action:" msgstr "" #: f.tools.cc:133 msgid "New Collection" msgstr "" #: f.tools.cc:156 msgid "Edit Collection" msgstr "" #: f.tools.cc:172 msgid "View Collection" msgstr "" #: f.tools.cc:193 msgid "Delete Collection" msgstr "" #: f.tools.cc:196 #, c-format msgid "delete %s ?" msgstr "" #: f.tools.cc:223 #, c-format msgid "add image to collection: %s" msgstr "" #: f.tools.cc:225 f.tools.cc:270 msgid "remove image from collection" msgstr "" #: f.tools.cc:226 f.tools.cc:271 f.tools.cc:298 msgid "remove and save image" msgstr "" #: f.tools.cc:227 f.tools.cc:316 msgid "insert saved images here" msgstr "" #: f.tools.cc:256 msgid "add image to collection" msgstr "" #: f.tools.cc:301 msgid "too many saved files" msgstr "" #: f.tools.cc:373 fotoxx-12.01.cc:205 msgid "Move Collections" msgstr "" #: f.tools.cc:375 msgid "old top directory" msgstr "" #: f.tools.cc:378 msgid "new top directory" msgstr "" #: f.tools.cc:434 msgid "completed" msgstr "" #: f.tools.cc:467 msgid "Batch Convert/Resize/Export" msgstr "" #: f.tools.cc:474 msgid "new max. width" msgstr "" #: f.tools.cc:481 msgid "new file type" msgstr "" #: f.tools.cc:482 msgid "same" msgstr "" #: f.tools.cc:490 msgid "replace originals" msgstr "" #: f.tools.cc:491 msgid "export to location" msgstr "" #: f.tools.cc:492 msgid "remove EXIF" msgstr "" #: f.tools.cc:549 msgid "Select directory" msgstr "" #: f.tools.cc:583 #, c-format msgid "replace original files? (max. %d x %d)" msgstr "" #: f.tools.cc:590 #, c-format msgid "" "copy files? (max. %d x %d) \n" " to location %s" msgstr "" #: f.tools.cc:601 msgid "location is not a valid directory" msgstr "" #: f.tools.cc:608 f.tools.cc:3007 #, c-format msgid "max. size %d x %d is not reasonable" msgstr "" #: f.tools.cc:654 msgid "*** file already exists" msgstr "" #: f.tools.cc:662 msgid "*** file type not supported" msgstr "" #: f.tools.cc:741 msgid "Program ufraw-batch is required" msgstr "" #: f.tools.cc:751 fotoxx.h:770 msgid "Open RAW File" msgstr "Abrir fichero RAW" #: f.tools.cc:764 msgid "Select RAW files to convert" msgstr "" #: f.tools.cc:769 msgid "Choose file type" msgstr "" #: f.tools.cc:888 msgid "Press ESC to exit slide show" msgstr "" #: f.tools.cc:889 msgid "show only latest file versions" msgstr "" #: f.tools.cc:893 msgid "arrow keys" msgstr "" #: f.tools.cc:894 msgid "instant" msgstr "" #: f.tools.cc:895 msgid "fade-in" msgstr "" #: f.tools.cc:896 msgid "roll-right" msgstr "" #: f.tools.cc:897 msgid "roll-down" msgstr "" #: f.tools.cc:898 msgid "shift-left" msgstr "" #: f.tools.cc:899 msgid "venetian" msgstr "" #: f.tools.cc:900 msgid "grate" msgstr "" #: f.tools.cc:903 msgid "radar" msgstr "" #: f.tools.cc:904 msgid "jaws" msgstr "" #: f.tools.cc:911 fotoxx-12.01.cc:208 msgid "Slide Show" msgstr "Diaporama" #: f.tools.cc:915 msgid "seconds" msgstr "segundos" #: f.tools.cc:919 msgid "music file" msgstr "" #: f.tools.cc:923 msgid "transitions" msgstr "" #: f.tools.cc:1040 msgid "Select music file or playlist" msgstr "" #: f.tools.cc:1727 msgid "Sync Files is already running" msgstr "" #: f.tools.cc:1778 msgid "" "Run Tools > Synchronize Files so that gallery windows \n" "will be fast and Search Images will work correctly. \n" "You can view (not edit) images while synchronize runs." msgstr "" #: f.tools.cc:1812 msgid "no top image directory is defined" msgstr "" #: f.tools.cc:1818 msgid "top image directory is invalid" msgstr "" #: f.tools.cc:1823 msgid "no search index file is present" msgstr "" #: f.tools.cc:1837 msgid "new/modified files are present" msgstr "" #: f.tools.cc:1844 msgid "no new files found" msgstr "" #: f.tools.cc:1859 fotoxx-12.01.cc:209 msgid "Synchronize Files" msgstr "" #: f.tools.cc:1861 msgid "Top Image Directory:" msgstr "" #: f.tools.cc:1883 msgid "" "file sync is necessary.\n" "cancel anyway?" msgstr "" #: f.tools.cc:1896 msgid "top directory is invalid" msgstr "" #: f.tools.cc:2292 msgid "Select top image directory" msgstr "Seleccionar el directorio raíz de imágenes" #: f.tools.cc:2429 fotoxx-12.01.cc:210 msgid "Show RGB" msgstr "Mostrar RGB" #: f.tools.cc:2719 fotoxx-12.01.cc:211 msgid "Grid Lines" msgstr "" #: f.tools.cc:2728 msgid "x-spacing" msgstr "" #: f.tools.cc:2729 msgid "x-count" msgstr "" #: f.tools.cc:2730 msgid "x-enable" msgstr "" #: f.tools.cc:2736 msgid "y-spacing" msgstr "" #: f.tools.cc:2737 msgid "y-count" msgstr "" #: f.tools.cc:2738 msgid "y-enable" msgstr "" #: f.tools.cc:2745 msgid "x-offset" msgstr "" #: f.tools.cc:2749 msgid "y-offset" msgstr "" #: f.tools.cc:2940 fotoxx-12.01.cc:213 msgid "E-mail Images" msgstr "" #: f.tools.cc:2947 msgid "max. width" msgstr "" #: f.tools.cc:2948 msgid "max. height" msgstr "" #: f.tools.cc:3093 msgid "too many files" msgstr "" #: f.tools.cc:3134 msgid "" "Brightness should show a gradual ramp \n" "extending all the way to the edges." msgstr "" #: f.tools.cc:3174 msgid "Monitor Check" msgstr "" #: f.tools.cc:3232 fotoxx-12.01.cc:215 msgid "Monitor Gamma" msgstr "" #: f.tools.cc:3294 fotoxx-12.01.cc:216 msgid "Brightness Distribution" msgstr "Distribuir el brillo" #: f.tools.cc:3432 msgid "Available Translations" msgstr "Traducciones disponibles" #: f.tools.cc:3436 msgid "Set Language" msgstr "Seleccionar el idioma" #: f.tools.cc:3502 msgid "Make Launcher" msgstr "" #: f.tools.cc:3540 msgid "Settings" msgstr "" #: f.tools.cc:3545 msgid "Startup Display" msgstr "" #: f.tools.cc:3547 msgid "Recent Files Gallery" msgstr "" #: f.tools.cc:3548 msgid "Previous Image Viewed" msgstr "" #: f.tools.cc:3549 msgid "Blank Window" msgstr "" #: f.tools.cc:3551 msgid "Directory Gallery" msgstr "" #: f.tools.cc:3556 msgid "Image File" msgstr "" #: f.tools.cc:3562 msgid "Toolbar Style" msgstr "" #: f.tools.cc:3563 f.transform.cc:1300 msgid "Text" msgstr "" #: f.tools.cc:3564 msgid "Icons" msgstr "" #: f.tools.cc:3565 msgid "Both" msgstr "" #: f.tools.cc:3568 msgid "Warn Overwrite" msgstr "" #: f.tools.cc:3639 msgid "startup directory is invalid" msgstr "" #: f.tools.cc:3650 msgid "startup file is invalid" msgstr "" #: f.tools.cc:3707 msgid "Select startup directory" msgstr "" #: f.tools.cc:3715 msgid "Select startup image file" msgstr "" #: f.transform.cc:50 msgid "Use buttons or drag right edge with mouse" msgstr "Utilice los botones o arrastre el borde derecho con el ratón" #: f.transform.cc:60 fotoxx-12.01.cc:252 msgid "Rotate Image" msgstr "Rotar imagen" #: f.transform.cc:64 msgid "degrees" msgstr "Grados" #: f.transform.cc:80 f.transform.cc:124 msgid "Trim" msgstr "Recortar" #: f.transform.cc:81 f.transform.cc:2289 f.transform.cc:3120 #: f.transform.cc:3383 f.transform.cc:3644 msgid "Grid" msgstr "" #: f.transform.cc:123 msgid "Undo Trim" msgstr "Deshacer recortar" #: f.transform.cc:139 #, c-format msgid "degrees: %.1f" msgstr "Grados: %.1f" #: f.transform.cc:286 msgid "gold" msgstr "" #: f.transform.cc:334 msgid "Drag middle to move, drag corners to resize." msgstr "" #: f.transform.cc:348 fotoxx-12.01.cc:253 msgid "Trim Image" msgstr "Recortar imagen" #: f.transform.cc:348 msgid "customize" msgstr "" #: f.transform.cc:359 msgid "ratio" msgstr "" #: f.transform.cc:363 msgid "Lock Ratio" msgstr "Bloquear la relación" #: f.transform.cc:368 msgid "invert" msgstr "" #: f.transform.cc:890 msgid "Trim Buttons" msgstr "" #: f.transform.cc:1064 msgid "Lock aspect ratio" msgstr "Bloquar la relación de aspecto" #: f.transform.cc:1072 fotoxx-12.01.cc:255 msgid "Resize Image" msgstr "Redimensionar imagen" #: f.transform.cc:1095 fotoxx-12.01.cc:326 msgid "Prev" msgstr "Anterior" #: f.transform.cc:1245 msgid "" "Enter text, click/drag on image.\n" "Right click to remove" msgstr "" #: f.transform.cc:1294 fotoxx-12.01.cc:256 msgid "Annotate Image" msgstr "" #: f.transform.cc:1307 msgid "Size" msgstr "Tamaño" #: f.transform.cc:1310 msgid "Angle" msgstr "" #: f.transform.cc:1321 fotoxx.h:741 msgid "Color" msgstr "" #: f.transform.cc:1322 msgid "Transparency" msgstr "" #: f.transform.cc:1325 msgid "text" msgstr "" #: f.transform.cc:1330 msgid "backing" msgstr "" #: f.transform.cc:1333 msgid "" "Outline\n" " Width" msgstr "" #: f.transform.cc:1335 msgid "outline" msgstr "" #: f.transform.cc:1342 msgid "Annotation File:" msgstr "" #: f.transform.cc:1416 msgid "select font" msgstr "" #: f.transform.cc:2045 fotoxx-12.01.cc:257 msgid "Flip Image" msgstr "" #: f.transform.cc:2049 f.transform.cc:2281 msgid "horizontal" msgstr "Horizontal" #: f.transform.cc:2050 f.transform.cc:2280 msgid "vertical" msgstr "Vertical" #: f.transform.cc:2155 fotoxx-12.01.cc:258 msgid "Make Negative" msgstr "" #: f.transform.cc:2158 msgid "black/white positive" msgstr "" #: f.transform.cc:2159 msgid "black/white negative" msgstr "" #: f.transform.cc:2160 msgid "color positive" msgstr "" #: f.transform.cc:2161 msgid "color negative" msgstr "" #: f.transform.cc:2272 fotoxx-12.01.cc:259 msgid "Unbend Image" msgstr "Enderezar imagen" #: f.transform.cc:2282 msgid "linear" msgstr "" #: f.transform.cc:2285 msgid "curved" msgstr "" #: f.transform.cc:2544 msgid "" " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle." msgstr "" #: f.transform.cc:2556 fotoxx-12.01.cc:260 msgid "Keystone Correction" msgstr "" #: f.transform.cc:2724 msgid "must have 4 corners" msgstr "" #: f.transform.cc:2847 msgid "" " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]." msgstr "" " Seleccione una área para deformar utilizando el botón [Seleccionar]. \n" " Pulse [Comenzar deformación] y tire de la área con el ratón. \n" " Hacer varios tirones con el ratón hasta que quede satisfecho. \n" " Cuando haya terminado, seleccione otra área o pulse [Hecho]." #: f.transform.cc:2859 fotoxx-12.01.cc:261 msgid "Warp Image (area)" msgstr "" #: f.transform.cc:2864 msgid "start warp" msgstr "Comenzar deformación" #: f.transform.cc:2931 msgid "no active Select Area" msgstr "" #: f.transform.cc:3099 f.transform.cc:3362 msgid "" " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" #: f.transform.cc:3112 fotoxx-12.01.cc:262 msgid "Warp Image (curved)" msgstr "" #: f.transform.cc:3375 fotoxx-12.01.cc:263 msgid "Warp Image (linear)" msgstr "" #: f.transform.cc:3628 msgid "" " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]." msgstr "" " Tirar de un borde de la imagen utilizando el ratón. \n" " Hacer varios tirones con el ratón hasta que quede satisfecho. \n" " Cuando haya terminado, pulse [Hecho]." #: f.transform.cc:3639 fotoxx-12.01.cc:264 msgid "Warp Image (affine)" msgstr "" #: fotoxx-12.01.cc:185 msgid "File" msgstr "Archivo" #: fotoxx-12.01.cc:186 fotoxx-12.01.cc:324 msgid "Image Gallery" msgstr "Galería de imágenes" #: fotoxx-12.01.cc:187 msgid "Clone 50/50" msgstr "" #: fotoxx-12.01.cc:188 msgid "Clone Overlay" msgstr "" #: fotoxx-12.01.cc:190 msgid "Open in New Window" msgstr "" #: fotoxx-12.01.cc:191 fotoxx-12.01.cc:326 msgid "Open Previous File" msgstr "Abrir archivo anterior" #: fotoxx-12.01.cc:192 msgid "Open Recent File" msgstr "Abrir archivo reciente" #: fotoxx-12.01.cc:193 fotoxx-12.01.cc:334 msgid "Save to Same File" msgstr "Guardar en el mismo archivo" #: fotoxx-12.01.cc:194 fotoxx-12.01.cc:335 msgid "Save to New Version" msgstr "" #: fotoxx-12.01.cc:195 fotoxx-12.01.cc:336 msgid "Save to New File" msgstr "Guardar en un archivo nuevo" #: fotoxx-12.01.cc:197 msgid "Trash Image File" msgstr "Mover imagen a la papelera" #: fotoxx-12.01.cc:199 msgid "Batch Rename Files" msgstr "" #: fotoxx-12.01.cc:200 msgid "Print Image File" msgstr "Imprimir archivo de imagen" #: fotoxx-12.01.cc:201 fotoxx-12.01.cc:340 msgid "Quit fotoxx" msgstr "Salir de Fotoxx" #: fotoxx-12.01.cc:203 msgid "Tools" msgstr "Herramientas" #: fotoxx-12.01.cc:206 msgid "Batch Convert" msgstr "" #: fotoxx-12.01.cc:207 msgid "Convert RAW files" msgstr "Convetir múltiples archivos RAW" #: fotoxx-12.01.cc:212 msgid "Burn Images to CD/DVD" msgstr "Grabar imágenes en un CD/DVD" #: fotoxx-12.01.cc:214 msgid "Check Monitor" msgstr "Comprobar monitor" #: fotoxx-12.01.cc:217 msgid "Change Language" msgstr "Cambiar el idioma" #: fotoxx-12.01.cc:219 msgid "Menu and Launcher" msgstr "" #: fotoxx-12.01.cc:220 msgid "User Settings" msgstr "" #: fotoxx-12.01.cc:221 msgid "Memory Usage" msgstr "" #: fotoxx-12.01.cc:224 msgid "Edit Caption/Comments" msgstr "" #: fotoxx-12.01.cc:229 msgid "View Info (short)" msgstr "" #: fotoxx-12.01.cc:230 msgid "View Info (long)" msgstr "" #: fotoxx-12.01.cc:233 msgid "Search Images" msgstr "" #: fotoxx-12.01.cc:234 msgid "Search Metadata" msgstr "" #: fotoxx-12.01.cc:236 fotoxx-12.01.cc:237 fotoxx.h:786 msgid "Select" msgstr "" #: fotoxx-12.01.cc:238 fotoxx.h:788 msgid "Show" msgstr "Mostrar" #: fotoxx-12.01.cc:239 fotoxx.h:761 msgid "Hide" msgstr "Ocultar" #: fotoxx-12.01.cc:240 fotoxx.h:752 msgid "Enable" msgstr "" #: fotoxx-12.01.cc:241 fotoxx.h:748 msgid "Disable" msgstr "Desactivar" #: fotoxx-12.01.cc:242 fotoxx.h:763 msgid "Invert" msgstr "Invertir" #: fotoxx-12.01.cc:243 fotoxx.h:796 msgid "Unselect" msgstr "" #: fotoxx-12.01.cc:244 fotoxx.h:743 msgid "Copy" msgstr "" #: fotoxx-12.01.cc:245 fotoxx.h:771 msgid "Paste" msgstr "" #: fotoxx-12.01.cc:247 fotoxx-12.01.cc:334 fotoxx.h:783 msgid "Save" msgstr "Guardar" #: fotoxx-12.01.cc:249 msgid "Select and Edit" msgstr "" #: fotoxx-12.01.cc:251 msgid "Transform" msgstr "" #: fotoxx-12.01.cc:254 msgid "Auto-Trim Image" msgstr "" #: fotoxx-12.01.cc:266 msgid "Retouch" msgstr "Retocar" #: fotoxx-12.01.cc:267 msgid "Brightness/Color" msgstr "Ajustar brillo y color" #: fotoxx-12.01.cc:268 msgid "Gamma Curves" msgstr "" #: fotoxx-12.01.cc:269 msgid "Expand Brightness" msgstr "" #: fotoxx-12.01.cc:270 msgid "Flatten Brightness" msgstr "Distribuir el brillo uniformemente" #: fotoxx-12.01.cc:271 msgid "Brightness Ramp" msgstr "" #: fotoxx-12.01.cc:273 msgid "White Balance" msgstr "Balance de blanco" #: fotoxx-12.01.cc:274 msgid "Match Colors" msgstr "" #: fotoxx-12.01.cc:277 msgid "Red Eyes" msgstr "Ojos rojos" #: fotoxx-12.01.cc:278 msgid "Blur Image" msgstr "Imagen borrosa" #: fotoxx-12.01.cc:280 msgid "Reduce Noise" msgstr "Reducción de ruido" #: fotoxx-12.01.cc:286 msgid "Art" msgstr "Arte" #: fotoxx-12.01.cc:287 msgid "Color Depth" msgstr "Profundidad de color" #: fotoxx-12.01.cc:288 msgid "Drawing" msgstr "" #: fotoxx-12.01.cc:289 msgid "Outlines" msgstr "" #: fotoxx-12.01.cc:290 msgid "Embossing" msgstr "" #: fotoxx-12.01.cc:291 msgid "Tiles" msgstr "" #: fotoxx-12.01.cc:292 msgid "Dots" msgstr "" #: fotoxx-12.01.cc:293 msgid "Painting" msgstr "" #: fotoxx-12.01.cc:295 msgid "Combine" msgstr "Combinar" #: fotoxx-12.01.cc:296 msgid "High Dynamic Range" msgstr "" #: fotoxx-12.01.cc:297 msgid "High Depth of Field" msgstr "" #: fotoxx-12.01.cc:298 msgid "Stack / Paint" msgstr "" #: fotoxx-12.01.cc:299 msgid "Stack / Noise" msgstr "" #: fotoxx-12.01.cc:300 msgid "Panorama" msgstr "Panoramica" #: fotoxx-12.01.cc:301 msgid "Vertical Panorama" msgstr "" #: fotoxx-12.01.cc:304 msgid "Edit Plugins" msgstr "" #: fotoxx-12.01.cc:313 fotoxx-12.01.cc:341 fotoxx-12.01.cc:3026 msgid "Help" msgstr "Ayuda" #: fotoxx-12.01.cc:314 fotoxx-12.01.cc:3016 msgid "About" msgstr "Acerca de" #: fotoxx-12.01.cc:315 fotoxx-12.01.cc:3020 msgid "User Guide" msgstr "Guía de usuario" #: fotoxx-12.01.cc:316 fotoxx-12.01.cc:3023 msgid "User Guide Changes" msgstr "" #: fotoxx-12.01.cc:317 fotoxx-12.01.cc:3032 msgid "Edit Functions Summary" msgstr "" #: fotoxx-12.01.cc:318 fotoxx-12.01.cc:3035 msgid "Change Log" msgstr "Editar el registro" #: fotoxx-12.01.cc:319 fotoxx-12.01.cc:3038 msgid "Translations" msgstr "" #: fotoxx-12.01.cc:320 fotoxx-12.01.cc:3041 msgid "Home Page" msgstr "Página de inicio" #: fotoxx-12.01.cc:324 msgid "Gallery" msgstr "Galería" #: fotoxx-12.01.cc:327 fotoxx.h:767 msgid "Next" msgstr "Siguiente" #: fotoxx-12.01.cc:327 msgid "Open Next File" msgstr "Abrir siguiente archivo" #: fotoxx-12.01.cc:328 msgid "Zoom-in (bigger)" msgstr "Zoom ampliar" #: fotoxx-12.01.cc:329 msgid "Zoom-out (smaller)" msgstr "Zoom reducir" #: fotoxx-12.01.cc:330 fotoxx.h:794 msgid "Undo" msgstr "Deshacer" #: fotoxx-12.01.cc:330 msgid "Undo One Edit" msgstr "Deshacer un paso" #: fotoxx-12.01.cc:331 fotoxx.h:779 msgid "Redo" msgstr "Rehacer" #: fotoxx-12.01.cc:331 msgid "Redo One Edit" msgstr "Rehacer un paso" #: fotoxx-12.01.cc:335 msgid "Save+V" msgstr "" #: fotoxx-12.01.cc:336 msgid "Save+F" msgstr "" #: fotoxx-12.01.cc:337 msgid "Move Image to Trash" msgstr "Enviar la imagen a la papelera" #: fotoxx-12.01.cc:337 msgid "Trash" msgstr "Papelera" #: fotoxx-12.01.cc:340 msgid "Quit" msgstr "Salir" #: fotoxx-12.01.cc:341 msgid "Fotoxx Essentials" msgstr "" #: fotoxx-12.01.cc:448 msgid "first time startup" msgstr "" #: fotoxx-12.01.cc:1944 msgid "Exceed 50 anchor points" msgstr "Se exceden los 50 puntos de anclaje" #: fotoxx-12.01.cc:2129 msgid "load curve from a file" msgstr "" #: fotoxx-12.01.cc:2182 msgid "curve file is invalid" msgstr "" #: fotoxx-12.01.cc:2187 msgid "curve file has different no. of curves" msgstr "" #: fotoxx-12.01.cc:2202 msgid "save curve to a file" msgstr "" #: fotoxx-12.01.cc:2337 msgid "cannot parallel edit" msgstr "" #: fotoxx-12.01.cc:2347 msgid "" "exiftool is not installed \n" "edited images will lose EXIF data" msgstr "" "El paquete «exiftool» no está instalado \n" "al editar las imagenes se perderan los datos EXIF" #: fotoxx-12.01.cc:2353 msgid "Too many edits, please save image" msgstr "" #: fotoxx-12.01.cc:2358 msgid "" "Select area cannot be kept.\n" "Continue?" msgstr "" "No se puede conservar la selección de área.\n" "¿Continuar?" #: fotoxx-12.01.cc:2366 msgid "" "Select area not active.\n" "Continue?" msgstr "" #: fotoxx-12.01.cc:2837 msgid "Discard edits?" msgstr "" #: fotoxx-12.01.cc:2838 msgid "" "This action will discard current edits.\n" "Continue to discard edits.\n" "Go Back to keep edits." msgstr "" #: fotoxx-12.01.cc:2841 msgid "Continue" msgstr "" #: fotoxx-12.01.cc:2842 msgid "Go Back" msgstr "" #: fotoxx-12.01.cc:3659 msgid "cannot open thumbnail file" msgstr "" #: fotoxx-12.01.cc:3870 fotoxx-12.01.cc:3992 msgid "TIFF open failure" msgstr "" #: fotoxx-12.01.cc:3886 #, c-format msgid "TIFF bits/color=%d not supported" msgstr "" #: fotoxx-12.01.cc:3901 fotoxx-12.01.cc:3939 msgid "TIFF read failure" msgstr "" #: fotoxx-12.01.cc:4051 msgid "TIFF write failure" msgstr "" #: fotoxx-12.01.cc:4071 msgid "file type not supported" msgstr "" #: fotoxx-12.01.cc:4178 msgid "pixbuf write failure" msgstr "" #: fotoxx.h:728 msgid "absolute" msgstr "" #: fotoxx.h:730 msgid "Add All" msgstr "Añadir todo" #: fotoxx.h:732 msgid "Amount" msgstr "" #: fotoxx.h:733 msgid "Apply" msgstr "Aplicar" #: fotoxx.h:734 msgid "Black" msgstr "" #: fotoxx.h:735 msgid "Blend Width" msgstr "Mezclar por ancho" #: fotoxx.h:737 msgid "Brightness" msgstr "Brillo" #: fotoxx.h:738 msgid "Browse" msgstr "" #: fotoxx.h:739 msgid "Cancel" msgstr "Cancelar" #: fotoxx.h:740 msgid "Clear" msgstr "Limpiar" #: fotoxx.h:742 msgid "Commit" msgstr "" #: fotoxx.h:744 msgid "Curve File:" msgstr "" #: fotoxx.h:745 msgid "Cut" msgstr "" #: fotoxx.h:746 msgid "Darker Areas" msgstr "Oscurecer áreas" #: fotoxx.h:747 msgid "Delete" msgstr "Borrar" #: fotoxx.h:749 #, c-format msgid "" "Discard special gallery list? \n" " %s" msgstr "" #: fotoxx.h:750 msgid "Done" msgstr "Hecho" #: fotoxx.h:751 msgid "Edit" msgstr "Editar" #: fotoxx.h:753 msgid "Erase" msgstr "" #: fotoxx.h:754 msgid "package libimage-exiftool-perl is required" msgstr "" #: fotoxx.h:755 msgid "Fetch" msgstr "" #: fotoxx.h:756 msgid "Finish" msgstr "Terminar" #: fotoxx.h:757 msgid "Font" msgstr "" #: fotoxx.h:759 msgid "Height" msgstr "Altura" #: fotoxx.h:760 msgid "histogram" msgstr "" #: fotoxx.h:762 msgid "Insert" msgstr "Insertar" #: fotoxx.h:764 msgid "Lighter Areas" msgstr "Iluminar áreas" #: fotoxx.h:765 msgid "limit" msgstr "" #: fotoxx.h:766 msgid "New" msgstr "" #: fotoxx.h:768 msgid "OK" msgstr "Conforme" #: fotoxx.h:772 msgid "Pause" msgstr "" #: fotoxx.h:773 msgid "Percent" msgstr "Porcentaje" #: fotoxx.h:774 msgid "Presets" msgstr "Predefinidos" #: fotoxx.h:775 msgid "Proceed" msgstr "Proceder" #: fotoxx.h:777 msgid "range" msgstr "" #: fotoxx.h:780 msgid "Reduce" msgstr "Reducir" #: fotoxx.h:782 msgid "Reset" msgstr "" #: fotoxx.h:784 msgid "Unknown file type, save as tiff/jpeg/png to edit" msgstr "Tipo de fichero desconocido, guarde como tiff/jpeg/png para editarlo" #: fotoxx.h:785 msgid "Search" msgstr "Buscar" #: fotoxx.h:789 msgid "Start" msgstr "Comenzar" #: fotoxx.h:790 msgid "Threshold" msgstr "" #: fotoxx.h:791 #, c-format msgid "exceed %d files" msgstr "" #: fotoxx.h:792 msgid "Undo All" msgstr "Deshacer todo" #: fotoxx.h:793 msgid "Undo Last" msgstr "Deshacer el último" #: fotoxx.h:795 msgid "Unfinish" msgstr "" #: fotoxx.h:797 msgid "View" msgstr "" #: fotoxx.h:798 msgid "White" msgstr "" #: fotoxx.h:799 msgid "Width" msgstr "Ancho" #: zfuncs.cc:3252 #, c-format msgid "help file not found: %s" msgstr "Archivo de ayuda no encontrado: %s" #: zfuncs.cc:3664 zfuncs.cc:7315 #, c-format msgid "cannot open file %s" msgstr "No puedo abrir el archivo %s" #: zfuncs.cc:3697 msgid "save screen to file" msgstr "Guardar pantalla a archivo" #: zfuncs.cc:6222 msgid "No" msgstr "" #: zfuncs.cc:6222 msgid "Yes" msgstr "" #: zfuncs.cc:6447 msgid "open" msgstr "Abrir" #: zfuncs.cc:6452 msgid "choose" msgstr "" #: zfuncs.cc:6457 msgid "save" msgstr "Guardar" #: zfuncs.cc:6463 msgid "open folder" msgstr "Abrir carpeta" #: zfuncs.cc:6468 msgid "create folder" msgstr "Crear carpeta" #: zfuncs.cc:6474 msgid "hidden" msgstr "Ocultar" #: zfuncs.cc:6535 msgid "JPG quality 0-100" msgstr "Calidad de JPG 0-100" #: zfuncs.cc:6728 zfuncs.cc:6741 msgid "margins" msgstr "" #: zfuncs.cc:6737 msgid "top" msgstr "" #: zfuncs.cc:6738 msgid "bottom" msgstr "" #: zfuncs.cc:6739 msgid "left" msgstr "" #: zfuncs.cc:6740 msgid "right" msgstr "" #: zfuncs.cc:7202 msgid "" "Initial parameters file created. \n" "Inspect and revise if necessary." msgstr "" "Parámetros iniciales creados. \n" "Revíselos si lo desea." #: zfuncs.cc:7218 msgid "load parameters from a file" msgstr "Cargar parámetros desde archivo" #: zfuncs.cc:7287 msgid "save parameters to a file" msgstr "Guardar parámetros a un archivo" #: zfuncs.cc:7425 zfuncs.cc:7431 zfuncs.cc:7437 zfuncs.cc:7443 msgid "edit parameters" msgstr "Editar parámetros" #: zfuncs.cc:7426 zfuncs.cc:7432 msgid "" "list\n" "all" msgstr "" "Listar\n" "Todo" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "load\n" "file" msgstr "" "Cargar\n" "Archivo" #: zfuncs.cc:7426 zfuncs.cc:7432 zfuncs.cc:7438 zfuncs.cc:7444 msgid "" "save\n" "file" msgstr "" "Guardar\n" "Archivo" #: zfuncs.cc:7427 zfuncs.cc:7439 msgid "" "add\n" "new" msgstr "" "Añadir\n" "Nuevo" #: zfuncs.cc:7427 zfuncs.cc:7433 zfuncs.cc:7439 zfuncs.cc:7445 msgid "apply" msgstr "Aplicar" #: zfuncs.cc:7479 msgid "apply?" msgstr "¿Aplicar?" #: zfuncs.cc:7536 msgid "(new parm name)" msgstr "(Nuevo parámetro)" #: zfuncs.cc:7536 msgid "add parameter" msgstr "Añadir parámetro" #~ msgid "Brightness Graph" #~ msgstr "Gráfica de brillo" #~ msgid "radius" #~ msgstr "Radio" #~ msgid "Search results file error %s" #~ msgstr "Error en los resultados de la búsqueda %s" #~ msgid "Select area first" #~ msgstr "Debe seleccionar primero el área" #~ msgid "close thumbnail window" #~ msgstr "Cerrar Ãndice de miniaturas" #~ msgid "file" #~ msgstr "Archivo" #~ msgid "folder" #~ msgstr "carpeta" #~ msgid "jump to specific file" #~ msgstr "Cambia a un archivo específico" #~ msgid "open a directory" #~ msgstr "Abrir un directorio" #~ msgid "select new folder" #~ msgstr "Seleccionar nueva carpeta" #~ msgid "xdg-utils package not installed" #~ msgstr "El paquete «xdg-utils» no está instalado" #~ msgid "open a file" #~ msgstr "Abrir un fichero" #~ msgid "Time Interval" #~ msgstr "Intervalo de tiempo" #~ msgid "Clone fotoxx" #~ msgstr "Clonar Fotoxx" #~ msgid "Save As" #~ msgstr "Guardar como" #~ msgid "Create Launcher" #~ msgstr "Crear un lanzador" #~ msgid "horizontal unbend" #~ msgstr "Enderezamiento horizontal" #~ msgid "vertical unbend" #~ msgstr "Enderezamiento vertical" #~ msgid "target group area" #~ msgstr "Ãrea de grupo de destino" #~ msgid "Area" #~ msgstr "Ãrea" #~ msgid "HDF" #~ msgstr "HDF" #~ msgid "HDR" #~ msgstr "HDR" #~ msgid "/path*/file*" #~ msgstr "/ruta*/archivo*" #~ msgid "All EXIF data" #~ msgstr "Todos los datos EXIF" #~ msgid "Basic EXIF data" #~ msgstr "Datos EXIF básicos" #~ msgid "Resume" #~ msgstr "Reanudar" #~ msgid "Search Tags" #~ msgstr "Buscar etiquetas" #~ msgid "Set Tile and Gap Size" #~ msgstr "Configurar mosaico y tamaño de la separación" #~ msgid "Suspend" #~ msgstr "Suspender" #~ msgid "Tags" #~ msgstr "Etiquetas" #~ msgid "match all tags" #~ msgstr "Elegir todas las etiquetas" #~ msgid "match any tag" #~ msgstr "Elegir cualquier etiqueta" #~ msgid "" #~ " Pull on an image edge using the mouse. \n" #~ " Make multiple mouse pulls until satisfied. \n" #~ " When finished, press [done]." #~ msgstr "" #~ " Tirar de un borde de la imagen utilizando el ratón. \n" #~ " Hacer varios tirones con el ratón hasta que quede satisfecho. \n" #~ " Cuando haya terminado, pulse [Hecho]." #~ msgid "Warp Area" #~ msgstr "Deformación de área" #~ msgid "Warp Image in Selected Area" #~ msgstr "Deformar imagen en el área seleccionada" #~ msgid "color intensity" #~ msgstr "Intensidad de color" #~ msgid "Burn" #~ msgstr "Grabar" #~ msgid "Fix Image Perspective" #~ msgstr "Fijar imagen en perspectiva" #~ msgid "add tags" #~ msgstr "Etiquetas asignadas" #~ msgid "color range" #~ msgstr "Rango de color" #~ msgid "" #~ "\n" #~ " Match Brightness and Color" #~ msgstr "" #~ "\n" #~ " Ensamblar la luminosidad y el color" #~ msgid "Auto" #~ msgstr "Auto" #~ msgid "Auto-search lens mm and bow" #~ msgstr "Busqueda automática de lente mm y curva" #~ msgid "" #~ "Drag right image into rough alignment with left \n" #~ " to rotate, drag right edge up or down" #~ msgstr "" #~ "Arrastre la imagen derecha para alinearla con la de la izquierda \n" #~ " para rotarla, arrastre del borde hacia arriba o abajo" #~ msgid "Match Images" #~ msgstr "Ensamblar las imágenes" #~ msgid "Merge the images together" #~ msgstr "Mezclar las imágenes en conjunto" #~ msgid "Package ufraw required for this function" #~ msgstr "Se necesita la aplicación «ufraw» para esta función" #~ msgid "Retouch Image" #~ msgstr "Retoque de imagen" #~ msgid "Select image to combine" #~ msgstr "Seleccionar imagen a combinar" #~ msgid "" #~ "\n" #~ " brightness \n" #~ " level" #~ msgstr "" #~ "\n" #~ " Brillo \n" #~ " Nivel" #~ msgid "" #~ " left: no RGB spread (gray) \n" #~ " middle: normal (unmodified) \n" #~ " right: maximum RGB spread" #~ msgstr "" #~ "izquierda: sin rango RGB (gris) \n" #~ " centro: normal (sin modificar) \n" #~ " derecha: rango máximo RGB" #~ msgid "" #~ " left: no color (grey) \n" #~ " middle: normal (unmodified) \n" #~ " right: maximum color" #~ msgstr "" #~ "izquierda: sin color (gris) \n" #~ " centro: normal (sin modificar) \n" #~ " derecha: máximo color" #~ msgid " adjust red" #~ msgstr " Ajuste rojo" #~ msgid " blue" #~ msgstr " Azul" #~ msgid " green" #~ msgstr " Verde" #~ msgid "" #~ " Set color depth to 1-8 bits per color. \n" #~ " Press [apply] to update the image." #~ msgstr "" #~ " Establece la profundidad de color a 1-8 bits por color, \n" #~ " entonces presiona [Aplicar] para actualizar la imagen." #~ msgid " color balance blue " #~ msgstr " balance de color azul" #~ msgid " color balance green " #~ msgstr " balance de color verde" #~ msgid " color balance red " #~ msgstr " balance de color rojo" #~ msgid "2nd file is not compatible with 1st" #~ msgstr "Segundo archivo no compatible con el primero" #~ msgid "2nd image not same size as 1st image" #~ msgstr "La 2ª imagen no tiene el mismo tamaño que la 1ª" #~ msgid "Adjust Saturation (RGB spread)" #~ msgstr "Ajuste de saturación (rango RGB)" #~ msgid "Assigned tags file error: %s" #~ msgstr "Error al asignar etiquetas de archivo: %s" #~ msgid "Bend" #~ msgstr "Mezcla" #, fuzzy #~ msgid "Blend Area Edges" #~ msgstr "Radio de desenfoque" #~ msgid "Brightness/Contrast/Color" #~ msgstr "Brillo/Contraste/Color" #~ msgid "Brightness/Whiteness" #~ msgstr "Ajustar brillo / claridad" #~ msgid "Build Tags Index" #~ msgstr "Construir índice de etiquetas" #~ msgid "Clear Select Area" #~ msgstr "Limpiar área seleccionada" #~ msgid "Color Intensity" #~ msgstr "Intensidad de color" #~ msgid "Composite Images" #~ msgstr "Composición de imágenes" #~ msgid "Convert multiple RAWs" #~ msgstr "Convertir múltiples RAW" #~ msgid "" #~ "Convert raw file to 48-bit tiff format? \n" #~ " (this may take a while) " #~ msgstr "" #~ "¿Convertir archivos RAW a formato tiff de 48 bits?\n" #~ " (esto puede tardar un poco)" #~ msgid "Delete Area" #~ msgstr "Borrar área" #~ msgid "Delete selected area?" #~ msgstr "¿Borrar el área seleccionada?" #~ msgid "Dimensions" #~ msgstr "Dimensiones" #~ msgid "" #~ "Distance calculation needs a long time.\n" #~ " Do you want to continue?" #~ msgstr "" #~ "El cálculo de la distancia necesita bastante tiempo.\n" #~ " ¿Desea continuar?" #~ msgid "Distortion" #~ msgstr "Distorsión" #~ msgid "" #~ "Drag middle to move \n" #~ "Drag corners to resize" #~ msgstr "" #~ "Arrastre desde el interior para mover \n" #~ "Arrastre las esquinas para redimensionar" #~ msgid "Edge Calc" #~ msgstr "Calcular el borde" #~ msgid "Error Log" #~ msgstr "Registro de errores" #~ msgid "FREEIMAGE error: %s" #~ msgstr "Error en FREEIMAGE: %s" #~ msgid "FREEIMAGE unknown error" #~ msgstr "Error desconocido en FREEIMAGE " #, fuzzy #~ msgid "Flash" #~ msgstr "Papelera" #, fuzzy #~ msgid "FreeImage" #~ msgstr "Redimensionar imagen" #~ msgid "HDR Image Weights" #~ msgstr "Peso de la imagen HDR" #~ msgid "Hide Area" #~ msgstr "Ocultar área" #~ msgid "Image Weights per Brightness Level" #~ msgstr "Peso de la imagen por nivel de brillo" #~ msgid "Index" #~ msgstr "Ãndice" #~ msgid "Index (thumbnails)" #~ msgstr "Ãndice (miniaturas)" #~ msgid "Index Tags and Thumbs" #~ msgstr "Sincronizar etiquetas y miniaturas" #~ msgid "Input Images" #~ msgstr "Imágenes de entrada" #~ msgid "Invert Area" #~ msgstr "Invertir área" #~ msgid "" #~ "Left click/drag: add to selected area. \n" #~ "Right click: remove prior selection(s). \n" #~ "Color range: add more or less at once." #~ msgstr "" #~ "Hacer clic en el botón izquierdo y arrastrar: añadir al área " #~ "seleccionada. \n" #~ "Hacer clic en botón derecho: quitar la(s) selección(es) previa(s). \n" #~ "Gama de colores: añadir más o menos a la vez." #~ msgid "Make HDF Image" #~ msgstr "Hacer imagen HDF" #~ msgid "Make HDR Image" #~ msgstr "Hacer imagen HDR" #~ msgid "No assigned tags index file" #~ msgstr "Etiquetas sin asignar al archivo de índice" #, fuzzy #~ msgid "Outline Image Area for Following Edits" #~ msgstr "Ãrea de la imagen para ediciones siguientes" #~ msgid "Output Image" #~ msgstr "Imagen de salida" #~ msgid "Package exiftool is missing" #~ msgstr "No se encuentra el paquete «exiftool»" #~ msgid "Paint Pixels" #~ msgstr "Pintar píxeles" #~ msgid "Print" #~ msgstr "Imprimir" #~ msgid "RAW file template" #~ msgstr "Plantilla de archivo RAW" #~ msgid "README" #~ msgstr "LEAME" #~ msgid "RGB Spread" #~ msgstr "Rango RGB" #~ msgid "RGB spread" #~ msgstr "Rango RGB" #~ msgid "Rotate" #~ msgstr "Rotar" #~ msgid "Save Image as File" #~ msgstr "Guardar imagen como archivo" #~ msgid "Select Area -color" #~ msgstr "Seleccionar área -color" #~ msgid "Select Area -mouse" #~ msgstr "Seleccionar área -ratón" #~ msgid "" #~ "Select area is not finished.\n" #~ "Continue without using it?" #~ msgstr "" #~ "No se completó la selección de área.\n" #~ "¿Continuar sin usarla?" #~ msgid "Sharp" #~ msgstr "Enfoque" #~ msgid "Show Area" #~ msgstr "Mostrar área" #, fuzzy #~ msgid "Simulat Mosaic" #~ msgstr "Simular repujado" #, fuzzy #~ msgid "Simulate Mosaic" #~ msgstr "Simular repujado" #~ msgid "Simulate embossing" #~ msgstr "Simular un repujado" #~ msgid "Special Art Effects" #~ msgstr "Efectos artísticos especiales" #~ msgid "Thumbnail Index" #~ msgstr "Ãndice de miniaturas" #~ msgid "Too many points" #~ msgstr "Demasiados puntos" #~ msgid "Too many tags: %d" #~ msgstr "Demasiadas etiquetas: %d" #~ msgid "Too many undo buffers, please save image" #~ msgstr "Demasiados «deshacer» en el búfer, guarde la imagen" #~ msgid "Total tags exceed %d characters" #~ msgstr "El número total de etiquetas excedió en %d caracteres" #~ msgid "Tune Image" #~ msgstr "Afinar la imagen" #~ msgid "Unable to copy EXIF data" #~ msgstr "No se pueden copiar los datos EXIF" #, fuzzy #~ msgid "Unable to replace file" #~ msgstr "No se puede guardar la imagen" #~ msgid "Unable to save image" #~ msgstr "No se puede guardar la imagen" #~ msgid "Unable to save image: %s" #~ msgstr "No se puede guardar la imagen: %s" #~ msgid "Warp" #~ msgstr "Deformar" #~ msgid "Warp Global" #~ msgstr "Deformación de la imagen" #~ msgid "Zoom+" #~ msgstr "Zoom+" #~ msgid "Zoom-" #~ msgstr "Zoom-" #~ msgid "adjust brightness / whiteness" #~ msgstr "Ajustar brillo / claridad" #~ msgid "assigned tags" #~ msgstr "Etiquetas asignadas" #~ msgid "bigger image" #~ msgstr "Image más grande" #~ msgid "blend" #~ msgstr "Mezcla" #~ msgid "blur radius" #~ msgstr "Radio de desenfoque" #~ msgid "brightness distribution" #~ msgstr "Distribuir el brillo" #~ msgid "" #~ "cannot create %s \n" #~ " %s" #~ msgstr "" #~ "No se puede crear %s \n" #~ " %s" #~ msgid "click or drag trim margins" #~ msgstr "Haz clic o arrastra el borde" #~ msgid "color balance" #~ msgstr "Balance de color" #~ msgid "computing" #~ msgstr "computing" #~ msgid "date range (yyyymmdd)" #~ msgstr "Formato de fecha (aaaammdd)" #~ msgid "defog" #~ msgstr "Desempañar" #, fuzzy #~ msgid "edge calculation missing" #~ msgstr "Necesita calcular el borde" #~ msgid "exiftool is required to create tags" #~ msgstr "Se necesita «exiftool» para cear etiquetas" #~ msgid "exiftool is required to generate tags index" #~ msgstr "Se necesita «exiftool» para generar el índice de etiquetas" #~ msgid "exiv2 package is required" #~ msgstr "Se requiere el paquete «exiv2»" #~ msgid "" #~ "file cannot be read: \n" #~ " %s" #~ msgstr "" #~ "No se puede leer el archivo: \n" #~ " %s" #~ msgid "graph" #~ msgstr "Gráfica" #~ msgid "image format error: %s" #~ msgstr "Error en el formato de la imagen: %s" #~ msgid "image not 8 or 16 bits/color: %s" #~ msgstr "La imagen %s no tiene 8 o 16 bits/color" #~ msgid "input image 2" #~ msgstr "Elegir imagen 2" #~ msgid "kill" #~ msgstr "Cerrar" #~ msgid "kill running function" #~ msgstr "Cerrar función en marcha" #~ msgid "open RAW file" #~ msgstr "Abrir archivo RAW" #~ msgid "open image file" #~ msgstr "Abrir archivo" #~ msgid "open new image file" #~ msgstr "Abrir nuevo archivo" #~ msgid "photo date (yyyymmdd)" #~ msgstr "Fecha de la foto (aaaammdd)" #~ msgid "photo stars" #~ msgstr "Estrellas" #~ msgid "prior function still running" #~ msgstr "Función anterior todavía en marcha" #~ msgid "quit" #~ msgstr "Salir" #, fuzzy #~ msgid "radius limit" #~ msgstr "Radio" #~ msgid "recently added" #~ msgstr "Recientemente añadido" #~ msgid "red" #~ msgstr "Rojo" #~ msgid "redo image changes" #~ msgstr "Rehacer cambios en imagen" #~ msgid "resize image" #~ msgstr "Redimensionar imagen" #~ msgid "rotate image" #~ msgstr "Rotar imagen" #~ msgid "set RGB spread" #~ msgstr "Establece el rango RGB" #, fuzzy #~ msgid "set blend radius" #~ msgstr "Establecer radio de desenfoque" #~ msgid "set color intensity" #~ msgstr "Establecer intensidad de color" #~ msgid "sharpen image" #~ msgstr "Enfoque de imagen" #, fuzzy #~ msgid "this area cannot be processed" #~ msgstr "" #~ "No se puede conservar la selección de área.\n" #~ "¿Continuar?" #~ msgid "toolbar::save" #~ msgstr "Guardar" #~ msgid "trim image" #~ msgstr "Recortar imagen" #~ msgid "unbend panorama image" #~ msgstr "Enderezar imagen panorámica" #~ msgid "undo image changes" #~ msgstr "Deshacer cambios en la imagen" #~ msgid "unknown image format" #~ msgstr "Formato de imagen desconocido" #~ msgid "whiteness" #~ msgstr "Aclarar" #~ msgid "Discard modifications?" #~ msgstr "¿Descartar modificaciones?" #~ msgid "" #~ "Rename failed \n" #~ " %s" #~ msgstr "" #~ "Falló el renombrado \n" #~ " %s" #~ msgid "Translate" #~ msgstr "Traducciones" #~ msgid "select new file" #~ msgstr "Seleccionar archivo nuevo" #~ msgid "lens name" #~ msgstr "Nombre de la lente" #~ msgid "Lens Parameters" #~ msgstr "Parámetros de óptica" fotoxx-12.01.2/f.info.cc0000644000175000017500000036244611701011017013336 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image editor - image metadata functions, EXIF/IPTC etc. ***************************************************************************/ int get_mouse_tag(GtkTextView *, int px, int py, cchar *); // get tag selected by mouse int add_tag(char *tag, char *taglist, int maxcc); // add tag if unique and enough space int del_tag(char *tag, char *taglist); // remove tag from tag list int add_recentag(char *tag); // add tag to recent tags, keep most recent void load_deftags(); // tags_defined file >> tags_deftags[] void save_deftags(); // tags_deftags[] >> defined_tags file int find_deftag(char *tag); // find tag in tags_deftags[] int add_deftag(char *catg, char *tag); // add tag to tags_deftags[] int del_deftag(char *tag); // remove tag from tags_deftags[] void deftags_stuff(zdialog *zd); // tags_deftags[] >> dialog widget "deftags" char tags_date[12] = ""; // image date, yyyymmdd char tags_prdate[12] = ""; // previous image date read or set char tags_stars = '0'; // image rating in stars, '0' to '5' char tags_cliktag[tagcc] = ""; // tag clicked by mouse char tags_clikcatg[tagcc] = ""; // category clicked by mouse char *tags_deftags[maxtagcats]; // defined tags: catg: tag1, tag2, ... tagN, char tags_deftext[tagTcc] = ""; // defined tags as flat text buffer char tags_filetags[tagFcc] = ""; // tags for current image file char tags_recentags[tagRcc] = ""; // recently added tags list char tags_batchAddTags[tagMcc] = ""; // batch add tags list char tags_searchtags[tagScc] = ""; // search tags list char tags_searchtext[tagScc] = ""; // search comments & captions word list char tags_searchfiles[tagScc] = ""; // search files list char tags_comments[tagFcc]; // image comments char tags_caption[tagFcc]; // image caption /**************************************************************************/ // View and edit IPTC Caption and EXIF UserComment data void m_edit_cctext(GtkWidget *, cchar *menu) // 2 functions combined v.11.09 { int edit_cctext_dialog_event(zdialog *zd, cchar *event); char text[tagFcc]; cchar *title = ZTX("Edit Caption and Comments"); if (menu) zfuncs::F1_help_topic = "edit_cctext"; if (! curr_file) return; if (! Fexiftool) { // exiftool is required zmessageACK(mWin,Bexiftoolmissing); return; } if (! zdeditcctext) // popup dialog if not already { zdeditcctext = zdialog_new(title,mWin,Bapply,Bcancel,null); zdialog *zd = zdeditcctext; zdialog_add_widget(zd,"hbox","hbcap","dialog"); zdialog_add_widget(zd,"label","labcap","hbcap","Caption","space=5"); zdialog_add_widget(zd,"frame","framecap","hbcap",0,"expand"); zdialog_add_widget(zd,"edit","textcap","framecap",0,"space=5|wrap"); zdialog_add_widget(zd,"hbox","hbcom","dialog"); zdialog_add_widget(zd,"label","labcom","hbcom","Comments","space=5"); zdialog_add_widget(zd,"frame","framecom","hbcom",0,"expand"); zdialog_add_widget(zd,"edit","textcom","framecom",0,"space=5|wrap"); zdialog_resize(zd,300,0); zdialog_help(zd,"edit_cctext"); // zdialog help topic v.11.08 zdialog_run(zd,edit_cctext_dialog_event); } load_fileinfo(curr_file); // get current caption and comments repl_1str(tags_caption,text,"\\n","\n"); // replace "\n" with real newlines zdialog_stuff(zdeditcctext,"textcap",text); // stuff into dialog repl_1str(tags_comments,text,"\\n","\n"); // replace "\n" with real newlines zdialog_stuff(zdeditcctext,"textcom",text); // stuff into dialog return; } // dialog event and completion callback function int edit_cctext_dialog_event(zdialog *zd, cchar *event) { char text[tagFcc]; if (! zd->zstat) return 0; else if (zd->zstat == 1) // apply, save text { zd->zstat = 0; // keep dialog active if (is_syncbusy()) return 0; // must wait for file sync v.11.11 zdialog_fetch(zd,"textcap",text,tagFcc); // get new cctext repl_1str(text,tags_caption,"\n","\\n"); // replace newlines with "\n" zdialog_fetch(zd,"textcom",text,tagFcc); // get new cctext repl_1str(text,tags_comments,"\n","\\n"); // replace newlines with "\n" Ftagschanged = 1; save_fileinfo(curr_file); // save in image file } else zdialog_free(zdeditcctext); // cancel return 1; } /**************************************************************************/ // edit tags menu function void m_edit_tags(GtkWidget *, cchar *menu) { void edittags_fixwidget(zdialog *, cchar * widgetname); // fix tags widget for selecting with mouse int edittags_dialog_event(zdialog *zd, cchar *event); char *ppv, starsN[12]; if (menu) zfuncs::F1_help_topic = "edit_tags"; if (! Fexiftool) { // exiftool is required zmessageACK(mWin,Bexiftoolmissing); return; } if (! curr_file) return; if (! zdedittags) // (re) start tag edit dialog { zdedittags = zdialog_new(ZTX("Edit Tags"),mWin,Bapply,Bcancel,null); zdialog_add_widget(zdedittags,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zdedittags,"label","labfile","hb1",ZTX("file:"),"space=5"); zdialog_add_widget(zdedittags,"label","file","hb1"); zdialog_add_widget(zdedittags,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zdedittags,"label","lab21","hb2",ZTX("image date (yyyymmdd)"),"space=5"); zdialog_add_widget(zdedittags,"entry","date","hb2",0,"scc=12"); zdialog_add_widget(zdedittags,"button","prdate","hb2",ZTX("use last"),"space=5"); zdialog_add_widget(zdedittags,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zdedittags,"label","labstars","hb3",ZTX("image stars"),"space=5"); zdialog_add_widget(zdedittags,"vbox","vb3","hb3"); zdialog_add_widget(zdedittags,"hbox","hb31","vb3",0,"homog"); zdialog_add_widget(zdedittags,"hbox","hb32","vb3",0,"homog"); zdialog_add_widget(zdedittags,"label","lab30","hb31","0"); zdialog_add_widget(zdedittags,"label","lab31","hb31","1"); zdialog_add_widget(zdedittags,"label","lab32","hb31","2"); zdialog_add_widget(zdedittags,"label","lab33","hb31","3"); zdialog_add_widget(zdedittags,"label","lab34","hb31","4"); zdialog_add_widget(zdedittags,"label","lab35","hb31","5"); zdialog_add_widget(zdedittags,"radio","stars0","hb32",0); zdialog_add_widget(zdedittags,"radio","stars1","hb32",0); zdialog_add_widget(zdedittags,"radio","stars2","hb32",0); zdialog_add_widget(zdedittags,"radio","stars3","hb32",0); zdialog_add_widget(zdedittags,"radio","stars4","hb32",0); zdialog_add_widget(zdedittags,"radio","stars5","hb32",0); zdialog_add_widget(zdedittags,"hbox","hb4","dialog",0,"space=5"); zdialog_add_widget(zdedittags,"label","lab4","hb4",ZTX("current tags"),"space=5"); zdialog_add_widget(zdedittags,"frame","frame4","hb4",0,"expand"); zdialog_add_widget(zdedittags,"edit","filetags","frame4",0,"expand|wrap"); // v.11.06 zdialog_add_widget(zdedittags,"hbox","hb5","dialog",0,"space=5"); zdialog_add_widget(zdedittags,"label","recent","hb5",ZTX("recent tags"),"space=5"); zdialog_add_widget(zdedittags,"frame","frame5","hb5",0,"expand"); zdialog_add_widget(zdedittags,"edit","recentags","frame5",0,"expand|wrap"); // v.11.06 zdialog_add_widget(zdedittags,"hbox","hb8","dialog"); zdialog_add_widget(zdedittags,"label","labdeftags","hb8",ZTX("defined tags"),"space=5"); zdialog_add_widget(zdedittags,"hbox","hb9","dialog",0,"expand"); zdialog_add_widget(zdedittags,"frame","frame8","hb9",0,"space=5|expand"); zdialog_add_widget(zdedittags,"scrwin","scrwin8","frame8",0,"expand"); zdialog_add_widget(zdedittags,"edit","deftags","scrwin8",0,"expand|wrap"); // v.11.06 zdialog_resize(zdedittags,500,500); // run dialog zdialog_help(zdedittags,"edit_tags"); // zdialog help topic v.11.08 zdialog_run(zdedittags,edittags_dialog_event); edittags_fixwidget(zdedittags,"filetags"); // setup for mouse tag selection edittags_fixwidget(zdedittags,"recentags"); edittags_fixwidget(zdedittags,"deftags"); load_deftags(); // stuff defined tags into dialog deftags_stuff(zdedittags); } load_fileinfo(curr_file); // get EXIF/IPTC data ppv = (char *) strrchr(curr_file,'/'); zdialog_stuff(zdedittags,"file",ppv+1); // stuff dialog file name zdialog_stuff(zdedittags,"date",tags_date); // stuff dialog data sprintf(starsN,"stars%c",tags_stars); zdialog_stuff(zdedittags,starsN,1); zdialog_stuff(zdedittags,"filetags",tags_filetags); zdialog_stuff(zdedittags,"recentags",tags_recentags); return; } // setup tag display widget for tag selection using mouse clicks void edittags_fixwidget(zdialog *zd, cchar * widgetname) { void edittags_mouse(GtkTextView *, GdkEventButton *, cchar *); // select tag via mouse click GtkWidget *widget; GdkWindow *gdkwin; widget = zdialog_widget(zd,widgetname); // make widget wrap text gtk_text_view_set_editable(GTK_TEXT_VIEW(widget),0); // disable widget editing gdkwin = gtk_text_view_get_window(GTK_TEXT_VIEW(widget),TEXTWIN); // cursor for tag selection gdk_window_set_cursor(gdkwin,arrowcursor); gtk_widget_add_events(widget,GDK_BUTTON_PRESS_MASK); // connect mouse-click event G_SIGNAL(widget,"button-press-event",edittags_mouse,widgetname); } // edit tags mouse-click event function // get clicked tag and add to or remove from file tags and recent tags void edittags_mouse(GtkTextView *widget, GdkEventButton *event, cchar *widgetname) { int mpx, mpy; if (event->type != GDK_BUTTON_PRESS) return; mpx = int(event->x); // mouse click position mpy = int(event->y); get_mouse_tag(widget,mpx,mpy,widgetname); // tags_cliktag = clicked tag in list if (! *tags_cliktag) return; if (strEqu(widgetname,"filetags")) { // remove tag from file tags del_tag(tags_cliktag,tags_filetags); zdialog_stuff(zdedittags,"filetags",tags_filetags); // update dialog widgets } if (strEqu(widgetname,"recentags")) { // add recent tag to file tags add_tag(tags_cliktag,tags_filetags,tagFcc); zdialog_stuff(zdedittags,"filetags",tags_filetags); } if (strEqu(widgetname,"deftags")) { // add defined tag to file tags add_tag(tags_cliktag,tags_filetags,tagFcc); zdialog_stuff(zdedittags,"filetags",tags_filetags); add_recentag(tags_cliktag); // and to recent tags zdialog_stuff(zdedittags,"recentags",tags_recentags); } *tags_cliktag = 0; return; } // dialog event and completion callback function int edittags_dialog_event(zdialog *zd, cchar *event) { int err; if (zd->zstat) { if (zd->zstat == 1) { // [apply] zd->zstat = 0; // keep dialog active if (is_syncbusy()) return 0; // must wait for file sync v.11.11 save_fileinfo(curr_file); // save tag changes return 0; } zdialog_free(zdedittags); // cancel - kill dialog return 0; } if (strEqu(event,"date")) { // image date revised err = zdialog_fetch(zd,"date",tags_date,11); if (err) return 1; if (strlen(tags_date) == 4) strcat(tags_date,"0101"); // yyyy >> yyyy0101 if (strlen(tags_date) == 6) strcat(tags_date,"01"); // yyyymm >> yyyymm01 Ftagschanged++; } if (strEqu(event,"prdate")) { // repeat last date used if (*tags_prdate) { zdialog_stuff(zd,"date",tags_prdate); strcpy(tags_date,tags_prdate); Ftagschanged++; } } if (strnEqu(event,"stars",5)) { // event = stars0 to stars5 tags_stars = event[5]; // '0' to '5' Ftagschanged++; } if (strEqu(event,"tags-changed")) // get new defined tags data deftags_stuff(zdedittags); // v.11.02 return 0; } /**************************************************************************/ // manage tags menu function zdialog *zdmanagetags = 0; void m_manage_tags(GtkWidget *, cchar *) // v.11.02 - separate edit and manage tags { void managetags_fixwidget(zdialog *, cchar * widgetname); // fix tags widget for selecting with mouse int managetags_dialog_event(zdialog *zd, cchar *event); zfuncs::F1_help_topic = "manage_tags"; if (zdmanagetags) return; zdmanagetags = zdialog_new(ZTX("Manage Tags"),mWin,Bcancel,null); zdialog_add_widget(zdmanagetags,"hbox","hb7","dialog",0,"space=5"); zdialog_add_widget(zdmanagetags,"label","labcatg","hb7",ZTX("category"),"space=5"); zdialog_add_widget(zdmanagetags,"entry","catg","hb7",0,"scc=12"); zdialog_add_widget(zdmanagetags,"label","space","hb7",0,"space=5"); zdialog_add_widget(zdmanagetags,"label","labtag","hb7",ZTX("tag"),"space=5"); zdialog_add_widget(zdmanagetags,"entry","tag","hb7",0,"scc=20|expand"); zdialog_add_widget(zdmanagetags,"label","space","hb7",0,"space=5"); zdialog_add_widget(zdmanagetags,"button","create","hb7",ZTX("create")); zdialog_add_widget(zdmanagetags,"button","delete","hb7",ZTX("delete")); zdialog_add_widget(zdmanagetags,"hbox","hb8","dialog"); zdialog_add_widget(zdmanagetags,"label","labdeftags","hb8",ZTX("defined tags"),"space=5"); zdialog_add_widget(zdmanagetags,"hbox","hb9","dialog",0,"expand"); zdialog_add_widget(zdmanagetags,"frame","frame8","hb9",0,"space=5|expand"); zdialog_add_widget(zdmanagetags,"scrwin","scrwin8","frame8",0,"expand"); zdialog_add_widget(zdmanagetags,"edit","deftags","scrwin8",0,"expand|wrap"); // v.11.06 zdialog_resize(zdmanagetags,0,400); // run dialog zdialog_help(zdmanagetags,"manage_tags"); // zdialog help topic v.11.08 zdialog_run(zdmanagetags,managetags_dialog_event); managetags_fixwidget(zdmanagetags,"deftags"); // setup for mouse tag selection load_deftags(); // stuff defined tags into dialog deftags_stuff(zdmanagetags); return; } // setup tag display widget for tag selection using mouse clicks void managetags_fixwidget(zdialog *zd, cchar * widgetname) { void managetags_mouse(GtkTextView *, GdkEventButton *, cchar *); // select tag via mouse click GtkWidget *widget; GdkWindow *gdkwin; widget = zdialog_widget(zd,widgetname); // make widget wrap text gtk_text_view_set_editable(GTK_TEXT_VIEW(widget),0); // disable widget editing gdkwin = gtk_text_view_get_window(GTK_TEXT_VIEW(widget),TEXTWIN); // cursor for tag selection gdk_window_set_cursor(gdkwin,arrowcursor); gtk_widget_add_events(widget,GDK_BUTTON_PRESS_MASK); // connect mouse-click event G_SIGNAL(widget,"button-press-event",managetags_mouse,widgetname); } // manage tags mouse-click event function // get clicked tag category or tag name void managetags_mouse(GtkTextView *widget, GdkEventButton *event, cchar *widgetname) { int mpx, mpy, cc; if (event->type != GDK_BUTTON_PRESS) return; mpx = int(event->x); // mouse click position mpy = int(event->y); cc = get_mouse_tag(widget,mpx,mpy,widgetname); // tags_cliktag = clicked tag in list if (! cc) { if (*tags_clikcatg) // selected category >> dialog widget zdialog_stuff(zdmanagetags,"catg",tags_clikcatg); return; } zdialog_stuff(zdmanagetags,"tag",tags_cliktag); // selected tag >> dialog widget return; } // dialog event and completion callback function int managetags_dialog_event(zdialog *zd, cchar *event) { char tag[tagcc], catg[tagcc]; int changed = 0; if (zd->zstat) { zdialog_free(zdmanagetags); return 0; } if (strEqu(event,"create")) { // add new tag to defined tags zdialog_fetch(zd,"catg",catg,tagcc); zdialog_fetch(zd,"tag",tag,tagcc); add_deftag(catg,tag); changed++; } if (strEqu(event,"delete")) { // remove tag from defined tags zdialog_fetch(zd,"tag",tag,tagcc); del_deftag(tag); changed++; } if (changed) { save_deftags(); // save tag updates to file deftags_stuff(zdmanagetags); // update dialog "deftags" window if (zdedittags) // and edit tags window if active zdialog_send_event(zdedittags,"tags-changed"); } return 0; } /**************************************************************************/ // Convert mouse click position in a tag list into the selected tag. // cc of selected tag is returned, or zero if no tag clicked. // Selected tag is returned in tags_cliktag, or null if no tag clicked. // If a category is clicked, it is returned in tags_clikcatg and zero is returned. int get_mouse_tag(GtkTextView *widget, int mpx, int mpy, cchar *widgetname) { GtkTextIter iter; int tbx, tby, offset, cc; char *ptext, *pp1, *pp2; *tags_cliktag = *tags_clikcatg = 0; // start with no tag or category v.11.05 gtk_text_view_window_to_buffer_coords(widget,GTK_TEXT_WINDOW_TEXT,mpx,mpy,&tbx,&tby); gtk_text_view_get_iter_at_location(widget,&iter,tbx,tby); offset = gtk_text_iter_get_offset(&iter); // graphic position in widget text ptext = 0; if (strEqu(widgetname,"filetags")) ptext = tags_filetags; // get corresponding text if (strEqu(widgetname,"recentags")) ptext = tags_recentags; if (strEqu(widgetname,"batchAddTags")) ptext = tags_batchAddTags; if (strEqu(widgetname,"searchtags")) ptext = tags_searchtags; if (strEqu(widgetname,"deftags")) ptext = tags_deftext; if (! ptext) return 0; pp1 = ptext + utf8_position(ptext,offset); // graphic position to byte position if (! *pp1 || strchr(tagdelims":\n",*pp1)) return 0; // reject edge position or delimiter while (pp1 > ptext && ! strchr(tagdelims":\n",pp1[-1])) pp1--; // find start of tag pp2 = pp1; while (pp2[1] && ! strchr(tagdelims":\n",pp2[1])) pp2++; // find following delimiter including ":" while (*pp1 == ' ') pp1++; // no leading or trailing blanks while (*pp2 == ' ') pp2--; cc = pp2 - pp1 + 1; if (cc <= 1) return 0; // reject tag < 2 chars. if (cc >= tagcc) return 0; // reject tag too big if (pp2[1] == ':') { strncpy0(tags_clikcatg,pp1,cc+1); // tags_clikcatg = selected category return 0; // return 0 } strncpy0(tags_cliktag,pp1,cc+1); // tags_cliktag = selected tag return cc; // return cc } /**************************************************************************/ // add input tag to output tag list if not already there and enough room // returns: 0 = added OK 1 = not unique (case ignored) // 2 = overflow 3 = bad utf8 characters 4 = null tag int add_tag(char *tag, char *taglist, int maxcc) { char *pp1, *pp2, tag1[tagcc], tag2[tagcc]; int cc, cc1, cc2; strncpy0(tag1,tag,tagcc); // remove leading and trailing blanks cc = strTrim2(tag2,tag1); if (! cc) return 4; if (utf8_check(tag2)) { // check for valid utf8 encoding printf("bad utf8 characters: %s \n",tag2); return 3; } while ((pp1 = strpbrk(tag2,tagdelims":"))) *pp1 = '-'; // replace problem characters strcpy(tag,tag2); // replace tag with sanitized version pp1 = taglist; cc1 = strlen(tag); while (true) // check if already in tag list { while (*pp1 == ' ' || *pp1 == tagdelim1) pp1++; if (! *pp1) break; pp2 = pp1 + 1; while (*pp2 && *pp2 != tagdelim1) pp2++; cc2 = pp2 - pp1; if (cc2 == cc1 && strncaseEqu(tag,pp1,cc1)) return 1; pp1 = pp2; } cc2 = strlen(taglist); // append to tag list if space enough if (cc1 + cc2 + 3 > maxcc) return 2; strcpy(taglist + cc2,tag); strcpy(taglist + cc2 + cc1, tagdelim2); // add delimiter + space if (taglist == tags_filetags) // image tags were changed Ftagschanged++; return 0; } // remove tag from taglist, if present // returns: 0 if found and deleted, otherwise 1 int del_tag(char *tag, char *taglist) { int ii, ftcc, atcc, found; char *temptags; cchar *pp; temptags = strdupz(taglist,0,"del_tag"); *taglist = 0; ftcc = found = 0; for (ii = 1; ; ii++) { pp = strField(temptags,tagdelims,ii); // next tag if (! pp) { zfree(temptags); if (found && taglist == tags_filetags) // image tags were changed Ftagschanged++; return 1-found; } if (*pp == ' ') continue; if (strcaseEqu(pp,tag)) { // skip matching tag found = 1; continue; } atcc = strlen(pp); // copy non-matching tag strcpy(taglist + ftcc, pp); ftcc += atcc; strcpy(taglist + ftcc, tagdelim2); // + delim + blank ftcc += 2; } } // add new tag to recent tags, if not already. // remove oldest to make space if needed. int add_recentag(char *tag) { int err; char *pp, temptags[tagRcc]; err = add_tag(tag,tags_recentags,tagRcc); // add tag to recent tags while (err == 2) // overflow { strncpy0(temptags,tags_recentags,tagRcc); // remove oldest to make room pp = strpbrk(temptags,tagdelims); if (! pp) return 0; strcpy(tags_recentags,pp+2); // delimiter + blank before tag err = add_tag(tag,tags_recentags,tagRcc); } return 0; } /**************************************************************************/ // Load tags_defined file into tags_deftags[ii] => category: tag1, tag2, ... // Read search_index file and add unmatched tags: => nocatg: tag1, tag2, ... void load_deftags() { int tags_Ucomp(cchar *tag1, cchar *tag2); static int Floaded = 0; FILE *fid; int ii, jj, ntags, err, cc, tcc; int ncats, catoverflow; int nocat, nocatcc; char tag[tagcc], catg[tagcc]; char tagsbuff[tagGcc]; char *pp1, *pp2; char ptags[tagntc][tagcc]; if (Floaded) return; // use memory tags if already there v.11.02 Floaded++; for (ii = 0; ii < maxtagcats; ii++) // clean memory tags_deftags[ii] = 0; ncats = catoverflow = 0; fid = fopen(tags_defined_file,"r"); // read tags_defined file if (fid) { while (true) { pp1 = fgets_trim(tagsbuff,tagGcc,fid); if (! pp1) break; if (ncats == maxtagcats-1) goto toomanycats; pp2 = strchr(pp1,':'); // isolate "category:" if (! pp2) continue; // reject bad data cc = pp2 - pp1 + 1; if (cc > tagcc-1) continue; strncpy0(catg,pp1,cc); // (for error message) if (strlen(pp1) > tagGcc-2) goto cattoobig; pp2++; while (*pp2 == ' ') pp2++; if (strlen(pp2) < 3) continue; while ((pp2 = strpbrk(pp2,tagdelims))) *pp2++ = tagdelim1; // force comma delimiter v.11.02 tags_deftags[ncats] = strdupz(pp1,0,"def_tags"); // tags_deftags[ii] ncats++; // = category: tag1, tag2, ... tagN, } err = fclose(fid); if (err) goto deftagserr; } nocat = ncats; // make last category "nocatg" for ncats++; // unmatched tags in search_index file tags_deftags[nocat] = zmalloc(tagGcc,"deftags"); strcpy(tags_deftags[nocat],"nocatg: "); nocatcc = 8; fid = fopen(search_index_file,"r"); // read search_index file if (! fid) return; while (true) { pp1 = fgets_trim(tagsbuff,tagGcc,fid); // next image file tags record if (! pp1) break; if (strnNeq(tagsbuff,"tags: ",6)) continue; pp1 = pp1 + 6; while (true) { while (*pp1 && strchr(tagdelims" ",*pp1)) pp1++; // next image tag start if (! *pp1) break; pp2 = strpbrk(pp1,tagdelims); // end if (! pp2) pp2 = pp1 + strlen(pp1); cc = pp2 - pp1; if (cc > tagcc-1) { pp1 = pp2; // bugfix v.10.9 continue; // ignore huge tag } strncpy0(tag,pp1,cc+1); // look for tag in defined tags err = find_deftag(tag); if (! err) { // found pp1 = pp2; continue; } if (nocatcc + cc + 2 > tagGcc-2) { catoverflow = 1; // nocatg: length limit reached break; } else { strcpy(tags_deftags[nocat] + nocatcc, tag); // append tag to list nocatcc += cc; strcpy(tags_deftags[nocat] + nocatcc, tagdelim2); // + delim + blank nocatcc += 2; } pp1 = pp2; } } err = fclose(fid); if (err) goto filetagserr; if (catoverflow) goto cattoobig; // parse all the tags in each category and sort in ascending order for (ii = 0; ii < ncats; ii++) { pp1 = tags_deftags[ii]; pp2 = strchr(pp1,':'); cc = pp2 - pp1 + 1; strncpy0(catg,pp1,cc); pp1 = pp2 + 1; while (*pp1 == ' ') pp1++; tcc = 0; for (jj = 0; jj < tagntc; jj++) { if (! *pp1) break; pp2 = strchr(pp1,tagdelim1); if (pp2) cc = pp2 - pp1; else cc = strlen(pp1); if (cc > tagcc-1) cc = tagcc-1; strncpy0(ptags[jj],pp1,cc+1); pp1 += cc + 1; tcc += cc; while (*pp1 == ' ') pp1++; } ntags = jj; if (ntags == tagntc) goto cattoobig; HeapSort((char *) ptags,tagcc,ntags,tags_Ucomp); pp1 = tags_deftags[ii]; tcc += strlen(catg) + 2 + 2 * ntags + 2; // category, all tags, delimiters pp2 = zmalloc(tcc,"deftags"); tags_deftags[ii] = pp2; // swap memory zfree(pp1); strcpy(pp2,catg); pp2 += strlen(catg); strcpy(pp2,": "); // pp2 = "category: " pp2 += 2; for (jj = 0; jj < ntags; jj++) // add the sorted tags { strcpy(pp2,ptags[jj]); // append tag + delim + blank pp2 += strlen(pp2); strcpy(pp2,tagdelim2); pp2 += 2; } *pp2 = 0; } // sort the categories in ascending order // leave "nocatg" at the end for (ii = 0; ii < ncats-1; ii++) for (jj = ii+1; jj < ncats-1; jj++) // v.11.02 { pp1 = tags_deftags[ii]; pp2 = tags_deftags[jj]; if (strcasecmp(pp1,pp2) > 0) { tags_deftags[ii] = pp2; tags_deftags[jj] = pp1; } } return; toomanycats: zmessLogACK(mWin,"more than %d categories",maxtagcats); fclose(fid); return; cattoobig: zmessLogACK(mWin,"category %s is too big",catg); fclose(fid); return; deftagserr: zmessLogACK(mWin,"tags_defined file error: %s",strerror(errno)); return; filetagserr: zmessLogACK(mWin,"search_index file error: %s",strerror(errno)); return; } // compare function for tag sorting // wcscasecmp does not work for plain ascii // so what happens to Chinese, etc? int tags_Ucomp(cchar *tag1, cchar *tag2) { return strcasecmp(tag1,tag2); } // write tags_deftags[] memory data to the defined tags file if any changes were made void save_deftags() { int ii, err; FILE *fid; fid = fopen(tags_defined_file,"w"); // write tags_defined file if (! fid) goto deftagserr; for (ii = 0; ii < maxtagcats; ii++) { if (! tags_deftags[ii+1]) break; // omit last category, "nocatg" err = fprintf(fid,"%s\n",tags_deftags[ii]); // each record: if (err < 0) goto deftagserr; // category: tag1, tag2, ... tagN, } err = fclose(fid); if (err) goto deftagserr; return; deftagserr: zmessLogACK(mWin,"tags_defined file error: %s",strerror(errno)); return; } // find a given tag in tags_deftags[] // return: 0 = found, 1 = not found int find_deftag(char *tag) { int ii, cc; char tag2[tagcc+4]; char *pp; if (! tag || *tag <= ' ') return 0; // bad tag strncpy0(tag2,tag,tagcc); // construct tag + delim + blank cc = strlen(tag2); strcpy(tag2+cc,tagdelim2); cc += 2; for (ii = 0; ii < maxtagcats; ii++) { pp = tags_deftags[ii]; // category: tag1, tag2, ... tagN, if (! pp) return 1; // not found while (pp) { pp = strcasestr(pp,tag2); // look for delim + blank + tag + delim if (! pp) break; if (strchr(tagdelims":", pp[-2])) return 0; pp += cc; } } return 1; } // add new tag to tags_deftags[] >> category: tag1, tag2, ... newtag, // returns: 0 = added OK 1 = not unique (case ignored) // 2 = overflow 3 = bad utf8 characters 4 = null tag // if tag present under another category, it is moved to new category int add_deftag(char *catg, char *tag) { int ii, cc, cc1, cc2; char tag1[tagcc], tag2[tagcc]; char *pp1, *pp2; strncpy0(tag1,tag,tagcc); // remove leading and trailing blanks cc = strTrim2(tag2,tag1); if (! cc) return 4; if (utf8_check(tag2)) { // check for valid utf8 encoding printf("bad utf8 characters: %s \n",tag2); return 3; } while ((pp1 = strpbrk(tag2,tagdelims":"))) *pp1 = '-'; // replace problem characters strcpy(tag,tag2); // replace tag with sanitized version del_deftag(tag); // delete if already there if (! catg || *catg <= ' ') catg = (char *) "nocatg"; cc1 = strlen(catg); for (ii = 0; ii < maxtagcats; ii++) // look for given category { pp1 = tags_deftags[ii]; if (! pp1) goto newcatg; if (! strnEqu(catg,pp1,cc1)) continue; if (pp1[cc1] == ':') goto oldcatg; } newcatg: if (ii == maxtagcats) goto toomanycats; cc1 = strlen(catg) + strlen(tag) + 6; pp1 = zmalloc(cc1,"deftags"); *pp1 = 0; strncatv(pp1,cc1,catg,": ",tag,tagdelim2,null); // category: + tag + delim + blank tags_deftags[ii] = tags_deftags[ii-1]; // move "nocatg" record to next slot tags_deftags[ii-1] = pp1; // insert new record before return 0; oldcatg: cc1 = strlen(tag); pp2 = pp1 + 2; while (true) { pp2 = strcasestr(pp2,tag); // look for delim + blank + tag + delim if (! pp2) break; // or colon + blank + tag + delim if (strchr(tagdelims,pp2[cc]) && strchr(tagdelims":", pp2[-2])) return 1; // tag not unique pp2 += cc1; } cc2 = strlen(pp1); // add new tag to old record if (cc1 + cc2 + 4 > tagGcc) goto cattoobig; pp2 = strdupz(pp1,cc2+4,"def_tags"); // expand string zfree(pp1); tags_deftags[ii] = pp2; strcpy(pp2+cc2,tag); // old record + tag + delim + blank strcpy(pp2+cc2+cc1,tagdelim2); return 0; toomanycats: zmessLogACK(mWin,"more than %d categories",maxtagcats); return 2; cattoobig: zmessLogACK(mWin,"category is too big"); return 2; } // delete tag from defined tags list, tags_deftags[] // return: 0 = found and deleted, 1 = not found int del_deftag(char *tag) { int ii, cc; char tag2[tagcc+4]; char *pp, *pp1, *pp2; if (! tag || *tag <= ' ') return 1; // bad tag strncpy0(tag2,tag,tagcc); // construct tag + delim + blank cc = strlen(tag2); strcpy(tag2+cc,tagdelim2); cc += 2; for (ii = 0; ii < maxtagcats; ii++) { pp = tags_deftags[ii]; if (! pp) return 1; // not found while (pp) { pp = strcasestr(pp,tag2); // look for prior delim or colon if (! pp) break; if (strchr(tagdelims":", pp[-2])) goto found; pp += cc; } } found: for (pp1 = pp, pp2 = pp+cc; *pp2; pp1++, pp2++) // eliminate tag, delim, blank *pp1 = *pp2; *pp1 = 0; return 0; } // stuff tags_deftags[] into given text widget and format by category // create tags_deftext with flat list of tags for mouse clicking void deftags_stuff(zdialog *zd) { GtkWidget *widget; GtkTextBuffer *textbuff; GtkTextIter iter1, iter2; int ii, cc; char catgname[tagcc+3]; char *pp1, *pp2; widget = zdialog_widget(zd,"deftags"); wclear(widget); for (ii = 0; ii < maxtagcats; ii++) { pp1 = tags_deftags[ii]; if (! pp1) break; pp2 = strchr(pp1,':'); if (! pp2) continue; if (pp2 > pp1 + tagcc-3) continue; pp2 += 2; cc = pp2 - pp1 + 1; strncpy0(catgname,pp1,cc); wprintx(widget,0,catgname,"monospace bold 9"); if (*pp2) wprintx(widget,0,pp2,"monospace 9"); wprintx(widget,0,"\n"); } textbuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); gtk_text_buffer_get_bounds(textbuff,&iter1,&iter2); pp1 = gtk_text_buffer_get_text(textbuff,&iter1,&iter2,0); strncpy0(tags_deftext,pp1,tagTcc); return; } /**************************************************************************/ // image file EXIF/IPTC data >> tags_date, tags_stars, tags_filetags, // tags_comments, tags_caption in memory void load_fileinfo(cchar *file) { void exif_tagdate(cchar *exifdate, char *tagdate); int ii, jj, cc; char *pp; cchar *exifkeys[5] = { exif_date_key, iptc_tags_key, iptc_rating_key, exif_comment_key, iptc_caption_key }; char **ppv, *imagedate, *imagetags, *imagestars, *imagecomms, *imagecapt; *tags_filetags = *tags_date = *tags_comments = *tags_caption = 0; tags_stars = '0'; ppv = info_get(file,exifkeys,5); // stars rating added v.10.0 imagedate = ppv[0]; imagetags = ppv[1]; imagestars = ppv[2]; imagecomms = ppv[3]; imagecapt = ppv[4]; if (imagedate) { exif_tagdate(imagedate,tags_date); // EXIF date/time >> yyyymmdd strcpy(tags_prdate,tags_date); zfree(imagedate); } if (imagetags) { for (ii = 1; ; ii++) { pp = (char *) strField(imagetags,tagdelims,ii); if (! pp) break; if (*pp == ' ') continue; cc = strlen(pp); if (cc >= tagcc) continue; // reject tags too big for (jj = 0; jj < cc; jj++) if (pp[jj] > 0 && pp[jj] < ' ') break; // reject tags with control characters if (jj < cc) continue; add_tag(pp,tags_filetags,tagFcc); // add to file tags if unique } zfree(imagetags); } if (imagestars) { // v.10.0 tags_stars = *imagestars; if (tags_stars < '0' || tags_stars > '5') tags_stars = '0'; zfree(imagestars); } if (imagecomms) { // v.10.11 strncpy0(tags_comments,imagecomms,tagFcc); zfree(imagecomms); } if (imagecapt) { // v.10.12 strncpy0(tags_caption,imagecapt,tagFcc); zfree(imagecapt); } Ftagschanged = 0; return; } // tags_date, tags_stars, tags_filetags in memory >> image file EXIF/IPTC data // update defined tags file if any changes void save_fileinfo(cchar *file) { void tag_exifdate(cchar *tagdate, char *exifdate); cchar *exifkeys[5] = { exif_date_key, iptc_tags_key, iptc_rating_key, exif_comment_key, iptc_caption_key }; cchar *exifdata[5]; char imagedate[24], sstars[4]; if (! Ftagschanged) return; // no changes to tags etc. Ftagschanged = 0; *imagedate = 0; if (*tags_date) { tag_exifdate(tags_date,imagedate); // yyyymmdd >> EXIF date/time strcpy(tags_prdate,tags_date); } sstars[0] = tags_stars; // string for stars rating sstars[1] = 0; exifdata[0] = imagedate; // update file EXIF/IPTC data exifdata[1] = tags_filetags; exifdata[2] = sstars; exifdata[3] = tags_comments; // v.10.11 exifdata[4] = tags_caption; // v.10.12 info_put(file,exifkeys,exifdata,5); update_search_index(file); // update search index file if (zdexifview) info_view(0); // live EXIF/IPTC update v.10.2 return; } // update search index file (replace updated file data) // overhauled v.12.01 void update_search_index(cchar *file) { char *ppv, temp_search_index_file[200]; char imagedate[12], filedate[16]; char buff[tagrecl]; int err, eof = 0, fcopy = 0, comp = 0, finserted = 0; FILE *fidr, *fidw; struct stat statb; struct tm bdt; if (is_syncbusy()) return; // must wait for file sync v.11.11 strcpy(temp_search_index_file,search_index_file); // temp tag file strcat(temp_search_index_file,"_temp"); fidw = fopen(temp_search_index_file,"w"); // write temp tag file (new) if (! fidw) goto tagserror; fidr = fopen(search_index_file,"r"); // read tag file (old) if (fidr) { while (true) // copy search index file to temp { // file, inserting or replacing ppv = fgets_trim(buff,tagrecl,fidr); // records for caller's file if (! ppv) eof = 1; if (strnEqu(buff,"file: ",6)) // start of next file entry { comp = strcmp(file,buff+6); if (comp > 0) fcopy = 1; // new entry is after this one if (comp == 0) fcopy = 0; // new entry replaces this one if (comp < 0) fcopy = 1; // new entry is before this one } if (comp <= 0 && ! finserted) // new entry inserts here v.12.01 { err = fprintf(fidw,"file: %s\n",file); // output filespec if (err <= 0) goto tagserror; if (*tags_date) { // image date strncpy(imagedate,tags_date,4); strncpy(imagedate+5,tags_date+4,2); // yyyymmdd >> yyyy:mm:dd strncpy(imagedate+8,tags_date+6,2); imagedate[4] = imagedate[7] = ':'; imagedate[10] = 0; } else strcpy(imagedate,"null"); // missing image date err = stat(file,&statb); gmtime_r(&statb.st_mtime,&bdt); sprintf(filedate,"%04d%02d%02d%02d%02d%02d", // file date = yyyymmddhhmmss bdt.tm_year + 1900, bdt.tm_mon + 1, bdt.tm_mday, bdt.tm_hour, bdt.tm_min, bdt.tm_sec); err = fprintf(fidw,"date: %s %s\n",imagedate,filedate); // output image and file date if (*tags_filetags) // output filetags err = fprintf(fidw,"tags: %s\n",tags_filetags); else err = fprintf(fidw,"tags: null" tagdelim2 "\n"); // "null" tag if none v.11.02 err = fprintf(fidw,"stars: %c\n",tags_stars); // output stars rating if (*tags_comments) // output user comments err = fprintf(fidw,"comms: %s\n",tags_comments); else err = fprintf(fidw,"comms: null \n"); // "null" if none if (*tags_caption) // output user caption v.10.12 err = fprintf(fidw,"capt: %s\n",tags_caption); else err = fprintf(fidw,"capt: null \n"); // "null" if none err = fprintf(fidw,"\n"); // EOL finserted = 1; } if (eof) break; if (fcopy) fprintf(fidw,"%s\n",buff); // copy this entry } err = fclose(fidr); if (err) goto tagserror; } err = fclose(fidw); // close temp file if (err) goto tagserror; err = rename(temp_search_index_file,search_index_file); // replace tags file with temp file if (err) goto tagserror; return; tagserror: zmessLogACK(mWin,ZTX("search index file error: %s"),strerror(errno)); return; } // file is deleted from search index file void delete_search_index(cchar *file) // overhauled v.10.11.2 { char *ppv, temp_search_index_file[200]; char indexbuff[tagrecl]; char filebuff[tagrecl], datebuff[tagrecl]; char tagsbuff[tagrecl], starsbuff[tagrecl]; char commsbuff[tagrecl], captbuff[tagrecl]; int err, ftf = 1; FILE *fidr, *fidw; if (is_syncbusy()) return; // must wait for file sync v.11.11 strcpy(temp_search_index_file,search_index_file); // temp tag file strcat(temp_search_index_file,"_temp"); fidr = fopen(search_index_file,"r"); // read tag file if (! fidr) return; fidw = fopen(temp_search_index_file,"w"); // write temp tag file if (! fidw) goto tagserror; while (true) // copy search index file to temp { // file, omitting this image file ppv = fgets_trim(indexbuff,tagrecl,fidr); if (! ppv || strnEqu(indexbuff,"file: ",6)) // EOF or start of next file { if (! ftf && strNeq(filebuff+6,file)) // not 1st time and not file to omit { fprintf(fidw,"%s\n",filebuff); // output completed data for previous file fprintf(fidw,"%s\n",datebuff); fprintf(fidw,"%s\n",tagsbuff); fprintf(fidw,"%s\n",starsbuff); fprintf(fidw,"%s\n",commsbuff); fprintf(fidw,"%s\n",captbuff); fprintf(fidw,"\n"); } if (! ppv) break; // EOF ftf = 0; strncpy0(filebuff,indexbuff,tagrecl); // next file: filespec record strcpy(datebuff,"date: null "); // initz. remaining data = empty strcpy(tagsbuff,"tags: null"tagdelim2); // v.11.02 strcpy(starsbuff,"stars: 0 "); strcpy(commsbuff,"comms: null "); strcpy(captbuff,"capt: null "); } if (strnEqu(indexbuff,"date: ",6)) // copy whatever is found strncpy0(datebuff,indexbuff,tagrecl); if (strnEqu(indexbuff,"tags: ",6)) strncpy0(tagsbuff,indexbuff,tagrecl); if (strnEqu(indexbuff,"stars: ",7)) strncpy0(starsbuff,indexbuff,tagrecl); if (strnEqu(indexbuff,"comms: ",7)) strncpy0(commsbuff,indexbuff,tagrecl); if (strnEqu(indexbuff,"capt: ",6)) strncpy0(captbuff,indexbuff,tagrecl); } err = fclose(fidr); if (err) goto tagserror; err = fclose(fidw); if (err) goto tagserror; err = rename(temp_search_index_file,search_index_file); // replace tags file with temp file if (err) goto tagserror; return; tagserror: zmessLogACK(mWin,ZTX("search index file error: %s"),strerror(errno)); return; } /**************************************************************************/ // menu function - add tags to many files at once char **batchAddTags_filelist = 0; int batchAddTags_filecount = 0; zdialog *zdbatchAddTags = null; // batch add tags dialog void m_batchAddTags(GtkWidget *, cchar *) // new v.9.7 { void batchAddTags_fixwidget(zdialog *zd, cchar * widgetname); int batchAddTags_dialog_event(zdialog *zd, cchar *event); char *ptag, **flist, *file; int ii, jj, err; zfuncs::F1_help_topic = "batch_add_tags"; // v.10.8 if (! Fexiftool) { // exiftool is required zmessageACK(mWin,Bexiftoolmissing); return; } if (is_syncbusy()) return; // must wait for file sync v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // v.10.5 zdbatchAddTags = zdialog_new(ZTX("Batch Add Tags"),mWin,Bproceed,Bcancel,null); zdialog_add_widget(zdbatchAddTags,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zdbatchAddTags,"label","lab1","hb1",ZTX("tags to add"),"space=10"); zdialog_add_widget(zdbatchAddTags,"frame","frame1","hb1",0,"expand"); zdialog_add_widget(zdbatchAddTags,"edit","batchAddTags","frame1",0,"expand|wrap"); // v.11.06 zdialog_add_widget(zdbatchAddTags,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zdbatchAddTags,"button","createtag","hb2",ZTX("create tag"),"space=10"); zdialog_add_widget(zdbatchAddTags,"entry","ctag","hb2",0); zdialog_add_widget(zdbatchAddTags,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zdbatchAddTags,"button","files","hb3",Bselectfiles,"space=10"); zdialog_add_widget(zdbatchAddTags,"label","labcount","hb3","0 files selected","space=10"); zdialog_add_widget(zdbatchAddTags,"hbox","space","dialog",0,"space=3"); zdialog_add_widget(zdbatchAddTags,"hbox","hb5","dialog"); zdialog_add_widget(zdbatchAddTags,"label","labdeftags","hb5",ZTX("defined tags")); zdialog_add_widget(zdbatchAddTags,"frame","frame5","dialog",0,"space=5|expand"); zdialog_add_widget(zdbatchAddTags,"scrwin","scrwin5","frame5",0,"expand"); zdialog_add_widget(zdbatchAddTags,"edit","deftags","scrwin5",0,"expand|wrap"); // v.11.06 load_deftags(); // stuff defined tags into dialog deftags_stuff(zdbatchAddTags); batchAddTags_filelist = 0; batchAddTags_filecount = 0; *tags_batchAddTags = 0; zdialog_resize(zdbatchAddTags,400,400); // run dialog zdialog_help(zdbatchAddTags,"batch_add_tags"); // zdialog help topic v.11.08 zdialog_run(zdbatchAddTags,batchAddTags_dialog_event); batchAddTags_fixwidget(zdbatchAddTags,"batchAddTags"); // setup for mouse tag selection batchAddTags_fixwidget(zdbatchAddTags,"deftags"); zdialog_wait(zdbatchAddTags); // wait for dialog completion flist = batchAddTags_filelist; if (zdbatchAddTags->zstat != 1) goto cleanup; if (! batchAddTags_filecount) goto cleanup; if (*tags_batchAddTags <= ' ') goto cleanup; // v.10.5 write_popup_text("open","Adding Tags",500,200,mWin); // status monitor popup window v.11.01 for (ii = 0; flist[ii]; ii++) // loop all selected files { file = flist[ii]; // display image err = f_open(file,0); if (err) continue; write_popup_text("write",file); // report progress zmainloop(); load_fileinfo(file); // load current file tags for (jj = 1; ; jj++) // add new tags unless already { ptag = (char *) strField(tags_batchAddTags,tagdelims,jj); if (! ptag) break; if (*ptag == ' ') continue; err = add_tag(ptag,tags_filetags,tagFcc); if (err == 2) zmessageACK(mWin,ZTX("%s \n too many tags"),file); } save_fileinfo(file); // save tag changes } write_popup_text("write","COMPLETED"); write_popup_text("close",0); cleanup: zdialog_free(zdbatchAddTags); if (batchAddTags_filecount) { for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); } menulock(0); return; } // setup tag display widget for tag selection using mouse clicks void batchAddTags_fixwidget(zdialog *zd, cchar * widgetname) { void batchAddTags_mouse(GtkTextView *widget, GdkEventButton *event, cchar *widgetname); GtkWidget *widget; GdkWindow *gdkwin; widget = zdialog_widget(zd,widgetname); // make widget wrap text gtk_text_view_set_editable(GTK_TEXT_VIEW(widget),0); // disable widget editing gdkwin = gtk_text_view_get_window(GTK_TEXT_VIEW(widget),TEXTWIN); // cursor for tag selection gdk_window_set_cursor(gdkwin,arrowcursor); gtk_widget_add_events(widget,GDK_BUTTON_PRESS_MASK); // connect mouse-click event G_SIGNAL(widget,"button-press-event",batchAddTags_mouse,widgetname); } // batchAddTags mouse-click event function // get clicked tag and add to or remove from tags_batchAddTags void batchAddTags_mouse(GtkTextView *widget, GdkEventButton *event, cchar *widgetname) { int mpx, mpy, cc; if (event->type != GDK_BUTTON_PRESS) return; mpx = int(event->x); // mouse click position mpy = int(event->y); cc = get_mouse_tag(widget,mpx,mpy,widgetname); // tags_cliktag = clicked tag in list if (! cc) return; if (strEqu(widgetname,"batchAddTags")) { del_tag(tags_cliktag,tags_batchAddTags); // remove tag from tags_batchAddTags zdialog_stuff(zdbatchAddTags,"batchAddTags",tags_batchAddTags); // update dialog widgets } if (strEqu(widgetname,"deftags")) { add_tag(tags_cliktag,tags_batchAddTags,tagMcc); // add defined tag to tags_batchAddTags zdialog_stuff(zdbatchAddTags,"batchAddTags",tags_batchAddTags); } return; } // batchAddTags dialog event function int batchAddTags_dialog_event(zdialog *zd, cchar *event) { int ii, err; char tag[tagcc]; char **flist = batchAddTags_filelist, countmess[50]; if (strEqu(event,"createtag")) { err = zdialog_fetch(zd,"ctag",tag,tagcc); // add new tag to list if (err) return 0; // reject too big tag add_tag(tag,tags_batchAddTags,tagMcc); // add tag to tags_batchAddTags zdialog_stuff(zd,"batchAddTags",tags_batchAddTags); // update dialog widgets zdialog_stuff(zd,"ctag",""); } if (strEqu(event,"files")) // select images to add tags { if (flist) { // free prior list for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); } flist = image_gallery_getfiles(0,mWin); // get file list from user batchAddTags_filelist = flist; if (flist) // count files in list for (ii = 0; flist[ii]; ii++); else ii = 0; batchAddTags_filecount = ii; snprintf(countmess,50,ZTX("%d files selected"),batchAddTags_filecount); zdialog_stuff(zd,"labcount",countmess); } return 0; } /**************************************************************************/ // menu function - delete or replace a tag for many files at once char **batchDelTag_filelist = 0; void m_batchDelTag(GtkWidget *, cchar *) // new v.10.9 { int batchDelTag_dialog_event(zdialog *zd, cchar *event); char **flist, *file; char deltag[tagcc], reptag[tagcc]; int ii, err; zdialog *zd; zfuncs::F1_help_topic = "batch_delete_tag"; if (! Fexiftool) { // exiftool is required zmessageACK(mWin,Bexiftoolmissing); return; } if (is_syncbusy()) return; // must wait for file sync v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; // v.10.5 zd = zdialog_new(ZTX("Batch Delete Tag"),mWin,Bproceed,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab1","hb1",ZTX("tag to remove"),"space=10"); zdialog_add_widget(zd,"entry","deltag","hb1",0,"scc=20"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","lab2","hb2",ZTX("optional replacement"),"space=10"); zdialog_add_widget(zd,"entry","reptag","hb2",0,"scc=20"); zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zd,"button","files","hb3",Bselectfiles,"space=10"); zdialog_add_widget(zd,"label","labcount","hb3",ZTX("0 files selected"),"space=10"); zdialog_add_widget(zd,"hbox","hb4","dialog",0,"space=5"); zdialog_add_widget(zd,"check","allfiles","hb4",ZTX("search all files"),"space=10"); batchDelTag_filelist = flist = 0; zdialog_help(zd,"batch_delete_tag"); // zdialog help topic v.11.08 zdialog_run(zd,batchDelTag_dialog_event); // run dialog zdialog_wait(zd); // wait for completion if (zd->zstat != 1) goto cleanup; // canceled flist = batchDelTag_filelist; // get selected files if (! flist) goto cleanup; zdialog_fetch(zd,"deltag",deltag,tagcc); // get tag to delete strTrim2(deltag); // remove leading and trailing blanks strToLower(deltag); // use lower case for matching if (! *deltag) goto cleanup; zdialog_fetch(zd,"reptag",reptag,tagcc); // optional replacement tag strTrim2(reptag); write_popup_text("open","Deleting Tags",500,200,mWin); // status monitor popup window v.11.01 for (ii = 0; flist[ii]; ii++) // loop all selected files { file = flist[ii]; err = f_open(file,0); // display image if (err) continue; write_popup_text("write",file); // report progress zmainloop(); load_fileinfo(file); // load current file tags err = del_tag(deltag,tags_filetags); // remove tag, if present if (err) continue; // not present if (*reptag) { // add replacement tag, if defined err = add_tag(reptag,tags_filetags,tagFcc); if (err == 2) zmessageACK(mWin,ZTX("%s \n too many tags"),file); } save_fileinfo(file); // save tag changes } write_popup_text("write","COMPLETED"); write_popup_text("close",0); cleanup: zdialog_free(zd); if (flist) { for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); } menulock(0); return; } // batchDelTag dialog event function int batchDelTag_dialog_event(zdialog *zd, cchar *event) { FILE *fidr; struct stat statbuf; char deltag[tagcc]; char **flist = batchDelTag_filelist; int err, nfiles, ii, allfiles; char filebuff[tagrecl], tagsbuff[tagrecl]; char *ppv, *file, *tags, countmess[50]; cchar *ppf; int maxfiles = 100000; // max. files with tag to delete v.11.04 zdialog_fetch(zd,"deltag",deltag,tagcc); // get tag to delete strTrim2(deltag); // remove leading and trailing blanks strToLower(deltag); // use lower case for matching if (zd->zstat == 1) // [proceed] { if (! flist) { zmessageACK(mWin,ZTX("no files selected")); // v.11.01 zd->zstat = 0; // keep dialog active goto finish; } if (! *deltag) { zmessageACK(mWin,ZTX("no tag specified")); // v.11.01 zd->zstat = 0; goto finish; } return 0; } if (strEqu(event,"deltag")) // tag changed { if (flist) { // clear file list v.11.01 for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); flist = 0; } zdialog_stuff(zd,"allfiles",0); // reset "all files" checkbox v.11.01 goto finish; } if (strEqu(event,"files")) // select images to delete tags { if (! *deltag) { zmessageACK(mWin,ZTX("specify tag")); // v.11.01 goto finish; } if (flist) { // free prior list for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); flist = 0; } flist = image_gallery_getfiles(0,mWin); // get file list from user zdialog_stuff(zd,"allfiles",0); // reset "all files" checkbox v.11.01 goto finish; } if (strEqu(event,"allfiles")) { if (flist) { // clear file list for (ii = 0; flist[ii]; ii++) zfree(flist[ii]); zfree(flist); flist = 0; } zdialog_fetch(zd,"allfiles",allfiles); // get checkbox "all files" if (! allfiles) goto finish; // was unselected if (! *deltag) { zmessageACK(mWin,ZTX("specify tag")); // v.11.01 goto finish; } fidr = fopen(search_index_file,"r"); // read search index file if (! fidr) goto finish; // no file flist = (char **) zmalloc(maxfiles*sizeof(char *),"DeleteTag"); // list for files found nfiles = 0; // count files found flist[0] = 0; while (true) { ppv = fgets_trim(filebuff,tagrecl,fidr,1); // next record if (! ppv) break; // EOF if (! strnEqu(ppv,"file: ",6)) continue; // file: /dir.../filename.jpg file = ppv+6; err=stat(file,&statbuf); // check file exists if (err) continue; if (! S_ISREG(statbuf.st_mode)) continue; ppv = fgets_trim(tagsbuff,tagrecl,fidr); // next record if (! ppv) break; if (! strnEqu(ppv,"date: ",6)) continue; // date: yyyy:mm:dd ppv = fgets_trim(tagsbuff,tagrecl,fidr); // next record if (! ppv) break; if (! strnEqu(ppv,"tags: ",6)) continue; // tags: xxxx, xxxxx, ... tags = ppv + 6; strToLower(tags); // use lower case for matching for (ii = 1; ; ii++) // step thru file tags { ppf = strField(tags,tagdelims,ii); if (! ppf) break; if (*ppf == ' ') continue; if (strEqu(ppf,deltag)) break; // look for my tag } if (! ppf) continue; // tag not found flist[nfiles] = strdupz(file,0,"batch_del_tag"); nfiles++; if (nfiles == maxfiles-1) break; } fclose(fidr); // close search index file flist[nfiles] = 0; // EOL marker } finish: batchDelTag_filelist = flist; // file list to process if (flist) // count files in list for (ii = 0; flist[ii]; ii++); else ii = 0; snprintf(countmess,50,ZTX("%d files selected"),ii); // stuff file count into dialog zdialog_stuff(zd,"labcount",countmess); return 0; } /************************************************************************** functions to view and edit metadata: EXIF, IPTC, etc. ***************************************************************************/ // menu function and popup dialog to show EXIF/IPTC data // window is updated when navigating to another image void m_info_view_short(GtkWidget *, cchar *menu) // v.10.12 { zfuncs::F1_help_topic = "view_info"; info_view(1); return; } void m_info_view_long(GtkWidget *, cchar *menu) // v.10.12 { zfuncs::F1_help_topic = "view_info"; info_view(2); return; } void info_view(int arg) { int info_view_dialog_event(zdialog *zd, cchar *event); static int length = 1; char *buff; int contx = 0; GtkWidget *widget; if (! Fexiftool) { // exiftool is required zmessageACK(mWin,Bexiftoolmissing); return; } if (! curr_file) return; if (arg > 0) length = arg; // change short/long report mode if (! zdexifview) // popup dialog if not already { zdexifview = zdialog_new(ZTX("View Info"),mWin,Bcancel,null); zdialog_add_widget(zdexifview,"scrwin","scroll","dialog",0,"expand"); zdialog_add_widget(zdexifview,"edit","exifdata","scroll",0,"expand|wrap"); zdialog_resize(zdexifview,500,400); zdialog_help(zdexifview,"view_info"); // zdialog help topic v.11.08 zdialog_run(zdexifview,info_view_dialog_event); } widget = zdialog_widget(zdexifview,"exifdata"); // v.10.12 gtk_text_view_set_editable(GTK_TEXT_VIEW(widget),0); // disable widget editing gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(widget),GTK_WRAP_NONE); // disable text wrap if (length == 1) // short report { snprintf(command,ccc,"exiftool -common -%s -%s -%s -%s -%s -%s \"%s\" ", iptc_tags_key, iptc_rating_key, iptc_editlog_key, exif_comment_key, iptc_caption_key, exif_focal_length_key, curr_file); } else snprintf(command,ccc,"exiftool -e \"%s\" ",curr_file); // long, output everything widget = zdialog_widget(zdexifview,"exifdata"); // widget for output wclear(widget); while ((buff = command_output(contx,command))) { // run command, output into window wprintf(widget,"%s\n",buff); zfree(buff); // memory leak v.11.03 } command_status(contx); // free resources return; } // dialog event and completion callback function int info_view_dialog_event(zdialog *zd, cchar *event) // kill dialog { if (! zd->zstat) return 0; zdialog_free(zdexifview); return 0; } /**************************************************************************/ // edit EXIF/IPTC data - add or change specified EXIF/IPTC/etc. key void m_info_edit(GtkWidget *, cchar *menu) // new v.10.2 { char keyname[40], keydata[1000]; cchar *pp1[1]; char **pp2; int info_edit_dialog_event(zdialog *zd, cchar *event); if (menu) zfuncs::F1_help_topic = "edit_info"; if (! Fexiftool) { // exiftool is required zmessageACK(mWin,Bexiftoolmissing); return; } if (! curr_file) return; if (! zdexifedit) // popup dialog if not already v.10.8 { zdexifedit = zdialog_new(ZTX("Edit Info"),mWin,Bfetch,Bsave,Bcancel,null); zdialog_add_widget(zdexifedit,"vbox","hb1","dialog"); zdialog_add_widget(zdexifedit,"hbox","hbkey","dialog",0,"space=5"); zdialog_add_widget(zdexifedit,"hbox","hbdata","dialog",0,"space=5"); zdialog_add_widget(zdexifedit,"label","labkey","hbkey","key name"); zdialog_add_widget(zdexifedit,"entry","keyname","hbkey",0,"scc=20"); zdialog_add_widget(zdexifedit,"label","labdata","hbdata","key value"); zdialog_add_widget(zdexifedit,"entry","keydata","hbdata",0,"expand"); zdialog_help(zdexifedit,"edit_info"); // zdialog help topic v.11.08 zdialog_run(zdexifedit,info_edit_dialog_event); } zdialog_fetch(zdexifedit,"keyname",keyname,40); // get key name from dialog strCompress(keyname); // v.10.8 if (*keyname) // update live dialog v.10.8 { pp1[0] = keyname; // look for key data pp2 = info_get(curr_file,pp1,1); if (pp2[0]) { strncpy0(keydata,pp2[0],999); zfree(pp2[0]); } else *keydata = 0; zdialog_stuff(zdexifedit,"keydata",keydata); // stuff into dialog } return; } // dialog event and completion callback function int info_edit_dialog_event(zdialog *zd, cchar *event) { char keyname[40], keydata[1000]; // v.11.02 (was 100) cchar *pp1[1], *pp2[1]; char **pp3; int err; if (! zd->zstat) return 0; zdialog_fetch(zd,"keyname",keyname,40); zdialog_fetch(zd,"keydata",keydata,1000); strCompress(keyname); // remove blanks v.10.8 if (zd->zstat == 1) // fetch { zd->zstat = 0; if (! *keyname) return 0; // bugfix v.11.02 pp1[0] = keyname; pp3 = info_get(curr_file,pp1,1); if (pp3[0]) { strncpy0(keydata,pp3[0],99); zfree(pp3[0]); } else *keydata = 0; zdialog_stuff(zd,"keydata",keydata); } else if (zd->zstat == 2) // save { zd->zstat = 0; // keep dialog active if (! *keyname) return 0; // bugfix v.11.02 if (is_syncbusy()) return 0; // must wait for file sync v.11.11 pp1[0] = keyname; pp2[0] = keydata; err = info_put(curr_file,pp1,pp2,1); if (err) zmessageACK(mWin,"error: %s",strerror(err)); if (zdexifview) info_view(0); // update exif view if active } else zdialog_free(zdexifedit); // other return 1; } /**************************************************************************/ // delete EXIF/IPTC data, specific key or all data void m_info_delete(GtkWidget *, cchar *menu) // new v.10.2 { int info_delete_dialog_event(zdialog *zd, cchar *event); zdialog *zd; zfuncs::F1_help_topic = "delete_info"; // v.10.8 if (! Fexiftool) { // exiftool is required zmessageACK(mWin,Bexiftoolmissing); return; } if (! curr_file) return; if (is_syncbusy()) return; // must wait for file sync v.11.11 zd = zdialog_new(ZTX("Delete Info"),mWin,Bapply,Bcancel,null); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"radio","kall","hb1",ZTX("All"),"space=5"); zdialog_add_widget(zd,"radio","key1","hb1",ZTX("One Key:")); zdialog_add_widget(zd,"entry","keyname","hb1",0,"scc=20"); zdialog_stuff(zd,"key1",1); zdialog_help(zd,"delete_info"); // zdialog help topic v.11.08 zdialog_run(zd,info_delete_dialog_event); return; } // dialog event and completion callback function int info_delete_dialog_event(zdialog *zd, cchar *event) { int kall, key1, err; char keyname[40]; if (! zd->zstat) return 0; if (zd->zstat != 1) { // canceled zdialog_free(zd); return 1; } zd->zstat = 0; // dialog remains active zdialog_fetch(zd,"kall",kall); zdialog_fetch(zd,"key1",key1); zdialog_fetch(zd,"keyname",keyname,40); strCompress(keyname); // v.10.8 // bugfix - quotes around file v.10.3 if (kall) snprintf(command,ccc,"exiftool -m -q -overwrite_original -all= \"%s\"",curr_file); else if (key1) snprintf(command,ccc,"exiftool -m -q -overwrite_original -%s= \"%s\"",keyname,curr_file); else return 1; err = system(command); if (err) zmessageACK(mWin,"%s",wstrerror(err)); if (zdexifview) info_view(0); // update exif view if active return 1; } /**************************************************************************/ // get EXIF/IPTC metadata for given image file and EXIF/IPTC key(s) // returns array of pointers to corresponding key values // if a key is missing, corresponding pointer is null // returned strings belong to caller, are subject for zfree() // up to 9 keynames may be requested per call // command: // exiftool -keyname1 -keyname2 ... "file" // command output: // keyname1: keyvalue1 // keyname2: keyvalue2 // ... // The CPU time for this call is about 0.1 seconds (BIG). char ** info_get(cchar *file, cchar **keys, int nkeys) { char *pp; static char *keyvals[10]; int contx = 0, err, ii; uint cc; if (nkeys < 1 || nkeys > 9) zappcrash("info_get nkeys: %d",nkeys); cc = 10 * sizeof(char *); // v.12.01 memset(keyvals,0,cc); strcpy(command,"exiftool -m -q -S -fast"); for (ii = 0; ii < nkeys; ii++) // build command line strncatv(command,ccc," -",keys[ii],null); strncatv(command,ccc," \"",file,"\"",null); while (true) { pp = command_output(contx,command); if (! pp) break; for (ii = 0; ii < nkeys; ii++) { cc = strlen(keys[ii]); if (strncasecmp(pp,keys[ii],cc) == 0) // ignore case if (strlen(pp) > cc+2) keyvals[ii] = strdupz(pp+cc+2,0,"info_get"); // check not empty } zfree(pp); } err = command_status(contx); if (err) printf(" exiftool: %s \n",wstrerror(err)); return keyvals; } /**************************************************************************/ // Get metadata for a list of image files and a list of EXIF/IPTC keys. // // Returns an array of pointers to corresponding key values. // If a key is missing, corresponding pointer is null. // Returned strings belong to caller, are subject for zfree(). // // shell command: // exiftool -keyname1 -keyname2 ... "file1" "file2" ... // // shell command output: // ======== file1 // keyname1: keyvalue1 // keyname2: keyvalue2 // ... // ======== file2 // keyname1: keyvalue3 // keyname2: keyvalue4 // ... // // Returned list of strings (char **): // keyvalue1, keyvalue2, ... keyvalue3, keyvalue4, ... null // // The CPU time for this call is about 0.1 + 0.01 seconds per file // (based on 3.3 GHz Intel Core i5 cpu). char ** info_getN(cchar **files, int NF, cchar **keys, int NK) // v.12.01 { char *ppk, *ppv, **keyvals; int contx = 0, cc, ii, ff, kk; char command[10000]; cc = (1 + NF * NK) * sizeof(char *); keyvals = (char **) zmalloc(cc,"info_getN"); memset(keyvals,0,cc); strcpy(command,"exiftool -m -s2 -fast2"); // build command line for (kk = 0; kk < NK; kk++) strncatv(command,9999," -",keys[kk],null); for (ff = 0; ff < NF; ff++) strncatv(command,9999," \"",files[ff],"\"",null); ff = NF; // flag: no current file while ((ppk = command_output(contx,command))) { if (NF > 1) // multiple files { if (strnEqu(ppk,"========",8)) // look for start of next file { for (ff = 0; ff < NF; ff++) if (strstr(ppk+8,files[ff])) break; // locate file in my list zfree(ppk); continue; } if (ff == NF) continue; // no matching file } else ff = 0; // if 1 file, no "========" lines for (kk = 0; kk < NK; kk++) { // look for key name cc = strlen(keys[kk]); if (strncasecmp(ppk,keys[kk],cc)) continue; ppv = ppk + cc; // name matches while (*ppv && *ppv == ' ') ppv++; // followed by blanks if (strncmp(ppv,": ",2)) continue; // followed by ": " ppv += 2; if (strlen(ppv) < 1) continue; // followed by key value if (strlen(ppv) > 999) ppv[999] = 0; // limit length to 999 ii = NK * ff + kk; // index for file and key keyvals[ii] = strdupz(ppv,0,"info_getN"); break; } zfree(ppk); } return keyvals; } /**************************************************************************/ // create or change EXIF/IPTC metadata for given image file and key(s) // up to 9 keys may be processed // command: // exiftool -overwrite_original -keyname="keyvalue" ... "file" // // NOTE: exiftool replaces \n (newline) in "keyvalue" with "." (period) int info_put(cchar *file, cchar **keys, cchar **text, int nkeys) { int ii, err; char *ptext[10]; if (nkeys < 1 || nkeys > 9) zappcrash("info_put nkeys: %d",nkeys); for (ii = 0; ii < nkeys; ii++) { if (! text[ii]) text[ii] = ""; // if null pointer use empty string ptext[ii] = strdupz(text[ii],20,"info_put"); if (strchr(text[ii],'"')) // replace imbedded " with \" repl_1str(text[ii],ptext[ii],"\"","\\\""); // else exiftool command fails } strcpy(command,"exiftool -m -q -overwrite_original"); for (ii = 0; ii < nkeys; ii++) // build command line strncatv(command,ccc," -",keys[ii],"=\"",ptext[ii],"\"",null); strncatv(command,ccc," \"",file,"\"",null); for (ii = 0; ii < nkeys; ii++) // plug small leak v.12.01 zfree((char *) ptext[ii]); err = system(command); if (err) printf(" info_put: %s \n",wstrerror(err)); return err; } /**************************************************************************/ // copy EXIF/IPTC data from original image file to new (edited) image file // if nkeys > 0, up to 9 keys may be replaced with new values // exiftool command revised: parameter sequence and -icc_profile int info_copy(cchar *file1, cchar *file2, cchar **keys, cchar **text, int nkeys) { int ii, err; strcpy(command,"exiftool -m -q -tagsfromfile"); // exiftool -m -q -tagsfromfile "file1" strncatv(command,ccc," \"",file1,"\"",null); strncatv(command,ccc," -all -icc_profile",null); // -all -icc_profile for (ii = 0; ii < nkeys; ii++) // -keyname="keyvalue" ... (options) if (text[ii]) strncatv(command,ccc," -",keys[ii],"=\"",text[ii],"\"",null); strncatv(command,ccc," \"",file2,"\""," -overwrite_original",null); // "file2" -overwrite_original err = system(command); if (err) printf(" exiftool: %s \n",wstrerror(err)); return err; } /**************************************************************************/ // convert between EXIF and fotoxx tag date formats // EXIF date: yyyy:mm:dd hh:mm:ss[.ss] // tag date: yyyymmdd // void exif_tagdate(cchar *exifdate, char *tagdate) { time_t tnow; struct tm *snow; if (! exifdate || strlen(exifdate) < 10) { // bad EXIF date, use current date tnow = time(0); snow = localtime(&tnow); snprintf(tagdate,8,"%4d%02d%02d", snow->tm_year+1900, snow->tm_mon+1, snow->tm_mday); tagdate[8] = 0; return; } strncpy(tagdate,exifdate,4); // convert strncpy(tagdate+4,exifdate+5,2); strncpy(tagdate+6,exifdate+8,2); tagdate[8] = 0; return; } void tag_exifdate(cchar *tagdate, char *exifdate) { int cc; time_t tnow; struct tm *snow; if (! tagdate || strlen(tagdate) < 4) { tnow = time(0); snow = localtime(&tnow); snprintf(exifdate,20,"%4d:%02d:%02d %02d:%02d:%02d", snow->tm_year+1900, snow->tm_mon+1, snow->tm_mday, snow->tm_hour, snow->tm_min, snow->tm_sec); exifdate[19] = 0; return; } strncpy(exifdate,tagdate,4); strcpy(exifdate+4,":01:01 00:00:00"); cc = strlen(tagdate); if (cc >= 6) strncpy(exifdate+5,tagdate+4,2); if (cc >= 8) strncpy(exifdate+8,tagdate+6,2); exifdate[19] = 0; return; } /**************************************************************************/ // search image tags, dates, stars, comments, captions for matching images char searchDateFrom[12] = ""; // image search date range char searchDateTo[12] = ""; char searchStarsFrom[4] = ""; // image search stars range char searchStarsTo[4] = ""; zdialog *zdsearchinfo = 0; // search tags dialog void m_search_images(GtkWidget *, cchar *) { void searchinfo_fixwidget(zdialog *zd, cchar * widgetname); int searchinfo_dialog_event(zdialog*, cchar *event); zdialog *zd; if (is_syncbusy()) return; // must wait for file sync v.11.11 if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; menulock(0); zfuncs::F1_help_topic = "search_images"; // v.10.8 /*** date range [_______] [_______] (yyyymmdd) stars range [__] [__] all any search tags [________________________] (o) (o) search text [________________________] (o) (o) file names [________________________] (o) (o) defined tags ---------------------------------------------- | | | | | | | | | | ---------------------------------------------- [proceed] [cancel] ***/ zd = zdialog_new(ZTX("Search Tags, Comments, File Names"),mWin,Bproceed,Bcancel,null); zdsearchinfo = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"homog|space=3"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"homog|space=3|expand"); zdialog_add_widget(zd,"label","labD","vb1",ZTX("date range")); zdialog_add_widget(zd,"label","labS","vb1",ZTX("stars range")); zdialog_add_widget(zd,"label","labT","vb1",ZTX("search tags")); zdialog_add_widget(zd,"label","labT","vb1",ZTX("search text")); zdialog_add_widget(zd,"label","labF","vb1",ZTX("file names")); zdialog_add_widget(zd,"hbox","hbD","vb2",0,"space=1"); zdialog_add_widget(zd,"entry","datefrom","hbD",0,"scc=10"); zdialog_add_widget(zd,"entry","dateto","hbD",0,"scc=10"); zdialog_add_widget(zd,"label","labD","hbD",ZTX("(yyyymmdd)"),"space=5"); zdialog_add_widget(zd,"hbox","hbS","vb2",0,"space=1"); zdialog_add_widget(zd,"entry","starsfrom","hbS",0,"scc=2"); zdialog_add_widget(zd,"entry","starsto","hbS",0,"scc=2"); zdialog_add_widget(zd,"label","space","hbS",0,"expand"); zdialog_add_widget(zd,"label","all-any","hbS",ZTX("all/any")); zdialog_add_widget(zd,"hbox","hbT","vb2",0,"space=1"); zdialog_add_widget(zd,"frame","frameT","hbT",0,"expand"); zdialog_add_widget(zd,"edit","searchtags","frameT",0,"expand|wrap"); zdialog_add_widget(zd,"radio","alltags","hbT",0); zdialog_add_widget(zd,"radio","anytags","hbT",0); zdialog_add_widget(zd,"hbox","hbC","vb2",0,"space=1|expand"); zdialog_add_widget(zd,"entry","searchtext","hbC",0,"expand"); zdialog_add_widget(zd,"radio","alltext","hbC",0); zdialog_add_widget(zd,"radio","anytext","hbC",0); zdialog_add_widget(zd,"hbox","hbF","vb2",0,"space=1|expand"); zdialog_add_widget(zd,"entry","searchfiles","hbF",0,"expand"); zdialog_add_widget(zd,"radio","allfiles","hbF",0); zdialog_add_widget(zd,"radio","anyfiles","hbF",0); zdialog_add_widget(zd,"hbox","hbA1","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labdeftags","hbA1",ZTX("defined tags"),"space=5"); zdialog_add_widget(zd,"hbox","hbA2","dialog",0,"expand"); zdialog_add_widget(zd,"frame","frameA","hbA2",0,"space=5|expand"); zdialog_add_widget(zd,"scrwin","scrwinA","frameA",0,"expand"); zdialog_add_widget(zd,"edit","deftags","scrwinA",0,"expand|wrap"); zdialog_resize(zd,400,500); // start dialog zdialog_help(zd,"search_images"); // zdialog help topic v.11.08 zdialog_run(zd,searchinfo_dialog_event); searchinfo_fixwidget(zd,"deftags"); // setup tag selection via mouse searchinfo_fixwidget(zd,"searchtags"); zdialog_stuff(zd,"datefrom",searchDateFrom); // stuff previous date range zdialog_stuff(zd,"dateto",searchDateTo); zdialog_stuff(zd,"starsfrom",searchStarsFrom); zdialog_stuff(zd,"starsto",searchStarsTo); zdialog_stuff(zd,"searchtags",tags_searchtags); // stuff previous search tags zdialog_stuff(zd,"searchtext",tags_searchtext); // stuff previous search text zdialog_stuff(zd,"searchfiles",tags_searchfiles); // stuff previous search files zdialog_stuff(zd,"alltags",0); // default any tags, text, files zdialog_stuff(zd,"anytags",1); zdialog_stuff(zd,"alltext",0); zdialog_stuff(zd,"anytext",1); zdialog_stuff(zd,"allfiles",0); zdialog_stuff(zd,"anyfiles",1); load_deftags(); // stuff defined tags into dialog deftags_stuff(zd); return; } // setup tag display widget for tag selection using mouse clicks void searchinfo_fixwidget(zdialog *zd, cchar * widgetname) { void searchinfo_mouse(GtkTextView *widget, GdkEventButton *event, cchar *widgetname); GtkWidget *widget; GdkWindow *gdkwin; widget = zdialog_widget(zd,widgetname); // make widget wrap text gtk_text_view_set_editable(GTK_TEXT_VIEW(widget),0); // disable widget editing gdkwin = gtk_text_view_get_window(GTK_TEXT_VIEW(widget),TEXTWIN); // cursor for tag selection gdk_window_set_cursor(gdkwin,arrowcursor); gtk_widget_add_events(widget,GDK_BUTTON_PRESS_MASK); // connect mouse-click event G_SIGNAL(widget,"button-press-event",searchinfo_mouse,widgetname); } // search tags mouse-click event function // get clicked tag and add to or remove from tags_searchtags void searchinfo_mouse(GtkTextView *widget, GdkEventButton *event, cchar *widgetname) { int mpx, mpy, cc; if (event->type != GDK_BUTTON_PRESS) return; mpx = int(event->x); // mouse click position mpy = int(event->y); cc = get_mouse_tag(widget,mpx,mpy,widgetname); // tags_cliktag = clicked tag in list if (! cc) return; if (strEqu(widgetname,"deftags")) { add_tag(tags_cliktag,tags_searchtags,tagScc); // add defined tag to search tags zdialog_stuff(zdsearchinfo,"searchtags",tags_searchtags); } if (strEqu(widgetname,"searchtags")) { // v.10.6 del_tag(tags_cliktag,tags_searchtags); // remove tag from searchtags zdialog_stuff(zdsearchinfo,"searchtags",tags_searchtags); // update dialog widgets } return; } // dialog event and completion callback function int searchinfo_dialog_event(zdialog *zd, cchar *event) { int searchinfo_text(char *text, int Fmall); char indexbuff[tagrecl], resultsfile[200]; char temp[tagrecl], date1[12], date2[12]; cchar *pp, *pps, *ppf; int err, iix, iis, iif, cc; int Nxrec, nmatch, nfail; int Fdates, Ftext, Ffiles, Ftags, Fstars; int Falltags, Falltext, Fallfiles; FILE *fid; struct stat statbuf; struct xrec_t { // image metadata record char *file; // image filespec char *tags; // image tags char *comms; // image comments char *capt; // image caption char date[12]; // image date char stars; // image star rating, '0' to '5' }; if (! zd->zstat) return 0; // wait for completion if (zd->zstat != 1) { zdialog_free(zd); // cancel return 0; } zdialog_fetch(zd,"datefrom",searchDateFrom,10); // get search date range zdialog_fetch(zd,"dateto",searchDateTo,10); zdialog_fetch(zd,"starsfrom",searchStarsFrom,2); // get search stars range zdialog_fetch(zd,"starsto",searchStarsTo,2); zdialog_fetch(zd,"searchtags",tags_searchtags,tagScc); // get search tags zdialog_fetch(zd,"searchtext",tags_searchtext,tagScc); // get search text* zdialog_fetch(zd,"searchfiles",tags_searchfiles,tagScc); // get search /path*/file* zdialog_fetch(zd,"alltags",Falltags); // get match all/any options zdialog_fetch(zd,"alltext",Falltext); zdialog_fetch(zd,"allfiles",Fallfiles); zdialog_free(zd); // cancel dialog strcpy(date1,"0000:01:01"); // defaults for missing dates strcpy(date2,"9999:12:31"); // v.10.12 Fdates = 0; if (*searchDateFrom) { // date from was given Fdates++; strncpy(date1,searchDateFrom,4); // convert format if (searchDateFrom[4] >= '0') // yyyymmdd >> yyyy:mm:dd strncpy(date1+5,searchDateFrom+4,2); if (searchDateFrom[6] >= '0') strncpy(date1+8,searchDateFrom+6,2); } if (*searchDateTo) { // date to was given Fdates++; strncpy(date2,searchDateTo,4); if (searchDateTo[4] >= '0') strncpy(date2+5,searchDateTo+4,2); if (searchDateTo[6] >= '0') strncpy(date2+8,searchDateTo+6,2); } Fstars = 0; if (*searchStarsFrom || *searchStarsTo) Fstars = 1; // stars was given Ffiles = 0; if (! blank_null(tags_searchfiles)) Ffiles = 1; // search path / file (fragment) was given Ftext = 0; if (! blank_null(tags_searchtext)) Ftext = 1; // search text was given Ftags = 0; if (! blank_null(tags_searchtags)) Ftags = 1; // search tags was given if (Ffiles) strToLower(tags_searchfiles); // all comparisons in lower case if (Ftags) strToLower(tags_searchtags); if (Ftext) strToLower(tags_searchtext); cc = MAXIMAGES * sizeof(xrec_t); xrec_t *xrec = (xrec_t *) zmalloc(cc,"search"); memset(xrec,0,cc); Nxrec = 0; fid = fopen(search_index_file,"r"); if (! fid) goto noindexfile; *indexbuff = 0; while (true) // read index file { if (! strnEqu(indexbuff,"file: ",6)) { // skip to next "file" record pp = fgets_trim(indexbuff,tagrecl,fid); if (! pp) break; // EOF continue; } *indexbuff = 0; // prevent possible looping iix = Nxrec; if (xrec[iix].file) zfree(xrec[iix].file); // xrecs are re-used if (xrec[iix].tags) zfree(xrec[iix].tags); if (xrec[iix].comms) zfree(xrec[iix].comms); if (xrec[iix].capt) zfree(xrec[iix].capt); memset(&xrec[iix],0,sizeof(xrec)); pp = indexbuff + 6; // filespec xrec[iix].file = strdupz(pp,0,"search"); // setup new xrec member xrec[iix].stars = '0'; while (true) { pp = fgets_trim(indexbuff,tagrecl,fid); // get recs following "file" if (! pp) break; if (strnEqu(pp,"date: ",6)) { pp = strField(pp,' ',2); if (pp) strncpy0(xrec[iix].date,pp,12); } else if (strnEqu(pp,"tags: ",6)) xrec[iix].tags = strdupz(pp+6,0,"search"); else if (strnEqu(pp,"stars: ",7)) xrec[iix].stars = *(pp+7); else if (strnEqu(pp,"comms: ",7)) xrec[iix].comms = strdupz(pp+7,0,"search"); else if (strnEqu(pp,"capt: ",6)) xrec[iix].capt = strdupz(pp+6,0,"search"); else break; } err=stat(xrec[iix].file,&statbuf); // check file exists if (err) continue; if (! S_ISREG(statbuf.st_mode)) continue; if (Ffiles) // file name match is wanted { nmatch = nfail = 0; for (iis = 1; ; iis++) { pps = strField(tags_searchfiles,' ',iis); // step thru search file names if (! pps) break; if (strcasestr(xrec[iix].file,pps)) nmatch++; else nfail++; } if (nmatch == 0) continue; // no match to any file if (Fallfiles && nfail) continue; // no match to all files } if (Fdates) // date match is wanted { if (strcmp(xrec[iix].date,date1) < 0) continue; if (strcmp(xrec[iix].date,date2) > 0) continue; } if (Ftags) // tags match is wanted { strToLower(temp,xrec[iix].tags); nmatch = nfail = 0; for (iis = 1; ; iis++) // step thru search tags { pps = strField(tags_searchtags,tagdelims,iis); // (delimited, wildcards) if (! pps) break; if (*pps == ' ') continue; for (iif = 1; ; iif++) // step thru file tags (delimited) { ppf = strField(temp,tagdelims,iif); if (! ppf) { nfail++; break; } // count matches and fails if (*ppf == ' ') continue; if (MatchWild(pps,ppf) == 0) { nmatch++; break; } // wildcard match } } if (nmatch == 0) continue; // no match to any tag if (Falltags && nfail) continue; // no match to all tags } if (Fstars) // stars match is wanted { if (*searchStarsFrom && xrec[iix].stars < *searchStarsFrom) continue; if (*searchStarsTo && xrec[iix].stars > *searchStarsTo) continue; } if (Ftext) // text match is wanted { nmatch = nfail = 0; for (iis = 1; ; iis++) // step through search words { pps = strField(tags_searchtext,' ',iis); if (! pps) break; if (*pps == ' ') continue; if (strcasestr(xrec[iix].capt,pps)) nmatch++; // search captions for word else if (strcasestr(xrec[iix].comms,pps)) nmatch++; // search comments for word else nfail++; } if (nmatch == 0) continue; // no match to any word if (Falltext && nfail) continue; // no match to all words } if (++Nxrec == MAXIMAGES) goto toomanyfiles; // keep this record } fclose(fid); if (! Nxrec) goto nomatches; snprintf(resultsfile,199,"%s/search_results",get_zuserdir()); fid = fopen(resultsfile,"w"); // search results output file if (! fid) goto writerror; for (iix = 0; iix < Nxrec; iix++) // write matching filespecs fprintf(fid,"%s\n",xrec[iix].file); fclose(fid); image_gallery(resultsfile,"initF",0,m_gallery2,mWin); // generate gallery of matching files // sort removed v.12.01 image_gallery(0,"paint1"); // show new image gallery window goto freememory; nomatches: zmessageACK(mWin,ZTX("No matching images found")); goto freememory; noindexfile: zmessageACK(mWin,ZTX("No search index file present")); goto freememory; writerror: zmessLogACK(mWin,"output file error: %s",strerror(errno)); goto freememory; toomanyfiles: zmessLogACK(mWin,"too many image files"); goto freememory; freememory: for (iix = 0; iix < Nxrec; iix++) { // free allocated memory if (xrec[iix].file) zfree(xrec[iix].file); if (xrec[iix].tags) zfree(xrec[iix].tags); if (xrec[iix].comms) zfree(xrec[iix].comms); if (xrec[iix].capt) zfree(xrec[iix].capt); } zfree(xrec); return 0; } /**************************************************************************/ // report metadata for the current set of image files // (from a directory, a collection, or a search) namespace search_metadata { char *keys[5]; // search keys and match data char *match[5]; char keyx[8], matchx[8]; } void m_search_metadata(GtkWidget *, cchar *) // new v.12.01 { using namespace search_metadata; int search_metadata_dialog_event(zdialog*, cchar *event); cchar *infomess = "These items are always reported: \n" "date, stars, tags, caption, comment"; zdialog *zd; if (mod_keep()) return; // unsaved edits if (! menulock(1)) return; menulock(0); zfuncs::F1_help_topic = "search_metadata"; /*** Search Metadata (EXIF/IPTC etc.) These items from the current image set are reported: date, stars, tags, caption, comment Additional Items for Report Keyword Match [__________] [_________________] [__________] [_________________] [__________] [_________________] [__________] [_________________] [__________] [_________________] [proceed] [cancel] ***/ zd = zdialog_new("Search Metadata (EXIF/IPTC etc.)",mWin,Bproceed,Bcancel,null); zdialog_add_widget(zd,"label","labinfo","dialog",infomess,"space=5"); zdialog_add_widget(zd,"label","labopts","dialog",ZTX("Additional Items for Report")); zdialog_add_widget(zd,"hbox","hb1","dialog"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"space=5"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"space=5|expand"); zdialog_add_widget(zd,"label","lab1","vb1","Keyword"); zdialog_add_widget(zd,"entry","key0","vb1"); zdialog_add_widget(zd,"entry","key1","vb1"); zdialog_add_widget(zd,"entry","key2","vb1"); zdialog_add_widget(zd,"entry","key3","vb1"); zdialog_add_widget(zd,"entry","key4","vb1"); zdialog_add_widget(zd,"label","lab2","vb2","Match"); zdialog_add_widget(zd,"entry","match0","vb2",0,"expand"); zdialog_add_widget(zd,"entry","match1","vb2",0,"expand"); zdialog_add_widget(zd,"entry","match2","vb2",0,"expand"); zdialog_add_widget(zd,"entry","match3","vb2",0,"expand"); zdialog_add_widget(zd,"entry","match4","vb2",0,"expand"); strcpy(keyx,"keyx"); strcpy(matchx,"matchx"); for (int ii = 0; ii < 5; ii++) // preload prior data if any { keyx[3] = '0' + ii; if (keys[ii]) zdialog_stuff(zd,keyx,keys[ii]); matchx[5] = '0' + ii; if (match[ii]) zdialog_stuff(zd,matchx,match[ii]); } zdialog_help(zd,"search_metadata"); zdialog_resize(zd,400,300); zdialog_run(zd,search_metadata_dialog_event); return; } // dialog event and completion callback function struct xrec_t { // image metadata record char *file; // image filespec char *tags; // image tags char *comms; // image comments char *capt; // image caption char date[12]; // image date char stars; // image star rating, '0' to '5' }; int search_metadata_dialog_event(zdialog *zd, cchar *event) { using namespace search_metadata; using namespace image_navi; int metadata_xrec_compare(cchar *rec1, cchar *rec2); int metadata_xrec_search(char *file, xrec_t *xrecs, int nrecs); char indexbuff[tagrecl], *file, **kvals; char mdtext1[2*tagrecl], mdtext2[5][200]; int err, ii, jj, iif, iix, nth, cc; int Nxrec, Nkeys, Ncache, pcache, Fmeta; char **ppcache = 0, *file2; cchar *pp, *Fcache[50]; FILE *fid; struct stat statbuf; if (! zd->zstat) return 0; // wait for completion if (zd->zstat != 1) { zdialog_free(zd); // cancel return 0; } if (! keys[0]) // first call initialization { for (ii = 0; ii < 5; ii++) { keys[ii] = zmalloc(40,"search_metadata"); match[ii] = zmalloc(100,"search_metadata"); *keys[ii] = *match[ii] = 0; } } Nkeys = 0; for (ii = jj = 0; ii < 5; ii++) // get optional metadata keys { keyx[3] = '0' + ii; zdialog_fetch(zd,keyx,keys[ii],40); strCompress(keys[ii]); // remove all blanks from key names if (*keys[ii] <= ' ') continue; memmove(keys[jj],keys[ii],40); // repack blank keys matchx[5] = '0' + ii; zdialog_fetch(zd,matchx,match[ii],100); // get corresp. match value if any strTrim2(match[jj],match[ii]); // trim leading and trailing blanks if (ii > jj) *keys[ii] = *match[ii] = 0; jj++; } Nkeys = jj; // keys found, no blanks zdialog_free(zd); // cancel dialog cc = MAXIMAGES * sizeof(xrec_t); // allocate memory for index recs. xrec_t *xrec = (xrec_t *) zmalloc(cc,"search_metadata"); memset(xrec,0,cc); Nxrec = 0; fid = fopen(search_index_file,"r"); if (! fid) goto noindexfile; *indexbuff = 0; while (true) // read index file { if (! strnEqu(indexbuff,"file: ",6)) { // skip to next "file" record pp = fgets_trim(indexbuff,tagrecl,fid); if (! pp) break; // EOF continue; } *indexbuff = 0; // prevent looping file = indexbuff + 6; err=stat(file,&statbuf); // check file exists if (err) continue; iix = Nxrec; memset(&xrec[iix],0,sizeof(xrec)); xrec[iix].file = strdupz(file,0,"search_metadata"); // setup new xrec member xrec[iix].stars = '0'; while (true) { pp = fgets_trim(indexbuff,tagrecl,fid); // get recs following "file" if (! pp) break; if (strnEqu(pp,"date: ",6)) { pp = strField(pp,' ',2); if (pp) strncpy0(xrec[iix].date,pp,12); } else if (strnEqu(pp,"tags: ",6)) xrec[iix].tags = strdupz(pp+6,0,"search_metadata"); else if (strnEqu(pp,"stars: ",7)) xrec[iix].stars = *(pp+7); else if (strnEqu(pp,"comms: ",7)) xrec[iix].comms = strdupz(pp+7,0,"search_metadata"); else if (strnEqu(pp,"capt: ",6)) xrec[iix].capt = strdupz(pp+6,0,"search_metadata"); else break; } if (++Nxrec == MAXIMAGES) goto toomanyfiles; } fclose(fid); if (! Nxrec) goto noindexfile; if (Nxrec > 1) // sort index records HeapSort((char *) xrec, sizeof(xrec_t), Nxrec, metadata_xrec_compare); if (! mdlist) { cc = nfiles * sizeof(char *); // allocate metadata list mdlist = (char **) zmalloc(cc,"search_metadata"); memset(mdlist,0,cc); } Ncache = 0; // cache empty pcache = 0; if (gallerytype == 3) gallerytype = 2; // make gallery deletes work for (iif = 0; iif < nfiles; iif++) // loop image gallery files { if (mdlist[iif]) zfree(mdlist[iif]); // clear prior metadata mdlist[iif] = 0; file = image_gallery(0,"find",iif); // file gone? if (! file) continue; if (image_file_type(file) != 2) { // remove directory from gallery list nth = image_gallery_position(file,iif); image_gallery(0,"delete",nth); zfree(file); iif--; continue; } iix = metadata_xrec_search(file,xrec,Nxrec); // get corresp. index record if (iix >= 0) // get metadata from index rec. { cc = 2 * tagrecl; snprintf(mdtext1, cc," date: %s stars: %c\n caption: %s\n comments: %s\n tags: %s", xrec[iix].date, xrec[iix].stars, xrec[iix].capt, xrec[iix].comms, xrec[iix].tags); } else *mdtext1 = 0; // none avail. if (Nkeys) // optional metadata requested { if (! Ncache) // cache is empty { for (jj = iif; Ncache < 50 && jj < nfiles; jj++) { file2 = image_gallery(0,"find",jj); if (! file2) continue; if (image_file_type(file2) == 2) { // put next 50 files into cache Fcache[Ncache] = file2; Ncache++; } else zfree(file2); } if (Ncache) { if (ppcache) zfree(ppcache); // get metadata for cached files ppcache = info_getN(Fcache,Ncache,(cchar**) keys,Nkeys); } pcache = 0; // first cache position } file2 = (char *) Fcache[pcache]; // next cached file kvals = ppcache + Nkeys * pcache; // key values for cached file if (Ncache && strEqu(file,file2)) { // cached metadata is for this file Fmeta = 1; Ncache--; // index cache to next pcache++; } else Fmeta = 0; // no metadata for this file for (jj = 0; jj < Nkeys; jj++) { // check key values for match if (*match[jj] > ' ') { // match value(s) are present if (! Fmeta) break; // metadata not available if (! kvals[jj]) break; // key not present in metadata for (nth = 1; ; nth++) { pp = strField(match[jj],' ',nth); // get each match value if (! pp) break; // no more, no match found if (strcasestr(kvals[jj],pp)) break; // found match } if (! pp) break; // no match found } } if (jj < Nkeys) { // at least one match fail nth = image_gallery_position(file,iif); // remove file from gallery list image_gallery(0,"delete",nth); iif--; zfree(file2); // free memory for (jj = 0; jj < Nkeys; jj++) if (kvals[jj]) zfree(kvals[jj]); continue; // skip this file } else { // all metadata matched for (jj = 0; jj < 5; jj++) mdtext2[jj][0] = 0; for (jj = 0; jj < Nkeys; jj++) // add metadata to report snprintf(mdtext2[jj], 200, "\n key: %s value: %s", keys[jj], kvals[jj]); strncatv(mdtext1, cc, mdtext2[0], mdtext2[1], mdtext2[2], mdtext2[3], mdtext2[4], null); zfree(file2); // free memory for (jj = 0; jj < Nkeys; jj++) if (kvals[jj]) zfree(kvals[jj]); } // keep this file } mdlist[iif] = strdupz(mdtext1,0,"metadata report"); // attach metadata for gallery paint zfree(file); } if (galleryname) zfree(galleryname); galleryname = strdupz("metadata report"); gallerytype = 3; // outlaw gallery adds/deletes image_gallery(0,"paint1"); // show new image gallery window goto freememory; noindexfile: zmessageACK(mWin,ZTX("No search index file present")); goto freememory; toomanyfiles: zmessLogACK(mWin,"too many image files"); goto freememory; freememory: if (ppcache) zfree(ppcache); for (iix = 0; iix < Nxrec; iix++) { // free allocated memory if (xrec[iix].file) zfree(xrec[iix].file); if (xrec[iix].tags) zfree(xrec[iix].tags); if (xrec[iix].comms) zfree(xrec[iix].comms); if (xrec[iix].capt) zfree(xrec[iix].capt); } zfree(xrec); return 0; } // sort compare function - compare xrec files and return // returns <0 0 >0 for file1 < = > file2 int metadata_xrec_compare(cchar *rec1, cchar *rec2) { char * file1 = ((xrec_t *) rec1)->file; char * file2 = ((xrec_t *) rec2)->file; return strcmp(file1,file2); } // perform a binary search for a file within sorted xrecs in memory // return matching record number (0 based) or -1 if not found // execution time < 1 microsec. int metadata_xrec_search(char *file, xrec_t *xrecs, int nrecs) { int ii, jj, kk, rkk; ii = nrecs / 2; // next element to search jj = (ii + 1) / 2; // next increment nrecs--; // last element rkk = 0; while (true) { kk = strcmp(xrecs[ii].file,file); // compare member rec to seek rec if (kk > 0) { ii -= jj; // too high, go down in set if (ii < 0) return -1; } else if (kk < 0) { ii += jj; // too low, go up in set if (ii > nrecs) return -1; } else if (kk == 0) return ii; // matched jj = jj / 2; // reduce increment if (jj == 0) { jj = 1; // step by 1 element if (! rkk) rkk = kk; // save direction else { if (rkk > 0) { if (kk < 0) return -1; } // if change direction, fail else if (kk > 0) return -1; } } } } fotoxx-12.01.2/f.transform.cc0000644000175000017500000044236511701011017014415 0ustar micomico/************************************************************************** Fotoxx edit photos and manage collections Copyright 2007 2008 2009 2010 2011 2012 Michael Cornelison Source URL: http://kornelix.squarespace.com/fotoxx Contact: kornelix2@googlemail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. ***************************************************************************/ #define EX extern // enable extern declarations #include "fotoxx.h" /************************************************************************** Fotoxx image edit - transform functions ***************************************************************************/ // rotate image through any arbitrary angle double rotate_angle = 0; // E3 rotatation vs. F double rotate_delta = 0; int rotate_trim = 0; editfunc EFrotate; void m_rotate(GtkWidget *, cchar *menu) // menu function { int rotate_dialog_event(zdialog *zd, cchar *event); void * rotate_thread(void *); void rotate_mousefunc(); cchar *rotmess = ZTX("Use buttons or drag right edge with mouse"); zfuncs::F1_help_topic = "rotate"; // v.10.8 EFrotate.funcname = "rotate"; EFrotate.Fprev = 1; // use preview EFrotate.threadfunc = rotate_thread; // thread function EFrotate.mousefunc = rotate_mousefunc; // mouse function if (! edit_setup(EFrotate)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Rotate Image"),mWin,Bdone,Bcancel,null); EFrotate.zd = zd; zdialog_add_widget(zd,"label","labrot","dialog",ZTX(rotmess),"space=5"); zdialog_add_widget(zd,"label","labdeg","dialog",ZTX("degrees"),"space=5"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"space=5"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"space=5"); zdialog_add_widget(zd,"vbox","vb3","hb1",0,"space=5"); zdialog_add_widget(zd,"vbox","vb4","hb1",0,"space=5"); zdialog_add_widget(zd,"button"," +0.1 ","vb1"," + 0.1 "); // button name is increment to use zdialog_add_widget(zd,"button"," -0.1 ","vb1"," - 0.1 "); zdialog_add_widget(zd,"button"," +1.0 ","vb2"," + 1 "); zdialog_add_widget(zd,"button"," -1.0 ","vb2"," - 1 "); zdialog_add_widget(zd,"button"," +10.0 ","vb3"," + 10 "); zdialog_add_widget(zd,"button"," -10.0 ","vb3"," - 10 "); zdialog_add_widget(zd,"button"," +90.0 ","vb4"," + 90 "); zdialog_add_widget(zd,"button"," -90.0 ","vb4"," - 90 "); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=10"); zdialog_add_widget(zd,"label","space","hb2",0,"expand"); zdialog_add_widget(zd,"button","trim","hb2",ZTX("Trim"),"space=10"); zdialog_add_widget(zd,"button","grid","hb2",ZTX("Grid"),"space=10"); zdialog_help(zd,"rotate"); // zdialog help topic v.11.08 zdialog_run(zd,rotate_dialog_event,"save"); // run dialog, parallel v.11.07 takeMouse(zd,rotate_mousefunc,dragcursor); // connect mouse function v.11.03 rotate_angle = rotate_delta = rotate_trim = 0; load_grid(rotate_grid); // load grid preferences v.11.11 return; } // dialog event and completion callback function int rotate_dialog_event(zdialog *zd, cchar * event) { int err, trim = 0; double incr; char text[40]; if (zd->zstat) // dialog complete { if (zd->zstat == 1) { rotate_delta = rotate_angle; // rotate main image rotate_angle = 0; edit_done(EFrotate); } else edit_cancel(EFrotate); // canceled rotate_angle = rotate_delta = rotate_trim = 0; save_grid(rotate_grid); // save grid preferences v.11.11 Fgrid = 0; // grid off mwpaint2(); return 0; } if (strEqu(event,"trim")) { rotate_trim = 1 - rotate_trim; // toggle trim button if (rotate_trim) zdialog_stuff(zd,"trim",ZTX("Undo Trim")); else zdialog_stuff(zd,"trim",ZTX("Trim")); trim = 1; // v.10.3 } if (strpbrk(event,"+-")) { err = convSD(event,incr); // button name is increment to use if (err) return 0; rotate_delta += incr; } if (rotate_delta || trim) { trim = 0; zdialog_stuff(zd,"labdeg","computing"); signal_thread(); // do rotate in thread wait_thread_idle(); snprintf(text,40,ZTX("degrees: %.1f"),rotate_angle); // update dialog angle display v.11.08 zdialog_stuff(zd,"labdeg",text); } if (strEqu(event,"grid")) m_gridlines(0,0); // grid dialog v.11.11 if (strstr("KB G KB g",event)) // G key, toggle grid v.11.11 toggle_grid(2); return 1; } // rotate mouse function - drag right edge of image up/down for rotation void rotate_mousefunc() { static int mpx0 = 0, mpy0 = 0; static int mpy1, mpy2, dist; zdialog *zd = EFrotate.zd; if (! Mxdrag && ! Mydrag) return; // no drag underway if (Mxdrag < 0.8 * E3ww) return; // not right edge of image if (Mxdown != mpx0 || Mydown != mpy0) { mpx0 = Mxdown; // new drag started mpy0 = mpy1 = Mydown; } mpy2 = Mydrag; dist = mpy2 - mpy1; // drag distance mpy1 = mpy2; // reset origin for next time if (! dist) return; rotate_delta = 30.0 * dist / E3ww; // convert to angle rotate_dialog_event(zd,"mouse"); return; } // rotate thread function void * rotate_thread(void *) { int px3, py3, px9, py9; int wwcut, hhcut, ww, hh; double trim_angle, radians; uint16 *pix3, *pix9; while (true) { thread_idle_loop(); // wait for work or exit request mutex_lock(&Fpixmap_lock); rotate_angle += rotate_delta; // accum. net rotation rotate_delta = 0; // from dialog widget if (rotate_angle >= 360) rotate_angle -=360; if (rotate_angle <= -360) rotate_angle +=360; if (fabs(rotate_angle) < 0.01) rotate_angle = 0; if (! rotate_angle) { PXM_free(E3pxm16); // E1 >> E3 E3pxm16 = PXM_copy(E1pxm16); E3ww = E1ww; E3hh = E1hh; CEF->Fmod = 0; } if (rotate_angle) { PXM_free(E3pxm16); E3pxm16 = PXM_rotate(E1pxm16,rotate_angle); // E3 is rotated E1 E3ww = E3pxm16->ww; E3hh = E3pxm16->hh; CEF->Fmod = 1; } if (rotate_trim) { // auto trim trim_angle = fabs(rotate_angle); while (trim_angle > 45) trim_angle -= 90; radians = fabs(trim_angle / 57.296); wwcut = int(E3pxm16->hh * sin(radians) + 1); // amount to trim hhcut = int(E3pxm16->ww * sin(radians) + 1); ww = E3pxm16->ww - 2 * wwcut; hh = E3pxm16->hh - 2 * hhcut; if (ww > 0 && hh > 0) { E9pxm16 = PXM_make(ww,hh,16); for (py3 = hhcut; py3 < E3hh-hhcut; py3++) // E9 = trimmed E3 for (px3 = wwcut; px3 < E3ww-wwcut; px3++) { px9 = px3 - wwcut; py9 = py3 - hhcut; pix3 = PXMpix(E3pxm16,px3,py3); pix9 = PXMpix(E9pxm16,px9,py9); pix9[0] = pix3[0]; pix9[1] = pix3[1]; pix9[2] = pix3[2]; } PXM_free(E3pxm16); // E3 = E9 E3pxm16 = E9pxm16; E9pxm16 = 0; E3ww = ww; E3hh = hh; } } mutex_unlock(&Fpixmap_lock); mwpaint2(); // update window } return 0; // not executed, stop g++ warning } /**************************************************************************/ // trim image - use mouse to select image region to retain int trimx1, trimy1, trimx2, trimy2; // current trim rectangle int trimpx1, trimpy1, trimpx2, trimpy2; // prior trim rectangle double trimR; // trim ratio, width/height void trim_mousefunc(); // edit trim margins with mouse void trim_dialog(); void trim_trim(int mode); // show trim area, trim image editfunc EFtrim; void m_trim(GtkWidget *, cchar *menu) { zfuncs::F1_help_topic = "trim_image"; // v.10.8 EFtrim.funcname = "trim"; EFtrim.mousefunc = trim_mousefunc; if (! edit_setup(EFtrim)) return; // setup edit if (! trimbuttons[0] || strEqu(trimbuttons[0],"undefined")) { trimbuttons[0] = strdupz("1:1",8); // default trim buttons v.10.10.2 trimbuttons[1] = strdupz("2:1",8); trimbuttons[2] = strdupz("3:2",8); trimbuttons[3] = strdupz("4:3",8); trimbuttons[4] = strdupz("16:9",8); trimbuttons[5] = strdupz(ZTX("gold"),8); trimratios[0] = strdupz("1:1",8); // default trim ratios v.10.10.2 trimratios[1] = strdupz("2:1",8); trimratios[2] = strdupz("3:2",8); trimratios[3] = strdupz("4:3",8); trimratios[4] = strdupz("16:9",8); trimratios[5] = strdupz("1.618:1",8); // fix inverted ratio v.10.10.3 } if (strNeq(menu,"autotrim")) // if not auto-trim v.11.12 { if (trimsize[0] < iww && trimsize[1] < ihh) { // use last trim size if within limits trimx1 = Iorgx + 0.5 * (iww - trimsize[0]); // v.11.12 trimx2 = trimx1 + trimsize[0]; trimy1 = Iorgy + 0.5 * (ihh - trimsize[1]); trimy2 = trimy1 + trimsize[1]; } else { // else use 90% current dimensions trimx1 = Iorgx + 0.05 * iww; trimx2 = Iorgx + 0.95 * iww; trimy1 = Iorgy + 0.05 * ihh; trimy2 = Iorgy + 0.95 * ihh; } } trimpx1 = Iorgx; // prior trim rectangle trimpx2 = Iorgx + iww; // = 100% of image trimpy1 = Iorgy; trimpy2 = Iorgy + ihh; trimsize[0] = (trimx2 - trimx1); trimsize[1] = (trimy2 - trimy1); trimR = 1.0 * trimsize[0] / trimsize[1]; trim_trim(0); // show trim area in image trim_dialog(); // start dialog return; } // dialog function is called from two places void trim_dialog() { int trim_dialog_event(zdialog *zd, cchar *event); cchar *trim_message = ZTX("Drag middle to move, drag corners to resize."); char text[20]; int ii; /** Drag middle to move, drag corners to resize width [___] height [___] ratio [___] // width/height inputs v.11.05 [1:1] [2:1] [3:2] [4:3] [16:9] [gold] [invert] [x] Lock Ratio [customize] [Done] [Cancel] **/ zdialog *zd = zdialog_new(ZTX("Trim Image"),mWin,ZTX("customize"),Bdone,Bcancel,null); EFtrim.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",trim_message,"space=8"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=4"); zdialog_add_widget(zd,"label","labW","hb1",ZTX("width"),"space=3"); zdialog_add_widget(zd,"spin","width","hb1","20|9999|1|1000"); zdialog_add_widget(zd,"label","space","hb1",0,"space=5"); zdialog_add_widget(zd,"label","labH","hb1",ZTX("height"),"space=3"); zdialog_add_widget(zd,"spin","height","hb1","20|9999|1|600"); zdialog_add_widget(zd,"label","space","hb1",0,"space=5"); zdialog_add_widget(zd,"label","labR","hb1",ZTX("ratio"),"space=3"); zdialog_add_widget(zd,"label","ratio","hb1","1.67 "); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=4"); // ratio buttons zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=4"); zdialog_add_widget(zd,"check","lock","hb3",ZTX("Lock Ratio"),"space=3"); for (ii = 0; ii < 6; ii++) // 6 custom buttons v.10.10.2 zdialog_add_widget(zd,"button",trimbuttons[ii],"hb2",trimbuttons[ii]); zdialog_add_widget(zd,"button","invert","hb2",ZTX("invert")); // [invert] button zdialog_stuff(zd,"width",trimsize[0]); // stuff width, height, ratio v.11.05 zdialog_stuff(zd,"height",trimsize[1]); sprintf(text,"%.2f ",trimR); zdialog_stuff(zd,"ratio",text); zdialog_help(zd,"trim_image"); // zdialog help topic v.11.08 zdialog_run(zd,trim_dialog_event,"save"); // run dialog - parallel v.11.07 takeMouse(zd,trim_mousefunc,dragcursor); // connect mouse function v.11.12 return; } // dialog event and completion callback function int trim_dialog_event(zdialog *zd, cchar *event) // overhauled v.11.05 { void trim_customize(); static int flip = 0; int width, height, delta; int ii, rlock; double r1, r2, ratio = 0; char text[20]; cchar *pp; if (zd->zstat) // dialog complete { paint_toplines(2); // erase rectangle outline v.11.05 if (zd->zstat == 1) { // customize buttons freeMouse(); // bugfix v.11.12 zdialog_free(zd); // kill trim dialog trim_customize(); // do customize dialog trim_trim(0); // show trim area in image v.11.05 trim_dialog(); // restart trim dialog return 0; } if (zd->zstat != 2) { // cancel edit_cancel(EFtrim); return 0; } trimsize[0] = trimx2 - trimx1; // apply trimsize[1] = trimy2 - trimy1; trim_trim(1); // do trim on image Fzoom = 0; // v.11.01 edit_done(EFtrim); return 0; } if (strEqu(event,"focus")) { takeMouse(zd,trim_mousefunc,dragcursor); // connect mouse function v.12.01 return 0; } if (strstr("width height",event)) // get direct width/height inputs { // v.11.05 zdialog_fetch(zd,"width",width); zdialog_fetch(zd,"height",height); zdialog_fetch(zd,"lock",rlock); // lock ratio on/off if (strEqu(event,"width")) { // v.11.05 if (width > iww) width = iww; if (rlock) { // ratio locked height = width / trimR + 0.5; // try to keep ratio if (height > ihh) height = ihh; zdialog_stuff(zd,"height",height); } } if (strEqu(event,"height")) { if (height > ihh) height = ihh; if (rlock) { width = height * trimR + 0.5; if (width > iww) width = iww; zdialog_stuff(zd,"width",width); } } flip = 1 - flip; // alternates 0, 1, 0, 1 ... delta = width - trimsize[0]; if (delta > 0) { // increase width trimx1 = trimx1 - delta / 2; // left and right sides equally trimx2 = trimx2 + delta / 2; if (delta % 2) { // if increase is odd trimx1 = trimx1 - flip; // add 1 alternatively to each side trimx2 = trimx2 + 1 - flip; } } if (delta < 0) { // decrease width trimx1 = trimx1 - delta / 2; trimx2 = trimx2 + delta / 2; if (delta % 2) { trimx1 = trimx1 + flip; trimx2 = trimx2 - 1 + flip; } } delta = height - trimsize[1]; if (delta > 0) { // increase width trimy1 = trimy1 - delta / 2; // left and right sides equally trimy2 = trimy2 + delta / 2; if (delta % 2) { // if increase is odd trimy1 = trimy1 - flip; // add 1 alternatively to each side trimy2 = trimy2 + 1 - flip; } } if (delta < 0) { // decrease width trimy1 = trimy1 - delta / 2; trimy2 = trimy2 + delta / 2; if (delta % 2) { trimy1 = trimy1 + flip; trimy2 = trimy2 - 1 + flip; } } if (trimx1 < Iorgx) trimx1 = Iorgx; if (trimx2 > Iorgx + iww) trimx2 = Iorgx + iww; if (trimy1 < Iorgy) trimy1 = Iorgy; if (trimy2 > Iorgy + ihh) trimy2 = Iorgy + ihh; width = trimx2 - trimx1; // new width and height height = trimy2 - trimy1; zdialog_stuff(zd,"width",width); // update dialog values zdialog_stuff(zd,"height",height); trimsize[0] = width; // new rectangle dimensions trimsize[1] = height; if (! rlock) // set new ratio if not locked trimR = 1.0 * trimsize[0] / trimsize[1]; sprintf(text,"%.2f ",trimR); // stuff new ratio zdialog_stuff(zd,"ratio",text); trim_trim(0); // show trim area in image return 0; } for (ii = 0; ii < 6; ii++) // trim ratio buttons if (strEqu(event,trimbuttons[ii])) break; if (ii < 6) { r1 = r2 = ratio = 0; pp = strField(trimratios[ii],':',1); if (pp) r1 = atof(pp); pp = strField(trimratios[ii],':',2); if (pp) r2 = atof(pp); if (r1 > 0 && r2 > 0) ratio = r1/r2; if (ratio < 0.1 || ratio > 10) ratio = 1.0; if (! ratio) return 0; zdialog_stuff(zd,"lock",1); // assume lock is wanted trimR = ratio; } if (strEqu(event,"invert")) // invert ratio button if (trimR) ratio = 1.0 / trimR; if (ratio) // ratio was changed { trimR = ratio; if (trimx2 - trimx1 > trimy2 - trimy1) trimy2 = trimy1 + (trimx2 - trimx1) / trimR; // adjust smaller dimension else trimx2 = trimx1 + (trimy2 - trimy1) * trimR; if (trimx2 > Iorgx + iww) { // if off the right edge, trimx2 = Iorgx + iww; // adjust height trimy2 = trimy1 + (trimx2 - trimx1) / trimR; } if (trimy2 > Iorgy + ihh) { // if off the bottom edge, trimy2 = Iorgy + ihh; // adjust width trimx2 = trimx1 + (trimy2 - trimy1) * trimR; } trimsize[0] = trimx2 - trimx1; // new rectangle dimensions trimsize[1] = trimy2 - trimy1; zdialog_stuff(zd,"width",trimsize[0]); // stuff width, height, ratio v.11.05 zdialog_stuff(zd,"height",trimsize[1]); sprintf(text,"%.2f ",trimR); zdialog_stuff(zd,"ratio",text); trim_trim(0); // show trim area in image return 0; } return 0; } // trim mouse function void trim_mousefunc() { int mpx, mpy, xdrag, ydrag, rlock; int corner, chop, moveall = 0; int dx, dy, dd, d1, d2, d3, d4; char text[20]; double drr; zdialog *zd = EFtrim.zd; if (LMclick || Mxdrag || Mydrag) // mouse click or drag { if (LMclick) { mpx = Mxclick; // click mpy = Myclick; xdrag = ydrag = 0; LMclick = 0; } else { mpx = Mxdrag; // drag mpy = Mydrag; xdrag = Mxdrag - Mxdown; ydrag = Mydrag - Mydown; Mxdown = Mxdrag; // reset drag origin Mydown = Mydrag; } if (Mxdrag || Mydrag) { moveall = 1; dd = 0.1 * (trimx2 - trimx1); // test if mouse is in the broad if (mpx < trimx1 + dd) moveall = 0; // middle of the rectangle if (mpx > trimx2 - dd) moveall = 0; dd = 0.1 * (trimy2 - trimy1); if (mpy < trimy1 + dd) moveall = 0; if (mpy > trimy2 - dd) moveall = 0; } if (moveall) { // yes, move the whole rectangle trimx1 += xdrag; trimx2 += xdrag; trimy1 += ydrag; trimy2 += ydrag; corner = 0; } else { // no, find closest corner dx = mpx - trimx1; dy = mpy - trimy1; d1 = sqrt(dx*dx + dy*dy); // distance from NW corner dx = mpx - trimx2; dy = mpy - trimy1; d2 = sqrt(dx*dx + dy*dy); dx = mpx - trimx2; dy = mpy - trimy2; d3 = sqrt(dx*dx + dy*dy); dx = mpx - trimx1; dy = mpy - trimy2; d4 = sqrt(dx*dx + dy*dy); corner = 1; // NW dd = d1; if (d2 < dd) { corner = 2; dd = d2; } // NE if (d3 < dd) { corner = 3; dd = d3; } // SE if (d4 < dd) { corner = 4; dd = d4; } // SW if (corner == 1) { trimx1 = mpx; trimy1 = mpy; } // move this corner to mouse if (corner == 2) { trimx2 = mpx; trimy1 = mpy; } if (corner == 3) { trimx2 = mpx; trimy2 = mpy; } if (corner == 4) { trimx1 = mpx; trimy2 = mpy; } } if (trimx1 < Iorgx) trimx1 = Iorgx; // keep within visible area v.11.05 if (trimx2 > Iorgx + iww) trimx2 = Iorgx + iww; if (trimy1 < Iorgy) trimy1 = Iorgy; if (trimy2 > Iorgy + ihh) trimy2 = Iorgy + ihh; if (trimx1 > trimx2-10) trimx1 = trimx2-10; // sanity limits if (trimy1 > trimy2-10) trimy1 = trimy2-10; zdialog_fetch(zd,"lock",rlock); // w/h ratio locked if (rlock && corner) { if (corner < 3) // bugfix v.10.3.1 trimy2 = trimy1 + 1.0 * (trimx2 - trimx1) / trimR; else trimy1 = trimy2 - 1.0 * (trimx2 - trimx1) / trimR; } chop = 0; if (trimx1 < Iorgx) { // look for off the edge v.10.1 trimx1 = Iorgx; chop = 1; } if (trimx2 > Iorgx + iww) { // after corner move v.10.3.1 trimx2 = Iorgx + iww; chop = 2; } if (trimy1 < Iorgy) { trimy1 = Iorgy; chop = 3; } if (trimy2 > Iorgy + ihh) { trimy2 = Iorgy + ihh; chop = 4; } if (rlock && chop) { // keep ratio if off edge v.10.1 if (chop < 3) trimy2 = trimy1 + 1.0 * (trimx2 - trimx1) / trimR; else trimx2 = trimx1 + 1.0 * (trimy2 - trimy1) * trimR; } if (trimx1 > trimx2-10) trimx1 = trimx2-10; // sanity limits if (trimy1 > trimy2-10) trimy1 = trimy2-10; if (trimx1 < Iorgx) trimx1 = Iorgx; // keep within visible area v.11.05 if (trimx2 > Iorgx + iww) trimx2 = Iorgx + iww; if (trimy1 < Iorgy) trimy1 = Iorgy; if (trimy2 > Iorgy + ihh) trimy2 = Iorgy + ihh; trimsize[0] = trimx2 - trimx1; // new rectangle dimensions trimsize[1] = trimy2 - trimy1; drr = 1.0 * trimsize[0] / trimsize[1]; // new w/h ratio if (! rlock) trimR = drr; zdialog_stuff(zd,"width",trimsize[0]); // stuff width, height, ratio v.11.05 zdialog_stuff(zd,"height",trimsize[1]); sprintf(text,"%.2f ",trimR); zdialog_stuff(zd,"ratio",text); trim_trim(0); // show trim area in image } return; } // darken image pixels outside of current trim margins // messy logic: update pixmaps only for changed pixels to increase speed void trim_trim(int mode) { int ox1, oy1, ox2, oy2; // outer trim rectangle int nx1, ny1, nx2, ny2; // inner trim rectangle int px, py, px1, py1, px2, py2; uint16 *pix1, *pix3; if (mode == 1) // do the final trim { mutex_lock(&Fpixmap_lock); PXM_free(E3pxm16); E3pxm16 = PXM_make(trimsize[0],trimsize[1],16); // new pixmap with requested size E3ww = trimsize[0]; E3hh = trimsize[1]; for (py1 = trimy1; py1 < trimy2; py1++) // copy pixels for (px1 = trimx1; px1 < trimx2; px1++) { px2 = px1 - trimx1; py2 = py1 - trimy1; pix1 = PXMpix(E1pxm16,px1,py1); pix3 = PXMpix(E3pxm16,px2,py2); pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } CEF->Fmod = 1; mutex_unlock(&Fpixmap_lock); mwpaint2(); // update window return; } if (trimx1 < Iorgx) trimx1 = Iorgx; // keep within visible area v.11.05 if (trimx2 > Iorgx + iww) trimx2 = Iorgx + iww; if (trimy1 < Iorgy) trimy1 = Iorgy; if (trimy2 > Iorgy + ihh) trimy2 = Iorgy + ihh; if (trimpx1 < trimx1) ox1 = trimpx1; // outer rectangle else ox1 = trimx1; if (trimpx2 > trimx2) ox2 = trimpx2; else ox2 = trimx2; if (trimpy1 < trimy1) oy1 = trimpy1; else oy1 = trimy1; if (trimpy2 > trimy2) oy2 = trimpy2; else oy2 = trimy2; if (trimpx1 > trimx1) nx1 = trimpx1; // inner rectangle else nx1 = trimx1; if (trimpx2 < trimx2) nx2 = trimpx2; else nx2 = trimx2; if (trimpy1 > trimy1) ny1 = trimpy1; else ny1 = trimy1; if (trimpy2 < trimy2) ny2 = trimpy2; else ny2 = trimy2; trimpx1 = trimx1; // set prior trim rectangle trimpx2 = trimx2; // from current trim rectangle trimpy1 = trimy1; trimpy2 = trimy2; if (ox1 > 0) ox1--; if (ox2 < E3ww-1) ox2++; if (oy1 > 0) oy1--; if (oy2 < E3hh-1) oy2++; for (py = oy1; py < ny1; py++) // top band of pixels for (px = ox1; px < ox2; px++) { pix1 = PXMpix(E1pxm16,px,py); pix3 = PXMpix(E3pxm16,px,py); if (px < trimx1 || px > trimx2 || py < trimy1 || py > trimy2) { pix3[0] = pix1[0] / 2; // outside trim margins pix3[1] = pix1[1] / 2; // 50% brightness pix3[2] = pix1[2] / 2; } else { pix3[0] = pix1[0]; // inside trim margins pix3[1] = pix1[1]; // 100% brightness pix3[2] = pix1[2]; } } for (py = oy1; py < oy2; py++) // right band for (px = nx2; px < ox2; px++) { pix1 = PXMpix(E1pxm16,px,py); pix3 = PXMpix(E3pxm16,px,py); if (px < trimx1 || px > trimx2 || py < trimy1 || py > trimy2) { pix3[0] = pix1[0] / 2; pix3[1] = pix1[1] / 2; pix3[2] = pix1[2] / 2; } else { pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } for (py = ny2; py < oy2; py++) // bottom band for (px = ox1; px < ox2; px++) { pix1 = PXMpix(E1pxm16,px,py); pix3 = PXMpix(E3pxm16,px,py); if (px < trimx1 || px > trimx2 || py < trimy1 || py > trimy2) { pix3[0] = pix1[0] / 2; pix3[1] = pix1[1] / 2; pix3[2] = pix1[2] / 2; } else { pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } for (py = oy1; py < oy2; py++) // left band for (px = ox1; px < nx1; px++) { pix1 = PXMpix(E1pxm16,px,py); pix3 = PXMpix(E3pxm16,px,py); if (px < trimx1 || px > trimx2 || py < trimy1 || py > trimy2) { pix3[0] = pix1[0] / 2; pix3[1] = pix1[1] / 2; pix3[2] = pix1[2] / 2; } else { pix3[0] = pix1[0]; pix3[1] = pix1[1]; pix3[2] = pix1[2]; } } mwpaint3(ox1,oy1,ox2-ox1+1,ny1-oy1+1); // 4 updated rectangles mwpaint3(nx2,oy1,ox2-nx2+1,oy2-oy1+1); // ww+1, hh+1 v.11.05 mwpaint3(ox1,ny2,ox2-ox1+1,oy2-ny2+1); mwpaint3(ox1,oy1,nx1-ox1+1,oy2-oy1+1); Ntoplines = 4; // outline trim rectangle v.11.05 toplinex1[0] = trimx1; topliney1[0] = trimy1; toplinex2[0] = trimx2; topliney2[0] = trimy1; toplinex1[1] = trimx2; topliney1[1] = trimy1; toplinex2[1] = trimx2; topliney2[1] = trimy2; toplinex1[2] = trimx2; topliney1[2] = trimy2; toplinex2[2] = trimx1; topliney2[2] = trimy2; toplinex1[3] = trimx1; topliney1[3] = trimy2; toplinex2[3] = trimx1; topliney2[3] = trimy1; paint_toplines(1); return; } // dialog to get custom trim button names and corresponding ratios void trim_customize() { char text[20], blab[8], rlab[8]; double r1, r2, ratio; cchar *pp; int ii, zstat; zdialog *zd = zdialog_new(ZTX("Trim Buttons"),mWin,Bdone,Bcancel,null); // start dialog zdialog_add_widget(zd,"hbox","hbb","dialog",0,"homog|space=5"); zdialog_add_widget(zd,"hbox","hbr","dialog",0,"homog|space=5"); strcpy(blab,"butt-0"); strcpy(rlab,"ratio-0"); for (ii = 0; ii < 6; ii++) { blab[5] = '0' + ii; rlab[6] = '0' + ii; zdialog_add_widget(zd,"entry",blab,"hbb",trimbuttons[ii],"scc=6"); zdialog_add_widget(zd,"entry",rlab,"hbr",trimratios[ii],"scc=6"); } zdialog_run(zd,0,"mouse"); // run dialog v.11.07 zstat = zdialog_wait(zd); if (zstat == 1) // apply { for (ii = 0; ii < 6; ii++) // get custom button names { blab[5] = '0' + ii; zdialog_fetch(zd,blab,text,12); strTrim2(text); if (! *text) continue; zfree(trimbuttons[ii]); trimbuttons[ii] = strdupz(text,0,"trim"); } for (ii = 0; ii < 6; ii++) // get custom ratios { rlab[6] = '0' + ii; zdialog_fetch(zd,rlab,text,12); strTrim2(text); r1 = r2 = ratio = 0; pp = strField(text,':',1); if (! pp) continue; r1 = atof(pp); pp = strField(text,':',2); if (! pp) continue; r2 = atof(pp); if (r1 > 0 && r2 > 0) ratio = r1/r2; if (ratio < 0.1 || ratio > 10) continue; zfree(trimratios[ii]); trimratios[ii] = strdupz(text,0,"trim"); } } zdialog_free(zd); // kill dialog return; } /**************************************************************************/ // auto-trim image - set trim rectangle to exclude black margins // left over from rotate or warp functions void m_autotrim(GtkWidget *, cchar *) // new v.11.12 { int px1, py1, px3, py3; int qx1, qy1, qx3, qy3; int qx, qy, step1, step2; int area1, area2, Fgrow = 0; uint8 *ppix; if (! Fpxm8) return; px1 = 0.4 * Fww; // select small rectangle in the middle py1 = 0.4 * Fhh; px3 = 0.6 * Fww; py3 = 0.6 * Fhh; step1 = 0.05 * (Fww + Fhh); // start with big search steps step2 = 0.2 * step1; while (true) { while (true) { Fgrow = 0; area1 = (px3 - px1) * (py3 - py1); // area of current selection rectangle area2 = area1; for (qx1 = px1-step1; qx1 <= px1+step1; qx1 += step2) // loop, vary NW and SE corners for (qy1 = py1-step1; qy1 <= py1+step1; qy1 += step2) for (qx3 = px3-step1; qx3 <= px3+step1; qx3 += step2) for (qy3 = py3-step1; qy3 <= py3+step1; qy3 += step2) { if (qx1 < 0) continue; // check image limits if (qy1 < 0) continue; if (qx1 > 0.5 * Fww) continue; if (qy1 > 0.5 * Fhh) continue; if (qx3 > Fww-1) continue; if (qy3 > Fhh-1) continue; if (qx3 < 0.5 * Fww) continue; if (qy3 < 0.5 * Fhh) continue; ppix = (uint8 *) Fpxm8->bmp + (qy1 * Fww + qx1) * 3; // check 4 corners are not if (ppix[0] + ppix[1] + ppix[2] == 0) continue; // in the black margin zones ppix = (uint8 *) Fpxm8->bmp + (qy1 * Fww + qx3) * 3; if (ppix[0] + ppix[1] + ppix[2] == 0) continue; ppix = (uint8 *) Fpxm8->bmp + (qy3 * Fww + qx3) * 3; if (ppix[0] + ppix[1] + ppix[2] == 0) continue; ppix = (uint8 *) Fpxm8->bmp + (qy3 * Fww + qx1) * 3; if (ppix[0] + ppix[1] + ppix[2] == 0) continue; area2 = (qx3 - qx1) * (qy3 - qy1); // look for larger enclosed area if (area2 <= area1) continue; for (qx = qx1; qx < qx3; qx++) { // check 4 sides don't intersect ppix = (uint8 *) Fpxm8->bmp + (qy1 * Fww + qx) * 3; // the black margin zones if (ppix[0] + ppix[1] + ppix[2] == 0) break; ppix = (uint8 *) Fpxm8->bmp + (qy3 * Fww + qx) * 3; if (ppix[0] + ppix[1] + ppix[2] == 0) break; } if (qx < qx3) continue; for (qy = qy1; qy < qy3; qy++) { ppix = (uint8 *) Fpxm8->bmp + (qy * Fww + qx1) * 3; if (ppix[0] + ppix[1] + ppix[2] == 0) break; ppix = (uint8 *) Fpxm8->bmp + (qy * Fww + qx3) * 3; if (ppix[0] + ppix[1] + ppix[2] == 0) break; } if (qy < qy3) continue; Fgrow = 1; // successfully grew the rectangle px1 = qx1; // new bigger rectangle coordinates py1 = qy1; // for the next search iteration px3 = qx3; py3 = qy3; break; } if (! Fgrow) break; } if (step2 == 1) break; // done step1 = 0.6 * step1; // reduce search step size step2 = 0.2 * step1; if (step2 < 1) step2 = 1; } trimx1 = px1; // set parameters for trim function trimx2 = px3; trimy1 = py1; trimy2 = py3; m_trim(0,"autotrim"); // perform regular trim with return; // pre-set margins } /**************************************************************************/ // Resize (rescale) image // // Output pixels are composites of input pixels, e.g. 2/3 size means // that 3x3 input pixels are mapped into 2x2 output pixels, and an // image size of 1000 x 600 becomes 667 x 400. int resize_ww0, resize_hh0; // original size int resize_ww1, resize_hh1; // new size editfunc EFresize; void m_resize(GtkWidget *, cchar *) { int resize_dialog_event(zdialog *zd, cchar *event); void * resize_thread(void *); cchar *lockmess = ZTX("Lock aspect ratio"); zfuncs::F1_help_topic = "resize"; // v.10.8 EFresize.funcname = "resize"; EFresize.threadfunc = resize_thread; // thread function if (! edit_setup(EFresize)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Resize Image"),mWin,Bdone,Bcancel,null); EFresize.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"vbox","vb11","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb12","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb13","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"label","placeholder","vb11",0); // pixels percent zdialog_add_widget(zd,"label","labw","vb11",Bwidth); // width [______] [______] zdialog_add_widget(zd,"label","labh","vb11",Bheight); // height [______] [______] zdialog_add_widget(zd,"label","labpix","vb12","pixels"); // zdialog_add_widget(zd,"spin","wpix","vb12","20|9999|1|20"); // presets [2/3] [1/2] [1/3] [1/4] [Prev] zdialog_add_widget(zd,"spin","hpix","vb12","20|9999|1|20"); // zdialog_add_widget(zd,"label","labpct","vb13",Bpercent); // [_] lock aspect ratio zdialog_add_widget(zd,"spin","wpct","vb13","1|500|0.1|100"); // zdialog_add_widget(zd,"spin","hpct","vb13","1|500|0.1|100"); // [done] [cancel] zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"label","preset","hb2",Bpresets,"space=5"); zdialog_add_widget(zd,"button","b 3/4","hb2","3/4"); zdialog_add_widget(zd,"button","b 2/3","hb2","2/3"); zdialog_add_widget(zd,"button","b 1/2","hb2","1/2"); zdialog_add_widget(zd,"button","b 1/3","hb2","1/3"); zdialog_add_widget(zd,"button","b 1/4","hb2","1/4"); zdialog_add_widget(zd,"button","prev","hb2",ZTX("Prev")); zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=5"); zdialog_add_widget(zd,"check","lock","hb3",lockmess,"space=5"); resize_ww0 = Fpxm16->ww; // original width, height resize_hh0 = Fpxm16->hh; zdialog_stuff(zd,"wpix",resize_ww0); zdialog_stuff(zd,"hpix",resize_hh0); zdialog_stuff(zd,"lock",1); zdialog_help(zd,"resize"); // zdialog help topic v.11.08 zdialog_run(zd,resize_dialog_event,"save"); // run dialog v.11.07 zdialog_wait(zd); // wait for completion return; } // dialog event and completion callback function int resize_dialog_event(zdialog *zd, cchar * event) { int lock; double wpct1, hpct1; if (zd->zstat) // dialog complete { if (zd->zstat != 1) { // user cancel edit_cancel(EFresize); return 0; } editresize[0] = resize_ww1; // remember size used v.10.10 editresize[1] = resize_hh1; Fzoom = 0; // v.11.01 edit_done(EFresize); return 0; } if (strnEqu(event,"KB",2)) return 0; // ignore KB inputs v.11.11 zdialog_fetch(zd,"wpix",resize_ww1); // get all widget values zdialog_fetch(zd,"hpix",resize_hh1); zdialog_fetch(zd,"wpct",wpct1); zdialog_fetch(zd,"hpct",hpct1); zdialog_fetch(zd,"lock",lock); if (strEqu(event,"b 3/4")) { resize_ww1 = (3 * resize_ww0 + 3) / 4; resize_hh1 = (3 * resize_hh0 + 3) / 4; } if (strEqu(event,"b 2/3")) { resize_ww1 = (2 * resize_ww0 + 2) / 3; resize_hh1 = (2 * resize_hh0 + 2) / 3; } if (strEqu(event,"b 1/2")) { resize_ww1 = (resize_ww0 + 1) / 2; resize_hh1 = (resize_hh0 + 1) / 2; } if (strEqu(event,"b 1/3")) { resize_ww1 = (resize_ww0 + 2) / 3; resize_hh1 = (resize_hh0 + 2) / 3; } if (strEqu(event,"b 1/4")) { resize_ww1 = (resize_ww0 + 3) / 4; resize_hh1 = (resize_hh0 + 3) / 4; } if (strEqu(event,"prev")) { // use previous resize values v.10.10 resize_ww1 = editresize[0]; resize_hh1 = editresize[1]; } if (strEqu(event,"wpct")) // width % - set pixel width resize_ww1 = int(wpct1 / 100.0 * resize_ww0 + 0.5); if (strEqu(event,"hpct")) // height % - set pixel height resize_hh1 = int(hpct1 / 100.0 * resize_hh0 + 0.5); if (lock && event[0] == 'w') // preserve width/height ratio resize_hh1 = int(resize_ww1 * (1.0 * resize_hh0 / resize_ww0) + 0.5); if (lock && event[0] == 'h') resize_ww1 = int(resize_hh1 * (1.0 * resize_ww0 / resize_hh0) + 0.5); hpct1 = 100.0 * resize_hh1 / resize_hh0; // set percents to match pixels wpct1 = 100.0 * resize_ww1 / resize_ww0; zdialog_stuff(zd,"wpix",resize_ww1); // index all widget values zdialog_stuff(zd,"hpix",resize_hh1); zdialog_stuff(zd,"wpct",wpct1); zdialog_stuff(zd,"hpct",hpct1); signal_thread(); // do the update, don't wait for idle return 1; } // do the resize job void * resize_thread(void *) // v.10.12 { CEF->Fmod = 0; while (true) { thread_idle_loop(); // wait for signal mutex_lock(&Fpixmap_lock); PXM_free(E3pxm16); E3pxm16 = PXM_rescale(Fpxm16,resize_ww1,resize_hh1); // rescale the edit image E3ww = resize_ww1; E3hh = resize_hh1; CEF->Fmod = 1; mutex_unlock(&Fpixmap_lock); mwpaint2(); } return 0; } /**************************************************************************/ // edit image annotation - write text on the image itself char annotate_file[1000] = ""; // file for annotation data int annotate_mode = 0; // 0/1/2 = 1st write / re-write / erase int annotate_px, annotate_py; // text position on image PXM *annotate_pxm = 0; // buffer for rendered annotation text PXM *annotate_pxm_transp = 0; // buffer for transparency data void annotate_dialog_stuff(zdialog *zd); // stuff dialog widgets from memory data int annotate_dialog_event(zdialog *zd, cchar *event); // dialog event function void annotate_mousefunc(); // mouse event function void annotate_gettext(); // render text into graphic image void annotate_write(); // write text on image void annotate_load(); // load annotation data from file void annotate_save(); // save annotation data to file editfunc EFannotate; void m_annotate(GtkWidget *, cchar *menu) // overhauled v.10.11 { char *pp; cchar *intro = ZTX("Enter text, click/drag on image.\n" "Right click to remove"); zfuncs::F1_help_topic = "annotate"; // user guide topic EFannotate.funcname = "annotate"; EFannotate.Farea = 1; // select area ignored if (! edit_setup(EFannotate)) return; // setup edit if (! annotate_text) annotate_text = strdupz("enter text",0,"annotate"); if (! annotate_font || strEqu(annotate_font,"undefined")) annotate_font = strdupz("FreeMono Bold Italic 44",4,"annotate"); // default font and size else annotate_font = strdupz(annotate_font,4,"annotate"); // add extra space bugfix v.11.02 if (! annotate_color[0] || strEqu(annotate_color[0],"undefined")) { // default colors annotate_color[0] = strdupz("255|0|0",0,"annotate"); // text annotate_color[1] = strdupz("0|0|255",0,"annotate"); // background annotate_color[2] = strdupz("0|255|0",0,"annotate"); // text outline annotate_outline = 6; // outline width } pp = annotate_color[0]; // insure at least 20 bytes annotate_color[0] = strdupz(pp,20,"annotate"); zfree(pp); pp = annotate_color[1]; annotate_color[1] = strdupz(pp,20,"annotate"); zfree(pp); pp = annotate_color[2]; annotate_color[2] = strdupz(pp,20,"annotate"); zfree(pp); // Annotate Image // // Text [__________________________________] // dialog // // [font] size [___|v] angle [___|v] // // text backing outline // v.11.04 // Color [color] [color] [color] // Transparency [___|v] [___|v] [___|v] // Width [___|v] // // Annotation File: [Open] [Save] // // [Done] [Cancel] zdialog *zd = zdialog_new(ZTX("Annotate Image"),mWin,Bdone,Bcancel,null); EFannotate.zd = zd; EFannotate.mousefunc = annotate_mousefunc; zdialog_add_widget(zd,"label","intro","dialog",intro,"space=3"); zdialog_add_widget(zd,"hbox","hbtext","dialog",0,"space=3"); zdialog_add_widget(zd,"label","labtext","hbtext",ZTX("Text"),"space=5"); zdialog_add_widget(zd,"frame","frtext","hbtext",0,"expand"); zdialog_add_widget(zd,"edit","text","frtext",0,"expand"); zdialog_add_widget(zd,"hbox","hbfont","dialog",0,"space=8"); zdialog_add_widget(zd,"button","font","hbfont",Bfont,"space=5"); zdialog_add_widget(zd,"label","space","hbfont","","space=5"); zdialog_add_widget(zd,"label","labsize","hbfont",ZTX("Size"),"space=3"); zdialog_add_widget(zd,"spin","size","hbfont","6|99|1|20","space=3"); zdialog_add_widget(zd,"label","space","hbfont","","space=5"); zdialog_add_widget(zd,"label","labangle","hbfont",ZTX("Angle"),"space=3"); zdialog_add_widget(zd,"spin","angle","hbfont","-180|180|0.2|0","space=3"); zdialog_add_widget(zd,"hsep","hs1","dialog",0,"space=3"); zdialog_add_widget(zd,"hbox","hbcol","dialog",0,"space=3"); zdialog_add_widget(zd,"vbox","vbcol1","hbcol",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vbcol2","hbcol",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vbcol3","hbcol",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vbcol4","hbcol",0,"homog|space=5"); zdialog_add_widget(zd,"label","space","vbcol1"); zdialog_add_widget(zd,"label","labcol","vbcol1",ZTX("Color")); zdialog_add_widget(zd,"label","labcol","vbcol1",ZTX("Transparency")); zdialog_add_widget(zd,"label","space","vbcol1"); zdialog_add_widget(zd,"label","labtext","vbcol2",ZTX("text")); zdialog_add_widget(zd,"colorbutt","fgcolor","vbcol2","0|0|0"); zdialog_add_widget(zd,"spin","fgtrans","vbcol2","0|100|1|0"); zdialog_add_widget(zd,"label","space","vbcol2"); zdialog_add_widget(zd,"label","labback","vbcol3",ZTX("backing")); zdialog_add_widget(zd,"colorbutt","bgcolor","vbcol3","255|255|255"); zdialog_add_widget(zd,"spin","bgtrans","vbcol3","0|100|1|0"); zdialog_add_widget(zd,"label","labw","vbcol3",ZTX("Outline\n Width")); zdialog_add_widget(zd,"label","laboutln","vbcol4",ZTX("outline")); zdialog_add_widget(zd,"colorbutt","tocolor","vbcol4","255|0|0"); zdialog_add_widget(zd,"spin","totrans","vbcol4","0|100|1|0"); zdialog_add_widget(zd,"spin","outline","vbcol4","0|9|1|0"); zdialog_add_widget(zd,"hsep","hs1","dialog",0,"space=3"); zdialog_add_widget(zd,"hbox","hbaf","dialog",0,"space=8"); zdialog_add_widget(zd,"label","labbg","hbaf",ZTX("Annotation File:"),"space=3"); zdialog_add_widget(zd,"button","load","hbaf",Bopen,"space=5"); zdialog_add_widget(zd,"button","save","hbaf",Bsave,"space=5"); annotate_dialog_stuff(zd); // stuff dialog widgets from memory data zdialog_help(zd,"annotate"); // zdialog help topic v.11.08 zdialog_run(zd,annotate_dialog_event,"save"); // run dialog, parallel v.11.07 takeMouse(zd,annotate_mousefunc,dragcursor); // connect mouse function v.10.12 annotate_mode = 0; // no write on image (yet) annotate_px = annotate_py = -1; // no location on image (yet) return; } // stuff all dialog widgets from annotation data in memory void annotate_dialog_stuff(zdialog *zd) { int size; char *pp; zdialog_stuff(zd,"text",annotate_text); zdialog_stuff(zd,"angle",annotate_angle); zdialog_stuff(zd,"fgtrans",annotate_trans[0]); zdialog_stuff(zd,"bgtrans",annotate_trans[1]); zdialog_stuff(zd,"totrans",annotate_trans[2]); zdialog_stuff(zd,"fgcolor",annotate_color[0]); zdialog_stuff(zd,"bgcolor",annotate_color[1]); zdialog_stuff(zd,"tocolor",annotate_color[2]); zdialog_stuff(zd,"outline",annotate_outline); pp = annotate_font + strlen(annotate_font); while (*pp != ' ') pp--; if (pp > annotate_font) { size = atoi(pp); if (size >= 6 && size <= 99) zdialog_stuff(zd,"size",size); } annotate_gettext(); // build text buffer from annotation data return; } // dialog event and completion callback function int annotate_dialog_event(zdialog *zd, cchar *event) { GtkWidget *font_dialog; int size; char *pp, text[1000]; if (zd->zstat) { if (zd->zstat == 1 && CEF->Fmod) edit_done(EFannotate); // Done, complete pending edit else edit_cancel(EFannotate); // Cancel or kill return 0; } if (strEqu(event,"focus")) // toggle mouse capture takeMouse(zd,annotate_mousefunc,dragcursor); // connect mouse function v.12.01 if (strEqu(event,"text")) { zdialog_fetch(zd,"text",text,999); // get text from dialog if (annotate_text) zfree(annotate_text); annotate_text = 0; if (*text) annotate_text = strdupz(text,0,"annotate"); } if (strEqu(event,"font")) { // new font font_dialog = gtk_font_selection_dialog_new(ZTX("select font")); gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(font_dialog),annotate_font); gtk_dialog_run(GTK_DIALOG(font_dialog)); pp = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(font_dialog)); gtk_widget_destroy(GTK_WIDGET(font_dialog)); if (pp) { zfree(annotate_font); annotate_font = strdupz(pp,6,"annotate"); // update font and size g_free(pp); pp = annotate_font + strlen(annotate_font); while (*pp != ' ') pp--; if (pp > annotate_font) { size = atoi(pp); if (size >= 6 && size <= 99) zdialog_stuff(zd,"size",size); } } } if (strEqu(event,"load")) { // load annotate data from file annotate_load(); annotate_dialog_stuff(zd); return 1; } if (strEqu(event,"save")) { // save annotate data to file annotate_save(); return 1; } if (strEqu(event,"size")) { // new font size zdialog_fetch(zd,"size",size); pp = annotate_font + strlen(annotate_font); // "fontname NN" while (*pp != ' ') pp--; // back-up to " NN" if (pp > annotate_font) sprintf(pp," %d",size); // replace NN with new size } if (strEqu(event,"angle")) zdialog_fetch(zd,"angle",annotate_angle); if (strEqu(event,"fgcolor")) // foreground (text) color zdialog_fetch(zd,"fgcolor",annotate_color[0],20); if (strEqu(event,"bgcolor")) // background color zdialog_fetch(zd,"bgcolor",annotate_color[1],20); if (strEqu(event,"tocolor")) // text outline color zdialog_fetch(zd,"tocolor",annotate_color[2],20); if (strEqu(event,"fgtrans")) // foreground transparency zdialog_fetch(zd,"fgtrans",annotate_trans[0]); if (strEqu(event,"bgtrans")) // background transparency zdialog_fetch(zd,"bgtrans",annotate_trans[1]); if (strEqu(event,"totrans")) // text outline transparency zdialog_fetch(zd,"totrans",annotate_trans[2]); if (strEqu(event,"outline")) // text outline width zdialog_fetch(zd,"outline",annotate_outline); annotate_gettext(); // rebuild text buffer annotate_write(); // write on image zmainloop(); return 1; } // mouse function, set position for annotation text on image void annotate_mousefunc() { static int dragging = 0; if (LMclick) { // left mouse click LMclick = 0; annotate_px = Mxclick; // new text position on image annotate_py = Myclick; annotate_write(); // write text on image } if (RMclick) { // right mouse click RMclick = 0; annotate_mode = 2; // erase text on image annotate_write(); annotate_px = annotate_py = -1; // no location on image } if (Mxdrag || Mydrag) // mouse dragged { if (! dragging && annotate_mode) dragging = 1; if (dragging) { annotate_px = Mxdrag; // new text position on image annotate_py = Mydrag; annotate_write(); // write text on image } } else dragging = 0; // no drag underway return; } // write annotation text on image at designated place, if wanted // annotate_mode: 0/1/2 = 1st write / re-write / erase void annotate_write() { uint8 *pix1, *pix2; uint16 *pix3, *pix31, *pix33; int px1, py1, px3, py3; double e3part, f256 = 1.0 / 256.0; static int orgx1 = 0, orgy1 = 0, ww1 = 0, hh1 = 0; // old text image overlap rectangle int orgx2, orgy2, ww2, hh2; // new overlap rectangle if (annotate_mode) // re-write or erase { for (py3 = orgy1; py3 < orgy1 + hh1; py3++) // erase prior text image for (px3 = orgx1; px3 < orgx1 + ww1; px3++) // replace E3 pixels with E1 pixels { // in prior overlap rectangle if (px3 < 0 || px3 >= E3ww) continue; if (py3 < 0 || py3 >= E3hh) continue; pix31 = PXMpix(E1pxm16,px3,py3); pix33 = PXMpix(E3pxm16,px3,py3); pix33[0] = pix31[0]; pix33[1] = pix31[1]; pix33[2] = pix31[2]; } CEF->Fmod = 0; } if (annotate_mode == 2) { // erase only annotate_mode = 0; // next time is a 1st write mwpaint3(orgx1,orgy1,ww1,hh1); // update window return; } if (! annotate_text) { // no text to write annotate_mode = 0; // next time is a 1st write mwpaint3(orgx1,orgy1,ww1,hh1); // update window return; } if (annotate_px < 0 || annotate_py < 0) { // no image position to write annotate_mode = 0; // next time is a 1st write mwpaint3(orgx1,orgy1,ww1,hh1); // update window return; } annotate_mode = 1; // next time is a re-write ww2 = annotate_pxm->ww; // text image buffer hh2 = annotate_pxm->hh; orgx2 = annotate_px - ww2/2; // copy-to image3 location orgy2 = annotate_py - hh2/2; for (py1 = 0; py1 < hh2; py1++) // loop all pixels in text image for (px1 = 0; px1 < ww2; px1++) { px3 = orgx2 + px1; // copy-to image3 pixel py3 = orgy2 + py1; if (px3 < 0 || px3 >= E3ww) continue; // omit parts beyond edges if (py3 < 0 || py3 >= E3hh) continue; pix1 = PXMpix8(annotate_pxm,px1,py1); // copy-from text pixel pix2 = PXMpix8(annotate_pxm_transp,px1,py1); // copy-from transparency pix3 = PXMpix(E3pxm16,px3,py3); // copy-to image pixel e3part = pix2[0] * f256; // image part visible through text pix3[0] = (pix1[0] << 8) + e3part * pix3[0]; // combine text part + image part pix3[1] = (pix1[1] << 8) + e3part * pix3[1]; pix3[2] = (pix1[2] << 8) + e3part * pix3[2]; } mwpaint3(orgx1,orgy1,ww1,hh1); // restore prior overlap rectangle mwpaint3(orgx2,orgy2,ww2,hh2); // update new overlap rectangle CEF->Fmod = 1; orgx1 = orgx2; // remember overlap rectangle orgy1 = orgy2; // for next call ww1 = ww2; hh1 = hh2; return; } // Create a graphic image with text, white on black, any font, any angle. void annotate_gettext() // revised v.10.12 { PXM * annotate_addoutline(PXM *); PangoFontDescription *pfont; static GdkColormap *colormap = 0; static GdkColor black, white; PangoLayout *playout; GdkPixmap *pixmap; GdkGC *gdkgc; GdkPixbuf *pixbuf; char *text = annotate_text; double angle = annotate_angle; PXM *pxm_temp1, *pxm_temp2, *pxm_temp3; uint8 *pix1, *pix2, *pix3, *ppix; int px, py, ww, hh, rs, fontsize; char *pp, font[100]; cchar *ppc; int fgred, fggreen, fgblue; int bgred, bggreen, bgblue; int tored, togreen, toblue; int red, green, blue; double fgtrans, bgtrans, totrans, fgpart, bgpart; double f256 = 1.0 / 256.0; if (! annotate_text || ! *annotate_text) return; // no annotation text strncpy0(font,annotate_font,99); pp = font + strlen(font); // save current font size while (*pp != ' ') pp--; fontsize = atoi(pp); if (fontsize < 6 || fontsize > 99) fontsize = 20; strcpy(pp+1,"99"); // use large size for text generation if (! colormap) { colormap = gtk_widget_get_colormap(drWin); black.red = black.green = black.blue = 0; white.red = white.green = white.blue = 0xffff; gdk_rgb_find_color(colormap,&black); gdk_rgb_find_color(colormap,&white); } pfont = pango_font_description_from_string(font); // make layout with text playout = gtk_widget_create_pango_layout(drWin,null); pango_layout_set_font_description(playout,pfont); pango_layout_set_text(playout,text,-1); pango_layout_get_pixel_size(playout,&ww,&hh); ww += 10; // sometimes it is a little too small hh += 2; pixmap = gdk_pixmap_new(drWin->window,ww,hh,-1); // then make pixmap gdkgc = gdk_gc_new(pixmap); gdk_draw_rectangle(pixmap,gdkgc,1,0,0,ww,hh); gdk_draw_layout_with_colors(pixmap,gdkgc,0,0,playout,&white,&black); pixbuf = gdk_pixbuf_get_from_drawable(null,pixmap,0,0,0,0,0,ww,hh); // then make pixbuf ww = gdk_pixbuf_get_width(pixbuf); // pixbuf dimensions hh = gdk_pixbuf_get_height(pixbuf); rs = gdk_pixbuf_get_rowstride(pixbuf); ppix = gdk_pixbuf_get_pixels(pixbuf); pxm_temp1 = PXM_make(ww,hh,8); for (py = 0; py < hh; py++) // copy pixbuf to PXM for (px = 0; px < ww; px++) { // text color is gray/white pix1 = ppix + rs * py + 3 * px; // can erase all but one color pix2 = PXMpix8(pxm_temp1,px,py); pix2[0] = pix1[0]; pix2[1] = pix2[2] = 0; } g_object_unref(playout); g_object_unref(pixmap); g_object_unref(gdkgc); g_object_unref(pixbuf); pxm_temp2 = annotate_addoutline(pxm_temp1); // add text outline color if any if (pxm_temp2) { PXM_free(pxm_temp1); pxm_temp1 = pxm_temp2; } if (fabs(angle) > 0.1) { // rotate text if wanted pxm_temp2 = PXM_rotate(pxm_temp1,angle); PXM_free(pxm_temp1); pxm_temp1 = pxm_temp2; } fgred = fggreen = fgblue = 0; bgred = bggreen = bgblue = 255; tored = togreen = toblue = 0; ppc = strField(annotate_color[0],'|',1); // get text foreground color if (ppc) fgred = atoi(ppc); // 0 - 255 per RGB color ppc = strField(annotate_color[0],'|',2); if (ppc) fggreen = atoi(ppc); ppc = strField(annotate_color[0],'|',3); if (ppc) fgblue = atoi(ppc); ppc = strField(annotate_color[1],'|',1); // get text background color if (ppc) bgred = atoi(ppc); ppc = strField(annotate_color[1],'|',2); if (ppc) bggreen = atoi(ppc); ppc = strField(annotate_color[1],'|',3); if (ppc) bgblue = atoi(ppc); ppc = strField(annotate_color[2],'|',1); // get text outline color if (ppc) tored = atoi(ppc); ppc = strField(annotate_color[2],'|',2); if (ppc) togreen = atoi(ppc); ppc = strField(annotate_color[2],'|',3); if (ppc) toblue = atoi(ppc); fgtrans = 0.01 * annotate_trans[0]; // get transparencies bgtrans = 0.01 * annotate_trans[1]; // text, background, text outline totrans = 0.01 * annotate_trans[2]; ww = pxm_temp1->ww; // text image input pixmap hh = pxm_temp1->hh; pxm_temp2 = PXM_make(ww,hh,8); // text image output pixmap pxm_temp3 = PXM_make(ww,hh,8); // output transparency map for (py = 0; py < hh; py++) // loop all pixels in text image for (px = 0; px < ww; px++) { pix1 = PXMpix8(pxm_temp1,px,py); // copy-from pixel pix2 = PXMpix8(pxm_temp2,px,py); // copy-to pixel pix3 = PXMpix8(pxm_temp3,px,py); // copy-to transparency fgpart = pix1[0] * f256; // white part = text foreground, 0 - 1 bgpart = 1.0 - fgpart; // rest = text background part, 1 - 0 if (pix1[1]) // use text outline color { fgpart = fgpart * (1.0 - totrans); // reduce for transparencies bgpart = bgpart * (1.0 - bgtrans); red = tored * fgpart + bgred * bgpart; // red part for text outline + background green = togreen * fgpart + bggreen * bgpart; // same for green blue = toblue * fgpart + bgblue * bgpart; // same for blue } else // use text foreground color { fgpart = fgpart * (1.0 - fgtrans); // reduce for transparencies bgpart = bgpart * (1.0 - bgtrans); red = fgred * fgpart + bgred * bgpart; // red part for text + text background green = fggreen * fgpart + bggreen * bgpart; // same for green blue = fgblue * fgpart + bgblue * bgpart; // same for blue } pix2[0] = red; // output total red, green blue pix2[1] = green; pix2[2] = blue; pix3[0] = 255 * (1.0 - fgpart - bgpart); // image part visible through text } ww = ww * fontsize / 99.0 + 0.5; // resize from size 99 font hh = hh * fontsize / 99.0 + 0.5; // to requested font size PXM_free(pxm_temp1); pxm_temp1 = PXM_rescale(pxm_temp2,ww,hh); PXM_free(pxm_temp2); PXM_free(annotate_pxm); annotate_pxm = pxm_temp1; pxm_temp1 = PXM_rescale(pxm_temp3,ww,hh); // resize transparency map PXM_free(pxm_temp3); PXM_free(annotate_pxm_transp); annotate_pxm_transp = pxm_temp1; return; } // add an outline color to the text character edges PXM * annotate_addoutline(PXM *pxm1) // new v.10.12 { PXM *pxm2; int toww, toww2; int ww1, hh1, ww2, hh2; int px1, py1, px2, py2, ii, diff; uint8 *pix1, *pix2; toww = annotate_outline; // text outline color width if (toww == 0) return 0; // zero toww2 = 2 * toww; ww1 = pxm1->ww; // input PXM dimensions hh1 = pxm1->hh; ww2 = ww1 + toww2; // output PXM with added margins hh2 = hh1 + toww2; pxm2 = PXM_make(ww2,hh2,8); memset(pxm2->bmp,0,ww2*hh2*3); // clear output to black for (py1 = 0; py1 < hh1; py1++) // copy input to output, for (px1 = 0; px1 < ww1; px1++) // displaced for margins { pix1 = PXMpix8(pxm1,px1,py1); pix2 = PXMpix8(pxm2,px1+toww,py1+toww); pix2[0] = pix1[0]; pix2[1] = pix1[1]; pix2[2] = pix1[2]; } for (py1 = 0; py1 < hh1; py1++) for (px1 = 0; px1 < ww1-toww-2; px1++) // horizontal forward scan { pix1 = PXMpix8(pxm1,px1,py1); diff = (pix1+6)[0] - pix1[0]; if (diff < 200) continue; px2 = px1 + toww; py2 = py1 + toww; pix2 = PXMpix8(pxm2,px2-toww/2,py2); for (ii = 0; ii < toww + 1; ii++) { pix2[0] = pix1[0]; pix2[1] = 1; pix1 += 3; pix2 += 3; } } for (py1 = 0; py1 < hh1; py1++) for (px1 = ww1-1; px1 > toww+2; px1--) // horizontal reverse scan { pix1 = PXMpix8(pxm1,px1,py1); diff = (pix1-6)[0] - pix1[0]; if (diff < 200) continue; px2 = px1 + toww; py2 = py1 + toww; pix2 = PXMpix8(pxm2,px2+toww/2,py2); for (ii = 0; ii < toww + 1; ii++) { pix2[0] = pix1[0]; pix2[1] = 1; pix1 -= 3; pix2 -= 3; } } for (px1 = 0; px1 < ww1; px1++) for (py1 = 0; py1 < hh1-toww-2; py1++) // vertical forward scan { pix1 = PXMpix8(pxm1,px1,py1); diff = (pix1+6*ww1)[0] - pix1[0]; if (diff < 200) continue; px2 = px1 + toww; py2 = py1 + toww; pix2 = PXMpix8(pxm2,px2,py2-toww/2); for (ii = 0; ii < toww + 1; ii++) { if (pix2[0] < pix1[0]) pix2[0] = pix1[0]; pix2[1] = 1; pix1 += 3*ww1; pix2 += 3*ww2; } } for (px1 = 0; px1 < ww1; px1++) for (py1 = hh1-1; py1 > toww+2; py1--) // vertical reverse scan { pix1 = PXMpix8(pxm1,px1,py1); diff = (pix1-6*ww1)[0] - pix1[0]; if (diff < 200) continue; px2 = px1 + toww; py2 = py1 + toww; pix2 = PXMpix8(pxm2,px2,py2+toww/2); for (ii = 0; ii < toww + 1; ii++) { if (pix2[0] < pix1[0]) pix2[0] = pix1[0]; pix2[1] = 1; pix1 -= 3*ww1; pix2 -= 3*ww2; } } return pxm2; } // load annotation data from a file void annotate_load() // v.10.11 { FILE *fid; int cc, err; char *pp, *file, buff[1200]; cchar *dialogtitle = "load annotation data from a file"; file = zgetfile1(dialogtitle,"open",annotations_dirk); // get input file from user if (! file) return; fid = fopen(file,"r"); // open for read if (! fid) { zmessageACK(mWin,"%s",strerror(errno)); zfree(file); return; } while (true) { pp = fgets_trim(buff,1200,fid,1); if (! pp) break; if (strnEqu(pp,"annotate_text ",15)) { if (annotate_text) zfree(annotate_text); cc = strlen(pp+15) + 100; annotate_text = zmalloc(cc,"annotate"); repl_1str(pp+15,annotate_text,"\\n","\n"); // replace "\n" with real newline char. } if (strnEqu(pp,"annotate_font ",15)) strcpy(annotate_font,pp+15); if (strnEqu(pp,"annotate_angle ",16)) convSD(pp+16,annotate_angle,-180,+180); if (strnEqu(pp,"annotate_fgcolor ",18)) strcpy(annotate_color[0],pp+18); if (strnEqu(pp,"annotate_bgcolor ",18)) strcpy(annotate_color[1],pp+18); if (strnEqu(pp,"annotate_tocolor ",18)) strcpy(annotate_color[2],pp+18); if (strnEqu(pp,"annotate_fgtrans ",18)) convSI(pp+18,annotate_trans[0],0,100); if (strnEqu(pp,"annotate_bgtrans ",18)) convSI(pp+18,annotate_trans[1],0,100); if (strnEqu(pp,"annotate_totrans ",18)) convSI(pp+18,annotate_trans[2],0,100); if (strnEqu(pp,"annotate_outline ",18)) convSI(pp+18,annotate_outline,0,9); } err = fclose(fid); if (err) { zmessageACK(mWin,"%s",strerror(errno)); zfree(file); return; } strcpy(annotate_file,file); // update current file zfree(file); return; } // save annotation data to a file void annotate_save() // v.10.11 { FILE *fid; char *file, text[1100]; cchar *dialogtitle = "save annotation data to a file"; int err; file = zgetfile1(dialogtitle,"save",annotations_dirk); // get output file from user if (! file) return; fid = fopen(file,"w"); // open for write if (! fid) { zmessageACK(mWin,"%s",strerror(errno)); zfree(file); return; } repl_1str(annotate_text,text,"\n","\\n"); // replace newlines with "\n" fprintf(fid,"annotate_text %s \n", text); fprintf(fid,"annotate_font %s \n", annotate_font); fprintf(fid,"annotate_angle %.1f \n", annotate_angle); fprintf(fid,"annotate_fgcolor %s \n", annotate_color[0]); fprintf(fid,"annotate_bgcolor %s \n", annotate_color[1]); fprintf(fid,"annotate_tocolor %s \n", annotate_color[2]); fprintf(fid,"annotate_fgtrans %d \n", annotate_trans[0]); fprintf(fid,"annotate_bgtrans %d \n", annotate_trans[1]); fprintf(fid,"annotate_totrans %d \n", annotate_trans[2]); fprintf(fid,"annotate_outline %d \n", annotate_outline); fprintf(fid,"\n"); err = fclose(fid); if (err) { zmessageACK(mWin,"file I/O error %s",file); zfree(file); return; } strcpy(annotate_file,file); // update current file zfree(file); return; } /**************************************************************************/ // flip an image horizontally or vertically editfunc EFflip; void m_flip(GtkWidget *, cchar *) { int flip_dialog_event(zdialog *zd, cchar *event); zfuncs::F1_help_topic = "flip_image"; // v.10.8 EFflip.funcname = "flip"; if (! edit_setup(EFflip)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Flip Image"),mWin,Bdone,Bcancel,null); EFflip.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"button","horz","hb1",ZTX("horizontal"),"space=5"); zdialog_add_widget(zd,"button","vert","hb1",ZTX("vertical"),"space=5"); zdialog_help(zd,"flip_image"); // zdialog help topic v.11.08 zdialog_run(zd,flip_dialog_event,"save"); // run dialog, parallel v.11.07 return; } // dialog event and completion callback function int flip_dialog_event(zdialog *zd, cchar *event) { int flip_horz(); int flip_vert(); if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFflip); else edit_cancel(EFflip); return 0; } if (strEqu(event,"horz")) flip_horz(); if (strEqu(event,"vert")) flip_vert(); return 0; } int flip_horz() { int px, py; uint16 *pix3, *pix9; edit_zapredo(); // delete redo copy v.10.3 E9pxm16 = PXM_copy(E3pxm16); for (py = 0; py < E3hh; py++) for (px = 0; px < E3ww; px++) { pix3 = PXMpix(E3pxm16,px,py); // image9 = flipped image3 pix9 = PXMpix(E9pxm16,E3ww-1-px,py); pix9[0] = pix3[0]; pix9[1] = pix3[1]; pix9[2] = pix3[2]; } mutex_lock(&Fpixmap_lock); PXM_free(E3pxm16); // image9 >> image3 E3pxm16 = E9pxm16; E9pxm16 = 0; mutex_unlock(&Fpixmap_lock); CEF->Fmod = 1; mwpaint2(); return 0; } int flip_vert() { int px, py; uint16 *pix3, *pix9; edit_zapredo(); // delete redo copy v.10.3 E9pxm16 = PXM_copy(E3pxm16); for (py = 0; py < E3hh; py++) for (px = 0; px < E3ww; px++) { pix3 = PXMpix(E3pxm16,px,py); // image9 = flipped image3 pix9 = PXMpix(E9pxm16,px,E3hh-1-py); pix9[0] = pix3[0]; pix9[1] = pix3[1]; pix9[2] = pix3[2]; } mutex_lock(&Fpixmap_lock); PXM_free(E3pxm16); // image9 >> image3 E3pxm16 = E9pxm16; E9pxm16 = 0; mutex_unlock(&Fpixmap_lock); CEF->Fmod = 1; mwpaint2(); return 0; } /**************************************************************************/ // make a black & white or color negative image editfunc EFnegate; void m_negate(GtkWidget *, cchar *) // v.10.9 { int negate_dialog_event(zdialog *zd, cchar *event); zfuncs::F1_help_topic = "make_negative"; EFnegate.funcname = "negate"; if (! edit_setup(EFnegate)) return; // setup edit: no preview zdialog *zd = zdialog_new(ZTX("Make Negative"),mWin,Bdone,Bcancel,null); EFnegate.zd = zd; zdialog_add_widget(zd,"radio","b&wpos","dialog",ZTX("black/white positive")); zdialog_add_widget(zd,"radio","b&wneg","dialog",ZTX("black/white negative")); zdialog_add_widget(zd,"radio","colpos","dialog",ZTX("color positive")); zdialog_add_widget(zd,"radio","colneg","dialog",ZTX("color negative")); zdialog_stuff(zd,"colpos",1); zdialog_resize(zd,200,0); zdialog_help(zd,"make_negative"); // zdialog help topic v.11.08 zdialog_run(zd,negate_dialog_event,"save"); // run dialog - parallel v.11.07 return; } // dialog event and completion callback function int negate_dialog_event(zdialog *zd, cchar *event) { int mode, px, py; int red, green, blue; uint16 *pix1, *pix3; if (zd->zstat) // dialog complete { if (zd->zstat == 1) edit_done(EFnegate); else edit_cancel(EFnegate); return 0; } if (strEqu(event,"b&wpos")) mode = 1; if (strEqu(event,"b&wneg")) mode = 2; if (strEqu(event,"colpos")) mode = 3; if (strEqu(event,"colneg")) mode = 4; edit_zapredo(); // delete redo copy for (py = 0; py < E3hh; py++) for (px = 0; px < E3ww; px++) { pix1 = PXMpix(E1pxm16,px,py); red = pix1[0]; green = pix1[1]; blue = pix1[2]; if (mode == 1) // black and white positive red = green = blue = (red + green + blue) / 3; else if (mode == 2) // black and white negative red = green = blue = 65535 - (red + green + blue) / 3; if (mode == 3) { /** do nothing **/ } // color positive if (mode == 4) { // color negative red = 65535 - red; green = 65535 - green; blue = 65535 - blue; } pix3 = PXMpix(E3pxm16,px,py); pix3[0] = red; pix3[1] = green; pix3[2] = blue; } CEF->Fmod = 1; mwpaint2(); return 0; } /**************************************************************************/ // unbend an image // straighten curvature added by pano or improve perspective double unbend_lin_horz, unbend_lin_vert; // unbend values from dialog double unbend_cur_horz, unbend_cur_vert; double unbend_x1, unbend_x2, unbend_y1, unbend_y2; // unbend axes scaled 0 to 1 int unbend_hx1, unbend_hy1, unbend_hx2, unbend_hy2; int unbend_vx1, unbend_vy1, unbend_vx2, unbend_vy2; editfunc EFunbend; void m_unbend(GtkWidget *, cchar *) // overhauled v.11.04 { int unbend_dialog_event(zdialog* zd, cchar *event); void * unbend_thread(void *); void unbend_mousefunc(); zfuncs::F1_help_topic = "unbend"; EFunbend.funcname = "unbend"; EFunbend.Fprev = 1; // use preview EFunbend.threadfunc = unbend_thread; // thread function EFunbend.mousefunc = unbend_mousefunc; // mouse function if (! edit_setup(EFunbend)) return; // setup edit /*** ___________________________________ | | | Unbend Image | | | | linear curved | | vertical [__|v] [__|v] | | horizontal [__|v] [__|v] | | | | [grid] | | [done] [cancel] | |___________________________________| ***/ zdialog *zd = zdialog_new(ZTX("Unbend Image"),mWin,Bdone,Bcancel,null); EFunbend.zd = zd; zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=8"); zdialog_add_widget(zd,"vbox","vb1","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb2","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"vbox","vb3","hb1",0,"homog|space=5"); zdialog_add_widget(zd,"label","labspace","vb1",""); zdialog_add_widget(zd,"label","labvert","vb1",ZTX("vertical")); zdialog_add_widget(zd,"label","labhorz","vb1",ZTX("horizontal")); zdialog_add_widget(zd,"label","lablin","vb2",ZTX("linear")); zdialog_add_widget(zd,"spin","splinvert","vb2","-99|99|1|0"); zdialog_add_widget(zd,"spin","splinhorz","vb2","-99|99|1|0"); zdialog_add_widget(zd,"label","labhorz","vb3",ZTX("curved")); zdialog_add_widget(zd,"spin","spcurvert","vb3","-99|99|1|0"); zdialog_add_widget(zd,"spin","spcurhorz","vb3","-99|99|1|0"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=5"); zdialog_add_widget(zd,"button","grid","hb2",ZTX("Grid"),"space=10"); zdialog_help(zd,"unbend"); // zdialog help topic v.11.08 zdialog_run(zd,unbend_dialog_event,"save"); // run dialog, parallel v.11.07 unbend_x1 = unbend_x2 = unbend_y1 = unbend_y2 = 0.5; // initial axes thru image middle unbend_lin_horz = unbend_lin_vert = 0; unbend_cur_horz = unbend_cur_vert = 0; load_grid(unbend_grid); // load grid preferences v.11.11 takeMouse(zd,unbend_mousefunc,dragcursor); // connect mouse function v.11.03 signal_thread(); return; } // dialog event and completion callback function int unbend_dialog_event(zdialog *zd, cchar *event) { if (zd->zstat) // dialog complete { paint_toplines(2); // erase axes-lines save_grid(unbend_grid); // save grid preferences v.11.11 Fgrid = 0; // grid off if (zd->zstat != 1) { edit_cancel(EFunbend); // canceled return 0; } if (unbend_cur_vert || unbend_cur_horz || // image3 modified unbend_lin_vert || unbend_lin_horz) CEF->Fmod = 1; else CEF->Fmod = 0; edit_done(EFunbend); // commit changes to image3 return 1; } if (strstr(event,"splinvert")) { // get new unbend value zdialog_fetch(zd,"splinvert",unbend_lin_vert); signal_thread(); // trigger thread } if (strstr(event,"splinhorz")) { zdialog_fetch(zd,"splinhorz",unbend_lin_horz); signal_thread(); } if (strstr(event,"spcurvert")) { zdialog_fetch(zd,"spcurvert",unbend_cur_vert); signal_thread(); } if (strstr(event,"spcurhorz")) { zdialog_fetch(zd,"spcurhorz",unbend_cur_horz); signal_thread(); } if (strEqu(event,"grid")) m_gridlines(0,0); // grid dialog v.11.11 if (strstr("KB G KB g",event)) // G key, toggle grid v.11.11 toggle_grid(2); return 1; } // unbend mouse function // adjustable axes void unbend_mousefunc() { cchar *close; double dist1, dist2; double mpx = 0, mpy = 0; if (LMclick) { // left mouse click LMclick = 0; mpx = Mxclick; mpy = Myclick; } if (Mxdrag || Mydrag) { // mouse dragged mpx = Mxdrag; mpy = Mydrag; } if (! mpx && ! mpy) return; mpx = 1.0 * mpx / E3ww; // scale mouse position 0 to 1 mpy = 1.0 * mpy / E3hh; if (mpx < 0.2 || mpx > 0.8 ) { // check reasonable position if (mpy < 0.1 || mpy > 0.9) return; } else if (mpy < 0.2 || mpy > 0.8) { if (mpx < 0.1 || mpx > 0.9) return; } else return; close = "?"; // find closest axis end-point dist1 = 2; dist2 = mpx * mpx + (mpy-unbend_y1) * (mpy-unbend_y1); if (dist2 < dist1) { dist1 = dist2; close = "left"; } dist2 = (1-mpx) * (1-mpx) + (mpy-unbend_y2) * (mpy-unbend_y2); if (dist2 < dist1) { dist1 = dist2; close = "right"; } dist2 = (mpx-unbend_x1) * (mpx-unbend_x1) + mpy * mpy; if (dist2 < dist1) { dist1 = dist2; close = "top"; } dist2 = (mpx-unbend_x2) * (mpx-unbend_x2) + (1-mpy) * (1-mpy); if (dist2 < dist1) { dist1 = dist2; close = "bottom"; } if (strEqu(close,"left")) unbend_y1 = mpy; // set new axis end-point if (strEqu(close,"right")) unbend_y2 = mpy; if (strEqu(close,"top")) unbend_x1 = mpx; if (strEqu(close,"bottom")) unbend_x2 = mpx; signal_thread(); // trigger thread return; } // unbend thread function void * unbend_thread(void *arg) { void * unbend_wthread(void *); while (true) { thread_idle_loop(); // wait for work or exit request unbend_hx1 = 0; // scale axes to E3ww/hh unbend_hy1 = unbend_y1 * E3hh; unbend_hx2 = E3ww; unbend_hy2 = unbend_y2 * E3hh; unbend_vx1 = unbend_x1 * E3ww; unbend_vy1 = 0; unbend_vx2 = unbend_x2 * E3ww; unbend_vy2 = E3hh; if (Fpreview) { // omit for final unbend Ntoplines = 2; toplinex1[0] = unbend_hx1; // lines on window topliney1[0] = unbend_hy1; toplinex2[0] = unbend_hx2; topliney2[0] = unbend_hy2; toplinex1[1] = unbend_vx1; topliney1[1] = unbend_vy1; toplinex2[1] = unbend_vx2; topliney2[1] = unbend_vy2; } for (int ii = 0; ii < Nwt; ii++) // start worker threads start_wthread(unbend_wthread,&wtnx[ii]); wait_wthreads(); // wait for completion mwpaint2(); // update window } return 0; // not executed, stop g++ warning } void * unbend_wthread(void *arg) // worker thread function { int index = *((int *) arg); int vstat, px3, py3, cx3, cy3; double dispx, dispy, dispx2, dispy2; double px1, py1, vx1, vx2, hy1, hy2; double curvert, curhorz, linvert, linhorz; uint16 vpix[3], *pix3; curvert = int(unbend_cur_vert * 0.01 * E3hh); // -0.99 to +0.99 curhorz = int(unbend_cur_horz * 0.01 * E3ww); linvert = int(unbend_lin_vert * 0.0013 * E3hh); // -0.13 to +0.13 linhorz = int(unbend_lin_horz * 0.0013 * E3ww); vx1 = unbend_vx1; vx2 = unbend_vx2; hy1 = unbend_hy1; hy2 = unbend_hy2; for (py3 = index; py3 < E3hh; py3 += Nwt) // step through F3 pixels for (px3 = 0; px3 < E3ww; px3++) { cx3 = vx1 + (vx2 - vx1) * py3 / E3hh; // center of unbend cy3 = hy1 + (hy2 - hy1) * px3 / E3ww; dispx = 2.0 * (px3 - cx3) / E3ww; // -1.0 .. 0.0 .. +1.0 (roughly) dispy = 2.0 * (py3 - cy3) / E3hh; // -1.0 .. 0.0 .. +1.0 dispx2 = -cos(0.8 * dispx) + 1; // curved v.11.03 dispy2 = -cos(0.8 * dispy) + 1; // v.11.04 pix3 = PXMpix(E3pxm16,px3,py3); // output pixel px1 = px3; // input pixel = output py1 = py3; px1 += dispx * dispy * linhorz; // move input pixel py1 += dispy * dispx * linvert; px1 += dispx * dispy2 * curhorz; py1 += dispy * dispx2 * curvert; vstat = vpixel(E1pxm16,px1,py1,vpix); if (vstat) { pix3[0] = vpix[0]; // input pixel >> output pixel pix3[1] = vpix[1]; pix3[2] = vpix[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } exit_wthread(); return 0; // not executed, avoid gcc warning } /**************************************************************************/ // Convert a selected tetragon area into a rectangle, converting the // rest of the image to match and keeping straight lines straight. int KST_pixel[4][2]; // last 0-4 pixels clicked int KST_npix; // count of pixels char KST_pixlab[4][4] = { " A ", " B ", " C ", " D " }; editfunc EFkeystone; int KST_dialog_event(zdialog *zd, cchar *event); void KST_mousefunc(void); void KST_warpfunc(void); void m_keystone(GtkWidget *, cchar *) // new v.11.10 { cchar *KST_message = ZTX( " Click the four corners of a tetragon area. Press [apply]. \n" " The image is warped to make the tetragon into a rectangle."); zfuncs::F1_help_topic = "keystone"; EFkeystone.funcname = "keystone"; EFkeystone.Fprev = 0; // no preview EFkeystone.mousefunc = KST_mousefunc; // mouse function if (! edit_setup(EFkeystone)) return; // setup edit KST_npix = 0; // no pixels yet zdialog *zd = zdialog_new(ZTX("Keystone Correction"),mWin,Bapply,Breset,Bdone,null); zdialog_add_widget(zd,"label","lab1","dialog",KST_message,"space=5"); zdialog_help(zd,"keystone"); // zdialog help topic EFkeystone.zd = zd; zdialog_run(zd,KST_dialog_event,"save"); // run dialog, parallel takeMouse(zd,KST_mousefunc,dragcursor); // connect mouse function return; } // dialog completion callback function int KST_dialog_event(zdialog *zd, cchar *event) { int ii, px, py; if (strEqu(event,"focus")) // toggle mouse capture 12.01 takeMouse(zd,KST_mousefunc,dragcursor); if (! zd->zstat) return 1; // wait for completion if (zd->zstat == 1) // apply { erase_toptext(102); // erase points KST_warpfunc(); // do the warp zd->zstat = 0; // keep dialog active } else if (zd->zstat == 2) // reset { edit_reset(); zd->zstat = 0; for (ii = 0; ii < KST_npix; ii++) // show pixel labels on image { px = KST_pixel[ii][0]; py = KST_pixel[ii][1]; add_toptext(102,px,py,KST_pixlab[ii],"Sans 8"); } mwpaint2(); } else if (zd->zstat == 3) // done { erase_toptext(102); // erase points edit_done(EFkeystone); } else { // cancel erase_toptext(102); // erase points edit_cancel(EFkeystone); } return 0; } // mouse function - click on 4 corners of tetragon void KST_mousefunc(void) { int ii, minii, jj, px, py; double dist, distx, disty, mindist; if (LMclick) // left click { LMclick = 0; for (ii = 0; ii < KST_npix; ii++) // check if very near a previous corner { if (abs(KST_pixel[ii][0] - Mxclick) < 0.07 * E3ww && abs(KST_pixel[ii][1] - Myclick) < 0.07 * E3hh) { KST_pixel[ii][0] = Mxclick; // yes, set new corner position KST_pixel[ii][1] = Myclick; goto showcorners; } } if (KST_npix < 4) // if < 4 corners, add a new one { ii = KST_npix; // next corner to fill KST_pixel[ii][0] = Mxclick; // save newest corner position KST_pixel[ii][1] = Myclick; KST_npix++; goto showcorners; } mindist = 99999; // all 4 corners already specified minii = -1; for (ii = 0; ii < 4; ii++) // find closest corner to click position { distx = (Mxclick - KST_pixel[ii][0]); disty = (Myclick - KST_pixel[ii][1]); dist = sqrt(distx*distx + disty*disty); if (dist < mindist) { mindist = dist; minii = ii; } } if (minii >= 0) { // set new corner position ii = minii; KST_pixel[ii][0] = Mxclick; KST_pixel[ii][1] = Myclick; goto showcorners; } } else if (RMclick) // right click { RMclick = 0; mindist = 99999; minii = -1; for (ii = 0; ii < KST_npix; ii++) // find closest corner to click position { distx = (Mxclick - KST_pixel[ii][0]); disty = (Myclick - KST_pixel[ii][1]); dist = sqrt(distx*distx + disty*disty); if (dist < mindist) { mindist = dist; minii = ii; } } if (minii >= 0) { // replace deleted corner with ii = minii; // last corner jj = KST_npix - 1; KST_pixel[ii][0] = KST_pixel[jj][0]; KST_pixel[ii][1] = KST_pixel[jj][1]; --KST_npix; // reduce corner count goto showcorners; } } showcorners: // show corner labels on image erase_toptext(102); for (ii = 0; ii < KST_npix; ii++) { px = KST_pixel[ii][0]; py = KST_pixel[ii][1]; add_toptext(102,px,py,KST_pixlab[ii],"Sans 8"); } mwpaint2(); return; } // keystone warp function - make input tetragon into a rectangle void KST_warpfunc(void) { int ii, jj, tempx, tempy, vstat; double px3, py3, trpx[4], trpy[4]; double sqpx0, sqpy0, sqpx1, sqpy1, sqpx2, sqpy2, sqpx3, sqpy3; double cdx0, cdy0, cdx1, cdy1, cdx2, cdy2, cdx3, cdy3; double px1, py1, dispx, dispy, sqww, sqhh; double f0, f1, f2, f3; uint16 vpix1[3], *pix3; if (KST_npix != 4) { zmessageACK(mWin,ZTX("must have 4 corners")); return; } for (ii = 0; ii < 4; ii++) { // get 4 selected tetragon points trpx[ii] = KST_pixel[ii][0]; trpy[ii] = KST_pixel[ii][1]; } // sort 4 points in clockwise order NW, NE, SE, SW for (ii = 0; ii < 4; ii++) { // sort top to bottom (y order) for (jj = ii; jj < 4; jj++) { if (trpy[jj] < trpy[ii]) { tempx = trpx[ii]; tempy = trpy[ii]; trpx[ii] = trpx[jj]; trpy[ii] = trpy[jj]; trpx[jj] = tempx; trpy[jj] = tempy; } } } if (trpx[1] < trpx[0]) { // sort upper two left, right tempx = trpx[0]; tempy = trpy[0]; trpx[0] = trpx[1]; trpy[0] = trpy[1]; trpx[1] = tempx; trpy[1] = tempy; } if (trpx[2] < trpx[3]) { // sort lower two right, left tempx = trpx[2]; tempy = trpy[2]; trpx[2] = trpx[3]; trpy[2] = trpy[3]; trpx[3] = tempx; trpy[3] = tempy; } if (trpx[0] < trpx[3]) sqpx0 = sqpx3 = trpx[0]; // rectangle enclosing tetragon else sqpx0 = sqpx3 = trpx[3]; if (trpx[1] > trpx[2]) sqpx1 = sqpx2 = trpx[1]; else sqpx1 = sqpx2 = trpx[2]; if (trpy[0] < trpy[1]) sqpy0 = sqpy1 = trpy[0]; else sqpy0 = sqpy1 = trpy[1]; if (trpy[2] > trpy[3]) sqpy2 = sqpy3 = trpy[2]; else sqpy2 = sqpy3 = trpy[3]; /*** sqpx0 = sqpx3 = 0.5 * (trpx[0] + trpx[3]); // rectangle bisecting tetragon sides sqpx1 = sqpx2 = 0.5 * (trpx[1] + trpx[2]); sqpy0 = sqpy1 = 0.5 * (trpy[0] + trpy[1]); sqpy2 = sqpy3 = 0.5 * (trpy[2] + trpy[3]); ***/ cdx0 = sqpx0 - trpx[0]; // displavement of tetragon corner cdy0 = sqpy0 - trpy[0]; // to corresponding rectangle corner cdx1 = sqpx1 - trpx[1]; cdy1 = sqpy1 - trpy[1]; cdx2 = sqpx2 - trpx[2]; cdy2 = sqpy2 - trpy[2]; cdx3 = sqpx3 - trpx[3]; cdy3 = sqpy3 - trpy[3]; sqww = 1.0 / (sqpx1 - sqpx0); // rectangle width and height sqhh = 1.0 / (sqpy3 - sqpy0); for (py3 = 0; py3 < E3hh; py3++) // loop all output pixels for (px3 = 0; px3 < E3ww; px3++) { f0 = (1.0 - (px3 - sqpx0) * sqww) * (1.0 - (py3 - sqpy0) * sqhh); f1 = (px3 - sqpx0) * sqww * (1.0 - (py3 - sqpy0) * sqhh); f2 = (px3 - sqpx0) * sqww * (py3 - sqpy0) * sqhh; f3 = (1.0 - (px3 - sqpx0) * sqww) * (py3 - sqpy0) * sqhh; dispx = cdx0 * f0 + cdx1 * f1 + cdx2 * f2 + cdx3 * f3; dispy = cdy0 * f0 + cdy1 * f1 + cdy2 * f2 + cdy3 * f3; px1 = px3 - dispx; // input virtual pixel for px3/py3 py1 = py3 - dispy; pix3 = PXMpix(E3pxm16,int(px3),int(py3)); // output pixel vstat = vpixel(E1pxm16,px1,py1,vpix1); // output pixel = input virtual pixel if (vstat) { pix3[0] = vpix1[0]; pix3[1] = vpix1[1]; pix3[2] = vpix1[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } CEF->Fmod = 1; // image is modified mwpaint2(); // update window return; } /**************************************************************************/ // warp/distort area - select image area and pull with mouse float *WarpAx, *WarpAy; // memory of all displaced pixels float WarpAmem[4][100]; // undo memory, last 100 warps int NWarpA; // WarpA mem count int WarpA_started; int WarpA_areanumber; editfunc EFwarpA; void WarpA_init(); void WarpA_warpfunc(float wdx, float wdy, float wdw, float wdh, int acc); void WarpA_mousefunc(); void m_warp_area(GtkWidget *, cchar *) { int WarpA_dialog_event(zdialog *zd, cchar *event); cchar *WarpA_message = ZTX( " Select an area to warp using select area function. \n" " Press [start warp] and pull area with mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, select another area or press [done]."); zfuncs::F1_help_topic = "warp_area"; EFwarpA.funcname = "warp-area"; EFwarpA.Farea = 2; // select area usable EFwarpA.mousefunc = WarpA_mousefunc; // mouse function if (! edit_setup(EFwarpA)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Warp Image (area)"),mWin,Bdone,Bcancel,null); EFwarpA.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",WarpA_message,"space=5"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=5"); zdialog_add_widget(zd,"button","start","hb1",ZTX("start warp"),"space=5"); zdialog_add_widget(zd,"button","undolast","hb1",Bundolast,"space=5"); zdialog_add_widget(zd,"button","undoall","hb1",Bundoall,"space=5"); zdialog_help(zd,"warp_area"); // zdialog help topic v.11.08 zdialog_run(zd,WarpA_dialog_event,"save"); // run dialog, parallel v.11.07 WarpAx = (float *) zmalloc(E3ww * E3hh * sizeof(float),"warpA"); // get memory for pixel displacements WarpAy = (float *) zmalloc(E3ww * E3hh * sizeof(float),"warpA"); WarpA_init(); return; } // clear warp data when warp started or re-started after new select area void WarpA_init() // v.11.12 { int px, py, ii; NWarpA = 0; // no warp data WarpA_started = 0; WarpA_areanumber = 0; for (py = 0; py < E3hh; py++) // no pixel displacements for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; WarpAx[ii] = WarpAy[ii] = 0.0; } mwpaint2(); return; } // dialog event and completion callback function int WarpA_dialog_event(zdialog * zd, cchar *event) { int px, py, ii; float wdx, wdy, wdw, wdh; if (zd->zstat) // dialog complete { if (NWarpA) CEF->Fmod = 1; else CEF->Fmod = 0; if (zd->zstat == 1) edit_done(EFwarpA); else edit_cancel(EFwarpA); zfree(WarpAx); // release undo memory zfree(WarpAy); return 0; } if (! Factivearea || sa_mode == 7) // no select area active v.11.12 WarpA_init(); if (WarpA_started && WarpA_areanumber != areanumber) // select area changed v.11.12 WarpA_init(); if (strEqu(event,"start")) // start warp { if (! Factivearea || sa_mode == 7) { // no select area active v.11.01 zmessageACK(mWin,ZTX("no active Select Area")); return 0; } sa_edgecalc(); // calculate area edge distances takeMouse(zd,WarpA_mousefunc,dragcursor); // connect mouse function v.11.03 WarpA_started = 1; WarpA_areanumber = areanumber; } if (strEqu(event,"focus")) // toggle mouse capture v.12.01 takeMouse(zd,WarpA_mousefunc,dragcursor); if (strEqu(event,"undolast")) { if (NWarpA) { // undo most recent warp ii = --NWarpA; wdx = WarpAmem[0][ii]; wdy = WarpAmem[1][ii]; wdw = WarpAmem[2][ii]; wdh = WarpAmem[3][ii]; WarpA_warpfunc(wdx,wdy,-wdw,-wdh,0); // unwarp image WarpA_warpfunc(wdx,wdy,-wdw,-wdh,1); // unwarp memory } } if (strEqu(event,"undoall")) // undo all warps { edit_reset(); // v.10.3 for (py = 0; py < E3hh; py++) // reset pixel displacements for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; WarpAx[ii] = WarpAy[ii] = 0.0; } NWarpA = 0; // erase undo memory mwpaint2(); } return 1; } // warp mouse function void WarpA_mousefunc() { static float wdx, wdy, wdw, wdh; static int ii, warped = 0; if (Mxdrag || Mydrag) // mouse drag underway { wdx = Mxdown; // drag origin, image coordinates wdy = Mydown; wdw = Mxdrag - Mxdown; // drag increment wdh = Mydrag - Mydown; WarpA_warpfunc(wdx,wdy,wdw,wdh,0); // warp image warped = 1; return; } else if (warped) { warped = 0; WarpA_warpfunc(wdx,wdy,wdw,wdh,1); // drag done, add to warp memory if (NWarpA == 100) // if full, throw away oldest { NWarpA = 99; for (ii = 0; ii < NWarpA; ii++) { WarpAmem[0][ii] = WarpAmem[0][ii+1]; WarpAmem[1][ii] = WarpAmem[1][ii+1]; WarpAmem[2][ii] = WarpAmem[2][ii+1]; WarpAmem[3][ii] = WarpAmem[3][ii+1]; } } ii = NWarpA; WarpAmem[0][ii] = wdx; // save warp for undo WarpAmem[1][ii] = wdy; WarpAmem[2][ii] = wdw; WarpAmem[3][ii] = wdh; NWarpA++; } return; } // warp image and accumulate warp memory void WarpA_warpfunc(float wdx, float wdy, float wdw, float wdh, int acc) { int ii, px, py, ww, hh, vstat; double ddx, ddy, dpe, dpm, mag, dispx, dispy; uint16 vpix[3], *pix3; edit_zapredo(); // delete redo copy v.10.3 if (! Factivearea) return; // area erased v.11.06.1 for (py = sa_miny; py < sa_maxy; py++) // loop all pixels in area v.10.11 for (px = sa_minx; px < sa_maxx; px++) { ii = py * Fww + px; dpe = sa_pixmap[ii]; // distance from area edge if (dpe < 1) continue; dpe -= 1; // v.11.12 ddx = (px - wdx); ddy = (py - wdy); dpm = sqrt(ddx*ddx + ddy*ddy); // distance from drag origin mag = (dpe / (dpm + dpe)) * (1.0 - dpm / (dpm + dpe)); // v.11.12 dispx = -wdw * mag; // pixel movement from drag movement dispy = -wdh * mag; if (acc) { // mouse drag done, WarpAx[ii] += dispx; // accumulate warp memory WarpAy[ii] += dispy; continue; } dispx += WarpAx[ii]; // add this warp to prior dispy += WarpAy[ii]; vstat = vpixel(E1pxm16,px+dispx,py+dispy,vpix); // input virtual pixel if (vstat) { pix3 = PXMpix(E3pxm16,px,py); // output pixel pix3[0] = vpix[0]; pix3[1] = vpix[1]; pix3[2] = vpix[2]; } } ww = sa_maxx - sa_minx; // update window v.10.11 hh = sa_maxy - sa_miny; mwpaint3(sa_minx,sa_miny,ww,hh); CEF->Fmod = 1; // v.10.2 return; } /**************************************************************************/ // warp/distort whole image with a curved transform // fix perspective problems (e.g. curved walls, leaning buildings) float *WarpCx, *WarpCy; // memory of all dragged pixels float WarpCmem[4][100]; // undo memory, last 100 drags int NWarpC; // WarpCmem count int WarpCdrag; int WarpCww, WarpChh; editfunc EFwarpC; void WarpC_warpfunc(float wdx, float wdy, float wdw, float wdh, int acc); void WarpC_mousefunc(void); void m_warp_curved(GtkWidget *, cchar *) { int WarpC_dialog_event(zdialog *zd, cchar *event); cchar *WarpC_message = ZTX( " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]."); int px, py, ii; zfuncs::F1_help_topic = "warp_curved"; EFwarpC.funcname = "warp-curved"; EFwarpC.Fprev = 1; // use preview EFwarpC.mousefunc = WarpC_mousefunc; // mouse function if (! edit_setup(EFwarpC)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Warp Image (curved)"),mWin,Bdone,Bcancel,null); EFwarpC.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",WarpC_message,"space=5"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"button","undolast","hb1",Bundolast,"space=5"); zdialog_add_widget(zd,"button","undoall","hb1",Bundoall,"space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=10"); zdialog_add_widget(zd,"button","grid","hb2",ZTX("Grid"),"space=10"); load_grid(warpC_grid); // load grid preferences v.11.11 zdialog_help(zd,"warp_curved"); // zdialog help topic zdialog_run(zd,WarpC_dialog_event,"save"); // run dialog, parallel v.11.07 NWarpC = WarpCdrag = 0; // no drag data WarpCx = (float *) zmalloc(E3ww * E3hh * sizeof(float),"warpC"); // get memory for pixel displacements WarpCy = (float *) zmalloc(E3ww * E3hh * sizeof(float),"warpC"); for (py = 0; py < E3hh; py++) // no pixel displacements for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; WarpCx[ii] = WarpCy[ii] = 0.0; } WarpCww = E3ww; // preview dimensions WarpChh = E3hh; takeMouse(zd,WarpC_mousefunc,dragcursor); // connect mouse function v.11.03 return; } // dialog event and completion callback function int WarpC_dialog_event(zdialog * zd, cchar *event) { int px, py, ii; float wdx, wdy, wdw, wdh; int fpx, fpy, epx, epy, vstat; double scale, dispx, dispy; uint16 vpix[3], *pix3; if (zd->zstat) goto complete; if (strEqu(event,"undolast")) { if (NWarpC == 1) event = "undoall"; else if (NWarpC) { // undo most recent drag ii = --NWarpC; wdx = WarpCmem[0][ii]; wdy = WarpCmem[1][ii]; wdw = WarpCmem[2][ii]; wdh = WarpCmem[3][ii]; WarpC_warpfunc(wdx,wdy,-wdw,-wdh,0); // undrag image WarpC_warpfunc(wdx,wdy,-wdw,-wdh,1); // undrag memory } } if (strEqu(event,"undoall")) // undo all drags { NWarpC = 0; // erase undo memory for (py = 0; py < E3hh; py++) // reset pixel displacements for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; WarpCx[ii] = WarpCy[ii] = 0.0; } edit_reset(); // restore image 1 v.10.3 } if (strEqu(event,"grid")) m_gridlines(0,0); // grid dialog v.11.11 if (strstr("KB G KB g",event)) // G key, toggle grid v.11.11 toggle_grid(2); return 1; complete: save_grid(warpC_grid); // save grid preferences v.11.11 Fgrid = 0; // grid off if (zd->zstat != 1) edit_cancel(EFwarpC); else if (NWarpC == 0) edit_cancel(EFwarpC); else { edit_fullsize(); // get full-size E1/E3 scale = 1.0 * (E3ww + E3hh) / (WarpCww + WarpChh); for (fpy = 0; fpy < E3hh; fpy++) // scale net pixel displacements for (fpx = 0; fpx < E3ww; fpx++) // to full image size { epx = WarpCww * fpx / E3ww; epy = WarpChh * fpy / E3hh; ii = epy * WarpCww + epx; dispx = WarpCx[ii] * scale; dispy = WarpCy[ii] * scale; vstat = vpixel(E1pxm16,fpx+dispx,fpy+dispy,vpix); // input virtual pixel pix3 = PXMpix(E3pxm16,fpx,fpy); // output pixel if (vstat) { pix3[0] = vpix[0]; pix3[1] = vpix[1]; pix3[2] = vpix[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } edit_done(EFwarpC); } zfree(WarpCx); // release memory zfree(WarpCy); return 0; } // WarpC mouse function void WarpC_mousefunc(void) { static float wdx, wdy, wdw, wdh; int ii; if (Mxdrag || Mydrag) // mouse drag underway { wdx = Mxdown; // drag origin, window coordinates wdy = Mydown; wdw = Mxdrag - Mxdown; // drag increment wdh = Mydrag - Mydown; WarpC_warpfunc(wdx,wdy,wdw,wdh,0); // drag image WarpCdrag = 1; return; } else if (WarpCdrag) { WarpCdrag = 0; WarpC_warpfunc(wdx,wdy,wdw,wdh,1); // drag done, add to memory if (NWarpC == 100) // if full, throw away oldest { NWarpC = 99; for (ii = 0; ii < NWarpC; ii++) { WarpCmem[0][ii] = WarpCmem[0][ii+1]; WarpCmem[1][ii] = WarpCmem[1][ii+1]; WarpCmem[2][ii] = WarpCmem[2][ii+1]; WarpCmem[3][ii] = WarpCmem[3][ii+1]; } } ii = NWarpC; WarpCmem[0][ii] = wdx; // save drag for undo WarpCmem[1][ii] = wdy; WarpCmem[2][ii] = wdw; WarpCmem[3][ii] = wdh; NWarpC++; } return; } // warp image and accumulate warp memory // mouse at (mx,my) is moved (mw,mh) pixels void WarpC_warpfunc(float mx, float my, float mw, float mh, int acc) { int ii, px, py, vstat; double mag, dispx, dispy; double d1, d2, d3, d4; uint16 vpix[3], *pix3; edit_zapredo(); // delete redo copy v.10.3 d1 = (mx-0) * (mx-0) + (my-0) * (my-0); // distance, mouse to 4 corners d2 = (E3ww-mx) * (E3ww-mx) + (my-0) * (my-0); d3 = (E3ww-mx) * (E3ww-mx) + (E3hh-my) * (E3hh-my); d4 = (mx-0) * (mx-0) + (E3hh-my) * (E3hh-my); if (d2 > d1) d1 = d2; // d1 = greatest v.10.11 if (d3 > d1) d1 = d3; if (d4 > d1) d1 = d4; for (py = 0; py < E3hh; py++) // process all pixels for (px = 0; px < E3ww; px++) { d2 = (px-mx)*(px-mx) + (py-my)*(py-my); mag = (1.0 - d2 / d1); mag = mag * mag; // faster than pow(mag,16); mag = mag * mag; dispx = -mw * mag; // displacement = drag * mag dispy = -mh * mag; ii = py * E3ww + px; if (acc) { // drag done, accumulate drag sum WarpCx[ii] += dispx; WarpCy[ii] += dispy; continue; } dispx += WarpCx[ii]; // add this drag to prior sum dispy += WarpCy[ii]; vstat = vpixel(E1pxm16,px+dispx,py+dispy,vpix); // input virtual pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel if (vstat) { pix3[0] = vpix[0]; pix3[1] = vpix[1]; pix3[2] = vpix[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } CEF->Fmod = 1; mwpaint2(); // update window return; } /**************************************************************************/ // warp/distort whole image with a linear transform // fix perspective problems (e.g. curved walls, leaning buildings) float *WarpLx, *WarpLy; // memory of all dragged pixels float WarpLmem[4][100]; // undo memory, last 100 drags int NWarpL; // WarpLmem count int WarpLdrag; int WarpLww, WarpLhh; editfunc EFwarpL; void WarpL_warpfunc(float wdx, float wdy, float wdw, float wdh, int acc); void WarpL_mousefunc(void); void m_warp_linear(GtkWidget *, cchar *) // new v.10.11 { int WarpL_dialog_event(zdialog *zd, cchar *event); cchar *WarpL_message = ZTX( " Pull an image position using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]."); int px, py, ii; zfuncs::F1_help_topic = "warp_linear"; EFwarpL.funcname = "warp-linear"; EFwarpL.Fprev = 1; // use preview EFwarpL.mousefunc = WarpL_mousefunc; // mouse function if (! edit_setup(EFwarpL)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Warp Image (linear)"),mWin,Bdone,Bcancel,null); EFwarpL.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",WarpL_message,"space=5"); zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=10"); zdialog_add_widget(zd,"button","undolast","hb1",Bundolast,"space=5"); zdialog_add_widget(zd,"button","undoall","hb1",Bundoall,"space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=10"); zdialog_add_widget(zd,"button","grid","hb2",ZTX("Grid"),"space=10"); load_grid(warpL_grid); // load grid preferences v.11.11 zdialog_help(zd,"warp_linear"); // zdialog help topic v.11.08 zdialog_run(zd,WarpL_dialog_event,"save"); // run dialog, parallel v.11.07 NWarpL = WarpLdrag = 0; // no drag data WarpLx = (float *) zmalloc(E3ww * E3hh * sizeof(float),"warpL"); // get memory for pixel displacements WarpLy = (float *) zmalloc(E3ww * E3hh * sizeof(float),"warpL"); for (py = 0; py < E3hh; py++) // no pixel displacements for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; WarpLx[ii] = WarpLy[ii] = 0.0; } WarpLww = E3ww; // preview dimensions WarpLhh = E3hh; takeMouse(zd,WarpL_mousefunc,dragcursor); // connect mouse function v.11.03 return; } // dialog event and completion callback function int WarpL_dialog_event(zdialog * zd, cchar *event) { int px, py, ii; float wdx, wdy, wdw, wdh; int fpx, fpy, epx, epy, vstat; double scale, dispx, dispy; uint16 vpix[3], *pix3; if (zd->zstat) goto complete; if (strEqu(event,"undolast")) { if (NWarpL == 1) event = "undoall"; else if (NWarpL) { // undo most recent drag ii = --NWarpL; wdx = WarpLmem[0][ii]; wdy = WarpLmem[1][ii]; wdw = WarpLmem[2][ii]; wdh = WarpLmem[3][ii]; WarpL_warpfunc(wdx,wdy,-wdw,-wdh,0); // undrag image WarpL_warpfunc(wdx,wdy,-wdw,-wdh,1); // undrag memory } } if (strEqu(event,"undoall")) // undo all drags { NWarpL = 0; // erase undo memory for (py = 0; py < E3hh; py++) // reset pixel displacements for (px = 0; px < E3ww; px++) { ii = py * E3ww + px; WarpLx[ii] = WarpLy[ii] = 0.0; } edit_reset(); // restore image 1 v.10.3 } if (strEqu(event,"grid")) m_gridlines(0,0); // grid dialog v.11.11 if (strstr("KB G KB g",event)) // G key, toggle grid v.11.11 toggle_grid(2); return 1; complete: save_grid(warpL_grid); // save grid preferences v.11.11 Fgrid = 0; // grid off if (zd->zstat != 1) edit_cancel(EFwarpL); else if (NWarpL == 0) edit_cancel(EFwarpL); else { edit_fullsize(); // get full-size E1/E3 scale = 1.0 * (E3ww + E3hh) / (WarpLww + WarpLhh); for (fpy = 0; fpy < E3hh; fpy++) // scale net pixel displacements for (fpx = 0; fpx < E3ww; fpx++) // to full image size { epx = WarpLww * fpx / E3ww; epy = WarpLhh * fpy / E3hh; ii = epy * WarpLww + epx; dispx = WarpLx[ii] * scale; dispy = WarpLy[ii] * scale; vstat = vpixel(E1pxm16,fpx+dispx,fpy+dispy,vpix); // input virtual pixel pix3 = PXMpix(E3pxm16,fpx,fpy); // output pixel if (vstat) { pix3[0] = vpix[0]; pix3[1] = vpix[1]; pix3[2] = vpix[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } edit_done(EFwarpL); } zfree(WarpLx); // release memory zfree(WarpLy); return 0; } // WarpL mouse function void WarpL_mousefunc(void) { static float wdx, wdy, wdw, wdh; int ii; if (Mxdrag || Mydrag) // mouse drag underway { wdx = Mxdown; // drag origin, window coordinates wdy = Mydown; wdw = Mxdrag - Mxdown; // drag increment wdh = Mydrag - Mydown; WarpL_warpfunc(wdx,wdy,wdw,wdh,0); // drag image WarpLdrag = 1; return; } else if (WarpLdrag) { WarpLdrag = 0; WarpL_warpfunc(wdx,wdy,wdw,wdh,1); // drag done, add to memory if (NWarpL == 100) // if full, throw away oldest { NWarpL = 99; for (ii = 0; ii < NWarpL; ii++) { WarpLmem[0][ii] = WarpLmem[0][ii+1]; WarpLmem[1][ii] = WarpLmem[1][ii+1]; WarpLmem[2][ii] = WarpLmem[2][ii+1]; WarpLmem[3][ii] = WarpLmem[3][ii+1]; } } ii = NWarpL; WarpLmem[0][ii] = wdx; // save drag for undo WarpLmem[1][ii] = wdy; WarpLmem[2][ii] = wdw; WarpLmem[3][ii] = wdh; NWarpL++; } return; } // warp image and accumulate warp memory // mouse at (mx,my) is moved (mw,mh) pixels void WarpL_warpfunc(float mx, float my, float mw, float mh, int acc) { int ii, px, py, vstat; double mag, dispx, dispy; double d1, d2, d3, d4; uint16 vpix[3], *pix3; edit_zapredo(); // delete redo copy v.10.3 d1 = (mx-0) * (mx-0) + (my-0) * (my-0); // distance, mouse to 4 corners d2 = (E3ww-mx) * (E3ww-mx) + (my-0) * (my-0); d3 = (E3ww-mx) * (E3ww-mx) + (E3hh-my) * (E3hh-my); d4 = (mx-0) * (mx-0) + (E3hh-my) * (E3hh-my); if (d2 > d1) d1 = d2; // d1 = greatest v.10.11 if (d3 > d1) d1 = d3; if (d4 > d1) d1 = d4; d1 = sqrt(d1); for (py = 0; py < E3hh; py++) // process all pixels for (px = 0; px < E3ww; px++) { d2 = (px-mx)*(px-mx) + (py-my)*(py-my); d2 = sqrt(d2); mag = (1.0 - d2 / d1); dispx = -mw * mag; // displacement = drag * mag dispy = -mh * mag; ii = py * E3ww + px; if (acc) { // drag done, accumulate drag sum WarpLx[ii] += dispx; WarpLy[ii] += dispy; continue; } dispx += WarpLx[ii]; // add this drag to prior sum dispy += WarpLy[ii]; vstat = vpixel(E1pxm16,px+dispx,py+dispy,vpix); // input virtual pixel pix3 = PXMpix(E3pxm16,px,py); // output pixel if (vstat) { pix3[0] = vpix[0]; pix3[1] = vpix[1]; pix3[2] = vpix[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } CEF->Fmod = 1; mwpaint2(); // update window return; } /**************************************************************************/ // warp/distort whole image using affine transform // (straight lines remain straight) double WarpF_old[3][2]; // 3 original image points double WarpF_new[3][2]; // corresponding warped points double WarpF_coeff[6]; // transform coefficients double WarpF_Icoeff[6]; // inverse transform coefficients int WarpF_ftf; // first time flag editfunc EFwarpF; void WarpF_warpfunc(); // image warp function void WarpF_mousefunc(void); void WarpF_affine(double po[3][2], double pn[3][2], double coeff[6]); // compute affine transform coefficients void WarpF_invert(double coeff[6], double Icoeff[6]); // compute reverse transform coefficients void m_warp_affine(GtkWidget *, cchar *) { int WarpF_dialog_event(zdialog *zd, cchar *event); cchar *WarpF_message = ZTX( " Pull on an image corner using the mouse. \n" " Make multiple mouse pulls until satisfied. \n" " When finished, press [done]."); zfuncs::F1_help_topic = "warp_affine"; EFwarpF.funcname = "warp-affine"; EFwarpF.Fprev = 1; // use preview EFwarpF.mousefunc = WarpF_mousefunc; // mouse function if (! edit_setup(EFwarpF)) return; // setup edit zdialog *zd = zdialog_new(ZTX("Warp Image (affine)"),mWin,Bdone,Bcancel,null); EFwarpF.zd = zd; zdialog_add_widget(zd,"label","lab1","dialog",WarpF_message,"space=5"); zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=10"); zdialog_add_widget(zd,"button","grid","hb2",ZTX("Grid"),"space=10"); load_grid(warpF_grid); // load grid preferences v.11.11 zdialog_help(zd,"warp_affine"); // zdialog help topic v.11.08 zdialog_run(zd,WarpF_dialog_event,"save"); // run dialog, parallel v.11.07 WarpF_ftf = 1; // 1st warp flag takeMouse(zd,WarpF_mousefunc,dragcursor); // connect mouse function v.11.03 return; } // dialog event and completion callback function int WarpF_dialog_event(zdialog *zd, cchar *event) { double scale; int ww, hh; if (strEqu(event,"grid")) m_gridlines(0,0); // grid dialog v.11.11 if (strstr("KB G KB g",event)) // G key, toggle grid v.11.11 toggle_grid(2); if (! zd->zstat) return 1; // wait for completion save_grid(warpF_grid); // save grid preferences v.11.11 Fgrid = 0; // grid off if (zd->zstat != 1 || ! CEF->Fmod) { edit_cancel(EFwarpF); // bugfix v.11.11 return 0; } ww = E3ww; // preview image dimensions hh = E3hh; edit_fullsize(); // get full-size images scale = 1.0 * (E3ww + E3hh) / (ww + hh); // preview to full-size scale factor WarpF_old[0][0] = WarpF_old[0][0] * scale; // re-scale new and old points WarpF_old[0][1] = WarpF_old[0][1] * scale; WarpF_old[1][0] = WarpF_old[1][0] * scale; WarpF_old[1][1] = WarpF_old[1][1] * scale; WarpF_old[2][0] = WarpF_old[2][0] * scale; WarpF_old[2][1] = WarpF_old[2][1] * scale; WarpF_new[0][0] = WarpF_new[0][0] * scale; WarpF_new[0][1] = WarpF_new[0][1] * scale; WarpF_new[1][0] = WarpF_new[1][0] * scale; WarpF_new[1][1] = WarpF_new[1][1] * scale; WarpF_new[2][0] = WarpF_new[2][0] * scale; WarpF_new[2][1] = WarpF_new[2][1] * scale; WarpF_warpfunc(); // warp full-size image edit_done(EFwarpF); return 0; } // WarpF mouse function void WarpF_mousefunc(void) { int mdx1, mdy1, mdx2, mdy2; double x1o, y1o, x2o, y2o, x3o, y3o; double x1n, y1n, x2n, y2n, x3n, y3n; double a, b, c, d, e, f; if (Mxdrag + Mydrag == 0) return; mdx1 = Mxdown; // mouse drag origin mdy1 = Mydown; mdx2 = Mxdrag; // mouse drag position mdy2 = Mydrag; Mxdown = Mxdrag; // reset origin for next time Mydown = Mydrag; x1n = mdx1; // point 1 = drag origin y1n = mdy1; x2n = E3ww - x1n; // point 2 = mirror of point1 y2n = E3hh - y1n; x3n = E3ww * (y2n / E3hh); y3n = E3hh * (1.0 - (x2n / E3ww)); if (WarpF_ftf) // first warp { WarpF_ftf = 0; x1o = x1n; // old = current positions y1o = y1n; x2o = x2n; y2o = y2n; x3o = x3n; y3o = y3n; } else { WarpF_invert(WarpF_coeff,WarpF_Icoeff); // get inverse coefficients a = WarpF_Icoeff[0]; b = WarpF_Icoeff[1]; c = WarpF_Icoeff[2]; d = WarpF_Icoeff[3]; e = WarpF_Icoeff[4]; f = WarpF_Icoeff[5]; x1o = a * x1n + b * y1n + c; // compute old from current positions y1o = d * x1n + e * y1n + f; x2o = a * x2n + b * y2n + c; y2o = d * x2n + e * y2n + f; x3o = a * x3n + b * y3n + c; y3o = d * x3n + e * y3n + f; } WarpF_old[0][0] = x1o; // set up 3 old points and corresponding WarpF_old[0][1] = y1o; // new points for affine translation WarpF_old[1][0] = x2o; WarpF_old[1][1] = y2o; WarpF_old[2][0] = x3o; WarpF_old[2][1] = y3o; x1n = mdx2; // point 1 new position = drag position y1n = mdy2; x2n = E3ww - x1n; // point 2 new = mirror of point1 new y2n = E3hh - y1n; WarpF_new[0][0] = x1n; // 3 new points WarpF_new[0][1] = y1n; WarpF_new[1][0] = x2n; WarpF_new[1][1] = y2n; WarpF_new[2][0] = x3n; WarpF_new[2][1] = y3n; WarpF_warpfunc(); // do the warp return; } // warp image and accumulate warp memory void WarpF_warpfunc() { double a, b, c, d, e, f; int px3, py3, vstat; double px1, py1; uint16 vpix1[3], *pix3; edit_zapredo(); // delete redo copy v.10.3 WarpF_affine(WarpF_old, WarpF_new, WarpF_coeff); // get coefficients for forward transform WarpF_invert(WarpF_coeff, WarpF_Icoeff); // get coefficients for reverse transform a = WarpF_Icoeff[0]; // coefficients to map output pixels b = WarpF_Icoeff[1]; // to corresponding input pixels c = WarpF_Icoeff[2]; d = WarpF_Icoeff[3]; e = WarpF_Icoeff[4]; f = WarpF_Icoeff[5]; for (py3 = 0; py3 < E3hh; py3++) // loop all output pixels for (px3 = 0; px3 < E3ww; px3++) { px1 = a * px3 + b * py3 + c; // corresponding input pixel py1 = d * px3 + e * py3 + f; vstat = vpixel(E1pxm16,px1,py1,vpix1); // input virtual pixel pix3 = PXMpix(E3pxm16,px3,py3); // output pixel if (vstat) { pix3[0] = vpix1[0]; pix3[1] = vpix1[1]; pix3[2] = vpix1[2]; } else pix3[0] = pix3[1] = pix3[2] = 0; } CEF->Fmod = 1; mwpaint2(); // update window return; } /************************************************************************** Compute affine transformation of an image (warp image). Given 3 new (warped) positions for 3 image points, derive the coefficients of the translation function to warp the entire image. Inputs: pold[3][2] (x,y) coordinates for 3 points in original image pnew[3][2] (x,y) coordinates for same points in warped image Output: coeff[6] coefficients of translation function which can be used to convert all image points to their warped positions If coeff[6] = (a, b, c, d, e, f) then the following formula can be used to convert an image point to its warped position: Xnew = a * Xold + b * Yold + c Ynew = d * Xold + e * Yold + f ***************************************************************************/ void WarpF_affine(double pold[3][2], double pnew[3][2], double coeff[6]) { double x11, y11, x12, y12, x13, y13; // original points double x21, y21, x22, y22, x23, y23; // moved points double a, b, c, d, e, f; // coefficients double A1, A2, B1, B2, C1, C2; x11 = pold[0][0]; y11 = pold[0][1]; x12 = pold[1][0]; y12 = pold[1][1]; x13 = pold[2][0]; y13 = pold[2][1]; x21 = pnew[0][0]; y21 = pnew[0][1]; x22 = pnew[1][0]; y22 = pnew[1][1]; x23 = pnew[2][0]; y23 = pnew[2][1]; A1 = x11 - x12; A2 = x12 - x13; B1 = y11 - y12; B2 = y12 - y13; C1 = x21 - x22; C2 = x22 - x23; a = (B1 * C2 - B2 * C1) / (A2 * B1 - A1 * B2); b = (A1 * C2 - A2 * C1) / (A1 * B2 - A2 * B1); c = x23 - a * x13 - b * y13; C1 = y21 - y22; C2 = y22 - y23; d = (B1 * C2 - B2 * C1) / (A2 * B1 - A1 * B2); e = (A1 * C2 - A2 * C1) / (A1 * B2 - A2 * B1); f = y23 - d * x13 - e * y13; coeff[0] = a; coeff[1] = b; coeff[2] = c; coeff[3] = d; coeff[4] = e; coeff[5] = f; return; } /************************************************************************** Invert affine transform Input: coeff[6] coefficients of translation function to convert image points to their warped positions Output: Icoeff[6] coefficients of translation function to convert warped image points to their original positions If Icoeff[6] = (a, b, c, d, e, f) then the following formula can be used to translate a warped image point to its original position: Xold = a * Xnew + b * Ynew + c Yold = d * Xnew + e * Ynew + f ***************************************************************************/ void WarpF_invert(double coeff[6], double Icoeff[6]) { double a, b, c, d, e, f, Z; a = coeff[0]; b = coeff[1]; c = coeff[2]; d = coeff[3]; e = coeff[4]; f = coeff[5]; Z = 1.0 / (a * e - b * d); Icoeff[0] = e * Z; Icoeff[1] = - b * Z; Icoeff[2] = Z * (b * f - c * e); Icoeff[3] = - d * Z; Icoeff[4] = a * Z; Icoeff[5] = Z * (c * d - a * f); return; } fotoxx-12.01.2/icons/0000755000175000017500000000000011701011016012743 5ustar micomicofotoxx-12.01.2/icons/gallery.png0000644000175000017500000000274211701011016015115 0ustar micomico‰PNG  IHDRžCzsBITÛáOà1IDAT8¥”kHSqÆŸÿñœÍ]´tÎÊòÖ²Ìt] Œe^6¬£²u‘²‚ úPbà‡èfWéQDFÒÅ.‘Å"¿­‚ÔŠ  m.3Ó™+o©-ÏiçôáÄÜþ³Ñóñ÷ž÷}Ÿ÷ùÃ!¶;74Úð0­ @S³#1~Ê«—¡ ?¹{úÕêPIôöüˆÑ÷ bø¸°*66.ŽÕEFž«¸ú´¾žÂóÂî];*.^Ygâ@euþ"cŠ¡heæ§·ëÛàÉãIƒÝf2›œïš£õºÞ¾~žjî=ù¥T*"Ƈ÷õOˆ›ÜÖÞéë·d›Z?¶wtvef¤ÛŸ4ººº©3BÐ`·I’Gúé–„n)PîûŠ­’ÔEñ¶»Uµ¥[üɱ»Ñ`·ù¶Q ë ,N”S\þXœ>RhÍgHbÏýšëk©V-_`ûÖMß>/N«fYCm°ÛnVž0%f"åË’e0×8‹r4Ý Ò™³2|ßZóåŒ$I¥¿jÌÒ(ðÝ£§Ã%Å;–í¡NÈÍ^@yT[EqsN!LÞÒ,=zšãÍÓ1Þ?'À¦õùg@yY©Ø,€¤Ô™Ó¦Æo.ZKm®V—•¹¼ªú&ų/¤5ù`þ8ª<_@©TDEém\çÿÌiitØÇ&&ÆËOöɶG¡T"Héæ„¬Kp)Xò ÕÅÊËÓ“¦Rµ¢p²ü ÅI F¹Ï#•üùS‡ø‡%{‘¯áõÊç+5+Rƒ¨»dÈUi ·á–‰Àq,Ï /2Æi‘±iÁ|›ƒ¦Àj]MáùÏô †¤d…BA5´¼}AÅAŠ;r`Æ´D…"ÖÊ¿Tñ™Ã߇=TƒaVRÕ¥ FñTã‚Iô„û,®m;J8Žku:ß;Z®Ý¸-×4ê½^Wºw?aBÜ¯WôzÅ%¹9AޏP{í­–¶N¯W"}£žÎ7jÖÑÔ4˜’¿Y)ÉRqöÈ—/ÝÎí2R©”ÏþE³É­­Ÿ~óÜf=ã»Õ¦tEXtSoftwaregnome-screenshotï¿>{zTXtRaw profile type iptcxœ=‹± €@ C÷~…ŸÐ뵩7;¹9ø‡z Šÿ?XL¼@Bã4ÝuŸm?6ê^SîU´èÊþ%H ˇ}›3§êóŒâ& ‰^\a„Œ†Í%–¼Á°"y<éÜ®t¿•À±iTXtXML:com.adobe.xmp 23 24 °áÂÞIEND®B`‚fotoxx-12.01.2/icons/fotoxx16.png0000664000175000017500000000332411701011016015153 0ustar micomico‰PNG  IHDRóÿaXzTXtRaw profile type exifxÚ¥•k²Ü( Fÿ³ŠY’Ѓåð¬ÊfùóaûöôMne’‰©6´Bè9­¿¿íôÊšSQ«fO©¥rà òý 'Δ+ÆôÈžžÚgy*Ï"êŸ'>äß⻂äŒ×cÈžð=AåþïãÙ@ ýÂ#«á¹¼yTŸùù4÷bájÓ˜až—ÈyŸÍž µ×ûãíÒ’¨Ô{âX9¦`ÚÏÙOÏr>©ô.¿ü—3h—~z[€SÈŝޒù³üCœå–§&>»¬Óµ+½É¾ vÀ¤ÿCì:Ö[ ydJ§‰å¯%׳÷Œ½×¥PZ1ä›]èu˜Û;ü+ ÍñSŒýj-ÓÔ˜yäŽ6{FP7šÔh'Z×`Ѐ[…;zæPGâ\y\(Êi´ÙÁyJ€å@Z¤¼wz|¡kßzí7(°ó$¨2Á] ð-ýŠÒÏÚÞç bO´.Ø|‚ 7öó† Ð~‚ªW€?Ú§'½r´@í„9pÀ–ûm¢+ÝTO>ÉÅV §èïD&Ÿ÷úc¨`o…3¸&…²‘(®³!@r°î @ª<á$›8—º%¬qºtYù–£&„Šá2ƹ‰€UŠ"¼r¨©hQUS×ЪÍÄJ253·SÜš‹WGððê-$Jh DDV¹ jŸV«^£ÖÚöl°Ü,5è7H:wé¥k·î=zím }F:løˆQG›˜ã"vßÂÓ,¸}Cgîƒç¢6ÓèËPrÄp› žhm…U¼×a‚b©(4ލÎp‡îŽèC´åÕ¦õΧÖiHŠ•!m£Ô]«Œ`ïYPÔê¶%±¬°€ÇøhµóM_Œ°öÖ¥!øˆ¢¤í±œfÞ2Ì›in}6ÛaFÁ\(Öðº.äk“à±áŠd^K#ÃiÂYØ‘ÙRNÝ™çÛôó`å7-.‹«sBIT|dˆ'IDAT8¥“ÍoÛd‡¯ýÚqÚæcmⶬv–¤B¥ÛTF[•õ€øÐ&!`ÓÔ Rí4 ñ?Ð B=€ ˆÛàÊ´SÕ层´²IcëÇHÜ8M&U^½:iÒ¸±ß—Ó÷=÷ç¹=À+B`nnív[éèè8^^^f+++h6›(  ©‘hT?<<¤†aìU+ÕïøÖ ÃŒâλéLf ¯-,\ÔõÄ I’/˜¦yjjrêv8¾Æ|þ¹ï³Çq†f.L¯eR©VþáCˆ•Ýê(•è­L&­†B]o­¯¯ä8ÎÃ0ηZ­eYVB¡.B©H8çbÍqÎÄb±+’,œ;ûDl4šW]×ýx|üÉår‚,„K—." ]Óˆe=ÇQ³Û¶á¶\…D£ÝÑZ­~±¼»Û¢Œ±ôðF66¶Ðl6¡iJ¥ž POžD>ŸG¡P„(ŠèííÅèè¸sg^Ûúúú%J©ÔßÙ٠Ξ>ÝÆìì,‰$tMÃêj‰D333 „`oϽû÷0öæt=‰ò‚žç£TÚïûÈår€ÍÍ-„Ã!ÄâÝøûñ#¬ÿy¡pŸ}ú 67·ày‚AE¢pÜvÁ9ø¾Æ,ËB\aqñ+¸õœÜþUÂõ/¾Äû¼‡ÊnŽpÎ8!àœƒsÆ"Ñ0²Ù,êÎN÷Ep>À©ŠŸoÞ„ªÆ!(¥5€4_ÊÀ9‡mÛè鉡\.ƒD:qxÔÂã A)¨>«TUEÛóöA,A@0ÆP*•@)ÅÈÈl묎0L«†T* ¯íAQ¿æ8kT¤´*Ë2?jµ‰,Üz­^v]—ol<ÁääTÿööv×_ùƒ®k¸|ùŠÿO¡ø¨Z©þôûk·ÈëÉÓoOO¿óËðð Z(¾Îf³Kžç1B™ŸŸO¥Ò‹žç *ŠRÝßßÿnié›-Ëj5 d`` ++¦i¾°mÛûÿmš¦IÝ”J²išÏïÞýÍÀ^õâÿøßÚn›·`IEND®B`‚fotoxx-12.01.2/icons/first-page.png0000644000175000017500000000157511701011016015522 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>øIDATHÇÕ•ÏkgÇ?ïÌdgfwGÍH£$YMµ’öX(Z ö «´ô/è©'ñf@éEX/O¥‚Л‡R*ÍaÛC„äÔB ¤ŠV³[bcÄd»›ì¯yçñàìî$1;{ðâï;ð}¿ß÷ù>ÏÌÀÛ ààÉ\pDÀ+ægq3ÙÜ9à‡8¬®Î©/[J)£-ÚƒXeN^¹ \ÃF0 #K&›@©ŸG½¯•"èÇ¢xÖ.¹§”šß?:tâØGï§éçœÕ'ùJ-LŽŽ=2éH¼3ý d²¹÷Pjáð¡ýìåR±á$ ËT–®d²¹ÝŽÖ‹ùÏŠ!ÿ¥~›>2ጎ+뛬W|ò釆Úf± Ó¾æÖüßNÏ 2ÙÜÊP7¦fR{öîeµÜ@B×˵åZ«C¸=ÞLvöÆ.äßX¦yãƒéC)7í±¾éwÈ£!òúÔº;`¯«à3àû©w'0,›µµî¸t6 é<ªÝty©;ª§À<¨Ë…ÂãóSS“)ÑÕZ+n¶DÍ5{[TÌ_¸Ôl¶¾}ðoaÓRBÊékš;áG,ÚõE+æg¾Ó¾>·øè¿M |’vWÄN˜ìKÛ z[sÈsòZ~ïDE®g²¹òRññ£Æ’v"A£©±LƒÅ‡‹:Ð=¿Ò³‚ˆÈO"rvåÿ'ZËÀ×!ù0Þ%½¸ Tx£˜Ÿ™ÿüâW«O¹¹ox$m».åâRº;ëA˜;bGOîX€ ¸@2ÌôÒÜåÛõµÂéõÕg•jUê¥Å$ 1.ÌžÍòò@´#B.ZùóÚÃÊÒ_gªÏKeÀÔª 8lˆ:³C@­B{ÚµW°ÖîüRxñhá´Á2ÛpíÜ:E"ÈìÍ9-"¦åú€NAûQ’ç÷¿§,û”nT6€& ÃôV¸ï žˆ(€ÒÝÙz¤:³Ý舀”þùµ^@GšÜ×OèÆKkY'¥KîtEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/icons/next.png0000644000175000017500000000151111701011016014425 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>ÄIDATHÇå•OHqÇ¿¿™qwvuQRñ l»–«aóP§Ð · º]"èÐ!è-H‡µ†]:F:%t0J íP‡ . ‚ûÚÕÜÝiÍ;óûuاYW!O=ø2o~üÞû¼÷~¿a€ÿÊÂãñÛûá÷³¹-2:(2v|¨ûô«Tê=ÝK ·ß‚::Z/¦[|ïºÎN5Ã'úÅPO爯Éü|ô܃Π„`` ,FŽôD Ž[ Fã½»í'ö—ptr…ëVCˆ8vf9IEg«kÙ º¼’)QÎM¿žøÒ:ÿ0jd°Ý+zÜ«!ŠN!ýÖÀ =àÁ/©„oˉ-FÉ¥äÜ…Æ#"<ò%k’ú—rEÒo­:*llêðìkáÌ£“W(¥ Œ1¸Êi%Ùç1x¬Ï/ ü“Þ “±]ЦCV4(ŠYQ·ým©TUƒ¢èPÔªŠ›*LðèïõSÊî‡Æã—­|‚ *:Êå LêRnóy°& ‘HËãg'åiÌÕæž>Ðm=<ü«ßÓeEÓŸ§æb7¬ä®€ŠIð{Àà¸bV‡ºU7^&ž ±š)†ñ85›pîß  LO'2&à>ÂC!<Â(2ÉeÊØ½ällÊ-f@`þ°¡ êköJ¥¢Às0 ¹\Vp+ù&ö´^LÝd¨Þ0K9K]Ý=¢Q1 ý\—M½r=³p÷Š:m;Ï€w‘ ˆ¦¨( ²^Î_Ë~xô€€és6ñßa³W”âêÕõOÏ>µ¤FM€Š±Ä!ÎáW!&Íoe—nn|^¬­³Ú“ÚöÃÞýƾ%«í ïk›/,½\ªUX±Umu¡×Ö2qÌß’eÔ&s·C>pûSïΘËStEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/icons/open.png0000644000175000017500000001112311701011016014410 0ustar micomico‰PNG  IHDR00Wù‡sBIT|dˆ IDAThµšY\ÇuÇÿ§ªîÖ·÷ez†Ó³pßF$ɲY lˉ ÛoÉCäkøëÄH b ÎfI$GpìH4%Š"g8[O÷ô~÷ÚòÐCšr$Û•ôKãö­úÕ9ç_§N5ás^á•N§óÆØ•8ŠeùÏ‹¢øwkí/4û¢c}âø/ú‚ÎJ»\©”¿öçñgô'ú';¯¾ò…êx<î ƒ›Æ˜K$€)– Ÿ»‰çxÖàb¹š)^à;œó•µ•ó7ïÜ<Ç,«z¾»uëÖ-ì>Ú½ý³ÿþÙÆt:ý¹5öçîˆð9zƒŸMª~ö!,W쓞Ûp@ûì;À„å°é¸Î×/]»x­Õm5=Ï«ììì„wî¼,šfy2™\c`;®ë– ÌLk kmñ)ã|&€U_#¢×ˆ1b4ìÇVÉðU!ÄApÛuÝU!D¢”’‚‹^xõÆÕs«ë«^! /-Rr]—]8ÁýÒ¿ä·-_)ÝG×Ò,íYk >/€mÆÙw›­æÏ÷zJ©¦5vj­M± ðc¯ó›ßüƒï}ï{;/¿üòF–e{{{="Z­Õk7vnß\_[_«ZkE! H%aaP*¬×ë9[ç·ª+kN¿ß÷•T{yžÈ^@K¥ÒÖ×¾þµ•jµºvxpÔ|û­·½Éxü€Žc̽råJý;ßùÎÆþþ~Àš”òú{wß›„å°Ã9÷•”žp""›d ²<…ïùÔ®wD³ÛàÍ•&k´½$‰WóEh­n¹\n}ëÛßÚøâk_Šî߻φ'ƒÆ½,û½$I~àÇX*ˆÀó}?¸~ýzyeeE´Z­æ÷¿ÿ}Ç œt±XøÃá)ê:Çà‚À%YŠÇÇqÿÃûxçgïp0[u=·eÎMÄø•§ŸÛ8€ A)øî×nŸëmö[ggç~¿Þ³ '¢W_}õÚ›o¾Yw]—Aànnnú×®_sîß¿_Úß{ì-æ  ‚qÎIA 1ãɃ“™,âÉx8‘q”ÖZq ±T¦çV'`»–Þ|õ˯tš­FÀ…[[[´ÒYNGóýý}ÏZ{žˆ^¾}ûöæ7¾ñÐqÎ9çA°V³Å*åŠXD?<8 þqyžÃ‚1!8ˆ1DQ­”¹½s'3ÚäãÑØOÓt=Á™—Ÿ[b9€VX¯]»quÝý„@8båâåKñåË—NMa2Ën’&×*•ÊZ¯×Ýn®ë‚ˆÈ÷}vñÒEò}Yša<šàèðÓÉÖZG@c UÊ|ñ _b«+«T Ëe€ÎE‹èj!‹U!–{ËÏ!±Ë¡_®V^ªTËíj½J‹d!r™¯¯®®U¾ûÍïŒ_ßùʃ{zýAý`ÿç/œ7årBbŒˆh}}×®_C«ÙÂý÷ïãàñò<‡’ LpA€F£IÕjÕ¹tñRýÖÎ-¿»Òµ“ɤ’&ɦRú²Öº` ?ƒQ¿ +…¥Ðu7º«Ýsk½5 Bæ* KÆ*TAQ¼ © Ã6zØ>¿M‡G‡ì'?ù1î½O¯t»h·ÚÄ9‡ã8(%ê´;ØÚÚB«ÓÂññ1>üàNŽ0FÃõ\0Á(+2žËÜ©7êáÎÎÍêµk×+÷‹ñhÔÑZ_° àËD7OŒÖ\iÕp]ïb©l]¼|‘y¾÷‰Ic­E! dE†\`‚huuªÕ*i­q°€ÝÝ]šL&6[.—™‚<ÏC­VÃjw«ÝU8Žƒ“~?|ˆù|"Àõ]2Ö0KVx¾ç¶;-çÜÚ+•BWiUŠ¢¨ªµnœ…Ó@¾0–¬…ð\w§Z«Þ¼~ë:‚àSò~iZkdy†$O!¸@§ÓA·³kÁŽŽi0 ÏsË9'Ï÷ „€#TÊÚØØ@«Ý‚ѧ§§8éÄ üÀ‡ã8ÐVCEŽ#¨×ë9Nå0,¬µEš¤›EQƘ1€Ñ“@·œóÂõÜWê­ÆnÝy‰¥ß pVJb‘, •DµZ¥Ë—.ÓöÖ6Ò8¥÷î¾GGGGÆq¸® Î99Ž!µÛm\¹r›= N†x¼÷qƒAAœ3’J‘¶ÝÕ®¸qã†ÞÚÚ\œ úåÉdR-òÂZk<ð}_ G¼Þl5¿|û•[<‚§JôÛÌó4¬”V¨V+´²²BÕr'''´ûh— O‡°dmµZ¥³GÔnµÑÛè¡V«áä¸>üè©7„ Fd¬! Ã9ç¥Ñt\™Ïg´˜EÇö§O¥¦Z¯À´Ú­×o½|‹¥Òï ð¢(P¨  –P«×È÷|Š££ñý~£ÑH»®‹R©DžëQ)(¡Óé Ùl¢È ¼ó_ï@ƒf»¥¬5O<Í&³©···ë ‡ÃY¼ˆî±?p]—c^¯7ê¯]½qŠ˥g¥ôw6¥²<ƒÔ¾ïa}ýÊ• mprr‚{ïßÓqk.8|ÏgŒ1ò\årÿö¯ÿÆ ­v q¡( p! ÂÁá>Þ¿÷¾Ьx‹ ñÖÓj¥™,äKa9Ü9·q®ZoÔ¹ïûÏ Æh­!•„1•j½^Ö×Ö1é­Ÿ¾íïïËR©$ˆˆ !(Ë2ø¤Ï•R³ñìî 0¬sÎ}kmØ]í² >“*=ƒÆ<ß…pÇ#, xž‡$NÀ8çâ)w’4Át2ѲS%Õ»Ñ<ÚÅY5úI@l­ýeÅáÑÁQË’­ey¶VEik{‹»®û4œ> gŽãµ°“éÓéÔz¾G“Ù\p8®³ìh8Y–Ú4M! U(©†ڵƎž¼ëÓ$Ƙ¹üÅl2C‘Ë,Oò›Ñ<º2›N·®ß¼Îðü™=A´LT&Ižc6›ÁIÄq‚z«†0,=˜/æ˜Mç6K³LæE_Jù±®ÅoÒH/âQ'ÿ½‘Lãtœ&©ÍÒ4Ðܺ°í4ÍeÁõœ D´ Á ãL%I­µBI…r¹ ?ðÁ8ƒp8F£FÃQ–Ì“Y¨ŸÊBž>û®ß&ò#%ÕO'£‰µ°\)…8Žo&IÒºxù’ßl5™ïùôdãù]`ˆØY¬3˹Èó"we!…ÖA)€ë¹ "XX; õ ?˜ÍÆóŠ¢ø—"/Nžg{@‹w’E<=.Ôi%£hß>==ÝܹõR¸¾¾Îƒ Î9¬µ¿‚ˆàºáV¥•’¶”R8;/@$Mìd4Éf“Ù4‰“S-õË6 áL…ž§Ü”ZéHk=“¹tò,“RjRº‰Ás\‡\Çãü7ÖOÖZ$I‚ápˆáÉPÊBNe.Åpxê/¢6·7Q KÖXƒ$õãÝý㓃“"RßãbÙKpveõ¼õ²´Æ.”R©ÌÕ¸…Š¢¸¡´ 5.ŒqFœs|Z)n­Eš% G8==U®§þx4® !°±½ Ë܆'rïÁÞéd8%­tÀ-%Åg¹äS†Æ˜~žäIÅ^š¤•8‰KY‘¹œ1Ž Á—Éýäó¬åyŽÉd‚ÓÑ陎£ÚÍVݵ.”Q8::ʾÿpÍ"²ÖÖÔ°ÌYŽe#x À…¹fµÖÚ‚ˆæF›cÆXª• ³,]SZ9iž NbZ&¦»Ôý3¥’Ra:›b4åq”œÎF³&c¬Þh5©Þ¨a<›Ývͨ?‚RZð°lÁ~•Ä€ú ßcT¥Z­'XîàB)UK’¤œ¦)I%!¥‚1œs! ”Âd:ÁèôTåiOG³ª#œ°»ÖåĀ㣾>Ü;REVˇ³>.–›,}Ÿ¿x±ÿ+û¨V­Íg'óÑBÉ\¾®•n+¥Äl6£ÎJ½s=´Û³Ãº1Æ=Ï«9®ã8ÂÑåJ(¦³)F§#“F©¶Öj,c_œM\ŸM¼À²sýð…=Yš#Ks»y~3%¢>ãü]-µÉ’ìB–fXQ˜/æÐJ‘6Q´Àl6Sœx:Ï\b̯Ô+|x2T“ÑDçiNX*À2lΚÑÞð·þòsxbLJ}ûÒ—r×u'q0Æ<Óz'A! RZQ’$˜N§H“Ä:Ì5Ñ,ò<ó¤’žœªxk£ áWÿ –Â1ðþÀ|ð¹Àñy~S'I2h¶šcQ‘Lk]RRÕ¥,¨(rŠãiœj¤ñ"aI’ˆ8Ši>™k™KÂÙí–+>pÀ?ø;?Á²Éû™ößj=ÆéàÛ·ãF»ñ¨{®{, Iy–·e. ¤I‚ñ餈fÑ4Ž•&)O1Ï’ÆXe¬'úÞðþÀ]Æo~E !&œóƒR©ôØq™ÆŒip8Pƒ£¡Ž¦<ŽbʳœimžœÓçÞðWþÀÛXÞäÏŽñ¿§÷:4bâIEND®B`‚fotoxx-12.01.2/icons/open+W.png0000644000175000017500000001146411701011016014622 0ustar micomico‰PNG  IHDR00Wù‡sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÛ ¢¥@´IDAThÞµZÛo×yÿËÌÎì•»K.IqIŠ"EQ$%Ñ–|ic7‰ã4ví E‘¢h€¾ç½@‹<÷? AÑÖMÓ îH7Jë '–E’e˲$^÷¾³—¹Ÿ3çôKJ´e7²•,°gæìÌ÷;çû~ßm >å`Œ¥Ap~bbâJé²çºÃè×qÿTký6€@@ãw0ا}ÀDe<›ËeŸûê_þÅ~åϾ²~áüùn·[m6›kJ©%@oä‘þk-æh7 R¶e0Æf+Ó•…µµcTÓ|Ê2çÏž=‹»wîž»üÖåÙ^¯÷k­ô¯Üà>ÊÓ`#¡ÆF2Ú±­›°`|tMP™l¦d˜Æ–VWÊ“åR*•Ê­¯¯g66ã¥b)ë8Î ]7M3« úI’@kÄ{>€)ÏBž$”Jh ô‘]²|žsþ%Û¶Ï™¦9Å9÷¥”‚3^µmû³§VO›š™JÅ"Nq@LÓ¤'N˜O?õ´U.–-)“Én·³„AUk]Ð|TŽSF¿\*—–SVª*¥,i¥{Zë`¤.¢”~æ…^øƒ¯ýëë=öØl†³›››UBÈTa¬°º~nmfzf:¯µæ±ˆ!¤€†B:kÓjµjÌ/Ìç+ÓõzÝ’BnFQT> ȤÓéùç¾ð\%ŸÏOïîì•ÞøÅ)§Û}À-{¥Ô\^^{ùå—g···'L !N_»~ÍÉd3Œ1K ‘â†A!Ú}„Q+e‘ñ± ^š,²R¥D‹åbÕ÷½Êp0Ìh­»€™ÍfË/¾ôâìSO>íÞ¼q“¶Íâ0|Ü÷ýŸx}Ä €”eYöéÓ§³•J…—ËåÒ·¿ýmð`8Z­VcÅ1†Î8£ÄlÕ¶pó½›xóò› TçÍ”YÙ\€wßI":a§í/oÿüç+ž¼@í´M_}õUåz.Š¥"lÛ¦Œ1pÆ‘N§1=5MÖÖ×P+`{ko_»wè‚˶3‰DH Ë4—rÏ>ûL¶\‡ý¡rzÎT’$Oj­gFëŒ@èdsYgç«ós s„R ­5d" !EF¨x,›Í¤ŽMϰÙê,³Ói4ê zýêuº»»«'''I&“!7`Û6)—ʨT*‡apìííao§†~¯Æ%Œ2ÊÓÙ4¯Ḭ̂ÕÕ5=33îÕöØp8œÖZ¯˜P©•þ(ª0V0”R/Uçªó3³3ÄØçòýx!‘p}—„qÈ(¥¬X*’S˧hlww—´›míz.”R:•Ji˲眔J%ÌÍÍ¡R™€  DÏé¡Qo Ž44@HAò…BêøÂqzêԩжmA ‹¢è„ø'´Ò €€Ä`G¢Ñ\.kCã ã“ãó¥ñR*›ËÆU¢¡I,b ¼zC’IgèÂÂY^Z&5Èk?zìíí%†aèL&CMÓ„a0 “Œ—'°º¶Šù¹yÄ"Æ?{z*I²S„0I,"3“ÉÖ×Ö KKK€ç8N!‚óRÊÅQÌÖàßï7äòÙ"cì¯Ö7Ö¿òØŸ¼ðôyšÎ¤Q¾ôÕ¯ÁîÜsš?ùÇ¿Ejý й27ïèc/|‰|ðhÅ¥KŠmlH®^%ÆÆÆá½¶má…³k˜˜œÀê™,./b¢2´Ñ–i%¶iÇ"âÝ7é7¿ùÍðúÕkaÅ-¿ð-W œ€J&Y4ÍÔb:mÏ/ž\¤)+uøÂòÛ7‘ßÚ9œï­žDkz‘ˆQ|ýIþǯH7/CëpmUe³YÊ_ï}ïðžóä“h~î³hÔë¸ýÞm ˜–I”VTÍSVÊŸ(Ǧ§i:1e"Ó®ëæ“$)ŽÔ© Ú 4Ñ,Û‚aHt©$1 NªÕª111l&k­ãÀæâ8¶•R]E׌±ØL™çÇÊÅ'ÎnœavÚ>"ÐÂ/~rYì|ö÷¡¡±ö­@j0ü›òJ¹DöööÔ™‹Ifgçžš}ãߨÀòò)ÌÎUÑl´°µ¹Ïó@(çœ0F‰’$:ÁäÔ$_]]Mæçç†f=ë8N>Žb­µ¾u‘)Ó4‡J© ‘‰ÖÐZk}ÈD½¥(ÎAå¾_)ÜÙ®‡Üöîù¹Øhàsç6È•­MÊoÜ8^ÔÆ†¶R*òä…§Ïðæ¥7ñ替¥_\Bc¾Óë+Ÿ‡Öš€Étq¼X]\Yb­N‹DA4‹˜¦”vÆ–­5T¢¡50’Ê4à,GùÝ[€l­Å(Ýx÷[¯°-AxÈkKèÉ“d¬×;\ÓŸÓ­Ý]U­V©mÛ(Ëxü±ÇQ,A Å+¯¼Æ9ŽU§¡”B!Š ò1 ÃàýÁ '•€‘2`¥S!¨O,…„RˆX„¾çi)†#ÝÕeÜãUÂæ6ÊïÜ<²æÝ?ÿ“#óÌÕßà¬ÉŽ€üV|Q\»~Mv:†!RF ÇçŽcccœqÄQß Ð¨5PÛ­¡çô1°³·Z½¦=×rΖmy‡<׃çz½á`جíÕeàG„éœ^>2/ÜÞDéí{DÚÆÍ?}â>Û1/_Frå­£±²B.þÏEÿ;ÿò÷ÒåKrkkKx®‡^·!Â0‚;táy>Ú­ú½<׃ã8ºÛîê¾Ów]×ëxž—ª”R¨…aøþîöÎôÜñY#_È „<ÀH¥ ¹q*e¢¹±Ž™ŸýjÍõwà›:ò»òÿ‘>öÖ%ÿÖ[¾~Mûg7ÆÏOY–…ápˆD&À¾ Hd‚$Iźݮv‡n†a7 £¶VZÒûž­lGat}w{¯?è’DÞ ƒÊ8‚rép>óÓ7`zþá¼~á qþܽð|Lýä÷Ø«\B47E̬™vú]ãÊ•+Q­VS½^ÍfÛ[ÛðZïç$ ˆXÀqGQ=¥Ô¦RJ|Àfàû—k;µÝ~¯FQô5:yø=Ý>šÎ^¿°q”Nïóà•%´6‰DX ã°Øl4SP¥ƒîܽƒÀŽDc ” Š#ôœ¾–2ñ¸aì2Æîˆéد%„xÇsÝw½~w8ŠD&Zký@;8tlÕcð§*ª‚áÌô×µO/ƒPB¸Á £Ô–Ræ‡î ! „Àp8¡q!él”Q~oè©D*—3ÞÍä2}ꃒ85ßóÿûÚo®ÿèík7n×j5-„ÐZkt?@ý>µ€Æ…s\×]9 BlÛF:“æ”k0Ð8Ž¡”ÚO~%ûbQJ‘ÍfÅšÍ¦Ü I„l*¥:¦iª–¥=ÏõõöÕ&!d,q)I’be²Â“'Ž8´¸~~Kÿþƒ#×cè./îÇ<¦‰t6C Ë Ýn—xžJ)bƒ1 ÊîË Þ¬£V««0ˆ¼8Wâ(~ÿ ?xPm4’Rîô»ýëwïl΂b†1fi­3˜š¤÷;4H ŽÖÙµ£zxn‰ÁÁÄ= ýóP)”Q¤,Üä¤Ûí`8"•JÁ÷|PFÁFþ•R fpøžã$"=)äUwàÞå  xZë·}×Ëìíì•5Ñ…0 §ã8Nÿoþš™¦yf2ÅýzhYø·ÿú§Îc)ƒaDkh§ç ×ë锕"N¿ Æ ÓØ¯haè  bK![ä®VºóÿU§€A‰+}§8aäGkîÀ]î÷zó§×N³L&û@á›AȾ¡RNàGúý> ߀çù+ɤ †ô{a(¢¸.„8Rµø¸òºö†^Ç÷ü·†Üt?Ðad”æO7JÅ8ç „²¯œ)ʨô}Ÿi­¹Ùl–m2 n0t:tZÐø;"–¿±h?L@i¥;RÈ_:Gkh&¥„çyk¾ï—O.Y¥r‰Z)‹PJ?R¥> €ŽtjÆxÅ‘)bÁ“$¶a¦LB ¡u³ÙJšõf¿ß¼ÇñÅ8ŠÝàÐZ‡ÐxÓz½Z,Û¾ëwÜ¡w®ÝnÏ­Ÿ=“™™™a¶mÆ´Ö ‚Ó4`pÐЉ’‰”BÇ"†”r¿®Ê9•À|ítœ°ïô{¾ç·‘tF©$9`¡‡i1‰D&n’$} # C!DBdgEÊ0 b&(cäãNBk ß÷ÑjµÐj´„ˆEOD‚·Zmkè1w|éLZ+­à^²uw»ÖØiÄXJ)sTKuZVÛ#Zé¡”2‘ìÆ"–®ëe"2J+”2Jc¸¯ªñ!Aè£Óê Ýn{2’·[ͶÕítóœsÌŸ…±‰H7[ ±yk³í´z$‘É8€&”¤ÄŸ¤É'´”RõÈ|ÏõRä<ßK‡qh2J 78ál߸>GMÁq´;íAà‡Wë»õ\Å•ÂX3³30S&ƒºsûnXÛ¬ÉÐ 9€,€ã°`€ü¤]J=ª_¶!wÃ02ãXâ(Ί$N…QD441LFÙ‡!Ðï÷ÑévüÓßí4;d¼T.brzRIìííE·ß¹=pû.ÑZF6ËF…ài'>M›Uk­cBÈ@%ªF) )3aLËDAäÃó=²o˜æ>ï˜J‰^¿‡N§y®ßîwú%JéX±\"cźNWÝ}ÿ®êÔ;2I¤F%xrŸÛÆ>uŸX)%™´LÓpFœK) ¾ïgƒ B !¡”c œsH)áôtÚm±×ëôó72“Ó“ŒP ¶WOv7÷dÆÕ€RuÜ‘“%£ëÇ£ïò…>e´1è ¥ˆÄg™ŒK)y¿ß'• TU1>>)å>ÝRÊR©TÁ0 ÃàF’Íex¯ßC§ÝQ$Zëd¤û|$x2<U®o³G%}Dzna. „Ô)cW‘¨ÐO„A˜"4Žc †$R’D%pÝ!úý¾d„ýnß$”Z¹±k5ZÒé8IDdÄ4|¤6ò  à€ðwìžj»uݨ5¢•ÕÇsÝJé.gœ^0æ{¾‹˜ÈDß÷Ñëõø¾6¨©Ü¾gGQ˜R ÕhKoè%*Q侇à?¼à5ï>RcóÎfÒn¶›Ë§—·(¥nÅ4I’´rLˆ˜ÄqD<ÏCà oèSß÷¹çzdà  rÐ=íxÀM?ð]?° æøJi£8^ü;mï4j†çy/ ºÃq¥TZˆØè;ƒ˜*êynÇQL|׳D“Q÷’ŒI(ñð'q{ Ï>ÿŒàœ;Œ±t:½e†¼u]ÒÜmÊæ^K÷:=湉ˆ&Éaš;pÀßøWoŒúG* ÿÞyLL9IEND®B`‚fotoxx-12.01.2/icons/next-row.png0000644000175000017500000000146111701011016015236 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>¬IDATHÇÕ•¿kQÇ¿ûë.°1I• ÄB»H&¢E„X +{k› Á")ý,Ò6 ‹ ,¢6 LÞzI.Ée“ËåööÇÛ·cq»¹wë]îŠ ø`ØYÞÌ÷3³o üïKé09¿õ‰#f[…^›úE÷nJÆH n¾z³vfò üpž é‡€ÒÔ¥¾¹bAÈŠ&©Ïã¤o®:@$âÔ—ãܱhs’\œ[$½µ ƒtÐq“óKEtIÑQi ‘å uÑæÌ¶D¾ƒÇ|€€FÁÐ’X(?ä †–d±©ù¾ïì7ëâîòÊȰ¹xõÚeÓ0t$Q ?jUÛlðš­15 5‹PÔÖuk´éì¸ šf¶å€–Œ]¹õ6â|Îóü‹#c#F#ààÒ!s.Àyœv pìEÐU'' 0g§¢f[¿z2³-AD÷jµúúæF944¥}‰»¬Q³€À÷ÁØvDs̶~Êû]§ˆÙ–OD%×=ÚÛ.W„*d–9¤# 8ÎvDw˜m}ËkõSf[‡ š­VÝã½Ê>’BÑÐE!Ê¿w|-0ÛúÜMçÌ{ÀlËQ©ºWõö«.D,@ hš‚˜GØÝªø zÀlkµ—†v†¾@«­¯º&g¾~´Hªf誅8¨ìú"9ïž¼Nãi€‚Öå3êw͉ëŒGÉmE3ŒÚAÕƒúÓòûg/ÓX=ÕRó0 JâÀÈ 'lmsxb*ä<™›GÏ·>,¿Hó3a5-°ýãÈ EÈ›&ûãÓoì]ù@ˆS“ýOŸÝd5'Ü«BJ-IÅ…á©n€aË^×IDATxÚí½|UUÖ>¼nÉMï I ôÞ¤÷Ž¢ˆQ@ÅÞ»ØuAglˆŠŠ`£ ‚Ò¥wBï„@ ½ßÜò_ÏÚgߜĠÑqfÞçwíçìõ¬^¶….õaù__À¥ã{\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀE~\ÀŽÛ†Ü–R7$$¨ŽÕj­^ÛÏÏåõÚ"áV«%ØfsX¼^o€ÅBöÒRgIi©ËÅ.þ+¿¨¸0Çírg—žËÍÊ?ä&ÏQ§³èpzzú‘•+Wžÿ_ߟ>þv`AŒ?Ý‹¥ô}ƒU=† —Ð;22¬ODDdëððÈzQQáAA!H‡ùÙýÈf·“Åbåûôà^Éëö’Ëã!·ËEL~r–ºÈ]ŠÇR*.)¡’’b***¦‚ü|Ê/ȧÌÌ̳yy¹ûòrò6äægÿ¼cÇŽµ§N*ú_Ý÷¿ €gžy©^rrüåGíÎ7RïÌ™3Ñn·ÛZ\£Fc 4H‰‰‰Y¹–?þ8ýu£:îºë®º±±±%%ÕÄ×EÁÁÁäççGv!vùeÑq¸ÝòxÜLx&¾Ä7@àv.*øßòÈ' ƒ¢¸XÀ•™IéçÏìKOÏœzòä‘¶lÙ’óß¾ÿ¿ €¾}ûÖdâ¾rÝ´iÓBj×®MµjÕ¢¨¨(y7Ê€ Ý»wSýúõiÀ€«ÏìÚµûË׿ºsç΂ÿöVvŒ5êú¶mÛÖ¼y³¨Èˆ(rø;„à™ÀÞJ?'œÏÀà Á=|âÑår ¡5@põXÊxOH¼Ò!++“>¸ûàÁ½7mÚ´iÏs þ:wÏVÕbãˆ%"‹É ÊÈÈ §Ó) d³Ù(,,ŒdaÀMÇŽ£³gÏ|2{öì{ªú[Ÿ|ò‰_:u‚rssƒGs¦¿ßËêú×[XXXÀ¯åoݺµèƒ>(©ê÷^sÍ5¡Ý»÷8Ñ»wŸ±\ó…^ñ÷z=Âýæ~% šóË€OV ¼ÆÄõÁÏgeeÑöí[—Í™;«ïœê¦ã/`ذaɼûBCƒkRƒõ…ØV«Š‹‹ø†\ˆÀÀ yZÚi:t舸›%Fó }÷Áƒ›–––vv¹\myëY¼TÝk¡h‹×`±Z¯Ùãõ:™$%L”,6ÌÒxÇØhÛÊ`Yß°aÃMxKe¿Ó»wï·Ü2bCçÎøsU&¾~/Ä?ï6Ôàa"— ܲZô;€R3´šPŸ÷2œ,1×®]½cåê_º1#åýŸ@›6müš4jv8*&ªFtt$%$$RRRM>…èZORÚ™4:}:Õ8Ó(%eï†åË—v¬ø¬âXÿ~ÂäºÒCLhþ ¯çO_SˆDŒÛ˜P«w=ƒéVM)úåx  sÜÓ§O¿îÿx#‚U™<ÿGÐb§ËÅ=.ƒøŠ nâl—G@ì·–ÚfP@á]b#¨ïäë¤~˜çݾcËáa7Þø?þxêÿYL˜0!þ‡ù?n®U«vbºµ˜ðI”È ˆ­Ë"?P‹%4ë·Bá~6iÿþ´gw ¹œ¥;#cÂ[Ïš5ËmþÎ9sæÜÓ¾}‡"#cx]j±ÜÊÒ6#ÁL¦rÏzHÏVV?6«U ­]»w|د_¿FÝ.,,| «­ëòòòé½÷Þ¡7Þ˶L¿r‡›Ÿ±g<º ¢j.wkn7]¥î2cЭŒ@—ËcH Þk€IJÝ{ôÓ¢…´uÛ&ºïÞ{)??Y~AÁ‹Ÿ~úéºÿ5,æuOMM{ˆõÖs=øh,ßœ¥VídªS«6Õ¬]“ªÇljèÇͱ^¦3igéè±£ €c”z*•Áp†¼S¦Nù€Ý­‡Í?’ŸøþU®z°wŸÞT¯^=ªV­…††Q`€¿ØV›]¸ºâ»Ý^ƒ0ÊÂÎÍÉ¡ ¶®Oœ8I[¶l¦í[¶o¬]¯Ö¢èèè§ÙÚ÷O sçÒéé§ŸbŒ£~ýúúRñðĪÛU^Œ á ‹’À­½‚Ò2 ¸Ë>«Õ¾RÃÊÈ…kùÓ¢´cç6óì³TÀÒ3';ÛÅ6ΧY§O¿ñÍܹ§þë8|øø@‡Ã6./ÏÕ§I“Zi,úc|à‘=5j&Vûá‡lôe ¨èè(ªGaáäÇþr©³”²™0lpæðßÅEE™M›6¡ž={d§¦žú ó÷ 7Ò÷ß߇mˆ&¡ü}‰¬JâøûØ4§ vÉð¬ÓÙ°´Š{&p´(î„èĉï/äÓYâ”ßÃßûöí—k0àJöN¢ÙN §P¶UìßÏîëÓ4sæLª[·ž§²Cëzøú"Þ=Jd»µÅoHÏ$€ËZ¢ ( I §G}/^ówøÓ¶[iÙ²%ôÚk¯Éýä#vÀg^^^ZaAÁ›K—/ÿ„m©*ºÿ6ÎËxãLÚ™g?˜ð^ò¤I“N´k×aÂÓO>}äTÀâõìÙ³qZZZb¡Örbƒ'"V¯^XË{¡"ð¾ÒRVúW^Nééç¨^ÝúBhp?ÅöˆæÏÏÙí~päæåQXx(9—üýlƒ{!uð½p« ØÞH 5R|{xëî»é•×^¢‰?¦®]» €|ã»ð=¡>Îw‰Å.\¬ løû—"v©»ÔP eðzßí.“":~€ïóغ} ­X±ŒÕÓ{bæ1ñ™ðÜO^~ÞæÂ¢W>ûì³ÿ””¸æ-\8ÿšAƒ†²ÉÝ5ƒŽ?úø£ÁеÅÅÅ)Q2°$G` ¿@€+¨À`ñ-¾ZL·oÑaµ-]º”>úh"ßl!¿ßFÆDEE2¢)&:FíϪ€E8{Ybk€ËKÅå$á<¸Ÿ6XT¼VÄσUÝ6b…‡R>ƒµ„ßwäðaÿö›tóM·P¯^½)¡z<…G0ÐØ~±ÙÊÞG4·"–E$ƒÇǽx­ÔU—z¥e Q¥>ƒÑcú;´ŠØ°q=í`)ðÕW_‹~!|QPÀ(”õãåçåÍËÍÏ…ß·í?^?ìxë­·›¾ûÏw¿ ­Ñ´YónËÌ¿tí5©wŸ^>Πœ>}š~ýõWY´ðð0ñBWCÔC—û¢l6èu«þ-övÐ?þÄÆâ~A;žÃ{ÂÂÃÉáçÏFDFÊk1 ŒLærN–06!2Á1ðö¦§Ÿ4wnÚ߀gŸ}6ö®»î>øÜscÂW®Xź4Fˆ‡Ejبqµoß¾Üg¶nÝJ³gϱ¸p <þÏãÕ\¯ È"3a!Jm¼°›4Ž'Ÿ=›Ž›”›…´Á‰Ïã½ÊÃ(ò‰i¥~Ôwh,-BBBåoDø£€¨†jÈÏ+ 3ìšÎœ5Ú·ëH5k²[§6Õ©[›ï1–‚ƒ(¥Z@` OrL¥²¬>pX,ÖrÏÉbZôrzå>µ‰ëƒ„Êeµ•ÅF*_îׂœAI±S¤Öoé²Età Cü6JN®)kÎLUÉÆžAyµÀöAqaáøŸ—/ÿøøñãÅ’’j=Õ¹sçqÛ·máðg‹<„&ˆÂ™¸I5YgŸ¡5jˆ¾Æî?räµlÙŠŸ¯)ˆÕqt, ¡¤¤HD.\Nm¾â†Qr­Z4zôÃwŠ˜Ôêß(=m‘ﷲȶYí1ìåìÇSÅâ‡ØÌÊÎ †ð}œ?ž&Oþ”Z¶¸Œm„x6`«±HÕÌÀñ»ðóÇ#s?ŒP)¢žPmJ½ýÚiRªÉm\¿Kî (..¡¢â"7D¤L6¨wìÜIì¥qo¾ÍÏåÐöž/€!Û¨aCŠŽµ—Í÷¢€ÓPÛK _šüå—óÿD$%&§ðBTÇb27À î†n:ÁYNg±,DVݺuåoXÕ ¸F"›™‹Îãdî-,¢œÜ†| …êF?¸yØÍtõ€«øýEBd9ù?ˆoµØe—^²²‹ÇâãßXðM›6‹qÌ„ôg¯"ˆÒÙx}ÿƒw¨]ÛNT³F26‰j&'‹j äûôg)»Ãá°S1K2mÂÅ=kcDãÒ ö€[…ˆ=†tÓ.*¼¦½i•(©„kÄ:b7yõêÕ,6ÓÔ)_Š„)..¤3|­û÷î“ 젦͚P­ZÉqÍÎ2€PX(ÙFQùùs2sr^˜5kV Uᨑ‘‘Ž€aðÃù `ñ"z†_Ll »h‘t6ý,[öq4|ø-¼Èù´wïmнüÌű²`¢OYNmZ·”Ô5Ä÷ ;€/àë‰çûÓÜ–––&ß'ªˆX Ø”èÇ{üXbøàPHL\-lp}€±ÕD%ª0q©O2€N§ž¦µëÖÒvö&6Eì#¼÷†I=ÊÒá ¥¦¦ ê7¨Ç×^Cì¶O¾!ØSÊ/)*ú×î””²‹û§ÀD~‡9æ„æ… âÇ6” Ž5;°/N<Ýu×húò˯hýú_ERÀí§Òy‘°PÑÌ]7ÿâ‹/ñsÉT=>22Ï3ñódѲ³³X?Ÿ¡ ëSû¶íÙ˜+1j1OFÄÏ¢ˆntø ˆ¶:ÒòåËøÇ3häȑԿ Ãhç!;¸aÃ6 gKÌŸ‡Û…‹[´huîÔ…¢YJà}ôàéÓ§¨CÇtýõ× ò-VCÄ“Y”qºVò6«EÝ °Úƒ˜!|Ê# `Bí©Õúw€÷åQóæÍÙ5ÛAñqÕé|Æ9y T $ŒUm7 ðÔ»w/Z¼øg‰/¬_¿ŽZ·nÅb};µmÛ–Ž?ÉÌôGØÌøB—RÇ8ð©æö”²ý•NGãï;.\_—ئ͚œ*Aƒª¯fͺ'ý–®wß}÷‰ª ‘%Àþ°à(æXÓ’Ù3ü}!9¹Y,ú…[ÓÒRéÛo¿¥Ž; ǃ;ônÁ‚AÇ=ñÄôóÏ?Ë÷5jÔXrp»uí."2“UG&!5õõìÙ~äñ}êÓû^Ÿ¡ç1R>â{AqïonMåø•á1’²›n½õÖ * 0 H\v»UÄ1@ [aj,2¾@’Yà=0.è:yò$ÿ¦MÜ=¨Œ½¬ÃµYý($Ͷí›E@¢x|1¯Ø? "…‰Ž?Áç1¡¼†Ël°2³2(ŸUr!«‡ô³ ˜óGØå<w¾ '÷ÕO¦|rð‚ ½&0Ð1„ŠŒŒ–Jhh°CÐk'Ný}±Ë-ÃhìØ±bÉ^è€j€î2dˆ\l“&ÍpÇZ¶¼ŒbcªÉâe°$Ico®Ï¸qãÁÙTfì~·‡Dï*CÌ„dƒëƒÙÈÓ!æB– Úƒ×a ¤¤ìa 0\P³fMª‘TC¼Xö<aòõ2¡ ÓRl€ô®Ö÷ø7¤ ôºÝîG¸Àˆ\à¿6 ¡@Tä ³à„—#píšµ´e+TÀd‰;ˆaÎS fv?›<‘–šFGgOŸ¥,fÌõëS›¶—‰g…ë›7>­ZµJoÐõƒù÷\ ß{ÿí«/õoó"=ŽD "r¡üAÜL0‹¹œœL1„àæA§oÚ´‘†BãÇÿCÀºW8Ë^sáJ|WxX«’NtŽ—iã€@Mœ8Ñ0¶<"jõQ–´ñq³NeB|úé'´rå*jÓ¦5=ôÐÃ4ˆ u«$À 7 bñÞRl׈ß¡qú±ë®‚(F- 5ÚýÃkeîŸÊ?[”™á *oÀ­"}.—âv‰eáK$XU,¡9!² ¦O›É\nSáe·®8‰ä3’NPSv»M$ÒáÃG…¡ jãâ«QŸ>½ÈÎ×7{Î\únö¹Ööí:PÃFwþë_ãZ^¬ó—±ß;$$\Ê» ,&SRv²_}NJ¼ØN@ DöçŸNݺu ¹B/â *`É’Å’á«U«ŽˆS¨äÊþD¯A ¤ž:A‘ÑátÇí£%ЄÅýʧi½¾KñùgX·†ÐÊU+h̘gÅ^M1fÌ4èñ2t©@꥗^i†…w¹T(¶²¤×§ƒ½å^×iÜ2)äýÍk:$^þûÈç²"Ò `á^`kAªÀV¸ãŽ;EÕŠÇ€;®Ýc(Xx 6Óø;ŠØe@x xL†‹‚m¯ñ»È È÷`"ƒë%êv‰få×~X0ŸÕÜ/âV⺠ÆPØÒ·ïå b'«ƒ#E|ðAƒ±Š*’C¬r«ÒŸH­‚0¨8š0áñN æ†ð{adÙÄ5ËÉ€·‹çàv8°_Ò®ð6\<§ >ñˆZ¤†Aè¼ü\Ê8Ÿ)!dÁ ò†,]‘aÄášàøHÔú Ä8=E]ƒ’„Ql‰+N÷z%u¬½ƒ‰?`¯êV6:Rà¥2@ÚX]<õÔBü06œëÔ­Ç4¨K[·l“€YfÆ9a€¶mÛÐk¯Žeõ/©ÃGQÛn——.¿¼ï7÷Ý÷ð  88ôu&þ‘¡² A¬üTp7†$ nvçN¥ `Ìðp»@<OðY ŸÃ"ÁR…' 0:wîÂh/–$Ò¢Å?Ê÷À³€%Î3æyz䑇ŘAí|Ó¦M4ð«A(øÚ¸a,ÞÄÆ:ôFúì³Oið C¥2 ×µ}ûvºí¶tÅWÈuÀ×GÕÍÂ… é­ñoÓwÞÁF×íÔºuqÍ(ÕÓÆ¢ô\p¨hÎÎΑð0\b—ÁѲˆVzh”¡Rà :ì$ØOˆ ß?=.NÝ@c)_˜éŠ+úӌөG÷ž"g{JaôÍ´¯ÙÙ$ëS«v] nÏÈAúäädóÚæËÚ=ùēԣgo:ÌöÚž”½tž¥@JÊ>ê߯ÿ7/½öÜ…À–ÿt6LnG„†Bü ÙÑ"j!ž±ø©©'%âž;wž/¾‘V)Â]x^¹(é4zôÝty¿+Äê?ºjñ’ÉÉz ¿…ï‡Ø¾ýö;Dw=úè£ü÷í(Ξ;w®a¼•ñ¡f`É?õÔÓbù¾÷Þ»ìÞ –€S“¦MÄå‚Ô™1c†ä0pí_}ù•øúmÛ¶c鲦Lù‚ç1êÖµ›,èî])l‹ìa©r„ApBŸ!÷Và3Å¡mÚe„«Èî¢]uÙáºZTA Þé°ÂnBh¼q£†T»n]G´x.¸þóÊÍÍ¡];wI¥u½ú E .ò‡îg@–JMvává…Á°AÈ9”g±”ÄuèО^yéU:}æ4íá{k¸uë6jÖ¼ù7Ÿ~úÑï l‹ÊN R$¡@3"˜+Q©“X]õÅbúæÃ? ýû÷ ·J1§¡›Üë®$–}v;w酪3§‹zÀ Ö*¤sç®â¿ã‚ÜO· »•Þÿ]É —€ð¦2:UØœnƒ‰0t»ví„èÇNœ ø¸x:ÇÆæ#GJìvË‘#‡EBA|þùgôã‹äú®ýuÝz›{ø=)õô)ù~Ÿ{äç'A$Ý2&*BÊßT,@©ê®¦Õ¦ I~ ’g1ØB0«ËØèXJfiЦM[jÙ¢9eç ¾ÝÓ—%*ó¯mÛâóÃŻ瞻¥ ßÈÆ+`¨m±Nž<.v¤ 2µãYºÁ•ÄýœJM¥~dµøõêÕ+n½ € €†f ð{€i€Ì Š7±@Èèýüó±úA,¶aÆԳg/K U?.\@³ç|ç3%ùÂW’œ\›^yåŸ ÛœWT[ÝX\}à†a{|ñÅd1èj׮ÄÜB÷Þ{Eü´ˆ YâØ«ÇQð¡•PƾñÉÿÃû@qÈ3ÏŒ¿è§Å´dɶgvÑiV0\¥&€¹Mþ"ª-GWŒBªëR`€­¡ ¬~Î…=¡¤=¬ñŽö̵‡`[h+µi¼ÁQQWHXe2øï»ïYO-alR™dã6‘NÁ%‡„ysì[²fÐ'˜öíÛK»÷¤Ì>~üðà  ‘Q•Â7&˜U’$âE’…`ѧ ž²Å± w#+öí·_ 8`hbAÀ½ú;v¼d uÀEšš­~m¨é&NüPz|à!zûÝÑ­W Èyóɪ–µŸ~ŠÌ›Ki§ÓXEÜÀnÔ"9¼†Æ³ˆCzÁ àu¨24?_©NíM( `+‹Þ…ùâÄkeRÃ!^†ª&.±"På¡xäúõ»œ¥ãuôü Ï2Ã4¢[oIëׯ¥j±ñR¨òàƒ÷KÁR­AJ ¡@5Œ(¶AdQ<CpÌ3ÏSÿû$R};·ïØuäø¡€£ahhÀnÅà €ïÿgPñÊQý2gîwôÃóŰQ5v6Y Gô릛nò…”Ýæ0þÅkJäZ$R¸hÑbšÇFò¨Q‹ôâ Á”öÅ `; €UIÝ>¤t¶àz=òÈ£Ò pï½÷KiøŠ+|efÂ]6?án „Ä}#" wE©0T±6pµS !UÌŸg#%ñ™bCíàž\ºuˆ4Á­ uE!v“D@0mðÁl“<,™V¤š£ØKª™L3¦CŸLúD®ž„Í®RвVRˆêTn$ÿ>¢®:t‘êeØ0ûØã9xð m\¿©8*&ºëÖ­¶üLØëøa. Ä*ð×€‹4@†kÖ¬"†@DÍIæ’*xo¿ýŽ,`Yw® ÷–ïØñRy¡¥ªn¶oß*×…›÷cΪËRÄË{ ÿf@ÓfäÇ*ŠE€‡üŠ/g7›Ž=l4pxŒä‹*ýÆ}¢Ó6¯°XU/A%AÏJ(îŨG”*h~ŸCÊàU?ƒQCé,)eWì´tœáGU ¢Šd‹KŠÄÐÓ‘Î.]»H¯%ˆŒk {@É<Úé‘GCPEZ]eÁ(Hþ.¨Î;Ó³¬Úr²s\…ylØî—.d£ÆåõZ´hÑ©rˆŠŠ8úDÕ,eßÁâ˜ýÛߊ3XÐ_~ù¥øÛ^#¨Ì—§*¨£@0vì8jÕª¥DýÊ7šØe@€Uâ–|I¬›.ÖЉ!4cZ¡³áûc¡˜cì1 gΘɆßbm#ò?À˜˜Äî`kñp@$p0ÚËDìJ±i ”e!(ãg¸º²Ùc4Œ Õ[bTC8Ùe„AWYO¸§°Êáiœ?ÎçE +’½ÑwÝ#öJÙ½¤‚DÈŽ¾üòËtààÃQ@÷, ðè£OH2Ê%Rœ¥Å €]¬ÿ÷Ðλ¨{÷nH¿Áøsåv?`‚¶Æ±˜H° "7Ô…†… ±!Œa£˜@ˆŒŠѦŠ&-´zõ*^ä…BpusÊ…BjT_,¼Þ½{Ñý(‚,3î´ÁW>ᣳ‹Rr#õóQ¹2+ b:??—íi,-¶ á¡›Ad(H!|?ˆ‚®¢¾oÄ2ð¨Å´Öñw™®77’è ÐÒ ¯Ã5C0 ^bðzâ«ÅKNó*—"ò ‘÷@ÓìwêÔE‚NRæÎbßÂß½hÑBZ»v­ ¿0oï^½©k—¢÷Kù÷ÔuXDÍ€ø8·oÛÎëݲs²¾™>ýÛáUÀ«¼P/`ññ¡Í ñmÅñP º•0R2$¯ÃZß»7E,N|º ÄÇ"cñ@pXªzÑð:\>èþÜÜ w ÏÃ8DÈ7;;S Ñûî»zôè-ž ú ,V;¯{0 Ô‘–N%$(Êï•Z²¨šHr‰´ж±=Ô£gOΘñíÕù>‹”¥„Š ‰r0ÝÜ…d€ z¡`E„‡J¯bùò¥¢óa,ÛAx»V*<‡¿±(0þಸm‹¥ìr\ îÖœl÷:n¯¼s±ˆ××r¦­rp9Dý”)S%fŽðilLœLˆÑï?°W¢|±±qRì/Ã,J¥Sy|”ƒGD†ËýÀdõ$q^2u¤l5B©øß(g+,.b]œ#¡ãlöáñœ¤‰*6·îÈ‘CÒýSƒ =ˆ{J¤«Ë~œÅz×n¹¾<†ÎEHš9 ƒ9ܬ"ߺØü,´—½¯mÛ¶1sîçïé‚{^=kÖôîå59ì&ÄÀÝXÄF;þ —‰ŠŽ¢Xý±ÕbÕÙÇF¢gæÌòopºù€.z^:£l ‡¿;vìDï¼ó®ÑÖåõq?¸]{Ú ¬(Ìœ^6¸¡¬IéÞ)ì ¤³%ÞºUªU»Ž¤iákoØð«T<5jØXï4®Ÿ‹áûBȶNdQu°•(a«Z¾—{ŒFPÝ\jt{´Dâÿ]h]ËΖ‚ ›3·B" ²nß»/E®ý (!C¬Bº­ÒNÊûžîjÛ¦åäIU”ÇÈ4êŠ$ ÝrŽ41+!røIMÀ¦¥´¼E˨»Ü9kÖÌ–¹„¨_e@¿Ÿ€¹F @L¬²@èI“>) / ‹©Å¿®|Ñ=ªÑÃë+=ú.V7‹î?™Êš3+Ü`N kƒQˆ`Ô) aEÇ1íãÅDD V=®aöì™’C(8:º9™KaÍ£é¥V­šÔ¤IC)uwð=“¡Žt©÷Ù³çÄ­CöRò.”›y| °°øQAÂŒ‚5Ä9úÔ´0U+‰÷¢o0ýlºä3²2³…«BP­”˜”$•Ò©{ìÄÉc’?dƒí@2•‹YLõSõ…‚ Z·îWñ ÐuölÚQfÖ:°‰ÐöO šJr|ùåTæô<15§ë†H@s©¤FUÇŒ¸Š"Ò¼RLu€…Ägu°ÇÜnåsþ¼TNÔët¬V¸¨£M›¶P³¦Í%°r:õMùò ¨:êо“,,Œ34ŠÔ«W‹¦Ž,2®G¦Ðë€øÐÇp½@XÔFb-t™ê|òH „Ö6®ë†ØºÙ,)BùW±ˆv„ Ùžóç2Ä&$Z½v•ä¬;FÍ€¿õs^¯×ç ¨^>Ñ©à&™¼òÊ«²øŠ“-&B—‰ÿòAUYc<6}ÚtIµhÑR¢„“>ý˜7j*€€d‚1W39I¸^÷1@7ÃUºùˆ€DŽ'lp¹À˜#ÚÐî!H •-Í÷!— ×™b¯² ¨Ú·ÿ 4¹¢(uíºÕüÙ³ DÃ,RáGŽ”´ø³Oau’¥bb¸[™dTLH¥Õ²¥Ëx=ZJƒIZZZeˆ:„‰˜U@5¾H€¹sg‹ŽÄ¢èa ÚØƒÀ©³wšó56ʼnÏÁðÁ‡}ååæ‚ 0ŠôcYXÖC&|(éì>}ûñ'Nœ@íX Ô©]Wˆ·µ6ëwOt:*sa 0Èh©_¿Ÿ ä~qýHvÐßpç@\UÕ[jت‰Tf°$k$s¢DbàÞñy€A1\krr-v©c…Iäþ˜jÑýs*UÖcý†uLôC-ýYl+À^:ä&é›`»ÍÃ(«V*kCú±ÇpšÝÌÅK–ð´¥C‡1¬ël¥8‹X»ªH`Ãn˦MëE/á± f=¯º³W‚´ ÐèÞCܰJÒ /¼ C§Tû´6òô•Z*ÿ $¸Æ…?, M›7Ó7“ÄÔø·Þ”äJ­äÚ¢·«'ÄóÂ…©TŒO©Df0´hÑ\lÄpÝ ¢w(8«(Å*¿#õ" ,†Aë‘ò2\?@_ eÙ.YKtÝÃ,E•0<„ÁXº:uPLdŒŽàZžI?#¶‹Íæ'X(Ÿ •”ñÙôT!6ÔØå—÷£ví;J€B Å€¸± îà@:—~VÂåpQÐÃ>>sæôßà8 fU‘¸yÓcyF*×ãÓóšàf„×¶€養.ËFìŸ9òvêÔ©“© ×<µÃ\ê5Bª.ßÛo½EW\q•4ª¾òÊ‹¬VjK}!®§F͉Ò)ãÔ)qr”[!Þ£GÑÕ¨YavìØ)\°(%׈ûhP2ëZŒ2#à…{Aý=šJÕ”Q æSÚé3ò½7¦Ë.k);H?H”ÌÁvhÞ¼•{p_ÈõïÞ“"ÖýŠ•Ëé|F:ÛnQ ii§ø{Zˆ$:äF¶qøÖÊë1W2{Ø ø§Ÿ~B%°Aû[DDDŸd4'UèD'í/+–K¹“¯KÖZßcÑ5t„6u¶ÌfäÍuœ®ÛàÁ7JOL )óýu¨ÙKÀø˜/¿šÊh?O·º“>úäC¶´ÏQçN]¥†>¶Z”DeÒûã¨À©Ë1D)êA 7I3¸ï ó•÷â–ÂæÍ›˜H-8+î R1vÜçè;ïb0u 5k׈ª€Qµd× ÄFRzrü6l¤±×ýº^$U­äºJZzJiûöTTXL‹/>8Í`:þŒx.íÛuæu ¤»ï¾G¹Ð•…ÑÕ ‹ÀÒ ¥ª94,®LD¦2ñª”8á›·lq©¹_[¿úo,ž¶ÌtöM¥KU† ¿‰ïQª F$\Êo¼™†*÷üã ¤®)¼W¸Ò’…’z¬@Å ó»tî. @ÝßæÍ[Ø=üUZéO¥ž0#®pÅ—3x:J9¸Å‹[ @k‘˜XE®•J€ –QU’,ö÷íO᱊ø’Úx#d*CM¡_mjPÖQkõ‚ôaà¡ MŸ…¬>NLÅl=VYÑôÐCJ–iT,tÇŽí¥´ @EêV9 ~æÏŸ/Ò×¥ YtB«ŒëíåËSø%–oê5¸Æ¨<ø,î ÷Ýw¿Ø½zö¢ŸýÈj¢†| ÝnáÂ¥yöÊ+¯éºk×Núqá"êݧùÙ EÑ?-»•ËOýº¨Fr¸m¤HM¯aà b#¥ìóç£ì-ƒ=¡D¥Ïš5½^Eœã©š Çbk©z7½0Z˜¹_'‚4€²Þ8»/ìªf…Éë×\s ö0ÚˆÊj+6…Z$é1áƒ÷iè 7Òô3hg?|äå²È ¤ÇŸxT8{ÆM’ÀÔ€öð[†Ó´éÓD²à:P) ÿ_¼ÕjK«,?£\ª‚¢pœNƨᑥ’FvI¢“_±¨¶ОŽÏBU`Z)¢ »wï”z¾éÓg²ÒŒí ~²Þ˜¤ºví:º¢ß•"þa# ™uìØ ¶Å²ùó $%|×軤âØ-9 5‰ ©cÔ"ÌŸ÷{Eç©f­ˆßìœ9sZËŠ¨² c ‹¸²F¸ò¨þù"_ñˆ UÞ£¬T%Ruß½œˆX"]A®ºZ¸X‡|+vÙ Š-^D;v¦Ì=—]ÖšN°¨"ˆ)üðƒ@RÆòdü:kÖŒÎp†9®Jn `ÛÖÍ’ Ô•/ÃÀZäkhýo–ÚOÕ¡`œ°Ö€k¯½FŒ±ò€LqU»fÍ* t`Ö†D‡GDÒ¾”ýlÐeÑMÃËÃx›>}†=Œ IâÏÃíÛ·Þ/M" Žn×A*p<æ#±»…jìäF(/©Þ=‹Eé[¤_Q¥+ãêÐKhWc^ Ø…,*,`¨5’ê)ƒq Nß}ç}êÒµ«H<tË–M2ÀrÞ¼ù|ý×2 Z Ã|öù§T·v#©š>cmd‰†P1Ô¢†5’jŠä,,(ð1€ˆè¬ÒÎËC˜½¡¥3f|Û¯"N31«W5ˆiVpõTLéЯΠj5 cJ¯[}â_{xÿÀײp­O(ê)W$"î_p}÷Ýw„ à›6n¢D&ì±ÇY*œdîj@O=ýŒ•³gÏe}ž!>¾—ǶíÚµ€E4bÄ­‰ÃokëI¦˜Ev&˜“ Â[‘ô¶‚Ø€õç÷Ù* v1*‚ŒÑqÒÄè`0¨ö¸¼ì,•-,qù¤îöÇÔ©_Jn\ /× ÜŽq6ˆ+Àd¸öšALü ôÝœïhÿ¾}Ô®})­Ûµs·4ÒÀ›Ñê284Pò°ΟÏdæFÙÙ÷3f̸¾¢P¥@ “0Õ{RvÊ”0]ò¤‰®Å¼Öùæ@¶´Nx@x B½þÀ¥ÌÛÜ¢j˦׃“f͚Ʉ¯Aë׫ Ô¶m;øš\ôÜócÄ熟½hÑOÒ'Ô½{÷ß;bÄpúå—_ä~5€ýà™ðkÒ}­*„ ó¥gx ƒ£ƒ)>’%–aJ·œ6B‘W—[ì¢ãçØÍ(¢ÂµG€…AàáïÍe)…˜?ŠIp'¸w¨84µÌ`ÝÎë‹XƺÀbÇõ£A^J둦FVó_ïü‹vlß.iì;GßIÇÙ&èÞ­‡Ô:úò#lÁ„ ÁŒ€¨h4ßæÉ`D9T5  xâÀ=âB!¡è@9ñ£ÓÁfPƒ@“Ö*@ïƒèËË+0uì*â« $d7ù7&ÅU‹“¦p5‚:W^uÝsÏ=2wç믿–.Z¸]ÛöR® )öä“KG‘–:¸.-šý)Œ³"Ì,.-¡PÌö³Q˜ª*ËÈ.¤‚B–^F¾¦;Qx°ƒ¢#‚)§ÔJ[çÒ©LxE|ß³_ ƒà<ÁKr9¥‚WK‚N:ÓW_}-Ľ-Y²H¦ŒÍšõ´Ñ7kÖDj'}:‰ú_qKƒo%Écc tóÍ·H`G¶…tzÚãòˆÀósæ|Oy D@Ìš5í¡¿€HIv:¼_üh•¥r:^»€ðã•T ,ÒF ÿàm^}õ@s×ÉôЊ6€²”Ào£ÇÜŠ "Nœ<ÅÌè¤7ƾ.jSÈ=C/ ÆÉ¶bãJûà>ø€|—YìKW{5á1ÕXgç“•9;êÉM #):ÔNéYù”•çd‚³ ÌÄvØ=Ltœìæ±-`3\>ŒÁa)Æþü¶Ô"JIÅhXöŽ`)øùSvÆy™PTäu »¢~øzì±Ç% o!lèp„›oºéF̓Ö;¤§qÿï½ûA wèØQ€Ý·ïª¿‚TV0„%"sfÏ•H`H(l‚ü×gΜþ|9„‡G³Û­É(PLqäȉpéð¯íf]¯ B+“Ú­R!åBÁW]5@º|U¥0ù CÊJ°•!ˆŠž+a®pJÙ¹~—÷¡G}„¹ÿ4sÿWbLA'öèÑK¾×wíµùýG€¸6©Íg‚¨ÑÕÔ̶â1™%@ƒ„ ðRz6¥`.giäg÷R ƒ9„·º)ІR€UC¸-”S—Ï_ê&v¤•ÒžÓEÂ….ŒãëÏÉÊW¶ˆnÁÀ ¬S§®Ü+æ*ó¿ÿ~¾¸ÇøŒ…ð2âãÞ'iù€À–píhÈЛ¤ùÖkQó…°·ÚÆç²”ÇÀçŸfŒÿK€ðs ±WŒmÕë@‰æ~s&PGÍ¡à²Þ9‡/¨¹ ÿ«hРëE×)Ýoõ5榣ê ÛUrå,ýãõW$û¶zõZ1îð7J«P IñλïÐÛo¿Á¿ä+Ä@=ž]î;„X åefPͤDró½$EQT°•²Ù;)(f£Iƒ=¹«¨»ÝEÁ~–. ´x 8!Ø.rÙ(+Ÿ}ñp¶'"¢ió)'Ï,¡¬Œ,*@WÙFÔ`poW_} }ðþêäIöýUÙ:ÖvÈ„>³fÍ’Ñ:Ӧͽ¸vÓ  ‹ Éé–òý¢âŸ@ì†ë{gÍšþqE/ J!Zì?"0uªœÙéùæÒps¡ˆö´ Ðj¿‹×@9Œ@è~¥¬å¸8Ö?ö%Ú´i+_O‚d±PX”µ#P……Aæé^{Ý@iÄО‹ýp÷"bb¥1#†Ei8\–ÒbJŽZÈÄô:™¸~^Š`®.aUha X(À¹ßê$b#ÒãÕacQ_Rj£üb+–$#é´…ÒÖ4'¥gäSÀÒðìLÙUkdýõ7Ô ACñ~V­Z!­bÈ.ÞvÛ­9D'ñªU«e#.l48b (+Õ© EÑÌc€?{.EEÃgΜùMET©$ F fïߟ"F ®ðÑ…‘æ8€ŽêÈ V:F®SÂø½Š€ÑSPP6)ô·C¢¼ò½í"1²bå*>|=Zæ  ¨]»Ö¼°Åb\AÒ NpÌsÏð4÷È.!6véX1Ñ 6¤\«ñÌý6b‰Æ«Äe%+_[T¨ƒìpEè!D*›%ˆµ”ìÞ€“,|ì)ìæßqÚYz°ºe‡Ññ\ÈõRÚÉTò0࢕&µ öPFÒ‹/¾,׉n¦ÈÈpZ³fD QG€uúê«/±‰?¿F AІ< æ È ¹¡ÂL6ša°·cáuìΫ€ƒ €zURÁHuê/u±§¹À\ #„zʆ¶TÍ^~`‚  Àè6טƒHx/’@Hó¢ßoܸq’Ù[µj mÞ¼Q*eP7‡’pTäŽ9\òþz¤½æ~4y„²q…j¡ˆ`JŒ§œŒs$ÑýôS±„áâ{V…¡„ûAæmðàAbêk”É êµ±µE9,Ž›0hås³Ø °¨&DôJX÷³¯_}îW1‹aâ`_@p¿Í%' AHŠÒÂR™]\Pb¥·lÙR™$#i„ ò{S§N•È2‰;wñôïã?*ßaÿâ ÜËÀÉÏÉ¢NíÛ‰1 nw¶ƒåEc;ÂÃúßÎâ=)*Šò™P¡€*ñ”P.ˆ%AT(Kþœû±ê±zA| ±“ÂRÓ.’Óê@g íTêJ{wïa5`Ç&Pb¸ Z«ŒÉ{ø¡G¤±d«ºÄ¤IO#­ ©†ÙLÓ{.¥çgiÀ€«ØÛé)k-É)C 4sæ,ÕNfñ:sr2³û|¤"V3AºV þtèà>ªQ³†Ïú×@ûýº>°ÈØÿÎ\h–2óÆø~,@Ÿ>ýdµv͆ŸV *{ÀFàú~Þ÷2¤òÿø‡¸J³pÿëÿÍqcéã?R=ùF)µªêU¾¾?'sJö§Ÿ}úJË8Ü@™»k* 5«µñ¤›ž~úIö°‹4RJ­óGâÄE ·Ýv‹èLm<êY~ 6òcãÏÍïÑ«;>~˜¸bòcQoa®t  Äs±XE­?.š×¢€½Böý½? ¼ ;ÄñcÌÌ+”Z´hø³·ã°ûøSóHFÍhõÊ•ìNzÄow{ÕTq0ŽÀÆBPªêÔ©“DtPæôî#ï{á…çi5»ƒãÞOëV¯¥–­Ú”M9åkŽ«+íáðà»=®}Ó§ƒÝÛ]1™Åá¨*å–JϺËU™AfwÐ Ö6€æBí è1/½zõ¡›oVÐݾ:®6W¡ ¡_äЇ¿UB¿(£°Û&”›nºi¨T×ø #Üj€¦|†*¹GïtúÜi*bNöcb[™ÓýYœû1¡ü¡zJT7pæ(a”>FÚcÁ%MÈâ¤,ñ„VæõS;ž@–ð{ý‚©f½´üçŸÉc±)#¹`hÇÄTÝ^±ª9œŒJ`¼çÅ_ cGOP¿Ë/—Á—÷ë/¹171!žÖ­_G?Ì_(ÒJ]¥§OÿºƒO–E#ßµÛmW ÖÞ}»‰*âTÖ¢ÛÂ5ÌE¡æª! ]ŠßÔ6Äù°a·ø"¿7% %i󨀨»ùæa¿êïQƒ8z9h À@£f/rÛ­;µc‚ºè|úr Í’ÀÁjÀ©"Ìñ,Z©±<ÈŠQ4¬Š\Cu€ñÅ×&{ ØñèõŠ 93í\Õn؈AæÜURMêÄÌ!E& €z¿3fIÀ0N3 Š!Ž9NI5’¨e‹V2`Æ$'Lãi劕¬þóß ž-ž1ãÛþ•@M© ðúÞ}»e¤›Îè$^`Mtíj#PKó”0 @Ü~ذ›%¨"c>ûB]O€ñïbùÌâÅ?‰”>ü6É`²h‹ͤ0õøølt‰ÆŽ26†i_¼˜¥,º’)©~2ۇȆÖ'ßIþ, üœìê1ì(á“qÀFœæ€%fÁ`´[¥HÄ ˆÅ+04edÐåW_M›7nb{åˆÊel*¡m HØißΣ™MÄôQ ˆ´7T$ÚèôºíÖ‘,ÛÈ{d‹=¯jv‹¡åì9,]ú‹¤ïl"}{seàIæ”ñU™²w—ôjƒNëx2» º@D×èP0nVïJŠò©Þ½{3†I¶ 3éjÖ¬)õêÙ[¢|ßÍž)j!^€h#­Ø&ÛÊC 9`@ÆÒØ]To#;Àæ‡æ §Œt#«¢;¥€ÅbSÛæŠþ7æ být%2|ú÷ßÿ@žC¿bµj1R ÷Æ-ŽÛnÎÆb2 »iåͼÆFH…†IÍÀöm;%5Ìx…ðre¸ž0§*%a¨¹ßµs»è墕EÍ¿fãPÇt(VÏ „dÁë]»vc 0\þ†Õ;{ö,yý‰'ž¢{‰ù¶ì rï½÷ʘ¬¢GŒ~Åg¦NýBæå""Ö¶m{¹‡E‹~äן’…Õ®ªŠ²`QjcxýX D„² ªß®%« l*ÄF˜pKðµ`sò"c—p ‰ôZ@öRãòd žÝ_JÅ`éc@SbÍdú|Ò§„>^|=½ò¤”šÔ ;ïM>ø¬áúõë©~ýº´dÉÏlëÜ,õ(ö¼ÿþû¤#èP‰ o„ŒIPýÃ4¥ùóæÓž=û(œ]V¦ÁulÌû Bº¬©Zsh´lsŽÈ”y”ª¹\‡ƒuM€Îš§„éMšt"HWç ¾ sóñ7Š$Q…ÊY4‹ Å •B ˆ=¥~œÌÝËtqTøÎ;Ç7¤aƒFR„†Î[n¹Y4µPv_öfi`áÅBI7˜í’ð`ªÝ¼!eœM£^h¨'€ÀÄgn¶2¼N%¤ˆï•Ùvùvæp›ø÷0ò ®ºõìE“>œHiéç§’N 9}ú_bÁªm ³“ÐR¦¶ÀݨzV­‘÷˜9£I¯!ƒo’̨ ‡Àt—š‚N˜ðÍ×_SZZ:"—ÅìJ6c7ùðoàp„6 ¶ï±Û¶?, gëtëöÍÒ“¦kÝ͹ s>@{ÚÀ‚óuBŸ‡èC—t"vÒZ¾ü±ÐSËQ(‰îa¤Eñ~ˆò÷Þ{G:}øA¥/ †:"b ;àÎ;GI$ RŸògQ "R€ÿöÀ_g#ÓÈn^lÕ¨_›²Ï¡¢ÌLQþØêA"&¾·Ø-‹ 3H:óQš#PƳy˜`Hd#Qª5iâGtôØqˆÇ(mÖ¢öj´þG ૯¾£úcåÀ8H !„çôýûJìÖî5ÆÅxÕ°‰ê q;øì³É2ùÌáïHÙ¿O+VŸ¥¿ñ‘‘‘) €È?@\5‘M‚€ZTtõd3c£Äœ Ðéc]è°dd»±‘„t(.„ÃÆ(ÛÆ¢@ÿ£ü ;•víÚ]¸±€ï 5ñKU¶:u”¶o }À‚aPõk¯½*G«QC"üD X15[Ð!qã`pF†RÆõÉã,¦¬ÔÓäÊÏ';¶©A"hè±È60R[»A"¸`ÆÇV£~}/—xÄþ±“§ŒõòÊxW5ZNm'Sdä'°XOtHÃîÁú!—û×_×I¯aÛ¶­eÍ^|ñE ¤n,1•”u9)X§š5dPô”/¾R=œîÒ·ØxÊDórfìfÔªJwðž=»dã5ÏÇåý¢G»hq_YI˜~?>«ËÂô B¼íSØåÄE-ÜÔ©S¤‘q{|¶«AÃP7‚¢kíÚ54~ü[ò»ØÍ[Óà÷›6i*¿…4`‚:О‹O - U€¡O, <(A÷—¢?r8¨N½:TƒÝÞR@¾0'›\E%*æn fÄ^2l’õs«æ-©fRM ÷".QÀ.«Í‰ì h$ÐEî÷+÷O5 |üñ$©jÆ:Aíµn}™ô `w÷ˆ­ï“©cûj¯a±Ñ¤1"¦»´kÖ¬¥üÄî`åäæµŸ;wæf2u³˜`alc´¬jo $’f÷O«€ŠB.4%L@wCbÓøô¸!ÄÀÇÇ{0iK ZŠ–ÔèÓO?­>ÙühÙ²Ÿe·°gŸ}Nügt×®[·V"„H*!€ ÑG}È–õ{FŠî;`;@cZ8Tª<ü$ ƒá[?5 4‚ï¿AÝ:T¯V2E…„‘UÆÆºÄDT1£uùD5ñN¶ô±0²tÒ<ƒ`ª‚/pA3㮟æ~¬ b°Õ’DØ¿@žý‚Í7!EÐöóÏKe8tÆù,jÌ÷/Æ'Lç°[ܨqš÷ý<– {aþòõ×S¯0BÀ•ÈúÙÏÏ¿oUºƒŸ8*7¿7§„µž7{f·P‡ÍUÁú„-€À~BhtÇ0ø\.¯ø½Ù¬QM )„Eܶ®—@M@×"†€ÿÉŸNí;´“=va„ÁÀE³ŒA”…éi¥e Òµ~ª±“Á)=߯¨Z‹oï^¯„#ÃÃ(Žm¡(DFÑ Ë†Abò(¶ÍèáZÔ5\>2öÿS*R¨ M´îÇÚObu&j]ºt¦™3¿“ÝNñ<$ÄK/½Àâ?Šê²ròdª”ƒAÁ Áa Ã>aIRXXì¶Ú<½çÏŸÿ+´éiRÀÄüš%À-¨Xde—|´£¢`.ý2ŠÔÏ›§„™‡D邼 0jä(ïÊV°kï•íàÁ–zóeÔ'‚˜³g'…¤Øèùç_Q K­UçÒ3¤µ ?ý´ˆÆŒyÚ·Ÿ‘>:FôÌ*i[š?mʨSþµj!e‹Çcôâ+×KïZn5v5Çžæ¾ÏzU·Û7KÁåsÿtTÏch&ö;ÄÚ!ä6¤¦|Þ2ìÉ[`vàk¯¼J\+Æ_zú™"ŠfU€6R‰³HÖ`⇟¸cb£Z±bÙh½ß@XXÄÛLÇ«Òê’)Ô»$«Íœå@PÙ”°ŠBÌn €÷Áj5j”© ¤ü¥š§„DèxÁ¾Báòî»ïQíZué:ö ¡>ôµlÕBfü`ç1•4H¢Ì™3»‚*0I_°MD7Þ¢¯Á£6…4&[ûªoŒj1ðtÿ’Ú+ÐcDé̵Nß:è†ÔôMø`¢¨Pah6mš·ðzðÞ7ßËR1KÊÀssrèdê êÕ£Ô ;ºk÷N‰®_¿É‘qö1v£¿â¯+ùC0qs8þùGˆ‰‘ݵݰÖ7"Î< B‹{³0—Œëè¡ÞTÊœ °:vìÂiê ,?%LuémZ¼’yõÕWéÞ{ï–é]( ;öM‰•cò¶®íÓ§LäÆvõ²åѽ÷Þ#QÄŠ ±lF©BXäQoeT'—ÁÌíjz¯?¯i–¯GvwKJÛcôèC{ ø.6ô8"… Ô“z?¬ Zü²9ÔIzþ¹çej¡ë1åêEœaÑ"˜+6&úõ±ãÆN„MÎg±¡ÿÝ´˜À7úûN¯Ê”°È¨(Z¹r¹˜BZ˜CÂÕ€n óm¹&›T©H –˜|U`êrÕ\oÞªOA à{P¶mÛ–ï˸dÞ@`xß³!0Ás@6­U«Ë„ ¸žÑ£ï5QâzY`5@t»˜óåÞ/ªÁ˜Ñ#0q¿W˜CÕÿ—'¾S Ú‰?–2{\\7Œ±‹‹‹eïfD?UÍD=õÔ“ÒàÚ¼Y ùnŒ²…íÛ§ŸŒëׯ£S©§ÎåççÞóË/¿¬1^b€@€•€ Ð=00xeUºƒa„­f«;$,X:iu¨·â˜ ¬lF*Ȱ‹®ÒÛÌ!ËÉ5U¼¬ÌT,ÄÀâsP9ƒÃÏÇÂcøÂË/¿B÷ßw¿Ì  êÕ¯ç«BB4sþüyr˜Ì…Òks‡p™40T!ä´*þ7W(ûä”ÇkŒÂQ()që_Ǻ X5bÄ(yWaéczf¢û¥qªªÙ!M“'A®(†0$Àæ-%r ɹyËfÄ ö¤ìºƒ¥ÝRCÔ» ѯw¾.7צÜð4 ÝÁDvüe˜Òžz·p]í£­s-€9¤€G„nÃùÄØt ©›{üŠ«VMDµ²lÍÜï-wù ü •°à" ½‚˜ÁÆxÿgŸ}.¿ƒ9?XPT#†T2¤†ôß·jMcž{–~ùe¹p=ŽÊ¶’WÛÁ—íu¤GÁ—G€±?°GÞ &j‹<‹¬K{öß1%}ùr5‡]= $J»1©¤oß>Ô®]cKÞ zàû¨c‡®R€zìmSF`‡ýìçõ{uÒW“vÄö@ë}/ýøŒŽŽÙZûÿѤPˆÜœœ,_CGÅ)ašë+J7@¢¦aƒ&2Â5?7_ªWñÞž½zˆšñ=†>…åo3öå#C*@r`a0í3JZ¹ÝR‚>l·fíjjß®==ñäS¢ Ð@2eêºòÊþ ’£¾}÷ 6Õ½:èÓO?ñí¢Á\ùa—‚³бÊ­NpXÇk¯½^6ׯZ€xèüA›7¦¦£Þ¿I“Æ2+Q7®bÒI€5kÚBúànnݶÝONVŸ+BB‚>þì³Ï–U ¸>ËoÁö;p$$$¦Ø¬öºØø!Ö J€ÄD™Zµÿ^‰èÿÚò×ù­ÿµ]P¯n}ºzàµ2ô[³¢4D*qº„ za%sè¥2ËZ&ð Sñˆ‚ =¬B×$h¡zþù¤Ì\m½O¦…`Cê´´T™ îƒJ@E ú dAòIo ‰£â€¨ªÚËÁ!;š1!á¯#Ð{[ËAäcö ôÇŽdCk¸«Èu`­°ÞcÆ>vQFƹ…³fÍÂnÚÀ«ŒÛ½ºFK…¿-±±qËCCCzË|\øÃ• z|<ñE°‘²BbûtˆY ˜Gn55Þ}û÷fŸO?†o*Ûîg±Øýü,EÅn—Ǩ4ù¾5ĸET²D*a$æääEôÑÄ&XTˆ~„•±I3†C¼ûö 6mÚHÎ=%ePo€áÌH,A"àP*ÀZL*›Ëkžz¢;™µô±5j,ÏW^y¥D71´¿.0S:µ%†Û§gÏÞ°BçøqoÒ„'lˆŠŠ)â_>ïµx6x½ö_سÏDpMü?äø @Þ°…GF~žŸp« .`±ª âõ‘Q‘¬£Õìüù æÉÜ`³x7À\ªgèwèБÉ뙼dÉ¢• ŒTþLUpOþäaùƒÛ¸ãØ€º¢ÿR6…y½ß|ýÔ̓øÛ¶mŽGžµmÚ´–¸J@LìMŒÌ$>§ÓÉ:°.X'$p0»šHhVEÉ;l“Í›7Ë MpÈM Ð®^“&Íd°Öo¿ý6»·/¾ãv{?#eÄÁ’/1N—qj=ÿ§_ ?ƒ##¢§ÆWOÑÓº‡Æô,fà#±€ý’Ø’þÞ÷{•M Ó*«= ­Xo_zé…òGЍ,@áú3^E ˜ŸócN|cìØ7‡awr¨ŒS[¼x íIÙ-E(0@a× ª@ö‡ÂÈ—b¼,¶™EéÚÌ`ëèYGPAÈ9àyL+GIÀ„œ>„u»uëFç3euRR"ž+äµAƒn‰ hµÚé™gŸòLšôÉKüÏ/LÖ}EŽ×DÿÓë§Çj Ïè„„¤…ÕbâƒÓ‘ìQQ02ºyíRK‡]1¡ RSOIû4€a.7oƒó¡oºiXþ”)“‡8pàe¾ ZäÿXþà5«¾G>ž|ðÁ‡ž~þùeÖ.‚3˜Ç²)ÜFµBmÀH<>]ŒD„V¡¯A b nºñfÉÀ•Äó0ŠQœ‰®æ­[7 ˆÅC!*2šP“0Zk×®%[ÓaÂ8v%Aêek0xƒ¤-íþûïÍZ²dÉc|½?P™˜××’ò/qüïìP‹Áß§aƒÆŸ„††[dc„@^„…‹àÇ(¶XQ€çÑ¡‹-ã¡ët²Gûÿ >¢u¨a»êÊÄ:â‹/¾Tct§ úâ¤J|Ô¿áð©6ãô3Îì^½òþûï%a]¥„®Œ3÷6µ‡Dæóäùî œŽÀ º}Ñl‚û…šDç1š9qÏjêY°Ô4€ø$W`°BR@êÀ¾Â÷¢¼ýé§ŸÚÄ {†ŸÚc¬KEޝ’q÷o€ÏȤ¤Z·²nDåéCùC}9{ß–1±ÑÒŽ„ç ã€vÔ®ëÁŽÈZ!ж°r÷¦ìÙ5dèà âg(¢2]öwšû5ñ¦3‘í‚gxàÁwß}¯äØUVSÍ †ˆ9…ãŽô·*Ws‰´ÃÂA‹õwS9UDRï¹AÁ!ÁÆ–4j«H€ :¹}0F¸à}‡¡±c_/ž=û»ÏLH…m¦Ó ‚¿•I*Sa““k ½Ÿ oG— )€ý‚cØÔž8¡Ò.†ÄNMb _°R^nfø;ï½÷î‡x1Жœc€«¨ÅÿßÍýfØ ø›`7Î>uêÔ»ïñÇoŠ’2Ýœ‚Øʯ°í:æ A¯ƒó±©6FÑ¢¶@¶˜—ì¤Å|°y 8(Ø„´À@׃ãQ(¢7x„„€/?yòdÄ–fdd|DŠëµU¯‰oãþíRò7F ŸÁpU«ß!*2ò>‡ua¢½(!±ºFpc€ôíCŠÁSà r%W®–o¾ùö_Û·oÅ/ñ‹Œ›ûKÌŸ€Yü› Uþ=°^½ú71²9ʱÔôHx|ð¿a@·CÊ¡ÈDÅ:T”JmÈ>pß1Å|bH} Ü  ìÛ—BS¦|á™={öJ6(¿æ—ÖQ™A§­{mõk PÑÒÿÛ A€­¸¡ B 0ðͱ4¨{mPPÀ@oÉ;ÿ[Ѳk…îÙÓ-ΰŽq?~âøÊ•¿Lf_úGƒàù´îÿOq¿ù¾Ì ÐÒÀf:õ¾sx¾gttô Þ½{w¹êª«C`Á#å­òõžr™>ùÓ¶vê0ÊÃ,#l¬Â¾èbÆXÛyóæÙ¸qÃ2–sø;LD5‡nÍ 0»{;£ü&d,¿„@ã1ÀXœà µa„w t4 ‹ˆ ed;ÔŽÞn‹Ï6|N³øÜˮ҆sçέ%Åñ%pSªÿSÜ!˜‰®­¦÷è÷'ñÙ…U\wöå[µnÝ:‰OB¶ñ,ÃÂÃÅ#²Xl’ôÕ>°#ÔNd§¥‹iË–ÍÅÛ·o;ÊÇ6Wðwn eÿèû®süþwãø7Ì‹UQdjÝ©9§•¨ð`¶ù†L|«[ma™Ëç¨|ÊYáü!ú@`&²™ð‰_ñ#$óÙ˜¥aVyuX‡Ç°æ§Æ£äÏËj¢˜¥^.süV˜ÀqODìNV¸ßЧ§ÂßžJžÿ¬Ó…'æÒºÒn:5÷è÷Q%7`eú¬ˆæÿñ+Þ«¥’¿/ôýÎcekXñ~¼¿óè½À¿+>WÙ÷þí‹r¡×*‚Á|V\(óE{*9+»ÉÿÅq!Z.ðËï|¶âs•Ý—÷Oüíýƒïú/Æï½Çò;Wv#•!øIø¿²f}ªzÞ?ùüÿ䯫úþŠÿöþÁ¿ÿ¿|üÙµ2ÿg×áß¹©KÇÿŽK¸ÈK¸ÈK¸ÈK¸ÈK¸ÈK¸ÈK¸ÈK¸ÈK¸ÈK¸ÈÿxùÈ!#ìIIEND®B`‚fotoxx-12.01.2/icons/next-page.png0000644000175000017500000000151111701011016015337 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>ÄIDATHÇå•OHqÇ¿¿™qwvuQRñ l»–«aóP§Ð · º]"èÐ!è-H‡µ†]:F:%t0J íP‡ . ‚ûÚÕÜÝiÍ;óûuاYW!O=ø2o~üÞû¼÷~¿a€ÿÊÂãñÛûá÷³¹-2:(2v|¨ûô«Tê=ÝK ·ß‚::Z/¦[|ïºÎN5Ã'úÅPO爯Éü|ô܃Π„`` ,FŽôD Ž[ Fã½»í'ö—ptr…ëVCˆ8vf9IEg«kÙ º¼’)QÎM¿žøÒ:ÿ0jd°Ý+zÜ«!ŠN!ýÖÀ =àÁ/©„oˉ-FÉ¥äÜ…Æ#"<ò%k’ú—rEÒo­:*llêðìkáÌ£“W(¥ Œ1¸Êi%Ùç1x¬Ï/ ü“Þ “±]ЦCV4(ŠYQ·ým©TUƒ¢èPÔªŠ›*LðèïõSÊî‡Æã—­|‚ *:Êå LêRnóy°& ‘HËãg'åiÌÕæž>Ðm=<ü«ßÓeEÓŸ§æb7¬ä®€ŠIð{Àà¸bV‡ºU7^&ž ±š)†ñ85›pîß  LO'2&à>ÂC!<Â(2ÉeÊØ½ällÊ-f@`þ°¡ êköJ¥¢Às0 ¹\Vp+ù&ö´^LÝd¨Þ0K9K]Ý=¢Q1 ý\—M½r=³p÷Š:m;Ï€w‘ ˆ¦¨( ²^Î_Ë~xô€€és6ñßa³W”âêÕõOÏ>µ¤FM€Š±Ä!ÎáW!&Íoe—nn|^¬­³Ú“ÚöÃÞýƾ%«í ïk›/,½\ªUX±Umu¡×Ö2qÌß’eÔ&s·C>pûSïΘËStEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/icons/fotoxx48.png0000664000175000017500000001462011701011016015161 0ustar micomico‰PNG  IHDR00Wù‡›zTXtRaw profile type exifxÚ¥WA’$' ¼ó ?IÁs„@þŸï¤ºw<³ÞX¯í®˜®j R¦Ršrþø=Ëoøi/MmôÙ{ŧÍ6Ùñ0êëƒ;q¥:ñLï±÷üëxiïE´¾¾ø6Îã;Cüº aä>Ÿ·¡þ~~½ öúmñÞ@0úƒõ9¬¶O'šï÷ûm°›µ>àôîÌ0ÏGHä~ßÍ'ÁåߨßC¼<¯SäZ¹¦`Ú®oï“Þå|™ôyü9ÿ]Sý™_>-€òDñG®Tþ:.ïá*¯ñò·ß>ý¤ç}ûb˜ò_{ÜúhŽJå=áË ŸU?.sÌóLhÞ:øÖŸôáüË&.œC v\†?ų=×Ä5Ó5vºpbÏjR£MNYè<Ac5>l¸3€ºcCŒ'ÇE»%›LÙ€œ%@ Á(g–÷YèÙw>û ì¼ S™`ŒüÃU~eÒϮ̛„ôò€ÍãÂ~¿1 P¾ƒªO€¿]_>僣 Ón˜ôº^&–Ò ÕË'y°ÌSÜ_D&Û¯õ×PÃÞŠÃ ÕN¢Ô‘ÌF„@äTKãH•7ÉM¤›q“Ú Ö=sYù5M*] ØLq€Õš‚?Ö8ä*ÚTµ«éЩޥ·Òµ÷nýŠ››X35€ ›æCF: cŒ9|òhŸÎ>mŽ9§;ötXö^ó#‹—¬¶tõek¬¹<@Ÿh¡ÑÃbÄ ß¼e·­»oÛcÏ퇨tÚÑrú±3Î<žàZJ¶Ôìi9r¦ Fïþþú¨Ñ5~ºóì5Œš½îåá Œ\Ì€7âv¡ùbVµÆ¹‹YÐ@QÆ!õb³©:unEÚ!Ö¤ìþBî_áVzû)nü«È• ÝÿDîÁ­ý„ÛPÛ·`ƃØ+ oL« û²&ÞtímœENì®tNÞÖ-²oU˜13eŸÕù‡%Ïnâ¶×™†¨Ô=g̽«î²·ÊrßÇ$mшÖô³í ÷!™ót¸‹Áž` ã‘ëŽ1"±ƒô `+GY?ëèVè$¤Ð6¥±Úè]ÆŠ±-V=sò^Óú<áõ´yö)»U:2 •V°¼ÏÅfê¤ »FÅ¢ cK>k*Eú$ÅÁ2ˆñ{E ÀØN£‡¼÷¸îœ!z–XºÖ¹ZmmÙ ¼š^AÈôfÄßÂZ¤¨e®ž'ÀêîUÁšŠÛ¤úÄŽ ‚XUŽÁgtæt;;"­´UÖ˜ƒb!qlV‡ ¥Û1Äh)¯½dvÆ Y{¬•sÑrBæ £‚8²Mæ±B'ŠÓ®=<;ðic€8Z;ÅA…B:lšÈÄ–XMÃ{-€ªÖàÙš ËÚøF÷)arÀc¶½•efÀ/èíiu1& ÅP ½]±+t;jY–ê§¡úi&טrVQŒWð` eƒ¨ávyøb®9P~·VDv…yEÁIèHM$Ý ñ~Íä­`œ…2f5¤•¶ãfð¶,Ÿº_îSu­ÓV7Ùæ`´Iôéºz _pøKÞŽ>ê…¯¹Ñ²$‚=Ñ&à€)Á@̯èsA¾ =ªxˆÚÍm äûœ ŒÔ€Z[—­a¯>±ùDƒÌg†¤Å‰Û7 ÚkƒëåYheF7Ð:…¼mtÛŒdÓyîÜv™íà° êA5àÍŒ¬£;ðGd!CÈæËåDŽ9(hdèÜJ)C; áK1 ø²Ô—)R¼n«ÎUÇ¡nÔÔÞZ87C@ÒÈVÖ>6üoPÕ Ônï…F)wë!ÍÛ­Öí($ý)ç3ç|ûµ *­Á—[(‡×Š™Cµ@?aKÐB—ÖÝ<ï’WmËŠ}[í=E’¡¡Ò´:Ò|ùM¼Â?DÕ[Vœ°Bà4õévéW| V‰Np¡¸…bû ~’k_ëz-Pžò ¹Pl;4ÐøÌ ‚>8ˆ¦%Б,½UïàØ­Wõv‰è›Š8`h<Ø9u<ìEé7n˜…<,F üSÈ¢+‚ì¬*ì6gò(p°Bm±^Sù"ÒÈ.2wìÌì²’!±Ë•OáTuõíÛ3÷žÿ¹ÿû?§/¼oïÛûönwÞzçRû›ßü×¥ö¾ðÅ?xlñn÷ßÿ÷D£mttÄÔ45kÖT‡††Ü‡~ø÷|×®]¤Óé@<ÞpqssË–H$Ògšf›¦iQÏõr¹ì‹Å…B±0ËåNÌLO¿‘Íe9sÊ>xðàï4‡~aÇUW]ÅÌÌøõ³³âsJ©õ®ëªáááAÃ|kçÎ{÷ìÙÃàà ¹\ž¹¹YMJiH)E.—s„îºuë¸ì²Ëèì\Ù»qãÆÿhii½2 5M“B€çyT*Êe›r©L©TbaaAµ6·ÙÓ3Ó‡t=°kddäX&“ùýôôôH”¸ïòÍ›oX½z š¦qöìx÷+¯¼ÒäûjßË/¿¬EÂÑ¿2Œà¶d"Õ‰"Õ…­ëÚ¤i~ýæ›o>ø“ŸìNÍÎÎ~µ§gÕ‡5MJ)|ßÇq\ªUǩ⸞爀i†ššZ®:|øà?üÅm·}βísßùÎw~7gÎŒÅ<ÏM8qbÝ/ùÊå ÅRJJ¥2CCàdÏ}÷Ý·ó‡OŽã3dM__çôôÔƒSSÓžËf¿ºëöÛ_~aÿ~wttô<ÚbÃ÷ÕŸíÛ÷Ó¿›™™YÑÜÜ$›šš8uê$³3³LNLrôØqñúë´ññq­½½]\uõ•„#a„Pd2IoïEHMczzšC‡Ru¢Ñ(º¡cš"‘ 1’Éé¦Í-M45§‰D#x¾KÙ²:ASº™€iÊt:Õièú­¾”º:;¯êí=zôèùáS'O#Žt´µµ Çuð}Ç©Ž„‰7Ä CLNM“Ïq|p––V Ý@Ót Á`˜P8D(BHAwW7ÇgE[=Ý«ˆDù\®¾-2™y2™ åR™@À$ ¡i’Ó§O³cÇM!? ½¥¥eâ6MŠèõýè›û÷ï¯,QÈ÷ýv)åšp8L©¼ÀÑ£ÄãQî¸ã‡æÉ'E)AgÇJ‚Á—\r1MMM!jM“)ê  $šÔ!pœ*š&ñ}¤BÈÚ85e¯µ“ÉF6]¾™±±QNŸ>-ÚZ› _RHVv®$ÕØHÿÒé¤<71±#‰µuuõ<­û¾°^ ‰×q™áÑG¿ÇÀÀk×®exx˜l6K©Tæâu—/äÈdæñ<]×—œimm% ¡TŸŸýì½µ)B|_áy.J)”R ÀW ×­÷ù>¾Rx®‡FÇFøÙó?Ã÷}®¿þzæ3ó¬¾hµ2ÍÐÏ<ÇQz D¹Z!”òY¿þ2*U‹3gNóä“O²~ýz¤”(ßù ÆÆF1 ÉÉ }ôº»{ð\—²Ufrr’µ}k9tèëׯçðáCÄãqz{WsêÔ)úûû<~œ¹LÏó‡Ã¤SiVvuÑ·f +W®djz’b±@gÇJªU‡zp8B>—gppû¿ðENŸ9ÈÓßú·‡Ð«ÕŠÔõpW-f‚@ÀdËÖ­Ü~ûŒŒŒðÒK/‡¹ûîOñ›aûöí|øÃ×S(êÔrñ•"ÂéÓ$9vì(…|)5¾òå/óÆ›¿Á²l ÝÀ0 t]Ç0 N9ÒÏK¡0+W®äÚk¯¡êTд \×env–xÌÁ0 2ósä y’‰$¯½öš ëº‚Öåe‘@H$¹îÚ•|ðºòöÀÛ<öØ8{vœÕ«W³sçÇ C¤Ói³Ôáǩؗ§‚ã ä dæ3üûÃS,ik]A{{;ñxMѤ¦áº.•J…R©ÄÜÜ,§Nbtt„ë>x±Xœæ¦Éd²IZš[Èe³ø¾ÿ¡›nºùûºaqÓ †¤Ç©bÛ¥Òù\Û¶øÅ/^äÀd³Y>ñ‰[…Â(¥–H)Åå—obÓ¦M8ŽÃÉ={øõkho[Aûæ¤ÓiôzôRJ<Ï£Z­â8UzzV177Ëää/þü%ò¹<·|òOøÜ½Ës{Ÿ`ÛÛ C„B!‘N§o ‡Ã½º"êû¾ GˆD"Äã Äãq„<ûì3LMM-9 Åñ}…,mD)%‹å‚ãTyñÅ šaúúÖbè©tšÎκº:‰Åb¸n­²,›B¾ÀÌÌ ÓÉ$ñxgÏóúëÈårÜu×Ý|æ3ƒïùøž‡ï+Œ@€P(d*¥bZ(êÖ4mW<Ö G£1R©Œ299QO:å¥:edt„¾¾>’ÉÆº$Ârú8på ÎŒœ¡¹¹…K/»„?ºr++:Ú(.ÈçóØÏwBaÓ Ý”¦³³“d2”•ŠÍñÁãXåšò)¥¨‰›¢\.‘Ëç°,ëºèËK €R©Ä™‘3hš¶¤Õ‹×ÜÜ?úÑ|þó÷£ëz@-ŒSZ°8yr˜®•]$”JEæç3&–e“Ïç±, ¥š¦ …H$$ <Ï£©)M*u5ñxŒJµÊ /¼€”’mÛ¶/©¡^!ºRB*uþ‡ÍÌì š&qBÔÿ¸HA©T²¬šêÔ³¦ïû bzzŠööXv‰FÑ@__gÎŒÏçèîîabb‚jµJ±¸À5W_ÍøÙqÎ;»DÝÞÞ^²Ù,6\†®ë, ¼ðóŸÓÞÞÁ¦Ð5ÒÂB­-„Z*w¡æp¹\Zzö}¿–pê+¡iÚåÙtb¢F·@À$—ÏrÅ[0M“cÇŽ333C±Xäí·8tè³³3T*vïþ1©TŠžž¶mûÑh”cÇŽÑÑÑA0hÐ×·†k¯½Ž§žÚM?.ÛPŸRày~ À’rÖM)…çºç9¿¨6𦽓AQ,žÉd(—-J¥—oÞˆ®ëLLLÏå9x𠯾ú ù|Mj¦‰¦i,,”8{ö‡æõ×_çcÛÁúõ—233C*•"°uëöî}Žb±H"ÑH:¦­±®¦8=- ¬hn$Ù˜djrŠGy„ýû_¥¯o-³³³˜¦I8b²uëV qŠ…<µ²GxBˆŠ®”XôeÉQ„BÊU¤¬WŒõw‹ÔQ¾B©šóžç²P*1?ŸaçÎ=v” 6òÐCß`ÿþWÑuƒD"Iu–¨uÞ*ˆ¥2 ƒ`Ð$•Já8.®ëq¸ÿðÒ»h4‚RÕŠƒt}¤oPv‚äü³•ó‰ã¸$bQ Ã@)ů~õ+ àZ­‹Å1 Ó4Ú±Œïû¶ã8–®vÄ{Ú…+±X:ÔºkI&’H)ÑuùùyòùðÀ?ÿtlôì!Ý0~999Þ?00°àû¾·<¨: *»_j²àºNC¹\¶-L3H¥RYä¿êéYuîèÑ]o½uäËd÷]L9rXÅ¢wßsÏ®¯466FGFFÅ–-[X±bŽãÐÒÒÊää$º®‘J¥R‹ÅˆÅbttt*Ó ”zè<þøcßrg¨Ô#þ[ª¢Ò¶-/Šø±htsk[[ ··—+>pÁ`ˆŽŽ®¹æ:Ïužyæé— `Õ}×K)åö÷÷ïïïïïì\Ù³yóææd2¡Åãq‰$Ñh”T*E2™$™l¤¹¹‰îîÕÑÑá½õÖ‘¯}íïöÙ=»}ßÏ6”:çEk‘ÞBˆ¶Ö–¶«V­ê½íâK.ÞtÑE½ šÔÜ\>wvxxøégžyúû•J土3ÞÃ4 „¥”±k®¹öê;nº¥¯¯ïŠÖÖÖFÃ0t¨‰ƒëºÞôôtöĉoîÛ·÷éW_}e¿ëº…úéâ±ó"÷~WÇŸ¹¸`Ü?tŽ÷í}ûgÿ fþU×lBIEND®B`‚fotoxx-12.01.2/icons/redo.png0000644000175000017500000000177511701011016014414 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>xIDATHÇÕ”]hUÇÿ÷c&³nÚ|¬I“Ô¨IK¨ÛT‹Æˆ¥jš¶Žñ¡…Š‚€TꋊÔ±Š"(Âh‘ ‚ZFK iµV¬¥X7[[6&1qMºÝÄ„ýÈîÎìÎ\œ-“ÒÝD± \î=÷ÿ;çÜà¿bª.oø'ûè߈ýòÞwÊ´+ r}UÓ÷õ*ûT]&W¢ìî|EYµüÖÇgŸ¨º,ÿ뉕áÁ;Ÿòu´lÝÂ9;®êrÕB{x±U—ý„.ñÍXÉ¡pBÙ¸{íJ`I]ÛÁSïVul04k¬hk/7Ùý®ò4%ìùöU¼íúõ¾J_-üe8o1ný7ú¶!ýÕùð›}‰|ÞÚdhÖ©ª.ÊèÛ+–Ý´sûíO\•cILä‚È83È‘4! „¹Z•-HÅ3xëÐ3¦íä» Í:Z²E„`ïÊúÕݳîQß±iÌðü# ”00ÊP%5®&øqlÀÄ–¬@Õåkd® =Öõ’ïDü¤òÓhò߆J©Rü,€¡Ô×8“ø 5ò tT?‚ÃÁýÙÐø÷'…ƒ.C³Ò¥™ §£u³<•ÿ Ëö`8ú“ø96˜>?Ó'Ré„÷֗ɬÁ-•;ðùI=3ìî74+·à-¢ŒÜÑhaQó4Ú«wâP¨×<7^0 D ã7/ÝŽ¿žž˜Ù/ôš%wM®«ðÕb._ƒ ñÎ'…ƒvC³n ‘2gñѱW3$'_ûb—õaÞ‡vf6ErV „’ñ‚xÁÞxÑœNNîY¬ø<€c‹£c±³f9¯A­¿ ÂA«ªË•žØl23û°±Ëzs±â—VÐ{"ÜŸŒ§§Q·¤›ÚvTŠ#ëzx9Éš݆fPæº @rÛ\ôËa…Aø mµl£g‹ u·,_#5Õ¬¦9‘ ÄùH[¸Ïîîw¢®hÁ¹ `®SüuíË\ÈpÃÆ¹H(ò]g} ‘¯½ö.û¶Yø2ŸÆB"ëÉœ{2/ÞÔ<È¥À7î•Ö,­'Ÿ]]ÞX;•ü}bàYsý\ìbBÔ°ä]÷ŽórÅ!xÇ“¼ytÀžŠEÎ÷Æ;·=Â6Q à]óö—ØÑ’îÿi8ÚVà{c±tEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/icons/quit.png0000644000175000017500000000164711701011016014443 0ustar micomico‰PNG  IHDRàw=øbKGDùC» pHYs  šœGIDATHÇÍ•_h[UÇ?¿ó;7I›¤MjYgbWÌŠ-|2 ç“ï± Š>éƒ l:aâÃuâC_¤ö¡L7|©0¥Õ®þÙƒv›(vH;×:WSKo³.&¹×‡Ô&éÖ&LðãÂ=çü>÷û=¿s.üÇ!Û >ðà>ÿŸÿéû)±õ&âúõÈd¹šNóG6 Àrôèk¬9K5kvtGÅ]Ô$“Ib±Ir¹ìÝ»Êüü</þ@4Åó¼m×›;‘·Ñ××GKK+¡PÓ¿‡Ã$w“L&îЙ+Õ¥R)Ô*ê(Ö±XÇ¢j¼ü3GŽÕõYÕ`­E­bÅ4 PÏ#18À7/¦X(l=Ï*Ö18ë*Tµ1ÀC÷÷²oü4çŸ~ž|nmãý‰‹Å7j-6PÎj`X7P*D6” àytïNùñ<Ÿ?õ,‰÷Þ†`¹»{zzéï‚@³¢V1Æ "8Ae­ ¾oû÷ì[u,Œσ…ÈdØ™JqðÊeFžyŽâ«Gù„sç¾ãøñwqB¶ì½DPGjP,âOO³ÕvšÙYZººx2æãW^æý7ßÙ E,Ö*b Ø`P1ku•e`È®çrUf¥t'™ä±œKñÐKÜXvËEÔ`TËݤe«nU°²B(n³á="®]ãLsyý šcÑõMŒ]0•&ªܼÉîpø–¢n.Ço@7àú>§#QäØ[츯«bCÔ–Ó¨ M_¤x²P,Q¨ý~ôqR¾O˜ˆÆh ØÑPÕ¦”XPŒúµ€³©GڹͿaÿ•³kùRy1|¿‹äÐÁöâñ6òù?Åu]¤Õ`L%E6g'ò·ó|¿:\ÃtG‚ÞS±3Õ…ë®099ÉÌÌ,–>Ëqœò5¡j#ˆñj[…\Úu/Rr„©©)æææ837Œç{Ø&Åh¨RX@üÒžàů'˜¹ú+ã_Žs!û)bPŒ:˜ªÂT{ì|qOÉѾú} 4µÿ­«ö8ú›žå×x ܘü¿Œ¿·»ùF00¤IEND®B`‚fotoxx-12.01.2/icons/folder.png0000644000175000017500000001112311701011016014722 0ustar micomico‰PNG  IHDR00Wù‡sBIT|dˆ IDAThµšY\ÇuÇÿ§ªîÖ·÷ez†Ó³pßF$ɲY lˉ ÛoÉCäkøëÄH b ÎfI$GpìH4%Š"g8[O÷ô~÷ÚòÐCšr$Û•ôKãö­úÕ9ç_§N5ás^á•N§óÆØ•8ŠeùÏ‹¢øwkí/4û¢c}âø/ú‚ÎJ»\©”¿öçñgô'ú';¯¾ò…êx<î ƒ›Æ˜K$€)– Ÿ»‰çxÖàb¹š)^à;œó•µ•ó7ïÜ<Ç,«z¾»uëÖ-ì>Ú½ý³ÿþÙÆt:ý¹5öçîˆð9zƒŸMª~ö!,W쓞Ûp@ûì;À„å°é¸Î×/]»x­Õm5=Ï«ììì„wî¼,šfy2™\c`;®ë– ÌLk kmñ)ã|&€U_#¢×ˆ1b4ìÇVÉðU!ÄApÛuÝU!D¢”’‚‹^xõÆÕs«ë«^! /-Rr]—]8ÁýÒ¿ä·-_)ÝG×Ò,íYk >/€mÆÙw›­æÏ÷zJ©¦5vj­M± ðc¯ó›ßüƒï}ï{;/¿üòF–e{{{="Z­Õk7vnß\_[_«ZkE! H%aaP*¬×ë9[ç·ª+kN¿ß÷•T{yžÈ^@K¥ÒÖ×¾þµ•jµºvxpÔ|û­·½Éxü€Žc̽råJý;ßùÎÆþþ~Àš”òú{wß›„å°Ã9÷•”žp""›d ²<…ïùÔ®wD³ÛàÍ•&k´½$‰WóEh­n¹\n}ëÛßÚøâk_Šî߻φ'ƒÆ½,û½$I~àÇX*ˆÀó}?¸~ýzyeeE´Z­æ÷¿ÿ}Ç œt±XøÃá)ê:Çà‚À%YŠÇÇqÿÃûxçgïp0[u=·eÎMÄø•§ŸÛ8€ A)øî×nŸëmö[ggç~¿Þ³ '¢W_}õÚ›o¾Yw]—Aànnnú×®_sîß¿_Úß{ì-æ  ‚qÎIA 1ãɃ“™,âÉx8‘q”ÖZq ±T¦çV'`»–Þ|õ˯tš­FÀ…[[[´ÒYNGóýý}ÏZ{žˆ^¾}ûöæ7¾ñÐqÎ9çA°V³Å*åŠXD?<8 þqyžÃ‚1!8ˆ1DQ­”¹½s'3ÚäãÑØOÓt=Á™—Ÿ[b9€VX¯]»quÝý„@8båâåKñåË—NMa2Ën’&×*•ÊZ¯×Ýn®ë‚ˆÈ÷}vñÒEò}Yša<šàèðÓÉÖZG@c UÊ|ñ _b«+«T Ëe€ÎE‹èj!‹U!–{ËÏ!±Ë¡_®V^ªTËíj½J‹d!r™¯¯®®U¾ûÍïŒ_ßùʃ{zýAý`ÿç/œ7årBbŒˆh}}×®_C«ÙÂý÷ïãàñò<‡’ LpA€F£IÕjÕ¹tñRýÖÎ-¿»Òµ“ɤ’&ɦRú²Öº` ?ƒQ¿ +…¥Ðu7º«Ýsk½5 Bæ* KÆ*TAQ¼ © Ã6zØ>¿M‡G‡ì'?ù1î½O¯t»h·ÚÄ9‡ã8(%ê´;ØÚÚB«ÓÂññ1>üàNŽ0FÃõ\0Á(+2žËÜ©7êáÎÎÍêµk×+÷‹ñhÔÑZ_° àËD7OŒÖ\iÕp]ïb©l]¼|‘y¾÷‰Ic­E! dE†\`‚huuªÕ*i­q°€ÝÝ]šL&6[.—™‚<ÏC­VÃjw«ÝU8Žƒ“~?|ˆù|"Àõ]2Ö0KVx¾ç¶;-çÜÚ+•BWiUŠ¢¨ªµnœ…Ó@¾0–¬…ð\w§Z«Þ¼~ë:‚àSò~iZkdy†$O!¸@§ÓA·³kÁŽŽi0 ÏsË9'Ï÷ „€#TÊÚØØ@«Ý‚ѧ§§8éÄ üÀ‡ã8ÐVCEŽ#¨×ë9Nå0,¬µEš¤›EQƘ1€Ñ“@·œóÂõÜWê­ÆnÝy‰¥ß pVJb‘, •DµZ¥Ë—.ÓöÖ6Ò8¥÷î¾GGGGÆq¸® Î99Ž!µÛm\¹r›= N†x¼÷qƒAAœ3’J‘¶ÝÕ®¸qã†ÞÚÚ\œ úåÉdR-òÂZk<ð}_ G¼Þl5¿|û•[<‚§JôÛÌó4¬”V¨V+´²²BÕr'''´ûh— O‡°dmµZ¥³GÔnµÑÛè¡V«áä¸>üè©7„ Fd¬! Ã9ç¥Ñt\™Ïg´˜EÇö§O¥¦Z¯À´Ú­×o½|‹¥Òï ð¢(P¨  –P«×È÷|Š££ñý~£ÑH»®‹R©DžëQ)(¡Óé Ùl¢È ¼ó_ï@ƒf»¥¬5O<Í&³©···ë ‡ÃY¼ˆî±?p]—c^¯7ê¯]½qŠ˥g¥ôw6¥²<ƒÔ¾ïa}ýÊ• mprr‚{ïßÓqk.8|ÏgŒ1ò\årÿö¯ÿÆ ­v q¡( p! ÂÁá>Þ¿÷¾Ьx‹ ñÖÓj¥™,äKa9Ü9·q®ZoÔ¹ïûÏ Æh­!•„1•j½^Ö×Ö1é­Ÿ¾íïïËR©$ˆˆ !(Ë2ø¤Ï•R³ñìî 0¬sÎ}kmØ]í² >“*=ƒÆ<ß…pÇ#, xž‡$NÀ8çâ)w’4Át2ѲS%Õ»Ñ<ÚÅY5úI@l­ýeÅáÑÁQË’­ey¶VEik{‹»®û4œ> gŽãµ°“éÓéÔz¾G“Ù\p8®³ìh8Y–Ú4M! U(©†ڵƎž¼ëÓ$Ƙ¹üÅl2C‘Ë,Oò›Ñ<º2›N·®ß¼Îðü™=A´LT&Ižc6›ÁIÄq‚z«†0,=˜/æ˜Mç6K³LæE_Jù±®ÅoÒH/âQ'ÿ½‘Lãtœ&©ÍÒ4Ðܺ°í4ÍeÁõœ D´ Á ãL%I­µBI…r¹ ?ðÁ8ƒp8F£FÃQ–Ì“Y¨ŸÊBž>û®ß&ò#%ÕO'£‰µ°\)…8Žo&IÒºxù’ßl5™ïùôdãù]`ˆØY¬3˹Èó"we!…ÖA)€ë¹ "XX; õ ?˜ÍÆóŠ¢ø—"/Nžg{@‹w’E<=.Ôi%£hß>==ÝܹõR¸¾¾Îƒ Î9¬µ¿‚ˆàºáV¥•’¶”R8;/@$Mìd4Éf“Ù4‰“S-õË6 áL…ž§Ü”ZéHk=“¹tò,“RjRº‰Ás\‡\Çãü7ÖOÖZ$I‚ápˆáÉPÊBNe.Åpxê/¢6·7Q KÖXƒ$õãÝý㓃“"RßãbÙKpveõ¼õ²´Æ.”R©ÌÕ¸…Š¢¸¡´ 5.ŒqFœs|Z)n­Eš% G8==U®§þx4® !°±½ Ë܆'rïÁÞéd8%­tÀ-%Åg¹äS†Æ˜~žäIÅ^š¤•8‰KY‘¹œ1Ž Á—Éýäó¬åyŽÉd‚ÓÑ陎£ÚÍVݵ.”Q8::ʾÿpÍ"²ÖÖÔ°ÌYŽe#x À…¹fµÖÚ‚ˆæF›cÆXª• ³,]SZ9iž NbZ&¦»Ôý3¥’Ra:›b4åq”œÎF³&c¬Þh5©Þ¨a<›Ývͨ?‚RZð°lÁ~•Ä€ú ßcT¥Z­'XîàB)UK’¤œ¦)I%!¥‚1œs! ”Âd:ÁèôTåiOG³ª#œ°»ÖåĀ㣾>Ü;REVˇ³>.–›,}Ÿ¿x±ÿ+û¨V­Íg'óÑBÉ\¾®•n+¥Äl6£ÎJ½s=´Û³Ãº1Æ=Ï«9®ã8ÂÑåJ(¦³)F§#“F©¶Öj,c_œM\ŸM¼À²sýð…=Yš#Ks»y~3%¢>ãü]-µÉ’ìB–fXQ˜/æÐJ‘6Q´Àl6Sœx:Ï\b̯Ô+|x2T“ÑDçiNX*À2lΚÑÞð·þòsxbLJ}ûÒ—r×u'q0Æ<Óz'A! RZQ’$˜N§H“Ä:Ì5Ñ,ò<ó¤’žœªxk£ áWÿ –Â1ðþÀ|ð¹Àñy~S'I2h¶šcQ‘Lk]RRÕ¥,¨(rŠãiœj¤ñ"aI’ˆ8Ši>™k™KÂÙí–+>pÀ?ø;?Á²Éû™ößj=ÆéàÛ·ãF»ñ¨{®{, Iy–·e. ¤I‚ñ餈fÑ4Ž•&)O1Ï’ÆXe¬'úÞðþÀ]Æo~E !&œóƒR©ôØq™ÆŒip8Pƒ£¡Ž¦<ŽbʳœimžœÓçÞðWþÀÛXÞäÏŽñ¿§÷:4bâIEND®B`‚fotoxx-12.01.2/icons/arrow.png0000644000175000017500000000105011701011016014577 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ÝIDATxÚÕ–¿QÇ?ïŠ9½SãkÌ×x­9;:k +;;kÿþÿJj†@«„f+ dW~xc3¬°rûî®q“ÉfßËÎç}gfgþ÷ËlYÏ à&püÒç€Ý²—×ûà.°\:å̧€Ñhðx\? ä_à«€, ‚@{@ñ¼ \s€Ùl&ƒÁàB!€(Ф×ë]dX.—2ŸÏ%Žc™L&Òív½ §Ò1Y¹\¦Óé|Î’øÌòÀZK¥R¡Ýng‚X_çI%­V+ Ù ë>½C´«Õjr ¸¢>Íú×ê¥" CÂ0¤Z­ºí·ê¼°Þ~¼Xk±ÖÒh4œówÀkà ðS{•x•©ˆÈx<–z½.€A Q¹Rý¼žhˆ.gÍë Ðl63j€Äq,ý~ß­Ÿª\õ"µÀ+à% ÃáP¦Ó©Û{ìër>s¢”€§À3à8Þ¤¨8î¤%y ìj—ÔÁ àaŠŠçÀ#=”ñQ‘×Äõt Åq"|ŸTa) `2@Ò&Ý.p¸­ïÀ7`,“¥jÎØi Z5;º6UÛ˜Ùæó"—¨šßj?y½¾ë+t­«IEND®B`‚fotoxx-12.01.2/icons/prev-page.png0000644000175000017500000000150511701011016015340 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>ÀIDATHÇåTMOA~f¶Ý~ E$JE=ž0^¤J¼ÈÙDÿñB=C¢• ‰1<®&\±š`ŒÀÉãÅ„“R@¢¾ö«ÝN¡…nY.^œäÙÉdž÷}Þyø/WôVò¡S.=kN¢Ãã/L8µp9%ö÷¿qçÚÆß…›Î mæv‡ä(ƒ«×ŸsmÛ_"mÍñk}þÓä|b]wžÓ,i®+ŽööuÉœJ§ñRïòâÍd7s‘ùîX{øBG»´¹c ÒÄ̧¯(2fØr¢eR£Íu3ˆ %%3½—;B-­-4»£ƒ1`{?ÁÁ~€Ã[+\Ëb˜ývà·¦@güEœKdêJO4jl@n?ÎKw»j{šM9ÐÚP­{L v;ù€Ròª·'æ÷üØÕÌãà6•á@Ñâöñä ÆùÛžKQ·ŒÜž:á¥s….¾à@Á[ý0«N+Ÿ ¥Ë™5Í2MX¦ EÑKPuì+Å€¢BU ¨j¾tÖ èzÁ^–§GùâøÒÏeM–¿Çñ,Š«/™÷£cE“%Òé€Á+¾},¡1èASè8Ά¼0‹Õuç 6üü>‡ôú|¤ÝG¨ yÓBÐçÆJ:Í8¯cÊ2©„l›Ay¥§OZîýþµ® y¸$ Óbà Z>h„ePæt Å)•§[Â~Ï‹ìÚ*2©„OÜs&vëÄaßêÇ'ó¦²1²“ÛÐtí`Ê‚ød’@Ù¹[=<ësßìÒÈ^nK¼pîN½e®°s×8 €üY˜ü¡®/Üåœm‰ $ZÉ«jý{Ë5Å‘°´ìâ†äoJéÙÅM&€b ˜¸“&ÓŠ(Ë G„™h.«hö¿Y(¿,Mœ‘ξtEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/icons/fotoxx.png0000644000175000017500000002332711701011016015007 0ustar micomico‰PNG  IHDR@@ªiqÞAzTXtRaw profile type exifxÚ¥—m²$« Dÿ×*¼H‚å‚ïÀË÷¡úÎøÎóÄó³Ý5Ó]—âCR¦RªgÿãïçùŸ,bOUoÖÍŸÚkσ›–>~%'I{ùûú•ñëøS¿ÉüõÁñÜþ°QþüaäÞï¯ìë¦äÏ©Ÿ¿}}PýEÖ›§úÍ¢þõ<¾64÷jÍÕÂrfû¼‹”r¿ïaK¸ÆÏoÎçÛËxŠ–þypw¹[±µ_ß¾,½Ëóu¤Ë÷ñ×þroÆ;ÿù¶/ÊÅß¹’ò¯ã?öKå3þüÛƒ{w—÷Tù6öÄ.0Ïÿ‚ØëÖ·@ç•äùšð˸ãß;'Ú9ûPG5øfïòÓùÏFLœØQ^ —ó_¹÷÷ê\˜.¨i¥Éµˆ}&¨Gª„ 9ì÷fɬšwv~s^uÇZñÜóz¡¨÷’“œ£4°\Т0šÏy¾l‘÷Üþž·¤qrSÉ¢ÅÁù?_Ï_™ôg×97„µôõ;_\0ãÂ~¿™Æ9_AÕ7À?®_>ÏOŽV¦Ý07i~¶˜*T/ŸÊ‹mažòû!žx|Öß*g+Æ&U’IQ1Ò!g! €†¤–KÍD5FæZŠM»I=Ö¸¼s³æÏ8šZŒdl7«V…?^Z´ªª©kӮÊÕÇÔÌÜ®¸ /^]ðæÝG+­6mˆAk­·Ñs/hŸvëÞ[ï} Îì<ìÌŒÌ<ˬS§MŸmö9ôYué²å«­¾Fä(QCãE±eC¥]·>Û¶ï¶û®rêÑcÇO;ýŒŸ¨ÉW ÿñú/P“/Ôò‹Ôç?QcÔýóû¼|a“‹ˆå* î/f©I­ù"w1K=“š1R/6!iˆåú”º%둟Øý ¹ÿ ·ÇêŸâ–ÿ*rÏ…îÿDîÅíÙú ·ß ·`®±OÞ˜¦Böñ|Ë:[ÚÓeÎ.³5-n‘k]£”udµ=—œ5ædeÁ™‘jH Å¢X~¬÷Ù»¸=ËÛÉ#·i&Ú›ÅêlÚË’Ýò ª‘fÕ¸4B6 ÆÜ‹P-¶I¦Aúµ9ÞyT½Õ5Xâ!sKŸ3ˆü!Àщ

YíµÔàÈs5Ÿ3ooÛ±K¡H<£¥²lŠøÎõZ6cng­ÂðNÕÏ‚¤tŸ;;±~¤wvª£w…01Õu65¦3ÆX›%“ÓÚ®Óõ@è€ë·åX—nãÒGò˜ìš¥—=y¤Ö³z[xø7T{ÝWÁÐ:ÄáX ++ƒ,©]ˆVÞtS¸¨ @SaB]4ZgÊñqJ;«€èºæÐdtÓØ’<¸ íB\Žš`dÓ¼¶ÎU‹='Á ]ýšÑv92NGJrbèaëcžNbÀ‚ÃÞ¥ë"§uÝ~ÄËÊ-°hz9·°AýÒƒÀÔIuqÝëxxÙ¶@{y{œÏíT©×¹g$„˜Sw{½ÊÚ.›N‚ð±¥~ÝZ³woùñJÂãEÚÀ “óæ‡×C—÷b{8ð;ôlÙŽó§î}»²…mÞ× ÄBIÈþ0­AúŽVA]-» ò²N¸Ô˜lu#M/å'ÙT«ƒ-¶vZšže ‘äK;°}BÙåöIp²qLÐèx|3ŠbAßU=²·š«Í=o‹¸»†º%u9·ë&/å¢Ešìpè;¦5üß“< êT†´ÉZW©y<-i=FS'Û@ãÜ¥dæ©v6e‚êÛ9•#W7‘X?l¬;ç3‘ìI9JäBÖÞÓ9ä älC`Ü} äqlÒèÙÌuŸCá›(25-S¸ $:ϡ־uâ°±L)·y:ïèPÅ „·iõôv “§F¿mÛ#¹Fz6dvÌbx•b=p5!“C)é¤Gl„ZuöâÔ¯: FdhFî±Ñ&-!ª^¦Uê­!• + ¼‘o#êœuOŠƒMj.ÅüMšäQŽúà«W*¢” Kè‰Q><èW{ÛÎ3Ó ÛFD²ÑW¹5â‡Mò~ Oÿ4¼˜W›n(R:Û}ÛY„{‘üx…I“ôE?Óì2y‘+dŸ åœP¡Ðvèäü&ÀDJ€«#[Šnd'J¥P}ègg˜†mÜ ¡Ã¨å´'Jõïî…ÖG;fGG}}ÒHD[°­¦“°O.·Ø:]ÍŽë,NѫУœ¦cÛÉûÉA ý0#B=ã6²Ô+øÓuëí¼x¯Ø ¥5ÂúÂT*6XÎFL›âÑ@·6xm7b•Q¢ýRTmYCÅýÑø" F¶av¡ÆÝ^‚ž …¤ó Άpw™Ò‘l,ºt4)B¯Á‰mGÀïP»Ýøp: úìO:ì„%í²H)£—+ìÚ(ŽuuAÞcÇ_ät.Ѽè®ÖÑ_^vn}nNâZdêüºË)WË'³Ù\ù•Wþi`¼#ûöí£££{êõú'}ßß!¥ìTJÕ|ß¿pË-k¿ñâÅo}÷»ß©®þÏŸþéŸÒßß LÓÅbQ¦iꃃƒ{{{z¶çóùï)ÿèSŸúÔ…¿ø‹¿ð~n”R,-eî:zôÈö ç/¤wíÚuÏÇ>öQM)ßWhš`xd[ÖŽ‹ÅDggçf½¼¼Ì÷Ÿý¾±ÿµýÌ^exx˜d2…®k+”ËòùÓÓÓrûÛoïíígfz†L&ËÒâ2©TM×ð}…ëºf•B”MJ¤”H)âºq)¾ïƒ€Tg§¸eíÚXlyéÑÌræÁr©ôgŸyì±o¨J%ýgû·ï´öÅ•+SbÓ¦þ“?þãOÏÍÏ?Ïçã÷î½Gl»c¦ipâÄI*å •j•|>OzaQÌ/ÌëBH½¿¿Ot÷tŠZ½F±P —ϲ¸´ÈâÒËË‹T*b±(ÃÃ#ØM›ÙÙ«9rß!Žëày.š&0Mƒp8D<%‘HLuÐÙ™¢³3Eª3I4À¶—Èår,¤¥§§GDcÑ„”Ú^Pð„¬oܰáÊÛ¶Ù?=yò-àÅ^Lœ?áW\ÇN&“¢Qoð½gž¡··ÃÐI¥R(õzÌr–l.Kf9Ãòò2ù|ž-[·ðáÏuñ|/Ð © 4©!¥¤^opáÂE2Ù ºaP.—¨Õê$Ý@ëŽã |-!x„@ùk!Ñuh4Š”’p(D6—crê „¬0W.O¢iÝÝ=z,Û¼¼¼üu˲>^©V¿ô¿þëo^¼tÉ>|øðÍx¾»-›ÉléééñxáH„\6Ïàà KKËär9âñ8±XŒ±5£8®ã¸(õz“óçÎÓÓ݃!%R\7[)%B 4M'Ó}ËZ>?üá‹Xfˆp8Œe…š†e™d2*Õ RêèºF£QÇ÷Žc·`‘h×s ‡Â†Îèèýýý\››ãòå˄–´âñøû–——w‹…ÿõ𾇿øéO:ý™Ï|æ:RjÂ÷ýݺ®[¡PÀf¯^EHA©\à±ÇcttÏó8}ú4O>ù$‘HŒb±Èøø­„Â!"‘wÝ}RH)!¤_Kt]#‰N/!´’@ðY) ÃÀ4M„Ôëõ`¡º†ã<Ï ]¡07RM7£»»›K—&8þÃCƒbÍ-·td–—?›ÉäGþäð·>ÿÙ÷ÂWŸøJ^…†b—Ô4)¥¤R)S©”±,“O~ò7Ùºu+ª•œï»ï>Ž?γÏ~Ÿp8L6“AJIµZ!•JaYÖJTµ¨<ÀÈÈ(ccc€BJë¹ärY&&.±œY"`š†i iÚJ Bàû>žçcÛMÒé%\×¥Z­Q*•˜›»Æš5c+Á\–bó¦MtwuqöìYb•(ãk×h/½üÊÇ{ð—~éŽÏOêB¨¨MRJà:¹\†‘‘Qžyæ{ 122‚뺜9s†ƒFÉår4 àû.‹‹‹ŒŽŽ®h£MhÒé4_ûÚW¹óÎ÷ð;¿ó;(]]]üÖo}’l6ƒc7Y\\` Ñz–×Îñ­g(|_µ²@|_!$H©±ió&¶nݺʊ¼ °:ìܵ“Ó§N395úñuòì¹ Ò÷<Å|_õ€è"˜À²"4 æçç©×üþï‰ññµ¬];N©T$›ÍR(±m›ÞÞ^¦¦'‰Ç—°mË ÌWˆÀ¤»º:yüñÇÅ÷T Ãàž{î! ¯Ü×>K!ñü€ ©·$0åûxž‡ç Ñ÷|\ÏEùªš¢ÑlðôÓOqòäIÇa×®]<øàƒœ={!4îï}Çy~MÓÆ„!Ñ‚<±g÷=Š9Òéæç¯qñâE6oÞ„‚F£A*•bïÞ÷’Ëfi4ê$“ .\¸À«¯¾Â=÷ì%S¯Õ¨T«œ>}б±1B¡ ìܹ“b±ÈO§§·‡Í›·ày‹‹KLNNrùòeæ¯ÍQ(qÃ0ˆÅâtww34<ÌØè(ýýX–E±X`öÚU¢‘(ƒƒC!xê©ïòò+/322J­Öà™gžAJɽ{ßËÂü×®ÍÕ6lØP]•ĈBo…bphˆ;wàz³³WyóÍ7¹rå š¦ÇùÄ'eâÒ%Î?C¢#Á®]»±,‹H$Âo¼NµZE)ÅÀÀ•J…ééi.œ>͆±ímLMMQ*—ˆ'\¼p‘^x‘ƒ‡píÚ,F)µ &†abš&¦e²BÄb1Ù¾};ý¤Óizzz0³!¢‘(@ I½Z'#¥äàÁ<øþIu¦8qâùb~% PôHÑŠÅ)ˆFc¬_+ïÿC|à011A4¡··Ÿ—~ôCö¿þ¡Pˆõ·ÞÆý÷?€¦ôW©À_.\8ÏñãÇI…Âlwçˆrúôi²™ ££c\ºx‰øö?0??‡”–iÄÑu€&ÌOˆ`M¶mS,©TÊÌḬ̀nÝ:xßýÌÌLD±, )+Íæ²˜¦RRjÄ¢1êÕZ|âÒ„ G"1)¥¹)Ÿ´ÀP-·è ¯·“§NòÄ_cjj )%ÑhŒ~ô_`šFË¿R^§«¡P)%£CCD"QôTŠõ}=¼:w×÷ïçÅ_Äq\zºûèëëcppˆD"A8^@)¥8ªV«,//S(äi6›œ:}Šl6ÃïÙŽ”a+ÌîÝ{xî¹ïS¯×¨×k»wïÆ4Mbñš®¯_·î¡M›7<¥ëº®Y–Õ¥ëšð['8\ÇÁqlסX,òƒ<ÇÉ“'(‹+©nß¾‡\ níï…߇µkƒà©‚|†ÒÓÓœ>}†©É)zzúèëë§¿¿Ÿp8Œ¦ièºah2àí) ‰Dèêê¢i7ÉesÌÏÏ377ÏâÒáp”¾þ~õW? BpôÈa„ìÞ½‡‡úÊW„, Ó4#ÝÝÝŸ³æs: ]×MZ–E<žÀ4M¤&q]—J¥L:½Àää$¼I±XÄ÷ý–©šÞ¸a¾¯ð}ÅìÛé+H[ío‚‹+W®ðÒ^bdxŒd¢“F³A,#O`Y‰DœT*E<8à8µzjµJ¹T¦R­R¯Õ1t“H$L6›ennž¿zò/)—JÜÿü«ùküʇ>Œòbåµ2Šnèº.4MëÆAÓ…š¤ÚB×ub‘]]Ý 088À³ßfEð•T%%¾ïsìø1ÖßvÛŠÙ«•¼ßRŸgnnŽÑÑ1ººº©Vëd³Y2™ ùBžL6Ãââ"3Ó3 4MòÓŸžàÒ¥ 6lØ€‡®iìÞµ“;¾þ—Ò9zåû-~r½°j½¥­·µ€f³¦]÷}¿Å¿¯§:Ѫùe‹û9»mJ J¥b+.ÐÙÙÉb:ÍÚñ5ìÝ»—Ç är¹•¦ç×¾öUÎ;ËÒÒF£|%¦iÑÙÙÉ­·®gëÖÛyä‘rîìY|åóãÿ˜÷¼ç=”J%²ÙÕZZµÊK/ýˆ'Nð‘|„={îB“’£Grï½{©T&X¿~=£££LMO’N§Wš¬BJÕ„@É–@>o¾ç£à†üÞ6õÕ1 -|û¸0Jù8®C­Vcqi‘üòÃ\¼x MÓØ°a#Ùl†'ŸüKf®^E)H$’t¤:± î°Æ†¾(wŒÄxÏp”-}&}QAg"JWWšÔX^^âé§ŸâĉŸ2>~+©TŠ£G±iÓ&l§ÁæÍ›ˆF"ô÷÷1€ %K©¡  ø2XèÍàyšÜt«5Ýí°À€ü´­Åq\êµ¹\Žññ[H&“,..122J¥Rá _øét$ Bá0QC²y8Åmƒ ¢:„”CRo2žð¸o<¶á‰N2•B×u–––ùâïýéÅ4ýý¸®K:½Èàà8ŽK¹RÁÇoYr{}ª¢¾liì&T›A½ ùYí ×ÏÖW=a¥IQ(¸÷Þ{¸xñ©T’ÞÞ^þüÏÿŒË—'PJ‡1­ñÉšîšð)”›Héc…]⇄ÕÄp+Œ'|¶Žv³ ¢Ñ8Bf¯Íòõ¯ÿRÉ©TЉ‰ËŒŒ ‹G‰D"LOM#…ìQ]oÔT@ùR”7ÐÖö;¿·Æ€ ÿç· |V¡hÚ â‰==½ 9º»{˜››ãùçŸÇu] à  2u’ )}Ê5¡a„ ‰FÄ@3–áS¯7ŒÁ`waÓÀ2M\×åõ×÷siâ"I|ߣ\®ÐÕÕEª3ÅuVªVdzŠJÉVä¾)ôQÜ~ÖTƒ¢Õ ¡ëBHÖ­§P( „$‘H°ÿ~òùµ¦ƒò|t©Çp…E ƒ¦fR÷ OPk:t'L¡ÐJP.—yùåWH$‚¢jnn~¥Âls™@¬VßK©ŠRÊ—-ÿo¾ü+šn[Ãê>_ûzu8ìzh&J)ÆÆÆÈd2„B!,Ëâøñ£-&&[›&‚p$ŒçûxŽ‹p]¤ããÙdz¨ûQrÍ0Ù¦AÁ–Tm…ò}â±(š&Ñ4 ×u9ñÓãH) …Âäóy’ÉñxŒ¶—{^Ðpõ}?ßl6}½õKíf¸nò×+¦„BF†Fžbÿþ7¨Tkx~@µ}ß'™Lr÷Ý÷¬ìN pîÜ9V·:„€Åô¢’R¾Ùl:y”B,p•»¥ÈÖe[¸Õ~¿š##‘H°gÏ]蚎”‚f³I&“!— ÒR¥Rfdd”÷½ïý<õÔw±m­^GH‰¦…ú<¹ #ýýŒôßB"C(A©TæìɳÌÏÍãù _)ÛÆnÚ†ÁîÝ{_;ÎâR]׉ÇÌL_%®¼y’ÉdÔÂÂBŶí¿~é¥:-@)2€Ç ï ,ËZñ¯…]Õbjïѵ"ÑŽ;Ù¹smöU*•èïïãòå ¶n½#‡“ÍfùøÇ?ÁÑ£G˜œœ¤Ùh ˜¾nZØ5›ÉÌ%¦ÔÅ€Oúà·:: ð¼ÀÌ›Í:B(úûûyôÑߤX*P«ÕX·îV®^¡Z­.⹊5==YŸœœü/3W§_/•Š¢[â,¶¸aX¦uSê[ Âñ¡í7Ö‘H¤Õ;4h6ôöõ’ÏçˆF¢üöoÿ{º»{õ:õj…fµ‚[¯ã¹.¾çãyð …ë{ØvƒF£N½^Ã÷}R©þßÒÓÓC±XÂ0 úûûxíµýD£1Êå2FC={¦4=5ý¥ééÉoÌÌL7[X÷<I)åÜ()„Â*ÕòM®¦À¦aâº>RhLOOÝ”ïûèºÎúõ˜˜¸ÄÙ³Ïññ‚ƒ²¸´H©TæÑGå[ßúéôv³¹ÐÚ¹ý"D»?ẞç£ë]]]Üÿ4m›åå ¶m³gÏ:L¹\Ås”*—KþoÎÎLOÿáþ7^ûû|>_Üö:u]×3Bˆ"бƒh4J:l9·ëýëV Ø´q³êïTËËK~6Wàå—_ öí[9W´ÚÑí×[æ®]ãÙgŸåƒü öæ›?½½½xžÇ§>õi^xáœ;wŽz½Þê@;´ß[mQRJ"‘[¶laçÎ]X–IwwõzíÛ·³°°àÿà¹ç½®®žÆÅÙ‹çëµÊs®ç~ûØ‘£Sù|Þ!ˆuê|ßw5M[ö|ˆ©©)òù<¶m¯ÌiÉd’õëocÓ¦Í<ôÐ>Μ9Íðð0º®qûíÛT½^kþÑý׿¿páâ±p(|ºi7/,-¥‹¹\Î~«à« t]ö÷~ip`èóÑhTvt$dlÍW®Lày.µZð:J©T¢Qo¨Ñ±±ç^ýõ/,--¦ Š©ŸõžîêFܸqÓöÇü¿íÛ·oÓåË—åÂBšF£A¥R!NcšFƒþ¾~¦g¦‘RÒÓÓC2™¤R©`š&CCCxžGGG’-[¶¨+W®ÿäOþø¿?ÿüsÿÓqÜ `7iü­C„ïû¦ç¹ÅD¼cW<ïîîî}ýýŒŽ ³~ýz2™ µZ]7_§xßû—'&&þàøñcçA1ÕüG£u4'“Y^ðÀ·÷öö†2™ŒÈçsÔjA,h»€®ë„Ã!::Rôõö*Çu½C‡Ìï{ß{úÕW_ùv±X¼ÖRD¥ôϵ¦6ˆ]áPx`ppøþááá÷Œß:007 S4õr>Ÿ¿tåÊ•ç>ü|£Q_$((œw|úÛ €Õ:ŒP([»v|Ç}÷Ý·oË–-;ÆÇLJúúÌH$¬I!…B)DZý\.ïNMM&&&Îìß¿ÿå³gϼšÉdÒ\7÷¶Å‘û ½0 ‘H$‹ÅâqË2c¶íß÷JÕjµP«ÕJH7~‘‰ÞfÞö[å²u-³³³3ÚÙÙ9²Bk‰.Ë ™žçùår©T©T¯Õ뵩t:]t]wµ ÆÛŸî5½õ­±jqí¶ïiOОìŸ"ø;­á­o=Š·ü¾z.õ6çÿSkyÛ±zïŽwÇ»ãÝñîøiüo¼ß/»èhUIEND®B`‚fotoxx-12.01.2/icons/fotoxx64.png0000664000175000017500000002332711701011016015163 0ustar micomico‰PNG  IHDR@@ªiqÞAzTXtRaw profile type exifxÚ¥—m²$« Dÿ×*¼H‚å‚ïÀË÷¡úÎøÎóÄó³Ý5Ó]—âCR¦RªgÿãïçùŸ,bOUoÖÍŸÚkσ›–>~%'I{ùûú•ñëøS¿ÉüõÁñÜþ°QþüaäÞï¯ìë¦äÏ©Ÿ¿}}PýEÖ›§úÍ¢þõ<¾64÷jÍÕÂrfû¼‹”r¿ïaK¸ÆÏoÎçÛËxŠ–þypw¹[±µ_ß¾,½Ëóu¤Ë÷ñ×þroÆ;ÿù¶/ÊÅß¹’ò¯ã?öKå3þüÛƒ{w—÷Tù6öÄ.0Ïÿ‚ØëÖ·@ç•äùšð˸ãß;'Ú9ûPG5øfïòÓùÏFLœØQ^ —ó_¹÷÷ê\˜.¨i¥Éµˆ}&¨Gª„ 9ì÷fɬšwv~s^uÇZñÜóz¡¨÷’“œ£4°\Т0šÏy¾l‘÷Üþž·¤qrSÉ¢ÅÁù?_Ï_™ôg×97„µôõ;_\0ãÂ~¿™Æ9_AÕ7À?®_>ÏOŽV¦Ý07i~¶˜*T/ŸÊ‹mažòû!žx|Öß*g+Æ&U’IQ1Ò!g! €†¤–KÍD5FæZŠM»I=Ö¸¼s³æÏ8šZŒdl7«V…?^Z´ªª©kӮÊÕÇÔÌÜ®¸ /^]ðæÝG+­6mˆAk­·Ñs/hŸvëÞ[ï} Îì<ìÌŒÌ<ˬS§MŸmö9ôYué²å«­¾Fä(QCãE±eC¥]·>Û¶ï¶û®rêÑcÇO;ýŒŸ¨ÉW ÿñú/P“/Ôò‹Ôç?QcÔýóû¼|a“‹ˆå* î/f©I­ù"w1K=“š1R/6!iˆåú”º%둟Øý ¹ÿ ·ÇêŸâ–ÿ*rÏ…îÿDîÅíÙú ·ß ·`®±OÞ˜¦Böñ|Ë:[ÚÓeÎ.³5-n‘k]£”udµ=—œ5ædeÁ™‘jH Å¢X~¬÷Ù»¸=ËÛÉ#·i&Ú›ÅêlÚË’Ýò ª‘fÕ¸4B6 ÆÜ‹P-¶I¦Aúµ9ÞyT½Õ5Xâ!sKŸ3ˆü!Àщ

YíµÔàÈs5Ÿ3ooÛ±K¡H<£¥²lŠøÎõZ6cng­ÂðNÕÏ‚¤tŸ;;±~¤wvª£w…01Õu65¦3ÆX›%“ÓÚ®Óõ@è€ë·åX—nãÒGò˜ìš¥—=y¤Ö³z[xø7T{ÝWÁÐ:ÄáX ++ƒ,©]ˆVÞtS¸¨ @SaB]4ZgÊñqJ;«€èºæÐdtÓØ’<¸ íB\Žš`dÓ¼¶ÎU‹='Á ]ýšÑv92NGJrbèaëcžNbÀ‚ÃÞ¥ë"§uÝ~ÄËÊ-°hz9·°AýÒƒÀÔIuqÝëxxÙ¶@{y{œÏíT©×¹g$„˜Sw{½ÊÚ.›N‚ð±¥~ÝZ³woùñJÂãEÚÀ “óæ‡×C—÷b{8ð;ôlÙŽó§î}»²…mÞ× ÄBIÈþ0­AúŽVA]-» ò²N¸Ô˜lu#M/å'ÙT«ƒ-¶vZšže ‘äK;°}BÙåöIp²qLÐèx|3ŠbAßU=²·š«Í=o‹¸»†º%u9·ë&/å¢Ešìpè;¦5üß“< êT†´ÉZW©y<-i=FS'Û@ãÜ¥dæ©v6e‚êÛ9•#W7‘X?l¬;ç3‘ìI9JäBÖÞÓ9ä älC`Ü} äqlÒèÙÌuŸCá›(25-S¸ $:ϡ־uâ°±L)·y:ïèPÅ „·iõôv “§F¿mÛ#¹Fz6dvÌbx•b=p5!“C)é¤Gl„ZuöâÔ¯: FdhFî±Ñ&-!ª^¦Uê­!• + ¼‘o#êœuOŠƒMj.ÅüMšäQŽúà«W*¢” Kè‰Q><èW{ÛÎ3Ó ÛFD²ÑW¹5â‡Mò~ Oÿ4¼˜W›n(R:Û}ÛY„{‘üx…I“ôE?Óì2y‘+dŸ åœP¡Ðvèäü&ÀDJ€«#[Šnd'J¥P}ègg˜†mÜ ¡Ã¨å´'Jõïî…ÖG;fGG}}ÒHD[°­¦“°O.·Ø:]ÍŽë,NѫУœ¦cÛÉûÉA ý0#B=ã6²Ô+øÓuëí¼x¯Ø ¥5ÂúÂT*6XÎFL›âÑ@·6xm7b•Q¢ýRTmYCÅýÑø" F¶av¡ÆÝ^‚ž …¤ó Άpw™Ò‘l,ºt4)B¯Á‰mGÀïP»Ýøp: úìO:ì„%í²H)£—+ìÚ(ŽuuAÞcÇ_ät.Ѽè®ÖÑ_^vn}nNâZdêüºË)WË'³Ù\ù•Wþi`¼#ûöí£££{êõú'}ßß!¥ìTJÕ|ß¿pË-k¿ñâÅo}÷»ß©®þÏŸþéŸÒßß LÓÅbQ¦iꃃƒ{{{z¶çóùï)ÿèSŸúÔ…¿ø‹¿ð~n”R,-eî:zôÈö ç/¤wíÚuÏÇ>öQM)ßWhš`xd[ÖŽ‹ÅDggçf½¼¼Ì÷Ÿý¾±ÿµýÌ^exx˜d2…®k+”ËòùÓÓÓrûÛoïíígfz†L&ËÒâ2©TM×ð}…ëºf•B”MJ¤”H)âºq)¾ïƒ€Tg§¸eíÚXlyéÑÌræÁr©ôgŸyì±o¨J%ýgû·ï´öÅ•+SbÓ¦þ“?þãOÏÍÏ?Ïçã÷î½Gl»c¦ipâÄI*å •j•|>OzaQÌ/ÌëBH½¿¿Ot÷tŠZ½F±P —ϲ¸´ÈâÒËË‹T*b±(ÃÃ#ØM›ÙÙ«9rß!Žëày.š&0Mƒp8D<%‘HLuÐÙ™¢³3Eª3I4À¶—Èår,¤¥§§GDcÑ„”Ú^Pð„¬oܰáÊÛ¶Ù?=yò-àÅ^Lœ?áW\ÇN&“¢Qoð½gž¡··ÃÐI¥R(õzÌr–l.Kf9Ãòò2ù|ž-[·ðáÏuñ|/Ð © 4©!¥¤^opáÂE2Ù ºaP.—¨Õê$Ý@ëŽã |-!x„@ùk!Ñuh4Š”’p(D6—crê „¬0W.O¢iÝÝ=z,Û¼¼¼üu˲>^©V¿ô¿þëo^¼tÉ>|øðÍx¾»-›ÉléééñxáH„\6Ïàà KKËär9âñ8±XŒ±5£8®ã¸(õz“óçÎÓÓ݃!%R\7[)%B 4M'Ó}ËZ>?üá‹Xfˆp8Œe…š†e™d2*Õ RêèºF£QÇ÷Žc·`‘h×s ‡Â†Îèèýýý\››ãòå˄–´âñøû–——w‹…ÿõ𾇿øéO:ý™Ï|æ:RjÂ÷ýݺ®[¡PÀf¯^EHA©\à±ÇcttÏó8}ú4O>ù$‘HŒb±Èøø­„Â!"‘wÝ}RH)!¤_Kt]#‰N/!´’@ðY) ÃÀ4M„Ôëõ`¡º†ã<Ï ]¡07RM7£»»›K—&8þÃCƒbÍ-·td–—?›ÉäGþäð·>ÿÙ÷ÂWŸøJ^…†b—Ô4)¥¤R)S©”±,“O~ò7Ùºu+ª•œï»ï>Ž?γÏ~Ÿp8L6“AJIµZ!•JaYÖJTµ¨<ÀÈÈ(ccc€BJë¹ärY&&.±œY"`š†i iÚJ Bàû>žçcÛMÒé%\×¥Z­Q*•˜›»Æš5c+Á\–bó¦MtwuqöìYb•(ãk×h/½üÊÇ{ð—~éŽÏOêB¨¨MRJà:¹\†‘‘Qžyæ{ 122‚뺜9s†ƒFÉår4 àû.‹‹‹ŒŽŽ®h£MhÒé4_ûÚW¹óÎ÷ð;¿ó;(]]]üÖo}’l6ƒc7Y\\` Ñz–×Îñ­g(|_µ²@|_!$H©±ió&¶nݺʊ¼ °:ìܵ“Ó§N395úñuòì¹ Ò÷<Å|_õ€è"˜À²"4 æçç©×üþï‰ññµ¬];N©T$›ÍR(±m›ÞÞ^¦¦'‰Ç—°mË ÌWˆÀ¤»º:yüñÇÅ÷T Ãàž{î! ¯Ü×>K!ñü€ ©·$0åûxž‡ç Ñ÷|\ÏEùªš¢ÑlðôÓOqòäIÇa×®]<øàƒœ={!4îï}Çy~MÓÆ„!Ñ‚<±g÷=Š9Òéæç¯qñâE6oÞ„‚F£A*•bïÞ÷’Ëfi4ê$“ .\¸À«¯¾Â=÷ì%S¯Õ¨T«œ>}б±1B¡ ìܹ“b±ÈO§§·‡Í›·ày‹‹KLNNrùòeæ¯ÍQ(qÃ0ˆÅâtww34<ÌØè(ýýX–E±X`öÚU¢‘(ƒƒC!xê©ïòò+/322J­Öà™gžAJɽ{ßËÂü×®ÍÕ6lØP]•ĈBo…bphˆ;wàz³³WyóÍ7¹rå š¦ÇùÄ'eâÒ%Î?C¢#Á®]»±,‹H$Âo¼NµZE)ÅÀÀ•J…ééi.œ>͆±ímLMMQ*—ˆ'\¼p‘^x‘ƒ‡píÚ,F)µ &†abš&¦e²BÄb1Ù¾};ý¤Óizzz0³!¢‘(@ I½Z'#¥äàÁ<øþIu¦8qâùb~% PôHÑŠÅ)ˆFc¬_+ïÿC|à011A4¡··Ÿ—~ôCö¿þ¡Pˆõ·ÞÆý÷?€¦ôW©À_.\8ÏñãÇI…Âlwçˆrúôi²™ ££c\ºx‰øö?0??‡”–iÄÑu€&ÌOˆ`M¶mS,©TÊÌḬ̀nÝ:xßýÌÌLD±, )+Íæ²˜¦RRjÄ¢1êÕZ|âÒ„ G"1)¥¹)Ÿ´ÀP-·è ¯·“§NòÄ_cjj )%ÑhŒ~ô_`šFË¿R^§«¡P)%£CCD"QôTŠõ}=¼:w×÷ïçÅ_Äq\zºûèëëcppˆD"A8^@)¥8ªV«,//S(äi6›œ:}Šl6ÃïÙŽ”a+ÌîÝ{xî¹ïS¯×¨×k»wïÆ4Mbñš®¯_·î¡M›7<¥ëº®Y–Õ¥ëšð['8\ÇÁqlסX,òƒ<ÇÉ“'(‹+©nß¾‡\ níï…߇µkƒà©‚|†ÒÓÓœ>}†©É)zzúèëë§¿¿Ÿp8Œ¦ièºah2àí) ‰Dèêê¢i7ÉesÌÏÏ377ÏâÒáp”¾þ~õW? BpôÈa„ìÞ½‡‡úÊW„, Ó4#ÝÝÝŸ³æs: ]×MZ–E<žÀ4M¤&q]—J¥L:½Àää$¼I±XÄ÷ý–©šÞ¸a¾¯ð}ÅìÛé+H[ío‚‹+W®ðÒ^bdxŒd¢“F³A,#O`Y‰DœT*E<8à8µzjµJ¹T¦R­R¯Õ1t“H$L6›ennž¿zò/)—JÜÿü«ùküʇ>Œòbåµ2Šnèº.4MëÆAÓ…š¤ÚB×ub‘]]Ý 088À³ßfEð•T%%¾ïsìø1ÖßvÛŠÙ«•¼ßRŸgnnŽÑÑ1ººº©Vëd³Y2™ ùBžL6Ãââ"3Ó3 4MòÓŸžàÒ¥ 6lØ€‡®iìÞµ“;¾þ—Ò9zåû-~r½°j½¥­·µ€f³¦]÷}¿Å¿¯§:Ѫùe‹û9»mJ J¥b+.ÐÙÙÉb:ÍÚñ5ìÝ»—Ç är¹•¦ç×¾öUÎ;ËÒÒF£|%¦iÑÙÙÉ­·®gëÖÛyä‘rîìY|åóãÿ˜÷¼ç=”J%²ÙÕZZµÊK/ýˆ'Nð‘|„={îB“’£Grï½{©T&X¿~=£££LMO’N§Wš¬BJÕ„@É–@>o¾ç£à†üÞ6õÕ1 -|û¸0Jù8®C­Vcqi‘üòÃ\¼x MÓØ°a#Ùl†'ŸüKf®^E)H$’t¤:± î°Æ†¾(wŒÄxÏp”-}&}QAg"JWWšÔX^^âé§ŸâĉŸ2>~+©TŠ£G±iÓ&l§ÁæÍ›ˆF"ô÷÷1€ %K©¡  ø2XèÍàyšÜt«5Ýí°À€ü´­Åq\êµ¹\Žññ[H&“,..122J¥Rá _øét$ Bá0QC²y8Åmƒ ¢:„”CRo2žð¸o<¶á‰N2•B×u–––ùâïýéÅ4ýý¸®K:½Èàà8ŽK¹RÁÇoYr{}ª¢¾liì&T›A½ ùYí ×ÏÖW=a¥IQ(¸÷Þ{¸xñ©T’ÞÞ^þüÏÿŒË—'PJ‡1­ñÉšîšð)”›Héc…]⇄ÕÄp+Œ'|¶Žv³ ¢Ñ8Bf¯Íòõ¯ÿRÉ©TЉ‰ËŒŒ ‹G‰D"LOM#…ìQ]oÔT@ùR”7ÐÖö;¿·Æ€ ÿç· |V¡hÚ â‰==½ 9º»{˜››ãùçŸÇu] à  2u’ )}Ê5¡a„ ‰FÄ@3–áS¯7ŒÁ`waÓÀ2M\×åõ×÷siâ"I|ߣ\®ÐÕÕEª3ÅuVªVdzŠJÉVä¾)ôQÜ~ÖTƒ¢Õ ¡ëBHÖ­§P( „$‘H°ÿ~òùµ¦ƒò|t©Çp…E ƒ¦fR÷ OPk:t'L¡ÐJP.—yùåWH$‚¢jnn~¥Âls™@¬VßK©ŠRÊ—-ÿo¾ü+šn[Ãê>_ûzu8ìzh&J)ÆÆÆÈd2„B!,Ëâøñ£-&&[›&‚p$ŒçûxŽ‹p]¤ããÙdz¨ûQrÍ0Ù¦AÁ–Tm…ò}â±(š&Ñ4 ×u9ñÓãH) …Âäóy’ÉñxŒ¶—{^Ðpõ}?ßl6}½õKíf¸nò×+¦„BF†Fžbÿþ7¨Tkx~@µ}ß'™Lr÷Ý÷¬ìN pîÜ9V·:„€Åô¢’R¾Ùl:y”B,p•»¥ÈÖe[¸Õ~¿š##‘H°gÏ]蚎”‚f³I&“!— ÒR¥Rfdd”÷½ïý<õÔw±m­^GH‰¦…ú<¹ #ýýŒôßB"C(A©TæìɳÌÏÍãù _)ÛÆnÚ†ÁîÝ{_;ÎâR]׉ÇÌL_%®¼y’ÉdÔÂÂBŶí¿~é¥:-@)2€Ç ï ,ËZñ¯…]Õbjïѵ"ÑŽ;Ù¹smöU*•èïïãòå ¶n½#‡“ÍfùøÇ?ÁÑ£G˜œœ¤Ùh ˜¾nZØ5›ÉÌ%¦ÔÅ€Oúà·:: ð¼ÀÌ›Í:B(úûûyôÑߤX*P«ÕX·îV®^¡Z­.⹊5==YŸœœü/3W§_/•Š¢[â,¶¸aX¦uSê[ Âñ¡í7Ö‘H¤Õ;4h6ôöõ’ÏçˆF¢üöoÿ{º»{õ:õj…fµ‚[¯ã¹.¾çãyð …ë{ØvƒF£N½^Ã÷}R©þßÒÓÓC±XÂ0 úûûxíµýD£1Êå2FC={¦4=5ý¥ééÉoÌÌL7[X÷<I)åÜ()„Â*ÕòM®¦À¦aâº>RhLOOÝ”ïûèºÎúõ˜˜¸ÄÙ³Ïññ‚ƒ²¸´H©TæÑGå[ßúéôv³¹ÐÚ¹ý"D»?ẞç£ë]]]Üÿ4m›åå ¶m³gÏ:L¹\Ås”*—KþoÎÎLOÿáþ7^ûû|>_Üö:u]×3Bˆ"бƒh4J:l9·ëýëV Ø´q³êïTËËK~6Wàå—_ öí[9W´ÚÑí×[æ®]ãÙgŸåƒü öæ›?½½½xžÇ§>õi^xáœ;wŽz½Þê@;´ß[mQRJ"‘[¶laçÎ]X–IwwõzíÛ·³°°àÿà¹ç½®®žÆÅÙ‹çëµÊs®ç~ûØ‘£Sù|Þ!ˆuê|ßw5M[ö|ˆ©©)òù<¶m¯ÌiÉd’õëocÓ¦Í<ôÐ>Μ9Íðð0º®qûíÛT½^kþÑý׿¿páâ±p(|ºi7/,-¥‹¹\Î~«à« t]ö÷~ip`èóÑhTvt$dlÍW®Lày.µZð:J©T¢Qo¨Ñ±±ç^ýõ/,--¦ Š©ŸõžîêFܸqÓöÇü¿íÛ·oÓåË—åÂBšF£A¥R!NcšFƒþ¾~¦g¦‘RÒÓÓC2™¤R©`š&CCCxžGGG’-[¶¨+W®ÿäOþø¿?ÿüsÿÓqÜ `7iü­C„ïû¦ç¹ÅD¼cW<ïîîî}ýýŒŽ ³~ýz2™ µZ]7_§xßû—'&&þàøñcçA1ÕüG£u4'“Y^ðÀ·÷öö†2™ŒÈçsÔjA,h»€®ë„Ã!::Rôõö*Çu½C‡Ìï{ß{úÕW_ùv±X¼ÖRD¥ôϵ¦6ˆ]áPx`ppøþááá÷Œß:007 S4õr>Ÿ¿tåÊ•ç>ü|£Q_$((œw|úÛ €Õ:ŒP([»v|Ç}÷Ý·oË–-;ÆÇLJúúÌH$¬I!…B)DZý\.ïNMM&&&Îìß¿ÿå³gϼšÉdÒ\7÷¶Å‘û ½0 ‘H$‹ÅâqË2c¶íß÷JÕjµP«ÕJH7~‘‰ÞfÞö[å²u-³³³3ÚÙÙ9²Bk‰.Ë ™žçùår©T©T¯Õ뵩t:]t]wµ ÆÛŸî5½õ­±jqí¶ïiOОìŸ"ø;­á­o=Š·ü¾z.õ6çÿSkyÛ±zïŽwÇ»ãÝñîøiüo¼ß/»èhUIEND®B`‚fotoxx-12.01.2/icons/last-page.png0000644000175000017500000000161611701011016015332 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk> IDATHÇÕ”MU†Ÿ[UýÉ40@Œh!`‚LXÈÂÄ ‰,4%ÑD‰qiL {û`¹Ä…á  †Z D†Ädb¢‹a˜LSq¾0v÷ôLuWWu×½—EW7 tO· žäMêÖ=ç¼ç¼UçÀÿÝÄ$ÛqsÀ—¾WþvJß@=¼].SqÕ~¶ãN*H!Œ‹\°€<À4:4[ú\qÓvÜÌ$Ãx’v*@¿õæ™™£‡¼#„øÅvÜÒ”qS ´àìÜÉâ+Ç¿!„X°÷è4q€í¸A_³Q–µLÑ•ŠÍz›“'^Îe2æ«Ë•ßmÇ=ï{奉@þíóç,Ã4¢?k ¦+›#/1­ŒõÂâÒ_¿ÙŽû®ï•ïM”H ƒzØC­õÖ«-vÚÝžT jA̾ÙY1wÚÞ+ 1o;îû ¤ÔhÍHŠ`o!Ë©×ìÂâbå;ÀKÐnwh…Ñ4?ÆÀö2t»P©¬¶âZß+Q"Õ¿Kž·Èð`©ÒŠãî×þí¯.ï*Q"ûfrO]öÿ% D„¸#(ä,PŠ5TR]ö½òµq…ô ôʃ9ÎÉ0 Ž·ÍI.k"»ÖÖ6B­õ¾W¾¾[§}‚ã7kNIUK¤Â2 :QLõÑ£–ÖúSß+ÿ4IJ À÷Êñˆ;Ï~œ)½tŽ$QÄí6Zµ%£à£Õ;W~²€ÂóÝHj9 £êr ÕlêFõŸ ªû®Þ¹²Ì{RÂŽ/;ö#§dfú®SFA0›[õí`má“Ú7–Óär »Í¿­Ýú ÃÐh¡µZßyøëg[÷½õ4¦/‡NŸ @i%Å`G¨´†ƒe´MsmáâÖ}osˆX%tbök­1oý8/uo <×:) ÀLÂz»öçAza¨Æò¼ÞêBA÷؈-öØcÎÁ_GuhVÌtEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/icons/fotoxx24.png0000664000175000017500000000513611701011016015155 0ustar micomico‰PNG  IHDRàw=øzTXtRaw profile type exifxÚ¥V[’) üç{$ô@Çááìñ7©ªéí±'¼öºˆ.h!„P¦D¥õ÷·þÂC’D½Z˜e<Ü0¨ù~ÐgÊ1=²§§öYžäYDýóćœëw†øî ArÆë1dÏ ð=Arÿ÷ñlP ýÂ#‹êYÞ<Šg~>Í]¬ºÚ4f˜çU¨”ó>›x‚Ö^oì·—–Š–¸'Ž•c ¦ýœíñô,çs wùå9ƒvé§·8E¹¢øÕQ2–Ó å–§&>»¬Óµ+½É¾@ì“þb×±ÞÍ#Sz>M¸ß§ÿxöžuïu)HßìúC¯Ã߆ ØáG¹(hhŽŸbìW ´Š˜Pcæ‘;Ú@ìAÝ$4©ÑN´®Á ·„;zæ Ž¬çàqA!§ÑfγT`9@‹)ï_èÚ7®ý?ó$¨2Á]ø–~Eégmï“„Õzüà\àÆý¼¡h?AÕ+ÀíÓ“^¨0W°å~›èJ7ª‡Oå¶@OÑßD&Ÿ÷úcH°·Â¤‰P6*J†t`v"² F¹rî@€TyÂI–R ØÔ“Ô-aÓ¥ËÊ·5 Hh1$c=™°Düq©àPÓ¢¢ª¦®UC›“djfn§¸5/.®ŽàÕÃ[-UªVƒZkÔµOãFDkسÁr³Ô ß éÜK—®Ýº÷Ú£·ú :lø¨#F›<Ë”©Ó¦Ï:c¶E TZ²4-[¾êŠÕ6¸¶Ë–­Û¶ïºc·jô¤ð÷í7P£5¾:zþB R÷»O_`ä`ÄXˆûA„æƒY®$¹ƒYFV(ÃI=ØLÊŒ%Yĺé…Ý¿ÈýnÉ䧸ñ¯"—tˆÜ…[Zú†Û¨ÍsaŽ ±; OLsAö-î’w†¦A/k¡KØZ±VÓ@èNn %|Ž9°$ ñ›ÅIìÒ© ‡× EïƒOÈsâ½fÛ¦UZÝ<íLZ©Ä²’ûj'Ü+´ú"ï#–o·Ïb {ªo¢9PNënêRœ¢]öt²‰ó¥λG(ûâRžë¢´~S½ež²’øPœx¶s³by“1ivv‘ D Ô‚cYö˜3ïF ®mˆ ‡ôÉËzÕFãªñ í Z •=Ö©»({‘h™#ﲺoRàÌæÒs“º“O³EUdôͧÞ/éæ8©ÎŽô»tqàÊàUf3ƒ{gÄmjS– ž ûcååØ@å * |?ì¿Áì(¸d@¿V@> d!ÇöùÈ&\×U¤Ïb|háBÜà˹¿ÿn,2!®CésBIT|dˆIDATH‰Õ”Kl\WÇÿçÜ×Üy83ž÷dÒ‰M,Å™¤;Á-©JíÐDlPj©BD)$*R¥n+V"% ÔZJX"!hEœ¨UꋉcJe»?fbÏÃöŒcÏxì¹3ž{ïÜ{ÏaáXm –ðßœ³øÎùë÷éûÀÿ¢®\¹ú_×’ýËÅ‹‰eY*¥”twÛ¯¿~…ß¾}¢(¢Ýnctt¯½ösD£‘ÐþcªK¦)nllìV*ëùúÖÖƒ¹¹Yó/w>yÌ@€……,®^ýå7ûûûÆDQ¤ËËùWsó¢ ;Ž ”6çæî¿óÎÛñtúø5·Û“dÌ5­I¡L ’a[öÍX,òÊ_~Y{slì ‚™™Yd³‹ÏÕjõŸ$±ç À,ÉŸÝ›˜`½=½§"ÑŠÅ⦢(êððˆÏçó]ס54ÔëuÔj[( N0äÿLoïþ¬¾UÿðWo¼ÑáÖ­[®¥¥ü Jɳ±X”Ú¶MÖÊåx¥\9è÷ ºa˲ˆÛíñV*ëÊns—„BÝdn· ·G…ªªØØÜ ‰x"A©ð‚,ËO ,¤ûŸ¬Š¦iô¶š­t.›£çÎ=x<Žññq¢È*ŽíÇ>ã8ðxÜ(¯•Q,A)c–e9œsÄâ ÒÝVJ¥ÂwZs¨¶]ÿ¡àr©Ow‚—L3™ òùe”Ëe¨ª ÁPŠ¢ R)ƒ3†T*…ƒØÝm£/b³Z¥"á0¢±($QÂÞþ=–—ó$‹»˜Ãoˆé!„Гƒ§0xrÙlÕÍ÷F:F«ÕBc{~­‰ùú>øàCä—óp»=Pœ’$¢ÿØQOÇÔÔ8N’R©¨Š²,ÅAç­V ³³3È=Èá/½„`0ˆP(„C‡¡¶YÅßÞû‚Ýa<ó̳øýš­Êå2æçç`u,\úÑepptùºÄ@ pVp»½ç#áè©#}}X])b­¼MÓ`š&!:““ŸBQ<ý§ÐÓ“‡êv! ãHß$“O`zz¦iâäà)0ưþp=#îgAÓÐõ6!àœce¥]7 Ë ù"4MCêð!ììl#“™E.—ƒmÛƒúú"ÑFG_Àµk×J¥<˜$–eq?–eó½iØ7!„ƒ1†r¹Œh,ǃ·Þº»wïATI@»cã¯wîàÒåËèëëÃÈÈ0J¥"’É$8ã €c ”RçüÑ 8C»ÝF4Åää$>þøDxñµTÃ}.|û¨ÚÖ®_¿]×q,Ý¿—`J9¡¤I8ûûï~A pŒÃãvÃï‘! "¤..‘¡7ÀÒÒ,,,@–¨ª{oÉq®QíǶÞ#í‰1†H$]7P­nBPt cGÃj™#·-Á‚ ‚ÕÕUPJ‹EaÛ:kK$„ìà„Ç<8çX]]…¦5ÐÛû躯χV§ƒF ÊØM²¯ m݆娀h4Û¶¬QBðAxŒ€1UUáóù`\.†Ÿ†¾Ý@}é!Ú‚®pMÝAie ‘pýýÇ`ã¼R©Ìw:ˆ„ÐuL–ÁìØ3¹$JÐuû|]д8FFÎlv‘Ì|þ9 [ „Àqlx½^œ?žûý~d2sfc§ñi¡˜õý÷ÿ\%‰Dò«=‡{ïœ>}ºKkî•R‰ë†ñ8ù-LJ…ÇãQ/\øþ«;;÷ïOÐB¡Ó4H$øÐÐSèéé5+•ʯß}÷½ßY–9{÷îß[º®C¬V7–¡ð/Úzûâ‰ã'º‰ÄƒéééŸÞ¼ùÇ`_êšP«mÞñÅï]:{öÜw$IŠsÎ)!0LÓœž˜¸÷›±±7oišÖør« H¢äz"• …B!O³©ÕëŒ1ÿ.ªªªxæÌ·º"áp\”$—®ëµ©©©j&3k<yþÞýë_(€×~+3IEND®B`‚fotoxx-12.01.2/icons/busy.png0000644000175000017500000000472711701011016014445 0ustar micomico‰PNG  IHDR0,#;gsRGB®ÎébKGDÿÿÿ ½§“ pHYsÈÈý×;tIMEÚ!17ÿá WIDAThÞå™il\WÇÿçÞ;ïÍ8ãuf7ìÎd ò)½@ʦšÒØblíÙýÓUyz1Á/ ·«ë¨gLáè‰ô¤çRJ) #B¹X;Å‘?sb°M‚ö.v'fX´È秇^›™ÑlŸ‘àŒEÎ/ÆÂUɰšËÎÝá|÷’`?É ¿^Ösl,#81°"Q]pþæDxüûmrøÈÁÎKÐ×Ù9*}ï•§ŸyfÊp<ßñCUQœ1ZPf«)+(8urðn_²\ÊaŽ]’²`?;üráÓ{zÇÃ!.8#V“XVôaz¥Ëõŧ~t½ïc‡¾9x)1ðKQ?{6“¬L<~hßö’ÍÖòd) ŒLÓ„M ò| 8ÑF'^~bó[G}–ûέãããÖ€‰túxy29Ó×ó÷­©5V2^DYÃÍæl_/@$D4ÑóìÆƒ]{?‡ïèëë>w©þ/`bôp<™pxmKIMK.Võ¦²Næ?TÁ(ûÖKk;÷þåvÉiGÿÁ7Çòá;/0™NLÄã‘ão´%Vµj…fßPãÚ±Wk÷½´û3~àr »ût¾üæ &ÆF;cñ¸85ðú¶ºú-†Ïó¡çÓ‡ž_ÙùÊ·§›û»»OåÓg^æGbt,™´ÓC¶¯Ûüñoj(úú_½UÚ|{ßÎÑ|ûc¸  ×E¢¥Ž+™«,+ˆT(Nùåð•ï M-mDKSW_{۽ÎdÓ2T8»zEÍÙá£=»R•©ýéôèG`SKÛ#E‰ê–«oýÖ˜Mê)a²e‰éõëÖŸ:>ðæ®DUe×äèhú#ÐÐÜúPQ¢º£}ç72–çe­ÉÞM^v¨ÂÑÆ ÃÑÕÄU§6®]}b¨ÿýÉŠªÎ‰±³4ÚÐÚþ³h¬êºæO}]7µt¼ÃMMk³Ë×TNTT•ÔCµgOO˜¬¼íÐúÕÕƒCG{ŒW-ß75::qÅê[Û,(Yþ‰Í·Ü#}le}-VV¥œ",âFV]'^ê;É¢©øè©Áˆ[xM÷úÕU‡†öý"µ¼rïD:=uŲPCó–v%Rôéú›¾´,pÏ]µµ)™¬L_ð4ZVÊüšg«cÖ;2?Óqã-?”`¿º¢#ª®~ªªyguyª,ycKu$UZ@™ÜŒô}Mr²$'C2r]†À&’fH¹¾•ˆ Ťtç†Od–ÇÊ+̉ôÙcK>-[nEËVÕÕÇ·µÖ*«R1ò|_¶)?L7žNûæi~óM/ß½”8­èIÿÑŠÛŠ®k\É>¶")%Æg2RJ¹`×n Þ.(‡ë[[o_R€¦öö B-\µ®±·¯K’ízRB·.îhOä7m‹ýž$ݹ¤^T† S¡íU‡æ—‘ãù2¸ˆÞG6·—ލXR)eJ„ Y]U )!ƒãù‹  °Hu‰ ,íðeµP ADF·pltB.* r+€ÕÑÑY’4ÚÔÞñ@ÃÆ ÷Ô­Y1}ŸFÒ#rv&-£¤S±°¨HØ(.EE@ETRDHe*W=¡p›Â¤yïœ5ÎÌ•ô ºu†Ü•ª¨O§G.ÛÇ݆Ím×~o×WŸ‹9ý%5Æœ„ààœA0BHÁB(Šg –1_‘1rYz†6=7]Ë@Ó2HÏÂyîTí`oOwãeù¸[ßÚz½`ôpE,ìªf®©‚H‚àœ3góÅ Îhþžà`‚ƒ1®àž¡ºž Åõàº.×âÚ¨(ÖeHÈâ†Ö¶_ÚJè›ÇÞxCËç¢ÚÚÚžzô¾:k¼7ªD–AAQ  „—AQ")a%¡DÀ<¤BL(àB™¯H’ Ï%h~A"ŠÇKæ,V2§«Ödz´;o#ÐÐpubMíÊâlz€u=ûÀûjaïº_àž†m™0M¦aÀ4uX¦ÓÐašóÅ?×Ôá»&VΖgJ;<–7€þþL2Åë?£]ÓtÃÝ¿‹žM|@úÒŸ¯T"dFÀ|ÝTÂe€O€M€+MX2[° Í_9X~¦§Ár²˜tí쾉ø $~›÷EÜØØXõ y½\DegÑdàã7ý÷¿‚ÿ¡ËdO~€myMT¾§]°ü,è„ûñ­ÏIEND®B`‚fotoxx-12.01.2/icons/zoom+.png0000644000175000017500000000240111701011016014505 0ustar micomico‰PNG  IHDRàw=øbKGDùC» pHYs  d_‘¡IDATHǵ”ßoUÇ¿çÎÌvÙn»¿è¶ÝÙýÛ‚@—˜>@âƒ5Æ`Z£„TðA߉%˜LŒ„À?ÐMÙÅ_Ñ`â!!ØVK Òv§»;+[ØÝv—Xº;3×fÉŠÛª$Þä$“{çžÏ9ç{ÎþçE«?ql7€^Ý‚æv À(€È‘Ã_=àø‰cÛœ&&úê‚F@–ë=®ÚZ€#Íç⪚ºs;Ƹ¡%:rx`ì_̨#^_KtKg{ –6”Åe,4*€Eä’s9BÖ41y=¾œkлV6Tæ|€ÑÖ[ìnq>Í0V¹Äš<äÏgTiöæ˜@÷j™ˆeß§ëåÖhÛo‰¦y¬´9›\tOÏgdhyÔŸ#Ã#šæ±f¬—sÑ”:{À3•¬Tb¢okgG@Ióă( ŒnÌgåÁþ ö÷`z># ƒÀˆ”4OlÝÜ Aô™å­ Ðëml2¢iCá€Á•þb¢ÀÀ‘10Ê]]ñ64fÇ­Z¢îPÀïQr|š1†¹ä¢{JIË@D z á‹Ë3› ³y½Ú*;3¹c)ô?™Rgº×ëÜafQ/2F˜RÒò`ÏÃ(uÂ`ÿ³àÍ“—ä¶ ;[¸—í 9kT¯)²]Ôßà´.ôMšacDDT"pιÁ9× ®çÿ(Ÿ_™›Õ4ö„kVëÒ‡€Øì’'T_]s+™ËhÆ{~ÝND<èûð;€v›uÊàd<ÑXãÎds9éµ£±xbG¸-˜]XÉØ­RÜå²Ç%I„šL?WZšê¿×5]G±¨aû†Ú€¦\]«‹"©¤Âvlptج‚(DÆ ì¡ÈDFI!ˆÆP]%‰Ûšk:n«Q R P>É?Ê¡ n_P/WY$Hù{÷ÙÅ|;ðÖ9§ÜN{¼PÔP(hèÛY·óNâ&ÊÛGT´òI>¤Îßu8œ oõv~veaÔ hëÝö¸¯Á·H"8çX)h°JL|­»¡»°¤V'”^ûV¹âcçoÞݾå©À¤º|ý·ßïÇSy}I`]¢£Ík ll´vŒOL$bÑé&U×®ýœ¯ªªÿäܧ»Ö ÷?xo»$I§ÑⓃ­Fs(T¿Þ娀»Ù¥¼‹§󷘮’+++oON^>øÆë¡ñ± ŒO(‘¡‘sTþ St€½{ôÝV«u/cìiƘ ÃHèº~5—Ë_<ùÑ©o`ßþWm6[o>—¿ßw`¿õì™s¹ÈЈãQ@ɹ`êò¨•À’i„O¹@{ù•½cáp—kæÖ\aÏK/ZΞ9·±=*2™©‚ ¦­`5a€€âðù »üwÙ¾¼øqà`ß:÷"C#örÀ?-@P,æ>>áy—Âá.˯¿LVlÓrܼ¬›e`f†Ëf&T&déßÌðù a—ˆ¨.24òÂþñן†5ÚŠ×0¸IEND®B`‚fotoxx-12.01.2/icons/save+V.png0000644000175000017500000000211311701011016014605 0ustar micomico‰PNG  IHDRàw=øsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÛ /(ðÎæËIDATHÇí•ÍkTW‡Ÿsï¹sïÜ›˜ÇNÚ$Z Ø„jJ?ˆ-E )uáÊE‚Á–.»ÍŸÑëfו‹R”b¡E ¡ÄDB›`l‡8“Ñî|äÞóÑE2Ó±`WnZúnÎá=¼¿çüÎ'üÿùOܼõý…4M¿Éx™@€B F)Âc0Z¡Æ¬±cl’$ Œ½pùò̺7øî÷u[(l¥R±qÛ8Žm¥R±¥RÉî>l-X výÖ-»²²bï,,´sV;N7×®}ý¾çùýAÅó<„Ø5hŒÁC½^§væL»@Ý»G¹\¦wm­«öìûéUÇóý+#GŽúùöçr4wvØÚÚâB§OŸ’¦)ÕÓ§ÛÑÊ û××Û¹ÏNùKÿ@çRþ|{ðyù9™L†lEZkêãã¨þþ6ÀZ‹óðᮣX›êÔmuÄüüü‰Ù™¹~?ÚÄ£ïehx¥ÝÝÝär9Þbgj €pu«}{Òsç²aîêÕÙ÷Z.Z'êÊνjç•R,--ñäÉ666øm|Y«Ñw÷.²^à×ãã|øÁG^&}ñ2à]\¥ôg*MY|¸Ø~´¼Ì£åe”RäóyÇAArò$zÏé›×¯ïÎ>›å—|ž‘‘ÍÆ¥–¶ˆ¹Oæ&B­5Æè6 ´Ö¤iŠRŠ4MI’%%/&&è{ð€ÒÄcÇáû>=ûzÂéééI@HÀ‰¢ðËËb±ˆRŠ÷ï#„ ÏZ1Æ „@)…1×uq/^„Û·ÖИšBJIš¦LNNzÕjõ+àg 8q­6].—ÙÜܤ§§Çqp‡b±H±XÀZ‹”€f³ ‡1é8c0RR;u OJÖÖÖÃZ­vpåèèè¾j¥*‡†‡88|Çùëäv^´Öì1hcÐJQØÜ$ŽcêÍf“ÆÖ3´±”JÛ$IâvK!DWæ@.çÎ^™!ÈHÏ#ãepÜ]˜ÞÙ,¾Ð…D]Ýloo³úø1ÏŠ%Ò4Å‹Öá8Œyß÷#™$‰‘R:‹‹‹ôöörüØ8a6$Žc¶ËÛ¤J¡•"Q ?ã†!aWDd1Zïºv]Ò$ÅX‹5„@JI¡P0ÏŸ?¿†á§ÖZÁÞ Ú »·‰žçÙ(Š‚)%I’Ðl6‰ãcLg­ÕjßÞ¸qãs¸€ôíµâ5|)Pš¢ãɯI¼°ÿþ/óO} Ë7'½@4IEND®B`‚fotoxx-12.01.2/icons/save.png0000644000175000017500000000212611701011016014410 0ustar micomico‰PNG  IHDRàw=øIDATxÚíUkH[g¶íVpl¿úÓ­ÝeÿºÒÕÁÖ? ¦l3QÈœˆVìj:W:j°kÕ6CVZœV·U!³VL¬šÖ¤1ïwã]c¼$Š—ÔK¢ˆ9Æœ>ûÞšRèö«ƒ x8_Î9ßó¼Ïó¾'(**êÅÿÿB½ñái­®ÞýÈØä5›„f“NÐ7?脇úF¯¶©ÞÛ U{ëjõý¡VsO¨©½ëUUUnªT'ÿV€ýé Ú%‡c+++ØÚÚÂÎί×××177‹ÙÙY8NØívLNNÂh4B£QãNEù$ã8ðBzPZzë}“Åà]]]ådÛÛÛDίn· ˜™™áÄCCCèííEGG, Ìf3~)¹¹§T^yç¯ýv§¬Ä¹à|Bz<<^[­§l6ŒŽŽ‚¯§¦øzpp0 000€––Ô7Ü÷^Ï¿FžHàÕß+~ÝWÚÝÓ›m‹‹‹‹fÓÓÓ˜˜˜ÀÈÈ'íaï´··CSWG.Øs®\½¼LÅ>'@Š …"Òd6îû|>TUWsÂùùy¯|¹ÙÜÜäΖ––ÐÝÝÍÑÖÖÆã©¾W—Ë…~TúÒÒ’=uˆçº²°ÂõØÅ0± 6›*&ðuss3åN BNÜÙÙ‰ÖÖVj2wÐÚÖƒÁ€ŒŒŒ2Æyð™À»A‡ó ®níïï³l­¨olÄØØÆÇÇ Ü)šááaôõõ¡««‹â!b. ÖÔAUu—;?“zÆÃ^áÜd%55õTYùí}Ê¿¿¿ŸšGSDÑ)¯ÚjµRîDNÑPs©±Ô>U:½žÞáñåääø$ÉÇÄÍãÉÊʬ¥Ê¨¡´™ˆˆFrccƒòç‚4¾ËËË”5ºÒTÑ*Œ»t8Ðh4`E77ŸfI \µZ-eKÕQÏò&aån2™Ý#—tèxt:är¹q ?ç·Ïر··Ö‡ü~?MÖîîî³Cçñ#Šƒ€•‘w1&K ‹êTª? •JÅ#Ao'&&ú<7¾øRŽ””d¤M£I@fV&Çù¯3pöÜWÈÊù/]B~aŠnÜ@n^bããùÉ)ü|‰cÇOà½'‘ ††† {+99Ùo6›žq%¥%¨¬¬Dqq1ò ò‘÷ýeä*rqịP0ÂkJ%~¾u·ËËñSQ²¿½™\ŽO¥2œŽ•BòY,$ŸK‘””$¿I=x-&&FM1Éd2‘á [ÀþÀrYóDæNÌÎÎÓÓÓÅ””1>>žöÀâñGGGW1î7ø‘CC(CØKÀQ†×é,<=ÉIˆn¼Dçÿþ'óOwD´Û—IEND®B`‚fotoxx-12.01.2/icons/print.png0000644000175000017500000000172511701011016014612 0ustar micomico‰PNG  IHDRàw=øsBIT|dˆŒIDATH‰µ–ËnE†¿ž®îéÁãÄÜ,±`ÙØA €E$"/x? ÁˆgÈ" ^ „¼BÆHoXp³Y„EÛÏØÓ3ÝÓÝÕU‡EÏŒo=’ â—ŽJ:UýÿuΩSÕð?Ãy¹Q‹T€Oûã¿ÁÀ Ë„Nâ³ýý}I’ä”õz½¾ÅÒëÅÇÇu»²¼¼,Àó€{’L•DT¯×±ÖÒív ‚*Y¦ñ}K’$ˆ@(¥@×uÆ€6`F ƒˆ°¾¾NµêS©¸¤iŠïû(¥ˆã˜Z-Àó|Þ Z­BIZKó¬³ ­3°Mš¦¤i‚1†,ËHÓ„0lÓn‡¤iʃ£u"ƒ œªkiÆäXkYZZÂ÷}ò<§÷¯Å1žç¡”ÂS ´ÖȈº– h“ç9wïþ€[© ”":Ýõz4I‰{=n..‰eĹ)ˆâˆ4MØÛ{Äôô4{û»¸®Âó: 7ù…ඈ¢ˆÍÍM<Ï£R© µF)×­¤)¯ÍÌ01qy˜i(z@Q4›8 ¨üû+++÷ë33¯Òj5ÙÝÝCkM«Õ* )B¦5°ÃÇ;ìì<Â÷}:Ý¿üú¯¼|åã§jµ÷ƒ/Á‘º¹±±±þúÕYZ;]ÿŽF£YòYDQÄØØ‹7®óÌs“4öùð£O~ÚÚÚþè¨þîoL\çÎU®ÎÍñöµk¸ý-ƒˆíÇí€HY–²¶¶Æô•—xñ…É…­­íK@<¨ó¸Ñ Ýycþ­ íü,:#¾úú”ë’$)€8êxA›LkVW¿@÷ R çüÖÇ¡ÙlT«h­égæX Ï3ž}zœn§E·¡óc b‹í§ÂZ‹5Ó'5¶XcÅ2^ÃQŇ"‡ V÷‰1ºÖÅXÇ"F†s'q_–žQñ2ˆàÞíÛŸùµr<Êy³"ÓsÖgÅ‚ÀãÆÁÏôû@õ•¾?ç½í½íºv´[—¬Æd€,lꌊÆã$ü¡Ä¨!•™hL4A6ÄLƒSF‘ÀˆÉ˜§Î%‚Æ÷ܺ¶£ÝZÚõë½÷¾ïëÎ0‰ñùqr~œçœ'ç<9˜H$ÿ317¿ r6›Å[äa„ȵˆä:ÞâÿkŽ9¨ñ¯ˆâ§šWÞšNfÓé”àÜápz½Þ=…¯‘Ç„T‡Z+‡bv"#ÖiÕØo÷lÊÇó#]WÏö÷Qš¯¬ôWªdEº8rîTû³3 zi‹®!dÞ°'&&ˆ˜Tév½BÖ›Cý»/}\X²áåŠúÅÊê5¢¨ŒÝ<>ô¥³þrý‹÷ÅaJO€z7AD…v—x×s3:¹ýÊ^©i[·/6vì0â1J)¥ÔÈçhO~îüê-¯YSŒìïWô’ïú=ˆ®K{èÊ7¶©?˜}}bz&™\¼gOéÂ…ˆh5®îèà±X…$‘–ϪƂœ›N¦\åÛIñrʤærAuµÔÙy9PU»kW‘ŒˆŠÓ¹|çΫ ȧŸ`ÓIµùj–MçÖ"Ñgù¥ªME$B¤ØÃy–.™ë?E×õö­i΄€àr¹ÒéÌò…B " ‰ ’Û §ØmŒ1D‘sŽÅ"DTÅ´,Æ,DDÆœ/©Ô?ÖBD!fNô»]¥ÀÏd³‡åboMÓò¹,û ¾9ÌUu‘»ldg×òíïI6[Q^èøñ²LN:}Ú òUqfÔ×/ŒF£ˆH¬á‹ŸuTý^îÅÒRéÉu!Óþ³|ë늮O9ªÆbwµm`ò`Wúƒ%ù{z»dmF£QÓ¶ÂÛ,»îõﮜ¿DŒï<©õi¾qC$‘°,Ëïó9Âa³w]¥ÔöRsõãIÐZ  ù³ÝµVq|îÞ(®LN¿ŸOMDÍí©©©©­]äò”ÓäCC ªI»=îû[~±•maÙÃT™µ´mÙ«{é½ñ‘x £q¥ÉL!gôŽÜP”a+ÞÐÙà¨|37õ!W‘”†4}bGçy³õ¯¸'—¯8õQ_ÉdÄW>O³kˆhFb*žHßp®ò.mc%Gs‰/,ý}»cþìþXD3wØ=ÏpslâZdüæƒÉLÚ4MB–e—Óµ@ ÔY’m1ÐÌorY×ìþ€ÄøN2R%œÛЧóÚ¹C¼ð·ìnâBü D¸ý‚LÈ6tIMEÚ,DFr£zTXtRaw profile type APP1xœmM[ƒ0 ûÏ)8B^MËqºQÒ´MÜÿcé(£H³”Äq–ò,ÛzÞÛk^† R 1Ùh†tBäŒ;’WDúrmµœQ¯Ãy j®Æ®ßþè‰kôF¼SáGjI‘‘Iú‡Ó¬‡&¸&i:vaAqÉ^Á;‹rUFç$æ]ÅãàŸô? Ã!§lzTXtRaw profile type iptcxœãò qV((ÊOËÌIåR#.c #K“ „ÃÃd#0Dš€yæ@qCss#3K³ ×ÈÌÔÜØÌÒ<ÑÌÔÈ€ !a`À=ù˜¶%Í äiTXtXML:com.adobe.xmp 21 21 1 O÷:œIEND®B`‚fotoxx-12.01.2/icons/drag.png0000644000175000017500000000075111701011016014371 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk> vpAgxL¥¦FIDATHÇíTKNA}UÝÌ\`XéÊ)¿¸ A]‘˜‰ºR#0†pÁ½7ì 3]. D#=ÄDMx›î®ª×ï¥ú¬ñÛ ÛÂòné)Ž"Ÿˆ k:·ÝMÛ ÄQ”ož¶h¯¶¯âi¼a˳˜8%µ@jCÿ^@/Ê•â³ã/Æ=×È<×›JÛò1OD`æaç®›ÿV€˜üæI+áDDrD„L&ƒjµ–#¢Å<®®/Æ³â æÎD$17Æ|ZÏÆå‚áÑñá-òÂzý KDh·oÂñë8 @ˆH8ŽV>¬R¥0íõï¥ÿГby'²åiÛÂw‡”R@Š/&Õ5UJAk ±æ­ú¤ÑhXqSµ( Cˆ˜Ù Àü˜€£õãùÅÙfÅ/£Ñhéækü ¼`toÚ®s"zTXtSoftwarexÚ+//×ËÌË.NN,HÕË/J6ØXSÊ\IEND®B`‚fotoxx-12.01.2/icons/folder256.png0000644000175000017500000001672011701011016015167 0ustar micomico‰PNG  IHDR\r¨fsRGB®ÎébKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEØ  „ôýPIDATxÚíÙs×uƿ۳af° ’ H$@‘EY’EÙ‘m9Зı#Ñ”¥rª’ª<æ%yLþ€¼$OΓòT¹¼Ð*©ÊñR±%[Žd[RdI¤HJ"¤H$ˆ…À fé¾7Ó=s{ ¶ÐóýX¬ééééit÷ùî9çÞ> „B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„BÈú!šõC§Ÿ;}ÄPê”8`'OýÊP ³†BÉWøÃÎP<+dË À™çžú3Hã;Žðt¯7ü \´þåÅ_œãé [R¾ù­o>- ¾ ÉS½!Ü4ž>{öì«<dK À™3gNÂ¯Óø7œ¼âë?þÁ_â© +ÅØ0e1¬¿§ñ7…ŒPêWgΜ¹Ÿ§‚là[§¯ØçR›˜ölÉua¥”Ëeäs”ËfØ&WÌ’<õ /ÜåÙ"›*O=õTox¯½öîÝËù¢-Cáù3gÎŽŽŽ®êúl¶ Ÿzè¾°sùh¶+ó]ž=²%```7º»{«.l_߆‡Ç°oß²ÙN^F\¶x†¡çîêº}Ý8zt88ÌRø›gž=ýóÌé'yÖȦ @&ÓèèèBggïó½{‡yEV@_ï.ìݳ¿êþŸ8q=ÝA›Æ”ÀÏœ9sˆg¸<Êæº¯1@: uo‰$Ê夔0Í,;áÕr18Ç«± ¦ebvn™L;R©¶Àm:;»Q.‘_Ê¡·¯ ss XZòøÚ±£ÇrñâÅÛ<³­Ë–xàÞ½y(©ø¿ÿfÙÄ•+—0==z>‡ö §»PÀ'#“ ‹ ùÓÓÏf­Æ&¾¢T*B)æ¤E)…k¡P,bpoðSÃC)…™™iœ|à0Þxó"LÓW&`Ÿ!ñö7Ÿ=ý$®óÌn=„@B]{ùìÙ³ŸDR¤’€U09y–UÆþ¡‘ÀÏ"K@©[8~ô Þ9w9h³6¡ð8*{ +¾ ©Î<ûô›êŸÎ~ÿ…—·}@gzú6 …%^èUË-¢P\²ÇøéêêA2‘„i-A˜]àIۦΠöB‰¿>~ìèÄ… —ÞŒ ”¢°¦§oò,>tBøÓ:;w ›í@[[†øhü&Ï÷ö%¦þã™gNßùÑžÿY$Àéê"«gff/ÃØèqÄãþËšÉdqìèIô÷ïFÿ®Kxç÷‘Ïs°Õ6(ÐXîÝ›Ç{ÞÆ}GNŽB çúwà‘‡ÆÔÔmLßÅüü=˜ž"£åR9h$¡KJ”Ë冎¯R³`ùël™ʦ©yˆ@eü“ÒÖ {ŸÑ.u`YKKIò‘ÓÏ>ñü÷Ÿ?·í@*IXŸœ@>‡óÞÆ‘ÑãhooÝ.›íÀÁƒ8xpkÿ=•ðÐñeå>Q1pJÁî&µÕB*YQ T*)Wî1 –iUÆVI@)ËÞ·½;•Ò²¿§ïCV·U€¤”Pv[AJºBZe/׎É9tY½ß½¿]5tíû ‹xë­÷aYnA6$ž°ý@ÉÚ#k§XX¹óoadd»úwGü¯U 8 ±X¬bTBAÙ߫ع²EBÁÊPU㔆² Ò£bÔ†a¯žÇr¶q —R†¶CÿMp)Mø ²™6d³i_é7q !€e™ôÖÝ.,|xùffïâÐÈ ìÚµñX<š¬ªÿª¼­ ®ÙÜ­w}@û¶ªÜÏP ÒåqTÞ+'”pr.Ï¡æHÍ»¨å="*Z&†l ù\W®¼ññËèêêFO÷d2$I±bÆÆÝ†Q‰ÁW“¬$⤖Sî$ í^×öïm1Ì~U-|€c¬Ês_ëïUˆ¢m¯¤‚•ü˜’g =€&z\–‰»3Ó¸;3Í“±Í›È =Bš/[BÊ&{Ù €9€­|Í•Âb®€|®€RÙähÉ"™Œ£-•DGG±ØÆ•í`` R(–0õÉîÞ÷þ"­…atvd|Cµ#&|È9SS3¸yó.ÏPéõ˜›ÏEÜàÃ@PJáêÕ)>¯Oš ël‘–ÿÚ5?iQ(•J--““3u?N¡½= Ã`Ý®Vi–ò,æòn[äi@µ¡£¶2…¥¦¦æ?ëéîÄg>û0 Á0 ZF‹q÷î^ùí똘¸¶I2:9€œ©J)àã›Ó*?¸o7¾ñ—O"™LÐZ”ÞÞn<õW_ÂK/ÿçÏ`7b_$-êÌÎ-b1ç/ËÕÓÓ…¯í‹H&ãà~­Àç?÷iŒ_G.ç.œ+ †Öºÿ-áW*Í h•¦earr6ð|<ùÅÇJ%y÷@"ÇñãcA–3@µž0õÉ\ÐDÆà>ŸŽŽNtvv£­-˜ =–´‚¶âjUÚ g¥,Ër¥°ke®"µ˜E*ç)âj¡ßðzE÷¶aëEõÙöš¸·U.ãt6Ú²Ò*ñ¸-ɽáÙ‡gß šhiûÓ×{ŽC>hÏï»Ãÿ{uõÞý7)­.®Ê{®ë§Ï-"b¿[ðdëxªÒí¤özíí™êû¾Þ~ŒŒŒÂ0V7K°a _A Ý ÜFW3|hÅ*B Þ'Â.–YO¼†&´ýyR7@À„¾nŒ®ï ¿ëÇá1|]˜üÛ†ˆ‡vjû ýzUÏj¬äá¶´ÎPàùù<òù’o}ïŽnœ1Áĉ ðúoᥗ»ìvíèêê@6›F<±}¦±ŽÇbhkKaÇŽ.ìèCgG{¨„÷îèCgggm|»=ützú6ryV&Íqšj]õŒ¿³£0‚tº]KüU¼€B±€[·nðn$­!'NŒa×®¾:Íû÷Dÿnø c(àÚµ+‘"’P*?ã‘GNøÖÇb1¤Ó¤’)Oq‡íCPeãD<;ì"þ’]S·oa~~–w"i ;€L:§_3Î`hß0vìè[uõÛ-aüAõó´Z÷AŸ/..àÆkàì?¤eàÈèÁj+88¸û‡†·m‹¯·än·Þ3aF@EÜBa |x‘Oû‘½Ë€»võAÃ‡ŽØ1ñö½$*¨â­ 3|gY!ŸÏáÃËašeÞÙ¤u<€ŽŽ,‰8FFƶ±ñ×Ú×§} ‰;w¦pýúU&ýHë @º-…þص§eÜ}˲P,qo~·ïLai)Ï»Ž´ªÐŽááߊ\ŸÇôÝ;¬ØJHࡇD"á/}µ°p.¾Ë˜˜&ÓÔôûáC#¾u–%ñþûïÑø ‰ºtwwûÖÍÌÞA±ÄÙn‰|àÂÔÉåÀ0„,ÇÆØˆÁKCBC€Íñl#B6# @CB€B „P!Qg‹L»ÃnB6ÃFè€B „P!­Á¦'8˜Fì„!„@‰HàÌ•G¡@¡B(„( ˲™Ä7Ëðk“hBZB”òNœIó'¤>"J à›X“@ˆÏè…Çî…QYmõ]ÓfSÑŒÝoe#M÷jˆ³,A7€å\Ð ß^iBð "H¥<"@ó'¤‘ÀFÑ\@J_"@H#!@Žñ+- ²Y‚ÐdÀmülþ Š÷ý±ÿF…›Ð   €` !9Ñ ©ÏH%Á^B¶›4@q0!+ˆùE$@ÖÆÿ+§€Ý„ørB¨fD›0¸²P€Êð`^tBjv´2`¿îB– "‘Ê?ˆ@Èòæ‰nÀŠ×¯ìࣀ„lªÐ<B@)骦šõW²­l_Àß …‘€€¿ƒB6¥õo¾HmPµ^! 6> °©%Á4¿€WœÝWŽäãÀúÇ®@Bêä¢(Êò¤²¬D¤(¨p‡´B‚Q®TqD¥€Cñ5”¾ªÀQ  0(¯7!!nÀÆç6o^[ „`7 !>óoN=ÍÌÔ†BêTr€¬åH@Bê¸ÿ‘|PTâ@ BÂlÂñDT ‚Tæ=óŽ „¸Ã€(Î `a@ÈÖ ÉõT@½„,×úoûn@!DenÀjë/*õØ @Èò"‰Š@•¦ßeø4BZ$Ðç¨ÎÈ¡„x#e¿M¨HÌ XkókÝ’WœO¼ï‹ù£(m^°"!Á `ð‘xÀ6~­$¸â@ B| ecë¶ ]³3 HH¸Є ÙÝ€zìog@H°¹ë]Q¨T«X›@1 Hˆßü›4Øh~@T€Š# YÞÿGD¦¯ Ö¦#„øÌÝß À=ØÑŠ!Mkò73¨öø Ç  ñ²™4ybUIú9ãà®HÑKOP°ýs¶û²)!@ssROþq!ªÀFyMÍQ3~Aã'¤Žñ;,cú鵨ñ†€eY¢žP©P{6€â6}¡[}ˆÈHnˆÍÌ̤ëfœñJq!žcÖ¯yI{Yl¦Ä¤¥”bYÃçS€„ÔÕ€CÃ6ü„í ¬HŒu6þ6F>Ÿo«ÓþW£ iLê” ×=€”&¢™sŒ@›R*Ôpžp<"d¹ö_4âÄõFØ~m¨Õ^£mÓ_K¥R*¤íׯ(Ï'„ŠA­( @H±5ûuÃø8jI?Ó¶K˶KK3þ’×å6Ö †ÖúCWŸPpâ~¡w R ÐÐHÀ”èñ¾ãè^@|=B°Ó¸žR&ëÙu8°â0 BB½í¿¨oIO> ¦yé1í5¾!€óýGâžø{D5 ”pOJÑ}Õh a»ö ­Qw\ÇKö«…jaþÕ{ޱ;ªbhqì üa xf?¥íÒ¨±Ó_ox®7Ð1mû5…†gg†¶³ =öe¥—S´BÖ0CwjCK'¬I¼-вXv€=@AAJ!k$æ1n#d9æµùø* ÞNú¢¢ Uͨ†ÔB\^²×5nÀFbÚ·b¨t :¢`…ÙçJ=òª»Ʋ˜RUO€ÆOȺÔ‹€õ®žÅÕ†Þe}§±ðý:®¿öL!d½Â¯Ô³×U…1z—ª„÷¸ ò9@BÖ︡ ÷kÑÀ×±kYó”°CŽ Äç)¯„½_`ÅÛ( môû i‚ÐPâ`=å)¼IÂSŒ­?!ëì:4RkoÕ#Ueµ’oWÒL²™b_ÃNC—…2øËºÛϹÙƒ÷Ú¥ Y^“(Ï%ÜÅU½](—@Yt[” ³×FW%2¤õ—Ú«nûµ?Ž7Íö oãå#Ä&‘hóµ !•³”Ç6•&ÞeÔ8Ç× 2Ž¡[Z.A†y¦i¢X*ùZÿX,†T*Í«NHÚSUÔ„À ñdˆÝX]ÐÙ‰wÙrv^²JK‹Ë—Ç‘ÏçQ.—`še˜¦ iY¼º„,ÕËW}ë,)µFX¡RL4Ðú²\‹´Ã˜gYÎNÏÎ@¡ á.DxõÚ5\zÇðŠÒ ãW¯cüê ßz³TšÔ ßiéÍe M<­¿©@U…LÓ´ŠÅÂ9ïóù<^yå5\º4Ë’¼²„Ôs·•ÂGMàÅøù½……÷4,;ºàñ¤ÇV­µzºÑÚÎãö« s¹7Smmùc™üôg¿Ä›oîÄØ‘ƒèhÏ ñjâêRaa~—Ç'pãúÍÐí>þøÖïm›s ݲfì¦G°V€füÉ!(ðáå—>óXïß! ¹iš¸59‰[““¼Ú„¬Æ-kö£Ë]ÑZéƒR€w^öîÇXƒ8;/{~°@Þ¼~óÖÌÌÌñR²þÌÏÍÿ·mwNO@I3r§õ/{Âç¬Ö÷V¨U Ihûr¹:~íüûw%“ÉQ^2BÖ‡R±øÞoóê¿—Ëå¼mƒÅ€W§Qv^åuGâptÖ9cÔåËW~?¸oo*•JÝ/jµÁ !« X,ÿõK¯üs.—[pViFî´ú–fðíë-z)bðjP]ÿ?(ùût:]ŽÅb]†atòRÒ( ÅówïÌüàå—~ýB¡Pð´ðe-Ö/i¡¹“(µþö¾×„ c A›öjد@m¾òê„¢{öô÷tuõö†a€… ¥\.oÞ¼ùI.—+h ¯ÓÊ+­å÷¶ö@Þþl©Ž¸¬™„mäIÔ& MyDÀ™¹TÏè9BH8Îðzï€=¹çÄÿKÚ«cü¡ƒnâëppe-Ð9eÿ¸3oYµ©Š|! ¡>4—_j"PÐÞ×q_§ƒ*ÚÆ_ÔD@Ù"PÔ<}‘>c !$¥¹üJ‚’ö™Þ ç–Ë/¬g®iÛ¨S¨õ$áŸP”CÿY˜Z(àäÊã/£6> ià¸÷;Ó‰ë†ÏÖŸ•çt!p ßIü9IÁÒJ  a€“üÓ“€„ÆÀIøéá€×0Wj¬…ÓàÄú‰£gO!õÝ~°Îéç×s+~Äv£ ÏéûOÀ=u˜>£0ŸåE@÷ô ? %û6Kô߉ƒ @BÖC ô!¿k6Ìfã„ôY¹ÀJ:„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„l=þ{Œåg€#Þ—IEND®B`‚fotoxx-12.01.2/icons/trash.png0000644000175000017500000000231011701011016014566 0ustar micomico‰PNG  IHDRàw=øbKGDùC» pHYs  šœhIDATHǵ”ÛoTEÇ?çœ=Ë^Î^évË.»”KI*r“R ˜¢ úhÐÄã_ ‰Ï&Fã“/$ÞÐ(ÆÄh1M4‘@}À¶¶„”*-VÚn³ÝîҲ׳·sf×v×¥ʃþ’IÎÌ™ù~æ÷ß üÏ!=Ȥ]}ýσ+†_9µÖZe a5 Ž=2À믽JW§ŸTb¼^: …Cá±äB<õÀìêë x x¥9væ»AjBàq{)—Ë\çÄÇaTMb‰›ÍiŸ'ÇGGÆî ØÕ× øæ7ß  âñ¸Èæò„7„ùðÄû ý6ÌÃ;wðü±H¦¹pᇦP(J¥8=ø=ÀÓã£#çWµ( ÿñÁñw‰F¢‹:BÔ˜½ÁðÈ¿\ü•x<ÎÄÕ ffoÐÓÓƒ¦ilŠvS5ªD6FؽsC#c/'âo75-+-Ú¼y+337Ð4 §ÓI4² €gž=ÊgÎÞÂëõ299ÉÁ“ÎÜBUU¢‘M!î:ƒ»v»}ô›ŸÃ4MºººP…žmÛéîî¦X,’ËåèììdmÁ`Y’™™›áVúÖš€ßÏþx~ß^¶lÞŠ$I†ÛåÆ4‘H!¥¢Ž,+,-/qmjŠ¢®³¸¸ˆÓaHßðÞOþêàG‰ÍÏ1=ý>ŸI’BP(ä©Ut½H*•$Ÿ/`Q,$¹42†fWOßó$âWk²å­¡¡!Ü.7õî ›ÍP.—Ig2tÄææ‰Åæ¡^§R©PÔ‹ ^&‘H`&×.í¿ïyr€Ó§¾æó“Ÿâñw`Q­wü7*Â4ÂĬVÈf³„#Qn¦swiÉ«,ªŠæÒxâÉClv°wg/Ÿ ‡U&µ0æ°rà±ýä³¢Ñ(š¦±oïžÕ¤V¨ªŠ¢(hšF0ØIÏö¼>/áadYÆãñ`µZBP«Õ$ YnÝYé~€–BB¡Š¢àõøèííÅáp`³ÙP ªªÒXÃá “É¶kÈMÜRG;­R©Ü^aµât:q»Ýx}žF†2’ôïf¥U/¡†ŽÜP ´J¥õz½jZØ ·ÛÓØLµ9üÀº•°À0Œ–kE.—Åét"êµö \M»›+·KÖàv¹[«½/º®·¾ý~‰D²ÙµêJ‹$À*z!î³/¾dÏî=˜†IW×Ê•2Ùlö@l>ÆÀÀ~ŸŸb¹Êõ¿g(—JW€_…¡ža>êy ‰œßs˜À´öñ‹óñÒ.1©ÏÂÑrTAuß^KÏv>ŽTú<Û/gÐnùëÓx!wäJá¯óo¨°ñ™¿þ¶ðíñ[;ݧҧ¹ v€¹þ b·[ŸÍ£Ðõ |Y˜ûñþÛ³÷̽×- M|óû…>œA°Ã¹)èhÃ8îVÑ1 Æ,£t´Ø3‚ºIiR£}ѺƒÌR^虀:s)Á•Ç …žF›8OI`9@ Á,ï}½¶Ð}n½Ï”8yD™ ŒnüC»~Eègmï“„åß`ó=¤F9¿´ß ÚàoíËs}pT!vœp°•þ¨èFª‡Orc+3ô‘)æ³ÿ(Rœm0i¢TœÄÈ‘ÌA„@&jT’E¹2ã #YEØäIêvaOÐ-ËÆÏP£7…¿oÿ5zQã©#¨a6â鯛/Pr0b¬Äã BóÁ¬$©òAî`V*#+Œa¤l&•FÎz‰.bÛôÝ_Èý+Ü.×ŸâÆ¿ŠÜu ûŸÈݸ]Ë>áöÔæ¹0ÇØ“…'¦E}¥/êìmâé6eµÀ-a•lêI DþŠ …ˆ¶”±ªÄ•TÇtËÁ­NÁ•U}ÁçÊQ¯*kSÎÐÅÍX>—,ìÞ94é‡uEÙy,Ö:¢ê¨ƒlFÛc^]ó‚·¡^iÖ÷j›¾±¡IdGîò&Cyô\‘c"¢…†ÂGv¡ ðHŶ–Þ ¸÷Š’©p ïN¬]ti£†€Rutƒ¿»Öd÷kȨÀ2,:­1u/„ðT4p³ëÒÝ‹¤Ñaÿê ÔnÒw‡½ÚC€>>"€'@qgÙ8¬wf5_?m´H‚ {W”*ŠÕH&à'?’£‹{æìG9ÈØžm¡Ä-ô›¬Ë¾1ód'¯Œ «9§+.˜Ã¥6í¼3Qøê)>7U¦Ô ž€@%·ÃÍäIí¯VGÅž3€VßU[çlâ—æ°… òTà˜°ÁœÅ§SϹz/ &qDþæ Xp¿Õ¶ ra;¹4òóýƒs,†ÂÙ;Þ'2ryhuµÄ)¸l»#ÙÁÆ–+eo:>¨â\ç“äOòn¤€ÄýÇsBIT|dˆ ÙIDATX…í—[lçuÇß7³;³»Ü ÉÝ—‘ºÐ–D‰Ö%ТЉcKõ›+©“—h‹º}©Q -ŠEúØú!r5‚2àÜŒºMQG‰L'µ$J¼H")QZQ–v×äÞ¯3»sùú@‘6PíCÑ—öƒù€8çwÎùŸø¿nâÂÉþþ‘L'éïïår‰B¡@»ÝæÂ…üï<÷ÜsŒIÇqû@ÂápG)¬o~ó¼ýöÛèºN»Ý楗^àë_ÿ[‘J¥Òápäp_$²WÓ §çèÕZµ[)WŠÅbqµÑh¬”+åÖ… ÿð©úö!™L!„xattô/ƒÁ@Òqœ›å^½uk¥ kúd·ÛV(Cѹs{íÁÕ¹+~ôÑÆ‰~#î—R=Ï—NG˜¦©BfØ …"V>Ÿû·bqãþøÕWKÿúëÿ @Èf„†††2¶õgÏž:œ(>šÝ›Ÿ¿þYÃ0¿Õ ¿¢Ií·»½Þùl6{þáÇûÆŸ92ý¤a†çùšeY²Õl‰f³)Ûí¶ÖëöŒF³ñxÓ‰D"wâøñÂôáÃÞµùù¦azúÈÉŸþä'uôØÑ³O>ù„^©”Åp&£Y__fa~>–Ëçƒkkwô………àÒâb4™JŸÈçòáPD†Ãa„M“tM×@:KÔê5™HÄ&3™Ì‹J©Qß÷³O=õTõàÁƒjii Ís=ùÁå+¿kYöïùžôíÃ&’ÉÔ__¹:w&Žþ‰îû~\¡&=Ïccã#fggBpóæM ù<ÆÛ¶1 ƒ`0H­Vcee™ññqNŸ>Mqs´ZmzNÏóB ¥D)ÅÄÄ8™¡aœ^ÕÕUlÛñxÌè‹ôÐ4= ¢ÑøñÁÁ‹ž<ÉÐl5(—KèºÎèèn*•2'N|†P(„”’F£NPJŽ;NÛ²ƒÜ¾}›«W¯²¹± @"ÑÏîñq¦"2G",ßZæG?þ1ŽãpîìYZ­öj½Þ˜Ñ…`"{ö2󹧩֪ܼyƒ÷.]âð‘#œ;w!$¾ï2ý:‰jãp#›åç?¿H>Ÿgp0I4G×u<Ïcue…¥ÅEöìÝÃñcGñ}Ÿf³‚`0ˆ¦Ùñbq3¥ÁT Њ^¯K©\b~þ:¿úÕû4›M¾ð…g0Í ÂàéÏÍ <ÕÛw¸{7Ëà`ŠcÇNL&‰Åbˆ­î§V«Q,nrÿþ}.^ü%/¾ø[|õ«_C)Åôái._¹œL¦’Ïèà'4M—!3D,cmíÙì=\×Åó<––Ù·o†ÜR.]ãA.ǽì}2™aöîÝÃää>„8=„@ˆ­s­ÖàÞ½,—/À[o½Å+¯|X,Žç¹DcQi”Œ¸aBA«Õ"—Ë ”Âó<.]ºÄÝ»wwT»ÝnsûölËb×Pšþ8µz•‡²²ºÂòò-òùfD”ã'Žrö…ÐA~ðƒ7¨7jÀ4 Jê€ÜV¥f«‰RþÇ‹B@aYJ)„€Gr4ê Bá™Ì¥R‰GQ­ÖX]]Áu’ƒI†2fff…BLìçÜÙ³¼ñÆ÷¹uã&§N=çyxž÷ñ.p]¥¾¿5J[ ØšñÍM\×åÐÔz½W._ægÿú3êµ:z@G—Ï÷P–––8þ<#ÃÃìŸÜËÉ“Ÿåþú}>sòä–S…£+…Ú.¹ïûH)B ”züðhë]©TAJI¡Pà‡?ú!žç3œê' Òox <ÖÊ.׮͡”âµ×^Ã÷}ŽLæýÙ÷…”šBЖÀNÍ}+àÇ™ogÿøÞóèöº¤Ó)¤Ôøö·¿…mÛ¤úãdâ&QS’JøLö÷89j’LpõêUfgg±m›ÑÑÇÁ÷RJ_)ZR¼í(ⱞ+¥vq» J)¤¦‘N§ñ}Ÿl6Ëýûë†I¬/„Óuê½@”† Ðóéþ(R .^¼ˆ®ëH©Ç·³ò•òºRtv¶¯lKê6”‚L&ƒëº y\×EtTŸWkc•êôºa,7R dMj yÇ!04´ !%v·ë¹®WÓ&à ±5iÛ> âº.kkkxžG"§^¯A€4Âôrƒn¹‰Ð1Baº¾Âõ<‚Ac'¡þþßó!DUUAà@ЉÜð}…ï+nݺI,¶µMÓd||œp(Dϲ¨—†°5Õq …ûÐe€ìí5ÇáàÁƒ;ý•L¦QJ©v»S¾ŸÓ…Ep4]ßJ‰OVB!¥`zzš`ÐÀ¶- ýýœ9ó›¼óÏï nPjXÈDœ>³jµEq³H«Õ¢¯¯/}ñKèºF¥RÁ²-Õl6Ú…Bá;ÕZ­¦e ` l»½“½BI!±:ñx8ŽC¹\"‹óåç¾ÌúúºX^¾…kYØ¥êÎ7C¯×Å4 žþy2ÃÃ*4X\¸á»®SÞ,ÿnyùÖwoÜ\òt]Ô„u¥Ô€2Eµ¶#D*•Jçc±þå÷fg»s×®!¥†¦IêõºxöÙgGÓ»ÒS_ùÊïh³³ï‰……yªÕžçaš&O<1Éç?†ÉÉý*‘HX³³³¿^_ÿðƒN»õOùÜ£…ù…ë]ß÷Ñ-«c Áûžçî–RjétZX–¥öíÛ_/‹~ùÊ¿ÿK¯×ëm7¤¦iÂu]*•òÐË/¿üSS‡^L&“á™™|_‰V«ÅÀ@?‘HD +Ó mÎÍ]}ýÍ7/|§R®TÚ–Ón·wzMëv»¾ïû÷ ÃÔú÷ïÛ§Rét^“òû¿øå/.är6-˲mÛêÚ¶Õít:¶mÛv6{¯yýúõËš¦¯NLŒFFF"»wï{öìqS©´‡nll¾ýæ›þæ{ßûî;ù|¾Òî´]Çq>©þ;?&z8‰ŽŒ 'c±xØuÝV>ŸÛ,‹íO*姘¦išvèСÐ ÃÌöíF§Ó.ÌÍÍÕs¹\ðþ ?Ÿ õÿö¿bÿ”­ê]+ÅIEND®B`‚fotoxx-12.01.2/icons/prev-row.png0000644000175000017500000000140011701011016015225 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>{IDATHÇå”OOAÆŸwvÛ¦Û?± ê´Š SIäOŒ 5ÌêÉïàw€+—%ñ;x51^Œ 1FèÑ›b"ÖBbAm)Ð.mwg×C:,ŠàÉ7y2›w~Ï;ïdøï‚ëÆ£ãä³ãÁg¦¼àfž´»F9Fåµpp:{{(øó÷ÆMíâJ¹·ïOÅ€ëÆÃ€ª<½3r]«ƒ!Õ—ä× ã‘T¶TÊÍ}8‘×1bôjlxP³˜Š•_[¨ÕRÝ«Ål,].åæ>þ•×½º D"X/[°mâæ6˜¢ Õ—¬®ïÇ/Ý](åæb°Cà= š¿ÚŸŒjñŠ[õÆ„Ûò… 6·27úʞqݸ׶×8ˆæS}ç;Ïvu²b¹¾;çJyùBUº–£—\7Æ4àº$¢×݉Žä…dZªÔáºhùB‚T ^áˆÞpÝÈ´4àºA z‹E2œ÷†ÇA<¬B ©RVÓíL4„dW A•AÓÂH§z£ šçº1°“C>ƒi“òÆHÍ`ô¦YCŬzÏE±ðé „ãÚ¾-˜XšZ!\7Ü[£”« FŬÂ4k€î Ÿ±4;Õ’ÓÖS!ùš,ËvŽ\Û–-š ’ÎÀ§d°gÒ§e‹¼›.¤JåfI;hÉQ[@eÁqå„»váÓ>æUI Ô¬:»á`Y±¯5!j{"o%ÍX«’x’“{sŸç~?çœ{îþgcÅ>=vd;€Ýš­å0€K‚úþ©Gép’‘hZÕЬ¼nw}mMe% ŸK%#±ØÌÝé0i•°ÿàCCÿ`E¬kZÚØ¾ÁŽ+ãþæÓY–€2¡eõ Vå«¥–‘ѱÈìÔ¤@O©lXx'€K­ë:f+\žÌí¸Žj@ÙD-µÌ“JÄä­ëCuº‹eBó“õîÖÓåÉq~Bœ10–‹G*×a§Ë©w·†œ,–åKÃH4u´·y¸Žæ¢d bàœÀ9Ap§Üœƒ×ÑŽçÚ½Œ‹&«¼E3è©klQ¡¸24 ˆ(/HÁy`ˆˆ“2î™F]C‹²:î ÖØíózj¤¾FD˜œºï7âî\e–ïävÿÊX«»:‘\Tó¾fϳ3±‰îR€æU®*>qßÌ1Œq÷©¶=n¥ àýãƒîµÍ®DxöÁ\—¯º@y)cøö—‰§¡Ú¾6×g•✈1ÆXž µÖJkm*m¦¦Õ7¿NÞÊfM¶#à,vÆá»sóµ¾úrçÍ©d"«0Üsø‡ Œ1€-)“44*öq¥™z¦ÑéJÌ%“⥗‘èæÀZŸ÷Öìb¢Â.#55)¤œˆ (SÁÌšH›&2™,6­©ô‘Ð €Ë¥º(83eÐæ5Um;œs"HN‚ ¥@™°I)¸ààD(·IÑéw¶MÇB ¸€Àσo¼úÚ+».*õRÇjïÕP*,ENHJ)s#'–+‘ÖÐJ£wký‹“×’ós³w8ôI© `ìöu¿ù×lùÛ¼[l’À Á'ŒÁ.Iìy¹aK&5]5þôØ_ì—}ì<þõ¡MŸ÷ŽÆÆnÜy™I™óœ8kDÕÚº2ïºF{ÛðÈH4ºÖÀvåÊÕ”Ífþêì×[K°Ï¿øl“”òeMîæVå÷ùêWÖT9àÞÜ|ÊGf¢·o’™MO-..~8::Ö¿ï½=¾á¡ Á¾ÕÖUyÀ¬’úôðÇÛívûN"zˆ< ”Šš¦y9™L]8þ剟àÝÝïœr8=©dêQïÞÝö3§Ï&ƒ}UKyqnµîRσ¥å ¹×6 ûÖÛ;‡®š‰›“é»Þ,;súìB°oÀQxò^ RèÜòìLHÈôŸ;¿Ào@—ã» ?ª½ûzWxì¨(ü“i&€L@YëºÿÜù× ]eü>úx“(" ­Í¦U²2\°2a™ÿ7Ñî|À clU°oàÿüÓÛßɹ)\fؽIEND®B`‚fotoxx-12.01.2/icons/save+F.png0000644000175000017500000000200011701011016014560 0ustar micomico‰PNG  IHDRàw=øsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÛ -68÷¹n€IDATHÇí•ÍO\UÆçÞs?æ\Úa(*-Qˆ ¡šX­†?Àи骋’’jºt‹ wèÚM׺sm ©ÖÜÔH0Öˆ¤ACêeÆa2à ÷žÃàP…U7ŸäæÜ{ÎÉóœ÷yßó^øÿyˆ‡'nÝþt&Ïóà Œ!Æ´6!œµk4Æ:a­ÅY‡µÖeYÖĺ™+W®.'àßúì“gžšx<Šb”Rø¾€1†<Ï©Õvxrdô¸{€ë|{Ýk7o~ð|D}q\ „hë[k±Ö²»»‹µîXKÞ=¤.»Þ½ Š®Ž<5 FFÛû~¾Ÿ\kò,C)…Öúá×KKÄqL½^§ºó‡1ß7 ¼Ó‰¢;OïòÀc"‚ƒÉ0 )Ä1I’`ŒÁZ{HÀ9Ç/8ç÷u®gâmÛ3???ùù·s4M]¥RqÕjÕµçÁƒî½÷²ë×g/tòÛQò’žÂÜÄÄyy”·+++lll°¾¾~¤ÿ«?­ñÂ…ƒ0LÞê´ 'ðµ6oô•úXþv™Íß~åµ™~¸w€kqÎáÜá$yçÆª;5š››¼ré"ÍVó2p° æ^ž›Tm g:婵&Ïs²,;$P(&IãcDQDñdQMOOOB^’¨_º$Ó4Ekçy|s÷.¥R‰¡R k-B´ÖKr±X¤\.ÓêRJò^\\|S>¥ýQ<‚ß@T€–èêªâ‘w`»Ûö¿ѹF ¾ dIEND®B`‚fotoxx-12.01.2/icons/prev.png0000644000175000017500000000150511701011016014426 0ustar micomico‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk>ÀIDATHÇåTMOA~f¶Ý~ E$JE=ž0^¤J¼ÈÙDÿñB=C¢• ‰1<®&\±š`ŒÀÉãÅ„“R@¢¾ö«ÝN¡…nY.^œäÙÉdž÷}Þyø/WôVò¡S.=kN¢Ãã/L8µp9%ö÷¿qçÚÆß…›Î mæv‡ä(ƒ«×ŸsmÛ_"mÍñk}þÓä|b]wžÓ,i®+ŽööuÉœJ§ñRïòâÍd7s‘ùîX{øBG»´¹c ÒÄ̧¯(2fØr¢eR£Íu3ˆ %%3½—;B-­-4»£ƒ1`{?ÁÁ~€Ã[+\Ëb˜ývà·¦@güEœKdêJO4jl@n?ÎKw»j{šM9ÐÚP­{L v;ù€Ròª·'æ÷üØÕÌãà6•á@Ñâöñä ÆùÛžKQ·ŒÜž:á¥s….¾à@Á[ý0«N+Ÿ ¥Ë™5Í2MX¦ EÑKPuì+Å€¢BU ¨j¾tÖ èzÁ^–§GùâøÒÏeM–¿Çñ,Š«/™÷£cE“%Òé€Á+¾},¡1èASè8Ά¼0‹Õuç 6üü>‡ôú|¤ÝG¨ yÓBÐçÆJ:Í8¯cÊ2©„l›Ay¥§OZîýþµ® y¸$ Óbà Z>h„ePæt Å)•§[Â~Ï‹ìÚ*2©„OÜs&vëÄaßêÇ'ó¦²1²“ÛÐtí`Ê‚ød’@Ù¹[=<ësßìÒÈ^nK¼pîN½e®°s×8 €üY˜ü¡®/Üåœm‰ $ZÉ«jý{Ë5Å‘°´ìâ†äoJéÙÅM&€b ˜¸“&ÓŠ(Ë G„™h.«hö¿Y(¿,Mœ‘ξtEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/icons/draw.png0000644000175000017500000000120111701011016014400 0ustar micomico‰PNG  IHDRàw=øsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ;ª@bIDATHÇå”_H“QÆ®í"t-F(¹¹|ËÁ„è„ £>!BL JìÑE„äªÛ±‹î"%ldDš5H¤„›]dÔE„LGjL:µ"¥\{»a“®ü¾]õÀáÀ{Îó;ï9ÐO* k†R c€¼î ÷ öGjËæ¦°d2É#Ý}6ƒ^ô^¯—ÙÉD­qà%£CŸ(þõͶºhÔƒþÍÓ'ÃçV¹·Ï%WÉäýVĤõ _˜I¹•XXø¦¨b7]ñ ô¸IŽþyÿ¶09Â=—¢ÔíÆ~æuέ>­íQE!½ÁThÙáaÙZBñ6¯¢Qž}™ j¦ÿéJŽôTKøV¥Ì ^“X,&€Ô—;š´¼"UUU¾ÏO—fC¡½ñ íôïž·I6ýüØc¤é\õíU“A ý–¢LN±½{xe~¹ª™~hàaýÒüJïj\ÍÙÆõœ@QU˦œÖÓÚÖ@Ï‹ÏA­õ‡h¸“Ĭ óƘgñZh¨)÷­5¯'àf]¥“eÓfªNù²èãA=X\\¢ÌnÇj+glOIDATHÇÕ”mhEÇ3»·¹K®×kLR4iÓjšÖŠÚXýô,ZÐR B㡱 *ˆ¡¤_ô‹ ”p4õâXEZ#×"K Ømlk/E¥y¹¤w{»{;ã‡\ʦ&¹øA†}fþ¿gþÏ3 ÿµ‘NÑžNZè~Y™¸xèŒpl¿ùB$¶â=!BV%I•¤SÈãªÞÕ¯ßsÛæ¨R•Ì2âà ^×¼åî•wv…¥®D{~@:Eƒa†6Þ²cUãÍ–(þòÌPLøÂÿùû÷åïŽhí¿“H’KGÌ!¾ZáþUí{ê®[¶ÑÀ=8`4£e3E7‹kÿÁX¦Ï>Ý[ÔÚÛ«”÷r"‰. H§X/¤Ñ¿öž½ÕÑ%MBåÅ™GD BÆÖ”Žqî‡7ò£Ãé/•_|4‘Ä+gÑ À¸|þ`[Ud[ØÉ~ƒrÏÎé±´ZX~ë3Õ`$sâmàé…XdIÉ'ñëoß´bÝ“w|¾3@(º3ú ¨Q”wåe(ÚÇ¢«öy¿Tð={]"Éà´Ö¬¦ç3üí[ù°ûó¦+cC«ëoÜBM`ŶòSßëjdødÞÉ;®4—šÑ¥ åœAσ¶EnbÒêù”CóÞ 8ŽíçµÈ¢e»ZÛŸ˜Vœ“‡vùÊÏ·­BÒU{CËÚ¦5›ÂÞÄA®Œ‘âTÇã´]µ°`C'/ÚwŸþîÕ‚[økzù×D’µ"1zéìàÈï_£Õ! ´¦iFÊ6ºãKxdy+Ï ƒä\—§6nçÀµbA˜QZ3± €ÍÔX&M-ÈÉq¸t;oÓußN>*íÑAÑ`lÎÆP€ßßÃW¦A«ÖdËðpçnN0õOñ‚€Ù|·€µ@Иõ 4¼ùmÀ" ºT«X>×C̰gºÓ7)M5_Öÿïñ7²4A!:úNtEXtSoftwarewww.inkscape.org›î<IEND®B`‚fotoxx-12.01.2/dependencies.sh0000755000175000017500000000156011701011017014620 0ustar micomico#! /bin/bash # # Check if dependencies are installed before build. # # Note: # The following programs are not needed to build fotoxx # but they are required at run time. dlist="xdg-open xdg-desktop-menu exiftool ufraw-batch" error=0 for dname in $dlist do which $dname >/dev/null if [ $? -ne 0 ]; then error=1; fi done if [ $error -eq 0 ]; then exit 0; fi for dname in $dlist do which $dname >/dev/null if [ $? -ne 0 ] then echo " missing: $dname" else echo " found: $dname" fi done echo "" echo "The following programs are required for Fotoxx" echo "(package names depend on your flavor of Linux)." echo " xdg-utils LSB standard Linux utilities" echo " exiftool EXIF/IPTC image data utility" echo " ufraw-batch convert camera RAW files" echo "Please install missing dependencies." echo "" exit 1 fotoxx-12.01.2/doc/0000755000175000017500000000000011701011016012375 5ustar micomicofotoxx-12.01.2/doc/translations0000664000175000017500000001510611701011016015046 0ustar micomicoTRANSLATIONS OF FOTOXX The instructions here apply to the GUI interface (menus and dialogs). For user guide translations, see below. Translation files are normally as follows: /usr/share/fotoxx/locales/fotoxx-lc.po "lc" is a standard 2-character language code, e.g. "de" for German, or a combination language and region code formatted "lc_RC", e.g. "de_AT" for Austrian German. "lc" or "lc_RC" is also the locale of the target computer system, as shown by the following command: $ echo $LANG The .po file contains the English phrases used by fotoxx, with the corresponding translations for language "lc" or language and region "lc_RC". It can be edited with any text editor or one of the special editors for .po files (e.g. poedit). REVISE AN EXISTING LANGUAGE AND TRANSLATION 1. Edit fotoxx-lc.po to add or update translation strings. 2. Open a terminal window and go to the location of the .po file. 3. Compile the .po file to check for errors: $ msgfmt -v --check-format -o /dev/null fotoxx-lc.po 4. Run fotoxx and check how the translations look. 5. Send the modified .po file to me (kornelix2@gmail.com) so it can be included in future releases. Steps 2 and 3 are optional. The usual binary translation files (.mo) that are output by msgfmt are not needed by fotoxx. The translation source files (.po) are read directly by fotoxx, and changes made to a .po file are immediately effective. Steps 2 and 3 are useful to find errors (e.g. format codes in a translated string do not match those in the English string). ADD A NEW LANGUAGE AND TRANSLATION 1. Move the source program files *.cc and *.h from the release tarball into some convenient directory. 2. Create template files (.pot) from the source programs $ xgettext -s --keyword=ZTX -o fotoxx.pot *.cc *.h 3. Create translation files (.po) from the template files (.pot) $ msginit -l lc -o fotoxx-lc.po -i fotoxx.pot "lc" is the language and region code for the new language. If asked for an e-mail address, reply with Enter to ignore. 4. Edit the .po file to insert translations for all text. 5. Move the .po file to the installation directory: /usr/share/fotoxx/locales/fotoxx-lc.po 6. Run fotoxx and check how the translations look. 7. Send the new .po file to me (kornelix2@gmail.com) so it can be included in future releases. PROBLEMS WITH LONG TRANSLATIONS English can be terse compared to other languages (e.g. "undo" becomes "Rückgängig machen" in German), and this can cause ugliness in the GUI layouts. Therefore try to make dialog labels and buttons short. CONTEXT DEPENDENT TRANSLATIONS Sometimes the same English text will need multiple translations that depend on context. A simple example is "save file" when used on a toolbar button or in a menu. On the button the translation should be short, but there is no limit for the menu. In German, this could be "speichern" for the button and "in Datei speichern" for the menu. The standard method to do this in Gnu gettext is fairly horrible, but since fotoxx reads the source translations (.po files) instead of the binaries (.mo files), a simpler method is available. The English text may include an extra string to distinguish different contexts. This context string is removed from the GUI output, so the user does not see it. The context string is any short string followed with the special marker "::". To continue our example, the fotoxx-lc.po file might look like this: msgid "save file" msgstr "in Datei speichern" msgid "toolbar::save file" msgstr "speichern" In English, fotoxx would show "save file" for both cases, and in German "in Datei speichern" or "speichern". INTERACTIVE TRANSLATIONS Use the fotoxx menu "Edit Translations" to revise translations interactively as the application is being used. The advantage is that you can better understand the context, making translation easier and more accurate. The updated translations are also immediately seen in the application dialogs. The starting point is the fotoxx-lc.po file as described above, which must be installed to start with. Translations may be partly or entirely missing at this point - it is only important that all the English strings are present in the .po file. This method is best suited for updating the translation after a new release of fotoxx, or to improve the translation. Use the menu to start the process. A popup text window is created and displays all english strings and their present translations as they are being used in the application. The format is like the .po files. Missing translations will repeat the English phrase in place of the translation. The translations may be edited in the window as soon as they appear. When the [apply] button is pressed, the original .po file is copied and updated from the edit window. This edited .po file is placed in /home//.fotoxx/locales/fotoxx-lc.po. Each time this process is started, a new popup text window is created for new translations, and these are accumulated in the .po file. When the interactive translation function is started, you can choose to show only the missing translations or all translations. Normally only missing translations are needed, but revisions in existing translations can also be made. Once a translation is edited and the [apply] button is used, the translation is no longer missing and will not appear again in the edit window if 'only missing' was chosen at startup. If the function is started again later, the option to show all translations or only the missing translations can be set again. When finished, replace the installation .po file in /usr/share/fotoxx/locales/fotoxx-lc.po with the edited .po file in /home//.fotoxx/locales/fotoxx-lc.po Delete the edited .po file to stop fotoxx from using them. When fotoxx is started from a terminal window, any missing translations will be listed in the window. Be sure to send the finished .po file to me for inclusion in future releases (kornelix2@gmail.com). USER GUIDE TRANSLATION The user guide is normally found here: /usr/share/doc/fotoxx/userguide-lc.html The file is a text HTML file, which may be edited with any HTML editor. "lc" (or "lc_RC") is the language code or language and region code. The user locale in $LANG or $LANGUAGE is used to find "lc_RC". If a file with the region code is present, this file is used, otherwise the standard language version is used. If this is not found, the english file (userguide-en.html) is used. If you make a new or revised translation, please send it to me so that it can be included in future releases (kornelix2@gmail.com). fotoxx-12.01.2/doc/images/0000755000175000017500000000000011701011016013642 5ustar micomicofotoxx-12.01.2/doc/images/pano-color.jpg0000664000175000017500000003442611701011016016430 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 318 312 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀþù"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmÁŸM²fkX‰-n„’Pd“Šš+Yæ4Û6oSj€€z<û›Eÿÿ^‘è«jÛ®.¡‚ÀãQŒnY{B„ò_ÕN>ïr8éÿ°è¦ï쫦ؙ‚o`-Pí^€ž8Ïo\JK½;L®•§œœslŸáNÑLi–Å.Ñ·\‡9gcüyî8>Øã©uCˆ£ÿ{úS‚»°¥¢3¾Ï§ÿÐ'MÿÀTÿ |v6’‚cÑtö®-TÿJ5_Q<(Ïúåéþë…m8¨«ØÎ2m—›N·PKhv Iû"ÿ…3ìv^W›ý§lÎ3öTëùVe…ÆÉ‰dq˜ÝTõÉ#ù×GĶE19‹e½1Ò¢6kb×S=ììã _GÓ€q•ÿENGåM[[& WGÓˆQ’~Êœʵ‹ –·` >ÕÀ9  ·2¤(¢G€„['·J­; ^æG‘§ÿÐ'MÿÀTÿ t¶–P°WÒ4ÐJ†ÿdè »±þÆL1ÆÒe¼ì•úzT·D<2£*+©Ç ýh´{ ï¹B->Úe-‹§0‹dÿ ‰­ìUж‘§8 Ú§øV‚™,!óq08ß·u¥šEO¶Ì›$`ë†eê(²½¬ »^æ|––Q„-¤é˜q¸bÙ:~TEig3M#MÈú2t…^_!^ظK@H,0 vÍL>K¤8wÙ‹6Ð0M G°&û™+mdÊ̺>œBŒ“öTãô¦ù6ô Óð?µÐåI…cMn. Ï¥66[Å$Q“)?Ê3‘š=ÞÁ¯s+ʰÿ N›ÿ€©þyVô Óð?µvÂ4àR1<³¹†ÞÜõ¤ž?–Ù¼•\º$–úâ£Ø=îæ_•aÿ@7ÿSü)<«úé¿ø ŸáVõEÙ:r£pÎÝ úâ­ÜB‹eó*¶Ò›\(²FqëNѲÐW•÷2|«úé¿ø ŸáO6¶b1Ò4Í…¶ÿDzuü«Ra <‚TR)ÕA ŽïPê[ÖÅDŠˆ|ã´ Ç•¢í õ]JpØÛÎ ‹DÓ˜¤Z§øTMбVÒ4ÐAÁeOð«Ë—Z| jÃtdïPØ9ìjkhÐB’Œ ÄÖ†¢º í™Ïmf‘G#ifÙ3·ý;~—aÿ@7ÿSü+JÃdÏ´Æ ¯ÌxÝÉÔŠ‹ö»a4q Èrè cã"‹G°^]Ì–?ôÓð?­XÙé·C&•§€-“ü*¤²´²` žÊ0*ö”sÏû£úÓœì“r±4úF–°HF—bSÿ.Ééô¯Ÿò}kèÛŸõÿº•|ã\æÇ½X_ÛÚhúTSL’YFʱÂòòƒ–_Î¥MNÂ2æ8n”ÈÛœ‹²ÇÉù}TÒ¿×èöý·­ìŸS@‡S±2¬¦£"ªÿb› £;zp?*†òþÚåT].y²›ÿˆ­œŸSFO©¡;;ƒWÐæüȽqÿ€Sÿñ«2)%%¼Bz쵸\þK]O©£'ÔÕûI2yÎ4±³ynÜŽ…ínšÓwÃýëüŸÿˆ®ŠI<¸ÚF'j‚OáQùóÏÿ¾×üiª’è'õ0wAëqÿ€SÿñnƒÌøÿ¯)ÿøŠÝ7“`¶?ƧWܪÀœ0Qí$‘9¬Áëqÿ€Sÿñf[üŸÿˆ®›'ÔÑ“êhö²g™&ÔÎíÊþ"ŒÃýëüŸÿˆ®›'ÔÑ“êhö²gœ†d…÷ÆÓg§63ý’‰ç[‡ß,— qøñŸürº<ŸSFO©¥íe¸ýš9ÜúÏÿ€Sÿñ~çÖüŸÿˆ®Ÿ'ÔÑ“êiûY ÙÄæ?sœîŸÿ§ÿâ(ÄÞŸÿ§ÿâ+§Éõ4dúš=´ƒÙÄæ’:4ãþܧÿâ)1sºüŸÿˆ®£'ÔÑ“êhöÒg—Ä?ÞŸÿ§ÿâ(ѧöå?ÿ]FO©£'ÔÑí¤Î'.D'«NíÊþ"ŒCýéÿð þ"ºŒŸSFO©£ÛH=œN_ÿzüŸÿˆ¤Û1º|×”ÿüEu9>¦ŒŸSG¶{8œ¾"þüÿø?ÿVì.­íD¢Oµ0pËe?¿û»“êhÉõ4¥VMYSIÝãR¶ºó`ŒÌ%0¼dãÊŒFà3‚Ãó¯Ÿk߯I:Ü?ó¹ÿÐ௨(÷M+ý~‡ÿ`wþvôÍcRžÂúùíÒ2ñXÆé¼±2•äËŸz~•þ¿Cÿ°;ÿ;zÖšÊÖá§·I ˆ‹ª@üù¡n"jš¬7ÍѲ’(¯RÑü¸ÝY·€CŒ±sõ¨ÿá$ž+‹—h–{E·žx]ahËy]FI;¾  ßk;Vvv 4¢f8êão¨À¨SJ±†If¶µ†)åVM»€Ý×åÎ9î8Í 1.5ÝVÎV¶ž;Iç‘mÌFÛj™†-ócoÆsÚ·4™ï.,CêþDáÙHÆÝÀtldã>™5CLðÝ¥œwKr°Ü}¥Q.0«’0¥˜ç'®}1ŠÖ··†Ö‚Þ1kÑA'ùÓ¸—¿ñå?ýsoåYýì–pO:Äe…!0HäX‚@ÀïÞ¶nPÉm,k÷™ˆª®®îìó+Œ§~ Õ e=ê[:)¦„ÂÓCæ‰'aÎ8Ï8#‘ô­h?ãÚúæ¿ÈUP²*°[yrÜ’Ç$Ÿs𹔉õUþ†uAgiÕ°žrí#“Èr6sŒ zTõ·Œ–#zî傹PßP*J f-ÜÛˆ,»¿¼ Ò¥¤*…P€@)iã2Áò¶Ò̪[û  ü3š[«H­-ÌðoGƒË“æsÐçÖ¥eWR¬) ÷¨ÖÕ”üí³î†rÁ~€Ó3 1†’Š) (¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠË½ÿÜö¹ÿÐ௯}½ÿÜö¹ÿÐ௦#Ý4¯õúýßùÛÖíai_ëô?û¿ó·­Ú(¢ŠC+]êV%íå½¾üìó¥TÝôÉæ¬++¨e!”Œ‚A‡¬Ûjkv2iÂ%d·¸I¡2F €pF3þ±¬?°_ˆ¬ Skn–¡#"ÒI)·¶ó„e¶ qLGgsu·•ç1t«qœ±éSW'5¥ÃëQ›{é.×RIP®a˜ÇÈ1Ï^s]e(¢ŠC (¢€ Žyá¶…¦¸•"‰ygv £êMIXÚìo4Û·µ’êÚÚfibDÞA*B¾ßâÁÿÔ¶¹·»„MiÍæoƤàžHÝ»õ¢ÁsJŠ(¤0¢Š(¤bK1’OjZ‚õYì§U™£`îqCVþÚÓÖ{˜o­çŽÝ'‘ ¨ü h¨Íp1Ø_ËcŽÞúwM) \Zy>Q¨p7’F9ÏNµ«;_}¦hÞÿ7¶ÓÄâ7Ø#7z.6¶AÅ1\êh®cÃ6·ñß´·ó܉‚8ž7¶‘QØ·;1CŽÛ@à×O@QHf]ïü†àÿ°}Ïþ‡x{íïü†àÿ°}Ïþ‡x1饯ÐÿìÿÎÞ·k Jÿ_¡ÿØÿ½nÐÉ) ·DiKüí€À쨥òµ/ùçiÿ[ÿ‰¢?ù Eÿ^òèIY’êš¼Z°šXhfŠ8v§É™ÏvÆsþ§åê_óÎÓþþ·ÿKåê_óÎÓþþ·ÿYBûS:ÑþÚ<Õ¸Ùö¿)wò÷ãoÝÝž:tíV­v|./–.ÙÄöü¼Ï/~=;‹wËÔ¿ç§ýýoþ&˜¦ôÌñ2[ЬO˜ØÁ'ýŸöhÒ..Z{ë;¹¼÷´•TM°)`Ê8ÈÉéíK{s\\Ã4o$rC²£`‘—ï‘@ Ò4qÌÞH‚‡†MÜ“OZ±T’ kXöZZd’x˜¢€ê8Pp? »@QHep÷3K*ÚÇX˜+ŒœÆìE;ËÔ¿ç§ýýoþ&’ÓÎÙ¨ý›Ëyÿ!“;AòÓ®+6ÚÿR»³Òàk÷F_6àDO §ž=x¦#SËÔ¿ç§ýýoþ&“ËÔ¿ç§ýýoþ&°†·©ÜYMwÑEöA<‰å‚'mÎç0œc×Ú¶u;›§º±³³œ[îÒ” T*ç2Iü³@\—ËÔ¿ç§ýýoþ&¢ó®Ù§œÚC Ï)`‘Ôj±¢ÝɤÛÜÌHà†Ú0 ‚G±Æj¬[]F©ujn9¤`¬Bw·PN=è™–Qêƒr–RŒHã£Þ¤ªÐ$p¼CÇq¸Usœ Ž:ž*Í!…Q@ãkË€ÏoXfPd‚ppx÷åj_óÎÓþþ·ÿPoºÃÓÉbñ$Êó0i°P$lœw5N}CQš8½Ò@ɧ ÉÆÌn8ösŽh©åê_óÎÓþþ·ÿG—©Ï;OûúßüMd&±1þÐYU-Òâ ¯–á"¡'w\ƒ'¸÷«zÅåòßIÂ[­½£\±1†ó8 sÐpsŽi‚w-ùz—üó´ÿ¿­ÿÄÔbiþÏ Òµ¤K6Ý»å#%ºkBÎsseÁ]¦XÕöúdg’m,ï-­Ý‘¸ÙªîÁQ• gƒïÖ€.!HÑ̪@?)È çü*J‚<â 8 (Þrp ê{Ôô†eÞÿÈnûÜÿèpWW¾ÞÿÈnûÜÿèpWSîšWúýþÀïüíëv°´¯õúýßùÛÖíWißRŠiÝc‹ÉtÞÇ *@'ð4ÙC”] .m]€&qó``wãJ´  J]íýæüè;ìþû7‘ö¸qæy¾gÚÿy¿ÎýÙÎ8ëÒŸ³@ò´Zù-„Çö—h$ôÏ\ž½jööþó~tooï7ç@ì¦ÑìbhíïmÆöÞì×™›Ô’rz ­{=•Ô·nãòäŠ5ßÀA~„£#ô­íýæüèÞßÞo΀1ìcHÑbÏ{pó#É+’è8PíZô¥˜ðXŸÆšÌª2Äîi Z)žlóÑ?1G›üôOÌPV·0ZMv·SG™(tó(a±GëÈ5 ‘hi±º·XábÑ•ºÚÊNs†<äÕÁ:’¨ú5h_ùì?ïªb(ËmáÙ|ÓZ……j«q€T…`Ì3Ï4ùÓB¸Œ¬·ŸÞ™C ¼2±ààîÈãйç¯üö÷Õ(—qÂÉ“ìÔÈ/t«x/-8Ô*¨™pük*ìÁu"Ô¾Ë*Ë#G4n§vìx`Aï[;ÛûÍùÓdœD»¤—bú³b€)X¬JÑÇm#IQ°._y$y>§š½PëcÖê#õQöÛOùù‡þû†OEAöÛOùù‡þû}¶Óþ~aÿ¾Å2Ö{8¬¥´½ž(‹<¡’G J³1žØ=j+ˆ|?s1Ëso¶ò×mÎß“”y ^ŽQ"nŠMËê­‘NÞßÞoΘŠ-€×«vn-|Õ*p.RTaI\à:S&·ðüñE·P°‰J‚nÎJ“’¤îÉÆ´w·÷›ó£{y¿:A©iª[ë@ WÖ°¦H.­íŠêok"F¨æ)æ\ ©¡÷ê+{{y¿:7·÷›ó  –{ 1‡˜–4E äqžýûUª '©'ëE!™w¿òƒþÁ÷?úàUï·¿òƒþÁ÷?úàTÄ{¦•þ¿Cÿ°;ÿ;z½}¬XXN º•ÖO/Ì!bw ™ÆâT{𣥝ÐÿìÿÎÞ Öôû©õ¦-¯¥ì¼œÚN±Ûóƒ’8ÇÖÍ繈[™‘¼ÕòüÅüÅÆ3òúæž$]¨Xí. Üæ-ô+¡c©ý®ÎÝï$±Ž]q‘R«ýÑ’aTu{o&àÇqi÷µšÁ&ô-Ò  Rr9ü£œûU[[wkT:­¬ºt×ÌÅ"‡ÌßžHH'éV–xš4H»\§=k–›Ã·×ZGÄÆñ&–@û7Ôd¯Ò§]/$±ûF‰Ck24.±ád!0@8<ûRè>§JYC,=zÒoN~uùzóÒ¸û]ù¯meÔ£¼wÙlD±4'É(£pbÀ°ävžsS&/ÙµS¦Î¶“ê@ˆNï¿8Îpéßæç·4Õ‚eH ÷•ú¢$ñ¬ˆ!f ã#9â¡Ñ£¹‹J†;È!‚UÜ<¸*“Ž uÕˆ¿ä0¿õîßúÐkq <7S/ØŒV‡lî#]¨qœgõíQ›ß‹ArRÛË/åöŸ]»1»8çéÍWºÒ®Y5Q \Á< ‚0„¯¶J‘ÍD¶z‚jm¬}…É{‚ßeÞ»ÂùAg8ÎG¯JÖq£¥¾hìÅ®ÍþnÅÛ·×¥I¤ßÂfµ·¶t U¿rR;FAö5™ý|<>–f̰˜îÎ6» w˜Çà1žœŠÑÑà¸Y¯îîa0¹ƒ¬LÀ•Pй8ÈÉÇò OpMtm¬!•ÄQìˆ*¨$–ïÛßéQÀ— l†öÒÚ¨æŒy–ÿqÁ`;ô$jMBFŠ{™)e)gdM†n_8õúUkk´½'Š;…„Ï¦Ü ƒzä…<ž9§L@ ü9Èöƒ¥B4í,^‹ÁùÁƒÞ6ÝÀ`6Üãv;ã4û›; «¨îfÎŒ`:JÈHÎpv‘‘žÆ•a×çá/j‘Ú^<±@ë&_*–\pÓК§§ë—èÖ©on·&×MŽêå嘩 ç…àå¾VëÒµ!Ó´È.Úê(”JKd%T·Þ*¤àß¡mFx¢‰ "O-TLÃ)œí<üËžÇ"€,XjÓßê“Å1 8R623ì]7 .1ßÖ¬[ò%ÿ®Ïüé‘%¬3Í4[VIÊ™î»F¸ô¥´9‰Øtiƒê3CòK/ú§ÿtÖN±%ãÿcYÙÊcóØù˜”Ǹ,dãpµ¤€ô5YÖQi<›L¶ëû³»I]§Ï­ 0ãÖMµô×r™š+Xo Feß»c¦1Àü=+_JÖ®. º’öÆKq yr*¸ ’õRHÇfrä†ó>ø#<ƒéRÙÛYÙBÑ[³ln¢IšN:`n'ÚŸ@±Uu»ÿ°ZÎÖVâKùmcrç` ñšªÚÄ“j6L†¶šæ+ˆÑ÷+‹w¸Á®.“¤­»[¬gÊf σSŸ“Ø©#ÓôÈÒÝ$ÝÚHϘs¹³¸“œ¶rsœæ€)ÿÂKu£Ïuc—²{ËuI·eWkqÁätÈ­6–â]2'¼H’f’"V&, o\r@ª‘iDQMB»&ŒÄàÊÇzªäü£Øb­\Èq#|Ȩ9à0?ÈPžôQE!…Q@Q@Q@Q@Q@w¿òƒþÁ÷?úàUï·¿òƒþÁ÷?úàTÄ{¦•þ¿Cÿ°;ÿ;zÛtG‘‡£ Ö&—þ¿CÁÇüIß¶{ÛÖÞþzûãÿ¯@ û<óÂ/ûàQöx?ç„_÷À§a¿ç ÿ¾?úôa¿ç ÿ¾?úô†7ìðÏ¿ïGÙàÿžß†ÿžƒþøÿëцÿžƒþøÿëÐ~Ïüð‹þø}žùáýð)Øoùè?ïþ½oùè?ïþ½7ìðÏ¿ïRt nþzûãÿ¯Fþzûãÿ¯@¨Ì±%¡Œ“Ô”ì7üô÷Çÿ^Œ7üô÷Çÿ^€öx?ç„_÷À£ìðÏ¿ïNÃÏAÿ|õèÃÏAÿ|õè¿gƒþxEÿ| >Ïüð‹þøì7üô÷Çÿ^Œ7üô÷Çÿ^€öx?ç„_÷À¥H¢C”‰úªK†ÿžƒþøÿëцÿžƒþøÿëШ¦á¿ç ÿ¾?úôa¿ç ÿ¾?úôê)¸oùè?ïþ½oùè?ïþ½:Šnþzûãÿ¯Fþzûãÿ¯@¢›†ÿžƒþøÿëцÿžƒþøÿëШ¦á¿ç ÿ¾?úôa¿ç ÿ¾?úôê)¸oùè?ïþ½oùè?ïþ½fÞÿÈnûÜÿèpWW¾Þdkpdçþ%÷=±üpWSîšWúýþÀïüíëv°´¯õúýßùÛÕ}róSMaí¬ðªYyÊ–ÑÄÙ}Øù·óeæÎ–ŠämµÙ!K»Á‹§¸û"F#Ss¡ÉØÎx5uu­Nco:|qÏ"Ìì. Æo* çÝÀ¦Õ…s¡¢¹-K[»Ô´™f°‰b¶And‘¤"L¹V€;&µ5ÍRM+SI³jöÓb<e\õÉ¡è ÜÙ¢¹WÖo¦¶u”ˆæµ±¸’ö8NÜH¿*€Ü•ç$çF¯©ÞÏc:ZÆ‘ÁlÖÉ,­)bŒv€9#“ŒäЕÅsª¢¹MFóR}+Y2=‘_¡`Å\aÓ p:sõæ·tëÉîžò¨£Ž{Y¼·±e9PÀ‚@=éE‡rXMíÌBhVÜFÙÛ½Žqœv'“¨ÿÓ§ýôßáTnæ¼¶ðŒ—G Ã$…Ù7O¦xï[‘Ñ#IPMQòuútÿ¾›ü)­¢ªX‹\Ÿ¼ßáZtɿԿû§ùPa–Ty³ÚF׫±‰Àõ5#¸E»ßqm¨ÞÚÍyˆÁRA#(åé´±_ø½[—^¾Œµ§Ù-þÞ—‘Û0óO•‡RÁÆz˜§a\×û-ÏüüÇÿ~û*d\ÇIçÆÛA8òˆÏãšÂ“Vº¹¿°u‹mÌw¬„£È‘äsÜŽÜf´lu‘ªGqåF+k—ÝÎ÷RJþ_FÜŠÃø€4´ÈÔEþàþTúC (¢€ (¢€ (¢€2ïä7ýƒîô8+À«ßoä7ýƒîô8+À©ˆ÷M+ý~‡ÿ`wþvõ~óH°¾¸ÜÅ#K³ËÜ“ÉW9Á Ã#>µCK M¡’p?±ßùÛÖטŸß!”ßFÓ]MštD!Y”a>î0x#±Ô±iÖ‘4L‘¹h‘Ñåw 67 ’sœµ?˜Ÿßb|~tÄg·‡ô–h@‰,® ª}ÐÀ›ù«wvV·Í ]²˜%G’F×/˜Ÿßb|~tXév%ï\Û ×êä†?¼޼pOLTw.›s2Ë5±.¡Ë+¨`¿wpǾjßb|~tRMO–Yä’Ü“pÁ¥W Äs´ÀäÕf;x¢–ycM²\8yNIÜÀ·t§y‰ýñùÑæ'÷Çç@¡’Äé&ÃP’5 ­±»í$çßzЏºŽžª^A€0?x)ÊŸ­xÿž¿øõ;ûJÃþ ÿ¾Å6]JÄÄà]ÀIS¼QçùëÿQçùëÿPzÍnc‹tápŠÆxèjͱÞòÊ¿q‚ªžÇÎ?1SùãþzÿãÔ†T'%Áüi uRòígbº ÞLæ@¥ˆÃ,§¯=¥Zóûãó¦·ÙÜåÖ6>¤@ÚÖ›iªÃ 2"M Mäe@øàûuê3QÝèÚ|ÐÁ "‰.–æ_ß9y}üîÏNsÚµ6ZÿÏ8ï‘FË_ùçýò)ŠÅ?°ØC+g)%³3Û–‘¾Wlä±Î[99ÎsLÓ­ Òô¹áYbi&y&”§»vÐpÒ¯ìµÿžpÿß"€¶Êr©#¸Q@ˆ `ðB€*}3ÌOïÎ1?¾?:CE3ÌOïÎ1?¾?:}Ï1?¾?:<ÄþøüèôS<Äþøüèóûãó  ëßù Áÿ`ûŸý ð*÷˲[€ƒ‘ö Ÿý ð:b=ÓJâãCÇýßÿmë{sxþuƒ¥¯ÐÿìÿÎÞ·hw7÷çFæþñüé(¤1w7÷çFæþñüé( ÜßÞ?›ûÇ󤢀sxþtnoïÎ’Š]Íýãùѹ¿¼:J(w7÷çFæþñüé( ÜßÞ?›ûÇ󤢀sxþtnoïÎ’ŠG”F¥žMª;“Q}¶ùø_ûê•ùº´§˜ô¦\xƒL¶»–ÚyÝ¢V0¿—`ÜøÚ8#©¦!ßmƒþ~þú£í°ÏÂÿßUwÏ‹ÌXüÔÞÃ*»†Hö¡n!iLK*ª†…Rûlóð¿÷ÕN‘Çó©’X¥ÜD|pÀqìj—üyCþà  $¹HˆJžÄÓ>Ûüü/ýõRÚ.nXà`/?¨­5Í>öS´Îà|Ï%Ägpäm? í°ÏÂÿßT}¶ùø_ûê­›¨BS<~Y8¼có¥kˆQUšdUºKé@þÛüü/ýõOŽæ9[ls=p¦¹¼ŠÞܺ³C‘£ 7` ôªÍp·pi·J¥DÄ8¨ /Ê€)^’uÈ2æsÿ¡Á^^û{ÿ!¸?ìsÿ¡Á^@饯ÐÿìÿÎÞ·k Jÿ_¡ÿØÿ½nÐERQEQEQEQEQEQEQEœ\ÚŸúhßúV-Ä:¢ßkQÛéþlz†ÁÏ2ÔyaNáߥmÍ>ÆF èÛ—=:ü‰¦bïÖÖ˜Žpè7‘HÖÑÛ,ÎÏnbÔZE ƨÆw `î{Ô­¡Ü™DðÀܾ£q#N î:8rFJñ×Ú·±wëëF.ý`ýh¸¬dx[K—M,÷ÜE0…bbÏ ñÝD`õny­{/øñƒýÁI‹³üP~jX£D‘ƒƒ v!’/´G}o¼§›MöTŠËŒëi ÿfG¦$sCl"IŒ±´NT`aIÏ t`ïZÏ¢VxY>p7Ïo¥»õƒõ¤3œ²Ñ.ÊÆ—6mäi¥ÁŠsBŠ’V?“ïvÞŸg¥]Ù]E,ÚZ^@ 192 262 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀÀ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑ´2MOy4Û7v¶‰™šÝ $ É'lé@`§M° ÝÙÓ'ô¥Ðÿä¦ÿפ_ú©¯-#¼ˆ+GCº9ï#zóÍCý¥Ð.Çÿ“ü)HÒ;tÛ´àâÝ8?•S]Fêæàéa’;ÄÏ›:T(Ç*?¼r8=;çŒë[[Eià íE÷É'¹'¹>´VM'GŠ6’M7OD@Y™­ÐRN*–ï Ôò†®ëßòÔëÖ_ýÕøCtùðÿÈÒñT$xfæUŠÞ-Y¢"DÄ÷è*ÓèúR£7öU‰ÀÏü{'øVhðþ™¥jšdö6ÞT;!o1›*CŽIô½7ú™?Ý?Ê„OØôŸúØÿß„ÿâhû•ÿ@{ûðŸüMW]*Y×Ͳ.öcŒ¿1ᇥ+é2Àžq½‘¶2œeùù€Ç,kkSîey“ýJÿ =ýøOþ&²i?ô±ÿ¿ ÿÄÖ…™öI|Ÿ¿¸b‹ˆÒIãVR_oÎ#õ¥hÞûµÊËKc…Ѭ‰=…ºñ4†ÓJÇþü'ÿWۆîŒê=q‘LHbd–Y𯷌Qh…äRû&•ÿ@{ûðŸüMdÒ¿ècÿ~ÿ‰­‚8~Ò²e”(9œU´Ë„ÜTž3ÖšŒX6Ðß²é_ô±ÿ¿ ÿÄÑö]'þ€Ö?÷á?øš»qf‰neO1vžCãŸÊœöPüÑ«¿š©¿œ`Ò´ò(‹M-ŽE±$ö'ÿHm4 ptkGý0Oþ&´-aŠ)`.Ìeq¸ÐUO3˽ßé'õ¦£ö3H‹ìºWý¬ïÂñ4ŸeÒ¿è cÿ~ÿ‰­cl†âs 9ÂêFj¼«ˆ-mØ79f Ö’Q}ÜŠ?fÒ¿è cÿ~ÿ‰£ìÚOý¬ïÂñ5v{%A)uáH|d~Tmoöµ·F“vpÄãÓµ;@W‘OìÚOý¬ïÂñ4}›Iÿ 5ýøOþ&­Oo’ò@ì|¶ÚÁ¨°?¹ºÿ®trÆ×°^W±WìÚOý¬ïÂñ4ŸgÒ¿è cÿ~ÿ‰«ñY@ë³È$‘w c öÑ,QË ;+6Ò\ÑhäVû>“ÿ@kûðŸüMgÒè cÿ~ÿ‰«—H–æTóT‚2$Ç?•8XÀ¢gÊ©¼ãh´ò*Ág¥M*Çýb3ßÈOþ&­ci_ô ±ÿÀdÿ [ \"\1bI8 íÍ[Oãÿ{ú Îi'd\[kSˆøƒaei¦[=­¼ fÁ1D¨HÚ}câWü‚m?ë¿þÊh©(èô?ùé¿õéþ€*[Õº‘+R#Þpòž¨¾Ã¹ôíü«>Îêkm EKxRY'†(Ày û’ÙÈû¾ê×›«Ï•—þ?ÿ >—nlÒÞ0Ñygtr)ùÕ¿½žç×=rsSZƒj‚U8,‡†÷™ôªþn­ÿ>V_øÿüj7VÿŸ+/ü þ5@jÐÉs¤^Á î’XsŒ’¤Qý¾çþ¿÷Ü?ür7VÿŸ+/ü þ5G›«Ï•—þ?ÿ ¤{«»Ût눌Žò4xËuþ'«Õ£?ú‰?Ý?Ê©ùº·üùYàcÿñªF“Ue*llˆ#ý1ÿøÝ »haXÌ!¶“Ï™Ž¤ŸOz'»i¡hÄ!wÏ™ž„OjO"ÿþÖ_ø'ÿ£È¾ÿ u—þÉÿÆêï-!Rãe³Ã·ïœîÏJKk!Øí `Œâ"ûþÖ_ø'ÿ£È¾ÿ u—þÉÿÆêùâ.I›åBÉÕ‹8]ÙëïQ›¬Á${>ûîÎzRyßô²ÿÀÙ?øÝE÷ý¬¿ð6Oþ7Kž!Ë"c¨fgc(ê®ïëU¼à³‰c@ …Îiÿg¾ÿ u—þÉÿÆèû=÷ý¬¿ð6Oþ7MN(9dÉ&¾Y"‘†C–;³A¿ýûKåõf7~µÙï¿èeÿ²ñº>Ï}ÿ@ë/ü “ÿÒæ‡`å‘,Z€EO2í¶qЍï½Ùºdæ¦û=÷ý¬¿ð6Oþ7GÙï¿èeÿ²ñºjqBäùoÞA˃=zšPf¼[€€mÚNx¦}žûþÖ_ø'ÿ£ì÷¿ô²ÿÀÙ?øÝðì>Y’ù ¢ÇÅWßùÉ¥‚ádÔÖfÂ)99=8õ¨þÍ{ÿ@ë/ü “ÿÑökßúYàlŸünŽx‡,‡Ý^+#ÃjŠÍ– çuEos䤫·w˜»zãï³^ÿÐ6Ëÿdÿãt}š÷þ¶_ø'ÿ¡N6°œe{Ký¯yyò”¯ÞëL[Ò±"*r’oÉ?¥f½ÿ m—þÉÿÆèû5ïýl¿ð6Oþ7G<;$‡M~²E"$ „mùæ­­ÈŽy¦ÎÌŸ|ýj—Ù¯èeÿ²ñºO²ÞÿÐ6Ëÿdÿãtœ 5^äÚ}Ñ%-ÙIVî¼VŠÿûßÐV\pßÄáÓN² :¶¿ÿ©¼Ý[þ|¬¿ð1ÿøÕDÚn訦•™ÎüJÿM§ýwÿÙMŽî~Ùá­2ëfÏ=–M¹ÎܦqŸÆŠ’ËOùxgéþ“=lË,p¡y]cAÕ˜à Æ´ÿw†~‘ÿé3Õ¯ÊðhóIÝÁ“”0ûñâ€4¨®oS½ÔR]Zk{ÓX*2Eå++errHÏäjx¯®,nîa¾½3B¶‚äJcPÉÉ`i Ý¢¹›}böÙïEÀ¸•"´71ý¦4F8Ï÷;}y¥šÿPÓš)¦»ûRÉi,æ?-UC(`œsÜš×õ÷éh¬-çU–ê3r“½´±ng•#P­Æ6ìbH<õö­Ú-`NärÏ dTûÇäuu ŒOB sšþ¥u¦Ù‹›ea,’H(@Æ<}Õç€æ´´Y¦žÚÚkˆ„SO yP †ÀlvÈçð  d¼’Ȭ(€÷ôñË2³‡$ÀzØ{U{¨>Ò·1eŒ1¶ÒFÑÆj—‡?ä ¥oèÕD›„…±æ™Ä3"•Ž¡[4Ée½‚)Fc!›ièÌ1üÏáRê1 µiB$Ctg¾{Ç¥IC¨ ŽH®~ÊÊØë«6™Š}ëq0b|ç?ÃÏÞÁäŸ^( ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(€ñgü‰Zû‘ÿèº(ñgü‰Zû‘ÿèº(£´ÿw†~‘ÿé3Ö½Õ´7p4 ¾6Á#$t9>•‘iÿ ï ý#ÿÒg­Ê«.i(ºE‘tÍó˜^8ô¥’ÂÖYI! Ï’Ù$‚ž˜éVh¤3> ÎÏÌ{Xs#Fcýì®ãÝ䜥PÓ4·ÔÌñA$Mů ;±Ÿ½ÐqÐõ¿E1ì´»; ÚÆÑ’11Šè8…\¢ŠˆÂ7—ŽG‰Ûï#Ÿ¨ Štq¬{ˆ,Ìßy˜äš}QÉI¥ÜŽCAU'°¾•œÀ-ඉÒ(IÀ`ùúÖ…î+ ’$”àðr8 úƒM啤–Ivœ¨r0®­KE!…gÚh¶6r#۬ɰ’íçý’Øý+BŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šàƒ è¬ m!£Ž91ÑÜ¿ üèÝ•ªËtu Kk¦¶‰ º¢±ù@#ïUTœØÉ ³Ëö´ºkd{hÔ´¤ ðåuúR»$±Ç·ÌuMíµwdúz}s0j7SÚZ}£ýjj^C#]Ä õ qJ×Ú‚-Å÷Û Šï#ìæ5ÚSx^¸Îyõ§oëîÿ1=?¯_ò:@AÎ8àâ–°ü= ¾mô¿i“ËûdÃÉÚ»s»®qŸÖ·(¢Šæõ»˜¢×U.îo"¶[Bø¶iÍ»©ÙíëÅ!%ÎA©ÝÁ£Ú´—(³ÊÎcóái^Hóò©ÎqŒššfêößN[8áK‹´gc.J ^òiˆÜWWÎÖ ƒƒƒœZål¤xíãÇ’6®ÊÄg ry^žjûkO¸¸ ø¯~Î6ùs×® ×åþ`ôþ½ÈÛª÷D³Áb¢Y6±SƒŒý+>ÃR¸¸Õ&¶¸h ØÌÝ‘„Œ ðÁ‰Á¯´.?ãêËþ»ý¨_ì¸?¿qÿßühþ˃û÷÷ýÿÆ©êÿjQÓ¤[·X^áPƒü¬NO~*¥ûÜÏ&¯p—sBlòQ ‰aüYÎ9 :Ø×þ˃û÷÷ýÿÆì¸?¿qÿßükiîoaÔ¯EÔÖíg´1£as°9Ü?‹9Ç5ÑÛHf¶ŠR0]é‘E…r‘±….ãMÓhØfn ®;ûš¯Ö™. ÖhÓï+™c°êªÙÁ#¸ÿWîX¥äD)cå?©ëQ,F‘‹,"Qp˜R:3Å*e%„o´×úÔ•sÎpFdè{|‹RÐEPEPEPâÏù´?÷#ÿÑtQâÏù´?÷#ÿÑtPGiÿ ï ý#ÿÒg­Êôÿw†~‘ÿé3ÖåEäm$Å,‘n9`„`Ÿ¡…>8Ö5Ú òrI9$ú“N¢€35M$j7ÖRKƒ ÷ì­’0GÓÖ¥mÁ¬ÒÓìàCn@¬T«zî9ç®jõ ¥“e IBv¤¾zæF'©$äþ4ã¦Ú4BbýܲùÎ7_ 篨nŠTM´Šõî㌬ÎIb¶“ë·8Ͼ*ÝPU”GQûi,dò|¼mÛœþufŠdÄg¹º¢/å´l¹Ec’ƒ ¹éãB·[Kh#šxÞÛ>TÈÀ8Ï^Ø9ôÅiÑ@ŒØ´[x¡Š?6w1Ü}§{0Ë?=xéÏjdÚ ¼³»‹‹˜ã’Q3ÂŒ63‚yêCZ´PÒ“íÉw-ÕÌícH˵ à㞤Ô÷ñõeÿ]¿öV«Ù#IWk¨a@]YÇtÖí!``”J»ORûsUo4[{¹ä•¤ž1(hã|, tÝÇáÆ)ßfûÓÿàDŸüUfûóÿàDŸüU2ïD¶º™ä2MÊÍo…”†?1Z@tCìÑÿ~ü“ÿŠ£ìÑÿ~ü“ÿŠ  .Î.áÿ®oüҲ⳽[ ²_³ŒïEçÌcýÖnê?3ßß@ÚDNOšHÌçúÑöX}$ÿ¿¯þ4[rÓŸúkÿ²­MMDXÔ* Ú@Q@Q@Q@‹?äJÐÿÜÿEÑG‹?äJÐÿÜÿEÑ@§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤Ï[g¡ 丆²¢Ð3b¤0ƒÜRi±§ØÒ\$£tŒz“Ü~)‘¢Ås O€J#…ÿ{‰·Jíòz “ô¦jšJÞÛYÛ Q #2– ìPFæ´è¦"½•µ„l–Ñì w1,X±õ$òjÅPEPEPEPEPEPEPEPEPEPEPEPâÏù´?÷#ÿÑtQâÏù´?÷#ÿÑtPGiÿ ï ý#ÿÒg­¬·üó?šÿbÚÈ;Ã?Hÿô™ër€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¢€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¢€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¢€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¢€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¢€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¢€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¢€–ÿžgó_ñ£-ÿ<Ïæ¿ãN¨ÞâÛl’¢ŸBÀP²ßóÌþkþ4e¿ç™ü×üj?µÛÏÄ_÷Ø£ívßóñýö)&[þyŸÍÆŒ·üó?šÿGö»oùø‹þû}®Ûþ~"ÿ¾ÅI–ÿžgó_ñ£-ÿ<Ïæ¿ãIÑKŸ.D|tæŸLå¿ç™ü×ühËÏ3ù¯øÒI4QcÌ‘=7S>×mÿ?ßb€$ËÏ3ù¯øÑ–ÿžgó_ñ¨þ×mÿ?ßbµÛÏÄ_÷ؤ™oùæ5ÿ2ßóÌþkþ5Úí¿çâ/ûìQö»oùø‹þû&[þyŸÍÆ”Ï(G¾GøÔks°Tš6'°aRÓ€ñgü‰Zû‘ÿèº(ñgü‰Zû‘ÿèº(£´ÿw†~‘ÿé3ÖåaÚÈ;Ã?Hÿô™ër€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ K<†l|Í#äúáˆþB–©\¶4 ß÷&þmI»++»ÔWö¶Úfƒ§ê‹{ÃäåœyŰ °èr «Ꚁµ»ÕéV+k†ŒZyc ªÛN[®ãÔ~U5­‰Lêh®cP¾Ô~Ñ«KozbKWH|¥*ÿ&â #?‘¨®u}ZêòåtèçÿGTØ‘¤e]ІùË@ç-! è[fæó6çÛiãôêŠáÙÅ¡uÚÆ@HÏCµ¸©h¶`y· ›Ì Ÿm ãõ5n©Û6Ós“æì‹XšŸg©éñj7Ñý¢öF,ò;£?(þèÆ(@tôW/&±r5hÞ[™läºû;oŠ1êÓ÷²ïÅ5µEÍ÷ÛIŠï#ìæ5ÚSx^¸Îyõ¡ký]Áéý]Žª“5‰§\Þ_O=Û]˜à†wŒ[$kÈS˜‘œž¼b¨iž±}%­ÑŠf¶œŸ1Y"¢ó‚¤6âAÇ_~”½4ð^iRO #1³#ÜgŸÌS×î¥dèmÿ|cþ˜¿ó5¬¿t}({Àø³þD­ýÈÿô]x³þD­ýÈÿô]ÑÚÈ;Ã?Hÿô™ër°í?ä៤úLõ¹@Q@Q@Q@Q@Q@Q@Q@W…kI!nGi‡¨,jÅBöѳùÔž»\®*C*Úèºu¤©,0ñŒ!’F“gÓq8ü)Òi|—j{peÜüÇiaЕΠ÷ÅOöDþüß÷õ¿Æ²'÷æÿ¿­þ4Ä5ìmdûVè³öµÛ7Ì~aŒzñÇ¥E>‘a<«#ÂCª„Ü’2@pFŸì‰ýù¿ïëdOïÍÿ[üh¸9’ÜÓOý”ÔõvñÆÛ†âެűùÔ´ \úiÿ²­U“EÓ¤¸iÌdvÜÛ$d }HøÕ¹-ã‘·ÁºeX®*oÙûóßÖÿ¬4m<] ‘ <ÐŒ÷¶çü*S§Z4BbýܲùÎ7_ 篨'ÙûóßÖÿ>ÈŸß›þþ·øÐ_Ù–mûbÄVrw’2†>¥AÁ?QI•emtn ˆÇ!$ád`¹=NÜíý*o²'÷æÿ¿­þ4}‘?¿7ýýoñ ¬ZuÄVÉåÆUÛnI#¶z}*ÚýÑô¨E¤y™ᜑúšŸ§¯§€8È•¡ÿ¹þ‹¢È•¡ÿ¹þ‹¢€:;Oùxgéþ“=nW3g©hsèšl7z„JðCÂÎcdqÓÊ{‘R}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑd=zS+ÎÓß_óõ¬µøwþ‚òàÆoþ.—ížÿ ÄŸø2›ÿ‹  È•¡ÿ¹þ‹¢^é³h–VºuÌ2,¸ª… {Ñ@ÿÙfotoxx-12.01.2/doc/images/synchronize-files.jpg0000664000175000017500000002453711701011016020034 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿíHPhotoshop 3.08BIM, paste paste trim resize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 157 471 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀ€D"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êtm'K}OgÓ,™šÖ"Y­Ð’J ’qSGa¢Iq, ¦Øy±`²›T¡éÈ÷©´Oùißõéþ€*¶±ûÉ ŠËþBƒ˜XË5þ"çûž£¹Æ9Å<Øh‚í-³l Υ‹T8QÜñÀ¢ëMÒáˆ2éZy9Ç6Éþh»fŠPÃP¢ç,ç³ýÏîã§~sV5#‹aþð§X¥±™ö};þoþ§øQö};þoþ§øRfŒ×G³F<ì_³éßôÓð?“ìúwý4ßüOð£4fgçbyý4ßüOð©WOµu º¡‹þꩪÜ0–Øp<á?í°þ•J+b¢Ûêh=¤k¹ôM=G©´_ð¥6¢/4èšxN»¾ÊŸáTlns ¨ÛÃ1\“Àäÿ1[’+Éhd¸ŒÄÑÆ6¾ì«ú Rš½†ï{\Ìò4ÿúi¿ø ŸáG‘§ÿÐ#MÿÀTÿ Òœ@±¤ˆ‰þ’ë´`| u§Ê;8’8Ñc¸ •àúÕZ=…yw3b³²™ˆMM$Çý:~U“§ÿÐ#MÿÀTÿ Ö‹ÍŽîBðGˆßhUaýiŒF×·`ûvü¹úR´{½Ì¯'Oÿ F›ÿ€©þy:ý4ßüOð­K4I!Öœ;Ÿ8>AíéE¨‡ËDQºË+)f\œvæ£Ø.û™ÏidˆŽÚ>™‡_ôdÿ g“§ÿÐ#MÿÀTÿ ÒHrö‰G’qd€zš‘êböÁ ¯î£Ø2Ã<œt&‹G°{ÝÌ¥·°f º>šI8ì©þ?ö\!”6‡§.ã›dÿ {캣×*@?…Oº 5q”ÙóíÍx=¨q]¹ŸrƒÚY$K#húfÖ$ôdê? g•§ÿÐ#MÿÀTÿ Ò‰c’ a&<µ™ƒzARH±‹¨A²|å²6( >€óŠ-ûîd´ÿúi¿ø ŸáG•§ÿÐ#MÿÀTÿ ›QSÓ)(xå]¿§­Vеµ{å$ÇùZý4ßüOð£ÊÓÿè¦ÿà*…34fŸ³as±þVŸÿ@7ÿSü(ò´ÿúi¿ø ŸáLÍ&höqìì“ʰÿ F›ÿ€©þyVôÓð?£Í£Ùǰs±þ^Ÿÿ@7ÿSü(òì?è¦ÿà*…34fgÁÎÇùvôÓð?Â.Ãþoþ§øS3Iš=œ{;$òì?è¦ÿà*…]‡ý4ßüOð¨óFhöqì.yÁŸ$ñÆt4`-S×éZCHÒNq¥ØpqÿÉþ™fÓ`ÿ®‹üë}?ýÿèµX¨½ i¶Ö§|K‚ _$v°E}™Ø Î[œ *OŠò5'ýz§ój+#CÒl5 ;K—1Bd´Œ¨vÆì"ç˜üécÖ48ä’Hï­å »ltÍTÓçŽÙ´I¦•"4g,îÛBô~¦µ­5{ éLVZ•µÄwŠur®éÈ  ¬hm:N×Ö†XÁ ûÆ@=GÒ£½Õô¹áš•¨;³Ì‚¶··÷çLžå-â2ÜN±F¸Ë»í'“ïBvw®slÓÿè)eÿi>Ù§ÿÐRËþþ×S¹Çñ7çI½¿¼:ÓÚÈfŽ_ízý,¿ïíkÓÿè)eÿk¨ÞßÞ?ÛûÇó£ÚÈ=š9oµXÐRËþþÒ‹Û5]fÙ@ì·,n¾¯aßÙQ¶[œä™Ô>OO—9©ã¹Ye–4v- Á`‘‘Ï~=(uÜ99£u`X±ÕlÙVi‰'ñ4¢îĵ,ŽpeâºíýãùÔwIm Mq0Ž5êÌØjÃÙ£žŸQ´¸`ϪX £ Lô¨þÕaÿA[/ûû]VçÄß&öþñüèUdƒÙ£–ûUýl¿ïõ'Ú¬è+eÿkªÞßÞ?ÛûÇó£ÚÈ=š9_´ØÐRËþþÑö«ú ÙßÚê··÷çFöþñüèöÒfŽWíV?ô²ÿ¿Ô}ªÇ¯ö­–ë­u[ÛûÇó£{xþt{i³G+ö›ú ÙßÚ>Óc×ûVËþþ×U½¿¼:7·÷çG¶{4rŸi°ÿ ¥—ýý¥ûMýl¿ïõu[ÛûÇó£{xþt{i³G(n,è)cÿúÔ ‹ú Xÿßßþµu{ÛûÇó£{xþtý´ƒÙDå>ÑaÿAKûûÿÖ£í?ô±ÿ¿¿ýjê÷·÷çFöþñüèöÒe”ûE‡ý,ïïÿZ“í?ô±ÿ¿¿ýjë7·÷çFöþñüèöÒe“ûEý,ïïÿZ´XÿÐRÇþþÿõ«¬ÞßÞ?ÛûÇó£ÛH^Ê''ö‹ú Xÿßßþµh±ÿ ¥ýýÿëWY½¿¼:7·÷çG¶{(œŸŸcÿAKûûÿ֣ϱÿ ¥ýýÿëWY½¿¼:7·÷çG¶{(œŸŸcÿAKûûÿÖ¤óìè)cÿúÕÖïoïÎíýãùÑí¤Ê'-ouaÌR6©eµ1ľ†µ¿·´u N¥lwdŸýjÓÞßÞ?fø‘ÛþWæ?ñç7ö D¦å¹qŠŽÇ™|SãÅHüû'ój)~+ÈÚ?ëÙô&¢¤g i_ëô/û¿ó·ªOmr¶n%·º6§V–KˆáVñp@•Ý´ñÚ®é_ëô/û¿ó·­ÚâäVC¦E¨Ã~Ö¯=ÉŠD[r›‚üÜs×1š¿uo'Ö âšK¢Wä ´›|ÐW8îúWBÐÄóÇ;Æ­,YØçªä`ãð©(¸£éR\jFiá»>f«"ÈwȃgÝÏz©¨G¨ÞÔÛ\åÆÉŒ3HêCb5ÂFGFlŽ+¶£&úœ^´nešþ;ß<ÅoöW@û¸ß¼Ý×5oK´¾#’[¹®#‘n&b>Í!I"9Ú<ÍÛ1Œ`"·åÓlg»[©­’IÓY‰8ÇN3Ž>•k&ú“c–ºÈº×­dÓ.®Zñ“ÉÜ”Ýäm=óÅDº~ Ñ.ÅÔ©öËE‘”¾ÖAAÞ¦ºìÑBc±ÉÜØÞŸ²™® …^²:[K(1•Ü*óœîƒÖ£¹´’}#R†[;é57.]™\£ |€‡îýÐ05ØQ@Xå5–IGg©›#jÂÑ"IU’mÝXuÁn:Õ›m.{»Ëí17œ,aŒJ‚‰ °r¸8'5ÑdÓ&‰'…â•w#Œ0É…sz#Kw"Þj\™"š;HÂÚ0C¹ÇI=OWOQÁ VÐ$ñ¬q ¢ŒRPÀ(¢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ Íñ'ü‹:¯ýyÍÿ Ò¬ßȳªÿלßú 4ø­ÿ#hÿ¯eÿКŠ>+ÈÚ?ëÙô&¢˜@Ò¿×è_öçoZ~JÝêmÌþZB*¹^I#±ö¬Í+ý~…ÿ`wþvõ­nÁu‰Ùˆ[©$öù4&Xé–êí4’ D.Ù¹~u?{¥=t«&PËçFAûDœÿãÕ•,o{¢jÚ¡VÝw -¸Ç"ßûë–üEC:ßZ[ßAi5ã/Ù`“%ÙÙrÄHS=ÑœýadndÙúOÿñTdÙúOÿñUÏŸ>ã|V·7çO7J!“Î9SÉÜWp^§®j}ItÈÖK«¥„Í\K#ÈYU¡òà»ý1j.ÂÈèç±Ó-€74AŽ{·\ŸÅ©çK± ¼™‚ã9ûL˜ÇýõX³ÝÁm£Û-ËÅ}<ÎéÓÂÅc^ä–É {·jäM¥iº”Í*MW“¿€n>ÙáGûÞÔ]…‘¤ºU‹¨eó™HÈ"æBÿ¾©­§ié*DÍ0y3µ~Ñ'8ëÞ±5hnN±"Ã=ìP®ÔT†gD äÈÜp>e^jÇÛ¢‹WÒÞk¹F·ÅÂ[h%A\®vƒ’yÆhRl,oì›?Iÿð"Oþ*ì›?Iÿð"Oþ*³ão\.£qv“ ”ZFŽëG´v_•¾mÙÎqíUl¥º:¬ f»kÃu º‰ÙŒkÍ´…?(wr}èM…‘²tËê„ʲUMËäã®>jlzvŸ)FÓ1¶>.$àã8ëî*4­ååÖ¯!ýÐ r{F§æaõaù(¬¤ºY4^ÞÎòáØM˜HÚAeX’ØÉ=èæadodÙúOÿñTdÙúOÿñUÎÄ÷–^eï¦R²/Ï;å@¸(î£ É#’i"¸½û-ÌMsrÖQÞÄhÞBD%Am®Ný»ºœñÎ ¶GGý“gé?þIÿÅQý“gé?þIÿÅW2³Ý¾žLW—_cŒ‹$Ò<…–0¿(,à¹Ç"­]4‹£Ù³êÎê%s’f‹Î^p¥×æã±ïŽô]…‘«•œ×W0ys ¨Ýö™>l®}jì›?Iÿð"Oþ*«hNÒÉs#Å$LË 1ÈrÊ|±Á=ÍlQvEì›?Iÿð"Oþ*ì›?Iÿð"Oþ*¯ÑEØY?²lý'ÿÀ‰?øª?²lý'ÿÀ‰?øª¿EadPþɳôŸÿ$ÿâ¨þɳôŸÿ$ÿâªý]…‘Cû&ÏÒü“ÿŠ£û&ÏÒü“ÿŠ«ôQvEì›?Iÿð"Oþ*ì›?Iÿð"Oþ*¯ÑEØY?²lý'ÿÀ‰?øªŠÝDW0)cl›w1b29äóÚµ+5?ä!{õÿA4^é†Ì’BV6#¨ÒAeÛÆïæ32‚OšÃ$cD¿êŸýÓ\ÿ‰Är&‡ße1™~auþ«ýQûÕ%'Ø-¿»'ýýñ£ìßÝ“þþ¿ø×# Ïu$¶:|7ÒÃ’é™ !’@¥ „. Ø7ýjÅ®«{6£ ÿh3O=ܰKdq݇g# rI4Ås¦û·÷dÿ¿¯þ4}‚Ûû²ß×ÿãÄÁÛ•·˜ÎŸƒþ?AûÝ: ôäU³«ê‡V‹ím{w2ËŒÆÑ§£r°îAçÓIcŠùŠÀ+qúÖ^ºæOêÝZÂBïÙ¦xvêö{{¦º½‚î-ªcd•de$‚UTÓëK¬ÿÈ}ÿ`ù?ôY¡‚gœüVÿ‘´ײÿèME¿ämõì¿úQ@¥¯Ð¿ìÿÎÞµdŠñçæt’! e©?Ä@Ç5•¥¯Ð¿ìÿÎÞ·r=h¸ [Ù•B®›0`$\ãÔ¿nŸþÓÿßÈÿøª\Z2=ißÈVíÓÿÐ:ûùÿGÛ§ÿ tÿ÷ò?þ*—#ÖŒZ/äíÓÿÐ:ûùÿMû\¾g™ý—.ümݾ,ãÓ;©ù´dzÑ °ŸnŸþÓÿßÈÿøª>Ý?ý§ÿ¿‘ÿñT¹´dzÑ °ŸnŸþÓÿßÈÿøª>Ý?ý§ÿ¿‘ÿñT¹´dzÑ °Ä»–4TL•F«Ä÷Õ;íÓÿÐ:ûùÿK‘ëFG­ò öéÿè?ýüÿЍ®'’æº}ÐSŽRáþ\SdzÑ‘ëEü‡b YM¤"}.u@IæhÉ$õ$—É>æ¦ûtÿôŸþþGÿÅRäzÑ‘ëEü…b¦’)æ™tûÓ[2ÅŽ8ùªo·Oÿ@éÿïäüU.G­´_È,'Û§ÿ tÿ÷ò?þ*·Oÿ@éÿïäüU.G­´_È,'Û§ÿ tÿ÷ò?þ*·Oÿ@éÿïäüU.G­´_È,'Û§ÿ tÿ÷ò?þ*·Oÿ@éÿïäüU.G­´_È,'Û§ÿ tÿ÷ò?þ*·Oÿ@éÿïäüU.G­´_È,'Û§ÿ tÿ÷ò?þ*·Oÿ@éÿïäüU.G­´_È,'Û§ÿ tÿ÷ò?þ*£d3O<‰å™Já €9Ç.G­´\vÁhÙGRª¢hŒ)öîÅa1èE[Èõ¥Ï½HÊâê!ŒE(Ú01nün)ÌAˈ¥ F vÉ\UœûÑŸz¯ö¨¿ç”½sÿï××§ZD¸ ‚E-˶`O׎jÎ}èϽTóâTe†ÞE-Ù`eÉü€ªºêü%¨£u[ ü#5«ŸzÍñü‹:¯ýyÍÿ `y§ÅoùGý{/þ„ÔQñ[þFÑÿ^Ëÿ¡5ïô¬ô,€âNý~¶õ»µ?¸Ÿ÷Ȭ=+ý~…ÿ`wþvõ»@ µ?¸Ÿ÷È£jq?ï‘KE!‰µ?¸Ÿ÷È£jq?ï‘KE&Ôþâß"©ýÄÿ¾E-›Sû‰ÿ|Š6§÷þù´PmOî'ýò(ÚŸÜOûäRÑ@ µ?¸Ÿ÷È£jq?ï‘KE&Ôþâß"©ýÄÿ¾E-›Sû‰ÿ|Š6§÷þù´PmOî'ýò(ÚŸÜOûäRÑ@ µ?¸Ÿ÷È£jq?ï‘KE&Ôþâß"©ýÄÿ¾E-›Sû‰ÿ|Š6§÷þùµ ʲOm€ÈòÊz+(L'÷#ÿ¾EOîGÿ|Šcc­×ÙXX ƒÝ›ùöëSý†Ëþ}-ÿïÒÿ…1á?¹ýò(Âr?ûäTŸa²ÿŸKûô¿áGØl¿çÒßþý/øPxOîGÿ|Š0ŸÜþù'Øl¿çÒßþý/øT2ǦEu´–ÖâY÷ykåvŒžÔý©ýÄÿ¾ESû‰ÿ|ŠŠ -Ìh0‰.G@ ©þdÒº$·PÇ*‡C¸•<ƒÞÂr?ûäQ„þä÷Ȧ̺E¼‰ëc¿ÝW¥¾€õ©þÃeÿ>–ÿ÷é˜a?¹ýò(Âr?ûäTŸa²ÿŸKûô¿áGØl¿çÒßþý/øPxOîGÿ|ŠÎñQá­W £ýnŠðº©¦Î÷PC>m¶M±…*Jî8ô#¥gël_ÂìÇ%´ù ?öÌМ|Vÿ‘´ײÿèME¿ämõì¿úQ@¥¯Ð¿ìÿÎÞ·k Jÿ_¡Øÿ½nÐERQEQEQEQEQEQEQEQEQEQETRqujé£è RÔ3«îŠH×y‰ÛžH*Gõ z}&ãTÖuÈOÙâ·–HwJ𖓈Ç(zïØÓ¤[ïìíbêoÇÚÚ5Ä®ÅarQ Û»°@Îk{íϤÿšÿñT}¢oùôŸó_þ*Åcœ3Ý}’ðÙÜj-¤ý¦&,í0Ÿ7kŸwž£'­,ò\@¶zͶœmÏÙçg‰—w;ˆ9b0 ó]?ÚfÎ~Ë>~«ÿÅRý¦|çì·ú¯ÿ@àmM¼JÉq¨¼,éä¦ÙvKÑœÙ'‘Qèûä×t·žKÙ/ãYþس³•ˆãh?(›zŒWMö™±²ÏªÿñT}¦lcì³ãê¿üU ……„æâìÿÓQÿ -8œ^À}›ùSmÕÇšò.Ó#îÛžœý(œ8’9cBû2 ‚3‚=é‡o%–«¨fÛuÔ÷;á•íÌâÀÚàô ñØóÞ¨Ç}¨I«Ý´oqè.„y’¹—î7Íò©=Fß^õÔ‹™ÇKYÇâ¿üUiŸû,ÿšÿñTË·ö¥°Ž E¢–ÊÞiØÊòH„¸-’Òx€§j³Hïj¶:…Ôa‰ÂNòNÄË»ø˜Ç n+¦ûDßóë?æ¿üU/ÚgÎ~ËqŸªÿñTÂÆvæÅ¨jëpKHþKï(TH< ¥‡âk?ò'_Ø>OýjûÍ;¡Qk($q¸®?SדËðž£s²ÆUÏÒ3Cw¬y·ÅoùGý{/þ„ÔQñ[þFÑÿ^Ëÿ¡5èWúý þÀïüíëv¹+MSC{ .Câí.-ì–åËpÊ… 9AúÕí}'þ‡ÿ¾íÿøÝt´W5ý¯¤ÿÐâß÷Ý¿ÿ£û_Iÿ¡Å¿ï»þ7HgKEs_ÚúOý-ÿ}Ûÿñº?µôŸú[þû·ÿãtÒÑ\×ö¾“ÿC‹ßvÿüní}'þ‡ÿ¾íÿøÝt´W5ý¯¤ÿÐâß÷Ý¿ÿ£û_Iÿ¡Å¿ï»þ7@-Íké?ô8·ý÷oÿÆèþ×ÒèqoûîßÿÐKEs_ÚúOý-ÿ}Ûÿñº?µôŸú[þû·ÿãtÒÑ\×ö¾“ÿC‹ßvÿüní}'þ‡ÿ¾íÿøÝt´W5ý¯¤ÿÐâß÷Ý¿ÿ£û_Iÿ¡Å¿ï»þ7@-Íké?ô8·ý÷oÿÆèþ×ÒèqoûîßÿÐKEs_ÚúOý-ÿ}Ûÿñº?µôŸú[þû·ÿãtÒÑ\×ö¾“ÿC‹ßvÿüní}'þ‡ÿ¾íÿøÝt´W5ý¯¤ÿÐâß÷Ý¿ÿ£û_Iÿ¡Å¿ï»þ7@-Íké?ô8·ý÷oÿÆèþ×ÒèqoûîßÿÐKEs_ÚúOý-ÿ}Ûÿñº?µôŸú[þû·ÿãtÒÑ\×ö¾“ÿC‹ßvÿüní}'þ‡ÿ¾íÿøÝt´W5ý¯¤ÿÐâß÷Ý¿ÿ£û_Iÿ¡Å¿ï»þ7@-Íké?ô8·ý÷oÿÆèþ×ÒèqoûîßÿÐKEs_ÚúOý-ÿ}Ûÿñº?µôŸú[þû·ÿãtÒÖgˆò|5ªpqö9{î7ùÿ"³µôŸú[×ïÛÿñºŠæûCºµ–Ú3E2Ý|Ëq• ‚3³Ðšb8ÏŠßò6úö_ý ¨ªÿ/­u­Å•ÄSÇöu£`Ã9n( ÿÙfotoxx-12.01.2/doc/images/stack-noise.jpg0000664000175000017500000002705511701011016016577 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿá 4http://ns.adobe.com/xap/1.0/ 155 314 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ›:"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑ´2MOy4Û7v¶‰™šÝ $ É'lé@`§M° ÝÙÓ'ô¥Ðÿä¦ÿפ_ú©¯-#¼ˆ+GCº9ï#zóÍCý¥Ð.Çÿ“ü)HÒ;tÛ´àâÝ8?•S]Fêæàéa’;ÄÏ›:T(Ç*?¼r8=;çŒë[[Eià íE÷É'¹'¹>´VM'GŠ6’M7OD@Y™­ÐRN*–ï Ôò†®ëßòÔëÖ_ýÕøCtùðÿÈÒñT$xfæUŠÞ-Y¢"DÄ÷è*ÓèúR£7öU‰ÀÏü{'øVhðþ™¥jšdö6ÞT;!o1›*CŽIô½7ú™?Ý?Ê„OØôŸúØÿß„ÿâhû•ÿ@{ûðŸüM.j9¢3ªÂ²4eÝržGÌ=+~H™s1ÿcÒ¿ècÿ~ÿ‰£ìzOýìïÂñ5ö,ßóý'æÿü],voe3+ÎòîEo˜ž9aÜŸjVƒØ/.¤¿dÒècÿ~ÿ‰£ìšOýìïÂñ5©oÛtˆ¡"`K6:zU8-ռ֙Ь_{iZ#» û˜qÿK?›§ú:sÿŽÒM(Çþü'ÿZlšÐFÌ©ÁïÒª¼*`–RÌYdÛõ¡(…ÙWìšOýìïÂñ4}“Jÿ =ýøOþ&¯ýŠ?>DÜä"ƒÆ’Ý" t_bÔ Â‹D/"Ù4¯úXÿß„ÿâhû.•ÿ@kûðŸüMH¥>Ò»3·pÆîµ«.ýòùá~Ï·‚qÖ†¢ºm˜æÏKP Ñl€=3nœÿã´ŸeÒ¿è cÿ~ÿ‰«’ªbÔLîQ—Ô|¿¥6kE‰’-ÄÊíÇ ùbe_²é_ô±ÿ¿ ÿÄÒµž–‡ ¢Ù)÷·Oþ&¯O`±Âì¥÷ É-Œ7Ò¢ÔÏúHÿpP”^Áy-ÊŸeÒ¿è cÿ~ÿ‰£ìºOý¬ïÂñ5~IM•¼"%]λ™ˆÍDˆ“#Ý\1UÝŒ êhå`»*ý›Jÿ 5ýøOþ&³i_ô±ÿ¿ ÿÄÕÕ²Oµylìc)¼×å´¶o,‰%ĹÙÓ­€^E³i?ô±ÿ¿ ÿÄÑöm'þ€Ö?÷á?øšµ´")^vpö|¸¥ûûVÏ3÷{7îÇ8¢ÐäTû6“ÿ@kûðŸüMÛJ'E±'þ¸'ÿVd¶ˆ¤rC#ynÛNþ¢5ºAÎêkm EKxRY'†(Ày û’ÙÈû¾ê×›«Ï•—þ?ÿ >—nlÒÞ0Ñygtr)ùÕ¿½žç×=rsSZƒj‚U8,‡†÷™ôªþn­ÿ>V_øÿüj7VÿŸ+/ü þ5@jÐÉs¤^Á î’XsŒ’¤Qý¾çþ¿÷Ü?ür7VÿŸ+/ü þ5G›«Ï•—þ?ÿ ¤{«»Ût눌Žò4xËuþ'«Õ£?ú‰?Ý?Ê©ùº·üùYàcÿñªF“Ue*llˆ#ý1ÿøÝ ™ 1VF¬­‚qœj_"ÿþÖ_ø'ÿ£È¾ÿ u—þÉÿÆëgR,Ë‘’}¼ÿϸÿ¿¿ýC,ÆiÄP.g8$ú{Ó¼‹ïúYàlŸün"ûþÖ_ø'ÿ©N ܦ¤É$¾•¦…‘F0¸£íÃΑü RAó!5‘}ÿ@ë/ü “ÿÑä_Ð:ËÿdÿãtùãØ\²-Ãp“O¤#€[$ý*¼wŠžj´bHÝ·`œS<‹ïúYàlŸün"ûþÖ_ø'ÿ£š!Ë"Sz;JðdñŒ9Å ¿>tŽñ†Y çÙï¿èeÿ²ñº>Ï}ÿ@ë/ü “ÿÑÏå‘•|àè›T…Í-Ìþ|Í&6ç¶sŠÙï¿èeÿ²ñºO³ßÐ:Ëÿdÿãtý¤EÈÇý±K@Z-Â!ŒnëúRIzÒ"ï\ȹ_==©¿g¾ÿ u—þÉÿÆèû=÷ý¬¿ð6Oþ7G<{–C§»ŽebmÔHÝ\7ô¦\Üý£a(”`zÒýžûþÖ_ø'ÿ£ì÷ßô²ÿÀÙ?øÝ qBåøï@…bš•WîäàŠõFõhÄÇ;3ŒgÙï¿èeÿ²ñº>Ï{ÿ@ë/ü “ÿÑÏòÈx¿o´4¬€‚›ƒŒ D½Ú°/>I'¯\Ó~Í{ÿ@ë/ü “ÿÑökßúYàlŸünŽxvY"¹‹ì“4Š­ºMÞYl‡ûAþÕçm\mÛ³¶=)¿f½ÿ u—þÉÿÆèû5ïýl¿ð6Oþ7G<–BËx®#E…R$9Ùž¿,—à¤i;67Mû5ïýl¿ð6Oþ7GÙ¯èeÿ²ñº9à.Y[üO3´A’Q†B­1®×È’‹j»n6qKökßúÙàlŸün³^ÿÐ6ËÿdÿãtsðrÈ“ûHãw’¾vݾf¥D·›a†=™òŸ~sÖ—ì׿ô ²ÿÀÙ?øÝ'Ùoèeÿ²ñº9áØ9dEq7;É»ŽqœÖ6Q¼?ô*£ö[ßúÙàlŸün§µH"XÙÛÿÒœÓVEF-;³F¼OUÿµçýwý×®Áywöôµ»¶‚?2'‘Z)ËýÒ ‚ /÷ÿJò-WþBןõÝÿô#Yz…§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤ÏZ·¤‹s†* *³À ü¨ßiƒÌòüäßýÝÃ4éœÇŽ:ª’?*åÛU¿ÿ„¡4•¶ÿEóLo ˆmòóÃק9®ƒ$é’dîÂ8÷ È Ù'{‰?%ÿ 6Iÿ?~Kþs¨\ƺæÙpmP4?(ù~LúsÏ­5o/#Ô£ûdòÃm!AÈÔÇ! pÍŒƒœú ¢M½’ÏÄŸ’ÿ…$ÿŸ‰?%ÿ çcÔµk›¹$¶ŠfŠ;“–?/`l’wg½hkRFÐÛÛKr·‚ÛÆŒHIßÀŠ/¥ÇÖÆ–É?çâOÉÂ’ÏÄŸ’ÿ…`[k3­¾yvá`ž'YFÐuäÄ+qP KV•¡·S?šmÅØcŒ¶Xœ) @ÀqÍtÛ$ÿŸ‰?%ÿ 6Iÿ?~Kþ‰ Æ¥u¨[ÛÍ;Z0µYeDDl¶ì’JŠMVàj´\Ik%ÏÛâApvŸ½G~(Ðl“þ~$ü—ü(Ù'üüIù/øW==ýûÁ5ôw~Tq݈H*)ÜHÎO^1I¥«\ÝÉ%´S4Qܘ¼°‘ù{`ä“»=èZÓ[»Í‘äùIåãqÅVµ$Û®Nì=À$ù@ÑXwZ…Ôk¯m—Ò0Ðü£åÌyôçŸZjÞ^G©ÅöÛ‰a¶ ‡dJc8fÆTç>‚€7¨®f=KWº¼’KX§h£º1ya#òöÁÉ-»w~˜­V[£¨ØZ[]5°œH]ÕÊxÕ¢¹›+íIVÊæ{Ï9e»kY"ò•G—p#œü¹ühRÕî¯$’Ö)Ú(îŒ^XHü½°rKnÝߦ(ZƒÐè§ž+hŒ³¸DÇÜàR¬±»º+«:crƒ’¹éŸJåµIo/ôËË–»ÙwB!l±®0²’zç½_–üÛÝjûähÂ4)E—ÜÊ0œžôt¸u7h®_ûWQNÔÕÞUžÙã¼Ñ pBå}kOO–ê-VâÂæäܪē$ŒŠ¬2H ívô  Z(¢€ (¢€ (¢€ (¢€ (¢€(Mÿ!û?úõŸÿCм‹Uÿµçýwý×®Íÿ!û?úõŸÿCм‹UÿµçýwýШZÈ;Ã?Hÿô™ëm”:•` ‘‚zÄ´ÿw†~‘ÿé3ÖåCö—g7—Ófî1éœgõ§N›­¤BªÓŠ’ŠÆ¼Óloe2\[L]—k.áèvõüiNŸd×+;A;:ʘTÐíéŸÂ¶(§qXÇ:}‘»ûWÙæY‹%DŠŽäâ)÷––·¥â‹G¬¢Daž¼® jÑEÂÆ;éö/`¶/k#[!!Gã=zÓ®ì¬ïY{yK Âº«£é•ÁÅkQEÂÆlp[Å2ÌÊ$XÄA¶9ùG8ªãKÓÅиÓ žf˜w®Þ™ü+jŠ.9[Í!îï̆Þ8£3,"w6<¦äã¯5¤tû#wö¯³Ì³ J‰1ÈÄVÅ'`±ª•€nÌp}É5#(u*À#ô´RÙþ]žtÞ_M›¸Ç¦qŸÖ¥(v¥¢€(ÞèÖÒ™n`,ì»X¬Œ›‡¡Áüh:E“\­ÃDÌêC(21PGC·8ÏáW¨  M¤Ùϵù%f,”‘”1ÈñbKhd¸ŠáÓ2ø#dñžµ-Pi¶‹qˆ¾Xå3(ÜxrIÏ_Ri­¤Ùϵù%f,”‘”1ÈñvŠÏŸDÓ®.ymòìÁ›lŒ¡ˆèHýjY´Ë9ÅÇ›o´í2䟛oO¦=ªÝ†PMÂ8&„BÅ&*dß+±m½9'ôùl–ûPHõ8„’¦˜¬w ääCK¥ÆuR=B'{xÝ%Š[€Å#‘pß/\úW?¤A¼úЮÉ.í\ÎA?¼;TäúœÕhRÏìZº’FmfV2®P1ôùl–ûPHõ8„’¦˜¬w ääCK¥ÆuR=B'{xÝ%Š[€Å#‘pß/\úW?¤A¼úЮÉ.í\ÎA?¼;TäúœÕhRÏìZº’FmfV2®P1A¾çÚ²uø ¹·Ó"dWîãqÁ\Í1­µ÷Ù!`‡T‡ËLð™$Ašëþ_æôÿ3­ª¶7«z'*…|™š#“Ô¯zäïšÓý Þý¬/—füî æ »ÙÛéS=¬1Û^ê [¸õ<,£†Ç˜ ¦ â…¯õéþ`ôþ½N¢šo$Çû©$Þá>A¾çÚ±ná'ÝÎ3Tà$ÚYm.m¿µÙ·ç>^:óŒçÔ-¯0z#¬¢¹Hv.º²ßÙ-rÂ.~Qqж?»œþÕWXš]bQu{om|.ó™y¥7|¡[v6‘Æ1ëBÖÀô:› Ñz³…<™š.Ns·½Z¬€mF#Ä‹y!*z€NAük^ŽÁÕ…Q@Q@&ÿýŸýzÏÿ¡Å^EªÿÈZóþ»¿þ„k×fÿýŸýzÏÿ¡Å^EªÿÈZóþ»¿þ„hÔ-?ä៤úLõ¶Ê®¥]U”õ 2 bZÈ;Ã?Hÿô™ër€!û§üúÁÿ~—ü*UUE ŠG(À´R¢Š)€QEQEQE†W°³ŽÂÎ;X‹2FŽO\ÕŠ(¦ ¢Š(¤eWR®ªÊz†–ЇìvŸóëýú_ð©UU*(U£RÑHŠ(¦EPEP|ÚJÏr$žîêHÄ‚A0òÁ# ÎíšÐ¢Š¯5œs^[Ý1`öá‚€x;†*±EQEQEQEQEBoùÙÿ׬ÿúUäZ¯ü…¯?ë»ÿèF½voùÙÿ׬ÿúUäZ¯ü…¯?ë»ÿèF€=BÓþAÞúGÿ¤Ï[[þy§ýò+ÓþAÞúGÿ¤Ï[”݉ÿ<ÓþùlOùæŸ÷ȧQ@ ØŸóÍ?ï‘FÄÿžiÿ|Šu݉ÿ<ÓþùlOùæŸ÷ȧQ@ ØŸóÍ?ï‘FÄÿžiÿ|Šu݉ÿ<ÓþùlOùæŸ÷ȧQ@ ØŸóÍ?ï‘FÄÿžiÿ|Šu݉ÿ<ÓþùlOùæŸ÷ȧQ@ ØŸóÍ?ï‘FÄÿžiÿ|Šu݉ÿ<ÓþùlOùæŸ÷ȧQ@ ØŸóÍ?ï‘FÄÿžiÿ|Šu݉ÿ<ÓþùlOùæŸ÷ȧTr–-hÛL·v3Ž þ”í‰ÿ<ÓþùlOùæŸ÷È¥ûÏÔÿøïÿGØÛþ~§ÿÇøšM‰ÿ<ÓþùlOùæŸ÷È¥ûÏÔÿøïÿGØÛþ~§ÿÇøšM‰ÿ<ÓþùlOùæŸ÷È¥ûvº›ò_ð¦@ìñøÜ¬T‘ßí‰ÿ<ÓþùlOùæŸ÷ȦÎÌ‘ü˜ÜÌÛ$ëOûwº›ò_ð ØŸóÍ?ï‘FÄÿžiÿ|Š_±·üýOÿŽÿñ4}¿çêüwÿ‰ ØŸóÍ?ï‘FÄÿžiÿ|Š_±·üýOÿŽÿñ4}¿çêüwÿ‰ ØŸóÍ?ï‘FÄÿžiÿ|Š_±·üýOÿŽÿñ5oŽáág/… Žps×ò  ²€5ë0ì³ð?Ž*ò-WþBןõÝÿô#^»7ü‡ìÿëÖý*ò-WþBןõÝÿô#@¡iÿ ï ý#ÿÒg­Êôÿw†~‘ÿé3ÖåQEQEQEQEQEQEQEQEQEQEÿÇÍ·ýt?úT•¿ëí¿ß?úR­íî u¥°±kTgó™¦FlüØÇ 1L‡_Xâ/¡)w¢??˜Ì2»:uóÓšmí­øÖVþÄ[8û?’VgeÇÍœðj¹Ñ.vý¯í6¢nÁb¤FH]¡1×=zÓ[]ÿÈõ÷™|ëöËesq$SÆÖÄ,°2"“Œqœç®hMzÛ˸kˆ®-^Ü+Ùªimnò$2‰Ä‘·r€0ÃÔÖƒÿÈAÿë’ÿ6¬È´¹b›Nšm-þÎÏæEBa»¯xEhƒ›ù?ë’ÿ6  ÓÈ~Ïþ½gÿÐâ¯"Õä-yÿ]ßÿB5ë³È~Ïþ½gÿÐâ¯"Õä-yÿ]ßÿB4êŸòðÏÒ?ý&zܬ;Oùxgéþ“=nPEPEPEPEPEPEPEPEPEPEPQO8FB7£nèxÇõ©h  û®¿çŒ÷ôÿ…î¿çŒ÷ôÿ…X¢÷ÝÏÿïéÿ 7ÝÏÿïéÿ ±EWÝuÿV_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêßóåeÿÿÆ«Ìá,×?è#'ýò¿áGü%šçýdÿ¾Wü(Ó¼Ý[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj¼ÇþÍsþ‚2ß+þÂY®ÐFOûå€=;ÍÕ¿çÊËÿÿQæêøÿKA×þ_ÿW˜ÿÂY®ÐFOûåÂøK5ÏúÉÿ|¯øP¦Ãôº¤w7QAG ˆs ,P÷EÀù¯Zò=WþBןõÝÿô#Wÿá,×?è#'ýò¿áY2ÈóJòÈw;±f8êOZÿÙfotoxx-12.01.2/doc/images/search_metadata.jpg0000664000175000017500000016255511701011016017471 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí0Photoshop 3.08BIMsharpen ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 658 735 1 2 2 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ’ß"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑô­6]ÁäÓlÙÞÚ"Y­Ð’JI$rjÙÒt€ê‡NÓÃ6p ºdã¯j]þ@ZwýzÅÿ -Kyf—‘…mÉ"ÑJœ4mê?ÎàÐغWýìð?šºNû¶iÚ{m88·CƒéÒ©¦¡supt½éÒdMÇ¥ÿÐÇþü'ÿNÍ­9ÌoØô¿úXÿß„ÿâhû—ÿ@kûðŸüM;4™£‘3ìz_ý¬ïÂñ4}Kÿ 5ýøOþ&—4fŽDÌO±éô±ÿ¿ ÿÄÑö=/þ€Ö?÷á?øš\Ñš9s1>Ç¥ÿÐÇþü'ÿGØô¿úXÿß„ÿâisFhäAÌÄû—ÿ@{ûðŸüMcÒÿècÿ~ÿ‰¥Í£‘3ìz_ýìïÂñ4}—Jÿ 5ýøOþ&—4™£‘3²iô±ÿ¿ ÿÄÑöM/þ€ö?÷á?øš3FhäAÌÃìš_ýìïÂñ4}“Kÿ =ýøOþ&ŒÑš9¹˜}“Kÿ =ýøOþ&²iô±ÿ¿ ÿÄÑš3G"fdÒÿècÿ~ÿ‰£ìš_ýìïÂñ4fŒÑȃ™‡Ù4¿úØÿß„ÿâhû&—ÿ@{ûðŸüM&h͈9˜¿dÒÿècÿ~ÿ‰£ìš_ýìïÂñ4™¨Žž÷³ÈâæH‚ªl –Éᇠ¡Æ+qó7±7Ù4¿úØÿß„ÿâhû&—ÿ@{ûðŸüMFš —¾—€pdÿâêm.4Q,®í¶%»±sSht ˨߲iô±ÿ¿ ÿÄÑöM/þ€ö?÷á?øš¼¶¶Î#*ò~÷%sŽõ¦Áe½]œ±ÚÅ0˜É?èï"ŸÙt¿úØÿß„ÿâi>Ë¥ÿÐÇþü'ÿZ+oé_,¡Aà ÀsQ[Áìß,Ås… ޽ï`»)ý—Kÿ =ýøOþ&œl´Å¶‹dèL Ïþ;VEª$“ù®Þ\X'häç¥Irªíjª®ÈWŒ›Z7 È¡öm/þ€ö?÷á?øš>Ë¥ÿÐÇþü'ÿWÞÕb’€g UñŸÒ™p°µæÄYwÃ…ô¡(¾vŠeÒÿècÿ~ÿ‰£ìº_ýìïÂñ5jîÙ`‰$]ã'_ý)!ŠlÓÌ_¶á1E£kŠò½ŠßeÒÿècÿ~ÿ‰£ìº_ýìïÂñ5zÞÉ%ˆ;o!É.8¦š-aŽ9fröü¸£ÝäSû.—ÿ@{ûðŸüMeÒÿècÿ~ÿ‰«cä¡݄ߜsŠF·‰–)!wÙ#í;‡ ÑhŠò*ý›Kÿ =ýøOþ&³iô±ÿ¿ ÿÄÖ„QÁúF›Ë †ÝŒtªW/4ˆ·õ;·c®{b„“{ ¶ºŒû.—ÿ@kûðŸüMeÒÿè cÿ~ÿ‰©-exå5fãsô}ö}¶Ý¥ rŸŒ3PÒOa&ßS3ìÚ_ý¬ïÂñ4}›Kÿ 5ýøOþ&´.LÉj²Í´Nò°ÇJl÷2‹6é&ö JÉôßr’Ù鮨MÉ þËJl´á×C²ã›uëé÷j֞ʱ\;QÊõJtgtJêò3¨ñÏNM6•í`MÚ÷)5®˜ŒUô[%#¨0 ÿÙi¿fÒÿè cÿ~ÿ‰­l./n ؤd/SÅ4Ø ¹T,ÛY q»ŽÞ”{½A¶Qû6—ÿ@kûðŸüMfÒÿè cÿ~ÿ‰§Ü*¤¥QdPG5j”èK“Bý›Kÿ 5ýøOþ&³iô±ÿ¿ ÿÄÒfŒÓä]…ÎÅû6—ÿ@kûðŸüMfÒÿè cÿ~ÿ‰¤Í&hä]ƒŽû6•ÿ@kûðŸüMfÒÿè cÿ~ÿ‰¦æŒÑÈ»;öm/þ€Ö?÷á?øš>Ï¥ÿÐÇþü'ÿMÍ£‘vv;ìú_ý¬ïÂñ4}ŸKÿ 5ýøOþ&›š3G"ììwÙô¿úXÿß„ÿâhû>—ÿ@kûðŸüM74™£‘vv?ìú_ý¬ïÂñ4}ŸKÿ 5ýøOþ&™š3G³]ƒŽû>—ÿ@kûðŸüMgÒÿè cÿ~ÿ‰¦æŒÑì×`çc¾Ï¥ÿÐÇþü'ÿGÙô¿úXÿß„ÿâi¹£4{5Ø9Øï³éô±ÿ¿ ÿÄÑäi_ô±ÿ¿ ÿÄÓsFiû5Ø9Øï#Jÿ 5ýøOþ&#Jÿ 5ýøOþ&›šLÑì×`çcþÏ¥ÿÐÇþü'ÿNŽ×KyQ?±ìFæ>Bñ5j[cþ“ûëüé8+l nåïì]+þv?ø ŸáX6Ó¬m|;4–öV°É½FèáE#æÀÍu+þ±þ‹ÿ³W?ãÏùæÿ®‰üÅsšºü€´ïúõ‹ÿ@Z‡Ä2]Å¥\½£ÊÃ#4¤ò€)<äô}ŒVWRÛèš*Ar¼ðÅó$(£—$­Ù};ÓuÉ5#¡ß‰-lÕ ¼™+tìG$,dûdSm­Ñ#]&é<›‹|½¼ññæÓE'ø¹ùÏ^r:vŸhò€º æT²•‡f¶};{õªZíå›[IyÓM ¨¿èÅL;d#r@PygÅs_nñ·ý,ïàÿã•»æj¿óécÿoÿƨó5_ùô±ÿÀ·ÿãT›¥Ýxž[ø“SÓía´ù·É‚Ãå8ÇÎ{ãµoÕ/3UÿŸKü þ5G™ªÿÏ¥þ¿ÿ¤Q½Õ¥ÝñuÄÉ4âHÞ7‹yh¿Äàç*{T¿nºÿ Eçý÷ÿ£ÌÕçÒÇÿßÿQæj¿óécÿoÿÆ©Œ“K‚K}&Ê †Ù"·Ž6 2=ê¥áÿJ“ðþB§ó5_ùô±ÿÀ·ÿãUŨHÅšÆÀ±ê~Û'ÿª‹QwdI6´+æ“5cì÷ßóáaÿ²ñº<‹ïùð°ÿÀÙ?øÝi팯š3Sýž÷þöø'ÿ£ì÷¿ô°ÿÀÙ?øÝÑ# Í©þÏ{ÿ@ûü “ÿÑö{ßúØàlŸünhƒ‘fŒÕ³ÞÿÏ…‡þÉÿÆèû=ïüøXàlŸünŸµAÈÊù£5cì÷¿óáaÿ²ñºO³ÞÿÐ>Ãÿdÿãt{TŒƒ4f§û=ïýì?ð6Oþ7GÙ¯èaÿ²ñº=ªFAš3V>Í{ÿ@ûü “ÿÑökßúØàlŸünjƒ‘•óFj³ÞÿÐ>Ãÿdÿãt}ž÷þöø'ÿ£Ú äd£5?Ùïèaÿ²ñº>Ï{ÿ@ûü “ÿÑíPr2 Òf¬ýš÷þöø'ÿ£ì׿ô°ÿÀÙ?øÝÕ#+fŒÕŸ³^ÿÐ>Ãÿdÿãt}š÷þöø'ÿ£Ú äelÑš³ökßúØàlŸün“ì÷¿ô°ÿÀÙ?øÝÕ#+椷¸ks!«‡ Õöãö>µ'Ùïècÿ²ÿñº>Ï{ÿ@ûü —ÿÔ¹ÆJÌj-]I•ËÁÏúßþÆ ³˜Úòï>^θ©>Ï{ÿ@ûü —ÿÒýž÷þöø'ÿ¤œWAµ&"^l|™òsü_{4‰x‘dˆI±}¤ãëNû=ïýì?ð6Oþ7Iö{ßúØÿàl¿ünŸ4{ –AÚÆòm…|·1îþ´©v¡J4Ç»rÄm?^ôŸf½ÿ }þËÿÆèû5ïýìð6_þ7G4{,…ûyó¤vYd2ýiN |èäH‚ˆÁP»³Å7ì׿ô±ÿÀÙøÝf¼ÿ u‡þËÿÆèæ`å—p’ðÑb„D·pû¹§áç¬Ë‡ÏÌw»Œ~ß³^Ð:Ãÿeÿãt}šóþÖø/ÿ£š=ƒ–BMt²B"Ž/-Cnûʦ ŒZ´z¶íÙéøTŸf¼ÿ u‡þËÿÆèû5çý¬?ð6_þ7G<{+;°!K ʪr¹lRÅq ÙK¹ƒI‘ìqQýšóþÖ?ø/ÿ¤û5çýìð6_þ7C”X(É öçûGœUq»{mô¤{ÍÆ ‘Ž3€ç'ëGÙ¯?ècÿ²ÿñº>Íyÿ@ûü —ÿÑÏÁÊÆ›¦hœí'4Û‰–gÜ‘ú–Ãg&¤û5çýìð6_þ7GÙ¯?ècÿ²ÿñº|ñì.YC,q±/‘HÆ c$·BG1/•HÃuüi~Íyÿ@ûü —ÿÑökÏúØÿàl¿ünŽxÞáÈÆOrfUEEŽ5ä"úÒ\Üyì„.ÀŠ æ¤û5çýìð6_þ7GÙ¯?ècÿ²ÿñºH®É"8®<¸fnï0c9Æ)R襺ƫÈpá³ý)ÿf¼ÿ }þËÿÆèû5çýìð6_þ7G<{$…7ù•ÛÉR’(„ýãëLÃæî«·n6‡=}sNû5çýìð6_þ7GÙ¯?ècÿ²ÿñº\Ñì>VGurndÞT( ´ çõ¨sV¾Ëyÿ@ûü —ÿÑö[ÏúØÿàl¿ün©TŠÑ Á²®hÍZû-çý¬ð6_þ7GÙo?ècÿ²ÿñº=ª³e\Ñšµö[ÏúØÿàl¿ün²ÞÐ>Çÿeÿãt{TÍ•sFj×Ùo?ècÿ²ÿñº>Ëyÿ@ûü —ÿÑíP{6UÍ«_e¼ÿ }þËÿÆèû-çýìð6_þ7GµAìÙW4f­}–óþö?ø/ÿ£ì·Ÿô±ÿÀÙøÝÕ³eLÑš·ö[ÏúØÿàl¿ün²ÞÐ>Çÿeÿãt{TÍ•3FjßÙo?èaÿ²ÿñº>Ëwÿ@ëü —ÿÓöÈ=›*fŒÕ¿²ÞÐ:Ãÿeÿãt}–óþÖø/ÿ£Û öl©š3VþËwÿ@ëü —ÿÑö[¿úXàl¿ünlƒÙ²¦hÍ[û%ßý¬?ð6_þ7GÙ.ÿèaÿ²ÿñº=²fÊy£5sì—ô°ÿÀÙøÝd»ÿ u‡þËÿÆèöÈ=›)楶?éPÿ×Eþu?Ù.ÿèaÿ²ÿñºrÛÞ£«­…€e9í²uÿ¿tU`TÙ¦¿}Ϩ_ë\ï?äW›þº'ó«æj¿óécÿoÿÆ« Å—wà餑7óŒeU÷ ¬¥NGËž‚¹Í /øððÏÑ?ôšJ³se¡cs  n˜Iò2Td¨ÇÒ«YLJ†~‰ÿ¤ÒV•¿ú£þûÿèf© ™7Z‹fKHž)Œ ·š­Õ‰ÎwÈ?_ZÔŠÖ‰á‰Ø lŸZš5º¤²\y{Cm̘ÀàzýiÞÁ¸Ï³Ûÿϼ_÷À£ìöÿóïýð*¯¢2´[ÚÅnûÌRù€îØÁy@ÎF «…™•Fp;rGô¢áb/³Ûÿϼ_÷À¤ SÄbEMìU‚Œ6“ý*Zcÿ¯·ÿ|ÿè @ÑE-ABQMlo[î³^ þ•ºÓUÈg´VS‚ \ƒ@‰©j!%»Åæ[Ètdc’>µ%QEšò$`uPNN2})j–²1cæã>S«àô#8?¡4–{Ø`%s½Áb‘»'žæŸmsÊ“¯ ¬0Ëõ‘åDÑÕ«k"ßu½© 7ñ?QøŸoÏß7NÕŸOŽTXS$žaw˜ƒ’ª~SéZªrjè‡Q'c«¢©éWí¨[¼­Œ¬›0v~PsœZ¹Y´Ó³);« ¢ŠZCŠZ((¢©êz„z|Í+qyåøzši6ì„ݵeÌŒã<úQ\Lz”ö÷ßiºgûìxÞ?»ŽÃÓÓ󮾯öëq4'Ù”õCèjçMÇVLf™=RÖe‰E-”RÒP&š("2Ï"Gõg`üM@š„Ž©í³;VU$ŸAÍR×o­ZÉíÒæ#8–?Ý î$SÓ­s¶³•¾„Í)òÖH˜–n/5´)Þ72”ììw4TV÷v×{¾ÍqÛ~÷–á±õÅKYlhQKHbQKI@Vv­ª>œð¢@²dÛŒcØúÕ$Û²i+³G#p\Œ‘(®J÷T–îæ Â‹w€6ÖG,I;}TqÇãšÜÒµT¾_*LGp£•z¯øvªtä•Ù*i»#FŠ)k2Ä¢–ŠJ)i( €OÞ©jÚƒiðFéÉ&ÌÚÊNsƒéX:†­%ú¦„Å'˜%$çi(õ­#MËU±š‰ÕÔv÷ÜÆ^ÞhæLãtngÓŠÌÒuu‹{‚||­ÐIþÛòög„ÿäßõÑôRRpqß Ô“jÆÕRÔ%´PQYÚÀœF’Äî±!%ü¶ CÇaÎ~¾ÕXêwfò±‰zyümÇ®?½úwéÅ6¨¬ýOä¼’;˜œƒ‘‰'ÔóØñ§½hP0¢–ŠJ)h ¢–Š+ñ'ü‰W?õù/þ”=vÇø“þD«Ÿúü—ÿJ¶_ñá២é4•£ú¶ÿ}ÿô#YÖ_ñá២é4•¡ú¶ÿ}ÿô#T„ɪ×ÍóГ2°ÛŒŒ*1Ræ«Kg’y…¥GÆ7G#!#ð4ÚäÒÄb–I6íer eÁ\²¢’[n$“Õ}M-ÄÜFc”§Ðâ¡þ΋þ{ÝÿàTŸã@‚U1&w1i&Œ’ØÉ;v²Õª¯Œ1È²î•Ø}Ó$ÌøúdÕŠ)i( aL¹….-ä†OºêTÔ””€Ûà›ì÷#lŸÂÝœzð¬½vâXHUrñ4-ŽùÆ3þ{×]um Ü&)Ð:ÌP{ç5O j1„‚îT9C1eaõÀ9¥bl\𲩎æpêÌα€H ?Ěܬ øhh%ij™®¥]´€dýOk~˜Â–’Š-%P9ae ýƧÜb\£Ž¨|Éy‘sa=µòZ¾7HáQòB¶HÏãÈí]}®› ¬³ÉÈÍ;nmÄaycÆ«´ùl`›g˜»¶8uÏbA­ÕW¦ÆNÖ»˜6ž½†î ZKr‘ÈŽÀ;€ÀñòûWMHª¥-e)¹nTb£°RÒQRX´RQ@ IEÎkš&Ð×Vjy%ž!ëܯøV^Ÿ¥\j04ÐIPûù$àÊ}k¶d Ö ŠÆKùK³{ï`;œŸÒ¶f£c'M7r¾‰c-…¤‘NÈÎÒoY$cjŽàzV… ¡F›m»³D¬¬‚–’–¤aIEVV¹am%•ÝãÆÆâ8« Xc‘À8ëZµðGqÇ(ÊH¥Xg¨<iÙÜ–®¬p7-‚ÄpvœWsk¦ÙÙHímFa†ýã6GГUO‡ôÃ÷­ÉúÈÿãZ`ÍkV¢•’"åÜ)i(¬ME¢’ŠZJ(  oL7*n-À*9\ãÍŸ_CøW9ei6¡yåC•?ÆÌ0#óþÜ2+õÍG¤Q³2(RÇ,@Æãï[F«Œlg*jNágkºÃ¯$ž¬}MMB€£ŠÉ»êËJÁKIE!‹IEVN½¦O¨5»@ñ¯–7˜Åzíé€}+Z†PÚ¤ÚwD´š³8mCNŸO’åds.v˜±ÈÇ­oèš0µ st7OÕW9òýÏ¿ò­&±çI™s$yÚOðçþU:¨N•¤ª¹FÄFš‹¸´´”V&¢ÑIE-%Pv¹a>£mp4jÉ s½ˆÚð>µÌê:UÆ›I<‘ï°ynI÷Ò»z†kHghÚDÜcm˞͂3úÖ°¨ã§C9AKSDÑ@U¹¼a†HOcØ·øU ÿÈ%¿ë¢ÿ褭qŽæ¡Ól"Ó­Œ»²“œÈFzØÀR”ܯq¨òµbÍ-%-fXQIK@ú­ãÛ*G ògæ=§ëÏùÅcù$Y <¿ô|mûÇ8õǧ¿ãÒºI †pX–@@ašp6í 1é@ŠZ]ë\«$¤cæàýxÿ9«ÕÐÀ†$Lœ£%´”´ (¢Š(¢Š+ñ'ü‰W?õù/þ”=vÇø“þD«Ÿúü—ÿJ¶_ñá២é4•bæàÚé·W ¡ŒBg÷ÁcUì¿ãÃÃ?DÿÒi*]B7—G¾Š%,î“*¨êI-Å>š]I,5 {袞$òÕ¤Xä T‘ÐúRC¨Dtøîîd·_©ó•s¿ÐÖUŒRO}¦É”Ö©inË3É ‹y*AœçŸN* ;{‹Km{›)厤Gb,Ñ»•¶u-û Çÿ@jX–Xà‰¥šDŽ5gvîMAý£cöo´ý²ßÈ'o›æ®ÜúnÎ*-f(§ÓÙ&[‚¡•‡Ùл‚@ÁÎéƒYJº…äs][91jA·y FùÙ‡¯zÊfÌz¦Ÿ,‰WÖÎò}ÅY”–ú óOkëD¹Íu Ü‘9ú.s\ýÖ"éÚ¸†Í¼Ã|’Ŷ.Oú²JñÓ;º{ÓuåÔ...á1Ý%ìË °hؤ³>ÒA=ÇJ}…ܽy­Onº¡H£?c–LçæßŒçó­iï-m§X&¹†9_Vo =kžÕ-n™õÕŽÖg3<DU n௎´Ëë&–ÿPûRjÞø!Sol²»@ÚÙBÈAÉí×=hѵõ¢\‹fº„\7HŒŠð\榬½2ÝãÕµI'ØíI~ö#Á ÷ü+RÝ^ÚÙ7w0Àá|×çD—¶°Û ‰n!ŽŒHÎôç¥dëS-¾¿¥HðK0 ?ËeÛîŽvŽMU†;ëM44VóÁׯ!Ž8CÉDps‚Xg8ÏJC7ÞúÍ-–åî XîÊdP§þœRI¨ØÅsIyl‘Kþ­ÚU ÿCœç,ìî>Ëf¦ÞvUÕšaæC´ˆùùŠàmö¬êÖ’®µö–K³m%¿’ ¬ 6ߘ’ •läÜÓµq¨YZ²­Íܳ ¨’ERG¶O5ºÅœŸØ®%HXÄ%W‘ÕUòÄ2y÷CÓµLuM=`YÍý¨…›jÈf\èqšÄ×lî'¸Ô vòȯº®ØÉ D¤œc®5s^M—ÜÛGuö¨ÑÄ~M±š6Î2¬1Æp9ÈúÑæ.¥©5‹8u/±M4q1…eG‘ÕUòHry´nì7µÎ­¯­ä[5Ô"áºDdPÿ‚ç4ѨY™dˆ]@eˆ‘‹¹êHÏRÆÝ×XÖ%hŠ,ŽV^ØÖV§”k8/üOlXœÀ‚A>`LÀ÷lúÒÒ ˜‡ÆDÿê¾aûÎ3òúñÏš”WÞ[Ët±ˆÞE sÓŒæ²4K˜ï„w12æÆÐÛ³õ›Žr=p€©5Vé•õ ~Óì]I8ˆ H·(cn‹Ï98£Í v:;‹ÛKY;›¨!wû«$Фý<ÒÝ^[Y¨k«˜`V8W ükœÕ¢ÔE±³›í.‚ÅQZÞØKæË‚1ÚJŽžzÔÅe²½†êêÆâáZÁ!8Œ¦7° r3Ç>ÔÛ—P²‚(å–îÞ8åÿVï"…¡'š³ž9¡ÅÙZL¶Ú}Ì‹vÖòiékhbI ©V G v溽:¶Ó­àC&ÈãUQ ÃŽ2=iØ'vTBîÁUFI' ŠÚúÒïwÙn¡ŸgÞòäWÛõÁ¨5Ïùßÿ×¼Ÿú ¬5^òûKž 9àKkb&–HŒaÁ@ƒü\óÇR]F͸u +‚â »yLc/²Eb£ßŠHõcEyo$lâ0Ë"Xô\篵`>æOCj2NKÅ´+%pGR;´ôÓ~Ûi, ¨ §Xö˜]äÀ ¹Áã4ÀèVhÚW‰dS*Y ÊBGlàÔPêWÄvò˜Æ\$ŠÅG¾SDŽg‚æöæ†{Ù ˜œa£@6ª‘øøÖtZ}ÁðU½°µo8i a±œÜÊsê3×Ö„µ6ÓP²’Ý®#¼·háäYªýNp*c<"WˆÊ‚DM컆BúãÓÞ°’ÏûRúöE´–ÒÖk?³°–/-¤rx!O÷G~+5¬õi¢mo*Ý]§Ø%]§äM y‡ÛpcŸB) ì#‘%$ÕÑÀee9 BqI4Ñ[ÄÒÍ*EŒ³»êM:8ÒÖ(Æ5£ÐYž%†IôY£Š6‘ÙãÂ"–'ç\ð)õÐH½ å­Ì-5½Ì2Ä¿yÑÃ(ú‘LMFÆH„ÑÞ[´[‚Y®ãÀÏ_jÃÖôÙî/55µ·m’Á;0«’Àd`¶ÞÇÚƒl’YßÊ–º…Ì×HîmÄ@œ¤íEéž[°ïH GU¶°¶šfpþC"ÊŠÃrn }:çš±Õ¼ðáž) ̈à¯yW6l/"Ð/´ö†Yîa&3'íCr¶A=XŒ{ZØ¿”ßh7¦('V’c’&W'iè¤fŽƒÜ±£c,/4w¶ï ~D•J§ÔçŠrßZðyȈX¸‘{°;·qž§Ò˜Ž€ÝÛ‹_´›ˆ…¹¼ÝÃf=wt¤‚òÖæ–Þæ£_¼èá”}H¬¯Ê%ðIJùR€Æ2#t*ßë§¥B>Õ5þ¡¨iÖ2A›C¤ñÌÒç í8Î÷¤4mÚÞZÞ+5­Ì3ªœ1ÃõÅ$7öw2˜ »‚YWª$ŠÌ> ×5¥åÌÚˆ^ŸOò„—6þAó2p£ ~¼ýi²½ž ;;)¬åtñªË B~{ZlGQo{kvζ×0ÌPá„n©÷ÇJš°4;UqJé¨G<0ŠOn‘ÆÆT@‘Ç&·è°&RûsmKfÁQÚ‰‹“ÎwùqSA}iuÉouÈŸ}£‘H_©ŠÊ¿[ص››‹[w•žÀ¤M³)½X¬{uïÖ¨Û[¼÷7¯u£-¼¶%2ZyN[wÝPdàœuúÒÜÚºÖì Ó佊x®b•XÃ"¶ÒHœñÖ­Åuo5¹¸†â) ÌŠá—Ž¼Ž+’=BçF¾ƒÉ–XâxšÝž*IB°, d€:àg5©©\-ׇ/åXfˆ%&Œ£}ÓØóFÈö.Û_Z^·PO³ïyr+íúàÒ[ßZ];%µÔ:}åŽEb> + ÀIyy¦\ZÙM¶¶a,’Ååù™@Aþ.yãŽ*-5/æÕìf¸K±2E(œÉl#Ž2GX/Ì3îzSΉoìÚçìËw¸Îß+Ì]ÿ÷ÎsK嬷oÌ/:}èÕÁeúŽ¢¹{PðO{)­®!¸"Y"Ûcåƒôlõ©´K–Pݦ —ŒÌ3w`äù2AÏvÏ­:ŠŽââ X¼Û‰£†?ï;…_ÌÔ•‘«#ǪXÞµ¬—Vð¬–(÷²3ckíêzÇLÒbGÏÕÚÚ3Ûý•gY³»,G¦8«6÷¶·Léms ̇#pÅ~¸éXw¶÷7w×-oo4Ku¦˜¢vŒ GÜNû½{ÒÚB×…„éÓÙÅi ¤ÛâÙ¸ þÿ<äqÅ>‚êm[ÞÚ\»¥½Ô:}åŽEb¿P¶÷¶·lëms ÅFኟ|t®~ÒÞñìo4ë(î×쌰És†DcÀL7|qêj}ÕEÔS:jÏ "“Û¤hÆT@‘Ç&„ý-%-!…Q@Q@qþ$ÿ‘*çþ¿%ÿÒ‡®Â¸ÿÈ•sÿ_’ÿéCÐ#VËþ<<3ôOý&’¯|ÑFŽO¼Ì ¡`A$öúÕ<?Ã@çî§|ˬ•¡5Í•´ž\÷QÄøÝ¶Iöœzàšiظžgý3›þü·øU{»k{ÍŸh‚á¶FÑ*ÍqR>©¤ÆåRµFU®€#õ©ûOu ·Ð2ž„\dÖŸ2ŠriöOP›YÖ(rcÆzýÜøÕˆ+xRmäŽ4U¿¥J.lK¨ÿï÷ÿ^ž%¶=.ÿÛoþ½È,GæÓ9¿ïË…,a¤ž2¦X–R½ˆïõ§ù–ÿóÜßÓþ4y¶ßóð¿÷ûÿ¯G0XžŠ¯çZÏÂßïþ½!¹²n£öÛÿ¯RQfŠ«ö»ÿ/qßÿþ½!½ÓÇ[Øïÿÿ^€-ÑTÍþœ:ßÁÿüi?´tÁ×P·ÿÀ‘þ4vŠ¢uM(uÔ­‡ý¼ñ¦ÿkhÿôµÿÀ¡ÿÅP¹-¡’æ+‡LÍeFÉùw :•-gkèÿô´ÿÀ±ÿÅRÿkhÿôµÿÀµÿâ¨BŠÏþ×Ñÿè)kÿkÿÅQý¯£ÿÐR×ÿ×ÿŠ  *œWÚtà˜oa/R—±ùxžÐô¸Oûÿÿ×  4Uo>Ïþ~Sþÿõè[›'p‰u1è¢l“úÐ"Íß-Úÿ¾ÏøÑå¯û_÷Ùÿ:¢’Ú.b¸tÌÑTlŸ—pÁã¡éOò×ý¯ûìÿZÿµÿ}Ÿñ T7v^Åå\+2åvCŸªjO-Úÿ¾ÏøÑå¯û_÷ÙÿŽÎÎÞÊ&Ö!d’$’{’y'ëSS|µÿkþû?ãG–¿íßgüiˆuGom ªºÁÀîÒ7$åSÍ;Ë_ö¿ï³þ4ykþ×ýöÆÇQMò×ý¯ûìÿZÿµÿ}Ÿñ TQÛCÓM{dœƒ+dØN=)þZÿµÿ}Ÿñ£Ë_ö¿ï³þ4ê©y¥Ùß0k˜™Îݸº‚=RüjÏ–¿íßgühò×ý¯ûìÿ**FŠˆª¨ *ªŒ@)i¾Zÿµÿ}Ÿñ£Ë_ö¿ï³þ4ÄCÄ «º9£®qF ,h±F±¢íTPª3œÀ¤ò×ý¯ûìÿZÿµÿ}Ÿñ¤1ÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgühÔS|µÿkþû?ãG–¿íßgüh—VÐÞ@a¸O22A+’3ƒ‘ÓÜTÇ“šg–¿íßgühò×ý¯ûìÿ,ˆ²FѸʰ óŽ U´Ó,ì]¤·‡2í.îîÅ}bH¬ùkþ×ýöÆ-Úÿ¾ÏøÐ¨¦ùkþ×ýöÆ-Úÿ¾ÏøÐ¨¦ùkþ×ýöÆ-Úÿ¾ÏøÐ©³EÄ «º9£®qF Zÿµÿ}Ÿñ£Ë_ö¿ï³þ4±¢ÅÇíTPª3œÀ¥¦ùkþ×ýöÆ-Úÿ¾ÏøÓVÛI°µ¸À|Õ+¼®ås×hb@ü*å7Ë_ö¿ï³þ4ykþ×ýöÆÇQMò×ý¯ûìÿZÿµÿ}Ÿñ QMò×ý¯ûìÿZÿµÿ}Ÿñ QMò×ý¯ûìÿZÿµÿ}Ÿñ RÓ<µÿkþû?ãG–¿íßgühôS<µÿkþû?ãG–¿íßgühôS<µÿkþû?ãPG O,ÃÏ–5‚ ’NÐI9Ϩ  UÇø“þD«Ÿúü—ÿJºF·m„Çw;œne##±À®[]“Îð ’c®¤lg¦gzmYLJ†~‰ÿ¤ÒV7‹?ä9ÿn‘ÿèo[6_ñá២é4•‹âÞ5³ÿ^iÿ¡½a£–Öþ&³ÿ¼?§é“H²ÀgŒŸûæ“ZãV¸ëÿ Š}‹˜­YÔŒ—ñRÕÐu5àWcµA,z`Ö¤²BÀH®éš­o*3íãpàóÈ=éÖwdº†9Nz{þt”<ÆÙ½ Ð “¾¦T‹pR\1è2)51pz×=<Ò5ëˆ`9CØ=½óÅ4˜´:õ¼R ‚ÿ˜ª—z×’ÀǰäsPÁ;µ‚È Ã§¡ª3D›¤O2Lp7p)Ù½ƒCbÃW7 è­5”2ƒÏ5ÍÁ2ù€ÄžL™'ŽÍmC3I`Ùü(I­ÄZ.™ÁïíL/2@Çû¢±µ­TØÛ3 r0£½>ÃRkÛHåFS¸ à 0-]Ëù0£×äÖ}å·— J°£ä‘Ur:Ÿj‡PvGò݆ޤåP\ê+=¸‡ä :ª@’¾àWŽîÔ1ûE°QØùyÞ¬J–²tlë‘æªA· ä„‹ M2[6ÄÍåçæóõ¥$­¡Ht‚Мâÿ¾*¼‘@zGýð*'Œ;Å3%z9Ǿ fîRHP|¬¬_ n¡3N¸™áŒÈ]°‘ç¯Ö£‹ ‘×Ò¡¿I(·V^>„ñœÔÇâ)­ å–g2ÉóïÔðÐoí˜rIçSþÚÕ5´š=£nFsEkh–ïo©A$€&ùPO$î«[¦›¹š²;ÊÄÔ%¸yn$·•G=µº Ä)o1KgÌ£ó·Q%´(…JT¿™ƒóe³œóïùUˆË…é”Zn·ý© 3Ûf<¿3;wg8ã©‘êw×)n û*3Å3»:³©1¸_—prÏ]immæã–ÞÛs+ÆcÓ$§ùT‚R"@Q .|ªq=jÁ—Z¼Š‘£‰Úx¢–  /{ÃÀ67~_íY–i mU%ŽT›j%¼¦7”‘ò€É“ÓwlÖ™¶·(PÁC—´ ÆÏîý=ª#¦ØÆÐ§pŒÀ»AõÆ1šb)Cö´]6Òy˜ÎŠÓNwdáG HëË(>¸5ZKT’Þ'Ýeº[/µ¯îŸÊýîs¸sÆ= lÃimnÄÁqüž^ÔP¹'$Ó–Þ À å€pŸÝÜ=©1£" Fy¦)Èšâä*´¡PúdsÔ`ëõ[ÝNîÔÜá­ˆ³…%203džæù~ï}ÜœV£Z[m»ºóئ·­–£¨]\–éöS$‰“´*H;É9#¦ÑŒõâ™öûǰ¹ŠáÄwÄ$kÂSËiÕ9ÜÁ†{Œt5«ö+O´²Áç°Á—Ë]ç·\f™gѬ0…0 ‚ uëÞÊ2 :¼1YOpe•®¦fDLciRvînÜg©ªÖÓÍö‹iÄò¼óÜÜG$FBWj‡À Ðcjò9çÞ¶NŸd×?i6væ|†óLJ_#¡ÝŒÓÖÞ¦H"Yœa¤°÷=hè#œK© °Y–îrÓéq3n2mÃ*“…åœ``qíRA-Õ´7öÆFYÙaX—í 0F“*vç$òGAŽ3šßŽÚÞ#!ŠÞ(̧sìŒÿ_ZŽ; 8•X¢T}áb@€61’^½é“,’%Ô®·y°^ÃofS´ÆÁ3•ÎÌryãÚ–ÚöY|D‚_µÆ’G2ˆ^TYpÇ#Ÿ˜ç üì˜!kp`ˆÎ£R€¸€õ§˜ÐȲRàŽ@8Èßò¡“ª:Ⳛ¶É†M“0HÔ]”¤väô“™m5´Î­$N‘E¶î@c%BàÇ÷HÎO¯9Å^}/N©“O´rªw@¤€:Ǥv«tn–Úp寖»ý>ö3@2¼Ò8×m#ÜÛ ¼Ä¨< x$~'óªÓj³Gª$J¡íÂÛ±ØÀ¼_'¨èŸhÜXÚ]íûU¬íÎ<Ø•öç®28¤[5u‘líÄŠV.W0qÛ *XÞ]=ëÛÞmG!Ú8ÄGæ@ØÜq Á`jõÌö÷:jÍ)–êEx1ܱ°ýæÓÛnÖ#Óp­¸m-­ÝÞ hbi>ûGRßR:ÓÌQ´‹)LˆWÚ (=p{fÌ85@éÒ_ÍmƒìÆhˆ*¦ˆo_þå¹,æU²-™ «3äç†üAükbÞÚ XÌvÐE’‘FgסºÓ­®m~ÎPF› `Ī ¡ê£ŽSƒêw)wqó[˜ ºŠ+iópœç>­éÎ)mõ+©ní5¸†æyb…;Ð nIÎ Êú g½_OµŽîK¯%w}ûÙAe%BáN2£‹K·QkâKÍ’FQ Œg* ž8äš]¥¤¥¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š((¥¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ª!kˆ¯bY¤„´ o€Ø™Á=ýêÍg¼0Éu;<1¹Ü9eøE0i¦[éÎÿcß,9ƒqeמA=ýk—Õ¿äúøýÕÓ}–Ûþ}¡ÿ¿b¹­kþIûúyýô„mÙLJ†~‰ÿ¤ÒV/‹ÿä6ÿõä¿úÖÕ—üxxgèŸúM%bø¬g^aÿN+ÿ¡= hæ5àÃV™€8œþ“No: `ä· £·¥©F¬÷„ä Ä…ÚÞá%NAÆi!ò¶®Ki$Ž„7S’3ÓÞ¬ØJZDï$ðWùÔ{¤YZ;ãàsÖ´-#EÔ?p»ß—½HüèMX›3©·}ÑöÆx¬)­!ûDѼ*ÑÊåØó’Ei¤Ë €9Ç­.•‡´ÝÄI'?ð#BchšÊ!ùˆLõ?^µŠ—œ°RNksHM5rNwÈ:ÿ¶Õ Ú ‘ALãƒõ¦#1¼Èe ÌÓÁ½¿uVŸ¼·®(8Æ:ŠÉKuIX°Y0088ϵlÙÇåÀ£ò OZc½Û+!A›—©ô8þµ6‡{‚±2¬Y…ì}+ZöÕ&ŠV@<ÀäÕk›Y fC»O 4°µÙöËöc„FPÂCÈúW;Í$¥Ú7dn–3…ú×Y¯XµÕ¸xT±G¥sŸkÿEXÕIX26Ï—iíÅ4&K¢Ü´Þs<„þ94뻨·ϵûØÈÍdL$Rcoð²õúÔ·k"¥·œ ³ì»TÚ쮆}ôò …î:Kw‘ ï‚9ŸZ½%»~öO/1ÎàÜOJÏ·F`I‡Zl”^ û²Ãµ$ñ£´SM0@îŽXœöŒÛcã¿Ò©É'9ô¬³¹Ð•Ñxß6ÛÆTôÞÜ“øTÚY‘õ{FbXùñäŸ÷…U‚&qòFÇðÀ­-6?/S´ó$P|äÂŽÿ0©÷›ÐwIÅGqs ¬fK™ã†<༎~f¤ªwöÓK-¬öþ[Io!m’1U9R½@8#9é]&­dÖé4·@²3ªyÒ*ï*ÅN9ç¥?ûBÔ^½™™uPåIsÓò&²›F¾|vË$;vÌi"@]ÉSòŒ°‘´àT²é72A4l~]Å’[Hû›r²†ä |Àîõ©mwmv…ín"à´NéÅ<*¦;i®œmˆ®~¿1õªö¤S™mmÚY<¼‡¹–`áNy.8ÆIf¬jÑÞÏl#±hг1žB‡g}¤+`û㊈ÿ¶!xa’&¦FF€nP¼19 pxëôÍ$ºÍ²(uI¥„B³¼¨ØãnŒÙ ö=2x5±ºìÒZEmÀÐŒ±Uˆ †Û’FÑÔ äóPI¢Î–íkm$F­RÖWrC(\Ê9ÈcÁ#·4À¹&­w† åD© ”Ú€*:î=G ÍX»»Â0#’Y%}‰xÜÍ‚{:y=«:]*áµ_´d‘n >th f5Æq÷¬Mc90Ío²M í*¦HW džÏCȥиÖ-íô¿·ºHS# <ÍÃ;—ê0sÏcWer³ª;2@Ü}‡½cÜh2M¦´bí’äÅ0ùvùe¥%ˆ;”œsŒŒUö‚xƒ¼+ Î ¤ÒðÌÃ<6Õû½øü¨#¬"Ã;=­ÂK¢<'fã¼€¸!¶óŸZ½ ¼‘†’ cüT°ÿ¾I­f[X\¦Ÿ4WV¶wHÁäó%gYOrÙåÆJµ¥Y½•³Æâ5ß)qyÙ8ùT8ã=^”ÀšKËh§Ky.aIŸîÆ\o êj¼ZÎ,/0¼Q$(KÈ«†^ø8õ¨î,î[SK‹b‚PJâV˪œ•1í ðNAö¨† ±y)$~ZÜI/Ëpñ4Ë«•ÁaМãµ!š2^ÚÅåù—P ”f2ÎñÇ#רüè¶¼¶»m®aœ!ÃyrÚ}ñÒ³ôý*{d´˜¤ò š22Ü–e ‚Fqƒýh³°»ŽÚHfXÆ!·yZTiçæ*¦=:óLEë»±l#\’É+ìHãÆæ8'Œ:y=©Ö—)wl³Æ+ °ÁR>à‚*-BÚY¥¶žßa–ÞMádbªà©R ã†ëƒÒ§ZµšÅ#+ÈYäf^…™‹=¹Å!–h¢–€ŠZ((¥¢€ŠZ((¥¢€ŠZ((¥¢€ŠZ()h¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€©øøŸýáÿ Š½TOü|OþðÿÐE:¹]kþIûÿ×Ëÿè÷®®¹MkþIûÿ×Ëÿè÷  »/øððÏÑ?ôšJÆñOüŒXõ±úVÍ—üxxgèŸúM%cø§þFE¶Kÿ¡5'°!ÖÖVÒÏÓH¿2h˜¼c§5®h²Çxïgò* ò?[–ÖQ_ZEç eP¤n u_z–M?È-\®YUË÷¨Ô¤ìb¢>Ö7R¤ÛaÐö©„¿f»,í´4L«ž„äb¥p«0r7L§hÇ^zð*=BE[/´BÊãî‘éëN+]DÙR Vò—s&ùKçí]‹zyRìÜ~bP|¼û×9fÖÓÄþ`VaÎåÚ?•ié[¤é,dº€7d}jÚ"çGÝ­¤^ZaFãǹ9?©¦ÜÜGu!Ž'ü–qÇ¿JËš3=Ù„mÎ `°££*œ*±ÁQ ãŽ3BLw/A†ê(]•›k1ØcüEh ì+êøÛ,l7¤R1Ço¥j‚^ ž2½(=”ͽVM»¤c޼`RCo%½Ô%ä,‰»“ÐdQq,‘Ê j®Ì0yóÅi\íx)èCtõÍ!ܹsp‘[ù¬FÊçm£·»xÙâRZY6ȧ¿ʧñþ]”˜ËÇ·þº«¥Bë}2©›¶£4„ØË˜­4¿´Ì4¸NXä€{ÖLŠú¤Ëö‚ÊTñòàÖî¹j^eFòÙ\ðN¦«½ºÁqNÌÎÖŸ+µÅ~…kÈÐF"9*øS“Y±ÂˆJ‡÷«º®æx¸FÜH'èk+vÉT++džGz—v‹V¹3Æ$—’Bޏ¤¤#1[óýé94àØ¸aþÁ?¥LÒa¼¶ã•ûµœR½Ú*M•Œ÷¯Í!Ç¢ñV4ˆ€Õ¬Øä0¸¯ûÂ©Ë yh¤°<óÐV®žjvT ³FXîÞõÑÏ–†gwU/nž·ŠÒI§rªö(À,I88àz·PÜÚÃtª³¡;[r°rŒ§Ô0 ާ¥@Ìûí]¬$U’|*´ÁØ 'á1v+œSäÕ&K›…6ËäAr–í'™óápBã±qÞ¦—I±œbhYþUVgùÀänçæÆzœšDÒmÅì÷rî’If€K…U@Êç ‚¹Ž3LE;}Jëm»Ý**½ÜÑf&ÎU<Π¯û¡Éý)·%KWšk5LÚ¸B͸2.8n>SÈõõ«é§ZÇ7š‘Þa”#A…ÎwñÞ˜šE„qK[ü’¡‘Èzªäü£Øbú‰ ôí,ðÍhDÑÛlR 9!y9Οw-³ÛG)+ÜHcù¤ØåfÉ8?Ý©d´ä‘Ýù*ì ÚIQÁõ&,qI4F@ ‘’éó`ƒ‚¤ã¿ :b)Zê†vZ…£•ÏÏœ4nÇ#'¯J¦uK‰vÊŒbIÉÂ`6ß2BgñÇøV“i–lª¦…,FÙYOÎrà ä‚{t¤û‚4pìEr±¬h\ä¬GràgœŸç@i)©,r3„ufŒípJœgÓ‚)Ô†QK@ E´”RÑ@ E-QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEUÿÿ¼?ôWª‰ÿ‰ÿÞú ×)­É?úùýõÕ×)­É?úùýô·eÿú'þ“IXÞ(ÿ‘ž/{Aÿ¡=lÙLJ†~‰ÿ¤ÒV'ŠÎßBéÔèOIìt2È–æ5rŇ«4ñ±Â.@<Y2J˧Úíb2è8ïÁ«ˆÒK"ª3pÊNlÖOÈ´V¹7ê.! ¿f~N§ž•Œ£™1V걫7Œ«p³àä:âd¥ãc»î¶NÓÔâ´OBm©LY=¼ªÈŠNXv«öÖW.FA:)—Sya]›Ú£$Ó4Éüë»…1´g*ÛX`ôÅv +š’'Ÿpmù@'>‡?áZ¶m‰YX‚ÁA ~?áXËÿIÀè"OæjÝ­ÎÍFãqãÊCúµ>n‚°ûènø:åˆ ÀöÏÒºäQŽœóXÓÞ‰-gJ7*pyQ\ôžz¤à1 ˆ¯‚ß|OV#­” ˆ1¹Ó£nŒá€ç¡¥•|ÿ1ܰT ·Ë×ǯ5“¤»ÛF<Ç; »NÿÖ´HÞßÀPCd}sJýÃ5+_·Û$²¤ÀHS> â«ÛÛÿg¤Ý9F9Aƒ¸œç'¥>ÛP¶›UŠ(&Þ&$ã¹aGˆæÎ rPÊ2~¿Öú]H%Ô㺽@†è¤c ô#ùSoä¶µVbȺ±ã&¡·º·0Ä 4§<Á_cY:é_¶/š®ØSG3jÌ,·.%ÌrJ²DÁ±š§w“P.U‘ŽõÞȲŠA'µYvW»˜€?RÝ•†’näƒÏgc… A¨ãS$ çKqžâ‰¨™±Ò65žÍ#Æ¡˜•Ç : Î=K‘fyÒ4s «6s»Oð©´k™ß[²ÜÜ5Âí¸Vi$ SŒf¯hßò°ÇüüÇÿ¡ ¸«™¶zugjâCöl}¤ÛùŸ¿û·ãiÇÜù±»Ç5£UooÒÒ[dxä9Ê.6||¥º}?Î*Ædß­É‘¾ÎºŽ|„ûÏ3h|œù™ÿ€çl÷§ÜÚÝIws*=ê“{¦É/”UàtÇ-Ïb;Vªß@÷ß2$ƒ8ó"t ޏ$P.³`êÄLÀŒÙhA@@, ŽG#¯jb3–ÎæK–‚I/–ÖãaÈ å e³“Õ±“ØûÓ-M-£òÞì´¶Ñ<åñ ¸oÚ26¤ü«ƒÇÖäWHŠÙx÷¾ÅY£h‹7\ÀM{±£³¦Õ’&t“wR¤eqô9üél3.yÝ-"3ÞÉ ]6òRXX'–ÜÄ¾ÝØäž§éL†Þaue-Êß‹qºùŒGï—»AQÔðp3W¬µ«{˜âgÝJp¿#2àŸ“/ °ÁÁ9äT©«YIt¶ë#™™ùmµ™A,c9Á¦"Ž›çÇm:?Ûp†0.6Ê^Sžq í÷ÇûUÝaaŠêÙæµJ¨ƒ,ã£(ÉRS†«hRWg–1 na,/ÛêHúU˜'[ˆ÷¢Ê«œbHÚ3ù0‡¨È´Ô#açMs™DÛ¡†I•˜– €ãå8#ëV/tÔ>v½µô"2¥ÄF"W#—9Ýžÿ…t5Ù-¾Óö³CöŒcÍòÆÿÏ­aÚµðÕ÷¹Ž'3,‹åÊÊ gi ÌTç uÅ[ÐDȳG"Ü2 \O/œ¦CÎ~I9SôãŸjÕ¢€ ZJZC (¢€ )( ¢Š(¢’ŠZ)( ¢’ŠZ(¢€ )( ¢’–€ )( ¢ŠJZ(¢€ )( ¢’ŠZ))h¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ª'þ>'ÿxè"¯Uÿÿ¼?ô@®SZÿ’~ÿõòÿú=ë«®SZÿ’~ÿõòÿú=ènËþ<<3ôOý&’°|`qâX?ëØèO[Ö_ñá២é4•ƒãAÿ^ëÿ¡=)l s9‹}–Ìu "§$TWÒɘÖ96«6“è*hàóRÞBNØÃes€y=j½ÚªÝ4Å…ÛorOµ*úÉçJ‰ 9.w÷ÔÕ½ÍS"H:žyÏoþµV_ßAƒ*ÆzÏdRÉ‚H<žÕwV&Îá¨Èa¸G®GPEW³Ü—Rw‰¼œzU›öä ’äõÎ1zÍŠi!Õ[Î\AÆN ­‡kê^šiã¸%6(x‘œŒÕùy·wã,½@ªåÍ#JI"1ÁçŒÓ-u2ûâ?*7ᑃõô§m4õÔʈàÚß;3’=ëMÕ÷gÜcÿ­QD‘ ««( ¢ƒœR 䏯\m=ðhnãHmÕÄisn²Ð•ÎÂq»ÐU{»¼Es ¸Ø¤‘NvœŠuôÖñ¼jì<È㤲Hf ½#9\á{Œÿõ¨[ ©¥ÑI-T!YU°Ãn6Š×Ôn ‘¡‚f#/GlY“ˆ­¦,v¦à=hŸt·£æca·Ç=©64‰ ‚häqv üÔÍÝd¯Î¸ Èæ •R"d¸«ö¤% /*[îbFyçê*y›c²H’Ñ9dJ†ç¹¤‰•e›çL³ä û ‰ç2‹‰Ñ ¡Œ¼çœÕ{‹ˆ…º•R ã#oCUkŠéf‘UˆeÞ@8â¢Ëd•?ZDºŽ]¥‡$t©%’Ö%ˆË}Ð:šÎÍl]ÓÜa†Á,¿ï-ZÒ­"]^ÉÒà>Û„8ÇûB±Òዺ²íaÑXu­­ ]BÎ@‰ÄÈztù… RZ*zžƒU¯må­Þ–) “z—Mê~R¤‘Ùz³YZíì–&ÆXÕÛ÷äRFáå¿_`pO^•±˜ØtŽýnhßRHƒ8|ðÏžqž8íQXéצB·¢µ6± âF _¼ªçw Ï+ŸJ%Ôµ/´y±ÁrÑÂ’³ dÜO*ZAÇÞÃ}*iµ+˜ïÚÅ#q¼H›‰ aÛ’Äö9sêAÅ0,YXKgÆ.Cæ]å|³´.1µbWשïÅ.¯¦NÙaóšVÜ$UÉ‚¬?$Q©^Kgb²¢#Ḧ9Af<‘3ê3íU~תm±Ã òÜ´[2 ye·mW89ÆïçFâš4Q_›ˆ…®ÒáöÉjÔ€Èù(ìqUàÓî¿´aŒ—K;i%t,¨Î`ÄžXã*¼zÔ¶úåÛÁmo ®²´’n˜<Í@6Ï@¦Fó-œµ¿‘ƒiÃòçù¾rqÏLûU«; ‹4åJùÅäP»qµ-Ž@={Ÿ¥RKÛ»‹ëycHdžd&àØEqóá¹Æ8ëQGª_.ŸçGäypXArêêîÎHlŸázœþ4ÑQX÷:•Ê\°­Ö½ŽÔÆêwœíËg8èÜ vÎ{Smu;—–##ÀÑËs45RvnÞx^F;æ—˜TV–¡-½¡il£y­ Ñ/m òýî¿7^Þ†¬Úê7ó ‡Ê¼S:È…Ù·ç‚1Œuç¯J`jRÖ5–£¨]\–éöC$‰“´*H;É9#¦ÑŒõ⛡©=¤«±ù<²ðù|µbry|IÐãg†mÒU}>´Ù¤»Ä„–RDf>A ¤’0F:Õ)5I£ÔȈĢe í8ò6î,yëò²ýq@´W6ú½Ôöèçiû \A*/–Ûppp¡àûV„º”¨ÓÝ—Ñ[¨9ÉW “ׯÌ*b5(¬>þþîï&Ý¡’D'å6’:ï$䎛F3׊ŸT–oøG®æÜ#—ìîÙŠLí!N0Ü~t‡¹¡EsÑÜÜXOq ²¼Q¢ó^ènf+œ¹R $ d3žµ4züö[â…‘\4Sò¡Fr?=@ÀczbLÛ¢°åÕ¯fœ&N‹oIJ…ÏMÎ¥GpÝ7‹©F¤É¼•ûq@ 7ìÛ°8Æ{tïך@lÑX ¬ÞC`—7 ¦[v©ÚFÞ $ä|Þ1ŠÑÓ'¿—ͰªciÔ*îÎr0úc®yÏJvõÎ3<6z—k7¯+Lì®<â¡6·§*Õœ){ “Ý\Ü „òFU.rª»A‘Žzóœô¤3fŠÉÒ¡Ž9ï¤yg>EÃ"™ndeUا£1Ï&¤Õe¸Y´ÓjU™îÊÒW[œãŒô=…ÜÒ¢±,¯.ÒþH§Ù™oÌL³ª/$ãÓ¹úÔ/qw5«Çr‘.Û†QðJ>Õ'kŒñØñ×Aè†t4W1k{¨Yé¥ÒHfÚEtþw˜Í!pÙPÅÎ8^½=ªôº…ôsKfL2] BÆc„áÁBÄ`È0F;¿ bFÍ‹§yz–fÜÛÄf·’V.…Æäe\ 0àä÷5bmF_ìk[¸•V[Ÿ( ù*…È> f€4¨¬«›«è¦KežÓÌò$™åx˜)ÚGÊvG^NN=*Ž£©ÝÜiwR@ÑÚªYÇ1 »y.Ý`F1ޏ9>”†ttVD——"þH-ü¥g½0†”3€¾@|¸wãÍ1uKÉV%V·‰ÄsI#ÈŒU¼§Û…Ï^IǽmQUôùÚëMµ¸òÂ’0^€b›ÜKP¥¤¥¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ª'þ>'ÿxè"¯Uÿÿ¼?ô@®SZÿ’~ÿõòÿú=ë«®SZÿ’~ÿõòÿú=ènËþ<<3ôOý&’¹ÿÿÈÉý{¯þ†õÐYLJ†~‰ÿ¤ÒW=ãSÁÿ^ëÿ¡½`[•­›iŸö¿ô#U¯¤+ ùiÂàAb™]Ä»ùš¬× 8*AÜAVv(–Г¦DÌr|ÁÉÿz­¹‘|ÖB~]Ôàž•š±Uµ,ëòp{ žk2Ôy‘n¯ôVxд®ÁO=é÷iž×1#$Ë3.ükq-”K2H¹g(?•YK½JòeRûC‘ÓçM>¦Q¦¢¬™>“höÐÉÌŒIìsŠ£¨Ú=«c.¦0ª$'·çWÖWŽápW ‚:þOåYšœÓ͙ʬy7,{qD'ti(YމMŠyâpÉçêE]’ñ(îg>ÔÙnUa+8v%rЇqÏ?Z”4 & €_¸ü‘ÅTnLì­bÉhã2I7Þ~A? …AiæÙÝÎ΂»œƒEóH l;íÊ8¦ T0\$·|³c(n£°ôâ«•¤ßq^í"ÅòÂë™C–b0ÊrW×½V‚íÇÏ&Ï›q 0sŒsM™Z+Òø“j—¸RsÇéUf”5ÉÝËIÅfî¶-$÷dÓKq$Å9Çó«6bG·ØË‡w§Ô†(mÄÛ¤a"ôŒdƒL¶g¶>vÇhHÀ'¶jÉmY£· lTÈG$VtËpH’<¬ |„}ÒjÑ’_$«E„l÷瓚­v#1'”‡å7¬Ów½ô4šm¿A­BPȆsZ §È+C„€¾½cO,Ò¸2 `“ØV¤ÚÍÃB(Ð7 ?Ò›ßvCwe1›Ï$!=Ílè ‹ym·3!àçø…rÓÞ\^ŽÀ*ž [Þ$jGœ…™?ô!NÁsÑ陕IC¹IÚqŒN üéh­Wm:ÅÖ5{+gXÉ(!rrqÇÒ}†&¹šyKLÒ§–D€ Ý@ÇCß9«4P^8Þ#Æ]¥ ‚¤zcÒ™¥´© ´1*¶õ P­Œdc¡ÁÆjZ)ˆ‚KIâKk‘†.âRIÁy4ómo狃>xD¾Xß@zÔ”R³¶›m˜òdÙÆ3œg¥;ìÖû }ž ¥òÆ áqéÉãÞ¤¢€(Ë¥A> —²’Ï ˆW§Í·w^q»-®ŸkhÌñB¾k&VA¼îbÄgÆMY¢€!’ÎÖhÒ9m`xãÇ–•LtÀ#Št¶ÖóÈ’Mo ¯(ÏbŸBzT”S±Ú} Ü}–=† ¾Zï=ºã4Á¦Ø, ±µXX‚шT+БŒ³E qÅÇ*"Œ*"€ö“ÊÎó¼¨üÝ»<Í£p^¸Ï\{Sè¦t°³Œ8ŽÎÝ@C…‰FàzƒÇ ÓÚÖÙçóÞÚ›ŒHÑ‚Ã9ö©h …¥ªÜ›‘k¸=eçþÖœ-áÿgÇäm+ålpzŒtÅ>Š@WM>Ê8d†;+há“ï¢Â¡[£Ò6bðˆ^ÆÙ£ ¸!…JƒŒg늳EC=­ÆÏ´ZÁ)„߶ϦGÿ""Û¼¨÷îß»`ÎìmÏ×gÒŸE1a…6ìŠ5Ø»ÕãåƒÇµ6ÞÒÚÕYm­ X弨Âç늖Š`AœWâ+KxçlæECœõ9ÆiZÎÕ®~ÒÖ°4㤦%.?f¦¢ImÍD¦9óæß‘ƒ’=¸§˜ÑŠE&3•ʃ´ãœ)ÔPRZ[J®²ÛÅ"ÈÁÜ4`†a€ õ<Ê„· J0P¨ÐÜœ}{Ô´Pf·ÚWÈ‹k B» ‹ô<{ÒKkm8o>Þw[|a²GLçÒ¥¢€–ðFTÇ i´P  œ=2h0Âaò Q˜víòö»}1Óú(°²h³¶1Fw"WjŸP1K=µË«Ü[A3ºÒFè2*j)ˆg“ÿ3ÊMû·îØ3»sŸ\qŸJ­{¥ÁyFÇÊDbÁR8úž§æSƒÉä`óW(¤1#!‰"v¢(E€ Z(¦ ¥¤¥¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ª'þ>'ÿxè"¯Uÿÿ¼?ô@®SZÿ’~ÿõòÿú=ë«®SZÿ’~ÿõòÿú=ènËþ<<3ôOý&’¹ßx†ÿNéÿ¡½tV_ñá២é4•ÍøãþCðÿײÿèoCØæeÐΜ„v™‡éT[÷@6w?P£®+FPKaÝnAüÖ³à‚IäqÔP§,ÜT-Šf“h b2z[«¥9$Z­2ùEAÉ$â«Ä$G`Î[ýœäþ=*¾ÇLi´¼ÆCtmæ-ò8`xnyÇJœjr0—a˜Jª ÀÍQ–'[‚wØSf‚H%XÜ“+ýÚ´–ç4”“³64ëÕ{pçrŒî=}¿Ï½d¬HNîÃ99QžO5fIdlzJ*-¾æ‰9$™b;³“±Ö%ʆÈëùÕ}á®|ÂJ.ýÁW°ô¤šÒx˜€=:Ó™KcåÚST´KÞÂÈárX¢¦s´õÉÿëÕa8ÇB;Ö¢B«n¤ƒÉ'Š©40¥\ÜíÇ4]“hµn¤öD­Ù ²®×¦pqü@VKyÄA`– ÓcžXUVF<ŒR7Ÿ34›[¾•:ܵ«§¹¦öÐà º_4Œm’{š¹2›R$Œ&Y$aÈöÇzæ‰9ÆìÓÌn3‘éšzís7µEÿíݸ²(bFÞ¸ ^Iå®ùr`+sP¥¤Ž¥Êð~µ!bI\ vD¤ÖʼnZÙüå·rv޵OkæªÈÖí‡O›x5\[ùqFò/ÊÇ?¥>F[UÀ#6wÉ4šè†ŸqDBbåù|ç®95µá©BëèøædÆ9Ȭ ¯%¹.dUbøËmÇ>µ§áŸù Øóÿ/ÿèBš¸¬S¥¤¥ªQE”RÑ@Q@Q@Q@ E-QE”RÑ@ E-QEQEQE”RÑ@Q@Q@Q@Q@Q@ E-QE”RÑ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q?ññ?ûÃÿAv©øøŸýáÿ Š}rš×ü“÷ÿ¯—ÿÑï]Urº×ü“÷ÿ¯—ÿÑï@v_ñá២é4•ÍøëþCñײÿèo]%—üxxgèŸúM%s~:ÿü_õì¿úÐö¹^ 9'²•U jŒžœŠ[>ëL öÈ©B„þ4á©M ”ê¹oÞ#à„µJûZ½Ô$äù…Fåû¿€©IXÛ²½‚I “›UHÀ qQ0Š=ÎAp~ö 5cgBÞc6z¨^* “ò‡Aœò)]¸Ê1²Ô¶’-¼¡¡+rSxíT¤¦¸ïÜÝY³Š–8«|¬Ië¸g4æ=¿”©Ï ·§J:ŠI4›Üˆ[>~l×Ö¬±+HQCw'¥6Ùf…·:É ôòɧ¬S»äÊ2xýÑ QJÖkñ;k‰ƒ9·9þ•~Ã@º»´–æ9#Ä]œõü*êüÐÄã=wéì1HF¢Hà¹TnljÄIµ¥¬W‚à¸òd@ÀôÏò¥¹Šo•œ¤p¸èJš}ÖNèg\õ0•,Öw­€-¥Âð0:ýhm Öz"T,ùTxû``þµVs8rå?¸Ú}óœY@ö"éwAx·aõ4s©¦ïs:„3¬’IJc½©‰‰¦#C€{V‘ÒîY†ëoÄ‘þ4­¤\#nU‘Ó b•МZÕ= š®k œÙÞ dq’‹ŠÁ˜4yó•½Mk[ØÝÄX°‹qÌ/¾).4ù¥ Nöç9j›FkMŒ‰.ìÅ î'UŽH¨ãp²çÊÖ›imÚh÷TM¥Œ][/þó©¥ÌKIlQ•ŒÈGËœkK÷[±ëqþ„*¦¶No-½ðýjöc³[°µDÛn#8óó .Rzjz}-%-Q˜QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE•%ÄqÝN¤>C»7ðAZ5“qÿW?õÐè W©;2$ÜUÐÿ¶Â:ùŸ÷éÿ¹Ýdƒðùcräß÷­S÷ÇÖ²5_ù'#þ»¿þj©ÁE+ 2rÜݲÿ ýÿI¤¬¯hzŽ¥«Gqin$ˆ@¨[ÌUçsrG¨­[/øððÏÑ?ôšJÚ¬š¹¢8km Y‡?è®  bÇþ…ZrXj(±­µŒÀ홥‡“íÍtÔRåCæg"Úv´ßòë/ýþ‡üi¿Ùš×üûMÿáÿì(£•38ÿìÍoþ}§ÿÀˆ¿Æ“û/[ÿŸY¿ð*?ñ®ÆŠ9P\㿲õ¿ùó”ÿÛÚ/ö^´?åÆCÿo‹þ5ØQG*cŒ:^´åÁÿð0ñTŸÙ×ýÏþþ*»J(åAÌqGHÖÏüÃÁúÝ/ÿMþÇÖÿèãp¿üUvôQʃ˜â­Ÿù†ÃÿSÿФþÃÖ¿èoÿ}§ÿ]År ¹Ãÿbkóáoÿ}§ÿM:¸åÆûí?øªî¨£•ÎèZÙ9û#èÑÿñTŸØçüúGÿ}ÇÿÅWyE¨.pgÃÚçüû/ý÷ÿIÿö½ÚÜ~Çþ5ÞÑG*ÙÀ7‡µóÿ.çþþÇÿÅTšn­Ã©ÚM-¹Xã™]Ï›†ôoJîè¡$aKIKLŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ’–ŠJǼ KxInê[oü³^ý¾µ±Y3ÿÇÕÏýtúÖ´÷3©±›nÊÌÛY‘÷f2>•CUÿ’r?ë»ÿèö­v$¸ÉïY¯ü“‘ÿ]ßÿGµ]n„ÓÝ›¶_ñá២é4•µX¶_ñá២é4•µ\æ¡E´ J)h ¢–ŠJ)h ¢–ŠJ)h ¢–ŠJ)h ¢–ŠJ)h ¢–Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š))i(¬É¡‘îî Ȫ ƒ†B…}ÅiÕ#ÿÿ¼?ôT¤ãªIîT6NN|ôÿ¿GÿЬ`møyK‰þGjêë•ֿ䟿ý|¿þznN[‰$¶6ì¿ãÃÃ?DÿÒi+j±l¿ãÃÃ?DÿÒi+j aKIK@Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ªGþ>'ÿxè"¯Uÿÿ¼?ô@®WZÿ’~ÿõòÿú=ë«®SZÿ’~ÿõòÿú=ènËþ<<3ôOý&’¶«Ëþ<<3ôOý&’¶¨RÒRÐ0¢’ŠZ)( ¢’ŠZ(¤ ¢’–€ ))h¢’ŠZ)( ¢Š(¢Š(¢’ŠZ)( ¢ŠJZ(¤ ¢’–€ )( ¢’ŠZ(¢€ )( ¢’ŠZ(¤ ¢’–€ (¤ ¢Š(¢’ŠZ)( ¢’ŠZ)( ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ª'þ>'ÿxè"¯Uÿÿ¼?ô@®SZÿ’~ÿõòÿú=ë«®SZÿ’~ÿõòÿú=ènËþ<<3ôOý&’µ¤¸†&Û$Ñ£c8fâ²l¿ãÃÃ?DÿÒi)uUÍþé’ÿ6 F™¼µÍÌ<ôýàæ—ívÇ¥Ä_÷ðW4Ñ-›¡ÈÏjËUÆÓùûÒL¤Ž—ívÙídô`©””eO ކ¹9³·¾AãÐh÷YŒ@ü0åriƒV.ìoîŸÊ‚:ŒUŒÒ0Ó!½4+QÔÎÍë*ø¨å^HŸ>A­£M>¦.«] ?´Cÿ=cÿ¾…'Ú`ÿžÑßb²•TŒµ9  8©pK©¢“hÓûU¿ü÷þû}ªÒh¿ï±X’Û˜Æâx¨Õ±V©&®™›ªÓ³GB&ˆŒ‰÷…*È÷]OÐÖ<3*¦Üýjh¤e<j‡I—íQ¤]AÁ`?Uù¾ï?J¤»˜ägŸZ½o¹S¤ád ¥Ý…ØßÝ?•û§ò©ÁÍ-A¥Êû[û§ò£ctþUbН±¿º*FF[œdÕ’@ëPË4J6³¨-Àõ=¨:(¬MB[‡–âKyYsÛ[ ÜB–ó¶qìÊ?1K¨Íº+j¦QiºÜOö¦€Ìcm˜òüÌíÝœãŒn¦G©ß\¥¸ƒì¨ÏÎìêΤÆá~\ÁÉÿ=O07(®~]fò(FŽ'iâŠX‚‚<½ì KØÜ9ùµfY¤6µT–9Rm¨–ò˜ÞRGÊG$OMݳLF½“ÚÑtÛIæc:+M9Ý“…)#¯, úàÕhu-RKxŸu–él¾Ö¿º| c+÷¹ÎáÏô4†oÑXj3Í1H6D×!U¥ ê€À¯Ó#ž£_ªÞêwv¦ç lEœ),‘›$ðŸ7Ë÷{îäâ¬+›TV=äÓ™äGqWöÀo`2dRÇ‚;2ÌSb¾Ô¥š%V´U¸žhS÷LJl-‚~o›!O}{RjŠçd×®’Ú9Ò4a#\¦Î\¯ \c88Z­\êW)rÛÜD—±Ú˜ÙNöÎܶsŽÀÇlçµ06(¬{-GPº¹,-Óì¦I'h*T2w’rGM£ëÅ3í÷asÈïˆHÖ5„§–Òªs¹ƒ ÷èi Û¢²%@uxb²žàË+\3L̈˜ÆÒ¤íÜݸÏSU­§›íÓ‰¥y繸ŽHŒ„®Õ€ ÆÕäsϽb: +˜K© °Y–îviôǸ™· H6á•IÂòÎ008ö© –êÚûc#,ì°¬Kö†˜#I•;s’y# ÇÍ0::+Y$K©]n&ó`½†Þ8̧i‚g+œ1;˜äóǵ-µä²ø‰¿k$Že¼.¨²áŽF ?1Ï@ù nÑY¨ó®!K9§ûl˜dÙ3AåÙAÚGnAÏAI9–ÓWûLêÒA4é[nä2T. tŒäúóœP€Ø¢¨Í#vÒ=ͰÛÌJƒÆAÄþuZmVhõD‰T=±¸[v;!Ø÷‹äõñ¡j½cyt÷¯oyµ‡hã™cp}Ä7q€yª×3ÛÜ\é«4¦[©à`ÇrÆÃ÷›Om»XM•ÆtV Æ té/æ¶ŒAöc4D0§Ň<œ.1Ò¤}Fîo-äšÞIbòM $îi *_Øcæ´ÄmQX‘êwóÙoŠEpÑLD{Ê…È@üõŽ=ëL½ÓÑüÆd–0ÂH‹FH#9ä~y¤ûŒ±EbEÕ4R–}ˆò¹’# Ør ®[©ð©$¾GðÄ×0†B¶òV•‹e2ÏœžG\æž×ƽŒúÊ]Ü|Öæ(.¢ƒÊÚ|Â'9Ï«zsŠ[}Jê[»@Ín!¹žX„aNô’s‚r¾ƒï@®lRÒRÒQEQEQEQEQEQEQEQEQEQEQEQEQEUÿÿ¼?ôWª‰ÿ‰ÿÞú ×)­É?úùýõÕ×)­É?úùýô·eÿú'þ“IU|@î5TU‘“1.pxûÍV¬¿ãÃÃ?DÿÒi+?ÄÒõˆÎÆcä©ãÙš‡°"¼ÒªÛ˨ǧ.%Vn‘‘T­ï£BˆëÜþUo€t?1èGCIjÝ2H²ÒíSÜ⬇eq*ü®§‘U-‰ûB†9«#qžSÆ÷Ø7©ÐÚL·0‰¯ñz‘²¢°¬®M¬ÁÌoÃJè2C FAªL‰GM R±“Ö¨N2¤žµ¡:0$ãåÅgÉ…R æº#¶‡7“*'-Œš¶ íUAmÜU€d*0Ã5 ¡°ÙØck¿áU7|½*ß‘““ɤxŒ’’Z qlŽ$ïV¢L1Ö™U 1À­BœŒV’‘’V s‚¸«J6Œ @è*+˸¬¡2H~ƒ»ç”®k½É^Drîª=Î*»êVéÜ·ÐV—]Ü f' ì*UV'å^~•›o¡ªF“ê¹ÿWâyªï¨NÇ‚·ÿª 3uýiâV¡E°m ’âgûÒ°úqÿרíÐ}²Û“æ/'$õ÷«Z-,;~ÑûãùÕrŠæ¥D–Т)RþfæËg9çßò©j;‹˜mc2\Ï1çäp£ó5%‰-­¼Ñ¼rÛÃ";nexÁ zdƒÔð?*x‚ TˆB‹„*œdAÀãڪǫY5ºM-ÄP,ŒêžtŠ»Ê±SŽyéOþе¯ffET9R@$ôü‰  Mµ¹B†Šü½¥6wéíQ6ÀÀ 66†;„fÚ®1ŒÔ–×v×h^Öâ)ÑN Dá€>œQq3ªc¶šá‰ÆØŠçëó?ZHm-­Û0A'—µ.IÀÉ4å·…B `òÀ>ç÷G·j§ý±à A4í24‚4r…á‰ÉƒÇ_¦i%Öm‘ªM,"å@6Åtfɱé“Á¦"ÛÚ[ÿ–)Ë JT¬H ’Ë…œ‘îrr}ê•Æ³oo¥ý½ÒBœQænܸÏQƒž{»+”…QÜŠãì=é ‰´û'*^ÎÙÊŒ.èTàuãsPË¥Á> —³i‚Ô¯O›nî¼ãv)‡XE†v{[„–DxNÍÇypCmç>µzy# $2@Çø©aÿ|’?Zbö+O´²Áç°Á—Ë]ç·\f™gѬ0…0 ‚ uëÞŸ%å´S¥¼—0¤Ï÷c.7Ðu5^-gN–˜^@¨’%äUÃG¯|zÒ9Óìšçí&ÎÜÏÞi‰Kät;±šzÛÀ“´ÉK3Œ4vç­6KÛH¼¿2êŒÆYÀÞ8äzõ×–×a͵Ì3„8o.@ÛO¾:Sèí­â2­âŒÊw>ÈÀ/õõ¨ã°³‰QaµŠ%GÞ$c uëÞ‹»±l#\’É+ìHãÆæ8'Œ:y=©Ö—)wl³Æ+ °ÁR>à‚) q‚¸Œê0%( èZy ‚BŠ\Èûà~T´PWÒôé ™4ûG*¡Wt H p*Agj·Fém¡þ[yk¿Óïc55ÄCqciw·íV°O·8óbWÛž¸Èâ‘llÕÖE³·(XD¹\tÁÇlTôR6–Öîï´14Ÿ}£Œ)o©iæ(ÚE”ƦD+픸=³N¢€ [Ti^xa’`CÉj³êqÏãPYèövKeI±¼I tUB÷=ªõY´ë!½³FpC •Î1×<Å4F)bŽHÏAR=1ÒEV:nž`ò …§“Þ_»wzãÍ%æŸݱÔF» yT‡ªŒƒ€@ÇjŠ`VOµŽîK¯%w}ûÙAe%BáN2£‹K·QkâKÍ’FQ Œg* ž8äš»E ZJZC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ¢ãâ÷‡þ‚*õQ?ññ?ûÃÿAúå5¯ù'ïÿ_/ÿ£Þººå5¯ù'ïÿ_/ÿ£Þ€6ì¿ãÃÃ?DÿÒi+?Åé7ÚâxkˆÀ?™­ /øððÏÑ?ôšJƒÄƒ7Qçþyæhc[œLžjÊ$¸‘ËžA¡c©¼dyÙÛœn?Ö­¼ æ%e§ó¬Ùôö\²eÀ?tš‹4i£:;wIÊnsÁ‘VÈÉœdôÅsz|2Á8ódd^¸QœVßœ$-¹sœuI™IY–x(å5£¥Þ”ÿGäuCý+ $š#HªJ€±rT÷«‰y•Û–àú{ÓC^æïµ™-ÆIÈ­ íZE0Ov=ê5ÒØŒ’+¢2Ií]é©”ÌñÅIŒ„ Ùyô§êri§f6m>æ›”ZÔqM,ŠÃ¨&šÑlŒV„6zÕ‘nƒøgu¡i¶µ1|§NX~< p 6+YcE(¨äŽU~Ã4ÝA{4Èn/¢´·ÞùÉû«Ý`O,·sy“·aÙEX¾‰ë31~8ÏðJ€•AÇçYÚú—²²…pO'5e¤ qŠÏµ»ŠâfXœ?–pÄtE¯]ËgiæÂFà@äfôÐ-®¦™˜öS ݱ\Kk7rróIŽáH_ä)¦ýÁ‘ÇûOº•ØìuÒß[¡ÃÜF¡jŸO™f¸…ã;°ÁükŸÓotÜ ¹<àWAb¼Œ.1¸c:ŠWê§m4²ÚÏoå´–òÙ#S•+Ô‚3ž•rª^Ý<o1¤“NåT;ìQ€X’pqÀô4†f6|4øí–Hví˜:,ÒD€»’§å`#iÀ©eÒnd‚[6?.âÉ-¤}͹YCr>`wzŠ}ö®Ö*É>ZmŒìcã<&1îÅsŠ|š¤©sp¦Ù<ˆ.Rݤó~b\.\v.;Óò-ì%H§2ÚÛ´²yys,Áœò\qŒ’ÍXÕ£½žØGbÑ¡fc<…ÎûHVÁ÷ÇFßRºÛn÷JНw4Y‰³•O3¨+þÀèrJ_íÉRÕæšÍS6†î³n ‹Ž”ò=G=i!±ºìÒZEmÀÐŒ±Uˆ †Û’FÑÔ äóPI¢Î–íkm$F­RÖWrC(\Ê9ÈcÁ#·5zéÚYášÐ‰¢¶Ø¤ 9 rBò0r?>þî[g¶ŽRW¸ÇóI°/ÊÍ’p»LEt«‡Õ~Ð ’E¸$ùÑ¢˜Ôc8=ÇÞ<±5ŒäÃ5¼vÉ43´¡2B¸`Tî8È$6zEº¡£V€!håcóç … qÈÉëÇÒ©Râ]²£yI"Y8LÛæHC ãž8ÿ ¸Ðd›MhÅÛ%ÉŠaòíòËJKw)8ç8«íñxVœ@#I¥á™†xm«÷{ñùUÚJC2m¬.SOš+«[;‰¤`òy’³¬§¹lÇòã¥ZÒ¬ÞÊÙãqŠ<ì„|ªHqžƒ¯J¹E1·w-©¥Å±HA(%q+eÕNJ˜öx' ŒûTFÃPX¼”’?-n$—å¸xš@åŽ UÊà°èNqÚµè¤3'OÒ§¶KA)ŠO" £#-ÉfR$g?Ö‹; ¸í¤†eáÌbw•¥Höž~b ú`sÓ¯5­E15 if–Ú{}†[y7…‘Š«‚¥H$Ž®JvjÖvkŒ¯!g‘™zf,@öçfŠC Z( ¢–Š(¢Š(¢Š(¢Š(¢ŠJ)h ¢–Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*‰ÿ‰ÿÞú«ÕDÿÇÄÿïýPë”ֿ䟿ý|¿þzêë”ֿ䟿ý|¿þzÛ²ÿ ýÿI¤ª~#»·‹SHgb„Âßy…\²ÿ ýÿI¤®wÆîF½$íû2qÛïµý_RÒª»+£«(ÇCL)Ž£« ç¼2K,yä¯@kfÙõ)¡ií‘n¡1 àãž*9’Ü»v.Ûìr󜚆æÞdg’&Qò0¹&–Æé'V·d àÜz±ŠEf‚@þä­zÁyöé‘%•aBFìuÇÿ®´m®”…ÜC}áß5…sj[QÁÂ/—½Žr=?¥MW>Ô̈zsCv»:$¹Ø>WuöíW­õÝ)uÜ}A®`Mu(ÌZLqÂñN¾ÔgµxV¤|þÜÓRªþÖ¶N%l7 ¨e×í¨ç¼ æšçÏŽ $Rœà`ƒHË#³…UÌòçÝ:Ô¹ÙDèb×ÖBçÉùPáó­,šÔ˜8dr[?•a@¬¢O4¨ Î1ÅZ[Ÿ!$œÈÂg QÌì $]}RïËv'ËÛþÇ_ΣŽöVQ+31+œ1éPyÏq¸1‘°zmÆIô§O’@ .GÝ߸\еÜ6EKÍU!Á‘·I!ùQG&±î5÷rìÒ.ç‰^G_^*=e¶^Z‘è㚣~ß¹²?ôÌÿ:«“c£Ó'·šòå­xr`cùi¾)ÿk¼¿Î¨øY³%Ç^«ýj÷‰}=”u%;éq(ê’8üði©¼†=©E¹ïQtl©Môc=G¥v^9·µää9øõrk©®¯ÂÀGðÉýE'%qºRŠ»V:ú†æÖ¥U ÚÛ•ƒ”e>¡u=*jÎÕćìØûI·ó?~-÷oÆÓ¹ócv3Žj̉%Òlgš•U™þp9¹ù±ž§&‘4›q{=Ü»¤’Y„ À)UP2¹Ã`®A#ŒÖmúÜ™ìë¨gÈO±ló6‡ÉÏ™ŸøwöÏz}Í­Ô—w2£Þ©7±ªl‘ÂùEP>LrÜö#µ4#M4ëXæóR3»Ì2€db¡È ¹ÀÎãž;ÓH°Ž)cK’T1°21ùU\Ÿ”{ VbÙÜÉrÐI%òÁÜl"Y<¡L¶rz¶2{zcÅ©¥²yovZ[hžráØ†Ü7íNÒ~UÁãŽi!›²Z@òHî‡|ví$¨àú“N–8¤š# HÉtù°AÁRq߆?cCo;¥¤F{Ù!k¦ÞJK òÛ‚X—Û»“Ôý)ÛÌ.¬¥¹[âQn"V_1ˆýàò÷c¨*:žiˆÕm2ÍÕTÂp¥ˆÛ+)ùÎXdOn”Ÿc°FŽˆ®V5 œ•ˆî\ ó‚süꆛçÇm:?Ûp†0.6Ê^Sžq í÷ÇûUÝaaŠêÙæµJ¨ƒ,ã£(ÉRP—XägêÍÚà•8ΧS«–š„l<é®`3(›t0É ³Á‚°|£ç`}jÅëNš‡Î׫+_Â#*\Db%r8ùsÙïøQÔ†ŠçíZøjûŠ\Ç™–EòåeP3´†f*s€FÐ:â­è"dY£‘nP.'—ÎS!ç?$œ©úqϵjÒÒRÒ”RÑ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q?ññ?ûÃÿAz¨ŸøøŸýáÿ Š}rš×ü“÷ÿ¯—ÿÑï]]rš×ü“÷ÿ¯—ÿÑï@v_ñá២é4•â˜ËøŽ"° ‚Ú‚W8y¹­‹/øððÏÑ?ôšJÉñL¯¼…]Su²Xÿ¶ÕQmRIÊÌûŠuš5û/–ýÝû‡¥iéqÉe ¨óã9#8ýzÏžeûL`Èø {ø‡£ÙÆq:Ü0š6$,àð8®dÛV:e­l?Odû2;©'ñ5êZÇ ÜF§1à¶Ã‚3UÒõ¬ì¬È@VO•É8Ú «š—–4Ù6Êpr;ó]I­¥êTFš¦;‹±„9ÁnœUÈ®P6\¹å‹ak>îqçK,R }j[Ò ‘‚©BÜñÏ¦Ñ sN;••7FáÁh®H—û³–ž¿Ö°­.$ »#¸*àpãŸð§ÝI+L]Щ'¯Sþµ\Ò¬'% “ŒŒçµWmRq¼¬cä?/'ô©,ž9›-±ªœsϨc²#6ãÏLëÅG+oRÓIh]Óæ–èÊ’"Ž ð?j$ë(ÊQ¦ÂKcž=k&Ò`i Ý(SØ*Ç“oµl² B˧A¤×`Nû—ŒÎíÊìäžWùÕ]£¶>|«½Ý‰;‡®+VA§Jv‡À&.IÇùíXÁQm°¸+½±ôÜhƒ³°¥f®eêæ9$•øŒH9É5Yž6Ž®å\*ç'­X¿Ž3wz6xªË ™-qÇþÍMÊ×F±iY¤ixm¦7W>b2”*‘Z·â6aXMÜýz f’„]Ì ÷yϵY×Bµ°Ü2)ÿÇ…TeÍLÛq©tgédEdC–Ûý çò©×@¹•>¥ÏøW_=º,±(„¦é‹nÈ åMUšÝ|æ’6'ÊÔäàdãýFy¬Ó±ÓíÛØæ#ðüì_3D6¶Þ 9ã>žõ¡¡ÛµèØ1‘Ì"S yrSŒ„üsQÙÈ’jÈñ¶VGFç¶@âœoÌ*³”£ftµVöù-%¶GŽGóœ òãgÇÊ[ Óüâ­UkÛG¹kw†eŠH$Þ¥ÓzŸ”©dvcÞº!Vú¸6ù‘$Ç™ luÁ øu›V"fb3e¢u°$r9޽ª¼: G~· 4oƒ)$A‰>xgÏ8Ïv¨¬tëÓ![€QZ›X„ñ#¯ÞUs»…ç•Ï¥jÅy ˆ­—{ìUš6ˆ³uÀ 4×»ê1Û:mY"gI7u*FWCŸÎ¢²°–Î%Œ\‡Ì»Êùgh\cjį¯Sߊ]_M²Ãç4 ­¸H«’X~*H¡ùŠËZ·¹Ž&}Ñ4§ ò3. ù2øÚ žEJšµ”—Kn²9‘™‘O–ÛY”À60qƒœ4h¢¿7 ]¥Ãí’Ô3©‘ò0>QØâ«Á§ÝhÃ.–vÒJèYPœ0À!‰<±ÆUxõ¦€Õm JìòÆ!MÌ%…ã;}@` J³ëqôYUsŒIF&ÖEž€-Læ[9k#Ó‡äÏó|äãž™ö«Vvi%Ê•ó‹È6¡vãj[€z÷?JШþÉl.~Ñöh~ÑŒy¾Xßùõ©(¤0¢Š(¥¢Š(¤¢€ŠJ(h¤¢€ŠJ(h¢’€ŠJZ(¤¢€ŠJ(h¤¢€ŠJ(h¢’€ŠJ(h¤¢€ŠJ(h¤¥ Š( Š( Š( Š( Š( Š( Š( Š( Š( ¨ŸøøŸýáÿ Š½TOü|OþðÿÐE>¹MkþIûÿ×Ëÿè÷®®¹MkþIûÿ×Ëÿè÷  »/øððÏÑ?ôšJç¼hÀx–a÷ísþû×Ceÿú'þ“I\Ï6Â_µªð?ßzº°EÙÜ©z|»¨ÐJ€~î;…"\쳞ݎ×ÉùqUï.%6Ví!fÞÄŒžÃ@Îç$`g¯zÉSv±»ª™¥©–þϰŒ¥ˆÏ «ZuÀ“GXÜ‚cn‡¦3šÎÔÇ—mhäşΪÇ!€ךÑls·©µ4ð¤ì]<Èåˆ*;ç½T‘ÔʬŽ@ü? †üÚ›u8SP[ÛÈØ!NÚ7ìhÞµ¹¸r@\.ÜÓìÄr,‡œ/޽ñɦßY¾™·g,>UROASi¶˜¦S l¹HÍãcžx!c4ï·ªg«Nå_å›Í_lЦ“ÜÆ$·pq’v·PGëR|ûH?+pJúU ²ø¼ó€ ÁIÁ ÇTª÷€¤Á㜌ò¼õàÖj£ÿ õ$r¤Ê ö ä­$©Ü¿&¬Â0­jŠí ,Àrýu^‹xÚ,Ì€ ùyéÒ”_)]·0eÇ!—¡>µ…µÜïƒË\ä±<¶*RKbµz²+ûµKìoݾE*ʆäÚW˯» ½-®Ÿq!qt>Œ=*DÓíÌ/Ýç擊cRhƒM¿Ž7’Dœ‘ÓÓþºŸW»i´âÅHÉÛ‘N‡KŠ|©–êqÿ×§Ýiò\Úy“$õçÛëM$•96îͽgYGµ‹ÊGów7`y_zM.ø[Á¶Hت©³Œ1ÜúW&Þ•GÊè?¥Lt‹eå c.î¶1Pâ™JvV6¤Õ4ÈÜÝE#$©!*ªr€j®qê‘Ggu x8•ˆtKÅè ü¿Æµ4 Iíµ a*>|õ9ãȦ¢9¶¬Îö²µÛÙ,MŒ±«·ïÈ(¤ÃË~¾Ààž½+V‘‘‘™T”;”‘§ÈôàŸÎ¬ƒ]KRûG‘k-)+2MÄò¥¤}ì7Ò¦›R¹Žý¬Q"7ĉ¸¦¹,OcW>¤UæÓ¬]cW²¶uŒ’¡R''qÍ'Øbk™§”´Í*ydHPÔ t=óš`G©^Kgb²¢#Ḧ9Af<‘3ê3íU~תm±Ã òÜ´[2 ye·mW89ÆïçZ¯o‰ãFŒ®Ò…AR=1éLŽÒÚT†Ú•[r„Œ(VÆ21Ðàã4Í·Ôo.Þ#kxeu•¤‘ãfË}Ÿ*îž½x÷¤}Jä]·ü{ù t–¦=§{ óœótÁàkFKIâKk‘†.âRIÁy4ómo狃>xD¾Xß@zÐ2^ÝÜ_X;ËC$ó ‰7Â+˜ç ÈÎ01ÇZŠ-Rùtÿ:?#˂ —WWvrCdn-Ç Ôçñ­Ágl'7Ú1äÈ#³Œg8ÏJwÙ­öûT-â™ÖD.Í¿< Œc¯=zUé,íf#–Öޝu=† ŽvŸ°µÌ"ùm·ØúNµhË©J(ýÖRú+u9*á2zõùåVÒÂÎ0â;;tY%êƒOkKgŸÏ{hZn1#F tçÚ˜º}ýýÝÞMº C$ˆOÊ m$uÞIÉ6Œg¯>©,ßð]˸G/Ùݳ™ÚBœa¸üêØ´µ[“r-a¬¢1¼ÿÀºÓ…¼"ßìâü¥|­ƒnQŽ˜¤ÆŒîn,'¸…‰Y^(ŒQy¯t73Î\©’2ÏZš=Nþ{-ñB‚H®)ˆyP£9ž `1ǽi¦Ÿe2C•´pÉ÷ÑaP­QŽiN±xD/clÑÜÂ¥AÆ3ŒuÅ1XÌ—V½špštI:-¼sÊH=7:•uÃuüÞ.¥“G¼•ûq@ 7ìÛ°8Æ{tïךԞÎÖãgÚ-`”ÇÂo[gÓ#Šw‘mÞT{÷oݰgv6çëŽ3éC 5›ÈlRæá`”ÉbnÕ#B›HÛÁ$œ˜sÆ1Z:d÷òù¢öLm1º…]ÙÎF¿LuÏ9éVÖSnÈ£]‹±p€m^>Qè8{Smí-­U–ÚÚŽ[ÊŒ.~¸  g†ÁïRâãífõãDiƒ8¨M„íéÇеg ^Ã$÷W7a<‘•K‡E@ª®Ð@äcž¼ç=+J;8® ÄV–ñÎÙÌ«‡9êsŒÒµ«\ý¥­`iÇILJ\~8Í$~• qÏ}#Ë9ò.Ës#*®Å=ˆîy5&«-Âͦ›R¬Ïp~V¢¸òÜàg¡è*ì–ÐI Ñ4JcŸ>`ò0rG·ó1BȤÆr¹Pvœc#Ó‚E01¬¯.ÒþH§Ù™oÌL³ª/$ãÓ¹úÔ-qw5«Çr‘.Û†QðJ>Õ'kŒñØñ×MÉ--¥WYmâ‘d`î0C0ÀúžåB[À€‚% (ThnN>½é1œí­î¡i¦³¤Ì!´Šéüï1šBᲡ‹œp½z{Uéu èæ–Ì˜dº…ŒÇ Â…ˆÁ`Œw~«ök}¥|ˆ¶²+°` è¿A“ǽ$¶¶Óîóíá—q·Æ$tÎ})ï°Œ¨5;ËÔ³6æÞ#5¼’±t.7#*àa‡'¹«j2ÿcZÝβÜù@oÉT.@Éõ5}-àŒ©ŽШ*6 A9 zdÐa„Ãä£0íÛåívúc¦(6æêú)’Ùg´ó<‰&y^& v‘ò…ݑד“J£¨êwséwR@ÑÚªYÇ1 »y.Ý`F1ޏ9>•¸ÖM@ÖvÆ(ÎäC íSê0)g³¶¹u{‹h&a÷ZHÃ=E3¤¼¹òAoå+=éˆ4œòä øè0?i‹ª^J±*µ¼n#šIDb­å>Ü(ÈÆzòN=ë_É‹™å&ýÛ÷lݹϮ8Ï¥V½Ò༉#cå"1`©}OSó)Áäò0y¤À“O®´Û[‰,)#è ñV)#!‰"v¢(E€ Zz_A-‚–’–Š( Š( Š( Š( Š( Š( Š( Š( Š( ¨ŸøøŸýáÿ Š½TOü|OþðÿÐE>¹MkþIûÿ×Ëÿè÷®®¹MkþIûÿ×Ëÿè÷  »/øððÏÑ?ôšJåü~q¯ÄxÿUíþÛ×Qeÿú'þ“IX>/³¸ºñ$&”­²üǠõ17ªN™a€?‹“õHFÍÜŸeÔǧ,CËÑ~SÔÕø`ŽÞ0V5Æ2{ÒBÐçotË›¸¬Ä1gN@ÇçSÛø~O)RY•O¢ŒšÖžúÚÛ;›-éÜþFMfW‚"£Õ¸ý(Ø7,d[–…¦,Æ$9À8©ŠXÛ'Ì±Ž¬?ƱÞ{™ÖL@ôN?úôÅ· ùUÜÇדAVf»jÖ‰…¤>Š3ÿÖªï¬?ü³ƒìj²p2åP´qC}š!“!‘‡@£Š[ØMÅnÎvöWûc³nó ùÎzÓíäv',ä“Îyuì¼ÂX™ŽrM_µ²[pP[¹­y;˜{KìENÝTŸÂ¦žÁ¤Œ°^qV“ŸXÚvö4T]Îv8öÌ‹pX+aTúRµ’ÚêžHeÚ[iœ*ŸSÊ’€psŒVŒ 0ö$ñRÑq—CxAæK#Âé-¬c™è~”Éà_ÝìxسÁ¬xÚÝw6éTž6¡ê>µ<7yãŒgjž¤òi(¦7&o±8\ªàÿ°ßáG—:qºáqþÓTpùÓÒi“îÈßW³'ÛwD¾m–âOÄÓ…ÝÒã÷Íÿ|ƒLûeÇwÏÔf”]åpðÄ Röl~Õv$û}âÿËE#ÝOøÕ½3P¹“T´W•i=ØU/´[7Þ‡oÑYÒÞØê¶b0àùñã¡þ!K•¡©ÅõRÔ”%´PQKE%´PQKE%´PQKE%´PQKE%´PQKE%´PQKE%´PQKE%´PQKE%´PQKE%´PQKE%´PRÑEQEQEQEQEQEQEQEQEQEDÿÇÄÿïýUê¢ãâ÷‡þ‚(õÊk_òOßþ¾_ÿG½uuÊk_òOßþ¾_ÿG½mÙLJ†~‰ÿ¤ÒQ«Æ^ýqÿ<Ç?‰¢Ëþ<<3ôOý&’«ø–ìÁr¨KDSɦ&U¸º‚Õ  Ä¥c]_Ï6í¹Eõî ÞÓÈZC“ØÕ*@ÏÏÝ^ìh %«#P’*²® ûšž+Y6åˆEþóqL7Q[dB¡˜ª“]K)Ë9ª6÷3•T´F‰kX:³LÞ‡Q˨¾ ÄcØVo&¤EýkUŒeQ¾£šWå‰?9#.à18Ï4ª•<@näã•j&NE¸Ò4ÀÚäŽù©J¹À ‘þФ‰¶µ>µ!v-´sŸJMF‹}ïʬ 89ÅF² ßtñß"’ݸ©iE•® ,œôþºÃ¾Ó˜¹ ʺR# öªòÛ¹fõê2pihV§ ö¬‡æTö±,m»’Ã¥i\BÄêØ'¨õªÈ¥ qMAºfKf¬Ç‚ÀmÎ}ª‘G=ªU8`TTУ%ri P ¯9éP’¸Ölëâ?ýS7©þ,g½M¥ƒý±eÇü¼'þ„)·¡šVg¢ÒÒR×9ÖQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEDÿÇÄÿïýUê¢ãâ÷‡þ‚(õÊk_òOßþ¾_ÿG½uuÊk_òOßþ¾_ÿG½mÙLJ†~‰ÿ¤ÒVŒ]—ÄQm<}™Oþ<Õ»eÿú'þ“IUuýîÿWK˜aÂï¨ËncŽO¸¦#‰$ó¦ùW²úÕk«ç›å(èi\ø\òm ócÿâª!ám`õ´þÛ'ÿZÅEu0›“èdœS•}k\x[Wòè?ïê(ðƯÿ>ƒþþ§ÿV¥æN2} ¬c¥K—85¤<3«ç›eöÕ?Ƭ'‡õT}™@xœþµ\ÑîG$»{Çjš/‘Áÿ…h·‡õ2r-ÔÛEÿQ êc­¸?öÑ?ÆŸ4{‹’]ЍêòØÀõàÓÝÆ§a×ñ«'BÔN¶\ã©•Æœ4=Dø÷ñuÿNQî5v*nÁ ½©êØÂ© }êÑÑ5"ÜÀ§þÚ/_Δhú—FµþÚ¯­ÑîZŒ—FUÆâÊI'®ýU•#‡%ê i ýpVÝ=Æõþy¥}÷iÙn3êYyýj/îU¥mŒ 7‚A“#Öª2œç$ãÚºÐuS‹a»×ÌOñ¨_Ãz–2¶ê}¼Åÿ¾h÷1q—fcÄ2A'#½HÛx,8ô­áÝ\ ýg?óÕ?Æœ|=«ãþ=TÿÛTÿNQîRŒ—C4²… „AMØT¤g¸ÈþU¤<9ªí Ù¦?ë¢gÿB¦Ÿ êáHcþþ ?úM×s[Iô3ñ¹¡â§ÑÉþزþ~#çþ*×ü#ZÇ{CøÌ‡ÿf©ôïê°jVÓËm¶8¦Fcæ¡À =hm[q¤û½-%-s!EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPTOü|OþðÿÐE^ª'þ>'ÿxè"€\¦µÿ$ýÿëåÿô{×W\¦µÿ$ýÿëåÿô{ÐÝ—üxxgèŸúM%mV-—üxxgèŸúM%mP ¢ŠZ%´PQKE%´PQKE%´PQKE%´PQKE%´PQKE%-PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPTOü|OþðÿÐE^ª'þ>'ÿxè"€\¦µÿ$ýÿëåÿô{×W\¦µÿ$ýÿëåÿô{ÐÝ—üxxgèŸúM%mV-—üxxgèŸúM%mP ¥¤¥ aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPTOü|OþðÿÐE^ª'þ>'ÿxè"€\¦µÿ$ýÿëåÿô{×W\¦µÿ$ýÿëåÿô{ÐÝ—üxxgèŸúM%mV-—üxxgèŸúM%mP ¥¤¥ aE%-QERQ@ EPE%´QERRÐEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPTOü|OþðÿÐE^ª'þ>'ÿxè"€\¦µÿ$ýÿëåÿô{×W\¦µÿ$ýÿëåÿô{ÐÝ—üxxgèŸúM%mV-—üxxgèŸúM%jMymná'¸†&#!^@§¼ÐÔUoí+ùþ¶ÿ¿Ëþ4á}fz]Àíªÿz)†x‚2¨P-¸`Ò][‘‘rc×p Céj?>ùëýô)|è¿çªßBŽ¢›çGýôÿ¾…h€É•ÿxP!ÔT/{jŸ~æúÈ7ûBÈô¼·ÿ¿«þ4\v,RÔBêÒxÿï±A»·Q–ž0=ÜP´U·YÿÏÜ÷õÆ·YŸùzƒþþñ  U·YÿÏÜ÷õÆ¢}_LŒáõEÿzeÖ€.ÑT?¶ôŸú Ùÿßôÿ’ NÂáÂA{m+ŸáIUèhÝ”PÑEQIE-”PÑIE-”PÑIE-”´QIE-”´QIK@”PÑIE-”´QE%-”PÑIE-”PÑIK@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q?ññ?ûÃÿAz¨ŸøøŸýáÿ Š}rš×ü“÷ÿ¯—ÿÑï]]rš×ü“÷ÿ¯—ÿÑï@v_ñá២é4•âU?ëˆÿК´l¿ãÃÃ?DÿÒi*‡‰ÆuDÿ®#ÿBj™ì8îc‘Ò¯D>AþíRaÓëWã(ÿv²‰lÜ»ñ-¸‘Ä?•a)xùF#ùV¾­!‡H»eê¢!ü«›QÜvºþ8­ˆW5#½$\{Š—d2°u XäUdeM*¡RJ’µ ,´$|Ù÷¥òdÛ”GÝÏZb\Ê™VÇr)ÿm˜ •>{«Égr§Ù'ýWê)>É?üó?\ûl¿ÜOʃy/÷¢ÈÒì­¼ÂU/mžjÃ,Ź GlQöÙ;¢Ò}®Oî/çVšDÉ69`gFYíJÞØgŒúžMBóË!ÀùGµF#ç$ÒnîãJÊÄïvLj׿ !ݲìMC=ìÃÕ½*›jsHØŠ?Ò“óäi„õA‘ÍdhO€Hê¤ò+JÒo>“çúÐŒ¹Rªø¬ ë@ÜJå·žŸt×IÞ•žmEí½³LÛV<îút¦„Ì‹;/X_.êßç©®‹KX­¯í"·Q97â*6`b…B ãŽ*Å‚,z…®â2¦=OÌ*„v‰¨KpòÜIo+ Ž{ktˆRÞb–Î=™Gæ+n¢KhQ ”©3æËg9çßò£¨Ì±¨^™E¦ëq?Úš1¶cËó3·vsŽ1º™§}r>ÊŒðÌîάêLnåÁŸó×Z[[y£xå·†DvÜÊñ‚ôÉ©à~U ‚ TˆB‹„*œdAÀãÚ€0eÖo"$hâvž(¥ˆ(#ËÞÁpİ ß—ðëVešC`[UIc•&Ú‰o)å$| rA$ôÝÛ5¦m­Ê0DPÇåí(1³û¿Ojˆé¶±´0©Ü#0.Ð}qŒf˜ŠPý­M´žf3¢´ÓÙ8QÂ’:òÊ® V‡RÕ$·‰÷Yn–Ëíkû§ÀÆ2¿{œîñC[0Ú[[±0A'—µ.IÀÉ4å·…B…†0y`'÷G·jLhȃQžiŠA²&¸¹ ­(gT~™õzýV÷S»µ78kb,áId Œ Ù'„ù¾_»ßw'¨Ö–ÏDöдNAd1‚¬@d{áA³µÌ$ÚØxˆ˜×÷îñÇáLFmäÓ™äGqWöÀo`2dRÇ‚;2ÌSb¾Ô¥š%V´U¸žhS÷LJl-‚~o›!O}{Vª[ˆPF¥Kù˜?6[9Ï>ÿ–)Ë JT¬h ’Ë…œ‘îrr}é&½t–ÑΑ£Ñå6p2åxbãÁÀ ÕjçR¹K–ØÖâ$½ŽÔÆÊw¶v峜tn;g=«A´û'*^ÎÙÊŒ.èTàuãsPË¥Á> —³i‚Ô¯O›nî¼ãv)­À«e¨êW%…º}”É"díJ’NòNHé´c=x¦}¾ñì.b¸qñ ư”òÚCµNw0ažã jýŠÓíãì°yì0eò×yíצG§YôAk !_Ì$`€Hz÷¤2Œ¨¯ VSÜcek†i™‘ÚT»›·êjµ´ó}¢Úq<¯<÷7ɕڡðôÚ¼Žy÷­“§Ù5ÏÚM¹Ÿ!¼Ó—Èèwc4õ·'i’–giì=ÏZ:çêH,e»š}1î&mÆB’ ¸eRp¼³Œ =ªH%º¶†þØÈË;,+ý¡¦ÒeAÜäžHè1Æs[ñÛ[Äd1[Å”î}‘€_ëëQÇag¢ÃkJ¼,HÆ2@ë×½02e’Dº•Öâo6 ØmãŒÊv˜Ø&r¹Ã¹ŽO<{RÛ^Ë/ˆKö¸ÒHæQ Âê€+.ä`“óôß“-p. Ô`JPдóBŠ\Èûà~T 2uAç\B–sOöÙ0ɲf ƒË²ƒ´ŽÜƒž‚’s-¦¯ö™Õ¤‚iÒ(¶ÝÈ d¨\þéÉõç8«Ï¥éÒ2iöŽUB®è@8àT‚ÎÕnÒÛB.üµò×§ÞÆhWšGí¤{›a·˜•‚AÄþuZmVhõD‰T=±¸[v;!Ø÷‹äõñ­‹K½¿jµ‚}¹Ç›¾ÜõÆG‹cf®²-¸‘@ Â%Êã¦;b„K˧½{{ͨä;Gˆüȃî!¸#ŒÍQ¾¹žÞâçMY¥2ÝH¯;–6¼Ú{mÚÄzn· ¥µ»»Ám M'ßhã [êGZyŠ6‘e1©‘ ûAe®lÒ‡±¨:Kù­£}˜Í@Œ)ñaÏ' Œt©Q»†[Ëy&·’X¼C ;šBF —öù‡­i­ª4¯ ¼0É0!äŽ5 Ùõ8çñ¨,ô{;H%„F²¤ØÞ$: ª¡{žÔÄRS¿žË|P ’+†Šb#ÞT(ÎBç¨ qïZ`¥îžæ3$±†DZ2AÈç#óÍ#iÖ2B!{fˆ6à†*1œc®*i!ŠhŒRÅ‘ :‚¤zc¥&3 κ“EÑÝ®B,¬f(\l'—äŒ9Õ‡½ðŒÜOdh¢— Ó36äÜ;ˆÈëœý+El,ÒØÛ-¸ŽZ!„'Ô®1LºÓ­®m¾ÎÈ#M†0bUPõQǃŠ`P}Nå.î>ksQAåm>aœçÕ½9Å-¾¥u-Ý f·ÜÏ,B0§z É9Á9_AŒ÷«ñéö±ÝÉuä£Nï¿{(,„¨\)Æ@ÂÔqivñê-|Iy²HÊ"‘ŒåTÇ“@‹´´”´†QEQEQEQEQEQEQEQEQEQEQEQEQEDÿÇÄÿïýUê¢ãâ÷‡þ‚(õÊk_òOßþ¾_ÿG½uuÊk_òOßþ¾_ÿG½mÙLJ†~‰ÿ¤ÒU/ êiÿ\Gþ„ÕvËþ<<3ôOý&’ªxÄÅëÿК¦¦ÃŽæ3u Ÿtº*ƒýáWÔqÿ”M£­‚t›°­´æ.\‹†NZu8®ÓSE“OºVm º þ5ÍËa& R{V­\Í;büDxBž š×²»[¤OÍYÏléq™ÆáÔU»UXµK…EÀ88ãŠiX¹¤ÚXŠŽI’5˰QïRõ|zÖWÙZòúí2ࢃ€x¡!6Y}F0p¨ïøS?´€ëb²¼×ŽFBdÊœiÆå½dÿ¾©j;#ao¢n¹O¨©Õ•†Fõ…n’_N Vp[¾sZZu¼ÛþðI<žôXu×hÈ‘©þR{â¶[>•…A¢¿ù2ùã‘B@Êâuc“Ï«rF8ôQùÓ­´Ë©p|¢ ÷~*ôz2õžø ,‚äPÛ«é3Í´Và*Þ“Íë÷Z³o 0!Ž%`„å²zÕ‰T.Ð6PãÔUYUÌÅ{•iʧڱõçW(†};ИX²÷ Ûý{ ¯§ÜI6µe´~ÓKÛ†qTÃHT±R£Õ¸©t‹·}jÅFÞn#ý¡I·qÙ“QÜ\Ãk’æxá8/#…™©*ý´ÒËk=¿–Ò[È[dŒUNT¯PÎzU’êÖMn“Kq #:§"®ò¬TãžzSÿ´-EëÙ™‘gUT =?"k)´ká§Çl²C·lÁÑf’$Ü•?(Ë NK.“s$AæÇåÜY%´¹·+(n@ÇÌïQ@–×v×h^Öâ)ÑN Dá€>œQq3ªc¶šá‰ÆØŠçëó?Z¡oa*E9–ÖÝ¥“ËÈ{™fç’ãŒdjÆ­ìöÂ; 0óä(vwÚB¶¾8¡ˆûb† ‚iÚdihå Ã’Ž¿LÒK¬Û"‡TšXD+;Ê€mŽ6èÍ’cÓ'ƒQ›¨þÍ%¤VÑÉ ˆÈÛX‚m¹$m@ÎO5š,énÖ¶ÒDašÕ-ew$2…ÈÜ œ†<;sL ’jÑÇx`0ÎTJ™@]¡Ø£®ãÔrÕ‹»±l#9%’WØ‘ÇÌØ'¹ '“Ú³¥Ò®Uû@0fIà“çFŠcQŒ`à÷xðjÄÖ3“ ÖñÛ$ÐÎÒªd…pÀ©ÜqHlô<Š][bÞßKû{¤…90£ÌÜ3¹qž£<ö5vW) :£¹! ÇØ{Ö=ƃ$ÚkF.Ù.LS—o–ZRXƒ¹IÇ8ÈÁÅ_h'ˆ;°¼âM/ Ì3Ãm_»ßÊ€":Â,3³ÚÜ$°:#Âvn;È ‚o9õ«Ð»Éi!’?ÀåKûä‘úÖeµ…ÊióEukgq4ŒO2Vu”÷-˜þ\```ô«ZU›Ù['ÿxè"¯Uÿÿ¼?ô@®SZÿ’~ÿõòÿú=ë«®SZÿ’~ÿõòÿú=ènËþ<<3ôOý&’ªøˆgP_úâ?›U«/øððÏÑ?ôšJ­âAëþf¦¦ÃŽæ3˜V‚ýÓþèª,>qZ(9ǰ¬¢[4µGXì®70Pf'ñ¬_½Ê0?îš¿â–UÒî7ÿõæ¹–4;ƒ:‘èkVìÈJèßg{ûJ‘«)P¡5Š57~Y½›vÂýî[nȦÁ«„©ƒ#xÁ#ÚŸgŠY®å€ãÜV<“4ÁÜ ÕS=…jÄÌÈTgsFÄnUm&vs3͜ԧ@óžžux£Ê…faÁíô"ƒÐæ†íÔ´›èMi¦ •¸ŽB̽t©Y‹&qÆj°Ö¡aµÁCVT‡±È ‘–R¸5a¯*¯”¬p\íZ ,'ªÜ“޵•,²ÝˆÚ$Á9 gÞ¡Ôu+ˆ®ž5|(éŠ, Sp¶\à{œ ®÷¶Ñðfú/5€o<ÃûÁ¸ûµI ‘áFâ€G½MßAÙu4ßSòÆ?ïT¶w“\JâfO”{V‚IîÌ Qñ„Î*m"VKçŒç… œ`dúƒ·Cn‘;:ƒ•>õ™¨ÀóÈ©¢<õ$žqô¨¬gÛ¬L„ðÎjû3‹Ô ÑÏÓ#üj¬Jw9ÉZEvW,ÄxÍZÐÉ:îŸÿ_1ÿèb¬E£<²šL ž$Ö¾••ž¥j‰·Ì2 üÌNáùQaÜíê¥íÓÀöñCI4îUC¾Å‰'CVê›Xn•Vt'knVQ”ú†ÔôªŸ}«µ„в@…V˜#;ã<&1îÅsŠ|š¤Ésp¦Ù|ˆ.Rݤó>b\.\v.;ÔÒé63ŒM ?ʪÀÌÿ8ÜüØÏS“HšM¸½žî]ÒI,ÂP `ª¨\á°W ‘Æiˆ§o©]m·{¥EW»š,ÄÙʧ™Ôÿ`t9?¥/öä©jóMf©›CwY·EÇ ÇÊy£žµ}4ëXæóR3»Ì2€db¡È ¹ÀÎãž;ÓH°Ž)cK’T1°21ùU\Ÿ”{ RQ!¾¥ž­š!mŠ@Áƒ’$/##ùÓïîå¶{hà…%{‰ 4›ü¬Ù'ûµ,–<’;¡ß @Å];I*8>¤Ó¥Ž)&ˆÈ’2]>lpTœwáçLE+]PÎÑ«@´r¹ùó†Â8ädõãéTΩq.ÙQŒI"Y8LÛæHC ãž8ÿ Òm2Í•TÂp¥ˆÛ+)ùÎXdOn”Ÿc°FŽˆ®V5 œ•ˆî\ ó‚süèí%5%ŽFpŽ¬Ñ®ÉSŒàúpE:Š)h(¢–€ŠZ((¥¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ¢ãâ÷‡þ‚*õQ?ññ?ûÃÿAúå5¯ù'ïÿ_/ÿ£Þººå5¯ù'ïÿ_/ÿ£Þ€6ì¿ãÃÃ?DÿÒi*ÿÇúÿ×!üÍOeÿú'þ“IPxƒþ?Óþ¹æjg°ã¹Žß}~µ£Ëî+<Þ/Ö´館‘lO’t·Ú~ýÒç\í¶—$ËŒ–箯[„ÜéáUK7ÚTïƒPyÚÚl0¼³zž+{+]ìq÷ÍØ‘ÑIÆ¥_Óáû.¥, ’0 ’y5¥ªB’ȸÆüê·Ùü»ãq“‚»Jþ9¤†XÔ!é»”UÔõô"­é.˜ïXWK¦ˆÈè«Ëü c½#]¤Q Þ`Α¿Ï¥2nT¹ ·³åÏqëRÛή…$.ÊÚ¬Ü ÑuûLq¶r¦ RŠz‡33eUÝp\ózúq]-³ƒ¤È­Ã„n½zVQ³@§¼Óo1˜ÆsŸÂ“ƒ™“iˆd˜îÌË€GCU. Ž}q‘ðSiãÖ©††Mí,nuuÀÆqëZV#ys7…ÀúT²‘›ihóJBŒáˆÏ@+lèÈÐ:¤…ea“éKŽ= š´š„m0[aÝŽ†•í°ísxÞ™^a‡~ Ç#Ž´ûu)3Iœ«wë] Õ´W‰¶UÁÇÊâ°.m®4÷8©íØÓµÉ½Œ¡/—ªî7úÖýĆš@7c·JÁ¸¶.Æh qœ²ÿÖ‰¾K¨åxp¹¹4Á ’òiA ûWû©ÅK£ÿÈjÇœÿ¤Gÿ¡ ©´è?_åZz=ª¦©fÌü¬ñðHîôè5«‰Ù±ö“oæ~ü[îß§sæÆìgÖU½¿KIm‘ã‘üç(<¸Ùñò–èôÿ8¤Q“~·&Fû:ê9òì[<Í¡òsægþý³ÞŸsku%Ý̨÷ªMìj›$p¾QTÓ·=ˆíZ«}Ü|È’ ã̉Ð6:àü @ºÍƒ«3"3e¢u°$r9޽©ˆÎ[;™.Z $¾X#[„K '”)–ÎOVÆOcïLxµ4¶Ë{²ÒÛDó—Ä6á¿hÈÚv“ò®s[‘^A"+eãÞûf¢,ÝpM5îÄzŒvΛVH™ÒMÝJ‘•ÇÐçó¥°Ì¸mçt´ˆÏ{$-tÛÉIa`ž[pKûwc’zŸ¥2y…Õ”·+|J-ÄJëæ1¼^ìuGSÁÀÍ^²Ö­îc‰ŸtM)ÂüŒË‚~L¾6‚Ãç‘R¦­e%ÒÛ¬ŽdfdSå¶Öe° Œ`瘊:oŸ´èÿmÂÀ¸Û)yNyÄrƒ·ßsíWu„u†+¨#gšÖA*¢ ³ŽŒ w%IüqN­¡I]žXÄ)¹„°¼go¨ #éV`n#Þ‹*®q‰#hÏäÀ s"ÓP‡5Ìen†$VbX0V”|àŒ­X¼iÓPùÚôJ×Јʗ‰\Ž>\çv{þÐÔd¶ûOÚ>ÍÚ17Ëÿ>´‡j×ÃWÜRæ8œÌ²/—+*¤31Sœ6×oA"Í‹pÊq<¾r™9ù$åOÓŽ}«VŠ)i)i (¢Š(¤¢€Š( ŠJ(h¤¢€ŠJ(h¢Š(¤¢€ŠJZ(¤¢€Š)(h¢Š(¤¢€ŠJ(h¤¥ Š( Š( Š( Š( Š( Š( Š( Š( Š( ¨ŸøøŸýáÿ Š½TOü|OþðÿÐE>¹MkþIûÿ×Ëÿè÷®®¹MkþIûÿ×Ëÿè÷  »/øððÏÑ?ôšJ‡_ÿäÿ®cùššËþ<<3ôOý&’¡×ÿãý?ëþf¦{;˜çýjýkF1™?àB³ñ™WëZQÞ÷…f‹f£Ǥœtcõ®gVZ_!UI©­}nûû?HyFw´»SýìWö÷$’'“Z;ÚÄ%­ÍHC1Çz±3ã­c VEéSã¿’æM¥Ux¢:W!¹” §!‚‡R¬O=ª¶(°²,GLŒqN•CÜIŒý("Øp07oÇSTf“³±³¤6ëuÝlV‘1Ådh­òþ×Z×ÈÎ9éW„ˆˆùOÖ²ui < 9À'•l7òqXz¾O•ŽÅ‡ò¢[ ¦’$k ‹qg]§8ÀäéZzd¿¸@O ŸçY{W{F p¤îõÅ(2ÔE¸±|a~•›Ø¤šz Ê Þ½@eUêÀ~5’-o±¹á/\³TO¿ G‚O­gkšlt¶Z¬QÎ g€s÷k^EŽxÂJ¡‘€Á®Eqæ*3Æ»ZÛѯ¥´siu ’,eN9OþµRiuWè7S±k)ãky ó åYÖ±™®îòÖR¹ Üd÷ǽjk÷n ØàùcÌ\÷ÿëT÷Z|:”âÜv]ØÒ´Zîe{7cžšîíX¤ŽËŽÃ€jÞ˜H×´¾§uÄYÿ¾…N^ÝâZŒ(1¨¿2ŸFþ¿Î™§/üO4쎗1ÿèb“V-QéµZöÑîZÝá™b’ 7©tÞ§å*A˜÷«5•®ÞÉble]¿~AE$n[õöõéAcaÐR;õ¸i£|I" HáóÃ>yÆxãµEc§^™ Ü"ŠÔÚÄ'‰0%~ò«Ü/<®}(—RÔ¾ÑäZÇËG JÌ€“q<©i{ ô©¦Ô®c¿kHÆñ"n$)‡nKØäÏ©À±ea-œK¹™w•òÎиÆÔ‰_^§¿º¾š5;e‡Îh[p‘W$ °üT‘F¥y-ŠÊˆ#2 ä˜ òF@ϨϵUû^¨´RÇ 3ËrÑntÈ)å–ݵ\àäc¿ˆzhÑE~n"»K‡Û%¨gR#ä`|£±ÅWƒOºþц2],í¤•Ð² ?8a€CycŒªñëRÛê7—oµ¼2ºÊÒHñ³å¾Ï•wÏ^¼{Ò>¥r.Ûþ=ü„ºKSÓ½‹ùÎùº`ð4yÛ=Z™̶rÖþF §È;ŸæùÉÇ=3íV¬ì.,Ò4K•+çl!BíÆÔ¶9õî~•I/nî/¬å!’yD›ƒaÇÌs†ägã­E©|º‘åÁaË««»9!²7ã…êsøÐEEcÜêW)rÂ6·XRö;S©Þs·-œã£p1Û9íMµÔî^XŒG-ÌÐÕHeÙ» Nyáyïš^`mQXPjZ„¶ö…¥²æ´7D¼m´`/Ë÷ºüÝ{z³k¨\ß΂*ñLë"fßžÆ1מ½)©KXÖZŽ¡urX[§Ù ’&NÐT© dï$䎛F3׊lZ†¤ö’®ÄkäòËÃäòÕ‰Éåñ'CŒœR·IUôùþÓf’ïYI˜ù‚6’HÁëT¤Õ&Pk"#‰”ƒ´ãÈÛ¸±ç¯ÊËõÅjÑ\Ûê÷SØ_£§ì-q¨¾[mÁÁÀv>„ƒíZêR£L?t _En ç%\&O^¿1ü©ˆÔ¢²4ûûû»¼›t†IŸ”ÚH뼓’:mÏ^*}RY¿á»›pŽ_³»f)3´…8ÃqùÒæ…ÏGsqa=Ä,JÊñDb‹Í{¡¹˜®råH$18ÎzÔÑêwóÙoŠEpÑLD{Ê…È@üõŽ=é‰3nŠÃ—V½špštI:-¼sÊH=7:•uÃuüÞ.¥“&òWíÅ,ܳnÀãíÓ¿^i³E`&³y ‚\Ü,™lMÚ¤hSix$“‘óxÆ+GLžþ_4^©¦7P«»9ÈÀw鎹ç=)Ø ÔW8ÌðØ=ê\\}¬Þ¼h­3²¸óŠ„ØNÞœp8«Vp¥ì2Ousp&ÉT¸tTʪíF9ëÎsÒÍš+'J†8羑åœù Še¹‘•WbžŒÄw<š“U–áfÓM©Vg¸?+HQ\ynpHŽ3ÐôvsJŠÄ²¼»Kù"Ÿfe¿10Ψ¾@`;NçëP½ÅÝüÖ¯ÊD»nGÁ(ûT®3ÇcÇ^=¢ÐÑ\Å­î¡g¦—I!˜CiÓùÞc4…ÃeC8ázôö«ÒêÑÍ-™0Ét% އ ƒ Á<îü)‰4V,åêY›sošÞIXº‘•p0ÓÜÕ‰µ±­nâUYn| 7äª dúšÒ¢²®n¯¢™-–{O3È’g•â`§i(]Ùy98ôª:ާwq¥ÝIGj©gÄ6íä¸?uÆ:àäúRÑÑY^\‹ù ·ò•žôÂPÎùòáÜt4ÅÕ/%X•ZÞ'Í$"1VòŸndc=y'ôµEWÓçk­6Öâ@Ë HÁz@¹MkþIûÿ×Ëÿè÷®®¹MkþIûÿ×Ëÿè÷  »/øððÏÑ?ôšJ‹_ÿõÿ®Cùš–Ëþ<<3ôOý&’¢×¿ãýëþf¦{;™ fU>õ£Ì ¶*€½LzÖ”ëÓþº ÉÌß’4X€8?kÿÙZ¸pØR î9àî5ÜøÒntôHcií]²Õ´l®U”«‚èk{ ¹ÃsÚ¯Y''¶Ê†ÎÂæêçì°D^g/¯þUÚ¾Œa"ªF.!…CÁ!€çêiX¥±Çßkà„Vkfg'œÔî#¶ÔÊdÉq»£“Wtv´]QRäm³`ArvŠv¸–‰¦Oo vò¢ÆU”1 WÁäc¦*½ëFoUíÈhB¬­¸`tæ¬"…$¤ÓÖ­=,.W¿A93þ­¹]Ý;zÕ'·ÿJš)¡W`¤…lpq]¾ÄeF«Gnãõ¬-z¹ˆÛŒ(ÁÆ1š%ª%nsVÚMÔòÁ²ËpS©š†Å ´öï*|¾hã?®ßO²¸¶k3&ð¸ùOãƒUn¬ÅΞŠ#Ex§Ý€,qÿÖ©qе«¹CSQil.<°7¢Êwðž£ë\Ã)R„©¹ÔëÖÒK¦[‚â?-v¾óÀÇ¿ãX‰n£Š<+ó7\ç¥B…‘nWv+1+µ‹ƒšÚJŒI#i IëÅ+i×D|ÌãµlÞÛÚÿf,Q©i¼°Íß§oçK–à¥câg’Láˆ+Ç·µt6 -¥”$«4l>ö©ižv¥›jÒD„3¿Â+¦›\¸¸m‘¤k ®l ŠµdŒÒrm£:îÞÞý7ÇGôö5§‡]zÁ Ì2ô?8¨>Ù:¼› ç$:Õ" ¥ÕôùH(«s Œ¡»‘mOJ¤dFdfU%å$giÆ2=8'󥢃B»iÖ.±«Ù[:ÆI@Щ ““Ž8æ“ì15ÌÓÊZf•<²$¨Nê:ùÍY¢€ñÆñž4hÊí(T#Ó”Èí- EHm¡‰U·¨HÂ…lc#3RÑLDXÚOŠ[X$Œ1pòNëɧ›k<\!óÀÚ%òÆüzÖ¤¢ÈE°œÜ hÇ“ ŒnÎ1œã=)ßf·ØSìñ(¯–0Pg NOõ%F]* õ½”–xÈ l@2½>m»ºóØ©mtû[FgŠóX¹2² çs#8Î2jÍ –v³F‘ËkÇ<´xÔªc¦S¥¶·žD’kxexùFxÃúÒ¤¢˜ýŽÓíãì°yì0eò×yíצ 6Á`hªÂÄŒB¡XŽ„Œ`Õš)ØãŽ(Ö8‘QaQ°žT~wåGæíÙæm‚õÆzãÚŸE0+¥…œaÄvvè²,J7Ô9žÖ¶Ï?žöдÜbFŒéϵKED--VäÜ‹XEÁë(Œo?ð.´áo·û8†?#i_+`ÛƒÔc¦)ôRºiöQÃ$1Ù[G Ÿ} Øõæ‘´ë„Bö6ÍmÁ *Tc8Ç\Uš(ìín6}¢Ö L|&øÕ¶}28§ùÝåG¿výÛwcn~¸ã>”ú(‹ )·dQ®Åظ@6¯(ô=©¶ö–ÖªËmm Ç-åF?\T´Sìlâ¸7Z[Ç;g2,jç©Î3JÖv­sö–µ§%1)qøã55€ŠKh$†hš%1ÏŸ0(ÆüŒ‘íÅ<ÆŒP²)1œ®T§Èôà‘N¢€"’ÒÚUu–Þ)Fá£3 O©à~T%¼H"P¡‚…@6†äãëÞ¥¢€#û5¾Ò¾D[YØ0Pt_ ÉãÞ’[[iÃyöð˸‚Ûã ’:g>•-Ä·‚2¦8cM ¨Ú€mäé“A†bŒÃ·o—´mÛ鎘§Ñ@5…“@5±Š3¹»TúŒ Yìí®]^âÚ ˜}Ö’0ÄA‘SQLC<˜·ùžRoÝ¿vÁØÛœúãŒúUkÝ. È’6>R# ‘ÇÔõ?2œO#š¹E!‰i IkµB(ô`RÑE1-%-!…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q?ññ?ûÃÿAz¨ŸøøŸýáÿ Š}rš×ü“÷ÿ¯—ÿÑï]]rš×ü“÷ÿ¯—ÿÑï@v_ñá២é4•ˆ?ä ¿õÄ3SÙLJ†~‰ÿ¤ÒUj ÿ\‡ó53ØqÜÎýrýkJ#‰—ýñYÑs:ýjúœ8ÿz²E³+Ä¿l2FÖÓ2"å˜gúÕk‰µˆà’îÝgxäÀeˆ–n;ãµ\ñ=üQØ Q´Ï,€’G(˜äÕ¿ ëvv omÐ-½¹$œfº"›FRi4jévÐÞÜÜ$F;©cQå²mÚ c@Hý*^kmJêK…UGtVpëéZÚ»ËarcvY#‚§â¼îÍoµ=ZÚ6–I™]Xon©¡ nçIs§yâhÔº¡fbšž–é’*¬[FìŒô#üu_d·ÿžJ}È©1ò…QíÅ+ ³“ÃñÅ vÍpí”볎1V"ðü FÓ†ééÍ?P¹“ûQb·MçÉ99àsÞ¤ŠÝžM×W*ÍýÕ8ªÊÄ94ìY[TU³>= 'Ù2~f`OOZ·À )”’: Ë0_rh2ì¢@£,Bgž”=”eXµgM¿UíîbV;•‡ÍŒN;V©°ŽÒâ)Œ—qÓšÆQišE¦¶Ô½KIKRPQE”RÑ@Q@Q@Q@ E-QE”RÑ@ E-QEQEQE”RÑ@Q@Q@Q@Q@Q@ E-QE”RÑ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q?ññ?ûÃÿAz¨ŸøøŸýáÿ Š}rš×ü“÷ÿ¯—ÿÑï]Urº×ü“÷ÿ¯—ÿÑï@v_ñá២é4•SÄGš×ÿ¡5[²ÿ ýÿI¤¬ÿ¶ÝYý1úTÏaÇrœ-þµ|È©—rƒ’}e[¾g^{ÔzÕÖè>ÉÝ,‚£¨œUË“±¨Ýýºö[“žAÒdþPsž€;ò*+ûg´™mä6ÀÄwæ’ÙK’¾ü롞«ø–6Î •å¨ ¨ÆÎkÂ+x…ŽÝ‚TmªG@y­DƒK[E†"ȉº\t#(ð¬hoZS´IåìÎ9oðéSÌ“±¬i9AÍlŽ­Ø"=ª,r®%gìŽ*-fGŽÕ ¾Ü¾+Ü9ë#~tœ’!&ËPjÃS–]>Ô,BÎÜúÒǸßëfµŒg¼¼þ‚ªsÕ‰üi›Ó'8<úÑí<ƒÙ­Íxí®‚Ÿ2îзfù‰­3ìn\4Ú¬X–0?™¬Ñ4C øçOj^ÑÙ£`C®?´%_÷ ¯ô¨ZÊÇÌ.×·’ØÊØýUI—Ú”\"—´cöh¶aÓ;Å4Ÿï;æizbòºzªf©=ÚâÃ|½ÈëG;Dj†µrÂôUÿ ŽõÍÍ«À±¤e‡ CYÇPAüB˜úš÷….v¨ÇŸM‰Y¢½·Û&x’7Àü¨¦·²±‰\:Íå¶öÙl}:VÌ5bXªJ’{w¬y´8g?/<{Vü÷ÔÍ&´döú„W¹ÓlüÇßÎ1ï]\’°$±¸AóàÍršF•-„ÂL© qúÛÓf¸•W϶–5óc*ì¸_½S+èTunæí-%- (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ¢ãâ÷‡þ‚*õQòî$¸¸1$d ù¤ çbžÊ}hÕÊë_òOßþ¾_ÿG½u-Êõ[ûøßüMrÚÁÝððŸ[‡?ù¨·eÿú'þ“IPkúMåö¢³[ýAI£œ±î}ê{/øððÏÑ?ôšJÚ¤ÕÕ†Ž>- RŽu³eAç÷©þ5n-áu´›@¬Ì 1‘Iúõ®–ŠR38Ïxrúêá&³¶Þü‡>bŽÝM.ƒáiVáŸU·)_,ªw7àMvTSZckZt²ÚG`>XŒ{š]&ÂêÖԤȡ÷‡R­Š)Y^æ¾Ö\œ ­VßPºTØ7€rT2€?:ËþÊÕsÿÿù?ƺš(qL„ìr‡IÕçßÿ"'øÓ±õnчýýOñ®¶Š9Ps3:6¯ÚÔûjŸãJ4}cþ}Àÿ¶©þ5×QK•39¨ôMI‡Í$1ý_?ʦ_\‘óÞÇøk~Š9Ps3xl½~ÏøÓ×Ãvý$¸•ǨÀÿØ¢®Ìäðþœ½Dõsþ:èúb˺·ûÙ5jŠ,»ÙNòÂ/³l²cl䪌gó¬ë}6íX™" ;a—ŸÖ·h§`2m¬®R%óc»åÏëZRB­k¬edV {š’Š)h¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¤ «yO4W±Å3@í(Û"€J‰ƒƒ×éVj&·axå’&lgf>ltÎA¦"­œz†÷—Rš-älX``êIç'Ó°®cVÿ’r?ëáÿô{W^Ö¥Ás;)àgò\×+â0«à‰Õ@^J‡Úö_ñá២é4•µYV²Ühš3Á*DðCƒ|EÔæ¤¹{7¯jµäêŸóýgÿ€mÿÇivŠ¥äêŸóýgÿ€mÿÇhòuOùþ³ÿÀ6ÿã´†]¢©y:§üÿYÿàñÚ§Œ}¶Ó¡ñèýÿí¯ÿª°ü[nÖ¾ –)$Y\Îd,©´Ò88v:šb<õu ÔP«ypª£ ?:_í+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿ?´¯ÿçöçþþ·øÑEÚWÿóûsÿ[ühþÒ¿ÿŸÛŸûúßãEi_ÿÏíÏýýoñ£ûJÿþnïëPý¥ÿ?·?÷õ¿Æí+ÿùý¹ÿ¿­þ4Q@ö•ÿüþÜÿßÖÿl—×’¦É.§uþëHH¢ŠÿÙfotoxx-12.01.2/doc/images/stack-paint.jpg0000664000175000017500000002334011701011016016566 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿá 4http://ns.adobe.com/xap/1.0/ 160 304 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ 0"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑ´2MOy4Û7v¶‰™šÝ $ É'lé@`§M° ÝÙÓ'ô¥Ðÿä¦ÿפ_ú©¯-#¼ˆ+GCº9ï#zóÍCý¥Ð.Çÿ“ü)HÒ;tÛ´àâÝ8?•S]Fêæàéa’;ÄÏ›:T(Ç*?¼r8=;çŒë[[Eià íE÷É'¹'¹>´VM'GŠ6’M7OD@Y™­ÐRN*–ï Ôò†®ëßòÔëÖ_ýÕøCtùðÿÈÒñT$xfæUŠÞ-Y¢"DÄ÷è*ÓèúR£7öU‰ÀÏü{'øVhðþ™¥jšdö6ÞT;!o1›*CŽIô½7ú™?Ý?Ê„OØôŸúØÿß„ÿâhû•ÿ@{ûðŸüM.hÍoÈŒ¹˜ŸcÒ¿ècÿ~ÿ‰£ìzOýìïÂñ5 XIy3²Ü¼AFÐ[îç‚=*hr³¨7Ò`žyþ.•©­Ø^D¿dÒècÿ~ÿ‰£ìšOýìïÂñ5&’éÅç¶â#{sÎ:š·<3Ï4J쌭œ:Š\±¸îìPzQ85‰?õÁ?øšÏKS†Ñlºñ5 ökIxÀCcžzÒ5·Ú/'$ªz/SE¢‘ŸöM+þ€ö?÷á?øš>ɤÿÐÇþü'ÿWšÀ ÀÜDewõZ spÂ=ÌžY'p¢Ñ È£ö]+þ€Ö?÷á?øš>ˤÿÐÇþü'ÿN”Ç¿÷[¶ÿµÖ®46Í"‰U•sóƒMÆ(W“(ý—Jÿ 5ýøOþ&i¥£Xçþ¸'ÿW£´…–%.âIW#¦)°[ÇŽI™·3áBûôZ#¼Šmi¥©Ãh¶@ŽÆÿâhû.•ÿ@kûðŸüMM~ÓdúÿJÔ>o˜€…û>Ï›v)5“°]ÞÆ'Ùt¯úXÿß„ÿâi~Ç¥í-ý‹e´qŸ³¦?ô»¤Sî Jb€qL1”²˜oo–M¸ ;D/"§Ù´¯úXÿß„ÿâhû6“ÿ@kûðŸüM_{(~hÑßÍTßÎ0i·Bµƒpa!#n1øÑhö È¥öm'þ€Ö?÷á?øš>ͤÿÐÇþü'ÿV¬în¿ëI”±+<‚IpÆ1CŒWA'&Qû6“ÿ@kûðŸüMgÒ¿è cÿ~ÿ‰«3ÛıG,,ì¬ÛH=sO¸²D·2§š¥HÈ“þTrÀ/"—Ùô¯úXÿß„ÿâhû>“ÿ@kûðŸüM_Ph™ä2ªn8Æ)¶¶ , #—;ÎLqîsE ‘KìúOý¬ïÂñ4}ŸIÿ 5ýøOþ&–â3ï9ÚzÔyªP‹4‘£ý¥Ð.Çÿ“ü+;Ä:V›}$Zuœn°±VHqØ[¿òÔº˜¬ïÿȹ¨×þUÎlK¡ÿÈMÿ¯H¿ôRÞ­Ôˆ±Z‘ó‡”õEöϧoåYöwS[hZ*[Â’É<1FÈPÜ–Î@?ÝôïV¼Ý[þ|¬¿ð1ÿøÕ9ô»sf–ñ†‹Ë;£‘Oέýì÷>¹ë“ššÐÜ»T©Ád<7¸ôÏ¥Wóuoùò²ÿÀÇÿãTyº·üùYàcÿñª“V†K"öWt’À苜d• í÷?ô½ÿ¾áÿã”yº·üùYàcÿñª<Ý[þ|¬¿ð1ÿøÕE#Ý]ÞØ“§\@Ìdw‘£À[¯ð¹=Xv­ÿÔIþéþUOÍÕ¿çÊËÿÿR4š«)ScdA?éÿÆè@TÍ©|‹ÿúYàlŸün"ûþÖ_ø'ÿ­½¢2äc`¸03Ÿ,8p¿Ç·ϱõ©×Q*AãúkÿØÔ^E÷ý¬¿ð6Oþ7G‘}ÿ@ë/ü “ÿÔ·îRRC-]aIÆ « ~AÊŒF±œ…Îj/"ûþÖ_ø'ÿ£È¾ÿ u—þÉÿÆéóÄ\²-ÔlCGÃnÎsO7ÿ½vò—kŒ:篽Eä_Ð:Ëÿdÿãt}žûþÖ_ø'ÿ£ž!Ë!Ëv±Î(B.0W9Í*Þ$s‰"€ Æwg4ϳßÐ:Ëÿdÿãt}žûþÖ_ø'ÿ§Ï呲#Iº8ü±éœÕ§Ô•ÏŽ»Knþ•Ùï¿èeÿ²ñº>Ï}ÿ@ë/ü “ÿÑϲ$[í¯yê—{­ß]²B$·/8"£û=÷ý¬¿ð6Oþ7GÙï¿èeÿ²ñº9áØ9d2y¼éšB1¸ô§]\ý¡Õ¶íÚ c9¥û=÷ý¬¿ð6Oþ7GÙï¿èeÿ²ñº=¤EÉ"Ho–8ãW„9ŒåNìb£k½ÐËÏõ¿9éGÙïèeÿ²ñº>Í{ÿ@ë/ü “ÿÑÏòÈêé /—Ö=˜Ýúô¦5Ú½²Å$!™óŒ~Ÿf½ÿ u—þÉÿÆèû5ïý¬¿ð6Oþ7G<;,†ÛÜù)*íÝæ.Þ¸ÅJ—û^òóå)_½Ö™ökßúÙàlŸün³^ÿÐ6Ëÿdÿãt9Áô$oJĈ©ÊI¿9ý)ó_¬‘H‰Ã!›vy¦}š÷þ¶_ø'ÿ£ì׿ô ²ÿÀÙ?øÝðì²/-ÈŽy¦ÎÌŸ|ýjŒWаf…eE9\œGÙ¯èeÿ²ñº>Í{ÿ@Û/ü “ÿÒSˆùdVw ìÊ»A9v¦æ­}–÷þ¶_ø'ÿ£ì·¿ô ²ÿÀÙ?øÝ_µ‰>ÍšÿòÐöOó›â_ù5úàßʤóuoùò²ÿÀÇÿãUCVºšçúÊ\B‘I´d$…Áù³’÷½;W9°ëOùxgéþ“=lË,p¡y]cAÕ˜à Æ´ÿw†~‘ÿé3Õ¯ÊðhóIÝÁ“”0ûñâ€4¨®oS½ÔR]Zk{ÓX*2Eå++errHÏäjx¯®,nîa¾½3B¶‚äJcPÉÉ`i Ý¢¹›}böÙïEÀ¸•"´71ý¦4F8Ï÷;}y¥šÿPÓš)¦»ûRÉi,æ?-UC(`œsÜš×õ÷éh¬-çU–ê3r“½´±ng•#P­Æ6ìbH<õö­Ú-`NärÏ dTûÇäuu ŒOB sšþ¥u¦Ù‹›ea,’H(@Æ<}Õç€æ´´Y¦žÚÚkˆ„SO yP †ÀlvÈçð  d¼’Ȭ(€÷ôñË2³‡$ÀzØ{U{¨>Ò·1eŒ1¶ÒFÑÆj—‡?ä ¥oèÕD›„…±æ™Ä3"•Ž¡[4Ée½‚)Fc!›ièÌ1üÏáRê1 µiB$Ctg¾{Ç¥IC¨ ŽH®~ÊÊØë«6™Š}ëq0b|ç?ÃÏÞÁäŸ^( ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®wTÿO‰ß?ú":è«Õ?äâ_÷ÏþˆŽ€&´ÿw†~‘ÿé3Ö½Õ´7p4 ¾6Á#$t9>•‘iÿ ï ý#ÿÒg­Ê«.i(ºE‘tÍó˜^8ô¥’ÂÖYI! Ï’Ù$‚ž˜éVh¤3> ÎÏÌ{Xs#Fcýì®ãÝ䜥PÓ4·ÔÌñA$Mů ;±Ÿ½ÐqÐõ¿E1ì´»; ÚÆÑ’11Šè8…\¢ŠˆÂ7—ŽG‰Ûï#Ÿ¨ Štq¬{ˆ,Ìßy˜äš}QÉI¥ÜŽCAU'°¾•œÀ-ඉÒ(IÀ`ùúÖ…î+ ’$”àðr8 úƒM啤–Ivœ¨r0®­KE!…gÚh¶6r#۬ɰ’íçý’Øý+BŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Õ?äâ_÷ÏþˆŽº*çuOùø—ýóÿ¢#  ­?ä៤úLõ¹XvŸòðÏÒ?ý&z±âi¤ƒ@º’)7aÃæ¤4jQ\ÖŸx«©Ì,Î \Âøú®7üÝ3žÕ%¯ˆdÍà¸òæX-¾Ð¯/à;aúöäqLG@]C,7@O&–¹Ä{ù5Ý.Kï³ñJʰ†Êä/“Ï׊“GÔÊÒ`HbŽ;””²¨?.ÓÆ2}ûæ‹Íú+—\¼­‹x#3Í\I2&ÖƒƒÁ>¤ãŠè"mÑ#nVÈ+Ðý=¨ép òþÕ|ð»ºÇjØF+’Iî>•7ö\߸ÿ¿ïþ4Ë_ù Oÿ\SùµU¶k¨|Ct“Ý<ëöa"¦6ªüÄ` ëH ¿Ùp~ãþÿ¿øÑý—÷î?ïûÿbZÏsf¤×SJ÷²m–&l¦1W¶0:RÙMr‘éZƒ]Í#ßK¶X™²˜`HÚ½±Ò‚æ×ö\߸ÿ¿ïþ5ÛÛB.šy$Xáo¼ó0 »TòsîkR³ßkKrœ¦PHùHáPަ€+XKc¨¤Ÿg71HŸÃ+:°›k‡µ\Ì–ñHzº+ÄRa!¶`øÛ¼íÈ™ÎqIiÿvÿõÉ  h¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Õ?äâ_÷ÏþˆŽº*çuOùø—ýóÿ¢#  ­?ä៤úLõ©¨YǨYÉk32¤˜ÉCƒÁÏô¬»Oùxgéþ“=nP Í&Úòs,»Áxšœ ö?NÕ¾‹ RÉ$×Eáòœ©=8´è¤32×DŠÚæ¾Õu/¥"I\@zãŒöîMØvâÒÚæž&µ$Å203×¶_JÓ¢˜Œ¡¡¢Ú}ž;ëÄB\¹VLÈXäç+ü±Z6ðGmo G„QœàRQ@ÛÈVúâŸÍªÀ³Œj y–ó!ã“ùóPÉ r0fpèÊÅOæ4ß³Gýùÿð"Oþ*€m¢[[Ü$«$Ì‘h¡gÊFOR=ÏRqš-´Kkk”•d™’"Í,ùHÉê@ǹêN3Oû4ߟÿ$ÿâ¨û4ߟÿ$ÿâ¨B²îcóäBGˆ´ƒ‡ §bò*O³Gýùÿð"Oþ*“ìäœI’rOœüþ´RÂÈÙæ¿ºYdÆÕXÁT ž¸þñïéÐ{Ý´ÿ8?ë’ÿ!IöH{«‘èdb?"jj(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Õ?äâ_÷ÏþˆŽº*çuOùø—ýóÿ¢#  ­?ä៤úLõµ–ÿžgó_ñ¬[Oùxgéþ“=nPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üiÔPrßóÌþkþ4e¿ç™ü×üi$–8†duAêÇϵÛÏÄ_÷Ø  2ßóÌþkþ4e¿ç™ü×üj?µÛÏÄ_÷Ø£ívßóñýö)&[þyŸÍÆŒ·üó?šÿGö»oùø‹þû«s°Tš6'°a@ËÏ3ù¯øÑ–ÿžgó_ñ§S]Ò5Üìz“Š`oùæ5ÿ2ßóÌþkþ5Úí¿çâ/ûìQö»oùø‹þû€“-ÿ<Ïæ¿ãF[þyŸÍÆ£û]·üüEÿ}Š>×mÿ?ßb€$ËÏ3ù¯øÑ–ÿžgó_ñ¨þ×mÿ?ßbµÛÏÄ_÷Ø  2ßóÌþkþ5ÏêŸò ñ/ûçÿDG]9+Õ?äâ_÷ÏþˆŽ˜ZÈ;Ã?Hÿô™ër°í?ä៤úLõ¹@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ €})#%c\{d¶«•N‹É¿ÜOæÕÏØé¶Ú÷1„™o%Ŷ×@ä0éŠC:Ê+”Òõ OTŽÖßíeu´YžO-Y¤%ˆ1“õ§Åª_ê)¤¤w?ek‘/šñ"¶Jq‘¸Z«ê*½øÆrFv¡aì@⹓­êR-­šv–t’X#Mì#lp…ÎMkÚM{&…7ö„e' 9à ‘éH «÷GÒ˜ 5üA†@˜g×*3úšzýÑô¦)ÅôõÉÿšÐÚ+›ðjúþ¡¤žrZˆÄ01;@+’ØîIã>ÔÝbíôøÍ¶”÷(Ö° QFŽŠ9ÆâüãƒÐæ•À騮mï/ïÚõ­¬Vã ¶XžûãéL±Ô﵇¶Š;‘gþˆ³ÈÑ¢³;Fì€8ýiÛúûÿÈWþ¿¯S§¨R⦚pÒE"ãîäd~•Íßjz¼º…äzÎÆÓj¨Dˆ¬ŒTœ±Ÿá«ÚC³kZ»:íba%sÐùt!—mF#uGzưõOùø—ýóÿ¢#­Ë_¹'ýuýÖ©ÿ Ÿÿ¾ôDt5§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤Ï[”QEQEQEQEQEQEQEQEQEQE ^Kî‰üÚ©¾…¦I4’Én\ÈûÝZW(ÍêW;J½,))²èT1Lû"~oûúßãHdWše•öÃqJ ªUŠ=2¤qíR-•ª½»¬*¦ÙJÅ·€€ŒŽ©~ÈŸß›þþ·øÑöDþüß÷õ¿Æ˜ˆ%Òl%‡Êx>_1¥;Ç$‚GáR<1Ûi’Ã!63=sɧý‘?¿7ýýoñ ZGI‘±ÎÉ©  —î¥DDZÿ×6þkSS%‰%8%ÿ|ÿèˆë¡DTPª0A\ö©Î‘âCÏ-ÜÓèkOùxgéþ“=nW3g©hsèšl7z„JðCÂÎcdqÓÊ{‘R}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑQ\ïÚü;ÿAy?ðc7ÿGÚü;ÿAy?ðc7ÿ@Îý¯Ã¿ô“ÿ3ñt}¯Ã¿ô“ÿ3ñtÑR$œÔšç¾×áßú Éÿƒ¿øº>×áßú Éÿƒ¿øºè3óJðØÆïoçíø×=©cûÄxÆ7v9ÿ–wïNûg‡¿è1'þ ¦ÿâê¶©¨h±èŒwñ<“ÆÌC\ÛhX“ÐøPÿÙfotoxx-12.01.2/doc/images/auto-trim.jpg0000664000175000017500000011413311701011016016272 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí 8 415 658 1 2 2 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀa‘"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?í¡)¬òÑ)ÂÆIƧҜdOúmÈçý¿Â›mÆÓÓýÜÿÿZ¬dŽsÈéÏZvÐD&Dçwž3ÿNíÏéA‘=fÿ¿ þ×·)rbÕ'·Ë4Me™@ëò±êHäàñÒ #YM*ÏQ“\”Çrbݱ]ɼósÀ9úRº¿æ/ý7ÿÀvÿ ¨KL?޿¡Ó%i#p÷"ä«áfx+ž\Ïcø÷Í4´ÀG‘ùãåþ´»>ùüWÿ¯Mµÿ;_)—5NþþKYŠ,OÜ™žX޽³õ©c.ùc?9éòŽhòÏw9ÿtV,Ú¥åµÎ_¸ € n;á!¿Ù&¶-n༌½¼›†pÊĢЎÔï/=\ôçåÒùgûç=ÎÑÍ;š\Ð1žW?|ÿß"“Ê=wŸûäR\\Åk K<y$ÿŸÿ]SÓõk{Ë_9Ù!ʪ»€Ø W+µÄÚEï,ŽŽxÿdRy}>sÇO”SéALÑÍ!Œò±üG#ý‘þ4y]?xyéòŽh’xaÇ›"&zn`3T#Öm›S’ɘ»²PAW>žÆš‹bº[—ü³ýóÿ|Š_+Æ}Ê)ýñßÒŒÒ?+¾óïòƒšQãçêº)ù¨.Y8ǯá@1â.Á‰í÷E__ŸÿšºŒæLŒyùZ=¹Æ3ÏOOδá•f‰dPFqÁìs‚(jÀØžYÈùÈÈ(ò²>ùôû¢ŸÍÒÏ/¾óÿ|Š_/ÕÏ×h§sTî¯]$ò  ¹FYÈÉÐ {†Å“ï7ýò(òÿÚ?÷Ȫ0ßȉ¶ì'–P¯ÿZ´­mÁ;‘ˆÏ÷ϹØ2hòøáÏýò)üÑÍ7Ëõs÷E'–?ç§è?ÆžH$àT"ç÷ªË)ÃÇÓš™TŒmv$®<Çœ|çþù¦3ýóŸ÷E?¶x£4û1õåŸïŸûàRygûçþù%G,ÑD7K*¢ž„ž´î–à݃Ëÿhþ*?Æ/<ï?÷ȨlnÌñÆ'QΊv ô4¯¸Úi]¡<¿öýò(òÿÚ?÷ȧóG4g—þÙÿ¾E^z?è?Æ›wp¶¶²Ü8b¨7&°µ]_Pµ‘T€¹ÚŠ"iÆÛaŒÝùæ„ÿ—ŸãýøÑåïûäU-7R–êQouoäÎbórœùŠÑü(—þÑÿ¾E_ûGþùüŒÜÿúè$“@ÆyíûäQåïûäT  <ˆü³ýãÿ|Š<£ýãÿ|ŠÀ’ëYþÏ‚îËFibcksÁ+’>ÿjÏðW‰u-oR– án±Ç IˆÐ©ÜG¯NMäuþ_ûGþùygûÇþù%6Gع=;ÒnÉÜ:òÏ÷ýò(òÿÚ?÷Ȫ¶Ú’ÜÍ$q*ü£9cŒZu¦¥Ó²)'ê*}¢Ð¾G©cËÿhÿß"(ÿxÿß"¤£5dùíûäQåÿ´ï‘OæŽhž_ûGþùyíûäSù£šg—þÑÿ¾EYþÿþ:)üÒŽ´–þ´Sè  –ÿÃÿ^ÐÿìÕ.Z†ßø?ëÚýš¦ç <Õ­‰1m_j¶ÿky #ÈapF>P>þï”v2rGÓæµ>Óâe•Ù'dn…˜‚0 gäð~nyÅO­ý»ÜyWˆ‹?$£` ÃåëÔäzçÅ6™qs¥G§OtZÝYdF(ãoÝPè0@3ך› ·`Ó³\›•e˜º—VU;GaùVóPÂŽY$(^f„Î8þ•-P‡ZÿÇ¿ýr_ä*†· b¤SˆKoÛÉÁŸÐtô«Ö¿ñçoÿ\—ù ›é÷•dxoÂZ–—«‹ÛíEvE÷`·v!ÿÞÈ´ ‘ëÅ%/ÐcÓÚ“ñ £–ñmµóH·JæKTØú£ýãê}ût÷®~ÞÖúåVhm$•2~e‰ˆ$~èî‚EÁåq‚1œOz­e§Cc•lYbX(< úq[Ư,lbé¶îI§£E¦ZDêC$«/p@Šž”ñÉïÆOSIX\Ùhs~/´»¸–É­m¤›jÉ’ˆ[ìÆqô5Ìy7_j¿fo9ùxÝ‘Áöú×¥:‡É÷Çz«W²^ ›‰@CÉÀôô¼*ÙXÊTîî;M†æÞÂ(¯'ófQÉÇOl÷«4cŽ9Çz:ô¬[¹¤PVv±¼dŒ+!ÀÎ3ƒŸÒ´±Ma¸c€-œó´Ï #EoÆ[2,`Hû¼ûôíZúS£ÙÃå·sŒôüxÍ'Øï26F~eNŸçëPØé?a¾i¡œˆX6a ÔŸéßÛ À$årTliQE%…bjPÈ·yùXî "nS‘é‘[|úŽh¼äÚØÚxäœSNÂjç>ùŒ†™á…pW)ÁÎ:òÈ5Ò’r=k>]&)¢x\þî@L/óüªM2ÊK+fŠIüï›+òãhÿ?‡ó$¥rR±nŠ(¤XŽ‹"27ÝaƒTeócvÜÿ(BųŒãc±ÿ ¾À8õúT/iƒk«œã>þµ…z*¢*.Ã,¼,NvÂóïVhTªˆ¸P0t ãV&î-cÜ«É~Áä+ó $lR3Û9ã9­zŠ[hn ³¦Jr§ü»wúŠ*AÉYÉ\£§Z;,s\‚§åDO!±×?Ÿõ©Q¬( #?žAô©_o^ÔádRV’?õcêßú¥¤ýXú·þ„jÆ*õ¨þT­ÀÍ"ýçúåJO@{ŠÍ†édA&ð« †¿#ôÁ¨®¤‡!¤ž4SÆ~ïó§·‡t–<Ú1Ïý5ñüµ$žÑåP²XîUè¦G ~´Ð‹¶j±†|ä²O©©?Ž*zŽÞmmã¶·ËŠ1…NÀ>õ%!‹\ö­os¨BÖ×í¶œep8ùI,2OÍÓ§å]P¸Ñtë™^iíÙúì7qè;zRzŽ.Îç?â[i%– ‹RŒÌŒ§ =Éô­ýH~ÈÖÖî¹XÃ/N@ü:æ£>Ò mZ^2¦W9÷<ÕË =:6ŠÆ3e”ç”lîi*ÎPQ} QEQW?­Ã6 Æ;[ß³ù2ª·l€Uºã¶xÇÐ×B*…Ƨ]NÓOnÅØò|Ö\öèµ,8Ë•Üçµ[YçÖl¤DG;^è(Æîy9ùG_Lsí]“s°ËnŒ°¸PPð23í’@ö¢>Ò ™e=G˜üþµjÂÂÓM‰¢±„BŽÙ` 9#êjR±sªæ’ìY¢Š*ŒÊº _컢àå9äûf¹)5M`ؤ¿lV Ê…ˆç“Œ“œ~•Ú\CÌ- £*ã ëXoá…)å%üÂ-Ù csÔc?ŽiˆÏð\Í>¡y-̦Iš%ۓ«r@ý+°=k/IЭô¹d’Ie|î1ÓØV¡ëÇÖÆŸõ‰õ?ú ¤“îVÿXŸSÿ µ$ŸêÍ=¾ñú×%âíCT´¾4ùfXŒE˜FŠAlú•=«­o¼~´‡aºuëÆ*diJj»G›h³_LÖ %KUÃÈÊ@$ƒŒsÏÇ=;ÕŸ‡Ñu™N0ZÕÿô$­fð­á¶[eÔ!Ku91¤L7vcœ“õϵ\м=&“|÷ u™ˆ n>`sÿŽÔF-nÝ3ZZI¾vU;8<êG'ôíV“$‚ÿ_Ýa|¶bK{»eFÔl)p¹IãŽAäw©ÛZ[I/~Ø^B/š tP eˆ¼š† ZÅk-¹»vG·[u"%RŠ œpÍÓœsб.…Œò ¦YLÿhW1£r»[å<aŽüvÅ;ø5Ønä‰,ín® Äebª¿»‘†Ü܃À©ìµH/¤‰mÕÈ’Ü\d…SÀ_÷¸n=©°Y kµiå Uá·tÎIõZ‡@Ó_OŠêY£0½Ì»„LÁ¼¤ÎU28À%Ž=úÐI¨×1Ùèâêb|¸mÄŒG\ɬèµ]F²›Rµ‚;kÇTQ¥¤ˆ¿ÝÜÁÏCŽõ¨‘G6™3 hä·Uu#¨+ƒýj„G$ãP¸º·´*ÐBê ¼.â-ŽÞüœÔ2Ä´ñ¥Â,’ÃqkÂ÷4è‘–eÚON¸<ûTQø¦Î[wdµ».­Ø6©vóŒ6<`G|T:7‡dM.Ú=bi&xíšÚaÆ‘Çö«h~]²C%áG,RF|•F8%@É8š»§ÞG}ËrFѹŽHäPudTíüºu‚Í”Y¦Ž fbwn&§´³KF¹*åÄí1Èû¤€1ïÀ¤Ôl#Ô`Hf8E•% îÚC}¨eÁâóÅ5©º˜\ t6e]e;  tüGd—æ×˘ȯ䳀¸c>_\ç¶qz½qc²ÙÈ¿»KILªˆ );JÿìÕV-õW½†`«+ù’Gä¡;»ç¢€%°Õm串mÖOÞÚ­ÎJµ À ŽùÇÊy«ó›k ‹€ ´13€Þ f«ézLgÚŒ,ïö™ Ýu=²X©«wQ-ͬÖîÅVT(H€A  [/}®=5L9®\$ñ±ÉŒŒ†:ƒŽ=©`ñEÂJðÅrÁ#35a˜ Ù÷Ã`ûU‘¡Zý«N¹Þþu„~Pn‚`¨ÝôÉ>Ù"¡·ðòÛÚIiì‰'–›b@ñ¦FFð23éÏ^h'׋‹)l-e¹†âå¡@‰d,@ÆW¾3ŠÚÎ@8##88àþ’Ú $ÇgtöÂÞã϶ ŠD‚ ÝNæüëX %Ž[¦Ô‘®^ê^Y²ŽÖF”„ŠݾG'îzõ gñN»Ò§ŸUMB@ÀñÄcE0‡ žXŒž§Àc½3û€Ïw)¥[‰`ª¯*Îz€H_Nàƒ\µžõ`XnI3Aà òä‘s•S×±äŒU4ñ]³Æ² 7QÚеÀ>Zsœûý§_jµˆ‘^$¦îg·Šfž+f µ$läç n$zÒC C¼0‰åÄVOgœUÊœýF(ĺ½”Wvˆ³r +h ¸p}jÿéÅP]"Ï}£¼JòZ&Äv“ò…ù½xéWùÎI&€F>«{©[^Á’YÌ×,8Ÿvü6 ó©©b×-%»ˆ§XÞV†+–P#w\åTõþ‚F ¦Ë¥\ÿjO¦Ñ<¨±…0+ìQÎÏs×Ôý)!УŽé$7RÉo Íq± µdlî9ÆHä;ôÀ`ñœË¼Åqo“A#Æ’Pg=9ÁÁ#‘PA‚òi×ñ¢¤r»:'È÷XáùÐr;Ô‘x~4ŒE%åÄE ÁlŒ!Wÿ8ÿëÔ’èPËm<yÍk© ÏãšÒŽx%’DŠhÜÆpáX§ßÒªëW§i7‘¢»Â»‚·B}*àŠ(ÝÞ8‘C—eP }}jÛHo¬æ´¸Å2•luÁïõ  Z–°ºuóÅ4lðGh÷ W—ÈeÓþ´Ó¯[ (Öwkt%‹RŠdbT°ï·ç8â˜Þ¤ÿn¿šâi¡ò­‰¸ÉŸ_jšïEYï%¼ŽâXnKÇ*H -•J÷ûÙ ARÇ]f³Csoq=ÌÓΩh¥‚#–É 0žIã5±eu õ¤WVìZ9+‘‚;ËÖlz†(ZÚþhnây[íÜ$;œéŒp+FÆÎ (m-Ãyq.ÐXüÄç$ŸrI?SÆ(ž»¨Ë§¥Ÿ‘öp× yÉ «þ•N?D-CÝ@d˜Í$h-Ø2H º³1ÈžOšÔ¿Ó¢¿k_;-§ó¶‘ä¸#Óæ¬÷ðÜ ±ù˜L;[æ%DŽrÑàðA##Ó¶«â4þÍ–M*)æo%%3ª‘?.àØëè9«ÒëvÑÝ´Mæ8åX^à(òÖVÆœç<Ž@ÀÍEyáñr$E¼’çDŽå4"P½Â~•$º,rÞÉ'Úf[yfYæ·aäÇÍÔ#úp@5HÁ#¸¦Çþ¬}[ÿB4ìäçÔÐ?Ï<Ò‹÷Ÿê?•QÖ¯¦Óôæž–FÞˆwà³`ëWÀÆHɨ.¡žh [Ý›gÎCªã=0{ý(9õ¯²iiyuw ʼnk7B€~r ïÀæ¤mrÐo!em­\(ùü߸WØ÷ÍS—±:qxþq2³»ÂŒ¬dÆì)á~èÁ=rM\] Ùo,nwÊMœ" ™“hÂî¹l}iˆn™¯ÙjwbÚÙdù•ž7;BʪpHÁ$uqž¢µIdO¥gi:BéyH§ J?ÇŒœtÀV‘\ƒŽ¢†‘¬\ÞÁ<× n¾R3dr&Œƒ¬zu©­5ë;–…V)ci. ¹äp¥À8'<Ȩ§ðé¼y^ÿPšáÞ °j’NÍ÷G_ÊønÓnlÞé÷O(—ÍŠ5Ëe jŽ: oü%zx–Žà)U‘‰PHÍ„f³ƒ×ŒñVçÕâiî¬ìŒS]ÃuC ñ$màç·>é‡A…/RæÎAoµ?%]HA…Æ~ïdUÄÓí"½{Õ·Ež@;@À<`uù¿§o¬}²}2;XÕÅÜ q)'ýR?3¸øÕªf‘o¦Ü]Í v7/œ7HÔ’v¯ ÜÌZ€1tíZêïP¹ŠU¶‰!w_'{yØ\€Ø øÓ ñ¤»Á†h™%Š'V(vo8RJ’0OãKq¡Ë¡5þ¡4è‚O)h…7©Só“€xéÛ9¨­ü5V—vò\4Ÿj‰bÜ‘¬{Bç …ãvNsŠ.|QanÌ­òliCaWî£m.2FFìŽ9;OtjÖfþ+5™ K •[pÆ2¸RwÒª¿‡aE¶6³˜ä‚ g‰$órXƒüDäç×ëW³lŽ ·ÍÕ {¶„ƒž™Ïñ@¾Ö'ÕˆiÈ6aŒ“"a¶óÚ·vÓ·±ÆzgßÛéUôÛ$Ó¬"³‰ÙÒ=ß3u9bßZµ@èÖµ i¯ü6í ¬‘ÆE¾K»>€ÔŒäÕëj+I­£»µ¸„OµK7–|²Ç0 NsÜqN›EŠgºfž@ng†fÀèSüv¡¾ðôWš‰¼óöohÙÓÊRIC‘†ê¹ï@^ëo&“ª\X[̆Ì:¬ì¨UNîüǽhiú‚Þ£h&‚x ‰#™@l‘•<}ª”þK™ïg¸ºf{¸š¬J»Tœó¼xÀ' ­,–뛥v-:"ÀÈãó  Ûýb}Oþ‚Ô’«4ãëïÿÖÿ çƒÞÅo¼~µ%þ£qyw™onÑÙ°Wiå*dr¡ˆ\À¨Éõ­|äþ5©éŒ÷è×­o5ÁS kv×[ÇöR»"æ3œßÚ¢ÿ…¯zZß³þ4î#վξÿ÷úOþ*³/¿ýþ“ÿН)ÿ…¯zYÿߣþ4ÂÇ×½,ÿïÑÿõcl¾×ŸßIÿÅP-þD|:òŸøXú÷¥§ýû?ãGü,}ÒÓþýñ \Ý'ûð=¿úÔ»¤Ïð~µä_ð±õïKOûöÆøXú÷¥§ýû?ã@»ºBƒõ£tž©ùò/øXú÷¥§ýû?ãGü,}{ÒÓþýŸñ \Ý'ª~F—tŸì~µä_ð±õïKOûöÆøXú÷¥§ýû?ã@»ºOö3øÑºOö?Zò/øXú÷¥§ýû?ãGü,mÒÓþýŸñ ]Ý'û­&eõOÖ¼þ>¿ýÛOûôÆøXúùþOûôÆ€=wtŸì~´n“Õ?#^Eÿ ^ô´ÿ¿güiáckÿÝ´ÿ¿güh뛤õOÈѺOT¯#?µñÕmïÑÿ?áckÿݳÿ¿GühÖ÷Iꟑ¥Ý'û­yü,}{û¶Ÿ÷èÿð±õïKOûöÆž¸ Ÿì~´»¤õOÈבÂÇ×½-?ïÙÿ?ácëÞ–Ÿ÷ìÿzîé?ØýhÝ'û­yü,}{ÒÓþýŸñ£þ6¿ýÛOûôÆ€=p?ØýiKIþÇë^Eÿ ^ô´ÿ¿gühÿ…¯ÿvÓþýñ \Ý'L§äiwIþÇë^Eÿ _þí§ýû?ãGü,}{ÒÓþýŸñ ] 'û­&é=R¼Œ|F×ÏE´ÿ¿güiëñÄm÷a¶?HXÿZõÒz§äiwIÇÜâ¼­|mâ·û¶‘߆ÿ™|_âæéimøÇýš™?ØýhÜþ©úךx¼ÿË õÿЧx·¸ÓÇÔñ GÝ'û­¤õOÈ×ø¨õ}0À[üißð’xŸþzéß÷é¿Æ€ô,É꟭.é89OÈמÿÂGâoùï§ߦÿ?á$ñ7üöÓ¿ïÓè9—Õ?Z]Ïê•çð’x›þ{i¿÷í¿Æø›ÅC£é§þßãJÀz.é=RÒ±ùóƒâö:qúþ4ÆñW‹ÇHlOÐþ*‹éY“Õ(Ý'û­y‹x¿ÅëÖÖÛð?û5BÞ7ñZýëHGý°?ã@©ºOö?Z7IþÇë^Lß|F¿zqõ„ÿ0üF×ÇkOûöÆ€=stž©IºOTüy'ü,mû¶÷èÿ'ü,mû¶Ÿ÷èÿzîé?ØýhÝ'bŸ‘¯"ÿ…¯zZß³þ4ÂÇ×½-?ïÙÿõÝÒz§ähÝ'û­yü,}{ÒÓþýŸñ£þ>½éiÿ~ÏøÐ®î“ýÖÒs÷?Zò/øXú÷¥§ýû?ãGü,}{ÒÓþýŸñ ]Ý'û­&é=Sò5äð±õïKOûöÆøXú÷¥§ýû?ã@¹ºOö?Z7Iꟑ¯#ÿ…¯zZß³þ4ÂÇ×½-?ïÙÿõÝÒ±úѺOö?Zò/øXú÷¥§ýû?ãGü,}{ÒÓþýŸñ ]Ý'û­&é=Sõ¯#ÿ…¯zZß³þ4ÂÇ×½-?ïÙÿõÍÒ±úÒî“ýÖ¼‹þ>½éiÿ~ÏøÑÿ ^ô´ÿ¿güh×7Iꟑ¥Ý'û­yü,}{ÒÓþýŸñ£þ>½éiÿ~ÏøÐ®“Õ?Z]Ò±úבÂÇ×½-?ïÙÿ?ácëÞ–Ÿ÷ìÿzîé?ØýhÝ'û­yü,}{ÒÓþýŸñ£þ>½éiÿ~ÏøÐ®î“ýÖ“tœrŸ­yü,}{ÒÓþýŸñ£þ>½éiÿ~ÏøÐ®î“ýÖÒ±úבÂÇ×½-?ïÙÿ?ácëÞ–Ÿ÷ìÿzæé?ØýhÝ'û­yü,}{ÒÓþýŸñ£þ>½éiÿ~ÏøÐ®n“ýÖÒ±úבÿÂÇ×½-?ïÙÿ?ácëÞ–Ÿ÷ìÿzæé?ØýhÝ'û­yü,}{ÒÓþýŸñ£þ>½éiÿ~ÏøÐ®âOÊŠò?øYÿ­·ýú¢€9CþBWõÙÿ™ªµkPÿ•ßývæj­RâŒJ)pjÌ:uìÿêmeoø V£8Ç5³†ïŸýaŠ?÷Ÿ?Ê®ÅáˆñûÛ–od\:æ)pk²AÓcë HÚsý1W#³´‡ýU¬+Žû94ÀáR dû‘»}­E£êŸ–ÒAþðÛüë¶»ÇÓŠ(ÉÇáÍA¿Ö£ÿyóü³VÃÿËK¨ÇÑKWIô P xf÷î\ýTéáÛûÆfÿý+[b€3—DÓ‡X ½#T«¥iËÒÎ?Ä“ýjî8¦Ðqad:YÛþ1ƒN¶Ã¥´„kSfŠv! ]¡ŒÀ/—üóOûäSñHh° òãÿžIù ]‘ÿÏ4ÿ¾E-/XÌ1°Äà˜Ö–ÍÖÖõŒTýé(°šÂ͇6Ÿ¢â£:NžÝm} \¥¢Àg6…§7ü²uÿvCQ¿‡¬Û¤“/üÕ£ðX ‹} ;{¨æYÙ¶6v²Žkg§Ýý8¦÷¥ÍÉõ£>´”Pý? N´Q@?Î)3Kši¦ø 3ô¤£4? OóÒ—4”}?•÷ý(¤ è(üqúÑE.æîsø“LhÑÇΈßUEV{ 'ûÖ±~…®ZAk4bÞ=ŠË“Îk¥Çâ_õðÿºKC1(¥ÅH¶ó¿Ý…ÏÑM!‘QVÓM¾»k/⸩—EÔ¥¾>¬?Æ€3ñIZÃA¾ïå/Õÿ¤_]³@?ÿ Å¥ÅmÍžn#ü§9ët£þ@4Vÿü#¿ôô?ïŠ?áÿ§¡ÿ|S°84`úVïü#­ÿ?Kÿ|SO‡œt¹OÅMVÁðýÇiá?]ßáLm ðt0Ÿ£Ñ`2°i+I´Kõÿ–*G³ñ¨›K¾O½k'à3H TTÏkpŸ~ ꦢ*è"€Š\QŠJ(¥Å%Q@Q@Q@Q@Q@ EPCþBWõÙÿ™ªµkPÿ•ßývæj­jèúWöˆ‘Œ»2£¦IÍnCáûÇï“{3ãô[ ù7^»“Žý nð@9ë@™6¶ÖüCo{…æ§>ý=1IøÐzöüé€{P~´ž˜ã==è烃ƒÞ€ %/â?:CŠ8ížžô@$jb \JPyÇõ¤1(£Ó¶zR€úô÷ïLBçi®êøP‡räs@ Š(`ã==è'Œúô÷¦HÔ‘Å) QN88÷éïÞ?ÅÓÞ€šiÄã¡Shh=hô÷éïGP ã==è¢ÏaEQÜ^žô™È×§½.E˜ÇB)Iôï@€ñM&“®=ú{ÑØ^žô 3A¥8çºûR Óf’ŽÀúô÷ïF8ÏcÓÞ€ 1@ç>Ý}©s@ ¢”ö÷éüèíž1õ aŠCKzJ(£Óß§¿z3À=Oz)œÉnqÕ×?Z\jrç¦>Ô*$qÝP)wð\R8÷éïMϤ!ã9â—·¯ÔÓ}iy÷ü©€ Š3Môç¯OzLð­?ñ¤Í'>½:ûPG×ò Í&hÈãß§½ ädt==èsHM%.=ÿJ£Ž9ëÓÞ“¨È g·O¥Òw¥üå@,>éÅ4 =UOÔS³Óß§½ç==é]ìí$ûöñ¢â«¾‘dÿòįÑÍ_ÇÈÇ­>§ò  ‡Ð  ùs:ŸqÅV“Aœ«ž6ú‚+9ëÓÞŒd9ÏLsšc¹ËK¤ÞÆ3änì°5Qàš?õ‘²ýF+´Ï~>¹Á¥ê0r}?Ε‚çƒEuòÙÚÍ÷íãmÝCúUWÑm˜Œ‰ž›[9¥`¹Í`ÒV̺ ‹ƒñzU9tËȰZe=׿þTXw)QO1°;H úcšM§¦)Ú(¢€Š(  :‡ü„®ÿë³ÿ3UjÖ¡ÿ!+¿úìÿÌÕZî¾Ùµì×p´jmþV•ˆŽ dâÇo®GßÃáû(­ÞJÏ‘æÈWzôè@ƒÈÈ>þ•Ãü+›û³Ä8_8qÓ Ž¿íc¥zi ž¢„ ˇÃö1[´oæÈÍœJø.¹ã1ÆA¤‹@±Ž‰¼ÉKç÷’czäc‚˜5¯ž)Šb2aÐ,"…âa$¥óûÙÞ21ÆüƒI‡ì"ã`ò³g÷²mÞ¹¦ÝÁ­`sM?ŻÃö@ÑŸ6VlâW*]r1Æc# óIƒcJÏŸÞÈFõÈÇ:ŒƒÍi} ;Œ{Ð\: „vï %gÏïd#zäcŒ8ê2 $>±ŠƒÊÍœK&ÝëœtÂÔg}:V¡ïKzÐT:ŒP4l$•›8•È.¹ã1ÆA¥‡B°Šˆ‰&/ŸÞIëŸBvÈ<Ö‘4Ðh:- Â(&JÍŸÞHFõÈÇ=ùª¶•§Ú[¼n²LdÎeëŸL:úƒùVÜ®rk*ùðŸ0À9ÉÏ¥a>ojëÇ笙ýô§çN1ÆÜ ÷šÔ°Ó4ôµduy7nýä„^1Á¦A¬½Nvóa.FïAž¾µgKwhŒŒFÆÆž€Ð2õ¶“aK G—vy!ùà€æ K‰a,’³ç÷’¼gèíÜiöÏæÉ Â·$w«¡€ ¦"Œ„P¼dI+âIHÞ¼c‚üƒÍFš5„0¼[d™ˆ'|„n\ú`ùƒW¤˜.~nÙª\y’2ò9çߌÒ8tm>("²LÌ2d”ã#±Ìʉa W˜¸?½”ã8é€^yÒ¬yê®ß/ üý*tuuÈaTt+¡hÙ^flâIHÞ¼c‚LƒDZŒP4e^bÙýä¤n\ŽØvÈ5¥ši4·C°ŠŒ«ÌÏÿ-%#zñŽ0údHt;a’2¯3>y)ÆqЀæ ibŒó@ÌètK¡xØI37I%#zñŽ0údH´K¡xʼ¥óóÊFåϦ˜5¥ŠC@ŒØ4K¡xÙbù̲°Þ2;`ùƒK‰c /Y&/œÉ)ÆqЀæ h \P32-Ê(Z2²L[¤’‘½xÇ?0i Ñ,!…£*óÏï%a¹sé€üAü«I²4žhFÆ(býe•†ñ‘ÛÌHtkaxʼÅó™%#xϦ˜<Ö‘ÏJn8ç‹c G™›8’R7§à€éI‰c/#Ì_?¼•eϦñò­GzBsNÀgC£ØÃÆQæ/ÿ-%#rñÛÌʈ4k¡xʼÌÿòÒR7ÈùƒZfƒÅ> Æ(Lef9Ä’°Þœc‚¥h¶0Âñ”y‹çç•eϦñò­íH > ÆZ6F™›þZJFå㶘?•$5Œ0¼l3?Y% °ú`ùƒZ¤&‹gãÙC¡V™›¤“YxÇ~`Ñe /F˜¾~yHÜ¿LâåWè4X ø4{(atdi™ÿ夤n^;`ùƒùQe /¦gÿ–’‘¸}0üÁ«ôQ`3áÑ졉УLÍÒIˆ,¼cŒ?0hƒG²†Œ¡˜·ñÍ‚ËôÀþ þU~NÈ höQBñ´m1ã”ËÇl?0hƒF²†'£i™óûÉHÜ¿L?0*ÑŒZ@gÁ£ÙÁ¡F™›¤“YxÇ~`ÒC£YC ÆÈg-ürãrý0üÁü«G”X hö0Âñ´m1ã”ËÇl?0i Ѭ¢‰Ñ£iËgLC2ý0ëÏ úV†h¢ÀgÁ£ÙAF§'¤“¹8Ç~”A£ÙC !F˜·ñÍ‚Ã逿 _£X 0i0Äñ˜ÚbÿÇ)—ŽØ~`ÓaÒ,á‰Ñ‘§gÿ–“Ì¿L?0*УBßG²‚C›¤“Y8Ç~”Û}"Ê™ FbßÇ6 /ÓøƒùV…/áNÈ è4›(axÌm1~¯1‡°üÁ¥ƒI²†7FFŸøæ!™~˜ÄʯâŒQd4{("dhÚvn’LFäã`úR[èö0DÈc3–þ9°Y~˜~`þU¡·Þ’‹ (Á£ÙC¡§/Õæ °ã¶˜4iPÆèÑ´åú¼Ä3¦˜5~Š4…¾‘elN_þZLÃrñŽ?Žh·Ò,`‰Æg-üs`²ý0üÁüª÷4P}&Ê39n¯1‡°üÁ¤‡H²Š7FFœ¿Wœ‚Ã逿 ]æŠV•¾•glŒ9o㙾dãcô¤ƒH²‚6FˆÎ[øæÆåú`ùƒùUê)…Ê0i6QDèñ›‚ÿÇ1 ËÇl?0hƒH²†7GŒÜþ9È,? æ ^£4ì([é6PDÊc3þ9Hܼc¡Gæ $M”1²´m;8åæ °úëš½E+ÌMMXZ9­Öç#ïÎ+ôÚý+Œñ>§iÄ‹)1¢‰7°8rÇŽçn z)ÄxÕ!I&0¶Yöyû¯Ó÷ʯõ2C‹Ôâh¢ŠƒAh¢Š³¨ÈJïþ»?ó5V­jò»ÿ®ÏüÍU @øUçý¾èÆq çtû¸l~¸¯O+šó…hû}щ±ÎéÓkc¯ûX¯Q4 ^ƒ4­ƒÎiN)´Ä4ŒfŒqÍ!"µ0J\ŒT{©¥©)ô™ ×­G¾“vhùŒúT{©¥°=èÏó7ATµ/Èa( ŠI¤(à O9<Óf¸ŠfòOR6àÐ#”žww]û‹Gò–Ç\ð?ϽZ[…X!ß‚0$àžŸÖ“Y·û4å×îØb:#T­’9gH÷€q“À©ÖZ:ÛÙï¤äâÇùCPÕ% ˜‡ Ž•oÏ‚ÖÔ±ÆÐ0Ö²Â^H˳Ë[êßçõ«ÔÌ6…®71Ûò¿×­&›ª«j/Œ” Ï ÿëª×ìŠdS“|ÛõÿëšÍY¶Þ‡ŒmÝŒ tÎjXŸ.ï€J·@x5zÐåA?6rOn+Òâ7DLlnAÞµDí$‹\G#ð¡¢w<ÑUÐ;a˜c##Ö§\ã““T©½è'Ši Qpši¨Ä›‰+ΪKvÌÁAæ‹¢8¶Ú§ö¯»‘çô« "¸Ü¼Šhi s@9¥?-„Ð)ZÞôìŒÒ(3éHsNÈÅ%h¥Í%0ŠLS©((ëÒŠF!zž´(¦‰PœãÀÍ)rhg ýj­Ü…¢eŠA»Ñ¸ÇãJã±!Ÿ ¼Œg]õR@9Çòõ¬ûk¦7 ‰¶B¼ûzÕV\ŒØ>ÀdÿJ‘ØÞ·¹ó¤f*8ÃjÊȈU+4Š 8Â’Ò>??J¶±¬(rAŒgµUÅag”F›±’zS>Ò¡SwVéíT/®Ä(am¬AÜ}ꘞG(ÄŒ}€ÿõQp±½‚D,=x§†VèsXRÞ„WE$7D-­è†$$±=qJácb—šªo#†<ŒþtGvŽØ¯J`Zâ­B&öÓ­IšhCˆ£™£4~4”Qš/”™£š†ŒÑM”RšJ(¢Š3IA£4Ä%%S®ÆÉ K!…‰i64¾ÏÓ÷È^+¸5Ãxá`I\Àü¹F˜z>Çýòó¨–ÉÆQE™ ´QEYÔ?ä%wÿ]Ÿùš«Vµù ]ÿ×gþfªÐð¯Ï:•ϔ؈ç>îøö+Óóë^[ðÄÜ‹û“ Q í仆ǿÞÅznóBd»©¤Ô{©7 b¸¬i¤úÓK BÕApüi !jBhQšLÓsLwši4ÝØ¨f*±f )jw"bqÁ¥a‹‰¼Å±V^Cv>Õ¨÷Q»4D’@Ç5›,/pÒü¸U ‘ëëïúÒ(]Véî ±­’O\Œc‘ÍgédXÂ’Á‰#Ó§~ýêIÏ• LwŽ>o¼áïI£&iØX1Únãô5=FnÊ{A Š¥[QÞ°ç[›)6F PK:ðzÿŸZй¾tJœ€y<•—=ܦÝð2ØÝœó´öüñI‚"¼¸“É.>Rv†õæªÜ8_%×nð}N?ɨD¥¤dï-Ï\SòÜıHñÇri ÙÒ.#wXÆåQ´Ðúÿúë¨ÒˆÚÌ@Þä’úõçèø“ËRfä¯òúWg¦ß†T^p¸\žÇ½4&n†äõäPîsÆ*¡œ¨c‘À¬{c÷å+´ÊGZ¦$nÏ8c­T[‚ìdØ#ÐöªÑ]-ÍžÒy«Ç2ìhÁÂÀóÖ¥ ÒF*Ò±ÈËsŽßäÕ ÿ4 Ü"äã»cÈÔé3?˜Éó3¿°ãü RžMÌéÅ.C/M¤Œ:®÷ê€Èýúõd\¤iò°P “éXÖð;©ÜÛÕÉl±Ç?¯µI}¢Ûp“ :ó‚MjZܳIœàX‚zw©äºh 8õü³Yq¿“ Àc‚çïS’P·G ¶3·ëÀþ´²­‘ïÞÈ»Ânˆ,<‘Ç?¨¨mò¨7Z°u}M¬õøQÈnT"äœ÷‡î¸µµ{ûè›w—nª@;²qŸåÅl+ T‚ÏZóY®ÒI¥E`ÞàºÄ­¹‘ƒÏl~5½a¯¬:J/1˜åÎwyü}¿*iÖóH¥Yw+9ääõÿÄÑ>ÌøHãpÜçL0ü?¥[ð– ÓX$#‚€ì“ÓëŠÐÑIº—'Ò6FT\šqoj©s(‚ÜmÁ÷¡4ª úƒÈü3ü«&{£$¼ À²ŸRÆ›ö“¹£Ny?7Ò¨MpÛ×,OMœúüqI±“yŽ—,ùÆÜúã8­¥É 2rWšæâEž䣜ä•n3œö•Z\)rË"‚¤Ž0qÇ¡ÁÍO ©m¿šŒùŒ¸åX“ŒŸÃ¯áM½u-ʯ—„dpÜ#Ž£¯ÀSsO@mâ˜ðY ÀýjBm¬ªi'¨íM°Ÿl(œácQƒô›¨*È„Ëûw§q÷L²m‰ž½9ô¨m$]«wŸ~‡úTóF«j—QªLoQéÆO×Ò«Û¸6PÈÄüÛTä{áÍHŇ{ ³—Ô`ãüiÊÁÜ;>æi·«è’6 Ú9ä–⤕Y#V8ÃØí‡ò§`'›ÚX;Î{UXg)¸ I'ÖªÝ\0…—«ÿñªBîFO,6Sï ¤ŕܯã—ÜÍ’}=«~ÞãÍCŠã¬YÚUi=ë±·"Höt\sßÖš,fŠnhÍX®:ô¤Í.h(Í’ A¤ïAÍQšMÔ´fŠJ %-%0 RRæ’€Šá¼r°$ÄÂÄ´Œ7³àŒß!kº5Âøé!I‰…²ÎÈÒû>Ò?ôµ2N2Š(¨,Z(¢€,êò»ÿ®ÏüÍU«Z‡ü„®ÿë³ÿ3Uh«ðDsÍy2A;Ä€)“ Ÿ”?ííýkÕ`FŠÚ8ÞC#"€ÏýãÜþ|דx1®ã½–KKÔ´¨‘œ¸ÏÊ?ñ¯U°iÍ”_khÞàœÇÓ5HL›š^iw{Rn¦M€çÒ›Í8½4¾h§u'4âi»¨i¼Ó‰>´Ö|Ï^”†0>õ›ª±û8Qü]IíW¦«Ï Þ¨Þä”W;œ‚N3EÁ0)ˆ´¥]ˆl0#ŒzÕÖLHäØÀqŽõQä[Iîo(ŒsþµF²¨rY±Eç·ÿ«ñúÒcpñ¤r*á‡-€¸í»òãü*¾˜Ëö‚-ä çF%Nqÿ â§û:ܼÐ!‚Gv'޾qPÃÙ´ë†p‘yLÀç$/òùMHµ¶† ² œ¨$޵‡tß+yR®29<ŒéZ"¸Ž;@cÎI* ò8úÖz²5¹ÚNãµÉÏ|óC)É ­¿î[  gHªÑÄä2©9ùíþ'¯_ÿUIäl<¬üÌ99ïM…Á»‹ÉÎYXaëEÀщäHä}Ž#$täd~€ÔM½$œ¯ UÇnãéŽÕ•q<Éz–è储óFЧqWÉmÔy€´¹9 Œäùõé@V…á²\m,wÝFOzÏ»‹ÍŠi r“•dt– ZÓš=BÃÈWØ8uûÄÖ{¡þÏ™£®Ö%½AÀãþú8§p4žãhãsÍ÷‡øö©åc{"*&%T ÈÚ>™nk)nn#‰Úd'ÏË)-È㎽ ?.¡pf¸·HPî<°'ƒÜ~´€dÚ¯“ª-š²—9Cè¼ãù€õ«]D·R·ð§õ,G—Zæ54µ¶ÖRE&Hœqž­Üzã8¨&Õâ*ªs7ôüiÜÁ­Â6†‘IrBóÓÈêZƒK¨Kwø¥gÀpü¯“g<\+pq†÷ïõ«ÒrUAùzñǹ¤ÀYcp\¹,Þ¤ŸSÍ2[—’Ú(™—`%¶ †gëŠ[ zszBK(ÎÏÿ®‹4 ˆË¹å~^¼síô­;Av¿a¹’T±/9NA#žOáëX¥ö²°'˜¶êè›{±<àãƒß=h(ö-Àû$LáI$¯øæ¶`žC \4žbãçPsœÓØf°2‚iXÄñÇ»æØsž>¸ë“Ó½t:\¹‰nÊSÌ@ï’ÀíÛšh ïŠCdòõx”q‚éèsÏ´¸ÅÎYÈoR»z»ÿ ûÓ5#ÄJÝ#|d:ã£{_L‡"}"8¥sºXö×xþb†"áÝ Œ«,eйê2?O­H·¸tó”p<ÅïÛŸ~¼œÖU“yÖ0É#€a!ÓÓmjÚÃHdû’;óÏÖšü‚ÝæX±‰WåöbpGâjºfÑ çýrr‹8þDU›Â×Z:•i3¸= (Ú&éôªšk$—.ò1à–÷99?^)5¡iõœ©’4PøÛÓÕªÅ̇ìÓ$jCy…Aéžÿ֪饀™×n ¦$ŸçL5ÅÔåÈ xÏÞ=?ÅV¹ÜĤ˜\åÕ‡FãùÕfW…Œ9ˆ Þø« +Írû@r£jq€rxôªÒNeºÄn+éÀÏô  ÉœÄWOm;JªpyËÛ:B¡ö}Üg×¹®šÒexIÈž™ª°™h°N)EbG§Zκ/ç˜9ã4ûy3‰KnÏ$÷§qXÐͨ>ÑwõuºÀý ;…É3Fi‡Ž§ZMêz0ü踉3HM74f„€~i)¹¥È§`4¹ÌÒf4”ÜÐM1ͦæ“4ü×ã´….3 ËHÊòóÑö‘ûä/ç]Îk„ñÐnG’ùw*Òû>1ûä-LЉÈQE‹EPCþBWõÙÿ™ªµkPÿ•ßývæj­t¾º—ÏqžÉ ¹#p רÜTãÚ½GN½ÓîmSû:Xšv…Q·¶~ïÒ¼«Ã6ûJÜÇ#ÚžxŒ€Ýp˜ÉþùZï´i÷ÍÅ¢‰aYBçxçœúãŠh–tY Ñša`:œ}j€ ¢£3  dÓÃä;ô÷¢â°¹¦Ò–ÇQPZ\­Õ¸•ö4.j¼œ·ëSšdŠN}qÖ€E)dhúeóíTžú+DÌ ª¹Ç·Oþ½[»½ŠÖ'*rÑÆÍÏJó×Ôg}F[ÀÛ]É c ôü°*n;ÔöÐY™¥\Æ:žõÎBäÝ"aI‚‰‚=qНw1‰¢VFŒœíë¥Vµ»ò¦óqÈ àþ½!a­0[i<©NÕ™ú *Ý]ó,†Ç±Çô&™{¨9E=$`C?}OPÃëÍd†Â±^„瞣ғ`Z¸»i¦“÷ä©ê3úSm§‰ ”9!±”ǯ¥TÛ’NhÝ•éÏ­ '†ãlªÌOé.Nä$rAÇ^MUÝžÔ¤Œ“Óšc'Ýs–Ú¬yÇùÍZ»DC;:ÿžÕ’­‘ÏÖ®}¥ž5^ ž ²ÜSóZhH™UѶ¶ýàö¬vl6w`çò«1Ý*Î’H[*0Ç®ïÃó ^Ýn é3bQÊÓðééÞ¬<ÆhÝY2Â’6mÀÉ|Ö@pe-’ªÍ“R—y¬oòƧ?6 ¨÷õ F¦‘©O ˜ƒ*+`ØäóRIpÒÆâñŸï`××½cÛÜlA²ôëN–u™¤6ÄRÀòI¦Æ©;=€TEV)×9àŸÇéTn®ZÖQ$`»E Æ=K!ùÔš•çú„°)'È­€õýy¬}Fò[¹m™«•ŽpOâ(¸nÍròöçéÅFÈW©Áõ¥g!J–$O_óÍ3,nÓ·îÿú©t *´m9ÜÆ¦r¥Ù‚í I ½½¾•Yw+Ç×#¥H[’6þ9¤ÊQ›ä8ROÝ>”Âà ‘‡;”O(ö<Ð1ìp@Àä`R+±R3Æ;P1“ÇjgÍ—¨Eý2"è8 ܧ8ÅuÖ7ký–Ë;ƪò}kƒV#’¡€ê3ŠÔ¡ûŒ Iœ«rH™Ï¯4~[׎Bê¹@Æêj»‹í-$ˆÆ9 NŸ®*‚ÌÎ3žy ðç¶ +Œ’{“*Æ*#M¤vçÒ«¾dd÷¹ëD„ sŽi›‰9ÜŒR”! áѱ»#¯CåRNcþÌŠ8­TÎ -6zœ‘Ž¥fDû †ë¸R¼$*ªä(ÈëÇST˜2ky„D‡l(c íÚµ4ëâ%ŒH»Ž7n*<¦OéXã©Áö5jÖFYÑ·öÆ?•4ÀÚººGŽU·ðsÏ×üö¨ì¤1†ûB©DÈ[”ç?95T²¸$<ûÑûÈ^EOâwÍŒg¿÷üé6œî^hŒ­½Šó÷_Ë¥_½ÔŽ„Jû÷"BL’2=¸"²,ñ ÜñÈ0à‚QïÍTPó\hÎ`gô¢ö ‚íf¸˜F²uP[£$}[ú“Ie4V“ɹ”î·C‘ÎO_ëTì–u†e—ø°FNï˜ÿ,â•m[*YðUvŒ p?¯JWCL 5 T,¢Gvg#©ÅWT `Ž90²ÆCúäò9úäRBëm…OÉŽç?äõ¤3€8r£—ÓüœRçC°ñfírác‘p¬ªTp?Ç5^=.q–žXbíóKžŸJØK!# *Ý\É´%r!Üv¨¯ZØC ÑFbYrT3øûÓ¾b²Aof2q€:UÄÔ )å´uË Í£inFy•\ÌN(©öùým´‹ô枺…³q¼©÷«㚉¢‰þúGøÕ*Œ—H²+ «ô4슪Ö0Ÿ»”>ÆZÏÌW¼3Vª.¢å-äÒdzÕCöèÆZ8äúR}°¯3C$~äU*‰“ÊË™¦“UZö/£,v‘éSî£óªM14?5Âøà@—köv%œ†›æû¯Œcþù ]£Ì¨TzœWã_'íq´X¸ /=ÿÐU:R)­QPX´QEYÔ?ä%wÿ]Ÿùš«Vµù ]ÿ×gþfªÐÞ$°É4ª›íÓa¸\•Þç®wíèk×íåV·B¹hãvqøú׋iÆá-îžû¥ftÜ1×ß±¯x‘„ŽysÒ‹‰ž>¯i „2‚Û‚ãëP^\•¸*…9î;t¯Í&ÚÒm¸LC jvï¤yìDK½±¹‡\ôßZóËÆ}Â>ëÏèjgÛÃ0Pxþ”\,zìWö²Ûý¡%]žµ^çTµŽ8 QÃ2p+ËDŽ>ë°ÿåKæ»pòHGO½ŸÒŽaØ·%ãÉu<ŒûŒÙ$€NFzsŒvª¤9-F™8éÐS÷gñ!bÜ€}eR0~BKóíþ½URTþäV‘Ö8ÆYŽÒ¬ÝؼQ³¢–’ö±œÒìÂílöÇ­@ÿ|‚1Þš ÆzcÖ—99n àã½K%ˆÇ't¦sŒô¥#iç©ÍPÇŽ _CIО;Ò=ù§ÁJ6¨ç­BgžEKù†8¨ü¾NIëONv b <žôÒsÅ.ÜŒÒt<Ð!¤¹¦ƒéÀp:Ó‹ä0¿Z@>Lç¯_z*Hѱ1±]Ù•"JË yïÏ¥C’®F:šÌe@Ц•åDV,UGŸõ¨”ùÁO\#4`ž‡ŸzEÈ cŸ=GJŒ‡íõ©qò¶zTc¯ž*€Ls‚Ù§#€B©=Æ{{QОô %CŽ¿HŒ §§j„}OåO„Ý8ê@ƒ2€yÏ#ØÔ»ž2sœóéFÞ qÀì?×Ñ­mÞæR¹ÃìzR|ªåF-² ·2Cº!’ª ÷õªÜl}+oK·‡ìwùK»m9ì?­bÜq;ù|¨b=*#+¶‡(éq„íÀ''Þ•3×$æ€Ø9©ÐDÓHx'9,qÒ´Ø‹™2ÂH³•÷Ô†æªw”ž=êQ»k×sj;a¹$uÙ€ Ãœÿ‘[1XÝÊŠÉ`ãך炶ß3aû¥¾«ëô®úÙ 2HDQF§åíòŠR¸îe&rq–#žÂ›g¤åž¦º@‹æFKžqœgŠ©GæÆTù€ÜÖvwÊñèq©š[6(­Ý”.@Í:ãrøzíƒ6Dƒ“‘€_ίKM<îÆì($õ=(äfÖŠ· ’ gT!@-ŽV­ÞZÆ-­¡.¬cSÈy9¨îuUÿz1Çü›©Ìñ‹aJ1éîkn†kqßdFp ­”KpB ›€ä}:×?n×­Ú’ÇË1äüßì·øVœÃÊ¿žd2G‘ø“þ"¡Æã.ù¶ƒþZGùÔ¿»ùœmÆwv®cûvëí‰Çö‘´t®¥ {¿’x< N(¥"¡Ôl†ž0Þ8º·ò<ýãË ·pÆ3\þÓyf»~ó1È?íâ» D#M¼l~ìÜNÏpÍÛð¦à’1¥e{ivÌ-¦IFH¢¾ßSX^éS°þ=Ç?öÑÿ¶ØüÇêjZ³áJ(ïK@ µ-„…”]6þê$T¤ÊRTjŽ:ˆ[¹j£¨™bê†ÍÚÚì‚„`ÉÂãžÿ…g¥æ 8Y­dúJ¿áS+ìð•Ëgsú?­`éî¦ éG—!‡QÓükD‘77PÔTüÖaý×úÓ†³"ÿ­³™à8• Â&ˆ.¶£ŸÊ†xÆ}i’ÞqÓpÇþ=Š™«uc´Ô6á­®ÌoˆB)›8äoÿDZRá‰Úy¤ÄL[ R«äŽj%ËŒ.OãJbtPHžÄ@JOÎHn3JҌýCÆÒÍÇÖ†d84€‰Ù‰9>™¸…ŒóD§oã×Ú…ô4 ãèÀ㎧֔ãnî1ëši#°ç9§q¶4–· ƒÖžN;ÔA²wqÇÝ­}N7·[Ÿ\g,=h@™gK¶kP·Æ˜2¹ôô­&ZJ&L q“ßÓžÕ~í#0í|`ð£Ò¨jÚÂh¤ù¥W«z`s×–âÞä R2¾ÕY¹=Ç_ζÌ1¾š‚à‘W¿VÀcדޡƒ~cž´ÏãHêwg4Š@<äÓ@(äçßš½fêLaæK±îs×òªxM Œdö¢9J}ÑÔs“Óž(4ÈP©Üü–ö ô¢".îE,sJñ˜‰O'žyÿFO-˜z ÐÁ;z M¸¯La9ççzxR'EŒpñçäP"„cž¼œÔ›>\ñš\㚑ح!‘nQ'$ã<ŠÓKq Ÿ˜_yx÷³$V2£<Óâ‘ÙJ,„©ÛüôÍ4ÄðyN$ü½zÖ\é°ôÀÉ5¥2C¼Gc@Ï=j½Ä*±ÈÙ9Güq@rp´ªGpÃ8¦6ãšz©+’sT9#×ÞœØ8ç¥ !àfç§©${`R ºÒùTŠ@§9â€A†Á…Hö©U$Ul¯ÒBÜ=zqÒ‹ŽÄQ‚ é’)›FjâB£88 RFF ù¬B•zcð¥U;ˆýê˜Ä9'ß½Göb¶áÈ#­H,BùØyÀ<ñÞºM?aÑ£WloWú×¹&³¨¹–…Â÷.i*&Ò„s}Ð펜Ž?Ʋo 1Ýy(F€V´,£Ž{DF“iˆ·ñc¿ÿªqå6¬gŒ„Ž{ÔE5"ÝœJéjácVtF—îä“P´2y¡H!#ükIo-[.B“HÊõ©n–Ëȵ¾uùÆí£¨5|ÝÐŒ†FŒ`²þÓœg®=Jè5->Öa’8ÀË“×Û"³ÕD¤‚T·NÔ¹—Dºz\ˆº2)ž,ˆÙ¶29o^ÜV”^GX‘åìrvâ¹ymî—Ëʽ¡½÷õ맆4[‹— ”(ñÇ8õëZ§¡˜ÃuwpÊT—ç–_N)×7ÒZ²*¢¶çúÖ¦G¸‡PXÄ™†INåaœð=‡Zlòì}Ž9Ôœ±'u<~TÓ@CszMªÃ$A£™CÝŒ¢¯‹£qhøpÀqÏLV^¨`Š8î&·fFÀTS÷: ŸLºŽâ V(Z%R¤†|ç=*"´÷iöÁ3@À«ŒývçÊŸ©,71Øm,ždLUHÎëV¦Ð&gó#¸N»È ¯­Gu§Ü‘d+ýžÝ£r;±R¿Î®Â*Û= ¾·Ÿ2—H”ÚI#>õ«p±I$Œ"H·ö+ ¬î`Ü^3”°X¸þöF@üiË•°pGÝ´Æ;÷?Ò‹ˆlÂj /Úcò“»9ÏL~UÒA|ßÊp3÷OÝÇ5È@KéúfstÙÏqÅOö‰‚ë’,¯òË´`ãjnQtéOmow½Ìð¸|óéÁ¶ˆÑh2îs,̓îÍU4‰˜èv²oe$à¸<Ÿ›ç¹ÆRÕ5’ÁÇÚ™›iÎ[w_þ¶E&"ß‚âhþÐÎ¥r‹ÈÆ~w?Ê´Aîj¥àùwiÄ’2ÙÉÆ2ÿëÕ¹ÀòÉ>‡Ƴ–å!ÒL‘ª³“‚@üê@A õRà¸òÕT_œöÅY^£€y#­ecoª`Åps™=+LãÒ²¾ÙuÊÐI·,ËOoz¨Ç´ñLleûÒx÷ˆ"ò´í@¬xSyÑý¢K%&¸!™¥`xǾ>¸¬én–Ö”F¸Ü¹Ï_ð­Q&DA…¬ÕÕ‰{§eÔ/øR4*t«%þZ±nóT‚âÆš$q½¶¨zpzTék ½¸hà ಫá¶ý8 } íiCxž%ÇcQB}í}ÿé›ÌÕûŸ"mTJàyà£d?=8úÔ’yot‹h${©å¹¦M¼Dih ¦ãž:àU¬+­n…˜³¦fç£äŒß!k£€[Ãlˆñ]ņOB:×5ã„jjð6ZTß0Îv¾HÇýó·ó g;EPÑEgPÿ•ßývæj­ZÔ?ä%wÿ]Ÿùš«@ 9µ»h‰¬kçôû»†?ñìUûv‰X—"'8-“?³ìEÇÙ®ŒXòB¯œ29]Ãøö*I7¹'?Z–—º¸W*³ÆëÙ–û-7íW Oï›?@3P…mÁ€À s#7çïJâìäÄ’)ŒØC‘ÐÓÿ…IïúÓ:òqëHLf2@Ü? È|ç¨+÷Þ§¸îÐ÷DÑGµ\8ûÌÀ|߀¨$è¶1Ö•¹ÎG¥#€»{怱RÇ ×Iá§e†FwXâowÿëW86\ ¿j±É Æ$•žA·`ÀSC:­^½Ó€· — †Î23Nžá[,ÆýTÛmÂÒ|ÀXrNIÀÇbj†dÞ]­ˆ˜/˜Fp#Øöükf;öóϵv“EÆþdjàƒÃ Šâå*’£¡©hLw•–*AÈéïJчž@?¥66ù‰ç=ùéNæG?7¯½Cµ·p3ïíIÀç#>•eWrg§~*›~ÍÉQˆnx©w‚‡=HªÄŒœŽ*LŸ…0`Ÿ­Z]òy'ñbj‰¦ ƒ±ˆ=°\•ˆ+‚ÄóÅ4ôárî)#gšEP<ãž*W·MÙϸjD6-IôãàÙM…ÎÎÎ?0ÂÄ€d|cºŸ%Iýá8Þ¢ã%i™€ß4Œc)ã·­DÌ_'#Þ—Ê|³äã€ÂœˆèI/ÀìJÿ…+†¦ì6ͤˆ]¤I¼€Ieà†o^¹­„ŽkhG …WwÑ@þuÉÇpNàä°"ãœ`†þ•¥&§0{½’޹_—#võÍW2+6­oĆ)&Œ—$•öÿ"­Çq ©.Àž:úÖlw¶3,"w”³ãlrN1ôÎj[»+©Í$cSÏVçõV¹$º[‹&Ž/ÕÃ` àT°•@̃ò°uk›‹{ü@YC ¾ÜV®ŽòI§—˜’ÆAœþ8ý+6¬Q´‹¬¸GuQ)ùCc oÿQkw÷örÚ­ÃÆ¦5ÜÊò3½3V#U“U ‰ݘzpOOÆ™«£•J‚ÂR=8¡VÞ"Õ~Ú-äHg7å—ž?øªÕ{¸ü§žîècVxמ¹àgñ¬‹ gþØ–VVØP{òÖ¬È]1ÁT‡4_P*.¡á«§Pd’^bIŒŸPGoïU‰4 £’(®£ï ! rzÿrIn§ÚBùlIÆ:oü;W]weç"ädŒÒ“v°Ò lÚÏOŠÎ'RÑ6n<޽k)ô;ë¨B¼Ð€GPNkJâÙ†—*ÌycƒŸ×ò¬ ôž(7«È6¶XŒÓ}Ž£B±}:ÐÀHÊ«A<ô¢vÄ&¨øJFŸKšww#%‰Í]¸8„ûâ²{–…~J½þ52Ž•ÿš0GROó©|äz @Jz§6‹<ŽX÷“Ç>Øýji¶§AôÅP½ÜgÚüÂ'òÀÀc5p$žÖhôÈ­P+JŽK‘ïTg°¸–ÌÇ´eŸ=}ÿ^´o.%kky×h’`d$®p9"©›»Âqæ§ýñïŠÕeM¡Þ5„0F£*ÌN[Ö’óA½˜Z„T>T`6[¾y­O´ÝŸùl¸çø=³Jnnü·ÿǦh°\ º-Ïö·ÚÊ®ÁŽpZ‚=P·q™ïBíùÏ8'éZ†âäƒþÀã¨UôÏ¥/ŸtGü|ÉÐö_O§­1ÃDÔXâ—o”ü1$ƒøÖ‹¡Xõ$ åÝ”´ß6ïŸqÿ¾ƺ¶šç<ÜÈzú_o¥r~- F&IÝãÌÙççÉÿ¾qC9ê(¢Å¢Š(Ρÿ!+¿úìÿÌÕZµ¨ÈJïþ»?ó5V€4,¾Ðm®ÌG÷;ÎÃøö:TŒ¹”u qL°[†µ¼hÛ÷Ïr7Œ{ýìt«=rHã¸õqÁëŽ=êV=}ÅFXŒt"`NWž)°@© g#ôÉ6íéÖ 8Þ€ôÏôˆÀ•Ï¿9ÁW®i©±ŠçƒŒæ˜ Û‰ÉSžàsRùœ ö¨øRƒœLU­J¥‚׊¬@ÎZ“waŠˆä hLG^„´ÒÀŒÖ‘‹+sÜSøfÝÕ¾”Àp*U=æ™×bNxÅ*CÍ!–’[È4Дž¥_J|`’Hà‘ƒïÅ>8B‚oCC2UGLæž`ÝO¡ªt‰rr0¥AìT9¢R[@HÉÀÎM(´ˆž>jº~^›iž:Ôó2¹ ŸePy}iE²('Õd’?•7–/Ñv¨„Bƒ¢÷§-¸#&¤ üêb3€{úPÛ‘XYF~òþ´×³…IÏJäXc–=ªo#o,~b ãÒœS²cÚ0ªãšc {j¤hÔã¦i”qÇsŠ«¤b`Ï‚Š‘ÑNGÍÏ¥9-‘>fçëOèï‘Àl v¥Ì"£@²;?·jh°Wl,‡ñQV™†rbǦriC¢·Lè ;÷#û& nbN2xÅJŒüÁqÛ4õ—|lJ0 ‚ ¥¦O=MdÛe¤ ª‹ÆöYÊ©ãéÚ¬°.§¨É’K6 éE?2–ƒ@PNOJ_Œî==:P"\IÇz\E‚ ‘šÑ‚ÈGSŸ¥‡¹¥¡8%±éAX‹–¤^0ØU­>9@s„Æ{“øÒˆ–~@‰Œõù}h™n+“!@É(ìyÏ5£w«Ý@ð4%UŠ$’NF1éÅbFñ¢îUäŽ}êË]9Û'¢ítî;W9öé&¼üí*É줂¬Ùêmy‰Î]Íò¯'×§¥6ÕÈQvwm5»bhÙB3Û¡ïW5«“ ë nXí<Ò¾à ëøÖû]o‰ÖtYÉ>õ™}o¦ß]Ëm%ÚÃ{$^V€Tãzu©ŸS:Úx—Qw’GU‹fòÇûØè>µ²ì‚f.@_“’@¯Ö±õ=î<‘¦ï>HÊýÕÆMYÕ¤hôËͯ‡U^Tàç½$€‰´¨EúOot¥U *8ÃAî3Ü×D0\sƒØ{Wg)Zt|²Û™_ Á9ÇLñ[Zn©±È4o¾jdŠLÖt̪¤r5•âX‚éå°2,ÿõ«Uf êüÑg ÃÖ²¼M<`Ãx.O\Zâ &Í L‚0ÝÇû!¿­XºlFãQÿRèqùZQ“–,Üd`/oe¨ï$ÛåÞAþ¿Ô4œþGü)€ãÇ^Ãúb—?3Aýüi®p¨ÿÙ€¥žœŸþ+Ò€©ö®SÅ©j[-$[æç£äŒß!:ê³×ÛÓú×)âÁÔb0¾Y¢ 7=$cþù C0(¢ŠCŠ(  :‡ü„®ÿë³ÿ3UjÖ¡ÿ!+¿úìÿÌÕZÒÓÒv¶º1¶ TqÇMÃøöÚŸœŒäóÏJ‡KK–‚èÂtª¦nœÜu÷ÅKµÃU†§Z–õo½Ó¿éLQóg'Š_›w¡“íŸéSq )Å1ò2NzqÒ—qÈçô¤É$ç;šH·2OñsíMEÃ;/5(PʤžôÌîi€Ž3¹W÷>¦‰}3ž”œœàqšq¥É<)Ð+eÈPq»&†^ISȨ÷áOsN~yíL cá=ñB0*HÅ"ŒF}H4ã Æ9¥aŽVõcŸZh,\óÅ5IëŒýhÜ ä‘ëïJÂnã×##ß4íÄ·'3Å7wÊsϦ«î|ëŒûRC$žƒ8¤`ëÍ"K‘ŽÂ•c,ÇN8ª!-™`œSòTÆ*X¡/ÐmбäªÜŽø¡Èiù~`%Xr2sô©aˆªÄ“VqÁÇJpãåŽG|TóÊ4‘ŒÓ” óøÒí ž8Å+Ï©¸ì.I奸Ӳª 9¦ËáGJEŽÁÇÌ –ô¤ùÞ4¹9ùFjXÄæÉ&‘‡/­(R­Ù½ý)ý “ÆXS@Â4ÆsÉÎ)e*ƒ#ô³“‘°Ÿ”T2±,'›'a…·œžœþ<0€Y™~cúS-Л°éùÕ®ƒ$æ¦rè…}ưg§áL]Ê»ºŽ½)e99§Û y!¶»à ô§v6@Ìs‚R}3SAN c¹þµ4ÖÂ4»aO×µ=ü‡Œb¯’Ìžaܹ%$@¾„SnùÚwz•©—žçò©ó÷Ž(åÔ›™·PḨ8ª‹!'šØ½]Ѹ §'Þ±æb%##Í;‰a“Ò¢»Ú…@aÏó©£8^õ Úî*0pO_JÉ|C¹\´…ç=rzÔ‘ `'§­<£ Û¸Œ£Š¶¶('fqž¤Ðï»?JB%'ˆÏô»f=#Œc5% »vGZvÐrx÷ At/ýõA·¸ÉùÔPˆQV2ÝN8æ›ÿ,ÏAÏ'5/Ù¥<4 ñéN6`¯2u¡;Hä9lŒåŽjæŸ*NÚ!ËCìÍüŒsëW4Øb‹Q‚åÐ~íÊŽµkVhí_¡¹®KÄk¿ÄY+ýÑ[¬[m|$uëšæïå7Ú÷ÚFw.c'žµµÑ•º›>¾¾KëØ„å B0’œôœV´†Ò_:ã²'~N:¸Ò°tÝFÒÞò숚<üÌÛó¸çÆ–úúY4‰®Jª´³íÇQƒëS}A#dèÀËÝœ‰$QÆÐ¨N„¨Ï¥aÞAye¤Ç©çå±Üc¬Ý&æêÚõ¼ÏýÙPNÞ=º~•× z5¶ŒUw³ årxàöühRM•¤A¬Í-¶ž®˜Ü"có¯õ"¹Én?´­nÈ%þ,Œ)ôæºMR{UØnlm žÑýEAö½Ô…#ÐGÁ¦È6,TÇ£¢œ|±¨<ú“Yº£6ëtFÚúÖ»¬šixª1]¹EbkˆZx1lV24-Çpö(Õs¹ žzUõç$V%²º_ŽD˜Œò§¥j[»7˜XcæÆ(K˜Ýíd¥‰\+æÝ€dÊaOQîMoKvm˳vÞ£85:jwñ´À1wߤ̭IJ´3„„~ƒ?Ò©ír>U'¯ò5wQ¸µ‚eSÇlÞ?j­&§¥Äüîîü¹ÏçzІ0‚n1ßéýiDlF9ôç5>mNy6ùjœa›Ûš©·uq©Ii1(Œ¶X’zñ¦£m)+rÙäc¾jQg!Îîòïþ5s©ê"ÚyVà&и؀ulS “Ëeo$·33È¥›çÆ}( ènµ¼qeš4ÿy±éé\_‹§öœfÊQ.蔩È’?ôµ´ˆ¢mG®ØáØ ‡f¹íq I­¼–%šÌ3Ñ÷0ÿÐBÐ4dQE†-Q@uù ]ÿ×gþfªÕ­CþBWõÙÿ™ª´±¢‰ÄWm……Q|áÇ#pÛÿb´|™ÝŸNzV^”'ò/ G÷"5óǮί¥]û±Œtɬjn’“€2uªñœÊ[øsÈõ©dqÁªÖäAÎXŸóüªV¨l¸J•è¿•1¢B>è´ÌœäyïN2nÇoZ‹;ˆ­*í=Œ{TYùqŽjFuv 6zT!Ž„ÖèÉDÂõÉÍ9‡úÌ7·J9+èri]Š«sË51í*Àã ö©‚ÍŽÕld‘ȤüØÞ€'_º8íH„m9úQœ²ž”ÅÎÜÙ4 wðÏZ‰rdÈñíR*ª;äàúÔ«k#2²ŒÚ•Á&0)eɰFwŒdóÍhEj¨˜aÉô©—#ð©çH¥ŠÂ7`¦¬ÄÊpA⬈€ì)û“ýjyÊQ+¬CéíN wqŸNõ(Lò*7v¥{ŽÖS»éÓÞ•q‚:óLÉÈl§šQŒô®IR9¤Èãœ:Söq‘õÿL¤qJ;Zs•y9 ÇZLbqsO0NoZP P?È¥_‘€o¢â¤¡®Ÿ! €sÔUifb¤àõfrJmQžr21T¶ç9õªHL7’1ÏøS°Ï ûqéëQn!–g‘ëRG(H–ªÖÄ—FBŽ08§œ{t¨â ¼ #žiÏ'9Ö.å« —œ.zž)É”má”¶zÓˆ(Årwt« ‰£ãœõÆ+HèD‹We"C¸ÊCN1ÏùµºŒu«v¤¬Ê’„}ÀÿOÏš’òØe爤ŒƒÛ5r¾èQµõ(€Àõ?÷Õ Ïýù?ïãRãæêh9ô¬®Ë²!“y_õ’ÿyÍQ‘“¼â¯¸|1UÞ/¸0±V™-KÎ1©§á ÉäwéH_“’*pU8;Ž3ž”¬; yJ±ÀÔ,…AU'q$RˆØ/Ý?tæ‹XBÂ2ç§>”Ä ¹¹ëK•”ŸZtk¶NAÆH¦2>ËŽÀâ–Rw £ÍÁ©V&*Huʤû3;–ίz.+”Ç¥+Þ’yâ­}š22ž•j ˆ¸E猒3šEA´àú~Ue,òíÀÆ*Ö 18;iè€/C֡ȵ! »W!j`¹'/Òœx§…;r*[.Äj¸>þ¾µ"¯¡$Sö(Æ_'¾Z8™¨¸ö#Á玴¥GøÐÅ[“MÈüÏ8íB@#qŒSX” vTç¯OÞ8¦L¤œªóÜzÒ"†fOr;TÃ<ù¢Pÿx•ô8Èô¦À…› Ž„þt÷ä3ÙU\#ªúgžÙSÜâÚ¤à}Ú B¹É Ž‚¥UsÎ{Z#EB÷qùâ‚yÀîxÍœñІfgö8§Ìà"‚_ÐU‘ãQ°žN<â’ClInNà$àÁÏZØ0ÂñŽžôç"F^i§‘œÖ„ ~ãŽ~´ÂTœõ‚NB‘Ðv£¯^EKËo*AàñZ1«˜þ`÷ª6ü`í^µ$—8'J†¯±I¢ÃgÍLúžþÕ&1÷ _qY­q ïÝŠ–;‰†#ñÖŽV„¤iFۣĘ'š-o^FidÜ™þùlzqHèÎGñëOIJŒ+šjVÜN"ýžhÆçÅ&àÝ€¦´Ìä©|ýi·Lô¬äR"¾xüi¤ñÁ« œã­V-´1ÿ×Í8ê60bžËˆÛ±¢VËqïK6zgZ»j+‹csÆï.òTölžjäVqÄ +ŽäµR äÚÆVC™$zzQçJx2¿=~nµºå±„®Þ…·° ’ 8ùºU%—?»`Aò§y®å´˜ôÜƪ±A!;ÎXÙ¨¨“ZíÍ"¼Cä‘PùÏ'¿QS* ÀÆãëRÆ«ŽWô¬Ò.±L³nÁçÓÚ•¤;~ãcéW–1»$-L"\ýÚ=¢(É"wÏÈBã §ù¿nµ¦Ÿº>´í¤ž¥íC”ÍnÉ«ŸSJm¶¨g‘WéZ;IН5˜¸eË•µ5Rû‰¢(ã‰ÔÇ¿¿a)&;²¬FÒ1Ð;Õxmc…Ãn99©UpDœçQT§Ð’ÛéHù1l$¶IeËZ[Û!q’ΔÆ?tcüâˆîä8V·÷‡­!žï+‚JóݪR¶Åo¸š¤‘G«Ë¸â0 sßÚªß!ÙðJ©'8â¥ÖìÚk¦’YÒ(˜q•-Ðý*¤sÅn«›égRpTG•ÿ8«æ@’±§q~°ÙZÃÎ~;k>K¶<¯;ýjIn–A”Š(ÆÊ0_­Gç¿ÞŠTÐŒàÖm¡¤VûDͻ˖=¹¦ý†öWfû;ŒžY¾Pj踺eȘ¢vP¨dÜ༎¾¥Žhæ+ |¨H’ê÷uËçéÒ­‡·…‹-åÁ`sˆPá±Øç·Jg”AØ3Øç­!Ènª=©s‡ Möy¦2‹A¹ñ̲{zt©F\)£GÇ%cÁöÿ"›ŒœîÇ©»G™Æ·Z9™\¨t¨ÁÄ’I$™!› ~T‡ËM¥S1ŠVFÆHÆžÇ8íR; irq·4Ü­Àâ‘ö“ƒÏãQžËd”Ò äÆÇ5‡â·[¨˼ Ì7}×ÜÃÿA [ Üy¬o%ºÝÂб.ðæaž¹€ÿÇBÖ´Ñ”ÙEVÆbÑEgPÿ•ßývæj­ZÔ?ä%wÿ]Ÿùš«@šlWrCvÖøò‘ÍÓ¦ñü{mOº¹ ÛBòpOjnˆ’˜¯¤je‡#pÛÿb¬[”+wR2EK%“ǦŸ1ˆPä ZΕ‚3¨P@éÅj½ì1¨òÃ3‰:•àðj€òÉ$ÇžNrzÔ±¤!m褀€£§­FF µzëR´…¨ôâŒê.(+”dq¦àÍó}joÝ쪂ïOò[øŽ}}éÞH$ úT±¤Dw–éëžsÖ¦Û×íŸ6 #ŠW*ÄKÏ9ÜTŠ¡}*q\óOQÈמµ7˜Š: cÖœ£'R œ`)Ä~ñ©(6€yŠ^sÉ>Ô›p8¤f89<öÅ Ϊ3œ}*6mÇ!ºûÓ\’0AÇ¥3v E;.lgëB®=©›³ÔJŒdóí@r2æ…Œ ïÂç§9Å&qÂ÷¥Ã?\`uÀ’À§DÞr0qÍDIF>±ØÒÄ7 Ä <1À2 0þu4§+‚p“œT.F‘ùäS̪ÁÇf'ôÿõÐHŠûŽXòy>Ôüe‰~1À梌á{ ç½"Èî7`uïÚ˜îHÎK³tÇËÍC´2°ß‚óG™É É$õ¨f=ãæ$ž=ê¶Òrxù€îD[À85z6¯Lu4òˆÜ8ZŽuqò™kŒg'"œ…®ìžÞ•9cÜË+œ u¨°‡æÁÉëíV„Ç,Ê®N>•e%Và~žÄgnÜЬb›B¹¢Ò Æ$öÅHƳŒ¡;’EH·'°íëK‘‚’/«/œiW7T¹æ–;Ädš‡ZeŒ€s‚ rG8ÍFŒ$7ÒëÖ¡ #mMS’CÔÉ«ý°F­6H†Aãœd¢ ÏRûx©2H!ˆ8íV6¸J†XÃ.WŠÑ4ɰ§;HÏ©þTôE'Ô1vTŠÇÔRwÀSÈÈúRy!œº…ÛèGzMç‘éNˆ°ÈäÔI±´‡ˆ±ÔŒû ™TcŠj“üDRðqósYð¨W'£ œsMÈÎÑŒ¾Ôð@Æ:žôš‡Î9¤Vd敃cŽ„ôõ¦•ÏBþ4Õ‚â‘’i84§ Ÿ›§¯zn0pKúQ ¬Dñ¬¯´³Cž•[ ›Õ»þ5g;dcŽÜ9M¼t?h›Dˆ†HÔo}ãÞ´´JâÙåh ’W0È<šÍ—!TîÉÀü+WÃ*yÙ€eœ‚8Ík–ÇYjSÓb¸h×2ƒÁŽ¿áXºŽƒ°–µù;íìkSL½†8c´+å„á}5ªB¾Tò*šv8'ŠH—k†SQ’UIÈ8ô®ÎïNŽT9]ã9Áíô®wPÒ)—Ltî7qõÅsþ$KE¾ˆÚ±Üðƒ0'î¾æÿ¾BÖâ7ÎAìqõïšÂñÛ‹Øš%ÞÓ ÝqúZÒ ÆlÆ¢Š*Ä-Q@uù ]ÿ×gþfªÕ­CþBWõÙÿ™ª´«¦Ew,†ßqŠ8Ä“…äì 9únÅY†Þâkvš;i$tˆ¤¨#®OO§5Œ$Û¬pF§,åAUbõáJÀmAiqqΑÈñ&KHˆJ¯äô$O,-4PË$K÷T•SXIrê0è*E»`ƒŽsƒ×úšžR®nÃlòÄf‚7x“ï:© qžOÒŸ Í O -$KΊJŒ œ‘À㟥a­Êc åTç çõçÞ¤WHWÜP ù¹Ï¯­.QÜÚŠ)&‰¦†7’³¾DRʸõ#§ãDPIQÜzÿSK•ͨÖyài¢Þ5ûΪHˆéM%žš¤’$ûΊYWêG²*0¬Bœä àþ¼ÿžÔÐN1óÇ<ŸoO¥¨\ÆÔhóDÓCÉgs %W<‘ÓŠ#ŠK˜šX’WŒgsª¦±GÊ0 Æ>ï8çè¥p) w¡ÏóâŽTÆÜ0Ë4O r<)ÖERTqž´ØášHÞhãyc\ïtUÇ©íY >U9à~\úШÚÂ÷Ž9ÿëqÚ‹Íhm¤¸‰î"ä…Í"©*¼g“ÐqNŽ)¦ŒË O$+÷™>¤V8ÊôàöÇùü>”«ò®2Tc•øÿžÔX ˜#iâibÞ!÷™T¿SBFÒ#MbPwH€²®:䎭bžá{€O?¯4ãoÏ·êyÿ#Ÿ•¨9˜âšâq<‘(%*1êEÅ4I4*ï dU%GsÍb‚W “‚>™ÈöäÐrQÀö÷™íÿ꣔.i´3ÜÂfŠ&x”€ÎªJ¯ÔÔ‘[ŽGZHÂ’ÒÆ¥•p2rzp9úV;åS(Ì£pÊçƒúóH¨p¬Àwù?—__sUʄ٭2ËmæZÀÒF¿}ÐUùsÉéQÅÄЂ)e‰ Þ褯¤qYa¶’ªÄø$gסæš$e+ObFZ|¨W5DRË Kko$±ÇÃ:!aø‘Òmk$–íwE$3ÉíDÍq Í2Ig.ŠH\z‘Ò³È\+;à:ûð¦Ç!B0Hú3úÿ…W(¹h-®.!ia䌙ÑI{šžÞn"yb…Þ8þó ÜÔŽ•»h;IPÝB“ƒúóFþÁˆç®?Ÿø~U ÜÙ†n"ya‰äŠ?¼è¥‚ñžHéÅIOq–žH—ï:©*>§¥aŽ„§íǧøQÊýÓ·×ÿ©ïÿê¥ìÐînÄ’Î,¼‘¯Wr£êicó§…å‚9$EûÌ«¿SXHÅFÔb£œ>¼Ò32! Ì ŽpÇŸñ¥ìÓcn5ÌM,É$qýæE$/ÔŽ”°‰."2Ç’ÆŸyÑ õ=«ŸAà=‰½ù¨Ø¯û#¥W³AÌtPFfˆËÉ"/WUʯԊH–KˆÚXQå>ó(È_©Ï£$ ª3çÍJ‡˜9ßñÿ=©:H.lÇ Ý#Moȉú ¨úžßGm³E$¶ð¼ˆ3–E,êEe(¸ ãŒ@ý?Î*<àar¾ på×ó×-A°Iq’Þ7’43 ,ÔŠ×ð”lð^ËïUR @à÷®@1P@b8è2èy«’2o ̉ç·>¿çðµ ³­bf…¦‡÷ѧÞhù õ#¥XÒµyÒ2Ê’\Û'ñ -³ñEsѰdÀùO}¼vöÿëU‹M™0e}Tpåýj‘›=>ÒöÞöÜÜZÊ“D£æt9 õ=¨Vµ»€¼¤‘§Þd`À}H¯%†æH$$;”ñŸÃ¡­k=F—Ë?»“Ó8òëÅ(.v6VWд‘:È©ÖXH!8Ï${zÖØL#3ÚºÝ@>óÇóúâ©Ý«}‘ÖçŽÇoËéQ[©bB[œòƒùuâ§‘™–aŠK˜Úkd3D¹ÜÈ2ÔÔÖzt·p!e)Þ(wmã<‘ÓŠÍÞ@ ¾ÀœóíŠhà è3øþ·åK‘™›Ö¶0̆hŸÏEûÅ~`¼g’:qVm OKfªÉW_™GÔŽ+–ÎÕ;2¾»N?ϧn*2ø_”íñGÐþµ5‰m³ª†St’M £_¾ÉóùS¾Ó=¾&DûÌŸ0^3Î:q\¶òœ¸8ÏøÓ!p ÇqŸOÿU; ÛS4öï%°2ÇÞ(2ãþ5Æ×6í%²I"(å£\€G=k ‰@B–¾ŽÝ±ÿÖâ£;”å°Çoóÿꦻd’äI$¼‘€t õ#Ú°µáln {Y ŽðæR8`Ì?ô´FHs·#Ž@Èõæ³®Oïßÿ×T„AESh¢Š³¨ÈJïþ»?ó5V­jò»ÿ®ÏüÍU Š( Š( £<æ’ŠK"ôv©äÀcp?QUè  ‚ô÷AøR‹´'æR*%+æ‚Ïf?ˆ§y‘7ü´š3K•ÍE+Ûñ¥'Ó5—œõ¨ ãÎŽ@¹¨“ǧYžtƒøÚö‰¾ir…Í £<õŸö™{¾~¢—í2úÊŽF;£E¹=i»OsT…Ü£û¿•l”t ùQÊÂåà3ņ@æ¨ý²QýÚoÚdëŬ.‹ÄnÞ”¥¸'Z£ö©íMûD§<þ”ùX®\gÞ¤ZCÐñÒ©ùò{ô¤2¹à±æŽQ¶ŽzûS\žõW{â4ÜŸZ|¡rÛ• H#=¹¨|óè**J,;–Àþí/Ú¸5ZŠ,,ùÊ{ŸÊȤòxªô¹¦"}ËýñI¹sà ‚ŠVÐäðF>µ4{W«.~¢¨QE€Ò£ÎC{œŽi|ÈÎrWó¬Ê*ysK̈ËEüé¾t}ÜYù¢ŽD/ý¦!Ñ¿CQ<ñžrÄööª´”ùP\œÌ@hûAÚ ¢„LgcÆI Þ nƪջaû¶õÍ ÉG4«†=j&BOZQž:TXd§“Š\â˜uÅ pØ?…+?>”ÉÔ…É=;Ò'·€oz@Ni§¯Z0wm⨠ïR5&¼ö dàÐN{TK‘œõ?¥IÎ ü©ZÃ@zÔ°8I0zT_Z@Fi…È3·ë^¥ÿ ÇIÿ …÷ä”±Òè!}ù%yx¸ p~´árÀ`ɯNÿ…c¤ÿÐBûòJOøV:Oý/`<ËÏÿgõ£ÎCÁã^ÿ ÇIÿ …÷䔟ð¬tŸú^ÿß)E€óQ:w”Ü'Lþ•é?ð¬4Ÿú^þIGü+'þ‚¿÷ÊQʇsÍL±ñõ£|}Cr{æ½/þ†‘ÿAßûå(ÿ…c¤ÿÐFûòOð£”.y¡‘FQæ/÷Åz_ü+'þ‚7ß’…ð¬4ŸúÞþIþ¹Bç›ûÃ?Z›C"þuèßð¬4úÞþIþ°Òè#{ù'øQÊ<ãÏLðÀQçÇ“ó ú×£ÿ°Òè#{ù'øQÿ ÇIÿ ÷äŸáO”|Çœý¦20I {r_,g‚Ä{ ôOøVGý/$¤ÿ…a¤ÿÐB÷òJ,IÂG«A2„sœsOmxc nÇŽï]Çü+'þ‚¿÷ÊRÿ±Òè!}ù%Î.5'vmIô&«›© ^Ÿÿ ÇIÿ …÷䔟ð¬tŸú^ÿß)E€ó#uqÿ=_ó¨ÌŽz³©¯Rÿ…c¤ÿÐBûòJ?áXé?ô¾ü’˜WúÒWªÿ±Òè!}ù%ð¬tŸú_~I@UŠ1^«ÿ ÇIÿ …÷ä”±Òè!}ù%yV(Åz¯ü+'þ‚ß’Qÿ ÇIÿ …÷ä”åX£ê¿ð¬tŸú_~IGü+'þ‚ß’P•b€ è+ÕáXé?ô¾ü’øV:Oý/$ *Áô4W«ÿ²Òè!wù (³·ÿX¿ë’ÿ!Rw¢ŠNÔ´Q@Òw¢Š@:›ü4QL "ÑE(¦÷¢Š^ôzQE%-PS¨¢€KETtQ@¢Š(h¢Š(¢Š(¢Š?ˆÑE/E¢Š(¾´ê( 4QE6–Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¯ÞŠ( Š( ÿÙfotoxx-12.01.2/doc/images/curve-edit.jpg0000644000175000017500000004733311701011016016425 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí6Photoshop 3.08BIM resize sharp ÿá 4http://ns.adobe.com/xap/1.0/ 396 253 ÿÛC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;ÿÛC  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ÿÀŒý"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ì¼;áÝ _ é2I¢i®ïc3=œd±1©$’¼œÕ´Ñ¼.÷²Y.¤ý¢44_b‹vÓÀ?w‘žõ7†äUÑÿìoÿ¢–©ø[PºƒOÓrš´_½Žìt²BpYÏpØÆÏâ>€T2dѼ/%ëÙ&¤µÄq‰1e(¤àòñ“œzàúS/´= Ö5eðþ”Å›ÙEèÙ§øpÅm Úl‘4ZŒMæ]ï;Á< ƒœ`wxÅXÖŽ-âÿ®ŸÐÕÁ^I'esì'ý ºGþGÿÄÑöþ…Ý#ÿ£ÿâhÝFêêöQìsûI¦•£4^kh:i»h2[B¹?ˆ¥]#D‘ÂG¢øyÙŽ¬POåYú¹’M2$Ž6}·!Fqòš©¦O%ž¡m<ö²$I 9 ÉÆ=qŸÂ¹¥e+XÚ:«ÜÔ:+tðæíÊ?þ&c£áÍ “ÿNQÿñ5£¤:YY}¦yV)ØÔ•-è[ùf§ŠÞº¹$s>UáWl ¤ò Û–+tgÍ'ÔÊ}3JŒþÒÔ´–±Œsé÷iŸbÑè\Ò?ð ?þ&·&4»åÁ¯°I<¶£[X¢šÖ9-Õ܉ ª°=þRy犇T6åÜÇûŒÿÂ9¤àüMaÑO éøÿZ×K·Ož(„ùsÅN £3øwïRé2°°ˆ fs¿ÀÀä稢еì+Êö¹‡ö=·‡4üÿ‰¥{ "7(þÒU‡Pl£ãµ~å Ž×ti-ï™è3Áqb´“P1ÈgPD¬~ævúš|°ÞÁyw1 †¨®|3¤…oºÆÊ<üv›ö=Ì·¤àüMm§ñAlñ£#<àyLtÅ0¸ihâxvª»îç<ü½zR´;åÜÇû&ÿBæÿ€Qÿñ4}“Fÿ¡sGÿÀ8ÿøš×H즚ÖGŽ8üÁ((ÊJœ/zz[ÛEãû(ºîÆÔlõÆîŸ;C°¯>æ'Ùtoú4üÿ‰£ìº7ý š?þÇÿÄÖÄ.’Ò‰YXüùÏ™ócåçô"Ÿ´ØÍ+ˆ™¼²Êê9= Ï_lSå§kØ/;ÚæOÙtoúôüÿ‰§-$F$>ÒB1Àceþ;Z×QXù¤4qÄ‘],d©ê¤dæ¡Ö?wilq+á#l½ZJ0vÐ/%ÔÍû&ŒÿÂ5¤cþ¼£ÿâh[]˜*økH$ð²ŸüvµošêHCZÌ¢ÃʪºŒqÈ#®iòÇg b@¤jј%WËH‹#4ùaØ9¥ÜÇ{M!£økHVS‚ ”`üv›ö}þ…½ÿãÿâktAn÷Wã†BnÊÏ ## Žk6ñ ŠÂÙa‰˼™w`6éBŒ–井>Ï£з£ÿàüMIme¢Ïu'Ú@8REœ|dÿ»U÷U9³©Zÿ×dþb´tamˆU%}ÍᯜãBÒøëþ…ÿ^Kñ¯O±Ó¯4•±±µ´WŽRÂÞw+×h¯kN²¾?¯øïÿú7ýr—ù­yçaèzV³m¦xo@‚X®¦–}:&D¶µ’c…Ž=Ä„æ^¾µhx’Øgf°3×MÇ?øåcØÿLJqÇüS³è¨*=XÕõ¨ý¯Â²H¶÷¯ /nV Pt$I $ûŠÜÿ„’Û9þÌÖ3Œgû&ã8ÿ¾*µö³m{'Øu˜ö¶ìÿd\ðG÷}éÿÚv]´\úð”RkCå»·žÎN¢;‹iˆõÆ:uü4ÚwBi5fQûE·üðÖ¿ðKqÿÄÒyößóÃZÿÁ-ÇÿZ©ªøiÐ?Û¬“?Ã$Á}Uˆ"´~Ãiÿ<ó5§¶Ÿr=œNd\[©%c×Tž»4‹•Ïä(3Û³hµÖ#¡}"å±ùŠéþÃkÿ<ó4}†×þx/æi{In>Hœ¿kœýŸZÏýn?øš<ËB1ö}gÿ·üMuaµÿž ùš>Ãkÿ<ó4ý´û‹ÙDæžî)#HÝ5ÆHþêã ÿŽÔ{í1³k?ø$¸ÿâk©û ¯üð_ÌÑö_ùà¿™£ÛO¸{8œ¶ûN?Ñõž:Ä’ãÿ‰ ½¡96úÉÿ¸%Çÿ]OØmç‚þf°ÚÿÏüÍ?m>áì¢rÞe®säk?ø%¸ÿ –å·BnÄ­Ô.p3ÿŽ×Iö_ùà¿™£ì6¿óÁ3IÖ›g•ÝhzÁ¬œõÿ‰%ÇøQºÐœýŸYÿÁ%Çÿ]WØmç‚þf°ÚÿÏüÍ?m>áì r»­?熳ÏýA.?“6xÇÙõœØãÿ‰®¯ì6¿óÁ3GØmç‚þfm>âöP9\Úg>F³Ÿ_ìKð¤Í¦säk9õþĸÿ êþÃkÿ<ó4}†×þx/æhöóî?eÇ)›AÒ gÿ—á@û é²>š%ÇøWWö_ùà¿™£ì6¿óÁ3G·©Ü^ÊŽSý9ò5œúÿb\…è™Ï“¬çþÀ—á]_Ømç‚þf°ÚÿÏüÍÞ§pöPìrx³ÿžÏõ¸ÿ _ô\çÉÖ¹ÿ¨%ÇøWWö_ùà¿™£ì6¿óÁ3G·©Ü=”;¦mç–µÿ‚Kð©-¦µ·ºŠ#Zo-ÃíþŸÁÎ>ítÿaµÿž ùš>Ãkÿ<ó4{zÃÙC±šÞ&µEf:v²åöUÇÿ^_ñ¾xî¥ÐnamÑMlò#cVÚAüzÆ¡m 6Û¢Œ!"@H'‘åIþ¼oâÇü‚¼%ÿ`ÅÿÐ#¬MOE²ÿØ»7þŠ‚»$žI8®:Ëþ<|=ÿbìßú* ì[ïJPÌ£ˆúJ(7‚ ¼Bîz³Æ¤ŸÄŠÎÿ„cD\ùx³'ï5ŒÒZ³{)#ØÖ­’týVÐÄ¿VÆ:A¨CæDYT«س‰¿'9åôxžo_YkºC¦Û vÜÚÚLÃåpn?yq“¹>«¾¥ÞØqã§4¥åµõ¸¸´&ˆ’7!Îê¡ÁäTÕBëF°º¸7b³Þã‹ËoÝÍÇ@X}õÎÇܤ•8¨<ícNââ©ÛŽ“[(Y€ÿj2pǦJžÄàp(ZŠ­ei©@f³eEmŒ†FêU”ò­Èà€FzUš(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š¥ªǧýüÿÑ2W‹üXÿW„¿ì¿úuí§üzßÏý%x¿ÅùxKþÁ‹ÿ G@‹eÿ>ÿ±voýv-÷qÖ_ñãáïûfÿÑPWbßxÐQEQEQEQEJûK†öeºVkkÔP‰y_4&s°’ääü§Œò0À[ûB÷KÕ¢ó ?nµˆìAÿM%“×#*rF2u¨ƒq@ ŠX®!I¡‘%ŠE ’#WSЂ8#ÞŸY’èÞ\ò\é—rXÏ#tûðÈÇ’Lg¦NI+Œ–$äœÓ¡Õ^9’ßT´639Â>ÿ2 \,˜ã³'œhFŠ( Š( Š( Š( Š( Š( Š( Š(  Z§üzßÏý%x¿ÅùxKþÁ‹ÿ G^ѪǧýüÿÑ2W‹üXÿW„¿ì¿útè¶_ñãáïûfÿÑPWbßx×eÿ>ÿ±voýv-÷%Q@Q@Q@Q@Q@G=¼P<0G<.0ñÊÕ‡¸<’ŠÊUÕ‡:Eé?åÒñšHϲ¿.„úüÀd§XÓüFÓ¬|ImáÛý>úßPžHâ?*•œàå+ÎsŽÈug\øwD½¿÷zEÅÚãKfé×Ò€4z+(i6Cþ$ú·NŸf»C<#ýߘ:Ÿø^¿)'!­®Ihqªéw6`už1çÁÔïNUGº¡9àpp¯EEmuoy›m¡"É{¤X\ºŒ+KlŒ@ôü#–w[ͨۺÿ«1ê3•ŒöÄlå0?ºT¯lcŠÕ¢²²u(xÚ7þMÿÆ©~Û¯Gò>‡Ì:Éêo¦ì7· rnh^ŠÈþÐ×?è]?øøÒÿl^ÇòÜxQuÄ%\¼¯µYÕ?ãÓþþè™+Åþ,È+Â_ö _ý:ôØ|A.­¨êº|š|¶k§¢2ùÜ;ùÍÕ{co­y—ÅùxKþÁ‹ÿ G@‹eÿ>ÿ±voýv-÷qÖ_ñãáïûfÿÑPWbßxÐQEQEQEQEQEQEQEQEQEQEQEQEQEQEOU'ì`výçþ‰’¼[âÇü‚¼%ÿ`ÅÿÐ#¯hÕ?ãÓþþè™+Åþ,È+Â_ö _ý:ô[/øñð÷ý‹³è¨+±o¼k޲ÿØ»7þŠ‚»ûÆ€Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  Z§üzßÏý%x¿ÅùxKþÁ‹ÿ G^ѪǧýüÿÑ2W‹üXÿW„¿ì¿útè¶_ñãáïûfÿÑPWbßx×eÿ>ÿ±voýv-÷%Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@µOøôÿ¿Ÿú&Jñ‹ò ð—ýƒÿ@޽£TÿOûùÿ¢d¯ø±ÿ ¯ Ø1ôèÑl¿ãÇÃßö.Íÿ¢ ®Å¾ñ®SGf_ ÄùÚú Šq×;zéLMÞîÇgÿ@ÑQy-ÿ?SÿãŸüM6EÄòË{2")ffòÀu'å  è¨"xRh¯fxäPÈËåÀô#å§y-ÿ?SÿãŸüMKEEä·üýOÿÿøš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿòÿ@ÑU hî¢ómõ &q]Ñ´l7‚2¨<#håšX#Ô$yaǘŠÑ’™ädmã4fŠ‹ÉoùúŸÿ!ÿñ4y-ÿ?SÿãŸüMKEEä·üýOÿÿøš<–ÿŸ©ÿñÏþ&€%¢¢ò[þ~§ÿÇ?øš<–ÿŸ©ÿñÏþ&€+êŸñéÿ?ôL•âÿ?äá/û/þ{Eô²™Úid)• ·(Ge‰¯ø±ÿ ¯ Ø1ôèÓt/õžÿ°ÿèõ‹NŽž%Ðd×’ÌØª]7Š­틽Ær8©´/õžÿ°ÿèõÔ†eèÄ} 1öétÏ0î¬lnµ'K?Ù–6žEm¨X ŽrÀ§ÚÜêz½›Éy}r=.(‚„šFiT–ùrrzcõ®÷sÇ>¹£{¬}zÒþ¿·õó<â[Z¶ð¿—,ò[ÞÆmD¨0±ÛÙ‘*6ÖààîbÒÀÇ:VRê—Ðè¶Òk~d7WwíZ|Ë!x•IPÒA…À®×{xþtcœ±ç¯4î+hqž4†}wPƒB‚Êòêák™þÈȬ‚±»(á¾lgøzRéšž©®ÞÙK$÷6òÁ§´—±íU{¨äØêÙ‚AàÁ®Ç'ÉÇ¥)f#‰™¤3Ït-sUN¡{öÞd¹³†p×POž@O-|°>a†ÝŒµ k—ÇE¸šOÂ!¶Ô¤‹}7)äî1¤þXRÁŽ~ïlg½zF÷?Äx÷¥óûíùÐ{9|ûyöK™¶É†r:0õõ©¨''&ŠlQE†QEQEQEÊ _JÒÕa:ÊÆ0V“`†$/LWm½€ÀcǽØõcùÐ†ÑÆøÒ)u›Ë?Eew{–×WKlÈ®ü±ä»(ûüõþÅ&“¨êšÝÞ”·6³Ae7Û-ã*\Äê…Xx<žFë]–N1“JRÌF zf4y÷‡õ½XÙÞÞß_}­á±y.ì"˜5Ì3Ñcò×ËÇ#·@yªñkwͤݻxŽÝ ·¼d¦þ6óÔÆKD³ùawgîöÇ|פïn>cǽ/˜ÿßo΀3DÿjðÚÜùsGæÙïÙ8ă)üC×Ö¼kâÇü‚¼%ÿ`ÅÿÐ#¯mÔtû’ç“ÿ#^%ñcþA^ÿ°bÿèÓ‡¦h‡ið±´'?ùÞº;+î, žY® ’Ʈؔ’3ÀÍèÝ$mÅH p}÷~•KÃÞ¥ª‹ßí 6KQ Ì‘£³Æ@à'ÊÄîÏJ¿pÁµˆ±ÿ>ÒèI@ Šy}bðH$~F’CJÈÿ¶ÿúPì«ùésÿÛühþÊ·ÿž—?÷ý¿ÆªÜëémtð3T—aÆø¬ÝýëUüY¬ßèú9¹Ó¬^æMÊ @#€ä3 ç8ã<ЗöU¿üô¹ÿ¿íþ4É4¸„lcžáU¼Òp~‡ƒK&¤ðiÂî{ ¤“ø­£A,‹Î:! úði–zªêÍ‹;Ûm‹ÿ/6íìúg­V–S>„Ó0¥µÞ@õ)šñ‹ò ð—ýƒÿ@޽•äZOúòúx×ÅùxKþÁ‹ÿ GHg¥èßó+ØOýo]„ŠtëP B€÷ä(W?¡¬ð§ý€ßÿ@·®ôû»Ù[»¬ÑMXó3×ê(ó9Ϫ¿Ùšwýí¿ïÒÑý™§Ð>Ûþý-¸}FÍAÉVv#Ðl#?™»Âj«“Öì¹Ü¦¤†ÚÞÛ>E¼Qnë±æ–X!6O J½pê  <Ïz<Ïz«ý™§Ð>Ûþý-Ùšwýí¿ïÒЯ3Þ¢º™VÒRÌØy?J‹û3Nÿ }·ýúZriö1¸t²·V‚"Ч©)_¨ åc#ÓÍ\iƒ±u`ÊÇ ƒÔTä0 Õ3£i$’tËRORbi«Y’Ó¾„žgaÀôy•ö.“ÿ@»Oûô(þÅÒèiÿ~…;ÄVdR¿Ó£-öøï€­“úжîS€“ÑH£ÜåN? *u½›µ´†=LhjIbŠt)4I"áuÈ©“Oa¤?Ì÷£Ì÷ª¿Ùšwýí¿ïÒÑý™§Ð>Ûþý-IE­þ˜J«¸>®¸9ÙnÁ½²Ëä*?³4ïúÛߥ©¢‚t)1ħ’@ .QºRpY# z»?ÌU­ÿJŠkk{€ðE.:o@ب¿³4ïúÛߥ  ^g½DZúŠ«ý™§Ð>Ûþý-Ùšwýí¿ïÒÐ~á–ÏÌ×;œ0'ô–å‚^Ù³1ÆO©Fõ§ÃgknÛെ&Æ2ˆ©$Ž9P¤¨²!ê¬2 ;½Ç|¨ª¿Ùšwýí¿ïÒÑý™§Ð>Ûþý-Zó=é“L© »°U I'µAý™§Ð>Ûþý-*éÖÁ’ÆÝXrˆ(¥<: ¶`{•ã??äá/û/þ{n¡ÿ ûŸúäÿÈ׉|XÿW„¿ì¿útéºúÏ Ø ÿô zê+—пÖxSþÀoÿ [ÖÆ©¬Á¦Io“=ÕÝÛ‚ÖÝA’LrÇ’rI hQTcÕí¼—{Ãö a‹Îš ™b3øRï»ÿ mÇý÷ÿM†þÛLÑno¯%[Á$¯#‘œÆ ¶ñU¼—Ã}a}¥ý¡HùPcʱÚ@ím§ãƒLE÷ô ¸ÿ¾ãÿâ¨ßwÿ@Ûûî?þ*iâþÚk›MZÎâ q™¤ŽueŒ´Aâ“þ]û7ûKûbËì[ü¿´}¡|½Þ›³ŒûP$¸–ó.,¦†1÷¤%_s†'c¥Cymá›Ë«;ˆî ’ÖB’ÄᕆÓÐŽµ;}ã@Èå‘!‰¤s…Q’i‚K¦†›qƒÈËF?BÙ¨õ?ùܸiú¦ºšuüXÝßÝÏʰÛlÈE 3ì£esÏJ@.û¿úÜßqÿñTo»ÿ mÇý÷ÿR6½¥Gz¶3jÐÞ2yŸf’eŒò¹ô§ÿli‚4“ûBÛd„o5pÑ eÇ<¯#žœÓ]¥¹K¾prH(Øü •dEt`ÊÀ2‘ÜšÃS±Õm¾Ó§^Awâ¾d\ŽÙGKÿ=ý{Gÿ ŠµERQEQEQE^ÿþA×?õÅÿ‘¯ø±ÿ ¯ Ø1ôëÛoÿäsÿ\_ùñ/‹ò ð—ýƒÿ@Ž€=7BÿYáOû¿þoZ:¶™{.¥e«i’[ý®ÍdŒÅrYc–7Æá¹A*APAÁéŽõ¡¬ð§ý€ßÿ@·®¢¦© ë׿ætþÌY¯ì Äfy6Ä–VVòòÜ1È!{sWáy Öíçš3¤±,l™Ê‰S'ï.F3[ÔS¾– ksjFÃOœÞC&­Ü—wN³<)3ºì;\+2áv€vžžõ~÷Ã&oÂ?j°ÀL`miÑI}ì7í G\ ®†ŠÇ5¬øB;ÈRÛNdµƒÉ¹üÙÛ2ÄPœô=yVãÂwz‰¸¹0Mä6Éy ÞËF‹ºâ3æã;y×ÑEÅdCn.wÜ•¶PÓ‘žS—È6sÓ=¹©¨¢‘F]ÞšºÏ‡nô×”Ä'’P$;NòAÇ~k+VÒuí^ÜKª›XÁ+A“;µÄÆ6@NåGÌ~Q»“Ö·¾Ës?Ù®cDf-¶HK`ž¸!…N¡ÿ?–ßø ßü]rÏá=WZÓKjogeqý›¤QÀÎû¶²¾d%TŽT  dòkBßÃw A<‚®¿´¢»¹cy%ǘ¨¥F‘~lcÀÖÏ“¨Ïå·þ7ÿG“¨Ïå·þ7ÿNúÜ›ib„:|º^­G+ÆßhšêáDdà+ä€r=s[m÷Q’ÎêxÚ+‹¸š'uޤŽã%ò«¤ä悊šŸüƒ.?Ü5KÅ:eæ¬+k=>möÍsq$2Àç€ÈQIúŒŒàV¤ð­Ä çkŒTN¡ÿ?¶çÜÛ6Oþ?Hxxo_“T°{ÝV;ë{Kˆf<î„@y! –-“¸¸ëÓŠŒøy4½NÊ[ø˜¢ <€ß¹d2…rÇiÆ~TZé|Cþ-¿ð¿øº×þü¯øQý—¦ÿÐ>×þü¯øPy´´ÿì½7þö¿÷åªY‹ëÄÚ­»ë°Ùjm©]į$FÝ¢’d†U]Èê§£Ò}ª+‹ë›½ «Ýv9l Ö hïฆW·]¿6÷TŒ1•à7>µÛj/÷/?ð_þ&íEÎv^gþ½eÿâi-£Åž û™§Gk«MÚc/ÿŸQÈdwB¤·P öÅ`Üj/s§^ÞÞíK‰íô{ÉÆÝ¸Q"4ŽÊ9Ï¥wcTPr#¼çþeÿâiµþyÞà,¿üM GqIs+ë,n:}Žãׄ¯ø±ÿ ¯ Ø1ôëØnäk¡4ë«v²©i#dÉ`:í^=ñcþA^ÿ°bÿèÓéºúÏ Ø ÿô z·­øVÇ\ŒE{k Ü"_5I&ø†Px8äbªh_ë<)ÿ`7ÿÐ-ë~kè¢—É ,²’Æ\¨÷ÇJC +4²‡b¬k…TTŒ‘¢‚Fyã'“Ôš¥>‘t5©5+è ûL)ÔS@d¨X©Rm?;ã‘éZPOÌ{ã9í Œ}ìi“^Ú[ȱOu NÃ*¯ R~€Ð ^³Ãgsªy¶vpM œi×A"”˶HbˆÞ’ÝK°Ç«¤Iyc•þ-²dTO›ä$1äWMPÍwoo$1Í*£Ü?—±åÛÀü V+éºbé³ê,»ÖòáeUÛ,,iÏ?s9÷¬Y<w'ÛJk j.™H†Ö)#‹"Mä°ó3–)(W9'­uP $¬s6>¹ÓM¬Öšœ sÓ»·w–P ¨÷dl%,ž+˜wj‘½¥¨¹ñ}œ‰ÎÍ» ž€WKE0±Ìj¾ŸQÓ¬,“UÙ¥™µet“cä(ó0Ž¿0ÁÀ$ŽOû Ï$wöÐêq¥¥úÄdF·%ÕãE@A Eãt”PF’+¨‘µ Úm½ãÞÃmäbA#ÄÎ †f=3Û5&“áÏì¶ÒI¼ó³,ž×ý^<ÍØùºñÓ§5·E Ø,¯p¢Š) (Éõ¦Jþ\NøÎÕ'Û{§·Žg¿™ZE B*23MK“ëFO­'ökÿÐBçþùÿ‰£û5ÿè!sÿ|ÇÿÄÐäúÑ“ëIýšÿô¹ÿ¾cÿâhþÍú\ÿß1ÿñ4¹>´Rf¿ý.ï˜ÿøš?³_þ‚?÷ÌüM.O­>µÌ2ØùR‹§™ZU’E_â8È „ÔôdúÑ“ëEdúÑ“ëE_PÿuÏýqäkľ,È+Â_ö _ý:öÛÿù\ÿ×þF¼KâÇü‚¼%ÿ`ÅÿÐ# MпÖxSþÀoÿ [ÖþŸsŒ·Q]H°»ÊdWs€ê@Æ·LV…þ³ÂŸöýÞºƒÈÁB3@BëqyuuýÌ[ÞWvX{r£?ì×â}"þÿÄzŒ¶V¶²•Ñ‘Òm<Ýÿ¼|¬m¸|sß·ë¹$ž´dã8 GŸÚI«6»msÛÀ¦ØY}ªiW}¸EÜ5ˆ«1;Á,À‚u–žØ¹5ÔbÕ¥i }þDpâ6Q¸Ù·ž¹'5Þon~cÏ^hÜØÆãLÓ¾·´°”QE"‚Š( Š( Š( Š( ®ãÚ_÷ò¬róP¶>M7cK-ØFŠIš$‘~Ï!Ã0V8È¡ä ظÛJR‡ùT ­ÜZ}ı‰Ól6â6>„ðyá˜`úÐ'ª0äñ|ò è4ˉnÊéͪ\¢’4`@S»’Hld ðsSAâ]N÷XÓ>ÉýŸ-´ösËs\±EÙ".å+s0ü¤/'¯|h:J¬j–Ï”’¤m̨Ê$`ï†V–õã¶)©áÍ1oåÚ:5³»Æës(rÎrå˜6_qÄç Ì¡+µ-CJû=•Õœ·–À’FD]ØuÚ’¸#‡bE:êvQ]­îmÔ[È‘G|]O Œo,m œœ«qxsG¶›[(ãy¢x‡˜^XãWÎåXÙ°ªIåWÕ-#ÁÖV\­ì¦ù®<¥#tªˆ±0d ºGa‚ûØã¦­}AÞÚ^øÆm3U²Óîí¬ZI¦ŠÒÞñÞHZGÚ§ ò$¼qÍtñž±4Ð,%“-ÏÚL,ú‹)Ä †Ü<£‚zŒgÜŠÓŸBÒ®µí mœÜ#•ŠÜJˆî‡(Ì‚± d•$z>™ „ÇhÀ%þñÎß4æNüçß§lRC~BE5]O¿éíåÝW.§tõªÃ••ªâŠX’(Á' ¬SÉÀ|õ¦÷ÐÁERQE^ÿþA×?õÅÿ‘¯ø±ÿ ¯ Ø1ôëÛoÿäsÿ\_ùñ/‹ò ð—ýƒÿ@Ž€=7BÿYáOû¿þo[¶¶kªI<·2ÍåÇ!"ŽFŒ c’T‚OéXZúÏ Ø ÿô zè~Îé+ËmpÖï'ßC«{àô>ô@os=¡‘¥X‚:3œ° »å'¾6ŸÌVMåî©wâ 46âÚÍ-mVâââxL¤ïfUUPËýÆ$çÓŠÙ†„6¤wmÏ#Ÿ™OÀz ¡©h6º•Ê]ù×V—H†/´ZHÚ2rQ²ažy˜  'Å+ …kyom`·—WÑ8TKŒª’Iæ3ÅR¶ø‰¦M§ÞÝÈŠ¿d†9¶Ås¡•Ûj‚Êp­œd™­«OivQ<1ÂïÙ¥“$¸4JX€}òí“BhßÙ’é×w×–Ò ·å¡ ÷v0‚9$ž4ÉW2íümå—™gf.nEêYùPÝFèY×p"@v‘€[Z>¦ºµ‰¸ò^ #™à–' ”t8##‚=é«£Äa¶K«ËÛÆµ¸Éq"–Ü8P1íÆ§±°·Ó£–;pÀM;Îû›?;ŸÂ?¯ëÔz–h¢ŠC (¢€ (¢€ (¢€ ¬Úu‹±g²·f<’c5fŠ«ý™§ÿÏ…·ýúfiÿóámÿ~…Z¢€*ÿfiÿóámÿ~…Ùšüø[ß¡V¨  ¿Ùšüø[ß¡GöfŸÿ>ß÷èUª(límÛ|°ÄÝ2ˆ©¨¢€ (¢€ (¢€+ßÿÈ:çþ¸¿ò5â_?äá/û/þ{mÿüƒ®ë‹ÿ#^%ñcþA^ÿ°bÿèЦè_ë<)ÿ`7ÿÐ-ë{ϹžwŠÊÝeò¸y$}ˆ 8$ŸÂ°t/õžÿ°ÿèõÐZÌÚkÎ’A4É!‘$… „Ô®1@‡[ÌÒ‡Y#1KÚñ“œz{ƒëTuiz]Ó[]Ë8‘!¿—k,«d‘¹™…’GJ½™-Ä÷RÆb2„D±¸*îÁ8èIcǦ+”ñ&‰©^k÷6ö—óAq¦­°6w‘CóïbCï`vá‡@{Ð3£ƒV¶¹Ôe³ŒçʵŠëÍÈØÉ#0\øüÅ\2"†,êý잟Zã¯<5«ÍmsnÐÛHóhö¶ûÑÕb󡑘¦ Ãàç£áý_W]Rñ´æµ7WÖ³›9%Þhâk)å£<ô pqÎ)Ù^¤¦úÿZ²º†R„ -exkMVжÁ."Ý,’ù3˜³æÎÐ"%÷3Z´1 ¢Š) (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š¯ÿ ëŸúâÿÈ׉|XÿW„¿ì¿úuí·ÿò¹ÿ®/üx—ÅùxKþÁ‹ÿ G@›¡¬ð§ý€ßÿ@·®¢¹}þ¡ÐŸ¾?‚Þºo.?î·ýüoñ QMòãþë߯ÿ<¸ÿºß÷ñ¿Æ€E7Ëû­ÿühòãþë߯ÿuß.?î·ýüoñ£Ëû­ÿühÔS|¸ÿºß÷ñ¿Æ.?î·ýüoñ QMòãþë߯ÿ<¸ÿºß÷ñ¿Æ€E7Ëû­ÿühòãþë߯ÿuß.?î·ýüoñ£Ëû­ÿühÔS|¸ÿºß÷ñ¿Æ.?î·ýüoñ QMòãþë߯ÿ<¸ÿºß÷ñ¿Æ€E7Ëû­ÿühòãþë߯ÿuß.?î·ýüoñ£Ëû­ÿühÔS|¸ÿºß÷ñ¿Æ.?î·ýüoñ QMòãþë߯ÿ<¸ÿºß÷ñ¿Æ€E7Ëû­ÿühòãþë߯ÿ†ÿþA×?õÅÿ‘¯ø±ÿ ¯ Ø1ôëÚï‘O¹ ù/ÕØö>¦¼SâÇü‚¼%ÿ`ÅÿÐ#¦¦è_ë<)ÿ`7ÿÐ-먮_BÿYáOû¿þo]E (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€+ˆä¼¿–s$ hùŒ.X±aü@ð6úw©¿²Ÿþ‚wŸ”_üEGhÛu[ÃÿL!þrW'¦jÚŶ‰£kSk3ÞµõÚÁ5¤ñE´†§ÈQT‚1žIéM ‡öSÿÐNóò‹ÿˆ£û)ÿè'yùEÿÄV-·Š¯e¾‚I, ]6îþ[e&mÈYw2ã%¡Èª6^;½M(j:…ºÅ6”ú”+m#1Ú¸Ê6@ç‘Èã­.— ëc¨þÊ~ÚÞ}ÄüEGi+Mj’>7e”‘ÐHÏéTü7®ê«\ǨéÏjЄd”C4q¾ìåGšŠIçг§ÇŠ¿'þ†ÔÚî,‚IIšhÞFt·ÊT`dü^ªoì§ÿ çåÿQ!Æ· ?óí/þ…déjÝÝö¡6µqg¥ô–égE°,gŸ0²–%ºðF6ÿ²Ÿþ‚wŸ”_üEÙOÿA;ÏÊ/þ"¹VñýÈþU­½ÂÇmö‹IJ‘È<ÕLè7˜ɑ֮?е8^}:[VÕ#½†Õ6JÞCy‰¼1$d`c¨÷  ïì§ÿ çåÿM}2TFdÔ®KH±•Ͼ~5ÎßøÇU²ÕÁ4Ÿ¶Kh‘5е†y7—'ˆÊ¡ 3ó‘ž•§ Nïqâ$¯ ME•71;G”œ ôx´Éæ—í#ÎFß6Ô¾=2¹¯ø±ÿ ¯ Ø1ôëÙWþE¤ÿ¯!ÿ W|XÿW„¿ì¿út†zn…þ³ÂŸöýÞºŠåô/õžÿ°ÿèõÔPEPEPEPEPEPEPEPEPDuT¸ @/ [sßóùnT°ðö‡¦]-Õ¥’,ÑçÊg•äg®ÀÌBg'îÖ´¥‚Ô,ÐÇ("ó¨ÿ³¬?çÂ×þü¯øPh´} Qõ8¬â[·%Œ›Ž‚Ás´1'¹§E¦iPG qÙ skœ°XŽ2˜'qÞ§þΰÿŸ _ûò¿áGöu‡üøZÿß•ÿ ‡N±Óô{vŠÈ4Qw(€7±Ú À©4ïùÄ}K0ú$~†œ4ûr,m…¬PIGªÀÌB†‚D÷mÈqõÀ'ðª×‹u¨hMh¦äíÞé+ “7ª°ö­"Žd),i"ªêüEýaÿ>¿÷å€(EáÝ (K%Û*l*ÓÈÊ«¸6ÕˆEÈ ÅOu¥iW¢è\ÚE'ÚÙbX‚̃ A*Gb0jÇöu‡üøZÿß•ÿ ?³¬?çÂ×þü¯øP!¡hâ[yD %¶$‚êPÌܶì¸Ï8lÕ¡•‘»ºR'¸;ç`Ç@ÆHÎÇ¥?û:Ãþ|-ïÊÿ…*XÙFÁÒÊÝX†X”úP"»#GáàŽ ²Ù€AìvWŒüXÿW„¿ì¿úuíº‡üƒîë“ÿ#^%ñcþA^ÿ°bÿèÐ3Ò4éÚÆÓÂ×Ïkw< £˜˜Û[<ÅY£„®BFvž}«Wþkoúk?ø(¹ÿâ+Ålþ/øšÆÆÞαò­¡HS0’vª…ùºàT¿ðº|WýËûðøªö_øI­¿è¬ÿà¢çÿˆ£þkoúk?ø(¹ÿâ+Æ¿átø¯û–÷àÿñTÂéñ_÷,?ïÁÿâ¨Ùá&¶ÿ v³ÿ‚‹Ÿþ"øI­¿è¬ÿà¢çÿˆ¯ÿ…Óâ¿îX߃ÿÅQÿ §Åܰÿ¿ÿŠ eÿ„šÛþÚÏþ .øŠ?á&¶ÿ v³ÿ‚‹Ÿþ"¼kþOŠÿ¹aÿ~ÿGü.ŸÿrÃþüþ*€=—þkoúk?ø(¹ÿâ(ÿ„šÛþÚÏþ .øŠñ¯ø]>+þå‡ýø?üUðº|WýËûðøªö_øI­¿è¬ÿà¢çÿˆ£þkoúk?ø(¹ÿâ+Æ¿átø¯û–÷àÿñTÂéñ_÷,?ïÁÿâ¨Ùá&¶ÿ v³ÿ‚‹Ÿþ"øI­¿è¬ÿà¢çÿˆ¯ÿ…Óâ¿îX߃ÿÅQÿ §Åܰÿ¿ÿŠ eÿ„šÛþÚÏþ .øŠ?á&¶ÿ v³ÿ‚‹Ÿþ"¼kþOŠÿ¹aÿ~ÿGü.ŸÿrÃþüþ*€=—þkoúk?ø(¹ÿâ(ÿ„šÛþÚÏþ .øŠñ¯ø]>+þå‡ýø?üUðº|WýËûðøªö_øI­¿è¬ÿà¢çÿˆ£þkoúk?ø(¹ÿâ+Æ¿átø¯û–÷àÿñTÂéñ_÷,?ïÁÿâ¨Ùá&¶ÿ v³ÿ‚‹Ÿþ"øI­¿è¬ÿà¢çÿˆ¯ÿ…Óâ¿îX߃ÿÅQÿ §Åܰÿ¿ÿŠ eÿ„šÛþÚÏþ .øŠ?á&¶ÿ v³ÿ‚‹Ÿþ"¼kþOŠÿ¹aÿ~ÿGü.ŸÿrÃþüþ*€=—þkoúk?ø(¹ÿâ(ÿ„šÛþÚÏþ .øŠñ¯ø]>+þå‡ýø?üUðº|WýËûðøªö_øI­¿è¬ÿà¢çÿˆ£þkoúk?ø(¹ÿâ+Æ¿átø¯û–÷àÿñTÂéñ_÷,?ïÁÿâ¨Ùá&¶ÿ v³ÿ‚‹Ÿþ"øI­¿è¬ÿà¢çÿˆ¯ÿ…Óâ¿îX߃ÿÅQÿ §Åܰÿ¿ÿŠ _»ñYÍiºÉg•GöMÈä÷+Ë>/Ã%µ—…­æB’ŧìu=U‚ #óªðº|WýËûðøªç¼SãSÅò[I©­¸k`Á (W ã9É>”ÿÙfotoxx-12.01.2/doc/images/select-edit.jpg0000664000175000017500000002557311701011016016564 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 273 286 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀÚä"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?è´½6Á´«&kVco$¤“´{T±ÙérK$KciæGÊmÔ‡§J“JÿEý{Çÿ ŠƒRÌÓŧÉó,£S×w±ÇNøöÍ?ìz_Ú~Î,m ›w-×ïÇ\Ùév¶ÒÜKah#‰ ¶-ÔðOj4¢‰ÂT­ÊœÎå™ñg¸8ãò¥Ö¿ä ÿ^Òè&€9ïøI¼)ÿ>qàÿ…ké'EÖ-ZæÎÆØÆ®c;­”€§¸­¦fÜy=}j‘&ëQÏüüýVžÖÆ9J:Èëÿ…GäÙÐ6Çþü/øTׇý%¿åPf¶QV2rw"3i m´ÀGý3J|CN›ýMŽŸ&8ùaCV Ó­ÞÛÈÎT ¦´ m~«bªpOS¹½i.G¢C|ËQ²YÛÄ“K²PzfÝÂ’;[II ¦Øä ÿ¨_ð«í~lO:ùlÌr…²½; ' åìvF8¿*4ì=L¿*Ëþ¶?ø¿áJ ´bé–Džƒìëþ !dxØwŽó¦°Øð²*_œc9úÓ´{ ì a³ƒ¦Ù?éÝœm­„bC¥Ùl<öuÿ –íd7[]@,~\£5jO.E’Ù_,‹ò®Þ„{ÑeØ.îgyVô ±ÿÀuÿ O*Ïþ¶?ø¿áW]}–6TÊ sùÔÒÆ¦x—Ëw1 †éŠ-»îfyvô ±ÿÀuÿ ’KKh‘YôÛ» ò?–*]EU2i+ó üªy]Zý#&РŒŽ§Í]‚ìÏòìÿècÿ€ëþ« £°UÓ,I=¿áZí ¸mÊÕN —ѱàÀ¦’}¶º‰-œ¨i4«%ãýBЖ–î¨ÃL°Ã¶Ñû…ëùU©âQt­,\fC–/ßáR¸oôu•fc…`Š›.ÃÔÍh-Tdé–8Î3öuÆ*nË?úØÿà:ÿ…]mídâ%VÛ#n7PM°ÆÛV>q³=:äuIG°›eXã³iN›c‚@ÿuÿ ÐþÌÓ¹ÿ‰}§ôÁ?³`?¿ýáüëluo¯ô"–ÅA·¹æ¾:‚5ÔH!Ž%òíŒäöTŸ?ä>ŸõÁ›QY–vÖW[išrJ_{Ú£*¤l䀫“À>£ó§¥ýš)ê\îb-däûüµ_MûúOýƒ[ÿhÖ¾h¿³2,†9˨ 7ÙdȨû´Kg4O±ÎѺ•e6ÒrQ÷jþhÍcãKÿžWŸ÷ÍÅMouajŒ°Gp¡›sf I'g$zùV–hÍcÜ\C,ÌàÌìm¥ÿâj-ñz_ü—ÿ‰­ÜÑš¥6‰äF窿þIÿÄÒ©…FÌKYøšÞϽ硧ÎÑ;¢þô¿ø /ÿF追/þKÿÄÖöhÍÒAÈŒÑz_ü—ÿ‰£1z_ü—ÿ‰­ìã½&}èö’Daf/ïKÿ€Òÿñ4™‹ûÒÿà4¿üMnM4pDdšUŽ5êÎØñ4¨ë"+£V A{I"0³÷¥ÿÀiøš3÷¥ÿÀiøšßÍ2’x–Hœ:7Fj=¤ƒ‘y‹ûÒÿà4¿üM»þô¿ø /ÿ[’L‘ÄŽÈÛ=ϧéOÍÒBäG?û¯ïKÿ€Òÿñ4¿»þô¿ø /ÿ[ù£4{I"9üEýéð_þ&ŒEýéð_þ&º Ñš~ÒAÈŽz_ü—ÿ‰£ÿz_ü—ÿ‰®ƒ4fk öhÁ£I‹JBãÚ_þ&´V´ÜΨæf·=~í^ÍRÖüI/ÿëÚOýÔJN[”¢–Ç ñcÄ ?é‚ÿ6¢—âüŒCþ¸/ój) ì4¦ÿØ5¿ökÖF÷ôŸû·þÑ­z(¢Š(¢Š(¢ŠÊñ2îÐnWhlíOCó ¥%Å“®ÖŽÑnîbŒÃhNÔ^rA r}€é]N”P95Åêë†ÛíkGŒB²ÈGš˜¾]¿1'#9¨ã½ÚÞÇý <ÈÊ“re^7}ÐqòqßÓ䌚7S@ö£ ½ðp­‡(17ÏŸÞ“ê?˜©5=5!ðõÜn)PÏ‹hÌHN8Êäæ·rsœóEdë1 âÓ¢,Êê<•8#ƒT®®®!¿–%¹˜\G,imoŒ‰S ¸ž9þ,žØ®4dã8¢ác7Jó${É¥šW?h’5F?*¨<`V%¼·–ZlÎYdi­çar•¸+ǹ®¶ŒŸS@´Ë ´–K¸ç…ocÁY … V'hîGâ¥Ð露¹µ y%ËH²¤nDX'iéÇ8ï]&Iîj+h#µ·H!FŸtžù¢àKEPEPEPTµ¯ù_ÿ×´Ÿú «µKZÿ%ÿý{Iÿ šá~!ÿÈÄ?ë‚ÿ6¢ˆò1úà¿Í¨ ÃNûúOýƒ[ÿhÖ½dißIÿ°kí× Š( °¬µ™¤Ïs,K &BȶÒµIþ2v“ÅnÖlz:G›»—·¾è¦Ó»9w=ýi ¥.«r..ZHå¶D‚&T!X圌õôâ´4ëÉîf»IaÄqNñ¬€Œ1Æ:皈h•”Kss)‘7;.B«n`zúÕ«{%·¹šhå—lÌ]¢$l q’8ÏoZz S;OÔ®[]«”¸¸òb.ÕùˆÏ¯nõ+ë`9H­&•”ɸ)Q€‡ò}êÁÒ 6)j$•Dry© #r¶íÙc¿¥2ßG‚¸K3±Yg#'yÉ<jEÕEÁ“ì<‘¢ix ¤®à1œžéëPÚê“©wsv//æIp¨ð†# Æzv¡´HíIçy'ÛºBT0Úr¸ÀƒëšžçO6ðF÷3‡…Ä‹0+¿pÏ'Œwô  sx†Ú#gB’»¼f'uM¥~öI8ôúæ¬ÉªDº\WèŽ@uN¾ìqMþÆcˆG4ñË3‰Õ†ö-÷³‘ƒŸ§j–ïOK¨àWšUx2J»wgdäОÔ:Â\‹²A$Í4~i±sŒ’O¯§¥@š¥ÃÛÊòÆcT»0¬‰´îfÜ`ŸN¦¬G£C À ¸¸‰áO/z²å×9Ãdc¯µ/öD?¼|þ[Ê&òò»U·n$qžM@Ž]zÞ·ÈޏówŽ2›~¤Œ}jm/T‡SYL@ˆ€À:¸ädr¤ŠGÑ­kÉX97jÆîýßNÇðfÖ·Œ£\K??z]¹=Q@RÖ¿ä ÿ^Òè&®Õ-kþ@—ÿõí'þ‚h…ø‡ÿ#ÿ® üÚŠ>!ÿÈÄ?ë‚ÿ6¢€; ;ïé?ö oý£Zõ‘§}ý'þÁ­ÿ´k^€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ¥­Èÿþ½¤ÿÐM]ªZ×ü/ÿëÚOýÐ ñþF!ÿ\ùµ|Cÿ‘ˆ×þmEvwßÒìßûFµë#NûúOýƒ[ÿhÕmqîEÅÛCs<_g²óFp î=G~: +žš[›oµÀ.n ÍéÌñÆÃæçÝ{f’éaX'’âSb·N¢gþ(öðX÷¸Í:*+—´¾”ÜØ¼·RMæœVL7.Ør1ó.1ô§Ò./&Õ\](pÎ$·g9Æ~RhÇnrs@ %`¼ÒÅk©]É%՜Ī$*¨¿/<1’Iª¶÷³½”FæòE´R#ÜDû¾P ¯ÏŽ™8Î(£Šæ ¶ùs#ÉP'ò55r–­rº|Ijò6—,„u-»å?Z}ΤnY ¿ Grû7͹wcån”ÔVsȾYšfœ–•Ð,o´*Õ”žu”í‘w 8“ﯽUÖ(ŒçΘaNR*àµ&OB/´[ÿÓçýý­¬b–$Krpe5IC+ºÅ!/½KÙ8Ç ŸjÙ€© }Ý£J©ÙlLuÜ­ýüö¸ÿ¿¦©K4VðA˜î®%u ËB÷cþyí[5’/Þ(’K˜¢Ì{€u=çœÖMš")»÷N^7@êIÏZ– †C,»÷  í+Á>†§ Š( Š( Š( Š( ©k_ò¿ÿ¯i?ôWj–µÿ Kÿúö“ÿA4ÂüCÿ‘ˆ×þmEÿäbõÁ›Q@†÷ôŸû·þÑ­|ŸZÈÓ¾þ“ÿ`ÖÿÚ5¯@O­9ÎNh¢€ ÇÔÑ“ŒdâŠ(Éõ£'9ÉÍP“ëK¹½OçIEM­ÛaàY“{:Ÿ3n2sW)’ȱ!vΧSM;W)ý‘?çÁïù«i5Äh¨¶ªFóúÔÏ:_ùôŸòãG/üúOùñ¦äÞâQKbO´ÜÿϲßÑþU­L°ÇöÑJ‚@#¡©¼éçÒÈ{îU6³Ç8äã>¾Õ#8vy€5-F^P2m¥ÀúëO2† ŒŠZ(¢€ (¢€ *9ÞË2K´à•úsIçKÿ>“þCühz*:_ùôŸòãG/üúOùñ  ê–µÿ Kÿúö“ÿA5:K#®å·”ŽGðÿUÖPVFFÒ7q´ÐñþF!ÿ\ùµ|Cÿ‘ˆ×þmEvwßÒìßûF¬^j°ÙÎbx§r±ù®Ñ¦à‹œdÕ};ïé?ö oý£EîuuªÈñÎ`·’ÔDì1o˜ä žZžmbÖJ1ÑB—•)o»¸ûÒÿkZùÑÄÅ•ä•ââQ“PÍ¢#—Ž;‡ŠÚP‹,!AÜ`a»p= mæƒÔ÷3 ‰"y°Wh»n2Ãê…=5û'hÀóv¾Ü¾Ï•7}Üý¨©­õ$¸ÉŽÞä§™å‡òø'8'è1ɨ?±!KáqWä ¯÷FÖ<¯Z³mdÖÖé W”ÈÇ`;bJûuë@^]Çg’@͹‚* Ë3€ «q­[[G26Ï1×g1.q–ôè*±}iö¸Ð Z)"q$nv°öî=ª¤Ú1šé.žxš}$/l¬¬$`òžOs@:Ì{Ä#—‡hÖB¿#8ÛšdÚ>Þâ{y’IÀÛPKq’G==Î*C¤!2œ}¨Üão¨Æßþ½@Úûkx¤ºYØþåžÀ.1†R~o¯f Z ™âŠÝ%“ÌŒI¸/Ê€’9ôä±wþ®?úíþ†*+[¶¹3˜V"ªGœÛ¯J–ïýZIc?øø }Eưl‡ÙÔVýä¸vÎsµqÎ1L²Õd¹¸…d€G ÈsÉ;}F8Èæ¦º°–îå[‘öt‘dÆw/#æÏLûS,ô‘mp’ÚHá Œ¨7r{új5^邽»1 $ÿ¸Õb«^4þšý¨´qÃvn?´G“>b³ ­éü8öëßÖ§·ÿh¿Ü_åU`ûzÜ·Ú'ŒÛ¦v•3çû݆=ºût«Vÿñíû‹ü¨ŸöÕŸÚZΠ3'šWä,£$gÔ`þF«Å­«Þ;:K ¢ZùÛ¥io˜G¶*H´8c¸™ƒFa˜»2Fð[®®9ô¨ßEo&o:æKŸô"5TÁAsœÀô  ¿·-¶øn#2¨‰“Å#>€þUrÒê+Ëežv¶FÁG¨"±!Ñ®oŒÓj ²_1"ñ)ûªGÌ AÜ{þU¹kÙíÒ,¡*9(úÒ€!ûY³¶Ò?2G¹¢“€XàjÝ…Û]$¢XÄsC!Ô6FzäLU–Ô^[ÜE¼Æëq½ •a‚*Õ§Ù#}Òe•Ì’9É>ƒ°â€,ÑE“ŒZÊÉÞ'}ÌbÆÐÓ1 ‘œîh>_ÜMmxÐ[Hˆ±Lc›cü¬ à’Wo$v&µ>Û-¾‘ö›¶…e ù‰RN1Û9>£KyYWPÁÓÌ;zü¹Ç?J•²6x-s†•‰é‚NF0(èh5Û‹˜àXmO%ÃÂÂBÊ£jîÏ#==E:=zI5…m\À’˜žP¯ò9bvíÆxëšž +r†1ÊHÒiŽâ0I$óÅc²/8wÎð$!X‘‚JçãÚ€IÖN¡s4,Š6"ÈŽ¶º’GñéÔqVm¿ãÝ?çUììì¬Yžß*J„%¥fÂŽ€dœ ž×þ=“>”5Q@Q@Q@Q@Q@Q@Q@Q@RÖ¿ä ÿ^Òè&®Õ-kþ@—ÿõí'þ‚h…ø‡ÿ#ÿ® üÚŠ>!ÿÈÄ?ë‚ÿ6¢€; ;ïé?ö oý£Z¬Šã ¡¾£5•§}ý'œĵ¿öj῾?ïŸþ½7É‹þy'ýò(òbÿžIÿ|Švûãþùÿëцþøÿ¾úô€o“üòOûäQäÅÿ<“þùì7÷Çýóÿ×£ ýñÿ|ÿõè¾L_óÉ?ï‘G“üòOûäS°ßß÷Ïÿ^Œ7÷Çýóÿ× ù1Ï$ÿ¾E>“ ýñÿ|ÿõèÃ|ß?ýz`:Šnûãþùÿëцþøÿ¾úôê)¸oïûçÿ¯FûãþùÿëШ¦á¿¾?ïŸþ½oïûçÿ¯@¢›†þøÿ¾úôa¿¾?ïŸþ½:Šnûãþùÿëцþøÿ¾úôê)¸oïûçÿ¯FûãþùÿëШ¦á¿¾?ïŸþ½oïûçÿ¯@¢›†þøÿ¾úôa¿¾?ïŸþ½:©k_ò¿ÿ¯i?ôVðßß÷Ïÿ^©ë ÿb_å³þ'oöMpßÿäbõÁ›QGÄ?ù‡ýp_æÔPa§}ý'þÁ­ÿ´k^²4¦ÿØ5¿ökÐEPEPEPEPEPEPEPEPEPEPrÝ!»c$gý)ÿg›þ{¯ýûÿëÓþ>-ÿÞ?ú ¬©îïƒj·1ß[7ù!hÔ¡`œnçë@g›þ{¯ýûÿëÑöy¿çºÿß¿þ½f.»3âql¢ÔH‘>_ç Àvô…0ëóBZ[‹tÞdÑ©F%ò€žF;í4¬mçÇ!>†?þ½PÕ_Ìðýä˜ÆëW8ÿ€~ªO~\OjÑŠêûTç·ÌHö㚆ÿþE‹ŸúóoýÐñþF!ÿ\ùµ|Cÿ‘ˆ×þmEvwßÒìßûFµë#NûúOýƒ[ÿhÖ½QEQEQEQEQEQEQEQEQEQEC3’'1Éÿ€‘UdÓ´Ùny# îÁ˜[kЕÎÞÞ•|€Fzo“üóOûäPV³ÓÞïíLˆeÈlï8$t%s‚}ñKö[(Ø„, ‰›;^ùpàAÿâhóuùóƒÿÿ^Oý©¨Ïý×ýþoñ£ûSPÿŸû¯ûüßãHXóuùóƒÿÿG›¨ÏœøøšòíMCþî¿ïóÚš‡üÿÝßæÿõ7PÿŸ8?ð ÿñ4yº‡üùÁÿÿ‰¯'þÔÔ?çþëþÿ7øÑý©¨Ïý×ýþoñ XóuùóƒÿÿG›¨ÏœøøšòíMCþî¿ïóÚš‡üÿÝßæÿõ7PÿŸ8?ð ÿñ4yº‡üùÁÿÿ‰¯'þÔÔ?çþëþÿ7øÑý©¨Ïý×ýþoñ XóuùóƒÿÿG›¨ÏœøøšòíMCþî¿ïóÚš‡üÿÝßæÿõ7PÿŸ8?ð ÿñ4yº‡üùÁÿÿ‰¯'þÔÔ?çþëþÿ7øÑý©¨Ïý×ýþoñ XóuùóƒÿÿG›¨ÏœøøšòíMCþî¿ïóÚš‡üÿÝßæÿõ7PÿŸ8?ð ÿñ4yº‡üùÁÿÿ‰¯'þÔÔ?çþëþÿ7øÑý©¨Ïý×ýþoñ XóuùóƒÿÿG›¨ÏœøøšòíMCþî¿ïóÚš‡üÿÝßæÿõ7PÿŸ8?ð ÿñ4yº‡üùÁÿÿ‰¯'þÔÔ?çþëþÿ7øÑý©¨Ïý×ýþoñ XóuùóƒÿÿG›¨ÏœøøšòíMCþî¿ïóÚš‡üÿÝßæÿõ7PÿŸ8?ð ÿñ5^ö=FêÆâÜZÛ©š6@ÞL‚3÷}ëËÿµ5ùÿºÿ¿Íþ4jjóÿuÿ›ühsâψTÿÓþmEsWÏ yæ’FÆ2ìIÇãE0?ÿÙfotoxx-12.01.2/doc/images/straighten-image.jpg0000644000175000017500000005721711701011016017610 0ustar micomicoÿØÿàJFIFÿáVExifMM*>F(ÿíLPhotoshop 3.08BIM0$resize trim resize trim resize trim ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 282 407 1 2 2 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ—"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?èÿáÒ:fÛ`zÆ3ëHt A'Mµsþ¬V•G9>SéH¢ˆÐôBþϵÔÄô¥ŒÝ4ëSôjXm¡d·æ,Ù*ĦŸöu|•šAŽÛþtƒþÝ#þ–¿÷èQÿöÿ@Ë_ûö*a ËÒç#Ñ—ü1K›µï©Ï4È?áÑÿèkÿ~Å'ü#Ú?ý-ïØ«"âá~ü$ÿºAÿ _¶÷ãdú©ÿ?Zå_øG´úÛß±Gü#Ú?ý-¿ïØ«Kyê*Q$dgpÔñ@ÌÿøGôúÛß±Gü#úGým¿ïØ­!†û¤ìhÅfÂ?£ù†Ûß±NþÁÒ1ÿ Ë_ûô¿áZ4Poö“ÿ@ËOûô¿áGö“ÿ@ËOûô¿áZ4Pwö“ÿ@ÛOûô¿áIýƒ¤ÿÐ6×þý/øVý‡¤ÿÐ6Óþü¯øPt-'þ¶Ÿ÷é´i§­gÿai?ô µÿ¿KþŸØZOýmïÒÿ…hÒPö“ÿ@Û_ûô¿áIý…¥Ð6×þý/øV!  ÿì-+þÖÃÜD¹þU›a¥iÏâmB²¶1$1°O,Rsœ è«#Mÿ‘¯Rÿ¯x¿­\—HÑâMͦZíñúT?aпègÿ~ü+Bç>Zý¥:ø÷ýÑü…›ö-þ¶ø¿áA³ÐºfÙÿà:ÿñ4ùµ»x\«,ÄŸ•GøÔð’Ùd“çýÑþ4ìÅqÿaÑ;i–Ÿø?øš>âÐ.Óÿ‡ÿQ·ŠlTò³ÿß#üicñ-”®#D¸f?Â#Ïõ¥a\“ì/ýí?ðñ4}ƒDÿ ]§þþ&®%ÑuÜ •Þ™¨eÕ¢€âXnzùy¡¢Ã!û‰ÿ@»_üüM'ØtOúÚà8ÿâh!±ÉϘ>©V#Õmå„J7í=öÓ°þÅ¡ÿÐ.ÓÿÇÿIö-þ–Ÿø?øš’MvÊ?¾îû¦š5ý8°S1\ô%N(å`7ìz'ý-?ðøš>Ç¡ÿÐ2Óþü/øU±¨ZÜ'VÆ¢‹X²•ÊG1f^ )¥`¹Øô/úZß…ÿ >Ç ÿÐ6Óþü¯øU‡Õ¬Ôá¥#þÂë s7þ:ßáNÌ.Wû&ƒÿ@ë?ûò”}@ÿ }ŸýúJ{kÚj}ùÿñÆÿ hñ”Ãþ>WñFÿ V ‡Ø´ÿ0û/ûô”¢ÇAÿŸ /ûô” kJ#"áüÿ…(¿Ò¤ç|'ܯÿZ‹0¸¿ÙúXYߥÿ Q¦h‡þaö÷á•çÓLFB"dÎ8LÿJ¯çèÍœù@{‚?¥ “ÿeh½³í1ÿ^ëþ«¤hîÛWO´Ï_õ þ½¾›s¸ÃåË·ïln•& A4ÑÆ0ž3žË@Çbi_ô ³ÿ¿+þUãE%ïQÍÄOîJ¥G?}ñüèGm¾}73\uÜÀÊÏ•'#ŽÂºñÆžO¢äk‚l‘Ÿj¤K-Å¨ÞÆÛÉqè[püY³Öõ‰$ÙYϼcùŒSô-.•yç_1…õü+jââYcT Ê‹Çç@[O~P5ÔVêqÑXƒýieÔüœ™!vOïDCþxÁ¬‚÷òylçg]«òþ½=tÖ·.SÝIÍúëlÜHø>އü*Â¥œ˜hÌc= >ßåXSÙý£zLYœ®P‘Üuæ¬ù#ìpîTÐP¢±¶RYã»ùæÂýÙÃ{2ÿÈÝ™-'"¤EÿeÈ©,¼C{Èä\.z·_Λƒªßv½QèØþƒùÒýªEûöî?ÝþY¬â ˜îcY¢bsÔúöéW_\‘æA•=ÕªR¾Ã4Eô9ÁÊŸö†?ž*Už'èàŠË훜:ÿ¼¹ GG˜ó4*ßí Ÿ©8±Ü×7Ý`~†‚ PXíåÁ‚rGm²o—4ãÊãÊŸ>̿ኛË´•Sͼ–E“ýÖÿ?!Ôv­‚T÷*Hý3L.[4•Y5W8óW>™ùÕAއ½QE%di¿ò6j_õïõ­Žõ‘§ÈÙ¨ÿ×¼_Ö€f¥×úµü•=NÛe>ˆ?•Guþ¨~?ú <ÿǹÿsúPœMÕߘåˆù°V@Ò>ÔBÒ7AABàÓÿÕZž‡Ì¿ó|±©lŸz²Im¼:ò×o去“ùÖˆz^#Š#摟—ïõíO–õœ°„ªF82¹à}+6g³,ZKÆfcü+»ùQ`óÝ_ƃøc8üÍ,vמ$gÕ‰©4Ûûd>K09èì1[ƈ  7¶»EpÌâ@p[žj{Ks€SÕqøšvª¾T{£ÿõ,'d¬H;òHôíý) 3õV·û£"°ƒjÝ?œ0ŒP3Xò¡…ÆþG¨«¾ƒ-XªyÀ0Ýx=)×E¬fŠæ/õg†ªÃ!Žd`zuúV”¡f·–> ËYMYÝ—7áIl/?ZE_õ)æ@EP…|ëS pÈJÿ‡éU‘ÞÚà263Öªú\EÛÛk¨—2Û:/PÜåY‡½v}ò^Á¹r1Ä‘ç>«QÞéö²>Ù#P_”•??Z†Û—ŽB£æU˜f]⥼Ѯmʘš!Ýz¨þµ›M ÞW&5WñÁªRnüÅ9#©<ÃZæVâe ¬Î;}ã[ÓÊ% RÍ´mÇ9æ¹îœç=)7p:¿ÈÒ=árI;9?o[·s{·þʵÎx+‰.Çû)ýk¦Oøû“ýïý”T QH¢qQO÷þu-Eq÷LD§û,àsäÿìµÄ²m ]¼®É¥¶:ˆò®9îÈ2©Ï­TI,ÛjÐÚiËl…•²K²ŒÒmÃm†Ûêç$Ÿ¥ièÇM¼³ -b2(ùà $ûóVfÑôéFÓj€ÿ³òÿ*`aC«í™dXãV“‚Zém§K¨dÉVõíXóøbÑóäË$Gßæ¦Ø[_hÒ“Z¿,c<§¾ë@õcä§š½»PeS¦)fí9÷ÿëÔÚ†Él €î\GZŰ—uͳžaÈôê?\О RÔ™ämÁr£¸ª!ˆS޵~áöGÏzÌ {V—ZE[«Br2§ÐЬ/¬ã.¼ Ãýh´¢ ŠËýÒí0ªÅy,`|’ Ê?Ï·ò¬££°!azvDñ‡#;\‘ü…RÔ-n açÅ´÷”ý*Ímuº& ¡Ê‘]=…ÔZ…©%Wžðþ$Ó“{É#”ÓÚ´íµ˜ˆò®eÓqÅZ¼Ñ’á˜Úâ9”üÈxéY) GzÜ++ Àõëü©&Q§tºlÓù›Š(#*ê´+bq*#}AO×$S,”Åayi+ ÛYF}@ÁþUÌ’?*ºßÇ<:ž’×"^ ÁÁÚAíÅiÀwB=³üÍ`øA¼Ý"H»‰üÀ5·iÿëôô,hšŠ( bµ“§ÈÙ¨ÿ×¼?Öµë#Mÿ‘³Rÿ¯x¿­j]ÿ«üþ‚jWBmûŸÒ£½ÿT~ü©òä7?À•$&q&ÙÀ`ñþ5–¥(‘-D?|³ S–F?;.®Ka1ûÏ}ä?ÌV‚4Ãú£d¸‡»Ò ojJr²Dßð#þ¿­o=°7²ôm£8ö¦vÇv ²‘Ç(i\vMVŒdC¿Ý!¿Nµ±¤ê’qm¨¡†@0¥¿úõ©Ì)›yDZçò§J‰$e]U”óó Ñp!Ôchç9À"°t™Äw“Ú±àüéýjÕ® ’ÇqkÈ *ƒÝsÆ? W9ö·ŠøJW% SÏQI=@Ó›äiesYS¾ã’sÏJI®g¼›d!Æã÷W“Zzf‘$2$×p™Héäóîj¹€eމuy“å‰;nŸÂ›*ɦ^ V‘f~QÐÖ•þ­r¨è B¨0ÅFOÓ5΋‡–ãq;™Žîh½÷FÚÆYu |¡ˆq–s÷G¥:;4¹Žubݘm˜ŒÖ¶ãƒ#çûÜdþ´ÉâÞ'£©»JÀs6ÒÍ¥j Ò+#!éèG¸þµÒêp;؇•zcõªš—ö†Ž·j3,K‚}EjèÒyú-¹nsßÖvWò¿v{5)†+9Åô§ÖŸ«EÙNBªN;ŒÁ×5e¼A)DÈ>§ÿ­NÓíc¸‰n§Üc€p3÷¿Îki|ÙšSüD‘ü…uaSÃð*u¨?žiå³’eˆGޝgùÖ}}+YX¥?»— HèÊzègˆI<`|ñej†¡h×zMŒMn7ížjop­E-ŒÑÜ;[åcüª9c]M m¹ŒnÏSìkWT u¢ÈÍÔÄ'×þ•Íé÷d%¾dé@§o23r«ç•?Àà|Êjæ’Ï»²ÐŽWºúÖݲÅuu¨Ûð™dì’µíg{-œùò¹èh<ùK´ÿiXø×Em÷Xž§ü+6ÆÍmµiÞ 'vÑÙçùÖ”CH=Éþ_ãC&¢Š(VF›ÿ#f¥ÿ^ñZ׬;þFÍKþ¸Cýhj^«?FþTùÔ·û¿Ò™yþ¨ÿºßÒ¤›ýCÿºhBg ~Ÿ.sÅdɵ¯xûºsYr 15b,i×òØ\oO™[ïÆz7ÿ^º;»X5 ¼³Áõιè|%tÂêKG9Yà=ûÔ³Igp“&@ =«K\¿.ßa·b—t¤ œTÚµ¼0YO1\(îMsš[3}²Gb[É8'¹Å$l®W ÊÑŒäwª2¡óÙAgÉük_Ãadk˜ÐËŠM.î;MY¡º‰LnÃæeCØÒ¾ jhq‚Ó(Ø/ý·ppÚ£·d{N28ã¿z‡Tº[K'”œ”î)â…iÄ1ààîvõ&³ì³öë~2|Î2Q!o2PAp•66)"²ýàAÀí‰wncl„?LÓ”íiá=<~F™•nPÄë½×Ðã5›au<óÁs(bžgǵ&3oN„ #)ÏŒzhŒ ™—õ«Ms•™yHEÉõ¬&ó6®[«å°}ɤ݄sº‹±ÔîŸ<™ó¤º@DEÉ £ Æ¥òMÖ¬BŒ®rßJšHþת[DyÜøÇ·Z¥ª±µ_.Òûªüª¥Õ¢yË4ŽŸíÕÃ(óü¾øÉöíY%ž}t…Îcp z2in3WM3qö«#þ>OÔ#Ul›n£uýݪÃñ«cþ>OÔè&€DÔRÑH¢aÖ«^©o¡ÿÐMYª÷c1°ö4ÄCªšeÁôLW s&MwómÑîOû8ýkƒ··šöáb…w;v½Í4I\àšFqÖ·[ÃRˆÁKˆËzm!GãY76²ZJc™6Ÿ®A¢àw6..ôø$aŸ”ü«²f:¸–^ sœv=+ÃjÖ" 4gi¬­fÑíueòNVv„{žjz4.óàøÁ©´{¶¶Ôd³˜å%áIþÇ_Ç¥>Så\³§&ùO§?,Ö]øÄé/BN3úÑk0;ÈÇÈ£ÓŒW;⻲ZÆIÈ$[wÞn•Ûsû½ÌÚ\×)o;ꬳ°'(Hút¦NqîEtºFe³¶d%£‰öºP8oÈŠçå@¯ÀÀ5±á›­—BÜ«üØÿ?…6¬÷ˆuxöœùL"o|ŽZЂöº6ïÈÖ\Z?—{pò·ÄùçžiºÆ£=¬_dÜ‚YFÐ}ÑïJÀL\Ëá⣓å•ý+“³ŒÍ#)$…¸õ­˜®|>Hˆòò§=Îj­«Cd÷2¦_•~ƒ¯ëü©F÷°|!¸ÏrÌI;T×·kêŽÇO» ãmexd¬VW— ÐÉþ]Ö%ße <aŸÊ«¨l%f¸ÄŠÆAøëWm¸#ÔåÿÖª“ ÖLã—òâ´ þdZCD´RÒP1ZÉÓ¿ämÔ¿ëÞ/ëZõ‘§ÈÛ©×­ÍKÏõMþëJ}ÑÅ´§þ™·ò¦]«?îéN¾âÆúæßÊ’<öy¿‡5Y›>µ-½¼—— (Yœð:­u6º”HUâY¤Qó»çöb8ò8«ºD¾F©ž8­Ë Öâ66±´R˜$‚~†¹–W†b¤mtoË wz¬lÓ%‰9f\rkޱl]prãf=8æ·´½m%U›kŽ{ÕX­Ò]rYÑ@K;ýt“ÖÃ+Û¢Y\‹ˆF6åHÅgêJ<ñ(ásëZL2ò)éš«} PÝÈÏâ)µ©'K ^5Ö—9̉ò?Ôõ±\ÿ‰ïÍÍÑ·NQ:нàùAŠå ã*À~ÕFÙbŽI› $²·'·4 ‡R‹†1ÅeúçœWGâPñ°êG?­`ìy§ÙÜY±Š¶´¨ðì†{Ž`Y[1áº0U«k[{LÙ¾2I)»¡©¬íR=:Ùa#÷Cƒê{þ}jެÂk¸‘0N@öµ kùÖûQ[[UŸsÈþOÕ‘¦˜u¢ƒE"‰êµ×@=¿¨«5Z稡Çþ„´ÄTñü.¾€ã²<;l±ifr’áöçýŸÿ^k¢¿·ŽêÕá—vÃŒ…êpsý+)^… B,$EÝõ ’i$-‘Žìœ};Õ/ië-‡œƒ û´šl¾n²Œü¦µ5%ÊpÝ6fœŒóApäõµ­ìz†¥j÷•‰ÁõÖu”y ßÞãõ§AÄšªU-&CŒqžôÚKQWK‹¹—ûÕBþ Ö‚EõçëÞ´õXnmXÏ$Jb'”çoµEg²úÎxz6ÝéMëªM£?Ÿá«ˆ•°ê\}3QX[¤ɶEDOéšÈÓ¯d°–@*êUÔ:»k3Ä·”¼4‹²5ïŒãúT­À¡z³ôàñùÖ¯…ì–Cq+.͉ùõ¬Ußs8UË4À­™¯›I¾Š+a¹`‹l‹êsTØ:›²XÆÙÙ"t>•ÍLÎ5)¯n>p¬žìFU þ•n}_íÍ‚Ÿ ùœ“ŽÕ“,’ÞN©,ÌJ¯¿JH zE°¾»y®Ô¦]ùà“ÐSµ}Kí ä@Æœ8©®Wû?K©$n>¦±Xàu4ögHœ*æÛ¡c•÷«—÷Ñ}šÔ9)V#5‰({Kp½&‘²@ê* ¤t—33`{T$ïp6¥ÖÅö±cåX£MÙ8®¾N%R=ÇäTך@Û.bî¸?­z\§*‡êCMIKÖŠ%dißò6ê_õÂëZõ‘§ÈÛ©ÿ×¼?Ö€f­×Ü?îéE÷üy\×&þT]ýÓþéþb¦•CÆèFCõ¤„ÎG‘ûUÉ\”P^kNâïȰ|Ì þ|Ó幎Ò`mñ壀=Eeêa+à¨Wø©‚:UÿGCаɮOÅ6ëð™WÇÌ=OjëàV[hÃu Ïjæ|VCÞÛÇê2i¡Ð[þà‘÷úƒéVt¿.ùÒVùdM¹>¢¤T!p3ž:VÆ¢Ãl¦æáJÇ 7EÐÓÙ•$± ¤Ì‹Ï¡©á‡íVs  ”ùÆ­\ñ ¼3Y!Œ,±Ÿ•€>Þõ‹¤ÝˆfÜÙ ®èhz[L½m7PÞÛÊºŽ¸íW'“ûVõ"Œ~æ6,íØsÈúÕAêW-EKa!‰.Ó¹P.)!!u{ÿ¶]¶Ó…ö©´˜– iµ — *™îÞÕgm%åÊÆ™,ç“éïZÚŽ ÒíÕÄ2äSzŒ‚ÓZºµ¶òIܧ‘Ÿzd×ò˜ÞG^A…QéýãõéPßK¬ ùU†Ð}Ò›ko-õ×S“Ë8ì=ªvl¬žòo›"1÷ßúUÍ^hâ… Œò: ê¬]L–P-½ªã€±ÿ¢Ö©h׬^fäF?ÇúU=§og,à· ÷ߊ˜• ÖöjÒ3}çš³mڥǔҬcƒƒŠÙµ°]:æ"ª,Î9%@ùyúö©5t Œq™Q&† rOJ£u¢_Ú!g‡r/ñ+nÐXÉ&§~÷K„…Ôã­jùn¼¬Ùöa‘@ç‚ø½¹Çîùüë¬ÿ—†ÿy“U =-õ)®#U@ñí*½ÏQWÿåàÿÀ“P4ME-%vªÓýôü?ô5«=¿ ­qÌ«ÿÿÐ…P‡Ü¶Ûi[ÐÆŠ×|Þc’¬£¢œu­›B~ÿAU$]®•†(ÒÊ+fy#õcQëryz\ì¸E\RzVn¶âHØrÒe@÷ÅG;¦Û<ÑGi¹È§ã]E”v–ûò7Þo_aY¾Qœ“°Â…íþEZžúr2±m\—8$Slõ)¼û ’`B·Ó=ÿJçlk[ß(+»pñþ=kZÎK›­APùmƒæcÙlÑ#ˆäaÔwö4Ë6v‘@ˉäuúЧ „G–Á™ÕzÆ~ðüë®üë+y9ù‚7=²?úõ fo¿~¤TøÙd01±Cš‰£9Eú q¦ ÂãБùO¤1+Nÿ‘·Sÿ®ÿZج};þFÝOþ¸Cýiƒ5o:÷Oó`ô?W»èÝ?ÌU‰XG³ 'Ò’1%•ÃËÈf5vc ¸"‚8R˜C@qÊÞ–"Ja†¦ý¸®?^>n´˜û `WW4¢8ËJå.팓£e„ä£tþTÐ*ÅæE íóz/ÿ^®]KŒ†p=³PݰŒI²(¾Rçžè+òê%š8™ls×ê3I±¤\iVñ^Þ ¿z§ÌNy4ëoÆ%ûM×R9‰xIáÛUtkán#G [R±³Ó 8MZ ²î\`œ€; ‘Q“åÝIþ£55ãùÞ`S‘Ú?<ÿZŽB™µ•†Pãpú."ýœk¤éu'úÙ¾èþêö§[ÂÖZ{\J3sqüß  ªë›xO#±ã¥Içý¿]PèmÁ`{Ž¿015"ñ¢•8Ïêjõ¥À‚ÀGó6Xuª²âQwsêáWóÿëVŽ,îlyp—?Ä{P»°XF&˜oºqò'÷}?£yÛ§9Ýs'<ôOþ½iY«\Ü5äÝÎ# ´Ý^8 hÓ6>lõèßP é’F¡0!@>X=Xž ®‚颲܅1 'þµbËâ8â"µBîX—÷×W¤$ŽY‰ÎÕéô¤Ymj¶v̶l69<§­N1æF'¸éŠâvÞi±¬©pÑ3±\#ñê*oøH/|½²yrz1^Jíí,´±ùGV©?åàÿÀ“W1á+¹îµ)üç$yY'‘]?ü¼ŸøòjLhžŠ(¤Q7oªËþ½>«üÍZíøUi9~«ÿ³U£âGx´°ñ³+‰V$^%¹UÛ4QËî~SùÖ׊?äÿmGõ®9‡µ%Ž¿ö¹Ä,‹7Ý$ç'Ò©jÏv—‰+²•Sò‘–‘@È'Ó­lÆ–ÔÃw“Œo^§ê(³è4hi²$¶§ÈP‘Š© O8ü¬ýFÚFI,†R~P ç>€UÏ äÃ6.@ùü+FKu†lSÛ&¦Vðý´¶g––^N{J½yÿ#n§ÿ^ðÿZš—}àû0¥Ôy°¹ïû¶þT—_û'þÌ´íGþA÷?õÍÿ•$K8k}JòÕBÅ;Ç ÷€©N¹~O3ï´…Taüê2>jb:D‘5{/¤ƒÏB3Áü(´ŠDX戔oïO¾ûDñåÊ’žƒšvc:áV·yAT;PNj„Ú`ãÜ»b8ê\ÿ…n[*Ékyà~•Ó*\@˜ûÙ?¨©°îY‰<¸Õà Ê×ožc¿Í#¯'û«ëøÕÛÛØ¬a/!­sV“½þ¡pïÖHñÏa‘MÌË3¸ºòK óÞ¬_ZkH#fä§™©¨­áa©G¬OКÐñçPØ?€?*L ÑÈ-´Ÿ5ï%8üjM2–·²ÿv0 šËw`‹9Db@­Í>3‡q¼ÅÈ?¡ìh‰¿²à >ig8÷ bµo“bZéQ|¸Ìþf—M·ßž\|±#JÇߌ:É»½“í²ÍŸ#=ÔQäµÍÔv‘ìieëÂÖT6—¬æRøŒøSììqç^dF9Øz·ÿZ®OzÈcUxUÅ\}3N·;HíÜnÀ¨Ù­¡âÚ5O~¤þuJY÷Y½ù¦ÆûŸŠ´ÇêÇ6p眷ô¬¾Æµu\ý’/w'ô¬¿J‡¸Ž‹Á‹ÿ Û·•ÿ³ êÿåãðOýš¹Ï&ɤÏxÿ¨®þ^OÑöj–¬4OER(—·áUÛ›¤ÿx&«=ªùzO÷¿öSLFwŠüK“þºý×"Ë]w‰Ø >?úê?ô\£²äPHý>=÷± u9ý+JoŸj©£ímRõ?øí]¾`sZÀ z,‹ò«|¥ÆI÷ŸQÔ­ ?h^H'Ò°R\8æ«Ý[dùàƒÔ{Ò”z ¹»s$ñm‰DÆ7‘XVLmµUrrU®jÆŸyæ“ Ç÷€qŸâ¨õX¾ìãŽpÆ  --JøŽ$þûÿJ­«¸“T”çøˆ­}Öîê Œ~ò4mß\b°¯r×.àdg­&V5Ì»Ÿé]ê´iÀð>QÿŽÖ&/•t¹èà¯çÓõ­ŸH t;J€AúŒQm‹Wa›c¬ÌÒ¶{äÿõë2ËO–ðù’;½OVöZÛq¨AjŒ Óe¿0X˜vÜ'îñŽõ¤€šVû4b8$c¦;ýk2kƒ’XÕÙØËf“Dw]ÛI¬GbʼnëŸÊ´æV –RmÏRê<ØÆ}$þ•FÛ(÷­ÔΘ$í¹Oô§{ ¹N+µð˜Ûi"´óþ•ÅŽÅv^|y©ê€þ\Ttr ~?úÿ–¢‰\´ßÉjjE!+Oÿ‘»Rÿ®ÿZÙ¬m?þFÝOþ¸Cýi!³Rë·û¿û2Óõþsÿ\ÛùS.zþû2Óõ?³îë›P‰gWùÔe:ÔÌë·­D]iˆÚµ‹þ%Ñ6:ƒüÍBßxŠ»ÙýÓÿ¡Í•Àcõ­–ÀlëÇm`7ÆÎÉü#ҳμÓܫՠf9Ƕ*¬SÆrj íäÆpO$TÊPn¾p>wïsƒYQ“c©‚~èl}A©¬¯ ³ÜžÌ‘§êV­.É`H#=jZ‚ÔA V;‰ü8¬ÝiËê.Ùã}jxzS$¾[ÿ¬…3ߚ˼‰¥7àlŸÄÒc)À¡®£÷K€:éæÒ§n>y ÿ åpz޽«¨ ¼>’uÝ’::¥À]Y@Ú¬ žø?Ö²ô˜¡–ðÆI£VèÞôƼ#M6xå$'ëB܉-a…vÇ$D”Ò@l<áîÞÝfUÉ÷9æ²/æ JãkúT–±=½ünÒÆÊá²èÙ;ÓuFIJ…ù›Ûši´ÅÔÎfbrMIhß9 Ð(¶“Û4ûl«sÔŠ¨·q—ut+9è\ÿ*ËêG¥t³ØhBQ[k¢ïR;ûW:ch¦Ù Ã)ÁÞàu~œãþyQ[ÿòñø'þÍX Ü6?ç—õ¿ÒäÿÀ›T±¢sEŠ‚‰ºÕlÿ¤¯ûßû)ÿ±UÇ7#Ø·þ‚´Ädx°‘cþZJãÙ›?zºÿœZ@2?ÖJä[šd—´&oíHrOý´uó’=qYšKlÔá>ä~•~ýƒoö­ [JÊjä2PzŸJÌÎ:³g'zSRÖÂ:¬—ü²¨Hþ.•rÊëíQ¼ Ì;âÇJÍÔ‰[°ÈpJƒ‘Û“SDVäyˆv\&3ŽãÔVrÑzÆa§_¬‡›yRº* ¥_²\t$Ê øÓ`gºÝf”>£Ò¢™Œvïnàî“ßWåwü\ŸÆ·usö*3÷âRÍ@£MSü^iòÿëV¢â] 5êPÇÐñúb“Î1w™C1 3ŸÊ¬ò0,¡º9$øÔ·ïTŽùÕé¤Ù2¤Î}ED·Ë ¨„&Ž 9ªkµÃrW<äŽ)÷6­ßè}=6-¬0~õ©lÊI9%•¿:è,$·ž8íç# ÷þ*çÒ&ŽG8ÍH !XФì·ªX› ’Íås‘é[¾“;}c#ò9¬Xî~Ù·˜ž¹´¼?ºÛR†'°8>£&3«Q¶á‡®ß䧨‰ÁõQú7ÿ^§¤RÕaÿ#n§ÿ^ðÿZÙ¬kùu?úáõ lÓºûÇè?ô%£SÏö}Ïýrj[Ÿ¿øý i5^4Û¾å“*Ï<}ßÞ=i˜>§ó©ç4Â2Z :kC{þæ±®˜)ëÞ´m¤Æ—ÏÝ'ùšË¿ ¶F3[íÇ)FÎkF#»Ö²3Z’nT'ŒÑ_@+!*йEû¬z·Ö®Ù]1ÖbU¿›×¶k.àmº“nrž>¦¯Dëw ´L^Íÿ׬¥£Á‘­îúߨûè?Ïzl’²º‘x:Ôše‘\yW°¸#yéžÙ¦]G-¯™ A#ßÔT0æÚIE ~y­­7-¢¼}ã‘ÔVd åé“{Êò­ÁµºAØ«~cÒ“ØfÒ%‡ÔöñE5šy„ ÐŽOéQßäHÉïšXYÓæ`1»¯Ö—@E{ˆÞÙ± '?tö5Üär@þíhÛÈŽVWRôöª—Q=£ ÄÕ[ûš`W¾ßöuÏ@ݾ”‘– »Onõ3Ÿ6ÛæÀÙ79\ŠÝð£fãO•ÓñÑËÁú/ójÄÑmL¡tÿVñ±#ÐäVßü¼ÿÀWùš¸âîX¢Š*K$ªéÿ_‹%©û~ÇÑú¿þËLF'ŒîmWý¶þB¹tF‘ É5ÓøÄü–£ý§?ʲ4;u¸¿+#mEFb*h’Xž+Ø™€?7PsÚ™y;4® ü¹®‚khãÕ5RΘVôlpÏ­swqI Ì‘L§ÌRx=Ö›-AëNŠO.\Ÿºk]|=3@®Ó*¹*W\ÉÔÔÛ»¤ºPî»d<>;ûŠž3ç$@– ýj-B×Ê!”e[‘ÇQRÕ€€È~Αcd.®EiiRy–3Dßy7æ1ý+Iaå?(ëVt‹´ŽMïÄS.¶y©zŒ­r…'pzƒR´w3*­…ù±ÇB*ME˸㓎õjÝógìmå¿áÀ¡ úßl1;E2»ï)^hŠJ³GóDÃå'·Ö­ë ›ËŸ@ô5ZÚäÆê²!(ü7ì+‰o ’yW¾ifƒ2;ŠŽâox&…·ÄÞ½ªÜn29= e•;—ƒ]6‰"]½¹?ë#a¦kâ/âQ{Sô«£m}ƒ…ÜüèÔô ~Yûüô©ê ÀùQœ~„ZŸ?ʃDaÿ#v§ÿ^ðÿZÙ¬kùu?úáõ ©s÷ÿÿ¡-7Vÿ]ßýroåN¹ûÿ€ÿЖ›«È.ïþ¹7ò¤„Ï=glr3Ú©öHä ’Þ]€£ôê+ro ¨$κY·:LÐH¨ÌŸøFwcéI&ž€P—™dî ±dÉU!X ©§›%w`¥•ÔáƒõLÐÉòòTàšVÖì Ò¯ž¬JâEê=}ên]£ ùg^ â¯F4k:«½ ã>¡ÔmBÉ–FäÐñ¤Õ€¨Î¡±`q¢>Û©¢ÎCÆ@üGéY(XJ( À’}§i÷OÇt $âËŠ´)õ›ml%·,ï„ÜSåê*Íû$è%Œå}==i4ŸÞ$öç«.åúŠHH«yfö¨¾Q%€ÈÈçëPA7ŸŽlm?øáö«÷·ˆ–P–æA… }+Á™J¯~8ª°®-ì2ZDІõ«p8’*r{Ñæ¤Ö" œ‡?ÃU­•ÂêðžÞ´†Oqñ Ç¨ª§*â´Ag±ª“ÄSèzS«ðÅÀ¸'æQŠÚÿ—Ÿø ÿ3\ŸƒÜJHÿ„ÆOò®´ÿÇÁÿu™©c‰9¢Š)IÛðªÑÿÇÑÿÿìµc·áUâÿƒÿþuB*ëwQZ$Rº+8$&FOAXVú”w7’°·HÝ¢+”AéÔVþ©h·Œ›0@X~+ ]5ËC´±û»*⮉4îcûF‹Ì‘ ©ÿhSÜE{,MµNðätî•R³óLpÜ´±ã-•ÊÄóU㺞Ù^1‹¹J,Œ1‘íTÐï5ÄYDƒ|„íÀ¨µ‡{»K>c¾m¢¦µ°ƒKÓÌì7Îèrí×µ6Á£{;†`cž,–<§Ö€)ß .õH–;v†(T€X`žj©ÓÅòÛS1@ìhéÚ„·WFmÁ".ßïdT>rÃ39ðNÑØú~”˜‹Ñ[¬â5TŒ~§×ëT‹¥–Ô‡jcÝI(y§bv|ª: šf.ûç¹.…¿,C6æÌ¨(ÚH9Ïz¯lÑcÈ톫®ƒ¡Øý܃ YȘ·ÊôÜjP`‰A=ª{fI`aÀ$N‰ôä”rÉ”?ÏúŠÎ2½¼¥9ñM—_5Û³'· ÚœÁUW…Î{n©.•2$‹h$`¶qøR[í‚‘¹ª–¤²Àcp»Y•HÎ3V­ƒº° #õèEZÔ>ÉnPJß>>ꌚ¨’ªÊ„cŠm ;“«bŽ¥XŽTÿJ¦ë²B;ç"¯$‰1 ¹OÕ Í»´”ƒõ© ømöÐÉÜìoÔN‡÷j}…R· šƒÿBZ–è¢ÛJ\däüTw_ëGÐèKO»]öÒ¯b1B9;ílL†³Å$}0À }+[Le¼ Õ^ÎG@j­Ö“dЧª†j²Z‹ik&EÁ ¹,xô²B4ã k}u 8ISxönô¦æ êPÌ<`rjçÚJE!If”ãæ#ÜŽ)‰kW0G:4QÆ9NôX ¬u¯îwï1ÛEË3ðµC§ÜI=ÕÕé¶y”œÆIÆ}:öÆ:TÚ¬±ÛÇ0Ä¡"öœù§jÁoo-³y~cp{cÒ@Î†ÖæInnnÔÆò?M¸Áþ´Û6).W;•ñSW­nZïLšg=d { UarmÐù\È~éþí.‚4œyHYʃŽ¥g(7°J«À Û¹ªï)òG%ž^»ShR’á:¡ð~¦³`eÜZ….¿u½*¦å²±RFO¦kWZ̬R¹*ÕBm‰\cvi †Crõ©lÜ­Úír¹dU›té„ÿnTý:×5'É Îî½»S.¢Nˆ ’¸çpëŽzÒDaá÷}§¹YíRM‹¸¸ìÉè*¼L…ü²7ûA…4C:³Z”ŸlS S–ëØò+^O³ÚX–™† Y¯<2®è‘”z‘ŒÕ4 êZxÚ2Z1¹%GZlÄI#±üE6;‚0zFjÄ‘,Š{g½NÃ-xGþB§þ¹é]qÿƒþêÿ3\·…-]u—*U#*G~qþÔŸøø?î¯ó4™Q'¢Š*K$5ZõíôoýÕš­oÌ­ô?úªë–#9þ5ÊÀþe¤åÜ º˜)$ÿ?¥nk³ºÃåF…™ÐóžœÖ~™dŸeŠâìm†1•WîO;i‰á¾”2¬©ohçj‚€Ÿ ®j+»Ë†œÛÜH®ˆx`1ÏZ°nžàËr£©ò ÆXñ‘Yl¢Itž·oÒ˜šÀ?g†4çq Çz§¬Nm­§†8Û÷ÄŠ2¾üþNX/dU tøNTÈúVUØxÔ#0bI»ƒF M¥Kö{ù8ÜŒ€ûÿ‘R+¬ï+Œz­S@EþãÀÝŸçS òã^ÜŸÖ¤F¶‘ÞNC¯îáù˜ŒÇüþ•$ºaµÔ¢¾¶RbËf1×c"¤Ð÷GbÎ@>cÇéÅkL–+æ¤{SžÖîÝH8xؤ`àõ¬›iUwÁ]Ç8í]ý¤Oa½Ð F0ë×9®^$r\G&ì‡ãéE´©bbŠ+ˆ*à2àw£uEÁe!\O±}²ÄéŽõ-ôJ#,¥‰^qJÀR¸2[*4s6ÓÆ7ãúU'•„ŒáÈcÜKÿÖ­].H/¬>Ë0Û!PQ÷ýUŸ2Éxf, Ÿâ‘FOåL–W¸ŒÉ$^­Éç9Ï5» ŒGSqI¬Â›­`¸&71¿9ú~•ÐYÙn¹ªÜ–ÌÝJËìEØ©àmÑîõÁüÀ?Ö±¼$û´p¤çË•”×úÖ½¯(ôQúqý*Yhš±¬änÔÿëÞë[5aÿ#v¥ÿ^ðÿZcf×úÑôúÕ‡FÕ^çýpúìËS\IåA#…ÉQž)!3žÖÏ«Z@½²j f’i&µ`×É•ÀÜV1ÓóëQ„žïUb‘•fL Ýw&¯ÌÑivëkh \Êväýâ}OÒ¶Ùc¶¡g Ü}ª&”¬»ÑOΡÉçÝI#ãÌÛÈ÷Ïj«~ÛWìᲑáÿy¾ñý1ùÕh`DÈѾ1»¶(KËó¯.· …‹h¤ÖF»t×3achÄiÈuÚsœR\Åyó4ó¹Id©Ç5žÒHg‘ebìªW,sÒ†À»at"Ò¤Lò²ÇÔ ~´!rÿ6~oj£l…Çû@~™« Æ<…ãªDni6Ñ\E-ÌÈ C÷q¡ìA‹éZƒ\ašÝ¢ ÕyÏåZzrù6VÖì¡p ’?3úÕ©X•Áã•\ÔÏjÒ[ݤ2£)d|`ŒÅeZH¡J0I95½«XÂ-ÖHÔ¤¹ïÇZæí$>C†êŽh¶ƒ5´öŽrŽÃlеFáQ¦Fe%¤Ó܉@~Tñš}ì@FX6vœŽ)X OÛ@¬vmª“;¼˜±÷ó…jiÛ‚PÂB¿#lÎ9¬÷ŽHä’·Ž?ÔŽ)’ÊÓ35®æ$“Ó'?­iØY ¶O3æ,3Ц"ß§ÊFs™Áp}«kOPñÆ}P›°Ë½)^ÎIvºŒàzU[I@»Ï9ÆMoÞÌ-´éŸý‚÷Írvû¶¸æ0¦:LkU©Öxa”É8Ü Œgò­Ãÿ'ýÕþf¸ß; ]†qº&Ý»#ÿðþf¥•bsET–?<Нk÷Ûèô&««YòÍôÿÙš¨’èÃÝÞ¥PÕ!’öî+8˜¤(7Ìðì+Jî`—Œ¡”®~•‘îŽclq$œ°oéW„eß\!—Éq¿ÈŠ:#ŸÄçIelI\òO'5ZÉTel“óqúÖ¬%-ãi$lÍhô@TÖfK+AxÉÂ@;×?rû&2JÈTnõ§_]½åÜ—€xEô^Ô2¨ÓIäH‡ÿZ¡#¤ºQK*îGlŠšxö*¨\àf¬éQm•A±Ë})gŒ€Ê~ômƒôëCŽƒE{;©`—÷oò±S÷Ny«çW‡& ÈÄ`v5› ì•~‡úSaŒK|[ª§?Ò¥¹u4wQ„|©*¶k—™š-Jx˜œqßµkØ£É<Ñ äßRÖ­š+ï4®®3NÖœ™k€ÃæP&¶o`S‘Të¸~5e&Ù «z,,v§úéØ÷4Þˆ ZèIx°¡ýÜG’?‰ª•Üa5yT}ÒŸÊ ’NAjÅê¿ÊuxÔ~c&¥j ´Ì2¤.=8§L¸•¸àšÑ†=¶-³þYúpj¥ÜxbGC‚)IXhµa©ÈcŸ.˜ã=@«Ë¨C$Q"ʧ$–¬H—jK‘Óåþ¿Ö¢´ˆHÒIŒŽ‹øóIÐj™s+`dG°ÿë×)Œò΄äï dVí”<*X—ØHÏ¥a\ÆaÔ'>|Šv>˜Ã+–VüëVþØ/˜•5ŸbWdê1‡WG4kqh˜¨lýE&œ=´­lQÔ t~¹`zœŽ=«WU†;¸ö¤rpEC-«¤ŒÉc´db*I-ækyˆ¤$HãÞ„"-,‰$–ŒNŒ½Iê:Ö–ŽvªzŽ?#Y)&ŸvÌwŽ$çŠÙ‡Þ1N¶ñô<ÿZv%—µuS£Ì.G×5ËY!23tc¿â9Œvq@>ì‡æ>Ã¥söAžî5LüÍÏÒ†RØÚðºlÖ›¶coé]y?é'ýÑÿ¡æ´h<­iNr mý+¤ÿ—“þèÿЪQ,QHh¤Xñ÷…V²ïþèþf¬ô5ZËîgý„¦IáÿMEÿgúš‘UUK`ð3ÅSÔ.-Y¬V3ÞÇÉ«Ñ:IèÜ2ウ´[žož˜û;í?ßÖ°üJ¯¬j®Dr6Ö\äq] œô¬)“OVÆq þ´“ÔG7 %ØñÅ+6`£•^ Tÿêm²¼3p£ÓÞ ·r}ø5ij#_Où¶9Æ?SŒ‚%AÁ[ê?ÏéQÙŒ«Õ«XF³FÑ·ÝqÁ=T–€s)Ì‘ÕjÕ¼‘£³¯Îç?•2âÝíîU;Ó$ï ž)ƒÇ”fšò½ N†¥î=lä0¸ÅuÓ/öTLOÅr–Ùf*£©µæ“*›ˆ+!'Oþ½Ð Ún†\üÇ•ÏzŽx—‚¦Ý5LÿiCc““W¤IZ K°ÝÎA4$+XÌÔ1sb_#|Ciã^ÕfÍÌ–Ö“»v?Õj³Fa›Í Bàîç­K¥6ë9Pà”“~1ë×õ§a5¡oÄØû-¿bÿ*¯¡@Œ’ÌypqîŠwˆäóÞ!è[óâ§´³ŸJLàm|—ÁÎ=(µØ}“ZÂ5ûr8„0­_ùy?îý ³4Öé ¶r§¥iÿËÉÿtèU*;(¢Š’ÅcÁúT6C÷Dÿ²ŸÊ¤còŸ¥6Óˆö_ýS“­!:‚×?ñª{£}Ñ;FXà•<ÐÕ™MðRÀ0Œuük.¨½ oPv¿š0<ØÃ¯÷“ƒùTZ•ÄaÙ*A+ŽzÓd? &šK î(QBflsN¦IQÐd`â­Çgk¹n䊷¼yXÇzŒR@E³µXŠí£ ;j94ÜŒâ›Ô ³,Wè 6É“î“ü«&x)Η'pz5ZÏNô²9‘6Kó¯mܰüjl)en‘¾V<`õÿõU¨/|ˆ#ŠGáWŠ¡ þØìO ?|PDÿ,Ë‘êx?74Gqtw¨žÕWRµyF¬ºäýk ´·±´.ñº~¤·5Rö5–cåÃ$ñI.€eÚZ¼óbx­‹/.Ê .n\"·LœP}žlŠ™õsÅW›KšñÃ\]î#€ð>”Üt²Ì}BånîÞEEE'…ZŠ0ɶU8Á[‰¡Â§,ìߥcßÇä‘¢±œ(ëSf†Cw1žéän8Ç «?l¸–ÛÊ‘ñi´*ð*¶Ä¹=¸â¯ZXIpI”‹éÉ¡n‡Ñ—V·!I!ˆcé‘]³©¡ö#ùéXvQ¤2F"L(aÐ{Öì½SÜ‘ùƒQ5a¦OÖ±,¸ñn¥ÿ^ñZÜ^qô¬+N<]¨ÿ×¼_Ö ¦iÜs8ÿwÿfZ–øfÒqþÁ¨œæä»ÿ³-KzØ´Ÿ=659b>XÛ%\ õ­kKë…_Þm˜ø ~u—2à!R9éõ«lNA®†“B5-ï!žeЏÎQ†Óÿ׬-`ùZ”Œ>ùðjUWf 3ZrB‚A#‚íÐ3œ=©(ØW2ÖÆI6î\¹5hYª`ä’*ô¼7ËQ¹õªJÀ6ØêHùEhDñL…7)¨5›žx sëŸj¸ÞYyb#h'1¸þU HI1Ì0ëÓÜV˜¸Ý•p‚D=ÇÞJæÝvðKÇÔ0ûËøZV •˜y¶ó`ü¯‚}l_H“ZËž ÿJÊRào˜veéøÒÌ·b6T]ÊTà­'£*éÚq†ÔÍ#'J‚þs¢/ïÖþŸg$zFÙЇŽ¦k:[x¤¸ýê#Ö„®´š 3ö< Ú†¼Ó<|ë÷N*¤0(S «êp%ö·µ·Ù´ó“ÐËØzãühjÈ71/–C  üãÞŸ¤œ\•< #*>½j°Ë±;Iç9'­??gt`s äcµJó´°ýV_6øíäF zòk§¾¹·‹OÅÄ€,`wé\vIb{““Š™É0¹v,_žÔÖâKK¸WÕ¶G¼&Æ8'#ò®§þ^Oû£ÿB®WÂð?öŽý¤ F= ueÒ öú¬§{ê\Iè£T”G'Üo¡¢Óþ=ÇüÿA³«o÷M%«›N06ÿ蘌Z _RÜ‘;)‹U'±¬5Òï™ú4¸”×t>ðú0j£+c––ÃP6àG¡†7b˜–Ê‘µ[þÊk­*p(ÛMTh¹Í-ž¯³iŠ빇ô5*XêðÅøIèk|•YGãM2D2 ÿ =£ ÃL¹cóˆ×èsý)ÇI”õ’1ùÖ±šùêŸ÷Õ'fÏÐG´ac1t‡Ç3/äiãIÈÁ›ò_þ½hy©þÑú#…!¸EêòÅ.v* )Ts)?ðpÒâï#ŸÊ§ûlK×?‹(þ´†þQÿ}/øÑÎû…ˆ×K€rYÏâ?žºm¸Ï àThF:.3ü…Ú݉ü¿øš9Ÿp°å°· ‡þú4 HñüÍ0ßH~í»ø þ¸¦›Ë£÷m›þùüU.gÜ9I¾Ïÿ–KùS ­¶æo³Å“ÔíÔFkÆé>¥GøÓK߈£þ?øš\Ìv&ð» c袟€ôP›ãüJ?šc¼n²¨üÿŠ¥v;°qÒ™0 £tÄŠ3Š©ö{“Öl}üM däå¦sôUÏò¦4c91è+ÛþFíKþ½áþµµíP¹'Î3X–¿ò7j?õïõ ¨ÿñð?ÝÿÙ–¨ Ù]ö£˜í›wû?û2Õ³Îr1“@™ÃÞnDɸc#­-Œ“#Ÿ™±Ž†»m«±xûRª®ïº?*¾qXã$¾ž;†]ªÀëORÉáaŽêk¯(¤ò£ò "ÿu*~ÓM„ÑËBs–eú¯øSÄñ8È•Oã])E?¿•'–ŸÝ_Êkä9±Ê“œjh8ÓEà"‹ýÑùSö¾Ac›šù¸®“bÿt~T»û«ùQíÇ6bîû§Ú§‚V·uX{ñ[Áû£ò "çîÊj»Œƒ¨3.Ñ ÿß_ýj¥åù›Ž 鶯÷GåFÕþèü©*‰t ¼¶0¸C#¯ lÒi–xâ/Íu,£t~T£û£ò§íW`åg3-¤0Á#Åï qßÌùr2‡`Ø?ÅŽ¼×¥?º?*aUî£J—;#Ε `±£õÇ5§k§p$¹9'¢Ÿv!<*þTì(SH,déd}¬N¨g#ý•þfœôÁŸµôÚ¿ÌÔÊ\ÃJÅŒQJ:ÑR2”´.£©R*°irO’Ac–ĤvÓÚ¼â]WQuŒŽ<æôúÓN­¨ãþB_÷ù¿Æ„z`ól}ecKåNÝvþ%þÍ^_ý¯©ÿÐFïþÿ·øÒÿkêô»ÿ¿íþ4XOó¦?ûàŸæi~Æç«/áÿQ^_ý±ªÐJóþÿ·øÑý±ªÐJóþÿ·øÑ`=HY7üô?€Qý)~ÈGüµ“ð|*òÏíSþ‚WŸ÷ý¿ÆíOþ‚WŸ÷ý¿Æ‹ê_eõ’_ûøßãIö4?x“õ$×—ÿkêô»ÿ¿íþ4kêô»ÿ¿íþ4XOûGªƒJ,ã*òÿí}Oþ‚7÷ý¿Æí}Oþ‚7÷ý¿Æ‹ê‹lƒøGåR¬*; òoí}Oþ‚7÷ý¿Æ“ûcTÿ •çýÿoñ¢Àzà‰})|±é^Cý³ªÐJóþÿ·øÑý³ªÐJóþÿ·øÑ`={`ô¥Ú=+È?¶uOú ^ßöÿOíSþ‚WŸ÷ý¿Æ‹ëû}¨+^Cý³ªÐJóþÿ·øÒÿljŸô¼ÿ¿íþ4Xw=p¨¦äßÛŸýo?ïûÚúŸýnÿïû ž°VµäÿÚúŸýnÿïû'ö¾§ÿA¿ûþßãE€õ¥¬K1ÿv ?éÞë\Õõ<ÿÈFïþÿ·øÔ+¨Þ‰üÑyp$x—s‰[-Ïsš,#ÔnCoSµ˜2m;HƒKçÉÓlØú¯øW™ÿjê?ôºÿ¿Íþ4jê?óÿuÿ›üh°ÏNÌFËÿŽÒùÓÿv_üv¼Ãû[Qÿ …×ýþoñ¦ÿkêô»ÿ¿íþ4XG¨ù÷Ý“òZ<ëî¿äµåÿÚúŸýnÿïûÚúŸýnÿïûz‡sýÇü–>à þK^_ý¯©ÿÐFïþÿ·øÒ _Rÿ ßýþoñ¢Àz¸Ÿû¯ÿ|­'Ú&þëÿß+þ5æÚºý.¿ïó'ö®£ÿA ¯ûüßãE€ôß´Íý×ÿ¾WühûLßÝûåƼËûWQÿŸû¯ûüßãIý«¨ÿÏý×ýþoñ¢Àzx¹¸ìŒà+þ4¿h¹ÿžmÿ|¯ø×˜jê?ôºÿ¿Íþ4§VÔqÿ! ¯ûüßãE†zoÚn»DÇþ¿ãGÚ®ÿç“~Kþ5åÿÚúŸýnÿïû/ö¾§ÿA¿ûþßãE€ôósyÿ<[ÿÿoÚ/çƒã¿ã^eý¯©ÿÐFïþÿ·øÒ _Rÿ ßýþoñ¢ÁsÓ ÅïüðoÍÆšn/?ç‰üÖ¼çûWQÿ …×ýþoñ¤:®£ÿA ¯ûüßãE‚碛›ßùäï¥ÿ Cqzå‘ÿ¾—ü+ÎN«¨ÿÏý×ýþoñ¤þÕÔè!uÿ›üh°Žn/qþ¬ÿßKÿÄÔ–ÍrÓ†‘Óò’\pOá¯3:®£øÿºÿ¿Íþ4åÕu?ãþëþÿ7øÑ`¹ë@Ñ^Iý¯©ÿÐFïþÿ·øÑE‚çÿÙfotoxx-12.01.2/doc/images/tone-mapping.png0000644000175000017500000004303311701011016016751 0ustar micomico‰PNG  IHDRú b2<ÚsBITÛáOà IDATxœíÝu˜TUðskîôv'ÛE.½¤tФH‡HHHH *ŠÒ!Š/H+­”„„ô Û3ÓsçÖyÿD„aYØ9ŸÇçñrvâ7w¿s÷ÌsÏ!ú÷ëÃñ|ii@­KçNÇóP„ee(îH g±X0ûVBBBtttõVƒ UA«ÕîÝ»×¾MÚÿ=tèP𦫝*©·oß~81 ËÊʪž¢¤ ?x'üYfffÿþý_xIRUvìØñà?ÉGoáãèâêñ¢êA*Q^¦-,Èy¨±‚¸{xûÖ ‹¼ÿϲRmNFªÉh„ÊŠ€ O¿ª­´: ÿ‡'î:p4YËVw9ȳÊL»[©¸ ¼ÀÙ8¡Ù¨Ók3üU¥c[Û|œN€Yã…´²»‰®^¡NÎîŽå=ðƒ‰ýâüñ<ŒáÄöÍ?ürA/PN$I’„ÄÍ¿Nݺg’4:瘖Íý(@)wñ¬꣖8dMåÙYù¥f qŠkRÇÉR^bnîNÀRš–’Q¤g1‰S\“:.L¹Ö]Ý1kYZJz‘ŽÅ áòñ#éÆB-(¹K\Óz.L¹Æ$¸xº’6]úÝ´‚rF;GÕ‰ô–ƒ²Â"ÁÕÛ c3““²u|UýÆg@ø£Ä!,-ÊlX<°µ´–‚"‰ÙH’áx¶N0”JDó¹â[9el€ÀëÿÜÿóE ÷¬×vl@ˆ«pwËÆÍ:ç°.½^Þ –!@Ñš}ýÌ–íG²ñ ^#FÆ0Åyeµo ’+8ºcÛΓi¯õÒ¹ž§Ç ÒœçÐXø@A@Q°™Œ¾Qá!>W´± !8kÑA¹3SûFtÐ/RÆ ¤Ü‰¶¥œ9¼iÏ©B̧Çð‘u¹ÒÜâ2ÒÍÏK¢?pÏÖß.•Ó^=†¬'”æ•‘n¾ÞãùC{~úíbéÙuȰ˜ÜÓ« ³tÏnÃG6J ´zÚ+À+=½wçÖßn{¶y}|ßo)_’›/úº™ w|•’]Žþ¼Œ*ü¥TwQdm¬T(è—€ùz8§–{c„´–S.ËL‚ÂÙc›8öÎáB–aHJ@€à8^„@Q©¸›‡[Ïî^t43ºmï~mÚ÷J½óå5!HLWŽür“‹?©KèÐS©Šþ¯7uÕÝÞ²no:YgêÔîíÚ&ßÙy×ø×EÞ–—vÝìߨY¦B+ÿÒü»Z£oÃò¼>÷öÎo¿”à„ÂÉ£y¯!š7Œ¼t£(W„Pxù•ß÷œÏ“õ2¡y›FW“’ÿ,!¦»vbïÙºÏÔ‰ÍÚ4º–”|6_´¿ÏEAx@Q–[gžÎ÷šôA¿ºÑQgnNãÝyÍ ?]ky;@( ‚À (î/!(Š6Vwœ$ ó³Ú‡YÃ}i+ ÃzÕí…e~-r†„Ž“LšÙg?òsKò³%eÞ®ÝàïûQ†€á”BåêJê~¾zûnFçu«e˰ðņSVú”ô\B¦µa*…[X\¨’–ªk™Êœ³ÜÃ×]–Á²D`ˆ%9iiºàÞ}Þ 9ÝñßÎÚ"û6NK\ü#{½ýF¼ÔÆp´JŠKœÕ*‰„Ä0`.*HIÏÌÑJn¦›7ðööt£ËI æâ‚”ôÌœb")Õïííé.-!00 '(’¢IKaîÍä;™eÆ" —Ë\‚ÕtyYÆŸWïÜåÍ·_oÒZŠIÑŠûK'‰G+ˆ»È‹FCy”¤Œ(¢h3@Q˜˜}VŠ„âÙôRž»ßs%^ ,ÇZÈÔR ¢d4lfÇ ÁÆs ÇKxEÎja¡h+J?vø\¾UÄ ŠM¥6û먉ñ¢„¼±ðZÎíæñÁnú'®i…ÛÇThý­#T7Øw¥°NÏQ¯ÇB(ö»“R©”$¤T* ,kcyŽ„PR©”" ¤Ôj ,ËÚ8ކ@(мÀ³@dyŽáxND€A(0 +B9NË€¹œ "/ðâþùÊÝ1 °,«–‰¼ Ò”•(?(–¿Føt°EgõÉ8K €R žÃ0ìÁ;Úÿ9KnÆ­‚<‡F?UЙ±óòò>bÔ‘#ÁׯžIIJƃ((h—ðºÍ›uíÒ)  ê«Eçé_ãðññéׯoÆñÉÉwtz=„@©TDD„G„‡©TªV"‚o¼Ö¶ @&—¹8;WO‰¯‚W2î6{úôöíß±2 `ÜØÑ‹>œ_­u½ ÎzégŸØ7vïþå£O>øû7ŒoËå÷? ÷½2q7™Ìë7l´ocH$öíÅ‹Èåòê«ë¥Ð§Ï}ú¼HMM;zì8BxñÒe@ß¾o 3<÷½qß³wÿ‡äryŸ>½ì-´„nÚ´qõVõr ³÷æ­V«=îk×n(**nÔ(~ì˜QÕ]]õ{éâ®ÕjEV¯ùêÖíd@¯×{|öéG8Ž»¸¸Twu¯ ™LÖºUK@ýzu9Ž»xéJ¯Þý+–-•ËåJ¥R¡pÄ?‰/KÜ5ZmRÒMÀÞ}X ˜8q|lLtu×õÊS«Õ€.;véÜ0eÚ «ÅZ»v\TT„L*kÞ¼iuøBUsÜÏ;ùÊU˜ýk”¥Ÿ~,•J«·ªlŲ¥€sçÿ¼råðò•+€^¯÷t¡;Õ÷÷¦¾o±XêÖ©S;.àáéS]Å8šæÍš6oÖ”a˜óç/¾ÛøCaQQƒúõÆ]Ý¥U­w³Ùl±Z5휹 ì-+—.—Ë•J:¯R]¤RiÛ¶­õë×cYöÚµD{ÿ~ù²¥în®ö^P SåqÿãÌYA®^MLN¾ãééQÕ#RÿÀÙ٠ЩS‡N:¦N›éììÔªU @Bóf5àKºûª$î:nó–mömAà!mZ·œ:eRU<òÜ-_öYzFÆþ‡7oÞ©ܵkçê.êùxÎqßµû—ãÇO¨TÊŽÛÛ[Ú¶iÆ3½rBCBÞ›4pú3YYÙøìÓ^õγÆeY“É 7~Ër}û¼1þ$Azx¸?òjÖªe‹&uèÐ0qÒÔZµ‚'M|àââü*Hþïq¿~ý†Á`LKÏøãÌÀæHjN'¹¦iooÀ¦6\¿~cúŒY€ýúúûûžj'Óþ5îß®]ÿí;vÌ(¿7gAYYùö;6+ŠbLtÔÆ k_@¡ÈË nÝ:ö_÷ºõßݹ{÷ôgºtîTÝuUÖ¿Æ}ÅÊ5÷·GqñÒåÍ›¨Tª6mZš4ndÿD8 1£GjKJ®^MܼekQQQllÌ;ãÆTwQOV©ÎLŸ~›5m2{Ö E‘žžžU\ò ðpwïÔ±}Ãø Ãܺ}»Wïþ“&Žoßàeþ8[©¸ïÞ¹•$_–Ñ5ÈKÅÍÍàççÛ±CûÕk¾Þ±s÷Áoøû¿œ£þ5Ä£G¸ßw¿ßqGǘ4q¼Õjýò«oiš–Jé·P*•Õ]Ô?ükܧO{¥yZ2™ìýéSÒÓ3RRR´ÄÊ0Û·ëÞ½ku×uê¢ Ï_hhHhhHݺuxž?zìx¯Þý—/ûÌÇÛ[&“Uoa(îHUñõõŒ1läˆaS§Í”Jéž=ºGD„¹ººVWI(îÈ‹°|ÙgYYÙÛwì¼zíšJ¥2ø­j)õΑ$88hæŒéM›4V)•S¦¾o‚ö‚¡¸#/Tƒõ{öì>yÒFÓ«wÿÌÌ,›Íöžuf Çñàà ¿úô3(JÒ§O¯°ÐЧGqGªÓòeK³³s¶ü´íòå«2™ÔÛÛÛ~ yA¤š~0{F“Æ ]]]µZíô÷g]»–XEÏ…ŽîÈK!>¾A||†aš7ÛòÓ¶Ï–.Ûô žïèwä%"•JCCCæÏûÀf³ 6ªaÃmÛ¶‰‰~^s± ¸#/#š¦·mýß…‹—ú-1ñºŸŸoçNÏ¡OúîÈË«IãFóæÎ ,.Ö̘9çêÕgíÓ££;ò²kßî5«•Ém–»mû®%Ÿ}þÓæpœ ˆÿr¤FqG^2™4"<|þÜÙǽ5xX£†ñ;´‹ŠŠ|Ú>=Š;ò*¡(jçö-/^Ú»ïÀÕk‰~~¾:v¨üÝQßyõ4nÜhÁü9þþEEų?˜wåêµJÞÝ‘WU‡í¬V&;;{箟´Ä¾D€Àñß~=Pá]PÜ‘W˜L&ŠŠœ7w¶ ý ²7>æ*¼ŠãÞ»wo'gWtñò 9vìÈým’¬x†¯ âîíã7iÒ à „UU‚T%Žc9¶‚qÅÄÝÅÅÕÆX-fSÕWå¸ÐD&Õ¢‚Îq†aè÷Ô<¨wŽ8wÄ ¸#Åq ;ó£{OÝPªÔ¯âR È«…cÊwÿøc†Ò4}¯ ò‰¿5õ8d3—nZ±À¾Zw}ë¢Vb)ºÑ¹mk{Ë‚ïC…KÒ©á‘q}ßW¯Éωړ?|u¥@pjgïÍÇÎuMhÚ´Kߦ›¾>fÞ¾õŸ‡EĆGÆ5hòÚ¾Û:'gåÕãÛcãêÚpùösgw|&«ôèœnNNžß¹­p÷Äñš¹o‹y÷§cÝ=|Ã"b×ËQ¸È§ÐcÜG~þey7†öí׸e‡Nºšµ’póbXÛ¾/Æ{xø†EÄ®ø-Kåáõø‘/•Š;,¿nûáTbþáL³.ówË­£Ë¿ÚV»KµTñg†63¹0À[qëx"c*¦¥ªž={òûœ^þËÞ8³ï³ {?ß—!ü}÷·þXþÂY Ÿ&f¯ìýl׊ٻ®åø¸:OY!ü~v·ï>š×ùÓõÓj<&rœmJÿfÁNJ›¦3Þùcgófíodæqæ‚Uã[,3 (Ƀµî3‘P_”úv‡úoL™;­eØýF޳ÍÒÆZ¦Å;¸£Äb“ú%X™?~˜ðåÄž)¢*Æ×EyÓ®¾/°ª’ŒðÚ圡„Œ•H$ÅfåŸc¶^Þ>õëÉÝ“MKóø•Š»ÀèS3²Ú ›Õ$Xn£¼Ç h‘qóR)Ý&ÔåÔ¡Ye`ôÌÁ†sÛ’RsI¥W˜¯G…Ãj(ò©·®ÔoÕpºÅ…9N>žXîµôÒQ«×Ky‹„¾MÂ;}M¥R4ˆª×ªYÝRmGH´ã’³´[–qÃl./..ÁÖdüçjÀg¤¥Ê]ñùcßjÓ¾÷ÖSÉ–²‚RÚ¥a\HÆ…CSf-ú=IPZX”£·–gÞ´XôÅÅšœu@°‹SaÝ!0¾¥»J•^ÂJ)ÃpÞ¢MÏ.ê4vN°B”z†|#AbÖ‰" uQw1Å“ýê·r‘+Rµ6Šzæ¸Èc@”JH«Åd¶0¬€ãòÀ¥C ß [7n šöñä3:vÝ%¬®—›‚c¹š:¼ -Ws,oµZM&3c1R”D ,z½Á`á%fc!A‰s¬™ç9‹•Ãq1üŸ;Œ–óV³‘ѧv~cŒ) ÅÂ¥_LÑINË8BÞìŒÏf-¹y¢_—ÖSo"Ü<ÈšÛ{yI’XL½ÎÀR8ïï7‘Ç0 ÁE«É`¶r6$EH$,F½¾Ü`£\ÀˆÇ÷¢+wRªŽ¨póüïY…‹^{îêm¯ˆz. iD£ø¤K'Š”ÁÁaMZ†‹?®^Ù´ƒ›Läyþy¼ö—†‘1µó’Ïüy#bÀd4à*¿h_õþ]‡x +ʼ}.UÓ°eSÆjEQ|à8Œa„œ&¬º2N€@€‘çVmJ¡Î¼hÃÇÍë†ÙJ´FK)@oñü¸}÷‘“þؽ.Õ,qWJ])'Ššú¡ÈN„PxP„üõb% —°@Ï«çNë½6÷BâM )Å0\„Px„@¬ÄΩÔ80ŒRwêÖcÿ©åSÇŒöWX“ó°KÆÊ9£Ú; ô qQÊê4 ¿e…Ä4¤8«(ŠÏöª_R†×OèÑê·kó†÷OhVŸ±r=†OZ0õÍŽï,§¹\r÷ªGínã;Ä•>úð= e·öµ‡.½X7¬eË8}o4¶³_ÜÐ6õföÕ!ÖíäÁ?1Œ¬iÇ÷ËŽ\ÒDG¥Þ¸Üéíé¡n.¯µŠÝòõ¤Ḛ„V­ÆrKMýã  ‚—†Ñn½^ïr`Æ—ïM(õ–˜“2ÊëtñúMØÿ× AƒøøxŠ¢Hâï÷†a¾^ž šû9Kä®^]ÚÆëýª%ÅR™S—úµ[´iãN ®îÞuölÖ8ŠbuB =º¤*÷öí[z«¤6‹ŠoÝ0¾NhTtç¦ÑÅÅú†m{Lž=Ýê £bꇆHF*•EÆÆ‡ùÇÔ‰v‘JÌ,צ~TH\’0y×öKss¡ÔuàˆÁ]; pó 1 £JÚ¢ûQ#Ð&mPlŒ—Rnd°à¨w•PCÏ$Y'<**.Z-ÀëDÖŽŠŽuW‡Ôkì«"œ¼ü;&Ô¶-ѵƒœ àÖµe½8ŸÈ¸h%°BêEÄEE‡Ëyóý«ø‚4ÍîÝ»íÿ¼îQ£F3F.—ÑÔ?â®T*I’Ôét…Bîää„a˜Éd6 ‚(’$éæêÊØƒÁHÓ´‹‹³N§g¦{0 £iÚÙɉ’P,ËétåÇ«Õ*•J% ¢Þ 7›-E©U*ƒÑȲ,MK”J•Á`xx¸8¡Óë%‰Íf3›Íš¦ÝÜ\ ÃH$mI‰TJ«ÕN$A°«Óém6I’îîIètz“ÉTSw/Žãnn®F£‰a‚ \]] MÓ8Žëõ:“&39Wß´yÚ©Íãg}ûî·¿x-€8£ÑdµZqwwwÓë Íoã`RÒÍÚÿù¸¸#ÈËØõ½iž¾–îâæ5kíþQ¯74æ¦r÷ø{=wt òjp«Õôä¥$Œ‹®('å?œAqG^ ,˦§g<ムÀˆAqGŠ;â@PÜ‚âŽ8wÄ ¸#Åq "öÒjÜ´EëÖ-ÿ·yë÷›~l‘Ð|øˆÑ6–efèðQ-š÷ý¦-?mkެɡ#!„ƒaĨ±­[µ\»nýÎ?7iÜè­ÁÃ(Š,))=f|Û¶­×|ùÍÞ½5l0àÍ!r¹¬ °hì;Ú·{mùŠU¿þz¸AýúýútrrÊÎÎ?ar§N>ýì‹ãÇOÔ­Sç><<ªÉÞ.•JyAE¦íí$Aà c“ɤ<ÿW»•!H’Àq›Í&•IyžE‘¦i«•¡HÃq–µI¥övHÓ«•¡(ÃþjçxBZ"±2övŒe9©”æ8@(¹×Na`YN*•r  ( Ã0Š·S c“H(Ëq2©”eY€ýÝ!à9N*ýk÷¾Ü»ÝÛÛG£ÑX,WWW½ÑZcf ŸôÇ ‹oý6µý’/œÉ²©:¶jÀZôé·®]JLQ¸…¾Þ¿30+3Pþ‡ë4šâµß®kžÐœeYA‚E!$\ìWÀ`¢øp;ŽcàÁv OKK¿|»uË&“‰ B!‚ `8†a˜(m£¯üõp¹ïëÝ_+M¿°pÁGÚ£]Go\®„–JM±}ìø‰ððЦ͚öê=@X'ž¶˜ûÿðÃss úõï—••óŸyɈ®®®5´Ù¾0 Rq׿ÜZ°b  ÏÈq Þ2žçŸvÈ5°pOU®W0À¥ýÆMë"q³êJËò2 VÉŠÝ¿wŒff¤>8*ÿ1’’n’$ɲœ(pI7®K$¯Ó()Ñ&&^Khž R;U8zŽeÙ+—/yxx˜Lf“ Íg_C@QT©T!¡! Ã<ô£J™¹qáXƒM' ¸eïq¹JÓ'“F´ï=d`ÏÎá‘qï.Ù”téWû¼(Ëv_$Üsn Œë=pHtl݆ÍÚ¸e”©Õ÷.²™õKæ ?Ïf.ê2lîíô;"•ߘñéô³WìRxú‘ùqåÜ×ßg”{J$\Uþé’8Ž'p‰„z `-[´ŠˆŠVx‰D¢PÈŸy÷"/ä;w¾þú[w7·‡ÚŸw(¶l?0~Í´¾Q§×/ÓQr‚ÀÝexö­k3w_I;»ñܶUïÌÙœT¢?º~ÆÏ«ß,`œT4 ^¿…Çï_öÖü¡]/—j©ý0 À•ž¾‘M²NÿбE×d³xñ—O›ÇG¥^;›£kùÙs‰¯ z?Ø]^á!yÂÄ÷ìŸNžX9†cjêå?È¿©ûþô©%¥¥µ?9Ӊ¹Æ¾o5TG6pæK¶]ÊW*$AÔíûqßXO¹»ûúa箉sSE„‡x9kÊ EFûvèÒA§ÓzÅ´®ëçrùbºZ& 8†“ŽãÒ² Jʵ©·ó5ÅuêÇÓ–â«·³tÅÉ©L»^]x£®Â˜víÚ„•ºúÛþÙ¨2·DjF{öÜ9é#S¥>±ïÎý¶e‡³ ¯m5”k¶o:9îË®†Ëœi†gŒ)gÒ¦7”›„¼0 `8Iˆ¼…cY«M¤Às"…ÿû´s Ž®ìtø÷ÓuÔ3®[óPÊ’i®0©áa¼ðÔ‡b2›ssóhúá%äŸw¦üîg;oLÛŸ8ØÏf0 ÝN¹´¨«Œ¦ž…DEžýëH í™NÏÏ»{ãN§ ¢ü´ ùÍè°Ü=Âc" %ý:ÖôéW™ÀØãÇr‹Þø/—fÍ·ðÈá•éÌ +*2"*2²ô‘ÎÌâžxô H(gu¯Këµ,ËÐ5ÚmÍ÷›~o¢Vë_7ª(Ä Ïý²q “sòçŸj÷šÜ©¹ÿRóãfÒ!ѺrѰÖè×Tºœô;~ýõž*yqLII7ýzxãwkõƼÛŸw7ߺ‹V¾I˜uZV„Ç©/M¹I(ãczc|¨I_ŽÓ.C† ¥cý-f³Ü=tìØQ‘ž2& é5bpù•ã=FÎ:~œ´4µçÀ!¹‘AFƒµYÇžJÎõnA1ãÆ¹ú«Ekƒò÷†îÚ._ø˜mû×÷Æž=ûÞ›<¡2“iyzzyzùZ­æJî#¤ÆðöönÓ¦•Õúð‰È'Ä=¾kÿV yqA!B¼nÏ‘õ0L„Hœ(++Ã%®¼ÅÚX£ÉD»„ôo4šÒ†ñ˜ÖýzÓf5””d˜®ñ€Ññ‚¨×ë£Úô¨#‘”••©ý¢Ä63ô cãYëÍ?M)ûz_G½¶à1]óìì’ 0 ËLO;uê„Jù¯³žK$©4Y§/Çİ >”CUJ¥ÞhyüN@^92™ÌÛË‹}djÞ'ÄÝ`0ا²ƒ–––=xaIɽÏó@WggÖXV\ĘŒF{vïßñþÚXV£ÑdmûfÚÇ,ÞÛÝh3Œ)iႹ¼ üoóO {|ñ•AÓô¬™Ó ‚”H*»à ò_½¸³ wSR~Ù³¯k—Î%eÿÈR• “Éd~Aš¢ã_Y< Ã\\\\Ý}€hËÊÊzüü!ý :z䛇ï³×ù7ˆ> ÔF£ñîÛ,ÇÖ .Ó™"V%€yž/+-±ý{ÿûQV«µ¬T[VVöÄQb8ûúúÌ›7/?7»° oáÂ….NÊ]»vîÞ½ÓÅY¹pá‡E…y¹¹Ù‹-ruUoߺuÏž=NNŠó”hв2Ó/^ìîî¼eóæƒö«•òyóæ•—iÓÒR?þd‰—§Û¦M›~ûí°J)›3gžÑ ¿sçö’%Ÿúx{|·qã±cÇä2鬿X,¦›7“>ýô3?_¯µëÖú$;;K«-Z°`¡“Z¹ç—_¶oßáæê¼hñGùy¹……ù ~èâ¬Þµk×îÝ»]œÕ ?\TTT››³hÑbWW§íÛ¶íÙ»×ÉI¹`Á­&+3cñG»»»lÙ²åàÁj•bÞ¼ùåå¥U´ÛU*Å´i3}¼½ëׯk0Züêw//ÓQâîî¦T*###dR©··—½=,4ÄÍÍM©TFFDH¥Rï ÀŠ¢ÂÂB]]]Õ*UdD8-¥}}|(Š suqQ«Õá4MûùúPæìââ䤎ˆ§%??¿€Š¢"ÂÃ""Â%I€¿ŸŸŸŸD"‰ˆwvrrvvŽˆ£(*ÀßßÏÏW"‘DFF¨ÕjW—ˆð0’"ü|}$”$*2R­V»º¸DD„“$àããCÓöv¥«›kxxI’A>>Þ4MGEEª”Jw7·°°P’¤‚‚ƒ|¼½¤RidT„R©tww !I*88ÈËËK&“FEF(rÐ’$k{yzÊ䲨ȹ\îééR‹"ÉZžž ¹<ÒÞîåY+8˜¢ÈZî …"22B&—yyyÕzuv»ŸŸïðÃòróžbJÔ—“³³“ÙlQ(äÇó<¯PÈÍf I’$IZ,µ›)Š"{»‚ãXä ¹Éd–H$[,V…BÁ²¬(Šr¹ìÁv¥Ra³ýÝNK$Ž[­V¥Ri³ÙìíF£I*¥1ì~;!”ÉìíR V+£R*­ ɤ÷Ú°2ŒJ¥´Ÿ7°·ËdRóW;-•šL&™L!¼×n±b8FÓ÷ÛE›Í¦T*-+Žã4-1™Ìr™LE–e•JŽv‰Äd6Ëå2A¸ßn!‚¢$f³Y.— ‚`o·ïFŠ¢îµó<÷Àî¥(Òl¶(ärŽ5v{Yy9@S¢"塸£kU‚âŽ8wÄ ¸#Åq (îˆAqGŠ;â@PÜâpK‘× {×kùåW 1p@ÿrî‰7¦¥Rÿ€`Ž­ÂÅ·mÛ–žž6彉÷Gk;&‡‹;IÑ·o&ÒtŽn/++ýþûƒ’Ée•‰;Ë¥§§J¨"êY˜L¦õë×׫WO¡P ¸;žç(ª _¸ ð2™Tùï—Y=ÀóœÀs"Q%}KQàišrrRWŃ¿Z1îþ˜9@ž'ȧ(Ãð*« 'ð§®§†BUò’ÆŠ‚ ˆ†A( ‚V¥ÇcÄATª3c*/JMÍ4Z9œ’ú†úP@¨Ì\ì•ÄÛÌ7/]ÔñAÃ=||/lÿj×]ìį›~ýjÁ”Ï·n=X×·˜Ÿÿ”Pà49™Ù¬ˆ©Ü¼BCCœ•4ªsZI(°9™Y¹EFÊ”ÎÁa¡^.*ˆ&N{žwKiʤñ³’2‹}|} .žA#g/í^ÏÕd0üÛ/@!Aà•ÿõ”¤ô9‘¢¥q1Q[õ5iÚK%¼Åè¬VDEÖ“)èŸâeUnœÝ7{ñ·&ssu2š­u[÷™=ë]_™À±l5ÅK¸sñè¤ÙŸ[ÂÇÇ‹ð^ïÌÕ§h,GqvOˆ;Íë—,¾xWsônN}œÓ]8{ÞÄ—ý´rm¦k½ùÃ{”k3¿_ý-×a`#—ùó–y„ÔºzîGJ;¼1~ÊøLYIöíÓ+ÖzïóU¡’’¯–,Ù{òª»X¿ñï÷oc5Þ{ÃPçíþö†Ä÷»ùt% k;¹uÝéR×1ý°¿®·P̽saÕê wr´‘ Û¾7çƒ0•ÀÚlÏ«±`ú_$ ûþÇ徸îêáÿ ôÙÊÀ°%#›NýŽ{l½ôk—YÊuÊ'+›×’™uE{6mX»ã¨»opÏ“ßêÔ0óò‘¯7þâäwîô9ϰ†“ç̉õ lÌ)þTDÖtôÐÊ+ö÷S'#i}NjŠ–—ˆŒaïúÏ8pVÀ$uZôXøádCÒ±¥kv¾5mnã7“¾ðǯ¾5&ÌÑíÆ™C«ÖlLÍ/­ÐeâûSk)öi.¯ñžÐwgÊ’¿ÜmÄþü–j]q‘ɶlÛ4Zyñì—³ËåJ%™W¯Ü(4áœî—#'n–ªÖlÞ>ª{øöïVå rŠ"/Ûž”VììñÓ§3×ïýsÞª/û·œùv¯Ë&‰\þ÷Üê"ÄX«ÙhÒ•••™ ÚÛ—ÏŸ8sI"Waø½¸›J2§¾÷Ù%n骥îæㇾcR{$îY[» 'ÉÿrŠ©$ë|–Ö8~Íj_Ê¢Õ–‡7n?¡w“ÓÛþ§·šöžúóÏ»Æ×mÙÎmTÏöé@yü‡å ¾Ü1gå×Ã{ÖûbÚ˜ƒ)e8[ºkÿ¡LPkÃO›<-7–,^ΫÝíKÐügŽ9)iЬÍZZ¦—:»û»© kat¶á“g.˜1òÆÁ “¿ø54*0#9ñ—‹) µÚTtwÇþ£rÿ0“&eÊÔùЯñç«>#òμ7~¦EíI’èœÌßžð»±h³êÊK4yŒÍf³ÙôzccœRZåŠÙ§ˆQÊi¥IáÞ~ïÎû¢Qlh—ý½Hã‘ãI4mýzó…nsþçVrêƒï~Ÿø¿ý¡.ʸ:G¸­ÙzÖÙÕåþÐäbíÜ~‘j•k­Ð¨õ—™p¹³çƒOÓ÷'e—Ž›;C)‘½ñV¶0éèÒØ:õÞ2™þcÇC—wW¡tòå%¥,ËšàåÉ–˜yáæ2hÖ×­â"{z?\Á~÷Õ†ï÷]üŦ:¾.¡õÞ¨ç³qëoO·Ú¡±§ÏŽ 1¼WIÚ• ½Xá •GHÔ#Æ½ÛØ¹¸§¼~Ó¶S®ºš£#hõÛÓ§Ö tSºÕúôý6¬›Çø7™Ú·ñ±ëy)tá’Ô9¤÷k-®œØš[Îz¢œ’õÔÇ”uùÌ݃Çä E¹RcXn޼w¸7Íï·0€©TJ€™KµF(qmÕÀ÷Ê©cEÎù¶OÿpÍù},yçyž¨Û²M“ºNáãå6dÝÕ™=ýtåå&Æ´ë¤ ¯+±”d "ÿͼ邡œ ˆn#&F»Ë}ýmxMž““ûßfHurqam&m W˾*˜À•é¥*©D"“Ò´Œ++Ó–”Y=d†¼lJOmXšõ³ÂÆÚ|}¢»whg²þ)S*X›¡¼¬¼Lg•J(#Ÿñ ’(©Wí­‡¯ÎË:rø×eË×N¹vwǶ%SúöO+ãk Æl'÷h4n×İòÃÓ™…É))µšwöqÁ¯¦é ¥_Î.Ë)Šê2|B¸3ÍshŠÌ¿=!î ïèváîûVo˜°v<®Ó‰¢( |þÑ=ûÃúŒïén6ß;ö@xÖÆ06›ÍEñÑÆur7{}ìGsFÒ.ž½œÖcô»ÜÅ­s×^Øü뢤è?à•žu>ÕbÚÈV2ëæV¡ÒõË>þíjÁÚ5S(6Qk±îûî³ÖáS7¯Ì·à½F /,Ù?°kHÜáó¡TÉɃÕÍz5T=ÿ~‚Èþé‡Ëi¶þƒûáå)Ÿ¯Úì^¯cHh ”’fd˜=,':Žß.wn„ Õé0kaãV¯iÏs"êwÄÊ'ó½…Óko½œ\Ðsø¸)eFÇ÷¿ûËx‹Å»?Ò-Béå<ûã Ç ç{}h­/.&t]×SÔ§[Üj59þÛ¦±ïÌnÛx•›§ß¸…k¼ÝDƒöYê©až<­†aJ¥ÒËÇÏ>ÃË ‹DQô÷ó£¤*xD“Á¨×ëýü|‹ŠŠí+6áïïGѪÜì4ûd‘8ŽûúúJåN„üܬû}w E•—•—••A1 swwSȹyyr¹ÜÃý°°ˆa™Lêëï€`³è ‹Š” …»—_VFÊãgQ}PXDlÒ+2é½eL‚pssU;{µÅƒÁR–Ü»ÇØ™”ŒŠ€M¾^¯Ç0ÌÓÃCéän¿eqA®¡··Waa‘ÕjU(^žù… Ô—•M~oê Áƒ‡RPPøÄ’dr…‹«{VFªD"ùkoû`Éä›Ìf/OOûS³ŒA"Ude¤ñ5€ã¸´”[Þ×l6§¥¤<{5•#Žˆ|"…KèÑã‡yWÑøïß#¯"÷ @L"subYCåûHÈ+ŽB :W9\Ü?ị̂ˇ?G,ËJe¯èùxšâ¢‹þT«UUQÏór™¬*ù•ãpq'É*¹ôQãÆ«ä-ÏüqæÍ·†Ti1€¶íÚWõS¼ü.îgÆÉ1ŒÄd(),,ªÌ-šAÈß_I¥Š0]NNn•>ÅËÏáâž••ýbž¨òÓ{Øl¶Œ´*?{ø¦yù9\ÜŸãEXÏ â ó’^«Š UÅq (îˆAqGŠ;â@PÜ‚âŽ8wÄ ¸#¤‚oU/üyÞd2Êd2ôUòŠòó hß©ûí›×öÄÝ×Ï·m»ÎèÀ¼Òòó²qþyÄ® îáá‘w“o¢ yWA$I Ü?ò^A܆!‚@ë= 5ê± Åq (îˆq¸Ë;j°°ˆXQàí2WÉ“&7mÚ¨S‡özƒá¡ùK¥2Aü/³1?»S'O­\¹rÇöÍyyùÿv÷%éÆ5©´ WHÎËËÛµ{w«–Í©Š¦±—Ðôä[ˆø _7N᪕ˆ“ʹŠ{‚áØ3.òxEº8«ÿmÍqQ1à j—­­†A•JIRO8{Žâ^£`Xծȉc†=îí„ ÞÏ<÷O«2ïsôQq (îÈ+ êµÅz«ðT߇¢ÎLÍd3ëÎ9\Ââ$IJdÊÀÐȨˆZrü·E¬þ#(jóÒ®]OÖ[9J¦Žˆ­@Aþ¹Ì}]—Ž]êNÛ¼gf‡¢‚‚JgDq¯™t)ãf-ö ŽŽ *.,*Ó™[¿ùîô1}e¸‰ç^Ðh¨ÂÔ³ÃÆ-àIyhX-–±â¿ž=óãqÎf£ñÙÛbhèBø…=Õ½Pg¦f¢(2ÎÇköúSû÷Ú¿ûÇ…c:ì\9÷`bŽ\.»qv_Ï.5n1sé&“ÜÄ™eÓ'Lÿâëw‡ jѺãŠÝ.îä.ÙÑ£S§f mæ®ø©¨$4ýT@¡ _8k±èRïpRÚý{÷íÜ´èý1þ ñÆ‘­¯wíß(að˜Y‰E6©\~÷â‘q£Ç~ôч­[½6t‚T“T&—ÛL…s&ŒlÔ¨Y‡®}~<›çêªN:³¿oî›´˜öñú"Q%ù—³C‡â^c‰XMz£©œÃäúöë\?`×Á“úâÛoŽžÝuü‘£[ÓŽý0æÅ¤‡[NFʾïÖÍÜzâÈ÷Ó×Ï{¢ˆÉºrdÊ‚5½¦~~øÀúÄ}ó?\É+Ýžª—l*ºòû­‚ñ?“±%Å…f‹©S'ÜOfÖ±ïÌøð÷£?·ðc¦Ž›d ”¢µìøé³\X×Ää+ TyÍ]l•óÇ>šTòÓ‰s?¬^àJ‚ô«G'Î\ÚâíÙ¿ŸÜ/Í;5}ò¥›„|êô¢¸×X@Qx^°ÙlF–ôpVé‹JsnþæáþéšÙµc›nÛ0ùÎÉ- ¹ Eë9G_ rñ‰mÒ6Üïðå;ׯžqñŽ©årãVNBã¸üÔ¹åÂS­l-É„zƒR­–e9›5M6ß©c¸tùfLý®$/¥ÜªTHëEÅ9LFHº÷hoÑd¦$ŸøùBÖ†¼´.õÂê4ióvç˜c‡vA©[|½Z‰W“7ohÈ¿{+Ϫ”yàÁPNÓôà‰Ó‚U˜êÝ(îŠùwož¿×÷Ýæj*G_r=WË„¤¶0Ó o/'NEÎ!Š"Ä%Rooÿ¨æõV~ûµ3 À2 £Õ–°,[ùçTùÕ¯ç£ÞóÕ¦·– QyŽÓåÞÚqäòŒý‰ÓZÖ*8ÿMÂÅO8–¢ Џ·3TzKðçMýša Ã|}"ë~üÍ×þ@„‚Íf³i‹Sͬð´×d ¸×XVs÷Ú™S˜ââÉ߾ܰ5¼Ý¨qÝS)ùî`óâésÇöŒš2{cÃÿHL|`IDAT·V7ö¥¶2xàT F)Z·ë6wÍÔA#ãúµº}þDé9hÈ[jòiN Òß­ßÜýíþiR¯lûùXïQï¾V'ôÊÙ?SÝ ¸>«8Oªxtˆ Fûµ^Ô7vvëXùwkñ¢Ûy¬ÏÀ¿Ü4ipßq“GöȺúG®‰8¼7MâO{Ž õÝk&ZáÔ&ÎÿäæÅãßòëùôëžØ÷•›%_âµ{Ç*p÷ÈØ±³zMýfËêáÖܼ Ô r±1 †Ó-š6Šv—ûÔïvl÷˜rtè ·wŸ¼ßÚY!yªóå"Ä[¾“vf–yfö”)›öœùáÚ±c†-û|Zúæùí»½íÕ¸ÃäIsU¼EáêÓ¼i5Á ‚èæФI#)¤ßýú§÷û6œ9rðÇ«þGøGÔípàço=t×F¾5øÇ}Ç·ópR7mÜ0ÎGf_µ·’Ðѽfrñ‹þþô5û’ËÆ¢Óf§Ù{#Ê æG.\€yK^V*ÇIÆ-[ÏrœV«Å%î3¿ùÞd2çäiÔa-éÔ•iÊÊÊž*îB½Ñ¢ m{èöeÍÆRmA¶Ô?áÂÍdHž5‘UXPâÚ,kÓW£Ñ0 Û¢W«ž®EÅÅ9ÅüìÕÿ›¿V0è4¹¹E ßú;ž 0è´ee¥ã¿üŸÕÊ”––Vþ,>Š{ÍIJìCK.ßg2™Zj8/ÿÞqáým*\Íø©@ ƒáŸÃâM<Ÿ–r÷¡[šÍæûµÝ_ù¡e¨MfóƒkMrs+X’úñPgq (îˆAqGê»×V«ùä‰ãUºB2Ïq²Ç®|îì’$¢£*¥ÂlyÂ7(î5‡\®|Ï‚c˜§§G…'CƒŠŠ*µ”l™5s:€;}„â^s¼°)lËK‹JKKm/ÌËÄãŽýUÚ:{ó÷š#-åV5ž^½<ú¨Š8wÄ ¸#Åq (îˆAqGŠ;â@PÜ‚âŽ8|«*¡$þÕU ‚kzTXtRaw profile type iptcxœãò qV((ÊOËÌIåRc .c #K“ „CKÃd#s 3ÅÜÈÌÔÜØÌÒ<ÑÌ(dlfafhnd”« ÉÒ·ö—&Ãï>³iTXtXML:com.adobe.xmp 334 312 Ò×IEND®B`‚fotoxx-12.01.2/doc/images/HDR-adjust.jpg0000644000175000017500000004205511701011016016257 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí 339 354 ÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀ3A"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ó/è¾oØkÞ#°Ô5 ûë¹-À·˜!%FrsíK$‰¶ÉáqO¡»J[G1ü!𻎣TŸÿ@5ïÞð6›wá—Ø"ܨ ®Ñg%rN¥qc1ãGšR¾—¶Û›Ð¡í.äì‘à‚ÇÀ„dxS^ ÿÓÒT¥ø%Yü!âVû¤Ü¨é[7:L1xÝô›RÞWV]Ç2Ä ã5ì~"ÃÚÖŸžu9"Ò.bùSå"…qžüóÅuáêF½(ÕS‘tæàúሒX<âI#yJËp¤={Ôé^ ‚gŠoø†9íek”C^ó¨Ef–Úm”VÚu¼G^„G¬™ß@ FO$U =G¿ÔOaÉäV‰'ýz™-Ûúõÿ#ľÁà_ú5ÿü Jtšg‚#m²xGÄ Ýp×(+Ù®´í|1y=µ¦—¶òHûæ@ælJp†Èã¬?ŒW+w©Ø\A‚ÛIn…&·Æ÷;FC`öíE;¦y«éžŒ3Â>!\Œ×(2)¿`ð/ý šÿþ%{•óhòL×°X^›m ‰&`WÌÞxàõö¨úΟ¦Ø¤÷r¬ße?#( '=:w£•Ùá¿`ð/ý šÿþ%HšO‚Þ2éàÿ2¬.ø× |Q´ÒížÀéÖÛNÛľFÐŽàí qùó[·ó_Má=þKû[}:;-·± Ëü[Áå³G*µÇ}lx÷Ø< ÿB¦¿ÿIJºw™€_ ëäžIÍ{9Ò¼;ÿñ-m¦‹!b’%Ø“ý!®r2§žxÅ^”xvÖþæH4ý&#§ÜÚzòŸÞú{×±x®m>Ý|M¨ÝiZ-ÅÒOµà0uoâ 7&¥ÐžÅ.l|¯±î—A;£y0ŒçøO<})ZêÿÖ×[[Øð¿°xþ…Mÿ’œºg‚Y—Â>!*½H¹L ö[BŸU¸¶[}6Bm'{BŽ<¨î2>é'ãÞµYl4í/[Ó4ËMIÍ…´»i>~sÎ1Ÿ­ $ ¿ëåþg„Ýè¾ ´‘RëÁÞ"…ÙC÷( ¡¨~Áà_ú5ÿü Jöé,´iõ‹ÆŽ :êþ=>ÜÚÛÜIû–cùç¨ã4Kkዾ’ÞÇK¹coÉNåŒ0`^z}©ò¡_Kÿ[#öÿЩ¯ÿàRQöÿЩ¯ÿàRW·ÝèºÓ5Ø­-ôØL/9K‰€“pt)Ü ‘Ûƒ^3BI¶Šß`ð/ý šÿþ%`ð/ý šÿþ%X¢Ÿ"'˜¯öÿЩ¯ÿàRQöÿЩ¯ÿàRUŠ(äAÌWûèT×ÿð)(ûèT×ÿð)*År æ+ýƒÀ¿ô*kÿø”}ƒÀ¿ô*kÿø•bŠ9sþÁà_ú5ÿü J>Áà_ú5ÿü J±Eˆ9Šÿ`ð/ý šÿþ%`ð/ý šÿþ%X¢ŽDŰxþ…Mÿ’°xþ…Mÿ’¬QG"b¿Ø< ÿB¦¿ÿITµýÂ7>Ö®tm'R°Ô,'ÿIœ8!ÛjÖ~¡ÿ"ëÚ×ÿFRÓ¹æÛ:üþMÿ}QYôT}=ðoÁzo>ØÛjÒ]F¶÷rÉ[ɰ‚xëƒ]RhÞ6ðêýƒFQ}h˜§¬mÓx$sJæ~\]Z~ÏÚœú{´wiç™z†ÈÆ+ ð6‹ãK¿ ÚM®ùÃPbþg«IcqÆQa`8Çs\ØŒ5Çàô–ýCÄúŽ¡ý©1Ë‹9ü´AØtçëVÿáIø{Ÿø™küÿÓïÿcZðˆx†_Ÿûì¹ÿ–;æ¸ÛÿÞ™ÿ¾Eð†x‡þ†Ÿüƒ7ÿ­a¨ÇDˆ“æwct_…:N¨Å}§êºâ\ÅŒ÷*àduÃ)ª·´+‹‰'›UñK#v7¼’{ýÚ¹ÿgˆG?ð“îöò¦ü|ãŠ?áñ¯þW¦ÿäz«±Yÿð¥<=Œikøÿ¯ßþƃðOÃÇ®¥¯ÿàoÿcZÙ”?-Ͷ¼Å~ûÚê‹"cýÅXÿß#ž™¥iê@»Ô£kz.ÂÈÏ?<:Ô<;©E®é‰h¯›©5&pJ²Œ®s¸Ž+Òáðͼч‡ZÕ¤CÑ–ð‘EØY·ü)OÐK_ÿÀßþÆ“þ—‡è#¯àoÿc]oü"qÿÐ[XÿÀ¶£þ8ÿè-¬à[QvG%ÿ Kÿô׿ð7ÿ±£þ—‡è#¯àoÿc]oü"qÿÐ[XÿÀ¶£þ8ÿè-¬à[QvG%ÿ Kÿô׿ð7ÿ±£þ—‡è#¯àoÿc]oü"qÿÐ[XÿÀ¶£þ8ÿè-¬à[QvG%ÿ Kÿô׿ð7ÿ±£þ—‡è#¯àoÿc]oü"qÿÐ[XÿÀ¶£þ8ÿè-¬à[QvG%ÿ Kÿô׿ð7ÿ±£þ—‡è#¯àoÿc]oü"qÿÐ[XÿÀ¶£þ8ÿè-¬à[QvG%ÿ Kÿô׿ð7ÿ±£þ—‡è#¯àoÿc]oü"qÿÐ[XÿÀ¶£þ8ÿè-¬à[QvG%ÿ Kÿô׿ð7ÿ±£þ—‡è#¯àoÿc]Lþµ€f}oTŒc?=é—$:—ĺœ§û±]´‡ò4]…‘•ÿ Kÿô׿ð7ÿ±£þ—‡è#¯àoÿcZ?f·øõ›Åw ~ë£8VüN?Z?°õ‰¿ãÚN,uûn±åçýß-dÏãÆ‹°²3¿áIxwþ‚:÷þÿö5ÉüWø¤ø;á®»u¦M}4×>Ln×SyœÈÇ»¹|â)¢r¾${V`pˆÒÊPûH\õ)øVÆ:óKøÖº¥×ÚõH¾Ñ>âÁß$g&ÀøþŠ(ªõÂù WßïÉÿ¡ ÷¨?ÔGþèþUà¿ä_¿'þ„+Þ ÿQû£ùT±¢Š)QEP@ ‚±¢ŠÍ¼Ð´Ë¶/-œBSÿ-#ö† UþÎÕ,ù°ÔštòÊðo϶ñÏçšÜ¢€0ÛÄQY)þÞôµQÍÄÄsÿmþ·Û5{HÖ4Íj›GÔ-/áFÚÏm2È ú¤óRê–qê:eÝŒå„70¼.Tàíe ãð5æþðSøvÎæ×Á×’)Ø´ŸhngnŸ»`>QÛw4Þ^êßé/g¦F.ïW練Ùzy‡¶{§Ò¢MîÜI­\²D 6¿ðâüsOÐníBÆ8ÚÖæ!óÛË÷ÉîÀŸ¾3Ÿ˜V½$h± HÔ*ŽRÑEQEQEF`ˆ–&$Ë 1Ú9úÖ\Ú 1ÈfÒ¤m>~§É#ÿ¼ó­Š(ûZëNã[¶+ëyn Æ«Ž¨;“Ðw"¶a–9âI`‘$‰Àet9àÓë}!í¥{O³ÊijÂʤõãøIõ±EfØjÉ<ße»ŒÚ_°¹á½Ñº8÷Ž+J€ *¦¡©YiÈúæ(è°OÐu?…yÃüIÕçø‡tͦ²|—“ "ä-œ•Æ8ühÔ©®é–vU©'‹öfëþ?5(í‡÷lãÇêÙ4ôðÖœX5ÒKxÃþ~d2¦}E-ljt¨¦hcºûUÂ46qµÄ‹þò %G¹À÷¨ÿµu;Ž,ôIâí¾òT@=𥉕lÛü)¼IH0¨Š@öŸ@g×î?ÖÞYÚ)àˆb.ÃÜïøQý€Òó{ªê3“Ã*Ëå£BªnQ@xoG„äXDç9\ɦâqZqÁg1Ĉ}U@©( Š( ¼ßö”ÿ’O{ÿlÿô:ôŠóÚSþI=ïý³ÿÐé >'¢Š*„}Gð‡þH÷ûòèB½êõÿº?•x/Âù WßïÉÿ¡ ÷¨?ÔGþèþU,c袊@QEQE’:ÆŒîÁQFI'€)k%÷j×&&ŒfÄß>ñþ½‡@?Ù¯®1Ó4”uó›„#Jþ›þ^=ÛýŸnõ´Š¨Š¨ªŒ´PMGN·Ô#U¸V¼¤ˆÅ]¨aȪ1_ϦȰk ¦6;bºU;[Ùÿº}úVÍ6XÒXÚ9T:0Ã)P¨¬@$ÐÍ$“égŒ¹ÜÖÿ⟨÷6!–9¢Y!uxØeYNAú(¢€ (¢€ (ª÷×¶Ö1y—s$KÛqäûÞ€,S'š+x^YäH¢A–w` RMchjZ‡e—‘ éswÀ#ÔF9?Ž*H4L«6¥<ÚŒêw/Ú؇ÕP|£õ"€)ê:…¾±‡N´–øç1ܧÉ7÷–Cør2>µ@®³Gˆõ#o§àqlB±oI\”cŒ¨÷Ù¨ P…#ªº•u §‚È4Ÿ§hÚm‹y¶–Ñù­É‰’F÷.Ù'ëšÑ¬R—+‹3i@äÄ/õ_UElE"MÉ+ÆÃ*Êr QEQEQEQEQEW›þÒŸòIïíŸþ‡^‘^oûJÉ'½ÿ¶ú4ÄôQEP¨þÿɾÿ~OýW½Aþ¢?÷Gò¯øCÿ$ ûýù?ô!^õúˆÿÝÊ¥Œ}QHŠ( Š+VñV•eª&Ž/íÿ¶¦Ú±ZnB[¡+‘Çz»¨3Þ\}‚’4ÀiåA÷Wû€ö'ôPjü$¤P¨HÐaTvŸh–vûØ—‘»»¤Õš(¢Š(¢Š@ ö54RhòµÅª3Ø9ÌÐ(ÉŒÿ}§¨üElQ@ †Xç‰%…Õãq•e9Sëh.t¹^}:>ÕÎémƒ`¯«GêÙã>µ£å¼ö‹s¨`#;ÉÀ_Jž«ß_[XCæÝÌ‘'A¸òO ë0ê·™òô8‰½ìÈDCÙϸù}óÅX±Ò#‚o´]K%åßüõ›¿î¯Eü=(·Ûu=KåÓ`[;sÿ/WJKcý˜ò3õ$c9ÁÆ ›ÖÖ_>C%Ýß{‹–Þÿ‡ VQEQEV4¶’iRµÖœ$’ÝŽf´ÜHûÑŽÇÔt?^»4PV·][¤Öî7Tµ“uo.Ÿ;ÞX#ÕÔXÙ[ØÀ!µŒFƒÜ’}É<“õ«È$ŽhRH]^'«)È#ÚŸXóE&‘+ÜZ¡{;¦G1žîƒõ#ñ­XeI¢Ibpñ¸Ê²œ‚(ôQEQEQEQE“uo.Ÿp÷¶(^';®-×ø½]Úöïõ­j(+[ˆ® I pñ¸È"¥¬›¯7Kîb]ö.wM¯1žî¸ê;‘øÖ¤R$±¬‘0ta•e9P¨¢Š(¢Š(¢Š+ÍÿiOù$÷¿öÏÿC¯H¯7ý¥?ä“ÞÿÛ?ýšâz(¢¨GÔä_¿'þ„+Þ ÿQû£ùW‚ü!ÿ’}þüŸú¯zƒýDîåRÆ>Š(¤PÞÜ}šÝ¤da êÄô5PPnõû‚ÜáWh!Ÿ¹Ï^:qêhm>ÜÛÛáØ´®L’1$å\zÀ{Uš( Š( Š(bÄ9$ö ³µL[J¶Öñ=Í댬)Æ«Š>µU¯nuf1é.aµè׸ÏûêF>µ¡§iöÚtL–Ñà¹Ý#ž^FîÌz’}h­ž–Ïp—š¤†âéNèÓþYÃ죹÷<Ö­PEPXò Ñ¦kˆØ®Ÿ!̱Èñ¯ õ;ÖÅ E`ÊH*FAék†ÐäÈ ÚS@äÛ“ÿ²/¥l«PÊC)ƒ@ EPEPEPEPY¶pp€é’7ð/01ïî“ù}+^’DY‘À*Ã ɴfÒîÎâ]ÖÒ[;õû„ÿ/ZÖ Š( Š( ¼ßö”ÿ’O{ÿlÿô:ôŠóÚSþI=ïý³ÿÐé >'¢Š*„}Gð‡þH÷ûòèB½êõÿº?•x/Âù WßïÉÿ¡ ÷¨?ÔGþèþU,c袊@VÔ&x  >Ñ)òâÈÈ÷## “ÏoZ’Öon‘[håV=ÍU´qyx÷*syŠ3Ï'ø_çj¿@Q@W3yã}6ƒÁ¸×?†Ê5;ÛÝO ž½oÞÝÁešêUŽ1ÝSè+-m®µ†~ÚǪ[+|ÒúiÇîÇÒ§²Ó¤yÅÞ© šãªGåÁì¼r}Ï5©@ªB¨©h¢€ (¢€ (¢€ (¢€ ‚ c£q ¦Ý:FýÜ™$DÇøO¢žÇð­Šl±¤Ñ´r¨ta†R2 QXÑHú4«ÃÓœíŠV90“ÑúzÃÒ¶h¢Š(¢Š(¢Š(¢Š(+»h®íÞÐÎ+*,’NçvåRO­Y Š( Š( Š( Š( Š( Š( ËMG*«Æãk+ ‚=+")F•`¸f}=ÎØ¦c“ì­íè:Ù¦ËMG*‡†HÈ"€×¥ˆ%›DaË$Úf~Y³–€z7r¾‡·zÚV ¡”‚¤dÞ€Š( Š( Š( Š(  ýFÍšE¼´]Ä1… y«ýÞ>ž•fÆê;Ëdž-Á[ « 2pAˆ Šž²ïQ¬nšþ!#Fø‚1€1¿Ÿ@9ö  J)ƒ(e ©w¥ ¼ßö”ÿ’O{ÿlÿô:ôŠóÚSþI=ïý³ÿÐé >'¢Š*„}Gð‡þH÷ûòèB½êõÿº?•x/Âù WßïÉÿ¡ ÷¨?ÔGþèþU,dŒŒ"Xbÿ[1ؼtõ?€ÍO I )`Q€Çòª–x¹º’ìà¢æ(¾ŸÄGÔÿ*½HŠ N¬Wyµ¦+m3ÛéÊpÒ§ÞŸÔ)ì¾ã“Ú€=ÅÆ§3Ûé³mã;eº9=Õ=ÇsØÖ•´VvɺlzçÔ“ÜŸZ|Ço C,q ª£ }QEQEQEQEQEQEQEQE x Ö+%ÆŠÄÛ§¦gsF>ü¾ÑÝ{ãµmQ@ ‚hî"Yau’6 § Óë}>kZçF cºkB¸Y}×û­ïÐ÷õ¨âñVŽo!²¸¼ŽÖþV ¶³²dô  Ê(¢€ (¢€ (¢€ FA¢ŠÊ·Ù7+n.Ÿ)ýÛâ&?ÁÏcÛJÕ¨® Žæ†dŒFjžq$S×Cp£1°ãÍO\zŽâ€4kÍÿiOù$÷¿öÏÿC¯H¯7ý¥?ä“ÞÿÛ?ýšâz(¢¨GÔä_¿'þ„+Ü.dÛejÅ^P#R:ŒŽ½Gozðÿ„\|¿Ï÷äÿÐ…{^œÂòo´)Ì1/•Ã7ñ7ÿ»Ðt=A¥ŒÐŠ5Š$F¢GX£g‘‚¢Œ–' $‘bžF Š2I<Y­H%™Ji¨sGƒ9þó³è;õ>Ðe×Ò’C¥õ;¸k‘Øz„õõéÓ9ÚETP¨¨t£ÅQEQEQEQEQEQEQEQEQEQEWâ†úOˆ1¢Š*„}=ð²#?ìñªBi“ÍMÞ™ f½cÀ:ø+Ášuåù¹[`î×1Ì[¦O®+ËþÅ<ÿo¢´çž@‘ Ë9ÈÀëÚž¥«Ao{­iÓX”ÿWc#(G˜¯÷·Ö¥Œ|Q\k,—°µ½ŠÉšSÙŸû?lÀ©¾Ï7üóoʳÍÿ<Ûò¤4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP4Tßg›þy·åGÙæÿžmùP ªêUÀe<FA¬›ØÊg±ylnO"H}×îŸÊ·~Ï7üóoʳÍÿ<Ûò w:ýŸm5ÇpL2éŽTŸÈRZCòêq\éÎ:›ˆ–=üÁ•Ü‘]ÙæÿžmùRiX›ò  v·–ב$¶—ÍŒ«Fá Šž¨]x[Oº•å—K‰gs–š$òäo«®õ¨?ịþ<õF/Pì$ô­Edÿgø’ßýUŵÐèÑ8õ$´y¾"ƒ‰ôh®åžÞ}¤ea×êEiÜD—I €”‘J6=Á¯,øõ¦[hß[M±V[[XâŠ0Í’?5ÜßjúÄVm-—…5k‰•€ò]áŒs’ò8Çë\gí ,óüž[»W´¸u‰ž`ÍßБÁ¦€ø¾Š(ªöOìÆü*ËsŽ~Ó/óÚê-Ó-u‹}69£šíçòdU?ê¾]Ç'§·^kŠý™?ä•Û×Ì¿ÌVåÏ„µc"Ágsg ´wÓßGrrf .ãŒc ÝsÈ¥î>‡B!ÒtëÁk}}7C”lð¤à1ôîx¤‡^²Ë­ÌðÀÂY"\¾Cln{sŠæ§S'‰4xå´ŽKøUî‘^só+}ÓížÙÅU´ñfœö±É{(µ’[‰ Ž&Ë3ynT·§Oαo<ww¬›ë¸í®Vê(æ·\Ám÷R6 ëÜR\xGRKku°šocžáÖò;‡ãY%ß·h8é•aÔ z S¼€}h¤@ÊŠ·0Æ2}ii (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÀÓüI ÝÂFè°+Ip„¼€"ÆN=9ü*¥çŽôH¢†KkÈ®§Š) œyjä€ç#‘ÇãT.¼<±°šæ5ˆ­øb€–up=±Íchz^¥â r+Ûˆ­â·²kA¼Dè²yLI0=;`zÓI6„ÛW;(|a£Üj¶V6÷ 3ÝÆÏ¤lWå xàä÷«—Þ!Ò¬5cy}W{U¼¶ÎB± è dÖ&áÍCNñ'öœ[I“ÎdFb¥c©Èã’6ô¬ý{EÕu_ëY­¼vWšu¼Ï2œæHNÂ$Þâ…g`îux‚Ä©ûUÄ01’dP_!„xçÔqK'ˆôˆî­íÞþ4ê­œòîçÓ=³Ö¹mKÀ·WúD\—6Ëmä·ÛÊorùÌkÈà{ÔqÞ¥ŸÁ×3ë“ÞÝGouá†Iã7×0¤n€#FãånQ jlÙx·M–Ö .å³M,‘¤G,Çc•ϑ޹ÚH•øW¨Ÿ¼Œûê´çð†¨–öãN¸†ÚùSöèîä/‚˜+ 磵™ûIÿÉ+Ô?ë¬úñ}QTÙ?³'ü’»oúù—ùŠíŒt¶¾½¶¥Ù¹ŽWEÊî €õÀ"¸ŸÙ‰³ðºÇK‰˜­K¿ ^·=¾Ÿ Í.«qp®¥14* ç=Ø*å-Žê×Qµ¹¶´™fDQ¬‘+¬ÀŒŽ [¯.““jÍ}o< gk ›ImÇÙÚ1ó2Àgœ¡æ½I‡É‚eû,–Ù™ÛI¼¾OßÎNô¦ÒèJo¨Í#Y³Õ­Ì¶“J1à ¬T’:ã"‹bÊ´rÊ.§ñ˜Žñ¼‚pHéÒ¼Èx;\žÆkKM8iwcíì×þr~üJF¼z•<Ž1Zº?…ï"–Êhlu F[¸¤•n¤·Úª¨Ãr¬@29<š-¨]åÖ©ck ijÝÀ©n¥¥;ÇÈ\ŠÌÿ„»EþÏ7ŸkýДC·coÞF@ÛŒôçé^_‹>¡5®‘iajVv2-ÅÂÎŽ·r,ŠÛ‰RHÞAûØ œv®©ômüEÿ ?öC‰Ôl4Ó4~aE£/Û3–éž‚‹ »ìurø£HŒY‘t$ûZï„F¥É\ã8xæ´§»Ž¸-Ü6éƒØù@Q““Ú¼¤øYµe,¤¸¼žÇɉáº,&óÞMÇ‘‘‡Çû½9­ÿËq6³¦Ãq$ðÙ_îùÁóÈÌÀè 3CZ}à·;…¼µxÞE¹…£O¾Â@BýOj’c™7Ã"H¾¨ÀŠò mùô+Qm&;=6ÚÚÔ\Z<ñ¨¾Ãdž¸éýâ3Ò»/†6‘©Í°¶‚mFgŠ Á€\(àŽ:ƒÓŠ-¸_c°¢Š) (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)I'©&’Š){RQ@Q@y‡í ¹øU¨ûIÿÇ«ÓëÌhïù%Z—ûñÿèB…¸ÑEb>Åý˜ä™Eÿ_:õºòOÙ‡þI”_õñ'ó¯NÔõ}7JXÛTÔ,ì–Cµ ÌËcè7š—¸Ë´R+PÊC)‚)iQEgjºî‘£´k«j–- Ê ›„ˆ·Óq  °ÛÁHÐA M!Üæ8—>¤ÏãRU }^Ââxá†áZYÑæ)÷±ÇoZ¿@4Åræ8Ë•ÚX¨É_Lú{Sª-Nî[=66¶0¬ÒÜÇ´ `ou_ÇïtîhÒ𘥆)!#7@TL)Ñ¢GÇ*F£ ¨¡@€•—´Ójo§Å¬hò^ÇÌ–É´Ê£¾W9{UÅ}[uÍ‘8įïõý(Í[~­øù²Î?çëÏ¿Óõ¬ KPÔ‹ô+K‰@„Ï!>ZY“)úã øþÔQEK{v–VþlÒÅ Ää“hUä’z ŠŠ‹MÖmuKo´i—¶—ge»¤‹ŸL®E[ûDž«ÿ|ð h©¾Ñ'ªÿß#ü+šðMÌ×Z=Ä·2´²h^.æ=„îú  ú(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ óÚ;þIV¥þüú¯N¯1ý£¿ä•j_ïÇÿ¡ à|[EUˆûöaÿ’eý|Iü먿ÿ‰WŽ/u+ý2æöÖêÆ+{ya¶3ùEYË¡»·/=9®_öaÿ’eý|Iüë×3Ž•/qî5¿mJ3wemeªDÓêv·,q°H­ö eÈùT ¬ ʫɥë:6‰¥_iqêwÊKgw“I!aù%*Ä…ØÀràšõ,ŸZ3Jâ¶·<¾mTƒÅQC5öª‘ÀöËg,QË22.Ýáˆm¼wÑkš]õçôû›9æ´‚;UçHƒ©%Ô„$ð3]vO­Ó jö:óÉ,–ñÝÅ—Sû<’äíÜO•‚z˜íRx:ÒâÖÞy&º×pÂxZÞPVMÜd-œôm¼cšôj2}h¸XSTõíçHbvGkÈTØë"QÇ·èzUºÆñEÕòÚÁo§é×W2 Vq,A ¡VR FrW¶:i á­,'}#BÑaÑîmõ[ 帞í ÚŠ–y½zñÁÉÏ5…£Ç­^øJÆMu¡+X},òHÆRd÷e-³v6ãó®ûû[Äù´{’¹äy ÈÏOõ¾• í!¶¶ÐåŠQQ#ŽÙT gÍàuúg¾9wÐV2t­âæçN…î5™´Æº‘ÝÏ·òÇ•¤³o+»žO^”º]&³á!¨¬‚ô ²™W-æqÆIÇ©5´uoãþA7Ç_³§¿ý5ú~^üCeo¬ßø·K½½Ó'·Š $ye*€<¹F¶OÎn™ï€_@¶·;ŠÉñí•¶¡áɭ’±>-£óue!‹G ­jÆÔµ½J+ÆŽÛÃ÷×F‰UÐ÷9¤3‚Ô%×5+SÝ¥ïØÌÎc½ŽÖX%| Ûº(ÈnN@'Ž*ůˆ¥m Úáu š­³ßJY·x¹pyùK:×Wý½¬б¨ßÈÿÆíÝcþ…CþþGþ4ÓW9¿ Xê‰â·›TºÔ’ín. ±˜d0I'ËËy`ÛŒr9®áÿü€n?ì#{ÿ¥Ký½¬б¨ßÈÿÆ¥ðE¥Õž‚RþÝ­§’îæsJ«Ì̹DZºX}noQEQEQEQEQEQEQEQEQEW˜þÑßòJµ/÷ãÿÐ…zuyíÿ$§Sÿ~?ýP·âÚ(¢¬GØŸ³#*|0œ…âNOÔW¬}¢/ùèŸyGìÄøc@?é~¢½w{{~B¥î2´Eÿ=ó£íÏDüêmçÛòo>ߤ?h‹þz'çGÚ"ÿž‰ùÔÛÏ·ä(Þ}¿!@ý¢/ùèŸh‹þz'çSo>ߣyöü…Cöˆ¿ç¢~t}¢/ùèŸM¼û~BçÛòÚ"ÿž‰ùÑöˆ¿ç¢~u6óíù 7ŸoÈP?h‹þz'çGÚ"ÿž‰ùÔÛÏ·ä(Þ}¿!@ý¢/ùèŸh‹þz'çSo>ߣyöü…Cöˆ¿ç¢~t}¢/ùèŸM¼û~BçÛòÚ"ÿž‰ùÑöˆ¿ç¢~u6óíù 7ŸoÈP?h‹þz'çGÚ"ÿž‰ùÔÛÏ·ä(Þ}¿!@ý¢/ùèŸh‹þz'çSo>ߣyöü…Cöˆ¿ç¢~t}¢/ùèŸM¼û~BçÛòÚ"ÿž‰ùÑöˆ¿ç¢~u6óíù 7ŸoÈP?h‹þz'çGÚ"ÿž‰ùÕ¤ŽWPÃn®;Ê—ýŸÌP?´Eÿ=ó£íÏDüêç•/û?˜£Ê—ýŸÌP?´Eÿ=ó£íÏDüéÓ\Ç ôVo" ™ci’1‚J)PÇð.¿OÉ&v㎽VûD_óÑ?:>ÑüôOήyRÿ³ùŠ<©ÙüÅSûD_óÑ?:>ÑüôOήyRÿ³ùŠ<©ÙüÅSûD_óÑ?:ó_Ú0†øQ©09£Áõù…zmõÂXÇ—RGÉ,p!$|Îì}Y€¯3ý£Ø·Â­K'?4ú¡ñeQV#ì_Ù‡þIœ_õñ'ó¯[¯$ý˜ä™Åÿ_:õº—¸ÂŠ(¤EPEPEPEPEPEPEPEPEPEPEPEP5[¥²Ò$»u.°G$¥GRg¥rÚoŒ7 Ö´çÒà¿·ûM¼ï:I.Íøb>éÛή£Xµ7Ú,¶Ââ– ÄgnáŒþµÅÞߨXÙëš¼°XZ}šÝm¡)óy~Xv,NN; ;ƒ5“ƺÚ¼âò@«$q”kiD„ɘŒ®â |Þ1С·†g»|K¿¶Ò³ C‡.w SÁ,ë6^˨Ǩjz”Þ!¶Eò¡*‚(K°'ïçž‚ªÜø ÛT–þ+›YfšI·Çs”Ù#ïuÈ?§ µ5ZD›â—,L¯è÷,¬§!–ßëcÿQ7á\‚¶þ?Ò`@бè× (Ķý¥uñÿ¨›ð¤ÆŽ^ÜÞj70éz<÷vv³}žk¡2 Þ1¸*±Ëc<ž*I<]¢EöÏ:êH~ʆY<ëicÊ‚˹FðuÍAk¡jšuõßö^¥mŸupn^)`-"3cvÒ0qÜVü+˧g3êp»y`2”vy °;ß,FF1€¡Òè‚Õ§k™@YV(ÚÊ&ga• Ýí‘ÈÀ9Ó¥ñn‹ÔVòÝ:K NÞ@#߉ÜFO`äT5 ÝI¯bÆþ¯c’)!ÄYØž6 ƒ“çéPKàÙ¥×&Ô&šÂãíM—)4R:2€0 ¼4ô¸µ#Õµ&Õô- íâ7ü$6qí?rñ?¥d~ÑßòJu?÷ãÿÐ…lkiÒ4= Ñ¥ŸøHlåÜ>ýâ6? Ö?íÿ$§Sÿ~?ýQ×@>-¢Š*€ûöaÿ’gý|IüëÖëÉeõ-ðÒ 1ÿu8ï^½ä·û?÷Щc#¢¤ò[ýŸûèQä·û?÷Ð¥`#¢¤ò[ýŸûèQä·û?÷ТÀGEIä·û?÷УÉoöï¡E€ŽŠ“Éoöï¡G’ßìÿßB‹'’ßìÿßB%¿Ùÿ¾…:*O%¿Ùÿ¾…K³ÿ} ,tTžK³ÿ} <–ÿgþúXè©<–ÿgþúy-þÏýô(°ÑRy-þÏýô(ò[ýŸûèQ`#¢¥ò[Õï¡G’Þ«ÿ} ,TT¾Kz¯ýô(ò[Õï¡E€ŠŠ—ÉoUÿ¾…Kz¯ýô(°QRù-ê¿÷УÉoUÿ¾…WÓõ;ÙѬõÙ,!UÀ‰-RLžç$Õì-oþ†Éÿð?þ*ºŸ%½Wþúy-ê¿÷Р[û [ÿ¡²üÿŠ£û [ÿ¡²üÿŠ®§ÉoUÿ¾…Kz¯ýô(›Ò¼?qk­®§¬K¨N–ïmµºÄ]‘‰àœò‚´µkkÛ»a†¤Ú{ËH°,¥‡¦ ­/%½Wþúy-ê¿÷Р[û [ÿ¡²üÿŠ£û [ÿ¡²üÿŠ®§ÉoUÿ¾…Kz¯ýô(–þÂÖÿèlŸÿ#ÿâ¨þÂÖÿèlŸÿ#ÿâ«©ò[Õï¡G’Þ«ÿ} äßÃ÷7O¨øŠ{¸-n¡»ý‘sDáÔdTW1ûGÉ)ÔÿßÿBê~Kz¯ýô+Ëÿi)ð§RÎ>ü}ˆS@|UEUܺÕ5 &öæÓM¾º¶¶IØã™€­Eÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÑÿ 6¹ÿA{ÿûþßãEÂM®Ð^ÿþÿ·øÔ7zæ«yCw¨ÝÍ uI%fð&Š(ªþÁÓçÛÿ"7øÑE†ÿÙfotoxx-12.01.2/doc/images/resize.jpg0000664000175000017500000003176711701011016015665 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 283 319 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀâÿ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmÁŸM²fkX‰-n„’Pd“Šž+YåtÛ6oSj€€z:óìj]þ@ZwýzEÿ  ­«nžælN5ù’^С<—õS»ÜŽ:dIöíem‰—fò¢ÕÑêxã=½p})·zv™+.•§’N9¶Oð§h¦4†KvVKÄ!®Cœ³±þ<÷lqŠ—S8…?Þþ”â®Å-ö}?þ:wþ§øQö}?þ:oþ'øRfŒ×G³F<ì_#Oÿ Nÿ€©þyýtßüOð¦æŒÑìâì_#Oÿ N›ÿ€©þyýtßüOð¤Í&ê=œ{;äiÿô Óð?Â¤ŽÆÖE݉`ÃÔZ¯øT9ªúœ¤ZÛœ“8ú/øÔÎ**ö*-¶_{ dRÏ¡Ø:“h¿áJºu»Eæ.‡§”ë‘jŸáYvZ@ÊÀºasÎrúƺ[fŒ%žKy»ËÀ'ÐÔ+5{ Ý;\Çòtÿúé¿ø ŸáG“aÿ@7ÿ“ü+VÑc6Ę|É7·š  Ï¥Dèš"Æ÷€;ùìzæ®Ñì+˹J[[(d(úF™¸z[!þ”Ï'Oÿ F›ÿ€©þ®‘{rR$hГhäã§µ%²!€–€<›Ïš /ËùôJ^ï`×¹––¶r)£éÇhÜÑ“ùS<«úi¿ø ŸáV¬+wŽžKb®3,q8Eò@® AÔÓj)ì$ÛêdùVôÓð?Â*Ãþoþ§øV¼p ½œ¢©oîƒׯ^ÔØVžHãòwùø!ñ÷=³G»Ø~÷s+ʰÿ F›ÿ€©þž]‡ý4ßüOð­kd‡uÆØ„’ H*Î߯²g+ç¾ÕÚ»ŽíUބܗPòì?è¦ÿà*…]‡ý4ßüOð¨óFj½œ{ÎÉ<»úi¿ø ŸáIåØÐ#MÿÀTÿ fi3G³as²M–ôÓð?–ôÓð?£Í£Ùǰs³R×MÒæ·IJÓÃ6xÉþ…ãí:ÂßÂWR[ØZE dÃÇ©0îtšw6p}[úÖ'Ä_ù®ÿßÿCË%fÑÑQ£aoi£éQLdß%œl«O!!Q?(8ûÃó©R°Œ»GÊ™s‘e.Xã?-UÒ¿Öèöoý·­ÌŸZC3N§`Ò¬¦+“"ªßb— £îûÊ¢¼¿¶¸U~Ô¸9æÎoþ&µò}hÉõ¡;;ƒWÐç<Ƚ?þÍÿÄQæCýéÿðoþ"º<ŸZ2}kOk"=œNṡûÓÿàßüEáþôÿø7ÿ]O­>´{Y³‰Îo‡ûóÿàßüE&ø¿?þÍÿÄWI“ëFO­ÖAìâs{áþüÿø7ÿJ²ªgd÷iž»m®òZèò}hÉõ¤êIÙ£›/6ç–å›ËZÎOê´™‡ûÓÿàßüEt¹>´dúÐªÉ Ù£šÌ?ÞŸÿæÿâ(Ì?ÞŸÿæÿâ+¥Éõ£'ÖŸµ{8œÏî?½7þÍÿÄQûŸïOÿ€sñÓdúÑ“ëGµ{8œÎaþüÿø7ÿGî½?þÍÿÄWM“ëFO­ÖAìâs?¹þôßø7ÿSÁwöu+’ŒœäØÌHÿÇ+'ÖŒŸZY0öhæXÄÄ–yÉ<’læÿâ(ý×÷çÿÀ9¿øŠé²}hÉõ£ÛH=œNg÷_ߟÿæÿâ)?uýùÿðoþ"º|ŸZ2}höÒg˜ý×÷çÿÀ9ÿøŠ?uýùÿðoþ"º|ŸZ2}höÒe˜Ä_ߟÿçÿâ(Ä_ߟÿçÿâ+§Éõ£'Öm öQ2m5 X-’6LÊIȳ›¾Ù÷¬ÞAyà»æ·f"9cG Œ…[*pCz0?uÙ>µÅxÏþEŸ×ü_ú. Í»»–••+ýn‡ÿ`†ÿÛzܬ=+ýn‡ÿ`†ÿÛzܤEP0¢Š(¢Š(¦<‘£";ª³œ '\ZÊñ5ɵÓásröѵÌi$ˆpBçžÕky4’Y–¹’[O¶È‘\8’!9Î;óíL¦£’x¢’(äp¯+m@ˆã8ü…r0ê:¨ÒoßÍ™îVk@É‚öû¿Öà—Ç^8Àãšu´ò¼š|òßÃq½eŽT”Ëåæ"0ÌUsÏ·|P#°¢°|+x×6÷½ÃÝ<%C\ |Èä$¸p1Ó•í‘[ÔQE†&Fq‘šZäot©uM{WŽ(-€ ©sæAò·)×ñ>+ÍEüE,2ÞÇ G9 ’dˆ/&ÌõÝ»­gWErqÏ2ÿ‘gÄõÿþ‹‚ZWúÝþÁ ÿ¶õ¹XzWúÝþÁ ÿ¶õ¹@Q@Š( Š*¹ŒæE¶B€zdœçLAqmÈŒL¤ùr,‹ƒŒ2œƒSî9ÎMgI<±HÑÉ©Z«©Áfn?ñêoÚÛþ‚–¿ø ÿüUW#'y>§ÖÍýãùÖgÚÛþ‚–¿ø ÿüUIºí¬å¹†öÚD‰I8·aœ ãïPàÖãRL¾I=I4•Ry…½Ü6“êV©<ùò£h°_qóUˆ‹üé!£m¤€xúÔ }T3<¾l0ÂU^R~fžè6N1š\œc'Ù/ÿçòßÿÏÿGÙ/ÿçòßÿÏÿLD¹9ÎN}hÜÞ§Ÿz‹ì—ÿóùoÿ€çÿ‹£ì—ÿóùoÿ€çÿ‹  r}M!$õ$ÔUâÜ,Mu(["1‚÷½ê.Ö{i®moí®£·fYiŒê3¸ó@¨¥# G¡¤¤0¢Š(¢Š(¢Š(®'Æ_ò,øƒþ¿âÿÑpWm\OŒ¿äYñýÅÿ¢à FÖ•þ·Cÿ°Cí½î£&•}mrYš !–?+³K€ÉøœøÑ¥­ÐÿìßûoZóÛAsåý¢“Ëq"nÚáô åÎ¥4oos ûM…¥Ã^ªeUœ¦$ñŽ”Ý^þöëK¹Š·Š híüÀÁŒŽ_iùNx\çšê •©{‡6ñî¹P³s €àME>•§\ÉÏe ´j è=À÷¦˜š9íR[é4Í|µÔf$º);”å1ónéÏL~5½¦Ý]Mq}m{ä´Ö²ªï…J«†\Ž $~f¤“L°–if–Ò&’a‰¿õü…XH£Ie•Uå Èë03øPꦥÿŸöÒ?ý Uº¯ÉjDjYƒ+`u8`¥8îb…ÀI//ceBÃq^âqëQ=´f1eC*«38ÆsŽù÷«W ³I)ß"HrTY¿øT-l¦¾(:/Øäÿ éR]ÌE6ð©ˆì@-¸6qМ»*h·›…hØåzr*ŠÛ"mÛ5ðÛ¸³“ŒõíVD¢=:æ·“I*¶ Z¸ä®éQ7u¹PVdóÇ ’OæYÆþaBXe‚ýÜý:Š|,Yçf&^Gük:îÆÖîô\É Þsó¢Æá%ÇMãâ´-ƒbWeeß&à`ãtü+œÔš où Yý_ÿA©ê r—vÓlvHËnØ¥ˆÈÇAÍ3ï.ïì¯u†ûI›Ê°ÃÀ_·º3Ud¹¼·»]55决–¸b ¦òÀ€qÆvŒzf·üû?9¦0NdtÍöY2Tg»Ó“ùÕxíôˆ­d¶ŽÁÖN]¤˜>ŸÃLEh¯î`ðö©(Í-›L°Èü— 2 õÇOÂ¥ÑÞhµ)ìšî[¸…´S $ •f,ÈìvƒŠž!¦ÃåùVr/”Œ‰‹I8SÔ}Þø¥³þαFK;IaV9`–² ÿã´ûì¬Õ ue'®j­ÂÆ–Ó²ZÇ}œÇ¹Hû€ ¤»–;‰€ò'xÌLŒÝðrWŽG 5BßOŠÚ ã¶Žíä™J\•^Ê (  —ûíõ4”¬rÄŽæ’Š( Š( Š( ¸Ÿȳâúÿ‹ÿEÁ]µq>2ÿ‘gÄõÿþ‹‚ZWúÝþÁ ÿ¶õ¹XzWúÝþÁ ÿ¶õ-Þ²,õϱήa6¾h1@ò6íøçh8ö¦½˯Œ`†Ê .Ñ ÏJꮱᕠr[Žƒž*òë;^TŽ9n¥{³ 1€«œ n¾€s“@TW._ùhÍ÷üùäU¨õËû]FÙ"6¯òªv·šGñ6s€^Ÿ1.uS­=˜žÊX£ˆÉ!ì¥3€ç$à玃ޘ‰ó}ÿ>_ùi’ËwO+ÙaQKÞ¯AYñø‚ê;{Á,QÜO é B(Ú"ìިİž{ö­®ÚóAºyZTI@#1í`J~Ô>ιÿ®‚–7.2•em¬¹Î_ê*¥å•¥ÍïÚe7ž|g:«'vñŽ{ç9úU˜˜<— “¸Çð-KQM)‘#ŒÉ$‡  ãß­KP7ü„¬þ¯ÿ Ò¹¾ÿŸ/üŠ´fûþ|¿ò*ÕYõ‹«K­L\Á†ÒÐ\F‰gå‡' û½*Ö58'¥£^Ëå„j°9ÉÆÓÜg=©ŠæŽo¿çËÿ"­¾ÿŸ/üе Z¼©£_ÝÝF†k"È#ÈW(3ÆzgŠ~™{z÷²Ùj"2“«@]¬HÁžA^½óÚ€¸¢K¯4FÖ›X©a™Añ§4“F†I 5ûÌ椼?é n‘w@ëº5Ë •äp•g%¥¥…•ÚÙ‹”Y"mÈኖÁË’GÞ=Îy  20H=¨¥¾ßSIHaEPEPEP\OŒ¿äYñýÅÿ¢à®Ú¸Ÿȳâúÿ‹ÿEÁ@­+ýn‡ÿ`†ÿÛzÔq H߆8Ãäã#nÝÛ½:çÞ²ô¯õºý‚ÿmër˜1èðÚÖêòÝÑJ×.¥‹a²¤pIÆ<Ó5 í2X¬Æá®MÀuchخӂTŒ`t Ö͆aØxv8´×†îYZiíšÞbŒ1†fcƒŽ¿7^žÕ~ÓLŠÎêY žãl¼´%”¦ì»¦s€;ãÚ®ÑNâ°UmC‹\öWF>À0$Õš) ¯&ê¨&£qŽª¥ÆWhç*H¾ O¤½ä‘Ü:Évۙà ®(ÛÇlwÍGökùöƒþý/øQökoùöƒþý/øSö-£G/{q4ò”o´<‹½JW {w©Ú -î(¥iÒGwvˆäœJÙ­¿çÚûô¿á@··"Úûö¿á@/ ¸–ût:‰ŠÝÏï£Æ[Ž›øsÐõöÁ«¶Çq‡C/ÿuEIäÃÿ<"ÿ¿bž †„.¡fÌ@]Ì2zd­OHʬ¥YC)êÈ4’ÙYÍsq4¯¿í y°ÚT?ŸÌjšèvBW¼¸’V)¶w•L‰³î€qŽ2zƒœóš³ökoùöƒþý/øQökoùöƒþý/øSÈ´»8à0‰d‰ÖA*¼€‰‹õfã¯ÓiúvŸm§´Ž·2Ï,Ѝd™Á`««À ŸÎ³[Ï´÷é³[Ï´÷é€ý‘î|Í»¡q¹[d¯CëY±Ås­ÇÛ/…ÌŽ†8®юÙÜ÷==­A¥¼#éÿ…9cNV(Ôú„Òï÷ÛëIE (¢Š(¢Š(¢Š+‰ñ—ü‹> ÿ¯ø¿ô\ÛWã/ù|Aÿ_ñè¸(µ¥­Ðÿìßûo[•‡¥­ÐÿìßûoZWZ•…œ«Ýí´8ʬ²ª’=4jŠ@AƒzZQQÅ4SR+ùm±öœíoCïÍIHHQ’@úÒÔaKèÖE ¢68a‘œ¯øÐ¼Äþúþty‰ýõüé ›J¹¸’ÞÞK)f‹ïÆ…Y“ê"š·cEs3+g),’(URÏ'·4ÄH[î°?CAe_¼@úšdéÏlð*(ry@a·=¨†8ä½›ÍEp±¦7 ã%³ü…;ÌOï¯çG˜Ÿß_Î’Ò}*ôÈ,䲸1œ8ˆ«m>øéPG¨èåƒ-œm+2ƲmVƒ´í“È  !ƒ}ÒÒ‚Ê¿y€úšd±¤Wш‘P4LX(À8+æimbŠI.XÕÈ(,3´êh|Äþúþty‰ýõüéÑ>hÞHE´‰v@¤)AÇqU­õ àÀ‰- –áÅíYOBó@dGµ!uS‚À}M7bÇ}*F¡WËFÚrÃú [H¡x¤’XјÙfð /˜Ÿß_Î1?¾¿5æÓÂKáög¶YÚD à בô¤†çIžà[Fö†çhcËæ(Æy^¢€$r)  8, ýi‘*¤÷(€*¬ƒtPiÖ±Û 4éBÎî©ä“Hbù‰ýõüèóûëùÓgŸM‚Ä^•àm»4 ¿qq޹$T¤X ‘jE·žWx‹ ¸¯Lã®=éˆN´Òè ¯çQEòÅ2¯dp£Ðf‘¦Ó,lmå¿–ÒÜH •w63Ôõ4€›ÌOï¯çG˜Ÿß_Τ…,®"Y`Kyca•t AúOû5¿üð‹þøÀ€:€ÊOÖ¸¿ȳâúÿ‹ÿEÁ]¥ô¥„îÆ¬‘³+*€A ×ã?ù¼Cÿ_ñè¨(gJÿ[¡ÿØ!¿öÞ›c{uâ'6î°Bö[Ë%¿š§çû£3ŽyÏÒ¥­Ðÿìßûo[”†sQiÛ¶¤–k7™ok6Jǰã±9Æj…½Çö\ÅßP\˜³ØgÁaœän,Àô%N8ÚQLV8ÛûmNé­Xnm!k@¨Á$æ wýÖmÁ`GëS½ŽÓ¬E,ÑÜM)u¹†ÞGWL/M¼r8ÍutP3ô#)Ò¢ó­M«ÀFw3ÁÃr3בWâýOý1oý jJ†UL²Ä¡ˆR¥IÇRô  +«¶·ÖßUò.þÏko0“϶ò–>„ygqb?ÚúŠ‹QÒ5ðäP*C1[yež-¹çqœ€Î 8¸ô­Ù–KˆÌsÙ¤ˆH%YÁŠ“Ì¹?òî?ïà¥ÒÁÖäqy¢ 9gP²*a€ìv{Ôð¶Û»ƒŒþî>?¨Õf’dy L‘óg$ŒRºÊ“´‘ p걌güM6îî YXçc¿t‚÷Rûŵô°‹kX^ÑâT°‹’f,Ù8è:w©µËC“o¤ÙCw4¢T¶ÝåOI(ÈÉäu­‰IJlÑö0uÜàíaÐýjO2çþ}Çýüù›v¡ýræ´[àý©­&õù™ÊÓ‰eP›T¨ç9#ü)š)d1Æ\îûØ àéH # Úišd›c~ÐB¡vâ6ÆY}‚†9«7ÍšÕ½“XÜGgjÑH²Ehì%q÷ð0p2Iöõ­YHä{4gŒ’Œ\er0qøTžeÏüûûø)…‡BSÿL“ù½¤sYË È¯»†VèFi!I<×–P° à ÿ4 â,©u,XØëHf1?öN¢¼F/´];I]¸…±ãÐü£èjÕÉ–ãÅRÁÑ[yÌ[l‰R «àn=2G°­²Ösf†UR¡÷Œ€zÐTžeÏüûûø)ÜV#›‹£ÿMþ€´Ã WZG‘kJ™ae|nrXã¶iˆnccòU¶€¹qHfL7ÙõK(\Ë< ³Ï$€O5™Háxð>µBÏMÔn¦»Žò{¨n&VaНœì>f⧺2çþ}Çýüy—?óî?ïà FnšofÒu íJ)!¸¹B¾KälTM½;dî?B+Æò-xƒþ¿âÿÑPWW(¸ž'ˆÂ8*[x8¹Oÿȳâúÿ‹ÿEAL +ýn‡ÿ`†ÿÛzܬ=+ýn‡ÿ`†ÿÛzÕžIH£Ë !#.phz+:-BGÕÌ*H"!e‘3µô\ž§ãµOwz¶·p”,n¥òîü¤çô eª*•ö­a§È±Ýϱ™K`+6ÕÄpÑîp)dÔíðZ ÎT6ÔFp ô,@ÂçÜŠ@\¢³4=U5;(™MÉ…e•QNÔÝÐg  ÿ¯ø¿ô\ÚÒ¿Öèöoý·«ú•Š_Æ‘ÍËÎå/´ò0=ˆëT4¯õºý‚ÿmër˜úu‹ÙYÃj!%2É3ɹäc’Iã©Í&«esu%œÖ’B’ÚÍæ(%[å#}kFŠC1n´­By$š;«Xæ¹·û=ÇîÙ—h$‚žÿ1àñRÚésØ]±±š/²Ê±¬‰*’ãbíêëZ´Sáíô8¼w ö쀺`äKÝ”úØúqU­ü;qëÜK5´çË™;7‘àœ`cWEEs-¥êv‡O[yGK¶d;GydmÉçõõ§Éá–)m"Ë·L‚eaùŒãiÈÁÑÑ@6º]ÅÛµœ–Ék8A,E*Uvü„vÇcIm¥ÝGáùt™§…‡`†DR0¤ ßéZôP C YЮ5-âŽâ-±Û´ ’îÛ’Þ6ž£ýiÏ£]{70ù–Ë›ÔîVXÊ1Æ:VÝ\† ú ò,öñÝF¶·k¹ |  vœ€:ô­ârI¢Š¸%`¢Š) (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+‰ñ—ü‹> ÿ¯ø¿ô\ÛWã/ù|Aÿ_ñè¸(µ¥ÿ­Ððqÿ†íÿ^õµ†þøÿ¾úõ‹¥­Ðÿìßûo[”Ü7÷Çýóÿ×£ ýñÿ|ÿõéÔP1¸oïûçÿ¯FûãþùÿëÓ¨ ῾?ïŸþ½oïûçÿ¯N¢€†þøÿ¾úôa¿¾?ïŸþ½:Šnûãþùÿëцþøÿ¾úôê(¸oïûçÿ¯FûãþùÿëÓ¨ ῾?ïŸþ½oïûçÿ¯N¢€†þøÿ¾úôa¿¾?ïŸþ½:Šnûãþùÿëцþøÿ¾úôêŒ f¸h£u@Š’»³’}ý¨Øoïûçÿ¯FûãþùÿëÒý–ãþ~Sþýõèû-Çüü§ýúÿëÓ˜oïûçÿ¯FûãþùÿëÒý–ãþ~Sþýõé“$öè$iREܪFÌu8õ÷ a¿¾?ïŸþ½oïûçÿ¯N¨áŽy≑g åçëš@; ýñÿ|ÿõèÃ|ß?ýz_²ÜÏÊ߯þ½e¸ÿŸ”ÿ¿_ýz`&ûãþùÿëцþøÿ¾úô¿e¸ÿŸ”ÿ¿_ýz>Ëqÿ?)ÿ~¿úô˜oïûçÿ¯\_Œ¿äYñýÅÿ¢ ®ÉK¤ï Œ¬UUƒŒƒ‘Óð5ÆøËþEŸ×ü_ú. ÚÒ¿Öèöoý·­ÊÃÒ¿Öèöoý·­Ê@QE (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ Ž&ÛsrGQ7©*¾ôK¹D„ñ¦2qœÏó‰cªj6Úv“¨]jv—Ì©,/»³Ê¦:ñVÄ—Kj..,âUžÎK»p’pƒ;_Ž tÍX²Òô{í¢PÑ‚¨^g“`=vîcˆ´½™c‚0³FÑ82±Âª¹?(>‹Šb*Kâk«U0ÝZFnœBÑKº‘&ìdÝ‘´ð­/¦¿ÑÄ×Ïo'œªU‘—8q†€8>â›=Ž—q»ÎŠ6-FO˜A „•Á‚ <Žiå`†Ò;kf$ ¤.ßxËMÔºk3P¾žÓI³KFXæ¹ ºäG¹ˆÝŽçÓߦj‰KK­?ì·‹Ær÷Ïè}éC{{s¢Ú({ã{q+Ÿ,OÌ@ “Ÿ®8ªÓxšèÂ.m¬âh#°[Ù„’ÛI9UãOZ°t Æ«­¸1»—x8Ç » c¶qR ?J¼"$½¸µeó˜†~^¾çž¾ôÄ4ë³}žþüAØ,¼À~cæ¹A“Œž:Ö{ë—ÆÍg¶’ßÖä8I\19_TœcžÜŠÓû–.$œFådklpFS;IÇ#4ØôÝ*8 ¤ÆdP×ÛY~éR[#‚Ž¢ÖÅæ9Ôeÿ®Qÿ7®7Æ_ò,øƒþ¿âÿÑpW_‰/&u ®Ä\Ž™Ëê+ñ—ü‹> ÿ¯ø¿ô\ ÚÒ¿Öèöoý·­Êñ†ìZè×vÅ(N2¼¥>ðˆ‚8?Ü?]óµ_úÚÿàYÿâ(ýCÎÕèkÿgÿˆ£ÎÕèkÿgÿˆ¤2ýCÎÕèkÿgÿˆ£ÎÕèkÿgÿˆ  ôU;Uÿ }¯þŸþ";Uÿ }¯þŸþ"€/ÑT<íWþö¿øøŠ<íWþö¿øøŠ¿EPóµ_úÚÿàYÿâ(óµ_úÚÿàYÿâ(ýCÎÕèkÿgÿˆ£ÎÕèkÿgÿˆ  ôU;Uÿ }¯þŸþ";Uÿ }¯þŸþ"€/ÑT<íWþö¿øøŠ<íWþö¿øøŠ¿MdWuVúŒÕ/;Uÿ }¯þŸþ";Uÿ }¯þŸþ"€-ùÿÏÿï‘G‘üñþùSÎÕèkÿgÿˆ£ÎÕèkÿgÿˆ  ~D?óÆ?ûäS–8ÐåcE>¡@ª^v«ÿ@û_ü ?üEv«ÿ@û_ü ?üE_¦4Q±ËF„ú•©ùÚ¯ýíð,ÿñyÚ¯ýíð,ÿñoȇþxÇÿ|Š<ˆçŒ÷Ȫžv«ÿ@û_ü ?üEv«ÿ@û_ü ?üE[ò!ÿž1ÿß""ùãýò*§ªÿÐ>×ÿÏÿGªÿÐ>×ÿÏÿ@‚…*€3Ð â¼eÿ"Lj3ÿ?ñvÇü³‚º7UÈ&Â×ÿ½óýÊæ¼cÄ>Õ¤ºH£{‹¨ä îb$ëÝ 1hº¾¦ˆ¨šâª€ ØAÖ—ûgUÿ ïýÿoñ¢Š?¶u_ú Þÿßöÿ?¶u_ú Þÿßöÿ( ûgUÿ ïýÿoñ£ûgUÿ ïýÿoñ¢Š?¶u_ú Þÿßöÿ?¶u_ú Þÿßöÿ( ûgUÿ ïýÿoñ£ûgUÿ ïýÿoñ¢Š?¶u_ú Þÿßöÿ?¶u_ú Þÿßöÿ( ûgUÿ ïýÿoñ£ûgUÿ ïýÿoñ¢Š?¶u_ú Þÿßöÿ?¶u_ú Þÿßöÿ( ûgUÿ ïýÿoñ£ûgUÿ ïýÿoñ¢Š?¶u_ú Þÿßöÿ?¶u_ú Þÿßöÿ( ûgUÿ ïýÿoñ£ûgUÿ ïýÿoñ¢Š?¶u_ú Þÿßöÿ?¶u_ú Þÿßöÿ( ûgUÿ ïýÿoñ£ûgUÿ ïýÿoñ¢Š?¶u_ú Þÿßöÿ?¶u_ú Þÿßöÿ( ûgUÿ ïýÿoñ£ûgUÿ ïýÿoñ¢Š?¶u_ú ÞÿßöÿŽçSÔ. h§¾º–3Œ«ÌÌ>„ÑEÿÙfotoxx-12.01.2/doc/images/stuck-pixels.jpg0000664000175000017500000003010211701011016016775 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿíFPhotoshop 3.08BIM*resize sharpen resize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 160 281 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀ "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?é´MJ} NwÒìYÚÖ&fkd$’ƒ$œU•Ót&¹kq¦éÞr¨bŸeLà÷éҥпä_Ó?ëÎýj=m`[U¸’FŠâ&ÿG’1—Þx ñg¦Þô“麲+O¦éÈ‚.mSæcÀŽMHú6ªÇû'OàϬáU4ƒ%Åë˪®ÍN%ù`þPÿrAÏBݺ}v$ÿTÿC@eÒÿè ¦ÿà2…eÒÿè ¦ÿà2… å£vFÂà©Áû¦QŒUì8É·aÿa°ÿ Ÿÿ€‰þ%ƒ±Tдö#¨ˆqúVdZ”ÅÔ5ÜÜ‘ÕÈÐÙJs{&ã°ï;—Ó'‘QŸBÝ×RŸöm N§€£qͪ?*‹ìú_ýtßüOð«Èb–;–V–@±d ÓÞ(ÆŸöó W°ÞÅ]£ÕwÑ™ég§HÛcÐôö>‚Õô¥k==I ¡ià¯PmSÒ¬éóybU1ÈÈàÑõZ·± [°s>QXêG=hqIì ·ÔÈû>™ÿ@]7ÿ“ü(û>™ÿ@]7ÿ“ü+J#‘-_É4ŒÊ›$qÃjmĦF`O?& `¼»”¤²Óã_DÓ@q¹Ñ“‘ùRGg§ÈHBÓÜîÚ¡þ•©4hlc—`’E€aOaëU´¢¹ËìQù½=è´lÝ‚îëRºéöL僧î$T•CäiŸôÓð?µRXn]bVi¼¨[.A5ÆÚÚ Èªp¹ûþÿ…T}äiŸôÓð?Ÿ%žŸ£>‡¦€ã+þŒœÊ´c‚Ñ-"iF|Å$°F'>ØéHÂ#ö2–‹Ë<€M`¼»™žF™ÿ@]7ÿ“ü(òtÏúé¿ø ŸáSj˜®ØŠA]‡‚=j¶jÕ8µ{ç$?ÉÓ?è ¦ÿà2…'“¦ÐMÿÀdÿ fhÍ?gÂçÿ'Lÿ .›ÿ€Éþy:gýtßüOð¦fŒÑì£Ø9ä?ÊÓ?è ¦à2…]³Ót›ˆ ¤iˆÛŲ{{{Övk_LæÄÿ×_þ&³©£tT$ÛÔmƤ­´¤iV„8ÿEOO¥x}uÿÓ¸ßʾr¬  ô/ùôÏúó‡ÿ@ZŸì‘áxûžT]±î×ühÅͤW/¹e…·G"2ú¡î*i1°’GûIÿ |?¯øÑý‡¤ÿÐ>×üh˜µ¹Çú‡ü¨û-ÏüðÊ®aé?ô‡õÿ?°ôŸúÃúÿkíŸc?fŠe¹ÿžùQö[Ÿùàÿ•\þÃÒèëþ4aé?ô‡õÿ=³ì;Ësÿ<$ü¨û-Ïüð“ò«¿ØzOýáýÆì='þðþ¿ãG¶}ƒÙ"—Ùn焟•eºÁCÃ2dsßéW°ôŸúÃúÿØzOýáýƇVú4 º™ía;.ß³`g?,@ΤH/#GŠ`€:J¹ý‡¤ÿÐ>×ühþÃÒçÂ×üi*–Ù ÂýJkê+*E( 0À¢³PÜ[dÙ+´ñÛÒ¦þÊÐÿçÖ×þúÿëÑý•¡ÿÏ­¯ýõÿ×§í_a{5Ü‚(¯áÏ”“&zàu¥TÔC"¬áÏVÇ&§NˆÄ´¶$ö ÆŸý‡¤ÿÐ>×ühö¯°{?2ª.£í‚uÜrp:šDMB0Áu ÔÖ­ÿaé?ô‡õÿ?°ôŸúÃúÿ×È=Ÿ™P& ¥HYUÚ8è=)©ê ªa°:Š»ý‡¤ÿÐ>×ühþÃÒèëþ4{o ö~eíïc$ǪHÁÀíNê•‚L «ÇAéW?°ôŸúÃúÿØzOýáýÆlû²ó)¢j1¡HÖuSÔB&£P‹:…èéW?°ôŸúÃúÿØzOýáýÆmäÏÌ¡%½ô®^H¥v=ȦýŽëþ}äÿ¾kGûIÿ |?¯øÑý‡¤ÿÐ>×üiûwØ=’îg}Žëþ}äÿ¾i>Çwÿ>òß5¥ý‡¤ÿÐ>×ühþÃÒèëþ4{wØ^É¿c»ÿŸy?ïš>Çwÿ>òß5¥ý‡¤ÿÐ>×ühþÃÒèëþ4{wØ=’3~Çwÿ>òß5«¦C$ve%VFó3‚;qþÏì='þðþ¿ãGö“ÿ@ø_ñ©W%b£MEÜ·uÿÓ¸ßʾs¯uû%µž¯"ZB°£ØHYTœpS^Y–{ž•ÿ2÷ýƒþißêVZw—öÉÄ^a!–Ç^fi_ó/Ø0ÿèQ­½ÊxƒFk8Riq>ß`#`ï@ÛTƒÎµòå…ฎI‡ä…ðçßÒ¤S±”Ôl;xz{t5“g£^ÙÉa0»À.^E … &Qížõ^ßÃWP階ŸæÅ²ý­ ùJMÝxþ˜ôçÖ†…νnÖ©6,SŸ´G‚Úã8àôéWïõ=8)¼bÞp ä–úÍa å­YÖÐEx$…³%óÏæ*6q–'häãëRø†äiÚ­¶£æÚîò$‹Êž]„ç*{ž:Pô@8õ:Y †;¥y.b•°”“Ѐx퓎µ±l¬°üêT³Èø=@gb?B*FQm\Ç©Giqcq Lì‘LØ*ä ô#éSGªZN­e Й‘#䲎8üxæ¨ÛÛêc[šòîÎ9@b–ì."Ù¼{ŸÂ¡Ò´GK{»ˆÖÞI¯cid\…Í’Bƒ¹Ï_\žô€ÑÓµ3ys=´Ö“ZÜ@ªÌ’~Vèr ªÝÔ¦ i%qEÎ=k;@µ¼µŠAn«q&k89•þƒ …^¿‰§±š$]Ìê@ëL ÚíΞ°ùËnÒO Ž(Ñ™™ÛØmíÔÕèËr‚Ë’=+#MÓÃV–ð¥ìñªµŽ@ÙÃ\OsŽzãŠÕ¶FŽÖ$q†UCH õÖ•/šÖöÒkR"yU܆ ‹Ôü¤‘øÕŸí$I>Æ~Õ*F²ˆâ#%[îòxæ²ÓOÔµßRŽÆÖÖQ«…›?j$aCq€'š]I¼Ñ-n­àH.’P%!3!á—§ÝôôéG@êhézˆÔ˜$‚[i<¹cr3Ôd ^¬N›O[áŠÖ)œ4v±>勎N}ýV½0 (¢ÂŠ(  «¯ù ·ýƒåÿÐÒ¼½òëþCmÿ`ùô4¯¦#Üô¯ù—¿ìô«{5ƒ¥̽ÿ`Ãÿ EZ×·¶Ú}¿Ÿw(Ž=ÁG–' rO°¤Š+/ûfÙgv’QºZ›†ß¬€ÆH#§·_jskºr[Å;É2¬ÌV46òyŽ@ÉÂmÜF;ãÀÒ :ȇYn5F¼‘c¶µx„d©ÉÞ€ãIÉéŒÕÛMBÖòÙî —1ÆÅdÞ¥ Ô0`8õ  TVjkÚcÚ=Ø„@Þк‡ÏM¹>{mÍCq¬Ç"XɧȮ“^¥´¡”«.sTàƒõ±EPZÓ¥¾ûw ͸ ùiaÉPØÚO°9§Ùjv—òJ–#ùD†cªä€>„ÐÊ(¢Â€APjÓÏ;Çlðß$g®ú:tm ‘áTH ©á‡¨¦~É÷_þþ¿øÑöH?ºÿ÷õÿÆ —SŽMí&]жÆãÍ-ÁàŒ{UXõø.bÓä³oÄ…Kpc¤’GÔøÑv+#HZÀ;ãûÒ1‘55sÚ‰`ºÑ<ó*¥âZ™ÝeŠD\¤q–QÇ+š¹m­E.§qc$r+D±°‘cvB7[_ÄŠÃCVŠ£c«Øj4V“ïp»À(˹sË7 ÷z <Ò\-‚îQ¹Ýú/§ÔÒ¡™&0ÜÜFåeèÿҒÑYº®§-Å¥¼Ë<·LÁwÊ#UÚ»ŽN T³×^öûOD‹ÊŽcp³)!°Ñ÷XpFOZkQ´U5>´mœ¡·]ò‰£hН÷°Àdq×¥T›]‰ÞÂKG"ÞkŸ.W–&åØ[#pp9é@TTV·1]Û%ŹfŠA”b¥r=pFqRô ŠÇ¹Öà·–%žêÞßÏ#ÊYCÀô$…¶kV<È÷*À•e?ÂGQHcè¬K—²<µŒ‚9¦ ÝÈB9ëëWÛYÓ–øY›ß ÷hb2¶6†>™Í1è¬I|Ao&©eec'še¹1JÞ[mÀRNÖÆÒA¡5·@W_òoûËÿ¡¥x{å×ü†ÛþÁòÿèi^@ç¥̽ÿ`Ãÿ EWµ{îþÉ5£Ä·s‰£çcpT‚G#†<Õ+þeïûý*Þ¤ _½ÔÓ5¬rÜXmªìÀ>üç%Göü*ÍíïÛ,o¬ݧ¶…¡hçfUem¹!€$Tv­Z)…ŽrÿÃ÷w’^»Kn ÄN£sŒIÁR@iõûUËm#þ$÷–sE »Ý†%yG+´Î'Êµè  )4ýZ{+hçkžÆHÞFr’ù†ß—#Ó8¦ùÏÚä–Ûí}Ó -倃Cc$ã¾+ ¢‹õ ü:%êIojó[gÛ^´eÝæ±ÜX)ÀäõÏNÕ¥£ÙËa§ýžfFo6GÊF‰~µzŠ(¢ŠC!ŒËk4¯^trÅU€`عŒÞœ¾cÌÓÌ¡®Õ@s´uäúÔ”S‹¯è²ê³Z´$J¤Çq»9x[”c¹Å%¶‰,Ýåç›Ùž6ñ æ6|oÏÇÊ?ZÛ¢ÔÞ¼“M²¶[ï·°šÙ‰fÁg ‚8éÅZUâ^]…{si{ i),ÂD*…~QŒ}È­º)·pµŒ=E—Mu7Ú–Š/*9£šGfuVásÀ&·(¢€±ó`¹iâA"º€è ÇB3ÇZ\É4âiSË ¥Q2 ç©8ã·lÔ”P6»¥M¨\ØÍ W lÎ^²B6åÀè­Ó¯J§káëÛi-æŽâÚ6G˜˜ãÜ‘qˆò;œOJéh g)má{Ò·ky4 f²ÞbM$¥Ûpmä0éÐU½KF¿Öí­`ÕM¬kÁØÛÊçrí##*9Ét÷®‚Š.+ìê;(£¾xžtYâÎÖ¡ÁÈ«dbŠ(œÔ|/kuo5Ô3J`UEò¦UGUû¡Áäc¦Fk …ï »±w#¦O§·J}€æ®¼0ÓË{t/µIt·ûŒ(+¯LÆŸ‡¤MRY¥ŠÖx&Ÿí´ò†¸$k`Ž ÅtTS©ÏÚèÚŒ3ið<¶ecpÓ#†a#®1Ÿ›®k ¢ŠÊºÿÛØ>_ý +Àëß.¿ä6ßö—ÿCJð:÷=+þeïûý*Þ¬+þeïûý*Þ¤;ýJÞÀijy$Ĉ㉠»`d࠸׬-¦ò¥iAUVˆ˜ˆƒtÞ‡ñ¥Ôln¥¾¶¿°–¹·WlÀìt|ddrTsTî´[éšñ"º¶Hu¿jÊ1d`6’ž¹½)j}zÆÞõíd3f6EyLcBÃ+–è3PÛø†#ô×pMvsIu™X+m8äŸJK I"Õ#ŽdQzaòóŸ"ÏåQË¢^µž¡`—ßeº•¦F!·«3 öÆA£@Ô»>µoof·S[Þ$DÄÛ¶P¥‡aR VٯŔBYd!X´q–E È%º Öˆ´9õiƒÆö˸ݵ þ5ÛÜ{Ò¾‹toìeŠKhVÕbV™ ‰dU(GÝ*}úP€µ¢ê§SI‹[IE+¦JŒˆá»ž+N³t‹½<Ï’Àö­#ÉÐÁÁfÉ·sZTT7W1ÚÄ$”1…ùFNMMQ\[Ãs—:o\ƒÄsõ…kêÈ©ý¯oÿ<çÿ¿fí{ùç?ýû4ÿì›ùàß÷úOþ*ì›ùàß÷úOþ*´ýß™øÏí{ùç?ýû4kÛÿÏ9ÿïÙ§ÿdØÏÿ¿ÒñTdØÏÿ¿ÒñT~ïÌ=ñŸÚöÿóÎûöhþ×·ÿžsÿß³Oþɰÿž ÿ¤ÿâ¨þɰÿž ÿ¤ÿâ¨ýߘ{ã?µíÿçœÿ÷ìÑý¯oÿ<çÿ¿fŸý“aÿ<þÿIÿÅQý“aÿ<þÿIÿÅQû¿0÷ÇZ9¾Y%Yå…ö*ª¨=ÉÈ>´‘I ¾^Ëû¯Þ…+”OâRÃø}¦Ç–›ã¶ƒtLÛ—÷œŽ#“žÔÄãÙ²Ä,(_ÞŽ6‚Bk7äZ%’àÚÜù,ÒÎ¥7Ø ãœKöôÿž3ÿß³MKS<æ[”+òíUY=Ù5/Ø­ÿ»'ýÿ“ÿФ1ŸoOùã?ýû4}½?çŒÿ÷ìÓþÅoýÙ?ïüŸüUb·þìŸ÷þOþ*€öôÿž3ÿß³GÛÓþxÏÿ~Í?ìVÿÝ“þÿÉÿÅQö+îÉÿäÿ⨟oOùã?ýû4}½?çŒÿ÷ìÓþÅoýÙ?ïüŸüUb·þìŸ÷þOþ*€öôÿž3ÿß³GÛÓþxÏÿ~Í?ìVÿÝ“þÿÉÿÅQö+îÉÿäÿ⨟oOùã?ýû55¼ëpŒÈmm¤0ÁÿQLû¿÷dÿ¿òñU,PÇ •‰H ÛŽX±'u$ú ͺÿÛØ>_ý +Àëß.¿ä6ßö—ÿCJð:b=ÏJÿ™{þÁ‡ÿ@Š·«Jÿ™{³þn|þ‰ÿ}õ©ê)¿?¢ß_ýj>Dÿ¾¿úÔ uߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýjuߟÑ?ï¯þµ?¢ß_ýj̺ÿÛØ>_ý +Àëß.³ý´ÙƳ¥éþúWÓîzWüËßö ?úU½X:WüËßö ?úU½HŠ( aEPEP]Ö4gs…Q’iîȲŸ§(?›S/¿ãÆ÷ò©5=V7ÉWŽi§ŠC+¹ä dàp0RHÄ&ëùñ›þúOþ*×óã7ýôŸüUCˆ,^;†»2X=©_:;  oºr PMZT°–ɯc¼…­—ïJmS@î¸ÿŸ¿ï¤ÿâ© ®„yÖÒĤãs#?4>¹¥%¢]¾¡l v(² z}i×sÅs¦ íäYbvB®‡ ýIQy®ÌË ¼’í8%J€§$T§­@·Øi×·—$ˆ`gw dàHc·\ÏŒß÷ÒñTn¸ÿŸ¿ï¤ÿâ©¶ÚºÉk-ÍݥΟ jµÖÀ=þV?­O§cp 0]Ã'Ú ¶¸;ÊŒ=qLW"Ýqÿ>3ßIÿÅP²·˜#–"f]Ø9üA4²kZ\J-ýº‰ª“ 䃂?Å:ðæâÐŽ››ÿA4ê…e–E¬Î‡î°*¼jSÐÓ`¹ŠÓCŠævÙ6ÊîÞ€.M!Ýqÿ>3ßIÿÅQºãþ|fÿ¾“ÿЦÚkvW:GöœŽÖ°)"Aq„hˆ8ÃsÁéùÔ‹¬i­b÷«}nm£8ywª}Í1 Ýqÿ>3ßIÿÅQºãþ|fÿ¾“ÿЍ/uÈLº|°Ý)ž8‰VȘ)éßš¼5 6Te¹ˆ¬’˜P†3‚AQïÁü¨°E  ²¬­Ô%F X“€ rM6?øú¼ÿ®£ÿ@Z$ÿ_mÿ]Gò4†®?çÆoûé?øª7\ÏŒß÷ÒñTËíf+[Ų†Öêòè¦óº‚Q}X±~u'ö½’É7-µÄà‚f üöÇ­1 ºãþ|fÿ¾“ÿŠ£uÇüøÍÿ}'ÿNþ×Ó~ßö·Aö¬íòwÙëŒzÓ“T°{™m’òš%-"P:“@î¸ÿŸ¿ï¤ÿâ©RRd1ÉÄànÚØäzä*­Þ¿l,…Æ4_éÂÛ_!w0ªÝÏü„bÿ®/üÖ€3n¿ä6ßö—ÿCJð:÷˯ù ·ýƒåÿÐÒ¼€=ÏJÿ™{þÁ‡ÿ@Š·«Jÿ™{þÁ‡ÿ@Š·©QE (¢Š(¢Š¯ÿ3ÿ¸•VÖ-nÎ¥g©Ø"M5§˜¾Ï1 áºÏš½4bh^"pHÍE›Þé>¾aý(Ìkv÷æ;^òÚ8ç•í †Õe B¬»²ÍÓ$ŸÂ¬]躅ü:…ËB–Ó\ÜÃ2Ú¬ÀdG×.8 ßÐVñûYᢷ?Y ÿÙisyÿ<àÿ¿§ÿ‰§Ð,cÙé2¥Í•ÊÚKm=ÀžäJÇ÷{Cg?AéV¬me±Ñ¥‚eMì’"©i·/OcÒ¯fóþyÁÿOÿMhîfÂJ"DÈ'k'>‚€±hõª§q±»T·[‚ÎãÉv $àpIâ­U.â7$FÊí»æb¤ÈÒÏ¥†´–·bʲ…¼¯.ÐÝ+· —ÚÜ„Êð9ü©!Ñõ(ô‰^Þ#üwÆîÙ&˜9äC08䮇7ŸóÎûúøš3yÿ<àÿ¿§ÿ‰¦#œ¹ðäðÍŽo k5¶•"º°;‹19á”–9ïÅtl«ÙD€…@Ts€ÖŒÞÏ8?ïéÿâhHæy’Iüµ œ$äž:àQp±9èk'Q³¹Ô´{ _ˆA¸`•EPpë’­z«]CÄ‹ ªªKp:d`Òš×,¯´ý;T-+^CrðJö!óDŠÀ`€9Å.·ox–ž£qh=ÌÖª–Â@ÄírÄq“ŸÒºSö¶h­Èô2ÿ²Ð~Öà ¹òÿ²ÓNÁcãKÔn“Q»6±Á5ÌÐ:[y ñd’ÃÇú 4ø~Ñâ¹ü‰K g7`©ÎÙä]¥? 3~5¹›Ïùçýý?üM"‹¤H-”g8W#Ÿû怰èn.Ïý5úÒÌq-¿ýuÈÒÛÆÑ‡i/#nltü€¢xÚER„FܹéHfmÄ7öZÜÚªÞGsÇ$^hЩ8 ·sê+7ZÓõ½JS¾ <¹<¦é@Umã‚Ý8#5ÐæóþyÁÿOÿFo?çœ÷ôÿñ4Ö‚hȺÒnåŠø$i¾]N+˜ŽáŠÈIÏc€j1¦j ¢ÞèfÞ8ÒA)KÅ”aËŒ¯ÞœÛÍçüóƒþþŸþ&ŒÞÏ8?ïéÿâi[œòè×Me,‹c,W›àÈšðJ%XÛvì8Î:×I+nÔc?ôÉøüV™›Ïùçýý?üM,QÊfó¦ØRª¨IëןÀS¸X£uÿ!¶ÿ°|¿úW×¾]Èm¿ì/þ†•àtîzWüËßö ?úU½\ž«¡K¥iFMy-.-­<Å22ŠH`{¨üªoíMþ‡¿ïôün€:Š+—þÔÑ¿èq›þÿAÿÆèþÔÑ¿èq›þÿAÿÆé ê(®_ûSFÿ¡Æoûýÿ£ûSFÿ¡Æoûýÿ ¢Šåÿµ4oúfÿ¿Ðñº?µ4oúfÿ¿Ðñºê(®_ûSFÿ¡Æoûýÿ£ûSFÿ¡Æoûýÿ ¢Šåÿµ4oúfÿ¿Ðñº?µ4oúfÿ¿Ðñºê(®_ûSFÿ¡Æoûýÿ£ûSFÿ¡Æoûýÿ ¢Šåÿµ4oúfÿ¿Ðñº?µ4oúfÿ¿Ðñºê(®_ûSFÿ¡Æoûýÿ£ûSFÿ¡Æoûýÿ ¢Šåÿµ4oúfÿ¿Ðñº?µ4oúfÿ¿Ðñºê(®_ûSFÿ¡Æoûýÿ£ûSFÿ¡Æoûýÿ ¢Šåÿµ4oúfÿ¿Ðñº?µ4oúfÿ¿Ðñºê(®_ûSFÿ¡Æoûýÿ£ûSFÿ¡Æoûýÿ ¢Šåÿµ4oúfÿ¿Ðñº?µ4oúfÿ¿Ðñºê(®_ûSFÿ¡Æoûýÿ£ûSFÿ¡Æoûýÿ ¢Šåÿµ4oúfÿ¿Ðñº?µ4oúfÿ¿Ðñºê)qÀ9Ç¥sÚš7ý3ßè?øÝ'öžˆsŸÈs×÷–ÿOùçé@wCܜ˄½±üIùׂWµGªè´ÓŸ¥ÌÏ F ÓGÀ8?«è:úWŠÓÿÙfotoxx-12.01.2/doc/images/select-area.jpg0000664000175000017500000003747011701011016016546 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 321 323 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?èt½6Á´«&kVco$¤“´{TÑÙéRM$KciæGÊmÔ‡§J“JÿEý{Gÿ  ƒRÌÓŧËó+öORßìœtïl€ýJûH·6†M»ÈëÀõp0£­4¢úm¶P»¤Ò¬”gò‘-m 2öÜ/_Ê­ÜÄÈy Ù“ærùÏáÚ¥”6Ø–D@ ã@Á6]‡©œööÉ’t»·?g\gò¦l³ÿ mþ¯øUó¸ÛN°ª’²œ‚ËÔŤoµcè62}Á¦”{ ¶RÙgÿ@Ûü_ð£eŸýlð™š3WÉyÙbÞ )gTm6Äén¿áWF™§ù‡Úß„ÿ ¥`Ó#ü•k'ÝüOó5D“ÐÒèòoÇ>$¼Ž(Ò4V\*(|£°¢ãùï¿Þ_ýQPYèÖW°ZézrJͽíQ•U‰W'€}GçR&¡d…Ê,ª\刷“æ>ÿ-WÓ¿Öiö oý£Zù>´@êFE¬¥Ô­öy2ê>ï°¢]BÊhž)fGR¬¦ÞNAê:UüŸZ2}hþ%_ܼÿÉŠžÞëOµ I×yË ¬IéÔƒZY>´dúÐ=ÍÌJ]ZP1ÞÞOþ&¢ó"ÿž’à<ŸüMnäúÑ“ëT¦Ñ.)˜^d_ß“ÿåÿâhßüô“ÿåÿâkw'ÖŒŸZ~ÒAÈŽm·¿þÉÿÄÒƒŒ+0ÖÒý–´õ+ÙlŸ†–Iæ(y6NIÁôôªÐk‘É„’æV‹d_¼¨GnEì9Q[t?ßü“ÿ‰£t?ßü“ÿ‰«í¬Ú,ÌŒî¡K/˜Pì,£,îFäh:¼"Þ)LwÎm‘§”w9Æx˜£ÚH9Ct?ßü“ÿ‰¤Ý÷ßÿäÿâjþ«©>Þ BF|éV?ßKå*d’pqÒ£—V–+KiþΓ ¤T/ ûãPX.w`g¯LQí$.DTÝ÷ßÿäÿâhÝ÷ßÿåÿâjö­qk=­½²n’vl±BûBŒýÐF:zjÖÏt-Ã>âæ0ûBàr¡ºgÚi äFvè¿ç£ÿà<¿üM‡ûïÿ€òñ5¥¤—VsOn²Eb¬è@lg§¯"«Yë°Éb²Üy‘Ê"GuhÈ-»´wÉâi!ò"¶bÿžÿ€òÿñ4™‹þz?þËÿÄÕ³«‰/-’2Ë2‰•Ô†R©»íØÕ‹V æÙšŒPH¢D+¹}FzŠ~ÒBäFfbþûÿà<¿üM‹þz?þËÿÄ×A“ëFO­/i äG?ûŸï¿þËÿÄÑû¯ùèÿø/ÿ]O­>´ý¤ƒ‘÷î¿ç£ÿà<¿üMºÿžÿ€òÿñ5ÐäúÑ“ëGµr#Ÿý×üôü—ÿ‰¤ý×üôü—ÿ‰®‡'ÖŒŸZ=¬ƒÙ£ÚXa¸Yä!sÀ·“ÓýÚ¾º¦äMÒ®ö 7Bê2ÇdŒrM]Éõªz©?f‹Ÿùz·ÿÑÉQ)9nRIly—Œ?äg¾ÿyôE0ÿ‘žûýåÿÐE†zþ³Hÿ°kí׬;ýf‘ÿ`ÖÿÚ5¡]L›ãФ7HAàãû´=^Fg¶pà µ€9ESûn˜DÇ0í„áÏ—À9Æ3ŽN}(H.jQYM}¥¬ 1hv;\G’Hê1ŒÓa¿±–k˜Ì*¦Üá³A==úu§a\×¢²þ–¶ë90ùlûòùÝéŒg4K¨iQC®öû%RÈBg u<”X.jÑXÑ_Zbåî#‚8¢”FŒ;² ŽÝy«ÖRC)2[1: t<š,QÓ¢ÔEºÏµ£†a)G@ÁðÁüé~ÁÝZÍØ’Ù]V$@ÜíÓ¥[¨çÅp# '†f[èqÛ]Íç2msõÏZ’úÐ^@±oòÂȹû¬¥Vm^×쎲¬·ê åIéøSlõ…–Ú9®|¸• iœîû 6Þ˜éïL “Zù·ö×[ñäùq÷· uíTÓH+p¤Ýj“›…ƒËä9$ýìôÉ'üjuÕ¬ZÝîÊùq¬pAôëÍ,Ú¥”Ç$³ª,£+rG®;­Ö?gÒÅ—›» Ë¿n:’zgÞ©ÜhÜÁRO‘ºB3 •`Áˆ'§?Z×9ihèÆ8bhÞ’0í‚ÜF®vãàûÓ´}6xÚ{É÷˸‰cíòÇ““Àô­j(¢Š(¢Š(¢Š(¢Š(ªZ¯ü{Eÿ_Vÿú9*íRÕãÚ/úú·ÿÑÉ@gãùï¿Þ_ýQGŒ?äg¾ÿyôEzþ³Hÿ°kíÒ·’X!˜°O!×$žæ³tïõšGýƒ[ÿhÖƒ]Û+kˆAq@ ”0·‘œm,û±œã‘YSi2I¦›o5C‹†NX½¸Fü+qY%MÊUÐ÷ƒQ:ZÆÈ¯*Òª N3Òš`ÌxôÛ‹y!¹¶[d¸MáѤvV Žwœü£µ9ì/¶ÞG ñF·-æ Á•°:q×9ç¥lýžùáýð(û<óÂ/ûàQt+všLð¼nï+uç•YøØW˜dŸ­Q½´¹°IÄf–æ9c(Ï å†~nAÀ÷®«ìðÏ¿ïQæÏÏò1oç»ËÂîÇ®:Ñp±‡&‰;("X÷,©2̹"=…I^G±«¥À-Ä…‚1a’I<žOãVþÏüð‹þøåDA„UQè£6 ¨®¤„ªŒž÷§E*OˇFä0èiô†2i¥–#Ì ©\—^3øÔ•˜¿Óæ´/³Ì]»½*ò¢3¹Td“ØP޲"ºÊÀGpi Ç‹H™|™'Žt‘ˆ–G#’܃óU["æÛL˜IJZI –Ëîô®’šî±©g`ª:’p)ˆÈm2êužk•¶yåXÑcêªäØÎìŸN*)tK©>Ï$³Çs2Äb”I$ˆÈåy8éÈçÚµÖîÙ˜*ÜDIàãšž€ãDPª…vÅ:˜’Ç#º£†hÎá8Ïò§ÐE„€ 'w¤ÑQÃ<7ùJ’¦q¹0ÏÔS$»·‰™d•T RÀž›Žæi=Q@S%–8S|®rO©8­>Š( ©j¿ñíý}[ÿè䫵KUÿh¿ëêßÿG%yŸŒ?äg¾ÿyôE0ÿ‘žûýåÿÐEèZwúÍ#þÁ­ÿ´k_Nÿ4ú·þ„k#NÿY¤Ø5¿öi5µ»Ío '©1©'ô ‹¬¿õÕ¿¥sqÜ4ú½ŸŸtít·rn¶85 ÁHÏLsï]2ª¢…EUQÐ(Àìœc4Ìý²ht+9¥º˜ËvÙ2¼Â5ŒàŸ½´àqéQµþ§%•§•+ï퀱Âȧæ?ŠóøWU“œæŒŸZÇÒo ì‰t÷ ¸.`· P éž:§0x\¼†iU“jã*óÓ­t™>´dúÐ7«Íygu´w¾T^Idšâ]›Ÿ= ØsÛŠU»¿}pÃ%Ì1‘@‰¤Ç˜›Fv®ÞrsÎêèÁ#¡£'Ö€9++™tÝ:Õ„³ËÖ’¹#ä*ÃN8ê}j[[Ë«¨¢‡íµ¯Ä^l2% e°hÏ>ÕÔdúÑ“ë@•ÅôÏm$W·ÒAGBè"¬äúš(èPÜt‹þº§þ„*jk*º•uVSÔ0È ßÿÇ”¿J¡®M,| 2êÔd¢˜aš²¶ÖêÁ–ÞGB#PGéRæµ´…¤•-/¥x§Ô#ŒÎ¬ 2ù|óŒu©¦Ô&_EkÌ L°º<£s‚™ÜoO|õ+£Éõ£'Í09?í=IO–]Ë(6Díë9'kß Ƶ5§ÃÚ‚¥ËÜmY±@ätí[>´dÐ=xæÃÈ禮·ò ¤œeäã œzvïU/e‘–i.—dÏmk#Œc—, ë#¡£'Ö‹ëp±Ï-ôï©„NnìÆmp6ˆ¿Ó=>lþQµ=IËÜä k2qÖrNÆü€ÿ¾«¬ÉÆ3MyV%Ý#…QÜœ Â×nní®- K•‚#ÌÒIå†qŒdío®8ÍRÔî%‘¤†òð¤Ë%¿“`$Ã*K ŒžsôÅt¢úÔt¹‹þû}ºÛþ~¢ÿ¾Å ƒF Ú„ãS ö·Fñ£œå…;N1“žjo]]ÝHÍ=ÔR~ì"nt|úm}1Í^Û§›±r÷{Ý[r«O”SŒd ·öÛfÿ—˜ü P€š©j¿ñíý}[ÿèä« q °T•@U}Wþ=¢ÿ¯«ý”æ~0ÿ‘žûýåÿÐExÃþF{ï÷—ÿAP¡ißë4û·þÑ­šêdßPí$ºBݬý;ýf‘ÿ`ÖÿÚ5¥m$°B#6ìØ'냒Os@‰™”ï2±RÈ☗6ò<ˆ“ÄÏßPà•úúS¢ –]¥œ¶2?*Â}&ò[{ûX[Ṳ̂¢»«å²pG!O=}iªúŒ;íD,“¥Ä¾Ptp@8'·Ò§K˜$y9£fï…`Jý}+.th&X9È’Ey•‰ äcŽÿ¥U·ðýÂÙInèDÉ ‰eiAI`HÀÇ9¦Ójö ,(n¢"mÛ8ÚJã#>¼Ž)ÒêPA¨‹I"-˜¬î'v03Þª<7mugvºz'’*p˜¾´ÝRÆâkç–+H®RKSäç·Ò€5Lð®ìʃa ÙaÁ=¦Kyk ¢)®aŽB2œ¥a­¦u‹k8¦Y‘#®Îy ùIÿ{#ò«:†•-Ô×Î"üï'Ë-á9?JÔvÆßíâ/#þzo>”åš&Ù¶T>`ܘaóQëXóis¬òKH‹z.À6Ÿ`rsÏ¥6-6ò×ì÷ÁºÉ35ºÈ"ÉØÇ™  qwlÒG¸ˆ¼ƒ(¡ÆXzÞÄ2ÈñÇ4o$}U+õ«OÓ/,ä³Ä#+%Ä…Õ•€ ë‘ØŽ)ú“-Œên#}ð£"Ì%R® ÏÝ<õç½nÒRÒR[ûJÇ$}¶Ûƒ´þõx>jY.!‰Ñ$š4y8Ef·ÓÖ± Ñ$H­ÄBY-f‰óƒó3¿Ö›.‘xahüˆfiíc„Èî3 (äûŽüwÄoâ³* ¬²Ã‚z¯"š—vÏæl¸‰¼¯õ˜pv}}+"ãN¼ûDÑÇË ×Ìe2WfÜ‚<ííëP¶‘{&Ÿsh‘ˆ`Ê41<ŠIÃî#p¾hy.!’=&¢Æ|ÀÀ®>µ¿³+ ¸á˜>cè9æ³Æ›!Ñ/`H^9®w’H­– äp:TzÞ{uÁn¡0ìÚŒ‰‡õ9¥hj” º4¬Ê«ðå‚çÙ©¢¹ŽFeÈV2,2Ûz‘ƒX×Z]ÛM:¥¼R‹‰¡—Ï.G³nAÏ?ÂqZ“û>ò Öæ8VVK©¤ò÷…,Ž0'ŒûP¨»¶/ ˆwÉÊ.ñ–úzÒP· 2sϯ‹c¦^ÚMfÑÀÕUnȬ¥A'둞­¯ùˆÛÿºÿÒ€Õ- ’#‡ˆÆ!2FTHÏZ–ÊöÞô?”¬1¹] °¡Áìk1¬ï/…êÝÛ”–hÞ8ä.¥#^ÀsÏš¹§Áro'¼º‰ag"XÕ÷p¹$çêhCjÿt~UZbÑÜ8…ˆ\ã'#ŒÕª£{Ÿ;å]Ì"%Wq\œŽâ€!Íð³¹[ã ‡atx†6Ÿîàúv=ý©5õÿ×Ý¿þŽJ¯Ã\Û\1µšT+™Xä¶9g§¿~ÕcWÿQý}Áÿ£’€<ËÆò3ß¼¿ú¢ÈÏ}þòÿè"Šô-;ýf‘ÿ`ÖÿÚ5¯YwúÍ#þÁ­ÿ´k^€ (¨`K™âóh@2q‚G]ÞÔ5Eˆ`äV*Hðªo®i±ÈѵÚRA=G^ÜâUIu8„-$ê` mÙéÏNôȵ[i..¡rckf!Ë09ÏNôÀ½š+*mvÖ)íx>Ï0|ÈAਦ=êåÅý­´Ï4ʱH@FîÈÈÆ:ñ@hªvº¥ã”·¹I.þ==i#Õl%ŠY#º’!—#°õú{ÐÚ*¤ú³2Í:«)ŽIÉŽ>€Ò˨ÙÃ$qËpŠòTCÓéøÐª*½Ííµ£¢O(F“î¯RM]BѮͪΆqÆÌ÷Æqõö¤ª+2ßY·þ϶¸¼–8pH\ú?/z´o­…Ò[y Ìà0P àô4À³P=Ô(åKG\)8üªz« âÚY'îÞY%¸‘c¹r@*wÛ!õûá¿Â¶Cêÿ÷Ã…1µØ|´hí瑊³:*ŒÆá³ÏcéZQȲƒ!Ê8 ¨4Cíú¿ýðßáN1°o ô!øUúÌxîçµ·[k¡nª¡‹ÜÌGAÏõï@¤‹&v“‘Ô‚)=Ì®£§Fæeó6ùžPÝ·¦sÚ¤ boùùûåÂŒMÿ?/ÿ|¯øSè boùùûå˜л¾öɧåSQ@}Ÿw+²÷þ•«Í´Gþž­ÿôrUÚ¥ªÿÇ´_õõoÿ£’€<ÏÆò3ß¼¿ú¢ÈÏ}þòÿè"Šô-;ýf‘ÿ`ÖÿÚ5¯YwúÍ#þÁ­ÿ´k^€ Šq^Z¤,$#É'¦ÓëRÑ@ YCÛ¹˜± rãY¶ú\±KlæHÏ•q4§ä8lÇ^FkVŠ@ssèÏcªÜDȈʙ]Nì0}*ìú]Ì¢þ$"Þé¼ÀÇ;•°ÆãÖµè¦zÛ^M{mstmÕ¡Y¬LÄÀÔJŽ 2Xìô¨L‘–²ug#8l+8÷­J(¸XÅ]CÉ*Ar¬W9Ä„‘Ž;fè×WH·S@¬-~ˈc î9ÿtp=ù­º)….•1ši§Ú$d(Rg_/j‘¸0\瞘Æ)dÑ&{¡4¯È’8Ò2I#É^¬ðsèk^I„l+»¨¹8¦ý ÿϽÇýû4À¯qkrº’ÞY˜I1yN“8ÎròªÑéW „|z¥¬—&.[,ªÛÖeêèH¦bÔC$Œ&S*4m–éÇ^j¬~Ž). <*²ï!Ö&BÙé&{gÒ’×ÃÂqçD¥ä‰ÿuÁòôÜy>´ /J`T˜ÊT3(Œü€ôÝéøÕ}V]BÞ”2\´eÈ(T0©=GJœÙLš„—6÷*‰6ß66vqèr1ÇÖ£³ÒþÊÖGÎßöX^/»Ûˆ9ëÆ1@G©Ã(œÅî!b¬V"rAÁךõ«EŠ'góK€©~öGlS&ÑüÍ>K_<|÷ >Y2§-»iävëIa£ 6·a2Ÿ$Ìv¤[W÷˜à ð(Iu»(°w‘YBÑ¡`ªÝ #¦jHõ;i.þ̬û‹2(v³ª¡#ò¬["êÞefÒÈ$Ž8åcØvž»·|¼}kJÏEŠÏP{„û;+;H3n<À[“óç¦O¥©¡ #P”¨ÉòF¯&“MÔZö[ˆž$F„€LrùŠIíœGqDAü¡HV0Œ3ŽM-„–÷S\Ï2I,ªùqykžÙ9<õ  ÔQEP¹$½Â-À·g œduÎ3Þ¢…D,ìÜ(•6mÎáÁ=þ´û¿;Ìœ[º¤¸R¥†G~ C]4H×›F•–‡!áÆ{ýhíE r\<ÇÏdû@ =ïõ©j4Ybi r ÛˆhÉÁÀ£Ò€$²FÎ_nÒ séô¬›^xïocUD‚ÑF]£f• Ôp:ôëZè¬ÞG Ïò®Ð1ŸsëTgÒüèµó±öÒvýÌ(_^z{P¿µívÎÇÌ mwòÎÒÙ÷9#ŠX´rT³£(rÊèT®Ð =5º2M§\YÉ.DÓ™ƒÈS¸0£Æ£“AI,ã‡|0ºK¼µ¼0ÊFvç¸$f€-.­m$jñ e Êq–;[¥R¼Ö#KhÊÑ9'RËÎå súñCxu|—E¸3‰drlÄer2Iü©SÃám#€\€ `m±àç9<`ýhb2Z$cÔ¨'ò§S"VHQƒ2¨€ÆqíO¡‚ (¢€ ¥ªÿÇ´_õõoÿ£’®Õ-Wþ=¢ÿ¯«ý”æ~0ÿ‘žûýåÿÐExÃþF{ï÷—ÿAP¡ißë4û·þÑ­zÈÓ¿Öiö oý£Z]Û[º¤÷DÍ÷C¸R~™  訣¸ŽIå…/Ýã3ÓùT´QQ\O¬ 4Ͷ4êiåÐIåî]änÛžqëŠu³GÌ®©Á#'®OéM–êmM˾! w±é@QPMw0Ë+È6C÷ÈçoùÍM@ EA8ß-¼D²9 ´àž¿…8ZØ´Í ¹2¨ÉA;néšsÄ’XŽ„1SùŠoÙãÿ¦¿÷ùÿƤþζô“þÿ?øÑýmé'ýþñ þÏý5ÿ¿Ïþ4}ž?úkÿŸüiÒ®‰6ùlÄyŒz÷÷5V e›uų*—‰ÉÞ¾½x>Çšµöhs¬Iîdoñ§,1£Uät%‰Çæiãµ-QEQEQEQEQEQEKUÿh¿ëêßÿG%]ªZ¯ü{Eÿ_Vÿú9(Ìüaÿ#=÷ûËÿ Š(ñ‡üŒ÷ßï/þ‚( BÓ¿Öiö oý£Tõ¸Ëjä³¼q½™MËmçdîéŒUÍ;ýf‘ÿ`ÖÿÚ5¯’;ÒÉ,z„6s"C-¼¶ð¡˜„†ÁäqœÕ˜-&ìâ’îêH·#I>îÐI98ç5ÒQšb±Ç\ «?ý8^4ï>J¨p¤ÿà8Î}kg_[˜§µº³ž_ž”gÇûÖÆO­ÌAgs³Zí”ǧ[ËäJs—.>\PÄTZŒsËlÉsöÆv·‡ìê…ö“»v:œÿzºÊ2}h¸Xæ/mÆ5¨ü»>c¹ïÚ˵yîç­ki±Iowyéš(c2±~£ æ´rh dÿ»?úèô¬»XjF-Ýnc¼šYe)€c;±ówÎTcÛÚµeFgŠD+º6Üt<ýiþ}×üñƒþÿ7ÿ@2ÝSϺÿž0ßæÿâ(óî¿çŒ÷ù¿øŠ[¢EÄxb§Ë~@Ïuªï!xdÄÅ€S‘´zSäûL²+”v©óXõ#ýŸjcE;©B!PÝHbL °>èúRÒRÐEPEPEPEPEPEPTµ_øö‹þ¾­ÿôrUÚ¥ªÿÇ´_õõoÿ£’€<ÏÆò3ß¼¿ú¢ÈÏ}þòÿè"Šô-;ýf‘ÿ`ÖÿÚ5­šÄ·b±i¬§iNAÿ¿5³:iöÊ ÂÛD§€Òm?SÖ€š3L‰l&šH£†x‚–1ÀnGoj›ì–¿óíýð(™¢ŸöK_ùö‡þøÄŠíÒ5 ›í94ú3QÆ–å&–åc!\‚Ò€8õéN™tûu&híÓ »”ǯê(Ù£4Û„±¶Ey`…U˜ >XêNj—ì–¿óíýð(”Tq­2/ ®BA€i`†ÛìQÍÑ,ïö)Ñüöþú}¢ùíýô*ÔR$±¬‘࣠ƒŽ¢’yRÞÞIœ|‘©fÀçf€+}¢ùíýô(ûDóÚ?ûèS翆 ;íάbØsƒñ«\z ª¬¬¹RõÃq82 ?ï dÿ/Û6ü¸\ñ붦º¾³ÓÄIq"B!:ã®(Ÿhƒþ{Gÿ} >Ñüöþú4wpMåXH²‚UÐex÷è*~=RûDóÚ?ûèQöˆ?ç´÷Щ¾Õ۾ǃæù^oN1œQÔr]ÍlªwªÌHãæÎ1ùPK4Np²#@œ»*sŠuðds‘È>†›ñÉá=¹4Ï´Aÿ=£ÿ¾…hƒþ{Gÿ} ³ðܲÀÊñ¶páÁÅIÇ   _hƒþ{Gÿ} >ÑüöþúwAQ,ñ<ò@¬ ‘€Ì¸èOäh0À®àA¢£ûD?óÚ?ûèTr€í@ÀÀê¿ãW<èVqo¹D¥ ï´qŸÖ€+ý¢ùíýô(ûDóÚ?ûèU˜&Šâ/2WBHÜ=AÁýA©8ôKíÏhÿï¡GÚ ÿžÑÿßB¦½ºŠÊÜÏ*’¡•~Q“–`£õ5?‚€)}¢ùíýô)É"IŽ­Cššiâ€Æ%`¦W™Xöý*+€Ô$ ¿JkM<ˆ§ÐœR}¢ùíýô(Kˆ-,d¹¸uŽ0ì]Ûýâô-¥í­ê±¶•$ÚpÀuQ@}¢ùíýô(ûDóÚ?ûèUÞ=z ¨’$™ØêØô9ªº¯ü{Eÿ_Vÿú9*ÝÈæîþSUÿh¿ëêßÿG%yŸŒ?äg¾ÿyôE0ÿ‘žûýåÿÐEÞCþ£Nÿ°Kÿí±®G3jv3F·{"†kU ˸ê¥Ef‚A¥¡8 ¥¸ÿÑ5©ºç¼qëæŸÒ€1.le¹–îñm¦7Aöy$\H0~o§½D-/dÔ.¤û+DÒÃp’lˆ*>~çÍŸ˜ŸÒº ×?óÊ/ûøøš7\ÿÏ(¿ïáÿâhM:sap––2ÛFm&L²‚@Ï #=óVRÊáõö¹œ\©3 "‘cÀù g*:äb¶w\ÿÏ(¿ïáÿâhÝsÿ<¢ÿ¿‡ÿ‰¢áa“œ‹ÃþÏþËUõ6–=SO¹Ky§Ž!()w•«Bd”H@2Œ¼ãŒQ›‘ü}ägô  Xì.¾Ôg’bŽspæ8ˆÝeP:q¸àž;ÔbÚàiKkýš¿góÆÑAr»~ù=sŸÆ·÷\ÿÏ(¿ïáÿâhÝsÿ<¢ÿ¿‡ÿ‰ oì˜m æŸ=Ô‹bb\ ²I»Œœü§ê{»HÅq$y 1ÓŸ3gߦIôï[»®ç”_÷ðÿñ4n¹ÿžQßÃÿÄÑp(éð}—G•œªÎX$±„ÙÓ€½…h¡ÅÔŸîæj'Yå]ޱªž¤9'ùSäY¾daNFcé@ì:D²ÛF·6ŒZ;9Bdr’ \zTÂÃPyü DT]y„ô›ËÛ·þúù¿ ÛÝsÿ<¢ÿ¿‡ÿ‰£uÏüò‹þþþ&€9»}*oìù#0Üùä¬ÑìêóÌæá. ’&½#YyîŠ(Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( 7Þ¢Š(ÿÙfotoxx-12.01.2/doc/images/unbend.png0000644000175000017500000003661111701011016015632 0ustar micomico‰PNG  IHDRά¼AÂsBITÛáOà IDATxœíw|TUÚÇŸsËô’6é B  "  »Šìbïbw-»Šºö»»*Š;(Š †*R¤Cè¡¥'3“)·ßó¼LR&É$Lâ¾Ë|?Qfî=sÎsïýÝÓÏsÇq™™™#F‡!‰byE—™™YXXøgã™};{õéÏ…¾ç8îÏ5(Æÿ*Û¶m€yqDzl´¢–½°ÔV»Øô; {¢™ð-LjO’Vbo.Qhdo‹éÔ|¯Ÿ\ki´nMT-ÙAÖû iøD˜æÒi|´õû€M®«–³šTEi&‚tL¡IÇ8ÞPÿXȾF—Oš»¿X÷l.|]TñVH´iõp™ RJ)EJ©ª[4ŠšF½Øðkí¿õsÀ¦Æ7¶¯a˜°9ZÓûPwQµákß—&lš7§æ¦‰6J±Q<µQ…Ïý›‹HØ<;­HmþO?UWW_wíµÇišVÿÔ²eËÖ®[÷ÆoVUV4ý!¥@Ã<Ÿï»ï¾{çÝïݳ»g¯…òfKvF¼•A¨Hrq©×+S²v§=#Éf$à2…Ê\ÄÚV‘Ú‰$K Ëçä¤ÚX€. ²H‰Ãfb¨^Yá-r Öø¸Œd‡…AÔµÊJï±*1˜ââíi #AÔµj_ðpI5åŒÎ8{F’ÕÈPÁ5}õªß>ý쳸ÿŸÏ>Ëó|sjC€Ðå… ¿JõÃ…úN4µ0ÌKT› Õ|VU•R”tJƒÁ WQ5] õt¸\.§3Žå8)Ô4këL5QaMÓ("eµÂ-z`xJ)H²Zá•IµÞ/mœI7@Jšk\r*oŒã¡B×)€$«ånÉ«B&0<€Ñb€ªªêb¯Ö…òPïù’:Ň’VµÔ-WËÆéžjI¨Ò ÃȘDWâ™CÒâ9@‘ã€%¨Uz‚U‚Q@DÂ23@Ÿ>9=€51 RÝÉÕ s¢mŽ ÛðuEIƒ;ÛäÕ¤Öæ¶fn­K —,Yr͵×VU”'$¹ÒÓÓ¯½öºþóŸÓ§?…ˆz@êÛUß܈ë›õDÖè§Mê­uŸUU¡TWdEUU¿ÏWW^BœNÇÎ;÷íÛç÷ûQälÝ€0ºªúâŒæŒxË>‰$;&€JŸH‰aXÎjŠRÔ°,k4™“m€"Ÿ(22€¥¤¤|Û!eyDÝç×ù`ò|¨´@¤bP09œv»©¶u[›7“¹kí#'„eyBáXLëÀœÔ,WmÜ/ǧŒëéTeÅãõAvÂè‘ýódÎ 麮QQ(Ø{äp¥Œ £©ªGãǵZinz·Ã67š<šÑá#oJ+R“eyÞ¼y÷Ýÿ@UeEBb’Ç]•šš:oÞ÷ã'L ”NŸ>¨ RÄúâh©ÞÖ¬˜Â‡ÇÆÇE¥”rÇóœÉd¬«›Íæ´´´ÂÂÂ{ï¿çÓO¾HÏlw媪†×/Ì5Ÿ3:ïTWo<âfrBQbm[tê]º¦_““nð{<뺃vÃ!5¾[vZZzš¨ƒêqÏYSè@²§îÑRÝÅ%‡zäôîÝ«7¨ˆªª×ÔÓ°6ß?ñ)T‘€hªðËà4ætIUÌ@Peïá#FsZ׸d¤¨Êò‘¢òÜ´ä!ºõ”PgHÅ¡£ßm*5Ú-­Ô~›kvµô›Ç£Ö,øãÍÍšµuËæÎ(¥‚ X­ÖÅù¿ŒŸ0±ÿþS¯¿!lnMYÞÐÚºíÐSøðµƒR:xÈŠŠro]=°Ûñqñn·gîœÒº ŠË.iH©G /“zº,<èjÁþârÝd¥ôW©ðÊ”0U•þƒª.PF–ÄÍGƒ‰䫽Õ;÷¹ÁÊÈêÒôp¥X9ÐÕª2/0œ,Kû=Ʋj™R^8 ¨22b@XúëÁ=““-¬®È~Ÿ¿BE²!µyÜþý ã–©Nõ^¥Ò#ë¥åAÞT€ÑƒÁcåêÑÒêÃbõôd«‘‚[‹½…^Õd¶–—y8xÌ`s^|N¶.)2EßñŠ|Qìß-!ÞÈ ¢–ùXÎд[³z {¨­mPÒµk×ÂÂÂò²Ò°Ã퉉‰y}úT{½õs/“É$ÂêÕ«'MšäñxýÊPó7—YlŽVìŽÒõ«î½½RÙY™5Õ^JuUÕV¯Y­“㺗T¤µMfDT$QUeD$ c0š9ÞˆT>–ãMf«, ª"›­v°’Ðu–5˜ÌgBtU•%A×5@`yÞd¶RJÅ ã F³UƒªªX¬†åtM•%A×4`Öd±1µdIPdÑd²²ôW³g4YeIÐ5Õls NEÁo0šXŽ—Ä`ÈxÂ0F³-§W· ýÍ 7ü¾{Sp›¦(Š$èTƒÑl4[Ãß·HÞä–r„у“r}ÕD,))NNN±Z­¢(6ê›\±lé”+¯nEj‹…eYAšök˜L&³ÙÜTg਋þ(³Ú/©™ ·Iç6ixI¤Q¸Æ·@ ªŽ¨’H¡¦H(¼Ý™`Mî¡!ÊÏ ^× ›|d9tÃï-T¦ÎK8Qÿn!f³!-‘7¥šâóú” ÄÏ0L8ã›O·ÁMhülÂŽò4ä¡Z©I’h2™Y–m*•ÔZ)@Ahî”$I’$…?WSix¬^­áD;°æŸ?õÿ«ý§ñùÞáHTÆ· QÑ5ªë¤þä’ÐP@R?dÃx›_©}.-é©Ù÷ªžžåëê=ÿØpTÑïÜUR¨ṵœÁ–º£'ìl8¢^Ó¦l4)ˆ@m×·¾ã×ÅLN„±Zm”ÒºZ;dfÖÕŽ›9©?—áD ¼å8k[éÂÄšÞ¯°Cx"XíW¬•UK¹Uã±ýú1ô; ouãjAãW®ö&ÿ4×}€õ¯«–7ZEBë_S¸\­Á¼ 'n@Ø™HMMjšõÕÑ‚ÈBtˆÔ\NÓ-ç÷ ;æZCä햨Ѷ$# }²Wñ'Ü…pé·dF«&ú«½¦Ö@j{öìõz½²ú#µS*büÏC›/ŽRRRzäæÖÕ²¨jü„ š¦uïÞMUÃwÌÆˆ!ÅÅÅC† YµjUx©uëÖmÍêUgÜŸa[Œÿ)~_¿îáG©¤qYyðàÁx½‘À1b„åàÁƒŽD4³#FŒ“'&µDLj1:‰˜Ôbt1©Åè$bR‹ÑIĤ£“ˆI-F'“ZŒN"&µDLj1:‰˜Ôbt1©5@SÄÊŠrQ†‰Ý™0èª"%`˜vÌGŒÝÐz ¶ïüÇ}jleõ²žöÆü-Î„ÄØ4Ϻìÿþ½é/¿÷“±]÷$&µúPoù¡õ¿ÿîæ-o&HlIl,{«…êò®M«6ì<ηk–uÌ«w .Þ™ÀrÀ™3ž|ë}™³V7ãØë„ˆ·ñ.¥}™|ì• *ì’™qÑ¿~ ¾mI®äÐ_n¿3–ŠF›C—}ó>x2tpÀ™“6”ƒÉj«.ÙsÞi½Bo|ákÁ˜ öÕýö…o~ç“\W”ý¥ÿëÁPZýϽÑ-mIr%îIr:-ß½<­G¯Á{}F;⪵gäÐA9=oñ,VóÆü'¹’¿+2jž‚. pë ßé .ŽeJ÷þzáèaI®äÔì>ï.>jKéÑ> cR C oj¼1­;ª^§Ù<³ K.íc|â±ç%ƒñ莅·þýý'~<‚è™æ{èÑ—4³9)³÷ê;qÇœ'–þû‰ßö—ó|^)FD|îæ ´ÚÛA$RyÝ¢Ù½úå‹‹Ž"bÁ꟨F'!’–ìœÓLV+ªUðR"â–üW»Å›×î;FXæÀæUý‡OùË@Û“÷?\PpQ94wÞëw>ÿÝ!«90ýѧ˘n{QØ71/Q„ó±´Y@–eœ«&@òÕãú/™]$S8¶#ŒÂ®wßÝgwËví˜dÿoË—î9Zc‰Ž¸ –ã¬ésß}at¿¬ANÁíWHß>#cuµÂuÉ8 ûrÆ?H³¡Ù2^òò#“þui›ÕÚ5oè»Kw²fû—ß’k rÆÅ÷¼ªÐÇ$¹’°9'zQ·œ5 {õ7~ëŽ ú÷êuÍÝO{ã†|ñÆm«_ŸÚ;«Ë]oýhèqŽÃ õíAD´÷{þæ÷”\ÿÚSÆ=»¯«¸ix²Ù7áêû¶ûÁäìvïßÿ6:K¹fTß§š³Ñ×ÿŒs ©“HŒ¬ï‰hô¹c>ûô“Svq!À³`åYZd;Òjc¼IªàYK€5Ñk™šÒu*PU²™M¡2%ÈuŽg” ÕM P°¬Éê”u UÎâçmDð´êÒâä,'Kl&VQ¨B ål„Ñ쬬«(h`0šˆÑ¬I¢.WÛxk5oc®ë„x“®q‰ª‘S¿¿éYMÓŽ>¼dÉâ«®¾Æl¶B°åµ-§¤Ôdùç•›xà¡Yíœz!›Pp8œaÏÆÅÅ[m¶E?/8pP›äB)-,߇Î|çwn¼ñÆ™3g¾þúk,Ë2 ¡”6»se+öGÑÀ–é˜RZ\\Ÿ"+”"ÒŽÌÕ1^sÝhÁ_¶â8eµÀÞ][{œrZwåò ¯ÞCóÄ-sŸ|ëÞ‹f­©°ÛqÝï;Ǽº·üò>qWO¸ô7""ž¯€b2-œ5ã©·æ¾»ª×|÷oFå._ˆ[¾~âû—î^¼£ÈdíÀ*g4ØX½Ì#€ÁJXCiØfC42›:*+Ë=wØ?Y–ÈI—+îýëΌនjP=Åžh®š‘%Ñ]UÙÜ%D:,Öž œyã&özïÃO—Nœêܼ½døc7›/ÝqÜ3þ©«ÌŸ_u” îš±oëaîì”d‡YsÚ@Vƒš¬ú}¾CôE!*”ì{í“×åR9ήù<•{·m)üe õù³“Sƒºév R` !@Š$zÝT×V,[æp8ží×ÇñM×6· žh@jž£Juˆ'¯ßZ¨®ï)ؽcûv£1| fô˜±Ldý5í,›t¾Ë£S_øú½›GÞíVãÏ¿4G)Xjâ™sÞ—³‘êƒ/¼ù¼Ý¥`"芊¢DJ)ÐÚv Aj`U@QTUuÇòY“ïzsÀégÚ°ªÂëçÍ–K¦ª&ª¬Óld‰Ÿa» Ä"Q…¨U –»éæ[±áÎψ†ñüò¯'[X;Ss]Ü0 ¬¸ŠðŽDGÔî |Ú€ƒ(Åú®æBÝÎHaá¡Qí”E~è× ÿ¸ê‘gfõ¼äù3Œà‹Ï=£G–4öÆ/žŸj%‘ò&¡¼Þ¦„µ[ÌþÒÝö•%X|KY†°¶äþ}zÏzwþOË'Oìm¯*qïÛœ¯q Ÿ,ÍïæYzîè‡Õ`€0T ê9Ö¨÷i²TªÐs»¸RŠýÔ×Í[×V:ºtRôÅ%Åëׯ?pààUW^i±˜%Iš7ï†an¹õæ`0xò¢pö;(í­?X“{yö‚e›\ƒÆw ?ŒÔNTY®¨¬˜1ãµ1çž{Îès~ÿ¡ÂŸ^tÅ—gfd b‡6 1qä[×ôÚüÛÖÉ^À2öÞÏ?wŸñŒ.)i¹=zN}ðÅAÂ×ëÈ ŒyÈégä:|wí7éª; $6Î` Fó¸)7_2"uúÕcÎyægümöKáÇtï‘;äú=r‚+‰5çÜ=ºûÏ¿v¢?Cõ½{Ž¡ÆIú]80þè¦;KÎåTìvû÷ßÿÖ;oËŠòéìÙÏ¿ðÂà!ƒkû#NRn–>ï¿qïæwï:oÜ%»ÔnÓžœRZ´:;B]?éé×]ýÆM›ŠŠ‹Ÿš>ýè±£ÉÉÉX; íoÜ©ºùŽ7ç_üJ’ÃÕE¾ËSæ/˜Pê"kàm‰F¤lêìKªãºúý>6£ÿØÏ¾Qá“5..!Ù´oß^! 4ì>ýõ÷ïü»OÔXÒ²Ò KVŒ(ñŠ„åmqif‡Yékß..L&N®[-Ñ/,[µ{ƒ‘AM eÍ]‡{ˆ8hРW^yù†oš1ã5‡Ã±qÃï=zô(++ÃèÈïqþƒëξÁ#3ŽÄ8¾6Ñ(D €¡lñÆn`f̘±„©×]÷Ö›o0,ë÷û1ÂW¥ýRCON²D¯;4¥)(Qƒ5±k|hš&IEÞ”˜šHEQQEÎ`se%QEc’‹Q¼‚¦ñ¼593žaJ©èΔœDQýº®+¦¤4'IÁŽðHÀ²¬FYw@Â2Ã0'YO?PJ5Uпÿóæ]:yòÒüü®Ý»—Õ^ËI´"B[B¢íÄ‘“Œ³~ä”R¤T–¤®¿Þh4-X°à“?„ ×ë 0[>©.+›'ÚIDATEQêg3”¢$I–êן4G)­ Î)A£x¡±»(Y–›ú(8ÐÍbLKršm ZˆVS4'K"¥”  dee8p@ø‹Ž ©¡¶ø$f”ÝniVfÆ›o¼1aâD¤ú€¿›;'!>¢çH¡òè¦'îº~òä+_|ï»2™Dój)œ1räÒ¥K@×ÔÇ{ô®;ïÄоfQ[rLÉM°‰m²18§ÜòÀ‹ÿ˜–ÌIíóK€šwñâ%ë{9³!ì3ð\FbJ›ô.iñ§o¾øï9£®¼mËýÐ Woö”rJi¿~ýN:T’DA‚Á@Ï^½Ï:ûì`0%G Þ'ï¼cM!½jêE›|ôêÇ ¢8²[çHaò”)f³9ðK’Ä0Ìèsϵ;ì’$EÝ‘?%›Ò½×À™‹÷rq‰ Ã[/sz’+9·÷ ÷òw=ôÊ'o¹,äẇf|úñ[7Ýÿ +^OHL LÏêööÂcf£÷É;/yüý|ÕébÐ÷ïé÷„Ž$¹R¦¼ŠIt±,oázòj!ÃÇÝ^(?¼_’+9#»ÛkùûL΄Wº¶Œ\}ð›~ÛËÓ®üë´ÇM|öùˆjeŽRÑïó©Šr¤à÷ùü~ÕiT)øÿúþ¢ÍþüùäI×ÜÑ õs¿>ˆª#¤è÷ûüþ@È‘‚,+~ŸO–äq¤0öMˆøöýçÍxàšù;&®êü±“0ýª¿}ùúWî¸ø¹˜ìôëüõ}?{å.¥ô¨OÆnçÿ=ïÞ7¶×Ћ&]1øÉnøzå¡ßʰhó·s^¸õ¶G?1»l»¶í:ûî7DÄõßþýÝ¿]öz~q\bǯÿx#"îûcNªÕõó’•A¡êÓGÎ{áÚ³ö(œÙt’€XYèhƒ† @çèÁIG¶n<ùhëø!Øø/„ ¦©'¯‡ª}köÔ³€n½²8±âxU4AP] ü!ƒ›þDúªDVa'Œ³k75fâ ïw;Pà–í*ñ}U4?àÜ‹/¿cÙš +ó=_ÑÅi±ef€‘G)g0)HªçÛ×ï}tæ¦y•Þ<÷âÅÞññª³“:Æ~þÜ…÷Îühßó&;¬ÕéÙ À€s®¼vè—û6ìc'æ€ð*²Ï+IâñâãûìÙ£½T…œhxæ&¨†!TU§ÈDÓ‹hªòÝœoãâÂ/ÃF%PmâCP©Ú÷ÀýÏqó{ÿź«ªÌ®Üa=’—}1kÇ‘ª¢CÛ¿úaS×—v·²Š¦×^[hÙ`L´ñEÛ¶”W Ňö­_³4¹ï…k¶oÛœÿ|Š#Q•€aYE•=*2l»ë%æÄÜ‘yéë¿ÿzöm^¶î€pæ%#ÚU8ŠŽ_0ÿ§wß~çØ‘ÃåeÇýèÙ³f}$@àäE×clžË8û‹­¾@Iþ¯[ûž•wò–Ÿ@•åâ¢ãÏ<óÌ’Åùþjoiqцß׿üòK»vîpWV`‡:R Œcø3¦›ûÂøQ£yav¿ ï¿éÊ3HЧ7n½Óýù3ï(*Ý·hܸqO¹qÞøø3'Un¼n¨knyŒÍ™øÄswZ¤*M?ñÃZµ&_3åÜâÅï^4ú¬'ßüaÜÕטªþ3âÌaç?­›\3$¤ôÚÕñÓ[/ìÙö÷wS§ÞqSWy×ÍûÐs³/xôãëºD}ÏfÏþð£Yªª~;gÎô§ŸÉÌÌ<á.ó$åfëÿŸoY;ãÖ‹/¾v³Ïuëã%@´)ÀÍ7ß²cçÎ’²²çž{~Ë–­qqq„a"ïìh½eMYß-XèËN üýF½ÿÙ0&9Ãû\pÛ’>ã–ø¬ é]{÷¶²š$º~^¼8ã ü ç¼öþée“HåŽÍ“2•% Y[jvnZæO?í½÷p9]ûq9 Xe˜þæÞ¸Ìq™ÿúðË`ÂÀ qù½ËGL.òJæ¤ny¹qƒzŽ;RégxcbjÏÐù¤¾³¾™sDqÄQIÓµöÞKÖÖó¼÷?ê¿÷hçHëž•ÔÞxš‡ 6}úSÓî½ïÕ3Ìfó‚Ÿæ1¢¬¬ŒÒˆ=ɶ„aÀ”Ç~qE‰RºõLŒª¿‘:G wß}7"œyÖÙñññ&Œãµ×lv»Ïç‹\ÐÔÕˆ%%o`‚*J’ÄšãÓÒUUVdÅGHRNßô^D*Š~!(˜Sû RÕ $I„ðŽÔœx–¥ÔîÊ2‡:&AE_µdNÎ9=«7!D’„€[B0$tí ŠaM ÝûÅQU%–ud÷IíÆqº¦ ¢˜Þk`v_Žè”úýÕr¶ÌÞýF„v;XÀО=µWßÔúÛ[“ØB«Ûu}䈟̚uñ%—,þå—!C‡–•×.îŠ#>>«g|Ã'm]!£aéâÅn·;ì! Çs#GŽÔ4­­ŽrºuEiåÊlÚÑÝh¡ŸÏGuý·ß~!Œ’a‰‹:l˜×ãŽI- ,˦¤¤M™rÅáÃ…šªuÜ$ž‘#Ïðü™á'|ó<Ÿ”ä2›Ím­q†ö=}ĈœœœŠÊ ¤‘:Ók+f³Ùf·Kb‡!;L&SfFf0ÔbŽ‚ˆŠ"Ævè|OJi*¤5k¥ªª6mZµ ÖVÒÓÒÓ³ºdwÐr/¨ë±oþ4¥4ŒHgpjJ Q–å?ÝÁÉT³t]oÓ†µBhU`Çí[ð?CçLûîPþ]©Øñ§“ZŒN"&µDLj1:‰˜Ôbt1©Åè$bR‹ÑIĤ£“ˆI-F'“ZŒN"ÌÀ"î)Øý_îs%Æ3½óú4=Fj„Ó† ÿ“Çqcü&ì¾á‡ÛEAì ÷°1NYÂKÒèïðã'Ö,ˆÑIĤ£“ˆI-F'“ZŒN┞ðÝt]§šŽ©ûvCaY6’í›tM×u:Þ¤¦Dn$ĤÖ&TU9røÈ¦MÝUnžç;.!Bˆ3Î9|Øðn¹ÝI³«DTU>pààúß×K¢ÈuðŽa<}øé9Ý»µdd-1©E ÕiáÁÂmÛ·^7uªÃßúN·»rö§ŸêTïÝ;O­Ù­¢1:Õ÷îÙ»c率y´£í ‹»ªò³O?Ñu­WóFÖ««E "=Txð¿^ÒíH1!!é²ÉS6lØÀ0¤¹ÅªHéž={nºñf¨uÔ™ bBbÒe“§lظ±#ëˆåjm@S5G\Do¿æ¹4‹O-/¿SUÕb·CÇûSjJÈȸøø` [reHh«žÎz®‘ì@Ej½üYcÖ4b7±ô¿˜ˆÔóg/9ަ×Èõ¨ÛÞ«3ÒjËŒ‡Î1IzŽ-IêÖ'Ɇ(/É•ìr¹zõþѲ£,ËDË$‹‘Ise°ÖöØ+@Û"R‡ÅÒs>°pûñqcÏ=v`¯%ûŒwç|4ÈJúdÆC¯|Ùµw_Á]ê\°î­Ï^íÅs5¦Û˜iBÉ×_þØwôM_¼1Í©]»§l_´vþws*$uÛ–ç=ôåçOL\üÍn{úÑc&¥ŠÝ‡žŸ¹åàE©ÜÎ_zðñ—*e>;+­‹·ËØá¶Üw÷³Ò“yëÞ~¾tv8ß‘‘š+@Û†®ë”RMS5MÓtJ©®È¢(†§gÆزðÀÓ¯|˜wõ³k~[¾òç÷»Âþ7^~Ãz¢xýwß,:Z ‘mv†¨ªª¦i‚÷x©»ºË¨q ëšXƒÐgôe_,XºxéÊyÓÏøê©‹ý ªc.½kî²_V¬YÔÏTõâ¿~¿þì“ %wîöÍ .|ã‘óW~õúüÕ{^ß°{Éòßn>Íúæ3¯@möÚ$¢ÖȈüøA,Wk+”R]×t]G]£”"`hÇ]×ý~ŸGTºÛä’å>íÆë¯•Kº`LŸWn=ªP»ÉÐd`탲âyA¿ÿXQ¹Å‘k7ð5DI¦€£ÅárÄ]òïyOŒÉ•üÕ&["käEI¢5ñÓˆêjXãÛhOÔ={Å‚¯=v×Ð$^Q@t\ý䳯¦só¯óïu/ºëÜ;VÔüˆR](2"!<€)Án9Z^\`WUUU’ºv>kåºBÃ0Œ-QÕ$MÕÔì|Œ”†âéÀ=¦Ne"RDD_å¾í;ÖþºèÅÇn½ðήxmó]@wô¿y|Þ7_ðùŠ?~üêýW>Û0î¶g³A‘Ôšú>¥H$¾~Tî'÷Ý´rOIyyéŽí›ýŠªkjhˆ1ÂŽxÔCá¹ÄŚtæÐ™?¬ø}ýªO>œ¹pùW¼•µ'a4D•„R§©¦‡*…®‰çŽX÷åË/¼ùí–]ÛW¬Ü1dâµVñÈkÏ~pÄؽmë±*®ª¼Ñ$<{þ(Q€`(žXnACá 2é]slúüû.ŠƒÎúË’Ã8® ƒMwÜóîLKòSך‘Ýû…ŸÝvV’ß³7¯w¯Š4§À,}òz[R¬Ö'f϶?öÄE§u7Mã§>öÊÛ§;‰Ú(ÂÂ0ôÀÁÚó/kÖä>óøÓ÷^q>a˜ÞCÇ?òü+ÿ:«×µ7=Ñý…[ޏ©O|ep¥eõVFbNn¾LW¸àÖG¿qÆ_÷ð]o”W¼ä﫾.ÿGmòõOžöòí®´îÓ\“—ßsи¯XÿÅ뻇¿Ò‹çeYŽ|;3Òµk×ÂÂÂò²R–eGŸ;æ³O?0`€×ëm÷Ãø_E×´_~Y4~ÂD»Ã¡È2çt¦Áö·^¯'T¬°çpœØnÖWí¥ˆqqñ¡0ÇÙlvðxÜËÚë… Š,‡> ‚ðÍW_Ýq犪…ÝDKSÕ¹sçÞzÛí¢$ÒÚ&“Él±6 Ø ?Âï÷Ùí‚YQâãÀëq†q:Olïè÷U[m6¦ÞzkzTXtRaw profile type iptcxœãò qV((ÊOËÌIåRc .c #K“ „CKÃd#s 3ÅÜÈÌÔÜØÌÒ<ÑÌ(dlfafhnd”« ÉÒ·ö—&Ãï>³iTXtXML:com.adobe.xmp 197 236 H\´ËIEND®B`‚fotoxx-12.01.2/doc/images/edit-caption-comments.jpg0000664000175000017500000002436611701011016020564 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 161 312 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀ‚ü"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmOgÓl™šÖ"Y­Ð’J ’qSGa¢Ë<°.›aæÅÊmP‡§Oz›Eÿÿ^‘è«jùšxa±ÿ’üѸé÷/þÁôîqŽF@͆‹öµµm‰˜¡}¢ÕÔñÅ%Ö›¦AeÒ´òKc›dÿ vŠQ#– -ò×[ÎYÛ³Ý}=Ôڙźÿ¿ý 8«±KDfýŸOÿ Nÿ€©þøìläE°`=-Sü*<Õ}Jb¶1€Hýï8úVÓŠŠ½ŒâÛeæÓ­TÚ€©6‹þG¦ÛJãÑ4öSÜ['øVU…ÎÙX°q˜ÝW99%HÑB†M6,@Óa›€ûqQ5±NéîgÇgc$¢%ÑôÝäãfOð§}‚Ïj‘£é§s[!9…hØ&ՈDޤŒ•ô¨à(¦ÕÈPLÎ zÕY_a]™¦ <#MÿÀTÿ •´ûe‹ÌmO êmSü)óŽýMÊ*á f¬][ÜItÒïa†ÝÆ)òÇA]êgyý4ßüOð¥[{`«£éÄž€Z§øVÄÐÆßt@;oÜpÁì;S$ Ð4¨‘Iç6€2ž§ô¥îö{¹˜¶vL²0ÑôÜG÷³lœ~”Ï'Oÿ F›ÿ€©þ£*6/ ñ !r„(éž´ëˆâ².1Œœ}âÔíÁwÜÌòtÿúi¿ø ŸáIäéÿôÓð?µ.V3 éåF<¸‘Ô…ÁÍ7K‰^Ì‚EgÁÛÇR{QhÚö Êû™¾NŸÿ@7ÿSü)ðÚYLû#ÑôÒqŸøöOð­+ee¼f(ØHÉÀÎ9§Ú(XЈcòÛ{àn Iòö~æB[ÙHÁSFÓ™@-Sü)óYÚÀ@—EÓ”ž™µOð©t·¥@ÁdxÈBN9©m­¥ŠR.4… ‰]² ªqŠ{ 6ÑCʰÿ F›ÿ€©þyVôÓð?µ6Æ—|¸üÅ·,ë€@o¥7‚a䯏…dWJÑì;˹—åXÐ#MÿÀTÿ <»úi¿ø Ÿá[˜ãbt#Û”úÒG st î®0€@ €h÷{½ÜÇòì?è¦ÿà*…8Ád\èÚpVè~Êœþ•©”¸Ûn€=ÎÂA c¥2u°*CºFî £wéE£Ø=îæg—aÿ@7ÿSü)ðçÉ4ht7 ÀZ§¯Ò­ê¨"p‹'^À~#¨ªV‡ý.úè¿Î©B-^ĹI;\ÕþÈÒŽq¥ØpqÿÉþå_à‚×Ä©´BŸfC¶$3–ç½ýÿè+Èþ)ÈÒŸõêŸÍ«˜Üô‹ û[=KK™B4–q•$rxúΟ«¤ÆòÕ¥üù@Nå]É®Gû§šr]Äò´Ir"}äW‡ÔPÁ«£žóí?çò?ûáÿøšQsn¹Ù¨lÏ]†UÏä+ZÛY¶¼‚ÞkYežMŸ)CÏ, Èéõ«kuÈñ­Â³§ßPù+õªÝI=ÈäG:×ÌÁžü9þkcóyö¿óùýðÿüMtPÝÅpÁp’…àìpØüª8žß nn™»`‚¹ö¡Th9çZÿÏä÷Ãÿñ4yÖ¿óùýðÿüMtë³}ۉʋ†û§¿^œS–ÚPË,̤d;GçOÚÈ=œN[εÿŸÈÿï‡ÿâhó­çò?ûáÿøšéž;T•b{—Y`[è3B¥£ÌХ˴‹÷\±#ê3Gµ{8œÜWVñJ²%ä[”äeÿ‰¤ií™ÙäYbIùÿ‰®”›¼»¶mƒ-¶åŽÑêy¨¬î4Ûèä{[בcfWÅÃq´àž½8ëÒk öhçüÛ_ùü‹þø“ÿ‰£ÍµÿŸÈ¿ï‰?øšé-ŵű¸Y'XòÃs\ Èb0qšvÛ3˜]·”Ný¥¶“õÍÖAìâs>m¯üþEÿ|IÿÄÑæÚÿÏä_÷ÄŸüMu1Á¨$Ši]£,ìAüsNû$ߟþÿ?øÑídÎ')æÚÿÏä_÷ÄŸüM'™kÿ?‘ßñ5Ö}’?ïÏÿŸühû$ߟþÿ?øÑídÎ''æZÿÏä_÷ÄŸüMe¯üþEÿ|IÿÄ×YöHÿ¿?ýþñ£ì‘ÿ~ûüÿãGµ{8œŸ™kÿ?‘ßñ4y–ßóùýñ'ÿ]gÙ#þüÿ÷ùÿƲGýùÿïóÿ?m öq9/2Ûþ"ÿ¾$ÿâhßmÿ?±ßñ5Öý’?ïÏÿŸühû$ߟþÿ?øÑí¤Î'%¾Ûþbÿ¾$ÿâhßmÿ?±ßñ5Öý’?ïÏÿŸühû$ߟþÿ?øÑí¤/g‘ßmÿ?±ßñ5$ZÇíÿh—v1œ&qÿ|ÓÞHXÄò²«Édû-WŽÒk}jæY4ñt·2#¥ÆäýÐ Ç<HÆzöªI§jm­Û\IÓ»ºùJžY 1ó“ÈÎZ×Ùýé?ï´ÿâhÙýé?ï´ÿâh@`øbÒybÓek6ë6ùw/ï·1p9÷9ô«¥C=Œw°É§¹ýü²£!«9`£,<ãœz°#¾xÓÿ‰¥Ùýé?ï´ÿâhdGc}7‡î,›Ox_í-:¤ÙTÌ_gÊÇñÍI¹œ™ZÉaŠ]BþÌYO–Š,pq’Fp3Zû/ÿ½'ýöŸüM/ÿ½'ýöŸüM @Fµ–Ò+¨å@Š×Rܲœ,ú^uñWþFÕÿ¯eÿК€;ý+ýv‡ÿ`wÿÛzݬ-+ýv‡ÿ`wÿÛzf«öy|E ¶­7—bm‹Â­!$—pÎH#$/AîMtW)}©Ëj×+c0ÙÃZÁ€ÿjΈ䑞ӜӮîõG¾œÅ¨Ék ¨ˆCWUÉÉÜ wãÚ€:š+–KÝJå­lÆ ñ?Ú.¢yÒ$Ý ˆ¤‚³ùTPêú¬y¸iþ×$Úc]ª4J¡06õ÷Éã­uÔwÅrPßjòAE \]CÏŠGPÀî ½†23×­%­ÌóëvŸlÔš‡í0y€"‰öȸFHôÁôÅ ub_j7ö—K “[ª1,þle‰&HÐccï“øQ¡^ÜK}uk{tf¸Qæ› A76•ö!¹­{[[y„4(ì$ \2óþ»”úýݵ´S\$N&ŠDŒ"‘ºtbõèàíƒ] Qbà«Lo(0 cœJ§q¥Ç=ũ܉mlþj±Ždç?‰8Ç^õ¡L ¤»¼¹Õ®aŠ[xaµdVWBÍ&FsœŒÃTÓX½7K!ò ¼—Ïf! |ÅÛ»æ'<ýÜãZØ–ÆÒk„¸–Ú'™>ë•äTé¤Ï<Ößd–î3¶fŒ«:˜ltãþyÃÿøQö‹ùçýü?áEá‘g¨ÚOU‚ßQII@Ñ/žîÃÛÎxôíU-çÔ ²Cm<÷i^~%;¿z1‚n½t_h¸ÿžpÿßÃþ}¢ãþyÃÿøR/ÃsÉ4³ÄÁ.£¹Q+JÈÝòJŒgû½½ªß‰m¾ÕáëøÀ·åV6 ±Úxã¯Ò¬ý¢ãþyÃÿøQçÜÏ8ïáÿ oPZ·Vë§éÆßP‘tç‹‹„œ±_—€_£8§\ÞÎml¥{qmhâlÎÆr÷[Ž;®O¹Åt_h¸ÿžpÿßÃþ}¢ãþyÃÿøPØ$gø^K™mnd½\4ˆdpsäÇÔv5·Yðù°Ë<Š‘–öd8(^>_E/Ÿqÿ<áÿ¿‡ü(¸語}Çüó‡þþð£Ï¸ÿžpÿßÃþnŠ©çÜÏ8ïáÿ <ûùçýü?á@語}Çüó‡þþð£Ï¸ÿžpÿßÃþnŠ©çÜÏ8ïáÿ <ûùçýü?á@þ-ÿïýzOÿ¢Ú¼Ëâ¯ü«ÿ^Ëÿ¡5zO‰ZY|=¨´‹„´˜ü¬Ns•æßäm_úö_ý ¨¿Ò¹›Cäø“¿Oûw­½¿í¿éþ‰¥®Ðÿìÿûo[´Ý¿í¿éþmÿmÿOð§QHcvÿ¶ÿ§øQ·ý·ý?ÂE7oûoú…ÛÓü)ÔPvÿ¶ÿ§øQ·ý·ý?ÂE7oûoú…ÛÓü)ÔPvÿ¶ÿ§øQ·ý·ý?ÂE7oûoú…ÛÓü)ÔPvÿ¶ÿ§øQ·ý·ý?ÂE7oûoú…ÛÓü)¤<·+ Èc '¨çëR}ÿçî_û嘆íÿmÿOð£oûoú…;ìoÿ?rÿß+þ}ÿçî_û倷ý·ý?¿í¿éþﱿüýËÿ|¯øTqïYe‰Û~Â0ØÆAí¿í¿éþmÿmÿOð¦ÊX¼Q#m2>ÝØÎ8'úTŸcùû—þù_ð íÿmÿOð£oûoú…;ìoÿ?rÿß+þ}ÿçî_û倷ý·ý?¿í¿éþﱿüýËÿ|¯øR=¤I[§Ü•qü¨;ÄCÕ>f?èsuÇ÷µy¯Å_ùWþ½—ÿBjôuüß jcìdlzf3^oñWþFÕÿ¯eÿК€;ý+ýv‡ÿ`wÿÛzݬ-+ýv‡ÿ`wÿÛzÝ Š(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(‘œ_ƒÿLþ„+ßÄ-'‰FnI³–f´Hvp¤$ÝŽí•ëé[R:EvF ­\“œŠ‡ÊÓ>Ä–_¹û™VÌŠ©wg¤^Ü îR˜ oYJ= R2=!•Lj¦þØ6ȱÍjâeŽE‰×ä‚ÇånAtªëâ]BXÞê Y%¹·Žk,²ª—uL>sÀ,G¿},thîÚé#…emÝ%;Fá†!s€Hê@§µ¶ñž;vE‡È Í‘åñòõöôWRÖuKíìR'¼xÞVhá‘“ @ $‚sÔœ —DæÔõyeâvò ‰ŽJÈüèm?Ex#…• ÄK!7½Ië‡Ý»ÙÅYO°C,³ÄbYd@ŽÊù,§ä^´\,TÕÿäM½ÿ°{ÿè³^uñWþFÕÿ¯eÿК½YRž¾V+a #þÙšóŸŠ¿ò6¯ý{/þ„Ôßé_ë´?û¿þÛÖíaXÃyö]îÒ(%é¢&Y%1ýáaO÷çW¼Ý_þ|,ÿð1¿øÝ_¢¨yº¿üøYÿàcñº<Ý_þ|,ÿð1¿øÝ!—èªn¯ÿ>øßün7WÿŸ ?ü oþ7@èªn¯ÿ>øßün7WÿŸ ?ü oþ7@èªn¯ÿ>øßün7WÿŸ ?ü oþ7@èªn¯ÿ>øßün7WÿŸ ?ü oþ7@èªn¯ÿ>øßün7WÿŸ ?ü oþ7@èªn¯ÿ>øßün7WÿŸ ?ü oþ7@èªn¯ÿ>øßün7WÿŸ ?ü oþ7@ˆ`€G¸¤ØŸÜOûäU/7WÿŸ ?ü oþ7G›«ÿÏ…Ÿþ7ÿ  »û‰ÿ|Š6'÷þùKÍÕÿçÂÏÿÿÑæêÿóágÿÿÆèîÄþâß"œ=ª‡›«ÿÏ…Ÿþ7ÿ£ÍÕÿçÂÏÿÿÐóÈÁ݉ýÄÿ¾ERóuùð³ÿÀÆÿãtyº¿üøYÿàcñº»±?¸Ÿ÷È£bq?ï‘T¼Ý_þ|,ÿð1¿øÝn¯ÿ>øßün€.ìOî'ýò(€ä"þB©yº¿üøYÿàcñº<Ý_þ|lÿð1¿øÝ3Äyÿ„oTëÿröÿa«Í~*ÿÈÚ¿õì¿úW¡ê0j׺eÕ˜³±Cq Dí$íÊ‘Ÿõ~ÿç5ç|X¤w¶_ý ©ˆæ†¯ª"ª&¥xª vÐi¶uoú ^ÿàCÿRlêßô½ÿÀ‡ÿ?¶uoú ^ÿàCÿPý³«ÐR÷ÿühþÙÕ¿è){ÿþ4Q@öέÿAKßüñ£ûgVÿ ¥ïþ?øÑEÛ:·ý/ð!ÿÆí[þ‚—¿øÿãElêßô½ÿÀ‡ÿ?¶uoú ^ÿàCÿPý³«ÐR÷ÿühþÙÕ¿è){ÿþ4Q@öέÿAKßüñ£ûgVÿ ¥ïþ?øÑEÛ:·ý/ð!ÿÆí[þ‚—¿øÿãElêßô½ÿÀ‡ÿ?¶uoú ^ÿàCÿPý³«ÐR÷ÿühþÙÕ¿è){ÿþ4Q@öέÿAKßüñ£ûgVÿ ¥ïþ?øÑEÛ:·ý/ð!ÿÆí[þ‚—¿øÿãElêßô½ÿÀ‡ÿ?¶uoú ^ÿàCÿPý³«ÐR÷ÿühþÙÕ¿è){ÿþ4Q@öέÿAKßüñª·7WR .§–g¤rÇ™4QLGÿÙfotoxx-12.01.2/doc/images/smart-erase.jpg0000664000175000017500000003170311701011016016575 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿá 4http://ns.adobe.com/xap/1.0/ 227 250 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀãú"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑ´2MOy4Û7v¶‰™šÝ $ É'lé@`§M° ÝÙÓ'ô¥Ðÿä¦ÿפ_ú©¯-#¼ˆ+GCº9ï#zóÍCý¥Ð.Çÿ“ü)HÒ;tÛ´àâÝ8?•S]Fêæàéa’;ÄÏ›:T(Ç*?¼r8=;çŒë[[Eià íE÷É'¹'¹>´VM'GŠ6’M7OD@Y™­ÐRN*–ï Ôò†®ëßòÔëÖ_ýÕøCtùðÿÈÒñT$xfæUŠÞ-Y¢"DÄ÷è*ÓèúR£7öU‰ÀÏü{'øVhðþ™¥jšdö6ÞT;!o1›*CŽIô½7ú™?Ý?Ê„OØôŸúØÿß„ÿâhû•ÿ@{ûðŸüM.i3[ò#.fcÒècÿ~ÿ‰£ìšOýìïÂñ4fŒÑȃ™‡Ù4ŸúØÿß„ÿâi>ɤÿÐÇþü'ÿP&“,éæ‹É{1Æ_˜ŒpÃÒ•ô™`O8ÞÈÛN2üüÀc–4­O¸^dßdÒ¿ècÿ~ÿ‰£ìšWý¬ïÂñ5zÆE:«ªLO‡QG‘¾Yšë*PvcšVöÙGìºWý¬ïÂñ4}—Jÿ 5ýøOþ&´ ”ìY{&õÎ1ŠŽÒÕ',%œnm§h…äSû.•ÿ@kûðŸüMeÒ¿è cÿ~ÿ‰«QÛıJó³áoÉŠ{Ÿ8~Km+ŒŸ­`¼Š?eÒ¿è cÿ~ÿ‰£ìÚWý¬ïÂñ5oK?éðN¹id1Ç%ÄR+7ðqG,ok ™Úå/³i?ô±ÿ¿ ÿÄÑöm'þ€Ö?÷á?øšµ4%žk0l7OÒqd‘¬l¥Ð3m"Ld{ñG,Bò)ý›Iÿ 5ýøOþ&³i_ô±ÿ¿ ÿÄÕ«›DŽDŠ1.æle±´ý*IôõŽe/¹Ila¾”Zy>Ï¥ÐÇþü'ÿGÙôŸúXÿß„ÿâi¹£5~Î"çc¾Ï¤ÿÐÇþü'ÿVàÒ´©¢Y?²¬F{}?¨浬ÿãÎ/÷‡þ…YÔŠKB¡&Þ¤_ØÚWýìð?¼ƒRUMNíBªÌà0ÜkÛkÄõ_ù ^×wÿÐdhzö‡ÿ 7þ½"ÿÐKz·R"ÅjD{ÎSÕØw>¿•gÙÝMm¡h©o K$ðÅ!@?r[9ÿwÓ½Zóuoùò²ÿÀÇÿãTçÒíÍš[Æ/,îŽE?:·÷³Üúç®NjkCp`íPJ§ðÞãÓ>•_ÍÕ¿çÊËÿÿQæêßóåeÿÿƨMZ.t‹Ø!]ÒK¢.q’T€*?·ÜÿÐ"÷þû‡ÿŽQæêßóåeÿÿƨóuoùò²ÿÀÇÿãTuw{bNqC1‘ÞFyn¿ÂäõaÚ´gÿQ'û§ùU?7VÿŸ+/ü þ5HÒj¬¥M‘`ÿ¦?ÿ¡S4f¥ò/ÿèeÿ²ñº<‹ïúYàlŸün¶öˆË‘‘f“57‘}ÿ@ë/ü “ÿÑä_Ð:Ëÿdÿãtý¢F^aXÌ!¶“Ï™Œä“éïK=ãM F! ¸Ž|Ìô ú{Ryßô²ÿÀÙ?øÝE÷ý¬¿ð6Oþ7QxiÅm’Ýd9È9ÅH÷ìþvä¼P£îÔg¾ÿ u—þÉÿÆèû=÷ý¬¿ð6Oþ7UÏrÈ‘oöËùq6cw_z!¾TŽ5xC˜ÎTîÆ*/³ßÐ:Ëÿdÿãt}žûþÖ_ø'ÿ¥ÏÁË!^ït2dzýcïÎzRÇv¢ßÉ– *sŒS~Ï}ÿ@ë/ü “ÿÑö{ïúYàlŸünŸÍ{ÿ@Û/ü “ÿÑÏå‘W4f­}š÷þ¶_ø'ÿ£ì·¿ô ²ÿÀÙ?øÝWµˆ½›*æµìy²‹ýáÿ¡U²ÞÿÐ6ËÿdÿãuØÿün¢sRVEB-=Mñ=WþBןõÝÿô#^»åßÛÒÖîÚüÈžEh§/÷J‚(¿ßý+ȵ_ù ^×wÿÐdhz…§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤Ï[”QEQEPÖ¯.ltùg´·Y˜—l*€3“ÜýéIè5©~ŠŠÚC5¬R°täVuåÝùÖVÆÈÛ û?œZdfÏÍŒpF)Û[ j®kQXɯyQÉݳý®)ÖŠ 6æa•*N8#Ö¬Ýj†ÖÝg’Âð¡BïµT˜Àþ÷Íü³@V}ί /qE=Ô’Gæ„A!?¼r@•µ{uÑ×SÛ!”0P£qÉÀϽ_¢±›Äq!™d°¾V€˜×÷jz1Ãr:ôÏJ³u«Ã‘Ç3ÝHñù» PÄ'÷ŽH  *Œ:­´òY¬Eœ]£ÏWŠîÝî|‰á¶TóÒ€—Ô`“ùUn5¤šÊécŠæÚSlòÂÒ¨]à«‚}G“ÐkSjŠÉ]Ymímc1\]\5ºÊë †!q÷ŽHïøÔ­Û‘¶Š{·š?5R„õ9 mYØIÜÒ¢²­u9åÖ.íÖVŠ6@²(\&T»-ŸÈÕ Š( Š(  È~Ïþ½gÿÐâ¯"Õä-yÿ]ßÿB5ë³È~Ïþ½gÿÐâ¯"Õä-yÿ]ßÿB4êŸòðÏÒ?ý&zܬ;Oùxgéþ“=nPEPUµw»Ónmã*X™·@HÇ5fªÞÏwO²Y‹†9ÎéDaúRcA wP‹H—É0¤{eÎwd¿¯Z§yi~5•¾²Î>Ïä•™Ùqóg<š¹¦^®£aÒ#F$*ÝAõZóQºS[K8çsœYæòÀÆ>é¦÷ج4KñÏ$ÑÉr÷iq;Up €ª9è=iºÞ‹q¨]I*%­Â<Z­Ã0ò›Ÿ™pÏ?¥_mVwŠ ÏÝÝH»¼¨•¥ÀÎ:…éîqOþÔ´¢Í¤e˜ 4lgˆÁü _×a˜·¬tYá‘níV´X^)Ù—vÞ…p =ObßN¸¸ð}µ–sã$I‘Œy­8u;K‹¦¶†FyqmÈê7cüi°êö3Ý}š+€Ò’@ùH GP${.+îtÉ¥¹Ô¤VŒ-ժ™'†ºñÓæÓoíe†âÉ­Ú_³$¤Å‚ü½3Üñ[UÜ—úÖžLãkI°}sƒü©mý]Çý_q”º5ͤ:{YË—›÷ r«&þ[¦qÏJô[ÖÓü–†ÊIšY%Þeu136AF ž3íZÚ]ÿö…³ÈÑyO®íÃ#®qLÔµ ­.m-­­–ynKc|»Ú3×›>óA–[ˆ.Y-/¥[u†Qv§âƒÉíW¯tÖ¸ÐÍ”"(*í >E`AÇÓ"’ßZ„Áp÷‹öW·E"¿æ ·s‘Û5!Ö´ñköŸ<ù~g—þ­·oþîÜg?…+Íi©K-µè‹yô1ïc#cø±xªÆ—e-œâyZgÛ žÃÛTê–SZIt— äÅ‘#0+³ˆ<Šl:µ•ÄSI¬Â ¯–Á€=>R3úPlõÚÌ µ·¹£hm™KãÁô¤³Ð^;y¡’ÓN…šˆ\[©ÄŒdŒqùš·u®Û¦—5í¶fò]QÑ••”’ Œ÷ÏJж¹Žê,[ö“ž6Cù0•‚æÚò=µÄ–ö2¥ºÁ$Sä§ËÑ”à‘ôÅ[þλ´¹ŽçNKE&†H•A‚H*@>§ŒVÍî2á´¾·Õg¸ìÍ ÖÃ(f`ÈBàíã‘õÅ_µûGÙÓí~WŸü^Vvþ楢€ (¢€ (¢€(Mÿ!û?úõŸÿCм‹Uÿµçýwý×®Íÿ!û?úõŸÿCм‹UÿµçýwýШZÈ;Ã?Hÿô™ër°í?ä៤úLõ¹@Q@eë‚úHá‚Ò d†F>{Bê®Ð#¯¯¥jQHe+G™ÚÓšÞ¥X4‹û >èÀ'9ö5™«éí>·ÌšWö…¸·òñ”ù[vz1« ¢Ÿ[‹Èȱ¶˜jÉrlͬÐD²¤9ãå'µg¾Ÿ©Ë©BÓÅq!ŽóÍó~Ð<¡NLðqŽÞ¼×OESþ»…mky¬M½¼Ö¶ŽÎf*²9=$‚O=…WÒ4‰md¶†êÒáͳ“ý¬˜³ÎBÜž˜ï]-–€Ek$ÒÛ£ÜAäJ~ô{ÃmüGZ‹Q/öR‹doUþWˆ2ŒøÕª(¤AyanPZmŠ[Œ¤p?gŒ^üŒàzÓõ}:KíKNaæb2y¥r¼r=}+ZŠb9fÐîã³û:DÎm®üõM±îTƒÕÈqœdã¥%Ü ioi4v7 <—ñ±Žk#¹ @ù‰#õí]U2H£—o™¾ÆÜ»†vŸQïBž¸Ò¯u }Jgˆ[KrÑá2sû¾yeèO·N)E…çÙ.eµµº¶¼`ŠLמc:É ÅŽÞ3ƒÇZèè Y4›Ù,õ@¶óFÓ´O\N$f)‚AlŸOZÝ‚æîF‡ÌÓÚ}ÛËJ¤¦:p Îjå\Š( Š( Š( Š(  È~Ïþ½gÿÐâ¯"Õä-yÿ]ßÿB5ë³È~Ïþ½gÿÐâ¯"Õä-yÿ]ßÿB4êŸòðÏÒ?ý&zܬ;Oùxgéþ“=nPEPE!u ° Ý<šZ(¢Š(ª×e‹Û”M&Ö*pq‚¥UØG#FÆ÷*H8™»Àª”n'+tTé¶òF²,—8`Ìíßñ§ÿeAÿ=.ïûÿ+ »$¢£þʃþz\ÿß÷ÿìÇwo•£bCLÇWýÍC,QYñ]i’ê f>ñ¹‘ö;ª­œ;ð5rTËKßh'®0õ¤”QESQÒD+©èTäuQUåS5ä6å™Q•¶œŒqŸÆ€,QLþ˃û÷÷ýÿÆì¸?¿qÿßühôS?²àþýÇýÿñ£û.ïÜß÷ÿ}]láK©QšR‹°ÌÍÆKg¿°ªöW:müòC\^T³¸/÷“ó ñšÐ¢£·$Â7•f\úáˆþ•%P›þCöõë?þ‡y«ÿ!kÏúîÿú¯]›þCöõë?þ‡y«ÿ!kÏúîÿú P´ÿw†~‘ÿé3ÕM$Ô‘Hñ¸ „†0èEW´ÿw†~‘ÿé3Ö¦¡g¡g%¬ÌÊ’c%?ÒÑ…§Þ*ês ;«¦³†×ð¾#~«ÿ7LçµIkâ3x.<¹– o´+ŠŸØ~½¹V•æ“my9–]à¼M Nˆ{§jŽßE†)d’k‹‹¢ðùNTžœGõùˆÏG¿“]Òä¾û0¬«l®BðI<ýx©4}Aü­&†(ã¹IK*ƒòíSð1êžµn©Ýœ]Ãÿ\ßù¥ #X#XD ¢á0¤t gŠXçœàŒÉÐöù³¢³½[ ²_³ŒïEçÌcýÖnê?3ßßBÛ–œÿÓ_ý•hš“´zeÓ£e…È#¨85Íi·ÜinÇPŠ9×½Ô¾dr’¼å°Iät®ªâ¸·’ÎÙ¡Ç\ŠÎ·Ð¡…íÌ·wW+m*9]v¡á@ÉÖ’Ø£ ^I¦j¡|¹ã”±#‘´ñΤ]^þâh ·É$³Ï阌àpäýjÐÐmÖÞ¢žæ3³Ã"¸Ýîª8Æ>¹©-t[{Y-äYfw¤`ÎGÌ_ïü±Ov#AwmÈ-ŽqÓ5ÿ´õÊOæµ=@?ä-ýræ´‘$÷?fŸVSŠóÊXC~ï`p›vôÉëžµ±­Gs.žRÐJd.„ˆ¤ØÅCØ9ã=é¢[5јÉ0C(™ û²ÿÞÆ3ï×3Ø3Bñ­íÚɽ\\ÿÈ#oµ©,[Ȱý¤4r‘.]Ѱ8É'¶:VU°±ŠÆ7XÚIGß$’6YÛÔþB­Pñö¹•¢óU¢Eeã‘—ëšMÊJ²6cû‡äùxÇñÅ%ʇº™ 4(2§rý Q³¶¾K×—¾lq|±*¥‡«úŸÓ¿Ðý·0Ÿúé'þ†Õ-Ciþ£þÿú©©BoùÙÿ׬ÿúUäZ¯ü…¯?ë»ÿèF½voùÙÿ׬ÿúUäZ¯ü…¯?ë»ÿèF˜¡iÿ ï ý#ÿÒg­Êôÿw†~‘ÿé3ÖåQFG­Q‘ëFG­Q‘ëFG­2H’TÙ"†Z‡ì6þ’ÿßù?øª³‘ëFG­ ´Eo°ÛúKÿäÿâ¨û ¿¤¿÷þOþ*¬äzÑO™÷‘[ì6þ’ÿßù?øªU²·S$Î1“3ŸëV(¥v;"²Ãé'ýýñ©5 ƒv§Qš(£#ÖŒZ(£#ÖŒZ)’D’½sƒA ¡Š~EÙ£þüÿø'ÿGÙ£þüÿø'ÿSQ@ýš?ïÏÿñT}š?ïÏÿñU6G­´Ù!É'Í$ñ“3“üèû,>’ß×ÿ›#ÖŒZEPª@ ;RÑ‘ëEP›þCöõë?þ‡y«ÿ!kÏúîÿú¯]›þCöõë?þ‡y«ÿ!kÏúîÿú P´ÿw†~‘ÿé3ÖåaÚÈ;Ã?Hÿô™ër€"H’{¹U¨ŠB°ÈÉ'<~§û¯üûCÿ~ÅEÅäßî'ójÁ°Ô®­/ïeº™¥°{Ç„907à'8ö8õ ~gGö;_ùö‡þýŠ>Çkÿ>Ðÿß±\Ͷ»qo£iQ2\\ÆÌÒË“`)îæ'‘V­üC8û<—°,1IÛ‰FS½9nçrpFhzÜû¯üûCÿ~ÅcµÿŸhïØ¬m/\¹¾:|oi<ži¹\Ý„ãŽ{’:æ«x—T)x¶ðjÚ=¬i!¥ æ¶~Xù<‚ÈúPô©Ñ}Ž×þ}¡ÿ¿b±ÚÿÏ´?÷ìVUƯqpÚjé†/‘¤ß2– zÕMCÄWp^\Am ÈmB‡_³ÊæV ¨Âõïšè>Çkÿ>Ðÿß±P\CÀÐÆ±–}¬`‚¥dêž"’Êpbx^5Ùæ@`ºîÇW*žz[‡-mÿ]öV ÑETv¶ðÍI4I#—a—À @þU%TšFB»db®©1 9ni7eq¥wbïØíçÚûö(û¯üûCÿ~ÅsšTÏ™öæ‡T2Çheßsr^)ÜôÞzý*éÔ¯!Ò#¹»¹³ŽYö˜¶Àì9Û´6Xý*š°–¦·ØíçÚûö(û¯üûCÿ~Å`/ˆnäÒá"Œ:Ü´Jbr‘üe>ö:pzf¥½×¥‚+á’ ¦¹VsÐÿß±UÕÉ#ŒmMŠÛG@I#Ê©Zêwéyi¡¾ËÕc“œÆÀg'ž;Œ}*ûêÿ\—ùµT›þCöõë?þ‡y«ÿ!kÏúîÿú¯]›þCöõë?þ‡y«ÿ!kÏúîÿú P´ÿw†~‘ÿé3ÖåaÚÈ;Ã?Hÿô™ër€"Œâòo÷ùµA›l]ÀÁ¤ŽîF’E~yn {Tòýë´oŒeqÈüi¾D¿óõ'ýò¿áHe1¡Û%¥¼SOZ!™PzŽ˜9úSîôˆ/lbµº–i„nHÌ7“èHÁŽ*Ï‘/üýIÿ|¯øQäKÿ?Rß+þÄEm¦ÛÛj77±îón àcÓÓ=éöö0Á5ļÈ÷½Ëàã€tS¼‰çêOûåÂ"_ùú“þù_ð  ÖÚ=½¬–ïË‹v‘£RFþ£§AÚ–}*9/ê››Y$Iä°LtÈ óî1V<‰çêOûåÂ"_ùú“þù_ð  7zRÌßi¹‰'eib—k‘ŒHè:WîNd·ÿ®¿û+RyÿÏÔŸ÷Êÿ…*[áü¯!^›°1ùPÔQEY"[‹ `rBÈdBG\aVjnwÏ'$ ŸÄRJ-Ë·û9Ô¯dƒÊ1yncÆÒ1Ù3ÅOq¦C=­´>lÑ5±)c`HôÇOj›È—þ~¤ÿ¾Wü(ò%ÿŸ©?ï•ÿ b*Ťˆ-šoîãg”Êò‚›™\ü¸ÇáMþõ[kx¢’x^ܱŽdœûÜ‘ƒŸLUÏ"_ùú“þù_ð£È—þ~¤ÿ¾Wü(’F`Ó%‰¦’b#ožB \VWî¥@m™¸’y{©gòb€ †ëýZ×DÿÐ…MM‘D(Ý WÔ,"¿X÷¼‘InŽX›k!éÁúUa¢[KˆYäk†V–g`]ŠG8Æ8銹öy?çêOÉÂ"_ùú“þù_ð .´«[ɦ’}íçD±2çIw'­2ßG†)f’{‹‹¶–/%¼öSòzp­Zò%ÿŸ©?ï•ÿ <‰çêOûåÂlôˆm.#˜Ïq;D¥!>á=qÇêrjØ9¾“þ¹/ójO"_ùú“þù_ð§ÅŒ’Y›«50*Mÿ!û?úõŸÿCм‹Uÿµçýwý×®Íÿ!û?úõŸÿCм‹UÿµçýwýШZÈ;Ã?Hÿô™ër°í?ä៤úLõµ±?çšß"€E7bÏ4ÿ¾Eþy§ýò(ÔSv'üóOûäQ±?çšß"€E7bÏ4ÿ¾Eþy§ýò(ÔSv'üóOûäQ±?çšß"€E7bÏ4ÿ¾Eþy§ýò(ÔSv'üóOûäQ±?çšß"€E7bÏ4ÿ¾Eþy§ýò(ÔSv'üóOûäQ±?çšß"€E7bÏ4ÿ¾Eþy§ýò(ÔSv'üóOûäQ±?çšß"€E7bÏ4ÿ¾Eþy§ýò(ÔSv'üóOûäQ±?çšß"€E7bÏ4ÿ¾Eþy§ýò(ÔSv'üóOûäQ±?çšß"€)Mÿ!û?úõŸÿCм‹Uÿµçýwý×®Ê׬À²ÏÀþ8«Èµ_ù ^×wÿÐz…§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤Ï[”QEQEQEQEQEQEQEQEQEQES'“Ê‚I1ªN)õ çüyOÿ\ÛùP2Qhä ÷Rîï´.?•coùúŸÿÿâj¶·}qg ¿Ù<¯6{„‡2©e³ÎΡMVâÎ÷캿¡¢icž…!~ð ä‚=M/ý¿çêüwÿ‰£ìmÿ?Sÿã¿üMU³Öໞ8L4ª^2m¨êG?¡Á¨ìüCow,+ö{˜Rà‘ ²¨äg€A8èzã¥^ûÏÔÿøïÿQ¦øîrøPÁˆç=*‚ß^¶¸¸Š5ŠácŠÃ; ÈFx9ìzš°ÿòúä¿Í¨¤ßò³ÿ¯Yÿô8«Èµ_ù ^×wÿÐzìßò³ÿ¯Yÿô8«Èµ_ù ^×wÿÐz…§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤Ï[”QEQEQEQEQEQEQEQEQEQET7Ÿñå?ýsoåSS%A,Oà0"”õ»K‹È­þËåy°\$ÀJÅTíí U—H¹Ôä’]RX”ù QÁ’pÁbN2Z;®€ÁŽ6÷ÞF Q¾ëþxÇÿOøR…µ…ü—v’ßÉo¶ÍXGäç21rsÓŽÃ4ÈtyÓOÒíÝâ-i1’B ÁaÇ~aZ[î¿çŒ÷ôÿ…î¿çŒ÷ôÿ…=Åc#HÐN&Ö`†8b¿‘cB*í^¥?þÍsþ‚2ß+þQ@ü%šçýdÿ¾Wü(ÿ„³\ÿ ŒŸ÷Êÿ…Pÿ f¹ÿA?ï•ÿ ?á,×?è#'ýò¿áEÂY®ÐFOûåÂøK5ÏúÉÿ|¯øQEð–kŸô“þù_ð£þÍsþ‚2ß+þQ@ü%šçýdÿ¾Wü(ÿ„³\ÿ ŒŸ÷Êÿ…Pÿ f¹ÿA?ï•ÿ ?á,×?è#'ýò¿áEÂY®ÐFOûåÂøK5ÏúÉÿ|¯øQEð–kŸô“þù_ð£þÍsþ‚2ß+þQ@ü%šçýdÿ¾Wü(ÿ„³\ÿ ŒŸ÷Êÿ…Pÿ f¹ÿA?ï•ÿ ?á,×?è#'ýò¿áEÂY®ÐFOûåÂøK5ÏúÉÿ|¯øQEð–kŸô“þù_ð£þÍsþ‚2ß+þQ@ü%šçýdÿ¾Wü(ÿ„³\ÿ ŒŸ÷Êÿ…Pÿ f¹ÿA?ï•ÿ ?á,×?è#'ýò¿áEÂY®ÐFOûå²e‘æ•åîwbÌqÔž´Q@ÿÙfotoxx-12.01.2/doc/images/search-images2.jpg0000664000175000017500000015452411701011016017153 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿíDPhotoshop 3.08BIM'resize sharp sharp pixedit ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 498 655 1 2 2 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀò"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?íî&1áP+Jßuã u?‡ùëPn¼ïsoÿ~ÿ‹§]]Åÿ\ŸÿBJËÕo$ƒÊò¤)¹›?€_ñ  ?2ïþ~mÿïÃñtn¼ÿŸ‹ûðßü]bÚ_¼’:¼å€Žûµ²_“@X]÷Ÿóñoÿ~ÿ‹£}çüü[ÿ߆ÿâé7Ѿ€°»ï?çâßþü7ÿFûÏùø·ÿ¿ ÿÅÒo£}awÞÏÅ¿ýøoþ.÷Ÿóñoÿ~ÿ‹¤ßFúÂï¼ÿŸ‹ûðßü]ï?çâßþü7ÿI¾ô…ßyÿ?ÿ÷á¿øº7ÞÏÅ¿ýøoþ.“}è ¾óþ~-ÿïÃñto¼ÿŸ‹ûðßü]&ú7Ð}çüü[ÿ߆ÿâèßyÿ?ÿ÷á¿øºMôo ,.ûÏùø·ÿ¿ ÿÅѾóþ~-ÿïÃñt›èß@X]÷Ÿóñoÿ~ÿ‹£}çüü[ÿ߆ÿâêô¬ÒyhÌ¡by°çüª®¥qkk ʈñý0Nî=Mcs}çüü[ÿ߆ÿâèßyÿ?ÿ÷á¿øºÈ:¥ÔJâUœÁç!@p=4ÇÔïÐI”¶ÊD³Ý=¨ [ï?çâßþü7ÿFûÏùø·ÿ¿ ÿÅÖLú­Éœ¥´*ÁcW ©br3Ž:}i÷w²§›4\! Uºncßèë@{ï?çâßþü7ÿFûÏùø·ÿ¿ ÿÅÖ4šôb]Ém˜£YOÞè{}iïä\^Ì#l(ÀdóŸÓô  m÷Ÿóñoÿ~ÿ‹£}çüü[ÿ߆ÿâë6[ËË{dgû;K+*¦ÝÁW>´ß·O,S@ÛVu•b ç¸ü3@›ï?çâßþü7ÿFûÏùø·ÿ¿ ÿÅÖf·+}„¨Ã~y¨ä¼¹µó ‰`Ûk÷Ý»æÏ÷úô}÷Ÿóñoÿ~ÿ‹£}çüü[ÿ߆ÿâë;Û¯¶Ï.õòV“Ë ôö÷÷©`Ô.ÝãGòO’2 á}›šƦûÏùø·ÿ¿ ÿÅѾóþ~-ÿïÃñu—g¨ÜÞA<‹äGå®99näó÷hµÕ$žÒ{§TTŒaP}íØþYé@XÔßyÿ?ÿ÷á¿øº7ÞÏÅ¿ýøoþ.²žòîÒHá UCI"3ncבғûRåîœGhR]„m;¾¹éøP¶ûÏùø·ÿ¿ ÿÅѾóþ~-ÿïÃñu’5I¾Ú‰û·æò²¨ÀÄðhMJèZÜ\ºÂc‰™B®wJƶûÏùø·ÿ¿ ÿÅѾóþ~-ÿïÃñu¨IuöÚfˆ»J…|¬ÀÕÛ+¹¦’â;øŸncÎ [ßyÿ?ÿ÷á¿øº7ÞÏÅ¿ýøoþ.¨Mwuý¤- òBù[ËH©¨"Õ.e¹ù`4Çœž¹éøP5·ÞÏÅ¿ýøoþ.÷Ÿóñoÿ~ÿ‹¬¨õ+Ÿ2DœGr¨Q²qïÐÔsj3Kjˆv:ÑݶäqÚ€±³ºóþ~-ÿïÃñto¼ÿŸ‹ûðßü]bÃ-ßÚ¬’)Sa·ÎÖÉ×<õ«6W÷ÜùW"8É„ØÀþ} cG}çüü[ÿ߆ÿâèßyÿ?ÿ÷á¿øºBõd_íWð4ó2®Ð¬Íó.G8 ,io¼ÿŸ‹ûðßü]ï?çâßþü7ÿYzxí öÜÏ, Ÿ¼}ÙoÒ¢Ô„Òê‘"ºl3ª¶ìqë‚? ÆÎûÏùø·ÿ¿ ÿÅѾóþ~-ÿïÃñu‡i?ïtçÆ•!*¤ã¯½Kgª^\sn¦9•Ú¤m=²OZ×ßyÿ?ÿ÷á¿øº7ÞÏÅ¿ýøoþ.³ôëÙ§‘’çËYîØ”Ϩ÷«ûèwÞÏÅ¿ýøoþ.÷Ÿóñoÿ~ÿ‹¤ßFúÂï¼ÿŸ‹ûðßü]ï?çâßþü7ÿI¾ô…ßyÿ?ÿ÷á¿øº7ÞÏÅ¿ýøoþ.“}è ¾óþ~-ÿïÃñto¼ÿŸ‹ûðßü]&ú7Ð}çüü[ÿ߆ÿâèßyÿ?ÿ÷á¿øºMôo ,.ûÏùø·ÿ¿ ÿÅѾóþ~-ÿïÃñt›èß@X]÷Ÿóñoÿ~ÿ‹£}çüü[ÿ߆ÿâé7Ѿ€°»ï?çâßþü7ÿFûÏùø·ÿ¿ ÿÅÒo ¾Eb!uvFVEeõ[G#ÿB¥ûMÖà ¨€œe­\Õªk{ˆ`²¶Íy‰q¹±ž%ÌÑOfí¬ƒpSžâ€±\]«mó¢fîÕ›ù=i¼þðÿÀ7ÿâ©$•â·¿’3µÕ7+c8;M¥Ý½Ü>}ÿžŽÅJùJ¿ÂOQô ,)¸¹ò„‚æL[±Ïþ?GÚo?¼?ð ÿøªH×Eÿ]äþoU/u;˜oe·Žhö1_ßmÿQžÇ×Ú€/Es>㽑ð3åùM}FIÿ=êìn$]I!†A#N_–æ>wb"3ëÊÓ´oùúë/þŒj½EP~ ê—1`£Ê~§ý¤ª¥¼Í™&$nçߨV¬ÿñÿýr“ÿBJ—qõ  HâµIæ/— ^ׯ5cÏþz/çZ›­­eùñÿÏEüèóãÿž‹ùÖžãêhÜ}MfyñÿÏEüèóãÿž‹ùÖžãêhÜ}MfyñÿÏEüèóãÿž‹ùÖžãêhÜ}MfyñÿÏEüèóãÿž‹ùÖžãêhÜ}MfyñÿÏEüèóãÿž‹ùÖžãêhÜ}MfyñÿÏEüèóãÿž‹ùÖžãêi’L±!yjŽôŸçÇÿ=ó£Ïþz/çZ1ʲ tpêziÛ©  Ï>?ùè¿|óÑ:ÓÜ}M©  |Á¾W.¬eN[°íúÒ³]˜ü‹±rÝö­ÇÔѸúšÄH,#GDŽ%Wl7QéN)fÛ²î@‡æþJÙÜ}M.ãêhH¬e*dH˜¨Ú>nßçÖ”-·—"3+$§, ~Ÿ¥lî>¦ÇÔÐ3%›ïÜ#;Ô#|Ý@íJ g8.¡[œäzVÎãëFãë@k‚ÄÑ*E±þòîÍ,qÚDcòŠ"ÆK¹É­­ÇÔѸúšÆhìØ8a0fùÏÌhš;+‡2Dì:kgqõ4n>¦€1ÙlÚa3ÌŠ0?äS ÄH—xÃa#ÓÚ¶÷SFãêhÅdAc—a±•ô↊ћ#b“·vÖÆvôö­­ÇÔѸúšÆ’+)fódXÙýK‘HÑY<Þs$FN»·~¾•µ¸úš7S@¾M›æì~íùÝü^´ôû*Fѯ—±‰,¹ÎsZû­­b,›# ¸67ž£ñ§3*;=»@¬ç.Y5µ¸úѸúÐ:4;ÄÎÑyÛv–VíéLò¬¼ï;d^fwnÝß×+kqõ4n>¦€1cŠÊ'.‰c‘Ù¦¥¾ž™ÛC ©ù»½ësqõ4n>¦€1ž;'ò÷,gÊá>o»DQÙA!x–5~™Ýþq[[­&ãë@ž|GþZ/çUâ‚ <È’5ïo?ã[{­­dÄÖð¦ÈŠ*ç?{½#gHÅ …*wcZû©£qõ4Ž‹iŒ Œy`ª|ßt´Ä†Áº$AŽ‹úv­½ÇÔѸúšÆ,íÉ0ˆÐž Ýš›Ïþz/çZ{©£qõ4™çÇÿ=ó£Ïþz/çZ{©£qõ4™çÇÿ=ó£Ïþz/çZ{©£qõ4™çÇÿ=ó£Ïþz/çZ{©£qõ4™çÇÿ=ó£Ïþz/çZ{©£qõ4™çÇÿ=ó£Ïþz/çZ{©£qõ4™çÇÿ=ó£Ïþz/çZ{©£qõ4™çÇÿ=ó£Ïþz/çZ{©£qõ4™çÇÿ=ó OÖ/çZ{©£qõ4’ÒBñDZ[L"TÈAíî)D±ü¤Kxc'q2~˜ö­]ÇÔѸúšËóãÃŒÅ"H0Êíÿëâ›¶ð¶ø­ìã~›”€0µ­¸úš7S@BdM¥dŒ²±~¼sŸý œn£*êc·!þøÞ>o¯ÖžãêhÜ}MeùèX3dȬuÙŸPK†VòS;a Ž£©õ5³¥êÃQ’D4{7-œ×44iµÍä ® ,»rßÒº HþÌy\Ü ¼Å„ÛÖ´š…´"<×Ô×¢›KXš‹E6ж#7 ÍsW~!û]“G H£æ ­tŽ7¡_QŠäo|òF‡ÜûÕß ÿȯôO— £~¦ÅÚ+#AÔSh¦Ö.±­ bÖö¬ ãï¿Qÿe[5ÎëÚ(}×6k‡êñ/ñ{j¸Zú“+ÛA¶~ û-ªDð¼Ì™Ë™[’k¤G߸þ% \…†‚o-#Ÿíb?0giˆœsZë£#DíP´êrô/Ô}Ú+2ÇQM¢€X·~ [k¹`û37–Ûwn<ýkb¹ýCÃÿi½šàÞó;|¢qÆ:çÚ®·Ô™^ÚiZÛ[·•vå¡$ç“?ËùWJ¬C)AëŽÑô†¼•¤˜”X®{¹qþ5ØF‰j‘ªª(Úª:N§-ô/mGÑM¥¬ËŠmµ¯jû7ZZ¹ ÿ-]OÝÿd{ÿ*Þ®OÄVÖÖsÛ‹t‰F|§)ëõ5pI½HÒÐÑÐu‘r«mpÿ¾èŒ‹Ûëüëv¹? ÚÛ]$Íqs®Ó“ÇSÆ+«Í²– µ¨´Sh¨,uÚ(3^»¶M:æÝç‰ftùc.7¹Í*hàÖ!yž8£VûÍ…ƒÞº}^Â;è>ðI“î?ô>ÕÍéºL·wŒ' qH{“è?ƶ‡/+¹”ï̬v0ÏÄbH%IPÿ6áRTq¢E¤jaTtêÄÔuÚZZ)( ôªú7üƒ‡ýu“ÿF5NzT/üƒ‡ýt“ÿF5_¢Š(¥ÇüCÿ\¤ÿÐ’—4—ñûýr“ÿBJ©ªÈ*óþ¸¿þ‚h\ÍDmàc–‚"}J æÚîâ+ • ¹I-á•~NæA޼õëíVæÔoD¦a4B?¶‹$§Í·8'>¦i 1œÇ)õUŸšæŽ±}¼rI ©<Î!TÁ]«¹ÏçOkíb+WiWq‹Ë’AVp»d`ä`tY£4ÔVT ï½€Álc>õ«Ü]ÀÑ5¾å‡ exã2ú|¹é×8Í 4óQ´;nhbcêPVú•ñû\öÓÂ`ƒÉØ ë7œœñÖ¥’úyŒ— 2$M#/¹IÆ `c’i°Ãe!Oª¨&k™RÞ=¼— ©ÜmÓ°_BGäM*_jT6Ú|[¼‹8Ÿ'ÎX¥™p>^Ù —4f³´éî®.ï ΂(¤Ø‘ªò>U<ŸÌUúvi ‚¨5Î[kIeksws%ÌR±Ùú­ œõç§OZ_í=EVâÂN’@¥ElŒAÊ«0íë@ßx[O½Èw¸‰3‘¸ >™SZ–VÚm²ÛÙ±F9ÀêO©õ5ouS40'ž–Ò¬OÄj $—pxÀ=)¯{~Ь:lži  ©‚¸µ³ž¿-t9£5GGó²mZiÚwhÕ·ƒÐ~Z]Væ[[=ð•Wi0ÏÊ®æ “ôÍX’Þ ›t°ÆíêÊ 3ìVóíýð+!ïï…ÒÙ ˜·‹±ŸËá”Ç»¦~õD5mJy¾Ël¡äŒÈDTýæÖÀá™qïŒÒ¢%Ù*/¢ŒS³\ûê[©¢‹ìÉ4;wd°ù†àz}+~˜ š3Y·Ü˪}’ ÒÝR+3&âÿ60=¸æ¨[ÜN’5µ´‰\_ÌV]ØÂƒÀõ4€èsFkž:¥÷’—¿—m‘ež8¼ÀJ¹]Äg!p;RE¨j7ƒ˜`&Þ;( ½ÎKîÏ»L ÜÑšJæ5X_ûCR¹/žD1íY! €wdÔ~†u¨ÒRG‘"Ey>ûË}k®uYc¹šVXîšD ç’2ÞÔYÏ5Þ­nñß;Eöv.¦-»˜I‚ ž†˜½©œíìÖ5ýåÚêSà ÄPǧŸ†MÅ›q—_ûfåç¶–5s’ÈQB£HÅ·7v\PCš3\áÕoc[k¦’'Šy%_ 'Ì¡Èÿ€óÇz¹£Ýj3È­uò%‹xs°a½ÖbG¹  |ÑšJæà»ž.Ú+BÞv&ªÆ¬6«žIfP?Zt¹¤ 7ÞÖz•ÛÉgq10YÜG +,[Ô³ò±ÎW’ãgAóÿ³Ùç¹iÉ‘ÀÜ9\1ïßúP#Ojú l1EoŠÖ(ÇEQ\ý¾±s­ÝÝÌL— 6à±ÿªÙ¸çßîô¥]SPη”l›t!dQ´HÛrʬzcÖ€:,Ñšç$Ôõ¸’Íf”\ùK$h ã`nŒÀg'Ö¶tù.d³F¼ŒG>HaxÏ‚GOzµš3YúÅÔ¶¶¨Ð:#¼ÉçÅQ·ï© ¸‹)3#ÍågrìÜ8Ï^Ô½šCÏZçìïõ{þ(±³¦X&ÔÆ@?q96ÕÍ+Q}FmË´C æ sæž«ø`þb€4ªôP)Ù¬µ+¸¤¼›ÎˆÅor‘6òÁ¶÷õùª6Öna•¤ÚÒÛ¼Sô4fªêS½¶›uâ*ýìÖv£5ÊÞÙÛÛJ±‰™Ã3.〹â¨C¨_ºÁ(š&RÉ E³˜Ê†ÁÎyû¼zè3Fk™·×nîe‰S`[†Háùˆm2èGþù®”õâ€4f±µ«Ô½¹Ky£Ž8-<ü4{‹6æã¯N*Ôµ+›¶kX7CƬŸ»U˜–,}î0§¥ožzÒQØVö…ÝÅÍý˜ž5[hä>jŽeôÚ?ÙÏ?‡­[ŠYí¼3ö†ŸÎ™m|Åv^û23ëõ :š¹£5€nµJ¸Qãµ,Í OðŽz_qQK®Ý,ˆ6¢ÿ«¸pW¤,¼þ;çé@&hÍTÓ'–çO†â`›2.?¸I+ÿŽâ­PæŒÒQ@ šEÿrÿ×YôcSÅ3Eÿrÿ×YôcPê(¢€*\Çô_õÆOý )Ž‹"2:†Fe=§Ïÿ±×?šSv7÷ÿñÚ­eºGk«íÜõÁÈüª´ÚBM©¥ã¼XWmXpìæ[wO´¶7÷ÿñÚ67÷ÿñÚ̵ÑÒE®Ý¢cómXáÙÝwÇ?€f-:ÊeŠÖ%RA C‘ùU­ýÿüvýÿüv€5͵Öß´Â’íû»»TÛûÿøíûÿøíDmmØ80&Ù6ïûÛzRKim6ÿ6}ä3Ô‘ÐÔÛûÿøíûÿøí@–V±*¬vѪ¨`7}ïÎ’m>Îq–Ö'®ÕÈû£ÓéíV67÷ÿñÚ67÷ÿñÚjF‘—(Š¥ÎæÇsëN£cÿ£cÿ  =•²Ä!ŽGòü·¦7ŽüTñiöq#¶rTž:•åsôÍXØßßÿÇhØßßÿÇh l­&¸ÛÆÓ.>r9ã¥<[@ aºñÑŽr~¼ŸÎ¤ØßßÿÇhØßßÿÇh;{xmcòíâXÓ%¶¯­:X£ž&ŽdY#q†VS¶7÷ÿñÚ67÷ÿñÚ£6‘i*ÛÆ±"C †C\†$Éõç­Júu”Ç ÚÄcî.1¶¬ìoïÿã´loïÿã´Ùmö:y µÀWûÀt©©67÷ÿñÚ67÷ÿñÚ†âÒÚ衸$+÷Kv¤’ÊÖXš)-ãdfÞWÅëõ©ö7÷ÿñÚ67÷ÿñÚ¬úu“ù{­b" ÞzbœöV¯t.ZÝ<üç~9úÔûûÿøíûÿøí-DöðIæo…Í>GÞ 5&Æþÿþ;FÆþÿþ;@Iek,M##9r¾­ëõ YZƒ ñƒú¬ múTûûÿøíûÿøíQŸK·¹ÔêáPbXÂ2ôÜþ=*w°´{;ÛDÒ†V G9׊Ÿcÿ£cÿ  Ø´„]P^»Åò32¬pí$‘™·ð{ïVíì­m]žÞÝ"fêTTûûÿøíûÿøí-V{ 9í£eLíéžµccÿ£cÿ  ãO³YcZÄ >è^Ÿ•>h i•S—ÛüF¥ØßßÿÇhØßßÿÇh†‘ien#G#í(òÁ`O#çÓ-…´ÐÛÁ FU Å£Þ23ÏçW67÷ÿñÚ67÷ÿñÚγÑí ´’’9üÙ|ÖýÞÕ £$ŒêOZ¿QÁÅ *"ôU§loïÿã´loïÿã´[P²KøR)²+Wpl⟠´0"yd•ÀèOSSloïÿã´loïÿã´XÚ%ɹKxÖcÎð9§Á6áÄ$AÜ»íÜÇ©©67÷ÿñÚ67÷ÿñÚ¥—mä·R"K3Ëæ+2òœcñúÔ©ai$Vñ$‡?6Üã=jÆÆþÿþ;FÆþÿþ;@–,6­3L!—ÍŒFQ!Ø›~…›ùÕë{h-P¥¼K“’¹©v7÷ÿñÚ67÷ÿñÚlˆ’ÆÑÈ¡‘ÁVSЊd–¶ò†ó ƒ'–r¹ÊÿwéRìoïÿã´loïÿã´V¶åL6è… e#±#ü¨6Šb+o0’cÇyÏ>Æþÿþ;FÆþÿþ;@gÒíîuº¸D”–0Œ½0Äç?JìlÞàNöÑ4¡•ƒÎáÐýx©ö7÷ÿñÚ67÷ÿñÚÍ‹HEÕë¼Gc3*ÇÓ’1ó6Nx' õnÞÊÖÕÙíàH™º•>Æþÿþ;FÆþÿþ;@ T,´‹KH¶ùQË! ­!L y{cÿ£cÿ '±´¸DI­ãuA„}ÑÒŸöx<ȤòS|JV6Ç(P*Mýÿüvýÿüv€Ñ£HŽÈ §ÝcÕséQGekË\GoÌÙËÏ=j}ýÿüvýÿüv€!K;Xü½–ñ¯”ÌÑá~ë¤}rjzMýÿüvýÿüv€#h!vvh•™Óc:¯§Ò£{ 7™&khŒˆVÇLtüªÆÆþÿþ;FÆþÿþ;@-­²ù{`ŒyeŠq÷w}ïÎ’;Kh­ÚÞ8Qa|î±ÏZ›cÿ£cÿ '±´¹ çÛG'—ÂîtzS¤µ¶•Ýä‚6gÊbWªwéRìoïÿã´loïÿã´ˆªˆ¨ŠUêMýÿüvýÿüv€ŠMýÿüv¢Q<¬þ[ƪ§oÌ&€&iº/üƒ—þºËÿ£¢Vš9‘e(ÊçnTTº/üƒ—þºËÿ£€/QERãþ?bÿ®RèIYú´¥$¶F¸kx›|ŠqÑI5¡qÿÐÿ×)?ô$¨ç’4À•wØ®hµÂæ\M=ĺQ3N“ÉÏp°¸ ÈÛîÄ~µ=ÝÊ.§§•»ÂÊìñµ†Öíõ­›¸³Ÿ›>¸¨ÚæØL`‘ÐìéO•‹™YL?µï ûI“j£fa;³Ò¨5Ó¤Ó¼wŽ×"ðF¶år8ÛôÉÍj »erÁ0Ç« ^Û+— †þðAš9Xs#1µ{õK|G4ÑGE^¸Û–qùóô5<ú¬ðÍx„FZ$f‰ç c–`O¯LW í³2L 8 ^ÛÄ& u;G?Z9Xs#(ê·p™T<3³]Ä«žaÔçøª×ö•ל¥’@màË6d;NqúÕ¯¶[mÙåü¿Ýòøü©Âòî·ýóG+ ¢†¡%Úês4-˜íí–R¦bƒ9npîéê)V¹ŠöÚ <·ó<¿3l{@ßÓ¾Oýò Ñûl>ÿ|ÒÛ|î+ó‡m¬.Œù5¹R+rH‘LížAY§&Ÿ¡}*ƒìÊÒHë¿ïª›³…cƒžÛ«JÞX¦ ñ¦9Á%pMH¨ˆTUì®) ·է–稓A ¹áIBÅWßü;ÕÝ&êâéKHc"F8±-±$þ>•¡µq«¥(èú Å[™›XdóßÚ|¯'<¼°wcëž ŸK%êW¹•à2ˆ¢ó_wN üIý*Ó^@’©Þ>RÛy£íôÚØë”ùX¹‘NÎd‘u8ZùŠÅ>ùƒr.Å={ “Lûc¿„égÌ¿d d 2o'ëWEŰ݈‡Í×äÓ…Ôv„Âÿt'r°æFgÚç†ù ²¹0¿–¾d§xFf ŒŒgŽqþ4°ê·²‹’!€yk&ÕfU!”àgçÏ8Ï cõ­!u®6®s€˜†êØ–&1–àƒŸ­¬.Œ«½Zsg˜f‰•+4¯O™p6¨Üyç9ÉéV-õ+©u–‚4ÂÌ¡ÈwÞÉäôÛøÕßµ[m ³åΕZ¬Ó¸Xßt|1þ€ÒjÛ;Ò¯®.‘>Óån{hçZîÜ“ùÕ:}AÔ»£ ’ß<’4‡h ~îiãMhZÕ_‚0»SN³f q'·ÉK™ÅKMnY‘™‘6‡„î /îÝÂ’@fǸ÷K¬Ü‚Ý!mÍ.˜mŒfœõçéSsOPÃcz+­Bþ&Ò€ÚÉ! zyßsö¹ˆ„^pýÐ|ç§SéT­5k—°²•öù˜Ã#gqÄÛ›êFjSâ­4vÍÿ~ªÅ†¹c¨]-½ºIæm'拘Ï=ÒhrÜeçÈ.»à¹sTš`,ïŠÝÏ40•ò¤Gù™ŠýÜŽ¼‘ùÖÔ’,Q—nƒÒ«­Ý¸U_@œP•Å{¯ØÛh’Ç%ã-Ä0ni€Û±×ó—7H²éR‹Í¢W ÃxÚãaÎU¦º·pw¦ìú¦i>Ñlv$½>AÅ>VÈ­©H?´í¢–ñíb0ÊÇk…É1üÏN-ZýlÌŒ‘·—gæ\3ovPǃøö­w¸‚LoMØé¹Å)»„ç œõùzÑÊÂèÎmVæ8 y¼”FfÊ„ò1…Wã¿BبçÕnRç~Q•<ÿôdûÿ 8Ü}ñžßi‰í¾\F>^Ÿ ãéOûD ïÛÉï·š9Xs#:BúU…уK6Àü0Û±›î«OïsžÕ%ÄóÜèðͱÀìÃvdØÁÆqW{uû¨¿ ŠS4.»YC/¡PE¬9‘Ž5› kAFbn$_˜«ÆíÀÀ†î1ÅO.¡ö–H¾Ì¦’%ܬHÚ»²yç¡â´Œ°•PP½^”¾t~Ÿ¥atdÛk3M0Ȉ1SÉ\ù˜1«nüÎ:Smµ{ÙìÄÞ\ Îðªäƒ·{… …bxÏS·éZq›h¤’HãÚò6ælu8ùOB¤í@2rp½håar•üŒ/ †{³m‰ØÈ§fçxÉéÁ'Uîç{;&¹¹{ux¤c(ùK•û‡ñâ¶ÁI“•V\ôeÍCwy ©:–ÏÌ>]Ô¬öÊ1ùóßiÙšd‘¡ÜG»åhvöË7èjY®Pjö;nþI•‡—¼mn88õÍIý­k’~|úí¦ÿiYeO—Êô>Xâ«–Dó!4ùƒj7ðý¤Ë±•‚³ƒ·#‘ôª1ÝH²ïKÇ’àÞ4~Al›±÷{`w«ë©Ù«T!R“J5;5bÊ„1êÁM’dg®¯~R×÷vå¦'=NïáŸõÁúTòj³Ç-Ümåo˜Ô.@]Ànf }y¬¶§fØÊ·¦cP5+1»Fï½û¾¿ãG$‡ÌŒßí[ÈŒˆ¯Ìn]£TNæ_SÜ÷ëW¡uö!XİÄÈ2[.~nœéÍMý£fSo—•þï–1ùS¿´í½þù£•‡2*jn’jQÛ¥ô¶ïò´¬& ª™éV¨âÖ®e¿ÞDaš_$~ò¶[ÿ!üÕu¯ìÜå¢Ü}Z0M?ûJÛ®Öúí£•‡2(C©Ýy[¿tc#fÜ fß#¯\ñŠkëWÓɱ&a çzìlÜ÷ëÐV‡ö•°þÿ¾*î4ø®^á#“Î|îf,ß–O….VÈd÷²›dÿGYÌ{øa´FÍœ+=h¼šH5˜¦ßùh!IðÁ‹›f>aÈïÚ¬.£hƒ …Gû)Šº Ø»±÷¶óùÐÓCNæ(¼5#‰d’O>Dkeÿžb2Ê@ú…çޥѯ%”^}­¥V(bÛ¹í÷5¾+Òḑe󙈽¯§ÏøKô¯îÍëþªŸ$…Ì…Žg¹µ»k-C÷;G$Ó…' óÀªGŠžk¶oI:;ÄËòïó7†î= Uÿ„«FÃ/•&¨ò4ÿøK´’»vÍ·¦ß+Š9%Ø9‘"]ÏÿÙ¬îx]ÑD²üû Hc<(¤·Õ¯§ŠáÄ0®Åb¡™T«Æßüöþµø»IPReœqŠ?á,ÑÎâc“æûß¹ëõ£’AÌ‚ÿV¸:s<Åû<æ²,Á¶íQž¿ÍVF©rÚ…ÄK b(‹®—wÊ»ƒ}윞Û}óU¿á-Ò6ª”— Ðy< ?á-ÒKoÙ.ž:9$ÈÐÓï.'Þ“ˆË¬Ì `ó†ãœôÛ×Þ¨XÜ<¶Ïæ^ÈU­Y_p)3ʃü>˜ö£þý+< ‡ý²¤ÿ„·I ®ÉpÝG“×ëG$»2-}¿þ)è&YƒÌð+d7,xÜZ‰µ©Ñg}‘NPÎQä2ùdãw×Úþ•,~\¶×ÎEGèJX|E¥Û†ò ¸]ÌÌO•Ô’Içêhä—`æD£TºòcÞÖÑ——oœØ(ÂÝÎ7øV–Ÿ;]iö÷<¨…éT¬ï4ýr9­âŽTHŠ—\úôû¤zVœh‘F±Æ¡ÕQØT½‡ÑEUxÞ3¨ó*~õ²3‚EX¬i€ó¦à¬=ª£a9XºÏ›$Šß¼ãæÏj›Fÿrÿ×IôcVEŸüCÀûßÒµô_ù/ýt—ÿF5(£+—袊’Š—ñûýr“ÿBJ­{Õ?³qÿÐÿ×?ô$ª÷Ÿy?¨îL¶)‘HEJ1HäšÔÆÄi¥*JLU§{q­»;°(=Í> Râ%–& †²üDD^T² éœ÷úÕ!€šhÐb"¢E™¬¹ýëò{·4±KA¤­HÒ”¹ Vþ›þ¥ÿÞ«•SNÿRÿïUºÂ[›G`¢Š) É™~çý£üé54£÷þñ¦cšè[=ÄÅiÔ¼w Ty¤‰wnŒÜqÍ;mgióï֯ўл3»ŠÕ D]Á¢ùW?€¨'PK³‚AûšƒWÑÒ$R[ﯡ#×ÛŠšã>JîÆw&ï¡\Õ¥wcx- šœ¯GÈMØàvÀÌ¡RgVþÖ\ûg5µ{÷Ñ¿ôX§ýJ)àîR1Ÿ”ÖqE6K#†Ž…MQ~õnA•¥UaÖ©¬$c"¦ÃÏsÜúVç„Îu¸H<cÿŽšÅ¬±7F:ÛðŸË«Âÿ ã?Âj„v—08¬ý¤v­)Õš«…õ­`Ìæˆ)qRí÷¤ÛZ\‹â“©j7tC†p>¦‹…†‘Hó¢•}7ÌÔõ‰¢û$‘0þ-ǧáX·—³Hß3´¸çx©sCQgJš…³\´&dàsßÒ­®ÊœŠæ…ä[ù1íÆqÏ¥Gç…;¡ß ÿafªÈuT¹5…¥ß˜§]\oW W¡ÿõWDÑ2‚zjÑI2lG×ëIRˆÛÅ0õ8¥p±f×ýQÿ{ü+7Zÿ]û§ùÖ•·ú³þõgë÷Ñÿºø‡/„ÌÅiø¥Åt ÛI¶¥ÛMwEæù½&“iå[‰$Š[p›v<_5gŒŸZÈk‹ñÿL}î Çz¹d$›Q`ò.OÍ€?ϵW6öm"è¡jVµ¹Iž ‘H÷ÿ­ëúTPβ„ùYwp3ПcV§gÊÇm£mJ 6pAÁÁö§y~”î!ÛFÊŸË£m+ŽÅfT³p5ÑTa\õüÉki$Ò+2ÑGZèü‹þèþUœÙ¬å×ãþ&7õñ'þ„j U›áÿ ¿úï'þ„j WTv9å¸Ú)Ø£BŠ)ÔªUH,2=); Üm¸£h1(Å.)iˆfÑFÑN¢çWàA·}#ÿÙ«­®OÀ½o¾‰ÿ³WY\U~#¦QE™aXÓ­›þº7ô­šÆ›ýlßõÑ¿¥iKr*lGgÿðÿ¿ý+_Eÿpÿ®’èÆ¬‹?øÿ‡ýïéZú7üƒ‡ýt—ÿF5:»Š™~Š(¬ —ñûýr“ÿBJ¯y÷“ñ«ñûýr“ÿBJ‚èe“ñ§É–Å\ÒÒâ‚+c!¥sL)R}*)S"lp¨¼½L¥Ê®5èdêlÏ M«Ý½r*-2v[ù#›¤{=Hæ¯^¥³\*3•™zmlZÉÔf&MŠÄŽ9'‘þq\Ê~õ·vÇD±³œ*“M(AÁÕ-?Xw…÷Æ ¦Ü¶züØ?JØv02ò«ÒºTîbãb·v` •ï“R‹P„wqÞ¦GÞ¹¨ävœ› $Y·]¨G{TÕZÈ“çûÕf³fˆ(¢ŠÎâWÿxÿ:N)%ÏœÿïmtGc8U}FW†Ñ89>œÔõ•®Üâ4„;*–VQÑiKD8îdZß¼©‘cŒåŠí·µuÕÃ#,WÈì>lŽý=ë¸FWPÊrCYÓ.hËÕ71ŒØÎp3Ž)..ãa RŒ©$œw¢ýÚ[–r}î}«9.Sçb@Æ)uéùV2ÕšGbWžkŽ»0ŽÀÍW’9_ï3»ÕGëÖ£–ü`½ýÇçQî]ËBHñÿê©°î9#ß/¸ç zsQKÃn.9R´ßã„íê*‡Ë‡±×üóT!ê[¡Ou­¯ ¦5{_uËaÇõü«ž2låÁÇq]W„™¤–*­ó>æïÂÿõñ@]Çú†ªAI¬Ý-*âä&ò‹÷}y°í§¥L··2_M$B‚³Ø#8úÕ{IÈ´§e+ç§#tÔâÒdƒÉ†hbM¡~XÿZ¤nîn´©®ÊHž&(ŽõúÔš}äæXí§TÁ]J’N=óÞ“mî>Tˆ_êۿ~ƒ#²t¥ªKЪ{¥ÔD«yo²òtYå ʤaG·ÛmNTž(Y–h™Š °n=Ï£•qáÉüè?˜x2`î5f-&H`H¢¸‰BI¼{b£ƒT¹‘í™’Ä…@î~•-¶¡3Þ§Ä m¨U·tç¡§a m¤½¼ÓJnC68(FÚ´-d/ÈÔ¾h)¹~aíÞ³tÖ–ê¼–ñò[&%ÆÑíUÌÅÊ‹ÆÚR?ÖEÿ|šgØ¥ÿžÑß&ªEªNÏ^D²˜ÔwŒw5:¥ì¾N"·ýó2',0GsG3TY»Ò亷xM¦ïâU5x ¾:˥̱ÚyQžbêÛ‰À+KkªÜHöæXã˸|¤ç+Þ•î;¦ð‚Ë<’µî ŽÎ@OSŸëLÿ„1?çûÿ!ÕûMZâà«4+å:±U¾\2Oð¦&§y$QnXϲݕ"¯ÚHžDSÿ„1?çøÿߺ?á Oùþ?÷î®E}}Ÿníå¸qÌ…Y¶ö±Zv÷+,1¾ôfuÏËÐý)ûY ‘ð†'üÿû÷Bø2 ûšówÁOþ½_Õ'˜^ÛGÎÃnX1¸þt¾k-ÔhÞnï²±Ìó~8ã4œäÆ ‘@ø2,ü·›G¦ÌÒŸóýÿêÔ:ŒÐÙYC†‘ã,YÃ7CíÍiÁpóY ] NTå} ¤—PpLÂÿ„5?çûÿ!ÑÿbÏ÷þC§Á¨] x#–fß$ªÊÿÞ\àŠ½ý«/Û–ŒÚA›Ê¸Y<Ügr‘ŒúëK÷ÿ߇òjË}Jì[ÆþB¡ÜÁÙ•ˆèp9­ yüØ#“r¶åÎW¥CmêËJÄŸé߇òj?Ò?¿äÔn÷£w½ ßÿ~ɪ«XJÌìfæbßtÕ­Þôn÷¦¶®SOxeY¼øþCžTÒ[=Õ¼>\2©BÌÃ6r¤·]ÜŽjÅÛfÒaþÃ*f­¨Ma4-YCnâ?ííCw¬:;‹³"†–.½ÝÓwЖÿ»o?žŒqµ‘¶ºõÁú÷ê*”nòiöòË2ÌÍ"±d/^Ôºqί}éåEüÞË7ñýýr“ÿBJ‚ëª~5=ÇüCÿ\¤ÿÐ’ »ûÉøÓŽä½ˆ8¤g¥› £WQgKV Ÿ›‚GaW'dDuct»…¸Žl6JÊÇð=)é.>ѽÀ\áEfø}Ú6–6@—~sÒ¡šõÞèˆáÝ׿|úÕ„åtmf;SÙ-ãLœ® ë‚Mf]䓜Z·;]8âHÀ?/óôªWέµÁÏ¡š-’Úî[i¶Žvc'¦+¤Ó. ØÆwï|mcïX6HçN3…f 1ÝÆÿ^®øx¢$ñ³.A?JÖ“ÔÎkCosœœkóß&’'¢ºô>µ`:c…ÀúVïC$>ÇýS}jÕAlÛ•½OYËsHìQE!™ÒÞ¿ûÆ |ƒ÷þñ¦Öëc¸b°/ã™&¼ÎÉ7’ÝóŽæ·'™-áidÎÕ¹5ÍÜ_Ã{ö•u;ÔwéÃzVsظâßy‹°~\×M¡Æéaþe%·6qå\›J±aj–^=…ušO•q¤´ƒ†Y8Ç&¦H¿¸žúIdŒ”€u'€qÓêyª°Ú+‚_tŠNc·ßµkKZZ$r€òÊ‹ü+êÕ_3¨ÆIç›-¸ª,p¬ ü'nâ}qþ4Éö ‰.®A‚?:ŸZ.ù9]žZ¨Py«È–¬ÎÝXG¿ÏáJÚ U† ””²:«qŠ«,AYG<´ˆÇÍ.¹ÔTÏ)’?˜ ŽsNÂ*¼Xû¯šè|-¶;øâÜÛö;Ø‚øÈÖ£•Ü#Úµôëâ =ÊA0¾›Z›ž,8ðÕéÜú¯08ë^©âKsu ÝÂnäã=Á®þ™`΀g# ëøÕÑBÍÔ«<¥€Q•­[NW8cŒæžšÇ ² Am½;Õ¥ÓL1Ó'Þ-÷OÖ$S¹›Ëe;wq÷VI–%yMÀSî"˜Éû´}£§ËŽ”Èínn_Ét+¿Ä`z`ÎÚÊhŽ—lžj©ò‡SȦùža|Ûn'=ÿ‹«úFcÒm#-ÊFàúqV÷7©¦]¹¶·dr'¹ÝÖ¥ûD_óÕ?ï¡W÷SK¹¿¼h?íÏTÿ¾…h‹þz§ýô*þæõ4noS@>ÑüõOûèQöˆ¿çªßB¯îoSFæõ4,6ËæJ#gõÞyýiÒ¥”ì_,°>Þ=85­¹½M›ÔÐÕü÷_ûî€1!´…/v–ÝB1`#È'ë“Sˆ¬‘™ÐƲFí属¼ZŸj‹þ{¯ý÷GÚ¢ÿžëÿ}Ð}»[ÛÛ¤1Ê›Pcï~´Á ‚Íç*Ä$Îì‡ïôÎ+OíQÏtÿ¾©É(q”“pöjÊH¬o9V!']Û¿¥*%”~^Ï,yd”ùÏÊO^õ¦nceýúOµEÿ=×þû  ÔK$òöùcË$¯ÎxÏ^ô"YGåìòÇ•’Ÿ?ÝÏ^õ¥ö¨¿çºÿßt}®/ùî¿÷Õf$V¾ô«sÿ-?,ñJ©d¾^<±åçéž½ÿi}ª/ùî¿÷Ýj‹þ{¯ý÷@BÛN ° ×Vÿr%ª\,Ë$k²=ˆ¡¸QšÓûT_óÝïº>Õü÷_ûî€(3[<É3Õü÷Oûê¤HÈc­d4V FÞ^Èþïï#ñÎjT’Þ8Ähè cuinoSFæõ4‘åXl‰1ØŽäùÏÊ:<›7ÌÄ{÷oϘ~÷¯\V¾æõ4noS@!,—n<¿•üÁóŸ½ëÖƒ‰ŒÆD{woÆÿâ=óœÖ¶æõ4noS@í ƒ"¡Ùµz~ôëš%‚4TGUF Ò´w7©£szš¡öˆ¿çªßB´Eÿ=Sþúszš77©  h‹þz§ýô(ûD_óÕ?ï¡Z›Ôѹ½Mf¼Ð¼l†d_¼)Æõ žaH ã¼ÁœV†æõ4››ÔÐhž¡ɉo¸ëRiN¯©Þ•`ÃÊ‹sÝêöæõ5VÄçX¿Ïüó‡ÿg  ñýýq“ÿBJ‚çªþ5=ÇüCÿ\dÿÐ’ º+øÓ[’ö!¬}næHÙvmù”޵§pþD/+ „ÅrÚÔ÷hÕää(ÎxëJ£°S]Gè÷~]ô°È»¢|¦ïöjâÊ‹8¸’(S… ÷˜jÆŠáÌaL[³ÐŸÿ]ÎÃ’‹#‡‘©t„–KÎå¾bxúÐyb6»ŽMŸÎ£Š$H[l©Š2:çôªÏqpnRm¿(æ<ŒþT Ó"Y™ÎÕ8ryÿËvRÅаÜâ8 Tñ©–Þo6VÊí!qÏëý*‘\¶ì¿^GåDA.‰¨Aöó$e:8È­h%Kˆ÷@ë"d®Tñ‘^y5Ó$„)Ú}½k£ðƶ„ ¾YK½í[ÆLÉÄë-”ª6}jz‚Õ‹#dçæ©ècAEP óýãMÍ6Sûçÿxÿ:A] c¹_UÛý9nÈHú×)q³s‚é–ùvúò+¡¿òî%hä”yJ¹nGˈ ‚’GõýkžnìÚ È‚ý—|%g˾µ§¢]‹{Ǹdrì¤lw½WFVä¼`z¶1N*›y¹ùs÷T*”ìSÔ¿pò]\ª áAnO½j´³'cî:§…þ‚²$b¬6«nÃüûRyrlýè8'…åãKp-¶ —7çx³Ñ~^>™©Þ`Àk ?Âå…g‹uó7í^~ïáR·“Ë9‰½W þ”X.X°¨#ìÑçýÚDÕ”y6ñ…'Óéþ5^;ȼÀF—ÜDAüøªí{åLþTÌ¡Î[w4€¿æI;±(-ƒÀÛééõ­¯ o}D¼í†Ûò®zü¦¹v½2p÷,ÞÜÖ§„çW×áC½Ž z}ÓLgm¨ ÙKôþµŠë]¢È…eOQQ}ŠÛþxû骉ÔÄ%Çuü饤ãîþU½ö;oùâ¿™¤6VÇþXûé¿Æ‹ çüÇ?þªBXŒk¢vä#þúoñ£ìvÿóÄ~güiXw§4èû'ùšmýý½„-$ò `ŒËpð3RÚ-”€°ÿÇdêöË|ÑY‹¯´ÚˆPîAå°-ýãÐî?»LF¢^Û<‰Ÿ™”?”\néPÛêÖ6ÏqÜ^TgYÀÛÉúV\Ú~£%ÜÄåc¸…Õ•£TT]»¿Ú-Ã{b‡ÓïšÞÝ>Ï(û%ËIòIïU·`®ìŒŒ½Šb7„Ñ|á"¶îß»åÇ®zT?Ú69QöÛl³m_Þ¯'ÐU1bëáë›H¡‘d–9q¬¥·6z•ùFsÛŽj®§a{, oo ~Ê#UˆÆ¸F-ü=>ílµå²Î kˆ–bp#.7×ëGÚí¼ó¸ˆÌ<½ãv~•ú]É‚üùΙ­Ê6åÉØ«žs؃TÌ-öë[‰U»þЮ¤°eçîxg>‚€:HnmîÒ ã•£8pŒ SïSV‰§Kk$Fâ ÒH!òƒ´‘”=>è_›¶~jÜ  é›gÚå H²"¯š2 WûEÎõQobCÁ„.;óšžì#[Þ‡}©æÇ“Œÿv¨‰âYHYŰ¢€§ õãžzÖ‘I£96‰ÅÅÎö_³Ø€ Æ?—§9¤ûUÀWf‚Å6¶ÒÐò‚±–É‹i;Æ?.j¬»wÜÛ¶Šm£‘ ‹s '1È©þËoÿ<"ÿ¾6Ëþ<`ÿ®küªzÄØ‹ì¶ÿóÂ/ûàQö[ùáýð*Z(/²ÛÿÏ¿ïTîQb›÷H©º Ú1Ю?hÕÿõÃþ¸IüÒ€ÎÞk c%JJ±ö[ùáýð),ÿãÊúæ¿Ê¦ ¾Ëoÿ<"ÿ¾e·ÿžß¥¢€"û-¿üð‹þø}–ßþxEÿ| –Š‹ì¶ÿóÂ/ûàQö[ùáýð*Z(/²ÛÿÏ¿ïUmÀU‘aVVz ¿Taÿ–ßõÙ¿¥Ek{Ém§oïqûûz=3ŸÊ¥Kˆ\°I£mœ¶Ösæ só‰lôHš í•Ë$jÜy…›§¾U§jÕtë+I›2Iyù™ÌÏú1ÿP躷hÚEž3à0?Ä~t¢âªÞt{]¶©Ü0O üåX×ŠÞ ŠÖ¿f•VY£Ãå}ßÏ*?à4[[4ºåÒ+¶·-4`»,ƒ ?˜ÿÀ¨SûFÇk?Û-ö¦75p¹éŸ­>KËh¤T–ævÆÕgœô¬‹-Ä4ýö‘ ”‘É÷xv+Ç¿ñsP¶rÖöÈÓ6˜–é–R|Á»åÏâ9é@ËwlÑÈëqH‰0q„#®}*¼:­¤«pæhÒSÍiceCp£{¥Êf ¶C؈m]–_ËŽx¨¢°¹K×½:Éö¯4[ïq0»ºíÎ}èJÛTŽæX‘T¨•¥DbFÆØ?Ë?J¿X:}œÑI¦ÀðLSÜ\2® ¢¶ð£Ž?Œqí[ÔQEQE J«cÿ!‹ÿúçþÏVª­ü†/ÿëœ?û=,ÜÇô?õÊOý *ž«S\Çì?õÊOý *+Œei¢Y]ÕÚ6ÀŽõÇj­»Ëw` ^@í]“Ȩ„Ç­qz—"0K'¯½g7©P eÜѧ â¬N‚S9mì>o›¦(7–á˜>µ%óÊy'9úV/sU±iÎÒÝ™w2çœó3YWŠù¶+اžkZÝã\ø|¯?7Oá—¨lûg¢ùIDw±rÑ7ió9^{ô¬†8c¯ZÚ±Ëi·åÇ ®êÆ*»À'œžÞõQÜE¨›.Á¸úV…ÙŽ¬¡Èa°‘‘TçÿVq’vÔþp5ˆ}ÃÒ¶‰œ¶=Ëý[}jÍRÒåI­Ýäo"®ÕKqG`¢Š) Í~õÿÞ5›¬Ý}’Ìíl;£‡sZ¯yŒ|§?1íT5M _Å‚%‡uLçÚ´rÐÉ-NL,—VåŒ*Òazþ&©üøÃ"qÚºl/-ѽ¤ìʘSå7\cÒ²ŸLÔÃ|¶Dr3ä7Oʰ6(&âäùKŸ­J<üüªúóW Ñõ™šÆç'ÖȩƗ¨7"ÎàÛ?¥1M·š±Ÿ´6ñÉRÇùR‹xŒ¹SÐq“Vÿ³o—¦uéÄMJºUïž3§ÜãþXZC  noº=êh¥€ï ûÎìuǵN¶;ðš]ÙÇñŠÿJ‘ô«†Œ´V7þñµ Ü3L#6ÀÊ1Þ³t‡nw6pmÿeê%Ê›;ª:ù-×5UôDÝJN›tTcÈnJ‡bsÿ­O 7üTPî ¿+€;}ÓÍVf¦q‹ …ñ7øV¯†ì¯bÕâ’âÊh•w|Ï|§½1•QTEPEP6¿ñî¿ï?þ„Õ5CkÿëþóÿèMSPEPEPQ¤1$­*EÈÿyÕ@fúš’Š(¢Š¬ð¸ivÇÉ)–F+‚>€ûTfÿ§?ûúßüEH<ùç•"‘bXð¼¦ì’3R}’ïþ~ÓþüÿõèM…‘_ìßôãgÿ[ÿˆ£ìßôãgÿ[ÿˆ©]g·(ÒL²¡uBmêqëïI¸ºÞé2D¡Ê…Ù»§´îÅd=%ºE ¶öà€<æãÿ§ý¢óþx[ÿßöÿâ)¿d»ÿŸ´ÿ¿?ýzn'‚XÒYU“ a6àã?ÒÉ>Ñyÿ<-ÿïûñ}¢óþx[ÿßöÿâ)ôP>Ñyÿ<-ÿïûñÂ’Ìû§¯ÈP*1n¸ÉÉÐTÔPµÔ1,KÊËŸÃi©>Ñyÿ<-ÿïûñú(Ÿh¼ÿžÿ÷ý¿øŠ>Ñyÿ<-ÿïûñú(Ÿh¼ÿžÿ÷ý¿øŠ>Ñyÿ<-ÿïûñú(Ÿh¼ÿžÿ÷ý¿øŠ>Ñyÿ<-ÿïûñú(Ÿh¼ÿžÿ÷ý¿øŠl(È­¼‚ÌK6=MKE5‘•™Š©eÎß§¥'—“Ì1¡|c~ß›™§Ñ@ XÑ]¤TPí̱Ó'½ G‘*;ŽÕÆO©÷§Ñ@Q@Q@Q@”PÑE J«cÿ!‹ÿúçþÏVê¥ü†/ÿëœ?û=,ÜÇô?õÊOý +–ñœM%ÅŽÀ 'Ý>ë]MÇüCÿ\dÿÐ’¹¿ãϳ̊Ÿ,sê¾”˜ÑÏYÚ0¸Ž\;`Ý}•Iª>É"ºªÿŸçSéÌpK!UÛiÏ8SúT:¤q¥æ¸½»í‹Ü¾‚Y7À '¯µKpÈþJ«ËõpqŸÆ4G-ÓÅ,P/ÊH?ãI¬[Çn«$(¨±òý '¸-&Qfñî]ÌÄ}à1À¬ÝM»Ç1¯NzU½-í¤³_´$lŲ­VÕ8îÿÑÑy8ßÒ’ÜO“ɰ•[nãþ×oçXm(g;àšèôhÃi®òBªþ[s´|ÕÎN<µAwjq݃؎V^ÖÁ,¼{T6M‹¨¾f\ž Óî—–UwuíPÅïc`w#ŠÕÎ÷Áî­etp³ã§°®‚¹ï36•;8;Œç¯Òº¤ESQEQEQEQE€(¢ŠQE1Q@Q@Q@Q@ÚǸÿyÿô&¬én®bÕJO+ÅŽ‘«+¿Äz†Î{c¥hÚǸÿyÿô&¤û¯Ú~Óöh¾Ñÿ=6|Ôƒgqua]\Íq23 ©®K?3š’ÛPÔ/Ìf£ýM·hùŸq^½—ŠÖ:mR œ/¼ƒïzÔ«klƒjÛÄ«³f»×oÓ­SÑîe˜MËÊn#Ú]%‰WnsÓop{Õ$»½kQ#\ÈÒÏrðÅ1!8RßÞ t^¤Öͽ­½ª¶‚8Tœ‹ŒÒ=´ù/oG»vÒ¼nõ  {KëëãiΰŽo1‚+QöŽä~YªÍ«ßO¦Íx—[´±Éå” $fõíéï]V¶ðíò 6j´7\}MP¿Ñ"½1 0E M¢Ü è­Ÿ—ò4ZÞÿR¸¿b‘Ÿ%.<¦Så… ëÛ·wé[ÕYZµÈ¹6Ñy㤛~oΧ  Fi-ã¿–(šWVQFI;EEáéYÍú;Ü;-ÆwLŒ½QsŒôçÑÙ6F+œÿ­oñ¬ùYW8ˆµ‚ñ+ò3·’*YïcœGóð½öú×`¾ÑPalÛõÕ¿Æ”x_G"Õ¿ïóÿ q/q…D“}ÔÖ`ÚÈoQžDäãŸÆ»ð¾ŽÿzÑýµoñ©ÃÚZFc[fz5¿ÆŸ+}c͘ÌÏ´·hÎ:U_¶G⩹›*r2v¿ð‹èÇ­™?öÕ¿Æ•¼5¤7Þ´?÷ñ¿Æ—+ œ\CµŽÇ,OJA,MýÓûÕÞ èÀäZ7ýýñ§ÿÂ5¤cdÿÈþ4r±<êúmÆÕÛ‰¿¥t5VÇOµÓ¢h¬ã1£¶æ‹søÕªÑQEÄQEQEQEQEQEQEQEQEQEQECkÿëþóÿèMST6¿ñî¿ï?þ„Õzœ<  qnß)B#züÔvŠ¡­Êå#Ÿr¨p ÊOGzkk«1Y·4¾HÊ;Ãã8#é@4VUƲŸf»{h¥g‚7;š#°:®v“ú±§ê1^üªdTW!®Cwê:ÐÚ+2×W¥Ë5¥Âù´xT-»…9µ‹Ql¬Ò3 ŒFK‚¿{+Û£EgC¬Û\˜Ä <»Ô7ËùT’oNAü«F€#71)+ç(#¶ê>Õü÷_ûê¨M{5­õ¼qE$Ë+Mº4 “´)œTí­Û‹i'XädŽÝn2åNxë׊ŸíQ³/ýõGÚ¢í2ÿßT‚áÆ¯öR®«ä—wkr¼õÎyô¨­®ž©5Ôí$V²ðÌ«¾Z±è©  þÕü÷_ûêƒuë2ŸøS¶Ônn.çÚXÕ YÛ¹‰'¾qúÓÓS)ae/•4ïrÛT¡³‚yç¨ÇÚaÿž©ùÑö˜çª~uYµ¸ü„xíg”ynP)ÚÙç׎)ñêé-Ô6ñÁ#4±¤¤îQµ[§äþ7Úaÿž©ùÑö˜çª~u0MÑ·Øû‚oÝ´íÆq××Ú’úél¬ä¹dgXÆí«ŒŸÎ€"ûD?óÕ?:>ÓüõOΪǭ£,›­'Yª¬gn\–+ϨïNÀcii;NÒ4f/”e]Ç'8é΀,}¦ùêŸi‡þz§çP®³D]boöƒÀéœmúñQ>½\ͤûU¶™>\tR{çøÖ€-ý¢ùêŸi‡þz§çUc×íd¼kuV?3"°e;™AÈÛœŽ‡¨§A«˜ÎË9VCš4b¿:þ|cßcí0ÿÏTüèûL?óÕ?:©²ë¢Á}ulÊòˆÀU+†fÇ#ž=êó]쵎gŠQ¼¨Ø£q8þñï@ ûL?óÕ?:>ÓüõOίQ@~ÓüõOδÃÿ=Só«ÔP´Ãÿ=Só£í0ÿÏTüêõGí0ÿÏTüèûL?óÕ?:½EQûL?óÕ?:>ÓüõOίQ@~ÓüõOΕ%ŽC„ucè ]ªÓÿÇÔõÍ¿šÐE@ ÓÊé"*3:îç1Ÿ¥:'rÏ¡w¦ËÑïú–ŠŠyLj6®çcµWÞ³lµ¨n®$Ž;ˆæ1€Î2¸Sü@Ÿ¼(¯U,ä1ÿ\áÿÙêÙàÕKù _ÿ×8özY¸ÿè댟úR’r@úÒ\Çì_õÆOý +;W€K%³Él×0#6ø•7òT€výhK#×­&à23éX)a©-Ö’ó$R‹q³y­¹vC6ã¯|ÿ:žýVçP¶ c*üÁšäÀK 7 û¹îxúиe$€À‘Få-·pϦk+O¶û>«p`…Ändyd’‡ql€­€Xr}j«Y³O2Åbév×bD¹ò¶€Ÿ/;ûŒdb€:+Ÿ’ MRÛ7H"ÎÂ## 3À Æ? šaçß,{åÆä ÓåPx=ù³K\çÙï‘e0¨á{¢ÎíiY|µ p0zŠ·å߉–O6wØmÇÝÚ¬3ûÂW·}(\ Á4$ ¬mRÎIo¤anһǷ.DLî9þ£žø§Ûªk\Ü­Œ°Õ•BÀA›Õ‰è}‡Z×¥®q§™¯bk’®Ó¶ã«,.qîOõ«®§ý¡™æ‘O˵V"ѰÚ3–ÎÍžÔ·Ebh3Í5Ä‹$³¾ÈÌóz 2wb¶è7 ã<úQzV'Ù'þÖyß÷ßhóEÃ/Ëåù{vîÿ{·ãOÒ-î줼7P)i] x]¤ó'•*×Þ¸'ràuæÃnr1ëX i ÌwÍ%ŒÖ© Tòc¶ê³¸Œa˜Ÿ¯;A4žºƒìøb²,Qˆ‚3/l è}¨d0a• ý)km¤{Ã%…¼Öv¬cGUO,¶’Û{qÆ{çÚ–(õ]y·7(û$Q¶Ü°ü¬§<ñŽ 7(®zê;éì‚4wa)T,yfgÈÛ»# cwZ±jRýì“$k‘ˆ‰B›VÎÝžÙ¦Õ409Á¥Gy(¹y›u¬lÆCœIüB¨ZXÞ"‘koäL hæy2‚G,CsÆï›Þ€:ŒgD¹ˆ• ÎSŒœgךt€$ëH]F2ÞœÖL$z,0Ϧ›‰R(Ç•åï@Ý9ã¶2F*´Ö"(¬ZÚ¦¹Š=± mA\îÏ͸~ïóàbå•~óõ¥¬½RŸS¶–{6º…b•p!ó0Å“N‡š¦–š¤Vnªó+ÇaTØÛpÞ`»G^Ô·kÿëþóÿèMY’èqs3ÈñEªêâÊe 1óŒí$zã]«ÈåG?t4Rž¶Ñ®^ÎËÌ1C,j K´¬Ëó# ÷ô>õО´QL /a%Ô©R¸?™§Ûéb£™¥i%YWm nf]¿‡üªo)=ýôhò“ÐÿßF€)¾ˆ<•Š;—14.Bçr–Ïàiòhѹ|ÊãséìƒÿdYò“ÐÿßF)=ýôh8´é!wT¹anÅÛÊØ8-œüÞ™9§Á§$BáÙ¼«#¸Èçô¥ò“ÐÿßF)=ýôh(´é¡Ó…š]‚¨£4@ü£¤w¤ÛXÃke?–V@ÌØåÝ–c¼TÞRzûèÑåGèï£@hª^JzûèÑä§¡ÿ¾]¢©yIèï£G”ž‡þú4vŠ¥å'¡ÿ¾RzûèÐÚ*—”ž‡þú4yIèï£@hª^RzûèÑå'¡ÿ¾]ªÓÿÇÔõÍ¿šÔ~RzûèÒ¬h­•ôëš`I"‘Ú ¬²̬qÎ1œÓ‘_s¼„|}Þ€ƒõ5%Ñ™mm®¤2ŸCY– ­„Ó=´ Ãþð·Ëœí_A[P0<š©cÿ!‹ÿúçþÏVê¥ü†/ÿëœ?û=,ÜÇì_õÊOý +Ääš<–ëºËæ†'síÆ1þ5³qÿÐÿ×)?ô$®KÇ?ññcþìŸÍjéÆòÔ‰»!¿ðš\Ï„_÷ôÿñ4Âiqÿ>ßÓÿÄ×3Euû˜{I7ü&—óáýý?üMðš\Ï„_÷ôÿñ5ÌâŒQì¢Ñ2øÎéåT]>#ž§ÎÿëQÿ •Úã~›ƒÐù§ʨéVlZÚà„hÙ™X0ïÛùUbòÜ.ªf$ˆ¥ýßl|øÇÒ¹>ÝŽ³s_þKùð‹þþŸþ&øM.?çÂ/ûü¹¬QŠëö19ý£:_øM.?çÂ/ûüÂøM.?çÆ/ûú¹¬QG±ˆ{I ñœã¦ŸúH—þKùð‹þþŸð®kbcö’:Eñ”Ê0ºt =¤Çô®ºó`ŽB6—PØúŠòÌW¨ÚÿÇœõÍô´mcZRos*]yâžæ?³gÊ}«÷¾oÒ¢ÿ„ŽAn¬Ö„Jƒæÿ ¡{&úãæmÞcgŸsUJ¬7œ’k‹œéå6Û^¹ÝòÙ¾»éSÄ?¾d–ßjrI?¥`…¾w Ï!³ô5 KfPÃqVû¸=sG8r›1ø…Ì®%´+û­“ÏéHS&ÑóãÖ«˜›ë¯Ü`–²ížÿ…3þY|âÓ÷˜û¹oð¬±oo’›åçnêl°F©¹w¶Ú£œ9MOøI¤û>öµQ&>æãþöñÛSežây?1ý+ ãíù˜†ëÏCéIÉ$)¾Xð8;¸5wêI±sâwŒ-cn7aŸ§éQNCâÊ?”ÿÏOþµQ’«Ÿ6FÅWe]Žç“ÃÿÕMI ¦n/ˆÚhãßkßÉóëÒ­XkRÝêdkdEÁòzØö®YZLƒå¶ ÑðÛ×#äªlñŽÆ©¡\ë.e0[¼wíÒ³Ž¯'üð_ûê¯_ÿÇ”¿JÃ+ZÒ‚’Ôάšz¶dÿž ÿ}RmIÿ<þûª;i¤VÞÊ&^ÒEÿí¹?çÝïºC®Iÿ>éÿ}ÿõ«<Ši(Ø=¤Ž’Á·ÙFä`¶æÇüÕš«¦ÿÈ:÷©¬©$1ø€ì‘®dwP"ó$SÛýߺËß>õÆ÷:ÖÆýÉÙ=ÄpI3ÜÉ5âA!žÓngÇ©$.M gµ$&i#¹‚+™^2Ø«Âò`nfݵ˜–#Þ€:ÃÀ棂hî`I¡mñÈ»•½EcÀCªO Ô— 2ȪdÚcÚ:só|Û³œÔZjt­­>%´5]Ø®Fݼ¿JßYÙÑ]Y“†Ps·¿4úåï‘¡¼ÕþÌeK¹<·L3’cÚ²®pqƒïéF\XIö ç¸åO³$~fûî,NWÎxâ€:S" 2ê*¹ä×ùÓë›-þÕ¥MrÓŒ,¨ï$Ž—+òœ]Üt"ºJ­"êâ5¤Û ª®W¶{TÿÙ¶þ³ÿß÷ÿm‡ü|]ÿ¾¿ú«´Oû6ßÖûþÿãKý›oë?ýÿñ«tPOìÛYÿïûÿ'öm¿¬ÿ÷ýÿÆ®Q@?³mýgÿ¿ïþ4ŸÙ¶þ³ÿß÷ÿ¹ETþÍ·õŸþÿ¿øÑý›oë?ýÿñ«tPOìÛYÿïûÿÙ¶þ³ÿß÷ÿ·ETþÍ·õŸþÿ¿øÒfÛúÏÿßüjåOû6ßÖûþÿãGöm¿¬ÿ÷ýÿÆ®Q@ÿ³mýgÿ¿ïþ4¿Ù¶þ³ÿß÷ÿ·ETþÍ·õŸþÿ¿øÑý›oë?ýÿñ«tPOìÛYÿïûÿÙ¶þ³ÿß÷ÿ·ETþÍ·õŸþÿ¿øÑý›oë?ýÿñ«tPOìÛYÿïûÿÙ¶þ³ÿß÷ÿ·ETþÍ·õŸþÿ¿øÑý›oë?ýÿñ«tP?ìÛïOÿþ5KäÜ˳2F›qÜ:Ÿ÷EhU&ÿŒßõÊ?ç%$“¤l‰,y ªXþB‰*ïFȨí!¹œJÁYØ-ÆW?ŸÎ–&Y'šDû‡hÏfaœŸä? ‘™QK1 Rj8îb‘•A`[îîR»¾ž´Û 6£0%Ã8ö¬ "ÛVŽêèêBe…V]ûŸv|À?„wí@ΞªXÿÈbÿþ¹Ãÿ³Õ³÷Ž:UKù _ÿ×8özY¸ÿè딟úW'ãøø±ÿrOý–ºËøþ‡þ¹Iÿ¡%rž7ÿ‹÷dþkZÒøŒçðœ¾(Å;b»ÎA¸¥Å.+GL°[œ¼¡¶Ã5œæ¢®ÊŒ\ž„šY—Ë Ó¬J¿qXgñÅ6ê?-.6Ã&çÚ6çŸ×Ö¯Á L.#¹ ¡6÷üý9«·1-ż‘¶>£5ç9{×;Tt±ÇâŒVþšaŒÌ¤mQóð¬ìW£Njhãœ\XÚ)qKZ7˜§bŒPq^¡kÿp×5ÿÐkÌq^iÿ×5ÿÐk“ÐÞ‰ÄÞ:¾±|®á<§f?í¿¥@îáát%]Í·µO{*.¡v:~ù÷£Ÿ˜Õi&Ɔ=kƒ©ÙÐz¦Š(ÉÇSFO­P“Ž´n'¹¢Š7SEP—·šrbwY`Pg¶*µÿÓµÇýñP¦y^;xCìÆâÍ´f—ý7þ}£ÿ¿¿ýj›íŸôï?ýñGÛ?éÞûâ¡ÿMÿŸh¿ïïÿZôßùö‹þþÿõ¨o¶Ó¼ÿ÷Ålÿ§yÿý7þ}¢ÿ¿¿ýj?ÓçÚ/ûûÿÖ  ¾ÙÿNóÿß}³þçÿ¾*ôßùö‹þþÿõ¨ÿMÿŸh¿ïïÿZ€&ûgý;Ïÿ|QöÏúwŸþø¨ÓçÚ/ûûÿÖ£ý7þ}¢ÿ¿¿ýj›íŸôï?ýñGÛ?éÞûâ¡ÿMÿŸh¿ïïÿZôßùö‹þþÿõ¨o¶Ó¼ÿ÷Ålÿ§yÿý7þ}¢ÿ¿¿ýj?ÓçÚ/ûûÿÖ  ¾ÙÿNóÿß}³þçÿ¾*ôßùö‹þþÿõ¨ÿMÿŸh¿ïïÿZ€&ûgý;Ïÿ|QöÏúwŸþø¨ÓçÚ/ûûÿÖ£ý7þ}¢ÿ¿¿ýj›íŸôï?ýñGÛ?éÞûâ¡ÿMÿŸh¿ïïÿZôßùö‹þþÿõ¨o¶Ó¼ÿ÷Ålÿ§yÿý7þ}¢ÿ¿¿ýj?ÓçÚ/ûûÿÖ  ¾ÙÿNóÿß}³þçÿ¾*ôßùö‹þþÿõ¨ÿMÿŸh¿ïïÿZ€&ûgý;Ïÿ|QöÏúwŸþø¨ÓçÚ/ûûÿÖ£ý7þ}¢ÿ¿¿ýj›íŸôï?ýñGÛ?éÞûâ¡ÿMÿŸh¿ïïÿZôßùö‹þþÿõ¨oµÿÓµÇýñPǹî%™‘2*€Ãž7sÿ~”¦ÿÏ´÷÷ÿ­K ŒÌñÈ›$L çƒÐþ†€$ 0Ã(aèFh¥¢€ @çj¨Ï\ f–ŠRÇþCÿõÎýž­U[ù _ÿ×8özY¸ÿè¿ë”ŸúW+ãQûû/÷dþk]UÇüCÿ\¤ÿÐ’¹ÿ¯²ÿvOý–µ¥ñÔøNcbŸŠk0WU?Å]ÍØãZ‚)f I®†'ò¬Ã2y{SV-· ò–9àZÔË’ªfO“ï(ÿãÄKdtÑ]H­Ér±îew_óŠ×üÞ•“;n!r@ˆ¹Sµ·qŽÍ×­L/"e–R};~&¹Ò*w¸ŽWÝã§=+ ÓË‘œí88­ß669ŠeÉ<†¬›½­s!Q·ž~µÓ†zØÂ²Òån7c½.*dHÚ7-ã¾:S1]‘•îŽi+$3bŸ¶ŒU’3év¿ñéýs_å^ojô‹_øô‡þ¹¯ò®\GCzNVïÃú„÷×* ’J̹uèIÅBÞÔÃd*îë]­ÇcªçÿÖ©Ïò9ùÇøÓ[ÃZ©ê±Ÿøÿíè§`8‘áWÙõÐRÂ1ªóòEÿEvôP#‰_ ê¸å#ÿ¿«J<7ªž qûhµÚÑL$øcRÀÂGÿ}ñ¡|3©÷HÇü Æ»j(¸XâáÕ>o’3ÿm×;¢OÂE®ÚŠ.8ŸøFu/ùä˜ÿ®«Wt]úËV†âdAî,C†<«ë]M\V"¸æ¬L¯˜»³æy{yÇLæµõ[¥²Ó¦¹e,g¿8¬ omç¸y­n<µVÉ£;$(@,r—eÏfFÓþsZRÎÁ-$’S,³Í(Ui%#;W8(§µ[  fèYG¨\/±”íÎÑU?´®í¿µ'¹„·XÊÀ’î^GfÚ?—j»Ü›è%Geþù.‘ †å%šyMÎß1ÜÇoN‚€"¼Õ§´òc’Þ!q)b«ç¡W–Ùœò8ýiY}ö¡mÖ57–¸“Ë Î6”å¿*»yd·F7ó%†X³²HˆÜê9cð¨n4ÁsG-ÍÃDWŒ°Ä£ý®3ùb€*_jW-r‘ÁÈRò8^]ÿ19¸û¼ã9ü)`׌ҾÛlŇ(ÁÎ~\ýá· =MZ—J†[¯9¤™WÍYŒJÀ)uèÇŒöñK˜‘— qp!}߸Ü6.î¸ã?®(ºv¡-Û„žÝag…gM²où[׃ùÖT†Ê(dIvä„B2„Uº(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*“ÈFoúåó’®Õs¨Oÿ\£«Ð#ŒÜÍ.÷uŽ6ÚN 8'ó§Ä9$‰˜¾Ð¬¤õÁÏ¥&Y Éå³}ï—rŸÂ{ ìÎܳ52áœHÛk;ÝéX:F¿¡u:CËä§›—“ptÎ<|­í] ‘¬«µ³ê œjìcFfö þ\J›ÈîØë@ËD`‘U,ä1ÿ\áÿÙêÕU±ÿÅÿýs‡ÿg E›øþ‡þ¸Éÿ¡%s1šÏý×ÿÙk§¸ÿè딟úW7âïõÖî¿þËZÒøŒª|,æ±N‘$XXïU\gÿ­O IÀŸj±©$Ú¼Ió»‹þÆ:ÖÕ§kQîRòç‘€NßâoAWüco%Â;3yG »=ªÕå¶Ÿ”α_ýsüê+«øTîÉÏ=×Û®9ÍÉPŠHs³Ë`²ÒB‰¿6Ž9üjá±²tmÐDÇ9;Pf¨‹›Y­þä¬>ë,C¯Ö–)üÎcE”1ÏÈß7åPYÕšló¼¯!3óÿß#5²TšD—½ÔV¼ó£Ûbeh€~—¡ªRWoÞŽFVµ¥.W©•H݉#HQÙ2d,¼.ãØœUrNF=«BG6‹m*íyI þ¼TQ*Kò}ÒN?¨ü+zS÷Ù•Hû¨­ŠB)ø£Örâ½Ûþ=aÿ®kü«Ï1^‡oÿÐÿ×5þU͈ètÐêKEW)ÒQEQEQEQEQEQEex–7—@»H—s•ð!\ ¶‘7$ðüÇn>­^‡¬º\ç;xê~µÅ» 52Œ |ãû­š™‘ØJ]Ñõ\@îj?ìë„ÈXÝÀÁé[gi2¶0Ù‡üšCÇ¥ÌvÒ®ÕH«ýàÔ­£^¸Âª¯Nw{V¸$}ÓŠx–Aü@ýEcÐì4‘·I´Sü1Vꦘs¦[¹ýM[ Š( Š( Š( Š( Þä;™yéÅOéMû,?ÝûúÿãSQ@ý–î¿ýýñ£ì°ÿuÿïëÿMECöXºÿ÷õÿƲÃý×ÿ¿¯þ55Ùaþëÿß×ÿ>Ë÷_þþ¿øÔÔP?e‡û¯ÿ_ühû,?ÝûúÿãSQ@ý–î¿ýýñ£ì°ÿuÿïëÿMECöXºÿ÷õÿƲÃý×ÿ¿¯þ55Ùaþëÿß×ÿ>Ë÷_þþ¿øÔÔP?e‡û¯ÿ_ühû,?ÝûúÿãSQ@ý–î¿ýýñ£ì°ÿuÿïëÿMECöXºÿ÷õÿƲÃý×ÿ¿¯þ55Ùaþëÿß×ÿ>Ë÷_þþ¿øÔÔP?e‡û¯ÿ_ühû,?ÝûúÿãSQ@ý–î¿ýýñ£ì°ÿuÿïëÿMECöXºÿ÷õÿÆŸiíEÚ:žùúÓè Š( Š( bU[ù _ÿ×8özµUlä1ÿ\áÿÙèfãþ?¡ÿ®RèI\ç‹?×Zºÿû-twñûýr“ÿBJç|X3-§û¯ÿ²Ö”¾#*Ÿ ÌIz°ÎpO|öªÎf ö¾5‘Ž6õj­27œÊgßËTäâ´,-ä{t‰8U%‘GêI¥RW‘Tãhè#}§íVð:ËÈù¶…l§5±åÇåùQ#)ÎZGe,Çž¼äõ¨¾ËåÞ@­š@ ýŸþ½^¾;aÚ€m¤çÒ°¹©BòeU f ‡ç—5—¤äçb„ÝÒƒÇ>µÒìŒÀ“?ßÙÇ=>•Y>V¶„—‡ÎÏ·ãEÀÊŽ)J4ð«ò–,xönßN*xlTFçÊýâ¦å ÀÞÇó­1my7JÀîÉôÇ¥0$2Nð”]©è»qÓžÒ„ÂÆbÊmX-ÒJŽz+â0ßLñRÜjPË ¨:m&TÏb[Yå$p¡HÇäi·y¡eBçʨ~YíWfL—ºUÅ©1F+ÒOC϶¤x®þßþ=¡ÿ®kü«ƒÅw¶ÿñíýs_å\õÝìoGrJ(¢¹Ž¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(–¯Î™?ð:ýkŠ)uÁ昱è3×ð¯@tI¤ŠOPj/±Ûϼ•p÷ËšÞDÆÓ˜Û=yçÞ”Fª} v²iör®Ù-beÎpV™ý•§ž¶PþTî+i?JByë]¯öm‡üùÃÿ|Ñý›cÿ>ÿß4®Kÿ]¯ûŸÖ©ë•Ä1ÞCg;ÁmæÉ.ð<¼îÛ€~ñùIü+BÌmµEP‚ÀØn5^ûJŠõ¥&yáó¢ò¥òˆלg úžž´†Q!.¾ÓnÞhY‚ò©<Ÿð¨-5 èœOy–I&˜YAb¹Û£Ž:稭š°ÏæAus±VxÕ—kÏ#=†pE!Ò-ÌqǾ]¨ò8äupÀöÿhÓ£ëÞE¿wmäï…f|Àwn ayaíD:÷ž<¸mã–å¥*Ç8d?)lïÇ@ö«réÓ*+´¿»„B¤6Á6}r Ò¶œ]I{w$±¿˜“1MÈpG.:襵íÙÐï®›ý|O>Ôr>M¤àqéŠKf[+;yn£¶ñïeûPRF?„Éö«Öút0YIi¾I#”¹v‘²ÇwÞéõªçDB»~ÛwŸ'Èg4}—îöõƶÈ$– 6šÞ/,<›Âœ°wÀašžÇQk˹âƉ2­L©Ç)Žúôª7Ú<²Kö{U™ “ËóÎP‡nJãvpN iG§"ßý±çšiT2§™·¨POãšRíQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ζ?ò¿ÿ®pÿìõjªØÿÈbÿþ¹Ãÿ³Ð"ÍÇüEÿ\dÿÐ’²õ½2}BHƒË æÇ\…j\Çô_õÆOý )ÔÓ°š¹Æ[øNþ;±+µ¾Íû޶séZØ3!;pxÍtT½F´0Æp$FÌ_+g9ÁÅé7f ±˜w%¾cƒ[”RQÌìË!T˜÷޼Ua¡Þ}¦KÅ„ÇñZèh£”.d.bÍŸ,‚sɨ!Ñ®£½’bÑ”aÇÍÏAþ½E `\h—2Ȭ Ckgïv©%Ñçv;^=»vžõ·E°¿ü#·ŸÞ‡þú¨ŸÃº™'aµ±.sü«­¢µu$ÌÔ"™ËYøzö/5îL2¸D õ'ÓB¥!Enª ~”ú*.ÙvAEPEPEPEPEPEPEPEPEPEP6¿ñî?Þý ªõí–ž²O{e2w?tz‘W-ãܼÿúT2éÖ÷ÒIç†Ê1 ÊÛOÌ€ÎâÔ´Ùçò¡´‘Ø©(Þ_vÀç®Ò*ºë[۽ͫ;Ê…ó\»ŒÖ’h–Q…òÑÕ—;Y\‚>@ŸÈ |;`¨¬®¡vÒœÿ:`QºÕìvÞ%¥¼OqmK¶La•y?t’?UßµX­Õµ«[4ñ‰P0ã×ðÍ,:>š¯4q)`ªÑ4~a!Còó֥þǶan²4²%¹Ü‘xü¨H#¶™¥e)å¾Ïž=»ºr¾£žµ^æçOµ¼Kia]ï÷q·òÆsúb¯CÂÒ•g>c—;˜œ:z:TSiÖòÏç>ýŃ‘À8  bîÍíüÔ³ î*È8 Ѻô¡¯låà6m”%KP¤¨Ï\û±>kåa™ãS°¯»ÂÑ&“i(o1·g9cÎFó  ÐÜÚܘÚš9%1>H%NÜñŒŠž´žYÒ;lù«HíŒçó7ö|;qºLù¾nýçvìcùqA°ŒÍ,ÛäódB›÷r úP£··’4³ÞmeÁQTZh¡½¸†k8Ûo—å‡ÌÛ‹psü5§k) –Â(PIÉÅUþÌ·Ã’ò³¹Sæ;†Þ˜>Ù?SQÒ乊w>A•$‘‚3ž öâ´"‚ÞU'ì»pÄaÓ;ÒC§Ã¡„ÉPUc†úúõ©màñ˜Õݲʼnc“’s@ ö+oùàŸ•b¶ÿž ùTôPb¶ÿž ùQö+oùàŸ•OEAö+oùàŸ•b¶ÿž ùTôPb¶ÿž ùQö+oùàŸ•OEAö+oùàŸ•b¶ÿž ùTôPb¶ÿž ùQö+oùàŸ•OEAö+oùàŸ•b¶ÿž ùTôPb¶ÿž ùQö+oùàŸ•OEAö+oùàŸ•b¶ÿž ùTôPb¶ÿž ùQö+oùàŸ•OEAö+oùàŸ•b¶ÿž ùTôPb¶ÿž ùQö+oùàŸ•OEAö+oùàŸ•b¶ÿž ùTôPdÖѽȅUc]¥‰Uíê=ê'µ‰Uš) õU#>ÿ-MsU'ºúTÞÚímŠëòíÿV‹ËV¸0PI8ª;ù _ÿ×8öz}§ü{­2ÃþCÿõÎýž€,\Çô_õÊOý )ÔÛøþ‹þ¹Iÿ¡%:€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€!µÿuÿyÿô&¬Í[M¸Ô[»lŽ\ɸRÙ@$ÇÒ´íãÝÞý «?W–î+WûË ½Äq³‘’Ú8¤2´ºó™Õ.JF`ýÓ a1@¬IÇ ëïš‹þÛ¶…w)D“`’pv9Ù´ªðš´ºÅá¾{ï]Ñ«1%Ã*ÞÀ ×~ìcï  ÃÞµëãR¸·Tíd&6”²çkcoʼõù¿úÔæ¼šßí¿>öYcزt@ÁzãøA&€6(¬˜/®î&Ž$óæn~pv2—ë»ô«Öòù¯0ßl“oÈs·€pÞüÿ*±Ed\jo¢ðŸ/ËFJó¼îÏ?Aþ5Z fê•c‰_pùœpT£08 q÷}{ÐAEcÚjÒ\]¢²F±¹ ·?8ýØ}ßNqWìåóí’Bñ¹9ù¢9SÏj³EbÍwlÚƒ1ŽO*EXÐ ¤ É$ôäÒ®¥t=#‰ö³ ?;°8V8úóŽô³EdÛÝ\ {Ù'ž Âìp*ï{V ?(4ê(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€1µ?øü_÷ù­fËÔÖ–§ÿ‹þã5¬Ùzšé‡Âc=ÍËOø÷JŽÃþCÿõÎýž¤´ÿt¨ì?ä1ÿ\áÿÙë™îjX¸ÿè딟úS©·ñýýq“ÿBJŠêî5S;¸áUU™~‹ÏJOEVkëe’Þ?9K\óïã9úc½ÞÁo2Å+:³`gËm£=2ØÀüh 4U{{È®d‘"“fhW à€Ä`óéQÿiÚ} Â]Õ·ù{š& »û»ÈÛŸlÐÊ)›ÓûËùÒï\‘¸dué@¢¡ŽâL›-ö1ô8úŠ“rç†}3@¢ªÏmo2Ã,›]€<+8ˆáyãœRÃ}m=ÃC’ãpå ƒ†ÚO ŽøÎ(ÍÊ»œa¶üÃû~tíÃvÜŒúP¨¦†Vû¬Ò@X_[³jù¹Û÷NÝØÎÝÝ3Žq×è.à¹y’7˜d˜å>žÿ…OES¡YKHÑùK¹„‘²¾£pä})æö´{§óc‰fß+?Ù#uY¢«[ÞÁp\#2²crH ô;XØÔûן™xëÏJu³Å&Wu£$õ§+«c 9‡Ò€E42·Ý ý*¿‚H¦‘LŒ!mŽ<§ÜŽ‹Œž£   4Uxï!–Õ®#fhÓpo‘·)A\nÏ·ZŸrîÆá‘Û4´S7¦ÝÛ—¹§È ¢™$‰m$Œnf'€*ºêV¦Ö[“#$Q ¾ôee㺑ž{q@è¨ê$¶KÞ4n_.&v9ÿeFj/í+R!)#I挨Ž6sŒã$3ÆN(åZêú IR9|Òî Ž'“…ÆOÊ#ó©#žcI#‘w+ÔzÐZÿǸÿyÿô&¨e¾³²i ä¨äw ä…¥´9·þóÿèMT¯´é¯îTÃ?’"‘·°8höñùÒßö¦˜³?úD"@›™¿ÙÆï½ôæ¡þÕÑÕ#o:¬K/ÉÜc'§‘ùÕe𵊙#F_-“f<µ2/Ë·!ñžÔÙ|;$·!ãâT\I´¶Îè€/E}h~Ô×0 qg&Ö/·©Ã1ë‘øÔñÝØÈО2Ó3yX’9oÇÖ©Ýh1Ý=ÐiˆŠà£˜Ê† êž¼(àÕ›K³HR)•™Ò8UVLAÓÀ—Q¹ŠÖÊIî#2Fƒ;BîÍ0^ÛDÍýË2ç ½\g¥X»n-e…Ü¢ºà·¥P¼Ò#¼¼óž\6C}ÐXcŒØP†£¥ºFFàßpçw88DZçÚ­ûP 3& œñÂîÿÐyª_ØÁdó!¸t *6ô3JºB+¿»P@”0Ï–Ÿ^  )%™Š6þLś銒äà rO2áŽÜ¾•RÛÃQܻߎ«ýÐp:U¹I¡8 ¤f€)ÛßÚ›{gdòdÝ[~m¼z}E:+»XÒvF©.Æ;yfÀ==y©"´Hä·;&÷o?øíT“Ió„ÞtË&ù„À4@…lÓ¿Pã¹Óߘž@¿7àqôïMƒRÓÉ}ŠQ” ÷‹xzf—û"-›K2„„@£åÏAÛ­3û˜Ý ÆâÛc*JŒzzÐõ0ý§j…óvgîó¶¨ÞjvúS-¹…¬Lê qÑG¹þ•v8¥I÷™¢„G9þñ5ÍŒW%#&?,ÁÎw}h'Ô-ñ4†Å7ð3†íNûNÉØBp9Ç\p3Þ¢}#ÌYÒi÷Å*$evvSÇó£û•`£b‰"WÚ™ÈQž˜éôÇ¥\U·œÌ»ˆm’ü½O\ÌUyõE·½0¼25ir¸ÎŒæ¬Ä’Feieß½Ë(Æ.:_Æ¢m6ÞKÉn¥I b£*z½èU²Ù¿ínqÐúgòÀ<ÐÚµ’¶ ÂýÝÝñŒnþ\ÕÑ t[CÊœ+‚q´¯Í¼y§C¥Íor˜dxQw'ï·–ðP›]B¬TÈ2!ÿxôùdH"y¥`ˆŠY˜öFÊÂ[[ku¸*èáåo¼\wŸÀgÚ­ÝB.m¥‰U(H÷ Ž£h6æloé•?ŸÓÞˆïÃ,’#Æ"r„}ãŸøj;½6;«¤œùe‚…o2 ù\çŒô¤›Ló–e2ü’H%ØÉ‘»ßÔ{P‹©[=Ìp#34‰½ ¡Æ>´è¯à”)·s´k»¹PIþF ´Ó…§ÙÄScÊVB Œ2“ž©§Ji-¤†[–bòù¡Õ6•9çóP¨Ù–À¸_»»=€Æzý9§¥äÈìv¤©'¥UþÉ….ä™@?8hUˆ;BðÞ˜Š|3[À‘EpÊ<Ðï…ão÷Tíýzžöëì–í7–Ò`… ¤I8ïõ¨!ÕmÙWÍc —d(áG{Ô÷¶Ñß[¼a°Ü1ž‡85HèÑɬ?Êc 1°ÛWÐg?Z{ûq ò‡,°ýì)ÇçSyèZ4' Ü£Ö©1öÝl¸nÜ*|«×'nq»žµb8fI ã)ÊïžÇð  tQERd Z(¢ŠÆÔÿãñÜoæµ›/SZZŸü~/ûüÖ³eêk¦ „·7-?ãÝ*;ù _ÿ×8öz’Óþ=Ò£°ÿÅÿýs‡ÿg®g¹·BÅÇü~Åÿ\¤ÿÐ’ª_[Ï,°Olbó!ÝòÊÅT†\uÕ»øý‡þ¹Iÿ¡%eëwwÒ@ ” `Û¾PsÓÔUF<ÎÈR’ЏÄÑ ¬+·?fòÕUÁUB¿/óÓ5=Ä÷poKVµC¹“Î`Kgƒ÷@¸æ²´ïÿçå¿ï…ÿ ³c¨^K>Ç›pÇMª?¥jèÉ+™ªÉ»­l¦‹R’}‘CÝ•ŽVo4“ÄŸ¦zÔ-§ÝÈf¼…¶’ãÎ.‹ãƒ·nÜ»×5 ýõÔSåTŒãjŸéUÿ´¯¿çàÿß þ•=AÖIØšOþîØ,VòlŒ£¦óÜ[;Á N{vúÔ³i2Ë5éAIpŒ3’ÌÄã¯Ë•tÕOíïùø?÷Êÿ…/öïüüû埰½´I¤Ðåubaµ öƒ/Ù•Ùc  ^»zŒgîÔÿÙH²*Ä~ϰ’Y”Fß0ÜFzõñTÿ´/çá¿ï•ÿ _í Ïùîï…ÿ =„ƒÛD¿}§Ïqq)‰¢\"$»‰Ü¡Xœ¨Ç9ÉêE6=:TÔ^é5XÄžL~k2–nämù Ýj˜Ô/?ç¹ÿ¾Wü)ßo¼ÿžçþù_ð£ØH~Ú#N¹žì¸´‰ƒùœw–÷N=qÚ¬C£Iø™ŠL>R&22ȸ@¸Û·‘Æ~ðëÒ£û}ßü÷?÷Êÿ…n»ÿžÇþù_ð£ØH=¼GhVr[O#=²B‰C¹U”ÊTœ±Èþ}zšÜ¬1}wÿ=ýò?¶““Ô¨ÏåQ:n;—©lf6c~ÇÌE·iþÐ1ÞËÛŒcïœûb§éÓéÆ.q:¹@¢L.$í^¿Î³îuĺ™r]€WŽ~”Ïí;ïùø?÷Âÿ…R£&‰uQqôË˨.¾Ûäyò•*ñÊÇ…lªchÚ=ÆNMLl._G»µfŒK6틽™S#…ÜFHïœw¬ßí;ßùø?÷Êÿ…/öïüüû埰½´KÒé“^Ý­ÅêÛåLkä«]ªÛ%FIãŒ:†- Çö¥xa“ÍY?œÊ\3gk¼c¦rzt¨?´¯çàÿß+þi^ÿÏÁÿ¾Wü(ö2l‰¦Ñn&¶Eu³wXä@ÂG¸Œ2áy#ÎZš!âÔË,r䆙uùíÛ·‘ǯ~•…i®_»Ì'¿*ÄëþÏÒ¤ÒõmIî¦K‹Ó,`á DÉk jks{IÓŽžb%Ú(˜F>ó¯V÷úõ¤Hu8¾Þñ­¢É;¬@;U~o“ýœþ•Hj7ŸóÜÿß+þ¿ÚŸóÜÿß+þ·±‘Ÿ¶E‹›K•ÐæµXžDu`’4ŒÌßÅ£©ëÐ „iÍ5ÃmŠÜ<³0•Ió0 g»Îzö¤÷óÜÿß þ¿o»ÿžçþù_ð§ìd/m”Ö¶Š~É•Y ViL)#gs÷Mii=¶—o ¨ÕNTXœ~µöû¿ùìï•ÿ ³auq-Ò£ÈYNxÀô©•%qª©»o­¾Ùc=¶í¾jÝŒã"¨>—qt&–âqò2°XNäùTËÏ\ô㊹©ÊðióImußÞ°?µoÿçäÿß þƒeÊi o¨Å¦Gmm$D‰Ìw*ÚÆöèJ«q£Îë@"Ä>O7î¹Îõ;~sìq“Tµoÿçäÿß þjßÿÏÉÿ¾ü*½“'Ú#rò£¨Auh6ȤŒ¬²2}â§<)ÏÝö¬óáóöy#Ý»$`1d«³0öS»fªjßÿÏÉÿ¾ü(þÔ¿ÿŸ“ÿ|/øQìØ{Dt RÊ$Ú«·+…9 xäV^³5ÌwGl÷ É+¶øÜØ‹Ž¾ø­=5¼Í:'%×v~¤š«}uwm6Û5Vw‘³û½Çˆóýå¬Ù¡TEf÷’-£»›8Îø€ÚfU;²G|þtËq«ºkÖf|´I¶F]¹¹ÝZpêÿhxá@Éå™AdÝ·v;:p¾¹ò´æX’Csþ°†Û”žá@B=h½ï›ssÛBA¹@Ýòí;¿»è3Ö´ìÍÓG§›ˆî‘òûÀ`ËÐãÌÏ?O~µ,šƒE%Ø’2DE(êÅŽ?_Ê­,³(6—'ÌÎ?Z©¬Á-Ý¢ÛE ʲÈŠíµvŽNN¦*µ¢\E,2KlÆãìÆ`>ó©îÞ‡­ê×76ÑCöP É(LÝÆmËü굦°òG’I*’:ôW<ÇÔ`ú@Pê_f“Ì{’C«"ì`[å;—<3›ô©™5n¯&H˜¤€”ÿ-y'¸ãZŸûVY-’Hm×Ì3,oH.}}µ-β-ÍÆëw+á¸ó2¦ò¿—ze›Ü¤(—&æBnB£ÚJã9 “òõ«Z²M6Ÿ$6é¹åÄ}p<žÜfŸÛË !Ò]Ž»‡Ëß>ôš…ÃÛZïˆ)veEÝÐ`¹?LÐ++k°má—|B².ØŸäû˰g#nGáLß2A~+­ï>c;XQœã¦Aü*ÌúƒY¼q\~ýÎ7¼JWh-€Hç'ÛncÓï&}’I¸WhÀöÏõ  Ì·ÉqÅ%Ó€# Î8eÁÞ[ý¯þµFë©%°@÷•Œ™9f °îàcø±ô­ ›«˜µ¢UAn#i$sÉÀô玾õkãè¯æ ¸t|í9ü Oi$­* Vo3ÈBùfãÿ³UMjÚîêXÚqé²ÎW8\pryÕZI§mD[BñƉ‘Ë®âÙ8Àäc¥@Ï–;Õ²$ûKù>ñ߸àÂ¥–K×Ô xVe‡(Jœ2ó»=—LÓÆ¶CÛ;6å ÏÊÀ¶ÜƒGöÜ{¡ÌO¶L#ŒI?•^³268˜1‡ïqž½½«3ì×o­ÉtaÛ Ÿ#ÌCìÛ×é»<çÒ•u¹G˜ïoÁØcNX†RÙ㯵 œÎ#tŒùOpäúöÅbCgsö[]ŸiImídBIçÉî8?•;f¦ï.éçY }Ĉ…Û¸tlã§¶kJîk¶ÁknÑ¡ti ºîáJŒ‘ýêŽME£köve…Ä[·¹ˆR0?àTX‹Øî"Ï‘VfPœŒ®á†-ì;µ¥lÅä¸âl p7ô<»íýsT_ZXÈÝå_dªãÎ;vçÚž/®M¥ìÍ©·f †Îq@ÞAxúÚ]Ç´pmŒ6㸆ûØÁ¯á5 mA­Fór¬‹#iÌŒ· ŽG8ùªüºšÅy ¹˜>Ð]yÚ[¦}?:»»†Þ…0Äs‘ë@ñE*ê3‰ÔËn€ Å•XnÈ=»Š©,z„Zm°G¸kƒé–>fËj/î´ÄÐ}£ÉU w݆ÎsïéJ5¦0[¸²”µÄ~j¢üÇn'Q@ m÷» ‘<åWÌKÔíÁéß5P@YÙxÞ80Ø~fÀÞ¯>¬åS)LmF;Yò@éé“Ö ‹Z—sFö’I"ÈÁ–%-µCc·SùP³šã‰@`y˜Áà}ßoëšÎ»‚ñµ¨î£Z;}¨±ÜC}â9þýY·ÔLìê¶Ì#: ÃçŠþýz¾Ë’0q@ ê-j»Íʺ,JÃiùØ»‘Èç5[ЍfuL–èÜYUlƒÛ¸¨¬5+æÇuuö”ƨª‚?¼@þóqϵIs¬}šGG·bQNJœ€ÁwmÏLÐ-ÄZm‡›ö©n7Âòð[Ý‘ùÓ‘ïF¦îþpƒk’¸8ciž¾Â¬i»J [fó÷cfáÀÀ9ÏãK¥çܼ)m6Å,¢M§nåëÏJµhKYÂÌ%¢ñ/ßéü^õb¢‰ãVtØÄW9ÁôÍK@ÚŸü~/ûüÖ²„¾nï—ÿiOò5«©ÿÇâÿ¸ßÍk,§—Ÿ›ýà? Ó„Â[›ÖŸñü†/ÿëœ?û=IiÿëQØÈbÿþ¹Ãÿ³×3ÜÛ¡bãþ?¢ÿ®2èIXÚøÌ–ÿFÿÙkfãþ?¢ÿ®RèIY:àÌ}úV´~#:¿ 1öÕÍ9q30ì* µrÀaÅuÔ~éËMjE~ÞdŠØÇæ«Wo@b¸ã~µ\-Þƒ¨µ#Š~ÚÀÉ«¹K¶™m*\Û¤ÑçcŒŒŠ˜ .;.)Ø¥Å3m.)ûhâ€oÇþ­?ÝËéÓÜN×â-› úWRŸê×ýÑ\µ¥{ÒV¹ÊÝÿÇåÇýuoçQÔ·ñù?ýuoçQ×D>c-–ŠZ¡Cw7Ùíd—Ú8§É,qcÍu\œ šÍÔn–Yá·WýË8óp:¯ÿª³©4‘pÙF– $ÁA9b[¿­jYFÒ8ò¥Y<¹7*“÷° Ï?OÖ¬X¬*ÿ»†5Âw®ýUÑ]Mu¾H”DŒ¤Ž2½ÿóÛÔíH¾¤°Ë.Ó“•ô§ ’æ! 2J›ä ó`s•ö¨ “͉_Ö»©M4‘ÉR ;’ Z-jdoMÿÔú7òªµoMÿÔú7ò¨©ð²áñ"æ±ÿ ¹þŸÖ¹jêuùÏþïõË×=-ªnRÑ[…G<¢ZF @þèÍIT5 µUhW“ÀlÇ·vEE]¾ŽIÒ-º´@šŠïì{È»IX™q‰]›;9ûœô©tƒ»H³lc1CØ¥åÀ2ª4qM¹•»ü˜þµÊt“Eo`“$ˆˆ’c*§åÛòãîöàzv¦ùVB(£)ææ=¬Ç ìAãùTwJη¸(q¢°®޵ÓçHáX­í¬þk5›¦:´hÚØ†¹fþ !n>™¥Ž FkY3óÆ ˆHÇpÜ1Ÿ›œãΠG-ã"A²lâ6bC1?xü¹NGÒ£]"V…D¦!*ÃJÜlläw  ÷)kwYYXFÛ²¯´©úƒÅ3ì²J!TŽHsÏדÍfÚØ\ ¹Ùo>Jžbñ! ~fÿ^¶®"ÛÉ R¹úÐuÓæ´}Šë0%æÞ¥½fçéRKkcæÈÒˆ÷ºmÏÔ_NõEô‹©J´ïž^аù®áJîÿdò8Çjž]9×d_½Ž8×#vݾæ€,¼VR”fhÏï|Ñóup1š–_³ÜFðÈQÔü®¤Ö4šÞ[ÇBQ²Bò»IÇÍÇ^=êit¿.ÝʀωOî׿,ϹOÔq@M…‘*¥C08¤bIóÏ8÷éM¾†Æ8¥k•`³°Ü¨Xïoe^ÿJm½¤Ñ}YafRÒNäs½‡;=9?•M}o$ËDW̆@ê€{cÛ­,fÄMÐìÚ‚L†Ú{a¹¦Eoa G`Œ pÙßœ0éß·¥A˜àî¸I'’cÞŗq=O¦G>ÕPhL°Ä¾TDÆFWÏ“l¸R¹'øO>ôªðÚ™m¢G%Î ÷vçò¨WOÓÚÝP"¼y!xH9ê:óôªòi.ÑÜ¢%Kˆöù™%âùí£QÔÔÐYË Qª[[¡3‡pY¤ ê3š€'d·³‘îH(Ó2+6 Ïð¨ýZlŸb»—s°ó"r™$¡ÈÆGlŽžÕ&¡j/m¼“·nõf Ü•.…#oDh„FMè2G—óÓ¿LPˆ´±…üÒ‘©à†fìxöɦ‹[ë14K˜­e†6đĊ‘°¨ùO_ëRÞiÝÎò»¢–Ï̬ijnÐ8žs@ä†ÂQ½Ù>fÈe—8ÇP}(6ök$¹cwS¸ 1õ8Î3ïY#J¹º†bÑC‘Ž"¨_”(n{8«ï¦°Šè)O6b¸|s€ª¸Ïà:»n!†¢„ ‰T,aO…X¬«+­VÛ _=ä9ËlR8 O­jÐ6§ÿ‹þã5¬ÙzšÒÔÿãñÜoæµ›/S]0øL%¹¹iÿéQØÈbÿþ¹Ãÿ³Ô–Ÿñü†/ÿëœ?û=s=ͺ.?ãúúã'þ„•“¯\$>B´.åŽw/ð€W?k\Çô?õÊOý +'\“dçwÝc‘õZNN:¢ã'fe-Ý»J³"–ÆYz.zþUz×cBŒ®­½w?†©yˆãæçä Êþ•vÏj¢²ã¯oΪ5¥-NŒ#ª~Pÿ½Š„ žBÁ_‚zW/­êWV—!‘ä*SÐë]ª–‡4©7©²—ÖÏ&Ä—yï°gJÌÕõ¥¶˜GlûˆV ñž1\òÈïÕÊãñæ§‚'UÙWäå Ç^k9Ulq¥®¦Ï‡/g™ãµ`<¸Ðãjõú×Bce8e ûŠážâæÖá^1ž: ¼u ñ»eFM‹…ìßäšQ¬Öá*WzfÚcM u‘?ïªÍÓ5H’˳€áØ|Ç'£e-œ€ýâlüß&+¥Næ.Üî#ó£ÄRÈç!?vp}qšS¹ž :iPyl8;Šç֯ʀÜÀç;†à9ö®?T{”Ô/fÇî•ü¶îœ}Þ>˜¨”­rÔS±{A¸w–A#Jø³¼g9÷®ö#˜îå^caö˜¦‚iS±»“^™n·‰±·(§œ çlÒ1±Í]ÇåÇýtoçQÔ·_ñù?ýtoçQ×t>–[…Tw2m¤‘Ws"ä ¦ì7íæHÿ!À—nì‚ËÒª‚ ?¯J·nÆ›(ùƒ—-ø ÎLlõ#ú×¥vv(ØÚ°›æ|žsV¤ÔÖ@Xç¿ØVU«bFÁÅNÊ í·æ%:É«–ŽŽÎá8äoàxÿÊ™qBG–PðqPÀØ´R;"Ÿ¡Sµ3í–û[åÁRéÍ¥Ë œy¢%5%G‘ÑNY1¸zfŸYöoVôÀ£¶8¯IÊÇÍ·¦ÿÇâ}ùUZ·§Çâ}ùR©ð°‡Ä‹z¿üƒ'ÿwú×/]F¯ÿ ÉþŸÖ¹Šç¥±½MŤ¢–µ3 Å¿_ôÌDÊÅùÀl`ÖÕc\úˆòÝ"à†8ê}MeWbéîwú1΋eùâµSQyâºY`yÆìîŠNÇw«šJìÒmàíˆ/8¨¯5&Óäm©ïcþ¶_/¢Ç&¹Î‚¾¨]í†"áÈ„eÀya„„÷ËqO“R¾´Š*ùí<ÆÈöìaŒçþú{ûN&—ÈPVàǽc“*:góMmbÞ{y.Çž?3jüØgðäSE5Kß6uùËFr›~a±†G¶FqùÕû{·—ì¬ò…ûK3"l9dÁ+Ïn0yúR\^@ëq ÊŽ2ŠFÖ%ËùúÓW·{¾\Š@ÞPü¤±\8ä v². Úý™Ýd±° Ú}gY5ÔéÇ<û%ŽK¬Í¸²±Ú¾Ã泊ߎA!p†ÆÚw.3ôõÕFÔu3jÉ ß$…Y¸ÏÊ»p:¯eszz¼wle%RìÒç‚»sòœöâ¬ë^`Ò/<§t“Êm¬‡ ;TRê±(ü‰^)áŒg<)`Àcž•#jöIoç´øBHéÏçœP4× !x/.å‚_´÷›‡‰Bª®æá†sÆ«}kzÞe{™âY·ˆÂ|»OË‘ýïâÍDº¬2¤mfß(ˆîR6Ÿ~*AwÚ¥€G(‘{~ìá‡Lç¿ÿZ€3õY%[âÒ¤»ìÈ®@vÝóqѸÇ^‚ŸrneÓ®æyX‘¶,YB¾3yàV¬n$‰\n”ƒYÑjŬîgxQ|‘Ÿ-]™ÿàCoËúÐWZ¤Ë¨D–ïÂåF:î Ÿ™qÔUy5ánY£r+4Þ^6îF;qŸQZÒj6ñ]$,q–ÚvŒçþ Öm<——÷¡Snsxd«§ß]5Ì0»ƒò¨1‘óòÁó ÿ{ŠÓ²˜\ZÇ/›æÏΦyô5ÕìÇ™ºF\¡Û÷Cc?îš§n© (f)cÁ¶îÆ;p(6?µÁö‹ß1ÕYW晜7Ï…ùOÊ¡}»U›;ËÛ¶<Ô\ù»ÝS!¶²€GçVáÕ-g¸xcv.›¸ÛýÞ U˜ß̉\n€8a‚? ÈþÐo*üÃyn]'s¿v¯©Ç¨ì3WmîüæµË°2Ä_ËhþféÎzþ½C°çSç±ÆÌòdœ|Ë´cõ©F©hÓB™`Óp„®;ž?C@ë+4­e[þyÈ`³4YòËÏP*„—ÚªÏ MIo ¯÷åÄyÞ›ùV˜Õ"X•Ý$åhÕU¶TÈÇV£¸IYD{ˆdozÊ–îù.&d_Ý$»ÊûØ ×ý£Ký¡rf¹Dd‘Ñ|ÄHÆí cånróÖ­ê7w6žQ‚ÞVGTËÌP‚ÇøM6Këiš[IT´Š„¼`»që@ã¸y&²¼–FŽ9ËìÊ®Ò>@Fq“×לSQ¼Û8b±˜XBÎW ¼·^‡n?調§möU•ÜGû•—hÎ6•ÏËÇ=nÔŸÚöÝ3&ô*¥6ß1Àâ€)Zj7“dr–¬¡zîgRsÿšuG['0ÝFò}¡—Ì<®0HÏ'ƽkÅwâ#r²‚AÚxÇP}*-JêâÎØÍ 1Kƒó %)Ž{aNh´º3¼!ä ïn²´[ï»úUmb)ç¼¶Šqº9>ìïåÁ;zãÐÓŸXµ‚GK‚©Ê›– Ç~õ¡mn¬®®ÈBrqÓ¡ÍKcHeÈó%G“¿§µná•gŠ0p‡ËïêAÏëY%£¸?+w«Ò"Goå< 3©;Îy?áC`‘fá!Š™Øá‹íÚ¿í±£Í…눕˜§v@è9¬kòb˜Â¶£`)þ¯æ>sæ6}Ei Y(Üêïu™ÐÄv*ò¿w9ª¥VâÚõåùÙKשî•sæGeÞdnN*Ι.Ë£‰©'¥7+‰FÆœrÂ_.¥ˆ‘öÈÍz,#Æ@‹ü«Êâ.ÒÂrår¿ð!^¥m¸ÚÁ»ïyKŸÊ¡^åiÐç.¿ãîúèßΣÅKsÿsÿ×FþuzøN)n¬ÍBõL2Ûùd±;~aÆ=kFYRšYI®Y%k†0+fFȸý+:³²±¥8ÝÜÕ°¶6Rùq•XÛ%‡ÌNGÝý+-Á‰Ê7éïïÍt~TK ·tŒÊ2ƒÞ¹ë˜Ëj,¨üÊÄqŽ2k†úvÐ’ ¿ÄôÀÎ+BÑ@ _ùVlv¬àòÜð1в,¼²ÉÉà Çð¡Ø³ ‚È¿ÝçÓ¶súÕ¦‘eºÚKÊãðëúÖ=®ékq*JÝÙþžm御¶-³¶0x凧5+qô6OÝ?Jæ4½Ëv_–A»vO'ÿ¯[—3tɤ‰ŒlªsÈö®jÖ\^",…ùÃmÍuNWHÂÕ!€#¡«zwü~'Ñ¿•gÚ¶øK¯Ýfb«ýÑž•£§ÿÇâ}ùVÍÞIZe­_þA“ý?­s5Óêÿò Ÿéýk˜¬©liSp¦O¸A!BC8ÀÍIU59DV섌£&´{·(Ç}*À°ÈWv⾵ÒX©b~féø rÈóéq'žÅƒŒ”íÇJlV¾{;µÃ ÎÃÓZæ•Ù¼t=Gÿ=ŸýrËiÉ36¡qCq %‘T6PÖ¢è–$㘥>x¤–)–.¢xÛ¯a´ŸåPPÛ+C"OÓΩßz°$¨$NÜw§>(„8º–6)ås´‘òr¾ÃßÞªÏcx³ÜÍn­¾Wÿ­ 2˜À^3ýáMŠÞö(¡EÔ›.w¯ï—+7ÍÏ~9¦ƒgÓ\ÉãÍ)eo\Dêr½‚=óïš}¶”‘ÀË+»»ã{në‡-éêi—P]n½Xáf28e`8CÈù¸>ÞõZ >ÿÊfc*È|­Òôýá<ó»ŠÖ·EŠYPÎÒI#™v³r ñ€;?GsgÒ¬ÓÏ/•Ê%vdwéŸ×Ä+rïm,ŒÐ,ëù•÷A%G#ü+fê3-´±¯WR£ò  øà³\F÷ÌòÆèÕ¤_•J‘ÆLgŸjDÑ4ùÊ»¤YÊP/€ýk=ô›»©RGÉØª»Y”î*Œ>l -ùzVÔ +Ýo’Ýã>Jî&L€Üü¸éÇ­A=´{cIõ)U£>vXƤàŽOËÐZl+l²ÞùZžéX”CåqÃp2¦“V¶žiÕáˆÈ 8`6–*CžŸ)é“íU¥±¼)-¥´O³å_Íe+Ë|Å@;°~lƒŽ´³m³ìÑå2&Á±ËîÜ1×=þµF}:' ï'Ý:ùA™6ßî—üO½q\Bm¡–-Þ\’1jªàãåï×?Z›QŽWXdŠ3!†På€X{gŽôÚZÜüÆc31V-¸|Û2;Uh´tO–æé„®ÀG†\à!FWž3Û4ÛM:ky ”ÂZC©e“ˆØ±ažzsÛ5 e땤¡ÃÒò–àã Óq^ôu48³2Ë#É Ÿ–,àݪg×8ó©–ÖÚ ËpÍ4lÓ³Hʾ]»ŒاZ,ÂdÄû–ÝCÈ_‚ÝÆ?­E«ZMpÐq’IŠSœb6ûÇó @ÃfJÖ×,r†*£iU-ÉaÆ{ç­Y†?*‹{¾Õ ¹ŽXã¹>µ‰5¥ÔFáäkœn$Ÿ5V7w 9È;xè>µv×óCÀ“¨óY£ý÷Ý_3ø‰nFÞ˜ÍhO¤™$›¹Ì¡×Ûrª;Fq×4¿ÙV°”“Í‘"‰a‚T–ÜÇçÚ¢Ž˜£¿Í´îŽ>@òáÜäô*Ç‘ÏÚµŠ†B¬8#PLû{„û\“²±› W#peÏÊ'ò«0Zù)Yd(‘,J„ü£þ½+i—‰j»„Ÿ,»]!u Ѫ•NI®3Va²¹Šs+ äùù^JyJ1Œã;üy  bŠò4;÷*HoâVÿƒû-V‘&™ ß·nß—qËÇóÍRŠÞðÛZ¬Ö×%"gÝ™wŸ”çw SùÔ–ö·PÝ\K0¹~‚$RŒE9ÈéÓó  ?±-<¸„Ï#ùYØ ( ààL} ¢ :ÌM¬ììÀ4CrýÐÁ¸ÀägûÕÛd?b‰ 7–!}Åx黿ְ!Òµ³æu €«'Ì2ã…äò¢ûrhn5·hÊK Ž5a³w±ÎMI,Q^Úìߺ)!õA²ímo’KC*JΩ¶FyUoF屎ÄUÎk(Do¸/•Á}Ø`¸oé@ ’ )în KÜ<ª|ûtuêWnâ1¸qjrÛYÞÈ÷Vwy}Ø2Àê݆W¡‡½RºÓn®å»€Gå#ÊÒ,ìÂà`ç¯^hšH c,l%A³Ì ´KeIùG§~”#ÃBaç4FáÇÍ‘Ø ÆGû4ÛkHcXbYÞSiÂä®W寥½¼×:{¥¾<삜ã=k*+¨dŽØÈû§‘–_œ“å.¶}HP3׿  yl"‘]w:—”K¸c*ÃÆF;S`´ŽÕà.$Â+mBÿ|“’O®+*M?P•q2õÞ|þ$mĆ\71Ç^œU›k{¸.-‚á‚yŠïç»YŽÞ­žµiÝ[­Õ»Ã&v¿\u¨ZÄyÒIóEæòê›p[ÝÈÈ=?*Ç–ÒêÎÎßÏ2´j‘ù¨'ù™ö0<–þöÓ×ó­K•Z,Rem”4!#w÷qÜñÖ€Ú-·–c¥Ž0R0€ÜAÆqŸ\ýjTÓ‘nušO3Ë1¦Bá€Ðu&¯Ñ@Á“ qowØ¡w9Ë6;ŸzšŠ(#PˆÉv˜}¿#{­U{"TŸ;ÿÿëÕû¿øü_÷[ùЉ¾éúU)4.TË¿êEcÿ!‹ÿúçþÏRÛ©Ecÿ!‹ÿúçþÏR2ÍÇü~Ãÿ\¤ÿÐ’°|Ná$µ'= úVõÇüCÿ\¤ÿÐ’±•2بîsVöóy‘– òNÌÿNµ½`¹™rsÉÆáTÌeäÞí¹•Ét=?¥^Óƒ}©sß8AŠHËÔ~Y%=‡5ÊÝàÇ~ÕÖÞ"Ï$™ÉìqXréjì~øÏ8§)¤J1eσxþU¹gÍ¥º¦QöýöàÇzaÒwr£ ëW-áh¡09›É8ÊÎk'4hŽ~Þ<,Œ€ÛM\»Œ ë|!ÚËéÏÞoñ­¸tû`…Qes¸Èõô¤ŸM·”.æÜÈ0§wAÏøÓæCHæï0×río5 fÏÿª·Ž†«¿l¤‡R¿{¥7û"ãÊx…ʈŸ²§·J´Ñ-;<+¡ìJj©n©÷zƒô­ùìï®Ñ¾ÑskdŽ>^?™}5´—“Ì5%‹•-ßÖ¢± ’L÷Š«»Ó׊õËoøõ„ùæ½~•åºeú[\ƒ ï…ç¨çµz¬|FŸîåO©æîãêoúèßΙR]ÇÔßõÑ¿2»£±É-Ìífâ8¬¤Ï"þuÎA•šÙ ãÍ¿JÖÖnDóy2˜Xdúä{U•ÒPÊÀ2ž1\ÕevtSVF«£\4ÞKùq}§x^¼tÉT-%̨Ø,v|î{œŸþµM£Þ[¥â}¥Ÿ [,ËœžzUˆh¦e·šŒ7îùƒí\û3r‹]=ºªÄ<Çç?Ö«XHæue?½ÝÕ«F[«°Ñ£ÛÂÛÎÕÎjd·#|±Z¦?Œ¨<ûõ¨Þ…* Bdã ឥºñD—Ùj›ÝI99šú”°Üˆ3øŠ¦eõh.£ÿHƒ,8ù­qµ[´·¶Ü““°çïïù´ýóÈÊ1äÜ{Ÿ›fãdÖëRJ±ýåW\óÖª$>GºUÛ68Æ{æ®÷Bµ™ÐØê?h¾–ß`P™ÚcŒžksOÿÅúå\æL³Fð¯Êï'ŽØʺ=8æéL‚JÚ¼2œ}äËz·üƒgÿwú×3]6­ÿ Ù¾ŸÖ¹štÅP+]–9vÄ„C–9é[uÊ\2Eq2ùªùcµ”ç­vB‚$…á…,ÏlJîüÿ=*ym]vpñÇ2odÇ<䢉V;C4™bß.ÇáŸÂ®i±ÇxZ3v g#èưlÝ#¿Ò04‹@£D0*+ýBm:9%Š*™@vf "íÎxþ•.”6évËœíL~µõΛnö¢ÂÈÓª •C|ÛG<ÿ:@E>¾È/fHch-õ¿;’¡†w‘Í@þ#»Š0dÓÑX,ŽàÍü+³‘Çû}ñW£¾Òn/.7}œ\@¥YäÛ¹“hbAë·›o.‘Œ $vÉ0m‰˜ö°Èp‡§µTÿ„’&òqaû˜Ê9—ï8Á¿Z³q«]ÚÝÃi=¤f[Œy[$%OÌdíã}í;ÞÃÍÚDû¶nÀÆw~jLYO}kwö€îÊËn¾`Ú¼Tw8ÏáL ³4Ï8aîå(6I»Œ½èyéTîuI!¼ò¼¨ü¥‘Qœ†Éð1íëVgž×N_1ÕbYeÃ0ǹüªŽÂ{È®Úh×hNW¿Ýç¯?\R¼Z½ÄªT[ —Í@.Bíqzf£ºÖ. ™™¡Q`uVË;,{»Ž=jÜrÙG RÚÚÇåI.ÀÑ*`6p¯ÿ^$úrj;`k¦;aK*…ÏÌzãÀõKÈŽ$³$’6dêªW§íwÇJ³ ôs4RÆ‘m£ÜÇçQü]1ŠŽ t¸mâÂÚÀ’«l_±Ž?»úSŒšRÉtíQÙOŸ´ª±÷cžÿ­[‚C-¼r¤º†Ê6åçÐ÷ž—“Ão.XÏ(¹h£ò“íò¯ô«ÑÏo²ŠX¶ÉòÄŒ6AùT‡Ømm纻‚"¤!d¾:z§·$‹¿f_(ì݇Ëe³ÐcÔzÓ"Õ/vÍ#C å¶Ðå„jÊI$…ϧj½k5¼²$ih"X•N®ÿdž™¦Á‘t¾T1ÙJ¥·•USÈï^ZFÔ›ý&EH…½ºåœ¹É;p1Ó‘úÕa­\dkh‘ãY@Ò‘÷vôãý¯Ò®ùºd÷ ƒi,û1Ÿ”¶ÎãéUÀÑÁ2µ–Á¹b ·i'iȼhöz”÷nÌ-v@7m‘Ÿ¯ŽÕ~ÞS,Hvê(Û—ŸCÜT&9.'ÄP›†@²•>ÓÀÉëÚ£¹¾¶ÓÞÚÙ‡Ï)Ø‘©Q€>¤ €êsƒ"<“oUD.z3œtã¶iN£r/LÐ0Œ/šÊü.ìôã1R¥E¯úG7Í ù@“œsëÏÒ °mû˜ˆ ?w*§‘·Ðph¢k7. ³Fž]¥THJ€ÈÍÉÇ_”Õ¯¶Þ<²¤V±æ8VB­. f òôöëR8Ód„¬‚Õ¢Ú™ ®Ó÷?JšU†dvd·@˜2 .Ð:sí@íõuÜB#¼ª‘´·x8Î8ëž1ê+F²ÒãIKku[›vŠ7ýÙ2ó5d_Y—d1S†Çãùñ@èªRjV1KåIy¾q´È¥mFÌÍÔ#coœ|¤œb€.QT†¥h×)n·´’¦ôýáOKëW…¦K˜š5;YÃŒõ  TTrË14’º¢(Ë3UãÔ,æRÑ]BàĬƒ êZ¹EUûu¦çQscŸç(õ4‹}jÑù‹sLnݼc3ùк*Õ,y[ÈN[—œsøÔÂâhÀ• nL¼=EOEPEPEPmßü}¯û­üÅDßq¾•-Êo¼—ËU™Ž=ÅE,[Cs’WpG#Ö€,[©Gaÿ!‹ÿúçþÏRZónµ‡ü†o¿ëœ?û=X¸ÿè¿ëŒŸúW;â·d¸´Ø;$û¤î×EqÿÑ×)?ô$ªž”š“ÄÏ+'–àœãü)5tåRIKr$ÀþôÙ­](Ÿ¶¦ãØ÷«‘ør?ñó+ÀEY‹HŽßÎ×Ñ=NvQ#;mu^}McßKuá.vlÿw)¢Û¯Y$cëœUi¼1e/ü´•OçM¤Å©Ä[]ܦÿ2v“ÓwoÖ§nÈ[º†ð…«øú—þø”xFØt»”ÀC‚läåØmÏ$úð¥ ÛOÎÃ5ÖÂmÞîoûäc„=Ó¼Ž>vûÇÖ™Œ9èµvKà«U\ É}yAþ5'ü!ÖØÇÛ%DQ\÷¹½ŽWLˆOt¸ò˜tcÒ’E˜´„²1\íëùW]oá+kvÜ/%cœœ¨çÚœþµ|âw\ÿÓ5©¶ pÞt°Ü!ÊóÇLâ´-¡šâäŸ:<7r+¢oZ³«ýªPTçýZÔßð‰Ûw¹ÿÛ5¡¡£˜¹€'AžHç®yªžK¹9‡,¼å_mv‡Â–¸ÇÚ%ǦÑQÛ.ð.æÃ{õéÜ›¶ùívª¤‹Æ~ø`sø ©wq%Ã'˜_ÛÚÿÂ%rog?Už µvÝöéÁÿqh°Î_L–á.6Àó*àîǼ ·OÖ¬mµþì£e¯÷ ü…14럲4OuIæù¨â;·r7sùŠA¦Ê·ft¹Aó4LyùÙvç;ºqÓõ©6ÚÿvÈQ²×û~B€ I”B[•b±Iå‹oTçïîþµisù²G”ò]bó#ÎK0cœ7?øïj¹¶×û°~B¶¿Ýƒò±[\Ä-ÔÜù‹f”°åóÐ ä€3ëž*{È Í¬°ïÙ½q»Ò«íµþì£e¯÷ ü…>âѦ¹YV@ŠQ¢u+Ê}x?g W}áóWj†Höüª¬c>ù>¸íWvÚÿvÈQ²×û~B€ µÑŬÙI#húüÑ|Á¶ÈmÞÞž¼ÓäÓd6¶°E:ÄÖêÍØÀ.c§¸©6ÚÿvÈQ¶×û°~B€'‰&[‰ä ´F tÇRO¿ô¢h[‹ywä³6Ü}ì©Ö ÛkýØ?!FÛ_îÁù ‚-!ÒhÜÜ+,x¢<`ÝÉÍ,ZAˆ M»÷zífluÿj¦ÛkýØ?!FÛ_îÁù †ÎÂx,#aÒI»çÃl\ð¾øzòßíV²C»nñŒã5_m¯÷`ü…m»ä(©ÑXI#ÇrH¬º,üŒr@ç¯NJ‘ôå"$Ûv*Jçï0#<û~56Û_îÁù 6ÚÿvÈPFÐÙÄÞeÖ^Rä‘̬:gý¯Ò¤ƒG0ýä{QÃ!|ØÝ»·sù Ÿm¯÷`ü…-¹ä(¶ö[¼,“®#¬3¸3nãžçM‚ÂæÞÕâŽåw3.ÜG„Aä*’Ý¿¥I¶×û~B¶¿Ýƒòbòµ[Im»Æ7uÅg6Šù‘¢º ]]Ihóò±$÷ëÒ¬íµþì£m¯÷`ü…W—HyLª× ±:ðˆ„Üa›æÁû½±M“G’HÊ ˆ£ge)¾`xËpxïšµ¶×û°~B¶¿Ýƒò[û—%fFm¤ ñ’%x`ƒ×½\‚ ˆšk1"B®X|Îݵ3m¯÷`ü…m»ä(BŠÏÛkýØ?!FÛ_îÁù Т³öÚÿvÈQ¶×û°~B€4(¬ý¶¿Ýƒòmµþì Mû» î¬c(ÊNÜŽ¢¨Áigf³}Ž'ß/l1ãû£=µ\ÛmýØ!K‹oH!@ÂÙJÂõRA¨ì?ä3}ÿ\áÿÙêdh† @µ ‡ü†o¿ëœ?û=,\Çô_õÊOý )ÔÛøþ‹þ¹Iÿ¡%:€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€!´8·ãæý ªmÍýãùÔ6¿ñî¿ï?þ„Õ5›ûÇó£sxþtQ@æþñüèÜßÞ?P¸ÿxþtn?Þ?P¸ÿxþtn?Þ?P¸ÿxþtn?Þ?P¹¿¼:77÷çEnoïÎÍýãùÑE÷çFãýãùÑE÷çFãýãùÑE›ûÇó£sxþtQ@ãýãùѸÿxþtQ@ãýãùѸÿxþtQ@æþñüèÜßÞ?P¸ÿxþtn?Þ?P4›Yð=KS~Õü÷_ûêšà=Ì*pGÌp~•jšr^V C„9¶†=ìmÍOö˜ÿçºÿßT}¦?ùî¿÷ÕYòÓû‹ùQ±?¸¿•VûLóÝïª>Óü÷_ûê¬ìOî/åFÄþâþT[í)ÿ=—þú§îoïΚe·kÃfP<¯0ü¼mÎ*;^mcÏ¥JÒy6ýZ›ö˜ÿçºÿßTˆª×¸gjqŸ­DuM8]›5 ¶!*­ýÒØÀ>Ù  ¾Óü÷_ûê´Çÿ=×þú«;û‹ùQ±?¸¿•VûLóÝïª>Ó×/ýõVv'÷òªë,ÝMloUŸ+Æ8þTíÄ÷?T±ÿÅÿýs‡ÿg©mãÙ?/Ö¢±ÿÅÿýs‡ÿg  7ñýýr“ÿBJu6ãþ?¢ÿ®RèIN Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( mãÝÞý ªj†×þ=×ýçÿК¦ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ÏPÿÀ¿•e&™5ÕýÿÚ%‘-^æ9Aóvª‘ózd Ó›rÉŠ¥¶ç uéIöƒÿfÆî¾õoíþxÍÿ|Qö†í ¿÷Í-§ü{'ãüê;ù _ÿ×8özšÝ p"7P9¨l?ä1ÿ\áÿÙèÅÕ™¹taq,%C.cÛÈ8õÒ¢þËúÞ~iÿÄÖ…Ÿý˜ÿô¼üÓÿ‰£û-ÿè#yù§ÿZPö[ÿÐFóóOþ&ì·ÿ çæŸüMhQ@ÿÙoÿAÏÍ?øš?²ßþ‚7Ÿšñ5¡Egÿe¿ýo?4ÿâhþËúÞ~iÿÄÖ…Ÿý–ÿô¼üÓÿ‰£û-ÿè#yù§ÿZPö[ÿÐFóóOþ&ì·ÿ çæŸüMhQ@ÿÙoÿAÏÍ?øš?²ßþ‚7Ÿšñ5¡Egÿe¿ýo?4ÿâhþËúÞ~iÿÄÖ…Ÿý–ÿô¼üÓÿ‰£û-ÿè#yù§ÿZPö[ÿÐFóóOþ&ì·ÿ çæŸüMhQ@ÿÙoÿAÏÍ?øš?²ßþ‚7Ÿšñ5¡Egÿe¿ýo?4ÿâhþËúÞ~iÿÄÖ…Ÿý–ÿô¼üÓÿ‰£û-ÿè#yù§ÿZPö[ÿÐFóóOþ&ì·ÿ çæŸüMhQ@ÿÙoÿAÏÍ?øš?²ßþ‚7Ÿšñ5¡Egÿe¿ýo?4ÿâhþËúÞ~iÿÄÖ…Ÿý–ÿô¼üÓÿ‰£û-ÿè#yù§ÿZP#B1}¥†æêy5-g¥ÿ”$·¾g\î&Ü’N}Tmü¸§i/üú^ÿà3ÿ…^¢©i/üú^ÿà3ÿ…ÚKÿ>—¿ø ÿá@hª_ÚKÿ>—¿ø ÿáGö’ÿÏ¥ïþ?øPÚ*—ö’ÿÏ¥ïþ?øQý¤¿óé{ÿ€ÏþvŠ¥ý¤¿óé{ÿ€Ïþi/üú^ÿà3ÿ…]¢©i/üú^ÿà3ÿ…ÚKÿ>—¿ø ÿá@hª_ÚKÿ>—¿ø ÿáGö’ÿÏ¥ïþ?øPÚ*—ö’ÿÏ¥ïþ?øQý¤¿óé{ÿ€ÏþvŠ¥ý¤¿óé{ÿ€Ïþi/üú^ÿà3ÿ…]¢©i/üú^ÿà3ÿ…ÚKÿ>—¿ø ÿá@hª_ÚKÿ>—¿ø ÿáGö’ÿÏ¥ïþ?øPÚ*—ö’ÿÏ¥ïþ?øQý¤¿óé{ÿ€ÏþvŠ¥ý¤¿óé{ÿ€Ïþi/üú^ÿà3ÿ…]¢©i/üú^ÿà3ÿ…ÚKÿ>—¿ø ÿá@hª_ÚKÿ>—¿ø ÿáGö’ÿÏ¥ïþ?øPÚ*—ö’ÿÏ¥ïþ?øQý¤¿óé{ÿ€ÏþvŠ¥ý¤¿óé{ÿ€Ïþi/üú^ÿà3ÿ…]¢©i/üú^ÿà3ÿ…ÚKÿ>—¿ø ÿá@hª_ÚKÿ>—¿ø ÿáGö’ÿÏ¥ïþ?øPÚ*—ö’ÿÏ¥ïþ?øQý¤¿óé{ÿ€ÏþvŠ¥ý¤¿óé{ÿ€Ïþi/üú^ÿà3ÿ…]¢©i/üú^ÿà3ÿ…ÚKÿ>—¿ø ÿá@j­‡ü†/ÿëœ?û=3ûEçÒ÷ÿŸü)tÝò_]Üù2¢:F«½ ±#vx<ÿö  Z(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€?ÿÙfotoxx-12.01.2/doc/images/trim.jpg0000664000175000017500000005534411701011016015334 0ustar micomicoÿØÿàJFIFÿí8Photoshop 3.08BIMresize sharpen ÿá 6http://ns.adobe.com/xap/1.0/ 1164 1372 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀr´"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ï袊(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+ÓOµ¹7RϘæêQ’ÍÐ7ëz²´ßõw?õ÷7þ…@ m/MR¡­ÐàíÏëNþÈÓÿçÕï¦ÿžêÚ;¨|¹29ʰà©ìA¬˜ï./.?³^P›IW¹^<À;/û^¾”u4½5ÆRÝgßãL¹²Ò-"ónc†óÏ!?_Š(à‰b‰"Œ«;]¶†ò+K{„E%ÒRq‘ÍVóü3ÿ?6_øÿÙU›[MõíVÕN ŽRÀÀÔ_ðŠh_ô þúoñ©4k+k BÞÒ!BD!A'’œõ Oa§Â@ûœÿ¶ßãQ}›NÿŸ%ÿ¾ÛüjÖ ~dú©šÖ1MÊM1~ͧÏ’ÿßmþ4}›NÿŸ%ÿ¾Ûüi3Fj¹¹˜¿fÓ¿çÉï¶ÿ>ͧÏŠÿßmþ4™¤f“è(äAÌÇ}›NÿŸÿ¾Ûüi>ͧÏŠÿßmþ5KO¼’xb1ùS¼k ™HÈ"®f’„X94/Ùôïùñ÷ñ¿Æ³éßóâ¿÷ñ¿Æ“4fŸ"v/Ùôïùñ÷ñ¿Æ³éßóâ?ïãBºgÚÚI~Ñ"|ØÀ'î(“GÄÒýªRS ŸQïJÐ È›ìÚüøûí¿Æƒo§Ž¶#þûoñ«štòy†=ß ⚥f…î.K1S´mâŽTžÃ»+[ ›èw·?­'‘§ψÿ¿þ5pD²%ª–m®OéNû=©þóöuïJÑ ²‘§ψÿ¿þ4}ŸOÿŸÿüj@žUè9Úø«RÅOs$»ˆF iòÄWe#NÿŸÿühò4ïùñ÷ñ¿Æ®Ïk ¤¡ ïŒç¡ŸdCl͆G »–þZ#¼Š~Fÿ>#þþ7øÑäißóâ?ïã]ŽÒ‘yvMùIoi@²Jßx>`1E¢‘OÈÓ¿çÄ߯ÿ<;þ|Gýüoñ¤”‘”@8ÈïLÍW$IçdžNÿ>#þþ7øÒy:wüøûøßãLÍ£ÙÄ9Øÿ'NÿŸÿühòtïùñ÷ñ¿Æ£Í£ÙÄ9Ù'“§ψÿ¿þ4y:wüøûøßãQæŒÑìâì“ÊÓ¿çÄ߯ÿ·™§É¿Ùní½¿Æ¨fµí?ãÞóëQR)- „›z”5=2Ê=2åã· ëÁÛ ãë[6D›rNI‰yü*ޝÿ ›¿úäßʯXÿÇ…¿ýr_ä+#Bz(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ÊÓÕÜÿ×Üßúj×<ÒË…Á‚O-ÛPdÝ´”Áö4¡y ·ˆ£—ÊV?;½·Ðz}i%±·’Ñm‚lDû›x({}j/±ÞÐROûò”}Žóþ‚’ß”  6ë*B«;¬’ ŒûÔŒN5¿–dŠe“1ãä‚?´[ŸúwOð£Ú®ÁÈQv±o Y5Ô†9 ¶‘ãRΜœqU´û¶º€³£#©ÁÊ•Ýî3Ú†%´‡6÷žt¦?)„Ê0ËŒc#ž;V”mÜpF¨’Ê Ü!¨Œ¹J”nUÍ&j÷Ø.è"ßøŸáGØ.è"ßøŸáWíWb}™V‰ ©°†9ù=¾´énæ–&¼°­× süêÇØ.è"ßøŸáGØ.è"ßøŸáSÍì>Yw*Ã;@ûÔqŽh°¢ÀÚÇ'Ö­}‚çþ‚-ÿ€éþ}‚çþ‚-ÿ€éþý¢ì.GÜ®·r(ˆ¿ºéGÛ$Ú‡ßøÕ°\ÿÐE¿ð?°\ÿÐE¿ð?Âh»#îTiÙ§3n'>Ô÷¼‘üÜ…ýáþcì?ôoüOð£ì?ôoüOð£Ú.ÁÈû•ÚöF2÷‹´ñN7ò˜Ê•%v–Ç8©¾ÁsÿAÿÀtÿ >ÁsÿAÿÀtÿ 9ãØ9qa½Ž0fw;poCõª±^I{6£®rŒâ¬ý‚çþ‚-ÿ€éþ}‚çþ‚ ÿ€éþs®Ãå}Ìöl±< œñIšÑûÏýÿÓü(ûÏýÿÓü)ûUØŸfÌìÑšÑûÏýÿãÿ >ÁsÿAÿÀxÿŸµ]ƒÙ³;4™­/°\ÿÐA¿ð?ð£ì?ôoüü(ö«°{6fæŒÖ—Ø.è ð?ð£ì?ô?øøQíW`ölÍÍmYókôÿëÕìûŸúüü)ÂÎì MÀö*'>eb£V;WÿMßýroåW¬ãÂßþ¹/ò…r× oªÛÏpgXí•ÕŠ#vüôÿtVíüx[ÿ×%þB³,žŠ( Š( Š( Š( Š( Š( Š( ¹ÉãÂOû ÿíe®Ž¹ÉãÂOû ÿíe  £ÖŠZJ@µÈ$ÑhWWêÆ+Ô–B’+Ńp=ý1Zv—wO-íÅÕËG¨\¨1ÊdöÏZ`nQ\Ä:Åì+xdó$U¶ÄfU®?‡·×š½§Mtº©·žóí(ÖÂ\ìQ‚Olv¢ÁsfšÎˆT3,p2q“\ßÚµ)d[ò‰-ë[ìò”í\ðG~µ"^\1¶ŽgY^-@Â\ Ë>ÇéBoI,qmó.ö ¹î}(–XáPÒ¸@HPO©è+š’k›Ãeu5Ð*o‚‹pƒ ‚@ç®i.æ¹¼n%ºýcÁ6'®{Еÿ¯@l颚9·ùnclv>”òp2k—{Û‹D¸ŽÔóê/eەϸÏêù{×ðí÷ÛT‰H»Šã‚vñš].llõµÏ¬·0Yi¶ñßÝmgU>XÛœ1ùÕÝ.îym®Öi¯m#F%ð3œzÓjÀÍ:+˜´ŸT¸6 êLÜ/!ýÊeHì8éSA¨Þ_&Ÿ¸[fš'y% Jœ`ǽt4W8šÍÄVö×w.¾Cy±9 Áuû¬>¸5_ë/(·Ÿ !ÂÆ3dá·ÀéÅuU’ÇA#….ÛW=Ï¥¹hÆì êpqÒ¹¯:æñôÛ¹®V½À·Lnž¹£­‚ú\êh¬og[ Ëë›É6¬¯F‘¯Ë†ÀÇŸ­@šµüv·qÊÄKÑÆ²L«•Ü…ãŠé¨¬:{…¹Ô šàÝ }¥¨åsŽ*ª_Þ&†ú›],"ebØÅ“©Ç½tW=5õ嘼„Ý­Ë%¯ž’ì¡Î1Æ*IMò¾lº„›®C3Ëå¦~è8Æ1E€Ý¢¹c«jS{hËy¿½$j™bÃ}jå¬ÚΡ ÏövKa,ˆŠ§snÇ^xúP7iNµ‘¥Ý\›ù-ïæ<†dbì*UaÉíÖ«ÀÒÁ¨k7+;â& ÀÃüƒÛ?•tV…娻±Y®Öåo#g*,ž1Û·5?›u.·qܲAo¿–¨§y9êHÍkS]Ò5Ü쪾¬p+œÓ/õ‹Í— ¹ŽUrC쇸ÁÝ×®i¯}?öTéq+½Üo˜“D¸\°é‚=è°=Še»“]t·½‘­à¦B‹Œã„Ï~µ_F¿Õ/&‚âEo³K¸¸mPvÛƒ»ó ŠŠ@CA„RÐ-ÿúÍcþ½#ÿÚ•¹cÿÿõɬ;ÿõšÇýzGÿµ+rÇþ<-ÿë’ÿ!@ÑEQEQEQEQEQEQEW9/üxIÿa?ý¬µÑ×9/üxIÿa?ý¬´´zÑAëERIÓâŸÎKH„›·nÆyõÅX𩔈—÷Ç2q÷¸Ç5-I4»Kxåû%¼Q<‹´’ zžžÕ[IцŸs-Ã4FG@bBªç¹5­E@,í€B€,žhö_­ÎØ0adIæçý¿ï}jz(¡Ó,Mйû,~p;·ûúýh}2ÆKŸ´½¬flîßïëVè  ÒXZH%[FÂbL¼G­>h-àò!‰V.~^£õ©¨¤2šéV nÖâÖ1”çþ•<6ðÁ†•"Â£Š–Šb KKxü­ªùJV<=@¦I¦ÙKn=´mªãîý*Õ–vÒÛ­¼FЮ ¡ t¦ÜØZ]º½ÅºHëÑ~UfНmg´×¡%î3g¶¦fX‹¯´‹XÄÀîߎþ¾™«tPc¶0<ò¤$²c‚OSUäÒíÒÎh,á†/7·©e?^jý†ghúRé‹1ÜŒó0fؤ(ÀÀMOe’:[F­ !ð8lõã¥Z¢˜Š±i¶PÃ$1[F±Ëè{ëR˜!/˜Ô´CŸîñŽ*Z(¤šmŒ±äµ1p= êjXí`‰ÃÇ«òÁÝô©¨  Öö–²´°@©#ua’ZScjn¾Ô`O?ßÞ¬Q@­¬--$i-íãÛ«(©V–g™P ÍÜÒ¤¢€*.›d’¼©lŠîb23ž´G¦XÅD–±„b NHéVè  k¥Ø­É¸[eÜ\ÉõëJºm’Lò¥´jîb3ÎzñÒ­ÑHECÅ„DU§ÑE01oÿÖkõéþÔ­Ëøð·ÿ®Kü…aßÿ¬Ö?ëÒ?ý©[–?ñáoÿ\—ù žŠ( Š( Š( Š( Š( Š( Š( ¹ÉãÂOû ÿíe®Ž¹ÉãÂOû ÿíe  £ÖŠ¡¨jÆæê¾DÃ1ê‘.»-Θ3«˜dy“q6ð9¤ŠC:SÀæŠçµKë¹ì¯`µŽ!ÀÈîÇq%s…ü*KoT1G"Ò&e|ädžôì+› ‚2j¹Z( &7Û'‡¡^]A”S,Moq#¢2“¼“Ïå[:‡ü{úèŸú¦–¢lŠRÈÑɨÌzÿ gý§ÿ¿cü*iâ®ä,¨I¼õ=ê¼0FQAEä°!¾ñÇ¥j”lfÛ¸ÿ6/ú Oÿ~ÇøUϰMÿ?Òÿß+þ—(…ÙጅùG“]L×.ÅEßs8[J—+^JÁ·ÝQŒíïQÁ5µÍ̶ÐjóE÷—åÿjÕËmºå-û·U¨R8cò¶Y•ò³åà—={Öe’BÅ¢º‚Aü Ò¤¨­ù‡þÿú©h:QÖªê„.쎒ÿÈÖ=¾±q§XÆ·±FÀZ c1“Œ ÷äPGEsRëYN'·û¦6W@ñƒ– гy«Ý£ÜÉo &ÞÚU‰Ë“¹‰Æq­slzZæ¬on­we‰í^ý£''z’qŸLUÿIy5‘’æHÝ ¸SÎîõí@\¿1vž(öy™Ë’ÿ°Ëÿ?³ß+þÃÿ!_£ÿ*¨d–aÍì—‘Å$Á`ÚG”xüœÐï°Ëÿ?³ß+þ}†_ùý›þù_ðªÑIvšüÑMp#o½.~lU úê[ûq,ÓŸ5\¿˜–øÃ/üþÍÿ|¯øTk +L%»,xù°£ŒgÒ´k>eI%¹ŽXL¨År½ºw m§†îÕîlï^e9߆jà9úŒÕyvšE¶(íRø€8Ï5a~êý-UZò[+UxG‘cPýN(zŠÃÕu{53[<Ê›äUÉ#Û?u½ÅÜúÕÏ”éöa nQó‘O FÕe¨ÜÉkeoe~t±¼„Êä…Pqש5©¦^}ºÉg)±²U—9Á€-ÑY:ÃÝÅudñ\l…§Td Ëg=O¥_¼ˆKnÀÍ$ r^3‚¥ÒáÖÄôVœ—ÒhóN—²n˜—‰¦Š'oÄõ­ Y'Ñí%•ËÈñ‚Ìz“L Wÿë5úôÿjVåüx[ÿ×%þB°ïÿÖkõéþÔ­Ëøð·ÿ®Kü…OEPEPEPEPEPEPEP\ä¿ñá'ý„ÿö²×G\ä¿ñá'ý„ÿö²Ð†¡a£‘r `ß)ÁȨ[F³-xÛ\µ &@oJÐ=h¤mÖ‹mtÌL“Ä]ryO1@Æ#ip}ª;„’h!Ø£ é”ÝGƒŸÝ·CmiqÆé¯ZX#ÿT?Þ=ñÚ¯ Keéoÿ€ÒýšùãåPP–¿ñî§Õ˜ÿãÆ¦¤è0:RÐsijÁ$/²)Sޏ5VM&ÒQ‘Y–8LÁS޾ü ½Eg"jÖò\]K#ÌpJàäcŠÏÔt{‹»çò#xb–DyN661ÉLg20r£tŽì°Æo³`f–oøþOú昢ݶ-ÓqÃçŸ÷En¿çŒ÷óÿ­FÛ¯ùãýüÿëT[²ŠÚ .î"‰æMà),1ê:UíM’¿Úl*Î~è# Ðmºÿž1ÿßÏþµn¿çŒ÷óÿ­Iý«cö•¶ûL~sc Ÿ^•Zï_²··¸’9Ín@u^Ü×ñ  ÓD»¥‰Bw*ùÇéRÔS\Åu¦<°>ô#ƒ‚;ûÔ´QEQE‹þ³Xÿ¯Hÿö¥nXÿÇ…¿ýr_ä+ÿýf±ÿ^‘ÿíJܱÿ úä¿ÈPôQEQEQEQEQEQEQEÎKÿØOÿk-tuÎKÿØOÿk-k[yßõÔÿ!T¡†æÞãTœ@%óZ$,ü(…Y"hö ufÝ÷±Š]÷óÀßt£×-`ѧú«…‘ÆGÊ0süêÄç76ÿVþTÝ÷óÀßt*Êó+È¡gç4øŽ.¦ÿq?öjË´Í©Ésyc#6JDþbl=†s“ߊÑu‘&2F¡·'3þ4o¸ÿžþû  Ú„W7ºˆS¸º 09õéV®î#ŽŸÌRo¸ÿžþû¦²Í1PèC'vzP„âò?÷úV^«ms{y•e²HLwfQ…Éã¯éZs+ïI#•ÈÁ8È4›î?ç€ÿ¾è¦£&¤öŽ––»¥ÚJ:çgvÀÍKn¾VŽñ V¶ Œ3'ޤ‚zÔÛî?ç€ÿ¾é¯çʉT0Á;³Å:N–ÿõÑj†µ¥Mz³Íou"ÊЖ<)>äqšÑš6d]„nBÏ|SwÜÏÿ}ÒMw©ˆÚùíJoPd=Ƕ*ÒkI. û,2°)ðÅOs‘ëÇåWwÜÏÿ}Ѿàô…G¾úwÖâ¶–"ò o÷MO©#ϧÜÃ/$lª3Œ’)¢ôO'=W£}ÏxTŸPô†f]XNOœZ¥Ñ‚³àr3ÇT¶6“A§ +›Uš?%·ã’IýØöÇz½¾ãþxûî÷óÀßtÛ¸’±Ÿ£i²ÛÞÉy:¼@Æ"Š'˜ÊU}Ïôz?øö›ý÷þf¾ãþxûî–8ŠÀQ-’qï@u„f³²™v1·‘$òÝ‚‡ãÉã<Ö]Š\ÝÜK©Cl®c¼fòK˜lƒÓ"·Z9!ÖÑL€‡ ƒb)ÈeGjˆ£¢«áŠ4e&›x« þR‰ ñ¸hUÇȤcéžôج/£6¶ŸeS~q¸¸eÉ=:çšÙßqÿ<ý÷Fûùà?ïº.¸ç9¾_ú昦¨-Ú/Vbýò($i¼Ù\.ÐÍ!Yc‘Ìh\ç®0qŠC34ý:æ-LѱÙ[~lôªÉ¢Þˆ¬bÀTx–+Á¸päc×Óñ­Ý÷óÀßto¸ÿžþû§qXÅG‘5 DÐM4/sç,‰qµWœŒ®zŠœé·-áû›]Š'yšEŒŸpçß§¾ãþxûî÷óÀßtÇšit×ià0>1°°oÔUª¬ây—ËhÂ)êwf¬ÐEPEP-ÿúÍcþ½#ÿÚ•¹cÿÿõɬ;ÿõšÇýzGÿµ+rÇþ<-ÿë’ÿ!@ÑEQEQEQEQEQEQEW9/üxIÿa?ý¬µÑ×9/üxIÿa?ý¬´´zÑQÜHbŒ°9 úœQ²÷þyÁÿÿ@QL…üÈUñÃ¥Ceyìrìãß5ÐQ@ú•Μm<{••_Ïã$ã[éÛÚ¨M£^:ÞË™X5Ù[o&N?tôQ~ sSÙêWœO$3mK•t  cÇ~ù§½¥àÓµfÄÉ#É ®Öä¹ÍtTP;yatùÈ\}²4T‘û¼.0sØuâ· ŒÅolÛ™)oRZ’Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÅ¿ÿY¬פûR·,ãÂßþ¹/ò‡þ³Xÿ¯Hÿö¥nXÿÇ…¿ýr_ä(z(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ç%ÿ ?ì'ÿµ–º:ç%ÿ ?ì'ÿµ–€6Kr~Vÿ¾M&ïö_þù4ãÖŠnïö_þù4nÿeÿï“N¢€»ý—ÿ¾M¿ÙûäÓ¨ îÿeÿï“Fïö_þù4ê(»¿ÙûäÑ»ý—ÿ¾M:Šnïö_þù4nÿeÿï“N¢€»ý—ÿ¾M¿ÙûäÓ¨ îÿeÿï“Fïö_þù4Öž$8iO¡4ß´Áÿ=£ÿ¾…I»ý—ÿ¾M¿ÙûäÔiƒþ{Gÿ} >Óüöþú&ïö_þù4nÿeÿï“Qý¦ùíýô(ûLóÚ?ûèP›¿ÙûäÑ»ý—ÿ¾MGö˜?ç´÷Уí0Ïhÿï¡@nÿeÿï“Fïö_þù4Ï´Áÿ=£ÿ¾…H9›¿ÙûäÑ»ý—ÿ¾M ÁFX€sQý¦ùíýô(Mßì¿ýòhÝþËÿß&£ûLóÚ?ûèQö˜?ç´÷Р 7²ÿ÷É£wû/ÿ|ší0Ïhÿï¡NI£á$V>Ç4íßì¿ýòhÝþËÿß&Q¼ÑÆpò*ŸsŠvïö_þù4nÿeÿï“Qý¦ùíýô(ûLóÚ?ûèP›¿ÙûäÑ»ý—ÿ¾MGö˜?ç´÷Уí0Ïhÿï¡@nÿeÿï“Fïö_þù5Ú`ÿžÑÿßB¤VW\©zŠÇ¿ûúÇýyÇÿµ+rÇþ<-ÿë’ÿ!Xwÿë5úôÿjVåüx[ÿ×%þB€'¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®r_øð“þÂûYk£®r_øð“þÂûYhhõ¢ƒÖŠ(¢Š(¢Š(¢Š(¢Š(¢Š))i(±Uû2œ ’I8ëÉ«ƒò¬}Bêk_É,kŽ7c;A|ø ­-ÂÙ¶žÑjM\,&á‚§ŸLЀèp=åM‘£K¨É^â¹9on^9. ãµ¼WîHæì Œm=Àô«6ïž!šãÏ–2ÖÑ•£kþ¤ÿ¾ßú¡‚à5ź°ÈÜx?CS¼öñ¸I%‰\ÿ 0 c‹›÷›ÿA5(ÓÛÄ:‹j Qx2㎽(¤ÂúÊŒAùWcq3Gkmqy5¥£ ^)7mgPß Éöæ§‚æïPþËŠ[©¢¬Åž#´¸_ºh©Àô•V½˜Hk•:–£söX ÆÁå¿ï ÞQvV#®xí]´ÇO³ûK#Í”ÞÈr õj›d ‰X€IŒÓª¤Í2éwßfÏóìÇ®8¤2ðš/”$ˆÉýÐF*“Ð~UÎé’höú\7,-:Ź˜`Ê[ûç­P·Ô®Â_m™ö5‘ž=Óù¬‡>¸ãéLHìp=åF ü«’žîóNÒ+¹¥Z$¥¥;Œd ©µ+™-mmb²¾y£šlI3Ï‚:nÁÛ“@®tR\AÌ6î@’l”뎵€·s…SëX–pº–•öÉ’FÌÁ]_~F85¶§7“ýúÐ3*ÿýf±ÿ^‘ÿíJܱÿ úä¿ÈVÿúÍcþ½#ÿÚ•¹cÿÿõÉ  袊(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+œ—þ<$ÿ°ŸþÖZè뜗þ<$ÿ°ŸþÖZÚ=h õ¢€ (¢€ (§Å÷è”TRê%.¤‚;;‰Ú0¥š=€ ôûÌ)?´fÿ eççÿ@QPÿhÍÿ@ËÏÎ/þ.í¿èyùÅÿÅÐÔT?Ú3Ð2óó‹ÿ‹£ûFoú^~qñt5%Eý£7ý/?8¿øº?´fÿ eççÿ@Ã4I—#*H*ÇÜÓUtõ‰¢XíDlrÈvŸ¨©¿´eÿ ]ççÿGöŒ¿ô ¼üâÿâèšUÃhU9Q±p¿OJ‘ÚÊII»º}Ö`¤¯Ðö§ÿhËÿ@»ÏÎ/þ.íèyùÅÿÅÐì’V•>β7Þp1úš–k·´åqލ§ÿhËÿ@»ÏÎ/þ.íèyùÅÿÅÐ7Ùñþ£‚Háx'©¦Bšt^­"b0YTãð©¿´eÿ ]ççÿGöŒ¿ô ¼üâÿâè8ZÊßq€[Ä[–ò®~¸ëRZƒäF2Ì2hþÑ—þwŸœ_ü]Ú3Ð2óó‹ÿ‹ ‚I · ¬r}2¨ä]>Y’Çk$ƒ£º©#ñ5/öŒßô ¼üâÿâèþÑ—þwŸœ_ü]2g³vÏäJ£¯†­;εܭºÊ0§Œ¨öô¥þÑ—þwŸœ_ü]Ú2ÿÐ.óó‹ÿ‹ œXIŽD¶xÁÈVU \RÉ$oåG S‡ ÐRhËÿ@»ÏÎ/þ.íèyùÅÿÅÐÕZ)’#"Èáòy8ȧÿhÍÿ@ËÏÎ/þ.íèyùÅÿÅÐ@iâc0KQ)êáWwçH‹§G¿ËŽÕ7Œ6ÕQ»ëëShËÿ@»ÏÎ/þ.íèyùÅÿÅÐ|Û\çt9Û·¸§hËÿ@»ÏÎ/þ.í¿èyùÅÿÅÐ]ÿúÍcþ½#ÿÚ•¹cÿÿõɪÿÚ2ÿÐ.óó‹ÿ‹£ûFoú^~qñt~Š¡ý£7ý/?8¿øº?´fÿ eççÿ@èªÚ3Ð2óó‹ÿ‹£ûFoú^~qñt~Š¡ý£7ý/?8¿øº?´fÿ eççÿ@èªÚ3Ð2óó‹ÿ‹£ûFoú^~qñt~Š¡ý£7ý/?8¿øºkêÞSD&°º‰d‘c ÞY±ÀΞ¦€4h¢Š(¢Š+œ”7ötì¨ï³Q.B)c('í]c V 'óÚyRJò(ulÇ8 jÁÿg™¿o^(6×Cøó¤†áÕ‰ÊÊñÚ¤‘S¹¸˜·NÔµ ­Õ¦˜F]—=éòBÁQ¢‘œ9Úàæ£·#½2±!2yÅM%ìºùÚVGÜY†8ô¦ïpV#† ¤p¤••Î{ŠrÚÎDœÉ—=iÿl·“c30±ùqŒŠ‰e·Uš/1¶>m½þ”µƒV+†Œ¸W*;æ…†á¢ó\§\楎òXØ—ß•  IÜj É#b°n=iëØZçX„¤0Cß5˜ßÞ?O-Ä/h±yNÜmü{ÕLÕ%q2O1¿¼:<Æþó~ui3N¹/˜ßÞ?cy¿:‹4f‹É<Æþó~tyýæüê<Ñš,+’yýæüèóûÍùÔY£4X.Iæ7÷›ó£Ìoï7çQæŒÓ°\Ú´bm¢Ï9Ï?VÖ?ÕZ×äú0Töñíãýj cýU§ý~Aÿ£rKvt-š(¢ÂŠ( Š( Š( Š( Š(  k‹ƒiqªNyc!sŒü§½HdÔ#ì–¿øøŠ«ª}ÝcýÈÿ‘«²Í+K.à $o´´¬FN3BW ØÍÔ¿çÒÛÿOÿG›©Ï¥·þŸþ"—Ï—þ~,¿ï³GŸ/üüYßfŸ+27Sòémÿ'ÿˆ£ÎÔÿçÖÛÿOÿRGö¹A1Éjàu*ÄÓü«ïúwüÚ‹ʲBD(Ö–Ø?ôòøŠ‡ì×óçþþ"´<«ïúwüÚ‘U˜Ã8MÛw‚„ãÇõÕÖÁ£(}šïþ|àÿÀ£ÿÄQö[¿ùóƒÿÿW÷M,Ï1åãqr{ý)ÞMï­¿ëG4»‡*2£¾°3[DˆgÁ+1ànÅEV¼{}/P[[vŠd”ŒDÒ•0ç§@~SúV¦¥¥ÞßÅyñE²@û“9èF?Z‚ÏF¾´»Roä¢\–$©9ý:\Ïp²ì·óçþþ"²ÝÿÏœøøŠÒòo}mÿZ<›ß[ÖŸ4»‡*3~Ëwÿ>pàQÿâ(û-ßüùÁÿGÿˆ­ó£•RpŸ0%JÚ´ÒNÑ@*¡˜¹=ú#G4»‡*3þËwÿ>pàQÿâ(û-ßüùÁÿGÿˆ­/&÷Ößõ£É½õ·ýhæ—påFoÙnÿçÎü ?üEe»ÿŸ8?ð(ÿñ¥äÞúÛþ´y7¾¶ÿ­Òî¨Íû%ßüùÁÿGÿˆ£ì—óçþþ"´¼›ß[ÖyñÈ‹8Œ‡È àã=þ†ŽywTg}’ïþ|àÿÀ£ÿÄQöK¿ùóƒÿÿZò´âBnÛ¸—è;ɽõ·ýhç—påFoÙ.ÿçÎü ?üEdºÿŸ8?ð(ÿñ¥äÞúÛþ´y7¾¶ÿ­òî¨Íû%×üùÁÿGÿˆ£ì—_óçþþ"´¼›ß[Ö&÷Ößõ£ž]Õ¿dºÿŸ8?ð,ÿñŸdºÿŸ8?ð(ÿñ¤~ѧœ#*Í·(NAüi$y<ä† »Ø–èÿõÑÏ.áÊŒï²]ÏœøøŠ>Çuÿ>pàYÿâ+Oɽõ·ýhòo}mÿZ9åÜ9Q™ö;¯ùóƒÿÏÿGØî¿çÎü ?üEiù7¾¶ÿ­Mï­¿ëG<»‡*3>Çuÿ>pàYÿâ(û×üùÁÿgÿˆ­?&÷Ößõ¦°¹‡kMå,ì'#'ŽywTg}Žëþ|àÿÀ³ÿÄQö;¯ùóƒÿÏÿZR»‡Ž8‚—7t¥òo}mÿZ9åÜ9Q™ö;¯ùóƒÿÏÿGØî¿çÎü ?üEiù7¾¶ÿ­Mï­¿ëG<»‡*3>Åuÿ>pàYÿâ(û×üùÁÿgÿˆ­?&÷Ößõ£É½õ·ýhç—påEHΡaÎÛh雓ÿÄUk»‰'†!4K‘jFB¾à~d9Î÷«JAu %òŠ/ÞÚNqYWC ÿ¨¬ûJ¤gIEPEPEPEPEPEP©÷u÷#þF¥º EvHÈûPã×å©÷u÷#þF¬KKö´M»ÅÀl1ÇE\7&[÷(‹qµFÕ \dRD\… H»±Üf­Éiu+‡o'#Ñ€¤[;•—ÍýÎìçï ~UФ­¹™{IP«p«À+B©X‰$3˜Ã3gå"­ù‰ýõüëš[›GaÕNoù /ýpoý jטŸß_ΪHÁµTƒˆNqÛæØÛuv–õc-ŽÜ63Ž:♥Íq$—!æ70F@ŽR¡Kâp@ãšXâI佂BÁd ÖÁÆ;žÎÊ+8ŒqI)Lm ï£ÛÒÁšyì Ö“Î WúSt‰ä¹Ò­¦™·Hñ‚Çɧ‹H…—ÙVIc¼Ã»óëE¤VâYÌk÷C¾ì{Pš)2=E¢€+\ÿÇÔGþB£€}r¶“`ã8å©÷¸@9!XŸÒ£‰Uïn‰âQÁÁêÙÇç@é·7'Q¸µžIQ/œòA#«›§¸³cóYÉ’2Øb=}9Û[-eiU¤ym/#–8ôæ’M:ÞK³fÄä“ûû“ž´Í"iæ†V–O:1!ÊT)uÇ\|óWê [tµŒ¢I#ŽÛßv>•6G¨ ª×ë-¿ë¡ÿЬdzŠ­tAšÜ3¼œ{m?ã@#ÔØáVIüj–—«µö±$h‰¡xCÇJóŽ}ñÎ;U舗‡µ–PZhË3ÉÏ#–cŽœš³E&G¨£#ÔP{Þÿ×U¨WþBpÿ×7þkS^|‘‘“(8¨AÆ¥<Ž?((n."Ôc4qIJ¢ínsÇJ‡EÔ..$ˆÝ´€ÜÅæÆ¥T.8éŽ{÷«±é°Gz÷bILŽ0Á¤%Hôǧ4¶ºu­¤¾dA²ª†rBØzPnî.ÿ³®$‚Ý’t$"œ1#?xüª "öIî®mÝä•bË$‘ìcœäééW’Ú8á’5wÄŒX’äO¡íIii  ,±g9wv,Íõ&€,U{ïõ ÿ]#ÿÐÅO‘ê*½ñJŒŒ™þ(ÿë_«è& W™î!Ų‹y§hU÷üß.rHDZ©Ü{jOs ÿÀMW](ÿi¤ÿ"C†UU‘ŽIû¤`u¡iªÉs-¸’ÝïòY_-ǨÇ–WFÖÂþY^IVÞi1¹· 2jÕ¾›ko8š0Ù\ìRäªg®jrØ[«Îß6ÛŒùˆ[å$ðN=h…ÍÜÚ¼©r¢1ödpŠû—’yéÖµª¥®Ÿoi3Mv‘!grß(è*ÖG¨ /ÿãÆo÷kïïËÿah?ö•m_‘ö)FHÀ¦±nþü¿öƒÿiPGEPEPEPEPEPEP©÷u÷#þF´æ‚\™"È<Pk3TûºÇû‘ÿ#Z-$¯4‹;Â6–Ç4ŸdµÿŸh?ïØ£ì–¿óíýû¿éŸóì¿÷óÿ­Gúgüû/ýüÿëQvB}’×þ} ÿ¿b²ZÿÏ´÷ìRÿ¦ϲÿßÏþµéŸóì¿÷óÿ­EØY öK_ùöƒþýŠ|qÇÄq¢ÙT oúgüû/ýüÿëP'˜cš?-±¸a²ÿ$QvñG&<ÈÑñÓrƒLû-·üûÃÿ~ÅIZVŽ·”Æâ[Í/úgüû/ýüÿëP}–Ûþ}áÿ¿b²Ûϼ?÷ìRÿ¦ϲÿßÏþµéŸóì¿÷óÿ­@ ö[où÷‡þýŠ>Ëmÿ>ðÿß±Kþ™ÿ>Ëÿ?úÔ¦ϲÿßÏþµ:8£ˆ.4LõÚ f‡Ž9FŽ÷”j<¢@“Eå–® ⑤Êb†/1€ÜÙl;Pö[où÷‡þýŠ>Ëmÿ>ðÿß±Kþ™ÿ>Ëÿ?úÔ¦ϲÿßÏþµ'Ùm¿çÞûö(û-·üûÃÿ~Å/úgüû/ýüÿëQþ™ÿ>Ëÿ?úÔŸe¶ÿŸxïØ§ÇQgË=v¨ßôÏùö_ûùÿÖ¡^e‘VhvnÎÒ<ã8 ¼i Ĉ®=f£û-·üûÃÿ~Å,’?š"Š=îFìg ?Ó?çÙïçÿZ€ì¶ßóïýû}–Ûþ}áÿ¿b—ý3þ}—þþõ¨ÿLÿŸeÿ¿ŸýjO²Ûϼ?÷ìQö[où÷‡þýŠ_ôÏùö_ûùÿÖ£ý3þ}—þþõ¨R£9Ž(ÐúªNtIk¢°ôa‘Q‡™DЄV86y¥’FY8Ó|Œ 8àP}–Ûþ}áÿ¿b²Ûϼ?÷ìRÿ¦ϲÿßÏþµéŸóì¿÷óÿ­@ ö[où÷‡þýŠ>Ëmÿ>ðÿß±Kþ™ÿ>Ëÿ?úÔ¦ϲÿßÏþµ'Ùm¿çÞûö)É1¶è᪨“ý3þ}—þþõ©7Î…LÐBBîœÀ  UÔ«¨e=ˆÈ¨þËmÿ>ðÿß±K,… "&÷s…Å'úgüû/ýüÿëPö[où÷‡þýŠ>Ëmÿ>ðÿß±Kþ™ÿ>Ëÿ?úÔ¦ϲÿßÏþµ'Ùm¿çÞûö(û-·üûÃÿ~Å/úgüû/ýüÿëQþ™ÿ>Ëÿ?úÔ©(Û’Õ‡u@ d\õ“þ°í*Ôg¸Œnš¨:°|â²î¸i?ì+þÒ ’Š( Š( Š( Š( Š( Š(  SîëîGüi[ù„ßyEDžiÚXq£­fêŸwXÿr?äkJÙYÍò«”c)ÃÈùG4šeä·gÚ'È †©çi#øRÝÜOý–×6 Fá<ÌL‡ŒàZ,4óejöës+«C0©9'¦Ÿ=›M§ý”ÜÊ ]­.fûcš"K9Z{8&pI±ÇL‘šš ²·6–©•¥6†`Àè8©é°AUgÿØÿë“èKVª¬ÿñúŸõÉ¿ô%¤Vþg{äí|»wtÎ;Òi÷WÍuþ\‚’% ŽF <ëIFg¾‰dh‹…ÓªñÔT¶&Ê$\<ˆQ·ßÉ ´òÏaç[/”äd ÐŒ}GZM.åï4Û{‰B‡‘0^™¥û3ý‹ìâæRøÇœp[ùb“N³û¢[ žUN¸ÓеEP[ŸøúƒèÿÈTpnûuÎÌnò“霵IsÿP}ù Š/{r¡Š‰aÔrÜÐzmüóÞÜ[LÑÈ"Pw¢2s“Æ^jК[›F{eò¤ÉÏB1ƒŒâ™kaä\µÄ·Ï1MŸ œà(–Å¥°’ÔÝÎ “ûÜÀœtü(º]Ô×)8›cyRY#,ƒ¿…^ªöV¦Ò™¤QÂåBíœ ±@V»ÿYmÿ]þ€Õf«]ÿ­¶ÿ|ÿè @FBê%˜àI'ñ¨l59nõI!Ú‚ÜÄ$ˆÿ ã'ØÔÑ€Ú‰ =ùA¤ÙÛ_›¸!HÜÇåá9Î~´ &YÞxe0«FèÅA•Žøî*®‘}-ãÜ$¥BÀT)œîžEZÎ!–?´Ë¹Ø°sŒ¦{:S,ìE´²ÌÓI4Òà3¾:ƒ€-ÑEZ÷¤?õÕjÿœ?õÍÿšÔ×½!ÿ®«P¯ü„áÿ®oüÅ2Ë…Ô/ ¸òŒpÆ$]€ƒƒžOµE£ê²ß:ùûPK™ydd¼O=}XM+¨Kv×R?š»2«·o83Þ‹=.;I’A4’¤JøÂ)ì=zw »¿xô님`}ñȤg¯Ó½G¥j&ò{ˆH¦0…a, …`sîzb­¥»¤2'Ú%fv$9ÆS=‡Ò™gd¶­#™^ie#|ŒœtpZª÷ßêþºGÿ¡Š±Uï¿Ô/ýtOýP ÿÖ¿VÿÐMÜÜií%1L>jmpçœÐßñýkõoýÒÿg7ö§Û¾Õ.vìòö®Ý¹Î:g­ rÈ"‰ä=K²´Rkâ<݈ẻ<¶RyíØV’Ûþòfy]ÒP–ØÂñÛëU­4¤µ•\M+ùhcˆ6?v§ÓŽz´Z=FítËù¥X^kYܪœê}ê]+P’è\ù…dã ˆP¶Fq´óþ4‘èª ¹†k©¥K†ÞÙ 0Ür0=…Xµ°í4<’Í0¤lé€;Ðs/Ÿ¥´¡¦vºá‡ÔVEßß—þÂÐí*׸ŒÃ¥´m+ÈU1½ú·Ö².þü¿öƒÿiPGEPEPEPEPEPEP©÷u÷#þF´å†6•˜‚žJ±\þF³5O»¬¹ò5¬û··¯­Eöxÿé§ýýñ£ìñÿÓOûúÿãOù½ó£æô_Î û<ôÓþþ¿øÑöxÿé§ýýñ§üÞ‹ùÑóz/ç@ û<ôÓþþ¿øÓ’$Œ’ äõ%‰?™¥ù½ó£æô_Θ xcvÜÀîé•b§ô4Ÿgþšß×ÿÍè¿7¢þtϳÇÿM?ïëÿgþšß×ÿÍè¿7¢þt€gÙãÿ¦Ÿ÷õÿƳÇÿM?ïëÿ?æô_ΛÑ:D‰’ äñ’Åêhx‘È,GpÅOæ)~oEüèù½ó¦>Ïý4ÿ¿¯þ4}ž?úiÿ_üiÿ7¢þt|Þ‹ùÒŸgþšß×ÿ>Ïý4ÿ¿¯þ4ÿ›Ñ:>oEüèŸgþšß×ÿT…·(;ºe˜·ó4ï›Ñ:>oEüé€HAaÈèA ÄS~Ïý4ÿ¿¯þ4ÿ›Ñ:>oEüèŸgþšß×ÿ>Ïý4ÿ¿¯þ4ÿ›Ñ:>oEüéϳÇÿM?ïëÿgþšß×ÿÍè¿7¢þtÕ†5`ÀGBÎ[™¥xÒLoÇB ~"—æô_ΛÑ:`3ìñÿÓOûúÿãGÙãÿ¦Ÿ÷õÿÆŸóz/çGÍè¿ öxÿé§ýýñ£ìñÿÓOûúÿãOù½ó£æô_΀öxÿé§ýýñ¥X#V :nvl~fóz/çGÍè¿0ãIgŽpGãMû<ôÓþþ¿øÓþoEüèù½ó }ž?úiÿ_ühû<ôÓþþ¿øÓþoEüèù½ó¤>Ïý4ÿ¿¯þ4}ž?úiÿ_üiÿ7¢þt|Þ‹ùЂ㑹هäMdÜõ“þ°í*Ùù½çX×=dÿ°¬ûJ˜%Q@Q@Q@Q@Q@Q@§ÝÖ?Üù×¾~µ‘ª}ÝcýÈÿ‘­wûçë@ EPEPEPEPEPEPEPEPEPEPEPEPEPEPS¥‘wG e= `3Oª·Ïc¦Û4P‰d‘Ò%V}£,q×€,¤Ïü|Qþ‘ÿé Źpͻר­R¡%¶E£qÚ—Èùø“ò_ð¥Hv¾övv Øãò ëþ=eÿpÿ*‚þÍî'‚æÚa Ä Ì»”ƒÔùU¶PÊTŒ‚0j!‡yü?ÂzŽ‹s¨á®.`w1”!¢%WŸ¼£<±.’dK•ó€óä‰þïM˜ãñÅ]òþ~$ü—ü(òþ~$ü—ü)žú<²XÍ`÷(m“òþe;· ó‚3Kшh¤Šq/îaÚ¬1Œž¼š¿ä?üüIù/øQä?üüIù/øP¡ÍÌßEþµ“sÖOû Áÿ´«b8Äyä±=Iêk笟öƒÿiPIEPEPEPEPEPEP?ªY$àŒ“ø¸Ú¶¸ÿ§Úõÿž«þ4—ú’_ÜMh–Á?ÖÈÊAŽÊi»5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñïím;þíïêÿÚÚwüÿÚÿßÕÿnÍkþ}ôïûüÿüE5¯ù÷Ó¿ïóÿñ¿ÚÚq#ý:Û¨ÿ–«ëõ¬×–9¢2DêèÚ¤e9ýUhìÖ¿çßNÿ¿ÏÿÄTsYê×MÏ’GñÊÅ%rp¬¨ô  º(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€?ÿÙfotoxx-12.01.2/doc/images/pano-pre-align.jpg0000664000175000017500000015473111701011016017172 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 598 976 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀÞ "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmÁŸM²fkX‰-n„’Pd“Šš+Yæ4Û6oSj€€z<û›Eÿÿ^‘è«jÛ®.¡‚ÀãQŒnY{B„ò_ÕN>ïr8éÿ°è¦ïì£M±3ÞÊ-Pí^€ž8Ïo\J›û#Jÿ ]þ'øTZ) ’Ü£%â0kç,ì=ÁÇÛc¡$‰O,®©ÌÌp¤žÂ€*di_ô ±ÿÀdÿ ?²4¯úØÿà2…Eÿ ‰ÿA?ÿ“üjÝ¥å­ìF[+˜n# ´´RúdwäP6¹/‡4xçÔ4Û@’>ÅÙfÎ3éíX¿ð—x#þ|!ÿÀÿ êîɾ™ƒürÿè¶«ìï°üÍÓÖ€3 Ót‹‹x§K±Ù*+®mPpFGoz¤-ôüÈ'MÿÀTÿ ¿¡ÿÈ¿¦ÿל?ú¬àÜ ÒœS½È›hwÙôÿúéßø ŸáGÙôÿúé¿ø ŸáIš3Zû4gÎÅû>Ÿÿ@;ÿSü(û>Ÿÿ@;ÿSü)3Fhöh9Ø¿gÓÿè¦ÿà*…gÓÿè¦ÿà*…&hÍÎ!ÎÅû>Ÿÿ@7ÿSü(û>Ÿÿ@7ÿSü)¹£4{8‡;ÈÓÿè¦ÿà*…FŸÿ@7ÿSü)3Fhöqv/‘§ÿÐ'MÿÀTÿ k+Xèºrç¦mSü)†’dD8f`ô­9‚ÛI N¬-â$†<ïo§¥7§°”›3ä³´Œ¨}NRÃ#6©ÏéO:u·œÑ.‹§3¯]¶ÈqúUùMsk#H\,eØ•Æ@ç4ÛWûE»eQƒÊL¹la}jl­±W}Ê`¶1F‰§ìOÙSü*/&Ãþ:oþ§øV•¤~\r¾Ý±2°Y‹ô˜¬ÈÎ]G¸ªŒbúäоM‡ýtßüOð£É°ÿ N›ÿ€©þ«}„H‘Æ7¨ˆ€=3Ož$Fäó•AÚáøv©÷{Þîcù6ô Óð?Â&Ãþ:oþ§øV®!‘Ñ¥H×lìœ Çüi¯yí–dD—%¤ ÓhéOÝ웹Ÿ-¥¤$ 4m9K ŒÚ§Oʇ´³DW}N ÿt›Tçô«·r%Í£M¥Ú)3’¸À=©“™.m¬ÁmÒ9a’}èQ]·ÜªÖ–KHt3kçèÉÛð¦y6ô Óð?´­¢]ÖJÈ„“ nÎ3Cˆ’{oµ,i!-¼?‡4Z=‚òîfy6ô Óð?œ–ö2:¢éif8è©þoQ†Ý•¹·dÇŒ}ª=? ò\7HP·ãÐSå¯a6ïk‘Íegô31l‡§^Õ“aÿ@7ÿSü+VÙƒÛÚÄꬲ 3‘ÏsÅ"$_ed_gòŽç?x=M¢·C»èÌ¿&Ãþoþ§øQäØÐ'MÿÀTÿ ÖFU@Š3‹o3%GÞ¥D‡í’b5ó%e@S×ñNÑì}ÌØlm§Å¢éì\Z§øREgg+”]MÊ‚Nmc…hÇk¹fHDD e±ùUv/ ­Ì²ŒM3ìǧsE¢úÙKʰÿ N›ÿ€©þñkdaiF‘¦mRÿFOð­YY#†/ݬerƒ¿Z†â8QnU ³ Î:ŒÑhö ¾æo•aÿ@7ÿSü(ò¬?è¦ÿà*…j:bö1,p­¶O”F0Üq“M’%ŪJ±¤Ä“ NEa^]ÊrØZÅwÒ4°2>Ιç§j‡Ê°ÿ N›ÿ€©þ|ºÜE<ÅA-:€Hä ô«LÈ$aäÅp#ûƒî‘E—T;¾æ7•aÿ@7ÿSü(ò¬?è¦ÿà*…kÙÀ™WO5Ô£åÔõ¦Yš(Õ<“Ãù±¸žØ£Ýì÷s/ʰÿ F›ÿ€©þyVôÓð?µ-V§«,>o æcnGçÒ£ž"ÚtEQc?(¨Ë“Ü´íÚ¼»•>Ãkå,ƒFÓJ°$bÕ:§¥CåXÐ'MÿÀTÿ ÕŽL_½¼eIŠзÒÚ"ùO¾$ÂC梅à~=Ò•£Øw}ÌŸ*Ãþoþ§øSžÞÊ6Úú>œ­èmWü*û :c2 ‰FH, ïàg¨4ºƒ)™$ [22N=iÚ7ØW}Êkf‘£¶‘¦aóôdÿ g•aÿ@7ÿSü+R„½™XÆÖYÌO¦iAIaPÑD<ËvrB€r)Z=‡wÜÊò¬?è¦ÿà*…]‡ý4ßüOð­F‰–K(`" ®}3×4\ZÊv‹É1*®Í¸Ü=sÞ‹G°¯.æ_—aÿ@7ÿSü(òì?è¦ÿà*…kܤ"ÜyVûã;v8Ú~½i—áïmÁ ŠrÆ= ×h\½ƒÞîgMkg „“HÓ`}™8ÏáLòì?è¦ÿà*…j[3ܤóÇní0ûà/ÿªi FâsY#óví ®Oj-ºßFdùvôÓð?Â.Ãþoþ§øV¬4 Ž6W¸t9\ñÏz Ž/%p‘ñ367ž(÷{½ÜÍŽÖÎD‘×HÓ6Æ2ÄÛ'øT~]‡ý4ßüOð«2'K?ŠwÜÝ*žjÔ"úæÐÿ.Ãþoþ§øQåØÐ#MÿÀTÿ fhÍ?gÁÎÇùvôÓð?Â.Ãþoþ§øS3Iš=œ{ ’yvôÓð?Â.Ãþoþ§øTy£uÎ=ƒ’l°ÿ F›ÿ€©þl°ÿ F›ÿ€©þhÍÎ=ƒ’l°ÿ F›ÿ€©þl°ÿ F›ÿ€©þhÍÎ=ƒ’l±ÿ F›ÿ€©þè¡°y‘“¦á˜øõOð¨sR[ô¨¿ß·N6ØjlÖþÈÒ¹ÿ‰]ñìŸá^Uñ.-|L‘ÛA)öd;b@ƒ9np+ØW«ÿ½ýyÅ?ù“þ½Sùµr£Ø_ÛZhúTS7Ég*ÇÈHT@OÊ>ðüêTÔì#.cŠåL¹È²—,qŒŸ—ÒªigèöçoWïµXì® ·h®&–pÅË.3üÅFu;•e1\™Wû¹ã#îôà~T“jZ}ÄA™A§ÚOo6ò©g6 ` ýßa[©¬Ër;kå³kKç•ó³d$‡ÀÉÁöÍ2êïK¼.a¼,åH¶H8ÇUô5Ýþxj÷ÅÝkÃ{o<’GÌR¼G*H¡÷¥T¼Ö­áÓg½µ–;µ…‚°ŠPpIŒã­ê–1D‘EÒFŠTYÍ…`»YÂH@|ÿø7ÿ[¢òÙ¯$´K¨šâ>Z! .©EK¸úš¨ÉÇa8§¹Îùÿ~ü›ÿˆ£Ì‡ûóÿàßüEk>­g·QÏp°ý—gšò°EÁ#“Çj­}â KG³D‘&7™ò™fER2w1õj½¬‰öq)yÿ~ü›ÿˆ£Ì‡ûóÿàßüEn-å»ÝImÌO<|¼jà²ýGQSn>¦k öq9ß2ïÏÿ€sñyÿ~ü›ÿˆ­K^+{ß²îf˜ vÄ_b’@'3ƒùTï}n— mö˜Â©'Ìñ뎸¥ídÎ&'™÷çÿÀ9¿øŠ<È¿?þÍÿÄV¦±o5…•ÍÄÑ[5âŽ9%’{ õ4ûÝZÎÉfó®có!‰¦hC3h$/^Ôý¬ƒÙÄÉó!þüÿø7ÿG™÷çÿÀ9¿øŠÜ´½‚öÝn-'I¢n†ôÈïNžs -.ÉdÚ3²1¹ÐQídÎ&™÷çÿÀ9¿øŠ<È¿?þÍÿÄUÛoYO–V’Ò Å—@D¥ÁPI保%ý¬—oÜ-: ÍÈ (õ#¨£ÚÈ=œLA$@‚$¸t"ÒpG╦GR¯qxêz†‚àƒø­xõ[ ¢–Xµ gŽõ޳) õ9âª^x†ÒÚ[8ã‘'ûfLL³ RÄ€zôÒö‘"‰xOWŸÿæÿâ(/êóÿàßüEn­í³ÜIoÔM4\¼k ,£ÜuÖ´Á ˜êvžPm…üõÚÓ9ëíOÚÈ^Î&NøñOÿ€sñnƒûÓàßüEn[ßÚÝ;¥­Ü34|G b¿\t©÷SGµ{8œæè?½7þÍÿÄRnƒûóàßüEhÜëö¶×SÁ*Üâßo*ÄJG¸ddÕ·Ô-’g€ÜÄgDÞb7íõÛÖk öq17Âz¼ÿø7ÿFø¿?þÍÿÄV¥¶¹§\éË~—Ð-¹s´ªÙ¹àûU¯µÃ<øòÈdxåGñ}=èö²gtÆùÿðoþ"“tß›ÿæÿâ+j]NÒ2‹ö¸L’!x£óFé3•ÿ f“«[ê¶QÜ[M@Ή s#¡ÇCGµ{8™ þüßø7ÿ@hG˜ÛœßüEt›©ªmª[&«˜Ò7ÚdŒÈ£cžþ¼=ÖAìâcî‡ûóÿàßüEÀ:4ÃþÜæÿâ+R÷]Ó죙¥¼ˆ´D¨²ɹ‚‚Fx#­]Šxç‰e‚e–7WFܬ=ˆëGµ{8˜QÜ$i"$“ áMÈÿ¾*2Я7þÍÿÄVýÝÜVv²\ÜËåÅîf=…WƒV†X$ždžÒ(À%îÄ0{äÑíd̓9Ý6ëÎoþ"”<@‚|ús›ÿˆ­©u;m㸚úÞ8eû’<ª¾‡85γi…åÕ½ÄW&Ò2î‘J ÁÇJ=¬ƒÙÄΖhæ•¥y&.ÝH²›ÿˆ¦fïMÿ€sñ¯ý­lö?k·š;„ ª|¹”€IÎ23S&¡i%ÛÚGyÜ'Þ‰e×ê:Š=¤–ÉafïÍÿ€sñf ctßø7ÿ[Ð^ÛÜ™µÌSÎ×Èiô8éSn>¦k öq9½Ð~oü›ÿˆ£0~oü›ÿˆ­ñ¡¹hJÜ*¬ÿg34GËó8ùw}HM§j±^ØÅpì°³«¹¤UV*OÓŽ¾ô{Y³‰CíÇÌGó¥0Bc6á²¢ŠhâH(aÏ6Sý’¶_R³Ib‰ï`Y&ƆP ƒÓ<ÔI¬Yˆ!’âê s>B$“ -‚GàôíKÚH|ˆÍžäNÀË,Ç )€†ÊA:Z$Á‚GØæçð ÛÖÆïì‚ê#s·w“æ øõÛ×6ãêhö’DsYƒûóàßüEƒ9ß6ëÎoþ"·EôFòkPÍæÃÊüq´’?¨áÕ¬¦†Ö_µGÚÔ4+#…gÏ <Óö²³‰˜?¿7þÍÿÄQ˜1óàßüEjC­Ú˜$–òx­.d·_6P»Šœdg}+A_r†VÈ# ƒÖk öq9¿Üzoü›ÿˆ©tx£ˆÉ6Èó´ )»ÿÀ+¡Ü}M©£ÚÈ=š9¬Áýù¿ðoþ"ŒÁýù¿ðoþ"º]ÇÔѸúš=´ƒÙÄæ¿qýù¿ðoþ"Ÿ Éï*I—r•?èSt?ð è·SFãêhö²gšÌ?ß›ÿæÿâ)?qýù¿ðoþ"ºmÇÔѸúš=´ƒÙÄæqýé¿ðoþ"¬%éŽ)%•WdXÍœ}vVöãêhÜ}M¬žáìÒ9ŸÜ~oü›ÿˆ§Å$pʲFò†S~Å7ÿ]ãêhÜ}MÖAìâsnÑ;3<“Ç'ýnOýñMýÇ÷æÿÀ9¿øŠé·SFãêhö²g™ýÆs¾lÿלßüE¹ÎwÍÿ€sñÓn>¦ÇÔÑí¤Î'3ûïÍÿ€sñ~ãûóàßüEtÛ©£qõ4{i³‰Ìâ ç|Ùÿ¯9¿øŠ±-á–/)æ—g c0Ï×ä­íÇÔѸúš=¬˜{4s8ƒ9ß7þÍÿÄTÊoò¤•w®Óþ…7Oûâº-ÇÔѸúš=¬ƒÙÄç<Ôû9ƒÌ›Ë,±M×þø¦êóàßüEtÛ©£qõ4{Y³‰ÌâïÍÿ€sñbïÍÿ€sñÓn>¦ÇÔÑí¤Î';,Ë1_2YŽÅ ¸³˜`ßî¿ç¤ßø?ÿ]6ãêhÜ}MÖAìâs?¹ÿž“àÿüE¹ÿž“àÿüEtÛ©£qõ4{i²‰ÌþçþzMÿ€sÿñ~ëþzMÿ€sÿñÓn>¦ÇÔÑí¤Ê'3û¯ùé7þÏÿÄQû¯ùé7þÏÿÄWM¸úš7SG¶{(œÏî¿ç¤ßø?ÿGî¿ç¤ßø?ÿ]6ãêhÜ}MÚAì¢sºÿž“àÿüEºÿž“àÿüEtû©£qõ4ý´ƒÙDæ?uÿ=&ÿÀ9ÿøŠ|- s#—œ…`N,æõÿrºMÇÔѸúš^ÚAìâgI­ØCË!¹DPYÙ­%9$íà`W™üTñRÚÙ?ô&¯LñøFõNOüyËÿ ó_Šßò6¯ý{/þ„Õ™g}¦®ÐÿìÿÎÞ¦Ô´±«ØO*“or‡Û)C– Ž„Æ Ó±æh…˜¨;’ðµC‚2äƒþÈÿ ÷:MѺ¸šB¦âÖHÕ¤å–<î=þ´Í#D–ËRó.#iRË$S‰ÆòƒÎ8â·7î\þBãû—?§fæ¨]ÚK>¯er„áŽesžA`Àü*ÖñýËŸÈQ¼rçò¬Âç9xö±ZÊ–ö‚ÚÆ[Eš&Üf.Ü@ÆNyÉüifѯ®­î›ì¶¶’Xíã†9W(Û²HŒüšé#+#̪Àg ÇåRyCûïú… ²1ì­/!Ö¦™!ös’DiU÷¹Æ àe}òqZù¥ò‡÷ßôÿ <¡ý÷ý?€0nt›™uIîÆc’êÖQ–v<îãñ¥Óô«‹]\\`r@R8+ÇüÖï”?¾ÿ§øQåï¿éþÔç¬4‹¸o-H`H¬ç–o´+‚óoÏc#ïs“ØWAš_(}ÿOð£ÊßÓü(Z²½¹¸§Úª\ —¢çaNz2ãæQ×þ^ dÕå–hÚXÚå®Reœ(V+ŽS'·\bºO(}ÿOð£ÊßÓü)ÈÂ9vc·[˜<ôûÚKw!6íbs’9ƒb´K»j¶ -÷šËvd†åÀ :ñÓ>•¿åï¿éþyCûïú…0±ZÁ® œbî‚UJ,Çs‘V3Kåï¿éþyCûïú… ܱƒg¥\ÄöUŒ‹{»‰Ÿæå}ÛqïȨ²õ9uĺ¸ùãŠIJ¿š»v2ªÔ×Iåï¿éþyCûïú…!œ¹Ðf¶Hö©)†ÄA"Ç*£¬¤œ`žjý…– ·¶w7íPþûþŸáG”?¾ÿ§øS¸¬svš5ärÛFðÛ¤v3‹…pZ}á¸#{œú ±o¤Í¾‰Çú2Ì21“^=y5¹åï¿éþyCûïú…aiLÖ3iîÑÄ‚ÞÒHdØGRÀÇQÁ­ÌÒùCûïú…PþûþŸá@Þ£ Ý]]êW)+bf…£ƒÍÄs„28ìLÒA¡Lºœ²O:=ÃÜG0¸!eÆ c$Žœbº_(}ÿOð£ÊßÓü)ÎE§ê)k¥™, ’M4´Ã›wƒŒ=½14}BÎÞØÛÅ î š# æ6á´ž tí]7”?¾ÿ§øQåï¿éþÞ sÚn™{§™bû4­ÄQ«OæÑŒ&ÜÈÈÈÇ©©ô­.k;‹)#_&À[ÊTŒ—õÚò‡÷ßôÿ <¡ý÷ý?‹…„Ís“hºŒ†kõºÛxn…Äpav|œ"–ÆFW9çøtžPþûþŸáG”?¾ÿ§øRm&å´‹ø#H¼ù¯MÌ`°ÃêÀÛ;q[QI,‘+ÏŠFå0m¿ˆëRyCûïú…PþûþŸáNáb†µdúŽ™%¼N©.ä’2ßwr°`¶ES½‹SÔ gÓàGµ¸IÄ-pfÆAÇÎA=À­¿(}ÿOð£ÊßÓü(ž´Ñ®{i¦Ž>Ñq<‘)b&УמN;“Uÿ°.†œ$p+2KVÁ$>y®§ÊßÓü(ò‡÷ßôÿ æ¥Ñï®’æf·‚ÚIVÞ5…d"9b8Î8¤—D¸“òÑÿ´f¸óº2þ|Ž+¡ò‡÷ßôÿ <¡ý÷ý?‹…Œé2iØ72K “íÕÔÀߟZÝÍ/”?¾ÿ§øQåï¿éþ‰c¡ªÏs5óHû¯^â(¼ßÝŽ›X¨ï‘ßÐUÒ5;kXÄPC3‹yíY|à¼;–Wýyk©ò‡÷ßôÿ <¡ý÷ý?ÂÎ"hšÖðiJ-§¸¸¸³v) ócˆò ã;FÂsÓÖ¾‡r°$sG bÊx$¹ä,? WK°ão›&=2?“ÊßÓü)‰+^Ÿg©DëŠûQ2«‰XFʜ߽š_(}ÿOð£ÊßÓü(¬bÜh©w¬Ý]Ü«ÞÝ#ḋp,NB‘ê:ÖT^¹An—™ãkX •ä'–P“Ü|ÜñÎEuþPþûþŸáG”?¾ÿ§øP'-µå–±h‹iÓ=Õܱ©êëžr8#Ò·´k7Óô‹kIYKƧ;>êå‰Ú=†p>•{Ëà2LqþyCûïú…3Fi|¡ý÷ý?Â(}ÿOð¤13Fi|¡ý÷ý?Â(}ÿOð Í¥ò‡÷ßôÿ <¡ý÷ý?€4f—ÊßÓü(ò‡÷ßôÿ LÑš_(}ÿOð£ÊßÓü(3Fi|¡ý÷ý?Â(}ÿOð Í¥ò‡÷ßôÿ <¡ý÷ý?€4f—ÊßÓü(ò‡÷ßôÿ LÑš_(}ÿOð£ÊßÓü(3Fi|¡ý÷ý?Â(}ÿOð Í¥ò‡÷ßôÿ <¡ý÷ý?€4f—ÊßÓü(ò‡÷ßôÿ LÑš_(}ÿOð£ÊßÓü(3Fi|¡ý÷ý?Â(}ÿOð Í¥ò‡÷ßôÿ <¡ý÷ý?€4f—ÊßÓü(ò‡÷ßôÿ LÑš_(}ÿOð£ÊßÓü(3Fi|¡ý÷ý?Â(}ÿOð Í¥ò‡÷ßôÿ <¡ý÷ý?€4f—ÊßÓü(ò‡÷ßôÿ ÍñÿŠoTÿ¯Iô^qñ[þFÕÿ¯eÿК½#ÄQá½Pïøó—Óû‡Ú¼ßâ·ü«ÿ^Ëÿ¡51Í¿ú+þÀrÿ+zßo¼~µmþ§Jÿ°¿ÊÞ·˜üÇëT„ÌýYåA¯Y°íjÙAÇ$r°ÍS“NÔ¥Õb´‹WÔ9!iÄâÙB˜aGút«:ÔK*[³ý«N’fÙw0![ uÆ*Xb-â‹K³Ã§íó¤]§–ÎÖ0ücÒ¥î4gZ­åµÔËq¨Iä\Àžß 2ü£p`,{çŠß¬Sh_êS[ ¶Íu¸o6&]û“€7ŒÀ>¾õ²O4И‹ÿ‹ÿ\›ù­>vt‚FC:©*sŽ*4ÿÅÿ®MüÖ¬PÆŒF¿¼º‡6áU í82g9Ú{cƒëÖ§ë+†ŽõŠm}¢GdzÿtþUKË6’9FÎÜŽsÚ²õIÒõ *»ÀR$n[g;”úŽZ›ŠçuERÑ¢x4{T“†òÃýÜóÃ8«´ +*ç\µƒQŠÐ:`¶Ù¥g ±ðxϯJ½} ·rÃæ p²œWŸ=¥ô:€°òˆ¸' ƒø»äã¯5µ*jw»3©7‘è6÷–—LVÚꊌ‘°? ž¹¯ Ø_ÚÞM%옶©b9;Ç_jéj'dʃm]‡Nµ—}®YAjÒÛ]ZÜJ …f\¶XŒ{ÒpJ0H¯;—NÕlí<Û›i"‰$ŒƒÖ®”Þ¬U$â´G}eyõ¸šÝ²½=Tú±\—„ìoa~ÎbƒÆ?Öû}¯å]mMH¨ÊÈp“’» (¤# Z̳.kùÀ‡*¤á€Y½ùúTö73*Iƒ¸e gØŠÍg´½ÈPì£iR œ@#?^Ôºs$WÑ,ò w9(U-Œ```ujã[™©;Øß¢Š+#@¨®fB\Ç¢SéRÕ]B&–ÛäÉe;°:ž0qøb)ý²ä¶ï0`£ãúÕûIþÑ$u8` a$r±û¢£Æ?™#ùÖŽŠñ•MθR§®yüÉü«IÅ%¡“oSNŠ(¬£’F¤@4˜ÎAõ©*­Ì]^?½Ô¦q»ÿ¯YVsPn QÆ×Ôš)DŠ9ùÀ”ŒøT•™·Û![{7Oï Ó¨ÃVuSºÕh9ÆÁGN´UMK&Ô á ÿOðÎ3í[Ê\©²²¸Ö¾ýøò€’¿3(=sÛ±«hë"F ¬2ïXÑ[<Ï`w±ÿ–lLw8­ˆcH£ ùG=rI=I÷¬hΤ›rZ'¸úLóŽøÍ-7þZ÷Oó¹ ¤ãäΖšÝSýõþb@ v¹?N;Ó^`ƒæG…U¾ºŽ)Ö7‘# ìdñÔŸLÔ2]Úº/-½OïŸçLF„3$ÈY À89ìjJÇÒ¯­¥¾6ö÷1NZ2ÇË`và÷ÇÖ¶)R$ôµKUu•¡¦E ''ž´ ’êú;Vº¸Þ¯VÛœsŠm¶£kurÖÐÉ™U…qü'¡¬;+[h4Y4ùu%2«‚<Ô*¹$ü¿žO¾jŸ†å[K°×7›¹¤H K"³ ´®àj9¥u¡Õì©rMó]­¼ÎΊ(«9B' ¥ªšŒË(Žû­´¾@Ú,NONÐî.âµ¶{™Ã$H73ÐT:v­e©™œ»Ìx-ò‘ŒýkûÁ¢ê6é©Es5טʆdäžý¾cßµYÑ®`³6vçPÎÛ#hLŠÅ2¸*1Ø~F¡97k2¥J4ܹ®ï¡ÓÑEg0V]åõÙ7Ùΰ¶Æ•²Íœ;Sðé©\¦¥qrž!ž+;¦„:!`An™¦"Kný"’yâi­”n>rˆ¥Lu)ý+¦t#"¼Úâêòâæ!{rÒ îˆ GåÅzVTò¿tôúPHTЀii©þª?÷ù CçØâ–šýãü…R×á4k¶³ó>Ð#>_–2Ùö´ +»_=Ëß<0^›},B+n%ˆ'Ÿ üëŒÖ¼Iâ 3S[U½Ñ6ã ç’ªMq«ÿhÂ× t.úDdRè2:SuËiâ–Ý8‡tŸ6v±,p=ÏOçÖ²Uy“:q˜7†Œ[’wìz è>‚ƒÒ}ÕúåJzV§)ŸwªGk"£`’FI8 ­:ëR[[„†MŒYw§î\U-Bm4Ïök¨ÃÌeW/$œÔ—’i6בO4J¸B ìÀÉÆ;žµŠæ³÷Ž˜Ó‹å¼^·5•ƒ(aÐÒÔvøû4[qƒôíúT•¬omNfQE0 (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€3¼Gÿ"Ö©ÿ^sè¼Óâ·ü«ÿ^Ëÿ¡5z_ˆÿäZÕ?ëÎoýך|Vÿ‘µëÙô&¦#¹¶ÿS¥Ø_åo[Œ~cõ¬;oõ:Wý€åþVõgR¼º]BÞÂÁaÜ+Èd›%cEÆN$å‡HL±ho#E¬{8&=ä0 ‚9ÁÓmxo!»7Ñ™¡ËÈl2÷ÈßÎHýQ½Ö†—§¤÷opÁ™] ‘Pez€²O°$Õiõƒ0Švò¾Õh¨1ü #ñ¢ÉŠæ¤V×2}¡ »•%›÷oÉRÆd!zvʯæ°Åv q4J ¬„u%¶OÊGC‚@ÍNuÅŠ ÷–’Û†¶{•ÜÊrª#ƒ×4+¯ü}úäßÍjÍSµbóFì… @X©ê¹+Áª÷w—ÒêßÙºh·GŽ<²Ü+2€I ‚2N9â”·Ø»wi ì>Të‘ÔpTúƒÚ¹-cÁº†¡*yz” ª6ùެo¸­X¤2?X6zÍòÇ,÷B¨$˜[ÙýšNùäÎFÞ¼ät4€ÚžÙ'|èT§w£EuF™ƒ/Üm íü==ª1®«Æ‹œïvÓ4Ø ¬£sdçÁ9ïQKâ4Böö7—ŠY]¨1ˆÎžH>”³f(#¤i (Û«{Óë&×^¶•%k´6B8Rpgu ѾBœç‘ŒjΓ©ÛjÖ)uk,nùÕ1CèqÐÓí‘P^VÕÚ ¡…ÔgÌ™ ª× ÛÞ±¬u‹ÿ²Ä÷p-Ì·rg¼~QxÀÉvÜÄzŽzcÖÒXÇ#ï-‡þöџΫ PŽò;‡G €/úÌzóÇ¡ö¨¿·ã’8 ¥ÅIJ£»D»AŒ!ÚÙÉÆAãÞ¢ºñ40§› ÅÄ l—/"‰‚AÏ4»EfA­Úâe¿+a,2ˆš;‰d• 0sƒkO¥0 cDÔV\š¤ëý·„þ%ê¦.͘÷|Üúúb¢Ä#ÌU–Î_-L 4êWb<ªã9ÆX ØŠ¢bÑ  ÝMI\øÖå¸Õ,Y!–3+íÄ¡òr9æ®éÚÂÞÏMk=¹š/:&?xœsÁã¨àúÒQKaÜÓ¤ A‚ -rÚw‰gžêš{„²J²Áa-²¦ï¾c‘òŽÃ¨ ‰- Œb4Ú3œS*…Ï[x¾Ââ)^8Ý™QZ4GGi70U´’GiÖÚÕÄsß‹«Y¼ïµÇ½¨*Xldc©ÎhK°®‘ÐSå ÿtÿ1UôëÔ¿·y7‰ã‘¢’7ÆQÇPqÇp±ÿ-û§ùŠ` Õ?ß_æ)ÔÖêŸï¯óêC+ÜØÚݲµÄ!ÙzGåP MŪŒõùøÕ;-Nîm^kk·µ·îÙ£a+ èêäí`zð8é°xžÖQ7îî%$)*H;m •$pzŽ¢˜+M2ÆÊC%­²Dä`°ëŠ·\ýç‹,­•ãl‡‘Fé7*3 ÄgæÈ©Á­ØeIàŽhÎRE§ØŒÐê›X.ãòîc(9Áõ¬ÍcR»³¾‚${k[gBZêæ7tÝeH ŸRi÷ä6ú¼lˆ “aQ–T$±RGËÀqפÿغníße\úî?ãK§C:ϤbU9 ÎAªø¢Î+8î^)<kd¨Øw„ yÀ;²=84Ÿð•éÃL’ñå‰%ò¼¶>cÇÝ`Ha†Š`oQXÒk‰ Åéw†KT¶6ÒÄr$QÃ9 óŽžµ¥d×cn÷Š‹pÑ«H¨ ÄdŸJž¡¹µ‚î1ÌbE ZÏ×5 »·ò<˜`·›u4lé F3êH›w¯Ac5œ7)>Ðy‘J˜%Ž2ªNâ¹=@î×ìó[´¦Qn÷?0`6-†:þ•Ц|µÜAl 0 úv¦«2óC¶º¹ûH–he#£#ŸÌZ¹Ôífµ6SY¬w¤e”¶~l‡–?H5™ ÔÒÛ|–ŒÑ4ÅÒ4‘Ôá°¾QŸS@GáK”I$×`îÚå@'9ìzÜ*€: ċĶóÅfÖðv‡´ÿ‡ê3ÞÞµ>Í÷P}ñTÓF+xnÕ¢·WjûeV,âB •ÇaÐ žMÕÝ™e òOÊÃÝnG\p{VŸÙ“û©ù7ÿGÙ“û©ù7ÿNèV3WG‰b¹.nVÚá\7.Ôßœ•ã=Ï|T:ž–oÞÆØÆ>ÍlÊÍ)d…)Žù{VÇÙ“û©ù7ÿGÙ“û©ù7ÿEÐX";¯3ÿLÛù­G{¥Çur—Iqqkp¨có`` )9ÚAŸjž8ü¬ù{=~SÏëNÌŸß_ûãÿ¯Rõ)Òx{mí—Øîn-à†9„²£©•ÝÊœ’Àç8?¥[%¼O YOsfb„Cû–_È ¸òO=y5{2}ïþ½“ûëÿ|õè¯öM¶òÛåæïíGßÀéÓ¯½_¨³'÷×þøÿëÑ™?¾¿÷Çÿ^€gi™¹0³“s1™÷Ô€0=¸XèÖÆÁ,Ä“¨ŽcéÉÈîOÓéúziþjÃ<ï±e‰È+$“·=Orj|Éýõÿ¾?úôfOï¯ýñÿ× ÞÛ Ë9­ZY"Y¡xˆ ô'½P] 1m»ßÞ:C´Àv¦½ áGÓœŠÑÌŸß_ûãÿ¯Fdþúÿßýz¡ý…l°¢Çqt“¤­7ÚU—Ì.à NF9Æ8èôK8–5¦!’XÂC–cÇÞÍ]ÌŸß_ûãÿ¯Fdþúÿßýz¯k¦Ak0–6‘ˆµK\1Ø„àôëÍY·‚;[híà]±Æ6¨Îp)3'÷×þøÿëÑ™?¾¿÷Çÿ^€!Õ4øõK ,æ–X£“ŒDFsŽA=ê»èÞ`F“R¾i¢mÑM˜ÃGÆ\`Pjödþúÿßýz3'÷×þøÿëÐ{h¢(Þ{«v…<Èœnuc–Ýs“Í,š ‹Á4 eŽ9mVЪ°ùQI#y=jþdþúÿßýz3'÷×þøÿëÐ ´Š ««•,^镜6WhÇáV*,Éýõÿ¾?úôfOï¯ýñÿ×  º½åÄÒµÅÔ"å\G€³ÀÎA#ƒŒ‚8§É£ZH.éUn%†V FÅ·htùFjædþúÿßýz3'÷×þøÿëÐS>Ö+””OrÑGæyvìÊcMà†ÇÇ'½I§èðXL²¬÷4qùQ ˜up ääñW3'÷×þøÿëÑ™?¾¿÷Çÿ^€%¬Èô;8â¶EiÑÚB#.®Idn9SŸÐUìÉýõÿ¾?úôfOï¯ýñÿפ2‚英’îî[rF®ë˜vœ©R9¹éH4<¹wÝݼòN³ý ²‰Õv‚0¸éÇJÐÌŸß_ûãÿ¯Fdþúÿßýzb#°²ŠÂÜÅHåœÈòHrÎÇ©?§åV{ç½E™?¾¿÷Çÿ^ŒÉýõÿ¾?úô/ô9¢¢ÌŸß_ûãÿ¯Fdþúÿßýz¡6‰ÍÀ–òòîá³G ²„BÊTã Bzšdµ†Þâžædž·>aQ±8jŽ™êsZY“ûëÿ|õèÌŸß_ûãÿ¯H ¡ÛÄ–¢ÖæêÙí¢ò–XÙw:““» ‚Iç8ëZƒ '©ïQfOï¯ýñÿ×£2}ïþ½0+jwÛÁF¾»‚&B%B¸=s•'òªñø~Ò+Ô¸Šk„D•&» ª$nè­Éýõÿ¾?úôfOï¯ýñÿסhü#ö/TyÃí’¬¬Có¸lã›-ß’jߨRK#kw<×JÍ’òòû Õ.dþúÿßýz3'÷×þøÿëÐmKIµÕ&¶–ë~mäÞ¡²ÞªH¯“š‹2}ïþ½“ûëÿ|õè+Û7» úê×È+óë¹Mg X¦Å†k˜¢U‰Z5e!Äg+’Tž¾„V¶dþúÿßýz3'÷×þøÿëÐ4+ n¯î$Y¯Ð$«»€8É_Bp3ôñ'üþ§ýøOð£þïÏêß„ÿ ƳÑõ;ýÿbÓîgÙÞ\E±šÖ¶ð/‰na®šè Æ%`ùhÿðŸx“þSþü'øQÿ ÷‰?çõ?ïÂ…h§Ã m•K\Y©  œn•£ÿ ¤çþCKú÷?ã@®s¿ðŸx“þSþü'øQÿ ÷‰?çõ?ïÂ…v_ð«´lÿÇýùÿ¾?´?á^ødøô˜ÿÛv§`¹ç¿ðŸx“þSþü'øQÿ ÷‰?çõ?ïÂ…ztðä¬K¤ÀáŠL³©ÍX·ðî‡k(–ßI´GåçùÑ`¹å?ðŸx—þSþü'øS£ñ׊$8Žè9ô[t?Ò½{û>Ãþ|m?ïÂ…K ½½¹-oo ,F GRGà(°\òøLü]ÿ=_ÿWÿ‰£þ?ÏVÿÀUÿâkÙ¿÷›ó¦—ï·çN¹ã¿ð™ø·þz·þ¯ÿGü&~.'kà*ÿñ5ì&Gþû~tÓ$ŸßoÎŽPæ<…ücâøÝ‘äue8 Ú¯øí'ü&~-ÿž­ÿ€«ÿÄׯ‰$Æß ;s!äóG(s?ÿ §‹ç«à*ÿñ4Âiâßùêßø ¿üMzïÚºm‘›=6äÓMÄä|ªýqó68õ£”9"“Ç>)eÎÌôÝnƒúS?á>ñ/üþ§ýøOð¯Yž&¹aöˆ­äUû¢Tó0•ö]©P~¹;mÐJ9C˜òÏøO¼Kÿ?©ÿ~ü)G.íâoüZè ¤Ífr÷Vþ6‰TÛêö³’yB.?J¬GÄùû¶?ðÿ» J9Ps3€:—Ä0Oî¤?Ktÿ £qâÛLÑNdW^ Ú¯øW¦æ”;øÑÊÇ“¿Ž¼Q’è+ Û ?Ê›ÿ ÷‰çõ?ïÂ…z¤–ðJåå·†F=YãV'ñ"©\h:5̦Yô»WsÔìÇò¥Ê>cÎ?á>ñ'üþ§ýøOð£þïÏêß„ÿ í'ðF3»‹gŒ·d€>‚²§øshbo³ßÎ$íæ(#ô£•‡20?á>ñ'üþ§ýøOð£þïÏêß„ÿ »uðîþ0¿f»†bzämÅdÝxC\·i3fÒ*rÒ•˜î‹?ðŸx“þSþü'øQÿ ÷‰?çõ?ïÂ…`OewnžÚXÁé¹ÍW¤3§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(§ÿ„ûÄŸóúŸ÷á?ÂøO¼Iÿ?©ÿ~ü+˜¢€:øO¼Iÿ?©ÿ~ü(ÿ„ûÄŸóúŸ÷á?¹Š(¢¹ñ¿ˆ.­e¶žñ)ÆãÉAFjÓø­ÿ#jÿײÿèM\Uv¿¿äm_úö_ý ¨ˆ¿òð¿ýzý*àë¼ø‹ÿ ? ÿסÿÐ"®€ *Í…Ö¥y¥Œ-4ò*/ùâºÍ?á®·sµ¯ E9ÈfÜÃðã@UêºwÂëŠ6£}4ägrD6)ôç­t¶>ðý–bÓ!gŒpòüäýsÁ§a\ð»k[›¹–f•øT ô·l¼â;ÅV]6HT¶ÒfÄd{àóŠ÷a†Ú/.Þ(á9Ù…§,<¢×án¤îÂîúÚå( äþ•½eð¿H„£^]\Ü¿2‚Iõ滚3E…sžµðG†íc(4Ä—-Ó1côÏ¥l[ØYZ¸{k;xYFG©êjÐ÷£½0 žäšBsIŠ1ŠJ1KJ:Ð!¸¤Å<ŠiÅ!£½©(¤RfŸÍ4Š`5ÙQÝ‚ªŒ’N\ÞÄr!1Ý®GçÒx‰58?ï —9ês@Zk§ÈŽÜ'L4ùð)cYþc,ÊIèpOŠB)ˆi@Äî'f”Æ™-´d÷Ç4f”u üi¦œE4Ði@ÍSè¸ ¢‚h –’–€ LÑGJRfŠ9 çÖŒÓI n °¨É£­âÂŒÓ1M4X (¨·Z<ÃÜQ`%¤4Ï0wâœ0à ÐRRÑ@„¤§bšìˆ2ìõ' ) Fn"ìſ݇éM3±û°¾}ðMEW2\º‘¯ûÇ?ÊšEÙÕ=•2?Z³F*ÃF¤Éç-JY¿¼hLQÇ­AïùšO.?ù柦å–vÊñ’;9e^i â°–ÖfmÇÊ1?‡5¨¸Q…‚”“ëHNïÁš$Ä´"Äg×¥aÞxá@û Áœóñ”þuèù¤¥d;³Éfð–¹3bíŸîØüª4ðα&BZn#¨¤Ö½pÔrÇ  Q_7 âŽPæ< øW\òá'éM>ÖÇüÃæü«ÕÂ,kµ2¹Í bXƒÚŽQóPÞÖ”‘ý9Ç¢æš|;¬ù†Üÿß³^µšBÔr‡1ä‡@ÖüÃ.¿ïѦ Wó ¼ÿ¿-þ뙣4r‹˜ñË› ËM¿j´žßwÌŒ®:¯µ¿º*öÍÇÖ“¯QG(ù Ž£•ì·6wLâÖ)”Ui4M-Щ°€1ÂàÒåcÈè¯Oÿ„KE?òìß÷Ùªàm5™g9 0qíG+2<îŠí¤ðÞÞ^ ¡3ò†CœU< ©‡a¶ì ðKã#éJÌ.Ž^Š×›Ã:Ì(ÎÖ2^»HoÐV|ÖWvê{YâRp ÆTgñ¥aQJAE%QEQEQEQEQEÚüVÿ‘µëÙô&®*»_Šßò6¯ý{/þ„Ô?Ä_ùø_þ½þpuÞ|Eÿ…ÿëÐÿèW@_Ã?ù-Üý×µ~âß ¿äuµÿqÿô^ÖÞÔИÚ^Màr)ˆaͦ›Ö€4¼MÆ( g4ÓJ}©=èšZN)s@iVÐ(I¦SL, ƒÅFîÁ=j »¡ç#Ö³!¿72åzÈ  Õ9}*8d{ÓRQœ{Ðo9ë¢èB…=©npÑ®?ç¢èBy¦„ÇÒO¨Ù¨Å"M.sNè)Ü@iiÄæ’Å ‘IŠLP.)ؘ8 š ¦g4€\ÒsJ)Å0(&“4PIɧbŠ&) Å:˜h ¦SñGÀf("œi(¤Topñá#œç®@ñ© FFM&cšåŸ/J™é¸“åO-!ÆO(éHM $õfüé9 3ëN£4b—4Òi3L-Iš)3@¤4ÒÔÒÔâi3M¥¦!Û¨Í6ŒÐ1sFi´P!I¦“KHh¦¢÷øT¦¡ë_ð ÒQE (¢€4RQ@ E%.h¢”Q@ ¤§ÒPi¬¡†=éô§>crá§µ‰Ø Wµf\xGH™X,O1ÎånŸ…oQFs޹ð$,Ãì׬£‡\óøV=ǃux‚˜Ò9‰êÇzE%.T;³Én´FÓÚ,¦UO¼Û QøôªDÔb½ŸµT»Ó¬¯AV±HHÆâ¼ãëK|Ç‘Q^sàý*bZ1,'[#>¼Ö%ß‚.cÚ\¤ Œ6’ir±ó#”¢´îô RÓ&[W*K'Ìg:26×R§ÐŒTŒmQ@v¿¿äm_úö_ý «Š®×â·ü«ÿ^Ëÿ¡5Oñþ@~ÿ¯Cÿ E\wŸäáúô?úUÁÐYðËþGK_÷ÿA5ímŠñO†_ò:Úÿ¹'þ‚kÚÎZhL”JAÁâŸõ C1ëIŽô1¡M0}©7c­›@ Á¤éNŠBš &qKœŠBh4Œi{P!õZåö©úTìp§5FMòzuÅ!”]÷ù©!/O¥d[Ì –P½üêäÌ Åê3Ž€ŠÂ #ÜH¨±Zu–סâùMMíbA8'ŠÉ¶’Ww=ÅhiÌeB¼gå¦Ù>âóüküÅIõ¨guP ÿy6K˜ÕOÍÒ™%‰$ ½jûŽjÍØàôÅ: ‰ˆ°éHeÕÉÅITEÁäU˜¦=鈚’ŒÑ@%(( šLÑ@i)M%.h£¸  Ð )¦œÒÑ@  âƒIL4”´P Å!¥Í!4 CQ7¤5ýêLÒQE! E-%0Š( ›KE%¥£ŠLQŠZ())h ¤¥¢˜ IN¤4i¨úé? œÔ þ¾_  cé1KE E;˜ Š)i€”Râ“€(¢Š3Fh¤¦š3II@ Fi( ¤4Q@%S)¦HhÆé^kâ¿ù.?à?ʽ,×™ø«þF Ÿ¨þB¦[ÌŠ(¢³,+µø­ÿ#jÿײÿèM\Uv¿¿äm_úö_ý ¨ˆ¿òð¿ýzý*àë¼ø‹ÿ ? ÿסÿÐ"®€:φ_ò:Úÿ¹'þ‚kÛH¼Ká—ü޶¿îIÿ šöêÆŠPOzZB)ˆF™O¦L Í!Å4µ&êp šaznê,+’b“uG¿Þ“uLŽô}*-Ô…éØ9ÁÆx5€lÈ8ÅWÈË}…1.”BC·>ýé ÄÖæ!Õ£ºœwŒ’휞X8Á®¢öÝ."wQÎ1Çzå%Bo€QÈozLfŸÚÎHÝÔ–àûWA ›-ãÀÊØD“^´¤n[+¨óc‚Ü»‘€8”Њwò:« =·{Êû\þvw;ƒÞ­O~“H逧–ÈèEArªŠ]1–ühÖ°(Cgš½¦_´–ÌxÏÖ°nO.}iú\åeÚOóJác©ó²8'ƒZÜF̶š"ÜÀw5|LÌØLmî#@0Ç&–ª©sÛŠž<÷%ú-Jd]¹ÍUY”ÞLì´î"Å•GzplŒÒúLRfŒÐÑIš3@ IFi3@ A¤Í¦ Å%.i %&)h¦RRÑ@%-%%RPE”Ä!¯2ñAψ.¿ÞÈW¦×˜ø˜çÄïÿAS-ŠŽæUQY–ÚüVÿ‘µëÙô&®*»_Šßò6¯ý{/þ„Ô?Ä_ùø_þ½þpuÞ|Eÿ…ÿëÐÿèW@gÃ?ù-Üý×¶W‡ü:–8|am$®>I8þ^Ù¸SBd™¤-LßIº\Ri¤ÐM4Ó„ÓI šBiˆBi  ši4À\Ñšfi7P‰¤&šZšÏŠar¢ª¥› ¬ Ëà]1ÙZÓ¸”•qØzÖ%Õ´p±Ú9ÎqIì/ŠÀÉ3ŽTúŠÁÔæYŒ›N¹Ãz±È“œmÚ~UÉéÿÖª—ƒlS©xù†9,eÍ?lh dƒë[eg´1… ö¬mÄÓ ¬{×{ˆÐ Ç­4²KhβXœdNißn'ÌyÏ-ÕÄSÈŒä|²ý~SÍeÜ\¥ÄA@þª‘‡›çKµè*¥LW‘Í4?ï \“޽)»ßaó†Nr‘[ÁÉf縛+Ù7ÅÊÃ<ûWic"OAT„Í Rž:Taš‚âõ"\äP.ã5^K•áGz¯ÚÈåw ÅSœºÜ 69È>”€½æ–‰³éŠä"Ä‚yÇJd $ŠÃ‚§ó °’F8vSjBïå]*® O¹w]¨£8ä­T–EFI“œ°Sþ:‰nešG.¥IùA¤ÔOå‚s’M,·DJ Ý+6)!S’ý8ô¤ˆ³L77©&˜qJ-ÍIÂB}Ž*„³F§µ®V,“†'ŠjfƒLŒ’€šÌ“PQ¬=®ð6ÄO'½0,øÿ´Eš[ifö«HáÔ2œƒ\,÷& V{¯=]Êavžµ½áÝA§·+6F½Z.7© U7Ñ}‘î?Ž+-µåwµD* §,sÐf˜¬oRR+Rö¥ ÔO÷ªZ‰þõ Òdg­#¶ÕÍR’b¬}ÍMÇbܲRsȬÙ.™ÉÚxéIw2°ûÝ5GÎEwçŒæ‹…‰à½¸ÉÏÍŒV·›˜ò9®q%D¹ %õ­=Ù¢&N„à{ÒCçÉÝ…Zw)ÉÆ²r÷j_&]…Cp{f˜ # "+ ܤpj¤E ˆ©`S8ÉíRÁçÛ0ŽhÛÉ'ïc S{É-·]ËŽ´€mªÈ…Ëpƒ[ÐDX‡º>í`DLI$r ²°O׊é"‘Z0n)¡2;©Š+2öS2e²=*ΠËÐÍ•¤1FT÷ô¡ %”²Ÿ½·5<€¬a^•X!3ž?.õb´€‘¹$Ò a¼ñ¼ô&¦ŠG,\Ÿ”tT3·l“ŸaVÕt s@å™ÄjXàvª1NÍs+–ÀÀãÖ–öã| ç8ª+4HîÄüÛ@úÓl ï©fPû½~µ«or®™ï\šË¹È-žq[šqûN ’_ZIƒFÊœŽ)iˆ6Œfš²E¢ŒÑš))i(¤¥¤Í0’Š3@Q@))sI@ EPIEJJu%0¼»ÄŸò0^¿ýzyoˆÿä?yÿ]*d8™´QEAa]¯ÅoùWþ½—ÿBj⫵ø­ÿ#jÿײÿèM@üEÿ…ÿëÐÿèW]çÄ_ùø_þ½þptµá+¨¬õø'ž!"(o”ý+ÚtýF;øL‘0|pYzgÒ¼GÃS5¾»m"'8ùþïã^áiÃTT¾g)ПZ¤L‹Í&ÓFÓÞ¨‘wi'Ö—o½!J@4ŸzBiÅ1Þš@¦sIš\RïL“HM8M" fÅWº›dLã°©Ø š¡|<ÈYWñ  y¯dy׊’hŒ¥KŒíã½EQqò¶ÝìÚʶîRbQ€}ªJ*Üùoµ üàŠ¡Iƒ&Llœ¨<~§{qbËù¸Æ+2íäóã‰HWßÐô“,i{>Ä7·(v‘žôû¸$¤^HéÍE¥:¼ó‰aY ÛïRj÷3E '¨£ 2àVBœÔÖ4O´†§Šº0erj™Ñ•(YXt®wSºo´ƒG ô¢'f…k6ï{:íaŒàjF­…ˆRyÜqƒW®g¨;¶‘ÓØÖ\1¬e7JÒàúÓœï¸Q–]À C/´Î–èç‹b´7/“‘Ì£šÉ•Ã4h?ˆ…úsWoå[p~€ç­03¦¹ò†RX¶äöæ­E!XÑŒyÏ<ÕV–),ƒÈvœ€§ñÿõÕæ‘f BòGáH -¡Û,Ó\ 9Ûè1Híq“8¤–eX–fû¥pkž×u"É|µ;å$“ìh¶ò®Òèw±]ÜU‹7ÎÖ—·½rºmû¾›³ÌfÁooJ³u¬%” €ç§©¤h’‚¥²1\­t³kòLîa~F#©õ«kí:J‘d*¯õ®ríä†bXœœÐØή“î¤L2…ºâ¬X\ˆŒ— 6Ÿ¾k&I^CºF,z úSF¥p5$Ö®$´6Øã&š²?™ ”Žê+,65v¹#x O`yÅ ÞhZ¤‚Àž7ÞoRko5Áh—â ƒˆ$šîNœaPWmo0–0r¥»àäU¡æ¢sóS‹`dÖmõòĬAçµ î_ ŒÖ=õØPzÎ}ZI%Ûº²î.d“Ïߊ–Ækä(õ&¡iÔÌQÛ‡ZÊYŠŒ6KcÐîÒ§JWIæÅÚùgzpµta‹M’Xùe^+Ž‚r¬Ítër«§œ`&Þ¦š™YnïÚNwç©®‰& ±¿˜C Ö · 4û*>ö*þ›°Èñî2 ¿xœô 6Öi6À:tȪ±Û'Úd(ä8@È}9äS¬¤1HËÑãåõ¨ÒPº¢2°êTç¥0!™‹Ü‚¸•úÖŒW>NUÉϽeê[ ¼V vÈG5eÚ#6×$Œw  ØÉ…ƒÞ«F{àpÝÏz¬'•1üÊ*¥O0ò£œ| ~¢Ö‡eüÑ“÷Ò§‚àˆä:ž};U5Ê\«tûFIöþª}É\¤áÇéHdöˆ$fr?v„}h¹Mœç¹ÅIl4.-ó†õŒÌ€7 sõ¦#>îVÚ ôQ\É'¶jܱ1Æÿ{ öªó¡Š@€3R0„s·žµÔéJ¢Ücƒ\Ü ©‘žqé[– ûÛêi fÊôëš\ÔJÛS-Ò˜n±æ¬’ÆisPE(T™ æŒÓ3Fhù¤¦æŒÐ¨¦æŒÐæŒÒQš\ÑIšLÓÔ”™¢€’“4f Fi( Íy_ˆNuëßúêkÔ«Ë5ãnðÿÓSS"¢gÑE%v¿¿äm_úö_ý «Š®×â·ü«ÿ^Ëÿ¡5Oñþ@~ÿ¯Cÿ E\wŸäáúô?úUÁÐŽ„":š £yiá:ôë^¿á˜­#Ži,_i !9Œc¥y‡.þŬÃ>Õp¹ ¬pÇ"½FÖôËøUmY"|sàŠ¤K6wÒ5™geg{w¨Kq ÌEª±cÀò£8>¤þu;éÚQÿßMþ4ciŸóåýôßãG0rŽ'ÞšOìm3þ|£üÛühþÆÓ?çÊ?ͿƎ`å;Ó<Á’)çGÒ‡[8¿oñ¦ÿdióçýôÆŽ`å+Jÿ?û5^䯒ȫÔu©î"ðÅ­ÇÙî[O†n?w$á[žœÍ[þÄÒO?`„þ'ühæS™¹L(ƒ•æ©It'e‰±ŠrGCøWgý‡¤ÿÐ:×üi§Ãú+¶—lqê¤ÿZWŽFIƒ[Éwl÷úS'ŽmÎâ 8ÞZè®cð¥«Ý¥Åµª5Wœo7ÝúçÚ¯ E‘ 6Ù•€ àœŽÝè¸Xäc k¬È $A Ç­Qñß™j`N Ew§AщÉÓ-Ééœÿ:‚}Ã4kqcaLá#`cÐ žOµ oor¦8ÀÁ¦Nø98­z‡ü#šé¤ZûgGü#šë¤Z߇cË\³Ä2Ë´žÝª6ýßΧåëÕ¿áÐÿèiÿ|Qÿî‡ÿ@›Oû‱æ&w•c ¿.WS l2#×¥zü#ºým?ïŠ?áÑ?èkÿ|QqXóÈõ 0AÓ¿½:iK&Ð¸Ë ôøGt<çû&Ó?îRÿÂ?¢ÿÐ.Ûþù ,pšŽ!ÓÎf~2;ZM2H£eŽF È7:æ»Ãáý†K¶#Щ?ÖxDãJµÙh Måê#y‰ü.1[[ã¹ÓŒŒ ¸†kÇ–ÖÚ~¯m ¼p$–ä•L€NîµZÇP¢Ù,¿0ãh¡13EÌ/¦œ}Üô9§¬SÛij;œã°²°It;q\VÕÝÄ­`‰€—m6âíÛLòƒŸÆ¨ë/:KÁ/2¸IþBšøM>ä–ašÆÕo¦ºfY#U¸Ï\zP2$¿š8ÀU9úÕiçiÉÞÝóÍ4FO~{ kü‡­H‹:t¦;…RØRy¥¸”É;` ŽÍöÈem¿(àôgס41 O^($äæ1F9N3ÛÒ¢$*àRÝ©öò•aúTjr¤ÓwÍ1 ¼ñ[ ‘¤ù›’IÏé]f‰ylÖ£lƒw¹í^hY˜þ­¤ÜùQíëÏ¥R`zň ‘\Ýì›÷W’ãýtÌ£#Þ°.nþs·§½6ŠxDn­Ÿ½U$„áäõ5,÷k0@8+K-ÜJÙQ–)É÷©UÜ'$çšD—ÀïP“¸üÝ)# J¡Ž57bÜ\‚´$½ßgä—Ø¸ëTá v‘óŠžY M5cHwÍݪˆK¼’!W±æ´´Ï›tÀE êÇ,k 'häÆv1êM]Šô«’]W°N´&#¬>[Û©VESý+wÝ::˜˜^³Æ6õÖuã—‘š>Ü‘Nã4uQ¶í’^?˜t%eµŠá›8ÇáTÖ@Ön%;®A­E¦»=¹Œ>:@š®CÓÒ«_í6o~mÀ(ö5ׂ 830Ydz¦/ãy`s÷,ïÚ˜†ÜïK…ÿ‡#°«øÛqñ¸í¨n“,ecœ2îüê{É"šòÕ7î8ôÅ!“ÜLÑZ± z©+mç; 知Mqœ¨äâ2Ø×Þª„iБ²3д^9]‹¸9É&ªO)k…bÙl’sÚ®,e„… Ï¥UŠÆæi„dݸ¤‹f Û˜‚1’kgLº'±ÉÀ’¶L  %EÀ5n†ÜîV,Gµ°òœ©sYÛÿËž•]õCÏÈÇô¨R—HÑ~¼Ðä#f •F ã/Ú¢–®mï.9 ¨ Ò“)ÏÖŽpå:åš6èãó§ä†¹½™Œ¨©ãÕdœz=¢S¤iQ~óJOFñ¬Ë·°É$¨ÃÜšØãý\®´{T†ŽhÍfùW‘ýɃ}E/Ú.ãûñúSU".VhæŒÕ¨¨ÿY¯áS%äÒAøÕ&˜¬Ë9¤Í0:·Ý`\Ó¹¥Í74™¦³Fi¹¢€šLÓhÍ:¼³Z9ÖnÏý55ê¯-ÕÎuk£ÿM[ùÔȨ”袊’‚»_Šßò6¯ý{/þ„ÕÅWkñ[þFÕÿ¯eÿК€'ø‹ÿ ? ÿסÿÐ"®»Ïˆ¿òð¿ýzý*àèOÃÑÚI«F—òà!²Ã¨ãŠìít›8.TþòH& Ã9m‹Ž„zà´ð â8í Äú5ºIã@6tÿëÓD²î‹B×ñF0‰p o&:ŸTû'Ø_íĈÎíݶãÙéŽsUì® ¶:¬÷3G Kt»¤‘‚¨ýÔc’i¯¬x~I¢šMWNgˆ’„Ý'ÊO~½i=Ê[é¿h7ñs"è/ú Æ9±áû˜ü¹õ]9ÔÃý)t çƒRŸh„çûcOÿÀ”ÿ@hÑYßÛú'ý4ÿü Oñ£ûDÿ ÆŸÿ)þ4 Ñ¢³¿·ôOú iÿøŸãGöþ‰ÿA?ÿSüh\É+åHÈK®J’;7øVvŸ#NUå™F1$Œù‘Zrjú­¹õ{ à.ÐtÏ¿¹¦Çªøz9EÕtòë¤Ý!ÇÓšs:Å…Þ¥ãjÎÎÒÒvšÉ½ÃcÉËÇZ¹¤ÛÞ§ˆ.,R»xô›H q#’¶ÞC r3[ã\ÐD†AªiØ`°ž<‘îs@×4vuÕtÀíÃ0¸Œõ9æšØ§áS_½¼¥ý´óÈ’y–w aÓ ·(Ôæ—ÅZΫo*Ç,æÆþ 8¬7j°¿Ì@2æFã§Ö®³áõ”ʺ––$n®&Œ1üsš%Ö<=1mGJ¯MóFØúdÐÁn­}$>"˜Kå\ϧÚʘà·ÝÝéÍ;ÅZ¾£kuuæßÞÚà¬ÂNN7–lãžâ»Ö|='úÍKJ~6üÓFxôëÒ²õðÖ§wç]øŒNÝÖ‹¨"Àûzezþ´\Vþ¾ã_Ô58µ^æßR¹ˆiÑ[I*G–Åö†Ü1ÏZÙñiÝ}á¦Æ7jQ}kMµŸ9rúŽ”Ûð3Fwc¦yæœÚÞ‚åKêšc9]ÓÆvŸQÏî8«iµKË»mÚÝükyqnêŽ0Šƒ+·Ž).µûÙü9¥¾ž džgó…ÂÀ±ˆ²ãÀàc5Ú cë‚ºŽ”6’ÃGÁ=Hç­#jÞhÖ6¿Ò jr¨eˆôº©ÈjúÞ Ö6“Ýß^YÆú_ Û&×<ü¬pp8qÖ—ZÕµc6›ê?cGÓ–u™æ¬’ž»˜© Ž>^:Öîª|9ªºùÞ$óË{{{øãŽEÎpÃôíZ?ÚÞ0Ç Ôt¦Š0#OŒšcœ¥Ü^+°[ýL̳y1¬S¨åFwÆFYNs‘Ž w5”5Ÿ |Ñ©iB\cxš=Øúç5'öþ‰ÿA?ÿSüh£EgoèŸôÓÿð%?Æíýþƒþ§øÒ£M_¾ÿEþµCûDÿ ÆŸÿ)þ4ŸÛú $ÿliüãþ^S·ãï@ŽâYÆ»déØÿèUÏCx‘º´qåÏRkâS+ë6.¬ZÔ• ä¸`×*“”Œ¦ÕëÝé\LÜŠáYfv\3ºdã¦+Næïd.Ä+.Ü+b¹t¸d¶<ýæÉÏz’âõÞØ@ËÖÀ·wzÒhÑ¢%I1è;ÖK<›•¥lð ÏzBÄ3À§Ü)1$ŸÞ¥{\±fÝÓœñM‘ËÇ"”® tÓÕ×s±PwP!‘¼cñ©7 â˜=)3Îi¯Ç#šNÜÓ‰Àæ˜9Ï 1Œ PHMfõ qô«ÓˆÜœ‚ªîö¥ý) :)µ$ƒn SšÎ,ìK’*оzœÓÐóš,Ž}iJfâiŸ b"˜Äã$sÚ˜[‚ic%4l"Ä27ËÎ)Ò\ÉäSÇz…Ñ£'Ò‘~ç4)h;“’y§¤Ž…ïÖ£Ç=)7c¥4ÄkA&è”7ËëIµŽîqŸÖ©Àç'§J'`Û²3Œ ¤ÀLÞ@Œäã¡Å.š@9o™OJjK±FÒ7ƒœûS­£Ewpà–ëL “În' \í•[Ó¥ÿJPË‘‚£ŠUµ¶SI&§^È™ü*yìÆJdrÈþ”±Å ¸ŽG# 9÷§—”<¾µ2ÛÜ¿ðãð©uùIfœH'Jl Æ@¢å¸äÒ®3u&‘ìžsìi{MC”Õ]:D\És \tP+>æ ¡ˆ™›çÁbÜ*¿”Yù,yîjÝÌ´üÒOè+G±(Îl‚zSÈÄ…_Ƭ C䎼šÐÓtýÈÄúÖL¤Ì‘Ç·éGÙ¥=I®”iëO+Yó2ìs"ÉÏ\Ó…ô5Ó $ô¥iéEÂÇ64ÿcV"ÓÆFV·…ªzT©n€ô ,A EP1š*ÕÐÚŠ=êµRb–Š`4Æ­Ôf¡kH[ª­ ˆÇp\˜Ô¦„V6*?Õ»/ãIäÝ'Ü—p÷)k¤“§VM^8¥1ʸaÖ©s!hKç\§ß‹?JQ|ƒï«/ÔSVµn­Š“í–Ž9eüj”ä…ʇ¥ÄO÷\SÞED,O )e/B™ö8¦µ’2‘ÌíœÕ{Nâå,† ƒFj©Šî5ÂH¬LŠhštš&>ëV¦˜¹Ykxõ¯/ÔÎu;“ÿM[ù× E:ùŒÊÜÖ¼öüçP¸#¼üènàŠôQEIA]¯ÅoùWþ½—ÿBj⫵ø­ÿ#jÿײÿèM@üEÿ…ÿëÐÿèW]çÄ_ùø_þ½þpt=§ü| {×áï.Ÿb •®r ç^}m‘0Åi@Äp§>Æšv%ž¡§ß&¡¤ÞÝÅ­ª[ø+¬.Ù?1üë‚ð‰Ï„n?ì-þ… wg©¤Ê[ ½¿¼:7·÷çI\LO V?h³¸c¬6 ëbbÆAæãiLýݹíÀ¡Øí÷·÷çFöþñüë˜:…ÔzT—S_ܸ»h!±*Ň rËŽƒ’Ùö¨!Ö/n-lRãPK/1. —P—hØ£9Q‘’xíÅ :ã!ç'§4ooïιԼš{\K°Ëp7ÈJ¦"xôçÒ³#¾ÖMŠ\YË6˜÷Ø0GêGËÓîœý}é½;®öþñüèÞßÞ?r×ÝÉÖ­VÚG`Šh\Ç·÷€¨ûç¨ç8â«>¹¨ ݬó·Ús`wå«ÞÏ<÷àPô –öþñüè2ÕÈÏk‘†ÿY“N’Q¨[º X|ÌïUþÛ†zõ­«Á>›£ÜDÆEšêšX×qõÆ0¸ü(°\ÝÞßÞ?ÛûÇó®.î÷R}*g’ñæ[ȯ#ò¼µ_, }¥Höïš¹%ô‘¥¼zàŽ·yMã¬LY”.#Îô$ôÎ^ôS¨ÞßÞ?ÛûÇó¬ ïï¦Ðô©–Ciq{,)#"T1ä€ÀãñÍUÔ5KÛ[«¥[õY´) £Æ»¯7c,{ä’@Û€ç4X.u;ÛûÇó¦É8‰ Ë(EY›¹É5‹”¹kq:´ëª4>Vq‹n@Ç\ZǾÔn¯tÑššÏö›TžDD@-ßÍŒ03ÆOÞÏJ ÝŽûsÿy¿:cÎ#ÛæJ{]ÍŒ“ÐzÅMB{KMoí·Oýœç,j”Æ r =€¬ˆ¯în|”¾˜H-µKm²³!;Xg’˜Sϧ­ p¹Ù‰ Hö4ooïθøµ…´¶‡í±éñ²\ÊeXÐod€ƒpÚ=O4[êÚœ‘æ¼ù!k5k)v¸”.ãœnæãÔ%pnÇa½¿¼:7·÷ç\Œ:µÃÛŸíy\‹–À‚3³Ëb:c®r}Å2]kV¹’Ñm¥‚ÝžÆ+€‘RWbAw;F ƒÏZìw·÷çFöþñüë•kíGí#]–ŠKù,¾Ïå®vdÀnÎ}IúUï O è–¾¥ö‰¤‰@Y7) Ê€'õÉ .nooï΢»vûÿ3«nþÕ%Cwÿsÿ×6þT ó®Ñ¿ìŸÒ¹• yïÞºo­Ñ¿ìŸû-ràa²=9¨{’ɶ’FMM$Xˆ68RÛ)03à1œö«jsnÎÉ•_áõ¢Ã2Ã/™óà ŽVÉLì4OþµŠ©P{ÔÅ;² ¸Œsyæ·šA¹ÇZqÚ §MrM"ŒŒ´¿w§9¤O­41éÚÐv¦’7qBšã Òž£žy¤l 3 .x¤ÏiÅvõ<Ó” ›Ž(BHj`sRQîì*EçŠl` $S¥$*ý)¸ýàçŠ{H>‚7 ÏSÍ]†Õ…™¸#§J¬ˆ²\(<ä[ú¨i…c< ʤš²]K„U›eX¡3Z32›k5þC·Òº?1môذ7ƒ¥sws³‘·qÎ*)7&ôЩ«$Fä‘Ò€0y©£Œ¿N}é­só V÷#•ˆ­ŒÓÔ’9íNeŒÅŒ|Øù‰ïMHöõlÐØr±äãkgÚ’"ÊíƒÔÒ2åHÍi®pa!võ¡7a4t¶V¾Ly}€ž=ªÚÚÀªBr=)-v‚#ýZ޾Õe$?dGp ˜ä žB®gÜÚ§Ú“ Çme…]Ë?3méÞ¤•7Ü#{Q´GÍ€À“&’ˆ\t—Çv-¼³¼ŒŠŽí2ÈYö4é# ¯)# !©o‡ÌŸCE•‚æGšßl`€@8©o$ÄnX€<â?AUЦ7×úÑ« 3êïS ËÕ8ó!`²¦5‚g‡õ¦ê*¾b0h»Ý\2âK`Þàf¸“›©Ië¼ÿ:퇞íAâ$'ŽÕÃÊs+“ÝQEÆÚüVÿ‘µëÙô&®*»_Šßò6¯ý{/þ„Ô?Ä_ùø_þ½þpuÞ|Eÿ…ÿëÐÿèW@Û®{‘´®2j°ÌÃ5 Áã™èÝÿ|û±Ÿíhº½ w§©®Á™ÿ„:|õþÖ‹ÿB†»ãÔÐ0¬›-WI–ýᵆD¹8óØdŒŒç˜ À8=OjÖ®QÓ/®eÖLIòÜÇn#ËãÍØXºç¶AÇã@ÍÍK O.'‰º®ÐTþ*þŸil‘–‚² Aå…üw)ÇáƒPèÖRÁ&¡(³0\òmA_… ¶3‘ÓÒ³¢ÑßFÒ#:ds}Ÿ wj»šÛHÉÉÃNy4Än¬¶6²Úië±”L Fp«Á?QOžk;ki¦D"‚&2aAÚ€dŒÜt¬ }&êÚ]2iôåºXDêbÜö}ÜqòŽ? ¬º.©=ÝëÍoå=Å­Ì.àD±»7ÜÆß˜û–¡‚:‘ö9<«­–äàlªäÀÕ^ Þ-Lê ,óOÎÏ3f=qµAôtÓŸ"6U"%9;Fë×Fk›oaÒÅ’Èî»ÙÎ7ð9ôçŠæõˆ w¬—6ÑÜ]O5˜†o1 ¡—i;‡ œÎk¡›N2øŽâöKhÝ¢Ç Œ*áØœwÍÍ’Ùã`§9$ô4öq"K ‹xûŽÀd} s‘èo¤é ý—ÂÜn»µ]ƒÌm¤n9;Xƒêi‹áù¥†Ú;Û8åHínT#Â&vÜ2:b†3¦ÛÉ/œ© J¿/˜ZÈÑ-, >¥¾Y^bÑn¹òó…sž@9+œœž”hZ\º}Þï³,=„ &Üa¦RÛ‰¾^õžºEâGoö­,^ÇÚÈ.˜Ë¾ådã¦G¨£`Üêv ýÀN7ôç·5Åg f5ŠÞ8Ër¡}Ç­s^Ô%ŠÚÛpe–ÑîPü‰"ËFyäòqŸjŽ}P¸K{›Ëi]çódº† ‘ö€x œ*‘Èí@¥¦Ûj*–ò\IŒ“^X ŸPÊqõ5n(mbE¶Ž8€UPœ/Lúãk3HÒ…¦£yq4b!H&—kHUcò=úúÖt:Ïöä÷‹­æw–+„0ì WXãÌã¦3Š63{ívÃRŽÅ#C!‰ä@€@#Û9©Ym%A¹-Ý"û¹U!>ž•ÊC£^Go"Çbš|‰¦Ëo%Ϙ˜–CŒ>AÏbrzfª¥‹j3Ý 6Ä[C Úù¶ð´GÌÚ\‘žPžAÃuÀÍs¹U‰€eHÈݼ£¯¯×Þ‘ ‚3˜à‰ %²¨Éê~µŸ¢[=…¤V‹mr±ò£Ìd·ÝÂqƒÉ©@Cwÿsÿ×6þU5Cwÿsÿ×6þT†y—ޏ—G?õ Oý–¹hŸkŒ”õ®«Çó´|Ð5?öZäÈÁ,OAR÷%›w3Ã%³4,£äÁ¯Z‚–WŸÎ³âù°F@ÅkLJÚ&Åv¡±£:ð‰d’BÙbU~ï¡­BªÒ‚T|Ñç–ÓHLòqØqŠRNÜšbí$€w©QëLRB‚h'Ú† Mn¸&€œóKÉíBŠzŽGJƒoAJT/½H°ÊÇp\­+Àìü‚+ŽÅfÆxéN 6Ôâ­;ÊèiÜ,Uò‰?x~tð›Iç¥Må.{þTÂÅrT½hb5)·Üy4×µ,x5<ÈLKB>Ûø…ṯ=œ±gçR8¬ÐÛM„giÍiO,7K/G~ÞõJM2âôf£F¶G+.탃XzŒ;n¶€qÛ5«q\G…À*ëéPÝΩHÊTZÊšjf“³‰Zˆ­L²n8Ç’â×Ë Ë÷XgžÕyo!i $ŒuÏjµm,©2`_;ê‚Ë£0R$1““ØS•æ·ô„¶™Z-€´mƒ‘TîáŽ9ä ùÍSšìO+îgyRuH®–+«AdѶ¼qª¸#¦@¬5”áz©ÅXšÞ_ô¦eº¦¯ª ²dŽŠ `¨›%VÚƒŒóÒ˜°ÎVO,–ÈÇ¥>Ú0·løþåEÐt_:ÝÙ ŒUÜÌÉlÅ·ãÖ¢·žvÜ›sÏÖ´d•×k€ö޽ê¼s½Ê²In±7÷‡zw@R‡Q˜ÊwJ3Ó¥i]Jâ‘O̱d¼‚Þwì›™O$µ±–ñ€6†•fÆŒ¡y(œ>ÈÙ‰ãÞ§Ô$f ‰ËÜcè*ÌšŠÛÒU# óQ]ÙO$K©;.7íZ’Œæš­¤S²G.Ì7rkb „x$‡|kÈ+k+*Pcožä8ÙëW,ƒy÷„‚ ïJÃSû3[Æ·Ù(Î3ÅP±ŽIÝœòã8Q’(ñÿJ±OM¢ Œ‘«Þ?a ¥Ѽ.šKVPÙM½Ç5Q,!ŸLd™NÐqÈïXhìšìýé=k¤ÓŸv'¿ZJ6î^Ó¡{t¹2©Êàúàb¹Ñ }mŽå9N3èjä÷X NsÜÖnƒ3I¬>æÏSÍ%­Âçe~~uª\˳zÕ»¢O—ž»j‘Lô¬Ñcšm³¤{I ßÒ¦š©—û^06m«B Oj¦¨N¯ÁÀ5lÖlòÈ·oµØ`õQÜLžÂÎâ=^I¥‰•ìYz¤eî¥ u=kCK»¸–õc’FeÁàÔw#æ´D³Z¶š[kALø^p3RkŒV[x¶Ž-×'ŽY¼ÔÚÖAz(íUïõóSr+±@r˜ ¸…šÊÑ2zt¨üF§í‹»¢u$…b‘w.pj;é!šDó„lÅGz£:§.:¥wx†CùkZ‚-ÑU *GPgÚ7†'9ë@ڮѨ±î¿Ö¸i¿×?ûÇùס´«,2¢Ä 0ù±ÆkÏ&âgÿxÿ: ¢Š)Œ+µø­ÿ#jÿײÿèM\Uv¿¿äm_úö_ý ¨ˆ¿òð¿ýzý*àë¼ø‹ÿ ? ÿסÿÐ"®€&µÇž3Zpí$Àz˶ÿ\*øÿWÇ=©13Ѽ0ðµÈ¬£ûV™FX+·=Mp 9ðdÿö‹ÿB†»{ѹ ˆ“¶I‚°ñLeŠ+k”ˆÈߨãÊW*»`àãÒ™%âDªÒèʾégaŸÒ´öR#ÚD訬+iãžH³¤*Å$<Íí“JÝþ˱ÿŸuüÍL ã¹JJ[ ¶‘\À‹ddœñU,ÏÚ%‘n4—µh$Ï$ïànàçÅHÍ3QÄäÚÇ#õ1«7ä ¦ÙÜÇ{g Ô˜¦@鑃ƒH ¨¢Š3ɇÎy1y `I°nÇ×­>Š(¢Š©q©YÛNÑ\N‘‹Ívs…EÎ$ð2x¸4nЧoªi×L«mk1vÚ¢9U²qœ ¸æý£aó¦Ûü¡Ë~õx ÷óÏnþ”ÄZ¢³ãÖôɤ-ï ŸÌq18pç‘Ó8ã5¡HŠ( b0 ¥X`‚2 6(¢…<¸bŽ$ëµ(ü…>Š(¢Š*¿øóŸþ¹·ò©ª¿øóŸþ¹·ò 1ñÉýöï§'þË\¶>WôÆ+©ñÏúýþÁÉý+—Ý•öÍKÜDð|©‚=+MYV-€Ž•‹çmSß—ínqŽ1H ãÇ)›Œ¸¹§}¡›êµ z†?_Jb-ÇnÜsK±O^ÜUEfAæ¤{Ð0||Üô4Ç9'½†(“94„*‘Žôå' {ÔJHÏ=iÁˆ к¥‚€ =)Ì[wÞ?A ŒÇT›‹š]JJãòA§qL8õ¤ AëL¶H>”¤óMgÂö¨™¸¤ÄOæ lb”ãªgæ©C1¥`¸®üp´ÍƑ܊nøÁù›ÒÇ—<|Ä})ŒÙë“Hd$`“Nxœ0Ã( ô§¥:)"LnËž¸5ePí4€JJŠVje‰™¢•”·$ƒÖ‘årw4ŒIç­DÛÂc&ïÀÈYÇòÎC˜ó]<æ),c™Kà¨8®a9Æõ´D¢F‘”p]xªM «¢Ù×;ϯä¼IÕ–Q¦ª WɦSnWÛŠ–Ñ#»µ »b-Ï'©§tɳF—™ȸ?.*CåîaÖ³§áƒo;†:Ua+}–V< ™$ÖÈú„ùmÍ\UÙj€vZÄ‹Z‘°û¤÷­á—…@;jR´ž<¯šåsŒgަ“ZÔ®tø£’ÙðXœ‚3ži,Æ.ˆ=r?™¦ë*®‡=>¦´z"Q]µÍ\Çû¨@Åýk¢†,@긥q’ʺT®Ÿkc•@+ºhÖ²î’Þæ)aµŽ{¥dk–þcFÞŒgx~77›8ZwvãÛAg »;ªso%¦–°m%ÐãëM¸–ò)C;¯ëN¸–àéË#Ò–ëŠQ•ÁèdÉäÅÇÙØäðqRhšdö·,±¸È8ÈïHú•ìQ¥8ö§izÅÅíâÀò '¶Ú.ºÑÝ}äÿtU2AŸñVî¿Öè*™ÇÚ? ȶ;¾ü*e¨”ƒ)õ¤ ó@‰1š§.Ÿ;ÊòÈaÇ5d¹)–Ú©i^#ú±’sU ÄÊz]ŵë<ñ•]¤T¦½Ãü‡«p_Ã|?wü<’JÏûr)?ºcÏZÕdj¶RÏ1*ŒqŽ‚«j7/*ùp¹ùt­ÿí'ˆ­'ö†åÜþtX9íKOºy!òávÚ€ uÞŸs-ÌdDø q[ÇP=E±ÿ¾…Úÿ>ãþú§`¹‰5¥áÔ•£Wòòô¥ŠÎóûFyYo%kd_É×È_ûê·ËŽ!NG÷¨°6pêC1‘œ £ÆK“+“×q¯GkéŒg÷h2 yħ2¹ÿhÐ(¢ŠÚüVÿ‘µëÙô&®*»_Šßò6¯ý{/þ„Ô?Ä_ùø_þ½þpuÞ|Eÿ…ÿëÐÿèW@Û®|“äqÜÕnf­€¢ƒêjXŽïÁ\x2oû Åÿ¡C]½ßúû_úø_ë\Wƒ€¸§ö´_ú5ÜÜDd(U‚¼nr22=iŒçî‰.6O4®ÛÁ•rŠð9Í>ýáh¼¡ä8Ú~fþïÓÞµ¨f,Öv“’~nOåIöEÿŸ+ɿº=ª1ölÏÓ¦íV²yÉ·bÅånù·nôýs]Ed¥¶ÇWKKe9nàþUgμþí·ýôßáYÔ’“º.qVa}Ÿ6ß ÊrÜ®3÷O­fÚjp^Lb‚{¦’0L¨È£Ê?Ý—‚};õéÍ]˜]LèÌm×fq‚Ç9ô¦y7ºÝÔ€sõéÍAcâØDS ütWö I­ôø¦[Ûx’É"B–²HÑLî8VN6áˆ#óîUB"¢çj¨QŸ@1K@¿ö}Ò^=àŽìNu"¬ë»˜ H^›sžqÖ¬øf9¡±º­¦DLç–9#yÎIGäÆHàçŠß¢€8”Ñ']=[^‰¿²šCóÉ‘rÛÆ~ÿ'е{¦\ÝÝ\\MÙÏf©uÊ¢PíÉÏ¥u”P3t(%¶‚îIR8îä 2w€F ê2N+\†iˆ Ž9džhmä‰c]ÌÈ hø×YM1¡HQw€T69õü(Î^­Æ©b¶6çR’g¸ ·—–†l;ÆÆ8õ'Š©-ÛÙG iÓDÖúuݳ*ÆÄ3ápAﻨõæ» (Î_ÛOoáûki.çžâim–•QLnNÕ0IÎzWHØÜqÓ4ÆÑÙ²©#•=8§PÝÁ+QHaEPEPPÝÿÇœÿõÍ¿•MPÝÿÇœÿõÍ¿•y—Žiô`;éÉý+ŸHÎG5ÒøÄn¹ÑÿìŸû-bª13ïQ'f4Š^FTíûÔesÐu=+TF:gÚž±¨=³Yó•ÈdýŽO¥;ì…F3šÓÙóuÎ}¨`ÞÑÎÃÍû#ކö_/zÐÀíÒ˜pXG3TT[`9ƒhï“Ö®"j] t\Šƒ•ŸÙç³ Oìùñ Õ\“€ c¹ª÷3ò)ÉîE$Û`â‘Q-ÌmÉŽÔ¡}ªrã8éP†ã­\[ 8ïR")ïP1$à žp2ÀSaqc…ÍDÁºlæ­„ÞyÍ#BAâ“’ØV3›Îí4ä8ã5k=*ÄaJƒ·¦U,„•Ì´¶låêE°W9É«æ0ÇãO@zTJ£èW)U-R.W¯­#) 5<§"ª»Çˆ6÷*:!»Žq´fœ]€À¥09Ýš77­XVbyý)rçøJÌlõ£Ì|ðO֋ɘF0)Wx=Á¨‹¾{ÒÙ'$šarè•™ÉsÎ1š±»,ÊoÉÝ3Y`19Á§F\H4j¶s­ÓïÖ;yX¨ÁÝR™­/ an6±ûÀŠÀVÆeã$Œ~uoItµ…ÙØrGJ´ÛWFRI –štró+o‘ŠÙ¸m¶Êѱpk ¬êvw NÍlÙ½¥Ú¬-*Ÿ—[´}­ä‰p¥‘$rG56¤ÊÂx/œÄÕ©´C‹$2nPzÏÕþÓb“´œã·&´%dª¦b.õ¥l)Ýd¯ŒnŠç!wÍ’v¼¬õäÖ¾v÷vN$›=3JéBòFT­“ÓŠÍðì`Mœº^ÿCZ——Ùnº®çsÀ“øQm{HY`rœ’£zO`F›ÄnE2hTªGŽ1𱆠Äp v¦žÃ–æ=¸Ï#¥bø~kÙÇBEu·ê£W5áµÝ­±÷cBÙÓ]®ü*—àƒÔ ¹uþ½ªˆÜ9ÍAL|g3?·ôÎöúÔã2ÓŠž1ó7Ö5iÿé­Í´ä|£üê¢) ááû«¦öéøÔúÛetHÅV'Z¢EãIü?…!?/àh>žÔÀSÀǵ„òhÿ`/ð¥/¯°¦žŸ…/v n#oe5çÏË·Ö»ùŽ"—ýßé^~zš@„¢Š(Wkñ[þFÕÿ¯eÿК¸ªí~+ÈÚ¿õì¿úPÿäáúô?úUÁ×yñþ@~ÿ¯Cÿ E\Mk=rx­$UÉÇzδÿŸCZCµK¼ð‡üŠ7ö‹ÿB‚»k©6,[CË @Xd ÷®#Áßò'ÜØZ/ý ínÿ×Úÿ×ÂÿZ`Iö;ïùý‡ÿÏÿGØï¿çöü?üUcý®ëûGí?l—ö—Ù~͸lòñýß_âÍ.½u?Ú¯š;é-ÖÊÀ\À#`ŽKr¼>Uÿké@ÿc¾ÿŸØðÿñT}ŽûþaÿÀsÿÅV,W—mz—mu(•µlmw|‹Ñ‘·×ø³]U;ÌÆ†ò9£F»„‰3Ò1ŸïT6×+u-ÄVš•¼ÒÛH‚>‡óýjíëšÜ€ ËpN?„ÕhÄQù^U¬ ± ÆQ‡Ê§®8é@ÆâH’AÀu ùŒÒ‚È9½Cüƒãÿ® ÿ ŠäìumN-;N²ÒíVfOŽf ÞI#nK.Þ~n½(³¢¹á«j_mf"ØÛãf±l!ÁÚ%·c©éг£_\ÞYܦ È·æÂ°˜ü¬ƒŽKÀàᇀ×r)kÒµ{Ý7D´Yü‹¤þÍ{ˆÖ%*é°†É9ÎzñW%ÖuEœNÖw"»y F "-‡\n<…ɾ:S°\é(®{L×noõ%´òâ߀y¶ ò?^¥¸ÏN+¡¤EP0¢Š(¢Š(¢Š(¢Š(¨nÿãÎúæßʦ¨nÿãÎúæßÊ€<ïÅc7ZGýƒÿe¬p@±â¼›­ ú§þËXûMc=ËŽÃu¥$@¦ù±šv6Žy¬Ù`3Hì1ïAÉúSN(x£*3ëO'åéÅ çbi‰‹œëÖ¤Ïn”£äÆEGq'i¢×ÄSJÀSÖ«f`ƒ’GZxäŽù[‚"¿3}ãTÚ‚±š÷™Ul˜IëBZ„o˜äzVª‚ç±éSÉîSŠ`pBïI  )Î¥IñíLE$àƒŠj.÷b$d¯^´ÖŠLá[?Z¿j?„ïN0#¿ ¯Ò«•îMÓ3„2ã?:<¹ÏL-j5ºÁ&šlÔŒ‡j^ø¹bgI!FääãšhŸµ:â,JFzw¨ a©8®¦—,®„ÕfUSœg&¬ÀCÅAvTcoãQ Ú ¢5eÎ8 J0H*!íJŠrsZ»X.î8Ê;¨§ 08ÇåA ·îdÓ03Ú¦à?Ì&—Î#î€ aÆËJ¥朞)‚FäS”‚ÜÒ…QÎ(¸›“¨9枎W$7z„7Z@yà÷ª@Ù d/ËšÓІnI¬?7'µkøja-Ãí9Å(§ÍqÉ®[:;®±Ç¥e^k0XÈ‘]@¼ušÓ^µÈø”n–/e?ηfB–ºmñŠ{9W÷:!8<Ôºlšm³Å)Éyá5Í€Ëwc±Š’q]cË/’žc—"EšW~¼OáMU²’TµÔ$ÉϘ6çžõÓ´Ùd+#ˆîA;wqš«w¡:ÛK«oóN샞†˜ˆ¢¿h-ar7<ƒ¹éZ¾xR!ê•Í_Û\F¶q…cåðÄ ÔÔ‹¥œ{I •‚å‹ýJ!mŒ+?Ã9.¤T.ÒGçX6×rIE9-žøé]† #áƒâ¦ÖLiÝš÷'ý!ë:ÿJ”WîOïäúÖ%³âòW-“»VMìS4¡ÊîrjuïT,&2O?MªØ}# Ó&²cÔ'¶ºl'8åzŠ×*JñÖ±î,¦HÛ̆æô«ˆ¤_µ¾ûeÃ’2£hÆk79Çùô«6#Ón±žO¥U ÜqÚ´Dˆz §¿…ÃúRì%‡áL¿)•çTQ@»_Šßò6¯ý{/þ„ÕÅWkñ[þFÕÿ¯eÿК€'ø‹ÿ ? ÿסÿÐ"®»Ïˆ¿òð¿ýzý*àèÅŠ—¹P:àÖŒˆë•±Ž¸ªZWü§ÐÖúd§\óYNV`u> ãÁóÿØV/ý í®Õ‹C"«0ŽPìdãØw®7¿ò*ÜÿØZçvòÈ#ä‚I8I­¨‹i¦ïíb—ícÍû›±õÛLdÒ]`VÓÜ­¿e&éòñÒ¦Ìÿóç/ýôŸüUŸþ|åÿ¾“ÿЦwéßlûgØåûN1æýŽMßžÚŸûBùçuÿ€²ÿñ5gÿŸ9ï¤ÿâ¨Ìÿóç/ýôŸüU2êé%’W$)læÚAÔcºÖ}¥­œÒKmmt]Á ¬`õTÈ‚y­'’HÔ¼¶Ò¢¬J?#RÐ"BG`•ESø UgÒ´×H‘ì-ÊÅŸ,l&NN?¹E!5«gu¼G2y§åêÿÞúÑkeieGim(Ç,qŸ­OE*ÚéÖ6[þÉg>`Ãl@7O¥-¾Ÿem ÛÚArÿ¬T@væ¬Ñ@Èb´¶†A$6ñFëˆ2¨ è¿AéSQE1QHaEPEPEPEPPÝÿÇœÿõÍ¿•MPÝÿÇœÿõÍ¿•yïŠãëIÿ°b쵌Πc½lx¯þ>´œÐ1?öZÄÛ‘ÍaSâ4ŽÁ¼³Rà÷4ªï½ÂÔ„Éè)Iõô©q…9>´àž ÒØcn?•!mªëŸ˜ð)¬Í+ÁïP<¤¿NµI –2†lš‚O™È< SC’ÃsBåäÆ:õ«Zõ&·LüÇ éVGƒM¢Ê¤ÆJÂNîì´¬39T#‰#½JÜ•)#9àš¸‰—à·Že/ ðW5ˆ]€ôõ©4÷Ìlp"›}‰d.«¼[éËs.£‚àç4ü‚zâ³°Aî?70=XT9¢¹¨#ƒOÇ­e™dÇúƦe?òÕèöˆ9ûÄ+#sבYÁ‰~MK;¹ûìO¹ª™ºÑtDZ¢‡å¨.†GšHNF94æ\žXÖ;Hdj®1L•Èè§ð©Øª`c4ÝÁqZÈw1!éH™ÎÊœÈEžk`qA6")1È Öœ!Ÿ²Ô+ç#Ó+ƒÉâ–¡d!†b{J-¥îôy®[$ÒyÎN3Š5 !â×=ZÚ€ršA+cïP¤·9jº†€:·PsÚµ´I!²•ÙÆÜJÍ' ךjÜ8îjâÉqGXÚ´ )ÍșúhšPAëH— ƒ‘œÕbw6à:gùÕ¹ DÑó­¡{f•¥EP1Ó¥lO~¯w´@6dRÇÒ¹Y$ýàÞ&´tÇúêÀÒoT8Çr-nv’îHŠŒ&T~5kCÔï-W )(‡nxªZŠƒ¨ÌIêÔû& 1‹PŸÆ†ÝÆ’g[ý±i± ê`ËŒ0ê AáÊyŽmã'­`M8›ìÐã•¿¯&äEþìf­= ÚÔ±öl*¤Ažõ¡§\ZÉ0[bN+îÈÇ¥£°þEXðfÿ6}Äà(À¨rºZ›w\É'Ö¹«xœÝÊr t7ŽWyI8¬H<“nÈ$žk62ÆœÆ31*OÌsŠÑ¶rcÉÍP±m`ä¹5n-Ëâ˜LÞZîÆp3RÙêP\ÄÎÙP§wj©1ýÓÿºk6?ùKþÔËW3jðÆQü²‚29#Žk(Md§ 2è4“œxrbORy®oH]׃w sZ"N‘/¬‹ùqüïè)ÔcW ±€OL‘Ídhê>Ý#ú#‚&_¶ÛŸö²iˆ¿·qszm¡…W AcíL:…ô’m2…'åCDoø˜Êçý£SFØbØ4Û çºŠáç™Ûjð3î)YBÙLÙ%‹(ÍE§6ËIýNëN‘ók´rL™ÇáHvÔ›S@°[¨òÃ5Ç×U©\‡øbÅr´ÂÁEP0®×â·ü«ÿ^Ëÿ¡5qUÚüVÿ‘µëÙô&  þ"ÿÈÂÿõèô«ƒ®óâ/ü€ü/ÿ^‡ÿ@Џ:³§·j}mÂØçŠÄ°ºQìk]9¬ªÛøLçÂw'þ¢ÑèP×m/úø?ë¯ô5ÄxGþE+û Eÿ¡C]´çÀé¨þF´[JÿÄMeuzŸ`y`°D’yVEð§®5tëZp½û!¹nvýÆÛ»Û»wcœg5¨xr+ëËÛÇ‘òùFÝŠ’#dÏÞGè4#©%Ù[9VYLäÈŒ]Žvó‚3ê3L¢5ËYíàžÑËE,ñÄX¤@Ûr¿7±éïJ5ý7͸‰æ–&¶Ì—η’0«œg, zc¯jʵЮcVK˜Qæ)ÒƒãrBî9ôè1M:ÝÍ•ýµõų5ãù¦dV-¸PxÚ_ZØ}BÛPÒo^ÕÙ‚#£«£#+mÎ °pGQV eÛÙý‡H¼WŠÕ$‘Y˜Û†¾\ î9Íj´0EIuX¯ÒÅÝÍîð«0 œd0£#¹]|A¥4rH.¾XÔ1&6;A^>qž>\óS}€V{ÆlšÕmö£ NsøÖM—†Í¥‹ÛyZtÛbG#£îe}îxè:w  3ªEçÂ.Hd—i†A.n{ôëè 15ý5íÚe–]«/“´ÛȾ2T!]ÄãÐUhôkø£…ÓPV¹†Þh’G ÁKW¯$.;óP¿‡¦’ÂÎkO2ÉËFvIb烸“œŠØ]FÍ¢µ•f —m¶ÇãÛ¡ëTîuû³Iíî#0°p|¬ºŒKu¤´Hì­Úi¢+$Oˆàç uÇøÕáUŽ+˜¡¹7TX—ýP ¬ùõÜTáÐÕΞڃY ØL²þhØ)p2T1IÇ`j¤>!µ¹ÕyÚ‹y&’fFQò‘È$W“ÈÈâ&ŠÒn :ím@Þû¤coÖ«'‡®$„[^ÝÄöñÙIe}­“ž2)¡»¦Î›ã¸8Þ‰†ÔüçpFv“Ѻ{Ô±j–SJ#ŠpÎgk|?ëe‡NÿJÏ}âî;¶Ôn¢k‰­E´m XÀ;ƒòzîÁô¥Òôa¨­Û\ ‹,q™Ï'â01íL º(¢ÂŠ( Š( Š( ¡»ÿ9ÿë›*š¡»ÿ9ÿë›*óï€n´Ÿû'þËXǹ=+cÅ$‹½#ô Oý–±•s–&±©ñEè)©qŠ@‡©* ½k&Z¿{iâ¥?/^žÔË‚»88"«ý¤!¾õ¸\ŠV,ÍÃ5 ºžÜãév ~$Upß1Íh‰l“À­M„N:š¬I$ô¦îmàúPÕÄjB¥NXäš•˜*”W#w'žÕ:6ñœæ²ißRЬûÅ-¹G(î 5ˆ±¢4†wª‹±-\‘ƒDâEm9­ dŽxÜç‡ý Qäí‘qžôç•­¼X#¸­¢Ñ›C'…ár®>† !³Å<êr¤ãÚ˜YN<¯Bâî…úŠk0^Õ(PGZc;VI–U”ïÈÚj£Úß2Õ²ÀÓ[­/Л! ú R„6@&šúÔ€½èz ‚Lîç¥ 8Î)0òÈBÇÒ¤[y‡-Z¾Wb[H‹NiC¿7J’HdS}*2¯Œ8"‡·$4Žsš È©<°ÁÎE6EØ£½MÐ\EûãúÓXýsFñž´ÐÀ7ÀxýiêÀ7=*5jMàg&‹9 äUflfƒ/ŠkcP?hÓ+8Ø&xSÚ¨XÚKm#<»G ªºB³côÖÙö†<~ìâ©Bán›µi³Fãd’ÝEëP¤vå˜$qйÅ'45¦Ÿ€ÊäŽPÏzž' ᑎF*Âï\XÓÜ Ðwç.ìßC©Ø¾B²ˆ¡*dEçžriaHBò$oLqRp:“Ö™»f§±ò]¶Òí‰Wå<žMruÕÞ¶ëy;|¦¹JÖ›mjL•‚Š(­ í~+ÈÚ¿õì¿úW]¯ÅoùWþ½—ÿBjŸâ/ü€ü/ÿ^‡ÿ@Џ:ï>"ÿÈÂÿõèô«ƒ  6J}i H¬›rD Š¾N_¢Q»Ð|sáû Eÿ¡A]ÔѬ£k0r<ƒ\‚ÿäN¸ÿ°¼_ú5ÝÏ–xã TXÛqs3E\0È©|Ò8À*{§f?—53gж+}ËHðÏ–ö¤slA;pj®âi¤œÓslJ(y#wËÒÁÓ§c“Y2Ò#t*6äT®F*³¿«Ø˜î‡­<¸sP!ç&'# Õ4$6ÉÂ\³@Çj¾. ',ÿ…T‹bÀß(Þ{Ôô¼%dc(ÝšŸj·9¸úUKÉ!h–Ç"«ŒŽÔÙr;sUÍtO/+#INÞô1gÔjrü!Õ Œt®G£¹KV@"‘=*Ú)ô©6w£œÒÅ!o!Çj_±¹ûÄÕõQOÅ/hÇÊP+×&ž-E\Å&ßz^Ñ…‘_ÈŒ• ,PG–äñëÍ]ÀÇ<Ôo Hqži©k¨™EnEAíWP¨Û&ÅmÃ<Ò"Œä(­$J 1Tåü¨ŸSBÝâuùQAî1Sˆb-¸(Võ¬˜åV?»lVc™‰ßõJ]Æ\1F$*¹,9£Wâ¾,1€½ [°µk•,>^Ö™ªØ+IæÎ’0=”Õ©=JI]㸳1‰]¹Á©m<è .-Ö³ËÚÇ‘³nØÔ©y+Æ QI½Úé°ç¶x=iÚvhüÍ)šlí/òû kÇßcõ=*.;1M‰2O®M7ìö1ŒÉ;¿²­8F‹×'4¦>w.úQÌ>V3ªs³7»µL.¥P<˜£AôÍ7…Rw aÆÞMÌ9PâóÉ’òŸ àSWåä ŸzTeeëÅ.T*^£µ‡«¡eÁ¦ÈÀ°ÛÁ¦`lÁnM yÉ&‹ s–õîäç­HÄf˜OaŒP„Æî{R’»³HvöëH0F@ª°ˆïpm¥ ôC\µt×ñé7û¦¹šÚžÆsÜ(¢ŠÐ€®×â·ü«ÿ^Ëÿ¡5qUÚüVÿ‘µëÙô&  þ"ÿÈÂÿõèô«ƒ®óâ/ü€ü/ÿ^‡ÿ@Џ:±cOt±©œõ­5a*ÇîŽjžŠªú”jç ƒü«JM¢WžqI¡3¸ð²*xRuS‘ý©ó‚»IŽ'ƒþºäkðÓ+xfè¦6ÿjÃŒ}`®Æçp(ꥶ8b\S0u-¬üGöÉäŠð¼±"Â. Ënxj†œžýzÔ6ºî©ç]Ý]NžD›l¬†HÂgnÅÆìð ÜH9í[þu¿›æýüÁÑþÌÛ¿=¹£ÏƒÌ2}üÂ0_ìÍ’>»iÎÚë:¤ÐËnoˆo¶[D· åHá$ê2«°ž=;Ö¤w“¶µqisª4Kl¨±BV0×Y\–$^>\cu%¶vÇlÈ3œ-«Ÿ_»Ö•§Ý]à‘™~ë5³¿CŽ)°±á)î­¢Ò­$ºiíî4ó2«¢ƒR£¨nù´­m–Ñ¡ØTü©É¼×6º–¥}k|̉5š:B³†I'±Ú¯ÝZùÞ1’mìM¥ŠI{ƒ1¿¼¤Žƒ• ûÖèŽ00#@8ãhÇ)p7ÀÜF Ç4ŽBjÿìO2j u#éÒÜÈ¢%d‘GŽÙÈÃdñZÒI„XÜ\ÉrçÊ‘¤‘T7©?tô­ác~#A¿ïáGÍõõ¥ *Ê ‘‚ã\,s1êz¥Æ½p¢â†+‡ŒÛ³ &0¹ 7zç8Çj­ þ®,­ÿâf¯%券:Fž[PBä1p<âºÓEĆ(÷€Û@ôÍ .»^ÙqŒcÓé@WœÍá{gq0›pÍ•¸>`RpÓß T]jVúYu).#‹SK"cz2+n%TÀ·l:WK±6Ø›EÚ0? 6&s±sßtuõúÑÔNÞçV¹{cý±2 ‘rJˆ";<¶;@ùz`sœŸqWîuY†ôû“#Ãqx#ã(¡XŒœ—@㸭Ј1„AŒã 8ÏZ8Ú?-£FØTü©Ê[j¥ý½ío!µ¸‘Ú8Ñ„…È#¸ÅT¾Ô®5+&k«ÑnCZ4vj‹ûàžHÜFâ@Áão5Û,q¨cE` `zRbb…¡Œ”û„ ;~ž”ÓÖâjç?âò¼Eo'ö—Ø6ÚND›Pç•ãæôæª\ë:‡%šñl$M=.cˆÄÚ%%²¿78áx\šº·Š)2E•9Ô}3JÈŽÊΊ̧*YA*}G¥!œ­þµ©Y_4RMì  ;mv"ôê7½mYÉq7‡üë¶Ý,±<œ•z.h•V$²©ÈÁÈ#ÓéQ]ÿÇœßõÍ¿•0<ïÅd ½=ôÔÿÙk%NN?*Ôñn>×£çþ©ÿ²ÖAª–QÐf±š»4‰*€'ïa$¾I˜®år94ÍûNHàžµ)qÀ‘×áPI·qXòM)vÇpäâŸazµ ØKR #“nUwÈP®1Ï5¯éœ{Ô71Fðž9ñP§Ü3ñÔ(Í(“oG4›PüÇ5mV„7Ï*rz•bç8Í»â«%Ð?)â¥VŒÔ8µ¹I’9çŠ~A´ÁŽÔªH5ÅLÍÙMU}äàZ˜Ü9¨š,àUF¢Bh w§—«TåÛÉ#sWÍrl HC‚iUGR*0@©³ŠÁ+1äÔnà‚3v)¥‰8©W*éX1È5"FriªO*ôô¬ÝÉKMÆ{ÓÅ+ ]¢Œçƒ@Å)Î8¤1¤ãŒRn‡vy“ny§a\ ?/E5z ž1MI#žx¨^Þ=êÁ<Ô’ã‘Û÷«À«W[b/³‘ ˆÍH“‚sÚœ2YHÔR¬AªM½ÊŠ4ôÍBæÞ'ò#vFF+®²¶Ø$î 3ÕËè¬\oPË·{×G¥Ü@–ënŸ.Þ€Ö{•u9e\7¨¬'³–ÝÈq•õ»“ƒUn,ÕÁ#oZ›Ž/¿R)®ØÀ<ÖíÞ–9h†ÆôìkꉲèsSbÔ®8J2GçA|¦yçÚ¡È' íNb[ýiXwFNM?iÈö¨ùØhY‚MqPGJv&£lž¹ëC>ÅéH.;*­žô7CÖ™ƒ°dã5*[M(áH¦…q½ð=) g‘Ö­ý‹p*MÄ *gßJ$¹ØfÈ ÏsR[–vÚ1=jg%$89VàÕf;AÛëÅZD¹1/„i¦Ï…䡿¹*êïÏüKç'ºå+HìK (¢¨A]¯ÅoùWþ½—ÿBj⫵ø­ÿ#jÿײÿèM@üEÿ…ÿëÐÿèW]çÄ_ùø_þ½þptbËþ>WœpkE®ìäV8$t5"\K6¹Ç¡æ“@z‡ƒñÿ…Æâmþ… wM"?0ëë\äi|3¾2uhº½ zc“ÉüèÏ5?¾?:<Ôþøüéû›ûÇó£sxþtÏ5?¾?:<Ôþøüéû›ûÇó£sxþtÏ5?¾?:O1?¾?:“sxþtnoï΀#óûãó£ÌOïΤÜßÞ?›ûÇó üÄþøüèóûãó©77÷çFæþñüè?1?¾?:<ÄþøüêMÍýãùѹ¿¼:ÌOïÎ1?¾?:i¼„ ÂäµIöØ?çá滛Ÿßb|~t϶Áÿ? ÿ}QöØ?çá滛Ÿßb|~t϶Áÿ? ÿ}QöØ?çá滛Ÿßb|~t±Î²‚c”6:àÓ™ö©f|Ô“@ óûãó£ÌOïΙöØ?çáïª>Ûüü/ýõ@óûãó£ÌOïΙöØ?çáïª>Ûüü/ýõ@óûãó¨® ¤À0'ËoåNûlóð¿÷Õ-Û²›æ$Û¿µyÏ‹uÖŸú§ô¬9Ž2±®xæ¶ü]ÿZ?8ÿ‰jJÂ/´g¹œ·ØC! «‘ƒI&Ä­Q‰ Ää㊌fF%+ !yÞÜҦݷ֣G »HÎ:S]òF?*†›e¢F“o9¨L¤‚3Ö”ð9è*¬M5lCÈÅ0·Qžô3`TLæ9«± FûÜPn(à rž)’,zr®ÓƒNÈÅ3ŸzH 3McQ³±<NœZ@ûÜûÔëŽÝ}MCgp«Š:¯5”äh‰Iæ¦€Ä Œ 3Ï5ƒm²Å÷5ŽwiìA¨ÛàUEw4±õâ‚_zjõæ¤Åhô%™võ ¸ïŒÔ’í#­WÇ5KQ6<¶iTÜÓãAŒ÷§à –ÀžE;©ëMæ”æ¦Ã°ð=éx¢-·½ ÿ•+0,äR€â¡ßÛmE#O b…kͤês»D1Ï,iáQWÈ‚ãv3¸úšpÆÕíÅE¹àž”ðGsš–¬@0 Bã%OJœ`ÔlpzŠq®èçÖ¡˜“8¤nFj’±\¦ç‡~[ ÛÚŸ+à‚8=ª- áb¶‘ Õ«-”rÇ”åHüªîÓ"Ã,µ’„Grr½š·c™%@ÈÁî+ˆ¾·¸µ9Áxý})–š¼Ö³/–ß&>e5\·Ø‹ÛƯŠÏº°I2 —NÕ­ïTp¯ÝM_9©(å.ôw-oÈÂzÖc««m•®«W›ìÅq’yÉÅVžßí–êïÚFCwœzHç[¯4ˆ ÈPOÒµÿ³à@r}êH£Žûµ¥Ê>de¥´ò.vb¬G§©ÃJy÷⯖ç#¥B̓ƒMEÌØäŽGÊ€š<Æ ƒ€*'“U£ˆ—`3ÐÛñÍÂÛÏ¢»îÁÓ`~ÉM}„“¼Ÿ¥CWcEµË‘ÀêMÅW‘ɬñ¨¨Æ"9Æ:Ó[QsœF?K•±¦‘¥æƒór1ꤹÎáϽeÿhOž6銌ÝÎOúÃO®sspÏZf@lƒšÁ.ÇøçJ²H¿uØ~4r ˜Ù#=ª'\šÌóåÿžùÓ…ÌÃøÿ:9EsCg©¡x5Císx~TŸj—Ô~TYˆÔ,äP„Èx¬¿´Ë܃øT‰ž•º­ªð®ÌGL ¥>¬\b8±îM;1/˜>EÏjçêÄ·“J¥X€§¨«Õ¥aQL»_Šßò6¯ý{/þ„ÕÅWkñ[þFÕÿ¯eÿК€'ø‹ÿ ? ÿסÿÐ"®»Ïˆ¿òð¿ýzý*à袊(Ó|ÿ"4ßö‹ÿB†½õ5ç~ÿ‘oû Eÿ¡C^ˆzš(¢ŠC (¢€ (¢€ (¢€ (¢€ B2=éh  ÉÔh¨­ Ur;~°~f§¢€ Å߬™£~°~f§¢€ Å߬™£~°~f§¢€!Š9<Ó,Ì¥¶ízNš3${Cm`C)ô ä~¢¤¢€ Å߬™£~°~f§¢€ Å߬™£~°~f§¢€ Å߬ó¦Ì‚-6Hó±°Ï¯`'€*³þ‹6Hû‡ŒûãÓüþ´å_úèŸõàŸÈW]¯Ä~º'ýx'òÅSQEQEQEQEQEQEQEQEQE ‘БR¥Ìé²7*)Y0.¦¥p¹Ýµ¾¢¦]Xào‹'¹³(©tâú™›#S…Ž0Ê=H©RêÝó¶`õâ°h©öQè>foeŸ-ÔúœÒ4iœÖ$t4å–EW`>´ýŸ˜\Û¶ð8éD‡¸Á¬t»‡ô«{0l’ÔRäÍwq´~Ð0Çœp+–Ma#l¢¸«Iâaªÿg/ŒrN)ò²öÛæˆ#‚qëUïlRHÛ*;ƒ\›øÖe}ðÚ.Iç{gІê2(Cg¹Á9¥ÊÂä—ºo“6ûf €ò¤ò+tki5¢Û˜Ê¶µpÓj·s³…9ÎTTwp䕲=*¹[‡yç)xUYo­ÔfŽ¿5q-,¬rÒ9>¤Ó(åήm^ÍH"mÙþèÍS—\‡"»c¿­`QO•ÍgÖØª„„ zš­&©tà€ÁF{ ¥E; »%’æy ß+œõ梢Šb (¢€ (¢€ (¢€ í~+ÈÚ¿õì¿úW]¯ÅoùWþ½—ÿBjŸâ/ü€ü/ÿ^‡ÿ@Џ:ï>"ÿÈÂÿõèô«ƒ Š( ÓÂ>,Òô}}3R²–äKpe *•#jœŸU­_øM¼'ÿ@?ïÒyµé?ðšøOþ€2ߤÿ?á5ðŸýdÿ¿Iþ5æÔP¤ÿÂká?úÉÿ~“ühÿ„×Âô“þý'ø×›Q@“ÿ ¯„ÿè'ýúOñ£þ_ ÿÐOûôŸã^mEzOü&¾ÿ  Ÿ÷é?ÆøM|'ÿ@?ïÒyµé?ðšøOþ€2ߤÿ?á5ðŸýdÿ¿Iþ5æÔP¤ÿÂká?úÉÿ~“ühÿ„×Âô“þý'ø×›Q@“ÿ ¯„ÿè'ýúOñ£þ_ ÿÐOûôŸã^mEzOü&¾ÿ  Ÿ÷é?ÆøM|'ÿ@?ïÒyµé?ðšøOþ€2ߤÿ?á5ðŸýdÿ¿Iþ5æÔP¤ÿÂká?úÉÿ~“ühÿ„×Âô“þý'ø×›Q@“ÿ ¯„ÿè'ýúOñ£þ_ ÿÐOûôŸã^mEzOü&¾ÿ  Ÿ÷é?ÆøM|'ÿ@?ïÒyµé?ð›xOþ€2ߤÿ?á6ðŸ}OûôŸã^mEt¾5ñŸˆ.íe²‚XR¼½®ÇÎI©e×.¡ÒåÔ§Ò;e‹ÌtɽÆQ÷sŸzÓò­¿ç¿ýû_ð£Ê¶ÿž6ÿ÷íÂ³ŽºÑ\µ­Õ•r’Â…VEuÄŒT6G¡‚«ñ_,šå™oÙR7.q†ß»ùmýhÞU·üñ·ÿ¿kþyVßóÆßþý¯øVJxž1oçÜXËKŸj2¬g]ÁGÂrËÁõúÔ¿Û²nû/ösh‰¼£mæ.>îýÛúcþT£å[Ïûö¿áG•mÿÀÊ…‚çñ< g•mÿQ’ÁúmÇíX}fõ«m1ã!î óVOᲟsƒùP¯*ÛþxÛÿßµÿ <«oùãoÿ~×ü+$øž'µž{{]â;Å´Mî>ìaòG ÏéWô½Lj³Ì`(Öò´N¨Dˆü¥~÷_ÏŠŸÊ¶ÿž6ÿ÷íÂ*ÛþxÛÿßµÿ §m¬ô»‹Á§Ü†V‹È ’1×°ëÜñÞ™u­¼=¾¨¶JðË•Á™T¨Æp3÷°  þU·üñ·ÿ¿kþyVßóÆßþý¯øVlþ$··½š eŽ$ÎâFâvÆÎ¼ä}x­kiLÖÑÊȪ̠²† ´÷q@ùVßóÆßþý¯øQå[Ïûö¿áTåñ— Ã@òÊdY X[Y%A ‚qØf¤“\Óc·†s9hçRé²&rTu$H¹=(Ç•mÿaž2¹  ^U·üñ·ÿ¿kþyVßóÆßþý¯øUm#SþÒžü*ŠÞTDß# '!€#“éPkô; €ù—k$JËå3*ï`>fà’4úšU·üñ·ÿ¿kþyVßóÆßþý¯øUíkx¡¸šrJEpðæ$“}@\sÓÞ¢þÙ…/nLÒĶ1ZE:Ês½˜~=½]ò­¿ç¿ýû_ð£Ê¶ÿž6ÿ÷í ÞöG¹3‰ ‰•¡`áÏEØFìœð1NMZÁô×Ô<í¶Ñ±Vg”‚*Fsž1Š—Ê¶ÿž6ÿ÷íÂ*ÛþxÛÿßµÿ ¬uÝ4[}£Í}¾h„§ÙßÌFBìÛ»8ç¥8ëzp´ŠäLY%bˆg,:€nÈÇ¥w¤K¦]êÒBÑ–A qŒçjäâñׇͅ•½ö“5ÃÛ@±xÐà…ã'¡*?!Kÿ ·„ÿè_ûõøÐkw¢Úµ‘ƒOŽ+7¤ÈéÔäÅ>ÃO–¯.ogI®.ö«ùhUTžˆó\?ü&Þÿ¡}ÿïÔãGü&Þÿ¡}ÿïÔãH˜xfG¶Hno•…­¿‘fÉ cr°fç“ò(üýjoìK¿<ßý²í#?š_Ê>^6lÛŒç$çÖ¹?øM¼'ÿBûÿߨÿÆøM¼'ÿBûÿߨÿƘXìF†ŸÙÖÖ/"¼håî§Í.IfÐlžù<ûdûU_ì;ˆ­´õµº‰g´µ6¬ÒFY]X œg®Täÿá6ðŸý ïÿ~£ÿ?á6ðŸý ïÿ~£ÿî%ÒÔøuôˆe!~ÊmÖFþ¹5,°Þld‚kp¢DFOÌ:“Ï ŽÕÁÂmá?úßþýGþ4Âmá?úßþýGþ4޾-ÓDÔl ñ¾ó?ÕǶ8·(\*úqŸ©4ëÍ /n&’iÙCÛE 4|¹â®èúkiâ夒&{™”†=‘¦0«ïÔžõÄÂmá?úßþýGþ4Âmá?úßþýGþ4ÝYØk{¸ŒÄòJwv8ý*œú=ËèÖÚbKfÑʼnÚhKœÊ3Áë\ü&Þÿ¡}ÿïÔãGü&Þÿ¡}ÿïÔãHÎûE[Ø ‚I¿u %7ÌŽÁp¬[Û–Ç®*mN:e›BÏ3Èd"$Ú‹ÀQÛîçêMpßð›xOþ…÷ÿ¿Qÿð›xOþ…÷ÿ¿Qÿ0;(´vŽâ9~п%ûÝãièÉ·oÿ^©?†2–Ì$¶–HªDñFW}ÝŽAÍÂmá?úßþýGþ4Âmá?úßþýGþ4€ëßBÝÔqÍk<Öò*ª` ‹o÷ÛÇ¥:5Å­ü5ÔOmlÒ˜!ûÂN Î8Írð›xOþ…÷ÿ¿Qÿð›xOþ…÷ÿ¿Qÿ;…‘ÖÿbÜÃp×6—q,Ës$ñy‘’1"€ÊØ>ÙQ‰qdm¥±¼Ï$IL±’²o}ä€ô®Kþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ ²×ÃæÚúêå.@ûl’}¥vœ:0ù@ôe9ç¾j o ˆlÛ}¢:ÜE ”`Ê_'•¹¯øM¼'ÿBûÿߨÿÆøM¼'ÿBûÿߨÿÆ€;2ÊâÚ[Ùï&ŠY®äWo)JªáB㟥S½Ñ.'žäAw[]Íó#ÆKM¿tƒÐ„k’ÿ„ÛÂô/¿ýúühÿ„ÛÂô/¿ýúühëp±Ô^xzYÕÂÜÄÁîfœÇ*¶Ã¼2ŒqÚƒá·òV5¼PVÚƒyyÃÄûÕºôÏQ\¿ü&Þÿ¡}ÿïÔãGü&Þÿ¡}ÿïÔã@5î›q>£$Í. n£œ-šDT ]ƒæ#äõçÚŸc¥Ý\øq »?gº–é®””ûæo\®}‡y®[þo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ ,t·ÚV ²Cs‘Í}=üRÈëòãTR£Œç§=éÓxhËR<ÐKv³É<žlDÄåÀ`Œ0sÛÞ¹øM¼'ÿBûÿߨÿÆøM¼'ÿBûÿߨÿÆ€:Ù4 Ö×Ç$0­ÍšÛŽ2,IÓæé[c€ Åy¿ü&Þÿ¡}ÿïÔãGü&Þÿ¡}ÿïÔã@‘Ey¿ü&Þÿ¡}ÿïÔãGü&Þÿ¡}ÿïÔãHH¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H¢¼ßþo ÿоÿ÷ê?ñ£þo ÿоÿ÷ê?ñ H œW›ÿÂmá?úßþýGþ4ÂmáOúßþýGþ4Àí|BsáÍS‘ÿ’÷ÿa½¿ÏóóoŠßò6¯ý{/þ„Õ¦|ká2>bcçõ®_ÆZ忈5•¾¶ŽXÐB¨D€g “ØûÐÿÙfotoxx-12.01.2/doc/images/rename.jpeg0000644000175000017500000003646311701011016015774 0ustar micomicoÿØÿàJFIFÿáÎExifMM*V^(1f‡ixgnome-screenshot0220‘ 0100 ÿÿ N ¸ÿí6Photoshop 3.08BIM resize sharp ÿá http://ns.adobe.com/xap/1.0/ 1 2 3 0 8 184 334 1 2 2 ÿÛC     ÿÛC   ÿÀ¥,"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ôOƒß <)àŸøvÎÛDÑÞúçL[ýKWÔtèïdý•®_hu8P«´*㜒NkÚà¤öépºŽ‹ä¸[þ^ÇþÙ×yá ÖKMÞI¢…dðÿq2ÃwÒ ¢—brΣ’9"¾sÑ?d¿±ZÔô =6_µ5¦»fî#j¬™fÛœ/s^ö>­L=UnÊLJƒ£JT¯%Ôú_Oú¥–}e£ø~÷OÔ´è5K[áûh E,“F2AýÁ<ÿ{×5kû3Dÿ¡{@ÿÁ-§ÿ¬[ØàÓô›;4h¬4­2ßIµ/ÃËO3¬¬¿ÂXMÓýœÔŸÚ2~½Ü7:•E©æâ%VJ?Ùš'ý Úþ m?øÝÙš'ý Úþ m?øÝchÉýúOí?¿]¾Æ=Ž^3kû3Dÿ¡{@ÿÁ-§ÿ£û3Dÿ¡{@ÿÁ-§ÿ¬oí?¿Iý£'÷èö1ìþf×öf‰ÿBöÿ‚[Oþ7Göf‰ÿBöÿ‚[Oþ7X¿Ú2~—ûFOïÑìcØ9üͯìÍþ…íÿ¶Ÿün§Ó|1»y-®‘à­U¸†?>XàÒtôÙp™G^8Ï~1ÍsÃQ“#ç­]Äún“¥x¶VÎ-SûKIû¶t%]Éæå³GÊŒsœ­sâ éÓr„S} ©59¥' º½†á©ç¶Öü7 h×6û|说{$)»;Nv àà‚AÁ犫quá;D§Ó|- ʆHÚM.ÅC¨êÃ1ò9×WiãïCâgV×tº†‰ikk4hñ¶‰,@+Ú$‚!H-¶EFÎæôªßœÞ3»Ð.“LÕ5{í.hå°ŠÎ"Ýö©Ẅ8#?*–;˜ ±¯=VžÎ–º}÷:ý•7´Ì;›Ÿ ÙG —w… IÆbit»U&> .n|'e(ŽãMð´].ÅIRp } ã5Õé~:Ð4ÿˆ.×-üA©iv7Úµ­Å”6K$ÞÂLÌÿ¸‘ŽÌ|¼ bìrrn…ñ;NðÕÝÌ:Eù°Ónüs&­2CdÛ[Hh ѪYví\>8À‡ˆ•ì©_p£J6»™ÍB|3r'0é”Aþ´¦“d|¿÷±-ðÖ§’ÏHðÕÜjv–ƒI²p¦Du®ÿ´ýVãÂ:ÀþÓ:Oˆ/&–Ý,Äb-)”ù(ª¨ªÈc!99A‘Þ¢ñ÷-¼Ow¦›KõÕe¶’äÉ~ÆF˜Âü¤2‚!°3eT+´ŒáŽw§UÎQ‹§k‘(F)µ=ŒÛ¸ô:+)uøN†ù –rÜé6*.P6ÒÉòü`àûŽÚã—’C¾›áyä™KF±ivL\¥@‘ô­í;â5–‰§[5ãǪÚx3PÒ# jΫ¨IÚjN>Êé3OgM¥%=Lyü+{vö¶úg…ç¹Lï†-.Éq× G‘Imsá;Ëo…§œ±Qz]‹1#¨À9Ðø“ƾ“ᦱ¡Ç®jäæÞŬ­oÙ×É–'_:8‡«T »·¶áœ’IÎïÄbM[á¿å‹U¸ºÒnõ-6-7KšÅì>òl "~Vn ÎAÅ/¬ZI:vÖߊ¢­u=lp–¯á{馆ßJðÍİñ$qi6LÈ}À"¶4ŸÉâ('¸Ñ¼¥j¶°KäI<:V›‰©+ûÀ¤ðÊsŒsW¾#üBѼIe=®‹p“[›‹i,-%ŽD“LU’$ò"] †Q#ž=+|Ym€$ц‰«jk­|öúöŽ/áK!HªÄ l©{#Ò´ö•'IJí+õ§N5,ç¡_IƒH×§Xtí—2´-ÓìüØbƒ%ÌÈ!&2ÀnOÞ9’Þ \Ü%¼zW†ZéÐH-Æ“eæ`Œço—šÐð÷‹4½#Jðœ÷’ƒ¥éZý­Èh¤}’ÝÊÆß¸bêAÈÎ;‘Zw¾>Ðßáí–‹hÂ&M +)t;…,WŠIiÐ,L¥°ÂS/Ô’cÚÎ2³§}{y²½9EZfAÓ4_ú´üÚñº?³4Oú´üÚñºÅ]BUU &ædúš_í?¿^¿±‹èyþÓÌÙþÌÑ?è^Ð?ðKiÿÆèþÌÑ?è^ÐðKiÿÆëûFOïÒhÉýú=Œ{ ŸÌÛþÌÑ?è^Ð?ðKiÿÆé?³4Oú´üÚñºÆþÑ“ûôŸÚ2~cÁÏæmfhŸô/hø%´ÿãtfhŸô/h?ø%´ÿãuý£'÷é?´dþýÆ=ƒŸÌØ›OÑc‰Üxs@b ‘Óž?ëszF‰oªhI­]ǤXZýš 맃ÂÚ{ÛØG8&‘ØÎÖËch ä·7’ùåuBü1ó£á·›Ávúuý¬2]jÖšU½¤BCþR¥ÊÜ2üß# Â~pIÁZç­^ÔÖœ£)ZL§¬hQxkR°¶¿Ñô»¤»’æ±Ô|3ek'‘p]b˜lR@&9ÖÚÃkñÏí%ðrÓÃÿîWòÚé:uÔ t,ŒLë 1`BsÂü£ë_aø£\·×üUÖ‚éRûT·Ô^;Ö8¸,MÀÜ3¾(Ñ#çO“cùÏö”¸2xòÍË(-§FNæÿ¬“Ö°©IN‚sŽ¥¥Tij·<'û<ÿmøGÃ×ïâ© 7M“ù+¦+„_³Gµwy£8ç½3ZŸðÌh?æm“ÿ+ÿÇ«Ó>ÿÉ;ðŸýl?ôš:µ¯x»Dð¹û_U´Ó|Ϲö©D{¸íšùxæ§¢Ÿà¿ÈúGƒÃ­y3ʿᙇLOý‚—ÿQÿ Î?èo—ÿCÿ×ÿ sÁ_ô4é?øŸãH~-ø+þ†­'ÿÓüjÖ?´ærÿ">«„ì¾ÿø'ÿ Î?èp—ÿCÿÑÿ Î?èp—ÿCÿ×}ÿ oÁ_ô5i?øŸãGü-¿ÐÕ¤ÿàZ?¯ãÿ™ýËüƒê¸^Ëïÿ‚p?ðÌãþ‡ ðT?øýðÌãþ‡ ðT?øýwßð¶üÿCV“ÿiþ4ÂÛðWý ZOþ§øÑõüó?¹}W Ù}çÿ Î?èp—ÿCÿÑÿ Î?èp—ÿCÿשh^1ÐüO$‘鵞¤è2Ëm0ráþ*Ù¨y–6;ÍýËü‹X<;Ú?‰âŸðÌãþ‡ ðT¿üzû3*ôñ„Ø<ý”¼ßWµÑŠŸí<_óþ_äRÃÿ/æx¨ýš0?äq˜Óþ%KÿǨÿ†hçÆc¥.?ôu{Uiã?Ÿòÿ ú–ù3Åáš9?ñXÍÏì¥Éü|êìÎ?èq›®ä¿üz½ªŠ?´ñŸÏù}F‡òþgŠÿÃ3Žþ0”ÿÜ)øõöhsã ý—ÿWµQOûOüÿ—ùÔh/æx¯ü3@ó8MŒcÙkÓÓýuög¯Œf=¿ä¿—úîžÕíTRþÓÆ?äRÃÿ/æx¡ý™Ã) ã X‚§J\é;ö«7߳ſ«öo·øÿRÔÛˆòÍ¥ŒcrŽ>\q^Åš*^c‰“NSÛɰt#´x¯ü38 ã ¨þÊ^¿ŒÔ‡öfSÇü%ò‘ï¥/ÿ¯k Õÿiã?Ÿòÿ!}GÒ?™â¿ðÍcþ+¸ÿ¨Zþ_ë¨ÿ†hãð˜ÍŽÿñ*_þ=^ÕE/í¥Cù3Å?á™Çýÿà¨ñú?á™Çýÿà¨ñúöº)iã?Ÿòÿ ú•åüÏÿ†gô8Kÿ‚¡ÿÇèÿ†gô8Kÿ‚¡ÿÇëÚè§ý§ŒþËüƒêT?—ó¶–FÀe™ËIΫܨâ—ö–-ý¿ÁêT?—ó?oOù-–ŸöƒÿFKQ,~"JÒ—ä5„££ùŸsü9ÿ’wá?ûØé4uOÁöó|MñµÕÄ1ÏqoŒPÉ*1#¤Œá3¡Š‚q×Ðbçßù'~ïÿ[ý&޲|1tm|}ãæ^»´ÜgŒþêoð…/´mS¡ÛxxkÒhÚ:SkqÅ羘%ˆÝðNï+;±×®Fçöƒð—ƒ¼=â9õ+XmuûKkí6ÊH•og†vU…¹ùñ—\ñÇ9é^icðWV¶ø©q¬Íû OŸh(ÕÞ_²Gl,Jù{?»Ýæy§å`ž_'ìËâ HÒ`¿ðµû#Úuö£~gY¶—#»}‘D ½dó74EYI!÷ü¢rÒÿ14’Ðú›]ñ‡‡<-y ®±ªhúUÄáŒ1^Ï - • FpYÜzŠÆ¶‚ºž’Úê§šÚ`š/´„ÆíÞVwcç+Éþ*ü1“â?Œ¯5•›NXßÂZ·‡ Žö6fŽ{¹­$I~á[¸$|À°À=¹øây~)xoÄWzÞwm£j–W«zÚ…êÌ-¡²[w³K5Œ@w8’O>Fg!ö•\ ˯õ¸Yt=Ñ~+ø÷‘⟠‘©‘}nvÈù؇æá›k`u88Î jÛø³Ã÷~ ¸ÐaÔ4©µ»tó&Óc–&¹‰8ùš wÈäŒs_3Y~ËÙhzm’7‡Eů‚µ? <«jØ{««¸'[õy*«€±Ã?Ê9&µ~ü¸ø{ñÛV½ƒL×RÖòçRƒÄ2ëú—ÛÖiíš'O°2b>w_0É’‡>Z°ªM½Á¥ÐõψÛÇã‡wpÁ7rkmhóD]ák;™2GU-gºŠéOýjâ¼_|×~,øt¬ÙLj Î?éÂò»^sÇ^ÔUVH)õ6(êq^{ñ[á°ø‘«ø+‹5L׆¡©[\K¶7€Z\Æ2¹`ó$äï× ð/~Îÿ5/ ørÂÂÅ[PÐã¾EÍÞœ²XHuYeµ\\#È­¡€*Ûml®Æe9{M­5]RÛDÓ.µÙ|‹+Xšy¥*NÄUÜÄ€3Àì9«*ÁÑXd†Pþø<Óñ¯œ¾%üñw‰²÷£Ì‹Pµ¹¾’åãv!ªKn¬ý¸õ¯§îÝdº•“”,Húf…ª¸u!¤¥¤ aEPEPEPEPEPEPEPESE~|~ÞŸò[-?ìþŒ–¿AÅ~|~ÞŸò[-?ìþŒ–¥÷7Ã’ï çþŰÎëÚ:ÎÖ¼ ªK¯]jÚ·k¥\^Gw‘jMu¾^B0 ,le†A#“ÇJÒøsÇÿ žä aÓþ½£©ìì®üQâmKOMZçG´Ó¡…ØcˆÉ+É¿©‘:Îzñΰ›‹º"QRZœçü!þ8ÿ¡¯ÃgþåûŸþK¥>ñÁÏüUž>¿ñ ¹ÿäºîá]ËÿC~½ÿ|Yÿò=ð¯&ÇüÚ÷ýñgÿÈõ§¶—dgì×vpßðˆxãþ†¿ û—îù.øDQ–$pŸÝ qXßð©µa×â¿úö±ÿäz„|2ÔÀ·?5Óq³” °ÜW8ݳçÎÝ™ç¥%d/Â}]‡ü”Mÿ¬yÿÈßøUš™˜Åÿ ^Þâ¿g±È¡Ç‘žÆ\Ù¢°áøc¨ÜÆ^‰ìê”´pXpFDAüjoøTÚ¿ˆšÿþXÿò=tkRV_ü*][þŠ&¿ÿ€Ö?üGü*m[þŠ&¿ÿ€Ö?ü@\Ô¢²ÿáSjßôQ5ÿü±ÿäz?áSjßôQ5ÿü±ÿäzAsRŠËÿ…M«ÑD×ÿðÇÿ‘èÿ…M«ÑD×ÿðÇÿ‘è š”V_ü*m[þŠ&¿ÿ€Ö?üGü*m[þŠ&¿ÿ€Ö?ü@\Ô¢²ÿáSjßôQ5ÿü±ÿäz?áSjßôQ5ÿü±ÿäz楗ÿ ›Vÿ¢‰¯ÿà5ÿ#Ñÿ ›Vÿ¢‰¯ÿà5ÿ#Ð5(¬¿øTº·ýMÿ¬ùªK jž ×´8îçørqðïÂö°ÿÒhêׇ.ÍŸ‰ü^ã‡ö{që¶r?•Uøsÿ$ëÂö°ÿÒhê¼÷òxcÄš¥Üö:…Å¥üvþ\Ú}”·[^/02²Ä¬Ã>` ãzPõ@œïþ2|YѼ%ðÂæ÷ÇZf7ˆ¼'o®O¬x™aÓ­eÔäXØ%ŒÀª«3Žf$íp¨õñÇ6Ÿµ›—Õnn´koÙxr4ø|†³—I²žIMžia<ò•bøãià`z*üG‰Kgâ0[©¡Ïþ@¤ÿ…‹üùx¦?ä¨tÿ¿WÐVÔù³Eý¢~%jú#²ÖÒYÆ…m«i—F8oî4™ä½X^Öác´‚!*£‚ÐffB¹2Ëž¿Vñ÷Å _ëÚø‚ëÅͦø¶_ ZiwU¼BúÓ–å'‘âŒ7˜“JÚ…#ÁBÇ5ì§âLdŒÚxã§üH5þ3H>"Â:YxŒqùj=?ÔPÞ–B¶§ û.üFñO´OËâh~&1AfÈ4kqs§ÜºKöˆ§ÎÙP©²2"í}ìx¯ðçÆ/øWáï†ôûŸ‰Ú…Š[Ùk-wªÞØZÝ\É­C:}—Hqå`ŽI$ÿ®(Øà)ôÜŸa”ö^#|tÝáý@ÿí ü,¤ÿŸOà‡Qÿã4ï­Çb;í[QÖtÿ…·:Å—öf³swÅõŠçó¶™rÒD3ÏÊÄŽ}+¢®WûF_ø‡A{kF m6åï.'¿±šÑqöyb¢UBÄ™sÀÀÚy®«¿oÆ“w¢9oñâÿ‡Ùÿ áÿÒKšà|Aoñ/Iñ'‹µ2ë&McQ†ÓJk§ŠÕ¬Æ•Cåqû¼Ü†Û ÉÜX ä ôïèw¬ºEíŒðÇ¥^-íºÝîHÁ¨,2’8È«ƒÅ~6Ü ð÷†zÐÃsý7Ð'ª±óþ‘}ñkCðæ¥s¤Ëâù:ªiúoÛôË»6š«AÚ^+§yü»{¬ZC‡hR3Òx˜ø‹Ãÿ5ý+à âÍGY‡ÁRi¶ú¾¥¦\µ›ê(±4N·OY•Y™ƒì.0ÇpÅzññ_üËþÿŠçÿ*9üGã+¨$†o øZXJ¼oâ –VSÁ?Gjb¶çÍ^ñŽ­¢ø¦ÛÃwß_E‡X¶†ÓQÔ­5õF_šÑý™ S•’á”fRK†?»ÙŸKðF‰©i?-”> ø™uK)låðǃ¯'û/—q ³ˆ•®Ú'XÒLÊ\Ð œ ­óð÷ÃgÖÂ:øcöôÿ’Ùiÿ`x?ôdµ÷¿†ô“ xsKÓA+ÙÛ$,ê8$“úþ™¯‚?oOù-–ŸöƒÿFKPÊ>æøsÿ$ëÂö°ÿÒhêÝÞ½q¦öf¬ÝÇË2Y´H"V$.æ•Ñrpp¹'ƒÇSá×¼'ÿ`[ý&޵<òøÓÅ\såYtúMT.…íOЕ­à]ÿ$Òjxþ„­kÿìù&«|Døï¦ü9ñ/ö5LJõí^Xôk~êçK‚†ÖÎ #I]Ì’£<ÐB"³­€Næü[û\xOÁŸÛ³_iº Ót­NÛF£Ëcokyy=­½ÔQBóÜÇŒÅr„¼ml°ã-Yê&δê¾#|­û{±ÿäš_íOЕ­à]ÿ$×1eûYx.ÿÖšâE©>ïG½Ö-åX¢‘g—Kkqo¤Œ*ÊèÖ(Êá•Ùrj¤µ%…‘û_‡u­SPYu{‹«M*Ú}>ÆÂì[Ë<âY×;Y‘vÄ]Üî(„)ÂI½…s²þÔñ'ý Z×þØÿòMÚž$ÿ¡+ZÿÀ»þIªÏñûÃJ’ÉW÷6é®éºÍ*VY¯£·’ÞUËåmº‹q ó|§ÝøEñ†Ãã6{«i:UýŽ™Ã[Ås}5£}¥•™[jC<R¼¬ËÃåë‡kì;ØŽß]»þѶ²Õ4kýkÿf7 ‰3*–d ŽmàHV#¡Æ©ªþ?`ú¿ûÿÄéÿô‚óúžÂŠ(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)€¢¿>?oOù-–ŸöƒÿFK_ â¿>?oOù-–ŸöƒÿFKRÀû›á×ü“¯ ÿØÃÿI£©4)Ä.ñFp ŽÇ¯§þ\S>œ|;ð™ûÑÿ^ÑÕÍ[Ã^¹4s^[ËçÆ»kk©­¤ ýÒÑ:’¼ ÇB8ˆl>%xþTÖõ =4hwÆ›¦Mä5ä3O Ž’¾1‘Ræá…kêü1¨ZjñCöí*}GW‹]šuו=äV°ZÆöçi6Ñ®Ö [ †Åj¿п瞩ÿƒËïþ=Gü+ý þyêŸø<¾ÿãÕ)YY™•¯|$ðï‹aðxñ Ƨ¯Ýx^ÿûFÎöþíZiåùÁYÊ¢¬‘ø1í …_JÎ×>øG\ LÚ¾Ÿ+˨µÔ¶Â7¼†þà\]ÛJJÄò*váXÙé¿á_è_óÏTÿÁå÷ÿ£þþ…ÿ<õOü_ñê«½ÂÆÿÁ_ _x–×W ©ZEocª®“ix#±k»DHíåhö%cŠ4#pRqžkOÀÿôŸkzþ·î¡«kºâÃËÏ$P—0ǘ£Œ2§›& Ø8,@­¿п瞩ÿƒËïþ=Gü+ý þyêŸø<¾ÿãÔ–aþ(¸óüEàÅÉùugr=¾Åt3ù°üÅoµ•¤øWIЮÍÕ´¢ëaŒOsw5Ë¢’ U2³¸ÏzÔ aEPEPEPEPEPEPEPEPEPEPEPEPESE~|~ÞŸò[-?ìþŒ–¿AÅ~|~ÞŸò[-?ìþŒ–¥÷?ÑÿïÂ~ŸØ¶ÿÛ´uÐ`W5à hn¾xMg‚…þư;g‰dû4|á­¯ì?þºþCÿÄÓoŒ ©ý“§ÿÐ7OÿÀ(øš?²tÿúéÿøÿ@Ëx`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙ:ýtÿü‡ÿ‰  x`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙ:ýtÿü‡ÿ‰  x`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙ:ýtÿü‡ÿ‰  x`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙ:ýtÿü‡ÿ‰  x`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙ:ýtÿü‡ÿ‰  x`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙ:ýtÿü‡ÿ‰  x`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙ:ýtÿü‡ÿ‰  x`UOì?þºþCÿÄÑý“§ÿÐ7OÿÀ(øš·FTþÉÓÿè§ÿà?üMÙýtÿü‡ÿ‰¦"Ý~|~ÞŸò[-?ìþŒ–¾ÿ‹N²‚Ex¬,¢‘yWŽÒ%aô!r? øöôÿ’Ùiÿ`x?ôdµ,gÜß¿äxOþÀ¶úMtÏü:ÿ’uá?ûØé4uÐSQE (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š£®ê©¡é77Í”B¹©å˜ðüqÍFºGŠ‚mt'­{1#Øâ,J¥ãþ<%}ÿÿÐÅzS̰ÈÎi¡3ƒþÇñ¯üûèø?ÿ¥þÇñ¯üûèø?ÿ®çÏSüCóå_(øoÀ^ ŸEÒ¯oô«ÝnóX׬¥¾†-ä·ˆE¼SÀ^F{”92(URpI!\ÜþÇñ¯üûèø?ÿ¤þÇñ¯üûèø?ÿ®BëöŒƒÁtø–Ô5KÙíôùõÝ%¢KE»˜7’¦ÔÍ$ñ*£æÜnXš¨Eû]hÖú¥­ë>Öt]ÛOÕõk™Z êi× Õ9 +ÚT8PÁ€Ï\ Ôïÿ±ükÿ>úþOÿÆi?±ükÿ>úþOÿÆk‹ñŸí57€-´;]sÀZÕ·‰õ´<:ÞÙ4¢UL’™–(gpwî' ®áŸÅK߈6ñ%«[­¦‡m£hº¥„W’[Þ§Û#Ýn¿ÊÊ#@*•;³»Œ©£ýã_ù÷Ð?ð2þ3HÚW¢RÿcÐ¥Ú¤ùiy6æöˆ Ÿr+»ó×ûËGž¿Þì8½S‹[Ñìµn¡YP7P>ý}¿:øöôÿ’Ùiÿ`x?ôdµ÷?ßù'þÿ¯¯†?oOù-–ŸöƒÿFKPÊ>æøuÿ$ëÂö°ÿÒhë ®áÏü“¯ ÿØÃÿI£®‡☠E.=Å÷”RãÜQq@ E.=Å÷”RãÜQq@ E.=Å÷”RãÜQq@ E.=Å÷”RãÜQq@ E.=Å÷”RãÜQq@ E.=Å÷”RãÜQq@ïÄ3j'Ð!ÿÇÅu—w€]Mƒ‘¼àúóTn­¡½·’ ˆÖhd]ŽÑ”õΰG€tÕV÷ZESW@€¸Ò€±Ó›Ì:×3ã?xsâéÒëV·FëNvk;ý7P¸Ó¯-·€®#¸·‘$U`0ÊÖÀÍ'ü Zoüÿë¿ø8ŸüiáÓçÿ]ÿÁÄÿã@$bÛü ø}o©i÷ñèwkqcyo¨BY½1}ªõWFf+,ª?Ã1èI«Íð›Àòé±éòør ìRÓP±×3K"o¤ó/#`ÎA1'œã¢í-ÿ§Ïþ»ÿƒ‰ÿÆø@´ßùÿ×ðq?øÑ},Á+jgÏð‡ÂVVÒ¦¿$–2<–Ú›x£SþÑx ê/>Ñçùd(Ì{öœŒ×C£èFƒª_êV¯£µ­ÕÔ×2ÌóGn®°.Ç$ /÷˜¶Xž+;þ-7ñÿ®ÿàâñ£þ-7þõßüOþ4ýEËc§ûfúôР’@’{ æ?áÓçÿ]ÿÁÄÿãAø¥8+%Ö±4g†Ž]VfV„æXwðWáÿ†Áà‹ø?Jøcöôÿ’Ùiÿ`x?ôdµú i Ih±FŠQ8ÀzWçÇíêÀ|m´Ïñ&ƒÿFKK Î§Iý½n¼3¤ØèÑø.ãÒí ²¶¤A“ÊbÝÙœvÎ9ÆMŸøx•÷ýÐàÍ¿øÕSÃį¿èFƒÿmÿƨÿ‡‰_Ðþ ÛÿQE¸Ãį¿èFƒÿmÿƨÿ‡‰_Ðþ ÛÿQEpÿ‡‰_Ðþ ÛÿQÿ¾ÿ¡ü·ÿ¢Šáÿ¾ÿ¡ü·ÿ£þ%}ÿB4ø3oþ5EÃþ%}ÿB4ø3oþ5Gü 297 481 ÿÛC     ÿÛC   ÿÀ)á"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ù×á?ƒÚïìÛů‹IâíGU½ñ+è@xnH·JÞRÿvTsÃdç$ã‚MXÿ„CöLó+|gÿÀX¿ÂàÌø'Ç„q×þ¤?믢¿f¯ÙŸJøµá‹okÚT~)¹Õ"’úÓM¿—uµ½¨lDÂ&$<Ž0Üô«ÆÍsJYUÔœ\å'hÆ;ÉÙ¾¾Kúgn <]GÔRWmì–ÇÎðˆ~ÉŸô+|gÿÀX¿ÂøD?dÏú¾3ÿà,_á^—ûJü‹à½eq§E“g,©ægp^Þ‘°ŒŠ¤Ü2£±¯zý|áO~ÍÚÕŽ½¦X[[ñèv:Üöên-%’ÌEe º®ñؼ}Mue¸êy–ë‹‹NÎ/tôÑýæ8ª2ÂÖT¤ÓOf¶µ›¿à|uÿ‡ì™ÿB·Æü‹ü(ÿ„CöLÿ¡[ã?þÅþ÷/Äo…~Õü à? øoðÞÞéþ0Úž£¦¬v÷š“Ãdïp~ÐÃ!|Âßx‘òŽ9~Í~iþ_é—˧k>*ÿ„oR´‡W[ÐÉ´s¢(Š‘´õöçÕä÷Òöûígø£™¥ªéÏOÁŸ ÿÂ!û&ЭñŸÿbÿ ?áý“?èVøÏÿ€±…}i«~Ïž ×ìd¸ðuŸ‰f›Lñ´~»´½¿uôGž&À‘¸rÙû¤‘VüUû.xBþÜøwSºÓÆ¥âµðÖ£ÕWQHÉWf)**ëå•ÛƒÉñÉÆV·V—ßk~hnN7¿õkÿ“>@ÿ„CöLÿ¡[ã?þÅþÂ!û&ЭñŸÿbÿ ú‹Ç¼7Ãë>·ñ.™¨é>*‡ÃjÚÝÚ´-™UPAÉ<‘Ž*ßÇ/€?~øgÅšo‰'‡ÅšPIWZ¬s> H_5~Ì€4?{*KÒ广­“üš+Þ½¿­íù£å/øD?dÏú¾3ÿà,_áGü"²gý ßÿð/ð¯}ý’|J%ø£ øFÿÃ~×4bô ™u½!nîc6;b‘Ûä#½šÇῆþ/ëR§‹<3¦x^Ê?ê~Ò.ü75¾.R9Š h»\H¢>[*98&ªTìÒïÿõhÍT½ÿ®ÿäχ?áý“?èVøÏÿ€±…ðˆ~ÉŸô+|gÿÀX¿Â¾¨Ð¾ø+úvïÉâ-jâ÷ÇøFÐè“,BŠBžt¡·gv:™ïRhÿþ/Äω½½½žûGÕ ²Ñt™õÈìê6@]¼ù«¸'…G^´”"öíËüÑwkúõÿ&|§ÿ‡ì™ÿB·Æü‹ü(ÿ„CöLÿ¡[ã?þÅþÔxûD›Âž9×ôf´¼Ó¾Ã{$ iw7™4JÊ®èv±Æ9^ `ù’ÿzOûéÿøª¨ÓRI¦''fŠ¿ðˆ~ÉŸô+|gÿÀX¿ÂøD?dÏú¾3ÿà,_áV¼É½'ýôÿüUd¿Þ“þúþ*Ÿ²]Éö…_øD?dÏú¾3ÿà,_áGü"²gý ßÿð/ð«^d¿Þ“þúþ*2_ïIÿ}?ÿG²]ÃÚáý“?èVøÏÿ€±…ðˆ~ÉŸô+|gÿÀX¿Â­y’ÿzOûéÿøª<ɽ'ýôÿüUÉwhUÿ„CöLÿ¡[ã?þÅþÂ!û&ЭñŸÿbÿ µæKýé?ï§ÿâ¨ó%þôŸ÷ÓÿñT{%Ü=¡WþÙ3þ…oŒÿø øQÿ‡ì™ÿB·Æü‹ü*×™/÷¤ÿ¾ŸÿŠ£Ì—ûÒßOÿÅQì—pö…_øD?dÏú¾3ÿà,_áGü"²gý ßÿð/ð«^d¿Þ“þúþ*2_ïIÿ}?ÿG²]ÃÚáý“?èVøÏÿ€±…ðˆ~ÉŸô+|gÿÀX¿Â­y’ÿzOûéÿøª<ɽ'ýôÿüUÉwhUÿ„CöLÿ¡[ã?þÅþÂ!û&ЭñŸÿbÿ µæKýé?ï§ÿâ¨ó%þôŸ÷ÓÿñT{%Ü=¡WþÙ3þ…oŒÿø øQÿ‡ì™ÿB·Æü‹ü*×™/÷¤ÿ¾ŸÿŠ£Ì—ûÒßOÿÅQì—pö…_øD?dÏú¾3ÿà,_áGü"²gý ßÿð/ð«^d¿Þ“þúþ*2_ïIÿ}?ÿG²]ÃÚáý“?èVøÏÿ€±…ðˆ~ÉŸô+|gÿÀX¿Â­y’ÿzOûéÿøª<ɽ'ýôÿüUÉwhUÿ„CöLÿ¡[ã?þÅþÂ!û&ЭñŸÿbÿ µæKýé?ï§ÿâ¨ó%þôŸ÷ÓÿñT{%Ü=¡WþÙ3þ…oŒÿø øQÿ‡ì™ÿB·Æü‹ü*×™/÷¤ÿ¾ŸÿŠ£Ì—ûÒßOÿÅQì—pö…_øD?dÏú¾3ÿà,_áGü"²gý ßÿð/ð«^d¿Þ“þúþ*2_ïIÿ}?ÿG²]ÃÚáý“?èVøÏÿ€±…ðˆ~ÉŸô+|gÿÀX¿Â­y’ÿzOûéÿøª<ɽ'ýôÿüUÉwhUÿ„CöLÿ¡[ã?þÅþÂ!û&ЭñŸÿbÿ µæKýé?ï§ÿâ¨ó%þôŸ÷ÓÿñT{%Ü=¡WþÙ3þ…oŒÿø øQÿ‡ì™ÿB·Æü‹ü*×™/÷¤ÿ¾ŸÿŠ£Ì—ûÒßOÿÅQì—pö…_øD?dÏú¾3ÿà,_áGü"²gý ßÿð/ð«^d¿Þ“þúþ*2_ïIÿ}?ÿG²]ÃÚáý“?èVøÏÿ€±…ðˆ~ÉŸô+|gÿÀX¿Â­y’ÿzOûéÿøª<ɽ'ýôÿüUÉwhUÿ„CöLÿ¡[ã?þÅþÂ!û&ЭñŸÿbÿ µæKýé?ï§ÿâ¨ó%þôŸ÷ÓÿñT{%Ü=¡WþÙ3þ…oŒÿø øQÿ‡ì™ÿB·Æü‹ü*×™/÷¤ÿ¾ŸÿŠ£Ì—ûÒßOÿÅQì—pö…_øD?dÏú¾3ÿà,_á\ÇÆ¿…_ßà«ão†~2²Ôt¯Yè÷qx¡ãLyÐÍ/£9ÄC’F3Óšì|ɽ'ýôÿüUs8$þÊ?‰$ŸøXZ7\çþA×>µ‚йQ•Ùóü-Ðzóþû¢¹z+Cô'özø7â¿¿°v‘£ø:ÚÊïW°ø€uSýÚZÆÑÅîی嗭{À¿ŒZÇìÏoƒ¼e¦Å¦ø¿BÓ¿³ma¸”=«(Ç•qŒ WfàŽsÒµÿà•ßòkOÿcçþ‹†¾¦ñO¼3ã»Xí|Oá­Ķќ¤:½ŒWH§Ø88¯ 5Ëa™F Ë–P|ÑvNÎÖÙÿW³;𘧆rÒêJÍwGÂ_5ßþØÞ<'Ã_ ÛÜê†ïU™î„VªÑÌòJÙTÜT¼þ5a¿fïÚxø:o 3ÃIቯF£&˜;|Tðð–áy.íæ¾ŽúïTñŠ´¡p|±òC vq¬j¹ù‹¸‘ÎkÍáÈÎ_øcÿô+øWÿ kþ"øcÿô+øWÿ kþ"¿F¨£ÛO¸r#ó—þßãÿý þÿšßÿˆ£þßãÿý þÿšßÿˆ¯Ñª(öÓîˆüåÿ†7øÿÿB¿…ð¦·ÿâ(ÿ†7øÿÿB¿…ð¦·ÿâ+ôjŠ=´û‡"?9áþ?ÿЯá_ü)­ÿøŠ?áþ?ÿЯá_ü)­ÿøŠý¢m>áÈÎ_øcÿô+øWÿ kþ"øcÿô+øWÿ kþ"¿F¨£ÛO¸r#ó—þßãÿý þÿšßÿˆ£þßãÿý þÿšßÿˆ¯Ñª(öÓîˆüåÿ†7øÿÿB¿…ð¦·ÿâ(ÿ†7øÿÿB¿…ð¦·ÿâ+ôjŠ=´û‡"?9áþ?ÿЯá_ü)­ÿøŠ?áþ?ÿЯá_ü)­ÿøŠý¢m>áÈÎ_øcÿô+øWÿ kþ"øcÿô+øWÿ kþ"¿Fªhìî&MñÁ#©þ%BE?m>áÈÍÿøcÿô+øWÿ kþ"øcÿô+øWÿ kþ"¿H¿³®¿çÚoûöhþκÿŸi¿ïÙ£ÛL9ù»ÿ oñÿþ… ÿáMoÿÄQÿ oñÿþ… ÿáMoÿÄWéöu×üûMÿ~ÍÙ×_óí7ýû4{i‡"?7áþ?ÿЯá_ü)­ÿøŠ?áþ?ÿЯá_ü)­ÿøŠýº‚K+i®.#{{xPÉ$²©TE%˜ž’M6Þ7¼PÐ+N¥CƒÜ ž‡ŽÜŠ=´Ã‘œðÆÿÿèWð¯þÖÿüEðÆÿÿèWð¯þÖÿüE~‘g]Ï´ß÷ìÑýuÿ>Óß³G¶˜r#ówþßãÿý þÿšßÿˆ£þßãÿý þÿšßÿˆ¯Ò/ìë¯ùö›þýš?³®¿çÚoûöhöÓD~nÿÃüÿ¡_¿øS[ÿñÃüÿ¡_¿øS[ÿñúEýuÿ>Óß³U"¸Šg#‘${yL3*°&9«oFÚÊpyÃÜQí¦ˆüèÿ†7øÿÿB¿…ð¦·ÿâ(ÿ†7øÿÿB¿…ð¦·ÿâ+ôjŠ^Ú}Ñœ¿ðÆÿÿèWð¯þÖÿüEðÆÿÿèWð¯þÖÿüE~QG¶ŸpäGç/ü1¿Çÿúü+ÿ…5¿ÿGü1¿Çÿúü+ÿ…5¿ÿ_£TQí§Ü9ùËÿ oñÿþ… ÿáMoÿÄQÿ oñÿþ… ÿáMoÿÄWèÕ{i÷D~rÿÃüÿ¡_¿øS[ÿñÂþÐßügðCöJñ|~7µÓ¬¯õïi—¶Ðé·év‚8ìîcl²Éb¿U+ã?ø*Ïü›]ýŒ¿ú*z~ÒRÑ•-Èš(¢˜°_ðJïù5§ÿ±‚óÿEÃ_`WÇÿðJïù5§ÿ±‚óÿEÃ^£ûF =5ÿÍãµÿ³ŽîàëŸgiV/’~Ëö“Cæuä íÍc-Ò)lÏo¬ý7Ä:n±©jÚ}•ô7WºL±ÃN Û<‘‰\v,„0ö5ñ—í«é7wÃÏBµÒ|/ %²Ôou Q̳–.bTòŠ)gq)Û"»:¾.ÑIñÇ$Ь‡ÄífßMÔô—†)^òæÍ´øÖú[uV_0îIÁ A´‘M%i7Óüíú;ö%¿z1]Ëþ ·sìŠ+âk]#HƒÁšõׇ¼oÿ 'ž÷E$Ò,ðׇõM?ÇÉuâ ²Ù]Aâ_Kgç`‘“­ÉŽ6!X€ÄƒŠìáŒ>ÿÏ·Š¿ð·Öÿù2¼–ÆÿTпgσ%ñ@Ô­´}Ư%Ö©†{=Ïz–2\doP-䵿 »œ×'ûgø¬ëzö³©iéúUæŸá{}WêÙßßj:Ô²4Žœ°\Ã~VØÙÝ–S‰dÚ9Òé-W_ž×Û¾ú®Þ¿[oÛcèoøc…¿óíâ¯ü-õ¿þL£þÃáoüûx«ÿ }oÿ“+ϵFðÌ_µ&¿7Åy/ÅÔÑhÿð¬r-™|¿ôn"™þÓ¸ÈͳÊþ×àMS¸ý¤/eñOÄ4§Œî¦Hoêê7zX•þÍ W"óìæÉí¼¿˜[axc½Yò®eë§ã®¨ŽowšßÕ®{ÿü1‡ÂßùöñWþúßÿ&Qÿ að·þ}¼Uÿ…¾·ÿÉ•å³ÞŸ ~ÑZÞ¥Oiãù/ÛS¹¿ñLö KJ&pék¨Å)hX|Þ\L… dGÍ_bT¥x©wEßÞk±áÿðÆ çÛÅ_ø[ëü™Gü1‡ÂßùöñWþúßÿ&W¸QE#kû2xáö£k®èöºéÔmDÍö‡Š5;èAò%Áhn.6#¨Êœ`€jÝzO‹?äÝ›ÿDK^mYȤâižÑî5]bú 7M·ÍupácL°Q“îHh×’~ÕÞÄÿ¼Wi&žÚ Ž(î~ÎˆÎØŽTf`“… x¬Û±I]ØõÂëI_ü|×<5©Z]¿‚±ôM/KðÚÞøRúÚÎþúëT¸7ù±éâ+¨‘)#&Fq)ýèÊmŸ.ô˜â4Þ.}f?ˆ×é2xaà–åöa¶µÉƒaíûOÛ<òy.ì µv»·õ½¾ÿ.Æ|Ö·õÒúùk¿}·ëǾüðoÄÝsã7ˆ¥§ÛÚÚ¦™c9]½Ähù¥bÄgæëÀ¯e˜m“Æãð󾣬Ÿ…|;áÛqs¯ø·âU¿†ìÑähÑMΛ¥$’;ª9DH¼×-µ°¡éEšm-öZ’Mì{„¿eß‚ž;ð冿áëŸk-ü~m­õ§Žµ·ŠdÎ2§íž Ö¿ü1‡ÂßùöñWþúßÿ&W„As­|4ÓôÝÄzu¿…4¯|L°ÔîSF½šçN±Ñï-f~ý¡„¼)<»taW< ÖOˆäÓ¼EðŠ×]Ö¼S‡§§5›ûM/ÅÖ÷ÃMÖ£;Ò(¦hH’  bl2’«„|ŒnÔmÍëáÿä¿L[nÏúø¿ËñG½jß²·Á ÿH²Ô&ñÞ¯pm,!—ÇZØk™„o)Dlä„ÛŠkOþÃáoüûx«ÿ }oÿ“+ɾ)h^ñ'„ÿgŸøïÁ á­2Òù ÕâÔäšQ¤ÚɧݤI,‡küöƒ"©]ÛNEvÞ5øqáÿ‰¿´G€¬ï-î5/ÅàÛ¹`´‚âT±›3[ˆK…`I\ý{RåÕÅôm}ÊâRº¿’{±zëöSøGiâ; ì|j×wË—ý¦&•¿g¯ˆÊeƒ Þ7žG”Þõé>&/ C°”Æ™dÓŒq |«›§iÿ²oÆFÑ|akâýâÞòK?ìÝ*âÆÇOÿDQ$â{‹‡t$'Ì!Yœ3õW‡¿äR‹þÁ¶_ÊMYب¾esÆ~6±ð…µ/ë7wizt&{‰"Y%eAÔ…\“ô¶¼ù°. >sÐŒ×Å?´^Ÿ¤O?Æ!⡪OãyÞÈx:^s¿Nò#ÝöhÓäuûGÚ<üƒ·v*ݦ‹swñªüx›ÇPø[ÇKâ˜åÓmŸÃ××7÷xt0Em2Þ¬ m$`£ÿ£¹}܌҂æü?¯UÕy2e'ÿ¯GÑúXø?ÆÖ>;ÐWXÑîî'°iæ¶*É߆7[”óÐõdx¢Èø‡ûûQ¶~Êo¾Ãç7ȳÌÛŸ»»ŒúׯzΙ|<'ðýuëû|=]SÄgP¸Õô»«ëïZë6bå-îmT¯±ÙöoÛ•$©~ð¿‡|7ñ'ÁZ†¥ªCâ›ëï Íiáê67Is¨‹àÖ°Æ’K!ÊP›Ý‹(š¬Ÿõµþþ˪)»6»?Ößwv}…çËÿ=¥ÿ¾Ïø×’þΣ:ÄÖ9,ß5BÌNI?f²Ÿ ð¯ý“´xÓÅ~¹»ñºC¥Î¾'ðÈÐ/ ¾–èæ›éæ½–=ÑË’Ž‘F” cýäñ/þÇýSÿI쩵e¸'{èzµQPPQEQEQEWÆðUŸù6»û-ôTõöe|gÿYÿ“k±ÿ±‚×ÿEOUÄÏÈš(¢¶$ý‚ÿ‚WÉ­?ýŒŸú.û ‰m¤C#Äãø‘ˆ?˜¯Žÿà•ßòkOÿcçþ‹†¾À¬¥¹H´ºâ+w:—;˜‰n>§žj1{p"1 å–ÜSyÁ>¸õ¨ÕÁ*Á€$dò:Ód¸ŠU’DBÝ0¨‰ìÅÚLÚuþ¡©Åƒ{Ù-î#ç9ŽE9CÇQT|á 7áÝ;†oVK»¦½»¾½¼’æòîvP¦Ifs¹›jª@  Ø9h¡h-É^êi|ÍóHÞaòÄîôÏ­sžð.àeÕŽ”—Oq«]›ëë»ë¦¸žy1…Ûª¿*¨áEn³ª•€XàzšZ¶Á¸Ž2Œ'Ê~Î>µð—Ç¿ð•éÆÛÅ^›VšÞ1¨@>Î.î§8uà–‰Ðàä®ì0 u”SNÀz7ü&6ÝøoÿÇhÿ„ÆÏÐàU¿ÿ¯9¢«™…Fÿ„ÆÏÐàU¿ÿ£þ?AÿVÿüv¼æŠ9˜XôoøLlýþ[ÿñÚ?á0³þèÿÀ«þ;^sEÌ,z7ü&ÝøoÿÇhÿ„ÂÏû£ÿ­ÿøíyÍs0±Úëž µÔl^4dŒªJ~kˆ[9‰ÔÉ$–«Š¢Š–îNGhÜ21V!ÁÚ) ´5[ÐÎÂòà3à±ó['3Íq$øY øÃ]SÖ¦Öo‘^I:¬Ë¦Ìñ1hÞK`v;s“×9Åu´Q³L:Xt’4®ÎÇ,Ç$ÖGìûe{à{ÏŠjöŸf‹\ñkêvÝ@ ÖÿÙö0oÚd ¿¼·”a€$FAêÑM;j#Ñ¿á1³ôøoÿÇhÿ„ÆÏÐàU¿ÿ¯9¢«™…Fÿ„ÆÏÐàU¿ÿ£þ?AÿVÿüv¼æŠ9˜XôoøLlýþ[ÿñÚ?á1³ôøoÿÇkÎh£™…Fÿ„ÂÏû£ÿ­ÿøíð˜YÿtàU¿ÿ¯9¢Žf;ûïÚ^ÚI”Fm ÷Vø\HMp—.$º”åZF Žã&£¢¥»€Wñ öøeðãT´Ð¼Kã]+HÖ!„É-”ÒæHÕ›*Xvär3Ôs]åYƒS¼¶ŒG ÜñF:*H@ü¤3ÆOí³ð|ª/ü,ý3j}ÑçÉ…íÇR[þÚßm>&ép†ëåÎëŸÈWµÿmj?óÿuÿ›ühþÚÔçþëþÿ7øÓÐOÛcàüQyiñ?LHùùy篤¶¿ÁåHÐ|NÒÂFrŠ'“ }GWµÿmj?óÿuÿ›ühþÚÔçþëþÿ7øÑ ,|}ý¬¾xÛàß´?♪j×Ú=Õµ­¿œÅå‘£`¨¹I8½ÓÄü)ð—À6wþ1׬ü=k=¥•¬/zû<ÉvÆÛu$b@$ô®ÏûkQÿŸû¯ûüßãPAyqm#I òDí÷™‚~¤PÁûk|¶BüNÒâBrU'‘A?€¡?mƒÑÂЯÄí-bn±‰ä  Wµÿmj?óÿuÿ›ühþÚÔçþëþÿ7øÑ OÛWàìRù©ñ7KIqë3†Ç¦qKÿ ±ð{2ŸøYúfeùò|ãߎkÚÿ¶µùÿºÿ¿Íþ4mj?óÿuÿ›ühÐgŠIûk|– üNÒÞéO!Qøb£ý–õ{/øCÇ:Ιr—ºV£ãJêÒî#˜çˆÛÙ€ê{Œ‚> Ž¢½¿ûkQÿŸû¯ûüßãUî.¦»póÍ$ÎHÅŽ=9 ¨¢Š@QEQEQEñŸügþM®ÇþÆ _ý=}™_ÿÁVäÚìì`µÿÑSÕGq3ò&Š(­‰?`¿à•ßòkOÿcçþ‹†½ÓâˆüJÞ7ðOƒ¼5ªZø~}zK©n5{«AuäÅo˜R8‹(gsÉàd×…ÿÁ+¿äÖŸþÆ Ïý }/ãÍÂ'¶´³ñZÛ8†_´Ú³ßËeq ƒñM ‘ʇ‚U†AÁÈ5”¾$RÙŸ.|7ñ÷ÄM7NðG†!šçV¸Õ¼Y¬jZ†akpÒ¼ZÌ‘b(î®`Qi2Hv`1Ôˆ¼sáŸx·Ç:ˆ ÝøwLв´[m+Kžk›ìuYíe´’f-1Šx§Y”9c¹Cí9Æ1[x᥵¼C‹2iØ.‹~ß6Ÿ»ÙÉ2gibIo¾IûÔs+.é[ÿ%i~-}ß"!öoÿnOò¿ßo3Åâ—­4ë–¾•§è^ ³Ð^ÓEKí+=„SMI¿1¨ÝòŒàä Ôо*üYñ—‹õ-[@ðÕåï…ìmö]¿­¾öó.ß×ü¹+àüø“ðëÃ^*ÐfÏêßÚšÄze垥i."H’ægØ#ÀÝùùmz7ÿgŸ€þð~µâσ¿…¶™i-Üžw‡tøP„Rp]¢ÂçÉ®†Ëöiøsaáí#E‹@•¬t½~?Û™µ;¹gmM²ÜË;Jd²zJ̤ ;Ÿø[Jñdžõ=\³]CHÔ {k«gfQ$l0Få!”úAA¥-oËýiþeGF¹¿­ÊÇÆvú—Á;ë9…¯ì»áYu;8u+BÆMM€Û%œPJÇ2B¥‹­ÂíG çksÄ^ø3áÛÿ߀>Ô4M;ÖzæŸ>ÓV[ñ<…GÌËû³’×Që¸ô¯Ñÿg¯èŸok}"êi¯áº‚îæ÷U¼ºžu¹HãŸ|²ÊÎÅ’†âr6ŒÍcÉû?|4½ñ}à’×X›T“L†ÚkIi6šoƒîd½ŽMsXVßê—7×z­Íª,€KqpòË"¢Bœác`q^‹®+^{ ßI)’úÎI$–0‚¨Ì²ÆAB ® °nr:f›×oëOøq¤úŸèþ øwá_ÄÞÖ>ü9ñ׈íü[&‰¦.•àý?KG·M"ßQv“ÌóH¹Ýó¼.N4ü'ìÿñ ź~›¡~Íþ¾Ò.%·µŸXÁÖ¬ó@³u± gÝ€O Í{ž³ðáŽá(4JÞòÖÆ]X]¦¡6¿~5 o¦AnßyÿifxØCƒ!0˜Û]ðGÁú/‰m5Í.Æ÷Hº¶Ž(ÖÛMÕ¯-le§—Kg«̨CÉ69ùW ?{U§å¯õÿ '¶›ëùèbÙGàƒtø9ðüŒã Øÿñª_ødÿ‚?ôFþÿá/cÿÆ«°ð€4¯†Úé::Ì`’îâúin|’Ï4$ŽÄ2Y@®’˜Ï+ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( +ÿ†Oø#ÿDoáÿþö?üjødÿ‚?ôFþÿá/cÿÆ«Õ( —~ þÍß-ü]£XEð›À±Y½Ä¬ñEá»8·í°¹ÉloE8Ïjæí¾ þÏ÷~*¸ðä_ üú¼‰žÜhÉ=3ž rG\WªünÖæð÷‰4»ûm#Q×®y=;JˆKs;>Ÿt€"’VÉ$€'µy¥·5 +ñ}oû?xžàæAvž°ó÷ž­ænÝ»ß9¬º”Kû2øo@Ñ|%ñçFðÆáÙ‹®ôÏø‘éPY“kˆÅ²(y³» ìÇ.p@ÀÿYÿ“k±ÿ±‚×ÿEO_@þÌÒ\OðãÆó]Ø\éw2øßP’KÕ <’±À$õ5ó÷ügþM®ÇþÆ _ý=5¸Èš(¢´ûÿ®ÿ“Zû/?ô\5Ö~Ô|Eñ_â„<5ámAì5[½Wù#œ@×Q(€Éoæ2²§˜ ¦YYyù®Oþ ]ÿ&´ÿö0^è¸kÔþ0x‹\ðÅÏ ë~¶±ºÖ´ï ø†êÞ=Fá¡€†&,̱ÈN$.ߘ€ \äaRÝM ›i#ƒö,ñ¿ü#^Ót[MSFÓu ëí+Ä–ö¹iq=¶‰q-´ì°ý’(¡Œ mßd1) ç¿8b[ý‡þ"^j¿ÃÛëާ­I¨¬ZÇü$6P麬ó«Á¬ t^8 Yf)1­¶»/ þÙ^;ø]ð“Á·^3Ñ¢ñî»á%ñέ©I­ÛÙùzkµº*ÛÇ„K$äÌçìøùB€g“p#£Ÿö¸øƒàÏüsºñ…ô-OÃÞ»Óm´ÛfHîD—v°½º3=¢©I Á¤‘Êù?2ªÊ1éå»mtOñi~ýk¥dú¿Êïò·ÊÇ'ª~Æ:Ň.ÀGŠ ðÏÄCV±Ñ%»‹wöñ°X"iNÀ¢VY|¦#”õ8=ÿÂÿ^,ðoíãïEátO kÖ·¦âëZ½·–òi$ò¼›{Kˆ•-ð„çSåm_-ŽMgë·®­¢Zé±\|;ÓŽ±sâÛ¿Mn¾*O³Ç¨Ä‘ˉ1¶KVŽP^m£a´ÆÙ÷žý§õÏ|wñ¿Ã <¦Y_øF .¯u¼J³E4mml!S±v2(`¢/ÌûÔP§Íd»?ý%_ðIú–1zùéNߎ‡¦|ðÔžøOá_ Çá ,íDgC‹T“S[?˜‚æOš^¹Ü}}«Ï4Ÿ…šžŸãï\ßøB-WTÖZò[µÌH-¤ƒdvXfó)ãj¯—Îìæ½cáψõ?øGÖu*×DÔï!ógÓìõÔ"²FÕ¸EU`@¼ÃÄ´V³¡hÿ¼Jž²¸ð‡ƒ~Ùnó¶´Ñê7—PF­±m¾ÌcH™˜/˜Óä[f:ç;6ïÙýÝMc²·tp÷³Ö¹à‡ ³ð‡…,äÕ ðe[{;¨­Ùï®,íã[™¥b<Я+>Yðà€y­-#á‰,¼QâKY<¨Z隟‚-ô gJÔí-纺ŠÝuo7z·Í夌¹A8^kGPø½âÍO͹e𦩧xÊÛ@Ö´½&î-KN¾†{f™qq5¬rä|¿ub!²àA­½;öˆÔo¾$O¡¿…­¢ÐV½Ð­51«»–îÚ×í.dµòÇ PÊJ͹@5R’Q”¥³ü­ù{ÿ‘){É.Ÿ«ÿí>ãŵÙ³Æ:¯|?§ÝønH<=¥^ݼ3¡[è–—²Å$$W7I*Kc$èÉ'Ï–@eeéŸ\xJÕ¬!x£ÁÚ¤nêVÂ;·iÑñ5©%ÑAb€ ¶9À5ŒÝžÅ-5>ÈÕþü%׬| 5-·Öz([ý¢8;`Uc·Ï]Š6Ž>QÇ.·ðÿán±âOêú®‘á»­jîÈXë7+’[|m q“Êàànìp+ãmGþ ÅâýZî SSÿ„SP:ޝxþµÕ¯4ý3BSÀñ}‚Xí™ÎÑ,»!ËHv²ã'7ãì/ã}Ã>-Ô--t=u£þÔki´¨.gÕüHu ØdDÔ“f Z…;J¼„„ù­/uªï÷ÿÁ!¶¶þ—õþgÔZ¶“ðÃ:¿ƒ¼?„t–]ŠëHÑ~Ë¡Iq§¸—2\[‹„¡G »+8b#ÉàW}£ü4øg¥ë„iš‡íõ‹u#‹tŒ\F.B –||ß¼ bÝv¯ ¯ž|1û&|Að†ƒáíKN ‡ÄoÄKŸZÜÜÚèööÒÙµ¡µ‚Qn·ÍÏ’÷aŽäøEû뿾:kž7Ô#Ñ5§½ºÕoX—Y»ûTËy¬ö‚FŒBï2·ÊŠV5nš-V»ëù&—Ͷ¾B[ùiù»¿Á}çÕ¾ д x_NÒ¼/gc§ø~Ö/.ÎÛMU[xÓ'„ Æ3ž•ç×w? u/‹ÚÎ.•i{â÷Óõy×N–Ktµue+u8S Ea¶F TtÅuü){ào…þÐu/AÑ/¬mDSiþ 6É;`ó}¼ÿÎs\'>ßjz¯ÅMcÃðøwLÖüO¡Ã§éº„ÖHÒG8IÖV˜ùG*âDüù•8Ä´}÷üŠŽ«¶ß™Ó|,ƒÁQxtYøv? M7ÚcµócI*0o06ì—R îÎF5¥má_‡ö.¾×¡±ÐáñZ¤ÞœA°ÍÎB” wdâ¾iÑbUµßµêÚo„ŽššÅ¥ý¶›%Ä—ÂÖ»´–xÑÞÙ]-åPÛž ‡KýˆüVÞ “Ã:…׆¢‘ô‹¼Mo4ÒßÝË6ŒºÙeV…sl’ o0– Ÿ»C“Ktëò°u±ôæ½á/·‡ô-TƒLµÑ<=ui.Ÿbó,0ZËn¶rÉ…*§•N8µã Yü@ðf»áFI¢Óõ›´û‰-Љ9P£, qG±¯œ¼eû:øëÆQx‡X¹Ñ¼¾)Ôµ8¯¬wêòÍk¦”±þc,º{­ÑÜ Øñ ÛŒ:š÷Í/Ž&²¾µ°>·Ò`)¨§Ë=Õùv@çdjªÎ\`œ¦®š}Ëú_p”žúßþ þó‡ñïƒ~|$ø|ˆ|9¦ÚèÜ©Kh¬æk‹‡Q jÒJì¸MªWŒbº½?í ³‚-'G°3´7ñXÜ[¤‡Ëo˜\VD±`€BÇ·¶* cø§á½?Nk-*òK]RÒøk@²¢¤s+H(Øb Žœç€MeÛü†Ûã‹Iio£iÚw„§ÕÄ‘KZCqso0Ufß·zï…vç*Ê«Œ©é ¯i¯x-Q´k²7ë¿wgns÷yús_+Ü~Ì4Ö¼ á­'Tм ©áÿêš´~²×®#Ó¯a½7GkÈ4ñå4åJ †*~áÁ‡öC»LÖ)£h—òk¶W±ßCq-ÅÕ½”ZJYI¸hÕÜî€p%IÚmïåú~_ ž›yþ¿Ÿê{ÆñGº®§­XÛkv­.ä ÙYöØ1Œ OÈÄí<)$t8ÍuÈ“F’FÊñ¸ ¬§ ƒÐƒ_"ÙþÉž#µðÞ¯l|-àˆîžçH›N²²Õ¥†Ö)m-&î¥Ý§È’;så4,¤1ËîPÇè Cã'Zðö©C¥\x~ÏÃÊºŽ«o…§Ôƒ"ªA¶ ‹+¨4az0ÒN×þ¬ש§âï‰Þð&¹á­#\Ô ïˆîžËMd–UBåYÕJ§‚äH$â³~ümð‡ÅmAÕ|3q¨Xk–ÓÞYJÖ3ú(¤1;8tSÎ]ànÁ+‘XÿþÛ|fÖ<-ª#“ÃöóíÑ ä†àù…‰¡d ²lîÀ#=+„ðÁx'ÇþÔSEðtšf–ºÕ½Åô:”Ñ^/µ¹#ìdŠ=£a”Å€ÀŽi»ÙÿZ˜Þ×Gµxkâ7‡<[á7ÄÚ~«ö.£gý½ÅÖmÉ‚Q˜Ý’@¬™ô`jè`ž;˜cšXdPé"0ee<‚ê+ãþÅ>'ð¿ÃÃlѼF¶-§ê7qê:„ðµåÔ0¼2Z4âÞCöE ²D gk)íËï_¼3â‡éà¿ iú&›§xJÓOº“SeÔe¾kyÌ¡‚ÞYnë—s¹¢U  ¼ ½5·rSvWìu>$è¿ ôkmO\û{Csu”éšuÅüòÌùØ‹ îIÁè)Þø™á¯hšn©¤ê±=¾ ÒÇoÐkkƒ$R4RÆÐÈÕÒDdde ¬¤®ãÂûÏŠÚ?‡4ûKöÓVÃ^³Ôî'†éíæBå˜D複=ºq^O®~È1[üG·¿ÑôÛ GÃMggn×.m/t©â¹º¸šâ°Jgy¤ºó2DKGË0o–.ï·_Óüô-­4>‹)ÑJ\¸Õì Zÿ¯o´¦!ç??/ƾÒþêpÉ®jà«Oìß Øé(ðö®«ây­µ9'sqöyË®ÖgŠ” À™$ Øøà†¯q¨ü.ÐdÐdÑl¯,î/|ebš\ÑØ½ŒZƒ^éÐyΊžjÎJr<Ï&âbèŸ-]´O¿ôŸÏ~ö!·v­·ù&þí½Oµ*ž¡­iúIŒ__ÛY3°\L±îÆ3Œžzαü!wâ‹ÍCÄ­â+; õ‹F[wÝ,¶÷’Ägó00»r3šæüeð‚ÏÆÿ<1âWOÒµM3GÑõ"þ4‹5ĶŒŽˆÊWmä’ÈÀ98žß×KÿÀ+¹Ðx¿â_‡üáígYÔ.临Ñã2ßǦ[É}q¬Ð¯&ä¼IàÖ_éEl jÑ5ú,–±Í(æ U°OQÆ+ç/þʇ‡4ßé—ðé«u­iZ®™Š!Õî'º»’¼®-E)¼ ùÒŸ“ ´1ŸÅÙ×â?Å]ÃÂæ? ÙjZ~—oj‚-Vrº}ÔS£™â›ìBIC"ù[O÷ê¡g¿—ëÉ}äÊéé¶¿¥¿7÷CiŸ|1¬Í¯Ãc­ÙÜË Îmµ$ŽPM´Ê·ü×§®:Ö†•â3XѬµHnDV·vq߯.ÔÁ"Âê3Æà2pFCAàà×’ÚüÕ<7­üT›Kð‚õ;?L/-ZîsjòHÐC\¢ÙÈ6n‰¥ß—,Îrƒ–®2Ù—ÅÚ—‚>è×ÿðŽéÒèZM·…üJ–ws\G¨i1$$¬,ÖñÍ-º|Œ¡B³ Ç5»zù~·ý>EìŸÌúOûK3\Ãý¥içZ®ùãó×t+×.3òŽG&¬XßÚêv©sgsݳçlÐ8tlÁæ¾^Ó?d˻Ϯ¡áý_“j¯oªÉâ[«K‹Ô¼¸y– ˆVÍ–1ºÆ̘ ‘ݵ}Àøð÷Á¾ÐRÏÃ÷2¶µ/ö™´ –Úv˜ZYP¤pyÒãbo®Y‹2ã-URoÈ—§âz'LŠÕøkበ~x7ÂöÚ†cÔ-õ¨à¾67òOgm¥´Ï4ò&è a Cå¢*0ÈOÊÒéýkoëÈ”ûÿZ\öú(¢ÂŠ( Š( Š( Š( Š( Š( Š( Š( "øÿ#þ‡ÿ]®?ôÙwPÔßÿäÐÿëµÇþ›.êÅîQç_³§üˆßì|Ôÿ”5óÇügþM®ÇþÆ _ý=}û:ÈñþÇÍOùC_<ÁVäÚìì`µÿÑSÕ-ÁŸ‘4QEhIûÿ®ÿ“Zû/?ô\5ØþÓ?õ/‚üâý& 6âúËKÔÑW‘£µ]íl…¤eä( I>ÕÇÁ+¿äÖŸþÆ Ïý zÇ› j?üž5†âç@KÕ%’ÚКâUkcH£ï³ÈB÷$Åc;Ý[È¥°ºí âoüRøe«j%]&Ò?ë Õbѯö±½¤“Cs±DÿX~hØ Õ=oþ â­Äþ-)àû=WÂÚk³h:ˆSjg}6TüÌÌîcˆw1DS·~ DMª|&ÿ„O@ðŸü5áŸÚÞ\”Ò¼âõÓ"2J®0[¤’Dçt€,’ s‚qRøzÿáœ~ ø‹¬Üø3Jð†« \›}wYÕl,mšåÝ$óšáXîâu‘”ㆾËÉ'ù-~ýmæg»Vê׿ßåo¸ðψ?µÿÅ^xCAÑtŸxç_Ô¬/u{ËýSH4¶†€yMsu¬ M¹Îç*¥FC½ïÃÚSÅ~"øÏâø«NÑ<1خ—i7¬’,/˜¥¥GÇÌ>bXgѾÕ|/=½¤“\\Hšp¸2}¤9Ž7œþêHÕˆPÀ°5ëÞðLjžŠûúOƒ%ðßÿ‡š_ŠBÇEµ·ñD w%φõ®¬m­m’WkÉZê¢wWIAVa²UÚ$Á5ô'‚¾$è¾3²Ñ+ëH5½OF·×?±MÊ5ÔVÒªáÊ}í›nüc5Áj^1ø_¨è–º×ÄÏ èÞKéá[4ø†šm¼·N±“LÊãr«0HtÉWšê,¼SðÃDñÆ©mk¯øbÏÅvÖ)o{fšŒ uminžhV‹~cP瀲“Æ*äÕÝ×õgÓÓR ­«ì¾ý¿àúžwûaüF×¼#áïé»Ö­5ýJõ®Ch]Æ£rÐ[!•£1AŽFÄ_n™ÉkwÁüEñ/âöš š%¯…`ðÞ¯‹›«ye¸ŸíÆó*¥dU@¢ÙNH?x¦Þ©ñÓá5§†dñ§„¯4¨ ¶6úÔ¥¤‹$˜ö±M¿ #mSå†É!x§x7Ç |E5§‡ô›Ï Ûë:¦o+xc̵Kÿ°´FX’[U;¼µI˜í ¨ó79Ùënÿ£ÿ€þFuéú¯øcÏ-þ1x«Lø¯k¨è×¾1¸ñ¡£ÚÛ]Á5ÄzŒë}q P@«*²d"œ³ˆ¬O5»ûExÏÚýÔV^ž Z×Ãw66æoµMy6ž·Mu-³£>6•,cŽGÜ1Šõ¤ø ðÊ=%´´øuá5Óe¹6CCµ™UYMž^7‘Ô62°èMsöú¯‚o>+O¥i_«ªhvÑh×þ$³Ó,Ö &)"óÍ¥wYJùn¬c‰]TH»¶î¡-•ÿ­?௚{­Sïëý|¿O=<À~Ó~:]ÎÅ´ýçÆ:„zmÕ•½…›½¼±\ióÞLç]B¨c[i˜ò¨+€± }·á_Å­/â'…<%y5Õ•Ž»¯i «Ç£­Ò4Æ!±d‘´jΣxÈù—žFyÝ[Ç¿5½R}OÄ_/ô]:Kh¯šîúÂKkWRél²–b¨A*Æ0Á{ÖÍŸŠ¾i:´³µ×ü)gâÓ¤„µ°‹Q·K¡§gÌp†È‡É¹W.IÂŒ;ï}¿-ü¾–þµG)û[øßQðÏ€4DÕu[ñ6­›£áí6}FúÒÌ÷3E1ÈìD0ºä!ÁpN5Îøö‚ñ¯Œô½&ÿH´Ðì-ÓÁiâMR=JÞv/GŽâÌ tòÊI¨Kd«. žk¯‹ö˜øG®øï⟉¼?«Xh²Ëj—"þÍfŽbÌžTo,ЍÒìùAu0sŠëá!øq¢øÅ<ý¥ákß@åt>Ú;ëˆ]žG" ‡df29ùH$±=ê]šOWþZ˜ÓWMì¿Ï_ò>kÒ¿k¯‰—v'‡4 G[Õ¦†ÞÎM1Y!Œ0LæE¸¹‰_+pWÍBY'!k¶Òh?ˆÄVÖºÞƒ¡éP[cA©X¬¦{Ÿ:öîîÝŒrÇ+D  hä —ÆöBÙ\×¹ßü:𦫦Ýé×¾ѯ4û¸ÄW—|/È6a] á‡îãàà_A^k?į‡þñì¾ “N³Ó[K²}V 2Õ4»i&2›0¯æ.\)lFqóÕ£jé.ëçäBNÎý¿¦siñ›ÅZ&“ãèVk]_Åøá|?¥A «O ¡ì­&XÒ7¸ˆG+gtÊ»ƒüÁkо|lÓþ"x Ázž¯s§hÞ ñ"\­¶•öÈËÜËnγù;y€ËŒà)ûÄrpaŸörÑm|Oc Ÿ ¬m­:õ²64ˆ$û ºQ€»fyÑÆ:×Eiâ/„š~¿à¿²ë~´Õo,åO [ÛßÛÆ×6ó²³›8•€‘\¢üуžyäæa¤Rnû~_¯õçrw•ýL¿ÚŸÆ×þ øAý{§kº½ÄM…Þ—e-åÔÌáL±A;ÈÈ›ßj£)à×ð÷â·¼e⯄±Ûk6¶zMþ…«¦¯e«é“%ì—¶SÚÃ'˜£1ɇbËîSÀŽÿþë^(Ôìľ½·þÓ¾Ö^öÖK-&O1­ÊI>ò ˜`U¶¯8©®¼YðcZ¾ðõ•γà;ûËë˜õÞ[«)$¸žfuŽêÙI%Ùe "d±85QÚýöü¿;™ÏWdíoøÊǃxö–ø‡áiðj¶'Õ5Xa“JºÁY"3kBÃý(¼±£àM\4@•ØHÈjêohŸ‰:ÛdÖ|;¡iƒD±³¾ÔìÞO6âáfÔ^ØùFäŽ#å¦ð¬òÜGЗ~ðåý„ö7^Òî,§¶{)m¦²£’mÏ)\cÉSÁ<‘^u«k^ð?‹-~è çÖ´¸ï$·Ðl4è,ím>ÐÊÄÓBn`ˆ­ƒ“ŒÑ R×ëäTõ»Z-?OÌ—À5‹Ïø¿DñªØø}´ÅžöÒÜZȨtøætMxdhd(, #FI ¼f½CGÕì|A¤Øêº]䎙}]ZÞZÈ$ŠxC$ˆêHee ‚8 ƒ^Wyâ€ÚøçG“Yð‰q}Í☠¿³³Õ¾I^ð£+ƒûà 99a]-ŸÆ†vÞ²´ñ¿…-àÕat[xµke[È·ˆ£Ê÷‹»6dgÏ–©|¿¯ëÏ`{¿ë·õ÷n|×á_Úƒ_¶øã‹ãq¨ê:F¯«,:¾¯¦Ü[éöÖöú…½Œ¦Úá£XçÞ5Á1»„Î9è:íâxoæ½[2׉u RÖ£µšüÃà YŠ)UÔ»I iBº!P@9¯E¿ñ/ÂuO ^êž Ï†ìdû~qqgÿ«F@$óa'÷1aÀ)R3Á«>ðwÂÏé×¼;¡ø?]Òìdyô]OK³µ¸‚Ý÷w¶•T;PŽSž”ãd•ú/Õk÷'÷‰¦ïg»ýŸ‘ç–Ÿ|wáûŸÚŽ£¨hÚµ§„æi45m$…‘³-îcW0å vÜq’ÛÈ aFGÄßÚÇŸ 4=[‹mYÕäÒåñ£iedÐÁo§¡·B|ùîÐ+ &+›+ˆ¸c^·ñBãÂ?t/xÿX𵾫w €´»šÒ /®íË`[îr»³ýÆ`¼šÅñŠþ]èN­ñSAÑ|!áÓmü.–²!†f…–icU9 á°‡ N¿u¿_ÏOĘ̈«oçú~Fw€u­eücñ~Ê=vyųØÞi±ëOçEd'³P»[ÊÞŒö85çz×í/âo |"ðF§¦Ak®ksèzþ­ÊO²[æ½cAqðNð…5=GNð†¼7ªMö=I4Ø-äžEtHÊ«ÌlIsNWwåÓo×úù[ÌPÑ.mwýMС«[÷üWèÿ®Ö4ïøË]ø½â¯Z¾ƒg¡hV5ÄöóIqq-Äs–Æ%UEV‰ûÄ‚GòûCx»@ø3¢ßÙ-ž¹âÛKÄh¤‡Ì†H,o.ÖGKsÃHF7ÈÅW"½Æ/ü;ÔuË¿ Ë{áÅñ öœ}ỉm…óÚàMmæ5V# €Hé^wmãÙnÃDk-´ƒ:\‹Xîô¥·3l%$ÚÝû Ýv“Ž+9'}õrâÕµ_ÕOðGĽÆZ‡T_YÛkºÆ‡¼º)ºF¹[if@™ÜcWuMøÆHëÉÿk OÅÑk_ ´Ÿ ê³é³jWÚ€¸Ž-_û-&X´ë‰T<þLÄd ¸%FH5Þé~:øIgã ‡ÓüSá¼Hš$&H`Õmüø´¸Ñ§„aþHJdÜR¬H“PÕ¾|q°Óྼð?Ä !w"ÙÇq-ž¥¹Ž1Ä`—bÄÛÎÞB6Oªªæ½´ÿ‡&Ûëÿ x¿€i¿xŠïÀZqÚÞÖžÓ@½ÖͲY]&£%‡Ú¡k’Î@Úß$0Äù™R”Þ6ñÆû6xgSÑ#i¾ ‘µ-Oúž¹¨øæÿÃV—RÙMµ‚¥õÄa¥Q6\B(*~eËæ½å>øN/XkÉá}5Ë agg©®Ÿ¹¶€QË·r  ‚x¦_ü3ð~¨5Á{áMìk»?µ„úl/ý£°ŸhÊþ÷h ùÆ*¶×tÿ+¢ZnÖþ´kó³ù}Þá¯ÚÅÞ »·º:f‡“mo¤›ÔQ3Ks%Ö©¨XI%¼›ÂˆØVXË)ÊÉÉèké='ÄZV½>¥™©Zjé·FÊõ-fYÚpŠæ)?#…tm§ §¸¨cð–…"&‹§"$P@ª¶‘€±ÀXÀƒ»f(:)cŒdÔš†ô¿ %êévQY ë¹oîLc™§åäby$ð=€p¤¯³óý-úÓúþ´4¨¢Šc<‹â?üúýv¸ÿÓeÝCS|Gÿ‘ÿCÿ®×úl»¨k¹G~Οò#|Aÿ±óSþP×ÏðUŸù6»û-ôTõô?ìéÿ"7Äû5?å |ñÿYÿ“k±ÿ±‚×ÿEOT·~DÑE¡'ìü»þMiÿì`¼ÿÑp׬|Oð9ø…ñ÷áΑذ½f©ugtSzÅq·’&eþ%Þ£#ŒŒò+Éÿà•ßòkOÿcçþ‹†»/Ú:ÿYÓþ5|)“@¼û¬Ææ8dk™mãbÓÚ²<_?–ÙÃA#¥e/‰/5ù”¶gµ|Wøñ ã—ZÇŠ¬tö’ÎkK;Lº¿‚Á¤’}‘ʆႣ®É²ƒ~pqÏsÃÿxwÆ;Õ´í*KÁo4I|²¬–÷‘@¶ü”àÄR4n0Á³Ú¾_Ôÿhïü1ºñÌw:ÆœúÍ·Šµ îl¯îlšíôÀ¶–RÏ4N˜óÙ¼¸ã™¶Ëu7?¶Šå´þÊ:|Zf¯¤èu}Y¬<ÛyžÐ¼7 m2DžKY߸<ü¤ŠMJš¶Ò_š¿àL•¥¯Oó·â{„~ø“Oø}ðë@Õµ‹µøNþÚg›OIDwpà 1Èc¸“ÔW;ÿ Ë©Ükw s¬éçD´“^ºÒÌvÌ.Ú}Q\J.œ4iæÈp¼¹“‚ƒ>eûJê:¯†|{â_xsK¸ƒÇ¿Øw>EɶMZÝßDÑÝ€˼fhÛ#pÁ¯TðÅM>ûö‰ø› \xËHÕc´Òô»›;+[¶ßn7_£1}¡Ð²*FÌélC¨}ÁS'}_[þ1‹ü¬ ~£küË:÷À õk/[E©ÚÀšWµ/ös´½Ð±UðŠ,È+ßxô¬ÍCà¿Ä+­CÅbÏÅ:nmªøfÛÃöWö"q{fð$Å'RN/1Î0@ƒšöO ø¯JñφôýC»úMü~uµÊ«(‘3€@`oJùëOÕôKö’ø§¢ø{dzÇâKOÛMga/‰/5m.ä7?ha¦µØ‹*ßä »>\mÞK);7~·ü¤ÿV$–y~-’:¯|"ñ·Ãk+¤Ñµ=®µŸ[jZ”—³Ýßtõx–[™YeqPìÀ/™œap}'âŸÃû?Šß üOàÝBy-lµÝ:}:Yá¼BD+½sÆFr3é_)]þÒ>,ðoìûà{ë?hÚ÷‰D¸¿¾¿¾²‹Ê’Kh#2ZJÍv¸ºÞø*»œáˆŒm5é>ñV©wãOÛè:ÊéÞ+ñ…ì5I×õK‹Ëoµ42³˜­ä—åXÆ®!:3D’”e}V߃ý"þaY¦´{þ+õ’ùþ!üø—ñOÂðXë~*Ól§X.-'¶Ñ®oì­nVH‚ ¤òeI«dù%¼²ƒž Q´ý–µ7ÃÆÇNñriwë{ìZ¥±Dé¡[iŠË“÷ƒ[™ìEo|'ý¡añ§ƒdñ޼ˠx[WÔít­ ÖâÙÖëÏ}ɸ$—û[K6€<’rAÈè¿i›ëÝ3ö}ø‡u§_ÝéwÐè—Oí„íð8Œáã‘HeaÔr*fí/OÃQÅs4½Wߣü#³ý’|I§êþ·½§K­êŽÊ±êS^ê1Åéíg!i®ey¤~C 1ò`koß³'‰4ŸxOR¾ñ{jšg‡î­.-à–âì$Iž¶¦Þ+Q(¶@\I/šQ¤ýá\à ñ=;ã·ÄoxËĺšü—ºTº_‡õ=oÅ—[¬ š;ÉReYfŠ4{ÈŤ¥ƒ ™!™@¯Oðwí?ã=_źo5 +O>(mjÞÖóV°F“M0Íw«'v]¾ÆÒ·™¤Ãœ|ÁkX·Ïu¾Ÿ¥Ÿâ¾ò¹,ö×ñßò>†ø‰íü-ñ…ÍÖ¼óO$§NŒ¤1ÆÒ¹†1žIXÊ)n7Nk–Ò>øÂŸ!ñ‰àÍ^ÊHcµ°™g´–î…’Xä[˜d_µª´‘˜Û1ª°ùÈlz†£ñ«Rºø³©i¶^&ðõŽiiÆ“£KšóÅdLå­&ó”m¾_È’r¤œqB~Î\ë{§÷j¿á·ÜmsE§Ù¯ÑÿÃì/Š> xãTø'ão‡¶:Þ³\–þ+}Jí'2GmvòÉ'˜ òêÒ0p@æ™â¯€¾.ñ¯Ä ĺ§Š#û%Ž¥§êgMK»ß³[µ³ñÃn$X_ÌùO›*3ƒ8Æ1> ~Ó3ßø;_ñ'ŽüE¢_h:Vc«^ë=›Å<êÆk I)yb!èÙlS_@øºY ð®µ$Rëö<Ö¯£´kšb KÒôÍlÖæÑ¤7­s\K‹ Èm¸†Ó–ÉÒY~Ë×išükw¦é³ë:T%°¸¸Tš×Rº½–C,îÒÈd7#–lîR{Ö'ÁoÚ–÷Ä>)ñZø«TÓÃ:ñW@°ÏažHÞˆãšl8P§iÚà‚ r+é©Cªx|jr—·¹µóᔤ«&å<àŽ÷«mÆ*~¯ñwüSû‰åŒ¤âü¿%oÂÆo„àñŠ$ѯ5oêžÓ/m,Ú[TÔ ºÜɲR¦³y²íWÁ06†T×òv·ËEþKçæ)ÊßÇÊìîu¿ÙÓ[Õü%âÿjé©áÛÍzoi󠸆óírjo1Îñ:‚Ve+…ÛŒ®—Á_üWà[-ÓJmNK­fmGIJ¬·w¯u‹hÛ-Ì#JÅ"Ù¸ €+Ð4èÚ÷ˆuÝÂùnuM ¡]BÝU€Ê…ã‘‚JŒðN;õ¯’ÿl¯xŸÀž;×u­/Ä:ÍŽ‰gàKˆï,loæŠ8Þ{¨áŽím–6eÄ‹†‘œT§ÊÒ]EÑ"¹n›þµvýn}7ñ“áèø­ð×\ð¡–ÞÔãH™®¡DTH¬C!á FÖ*üðö‹âÜø_GÑ|/¤x^úòûû3KÓ£¶‰äžÒH "ÆU¿y’q’+çߟø{Pø›¤Ûx»^—Jð]¥¥Öšðj72Þ-¾©.ë–¸vbfkX⺖ݱ$C÷â _@x#Æß<'á-Ʈ鶪4Û éõëu§¼qŸ%ne–g< à¾Õç§4ãgë¯õóöþºw…gMWÀÞ-Õ5m:m3R)u©êZEÖ©}¨É-µÕëÈï˜LÆæWRñ f\dd“TÏìùãcà/iQkšN—âÅqg‰ôÉ.¡¸·‚S7–¹+&ã/Á‘ŠFx*ê¿k·ÕözñjèºÍÿ‡µI#Š(5=.åíî-Ù¦EÜ’! :ö<ŒŠù“UøŸ§ø®=kEñOŽu/ xºëÆwZ$Ww>4¿Ñ­t¨-¬l…õÆØ®¡Ž@¬Ž3•2܃­!¥ùÙ/Ãü¯÷´÷ŸVÿ¯Ãï>ƒøðCÆ_u?‰p]êú$:'‹<8¾‡÷S<öâ5¹)#òÏrw(Ç Ç&¸ßŽüX5ë>·‹Ä:§‹lu=í'¶F‚ÚÖîÚÞ2YžEÁ lŠ•8#_BøSÅÞ½Ô$𾑫R÷HÓí.%Ý3Ü9·™XA+LÙó ˆœîÜIÆO\Ÿý«µø´¯iPë¾+Õü#á¿øFµ‹›;+XŸLiõˆÍ¿Ùcß ©™ÂŠ@Û–Cœ£àb'Ë}Wæßê¿¡ÛÓôKô‰ìž Ñ|U£krZê–ákM*ÎÒÆÞɸk”R'‘Üñ·î\v'=«œøËð“VñƧ§ë^Ômì5{{ ½&dº–â–Öà.ý³[ºKŠÈ¬¬Œ^GZåþêß¾%꺮â½V×MÓ,4}.-ON²µž×Q’æçOs¶î)Ñ e•¾Säm pG—\þÑú׃¿gOË¡xžÊÅ¥\ÿiÜ댷¿é±~òÚy¥¹ÅÆî6’ò”àÖõþ)9½nÿßúìeEYFZY~±èŸ ?e{¿‡ž+†ê}](xnúÂM^¿á/¹¶’]"=šBN¶Öð}«dO$™_’S’ÉQ½þÍ¿ ¿?é>n_ïmùþŸÒ:ÿøcÜYéšu÷ÿ´,4è+´MvÑÀƒLû“ ”[ªï2Kæ20®@­/ŠŸ³Çˆ.mn£ðüòɪêך,V×¶Q¤i¥¥­»ÛÜK)g¤I,x@[;fðÄû?ÅáÍ+SKñž£áë}~ëCe}öѾÅ|’06ÈÅ0pxýŸæðí¾¢š¦».«sáK_ ͨHÒIv|¹.ÝœÍ#3°ÅÒ¹‹~ìI¯5Òÿc}KLÐü;²þÅuß Im›y¯«©º·†Ö{Q’ý§Í·Â\;*ÀÁC*ÄWksñºö?Ú'DðÚxC»ð¾²ˆºuŽ‘W·s1¶šV–w[€ðE˜þWºe-ǯxWÆz7í/n´KÕ¿‚Îòm>yXž&Û"rpxÈâ‹__ëGÍþ!¢÷­U¿%øUàÏ:·€u9WE—E²Ñu>ÞÇXµŒ\mÌ~i-k+31ÜgsûÒHb[<‘X¿~ø¿àÿÛý3ÃWš#ø®×H´Ðtmjò{ë –ðŠÒÅ<®±ª®_ɇjîÈ cèš)[Vú¿ëõcòƒ““ëES¢Š(¢Š(Ⱦ#ÿÈÿ¡ÿ×ký6]Ô57Äùô?úíqÿ¦Ëº†±{”y×ìéÿ"7Äû5?å |ñÿYÿ“k±ÿ±‚×ÿEO_CþΟò#|Aÿ±óSþP×ÏðUŸù6»û-ôTõKpgäMQZ~ÁÁ+¿äÖŸþÆ Ïý z×Ä¾øƒû2ãY’ßKÕ#ŽÂÖHã’i$khÑCHÊ‹ó8É$3^Kÿ®ÿ“Zû/?ô\5êß>Ú|Vøíð÷ÃïY^éš™˜K™í¤(ÈH0M§ØÖRø‘JÝOlð÷íAá¸/bñ#IákOÕgÒ.ôÛÌ\f‰!‘Û̇zy{.`&BB‚ûI ­™¿hï†Ð&®Òø®Ñ#Ò¾Ò/£"'NmÔ”„`¹Á"¹oþËZ±¯èºŸ†4ïè‘ØXÍ¥¾•«xZ=GO6ÒÌ“9†–ÛÓ;òÊrw#pDZÇìµ­¤XØÂFÐ¥­îµxX‚ö…ñ»+à/;÷±œ/JÑl®CßC¶?¼cÒuØåmJyí-!ŠÖg™¤…•fSBȺ,—'‘“ÄŸü5o¢Î,^ÛÄ7÷-io£Æè{5ª±º‡2aWhF \…è3ÈÏâÏÙ¦û]½¹ŸMñ=–•%Þ»w¬I¨*VÔíu·SÔWQ-þfe‘_+º?“›>ø-7ü.ˆÞ/Õ­n4û-RìÝ.ÎKˆä*$Ž1{x2í O•¾`mË<Â);µ¦öû—ë§ã±KIkµÿ ÿ–¿ðN»Ã?ü$žðüÏ-¿†áºðù×`Ó% Ÿf°‰b“ä §pÇßÇ߇úcj_k×â²û&¯p÷³D¢Õ"Yd•YÛ+¹ uÄkŸ³çŠüàÏ êþ,ˆ·†îÌ?kÓô³¾ÑÞ# Ú|ÊÓ¿2FWtª@ß0AŒV/c†ñ¯‰üC©ÜxªÒµ;mfÞ9‰¾ù¡hÖå%¹iÿy!³j‘€N=[;~Ÿ×“ò!]%+ÿ_ÖëÌôÝKãÏ„-tí*îÎô_¦¡®Ûh1¨¢)u4±Ç‡Þ£ib°¸ ’EißøãÂ~&ñ¡à9µYâÖf‚X^Þ¹²˜¡@_ɹM„8V1>åê#5Ãx÷à'ˆüC=ûè1Ótu¾ñ%‡ˆç]KC’ôï³{y!‰J]Ã…/n»‰É!°6‘š‹Dý›.tïŒö~>¼ñ•ü¶÷wÛ?±öÞI$ö¢ˆÝ4îEºZ8•ÜYÏÍB×âÛþýnSÑi¿üò±êš/€ü=áÿ躖‘jš^‹å> SÎû; !dV|·™ËeÉ,KI$šó¨ÿhèÅ¿ \øfúßN‡^]wí04R^›(ïù!¼Ð¾\€oÛ€G8®÷ᮑâM Àú]—‹õÄñ‰Q]ïµáH£wwgØŠª£b©* T¾bkœð¯ÀŸøkÆþ6ñsZi÷¾"ñ&¢oST}>1we³·¶ònX¯î ðT~ðŒw)¹^ë_óÐ-¥†ÁûF|:¿ðÊx‚ xÝhRùe/¢Óî^©uu">Wj±Ü8äŠn¿ñûáì:…Æ€Þ7‡LÕ A„ö©¼Ç˜>Ð6»Fñòy°äì ãW+â¿Ù…õÿ…¾ðm¿ˆm/ i‹¥±Õ4¶Ú^(µû?šÖÞr*ýô,ο…«…±ý–uÛiþ·½¹†TÔo¯&´·G¸ºþÈM9Œ2-Ã8R±£yMn»[y2â:jÝ?¯ëð—ò=~?‹ð_ÚßWøƒu¬û*ù7Vñ;Æg‰æ‹b[Û£6øãwèØT$ã½KÔ¬µÝ:ÓR°ž+Ë+˜–X."!•цAЊùÒãöBÔµ µÖu?è:׉-ç´’Ìê~3éiSYùrZ½ÒŽfmÂe!À#åÊW®ø_ÁÞ!ð÷‰tµ]_O·ð† ­‚èzfœ–ÑKze®@&Ò4‘«‘û×ÝÊ©5Õ¯»Òßç§üyÿ[ÿL§ñwâÌŸ î¼-gkởj:ýäö–Öö÷0Ûì0ÚÍrîÏ+*²ïÔÔ~øýàïÛxdÛÝIo¨ø‚Æ;Í:ÊîÙâ2y‘³¬^i_,9 ß.ìœqšwÅßÚÆG â8­¯ô öâò].îÕgŽóͳžØ)Éù ™Ä°H(1ƒÈó}?öF½‡Å^ÕµÛëCÔl¯¢¸¼Ñê-U£ŠÝ.LäEB»‚ǹÜ-ó©…ÜšžŠë_.£žŠñÞÏïèwV|+↖ÚÿŒ´ÈôKIu7²:V£_?Û-îhE‡Ì0x|Å)’6nãnFîñ‹ÃšßŠô]M¼ŽøêÚdº´HÛc0#*’2î[Tƒ¸ ó½wö`¹Ö4Èí½¢Ý®“â õý=_ÃÆò wfY⼈ܨ¹R.$(È`d![v„|I‰|)sˆü1aáýL¸ÓgÑ4ß Éj“-Ã)¹0²Þíƒ;Á±öä–2K^]µÿíù-í?뮟%ÿísðÙcÓ%Óµí»{«ë{I$³‚Cä$É+E>ÖPÒFÞKhÃnÈ##šõo ø‡Lñnƒ§kš-ÜZ†•ÜZÝC÷d†AÇÐò;×Íßg/iÚΑ¨x–úK;? Ç¥éú=¬ö6ñÏ%­ŒW'›äÜÌ…™fRd »ŠœCàúŸÃï…ž!ø{'„ô«? |-¤[_}²ÐZ¢Éq4ÆH‰Èb‹wû®2q‘н-æ-yšèŒ¯ÝøWöfÒ'ñ¦—©jÚ–¿o§™5-n[™$vg1£\ßL”³»•c“]k|`ÐtÛ­ LÖæþÈñ&­j·I£®n¥ m Ïd »€ä…'8<Ñø‹áÍcÅ^“OÑ/ô{ ™|ïhçT´–?âG€M 9õ1ï^kà/ÙÏTøY£]x_Ŷ°¥Å¤ëQj1ž;¸#º¹¹ŒZž?²l{Û”U>rˆÌk‚cÜÑ®ßÖßæºþµÿ#KÀ´ß:6Ÿ§I=°»ÖcPþÕ`Üͽf`¬) Å´Ü‚W1‘œàWAuñëáýŽ·ý'‰­ýn £Äˆì°ÈËÄŽ¬cÊ  pkÌµßØÚÇ_Ðt._Ý[¦•¤Zi =µ I!½[‡`wü¾bˆŽpœž•ûZxKT°¾Óµj²É vú»ø£Ã ©=ÂÇs4ñ½³yéöiÚIa*± ©Ýj×WîþîŸ×˜Jêöþ»ÿ^G¬Xücðõõ§‹®å’Hl<7~4ÛÉD#ù›#b<¥Rã™û¼õéÍoø/ƺ/Ä/ Úkþ¾MKGºÜ ºUö±FÀ` ¤tí^MyðCâ%݇Ę#ø•¤éÓx¾á'ŠîÃÃSÅ5†Ñ L¡ùÞÞ&L®ÆûÔ¡+³Ñ<âí¼eˆ4«MDI×U´Ò4³k úy&;hcŽI&hQ o$JX˜Ôtf-µòûúƒßO?øï‹ÿì¾øçÄwö’_D—Öio‰yg!|’‘¦és¹ £$œ åfñ?‡¯¼oðßW×´k›/j¢æÓLµ“T3ÛÚ¡‰äycÛ;²G€ê ›X€vîßøçFÕ|Aá‹Ë ÿNÓ¯æÚm[M:…©]ÀºI–"êË•áÔŒçØÉîù‹œHï¯õýkùyŽ[hvV?þéíâ+«MsN³ky¦›T–;gˆË42‹IƒÎu’5‹åÜrª=*Ô?´?ÃÙôÛB?ÆÖ7—RØÇsöYü´ž'T’9f"*ìïÛ‚qØ×žx¯öc–ÛÃÐO¥ê÷wÚ¦y©êºl0ÙÄÌn®µ_íò²O:ÆøB¥Óz‚CFHÇ%ìâ?ø=ÏŠ3jãþ›DþÊk•»iDUky|™ÕIP¤ƒi “š©{ñ«á„ÖÖ®u[…¸¾žßIv²’K…»Ž'ó’8ü³$r,bMÃh;IìyòÍöRñˆ4û´ñG‰`³ŠË[×õ?YÚiážÎKÍJiãšâ_8‹…òÙD"¾c†f!Jú„>K¡xƒFñ§âõ=~zûÄ:”ÖúÙíî®.,þǶŒ®aD‰c’„–˲Öëþ§ŸAyù†‡ñ{Â%ñD¾Óu¸nuˆÃÿ£ùn¡Šcz«²…v\ʤ²ó0k¯eWe =Íx¯‚ÿgwøyâýcVѦð̶³Ïb÷Q«ÁutÌï¿QÑowùD¶íR탻Óü ¥ë:'ƒô‹ëÄìÈ—º™…"ûDØù˜"*¨èMlŸQõg˜è¼4ÚïÄF]AðëL5¿Ëqlµ° L°#ö…k:ò«Çg¨½øùà-u[t-‡žð4ßc¼™C7˜yˆ`w89ÅygÇoÙ«Å`ñv­µ¢Üê’hz®Ÿ¢[Øh‚ÆíÚîÕ XïnÚáÅÄHr Ž!½Q‰;p]ãÙTñĽƯã=6ûYÖÖê-JK¯¬TKpG5µ«]ÄQÄË#J2ïò`€"òÚÝ?ëúc²¿•ÿÕ¯~6xcKÖ|Ui{|––~ÒSYÔïä'ˆ܇møÆYB!mËzu­ÿøÛBñÕ¥Õ·z—ÑZÜ'6¢”(l2¸2qÈ Šñ¯þÍ>&ñ4>+Ó.|s¥§‡µß hü=/Ú ‡È’5›Î7¥YÃÈÎG–Pƒó×o}ðÇÄ:櫨øwÄãK“Z×l5 AÚÕ–ÎÑ%·MÁ2ˆÂî•ÄZ´”¬¶ïóÿ-LÓ“Iµý[üô;¿jÚV‰ww¦io­_Ä›¡Óâš8Zvþèw!WêMy?ÿi}7[ð;x£Å:ç‚tƒ{qcn×2%÷›-¼óC?ü{y›ù›ŒkÚM|÷®þÉÏ©ü=Ñü/‰­],/u‹§þÖÑþÙk0¿žyI6þz6/´b7f` î(sŒœ“Ñ\Ù(µ«±ÜÝü^ð>ãÝBd²·¼]FóZØkO5VßÒ&ë’ARUKœà·;+øÅàÿ_Mg¬k ÜEs,0ÛË;G*£°j–‚a“ÿ<ÛÒ¼ÎoÙ«ÄW7övóx×KZøGþ쇇ä~IŽÓùÿlÙæy°«ŒC€§iõÍÚþÃÑéZ$Övž0[ù¥šÿÛúOÛ­¤…-'ÖHDɽÍÍÝåÒ»6æc´–Ÿ»üõ¥™ ¥úï÷/øcÚ´ßÞÖ³¤|`¶ðSxí ¸´–ýuÓªY¤"Î)!ŽiŠóS:|¤dóŽ”ý#ãÿÂ3H€iz테ןg··´²–?:yRYÁŽ%Œ±ÌáÔÛXäÖߊ>Zø³Ç‰âËÙÜørÿòؤx/Ô°;H$ÏDÆÓùÏ<ÃoÙ{þ9ü$_PðèÑKi&‡á…Ónn ŠÆêÎ4»”Nþl€]oÞª‹•8Œnã(ÞÞ÷õ«ý,ËŸ^_ëOóº;û_Ž~¾Õ´}6ßÄ–³ÝêñC5˜]’E˜.j³àíV ž€f±õ¿ÚSÀÚoƒ|Gâ;=Pê–z˜\40J‘ù‘Hñ<~k @DˆÊNp¸É s\g¿d{o‡þ$Ò5ïêCöW¿moà uzÒÛ»´rZ\yëöcó¼’à®T©5Ðøƒà.­sðXøk¡ø¦ÏLmZMH\ê·ÚCÝbˉæ‘R$¸‹<ý¡Ë‘òä©Î;ÛO?øVëåÿÛñ‡Ç;Âß|/à´ËÝKYÖÑçg‰vCiõ‘ݸnxÚ¤Ÿ\VG„?iÏ ø­¼cwö=FÃ@ðæ¥ý–uI­¤µÌ yp*™@Âå”gôÁ®²ÏÀº¤þ)ð׈µ­nÚïSÒ¬.lçK ¶·¸iYõFšCŸ>£¥r$ýžåÖt-bÊCæ_ø¼IåjZs]Y>åUû5Ä 4fhþ\ýõç-hõìþû¤¿ ²à~Nÿ‘êžñâ½ËXÒ/#¿Ó/#ÁsʺžþÞ„A5¡^Ið¿à÷ˆ~iÞðöŸâ¨¤ð¾ƒoý£o„p¶¥4Ò„ÃyQÇæHpŒ9T#"½n›µô{jQE!žEñþGýþ»\é²î¡©¾#ÿÈÿ¡ÿ×ký6]Ô5‹Ü£Î¿gOù¾ ÿØù©ÿ(kçø*Ïü›]ýŒ¿ú*zúötÿ‘âýšŸò†¾xÿ‚¬ÿɵØÿØÁkÿ¢§ª[ƒ?"h¢ŠÐ“ö þ ]ÿ&´ÿö0^è¸k×~$ø_JñÇiÚÆ—o¬Z6¯8µº‹ÌRâ°qëÏý+È¿à•ßòkOÿcçþ‹†½‹âÄ áoÇïx§Ä×ßÙÚ&›¢k2ÜÜyO)Q¶D˜’@I"°©dã{\ÒÍ4sZ^¥ãO„¿¾ hÞ—Kð•¨øJÓQ¾¼¾_%oµƒº´W±¹g%w3"˜esÒA´×mªübø‡c«xèËyªKáË4¼O _Yið[Ë©Ê$‰nwÉ$¬IdÍ"£˜Iš0ÌVC =bûö ð&†ZyuÕ¼ñôý-|;¨5ûG ì–Y-D>lQ©#/"ªàƒœ×=ª~Ü¿tmO]°ºñ\«>Œ. Ã&—vñÊmÝRqˆŠÎѳ€Â"Åy'€kw½ý¯‘’k§—õó<–ÃãĘü1áë½[ij¸µ×µ>kmÚ¶¥¯Ä†ÔÛµ¼—tpΫæÊ¬bãc#|¤?Öz?Ž´­wÅúÿ†­vÕ48­e¾ ,iö…vC‘µ›ld•• ¹Æá^M©þÜŸ4m"ÇQ¾ñ%í´WSÝÀÐI¢Þ‹‹Fµd[ƒs“¾ÝPËZUQójÞ«û_|,ðö¥â˜ïW˜h>µ¨iÞÔ.m-p²«Ks ÌEH%¹Å6ôþ»%ùëóßêÿå¡Cö­øe¡xÊê¾¶ÖuüY£Z<ïoæ:ÙµêyÈØÿ–eIÜÊA9¯4‡[ñ§ÁùÕ|G®Þ-†¥Û=ÝÝË)ah2Ç ' ž‚³K‘K]ïø¨ÿ•þf—Rk¯ü;ÿ†ù!7ÅßOàM%ü]â¯:ëNñþ“o ð¤7pêvBæÑçw”éöÁÖi͆@)÷˜O¢kÞ%µømãÏ‹š¶“cx÷ú·†`Ö´Û}&5óõ)bŠmf?¼¤tÊ‘Åv“~ÔÞ·ðíÞ·0ñ$66W/iz$𾤲Ù:IJ±ž#øTFÊÛÜÁëWõŸÚ?Àš­­XÝê7Ût[Ôµ-B *ê[Kw§I$ºHÌ@4hÄ|üð: kFïoÿfߥÉO£×þ¯ÿùóÂß~/xž+Ý1¼ay zqÔdMkJµµÔ>ݲÂ9¢_>M:Þ)LXf;tÏ+¹ˆÝZ>ñ¯Œ$ÕoíîQY“ÂÐX"Z[Z>‹¿i2óIiå™y!O—`@ÊXúNŸû`øE§Öÿµlu­%,¯…­«h÷Òj7[%Ä’=ˆ·¨® ,¸Á WKkûLü=½¿¹¶‹Y¸x Mï¨ÿg\ý…‡Ø£¾n|¿)‰¶•% ’àÕ])_ÉþÖ¤ï__ëåýhv>ñÖ•ñ+ÂÖ¾"ÐÞit»©&Ž'¡gò¦x™‚°ihÉVèÊC¯Œ>8[k7ÿ|1fšƒkòøá¼Eoi›'L²} ÿ–^lr'ï« f¾Éøuãm#ÇÞƒTЭ5-/ˆàRÒn4Ö+µJ”ŠxÑŠà Óηï亊Æá좆âñcc W˜£wÇœ+õ![‡¥g(]©>ŸæŸèkÙ4ºÿ_©ówÁ?Cð‡Âž(Ÿâ'Ûæñ­½Æœšž§ ¬Ó&¥ÀéæÒ0¤¬K–‡Ê)$r–,[{{ÅK ½Sá§Š¬ìc’[Ùô»˜áHs½œÆÁBãœæ¸ý?ãÆ–ßô/x«F»³ŽöVW³Ñ¬®µ¡o,nãp1[‡Ø<¢ÞcF€qœ–ßöžøws«‹õ‹­»ã‹íí¦]-Žù-â'ÚŒ~V怆 ¿$ü¿{ŠºŸ¼RFp÷,|¯mcâë%ñ׈l¬t-6×öBÛÅ7W:N«}oa~“ÙNˆÊÊèÓFáþm²Æ™G -tžñg‹õ?^ ø„þ×tiãOðÄ1ÜFÖv–÷HË"ùLé;âêm=„žFq¶â˜`=Dý°<#«Ýêîö:ݾ™oqag§8ѯžûRšêfUŽËìâm¢8YÀÊÊ d]êüeðäž1¶ð¼#W¹Ö%†)åŽßE¼–;!*–Œ]J±¶f²•>ÕZ©9wwÿ?½~Š~ò·—áÓñ_y±à¿é^?±¿¼Òy-¬¯çÓdyíÞ ÓBû$Ù¸ ʸd+濈qß7ÆÝc@F¿SÕüWáNÂ(ƒþòÎÙÃ]J‡v FÝž:kÔí?j/‡qA0n §ÔOJÔõ¦’)gR-¼!FHfo3nß”óš»aûOü:Õ5½K³Ö繟Tû8†h´ë–·ŠIÙ’§˜GåÁ+º2åemÀ®3ÅM®âý?Gú}Åó[™züº%aâßøᦿ¥ÛxÛ凉WÆ7öSÞj²ØZ*»¹’e—û2p‘ÍŒÜH3"„¯Lï†*ø‘ªëÚޝ5NÒÿP±ðͦ§¥¦žŸd¾Ý{¨Á3¸’$gË 'îÄX$P¤ ûOšãï>+h_áðNu+}íÒêD³Òîg‚Ú'.§#1BÆøÞ˧-SÝ5ø-WÌ›|]ÿu÷ü!ã­'Ç/¯ %ç‘t]RméåãSq¡FXê íܹ•†r¦¼ ã?†uI><ÙèV0_M¤|A¶°{É!.!·}.奘3§·W¶~Ì9¯B¶ý¥þCáû^ÚmPi v¶ö÷0x~÷ËÔ§–B²"ôÂϸæ ùäô楱ý¨>jW–6öÚ­ì¿k‚ÚàÌ4›¿&Ùn.'¶‹íy[mÉšÖxÈ”©VB &¾}Wçoéµfž¼?ñ“âÕæu®xÊÓKî,“ZO.o¼2ñRfHäÓ¢H‘c2!›¶+†*­º½§í ñ2ãMðm톳¨¾èZg¼†Þµ¸¤Ôåƒ1ÚǧÉ#´pÆ …n-U£|Ù"½×Yý£þxÞ#mNþîëDÓ-¡r&Ò¯c6Ë0϶ýØ71‰6©xw€Yyù†wt¿¾ðîse zŽƒo¤[ZÉý™u¡^ZN"žá­ ò x•äÝ*ÂrÊOßRj6M_¿ßý[ó¶zÛôþ¿Èâþü_Ô4ÍgâsøÇĺöáèä¿“R³KgÓ-`I&ýÄk¼S¤êˆ7Ç+MœŽrkÝômRßÄzŽ¥L–·öÑÜF—4Ru £ÊØ<©ƒÁ«wñÝC$3Æ“C *ñÈ¡•ê=E>Ž–cësáé$ñß‚í¼Zt(o-æø{/öž¡yælŽÒûQŠy äY•Pæ)ByeŠ8Nä>,ÿaOªÃã3«Ã¥i'QƒûÆ »}QÅú ŠyÚÊíåïV0GÁ@ “ö.hÍ÷Vºÿ_ç¨=[gÊú—ÄíWKñ'ÇH¼+®I«ë6¯`me—OŠY,£n™÷¯Óìü>¾9K¿Z¿ü(¨ê?Øp\Å!Ó–èÅj#r˜ÿRX^yY“·’µöÝ¡ÿÍuéývéØkàQ}:ÿ_s–ð÷Ž´=KÄ×>ÓMÁ½Ó4ëkÙÛÈ"Žw‡˜F7„íÎà9#šðÚ§]ñ¿€¾#x[Äž ŠòVm*õµ?³Úý¥ZÎÏmä… $ʆ nËü¼Šúu Ž9d‘cE’LouP c¦O|Sêf¹º÷ýJZiÐø·Á¾)ø³ðÿÂv¿ô´]êÞðl%Šk‹$˜Üìá°#gûr<„ä9W ž ¨®>%|RÖ5seៈZö©áXn­ÖÓÄãA°ûF dXEÌ. ¨l ùVHÐåʱ,“ö—ám#EÕµ]RÇN‚×QÕ]$¾º1%Ã"íMÍÔàpn}kS5rwm÷ÿ?òÓÎ×êf¢ÒK·üÖÿ},¾.k§]KÇñ÷/Ÿá|—&Ò]:lõmH‰XCn“-!‰Ù‡ËòªŠg‹>'üIð‚\éÚ¯Ž5m;F·’Òæo¶fnQ¥Ò¦˜Z„û9„F×P ÉŒ¸ó6o«±³Xþ'ð†ã;(ìõ»õXä¬R“·vÏg‚xjÊùãþ ³ÿ&×cÿc¯þŠž¾‡ý?äFøƒÿcæ§ü¡¯ž?à«?òmv?ö0Zÿè©ê–àÏÈš(¢´$ý‚ÿ‚WÉ­?ýŒŸú.ö_xVü~ð6ƒsvÖ6÷ú¹— 3lVŽNÉ‘ãaŽÌ¤WÁ+¿äÖŸþÆ Ïý wÿ´O„uxëKÐô‰õ5[Ïøš+A¦J"žY¬a# Aᘅ?^¢±Ÿ™pÝXõÏþǾð|^OxßÄš&· ­ø‡Q´¸¶2ÝZÝÌ“OnÑ´MÂ#Ø#UÙƒÉÎ ±‡Ã+ÝoƾÓ¼Sw ¼/}¢Y®žn´ÿ¶JÒ3yãc¼r”Y¯Þó¾§àïˆÖúÃx&‰vÞ ðßÃéíÞ}CD¹[Ã~·ví=Öh4Xm|Á«×yãßøþÓÅ¿í<cñ$_jÖZ`ðöªÞ»SÔSÏöØà¹6€U yaÙ”î>Y95´ï­®ëåþNÉÿÃÜç‹N/Nß§å»Òǰk?°Ÿ‚õOO¯Ã¬ê¶šÍÆ©©jRÜÉmcv^¼/,;.-äPªÐ!Fzå¾cší/~¯†|ñBÇÂñÛëz—g{ɬ¼EsäÙ ZÒR›¡…™cÙœmc’z câ_>6ü5ðÖµ©â_ˆ:f™¤Üø– T¶²æöXç² zí ¯—-ÆÙ@U-»Ÿ~ø=®|Lƒã׋lµÛŸxÃwZUÍÄ7ói—6š[*AåÁKŠæF&M’C+óoEã —ž-t·é{~ÕËME§Öÿð/øÿV=Cá'ìà~üøyàK/êzLþº·Ô/¯4WTþÔ•Yžhfó‹A#9 1 £"½⟂¡øðçÄžž!2j–2Û7ßæ*vŸ0#”Ã`îØØÆvž•Ÿð:òæÿá'…î/ÄÒ]IhFñ•ªZêÄî?ñó¨þÀtÅxZx›â{üyÔâ·‡Åú,ãW¶šÆm2êK;uŽÛuœñ\²KI"ü«b2C)Ô|ÎWópà”R·‘¥§~ÈSx¯DÔæø‡â)'ñ¯qxn%³6÷‘¬wÅ3Z¢ @„‘!—,çÔ&ýŸü7wáèSßÜéÞ%Òíô›ÅiT2E ¿Œ„(Ãí䓞GAÒ¼kÄüAmð«àψ5ís⧨Ù_麇ˆÌOq{=Œ‘ÊÆÖZC¶g]Ȩvîb@‘ô>‘ãËMSÇ:—…-쵟L°·½ŸP– ¶ÿ½,-Äîóp…Š•}*­î¸t½­è¿à±^ÒOÊ÷õðày–£û+hÚŽ­6¯}âF÷Åwwxu[ë; † À´k‚í rsÉÓÁðGµ¾’öSPK¦Õ®lìè¬0#òöìòáVÛŒn'øp£Ïÿj›+Øümð÷W·‡Æ ¾®àÍ.kÛ˜%’Ý*Â(¤*®Ã#$ šÃðÇŒ~'Ùx“LÒ|cŠR÷íð_jÒiz=ÄÖ1ZÛÎH§Š&FÅúÝb4f“qa—9§woOÏþÙoM}¯Ñ}Ç¢è?­¼áI´}Ç7Ú\º®»§u{‚#'•å£Û[ÅH¡WX°Eê\I¯d’hãdê…ÎÕ q¸ú ùÃV‡Xøáû«ß x†ûQð§fÕö·„®£Ô’Ðê÷¤ðÂÖÉ$²5»ÆÌaBçsnù‹ Ÿ_ÿ„Ÿ[ý týCY¶ñ•Õ•—‰Åî›o‹rÚ]®ý‘òϸBBÜ}¥§R…¼Ðp¦0¥I#.f¢Õ®×éý|Ÿ˜¤”n×Dßçý|ÑéZ—칡kþÓti|E©\éÚN¥u{¦Ç,“Çj&Ic’ ,|×*Òu a¸«V²¿…,¼1o 5î©s§C¨ÚjEf’=Îöö)fˆHAò˜Ð1Æî„+Éüsâ¯x+Áº6ŒÞ=Ñ!ƒÄúëj·hwZ]Ô¶¥5›ÈÓ[F3 b\/ßdó6f“ã‰qxßÀñx‹Tñž—®jZÅ”Ít©•&›ý“$’3·•°Ü}¦9 E¼Kò&ZˆYË—kòþ–þ¾b›åNO¢—ü¼ö/øeË&е:_ê÷­ªýŠ9§¾´±œ¤6±4QG´Tá³æ¿r‚sÝ+à%—‡¯AÒ+±ñ‡ˆ—N¿¶µµ½¿±¹·½Öe˜Åöw‘A$?½‘WaÊN×#§Ñò§˜Ž›™w7)ÁâªZÞúßü/ÛþÉšgƒµO ÍáOɤ\éz¡º»e³Šh¡‚ÆòÞ%Ž4ƒd“;\®ó(%—qÎ@»ð‡ì³á¯ø‹KÕt+ë›cl±¸îlí.^úTw9å’’7f•ÙŒLƒ'€+ÉÀ„Ñ>|A›þ½KZ×[Å_Û êV u¨Ü%½ôn'‹ %%fÝÌݨ§ñ#QøãˆÓ[xcRñ¦ˆºÇØCxt™àÓ °‘_OtÒÈn#eŽb’n…Fɡ˕F[½Þ—õò¸’¼¤ž>æÿ¯™ôOü/¨ø^ßXŸˆ.¼C>¡ª\ê÷*m"‘¿wmäá#@£“Ënn7``x»àÍŒþ!è>*½Õ.ámÒX,í ‚=Î¥¾ôâ?8¡ÝÌ{ö:×Ì·ž=øùãÛ 'XÕt¯øHŽÚÎMRÛMÒ.nn„3ç$C™ždx[zÄ "Ì„¯S^±àMÆšÿ‹üº·‹]¼¾äÿËæ;Ý?5ù›³~ÌUσ­,Òí¼I.¥uãû)/®þÂחךB5¡˜Æ4Ñì¨T °Qk3F¾ø·ªÁ«øî|ko-•¾›q¦é“ؼI;>µ|³¬‘·1‹o¹x*…ã9¡>~Gèý4¿ëù„½Å/[zô>Ÿð—†5ê#ºÔ5û­kûWP7vðL»c°‡b"ÁÉàm,Ovrp:WG_ ÍyñOÂÕ5‰u¯K-¦…7ˆ$ÞØ¡k›MSzÙodUg¶ ä«+™>ÅðçÇÚŽ•¦øOñ:Æ¥âÉy©*ù*WI·òÚáR~Ax |ÙwȺþ½?G÷\rÒVþ»þ¨õÊ+Ìh+OjÒìü5y¬é÷WÍœW7:ÿIŽØ¹óNv¶ÕÇVÇó&›«|oµÐ­£½¹ñìšßØí[AQ¦Hñ]jrAe$Ñê,!ÛºÉ,ë™Lhª²(bÉŠQ|Í®ßðá->颾I¾¹ø­£Gu¨Áuã¨æÕ5yî¡k7›É³·ñîÄ[²ö*ÁUw4¨FÀI¹j?Ô¤gTf 3Œ“Šù‹Y»øœ~>k‘s[ÓáK¨Îƒ¥AáÛ»&öËìi‘-â³Ã!ŸÎÊÊëµp¤2ç[ѵ_üI'Ô>(\ø‡JÖtmC[‚ãO¼¶¸Y"»‰®ÖÖ?³ƒq(‘À·)(›Kt-;®oëú]{Ý¿¯ëåÜúòŠùí5ß[~ÐÞŽÊãÆ÷‡o­¢Cg>™}ci¦ÅöYY®.&’ØA;3„6’9Q˜|§iëÞñݯÄ="óR²±¾²µ‚þâÁú5C9†CKæ2Á°N ÁàUÿOÄ騢ŠC (¢€ (¢€ (¢€<‹â?üúýv¸ÿÓeÝCS|Gÿ‘ÿCÿ®×úl»¨k¹G~Οò#|Aÿ±óSþP×ÏðUŸù6»û-ôTõô?ìéÿ"7Äû5?å |ñÿYÿ“k±ÿ±‚×ÿEOT·~DÑE¡'ìü»þMiÿì`¼ÿÑp×®|Oñ…ÇÃï~ñ-®•>µ>“áŸÞ­»¢4¾\>2ì —žsè â¼þ ]ÿ&´ÿö0^è¸kݵÍÏÄŸ´§Ãý#P‹Ï°¿ÐuÛ[ˆ²FøÞ(U—#‘H¬¥{è\m{c·ñ_íá/‡z†‹¬o´[ZÓÿ´ÛLžæÄKklÊÙ¹@YÆ#$¤gäàâÇÿi3¦x?ź熼-ªëZíhº´ÑÆ–7wΑM CÍó™•™ÓqŒ!te pkx|³Š- Kx¢ÓTÒmšÁuh.`[››BÊÂÞoÜìeW \cïrrû¯€ÓëÖçUÖ£Ðõ›‡½ŸAŽåœw/"Ë$ñƒ˜¬ò)r7•ÜîB‚ÄÖîÍýÿžŸ‡ãäcd•ü¯úþ?‡™Âx»ãoßêšEψþ_ë:Ö‹ý§v£¤ØÜ\hFÊ[D¹“{ÊBô»gbËÏQŠèîhÛ jký7Ãö7VדG‰¬êöãû/S¹´]ÓÅŽO7åÏ̈Få m5£¬| ðCk…ÕõÌö÷šúêVl’^*y¦ûì­:Æå±a P3€®xŸBýžü/ øŸû^9u¨b[Ÿ±i7W¬ì$¹P·2¡Cg%™€ÞáB† æ®ãgÛñ4ÚWóü:òþÒZ'„¼}©èšž©¬kZ ø‚êËA…%v‘,Fâá¼Ù1£O…]Ò6ï•.¿kŸ Cq;[è~$Ôt¡m}uk¬YÙÄö·ËgžàCûÐä„aÈ¡ÎB“ƒ¿Ù“Ã׺&“¦¾»â$]6ÞçNŠæ+¸’gÓ§(e°vsò¢ÁÀldçÓöm¾Ñ>$\øH¾¶µÒ´û[åм?$ÎÖQ\\‘3º ʆn¿.ÎsWÞþvý?OúX”šKåëïù[©ë^ñþ—ã«e4ƒ-Ŷ—r¶¯{…ò'v‰$ýÓw².N'Œ×I^áÿ…^øYà?†? åñšøz{-NË[huk>µ<%¥6è÷Éí¹ŒnÌhñ^¹¤ø¿Bñ©ªéº^µ§jZŽ•"ŨYÚ]Ç,ÖnÃ*³"’c$r‘OÓúØI÷5¨¢ŠEQ@b§‚|;ŠŸÄé ikâY!û;ë+e¼h¿¸fÛ¼¯Œâ¶¨ Š( Š( Š( Š( Š(  ýwÃÚWŠtæÓõ­2ÏW°i#”ÚßÛ¤ñGµVU`qÁŽEhfŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¬­sš'‰¥Ó¥Ö4m?V—N¸–O}j“5¬à%ˆ°;@eÁäóZ´PEPEPEPEPEPEPüN¸ŠÓÇDóÈ×.òHÁUi—„’OÞ±?á3ðÿýtÏü üiŸ´.‰¦xXÒ´ígJÓõ­6káæØê–‘Ý[ɶÒá—tR++a€ap@#+ÊÿáL|4ÿ¢_à/ü$´ïþ1X=Ê:ÙÂE›À^>‘…¤økáµ½†‰£éºž—,ëe¤ØÅg±o™„q*¨'¹ÆM|{ÿYÿ“k±ÿ±‚×ÿEOT·ò&Š(­I?`¿à•ßòkOÿcçþ‹†»ÚsÞ*ñoÄoé^ ¸Õ-|Cq¥êB ´kö±ºEZ™ L¬¥NÀÝùéÎq\ü»þMiÿì`¼ÿÑp×Ñ)grÿµËԶžKK]'WóçŽ&d‹r÷q ’êx“W’CÄüQð«ö‹nì4ëÏ\ZÛêšý§…åµñS«YnÔb“NºÔ$’b÷vâÜH¡f22¬¼ŒuZ·ƒþ7XYü]FÓ|e¯xæòöòM#W_Mo¡ÿfHÐùZZÃs—4q†è±È\1ópõö‡ö½¯÷ßþý7øQý¯ký÷ÿ¿Mþ­ô·•¿¯?øbm÷ßúþ·Ôüý²øñGXðÇ‚õ?éÞ:ñ<¾ø‘uq1xŠêÛP]KFXåŒ}½Yfà´í2¦äß´•¨þx«Æz—í’ž»ñŒµ[í>OϯZÃâyn4ï³tÔŽÙf)nѬ›?x€™ì±Ðoí{_ï¿ýúo𤵢“†až¸‰¹ý*ã>W¶–kïI_åkúÜ%ê·ºü­¾ã•ø%a}¦|(ðÍ®¥m¯ÙßGjÐx§Q]CRFÜx¸¸RDîLÕà^2øYñMÇ‹¯4CÅq꺼ž&·Œ·‰nLÃ%™þÎ0Dgòà"uM«¯<€Æ¾¨þ×µþûÿߦÿ ?µí¾ÿ÷é¿Â³—½2Öš;jzWõ¥—Ä×>×åµ³ñÍŽ±k£ÝN’]-‚[œÅ”ªaݘ #8cŒž}'D±Õt¿Žþ"¾ŸH¼m'[Ò¬üEax<ÝñÉónV>`ÆžkÐ?µí¾ÿ÷é¿Âí{_ï¿ýúoð§}þ¶Kô!Æûú}ÒæýLo‡,¼ñׂ´ÍzûA½ðÍÅò¼ƒLÔp."{Ë÷K WÚy]Ø EtµOû^×ûïÿ~›ü(þ×µþûÿߦÿ .QTÿµí¾ÿ÷é¿Âí{_ï¿ýúoð  ”U?í{_ï¿ýúoð£û^×ûïÿ~›ü(åOû^×ûïÿ~›ü(þ×µþûÿߦÿ ¹ESþ×µþûÿߦÿ ?µí¾ÿ÷é¿Â€.QTÿµí¾ÿ÷é¿Âí{_ï¿ýúoð  ”U?í{_ï¿ýúoð£û^×ûïÿ~›ü(åOû^×ûïÿ~›ü(þ×µþûÿߦÿ ¹ESþ×µþûÿߦÿ ?µí¾ÿ÷é¿Â€.QTÿµí¾ÿ÷é¿Âí{_ï¿ýúoð  ”U?í{_ï¿ýúoð£û^×ûïÿ~›ü(åOû^×ûïÿ~›ü(þ×µþûÿߦÿ ¹ESþ×µþûÿߦÿ ?µí¾ÿ÷é¿Â€.QTÿµí¾ÿ÷é¿Âí{_ï¿ýúoð  ”U?í{_ï¿ýúoð£û^×ûïÿ~›ü(åOû^×ûïÿ~›ü(þ×µþûÿߦÿ ¹ESþ×µþûÿߦÿ ?µí¾ÿ÷é¿Â€.QTÿµí¾ÿ÷é¿Âí{_ï¿ýúoð  ”U?í{_ï¿ýúoð£û^×ûïÿ~›ü(åOû^×ûïÿ~›ü(þ×µþûÿߦÿ ¹ESþ×µþûÿߦÿ ?µí¾ÿ÷é¿Â€.QTÿµí¾ÿ÷é¿Âí{_ï¿ýúoð  ”U?í{_ï¿ýúoð£û^×ûïÿ~›ü(Ë~$"¿ô-È’¸™‚È×#M» AȯÑ?iïëÿføWoámm-[x†}B[à x†öÍÝã²{”³ﵚßýd¸Q´Ì÷Ú­€Nó„Ô¾2Gs%Ê|ÓVêXÄ/r¾&³¼`–_* $.q’MdQà6­}¬ø7DzßÞMy$^7Ô-âó[å†$XBGŒ* ç   ’q’Iù·þ ³ÿ&×cÿc¯þŠž¾Ÿø)àx#áÖ¾dÑÅ·Íe\òÌLžÛ…|gÿ[bß³m“1,ÇĤ’rOŽâgäMQZ’~ÁÁ+¿äÖŸþÆ Ïý }_ÿÁ+¿äÖŸþÆ Ïý }YKrQE (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€-Û€Ún ÈÛ_úèµæ¾.øÙá/xô³©ê:ÄVÂòâÏCÑ®õ)-a' $ÂÞ'ò”àà¾3ƒŽ†½.ÛþAº‡û±ÿèůÒ5cà§Ä¿‰Ww~ñ7ˆ4ÏßÚjú~¯á]&]I·Ei³ÙÜ, ¼%Laãg2%o˜"š³vÓíúü­Ô–ÚÙ_ÖŸ;ô=VÃŦ– o¨Ù»_³ÛDdU’Ta•!ÍúU‘¬im|¶BúÌÞ3[q*y„Ž .s‘_&üpð—•áH®å’XÞYnueI2DâD0G*6p¯¾º]sàÕÜ>5ÖtïÊž-¹ø¥iªØêQéÄÞ5½´ßßðé~¿2Ÿ*¾ÿðÍþšGGªé’ßÉb—–{,öË*™z•Î@®kÆÿtx:÷ÄŽN³eiqom,zKE,æž8Wï:¨ÃH Ë€q“€|Ëá¾£ÿ £ÆÞ Ó>êšOÅë›Mi?á1›Ht†õåi r&­,‰ctSÌÊž ®ÒF¿ÄÞñøSÃ>·Õ'·Ñ­¥ÑµOG£[+Q‚VÁ¹š5Y L›×`$¹éÅJi=´üERN1m.ÿ§ü9îþ µû'íaจ]ñø_\BW¾%³¯ÿ‚¬ÿɵØÿØÁkÿ¢§¯ ¼Xë'ísáV ­á­x‚Au¥|ûÿYÿ“k±ÿ±‚×ÿEOSÍùEV¤Ÿ°_ðJïù5§ÿ±‚óÿEÃ_`WÇÿðJïù5§ÿ±‚óÿEÃ_`VRܤQE@Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  xâßÀÚ óϤxƒZ{†Ž(í¼;¢]j“d8bY-ãrŠ?3`v$ ááÚÑ>ø¡ÿ„­ÿÆ+Ôh§ .ÿ…ÿiÿDûâ‡þ·ÿ£þý§ýïŠø@jßüb½FŠ4åßð¿í?èŸ|PÿÂVÿãÂÿ´ÿ¢}ñCÿ [ÿŒW¨ÑF€xŸ‡ üoøãÅGHÕŽ±ur-ÊâVòÙ" Û’6\­ÆsÅ}/ÿý›ÿè|¸ÿÁe×ÿ¯ÆŠ?òPµïúújåéY0?p?áâ?³ý—ø,ºÿã4ÃÄfÿú.?ðYuÿÆkðþŠ\¨w?p?áâ?³ý—ø,ºÿã4ÃÄfÿú.?ðYuÿÆkðþŠ9P\ýÀÿ‡ˆþÍÿô>\à²ëÿŒÑÿý›ÿè|¸ÿÁe×ÿ¯Ãú(åAs÷þ#û7ÿÐùqÿ‚˯þ3Gü\à²ëÿŒÑÿý›ÿè|¸ÿÁe×ÿ¯Ãú(åAs÷þ#û7ÿÐùqÿ‚˯þ3Gü\à²ëÿŒÑÿý›ÿè|¸ÿÁe×ÿ¯Ãú(åAs÷þ#û7ÿÐùqÿ‚˯þ3Gü\à²ëÿŒÑÿý›ÿè|¸ÿÁe×ÿ¯Ãú(åAs÷þ#û7ÿÐùqÿ‚˯þ3Gü\à²ëÿŒÑÿý›ÿè|¸ÿÁe×ÿ¯Ãú(åAs÷þ#û7ÿÐùqÿ‚˯þ3Gü\à²ëÿŒÑÿý›ÿè|¸ÿÁe×ÿ¯Ãú(åAs÷þ#û7ÿÐùqÿ‚˯þ3Gü\à²ëÿŒÑÿý›ÿè|¸ÿÁe×ÿ¯Ãú(åAs÷þ#û7ÿÐùqÿ‚˯þ3Gü 163 322 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ£B"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑ´2MOy4Û7v¶‰™šÝ $ É'lé@`§M° ÝÙÓ'ô¥Ðÿä¦ÿפ_ú©¯-#¼ˆ+GCº9ï#zóÍCý¥Ð.Çÿ“ü)HÒ;tÛ´àâÝ8?•S]Fêæàéa’;ÄÏ›:T(Ç*?¼r8=;çŒë[[Eià íE÷É'¹'¹>´VM'GŠ6’M7OD@Y™­ÐRN*–ï Ôò†®ëßòÔëÖ_ýÕøCtùðÿÈÒñT$xfæUŠÞ-Y¢"DÄ÷è*ÓèúR£7öU‰ÀÏü{'øVhðþ™¥jšdö6ÞT;!o1›*CŽIô½7ú™?Ý?Ê„OØôŸúØÿß„ÿâhû•ÿ@{ûðŸüM.hÍoÈŒ¹˜ŸcÒ¿ècÿ~ÿ‰£ìzOýìïÂñ4fŒÑȃ™‡Ù4ŸúØÿß„ÿâhû&“ÿ@{ûðŸüMW]&Y×Í’.öcŒ¿1ᇥ+é2Àžq½‘¶2œeùù€Ç,iZŸp¼ÉþɤÿÐÇþü'ÿGÙ4ŸúØÿß„ÿâjÕ‚ï.ÒÞZä:šuä%®c mó±Áìhåì;»\¦,´² -‘®-Óüvƒe¥¨è¶@™·NñÚÑX⊔™™W žŸ…0Â%kTwr¬žÜqÚ•¢e²i_ô±ÿ¿ ÿÄÑö]+þ€Ö?÷á?øš´-Â[qK³'¦)òÛÇ ÄJ„—–éNÑ È¥ö]'þ€Ö?÷á?øš>Ë¥ÐÇþü'ÿVoü‘;÷ÏÌ1øTñ'Úm vIƒô£–6½‚îö3þË¥ÐÇþü'ÿJlô°:-¦mÓŸüv´ö$RK<`1eqëþE5¢Šxí£verŸ.:~4­Ã×¹œlô°¡Ž‹e´ô?gLè4ß²é_ô±ÿ¿ ÿÄÕà„Am¹‰n6žh¸†)¯¼¨·+–ù³Œ¥;DWe²é_ô±ÿ¿ ÿÄÑöm'þ€Ö?÷á?øš¹wd°ÂdBã>9÷©, 9J:#n3tZ6º Êö3þͤÿÐÇþü'ÿ@µÒ‰ÀѬIÿ® ÿÄÕëØÃ\A•'züÍûßJ$´X^ x@ ¾3úQhƒr)5¦–¬U´[ Gcñ4ŸfÒè cÿ~ÿ‰¥Õ¯ ³½Ýr“4o&ÂbÛò–Éöš´–q5ÈQ!hš?1Xc$Qh…äTû6“ÿ@kûðŸüM'Ùô¯úXÿß„ÿâjá²I &m’’>n£Ï" nwrI!‹? |°äVû>•ÿ@kûðŸüMgÒè cÿ~ÿ‰«—v+ D.6œøçÜb¨æ…½„å$;ìúOý¬ïÂñ4}ŸIÿ 5ýøOþ&™š3Uìâ.v^ƒJÒ¦‰dþʱíötÿ ö6•ÿ@»üOð©lÿãÎ/÷‡þ…VkžZ3u±âZ’ªjwhŠVg€ãE.«ÿ!kÏúîÿú¢½¡ÿÈMÿ¯H¿ôRÞ­Ôˆ±Z‘ó‡”õEöϧoåYöwS[hZ*[Â’É<1FÈPÜ–Î@?ÝôïV¼Ý[þ|¬¿ð1ÿøÕ9ô»sf–ñ†‹Ë;£‘Oέýì÷>¹ë“ššÐÜ»T©Ád<7¸ôÏ¥Wóuoùò²ÿÀÇÿãTyº·üùYàcÿñª“V†K"öWt’À苜d• í÷?ô½ÿ¾áÿã”yº·üùYàcÿñª<Ý[þ|¬¿ð1ÿøÕE#Ý]ÞØ“§\@Ìdw‘£À[¯ð¹=Xv­ÿÔIþéþUOÍÕ¿çÊËÿÿR4š«)ScdA?éÿÆè@TÍ©|‹ÿúYàlŸün"ûþÖ_ø'ÿ­½¢2ädY£5/‘}ÿ@ë/ü “ÿÑä_Ð:Ëÿdÿãtý¢F,fV3m¤óæc©'ÓÞ‰ïhZ1]Äsæg¡ÓړȾÿ u—þÉÿÆèò/¿èeÿ²ñº‹À«HT»híŒQ‚¬[%Á¥kÆhQXèÛƒ“Mò/¿èeÿ²ñº<‹ïúYàlŸün«ž=…Ë"s|²Q £ËÃ>î>´\Üd·ò]¢\9Ùï¿èeÿ²ñº>Ï}ÿ@ë/ü “ÿÒæˆrÈ’KätØ ¥÷0ÝœÒK{º4H£òÕ[pËæ™ö{ïúYàlŸün“ì÷ßô²ÿÀÙ?øÝðY ur—p„#Ÿ¼Á³š[kÆ·ŠD マ”ß³ßÐ:Ëÿdÿãt}žûþÖ_ø'ÿ§ÏX9e{ŠoÙ}Ÿo½žÞ”õ¾Úð7—þ©q÷ºÔg¾ÿ u—þÉÿÆèû=÷ý¬¿ð6Oþ7G<;,…{ÂÑ"ÁG.iÒ_™fŽ’’sœÓ>Ï}ÿ@ë/ü “ÿÑö{ïúYàlŸünŽxvYÅÄR¯Én#brX6sKov‘BñI˜¬s÷±Iö{ßúYàlŸün³^ÿÐ:ËÿdÿãtsÆÖ$¯qçPa4n‘ª¤`€™¤–õZ5H¡ò¾ÿ½ži¿f½ÿ u—þÉÿÆèû5ïýl¿ð6Oþ7G<;,†Kwçëo%¹ÎH†Aýi×1>1¹… šs)R™ÿ|÷ì/§Jš…¾¨’ÙËm§Ú‰#˜VåÜ £®H(8æ³îín&¸´‡UµŽòýÇó ,M– ¼/NF1Þ³m_BÒvÔÜŽü¤0Ôf2HläÒµê‰VX`XÜ“œæ£ŠÊê(Ö8ôËE^ÉÇþC§ýš÷þ¶_ø'ÿ­9áØŽI ¸¹Šeù-ÄlNKÎj¾j×Ù¯èeÿ²ñº>Í{ÿ@Û/ü “ÿÓU"ÂL«šLÕ¯²ÞÿÐ6Ëÿdÿãt}–÷þ¶_ø'ÿ§íb/fËÖ<ÙEþðÿЪÕgFÚ¤H,l‚ŽƒíÿÆéÐ^]ý½-ní Ì‰äVŠrÿt¨ ‚‹ýÿÒ°nîæËDy«ÿ!kÏúîÿú¢WþBןõÝÿô#E =BÓþAÞúGÿ¤Ï[•‡iÿ ï ý#ÿÒg­‹‰âµ·’yÜ$QÌǰ¤2J+%µ¦kYæK ¸ÂDÒ#ÍTl úä~ U›KÖžH‘’1¾Ýf$H3“Ûo\{ÓvŠÌÔ5ˆ ±ž[I žXJ†EpÛrÀrã­h$Ñ<H$xÞ¡+ž™¨ôTKunÈŽ³ÄVFØ„8Ã7 õ<ʨÞë6ö—öÐ<ð,rY]äË*ú{Ð3NŠª×‹çÛ¤f9#œ3Ž€gü_‡J‹MÕìõ+a43F]ÏpZ1þЊ_¢¢·º·»BöÓÅ2ƒ‚Ѹ`áH×–Ër-šâ;r".7íME@÷¶©r¶Ïs ÎÝ"2ÇðëKswmh¡®®"IÀ28P:C&¢«>£e—æ^[§›Ì{¥Q¿éÏ4å½´{“l·P´ëÖ! Ü?´ÄOED.­ÌK(ž#6Åm㳌ëž)u¶õ a¢Åæ2 Žq÷zãÞ–(ªcWÓ ¦ÐpOž¸Ó­K=í­´k%ÅÌ1#ýÖ’@¡¾„Ð"z*)n­áƒÏšx£‹þz;€¿0ßÙ‹o´›¸ãÍóßÏ¥X¢«]݈´Ù®á) HšE ä6zŠjj%•¼÷sÜŠF÷ #8  tTS\Áo<ÑÅ÷Ý‚¯æj7Ôlc¼·Q(Ì{¥Q¼{sÍY¢¨Í«Z[êBÊyR'hÄŠÒ8PÙ8ÀÏSÅI â´SË1Š$†FBÞh#¹=±é@¨¨òÕ­ÊÜÂ`òÔ8Ûùô¥¶º·»Bö³Å:‚ѸaŸÂ€&£ÒŠ(¢Š(¢Š(¢Š(ªÈ~Ïþ½gÿÐâ«õBoùÙÿ׬ÿúTäZ¯ü…¯?ë»ÿèFŠ5_ù ^×wÿÐêŸòðÏÒ?ý&z·¯ÙË}¤M4¿+ª“€ÅX~8ÅT´ÿw†~‘ÿé3Öå 1§¿mFÂæÖ;ئ’–ªÓÆî‡ðª)mws»ÉŠhô‘ ³¡\>HDZ®žŠ×çþcþ¿/ò9‹ .<9%®Ÿso:$jTÛ‘‚t8Ãc¯­)m{;ˆXKî7NÛŒÿ}{ÛéZÔQq[K•ÞŸz.®"Š 6rµí¹áÜv_ãüÅX³±˜Þi“Ü[6éZyæ ™\ èqøWKE @9:Îxµ 1öy(ç»ÇÈ@U'åúÚ¢[{™|,údv·ÝBüÅ ’ ‘]]‹¡[ ¹¸¹ z]ÑQ…Ÿ„qœ`Ç­fÜZMö{˰L÷³]#¹åpXmý°8Ç^+¬¢Ž eX[²ëzœ²BpÆ-ŽË× Î WÔGÙõ³wqi-Ì måÆÑÄdòÛ$žLŒsí[µRóLµ¾p×(ì@Û…•Ôè@ Æ“…á«vi,exIû9@r¼gy8Ï­G*ß\jÖí4w"H¯s±m@ŒGÈÝæcž1ž{ô®ª8Ò(Ö8Ô"(T =)ÕWÖÿÖ÷´·õµŽj+iGˆF·ý)šý[¶ /ýöXÕRÞi5æHdem5‘HRAlž¿µjZX[Y0! !˳9v>œ’MY©éoë°ï­ÿ®ç?m§¯ö–œïf6‹I €ß&ã¯_ÖªD/`ÒtÛwŠæ(8•£¶ódRÊ6p1žq]]Þ¢Z¥¼ÖÖz,×VsÍ ºH¯ˆ³#ò¶Î½2:qš« M½ÜIr–éus¸C »¡-ÁØAô#‘]eåŒÊ¢q!Ør6JÈñÒ*Kkxm X-ãÆQÖác.ÞÄ'†®-í¼ö2Ç)U™6[µ-T·qXÚµÄÛ¶)í<ó©è¢›,‘ÃI+¬h£,Ìp÷4מáó¤•,g{0 ­!’QU¦ÔlmÒ7žòÞ%eåU =FO5)¸„A癣íÝænq래¦"J*®í§€Ï ÄRD:ÈŽ ÄRÛÜÁu™m4s&qº7 3õ-Äš)Ò9QÞ3‡U`JŸCéO Š‚æòÖÌ)º¹†Ü)•Âçéš|sÃ,>tr£ÅŒïVqõ¤2J*´:…•Àså¼¾XËì•[h÷Áâ‹mBÊíÊZÞ[ÎÀdˆåV#ò4ÄY¢Š€^Ú›“l.a7þYyƒwåÖ€'¢«>£cÏÙžòÝgÈQ•CdôÎiË{h×&Ùn¡3ޱ áøu  è¦K,pFÒM"GòYÎüjÔlRÝnöÝ`s…Ê¡Iô8¤2ͽå­Ú3Û\Ã2/ ÑÈ®*H¥ŽhÖHd†C)È?1¢ †öÖyž(na’TûÈ’Ëõ¥55.~Íå»Î RÊ¥²:Œg4fŠcM̰´¨%pJ¡a¹€ê@¦Ü\Ák™s4p¦qºF 3õ4†KE4H‘]JÀñ\Ô2jQ[¥Ä—véð²4€+}piˆ±EG Ä3Â&†häˆôt`Tþ"›oykw»ì×0Í´á¼· ®(j)‚hŒÆ*Tn(n×” ¢3D¨eQ¸ a¸\zPè¨n.í­››ˆ¡ p¾c…ÉöÍ6æþÎÐ!º»‚ÿwÌ.ï¦zÒb¨Mÿ!û?úõŸÿCЦ“P²‰ciníÑeŒ´Š7ny¨fÿõŸýzÏÿ¡ELG‘j¿ò¼ÿ®ïÿ¡(Õä-yÿ]ßÿB4P¨ZÈ;Ã?Hÿô™ë6k‰#‚þõ5 ÅÜ7P™‰V€ ³§9úÖ•§üƒ¼3ôÿIž­ÙhöÖ³Í;dzÉ3J²˜†äÝØ´-áŸu;ùšß™w4+”Ѳ±ùn@¾Onõ[ûBù|?w$Žš€•RhÉÀ·ÎÓœó×ÚºVµ·vfh"ff IA’GCõ©|ˆ·»ùI¾@ÛhËÐZC9K´¼H¾3Ll|¦UûQœ©Þ2w0þUÓ[¬_j¸d¹iYŠîŒÈGdz֖->ÊäŽ+Kxã“ïªÆ 7Ôcš’(!„±Š(ã-€J¨ÀÀü…1>(ûD±ÍÙÏ-œvìùB›L˜8-– סçéUuåÝ’Opl’+,BTF³‚yÈè¾jêÝDdu Œ0Êà JŠk;[ˆÒ9í¡•î« `¿@zRþ¿1ÿ_‘…æÍuce«yöO«†tùXŽA_»ïÖ¶-®#¼Òa¸•4š5m’rªO@’{ ;—W¸´‚VA…gŒ1_¦jY¡ŠxŒSD’Fz£¨ þ˜ŽZ+7º:Å¡–ØÎÍ­$|B@è¤vû¼òzÒÛO}%Þ©qakí‘Ãþ u/“–…€z}tkcf–Íl–°, ÷¢€§ê:TÑÇ1ˆâED^Š£~Ïøhµ-J´ž2L¥IÎÑœNIë]1bÝQUߘ ÇLúÓè ]óF±¤ùÇ4™— #íåõÁþU€tö–åR%Ô—í¶ê0°¨Áö$)'¡ÍvMo"HÑ£Oá[qE1ˆâcEèª0áUΕ§4þy°µ2–ÝæWv}sŽ´u¸t2®$m/Qk„šÖâ;»¤Vˆ®%R@_”çœc8Ç­7ZØš…ŒÁ­Zº\ÇRäã9îy:ÖÒØY¥É¹KHsÉ”FÇ­ agÁ¸KHsÉ‘cãÖ…¥õ2üE,s[Ú¬2ÄÒ}±KcWÈ׎¹ÅA¦\%¥¦±5ÊDÒA3I'•Ìdìmü1ŸzÝkKf‰âkxŒrÎ…žäw4‹gj–ÆÙm¡XX‚§ðéK£þ»©COÒ¢:0Šò0òOûéÆHÜçœv1Ó—ÃÂ;d;yÔÖ®8Å2(£†5Ž(Ö8Ô`*ŒøSî#Ê+{íV«Xâ‚ÖÓzDPecÁàçêi–Ò¾™²ËmwÔ’²ùk‰Pœ¿Þ”ÍY-äš5¬FÆg³šI%t„¯Ü,J§ÌWå9ÏÓŽõ&™ ]xLe–;I-™ÂWàŽ‡5u5ZM:Êh’)líÞ8þâ4JBý8  Úeê_èÞ}Ìq,xuc  þŒÕ0ÒKq«Ú["“oåÛ[®È3Íéž0; Ý0Äa0˜ÐÄWnÍ£n=1éP[é¶’y–ÖVо1º8•N> P9`÷6ºÄìš}Ë]½–çó #î<œ1Àì=1Ri mµù Å´ñ;ZžiŠ Ä–8cØzbºo*?7ÍØ¾a]»ñÎ=3éHöðÈÌÏ lλ••ô>ÞÔ_úûÃúüŽ{W-6²M›Ú—û $ÝrŒ¤œmýrzt¦Âƒû/N¿µ¹‚#of@Šìnܧä»×·æ±³¸DYí`•cûã éž”MagpÈÓÚA+ —Œ1Qí‘Å/ëóÿ1õþ¼Œk»¨ux㵄^_ÛƒûŹŒŽI>ƒ<æ®Å Ûêšt(Å–;)1<Vî4ë·seo3€ÒD¬@ôäUspëv1ÄŠˆ¶“…Un‹ ¦#É5_ù ^×wÿÐj¿ò¼ÿ®ïÿ¡(Ô-?ä៤úLõ¹XvŸòðÏÒ?ý&zÚØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@¢›±?çšß"‰ÿ<Óþùê)»þy§ýò(ØŸóÍ?ï‘@ªÈ~Ïþ½gÿÐâ«»þy§ýò*”  zÌû,ü㊀<‹UÿµçýwýÑF«ÿ!kÏúîÿú¢€=BÓþAÞúGÿ¤Ï[•‡iÿ ï ý#ÿÒg­Ê(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š¯tÒo†ÛcJÛwz þ”ï°·üþÜþkÿÄÓ.?ãòÏýöÿЪÞÞßellZÙÙüâÓ#6~lc†ªì-î]û ÏíÏæ¿üMaoùý¹ü×ÿ‰ªkËS%ôEnà”Bb‡çóŒ®ÞG<ôæ¥:õ²Ù\\Iñµ± ,,£ÌRqŽ3ƒœõÍ‹_aoùý¹ü×ÿ‰ Ø¾8½¹Ï¾ß𪩯[yw qöÏnž9Tn!¸Á äñÅMc©Çy,˜f·š0£™@;OB0HÇ‹…‡ÙÈòB|ÌoFd$w âŸ;2Gòcs0POl?­Ecþ®oúï'þ„jKºŸõÖ?ýR{”¶$ûwº›ò_ð£ìmÿ?Sÿã¿üMVÕ5­ç¶´³$»¹-³Ì$"*Œ–8çÓzrO¨[[;ÞÄ—N[5Á#èíýi?ØÛþ~§ÿÇøš>Æßóõ?þ;ÿÄÕ6×íÅ’\¬ Ï7‘ä…`“Ÿ”‚qÛÖ¯Úý•åh®D”BmÊ~óyä(àñÎsйö6ÿŸ©ÿñßþ&±·üýOÿŽÿñ5ZMabŠöwBy‰ mµL‡OÞÀùª£Tûf©¥µ»ÈÊ'FÜÊÃPs@Ó|w 9|(`Äsƒž¿•U›þCöõë?þ‡[ù?ýr_æÕRoùÙÿ׬ÿúTäZ¯ü…¯?ë»ÿèFŠ5_ù ^×wÿÐêŸòðÏÒ?ý&zܬ;Oùxgéþ“=nPEPEPEPEPEPEPEPEPEPEPEP[®.¬ÿßoýªåµøÖúÈ[8ò<’³;.>lç€sZp¼¢7ˆ$m¹sÐñëQf÷þ}¢ÿ¿ßýWaw3qµyñ¶¢nÁb¤Fp»vzã¯Z&Ònîm¯žg€]]´*“±ÀÎ2O^Õ§›ßùö‹þÿö4f÷þ}¢ÿ¿ßýÌýWF}Fâ勯©,¢ägæW-Èî:TúE‰³23ÙXÛ;3kŸ›ë*ÎoçÚ/ûýÿØÑ›ßù÷ˆÛ_þµ Xéÿê¥ÿ®ÒèF¤¹û‰ÿ]SÿBZB`‡k±%˜û““Nž3${Tápr)=Ê[5K)®'¶¼³‘êØ¶Ñ %X`©Ç#·>ÕRþËSÔm£[”²Ìr‡òŽc•pFã=H=;V–ë¯ùãýü?áFû¯ùãýý?áRE¦‰q´âÞ-—ÿj)ª¸û£ü…Kq£Ü½åÅÜ2IJý¥'„6H8M„7¦yéšÒßuÿ 267 373 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀÖ+"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmÁŸM²fkX‰-n„’Pd“Šš+Yæ4Û6oSj€€zœƒÏ>ƦÑä§פ_úªÚ¾éî ‚ÃJ1¹%í ÉU8û½Èã¦@þâ›Ï² 6ÄͳÌ*-Pí^€ž8Ïo\JK½;L‚5eÒ´òKc›dÿ vˆcŽmÙY/ƒ]9gcüyî§AŒ b¥Õ!O÷ÿ¡§waKDg}ŸOÿ N›ÿ€©þ}ŸOÿ N›ÿ€©þ™£5ÑìÑ;³éÿô Óð?³éÿô Óð?“4fgçbùýtßüOð£ÈÓÿè¦ÿà*…&hÍÎ=ƒ‹äiÿô Óð?“ÈÓÿè¦ÿà*…&hÍ?gÁÎÉ#´³•¶Ç£iÌ}ª…Iý™ý¬ð«´…mî1ÔÂÿʲ!—æF ’{V3´]¬\nÕîm‹;B6û¿½þŠœ~”Ï&Ãþ:oþ§øUë2n–øÄ 2d¨œ¬:ƒjŸáVí!¦Ü·ì¿s¯Z³k »•çØ,«åí @õ$ÐÒMè ¶·2|›úé¿ø ŸáG“aÿ@7ÿSü*üå`´-#ævL•Šžâ[?™U¶²mp ÉÆ:þ4Z=‚òîdù6ô Óð?Â*Ãþoþ§øV˲‰y0ü· ÜtŠe´p¨™R5–f  )!{uíKÝì÷s(ÛÙ*+N ÝÙWŸÒ›åXÐ#MÿÀTÿ Ò—ÓâòÕ|•fg ÝSÎïˆ Ê¡ÚG§&£Ø5îcyVôÓð?Â*Ãþoþ§øV»¯nÈC·*¬¨>Nz‘Þ³'ùg‘w+aˆÊðÒ©F-ÚÂrk¨yVôÓð?“˰ÿ F™ÿ€©þÌÑš¯gÄó±þ]‡ý4ÏüOð£Ë°ÿ F™ÿ€©þÌÑš=œ{;åØÐ#LÿÀTÿ <»úiŸø ŸáQæŒÑìãØ\ì“˱ÿ F™ÿ€©þ-¥¶Ÿ=ÊFÚNšg¥ªz}*¶jÖ˜Óâü‘¥*qIè57s@iQ]‡þ'øWŒøÞ8àñv¡¤Q«(TB¨ù î)÷Ôÿ3^!ãÏùõ÷×ÿ@Zå:Z°Ô-¬ô}*9Ù÷Ég*¤Lä…Dü ÿx~u,z¦vŽ9ÔÈÛœ‹IrÇÉù}*¦”qs¡cþ€ïüí«{sxþt˜uM=¥IŠNd@U_ì’䌌íèp?*†óPµ¹Uu!³Í¬¾ŸîÖÎæþñüèÜßÞ? Ùܾ‡7æÁÿ=eÿÀY¿øŠ<Ø?笿ø 7ÿ]&æþñüèÜßÞ?iídG³G5æÁÿ=eÿÀY¿øŠ<Ø?笿ø 7ÿ].æþñüèÜßÞ?ÖAìÑÍyÏYðoþ"2ùë/þÍÿÄWK¹¿¼:77÷çGµ{8œ×™üõ—ÿfÿâ(ó ÿž²ÿà,ßüEt»›ûÇó£sxþt{Y³‰Í aRgXt+m8#ñ J󤋶K»§_G†á‡äVºMÍýãùѹ¿¼:^Ñ‘É{sÖYýºMÿÄRn·Æ<É1ÿ^“ñÓîoïÎÍýãùÓö²³‰Ìn·ÿž’à$ßüE­óŸ2LÿפßüEtû›ûÇó£sxþt{Y³‰Ìnƒ9ódÿÀY¿øŠ [ž²ÈíÒoþ"º}Íýãùѹ¿¼:=¬ƒÙÄæ7[ÿÏY?ðoþ"“6ùÏ™'þMÿÄWQ¹¿¼:77÷çGµ{8œ¾mÿ笟ø 7ÿA6çþZÉÿ€“ñÔnoïÎÍýãùÑí¤Î'/›|çÍ“ÿ&ÿâ(ÿGÿžÿ€“ñÔnoïÎÍýãùÑí¤Î'.~ÎzÊÿø 7ÿF`ÿž²à,ßüEu›ûÇó£sxþt{i³‰Ëæùí'þÍÿÄQ˜?ç´Ÿø 7ÿ]FæþñüèÜßÞ?ÚAìârù‡þ{Iÿ€³ñfùí'þÍÿÄWQ¹¿¼:77÷çG¶{(œ¶aÿžÒà,ßüE‡þ{Iÿ€³ñÔîoïÎÍýãùÑí¤Ê'-ûŸùí'þÍÿÄTÖs[ÛÝ$­,¬< Y³ÓýÊè÷7÷çFæþñüèudÕSŠ3—X±Ü‰ºeÞá½¼Š73` •Ç$ãñ¯ñçüŽzûëÿ -{¸ÄÙA’ãöÓÿJ#¯ñçüŽzûëÿ -fYêzWü|h_öçm[Õƒ¥ÇÆ…ÿ`wþvÕ½@QHaEPEPT5‹¹lí¡x6î{˜£9áœú¿Tõ;í UˆMä²J’«ìÝ‚¬ÈÈÏOZb mvÀ\Ii@C"‰ gc2YUº<{‰Sy¾f3·o\㟥@|>¦ÚhEÙXmáÏ—ÓÊïלþžô—þŠù§wš2ò]­Ò mĈ¤&ͬ¤üÀŒú~”¦¥Ô7¶©qnI‰‚ A¡SÔ6ËgeºˆFÁÏ“‰3žÊ ÇçSÐERQECS»–ÚãNH¶ââíb|Œü¥Xñù ƒþ-;l®ZQq¼ÌLEC†(‹ÕkP±ûiµa7”ö× :›ÆAduÖL‚ÞÒêÖ-V9¢xÒAd¢d Š@~ltè3O º—ˆl¶ãeЛÌXÄóI*Xazãœûµ}©Cco Ó$ÇÏuD#,åˆÈCTµ ÞKrâæ.$+5·˜f솛 Ž˜«/¦oƒM‰®¤ca"Iæ8ÜÒ•R9ç‚sךR+?X^8Xüô ŽÊÒBÈgß‘Éä{T â8®ã⯖%,ÖÎŒôsÇÝ÷©#ÐB-°ûY>CÜ¿ú¿½ç÷ã¿v¦¿‡ÃZ=¿Ûͧ‹ÞW§ñõý?Z@mTW.ÑÛK"ýåBF}@©mE\çjŸ ¦Ë–'Ž©RG½ÈkÌȃÄñØY½és,–ÑÏ;G+oâb>èÎ*˜kök{v3&É/1¢"2ê2T7Bp R_ Ʋ[HÓZLðÀ9¸±YC*´®[å88=séVÿ±Û¶ëožðf,™HÛŒöÏ_Ò˜µ,Ûj y§=ݼs"l܆XÊnÈ ¢¨é>!·¹Ób–ð¼ Qq'™EeæeÏP*}/G:}µÔMr®.vE—\`íMÇêyǵU‡Ãy´û>¡~nU-Î/./b6'æ9n ö  QkÖ2.OŸoJK##mFÁþxÍIo¬ØÜ̱C#;µËÛ`)áÐe¿ wªÏ¡=Ì7ŸÚæââæÜ[‰V,F ’\œ¶ãœç°éNÓt´ý@]­ÃHD À2z‘n´¤ÚçüyAÿ_¶ŸúQxÿ?äsÔß_ýkØ5Ïøòƒþ¿m?ô¢:ñÿÈç¨ÿ¾¿úЩé_ññ¡ØÿµoV•ÿýßùÛVë2¢–b’OjZ*ºF+˜åEr»!ç§5=!…&@î)k:3¥Á§­Þ§É3&ù#ÞXï „ö  ÃÔQ¸zФòx} IšÖÜG!!OÙ$uãm0Ýø`CÅlDs)do$`€qžœ úÓ¡¸zŠ7QU.‡ín á±Iƒ ð À$ãŒûÕßì½;þ|-ïÊÿ…7põn¢ý—§Ï…¯ýù_ð£û/NÿŸ _ûò¿á@ Ü=E‡¨§eéßóákÿ~Wü(þËÓ¿çÂ×þü¯øPwQFáê)ßÙzwüøZÿß•ÿ ?²ôïùðµÿ¿+þÝÃÔQ¸zŠwö^ÿ>¿÷åÂì½;þ|-ïÊÿ…7põn¢ý—§Ï…¯ýù_ð£û/NÿŸ _ûò¿á@ È=¥¨ollíí$šÞÖ¥A¹^4 AúЏvô”›‡¨ª÷H²ÜÙÃ"†ŽIHu=cƒøL¼?%ñ²HlÀ%vy#’:€q‚E[Ü=E‡¨ª¶çÃ÷7&Úl^QŸ”B¼àààãñW?²ôïùðµÿ¿+þÝÃÔQ‘ê)ßÙzwüøZÿß•ÿ ŽãM°Ky,íÑ•I ‘… ã±ú)±’ÑFÇ’QIüª¾£Íº!Îך$nz‚êügpõn¢ªÌž‚õ,å‚ÅnC瞸ÏoZ·ý“¦ÿÐ>Óþü¯øQ j&áê(Ü=Egj§F²†î8¬ìöW¸XZ!ÊÔñÓ5¥ý“¦ÿÐ>Óþü¯øS² ±7QFAî)²tßúÚß•ÿ «©ØÙÚéÓÜ[ZA Ñ!dxã Aâ„“Ù¹ÿP×í§þ”G^?ãÏùõ÷×ÿ@Zö-{þ=bÿ¯ë_ý(޼wÇŸò9ê?ï¯þ€´†zž•ÿýßùÛVÅÜm-»*(cvžƒœ~=+Jÿ þÀïüí«z€9K î?êízò-Úº,~[+.ã‘¿<|ºô®±ŽXŸSI“E‘=¤×šU‚@dR·ûÙã Pí“ÍkÔ}ªÖ?&(íä@ÌÁžVCÉ' }}i[XpYÁcÛgI˜‰î‘©äô·'µC©M,–PiöºuÜ6RÆVVH~dŒq°/bG~€V§Úo¿çÚ×ÿÿÑö›ïùöµÿÀ†ÿãtÀÀÕ´û¹n§û5¤á&‚#FûIùfÏ åžµÖÕ´ßϵ¯þ7ÿ£í7ßóíkÿ ÿÆèõGí7ßóíkÿ ÿÆèûM÷üûZÿàCñº½EQûM÷üûZÿàCñº>Ó}ÿ>Ö¿øßün€/QT~Ó}ÿ>Ö¿øßün´ßϵ¯þ7ÿ  ÔU´ßϵ¯þ7ÿ£í7ßóíkÿ ÿÆèõGí7ßóíkÿ ÿÆèûM÷üûZÿàCñº~©ÿ ÙÿÝ¡þû}MA3]\Æa–;xão¼É+9ǰ*?LNI>´¿ñÿaÿ]›ÿE½T2O{¯§Ú¬®c·´”ýŸ÷yW}¤yŒ{ ü}*ìÑ»<2ÄWÌ…÷¨làðAŽœOûM÷üûZÿàCñºÂÑl/aÔí ¶Ó/’Ó™C䟒<¬sϼҺº£ö›ïùöµÿÀ†ÿãt}¦ûþ}­ð!¿øÝ^¨®¿ãÖo÷ùUo´ßϵ¯þ7ÿ¦É-ì±´f+h ™ˆü6 þt°ÿ¨‹þ¹¯ò¡þ¦/úø‡ÿF-YPUGE¢º„ÏU`¬®®¤Ž2¤ŸlŠàö1µM2ö]Bþ¢™–úhdIo–¡v¸žA]„ŒuÍtžsý°ÛýžMž^ÿ;™Î6õÎ{ôª¿hÔ¿ç…—ýÿþ"“í—üð²ÿ¿ïÿÄS°®sºž—©Zý²âi¡š6±º3L!*ÌX wp€ÚVTí}qMmbñÈ¥]LïÈ=Gܧý£Rÿž_÷ýÿøŠ,4ªŽ·ÿ [Ïúäj?´j_óÂËþÿ¿ÿLŸí·p=¼ékR ®É#3c¾Qüé­2{þ=bÿ¯û_ý(޼wÇŸò9ê?ï¯þ€µì:éͤ'Öú×ÿJ#¯ñçüŽzûëÿ -HÏSÒ¿ããBÿ°;ÿ;jÞ¬+þ>4/û¿ó¶­{Ödµr¬W ,?„g“ø ›#Ö–¡»³µ¶³y­âT•Q×ï;võlôçÖ§nÓ4•ZÚ+‹È¼ñvb؃€ާéVkV†|pÓE†&‘кƒ°‰#=3Í5þÁsÿ?ïÿ~–°\ÿÏûÿߥªšî£yowekb¬~ÒŒˆŸ” (ÞÊ2sž½â©Í©jÇbù°Àé§Irà(p]XÈ8Á@'ë@°\ÿÏûÿߥ£ì?óþÿ÷ék:ëU¼Imn]Œ6/NÆ4Yf<†äF½t4X.gý‚çþßþý-`¹ÿŸ÷ÿ¿KT"A'ˆTé÷7,°Èæñžáž3q©8`zÖýgý‚çþßþý-`¹ÿŸ÷ÿ¿KZPØ.çýÿïÒÑö Ÿùÿûôµ¡Egý‚çþßþý-`¹ÿŸ÷ÿ¿KZPØ.çýÿïÒÑö Ÿùÿûôµ¡EeÏŬ-9»2ªrPÆGÔU–b= §üƒgÿv‡ûíõ4^å¤ó †&ÓI·yÚ–éøSþÁsÿAÿ¿KL—þ?ì?ë³è·¬yoîŸÅ¶jÞÖX’ŽÔ!ù›6O#®:s@`¹ÿŸ÷ÿ¿KGØ.çýÿïÒ×?¢]Þ>¥§¼“JïtÓ‹…iË—w:&Òxëšì(?ì?óþÿ÷éi²Z]EÈ/K¶´cJÒ¨®¿ãÖo÷ùPumȬ7(8úІîGŽåà;ºF Ææ?­Iúˆ¿ëšÿ!Pß«‡þ¾!ÿÑ‹Hd¿`¹ÿŸöÿ¿KGØ.çýÿïÒ×?«]^&«*M2Ém4 n‚r«†ÛÇ—Ñ÷Ã'¦8®Â˜Œÿ°\ÿÏûÿߥ£ì?óþÿ÷ékBŠÏûÏüÿ¿ýúZŽâ ‹Ky.MÙ”B¥ÊÀÜ$dt­J©«È"óþ¸?þ‚h;]´„z_ZÿéDuãÞ<ÿ‘ÏQÿ}ô¯b׿ãÖ/úÿµÿÒˆëÇ|yÿ#ž£þúÿè @§¥ÇÆ…ÿ`wþvÕ½X:Wü|h_öçm[Ô[ÁHÀ+÷FI þè'ð-RU{9 ‚ÌÛ]çܬ„‚ éÈÁ«]n§“&ÞÎyc®õdpz°42è­f¶mknm”äBmþAÿÆ)â]-@ @ü =û½:{Ry÷¿ô¹ÿ¿‘ÿñTy÷¿ô¹ÿ¿‘ÿñTÄ#c¼ÑLÖöí, ÜÛå€qJ×Í¸íº„.xÝóÎ>÷þ×?÷ò?þ*>÷þ×?÷ò?þ*€#Ž- +¯µGgj—‹y«lî=Nqœš¹ý£kÿ=ýðßáUüûßú\ÿßÈÿøª<ûßú\ÿßÈÿøª±ý£kÿ=ýðßáGö¯üô?÷Ã…Wóïèsÿ#ÿâ¨óïèsÿ#ÿâ¨Çö¯üô?÷Ã…Ú6¿óÐÿß þ_Ͻÿ uÏýüÿŠ£Ï½ÿ uÏýüÿŠ  Ú6¿óÐÿß þhÚÿÏCÿ|7øU>÷þ×?÷ò?þ*>÷þ×?÷ò?þ*€,hÚÿÏCÿ|7øQý£kÿ=ýðßáUüûßú\ÿßÈÿøª<ûßú\ÿßÈÿøª[˨®m^ <’| ?ç3±#¹ªææužÎx£Î ³!ë†&§#€+Üen-f ”ŠRÏœŒ¹üÈ©ÞîÁäIk4/û¿ó¶­›‰L0—UÜܤœÖ±´¯øøÐ¿ìÿÎÚ¶åf£|ể‚=ÅG,W6°‰'Y Ò L wÁÿœŒ=*'I¥O.yÕãþ ©‚ãМÿ*”œœš+.æâæÓÂò]ZL#’‘¹@Á‡˜x­J­miþƒ%¤Å‚JeRTๆIªëÚ[ÁÊòK>í‘«"’S—e Žýê«x–Ô¤oomup¯l×9WåE8lîaÈ=†zqVgÒÞqo+^8»· «8~eldéŽåDšBK!’k‰^F´kVbÈc’xi‰úÔo†Î&åeÜ…Tn‡æ`ONÀÖd\èis´\1‚@ËRr¸Á Œ©ãµ^kÔW+äÜ2!b?cîÚX¯l(u<õç¥t5•u¢Csy$ÆyV)ÙxF6Êɤñ‘Ðgp+V˜‚Š( ªjßò½ÿ®ÿ š·Tõoù^×ÿÐMP׿ãÖ/úÿµÿÒˆëÇ|yÿ#ž£þúÿè ^ůǬ_õÿkÿ¥׎øóþG=GýõÿЀ=OJÿ þÀïüí«z°t¯øøÐ¿ìÿÎÚ·$‘b¤áTdšu¸q†–Úh£bvôÈÎGâ*zC §/ØRB)%Våãç×€«•ž·péú)½–ÍîJþaŒ&à7‘“¸ŒödÓÛôÿùüü “ÿ‹£~Ÿÿ?ÿ²ñu¥7Ù-Ó|þDIœn|(ýi²Iaß5í“pÈÜTdP#?~Ÿÿ?ÿ²ñtoÓÿçñÿð6Oþ.´dk(dHå6èï÷UŠ‚ßAÞ¥ò!ÿžQÿß"€2wéÿóøÿø'ÿFý?þÿdÿâêÛÝéɩŧ0OµJ¥Õyàzœ`~5oɇþyGÿ|ŠÉß§ÿÏãÿàlŸü]ôÿùüü “ÿ‹­o&ùåýò(òaÿžQÿß"€2wéÿóøÿø'ÿFý?þÿdÿâë[ɇþyGÿ|Š<˜ç”÷È  úüþ?þÉÿÅÑ¿OÿŸÇÿÀÙ?øºÖòaÿžQÿß"&ùåýò('~Ÿÿ?ÿ²ñtoÓÿçñÿð6Oþ.µ¼˜ç”÷ȣɇþyGÿ|ŠÌ‡ìO*ˆçó\ªµËÉÏ® V麔Q-„®± e”…´÷ûíõ §Ÿ·`ç$ãùíUwéÿóøÿø'ÿS\({ËpZc•<ƒ„b?P Iå„·ÏgEäFÚì°1Elgñ´vÍUß§ÿÏãÿàlŸü]ôÿùüü “ÿ‹©íu.îèÛA´¾X)1¯´á¶±l¸«þL?óÊ?ûäPNý?þÿdÿâéTØ;ûG™“÷éÜÀ±µ|˜ç”÷Ȩ® „ÚM˜cû‡øG¥0õæ›"ÆÑ°”)B9 Òˆ‰0ÆIÉ(¤ŸÂ«ß€aHÊ´ñ+ÜPE!‘ïÓÿçñÿð6Oþ.úüþ?þÉÿÅÔóê:]½ïÙ%Ú$C *…Ž3€Olš¿äCÿ<£ÿ¾E1;ôÿùüü “ÿ‹£~Ÿÿ?ÿ²ñu­äÃÿ<£ÿ¾EL?óÊ?ûäPNý?þÿdÿâéÑ}…äP“ù­œªµËÈ3ô,Ejy0ÿÏ(ÿï‘UuH¢].éÖ4 ‘3+RAù  çüyÁÿ_ÖŸúQxÿ?äsÔß_ýkصïøõ‹þ¿­ô¢:ñßÈç¨ÿ¾¿úЩé_ññ¡ØÿµlÜÆÒÀU1¸Ë»¡ çŸn+Jÿ þÀïüí«z€#¹™î­žÝmå¤]®]p¨Sž‡Û©Xå‰õ4”R¬ù-%¾ð­Å¬|Ù<ЛŽ;É­ †¸·CÅåî,¡$däô>¦”5{;ÍAì/–Öá| {PЗ° ÙCŒÔ7áPaHBiò.™-º,®®UÙ žŸ—¶¼Ëßùéoÿ~Ûühó/祿ýûoñ¦%¡‘>Ÿ~'´’ÞÙÍЂ(å•Ú7‹å9!ùëÊõ®–¨ù—¿óÒßþý·øÕv´ÜÅÚßO,NI6ü“ùÑp±Mt[ØuûKµºó¡M$¬Ñ€Ãp çž8qŠèª™yÿ=-¿ïÛeïüô·ÿ¿mþ4zŠ£æ^ÿÏKûößãG™{ÿ=-ÿïÛ^¢¨ù—¿óÒßþý·øÑæ^ÿÏKûößã@¨ª>eïüô·ÿ¿mþ4y—¿óÒßþý·øÐê*™{ÿ=-ÿïÛeïüô·ÿ¿mþ4ýSþA³ÿ»Cýöúš†Qq:¦–/-¾ðD ‘éÉ©IÉ'Ö€ —þ?ì?ë³è·¬¨4[¸5}Ñ@Wý9®Mçš9‰²L{sž§Æ;ç5¯,EÚ'F $M¹IÁ#èM?̼ÿž–ÿ÷í¿Æ„.“£^ÛêK4l±X4„HeܲîÜjÿ óg×­uG̽ÿž–ÿ÷í¿Æ2÷þz[ÿß¶ÿ½Q]Ǭßî7òªÞeïüô·ÿ¿mþ4Ù Ü‘´m4!X`•ŒçÙ4°ÿ¨‹þ¹¯ò ÷ú¸ëâýµ`ªzúS'‹Îní¤2²œgGê) ÈÔ´kÙõĉÁ{,RD¸XÂ… z±Â ¸“Úºz£æ^ÏKûößãG™{ÿ=-ÿïÛ1¨ª>eïüô·ÿ¿mþ4y—¿óÒßþý·øÐê©«È"óþ¸?þ‚ižeïüô·ÿ¿mþ4É–ââ&†ibòœm}ˆA#¸äÐ]{þ=bÿ¯û_ý(޼wÇŸò9ê?ï¯þ€µì:éͤ'Öú×ÿJ#¯ñçüŽzûëÿ -zž–@¸Ð‰ÿ ;ÿ;jÜó×ô¬M+þ>t/û¿ó¶­ìŸS@ ó×ô£Ì__ÒŸ“êhÉõ4†3Ì__Ò1}J~O©£'ÔÐ<Åõý(ó×ô§äúš2}M3Ì__Ò1}J~O©£'ÔÐ<Åõý(ó×ô§äúš2}M3Ì__Ò1}J~O©£'ÔÐ<Åõý(ó×ô§äúš2}M3Ì__Ò1}J~O©£'ÔÐ<Åõý(ó×ô§äúš2}M3Ì__Ò1}J~O©£'ÔÐ<Åõý(ó×ô§äúš2}M3Ì__Ò1}JqlK`ù¨~Ùüõþt'˜¾¿¥búþ•Û!ÿž¿¡£íÿÏ_ÐОbúþ”y‹ëúTl‡þzÿ:•$(d}Ê{ƒ@ æ/¯éG˜¾¿¥L± ÈûAã“Qý²ùëú“Ì__Ò1}JíÿÏ_ÐÑöÈç¯èhO1}J<Åõý*?¶Cÿ=CJ.â,—’p3‘@µ¦ gü¾ÚéDuä<ÿ‘ÏQÿ}ô¯a× û?òûiÿ¥×xóþG=GýõÿИSÒ¿ããBÿ°;ÿ;jÞ¬+þ>4/û¿ó¶­ê(¢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ½ÿI~”ûýbÏO¸KyÌæWBáb·y0 €IÚ#­2÷þ<åúUH_Áâoí,î5¶’TM¬YHÎâ8ã¶hZ-FÎ[X®£ºˆÁ7ú·.oaïíR=Ô̰Ƀš}LJîšÒí(în› LYreBÄO#¨ä☎¼\Bg0 SÍ%7 Àzâ©Çÿ7xÿžÃÿ@ZÀÓô[˜ 8 354 291 1 2 2 ÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀ&ò"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?óÝKðÄ>Ð5mk@ºÖu]V{„fŽ÷ÉÿWƒ“Ç¡¤vðJ€¯¸à‘«‚Ôí 6ß…þçnn¯Æ}2f¾‡Ð¼5¥?ƒ¥[uýÄ(G“©2áA=zŸZàÆãe‡”aÝ»½í¢:(ÑU”’Óæ|û¯„%uX¾ß»7 XŸ§-Þ™á{FU»øo©ÀÌ2º¨RGâµ§á+¤ÑütÆÚ{Kx­nrtäD™\àžÃßµzú‡…[ź,úޝk|¾Tæem@Þ[A!'ï8œàð+ºœ•HF¢ÙêsÍ5'Ë-´Ÿ ]As5¿ÃFH­“Ì™×WR#\ã'Ž™ªßgðwýëïü/øW«júÆ€!ñAu¤D÷RDEÌl³È%è»p»öŽ‹Võ­KÁ–J­£É§¬ðÌž|iüa‘Füzî?J»!jy6Ÿw“ðçQ“j–mš°8©¾ÿÁÂÿ…zö‹sàø´K«{­GDxå€$²D’Fw7•´Ÿœäcv©."Òdðn£qjº9²HŒÆ«ýª9²7—$dg·<ö¢Ëqž;öÑ>¾ÿÁÂÿ…gðwýëïü/øW¨xòÿÂÓx]£Ñ[Hn!6â)Ð\ÆF7†@7úçq¯0Ü=Gýõÿס$Âöìþÿ¢}}ÿƒ…ÿ >Ïàïú'×ßø8_ð¥Ü=Gýõÿ×£pþðÿ¾¿úôùs öÑ>¾ÿÁÂÿ…gðwýëïü/øRî£þúÿëѸzûëÿ¯G"a>Ïàïú'×ßø8_ð£ìþÿ¢}}ÿƒ…ÿ ]ÃÔß_ýz7ïûëÿ¯G"a>Ïàïú'×ßø8_ð£ìþÿ¢}}ÿƒ…ÿ ]ÃûÃþúÿëѸxß_ýz9Ps öÑ>¾ÿÁÂÿ…gðwýëïü/øRîÞ÷×ÿ^ÃûÃþúÿëÑʃ˜O³ø;þ‰õ÷þü)[Kð~£iªÛ[øJïM¼N¸»†wÔ|Õ5îFáýáÿ}õéÚyÿTÁò¿èsü IÆÈ¹ãÉ©ÞFЉq U‚Š¥EAGÖÿ¼)¢ø§á½b·B g1eÙJl0Ga[øÄÐ7Ùt½~Óû<©%Æñ4jx#Çò3Oý›¿ä“i¿õÒ_ý½>¹ëP§ZÜêö.pøNNøIá+{TKÛ¨]e¹–GV‘»œ+`Jµÿ ·ÁxÇö÷ú_þ*»ZJÑh¬‰z»³‹ <:hQÿßùøª?áVx+¾…ýÿ—ÿŠ®ÒŠw`qð«<ÿ@(ÿïü¿üUð«<sÿ(ùãý|¿üUv”´]Å…ž þ@Qÿßùøªkü/ðBà>‹ ýn$û5d_¬/ñ7SkË‹òÖÔÃܲ«†Ï–‚äûƒXz•ýÝÔ–×—ßm¾{){i-Ô­«™ÐñŽÃŽyã5VÕj&ìvŸð«<ÿ@(ÿïü¿üU(øYà®1¡GøO'ÿV¼”¾ñS_ÜO:ê2Ÿ"fÊBAR;€.+’ðTwš†<7ª\¼E{s^O™ÌLdÈ]ˆ6Þ@©Îþg‚Áÿyÿ®òÿñT¬ðW} >?鼿üUs¿ÛÚÝ݆«}o©L‘YØÝ^B© âVIäGMªš—]¿ºÔ4=íÍͶ Œátø@CJÊCÇŒœçѨ]‹ð»Á<…ÐáÊõy8ÿǪýÏ|=s§Åaui<¶1«·{ÉŒkÿÝ\審<wK¦`Ó¥¾¶Š]UcBÂ3mű‚K…\žj¢k~ ¸´¼ºþО4³Ò¾ÕXT –º«6GFU­;t΀|,ðWOì(ÿïü¿üUðªüæ뼿üU'ÄC{ª6¢i^Ë,á¯'r¤n‘Æß™Ý ŒƒÎàÖ Þ½®ßÛÜ_ÙßKf-´ûY ±…XÚgŽ@Ýzlè)+ŽæøøWà¯úGÿåÿ⩇áÁÁÑ`ƒq'~ŸÅYz–³}§êé·úäÖö©ªËl÷xźÈ8ÀÃ3íT´kÛû¹a½»Œ «©´àìÑ}åß ‚>RT+{n¦¯Ü.t+ðÇÀÌì‹£@]NdûêŸÿ ³Á_ôþÿËÿÅWký£áý-o´¶i¯gîòM eH¸+æU,p¹=øÒé7zÕî§¥Ù¶¹o-¤÷2îšÊA;X·mg1 w éK^àìøUž ÿ  ÷þ_þ*“þg‚¿èýÿ—ÿŠ®Ú’•ØÎ+þg‚¿èýÿ—ÿŠ£þg‚¿èýÿ—ÿŠ®ÖŠ.Àâ¿áVx+þ€Qÿßùøª?áVx+þ€Qÿßùøªíh¢ì+þ_‚¿èýÿ—ÿЬoøÃ~ðWˆ¯ôm*;kÁ§Í”HìB²ò9&½:¹OŠÿòN®øcÿ&ùkÿ_#ÿG­{¬¿ëýã^ðÇþMò×þ¾GþZ÷YÖ7ûÆ¥ŒeQHŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹Ÿ‹?òKõïúô›ÿAÓW3ñgþI~½ÿ^“è"„À´QEX«¾ÿɾZÿ×ÈÿÑë^ë/úÆÿx×…|1ÿ“|µÿ¯‘ÿ£Ö½Ö_õþñ©cER¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®gâÏü’ý{þ½&ÿÐEtÕÌüYÿ’_¯פßú¡ð-QV#êï†?òo–¿õò?ôz׺Ëþ±¿Þ5àÿ ˜§ìï*3°¸ÈUÆ[÷ëÀÎuÞñþ»âGÕ~Ýá F²Ê<Ÿ-wdž¾k®zjXÏG¢±¶5úõŸûùiÿÇèþØÔ?èWÖïå§ÿ¤Õ‹ý±¨Я¬ÿßËOþ?GöÆ¡ÿB¾³ÿ-?øýmQX¿Û‡ý úÏýü´ÿãôljô+ë?÷òÓÿÐÕ‹ý±¨Я¬ÿßËOþ?GöÆ¡ÿB¾³ÿ-?øýmQX¿Û‡ý úÏýü´ÿãôljô+ë?÷òÓÿÐÕ‹ý±¨Я¬ÿßËOþ?GöÆ¡ÿB¾³ÿ-?øýmâ’¹ÝC_Ôí¬.gÂÚîøcÿ&ùkÿ_#ÿG­{´Ä—l±<ž¦¼'áü›å¯ý|ýµî²ÿ¬o÷KÊ(¢Q@Q@Q@Q@Q@ šVbßx“õ¦Ñ@Q@Q@Q@Q@Q@Q@  s?Oü[ x’Iû$ÝÝÒ×3ñgþI~½ÿ^“è"„À´QEX«¾ÿɾZÿ×ÈÿÑë^ë/úÆÿx×…|1ÿ“|µÿ¯‘ÿ£Ö½Ö_õþñ©cER¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®gâÏü’ý{þ½&ÿÐEtÕÌüYÿ’_¯פßú¡ð-QV#êï†?òo–¿õò?ôz׺Ëþ±¿Þ5á_ äß-ëäèõ¯u—ýc¼jXÆQE€(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+™ø³ÿ$¿^ÿ¯I¿ô]5s?ä—ëßõé7þ‚(@| EUˆúïàΛ6­ð.ÆÒب‘îIËœ`Äþ•펈]š¼ž˜?á^Uû6ÿÉ&Ó묿úhk7WÚþ)‘õ»«ôÛxe·Ud†(Ìw)0$*XÏCòÓþz§äÂ-?çªþGü+Í­¼m¨½î›¾ͽÉKyTÀÉåNÐù„o-ó`õzµoâ}i5{É-|Ý_LFL+¥­¡iî“,rp0$:Ð+žµå§üõ_Èÿ…ZÏUüøWërêzÙ¬#k 9å¶ré´®ÄϘ[süsƒÖ´ä×/¬~ÿlêon÷³[¬±¥´LYÀÚ Kž¼}(¶s±òÓþz¯äÂ-?çªþGü+ÌtjæÖÃHK…ŸSþÐû,·WÖì¬Ñ4m*ɰm9ùY{}Ú}‡5ylî5 «hbÓ‚Ê«)„þéѶ®@r_'ø@ÈäÑn¡sÒü´ÿž«ùð£ËOùê¿‘ÿ óOøKõϲ\ù–ñBÖ7fÉÚ٘ƞPp|‘&G\˜ã­z¬©=¬3#I]YF3‘E‚å-?çªþGü(òÓþz¯ä¢¢É|´ÿž«ùð£ËOùê¿‘ÿ ŠŠ—ËOùê¿‘ÿ <´ÿž«ù𨨠 |´ÿž«ùð£ËOùê¿‘ÿ ŠŠ—ËOùê¿‘ÿ <´ÿž«ù𨨠 |´ÿž«ùð£ËOùê¿‘ÿ ŒrkƒY¹=ÍÄÆ{톃ær¤'Ú¶òàà \Ñ`¹è^ZÏTüøQå§üõOÈÿ…yG‰k謋Iþèÿ ÀƒÆz¤–:}ÝÄPZZy“Cy9·iBºKåµ_('?6µñ_‡>#ÇO±Kü¨ ŸÑE@}§û7qð›Mÿ®’ÿèuÞÜèzEÍð¾¹Ò´ù¯F¸’ÙN:|ÄgŠáf“„ö @;ZsÈî ®îÊóU»°†ê3¦<^j¬ÀnRW9ê¹öÍKé4}2Kã{&™b÷¹ÏžÖèdÎ1ØÏµ=´Í=£ò…™ˆCöp†Ç•vcw S¼ÍOqù´í¹ÿžmÓŸo§ëH$Õˆù›MÏýsn¹Þ›¿{Ò&Ñ´¦¼û[ivënÏ8Û¡}¸Æ7c8Çe¬íž¡{h(J˜ã1‚±•û»Glvô®sWÕõñ.‰a$–è¯t ŸgÞ Ä‘†>ÿ…v9c îƒ÷AÏç@$±´’õo$´ï¢AŒã ŒŒd÷î}j¹Ñ4“<ó6•`f¸R²Èm“t€õ q“žù­O9½þøáGœÞ‰ÿ|ð  cáÍ Â!:&–bWó}’=¡±ØÇ\qšÔ``0¶)n'‘mäeØTv8úVo‚®e»ðv•wrÞm̶PHîÀY”h ,QŠ“Î~Áü…szGÿ| Ž’¥36ÿßü+÷S]ø§ÄÜH^(g#BT<œs@£!™²xOûàQç?¢ßü(⥼ȲW!s‘Û'™ª:•õÇü&:%ªË¶ÞX.]ãPbv“ùšè¦rŽªch<¨=¨¾‚±t='ϸ›û+Oó®IödÝ =Csœw«’[Ã$ÐÍ$É,$´NÈ !#©ìpHÈíV<æôOûàQç¶:'ýð?Â”ÒÆÑ.Úé--Öé·fa‡9›ä*ƒþèôQt cž5ÑôÑäTZÆ„ÜsÏ5¯ç1ìŸ÷À¬ ]Ïw>¾nd.!ÔÞÆ0Qú’̲ºŠ¸6˜¹-û*~ì“’WŽ2yúÖ7ÅrOß’r~Å'?…uuÊ|Wÿ’qâ?úò“ùP€ø&Š(«ö¯ìÓÿ$’ËëqüÍjjÚ~»||)6wÁ°ÈÂKv•£"˳näs©Öìû5Ì¬ÞÆÙnn Ì©J#-ÏÌ}:×Cñ|ÑÁ ŒJˆžZfê,‚¢Ç¶qïSÖàÖ–'ñV›¯ÝË£ý†ú܈®áy?Ñ ÀœÈ~nÛõ¦øÃM×®í´µ±½¶sݫʩo™fR_ïp  ‘è:ÒyÞ0Î~Á Î>ÕNxû¾ÿ¥ —Æ@se 8Æ~Õ<ö}ð/jC±²· ã%ÔÂYá7:‚¨[É¹É “ŽßëŠíuQtm—ìGÚ6.ß?vνñÍqPiž ½ñ•y©ZCvÓù²Iö”c´E"…UU9œ“ùVþ§¯-áK íÐYõP·üPÀ³jº¨´›ígO7_òËÉ/åÿÀ²3ùQ§.ª<ßí6Óº~ïìÆN¿ínô¬¿íнiÿƒÿâhþÑñ?ý ÖŸø1_þ&€.ºÀIÿ´ÛLò<¦À¶2Î8ûÞÿ‘ Eÿ°}·þ€*Œ·¾'’'OøGíFàF´ÿ‰©ô¨õMÁúUµŒ7wÐZéö€ˆ¥T†#žE3Çvz•÷…õ4‰‘&{iT£Bdir‡å\‚kCKƒQƒKXï. ¸¼60ˆÆ«òŒ2Mfÿhø›9ÿ„zÓ?ö_þ&íнiÿƒÿâhZ ÚÜÓÓVÿÚ§Ûòý”ÈN}÷ÅQð—üþ&ÿ¯›oýQhxŸò/ÚàÅøšw†-õKKÝoQÔlâŠ{¹b’+xîä"c–ÆM7/Ç‘/ØüŸ´cäó‰ÙŸ|j¾žº——(ÔÚÃyÇ—ömäwÎíÀ{VWö‰ÿè^´ÿÁŠÿñ4ŸÚ>'ÿ¡zÓÿ+ÿÄÐ?iºý¿ŠukBöµ”ÂI[B¾hxR[Œgš·âùü)ÿ_ÿè‰)´|OÿBý¯þ Wÿ‰ªÂß]Ô¼E£]_i–ÖVÖRI#ºÝ‰ Ý ꀱÔê©q%¹K)£†à¢ì’DÞª}ÆF:æü§êömÂê×0k»·H…¹¾k‡mùÜx`r¡ÕÝGP×Åã­ž‰Öë…IùP·v㊭ý£âoú­?ðb¿üM A5{ kíÄÊÚgØ·l2y»yÇlg¥bx·L×/5]6îÝm¡¼µ­L†/ÝÈ ±Ü8äÄU¿íнiÿƒÿâhþÐñ7ý ÖŸø1_þ&½F^‡_øqeq$‚Òë{€Çjdãµt:ÏÛJ¦›Q>þ>KmÆ9û¹5ÍÚ[ëwÞ)Óïõ-:ÞÊÚÒ Ð”º³ Œ¡«×úˆ~Ù ´ÐíåpÞùP°®1Å•‹°¦¤tùæ[(ïNv<*ÍúÖôÝjÅõFÕn¡x¥½™ÕØÆÎNÜ8%Ê}*Çö‡‰¿è^´ÿÁŠÿñ4¿Ú>'ÿ¡~Óÿ+ÿÄÐ]gíùVÒþû¹“ÍÛùc5ŸàáûߨbOý'ö‡‰ÿè_´ÿÁŠÿñ57„l¯­ Õ%Õ!Š ïoÞèE¾`U1¢àœuÊšÝ5Ê|Wÿ’qâ?úò“ùWVk”ø¯ÿ$ãÄõå'ò¡ðMQV#í/Ù»þI6›ÿ]%ÿÐëÓ«Ì¿fßù$Úoýu—ÿC­ïêï§Zê×rýµ¬t›5º– Ù=Ã;í7UQÔ‘Ú¤g_F+•ðnª×ɦȂôYêv {7Ç3[”uVVoâS¼O÷MsÚÞ½­ÚøS’+‹•Óì¯-b,R#oo·~þ|Òy8Ú¤zãšVÖÁÒç¦QÍp#Å7þm¥õäGfÒÞªC¹–~_±ÎÞcÍRÔòäÔ­Ð.t”QY±ZI®xŽm=ï'µ³¶fqnÛ$•˜>n¡F;u f/Ö³´º?ˆN—ö¹®íf¶71Ût‘`¥Kw#ô5Ájþ!ÖlüQ žåtË]B rÍFÙ” sæn=Æ2G4[[Kž›K^ygãVâÅ.HÂݘÎIbš(•å•QVGt±¸S#‚oxêþî×W:¤©%Ä:”Ðþí‹"¨ €¹çž=è°¹‘ÒÑÍ%ghZCø”__^j–ðÇs%´ö²ùelT³‘É% tÚGÑašTVf—$ñ6§es7Ú¥Óî "`d]Šã8ãp÷Æéž ¿];F×/ï.¦TfÅ´1Cä@Çvؘ–dmå€<ƒÒ‹ka7cÑi+ΛÆÚÚÛÙÒâšêæÄj>E¼3ËòyEo˜Ÿâ8QVµ½¾û6“3Ù[<‘6`˜22F[s¾ß, Œ žôìîGyI\ç…u»íF#S‚Ú)^ÊÔû;dþOqë]!¤Õ;…™me.¿â«¼žÒÊÎ$w[gÙ$¬ùêÝB€;SÒÞ]#Ä2éFê[»f¶ûTO1 $xp¥X÷ ‚} /Ò×™ÞëÚÜ%¾qqtºm¶© £1HºFʹŸ7q-Á ŽFM^Ñ¢´þÏ/÷ò£ìòÿq¿*β°[i§¹–ââòúp—7 tP ª98½2}#N¸Šî)¬âxï=°ÿXÀOÓ¦måÀÕ^ ¢¸…e‚E’&û®§ óŠËÃ:$q\Dšt+üH››œð3òóÏæ®éšuž—nÐiÖÉo9••I;œõbI''®¤nùؤý)ÿg—ûùP5œúc¥Ü÷:n¥{¦Éqƒ:ÛìdÛ][ €F8µþÏ/÷ò£ìòÿq¿*£§ÙC§ÛyÛÊ–.ï#nyõf=ɪ á/šñtËqpÌÎ[œnn¬;A9 ¢Š*Ä}¥û7É&Ó묿úv7ž"٪ϧéú]þ¥5²«\µ°M°†äY†N9Ú¹>ÕÇ~ÍßòI´ßúë/þ‡]\ú>«i­__hwv š‡–n#½ÛËd]¡Óa㪜r:Ô±½ |A¥Cj.%½‰!-"n'ø‘Iqõý*oh·6—Pj´û<Ç9nû½GCž+¿ðV¡yÚû1b²\Ë1šhÙNáÐXžùÏls§©øLÞëšEкT²·Ž(ï-ÂóqäüÑc°ÆN{Qd+»ØÖ³×tËÍFK kȤ»vèÆ{uÁèqß•7‹@½Ôà‡N™âÓØ¤×2O q« È-¿#¦¡ðÇ„›DÔüÆM:h"yžŒIöŸÞH ƒ©‡QŽ,Þ ‚Uñ ­öS{ªHÍÁŒ–…Lj˜'¯bxõ¤ì4\ÅV(u~ék¤ñÀ¶ï4¼jãh?Åúfµ¬u;ä¬îb˜Iš»[$¦q»™â¹=KÁÜL÷Q\ZÉp·qÝEáÄM¶ÜBÊå~ažH#8â·ô-.M5 ‹ÉÓ!-ʵÃ.X€Ì~ç=ùÏ>ÕNÂÔØïYþ%ÖcÒf<‰î®î§1[Û@y[’q’I$Z“â­&âúöÒ÷Nž5 ÚX|õ-†Y[Œ‚yÁǤe|i¤…dÔd“N¼IZµ¸_Þ+… GËÃi ‘Š»ÿ >Š.­­ÿ´ 2ܪ9Y·)K“€rHÉÈÅ$3¥°ñ“~a—ÑHÓ;D‹È%•K•Áv‚ …üU¡£[ÔàÍÈÝÉà ÅAÎ8‚2kš>¼:^¡W––wóÝEunðyްM„™² sÖ­]ø§ ÖqéÓÚ›h-dŠôIò‰Ã&ÓƒÇ*ÝðsB°µ4t\ˆ*ɧ;ªé(cAEPEPEPEP\¯Åù'#ÿ¯)?•uUÊüWÿ’qâ?úò“ùP€ø&Š(«ö—ìÝÿ$›Mÿ®’ÿèuéÕåÿ³–ñð—Lò–3J>c€þkÓ¶Íýè?ï¦ÿ –1ÔS6ÍëýôßáFÙ½`ÿ¾›ü)ú)›fõƒþúoð£lÞ°ßMþú)›fõƒþúoð£lÞ°ßMþ&kŸŸDÕ&žIá'ÔS{Ú°C…ÏaòÖæÙ½`ÿ¾›ü(Û7¬÷Ó…sÿاý :—ýøƒÿˆ£ûTÿ¡§Rÿ¿ñ5Ðm›Öûé¿Â³zÁÿ}7øP>|?©Gü%:–ê!ÿâk[DÓ¢Ñô{=:ÝÝâ¶ËV|nnIÉÇMZÛ7¬÷Ó…fõƒþúoð  ºµ¥Õì ¦¥=†341£öùõ¬Ÿì Sþ†KþüAÿÄ×A¶oX?ï¦ÿ 6Íëýôßá@ÿö©ÿCN¥ÿ~ ÿâhþÀÕ?èiÔ¿ïÄüMtfõƒþúoð£lÞ°ßMþ“ hGJ¾Ô/'Ô.oî¯Vy&T]«ý ËFý+f™¶oX?ï¦ÿ 6Íëýôßá@¢™¶oX?ï¦ÿ 6Íëýôßá@¢™¶oX?ï¦ÿ 6Íëýôßá@¢™¶oïAÿ}7øQ¶oïAù·øPè¦m›ûÐ~mþm›ûÐ~mþúå>+É8ñýyIü«©Û7÷ üÛü+–ø«¸|5ñöBßc“îGOzQEb>Òý›¿ä“i¿õÖ_ý ½>¼Ãönÿ’M¦ÿ×Iô:ôê–1sFi(¤æŒÒQ@ š3IE.hÍ%¹£4”PæŒÒQ@ š3IE.hÍ%¹£4”PæŒÒQ@ š3IE>%"©èH#< ‘å0ã™?úÔËõÑÿ¼+…ñ”–_ðšiPjú„öš{YÝ;yw²[+0dÁ%XdŒœf€;ÍñÏÿ¿Ÿýj7Ãÿ<[þþõ«Ç-¼M¬[éíæêfÞ;{V¸±ûDAäÔ‡œÊ«“Ï §'x5¥?ˆµûU’ûÎ[ú…ÝšXù Âî¿0äËŠvÎ÷Å:ŸöW†õKûhOmm$Èò»•Iã¥`|P%¾kŒø,Ús1ú”Ïõ®y5-SRðŠR¼±»ˆé¦HÌ#º3#n çƒ]Äÿù%Ú×ýƒOþ‹ZÀσh¢Š >Òý›¿ä“i¿õÒ_ý½:¼Çönÿ’M¦ÿ×Iô:ôú†1(¥¢ E-”RÑ@ E-”RÑ@ E-”RÑ@ E-”RÑ@ E-”RÑ@‘býëî*Ÿ1¥à$×5qâK ß÷Ú&». Æý 応uÒÒçëEÀæäñE¤Œ&âd9BÚÉÚ}³…/ü%6¹û#Ä ƒ¸Ä’ë úýξõÑçëF~´îâf ¿ ë6Z~‡¯,÷6Ò¢ªè—)¹Ê2|¿çW~(©O†â°!—Ne ö!:W]“\§Åoù'"ÿ¯)?ôø&Š(«ì¾øÕ©x ÃñèiWklîL²;s“ž•¿ÿ 9«ÿл¦ÿßmEÃNjÿô.é¿÷ÛQÿ 9«ÿл¦ÿßmEXþsWÿ¡wMÿ¾ÚøiÍ_þ…Ý7þûj(¢ÀðÓš¿ý ºoýöÔÃNjÿô.é¿÷ÛQEÿ†œÕÿè]Óï¶£þsWÿ¡wMÿ¾ÚŠ(°ü4æ¯ÿBî›ÿ}µðÓš¿ý ºoýöÔQ@ü4æ¯ÿBî›ÿ}µðÓš¿ý ºoýöÔQE€?á§5útßûí¨ÿ†œÕÿè]Óï¶¢Š?á§5útßûí¨ÿ†œÕÿè]Óï¶¢Š?á§5útßûí¨ÿ†œÕÿè]Óï¶¢Š,ÿ 9«ÿл¦ÿßmGü4æ¯ÿBî›ÿ}µQ`øiÍ_þ…Ý7þûj?á§5útßûí¨¢‹ÃNjÿô.é¿÷ÛQÿ 9«ÿл¦ÿßmEXþsWÿ¡wMÿ¾ÚøiÍ_þ…Ý7þûj( þsWÿ¡wMÿ¾Ú²üQûBj~ ðõþ“>…a wq4M$nÛ”ŒÑEy•¿„/ç·ŠdšÔ,ŠÍœŸîÑEÿÙfotoxx-12.01.2/doc/images/show-RGB.jpg0000664000175000017500000003617311701011016015750 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿá 4http://ns.adobe.com/xap/1.0/ 266 282 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑ´2MOy4Û7v¶‰™šÝ $ É'lé@`§M° ÝÙÓ'ô¥Ðÿä¦ÿפ_ú©¯-#¼ˆ+GCº9ï#zóÍCý¥Ð.Çÿ“ü)HÒ;tÛ´àâÝ8?•S]Fêæàéa’;ÄÏ›:T(Ç*?¼r8=;çŒë[[Eià íE÷É'¹'¹>´VM'GŠ6’M7OD@Y™­ÐRN*–ï Ôò†®ëßòÔëÖ_ýÕøCtùðÿÈÒñT$xfæUŠÞ-Y¢"DÄ÷è*ÓèúR£7öU‰ÀÏü{'øVhðþ™¥jšdö6ÞT;!o1›*CŽIô½7ú™?Ý?Ê„OØôŸúØÿß„ÿâhû•ÿ@{ûðŸüM.hÍoÈŒ¹˜ŸcÒ¿ècÿ~ÿ‰£ìšOýìïÂñ4fŒÑȃ™‡Ù4ŸúØÿß„ÿâhû&“ÿ@{ûðŸüM£4r æb}“Iÿ =ýøOþ&²i_ô±ÿ¿ ÿÄÑš¯3C}ºO™ŽK÷ÿ~‡-ÚObÇÙ4¯úØÿß„ÿâhû.•ÿ@kûðŸüMBtÉ-9šíÜoÚT–ÁÊ·«AZöŽ °Hlò}êMF×CN]Lÿ±éeKbÙ`u?gOþ&“ìºWý¬ïÂñ5¢~Ë0¹Ü¿¼ù¶úÔFÉY|Ç>T`ÉÍ+D/"ŸÙtŸúXÿß„ÿâhû.•ÿ@kûðŸüM\‘¢ØÅ(;OB *Øe"$¶YðÃÐsþí¼Š?eÒ¿è cÿ~ÿ‰£ìºWý¬ïÂñ5 Ú.¡%CàgëZÓÝ7žìá~RqœÐÔW@M³ìÚWý¬ïÂñ4}›Iÿ 5ýøOþ&®£ý–Á&A’FÆâ3Š–ØÊרó£ÈÇ¥1ìfoÙ´ŸúXÿß„ÿâhû6“ÿ@kûðŸüMh]î{ò2Já¾üxàVni¨Åô“C¾Í¤ÿÐÇþü'ÿIö}+þ€Ö?÷á?øšnhÍ?gs±ßgÒ¿è cÿ~ÿ‰£ìúOý¬ïÂñ4ÜÒfŸ³ˆ¹Øÿ³é?ô±ÿ¿ ÿÄÕ¸4­*h–O쫞ßgOðª9­k?øó‹ýáÿ¡Vu"’иI·©ö6•ÿ@»üOð¯ Ô•SS»DPª³8 7öÚñ=WþBןõÝÿô#Y½¡ÿÈMÿ¯H¿ôRÞ­Ôˆ±Z‘ó‡”õEöϧoåYöwS[hZ*[Â’É<1FÈPÜ–Î@?ÝôïV¼Ý[þ|¬¿ð1ÿøÕ9ô»sf–ñ†‹Ë;£‘Oέýì÷>¹ë“ššÐÜ»T©Ád<7¸ôÏ¥Wóuoùò²ÿÀÇÿãTyº·üùYàcÿñª“V†K"öWt’À苜d• í÷?ô½ÿ¾áÿã”yº·üùYàcÿñª<Ý[þ|¬¿ð1ÿøÕE#Ý]ÞØ“§\@Ìdw‘£À[¯ð¹=Xv­ÿÔIþéþUOÍÕ¿çÊËÿÿR4š«)ScdA?éÿÆè@TÍ©|‹ÿúYàlŸün"ûþÖ_ø'ÿ­½¢2ädY¤ÍMä_Ð:Ëÿdÿãtyßô²ÿÀÙ?øÝ?hƒ‘æŒÔÞE÷ý¬¿ð6Oþ7G‘}ÿ@ë/ü “ÿÑír2 Õˆ¯ŒpƆJ(\ù¸Î?»Iä_Ð:Ëÿdÿãt}žûþÖ_ø'ÿ©”£-Æ£$%ÅÙ< €6ìïÏb=­> ¨¢UÝn¬ëÈmئýžûþÖ_ø'ÿ¤û=÷ý¬¿ð6Oþ7B”R°8Éê:KÓ$R#/.Û²JyÔ7LÌbB²×ñ¨¾Ï}ÿ@ë/ü “ÿÑö{ïúYàlŸünŸ<;,…šñžHÙ"Ç÷Tv©N¦þdŒ×gîûÔ?g¾ÿ u—þÉÿÆèû=÷ý¬¿ð6Oþ7G<;,ˆQö:·\Õ¯í Í+4yŽQ‚›¿­Gö{ïúYàlŸün³^ÿÐ:Ëÿdÿãt:‘bP’ Ï.#‘‰c'!IéRhp²@UMwvúÔ_f½ÿ u—þÉÿÆèû5ïý¬¿ð6Oþ7G<;–BËx¦ 0ˆ•Ž[æÉ5W5gì׿ô ²ÿÀÙ?øÝf½ÿ m—þÉÿÆéª‘Bp“+f“5kì׿ô ²ÿÀÙ?øÝf½ÿ m—þÉÿÆéûX‹Ù²®hÍZû5ïýl¿ð6Oþ7Iö[ßúÙàlŸünköl«šØ±æÊ/÷‡þ…T~Ë{ÿ@Û/ü “ÿÔñ¶©K £ ûcÿñº‰ÍIY´õ4kÄõ_ù ^×wÿÐzì—oK[»h#ó"y¢œ¿Ý* ¢ÿô¯"Õä-yÿ]ßÿB5‘¡êŸòðÏÒ?ý&zÚwXÑØ*¨Ébp¬[Oùxgéþ“=Yñ$Üè—À#|¬Qzº†ÄHhOíû†g‚F”ÇH”8QžŒ·mwöƒ!‘D¬»ñòŒÿ}k6çV°Ô4»«k9ÕækwÄ Ãå<Ú³â’I\½ƒn˜èãË+×p$~y§ý~bþ¿#¡Ô¯FŸb÷% „*6ƒŒäýjÕq÷Kÿ„rài¦?µm‹ÎÎwçxûùç9­¦ê+•#RWÍËùû¬¿ìã íE‚æ¤yÁÿu${§Î1»ǵK\”‘$ðù2¨xäÖYYOFðj¬-­mµIàˆ$¶—ˆ pNc!Àôž=èZÿ^ŸæOë×üŽÎŠã¦€'¢«Ü*¼ñ£€ËµŽLäUšKh¯­­M²œ9 ´`müiØW4¨ª¦Þ?ÔGÿ|Š£c{ew£tî•™ Ph°îLP€)h¨æ”B›¶–É êI8€’Š‡Ì¸ÿŸ¿ï´ÿâ©ñIæÆi^H õüÅ>Š«oz'½»¶A¶* gïn¥ÔoO²{–BáAõ Z³E ÜâÖÎk‚¥„HÎ@ïšCÜš«Ágw7*X½ÁRàžÑŠ’Ú_>Ú)€Ú$@ØôÈÍIOanQEQEQEQEQEQEQEP›þCöõë?þ‡y«ÿ!kÏúîÿú¯]›þCöõë?þ‡y«ÿ!kÏúîÿú P´ÿw†~‘ÿé3ÖåaÚÈ;Ã?Hÿô™ër€#µÿ…Ïýsù½Kÿëÿ]¢ÿÐÖ¢’e Ë rкüéÖÞ6 –ð«…cÒ€)ë>Ù¥û.|ÿ³Éåã®î1Šç´á§kéÇM çdó‡;ƒ`}ü÷Îz×Ym)%¸†án®bš8Äeцd\ç {úbžšd)kwnM—Lìç# ·\qWh¦tº4Nax®.-åŠ!–&™GcAüªÔÞL²¿Ÿ4žfß–FÈ\ p;g©©è AQM‘·ÚØ+Ó ƒÔÜT´P{{D‡h%U9XáˆF€ú㹩.![‹y`rBÈ… pF*J) £ý•EZE{07d®0TñÈ5VoÛJ’Ä—7pÛÊK=¼n6NO9ô"¶(¦#2}d»šâ;Û»vœ(‘beà`uRGàjí¥¬VV±Û[®Ø£QœÔÔPQ$rÕ‚`ˆNvºnéÈÅKE28ü°Ä±vc–fêMTÔ4žšÞo´Oo,Š4%sÈÁê ^¢Ê/¥¬Út¶W77 /ñÈWzú`€g¥Oek¤VЃåÄ»FzŸsïSÑLAQ¼DÈ²Ææ9`0zÞ¤¢€#Ù#º¼ò‡+ʪ®Õ×9?=•]J°HÁ¸¥¢Ìáëm‹ ¸»kE9­.cö3l⤟EIo&¹ŽöîÜÌH°º¨8²?ZtSKXl­’ÞÝD_×¹©¨¢Q@Q@&ÿýŸýzÏÿ¡Å^EªÿÈZóþ»¿þ„k×fÿýŸýzÏÿ¡Å^EªÿÈZóþ»¿þ„hÔ-?ä៤úLõ¸zôÿw†~‘ÿé3Öå&5 -ôßd~Ô±˜ÛÎ’â1$?ÂUw9úUëIç].îTÂh¦“$)Dl7$òqŸ\ÖŒV°Áh-¢R‘*íX‚×9ªÑèöQÅ$A%hämί<Œç= ý}{Ó×'’˜£Qö©Œp-¤( K*òOÊx¤ºÞØÚ\][ž+ÈÑ]¢(q¼r¡¹ŠÔ“M´H/õŽ$m®T††Üb•´ûf³6®®ÑŸšF-œç;‰Îsß4u¸¨¦Æ‚8Õ± 071cø“ɧPEPEPEP\­…ÄãP…‹Ý®ë™Ã<³ŠURØE\œØt=kªªßÙö¾RÅå|‹/œãÃçvsŸRi¡ˆ.³]IlZæP°H›02vá³ê?Zµ§“®Üý­¡i>ËÌJ@ÆçìI«‘ivqÙmpTÆdb€ )8€§ZéÖÖr¼°#u ÌÒ3’p9'Ö˜™jŠ( Š(  KœËÝËݳÍu$*LG¨R¹ÇA×ÔÃR¼[[ÛÙgµyTF¨w¸\àç8= ]þ˳û_Ú|£ænßöÝßÞÛœgß©£µ‚8¤‰c\ŒÌêy·'­.ƒêbnòy^krí„òØ[K†fÛ´†ld:úT‹ª_°Ž?-p± d·’5e*NB±ÎAëZ ¥Y¤RE±Ú9R²Jî1’qøRǧ[F #1L’»ØÇRIèOÄeÌ—V¥¦ $I6Ø0 V# véVê8 ŽÝYb]¡œòO$äŸÎ¤ ¹kIçñ»µW¾–'–I‹DË–î8=;k©ª1éQÜyë—i]”1êB“€y=¨[ƒØ¥h˧Úk/mh!™Ý."5=-î³5©,häC ( OÌìW·$tàsZ?`¶óå›aÝ2íom­Æ9\ã8Î3QG£ØÆ²(„°‘m¾Fl¨è9g!PȾç½%¡Ò`iÅŸØ£dæaÀWýìZ]Ôç¤_³-Ä0yilñÀdòXíÚÒcq>¥:ÖÆ€­·Ð#ŽU"9Db€°_lÿ:·bt¹¡–=<ÙÉ?¼X6•$úëSY‹U‡e„DŒWl8Ú§¸ã¡¦"z(¢€2/ …|C¦ÎD¯æ+?rt¬á¶ÚŰkqçËw&û€à™c!ŽÜg8ŠØ¸H›PT¸K/xÚ$döÆy§C.”5 ²ûkd8BžaÇ\ãš=Šzu˜×.g´µ‚¶A1FsŸ™ºz £ó©µÉ•ô™ R©ŒÊ‘ÊÊÝx 8ÎjݥŔ¦D³šÝÈbd²œÔœw§˜­á‚@c‰!9i)ÏR­!õ9cŠÍdoöÅS'ÉÝå·§ÝÝŽ=ëoÃÄý×9'‘#ÁÈÚàaÐ}*eþÊþÌ;~ÇöøÛåuüºÕ«'ÈO³y~N>O/qíŽÔÄIE¼µ[‘lnaž‘áÖ€&|„;zãŠåôÉya"ìßqní1V%œü¹/î+¡Kû9.M²]ÀÓ‚AˆH uã9¢좻•aHåÆù‡©Ç? pe=re}&Cªc2¤r²·EÞGN3šÄ1ȬÖA ÿlU1|ÞQ;z}ÝØãÞº“¼0H q$'- 9êOõªëý•ý˜výìñ·Êëùu¤2ö\æ4žD#hc€=‡Aô­JŽßÉòìÞ_““ËÆÜ{cµILH)¤ƒŽ -B.íšäÛ ˆŒê2b7ôëHg?¤E%®¯iÙÄR}þÓ 7žA\9ÁõÏ'“ZZäÊúL†)TÆeHåen‹¼Žœg5=ƒi†IFœÖ›ÉÌ¢¹ÏûXþµ9ŠÞ$8’–œõ'úÓbêrÆ9šÈ$ß튦 O“»Ê'oO»»{Ö߇‰û®sO"Gƒ‘´1ÀàúTËý•ý˜výìñ·Êëùu«VþOŸfòüœ|ž^6ãÛ¨¤ßò³ÿ¯Yÿô8«Èµ_ù ^×wÿÐzìßò³ÿ¯Yÿô8«Èµ_ù ^×wÿÐz…§üƒ¼3ôÿIž¶ßî7Ò±-?ä៤úLõ¹Iê3’ðäÂ[,}¢ ‚–¬›`hz}þNzc·Òº™Þ(áw¸dX”e‹|Ô0j6·´0»; ŒˆÛi#¨ ŒÀÔóJDÒÈHE8ŸÈsM±#˜³žÝô++ˆ®í3ipÌVYp™%€ŒààäqIn#ŠÆ‹El%ó'x0£k+6pG§~kûRÓû<_yŒmÏF±?÷Î3ÛÒ–mJÒ"šINɆcڌņ3œžŸ•ÆsÚÄ××Z\3]X˱aþB€ È,ÀàqüFº¤%‘X©BFJœd{qU¤Ôí#{uisöœyET°lôä Æ­Ð# ®ìÓÅF5š!¶*P8 _p8Ç®++Mòeò¢–xü¡g22 ÃÚƒŒ‰sø‡ƒÖ»¤šµ“™˜êcC#‰ÐíHÈLÒè>·2mîîÞ«}:s¨Ä‰ŽtØ äÀ?5gÃ%½äKm$—.9SøpO"¯Å©[Knó¯œ#@ /‹‘ìþ-¥Ô7–éqnÅ¢ºJ‘ß4ÅКŠ(  -JîÂãTOi­¡xåIegeV,*«žIµ’nÄ,nlæŽy­·JÌÈ@;½˜ð8¿³£m=ËAšÎ¬TŸ!ö:ØÛúÓ­µ k©ž(œ¦rÂ6ÚpppØÁü  >¥^x¯4y^ó#ŽuáOEq¼c¾5Žwk‘qµûb±¹ û½ÞQñœcv;ã"º¹çŠÚšg  ³Õ\j¶fØÜy§`,ƒoÝýݸݟlR¿‡Ãý[Ï#GÆRÇC×ñ­JŠÞâ+¨h0 –8 z¿X­™¶7iØË ÆÛ÷wn7gÛ=½ÄWP,Ð8xÛ¡éÿê¦Y¿ä?gÿ^³ÿèqW‘j¿ò¼ÿ®ïÿ¡õÙ¿ä?gÿ^³ÿèqW‘j¿ò¼ÿ®ïÿ¡õ Oùxgéþ“=m°Ê2+ÓþAÞúGÿ¤Ï[”€ÊÐäh,àÓå·ž9 M®LgaÇpÝzõ­)dX¢i1 2B)cøɧÑMê„Û<1,oÒÈEØm¤ÜKŒ dõÔX'L¸ò¯"·0¸Ž+|‡î‘œ¤g뤢ÎrE’ÏHÒmå‚v–9c‘Ö(^M€œ•¦k¢RC àŒò0ih¦ 'žµÏìKJYÖÞøÀöò,âhÜœ`Fžyáxé]†bénÐItÈ/M‚F»èå÷s ÄcÒ¦ðã줢š7FmË,L‡–$}à3Á­J)ˆ(¢Š+™‚…Õ#&Œ­Ü’4&#ä¢ß8|rNzdòOºj)K–ƒÎ×EÌ݈ÌL%7(à)ÈÀMÝ;ço*mLÉ}¥Èb·˜4S©1²áœ#‚p;ä=kVŠå¤åšì ùS¸¡óŠˆŠoÛŒç'Ó·JØÐá’+9Etóf’EW`¥¸Èì{þ5£E0 ÈÔ¦ ­iÿ¹¸eˆ¹vH”n\@ÇZ×¢€0V2ºª=o“|®nDªâ,y¸ÎìcmE Ãsm5¬¼8Y.DÛ¼½Ãvg_»Û­ttP´ejfKí.C¼Á¢I— áß qëYfÒrÍvá„\©ÜPùÅDE7íÆs“éÛ¥u4R;C†H¬äiÓÍšI\a‚–ã#±ïøÖSþãí:”vrÃr¶ñ:¹e·v¶r 0 9þµN K %.Gxó1+û­™r6:Àc=ºWKE @z™öQÉ.§yw*2ˆ" 1òŽIüIýE©™/´¹ VóŠu&6\3„pN|Ç­jÑHXÚNY®À¼0‹•;Š8¨ˆ¦ý¸Îr};t­"³‘¤WO6i$Uq† [ŒŽÇ¿ãZ4S„ßò³ÿ¯Yÿô8«Èµ_ù ^×wÿÐzìßò³ÿ¯Yÿô8«Èµ_ù ^×wÿÐz…§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤Ï[”QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEBoùÙÿ׬ÿúUäZ¯ü…¯?ë»ÿèF½voùÙÿ׬ÿúUäZ¯ü…¯?ë»ÿèF€=BÓþAÞúGÿ¤Ï[•‡iÿ ï ý#ÿÒg­Ÿ6?ùè¿>Šg›üô_Î6?ùè¿ E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀E3Íþz/çG›üô_΀)Íÿ!û?úõŸÿCм‹Uÿµçýwý×®ÊCkÖdGÙgä¿y«ÿ!kÏúîÿú¦¨ZÈ;Ã?Hÿô™ëwqõ?aZÈ;Ã?Hÿô™ër€qõ?©üé( Ü}OçFãê:J(wSùѸúŸÎ’Š]ÇÔþtn>§ó¤¢€qõ?©üé( Ü}OçFãê:J(wSùѸúŸÎ’Š]ÇÔþtn>§ó¤¢€qõ?©üé( Ü}OçFãê:J(wSùѸúŸÎ’Š]ÇÔþtn>§ó¤¢€qõ?©üé*;‡1ÛÈëÕT‘ùP»©üèÜ}OçH,bÀÜÒ³w>k þF±AÿMïóÿ.ãê:7SùÒ}ŠúkÿŸühûô×þÿ?øÐî>§ó£qõ?'Ø ÿ¦¿÷ùÿÆ¢Uò®žÌP*°ÜrFIÏá@¦ç_´ÏüúÏÿ¡E^CªÿÈZóþ»¿þ„k×fÿýŸýzÏÿ¡Å^EªÿÈZóþ»¿þ„hÔ-?ä៤úLõ¹XvŸòðÏÒ?ý&zÜ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¡¼ÿ)ÿë›*š¡¼ÿ)ÿë›*WñÍÄÚ%¬æžê8™ÕUˆSœã Š®ú•Æ| ÔnEÕ¼É*Kå…u(2AƒÁãVµ{Ô"…bœA$3,ÊÅ7Œ¯b2?W7ÚYu;“w#ÄÐŒ EEn»G<ŸRM.Ÿ×oóëñ%´Öf’æo,M¨¹RÐ7˜8à pqÏz†ËÄ2ÎÖ¯qb!¶»fH¥n9?0ÀÆp}imt©£¹‚k»ãr-”¬ 儯F2Ç<œqÚ’-Ge§Û÷ 9|Ììûü0Ç^>÷éMù ¡Šíï/`…R!ÖáZ@Fq¹*=~µªÇ:ƒÿ×%þmT4í2}=’(ïìãÎÈš¼Ã~{}*è9¿“þ¹/ój­7ü‡ìÿëÖý*ò-WþBןõÝÿô#^»7ü‡ìÿëÖý*ò-WþBןõÝÿô#@¡iÿ ï ý#ÿÒg­Êôÿw†~‘ÿé3ÖåQEQEQEQEQEQEQEQEQEQEQEQEÙI#taƒN¢€+ˆî@Àš2vCŸçK²ëþzÃÿ~ÏøÔôR —_óÖûöÆ—_óÖûöƧ¢€ Ùuÿ=aÿ¿güiÐÄÈÌò0gl €KHÇã9Æs´š`Q›þCöõë?þ‡y«ÿ!kÏúîÿú¯]”cļ˼ý±üPþuäZ¯ü…¯?ë»ÿèF€=NÎÖk E{y’) †)x˃û’¸À#ûÞ½ª×•«Ïí—þ¿ÿ¯!MFùQ/.T`+çKý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÑåjßóûeÿ€oÿÇkÈ¿´ïÿçúçþþ·øÑý§ÿ?×?÷õ¿Æ€=wÊÕ¿çöËÿßÿŽÒy®1öÛ>„Ç«÷ÿ¶µäÚwÿóýsÿ[ühþÓ¿ÿŸëŸûúßã@»ßö‚]]\Ã&ÈÞ5X¡dûÅ <»pqï^EªÿÈZóþ»¿þ„hþÓ¿ÿŸëŸûúßãU™Ýس1É$ä“@ÿÙfotoxx-12.01.2/doc/images/sharpen.jpeg0000644000175000017500000005106711701011016016162 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí6Photoshop 3.08BIM resize sharp ÿá zhttp://ns.adobe.com/xap/1.0/ 8 264 222 1 2 2 0 ÿÛC     ÿÛC   ÿÀÞ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ï4=+Ÿ ¾¾©.‹m=¶™£C¨ÞHºl7WWr3Û¦•×ø§=þêÖo€¾5xâŽ4/ Yxr{Kí^åm¢–ëÖB8Ë휜V£.—¯x"ïAÔî®m¬õ]ÚÉç°H¤š ¼¹ îŠÔ•ëüUƒà¿‡^øk¬G­x~ÿQ¾Ö£aäÝê¶Öñý—ïdï—þ°ÛóWÒâ–'ÛZ•ùtôØùü2ÃÂ’R²±évvÚMͤGV’5¨Ó­ÿ‰Ü©¾Á¤ÐIÿÁm¿ÿ\ÄzŒEk2v¨ó)ßÚÑÏuÿ¾«èãesÈswÐé~Á¤ÐIÿÁm¿ÿGØ4úé?ø-·ÿâ+šþÖ‡þ{§ýõGö´?óÝ?类H“ÎΗìGýtŸüÛÿñ}ƒHÿ .“ÿ‚Ûþ"¹¯íhçºßTkCÿ=Óþú£’!ÎÎØèÁrtm#ÿ°ñëýOÓ~À“é~K›ôŠH,’å#”e$’?+…Áå-·rîÅsGUëÓþú­–ø€ÇÂñh1Û·ŽâÚäMu¬Ëw†…ƒâ¤Œ e|a•Y—ieÛ\Õc4ãìõ×_Czr‹O›¶ž¦¶§áh´mUôëÏ Z%Ù¹šÚÜ @¼1¾ B<¿Þ/ñqŸ•ª8¼; ·sÚÅàøäº·Ó@ž $!þæôòr ãå'­fÜ|@Kë±=ö‘¦êpÿlÞkOgyyæE#\.ß!³S‚®UÂæ!NÖþ#6½c}fÚ}œv:{,A–4µ•ä_‘aE;÷ã`UUÆï›î×4~³dœžßænÕ¶Ÿ¡r}ÆÚÊ+Éü/koe(SÌú$Nev±ŒÈéÏ?ÃRKáè`»ŽÒ_GäÊÒGlÞ #ªŒ³ªy9 2G4Ío⢪[éVö¢Y,txî5).Ù÷µ¢¤¢1 M«¶EÁ}çŒí_›uC­|U¸Ö./&]>ÊÁn Ô!x ½L,—i±çR–ÑîÒ\¾FénêQž!«ªk¯üÄ|´“³—oø$’é:|7‹fþÓ ½2ÇÙ®´¨¡‘^Bn @;ÃtéVÿáÃ\(ðl3‹y¤¶’{mM ’7(ådá”0"¹«¿}³U°Ô vñ=”Vp¬ãrJ-±µ‹íß»´íÿj´ï~(]^H··¶ó!ÕaÄz‹|Ÿo“{¿ú±óEÑ¿þÅi%Y(¸Å=ïýy‘IÞîÛÁû‹ph÷7w°øFîíöùöÑhäƒwÝóC”Ψ^”Ø´[+=ïâ𵬺z+;^G¡£@ªŸx™xç<ñÞ«é#Óuÿ퉼?¤jW«ö%înµ·ÙP&QÞÝÈ2€ m S ‡j¿eãm-¼!©¶ Ö#T}/PÓ-ÚòC6ۙ̄<~ZÆ,[ÌÞx òn¬gR¼7§ý[üËŒiKiX‚]Æ!¸›Ã6vöÓª¸›D#—ø¾F1àô= GýŸ¤ÐIÿÁm¿ÿPøƒâLÞ"ÓÒÎ[k+0¨žâÞá3söqˆ‹'¬§§Þ™‚ó´|Õý­ü÷_û껨ÆR‹öŠÏô9ª8¦¹ÿÌé~Á¤ÐIÿÁm¿ÿGØ4úé?ø-·ÿâ+šþÖ‡þ{§ýõGö´?óÝ?ïªß’&\Òìt¿`Ò?è ¤ÿà¶ßÿˆ£ìGýtŸüÛÿñÍkCÿ=Óþú£ûZùîŸ÷Õ‘iv:_°iôÒð[oÿÄV^¹g`ZÆÖßJÒíþÕ?•$Ðé–í"&Âä dÛ»äÚ»·~ë}ÚÎþÖ‡þ{¯ýõU¯µ‘#–)Qå™Â‰B“ò:ðÍòççÝÏ¥'5&tw?mmô¸ïÞÞh¬åTd¹é¥ÎD~ÇóȧvèþR¾SîÛò´žñÛÂZn»àí Z66¶:·ÚÚwÓ ¬ÀНòÌ~uëwž=Õï4¤ÓÒ°…P[ÛD¶ê¶Ò)$Ëór²¾é7³3óš¼çâÞÄðU…·™à.">b‚D§§ü ­rÂ2P~кŠ5-Ñ÷‡ƒt-.OømŸJÓÝŽ•fYšÒ2NmãÉ-ŠØþÀÒè¦ÿàüMUðWü‰>ÿ°M—þˆŽ²Ï ~=ñ“@ÁeD–À´lWpÜ>ÍÆWæ¢Òþ`÷”ÑþÀÒè¦ÿàüMØOý4ßüÿ‰ªŸð­®?èwñ?ýõeÿÈ´¶¸ÿ¡ßÄÿ÷Õ—ÿ"Ó´¿˜=ßå-ÿ`i?ôÓð ?þ&“ûIÿ F›ÿ€Qÿñ5žþ w«x÷Äkq*™#-€vUÆæìÜãrçê*oøV×ô;øŸþú²ÿäZ-/æ»ü¥¯ì 'þoþGÿÄÑý¤ÿÐ#MÿÀ(ÿøšÉµ¶¼ð׌lôi5{½fÎþÂâí$ÔBhZ!R»£D §Ï· ­ó6ï—¤¬äçñ -Š_ØOý4ßüÿ‰£ûIÿ F›ÿ€Qÿñ5z¼îÿãU¤~-¼‡Ãºåö‰á…¸†±k:WšѦHÁ[9XÊrß-G´Ÿrýœ{¯ö“ÿ@7ÿ£ÿâhþÀÒè¦ÿàüMp—?´™üK6ƒ èºÏ‹5H§’%‹HH<¹"Š;y'œK4ÑÇåGö»xÎ\3<„"¹V+ÉÞ~ÔÚ7„/u{/¯›ugªjìáko§[¼qùò ¥FLáíÚ#µ©ûIÞ×$-{Ñý¤ÿÐ#MÿÀ(ÿøš?°4Ÿúi¿øÿ\¿ÃŠšwÄë½}4˸-´‹Ç²k«©mÇÚ$xܬQÊóĹˆíó£‹+µ†åù«¶ÅÒ§pä‡bö“ÿ@7ÿ£ÿâkœ¼ñƒ¬îç¶m>ÒY`o.O³hæUVþédŒÞÕØWþ9Ö>|—ÄFŸe©-¦µ}ö¨¯®^ܶ§21Œª>\n …ÿj…RmÚâäb×ü%> ÿ Zà‚Oþ3AñOƒèŸø þ3W<_ñ£SðïŽï´Ëm"ÖçBÒgÓ-u+¹.™.CßJcŒÅ¬([s.sÅzæNzЧ7­Ã–µ_x8º Ó" î#@tç'j¯ú®¬Ì£ñ«Ëyá£"+èðÀ®áîtc dœ Îñ€+µñûcBµÉàjÚfOý¿[לø“Uؾ5ºoϫǩéwK—$*[b3åùFåùwoÞ_y`Ãb®Ê=¤û‡${QÐ4•'þ$Úx?õåÿGö“ÿ@7ÿ£ÿâkN÷þ?n?ë£èU4½¤û’=Š?ØOý4ßüÿ‰¯ý²t»O‡šCAaelÇUE/ª &^2}_?~ÚòN´û /þ‰–“©;n5ö=§Á_ò%xkþÁ6_ú":ò/ë^1Ó>hŸð†Áy+väj§y¦é,¾Ýu½£[\¾wlûHÛK`¼¾»à¯ù¼5ÿ`›/ýs^ñ_‡á’ÆÂÓJÔlRi¦†iõ ,²¼Œ<—èÎß6êÒÅÆöÕ?ºäOFº3Ãoádø‚O AâVñ^©4:¦‡=¬~‡ptù ]A¤ž[Æ’Ò7ŽXãHs¼@~PËSQ¿Ä‹U×´ý6ëÄ×>0“Ãú½ãéZ¦ž-ìÒío¡[v²sïU`v ÈdR[æù¸¯}ò¼mÿ@]ÿRÿò=dh¾Õü9¨ßêW‚¼-§jƒ¼»·Ô™%¸9ξÍÈÏͶ¶Pó]z®«ô3æò}:>‡? kÿáBøÚ{I5 ¿—ö—Ky(De»²´i›ÌÜɘ?*å«Î.eñþ€þ&½ðÄ5¹ÑuÚ=Ö§ªé·vz½ÍŠiªG§Í1At¨„­©l|§jüõïÞW¿è ¢ÿàêOþG£Êñ·ýt_üIÿÈôœ/Õtê¿Ì¬­g×§sÁ,‡Å è=¹¶^øÃT»Ñ¯'–-:ê;I¬¼«8®åµ?bf[…Xî”#yT ßg?-uŸõïÏâ"?_øÁ4·Š3£'F»1Næêo2=RI,#’2‘ UW–+deóY‡ËéþW¿è ¢àêOþG¥ò¼mÿ@]ÿRò=>Mw_x¹´µŸÜx‡ãø‡á/‡žÓ|?mãy§iÚµ¾¥-îŒÏsk!½µâÕå·SäÞ-…ÖB?å¦Ü.¿ö‡Å[ëMzæÏPñ¼ZnŸa«\ø|]iB½@¤–¦Ì]E%¸s#1»QÔwŒ+þ*ö+ÆßôÑðu/ÿ#Òù^6ÿ .‹ÿƒ©ù…{Ý}ëüÇÍÒÏî4//Mçį³.ÇþÃÔK.z1–Ç#¹®ž¹/èËxŒkÒYÚ=½¬–vöÖw >D¯;»²&Iò“hÛýêëk*Í6­ýj]$ÒwŠâ¦øsm¤\x‹TÐÍÄ—ú¬sJú5î Ñé3ݺmó$UÊoÚdVþöÂÕÚæŠæjæ÷±å> ýž4?xÁú:ާi©xzÖx¯¤^4Îg6é˜6èä)*Ãp1Ç·nÚØ¼ø#á‰õƒ«[héZ›Ý\\Ëu§Üíy|öI$·! xܼíeÝ]ð¢ªúÜVÒÇ+ῇG…üQ«xŠõ ýgR‹ìòÜêWSaD€ Ânn¯–ùUwWSKE,a^oseàý{áÔþñŠG†›ûVöâ{Oí(ì§•òY£Îñ’…]#óë^‘XV¾/ÖoIJh¾Ö5[¥–Ü]ÛÜÚżnÈà 'F 2°Ý·øhþ…·ˆìµ»ïi·7p s2¾½ÃzÖìZÝçE`®Ñ±f\cž¹®óþïètð÷þ `ÿâ« þ/ÿГ¯ÿà}‡ÿ%Qÿ ‹ÿèH×ÿðaaÿÉTî+ ñŸÄÏê:=´6~+Ñn焞\Œ,ÁRòvÀºª¬Íè®ûQ}JÛÁãñ Õ,æµÓôHü¢`yÌŸ<Ÿ7áv)mÛ¾ò÷Wž0ñ.ŸRÝøC\·‰æŠÜH÷öX $‹g\å™GãV¯|G­iö“\jZ¥g§Æ»ç¸’îÞEW`²’Bõ;E!›7lêr¿021Sÿ¨©dŒÅ##}åm­IH`:WÏ¿¶—ü“­þÂËÿ¢e¯ ‡Jù÷öÒÿ’u£ÿØYôL´0=§Á_ò$økþÁV_úOlŽ•à¯ù|5ÿ`«/ý'޶GJbŠ(QEQEQEQEã-yü/áoY޹“O±ší`gز4q—Æ{gâ×?´7‹ìum3LoißÃ[Ô-´hoï3 㲬pÊ–Æ%tX¥bÓ4J~US÷™}öæÚ Ø%·¹‚;›yT¤ÎŠé"‘‚ ·ÊÀá¬}_À~ñ Þ“w«xgDÕ.t“6kí2 šÈ¸03£yxÚ¿soÝZúƒÛOëcçø>?ø¥­il%œyk¶TIår¼²çŠï%øÏ­êþ2¸ð¾ƒ¥é'PMwRÓëS¾xíü‹;{idc²2Þk}¤€Š8³®ú/‡†mVh¼#áø¥Õ£’FX´‹ukèä!¤IŽÌÊ®@$6àÌ>j†_…~ŸBM_øj].>غcèÖ¦ÔO€<ÑÍžföîÚ…²LOvοµŸüWÔ<9…®›C²ÔçÒ'Ô–Öó˸”ÌÓ5ºÛùLͰ(›Ì­Šö Æ_xq+Ù;Wm iWox¯Àéâëµ»ÈÖâÒÒîÙŒ·LŒ©+ðÊ$ÇOá4¬ÞÀÎÇã/‹5Yt]5Û&o nÒí,Ð[ê­¨ÈRy?z<õÛÏ–ªÉ´¡Ü$-};Œ^m<Úί¦jÒü:–]SK‹ÈÓïÞÂɧ´B1²ó7 #øW»ÿ ôŸô-k_÷Í¿ÿ«ºd$ÿ"º¯Æ­¦ð?ëúÞ¼×Äzm†›¢xÓU¶ðåýާªé—"þúkèd,ìógl„ÆÔÀùT•_¼ÕÕø§Ä×šæ™ ­·†õe‘o¬î Û²;˜¤~|ïD5ÂÍàc#kòXè7öz†·löÒMuzol$¼h£óXD°î~v]ÍóT²‘ê7¿ñûqÿ]ÿB¨©÷.²ÜÍ"ýÖ‘›õ¦R•óïí¥ÿ$ëGÿ°²ÿè™kè!Ò¾}ý´¿ähÿö_ý- g´ø+þDŸ Ø*ËÿIã­‘Ò±¼ÿ"O†¿ìeÿ¤ñÖÈé@‚Š( aEPEPEPEPIÞ¾WøÅð¢Ú]cãiÚf¢Ì<)§Ýiûîïn-Åì×Z€ÄM&Ç;D;“xZí’ûÇóøÖÓÂíâ}\XÁâK›Yµ¥Ó-EÝÍ ÓåŸ'É@&m»ÄCå]§-óSZ«Šöv=ÊŠùOø¥ñJ÷DÖ.5_Xxzévµý”Ëw:\ßj - -bé 4[þkŸ´p¬ÆÊôïücoâ[ßÙ>µkk®xŸG·ºÐ5m:’æ)´«XäžáÒ0Ë"„4E|³•mÛT]ý?½›_Ö‡ÓtWÈ6~/ñ÷‹¦ð¬“ßÞY\麮¡oy¤‹TѵÁç‡Ó£Â!h“~bî¾R”‰V½öp¹Ô5x·UÔu{ïÜ\è(¸¿½ÓVÌÇs›§žÕ6E+66]F7³7ÍM+«‰»;zþ+›Ñ—Å^/¶—QÓ.t‹<]ÜZÇÜ2Ë!òfxX±VP2èHøv×I^1ñ.âÒÏöl¹º–îö×Pƒ^½“Ok›ˆ¤i†©7…”°Ù¿†ùi-õêðŠøëþ‚žÿÀIÿøå'ü"¾:ÿ §‡¿ðþ9^ƒiy¡k Õ´©5´è$ŽD9¤dSSµ‰NúžY«i¾3Ñm ¸¹¿ÐÞ»¶µ+¤Û‡›ÈЭHëý«¦uÿ¯èkÏ|Y{+x;Ä ähÈcÓ/ƒý‘[ÌŒH¥¤äþ7›ûÌ𤣷š/"i#'%_ni•-ïü~Ü×FÿЪ*Jù÷öÒÿ’u£ÿØYôLµôé_>þÚ_òN´û /þ‰–†3Ú|ÿ"O†¿ìeÿ¤ñÖÈéX^ŸÁ^Û)ˆÿeYr9ÿG޵¼‰¿çí¿ïÂÿñTžŠƒÈ›þ~Ûþü¯øÑäMÿ?mÿ~Wüh=“/üý·ýù_ñ£È›þ~Ûþü¯øÐôTDßóöß÷åÆ"oùûoûò¿ã@ÑPyÏÛß•ÿ<‰¿çí¿ïÊÿOEAäMÿ?mÿ~Wühò&ÿŸ¶ÿ¿+þ4d;(1Œ†1¶íÜqŒc½j¯“7üý·ýù_ñ£É›þ~Ûþü¯øÐ¶žF€0cÀô¤’i%;³ÓqÎ*¯‘7üý·ýù_ñ£È›þ~Ûþü¯øÐõ ËâÙ>›¦Yé‹]\Ý$ך„Ö³'+ÌP¢[Ê ·;‡ùEiy3ÏÛß•ÿ<‰çí¿ïÊÿþ¿ÐÃÿø=¹ÿä?á+ñwýü=ÿƒÛŸþA¤ò&ÿŸ¶ÿ¿+þ4yÏÛß•ÿw ÚåÿŠõëH­dÓ4 T[»kŸ15{™ òfŽ`¸ûûÞ^Þ¿.sót¬«ß ë:Õ…Õ…çö]¥­äf+‰m®&–R¤`áË`œnj鼉çí¿ïÂÿD¿óöß÷áÆf—ΖIÛæ36)µ‘7üý·ýø_ñ£È›þ~Ûþü¯øÐ2qÒ¾}ý´¿ähÿö_ý-{ß‘7üý·ýø_ñ¯ý³ò¿ ô`_?ñ6_›Ïîe¡í^ ÿ‘'Ã_ö ²ÿÒxéÍâk_:D†ÛR»òØ¡’ÓNžxà:FFGÖ›à¯ù|5ÿ`›/ý?þ0°ð§‡t(oŒ¡õ}zëN¶&ïÞ½ÕÃ)oA„ni¡l®ð‘Çÿ@Ýkÿ×üjøHãÿ nµÿ‚k¿þ5X?µ„-Q&ÚÜöŸe›P¹»ŽÄ˜¬í¢¼{9%”ç…£ Í·,j¶Úþ8ý£!Ñôír} EÔ5t_iúÌo½&yµ{Yã…Qüà Y˜®àªX¼´ÒÛÌMÛs§ÿ„Ž?úë_ø&»ÿãTÂGýu¯ü]ÿñªËÕÿhßhž‹Äwšn·—÷vú‹‹E-¤½«ìŸí+¿øpOî÷îU,»–‰?h®bŠÓÃþ#ÔZã]¸ðÝ›[X©[ËÈVá¦X‹:æ5²“+mNœõÚX/mÍOøI#ÿ n·ÿ‚k¿þ5Gü$‘ÿÐ7[ÿÁ5ßÿ©uOÓ¾Øxâ5¿Ô´{é­-íá²µi.ž[‹„¶Hü£Îÿ6@Œ;a½+#Ã_´V⛩m Òuû[„Šý’+Ë,Í=“ì»¶æù¥ˆû­ÎÖm­´°\Òÿ„’?úë_ø&»ÿãTâXcBí§ë¢Œ–}"è=I1ñXšgí1á½_R±Òí4Ýf]næêkI´¿"!5£D¶îí!2la²æÝ×ËwfWà|­¶÷Á?6ÿ,oâXÖmGM¸»¶Ô'ÓÑšÊÚTº–(íÌŒHóÌH’4}U]Y‚‰%®ÇAÑÜÁ±8xåEtqІèÕ!éX~çÀþôþÍ·ÿÑk[‡¥IFV½â½ÂÑÀúÖ±a£Ç3ùq=ýÌp‰ÑK‘“ZjÁÕ]X2°Îàrõ¯øëðŸ[ø¡â.•t4«[H5Xîu6µ‚í`ó¬Ú(÷E6àêÌHùW#§Ë^omà‹‹ªø4mPð¾‘aa¥KÕ§ºµÅfÐÈdôA…)\ÚI+¨V2&v¨&})sâÍÓT—N›S¶PˆÛï¶. ŠfvHCöÝX]µ­Šù‹ÀŸ ¼u¥jrÞA§ø§Lk†ðÚ^\ë> k»‹‡·žgÔYd3»ˆ|ì,ƒmT_»MOüOÖ|ý©Eã=&{/ èZkÜYê}Åî£mtMܪ#½†FYP y„ÑJèí‡ÜµV°_ô> W;ðê=Zx}5Û¥ë e\Ú}²K³ ‚iÉ-½œŒážM»›¢íI«;wW0¼Isy&¡ i6wO`ú½óZ½äH¯$H¶óLJÊ“ˆv‚Û—Û[îѧxFÓW¾¼³±ø›«ÞÞY>Ë«{y4Ù$¿»"­¶TýhÕäwðý…æÿÓ}ÝdxCÔuŒšïˆu/ÜxV+(®ô½)âŠÙ!»…çæ¹šH¤.ï3ÄŽˆPyj±-! -ì&úWü*ë¿ú|Iÿ|Xÿò5ð«®ÿèyñ'ýñcÿÈÕÞÑNÁsƵ[ ¼9µ%ψüWª5•ÔvööÚm¥¬÷7Nñ£„-ºäýãµU~f*ªÍ[Z,›.^õ RÎ[H/mî/aX§ÚåÁGû‹Ã"•ù•«;Æ>)_ê$Ô®oo¬ìa¹‡í2XÛyåÁÏ ØÌˆò©ÜÜ-OáûÉïõ‹›‹‡ºi%°¶}·±,3G—˜…uÀò~j‘Q@Àt¯Ÿmù'Z?ý…—ÿDË_A•óïí¥ÿ$ëGÿ°²ÿè™h`{O‚¿äIð×ý‚¬¿ôž:Áo ØøË¶¶W—šu曬Ü^ÛÞéÏÜYÜ-äÍ":•þë£Wûµ½à¯ù|5ÿ`«/ý'Ž¥¾ð¾‰ªÜ‹ÝN¾œü¦k‹HÝÏü –=·ÀOÚøZï@VÕ^ÎëI—FšI¯LÐIs%Ó¶LxÝæHÿ1ÇËŠ±¨üðîµã[ßê—º¦¡ªOqo4%ÚÚ%µX®á»X”Ç 4‰æÛÇþ½åePU7WQÿ?†¿èZÑÿðþ&øA¼5ÿBÖÿ€ÿñ4îÓO°Y3ñ§ìÙàŸ“êq¬ÒjM8àc"_¼mr ËòÑ&Æ‹dƒoÚMXñ_ÁÕÔÓÁöº·}áø4o^øŽkÛyÓíŠóÛÞ«y;âxÉónÆRD#`låŠîí¿áð×ý Z?þCÿÄÑÿ7†¿èZÑÿðþ&„ô²þ¬ '¿™I>xzhÞ‚ˆ4M&æÒæÕròù–× q3°bÅ¥KäüÙlⱵς~ñ™y§Þ. Ö×_Û@—!IþÒbn°vvÝòwø·WMÿ7†¿èZÑÿð_ÿGü Þÿ¡kGÿÀøš]üÆ´<î_Ù›Âèóé2ê:ËéWšˆÕ5 EKã¼—ÊŠ!ò¥¢ýŸä9¶òæc¿æ®ÃÁÿü;ðÊïQÔ4gºÓ¢¼ó§¾‚KöYåyžf¸‘6íY‘—zí,„+ïò×n§ü Þÿ¡kGÿÀøš|^ ðì2+Åáí&7S¹Yl"V_üvÙ6Bx*7‹Á~Ž@Èë§@¬­ü?»ZÚ žrzô´R(1F+—_‰¾oßx/ûUÄ–:bë6lŽ«£9Uv—_T?.wmù¶íùªåŽ<9©ÜÛÛÙëúUÝÅIJC P^Äï$ˆ2ê?1P˸/Ý 67(Åe[x«E¾¸¹†ÛW°¸šÚqk4q]FÍǤLð粟š™uâýÆKxîuÍ6Ýf»LŒa “óß.?½@W?á¯ø{Æ:–»§èÚµ½õþ‡vlu+xÎÚ`!Ã{ó—ï.íÊÕÐP WI›YÌ—2Y^ÙL.-®cPÆ7 ¡Êž(îu¿…¾j“Íñ'ý ±à¡øõcø¦ÜjzÏ…t‰™ÍŽ¥¨´7)‘Òy‚HN;f³-âøO=Ç‹áhîí„“ÎÖd¿þѶŽÞ=²"¼›VTÄR|ñ_—­:¯3Äô2Cÿ‚„ÿãÔyž#ÿ¡’ü'ÿ® k?N‚5Qo¬Íúi¢ÀXêÿÚ?i1yÂ/±lûNL_½»ÁOŸîüÕÚøáÏ€|O¡éú¾—jo´ÛèæÚê;û‚²ÆË¹[>g Z«1]χ5½¹¼o¿Ú.]Ù,y mýÕí'Fd“Í%Ü—·S…W•Ð Ú™* /»·zÀ½ðM¦›ÿ ‡aկ⻆+X/õIa‚ Ð!,òf¤±!U›žµô{H´ýN[x,¤Ó#’ÆÚêK &ýžViC¨mÅ{/Ým¿-HÍš(¢€é_>þÚ_òN´û /þ‰–¾‚+çßÛKþIÖÿaeÿÑ2ÐÀöŸÈ“á¯ûYé%ÔµÝ[ÄcÆÖí­jº¦¡qsa5¨û³º´ûeTóŽÈ'U?'™õÝ[6³LN¥ Ý€Ñl¿ MÛZùmzYÄê„'Eʨô붽Ɩš÷U—=]Ùó†‰û4x‡D—JºŽãÃisᨭí´Å€ÏÕÄWé{ç_·’ÞL§aO”OóI,›Žý•u?fFó@¿‹R¼Ð¦Õ®´]kOY’d‚{ëát¬Œñ–Ú *“€Û—…¯ h¡h­ýy‹­ý/á÷ƒµ/k¾1ó×M—MÕµÔ­îí¤µã’9£1…˜ƒ«¬»{nEÛóv½¨¢†î XÂÕäwðý…¦ÿÓ}ÝsÚçÂ?xË]øµoª®‘§h^1Ñ£Ñío-o渺€Eè’<-/?h$¨”ãgÞmß/YâÒŽ˜òë/6P+O-Ã[ùDta"²²õ +Ž'ø{ùþwßü—KɃMl9þøÎM]LÒ̾"‚s+y‰î¤,Àc–7>k«ðÇö+YI.…,76îÀI5ÔþxUñ.¢Ç¯&—o-åÝ´—ÂЋxây$d%3ŠªŸ.s÷¾Zì+Æ~µñÇ„5Ï^É46z½ŒöIo·ÌD• lS;—!OzOgmÊVº¾Çœé¿´ iÞ6—þ2Ò‡†æm?L½‚k#q¨Ûƒ{qqbyã€Eæ]ò “«foÚÁP‹’.µ{ƒ£>’×Ãú„ï=Ì*N*BZqC.öz \³(e-wÄtM«Ëqyö–—a0‰— …ijÄËòõw•ƒvÚnÚÅñgìçáhú}á3I§êÚŽ±m=í­øIo§šk…0ÜDñ²ff •ܸ_š­Û§õ©”9­®ÿð ž*ý¥ü1§xSÄ¿‡Úç^2[Íqpš}Úiûdû;íû_•ä´¾]Â?–ŽÏótûÕ³}ûAxÇLŽùõ OË’îâÌZ ý¯£’ÝVIüËO'ÏQ\¼ˆ Sœ2Ö%÷ìÁá­CY:„—÷6¥l¢°Ž 2ÂÇO$òŠ£˜aV•WÈVHäÜ‘îùUv®Ý}sàf«jZ–§gâ gDÕoïï/f¼²ò íº‚'€,ˆÀ![hŠŸ¼¬>õ'¶ŸÓ)yœÞ¹ûPèZ‡¥Œ]v%ŸÅþ†Eó"}aÙ‘ÆT”±ºe$wÚê‡?Þ OðƸüYãÒ›CžËN½ŸR¶Òµ6•d[É,gò.sæ<¾ò„ýõF'o˹šü‰iâŸÞÌ K}Yüé¤8Dgq{nwEÿy…/…þxg¾,}nËs2^Ïc¦Ü\B-ì$¼›ÎºdÚ¡Ž÷è›fç ÷¨[ùØõ-ÇÛüþ4n>ßçñ¬ïíí3þ‚6Ÿ÷ýÆíí3þ‚VŸø¿ãLG¯ßÞGsâ{=;Ä~½¸»„%õÔBcýž-ílB³Ž6îùryVû¬–‚ÿ^žV¹´»¹m:Ô]MaþªIU¦ W’à$³*ÕWXµ>"×ÌÖašâ"®ìOî#Ïz“@¹Ž÷_Ô¤‚Ež4µ¶‰¤ߺcÛ£}ÖÛPQÐÑE Jù÷öÒÿ’u£ÿØYôLµôé_>þÚ_òN´û /þ‰–†³x:_+Á>;eléV_êã/ÿ.ñú ÕûRÿÏ+ü“ü+7Á_ò$økþÁV_úOlŒP"µ/üò¸ÿÀy?µ/üò¸ÿÀy?§âŽ(Ú—þy\à<ŸáGÚ—þy\à<ŸáSñFAö¥ÿžWø'øQö¥ÿžWø'øTø£ŠƒíKÿ<®?ðOð£íKÿ<®?ðOð©ø£Šƒí+ÿ<®?ðOð£í+ÿ<®?ðOð©ø£Šƒí+ÿ<®?ðOð£í+ÿ<®?ðOð©ð(†ûJÿÏ+ü“ü(ûJÿÏ+ü“ü*~(†ûJÿÏ+ü“ü(ûJÿÏ+ü“ü*~(À  òO±¼rÛM$n»^9-‚¿í*ö>ÿ@ ?ü'ÿ­n(â€2±ôoúÙÿà¡?øÕØú7ýlÿðPŸüjµ±Tõ]RÛE±’îîC¼eCVf%›jªªüÌK0 Øéh¡WF·EiöJ³ÑÁŽYaŒ„ŽÍÑAÿuR±Žmˆÿ?‰?ð¾ÿãÂsmÿ@á;}ÿÆhwí+ÿ<®?ðOð£íKÿ<®?ðOð¬/øNm¿èâOü'o¿øÍ-·Ž-.î%‚=7]ûDJ’ÚûWñ Æ=þ¥=¬Bî8c‘Òi#Ž(Ã/ÎåcÎ9cóT¾ ÿ‘+Ã_ö ²ÿÑךüSÑo¼CðïÂQÚXkWöö~0kÛõðôÆ+Õµ[Ë¡+£¡W¬lçäùöÒ©+ô=wT𞙣é×7×Þ!Ôì¬íc2Ïus|‘Ç j2ÎìË€$Ñ{á-3NÓ¦¿ºñ¥”Q4Ò]Kz«FK³mÂŒsšùö/ |OÔ¼1¨ÜßÞx¶+û/êƒE´þÖ’6ûkÝÜ›ŸÊuÜGhm”ù„‚ܾç]ÞñøÖçâ h7“x¶ã\ÕÓÄQÏêÚEÝ Ó$ûpûË܎ц!¼ÂÛÉÊUï{z…Ï©!ð–™skmsˆu) ¹ ÐL—¨V`Ã*PíÁÈäc­Yÿ„×þ‚úÇþ/ÿ_2_|(ñ•†§j¾,Öü7£jÕUV»’ö9Ö ˜ïÌ-‹&¼ƒä¡™mˆ>ín]øcâÆŸ¥¨øsR×#ñ§'‰áOí}Aç²µŒù­¤²Ã1h¢Ã,X Ä9aò¨ú‰7¡ïÿð€ZÿÐ_XÿÀ•ÿâhÿ„×þ‚úÇþ¯ÿ_,&…ñÏDµžÖãÇšÄpê+5§‡/µ- Iå¨ušü^4ûYºíÔ™>F]¡}Wàºx¯KñŸŽ“Uƒ[½Óîg’âßX×n.¢ý鸗m´6ÒÊðˆÒ6P²Û"+ª.õ,iÙ\/Ôõ/ø@-è/¬àRÿñ4ÂkÿA}cÿWÿ‰¯ôÉ>"êš®±áÛ]KÇPx¢_ yú›Kª3F×Í«[©¹±Ë²Ç„LË ›wù•ÚxëFøŸgñB8¼ m¯XXZ™tøoo5kíBÖæÔé³ùSÈgà /1Ÿ-æÌjÌûmODû­»á.Ÿá›mQ´É¼eq¢ oe&©˜<ÁÌ*SÝ'–ûGñlm¹Á­ø@-è/¬àRÿñ5ó…üãý3ZÖµ Zx»M7—š>)»i§Åmyö£#HìÆ%šHËò ü‹³jÔŸ¼ñUo YøXñši¯©@úý±º½²:é·ÂyÙ¹i'¹k_’Ý’%eFE\µUµ±7¶¾W>“³iž!­êÞj…v_µ&T‡Ù?÷Íføvê[½-¾Ðþl°]\Ù™Á*w„1Þ*›¿àUå_|7â#âe—ˆ<]§kϯ_x7L°›S–êslnmæ½óRåO'Ì)4 ¥“–weåš½?ÂoæiW ë©ê'ÿ'f¤ídRÝ£b¼oÄ$Ñh #Á žÞh¡´Õ/Þl\[ê7k;ØÂ;v°·elüÛ®mýkÙq7ÿ¼ªÜjw¾±¹¼Ô¯£Ô®¯¤Þnšå<°®“çÍ‹o‘lv—“™êŠèûž{§~ÕKw¦[êw>׬4É4Ë]qѼ­:i|¯=‚Ë’Q¾mŸ|Ž@­MWö•ÓôkÖ^ÕKžöóOÓ5ðyz…ŭз¹UMûãØâR¥Â†X_oUÝÚIðƒÁ²è略…ØIC0‹™Çú m½"Ï™žæßÿíU[¿¾¿Ôu«ûËs«,és¾þëËO9ÃÌðGæùvÒJè¬Ò@Ù¾lî§Ûæ&aëÿ“LÖ®´?ÂÚ¦³}¥¨éÌKkþ‡m IJæIØV`«Ü•ÁU߆uˆÞ,ñ £<5mi¦ÞéÚ™•CÊ—V‹8Y#ÜNï›°Ûò¶kcEø?àÿÖZL‚O>êåçŸRºžYd¹"¹g’Y™¤HÐÌØÛ‘´üÕwß<9áA/ô}>[ …Óíô²#¿¹0µ¼ ²hŒ†&tO”JÊ_oñSV¶½ß§ôŽ”t®oÇ#6:7ý‡´¯ý.†ºA\ÿ-§¸Ò¬ä‚'k]JÆòHá]îcŠê)$ÚVØ‡Š‘ŽÔ~"kºÅh÷é§ÝèV¾}rÌZÁ$wHc}Ž]•·rFqþÕpö|dö–7PhG^Ö"Ñ.´û¨ Ÿì¶i¨Èé²hÚ]Ò˜|²AY#ór"®ÄØx¼75é5ù­“¼ªµ¹€ŒyFÔŸ'ó/ï|ß{šÌ°ðo½3ÃúŽ‹o¦j‰a|ñ;åuFž?$î€C1&HV#Ê™DšÛRwØî¾ø¾ûƾÚ”PŨÛ_^i×&Ó>L’[ÜI ’0I!_fí¤¹ÆæÆã‘âÀ³ø“Äv­uªY}«KÓá7:D/-Ìkç^î(Qgøãw÷¶Õ¯ ø‹Â> Ñ-t"ëM>Ümaxí’Å™™Ý 3ffv$³1,rk˜ñv¯ˆõ]hYÏ­YGuae :…•…ÂK©%ÓåwG´²ïˆá•”çk+)eªlH¿¥ºÅ­h¶I>©x,ô‹Ø…α‰;¯Ú,ön,ˆÎ@Üy;~o˜µyíŸÿ$ëGÿ°ªÿè™+Óüc4z…›yºä6Zdöó_êq4rÜO,öòAPú¹mAµWjí¯0ý´?ähÿö_ý%C-Ñà¯ù|5ÿ`«/ý'ŽªÃ¦ëšRÉobútÖfifŒÝ4‰"y’ œ­ó;U¯È“á¯ûY陫IçJYdp»CI$†G!}7;m«ôPQY^'Ñ[^Ñ'´]OQÒ âëJ‘#vœðÎŽ9Û†â¾Vð·2Ê‘¥Y`±þXGZŸÚvŸóõýü³EVþÓ´ÿŸ¸ïà£ûNÓþ~áÿ¿‚–hªßÚvŸó÷ýüiÚÏÜ?÷ðPš*·ö§üýÃÿÚvŸó÷ýüfŠ­ý§iÿ?pÿßÁGö§üýÃÿY¢«iÚÏÜ?÷ðQý§iÿ?pÿßÁ@hªßÚvŸó÷ýüiÚÏÜ?÷ðPž WþδŰˆEä*hŒõ@¸ûœ>ïËIý§iÿ?pÿßÁGö§üýCÿZm•õ¥Í¥Í¥Í¥È>}´Ð#Ç0 ½mnûÞ•V èv“‰áд¨&æÐKŸ ²Àx1ÛÂr~_»ÍZþÓ´ÿŸ¨ïà£ûNÓþ~¡ÿ¿‚€{¥Xjv×÷º}íµÆÐÜ[$‰6ߺXmlvÝ÷h¼ÒtíFŠïN²»…™¢žÚ7RTaNcÀþí;ûNÓþ~¡ÿ¿‚í;Oùú‡þþ ™cDTEDLDPª t‚²|U¥\êÚmºÙìk‹kÛ[ÔI`“ȸŽ]™þùxϽhiÚÏÔ?÷ðQý§iÿ?PÿßÁ@<]"êO¨/ÃíQoÞ1] ´±+&r¿ÚóŒöõ«?ð°ï¿èJ×?ð/Lÿäʯý§iÿ?PÿßÁGö§üýÃÿ;“bÏü,;ïúµÏü Ó?ù2¹mNïVÕõ½BðøZý-®­­m¼™îìwæ7¸bÇmÉã÷ÉŒü­í]ö§üýÃÿÚvŸóõýü\v1´]6ðë)}ucý› ½”–q[¼±»1y!}ß»vUÉã's3×þÚ?òNtû /þ‰’½ãûNÓþ~¡ÿ¿‚¼öÎt—ᾌêùCª®NAýÌ´˜ÏlðK”ðW†°Hÿ‰M—Oú÷޶¼ÇÿžùÖ'‚¿äIð×ý‚¬¿ôž:Ù(ï1ÿç£þtyÿ=ó¦Ñ@Çyÿ=ó£Ìùèÿ6Šw˜ÿóÑÿ:<ÇÿžùÓh yÿ=ó£Ìùèÿ6Šw˜ÿóÑÿ:<ÇÿžùÓh yÿ=ó£Ìùèÿ6Šw˜ÿóÑÿ:<ÇÿžùÓh y¯ýöüëOh1HÈþ °GS‚­w þu{W%t«Ò†LÀÖ>±ñY¼žðõ„µÏêzΛ$ðZèoc†;tƒÌf7Wùl¸U,NŒ Yÿ„ÿÃÿô1iÿøŸãGü'þÿ¡‹OÿÀÄÿ‹Bý£¼®a"ë¦ÊóWP!±½†H¦…Ìïn#œm"3DñänteRÕgKý¡<­hz–µgâ›It½>Ú;Ù®™$E0Hì‘È™Qæud3ó¿{媰®I§ø³JÕ®DZ½¥åÁ„PÜ«¹ü­O5Çñ°ük#Zñn“ã 躾v·Ö‡X·…%ØÈñȳ˜äB®£¯Ì¥HV£ÅLWÃ:¹RU…¤¤Øí4š°Ö¤MãÍ‘µý=YN7‰:?á>ðÿý Zwþ'øÔþ+ø¥u/øgNðÞ³â{Q³’æßIÐ…²4V°yI$Î÷3C"´Ñ. î%€ y§]|rðž•u-¦µ©É j0ؾ¡qe©@ñ´(yò!p lé.ÈŽÇ [¥.lVÿ„ûÃÿô1ißøŸãGü'Þÿ¡‹OÿÀÄÿ³ÿ ëÀïáùu•ñfÂ;¸¬>Xe3<ò¢ÉiÏ1ËÆÁÓjËó ­·Ç?éw±éßÛ1É«Íh—PYu-æFÒC±]±É*£FÃ6 vÐÕ·wØ“Mñ ޵ægêP_y|[Î$ëƒ^ûhŸø·zAëÿeëÿ\e¯a²ñü&ñ‘öOíÍz`.Æ$6nœ íÞkÇmù':?ý…—ÿDËD•´cM=Qí> ÿ‘'Ã_ö ²ÿÒxëdt¬oÈ“á¯ûYé ÓoåRY]-ï#b•(ϧ"Š(ÿÙfotoxx-12.01.2/doc/images/remove-dust.jpg0000644000175000017500000002777711701011016016642 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿíBPhotoshop 3.08BIM&resize sharp resize sharp ÿá 4http://ns.adobe.com/xap/1.0/ 170 265 ÿÛC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;ÿÛC  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ÿÀª "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ìü=áíO iRI¢éÎïc35œd±1©$’99«I£øbKÉl×FҾѫ¼fÊ0vž„|¼Ž"§ðßüŠÚGýx[ÿ赪:ì3ê÷±ØinÖ·ÖãyÔBäZ+vÇñ–ÇÜéÜö¤2xt Os5¼Z6”ò[ãÍÊ?ž€¸ÏµE}£èv¦0º”wç9²¶?Ù÷«:G ™ÓþÈm.-Oïã,_{ùhýðÝryõÁ¤ÖΣJÒš¼’dMÚ73~Å£н¤àüMbÑ¿è^Ò?ð ?þ&“u««ÙG±‡´}‹Fÿ¡{HÿÀ(ÿøš>Å£н¤àüM&ê7Qì£Ø^ÒBýFÿ¡{HÿÀ(ÿøš>Ç£л¤àüM7u¨öQìÒBýFÿ¡wHÿÀ(ÿøš>Ç£л¤àüM&êMÔ{(öi.å…Òôs•´= %bTy–Ñ.HúŠUÒ´g$G£x}Î ÂÁ <{b¨jQ]]iöëmo,û'}Â5-•qœUk#war­se,AÑÕ\qŽÿZå–’i#xê®Ù¤,t–]Ëá½(QcÿMû&ÿBî‘ÿ€Qÿñ5±¦ÝÃ¥º<å •¸éÆïjl_bû ³ˆZL¿˜22m§=>™­ùbž¨Í9>¦OÙtoútüÿ‰£ìº?ý ºGþGÿÄÖ¸šÎ;qˆ­Y–›æ%‰ÃgŸJvÝ=KªýœÄüÆfù€þ´Z‚òîc}—Gÿ¡wHÿÀ(ÿøšO²èÿô.éøÿZbM8ÛC3„]±ºÊ`üÍ푊Wû2˜Ä ;1ã{p ¦£ ÚÂæ•¯r“YiJ2|5¤êlcÿâi¿fÑÿè]Ò?ð ?þ&¶ç¹ d’[¨Þ٭ˆ·†%±Øvæ«È¶ŸaiTÀKCU nÏÍÇo­%v ˹˜-tƒœxsH8ëþ…ÿIömþ…Ý#ÿ£ÿâkužÞ9¤µ¢™``±œ`Žç½`;íœg'îôü*£K ¥).£¾Ï£ÿл¤àüMgÑÿè]Ò?ð ?ð¨÷Rn«ö0ìO´—r_³èÿô.èÿøøR}ŸGÿ¡wGÿÀ(ÿ£ÝFê=Œ; ÚK¹'‘£ÿл£ÿàáG‘£ÿй£ÿàáQn£u?cÁí%Ü“ÈÑÿè\Ñÿð ?ð­?HЮàydÐ4”ÚØâÊ?O÷k+umèÇ:mÇûÿÒ²«N1…Ò4§6åf-߇4$´˜ L ¨Ä¡EÁÇûµòÖkë{ÿøõ¹ÿqÿ‘¯’+è>šÒµF³Ð´ 8tû«ÙçÓ#”$1µQ" IwQÖEéW¿µµcþOþþÚÿñêÍÐ×xgþÅçÿÛJÚ»Õlln µ¹¹Xæ¸ÿU$· t²G>ô†WþÖÔqøFu?ûûkÿǪ­ä××¥ øsUM™Æ%´ç8ÿ¦ÞÕvß_Òn櫓‚ú'¹Z<àå~ð÷Ç|UYü]£Ç§]ÞÁt·If¡åHN[i8ÈÎ23Þšm;¡4žŒ§ä]ÿÐWÿ¿–Ÿüz"ïþ€¿ýü´ÿãÕ±6µ¦ÛØE}-Ò¥¼Í¶7`FãÈÀÎx=ª¼Þ$Óíá¯.!†¶m9bw)o™Bü¼SŸjÓÚϹÎ=Œÿ"ïþ€¿ýü´ÿãÔ}žïþ€¿ýü´ÿãÕªž!Ò%º‚Õ5Zk…Våƒ ¯æ9¡Ô5Ʊ¿º¶òbÛo`nüÉfع ·àà{óô£Úϸ{8v3þÏwÿ@ _þþZñê>Ïuÿ@ _þþZñêЗŚ´jP¬¨v² œ0 qÉ£â›-:8îY£šÒHc•dŠL¹" `¸å~`IÏàhö³îÞÅ?³]ÐWÿ¿–Ÿüz³]ÐWÿ¿–ŸüzºXfŽâšÝŒ«`ŒÆ¨êQAp‚yÚŠòœe²øÓU*7k‰Â ¡ŒÖS±ËxwUcîÖgÿkP¶S¡ÊxwUSê­f?öµhhéßóÿ7ýüj?´tïùÿ›þþ5UêHVCì·_ôÕÿïå§ÿ£ì·?ôÕÿïå§ÿ«’êv+4w“;€v¯˜Ã'Ò­Íc=°}a#ÎzÆýcü}€'ð¤êMnÁBdd}–ëþ€¿ýü´ÿãÔ}’çþ€¿ýü´ÿãÕ°¶²õeÄp˱Ç8 ‚wœpGcÖ«E¨YK rýªáw¨ln2:PªÏ¸ù#Ø¡öK¯újÿ÷òÓÿR}’çþ€¿ýü´ÿãÕ¥öË/ùüŸþûj>Ùeÿ?“ÿßmG´ŸqrG±›ö;Ÿújÿ÷òÓÿQö;Ÿújÿ÷òÓÿV—Û,¿çòûí¨ûe—üþOÿ}µÒ}Ã’=Œß±ÜÿÐWÿ¿–Ÿüz±ÝÐWÿ¿–Ÿüz´¾Ùeÿ?“ÿßmGÛ,¿çòûí¨ö“î‘ìfýŽëþ€:Çýü´ÿãÔ}Žçþ€:¿ýü´ÿãÕ¥öË/ùüŸþûj>Ùeÿ?“ÿßmOÚO¸rC±›ö;Ÿúë÷òÓÿR}Šçþ€:Çýü´ÿãÕ§öË/ùüŸþûj>Ùeÿ?“ÿßmG´Ÿpä‡c3ìW?ôÖ?ïå§ÿ£ìW?ôÖ?ïå§ÿ­?¶YÏäÿ÷ÛQöË/ùüŸþûj=¥NáÉÆgØnè¬ßËOþ=Wlg½±…¢O ê²lÒZñê›í–_óù?ýöÕbÆâ9n¶Ã;Ȇ6,“‚ 㯱©”ç%fÆ£î‘\êïq$Ö7:eÝŒÍk$éç´LTª¶ nÜå×®:×Ëuôþ£ÿ#4_ö»ÿÑWÌ‘¡ô¶ƒþ»Ã?ö/?þÚUÍkF»Ôomnl§ŠÒXxûPwªî¨åu8å[ކ©è?ë¼3ÿbóÿí¥tÔ†rVÔn.¤ðÁi¡ysq‚eo5¤ “Ð ®OôÍ/ü!÷³Ùˆ.ïí·[X}†Ñ¡‰€Û¹sç¿î×ÇS]e Æ>«¦_jºT1N,Úõ˜$–1 á£uÃÿ:͸ð¾¬èê58.EÃ@nüàÈnDhA¨à3`œuë¨wXÑØ*(Ë3=iA9€±Ì¯„ä:ëj ±Ïôºúï ÿؼÿûi]0$t4†qÛך}è½Ông_³ZL“ªB’DÓ’»ÝÀÎIª?ð“ë-¤ÙÍo~&•¤¹K‚±Ç&Ët`>Ñ”K/•·8¯CÞÞ¦ìˆÓ{ŠÚÿˆîío¼¯Gip. 62£•ääŸgr€6Ùv}Öcìnd?û5bhfYÇ|Ö‘”’ü!ÎЋÜdôÊç?•¨ÿÏMKþù‹ÿ‰­eUEŠT`ÐRÐG•¨ÿÏMKþù‹ÿ‰£ÊÔ禥ÿ|ÅÿÄÖ½‘åj?óÓRÿ¾bÿâhòµùé©ß1ñ5¯EdyZüôԿøš<­Gþzj_÷Ì_üMkÑ@V£ÿ=5/ûæ/þ&+Qÿžš—ýóÿZôPG•¨ÿÏMKþù‹ÿ‰«šzܬrý¤Ê~q°Ì61Ïݽ[¢€0µù¢ÿ°EßþŒ‚¾`¯§õù¢ÿ°EßþŒ‚¾`¦#émýw†ì^ý´­-_Ä6Z,©ÒÜ3ÒF ›ÂÖó+)»nŽÒ?¸:@áëßúSâðâ@,Ì7Ò¤–bãË,fÎN÷sÇ­S±*å½GV¶Ó•f–k†+0DdwÀÉÀ€ªËâ]9¯ÖÓ3‚eù­ ĤdF_ íëÅI}£Ëtöw0êõš•[ƒpá†rduÆx#U|.Ò³ê2½§ÚVñ­|¥ç;·u ¸Ûëß#"Ø6Ÿwsm îðZËsMD· wmb9翽[·ñ¼÷Ößc¾[‹ˆÄ¾Y¶o‘ræãžõü"V†ÊÞÒK™^8-gµ?(Ö_¼}ˆ©m´ Þ[½NK‰žÏì~bD"!3F ù©ÿ_ŸüÔkx¯Neó#»Žh¤Ž#nöÌ%c&vaq’ÖÁö5-®ºnué´¿°\ H"˜LPào v¿!{žI¬»?ÅcgwoÕ«´†7ß§!FX÷`²nùœï9lçZ:g‡Ž“w Öú”ÒF¶ÑÛÌ“ v›`;[vrÍïÐR@lÖlúí¬2ÀÉ;×_÷èÑý«üû]ߣOþÌ´þìßø/ÿGöe§÷fÿÀ©øªgö¬óíuÿ~Ú±ÿϵ×ýú4ÿìËOîÍÿRÿñTfZvoü —ÿŠ jÇÿ>×_÷èÑý«üû]ߣOþÌ´þìßø/ÿGöe§÷fÿÀ©øªgö¬óíuÿ~Ú±ÿϵ×ýú4ÿìËOîÍÿRÿñTfZvoü —ÿŠ jÇÿ>×_÷èÑý«üû]ߣOþÌ´þìßø/ÿGöe§÷fÿÀ©øªgö¬óíuÿ~Ú±ÿϵ×ýú4ÿìËOîÍÿRÿñTfZvoü —ÿŠ jÇÿ>×_÷èÔö·Iv®ÈŽ›k]§¦j?ìËOîÍÿRÿñU4ðÛ+,*T1ËvrON¬Mcê?ò3Eÿ`‹¿ý|Á_Oê?ò3Eÿ`‹¿ý|ÁLGÒÚúï ÿؼÿûi]5s:úï ÿؼÿûi])èi ®mÑŠ´ñ©AaIö»oùø‹þûz^› ÙÝjW–±¼HZ[‡T ì¹êÝÏ5vÎm;P¶[›)-n |í–®§pGÄVû]·üüEÿ}Š>×mÿ?ßb´<ˆçŒ÷À£È‡þxÇÿ| ¥±ËŸ.E|uÚsO¨ï#Ž;ûF V*1‘·?Τ¤0¦»¤k¹Ø*ú“ŠuC±$ÔíÖE ¡€###þ¦€µÛÏÄ_÷Ø£ívßóñýö)˪ho¨9/´ö½Sƒl%C(?îç5{ȇþxÇÿ| b3Åݱ8þø©©Ë&Ÿ5äÖbi¢^HötVȧ|©§’tø 9ù­!–h¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÂÔäf‹þÁú2 ù‚¾ŸÔäf‹þÁú2 ù‚˜¥´õÞÿ±yÿöÒºSÐ×5 ÿ®ðÏý‹Ïÿ¶•ÒžE!œÏˆRéôIj³æÚæÚWx-šá£QËlPIëúÔÅnõ}WGšFÔ¥¶‚Úå¥fŽk ò†fôùÚÀ<kNwmo¿ÙA®¸`äú “íóá'ýüOñ¦˜š¹Å[&±rš‘¸þ×Óâši#ŽÉ Sy¹(¤’ÌÈ&":b–îÝ›j:m¹µÙ…ng1Íæ™Â¶þWin@ší>Ñwÿ>ßÄÿ>Ñwÿ>ßÄÿAbK¦cyb¬Û˜nÉÆ2vu©ª¢-Ä÷QK,>JÅœÀ–$cµ[ ¡ ·S€ÿÓ)?öZš«Ü$¢hç…<”¦@$tÏÒœŒú>¬×wɲØn †´[Þ2€»eFê@` ¨šI³ñ@´ÔOÛoV6S#G4SÞrNÆI˜¸í³‘Åvh»ÿŸ ?ïâh»ÿŸ ?ïâ,nbøJÝaÖ5˜-uH-ä¶·MÚ—›æ}Ã2rq‘÷~_JÛÓ¿äû¿ÔÓ~ÑxzX¸>ò&?Mk ·µŽA(¸$SlIX–Š(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š( Qÿ‘š/û]ÿèÈ+æ úQÿ‘š/û]ÿèÈ+æ b>–Ð×xgþÅçÿÛJ高Ѐ3xd‘ÿóÿí¥t¾\óÌ~güi uß.?ùæ?3þ4yqÿÏ1ùŸñ QMòãÿžcó?ãG—üó™ÿuß.?ùæ?3þ4yqÿÏ1ùŸñ QMòãÿžcó?ãG—üó™ÿuß.?ùæ?3þ4yqÿÏ1ùŸñ QMòãÿžcó?ãG—üó™ÿuß.?ùæ?3þ4yqÿÏ1ùŸñ QMòãÿžcó?ãG—üó™ÿuß.?ùæ?3þ4yqÿÏ1ùŸñ QMòãÿžcó?ãG—üó™ÿuß.?ùæ?3þ4yqÿÏ1ùŸñ QMòãÿžcó?ãG—üó™ÿuß.?ùæ?3þ4yqÿÏ1ùŸñ QMòãÿžcó?ãG—üó™ÿuß.?ùæ?3þ4yqÿÏ1ùŸñ  MGþFh¿ìwÿ£ ¯˜+éý@âX€Ù|ÛH+æ b>–Ð×xgþÅçÿÛJé«™Ð×xgþÅçÿÛJé© (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š‚ÞÖ;Ù®Zw”ˆ¤¢¤¬€ ªsò‘“ówô«Ù6ôñÿRÿñU—}+àëϲ8Y ²œ|•äÀÒoÎïG=åÅëK`Òê5ÓΣV˵‹àpFrx Ggý“gÿOø/ÿGöMŸý<àT¿üUpéâý\i²Jš…­Ü²é†íŒp€,¥ÞŠŒóíל¡«:‰u­-/,LËs,°CöµŽ4+‘î$«2¦A9‹ =õ”6vRÜÛ¼ë$CpÝ;¸8ìC*sÁ5“i{yá%Ô‘Và‡VFÜ ü¬v3($užk]¾ñ¡‚+ÚÚGz÷;ÊvJQBJÈá#×½Xþɳÿ§ü —ÿЬNæöÓÃ:ÔÚp&í­Ñ“¸ ÆsYgRÑt!n4ZîææäF‚Auö†bÄrVWœõ'h€êÿ²lÿéãÿ¥ÿâ¨þɳÿ§ü —ÿŠ®&ë÷útsGy ´°Ø]\H âW†V@€^v’9àâ¯ßOuu0¹†Ü[ZÅ4:~À^è¼[þñç;xô4ú\<Ž˜éVJ2Æp=MÔŸüU@ð-üQBÒyrÆå•ä/‚¥pA$žõÃÏ­jº·…/dÔ‚=¨²‰KA•9K.#‘þPAlk»»`Úµ¶;E/óJÐIêcj?ò3Eÿ`‹¿ý|Á_Oê?ò3Eÿ`‹¿ý|Á@Ï¥´õÞÿ±yÿöÒºjætõÞÿ±yÿöÒºjC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€)yék5ÊN­¶Y7©ØX0Ú«Žû4ÞiöÊVÞ%…X䈭Ê}ð*öHèhÜ}MQ[Í=…‰Hw8äo>§ŽW¾²‘]],œ8h õãŸÆ®î>¦ÇÔÐlóÁ5“YÚGÃj"DUWô Ò=M>´P$º[9'Iƒ©iK©H €;}*?;Jăì°â_õƒì¿ëòóøÖŽHïFãêhŠÞØ"HÕT.Ыn@ éŒtö¡¯,HähÕž.#cnIO¡Ç…^Ü}M©  s¦¢È©j%ÿXÛþ¿/?>9EÕürÆËŠ'RÅJŒ’¸?J¹¸úš2Maj?ò3Eÿ`‹¿ý|Á_Oê?ò3Eÿ`‹¿ý|ÁLGÒºe®¥ý›áÝCNŠÒcŽ xîn¾°0 ª>qåž0:ÖŸâ_úéø3—ÿ‘ëæ•ñµ,i¬_ª ª·.Àg¦)á#×è5¨àSÿ!ŸJùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@Jùþ%ÿ ^‘ÿƒ9ù?Ä¿ô Ò?ðg/ÿ#×Í_ð‘ë¿ôÔ?ð)ÿÆøHõßú jøÿã@F›MV]BMGP‚ÊÝ"°šKk—˜±v²wF˜Ë÷ë_0Öü$Zçýµü ñ¬êb?ÿÙfotoxx-12.01.2/doc/images/revise-RGB.jpg0000664000175000017500000007074411701011016016267 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿá 4http://ns.adobe.com/xap/1.0/ 454 292 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀÆ$"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÜÑ´2MOy4Û7v¶‰™šÝ $ É'lé@`§M° ÝÙÓ'ô¥Ðÿä¦ÿפ_ú©¯-#¼ˆ+GCº9ï#zóÍCý¥Ð.Çÿ“ü)HÒ;tÛ´àâÝ8?•S]Fêæàéa’;ÄÏ›:T(Ç*?¼r8=;çŒë[[Eià íE÷É'¹'¹>´VM'GŠ6’M7OD@Y™­ÐRN*–ï Ôò†®ëßòÔëÖ_ýÕøCtùðÿÈÒñT$xfæUŠÞ-Y¢"DÄ÷è*ÓèúR£7öU‰ÀÏü{'øVhðþ™¥jšdö6ÞT;!o1›*CŽIô½7ú™?Ý?Ê„OØôŸúØÿß„ÿâhû•ÿ@{ûðŸüM.hÍoÈŒ¹˜ŸcÒ¿ècÿ~ÿ‰£ìšOýìïÂñ4fŒÑȃ™‡Ù4ŸúØÿß„ÿâhû&“ÿ@{ûðŸüM£4r æaöM'þ€ö?÷á?øšO²i_ô±ÿ¿ ÿÄÑš¯3C}ºO™ŽK÷ÿ~‡-ÚObÇÙ4¯úØÿß„ÿâhû&•ÿ@kûðŸüMBtÉ-9šíÜoÚT–ÁÊ·«A[6¾wØSȶãœúRjºrêf}—Jÿ 5ýøOþ&²é_ô±ÿ¿ ÿÄÕùmÒ{öHÈ -·Ö†±d&EG$`ã Ò´Bò( M(œ Ç?õÁ?øš ¦–¤†ÑlŒ ÿÄÕµ·ª33 »F=ZÙ–k¹Ã»¶Îp1¹©Ú!y~Ë¥ÐÇþü'ÿIö]+þ€Ö?÷á?øš·¢Í,˜ó'b>cL½·̸'k ÝE±½…ynWû6•ÿ@kûðŸüMfÒ¿è cÿ~ÿ‰­x|ã°ˆ)B>|úT,"k©‘U„|¨íšVaÝ™ÿfÒè cÿ~ÿ‰£ìÚOý¬ïÂñ5lÍ=ÂG$Lb@29«Òîy&FhäM¿,c¡¨®€›}Lo³i?ô±ÿ¿ ÿÄÑöm'þ€Ö?÷á?øšni3WìâO;ö}+þ€Ö?÷á?øš>Ï¥ÐÇþü'ÿMͧìâìwÙôŸúXÿß„ÿâhû>“ÿ@kûðŸüM34fgs²Õ®¥\nÿ‰EŠíÇü»¡þ•?ö6•ÿ@»üOð¤Òÿå¯áýjìê“ýÑü« «JÈÚ.èòïÛAk¯ˆí ŠòTíŒäöT¿ÿäcõÁ™¢¤g hòÓëÒ/ýT·«u",V¤G¼áå=Q}‡séÛùV}ÔÖÚŠ–ð¤²O Q€ò÷%³÷};Õ¯7VÿŸ+/ü þ5@}.ÜÙ¥¼a¢òÎèäSó«{=Ï®z俦´7.ÕªpY î=3éUüÝ[þ|¬¿ð1ÿøÕn­ÿ>V_øÿüj€$Õ¡’çH½‚Ý$°:"ç%H£û}Ïý/ï¸øån­ÿ>V_øÿüj7VÿŸ+/ü þ5@H÷Ww¶$é×$3ähð–ëü.OV«Fõº•Sóuoùò²ÿÀÇÿãT&ªÊTØÙFúcÿñº3Fj_"ÿþÖ_ø'ÿ£È¾ÿ u—þÉÿÆëohŒ¹i3Syßô²ÿÀÙ?øÝE÷ý¬¿ð6Oþ7OÚ äd9£57‘}ÿ@ë/ü “ÿÑä_Ð:Ëÿdÿãt{DŒ‡5Ï}ÿ@ë/ü “ÿÔÊQ–ãQ’âèÜ"§”+nÎüö#ÐzÒ‹¶[tFplÑö{ïúYàlŸün³ßÐ:Ëÿdÿãt)Eh2cÍö.|äŒ Ã ¤ä5G,èÌ ""§<6sGÙï¿èeÿ²ñº>Ï}ÿ@ë/ü “ÿÓçˆrÈ|÷Æi£¦s·4 ÈÍÃÊðn,A9iŸg¾ÿ u—þÉÿÆèû=÷ý¬¿ð6Oþ7GþyÎk_Ãä)ºŠåHÔ•órÄç~~ë/û8è;Q`¹©ÞpÝIÇ)óŒnÇqíR×%$I<>Lª95–VSч<†k k[mRx" -¥â˜ÇÈp='z¿×§ùƒÓúõÿ#³¢¸Ï\£jœZÛÝ[¼b"ÊÞt£ åN@Ç$c¡§ëÍgçjÿÚ„yâ/ô!&qSßvsK¥ÇÖÇaPÜ]Ela±iiœ±ÏøW{}2ß]ÁlLqýšIãv`6Žc!€v}ëoÄ‘Çö;xH#¹C;2åvà‚HôÉÄѹEr÷gJ7ÑÍŸÙ_feÀ"-ÛŽìcø±Œ~•zÉe m½žH BÀÊÿ}¤ûãº\}Mª«©^>ÉîY …*6ƒŽ¤ë\ÄrìF 6ˆÇºâ̲©?1Ç\œ€{õ¨ÚWHÔe´»¶šDZX™UpK`±ç~”úˆíh®3UU¹Õ®¾Õyon®¨m%š6bhæ6 9ÏlÕãö%ÖçÛ+J diAÚFJöÎìç½ ûk¨®„†$G#FÙù‡Zš¹í l"Õ/RD‰us)\9Br}1T53¦WWûij Ÿf#>`mœlÇ|â—AõgW礘|©>æÿ3'\c>µ-sE”_1Õ@ÇöRý 7ûÜÕ}4^Em~“ ?µ ®mK[ÊÇÊû@õ÷Å7§õê/ëò:{¹Å­œ×K‘œß4ëi|ûh¦h‘cÓ#5ÇX[Ç%­ËZÝÛ´¦ÊE–Þ]‰_,~`i÷SYªØ^¶¼am­¤™ßÁëûYöíÚ‹_x_úûŽÊІ+¨fšhclÉ‹‚6ädTÔQEQEQEQEU gþ<£ÿ¯«ý•~¨k?ñåý}[ÿèä âüŒcþ¸/ó4QñþF1ÿ\ùš(²´ÿw†~‘ÿé3ÖåaÚÈ;Ã?Hÿô™ëpœ ÐEWŽy¥dŽÎVFS¹G¯-RE+;º!ÿÈÆ?ë‚ÿ3EvVŸòðÏÒ?ý&zÛoº~•‰iÿ ï ý#ÿÒg­Ê]7þA¶¿õÅ?¨ÛþB×(ÿ›Ó ¥©$›X =ü¥ÿ |qG"(Ò0y! þTÎëOÚ­?´?ä¾o39Ù¿?.ïn½k/ÐÏÙJ‹#¨>öÚÌžVN2®qÞºÿ&d,FÊXKy9ô¥ÙqýÈ¿ï³þB9XÒ;{Ki£»†kQ¨#~á Ç dœ ãó©m$³³}Q¼rjK$Î#ÛûÇN£ßWK²ãû‘ßgü(ÙqýÈ¿ï³þ_—ùõùÿ™ÊèÛî–ÚKSÙîdµR¨­“Ôyü«³ª ò##,j`äãô«t7¢QEHŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¨k?ñåý}[ÿèä«õCYÿ(ÿëêßÿG%pÿäcõÁ™¢ˆò1úà¿ÌÑ@•§üƒ¼3ôÿIž·+ÓþAÞúGÿ¤ÏV¼E4hWO ´rm ¬§@È?!£JŠå/õ;Ù4wÓ┦¥q<ŠpUPgxôÝòãýïjµw®Ï[ÛÞm–fw†Isžƒ Ó¡äþ´Ät4W;mu{­C$Em·Ù#É è̓¼ä‘ƒïR5íåÍ®©,‚ØÚÁçD#(Û›hîwtü(z!­Y½EbC}y3[Yééo-ªM#J”ÀP±ç5«Ú|Ù|ÿ'ËãËÙœôç9÷éCBLšŽ”Vf­r-ḚE/¼jÛ9Ãldã¨q@`ƒÐÑ\ç‡u_í(å˜[Ç C2F|U$V8û§¡kkRvLºtb¬°¹AÁ¤Ý•ƕ݋4W%¤Ý–ºÓ’ÎæúiZ/2í.ÊíÛÔoÿkÛÅY²ÅÞ”5CQ»ˆ6dÛ ¥R5ÎÚ:þ9§a\é(®SP’âM_RX×S›ÊHÌBÖ}Š„©<Ã9úßÑçk&Ög•fvŒn‘Fü}hå! u4€MEgi ŲOqÊòß8ÎÜö˜  ¨¨¢O&y`RJ(V\œàñú~µâjlIö¶I ›ãµ—ËfÂñÎáÓëHfõ€Lš}Ær ävò;A4W3*[î±ùˆê1×½[Ò¥’îöúìÈæßÌòaL¸_¼À{¶yö¦#RŽ”T5¹½h¥ÉŽ4 ·<1$õúcõ  Á¡¢¢žÚ+S° çTe^qÓÔg5£rlô뛕]Í Làzàf“ÐkRÍÍÍmuˆuQ©ÜµÚC眿•ÙÓ½iÖ±¾­ªÞ´—W„Žb”&åÉã¡üE;訬Ýîk«)à $‚g„È7í8ÝŠÒ Š( Š( ¨k?ñåý}[ÿèä«õCYÿ(ÿëêßÿG%pÿäcõÁ™¢ˆò1úà¿ÌÑ@•§üƒ¼3ôÿIžµ/ì㿵kyY‚1RJžx ÿJË´ÿw†~‘ÿé3ÖåV“O¶‘çÄ[ˆü©$x­U} hn.`–„"X˜d› ƒùV†gÍ¥$·Ü-ÕÌSGŒº0Ì‹œá²LSÓL…-níÃI²éœädëŽ*íÀΗF‰Ì/Åż±D"ÄÀ3(ìr?•Z‚ÛÉ–Wóæ“ÌÛòÈÙ Žlõ5=*) 6àÛ[zdz‚;ЖНohíDª§+1Ð\w5%Ä+qo,HY¡#®ÅIE!”² È«H¯fÆàŒ•Æ ž9ªÍáÛiRX’æîyIg·ÆÂIÉà‚G>„VÅÄfO¢¬—s\G{wnÓ…,L  ªHü ]´µŠÊÖ;kuÛc 3ššŠ*$ŽXr°L Î×MÀ}9©h G––.ÌrÌÝIªš†˜·Ó[Íö‰í倱F„®y=A«ÔREôµ›N–Êææâáeþ9 ï_LàŒô©ì­b±´ŠÚ|¸—hÏSî}êz)ˆ*7ˆ™XÜÇ"Œ B;Ô”P{$wWžPåyUUÚ úã''ñ§²«©V© ÷´R<=m±a7mh§"Õ¥Ì~æqíœT“è©-ä×1ÞÝÛ™‚‰U¶GàkNŠ`Cik •²[Û H“ ëú÷55P ¢Š(¢Š(ªÏüyGÿ_Vÿú9*ýPÖãÊ?úú·ÿÑÉ@Ä?ùÇýp_æh£âüŒcþ¸/ó4Peiÿ ï ý#ÿÒg«ú†¤–2ÁÙçžYËHBç“ÔŠ¡iÿ ï ý#ÿÒg§ë6·:¶–`y¡eÝ4hgËß žœÐ2ÄZ¼sªyQ•€{“NQ‡ì¦âéZÉm"è„ÇëÖ¨Þ luѨ}ž[ˆ$·ò[É]í qÔƒžÞ•RF¼ÔD/5¼Æ%ԔƲBTˆ‚õ#3žM _ëÌoúûÇÔ,£†9žîÝb“î;H·Ðçšt÷–ÖÊ­qq *ü)‘ƒôÍ`ë6’®°'"äZµ¿” ´ .Ó“T©À Ž@íU®4é-®-ŽošÐYˆQ’Ýeu99 ¥N2è;R¥¸¿³µe[‹¸!.2¢Içé“VAï\ýžš©¨GC,¶Ë§,jÓ§ûGƒÆ3ŽÕÃé,z”s#¤‹\F;iˆÑ¢Š(¬Ëi »žÝl®ç6áL¯© ÈêÀŸÀVrº…²gR70jl“$b3h$Úÿ);~SøÒ5áÕãšø"² Sh.D¬qÁ8ç=*øž"è¢TÝ"îA¸e‡¨õŠæ ±¿*!¸€¬“im*£j°'ãÁÔ:ÝêgŠ [˜%ŠÂXY¥ˆ W!@º‡‘Mÿ_ˆ¿¯Èé`»¶¹g[{ˆ¥d8`ޝ×*jç4 EpÊÿnI €ÆRkuã#r¨ÝÈã“] U gþ<£ÿ¯«ý•~¨k?ñåý}[ÿèä âüŒcþ¸/ó4QñþF1ÿ\ùš(²´ÿw†~‘ÿé3ÖåaÚÈ;Ã?Hÿô™ëfY¢„)–DŒ3˜ “Ð}hôQMwXл°UQ’Ìp¤1ÔUS©XãÞÛáÍ\1ö9æ§i¢I7‘äÎÅ,lrp;Óú)’Ë1´’ºÆŠ2YŽüj)/ìâHžK¸%æ6iôçš±EEö«qqö>/;ò÷ØõÇZK{»k­ßf¸Šm§ å¸l}q@QPÝÈa´šUûÈ…‡à*9-ìmÖ?µÞ4o'B÷%7a‘úPª*¹´°ˆ ˉˆÈŒÜ¶â=qšm´mÙamxÓmûÞ]Ñl}phÕ^{KuVžæHƒ÷,¹>œš—û2ßû÷÷ýÿÆ€EW60Çwn˜«Fă3uqßÜÔvæÎéÝ!7ÀeðãûË“‚3þpF@.QLÌ–ñHzº+ÄUh£†h%º»ãUvóJ*€qØJ@\¢ª¼rD’½ã,rcc›¦³Ó<Ñäi¿iû7ÛÚ?ç—ÚŽþ™éœô¦ª*)4ûX‘žIfDQ’ÍpÀùÒEag4k$3K"7FK† þ9  ¨ª÷Ų¼ùós3 {úc›»ä\dà>Õ'¢“ž ÿ=F@-ÑQ ™cÜXFûA=q€­EåýªùáwuŽ8Õ°ŒW$“Ü}(ÍU ÓdI/ ,_ëº$'מ*H¬,æd†idFèÉpÄÇ45\ÚX‹¹LFDimÄzã9©²àþýÇýÿñ ÑLþ˃û÷÷ýÿÆ©æÖ ;y&[™$‘íݘð2pAŸóÅ_ªÏüyGÿ_Vÿú9*Ìad¹h¥Œ¸ËèG Ÿ]Õ[Yÿ(ÿëêßÿG%pÿäcõÁ™¢ˆò1úà¿ÌÑ@•§üƒ¼3ôÿIž¯Û]_K½´*Ê‘¼›Š¨|ap@9#$â›iÿ ï ý#ÿÒg­ÊC"´•¦´†WFÝ20ÁSŽAS\†YôÒ±$HŒÁWqÚߎաE6$sÓÜÎö-o47.'wg6¬XEÆK*¯òÀéšt¶·ƒW±™`I YÆÛÛtqùdr6ðr}y8¿EGpëάÊHT,!’k\¿† µ)}¾N©jÄ’ œ¯ç¯Zèè¤3œkIÖîâ)3G<¨ m¨B€q'B01޼úUÍ?tšÄ÷ .&ˆ.éá1”9?"‚G=p~µ¯E;ŠÅmGþA×?õÉ¿•7W›©l!•¾Ð¥T¤®9û óéÿÖ©îbóí¥‹8Þ¥séšr]J¨ªör–«¦? °¤3ÚÊ/¶"\`ÜG*,íØFKc‚#ïÒ®i-, ÐÆn¥³Š´ÏÆ ?„| ‘oÆ®ý²OùòŸþúÿŠ£í’Ï”ÿ÷ÔüU1Ú¨y¤·¹\yOnë±bÜÀ¶Óµ—‚{zŠÕ±â±·ŽS™5V>àsQý²OùòŸþúÿŠ£í’Ï”ÿ÷ÔüU%ÑawÒòß’3Ý*½½êÏ&ØîbrYDg g<ð}¡ô§M$ÒÎŽ-eQ”哹_ö½©Š$RÅ- ³œ’YOLœšÓþ<íÿë’ÿ!M±uM:VufQ,„…BÇïžÃ“RÄž\1ÇœìP¹õÀÅElÒÚ#Çöw•K³+#/sžrG­!˜é¦ÂÅŒAcµxY»nßòü¤ЀFz{Õ»Hî-.`Ž'¹y\ ¹F‡÷X`ûzð;Ÿ¥iý²OùòŸþúÿŠ£í’Ï”ÿ÷ÔüU1õB÷VR,qMû™Ð°ÙËe$¨þ.?•;EŽD‚v3LΞbíb0HÀÆH'jo¶Iÿ>SÿßQÿñT}²OùòŸþúÿŠ¡h¯¿ãÜ×Hÿô1TÚô$ÞK\Ä%È<£“ž˜ä{ûJ–æyfˆ"ÚLõl–³ýïjŒ‰ ‡6Œ\e2ëü^Ô%¹%§Éùœ1ü I†Ô®Tô0 ýZnŒŠåÆÛv3œpô¤H/uŒÊ®HR'ÔÞÌCerqåyÒ[ÛG|Û˜Ù‚ÈCËç¡íZÚY{ki^HçešçäÌxl Åp1’ <µkí’Ï”ÿ÷ÔüUl“þ|§ÿ¾£ÿ⩈ʚÚs«:…›-v“+ù6\ØàðÃïÒº ©öÉ?çÊûê?þ*¶Iÿ>SÿßQÿñTt°u-Ö:]‹kKo6â(•¢\CŽgœþ}ªïÛ$ÿŸ)ÿï¨ÿøª¦‘Éöx¢’ÑŸb¯R„dcž¾¢€%ÚKˆ™˜6bb0…xÊv5³ÿQÿ×Õ¿þŽJ±ÈÓyŽ…R  9 öúU}gþ<£ÿ¯«ý”À|Cÿ‘Œ×þfŠ>!ÿÈÆ?ë‚ÿ3EvVŸòðÏÒ?ý&zܬ;Oùxgéþ“=è¹{øc·fÿy\rð€A\—®3ÐñI±£rŠ‚Â_>ÂÞ]Å÷Ä­¹† ÈêE-ÚFöÏç;¤`nfIžªA¦ôÔšŠçZÞøGüô’8‡™wÞH¦5<Žçv8m¤mæþïa^Wfzõ9ÇãÚ¤=ÔWæÞãÍâØ<¦I·‚ùÆáÉÚ´”³Ý˵ek¤Š9<  o‰~CóÆ8ïØšb/ýšÿþ~-ÿïÑÿâ¨û5ÿüü[ÿߣÿÅRjó²ØŸ"L,q»+`¨,ç·õ£E’V‚t”“åLȤ¹~07N #'Ò…¨ –;Ø”3O•xˆ÷ {Þ¤1Ì$›¸CH_+’SÞâ§¾ÿP?ë¬úªO?žÖneÈ!÷.F:`îà{täúšš&b_Ѷœt<üˆ¨Ù¦–äÁnQ ¨fgõ'~Üóœ™:ß"ÒZÿÈRúâŸÍ¨û5ÿüü[ÿߣÿÅQökÿùø·ÿ¿GÿŠªb ‰#Ô­­ç”²Ü&Ã$îF 7$gžž´É$Iôÿ.3sÚ»Ãití™}ÙË(ëÏOJ¿ökÿùø·ÿ¿GÿŠ£ì×ÿóñoÿ~ÿV·”ˆ#:´Á3ŽíŽøúÖ>…=ÃÜD$‘œMj&mÒù²9Áû¹Ë >Z:Ø:\½ökÿùø·ÿ¿GÿЦGç5´SIu b@§æ¹è3»Þ´ë!#Š{;ešÐΫÆv•åFx'üó@WÍŽo*VWÊ–VQŽ„Çâ*¦³ÿQÿ×Õ¿þŽJ°‡ý"%ØÈ'1ÉÆS¾MWÖãÊ?úú·ÿÑÉ@Ä?ùÇýp_æh£âüŒcþ¸/ó4Peiÿ ï ý#ÿÒg­[›+[²¦æÚŠ}Ó$a±ôÍeZÈ;Ã?Hÿô™ër€€)²"KG"«£ 2°È#ЊuöV·% Å´2”ûžda¶ý3Ò‘ìlä¸[‡µ§\bFŒéÏZ±E2X£ž6ŽhÖHØa•ÆAúŠŽ+HRXcTmÊ0lc#ñSÑ@ÞÆÒK•¹’Öq‰Z0Xc§=iðÛA;C q™\¢¸úœu©h /Q¥²e™ß’Ë¥]ÃÞI6Œ„Ÿi*~‡¡©Ý‚!f8P2M@.§` YÜ2žAùF3@I4ˆæ#ج¡v‡R€ôÏ¥,3i0+¬2YF¯Ë„d¾¸ëMûMÏüù\~iÿÅQö›Ÿùò¸üÓÿŠ yt‰"H¤’ɣЏéÚ§þвÿŸËûú¿ãUþÓsÿ>WšñT}¦çþ|®?4ÿ⨷¶­u%Ì,n 9_ð5VÜYÛHÏÛ‰áWÌݰuGažßà*ຜÈÚN‚@,¼Œ÷÷æšu½´ÁGS¹Oè -º”¶…a–5{P[Ih–ÒÛ^´* ŽJLF$pzŽjÐ!€ äjµ9fÛÍ(S‚É€3ø‘H†MU…ìcTmÊ ã¯t÷ef¹µb‡*LŠvžœT?i¹ÿŸ+Í?øª>Ósÿ>WšñTÀÚ4²²)šÏl§2 ˇ>þ´è®ôè#Xḵ¢£¨ð¨¾Ósÿ>WšñT}¦çþ|®?4ÿâ¨o/­ê>b è©8²{¡9¸\Œ‚_•ˆèHîGùè1m®ç\³¸PH%z“ü^µ'›sÿ>²ÿßiÿÅPmNá+ÿ É•>£hÐÓRXíµ$Ö4x”+1ÀÈ'#?Mžb“‚8 õ™%ÁŽAqÉ,˜ÉTÇñ ¼½oÂi¿¼ûüGósž}y¥‘t9R4iΑŒ"°BééNûMÏüù\~iÿÅQö›Ÿùò¸üÓÿŠ  Öš®®³ÚUجrÐ{qI Æ—;C5œeÎ\£(Ü}N:Ó>Ósÿ>WšñT}¦çþ|®?4ÿâ¨Çö…—üþ[ÿßÕÿÈ?d¸´·Y.nˆ£rKµ‡#>‡üóWþÓsÿ>WšñT±ÜO$jém)Vƒ¹yñ íŒm2ù;LQÄWåè9\Ò¢ÖãÊ?úú·ÿÑÉWVw)"Ó4&/™D{'He<úR êRBÒãPŽÛ&-ÉVØ[h÷çê*Î¥tÖ–žd`gT\‚@,@ɯZdšE”·0ܼ™â}þfÅÜçËsëõ¤šÅf†Xä–V8pr3#oˆÏ9¦!š]ãÞA! ñÈP¥AàpyÁ«µ¥ªZDȬîÌÅÝßf=Î0*z©pëäLìDOÉ8R«Ú°Šf/¨ üΨÄ`7û>ƒÛŸÏ9žèâòÿLßù¥U·ûZÈæâuxÀÂm\=[ß· =§üyÛÿ×%þB›cæÿgËä2,žl›K‚@ùÏP§ZÇœõɤÓÐÉa*,d—1õ~”†@u ³¤Y^¯Sš¥ sòóÇ^ù¤“T5²—æ¬xØysùÚû$dþ5/ö8þÏŠÈ_]â*Tâ=ß)»ØŠöLfãÍiç`]ehÉ]¬àñœð8:Sê.„º•ÓZZy‘€]Qr ±$½iº]ãÞA! ñÈP¥AàpyÁ§Íb³C,rK+ 89ŒŒ·ŽÄgœÓí-RÒ&Egvf.îøË1îqB%ïú…ÿ®±ÿèb©»«]‰Æ¢ªDØG|úŸ~ßžmßÿǸÿ®‘ÿèb©¿ÚÍÐ):‹s‚À¯Ì1ؘ>üþ|M ’ᔂ €‚?ÜZK_ù Oÿ\Sùµç-9ÿ¦¿û*Ñmÿ!YÿëŠ6 C4b÷í~[´„A‘»*¤Iç-Ц5«Ÿ&ÃÎe.â'‘T#máAÏ㜠¿“’v¸‘î’v ñΈW ŽÀTi¡ZÃKf’Ü‚ÿ4AA!ÎHéŒt÷ $S”0eÛ»+ÐŒv¬Ý+TšòuI•–96£.ÞŸ)ÏÞûÑÇZ½ªDcî#Ž?,EŸ—sõ⢲Ób²}é$„ r–™ÎÑÓë“ÅC¡v²2²ØÚÇöï³mIØÀ18ëÛÛý:ëÖ0ûQ²¶6’¢0A.T‚©QÃ%ÌÍ"]ÛÆ±8Êá²@ôo~üqùd€IU&k(¤>dÂ'nH2gðTÖĵ¤œ“’L±!,¦›Éi_Í|…saˆqÚÈ|ý?þOþ¿ÿGŸ§ÿÏéÿÀ·ÿâªq©@ð[I ¬²½Êy‰ªî ÆIÉuéÇP·[¿ Âÿ|FdÚ6«‘§œçíŽiˆ­çéÿóúð-ÿøª<ý?þOþ¿ÿZsCi–DÈ(U,IÀñ4–“Åw:ÄP«tp2¬;dP.žü½ÜçéÏþÍKºÃþ{üoñ«×Š¢!@>l}¿ÛÍv.ÀHÛŒ%¾cžàtÀ÷çòäˆF#V6uïQÜý™p󸌎o(0E>— £ %àz|ª™4ȶ©1pHWí’ÙþByúüþŸü þ*?OÿŸÓÿoÿÅU›+û{ÇØºeˆ]@Þ™Æáƒüðy§^ÞCfʦ•ÙYöÆ £©äQïL ž~Ÿÿ?§ÿßÿŠ£ÏÓÿçôÿà[ÿñU©•,k"e`u±?º¿•dùúüþŸü þ*€tð€Àá¸ýk[bu*ÏI.—Oµ[Hãv1©&F€ãŽrÏ¡u¿Ah6x,±üÍVÖãÊ?úú·ÿÑÉVØîºÊlg…‹ŒðW®=2j¦³ÿQÿ×Õ¿þŽJà>!ÿÈÆ?ë‚ÿ3EÿäcõÁ™¢€;+Oùxgéþ“=ZÔm.å¼I­|œ21wÈôé‘Um?ä៤úLõ¹HdV°-µ¬P)%b@€žøª6ÐßÃ=ô­ ±óØ<`NÝB…Áù8éžõ§E7¨–†ØjcK´²1Ú4q®Ù”\0ó;:ãYšÊââþÞc¬^Kç#“&Ür˜Ú8Éõü+RŠdÞ`‰¼•V“(vÚÔàÿ*Äþʺ}&ÞÒk; %Š3‘¥c³ó/ÉœûqÐs[ÔR†t9MÏÎÑRl'÷‡™¸àü«Ç?Z·ºóþ{Áÿ~ÿFëÏùïýø?ü]V¿ÓînŒl¶iÖ"Ž®NÀNå8Ïú«FÖmk r"@€úàb«î¼ÿžð߃ÿÅѺóþ{Áÿ~ÿ@Øê s-ú;§¥Tµ•å••íæ‹ËêÍ+[ýžyÿý|Nñ\I"»ÏUJŒBG\µì)<‰áqþÌX?ú>Óþ<íÿë’ÿ!Iaæ >_%U¤ódÚ¶ƒóžø?Ê¥UŠŠ0ªØTQÇ4„"£1m¯ì×0¤wö-ËÙÚ,ÐÚI-¼-Ö‘Šq‡oPGL~5,z,Ér…š)H’´ÍŸ3*#èJƒœÕýןóÞûðøº7^Ïx?ïÁÿâé€ÛÛ[‹Ëi#o$2ʯ' ƒ†ãŒàŽ3NÒìÚÎ ˆÕ¤¹Hþê àtv£uçü÷ƒþüþ.ןóÞûðøº€I}ÿãþºGÿ¡ŠÏyn„"Þv ‚$6Ð;çž·Ïe[©“cÏ7â؃ýÿjo“?ü÷þýþ*€m÷§ëþ³¹Ïð-$ R¹SÐÀƒõj’(ü¥#vâÇsc'üMhœOçC G+´î]ÀŽÜd:C+iš\Öraháò“a?¼<|ÍÇå^9úÓ¯ôû›£Û-šuˆ£«“°ƒ¹N3Áþª³ºóþ{Áÿ~ÿFëÏùïýø?ü]7¨‹°‹kX`S‘×-RÝyÿ=àÿ¿ÿ‹£uçü÷ƒþüþ.†î.ÖÃglëó‚"‚8È÷íù‘uçü÷ƒþüþ.¡ŽÚhãT¦BŒÄ{À¨ˆqA å1 ¹l§sPë?ñåý}[ÿèä«QBQË»ïlm] Ìú «¬ÿÇ”õõoÿ£’€8ˆò1úà¿ÌÑGÄ?ùÇýp_æh ÊÓþAÞúGÿ¤ÏZ·7¶–{~Õs ¾ï› \ý3YVŸòðÏÒ?ý&z“Wºœ¡îâEŽPd¶ƒÍ ’˜mlg·jC5Õ•Ð:0eaAÈ"¡[ÛGŠIVêŽ#‡q !¡=ªXŽèåŽ@å—ýF `íIßR]—1nGAÍ>¢6¾Õoöo´ý¢/#ów¸úô ^Z›Ÿ³ ˜|ügÊÞ7~]kš¹±Ô¦Òn”²Ç#K(·Fä!0}ÈžGzѺó'¿±'2E"™"ò”89mûFHϯá@òË1´’ºÆŠ2YŽüj)/­"Š9dº#“î;Ho¡ïR\:dz«2’ ÈdšåÌrɦéãʼ„Çjñ3%³ÜBü…Hû§×ºŠC:3¨Ø­À·kËq98òÌ«»?LæŸowmu»ì×M´á¼· ®*„qË-ÍŠKŽ;XD¬%|Â6…¾ïÒ›§î“XžáEÃDÑÝ<&2‡'äP@Èç®ÖŸ[ ¡£w!†ÒiWï"€¨ä·±·Xþ×xѼ Ü”Ü}†GéK¨ÿÈ:çþ¹7ò¦êóbÕ-„2·Ú£J4‚5Ç?t}?úÔ†;ìúwÚ~Íö¶óñŸ+íM»òÎh‚ÛO¸gX.žR‡ é›o×Нv —vin—/亟-á+6Ÿ˜¹œ™ü* )`˜3Å9 l„‘òÈ9Øœ|ï<ôÓ~{KuVžæHƒ÷,¹>œš—û2ßû÷÷ýÿƨj¡æ’ÞäEqå=»®Å‹sÛNÖ\d íê+VÆ7ŠÆÞ9NdHÕXûÍT60Çwn˜«Fă3uqßÜÔvæÎéÝ!7ÀeðãûË“‚3þpFm]qm -ù#=Ò«ÛÞ¬òmŽæ' e”FrqƒÏØúJž2[Å!êè¬UcH%·–êòá£E‘—>qTQéV-?ãÎßþ¹/ò ý›Jšo!ç+4˜±'yÇÅ0é« LפE!Â9»;XûóJ-´ósöavÞ~3å}©·céœÖ[Û²¤s¸ut˜H݇ï©ÆÖ\…8#8üjÔ;šêÊÒx¦_²„f@äI&Ü}à1ÜæšzM>Ö$g’Y‘d³\0~t‘XYÍÉ ÒÈÑ’áˆ?Žiš¡{«)8¦ýÌèXl傲’TÊ¢Ç"A;?™‰&gO1v±$`c$Œ´ b\XCjÊóçÌAÌÌx,ïèiŽlRì[‘q“€\HûTžŠNx'üõ¹}ÿãþºGÿ¡Š¦×¡&òZæ!.@ åœôÀÏ#ߨúPð‚¦X÷¾ÐO\`ëQybêùá‘ÝcŽ5l#É$÷J}¹%§Éùœ1ü E¿ü„î?ëŠ6¤2(cÒçYï1cr—d…ø!ÿÈÆ?ë‚ÿ3EvVŸòðÏÒ?ý&zܬ;Oùxgéþ“=nPEPEPEPEPw1yöÒÅœoR¹ôÍ9.¥TU{9K‚UÓ†XRO(† %#!±ü*5‚ýÔ7ägo–N?Ðßl“þ|§ÿ¾£ÿâ¨ûdŸóå?ýõÿQ}šÿþ~-ÿïÑÿâ¨û5ÿüü[ÿߣÿÅP¿l“þ|§ÿ¾£ÿâ¨ûdŸóå?ýõÿQ}šÿþ~-ÿïÑÿâ¨û5ÿüü[ÿߣÿÅPf’igG²€¨ÊrÉܯû^ÔÅ)b–…YÎI,ƒ'¦N ?˼YÖ'ž™Y²"=ˆÿkÞœs¿Ë¹‚FC†P˜ÁÆp~cŠ’$òáŽ<çb…Ï®*+f–Ñ?³¼ª]™Y{œó’=jXÜI8èê~" ‹íW[ž"Ž0ÅFä,NqÞ€,}²OùòŸþúÿŠ£í’Ï”ÿ÷ÔüUEökÿùø·ÿ¿GÿŠ£ì×ÿóñoÿ~ÿ@ý²OùòŸþúÿŠ£í’Ï”ÿ÷ÔüUEökÿùø·ÿ¿GÿŠ£ì×ÿóñoÿ~ÿ@ÌòÍE´˜êÙ-fûÞÕm¸Êd×ø½©eŽö% ÓÀAe^"=ÈÞ÷© s fîäÊäÔãw¸ ÝËŒ3¶ìg8àéH^4ë•]¤0O©½>&b_Ѷœt<üˆ¨Ù¦–äÁnQ ¨fgõ'~€&ûdŸóå?ýõÿGÛ$ÿŸ)ÿï¨ÿøª‹ì×ÿóñoÿ~ÿGÙ¯ÿçâßþýþ*€%ûdŸóå?ýõÿGÛ$ÿŸ)ÿï¨ÿøª‹ì×ÿóñoÿ~ÿGÙ¯ÿçâßþýþ*€%ûdŸóå?ýõÿTÒ9>ÏRZ3ìUêPŒŒs×ÔTÿf¿ÿŸ‹ûôøªd~s[E4—PÆ$ ~hûžƒ;½èÑ,7˜èP* “’o¥WÖãÊ?úú·ÿÑÉV×ÍŽo*VWÊ–VQŽ„Çâ*¦³ÿQÿ×Õ¿þŽJà>!ÿÈÆ?ë‚ÿ3EÿäcõÁ™¢€;+Oùxgéþ“=I¬,òê0ùƒ,…\¼ãoRœ÷¨í?ä៤úLõ´cFurŠ]rˆäg®)D»"E9ÈrÅ¿SÉúÖí,úœQÜNHº‰#-+óùw•“Èéž+¡ª«¦X!¥²ù£ˆ”oüsLg>·eÅ«™]b33 ºdÆÝ¸O¼Àï~•a§º–×+甸ž?(™¾_,¨Ê”ÏÞêsǵm5…›@5¤$9XÌcjŸaŠpµ·hD'Æ<̓v=3Ö„!ÓÆ&…ã,êuF*9Îî$Óôå3ȳiYüæBXmä·S€IÁëÞºIbŽxÚ9£Y#a†Wê*¦Ø¬"²¶+n"]¡½qŽ´†aùúŒr[\È%2O${q/É´ Ü»3×99ÇãÚ¬h3Ü=ÄBYÄÖ¢fÝ)›#œ»œ°Àãå­‘kn.~Ð ‹Ï#nÁ»™ëD6Ð@ÎÐÃfC—( n>§iˆQÿuÏýroåF®YA*I*2K69Prêq×Zuê4¶S¢ ³!{â’Yt«¸c[Ãi&Ñ“í%OÐô4Éж¯¶šo1[tÿ½c¦:mÎ2xížôÛ öú½Ä#ˆŒBDV¥dÄ·*}‡õ ] L&NŒaÆÍߥ> 4{euìbWûÁ (o®:Ð]fixR)ŠD`’]É)L‘·œŽ¸œt5§c#Ëco$£b è©8²{¡9¸\Œ‚_•ˆèHîGùè0z¹ç8#2t=¾E¦ÂHÔnJŒ‘`~-Kjw _ø^L©õ@þ†š’Çm¨É$ġYŽA9üi ¥¡ÜNÓÇæÊγZ‰œ´¥ðÙó÷z°Àãå©u™¤yáH¦)‚Iw$¥2FÞr:àqÐÕ¸çÒ¢ó<¹l“Ì9}¬ƒw×Ö‘åÒ$‰"’K&އüóH èÒ"]Œbpœe;äÕ}gþ<£ÿ¯«ý•-±¦_'iŠ8Šü½+úTZÏüyGÿ_Vÿú9(€ø‡ÿ#ÿ® üÍ|Cÿ‘Œ×þfŠì­?ä៤úLõ¹XvŸòðÏÒ?ý&z¹{,W)o Cû¶•圪 Ó#××µ!šS"q$Hᕃ(;äqíUõ;§´³2Æ;•K8%Pcì:ÓnŠÄµÌ–>|/nþUÊÃ#m²Ê2¼ñÃg½Lº£>­%·™qG ‹ ìT½«×€rN(VŠŽ7Éo!‘dÇÊ\Ô+0ê7gG²½O 4¦/5Jæå玽ó@ôVmÕíŶ§%£hfl`ÄË´`óægi<}Üf—OÔ%¼¾¹Bа*#ÂyÜÀ–?]¹Æ€4‚!f8P2M@.§` YÜ2žAùF3I¨ÿÈ:çþ¹7ò¦ê7ó[40Û„ÞÑ4„º30Àé’zô†Iö›Ÿùò¸üÓÿŠ£í7?óåqù§ÿV ¸Y¬£¹…xĘôf¨iZ¤×“ªL¨°ùɵvôùN~÷ÞŽ:Ó¶¶ô¹/ÚnçÊãóOþ*´ÜÿÏ•ÇæŸüUhÑ@Âês Ci8b ²ò3ßÜSšiÔöÓNå? 5%ìw‘3°U?$àuJ¯jÂ)˜¾ 'ó:£€ßìún<äÀ!€ äjµ9fÛÍ(S‚É€3ø‘N´ÿ;úä¿ÈSlD¦ÂA‰žt˜gBÀ|ç°#ùÒûMÏüù\~iÿÅQö›Ÿùò¸üÓÿŠ©4«‰î¬„×6,ͱ£B¡—8ž½z÷ª’jÒ¦¤b žBΰ±·@ù·t°ëÔÓë`'ûMÏüù\~iÿÅQö›Ÿùò¸üÓÿŠ­(5®ç\³¸PH%z“ü^µ'›sÿ>²ÿßiÿÅT׿êþºÇÿ¡Š¦î­v'Ѝ\#aóê}û~y±žb“‚8 õ™%ÁŽAqÉ,˜ÉTÇñ¢ %Ã)¸´Ø.¥rÇ êÔ†i¹ÿŸ+Í?øª>Ósÿ>WšñU¨Üj3G=ºHè$Dh_äR{’Fÿ¨ÀÍ\Ó.eº´ó% ì¡Ð®À`cNÂ"ûMÏüù\~iÿÅQö›Ÿùò¸üÓÿЍ$Õ¥MHÄ<…`#cn$ónè9`1ש­Š:\ ï´ÜÿÏ•ÇæŸüU,wɺ[JU€ î^AükB²2²ØÚÇöï³mIØÀ18ëÛÛý:€ZIYܤˆñ¸Ãc‘øU=gþ<£ÿ¯«ý•ed\BD‰!8fN„å*¶³ÿQÿ×Õ¿þŽJà>!ÿÈÆ?ë‚ÿ3EÿäcõÁ™¢€;+Oùxgéþ“=i^X­Ó¤‚Ya•¨xñ§¨äŽjÍ´ÿw†~‘ÿé3Öå!‘Û–öñÁvF¡W>€b–di"dY^"z:c#ó~”ú)î#:]!$´âêá™æ»®ÂÎÙ'*GP:bœt¨À•¦˜ë#&Wkº€3žL:Uú(“!’&E‘£$czc#éGéYÿØÃû:+!}t#‰”«b=ß)¹ØŠÓ¢Ê2i¢iQ®.§š4!„O³i`:œ(>øÎ=©ÖºU•Ü—6ÐGÈD ž0;矠«”S_QçO¹ÿ®müª[›ïR'2Ë)º"*ØÈä8ôò=*‰“OŒìûVÌq´\²øâͶTt(~Xˆ“s^*-6+'Þ’HøA ùiœí>¹eÓ߃w»œàÝ9ÿÙ©wXÏqÿ þ4=¹ËNé¯þÊ´[uIÁèaOæÔø„b1åcgQŽõÏÙ—;ˆÈà6ò‡óRáÂah…ÕÈ?)eÌiœí/Nç&­%£%ºCö©ÎÆ åR@þ ~GÏÓÿçôÿà[ÿñTyúüþŸü þ*˜‹m¦Bןh/& ‰ Y €Ý3œc¾8«µçéÿóúð-ÿøª<ý?þOþ¿ÿ@Œ>Ôl­¤¨Œ#PD‹• ÏäŸP¾~Ÿÿ?§ÿßÿŠ <à0¸n?Z™3ö˜Ã1r!`Xõ<¯5³ÿQÿ×Õ¿þŽJ³oäZ ž ,3UµŸøòþ¾­ÿôrPñþF1ÿ\ùš(ø‡ÿ#ÿ® üÍÙZÈ;Ã?Hÿô™ër°í?ä៤úLõ¹@Q@Q@Q@Q@ïØ­…Ã)Á±ð§OuoaQ‹w”-²% ¸ÉäQïLÔäsÿ\›ùSu>[¦†hVe‰£Û1 à†GOÖÍ1IÊJ2îEU²¿·¼}‰ ¦PH…Ô éœn?Ïš’y!Š+eØmÒ…‰;ò0¶1š§¤érYί(„ypùJcÎ_§ÌÜ *ñÏÖ«©= ]‰ýÕü¨ØŸÝ_ÊE!•do¢À÷OÓê•2\ÌÒ%ݼkŒ®$F÷ïÇ–JÝ€n¢8òß¡#ºzUKY^YY^Þh¼¾¬Ò±¿Ùç‘ïÿ×À›bZÒNII?€¨m¦ŠÚÂ[‰Sq3²à ³ûT!SZÇ¿ýr_ä*²Zµæ”ñ¡]ërΡú²gØã€¿i!ÿÈÆ?ë‚ÿ3EvVŸòðÏÒ?ý&zܬ;Oùxgéþ“=nPEPEPEPEPee£q•aƒô¦¯ÚÑB­ÄD€ZOã†Û¹ 6“J¿y°ü2K[8"Gººt/¹î >Ü@n¼ÿžð߃ÿÅѺóþ{Áÿ~ÿGöe¿÷î?ïûÿE¥Œìë Ì’8p—,vŸCƒÅKºóþ{Áÿ~ÿFëÏùïýø?ü]Ùp~ãþÿ¿øÑý—÷î?ïûÿFñ\I"»ÏUJŒBG\µì)<‰áqþÌX?úÆîãMÓhØfn ®;ûšŽÜÙÝ;¤&á £3¾yrpFÎȵPˆ¨£  =…EsA¸A2*3ÚñîÁ=pC |d·ŠCÕÑXþ"«Ã WËsu4ˆªî2%(ª#±ö¤ןóÞûðøº7^Ïx?ïÁÿâé‘XYÍÉ ÒÈÑ’áˆ?Ži¦ÒÄ\ Ì‚b2#ûKn#×Í0%Ýyÿ=àÿ¿ÿ‹£uçü÷ƒþüþ.ì¸?¿qÿßühþ˃û÷÷ýÿÆ€*ÝL›xq¸7ÄïûS|™ÿç¼÷èÿñT\XCjÊóçÌAÌÌx,ïèiŽlRì[‘q“€\HûTžŠNx'üõ±~R‘»qc¹Ž1“þ@¦´N'ó¡#•Úw.àGn2?, ©–=Å„o´×úÔ^_Ú¯žwXã[ÅrI=ÇÒ€&Ýyÿ=àÿ¿ÿ‹£uçü÷ƒþüþ.¢ŠÒÆvu†æI 8K–;O¡Áâ‰í,mÕZ{™" p ܲäúrh]ןóÞûðøº7^Ïx?ïÁÿâèþÌ·þýÇýÿñ£û.ïÜß÷ÿ7^Ïx?ïÁÿâêí¦Ž5A:aT(ÌG·ü ¦þ˃û÷÷ýÿÆ©æÖ ;y&[™$‘íݘð2pAŸóÅZŠŽ]ß{chÂí~gÐU]gþ<£ÿ¯«ý•f0‰2\´RÆ\e‹t#O®ê­¬ÿÇ”õõoÿ£’€8ˆò1úà¿ÌÑGÄ?ùÇýp_æh ÊÓþAÞúGÿ¤Ï[•‡iÿ ï ý#ÿÒg­Ê(¢Š(¢Š(¢Š(¢Š­¨ÿÈ:çþ¹7òªú¼R`”$ÏÙÞÙ'üùOÿ}GÿÅQöÉ?çÊûê?þ*€è°»‹iùoÉî•^Þõg“lw19,¢33Œx>ÇÐúS¦’igG²€¨ÊrÉܯû^ÔÅ)b–…YÎI,ƒ'¦N MiÿvÿõɪRDòèÌ#Vm·[ÙTd•äàwàt­“ˆ8óŠ>¸¨­š[DxþÎò©vedeîsÎHõ¤zY{ki^HçešçäÌxl Åp1’ <µRkiάêlµÚL¬äØrwcƒÃ g¿JÕûdŸóå?ýõÿGÛ$ÿŸ)ÿï¨ÿøª}@·ETûdŸóå?ýõÿGÛ$ÿŸ)ÿï¨ÿøªu÷ü{úéþ†*›^„›Ék˜„¹'”rsÓ<céRÜÏ,Ñ[IÞ­’Ñö`½íQ‘!pæÑ‹€@l¦@=‹Ú€$·$´ù Ÿ3’?i!ê7!N 0§[£"¹q†vÝŒçý)’ Æc2« R€F õ w¥¸Ê,3C2;Ç8Zˆäߘò¯wBsÏÞëOÕCÍ%½ÈŠãÊ{w]‹æ¶¬¸8ÈÛÔVÛ$ÿŸ)ÿï¨ÿøª>Ù'üùOÿ}GÿÅSz‰hIcÅco§2$j¬}À槪Ÿl“þ|§ÿ¾£ÿâ¨ûdŸóå?ýõÿCww¬[¬t»Ö–ÞmÄQ+D¸.‡(Ï9üûUß¶Iÿ>SÿßQÿñUM#“ìñE%£>Å^¥ÈÇ=}EK´—30lÄÄa ñ”ìj gþ<£ÿ¯«ý•b%‘¦ó ¥@$rAíôªúÏüyGÿ_Vÿú9(€ø‡ÿ#ÿ® üÍ|Cÿ‘Œ×þfŠì­?ä៤úLõ¥{¨ÚØÅ˰iI©98ëƒY¶ŸòðÏÒ?ý&zÄr$:ž•$—†Í—3|¿/ËþÐ#šCEó­Z´vò[·œ³\8ùJ1ÏPy:Vqp¾ÌMæ4öË©Ç'ÛHó2¤{` Œ U‰¦Ö%W¶ö×Âï1ù‘7šSwÊ·cic´×õø ÿ_‰ÙÕmFñl,Úå¸R£ú?­s[B–÷šŠ qjxY‡Þǘ£ôÁÀçÚÓþú?üM`?óíiÿ}þ&€/î¢ÃÔU°ùö´ÿ¾ÿGØüûZßGÿ‰  û‡¨£põCìþ}­?ï£ÿÄÑöÿ>ÖŸ÷Ñÿâhþáê(Ü=EPûÿŸkOûèÿñ4}€ÿϵ§ýôøš¿¸zŠ7QT>ÀçÚÓþú?üM`?óíiÿ}þ&€/î¢ÃÔU°ùö´ÿ¾ÿGØüûZßGÿ‰  Aèj ËÈ,bÜ>Å'h–$ú94Û;cnÒ±H8P3ž™ç õ¨uN=*ËÏ}»™„q‡m«¸úžÃ¹  ^Á¬Mè¸_ 6ÒØ9 œcÎ}±š­{yo}¦G-´Óívêx ‚&N<ƒõ¬³öXí-.㺎í#¾óï%‹• TŒàt#ð©…À¿»‡&Ú}B×Êl`>0X{g¿µ?ëòËüCÿ‘Œ×þfŠ>!ÿÈÆ?ë‚ÿ3EvVŸòðÏÒ?ý&zܬ;Oùxgéþ“=ma¿¾?ïþ½:Šnûãþøÿëцþøÿ¾?úôê)¸oïûãÿ¯FûãþøÿëШ¦á¿¾?ïþ½oïûãÿ¯@¢›†þøÿ¾?úôa¿¾?ïþ½:Šnûãþøÿëцþøÿ¾?úô³¶$“o'ýGØ­çÞ/ûàT¸oïûãÿ¯FûãþøÿëÐií §Spßß÷Çÿ^Œ7÷Çýñÿ× QMÃ|ßýz0ßß÷Çÿ^€E7 ýñÿ|õèÃ|ßýzuÜ7÷Çýñÿ×£ ýñÿ|õèÔSpßß÷Çÿ^Œ7÷Çýñÿ× QMÃ|ßýz0ßß÷Çÿ^€E7 ýñÿ|õèÃ|ßýzuÜ7÷Çýñÿ×£ ýñÿ|õèÔSpßß÷Çÿ^Œ7÷Çýñÿ× QMÃ|ßýz0ßß÷Çÿ^€T5Ÿøòþ¾­ÿôrUÜ7÷Çýñÿת:À"Ê<°?éVý?å²{ÐñþF1ÿ\ùš(ø‡ÿ#ÿ® üÍÙZÈ;Ã?Hÿô™ër°í?ä៤úLõ¹@Q@Q@Q@Q@Q@Fòû6‘ñœ.8IM·ÿÉÿëš6 îŸþ}%ÿ¾“ÿŠ£tÿóé/ýôŸüUBþ Ó#á{†SùnÆ'­è_ZÒÍSÝ?üúKÿ}'ÿFéÿçÒ_ûé?øª¹š3@÷Oÿ>’ÿßIÿÅRÇ 8*zƒRÚÝÃv²X‘dcæ?ãêëýñÿ ­HÌK1À$ÔbIX[YJž‡*?™¤¼ÿ)ÿë›*šúþÛN…eºrˆÌv£1,z&‘îŸþ}%ÿ¾“ÿŠ£tÿóé/ýôŸüU-–§g~\[LÓï#)V_ª«y E=ÓÿϤ¿÷ÒñTnŸþ}%ÿ¾“ÿŠ«™£4R97–R¬Ž½UºÓê7ÿƒÿ×%þmR†€"Y]Æè­ätìÀ¨ó4»§ÿŸIï¤ÿâªKWXôØ]Ø*,*Y˜à޵žµa}0ŠÚfv |· Àz1? îŸþ}%ÿ¾“ÿŠ£tÿóé/ýôŸüU\Í  {§ÿŸIï¤ÿâ¨Ý?üúKÿ}'ÿW3Uu;á§X½Ó!p…FÐqœ?­4JC„’'Œ·Ý݃ŸÈš©¬ÿÇ”õõoÿ£’®Þýëoúëÿ²µRÖãÊ?úú·ÿÑÉ@Ä?ùÇýp_æh£âüŒcþ¸/ó4Peiÿ ï ý#ÿÒg­Êôÿw†~‘ÿé3ÖåQEQEQEQEQE'“¸ŸÍªJ®Ò,7NÒ0UtPœ ‚Æ€9yÅóXë?°µì‚áV2e Æâ§8éÛ´ÝIR}Nán/míãdìRͱ ´sç¶k¬ûe¿ü÷‹þû}²ßþ{Åÿ}ŠÎ~W·µñ";½½ýÌ’" ùРezü½ÏN½j¢ÆÓk2ýªöÞÚø^f?2'óJnùB¶ìm#Œc×5Õý²ßþ{Åÿ}Š>Ùoÿ=âÿ¾ÅV1ô°Eª_$‰êFæV\HPœƒŸLVÄG77'ý±ÿ ­l·ÿžñßb’Øïy¤uÜ>¼ý(¢ÞÇ”ÿõÍ¿•PñDé 6Êá#Žú&f<9äÖ…Ò—µ•Td²áMûm¹äÌ‹ìX(…s&§¨­³›{I”΋…f`6¨=È#>ÔÍ)¬Æ§aý‘»w”ßmëýÞ7çø·~=k¡ûe¿ü÷‹þû}²ßþ{Åÿ}Šrúe¼vÖš-í²ºžvŽWd? ëÐStËê¯-í¼Z‚;âòœO'\†%°GqÆ8®«í–ÿóÞ/ûìQöËùïýö(¸=E'7ò×%þmRž†«ÂÂ[©$C¹6*î Éÿ°zPN³ ×>1@†Fò£b‹ÕÔ`‘ø€iÒx†Â[…›­ÄÉ 0¶†8ÇjÞæ(íãŽI)Vl@ÅIöËùïýö)t°ÎFÂTVÔŤ¶†'Ó™ÙlÔª+óÔ~oʬýœØ Oì˜ü™îtéKøÞáT©Ç®IçÞº_¶[ÿÏx¿ï±GÛ-ÿç¼_÷اý~æ/ëòÿ#›w±ÿ„zàh„ Ã}£hc.ÜÛ»ç÷ªíK£ê2ÙÞZÍ"- ¬Lª„8%°XóŽ¿Jë>Ùoÿ=âÿ¾Ål·ÿžñßb‹ëp°\H²ý‘у+H#¸ÚÕ[Yÿ(ÿëêßÿG%Jò¤óB"u}¯¸í9ÀÁÖ¢ÖãÊ?úú·ÿÑÉ@Ä?ùÇýp_æh£âüŒcþ¸/ó4Peiÿ ï ý#ÿÒg­Êçãžm'ÃrÜJ‘F¢<»°P?Ñœu5£ý·¤ÿÐRËÿühýCûoIÿ ¥—þ'øÑý·¤ÿÐRËÿühýCûoIÿ ¥—þ'øÑý·¤ÿÐRËÿühýCûoIÿ ¥—þ'øÑý·¤ÿÐRËÿühýCûoIÿ ¥—þ'øÑý·¤ÿÐRËÿühýCûoIÿ ¥—þ'øÑý·¤ÿÐRËÿühýÖ¨mé?ô²ÿÀ„ÿ?¶ôŸú YàB^Ú=åFÑè?*£ý·¤ÿÐRËÿühþÛÒè)eÿ þ4{hô•G üªöÞ“ÿAK/üOñ£ûoIÿ ¥—þ'øÐí£Ð~TµCûoIÿ ¥—þ'øÑý·¤ÿÐRËÿühý&Ñè*öÞ“ÿAK/üOñ£ûoIÿ ¥—þ'øÐí£Ð~Tmƒòª?ÛzOý,¿ð!?Æí½'þ‚–_øŸã@¶AùQ´zʨÿmé?ô²ÿÀ„ÿ?¶ôŸú YàB_(ªÛzOý,¿ð!?Æí½'þ‚–_øŸã@°P(Ú=åT¶ôŸú YàBÛzOý,¿ð!?Æ€/mƒò£hô•QþÛÒè)eÿ þ4mé?ô²ÿÀ„ÿ½´zÊ£Ð~UGûoIÿ ¥—þ'øÑý·¤ÿÐRËÿühðt¨k ¤`ÿ0wç‰ÐPu½+?ò³ê:\'øÕ]GU°¹‚`¿·–F¹ƒ“£ûä=ÏOÓ­qÿäcõÁ™¢ˆò1úà¿ÌÑ@º,m4Û[g´¸f†Œ‘·ªëíV?áaØÏÏþ;þ4Q@ü,;ùó¹ÿÇÆøXvóçsÿŽÿPÿ Ãþ|îñßñ£þ‡üùÜÿã¿ãEÂðÿŸ;Ÿüwühÿ…‡aÿ>w?øïøÑEð°ì?çÎçÿÿ?áaØÏÏþ;þ4Q@ü,;ùó¹ÿÇÆøXvóçsÿŽÿPÿ Ãþ|îñßñ£þ‡üùÜÿã¿ãEÂðÿŸ;Ÿüwühÿ…‡aÿ>w?øïøÑEð°ì?çÎçÿÿ?áaØÏÏþ;þ4Q@ü,;ùó¹ÿÇÆøXvóçsÿŽÿPÿ Ãþ|îñßñ£þ‡üùÜÿã¿ãEÂðÿŸ;Ÿüwühÿ…‡aÿ>w?øïøÑEð°ì?çÎçÿÿ?áaØÏÏþ;þ4Q@ü,;ùó¹ÿÇÆøXvóçsÿŽÿPÿ Ãþ|îñßñ£þ‡üùÜÿã¿ãEÂðÿŸ;Ÿüwühÿ…‡aÿ>w?øïøÑEð°ì?çÎçÿÿ?áaØÏÏþ;þ4Q@ü,;ùó¹ÿÇÆøXvóçsÿŽÿP%â^kTpFñ¯–«ã9ú}h¢ŠÿÙfotoxx-12.01.2/doc/images/user-settings.jpg0000664000175000017500000004330311701011016017165 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 414 430 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ7C"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?èôÝ:Å´»2Ö6¤˜#$˜T’vj’+]2Y$lmCÆpÊmÔèzt>µ.—ÿ «/ú÷ÿAVú7¿Ÿe›ùRC•{Û?Áïïéõ  bµÓ&’DŽÆÕ¼³†o³®3éœu¨5Oì­.Ùg›LŠ@Î,VÈÌN éøUË #0ù+ðü­÷}ýÁõïM¾`—6 Ä(žIÇü²’€9ÿíýÌ üJÞK->Ku™,-pÈfèF}*Ä×ù/ûåû§øª+?ù[ÿ׺ÿè"€)yVŸô²ÿÀu£Ê´ÿ }—þ­74fº93Ê´ÿ }—þ­U§ýì¿ði3FhäAÌÅò­?èeÿ€ëG•iÿ@û/üZnh͈9˜ï.Óþö_ø´yvŸô²ÿÀu¦æŒÑȃ™Žòí?ècÿ€ëG—iÿ@û/üZni3G"f;Ë´ÿ }þ­]§ýìði»¨Íˆ9˜®¶h…šÂÄ*Œ’`^Cö3þ}tÿûð´÷ £‚9¥^1i¥ÉÅ—_ö*eËÐ×3êW‚k‘˜tëÎD ŠG†Ù«iÖ Ž¿¸Z–Í‚É(F„FIùXáHÉéV¢’Ú6”DS;‡Þl=4Yvßr‘o…?Ù¶X»þ޼ÒýžßçO°RAjÉLì‘UÉdÈÏ\ñK4 µÁi£pÉò`^”Yv ù”vZÿÐ>ÇÿÖ–¿ô±ÿÀu­ '…·+eR…@Æ}ñK; ±1(ÃÍ8Ü6€1Ò‹.»îglµÿ }þ­-ècÿ€ëS_º´à¬ò¼àƒlŠ­š¥ÖÂrh~Ë_úØÿà:Ѳ×þö?øµhÍ>D.fI¶×þö?ø´›mècÿ€ëLÍ£‘3¶×þö?ø´mµÿ }þ­34™£‘vfI¶×þö?ø´mµÿ }þ­Gš3G"ìÌ“m¯ýìðhůýìðj<Ñš|‹°s2h£´yQŸc†`-Ö´?³´óŸô N8ÿP¿áY¶Çý&/÷Çó­¥þ/÷¿ ¬j$ž†w<·Å1Gˆ®Ò8Ѫ€Ê; )Þ-ÿ‘–óýåÿÐE™ggvÑYXA´Ó»Z#þì QüL=jqup:i—#þÿU´Ï¿aÿ`õÿÙ+V€)ýªã9þ̹ÏûðÿñtÙ&’UÛ.‘<‹×Бú½^¢€36Gÿ@ÿ¾`ÿâêf¹œ¡_ìË Çøý]¢€2<©çÂóþû‡ÿ‹¤ò¥ÿŸ Ïûêþ.¶(ªç¹QåKÿ>Ÿ÷Ô?ü]T¿óáyÿ}CÿÅÖÅsÈ\¨ÇòeÿŸ Ïûêþ.&_ùð¼ÿ¾¡ÿâëbŠ9ä¨ÇòeÿŸ Ïûêþ.&_ùð¼ÿ¾¡ÿâëbŠ9ä¨ÇòeÿŸ Ïûêþ.&_ùð¼ÿ¾¡ÿâëbŠ9äˆÇòeÿŸ Ïûêþ."_ùð¼ÿ¾¡ÿâëbŠ9åÜ9äKÿ>Ÿ÷Ô?ü]/“/üøÞßPÿñu±EòîˆÆò%ÿŸ Ïûêþ."_ùð¼ÿ¾¡ÿâëfŠ9åÜ9äKÿ>Ÿ÷Ô?ü]D¿óáyÿ}CÿÅÖÍs˸r#C0 ‹ÀGûpÿñtéæR –wÌG«Âöz×¢Žy*1¾Ï/üøÞßPÿñt}ž_ùñ¼ÿ¾¡ÿâëfŠ=¤»‡$Lo³Ëÿ>7Ÿ÷Ô?ü]'ÙåÿŸÏûêþ.¶¨£ÚK¸rDÅû<¿óãyÿ}CÿÅÑöyçÆóþú‡ÿ‹­ª)ûIwH˜¿g—þ|o?ï¨øº>Ï/üøÞßPÿñuµEÒ]Ã’&/Ù¥ÿŸÏûêþ.³Kÿ>7Ÿ÷Ô?ü]mQG´—p䉋öiçÆóþú‡ÿ‹£ìÒÿÏçýõÿ[TQí%Ü9"cÇ ±È®,/ R7CÿÅÕ§¿’% .ŸrˆXÅ¢8É<>jõSÕ?ãÄÿ¿þ†*\›Üi%±ç^-ÿ‘–÷ýåÿÐEx»þFkß÷—ÿARÞiŸ~ÃþÁëÿ²U÷»¶Žu‚Kˆ’gû±³€ÍôCLûöö_ý’£»Žhµ_6Ê Œ’´b]у(=wuR€5¢‘&Œ{ìfÈËÊ öéëRÚX]L¨nÒC"ت)vƒ±gìïCŒõÆN?LRZ+±žîÒÖ)¢dfΙ‘ŸÏlõ#±jôZß‘›P…`y¶›¨Ê¹A·8'hPsíL’’°P½}dÀ—0ˆ•”*;eB –nIÎzqÒ©MwxúlF{Ça4QÎϱTʼnW8Àéƒß=(­¦´ˆŸ}Õy“ŽOJÆÕ”Ü®˜Ê³¬’ŸÛ ØÜ¸ý*µàò&x˜"¤&Ô£óœòyÇÖ€:J+™‹QÔ¥’ï7v°”Œ‹ q· {’G5m¯'¸ðܳ[É3Ê2¬øRØæ+´`ñœH ºcËg"/¾fÔ×>Ú……¬W ¦»`,yfÜbG%²¹ÅSžê[»%–vW‘­.P2ò :c¯ ·¶Ëmcö”‘ñ+•$'ÍŒgøxÁϽmÄI·$õÁõ8?–)-ÊÙK¨C¥. ­0E¶fs<Þ`‘û¹8ý*åíö¡ow¤O¸ˆI½Â¨“ŒrÃ{dóL ê+›¾Ô®š;«VT/m¹¦ÊðT‘åþ`ÿ㦭i\híó"*n¿Ù¶üûqùÏãÓ  ª+ž½ÜÖöâ !3´Òµ•Ôc“ÁÁ<õbâñ¦Ñ­®"™òóÆ¥ñ°ŸÞ`ŒÄPÍÎý¿RwÊÜĪþyþYÀ{ÓÛZ™¯,Ä_vO$J…FñžsßÓ¿Es2k—q§œ$ŠBñJÞ@^b*À œûóÒ¯Ào¯´»¤yBË’!–6ôgi sïÒ€5ê ­bžXä“syg*»ŽÜö$w¬)/ä¾´¸½\ˆ¢Ž8¼¶'a`_#Ôp?:—ûGS¸½¹ŽÜF¢7’0·#å=rrqÛ4¿Esqk÷7 `¬¸’·’Š |€?-õk÷´ÈЪJcS´ˆ·r¾(£‡4µ— î6·;¥ŸµIó€ÜŠÔ Š( Š( Š( Š( ©êŸñâßÿCr©êŸñâßÿCç^.ÿ‘š÷ýåÿÐEx»þFkß÷—ÿAPy¦}ûû¯þÉZµ•¦}ûû¯þÉZ´QEQEQEQEQEÆŠ7l²)>âQÛÀ—´’³–ÜG FÜ"b`œžF}pHñÆiÿ-<¿/bìÆ6ãŒ})$Š)vù‘£í9]ʵqÿm¼:pûDÒ•¸´v˺¶æ9åxÏZÙm^UÔ„ªÉ,›¶µÂnÆsÏä>´À×1£nÜŠw}ì¨çëG—›æì_3ß´nǦkš»Õ.ÚÎ#qHÄAr‹n¤ —œšÒ¹¼œèi|’¦àRV1}Ý»†á϶h@ÚÛ±rÖð’ÿ|˜ÇÍõõ§ùi°&ÅÚ¸Âí…`ǪÝ\ÝGà‚âád·*9h9ÿÐ&‰ª^%¢´Go-É71m²€sÇZßòãÿžißøG~´†K«˜c.ƒ ÛWè{V·×w–Î4·KÑ–3æ)9'8Ç=1NMbõáY-ÜÏ’Ä‹œ¦ßányÏN1ƒ@0iCz÷ežI˜Ëíàdpz¹«QÅ+¶(Ò5ÎpŠý+Ï\{ËÕ†(Ód’sóDîoûècñ·@ òãÚWËM¤ä£úÑåGæù¾Zy˜Æý£v>´ú(‹)QAÆã=i¨p°ÆŸ>o¯­IE i‰tUÊŸEÀ(¢Š(¢Š(¢Š(¢Š*ž©ÿ'ýøÿô1W*ž©ÿ'ýøÿô1@uâïù¯Þ_ýQG‹¿äf½ÿyôEwšgß°ÿ°zÿì•«YZgß°ÿ°zÿì•«@Q@Q@Q@Q@Q@´1±$¯'®Œý@ëøÓð1ŒqéQÁÚc2¼Ž b+`.?Æ–6-ârFF}pHÏéHbÓ¬¡ "³·@ãkmŒ CNk/š¶°‰ÆñÎ1Ž¿JÄŽþö>Êæk£p.Õƒ!ER§k©p1ß5e5i’ÞiLJaµµI\–%Ø”Ï{SSì¶ÿ/î"ù ò9} 8A‰¢ ó¹6ŒõÈ÷¬˜µ{¹8Í I¥$e÷"©byñJS¨]ÛË©I0á¶ òr @p=²{Р·„4l!Œ4K¶3´e ô Ain¨·‹J°}ÒrGКÍ}Vê6kw‚´‰bA‡%0ùÁÎ3Æ Jš”¿nOyþpS‚q³fíÃñâ€.}ŽÔγýš9zI°n,v¶ðÈòEHò}öT·Ö³ÜÒIus-á¶·¶ŸÊòÒ0ÙéËdÎîØ¨oµ‡u¾·@6ùå@ÃÉ?íH ¨í ˆ©ŠТ”Rª9ÀöÍK\ðÔå³’àižIâŽ0C0\Âð=Jµ¥{<›ÑÖßÍts–nþ´Ø#^Š£¦êP22(*¡ žK0ɇz€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ §ªljÿ~?ý Uʧªljÿ~?ý Px»þFkß÷—ÿAQâïù¯Þ_ýQ@æ™÷ì?ì¿û%jÖV™÷ì?ì¿û%jÐEPEPEPEPEPyL¾_+PhjÝ P¢hÀRÛÇüÞѦ?6¦\ê±[¬­°•†T‰Øœ ±Ë"€(Áo£ÛçÊXW*S%Éž dð>•26º«B¨FÈ*üªáÔ¬Ä 9|¶b£ƒ’GQ޹¦Ë«ØDT=Ê êq“sƒÇÐÐ’-̺ò·Úd't ç#ð§yzW™¿÷%Šyg.Nåé‚3ÏãZ'P´YÖ:ïl`}zsïLKðoVÚKy¢gݱœ.z:£zT(?%@q ù²w‡9íMˆZ®¥%ô—Q<¥<´À µ3œu99ïZ2j6ðÉ2ÈJ¬!w¹(,x_¯OÌSU´6s\Ã*ȱ œŽœg޽Rž&â:Q IÆ[qÇLàóøÐ°é+,’éùŽï½Æp3Þµ'»‚Ù§.ÿº$Ÿ škê‘Éo:†£ØôϦ}è5¡ÒBCmÏÌsòŒœõ¿Zzµ”@›y¢Ž_/ËW$¶ÉçžIïZRܤwÁµšIs€¿ÂäŸnƒñ깑Ø$víµ˜çŽäcŽ´COû…¹‰.#bÎÒ; ÌÇ$ãµYûm·ü÷þú©cÕ,¥äŽpË7`Œð8Ǩ4æÔ¬Ö˜Î»Š©ÁÉ#¨Ç^1@}¶Ûþ{Çÿ}QöÛoùïýõS6§d±Äæá6Ê»ú¯¯°÷© 帹þ`2ñò€N3Ó'   ¿m¶ÿžñÿßT}¶Ûþ{Çÿ}U§º.Öß±C#0 zÔQj–S+´s«Ô;`èh/¶ÛÏxÿïª>Ûmÿ=ãÿ¾©×:šÇb÷vÊ“¬m‡ŠúyT·wOm5²ˆ•£šAmø*H=±ÏOZƒí¶ßóÞ?ûê§ C# Ó¦¾µ‚u†Y•dlp{gŸLûÕWâÆlqƒ.?裂 >ÑüõOδCÿ=Só¥¼Ô ²•!t•¸X£-…Éãê*Hµ IŒb;˜‹J‚D]ãqR3œu ¾ÑüõOδCÿ=Só©ã¼¶•CGs«6ÀUÁ½>¾Ô{j‰½îaUÁ;‹€88?•Cöˆçª~u[R‘$±bŒGÐÿ¶*ù½µU‰Ì Mþ¬—?ÓÖ¨k=éþŒçž.ÿ‘š÷ýåÿÐEx»þFkß÷—ÿAPy¦}ûû¯þÉZµ•¦}ûû¯þÉZ´QEQEQEQEQE ÍÑ…CH!] œrؤþÍ?ÙðÛÒE•ܼÁ·1üNiΩæó 9ʶ ¾[Ïy¿ï¯þµ@tÉ’o´C,~håPêJá€Ê¡M £pBªƒ•êFüþ¯úUß-¿ç¼ß÷×ÿZ-¿ç¼ß÷×ÿZ€*E¢˜®æŠ3ù² €8ÁÇð޵<·‘ÞËs3C1`Bc ªöQØ{š“Ëoùï7ýõÿÖ£Ëoùï7ýõÿÖ ÓNs`‘ÈàNÓ,ò·PX0båP "xìn-ã–2fˆDK€0A?­[(@$Ï(¾áþÕó*ÜÈÅNwæ€KK–kyÕá[ˆU“„~ ð*+­.k‰%ýôa.Uÿ)ÏËý߯½XòÛþ{Íÿ}õ¨òÛþ{Íÿ}õ¨ÖÖò}¶âê`760v ÿ“ùUS§]H·«+ÂÑ •ÏÊ@úU-¿ç¼ß÷×ÿZ-¿ç¼ß÷×ÿZ€*ÿc̾iK€ œàddyŒø$süX¨?³æÓ’9£mò‰d`&q‡Œ{kGËoùï7ýõÿÖ£Ëoùï7ýõÿÖ  è4IEµ©a[,2¤™#ŒŸá>殾Ÿ)Ô#ž7H‘JîÙ¸cgTž[Ïy¿ï¯þµ[Ïy¿ï¯þµ ŠÉ¤Šñ®x’ë*vœíLa@ü9ú“Yö¶w—&rÎbýÄp£ùmv±'ƒÏN2=x­/-¿ç¼ß÷×ÿZ-¿ç¼ß÷×ÿZ€+G£¸²¾¥Pn[rí„àÔäô«7VÓÜÛÀwÆ·H$¤ŒñëÐÑå·ü÷›þúÿëQå·ü÷›þúÿëP{%¥½yÿrâ`¾bÈàL{ÿÇŒÿYô6©|¶ÿžÓß_ýj_-|¯/.Ågk|·—ÑL‘E2,O#ÊÑõ#ž=*+mt±¼·–d/=ºB²Ó GåÍiùRÏvÿ¾ETŸóÝ¿ï‘Gm¥Ý¼sʼEå$dì œ‚N;ç:T1h2ñ±IÑBùÌ(A,›88;†EmyRÏvÿ¾ETŸóÝ¿ï‘@óè÷W —L—ÁäÊ¢Sñ‘ÏžJ½ªŸ‘‡ ÿF µåIÿ=ÛþùWQ‹e›³9v/ÉôÞ(ϼ]ÿ#5ïûËÿ Š(ñwüŒ×¿ï/þ‚( óLûöö_ý’µk+Lûöö_ý’µh¢Š(¢Š(¢Š(¢Š(¢Š(e·h¥3„.ù…û ñøb–,ý˜uèqž¸ÉÇéŠIXB¬ig€2£êhó'ÿŸ9¿4ÿâ©ÌÃuzºtfÉ"ZDûB«n,ääÐU‹½JæÚÞhZé¼Ä¸hÖv(ƒC ÇiñÀæ·üÛùóŸþúOþ*6àt´ŸþúOþ*˜åίt"ÞïìÎa…ãŒ"âbÇæêOAVô›ÛëRDžxB©pÖû¾tÁÂ6ƒù“œÕùíÌ«$ÖwM´ƒ·ÍI#+»¬ù·þ\æÿ¾“ÿŠ v;w[=Zð¬$«\…b¤¿õãؤ¸¼¸µ’ëÈuˆÉq™#¡Â9ÎÒÈÆq]›?üùÍÿ}'ÿG›qÿ>“ÿßIÿÅPZkÍ&Ÿ Ï$rÈW%ã9Vô#üªÕCæOÿ>sßIÿÅQæOÿ>s~iÿÅPÔT>dÿóç7æŸüUdÿóç7æŸüUMECæOÿ>s~iÿÅQæOÿ>s~iÿÅPÔT>dÿóç7æŸüUdÿóç7æŸüUMECæOÿ>s~iÿÅQæOÿ>s~iÿÅPÔT>dÿóç7æŸüUdÿóç7æŸüUMECæOÿ>s~iÿÅSÄŠbó9 ‚N{c­>ŠféHȶ“UÖŒÍÿ>ÒßKþ4ú)™›þ}¤ÿ¾—ühÌßóí'ýô¿ã@ªz§üxŸ÷ãÿÐÅYÌßóí'ýô¿ãU5'&Í•‘‘ƒÆpØé¼zPžx»þFkß÷—ÿAQâïù¯Þ_ýQ@æ™÷ì?ì¿û%jÖV™÷ì?ì¿û%jÐEPEPEPEPEP-¿ãþúæŸÍª­Î¥8‚Y @c[„‰02_æ¿\¦Ugº¹D-Þ ØÎ9n Š›ìý’nDq+ƒÎTä~¢€ °eEKiZv‘£òr2 ŒžsŒcBúüCg•m4Ð6F ÝÁÉëò²ú\,K+ËžkJ$FRF8Æ1H4{E :…UPznÿâÍBuûOµ,’Jw( °|¹Éê: •.®—T[iD.ެ߻4`tÝž¹ü)ñé±Ã*¼3MÂîEa‡ÚñèLRA¦ýžieŠêrÒ’Å_i=;gŽÜÐ%ÔÚ7¸q’!]¿yä'¯­Eý±çi·7A*4QïÁÚN<õÇcÅ[O‰l¢¶%˜#+–îÌvOÔóQ"³IK4i*r¥I*3Ç úгÞù- IÍ4 •UÀàu$ž;ŠŠ}Y ‘• ¬A Ì1ˆ÷tÏ<þ#éêéë‰üز`T0¨é‚? lÚTI½Þ^B‰7íé»ÿ­Š’[—û|V±IRò“ü+Ð~$ÿ#Ph˜ã¿–XÜý™ÀØ1ž€ðsïÞ­[ÛfžfmòLÙ'ðþ¦«)?Ò—3È·È`ÉàÂŽÀPQkI$S³[¼f,dHê¹ùŠžsŽ šXµ¨§Š&·‰æ’FuØŒ§zœçéùÓÎlwÒ+ •!Ë‚8ÇV=j)ô’‘/ÙŒÂVÈòí?0ù¹ zñÆ?*cøŠÕ"…ÊeˆMµTªŸ©äðxiu8ßPû"¡'î,g€NOáQÛé ½º,òÇ,Q™â8Þcœ÷Ï¿5<¶ÍuÒK+Ø2ÆHÚwéŸÖ€[Ý—’GÇ“FIŸÓÐÀPÇ«‡ówÛIHVl;(Ê’qÎp:w«Y$pÌ’5§fi Ýž1ôðªº+;íŽHxÒ4 !r¡I ä¨ïŽÇ§9 ŸV7\÷6ryonà0\œddcžÕoPšh'³1É…’a®È ÿ…KƒÈ¹ŠG’Ars#3rNÈÇN‚Ÿ5’ÏmRM)hØ:Ë0èzcô  ÷zݵ¥á¶nYvïù”ž˜äþ?üxÏõ—ÿCjìÏç¬óFì“c$ÇLñü±P1Í„ÄršG¸,Ô¯­fÜÇËž6´×PàŽ'š|:ݼ‰¹ã–0°¬Ò³/Ë+œëI{d×7iqÉ…Õ>0 {ý*+}Ú Yíƒ;EÇñ ‡’’«;«î µrI ù‘P¶$‚užêY&™U|ìSo+€8È<Ò&‹+8‚M¢UUÐ:¨F®2hÝεkk°L%VdóvdƹÆ[Óÿ¬j-`‚¬AÏÿèÁUƇ ˜&;âË&HÕ÷.r:ôêzTÚ¡Ê?·—ÿ£y÷‹¿äf½ÿyôE.ÿ‘š÷ýåÿÐEÞiŸ~ÃþÁëÿ²V­eiŸ~ÃþÁëÿ²T÷š[Ý­³[ܳ¾v•!±×ñ  ÔTÝÛKæyW?—÷ö¸;~¾• š”`x'I¦nÁœ÷J»ERÓõKkû1%Œ0¼~`%$séÒ¤þвû?Ú>Ùoäço™æ®Üúg8ÍY¢ª\ê[Ë[%–I²¬HXíþœŠHõ;7¸–ÜÏK(ìɈrŠ©öø¾ÞmAS¶6w}à AN¹© ¸†æ?2ÞhåLãr0aŸ¨  h¤bK€9&¢óŸ`‘¡uˆÿÇÔŠ{ǃFŽfP3ì¶ßóíýû_𥹛ìð™ rHðƹ5ZßVµšæw6é.<¿? ¿>™<вÛÏ´?÷í²ÛÏ´?÷í›%í´hÌfC·wʬ %FHǨ¥´º‚öÝg·‘$FåX{w û-·üûCÿ~×ü(û-·üûCÿ~×ü*Zªoã„ã,2«¼naê9"€%û-·üûCÿ~×ü(û-·üûCÿ~×ü)g ¶’áÏîãBäŽx4Õ¼¶2$~|bW]Ë`޹ÇZ_²ÛÏ´?÷í²ÛÏ´?÷í˜/ìÚ™nà1Fpî$TûœñGÛìöFÿkƒl§·˜0çÐsÍ?ì¶ßóíýû_ð£ì¶ßóíýû_ð©©’H#\I'¤Ð>Ëmÿ>Ðÿßµÿ >Ëmÿ>Ðÿßµÿ pwXš2ßt’?•Cy}£Ä²<¤…X×q84 “ì¶ßóíýû_ð£ì¶ßóíýû_ð¨£Ô¬äŠ>Ñ ¿Õ‰)cÓ=ê jÖÝnþu2Ú2Àsôç­.}–Ûþ}¡ÿ¿kþ}–Ûþ}¡ÿ¿kþèg†â?2ÞXå8 Œ~b¤ ~Ëmÿ>Ðÿßµÿ >Ëmÿ>Ðÿßµÿ šŠ‡ì¶ÿóíýû_ð©p1ŒqéKECöh»)F4}š/Fÿ¾øÔÔP?f‹Ñ¿ï£þ4}š/Fÿ¾øÔÔP?f‹Ñ¿ï£þ5_Q#±mƒxóÎŒUꧪljÿ~?ý Px»þFkß÷—ÿAQâïù¯Þ_ýQ@æ™÷ì?ì¿û%X»³{‹ËyU‚¤i"·<üÀН¦}ûû¯þÉZ´€À]áíÌR½¼{-¾Îž^H~AËp=:sÔÔßÙwO1¹³¤¦â9|´'` 뎧>…lÑL 4‹ä‰Ì·…à†Xâ’<±bç‚Ùôæ–ÓG¹ŽU’V‹þ>–b<Ö“€…O$ œÖ훫YOvìñÁ½AÛ+ÈÈñŸQ´ý*­Å”ÐÛß-ãÅ>HŒ‚@ ”UÏZÜ¢ðÑ.®-•ãIgÄüœ‡f Æ;qŠÓÒìœRoRIsm™äÎ3–æ¯QLJ‚Xž2pCÉ4°˜Z0 ¬û†ÜwÀëO¢€"î”wV š Ϫ·—(Kao*ž0}ÁQÏЊè(¤3i}ºâç|@\#DÊ3ò®0¤qËqÏáéZ|sÃeW" ñ¨Oݱ €1ž@«4S„db±›CVÕa¿&C, mÇ–H÷鎥mQ@o-ŒÚdÖ‘á1)nŸw5Et»•ûTA¡ò®“$:xã‘Æz޵±E!˜gHº•ËöXܤ1…ˆ¤#†$ñ×°­i7Båæµ0Ç!™$ÞAE;r6í!³·§ÓšÜ¢Å`¨äV%1½p¡ãÈÔ”PÞfMÑùj‡—tÉ{4+†WÌwŒö}kfŠb*ÚZµ½Íì‡nÉå(^ß(?ˆ«TQ@Q@Q@Q@Q@SÕ?ãÄÿ¿þ†*åSÕ?ãÄÿ¿þ†(μ]ÿ#5ïûËÿ Š(ñwüŒ×¿ï/þ‚( óLûöö_ý’£¾Õn,î.áXÖiG–Ð'MÀƒ»òÚjM3ïØØ=öJ¼ö–ò]Çtñ´™ˆRW ¹,V"£Vb2½?‡ š«q4³˜„"}åÉ» !#wËíÐUè´»¤ŽHíÕZ7iäðÍ÷=l-Q E‹å€ÜNÜ‚ׂzÑÐ Ïí«ˆ,¬ŒÖ«-ÅÄ{À˜‚' Áç¦?Ø‚O:åØÉ½Cma‚¹ìj¨Ò,„IÂÆr„Là¯lœíÒ®¨ ¡G@09  ËÝB Y&Ë0ùd‰Àà| ãïzU«p‘”»`e,!sÛ=ñO’Ù$l–aó‡Æ€Ã¡äx©6–%ÙÙº³cú@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªz§üxŸ÷ãÿÐÅ\ªz§üxŸ÷ãÿÐÅy׋¿äf½ÿyôE.ÿ‘š÷ýåÿÐEÞiŸ~ÃþÁëÿ²V­eiŸ~ÃþÁëÿ²U[ë‹öÕ.á´{‚ÑljǓ»;ÉǽoÑX­J—’Æ$„$¥\+/̃$dõî8¤]^ñ^;y#·7š7†ê:ñ´ýr(rŠÇ‡Sº¸žÞHËʲ±É_Ýß®{ô¨^˜}¨¤hè´°¾ÖPØ`¸9ëר  ú+=Jõ.ü»•¶1­À·càI+¸0ÏnqŠ—LÕ$¼½’U1ù~lR+¹wc¿^ÜЭU-eŠè׌¤‚!b=8¤2í‹«t÷æ­wÃ,nØ9åAÝž˜ç¥E¯¨=º·Ùá’IaYFíRÀާÏiˆß¢³f¿—ì’Û42=Ä‹r§hÉÁ8ëøUHµ‹ÅŒ½ÄPÑÎT!<4G9ìq@µ®áÒ8Ôrq¸àp+u[øÜùélÈžIm›"CŒú~µ°ãúÛêßÊ€˼þì÷Ùÿ <»ÏîÁÿ}Ÿð¬éî®á[é`»ibŽ2ªÒ*ãÍÏEÀç9Ï?Ocyp¶Wí)‘¥·fÚ’¼  €vðÔk˼þì÷Ùÿ <»ÏîÁÿ}ŸðªúLóµËC5Á¸V·ŽmÄ´¶r8íÇ«E‚æsK$p¼³½¼H„†frçqR©pû$ ÊîR§ Ž?ÄTN‘ÊØ–.Ù¨b1œžÆ– ¨ñGlD‚®s•  袱5÷°Ôn¥U2mTÏi çõ  º+ûKR&(¾ÏR°•‰”0 03‘œ÷ÏJ–ÇT–æò5•¦Œ< ‚LŸ(' ÓŽxëÆhZŠÂ·½¹·½Ÿw—%¼—ÞNÜêJŽGl{R®±vÑ,‹ -çÅ$"’Xlìß_n†›•i^c*„ª†b䎹Çò5•k®›ËÕ‚Ô¬’-³÷£ÚK7àA•]ºíSPž,oŽÝYsëóP"Ï—yýØ?ï³þywŸÝƒþû?áQé²Íö‹›yn ÀŒ!Y~a’8ã·ëYæòîÞ) šy–é™çØUUŸ—ùÐ5<»ÏîÁÿ}Ÿð£Ë¼Ç݃þû?áI¥M,‘Î’Èe0Ìщ°ëŽ;ãð«§¡  ÿ9ÂýíѦÆÅg ±Æp8æ¥BÇr¸”ààñÓ?Öªˆ`š(ÚkQ#yJ»‰¼sÇ5f&Üò’1óû¢€$¢Š(ªz§üxŸ÷ãÿÐÅ\ªz§üxŸ÷ãÿÐÅy׋¿äf½ÿyôE.ÿ‘š÷ýåÿÐEÞiŸ~ÃþÁëÿ²V’ÅÈò*îf“ŽŸÌÖn™÷ì?ì¿û%jÐ_ìû?9æû4~c‚±×=:t–V²©Y-ã`UP‚;ƒð«P1ÚÁ—å‰å© õÇÖ¢]6ÅL…mbA‡ùzŒçùÕº(#mbÆ$,\HN?ˆ õÅ2ÞÆÖÖF’ÞÞ8Ýøb£ïV( šè²##¨da‚¤pE:£šO)7`±$rx€"‚e”[Æ$@0€8=…£Æ¨Öñ•UØ:.sŠ~n¿çÝïçÿZŒÝϺÿßÏþµ;1\QmŽ8ÄH" ()¦›;b»LànÇ÷¾÷çK›¯ù÷_ûùÿÖ£7_óî¿÷óÿ­E˜îÒݳ˜Pçnxë·îþT²en!—ieBwmíå¬h T`À`u$ŽMKm«Û\ΰªÌŽÌPy‘•‡%r{Ô:ËÛÝN†ÙZŸÍÃÀt\s×Ö¬.š‚áeó["á®1Žåv⢟E‚k©®·¸wGIvc*1Ǩ>”ë½^+t¹9 °FÒe*¸4jÆŽZlÅÁæ•t!þö?Ïz¬ž„I;4ĉRDâ0rrÝñÚ§}#Ï n.YÜÄ#Þ¨mÀ÷ä(Ý¥ÜWaü°êÑ®Ž¥YN3È4·_v/úíþ„)–v†Ù¦’IŒÓLÀ»• 8ÒyÄqÿ×TÿÐ…5¸žÁ}~Ö’[¨·yÒ,eÁ&N9ÿ 5+õ°µi|³,œìN 3øp:Ó. [¥ˆ+åȲ ¸9ÅCu§Åy­ÓîøÚPÃhèIF¦ÆæÊ³>Û¤ÝænS·v=M55fžö{{kc'—äráD„6Ò°=é«c ®qhQýï—]ôhI$´‘­á1¹;rs‘Í7¸"WÖ¤M6k£dÌðÊcuGxêwz~j{­I­¯í­Ì(Ë;R%ýÎÜtÎj°–ÒÞÆI—c ªchQôɧ]YµÔñ4—¹ÖAŒgrœ›Ò€$°Õâ¿»’(€€ífl3àà1Óß5xÞ7ÐZʳÓVÖá$óÞDˆ:„°1Éç½_ Ë~Ö ¶žñçaql±ÂÜÆCe—œv'Û4æ9ÔýrþµZÚÐÁ;9¸–DG#¯×ñéS!Íû×/ëL 4QEHŠ( Š( Š( Š( Š( Š( Š( Š( ©êŸñâßÿCr©êŸñâßÿCç^.ÿ‘š÷ýåÿÐEx»þFkß÷—ÿAPy¦}ûû¯þÉZµ•¦ýëqÿõÿÙ+OûÇò QMÁþñü¨Áþñü¨ÔSp¼*0¼*uÜïÊŒïÊ€L–5–2Ž84¸?Þ?•?Þ?•Aö1ÿ=æÿ¾‡øQö1ÿ=æÿ¾‡øTø?Þ?•?Þ?•;°² ûÿžóßCü(ûÿžóßCü*|ïÊŒïÊ‹°² ûÿžóßCü(ûÿžóßCü*|ïÊŒïÊ‹°² ûÿžóßCü(ûÿžóßCü*|ïÊŒïÊ‹°² ûÿžóßCü*H`HI`Y™º³š~÷åF÷åJì,:Šn÷åF÷å@¢›ƒýãùQƒýãùP¨¦àÿxþT`ÿxþTê)¸?Þ?•?Þ?•:Šn÷åF÷å@¢›ƒýãùQƒýãùP¨¦àÿxþT`ÿxþTê)¸?Þ?•?Þ?•:Šn÷åF÷å@ªz§üxŸ÷ãÿÐÅZÁþñüª¦¨²nsóÇÿ¡Šó¿ÈÍ{þòÿè"Š<]ÿ#5ïûËÿ Š(¼Ó>ý‡ýƒ×ÿd­ZÊÓ>ý‡ýƒ×ÿd­Z(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠdÌR&+×µ?ì§þ~%ü—ü*+õ-ø:ÍÔ¥„ëen¯%·‰m7®ÛƒÝ»®Á?Zký”ÿÏÄßøïøQöSÿ?ã¿á\âkWéj¯,©±Bްº|×$’?éÜÕ™uKèn$”:˺’Ý`Ùè…Ï\äP#eí™Q™n$$ Œ…ÇòªZ‹oÓCy£?øòÔ:%ýÝä½ËÅ"Õ”¡\© ä ã¦3ÏZ–÷þAIõ‹ÿBZóßÈÍ{þòÿè"Š<]ÿ#5ïûËÿ Š(¼Ó>ý‡ýƒ×ÿd­ZÊÓ>ý‡ýƒ×ÿd­Z(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠŽu- =ª7xä`ÏlÌáhòEX¢€ iQ˜3@å—¡1ä¥jç>CõÏú¾þµ=[zª¸ŽÝ•Ÿ®#ÆO½E¨)M4)ê1ÿ-^ªZ§6G¯ß±þð ;ñwüŒ×¿ï/þ‚(£Åßò3^ÿ¼¿ú¢€:X 296 382 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀí2"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmÁŸM²fkX‰-n„’Pd“Šš+Yæ4Û6oSj€€z<û›Eÿÿ^‘è«jû§º‚ J1¹%í ÉU8û½Èã¦@þâý³ì£M±3lÞTZ¡Ú½”—zv™+.•§’N9¶Oð§h¦4†KvFKÄ`×AÎYØÿ{©ÇÛc.¨q ¿ý 8«» Z#;ìúýtßüOð£ìúýtßüOð¤Í®fŒyØ}ŸOÿ N›ÿ€©þ}ŸOÿ N›ÿ€©þ™£4{8‡;ÈÓÿè¦ÿà*…FŸÿ@7ÿSü)3Fhöqìì_#Oÿ N›ÿ€©þèí,¥m±èÚsAjŸáLÍ#ÈVÚãL-ü©J +ØjM»?³ ÿ þ/øSc°µ•™cÑtâËÔ}•8ý+¾a•b'µtö,.>ÚËHKÎÒAc¥gŸBÝ×RŒ–¶Q9I4}9Xv6©þ [&VeÑôâ«Ôý•8ý+Q=ðËýÖ}9ïJFÙ®£·Eó‚1žüU{½…¯s#ɰÿ N›ÿ€©þù­,¡“dšF˜ÿDz…\d°ƒq·Þó›*súT×ÄIÐd\ĨU±Ï>ôí»îgŧÛÌ›âÑ4æ_QjŸáQ, éh#‚>ÊŸáZVf±AçÏùJœsŽþÕ$4×&HCOærƒåöÍ+$Þ€›ks#ɰÿ N›ÿ€©þù-l¢Ù»HÓ>uÜ1l?*ÑXÕ­î6D!˜ï`}=¨†"×â4M¿g ÿ 9ÿëÓ´{½ÜËòl?è¦ÿà*…>K9˜ªig±Í²páZ(i'/l¢}ä…üxª²•‚ÚåÕv¤òÕOPZ-Ð.û¾› DdmNIû2tªþU‡ý4ßüOð­]FuÞ–¥±þ÷Oø %Â%vÇš>Ðééô÷¡(öÙ—åXÐ#MÿÀTÿ <«úi¿ø ŸáZ·ñ¢#ùñÇùª"*%{Ñtˆ#;ã‰Gš¢ ˜Ë/¯.WÐ2êf%½›çf§ œZ¯ò¦ùvôÓð?µRSý©q ,kµc@ÉãƒëYSïYœJ¸?0¨Æ/ œšê]‡ý4ßüOð¤òì?è¦à*…34f«ÙDZ<ì—aÿ@3ÿSü(òì?è¦à*…34™£Ùǰ¹Ù'—aÿ@3ÿSü(Ùaÿ@3ÿSü*<Ñš=œ{;.XÚi×3}'N.xµOð«ÃHÒˆiv<ÿDz…TÑÎnÛþ¹Ÿæ+Y?Õ§û£ùW=T”¬©»­OŸµ \¿TPª·2ª0ÜxŠ5Ïùj?õõ/þ„h¨,öË ûk=JŽv“|–q²ªDÎHT@OÊ>ðüêXõ=>2íw dmÎEœ¹cŒdü¾•SJâãBÇýßùÛÖ¼·[%"K,˜ÜUp=M™Õ4ö•%1ÜWû¹ã#;zÊ¡¼Ô-n#UCp¤6y´›ÓýÚÑûTÿóçuÿ|ñ£íSÿÏ×ýò?Æ©&ÄÚz~lóÒoü›ÿˆ£ÍƒþzMÿ€“ñ¹ö©ÿçÎëþùãGÚ§ÿŸ;¯ûä_<È䉇æAÿ=&ÿÀI¿øŠO2ùé/þMÿÄVïÚ§ÿŸ;¯ûäjŸþ|î¿ï‘þ4sÌ9"ayÏIðoþ"2ùé/þMÿÄVïÚ§ÿŸ;¯ûä!½d#΂x”œnqÆ:=¤Ã’&™üô—ÿ&ÿâ(Ĥšu#¡[iÁˆZérÞ¦ÇÔÒö²³G6ó#ŒIuv㮆‘ZixY%?öé7ÿ]6ãêhÜ}M%Q­‡ÈŽgu¾1æKúô›ÿˆ¤ÝoŒo—õé7ÿ]>ãêhÜ}M?k!{8œÆëùé/þMÿÄQºßþzKÿ€“ñÓî>¦ÇÔÑídÎ'1ºùé/þMÿÄQ›|cÌ“ÿ&ÿâ+§Ü}M©£ÚÈ=œNc6ÿóÒOü›ÿˆ£6ÿóÒOü›ÿˆ®Ÿqõ4n>¦k öq9|Ûãd˜ÿ¯I¿øŠ‘çGŽ8Úi6G ZMÆàÒn>¦ÇÔÑídÍ¿ú?÷äÿÀI¿øŠUhUƒ,’eNGú$ßüEtû©£qõ4{i³‰ÍK,RÊÒ¼²s’E¤Ãÿd¦~ãþzIÿ€“ñÔn>¦ÇÔÑídÍ¿î12LפßüEƒþzËÿ€“ñÔn>¦ÇÔÑí¤Î'/˜笿ø 7ÿFaÿž²ÿà$ßüEu©£qõ4{i³‰Ëæùë/þMÿÄQûŸùë/þMÿÄWQ¸úš7SG¶{(œ·î笿ø 7ÿGî笿ø 7ÿ]NãêhÜ}M?m öQ9û ›{YÚGyØÆÒooö+FRÎYâ·F•^L¬bH¤ã,Ο¯î>¦³µ"N££äŸøûý'š³”œÙJ)+#Ã5Ïùj?õõ/þ„h£\ÿö£ÿ_RÿèFŠC=›Jÿ þÀïüíëRÝ‚j7Œz¢Ïþ?YzWü|h_öçoZ(HÔ.öã>\XÏüšê&3OÖÒòÈßËk-¥——æ¤ó2meõቼâ›ý¹ ÓØ­‹¤ÑÜ\d' ¦·CÎx}kO\Ý­Øì¬…Ä[Lv{Ê<›ƒ ¸dŽØ Üò¨ùFBžqZ2Á«M{g~Í`.`FÈ$r…o íÎFޘǽZ—o5i ÔÅ…½„÷S|ãåº( »oñ0ïQ¶±'ÛmíÖ(¿yyögÃî+û²üñÁíŽj ­"Ú÷[·°[\¶ÞRÇ4aÈmÙÝ‚1ÓŠ…´™þ×ö…š/øÿûVÓŸºcØFqשô¡_xÙ¤ºþ”Âr·Ñb-!çŒQž8Ï4·—1Ýèï4 Z6Æ R§ïÇšÁ²ðô––mm$Vw>T>LKq6Yr#ÝÏ V‚Csm¢on|ùwçvâÛAa…Üylz‘Í5¸žÆÓ}ãIJßxÒVe™vÚÜ7Ën-çHä•áŠvdޙܣœö=G85Z_•¿½·[xÄv„+I$¬»˜ãÑÇÍëŸju¦s ìYák+K‰na ˜Y÷pÝ€ۑ׎”ëylõ8hÁ¼¸Yœá@ Áã¯ËM Qðë–éf÷„‰úTÐ %¶1Ç^ƒ&­GªXËt–±\,’ÈÔ ,6‘r8?‡n¼Õž)awŠ{‡Didˆ2JÁˆ,œ‚÷U˜4‹›}FÖKO³YÛDˆ²ˆereP¸ØPŒc=9Å©¢u A~,|ànqIǦOAøÕ ßZ%•ä–3E<öÈX§88m§žà8§Í§]¾¸—p<6ðqç2HûæPÚÉ¿FÎEfAái¢Ó¦±-nvÛ´6÷YY°H8(~U íô¤ëê–)~,ZåÉ ÷# g¦}ºÕK¯iðA$±ÈgJ‘Iå© m½qΦj¼z ««Is*ÛË ò¬î òƒ…åQò·# œHÔ—GLYùvmZÉ—ö0`cŽ úâ˜jhɬiÑKr]*<À2ž>\Ÿ\U{vÙu[]:ÚD–i.|™@ÏîþVcÏLð8÷ª·ÅƦד­¬¢åc4òª¡^ë·‡ô`)ðè÷±^Û'lÖ6÷²^)ù„¤¾ü©ÁåÏ9ü([‰ÞÆíQH ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¬ýGþB:?ý}¿þ“ÍZŸ¨ÿÈGGÿ¯·ÿÒy¨Ã5Ïùj?õõ/þ„h£\ÿö£ÿ_RÿèFŠb=›Jÿ þÀïüíëR{O2o69š'#kÜ;pk/Jÿ þÀïüíëv‹Ø,Sûÿóüÿ÷éhûÿóüÿ÷éjåù˜¬ŠcŸþŸþý-cŸþŸþý-\¢ŽfE?±Ïÿ?Ïÿ~–±Ïÿ?Ïÿ~–®QG3 "ŸØçÿŸçÿ¿KGØYˆó®žD;vÏåW(£™…QH¬®¡‘ƒ)èAÈ4#+¨d`Êzr IBÑUÑ&º¹™à°à|ª $Œ÷©>Á?ý%ÿ¿kþÄIEGö ÿè!/ýû_ð£ìÿÐB_ûö¿á@QQý‚úKÿ~×ü)ª’ÛÝ,2Lf8%@+´¨íþ÷é@QE e,T0,½Fy†-Q@ŠÊà•`Àp}(< Z*µ­½ÅÕ¬W&ñãóT8EEƒÎ9©~Á?ý%ÿ¿kþÄIEGö ÿè!/ýû_ð£ìÿÐB_ûö¿á@QQý‚úKÿ~×ü) /‰#‘·4R-ŒnàãþúP´QE!…Q@Q@gê?òÑÿëíÿôžjЬýGþB:?ý}¿þ“Í@®È{Qÿ¯©ô#Eçü‡µúú—ÿB4SìÚWü|h_öçoQk—ÚŒ—bÎå"K;w±¢ æ0cÁ=@ÀíRé_ññ¡Øÿ½l¼0¹rðÆÅ×c@w/÷O¨ö v SV¾Ö%Kp±Áâ"åüªTܶâÜäqŽ*”^#Ôæ „Y%‰mQ¶g€€üz`“jëZÖÕ®Rå­`3 Ú’˜—z@q‘NB"W.Áíõ÷ë@j`xŠÿQ¶»¼7IYØ­­0†#ö©%ÔîìÅõ¥ÅÓË4rÀK(™à‚vö<“]Á ›¼Èbrë±· ;—û§Ô{RKmm2ȳ[C"Ê<`‡¦r9ǽ 9YõýJ-&Öà_“÷‡<ºsV<'5Õ¼U¤³¬¶÷6RJ‹å…1eã#¨!»úWFÖ–¯äïµ·o#ýVbSåÿ»Ç…9 †2†8bO-J¦Ôh=@ô w†Ú"É> ŒHV* |¾½« g’? ̱Ü˰j- Hf%–/;|’Gf¶c1Å=ÚÝFZ)öã÷eÕ†0AÀ4°.‘m‘ÛYÅ J0ë¡PãЀ¼õ¤3Ÿ7eû6ù?Ú+_µ7Ê,cózã~zóBÜ\O¼³HÖ¦âéTý¤Çæ8@dœ ÿ]µÑùšgÙ>Éöuû61äý˜ìǦݸ¥–M6ku·–ÝdqˆÚØ•éÆÜq@ ðìÓ\h6s\;;´}º¸Ï ~£ñ©.¿ä%ýp—ÿBޤöÀ`ôÅÿ iÅêK}‘ÄêY”®K2Ý40%®Zþk«=gV¾µ¸TEn^&Œ0”e†3Ô~ÔÔm/¿|17˜}Èà:g׀審ª]K~JFmc{ˆ^'òðŠ‚Ÿ½¼’@$ŒÍ“j÷±Ùf ¨-E¥³¬>X>qp3Ôð£§Ô›;F¸k†´·3²ìiLJ\¯¡8Î=ªþ‡k¨O Ü1ò¡$B(ðì®å:M€“^YÛ\ùw »¾½‡ÉFÄŒ0ç9_Öº±ÐíYîÍÑhï q•qýy«þL ‚!ˆms Âç,=ÎO>ôØm ¶’ÖÞ(U‰b± @IîqÞ‹…ŒË«I.´(Ç}·“öI$t ˜ÁÚÊxÎk>æúKÈl¤c-¼N3*}©“ ·u|@=sÍmÄ–iö¶ú¢Êöèl¶åÂ1‘Á«Sͧ\*-Ä"PŒÛ³m#¡@r××—ÏO4²¤ñXA*1k°$¶Á÷É`«ƒë]²QK 1Š¥,ú|ÒÇ,Ðù’Ds5»‡ÔqRÿh[úÉÿ~Ÿü)j³¢ÿ_wÿ]ÿöD©ÿ´-ýdÿ¿Oþ&yJ•ÊYC mQÓð4-QHaEPEPYúü„túûý'š´+?QÿŽÿ_oÿ¤óP†kŸòÔëê_ýÑF¹ÿ!íGþ¾¥ÿÐÄ{6•ÿýßùÛÖíai_ññ¡Øÿ½Ϋgwp–ilb´²7r Cnp ƒÇ® nÑ\ôZÞ£w©É•–ëT›É,cbGÊòÝ0 /\wª‰â»™UU-¢Énª™Î Öà>½sëÁ .u”V ôw+H–ãlÖžq.øÏÊÜùÕ‘¦êóZÙMwFI®#±DV,áYÔòz±þf€¾¶;Z+žÔ/µ#áK»‰ckK¸Ûj¶Ò»†á† yç§ëRj­ö<–³ in$…ZÕ‘VGÞ”‚Äñ¹_Zæím¬_}¦'¹Kfµžò[D†!BØc’C·¶1žô¾Õõ QÒYì¼»Iá2Ç F]œŒ)'†È9ÈÆ1øÐ7¨¢³u›—··wXäG ÊQ öãåãžäñéHf•>¦¹ÿ êrêv)s$$\±W 2nÉ„dõ«zÖ¡ua%»F"ŽÔäÏq$lë1€B‘Œóó(«“êhÉõ5„úÔ£_ŠÒ0’ÚÉ?ÙËLo°·ßÎÖéÐõBs[–¦ §â[9/~‡ž§pçëÅ.Y“êh®rM~þkáŸ`e"†G]ŒÌÞ`Î×9ö®ŒðiØ.QPZZÇwÍ;9c#(Ê„‘Øûgñ dôTVäìtf/åÈÈÿç…`xžþîÒYÚwŒ :yp¸ûÊÑ€SùÒ¤¢¹9nõKK[‰#’í-¤0Å×È»Ñݳ1ò€{÷­ËKkÛ‹/·]]Lˆ²7Ÿƒ´@ÁuÁâ…sC'ÖŒŸSEAvÌ"P°»ªþè'¤2|ŸSFO©¨®-c´ˆMHXd,'9¬ß\Mk¢É%¼²Æþlkº!—Áuø&˜|ŸZ+“¹—[‰bKyî!IoâŽÝ¯wºíbÁ€þ@÷¦Ë¯]Jº”»@Èm¡) ì®ÎUÉõÇ_CÁ¢Ás®¢³ì-¯g²7×WS$k#yø;A$d\t­ (¨.Ù–¶—uMßÝš[›Xí!óài¡ åƒóŒ}h5WS…¥³•Râh Áá ¸ßöáj‚ãvíà7c±œgg§&dˆˆ–È!hsÄlAeëÐ*Õ¦úVŸ$°ÊÖ©æ@¡#e%HQÐ@ô9«”QL¢0!fei·ÞØåw}jZ) DUDŠT`ڨǢéq¬á,£áJË’Nå'$rxç~ŠdÑE<- ñ¤‘:ídqG¡^ÇL±Ó‹›+qÇs1 t“Àô«tSS]D(êOôê) `@ÊŤrŸt;– ô¤¸·†æ?.â1"n ´úƒ0*Z)ÐE;FÓFÄâD'øXt?©¨ÚÆÑšážÚ&7*}Ë‘ ߊ±E *Xé–:qsen± w3AÉ<{Uº(¦!®ŠèQÔ2‘‚zbÀ•‹Hû9PîX/Óÿ¯RÑHb2†R¬2Áµ_ìa O³¦Ûd)çäR»H‡fŠd1G1à Ž5Š:(RÔä#£ÿ×Ûÿé<Õ¡Yúü„túûý'š˜ ×?ä=¨ÿ×Ô¿ú¢sþCÚý}Kÿ¡(Ù´¯øøÐ¿ìÿÎÞ¶'‘Ô¤p¨id8PNã$šÇÒ¿ããBÿ°;ÿ;zÙ–6fGÂÉÊ’2=0h¸‚DYÚ9C´:)\B2:†ÿP‡OùË+´Ï寑F]˜àžƒØœùÓH?–«ʤd¶O©$Ë ÝŸÚn¬§ó6}’S.6çÊWÝhí›?¶‹\ɸ¸Œ¿–v#! tÝŽÕPøŠÖãO¸–ÏÍYE´“ÁçDÈ$ :®z€qN‹ÃðëÉ~Ÿda$žiZ+J­Œ|²g qž†©éÓé6‰ªÜÑZ<±m1obÇ'qÇN”t¦¢j±F¶Ir²«ÜÇïGËÞÀq» æí»,\¾eÛnMå·—p@n„çŒ Î>-woq-ìR4>I,Ö¹qåã„mß 8ä`Õ‰4–ÆëN’ô ÙÝ#òFøÙ›wÞÎ<Crõ¶§msò‚ñ õË2høÏ ûsU“Ä:{[O;‘aˆLD²³!à2‚2Aö§ZèÐŦ\ØÊ¶nAW6–¢ÜF:rzóUdðô·L·š—3Û‹hämƒÜ’Ts‘Ó¥Y:Ì1Ï!¸&cµóÙe‰–Eù¶äçŒ{u¦Ç­Ã=ÌÂ&iÄR$ðº·(Ì0;}Þ§ŠMgJ[Ǻº2JL–¢H xa“Ï qTô½.úæõõFFÅÒJ Ø\,lŸwqÛ÷½ON” w/ÙëÖW¹òàŸ(Ì¡`e@pJd|Ü‘ÓÖ£“YYe°û.åY/ ¼ë,eY0ŒØÁèx¾XZZý¹—ìÖ²[îýý̧$g§ËŒwÏQN´ðçÙR3Ì(ñÞ  !µÙù6 »Ž ç=hÐ54´íBJ>Ù&y#*…sÔUºÌÑô¦Ód¹v¸GóÈ>\1£B3’qÁ9çéҴ袊ŽiV ÁŽHPd’i ’Š©&¡RÅÉ,m)!®3޵lðh¢Š(¢Š(¢ŠÏ]oMk‰ [ÒDÌ®1 W¨Î1ÅhQTŸVÓã$k¸ö<&áH91›éȤ:Æž/MŸÚ3:¥1Á##'èE1¨¢ŠC (¢€ (¢€ (¢€ ÏÔä#£ÿ×Ûÿé<Õ¡Yúü„túûý'š€<3\ÿö£ÿ_RÿèFŠ5Ïùj?õõ/þ„h¦#Ù´¯øøÐ¿ìÿÎÞ·k Jÿ þÀïüíëGQ‘ãˆWl†b±œ3íRvsŒPÊ+˜ð¦±6ª’ÌmšI„@îb² à6H+ŽyïZZî§=€´ŠÖ/2k©LjJ3…–'jòzt¤3VŠæå×udÓážÒf¿HHòœ0˜vF:àµ,šÅôw³»Gll¢½[B£p—æÛ†ÏCËtýiˆß¢°­µ›É.mä–(ÕÔ–±ª“æ©]Ãsv •õZ+»á§<׬¨uC `nGQçíÁ`yí®hJàÙÔQXPk7ou ’EØîo$´TŸ5YK Ƕ CÇ`E&‰«ß^Mh/c¶ }o$ñy;MŒVÏ^¨ÇN”Íê©©Fò[ªÇ#Ä|Å>b.Js×ÕnŠC0¬-¦&æëR‘n5)6ÃÇ:d|»¹'ÿ­V¼Ef÷öÝ!ó•®".A@à¶}±šÓÉõ4SÊj:¾»‘ ëh%´kX”‹}¤ä œ§nGQI‡#–ú ®´Äs&¡t× Êøˆr…½FvãÓŠë(¥Ð,qÇK¼66K¨i·»,L1Æ »Žäðvã Ûõi´}Cí–Öò,À÷ÓÀ’!Ï×qÚ?]=ÂÇ1á*âÎøÍx—It#u™Ìj#œ–ÎíàåÏqžƒ"¥-Ý…åé’ÛVm÷sH‘¢ƒ +¯ë]-\,q«¢ê6ºv¥´>§nï¶.–Ï’|‘þÏÍÆ8ܨ­7N¸XÔ.¥šêyc)° ¨9ÏQ޵µE¢Š) (¢Š(¢Š(¢Š+?QÿŽÿ_oÿ¤óV…gê?òÑÿëíÿôžjðÍsþCÚý}Kÿ¡(×?ä=¨ÿ×Ô¿ú¢˜fÒ¿ããBÿ°;ÿ;zÛ’4‘v¸ÈÎG8 úƒÚ±4¯øøÐ¿ìÿÎÞ¶¤–8€2H¨MÇ,J¯¼³»€ÎÙÀöô¨ï,í¯¡ònáYPÀ‚¤wr¸¥û]·üüEÿ}Š>×mÿ?ßbȲ´óÆmU•ã6æbJ‚H'=N~µ¶‡g£q*,×Ïç+0?»ù@éœÇ\gš»ö»oùø‹þû}®Ûþ~"ÿ¾Å1G¦XEz×±ÚF· œ¸ÏSÔÐÜ“I.—a-”VOl¦Þyh†ÌtÁ#ó©¾×mÿ?ßb¥VWPÈÁ”ô æÊ×Z}Ø„\ÀÈ9Œî`WŒpAÏOÎ’=6Æ+潎Ö5¹l’ã=OR@OrMO,ðÀšTŒ…˜ ‹íö_ó÷ýüÄ$úu•ÃJÓÚÇ#L$'?0#?CÐõäéÆÄYHþÎx\œîþöìçw¾sR}¾Ëþ~àÿ¿‚·ÙÏÜ÷ðR ÑtÃ4SAæE·iÞÜíû¹çæ#Ôæœ4ßeÿ?pßÁLCcÓ,#¾kèíc[–É2 õ<@OrM>Ks†CnX'äV >¸Ÿo²ÿŸ¸?ïà£íö_ó÷ýüfŠ­öû/ùûƒþþ >ßeÿ?pßÁHeš*·Ûì¿çîûø(û}—üýÁÿY¢«}¾Ëþ~àÿ¿‚·ÙÏÜ÷ðPš*·Ûì¿çîûø(û}—üýÁÿY¢«}¾Ëþ~àÿ¿‚·ÙÏÜ÷ðPš*·Ûì¿çîûø(û}—üýÁÿY¢«}¾Ëþ~àÿ¿‚·ÙÏÜ÷ðPš*·Ûì¿çîûø(û}—üýÁÿY¢«}¾Ëþ~àÿ¿‚·ÙÏÜ÷ðPš*·Ûì¿çîûø(û}—üýÁÿY¬ýGþB:?ý}¿þ“ÍSý¾Ëþ~àÿ¿‚«_²½þŒÈÁ”ݹú<ÔáÚçü‡µúú—ÿB4Q®È{Qÿ¯©ô#E1Í¥ÇÆ…ÿ`wþvõ·m·ÎH¬Iƒé’ÙþCò¬M+þ>4/û¿ó·­˜N/.?ëœÍé–:晨J"³¼ŽW`YTdn©ëøUüמYiš§ö}¤Ko¨yÖÖ³Æâà(7##Æ bpçŒÖ¥Î“¼:Z ÜXÅ ­ Aþ¸ªáÊäxažÄçÞ˜~hÍp÷­5­­£³n¼´Xof“FÛ“Üà•ϰ¦Ï§ÞËŒúcÍ©M#Ìm¤ˆI “µ@cŸ”€¼7lšî³TTwt7)ÀõÅsÑéw'ÅR]] ­ßiCí?ë¡ÿЀÍ?óï?ýû4y§þ}çÿ¿fªÜxŠ{›¨ÞÊðÃi"Ç5Ê„(…€#Û±óvÕ¯í­77#í‘ÿ¢äLIá8 Ÿ­1šçÞûöhóOüûÏÿ~Í/öΛö}öȾÌfüÿ¦:çÚ‘õ­67$¼‰Zu '€}³ï@šçÞûöhóüûÏÿ~Í=u]=¯šÉnâ7)Ñç‘’> sŠ«c¯ZêËYYIÑ-¹”ȤõÜ>žôid@èr 5åÁ»±®N)¶ßêßþ»Kÿ¡µIoÿÒ×%þfÆy§þ}çÿ¿f4ÿϼÿ÷ìÔVzÚ^Íþ‹cvö»Ù>×…2 mÄdœb¤î–mfº±ù0²1ÈÚIÀÈëÍ1 æŸù÷Ÿþýš<Óÿ>óÿß³HuÍ,Y­Ù½‹Éw1«g«£síOm_O[Èí Übâ@ ¡<œŒÄúPDÃr‡ŽDÜp ¡>•SQÿŽÿ_oÿ¤óS­¯ŸRÐ-ï$@$É•S1(Ò›©ÈGGÿ¯·ÿÒy¨Ã5Ïùj?õõ/þ„h£\ÿö£ÿ_RÿèFŠöm+þ>4/û¿ó·­ÚÂÒ¿ããBÿ°;ÿ;zÝ Š(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¨eâæ×ýöÿЦ¨å‹Ì †*Êr¬;ŸÈšÌ‹B·mRöòùDÂyÒX£ó_`Ú |ɤäzkè÷ ¥On&‡Î7íy9(y½U¸üñúÖ—“?üýûö(ògÿŸ£ÿ~Å;ŠÆCh÷åÍù’ÓûCí‚ëÊËy%Ékeoký‘ˆ"HúíP3÷}ª_øZRÐûýÿØÐý±¥ÐNÏþÿ¯øÑý±¥ÐNÏþÿ¯ø×ÿ JOúÃÿ¿û?áiIÿ@Xï÷ÿc@ÿöÆ•ÿA;?ûþ¿ãGöÆ•ÿA;?ûþ¿ã\ü-)?è ýþÿìhÿ…¥'ýaÿ¿ßýwÿÛWýìÿïúÿÛWýìÿïúÿpð´¤ÿ ,?÷ûÿ±£þ”Ÿô‡þÿö4ßÿli_ô³ÿ¿ëþ4li_ô³ÿ¿ëþ5ÀÂÒ“þ€°ÿßïþÆøZRÐûýÿØÐý±¥ÐNÏþÿ¯øÑý±¥ÐNÏþÿ¯ø×ÿ JOúÃÿ¿û?áiIÿ@Xï÷ÿc@ÿöÆ•ÿA;?ûþ¿ãGöÆ•ÿA;?ûþ¿ã\ü-)?è ýþÿìhÿ…¥'ýaÿ¿ßýwÿÛWýìÿïúÿÛWýìÿïúÿpð´¤ÿ ,?÷ûÿ±£þ”Ÿô‡þÿö4ßÿli_ô³ÿ¿ëþ4li_ô³ÿ¿ëþ5ÀÂÒ“þ€°ÿßïþÆøZRÐûýÿØÐý±¥ÐNÏþÿ¯øÑý±¥ÐNÏþÿ¯ø×ÿ JOúÃÿ¿û?áiIÿ@Xï÷ÿc@ÿöÆ•ÿA;?ûþ¿ãGöÆ•ÿA;?ûþ¿ã\ü-)?è ýþÿìhÿ…¥'ýaÿ¿ßýwÿÛWýìÿïúÿÛWýìÿïúÿpð´¤ÿ ,?÷ûÿ±£þ”Ÿô‡þÿö4ßÿli_ô³ÿ¿ëþ4li_ô³ÿ¿ëþ5ÀÂÒ“þ€°ÿßïþÆøZRÐûýÿØÐý±¥ÐNÏþÿ¯øÑý±¥ÐNÏþÿ¯ø×ÿ JOúÃÿ¿û?áiIÿ@Xï÷ÿc@ÿöÆ•ÿA;?ûþ¿ãGöÆ•ÿA;?ûþ¿ã\ü-)?è ýþÿìhÿ…¥'ýaÿ¿ßýwÿÛWýìÿïúÿÛWýìÿïúÿpð´¤ÿ ,?÷ûÿ±£þ”Ÿô‡þÿö4ßÿli_ô³ÿ¿ëþ4li_ô³ÿ¿ëþ5ÀÂÒ“þ€°ÿßïþÆøZRÐûýÿØÐý±¥ÐNÏþÿ¯øÑý±¥ÐNÏþÿ¯ø×ÿ JOúÃÿ¿û?áiIÿ@Xï÷ÿc@ùÖ4¾Ú•ŸýþSýjÅõ•Ϋ¤GmwÎ.¤%c1Ç‘7=OµqŸð´¤ÿ $?÷ûÿ± |S”tÑ¢I¿ûâuÏùj?õõ/þ„h¨/®>×qu³g+I·9ÆI8ÏãEÿÙfotoxx-12.01.2/doc/images/gamma-curve.jpg0000644000175000017500000003327711701011016016564 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿíFPhotoshop 3.08BIM*sharpen resize sharpen resize ÿá 4http://ns.adobe.com/xap/1.0/ 291 248 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀ#ø"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êtm#K}OwÓl™šÚ"ÌÖèI%I8ªš•÷ƒô»³k„S(¯Ø·pzrŠ×Ðÿä§פ_ú¨ ³´¹Õu¸µ‚fHÃ6Q\÷ÕšÛC;N¿ð~©x¶–0XK;Bý‹n@<•¶?±´ŸúØÿà2…Aqgimªiok,fpLq…$yOǵi7Ø3`ÓtKˆ¼È4ë\‘‘lœpAãƒDZn‰1E§X?–Û[É€}:UKåžâòfÒ7qÅÛ#î©Ûcÿ@=/ÿ×ü+SMÓ`i%IaYc7 ! 2êAÀšu…»Á-RtHe”“” ð=¨^Ö׸?bºŸn±ÿ —ÿ€ëþŸn±ÿ —ÿ€ëþ~ÒÒÇû¤åó#c$‘ÆX¡àà~"³t8£¸žo214‰ Æÿóÿyÿ}¯ÿJã±z¶•b8®#D)ùPº¶”ŒÌ—©s–!O'×¥Oö7ÿŸûÏûíøš>Æÿóÿyÿ}¯ÿEÐj`kMk¨ÝG,7ö誛H}Ùëì+;ìQÐJÓÿÿâk°ûÿÏýçýö¿üMcùÿ¼ÿ¾×ÿ‰¨p‹whÖ5§dqÿa‹þ‚VŸøÿÿNKo,b=^ÝþëH?öZë¾Æÿóÿyÿ}¯ÿGØßþï?ïµÿâi(EmqºÓ{œ‹[—R¯¬@Êz‚òÿ ÓE U*ºµ²ƒÔý»±¿üÿÞßkÿÄÑö7ÿŸûÏûíøšn{ÜJ´ÖÖûŽA-0©k·9+ºL¨ÛS^+]β¶¥cD‹˜¡@ì8÷®§ìoÿ?÷Ÿ÷Úÿñ4}ÿçþóþû_þ&ŽHÚÚ‡¶îqÂÏ Xjöàž§|™?øí ±P]VØÔ“Ÿ¯Ë]—Øßþï?ïµÿâhûÿÏýçýö¿üM/g1ûyù`°P­¨¨NñÚScŸù‹ÛuÏÞ“¯¯Ý®Ëìoÿ?÷Ÿ÷Úÿñ4}ÿçþóþû_þ&g1ûz‡,Jçn¯n3× Ïþ;W-ímL0^éŠÄ2í“~áÒº±¿üÿÞßkÿÄÑö7ÿŸûÏûíøšj[\—ZrÜâ—OÚ¥WVµU=@i?øíKij–³y‚÷N—ŒmHG×€+°ûÿÏýçýö¿üMcùÿ¼ÿ¾×ÿ‰¤¡î7^£V9È¥¼ºûDšµš>УË2(P;– :y9ίlsÉù¤çÿ®×ìoÿ?÷Ÿ÷Úÿñ4}ÿçþóþû_þ&‡¾à«Í++IÓ‰ÿ˜½·\ýé:úýÞ´gçûbÛ®~ô}~ïZí¾Æÿóÿyÿ}¯ÿGØßþï?ïµÿâhöqóÖ*y}Ç4æPBëÊPAŸüv™ý’Ÿô²ÿÇÿøšî¾Æÿóÿyÿ}¯ÿPOö{f q¬M¯2G°ÛKÙAôaõš‹±Æd¯ýì¿ñÿþ&º}öÆÃK‚ÖkØ™ãÝ’±ËÜ{ÔŸj…¸‚óT»¬qò¯(+SÔüKý¡Ò ¹“NÀóe—˜îéŒ`cŒUÆ’Ž©:óš´™¹®ÞÛ^xcUû4Ë&ËvÝŽÙÊŠƒ^ÿ/òOú uúIEmfÌX¶ßñ壨-¿ôëvÓþ<àÿ®Kü…a[Ç–ÿ`¶ÿÐ#­ÛOøóƒþ¹/òÜq%¢Š*J (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¤$(%ˆu&€‘™QK1  d’pª?l¸ºâÂÿËyU>ê:·×Ó¥]5ƒÞË%Û²cËSêqùçãíÜWûV 8²I.Ïf…rŸ÷ßÝü‰£¤ü†¶´S+~8 ~¦¯ÑEÐ?²ã“þ>în—jãЪVïNòtý:DäØgê?‹ëÓëSAoŠYŽY˜ä±÷?äQkn<‡œîºÆÞÑ)ÊýIÇ'ôúõ«QEÀ(¢ŠC (¢€ ‚ûþ<.?ë“#SÔßñáqÿ\›ùZïüyx‡þ¼SùIEïüyx‡þ¼SùIEkÙaÖßñ壨-¿ôëvÓþ<àÿ®Kü…a[Ç–ÿ`¶ÿÐ#­ÛOøóƒþ¹/òÜq%¢Š*J (¢€ (¢€ (¢€ (¢€ (¢€ (¨®%h£Ìq4²1¨õ÷=‡¿ó8Ë™›x¶ÀÆAÛ‹Ýò§ñÄ–ð%¼B8Áë’Ää±îIîi–ñ#g§˜çt®8þ=»Tbinÿã×䇃ç0ûÞ¡Gõ?­1M2Å…Ái“þÞ£û;OÍÞ{D>èúÿ{ñ⤂Þ;u"0r~ó±Ë7Ô÷©hô¢Š) (¢Š(¢Š(¢Š* ïøð¸ÿ®MüOP_Ç…Çýroäh`ak¿ñåâúñOå%k¿ñåâúñOå%¬wd=‡[Ç–ÿ`¶ÿÐ#­ÛOøóƒþ¹/ò…mÿZ7ý‚Ûÿ@Ž·m?ãÎúä¿ÈTKqÄ–Š(©((¢Š(¢Š(¢Š(¢Š(¢›$‰m$Œe˜œ(&• ‰¤«×“øÔÕD`³yòÆíu ù! }=©9ëÆOŒ}£P¹Iá‘¢µO¸Jà¹þðõ™¼‚/Å B¥cÏ$“’O©5[ r²™˜=ã 1‚"qHç>çëùUª(¥p (¢ÂŠ( Š( Š( Š(  ¾ÿ úäßÈÔõ÷üx\×&þF†»ÿ^!ÿ¯þRQF»ÿ^!ÿ¯þRQZÇvCØu·üyhßö oý:Ý´ÿ8?ë’ÿ!XVßñ壨-¿ôëvÓþ<àÿ®Kü…D·Ih¢Š’‚Š( Š( Š( Šl’$H^GTQÔ±À]^k¡û°Ðĉ—æ?AÛê*v$×Ç™eÇÜSÓëè*‡Ù忹Ìò†Š&Ë<+cî_v>¸ç®óehùk"·1ƒþÑÎXöïÞ­ECÇ…Ev§{ã袊‘…Q@Q@Q@Q@Q@Q@A}ÿõÉ¿‘©ê ïøð¸ÿ®Mü -wþ<¼Cÿ^)ü¤¢wþ<¼Cÿ^)ü¤¢µŽì‡°ëoøòÑ¿ìßúu»iÿp×%þB°­¿ãËFÿ°[èÖí§üyÁÿ\—ù ‰n8’ÑE%Q@Sdt ÈÁTu$à uWšè$žLHeŸØ03ÔžÔ™šçîî†/ï¾ÞãÐ}yö40Ç{!@«’ÇÜž¤úš{†;RÎ%»q,€åW"óÁ×Þ‹›†W[€÷2èƒûÍííßó ¹¸eq¸pã ˆ?¼ÞÞÝÿ2mn¶è@%ÝŽ]Û«Z=@tb Ç«6Ð7ä⤢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ‚ûþ<.?ë“#SÔßñáqÿ\›ùZïüyx‡þ¼SùIEïüyx‡þ¼SùIEkÙaÖßñ壨-¿ôëvÓþ<àÿ®Kü…a[Ç–ÿ`¶ÿÐ#­ÛOøóƒþ¹/òÜq%¢Š*J )²H‘&ù*úš®D÷8å ‡¿;Oö~½~”ì!ÒÝbC ºù³t ެ{×Úˆ­ˆq-Ãù²õ•û#üjXbŽÄq(UM,pFdšEDYŽì£ëÄ)q¨i×:fœÌ·R(hm« å^qÐ}±VwÜ_ñšÖß¼„ïìû£Üóéê-ÛÁ´B(#€çÖžÁ¹‘á=&÷GÒ ¶¥p—&BÆDvlŽ02ÀZÛ¢ŠMÝܰQE†QEQEQEQEQEQEQE÷üx\×&þF§¨/¿ãÂãþ¹7ò400µßøòñýx§ò’Š5ßøòñýx§ò’ŠÖ;²í¿ãËFÿ°[èÖí§üyÁÿ\—ù ¶ÿ-þÁmÿ GZ6š¶šmQRþÙÞ(”º$¡™z@ç©ëQ-Æ­%Ñ.b¶O6Qל*óÜúûuªWŒ/1‚k‘˜#;®Ðí\°öÏÒ¥ŽêP,t¹DcdÄJG¨œý@¢ÁrÜvø2fó%õÆ~ƒ<}zÿ*uÅÄÑù—3Gg‚ŒúsU>ϨOþ¾ñm×û¶È ÿ¾˜ËKo§YÛÉæÇiq6F2IMìKcÛ8£Ôd_kº¹ÿa³þzÜeú dþB¤†Á‚{£ö‹ülÕÿuI!OrjݯØ,QE!…Q@Q@Q@Q@Q@Q@Q@Q@Q@A}ÿõÉ¿‘©ê ïøð¸ÿ®Mü -wþ<¼Cÿ^)ü¤¢wþ<¼Cÿ^)ü¤¢µŽì‡±-‚yhqç´Öÿ€EUì¼ ¥Y^½ÜO3Èà†ÊryÈî=oKûºýƒþƒm;¬h]ÎrML˜Ò+AfÖЈm¥Ž‡DŽU€©<«ùúÿÈbš·±™ ²2ã©%xú€r?)×[¶ÆªÌ»¤PJõÇäÏzÆUÇüýä1G•qÿ?_ù TJ ’YmÒöF–%ÔKó.F?Ϊý¶ÞâÜÉis9y-ÍÌyÎ6ç#ŒücŽÔZânÅÿ*ãþ~¿ò£Ê¸ÿŸ¯ü†*s֚w8­"ˆ¼«ùúÿÈb*ãþ~¿ò¥ûFÒ<ØeOFlcô9M@yWóõÿÅUÇüýä1QÚjv¯²Òò›Â8β–Žâ7&$ÜÊäÎk2ÚÎô7žÐNèu$ŸtˆV]»I*:ÇaÇjêhªR±2Îjµ¶[ÁäÜ+A-Ë4¬–C³ž‡¨ãµ?Ã6—Jïvó+y!dàe ùûÛ‹°cצ:×EEÁÊQEIG9¯ÇŸˆëÉ?””Q¯ÇŸˆëÉ?””V±!“éw@ÿ°qÿÐb­ÊÃÒþîÿ`ãÿ ÅVõ «‘kafÉ“«»Jë¸*®3ܦZ±§dhÑYRêob·Q\>[[uFÐᙀí÷i’ëoܰ³-«"Ë'˜•[8Ç@¦Ì|ÈØ¢±.üG¹a±9¡¤™cGÚc¸ô稤¾ÖY´­:öÉŒiy2!>Q•”s…NGj9X¹‘¹EswšÄecK™‹Ÿ!·4>PÚÓ?)dø’ݵ6²Ž4vóZeÞ\îu¶iò°çW±·U¡kË”2À îeÉÏŽßJž2ͳ¦Æ ¹Î¥eI5ž™[ó®.ž$gûªLÉü©+sY»+š>N£ëkù·øQäê>¶¿›…e\kwz]Ä–÷{.Ø¢¼LƒËÎ\&\rÚ}lj’Ö6[˜V…œBQæUL•ÝçŒ`åWËy™¥äê>¶¿›…"<ñܬ<ºS=ˆ¯ÔVRx­eŒËohdŽ8|éXJ>Q¸©Ç÷¾é­6K¨Ûºœƒ‘ù¥L’KAŶÇHóµÈ‚ÜG»fò\œc8íKäê>¶¿›…3qML•?g8ÿ¾…fØk7+o+ê3GÌq†{iSÈ Ïg$†_qDT^ãm­_'QõµüÛü(òu[_Ϳ³ ñLÆ$xÂÆRS½d ¥£Á × ç>Æ›'ŠàŠé –5FýØ‘Ze¥Æp«c#5\±'™š°I#4±ÊIm;zþµ5W·9º½?ôÕô«™dW3 {if#"5-\Ry:ý:þmþ©ÿ »¯úäßʨêZµÕ–µ HÌÖÑZ]…ÆäŽ98íN)7f)6–†—“¨úÚþmþy:­¯æßáYsx…mî%*¬èÒFªÒ8HÐ2n¶8ÏN{šwöíÄ3ê-4 öÖÌŠ¥æË"œc¾KuÍ_,Hçf—“¨úÚþmþy:­¯æßáT[_xËÁ-›-âº"Â$6üàîôàçéMÄÊcŠ;,Ü<òBPÊ:œãßÒŽX™šN£ëkù·øQäê>¶¿›…fÍâxa¸»„¤r5´2Mˆ§W$'P@û§žôL²ºÜXÒ7da0m»þéõ¡F,š4 ’Fic˜(x˜)ÛÐäýjj¯nswzéªÿè V+2Îs^ÿ?ÿ×’)(£^ÿ?ÿ×’)(­bC'Òþîÿ`ãÿ ÅZW¶_üÝêñ6è䶺‡ÜVn—÷tûý*ܨ–ã[“hV“¨Kr[aÛÍæEÎpÞ£5etûe[¥ØJÝãÍðp¡jŠW{Ër€ÑíÒÞÞ/6!mŸ*Drg¯=óÞ§–Î)–ØJ]ͳ¬ˆÅ¹,>½jÅ]…‘JïKµ¼•å˜>öEL«c[p#ß4 2žI#–â1.KÆ’aI#ãÖ®ÑEØY qªÄ(9'êk+É‚êÄÛÜ€WÌs×O˜Ä{†µê'¶·v,ðDÌz’€š‰&ö*-#çG·šÒXRâO6VBÓHûŸ Á°n•0ÓmEwË¼ÉæùÞoï7cÝôãéZ¿cµÿŸhïGØíçÚûàTòϸýÞÆkXÛH%ód’F–³I’T>MYƒn‰Tä$,:ç®?•Yû¯üûCÿ| |qE"(Ñ3×jše}X]tEK‚¡ÉÀhHÎqÜVyÒ,Ÿ&Yg•ð¼“e“´öäøVÜ‘G(XÑÀé¹sLû¯üûCÿ| e{¦VÔÉ}.ÆKu‚mÒ¨›ÏÜòe‹÷Éô#‚=*v¶„Þ¤šXäb ˆä¾:dUÿ±ÚÿÏ´?÷À£ìv¿óíýð)rK¸^=ˆ¬Né.›¨2Žà Vé**ªŽ€ ZÒ*ÊÂnì«©‚tËI‰¿•U¹¶¶¸ži\äË…ˆn¨NkR¡û%¯üûCÿ| ™E·£×S)´ÛVYe–1 U}’cpUÚöÅ!ÒìrànT‘Yv ®ä˜÷oÌ…÷oÌ…W¸ŽîÖ®£‘c+äíÏãš³I¦´cÑì&=ÛóáF=ÛóáUã7RÏåN‘,RlÁv~PsÔzÔŸd½ÿŸè¿ïÇÿeBŒžÈWH“íùð£íùð¨þÉ{ÿ?Ñßþʲ^ÿÏô_÷ãÿ²§Ë.ÁuÜ“íùð£íùð¨þÉ{ÿ?ÑßþÊ›•.d·™ÖBˆ®WoRF1“ýÚM5ºÓØÃ׿ãÏÄ?õäŸÊJ(׿ãÏÄ?õäŸÊJ+H’Éô¿» Ø8ÿè1Våaéw@ÿ°qÿÐb­Ê‰n8…QRPQEQEQEQEQEQEQEX¶ÝUý;·þ„µ‡e¨ßŧi·ò_Ipn¦É ¢cˆÊà1Žù­kÉä’GTC.æ8ܧü*…µ¾i*˶W\í&mÛs×'…Oµäm ÓrÕC®Ü<ñ³Aµšy Œ‡;ò›†Hô;OéUàñ5ÂØ››ËhÀk#w‰‰àcå9y*G¤Çv×HmDÍ’[ÌOSŒàê9¥EÒ‘­v¤F@@Cü<žœRöêÁìÂNâûO½K›fˆÆ£ ±Õ\ÛpŠÚ¬%[m$·±‘ `"Ì\“è2Oé[´ÔùÛh9\V¦Eíôº~©\C·Ì€ t\ª ŸaœÓæž}.Û|š‹ÜË! ¢dà·}¢5ÏáÍ$ËwÓÄ«$¤í€J(èzŽ R[=b˜È#ý$åqÓwËøb’­Ë :wÔ‰/%·Y µ‹å¶k‰؃ò±RÝêâëSM$òAf·Ey ±ÞÙ]Ø{P$zLqìF¶ c1æç*NHëêM=$Ì“o·"…MŒÐ8÷ÍÝ Ù2›k·—±@ `V–YdPAp Àdôé‘]6íNsÿLcÿО²RßGŽ6ÜFľy r07qϦ+FÉÖ[©¥ƒ¡2œ‚AlŒþ"ŸµSi TÜnÙ“¯ÇŸˆëÉ?””Q¯ÇŸˆëÉ?””Vñ!“éw@ÿ°qÿÐb­Ê±[„±Ñ.`µ{…ŽÄ#*2©’<}â?ºj÷Ûo?èuÿaÿâêd†‹ôU¶ÞÐëþþÃÿÅÑöÛÏúÝߨøº›1Ü¿EPûmçýî¿ïì?ü]m¼ÿ =×ýý‡ÿ‹¢Ì._¢¨}¶óþ€÷_÷öþ.¶ÞÐëþþÃÿÅÑf/ÑT>Ûyÿ@{¯ûûÿGÛo?èuÿaÿâè³ —èªm¼ÿ =×ýý‡ÿ‹£í·Ÿôºÿ¿°ÿñtY…ËôU¶ÞÐëþþÃÿÅÑöÛÏúÝߨøº,Âåú*‡Ûo?èuÿaÿâèûmçýî¿ïì?ü]arýCí·Ÿôºÿ¿°ÿñt}¶óþ€÷_÷öþ.‹0¹~Š¡öÛÏúÝߨøº>Ûyÿ@{¯ûûÿE˜\¿EPûmçýî¿ïì?ü]m¼ÿ =×ýý‡ÿ‹¢Ì._¢¨}¶óþ€÷_÷öþ.¶ÞÐëþþÃÿÅÑf/ÑT>Ûyÿ@{¯ûûÿGÛo?èuÿaÿâè³ —èªm¼ÿ =×ýý‡ÿ‹£í·Ÿôºÿ¿°ÿñtY…Ëõ²l¨Ý#}Õþ§Ú©µõöÓ·F¹-Û2Ãý ó¯‰ù´›¦ 2çÍ„>Ÿ…¤Ó £;V éþ"!Ùóf™b8 207 237 ÿÛC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;ÿÛC  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ÿÀÏí"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?æ´­+ÓøBßÄ µÔ/.®ïZÛýÀf8$E<Ò<£Ç™¡x…3ÓsÆ3ÿÒÛ¿—ð§HŒíÖ˜þHõè^ðž—6‰„-rÑ '–DÜ[#'èLW6#ìyRWoe±­:|÷mÙ#ÏþÇà/ú¼Iù§ÿGØüÿB÷‰?4ÿâªKû[{qí 8µ•|ÔÜÃ`ã=ŽAÇÖºÍOš+“§[hÖ°hùˆG©-¾ç*Jüæ\ã’qŠÞŒãV qêg4á'ÐãþÇà?ú¼Iù§ÿGØüÿB÷‰?4ÿâ«ÐôßÙi^"²š®`au-°K¢§Ï2D‰Àã5о³Ãâyéf[#p÷M´B®QÎïÆ´²&ìå¾Çà/ú¼Iù§ÿGØüÿB÷‰?4ÿâ«o]Óôû.•eÃÉtYi¼ÍÁOŽµØ¦“á×ñ3Ì ·"Gkg±p³($¾Ücp~´YZâ¹æcðý Þ$üÓÿŠ£ì~ÿ¡{ÄŸšñUØiž´¶£w$Ê#”î:H¦@¤·ö‰ö§]øzÊ]kXq¥_*ÚÑYBT<ù|oO—„°‹!Üã~Çà?ú¼Iù§ÿGØüÿB÷‰?4ÿ⫵þ̱¿ðÞ›k<3Ã:C},$2…®1Éè;c¨ø{L³Ôô£ž% 6« FU ¼!SXW9±ø þ…ï~iÿÅQö?нâOÍ?øªìfðÖ>œ^Ê;¸îÖiãó%FPc}¥OÊ:úö«> Ó ¸³YhZG–7€Ì¤ÈꛕUЍÉéÜQd=Nì~ÿ¡{ÄŸšñT}À_ô/x“óOþ*»ˆü¦Jhä[”YÃ9µóHÉ 2ªr…Qÿ„jÁ´ÍZ[eºžk9d³)<µç%pXg•È4Y§+ö?нâOÍ?øª>Çà/ú¼Iù§ÿLÔ~”¿—éO”Wö?нâOÍ?øª>Çà/ú¼Iù§ÿMü¿J?/ÒŽP¸ï±ø þ…ï~iÿÅQö?нâOÍ?øªoåúQù~”r…Ç}À_ô/x“óOþ*±ø þ…ï~iÿÅS/ÒËô£”.;ì~ÿ¡{ÄŸšñT×¶ðk¹ô(õf@?ô:?/ÒºèÖðÉ}yåf#J»–$C´ñêNN}1\ؚʄ9­vôF´ ê;ÂÚøÔ2h#e=d#ÿC¦¼âÉ ø‰þó ÿÙëgÆ:U¦•¨Û\X²îv«˜×j¸lààô Ê·¼á›=GKŽáã†K«¨DÅ¥]ØV<(ôÀ#êkžXÔ©©(ÞMÚÞ~¦Šƒæi½S‡’/‡ÐÂf“BñÆKLèUâhÃ+ÔôÍ.â{xa›` )ÉÀî{õ5¿ãÛ }*{ˆ-ò&hÞ¤réžxö¬o‰òPõ¿úù?ÈWU*Ь‘”âá+3¶ð~ƒiâ†v–·’ÜD‘jJ­mÀÜ>cWÒ/h±µ”’ßEå˜RxHËÇÐðq€{SþÉ?ƒþ¾ä®¢³¯Fl§Ðºs”68è< Ú“5öµ{wmrÿ*Cg*uç$ŸN˜{X?ì B#­ë¦!Ò3v»-˜®¦›s\ÜKSAC›$“@Ço¥\R„Tc²%ûÎìæÃûefÖõâÈ0ŒnÔ•úœ~‡ÚyB‡Z×JÜTÝ® õÆÎ¾õÓùþƒz_ëþ5b×J»½Ýö]OO›f7lV8ÏNþÔùƒ”äáöžÒy¬ëŒçít…¿=”‡Úx›ÎÖ¸%ëæ ¤ÝùìÍvßðŽjßó÷gÿ~Ûüjt»ÛiÖ+‹˜2è\»;Ÿö¿Jwb²9ø@,|Ÿ'ûs^òºùl]¿–ÌRÿÂgæ ?·¼Aæ(¿ÛWp€ìé]@‡|r¼W‘Kå¬g‚9#9¤=h» #—ÿ„ËøžëÜúbñž¿Áß¿­"|?°Œ·® p v ëÂu÷®¦Š.ÂÈåÿá±Û·ûs^Æ ã틌£ît5b×ÁðZ]%ÂkzÄÏ!Vêhç@ÇÝt"º (» #ž¼ðl7ׯú}w[ÝñÄG(TaPÙÚ3®ëååÞ.ú‘³šê(¢ì,rŸð®´¿ú k?øŸüEð®´¿ú k?øŸüEutQvG)ÿ ëKÿ ¶³ÿ ÿÄQÿ ëKÿ ¶³ÿ ÿÄWWEadrŸð®´¿ú k?øŸüEð®´¿ú k?øŸüEutQvG)ÿ ëKÿ ¶³ÿ ÿÄQÿ ëKÿ ¶³ÿ ÿÄWWEadrŸð®´¿ú k?øŸüE,V«áfdÒ]NÎL²íiPŸ¼À §ñï]UH*±å‘Q“‹º9)¼=©xªénuÖ›N·q VåVVaÐô!@É÷5$úÿ†ak6)ï­RÄGš…qÇCžGzWSEg*pQìR©$îqóx:\M¨x–ââÝäÿWolêg©rA†¯<ø†Åü}¬9ê×ý{x_ÄùµoúïýoN**ÈÎNîìôφ_òOàÿ¯¹+e¥º]zŒËöi!r" ÎF9'ñè+á—ü“ø?ëîJéŒQ™VR€È …nà´Þâ[¢ Ä×=>ÁýM¶í Kx—ÑGqmå,‹|žÃëRö.;•þÍj÷vû!aZ™Œeò\ýýöŽ•½áˆã_:HÐGçE”§.8Ï8â±E­xÜk3ˆa´|¨ÎxçÜÖž•}a§I<’ßÍrÓmäÛ2ãÿÎ Ò¹¬Ýãdtµ…¯1[Èÿž/ÿ¡%Yÿ„Mÿž’ß—ÿ ÍÔïíõ ãkrÌ6 ¹êWÔ{Ý´sÙ˜ú}„lS­¼ÓÉçeŸÍuny煜ѩÝ=•£M+¾ôEV8f Éüiºnm¤¥À·@<ç-ò¦0;/á“VgŠ9IP:îÔÔRŒÚÝͶ÷º¶‹ËIdˆùR;•Kg*S«ÜÂ|»‹x„Ÿ¹aåÈYvÈáy8ê3øÖÙmËn0!;Ìœâ#þUi¶1Á$ iŠ_¾¸?6:~]½(”ú¼ñ¤Ž¶è"Šåá’V,U@;›‘œý­:^iõCoœn&1B9Á;‰Û·ºæ­.ÀÂ!6«å«Û¹°IêO<çÞ¤vËrnVYWŒöéÓô£@)I©ÌzÅ`H­¤X³1gr€§ûØã&«ÿl]]Û‚ÝfŠf1™„;xã9Éîj½´©"<Ë+qÏÌÃ?^åQ¶™`ð¤-h†4$¨ÉÈ'¯9Ï=ù¤vŸ©8’ÎVs2@#ÈOXYó\¯ãš’=bwr< – +3R¨\Ôã¾j¾ú}”ˆQíc*vñÈû¼.1ÓÔƒN²V-“ÿ«8^sÓ8<óÍ;«ŠÌ¡}<ÑkÊY½• ™£2ä–lð8o»ÐñDš½Ü1ºImŸˆYÊJbG ÉÇQšÕòb2´¦5.꘎ª2qúš†=:ÆÌqÚÆ¨YXžJœ¯äG¥lŽêêæ-­£Ž¹œK9¸<ã'ò¨«?ž7Aƒíذs¿yqŽ™?Z¿qkÚ¸‰däg ƒêäSVÂÍ.ÂÛF&Q€øäqÏg­ 2lõ;¤ÓmR(ÒiÐÏ+Í!‘€prjõü·÷2ì‰Þ5C–c¼–@ÃŒc¿­Júe„‘¤oi$d•\ œŸÀút« q»º"«HAr?ˆúS–5‰U.DéFác‰÷–`[jœç=¶ç®*×®šÕfŠÒ<¬M*Èì¤ym´Æy÷ÅiÿfXípmPù‡,IbIÎzç#žxÅ9l,Ö?-m&ÆŸ•ŽX~&ÌÿíkÓ:Ú {´4ª¹2›Y ƒœg?.:T#Yei/lVnÍlë!S^G_JÒ¹Òl®äå‹î8r‘¼…*3߀OJ˜YZ€ [FFbP€‡ªãÒž‚Ô‡M»¸»Ž_´Ú¼  GUpFr7(ÑÎq×µ6ßX‚âO-a¸V;Âï™~òqHf…@kÿU?šeò¼/÷›±»úsši×-1ÌfWŒÈvÆO– à–ôäPy{pš­­º¯—"$,¾?¼1ׯ?C@×lÌ/6Ù•/57FG˜™rúŒ‘ùŠÑ¢ªM¨%¼0<ÌwØìùÉçŒ}4×Õmã¸òYeùYUßaÛ7EcØò?:»ES­±~pÊËÿ<ó»ùbjÑH" or^eÞ©åüÛ8ù æ€/ÑTíõ;{›Ÿ"1 ,£²²m8m§¾)§W· ,›&1Fþ_˜#Ê»îÛµ}Nî(õœºŸum@¢´Ë"áªnÇ·cô4.»fмÅfTy˺2<ÄÈ—ÔdÌPȜ˹ã,>ãŒ0úÓ袊(¢Š(¯ øÿ#Ö­ÿ]ÿ ¯t¯ øÿ#Ö­ÿ]ÿ ªˆ™éŸ ¿äŸÁÿ_rVâiæ=F[Õº“2í … }Ðzž~µ‡ðËþIüõ÷%užà‚cƒ}r§§”ŸÍ©µÁŽ™±ÑÊÑ’=2¤fÈçðê5ŒðEu#³É ²ÌFÈw‚; Ÿ×Š’OÛ\A"^N÷RÉåæINÝ™*ãdž£œÓ~ÌŸóÚïÿ%ÿâ¨û2Ïk¿ü —ÿЧp±*h6©Ư´=»@|¨’1†9'j€§Þ¨‰ì#¤¨Ï²¯ödÿž×ø/ÿNKxÑÃæW`0 ³<˜ún'\,W¸Ó!¹ºûC»†Â cå}ãõ¨§Ñ-®!hžYB³Ê䩿@Aü³Z4RèMk ÿgIN&óC!UÊí *¡=¿Xü9l ´²I5¼{Ú7;ŽŽIäV½î!kHÞínNr±4[{`‘þHhPy&'¸žEùîÇî“ àqÏÝŸJÓ¢ïì×P·0;íFûÃËWÈú0ýj¸Ñ` ž'(Ï ‰@“×°Ï®+BŠÎ4Bbÿh˜§ïvÇ„2}â3ÜÔ§MPÐ<7ÂðÄ!Ü è1ÁéW(  6:=®ŸpòÛ¢ ùÀòP0ÉÉùÀÜM:<~[Ä.¦XŒžj ÇîŸvýÊqŸ½Î­hQ@cÒaGIiQ+JîØÌ„®Òì0ãÒ¢] $Ä÷È¢"-ØýÒd9û£“éZtPy4QEQEQEá?äzÕ¿ë¿ôî•á?äzÕ¿ë¿ôQ=3á—ü“ø?ëîJßkø’ù-%Wá¡ÚÇÀ?JÀøeÿ$þúû’¶%±ž}Z £´IäLŒ|×\r‡Œ`“êi=á¡T¿µ-šá!…Ò}É#Ô…ØAç¯5=å¿Úì§¶cócdÜ;dc5@é÷’˜ÒÎ/*!Û¸eòŒré ±sª[ZÚ4Îèd„"EÞÀ ñÏ=:Õ¨åIÚêJãp%IÁ¬q£^EcwhŸeawS+1åÀùNW#=GSÅZ·Òä‡K¸ÓÚUØá‚J¹ÞwKzœ÷î=)±v- ëC Ì.¡1Fpïæ ª}ÏjVº‹ìu¬±…,a±ïÒ²Îs* ´‰€E¥cpÄž8õ«-¦ÈtíNÙZ0o$•£Æ@PÊÓå²2t?0>àžªý†’öÖ× .Ñ$Ѭ[–MÃ`q±qúýhè2ÔZ¥„ÖÑÜ­ä>T„c ã8úóÒ§šh­ã2O*Dƒ«;ñ5“ý—~c„²X»ÇlÖÅ]˜¦Ó˜|½xäzw§ßZËmk§Q®ÞÅ”hÝüÌ!\¡ˆ<ç8  yj©µÌ!e8‹Œ?ÓÖ›mmw$±C*´¹GLüÊAÇOOzÅ@º’ÎÓÍÈxæ…¤Û€Î[ƒ±½}¾µ«ci= ¸¼§Ýž6Þwã†ýs@ û3 Ì.à1Fpïæ ª} íOûD8Ï6oÎá÷}~žõ‘‘}P Û0µ”<îå(B¸-´3‘ÁÆ)D¼ŽÔGÛ3¼E feUó·Ë€xÆ8  o¶Z‰|¯´Åæmß³xÎ޹ǥ4_Ù”Gp‘¶£ úSTdѤ{kØwÅ›BA#äPn:?*ŽóGº¾¸ʰ(hŒ2C¸P¹ÎA1ŸË æ.´÷0[gš8ƒ#Éô棖úÞ5Ÿl©$–è]ãV€¸íPÜÙÏöøní– LqŠNÄ`>`pyâ©®‰>DlöëFb’®|É †ŽÝÏ'8€Ó[È Á¾Tî2FÎŒàôô¹‚Ižæå—E`Y~£µdK¢ÝKÆM¯ïíâ†WbKE³ºqϯnkJÊÙ­EÆâ¤Ëpò‚¾‡Ï¿ô¥š(¢ÂŠ( ¼/âüZ·ýwþ‚½Ò¼/âüZ·ýwþ‚ª"g¦|2ÿ’ý}É]Erÿ ¿äŸÁÿ_rWLÒ"²£:†s…òßJOq¡Ô…€ê@úÒÕ0Dn§ó#GÂ&7¨lr}~”€«½¼?:7¯÷‡ç[¡m¿çÚûô¿áNÙkÿ>Ðߥÿ v ˜×ûÃó 0=?JÝ+mÿ>Ðߥÿ ÍÕDAí¼¸£B\ƒ±äm>”X.U¢š$C1ˆ7ÎqÙÆiÔ€(¢Š(¤Þ»ÂnˆÈ\óZZ(¢“z‡ ¸n#!sÉ´QER+«çkÁÁÁÎ¥5fæxUÁxÀ,¾™éü¨ôSc‘%£n ÅO±E:€ (¦K*A Ë#DRÌǰhôR) ¡È`>Ô´QEW…ü@ÿ‘ëVÿ®ÿÐWºW…ü@ÿ‘ëVÿ®ÿÐUDLôφ_òOàÿ¯¹*üÖwÍâ k··ŽHÒl#‰ ò£ØAÈÛÁ$úú ¡ðËþIüõ÷%užáÐ)ÖDý²ä¾R6¦ÓIm®žT€Ì²"©• “ßëHfDŸÚ–úuÔŵ¥ŽÎsu$ÌÛ ˜; Yãé³·^jGTk+°®¢–ÄÀBÜ ǯ›³qߌmè}vÖÁÔ&`U´×`x È„Öí)ÿè'ýýOñ§qXÇû¦ð93ê/åÚÊöä¢!÷|ªC`±ûàäVÅã9û˜0ç–ÆÚ?´§ÿ |Ÿ÷õ?Æ¢–Y®ç…žÜ±o™Ã$c}h¸XÊÔ὚ø¬_jò!ÊfQþ´nät;z‘Ú« mBÑL°Ç}pÛîÆó9Ü€/©ã¶r}Mt4P;jsHn¡·_¶å³Gp_9e)åñß¼#wãøS=RâÊÁÄ·kÛ² ‘Ø>ó‚Áy?.>÷µÓIr€%‰$äPÃõ§Qp±—{nÿÛ6· Ä`dýªä©‚»ÁûÜTz4w‰:–ñ@·Åɺ$†Ÿ#”Ïo½÷~\b¶(¢ác’-O˾Ke¼rÎÎ5Ýÿ2"·w8)üéÖ¶“%íœ÷+{<`J¨Á'V,…Cçæ+Áå¸õ®‚ŠŒKû;¹ï.$Sx’Ê•ÕJ“ûÌqÓ©ê*¥äzª@ðA ñh¤—ìòƒ3’7 €íàŒw|ŒWMEKiâ{ÅŽ åg»ß#DdÃÂHÎÎvîÿwæëI%œâ[‹»8¯Ñ”AäiA`î ­÷¸þð$ è(¢ác[;ùæœ;_*¯ÚZ"’ºüÛ—Ëèyã8"¡¼žä\Æ.ín\Ûù+: Î7† Æsžð®–›åGæù¾T~`à>Á»óëBab† ’R6‘/Ô!Ú-wñ&‹g8ǯµœmubš/.ðÌðη>i>S’À™ù}>ïlæº*)ƒ÷^rN ·}w›iw¬"EY'»™®N‘’;ôíNÁsRŠÁmVþ{ù¢‚50#?u[i@ÛÆ[=úmíÖ¥Žòæ Çr·QÜOåÇó”à´`üÜž}E ›4VÔ¯mgcu< ]vÙ S…ƒ}ãù~µ]u;Û–‰àA¶êJPQÕ¾ò‡#´X.t”W=wqu§_fê¿–±ùÎû¡ëŒtïRÏsëÂd‚ó`!PA‰˜3ÁíÞ‹ÍÊ+j÷ÐZ±™ ‘ÚÚ)ÕÂX÷¶Ó¸dä ç5rÚúã욃»ÇröŽÊm…¦O­NŠÅþкÙj¿o³Í—3y"as·ïrO®GCÅW]Neiï¶"Êö0£÷Ž }9ÏÒ‹ çEEbÿh^¼ÉiÅ»1»ý¥b%H1³.î£ëÞ¶»zÒŠ( ¼/âüZ·ýwþ‚½Ò¼/âüZ·ýwþ‚ª"g¦|2ÿ’ý}É](†%”̰Æ%aƒ A¸¯Zæ¾É?ƒþ¾ä®¢“Üh*5··A„·…yÝòÆ£Ÿ^jJ2=iÆ‚`Í,Ê6‚Ñ‚@ôtö§¡‹PN2@Á8éFG¨£#ÔPV‘J¤1*–ÜB Ÿ_¯½;b˱pßxmo¯­‡¨£rÿx~tl@A ÁÈùG^™úÓ>Ïtsoôûå®WèqÅ?rÿx~tn_ï΀+Á§Z[]½ÜqŸ=ÁFlœš8b‡>T1Ç¸å¶ \ŸSŽ´íËýáùѹ¼?:gÙ­öíû4CoÛå.7zã}éeŠ)ñçC¸9bÁõæ¹¼?:7/÷‡ç@b‰¥´Q™Tad( ¡ê)QJ,1*±ÜUPO©´íËýáùѹ¼?:6!9(™Îìí}~µ¶¶XÚ%µ€Fç,‚% ßQŒ“rÿx~tn_ï΀`€¾óo `6†1®qéœtö§BrcBIÎJ޽3ùRî_ïÎËýáùÐ%·ŠXš6]ªË°”ùNßLŽÔÛ;;{<›X„iÄç֥ܿÞ—ûÃó }šÛc'Ù ÚÇs/”¸cêF94òª[qE'rTgŸOj7/¨üèÜ=E"Å*¢E*ªªûÔêLQK‘ë@fŠ+Âþ Èõ«×è+Ý+Âþ Èõ«×è*¢&zgÃ/ù'ð×Ü•ÔW/ðËþIüõ÷%užãAš\šJ)¹4n>´”Pî>´noZJ(w7­›Ö’Š]ÍëFæõ¤¢€szѹ½i( ÜÞ´noZJ(w7­!“€¢®il¶“É›v…íÖÎe#ùTÛ-çÚûô¿áNÁs ÍߥLô`kp¥¯üû[ÿß•ÿ ÎÕ„J-ŒqF„Í‚QälcŽ>‚‹Wqõ¤óG÷Å6Cˆœÿ²k]Ê8ä–+dA–w@è9$Š@dùƒûâ1¼?:Ú…ì.#ì¨z2F„Ä “e¯üûAÿ~—ü)Ø.`ù‹ýáùѽ¼?:Þ)kÿ>Öÿ÷é¡Y¬d¸’Ýa·2Duò—€sŽÞƋ̊ð¿ˆò=jßõßú ÷aÜÿ3^ñþG­[þ»ÿAN"g¦|2ÿ’ý}É]Erÿ ¿äŸÁÿ_rWQIî4QE (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ‚â9.<=«Á4Žþj*(ÉbbL?ž™óÙ™‘mZe’_02ºŒ|ª¸9?ìþ´Oɼ¸¹Zmœ¶M‹ÄÏ4>IšB`ÚÀ´‚rFãQyŒ–²Gnºª@æÝXNò Kù‹æ•$î ·9#åô­oí)ÿè'ýýOñ£ûJúÉÿSüj¯¨­¥Œ›«}Y`òPÞ›X¯e +HbÚ §ÎÃq<Œôæ´]fŽÇKŽâV–Pà<Œ…K-ù ô5/ö”ÿô“þþ§øÔSM5ܰ·0¤.\–u;¾V\ ½ŸÂ—A„ßê$ÿtÿ*f£ ’Ç¥\g»·€«Ë.òFÌ·ø°H8©$]ñ²âS¢¿¸Šâ6Æ4TÊʘ8Ï&š¤·óÉÓìoíÂá£eŠdÜÛ¹ Š6Ž;¸©á·Ôc¾[„kÍòÝÜ+‰$vŒGƒå¤áF@ÁUïí)ÿè'ýýOñ£ûJúÉÿSüiˆÅxµ¦Úª&ª$¿ÚO<³­÷6ó·v?ÕñŒV–‰ݽԦèÍ#=¼?¿x™w‘»ƒžŒš±ý¥?ýäÿ¿©þ4i\vÓäÿ¿©þ4î+ÚÚ¡úÿ3^#ñþG­[þ»ÿA^áoCn‘±€ç¹ÍxÄùµoúïýzgÃ/ù'ð×Ü•ÔW–x[â¿„t_ìKÝ!îe‚w,D¸“Ó§­lÂæÒÿè\oûþƆ® ÝÂÂæÒÿè\oûþÆø\Ú_ý ÿÏøÒåÎîŠá?ásiô.7ýÿ?ãGü.m/þ…Æÿ¿çühå ÝÂÂæÒÿè\oûþÆø\Ú_ý ÿÏøÑÊ;º+„ÿ…Í¥ÿиß÷üÿð¹´¿úþÿŸñ£”.wtW ÿ ›Kÿ¡q¿ïùÿ?ásiô.7ýÿ?ãG(\îè®þ6—ÿBãßóþ4ÂæÒÿè\oûþÆŽP¹ÝÑ\'ü.m/þ…Æÿ¿çühÿ…Í¥ÿиß÷üÿ¡s»¢¸Oø\Ú_ý ÿÏøÑÿ ›Kÿ¡q¿ïùÿ9BçwEpŸð¹´¿úþÿŸñ£þ6—ÿBãßóþ4r…ÎîŠá?ásiô.7ýÿ?ãGü.m/þ…Æÿ¿çühå ÝÂÂæÒÿè\oûþÆø\Ú_ý ÿÏøÑÊ;º+„ÿ…Í¥ÿиß÷üÿð¹´¿úþÿŸñ£”.wtW ÿ ›Kÿ¡q¿ïùÿ?ásiô.7ýÿ?ãG(\îÈÈ<ʼ/âüZ·ýwþ‚»Ÿø\ÚYÿ™lÿßãþ5Ä]Ùê^:×õSJ±,­"³£J€¦FR3÷OJ¤¬&ÿÙfotoxx-12.01.2/doc/images/edit-pixels.jpg0000664000175000017500000003467511701011016016614 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 262 357 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀä6"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ßÒt½=ô‹k Ff·Œ’`RI*9':Øi-;@,l¼ÕŠý3ƒß¥I¤ÈÃþ½¢ÿÐ3V, 33$èq Ë?Â|úPMa¤@Ëcd»Ø*æÝ9'°â¤þÉÓègÿ€éþ[L/5ËÉ~6êŒy_Þéëžçð­Zç/u Ø]=µÔ6qÍ7/ØóŽ3Ô.;Ómµ_ Ý\Åovo,¬ìXÉ'ªÖ•¥´×:‹Ím ö¬nxÃyqúŠ5+;X …ⵂ7vød‰A¾NàPÒéšjFÌ4Û#Ÿø÷OðªŸgÓÿècÿ~ü+Rçþ=äÿtÖ^kHE5©mÙôÿúØÿß…ÿ >Ïaÿ@»ûð¿áFi3WȉæbýžÃþv?÷á“ìöô ±ÿ¿ þfŒÑÈ…ÌÃìöô ±ÿ¿ þ}žÃþv?÷áŒњ|ˆ9˜yô ±ÿ¿ þyô ±ÿ¿ þ™£4r æbùô ±ÿ¿ þß/Nÿ m‡ýøOð¦Ë†‰Ôô*A©Ž…až!Àü?Â¥¨Gq§'°Å‚ÁŽK±'Úÿ ‘¬­QK6h w6ËþØ­ ²¾À›U¶îrjåñS+¨3gpÎ~勵‚ï©Qm,Y—I±!FIòÒ‡³´FÃi@ã?ê§åZªÇ ÔkÅUoïP $îAýÀ;}iiØz™«obÄÒ¬‰=·_ð§+PÊ­£Ù‚Ç6ê3úT–­›ôùv|ßtv«O4[ÌcJÏ0à‚óÒ›ŠOa&û™ïmdŽU´«Â<„ÿ O&Ãþv?÷á´"†9'0ªü6OÆ’Þ8ŠK,‘€CíÙ´£è(´{ì¥ö[?(Éý“c°gÈN¿•3ɰÿ ]ýø_ð«î±ý–@ŒbqÆ9ÆE|Šª Œœ2ãša]•|›úØÿß…ÿ <«úØÿß…ÿ nhÍ_$Içc¼«úØÿß…ÿ <«úØÿß…ÿ fhÍ‘v?ʰÿ ]ýø_ð¤ò¬?ècÿ~ü)¹£4rD9Øï*Ãþv?÷áÂ*ÃþV?÷ᛚLÑìâì—aÿ@«ûð¿áZ?ÙZnqýgÿ€éþ—šßÿ–ô¬ªE+XÒ ½Î'⥶•lÖö°BÆ|J¤§ÐQSüIÿE¯ýwÿÙM™gI¤ÈÃþ½¢ÿÐMöhþ×ö–ËHjäðƒ¾b}k"ÖÞ¤Ñ#¸‰eO°Úã#;cçõ­ì7þ|-ÿï@Ïmï‘$G(êpG¨úJš©di¿óáoÿ| ?²4ßùð·ÿ¾!ÓÜM4ßÜÂ&}슱‘œÆTžŠ)Ny ~v¡u*$‰&±€J°aœ(=@§di¿óáoÿ| ?²4ßùð·ÿ¾Y¸RÐ:¨É#Y¿fŸþy7åV²4ßùð·ÿ¾Ùgüø[ÿߪ3å%Æå_³Oÿ<›ò£ìÓÿÏ&üªÏöF™ÿ>ÿ÷À£û#LÿŸ ûàU{V.DVû4ÿóÉ¿*>Í?üòoʬÿdiŸóáoÿ| ?²4Ïùð·ÿ¾Õ‡³E_³Oÿ<›ò£ìÓÿÏ&üªßöF›ÿ>ÿ÷À£û#MÿŸ ûàQíX{4Tû5Çüòoʳ\Ï&üªßöF›ÿ>ÿ÷À£û#MÿŸ ûàQíX{4S6³A‰¹ö§ùwÞ³ÿßUgû#MÿŸ ûàQý‘¦ÿÏ…¿ýð(u/º u*yE÷”·žMHâùÔ«ù¬§¨5?öF›ÿ>ÿ÷À£û#MÿŸ ûàQí<ƒ“Ì®Rô¦Â%)éړ˽Þl›€À>Õgû#MÿŸ ûàQý‘¦ÿÏ…¿ýð(öžAÉæUònüÏ3d›óÝé>Ïu¿–û³œã½[þÈÓçÂßþødi¿óáoÿ| =«ì̪b¼#d<îü}iB_+—PÍÔŽõgû#MÿŸ ûàQý‘¦ÿÏ…¿ýð(öžAÉæUÞØYFã“ïD‘^K1d|tÍZþÈÓçÂßþødi¿óáoÿ| =§ry”¾Éqÿ<_ò¤û%Çüñʯdi¿óáoÿ| ?²4ßùð·ÿ¾?jÅìÑGì—óÅÿ*>Éqÿ<_ò«ßÙoüø[ÿßì7þ|-ÿïGµaìÑGì—óÅÿ*>Ésÿ<_ò«ßÙoüø[ÿßì7þ|-ÿïGµaìÑCì—?óÅÿ*>Ésÿ<_ò«ÿÙoüø[ÿßì7þ|-ÿïGµaìÑCì—?óÅÿ*ÛÇÌO¨ÅSþÈÓçÂßþødi¿óáoÿ| ‰O˜¨Ç”ç>$ÿÈ"×þ»ÿ즊£âð– ÝHôŸŠ’Ž—Më¢ÿØ<ÿè1VÍci½t_ûŸý*ÐÔ.…Œ×,¥„J[hïH 4VT·š„ o‘[«™6ÆŽÅrI?‡jªo^êóO2 ŽX.äŠUS•%PœlL ú+ÏW¹™¬äšÖÞø1‡kË€HÝõ·Jµ£]\ßXGup± ™C"ÆI {æ‹ËÕqÚ%ˆ¸¹Ž3òîwu¥ªZÿŠfqÿNçùRÕþÕð÷ü÷±ü–í_Ï{ÉkˇAKY{_#ÑúŠþcÔ?µ|=ÿ=ì%©m®´k¹<»ck+õÂ(8íýkÊ«¥ð/ü…fÿ®CÿF%5RîÄTÁ¨AÊçl¨±]Ë`*lV :KÈTµ9¿—þ¹'ój’µ8Š(  zT.‹5ÜPÉþ¬«1ûÄcõ'ð§KVóB`EŒ»m*£ŒuÅKEQÕ.æ´Š³¢4“L±0œ ÷⨶¥,’Añ„š;ä†O.BåIÜ{ nQ\ýíåÍæ…}rR(íLrÁ&CƒŒžÝhè×­¨Yý *¬' ,@%½{PúBqÖ–±uë©-­§!óŒ[@R»‚ƒœ±^ý‡ã@4µ“ O5Å”Ï匳F£`€³“ùTº…ÝÔW¶¶–i <ë#)  z}hFŠÁ¸×Ùtèn"XÄÌ´,®çä88ÚO—»Änn¢qʪîvüÍéÛ¯Zߢ¹ë½CPûLVŸ¹Žå.ãRT’ެà÷í[é¿bù›wãæÛÓ>ÔêLŒã4Ù˜¬.Ê2ÁI’ W·FdY—&S÷¿Ú€$¢¢¶bÖèIÏPûÀü@ñ¬{mv{‹Ý©hæÜÈñîIòíÏÌ[q‘޽é»Eb&«uý‘ äßfŽK‚<” îNsÆ$ž;S?·f{[)ÄQAá¼ÉfݱmÎ8Ï8Î:SzŠÃ¸×'MJ[{{Wš8]öÅ#,$ Œ:šÜ=hñüŠÖ_õ÷/þ…%xÇþEk/úû—ÿB’ŠétÞº/ýƒÏþƒjÍsÂñJ¡ãqµ”÷•¦õÑìô«f€(cÚýœBÍ;`èÍ),„p6žÔäÒí#ŽDaäÈeVÜw=I=óWh  6úM´âX‘ò¹Ø¬ä¬yë´v«6¶ñÚZÇo"8—j‚rqRÑ@ U%ˆÜèíœ"ÛŸLÕº‡ìì¼G;¢ö\ÌRÉ8ñöÿ÷éøº?á ùûûô¿ü]u¾LŸóòÿ÷Êÿ…LŸóòÿ÷Êÿ…O$N­Uîr_ð„¿üý¿ýú_þ.´´/>‘vóyÍ.õ ‚ЏùÏÞ>•·äÉÿ?/ÿ|¯øQäÉÿ?/ÿ|¯øP ¥‰©%fÅS›Ùëš6©ª8¢–%‹³ucRU˜Q@†IÈaÐäpAö¡"TmÙflcsœœSè  µƒj[Ư°G:HÄ1S×w§G¥ZD‘ª«Ÿ.a8frYœw'½]¢€3ÎiûåhŽ`CÆ$;9ê@ìjŽœ6ÒÍ$*TÍ‚ã<3\uõÅX¢€ cÄ®ÁŽU‡FS‚)ôP3Œ’ÝYŽIªŽ–oõ IšVH Ylr®KŒcéZTP|º-”‘E¬‘,HcS…ISÔ\ÓŸI³tddm­D@oáS•«ÔP+.ÖêI$‘\<…X²¹èG§ZµãTˆQŒ±É?SO¢€£û¢ ^h¢1;ÄÅã ‚¼qõ5-QERt¨ÖVq¹!‘”ô Z–Š|Ÿóï/éþ4o“þ}åý?Æ€$¢£ß'üûËúäÿŸyOñ  (¨÷Éÿ>òþŸãFù?çÞ_ÓühJ*=òϼ¿§øÒ¤ò0U”à«Epž1ÿ‘ZËþ¾åÿФ¢ÿÈ­eÿ_rÿèRQ@.›×Eÿ°yÿÐb­šÆÓzè¿ö?ú U³@rWЬú®ª°ÙÍ%ÿ™ÙçHÎ";Wè£Øõ®¶£HcŽI$D ò]‡ñ0?Jç.ṓÄqJ-;¤Xí›ç‹“ ãF ,:a¸žÎ;Ë&’qtβFvŒçi?^ÕÓQ@¾Ÿha½µ’ûOš` 1DÍÄÂCŒñ•ùHäÓt«&ŽâÏɰžÞæ9¤k™Ú&Ed%¸Éá³Æ1šê¨ ,si¦ÛC³™,X\¤ë,ê±þõÀsÔu'¡¹¶3‹‹¦²¹r×/$PKfî²|Š>eÇËÓ‚k­¢€9‹í9îQºk+o·eRY„wŽ+FþÉou}4Ü[yÐ$r—Þ™Ul.3ظ­j(¸Xåã‚é¼Eÿdh$º»%³1à€Lt¼ˆÉö»‡‰°äƒÎþ„Òºª(–³†âÆÖÆIlîX–8Y™v@*E}œ–·º{ )%›Ë‰$2Û¶ pJÉÐc¸®¦Š/­ÂÁU®¿ÖZÿ×u«5 ÄM B„G»º([ƒØç¬àºK‹¶.ÅÄ·Îa‘ y[Ì7ðÿ{ƒÏ÷þy[ßÖÿâh°\»Xo}oemmö©ä…ÜÈQÆq×Û½_óïç•·ýýoþ& HgXc’ª9sÔcîûRc2I‘(ݲŒ0åzŽÕj¡Ž9<ß2B™ T$õ ÷Ò¦ Š( ¿Üo¥3í‘Ú[X¬‰œ¤I´\óíÅ=þã}+?P·ž{-”I-´‘Ì#-·~Éèphóê–‘Ü\Ã4«Ù•G…L6qÉúSÿ´l¾Ëö¯¶[ýŸ8ó|ÕÙŸ®qX2Ø_]µÍÔ¶â'žk}°™ФlI$ƒŽç€{Rͧ]G©MyªMÞyÉåÁˆ)ažÈ=q@3RËY¶žÊK¹¦†g‰diV°zsV缆/7y¤fMÈsxõ®z Øc·¹6JïÔÓ]éœs·#ëVb°¹Ã—–»O8•–a„Ýœ.zJÀ“wÚ-Ô²,P•ºF >¦˜Ú•Š[-ËÞ[­»,¦U~‡8¬‰$ÕeÒ–¬e¶–%Œeˆ—‚ÄŒã5N-:ò-<‘iqö‘w$Б4[ãÊã-“´çœCݽý¯f5bÓÆ²´k${œ bq·žzSü~ÍþêÿZηPƒUŽâ[u›Î¶Ž)ž7P#u$“‚A#žÕ §7sº¿Ö€G ãù¬¿ëî_ý J(ñüŠÖ_õ÷/þ…%Òé½t_ûŸý*Ù¬m7®‹ÿ`óÿ ÅRê‘êöZÙdIK¤´ÁÈñšÔ¢²ãÔç¶ÈÐÁ½³´~cÌA,1Ômàs×?…V‹ÄKk#GmN— Ñ)Øw ƒ¸®JÝ¢°å×gˆl{H£•&0Ê^b"B îÛÜØT·zµÌ7 œrÅkË+yØlOÊ1ƒÓÔP½y¯%µÔ(«‘I³8ù‹»¡ÛŒwõ¥}fX¢¾¹’Ùµ¤"L»°Çðãsë@V kó¼LÍ Þlq¯ï·´W昞…€ã“õ«W:tw+p³Oo2®Âð°—9ÚAŸÆ®Q@¢Óc‚駆{ˆÕػ®<¶cÔFyö"˜º= ‚Þ$hàWE ÝCg9ãÞ´(  Ñ£D Š?µ^€þêo0oŒc# Õ˜l£Šån<Éd”Cäîv#9Éã®jÍU{¢Û±à —'Ò¬Sd(¨L›vcÝ(“OŽ[ŹšIdØCG7È„wu?\ÔcKCv.%¹¹™”±]ÆØÉdbG9ª»ôKûå(ߤzXÿß)@'Ñ cß5ÈdÊg|Ò'£ÿί¢,h¨€*¨À°¬úG¥ýò”oÒ=,ï”  šÂ’ ‰mm^ÒìÛÈ"E;—r• gQØÔ›ôKûå)ûôßútÿ¾V€n‚9£]ßdL ;e+É?Z¨ h ‘oåmïå€éRÐEPThCÐ;UBGò§¿Üo¥KhÑ!ÿ®kü¨¿ž¿Ý—þý·øQç¯÷eÿ¿mþ'ö¯‘q7›û»f+)Ú~ROׯjdWUe`C ¥Tó×û²ÿß¶ÿ <õþì¿÷í¿Â¤¼½KCpXÍ*Ä1ØžõgpÎ3ÍRó×û²ÿß¶ÿ <õþì¿÷í¿Â¥½¿¶Óá]Ì"Œ°@NzžƒŠŠóRKK„…‘˜¼RJ=zÿv_ûößáNI@Jœààö"¦µœ\ÚÃ:‚¢T푚ƒþ_gÿu­p¾1ÿ‘ZËþ¾åÿФ¢ÿÈ­eÿ_rÿèRQ@.›×Eÿ°yÿÐb­ŠÇÓzè¿ö?ú U±@[^ÛÝAçC )’2xÆ*_6?—ç_›§=kšOc¥›3¦ºÌ· ecË*ù™ëüC¾ ²¸’ãʶ³ahŸfh-Ã|Û²An¨(¥ó~Íë»Ó<ÒyˆI×+Ôg¥s÷šd>¡r–„Üý®†@¿6Ñ·v§\Ô[½µ¶°±ZÈ-Ú XË4;q'å üc¯Ò€:u‘K+©©1 oÞ»}sÅsvöóˆî'Ó´æ‚3f±ùRFK&G!{àgžù¨­ôÙÚÖê/²Ì`’êT’@ûÿ à -¨\ê|ÄÂë†éÏZ<Äß³zîþîy®sXÒŒš‹ ÿch8¾Ë ¿”rs€~ïQȧ\iry—— lÍr.àhfÛó•}1œþ4-A» ‘]AFiÙ###¨®z=$‚òÎêÉÖæS!7l™Vå~Ëj—GK›Í:òñ€ŽêìlSž›h9úäþ4€Û¬§pzUx¯£šúkTäŹpFIý+›µÒ'ûëwqÝy7GcY9€ÃïƒÏ½K%Œ’G¨µŽŸ-¤O J#dò‹á‰`>£ŒÓ¦ÆT°u*:zS 2¤{Šã¤¶û\×`³– xæ…¤aŠ€sòcƒ×Ñh–Ëka±<ð¬å‚ÍB¹ìtÍ ¯t{pFA™rz±UîÖ[×eþ´eï­Rö;6™~Ñ %cœþßG«e%áµIÁ˜1´€H䀨Á#ÐŽîÝŽ¯c4q|ª_Ìp?ÙÀɬ´²ºÁaöyȹ’fœý§v0{“¸ }hbÏT²½•¢¶›{¨Ý‚¤dgŒ÷OªY[Ý if )ÇI ž™ `g¶k&Énc’ÎG±Ÿjñ¸fF;@ Ï#åÎ~”_[\´·öék#ý¹ãt”µǶ1ŸÆR¶i~Ãl"Ú?t¤–ú*èàb°¤¾‚ÊÚØÜ´Ñ£Ä¸pNÜí/Ïjh¹&ê2Wk›#ñZ}U‹Ë•‘ DÇl‡æ^W­Z Š( ¿Üo¥-³bÖúæ¿ÈPÃ*G­WæŽ5ŒÛ»mr¥pqõ4r·QAªØ-•įy+<2"f2Ët\`õ¨î´·2jÑžå$·û<¡ï•T§Ó®k{Ηþ}eü×ühó¥ÿŸY5ÿ=NìL5(¼Í>f½™®¼²ÊbÉ#çèö§ÛÙ̺„8³™o–ñ¥–ð¯ÊÐäñ»¸#oc[¾t¿óë/æ¿ãG/üúËù¯øÐ‚Æ~©mw¨êKi··ˆœÎ„«»‚¼c© Ÿûꩬ7ò%’Ío)’+{‹Vm§°·Ðã­nyÒÿϬ¿šÿt¿óë/æ¿ã@”Ì4«EtxÝbUduÁ ? rœÝÍþêÿZo/üúËù¯øÒ¯¾Iv—À œ‘Џ-Æ?ò+Y×Ü¿ú”Qãù¬¿ëî_ý J(¥Ózè¿ö?ú U³XÚqÇö)=?³Ïþƒj‰á(Ž%M’· 1=1ë@QEB×­Ò[û×Rê1Øc?΀&¦IKG"‡FeaE>˜²#;"º–O¼ ò¿ZC0Àµ-29PLn®*JœàŽ¢ŸLAEPsÃÄF)ãY#nªÃƒNETEDPª£€:šÌ¨¥‚¨$œ@¦KsDÑÊц °àÔrÝÛBˆòÜCÉ÷œßOZqž2ÂeŒJã*…†â=@ ÞÚ Xü»xR$ÎpƒÔ´Ô‘$ÆêÀ SœÔS¨¨¦ŒÈ©‘ƒ.zdzÔ´P|û¿ùãoÿ›ÿˆ£Ï»ÿž6ÿ÷ù¿øŠuß>ïþxÛÿßæÿâ(óîÿç¿ýþoþ"E7Ï»ÿž6ÿ÷ù¿øŠ¯7 Gˆ"ªä±ì:ýßjµECn$ó$+¥@ROR äè*j( Š( Š( Š( Š( Š( Š( Æ?ò+Y×Ü¿ú”Qãù¬¿ëî_ý J(£²£ÑÀêtæøìuBÒxç²ÑôØ÷»iÐÍÓ˜ÂI>ƒùæ´tÞº/ýƒÏþƒläã8 V»Š K›{‹™..$ž6I%gVÀr¸SÀÁ¥Gi kµ“O¸žæñleó²3”—Ž0~ï=½«®Éõ4'©4Ï蓉/ã[K«‹˜~Ï›“3³l—Ž9û§®T~U\Çy¥¨Þéñ´’É7ÙsÀÖüèMu“Ô“FMr ²éúsÚÁ3¤_íž]Ì¿)\ä²òldZž(å¸60¾£4Ñ4W²[Îëœcn[9lsÖºŒŸSFO© ,rÖr^EonöÓÜM=Μò•–BàÈÁôëÐScº"Úé´ûÛ©ã[ižGf1ËŽ1ŸºÝx1]^O©£q=Ís·&‘ii{—2FјåW™äùFÖäŸâÀªõÕŠŸ{ÍÓ´pe‹±9p3“Ï<úÕÉì⹞9fiË!„{¾BAÈ$wÅXÏ9¡ëpZÕõÕ¤:Fm?ÙRk›p‹-ÀvÇ'ðã¹¥¼°‰EœšuÎù%Xãƒå  €û½$ŸZé7ÜÑ“êy¡…Œ? ÜÉ$-lBùp()'*ÄõnäûÖå“ÔÑ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ŒäV²ÿ¯¹ô)(£Æ?ò+Y×Ü¿ú”PK§sý‹ŸúŸý*ר¿Ý‘¦õÑìô«f€±º(Ø¿Ýê(»û¢‹ýÑN¢€±º(Ø¿Ýê(»û¢‹ýÑN¢€±º(Ø¿Ýê(»û¢‹ýÑN¢€±º(Ø¿Ýê(»û¢‹ýÑN¢€±º(Ø¿Ýê(»û¢‹ýÑN¢€±º(Ø¿Ýê(»û¢‹ýÑN¨à…gò3çy+JvÅþè£bÿtS¾Ç¬¿÷ñ¿Æ±Åë/ýüoñ ì_îŠ6/÷E;ìqzËÿüi²Z"ÆÌ(`2òû¢‹ýÑI‰õeš‘‰î]˜**±’séô ì_îŠ6/÷E;ìqzËÿühû^²ÿ߯ÿnÅþè£bÿtS¾Ç¬¿÷ñ¿Æ±Åë/ýüoñ ì_îŠ6¨þKöX &à34ä~µ Z/˜ä«2ç×é@7ŒäV²ÿ¯¹ô)(£Æ?ò+Y×Ü¿ú”PK¦õÑìô«f±´Þº/ýƒÏþƒlÐEPEPEPEPEPEPEPEPEPEPEPYÚ”¯‡ïž'due8 ç±­ª#ŠâÚ{yÔ:32º“Œƒô¤32âáôIm+‹‹ˆæÌM!ü©»p'‘èyÇ5'ö½ýºt-¤ilÞæ?)HTgiÉäs׊»i¦ØÙ³4ì»K»3±_L±'ÔéZ}ºJ‘[*¬ªQÆæ?)þ“Àö¦ÄŒÙµëû+v7+ò¼Ë‰@.ÁpA'8'Ö´´ë«ÙíîEô; på˜÷Œt“Œ}jG±³%º81y$6HÙéþy¤ŠÞÞÆÖD€2¡Ò3öõbh¤ÐǼ_îåD-¶æsŒü‰ÿ³Q"Áê*j0[¹A8%ø-þ"ÌíöÎVêöäÊå£YJÆ€6mqŒóUâñ ÙK¶ÂH‹h×6ò0Àtà±ÈéÏ¢4«tnVÜ,¥·®ÁKz•i?…6-N…dXíð²Fbe29UŸ”}1L o­j¡áœ[K;G Äꌊ<ÆÛóOCïRê–¥g-µšyS\Ê®í"[±\.8 »=úæ¯Kcg6ÿ6}ñˆ˜6NPÿ×ëQ6“`öéBÅ#bÈL¯½Ië†ÎáùÐ-H4¹¥›[’[˜Œ35ŒEã?Âw6E_¶ÿVßõÒOý Ò%­´S,ÉY?(6㾇ž[N`ÏbîG¸,H¡?ŒäV²ÿ¯¹ô)(£Æ?ò+Y×Ü¿ú”PK¦õÑìô«f°íd0A£Nb™ã[„ÅI‚V†¯jEÿ>÷ßø/ÿ@¨ª?Ú‘Ͻ÷þKÿÄÑý©üûßà¿üM^¢¨ÿjEÿ>÷ßø/ÿGö¤_óï}ÿ€Rÿñ4zŠ£ý©üûßà¿üMÚ‘Ͻ÷þKÿÄÐê*ö¤_óï}ÿ€Rÿñ4jEÿ>÷ßø/ÿ@¨ª?Ú‘Ͻ÷þKÿÄÑý©üûßà¿üM^¢¨ÿjEÿ>÷ßø/ÿGö¤_óï}ÿ€Rÿñ4zŠ£ý©üûßà¿üMÚ‘Ͻ÷þKÿÄÐê*ö¤_óï}ÿ€Rÿñ4jEÿ>÷ßø/ÿ@¨ª?Ú‘Ͻ÷þKÿÄÑý©üûßà¿üM^¢¨ÿjEÿ>÷ßø/ÿGö¤_óï}ÿ€Rÿñ4zŠ£ý©üûßà¿üMÚ‘Ͻ÷þKÿÄÐêàŠC™"G>¬ Õ_íH¿çÞûÿ¥ÿâhþÔ‹þ}ï¿ð _þ&€,}’Ûþ}âÿ¾d¶ÿŸx¿ïUÿµ"ÿŸ{ïü—ÿ‰£ûR/ù÷¾ÿÀ)øš±öKoù÷‹þø«m°e‚ GBUoíH¿çÞûÿ¥ÿâhþÔ‹þ}ï¿ð _þ&€/S$Š9@F®÷†j§ö¤_óï}ÿ€Rÿñ4jEÿ>÷ßø/ÿ@>Émÿ>ñß²[ϼ_÷ÀªÿÚ‘Ͻ÷þKÿÄÑý©üûßà¿üMXû%·üûÅÿ| >Émÿ>ñß«ÿjEÿ>÷ßø/ÿGö¤_óï}ÿ€Rÿñ4cì¶ßóïýð*F!GP03ÉÅS:¤XâÚû>örÿñ4‡Sœ[ßwÇú$Ãÿd GÆÖ?»kÿ~ÏøÑÿ ö±ýÛ_ûöÆŠ(ÿ„ûXþí¯ýû?ãGü'ÚÇ÷mïÙÿ( þícû¶¿÷ìÿðŸkݵÿ¿güh¢€øOµîÚÿß³þ4Â}¬v×þýŸñ¢Š?á>Ö?»kÿ~ÏøÑÿ ö±ýÛ_ûöÆŠ(ÿ„ûXþí¯ýû?ãGü'ÚÇ÷mïÙÿ( þícû¶¿÷ìÿðŸkݵÿ¿güh¢€øOµîÚÿß³þ4Â}¬v×þýŸñ¢Š?á>Ö?»kÿ~ÏøÑÿ ö±ýÛ_ûöÆŠ(ÿ„ûXþí¯ýû?ãGü'ÚÇ÷mïÙÿ( þícû¶¿÷ìÿðŸkݵÿ¿güh¢€øOµîÚÿß³þ4Â}¬v×þýŸñ¢Š?á>Ö?»kÿ~ÏøÑÿ ö±ýÛ_ûöÆŠ(ÿ„ûXþí¯ýû?ãGü'ÚÇ÷mïÙÿ( þícû¶¿÷ìÿðŸkݵÿ¿güh¢€øOµîÚÿß³þ4Â}¬v×þýŸñ¢ŠÏÖ|K}­[¤kT}à¢s‚=}袊ÿÙfotoxx-12.01.2/doc/images/annotate.jpg0000664000175000017500000005340311701011016016164 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 445 585 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀaÐ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ëí’êôÜJu+˜‚ÜýïÿïÜ_üE?ô¿ÿ¿qñj6µ{ÙR4¹x0 £9ýEœV¬|í–ðè/ÿ~âÿâ(ÇýEïÿïÜ_üES—Ež;yeþÓ”ùq³°öÿzµ4ز$›Ê`… ~¼þ”¹ak¦ÒêWÇýEïÿïÜ_üE÷¿ÿ¿qñ7ÙbIîDÅöD7 ¸Éœlà¤2<…U”.Ügæõ£–#æ‘_þãÿ÷î/þ"“þãÿ÷î/þ"¬ (‘ŠÌîwJcM£õ4ÙcŠ+$V.%d ¸ä_j9"Ò!ÿ¸Åÿýû‹ÿˆ£þâ÷ÿ÷î/þ"¬µœi?Ì]C£0=~(kh&¿™´i%ò@ü½±i¿î/ÿ~âÿâ(ÿ¸Åÿýû‹ÿˆ¢XâŠò5ŠA"PqÏCжö°Iq3H]s0Bc"ŽH‹šELÿÔbÿþýÅÿÄQŸúŒ_ÿ߸¿øŠšK8÷Åäù¬CŒñÜRµ„^t{$c#9Á xì1Űigþ¢ú‡ýû‹ÿˆ£?õÔ?ïÜ_üEL,¢yâî±¼^aÜFEV¼Ž(dQ¡Õ—?x§ÓŠjnÀå$;#þƒÿ÷î/þ"Œú j÷î/þ"ªn£uW±‰>Ñ–÷ú j÷î/þ"Ãþƒ‡ýû‹ÿˆª™¤ÍÆ!íspÿ Æ¡ÿ~âÿâ)WçuQ¬_åŽîâÿâ*–jKsþ“ûãùÐè öŒÔûÀÿ˜½ïýñÿQiÓÜG¬_YÍu%ÄqE¡‘TXÉŸº÷Ei/Wÿ{ú Ŷø£Q¶ößÎZæ7:$lŠ}AÊŠž€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€14?øó›þ¾¥þubk4žê)¦fu‡æH¿‡f>¤vôëôÆŽ4šÊe£}QÃ.HÈçŽ+SûLÿŸ4ÿ¾›ühimKÈîÕÚ9“åf_ùhŸÝoQééV*ö6™ÿ>iÿ}7øÑý¦ÏšßMþ4†Coc©ÚÛ¥¼:Ÿ—Âï±bqžäJ3ùTö–—1Þ½ÕåÔ39ˆD¢( ` ç'.Ùý)?±´ÏùóOûé¿Æìm3þ|Óþúoñ C5(¥yPǰçj“TþÏqÿ<%ÿ¾ _þÆÓ?çÍ?ï¦ÿ?±´ÏùóOûé¿ÆµV•ˆp»¹Cì÷óÂ_ûàÑö{ùá/ýðjÿö6™ÿ>iÿ}7øÒcéŸóæŸ÷Ó?lû Ù”~Ïqÿ<%ÿ¾ 'Ùîç„¿÷Á­ìm3þ|Óþúoñ¤þÇÓ3±§ýôßãG¶}ƒÙ>Ïsÿ>òÿß•"¼ÃÇÊÀŸ/?ÌUÿìm3þ|Óþúoñ¤þÇÓ?çÍ?ï¦ÿ[é`TíÔ©!Ôdãq1WR¬ djkGxÑŒìpYëW¿±´ÏùóOûé¿Æ˜Ú^Žˆöñ+>v‚ì `dãšJ¥¶Cp¿R»ö RüÈþ洞ڃ‚)NH'÷~;U¡£éd-ƒÐ†oñ¦Å¥é3F$ŠÚ'Cœ2»pq×>´ý¯½Ÿ™Ë©+;*K—9?»ïëÓŠj}½#hÖ)v±É2yüªÈÒô‚®ÂÞ"¨Hc½¾R:çšUÒ4·Etµ•†AÄùÑí|ƒÙù•¤}FTØñÊGˆ°N:sŠS&¤eY<¹wŒˆºýxæ­ciŸóæŸ÷ÓØÚgüù§ýôßãGµògæPt½’Q+A.ñŒb,tü)åµIò¥Éq!ý×ñzô«ŸØÚgüù§ýôßãHÚF–£-i¥Ûühö¾AìüʵTˆ¦\¸ýßs×µ9^ñ¦Gž ‚¾Zm#?…ZþÆÓ?çÍ?ï¦ÿ?±´ÏùóOûé¿ÆkäÏ̯q-ì—),V÷c]ªJ’O׊¯4w³¾ù-å$ q?­ìm3þ|Óþúoñ£ûLÿŸ4ÿ¾›ühUmÐ;õ2þËuÿ>Óß“ì·_óí7ýðkWûLÿŸ4ÿ¾›ühþÆÓ?çÍ?ï¦ÿ~Ýö²]̯²ÝÏ´ß÷Á£ì·_óí7ýðkWûLÿŸ4ÿ¾›ühþÆÓ?çÍ?ï¦ÿ~Ýöd»™?eºÿŸi¿ïƒR[Û\‹ˆ‹[ÊpI(xæ´¿±´ÏùóOûé¿Æìm3þ|Óþúoñ¥íß`öK¹t ÷9ý+ þf›ÿú÷¶þrÒëº]„£46Á$ŽÖVFWl© H#šþFÍGþ¸[ÿ9kS~ÛUí¾è«QEQEQEQEQEQEQEQEQEQEË[¨µÿ°«ÿZ߬ oõ¿öë[ôQE†QEÍø +êzDr<¶i· ‰Y#8N2Et•GR½°µhc¾C#JO–‚ݦ''…SÚ€0§½»·ûL–W¨–ö0ÀËJ¯î$0ÜFìqÁT+}qc¥ßµµó4ÿÚ#E!L[#L~~™ËdWIgwetZFÅæT0úƒž1Ç5Σao$˜]Kä4ŠWí'æ>Ÿ-1v—¥ÅÞŸk6¢d3¹’.C"¦Ý¡ŽÝ¹äç~báöx¿-xð²]‘¸œ‡9_˜ÜtÁæ´RòÁ/RÉ$›ÊóB€ “”ô䎂§•íĈ%1yc߆¥ •ޝ«M¦Oy>¡ £ù›ÇxåÜ0ÎÝ äç¡©Zî{‘¥O}|öRý®UŸhAövØqÌ=¹9Îxí[šmíµüQ\%¨În ²/BxúŒfœ÷Öoy©H¤I£yLŸ)O“nsïÈü¨¿¿Ù¤^ÜØ2\Kmà)ÝóªçúqX²Ì†ãK—ûL_äÍûÒÆ…F?“[f{ 5¡ƒrÃö¹”’pÍÄ’jÂý”Iä¢ÀïìsõÇõ {K¾šY,`žýlâ[(dDTEûC6r9€0¸<Õj’[iÓ}±Ì1ÛC$É—Ìl¾î¼—ºž¢º—6¾dqIäyƒ˜Ñ€Èúðª÷Ø^Ú´SI†6RûF0Àí'°$r;Ð9rn,ì#°žøX‰,¥¹•ö)3ÌÇ,¹aŽ7tôô«š}ÕÂ)gº™-¬tè$ò#òPç$ŒöÁ½æÚ]…íæ'æ J·â8MnLId>ÊzÇ'o­êÎïuÚ•W·Ûpþ\†ÄìxǧóWcÔîÓBÕ'†ì^=¬íS²)ùp¿18ɹÕRû]¾I„¥Ë%âG;—ýÚ¤ž[ä09'Ž­v;W9عÎz¾¿ZkC €¯ LÈ €€}i å﵋µ»‘…ð¶hæ¶H­/ï–B»˜–‘ó0Æ6Ôš6«5ä“ßÝÛ%ª |èžD§‡¾âzçŠØ¹Ò`»¾ŽêâYÜDÊËW`e9îî냌ãÚ®¢.ÎbŒ³ 3laî{Ó&ÃA–Š(QE†QEgx‹þE½Sþ¼åÿÐ Sù5úáoü嫞"ÿ‘oTÿ¯9ôTßþFÍGþ¸[ÿ9iˆß¶û¢¬U{oº*ÅQEQEQEQEQEQEQEQEQEQErÖßê-ì*ÿÖ·ëÛýE¯ý…_úÖýQE!…TFâH2 ƒƒ@ÖF¯§ÝÞêZ|¶ÓÉn°ù»æfäܘ09Éöü«Kí0ÿÏAGÚaÿž‚€9C£^Åa0–8àÛc$/+Î1+ù¡‹œ€ã'ž™Å7M´]SRiáÓ`ŽÎ;骉  ‚~RTòæMu†â0]H=ˆ¡n-ÕB«*Ø i‰£ŸÒô«» FdÓÒX¶ÉéþŽ<æe<ž›OnF:U߱Ͽqrö t—<»É›p ‚0Ç8ÉÏËšÔûL?óÐQö˜ç ¤9h´HéÞCˆë§ÇnA”bB’–+x ½ýê]KH½Ô&´žÛNK8íÒBÖŽñì”åFØz6åÏWIö˜ç £í0ÿÏANác7V¶žy´Û¨ìÀ·rÒ[3 #rÆNÓƒïôª1éƒSBlãVßj7þbî1ÿÏ<}ìãåÇÝÇ5Ð}¦ùè(ûL?óÐP3eÓ$›Y½º1 ó-(&8%/œwEb[xvét׆KI|üAo’.EY˜€€À'æçœW[ö˜ç £í0ÿÏABv®`Å¡<â{kHbÛª•Óh"ḟ—ô¨l4ÌAue1à Ñ\\+«Íü?íÝâºO´Ãÿ=i‡þz ],nr¯¡j²ÙG5Òﺎt‘¼dÉhQHÞ ä“¿ ëØ×E¤Z‹-.p’¦Ü’²³.I8Êü½úXûL?óÐQö˜ç §p±-Úaÿž‚´Ãÿ=!’ÑQ}¦ùè(ûL?óÐP´T_i‡þz >Óüô-Úaÿž‚´Ãÿ=KEEö˜ç £í0ÿÏA@ÑQ}¦ùè(ûL?óÐP?È·ªל¿úªoÿ#f£ÿ\-ÿœµc_š'ðà“g6üÕwÿ‘³Qÿ®ÿÎZb7í¾è«^Û@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@µ·ú‹_û ¿õ«~ ¼¾ÓôÙ/l¾ÌÂ,ë0l·LcRÛýE¯ý…_úÖ¶£e£a5œ¬È“.ÒËÔRcFcx†;á§ß²½È‘#’Hp#FsòŒ3n=FpíELjPÙj ko7Ú, ‘äY.p­ÏSŒŒgŽjãiIý¨÷ÐÜÎóæU[u¸¨Ë©8Àç¨<~"µT–PH*HÎQ\äº}»Ýép,‰ökYåiW÷ƒ¨L¿0Vôâ·¾Õmÿ?ßb€(Úê—kVO§Ì‘C·îç“ógqŸ\TV^$±¾¹[¬ŒÎÄrŸ½Û×vG¶à3Sˆí—S{Øï•|ÕU–=ÊU±œ{޵ ¬Jb·Õ ÀªËd¡òóÓœdã¶h[]f;Øåk;[™L*7®H~ñüÌ>aß·½;CÔ&Ôô¸.§µ{v‘¹*U²:® 8úàÔZu¥†œìmïÙyŠÒ½ûÈÚ=ýxô©4ÈíôëEµ[õ–(øŒ;.Q}2:Еڭ¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû5Ú­¿çâ/ûìQö«oùø‹þû•âßù^ÿ׬ÿú)ª‹ÿÈÙ¨ÿ× ç-[ñLÑI ÞˆäG"Ö|…`å“UGÿ‘³Qÿ®ÿÎZß¶û¢¬U{oº)gÿX>”Ò¸ÑTèªåË”U:(å —(ªtQÊ.QT裔.\¢©ÑG(\¹ES¢ŽP¹rЧE¡råNŠ9BåÊ*r…Ë”U:žß£~œl3›¶ÿQkÿaWþµ¿Xßê-ì*ÿÖ¶ä.dŽ(Іr~fÓ½HQIök¯ùù‡þüŸþ*³]ÏÌ?÷äÿñT´R}šëþ~aÿ¿'ÿЦ,S¤rº8pHeR¸Ç¶O­IERQEQEQE@$¹šYÖ(˜DB³I!^qž0b(z*//Qÿž6Ÿ÷ý¿øŠ<½GþxÚßöÿâ)ˆ–Š‹ËÔç§ýÿoþ"¢܈iVÖ$VebóŽ»}EZ¢£S2ËåΈ¤©e(ÅÁõÔT”†QEQEQEQUã{»ím &5b™’R¤‘Áà)ï@(¨¼½GþxÚßöÿâ(òõùãiÿÛÿˆ¦"Z*//Qÿž6Ÿ÷ý¿øŠ<½GþxÚßöÿâ(Z*¼¿o‰7¼»AâfîqýÊq7BQ‚B óŽHÉÆÞœÎ€*x‹þE½Sþ¼åÿÐ Sù5úáoüå«:ëðΨYv°µ™Xg8! Vù5úáoüå  ûoº).™P—v ª¹$ô–Û¯C úmÌwˆ¼’XƒÈÇ?ÒšRm&Rÿ„‹HÁ"ú3žçéëJUëŸËŠn™£\j1Þ6¢Ð‰I*‹`xç5çN¥gˆ´VË¿sKÍO•%Ëm[mjÞŸeíÊûú•õ­üm%¤Ë*©ÁÇcO¹¹‚Ò5Ì©c«1ÅSÓôøt‹yåišWaºYXc… vï\­íÕÅû¥äˆÌ\ü€.ï!;ar2Þõ½\G²‚sZ¾„Ôp‹ZîÒ߯«¶žvù_C¥_i,á~Ó€‰…üñZªêÈX#!àŠàݶ¨0ù<¬Ñ VùÖ¶|>¾zjl„ý›h*û›²žµ[NI[äÇî¹òiµô—7TŸDÖþŒÑ> Ò”ûtYñùÔ×z¶Ÿdê—7Q£2î9$zñ\Åý”–2=å ®™Š@1•ô#¶?Ze½ÍÕì‘ZÇ••7à¨G'“À¨úíE'_{±Ÿµ4¡Ëï-•÷_Í~[%ëé¹Ôÿli¿d7l‹É ´¶{úb¹˜uIµýÅÔ‘Á$Î9'`ˆghÇ©àæ¯j: ZT—_k“í0æS6ÑóqŒmì*ž™esª\IÚM¸†5.V=ÙfíÉö¢½JîpŠZï¹´›Œ¡ì’iÞ÷mlµ_×k[z¤t–šÆ{8†ÚéB2Mj[ôo°ltµ»Žæ{É.Z#˜Ô @§¦zœÖõ¿Fü+²n>ú³&J*ÖüïøÙ~G9mþ¢×þ¯ýko8¼ƒþü«ÛýE¯ý…_úÖ̬æ'æü($ȲԯfÕïÌ×fµ¹t –èbب c9äþ• ñ4éh×:zÆÍï-ÂÏ»z¨Î”àZÑ‚kå™åVÞDczÊU—a%H ðFO>õ8Ú.mãF,#‡''u4ÃRÍQHaXbêö-q£¿¹{{w”%²ŽQކN¡³ž8éÞ·*‹i6ox.¤;‡ó´ÌP7¨\â–šÅé´Ò±Î׫ÒK“æ ÜÇ ‚Çñol Æc8;±ÏÍÉîûÓbñDÂÒ+‹½=Sí6þ}²Å>òÿ2®Öʧ.¾£­m :Ð[Ú@±mŽÌ©€A]£žü~uZãD´k·†Þ60ÀÐB²»m Ä9꣞£Å©žÚ¥ÜšÅ´q-³[\²J°ÌdWã£ùU­ ]“V—ÆHbx¼Øäùˆ#= *89à‘ïF— %°yo[͸k8+#°Bh›–ã9Ï­_±Ó­´ýÂ×ÍT#VeQè œ€ԷYsq ”ZH±Ku|ñy¥wlf$ç õ­: ¢ÂK9-5c‰„í"†“Ë`w¬§ ÷ê)ÕÕncðåíÔ›$¹´ybÝ· åX€ØíÛ?XÒ§»×V7“­ÃB‘Ȳ„ ÙàÇZdi¡G…nmü¯-£(nr1Ëdg’O~´ûѬŽär 3ÜcÉ9àSVŠ©ý§§ÿÏõ¯ýþ_ñ£ûOOÿŸë_ûü¿ã@¿ÿFú¯óŸ%“ޛDz”Üï &þ5Ç`sÂût95=î¡dö¬©ynÌHÀ©=G½fI³êhþÓqw5¸”mgzêÄúÙÝá`ã‚ýÔÿ#f£ÿ\-ÿœµ6±“á]Uˆ8kiØ{†¡ù5úáoüå  ûoº+Æ7- ˆƒ|q¥È1»¹ä/9ǽm[}ÑItªî¢°ÇF¤âäšN˳¹ç†éVÚþ8pñ\G4£¤`0?PM t¢Öú(°ÐÜùA¥#ÔýFk¾Æ ª`þyq„(#M‡ªí?…sÇão{d×ÞkJ¤)ònùUºk¶¯MÕ—ëÔç<+6ëÛÕ‰D‘HÌ£¢‘À_ëYú¥ºÁªÞD\Æ»Öæ6^ ç¯êçW5mnîÓQ–ÖœQãh0–2d}î8Ço²Lÿj¸VF7w2J®èP.?‡ØW5gMPWº{؉җ,iCšþêNÍÚÖ÷›·.Ú~}YÐøoM¢ßÊ›Y—mºàOï}Oò­ê>¼Q^*jœTQÛ-—õÿæQEh#˜ñR8½·žC² Æ$ìŽHëøҩůÝZÙEkXF± @û‹øõ®É•]Jº†SÁ 2 C¤-º+X½V0 rO?hç Zæ‘’Þý´²{_îßÌÉÒ>ߨ闉|ìÐÌ¥"‘“c‚ž•ÍφdŠñb.ÆŠf*¬=Aν’NI¨æ‚… <1Ê@ê?:*áyã{UÔï%$ìÖÍ[µÕ­¯]¼¬yôÍjÃ}ÖG‘¿šÓ·½ŸGÒbHí£·’åØý¢E Áǯ< öÍu°ÚÛ@s´1ŸUŒùÔŽªãªãцiC 8ÝókèÞ*N.2“iúÁü[^G nòõU$šà¸g¸xÎd õì3ü©–×ëŽxåóÇ÷[×Þ»ÔD>Z"g®Õ4žL9Ï“zç`ÍeõdÔµ½ïÔãt©´µ|Éß›K¿'¦Ý-Ùº“Ýj>YM»$²y#v†çP3X¶Z´šy¸kW³‘g`夂¸Åvù9Í@ÖVm!‘­-ÙÏ%Œ`“[Õ¡)IN2³Z¹'+­7óÑÙþ‹SŸÑõ-SPÔÑ„©,>pHñby'¥u¶ýð¨G t€*k~øV°ƒ„m'qJ\Öÿú$s–ßê-ì*ÿÖ·™UÔ«¨e=Aƒmþ¢×þ¯ýkw꟭Œû-·üûÃÿ| >Ëmÿ>ðÿߟ‡õOÖŒ?ª~´†3ì¶ßóïýð)éq‚#»F(Ãú§ëFÕ?ZuÜ?ª~´aýSõ QMÃú§ëFÕ?ZuÜ?ª~´aýSõ R†#¡#ñ¦aýSõ£꟭?{y¿:7·÷›ó¦aýSõ£꟭?{y¿:7·÷›ó¦aýSõ£꟭<’z’~´”Ü?ª~´aýSõ QMÃú§ëFÕ?ZuÜ?ª~´aýSõ QMÃú§ëFÕ?Zu(fÆ™‡õOÖŒ?ª~´ýíýæüèÞßÞoΙ‡õOÖŒ?ª~´ýíýæüèÞßÞoΙ‡õOÖŒ?ª~´ýíýæüèÞßÞoΙ‡õOÖŒ?ª~´CÄ\øoTÏüúKÿ ¦ÿò6j?õÂßùËVüC»þÍS%ãÎ^™þáªÿ#f£ÿ\-ÿœ´ÄoÛ}ÑS•Rr@5·Ýb€±?º(ØŸÝê(¸ ±?º(ؿݴPv'÷Eû¢E»û¢‰ýÑN¢‹€Ý‰ýÑFÄþè§QEÀnÄþè£btS¨¢à7btQ±?º)ÔQp±?º(ØŸÝê(¸ ØŸÝlOîŠu\ìOîŠP¡z)h ZÛýE¯ý…_úÖý`[¨µÿ°«ÿZß Š(¤0¢Š(¢Š(¢Š(¢Š(¢ŠÍ´×4û›Yn>Б,.VA#P†+Ï×¥ES¦žc Ø6Ì¡·ŒlôÛmZÒãR¸°Gxvü¤ýðT6G¶ 1¨¢ŠC *ޱ¨.—`nÜ¢DS“€0\þ§SOŸkûlfÝ·ÍÞ6çÓ4¹ET—R±…`ináU¸ÄKŸ>žµZßXŠ[iÞCMÎ# –6 œžƒßµjQTF¯`%† .àK‰QXDdüÃ#¿Ö¤MJÅïM’]Â×# Änã¯ÀµEÉeŽžYR4fc€©¤1ôUXu+âŽXnát’O)\Ïý߯µ@úÝ‚jY™Ót¡¶¶áÊÁJýriˆÑ¢²¬u¨ç·ŽkÑI+”|¡¯N¸ïž•a5}5íé/­ÌB´Æ=.ÑQÁ4W¤ÐH²Dã*êr©(¢Š)â/ùõOúó—ÿ@5MÿälÔë…¿ó–®x‹þE½Sþ¼åÿÐ Sù5úáoüå¦#~ÛUí¾è«QEQEQEQEQEQEQEQEQEQEË[¨µÿ°«ÿZ߬ oõ¿öë[ôQE†QEQEQEQEÎI¡ßɧ 6x6ÛÝ}¢Y Ÿ9m¬T½z‚k£¢€9«O=µ´q­½¹·v¹Pey·ÌH 30ÉCŽkNÒÖößV»œ‹soxRGÃèá0Gœ¥iQNâ°QE†gëvs_iÆo+ÍG"‰ v¸lôô¬étMÖi–hRk›¡4ðE;Ä¥m $vs‚NqŠèh G=¦èú†˜,ž²M$v¿f•d‘€Q¼¶U¶’zã àS-¼?yjuÐ8Ô<ñ rr›‰(Tã§<ŽÇ¿IE7¨üšËZÝÄ ÓGj¨rx1˜ôü¿¥TÓÒa¯ZÚD"– [›‰šUW 7ûÙP3–Ç溺RI$â‹ëp¶–¨ë/¨i²[FÈ®Y]wŒ©*Á€ocŒ½E!˜¤_Èòß1µK׺ŠábVo+Œ`¶3’ ç”–N¥gwØû#HÍ7œžcaVG ò¼‘ŽàWAE1Xæá½ûÛ™mÿãÖ{t;;äܤñÇjMKÃ÷W­s‘‚­¢y¯òŠÊrËÊðÜé]SK´:|p–" 3*ÊÒ Ä’~fäç9æ­ÑEQE!™Þ"ÿ‘oTÿ¯9ôTßþFÍGþ¸[ÿ9j爿ä[Õ?ëÎ_ýÕ7ÿ‘³Qÿ®ÿÎZb7í¾è«^Û@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@µ·ú‹_û ¿õ­úÀ¶ÿQkÿaWþµ¿@QHaEeÅ©Ý]ÝÌ–6+-´ù2O$á2ö®qžäRnYÍæÇlîd !‰š2B™ÎÒxlcµjÑXÐëö±Ùڵ㷚öñÍ1HÉXìGÝÏZ½£÷óYIJ³Ãï债gS°®[¢Š) *9Y”* Ý‚Œô%G'úÛúê?‘ ýžëþ{Ãÿ~ÏøÑö{¯ùïýû?ãY¾$šhšßÊ–Hò;XŒô¬_¶ÝÿÏÔÿ÷ð×%ll)O’Ižn#2¥‡©ìäγì÷_óÞûöƳÝÏxïÙÿäþÛwÿ?SÿßÃGÛnÿçêûøk/í*]™‡öÕå‡ùTÝG?™ mÛ°Œþ9§#EqÑ€" ÓÙ›K»³½Y‰?qO­Iü{Åþâÿ*ï‹æI£×„¹¢¤ºƒd†-¡˜,Ü€;~"Ÿö{¯ùïýû?ãIü„#ÿ®OüÖ¸/ˆšÆ§§ë°Åc=¼mb¨Øäó]z¯QSŽì²¹ß}žëþ{Ãÿ~ÏøÑö{¯ùïýû?ã^-ÿ 6¿ÿA‹¿ûì…ð“kÿô»ÿ¾ÇøW§ý‡‰òûÈö¨öŸ³ÝÏxïÙÿdË=º $xÝ7@R'§Ö¼gþmþƒ÷Øÿ ökž4ö'2sÀ’¸±x¸[{N¿¡Q’–Ä•óe¢‰‘v(f, ëœqøõ¦ÚÿÇìÿõÎ?æõÆX¿gºÿžðÿß³þ4}žëþ{Ãÿ~Ïø×â-[Rƒ_¼Š ûˆãWU_À¬ßí½_þ‚w_÷Ýa*ñNÇ­G&¯VšœZ³×úÐõ³ÝÏxïÙÿ>Ïuÿ=áÿ¿gükË¿¶õú ÝßuwGÕµ9õkX¦Ô.^7S!äP±nÅO$ÄB.M­=ÈôC$k+#¬„¨* àŸ_cRSnŽM–ç§þÓjunxÁERâ/ùõOúó—ÿ@5MÿälÔë…¿ó–®x‹þE½Sþ¼åÿÐ Sù5úáoüå¦#~ÛUí¾è«QEQEQEQEQEQEQEQEQEQEË[¨µÿ°«ÿZ߬ oõ¿öë[ôQE†eÇ¥ÜÛ]LÖWë´ò™dà߆8ݵ· gÁ¨`Ð m KzÒ[[,‚Ú/()Màƒ–ÏÍ€ÄmQ@?ðŽH-¾Îš‘Xå·K{Œ@3"®@+ó|§­iÙX­œ÷r,›…ÌŠávãf.3žzUº)ÜV (¢Â¢›‡ƒþºäjZŽhÌŠm¬¤2œg€(k–ò\˜C;Cgô¬¯ìËŸîŠèv]ÏxïÑÿâ¨Ùuÿ=áÿ¿GÿŠ®ZØ:ueÍ+ž~#-£^|ónç=ý™sýÑGöeÏ÷Et;.¿ç¼?÷èÿñTlºÿžðÿߣÿÅV_ÙÔ{³ìl?w÷ÿÀ#´ "0Á’(þ•<ñïûƒùTmË©Vž=¤`툃ÿ¡Tê¡T(èwEr¤‘êF*1Q]ó‹Øÿë“ÿ5®/ÆþÔub)ì‘„³íç$×i,L쯄uÈÉ\‚·à)».¿ç¼?÷èÿñUч¯*Hn««Wÿ>¹ÿ<¡ÿ¿¢øAõÏùåýýê›.¿ç¼?÷èÿñTlºÿžðÿߣÿÅW§ý»Šì¾ïø${(žWÿ>¹ÿ<¡ÿ¿¢½Nå³fqœAë%.˯ùïýú?üU!‚i0&™  ãž¹5ÅŒÇÕÅòûKiŲ̂ÁGbÁëQDqy?û‘ÿ7©j"Êd†EBÀ »ÆqÜzšâ,ãuÍP½Ön®`D1Èÿ.[ GþmWþyÇÿ}Šïö]ÏxïÑÿâ¨Ùuÿ=áÿ¿GÿЬ]·sÕ¥œb)AB)Yiýjpð‹j¿óÎ?ûìU­3ÃÚ®¥oq2'—†l6Nµv».¿ç¼?÷èÿñTlºÿžðÿߣÿÅP¨E;•<ë8¸´µòÿ‚žÌÒìSÔ †Ty¥VØr¡So8Ç©õ5=lyEPwˆ¿ä[Õ?ëÎ_ýÕ7ÿ‘³Qÿ®ÿÎZ¹â/ùõOúó—ÿ@5MÿälÔë…¿ó–˜ûoº*ÅW¶û¢¬PEPEPEPEPEPEPEPEPEPEP-mþ¢×þ¯ýk~°-¿ÔZÿØUÿ­ZñÕõ†™-팖ÃÈRÌ“DÏ»¦0C ~´ Õ¢²­õ•¹ºµ¸‰%k1™®G’»€ ÌONùÅV‡ÄÐÜ[-íŒÓ ”¶òã™aCƒ·á@ê+/¤ÓÛ[¥¤‹4ÌêË$Š» 6ÖŸ˜÷ÀíO‹\W½òžÒT€Ý5¢ÜR¦AÛÈð kÑX_ð“[ /£1†{8šR#™$ÜÇcòžœKÿC§’òßÊã2´M<`ªŽ 8b}4†oQXÃ_CvSì’ý˜J›Œ®:†^3œr9§E®y–ðݵ”ÑÚO"$S3/Ìà63:uõ¦+šõòùJRÌÌTw&¢°»[Ûv™•¯Ïñmb¹Ù–ëým¯ýw_ëHbî½ÿŸÿV׿óâß÷õj¯öÅçÛ·àûÛ>ÇŒ3w÷³œc‚¯Çþ©?ÝÊ€#žvÒ8â2Êù!AÔäÓwßÐ=¿ïêÿUÕ>óÿ×ÇòSE×®ïZPö>|¶­"Ä7n¶e*6È3žýp:~4Äjï¾ÿ {ßÕÿ7ßÐ=¿ïêÿ;E¼¹¼ŠàÜù."˜Æ“B¥RPÉ“Ðäu=+J‹ 2Ò[¦‘£6eY@b ‹ÐçÈÓ÷Ì»L°mBÁwœÖ‹À{ˆËÍ™ kºK_¦ÇÖªÛÚÚØÛ˜,–xáic"'VÚ‡pÎ úžzÒ~ y¤óŒ0@Òº¨fÃ9Ç_¡©êŒ×bÀê—…7ù‰&ß\y‡†Oº÷þ|[þþ­¯çÅ¿ïêÒi——{=Ž¢ 3Gs€¥[pÆ <‚§žùíZ”Ås3uïüø·ýýZ#–å˲àÆÛXÿ"+N²/ ‚ïíV×>y‰§Ö5oœlO”:€'W:¬Ñlß§p 3ÈʤªÇºÚÛÀf1¤­°JÊ6>9ñ«tQE†gx‹þE½Sþ¼åÿÐ Sù5úáoü嫞"ÿ‘oTÿ¯9ôTßþFÍGþ¸[ÿ9iˆß¶û¢¬U{oº*ÅQEQEQEQEQEQEQEQEQEQErÖßê-ì*ÿÖµõ 8µ lç.#•v±Bü2 d[¨µÿ°«ÿZß eô«[…Ô_0®¢¡f±€oËÇ}j4+xŸ{ÜÝÏ'ŸåädÉdQò¨Ƕ}ëRŠdÍáûYÄ÷~CNÓ¼A“k1mßÝÈÁô ÔVZ˹®og™ÇÛ$¸ŠãÊôlc9üqšÛ¢€1bðÍ”qIÚ/'­Õ“!9!p¹ê;æ®]i‘Ü\ÇsÍÍ´èž_™(,vÀƒÈôÍ^¢€(>‘k!”³L|Û„¹o˜}äÆNŸ(ÍRºÑ=.{ &–)†ÄŠy€Ka×+…ÝÁÆ&·(¤6VÑÙYAi%!@€ž§ϹëM»!Zى¬êI=«‚±¦oì»íµý¢Lyžw‘æ/ÌÆ7ãÎ=ñíZ^l_óÑ?ï¡T¾Ïoÿ>ðÿßµÿ >Ïoÿ>ðÿßµÿ »æÅÿ=þúNöXüøpëѺ¥'ÙíÿçÞûö¿á@†ÒGÒ1þYÜ,2n˜7ÊBñõ5q õ éH#NV(Á@)Ô†gê)¾`…•<Ëy£ çq?¡të&·™fÔåyæ‡É3—tjz„ãò«ìªÊUÕYOfÏ"ù÷‡þý¯øUiÔZ‰§­½Œ©Ñ@$hÆÀ@â­ý®Ûþ~"ÿ¾ÅUò ÿŸxïÚÿ…Dóïýû_ð£AjAxñ\M:GrStH<ÈœeN_¥VµK„Œ}²ñnn$•3±v"€Ãî®N8äò!Z"GH"HÅ*¢)ÊFŠ}U@¤1ÕTG ×w¶÷[|©íÑcÃ.óZ¦º#ŒHˆãÑ”çHc4ëm<ÈâêIå*´“H m_º¼ÀÉüê÷›üôOûèU/³Ûÿϼ?÷í³Ûÿϼ?÷혬]óbÿž‰ÿ} Ì’E3\ì•TùÙ9q*o³Ûÿϼ?÷í—Ʉ bÿ¾WV qn¡÷•ff?ðö"­Ò*ªgb*ç®Õ–Š(  ïÈ·ªל¿úªoÿ#f£ÿ\-ÿœµsÄ_ò-êŸõç/þ€j›ÿÈÙ¨ÿ× ç-1ößtUНm÷EX Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ZÛýE¯ý…_úÖý`[¨µÿ°«ÿZß Š(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¶£yŸ§Ïy(fHP± ÔûVkê÷¶ Õí!Ž+€Û *ÁKm`@êò8È­[»hom%µ¸]ÑJ¥XŽ g®‰æIj7óÞ¤*Ë:*Ê•,výæÁ#>ý(=C_X#‹ì¶òM,‹¡0RF 1ÏÞý=é«\%ýÒI˜‘^Ù7@Ìža ƒƒ×§98÷¡|7û²$Ô¦wXâŽò”Äm¹sýãùT·-,·®ò9…äÜѶAÇlç§ µÑ¤Ÿ÷í¿Â€´yÿ1þmÞÌ…3íúIÿ~Ûü) Ì`dïÔ£é@mÞÌ…G÷ŸóáJ rCK@ Ú?¼ÿ˜ÿ 6ï?æ?˜n# W,HàíRqùQöˆý$ÿ¿mþý£ûÏùð£hþóþcü)ŸhÒOûößáIö˜Ç]ãþÙ·øP›G÷ŸóáFÑýçüÇøR«PÊAdÞ–€´yÿ1þmÞÌ…:ŠnÑýçüÇøQ´yÿ1þê(»G÷ŸóáFÑýçüÇøS¨ íÞÌ…G÷ŸóáN¢€3|B¸ðæ©Ëô9zŸö Tù5úáoü嫞"ÿ‘oTÿ¯9ôTßþFÍGþ¸[ÿ9iˆß¶û¢¬U{oº*ÅQEQEQEQEQEQEQEQEQEQErÖßê-ì*ÿÖ´õ JÓMXMÜ…Ò׌ò}}½f[¨µÿ°«ÿZ—SÑî5MBV–äÛÛ-±†0ª®_~w’NøÒ§5í¥½Â[ÏuSI÷#yfúÉ¡/m$ºkTº®ïD$ÇÔu¬ ´]BêÎð]Ç ÜK¥‹UbÀæEgÃ{uSŸZèw,‘Éý¢÷@Fá&Üç×Ú˜®kOªYCiur.#•-´Â6 S8 t4.©§¿}5m ‰KiÂÙÎþ‰7îã5©¥XIjÞciádšmò´· #&— ×·â€6iƒþ?`ú7ò§ÔLqwöoåHdW^ ±µžhŸÏqo>HágHxÏÌÀ`qϰ«cQ²k”¶¶æwPËš»˜@ÎzVÙu[!¨ZØÁo4W²¼«4“lò‹€eÆ[ÈÇ^œVLTíq¤ÛCE–ƒíŽà4{Nà¸Îxã½5¨™Úý¶×í-mö˜|õ]Æ/0n 뎸¤µ¾´½V6wP\8cð}+˜Bu;™%‰¥Vž[ˆg.¤`¦3žvõÆ?*»¤é³XÝÚÊÉôô·¡¸#óïÍ /øò‡ýÁST_ñåû‚§¤2¸¿ƒNÓ<û‚ûLÌŠ¨¥™˜È@¦¦­¢ÛÇ5Ì¢ÐJÛQn¿tÄúaªÔF} Ä,Öó2±òÚ_/¤ÈnÄv¬kÍ3]¸ÓE´ŒeÄÊaûB—@Àl ì>`>l÷ärq@ޏÝÛ®ý× Œ²ãåcÐCÈãÞ’Ëk‰%Ž ˆ¥xN$TpÅ¡¥s«¢ÜÿhZ±‘>ÍåÄ÷#<ù±.\äß“Ã:4ºcÇö¨›Í·€Â³‰Ã,€NŒã<÷¦#fÓþ=ÇûÍÿ¡š¡³ÿeÿy¿ô#SR((¢Š(¢Š(¢Š(¢ŠÎñü‹z§ýyËÿ ¦ÿò6j?õÂßùËWÇN„ŒÄT´P.¿ç¼?÷èÿñTl»Æ>ÑôÈÿñU=—uÿ=áÿ¿GÿФòîh‹ðˆÿñUbŠlh"‰c^Š0)ÔQ@Ä3&DS BI£$Œœžr;š_.ëþ{Ãÿ~ÿSÑ@yw_óÞûôøª<»¯ùïýú?üUOE2(ÄQ*N;žôú( Š( Š( Š( Š(  ïÈ·ªל¿úªoÿ#f£ÿ\-ÿœµsÄ_ò-êŸõç/þ€j›ÿÈÙ¨ÿ× ç-1ößtUНm÷EX Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ZÛýE¯ý…_úÖîÄþà¬+oõ¿öë[ô݉ýÁFÄþà§QHcv'÷û‚E7bpQ±?¸)ÔPv'÷û‚E7bpQ±?¸)ÔPv'÷û‚E7bpQ±?¸)ÔPv'÷û‚E7bpQ±?¸)ÔPv'÷û‚E7bpQ±?¸´ê†­M¨žè&K6]Ϲ“juhÚŸÝZzZÙH¡’(™OB9ï±ZÿÏü©Ôþêѱ?¸*_±ZÿÏüª¹!½ÙÚb£¦Aã@ØŸÜmOî­GsÌj¹8iN= ji-ì"Ê <ÇÝ©ýÕ£jujAghFDA¥û¯üðOÊ€"ÚŸÝZ6'÷V¥û¯üðOÊ¡H´ù§šÚ5_6¦@¹wgþ€(x…TxsT!@?c—ÿ@5QÿälÔë…¿ó–§Ö¤ð…ë¹Ë5„„Ÿ,Ôÿ#f£ÿ\-ÿœ´¿m÷EXªößtUŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šå­¿ÔZÿØUÿ­oÖ·ú‹_û ¿õ­ú(¢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ Ã׌ØV†t ÞÄÒ]Ãh—œLVåV‰ç|±o#àœ22à‚IîG­s’;­ÅÕÎ’³ÚèÒ4 3Ã'ñ6÷Œc ch,Ó¥M]Þ}Žº¾û—²ˆ¥2Hðˆò¤·³‚zàu®ƒíç?eŸ?ï'ÿIö‰ÿçÖ~ÚOþ*˜ŽI¯5yZÕgÔ%µ@ÌûÀyDŒ `£ p†àæ» 7ëœdBs¨¦ý¢ùõŸþúOþ*’!#Ü^3 ´ “Î{PãîÇÿ]£ÿÐÅcê-gˆåŸ\€IjÖê¶­$FHÕ²wŽ„?/ZÙ¸VhÇ–2ÊÊàg®8ý)¢âqÒÖqÿOþ*ñÔgo[%¡–„É„»âHLyܪ¹Ç#œŠ¯Ú¼Mmq{,÷vs¼«#6ººà¨= `¥u_hŸû,øÿy?øªO´Oÿ>³ÿßIÿÅSè9½JìùCNÔn¿³‰“θ’Yw 06†` ÷Ž8ö­=Ï©x.¤óf’Úټ݅D¸R Ç{Ö—ÚgÎ~Ë>ÞOþ*Ï9²çÝ—΀±ªÈ™wÿ`çÿÑf¢ù5úáoüå«Ü~W„ïâ'%,d\ý#5]ÿälÔë…¿ó–€7í¾è«^Û@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@µ·ú‹_û ¿õ­úåÖ÷NŽ mo.n-æŠñåVŽ3sÁ©ƒKý«¦ÐSÿ¿kÿƨ§¢¹í]/þƒúŸýû_þ5Gö®—ÿAýOþý¯ÿ žŠæ?µt¿úê÷íøÕÚº_ýõ?ûö¿üj€:z+˜þÕÒÿè?©ÿßµÿãTjéôÔÿïÚÿñªéè®cûWKÿ þ§ÿ~×ÿQý«¥ÿÐSÿ¿kÿƨ§¢¹í]/þƒúŸýû_þ5Gö®—ÿAýOþý¯ÿ žŠæ?µt¿úê÷íøÕÚº_ýõ?ûö¿üj€:z+˜þÕÒÿè?©ÿßµÿãTjéôÔÿïÚÿñªéè®cûWKÿ þ§ÿ~×ÿQý«¥ÿÐSÿ¿kÿƨ§¢¹í]/þƒúŸýû_þ5Gö®—ÿAýOþý¯ÿ žŠæ?µt¿úê÷íøÕÚº_ýõ?ûö¿üj€:z+˜þÕÒÿè?©ÿßµÿãTjéôÔÿïÚÿñªéè®cûWKÿ þ§ÿ~×ÿQý«¥ÿÐSÿ¿kÿƨ§¢¹í]/þƒúŸýû_þ5Gö®—ÿAýOþý¯ÿ žŠæ?µt¿úê÷íøÕÚº_ýõ?ûö¿üj€:z+˜þÕÒÿè?©ÿßµÿãTjéôÔÿïÚÿñªéè®cûWKÿ þ§ÿ~×ÿQý«¥÷×õ#õøÕjø‹'Ú§d—±þãUGÿ‘³Qÿ®ÿÎZ£5îsM­j/ªQ×ËQ¸‚8‹=ÏçVl®bÔ 269 403 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀÞM"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?èt½3Om&ÉšÂÕ™­ã$˜’vj•,´§á6~bYMºç¿J—Iÿ=ý{Gÿ  ‡UÃ4KoŸí°íê[ý\þ‬´¤!66~d€•Qn¹Àêzt©²ôïúÙÿß„ÿ ‡J™–|ý¿9œ·R;mÿcÓùç5£@Ÿü$^ÿžÿø?øš½¥]x{X–Hìm-]£]Í›U\ 㸭 WûOùWþ=bíþÀ¥ q0ÿE~ƒý´ ®ll!Û·N²9ÏXü*"Çþ¶?÷á®j?ÇúU<Ö±ŠhÎRi‡‘cÿ@Ûûð¿áG‘cÿ@Ûûð¿áIš3Uȉæbù?ô ±ÿ¿ þy?ô ±ÿ¿ þ™£4ùs0ò,ècÿ€ëþy_ô ±ÿÀuÿ 3Iš9s1|›/úØÿà:ÿ…M—ýlð“4fŽDÌ_&Ëþ¶?÷áÂ&Ëþ–?ø¿áIš3G"f/“eÿ@Ëü_ð£É²ÿ eþ¯øSsFhäAÌÆ¿ölmµìtå>†Ò…:c°U²Ó˜ž€B‡úTÖö6÷FW–-ì Œî#ŒCN¹ÓímâY#‡k‡%˜ãó5>åì?{p[7®‘fWÔ[¯øRGgm.vi6Mޏ·_𫊓<†,ñœqŽiÛâavw•ŒºüËøZV]‡vgý–×ÌÙý•e¿ÓìëŸåO60t‹0ÍÐ}yý*ó17“(ùd1b3ž¾ù¦ÛBñMnÒÞÛ²¬zqE—`»(Éimf•d¹é›uÿ g•eÿ@Ëü_ð«—ƒm’ ­ü®rO½PÍTbš“C¼«/úXÿà:ÿ…U—ý,ð›š3Uȉæc¼«/úXÿà:ÿ…]—ý,ð›šLÑȃòì¿ècÿ€ëþyv_ô ±ÿ¿ þÌÑš9s±þ]—ý,ðÂ.Ëþ–?ø¿áLÍ£’!ÎÇyv_ô ±ÿÀuÿ <»/úXÿà:ÿ…34fŽH‡;åÙÐ2Çÿ×ü)DvDý™cÿ€ëþiTüÃëG$CšŸÙzvHþϳãþ˜'øWñÚÞÚkoo !•óåÆ=:â½ þZ?üú×ñ3ý~Ÿþëÿ5®cs¬²½´³Ñôïµ]Cûhöù²Ý„\ã?ZTÕtd•å]FÄI&77Ú'Z‡M8›GÇýÿhVÁv%ç@­ªèÏ*JÚ‰’<ío´.Fz÷§ÿmi_ô²ÿÀ„ÿ±öøû<Œ=B’(û|~²ÿß þìÂèÉI4ãXãÕ•QUQ©0€|Õ5½î‡o1•5HB»7I{¿9ÀÜÇh}¾?Yï†ÿ >߬¿÷Ã…atg^jzlÅ6jv?.s›„ö÷ªßl°ÿ ‡þ§øÖÚßFÌ{‚x”çSîoïΩIÅX—õ9ß¶XÐNÃÿSühûe‡ýì?ð%?ƺ-Íýãùѹ¿¼:=£"9ß¶XÐNÃÿSüi>ÙaÿA;ü Oñ®sxþtnoïΟ´aÈŽsí–ô°ÿÀ”ÿ>ÙcÿA;ü Oñ®sxþtnoïÎhÑçÚìè'aÿ)þ4}®Çþ‚vøŸã]æþñüèÜßÞ?ч"9ϵØÿÐNÃÿSüi>×cÿA;ü Oñ®“sxþtnoïÎhÑßÚìè'aÿ)þ4}®Çþ‚vøŸã]&æþñüèÜßÞ?ч"9¿µXç?Ú–ét¿ãGÚ¬{ê–'ët¿ã]&æþñüèÜßÞ?/hÇÈŽsí–XÇö­Ž=>Ô¿ãIö»,cûRßi_ñ®“sxþtnoïΟ´bäG6nì]RÇúz_ñ¥ûežsý«cŸúú_ñ®sxþtnoïÎhÑÙ»²=uKõº_ñ¤ûUýì?ð%?ƺ]Íýãùѹ¿¼:=«Ds_j±ÿ ‡þ§øÑö«ú ØàJt»›ûÇó£sxþt{Y³G5ö«ú ØàJj±ÿ ‡þ§ø×K¹¿¼:77÷çGµ{4s?i±ÿ ‡þ§øÑö›ú ØàJtÛ›ûÇó£sxþt{Y³G3ö›ú éÿøŸãGÚl¿è'aÿ)þ5ÓnoïÎÍýãùÑídÍÏÚl¿è'§ÿàJi²ÿ žŸÿ)þ5ÓnoïÎÍýãùÑídÍÏÚl¿è'§ÿàJæÄ0?Úz_ùùOñ®›sxþtnoïÎk öhÏþÚÒwý§eÏý<'¿¿½qß]d“Mt`ÈÈ쬧 ƒ·W îoïÎ¼ËÆ?ò ð÷ýy/þ‚•™gi¦ÿ­ÑÿìßûB´îãÚ_÷ò¬Í7ýnÿ`ÆÿÚ§sÿÒÿ¸• p#“P·°¶µ` ‹lä¹è š– BÚâÜOëåä®[åÁô ô>Õ™mqtÚa‚I"6ç‘6åÂ:0#ô¬¹4›Íy±Í/•$¾iC4ű‰0àŽƒàŽÔÄu¦xê;t]ÜšŽ{è-ášY%`Bòr@'ŠÀ†Âk[û6µ·”…Hã–KŒzÈažÜ«‹qå\G*Ï瘦E”˜ü·/ž¤ ç¨ëÒ€:;¹ã¸ÓZHœ: 縫­eFYtmhmJ…?—¯?/ªzÓ ¨KÊó´P¢1E K¹sŽÇÐÔÕ3Ãw,žSºº(Hê zŸqR1T̳æD]ÊXrz=­G}{o§Û‹©<¸8'“ì*Bí-¹‰ÑU|ÄrI_Cìk?Q³»½¿„FcŽQ˜´©¼31€Ã ÏçH –8Ð;Ȫ§¡$j¬:œ2iqß·îÒH÷ª³~•”–ˆ–_j²ûjZ,ùy_˜lp ÇAŽy¨—J¹ŠÊÕf°ElŒ^T˜Ÿ9Ï'Ù”úÐCs–q\±¤ˆæ8ÆE4_[›Ï²ù«æùb@;I¿CY÷–2>‹gA,“@¨@cm`¸ä7 =©[]ǨAs=„níj±ݰ¸b{žlô£¨kcaf‰ƒ•_¼C>´ ¢hÌ‚T(:°aø×/•¨¼w¦[gOfcaˆÕZMÀü»{c<·5jëI•nÝà³Gµ n¤*ÊWpaŽ™åO<P½¶¡ÄrɹQ#”Ź˜aˆÇ#ó« ,jT4ˆ }ÐXsô®wì¢ÈÆ–F8d»yX™ÕÀl¨æ§Òt¹ã–ͯ Ãb"Üøb¯¿?ž;Ф—Ñ%ô€†’]ÝùvŒóDWñK{qjHW„¨ùˆù· ñXúf›qo}c¾ÄFÖâ_:ä>i`psœœûÒjeÄ÷·â;ÏrÑn‰Qåmž¹ãÚ€7æ?ÞýÒÆû79;sOi¢]»¤A¿îå‡?JÄ»²½?iÛ–ŠkÏ1‚¬lå6`òõê¼ZmìºqKF{¸cØÞnÆŒ.üàó@î´ÓÑAëEQEQEQEQEQEQEQEæ~1ÿO‡¿ëÉô¯L¯3ñü‚|=ÿ^Kÿ ¥všoúÝþÁÿ´+ZDó#d<VN›þ·Gÿ°cí Ô,æO.$ ØÉÜØPeŽò5 0ÈF \^Ïïñÿâj×—uÿ<áÿ¿‡ÿ‰£ËºÿžpÿßÃÿÄÓ¸¬UÅçüñ‡þÿþ&Œ^Ïïñÿâj×—uÿ<áÿ¿‡ÿ‰£ËºÿžpÿßÃÿÄÑp±QṘl‘bD$d«–?ÈUÚo—uÿ<áÿ¿‡ÿ‰£ËºÿžpÿßÃÿÄÒnãHuß.ëþyÃÿÿG—uÿ<áÿ¿‡ÿ‰ QMòî¿çœ?÷ðÿñ4yw_óÎûøøšuß.ëþyÃÿÿG—uÿ<áÿ¿‡ÿ‰ QMòî¿çœ?÷ðÿñ4yw_óÎûøøšuÅgó9+€ Š%‘bŒ»döu$ôú*2ãþ|fÿ¾“ÿŠ£Ì¸ÿŸ¿ï¤ÿâ¨j*2ãþ|fÿ¾“ÿЦ´Ó ¬¦ grw8þõX¢¢Ý?üúIÿ}'øÓÑ÷®pTƒ‚PhÔQETje‘œDˆBíŽ#Nòî¿çœ?÷ðÿñ4ê)¾]×üó‡þþþ&.ëþyÃÿÿ@¢›åÝÏ8ïáÿâhòî¿çœ?÷ðÿñ4ê)¾]×üó‡þþþ&’7-¸2íd;Xg<õþ´ú*9eòö€Œîç «ÔÓ|Ëùñ›þúOþ*€&¢¡ó.?çÆoûé?øª<Ëùñ›þúOþ*€&¢«™¦VUk9”¹ÀË''ÿ{Ð~ùûÚIÿ}/øÐµæ~1ÿO‡¿ëÉô¯JV‡B2+Í|cÿ Ÿ×’ÿè)@¦›þ·Gÿ°cí Ö‡‹¶ÿ®cùÖN›þ·Gÿ°cí ÓS‹¦ÿ®cùÐ'ÕbA|#ÃIi˜FF‚qúVm‰Ä‚F¸ò"[ Ù­$ó6rÆ÷çô5i´[ݵQ´'‰VîøHÑÀ`ˆ¤ƒŒ“óOÊ;â€/]|ܶ‰mÚfISæ3OåU.ü@ØŒ[ÛÜÇ(š-ñÉ èäŽ{àõÅO¨éÉtÒÊììÙ òÐ œrzñT,´ë˫Ǻ¾‘×kBP¼!¶<¨c½×?…@½ý»æ^ZEok4‹/š$Lñ²à‚qüU,zí«Ü˜Z9ã_1â:a“;€9ö=}*¹Ò].…Õ½ç—0–GËE¸mp2¸Èþèçô¥:ÛFuKhï/~Ó¨(Ö!ȹ$‘øPËâK#’œ*ÆeBSýjd ¯>ã®:Óνn£k[܉üÁÙÊù °ïŒ`sT¡ðòEe5¢ÏÐ"2Û*È£9ù˜›¦;T÷ÚS]IrëtÇðÐç×·=x«PùÇÖSÿ ­KEPvºŽÆÎöê\쉋œu8QQ¦¡u³]êQA7—pOEÆ9<ö§´Ý[]ÛÌ3¬U€=ŠŠªtË™­ZÖëQ2Å´È„+©bs‚Fa@vÝ`’G†ádÑ@$Ë}Þ3Ž}sQ6½ºêÖ(-f1äIc #eô'ýiŸÙ '™%ÅÙ’âIc‘ämC¡sÇ~sÞ‰4—ûc]ÁwåLfiAh·•ÆFzg4r=U&k‘µÃ­¹*Ìa˜uQÏZ‹ûzØÃ¤7 #Êa„Ã’:ã§=j)t…“Oºµ7÷ó™·làƒ‚3ÈãŸZ®4&|–«qn<ÙL¯þ‰òŒŒ|«»å#s@êRI«Ëfm¤Øˆæ awÃsíÛ52¯¹ÿ®ƒÿ@Z©o§Ikx“CvÅ<¤ŽU‘74›FÝ‘ƒëÁ«0œËqÿ]þ‚´?üZ¼ßú ¨ Õå’ê=ð*ÚÍ;Á†ù·.y#ÓS¿üZ¼ßú ¨áÒ<»ÄÜ3[Ç+M;Ú휒ÝÇÌp=èiÑEZí‚=³1 $ÿ¸ÕFÚ »7#Pg–Lù»œqØÎ±øæ¯^=¹ÿ¦‡ÿ@j¡ÔEÉÍ·L•eûòç aÑqí×Ú€-ÛÿǺ}?­y¿Œäáïúò_ý+Ñí¿ãÚ?§õ¯8ñü‚|=ÿ^Kÿ ¥všoúÝþÁÿ´+RH•Èm̬8ÊœV^›þ·Gÿ°cí ÔXÒ[¢²¨uTÈVäg>”Ï#þ›Ëÿ}ð£Èÿ¦òÿßCü*ÏÙ-¿çÞ/ûàQöKoù÷‹þø[Èÿ¦òÿßCü(ò?鼿÷Ðÿ ³öKoù÷‹þø}’Ûþ}âÿ¾Vò?鼿÷Ðÿ <úo/ýô?§Xl™Š¬Vå‡PföKoù÷‹þø[Èÿ¦òÿßCü(ò?鼿÷Ðÿ ”%‹\5¸Š*¨v]ƒ @?¡§µ½¢.悹P(¿‘ÿMåÿ¾‡øQäÓyï¡þam­C,°=Š_²[ϼ_÷À  ÞGý7—þúáG‘ÿMåÿ¾‡øUŸ²[ϼ_÷À£ì–ßóïýð(·‘ÿMåÿ¾‡øQäÓyï¡þgì–ßóïýð(û%·üûÅÿ| †8–Ðù?­/öu¿ý6ÿ¿ïþ4ϳÅÿM?ïóÿ!¶ˆõ}Œ®­IýoÿM¿ïûÿGqc q†S6w¨ÿ^ç«ë@ öh¸ï¶ÿ‘UQB¨G@*Œ’Û%ï“ö{£ 8‘ö#žƒ®ƒŒÕ¸†ß12HG* 98À?Ö€$¢Š('Y‹t'®ÓÖ›äÓyï¡þûxb™¦icW!öÃ8ãS}’Ûþ}âÿ¾Vò?鼿÷Ðÿ <úo/ýô?§xl£Æø \ôÜ S…­©ðØ[Èÿ¦òÿßCü(ò?鼿÷Ðÿ –á,m¡2Ï) (;œÔÔŸd¶ÿŸx¿ï@¼úo/ýô?¤Ž5p¹ää“Ôš—ì–ßóïýð*€I'xT|(ôAþ¦€ñ¤ƒ¹}1øÓ>Ïý4ÿ¿Ïþ4ÙÇ™<–`’1Ý´àœzÔ‚ÂÔ±PÒîGÚ?΀öx¿é§ýþñ£ìñÓOûüÿãOþηÿ¦ß÷ýÿÆìëúmÿßüh?³BHʹÇLÊç­/Ù¡þáÿ¾Ûüi²ÙC°3a܆ÌÎr6±õõ«ÛËm=шAum‘ í#m”ޏçŒ{õíš½Ð` ØWšxÇþA>ÿ¯%ÿÐR½"Z$äã“^oãùø{þ¼—ÿAJí4ßõº?ýƒÿhV¬gmÿ\Çó¬­7ýnÿ`Æÿڢ壟~Æe+·åÇ4s}ê§Ú?锿÷ìÑöúe/ýû4o}dÝI©ÿm[ù0Äm‚¾I•€=>÷Ë€zâ­ý£þ™Kÿ~Íiÿ¦Rÿ߀9‹HÚ9íæh-á„êÿ¥'úÂw+p0 ã94ë+ýM๑nÕ¯ ¶ÞawGÏ!Q·™9÷®—íGþyÍÿ|>Ôçœß÷Á :™: I¬]½­Ü—iöh’GÜCnlo§½&¦ò}²ÊMn(VÅL›‚1xÃ`l/?Úö­stOXæ?ð@¹ÇHæðEÂÆ%åè€Gý’ãìר`ƒÉû©.î£Ó ·ýóLƒS•¼@!ŽfQºHä…ç,ØUá¶c匃žsZî±Ix—OËHƒä6Õ8Æ@õÁ<Ôÿj8Ç—7ýðh'Cšá'ÓüË©æ–o,‚W݆R¸#Óï+¡ßU>ÓÿLæÿ¾ hÿ¦Rÿß³@÷Ѿª}£þ™Kÿ~Íhÿ¦Rÿß³@c›Öÿ®CùšŽóý\õÚ?ý RŹçi ²®Ð£pÁ<Ó®#i#1¹Y\g¡Á¥bêa?´o×7ï,&Ìã£ÛììþµÔU_µÉÿ>’ÿßiÿÅQö¹?çÎ_ûî?þ*€-TŸñïÿOýS>×'üùËÿ}ÇÿÅTsÍ,Ñl²¹NK§b÷½¨Ô•®â ®#+åœî=7w© ÎfÉÉó9 ²µƒuÊÜ› gE*²›€=FsV!FEmø ÌX€sŽþ”%Q@ µlyßõÔÿè"§ßTƒ´/ 1¹ ÛUÏ`?¥;íôÊ_ûöh/_çÕôÅŽÖÞåÂNDsœ)ùG±¬…»¸†ÎÎx-¡òäË4¤ÛÎcÎîô zŠêþÓÿLæÿ¾ j?Ü›þø4Íj÷æx¯¯d[€ð xPíI—å%€þ/›wÓ»üš©ö¢?åœß÷Á£íôÊ_ûöh¸X·¾ªÆs5Éÿ¦ƒÿ@ZO´Ó)ïƒD¿xì¥w¾à\`é@ÿÇõ§ûÍÿ šÆ³ ý§nˆ¿ñ1[ÉZàãæòŽìdÿw1[R«ù°Ê‹¸ÆÄ•Î2ÇúÔŸk“þ}%ÿ¾ãÿâ¨Z¢ªý®Oùó—þûÿŠ£írÏœ¿÷ÜüU-æwÛí 0à‘Ÿàj©úJѪ]ÄÍ!`ª#9;zÿ÷©g–Yš,ZÈ»±Ë§÷Hþ÷½@ysËŸÖ¼ßÆ?ò ð÷ýy/þ‚”Úi¿ëtû7þЭ58»oúæ?fi¿ëtû7þЭI"CndaÆTлª‰ÒlQûqµ„Í´ŒùkÉÈ;ºgÉmÿ<#ÿ¾i¦ÞÑN(÷¨ëÒß.žÿ`‰]Ž2|¬9SŸÒ°µÐ²ë2}µôëiZÄç¡”g{}Ãòœûãð ¥#±’iaHâ2Eë·îç¥IöKoùáýó\½äÖé,§Í·p¶o"¹ËˆÇ IÇ>æ–ïV¹–WhnÔX½Ó¨ŸÎòÔ‹´o ØÏnOz\êþÉl:ÁåIö[^?s=8Õ(žõô›pÖòGLHÍ)Tp{ƒ´çòˆb¹¶†ý¡5´±åY®9@ÀÇ®HSì=襚; bXâS+ìL¯Þn¸ý ñØÜ³AOg ®ò®n+‰YË-äW-ü{Yf2ìÊ09m«Ô‘Û½2Öóʲ³†{Ù,í•fÜñœ(s…'‡8ïG@:¿²[Ïÿïš>Émÿ<#ÿ¾k˜¹½Õü›x•Ý.oí—Ëã9å¸í•#ò­}òKûyo˜·•;æoáPþy  ²[Ïÿïš>Émÿ<#ÿ¾iûèß@¶,WL‘¨P6ÑÓ94˶e„b¥Ý#¨€?ΞÇ7­ÿ\‡ó5çú¸ÿë´ú  NŸn Í“ÛÏñ¥þ΃ûÓÿßçÿÂÔÂhÞñ0iaû#¼}ßlîÏë]ETþ΃ûÓÿßçÿŽ{£Œ2´ÙÜ£™›»ëWê Ïø÷ÿ§þ„(:Iíc½ò<›£;^q#ìG=óúôg­[ˆmó$„r ž¸À?Ö¡kõVek¸ƒ+„#Ë9Üz nïRÁœÍ““æsÆ?…hZ(¢€#‚æišTCí¹ÀÀÿ›ì–ßóÂ?û棵8ó¿ë©ÿÐEO¾€"k{E8h¢Ü jÇbó¼ FXÀf]½éü«›ñõÐ.&²„"®âÞ3¿øy?CÔðZ<‹æÃ(µ´båö+á‰ãž:ñÞ…¨=»ì–ßóÂ?ûæ²[Ïÿïšå®õ{‰eíîÔÙ5ÞÏ;ÎØª¾R7…l Ùí]•$ͦÀgš9ä+̈rgƒœ ñí@\±öKoùáýóPDIž{ÿ1ÿãúÓýæÿÐMcYˆÿµ-Âø˜‹ÉMÁÇÍå|ØÏû8ÙŠ›¿ÙÐzûüÿãGötÞŸþÿ?øÕº(>[(£–­6È`fc‘µ¯¨^Þ{[‹£ ÃtˆÙLÒ6ÙHëŽ{{õíš¿yöø 0à‘Ÿàj«òÊÑ„»‰Œ„…3“·¯ñv  ¡bСc’G&¼ßÆ?ò ð÷ýy/þ‚•èöÿñïÓúלxÇþA>ÿ¯%ÿÐR€;M7ýnÿ`ÆÿÚ¢ìcŸ~Öe+·åÁÍféßët~3ÿÆÿÚ¯–þáüÇøÐi_îKÿ~Ûü(ûJÿr_ûößáRe¿¸1þ4e¿¸1þ4ÚG÷%ÿ¿mþ}¨à›þý·øT™oîÌoîÌGö¡ýÉ¿ïÛ…jÜ›þý·øT™oîÌoîÌGö‘ýÉïÛ…jÜ›þý·øT™oîÌoîÌGö¡ýÉ¿ïÛ…jÜ›þý·øT™oîÌoîÌGö¡ýÉ¿ïÛ…iø&ÿ¿mþ&[û‡óãF[û‡óã@ý¥¹/ýûoð£í+ýÉïÛ…I–þáüÇøÑ–þáüÇøÐQó¼›YWhQ¸`ži×1´‘€˜Ü¬®8Î8ý)ùoîÌoîÌ/ÚäÿŸ9¿ï¨ÿøª>×'üùÏÿ}GÿÅRe¿¸1þ4e¿¸1þ4¿k“þ|çÿ¾£ÿâª9ç–h¶ IAܧ%£ìAþ÷µ?-ýÃùñ£-ýÃùñ  †Ü5ÒÝ5ŽgE*²›€=³º¬ÂŒˆÅøfbÄg8àéNËpþcühËpþcühÔSrßÜ?˜ÿ2ßÜ?˜ÿ„9…ä ŽC6àUIìo¥;í+ýÉïÛ…I–þáüÇøÑ–þáüÇøÐjø&ÿ¿mþ}¨roûößáRe¿¸1þ4e¿¸1þ4Ú‡÷&ÿ¿mþ}¤r_ûößáRe¿¸1þ4e¿¸1þ4ÚWû’ÿß¶ÿ û×*W{ä×úT™oîÌoîÌ2U6QwùlI\€H Ž3ÅIö¹?çÎûê?þ*“-ýÃùñ£-ýÃùñ û\Ÿóç?ýõÿGÚäÿŸ9ÿï¨ÿøªL·÷æ?ÆŒ·÷æ?Æ€#žYfh¶ÚÊ»±Ë'÷Hþ÷½A¸Žâ[ˆìBM(ältÉÍ[ËpþcühËpþcüh"CH„‚TsŠóoÿÈ'Ãßõä¿ú W¥‚{©ˆÿóOÿÈ'Ãßõä¿ú Pi¦ÿ­ÑÿìßûB¶+Mÿ[£ÿØ1¿ö…lPEPEPEPEPEPEPEPQ™~r©¹^»GJ’£†hí⻚V nY˜ö4oùá/ä?Æïÿ<%ü‡øÔúÜRË Ékun—Ë2®zÁ$gÜ ±iªXÞ³-­Ôr²Ä)íëô ÞÿóÂ_È#JPnx¤UXŽ Ö4æ†YEäF8±½·p¹8­+ÝÁy¦\Km*ÊISÐã¥KQ™~b©¹^»GJ’ ûTvV——Sgˉ‹¶NŠC½ÿç„¿ÿ7¿üð—òãI¦¦Ùî.­æ³qþ¿o9ôÚMI¡i.ß.â6Ý•pz¨8'ð&˜†oùá/ä?Æ•9#Yz« Hº­‹ËKuy@d]ßx‘ùÒ·üKÿ\Óùµ+¸EÉÏ ½7{ÿÏ !þ4K÷¢ÿ®‹Q\êâ É-’Êêv‰Gh‚ çô=  w¿üð—òãF÷ÿžþCüi§YÓ„PH×qªÎ»£Üq‘ý)òê–PÝ‹Y.cYÎ>Byç§ç@ ½ÿç„¿ÿTpà‘AÁr 95 G¼6‹q¸Ì`óÇZbÇÅÏýtúл„Ç’p&“{ÿÏ !þ4øúƒêßú ¨åÕ•nä¶·´¹ºx°%hUv¡=‰b9ö  7¿üð—òãF÷ÿžþCüië¨Z=Ó[ ÓÏA–ŒžEGo«é÷+#Cw¬k¹Ènƒ×é@ ½ÿç„¿ÿ<ǘ%ü©¯§‹e¸7Qˆ™¶†'©¢Þÿí”¶éµ¢XRU‘Nwn'ü(êÁÔ2œƒÒ¼×Æ?ò ð÷ýy/þ‚•èÖ¿ñî¿SüÍyÏŒäáïúò_ý(´ÓÖèÿö oý¡[¦ÿ­ÑÿìßûB¶(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ª“Û-í•õ«±U˜²;eUº…¢;4R*†9!—<ã£ÒÌÿ²jFÖ;ãn°Û:ÈZ&%¤+Ó‚>_^õCHÓî¯tÛ¸ÁVÒF… .ÛÆ9à`¸õÅol¸ÿžÑߣÿÅR”¹=f‹þýŸþ*˜¬bG¡Î,ZŽ18XÑe72HUÃîôè+Kìïö´¬WeÉÞ€{FçñceÇüö‹þýþ*‘¡šE)$ÈQ¸!P‚Gæh¸X±UÈf‚écHäfrI÷[å^µX¨LRfŠEPÇ$2gŸÌRŽº^¢Ê°º[FÒ!±\8Pwañ•ÎGÓÞšt;¯ìØ"ŽTŽu’@çyoÝH~eÉ䞇žâ¶v\Ïh¿ïÑÿâ¨Ùqÿ=¢ÿ¿GÿЦ#,h¥57“ËYmžTq"y{@ä+ch#5¬oe?ôÍ?›Sv\Ïh¿ïÑÿâ©ñFP³;nvÀ$ ÿ]a&ûÑ×Eª3A¨Gª\\Ú-»,ñ"fI*A<àzÖ„±ù‹Œí ‚¡¨ö\Ïh¿ïÑÿ⨎4K›Xd†Ñ •g¶û<6FÓ–%€ÁÈùϦ—G˜Ã{:7œ°,lÇŸÝŒx­-—óÚ/ûôøª6\Ïh¿ïÑÿ⨸¬fØém¨™eA,k<“Ç'Ú$Ê–Ïü³û¹äŒÖ¤'2Ü×Aÿ -7eÇüö‹þýþ*Ÿ~Xl¶æc–8ÆM#œ\AõoýÕ%·¾³¼¹{5‚Xn\HDŽU‘°èGzXËí*ÛYNAÆE3eÇüö‹þýþ*€2“K¿mU.n%*<¤9ÊÀ…P˜Âã={â™.…q-œ>dJÐÚ4,y ¶ä#ê>S[.?ç´_÷èÿñTl¸ÿžÑߣÿÅP3oìoo¤¶¹’8–X7©Š;—@U€ä:€Aã¥XÓ´ö±¼Þ‹@m’-Ë*IÆOQÏZµ²ãþ{Eÿ~ÿFËùíáÿ⨠kÿéøÿ3^sãùø{þ¼—ÿAJô”UŠ5@xd×›xÇþA>ÿ¯%ÿÐR€;M7ýnÿ`ÆÿÚ±\^1Ñ•¬š[Ü5¼K2DŽ ÆO|Qÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”Wÿ g†ÿèŸø ð–xoþ€)ÿ€ÑPyEpð–xoþ€)ÿ€ÑQÿ g†ÿèŸø w”„àf¸OøK<7ÿ@ÿÀh¨ÿ„³ÃôOüŠ€;®sÿ×>¿Jó_ÿÈ'Ãßõä¿ú V‡ü%žÿ  à4U‹â½v×Z6bÒ !KueÚÀÚ€?ÿÙfotoxx-12.01.2/doc/images/rotate.jpg0000664000175000017500000003144311701011016015651 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 279 300 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀâó"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'L}OgÓl™šÖ"Y­Ð’J ’qSGa¢Ëq, ¦Øy±`º›T¡éÈ÷©´_ùißõéþ€*¶±™g‚ù ¯ÍŽ‘¯rÿìNçäd<Øh¢ím³l Ì…ö‹T8QÜñÅ%Ö›¦AeÒ´òIÇ6Éþº)DŽX$ /ÁÝt\å»0=Óû¾ƒŒšŸS8·_÷Çò4â®Å-›ö}?þoþ§øQö}?þoþ§øRfŒ×G³F<ì>ϧÿÐ#MÿÀTÿ >ϧÿÐ#MÿÀTÿ LÑš=œC‹ö}?þoþ§øQäiÿôÓð?“4›¨öqìì–;Itz&žÃÔZ/øR¶ŸlªY´;Rmü*–¥1[8$~õ³ ¨´û²¶àãtl«œœ’‹i;XÑ]«ÜÓM:ÚHüÄÐôö_QjŸáPùý4ßüOð­kCÙì÷³ÞÛ0p ÏCL·RûÏ“Jfýê·;V®Ë±7vÜÍû5ŽÍÿØúvÜã?eLgò¤òtÿúi¿ø ŸáZC›;„µTp³ Ž´³B‹§9(¤ª)YãÔÓ´{½ÜÍ{kØ«èÚr°ìmSü)¾NŸÿ@7ÿSü+bU©!™ÂÃ1¶ÎqÜ÷ª:žÕ’0!h›oÍ}ð Eé`m®¥y-l¢m²hÚjœgÕ?›äéÿôÓð?µ¦*²\HQ’$#ræ›yl“ Ž4òÞ=¬Î3ŸÎ„£Ø.û™^VŸÿ@7ÿSü(ò´ÿúi¿ø ŸáZ÷QB‰™0RÛ†_õ2á#òâ2¬!MÆ31·ê(\½ƒÞîeùVôÓð?Â*Ãþoþ§øV†ª±¤Cåÿ•ö¨~šËÍTa+Ø™JIîIåXÐ#MÿÀTÿ O.Ãþoþ§øS3Fj½œ{ òì?è¦ÿà*…]‡ý4ßüOð¨óFhöqì.vZ´¶Ó§¹XÛIÓ€9éjž™ô­¤i$divø ŸáYúYÿ‰„FÿÐMm§ú±õoýÖb¢ô6¦ÛZžãxãƒÅÚ„PF‘F¬»R5 £ä^€QNñçüŽzûëÿ -™g­Øj–Z&–·S¬m%œeAÎH¹þcó§G«hñ¼ñ«ÊAv rÄp2qU´’EÆ„AÇüIßÿmë{{xþt”Ú¶ŽÓ$ͳ|ºTI܆µ¬74;P-òº®ÌƒŒàÕU®¤ðZµõÌ^wŸgˆ« ¢uÃtÛœuãºQ +’°Ä"þà@òéG••åyQùxÆÍ£n>)ÜV9¥Õ®¢”îÔ>Ñe¥-xÈ€æ1Í\×oî-õ !þÑ|QZ£bŠÞsƒ¿0<8óÖ·D0‰A [×£lCNtGÛæF´åw(8>£4€ÅÒî/¯uVk‰å"µ‚FµT]»ÝI`ÄÜB:V^µu5ÅÍÔ3ßù^Eõ²Ed?x›ï$Ç’z|µ×àn-¸õ8äÓZ(ÕÞ(Ù×î³ $}jwÖámzMBê+ Nú{Ûƒ¶õíb%X¾pªrËïÉbGµU¶Õ¯¦µ¶ŠëP[ekÉ¡’ð؃*ÆÌœã8íҺˆU¢lîR£=r;Õ[Ý:+»e·Yd¶ŒíPìC)¥c%ýìþÒåKÖY®®’¸TBÅK‘ÛœJŽêòêÎëQ.„`\ZÂ÷MnEe9s€?^k¢µ´‚ÒÒX#(F7${çÖ’îÕn­Þ!,oÆçˆ.ã]ÀƒøŠå-ÞëQÖ-–=Z]еäqÜ¢DY”ðÛ´õìYðÝÛÞjmwsxÑKskm'Ù×hYIC’¸>„{×A§éöúu°†ÝIÃ.ø,Äõ< À©ü¨ƒ+£Üƒ v ¨ô” Ç5ý¡«Kâ9àŽâã†áP[Èè¾deA$7rpAÇ*¥íÄúŽz÷¿j»ò.™­*ˆ/ÜÀ»c’k²1ÆÒ,e×î¹PHúO&=ìë,Ž0dU¿:qrkš„VÍ%¾¨/ìã•ò‘…·f‘U OÞÏNkfÚMV_ß²ÞG%Ê–û,ѲHxP@l(Rsžƒ¡{OÒ-ìg–q$ÓÍ*ìi&Û½q…P?3W£Ž8“dQ¤kýÔP£òt¹ÉZë—ú…ê$NR çY­–>X(9Èyù¸£D¾£c$×­neÒ¡+Õf;ß+¼uwk­ƒDQÀ¤1Dvf(ÎϹ”/ÓÒ‹ŠÇ3áI.­áÒ-^íç·¹ÓÞPŽŠ<¢Œƒ TAzç§Zd3ê·7VÃûbxÒêîæ« GËî+·+þÎsøWTQFÑ…ÐzP0Š0IQÁ=MQ¤rCY¼žÎÒKIl3`gój|ùCm#æŽ3Ï=jK½nök³<âÚá¬`š™W*íøÈçœpsŠê Q2ª´Q•C• }½(’(åeibÊœ©u¦h™“V¾¶}UMÁ¹¹Že·Hü¶ˆ*žxa‘ÇžqIo=õÆŸºîò¨¾Ùdct‘3¦AØÇLqžµÓ¤QÆÌÑÅ3òÅPß_ZÏÕâŽ+(DQ$`ßZ“±Bäý¢?JÇøóþG=GýõÿЊxÎÜ>P[('¿á\ò]Ý[èúLQÞ-­£Ã3 ‰'10íËlñÎ8Í;Ê+ŒÔ5˜nYnõ7†ñ$µ[xb;Rtb»Ü>l’ÃÛ¦žâú-KØîçg–ñ£•žL,1 ȼ“ƒNÁs­¢¸››ûøí,wê}ŽV›ý).Ê®FÝŠeòÎO-ü#8ëëzÖúhµÛ(.õy$ÑF¾]´¸vd»GŒ•=wgJçQERQEQEQEQEV~·ÿp×í§þ”GZŸ­ÿÇœõûiÿ¥ÐxóþG=GýõÿЊOûøŸãKæÞÐ>OûúŸãO•…ËU6óþòßÔÿ<ÛÏúÉÿSühåarÅS³Laš†M»‚±#ÔSÒjÀQQ´æyqÄò°!p0?) ’ŠuÇüùËÿ}§ÿFëùó—þûOþ*€$Ž„Š]Íœî?Eºãþ|åÿ¾ÓÿŠ¡$&C‘´nì6Gàh ôè..–yÞáö²¸ˆÌ|½ËÈ%zžjæãœäçÖ’Š.æÎwýhÜØÆãùÔM#yž\Q<¬âø‘Fëùó—þûOþ*’QQî¸ÿŸ9ï´ÿâ¨Ýqÿ>rÿßiÿÅP”TM$襞ÒP dÊp?RCFA ¢ŠdŽ#Bì ÇaÔŸJ}ëùó—þûOþ*×óç/ýöŸüUIEGºãþ|åÿ¾ÓÿŠ£uÇüùËÿ}§ÿ@V~·ÿp×í§þ”GWc»2²2:cr¶8ÏN•K[ÿ8?ëöÓÿJ#¦#Ǽyÿ#ž£þúÿè E<ÿ‘ÏQÿ}ô¢€=SJÿ_¡Øÿ½iê?ñéÿOýVf•þ¿Bÿ°;ÿ;zÓÔ¿ãÌÿ¾¿ú§Äö/K EwnŠ 5J}VtcªaÚ$L1d zÓo­íï­ÞÞê$–&ê®23ØÕ%ѬãПIQ¼AÑ@,qÇߊ¹¦jrÝÍ=µÝ©µº€#´~`pU³‚úG¨ïKeª5Ö©wdÖ’ÃötW&1a;”õëéT¬ìo ¹{¹¯"’âfe""Ä€ü g‚I'5f+o/V¸¾óC[1ÓicœÿÀ¿JbÔ±)Ϋýpý jz¦uXÿëƒÿèKW)Hh)-¿ãöúæŸÍ©j(Î/&ÿ®iüÚ¤¢ÄבCuonäù—%–<2±Ïà*¦¯ª1`"ÒYIJ¤lÊ@XÃ0\’}Øp:þµ^÷DÓoµ/n-byb$’Èþý3š›T´þдX‚=³E&HÏÜul~8Å13S5Jnuÿ®-üÅL_$š¬Ç7ëÿ\ó5QHcmãúãþ¹ÇüÞ¥–ò(n­íœŸ2à°L>Q“ŸÂ«Äqy?ýsù½T¼Ñ4ÛÝF ë‹XžX³’Pù>ÝE1umTéÆÜ IfJ‘—RG¹‚ä“îz ­>¾bÔ$‹ìnÖpÜ%´·>`d|c Ü|Ê Ï~†¦Ôí ý¼q {&Ž\‘œì`ØüqT§Ñ^ké[íJ,§¹K©aòþbéŒÙàªO¨Bw7g?¸“ýÓüª­¿ü{Cþâÿ*|ï˜dÿtÓ-ÿãÚ/÷ùP2JŠãî'ýuÿB-Csþ­ë¢èB˲ʱFò?Ý@XãÐU+½Z mûT#ɉdEÝŒzu_Ú[j¯mw Kvuί֠·Ómì´ìû8` å„>d`«œc,£®qÍ ōڶŸGÏXV˜bÊ\6ütÚ­ž3ÇJÒÒï×Q²6‰Ã¼rFÄެU†G^GZÃËi Ig41^­È¹°m‹;JmÝÚǾsÍjévƒO±<ÙÞY$Æ7;±f8ì2x¦-IOüÏþâìÕO[ÿ8?ëöÓÿJ#«Hs{?û‰ÿ³U]oþ<àÿ¯ÛOý(Žž=ãÏùõ÷×ÿ@Z(ñçüŽzûëÿ -êšWúý þÀïüíëjh’hš9UºÖ.•þ¿Bÿ°;ÿ;z׺$@Ø$d‘îh°¿kûŸÉ?øš>Äÿóÿsÿ|ÇÿÄÕÿ°Ú>Ο•#ZYª–h"u$S»‘GìOÿ?÷?÷ÌüMbùÿ¹ÿ¾cÿâjð³³ d„ ›}Ø"88àQvEk{U…ÚC#Ë!ÞøÈœ*z‰£H/U!]¨ñ’TtÈ#ŸÖ¥¤ÝÆ‚¢–îdxßܘä~ Š–£Ž(绑f]ꈥTôÉ''ô†3ìïÿ?“þIÿÄÑöwÿŸÉÿ$ÿâjר­?çÞ?Ê“ìva‚˜"Éè1Ö˜ŠßgùüŸòOþ&"6.]är1¹±ÓÓ€Xû§üûÇùUsCz%Úb£¦Aþ´-QHdR@÷¬ã¦9ˆ4ß³¿üþOù'ÿNŽ(罕fPê‘©PzKgù ±ö+Où÷ò¦"¯Ùßþ'ü“ÿ‰£ìïÿ?“þIÿÄÕŸ±Ùî äE“ÐbZÙ3Xb%zÚ€+bÃs;)ê§hÏä3S€ À³YÛ\¬*¬W‚ 2/lÝY?•>›",ˆQÇÞQ\ó\‘¹ÕN !û;ÿÏäÿ’ñ4}ÿçòÉ?øšµö+Où÷ò¦µ¥’.ç†%¤b˜ŠÿgùüŸòOþ&³¿üþOù'ÿV ­Š€Z(Fî™ïNû§üûÇùPD±n!™™¾ó7STõ¿øóƒþ¿m?ô¢:¶ˆ±]McX/¡9Î?*©­ÿÇœõûiÿ¥ÐxóþG=GýõÿЊ1öyÿïš Ó‘ƒÆ?Ý¢â±jgýÄŸîŸåP[ÿÇ´?î/ò¨žyÞl°ÀÊàTñ®È‘%TÒÇTW?q?ëªèB¥¨®š/eƒ+ë‚?JXžI„.mÖ6— ‘ˆR}Ȱ¼EóiöSêOdûÞ KceqÇçIo£\Ey Ï$%RâîR2rD¿ttëëýi‹©³eªØjéewì€ÙÀõúTvßvOúí'þ„k;IÒ§±›Oy"-¬ ³ì'–Ütâ´m9‰ÿ묟ú 5QHc#ÿ”õÅÿô$¨"ÖÒâíá´±¼¸Ž9|©.#UòÕ‡QËqßÔ âýý1ý +iš½¼Oee=ºÚ5מ%ó%E/½—`÷GšÜLÖ—[²D¶ž¥†UŠEóì%‚õõÉéøTWšý¤:®Ÿ±Mq-À†D Ìcilýx{Õ6Ò.—%¨’ 福 rq°Í¿:ãõ¨ãÒ/£½Z›8u /D›˜Jwn;Jã—ëž‚šµ×õØNöfÉÿ„ÿî'þÍTõ¿øóƒþ¿m?ô¢:´‡7³ŸöÿfªºßüyÁÿ_¶ŸúQ!ž=ãÏùõ÷×ÿ@Z(ñçüŽzûëÿ -êšWúý þÀïüíëv°´¯õúýßùÛÖíQE!…Q@Q@Q@Q@Q@Q@@`;fä†MÜþb§¢€ ò®çå?ï×ÿ^*çþ~Sþýõêz(*çþ~SþýõêH£Fy$“ÜžM>Š(¢ŠŠX™Ý^96:‚3Œ‚8Çà)¾UÏüü§ýúÿëÔôPUÏüü§ýúÿëÑå\ÿÏÊ߯þ½OEG F2ÌϽß8ÇNƒO[ÿ8?ëöÓÿJ#­ ÏÖÿãÎúý´ÿÒˆèǼyÿ#ž£þúÿè E<ÿ‘ÏQÿ}ô¢˜SÒÆgІHÿ‰;ôúÛÖæÏöäü×ü+Jÿ_¡Øÿ½nÐv·'æ¿áFÏöäü×ü)ÔRÝŸíÉù¯øQ³ý¹?5ÿ uÝŸíÉù¯øQ³ý¹?5ÿ uÝŸíÉù¯øQ³ý¹?5ÿ uÝŸíÉù¯øQ³ý¹?5ÿ uÝŸíÉù¯øQ³ý¹?5ÿ uÝŸíÉù¯øQ³ý¹?5ÿ uÝŸíÉù¯øQ³ý¹?5ÿ uE;0¨v—p¹Æqš~Ïöäü×ü(ÙþÜŸšÿ…;ìGþ~î?$ÿâhûÿŸ»É?øšb³ý¹?5ÿ 6·'æ¿áNûÿŸ»É?øš>ÄçîÉ?øšnÏöäü×ü(ÙþÜŸšÿ…6fFAdvB@ÆpqšB[”…d1‚…ÉP3ÁýiýŸíÉù¯øQ³ý¹?5ÿ wØüýÜ~IÿÄÑö#ÿ?w’ñ4ÀnÏöäü×ü(ÙþÜŸšÿ…;ìGþ~î?$ÿâhûÿŸ»É?øšnÏöäü×ü*†´1gÌÇý6Ó®?çâ?AWna{kwn$,n*áp@íÀO\ÿ8ëö×ÿJ# ñçüŽzûëÿ -xóþG=GýõÿЊõM+ý~…ÿ`wþvõ»XZWúý þÀïüíëv€ (¢ÂŠ( Š( Š( Š( Š( Š( ¢›ïCÿ]WùÔµ ÑØ±¹û«"’}h2qqw¯j1NæÖ;kxž?,®Õ'vIsÐU;ojSéŸmH-UmmâádÜ »³÷1÷F œõÞ´n¬´KÛ“qw¼²·HpÀtsƒøŠ}Ͷw4s\Çk#ÄRX@@8 z)ˆ«>½õÄ‹±±·¹·« H”'Í»8à¸ãºÓôMsQÔ®Õ¤±Ûe/™µÄl<½§,N8=ǽZtÓ$2—òÍ"K'Ï÷1´õí´~TØ!Ò­®¤º·G,™,VLOS·8ý(™jÛ•”ÿÓgþtä8ÔÿÓÿЖ™gÌ,ÝšFaî ¤’E†íF ¦6\“œ©þ†Ìý§ÔDšÖ£sˉ[ÆTFŠŒFc$2N{Õ%ñUç‘|â8e j.­e0·©Åuý˜ëf×Íp‘$ÁYbÚÈÏ’¹Î@B1žxäR^kš¬Z“YZÙ¥ËÛGM²'Ä¥‰ÈSŸ`N­\¹ƒIº‹…·“Î*\—ä•û§9àQLk=Úd‡t 6óˆ`Î ÎXg×4–Ùѵ~¼Þ\õÿz¬ëŸñéý~ÚÿéDtKö4·º[O(IrK0FÎ÷#ÅçüyÃÿ_¶¿úQx÷?äsÔß_ýh£ÇŸò9ê?ï¯þ€´Pªi_ëô/û¿ó·­Ú±‚óìº-åœpJ#ÓDL²ÊcûÂ"!O÷çW¼Ý_þ|lð1¿øÝ_¢¨yº¿üøØÿàcñº<Ý_þ|lð1¿øÝ!—èªn¯ÿ>6?øßün7WÿŸü oþ7@èªn¯ÿ>6?øßün7WÿŸü oþ7@èªn¯ÿ>6?øßün7WÿŸü oþ7@èªn¯ÿ>6?øßün7WÿŸü oþ7@èªn¯ÿ>6?øßün7WÿŸü oþ7@èªn¯ÿ>6?øßün7WÿŸü oþ7@èªn¯ÿ>6?øßün7WÿŸü oþ7@¶¯÷òm_î/ä*›«ÿÏþ7ÿ£ÍÕÿçÆÇÿÿÐí«ýÅü…Wû‹ù £æêÿóãcÿÿÆèóuùñ±ÿÀÆÿãt~‚à€~µCÍÕÿçÆÇÿÿÑæêÿóãcÿÿÆèöÕþâþB«ýÅü…Qóuùñ±ÿÀÆÿãtyº¿üøØÿàcñº½µ¸¿£jÿq!T|Ý_þ|lð1¿øÝn¯ÿ>6?øßün€/PrGÐV~·Ÿ²A×mµíÿOÓŒš¹ÿ—ü oþ7P\Áª]ˆc’ÖÊ$[ˆeg[‚Ä‘àyc' ޾ž”Äy'?äsÔß_ýh£ÇŸò9ê?ï¯þ€´PhÕõDP‰©^*¨  NÀ:ÍÛ:·ý/ð!ÿÆŠ) ?¶uoú ^ÿàCÿÛ:·ý/ð!ÿÆŠ(þÙÕ¿è){ÿþ4lêßô½ÿÀ‡ÿ( ûgVÿ ¥ïþ?øÑý³«ÐR÷ÿüh¢€í[þ‚—¿øÿãGöέÿAKßüñ¢Š?¶uoú ^ÿàCÿÛ:·ý/ð!ÿÆŠ(þÙÕ¿è){ÿþ4lêßô½ÿÀ‡ÿ( ûgVÿ ¥ïþ?øÑý³«ÐR÷ÿüh¢€í[þ‚—¿øÿãGöέÿAKßüñ¢Š?¶uoú ^ÿàCÿÛ:·ý/ð!ÿÆŠ(þÙÕ¿è){ÿþ4lêßô½ÿÀ‡ÿ( ûgVÿ ¥ïþ?øÑý³«ÐR÷ÿüh¢€í[þ‚—¿øÿãGöέÿAKßüñ¢Š?¶uoú ^ÿàCÿÛ:·ý/ð!ÿÆŠ(þÙÕ¿è){ÿþ4lêßô½ÿÀ‡ÿ(  ³M-Ä­,ò¼²7Wv,Oâh¢Šb?ÿÙfotoxx-12.01.2/doc/images/brightness-color.jpg0000644000175000017500000004475511701011016017647 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí6Photoshop 3.08BIM resize sharp ÿá 4http://ns.adobe.com/xap/1.0/ 451 245 ÿÛC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;ÿÛC  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ÿÀÃõ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?åô½/óøFø† FîæêôÛ¢2îcŒŽ;)憃áúc~‰âEÏLìû5ìá^’ç¢ë™ÿǽÂ^Ó¯4¥3¬2]K–G•7uì=â¹±…G•%vöF´éóÝ·dŽìž#?Ø>&ü“ÿŠ£ìžÿ ‰¿$ÿâªÖ«g­½µ©Í¼ªÏì {ƒŠì/¼7k…ÚÒ8í¿´mmÖíÝdS3’ÈW®kjU#Vš¨¶fs‹ŒùYÃ}“Àôñ7äŸüU'Ù<ÿ@~IÿÅW}‹i¦ø~ðEËÉ5½¤­ráLg|Šq»ç4Ö𮥬JÎ÷rnÕd¶™£Ø6 MÁ°çð­ZH›èpdðý|Mù'ÿGÙ<ÿ@~IÿÅWi¢øoO–×LÔsÎZæ5¹•¨2mi\°> Õ; 6ñôfÆXíÍÁ ¬õìù}(²½‚ú\åþÉà/úø›òOþ*²x þ€>&ü“ÿНA»Ð4íRçKÍ¿ÙRigIZ ³3RÀlŽßz³tý6ÃVÑlÒ9çµµ¸Õ¼°%1–Qågï“Ç\{RIv9²xþ€>&ü“ÿФû'€¿èâoÉ?øªô4+ IÚKkÄIô›§–Ý ¨ãå!p ޽j«è:m¦Ÿ¬¢ÚÝ^*%¬°”Ûç pO]¤c׎”hœOÙ<ÿ@~IÿÅQöOÐÄß’ñUÖÝxgLM$É ×Kv–v÷NÒ2È‘¶ëÖ¬êžÒtë»HêðoºËò†.¥Iܘ^99õ§d+œOÙ<ÿ@~IÿÅQöOÐÄß’ñUÛÂfnomÖ+ã2F²[Eæ¦$R Ü_f;}Þ Qð·†-õ»¸º¢³˜ãš9P.í¹ÁR¤ŸÌQd;œ¿Ù<ÿ@~IÿÅRý“Àôñ7äŸüUu—~Ó"Ò™âšè]Çc Û³²ˆwÚF1‘Œg­Yñ“k£x^êÒÞbÔcS5À_Þþ윦Ýüè² N'ìžÿ ‰¿$ÿâ¨û'€¿èâoÉ?øªì/­^ÃF²M3A·¾·º²óg½’•ÕÎwÀávàœÔ‡Â¶V–)v­wæÁ¼æyýžmìEã9õ§Ê®+œgÙ<ÿ@~IÿÅR}“À_ôñ7äŸüUzþµÔu«énûtú‹À‚Ùlnàï‘ÐätÅsZ¶›§éÚM‹£\Iwv¬åüÅò€W+ÀÛžqëSd3ìžÿ ‰¿$ÿâ¨û'€¿èâoÉ?øªvGù4d“UÊ+û'€¿èâoÉ?øª>Éà/úø›òOþ*‘þMäÑÊÖþA—ÐüH£Ôìû5(µð WBñ)¸ ÿÅW[àÝÂþÈÞ]ù-$Èòw,h¬=óœÖ?Šô«}WˆÚ2ndG¦àÀ낸ʯ%´½¯çé¿C¢TZ‡5õìd´Loѹ®ÆöiSÜ[Ú°h%è… ¬¹ €ú{R¥ŒJœ©hïgÞÃÞúö0|GžñV§¦iw3Á 3ld98Ï~¦Š—â/ü”oþ¾›úQ]¦iáÃâ/†–¶³\Ën"Ô^ex€'!HÇ?ïV”2kÞO±‹;«ÄXÌQÜZÄdÞà¹*q׬СÊDJ”Sê ®£É‹û‚&/î .ÂÈæ¿á Ÿ2øK5¬ÊÉûÁóÀ ê=Dþ*#øSuŒmE`„ ôôJ꼘¿¸(òbþà¢ì,ŽOþä_ôÔ?ï„ÿ ?á^EÿAýCþøOð®³É‹û‚&/î 9˜YŸü+È¿è?¨ß þ¼‹þƒú‡ýðŸá]g“÷L_Üs0²9kkm[¨ְZK«Y0!`¸†*È9ê31QOáýOÅ—‚÷Tit˜bP°Fˆ¢CòŸºãžk®òbþà£É‹û‚¹ãBŸ:4u$ãfs6“kþ…¬mí®®áùV;‹XŒŒÊ¤• •<{©?„/|Wu.£¯O5þî— œ’ßÝè0:×cäÅýÁM1¢IUÁÝý ¡K™À TrVgˆ|Amþ=ÖŒn¸'ôS|}ÿ#έÿ]ÏòWY‰é? ÿä/ý}Iý+®=Mr? ÿä/ý}Iý+®=MCܤ%QHŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ˜ÿ~/÷ÿ¡§ÓïÅþÿô4áž>ÿ‘çVÿ®çù (ñ÷ü:·ýw?ÈQZzOÃù'Kÿ_RJëS\Ãù'Kÿ_RJëSP÷) ER¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¦?ß‹ýÿèiôÇûñ¿ý xg¿äyÕ¿ë¹þBŠ<}ÿ#έÿ]ÏòV„ž“ðßþIÒÿ×ÔŸÒºãÔ×#ð㟇J?éêOé]A·?½›þû¨{”‰h¨¾Î?ç¬ß÷ÝgóÖoûîÑQ}œÏY¿ïº>Î?ç¬ß÷ÝKEEöqÿ=fÿ¾èû8ÿž³ßt-ÙÇüõ›þû£ìãþzÍÿ}дT_góÖoûî³ùë7ý÷@ÑQ}œÏY¿ïº>Î?ç¬ß÷ÝKEEöqÿ=fÿ¾èû8ÿž³ßt-ÙÇüõ›þû£ìãþzÍÿ}дT_góÖoûî³ùë7ý÷@ÑQ}œÏY¿ïº>Î?ç¬ß÷ÝKEEöqÿ=fÿ¾èû8ÿž³ßt-ÙÇüõ›þû£ìãþzÍÿ}дT_góÖoûî³ùë7ý÷@ÓïÅþÿô4ß³ùë7ý÷Iå’3¾Fùº3dt4áþ>ÿ‘çVÿ®çù (ñ÷ü:·ýw?ÈQZz'€|ßøVyë¼é¼¾Ÿ{u÷­ï Ë©MáûgÖ5þér6ðC°åã ?úõðßþIÒÿ×ÔŸÒºVf‚ûœ˜®2_î¸Ä8èW§$Ô1¢ÅQHaEPEPEPEPEPEPEPEPEPEPEPE5Ý"Bò:¢¯%˜à §6·¥Û%Ô-ÔžGÎò  ÔÇûñ¿ý R°—‹m?P+þŠÑ+PòmLc§ÍÏlÕe»Õæñ¤riòÚéæ) ™ 9ó6ä¡eNìœ@<‹Çßò<êßõÜÿ!E>ÿ‘çVÿ®çù +BOIøoÿ$éëêOé]UÄBxž"Ì»º2ã*{FAçG+•øoÿ$éëêOé]qêjå"yšxwÓ«Mþ§MŽy up#èˆ>Øõ­IêsI@Víœm'‚@7üƒÿ?~kþ€–Š‹È?óñ7æ¿áGçâoÍ€%¢¢òüüMù¯øV'‰|CkáÍ<Ü=ÃÏ6àÜLŠÍÈÉ)éšè(®{HÔõI·¿³·{h§ D—3£¯ «’>R9ÛøŠ¼ºUÔÀý»WºpßòÎÛ¨õ€Ü{r š¹u}gbª×wPÛ‡8S,wlõªÃWÇ•åÉé‘ Aô%ñŠ}¶“ifÅíäŒ0ò¶WíHÀ³c¶IÀÀVL,zÜÎ~¥€*cZŸÖ6#¨Ê½Ëb@§Ü3çIýŸñ÷y}x:m–`ŠG¡X©üE[òüüMù¯øQäùø›ó_ð í´ë6mg N§!ÂÀû1ä~uh’Ç$’}MCäùø›ó_ð£È?óñ7æ¿á@ÑQyþ~&ü×ü(òüüMù¯øP´T^AÿŸ‰¿5ÿ <ƒÿ?~kþ-çâoÍ ÿÏÄßšÿ…KEEäùø›ó_ð£È?óñ7æ¿á@ÑQyþ~&ü×ü(òüüMù¯øP´Çûñ¿ý 7È?óñ7æ¿áIå’3æÈÿ7F#  ñ÷ü:·ýw?ÈQG¿äyÕ¿ë¹þBŠÐ“Ò~ÿÉ:_úú“úW\zšä~ÿÉ:_úú“úW\zš‡¹HJ(¢ÿª³ÿ²l.ç³ôE"H¾› Ï÷H>â´(  fÖè-cÿ‚Çÿãô}—X<6¯hêSN`ß3Ô¡«ôPö4RÇåÝå稖]ªGlªùÅX‹O²‚†++uñ½| wã¡lýâ2y9«PQ4 ,h½(@)ÔQ@Q@Q@Q@Q@Q@Q@Q@Q@1þü_ïÿCO¦?ß‹ýÿèhÃ<}ÿ#έÿ]ÏòQãïùuoú$ôŸ†ÿòN—þ¾¤þ•צ¹†ÿòN—þ¾¤þ•צ¡îRŠ(¤EPEPEPEPEPEPEPEPEPEPEPEPL¿ûÿÐÓé÷âÿúðÏÈó«×sü…xûþG[þ»Ÿä(­ ='á¿ü“¥ÿ¯©?¥uÇ©®GáÀÏÃ¥ôõ'ô® ÛE“Ì¿÷ùÿÆ¡îR%¢¢û4^²ÿßçÿ>ͬ¿÷ùÿÆÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÑQ}š/Yïóÿf‹Ö_ûüÿã@ÓïÅþÿô4ß³Eë/ýþñ¤òR9#e/ßÅ#7cêhÃü}ÿ#έÿ]ÏòQãïùuoú$ôŸ†ÿòN—þ¾¤þ•צ¹†ÿòN—þ¾¤þ•צ¡îRŠ(¤EPEPEPEPEPEPEPEPEPEPEPEPL¿ûÿÐÓé÷âÿúðÏÈó«×sü…xûþG[þ»Ÿä(­ ='á¿ü“¥ÿ¯©?¥uÇ©®Gá¿ü“¥ÿ¯©?¥uÇ©¨{”„¢Š)QEQEQEQEQEQEQEQEQEQEQEQESïÅþÿô4úcýø¿ßþ†€<3Çßò<êßõÜÿ!E>ÿ‘çVÿ®çù +BOIøoÿ$éëêOé]qêk”ød¡þÆ­ÐÝÉŸÒº)¥µ·*'ºû»åÛŸ¦jå"ÅÁ‘ïƒþÙ¨çhm¢2Í+ª.2K瀞Šg’ñ?ýöhò—ûÏÿ}š}"2y~ko;|ÎqëŠw”¿ÞûìÐè¦yKýçÿ¾ÍRÿyÿï³@¢™å/÷Ÿþû4yKýçÿ¾Í>Šg”¿ÞûìÑå/÷Ÿþû4ú)žRÿyÿï³G”¿ÞûìÐè¦yKýçÿ¾ÍRÿyÿï³@¢™å/÷Ÿþû4yKýçÿ¾Í>Š‘K3º¨$¿šÞRùy•ÿzpŸ9ùŽ3ü¨j* Œ6ñ4³Jè‹Ô—Љ9'‹Èv8Bpãzã2~µ!ƒQMi°×"(ä_$~õÑâ 2¤ò¹'<±Îq[Ù¢ŒQEÂÇ3 ê[]o]Bo)•6\3nÉÜ ‘¿2WÚº"ícK ÂåèÝ‹2ûy'ëÍK‘ê)hÂ|}ÿ#έÿ]ÏòQãïùuoú“Ò¾|;R;\Ëü«¹Xá9 oj…5¸b~PrOã\'Þ>ÛĿʺmTjX8ÓäU“)œ¡bFÔé‚1Q-ʉ±äÅÿ<,ÿðƃ_óÂÏÿWükù5†šËì÷`Kûâ!ltnOÍ÷zqëŽh‘uS¬ÂÉ<_e¶áå7_—©Ý×®?­IE«Ÿhdic;„k´Œãð«ZTvòE;MR0˜¨.°6©Ç?STæíý2oýj{Awåg¡Ø¨'bu ~Fš%šâÚÇþ|í¿ïÒÿ…/Ù¬çÊÛþü¯øVm¼º‰sö¨m#Lpa¸y~†5þt†mWÎÀ·±òw}ãtûñë·ÊÆ}³øÕÒ6Ö?óçmÿ~—ü+;TŽþÌa†8‹K´”P¹Xöú .eÔi ¬‰ŽL×ÏÐFßΠ½i²ó‚,†S¸#Pv7B@Ïä)&œÉy(š$,`€êûÖ ¶±ÿŸ;oûô¿áXöLEü Ïÿ¡S5%ÕžöÌÙMB%ýàh™°6·,C:qëŠ3sìÖ?óåmÿ~Wü)¦ÞËþ|í¿ïÒÿ…Q¸–øû,vÒâó¦hñôÂ6J|/pbåbI;¬R_̪ŸÒ€3›ÎaVYØ8­{H,ÚÎÝšÖ-Z0I%A<â±Tåg?ôÚ_ý Ö›·Ø-ˆÿžÿè"šÚÇþ|í¿ïÒÿ…ÚÇþ|í¿ïÒÿ…fC6¨ex,’,òÑÝ;7äbõª×CVmfÙ ž%µûÃDÇ:Ý}?­1õ8­c°‘ã·…vá‘‘Èôªvê¨Û¤ª¾U†AÂ1ü@©u6?ÙòsÝô!UÐãR´÷wÿÑoHfз²ÿŸ;oûô¿áNÖ?óçmÿ~Wü+UÕŽ¹ ÇÔž˜^H0¶můðwÉ<ÓŒ+]Û¤ŠPOC["ÞÈÿË·ýú_ð¬Bqwmÿ]–­M.¦%"Ú 74·.Ÿ ‡ëHf˜¶±ÿŸ;oûô¿áA¶±ÿŸ;oûô¿áXÚÇö”šc 'ÀÈ ÌO²GçúU’÷Éhýžk‘×s4Qž~ŒGZYº‚Ì[JE¤ B1cŽ=k"2LHOR¢¬™/MÁ»ŽÞ2#;|‰šLðsȸýj´?êcÿt* ñ÷ü:·ýw?ÈQG¿äyÕ¿ë¹þBвOIøp¥þ…Q’neò®¥/àU;Bä4d ‹í\×Ãùbÿ¯¹?¥u9>µ) þуþzûñ/ÿGöŒóÐÿ߉øš~O­>µ6ÈEšë|{Š,[K2Ë'Œ€{Óí/!³k„ŸÌRóoR"flQØàÓèɦ"_ík/ïËÿ€òñ4kY~_ü“ÿ‰¨ò}hÉõ  ?µ¬¿¿/þÉÿÄÕ{›¸¯'¶oo.BîZ6PÆÀîEI“ëI“@ Žá-/šI·„x¶†Tfç9ì XþÖ²þü¿ø'ÿQRäúПÚÖ_ß—ÿäÿâhþÖ²þü¿ø'ÿQäúÑ“ë@A–‚FÚG™$Ž Œ$qô"¦´Ôíb²·ŠS*É(Ž<‡8!@=µdúпÚÖ_ß—ÿäÿâhþÖ²þü¿ø'ÿQäúÑ“ë@ ½¿‚êÔÁ˜Ò;.…ÔpÀžHÇAM’A å´ìǶòªX€Q”p9êEI“ëEKý­eýùðOþ&ík/ïËÿ€òñ5O­>´'öµ—÷åÿÀy?øš‚ÿP·¹Óî ƒÍye‰‘’ã$ŒHÀ§äúÒdúÐs¿—,2Åc™Y¶Œœ}YþÖ²þü¿ø'ÿQRäúПÚÖ_ß—ÿäÿâhþÖ²þü¿ø'ÿQäúÑ“ë@Χk%¬±Æegt*£Èq’G¸¦F¥bE=B€*vO­á>>ÿ‘çVÿ®çù (ñ÷ü:·ýw?ÈQZzoÃùbÿ¯¹?¥u5Ë|0ÿ‘/úû“úWm¢h6Žš.ïi&ye‹‰ade`:RÕØÊTSîm"±Ôn­` !B…œ¹^y$šÊ›Wònn¢hT hËüÒaäs•\r;g=jFiQXã[¸F>}‚¢'”deœ6„ `g¯=?Šï[iêÞ&%‰C,Ê$ãxRzS°\Ý¢³ ¾1Ü^¬Þtn¼¸Äp³íãå$òj³ë72úbIEÊEå<¿6 w |½=è°\Ú¢²Äº³hW*â'Û($9\ð¸É^@ÝúR&¹/Ù„’ز³Ûý¢%I7ï\€rqÁ‡j@lQPÚOö«XçÌgxÿ–o½zö8¨u;©m-U¡ æI"Ä¥þê–8É  ”U%š{K˜mn% >â&Í»Fzsš­³4èod6ßhpÒà’08äñí@ÔVDÞ †8̉dÌj®ÒRÎ7`žØ$ûÒ]jò>„/­ó™V3òy˜ùœ÷¸éŠv ›VíüñDª——eÜáòN<Ä(Ã=Ï>õiµä:«ÙE|JaJ7oÆ~ï]½³E‚æ­Mgfo<Óö(FÁqåîÏõ] ÔºìbåÎp}3Þ¥´¹û4Òà°Œ†Àï…¤ßìoú~?÷ãÿ²¥þÅ?óýÿ?û*ÇVÔà‚ÂúâxeŠñÑZ0ý0ÙçécñiK1wyf`ŽKf¹ˆ¬¡÷*ã ð0yÞõVÍoìlË÷þ@ÿ쪽峷3 ¯3k(*bÛœ°r}j„*šè¬6öQÉpÒˆð.A”-àýÒ1޵f]@jWJ¬‚fånª|Õ~,Vm4ówl“›¯/yl(‹v0ÄuÈôªÔ›è¼>­§Ç¾pì$/šÛˆ dÞ¤f‡ö)ÿŸïüÿÙQýŠçûÿ öU‘/ŠÇNYÚâ+²„žiû<ƒoPŒîèqV‡ˆÔÜ›s ¶‘»¤{7ùŸLqZ­\:9í}Ïýpÿì«:&ß¹î)t_¦³3"DyBd+(|©8Ãcî·#zŽÐæÒ#ê´˜ÑáÞ>ÿ‘çVÿ®çù (ñ÷ü:·ýw?ÈQVIé¿ ?äA‹þ¾äþ•ÖÛÜÜÚÅå[ÞO{‹l_,€IÉÆä'©'­r_ ?äA‹þ¾äþ•ÔÔ=Æ…fy$y$‘ä‘È,p:?J©6™iq+I2<…”®FÚ¹8ÀãÒ­QHegÓ­$WW‹!Âù!Wò¨†`×Êr®…6™X…RrBŒñÈнEE¼P<¯Ó\î'$ gòªçH²a&ô‘ÚM¹v•‹ §#9$ô«´PQ§@ŽÏ•— ‰[ Æ2Ã8'ÍCg¢ÚÙÛ,JÒ³ˆ„f_1ƒ`zsòŒö¡EEom¤"j[’I$œ’IêI¥žÞ+¨ZÐÙå_5ZO¾V ÇÉÆqÞ¬Q@ DXãT\íPÉÉÇÖ¥ÓpÒÞ/_™8öÛL¨¥µ¶œ†šÚHè^0ØüèÌ:%¼Ë,P0d$Æ¥Ù–2{ª“øTV²±³[vG¸"%žRÇ+ÜIÚ ªÿÙ¶óákÿ~Wü(þͰÿŸ _ûò¿áNácJ=6ÌGÈarñ™fw*HÛÜôÇj¯{o–’–ð¦ÈÖh‚©$õ•Iëõ&ªÿfØÏ…¯ýù_ð§Çei ‡ŠÒÜtd‰AŽ(¸Xšeo掑H_o™.|·*A·qȦÔXÙÊåä´Üõf‰I?Ž)a¼=§2íò% Ög ᱸ3g$¾•etëU¼7‚Üyæ!î~àíŠÌþͰÿŸ _ûò¿áGöm‡üøZÿß•ÿ wRÒÆ+š±ñ…yY•ôáGÒ³ll-Ϫ oöu‡üøÛß•ÿ ²8ÀP„øûþG[þ»Ÿä(£Çßò<êßõÜÿ!EY'¦ü0ÿ‘/úû“úW@÷˜‘’5Ý·9ëÛ¯A\ÿÃùbÿ¯¹?¥l©ÕtÛÙfÓ€a(#và’0HïÞ³úu.A2Î…—±ÁV]^Ö‰!q(ò™VI<³±KtËtïOÓm^ÒÛd˜ qòƒ  šÍ½Ñn®/n¤Œ(¼l’†6€9î·#½óäjÍ{Nc#Ê¥AŒ:† gûÒOmN|Ô‘àFvÀéTçÒ¥’;°<½óÝÇ2·}ªPœñ×å5Ÿ…ÜÒ›e´1¤0\'Ú6O1Ÿ¡;”gðÍ1'U³[¼3§’JÊÁ¶– qÓ“S-å«È±¥Ì,ì2ª$‘ì+2}r²y"˜íð¹ÀgƒñßÍ9ô»‰žâfŽ–[ˆe\6v#8¢ÈJæŸÚ`ó?:=ñŒºîQêGjgÛm6#ýª²!óúZÇù·rý¡¦dýò¦íùàá7wÇÞ=HtÝH­»æ/´ÄX K¯Ê„ƒµ†Ü7N£ŠmÑAëE (¢€ (¢€$‚ÚâéY ˆ2«m$¸^p¨©?³oÿç‚ßåÿ~•.Ø'— ÿ %âžuy\}œâFòŸh<|¡±‚ÜŽÏ=)€ßìËÿùàŸ÷ùÆìËÿùàŸ÷ùÆŸˆì%h’)dw”!rË‚ÜÊ`‘÷±Q]øªÂÞ+¢’¤¶GbФoÛ÷‚¶0Äw8¢Â¸ïìËÿùàŸ÷ùÆ“û6ÿþx'ýþ_ñ«êÁl Üv×2ñ‘”ÈçþÀõ4ë=@^Ø[]…(.!IB“»€8ýh°\Ìä 6²¬=©â²¼š$• RŽ¡”™TdœUrÛ¤¹?ôÙêâê°XévO;8ó"‰R6vf(8  “ÐÐ1¿Ù·ÿóÁ?ïòÿ/öeÿüðOûü¿ãJ|I¦¤ÍÝle’ÈÁA$n#€ä®síNoØÇl—ó*ÈHEky¶I ·qç8ÅÆf_ÿÏÿ¿Ëþ4fßÿÏÿ¿Ëþ4û?A}{5´K#•™cfÃ.ìïhúš‹Pñ6Ö÷¢-ÆæÚ %XäÐ>Ñž aÓ¦h° tëñÿ,þþ­VF¡‡CW¬µ9.on¡eP òö‘ßräÖm©Í¬GÕhjÀÏñ÷ü:·ýw?ÈQG¿äyÕ¿ë¹þBб›ðÃþD¿ëîOé]—pÅ'–Ïóã%UK=ñ\çÃùbÿ¯¹?¥z…ä¶ŽÊx‹*܉æà°'å?M¸ö5-]ŒÆŽD•ÆÁ”ô"O¹h$ÔnåµÚ`yR¿u›b?åXW× {xŸj)_QMò¤Gv‚îh̨‚p~e=€ééK¶ïþ‚w_÷Ä?ün˜Ÿ¶ØDw0ÀÑÈdy!ƒ±$gÈq9Ýš`ð¼ \'œ¾\¢_,˜Ø¼EóœØÇ'øGÖ§ÛwÿA;¯ûâþ7FÛ¿ú Ýßÿñº.øá›ìžUÄé,…H2${ÿ€äÿ:,­~ŧÛZßöxR-øÆí  ã·J¡¶ïþ‚w_÷Ä?ün·ôºÿ¾!ÿãt„C“sÿ]äþu4VŸk±Ò%ó6}a›s»÷xÇ·ZŽ8ÄI´l’Y˜òÄõ&š‘O,qj1ƃj XˆP:Jùšjøv4»–u–'Y¤ 4,å‡_¾=±Ÿz‹þ’b7À˳&co-U€BïÜûÕcmßýî¿ïˆøÝnÿè'uÿ|CÿÆè[)´û—x'`‘T<">e\eNî±ëTÛÃ&I®kó š9£ŒïORXƒŽƒ *}·ôºÿ¾!ÿãtm»ÿ ×ýñÿ  vV/ku4Í8α†=¸eÈäð}?Z£bscõAOÛtx:×ýñÿÙ)ÑÆ±F‘ Â  ¸%cÂü}ÿ#έÿ]ÏòQãïùuoú“Ó~ȃý}Éý+§xã”,QÈO1céšæ>ȃý}Éý+µÑô;}VÕ¯od™ÃHéQÌÑ„ ÅrvI$Ïlqë-]Œ§J€ÀcLÒÍll¯.-<Ö•aa±Ûïma®=kŸ»ÖnáÔç·‰£b’ÇPùL›€'÷™À=zŠVÖÃ7÷± –99£scŽ=3X‡Å6"âhºˆüÌu,Å: ät8ÏZµ§Ý]\_ÞÇs„D±ˆvçvNG®åH Ç;²sëKæ8$ïlžù¦Ñ@ ½€Æã޽h.Ç«õ4”PïlcqÀíšRîNKýi´P–cœ±9ëÍ!$œ““EQE¨’JÅb†IJý틜SþÍwÿ>W÷ìÔº\¾\—cþ¹Ÿý ’ËÄ–—ú@¿·’'"!#Ä&\ÇžÌs€~´ìe¼ÿŸ+ûöhû-çüù\ß³V®|E§ZE3Éw6ø3"8-$ ‘ž=êuÖ¬¡U¾¶cqþ¤ TùŸîóÏáE…s;ì·Ÿóåqÿ~Íe¼ÿŸ+ûökHêÖbìY›¸Éùƒ~?ÝëPÿÂA¥ßý§i·—Ÿ=q»û½zûQaܧö[¿ùò¸ÿ¿f›$s»¥·š5È«óëšu´Æõ X¥Q¸£ÌªÀzàž•¡wΓæC"IWF0ó¡X.S¢Š)QEQEá>>ÿ‘çVÿ®çù (ñ÷ü:·ýw?ÈQZzoÃùbÿ¯¹?¥u–ÓÜYïû-ÃB$;™v†úàô5Éü0ÿ‘/úû“úWWie¨êA䲊 1O2w+¼Ž¸LúԽƆó–ffws¹ŽKSUeÓ­¦[…uoô†Vrzв¨òC<~\Ñ6×\äz‚¡RmJ(®ZÝ"šyâËl¦jF8iК=Ófݾ!òþnI·<Ó­,a³i7•Þ]¡šWÜp¹ÀýM8ÞÚ¬¯\Â$w:Tz‘ØRë5…&7Pˆ¤8G2 ¬}zžŠ„]Û“l."3ŽLAÆïË­M@Q@Q@Q@Q@°ææð³þÏY¿ðŽÜÿgÇoæA½tϲ1ÉÁ|‚Nœ~zU°."™å¶š$2%ˆ¸ã8Æc©§yú—üüYÿà+ÿñÊ`U“D¿tºŠ) ‚ÞOž8¼ÆpdÜwÝsŽ@ÏZ[ÍþöK£'Ø×íÂ13fh¶Ÿà;FïQœ`ÕŸ?RÿŸ‹?üþ9GŸ©ÏÅŸþ¿ÿ¢â±B;Ѭ¤ m›hïdºk†ÔÀðI]­×ñÚ¤›EÔÿ±l´èn! ¹†eó 8À ìl޼`f­ùú—üüYÿà+ÿñÊ<ýKþ~,ÿðÿøå,ÖåtЧU ¼ ûûyAç¤höëÁÅJÖc¥M”>e÷š»:ó©ëÍ?ÏÔ¿çâÏÿ_ÿŽSdûeÀT¸¸€Æ\¬P$©r\÷µ QE†QEQExO¿äyÕ¿ë¹þBŠ<}ÿ#έÿ]ÏòV„ž›ðÃþD¿ëîOé]¶“ª>™lÖÍlÓÆž3 #q,A Gryë\OÃùbÿ¯¹?¥touJbùÝÀÉXÑœêp*^ã,Í3ÜÝMs"…yˆ;AÎÐÏsX÷6:‚=ïö|xw*Ñ8]¹<éZqÈ’Æ$ƒ)èE:¤fEÎ4öw‰P<÷ 2]»x>ÿ‘çVÿ®çù (ñ÷ü:·ýw?ÈQZzoÃùbÿ¯¹?¥u5Ë|0ÿ‘/úû“úWSP÷)ãF©ü¨¢©ü¨Àþñü¨¢€ ïÊŒï7ýò(¢€ ï·ýò?ÆŒï·ýò?ÆŠ(Àþûß#ühÀþûß#üh¢€ ï·ýò?ÆŒï·ýò?ÆŠ(Àþûß#ühÀþûß#üh¢€ ï·ýò?ÆŒï·ýò?ÆŠJ0?¾ß÷Èÿ0?¾ß÷Èÿµm¦=Å´sÀžb†ÛäîÆ}÷ ˜h¬åüà?ÿeNÀgà}¿ï‘þ4`}¿ï‘þ5¡ýˆßóþ?ðÿ²¤:3ùøÿÙQ`(`}¿ï‘þ4`xÿß5%Õ³YÏfa(‘Y ·ǹõ¨d}‘³z @;ûÇò£ûÇò«çEpH7ã#Ž ÿ쩱[þÇþÿöTì~©ü¨ãÔþU¡ýˆßóþ?ðÿ² è­ÿ?ãÿÿû*,3è«ÇF~×ÀŸúáÿÙV|M¾5Z@x_¿äyÕ¿ë¹þBŠ<}ÿ#έÿ]ÏòV„ž›ðÃþD¿ëîOé]Mrß ?äA‹þ¾äþ•ÔÔ=ÊAER¢Š(¢Š(¢Š(¢Š(¢Š(¢Š( ô4PzmÅýÕ¶§‹WD’gŠ-ò&ð ðN2?_¸³{«kÄY碘ß4Èv¨Á<ûÓᲇQÑ­#˜Èª:´m´«œÔƒF³²Û˜äa3‘ÙÉvaÈ;ºä`bšñĬ `ítg04&UHMùÝÐŒb«\øÒÒmäÙÌÐùÅ^UB 2~fÈ<J¿“kFÈ’ŽF”;¹,ÎFÒIïÇÔÑí¢X„ q…J«E)RTÄÜdÓ/¥ÝÚ°9 Œ>„¥U¼8´”ú-O|âgn;ù“ÿ}GUµ>sè†ÑRÔ/?µ`ÓìÚ(¤™d•¥•KU `(#$–êü@të»K+·†YgeBÉ"«fÀ"2Kc§­Z¿Ó­ï¥V”H6&9br¬¹ë‚;¬4+12Ë›’Á‘›2’$(r¥½phØ|Px!d•£“xmÂ3óp:zŠe׊M”½ÝªÀ÷1$· ®3’Ç€}ªÊéj"_%ŠÄ$ ä|ÿ{>½i‹¢Û¢"¤·jc?»q9ÝÆ0¦;Pt]]õ+‹¹•ØÀ|¦‰XÉChsiõZцÎ+{‰.Ìß*¨‘‰Ý·¡>þõ™`san}PPÁ!ãïùuoúî¢Èó«×sü…b=7á‡üˆ1×ÜŸÒºšæ~Âóx5M¹R™‚úz×_ö ýbÿ¿Ëþ5/q¢µgìúÅÿ—ühûþ±ßåÿ› ­EYûþ±ßåÿ>Á?¬_÷ùÆ‹Zгö ýbÿ¿Ëþ4}‚X¿ïòÿµgìúÅÿ—ühûþ±ßåÿ,j*ÏØ'õ‹þÿ/øÑö ýbÿ¿Ëþ4X ÔUŸ°Oëýþ_ñ£ìúÅÿ—üh°¨«?`ŸÖ/ûü¿ãGØ'õ‹þÿ/øÑ`+QV~Á?¬_÷ùưOëýþ_ñ¢Àgµ£1f¶Œ“É8¤ûŸüûGùVØ'õ‹þÿ/øÑö ýbÿ¿Ëþ4ìÀÎûŸüûGùQö ?ùöò­°Oëýþ_ñ£ìúÅÿ—üh³”VðÁŸ&%MÝp:ÓÈ `=A«_`ŸÖ/ûü¿ãGØ'õ‹þÿ/øÑ`3¿³ìÿçÚ?ʰYÿÏ´•hý‚X¿ïòÿ`ŸÖ/ûü¿ãE˜ß`³ÿŸhÿ*>Ágÿ>ÑþU£ö ýbÿ¿Ëþ4}‚X¿ïòÿ`g}‚Ïþ}£üª~``8*ר'õ‡þÿ/øÑö À8x¿ïúÑf€xûþG[þ»Ÿä(£Ç¼øçVÿ®ÿÐQVIŸ©<–:¥Ý­¬²E sº¢,‡õªßn¼ÿŸ¹ÿïᢊ>Ýyÿ?sÿßÃGÛ¯?çîûøh¢€·^ÏÜÿ÷ðÑöëÏùûŸþþ( íןó÷?ýü4}ºóþ~çÿ¿†Š(ûuçüýÏÿ n¼ÿŸ¹ÿïᢊ>Ýyÿ?sÿßÃGÛ¯?çîûøh¢€·^ÏÜÿ÷ðÑöëÏùûŸþþ( íןó÷?ýü4}ºóþ~çÿ¿†Š(ûuçüýÏÿ n¼ÿŸ¹ÿïᢊ>Ýyÿ?sÿßÃGÛ¯?çîûøh¢€·^ÏÜÿ÷ðÑöëÏùûŸþþ( íןó÷?ýü4}ºóþ~çÿ¿†Š(ûuçüýÏÿ n¼ÿŸ¹ÿïᢊ>Ýyÿ?sÿßÃGÛ¯?çîûøh¢€·^ÏÜÿ÷ðÑöëÏùûŸþþ( ¿áö…¦ø€ê/ªÛ›–ˆÇ°´ŒÎìô#=QP÷ÿÙfotoxx-12.01.2/doc/images/slide-show.jpg0000644000175000017500000006562111701011016016434 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 268 341 1 2 2 ÿÛC     ÿÛC   ÿÀ U"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?úçàçÁo‡Z‡Á¯‡÷3ü>ðÅÅdž´Ç’æm ÎI^Y-bý칋®sõ¯-ø“ñãöQø3ãýWÂ(ð§†ìüA¥yh·OG*'™rÆD‘ÛÏ9c;}+è/ßòC~ÿس¥é u‰ðÖóIƒÅßÅ󨬧ÆP—0ùþÄÒ3Ó¿­xÑûIy—³÷çþ!~Í_´OˆµÀÞðÆ£¨éöBúéfðtV¢8üÑ?ymÏúÁëßÞ½_Xø?ð¯GÒîïîþøHÚÛEæH-ü5e'þÒª y§\~Ñ~]5íÁºöád#` ¼ÐúyçŠô­GQ¶ÑìeÔogŠÊÒÒ/6[‰ÕEµeV¥EfžåÆ ÞçÇðßàôžÿ„ƒþŸ®‡öQx5/ì;/+É=&ÿUSh¿ >ëz=¦­eðçÂocu¸äðÝ”fHL+Šò$ðõåö¦Þ4@Õ'øN×çPOB¹šI±»ûa-p~LfQgϘOŸä‡¯¦lu{MO·Ôì.¢¾±»‹Ï¶½†mÑMbzR©U-ÊPƒ{$x‡^ð¦—â ZÂ?„¿šKéíb–_ÛôŠ\Ï/J£ÿ w…?è‘|;ü|=oÿÆ«“ñÅÿ—ã¯ÇÿQk¿ýXo¯«™âF•CôNT“tÏCÿ„¿Â¿ôHþá;oÿÆ©á.ðÏý?‡øNÛÿñªó·Ò}»ØTÿjbÿçá×ý‰„ÿŸg£ÿÂiáú$ÿðžƒÿRÿÂgáú$ÿðžƒÿWšh ?´gý©ŒÿŸƒþÄÂϳÑÿá4ðÇý/‡_øNÁÿÆ©?á8ðÏý/‡_øNÁÿÆëÍ>Ü(ûu/íLgüüìL'üû=/þ ÿÑ"øuÿ„ìün™ÿ ׆?è‘|:ÿÂvþ5^göóGö£ûSÿ?û ÿ>ÏKÿ„óÃ?ôHþá=oÿƨÿ„óÃ?ôHþá;oÿÆ«Ì>ßGÛèþÔÆÏÃOì<üû=&oˆ~·†Y¥øKðÞ(£=?áƒÿUñoÁ§þi?ÃÑôðÌün¸¹ŽðˆätRþê¾ñ¿ø[á)5+ÇÐÿ{#tÓ õ¯ªÉê}~xг>7<£ ¶pT0ðÔù_Mø•ámaƒYü$øy02ùX‹Ã¶øÿÑU¿¥K©¬G¥Cð?Ài~ÐÍ;Cqá«x±gÿUWu§—Áÿµ8‡ÂZF’÷1Enðé„Åg Éö,dcÚºôtŒ^KÍfî}OTÒu?±õÍZ;¹,¥òäò¢œÿ­?…gZU=·³§V¬aAQ§:˜xëÄóïèöu•Ý×ÁŸ‡Ñ[j #ZÍ/† òä¿åžjmwÄ:g‡šÎ;ÿƒ_mò×ívë'‡­þx½?Õq]wƒ4ýü=àKkë-óÄ1èºÚé¶:›ÅäÜ_Çtþ\rñÛŸÖº;›MTø›®»g£·‰!ðu²YiRGÙ~ÕæÌ B7“ÿl|â1ß½bå‹”?Š\¾£ ÛêçÿÂÅðàÿšCðÜÿܽÿ­$Öí&¼°µ_ÞI¯ä1[ ü5n<ÉSþ®¹Ï‰W0ie‹FÑ Ò¼©­wésM’%ÇR|ï'Êü+Úü9K›i|‰#·Ärÿߪ­ÿ +çþiÃü' ÿãUèþ&_ø›\ðÖ±¯ØéZlMã íêH#û,76Ãv<ᑞƒ÷¼~´ë¸¼7¥øÏÁv^)Ðü1¥kz¼÷Zuþ¥$RD–ò’m.qŽ?|?Öã½k|_LAŠXk†Ôóñ/ÃßôH>á=ÿ¥ÿ…™áßú$ ¿ðžƒÿ×sñ‚ÛÁ^øoª]è‘isêmäxX1·„»·Ë=Ñ÷1äþóP¿#ÿ¯^^/ŒÃO“ÚžÆ .Àc æ°ö±ëŸð³ü;ÿDƒá¿þÐñªOøYþÿ¢Aðßÿ è?øÕy/ö¨þÜ=+“ûcÿ?Kûÿ>Ï[ÿ…¡áßú$ ðžƒÿQÿ CÿôH>ÿá=ÿ¯$û}EöÿaGöÆ3þ~ý€ÿŸg¯ÿÂÕðïý†ßøOAÿÆéŸðµ¼=ÿDƒá·þÐñªòO·Ô_o£ûcÿ?ûÿ>Ï`ÿ…«áïú$ ÿðžƒÿSámxwþ‰Ãü'`ÿãuä?o¨þßYlc?çà``?çÙëÿð·<=ÿDƒá·þ°ñª?ámh_ôGþá=ÿ¯ û}Eöÿ¥?íŒgüüì üû=«Mø©áÛÝVÖÖO„ ±,±Åÿ"ôÿí•}ƒ'À¿†ŠÌÃo ò/Yñªüæðæ¡ÿ&“ÿ_1èêýO$ËÜy?ö­{™^?‰öžÒ¡ñÙþ•5Jžÿðʯø+g„ü=àcáœZ†4+‹{÷•t:Ö²àËåÅÉ8ôÉÅsþ Oÿ!¿„ßõï©;Z+íð‹žŒdÿ­O‰­'´¹|ñ*ÇÁ¿ ~hÍ¥ëz櫨ø*ÎúÞÛH±,6°Z,²sß7°Šn­{áj«|Ôõ}@Œ=Ö£àËyå—œÿ­>äŸÆ²¾ÿÈÅðþÉ%çþ‡áúìµ/ÚÁZ'ŠõöóSµºÓï­t뻳¢Ý‹i*o<Ÿ&?õÐp&¯6ªµK¯ëS¦¦O‡ñ¢FzÇ‚ÿã]&«ãÏéÕüU.£ƃ£ÚÍw{yd<íÅ›.<¯Î¹SñïÂpøjmzëþ2ÁdŠÖ¨øgT¶{¦—ýP†ÞH|é±ÿL¨å¾¶#™£Áuï„)®ëú¦¦Ö^;µmBök£ü!Í(‹Í—'þ[VhøHè¾:÷&?ÿ%×Òú—Æÿ èÖZ=ÅÛë+s¬¤Ïc¤'‡¯ÛRu‹ývm&aÿ~E_Õ~)xgÃñxeõ=Pé§Ä ɧhE%·˜vO™þ§é75ÂðXw«¦zpͱ”Õ£Vßqò¿ü(¦ÿŸOÿáÿü—Mÿ… çÓÇ_øE¿ÿ%×ÙÐkw÷^ÛÍwZE&%ˆÒK­i¶º±žöÚ+µ‹Í0É'ïk/©a?çÙ·ö¶aÿ?¿|eÿ þ|uÿ„cÿò]/ü(Fÿž:ÿÂ1ÿù.¾½Õ|Wk¦Cn`R3M&;ibÄ+/ü¶?ôʪxCâG‡¼}á _hš­½î‡sn.ã$E iÿ–_J?³ðÿóè_Úù‡üþü’áŸüññ×þmÿÉtÃ?Ÿùãã¯ü"Ûÿ’ëê=[âî—§kqØZ[ˬ<š%Þ»ú|°ÉÑZ´"XGï¿Öþú¬x—â†á-WÃÚ]ÄÊú–·¨[i°ÚA,^lÈ:Ëj_Ùô?çØmfó÷ò>Uÿ†?óÃÇ_øF7ÿ%Ñÿ þ燎¿ðŒoþK¯´-5›+û™í­¯­ç¹´âX¡—÷±~5Ëx»âç‡ükk$÷±\C6­k£ÊÖ“E¶Îiü¶?òÊŸö~þ}û_0ÿŸ¿‘ò ýžÈÿ–;ÿÂ-ÿù.øg³ÿ<Ãû_0ÿŸß‘ñYýžÿéŽýÉoÿÉuü3\}íüuÿ„iÿäºû‚ ãœf)#›ËýÏî…OøÓXJ jbžgŽ«üJ·ù/ò>ÙÉ^ AãÏ$õŒx)¶þ_j¨×öi…"h–߯ëuAà–þk¯ºè§õ\/üûí£…þCOílüýüù Çû5Gb4‹ÇHƒøWÁLåöºd³¼A‚[xÝ 0_0È÷ÿJ¯»óFi}G ÿ>Çý­ÿŸ¿‚ÿ#á$ý˜¡Œåañº»r<ÃOøúéD³1#"CãtFûʾ `×ý*¾ìãÒŽ=(úŽþ}‹û[ÿ?þGÁñþÌPÄÁ’£Ú ø%Óþ>úTŸðÌÃÓÇøE¿ÿ%×ݹ¤¤ðG½1¬ß0[UüðŸü30ôñßþoÿÉtÃ3Oÿáÿü—_vséF¡£û?ÿ>Çý±™ÿÏïËüƒá˜Úñ×þïÿÉtÃ1µã¿ü"ÿ’ëï,CF¡£û?ÿ>Ãûc3ÿŸß—ùÿÃ1µã¯ü"ÿ’é?á—Ç÷¼uÿ„Cÿò]}çŠ1YgàÿçÐlfóûòÿ#àøeÁýïÿáÿü—Kÿ º?¿ã¿ü!ßÿ’ëïl0hþÏÁÿϰþØÌÿç÷åþGÁ?ðË£ûþ;ÿÂÿù.“þdÇ_øC¿ÿ%×Þø4bìüüûöÆgÿ?¿/ò>Ó¿f_ìÍJÖè7ަû4‘ʱ¾:×Õ}b~-H]˜|?ñÀÜIÇö3÷ükÐ0qM1û×u8|?ðÑÊÅâ1nøŠ—gå_ü³[ǶŸ¼C¡™®tý[E¹Ô­¤h‚f ÖÖH¿F¢¸oø(Pà_왑ÿ2%¿þ‘XQ_Q‡-5Òÿ™óµåwä~Š|'ÿ‘‹àý’KÏýÃõ«¤~ÏÚv£ñ/Çž#ñ<7:¦­¬Új–6X-Ù¬à€y¶q¿½„ÿ®ô¬¯„ÿò1|ÿ²Iyÿ¡ø~½óÒ¼ªîÕõÕô£ÍýtGË~"ý˜µÙ¾øNÊÎDÖ4­fóUÕ­,~ÆS3K?–æk¸&ŠcŸÁšýY<7û8êÞÖô(4Í$Ò„šv¬úΧow-Ú­¤£ÉŽxáŠxdÌÞOò¼þ¢¾ ÅW/¶è_²>}ðÏÂOÙþÎ>?ð%Üvw–sk¡Ù—µÅ –‚.¤†(a”ù¹>päS´¯†^ á¬Ú§à9uuŠkŠ[ÇŒ^!Ìö×&ÓÉ=1Œ×Ð?ãšC޽é{`öGÏøsñ7ÀúÆ‘â×kOk¿b¾Ò.ì5H‹›k½3Z/Û1ûé é1=sÇjë~)øKÄ)¹ðˆÿáÓ5GC¸žâûA¼¹‹Éýü2Âq,¹Œõì3^¡©ê6ºNŸu}{,pÚ[EæË4£ý\]…pðÒ? Î|{áâ:ä_ET«7Ðq£)ÿ€º÷…þ%hú•Ý–— ¶‹«êúŒ¾"‚Q%î¸/ þ\ÇŒþë΋©?ê1YºÇìï«ÞüuÔ|],rj¶Sêë6ÒÁc’ñÚC ÚÎd³šïÊ—ÉQˆfÆ%éÔŸPÿ†’øeÿC燿ð:*?á¤þ?á<ð÷þER«K±§±—òžGà¯Ù—ÄžðúhÓò9L< qØM]_„þߨþÎ7¿u¯Y¹¶Ó“LÆ‘/¬P<ó6?uœt—&»/øi?†C§JÙ˜ñžqɯ¥Õ‚0bèüݽ¨íÍCª/d|çû6~Ï¿Â-nîç[¸º»½·Ó[KS[› ðyÍ)†Hn|ÒF}$§“’zŒmöyñ¼i³hÚ]¯„WÄv¥¾™¨k˦Xn§žë2Ã&ŒîLRùÓ Híõ-Î}ê½·q{æYÿgÏéO’-Bñ>Ÿc©x‚K_ ßNÎÞÚòHM¬°®Ä*%_'þžN85›®~Ê>&¸‡Ãöšv¿hâÓ@²ûuûOóI¬éë3é²úb&ý±õf-Oµ²gðŸÁ÷ð™¦ê¬Hòßêmù‘ɦ3Î2k±Š2(ÍesT¬-™¥¤11F(Í-&(Å£4bŒQK@ Š1FhÍ£fŒÐŠ1KEQEQEQE&(Å-!é@ÿðPŸù!²oýˆ–ÿúEaEðPŸù!²oýˆ–ÿúEaE}Uƒæÿ6x³ßä¿#ôSá?üŒ_ÿì’^è~¯t]FÙ®¾Ê.c7CþX‰{^ðŸþF/€öI/?ô?×?〞"ñŽþ#ÿÂ;i†áñnyou¯ßIm4Ó]5´Å5¹P.¢À\M 'Ó¯>5uy¯ë«;é»Cú죿¶l>ÅöÏ·[}:Oæ~èý)ÃQ²–h¡Žâßí<Øáó:Wʾý›µ- ÃN¿mN4Õã¿¿ðN³y¥5¥ÞÛ)`EöKx yÍþ´fQÎ+v>%E~|9¤iò·ˆ,µøüV·pµÞcP¬šDö_ÜË'ÉÄǹ½” ö§Ñ¶zóÌ–×6Ó<_ëL2ª¬ +âN‡­ø£_Ðí§]ÞÎæêãΈ@c˜LaĽÿÔ×鲯³aá m3NM3šï…5½VÔôòÒ^]Ì ´Òù yý 9÷ªGö½¿Ò&ø§ÂZ·¼'á«Ïik?…4‹ˆ¢ñƒ4×WS £ýЄ€!~\WªxºÃVÒ?fBË_]:=jÛÂÍÚèИl£›Êçìàò9Çá_=üRñ.ŸàωõkÏÏ ÞÃàm M¼WÛþÕ™7š üª%/«Ó¨Ôÿ”ô°4¡^­5R?Íù#ë‚RÂUðÇCÔõýK¶×% èíì’8ãš9$Œœ{yx®ëþ½'þø p³]ý¦¡ðWÃWV6M§XÍòAjç>Dh“jçØb½W°¯ ÂJSÃÂsÜùüJpÄN »üÌŸøG4ŸúØà,uæ?´æ‰¦ZþÏ?¦‡N±“Cºt‘m#;”{µì¿Â+Ê?jù7_‰?ö/^ÿè£]3KÆ ó?ñïû‹ÿ¢ë3TÔç‹QµÓ4ûX.o§†k“ÉåEåÄaûZÊ´âÿQû‹ÿ¢ë]‚k?ØêÑÚ\Þ¤76¬,ãóe̳ZËÿ´|zøu=©|Zÿ´µ[]CO‡RÓìí–úSm_O˜!3Ïÿué†Î-SÕï¼X²}«Y^$ذhÿÖ€<ÿ+ù[mø«IÓ¹Ÿ´±ôWÛ-Gü½GÿhšöÚá‚K˜áž_õPË/úÊùWÀ_²÷ŒôÏh2ë·úmÖ!‚Ç[ˆO’ú~“,2hÿž’)›Ÿùx=+£ø½ð/Ä5ñ·ˆ¯lt;PmrßO‚ÇÄW·›n¼4ÐH|ç‚222ç‰Ñì©÷+˜úkMu5´76ó]CİùŸ½¬xïMøàÅ6ökVÆßTŽ ÏÝK3®áæûó^Cá¿€ZŽãË?Ã¥évz©ñ¶«©ÞêvïžM:â3"fÆXà¨òzq\6“ð_YK†¾kYaðý®‹ã‡ŽÞY¬¥³²InÑLq–cçÂaâõ¿ç…k Tö#ÚK¿ìañÊxQÒAzÚTšÃÎß꼨æòiúŸÄhº†…ö¯jàÛiçþXÉ(‡ÎÏ›ÿlkøŸàkÞ7Ôuï A¤Ü\\xFûDõ7Ý 7r´3Fe‡š*òï þξ&ðæ›asàÛ-rÞÃÅskpøcV—OBðϦ‹Iwù0 H›Íýþrk8S¦gÔŸÚv"Yâ7¶þt¼š/3ýQ¬‰|wáÃâ[>§êš…”·Öñ ÄD2Ÿ7ë-|Í쯪 {ÆÓkºn«â¼X•.l5-2ÎQo•¶›÷"èùcµÄÆ `rv> øOâ½Ä>ÖõÏ hZºéV×ú{Û[¥»i½äsCt8äw_”"šhs8ïÔןx·öIÔæ¹ð±’ï^ÓàÑ×K¼—Kº°†k}E¯òöú/µ[ÌT¼Ò–>Gïsä÷ŸeûV}S6¿¦B'2ê6ñyÊqö¸p É'Ép(öK¸{CÝè¤)k (¢Š(¢Š)JZCÒ€?ÿà¡?òBÿdßû-ÿôŠÂŠ?à¡?òBÿdßû-ÿôŠÂŠúª?Íþlñg¿É~Gè§Âù¾ÿÙ$¼ÿÐü?^ö:^ ðŸþF/€öI/?ô?׽ނ¾üEýug¥Gà×D.(Å-Êt ÖŽžÔ´”ÎxëÃÓø·Áî‰ÑÛÜêvRÚG4£þzE^gÃoˆ7ZV‘g©é 5·Óì!°[KG»¸—ˉ@Æd9ÇÆzó^ßš:Õ)T[³Üó]:oŒÚUŒvvp|6´¶€b8m¬ïâHÇ ˆ*ÏöÇÇ3Ïð÷þüjüURŸÇÞ1Õ<[âmÞ ´ÕmtI"¶žêãXŽØ·™— ¹¤u‹Yÿ’u¦áHŸüb½(}{·þ’yòžú¯Ì‡ûkã—üõø{ÿ€÷ÿüUsþ=Ð>0üGðn»áBçÀVÖzµ¤–SKþtqH1ëé]/öÇůú'z_þ‘ÿñŠ?¶>-Ñ;Òÿð¤ÿŒV¼¸Ñóa{~gt¨ÛH!ñs×­;“\ö¿Å¯ú':gþiÿÆ)µþ-Ñ9Ó?ð£Oþ1\ŸR®kõ˜åÁÿküZÿ¢s¦áFŸübí‹_ôNtÏü(ÓÿŒRúqýb™ÝâŒW ý¯ñkþ‰Î™ÿ…ñŠ?µþ-Ñ9Ó?ð£Oþ1OêUÃëÎòŠàÿµþ-Ñ9Ó?ð£Oþ1Gö¿Å¯ú':gþiÿÆ(ú•púÅ3¼ô¥ÜJíÉÛéž+‚þ×øµÿDçLÿÂ?øÅÚÿ¿èœéŸøQ§ÿ¥õáõŠgyIé\'ö¿Å¯ú':gþiÿÆ(þ×øµÿDçLÿÂ?øÅQ®X¦w”˜®û_â×ý3ÿ 4ÿãküZÿ¢s¦áFŸüb¨×¬S;ÏÊŠàÿµþ-Ñ9Ó?ð£Oþ1Gö¿Å¯ú':gþiÿÆ(úpúÅ3»Å/ÿª¸?í‹_ôNtÏü(ÓÿŒQý¯ñkþ‰Î™ÿ…ñŠ>£\>±Lï=(®û_â×ý3ÿ 4ÿãküZÿ¢s¦áFŸüb¨×¬S;δ˜ã«„þ×øµÿDçLÿÂ?øÅGý«ñkþ‰¾—ÿ…"ñŠR®X¦z(Ís¾ñL^:ð‡ÅÏO¹¹š3X{üaÿBÕ§þ Sü(ßãú¬ÿðbŸáG²«ÿ>ÞŸsvƒÒ°¼ßù–lÿð`¿áW´-R=oG²¾Ž?,L»„^Ôškq©'³?¿à¡?òBÿdßû-ÿôŠÂŠ?à¡òB¿dÏû-ÿôŠÂŠúš?Íþlñç¿É~Gè§Âù¾ÿÙ$¼ÿÐü?Zž#ý£WCñ•ÿ‡­ü â=vKMbßÃñÞYËd‘O¨\Y Ä÷óÃÀ†~¾õ—ðŸþF/€öI/?ô?סÿ£ðÜÚÜÚÃ-Ø»“]‡ÄîæÝ}²1i?ôËÉ„q^5k{EëVwÓø?®Èãí¿j-ox‹W²©¡i6úÍí¤‰ • ÝÜZïÖùÖSu¨|añúÒÞÛân™ †³¦?ƒíg’ãQŠ;I¤r"†R`´–_:Aûî¡úU­Wö^ðv­göt¼×4Èž´¹M>þ1öëy.Í×—?›#Κ^8ïÏ2&Ð×”ü:ø±â­NóLÔøccà¿^_é:®¯ô“]I¢›˜äÓ„³Í0W›œÿÓZ,>øwN±ðõœ]ùZ¯6·d Ý.¦ó²Çþ™~ún=é~íßêxÎû\é~ øeà ¿ ­Kį‡Nµ}-³ZCåFäù£ÎšÇ'ýDÎõô´ÞZÁ=¼‚Ki’)_úe^gkû>ø{K·Ñ#е sC} ±·¸°¼ç{7—ÍSb”˜zÓozõS’ËŸ¼‡&Š®=O#·ñ³ü5Ÿã§‰Äj/¥=•е3DŸè‹ÿ-OóÿÑñ¿í©xgÅ—~°ðœz…Üz®‡¥[Ës¨›h¥mDJÌßêú‘LsØŒUŸ xoLñ—‰~1ø{U€\iú‹Ù[Ý@{Å%šñúš¿¤þÎ~Òõ¿ŸQÖµ{÷¿Ó¯ç¿ÔïyÞâȶÜ|¾xæ¾–‡ðàysÜâuÚÄ®‰i¥h> ‚ïÅSYë“_Úˬ˜!²‹L’&’ <Ó3M4^Nb‡ ’ÞIÍsžý¬5'à ÒN…7Œµ|/¡_ëw¦æa{,×pÄH†måóeÁ2L#Ð÷¯YÕ¿g/ ëvëwº¶›"É~æïO¸Ž)ŒW¬êDêe1Dqùd¼ŒrZþÏš“&„t­wÄz iÚ]¦‘:iZ‘oí­Wl+q„ÈÀÝûȼ¢wœVÑË¥ÿÄ=Wö§¹Ó$K|)£h°^¥¥–¿p­2Í,ñ å‹ì€K/î1åp¼4ç"|e×|'àߌ>"ÔôhõC·ä¦i«›ˆdO²C,b9šÎ,ëÆÙpAäæ½†×Áú}¯µ'™ý­{a+Á2K"ñØæfý=ëÎtÙÆÊ×Mñ]–©âßø–ÓÅGv§m©Kd#’R±FfA ¬@1ŽÉéŽÞ€¾ÑÌø—ö—¼ð…Ž­§k··ñ|Z­–iai¬Isc*ÜÂÓÇ<×eÝX¡œÈ2ÿ©Âù¹â–£ûFëú×…- ð÷¦ÿ„’÷MÖu ¸.µcc´6A ²Á$O•º8r>ñ‡¥zw‰þxcÄÚ–¯w;j6zž§sköÛ;£ ¶ÓZDb†XbÏ®rk;Ä_´¿è66Wþ&ñ,ú¥µÍ™×>ÝÛ§·œæh¦+ËhîøòøÚ=ê%ðÈq:Ú׈> |?Õ5)Íx{O¹º¸“þ[I%¬FF#Üó]÷ðŠÃðχ,¼#áÍ#@ÒÓìúv•g´lûÝaŽ1|ž¼É­ÓÈâ´{£ðŽ¢“4f‘bÑIš3@ E&hÍ-™£4´RfŒÐÑIš3@ E&hÍ-W”f)ª|Ô2ª–†Œüý×À…Ÿö*é?úMlkÒù^/ðCÿÓüÿúGwY?Ï•ðá§ý‹gþÁV|k/“­øEÿê!?þ‘Ý×Çbçì¤êÝí#cȬjïIñ]ô9/|=-Ÿü&Oá¡¢‹ ¨¯RÎ.ÍáœÄÇþ˜ˆGÖ»¸¿iô½ˆIgà¿^Ku¯\xsHŽ9,÷jóAçý¡£ýöEöi¿×˜sõé€>h]šúmK^¹ÓîuS¯6†÷‘ÿf½ÙçÏÇ•æŸõ]å5r÷áW‡î¼?i¤E.©`ÖZ½æµmgyäÞÛÜÍ4Þ|Ñ:ΣûbŸ!_PcµŸÛ+Ã7‡.õ‹[òmôË‹¶³E‡Îi£½û¶c÷¿ë„ãòüªÔߵޑ/í|3a¤êšœ÷·’ZÛßEqg£ˆ¢‚I™4ñäÿ¥Â<‘ûÞEfEðgÁÈ<"§\Mÿ¥Ô·vm-Éó$’Q‰gºÿžÍæflúÖd|5´Eq®ÛxSJØdÒ¡¼ŽH®öÊf|’Å矘“û£SV³Švö|Χµw†êòÆ–9!d0çÎ-y^Iôô¯º¼Õ¿­YèRv‡õÙ¿Epcã¿¢h×pëuî¶¹±:–‘ui²ŸùcæËîæãýM`é´çÃýkÃšŽ·¥k¥Ziˬ¼—ú=塞ɿt'…e‡3DxÿS\žÈÛœõ¬ÑøW‰|Aý¢m| –¥—{r.-…ÁЮô»»]MË^ÃiæÇ ±p}À?ë«NÚ™}«.£-÷Ésogg¦Á¢jVó$ƒÎòͧ•摈³û®8§ìY>Ôõ£Ïj? ò}Wö—ð›g§^5þ¥qgg.¨·6ZMÔë¼sy3M1ŠEåKÿ=k¥Ðþ*è#ñ¦§á1î¯ïô´¯.­¬${ZHDÑù—Ÿê›÷Dtõ¥ì˜½©wVøcá/jrêZ—‡­.¯®R8仑¥ŒËTáLøùmïìŸüz»<ÚŒRöõ?œ~Îÿ cÀÿô,ÚÿßÙ?øõð¦<ÿBͯýý“ÿWgF¥kíêÏÀöP8ÏøSÿ¡f×þþÉÿǨÿ…1àúmïìŸüz»<J0=(öõ?çà{8gü)ÿгkÿdÿãÔ˜ð?ý 6¿÷öOþ=]ž¥”{zŸóð=œ3þ¿ÿèYµÿ¿’ñê?áKøþ…›_ûù'ÿ®ÏÒŒJ=½OùøÊÿ _Àßô,ÚÿßÉ?øíð¥ü ÿBͯýü“ÿŽ×géF¥Þ§üügŒÿ…/àoúmïäŸüvøRþÿ¡f×þþIÿÇk³Àô£ÒoSþ~³Æ—ð7ý 6¿÷òOþ;Gü)гkÿ$ÿãµÙàzQéG·©ÿ?ÙÀã?áKøþ…›_ûù'ÿ£þ¿¿èYµÿ¿’ñÚìð=(Àô£ÛÔÿŸìàqŸð¥ü ÿBͯýü“ÿŽÑÿ _Àßô,ÚÿßÉ?øívx”`zQíêÏÀöp8ÏøRþÿ¡f×þþIÿÇhÿ…/àoúmïäŸüv»<J0=(öõ?çà{8gü)гkÿ$ÿã´—ð7ý 6¿÷òOþ;]ž¥”{zŸóð=œ3þ¿¿èYµÿ¿’ñÚ?áKøþ…›_ûù'ÿ®ÏÒŒ =½OùøÎk ;]*ÊÞÒέlmcŠÚÞ(†!†ºQjº-žµdmïíb½„Œí_ïAËS÷¦©[c–ÿ…eá’yÒ"Ïýw–øV^Çü‚"ÿ¿Ò×Q»ÞÞõÏìhÿ!|Óîrÿð¬¼3ÿ@ˆ¿ïü´²ðÏý"ÿ¿Ò×Q»ÞŒûÒö?9§ÜåÿáXøg¾‘ýþ–ºX †Î(¡Š?-cÿUíO œV§ Ã#šs??à¡?òBÿdÏû-ÿôŠÂŠ?à¡?òBÿdßû-ÿôŠÂŠúú?Íþlñ§¿É~Gè§Âù¾ÿÙ$¼ÿÐü?[¾ ø /ˆ5O¼~)¸±ÑõíVÇ[»ÒãÓ„’»_²`Å7›‘ÿpõë á?üŒ_ÿì’^è~¯{¯»öuõÕž…%x?ë¢,óƒÁúW©t `zzÒö¡ì¼Àr2zûÑŠ¡¦kv:Å´“é÷1]ÛÇ$±<ÐÉææHŽ%ýjÿJÊÆÉÜ1F)h¤11F)kŸ_i ¤³Ü u†ÒYhb¡µºƒP·Šâ <Ø¥©¨Å¬ýGÄ:f›u­åí½¬ÒC4é ²ğ/õµfÖò BÖ+›I#šÖX¼è¥‹þZûÓ±7¹>(ÅR³Ôíožé-®cžKi¼‹˜á“ˆ¦ïWsHiÜ1F(Í aŠ1KYz—ˆ¬4©â‚æfyäÿ–PÃ,´ æž(Åei~ ±Õäòà™„ßóÊheеhbŒQš3@(Å-˜£F RÆ}JãMŠâ3¨A–{A'ïb‹°«Ù¢ÂNáŠ1KE JZ(¢Š(¢Š(0(=)iJüoÿ‚„ÿÉ ý“ìD·ÿÒ+ (ÿ‚„ÿÉ ý“ìD·ÿÒ+ +ê¨ü7ù³Åžÿ%ù¢Ÿ ÿäbøÿd’óÿCðý{¦£Í…×ýs¯ øOÿ#À?û$—Ÿú‡ëß|þ/ø‹úêÏJ_ë¢0<1âH ð¾‹ÝFXÚG/ê§x3l¾ê„Ñþ7“ëVßCÒ%“Ì}&Æy½M¬5¤ª¨…ByqÇÅs^oø†©XøßÄŸE±ø—ã  kZç‡|O¯x×DÐ,´ÝrþêëH†)Þx®‰Ôôø±èžp0®€3Î+±ø⯈Þ'ñÐÓ¹®išÞ£¥Ûj:¾šÌÖ—eìÜŒ§¨Îhöªàé³Âü1âOxãŧ„µo]xе„PËk¦¼J,Ým’{¸Œo—< ·›Ç$ÜÍ}Ô篽?ÎǰÈå?ºOÊU*\¨«s^ñV~ðŰ¹Œ,ZUœRb_ú`+¥ÅQ“CÓ%É&•e4Þ¦ÖÖ>Ò¥?á–ÒoS7Ár 49ø$Ô¯åAõÔg?Ö¼Y×¼mc x§_ºñ7ˆ¬lÿá1m*éíìá•4}$M.-áò|Ñž?ç·^µôò*¢m åÇñ+©{^ÏJªr×Re4>@7úç‹u=úökÝ^Öm;ÅúN…ªÜéûn5(>χv"à•‚lÏo$šëõ-{Çzì÷¢jzݦ„4Mú}œÓjÚ|x‚+Ù„}%òaó¥ÿs_Hù®KìKc'=~´†F/¸±-×vy­}ª#Ù3ãox‚çCÓõûÍ?ÇzÚxVñé§RÊnZÔiçÉ1`Ï ùâ@«¯Ž¾1ÜxsÃ6–÷ë®xÂÎ{]&îæÂ~É%®¤f73Ãå~äϧ.p+ì3<¥Ã™x ¸æÈçvXüÝyëG¶dÏ‘bñ_Ĉ6Ñkø“Ä>´Ö4]ÄúuŒ66Š-¼‡²†Æ ¼èNJ¿›?Özú{Ázäž$ðW‡µ{¨„ºŽ›kws9Í,>qú+pÌä’]‰'$ç½4’Ä’rOsIÕ¸Õ'q+›ƒUIñ¦½+Ìtí8Fdôóo8®–ª^é¶—Ëþ•gmv#è&‡Îþu’ÐѤՙ&«¯ã]-’d¸i—âO/þ»Ù×ñQõÛï|=ÐtÍ{Uðæ©\^½ýΔ°¼Ì‘Zyª?{ ÝÎ+Òì´ûkÙkioh²rD1y?ʬ!H€zZÿ—• åì|c§üIøËuwãkí‹TÕ4û{ç¿ðÁâïMŠ9Ï“s§Øð1yÓùùÎMoÁâ=Nø³ x–Óâ‰üA¥¶…skc¨²³k7"xfþÏ$Yr=‡ï½ëë/9öªïm£3À§©¹>k’FÌy­½ª#Ù3â¿üIñï ¼Ó-¼WªA¦\ë~Hµ i-o/lâ¹{³wö³†(æÌ0îˆB<ŠÖñ'ÄÏh>Ó­üMãM_Âú•÷ˆ,%ñTv‰ï.md…tاcŠ5~Ðp!ÿ–q_^µÌ­ÖGî|ï;&®xÓã/Š'W¶ždÒ4Âó\xzÛLˆIv÷2iÒÝùSÌ'ó¢—ÿ©¾~keKÜç#ÚùRÑï_%x«ãÿˆ<àOK¤ø–ÏÆºÍ®‹µ¨˜ô –ÒÚŸ$ òý³>¸ÿ×ì´/о5¹ø÷šuφïü_ªø^6-6H.`X#i`—Ïó?/üñïJTƒÚŸAÒW‘þË:®©¬üð]ö­âˆ¼W¨K¥[n¼¼Ì„Û‚a—ÍçMê{ó^»Þ•J~Îc¤î´QY…cIâÍ96>±c‘ú]E[5Îøêð/†ÛÂì4›/2Qê2^æüRÇ4[ãs,RËX¸§u®wÁaËåà/öލSêuëæ/Œß#Ñì!Õ<&Úĺöx·‡[»?bXÝqyÓ3óÿ\k§Ùy‘íO¯óFkåÏ|Hñ'ÃÏüAñ4þ†×Ä–žÓ4d¿û\ §Pž3Ï>I?¥b»xËã'~èÞ3þȂΠÝRòÙîlཱིÕ+Xd…¦³Šîe?ßšÏÙµ>½4w¯ý—u}gYøOowªxž_ù²"£G›»ó%Ì3Ïæþüç¿îztí^ÉÞ¦¢±¢w¨ê:ÍŽ˜b·¶Öžgüö—Ê«ÕÏØÍx×_gDršvœ¼~iÿYyëY nÆž«Ùjk›+Ë{±üñ“Í«˜¬)¦‰ük¥áDÆ™~¤~_ü·³¯3ý¡>)x—ÀמÒ|/o»Ö¦ž¾šdŽ! >hÿ_4úÿËjv¸®{G›üô¥ü+ãq¬jš¥öµâKX´zOx*}Fʨ®!·ŒdÅ/0ŽÙôéée>8x—F¼ñ ¦›«xW¶ztÞ%ÕäƒP°’oí·Õg€DÄÎ<Ÿ;©Ç5Óìˆö§×ÿ……|Ѭ~о/𾥪ßêÖ1-­Æ€ú¶áË[PòÝIö¹ žo7Ί`N?ÔŽëµýž¼uãoØj3x¶ ´)iuc©X›O߉ïãò »œ Àg‘œg—²j{- éKX›Q@Q@Q@Q@!éKHzPãü'þH_ì›ÿb%¿þ‘XQGü'þH_ì›ÿb%¿þ‘XQ_UGàù¿Íž,÷ù/ÈýøOÿ#À?û$—Ÿú‡ëßxÂù¾ÿÙ$¼ÿÐü?^ø:WÏâÿˆ¿®¬ô¨uþº#þ­þÍÏýs¸š¶!‚ (b‚„QÄ1#€j“¥®S{¿ØšiVÿ‰u¡.;ýšÞù‡÷ƒþÛf›gáÇW“VµÑô»}VXþÍ%íµŒK;Åœù&n¤gœV¥'Zw'•ê|=ð“,*ÞðøŽÖ_:†—-æÿžËû®½k>É$óÎ×ÌŽ?þ=âÏ›×Ìÿ®¾õvŒÓ»TPÓtm?D?Ùúm•€žO6çì–ÐÂ$—þ{Mަ¯ _Oj) +QH ¬!à­¾œ‘Ÿúeq-nÒq@­r;H ³‚+xbÅB+&ך“jo iV³_œß´z|"K²?ç¶?×MmRÓ®Q“H±¸y^k Y$yL²™ ‹ýiŒFÒþ1 eƤßÉg%Ö“§Ý½„že¡žÖ)·òÈŸõU¡KÖ‹²yQV[Igó嶆K’GæIï¶Kÿ,óù~UKGð¶‡áØ£LÑt½!¤tV1@"ËÀ÷<Öµ]•,t]?Ižúk=6ÒÂæú_6åí-¢†[©qÖoùì}êý´V ËÔô ;T’)o-y"é3ÉåsZy¥éH£3KÐôý$–²µKw=eGó3NÖ4=3Ä6&ÏVÓ¬õm>aÍž£mП¨—­hg=óKMÕÌ£ i^XC£Ø˜ö%·’lâÇ–Ÿê¡ú{V=×Âÿ ê>,¶ñÎ…§]j–цtÑt}?IIäó]tëX¡ó¥õ>WSîkRœõ¥v¨JZ(¤XQEQEQEQER”´‡¥~7ÿÁBä…þÉ¿ö"[ÿé…ÁBä…þÉ¿ö"[ÿé…õT~›üÙâÏ’üÑO„ÿò1|ÿ²Iyÿ¡ø~½ÓRýÕ…Ô‘÷޼/á?üŒ_ÿì’^è~¯z”y©²Nµóø¿â/ë«=*=®ˆæÕ/&_6/ÞÅ.&³uOµ{*ÇSðµÕ¦— ¶vq–‘É eÌóyÀâ^8®›ÓÜÀàWöŠÖßâ\ÞÓ¼ ¬kú-Ž¡s¨i¶RKæ=¤2ù䘼…‹÷Ðñ4ÙÇ5[ÄŸ5Ý7âÖš_…®­5Kû=,|I©"·’îþö3çCäÿ¨ÿ\:×°'ï §Œ‰ãÒ¢‡\ÊÆ×èòÄÒìŒÅûÈÆ"—©íÞ­_xú¾¼šÅÞisªÆmLwsŒb’i!ÿȳMùÕsÓYr™_ |osãï ɨ_ØÅ¦j6Z•Þ•ymždFhg0Ÿ*_N+´+7FÑ4ÏÛÏ›e ½ÔòßN!ãÍ’^f˜ýkKëÖ¹Ñ1h¢ŠE cšù§Uñ½ÜÖÚO„¼?ðõ.´†8à‚ÿRŠâ$0ÞEéQ'5ð›„~1<f‹Âp%Ì©<Ö÷7v: DDW“B8¯%Ô¿iÙt9uد4þÝáÁ®Ýk–pÝþöÖËOŒInùîfóàÿ¿Æ½ÖÂÎßM³† p`vâ²ãð_‡ÓYÖ5¤Ò,WUÕb†×S»þúêÞíŠcí“ùÖ´ÚêbÓ<#Jý¡|w¬H_æjú¾©m§ZÏ«.£§iÒ ,¦±$Öp±–±ã÷#ò¨õÚ¿]“Eðäº&Öu­CM½½º°Š+Ë·Covm%†ig(À˜™ŒXÇ8Î+Ù´„¾ð„:lZf‡´z}Ó]ÛÆ÷Èmä0Ë 1eýÏîe˜`c©¨5?ƒ¾ Õôë ¿ Û›}=¤{1’E%¼’KæË‰c—Íýì¼þ×g´¦cï­#Ó¾+ø²{]GRÖÐ þ{m"ÁZê{ FÔI4 G§s4sÜÈYÊM,ꥩót:*–™ðSÀz%­Ì:†m-â»hÑg–HÁŠO2+2þç’qO=1ûÌwÂ^øïJ×£Õ¬-tígAÖ'ÑoⳜ¼^dQE/‡‘˜¦‹¯¥w˜¬Ý7FÓôFÔMœ6tuß$c͘Çåùß_ÝCZu›³ØÞp¯(øã?ÁÚž««jÞ¹ñV—go§.Þ1´Kve˜gþ¹CŸÂ½\šÇ¿ðí¶§uö´\ÚÍ$~\†Îb<ȿ̵„´4_ß<ÓàýïˆuMqµ]WJ²ðÖŸ«ÙÜÜéú%¤\G m†Iˆêq1üë£ø‘ã­þ&ð†áÍ+N½¾×¦¸…›TºžÚ(¼˜|ì&««Ó|;oav÷ 5åÌá<µk¹¼ï.Ÿ}¢é—úž©\YÅ.¥`Ò›+‚?Ô‰¿uNšÒçøOŸ¯?kI4ýoĶñè¶úÍ…®™s£ê6Fí ¼ } ˜Îš¢?½šõp÷éPZ|Wñ‡‚µßˆí¯>þ!ž›§éúTDÍæùÑ$[þìæò9Ÿ†5ߊ(Ò-ôÿéÖZTž°×õIno¥ûM»\I<~LQyX}þ[µ{N1\ÿ‡üáïʯ¢éi®¶pi‘½ºH¿è°É,–ðàtY¦üë ¨©ìúREV&ÁEPEPEPEPHzRÒ”øßÿ ÿ’û&ÿ؉oÿ¤VQÿ ÿ’û&ÿ؉oÿ¤VWÕQø>oóg‹=þKò?E>ÿÈÅðþÉ%çþ‡áú÷ÁÒ¼á?üŒ_ÿì’^è~¯t¼—ɵšXÿåœ|WÏâÿˆ¿®¬ô¨uþº"ÏZ+˜Ðô+ ý I¹¹¼Ôþ×qk ’”Õ'2ËÉàÕ¯ _5öŒÆwy;Û«c$¿óÎ+É¢‡ôˆW=yÌp\R׋ÉûC—:‡Øü¬^m×gðÞ˜c¹´Î«}á²3çbùOïfçô®gŵMZý%Ñ^ãC[ ø®}CO¸Ž!-¶£`¶Kä&5¯±9ôoáGá^;¨ü|±ð§ì®nlïõÿCc¤}¢ÂÚÜ@’Ïyäà óæÄ?ëfÏúãøÕ+oŽ×¶>+Ö|<<=«k&}J <:%³ ¦ ɱ/›Œžf积 ÙíOo¢¾d‡ö¢Ô&ñ >%ÃúÁ±k·v°ÉheÓÂ_ϲÊ<ïßÜÿË+Ôþü@×ü]ãßi4k¡hzŒ–Ä3FL›ôû;£ °ù¾o›ûî´ý•D/lzM‚–±7p}é¬v_<ë?ôk; N·×|AñòÖÒhôÅ¿¼† ‰e·ó·Ÿõ=h”¹ Tå'hDfé\÷€õ ÍCÃV¯©cíÐÜÝÚJ‚C >UÜÑ­úD+‚°ý -5Ùè6¾Ô›HºÕçÐSÄ&H>Îo¡ˆË,{DÞv ¯¡¢ Ô2æ=xQšð ïÚ²ÛGøO¢|AÕ|1>•£jª·6êZ¾Ÿk=ÌC bó&äàÿ¨¾éiKŸ'ÄgÄ?üR>¿²‚ËX†h 3}¦ÒÊha”K7úÑ-éùîqï[{Gµ=ö–¼ûàçÅ+ã?†/5m,,)a6›ãP¶ºÔ¡.¬EÙ6ŽcŠ(¢AÚo*Eu{¤ÿžþÿEFé?ç‡þFŠiP,IEG™ç€ÿ¿±Q™ç€ÿ¿±VF¼Âí5ÉÚx¬ÉíuR­ij,íä’ÊeŽÿ,|ßJêó'üð÷ú*3/üð÷ú*\í;´. &ÈY£¼Š#»ÍÉ’Ieóf?‰”×’iß³´|\‡ÅòxÓH´Ô§Õm¼=k ¢¹ž/$Ïþº½£2ÿÏü‹ËÿãþþÅ@ùúÄÔ¼7%Þ«%ý¶ tû™"Ž'+šdòüß+ÿFË[—þxûû—þxûû MÜÇÒü?%Ž ·—ƒj¤RÁh¼¯(Ja?ûF¹O‰?tÿ‹æ—.»?ŸáëKBÚm&(°÷_k‹Ê$Ëÿ\|Ñø×¡æ_ùáÿ‘b£2Ÿùw÷ö*kA3ÌgýŸ|%¡_éz¬º·ˆ£½Ômu›»ËûÂ×qlrÄÅèaÏò©ÏÀ G¦ëº~>«¡ÛøƒUŸUÕM»Ún^rwFÆH¹‹ýoîzOG-!ÿ–þþÅFdÿžþþÅZ'PÎÊ÷¹KEÑl¼7£iºV™ZéÚ}´6¶–È0© # ÑÆ*=ÒÿÏÿb£2ÿÏÿb¬SH’Š2ÿϸÿ¿±Q™çÜߨ¨2$¢£Ì¿óÀߨ¨Ì¿óî?ïìT2$¢£Ì¿óÀߨ¨Ì¿óÀߨ¨bJ*<Ëÿ<ýýŠŒËÿ>ãþþÅEƒ™QQæ_ùà?ïìTf_ù÷÷ö*™R•eÿžþþÅK™?¹ÿ‘b .~9ÁBä…þÉ¿ö"[ÿé…ÁBä…þÉŸö"[ÿé…õ4~›üÙãÏ’üÑO„ÿò1|ÿ²Iyÿ¡ø~½ìtàŸ ÿäbøÿd’óÿCðý{Øè+çñÄ_×VzT~ýtBâŒRÑ\§@˜£´PbŒRÑ@Q@Q@ Š1KE&)h¢€b–Š(¢Š(¢ŠLQŠZ(¢Š(1F)h çýÔ{ë²ñ›^ÛAqi k—6²4W)hrÄFG­ÍK›+¯úç^Gyñ¾ïះ~è:5†¡}­x|ÎÿZM:b´´ä>d‘ÿ®†1“ŽqT’©?fÌê¶£¡è¿ð–^гâü_ñ£þËÏúuÿü_ñ®CÂ?µ‡‚¼U£Y]ÎÚ–$Ú3ëw‹.™töÚuš q4÷qÄa?q/üµö­[Ú_Àš†…¨ë+ªÞ@–r[Ã=•Þ™wþùÎ-Ö+9aÊfëŽ/Þ`סõ89Ëíßò_ð–^гâüãGü%—Ÿô,øƒÿøÖE×í+àm;SÓôë½FþÎöÿÉ";­þ!kçÊao ËC,þQª’~Õ¿ eMUßÄ/ZtrÌÓOcw7Ç7‘!‚C—wûïÝ£ù¾Çš>§æo?ä7eñÙb2^hÚ¾h£2ÝÝÚãðÒ௨85ä|eÿ…¯à¿‰Æ+)­,ômI4Ëc}cyi3 fxeŠb9›¥zó¶$ú1ëõ®:TçÈŽªmÎ:œôž/[‰ä[M#TÕ ILO=•˜xLƒ©æ—þËÃÿ2ψ?ðs2|X·øaðïí†ÂãVÔ/uû­;OÓ-¸’âê[Çò£Ïn¼ŸjÒ¹øß/‚ü?ý©ñB¹ð²‰ÌMý·åºD?嬳ÛÁˆAÿ¦µ½ =:çç2IÓŸ'!«ÿ eçý > ÿÀþ4ÂYyÿBψ?ðgÚ;Á2øÕ<0Ú¥Ëj¯sŸ»û.ëì?i’q va¤ˆƒåù§§¯X$ý¥<¶­zú¥ô–ZuÉ´–ößH»’ÖYüÿ$Co ‡eÄÞnG•›%kõH9Ÿ·Ÿòð–]ù–|Aÿ€#ük[KÔ-õkoläó¡˜dÐ×àŽÖ~;ø¢ºÝèm¡½÷ÚfŠHgŠê+³ÐÍ ƒÌƒé.+cá¯Ñ¿í§þ–¸ñÕ9ÂÆ´ê9î~KÁBä…þÉ¿ö"[ÿé…ÁB?ä…~ÉŸö"[ÿé…ô”~›üÙæÏ’üÑO„ÿò1|ÿ²Iyÿ¡ø~½ìtàŸ ÿäbøÿd’óÿCðý{Øè+çñÄ_×VzT~ýtC¨¤Í®S Z)3Fhh¤Í ¢“4f€ŠLÑšZ)3Fhh¤Í ¢“4f€ŠLÑšZ)3Fhh¤Í ¢“4f€Ñš   ÚˆÿAºÿ®uâ6?´GðÏ^Õ`·ÔàÐ4 ‰§]ØCw Ïi yçþ¸×»k•ÿ…i íc¿Ž!ü ª]ÅåçWhWœá:f´åùxŽÅ ôï]øíu+Ë•ÓüW [è66éå}š<à%‡þÿW9wðPÕdÔµ­[Æ·Þ<–]6kMqtˆb†Ù¬%šXBÚy¿¼¿ŸÎýñûÇýM{'ü+MÓRÿÁÅßÿ£þ®‰é©àâïÿV 8åÿ/ n‹Ù1}ð=gÇ â­oQÑõ}BímSXŠÿÃîéxÑIûŸ²Ænñ퉄õ“¥~ÌZN•§ÞX®©‰ K£jvºP]JÂU»ûX>y›Ê˜ùÑg>L5ïãᮄ?ƒRÿÁÍßÿ£þ®…ýÝOÿ7üz§—üá|?ò³Ë¬¼'©xSž7ŸY×áñ&­¯_G¨^Ý[é¿`†3PÃÄ>lÜ~æ½ÝÆdÏûGù×5ÃÍÞXåTºg‹î¥Ö¥uÿÃ}¯ò%~_ÃÙ~6ÿϧ„ÿðY'ÿ£þËñ·þ}<'ÿ‚É?øõcÉßü^y÷ü?àŸ¨?ð¾¼?ÿ@Oá¾×¿ùø_^ÿ '¿ðßkßü‰_—ßðö_¿óéá?üIÿǨÿ‡²ümÿŸO ÿà²Oþ=G${~?ðž}ÿø'êü/¯ÿÐÇßøoµïþD£þׇÿè ãïü7Ú÷ÿ"Wå÷ü=—ãoüúxOÿ’ñê?áì¿çÓÂø,“ÿQÉßüçŸÃþ úƒÿ ëÃÿôñ÷þí{ÿ‘(ÿ…õáÿúxûÿ ö½ÿÈ•ù}ÿeøÛÿ>žÿÁdŸüzø{/ÆßùôðŸþ $ÿãÔrG·ãÿ9çßðÿ‚~ ÿÂúðÿý<}ÿ†û^ÿäJ?á}xþ€ž>ÿÃ}¯ò%~_ÃÙ~6ÿϧ„ÿðY'ÿ£þËñ·þ}<'ÿ‚É?øõ‘íøÿÀy÷ü?àŸ¨?ð¾¼?ÿ@Oá¾×¿ùø_^ÿ '¿ðßkßü‰_—ßðö_¿óéá?üIÿǨÿ‡²ümÿŸO ÿà²Oþ=G${~?ðž}ÿø'êü/¯ÿÐÇßøoµïþD£þׇÿè ãïü7Ú÷ÿ"Wå÷ü=—ãoüúxOÿ’ñê?áì¿çÓÂø,“ÿQÉßüçŸÃþ úƒÿ ëÃÿôñ÷þí{ÿ‘(ÿ…õáÿúxûÿ ö½ÿÈ•ù}ÿeøÛÿ>žÿÁdŸüzø{/ÆßùôðŸþ $ÿãÔrG·ãÿ9çßðÿ‚~ ÿÂúðÿý<}ÿ†û^ÿäJ?á}xþ€ž>ÿÃ}¯ò%~_ÃÙ~6ÿϧ„ÿðY'ÿ£þËñ·þ}<'ÿ‚É?øõ‘íøÿÀy÷ü?àŸ¨?ð¾¼?ÿ@Oá¾×¿ùø_^ÿ '¿ðßkßü‰_—ßðö_¿óéá?üIÿǨÿ‡²ümÿŸO ÿà²Oþ=G${~?ðž}ÿø'êü/¯ÿÐÇßøoµïþD£þׇÿè ãïü7Ú÷ÿ"Wå÷ü=—ãoüúxOÿ’ñê?áì¿çÓÂø,“ÿQÉßüçŸÃþ úƒÿ ëÃÿôñ÷þí{ÿ‘(ÿ…õáÿúxûÿ ö½ÿÈ•ù}ÿeøÛÿ>žÿÁdŸüzø{/ÆßùôðŸþ $ÿãÔrG·ãÿ9çßðÿ‚~ ÿÂúðÿý<}ÿ†û^ÿäJ?á}xþ€ž>ÿÃ}¯ò%~_ÃÙ~6ÿϧ„ÿðY'ÿ£þËñ·þ}<'ÿ‚É?øõ‘íøÿÀy÷ü?àŸ¨?ð¾¼?ÿ@Oá¾×¿ùø_>ÿ '¿ðÞëßü‰_—ßðö_¿óéá?üIÿǨÿ‡²ümÿŸO ÿà²Oþ=G${~?ðž}ÿø'êü/¯ÿÐÇßøouïþD£þׇÿè ãïü7Ú÷ÿ"Wå÷ü=—ãoüúxOÿ’ñê?áì¿çÓÂø,“ÿQÉßüçŸÃþ úƒÿ ëÃÿôñ÷þí{ÿ‘(ÿ…õáÿúxûÿ ö½ÿÈ•ù}ÿeøÛÿ>žÿÁdŸüzø{/ÆßùôðŸþ $ÿãÔrG·ãÿ9çßðÿ‚~ ÿÂúðÿý<}ÿ†û^ÿäJ?á}xþ€ž>ÿÃ{¯ò%~_ÃÙ~6ÿϧ„ÿðY'ÿ£þËñ·þ}<'ÿ‚É?øõ‘íøÿÀ<ûþðOÔø_^ÿ '¿ðßkßü‰Gü/¯ÿÐÇßøoµïþD¯Ëïø{/ÆßùôðŸþ $ÿãÔÃÙ~6ÿϧ„ÿðY'ÿ£’=¿øçŸÃþ úƒÿ ëÃÿôñ÷þí{ÿ‘(ÿ…õáÿúxûÿ î½ÿÈ•ù}ÿeøÛÿ>žÿÁdŸüzø{/ÆßùôðŸþ $ÿãÔrG·ãÿ9çßðÿ‚~šßü|Òˆ,¼=ãÖ¹”ùFâo‡Ú÷•ý4ÇÙ+Ÿt£Uð׎äq ߀5â&—þ&"×”?óÇüΓÿføÚüzxOÿrñêOø{7ÆßùôðŸþ $ÿãÕ¥ôüà 3Ÿëï.ÿÁI4«¿ ü'ý˜´Í^Ê[}BÃÂ+csk3ys[Ϧž²G"Ž„?Z+ÀÿiÿÚ§Åÿ´¿ü#7ž2´Ò ºP¹ŽØiöòB¡_Ê-‘æýÁúÑ^å ^šrß_Ì⪟=——äÿÙfotoxx-12.01.2/doc/images/translate.jpg0000644000175000017500000013255711701011016016356 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿífPhotoshop 3.08BIMJ>resize sharp pixedit resize sharp pixedit trim resize sharpen ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 460 668 1 2 2 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀÌœ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ÃU'$·Z‚xðÝsInds’Õ`üU–æeDG娌’¬˜-ǵh4WåÁ5M—socFø,7Q«c ëSB¸f…·ÉÜ)X|ijݙQpëU¾mà>µn;p£$®)Æß$èj†Úd ÇSÅ&åcÚ³ Içq$SZÑ4—(¿)*8¦Þä þ5ZU"SN…¶Ê=ê¬>‚»±cS&dŒ`üíC(ßz!%džzÑaô'å¸&*zafã½+Åg³èa|jÛ<+%QžÕžß4‰‘ßšèÖÚÈE‘€ÝÞ©î8™Ë ]£0æ®j± 3l¹ÀëëZVúe”—e2¬¸ãNî [mÊBjJ*ÙÝOn,çpضX®JžÞÙZ(÷ëTõ¸I Q@úÁæF¦‘Hì3ƒU‘ZYÚBI БTᔼ£q}½ëv›uBÆp8Y†æD‘»MËÓŠÔS½“´qŒf£- ÅÁÝŒS[K¶šá•W8è)48» £ÝAæåÉàâ“[¿¶¸µ(§jõ®‰§7½Ì`V¬jÖÖÔo$oŸîœÐ·{ Ь!½º òóÅK}¶ÒY2DZ«>¶ÞI†n…[¡ì$›RÇvïzwÔKcœ‘®w™0ö*kEœþðç®sZúͰ°Œ!SÏB*kšK-€7¨¥{“d1Å5Ã('ƒÜšmÕª-äqìÝÀèqUd3Ú^9{ÓíËyÍ4›‰= 4ÉE‰à%V@6Ÿ~•z8€ `¤uªÑÆ'„ƒ€@Èç½VºÕLH°ùgxàœÐ•Áé¨FØÕ$uMÀ6>~Õ>§#²¤’2î^н* VHÙ¤8fõ© ° ªÈ¤ã¸ /rKf{˜ ÂLl£œUYã‘mçyôË5Mfÿgf‰Ç>¹¨/eó™`Bp[šiaÐ@é •€}*% ×Î[óÍ[{MŠ¿; ™ªóÂdÈÈ4!2ð(Ѱ ñYq[5ÍÃ1c±MYÔ †Ûägò§Z –€9äæ“L…× ³Q^’ddu«Û´‹Ô‡ìé¤Ù ØÒO¸Xt1‚Ø>”Û‹†lqätÀªp^ç÷r3϶mîl|¬ 26:R“ìTQg!`wǵ‡½TÔ.Y¿sù›¸rí_sH±lP8”bi%ºŸgÝ…¨1ñÄÖöB2r*­¥ôÖ¹E‘‚“ØTó_}©ÈäõÄ@Gæ(¯Z¥¡,ž;— æ)ÉîJ؃YŽ;|¼ Ha«JI9ÉÇ8$q˜ˆïS£z‚}‹—zÇÚ#ƒgךŽgšeŒàdäâ¬Ã ŠKÓÖªÁ™nÞBÃåàRVC¹t¯îü³÷p:ÀºÜ›Vfݦ¹]¼žj rBÈŒC/¿"ˆîMšÔßûŠG˜á‡lŠÐKr™`GÐ×1§xÊ™˜ŽÄP×—N›;€;)è‹WhÛÔ,! sj£†Ýp\ŸÖ³"¸&Òò7~jÄÏ0“°“×&‹¤RMêww*[#ü¹É«­•„"Å`[´’Îó(çµXN®q#>µW¹6±>Öµ˜9#ž•²md1¬ÈVA¬‡2KÆÁrj}.í­æX'c³=ÏjdÞ̵$„.Ò9ý G8ëŒWQiþXg)|Tw/¥6^<ž˜¨l³1ö”ÄŽ* ìÌRî]ÁÇåVO6× ¨+6ûV‘»³#c€E4ÀÏ¿y./V ÇnyŠ»çÉh›mî  ãnxªš|207/Ë?9«OõåAü(oRF,ò]ó]˜þ•X¡¶‘\Pž=ªÄA¡}˸{Sä"Xʰê(¸jÇ5ꊫ ö¦Z^ÈA9¦EQD_0Æàdt=Í?Ê00 ¶jl¹oY9µÓŽ1”¹ÿÐV½7§¼ÃVɱÓIë²èÿã«^¡ZGbX”´QT ¢Š(¢Š(ÄÌ Õ™Ëd¶ib·gæ•­È=k"4²8Ò’F8ÀÍ,n©Ãr*|FÄr*y¬_*èV·‰ó’¼ÓvŒ‘DR¢¸ŠŠîå‰Ú‡ò«]È{–÷·8Å8íÅaY¯;Ä /SÞ˜²3rÎh¦ó*œ‚:®ÓE!õªüã®j <Щ&Ëb£X#až‡5 ïlô¤{’\ª®=i±X²ÖÊNI^H± Ú¥F-Iü*Hp¼ÿ:A± ÄmµZšÄà0«Kæ®ÕçYûh}ˉ!Ëí]Ž9&@H$ÄÕHß”ŠÔ·¸šˆAÓê9©lÒ(K`þnSzàrV¡),×e@cßš–ÞæîÞQ\·\¨55´óÛÞîtVfÀ#S‰müØA&]›j+€gaóïnäš&fódgfŸº:TVQ=Ä¥âl@úX–(•d pIÅlg(óÓ°¼Ç†éI`prw Ú¿ñ)f£pŒ‡ô£[‰lbÝÅ4waè8àU}ón$»#žÔßí‰w³åVê?Q5ÌŽrû}@Éýjœn$ìZXŒ‘œ3àvÍR`7ÔSüùü²¢WU=»TD°ë#~ƒùP¡`r¹¥¦Ìñ’&0rGJÓ¹¾,Öò*ÈœíÜ+™-žYØ}sI•;ÿ!G"½Ã›K÷ÒêS+]H^Ý+f NÖÂÅ‚@ï\~å<ŸÇ#…R? )X×¼¿k@Èc§"¯¢(Q$ }ë›þ¸ý*Už~1#Œ{æŸ(s8ýqYì1"Sœô<æ‘5KÄwÆqê˜?¥D×^d¡æÿ»Í$»š“o!ZµqÓp”3°#=éÖZ¥¸”ôÜ*kÛÐP*Dâ,hÒ¹¶µ{°àƒX\Q XÈI#8Ï5"ÜF°²Ë»àÕ[i ’~`;SB{š2NË!UþÓÈñðsŸJzÞ,d3FÒ¸éZ1ÝÛ]Æ-š6ïž•ÎåXÁ¹žk…XFHÏ8©’=è#i0GQéM¸WþÒ+¢öÿ*K£û´mÃÓ­S%nXMgÕpÃÔŠ¯$§;ÙYùéLxn”ltv\÷© Y Û"°˜¥dYNb¯±=*h‹ ù\ {⦞Þ<XãÜU¢’G§Íã&‘/GrK›‰æašÍž8=©ñÛl›¨æ¥·²!<È~vïÏJw‘víµÇ~)^ÃJã!’_ £>µrhÒhAЃÁç ,y“ëëUcfòÉÚ¡14$1´WI<ŸCÖ®2yGiÅU–×xe˯LUio%|†¸Å;)±fþS åŽCoº8€+“ÔÒ"=äÛåo” ÔT®Û[j`\TI[D Œ‘Ë m§¨åëN‰I$°&¬1Š”š.RºÐ¤1êNv7éR^·™n¤äuéTM^:‚ hÝrA­¹*M‚O³.~|wZöòi@‹›Ú¯O$&ÜH[Ó<Õ Fß+\L¼/jGÏÐ|JaPÁïSGnòJí}¯y*±©¡¦”.€ú É]1Ü·÷j©tâAÀïOz@Ò±ù¹©ÕP§Ìy÷«Dµq–·®›#±5:ËðØŽã­gΡXº;NŽU"›]DF¼.FlZÎÔ%ûLÑ[¨qQ щAÜGª;Xß&gûÍê(å{…îjyžXƒ€¼Sd¸UÇðªû‰qž{sNdR~ð<ºŒŽ[†~™¥¶f.wœsQ=¹•¿vƦŽÁ˜íwÁ>¦¬c.ãv!ÐîÇqH— ê´Ë©$µËAó{zÔ4«‰vóÕ…4´°>èÒÔåitý5™B—Cèµê5åš„‚]7MUºþK^§Z-ˆ–’–˜Q@Q@D‘L qLx¸Èüªrœ³n<ŸÆ°ÔÇR5µ%ò{Õ´·‰T–p*¼÷*¸Ð°;®KœUYv>M˜%[>•L³oäÕÕ´Üp ÅZùJ8¥p¹7õ§y{{P§æ«‚-Ë÷iÜ r .{Õdc’1ZGÌ*6†5=)Z%º Qof5;¿pš©:0lœšb-D˜É:t¨d„ç*Ü}iF*b…GÔ‡R4R­œÔk‘8Ï­JU‹N*Qo幧Фõ%‘PÖ„™ÕB¡÷ïšI6zä }­¹tgù†9éPh·.¤0S^K=­Í´ÈÞgÎyùª/=¾ÏŸ7•ý*„·“Ï*ù’3`áG½;r椓g|î§#éT’é¡‹jŸ“<Œã'Ò¨;mËÈXã¯ÿ«™#|ÇÀã>¾õQD¶ºÍxîOÏ×¾1úU|e²Ä–õ?áM9ôæÇ§õ«±$¡€8'qôÖ–ê»T}1Q)ÛðÅ81 À¦!ÜóH3õ?ÒŸ¸ŽC ²§úÔeÛ# ~4»‰ëÓÚ€Üþ4™Çc“ëÍ0’:·ëIž>÷ë@naÐ/åFò8¦{IùÒå÷Oá@ÇSÕ@4`u úÓ\ò>Ô»½0hà?÷ÉýhÉ ü©€ã #ñ§ÿkó ‡ÀçFøæhÏÈÅÝ9•D±Å >ÄRøº ,ˆ ?Ä£ùбÙ-AFù—šÊ¡³ô4ä}¤ØaëJÃ7b"HùÆqM-$JHǨ[]ˆß÷‡n*.î> ô¨±H³¦\¸y¤PÄÕ”ÔÚÎí¦‚!å·ðŽ*̳-åä&Fzb­´‰äQA"¶F“ëžb6ªj[=N 2ÂÈ;f³í®ÛìeÁÀ¦H²TŸ|÷¢ÁrÞ³yc5¹X÷„ãNj¥ƒ5¥³!Uú“×ZÎupdrÖº4t¹ïñ¤Ñ:˜\}žv\’:‚*ÙÔåxðFÓÛŠ³«hÐÚ@\H»‡½eîF…YHcíÖ˜¶,’Zg?Ò¡Œ!ž{Ô˜L䜭 4{¶æ‹ÉþT'â©\·Ú.1‚|TÒÏq“íU¬ØÒ>cMF¸Á.Ü M¾&Ü2zûS.¢2`©ªþ_ÏÉÁïNÂٗѾC†È¨ˆvƒéEº|ØRyÑZÛY´`´€:š—¡v¹Íl*q’(þgÞÎG~õwWHá¸Û+{©â³¥¸h£<òjš!x™®6¤…¶öÅZ·U$ŒuéQÙ£"îa–njNc›##4É·RW_,žúÕ±ï‡ÍNž Õgfo¼û³Û$2Io§ „ÖvîZW!y gsQ5É݆ȩ.$VnF ô¨ÓÚ©V“ƒùÕI$1¶Q°On¢­’¡qTÑ<Æ.Ý=©“¹¡ ˜‹4€KŽÔø®•·o==«="q.w~u>'ÝžüistVÔ°wdpjEUØ`ŸCM’ExÆÍn9àRÐïrí¥Ä1Æ|Å€éëP]Ü ÷E”zu¨LM#ícC[ç„`M4ZNÄd¾O&”8#Þ†‚Ul6qN{\®AéïNäÙ’Þãû/LÛÓmßòZõZò‹Ÿùéœç‹¿äµêõ¢ØLJZJZb (¢€ (¢€<9Ш¦naÀ&®\mi¶/5¸©$Ì8Øî«ß½E.Nç*ÃÒ™)9Á‘IŽ:£J×MŽáTpH'5–`iî[ºGRy­#ošN8§,3ÛÛlääš[kŒi|¾0x¨Ú_3އµ1 f=NiÞ@qéUrZ-BàÄ)ÔÔ7š„’…\wÅ3i TއŠ0x¡ Œ­¡\¼ïË[ÖœÀæ­ˆÔŒ)’,K }ã#µ¹Q™å;ãRˆÙp¥¶l{°wæœ –Á?¥BÆ»“R”27ëH¬Áˆ«vÈÜ æ•®4>Vê¿Ê¦Ùógv1Iv¡éQ“Ç\Zm´z–y@VÿëUßìÉ!a!#uô5ŸÃÂAUÝõ5§4ÓÜBv® ¬ÚfñhŽâX¢1Ç­c\ÈÓN±AÁoJšH'\¼í€)4w†}8¦®&Óб} ·ÒôȘrìþ‹^©^c¬ÉæZiÌF2—_ú ×§VËc'¸QEÄQEQExÓZ•!˜á½ê;ˆ%Ù»qÇÖ¥žU’Sóæ’K€°í'5ƒÑ™­!inU ÆO5wSÓ͸ ¿7½E`L—"º+¨–XÂðxèiJMHÞ)Zìæ¬®–õ«TÉž«ž*éÓ#l’Ê3Û›qbé!8­.g£dæø¸ïH&.¼œUd†BÛM]K<Œä –î "£/_˜š€+U­/Ì«Il¤ñB Ü‘À¦2“Ú®¤L½E,qƒ(1TMÊöá¶eúf¥òø­°¬yÀ½¼÷7[-¡’R¸3L:‚C±q‘Å=màíŽLÌxTÚrÕÐÛxRúhÁ£ƒêrGà+RÓOµÑße¸-1PVóééQ'mM#Ù—§ø8­¨M°ž|¸ù'ê{VÔu•“·†0ýG‰úÕ™åH¡;ÜnÆqœW7¦ÏvææàŸôuÈ@}o ¬C¦îkÏ0Iƒ —99ÇAýj»e¼ÀK!l°m‡ßüõ¨Ý¼Ð·pl’w`‚=8Ï#N²O ‰³´H¤¿ÊO š¨ØtÒ#o~€îª0WžsúÕiع¬wäà·Ýý*G›í UÄ£¶à# žùªÌè$!·‚uaÆxúÔ¶ZB}£ç-¶KsÁVÏ'õ¥Yþçi'ý_ƒYrK±ñ½È$Ž˜8ÿ$TóÜaUÍ·“?_qYJæñ±d\ìÚ³²à) <±‘ƒÁ÷ÍgêP¥Õ¾çÛ `í›=Î:SVf º9:‚¥»U®Ò-Ád<“UÓ&¢N:™§–ÅwƒƒLWlåsV^Ñ”3?5X;tS€}+º.ç™8Ù·; ¤,yàçÒ®ZYÇ-»Ë$ûBõÇaRÙè÷z‚Ê`C 9“·DÛÈö©N1Vÿ³dHRRT«¶Ò22=ÿ3U$F†FG© Œ÷¢ú€â08é@4ŠÃð Œt 4G)Aâ zÒŒýhÈ=)2{Š<žG ŽÆ˜>¿Ò“߀{þtuàøŠh#ÞqúPà @õ§n8ɯJ‹w8ÝKÈ=Ei>§vöþD¯¼c‚ܟάؠWD|ãŠÆVõÆ*Ì1ŽJçñ_¥C‰I›2XÈ&Ø‹×Ò´"±XÀޠ繪v”»Ã±WZ±¨js¸Ä1ŒûÔòؾk‰6–²3?÷éY­h«)VÏB)VûQ8o§j–{Ü[îh@#¸4ÄÙ›+_fãxæ‘£{™ÁÚ+BÇKžå~ÔT•==)³ÛInûÀùO_jˆ”›*ý™‚0E<•Eá¿:”Çæ|Û”þ59²„EºB9©æ4P¹˜·d¼ü¨ûhSNh’¼ùxü)ÌŽ[½Rw!‚Ì\’@nõ<žJ¡;¨Ê$(w)ÅC {‘œýÓÛÒ®+ò„k,“ 6Ôä Ð]±ÌŒHãŠ"lÂqŽ˜¦ƒ9l1'éRÑI»'aÉ$| òK…ÁÏ­@ø÷…úSÓÌC¾üèØ ZqXL¤¨#·µf©OZœy’L ò°'×¥%Ä&Õƒd4gœŠh–9QBä© új”ñÆ×+ž 榒åÝÆÁ„ÅÖe³#·ÌzQ`½É\¬jWã­4’¨NJ´-Ô'9&¤E‡aÜŒy©-#!î[?wô¥[É—H­gಠc±ªímÍ4Éh#"uÌŽN}M1X#' t÷¤ò˜pæ…Šî_¼=ꉒ¸6:¨éëW-/fFHÇó¬ó#ª£‘ÛÒO#BIûÀrË:¶¬nbòR!“ÜT¶WVÿe•(àwMcÂá I"““ÅL'R=? –ÍRÒæž¤Áôý8†ÈÛuÿ ­z•yUàIÓ1ÓmßòZõSZ-ŒÞâRÑE1Q@Q@)ä®2ZAnÂNjD·rGÍÅt^ÑCËçL7(õ®w+Ý™VÖ-nûñ×¥K5Û!Îx®ÊöÞÛËÚTØW!yo1Týj„Í$¬ŠGR Ø'úSþÖ¤à‘T¯-Õ_7aKolå~uäV»£+ZUõ¨¼ægàþ²ÀJñÉ«vV‘¢y’1Ï57±¬cpQ”ù—ô¦Õ˜õ¡ öÌ䃦j¤˜31A•’o©SŠHa†ECš­*Ï#ªªäà`rMiÀ¯,‹jYØà]®“¤C§F³L¨×8å±÷=…Tu1²1tO»Ä’êŽS¿”§ øžÕÖ[ÛAgŠÚ$‰=c?ZŽK¥^ùôÅ1®²ÜœV·He™[’"°¯eÙ©£P¤ž~˜­O0±Ï_AÖ²5;y£™. a¿t÷¬ª«ÇCZNÒÔÄÖþÑsâ;hU˜#)koÈQipº¬QÏLž„þyª_î9Ž5”¦EäãÓÚƒrçc9i!nB`çžGéXG¥ÎÅ4îcùá û†]AÀë‚@Ï&©É#«®†Èó[…=¿ @[ÍòÔ>ÓÌg€Z¡uc»eá¼Ù~¢“f‰X‘®ƒpò ʧhúø ¯pÆvØv±=“ ŽôÉ&3‚$ß"§“¢•6ò!}çì=i¤&ÊWPya2‘»Ø=°zÔS´— Ns“ïœÕÙÒ2Ð2xÊŽHíϱª¡_ žUs¿úÕØ”ì‡cœ€HÆà{T×°²‚â0@Â=*wóFÒÈ`G§qWâHæÃ`’úvúVoMMW¼¬aÞoŠÐn<ÈzÏH."º «xµÜn+:(<¥cùl¬Ñ8ÚëÁº)Êèâ« HªXóÎíš±íÔ@ˆ®%sœ#íêZcBsFÀ¢¶æ0å.\j³Í‹Ë…ŽX¢ã4š&÷s \ýH¨líšêåQzg$ž€U­GmÍìÓFÊ© ÏONÕ ê>] Žƒ3C¸àƒëMÝšÐý¨ǵ4qAõ ýgôƒëŠ çž´QŒz}iA=%'½ìi:zÑ’F£$uÍ.îÆ”íMϯéK‘ØÐœÏ.:äS1ùS†@õühåëÛº¶2 Ÿç[é2\D#•>µÉîù¹{Õ›[—¶bW$¾õ-™»((½ðyõ¬ÿ-¯'òÐñÜS¦¾ˆÛ–äî N~ WÚÍY·cEcRÞâúÐyq\a@àu——O½&ÃwžÑH€ùÈÏ^´6%›õíKšè|¶3NñÆßÒ¬Á× #1úV†£b<‘*Ž}E3K±šXüØÜ(èJÑ„vKÜšd‘ÿ){Õ›¡6áæ:©•Rîãe¹Î7tw¡ •]ZêäD§å¡›½vÆF=*¦Ÿ ¢™22Üäõ©ÍܰI„úçW&ÄRC%„»%)èj`6¯˜HÛIq$÷ÑüÑG ŸåN´‡Ï$ô¡ê-„iã” ¨ü1åHˆ8­XNÒ*Ù[X”îÙÜŠV(ÊÉ~]yëֳﮄ§ìð€Fy V†§{l‹¶ÝQ™»¯Z¡JùŽ>cOb[—Ãl ¡8Áb9ªñJÀÉÇaVš(Ü<­A1Œ®~aÐИ1©“iv_Cž†Ÿ4“(À”‘êEDÇæàš¸‘XÏî(îRG‘†<÷õ©Õœ±Á?–jÜÑ,H7cv:UeÈ9(ˆÙ˜7oƤ¼¶ ØÇ½LbWÁ9÷ª×ð~ö+x¹w>½(¸­a¶öãQÔ½pqš–kHЕpǦOZ”è×H®ƒß•ÕÙCr)s(Y6žmš;µ) <Ô‚ÚÂb)$ôÅ2uY ÈŒ,ª;taL·•W ¤+/ ‘Cõí¡s_m­´Ø— ŠäþjµéUæZÜÏqk§K!ËîF~еé½ëU±,JZJZb (¢€ (¢€< Ûºzsø×OgtY&==y¨µ+"-¾Y#þèæ² ±yÎ\ŸïW»›Â (½sy$Ù ¾Õ™#î|Ç'¿¬öª¡Ï=jÄÊÒó.ãŽô'ÐÉÁ¶sËnÙ22`{ÐÓ²FYcéÖ´|áz\ÂDxõ$Õ}BŠËbc-ÇNµIØ9•ö†s’ü)^V“°¨E¼‘òsÏ­=b­q§b{Kv•¾Zš[yb< TÖ‘¸8È­]>?µÞ!T3œv¬ÝÙ„¤Û/øoM[;a{p? ùþõúšÔ–ãß©¨¥¸à“€;ØzU)'ÜzÍmd2ÛH‚ÌO_JfâÞõU¦ÎÐ8œ’ qŸ~ÕI\.^AŒaÈ>”’me*ØÁëPyáO\š‚YÎpOõªŠ3(]Äc—åwÈ$§4†óÍ>³(<ÿ#úU»§bFg9\ŸçUŒªFù6àà¾ÄW%hYÜîÃÔ¾ŒˆÝ’Š))À.~l{b˜²+©Âd“†ó˜qQ”1±2G€@È$ŸÀÒ9U9–6,OÈìÝ ç±ÖÉÙ‚íu;Ê7ÜÚ:QHw®K9@O ê÷Çÿ^£2†?½R ŒeÆÕ?ãL ]A5ƒ¡ÛØûwª’«Ø?rË–UÉ zóTç2 íVãålÈê*ÚÅ»‚’³³ã'×55ÐÊ‹‘(o0yas’½Zbi°Û‚§ž¼sÖ¯ÙÜ(’ Ã|¡»ätªsÄ"®q”ÎàœÓ9ç,¡‚îóϵ7dJ—+4/í¥…ô_ïmçü:UfÚ†XºÇ.:çÔÖš„‘\Ys‚=p*Y­ôëó½Yc•»®A?Ó5)òî)®mŠm¥MÑ&B ,=þ´‘Ø[$‹ö‰÷ç’ ã<â’}*uÏ•s¹AèIUqeÎe¸ ÏéZ'~¦¯±{ÍIA§@KdŽ{ç¿ò§5²ÄVÕv±U̧խG ÐÛ Ž)p ÉØ céL‘ä U¢òòKu4µ‰²&×o˜Oji_L}*i…Áx¦ ãîãêk¢;Ïr‘Ú””çýšc.ygëT!2=iCg¯4Ãî)AÅ;Ÿ”þ§ÜSx<Óõæ€ qsJ3Øþt˜ô<уï@ Ï#4`})»ñ ÒñëŠ^;ñGÐÒ޼Ð4¼w¥ƒøiÏÖêheaœHÏÝ­K[qµíÜzóÒ±ÔduçÖ¤†æHr1vì~µœ£rã+;Ú41ÅH÷9¨1Á‘Šm¤ßj‹p”“ÝO8«pOóm w¨²Eݲ7…ˆ\t=ê+««l¤L0?„ŠÓ.OðñÚ³îÁ¶œL ía’ R%‘®®t¯ÿÅUœ n"‡©z­Åu¬_vÜv5F‹ß´£îjV°^æÓÁ°œJ|‚™8ÏûTØî Eýç_­Gs4S€¨Ï·ZEXlžhæ ¸ª‚Yí&$œnêz¿,¸Y\­TÔ¡òÈa&îßJi‘%ÔíN²‚3×'­ ?‘/ÔšŽ( ˜4·Ðùu5BÖÅ[FE¹f`YⵚD¸!Q³í­XÚî sH³\D>XÈÅK).åól"ûÙÁõ¨Ö8‹ò¸ªÏyx냌Uu7 Ø'9ô6±jÅ»¨â†U(ÀƒÔ µfÊÓÞí©,t'¸¶i ÀdV4­:9í\—_1Hæšš%ÇQšÙ˜…{úŽ1T\@3€=¹©çAÆ×tÏ¥Vžå7^ió'°­a³IäÁ¸õ8§évÓÉ)¸lù˜ùK « ‹u¨Ç#$ëá{h‚íeQZΤÜv.¹s æs+nÔ‰2pyÅmÏ5¼Ñ•.µÏÉïcÃŒœSNn[•(Ûb!2—ùUX{Ôw1ˆ¤VLmnqüéáIù1뚉á×zÆv/|VÝL¤›'Õqö4ü_ú רW–êv›¦sŸ’ëù-z‘­Q˜”´”´À(¢Š(¢ŠàdK™Q&¹m¤ÜÆïÑZa× ªøz­¨kPÛɱÙ‡)¯1Bæòrâ)J€¿ÄhXVü$ÂŽ§Ú³on]¤yé“ÅCm4ÄjO'#æ±ÐC¥ÛÇ 19ÍAo–éRNc¥P“TšÕ–>HçëPEªºHÌ©NyíRÑ<èÔÖìâÛ˜v?­eYÀ¨…˜dçŒÕ¡©4Ñê¬{š®÷ · 0=+U±Œåظ*1žõ©¦©K]ËÁ‘²xì+ž3üÜž+¥µp-bÀþGãEîL{“O&8Ï5Yœ…e#†ÅXXL‡=ÍHlÉãéT2“Kž"ž®ÛqRIq‘–¨ZhT}ãø qš¸ùF´ÛN?ZA.æçüj´²BÄÍR*¼÷‘[®CãAÍj¦…ÊÍ3f³Ž¸cߺMĽ„ªG<ñXͯº·Ë¹} K‰ œLéö’±p¼]ËØ]—ƒØ‘ŸÖ›ˆM¹ù]À±üøÿí›?ÖF¤õÚѧ.»hwÂp0ISúä³]ÕP®m$²UìÐu¨Z"pã¡ä`úcÒ¯ ^ĸ+2GÆ>J–-NË;ÐÁöþtû)£.Hä‰ò^ÍÉ+þ"– ¢WPÁŒ.Ò=MoǬXÊÌ?ÙP3üè’2ûh*2Ž20AúÓcœ•cÄb<&Òv‚ÙÜpj“‚$¯UläsÛÖºK­U„ˆ’9‘Ž>^J­c\Ú*•G )$ p:ÓŒ†Ò{ŒÇ#xq×éNøpXÛ¯áOhp20Fx8Å1¢>n6`ñò©­tf:¢s"IdÀüþšŒžf°°|šŒ_ݼ‡o$:Sã‰æ“ ÎSÔuÇzV‘+ Š»NFÓŠk<Ï„1‚®sV–Þ8¡>pNwn'ùR©®ÌÞüâ„g'rœvîG1°•`!°ÊE\ŽL°çŽ*Ã4@ €:íâ©È…1¢Q‘€Q¼AFc½i|ï®×eFÖ¤œ4ƒ8äc§õ¡Hn&S"“Ž~´Ï$œì þ5©ö2Ç÷cpö5Ö¬œì8«˜žS8©S†Zºð zuªío pöëV¤‰qd\Ò­÷²>´ÊÅ`'P8÷ Òt ÝéK×¶)(9 t|á¤ð§d"€>´ðCýi¤wƒƒHe›[¹-&¿ˆìEt݉âC´zC\ÎsÚ§±»kK…;¾LüÃÚ¥«•Xè'Ÿåç$ãµP»»fŒ©Ï­_•­åU|äxô¬És^íOº¾õ ÙÂâ/Ÿ85¯ca ¶¡Ã#Þ›‚6•àÕI3m#)'i9JlKCZ9eÇ9¹­?Mµ‡B{t®quØm-ÂÆ…ØSañ!wÄŠWëYÙ—¡ÓklMø}A¬ á&3cê?Zسբ)–a‚*…õø’såà®=)ʼn£§kfÙ"ãëMb÷—J¬1žN)Ó»_ß…Æå_j|ˆöÒrHº»£'¦æÂ½²Cµ[¶*”ÒFIsÓ5q©«œS¥8ØAÇféC)2!1û½ZšÔ%¬¥¥„¸4øÃ*‚"OÀäTÍq…ŠL<@mg#Ë&?CUcÔÊÞK%¾6HA+ëNš1q/ú³øS×Kó$ *æ¦É“ ]äÁ‘1‘ÔU[ ‘B_€OJ_6ó{G³rGÃ`f£[f¾œù˜P¸Èª²Bç¸í6Þ"›å8cïZb;t!ev±«}…SŸJk[1æõ©vaít'˜YË­ŸCÖ«G+[Á˜ƒÎ)RÑ”–Ê’;ÔÉoæe@ È|üĶ@^Ë‚YNy®Ž8`‚ØÄvò5ËXe 7µ^·K«“‚Û»`Re&ŒíUYØ èßòZõ^g®Âmí¬#aƒ¶è‘õU¯L5ÑŒ^áE%-1Q@Q@f¦ISJÇ=ª,ªŒƒëQ\ÝAïPAx®yýzÖ7lÐ…a£Ò­ùQ”Ü„Ç ƒ`õü*(Qç‘w1AƒœóøS¥‘ÂFÄøŠÑk¹Ï6º GbØ*A=H^µ!C´|ÀôÈÿKP}?ÖË!ÉËmô=CÁc°>äÓÕNpTÈÞªé*ž lßSÿÖ©ŒÜ”cñ¨f‰¬jÜ4iŸBØþ•f5X¨' Óòª±È’”ÿwÿ¯V†Wbà{úª ±1Œ»¸ŒžùÆiŸfýç?0üÁýiÑ Ý)üóV¢‹~29<õþ¿ýjac2}9™Ùc@€ö4. Ü~eàîÖ·–Êìõª°Ï±•# Ú3øÕ"J7!‘w.ÏPGCùÖ|zÏ7”’\ýÖtv2 ƒ«¡ÚÍ·¥_HÚ‰ Á çù˜¹QÃÝè3Ã!HÙ]—„á¿.õ–ñ¼NQ”‚:ƒ^…-›¬»–<ü,ßâ+:çK†çw™ûÈÙçÛŠ¥>ä8v8ßz9­Ë½ Fª#l1þê—ö{ ÅÆÞßäUs¦.FgæŽsëVšÓk|ÍŽàã ÔSÏ­W2(h<õâ‘”©ãŸj\÷<Šwƒ$x§`9£:f*QžhÐÚiϲ©’áÀx ‘—=ÆvãŠtlÑ;?“tIÿ§Y?øššòi"ÑíBÏ4A¯'Ýå9RF3Ž M.‘©Çiç›û€ÀdÅçÉǶìõü+9J1µËI½†ˆe?g»ÿÀY?Â’{yfi¶ºt?e“ü* =%½pŸÚW‘Ð4ò\ôúSžÞèÊßÝ”þíÛ.ïÀœö5§"'™ì2=1€ùí®ÒÖOþ&”é€õµ»ÿÀY?žlõŽÆâóä'?émž™ã׊Skv‘ÈÒ^Þ+,~b¨ºbNH÷ã­Ì"Øéæ=>Ë'øSÍ´˜ùm®óïm&?ôO±Þ„vk롵wô¶ÃsŒž¼ÐlïYÈŠîù€U$µËOa͈|Ì~mö5s-µë»÷[Y0?1K$.CZÞ?ôë'øT?e¿Ùý¦ô‰ÀûSg“ž~µ¢ê) o{y¹x8ºcK‘õÜž 9¡|ù7L½‡ÙdÿâjËFìãÖðÛ¬‡úVnùÿçò÷ÿ^óÿÏåïþ½>DÑT‘N~Ëwôû,ŸáOmì¸6—|Ó¬ŸüMeù“ÿÏåïþ½dÿóù{ÿ/G"Í[&ki‹µÛ¯ ¶“?Ê®K{¸»E§ß+0à›WÀü…sÞeÇüþ^ÿàKÑæOÿ?—¿øô½šc¡Ò.âÓ­9¬5 dvË2Ú¶2~µSTŽ·ZXêIܽ«àþB²|Ëùü½ÿÀ—£Ì¸ÿŸËßü zj å§¶ºuÁŠç?õë/ÿOŠÞU’ ¶úZÉþK̸ÿŸËßü z<Éÿçò÷ÿ^f˜6žæ”Ჶט÷µ“ü)ÃÎÚïõë'øVg™?üþ^ÿàKÿdÿóù{ÿ/þ4½’‘~Ks!ù­oí‹Y?Ÿoö‹gÝ7£=¾Ë'øVo™?üþ^ÿàKÑæ\Ïåïþ½Íbþ¦“ê o˜.ƒD²«k';ÀÆ8íŽkª>%„ùêXÿ¯F®ÌŸþoð%èß?üþÞÿàKÿ]‡{Ïü$°ÿÐ?SÿÀF£þXè©ÿà#W æOÿ?—¿øÿãG™qÿ?·¿øôXW;ŸøIaÿ ~§ÿ€Gü$°ÿÐ?SÿÀF®&wqq]Þàtà dœŸ@©õí9’jRÇüEguÛùžJÎU#ÊËQm\ë“ůu©‚î)ä*e„¦rÁsÏ¡5µÍy¾žï&¡¡´²<‚ ;'`FsÞ›ŽƒW[–5—·ÔfË.¯µF¯$ãý[¯äkZæÑ'¼óp>p1štð=¨ ;´FÃm™ke+ž]”{­94õÜwNÇØ«‹!‘ÕŽ§55×ÙàUÙóœtn•[{¢€´´AüR7±Í=-øÛµ#úðÍÞÚUPШ'9BÇ}M$(ÎgW‹™ )ÉÎsý*ôÀ[£™Hî…œc§òª÷I 'ioáU'ðëK•ÎÄž6ŠÙЮDcä=xôö¨²…b;£.Þ¹ïO€¼œ¦Ðx8$ƒÏ^i#v„¢Í‚+¹O?ç­¨\Ì¡5¾÷%(Ç#‰F£ÇYxúÕÿ²Çk1U|vϨ榹DÛåy ‘÷”v÷öª°6f$,Ìvársó6ÓŸZS¼HREäž§'?^òäåßÓòýi„ó¹$qÈ#?•$¢Ñ0 íNÙqüF0;ñVà´%È@„Õ”ˆ‡ryã=3ô¬äÍ"ŒÅ‰›‘òŽØ4yX*0{й-º¹Î 7Cô¨ÚØ(ûÇs“Pj†*Œ÷ãÐ xœ™¹ü¨ØbÙÇ\ƒš”:ãæT#¿4€š6|íÞäêÜùÕ¨äd8c #ø–¨—N3¸ãÐÔ¢fRYAä‚2(5QÉ>cÊG@ÉþˆÑÕ€?‡=*=¶6õŒ`²åJU”)Cm^ŒAíTI u‚%Ú„ú•ã­Ç"Ý=ÇU"ÒdOuþFžª14ך´Ón!GÎ êy¨et`sǃJÁ>]§‘ýÓšf<Â@Ù–8Çã@Š’*–-‚F>~qøÖt H‡'æÎèkJTÃùC pxªsÆY¶`¨êÆ€3¦ŒPÍßn*¼. Û¸c‘ŽEiHÙÝž9'šÊ‘ÚÛrwý³T„ÊRÇò^AéU[+ÏçWÝIa·jޏ^¼šíż?óÅ?ïšO"ÿ,cÿ¾EÃÿekB´ÚiUOÍ';I#ø}ê;W¹˜Ë$úvãÇ 'ÿ“ø×zmàÿž1ÿß4}žùãýò(Ô>ÿ„{TÿžúýöÿüEðjŸóßNÿ¾ßÿˆ¯Aû4óÆ?ûæ—ìÐÏÿïš5 =ÿ„{TÿžúwýöÿüEðjŸóßNÿ¾ßÿˆ¯Bû4óÆ?ûæ³AÿÍüñþù£PÐóßøGµOùï§ÿßoÿÄQÿö©ÿ=ôïûíÿøŠô/³AÿÍüñþù£PÐà!Ó52qy!¶™e€³0SÜ£8<þtûû¹uÈþÇgç`T¹ÈD»ÕÝýž1 ²)L10ÁÔV2¤¥%"ã;+}¤–Æ‹m+Æò ˜óŽnã z×£W ©qâÝ7Ž›GþFZî«b9—NíØ„^iÓ­£B|«Bþ›V¦Ó¢µóßå]€÷«WZÕ¡U ¸ç¢ŠäZ›ìVµŠêkuI$KÐJË»éŠÔ¼Ôf¼‡©Ž29&³å„¨ÎÒÆ“!¤Ê%É ÷…!À`J÷õû™¤EÙÞÃúÕ?°ÜÊᤠ;àñSbUÉîí­ÞØJŒ2GsÍd:®6( }Ej˦¹^¤f§[Ekg´¸g=zÖ±E4c[Û–—æ®qGÆõª¦TR\ œÐ$Yˆ†=ªŒe{„¬ÎwyŽÇ¯ZF»»d îYqž UШªëC d ñI¢TìQŽGu<œÔÈæIõjц{桸‰ONi2£©  iæ*ÄÕµ™Áåö¯óú ÏtxŽèð?ZtSÈòa³î}šº4qV4¼ÆfÚå‘þ&š³ \÷äúÓ¾Ûyp"»w>•BÞRÒvïÉ‚žäò¤iÚ~òpìw|À*ã‚Çùã¯åVï®?wä‚ò(nrrdo¯¥P¶“ËÃð¬F=#8 å°sÐŽ¿ýz™J:€Fà{ñ¢;]£*HLðªš@T`oàwƧ*B°•aÕi›$R27g¡ÆAüi<í“•'o Í4+Ž d…±Õ_óô¦ÀÑÁvùOb3Ÿ¥JgóW.ª¬ÊGñ~4å™äǘ¡€õíïšb¸ù‘|ÄbOoð"³…Ãy¥Xe”÷àý*óºÇ‡Œe}ü9¬ûÆ9!Jž¤t?•ZŠp$!œ–=AÅjµ _ŸÈîEGŸ9̬I?ÃC†ž.ÀnÆxäÔIjÊëÇñ®žçM6ñ9Ú Ï­codl0Å6ô!¶2}=§Pî•R s ÅvžµÐÛÞÛGo‰ÏÜv¬ë©cvßÁî)\N7@H}) ¼f¢GÈÁëDƒ ޵g=µîˆâ©´¬Ç5)BrFzt¤Š1æ Ë‘HÒ*÷1ƒPœîÀãÖ¯HSÊ¡EWeP{RiŠR±à`½jXPpäuÁœ{óŠ`X°B8ç¾)¥7&ÉQ›#‚#ß4m€r:{ÔÑÜG#‹ž½8¦"“ÆÑ·ÏŽ ÜÔr ø3r#Œf¶ah1&É1éÎ*œÖ«ÁÜUqÂúÐ;•W,¿»Ì+ØžqV#1Ì®c`u ÁÿÌTA$œG¸ädUwÞO”ˆPu<`šžgUG¸²×©ÅV”ìP!Rrs¶3ˆ»|äŒai:ù~i9 ÇÿZ™•’sÔÏ• ÆU‰Á9ãõ«Ó¿?F#ŒõQ¢f îpTçëL R¦åʃòñj¨ó:õ<ŠÒwV‘òöm úúþµNkR³9cæã­\Y ïô ´ékÛ“s!ù‡¥hD¶ ŒH(ᶈø#8Á¯B:Uo ÿÇ¢×ĵÒÖ†f–’ÿjÆaÀ˜Lòùl:!\gëÛ=úT‘is­„ÖùDR“w„Çlà}r}ë`z)LZ4—±]J‘‚‘2mà’{U¢ Œ=>Š¡s§¥ÍÔ:)Ž Ù^œœzTM˜êkrÎ¥RBÙÜ~é\m Óñ­jJÉ[Çgek 5³†`FuéǽEˆÑK eI@TÜ|ÆP„x¨çí[tPB’@ž¸Í>ŠZ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šáu/ùôߪÿèñ]Õpº—üúoÕôx®ê€9k“ÙÝ"l9æÒÆée2<ŒÜð3[±i„çsaê½Þsić9é\ѱ§;!%Êy0=:Ԇ顷ò“ê85ö¯Wœu"®Þ}Ø‚¤nãÚ“j; 7" ½œ/Ä{ÒÿjÝ8Údm£Ðâ¡q8úÓ%S…8Éíš"îD¥m\_Ê*¤‘Þ±ÚòC6æR}k¡··BCLøOR:S¦³°k„jaz~5OÈI÷0ÛlÉÆ¦H— Á·jÕ¿Ó`iH‚UãÒ³ä²)ž>Æ¢ÅÝ[B¯™¹²Òµ4È¢ràsÍRc Éù½*@¢SÐtÕÙ“´uz±,¤A eìEE«Ë’;t«"ÜßÊ—Ï(>Eã½;ÏvWr’qÀªòYNdÈÉÍ\kõû¤Ð—Ùm«ß½Vˆ–ÊËc1íOû nŽ;ÕÙ%‘#Þ'ëÍg‹çf#i'<Ð Rä¬o¸òF[aYú“ïþyª"땨žêI& U$ ôSQд^X9.Êœzd“M¼$Tg¶×$õèOåŸÖ¢Ž&!?66 ÏsßùšÎº¸>VÑ“•†}Iþ|Ph_ŽRmò aŸ ŸN£óäÓ¼ÓçÏVÚ¾à çôRYH€Œ’UN1Ó#ÿ®jv'̉…Ub ?Æ¢ì„Gk9^L¤`û3V"P°Ç9ãrŸCÍVœª´qÿ †Sõ?äU‰¤0Ø[Ä~ò䑸gúÔ³E±JY¶làYˆé“×üûÓœ,f$9 ÃkÎ9È€ÅGo7›@÷çÔþ•2fI¤CÀ÷éýjnZB6D›@ù†ûÀŸñ©s#÷ÁÈì@þ¿ýcPÃ2püìÊŸæ?YÁ€KѰFϹ b:‚„õRÝ»u¤hÃ!\pO_ÆžØ*¢òHõXÊ‹´öH¨Œ¸mÝG8ú{Ò°p9ÁÇcY÷Pð gkž¹jòH$ ÒàtÈ=ê)Tí*7g§½PŒÅ-€¡‰>þ¿Ò”Jð¸òÀó¾:zŠ–[s Œs¼ã8õ¨¶©œåxÈ9ÉíäTO2UÃçœ]óÉ6YÉÁ縬șÌÛ$8“¶z˜Èø »h'¿c@Ý♈ˆ‚£¸æ‚ &#=ERG†ÑZERd=T)öWãv‘<‡¿ÿ^€!6€“+äÓçZgpG´!9#ÍhÜv˜É Ã’½qïT¯Ya*ˆ™ƒŽß…0'9N\®rzâ©N¦gÕ†þTNÎZ!nT®d=IúÕ§ lŰ»2Açi  é3— 6„'w¨w™ì<ÃÄ™ÚG¥Yòd^sÂóóÆ1P—x\a]ãñþ„SD3¸ðĉˆyQEĹ,@·Íí°Mÿhˆ&vî.1ŸJæô Ö˜#yº”áºpÀÿJÐþÈš+`°ù@ÙGhL©ÆÒ^ëdfÍcs—Ê2§™ŒìÜ7~UwÐIN%Ab¾aa´ûç8ö¬Ö·“ûZ$UIœNÎP†»+×Çãß©O¹d&TƒÚÀMä©Ï?/oÇ‘L [•º·Y“!8Ï× êvȳ1fÄ —“Ðãñæ¦[5¥„09RÈvtä“Å&£d.¬§†5EiW±ŽþÜЛä `Èdpв ŒOÐóR‹˜L­• ‹Ë&á=qTîìd1A¢©D™ec,ÌO  úR.Ÿ"N&_/wÚZc‚rr›qœzД¾­É–5ƒ$yŒãiçÎqBß@÷ê Ã'ïç$mõèj’ØÜµ™ŽHâóDÆT+1I$ç;zŒúQý™+òÉ®€ u« oߪ—Ç YZ|×±iðÝÿkXÙGs»bL„žO΄–hæ2ieýJ“ý*¹6‹I ¹Ñ'·“Ì|>ªKHÀ88âqu=ÊâOidºGôªÉÂHñ™“ìßáMA“=Kí³X ‰¼“•<{ÕF‡sdø‹LÏѿšÖÊý|E¦ãßáOŽPžÉ1˜Ø1ª€ˆ›µYûvñš>›¿Â¢}.>÷ˆ´ïü{ü*]+”y¸2GµzÔD«ËQǧÃ6ø‡MǾï𩌠ŒÂC¦~Mþr>¡ÊÀ /÷@Ö€$u<j_ ÐŦ~Mþ}pGü$Z_>Íþùr½ÆÊ 2ÇŒmBÝ{œåüé«g;aǰ©D tñ—ϳ…!·‚|E¦ztoð§Ê7qè+^:ŸÒ§@<݇)Ц- ÂE¦`ûð§ pwü$ZfO±ÿ 9 E±‰®_wyÎ;øT—OæDIç=ÿþ¸ª n±"Ó2ùÏ×éOh˦Óâ/Fÿ \Œµ!d%-À-!'>€qþ5m2-ÙÞ`8ôéþA­Õ™Iñ™òŒ½þ#†sψ´¾¹èßáSìÙJhš€[tœ~5bÆP/ §$çÔõþUž±ìRÄ:_ g†íøT€º‚?á"Ò°zü§ü(öL|èÐE"E= ‚£×¦1ù –T|»rWrJËó$ Oü$ZVN?…ºŽý( éâ-(sŸºiû6Ñ{OROãÿë¡”mö=ÿÏÒ±¼ùsŸøH´žÙoð÷¥ûDØQÿ •…è6·øRöL=¢/ÝÀ ±““¸#Y‚&,8êsÇùõ#O3 i_÷ɨ sÿ —ŸPü)û6è·/‘êÝ3éM+3ÜuÏ\ÕegÝñ–9ÏFÿ O/÷†OøHt²Ä磅͇:4¢Fg?Ü^þµaœ¶àŒ`ZËHˆ´¾˜èÔÐÌ?á!Ò¿ï“G³bçFž#;²1Ó àóqÀÊ㸪FIƒâ'î·øPÒHøÏˆt®=ÑìØs";›f/°avó_¥W’V ‡ J¿_­X‘ZF Þ!Òò9àß…1íÑùmJÏ®Ÿ s¢% $`÷>µ$òIpv+„ ÁÇz‹û:rËq`¯—t9#œóþ Û,6ÍžfHÁÇ׊’Úã›íãzž§½Wóe˜ÏpF<Í»T{ãùÒ@ÎÃCšH42 ›þÓ(ó€IœVŠê—mkæ2D»[÷Ž˜"àž€ç·áU|,©% ¡”ÝLpF{ÖûÙ[H{hX¸<úô­LÙEµþ؈‚ Ì!’îÜ;œÔ2ÞÝɦLâH¡¹ˆ©eò›ä·'žÿ7CéZ §£ß‹§*Å@ÀØ3Ÿvêzž*T´·Ž'‰-áHß;‘PßQÞ˜ž[±{ ²NèÌ’9SØŽƒ=óëþnt• ‘a}’!XôhŽ¢Ûåĉ´m]ªÑè=ªZƺkØæ´„¼Ò3 ýœ b3ÇÞÇ@jH/ne¿h„#ÉG1’AÈÂçvz~­i˜Õœ9U,ȨþÍçy1ù½<̓pZÊ7Z„ºLw"X!i1„-´çžÿ§½ZšI¢Ôm#w ®®PW3œg§·ëWM¼M „Ć21°¨Û¥DtûBèæÖܼ`o)r£ÛŽ(2Nö]û"™á2ƪIaóíÁõÇ·Ò¤k«™^ÀÁq$•ã“1J«ä`œŽWó«Qip$“É"Ç!›!@ÆsŒÏÔÔæÒÝ¢XšÞ&>êWè;P.纼–ohË «)®}Ï@9è}ª!#¶‹c1÷¬±ÛÏ È¡ƒzñšÕû,"s8†?8Œyìzg­d·òÞ?"/.N]v 7Ôw  _\ÿi=¼pƒlªÄƒŸ›ø³ÐéÞ£¶º½¼ËÌ1Ë$K*2ç 7`ƒœçZFÎÜÈ’"ßÂ7–2£ÐqOHc#D!vª§Ò€Ý$HUfpî3–¯5--%-Q@Q@Q@Q@Q@Q@.¥ÿ#~›õ_ý+º®Rÿ‘¿Mú¯þÝPžÚÅ=ÜM(ýª)Q¢/Å;NÔ䱂Tò·dü§µ@Ò›Æ>kàzvÉ®X¶„âŠòeÎU¿Z‚id 71À©%2vò½W.­ÃÒúØŠFyvN)J’ š|²*&5.žÉ+ãÐ÷¬Ûc±j’ §$‘P¬&G9éRË3‰6¢IÚ¹ ŠI—B3i>TÀg ìIQ[·º œzw›„H8ó K}:bªéz]¾¥á½1¥yRH„ž[FÂHê9è8â§’ÓW™<†xV=Ù2ïÈôÈ^¹ö«ª¤ä¹NˆÚÅ-Õ.÷Ït€Ã|êX gÎÐ3Ðdäþn= 4òÆÒ>#œ¡*»°› †þCñ§ iâ?+ο(:´ õÆÓÞŸÿõ˜Î.u!‘ƒ‹¾£°ûµÐž†v!ƒG†XíœÉ1Y£,HA÷ñ÷O§'Þm¥Å õ’Ͳù¯óe–£$m$J”x~ÑH+u©£} ùi«áÛ%P«s© ¾3ë÷h¸X†-"ÙäϘE"ÆÑŸ,nبÏ=Šö§:³0’6i#Èò$²É·8Ï?ýzü#¶\¤j\céC·#ø{RÙ‚\êA€À"ïׯðÑp±RêνÓãŽ9BL‘—'î’q§óÏ¥][H.ï'@ª‰wör<¿ºð[¯·Zgü#–8QöG ÷GÚ¾ïÓå¡|;d¥ŠÜjJ[ït~¿- ³ÛC ²Œ4$È’>@ œ1Îx­‹ÍÖ[¨¢·@óÚ6'<€¹ãv3œcŽ=êá­˜â§þÃnV’P[ÍÚ»-µ€ž9Ï~)ÿðŽXì1‰õ‡ªý«Ëm;ûÐý¯SÝŒgí|ãÓîÑp±èqµÃ$[wœ¸Ü`w®jÇöt l%ž ‹öy "¢ïR9b;g·5ð݆ݢ}Gn1µ `õþôãáë27Z™`uÐz}Ú. '‰m•†EÙ .Ч•¸ØþµZ-»Ï$_i“>bF˜U8fRpÜöÇlÔŸðŽÙŸ´jY럵½¿†”øẕcu©–'$ý«¿¯Ý¢àsÊÛ”ŽG§ÿZ—?çýjÝÿ„cNÆ<ËüúyüEðŒißóÖÿÿÿO˜,agüãÿ­FÎ+wþ;þzêø?øŠ?áӿ管ÿÿˆ£˜,agüãÿ­FÎ?úÕ»ÿÆÿ=oÿð ñÂ1§Ï[ÿüüE±…ŸóŠ3þq[¿ðŒißó×PÿÀÿÄQÿÆÿ=uüüEñ…ŸóŠ3ïúVïü#wüõÔ?ð ñÂ1§Ï]CÿÿG0¬agßôÿëQŸóŠÝÿ„cNÿžº‡þþ"øF4ïùë¨à@ÿâ(æ Yÿ8£?çýjÝÿ„cNÿžº‡þþ"øF4ïùë¨à@ÿâ(æ Y=éV4ëa{|°»mŒ)‘Èã `c8õaZ¿ðŒißó×PÿÀ‘ÿÄÐ4íHŸNšq8òÞPèøû£Ûš‰¶âÒ*:=JÚþ•˜‹,NíbÀ¯Lóõ¬Œ0Ôt}ƒ$XŸý L×A6Ÿ}©š¬¢;u%ŠÇ"–cõçŠÆÖm„ ²´¶Þ,Ê&㓃¼òqÏSÚ³¦š™Or¤ÛÞvP¹ïØò*Ä÷Z[ÀJ°#¹jÛ@¶zDóL¶Ü&zçž+. [tʸÿ”"™ÜxWþ=‡ý}LGç](®KCžH4“$!Ký¦P»Ž-ŽkI5k¶µ2˜c_÷Œ7EÆsŒdþU©“7)¹¬¿í)êF«ç¸î9BÙÔȯn%B¡îÚ¹ÉQÆsëŒvõÅ06¢¨hÒÉ6—’¾÷`I$çø~õ_Rkû[+¹–èç» «•ù¸ê1ÓÖ€5è¬i.ïm# ̲Ií »°¸ãäSgÕ¤ftAˆ+Œ‚¬wãjÛÍÍ`›¹¤±ÄͶXDŠB yÏL÷ÏnE\šúäj-o ¶øãÛ½‰Áù»¥iQUm’é%”Ï0‘Iù6ŒŸOlUª(¢–€ŠZ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(…Ô¿äoÓ~«ÿ£ÅwUÂê_ò7é¿UÿÑ⻪òi·¢rN*6—Ë-ôª²ÝÉ"êëPI30»W*‹…ùš3Žõ[îŠ}—ï!'2 #=)Ù™7®„¦d8ì)Ö €0èsQÛ\-Tûc#¶Õ\ç­$˜Xܫɴp:ç€h:ÞiÚr‹,Rïœà»BgŽ DÔ]ã <°v!bOÌØ9öÇ5¢8è}(ãž=~QÏÖ™‹w,S\ðBîSÎ$!z/aëô¥·f=ÅaùQŸ †Ü:m'“ùV˜ã 8éHm_ Q@sƒê3úQGÖŠ(¢Š@QEQEQEQE0’Š( šäõÙ/[98Å©Ç×]`®GÄ?ò6ZñŸôLÿzŽ€6ò/í ÄbF( vÏ4ýMm­ÎÓ!o˜ƒœò)T:\€nF#óçš‚;'’øÎì d—µf™gWáŸ/ì#ÍÛ´\ÌInkmáÓÞ!½ (`œcwjçô;´é~H sw)Ãt8oð{ûXí|¸£‹x}ÈA!Á ‚_JÔ†^{Ky55¤O1G …¦:õ#¯ù×Jµ´”²À°‡Ç Ÿñýj¬–ŽuˆÔD’0™¥ÚAa\téŸ~ôø´¹³§·ò¢E;|¨Û ·øü³“LFœm1¢#GcåP@ÏoÆ‹Ï ÚÉö• R\‘¥WB[Ø.e‚5 &ÂÚIÊ®²†R¤Æ  á.™oo*¢E,†%ù,NéÀã’xâž‹bÓLÞLk$må–e$(<~™¨ézÁ¦DN0€d³pzƒŒûÔvúlÑß›¹v;Èß¼Brª (%G®Gâ(HŸO|oMlÙÊ¢»¶1ǧ`ÛZnFh¢Ý’WÒ³åÓ§:4ÖKk ;¡² I!±ŽÙéV&°–{ø§*‰a§C‚w)Êc×’s@áÈIÀC‚ÄŒ{ãšyž ¡Œ¨t;‡5ÚuÄñÞ£@‘‰¥Y 0ØÇ¸ýjX´ ^ÑžE‰ävŸ,¸ôÅiùÑn+æ&@ɹ֢–òÞ(Ä((Í´ù¹ÆqÇÒ²ßHo>ç÷HÆQ!YL„™q´¯·OLb¯Y؈%Ÿ)ÆØU@ã!pN?ÏJ¹‰#WS•`>ÆH (Àà ZZ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€8]KþFý7ê¿ú”&(ÅU’úXÉ•JÈÛ‚äö¥ûZ›µ¶ÚÛÞ3"¶>RóøÎ€,ъE"?¿ƒœ}iðOñù‘¶å$Œû‚AýA  (¢Š)h¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€8]KþFý7ê¿ú†§ /¨åwÐ…£¹ÏB ÄA­[O¶\0XÁ5Í·—!” ƒImâ94ù6ÇÏ®yªpæ;a5cDEqo 9\ö©Ì¿/Ь.¦½>|ç“ÛÒ•¤E^On”B '=I¹3SÇo…ì˜ôÏëZígs©¹i" &ÿ,)u랸ö¬Ÿ |1bC¿ùÖ©–fƒÈiI#‘éšê-¯.¤a†å^H^¤ äö¨d½d„B<°Ù‘÷‚õfâ!qVfQ¹[+Œ‚EFö‰ Ì#1]¥¸ç>˜àŠi¾…X«’ ±…869=©Æò …²øPaÌ}½qL:|m+‘ü·|`ýì¶â ô¡ôø$gyæwIU##=±‚y#$RÊ:ɺ« ƒëKHªT¥ –Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(+šÔóÿ ¥¶qfÄø ×L+–Ör|cj°M©ú‡t¹)QvÙ]ÁAú÷Ç¥OsIÜ89õÍLb*îC‘ÎåëùTL³ßB[qNÍÐgÒ±44t+µi^P Aº”áú0<þUûh­„q$>`}Ñ@T8#%HÁôªïo¥´‘*³‹©€ xå±Z+ªÜý—Ìx¢]¯‰neEÁ98í[£65í›ûb #ŽG š@¤0 ãžßz’=>àÂ|Ëx¸º3ˆ·¬Æ:u+j3}­Q3L!7ÌIMÙÆ:T/¨]>›;)Š˜Ê–FF;ìsŒýzSK¶{M>y6n@AØxêzSu C5«­¼q‰K+sòç $}(’{‘{´b"Z##¹Î|Õ™ÒVÖU®ž€â€2¤°¹1‚"ä{±rÿ0ù0Wåõ8^µ+XÜ}ºiaÄ%RX¶smÀí‘ïɡԯ.lb‚6˜²Ò¶ÕÎôSŸ5`jNÒ„DRf9ûÀ `Ð(t‹˜ÎöŽ‘ËvíV¢ÔŒqW-ì§µk"»Êâ“æÆxöqô¦&£rö%ÄjgW "ß13Êõ?…K ì—W°yF!HÎXüÁ³¾Üwö t½(Ú»ùÈå+¸¸!Á9åp?\÷­dUQ…FIÀêk×S¸ŽÐyåŒeÑþf'çÛ‚äò0K Ü—2ØÌYã&áátèÇFG uäPÎG­½d½åÄê!I!·EtTç×ð¦E¨ÞH"_!݈ÜáÔ´·€{cõ  œÑYöíutmîRDKwY£#'89çñ_Ê´(¥¤¥ Š( Š( Š( Š( Š( Š( Rÿ‘¿Mú¯þÝW ©ÈߦýWÿGŠî¨È­£.p lG Áù·SYêë ÛœzUäñ ‘,xÜFk‘ߣ#¦£¤¶‘¦ 2i²ÄaF$Z¿jº…äÆP› éWäÒ"M6I.¤¹=ju)A#‹ÔïvXñÚ³áÛ5Ê’8ÍZ¸¶Ì‡'ûÑpÂÞ»¾µªvErØžæåã@‘Ÿj®ÿiò÷7^Ôå»T“;7~e.Úâ@¾PQê{ÐO*êt¾ÿ‘fÇþüêð àñôª>¼/d¾¡ÇëRˆnŒknQa÷y™ù«T )i)hQEQEQEQEQEQEQEQEQEQEQEQE æµ §Æ¶»×r‹F$À^ºJæ5…gñ²£mo²à/GA­Ë³Þ,×+díq#ž)Uü®‡SÐjlpF%YÉ*žW±ê9¶™¶Fw ù²?•bYµáeY,ÀuVêc‚3ß5¼ö6ΡZŠƒ6÷¬ ÿǨÿ¯™¿tÕº3eÓ‘ïÖéʼ…€s‚9=Ç=*t³·Hš%…o÷—­OKLDQÁeJFªQv® z~•%-%0Ä…Ë”RÅv“ŽqéQ‹+UpâÞ0Àc;{cËŠžŠ­ö Q“ä'—œíÇZ{Z@Ï41–ŒaÑòý*zJ€Ú@Wi†2¸+‚½³œ~|Ò}ŠßÊ"†Ý´(ÆzçëïV( M´&_4ĆB»Kc·¥6++xT,pF¸$Œ/sÇò«PQ4Š@À` u´QEQEQEQEQEQEQEÂê_ò7é¿UÿÑ⻪áu/ùôߪÿèñ]ÕyΕáýBéCI*ç­t c¥i)ºä¡qÛ<ÕmcÄÏ ˜ìãö Šæà·¸Ô® ÝJIcëï\¯–:³Cv÷ÄÛƒ-„ ('Ï›ËÓþ‘pÂ<ýÞk {{-<¥».âãïzU;½;r³Àà¯\Tói¡W1®V7©À•Y¡MÃn \[dsòŸÊ¢h^'éõ¡K¡C¢µÜ2¢¢š¼ÐT` ¹ ¡ºÒ<ÀƒÒµHÁît^ÿ‘fÇþüëK#8ÈÏëYžÏü"Ö[~ö\ÖÜ‘X®“º5Mû0­Æòþç®sZš¢£ð¤ªÚ”ÑÁlÍ#cæaödçœþUûL‘x­çŽhÊÿ­vÈ‘·`¨lñßz(§ÒŠÇ–æF±š3"DÆÝŒhäöÀõ«2Ot£WŒ23‚þQ …MÃŒñÏ hRV\·÷AäÚ±."Þ‘‘ó7ËœŽy玪ÜÉç4RÊŒQð6¡Á\ôÉÅZ¤úVBÏ4Ò»¸Œ´ 1báˆ< ¼c×9íOKÛ§„ȯŒÙÛ‘&càm¤V%›šïo¥"UgR€àrØäþ5¦5{£kæ˜"]¯‰sEÁ98튧á…G²@ ý¦o½õ­·´³dÅÐÙöÍnŒŠçR—í©$f˜BÍ¥³Œt¦E}p #b´Ívas°wÎqœqÓ׊ì#“Q[–hþP00s‚9=Æ íøö¡í´û[W/ià[¯__­0¤K$úl2ÊÛ™ƒsŸâ4Œ— \¸ ˜cE^r:JµÅkj¨Š0ª8éM»›i>уR_=1øPTz…äz}«ü³¼–í;´‡o@83jåY‹%råsÏ—³poéõ§´»kx°€BäÄ"f'x…\XmÄÆEHüÍžYls´rÒ€3ÓS¼6žcÚrñª‚Jƒ¸ã¸Ê¥ó¯Æ©mö<.î ž¡dqèZ±¥¬(Q!W!ˆ÷µI,pI$o"©’>Pž£>”ËTºYe3Ê®„þì(ä Ÿé¶­•wH²28o-ж;É­Iªè­Êî€ÜŸZ}-7zƒŒŒÒy‰‚w ôú*»nݤkBàòÀþU5-”´QEQEQEQEQEQEÂê_ò7é¿UÿÑ⻪áu/ù´ßøþÝP8µš%ß±Mcß«Û800㡬Eó¦ösj~ŸÓ^ •ØÍs8«¹RåBÉøëU’ðió¤“r“éȪZË%Ø6àþï€}jÄ©öË_5”‡=F*9l`Ö¦‡ÛÞ8üÈ@u>ƒ›q¬Ç;m–ÜÄßÞÔ5Í™ hÛ¨«Y%Ã_âéÇO­îávŒû“¼îŒãèxªn÷lÖúèS6Aê: ²tË;XwHå›ïMTIص«šžÿ‘fÇþüëGví«¼ñ¸ŸÎ³<8Û<-dÄgÏë[ a,vfäܳHyM .1’=Zê$b³!%X©éqA‘ÎIvÉëóTW31V|°P d’HùÕS¨©E*ޤ‘€Ãï ØíïÅ 4Ž3‡nzóMÜÞ§óªËt~Ï —c$’3þ?•A©$ß,² œvË;ûvÏzÑÀ°Nqž´›BIZ§-㭚ϻ죜sBjÉ$Ûh¬™<õôÈï@C¸9ÙõѽÏWlúæ©¥üOõ Fôõb¿ÌzÝ«G4›– 1ÉÁÇN½YÞÛvîm¾™â€ì!˜cTS<½ùEÝŒŽqž¼ýi£SŽ8à°ȹ8è2Øîy  î¢E à° zÒ†!p ¦â¨A~òÃ,FFy<¶+Ç8$ã×éWS„ILrí×Ë;óÓµ^f-ÔŸÄÒU#ª@¢êëæ¨qœ}Òp^榶º[‚ÊÐ…ßó«’3ùЊ*ÍóÃwä¬hÜ)qÜÄœ`qÌÓþß™$j¬Ò#„Ú¸%‰8íïë@èª6צCÈ>y Uz죜ûT°ÞÇ4±¢+åÔ¸'Ó$~=JŸ$±UGr'j“NŸ;lŸóÂûôj}=Ý ÛÄœ"`3ÅÔàà~tã«ÏöXåKdf)$¬<Ü)Dî§ç9? v®$ÿžÿߦ ‰æ‡Ö2+~7"º“µ€#èjÿøôsôãñ¢ÀcìËïƒIÚ‘Âý§i”ÄÉ´GÎG¿×?Δ`(Ç ¤ÑEQEQEQEQEQEQE‚¹}faoâûyÈl1޹WÔW%â<ÿÂS1jOèôK±W'Ÿ˜þ?äUû­Ð´ØÃc èúõ”îÊC˧=êՠ˜äåzÖF‡A¢[ý¯I0íW w)*ÂsŸÂ®c˜ëZØ£Œ–"Ý/ã]:YNWh@|¤N¼ñP>•4¶öBk}þD˜£iù†Aôê9­ý´¸µdɤ‡–þ]‘¬³¨XåÆY~M½zŠ‚ßG\D$³$,cvW_¸W ¯zÝÅôâ€*YZˆ­ ª™£ERÝOÖ­Š1ŠZJZ( Š( Š( Š( Š( Š(  º‘¢¶‘Óï(⧪×ÿñç/Ò€8ÝCŸi„õ!þFZîë„¿ÿ‘¯Jÿu?ôr×w@^\LNô ƒœŠš5Ž Ìƒ'ùTK?#yŽ0zTvo&òŽr:îÍr½‹wdâ5 Ò²qŒœÕu¿ýá ‡ƒÇ5%åâ Û×úÕHndaTž†¦OC4ìõ4¢–K†ÃÇøš½ÃÌÜžµ™op!CŒ³TrK$Ç.ßAšÊÒ“±«”¨Õ—QV8’?*Ï•žF-'#3Šj Š2ÄsPI#HN¤)%«1u:O ȳcßïõúÖžæ0ˆŒŽbÁ‘‚=:g—ᲆ,Iè7“ùÖ™Ožmäã;ò:zã9®²Ð’"Èñ¸ øƒþ5µƒåÌyÛÓ,½»ùԮʀ–` w'¥7ÌL¨Þ¹nœõúP~Í’±aö©Êç+ô>Ô‰meJ\ ¼9à “ƒëÉ4=Ô)*ÆÒ.X‘Ô``f–kˆàd[/÷@“ùPˆc ùb ¨ÏLtæšö0ÚcÀosŸÏ<Óıí'zàœ·O¯¥6ãœ6Æi ç¯þ” gØíÉS°ü¿í›œóëÏ4õ‚4.FýÒ}æ-Ï®§y‘ù~fõÙýìŒ~t’OjÌ\eW~縠Çk ELaÐŽK ¶y9õçéJ¶ñÆT¦ôÛÓk‘‘œàúŒö¢[ˆãŒ¹n‰¿o|c9¤7¬ €äÿ_" vàT+Œµˆ9ÁúòGÐÓ’Úpc‡!\€Ã$àúòOçNÆFwòîÁ`AÉÎxëšOÀÉu ÑaȪpO\ò>µ<£Oš5I¥’@¹%²AÆTãøO¥RócO˜¸n‡w_¥1.¢p\çœð1ØúSsûB×þzã§ü*+«Ëy­Þ4rY‡iõúVXž" ¡©ÝÒ…–7û²+}€¶¡oZã{üÉ…›÷8éÓ5' ö¤ó#.ð è7`š¡r†áÔg‘øR´µ%²Ú,sÍxŠÁ]Tnäô}MNÍ£¨ˆ”‹ä©Úzg>œñÍÊtV¸Ó¬ÿçÚ?Ê¡»²µŠën€†^qÛ#üM:Š ‘òXšÑV%l›8cßùÿ:ýZs“±sõÀ –’–€ (¢€ (¢€ (¢€¹/+7Ší‚Œÿ£r=¾lþ•Ö×!âY<¯@ýůøõ6ð,)?x ¸>¢«æL…W!›¿LT°,óί*©@N}V¥höÎeÙ€œ}ëCªð© h 8æ~k£óÞ¸õÍrš%¿ÚôŸ'j°k©r­ÐÃ5tèóGh-ãgo@ íSŒd‚0˜í[£# Þ¹Û¸gÓ5\+«¶vª±ROLÖ,–ì5˜³rJ&YZP~`6·žÙçÓŸZzXÌÖ¬d¡ןä˜uôàã#¯§½05íîæš2J6qÆ:?¥C&§g¼ê_¯íþ|RivÒZéÐÁ.Ðè!N@äž´ÝFÔ½›‹hTÊY[ » óøP˜naš$r©F8=ý)±\¬—3@â [r9Á¿CÒ²'Ò§™¥ˆHd’GhQÔl,’1Ÿ©Æjä–“yòªd$ö˘&6]Üœò~÷_j»5Ô0ÅæI*ªî ’{“Œ~´ýë7 žƒ=k-%—O‘>È‚PÈÁ••Ê£€}zœóRͧ¼šŠ\y£Úª˜vòGCÇû§Ö€4 »†wtŠ@ìŸxÜ‘üÁ©ê(âDvdERÇ$€2zÿ‰üê\Š(¢–€–Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ª÷ßñå/ûµb«ßÇ”¿îÐÿ#V•þêèå®î¸Kÿù´¯÷SÿG-wtå‘É{ƒõ=1MuHãù[“Ö’ W’Bàjr…¸ÛÒ¸½›cö–ÐÊ’ÞI¤ÂäÔ‹j°‘æœ}Mi+ùCäO©ªW“ÆŠN71­TtÔÊNìh¸E;Wšpgc•QY +—,8­xrm|ïA“SËÊÁèL³³)WL¬‚B8õvÜ,±o¦á&,à­ÔÔè|8¡¼/d§¡?ZÚ{¹d´ò %v3ç¶1œb±¼5ÿ"ÍüùÖ•t‘ÜÂ.TíÀ‘†ý?ZªÚ|„Ä¢e n ù³ÁÆ}°«Ôt e4±ÀXÄR=Øù9lƒÉ÷æžlÁ¡ÝˆpJ»)'n:‚¥Y¥ EÓÜLd–T™N6Ž@lôÇøÐÚi“Ì "*Ÿ3k"üß0Ç>¯äÒPAe‹6‡äÜϼ’xŽFÇN˜¨Îš^BÒL”à›n2:rxÈëZ”žúayÚ@K(çû­³o¦qø÷§¥‹Æ¨¨ñŠÈ )É ŽÞ÷«´P3F’6:™nM ôä¨SÛ'§­Iq¦‰§÷.%€6»qÓ8öÎ95{ð¢€#† JFÜ9RŒcŠ–’–€*\Z<­.ÉQVTòÜ0$Ï#ó5iÅÞLȪ¤¹AÞw.0O ëùUê\ÐtáË8ÉFRF8$‘€àzTCIýÎÏ1rP¡8à‚¸kJЦöLdߢ8ÈuHŒv&štæ`Š^0¨NÑ´ò çò«ÔP&ÓTº•1… Ä€¿xRõÆ)‚¬²– mà’û†~=ªõ.h‡öq(ûž=ì¬3·î’û‰ÏéKmm,wæFV%2çŸv:õ?ýj»KšžÖßí6—1aI.¤nb0x9Êœ‚;éCh¬ H£˜chågÉ$3n$žsžµOQôb3ù2}[þûoñ¢àt«jñêÞ_æ+¸ˆ>†FÿO1½Ÿ«±þ´î`7&îE”/1°ÔŸðÇò§„O÷Wù <ÅþðüÍ&õþð¤ÒÓw/¨Ï¥8õ ŠJZ(¢Š(¢ŠJåuÈEÇ‹­ã#9µ'òkª®7ÅsKoâ8^‰>Ë´®àC@¸”BÞJ?;pçÓÚ«Ã3I¯ò¡å[©¤´¶™­ƒûÇ$žµrÚ8ðÁ£{Ve…;[ifXÐ;‹©@Rp2[kLk›Q+@ˆöÈÛ˜¢ g$œqŒôª^D–ÉC.Wí3p~µºú}«¨F„m8Œö­Q ªÚ”ŸkXÖ$hLÂÛþbv–Èœ †MJæM6icÅq]Ѿì =ˆ súUÉ4èÞýn˜¯ÈA/9ÁœôÁôϽL–6É Â± Ž0À’sýiˆ†K‹…¼ŠÙ#Œ³Fdv,@ `qïVnSˆJ‰v…†@=³øÐ–ñFU‘>d]Šz½qúT¸  ä–æ;Ëx'tbâF;G\·‡Zˆ^Ký ß+4FV…på‚ç¦:~?¥^¹²·º*ÓǸ®vœF~” +a1˜B¢B»w{tþ_Q‹S–KeÄh.AŒ³,‘Ÿ›# ãÚÞÜÃ{ +D¢`î–$¼sÎ:ÕÕÓ­òÎ 9'±Ï_Öž,íÀÀ‰qòÿã½?*ËYžHžE´`¼l.G,Hóž3VV[Û¨óGFï€ä‚AàŠ²º}ª3ÎO'®sÓ·<ñSGG»b…ÜÅ›ÉêhJ))h¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ª÷ßñå/ûµb«ßÇ”¿îÐÿ#V•þêèå®î¸Kÿù´¯÷SÿG-wtæ¨^¼ÓÂðNxªÊwŒ†Çµ?,¬ŒE—k ƒŠ¥%º÷ù‰ô«§kŠ…¢9ùëI¡™—P (öX[ؤ]Y…Xû:×TSÁºO1º(ã¡°r¾ƒ#f0ìo­1U„½Â×Ö¤„´„œ`v⦻…¼Ÿ“®*»)FÆÿ†¿äY±ÿÿ:»$â96qœg“T¼3ÿ"ÍüùÕÉ"—Îóah¹MŒ’©*î=ñ]LÑDÛãÀÉàg9¿DomUÙæÊpAq‘õæm Åæ4² $‚Hü? Y <Þ™ü=7ã?Ê„2Fº…Y”Ie 2ïŒsõ¡n­ÙÖxÊÆ~v0¾ÇÓ¡ªë¦F¹ÄœoÞ  î G\rG¥+éêÊåUUNßî¶àx>´šK¸cH˜¸++VŒŸzO¶A™·HBÁ\±Àô•ʼn¹žY$¸l8`•Ü1Ç8Ç~”ù- JfIBÈ\°%2Wi}(ö»Éè3f5*Ûvs¹Whç=;ÐÚz3ÄKî ÆÁÃÓ¡äPã¿¶}ᥠ(v‡÷ÎzTêë"F Œ29ª?0~Ðv‡îŸ¼§ õéíV¡ŒCÆ1ÁÉÛœNIä“×Þ€,ZIo ´ÒO™ö(Ù¹‰!x­hÛ¥¥Ä+4pFU½P}úÕ +s=³ì“Ë’;1ŒŒ…Gq×½hÚ@¶¶É}ÛrK䜓úÓÿ²ÛÿÏ¿ïU¯¡†8QÖÔ‰£Ö¯dzΪjD}”r>ú÷÷  ˆ¦™ä¸Y­ÂÄ?Õ6ÑÈ¥8õ¦ª¸gÞAÃëN?xÒ”´”´QEQE åõˆ„Þ1¶FéöR æº\ˆåx|SFFﲑϸqýhþ¯ QIoÉÄŸóÝÿï‘Tä;<Àv"€ŒU¯±'üöûä/ØSþ{¿ýò(¥oìIÿ=ßþùãGØSþ{·§ÝX ”b­›ÿžïÿ|ŠO±'üöûäQ`*ÑV¾ÆŸóÝÿï‘þ5JC±dç; žø ÑVÍ‚GžçpQö$ÿžïÿ|ñ  tUϰ§ü÷ûäT¬^$/¹¶à€;ŸÒ€"¥ÅIo›~é … `.{TßbOùìÿ÷È  ´U±bŸóÝÿï‘GØSþ{·ýò(°(«bOùìü²(ûÏvÿ¾E¥kìIõî?à"£žÙb…ä1* ÁP )iÐÇæÌ±Q´¶@ÏLXûÏwÿ¾ET*PÔRl_îÊ®‹ã??ì >™ÿ\ÿ÷È  [û«ùR… rä{Uϰ§ü÷ûàQö$ÿžïÿ|Š©“ëISÜ[¬0—YYˆÇG¨È"JÈ\¨Qž{Ð(ÅZûÏwÿ¾E/ØSþ{¿ýò(-[6H?å»ÿß"° ë;ß"€*bŒU¿±'ü÷ûäR}‰?ç»ÿß"‹V¸ÿÄeñEº®sölñí¸×mqn±@ò,ÌÅFpTs\oˆ.ÓÅM Ê­¡à}:§4¿ºòå;£cŒ§éïÒ¬[Ù„¶óžq…}Ä0ÁÇNj…¼þ|,ê=B€i——|ê¡È^›;(õ*çuá„G° ê>Õ1ÁéÁ­Ö²µdÚb]¹Éå\Þ‰mö½'È(®êL«t8aþwûD³‹hË,›Ð|¬ªv‘–ƒÛßÒ´D/§«ê tÌ›SUS [d¶qŒØ|qNk[kwÞŠ‘gse‰ÁõÏcY²Cn1åÄóùÂG‘[æUòÈÛê}xüiÑi$é—æÒ ¹ H¨NáÔ±ï×Ö˜pŬp¢¢(ÀU Žñ`’ÙÅÈ 76îÇ9ªƒM†kËyd³‰"Ž«!p#qÛµh¼k"pÁ^ÄPd­¥aIe˜F“žpÜ£×5tCnX0r[âF3ùU{‹÷væ6h¢Œ>ï-öœŸç“š¯šé«=ÃÆÎK–Yw¯B¸ÚxÝnèôqÚØGò…‰ Ôã=ŸJ¥ "¦-žƒSÚ±—E‰4d„YÛµÀ*Í•S¼†ÏSí‘øÔÒZ¸Ô,e†ÅQ!R¥†Á´€£Øzt  )fŽ$g‘¶ªŽO¥,2Ç4~dL2FG¨8?¨5¤ZÆoå_*& ŽY†ó¾rÞüt<þB·ãcM¨Œ“©Éýhô´”´QEQEQEQEQEQEQE•÷üyKþíXª×ÿñç/Ò€8Ûÿù´¯÷SÿG-wuÂ_ÿÈÕ¥ºŸú9k» TxD_ùêOýu§G=L¿÷÷ÿ­LYnIÓ팛{“ÈNM5o±-"8i‰ ·8cž0xê2GÐÔ…’xkA‘²þi?õØÓ£ðî…e@멦Ëw,/p„K‘±½NUÚ9#¯?Z»ö»ùãÿ‘Ejœtƒÿ" .+ «õ,Ü9o0 ÂPAÏpMWWQùÏ "É*ƒ1@1„é‚@ëÇ_Ö´>Õ7üðÏý´¿kŸ9òyõó k‹¶¸Q1R¬ì…Bð¸@Ù ßœŠKƒû‹“þÓÕµNå‡þDFψH !oÃ=³@½¶®J‚Ñ$e›÷¬¸ùº€Éö8¨m//.¼¡¹ÑZSó]ÛvnÁÁ sWêbIû8äçý`¤7Sž°äAEÀ‹NEˆ´Š‘ ,S2Nç¯óW|Éd·³iˆÞÒ6qŽ~WÇN?"jCu99ò?ò(¨ÞIfxË @Œ[ïîÉÚ@úuý(¸ÎÒ >øDX>Î œàô¦O-í£Gj«¸OšdRÜpY¶‘ÆO§G’¤aÃ~ðÆ}~µ ºœtƒÿ" ªf¹ó ’YäPÆ@T&yN´Ëkë¯2Þ'uŒ° åøÇ—ÄõëÇáWEÔàñ=üÁL²Èeq‰Ã.ãøõ¢àUŠîéͼ¬òò¤R6²I”Àã±ÁÁúÔM-ÝÌ!¥É&9qÔ1¡žý;Ö‘»ŸþxgþÚŠ>Õ?üñÿÈ‚‹…ŠR^Þ‰DƱ‚¡€älÎG9'>ÝYMöK´‹ðíÚ[+žžÇ5'Úçç÷×QQÍ,ÓBÑy!7 nÞ=踈âìcûý+=çºarî“ùw)" #å]£åǹÁüÅ^Ë$Ë*.ì “ޏõúSþÕ?üðÿ½N9îíÌÎñ¶0™°6¯¿ÅïL7­`bhÿÕ[‡l©ÁFÕõÎw~UíSÿÏüˆ(ûTÿóÀßÁNáb§ÚïäžDÈŒy›>è%ìyãžE5ï/üÛ…R&BåA8ã rsôÇåW~×?üðãþº >Õ>1äqÿ]E+€Æ’F³”LrÉ1@ØÆà`Óá}“ÈOG“ô£–I§M†0ƒ –.CžßJÝ»†Ðz}N+žÔ¬íïüqkov¤ÂÖ¬XŽÏ_º¤šxš#PÜ.? ÜçÇÖ„w³ýJb5úFVLsæò?Jt:‡âŠÙc’L™þ•c&ŒÒ†$H¬‹¹Â‹¹ýûÖ迵ëæÈ×7¡ÿÈ)¿ëîoý ¯S¸·ÛÏOÒ·ZÿÏAùÇæŽɢ㱱öûoùè?*>ßmÿ=äk#Ÿòi9ÿ$R¸o¶ÿžŸÎ·ZÿÏAùÈçü‘þ4séúñ¢ác_íÖ½äý 'Û­ç§èk'ŸOüxúãÃüh¸XÖûu®Ö~”¢þØ<ÏÐÖG>Ÿøðÿ9ôÿLJøÑp±¯öûoùéú>ßmÿ=?JÈçÓÿãG>Ÿøðÿ.¿Ûí¿ç§éGÛí¿ç§éYúãÃühçÓÿãEÀ×û}·üôý(û}·üôý+#ŸOüxúãÃüh¸ÿo¶ÿžŸ¥o¶ÿžŸ¥dséÿñ£ŸOüx_íößóÓô£íößóÓô¬Ž}?ñáþ4séúñ¢àký¾Ûþz~”}¾Ûþz~•‘ϧê?Æ“ŸòGøÑp6>ßmÿ=?J>ßmÿ=?CY?äñ£ŸòGøÑp5ÿ´-¿ç üIÌS#mÄJÄçüš9÷üéÜ,tÙcY#d|íaÍ`ãëùÒ`úš.1õ‹tÀ;mùkº®ÿþF½/ýÔÿÑË]Ý1óé¾dRDÑ’¶ç±“õü)Mß26r³ä®qœ{ñéPÂmÞe?÷÷ÿŽQÿU·üõ_ü‹ÿÇ)X Æ™…‘|·+),à¾A'©ÇùÅ/öv!1yD¡;ˆ-É>¤þòªßð…[ÏUÿÈ¿ür—þ«oùê¿ùÿŽQ`,¶žÍ)‘•Ëóü|.{ëMþÌS ÄoÊ1ùñøÔð…[ÏUÿÈ¿ür“þ«oùê¿ùÿŽQ`-5iÌæ"d$ópHèqê({7ÝæùÂGÿúª·ü!VßóÕò/ÿ¦?‚àØÁ%Møã>n3ÛþZQ`+øg'Ã6 ’X`½ZÞDÿóÂOʲ|2qáÝ4ôùÏþ‡ZÏ©æ’6‰Ø«"¨A¸±`OO—Q‡‘?üð“ò£ÈŸþxIùS—U‚[³oÊyÝþý)‘ëPLUbY]Ø€ªä‚ é€*áäOÿ<$ÿ¾i~Ï?üð“ò¦.²¢å™ èX.ÒKrÆ:öüéÃY·(ω6"os·„äŒ|Š,ìóÿϼŸ•1ÁBC«)8#µÛ6äd¬˜ÞvÝà€w~có¥¾'ÏpG+?S@ !˜Œˆ$ü©|‰ÿ焟÷ÍJ.Ⱥ†ßoß„¾sýݼãߥW¼kæ´›¼µÝ°„?>ӆǮ ?ÈŸþxIÿ|ÑäOÿ<$ÿ¾h¸Õ<¸¤1Dí"G½†Þ‚@cøvͬB‘åÖE}ÛLe~`qžž˜Á¢ÀDÿóÂOÊ£ÁÝ´)/»{楇T†yB |ír¤+aCÐæ£¿ÒÔÿÓs@ò'ÿž~T}žùá'åLþÖ q:JbHàå²ä¹s _í¨Ù Š9]»Û÷vÞŸx~tï"ùá'ýóMdxÈó#dÝÀ$uÿ8¥¨Ê«Å wT+\¹$üü¨šán!µ•3²Gܹÿq¨ ¤¥íEŠZ(”RÑ@ E-”RÑ@ E-”RÑ@ E´”RÑ@ E-”´Q@aH¥¼fSfãÿ’·+–Ö£øÒ‰£HÎK°þZwÙ¥þá¥û4ßܪ?ð…[ÏUÿÈ¿ürƒà»e¼ÕãŸùkÿÇ)Ø´Où7ý}Íÿ¡UÚ¡ Ú*¶ÌòÜÆ¯Ò`RÑ@ E-”RÑ@Q@Q@%-QEQEQEè¡’mÛ §y#ù —ìsÿ~ûé¿Â¡Žà[Ás#0rÇ¡¨F±1p·EvpÎTü¸Èy”wìSÿzûèÿ…7ìsÿ~ûé¿Â©Üj²ù”Pƒ,n-•\äŽÕf+æ{¿³þucŸáÀ!¿qLDc¸#î’>•$PÉ0% 2ÄŽÙì D§;Ï«·ó¥_e´ž]»Š¿Lã$He±Oýèï£þ}ŠãûÐßGü*¼ºœ\$.ˆ[€þ[´œãœczçÚ’=VgUS ¤òö ÿ.8ÉÇÇ¥XûýÚûèÿ…E$oi,7 ¤‘×éî*µÖ«;Gt‘Déå+4@`¹ëŒcœuü*åÙÍàˆßÍh ÿþF­+ýÔÿÑË]Õp—ÿò5i_î§þŽZîê‚’–Š(¢Š))h ¢–’€8¯¾Ó˜œäœöë\¥¡”˽wo ýÀ 3Y^ÿ‘fÇþž?Ú­.?ùæŸ÷È©cØÆÑ2”ÌHÈ„ÉÆ9þgéš!†Êž[€#9@\ax#·lÖ›åÇÿ<ÓþùyqÿÏ4ÿ¾E ì–6³’¼…Ý(ùyÏB3Îiæ#«0pè#mÎ9PIÇ$Ó|¸ÿçšß".?ùæŸ÷Ȧµ½“FQäÜ $ºŒ‚sØAMºq,ó0!¿t2G<äÑåÇÿ<ÓþùàŒ(zŠWKiŒRÙ$Xöƒ€p@È ƒè) 5.RR¬û€"AòääíÎ@ÉúÒlNñ§ýò(ØŸóÍ?ï‘@-lU6#•M»J¬ÀõüÏLS¤‚ÊF,͇,pq@ÛÜzRyqÿÏ4ÿ¾E'—üóOûäPª–ˆâ@ë•rãçx§ô¨ÔHŽXlóÉ϶zÓ¶Gÿ<Óþùì c”ò¶Ñ3#$üÈ Œ1ü©«šõ1Éó¸ÎÖ ‘ÀÝÏ.?ùæŸ÷È¥òãÿžiÿ|Šd¶–ÅŠå’A·3ä€3€:v$sN+ig/½b$g9ãcr(òãÿžiÿ|Šrª¯ÝU_ €’–’Å¢’Š-”PÑIE-”PÑIE-”PÑIE-”PÑIE-”P×1©ÿÈÿ¤ÿÛ/ý×M\Î¥ÿ#ö“ÿl¿ô3T€ôzGûô4´÷èiˆãü=ÿ 8ÿ뼟Ҵ+?Ãßòþ»Éý+B“QKE ŠZ((¥¢€ŠZ((¥¢€ŠZ((¥¢€ŠZ((¥¤ GHÌË4nêøÆ"g`‚¤Ûa½Ù¾Pƒì´däñ·­:ŒPZDò:[;F%ØÚ¹-ž¼íéDR[DÎÉÖçy·“…axQŠlyÚInflŽ ¥ŠTŒJ’Ç#+¶F!g 0`ih V³R¥mYJô"ÍøÿÇiÍ5«¡F¶r¤TÚ9ÝíIEe¦âßf|•ÚOÙ‘é÷zcŠFq-ÀtGTTÛ—BœätžÞ”´zÐ5ÿüZWû©ÿ£–»ºá/ÿäjÒþ‰ÿ£–»º¡Q@Q@Q@4°ÉÇÖP\AÔA(&9U‘€8È#šã<5}a‡¬âŸPµ†DÝ•y@<ŸJÓþÑÒÿè-eÿ…J|¡3kg$œŸÞ·øÑÿ6ÿ>ÿ[üiXd_Ú:_ý¬¿ïð£ûGKÿ µ—ýþ/ü Úüú¿ýýoñ£þmþ}_þþ·øÑ`"þÑÒÿè-eÿ…Ú:_ý¬¿ïð©áÐ?çÕÿïëðƒhóêÿ÷õ¿Æ‹öŽ—ÿAk/ûü(þÑÒÿè-eÿ…Kÿ6ÿ>¯ÿ[ühÿ„@ÿŸWÿ¿­þ4X¿´t¿ú YßáGöŽ—ÿAk/ûü*_øA´ùõûúßãGü Úüú¿ýýoñ¢ÀEý£¥ÿÐZËþÿ ?´t¿ú YßáRÿ  Ï«ÿßÖÿ?áÐ?çÕÿïë/í/þ‚Ö_÷øQý£¥ÿÐZËþÿ —þmþ}_þþ·øÑÿ6ÿ>¯ÿ[üh°héô²ÿ¿Âí/þ‚Ö_÷øT¿ðƒhóêÿ÷õ¿ÆøA´ùõûúßãE€‹ûGKÿ µ—ýþhéô²ÿ¿Â¥ÿ„@ÿŸWÿ¿­þ4  Ï«ÿßÖÿ,_Ú:_ý¬¿ïð£ûGKÿ µ—ýþ/ü Úüú¿ýýoñ£þmþ}_þþ·øÑ`"þÑÒÿè-eÿ…Ú:_ý¬¿ïð©áÐ?çÕÿïëðƒhóêÿ÷õ¿Æ‹öŽ—ÿAk/ûü(þÑÒÿè-eÿ…Kÿ6ÿ>¯ÿ[ühÿ„@ÿŸWÿ¿­þ4X¿´t¿ú YßáGöŽ—ÿAk/ûü*_øA´ùõûúßãGü Úüú¿ýýoñ¢ÀEý£¥ÿÐZËþÿ ?´t¿ú YßáRÿ  Ï«ÿßÖÿ?áÐ?çÕÿïë/í/þ‚Ö_÷øQý£¥ÿÐZËþÿ —þmþ}_þþ·øÑÿ6ÿ>¯ÿ[üh°héô²ÿ¿Âí/þ‚Ö_÷øT¿ðƒhóêÿ÷õ¿ÆøA´ùõûúßãE€‹ûGKÿ µ—ýþhéô²ÿ¿Â¥ÿ„@ÿŸWÿ¿­þ4  Ï«ÿßÖÿ,_Ú:_ý¬¿ïð£ûGKÿ µ—ýþ/ü Úüú¿ýýoñ£þmþ}_þþ·øÑ`"þÑÒÿè-eÿ…Ú:_ý¬¿ïð©áÐ?çÕÿïëðƒhóêÿ÷õ¿Æ‹öŽ—ÿAk/ûü(þÑÒÿè-eÿ–¥ÿ„@ÿŸWÿ¿­þ4  Ï«ÿßÖÿ,_Ú:^ä-eÿ‡ø×7{<>;ÒÞÚxçEh—|lgy8ýk©ÿ„@ÿŸGÿ¿­þ55¯…´6Qqmk‰î˜¶äu÷çð¦ØéM“ý[})À`HÇŠyý…Þ­aj-àÓ%’=ÅÁ’Îló@EXþÖÖÿèÿ’sñ5Üt=ih†þÖÖÿèÿ’sñ4kkôÿÉ9¿øšîh û[[ÿ GþIÍÿÄÑý­­ÿÐ#ÿ$æÿâk¹¢€8oímoþù'7ÿGö¶·ÿ@ü“›ÿ‰®æŠá¿µµ¿úäœßüMÚÚßý?òNoþ&»š(†þÖÖÿèÿ’sñ4kkôÿÉ9¿øšîh û[[ÿ GþIÍÿÄÑý­­ÿÐ#ÿ$æÿâk¹¢€8oímoþù'7ÿGö¶·ÿ@ü“›ÿ‰®æŠá¿µµ¿úäœßüMÚÚßý?òNoþ&»š(†þÖÖÿèÿ’sñ4kkôÿÉ9¿øšîh û[[ÿ GþIÍÿÄÑý­­ÿÐ#ÿ$æÿâk¹¢€8oímoþù'7ÿGö¶·ÿ@ü“›ÿ‰®æŠá¿µµ¿úäœßüMÚÚßý?òNoþ&»š(†þÖÖÿèÿ’sñ4kkôÿÉ9¿øšîh û[[ÿ GþIÍÿÄÑý­­ò?²8ÿ¯9¿øšîh ÔoõûK›«¢1²*…¶‘ÃK5ÞŠ¡öæ…ÿÙfotoxx-12.01.2/doc/images/batch-rename.jpg0000664000175000017500000002730311701011016016701 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 206 350 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀ¥"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmOgÓl™šÖ"Y­Ð’J ’qSÅa¢Ë<°.›cæÅêmP‡§Oj—Eÿÿ^‘è«jùžâlxÔSæIHPõ/þÉÇNäqÓ O°h¿k£M±3lÞTZ¡Ú¾§Ž3ÛÖ›w§iF¬ºVžI8æÙ?¢˜Ò)mÝY/T†¹ÞrÎÇø³ÝN8ôéÅK©œ@ŸïÿCN*ìRÑßgÓÿè§à2…gÓÿè¦ÿà*…&hÍt{4cÎÅû>Ÿÿ@7ÿSü(ò4ÿúéßø ŸáIšLÑìâì_#Oÿ F›ÿ€©þyý4ßüOð¤Í£Ùǰs±|?þoþ§øQäiÿôÓð?›ºÔýœ{;%ŽÊÎ\ùz.žØë‹Tÿ yÓ­ÀÉЬð©ÞÊWM ÿ¬NŸTÓîB]Fî®§šÆM'kFí^æ´Z}´ÊZ-O`8ȶOð¨šÞÁX«húp#‚ ª…héê_O_Ü™H”ÛŽ:Ô±"½å²àúöª´o±7v2¾Íc³ö>·8ÏÙS¯åH–Ö2:¢énXà£'øV“û-Ävê²fÈ .:ÐQ„–Æãû>äùÀ'>´íÀÛîf½½‚;#inTàÿ£'øT£N·h¼ÕÐôò˜ÎEª…XÔxBŠgdÊŒdU›vŒ%§-çyMåŒáO±¥ekØ.ïk˜þVŸÿ@7ÿSü(ò´ÿúi¿ø ŸáZ¶‰´Ýäy¹¼ÐÈüúR ¡Ž/-6¼ ÙÛÎGNiÚ=ƒÞîeùZý4ßüOð£ÊÓÿè¦ÿà*…jM .œK*¶J¸Pþ¦¤‘‘P!‹÷r"t=h÷{åÜÇò¬?è¦ÿà*…'•aÿ@7ÿSü+b¡Y.":Ë€vþ59_>@ŠUwÚœcör]C˰ÿ F›ÿ€©þyvôÓð?™šLÕû8ö'’yvôÓð?Â.Ãþoþ§øTy£4{8öv?˰ÿ F›ÿ€©þyvôÓð?£Í£Ùǰ¹Ù&Ëúi¿ø ŸáV¬l´Ë!“JÓ€Lt¶Oj£šÑÒŽb¹ÿtZšJ-¢á&äM>‘¥ˆ$#K±)ÿ—dôúW×Ñ7?êeÿt×ÎÕÌl{¶Ÿmg£iQÎÎK8ÙU#g$@OÊ÷‡çR&§§FÎѤÊÒÎE¬¹cŒdüµWJÿ]¡ÿØ!¿öÞ¶Þ@ˆ]Û £$æ€3ާ§´©+$ÆDUþË.@=GÝéÀüª+ÍBÖâ5TiÁ žmeôÿv¯­ÜŒ¡’Òé”òÞ¿­/Ú¦ÿŸ;¯ûäRM;‰´Ì?6ùë'þKÿÄÑæÁÿ=dÿÀi¿øšÜûTßóçuÿ|ñ£íSÏ×ýò?ƯždrDÃó ÿž²à4ßüM'™üõ“ÿ¦ÿâkwíSÏ×ýò?ƵMÿ>w_÷Èÿ9æ‘0¼È?笟ø 7ÿG™üõ“ÿ¦ÿâkwíSÏ×ýò?ƵMÿ>w_÷Èÿ9æ‘0¼È?笟ø 7ÿG™üõ“ÿ¦ÿâk ‚àM¸êÈpÊÃT¹>¦—µýœNmeRât'ºÁ:ÿ%¤icr ÜÜ>:o†vÇæµÒäúš2}M/h÷"9Ðùk'þÍÿÄѺùë'þÍÿÄWM“êhÉõ4ý¬…ìâs ÿž²à,ßüE ÿž²à,ßüEtù>¦ŒŸSGµ{8œÆè?笟ø 7ÿFè?笟ø 7ÿ]>O©£'ÔÑídÎ'1˜?ç«ÿà,ßüEƒþzÉÿ€³ñÓäúš2}MÚAìârùƒþz¿þÍÿÄQ˜?ç«ÿà,ßüEu>¦ŒŸSG¶{8œ¾`ÿž¯ÿ€³ñfùë'þMÿÄWQ“êhÉõ4{i³‰Ëæùí'þMÿÄQ˜ç´Ÿø 7ÿ]FO©£'ÔÑí¤Î'/˜ç´Ÿø 7ÿFaÿžÒà4ßüEu>¦ŒŸSG¶{(œ·îç´Ÿø 7ÿGîç³ÿà4ßüEu9>¦ŒŸSG¶{(œ·îç´Ÿø 7ÿW,.ím„¢G™ƒ€>[i}ÿÙ÷­ÜŸSFO©¥*²’³¦“º( JÖëÍ‚'7ÊgÚñ2eF#på‡ç^^ózIÖ Éÿ— Ÿýðj‚pÒ¿Öèöoý·­-SþA—?õÉ¿•fé_ët?û7þÛÖ–©ÿ ËŸúäßÊšÜÁ¨ê¿c¼‚Ò;Y®®'Ê‘*ã',@î)ÒêöPO3¬3Ȉ۪ç 8àsÅQ×-'¿EŠ(,eQ“›–ehÛ³)PH?—Ö³‡‡æ[¥’Y£½WŽ%œÍ4‘’È1¸ÈlõÃ~tÐh5ëu³kBDƒý&XP ÛŒã¯A“V›V±Yá‡í(ÒL¡ãUËeOCÇ@}MsÒè&Dš9¡wŠiÙTË$A’Rå“AàÕË->çNº-eöQo,q¤±³01ìùáÏCн§ë–ú†’Ú„I TŒ»¡RÆxÉàôíQíÉ-”Wma%¼Rùf6žTƒ‘ºX硟ewo¢¾™<–ì©E ¡l•9Á`G‘Ó5h0A£ÛÚZCkè`3H‰·Ì1I$ œàõõ£¨t/Á®Û­¬³ßȺ–ÝÉ-±ˆÎ:ô5i5k.c¶Žå^YT:„‚¤dŽkŸ›A¹3 £šhî'‘Ë$A’R “AàÕˆt«‹{ëI->Ïi *‹/•+“"€~B¤`ŒžœŠkÆs©]¹õ«RÜæþèÿ²ŸÖ­Ò–ãAXßð‘[o™<‰òŒV1…ÌÌfgûÜsZÙ¬=[@„òËÚÆv‚ & žL„ ‘·+߆5#/jz­¦™ë™U$e%ä–ÀöíïUnµ³k¡Ùß´åºòÕcÜB†ažHàsØÕeÑ/í¡…­%µi…¼–ò$…‚f,6°ü¹Ç#;UÓ¥Ëö=&*fÆHÏ?0U âš8u——Q·µòáÝ•ÊÈ[n"Ü uïÛš°ºæ–ÑK"ÞÆR<÷8õÉ㊥.…<š¤·~tA$¸g+Îv4"3Ûï3éïUí|;4/YÏ"F±E#\Ì AÏ ì<6ç‘@¨ZGcöÙ& oŒï`G|tëœö¨¦Õôø Šy®U\”ܤSŒdP>í´gtðÞ\ç%¥‘”}ìœ Ùa±œŒÕ ´ éÒi®c¹¸Š7ŠA$ÒÆ¬¬Ù:òq€9ûPŒzÄ"kórñÇojñªIœïÞ ¯^1R>³¦¥¼S›´Ù1"<K×Ïý+.çÃr»KäI iæA4I¹× í*Hä)9•4E圶÷v+f—²$±<²26ò `äϨæ€Ôµo­ÙÌo±‡ìnË!pBáqóg§~iÿÛZh´ûWÚÓÊßåç;¿»Œg>تäöº…‘žÝ`¹›í¸-½_*v‘ýܯPsÍè·p˜nà[H¯b˜ÈTÍ,‰ +·—a¸{ÑÑïÿ´ôä»ÚªÜ 0€J½T´{9ltä‚vF—{»É\³ž{ÕÚ(¢ŠC (¢€ (¢€ (¢€3/?ä5ýx\ÿèp׃W¼ÞÈjúð¹ÿÐ᯦#Ü4¯õºý‚ÿmëjXÖXÚ7V"±t¯õºý‚ÿmër€)‹)€À½|™ŒGØçÿŸÖÿ¿kW(§ÌÅÊŠcŸþ[þý­cŸþ[þý­[$I Ôš FAèæadTûÿóúß÷íhûÿóúß÷íjås0²)ýŽùýoûö´}ŽùýoûöµrŠ9˜Y[[ˆ7’í#¹Ë1ã5=Rnã (ªöñOx0º1.öPª€ýÒGSô¤2Åϰ\ÏüŸ÷íhûÇüÿÉÿ~Ö˜‡ÑLûÇüÿÉÿ~Ö°\ÏüŸ÷íhôS>Áqÿ?òßµ£ìóÿ'ýûZ}ϰ\ÏüŸ÷íhûÇüÿÉÿ~Ö€E3ìóÿ'ýûZ>Áqÿ?òßµ ÑLûÇüÿÉÿ~Ö°\ÏüŸ÷íhôS>Áqÿ?òßµ£ìóÿ'ýûZ}^âÞâÖÚ[¶4žR(È`qÅYa†#ÐÒ”QEQEf^Èjúð¹ÿÐᯯy¼ÿÔõásÿ¡Ã^ LG¸i_ët?û7þÛÖž£3Ûi·SÇñBî¹é ¬Í+ýn‡ÿ`†ÿÛzÛeWRŽ¡•† °È#ÜRcG'>³ªXÀc’d¸’XmåY|µO/Ìb€qÛ${ÓçÕµ{8"7!7OæÁB’eàÆ[i  ÕÒ›{v5¼$2È1ŽTt_§·JHí-b‰"ŠÖŽ6܈±(U> cƒïM‹S ÛQ¸Ôô]Nip#ŽÛÊ*”!ó?#ÇáU¬µi¬,„7‹qi±Ì(†èXíP¤g9ã8èk©X¢DdH£UbK(PÔ‘ß56VpBðÁgmR}ôH•U¾  çUÕŸO˜–Úö×[%}‘™<½›²vÒrGCÒ6³¨Üj+›µâXa•KQ0~I;˜1è5»ý—¦ùìë?%[xìé´7®1ŒûÔ²ÚZÎñ¼ö°JÑ«g‰X§Ó#€25›ËøïäŠÎå!Xlžä†ˆ>ò Aôª±ë·jö‚æÚYR Q‘«4{¸9Ü{vÅtNÅž(Ù™vÊ +éôö¨¾Ãd.àYÛyè0²ù+¹G 8È¡9˜5 fx “ûB5óíf¸ìàí1¶õèsõ©$Öµ[›¸£²ýö’€9~¹,À€:p t¢ÚÝB…·„Rª`aOP=qM’ÊÎ_+Í´·'ýVè”ùîäqøPôšGüxŸúí/þŒjZ†Æxí`hgÞ¬%vû„‚ @÷  **¯Ûí¿¼ÿ÷í¿Â·ÛyÿïÛ…Z¢ªý¾ÛûÏÿ~Ûü(û}·÷Ÿþý·øPª*¯Ûí¿¼ÿ÷í¿Â·ÛyÿïÛ…Z¢ªý¾ÛûÏÿ~Ûü(û}·÷Ÿþý·øPª*¯Ûí¿¼ÿ÷í¿Â·ÛyÿïÛ…Z¢ªý¾ÛûÏÿ~Ûü(û}·÷Ÿþý·øPª*¯Ûí¿¼ÿ÷í¿Â·ÛyÿïÛ…§ü‚®ÿëƒÿè&‘þû}MC{uÅ”ðC½¤–6E[HÇqS1Ë’=h(¢ŠC (¢€3/?ä5ýx\ÿèp׃W¼ÞÈjúð¹ÿÐ᯦#Ü4¯õºý‚ÿmër°ô¯õºý‚ÿmëjI(šIX" ,ÌN½!Ž¢²§×ì"ŽÚ`ìðÜMåU?)Ú[$c=»U±¨Ù›Ág稆BFxÏ…1¨¬‰|G¦¢ÀñÊeŠY¼è¤…;XçÜ|§¥LÚͤ+3ÝKH“”†,X•Ü8ƒŽÔ£EgÍ­i[Å<—±æRѰ9ÜSÇaS\ê6v¢<ê¾1ŽIaêíÈ  TUGÔ¬’õlšæ1pØ3ÎOAõö¨ÓYÓd¸’¼¤Œ1`;ûÜô8ïHeú*£êV1¦÷¹WÊdŸà=¡}sKHv¼ŒG#Sƒ’GQ޼P#FŒÕ6Õ,X#ûTeî4AyÜCÇoz[}JÊêåí­îc’dÎåÐàýp})o'Ö¢šê(X,ŽCœIý*ZŠÐí¾½`¥ˆŽ3ÔýêC#þзþóÿß¶ÿ ?´-ÿ¼ÿ÷í¿ÂˆµÈL¹¾– áò˜ž7¹`@ÀÁ#’@ëA×aXd2[\%Äs,&Ø…Þ]€*99Î:Óh[ÿyÿïÛ…ÚÿÞûößáVì/£¿¤DxÙÇ$näaÔqV¨:¨§b±¹,H ƒúÔ¹>´]ÿÇå·Ñÿ¢Ã'ÖŒŸZ¥q©Aks2\¼qÅ ++9~FX»Žœu¦ÿlé¿dûWÚãòwùyç;¿»Ž¹ö  ù>´dúÕ5Õl^ãìër¦]Êàð¤g'ÓZ‰uÍ-­Þáoc1#*±êÝ8ëÏoZÑÉõ£'Ö¨Zk:mìâ[Èä‘!FyÇ_ÄzR oLd…ìE`¤9è3ŒûŒñÅhdúÑY3x‡NmÝe2G4ÆÈ ØÁKr:öôïZ ä:iˆl’$H^F £©5Ûíÿ¼ÿ÷í¿Â–ïïÛ×tþt²ëpGzÐf1¤« ÎØ®ÝóžãœcšoÛíÿ¼ÿ÷í¿Â·ÛyÿïÛ…O¤$ÕäÓšÚhÝ#óD·k®qÆzúн@ýÓ+ëî¤m>ä‚;ð׃׹·ü…"öµ¾ÿÑñ׆P¸i_ët?û7þÛÖµÜ^}¤°ùqɽ ì“;[#¡ÇjÉÒ¿Öèöoý·­ÊC9øôV8-ßíï=µÏ RJ ìÞWqêNHö£ûQ“[†òââ)"Ž8~þL¨ØFÁ6õ?{­tSŒ5Ò/`Òt¨`’Ý®´ùüìÁ†d ŽÓµ9t{Ÿ·-ËËü ¦žžVÂsúVÕ_¨Xã5 ½-.>ÎbškȧËÙ!¼Œë´ªž~lp=ø­CL½¸´²[3 70Dí +#ÇÀA 8ämdŽôP¶°[[˜Ø b[‡1Oo4Ë3ožTd`áÈÝãV*úí;OŸÉkH­î"ŽhƒnÃ(ÁpFüNMu4P-'‡5 ¨<»©íU¢·ŠZ'œÆán\ã±8«ÖZ4°ÝÚܲÁFҴʳÉ)rÈÎ2OënŠÆ•£êSGäÉi*¼)û™”®ÒÜ¡Ç<7CŠv‰¡I¦\)”E*B®°ÍçÊ_ s‡å^:àÖí‚¢³ÝöûÝ€òãÀ'?5KQ˜LÒÅ+FìlAÇN´†gE£êé·ö·e®.>ÓG#8VÜ Ž2£šoü#Óµ´’l—xåHT±ˆvŒò sŽý8­\\ÿÏÛÿßµÿ 1sÿ?oÿ~×ü)ˆn‹§¶k"HSÌšS+,yڹ䀭¡‹Ÿùûûö¿áF.çíÿïÚÿ…>ïþ>í¾ü…¼Á$²´Œ …È õéRP.«£O}su,RÄ¢kx¢PÄðVB䜘¦ÜiƒV›Rµ’ÜÉö,qÊX)XB à÷f·(¢ác é3\E«¥Ô±§ö”J‡Ê$ì! ž zÕKmá#(·Yãš2-IJïHÉ8ùÇË×€8äó]\,bÇ£L²ÀÍ,[c½–ààœípFy¬ø|/q™%›ré†Ìò±+¸”9 »žkª¢… wzMéÕeÔm$¶/ö”š4•˜e$ƒÎxÏJÛÚ7cv9ÇLÒÑ@îþý·ýwOçTî4 eÔÞP`ò%gg9óI@:`”^sÅhK•@$‚¤2‘ÔÞ—?óöÿ÷í€+ý—Qÿ„“íÞ]¯Ù¼Ÿ#ýkoÆíÙÆÜg¶3øÖ½PÅÏüý¿ýû_ð£óöÿ÷Âÿ…d·ü…"ÿ¯[ïýxe{½Â,z½º.p,.y=I/ 'ó&¼"€=ÃKÿ[¡ðOüJ§ý»ÖÖãýÇü«Jÿ[¡ÿØ!¿öÞ·(»÷ò£qþãþTê) nãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•:ŠnãýÇü¨Ü¸ÿ•#Ê‚ífcÑTdÓ|Öÿžÿß³@ܸÿ•÷ò¦y­ÿ<'ÿ¿f5¿ç„ÿ÷ìÐ÷î?åFãýÇü©žkÏ ÿïÙ£Íoùá?ýû4ýÇûùQ¸ÿqÿ*a›h%¡˜Ô˜Ï !€ äA Ü¸ÿ•÷ò¦´À9EGr:ìRqIæ·üðŸþýš~ãýÇü¨Ü¸ÿ•3Íoùá?ýû4y­ÿ<'ÿ¿f€¸ÿqÿ*7î?åLó[þxOÿ~Í*Ê „dtcÓz‘š¡yε \õÿ~ðj÷›Ïù Aÿ^?ú5àÔÄ{†•þ·Cÿ°Cí½nV•þ·Cÿ°Cí½nPERQEQEQEQEQEQEQEQEØãÿþÙæ*•·ˆàžXƒÙÝà Ó41Ï MŒêHÇ Hû§¨iN/¿í‘ÿÐ…fiš —œ nÄ’º9•Ùs6©áN$Zb4W]ÒšÐÝ Øü€Û7ó‚}¯áRM«éÐÛÃ<—qçÿTÀçÓ’º]äH·’Ù®´åÛ¶BÂ7Êí<‘ìqQÛéÖ kqi%¬·,¢D”²'ï1Ú@$`NhsûRÇíÂËíQý¤ÿË<óÓ8úãœS#Ö´ÉDæ;ØHKHw`(þžõ‰ƒ"j’Í/—,Nn™CFäcˆþáç¿«[x^dÓšÒVƒ|Qà¸óå“8`Àn£!MoiZÌZ¥ÕôvÅZbdù·.OŸeÿ6ÿõÉ•VÒí¯a»¿»¿û8’é„Ù‚…\u U›/øñ·ÿ®Kü¨`‰måHVòYX"#nf= 2j½ž´·Q†±¼‚Óg˜·*…eõÀ%†}À¤–Ý/-¯í%$G>cluÁ@*ƒZëϦ5‹\ÙFR0‰qº»ãFß— rA8ϨÚ昶‹tבù.þZ·<·¦:æœúΚ‰næò".FaÁÎñê1Xš~‰wo$2Êð‚—Æé”O$¸_,®70É9õ¥±Òu 6ïí6¯g#Iæ$‰#2…C+8*BžpØ#÷ FµÖ·eºŠˆ¤º·ßÊÏR£$Rùææ×M¸`ˇ vÌlkH’Ü$†)"v™â•®%-IŸùg÷?ˆŒŽÕ­rÁi¦[ÎPËÅ *H‡Žƒ!¼ÿÔõásÿ¡Ã^ ^óyÿ!¨?ëÂçÿC†¼€=ÃJÿ[¡ÿØ!¿öÞ·+ž²¹·µm îgŠ:KÒ8POú?Ö§ö¾™ÿA+?ûþ¿ã@hª_Úúgý¬ÿïúÿÚúgý¬ÿïúÿ!—hª_Úúgý¬ÿïúÿÚúgý¬ÿïúÿ]¢©kéŸô³ÿ¿ëþ4kéŸô³ÿ¿ëþ4vŠ¥ý¯¦ÐJÏþÿ¯øÑý¯¦ÐJÏþÿ¯øÐÚ*—ö¾™ÿA+?ûþ¿ãGö¾™ÿA+?ûþ¿ã@hª_Úúgý¬ÿïúÿÚúgý¬ÿïúÿ]¢©kéŸô³ÿ¿ëþ4kéŸô³ÿ¿ëþ4vŠ¥ý¯¦ÐJÏþÿ¯øÑý¯¦ÐJÏþÿ¯øÐÚ*—ö¾™ÿA+?ûþ¿ãGö¾™ÿA+?ûþ¿ã@%„»‡I 8ÈȦù3ÿÏÑÿ¿b¡þ×Ó?è%gÿ×ühþ×Ó?è%gÿ×üho&ùú?÷ìQäÏÿ?GþýЇû_Lÿ •Ÿýÿ_ñ£û_Lÿ •Ÿýÿ_ñ  ¼™ÿçèÿß±G“?üýûö*í}3þ‚V÷ýÆí}3þ‚V÷ýÆ€%0LF ÑÁô@*tUDTQ…Q€=ªŸö¾™ÿA+?ûþ¿ãGö¾™ÿA+?ûþ¿ã@¼ dgŠSo¼04žLÿóôïØ¨µôÏú Yÿßõÿ?µôÏú Yÿßõÿ›ÉŸþ~ýûy3ÿÏÑÿ¿b¡þ×Ó?è%gÿ×ühþ×Ó?è%gÿ×üho&ùú?÷ìR¤ $W–S!_º6€õ¨?µôÏú Yÿßõÿ?µôÌÿÈFÓþÿ/øÐ7Ÿò‡þ¼.ô8kÁ«ÜZîÖëY‹ì×1M·O¸Ý±Ãc懯&¼:˜ŽòÓâCÛXÛ[&7D‘†3uÚ gîûTŸð³[þ€°ÿßßþÆŠ(ÿ…šßô‡þþÿö4ÂÍoúÃÿû( þkÐûûÿØÑÿ 5¿è ýýÿìh¢€øY­ÿ@XïïÿcGü,Öÿ ,?÷÷ÿ±¢Š?áf·ýaÿ¿¿ýð³[þ€°ÿßßþÆŠ(ÿ…šßô‡þþÿö4ÂÍoúÃÿû( þkÐûûÿØÑÿ 5¿è ýýÿìh¢€øY­ÿ@XïïÿcGü,Öÿ ,?÷÷ÿ±¢Š?áf·ýaÿ¿¿ýð³[þ€°ÿßßþÆŠ(ÿ…šßô‡þþÿö4ÂÍoúÃÿû( þkÐûûÿØÑÿ 5¿è ýýÿìh¢€øY­ÿ@XïïÿcGü,Öÿ ,?÷÷ÿ±¢Š?áf·ýaÿ¿¿ýð³[þ€°ÿßßþÆŠ(ÿ…šßô‡þþÿö4ÂÍoúÃÿû( þkÐûûÿØÑÿ 5¿è ýýÿìh¢€øY­ÿ@XïïÿcGü,Öÿ ,?÷÷ÿ±¢Š?áf·ýaÿ¿¿ýð³[þ€°ÿßßþÆŠ(o‰®Q”hñ.á‚DØÿÙkÏwû~´Q@ÿÙfotoxx-12.01.2/doc/images/bright-ramp.jpg0000644000175000017500000002771711701011016016576 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿíFPhotoshop 3.08BIM*resize sharpen resize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 335 238 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀOî"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?çôû®³­¥ìÓÍu䣑–8ãÂ”ÛøHuÓuñÿ_ñ¢ÔãÀVþ¢ëüu~ðí¥ýŠKr‘K<È$Ä£pU=L~ujÊ’Z]½‘p‡1Ê}ŸÂ_ô ×ÿï…ÿ>Ïá/úëÿ÷Âÿ]Öl£ÓuO*ݳ …— N€ÏØò®tí?û7’ÞÜÿ ùϰ¹Ÿw@@mÍiNj¤9Ñ2‹Œ¹N/ìþÿ n¿ÿ|/øÑö Ð7_ÿ¾ük¥‡Ã±É§E3µÄ3,º»! ¬qÈüEX>Ó]ŒpÜÞ Y`Mê¸Þƒ'>Æ­¤‰9/³øKþºÿýð¿ãGÙü%ÿ@Ýþø_ñ®ŠçDµM5¥†k´GiËïQåÝëš±§é¶º†‰§Á/›ÒÍ(I#@@ gç=qNÁs•û?„¿è¯ÿß þ4}ŸÂ_ô ×ÿï…ÿé-tëH.t…ó&k›¦W9U1…ÜAë×¥Mmáè.ci¤’ä´¯6$#ØO éžÂ•¯Ùü%ÿ@Ýþø_ñ£ìþÿ n¿ÿ|/ø×U§Ú\é¶ò!xîaÓ’rFÇ]Ä÷ÝKy¤é²kò[F·0Gl›@ÁÂòçõÍ; ¹Ê}ŸÂ_ô ×ÿï…ÿ>Ïá/úëÿ÷ÂÿtñxvÚK§aq1µû*\ Ê«ÜI!GJd:¤“_CÔ—2Àr•Æ3žx8è@¥d9¿³øKþºÿýð¿ãGÙü%ÿ@Ýþø_ñ­KL‚ÛKµ»µyf€LˆÎÜ}à~µþ”’ÖÝ–I ™¤$YYÜ9CŠv œ¿Ùü%ÿ@Ýþø_ñ£ìþÿ n¿ÿ|/øÖüZv›-åàÝ~¶ö4¹T;`8튒ÓBµ¹´Ì÷"[±#Á„'÷Ï©ö¥d9ö Ð7_ÿ¾ühû?„¿è¯ÿß þ5Ѧ‰bÖ¶Sýª_*R¢y]‘Ÿ”Ž ûž)lôÕ·ñladHØnS0WÜ žxÊ‘NÈ.sgð—ýuÿûáƳøKþºÿýð¿ã]-¦‹§É§Gqs=Ø‘­ä¹a\mVÁ=êx|1ÞI =Ï’Û<™²Š>eÈ’}…+ÉýŸÂ_ô ×ÿï…ÿ>Ïá/úëÿ÷ÂÿtÃð.IÞK†•mž}ê£ÊN6ç®j=WB·°ÓLÂ웄Tb¬Ë‡ÝýÐî3ÜsEïÙü%ÿ@Ýþø_ñ ÛøHuÓuÿûáÆŸÏ¿ë]†ôKkë1st°Èò©yüª.p=yÎk*õU$´»eÓƒ›9ϳøKþºÿýð¿ãA·ðë¦ëÿ÷ÂÿhkútzV£Û•ò¥ÀÄgåäd­o è_Ø¥ÄðÇ<³'š^B©û Æq‚k)b¢ ¥gw¥¼ËT›•¯§s˜h|"ªY´íx($ªàγ5øcѵºD³ÃG"’ÿ6C`ãð­ÏX&—,ÑBÊctteBJ«'ÈÖ/Œä-oÿ^6ÿú-kjuHó"%c¢ðî’uCÜý¢¿2‡ò÷òLdzÖ…­õ燼¸.UÏ”¥#™T”‘qô>ÞÔÿȤ?ëåÿ®ˆ1^„¥gZ”jY>…Bn;xÒ/õÙEËNÖ0ÇŸ-ž-Í!<´‘Žþõu|?«££¯‰¤ ~Zh>TþïÞé]“æ# ÄuÀÍ&ÿöþù5Tâ©Ç–; O™Ý˜_Øšß’°ÿÂS7–˜Ú¿eéüTƒAÖUƒÊ;HÙÞn§ïu5½¿ý‡ÿ¾MÿØûäÕÝ“cÿIÕï­â·}Ë·Š$ŒE¯ÊÛF ¿_Ò¡‹AÖ`¶kh|Q,p¶r‹j9ëüU½¿ý‡ÿ¾MÿØûäÑv9áá½P<È>ç]¿{¥=´=i•x¦bJ.mG FûÞ•»¿ý‡ÿ¾MÿØûäÑv0cÐuˆ¥Icñ<«"F#V£„ït§.‰­¨—oŠf_8æLZ˜ôÉù«sûÿ|š7ÿ°ÿ÷É¢ì,s÷Õ®bH®£ùSé‰÷¤úåO¤0¢Š(¢Š(¢Š(¢Š(¢Š(¬{.Æ_Z]Éoºq Ê{}ähöœgdÖÅR“þC–¿õë?þ…]¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(’t_÷×ùŠóOˆ?ò4Éÿ\£ÿÐkÒäè¿ï¯óæŸäi“þ¹Gÿ ÓBg[àù‡ý|¿òÐ×=àù‡ý|¿òÐÐÁ O½'Ô*}1>ôŸQü©ô†QEQEQEQEQEJOùZÿ׬ÿúUv©Iÿ!Ë_úõŸÿBŠ€.ÑEQEQEQEQEQEÉ:/ûëüÅy§Äùdÿ®Qÿè5ért_÷×ùŠóOˆ?ò4Éÿ\£ÿÐi¡3­ðüŠCþ¾_ù èkžðüŠCþ¾_ù èh`†'Þ“ê?•>˜ŸzO¨þTúC (¢€ (¢€ (¢€ (¢€ (¢€ ¥'ü‡-ëÖý *»T¤ÿå¯ýzÏÿ¡E@h¢Š(¢Š(¢Š(¢Š(¢Š(¢Šdýõþb¼Óâü2×(ÿôô¹:/ûëüÅy§Äùdÿ®Qÿè4Ð™ÖøþE!ÿ_/ü…t5ÏxþE!ÿ_/ü…t40CïIõÊŸLO½'Ô*}!…Q@Q@Q@Q@Q@R“þC–¿õë?þ…]ªRÈr×þ½gÿТ  ´QEQEQEQEQEQE2N‹þúÿ1^iñþF™?ë”ú z\ýõþb¼Óâü2×(ÿôhLë|ÿ"ÿ¯—þBºç¼ÿ"ÿ¯—þBº!‰÷¤úåO¦'Þ“ê?•>Š( Š( Š( Š( Š( ¹‹Û VOYÜErËhržq"²o÷ÊñÞºz¥'ü‡-ëÖý *]¢Š(QEQEQEQEQEÉ:/ûëüÅy§Äùdÿ®Qÿè5ért_÷×ùŠóOˆ?ò4Éÿ\£ÿÐi¡3­ðüŠCþ¾_ù èkžðüŠCþ¾_ù èh`Žg]ƒÄ’k¶ŒÄZ…_3ç@7gž ÏLVÓ&©¸â{gþy?øÕ”ûÒ}Gò§ÒKf©ÿ=ìïÓÿ5Oùïcÿ~ŸüjíKf©ÿ=ìïÓÿ5Oùïcÿ~ŸüjíKf©ÿ=ìïÓÿ5Oùïcÿ~ŸüjíKf©ÿ=ìïÓÿ5Oùïcÿ~Ÿüjí…­Ãâ'°Æ5¹Ÿxâ!±±ß—8©´¸µÔÓ [Ù­EÀÌ)fÎ㌕8 ÿÈÓ'ýrÿAªBg[àù‡ý|¿òÐ×=àù‡ý|¿òÐÒ`†'Þ“ê?•>˜ŸzO¨þTúC (¢€ (¢€ (¢€ (¢€ (¢€ åïµ[è¼qggº4‹”bv»&ãœãŒ ê*œŒ·-FN>Ë?þ….QE (¢Š(¢Š(¢Š(¢Š(¢Šdýõþb¼Óâü2×(ÿôô¹:/ûëüÅy§Äùdÿ®Qÿè4Ð™ÖøþE!ÿ_/ü…t5ÏxþE!ÿ_/ü…t40CïIõÊŸLO½'Ô*}!…Q@Q@Q@Q@Q@R“þC–¿õë?þ…]ªRÈr×þ½gÿТ  ´QEQEQEQEQEQE2N‹þúÿ1^iñþF™?ë”ú z\ýõþb¼Óâü2×(ÿôhLë|ÿ"ÿ¯—þBºç¼ÿ"ÿ¯—þBº!‰÷¤úåO¦'Þ“ê?•>Š( Š( Š( Š( Š( ©Iÿ!Ë_úõŸÿBŠ®Õ)?ä9kÿ^³ÿèQPÚ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€'Eÿ}˜¯4øƒÿ#LŸõÊ?ý½.N‹þúÿ1^iñþF™?ë”ú 4&u¾ÿ‘H×Ëÿ!] sÞÿ‘H×Ëÿ!] ÄûÒ}Gò§ÓïIõÊŸHaEPEPEPEPEPT¤ÿå¯ýzÏÿ¡EWj”Ÿòµÿ¯Yÿô(¨íQ@Q@Q@Q@Q@Q@ “¢ÿ¾¿ÌWš|Aÿ‘¦Oúåþƒ^—'Eÿ}˜¯4øƒÿ#LŸõÊ?ýš:ÏŒø@žn¡ö·¬p¸uyÉß™Ø~DÖ/€?äRõòÿÈWCC1>ôŸQü©ôÓ’O9=pÄRykþ×ýöÆÇÑLò×ý¯ûìÿZÿµÿ}Ÿñ ÑLò×ý¯ûìÿZÿµÿ}Ÿñ ÑLò×ý¯ûìÿZÿµÿ}Ÿñ ÑLò×ý¯ûìÿZÿµÿ}Ÿñ ÑLò×ý¯ûìÿZÿµÿ}Ÿñ ÖÖ±gŠí,ŸÎ14@8Ý#G·ŸÀÖÏ–¿íßgüjÓl^énžÒ&¸R ÊÃ.éƒ×еE3Ë_ö¿ï³þ4ykþ×ýöÆ€E3Ë_ö¿ï³þ4ykþ×ýöÆ€E3Ë_ö¿ï³þ4ykþ×ýöÆ€E3Ë_ö¿ï³þ4ykþ×ýöÆ€E3Ë_ö¿ï³þ4ykþ×ýöÆ€E3Ë_ö¿ï³þ4ykþ×ýöÆ€ :/ûëüÅy§Äùdÿ®Qÿè5éQˆ¤E‘ e8e;Éõ¯5øƒÿ#LŸõÊ?ýš:ßȤ?ëåÿ®†¹ïȤ?ëåÿ®††d±™h–H÷£ÆPE$1ƒ<Òç¼›xúm¤¢ÂŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ™,k4e¸ûŽTþ`ƒO¢€+ØZ-•¤pf* ]˜í“Àöç?äi“þ¹Gÿ ×§W˜üAÿ‘¦OúåþƒT„ηÀò)úùä+ $’psþÿ‘H×Ëÿ![W¡«l‘‚@î3ÏéI‚'Œ‘Éç¡#Šs’0ÆMfÉu¶ÐE,.>d›d3ëŽÃ¥]¸c¸b¬Ìªr©8=*º-«1^Aå ¸…IíK¢Cò8q’¤ŽÄu… Òʬ]‹Ä“Bàï/·$äè8íZz_ *C-Ĺ݉¡§a\¿L’ThmŘáUT³1ö“O©ô¹bƒT/9 -ˆÍÐäŒûñùSU%Å ÈŽvI#c׊}^Ö&‚ií–&Wx™™ÊœáJŒû±Sø{V-ø‘¤´DY&Úå6±ëõ„\¦ù‰æù[†ý»¶çœtÍb‰oþÛ*¬ª$Vm±;œ²ãŒ.Ü{çuK¥ú‰ušYOÙ€Éü-¸d{}(°ôÙ#Bò0UI§RHî­¥”f(å ügð8?…!‘‰Áe ñï8S,. $ Ôµ©­\[Ë¥MJ,ɶ ¤»ø[ð89íŠÅÔžU´¸’Ôf@¬Pc4Þ‚DÔVÎÒ-ÊZÝÏ,aàPäüÃqù»qRJ׉©˜VpYDBYïðî9ÏqŠ,6h®yg¿1LÆãlO™r]Nጠ ÌÖµ—˜“ÝÀîìgäà®HÏ~h°é’Ê‘.ç8à2Iô¹§ÓìäŽRÞiÈ€ÊôV8Áöî?C YC8FIcr ,M8ëÀf$‰†‘‚@É8äðjkSÛË 0ÆêòùÈãiÎÕ>Ù\ÇÏk#6,ʱ’ËÔ Ã&˜‹­"#"»Îp ÷=¥:±ãykw/$-ÙHã’¥ü·f› ÕÓˆ¢î#†_1û¹þ”µEfhï<ža–u‘v¯Ë¼³+wÎUqô­:+Ì~ ÿÈÓ'ýrÿA¯N¯1øƒÿ#LŸõÊ?ý„ ë|ÿ"ÿ¯—þBºç¼ÿ"ÿ¯—þBº!¨mÁPiwcu†7zÉúõè A›8éÅ:ŠV …F ÑE0PôQE.N1“J '©&–(å™a@Û-–éüKö+¿ùäŸ÷ðPtéSý†ïþy'ýü}Šïþy'ýü\\íU\õÀ42«©VR0G­Nlî€$ļzH*`Êt#"€QÀ¥a@€òqÞ¤€N)9,ª£,Ä(¤Ôßb»ÿžIÿE¸úšLÔÿa»ÿžIÿb»ÿžIÿ ¢Ÿ,Á’XÔ #$88¦P1 0ªª ”AÅPäç94dã8¤¢€’z’i(¢€ óˆ?ò4Éÿ\£ÿÐkÓ«Ì~ ÿÈÓ'ýrÿA¦„ηÀò)úùä+ziR^iN³jÁðüŠCþ¾_ù ܹnm¤É "•$v¡‚"ŽíЇ¸íѰ¹$œÐóN’öÚ0KÉÒO/wc8À¨dµ¼š.iá%J²2©å”‚ ‡j!±•dŽY%Bâá¦` ã•Û@­Ý»*0”bBBûã9ü°imî๠äHo^1ô?J«ý˜­=Ë<§Ë•X"÷ ¸þ8ýMIadmwÚÎT q$ŒHïÂŨI%¢ÝqNV’AÎN;dÔ‰¨D-üÛ†æG@I;IÒ¡HŠ-9mãXRo—|ª˜/†Ï=é$ÒÜíe”nI$eùÝW9Á*A¦ø§ŠlùN=J’¡¶‰ ŒD6ÔŠ¹ãד֦¤Ö²kŸ¤û=F5Á°\}š_±–Ú'ÈÇ\gqžô–|Ü]ýØ¿öz¯ý—9¶&æ?±Óió6ç;sÓñ¦šqjÖ’Üxç@Åq‚2GPCQÿmØ‘…Êâ>Xàúã^xâ³­të–l\²$ u,ȃŽzcšŽ-¥°‡ÌBP*Ç!’F!C¤:v¦#n Øn£/îPvž úzVm·üzÃþâÿ*µ ¹Š{¹Kç¸p=01U-9³€ÿÓ5þT˜ÉTížÜÿÓdþu<š£-ÿØá·i]P;áp #ŒõèzUWâ[úìŸú¥Ôl&½!C[ª ‘”ù‘ŸU=¨@]}ZÒ9$æÚÑ‚Ì ‘ÀëŽ9ü)Òêv±oó&Q°)n¿ÅÓóÅe¦•)½ó®n<èÆÿ¼îI 1¤íöÁ¢·Ø„Os¾q*Éæe—!FÕRãÐõ&€4.®ã¹ÓL°¸tfPÿxT'­1íÅ®–c  ™›k³d—å‰&žzÐÁQHaEPEP^cñþF™?ë”ú zuyÄùdÿ®Qÿè4Ð™ÖøþE!ÿ_/ü…t5ÏxþE!ÿ_/ü…t40AEÿ“F§ê) (£Óõ`úãÃüh¢Œ7÷Gýô¿ãFû£þû_ñ Š0ßÝ÷ÚÿoîûíÆ€¶E‘¤†_,¸²»ÆqüÍ.ë¿ùúOûóÿ×§a¿º?ïµÿ0ßÝ÷Úÿ7ußüý'ýùÿëѺïþ~“þüÿõéØoîûíÆŒ7÷Gýö¿ã@ &ì‚ ÒóéÏó¥DXãT_º (ú vû£þû_ñ£ ýÑÿ}¯øÐ$Bàaв°elgŠ]×óòŸ÷çÿ¯NÃtßkþ4a¿º?ïµÿnë¿ùúOûóÿ×£ußüý'ýùÿëÓ°ßÝ÷ÚÿoîûíÆ€#užPiÃ&A*#Æpr9Ï­IFû£þû_ñ£ ýÑÿ}¯øÐEoîûéÆŒ7 ÿ¾‡øÐE>Ÿøðÿ0}?Q@séúŠ(¯1øƒÿ#LŸõÊ?ý½:¼Çâü2×(ÿôhLë|ÿ"ÿ¯—þBºç¼ÿ"ÿ¯—þBº ¢Š) (¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠBqŽ $à9&¤òn?çÖûöiŠvÜ[ŸúlŸÎ­O«Aop`u™œ'˜Û"f ¹ÆI:S“qÿ>³ÿß³G“qÿ>³ÿß³WÖúÜ“yÑùr «V¼…d´¨®Ý°Éü(°\Ïòn?çÖûöiœ†*ÊÊê°Á¦n£ùFDóÎÜóùVuÃn¾—ýÕþ´ÂqŽ $àÜÔžMÇüúÏÿ~Í1NÙà?ôÙ?ô!W.58-¤HŸ{Èà‘h]°:œÔ[ɸÿŸYÿï٣ɸÿŸYÿïÙ«ñÞÂåTH¡ØnÇ §ZtwÊYc•¯P¬(°\Îòn?çÖûöhòn?çÚûöjñ¾·ØÏçŵN Þ0 2;å–îXÆŠÛ»ÙÆ?*,(ȯ2øƒÿ#LŸõÊ?ý½1L‡ÖWÿÐyŸÄùdÿ®Qÿè4 g[àù‡ý|¿òÐ×=àù‡ý|¿òÐÐÁQHaEPEPEPEPEPEPýlõÙ?ô!DÑ^Gª=͵ºÊ¯ÇÌvÄóžqÏj$V`¥ Ž®¹ésOûMçüò·ÿ¿ÿÄÓOû*h#¶ W~\NŒŽB€Ìs¸g·QëŠkèóýžT"9eû,QG!#;Ô’NON¢¯}¦óþy[ÿ߯ÿâhûMçüò·ÿ¿ÿÄÑp±Wû.S¬=ÄžkÆÓ,ªèñ€¸`åwcŽÇÕ™útÿî§õ¥ûMçüò·ÿ¿ÿÄÓHd’Yv‡|p¼€Ä×xÿô1Nš˜uymÌ$ˆDè\)9Çs‘ô¦Ê¬ÁJ]sÓ ƒý)ÿi¼ÿžVÿ÷ñ¿øš@T–Îþ}J)å@ª’£¬˜UN7סÅ6-"d‚Ý$N –9HÎ[§Nµwí7ŸóÊßþþ7ÿGÚo?ç•¿ýüoþ&˜fÓ®f†Ø-ªÁösƒOï>\dn~c5kL±’ÊR6·”`DÜ3 àã¿n8©>Óyÿ<­ÿïãñ4}¦óþy[ÿ߯ÿâh¸XŽ”oúë'þ†kÍ~ ÿÈÓ'ýrÿA¯K‰ qíb X‘Ó$’y§Äùdÿ®Qÿè4 g[àù‡ý|¿òÐמøÅ«áÍ=ôË4Ï$s1cæàÓ=«OþU·ýýþÿëSh¾Šä?áe[Ðßïþµð²­¿è?ï÷ÿZ•‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_Erð²­¿è?ï÷ÿZøYVßô÷ûÿ­E‚ç_^cñþF‰?ëŒú oÿÂʵÿ ÿßßþµsZ‹Ýx¿^–}:Ïky@˜Œƒ€0:œzŠiXÿÙfotoxx-12.01.2/doc/images/grid-lines.jpg0000664000175000017500000003001411701011016016401 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 250 343 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀÈ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êt}'LmÁŸM²fkX‰-n„’Pd“Šš+ YåtÛ6oSj€€z:óìjmþ@ZwýzEÿ  ­«f{˜`±ãQO™$í ÉöN>ïr8éÿ°h¿k£M±3lÞTZ¡Ú¾§Ž3Û×Ò’ïNÓ Yt­<’qͲ…;E1¤2[²²^! råñ纜qôÇ©u3ˆSýÿèiÅ]ŠZ#;ìúýtßüOð£ìúýtßüOð¤Í®fŒyØ¿gÓÿè¦ÿà*…'Ùôÿúé¿ø ŸáIš3G³AÎÅò4ÿúé¿ø ŸáG‘§ÿÐ'MÿÀTÿ LÑš=œC‹äiÿô Óð?Â#Oÿ N›ÿ€©þÝÔn§ìãØ9ؾFŸÿ@7ÿSü)Émbì4}9˜ôÕ?™ºŸí”cü©8E+Ø›d¿Ù°ÿÐ Çÿü*?²Yù¾_ö.Ÿ¿û¿e\ÿ*ÂŽfÇÝv8çÚºM>á$¹b­·|A#cÇ!@þ†²‹O¡£ºêC5¬ót]9sÓ6©þ‚ÒÈÂÒ#LÚ¤þŒŸáZZyR[ùà™¶UŽGJ]e´–YUïTª]£Ø›²°´²0´£HÓ6)ÿ£'“ì¶~W›ý¦ìÎÜý™:þU¥| ØÏòF±—_,¦90Ëq¤í…w0›8ϵ F×°6ïb£ÚÙ$i!Ò4ͯœ£'o™åXÐ#MÿÀTÿ Ó‚%V³Wwf@Ù’3Ö†V·–T@î€xã¥`÷»™^U‡ý4ßüOð¤ò¬?è¦ÿà*…l*»e¥[Ë%Tí>¸Î+"–yr¶Œ¯CN1‹è&争åXÐ#MÿÀTÿ <«úi¿ø ŸáLÍ«öqìO;åØÐ#MÿÀTÿ <»úi¿ø ŸáQæŒÑìãØ9Øÿ.Ãþoþ§øQåØÐ#MÿÀTÿ fhÍÎ=…ÎÇùvôÓð?Â.Ãþoþ§øTy£4{8öymmôù®R6Òtà=-SÓéZ#HÒˆÈÒì?ð?³ôÓþŸãüm§ÜSüÍaV*/Cjmµ©â6Ž8<]¤Q«.ÔE Ƚ¢ãÏùµ÷×ÿ@Z+2ÏXÓïí­4}*9ÚMòYÆÊ©9!Q?(?ÞJšžŸ;G™s‘g.Xã?/¥UÒ¿×èöý·­ÜŸS@‡SÓÚT•£¸2 *¯ö9rê>ïNåQ^j·ª©¸R<ÚMéþíldúš2}M ÙܹÍùÏI¿ðoþ"2ùé7þMÿÄWI“êhÉõ5§µ‘Î'7æAÿ=&ÿÀI¿øŠO2ùé7þMÿÄWK“êhÉõ4{Y³‰ÍyÿÏI¿ðoþ"2ùé7þMÿÄWK“êhÉõ4{Y³‰ÍoƒþzMÿ€“ño‡þzMÿ€“ñÒäúš2}MÖAìâs[áÿž“à$ßüEá,àŽA³‚?ñÊér}M>¦k öhæÚuu*÷WŒ§¨hn?øí7t?óÒoü›ÿˆ®›'ÔÑ“êi*l>DÎc0~_ü›ÿˆ£tóÒ_ü›ÿˆ®Ÿ'ÔÑ“êiûY ÙÄæ3s¾_ü›ÿˆ ˜W—ÿ&ÿâ+§Éõ4dúš=¬ƒÙÄæ3÷åÿÀI¿øŠ3üô—ÿ&ÿâ+§Éõ4dúš=´ƒÙÄåÿqýùðoþ"—0ÿÏIðoþ"º|ŸSFO©£ÛH=œNc0ÿÏIðoþ"“0ÿÏIðoþ"ºŒŸSFO©£ÛH=œN_0ÿÏIðoþ"ŒÃÿ=%ÿÀI¿øŠê2}M>¦m öq9ÜÿÏIðoþ"ÜÿÏIðoþ"ºŒŸSFO©£ÛH=œN_÷?óÖ_ü›ÿˆ¤ýÏüõ—ÿ&ÿâ+©Éõ4dúš=´ƒÙDç,æ‚Þå%g˜…ÏÒoO÷+Mu{-È›§MîKÛÈ£s6É\ ’ãZ>¦³õ¢~Ç'þ?mô|u““»*1QØñÿÈå¨ÿ¾¿úÑG?ärÔß_ýh¤3Ô´¯õÚý‚ÿmëv°´¯õÚý‚ÿmêzöâßT-î¥K`ŠoЍ>Bnù\Äò^=¨£¢¹ß^^ÚÄ$¸žÚΗåXîöÉp¸<É…n‡ç¦EgßêÒ‹Û“ ýÄWK»ÙÙ°”°ÉV\dž™ô Ê™$‘Ä•Õ!AcŒ“ÐW0ú´çÅ©m …GÚ /nóä²ì'po œ|Û¿ ŠÞü˦Àí¨É. ×}ªÇî “Bãåô¡j:ú+‘7š”8»‚æiåšîêà§Ê¦2*>µkÃwÂçSš(µ9o£qÈûÈù%,C 6ý;Pµìt•^õ˜G£2J¨XuœqV*µïü»×Äú p{%¸µŠi#2j£$H9ÁÅIfö×w K~¥³ËH1P\91ß!ÆÕ¹ì?ÚjѲ-öÓæÝ–ÿGÿwiéíŒWD¢”LSm“ÿe§üýÝÿßÏþµE-ŠÃ5¸7,$«“¶Æ?Ì Ôªwùßk´€|Ó‚Få›Ö5±›iuiwtÐFבƒŸ&g'dØë°÷ÇëÔdUøÉoÕãV?R¦¬ò±¸³ØD{À¨´ÿ+úäŸú©-Q@Š+žÕ.o¢ÖWO‚Wý£07hÂÊ3Ž>QúÐ#¡¢¹OP»¶Ô­úXâÜBýŽÒç.Ù`È7P1޼Ôš”­¬˜âÔ%žëûFHd³àªÀ3ócç>Ô֠ζ˜ÒF²$lêóµIå±ÉÀï\e®·<º³»}’IV›Îx\0Ú6œòäÕ彈Í`týMïP­Áy«Â,ã§ö :Øê(®0Þê–1•¾¸\YE<’8 ÐåÔ;/•‰Çµlønén´DW¯yoÈHev JùjO sÉ4X.mUyƒKw¿˜èŽ˜¡Áãgñ«üÅmÜ“úR/öbÏÍ×ýü£û1?çæëþþVí³Ãy¯‹/4Ï%Š8;‹1bdééìYðØ´ûuáÒFåDÀBy¿6ì{ãn}úÓB¹§ý˜Ÿóóuÿ* má¶•Œ·3ˆR‘‹IÓsùV­Q»fKÅep¤By+»ø‡lŠÎ·»†{yåŒ^A4 d\p];6=>£Ú¤×-b—Ö¿úQIw,gp èãÊbBÆGP{î4Íwþ=¢ÿ¯ë_ý(Ž€<{ÇŸò9j?ï¯þ€´QãÏùµ÷×ÿ@Z(Ô´¯õÚý‚ÿmë{$t&°t¯õÚý‚ÿmëv€:*­â†æ{ˆÃ n6ù‡=väçRÑHbîlc'Z77÷çIE#åÑ”³Ã«YØAfòIM$²­$Ò™ÐdöäÕª(¨.¢yQ x-‹ àã5=Cs#Æ‹å€]ÝQwtœfšRKU’F‘´Æ,ÌXŸ´¯SøÓ­áû4ÂXtÂwûBš·öKÿùü·ÿÀsÿÅÑöKÿùü·ÿÀsÿÅÕûG±<ˆ_¶]ÿχþGJŠinçh³g°FÅ¿×)ÏÊÃúÔŸd¿ÿŸËü?ü]G$W±É µÔJåx€Œ|¤ÿ{Ú¦þEXhYÁb¶ÊºëÏÖ§‰<¸c9ØŠ¹õÀÅW†S=ÔöÐj6²Ïo6!Êç¦~n*ÌOæE€`:†Ç¦Fj@uQ@«­”+|׿¼iŠíœƒŒíp3V(¦!C0 ¡¶·ŠÑ$HU’F•9Ë1É©h ,Ç«ÎÍýãùÒQHc.#ûD-I*þ(Ü«¡¥¤6q²C¼ïrîò9vvé’O^…OE ‹"ÜÃq‡1†3‚Aô'éST<¦x­à(¯&Nçn3ùÐÿk›þ|ßþþ'øÑö¹¿çÍÿïâGöKÿùü·ÿÀsÿÅÑöKÿùü·ÿÀsÿÅÓ'ÚæÿŸ7ÿ¿‰þ5^f¸–q ¶*Á‘}Aõö©>Éÿ?–ÿøøºÊ½[]AÊÈ€úýïz¡•âhD+>A;‡êp:šf¸sk õ½µÿÒˆéÐ] íeº¶¾¶ºŠeF„`¯QÇšn¶1kô½µÿÒˆèÇüyÿ#–£þúÿè E<ÿ‘ËQÿ}ô¢€=KJÿ]¡ÿØ!ÿöÞ·ppp{dV•þ»Cÿ°Cÿí½n0 ¥OB0i ÁÒ5Û‹Ô¼y­Ã}Œˆ-Ô»Hù9uûœqïžxåé«Ý¼W÷Þ\Ige¸YOœåP7\ázã5« ­»#AFcˆB…F0ƒ¿JaÓ¬ïÛ ²} ŒFî1Èèxõ F,úæ£gÂé-ah·q´[¶¨,«dó÷¸#çS^ê·ÃU{ AlŒnc…d•€ 9$3÷}«JßJÓ­aš{(R9†Ù.CCžÜž:R[i:u¦ß³Ú"q"œ’C@9'БO@ÔÈÒµ CPÖ—÷±B‰lÂhŠVe™”9Î:œ×ITΕ§ù‘IöHÃÄÌÈà ‚ÇqïÎO8«”t¡Uï:Ûÿ×ÄάTjÅbeRÞ\¨ä“€y¤2µÃÜ[kÂ[·º“H‘Àc‘|°ÄteëÉï[••åé_nûi¶sqœ‡0ÈpqŒŒŽõoíöÿôÛþü¿øSjª_²Z2D§_ݽ/Ûíÿé·ýùðª÷wQÊÐyk1Ù!'÷/ÀØÃÓÔŠdPà Db±XÌ[¶0eÊîå»ó“Éõ<Ô–Ÿñçoÿ\“ÿA™kckit×GtÇŸ.6F)zìã?çµ C´(ßy#U?P¤”QE Šé¦[YZØ)˜!(dŽ3RÓ&Y'XdXä#åf]ÀR23ùŠÅ±×Þí̉k,¶â8³äÆY–F°<ðÅ1uCûj…-v\:GmÍ”- @]³Ï\ô­M/OM´0£w‘¥•ÂíÞìrN;ojA¤i ÎE”X¸J¸;_<ž:uô¦#=5‹ÈïÊå-ÚT¾ŽÚY#++Æ\ ÊžÁ'õªßÛzœÒH¶Ëf¦%¹vóŽá›@<;óô­¡¥iÂÄÙ}Ž/³3o1óËg;³×<sšXtË t ¬h¡8ÏÝc–{žh;Bº»¾Ô/çiÓ웢+ !,»¡Fá³€2Ojܪ±i¶0Ý-Ì6È“*îGÊëƒÇj†*ùŠÚÿ¹'ô©ê 3í¼åXÆ•Š©$d p>”†VÓžâ aàÔë͘ÊðæEh™p‚}ër²­cÒ¬çyíí%~ ù2Œç#ô«o·ÿ¦ß÷åÿ˜‹UBô¸1¼~b< ¬¹ÆA#5/Ûíÿé·ýùðªw’Ãs)VŠY"h™[$qÓÒ€p‘¥µÃÇf±1·1–R£åà`ƒµ&»ÿÑ×õ¯þ”GU-¬"·‚hàRË2”ó' H^Ë’8QþsVµÃ›hˆï}kÿ¥ÐøóþG-GýõÿЊ\™8àƒ‚8ã¨í@¨¢ŠC *½•¨¹·2É4ûŒŽ>W `1ôø_6=ÌÁ%* œ`ë@‰h¢ŠQEQEQU®ïRÒ{XäVÅ̾PqŒ+m$gëŒ}hÍŠÞ(ÓM7o2+mÝäÌÁmªHÏäžÄTpøž”ˆYÚMq3ÈñùqIÁUÜNíÛHÁìh½EbKâ[8…‹²7•x«@˸íû„î8=p G§ë3 ™ ½‚o-¯ä¶ŠãåØ~UÀ9öÎ:Ó ›ôW/Š!±ÒlÚýŒ·¤’6]åWaüDdô×K ©<ÍÊH¡Ôû‘@¢ŠŽrV ¤ÊÉ(¨à±G·ÚkŒ²‚x})-Xµ¬LÇ$¨É=è-Q@³õ¯øóƒþ¿mô|u¡Yú×üyÁÿ_¶¿ú>:òÈå¨ÿ¾¿úÑG?ärÔß_ýh¦#Ô´¯õÚý‚ÿmëRúÊ+øV‚ÞVð΃áojËÒ¿×höý·­Ú§›mœÖ [r¿%Pÿ>ƒ8 hëöd‚kë©Ò9#’?0®WaÈgß<Ö•sáËk‰¥™nn!–S&æM§‡ y”{ÒËáëi]¹º¼qÇ,!—lŠƒ “ŒýpkbŠË›C·–ifYî"•ç ÈW÷ni##¡sZ0£E FÒ¼¬£ßo®0)ôPERp¼JR+™QwÛ…8ÉÉê=M:4òÃ|ÌŘ³3c$ñéôú(¢Š(¢Š(¢Š(¬¿YO¨éÆÊÁóˆÌÞ`_$‚oRF;V¥NçL¶¸Ó–ĆH FNJà©Ô)©¦=´óÝO<¶ÅʳíÞ0s€*õÄa/…¬ÑUc¹¹T0ê63cn\¹žØ«1èp%ïÚæâD r°1_-d?ÅÀÉÇlšÔ¢‹…Œˆô`[˨-ꮥIØÍ¸©È ŒôïZã€IÀê{ÑE×PèÈÝ`Ó¨¤24ŽTEE»˜*Œ•:ß4èÐGƹŒ õ§Q@Q@gë_ñçý~ÚÿèøëB³õ¯øóƒþ¿mô|tä<ÿ‘ËQÿ}ô¢Èå¨ÿ¾¿úÑLG©i_ë´?û?þÛÖíai_ë´?û?þÛÔž$ŽúX M$Ê·ÆBcpHE9ßÛéžø¤ÆlÔ7WPYÛ´÷2â^¬ké57ÐU´×’8¾Î C$mö ‹ç-÷ºöª2ZËs ÑÁ ñÓÍݱ…fóƒ û ù€éÏÖµ°®tQj–S\¥¼S™×xM;gŽ:¸«•Ì\i€M¬º½å¿,2¡•Éyà¿¡=}ê¥ÐÔ'²ÓóÅ¥ª™–@«<Ä·–L˜Œôï@zËÊñ#©xñ½AåsÓ4úç4›cm®3^ ©¦’ÞÆÇU|) X”fõ­ËØ^âÒH£pŽÃ‚Iü¹¢Árz+û"ïþ{Eÿ¤ÿ ?².ÿç´_÷úOð«är9ŸcjŠÅþÈ»ÿžÑßé?Âì‹¿ùíýþ“ü(äpæ}ª+û"ïþ{Eÿ¤ÿ ?².ÿç´_÷úOð£’=Ùö6¨¬_ì‹¿ùíýþ“ü(þÈ»ÿžÑßé?ÂŽH÷gØÚ¢±².ÿç´_÷úOð£û"ïþ{Eÿ¤ÿ 9#Ü9Ÿcj£yB¸EGv#8Qœ ÉþÈ»ÿžÑßé?Â¥³VÓ&ÝM ÚÛÉ™jN)-ƤßCCÌùöŸþùÿëÓ’PÌP«£¬0qëY¢áu¾þïõ½¼Òøÿ¾xÿëSåo»ß ŽEHð[ÌeϪƒš‚Í*+;ìr/ü“ÿ‰£ìr/ü“ÿ‰  +;ìr/ü“ÿ‰£ìr/ü“ÿ‰  +;ìr/ü“ÿ‰£ìr/ü“ÿ‰  +;ìr/ü“ÿ‰£ìr/ü“ÿ‰  +;ìr/ü“ÿ‰£ìr/ü“ÿ‰  ÏÖ¿ãÎúýµÿÑñÒ}‚OîEÿñ5¡C¥ÛFä/mž·(q“Íy/?ärÔß_ýh£ÇŸò9j?ï¯þ€´SêZWúíþÁÿ¶õ»XZWúíþÁÿ¶õ7ˆ/dÒâƒQ æÞ"ágr° À⓯QÜ\ÁkšêxáŒuy(‰®~æmfÏF·[ÖHÐyBâí$-*äçnÜ2FrqŠ©–ÔZÂ6ºš[Q©•·¹È "˜ç8ÁÁÈÎ)Û[ çQí¬—Þ;¨Zm›Äk -´÷Ç\{Ôù>µÇº[}Vî=Gì­öýŒe˜F¬^7`áˆÍGªÞÈ,Œ7FÆÞ[MðÉw7–ZMØùˆFÆ8È9 Ì09çy¥®C1G®ê‘KrËvóoû>ì)]‹ó…úƒÍkêÜKm¶ÕŠÉ¸où¢ÁrÍ‹öMWûïÿÅdÕ¾ÿ÷üUû5ÝÏämQX¿dÕ¾ÿ÷üQöMWûïÿÅÍwAÏämQX¿dÕ¾ÿ÷üQöMWûïÿÅÍwAÏämQX¿dÕ¾ÿ÷üQöMWûïÿÅÍwAÏämQX¿dÕ¾ÿ÷üQöMWûïÿÅÍwAÏämSdŒ…bryT±ü…d}“UþûÿßñVtásmu(ºbY£rḞ”œ,¯q©_¡sí)ýÙ¿ïÓ…:9RBB“‘ÔAª¢KÝÃ2œoÏ_áóIÿÐ8¦]y·ãÊ.JÅÎÇ ßÞ ³BŠÎû5×ý7ÿ¿ëþ4}šëþ›ÿßõÿÑ¢³¾ÍuÿMÿïúÿfºÿ¦ÿ÷ýÆ€4h¬ï³]Óûþ¿ãGÙ®¿é¿ýÿ_ñ  +;ì×_ôßþÿ¯øÑök¯úoÿ×ühFŠÎû5×ý7ÿ¿ëþ4}šëþ›ÿßõÿѬýkþ<àÿ¯Û_ý'Ù®¿é¿ýÿ_ñ¨õ‘4»e˜’âöÛ998ûJcŸ¦(É|yÿ#–£þúÿè E<ÿ‘ËQÿ}ô¢˜RÒ¿×höý·­[«(/#q½–&Ü9 ǃóý++KÍ¡ƒÿ@wÿÛzÛØ¿ÝýM;'9Ï4»©¦l_îþ¦‹ýßÔÒýÍê:70þ#ùÓ6/÷SFÅþïêhù8ÆN=))»û¿©£bÿwõ4ê)»û¿©£bÿwõ4ê)»û¿©£bÿwõ4ê)»û¿©£bÿwõ4ê)»û¿©£bÿwõ4ê)»û¿©£bÿwõ4êd‘E*…–4@u—bÿwõ4l_îþ¦€"û§üú[ÿߥÿ ’8£‰vÅ ôURì_îþ¦‹ýßÔШ¦ì_îþ¦‹ýßÔШ¦ì_îþ¦‹ýßÔШ¦ì_îþ¦‹ýßÔШ¦ì_îþ¦‹ýßÔШ¦ì_îþ¦‹ýßÔЫ?Zÿ8?ëö×ÿGÇW¶/÷ST5•Î ¦Ú÷?óÞ:b<‡ÇŸò9j?ï¯þ€´QãÏùµ÷×ÿ@Z(Ô´¯õÚý‚ÿmëv°´¯õÚý‚ÿmëv€ (¢ÂŠ( Š( Š( Š( Š( Š( Š( Š( ¢ºb¶Ò88ëRÔŸñé'Ò€,ý†ØûhßãGØm¿¸ß÷Ûsž } x¢Ôëkl`û¡<ðݽzg¾3ӚϊöæÚÖïo®¬,ŠÎöŽGÎÿ?îÑ‹~ïAÔŒSÙý†Ûûÿ}·øÑöoî7ýößã\•Ýö¨b¸º–î{yí4èn<•ÀC!-¸0#¾1Š—NÔu+´SÞC[‡Ñæ;š §iXö}vï_¥Ö¹ÐÂ6I<@’±É…ÉÎU?ÔÐÈ%ºŠ'άÄŒããDG7GþšýiAÅôGý‡þ”†Möoî7ýößãGØm¿¸ß÷ÛrÖϤ&¯xuõ„êk&ßí'ËãËò³Ûéß9ªi¯ÞJú›ArÈ”òˆšq#Àêp26‡Û&˜¯Øm¿¸ß÷Ûa¶þãßmþ5ÉÜß^ØÌö¨Üý‹if¹|3À¼68UäŽ2iš–©uöè!±ÕcŽÕ­Õ­®'¸Ú³>âp„IÐ|¹^¿+$«flr^ßp%\®£85·ÿÿ×í¯þŽªi¯‹ z6À‘n¦,¾™PGàjÞ·ÿÿ×í¯þŽž?ãÏùµ÷×ÿ@Z(ñçüŽZûëÿ -êZWúíþÁÿ¶õ»XZWúíþÁÿ¶õ»@QHaEPEPEPEPEPEPEPEPQ\£Inè¿xŽ*Z(µ¾Oî'ôZ>Öã¤7÷ÍME ûSÿÏ ÿïŠ_µ¾1äÜcýÚšŠ†Ý[÷²:•óp¨úQ6ô–9U …½yÇøTÔP2và`Cqÿ|Ñö·ÿž7÷ÍME!û[ÿÏû浿üñ¸ÿ¾jj(¬òÉqÂ°Ê ©PYp{ÔZßüzCÿ_¶¿ú>:¿YÚÎM¤Ëí¯¯ü÷Ú˜CãÏùµ÷×ÿ@Z(ñçüŽZûëÿ -èvš¦Šö:\ŸðCiqod°’FxeŒ°!ä­XþØÓ?èoOÎþ&Š)liŸô7§çÿGöÆ™ÿCz~pñ4Q@ÃûcLÿ¡½?8?øš?¶4ÏúÓóƒÿ‰¢Š?¶4ÏúÓóƒÿ‰£ûcLÿ¡½?8?øš( ûcLÿ¡½?8?øš?¶4ÏúÓóƒÿ‰¢Š?¶4ÏúÓóƒÿ‰£ûcLÿ¡½?8?øš( ûcLÿ¡½?8?øš?¶4ÏúÓóƒÿ‰¢Š?¶4ÏúÓóƒÿ‰£ûcLÿ¡½?8?øš( ûcLÿ¡½?8?øš?¶4ÏúÓóƒÿ‰¢Š?¶4ÏúÓóƒÿ‰£ûcLÿ¡½?8?øš( ûcLÿ¡½?8?øš?¶4ÏúÓóƒÿ‰¢Š?¶4ÏúÓóƒÿ‰£ûcLÿ¡½?8?øš( ûcLÿ¡½?8?øš?¶4ÏúÓóƒÿ‰¢Š?¶4ÏúÓóƒÿ‰£ûcLÿ¡½?8?øš( ûcLÿ¡½?8?øš?¶4ÏúÓóƒÿ‰¢Š?¶4ÏúÓóƒÿ‰£ûcLÿ¡½?8?øš( û_Kïâôüàÿâi©h²˜üÿ$‰©.Âð€Å0É œeEP™xÎâ ¯ßOm2K²•t`AùGz(¢˜ÿÙfotoxx-12.01.2/doc/images/expand-brightness.jpg0000664000175000017500000003253311701011016020001 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí:Photoshop 3.08BIMtrim resize sharp ÿá 4http://ns.adobe.com/xap/1.0/ 306 248 ÿÛC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcÿÛC//cB8BccccccccccccccccccccccccccccccccccccccccccccccccccÿÀ2ø"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?¢Ÿo¤érˤEyqw³»ÊSî‘þ?¥Bo4ÑŸø¦­ÈH¹bã¶–ó?ØÞã0ʹôË(Íu±[[­ŽÈXÓª5Ï^¿²²JíšS§ÍvÙÉ‹8Œ [ê.ÏøS~Û¦uÿ„jßÞûIÇçŒSZ(ÿ´ÚØ|±<‰@ÙÈý?Z릆6±"%W‚€ (¨©ŠåK•^ú•W½ÙÊý£OÆá¶Çý}Ÿð¦ý·Lãþ)«pF7$øãYCê‹jüÀ&#ê6îÅu7Ém-©CÏÉ’¤ ´UÅ(4’óRºwg7ÙJû#ð´Þ‹tIþTHöq6Ù<-7£]•?A‘"¼ýäU7 flp:sZ>|}¯˜ðŸ.A ·Ìz“]jÍ\ÄÌÝe䙿á·òÃmÝö³×Ó¥5%±wT_ Ûc€>Öy?•Y†heµG¹ò·›…Üv㞪ÝÃ($coµŒ4X/¹ì+™¥¬ÄÆøE 2·hº$çò¦ì øfØÁÿK?áZËyŸæJÝc;ëïõ¦ „Œ#Z´r9OÉ@ž~ŸÿBÍ·þŸð£ÏÓÿèY¶ÿÀ³þ¬’Y*²Æ!aæ>ðΣ#·'œ}*»<-¥º(ÙT`¬\ç¿ñ@|ý?þ…›oü ?áR ¶‘7§„âdþð¸b?•YÕž%mÿê£*p1ê½¾´ûg'O¶Xï#’RÍ™pqôïE‚å-Ö^Oÿ½¿–nﵞ¾)K)l~ÛÑn‰?Ê®Í=¬¥åAÝv @%qëÔ °·ǨBâhWz¸aòa=9^(#íyÿ™jÛÿÏøTÒ%´~nÿ Û+ÿÒþîzv©n.6XF™·i™ØHP)ÀöÇJ´e„K~°Il»š?,1]‡¯áE€Êóôÿúm¿ð,ÿ…(’È¡qáx6‚ßj8Ï×~Sk+_G À¥Šb@gv Kwr ävò[€$GÊ\szÍ™¬ •£—ÂöêëÔ³ÇéLóôÿúm¿ð,ÿ…i³Û‹›Ï³µªÈY<²ûvmïŽÔ‹HÙÌFÖºP7~\sŒö¢Ás3ÏÓÿèY¶ÿÀ³þyúý 6ßøÂ’ë`»˜FFÍçn¨³ïúÓ°yúý 6ßøÂ?Oÿ¡fÛÿÏøT9÷ýhÏ¿ëE‚äÞ~ŸÿBÍ·þŸð£ÏÓÿèY¶ÿÀ³þ}ÿZ3ïúÑ`¸ÍA¬gÑï%·Ò¢±žÖX€d”¾wn?‡Ý¢£Ÿþ@ÚÇýv¶þRQR3§Òt{-WÃzgÛBc‰‚r¸Éçù LÖ¢"(š)Ð}ÙL?=~•Âÿò-Ø×?êkV³8ÏâEFN;ü^³ò ¸šW¼o˜ÌŽB«vÂ÷Þ™ýŸ­®èUm™Oü¶2 }qÖº:)J”%k­†¤ÖÆøNÎ8Žy…âüÞyc´·®Þ˜íQ6›®N<‡hcŒðdó· {/Zé(¢Tã&›BRkc? é)«-Ã9o=†ãÜàt§Â+¤Ï+üjÙ¢´$ÆÒAGrè~ÒÕ5ÆatA¹k¹H集ãò­:(þ]#þy\àCQÿ®‘ÿ<®?ð!«fŠÆÿ„WHÿžWøÔÂ+¤Ï+üjÙ¢€1¿áÒ?ç•Çþ5ðŠéóÊãÿ¶h  oøEtùçqÿ Gü"ºGüò¸ÿÀ†­š(þ]#þy\àCQÿ®‘ÿ<®?ð!«fŠÆÿ„WHÿžWøÔÂ+¤Ï+üjÙ¢€1¿áÒ?ç•Çþ5ðŠéóÎãÿ¶h  oøE´ùçqÿ Gü"ÚGüó¸ÿÀ†­š(þm#þyÜàCQÿ¶‘ÿ<î?ð!«fŠÆÿ„[HÿžwøÔÂ-¤Ï;üjÙ¢€8ÿiVz_‡§û:ùÒÆ\¼…‰Ûœuúš*ïŽÿä^oúè´S÷…ÿä[°ÿ®ÔÖ­ex_þE»úçýMjÒ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¤ú•´Æ)®$•9«*ÁÑYNU€ úƒ\‡ˆä3/û«ü©t9æmZÙyY3¦BF0{f·ö72f>ÖÒ³; (¢°6 (¢€ (¢€ (¢€ (¢€ (¢€9ÏÿȼßõÑh£Çò/7ýtZ){Âÿò-Ø×?êkV²¼/ÿ"݇ýsþ¦µiQEQEQEU{«ëk2‚æeŒ¾vç¾1Ÿæ*Ås~,ÿ[gþìŸû-T#Í+9r«Ås–‡€Â¤®*ÛW½µa†E©$€õ®Æ/o ·,Ñ«©ÕT¦à(MH’Š(¬Ë (¬/ÝÜÚÉj-æhƒ‡Ý·ãn?™§ó;!Iò«™~!ÿÌ¿î¯ò¦è?ò¶ÿxÿ#TæšIä2LåÜõcW4ù Û¼‘®ëZò8ïyÜì袊à;BŠ( Š( Š( Š( Š( sÇò/7ýtZ(ñßü‹Íÿ]Š`^ð¿ü‹võÏúšÕ¬¯ ÿÈ·aÿ\ÿ©­Z@QEQEQEÍø³ýmŸû²ìµÒW7âÏõ¶îÉÿ²Ö”¾4E_˜ß[Ç¥¿ýrOýW]õ·üz[ÿ×$ÿÐEoˆÙÐÝ’ÑEÈt…s~,ÿ[gþìŸû-lj³Ém¦Í4$AHÏzäo/®/Š–V1ä.qŸä+j0n\ÆUd’±Z´4ù Û¼‘¬úÐÐä3mþñþFºåð³š?;:(¢¼ã¸(¢Š(¢Š(¢Š(¢Š(¢Šç‚ºÝwþ@×?îæ+Œ®¬:V¹ÏY»Ø+¾¶ÿKúäŸú®¯è*?¶­ŽwäkJ°æ^„R—+;J(¢¸N³?]ÿ5Ïû£ùŠã+³×ä sþèþb¸ÊëÃü,毺 ÐÐä3mþñþF³ëCAÿÍ·ûÇùÚ_ 2ĎΊ(¯8î (¢€ (¢€ (¢€ (¢€ (¢€9ÏÿȼßõÑh£Çò/7ýtZ){Âÿò-Ø×?êkV²¼/ÿ"݇ýsþ¦µiQEQEQEŸ®ÿÈçýÑüÅq•Ùë¿ò¹ÿt1\euáþsWÝhh?ò¶ÿxÿ#Yõ¡ ÿÈfÛýãüm/…™GâGgE ÜÛÆådž4aÙœ^qÜyüJ<´ã°§ÓcÿV¿AN¯Mlp0­ þC6ßïäk>­i×+gë2¡É Œž=éKfÝÍŸ¦êÐêR¼qE*]ĸ v'Ö´+Îi­Þš{QHŠ( Š( Š( Š( sÇò/7ýtZ(ñßü‹Íÿ]Š`^ð¿ü‹võÏúšÕ¬¯ ÿÈ·aÿ\ÿ©­Z@QEQEQEekWVòi7 ñ; à“È®F›Zp: uwÓ‡"8§>fQEhA{IÔ?³&’A›½6ãvÜr¡ô¨u ¯·^=ÁŒ&àÜç õªôTò+óÌí`¢Š*‰ (¢€7|)ÿwõËÿfÓW3áOøû¸ÿ®_û0®š¸«üg]„(¢ŠÄÔ(¢Š(¢Š(¢Š(¢Šçžþ_o1ïÓŠË–m^xLS5Ĉà CŸÈT£ÇLæß÷ÿÿ±§1ÿ˜{ßÿþÆ®3Šû$87ÔÏû%ÏüûÍÿ|>Ésÿ>óß´‡XÿËÿ¿ÿýjpñ“ùq?÷ûÿ­Z}aö#Ø.æ_Ù.çÞoûàÑöKŸù÷›þø5¬<`Çþ\ýþÿëSÇ‹XÿË™ÿ¿ßýj>°û°]Ìo²\ÿϼß÷Á£ì—?óï7ýðklx­ü¹ŸûûÿÖ§1ÿ—CÿúÔ}aö`»˜_d¹ÿŸy¿ïƒGÙ.çÞoûàÖøñ+ùu?÷÷ÿ­N#cÿ.Çþþõ¨úÃìÁw9ï²\ÿϼß÷Á£ì—?óï7ýðk£ cÿ.çþþõ©ã]cÿ,ýüÿëQõ‡Ø=‚îs?d¹ÿŸy¿ïƒGÙ.çÞoûà×P5¶?òÀÿßÏþµ8k å‰ÿ¾ÿúÔ}aö`»œ¯Ù.çÞoûàÑöKŸù÷›þø5Ö Yü²?÷ßÿZœ56?òÌÿßt}aö`»œ¤0ÞÁ*Ë 3$‹Ñ„gÒ´¬µ=NÝÝ® ¸¹R¸ Wnzðµ¶5?Àïªx¾cü'þú©•U-ÑJ“ŽÌ¢šáÚ<Í:ð7pˆüÉʬ ZÜ€Lw ã§ÙßÒ¬ ¶?Âïªp¹cØþu“qìh“îA¥o!#¦rñ2ÿ1Vcu‘¡Êžø LÇ×ó§nÏZNݨ´Piâ<÷¤(©D9þ/Òœ-³ü¥r¾;ÿ‘y¿ë¢ÑR|A‹ÊðÿÞÎd^ÔS ëF¾Õü9¢}Š4*97–‘W#O±ª#ÁºÐÿ–0ÿßôÿëχ4V$6,““‡qúâ“þ­þ±ßÉ?øªåƒõ‘ÿ,aÿ¿éþ4ñá`ËïúuðhŸô ‹þþIÿÅQÿÖ‰ÿ@Ø¿ïäŸüUsCÂz¸ÿ–Pÿßôÿxð®ª?å”_÷ý?ƺ/øF´OúÅÿ$ÿâ¨ÿ„kDÿ l_÷òOþ*€0…õAÿ,âÿ¿Éþ4ñáLË8¿ïònÂ5¢Ð6/ûù'ÿGü#Z'ýbÿ¿’ñTŒ<5©ùgýþ_ñ§j#ø"ÿ¿Ëþ5­ÿÖ‰ÿ@Ø¿ïäŸüUðhŸô ‹þþIÿÅP`ðö ?‚/ûü¿ãOøþ¿ïêÿhÂ5¢Ð6/ûù'ÿGü#Z'ýbÿ¿’ñTLhWÃøbÿ¿«þ4ñ¢^á‹þþ¯øÕŸøF´OúÅÿ$ÿâ¨ÿ„kDÿ l_÷òOþ*€!5àþ¿ïêÿ·ìÔš›ùzÙÖÐ’œT—R$œ]™›ý¡cýÿÿßÿþÊí ïø—þÿÿöUvK;e¿¶Ž8U¡w`í»?7÷? i²¤µ pÈò2ì,He_åUbnTþбþÿ‰ïÿÿeGö…÷üKÿÿû*½ö;o´[“o…xä,‡#•Æ;äS#¶‚HÒe¶V‘íˬ!Ž g^”hV¾³R Œó?ÿeIý¡cýÿÿßÿþʬñwÆ1 uÇ+R`ZÄ© ³ì£”y`ã×®h°K}fÌO‰‰=Ÿÿ²¤þбþ÷‰ïÿÿeVãHP²†8Dvpä6HúñKci‰6â`ò8•Ë“Z,*ë0¡‰ñ6ÓÐùüüz“ûBÇûþ%ÿ¿ÿý•]µX¤¶³†X„ŠóH£$¿•9#IÓOF¶G‹,¬Ù?/=:÷¢ÀPþбþÿ‰ïÿÿeGö…÷üKÿÿû*¹ µ¤þD†›Œ‹°w‘Ò…µ·ûQ_²¾LYÚQ°§=qœâ‹OûBÇûþ%ÿ¿ÿý•Ú?ßñ/ýÿÿìªìQ3O ¬„o!Œ`c¦AãñªšÆ §ý†ôô¢ÈÿhXÿÄ¿÷ÿÿ²£ûBÇûþ%ÿ¿ÿý•^hÖöKIp²ÆbošEù˜ŽÄ.9ôÅ6K[hå•þÎ ‹o0!$a³õ¢ÀSþбþÿ‰ïÿÿeGö…÷üKÿÿû*ºÖbWŠÙdÇ·äŠQgj.ï„9Œ¨HÀ'ƒÔàš,í ïø—þÿÿöThXÿÄ¿÷ÿÿ²¨/#»•#VT€ØÈ¨Ïj,.ÿhXÿÄ¿÷ÿÿ²£ûBÇûþ%ÿ¿ÿý•Rÿ=¨ÿ=©Ø.]þбþÿ‰ïÿÿeGö…÷üKÿÿû*¥þ{Qþ{Q`¹wûBÇûþ%ÿ¿ÿý•Ú?ßñ/ýÿÿ쪗ùíGùíE‚å››Èe°½k;­r+‹x„£íÞ±÷¢©Ë _þ¼WÿG-#:+]"-cJx¥šH„wÓ°('æ#¿Ö/W°g[i®–XWp`:gÐÖ‡ãÂúûŸÿC5ròú $Ì­–ã¤n9 p ÷¬ªSMQ“ŽÆ >šìµÖ¡w%¼ïÀŽ ­µzòO¥Kÿ„?ô»ÿ¾·¼øwÈ‚hËE÷Àaòý}*Ô-ÞâHVE"(Ä&á´HÆs׊¸«+!7}Y—oáxí§I£Ô®w!ÈÝQŸBI'RºÉÿ¦i[òË+ºY0{³LûL~aR@@üÂÃiãÖØŒ?øD!ÿ ßýð”Â!ýî¿ï„ÿ ÞyâYžTP‡ Y€Ú}ê1yÚq¶!1rFݤã¯áEØ¿ðˆAÿA+¯ûöŸáGü"ÿÐNïþøOð­øäIP•0½†x`á‚Þ5û>àFRr>£¨Ï­º(NÀÕ̽cwÛ4ÖXÃ-Á>Y ò7LñŸ©ªÐiwQCq¾ÖLÖåLãj–¶ÓìíøVå-`"ê;[x°ÓiÙÙÑÓ}À+ÿ>FážéÅË)‰­Õ~t{Ãy…±Ÿ»ïéÚ·(¢áb®œ—Úbì*ɼPvöÝ·åÏÒ¢:¥¤ŠGpéÀFÇŸAWé>Òxí¾€(kØ–Sæ¸ÁÏú§ôúRÿlYÏGÿ¿Oþ{íCþ~ý÷GÚ‡üüûî€2´µw¶–EGÚ÷2’¤dÖ®yoýÆüªsp„ä̧þGŸüõ_ûêyoýÆü¨òßûùTþ|óÕïª<øÿçªÿßT–ÿÜoÊ-ÿ¸ß•OçÇÿ=Wþú£Ïþz¯ýõ@yoýÆü¨òßûùTþ|óÕïª<øÿçªÿßT–ÿÜoÊ-ÿ¸ß•OçÇÿ=Wþú£Ïþz¯ýõ@yoýÆü¨òßûùTþ|óÕïª<øÿçªÿßT–ÿÜoÊ-ÿ¸ß•OçÇÿ=Wþú£Ïþz¯ýõ@yoýÆü¨òßûùTþ|óÕïª<øÿçªÿßT–ÿÜoÊ-ÿ¸ß•OçÇÿ=Wþú£Ïþz¯ýõ@^0ÿ‘nóýÄþkE'‹¿äZ¼?ì¯þ„(¦"dðæ¦èÅYe¹!”àƒ“È©?´ï¡ò-Þ(iRB‘†!Nïq}ù§è1¤ÚeÔR®ä{©Õ—Ô9v6ʈ­ÂüÊÜ»mû¸ÉàNžÔ€§åÈ”ÛF#3Étñïvb€*$£ØU4ÔïÙç»D‹Z$‰¤m¿,Œ>_rZÖ¼Ó£ž"±$jæO4³ûØÆAVz-t»[k1nPI˜ŒR7+¹I$ŒÀÉ>þô¦Ks4—4¨ñ,ÅcpÊ0­Q—U¹ûK,qyr4Ñ ÈpT6}ööéZñ[A Ï,Q”y1»Ø?ðã<qš«k£Z@æF%‘Ì™bÍŒ99ÀÎÁÆG4":ŒÉkd#Œ›ˆÑÑËýÕçÝß>ž¼úUgÕnîmn^;yÁdXÝL{AÃ#iɬlmI$À¹% ;›9O»Îr1íïëLþͲß#ùÉ»x8S»¯Ëœ}@¡‚+C}2ÞAÁ"‰‘4ŠÙ”•ÉÃtÎ{kJD(ô#P‹Q:Íå鹑ʌ ·;r|f£{K’Ħ£$iÙD qø“M‚-–bÈ7–çíÇÖ¨‹;°sý«'þ¥c»ÿ ¬¿øŸãH ºÍÁnIº—“ÏzµýÑùSí,c¶„¡–Iœ€2I犛ÈÕÿJ­ýÑùQýÑùUŸ"?Wý(ò#õÒ€+`t~T`t~UgÈÕÿJ<ˆý_ô  ØÝ•Ý•Yò#õÒ"?Wý(¶÷GåF÷GåV|ˆý_ô£ÈÕÿJ­ýÑùQýÑùUŸ"?Wý(ò#õÒ€+`t~T`t~UgÈÕÿJ<ˆý_ô  ØÝ•Ý•Yò#õÒ"?Wý(¶÷GåF÷GåV|ˆý_ô£ÈÕÿJËñ‡ü‹wî'óZ)<^sá»ÌuGê(¦üØÚ0(×ìƒ&ÒíTf`ß÷r ÉëØw©­Þ¢Q¿ó–¢¶Ñ’ÓËû=ÁUTEpÑ+oÚ0'î’:õ©m¹Öõúåoüå  ÿòÈÿ¼?‘¬ë;«ËÌOp-©ª†c½€8-Óx­ùdÞÈÕtæÈ†òT·._ȧœ¨ÿúè×-Ñ'2C24)¼§ÊÌ˹X÷#ƒƒÏJ”ꊮa6·ió<¿³€¥‰ÆìçvÜcœæ«Ç D‘þÐÅD" ®2¶N:Ÿ”sV§ÓVK¹.£â¤¬0\)R0z‚ E.·m ÞT©"•Ú%'oî‹tœŸøqPÜM%Æ—ËâùŽ`ò«#LÛrgK’ö™s ¶ò8ÈÏÝãŽõ ýºÚéñD¬XÈß'ý©Aþ´Ïȹ{ôú¢ȹ{ôú¢˜ðïüxOÿ_sÿèfµk+Ã63òú\ýN?ŒÖ¶ßö“þû€J)vÿ´Ÿ÷Ø£oûIÿ}ŠJ)vÿ´Ÿ÷Ø£oûIÿ}ŠJ)vÿ´Ÿ÷Ø£oûIÿ}ŠJ)vÿ´Ÿ÷Ø£oûIÿ}ŠJ)vÿ´Ÿ÷Ø£oûIÿ}ŠJ)vÿ´Ÿ÷Ø£oûIÿ}ŠJ)vÿ´Ÿ÷Ø£oûIÿ}ŠJ)vÿ´Ÿ÷Ø£oûIÿ}ŠJ¥&žÒHÎu-AKá^0°ù*ößö“þûmÿi?ï±@ÿÙÿA=GþþGÿÄQý˜ßôÔïäüEhmÿi?ï±Fßö“þûŸý˜ßôÔïäüEKgb–’M žy¤”(f™”œ.pþñ«{ÚOûìQ·ý¤ÿ¾ÅWº¶7*ª.®` sû’£w×*ɪÿÙÿA=GþþGÿÄV†ßö“þûmÿi?ï±@ÿÙÿA=GþþGÿÄQý˜ßôÔïäüEhmÿi?ï±Fßö“þûŸý˜ßôÔïäüE'öJ³!–úúUGWØî›Iœ =Ehíÿi?ï±Fßö“þû‹âþ|7{ôú¢Œxjó•?*ô`ˆQLÄLÑë׫(¾i8SY¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£Ey²ÏGÿ¾lŸóÑÿï£E†Ga‚ìG¡4QEÿÙfotoxx-12.01.2/doc/images/gallery-selection.jpg0000644000175000017500000016241311701011016017775 0ustar micomicoÿØÿàJFIFÿávExifMM*JR(2Z2010:09:29 14:40:45ÿí6Photoshop 3.08BIM resize sharp ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 391 606 1 2 2 ÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀ‡^"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?úKXÕíô¨^kÙ#†ÝYÈí™È >¥˜îk,ø×G±½€(䜞Ÿ•7ÆŸêmÿì%§ÿéTUR©/˜×fÿû Dÿ` [ÎiÿœóŒcfîzùŸ>1*ãÐÓ»ñ^™jÑ-Åݺ4Ñ oÎèÏFt>´–Þ+Ó.®àµ‚‘{È.B– qÏ OÐW#¥ø‚ÓÂú=¦§¨%ËÛE¡éÊËn†G%™”½HÉûóRÇã-7ƺ ºdWÑ-¶¬¡¾Õnѵ­Æ0^‡8¦)ñ–ޝ"}¶ßtnñ¶œ21V;0#ð5sNñ ž¥æ›âœÅ€áü¤çö?•yÅ”w÷'T¹ñdˆ÷GöCß,lÿo¼ó7ynìy}yÆ1Åoø-fKÛ•º7&eÒ웦c6w\Þnù·sÉ<Ô°Lí>ÚßÜ™¥ûsÿp~uScüâ§™•bßÛŸûƒó£íÏýÁùÕJ(æabßÛŸûƒó£íÏýÁùÕLœQóŠ9˜X·öçþàüèûsÿp~uSçcüâŽf-ý¹ÿ¸?:>ÜÿÜTÇùÅÿ8£™…‹nîη?÷çU1þqF?Î(æabßÛŸûƒó£íÏýÁùÕLœQóŠ9˜X·öçþàüèûsÿp~uSçcüâŽf-ý¹ÿ¸?:>ÜÿÜTÇùÅÿ8£™…‹nîη?÷çU1þqF?Î(æabßÛŸûƒó£í­ýÁùš©F?Î(æabßÛ›ûƒó ^·÷çU>+ÉüAý¥©x×J¿Óï º…Å­«´fx£HmdÂ0pKHÒ ÿ°½p(æacØÅëàmoîÌ׉߸ÛÅÙÚ5ʶ–}1n/°4¿Ú"R¦sòÝÏ#°æÃøƒÆê²F—ÖÖ°Ëyh‘¶ž$0,1yŠÙÜ9ùr@ý;±$dûcÿÏ1ÿ}Po[þyûëÿ­^+¨xßÅ]↠hîôÛ{ ²C”¹™ŸG»;—†l·#*x‚Ò×Ç:Íͦ¥ª¥¾иµ½¸–D»›¨X£o’4L‘ŒðzÐG²‹æÇÜ_ζ¿÷ækƧã Tii© ŠÞúËOsqhÓ±i­Ä’H_v[œà uüEâ Ñõ8¬"¼ÖcÒµ2[°f’9Q€:vŒç(» k­ýÁùš>ܸ=~õxÖ­âÝbÛMÓd²×b¸µ•'y5?ì–Á™Y-¼¼ü¹$ó“ýÞ¢¬\j¦£«xP½µ1:ê6rZɽ– š–fUÏ 7¢îÇ0¢ì4=wí­ýÁÿ}R}µ¿¸??þµxM¿‹¼j4u¼–úÕÏöPÔŒ_ÙäV,ÅÜdsœ}zÞ¾ñ†³Ä%Ó¬ãžkSr-ÞÚkUü2>âÌ n*ç¥cI³öÖîƒþú£í¯ýÁùšðÝÇ>)žËQxž=Fú_UÓÞ"äÌ£ œ¾Áž˜Ïz|Þ5ñx}.ΣlbK²žr[©šâ1íª™ò÷g¶ðH ph»oûkc>Xÿ¾©>ÚßóÌ~ýjñÿëPÿg_jz”Úâ§™ockogy-›üŸ1̆2væ Ù'1Î0pµ[½r³Hµ­Zúôi¶ŸÙRÚy© õÇŸ‰Ë(s·ï/=軑ï¿moùæ?3þ¿ln~AÇûGü+Æ5=ZâxöÓÃÚ•ýÅóéÄÙBòË(K¥ó ‹±Ú¤ aW©þº¼º»“O±Ô5{&êöÐ[\ÝM!— –è+¹ß³* çŒ¶¥ °²=“í­ýÅüéëpßUÌøâ{x<5z÷WRÚÄ@ıÍ,[X·¼_8Rp ³^KuªI€´Èoõ/C«ÜÜÞEcuöÛˆáXƒ®'‘¾ô±(+´0%²F9àR{ ~ÚßÜ÷Õm|«™ÿ òÁ«ZÚüVÒ"MbúxçÓŠ\#É'ÒžQgb³ ¶@îsŠÁø«aw'‹5{ÍéÉÜ!Tãv@ëŽkSNñn½/ˆô/æ‹Ê¼†2ÖÊßÌmÍ¿s±r ¡ 0Ãv3Îhmô \ûkp~tŸmîÌÕfêG½%ad[ûsÿp~t}¹ÿ¸?:©F?Î)s1Ø·öçþàüèûsÿp~uSçcüâŽf-ý¹ÿ¸?:>ÜÿÜTÇùÅs0±oíÏýÁùÑöçþàüê¦?Î(ÇùÅÌ,[ûsÿp~t}¹ÿ¸?:©óŠ1þqG3 þÜÿÜnîΪcü⌜QÌÂÅ¿·?÷çGÛŸûƒóª˜ÿ8£çs0±oíÏýÁùÑöçþàüê¦?Î(ÇùÅÌ,[ûsÿp~t}¹ÿ¸?:©óŠ1þqG3 þÜÿÜnîΪcüâŒQÌÂů·?÷æiÖ×’K~a!By{‡¯P?­R©4ïù Ÿúâô!M7q5ddx¾x^x´ÛãV`ÈaˆÄ¡DeNI‘ÐpÅqƒž3Ú¹ÿì}<çþ(KóŸ[»þI®—Wÿ‘ÓMÿ¯[Ÿå_¡½Alr·0GrÐ4þ Ô­ãòbasj¥q´¸jK{h­î¡º‡Á𹀿)îÙ™ ÈãuÉäÆº‰$XÑžFUEä–ô¨mï­g}ÜDïýÐÃ'ð¡\69it»9§ydð5ñ’G296À33O gq$ñÉ&®i€é"_ìßê6Þn ›.mIm½2MÇl×MŠ)\iÿÚºý :¯ýÿ³ÿãôjêô,ê¿÷þÏÿÖÅ5äHc2HʈY˜ãÆ€2µuúµ_ûÿgÿÇèþÕÔ?èZÕïýŸÿ­ kÛk‡)ñ»ãî‚*Å %¸“¾ÆGö®£ÿBΫÿü~í]Gþ…Wÿ,ÿøýkÑ@Ìí]Cþ…­WþÿÙÿñú_í]Gþ…Wÿ,ÿøýiK<0ïóe !vÜØÚ£ø ª–ºÍ…ÕãÚAp À%B”a»B“ÃcÛ4ö®£ÿBΫÿü~í]Gþ…Wÿ,ÿøýkž¸ïEdjê?ô,ê¿øgÿÇèþÕÔèYÕð"ÏÿÖ½SƒR±ža¶ÒJÄáUf>£š§ý«¨гªÿßû?þ?Gö®¡ÿBΫÿìÿøýlQEÚºý :¯þYÿñú?µuúu_ü³ÿãõ¯Aõ  í]Gþ…Wÿ,ÿøýÚºý :¯þYÿñúØÅ%cÿjêô,ê¿÷þÏÿÑý«¨гªÿßû?þ?[P7ö¶¡ÿBΩÿìÿøý(Õuúu_ûÿgÿÇëN ˆnUÚÞT•QŒncmØaÕN:éR‚ Ç_o­ ˜ÿÚº‡ý Z¯ýÿ³ÿãôصKøc1Áá}R4$©5œ“ÿ-û“ŸÆ¶ù¤  ‘­ê™8ðî­Ï_ô‹?þH k:ž?ä\Õý?ãâÏÿÖ¶hÍc$kZ ÉÕÁ=þÑgÿÉɵ]Bhü©ü1ªËÁØóÙ²œr2 üò­ŠqÁÁöÍ2¿¶uLȹ«÷ÏúEŸûoGöÖ§Î|9«s×ý"ÏŸü˜­¸‚Iå†9by¢Ì@ÙdÏ@W¨Ï½KFÂFOöÖ©œÿÂ;¬gþ¾lÿù"£ƒT¾ˆ0ƒÂúœaسlšÉw1<“‰ù'ŽkjŠc+ûoTÿ¡wXõÿ‹>¿øHuL¡Sá½_iÈ#íü‘ZÙ£ŸÖ‹‚G'£Û.‹<³é¾Õ㸘y¤¾·ö©ÈPÒ]uÀÀö­oí½S9ÿ„wWÎ1ÿ6ü‘ZÀîåppqøÑš.1¡ÕoàCáR ĹÙ=˜É'$Ÿßõ'©§ÿmj|ÿÅ9«s×ý"Ïÿ’+ZŒÑp±“ýµªcðŽjøôûM§ÿ$Toª_É*ÌþÔÚTUÚk2Ê\?ŒàVÕHõ¢à‘5}IOËá½TÄ\YÿñúpÖµ@IÕòéâÏÿ’+T° ¹¸_\ÑÍc(kz§OøG5ü ´ÿäŠhÖu5/†õp:ñqgÿɯEc'ûkTÎáÕò:¤YÿòEZÕ0sáÍ\ƒ×ý"Ïÿ’+ZŠ.1†«¨гªßû?þ?Ký«¨гªÿßû?þ?[ddŒŒŽMdjê?ô,ê¿øgÿÇèþÕÔèYÕð"ÏÿÖ½‘ý«¨ÿгªÿàEŸÿ£ûWQÿ¡gUÿÀ‹?þ?ZôP?ö®£ÿBÖ«ÿìÿøý'ö®¡ÿBÖ©ÿìÿøýlŽj‹ëdr4Rj6k"±FC:‚8#rji_a7b¯ö®¡ÿBΫÿìÿøýÚº‡ý :¯ýÿ³ÿãõ²r{jJC2?µuúu_ü³ÿãôjê?ô,ê¿øgÿÇë^ŠÈþÕÔèYÕð"ÏÿÑý«¨ÿгªÿàEŸÿ­z(#ûWQÿ¡gUÿÀ‹?þ?Gö®£ÿBΫÿü~µè  í]Gþ…Wÿ,ÿøýÚºý :¯þYÿñú×¢€2?µuúu_ü³ÿãôjê?ô,ê¿øgÿÇë^ŠÈþÕÔèYÕð"ÏÿÑý«¨ÿгªÿàEŸÿ­z(꺇ý :¯ýÿ³ÿãõ¡á«Ñ©+ºh§‹zŽ0Œ8Ë7ð3ò€7qÎ+¥ªš•’Þ"ž‰Ñ°ƒÔèp=:‘ŠªrQwdÍ]YP½ó®íã‹Ëœs”¸??ÏŒäsŸÃ5ÞZÈóZ[Ë"ìy#Weþéeóé\¾«¤êrYÌ–1Á„Àa‘ýÒNHqÀÏ?ZÐð†¡¨_ØJº½¥Å½Õ»Ù¥g˜NrGÏ‘ÇÌ| kN3ØŠQ”w7h¢Šç58@ŸÛ–nàì¹·’(ÛX!€ÝôgrpkþÒ ºµ¸fõ_0Å HÙR?Ô¹Üyæ6'ž¸¯DÖ´¸u{&·Ÿr0;£•>ôl?‹üAàŽ+Ǿ%%î¡^Úê±fPö×±¯îfu!†Oð?Ë÷}GÕ&g+£»øyâɵùg´–&/4\*ío½´¬€p„0àWk^û2ëšÕ”hÓE¦yHTfÄnèFb¿.푟~Õî]©4\v)ýÓý+Ǽ¥Ûkt†òîúµ[e‰-YSiò·ä7G ƒëÖ½_Zµ–ûF¿´·}“Oo$Q¿#”¨lw·¯.J 6“‚>sÔ1^‡^S¢èzœšîæhMmw1O$¦ÜD#ëŽ9­z±ê8ëEÁyjÞñ Ç™pnã»/4QÏ3h÷t|²»”p0Þäü¾…\,~ »¼×onõ«¨æ‚WfQŒŒŠÝ6…ð;Œ÷ji–üš…á¹Õ¯/¥šÞpÑ$eÉVpܸLâ0603É'8ÉëÏ\×'àÿêz¥v×Kc(¢“¹Ÿ# Ã)ÇÊpNr=gjj(¥ãÖ…¸=Ò|[ÿ·‡5ˆ­-Á¾»Ö®ŒnèDQàE–b9cÓ 9'5‘¡x÷PÑ–ìA=µÃÝÍçË%ÜfFgÀ ` 8í]ÿ†¼4óøg\ÓµÝ2O.ëUžxÖCµ‚á6ȇ·CŒU/ |2±·Žö?Y}´ùäÛL·ضŒU`7d6qž¾•éB¥Åó­N)B«iÅ÷‡¯dÔ¼?¦_N¨&¹·I\F0 °è;ãó­ †ÎÖ8--còíàb7Ú£ ÿõÍK^tšnèìŠÓQh¢ƒR3ø•ã+ÿ ßéðY M—Ë#4ñ³U¸eÇÞ<œö® Bñõæ¯Ýß³¥ÄWÓy—VªJ£aUr€’T€9Áè{ëþ#ð¾¯ËÚ½‰ºšÜ2ÆDòG€Ä>Vp¾½+ŽÐ~Aeâ{íBîÍ^Á%Scgæ3ª€¨ 9o½ón ã<öèP©AS´Ö§%XUr¼^†‡.a¿ñÏ‹o­Õ–;…µ•|Ä(ÄbÆGQôÿïk”ðÝ…ì>8ñ]íÝ´‘[] 2·Ý|E§¿*k«®ZÍ9]ÒMGP¢Š bhç_¼q&‹!ÒtÕxo7ItëÄhzl†nÙè;öè½ëÆ~³ñ.”mnâ>jÐθ zöOpx?•mBQSN{ÕRq|§èß5H[±–(ŒŽ¦â7y»³ÌdÉåˆÍ{ûŒ1Á?¡æ¼ËÃ? ôØôx"ñ’.5ïæÊ—S*¸ÞÅpàÛÆ>µé„’A8Î=sÀ5¶*t¦íMXÏ Å{ìJ(WÐ¥üyö¤4~tÕ¯¨3¼MñQÔíµM&äiñÛJÒÛŸ.'Þ3/ æ}î:ãð®£á§ŽeÔnãѵ%Ĭ1or¿;`v¹õ£÷çw©³â¯‡º\úf¢tm .«8w†f»˜*ÈÄœà¹ÉÎ?Jßð7…í¼/`cŠ ÷’çÜž­ßjŽÊ3ÓÛšô'Rƒ£dµ9# ª¥ï¡ÓRQô¢¼ã¬(4PhÅÞ ¶ðÞ%å™%cåÁ82Èzaê{kÄ,¼eªÙxœk-:ÜMqþ¹w‘ÆHÂÁ@?)듞rAú!¤’5&,’z€kùŽ4é° ŽãH–$E ‘ ÀP:Oô®9µ}˜«-@QE# (¢€ (¢€ (¢€ (¢€ (¢€ZÌðüyZÿ×9¿ô¡ëOÖ³<ÿV¿õÎoý(z¨î)kò:i¿õësÿ´ª?êƒFÒžô¦õIcF#ågU'€O“€2qRkò:i¿õësÿ´©ÚÆœš¥ƒ[I4Ð é ’»”£«‚8#ªŽÔ¥¸ÑBOéˆO´m¶Û)q$2$¡£*6˜Ên ó¯ËÃ®Í â½$[™¼Û¬ ^Ÿd›ÍŠò›7Jàg“UïçÁšdó¬ÍóL¬ù3ÁÜ6Ü®Hp9äÓB6tÍR×SûA²i$X$0»´,ª]X© XÀ=3ÛÔR꺶—j./]Ò#"F6Fò3;°EP'$ v›eŸj`€±ŒÍ,ß682HÎqŒq– U?éóêv0Ãk1†E»·›Ì  ª¤ŠÅ†r3òžZLkmFÍâ=6Hîd’ä[³2—²°‹a |Ì.cÁ'%ö‘Gü%:t~fÉnÙ–á­@ŠÎv/*– ¨üûv6Jä2xæ³õXjëÍÍÄ„y¥ätŽBÍ#+4ƒr•WÈ+Œ ³¨xZÂúÒ%$˜.fº¤Š9pÒ³3® °%ÈàÓx|W¥ÝܬÜÍ3’ª¤A!F-˜ >Ý¥Š@Ï<Œdb¬xTMkFµÔ#†â¸Œ?—µ¿‡ìíÕ&uUºŠíQQC¤j€P\&HoG°V™’M$Ñ@¡"2¹P•x§æh†êº­¦–›·—3?—C ÊîØ' ¨ Iô“Tí|O¤Ý]-½½Ó¹fD!(—PÈ<Í»9R$ôëÅZÕtÅÔÖE¹šÒæÕËE4JŒWr•#kÁþU¥xJ;[™ÖK‰Æœ—Í®àÁ¼¸QC¹ÆíÛ”’2 R@ËkâÝ‘Yg¸"B‚0-&Ì»óµlË©*@eÜ1ß‘Zö7p_ÚEuhåá”e R§© ò ‚#šÃÑü!¦éR[5®[ÈËx‘€P@VuPX`õ'<}kgL±M±ŽÖÍ3¾\ä’î\þEáNÀE©êÖškÀ—-1–rDqCÌ*ØìOAÞ³[Å6VÒÝG¨…¡žTQo/îÑP™jüˆ7€IÀµ¥¨i¿kº¶º†êkK¨*ËGÊ0”‚þ9ö¬ëÏ ÚÜÍs*]ÝÀ÷^jÏåì;ã&äèOð.ädÒèƒâ],E<¢[†Š<âÒb$“q]±¸îÈÂ9­ ¸/í#¹µrñ9 ¬¤H9nAW=uà­2êk‰'rÍ)Rª ‹b•mÊJmÄŒ>îXŒúÖö™e›§ÃiA`ãdIäõÚ˜QÉì)‚f7Šà½±Cd™J9“åleA''n3ÆhKP,Câ«›1-¡¿’òÂ9¾Å2.6‚”åGÍÂã'±«zˆ4í:øÚ]Í"L#¶!‘•’¡™ÀÚ«s’ïTôß Ûé×)qkw:L“¿w q¡Êí`#U H&“UðójšÝÔ“ÜÍŸ5œvÒE .fÝ™`8ÈÁäŠh\¼ñg=Ä7rO£9ó-dPʤQŠâC’£ Xò*øJ´Ÿ IæÝß4P³˜Ì$U ÃËÙ¿“ŒÔÕßÙÉuw|<·’‰Y6ˆÖBÎÊÿë1¸€Up À*+O Û3.´Á¯Þî[¥ib†ãhtE*ÊT¦p€ü½=O97uJ“Áðº¼2*º:œî 2úŠÍº×´ûMHØO,‹p¢&|@æ4óªn|l•8ÉýkFÖ"†0«q„Pª ÀŽ˜Àâ°®´¾ñíÕÍÌÉc,vÀÁR%1;œ6A dŽ˜ÈÈ¡ö±)ñN”™^í±+ÀYLÅÞ2Áö€™` ¶HÈã’2*Í®»§]4 or$3MäGµî}žg_M§;ºÞ©_øRÂúÚÖ)X³[Ë4±¼°Ç7úÖ,ࣤdñÆxjË@³²Ö´¡i¢Ùm– bP‚ÃUpÆ(8kúwö£éæi>Ò’¬ ˜\F”2©|mÜAgžƒž*ñ>˜¾`‘îÒTdO%¬§Y›ym»c)½†¹PGÊyâ¡·ðû¾³¨]ÝÝL-¤½Šî+d+µš8‘C7¹Oç¨Â“Ú´–º’ý<­Ž‚ÏɼnbT+±Á‹rAõ  ?øJôfŠÖQtíÊ—V[yHUWs¸w2ûFEo zçò®BËÁ6¢ËN:‹E%ìùS3ÛÇ8qæ3•Ë©ç,FáŒó펽Ûs1'¯=sŠ`dGâ-1ïæ´&…Ú7f†EŒ:®öPämÜŸ½œsÚ ,ѾÏç½ÓÃËóϱ 2³)ù” „)Ã}ÒFMK/‡ìæ-ç4Îs-ç@L‘Ùs×?\÷¬øü¦.žld,m•ž8aŽÜÈNÀì€3m$6O9± «Í-[ƒT¼¾·† ¸¾Ìè¡ç·’5pÑ£ƒ–P‡Ê~aÔŒR[xMº–Xà–vxüáƒm(Þbm²%~|ü9©ôí4ØÝ\Ü}¶yÚä!•eU¤DU2p U=«ËÂ…ìîSQ¾º&W¼¤L B³Èä•`7nÚéà“Ö˜¥ñ^‘l“\®7ïŒÙÍæÆ#Uf.7*€èw2†^ya5ý:Kè¬Òg2ɵAòFÐ:£>6+• ì$6ã‘\ö£à÷²³|>$K«¡$nbòmÑDEÁ@¼.cC•²\Öŧ…l-5XïâXÚdò˵‰˜ºFr¹Rë©ÆzsB°Õ‹´W´šä]J!‰ ¬Ím*îPá¨Û—ˆ.qžk|ò=ë”Ò|$KŠ-NîâIÒ@eÛ ´ÂRŸ™sØëI ¼Q¥C!Ie¸—·ZJ»ö1)…}¸;qÈ«Ðjv“› ¥ü„I$!\n^qƒ•ç‘Æq‘T›ÃvÄjÞ\fiœK"Ém„¸] ‡*]x€qÜc&¥Ñ´;m#I“N·–gŠMÛ¤”‚ø (ÇEEUì¼æŽäU_hæiÅÂÅp‹*3ZL£ËlbF%>T'f“S'‰´‰.~ΗLfžL™ÃÊb^Ý|ÀAGSÍCwákK˜a„ÜÝG Ú¥”¨›c²>SÁäc©ö¤·ðžŸo¬&¤’\™’ö[Ð¥”®énΙڿx ýìš{ÐzNjĺT—Ä.Y7{É Æ™ˆâ@€§'‚xç¥lw¬Iü5cq†á¦’÷.ÊOÞóÃ:aÎ;ôëH: >,Ñ–ÜÍ-̰ ;OŸm,D|¥€*Ë‘•©èpväñVt}a5;Bíîá6’ùE¦·xÃüªÜ¿ícon¸ÅfiæÈZ¼¯å ¸‚­Ë8»fòÔd£ËžƒÚ¶4í?ìW7“ ¹¥ûS¬®Ž aÂ….Áä ã¦sŠ,™Íâí[‰Ä÷.‹9ŽB;·%¡oº29ù|W¢Ç!F½‚K'Ë·Ë7cýµÇ÷³Æi%ðÜ-kk ½õݳA cØY㑲Êw:‚9~µXø+Jûh¸Cp€Mo*Äv …v„ŒíaÞ¼SV§LÀ© Œ¦h¡‰$’y'&ŠOp (¢€ (¢€ (¢€ (¢€ (¢€ZÌðüyZÿ×9¿ô¡ëOÖ³<ÿV¿õÎoý(z¨î)jÿò:i¿õësü¢«æ¨jÿò:iœgýëùE\…ïŠuï·ê1iÖÖWOæ]ÛYÚyl%2Ã3¶í¬¬N6€§•äç„Þ£[÷lv¤®KDñ Þ¡áÝ^{«»K+‹ ™-ÅåÕœÆÊ©ùH@ß·i`r3‘œRØk:Ë I|-c]Fê[yãû3¤Ž‚9^9ÌY‚c`ÄnìrhH.u§ÔÑ\'ŠüO­i^'6öq["Ú+9®ä’ÅiÝï+(ÂŒmŠBO\u¬H¼uâk¨ì­íl,Eû•œ¼2yr ²[þâò˜7'•8ê)ZàzµÁxoÆ×:ïˆ-mmÒØÙ^3^[HªÛšÀFà1çüåPOM­Œgš¥ªøçYµÖoôølíǪCo…ƒl|±31 1Lˆ=>uãƒNÀ™é]èÅrøÓÞe®•s1û$ñ¾¿¥êšñK{1¦ÙÉ5½¼’[œ4«cö…„Û˜îÈÛå¢íþ0~R7µx.¥–öÞÎßL°Š%¿gŠMÞjÏ]2ë*pÜ©É84X.zp¢¸Ïx—T×/å´Ô`´†{+A-òF¤’f n£'þy+îÏVÇÝW5iñ#WKm>{ë b±¥Ä·æ$e¾D³[ù$±‘ ƒ÷¹SŒd`µ‚ç¬Q\¾¡âÕ³¿¸ƒìMö{kÖ±žîGÛ DG™,Ÿ4*yªö>6û\³0Ò/ÒÑoVÒ;—•dct-Ï%@Îã¸[ŒýÓÅ €ëŸ¹üq bm4ygY•ßí¨nžØ`¾™öSê1Vî¼–·Ö¥ Xm*Ý´ñÅ+[ýH2¨’gŽKô¹è4Wž8„¼o=„°YIγ»ÿ­hÚ`R< ;b"ÛrÖý/ÆMwmg-Ö“{d·NáuhÁUç. ‘„*x0H¥¨'s®Åë…O\\šÓA–Hæ+lnQs!´K²<€Èÿx:ähê>&óô­?PÐîm^7»³Šæ)£iRáã] ‡_œ7N”Ú°&u9÷£·ÓŠâíȉIwsØQ`¹étW%á]jsiçQ»µ'R²þз¶‚ÂdòãÊ’¦á˜£²î¨Û¹ÀW[þ©l ( ÐEcx¯P¼ÓìíNhæêîE–áãyÆâ ‚xÈê2{Šå!ñޏnôIf±„i÷³Ak˜­da,q$22ÊdJ¡R@¬²±ðHž‡JkœºÔµøKmlln,nmdC$ð w2[G´âW”I·À …A “ž*¦½©Gà gU­%Ô¬>ܪRH wU; –ÁØ27sëNÀ޶ŠòõñÖ»§]ǵim¶Þà›èÒܤÉn`VW “H îfã{|‹Ð7X¢ñ爠±ûBÓNþÑI/•o¼ò­Ð|–XÖa‰C"…åʪH-ƒÁÀ©ÏŒDV­-æ™um*²¼3|Œ\y a°Àg 2£ úÑ`¹ÖQÚ¸“ã©#¼íHí•Ü™ÊbK“nÏ€3Ø;{©êÅjÜë36·áÿìÛ«9ô«ù¦·““!dŠGÜ’o 0Sm=zŠçCEqÞñ¯}¬_éúåªÛ˺ܶψ™yv"^!Ójž@ä塸âFÓ¤¶V—Ãg ÅÄIc4qÆ$´´†à¹L /—´¸SŸz,=jŠÆðýíÄ÷Z•†¡{Ýõ™Bæ mT+ƒ´ìÊëÁÃ+cÛ5²zŸ­ 4 …QHŠ( Ö³<ÿV¿õÎoý(z¯¤ëë¨ëú¦ž ‘Ó\¥N%#‡ê00Øüž•cÀñãkÿ\æÿÒ‡ªŽâ‘&±ÿ#®™Óþ=®”u‰wªøn+ëöŸN®¥Wµº—ìjZdS´«¶>eã'+oWÿ‘ÓLÿ¯kŸåyÖ°™Ôï½î%?øñªQ»"råFìúÇ„ „v3i¯c4iltô1"±ÉP˜Ú<‘ŽÜæ “[ðS%¢I£Z²Y±{e:j '’ƒ^pxÁ®Jxùª¯&›‰š¨Ï@¼ñ?„nµoï4Ø®/áÀŠæm=^Xðr6±Œ6zw9©Ž|3ÛªÛÈ«nK #‚ Oî’†G©õ5æn W•rÇéRÕ‹Slô»xFÀÄlì>ÌÐBmâò,yqnbíåSp¨àã4Öøá-’ÆÖÓ–UšE6_~@W áo•pz£ÐW•Ì•Ÿs9ÅD™w=SþoÏ©E§®5,Sû% ÊÀ–ËñÉ'žäšØ>+ð—Ú>ßýÚ¢O Oýž¾bÆ6nÆBàž:`‘^'¢D?á1Ð&*ß+Ì •ܸ1ãÜšè.3oÚIÃ#°#õþX®j•œedtÓ¦œnÏG´ñgƒm?ÑìôÈmÆKm‹OT”ÚHu*qŸBGJ°Þ:ðŤRİ4i"„‘ÏÔ.XÈÇè+È–ü¼æ+vN™œqîÕ¨,2<ˆ:¹ÎàFAϾkxÉ8Ýœ²º–›²LÓA§¬m&NIb<óÏZñ+8´ëIá}™Z6’KŽP'€Hϸ«º³e­Ç;Ø9c ìpzÿú½ë%S›Tl©ÙÚ[ž‰sû@øÞB.¦X8³<‘ŽOµuñEKH®½Ù",‹þŽx 23éÖ¾WÓ¼;¥_]ÞM} ß´8ËK€oaî:ÖÅâJ~X5}]G@ Ùqص•®bݯgq o#çj)cë€+ÎŒ¼ =¤ð·ºa4ñ6–¥fsŒ;Œ|ÍžrkÐõoøóºÆqå·ò¯™-#fýÑYÉÛb™ëz‡‹¼©ª GI†íSfÑ>˜’Ù€dcqÐ1ÇZzxËÁI¨C~šdbþÄ1\9|ØãU±¸W”íüévÔs´#Ô›ÅÞ{ÙïdÒa{Ë…)5ÃéŠÒH¥6ÌFXãôã¥i/Œ<3®Ü‹Ií>Ò× öR.lÃ+«ò1#îgt8é^7·žµ¥£Žò&ïÈÆpzg·ÿ^¦UšWUÙô%¾ŸÍqq ¤0Ï35Ö5W“hÚ¥ˆäàp è; ?²íLð›[6‚ ˜cò×lyR¤¨ÆUœ}Ž„Ö7†üO&¯¥Gq ´ªÀ’=¥¶È¤‚¡º0ÊõÏqGƒµø¼WÝÕ¤pÅopÐ<~^çx׎•‚Æ·ðÄÓÙÛs•ÿ„£ÀV÷7Viv ý—p¼5<¸§È\§Ë÷†À3èÚ´äÕü(äï¥Ú±¾M×/ýž‡í*~oœãçç{ב|ZÖìtˆ²éö:[¸˜”Á…S9“êØÆqí]##C§EŒ2–ûKgŽü+J˜‰F)®£3v‰†%Ž <Çð±Ç¦(U÷ãtÞKö¹ëSj|6šm/m$žÆç,öϧîÎìÊx'w<Žk nB…\±<{Õ‡RÖw6²æÛ6áÏàÆ·Sm\çnÌö»/‰þ €ÛÅci%¸ 0´ý‚$l‰ÀÎ2©ZüGð™u%Ü0^‰fq"g‘ UuÄ`c`ùäéÉÞÜó^®RDdä†íWÆž×óOo@†týà:¯×¯åT݉s±îÿðžx+ûDjƒO_í  ÏìáçG÷ñ»8ã­MsñoÂöñ<³Éz‘ %˜ÛŒw¯3ÀÑ.&N˜t›®ÚE¥ÜÁ#‘!ÉB8ï^›ÃABæ¬Û±ôž™ãýRÓíïmß‘p‚DÝÖ´,üU¦Þ]ÁoÚ<ÉX"œr{W“øNÜEám0-#?˜ÍtþöÇü·Oý ¼§-lzº\îüKªÙhš桪+=Œ ûÕXüÍÊĹü@úWÄ4ǤGäZ¿™mÒÔ$žY0§Üs]Åá»áζ?é’ÿèůž,âäŒVˆÆR±íÓxÏÀ··1Ü]iOpŽdI¦Ó˜;c-¸Œƒò®OÀô«V~2ðuµåÍížž–÷·ññq€Ifÿy€Ë~$×AJ½íÓDóž£gâ_Z4e¤[[´²,²4j!wWˆ°`=A稫“xÇà '³H&Žpïd ó„|ŸâQÐõ⼩OéRÏz,Ìõ$ño†¤ö«i‹I‹´Ð}ä.I}ËŒÙ%9'œÓ¯ïÇ€-ñÐS¼j´…Ìtz¯†ôû™îltèmnn 4³Ad¨ò’rK2€O$Ÿ¯5lø»LEÏá®HÁÏ"£x £”Nv:¹|k¤Ä¥›íXÿ©5Iñ–«%¼v¦]Ó«:o…çœ×šjPbÖSíéï[^ýÏ‹´«}Ç e1ÆÙSÓñ¡FîÅÅÝWŒõm#JÒëöësgq0„Âöâ`íµœeNGðÓ¨®j?ø0^[Þ&žîÞ/"Þq§€ðÇŒyhØÊ§m£jïŸ>Ñ Ø¡ízþC–¼¸iƒh sB‹a)jz>-ð$©yo â.Åž=1VU\c€ÈqLÓì¼_à«ìì4¸­m.  ‡MTŽ\ç;”‚GÐמ®™žÇ¦5¹Æhäv5HÓ¾2-öϘûßϰY70]»¹¼döâ¼×ìsü¼jA¦Íå‡Ç'"—,‡ÌD>)ðak§:\®—˸?ÙÉ™—aøù‡®ztéM>(ðVËd:D-y·_ìÔÄ<çåùrÀ1Î yÉ´¸Æ6ŠCc>Ó3Çj|’[…Ñ釯ÞÚA±ÃÀå÷‘Ó¡›ýîO4Ëßø>ööÞòþÀ]^[œÁq=€’X}ш$~æŸÙó§¥Ù®s’M’{ ™ˆþ.ðh´º·¶²kE¹“Αí¬XËÔHx9pÜî j[øCM±K++iâ¶H’Ÿdݽ(ryo”–ÏæÿÙmµ‰'ç‘Iý”ÜdžiòHIÓ|uàý.‡K°û Lw4vºx‰\ú gÿ¯VOÄïɽÏý{òÃ¥€Às@ÒýE5I‹˜õñG㩾ÿÀc[žñV›âoµfÿѶ™<Øöc~q_ºkÄ›K]œ÷½+Ñ> Ú­°ÖqÆÿ$ñí¾‡M¡©\ôzŽY$ÜǯŒ’}…IëT¯³æÛ ÿþU›zµ/ÄÒJœnÛýÒÀÖW€ãÊ×þ¹Íÿ¥[6ȱü ŬîÏÿ¥/M!ú¿üŽšgýzÜÿí*àõeÿ‰éÿ¦òÿèF»Í[þGM3þ½®”UÅj‹þŸ{Çü·—ÿC5¤71«²0æN¼VmÄddàVÌëÁÍf]íQ“Ω™#-ÀäTc Ö^»â­H,.ï¡ùf§s~B¸ËÏÍy+ Jy+ç\ª?ÿÖ¬Þ¦±G})<æ°u}sMÓ³öËÈQ¹ù2Kß#šâ®¤Öõ/ùê­°Ú‚œ{÷¨íôÛ;^c„;»üÇ?C±ªGcáŸÛÞj-¬7bF—lR*G'ØcùÖé±¿Ôæ’â ©Ó{n1Ùb:žµbxÊyÚö{iš9c`9mçõ»×r4­N¶Yìä¹¶xÛqù'‰fpAÛ€2kžôԮ͛|¶G/©´D,Í«°Hž)2J€?Bk*þöÉ Ö 34Ÿ6Fvã>ƒ¥]™u-CQ»šúWÉ oõÛË`mÉÈ âªkº:ÃÚÊîIÄb‹¨+´³ryÆï™Ó­àú™{Û3„ñ¯¨Ìá^Ó•ÂÞr»ž:R.éâWw¸ÚAôô5²¶zc^¥…Ü‘ÅÀe­Ë™Xœ*€¤m8Á<úõ§O¦GDÄöÓ"ýØ£‘¢aŽ£æãÞµIX—гm}m¡xVù¦hÖîú/³ÆŽŒX•*ÐÚž»šp;­¡w”<³ÎÒã· t5§¤ØµÄ °-Í`ø~Ùe¾™ÄŽËÈT-§<‘^ƒ YÆ×¤žÂš—ºL£ïh}!ªsguÿ\œãµó]²ÿ£Çþ诤õ/øóº÷‡þ:kçuýÄîåYÌ–‡…ö¤š-&+Á!¡A«ºb´ #ƒüª° b‹[ÄYñ¼¥[D»¶þ=D¶e'f{•¥­•œj–³YBœáb@Ï< tÉÉ«±ÜD©zX ä( oJòñ¬HС…Í#.³\ÀöÉéíRCâimQãÁŠ7˙ʟbqøWšã+ìvÞNcÎi ZÚ÷Åš]•ƒ´²Ù7™pê8Œ¹PªHïÇJëüE8ŽÍÊ£1(…RØÉ§5 ¶²_;ìlŸ¾6Ie†2Îàõ$‚IÏBzSg¿{ Ü‚HøÉ#ÜtÁ®«¹(鱃¨“hä,mK^®åeD )l (ôlUKk…arc&RO™#s s´wþµèÂêÈ (8Ú˜4E«ÚÁ¶Žf#¤PvóØWLg.ˆäsŽÌáô Q³ÔPº€[ÃI<-#pÌ£+’:|ØÍc]øoÄѵ´2‹H¶½™ÏlwÏã^¬ëðÜC0Š{yí>J…qÕGÊOtÍ;Âw Úe³HË%ݾøÌý)bOû¸lDèG£®…*x‡Ê™ç êJ̵“Ž…|þŸÒ¹ÝnÞX-çŽx™…Þ„G¸¯qñUÌͤˆ-ÈI¦”aó-W [>ØýkêÔj0]]j­%$ÅnчÌdõ9­°™J𼑞+ <¬v:\2Â0ÛÄ¿’ŠÙÐSþ'6'Òeþb¸Æ7×Ëe)˪䂧§û?wzCªÙtl̇ƒžâ­]»–¤œt4þ,óð÷YôÍô5¯Ÿm†9¯ ¾,É=Öëšèi_=ÀØ\Üæžæ¤,8«k()´ŠÍ‰Æ8©ÕýM4È/#± ÏŽUÈ€ôç­[…× 8íCh¤‹ÐŒâ®Ä½+6)]äòãÚ2Xž¹íTµË¥…ìÐÜJ¨òƒ#¡8Ø9ÇãÒ¥¾…[¹×ÛÇÀ&´"ŒqÁéYÆ´LtÖŒU"N{X‹¸w OÎ[âÅ¥ºð±ØNÇéµ@«ºÒb8Ô ßsß´ÙáøÃu¨™[löó3DÒ3íàcöúT©rÉ›Â7…Î÷â4›@K{qò=qiå¡2H“¸õÇÇã]ÇÄFòô›CŸùzîß‚;×öŒc °NžžÕpzOq#Œr; (Ë,‡·¯JD•z~>”Ä”®ß—•àpyä~uw&Å»[1p*ùU¿¸µ°•ḓèŠÌO°dŸÀÓ$ÔÞÝÄ22¼€©ØqŸZεԢ’òy÷ ‘bX˱%Ìà¶Osù ‡-F—rÂɩܜØéËXÊÉw*&ïø9ü:×+®xÇRÒ5?°ÉmÞZ‡&e`£ßôÈ5Ô.¥° 0IÁýkñ p+ÏzÊÌd}ó>z§ =«¶¶6„SÜô¿j?ÛRGsu pZª$òÆÿxÄÄá—cpçž0k­ñgˆ-4kØôû í—ošz$H #%ˆö==+çÏjW1ÞÞA¦^Ë ª¢‚NVt “pp0y¹ÏjõkAu] VÄ9kx°ð±ù„A¾`Û¿5äu®*°“¨œßºi¬Ò2¼Wâ ^Ö6i"Ñ`P¤â v}¸õbG8ÅGácûNÔ¤êŸlCó¬chÛýìjŒµAâKN¶yÀydI¥XƸ$Œp 8úÕmjÎ}"æ-NØyjă”p Ô®:œb»cjoÝØÅûÛ¨6¨pv†Áç³Æžf)Uñ¸Ûÿγ,õ(5 =%B¡_\äÜ{Š´n¤YchîfM„É^:d{W\d™”¢ÉrY j9 ýO©ñÛÃ$²*ÝD0*FNqÇ÷ªír]±,­.Ñ…ÞsÏ­$³ù²üÃéõtü*ï}+!ïìX0 p}G×gð¸¦;ù_û=q/"¬1¨'HçŸ×ð®Ûásn¡@ˆþ¯QSaÇs¹ªwßë­¿ß?ú \ÿ§}þºÛýóÿ ×ØÙzQøV7?ãÖ÷gÿÒ—­?¨ü+ÀŸñëû³ÿéKÕÇb^ãõù4ßúö¹ÿÚuä~4ñ߇ôFù/ïãó’â@bæ|‡9àW®êÿò:iõísÿ´«ä/h6'Ç>$» ÒɪݱÝÐ~ýû~UQz™ÔZ+šÇÅË›×h¼;¥;ž‚Iû{àST-¬£d×ws®é%d?ºŠpä|Ç"¹ëMÁ]jÎ…'¡ÇøsÁšïˆH:u„¯<ÊØTð#Åzw‡> Û®×ñ¤ÓÉ‚ÄdgйV¦»ãÉl¬-.4û#öIã&?=×r“8jŽ=+œÓ|}ãh5÷Kµ²¹Ó6–  ©å7¯Ú3Ÿ¥q·^¢½†ãÊ{ƒáÝ/@‡ËѬ ´rç/#~'šÑ“ÔÊìGûXýõ®./ˆW–ñ>ŸåÔ² a6Ò6  (úæ²5oj±¡ó#°Ò“û×·A›þø‘øšòjN¤Ý’7….­õìvó®.a‚P?ç¤Aÿqþ(µÑ!µ–Q5¾™q´…‘"ýÖ_ºAǦkÏ5OC6ï´kZûrÊ?²ÇùŸ›õ­tµÓì´A©6™»h·8™Ÿqè»›žâ°têÑjSl銌•‘ä¾-ÓPòµ H§žxÆ.¥ŠAµFVØqí\¼w…6°$®AÆàÙü:þ•ô[‰!²† e2ȈÜäî `œ}s\ÕŪܙ!µ¶IIÉ‘bP~¹ÅzTs_³$e<5µLñOÚMi o h&¼&T‰†cž‹Æ1×&¢Ñ-ï¦i>ÅÈê2ÎØÈú“Óé]¦µá‰õÝCSÔZê³¶ 2–-’€|¸í’zÔÚm‚i^·IJ²g®æ>ËÄ׫§ ®î}[Nk6ÆÍe}JWq6æ;xÃëÈ“Xºm;3>kètVñéQh2Ipì5&`bQœ*úñÎr?JlÒGkglˆ»©f(Á'8Æ0éXíp—·¢Â<°=BާëÇëZsD¾aQ!¸ÁÉ—nÕÉê·^}1TàTøt(IvWi?Å’;f€Ó\DÄ!òðwqšÒµ±‰Áš`ÞPôçô¨/oáªzœÒ’WÑ#•6În Ë­:ÑÒXn¥+) òd•íéÇ8ªºåÔÈñ›96†ÞqŸÃ×ñ­9|Y§ùžR_C½@ãñ纎áCü¬r9àþ•¢…–¨·=yŽv=búêtޱO çß9â·þâî-Àéîj´˜ËARņ#=sŸéI$„öàqN)"*Jò¹;™¥™›x•ý‘À^¦<ÖÒy‘HÈÞªiÒI´dãžEUy²¨ sŽM)EIZH#&âu:BjšËZ¥Äm5³¹Œ7–…ùˆ-ùf©|]¼»Ó„zm¸ku B`ìùsŸËֺϥ²ª\G¨½¬vñmhç8 ßÛžÞƒ$Wšø·Yû‰µ ém4ˆ˜ãæcúpµ4éB? Ó').ijÎIµž×QHHs’ÄîÇsŸzõ†³+ø¿Ã®«±šò,…à}ñÅq‹[Èâ—lvÄHWœ<È=ë«øuˆüsáØÔ‚ú?ï¡W&¹ Ÿ-ÏtøÓv–? 5ë‰wŽ4û£ÖD‡ZùzÏźmÄÑÂ0•Ø(_(õ¯¦þ:ÿÉ'ñ?ç’èÔ¯g’H"i` ²¨Èn8ªÕ#Ö¬ìnd‹Ì,…Iàgîû}j;Ö¹µÚcDb9éŒWà¯]ÛH‰<²²îópûØïŽ™Çzôãb5­>âêÑ“|+æmf°Î:w5œ”ŒÓÖÆ—«ùíoÚ)y4·‘ŽÊ§]$VzEÓŒ¬ð’2|§ÛýìžÿZ¸w‡í—m<†8fˆä€UÃÖ´òT¾E‰þC väô$?J§Ô%RÆî£iq%鼎áíÌä2(UPÌOÊ3Œdf¥ÿ„gÃë Ks¬íÆ—È„Gu»2:v㜓\æ¨k\¾ðÝÂx~ò$b….íÊ‚dˆr3è^gîÌó–¹OšU$*±#ŸãȪ~éµ5ÎI³Óì#†â3W×@½ÅÊHÌàåG#ÜôÈ®ƒÂÅ¥ÂÛÇ"„¸$²ùl6c¡Üzý:÷®Á­xó9Ó®$I.b¸‡6’ŒGQÀÍzFƒá>d¹’y.¯/îÿå˜û£q×5—<›÷QsŒ)¯yÂHŠ2̪¸êM(¾µ_ùj§èkl‘ÇÊGÊ8^ã‡øTfPp_<’ØæçLé#¼¶|m•yõ«*Q× © äWŠø×T¼:ÂéÌÆ5}Ëd>™ì*dž´ûƒiÝ­õÄ.K± ãŸ\ÓU_SNUËÌ{…kœÒõyàM·²­Ê c„Ù$]²ÀðG¸=«rKƒ5¢ËcåL_wI… ÷Î>•¬er\z£?W¸…Oo›òçúUO®ïÉ7$ù2¾Â¬kR…½e ³ŒŸ©Åhx28F¢a‰ŽzðjTy›:©´©|_º~±sÆëÕ_ü‡'øW•i») 7?…z‡Æù4üÏúÿè©kÈ€õ£™£åÔ½•²w'ž*m4ÍwE ´‡ ™Æãé‘T#.»„dêTäg‚9®‹Á·PéWMsmq7– B"PÛIêy"³«_Ù®fÊ…>g¡…®.©ÄqM¦]Yļ2$mÞûº}:Ö6·§êzU´-q#Ú=Ÿ”Fòù$Îv ‚+Òo.Ö_>n‘i0êqqœþ +Îxõ)ntª<ïo¤›t‰)Lñ¶æFãê¦Ï Õô7)ghû!Uy³±^@’G\qéšèn5K¥×EíÍ™ò 6ø×¦1œp>µÒ'‹æ‚K}æ.AÂ:…ð­)n¿2½Ž]Ce–êÉ2cHÃ<ŒO©^=y¯@ð*\蚌qÄó­Œèff™8ŠUÏ „w–ÓÆ:³Ê«‘!$ÿê£ñ5·eâ Vò ÓEco˺ï$àç8úVq~ï+ØjÝÑ‘©xBòß^:Ÿ‡¬h¦81G‚ÖÍžWa<œ¯aߥuÚÃ'»´ë×sCòð#†–B¾Ýö¨#ñE¼:º>Þ®$Øä…l`;z øé[‰¯÷<:œ–Ì%*`ÜÈÁwpÀC søÖN½EöqlܾðŽ…a£Ë›¦˜ ³À7Ë×Õ²OÐ×–kV—zMé†V¤ŠEH¾£ß×Ò½¥nÔõÇZÂñM¾©`öÒíV1?#‡¨§…ÆJ2³dÔ¢šº<ˆÝɜ淺žô˨^Þy"”bDm¤UféøW¶ª½ÑÈ㮥¹5…!rÄ`cõ¯Kø-x.—ZÚAÚ!?ú3ü+É> Wª| wÿ–ûRŸµ“ÐJ6Øõ/ñªwßë­¿ß?ú \íTï¿×[¾ôOb‘§§õ…cxþ=`ÿvý)zÙÓú±¼ ÿ°»?þ”½\v%î;Wÿ‘ÓLÿ¯kŸý§_+x¶Cÿ gˆéý§v?ò3×ÕZ¿üŽšoý{\ÿí:ù+ÅòãÅÞ!ÿ˜¥àÿÈòU-Ìæ´2oï~Émæݶ¨ôäÕ¦Ž{ˆÚÓÍ‘™FôÉ%[¾9#?UפYcŠÑÛŸaZš%ŸöN‘ý¸d»»fò$RsŒö‰Ím ñ‡ºÑɵtAmךµ¬3’URzã§ç]®©v×”€’cˆùh§°ëÇéYº&uc«Ç-Üùkž²²”•ÈÆ~µmbbæ@ß–ýj+Û™$mFé³ðúÿL¼ð¥Õ“É:º—ß4AÀQ’:ñ‚xÀæ¼C\Ôõ½_Yk9.¥{. oj3ʨ\nÇ#«¥YÚøkP’âvŽòi8D`*£söG̼ãé\?Ξٕ6¾ Øõ-Îx¨ÃAÕml‡^ª‚GQ?Šnc°†ÉuwŽÚ%Ø‘BÅ@ö;y$œšÈ{Ø‹y¢Cý÷$ŸÌó\ž¡¨Ejv¶]úíªÎHù”{â¶xZPv[™*õ%¯CÓü5`umjÚߟ)œ<‡ÑÉ?νŠð¤‹†E*@#¦?¦+æÿ ø»Rðýß›jèñ2íxrÓ=Wð®úóâ¤/`%²Óe’ã:;ª…>¹ê^g¯V¢åWG¡†¯N1wÜôÆàäñ\~­â;J™””¼»ä¶Œäîõb: ómsÅZî©»±ejÙýÜ Œ©9þUÇÿj YCiùYYI?ãK “¸{ÕXTÆ_H£Úõ;‹_ÇÑ 1Äê71mÌNz ØÇ'§jÄñ¶«z[-¼‘Ȳb  ‚%F2=–¼²ûR¼¿ºžWÿd¶åL´–@ñ‰Y™„çn}zé8뱇´gUi<·O4¥w>cô®Ó@»kvÞŽ2;šât©†Õ#>•ÑY;(8ô­ÜVÈÉI¦}¯(:N ÿ—wþù5ð~›QÚ@Q1E$õ$â¾ñ׸ҵÿNòè&¾ ±oô8?Ü_åRS=7á^•¡k²ÞXj÷†ÆýöýŽmØËw\taŽÝkWQðõÿ…üJ¶Z’åáyíå²²(ã>ĵåHÜ‚~½3ƒ[Ö~+ÕúÂ-Rñ®¬­•â‡Ìùž0åIRÝJüƒéNêDr[Sµ·¼k¦¸€ñº¬|úãô­ uû½{ÄwwÓ+ÛÛÈ«ÀYyÁÜX㌓ÀW!}¨B-S"*—,FîØöö©<;¾õÔî3ŽG^9©ålÆu½ŽßYÔ`Óô±<²**)g ô¦~½«ÆµýbïZ˜ù¦Dµ'Û'½3ŽI­k&öýl!|Á .:3ñôjσ4•–1xÈYÉH‡ Î?3ŠÒ1¶†irG™œ‘ÒõÔÉ¡M¼áN{às]7ƒµ!ž•å×^4Ö§â9!:|‘ç·^sX×Z…ýÿ7sÌ;‚Oÿª¥ÄQ¢ÏPÕlž½ëèŸ ~ÎH° ¼Q©ˆ¤àýžÔnÇÕÏôüêÿ‹>|7ðýš¶±u%¼ª ,vÌ|ÆÕN>):‰t6PMXðm>å™ ¾s<³6çr:µwÿÂyáÂÀóï¡\ãYiñßÊÚa¬Ëæ=@r¾øãò®»áó㯌söèô!Ys^Fʉí?9øQâ ?çŠèůg¤¶•z’+ìŽ?òJ¼@?é’èů—,t=NõwÚX\ʇ€ëÇæx­ù’Üט¬¾LvQÌŒå]ztP;ý ®÷ÁšÇÙ."9Y# ×—j—O§Áq§\Z0™I1—| z‚oJƒ@Ô®4õi#qåvFèO­i¤‘‹¦Ñí>0´Žâáµ;(dl˜Sè=«"ØB¦¿Ö¢Ô´ /V¸†âq5¹$ñ†YN:m?tý8>•~ÎîU†ö6Î0Hì=Çqî*ΠöÚu”—pI½Us÷¸žôšRÑŽQw‰££é6–jB3Fd¨àWAognc ò‡Î9|~"¼&ûÅ—÷.oxöÉŽªO'ØvtÞñÅÔ2ǯ"ÏùVá§?Ä =Ç5¤i¤¬*Šoßg©J·6¬ 7œ£ÃƒøSá¹YƒÓƒê¸íImp²2¥Hìzæ«ÝÛ´mæÛƒ»Û½7nss\Åñ¾€ú½’Ïd@¿€î‹±öAzæü®yÚ A˜ù‘7XqÆ—µz“4ìˆRí´nànô>•ÌøãÃK©]I}¥³Ô@Õ~ä¤c¯£{ÔÎΊ5Õ¹fk©72>ЭK2ÆF2:}¹à÷®Ç6wR,Shú•ÞŸq¹¶ì‘9àAµsw:þ¥£Þ4w‹5¥Âõã†ÁëèGÓ5\ø’ëV»†íq>vDŠSÇnþõ,“:`•÷ÐÖеz¦þÞ¾}@!ÎqÆ:ãükÓþ jé}âñB­öiïç·Ò¼7OþÔÓ—U†úæa NÁm˜d1îÀž}Åz7ìïtÒ|EØÄÙ̓ø é‚Vl·.ˆõ¿Œ‘<ÞÓÖ"7}¹{ÿ,¤÷¯:Óü-¬_ö{KÉþ%‹hŽ8¯iñOˆ¬ü3aåô/2É0†4@ Uˆ<ôáOç\¥ñ‚õà :‡c3?AY¤„ûº‡‚5}"ÀêW6jé Èï¹±ž¸Î8úTk³Fª²ÁåöÆÌJ§«xÓ[×íõ ¹žÚ^>ÙÖ%ÌÐEr¶ÒKu ì¡Õ7dã×éô?…yYŽUu‰Ó‡¨££:YuˆæàA`sÄc§à+&óP².–p’r2?@k—½Õîm!Â3fç$ŒŽÝ0qøÕ©=ânb<Õ<ð™þµâ,–§o´¹ÓÉ>šÃÑWðí×ñ4¥‘óBßQ/5Ê´ÏœƒMûDŠx5Jƒî>dtÍÝ™6wC:d®X0n:ÅrW©é¬â&høÃÇ!ŽE[k¹Rinõ(, VÔîá·Gä$™faë´sø×EN>í®e6·.ø4Ï®jÛÙÚÈgVWšâi>P™çèùIôÏzîü4ÑøÁvÖvÒÆ5-=˜Iåò¤v®>xĪÁÔ#œÖÜFÖ`m¥“ÌŒÿ¬êCŸgª*œ¹tgÖñ~›ªc¯ÚÅg2(c”y‘99 A9Æ}:Wlþ ðÕôoqoª0$I¸õÁȯ~øÖ_ _ÝO6™¨·(£žLaûÀyëÛ½t­ñRZFÓ4‹»Ù-j„ÅôÀ@@öŽy^ÒÌ»+]3Æ÷bñÔpxˆÆ{ÏÙëX2\O$dEÅÇ.y'=”zÿUŸS›RÕD×w»–`:ü ì~Y¦±ã6Ú\¢fÁ/#ðÏ?…mÞ׿ä¨cþ}äÿÐM|§çìgûƒù ûÓ_ÿV¡ž‚ ?ô_ØH¦Ò cî/ò˜ì\Qœ/CëTµ%p¤)Á<±éÅ\óBòLÈAËÜÔ­îSJÆ$ñ¸m¡›ŽÛ-ÝåŒæ[Yš)1‚AÏ[û9¸sÁÏ®1L6eHõïZó#7ü2î‰_$³e˜“Ÿ˜žkѼ7yЭ6àaôÎ9¯.RÐŒ¼{LÖ.´çck(~bŒ23ëê? qfUaάT·e‹7— yQ<É2 Ë× ÈÅy?‹µí=^âHøRäì:f¯êÞ"Õ5ÅXg—ýáI²0q××?S]…þêZ¶Éîä[;iÌ뽘~ ð2Ä ™ÔQܪTdy¼p `‚I8¯@ð7¯ø­Ñìl ½‘ 5ÕÁòÐ{óÉü5ë¾øq£hPÝ\ÚOqµAFÌ%È'q¨ÇQŸ­mëÚÌvÁä½ÕÆø¸>þŸÿÇÅ\5dODÏ|øÐïÃ-uѰël¡.+Çü9ñi„0x†G©uíèëßë^Ãñ¤gᆼ1ÿ,—ÿF-|®…”‚ô­æ“Ftåcèô𗇘<ƒQYO}¥Ì'±šKw;£lgÛ?:ûãÅž Ð0·Q²L8ê=¹¯ž¼}ð;XÑÞY´0Ú­˜¶Ä¸™ºôoÃò­”û˜ò\á4‰w%’/YEua¾|t'ò­?kvZ]ªx~á®l.nW„Ý·ž„Wžê2A,‘Ë ˆ`Wk)ô ò S†Iâ1 •Œ) “ËÏŒ ØõÆjÒW¹¼§¯øCE‹ì0ÜɼӒC2†Ø£#Œý+s[ð¥¼ö&[$1]ªî_—hzØþUŸá}·þÛ¸¸ƒ!UI'=AúsŸÀ×A¥^Êm’¢ï2ŒyŒùÝïô­’Lᔚw¹Ã\ÝiÏg+:Ûî×a8#ð?λûk†t`0K {×øzQoñhc`VS&í½ò›ˆÿ¾…zm¼Íªê~e ÿZ¨««VÒWEKÝÖ×L[;Xn<`‘ßã¯çVVãrýì_QRk..aið7 Æ=qX¢êµù6‹7’±î '99QÇl~´%Љ;ê‰uxm.­œjÃ4(77𻀼ôúÖW‡ü;e4ÐÜèÖpYÛÎÞZßÃpL`ýáïÓ=êÞ¬^æÐÃ&×!d ŽPœ63ßü+ rãMÐÞKx¬ÙHGšvÞX/jôäþF³”‹:è=›2~%Z}Žq Q¼€(rÀ}Ìd6ãêØã·UßÙ±•¾%Œ~Å7òÂkZÕÅÌÒ®®c‰ò[÷Ì<ÜðKóÉú×mû4gþzóÿ.Sÿ!XÆéXïnèö?ŽŸò,é€Oö‚qÿle¯4Ò¼==Î׸ÌHOøˆúv¯dø”ŠÚE‰*¤‹µ##8>[ÿõë—²EÎé÷ÏjnISLÐa·QåD©“ø×—|^„Ý^Æövïm§± #¦E<àÞ æ½ÖËR³ŽMŒOîÇœõkRÒ´oY¬Ð[ÝF˹s€Ê=Tõ§³ºÏgñÝ䪚¬flŸ˜¤a$Èþ.œŸ¯Zгմˆ·ÜÈ›€È’.žÜf½—ÄìîŸFÔ͸<ˆ®Sv=·1^Wâ_†$Ò%K¦O4*N.-ÔÈŒñdvú×5L$$i²CáÖ´‚c[À§ÕÔŠ´ ³˜n‚òï^{q¤Ï þò'RFSÇ×5J§Àú‚EsË/Fh±ª=WUÑSLð]׈$dhù‚$`rAàœvÿ ñÅŠçS¼i® Mu)ÞI=™¼ÕK¾ Ã.H Ïq[>û/öÊ-÷ü{9C!ÿcÕÓJŒ}ÝÌ¥77©>–Ê„²G&ÑÏ–ÜŒV‡†ež Ê 4A²@ ÇÛ?ʸ=#ŲXéÚtnë?~å¼²I<ì_Z•uBîGó%òÒLnŠÚ¤g¡O_ZÊ8XA{£•Fõg­éfDci*;)ÚNsõÿõÖÒÆ$‰d¯_jäüfóC4áWÄh¿ÞÇ9èfÐAn±u*¸'ÔÖÊ*À¶9éa5Ý|%]£W¾OþÏ\­Ôc’+®øV0uo¤_û= Yˆï;U;ïõÖßïŸý®§}þºÛýóÿ Ó{ zQøV7?ãÖ÷gÿÒ—­?¨ü+ÀŸñëû³ÿéKÕÇb^ãõùôÏúõ¹þQWÆ^2aÿ ¯‰AÏü…ïô|•ön±ÿ#¦›ÿ^·?Ê*ø¯Æÿ¿‰Ç¦¯{ÿ¥NâkC&i£78QšÈ@Ò;;wäœÖŒ£r0ÏQTF#7jLqD2(yãŽõ€îÎóÏãO$±=@ëÒ•PŸ›b¡c¶ÜŽOzê<âDðß‹­5 ·q˜åÀÉ Ã}:þ2`cùTÚSÁ+´w¥(©Åʼn7t}=¨üJðv§G¨E©‹ûõ¥½®s#õ’8ã_€‘ÈÉC 2|›³yIÔøŒÍ7ÃALr_: ‘´6Þžýÿ ètæ–7òtÕÄ«ÊÐóúòkKÎÒšÎ[‰$WŒžQ°sŸqÉƹ½OYyƒCb¢Þß8Èêßá[k-Ä’[š¾µ ›\Ü]3§úW'}s=ì¦[© 7P;-!EP[ ç¿Z…ø\¯RzQ/„ÞågŽ@cƒÍD¨AÏQR–ÎqHÍÀ5¢!Û ä%º€1Räò’*¶w RÄtcùÕ~„j}ªÞæÜ8O66MǶå#?­|÷ìÝq1Æ|U*¡ãÉ»À«è¹ÿÖŸóÚ£ÅH>ÙÎpyñLøßüUþÎRIŒøšßúsoþ*¾ƒ¢‹ >¯ìé2ð|OþœÛÿЧ7ìí3 Áÿ€mÿÅWÐQd>kÖ¾Mf–þ^¸n¥ša qAh¡˜í,OÏ"ŒaòsÒªGðPP2×Íÿl­?ù*¾‹Ö8Ôt>åøÿè‰k+R$j:½ÝÝÍúØÙ$ "[ܲyqûGÎßwŽI’–•ÄÏOÚšcmÓ+_þI®ÇÃ^ñF‚Wìï¨:p6ì´Á„}§~®ëOicÖôYaž÷ìWérËÅÉ—|jŠQˆ lcÉÆr3ƒ:šR„zIžg¬éž-Ô-¾ÍgÞŸÙ Z¨Ï¹9ÁôÄMð“X¸ÉwöùÜœÉk´}Úyükè:1IF+D793À‡Â[Ýßqþůÿ$Ô‘ü.ÕTå ¿'×m¯ÿ$×¼ÑIÓ‹œ  õP1ö{ÿûæÓÿ’i²ü2Õ_þ]ïÇákÿÉ5î”b’¥ö’<_„ú«ÿË+áÿµÿäš±áß…ú¦‘â-3Thu VÎå'hÂÚÛH8í^o„>2åÓ¡öùÿÙªô_ |aQ©Ó#nøûl#oÓæ¯¤èÅ.TW;<¯Á°üBðóˆ$Ó~ÙdLr^A‘ì>ð­/j?uöhº2YFF>{Ûpߘsúb½ ФK»>]ÕþxÛU¾žîîÆ¸˜ïyä@–õåŽÆ—àOYÆÝ>Ïí^Åý¾»¨o§{[‰ã…çx£gX|ÎBç êN0=è¸jÏš<-ð»ÇúБl-$L…d±|ÃÓïu®ÂçÁž#’60h%%ë·í¶áKßdŸÈW] üF‚oßêºâYZ-ªÅºÚÒå§N6HŒŠÊùÀî Ï Xk_ÚƒM±’à³1{9#†÷®æÓÃÞ, þ— m=ü«Ûvý ç]m¿Ä­â×|QjMveŠì¾Ï™å2)d* à “ÈÀ8«šŠçÕ|[}£¶k¼Î'•@Ú\1éû¿w“’LSShS£nrC@ñÆFЮ0Güý[ñÚä¼SàoÜÝ[Ëá«H¬Ñ K‰íŽ[×;Ïå^ž8º—âï†ÒÆÕ!µ–(¼÷žS#nˆ>U" Œã–\úÕ +âRª%Þ®ð¶ýmz¯mlë$³MpñT,p8œä“ŠFÉXxDóà‹N­æÇ¦nc’Râúg¥R›áîØ½í´2Êwè°?ñì~•îCâ>ŒÿbX!¿šâæIbò¾'ˆ¨pÙ#»Ž…‰Ï®ÔðHôéøT¹7¹¤a±ò|¿|pÃ>Óñ½‹ÿŠ®»áÿx/ÅÿÚÚž.-ż‘í®àgÜøgQƾ¢•Í58¿ÿlk6ðÚøzþ6Žq!2ÜÚ´+Óì+ßIñ CA¸?K«aÿµkÓè¡0<ªëÃ:¥ÄÞshº”s¸4w–¸ÏÓÍÅ"hž*‡Ïò´ÉÜÊÛy­•†:Â_çֽ[Sçh,qÖ¯¬Á F<=|þ^­O8÷›Ö¬%æ²­‘áíDö¹´û^ºš1G; NJìÞ^)¾¹¸Ï_2K'?¬ÕÌjÞÑõRÞw/!süV÷vÑ‘ùOÒ½N–—3ç=gà‘ŸqÒôýb=âk7þ³úW)qð+ƾp6––êÉ÷]¯"R=¸nõõ¾(¡»î+u>Qÿ…Eñ/ìbÐÛÚoº±i/–?à;¿•eÉðÇÓJd–ÒÄ»œ·úlã_aQR’A«>GƒàOS­…§á{ÿZúÁG*ýªÁ`óå]@Ç‹Šú†ŠoQØò? ÛCei,ÚKyläkVŽB¤£V'*H<89«7r “š³i¤ßÞê>!’ÒñÿjÊ3æ"ÿË8¾ž”é¼3­¹ùlÇýþüh½‹ès·2ry®¿ái%µb?é—ózÛ n–#þÿÇÿÅWQð÷FÔtí/í;$Ëålýâ¾Jîô'GZ‘3¯ªwßë­¿ß?ú \íTï¿×[¾ôÂFžŸÔ~àOøõƒýÙÿô¥ëgOê? Æð'üzÁþìÿúRõqØ—¸ý_þGM3þ½nöU—žšifŸÃš$³JæI${Y%‰Û÷³É'¹«Z¿üŽšoýzÜÿ(ªý'¸ÒÐÃÿ„?ÂÝü/ àºþ&ø7‡¯…¼?øéÿñ5»š(¸ZÆü!žÿ¡WÃßø,‡ÿ‰£þß vð¯‡ÿð[ÿ[´R…ÿg…?èUð÷þ !ÿâi?á ð§ý ¾ÿÁlüMobŠÃ𲃷ÂúúiÐÿñ4ÿøDü4zøkCÿÁ|?üMlÑ@‡Â>=|3 Ÿ®ÿIÿ‡…ÿèXÐð]ÿ[”Põ‡ÿ…ðsáÿÐÿñ4ø[·…ôÃN‡ÿ‰­Ê(°Ì/øC|)ÿB¯‡ÿð[ÿAðo…;øWÃøÿ°l?üMnÑ@Œ/øC|)ÿB¯‡¿ð[ÿGü!žÿ¡SÃßø-‡ÿ‰­ÜÑšz……c’IþXëÚ’Š)QEQE—¬Çþ‡Óþ?{ÿ× j…þŸvu™nìï´ ¬Ñ?•{ ŽVH÷ß,€7ÞÈ dt_Õÿä!¡ÿ×ïþЖ²|5£é7:tÒ\i6=ýû3=¢HÄ}²n¹ROaøU d¶6c]·¿¿Ô4Ÿ.™ü«X7I*€Ì7¹ 8Î%‰ä’z´Áÿ=¢ÿ¾…PþÀÑqÿ"þŸû'ÿGü#ú/ý4ÿüGÿÄÐõEÿ´Aÿ=âÿ¾¨ûDóÞ/ûê¨`hßô/éÿø/Oþ&ì þ…ý?ÿéÿÄÒ{í0ÿÏh¿ïº>Óüö‹þûª?ðè¿ôÓÿð\ŸüMðè¿ôÓÿð\ŸüM^ûL?óÚ/ûî´Ãÿ=¢ÿ¾êöÿBþŸÿ‚ôÿâhþÀÑ¿è_Óÿð^ŸüM^ûL?óÚ/ûî´Ãÿ=¢ÿ¾êöÿBþŸÿ‚ôÿâhþÀÑ¿è_Óÿð^ŸüM^ûL?óÚ/ûî´Ãÿ=¢ÿ¾ê—öÿBþŸÿ‚øÿøš?°4oúôÿüÇÿÄÐß´Ãÿ=¢ÿ¾èûL?óÚ/ûî¨ÿÂ=¢ÿÐNÿÁtüMØ7ý úþ Óÿ‰  ÿhƒþ{Åÿ}R}¦ùíý÷TáÑè§àº?þ&øGô_úiÿø.Oþ&‹íÏx¿ïªŽw¶¸·–'_.D(ÛdÚÀÔ0äqU°4oúôÿüÇÿÄÑý£п§ÿà¾?þ&€¹Š<áÆ´Ô »–êùï‘#š{Ûæšmˆr 9烃ߧ4ôð‡v[¤í%ÊÄ&P'¸x•88ÇaÆ1޵­ý£п§ÿà½?øš?°4oúôÿü§ÿL 8|áØ´ñh“Ý ’$ÐÎ.öËnÈÝ…qŽ:çœÖ•Ž‹¥Ùjë©Awsö¿³¥´¥îË ÕA Ò÷˜n''¹«_Ø7ý úþ Óÿ‰£þýþ€þ “ÿ‰¥p -:ÂÿT½µ—mƤÈ÷$Ê%"ãÓX+à_ ³ewlá²Pn9X㑤BmÌN{ôÅo`hßô/éÿø/ÿ‰£ûFÿ¡OÿÁzñ4ÀÄ»ðg‡ï4è,.®¯$³‹4MyÄÙ#!€꣦Zê¾ÑA4@`óŽ1ÅPÿ„{Fÿ ÿ‚äÿâi°4oúôÿüÇÿÄÒ‹¿iƒþ{Gÿ}Ñö˜ç´_÷ÝQÿ„{Eÿ ÿ‚èÿøš?°4oúôÿü§ÿ@Ëÿhƒþ{Åÿ}Qöˆ?ç¼_÷ÕP‹•BÓqÀΞƒ·ºÕ;«O YÊ"ºÓô8enBÉi–ß/4$Û² ›_iƒþ{Gÿ}Ñö˜?ç´÷Ý`˜ü §›=>ö±ý–ö ²‚¶=Ŭ?üMS„—A)#sí0Ïhÿïº>Óüöþû¬?²øSþú'þÃÿÄÓ&OÂÍiáøÃp7ÛB2G$»΃í0ÿÏh¿ïº>Óüö‹þû¬(¡ð”«º+-×ÚÖ#ü–‰ ðœ_ë,44?íZÄ?öZ=œ» Ÿh‡þ{Åÿ}Rý¢ùíý÷Ximá9Éa¡°õ±ñ5'ö†OM/FÿÀ8¿øš~Î]ƒw6~Ñüö‹þûŸhƒþ{Eÿ}Ö?ö†¿è£à_üMÙþÿ Vÿ€Qñ4¹%Ø9ѯö˜?ç´÷Ý*ÜBHU• 7uö¬Sgáaÿ0Ýö‘ñ5WÄ:F“oke-®•ao0Ô¬ Iš#ôÈz”œw•ö-x?¯ˆì1/þ‹Š·ñ\ÿƒúøƒþÂòÿ踫¡©è11EPj÷úëo÷ÏþƒW S¾ÿ]mþùÿÐi=†=?¨ü+ÀŸñëû³ÿéKÖΟÔ~àOøõƒýÙÿô¥êã±/qú¿üŽšoýzÜÿ(ªÿz¡«ÿÈé¦ÿ×­ÏòН÷¤÷Ø(ÅR¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š( ÑA  ÍcþB:ýý-fh7W6¾¹û öú|Œ€í}0¿ÙÝô´õùèõüôDµCÃwãLÐ/.„m+­ÍøŽ%ë+µô¡T{– ­4")!×ô‰/×L—P¸€HbˆL¾q ¶‘"±–.¤t±#5\_xÀ̲Ûý®Hê¬Ö<è‹‘ºL¨d88 Ç8âëxŸRÒžú N {¿"O!eŠ_,™Ö9ˆ(AÂeœîÜHàõ¨_Çw0Þ4Si1†qmpÑÝ—!Ë•>XØ7ޤ©ÉÆh‰{d¹Õ.´ëÔÿµÍì“€.-ínSì˜ \²ÆŠdar¥qÔ‘“Z:¤ÚåÇ¥KsÚ'h£TŒI²Õ°v¶@.åŽîêR·ˆ5kÝ>ÊxaŽÂòá×ȵb&[•e ’Ü »‹ô-Þm_Ä÷¶SÜMkg ͯžmbYe1d¢³Hû‚¶Fp cªžhh Ðê:Î/Ц¢oÆÉ²öO¶7Ëyþ_ʘ)È\’[åö©¤ÕµKmNj2騋#5ʼnMñbC#¹Ø ¸!6¦Ÿî¶r%‹Å.îdµ‹`³³¸†!?§fRŠ¡N2yyÀéS\C¬Cewgn‹º8ç’+£&É;  Ü€',pFOÑÔ rI©X§:‹]\M4÷QG “ÇèŸj3( c'Æ,ºŒ-ì'—ó϶6Ũo-ÉR«d1Ë ×G·{åé¤ m©K3"–Øë”ïÆI 9'5‘Ä ¡i4’é6ëRâEŸncáˆÜÉÁ\ãšC!ÓF·oq©@^ü\^;Û«J’IVábT…ˆÊa~èÆî±ê~¬ºÆ¢«qª-¬y'áÕàTb«!$³09òÆñóž3wNñN¤ßÚ&åI °µˆ6Hgh£C‚sž:à‚­Ûšdúî¾u{»(6JÉ!„â%Ü'i@ÝÏÞ8VÀ;“­¹·¡Msoá¸!Õ`¾yšæ"4‘œF(›³¸>Ö\‡8=8ÃÓÝã·Ð.LZꓨ»˜Æûuì-Çò! åùÅO!nlƒWæÖï§ð ºµŒ‘ ɘ›v)ò…iŠÆHÈÏÊG¦j¾â­@]ê6Úµ¤kqä1Gp»R˜C×s.þOCÓŽ¥õ§ö—‰ÞÎßi»_ß²Érönwœ&À"‡n-œ¨<}ürWQÔ¼U$òÃf—‘4?h,âË*ÄI'” ‘†tõëžEÕñ…óˆ¢EWÔK¿™l.XyHª­ËÀÞCŽËßuG©xækc²ßKŽYÏfu³jÅ,‘öCÉ’¯ã4 7#šæ]“W·¹1›`e’âWn„çŒü¾¼W ñÁ¦È±jr;hðÀ¨ñ\£,¢9VvbHPàì#Ì ÍÆßZï­u&ÔôÏÜ–´º{u—yž8Éôb¡[8> W-¦xŸR¹Ô4$°ý–æÎÊK‚#ß:ÉÇÞÝË*à(`>bÄ -¨#÷¿bE¿[ùCÊ!†Y­Z91åÆEm]Á”׎OSÌê6:†«©ÒáÕÎmA SÝ[(ŵÆã¼;GÀXZê|E¨¼VÚ|Úuì ½õ¼L +‰QçXÜB<ŽõËiúÿˆd†ÊK‰ VwŒÄ\µ²† ‹3²F™ù²¨¸fÇõ=5¼%¡g«½•ú_]\$n&Ô'iI´¨ŒªãÊù—$í;Þ»aU4ëˆïl-®¡mñOÊŒF7vàÕ¾ÔyCSéûçÿA5㟭cŽëLÔäE;H˜í•oêkØõ?ùcŸïÿC^Iñ¢yHí§Îöé(v»Ü‚5/‘³îÎ< a…m†þ*3¯ð{öÛ[¹w¢±U@ç99ÓØÂa  ŽžõÀiÅD ‰_‘ØZô­?3JˆŸáv×ú×µ9&¶9`ˆþÎû£ò®Wâ²>Ì”\‹…ì?ºÕÚê3ÛiЯ%XÐqÉï\Š5 bÅ ‚ê(ŠÊ¯¾Rã·ZËžÜÑŽ‹Þ‰~À¸QÅIâˆO*>á?­Gáç[kq›Œº8àU¿Em k6¥¨[YÇ‚•‚îçøyç¯jé–.‚I\çö3nã49 Š4Y¨Äe¸ü«§·¸¶Ù˜ÄÌØ !ûc¾+ÓµM.Þ5)s5Ädd:ÙÊA ã§k´Ñ'µÔlÌöRE,aŠð0TúcëZ:”nŒÜe¨¢h<¼ˆn±‚<†ïõ±Í Ç™û˜sÇ#¿áZÜu1'?슓ì¨ý\|ÿ°+6ÐÕÌ»Û(O̪B9ãŽõÕx·þ=,GýDlô² Ä–ÝÛ° Œc¹âÏøô±?õ±ÿÒËzós­x^· ð_Ø^_ýt5Ïx?¯ˆ?ì//þ‹ŠºòÑ(¢Š S¾ÿ]mþùÿÐjáªwßë­¿ß?ú '°Ñ§§õ…cxþ=`ÿvý)zÙÓú±¼ ÿ°»?þ”½\v%î?Wÿ‘ÓMÿ¯[Ÿå_ïT5ù4ßúõ¹þQUþôžã[QHŠ( Š( Š( Š( Š( Š( Š( Š( Š( ƒE—¬ÈGCÿ¯ïý£-Sð»Ú[è—Wz€ [»û‚XgiKÙÎG¿¥\Ö?ä!¡ÿ×ñÿÑÕO ZE{¤È—,Ë _ÞLÃp‚ßÊÃ9tãŸj¤ ³‰´â×që/e×û8S¹Õ±r1Üw"º?¾‘X6±-ìX•Ì-h’³çË}Àù`àlÝ’p:Ö-½Ï‚.ÿ±4¸fŒÆ/ØbQ&Å1:»|ØÀPUq’ÆA¡6n¼A>ŸVŠÃ΂tŽÙHýàIJ qœd «£øFÕ¤¹žKHâ’ÞécÚåÄ…6HÞ7esÎFjÔ­ Øø=ƒ³G¡Ù-ˆ1_.LcûÇç\g<Ó-m4 VþîúÖVy–ð-ÁIYUçŒ&Ðs€Àm\cŒ“êh¬¾ ð”:5£Í¼zuĬð#X¬ËŒÈ¨W§#æÆ=ê{ßørÍä–X’3{GbÎÌÚ6' r>Väñž•5¾¢Åþ‘oxé;ÎÌ×)t¼ŒÄuÈUÈÇ`i·€'š[‡ÃKæ.è€7³ 3ÆY›>ô$´’E} ³ÚZÅw Ñe-ç]‰ =˜0àzäW-câM,_èqǤÚ[‹›x$‚A´<h vÆ»y\¯ÌÀ¼85ÐÍc¦YiòÜÅ&`›‹XÌ“´`ä(dÏ'€3íXú\¾Iô[+kÛ¹E¼j–pËæ˜Ð‚ê»ò6‡ù@sŸ“‘@MpÁ¥¶u—g9K¨íÖFÂ=¸šEBÉ…=Û‘•Ï<×7Œmu[t²“JÓæYñ—(Öñ¢ùŒ|ÖÚB0·oqÏR7µ‹]6Ðé§Q›Qh¾Ö‹ ƒ,‘™ZPÑù…AÀ´ØQÀ¬§Ô<1s¦ZYG%ò-³³$vÓ¬äãtk³{©Q&HqŸJvð:ËH ÊTätì{Ô½ª½Œ[ÙÁª‚(Õ#Aü*úUšlHÏÔ¹0×Oý”×Î4«;¯¥ÕÖ£=»‹("ŽÙ”J|é1¹ÏÞïé_Fja·Ÿý«åÏÚ#Ä6ÚWÄ+x/­üä:tS&nf”óžÜUQ’S»Õãc6òõØ:åá’2;<þµé~»¶µÑå’êxáŠ6,YØ.>^OÐb¼ŽßYŽøé:œQl[«’÷7\~x®žòòd´…,åÛÌBà€g§OνIT²l傳±KÄž X|G>«u¦\܈œÇe€#zç»1ä〩ª> ñ„º¦˜‹K¤™iwg5¿m&æD¼taò˜ø_çÆ{b­t»ƒûûh[ЕÇãí\k£¹³…Ö‡¢k–ú}ä—w¶M4“FrLcqàg¾­ï\Ç"iÚòÃ,Ñ]B¶å¶nx™r@õPG_u5ÐH¹‹dQº/ý3“üjü”ÚLºd’“jä¿ÊQ²>eq‘@9Ç®k:ø¸¶¥…S¥Ñœß†¼I¥Ã"­ÝÛÃs@?˜p£¾Zé´oXÙêækK”6wL«4a”íf8ö89÷ëŒÖ~àmêA"ßKtðœ$<`ô8Áêb+sûEÓ„×–šIÔîÕX¶sÏ÷˜SïšÚÄZä‘Á»Ý ¸Ž@‡B2s‘õ« ãâ°èí¬gµ-tò˜’)¯Óæ8çð«/9Áí^)F´oŽppvfÈu)V|[Åý„l¿ô¶Þ°#¹ d×AâÎ-,¿ì#cÿ¥pWaS§ Ö¤ëâû Ëÿ¢â®†¹ïõñý…åÿÑqWC^QÖ%Q@ªwßë­¿ß?ú \5Nûýu·ûçÿA¤ö4ôþ£ð¬oǬîÏÿ¥/[:QøV7?ãÖ÷gÿÒ—«ŽÄ½Çêÿò9éŸõësü£«ø?ãT5ùôÏúõºþQW¨èº­Î­­(þÔµy…á–ö!#!¶x…cQ÷œ?!WæÈ'¸Ê{lz^>¹ïíG^à~5çÚ:ÞXx?UUÑõ襞ií,mb•XB0±àé¹÷° C`’@(KKY,£ðSýŸW¸ž ÉÞwŽÖël1ÇöI­àÔ¦EFE¶* Tdí`sóç®8äô>1K×­$€óeð5ÅÍìé#¤vñ`Å;!W¼å”—)&æ\®J‘ÇìGá[‹ m&îÞÞO²ýŸjÄøfÇ Y™È’@=‰"» 0)ÌÏáÉ$ŸN†+¸“I³‡Ë[F€–fÆ<ÍáÀÈSÀ*FI''¡kàË›K­íuT‘g¶‘œÙ¥ ªí9, -žývÝh4€â ð_‘$‰ö˜^Öi È‚"Œa2]Xä‡,B¡8P=ÍMyàÔ¸Õoo ð‘3´Ñ£[¶èådTÜ]\ÒF6NsÒ»qK@Ns¤éQYY^F8åùžbfwÞ—û ³|¤’xù¸æ”Ô!¶Ò£þÒµi­nÍÝÄÆÍ·\¹R #ÌàÍÏ#+¬¢˜ß‹|84ôÇ›75õÎ¥ÿ,?ë¡ÿÐZ¾{øãmgq¯Ènåh¦[šÝïÞl¹Rsòýjcñ ½µž=;ÂqZ›„–âÞe¸ŒÆ8unxÈïVu­iu»8ìÈhnEHù 1gñÏëYf Ç…ŽÜ­Q¿BˆØb3Gb;ŠísÒÌÅG©é:ûK³¸ºYuf0Ê€y?+`òIÎ>¢¶â£`wSÛð¯Ÿï5+™µ)/.¸ºnK( ÉN;÷5¹¥xÿU±dIÂ][€ÉHúã”{¦{»Äîfˆÿ}[§çþ5 ðËØÒúõeÓæ”ÆTÃeXà8)$µàÞ/ñ|~ Ó-ílRH¾gˆœ“Çc¨ÿW<­]xG]µ·Õâ¸mäSsk1? >jÑ”àð{`õ¨öwZ”ž§ÔZ4¶³[Åö9¡š" G$EH‘}Aç5­*ùdŒ’ËÏqŠó¿FšW‰5o–Fn/-'\<-ƒœtÈœ ×W¯_<:\ížTì§ÇîŸ^kÆÄRtêY3ª2RDºãZ]é7šƒ/ÙçF÷cÝÇ¿qô®SÂ×o¦›)ÚVk9^ò6âÁIç'°éô®[]ñ=Š;Þ\‰0AÞç²ñ9cœöüEpúoôß·^ηm-Ôþcyñ•S€Æ3Ç®y¯§Ê’¥%Îô<üM§ …Úãïí¼[ÿv?ö±ÿÒÈ+ç½;Å-4{ât3÷£pßž:WО.´²šþ–[×flâù\Lp‰«ÜƒÁý|Aÿayô\UÐ×=àþ¾ ÿ°¼¿ú.*èkÃ;D¢Š(5Nûýu·ûçÿA«†©ß®¶ÿ|ÿè4žÃFžŸÔ~àOøõƒýÙÿô¥ëgOê? Æð'üzÁþìÿúRõqØ—¸í_þGM3=>Ísü¢¯;×|}¯i¾'½Ó–×Mûö0ECîJÎt A­Ù”.HVXÃç±z3DgÙÌmo"@-«êGÿª»OjP]@—V×V“E4ÆXŸß&ìîWàò\t°m?^6XL[IœÐ†Î’ë–×zTÉq™4¸Ì> ±ûŒÀ‚@¾ [Õ¾"kw¶Ër tŠ·˜ó0ÜsÁ’=…qaNpÎ{s]—á{»¢è hȇf ƒëISS{5´(X\\O©Ç+¼³Lçig%‰Éÿ.(ÛKQ$Àaäè‹ô5éÑP¥SžmÉèh]ÃvAVÞ$?ô+ŸcߎE}[ã‹k/û Xÿé\ð¤…å˜Ïu+M9êÌz}}×ã?ø÷³ÿ°•þ–[×62|Ü®Ö4¢­sÏG‹5]'Äš®›¥éðÝùú¬ìK)8Ä1œãœõœßo´-2I¼RÚK_,¨«g`¯æ9¶\ã’£¯¹ß‹‹ïø¶ÒÝ%C¬Ä$ 3F$‰æÇ, ‘ï\_…nô¯.±gf¦ÛÊû$0(\I»æbz·<ž0x®&‘²Lô=sã^·kk ìz~›§Ø;q%âÉ+Éžp ãÔŸ¥wßb–8Ç©À”$¬6zµS¾ÿ]mþùÿÐjçj§}þºÛýóÿ Öoa£OOê? Æð'üzÁþìÿúRõ³§õ…cxþ=`ÿvý)z¸ìKÜv¯Ï4Ìuû5ÏþÓ¯øÁ¯i:ÍòAe;´ÖæKI¿tØ‚7të‘Ö½ƒWÏü&šgý{\ÿ(«æ¯ˆ^5ñ&­®ßé²ivòÙéÚÔ0΀«yk)PƒÂõï]xM*ø„Üt+ÚùpÏj.=?Öºo ’·ðgþzý+‘½?g¸Ó¤@p.{®»IýÝòû8?­{ ÚV9Ò;czÐaã$qZ<1È÷9÷¯=ñ©}ªë7Z^› ·Ó­æp7<’1û‹èq’}»t¬%;Xéå»´ˆáçLúŸå^{&•tu›ËˆÐ4NÒ#9V9é]:š¿p@à“7ÿ[Šä//e³Õu$[¹~Ï»TdÇ®jTªßKÔ^ç¥Í²Œ‚ r*Χm=̪WƒÝ¶ö®?Âw:í½Ô×WD¦ójp1Éãê?*Õñv³¨Eg¦Ã¦Ü ¸VIgD áÓƒ<ŒœûR¯‹ÄÂÑij(Q¥+²ÄÚÊ$^ÞüŸðÅmY ‚3E»§ ¹ü«Ì´û+yõ,êu¨»&õûUÃ>qׂv÷«§Ò|1¥ÜZ¨¼Òm|&$Ç>¹ñ]¸gY­lc5Mlz-¤lTœ=ªt O ~"¹?Ü>“xÚ-ìŒêy·‘Û9Žx>w[Tj¥&™’]Ѝ§¦à)ÅXTcéRÆjR¾•e$gÌ­·åª\ÂÀd[É#š¯sçÕPåÔèµOùÝ×'ÿÐM|±n@‚0Ãøò¯ª5OùÝúbßú ¯•­2mãÿþU–L®æeš»r“²§Q×éQ‚ªÃÔu§m+Á¨äŒõæ½Ët<‹½ËPßml´z Ó„Í,HÆ8=«›*ݪh¥e9 Q*KsHVkC²ømü\=l‚<ɇ§ü°–½¯Àñç7ý}ßÿétÕäÿ 4Æ][ÃÚ£ºKé¢6p‚Ú^ï¬W¬xþ<æÿ¯»ÿý.š¾[2’•m ÀŪZuQ\(ì (¢˜Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ú§ü°ÿ®‡ÿA5òÇí¤j·ß-¦ÓôËë¨F™ ·’E %˜HÏ þ"¾¨Õ?å‡ûÇÿA5JÞGU+2‚äðMg~Y\«] ]xg_dùt-Wús“ÿ‰ªð‹ø‡þ€:¯þIþ÷×'üôûê“Γþz?çZ{bT,| '…¼BÊGöªíÍÿªÿÂ+â HþÁÕý¹Kþú æËÿ=ó£Î“þz?æj\îW)ùó7„¼DëÆ«äsÿRÿ…@Þñ#G´è¾3Ÿøñ—ü+ô3Γþz?çKçIÿ=þú¤§`å>ðw‡/­•RóÚ¼W$Ÿßý†LãÆ㯱®³RÑ®l­ƒÇ¥êÓ;Œm‚ÒRÜŒgüó_\yÒcýcÿßTy²vwüÍl±VHžCá½GLñN 6V‚Ôp±%¬ƒ?¥S_ ëê¡WAÕUG@,äãÿ¯¼ÒÿÏGüé|é?ç£þfˆâè'NçÁm៞?°µoü—ÿ‰¯¶|eÌxéý£cŒßl‚¶üé?ç£ÿßUƒâÏøò±ÿ°•—þ–ASR³©aƧϺόt¯ üUñ¤Z“—sÆDdr›[wÐ0éÞ£ðÕΟ{§x†æÄÚÜ´6æhá@GÌ9ló÷õÁ|j 'Åíz&UPnÔ¼„›`c­t¾¸›ÃÞ˜\OocfµÐæwR@ ¼œØÇ95®;3ѭ̺¯Ã‰¥³‡dÍ3ξtxÛ· 2£©ì?­tÿÙÓIÔ ¸¼¶žî&ŒÉ$~ë$ãp žx>+Å5‹Ö¼Ñnu4¶’öÄ‹k%܆€ ç«Ófkë‹ë/ý®Ò 9"–ÝDp.)WoÄóšE³ÚzU;ïõÖßïŸý®zÕ;ïõÖßïŸý¡ì4iéýGáXÞÿX?ÝŸÿJ^¶tþ£ð¬oǬîÏÿ¥/W‰{ÕÿäsÓëÚçùG_:øÃYx¼Ewcöh^;jXžR¡™™ÇÞôçŸÂ¾ŠÕÿätÓëÖçùG_!x¯Æéþ5ñ5½Å¼RÍo«Ü4~`%YÜŽœç‘ù{×NJ-¶DÕÒ6ÅçbÁK3… §«w8¯-Õ4VÞÑÖÏQša34ÌùX™Ød¼ž:ô­-I®gÔ]­/å¢<{BaÜWm˜$ÌÍ#@á¹Ûô®µ=ã¢*èâ ÒuHáÅÛÝ1'ï<ŒÇõ5žö2µßÎCŒƒÊ玽xë)s I°H’§|ê=jä2ÛÌ6°‰ÀÀä(âÔ^¨NÏ(DÕ­œ½­ÄÐpHÄœNqL×q¢Cuâ\Ø]M»QVßÞ’Q¿B§é]º^r¤Mcg®Ð*}>ÂÎÒãe¡x]€Sòî¿?•c‰ÅB¢ßcJtùwGÙÝêÀJ×QÉr»‚¬‘;¹ONü}Et?Ž5DÖƒó2«í*¾§< íõO h“ߥíóÚÇ5ËaÏ̦SßýxëŠÕÓü'¢Y$Vß_-[w¾O?­M,ÑÒø˜ç‡Œ¶G '‰Q˜Ã¥ÓÞÆUíšÜ H<V :¯Mðî·&¡ Eso4P¢ù‚EÛ’{ã­C¿L³cñ%Ÿlâ»?ñe)8ÿ»ÿý.š¾'ïZGÕáÕ©Dëè¦Þ.áëúÖ(ØuÝÃ×õ£põýi€ê)»‡¯ëFáëúШ¦î¿­‡¯ë@¢›¸zþ´n¿­:ŠnáëúѸzþ´ê)»‡¯ëFáëúШ¦î¿­‡¯ë@¢›¸zþ´n¿­:ŠnáëúѸzþ´ê)»‡¯ëFáëúШ¦î¿­‡¯ë@¢›¸zþ´n¿­:ŠnáëúѸzþ´KTëûçÿA5B/ºÿïŸéWu2‘‚>ùÿÐjœJHl+}ãý+)nZØp¢”+u¿*]­èÔ€m§moF£kz56ŠvÖôj6·£PqE;kz5[Ѩ´S¶·£Qµ½€X¾-ÿ+û Yéd¹µ½ bx´bÊÇ?ô±ÿÒØ)¡½“þ,*ÿÂÒñŒ£r_/þ€†“XÒç×,~ÉôfÕn·Nem¸P€«ÔŸ½Ö™ñ^ö>,ø’;µ>PºSòžIò׌uüi<#¥ÜxŠ®"2ó™ Jу¼–Ïlp¦ˆ¦¯pVléî¦Ó¤¶º³i[ÍÌáUc_ÄW©ü [$ŸÄ?ÙÒ¤¨R×Ì•ß`®3žžƒJò‹_ØÁ{ú•‚ݱÏÙæ½ÁÝÏ\=8Í{/ÁÍ5,cÖ'ŠÎ;$»0ȶè§å\?$ää““ÐT9{Ö4“VÑŒ{Õ;ÿõÖßï·ò5s½S¿ÿ]mþû#Mìf·4ôþ£ð¬oǬîÏÿ¥/[:QøV7?ãÖ÷gÿÒ—«ŽÄ½Çkò:iŸõësÿ´«á/ŠsGñÅ•%$Õ®Ø_ß¿øWݺÇüŽzoýzÜÿí*ù/â6™/ü%šÔÄ.Pº(F8ýûžZB7¹/c#áŽçÑ/-åR“ 0ÆU†ò­oj°Á¦ÛÚÜ8IagC»Ãz×9¡x }„tÃÖ³\<¡Ý™YËõÀ9îGJîU,¢b£©Ñ뺮©c­Á.;¬ŒÌßgDÞ².s’;ŽŸ­v–—Éyiky¨KˆÃ•!Hà¯áƒ^qáËä‡Ä6É#y' 1Ä{Ç^OgâË­QžÆ{xå¶äÄý[2TúgµsU÷ž…ÇcÓÖNØVÑ“ –eú ×5¦xƒKÔýo"b9ŽQO±ë[j\&þñ#ñÍ$Ó4LÕƒí*3o(öCHšÕݤRy¶’;îl\ŽŸZäõ¨ëö¶ˆÎ®]Aä¯@pO_À×59JÑÒJæ'Ähµ [ëgI»xJ*â2O–êy¯OQšÛµ½[ˆ£•HÚê ç°®sĜזZ­½ÂŸ) |mnPyÍbxSÄÍ£Z8¡V_”3†ÈùãŠû\¥Ë›’]'“WG¤$ƒŽE?Í&¹Èµ4e\0üêÌw€©;…{s¥î³…nzÆ¡ÿw?õÍ¿ô_7Çî£ãøGò¯¤/ÇúÀïå7ò¯ž¢PaN6å^nKñLœÛh•„Z<³‘ZA½ð©¸Ç¦zr­,{ ÎÑù×¹Í})"·ØÚA>õwBÑ%Õ/á¶%‘d$³÷@ŸÐU«yJ<„?RkoLsèìégy›ø©ç¡þ•lj¬áNM4)©Í&lé2 m{ÃzMœ73ZYÏ4s]´H#í¡î8®ŸÂh­£9eV?o¿ê3ÿ/“×§ ù|u Ísuuwlg‘£šIp²+[ÈFpQü9ëž•ÚxKþ@¯ÿ_÷ÿúY5|tææÜ™ôÑŠŠIÞTóÍ?ï‘þyQÿÏ$ÿ¾GøW?ªj×êÁ ‰ÄBò›‹¡³í×Yu‹Ã÷n“ðˆdä9N§Êþy'ýò?Â*?ùäŸ÷Èÿ 寝yŒ‹¤8ëû‘þ})±zMÊß‘G8r³©ò£ÿžiÿ|ð£Êþy§ýò?°ômR{‹ô·Ò@êpvíÚG>õ¼)§Ø¶ã<˜¿ç’ß#ü)|¨ÿç’ß#ü* NäÚi÷cŒ¸Ï·5Îbó'ý%2:þèt¡È¾ÇQäÅÿ<“þùáG“üòOûä…sW¾ÿŸ¤ÿ¿B“û^÷þ~Sþý žt¬ê|¨»DŸ÷Èÿ <¨ÿçšß#ü+–mrî,ÈÓG"¨É_, ÃÓ9âºÇáˆ=#õªM0jÛŒò£ÿžiÿ|ð£Êþy§ýò?œ(ªƒ<˜¿çšß#ü)|¨ÿçšß#ü)õÌßkBöxâ‘#Hßf6g<Z–ì4®t^LóÉ?ï‘þy1Ï$ÿ¾GøW/ý±y‚MÒc¿î…/ö½öB›”Óʹƒ•?“üòOûä…/•üóOûä…rÇX½ÿŸ¤Çýrû]jçí1–9Q¤T GýæÆrãG2aËc¦ò¢ÿžIÿ|ð£ÊþyGÿ|ð§ž ôÏjOÀU!] òbÿžIÿ|ð£É‹þy'ýò?ŸøQø a Ï&/ùäŸ÷Èÿ <˜¿ç’ß#ü)ÿ€£ðƒ<˜¿ç’ß#ü(òbÿžIÿ|ð§þÀP;QTŽ„.)4$’‰“Ï S±E åÇÿ<ÓþùáG—üóOûä…:Š,|¸ÿçšß#ü(òãÿžiÿ|ð§QE€o—üóOûä…\óÍ?ï‘þê(° òãÿžiÿ|ð£Ëþy§ýò?ÂE¾\óÍ?ï‘þž\ÜOûä…>Š,|¨ÿçšß#ü+Å*«§ÚmUÔôþ€ù{†¶±XÞ*ÿu§ý„ôÿý+†‹zün·7?|C—ºEõ(¸ô¯Vñ[Cà_ÎövÖ¶—Þ\q•¶áCôb¤òyã?Zæ>&ø6÷Zø•âKËXDÀÞÍUÛ¶4=È=ÅÀZ¥ã_Ësq=Î"¬²E»¤ž`뜀?ÚØÓ·5‹„[<¦êy&f–f/,¹˜’yëüñ_Z|Õ.î/üM¥Ït×v–1YKo#ýìJŽÌ¹î»‡óî©à™ííä–u¸…<ͱD3˜áO›§LÇZ÷ŸÙÊ)Dž  {{vµ±†ߪìî3Ã19÷œ}ípqÜö~ÕNûýu·ûçÿA«ª÷úëo÷ÏþƒIìB4ôþ£ð¬oǬîÏÿ¥/[:QøV7?ãÖ÷gÿÒ—«ŽÄ½Çëò:i¿õësÿ´«ço\X‹~ÖêÁ^ìê7OÈr¬€ÌÇwéú×Ñ:¿üŽšgýzÜÿí*ùƒÆ“øIõÀ1Æ¡uÇý¶jÖžäÍÙÊyr8$œ6i'Œ}š7õ8©õVÉŽ­¤§MË!­ÞˆÊ.樥£Âã{a@Åa2ÚFVx$s[׿+E2žQ²ÏáYšœ¦êv”¨Üܵe6îZ(´Ò'qçÓ³£x·XÒy,ñŽ©&HÇÖ±O¡¨ÎFsQ{”´:kâF ‰ƒ*mò±Üžß^*m[C¿°@5(3Œ” í$tozçì'6÷°ÍýÆ íÇ5ê¾%’k…½¸ŠÌO§j4«x2ÁTŒ„nÛ•¾‡ó§›³äu~ÔÆ ¦²¹fxpy–H†Hç¿B> W£|:Õ‡ˆ<,—%üÛ«såÊýIÈÈ'ù~ò×…üU¨xkRMONtó• RG %eSØNùõ«þñõÞy~ÞK›;ÒKÛ[ÎÑ'$aÏõ¬+Ru)ºqq—,¹­5 ÁolÎä(#’Üb¼¾ïR²Ób>O–Ä7˜Ò“±7Œç9?‡åwÿ®›N†ÚÆÚLÄ»VKˇ”}qZŽ©{ªK¾úêI›9 sø à „tž¬©ÕæØôßøñV&ŠÐÉH<…)ûíûÍþy¬}7Ǫˆ—v“A… º0EãÎè’-ÌO† ÷sŽõÑiþ“SFˆÛBzHxÈÿdW¿‡…H«Ò8¦ÖÒ:/Ä–—Gz„.Ý•ŽÆüm®³s €û±Y:W†´½&_áʽ÷Q·¸ôÌÿ#^ÄH 9Ú?•a“=fÎ|×ì›^Óç”ß\AR-Ÿ+#ûË·®8ϰ8Î9íÅu6ÝØèË&Ÿy¶k–@bWF>b¨ 2ŽOB?‡ÄÚ||²XÝ‚ï`”#Ôµ­,d~±(ÈÆxWìc$dÛÛ£°T-¸äþB¬_Z®§f-‚Ç!Ár3Ç^vç°þU™eâJ¾G¾½´;FÕI“}OQQø?Å~»âû= á$Ü£¾ÖŒŽKnnáxïéYã1q“?#\.IÆv5íu)äøçá=>&?`ŽÐ°ÂÞÂÖ\“Ørnõéþÿ+ÿ×ýÿþ–M^[Ah]H¦[…Ž%舖ò¢àvuúzרøGþ@¯ÿ_÷ÿúY=|âØöÑÄøîêæÞûV6dùêP¯ˆùœwÀãÚ¸±{n—?e¹›ÈšðﻑY”D ¸W–È\:õøbþ÷V–îÉ¡e”)"FÛ´ªŽùf³áÖóŸôlÿ×zÁ§sdÑççPÕ –r²­¿Ÿ(’YÑpA @QŽÞ ÆÐN0©þ¡om0S $»-pHR F\ü™B@-…É ôë]àð†µž>ÍŸúïGü"Ðéön?é¿J5 ø{q4÷ö&éÑæ0¹fLá°Ï89Æ è2Mz)ï\Ÿ…|;y¦êFîù¢]¨Ê¨»9þ\WYô­ µ&F_Šßj'Ò?¡¯"Ôn¯²©jæ“ÉV’8•ˆFÏ$Þ½=+Ùµk?í *îÐ8C4mo÷†3\/ü!ú×#¸íûüJ™'pއ5mEd±ó&•ËSjªîDŒ”‚¸ mÆsšƒOÔõ‹–¶Iï dA>ÄRñ¼²¨(Ç1ÈêsŠî¿áÖ°ãÛõñJ|!­‘‚mºcý}JL«£–Ðæt´¼†[‹‰¥YåÜ&ÆT$cŽ„{ŽxÇJ÷ ¸‘ÿÞ5çPx7Ty‘.ZÝ È ÂPH_aŽx¯Cs¹ËzœÕÁ2dÄ¢Š*È òßIkwªšE?Ç· ¼òd’ppãŽ}`×­øWQ¸Õ®n¬žŠg7¾Â§sÇ=*f´.-\òÛíGQ¼ÒeŠîi×äeRßha)bºà&sž•ª——x¢Ýç–Fhæ¸O–p¦Ò·“‘Ü’xØÂ!­dÿǶOý /ñ#FPµÕ±Á\gB;ûæº/øD5œ`}—õÜ…[Ò|%©E©ÛMvð$0Ȳ1Y ’†ÀãÚ„˜ŽñþùúÓiNAŠJØÈ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Åò´ÿ°žŸÿ¥pÖÍcx«þAÖŸöÓÿô®`Ïœ¥©ÎÍ%Ü ÛK¡„zä1ÏrMzN©ão ß[Gh÷W.’Ä@V·œ»©êITäüØÀ= ¬Ëû>ÃÂú-守×8ŠtˆIåÌc¸—ÎWŽüž+Í»œÜ“=ÚI£<-er5×¹‰¤m7I·žƒ“$ˆ¤tëÆO­kø'@žËãì÷·P¬U/ Y$QŠ¡zœ~u»mwtÞñF¡¥ÔÀ7s"©& ^ cúT~ |Sâ{xµ˜íå´)~æ!Õw'ü}sW¤îDU›=ëÖ©j,¨öîì†f$œp®Š‹ÊIu?1wlfp¨\VÕDZ.Ÿw”!b¬x]êWwÓ#šÍð'üzÁþìÿúRõwTQ#“æSòžqšÌøm+M£iòÈrò[Èäû™˜ŸçN=‰h±«ÿÈë¦×µÏþÒ¯‰¼i(?ñP$È^óõëí­_þGM3þ½nö•NllË3+Bìw±0!Éü¿úõJVbjèø&gù0k=š¿AþÇgøò³ÿÀt¤û —üøYÿà:…Z«bU3óåZ‘Í~ƒý†Ë½—þ§øPll±ÿ6øŸáGµL|§çt¹SHœf¿D¾ÃeÞÆËÿÓü(û—üøYÿà:…O:‰ùÓ:åIô¨„…Aë_£a²ÿŸ/üOð¤û‡}>ËÿÓü)s”üæ²hÒöxĈ®¤¡äé^Ÿ£êZf §.-Ü€ظè tçšû/ì?óágÿ€éþ +0A[1ô·Lÿ*Ö•~MÑ…Ï’5VÒìíÄ—!uýÛaAõ\t5Æê^"šæ6‚Å|¨;?õ÷>æ¾ék+6k+2= þ¿b²ïcgÿ€éþå_™‚ƒ??£@¥™²Ò7;ŽI4òÕ÷÷Øì¿çÆÏÿÒ±YÿÏ…ŸýøOð«Ž)Gd'I³óùŸÖ£v5ú ö+?ùñ³ÿ¿ þŸa²ïceÿ€éþÞ.ëa*Dš²™-n1BÑ2î‰\f¾uм1¨¦¥o©©ÙÜéh¹iÌL—FP ŸN+軜´2ç*Ãæã?ýjñ;½ZßKx¡1Kö‹˜Ü¦á›æ$¯pq6tÅhE=†Ÿ€·.cœ4b2Y‘Ä`§Ï*¶FAõ«!±Ó›CðôKE§–$fC÷$·Þõ‹"Ã~. ‘ç>|’\(à €8È8Ç!G©Íjj+ky>—c4GnœÀÈL02©Êœ’ÚO®yÍ]7Ës9ÇbÖ‰n|3®]åšÝ®—bGÎʘVÁ­[øU žûXž!%¼°Mr 4k÷JBvœçA®zÒê{hn¬ã)öižO:Þo™ÏÝýâð1ùu®ƒá}Ð¶Ö ÉðÔÉ’CÏÖª‰«ž+ºú°,ÛWìêIöÜÙ®v?[=·Ú#7O )Kyðs‚ƒnXp~a‘ïZ?Jba”kpýôsüë‰}8Ée ¬·RI$l ÁUB°ïÁëê¤õV‡M‰¬f™bŠà¹} 0VÙó®åË}ÞGNy¤_Y´ 2Ë)Œ8Eo*LHÇ ã2F>\×7m¦ÁoQ,²²Æñ8$Ÿ,:zâ›&š’Y%¤— $106á£Så…$€OñŽÜÒºÑC¯%û]G I:Éœ[z•#¨ §=ûWyâ¿ùÙúiiãÿ'!¯(³µŽÍe1KÆj AXäêX׬ø³þAöƒÿiéÿúW ]7vg$|§ñgÃúíçÄOßé%Þy·dRà‚±¦NÜû× ÷^$ÒIûLwhQŸZz ì“ëÖ›ü„­~ü©Â¡i– BÌ»m Ì€ú´„W–7[†ÞsüYþ÷oœÿ*¥ðÇþ@:Wýz7þjÖÕc!¸9ÇsYŸ âh4>1¾+y#lz‰ÜåD~ {uù4ßúõ¹þQUþõCWÿ‘ÓMÿ¯[Ÿå_ïMî `¢Š)bŠ( Š( QEQEQEQEv¢Š†ø•²¹eÁa0Ï|-|É}¦]ø“ìrk¶Q[‹p[Ì·vbÑ•%†ÞO+·üŠúcS;t˶çˆXð2zW€x;YšÚ&Šök’,ÒV‚[uVIÜF;zŽG#&¢m­Q¬52<1¥Ûè0Éœ/eI!eù-É+¸0ÝÉ›ÿÔ ^½úèñ® ®ö‹îlÌÊs¸/f?6Ojn—â~ÛÚü7÷Wm©Oû$³1ô‚ß¼1±à §…+3M°ñG‡0dû”Ñ+1½yžå•{Žy\ƒ9Î*¹´¸ùnô:Ø´ìüaw¥ª[Oä*ñZ¹&HÕ"®ßâ=Ozê¾Gs¯âk{«C GŠi¼˜Ä¬¨ÙÊŽ¸9éÅy®¬Þ,Òo-uûŸì‰'¿%"¹… &å^ÁéÆHÆ ë\ÏÁ_]x_ÇöPê73AirÂÚü\6å GžÄaÅDÍô=ŸFÐd‡ãN­]«yÓ£WiðcŸåØ99'½zo„¿ä ÿõÿÿ¥“דh~.µñÆÝÛG’t»_8Ç$gïŸ³È è=1ùžõéú`Õ´Ëi­†“ö…ûUÌÉ"ÝD ¬—"ðNAñõªZnfÎŽŠÈûn±ÿ@6ÿÀÈ¿øª_¶êçþ`MŸO¶EÿÅR[4f²~Û«ÿÐ ÿð2/þ*¶ëôoü ‹ÿŠ¢àkQY?mÕÿèßøÿIöÝ_þ€OÿÿñT¯Š1YmÖ?èÃþß"ÿâ¨ûn¯Œ ¿ð2/þ*€5ÿGà+'íÚ¿ý›ÿ"ÿâ©>۬Рÿð2/þ*€5謟¶êÿôü ‡ÿŠ£íº¿ýŸÿ!ÿâ¨ZŠÉûn¯ÿ@'ÿÀÈøª>Û«ÿÐ ÿð2þ*€5¨¬Ÿ¶êÿôü ‡ÿŠ£íº¿ýŸÿ!ÿâ¨ZŠÉûn¯ÿ@'ÿÀÈøª>Û«ÿÐ ÿð2þ*€5¨¬Ÿ¶êÿôü ‡ÿŠ£íº¿ýŸÿ!ÿâ¨ZŠÉûn¯ÿ@'ÿÀÈøª>Û«ÿÐ ÿð2þ*€5¨¬Ÿ¶êÿôü ‡ÿŠ£íº¿ýŸÿ!ÿâ¨ZŠÉûn¯ÿ@'ÿÀÈøª>Û«ÿÐ ÿð2þ*€5¨¬Ÿ¶êÿôü ‡ÿŠ£íº¿ýŸÿ!ÿâ¨ZŠÉûn¯ÿ@'ÿÀÈøª>Û«ÿÐ ÿð2þ*€5±P]Ú[ÞEåÝÁñçpY@÷ªnÕÿèÿøÿGÛµú?þEÿÅQ¾ƒD‡@Ñûé–¿÷ÉÿOì þ–¿÷Ïÿ^™öí_þ€Oÿ‘ñTŸmÖ?èßøÿJù'öÿ@Ë_ûçÿ¯Z1¢EG*Fƒ ª0VWÛuú¿þEÿÅRý·Xÿ ÿàd?üU;XWî]¼±´¾·¶ÑN•óqôªßØ?ý-ïŸþ½GöÝ_þ€OÿÿñTŸmÖ?èßøÿCH.Iý£ÿÐ2×þùÿëÒÿ`hÿô µÿ¾úõÛuú?þEÿÅQöÝ_þ€Oÿ‘ñT¬‡rh´].VH´ëdU¶ž Wñ_:}¦zÿiØÿpÒý»Wÿ ÿàd_üUUÔF­©%¤¥ d[ËYÞWºÂ¤S¤À9' qÞšÓa7¦£¼×Ä?ö—ÿEÅ]ë\÷ƒþ÷ˆì//þŠŠº{J(¢*– In¤¬Ì<‚6ÕÞÕRøöíØ1údb“.i–¶é"ºÂÇ œœ}éøVg€øµƒýÉÿô¡ëbÇ€3ÀÀ¬m ôÙ?þ”=\Iý_þGM7þ½n”U½PÕÿätÓëÖçùEWûÒ{lQE (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ PmP¦Ý€L.~†¾$½ñ ðìÚií×ñ…2á¶1Ú2'ÏJûŠhÖXž9(ãiÆA¯;¸ø#ðîæáçŸÃîó9ÜÏöéÇ>¼6*“îRmjü%lj¬õ9õK–¶SÛK<¨ª#’`Œý¡Ó¯Eø­ü$^&õa6+i?“)Û$JÇqàp[‚G`1Ú½‹Ã>ðÇ…ìo­4-/ìÖ÷Û~Ò­<’ù›s–$ñ“Ò¡µøsá[[k‹xtÙ¼»‡i%ßw+–fûÇ%Ž3íM´Ä›ê|Ùñ:R¶Ú¥ƒ ÷(Ñùéÿ÷üURqD+ìxMÅÄw>Š÷HÔZ”Q—µ{eò¦¶“dxä®?ýu“àŸj—R­¾§©jw/©²ÙZ?Ûfe‘s+`HÁn2G¨¯¦ôÿ… Óí&¶³ÑY ˜ƒ"›©[y9->•bo†¾yldH6²ÙFb·k;‰`(_¸A'ß“Y§½Îªó§5f­e©œ|a£hRYj–·¨jQÛ;›ó}q1ÁØ$ØÈÀéÇ5àÚ·{·8×µ_ìl¬Ðˆï&àøBwg=süëꓣص”Vmµ¼q˜ÕZVbTúœäŸrkëáß…n£™'Óed™Dn¢îUÊŒqÃ{ ¨¸ý£ÍÁÝ#æ_x–÷D‘XkzªµçïIJÝLZ(Ç@ÞG'ê~•ÂKñÄÎ¥S^Õ2ö§û§¢ãØóšû3QøWàJÊKíM?êóq eþð9ïëY?ð¢~ÿиÿø0¸ÿâé]v>^“â6µsjë î¡ à´wÓxã˜óÁüë_ø´y޾"ÕƒÐܱþ¿Júö/ÿ¡}ñø~@Ý3öùûñýú_øR?Ê>|W›ûƒÇí{ ¤âL›è|Ñ«ø—Ä·¾$ÓSKÖu+ õ‡dbòYvª%ŽãÉ'ñ­›+ÿ#ËÆ«ªÌÈ‘L×3 l dá‡ôí_H·Âÿ<ºd­¥JͦàZföb#îzZÔ>Ðq·ì'iíçÈsúÓæblÏŽî¼Uâ{85(¦Öu?œ6kÙˆu㜂5õ…¼+¤Þx[Eºº:Œ×6óI/ö­ÒïfK qÎzp+2Oÿå‘ÞMBÎŘÿhOÕ¹'ï× XÚAaameiŽÚÞ$‚$ÜNÄEÂòyè>¦¡É #þíþxê?ø6¼ÿã´Â¢ÏGÿןüvºÂŒR¸Îþíþxê?ø6¼ÿã´Â¢ÏGÿןüvº QŠ.?ÿv‰ÿú¯þ.¿øõðŠÇÿ>ú¯þ.¿øõPøEcÿŸ}Wÿ—_üzøEcÿŸ}Wÿ—_üzŠ( ‡ü"±ÿϾ«ÿƒË¯þ=Gü"±ÿϾ«ÿƒË¯þ=EÃþXÿçßUÿÁå×ÿ£þXÿçßUÿÁå×ÿ¢Šáÿ¬óïªÿàòëÿQÿ¬óïªÿàòëÿQEpÿ„V?ù÷ÕðyuÿǨÿ„V?ù÷ÕðyuÿǨ¢€¸Â+üûê¿ø<ºÿãÔÂ+üûêßø<»ÿãÔQ@\?áþ}õoü]ÿñê?áþ}õ_ü]ñê( Aÿ¬óïªÿàòëÿQÿ¬óïªÿàòëÿQE¸Â+üûêßø<»ÿãÔÂ+üûêßø<»ÿãÔQ@\?áþ}õoü]ÿñê?áþ}õoü]ÿñê( .ðŠÇÿ>ú·þ.ÿøõðŠÇÿ>ú·þ.ÿøõPøEcÿŸ}[ÿ—üzøEcÿŸ}Wÿ—_üzŠ(ÿ„V?ù÷Õ¿ðywÿǨÿ„V?ù÷Õ¿ðywÿǨ¢€¸Â+üûêßø<»ÿãÔÂ+üûêßø<»ÿãÔQ@\?áþ}õ_ü]ñê?áþ}õ_ü]ñê( .ðŠÇÿ>ú¯þ.¿øõðŠÇÿ>ú¯þ.¿øõPøEcÿŸ}Wÿ—_üzøEcÿŸ}Wÿ—_üzŠ( ‡ü"±ÿϾ«ÿƒË¯þ=Gü"±ÿϾ«ÿƒË¯þ=EÃþXÿçßUÿÁå×ÿ£þXÿçßUÿÁå×ÿ¢Šáÿ¬óïªÿàòëÿQÿ¬óïªÿàòëÿQEpÿ„V?ù÷ÕðyuÿǨÿ„V?ù÷ÕðyuÿǨ¢€¸Â+üûê¿ø<ºÿãÔÂ+üûê¿ø<ºÿãÔQ@\?áþ}õ_ü]ñê?áþ}õ_ü]ñê( .ðŠÇÿ>ú¯þ.¿øõðŠÇÿ>ú¯þ.¿øõPøEcÿŸ}Wÿ—_üzøEcÿŸ}Wÿ—_üzŠ( ‡ü"±ÿϾ«ÿƒË¯þ=Gü"±ÿϾ«ÿƒË¯þ=EÃþXÿçßUÿÁå×ÿ£þXÿçßUÿÁå×ÿ¢Šáÿ¬óïªÿàòëÿQÿ¬óïªÿàòëÿQEpÿ„V?ù÷ÕðyuÿǨÿ„V?ù÷ÕðyuÿǨ¢€¸Â+üûê¿ø<ºÿãÔÂ+üûê¿ø<ºÿãÔQ@\?áþ}õ_ü]ñê?áþ}õ_ü]ñê( .ðŠÇÿ>ú¯þ.¿øõðŠÇÿ>ú¯þ.¿øõPøEcÿŸ}Wÿ—_üzøEcÿŸ}[ÿ—üzŠ( ‹ÿ¬óíªÿàöïÿŽÖ¾‰aýœÈ‹n-­¢ˆÇ ž['œäœä’I$ž´QU`?ÿÙfotoxx-12.01.2/doc/images/save-as.jpg0000644000175000017500000013062011701011016015705 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 538 625 ÿÛC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;ÿÛC  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ÿÀ¾"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?Â1A¢hvñZÛÁ»xY¢RÒ¤’I¾p;U3«ÍÚ?ïÂ…[ÖŽ4x?ë¿þÊkÞèÚN³ª#ºgfñ±Ç|uÅE“*íeÕ®¢r(굺?ñÚaÖ§òËyvù ú„ô>ÞÕJêþ[¸£[‚$’<þùÎÀó‚{àç\zb®ÿŒÿ?ÎŽTfÔ:•üé#Åm ‹îr¶èvŒã=)òê–ó˜n-áŽE•hž}*Ž«¶‘<—1D²NP¤eØí\õ$¼v¦]]‹ËùnV?+ÍmÅ7Á=y<õ¢È.ÍUÔ.£H­¢’Gè«n„ŸÃm$Ú…Õ¼¦)í#ŠAÕ^ÝTÀ­OámBK ~Þx®, +‚÷³£Á¼r§Ðú×Ilþÿ„šâyuË´ò!Þ5 VåKgçDšBwóO‘h.frÚòÿÏ?ïÊ…ÚòÿÏ?ïÊ…t—7þM2öâ²76²Mko ¢“:;’Œýí£pÏ=½ª?Ïá¶Ó ]û9œ¾S[:‰V=œ‰ïœrÜæ••®;»™"]PÂ&þÌ>SDŸdH=9ÛŠ[¦Õ,¢yn´ô…o!‹Û Ä˜ÎÞqÍjk¾%µ—MÒ4¸fQaÏ*^¾ØØ7Ì; Àç#<ý+NMCÂóÜËÍ呱‹^3˜‘Æ×ˆÅ´2…ûË»®:SqBæv8ßíyçŒ÷å?ÂíyçŒ÷å?¯xÊm1õìï°’">sغÜ烄áN;W=º•îÍ?íyçŒ÷å?ÂíyçŒ÷å?³7QºŽTfŸö¼¿óÆûòŸáGö¼¿óÆûòŸáY›¨ÝG* ³Oû^_ùãýùOð£û^_ùãýùOð¬ÍÔn£•Ù§ý¯/üñƒþü§øQý¯/üñƒþü§øVfê7QÊ‚ìÓþ×—þxÁÿ~Sü(þ×—þxÁÿ~Sü+3u¨åAviÿkËÿ<`ÿ¿)þkËÿ<`ÿ¿)þ™ºÔr »4ÿµåÿž0ß”ÿ ?µåÿž0ß”ÿ ÌÝFê9P]šÚòÿÏ?ïÊ…ÚòÿÏ?ïÊ…fn£u¨.Í?íyçŒ÷å?ÂíyçŒ÷å?³7QºŽTfŸö¼¿óÆûòŸáGö¼¿óÆûòŸáY›¨ÝG* ³Oû^_ùãýùOð£û^_ùãýùOð¬ÍÔn£•Ù§ý¯/üñƒþü§øQý¯/üñƒþü§øVfê7QÊ‚ìÓþ×—þxÁÿ~Sü(þ×—þxÁÿ~Sü+3u¨åAviÿkËÿ<`ÿ¿)þkËÿ<`ÿ¿)þ™ºÔr »4ÿµåÿž0ß”ÿ ?µåÿž0ß”ÿ ÌÝFê9P]šÚòÿÏ?ïÊ…ÚòÿÏ?ïÊ…fn£u¨.Í?íyçŒ÷å?ÂíyçŒ÷å?³7QºŽTfŸö¼¿óÆûòŸáGö¼¿óÆûòŸáY›¨ÝG* ³Oû^_ùãýùOð£û^_ùãýùOð¬ÍÔn£•Ù§ý¯/üñƒþü§øQý¯/üñƒþü§øVfê7QÊ‚ìÓþ×—þxÁÿ~Sü(þ×—þxÁÿ~Sü+3u¨åAviÿkËÿ<`ÿ¿)þkËÿ<`ÿ¿)þ™ºÔr »4ÿµåÿž0ß”ÿ ?µåÿž0ß”ÿ ÌÝFê9P]šÚòÿÏ?ïÊ…ÚòÿÏ?ïÊ…fn£u¨.Í?íyçŒ÷å?ÂíyçŒ÷å?³7QºŽTgWsoiqµÄÖ‘4 d¨ÛœŽøúQCÿÇŸý{Çÿ ÑJÈ|Ì»§h¶ºìÞíæT2sÀîš¹ÿ ûEÿž÷ß÷ñ?øŠ<;/‘ ÄÛwyp³c8Î Ö­¦´—d #ϸHŒ~hˆ]ߎGO­1_ð¯´oùï}ÿÿˆ£þþÿ=ïï´ÿâ+dë\Ÿ82:¡ŒÂûòßw ŒœàþTØõË 1Ð*³fH™A pØÈä‚zQ¨ð¯ôoùï}ÿÿˆ£þþÿ=ï¿ïâñ»o¨ÛÝ>ÈüÍÙ*U£e*@Ï9p{õ«Tj1ÿ ûFÿž÷ß÷ñ?øŠ?á_h¿óÞûþþ§ÿ]=®1ÿ ûEÿž÷ß÷õ?øŠ?á_h¿óÞûþþ§ÿ]=\\ü>Ñ@$Ï}ÿMÿˆ¥áÍŒ±¬‘ÛjîŽ2¬<ØýÚédÿVßCVoEÙ·±0NñF–Qn>vÅÉϸçÒ†ì®4®ìrð­m?çÓXÿ¾£ÿâhÿ…kiÿ>šÇýõÿ]MPª·Ú¦ù¶ñöƒ‘ž„Œñš@º¡ ~Ñq† GïÏðõïSí<Šäó9ïøV¶Ÿóé¬ßQÿñ4µ´ÿŸMcþúÿ‰®-â<¢ãPš5„eÊL\ƒœcõÍm[]K¦é§¸ Âé#ó%Üà†u§<îãÓ<ÓŒ®ì)FÊçÿ ÖÓþ}5ûê?þ&øV¶Ÿóé¬ßQÿñ5è°x—K¸ÞDï¢<›æ‰£VTûÅKÔ‹â}1¢.}ûÖ1 ·q)$Ln9œã±­,EÏ;ÿ…kiÿ>šÇýõÿGü+[OùôÖ?ï¨ÿøšõ+è58î혴R‚T²•<ƒÈäUŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÑÿ ÖÓþ}5ûê?þ&½jŠ,<—þ­§üúk÷ÔüMð­m?çÓXÿ¾£ÿâkÖ¨¢ÁsÉáZÚϦ±ÿ}GÿÄÓ[áÖß>-Vc´3ºc=‡Ý¯\¬¿ÿÈ>?úïþ…E€ò]Jµ‘m£,Rå©cÉ 3ïÅ&µÿÒ¾ßú¢¤eÿD'ŠxIÀ’RGl•­VÑ`7Ó‰$I-á0î^7»A>â³|+÷Ÿþ¹ŸæµÑÒ&Ó@ŠÔçÏÜwÆß,As³8Ï'$îäÓæÐmçˆE,®TN0?å¡ÏéZtQp)Ùiÿb$±€I."·XÃñœzUÊ( Š( Š( Éþ­¾†´§²»º³³Y‹ˆ ¬YýàBý gÐ z#úÐõVvw->›«¼l‚¬Žª¯ •rÁqŽ3ÇAùSæ²ÖfI¬T,˜é*ü uÇ=Ï5Kþúÿ¾Ûühÿ¾¿ï¶ÿžTW3.½†«#aôàÑ”ØÊÓ©fç#-žÕ$šV­woR”å%–2F$ŠàŒd“…ÛŒûÖwýõÿ}·øÑÿ}ßmþ4ÒIÜ–î¬hYxMä°ڵߞ‚bH£P¡„î;º“ƒM“ÃW6vÐɧQ} ÁÒhíÒFÒ¿8{†>xÅQÿ¾¿ï¶ÿ?ï¯ûí¿Æ®äØé´=>M/F¶²šA$±©Þê0 IÇâjýq_÷×ýößãGýõÿ}·øÑÌ;Z+Šÿ¾¿ï¶ÿ?ï¯ûí¿ÆŽ`±ÚÑ\Wýõÿ}·øÑÿ}ßmþ4sŽÖŠâ¿ï¯ûí¿Æûëþûoñ£˜,v´Wÿ}ßmþ4ß_÷ÛÁcµ¢¸¯ûëþûoñ£þúÿ¾Ûühæ ­Åß_÷Û÷×ýößãG0Xíh®+þúÿ¾Ûühÿ¾¿ï¶ÿ9‚ÇkEq_÷×ýößãGýõÿ}·øÑÌ;Z+Šÿ¾¿ï¶ÿ?ï¯ûí¿ÆŽ`±ÚÑ\Wýõÿ}·øÑÿ}ßmþ4sŽÖŠâ¿ï¯ûí¿Æûëþûoñ£˜,v´Wÿ}ßmþ4ß_÷ÛÁcµ¢¸¯ûëþûoñ£þúÿ¾Ûühæ ­Åß_÷Û÷×ýößãG0Xíh®+þúÿ¾Ûühÿ¾¿ï¶ÿ9‚ÇkEq_÷×ýößãGýõÿ}·øÑÌ;Z+Šÿ¾¿ï¶ÿ?ï¯ûí¿ÆŽ`±ÚÑ\Wýõÿ}·øÑÿ}ßmþ4sŽÖŠâ¿ï¯ûí¿Æûëþûoñ£˜,v´Wÿ}ßmþ4ß_÷ÛÁcµ¢¸¯ûëþûoñ£þúÿ¾Ûühæ ­eøƒþAéÿ]ãþuÏß_÷Ûg=ÇL’qùÑp±Åk_ñý'ûíÿ¡(Ö¿ãúO÷ÛÿB4R¥á_¼ÿõÌÿ5®Ž¹¿ °O1›€"$þk]š~dƒÊ_W RôSw¦ ܸïëÒ€èÎP:–^ª"€E0Íãtˆ¥‰nàâ’i–»¶‚ÇsmIE1¥E.¡Õ™%Aæ›-ÄqF˜d€Bç“@ÑMi#Y?1w/Qž@¡$IQÕ¿Ý9 '“Ú£Y&u–²aw ÈüZžÿêÛèi±Èâ•8‰:.{Pºãþ}$ÿ¾ÓÿŠ¥Ýqÿ>’ßÄÿâªMî!r= 4]GæùEÀm¡°HäÿU77óé'ýüOþ*ŒÜϤŸ÷ÚñTÿµC·Üã;†3B\ÆòrßÄÿâ©Æê%<±©$€ ŽÔ¿j‡fÿ96ç· f€›ùó“þþGÿÅQ›ùó“þþGÿÅTsTRÝaÍhŒ1C"îQ’7 Š7óç'ýüOþ*ŒÜÏœŸ÷ñ?øª™&Ir8e=ÁÈ¥ß@fãþ|äÿ¿‰ÿÅQ›ùó“þþGÿÅTûéwÐ|ÜÏœŸ÷ñ?øª3qÿ>rßÈÿøª±¾ô_7?óç'ýüÿŠ£7?óç'ýüÿŠ«èß@ósÿ>rßÈÿøª?ÒçÎOûí?øª±¿Þô_ý'þ|äÿ¿‘ÿñT¤ÿÏœŸ÷ÚñUc}è¿úOüùÉÿÿŠ£ý'þ|äÿ¿‘ÿñUc}è¿úOüùÉÿ#ÿâ¨ÿIÿŸ9?ïäüUYßïFú­þ“ÿ>rßÈÿøª?ÒçÎOûùÿVwûѿހ+¤ÿÏœŸ÷ò?þ*ôŸùó“þþGÿÅUþôo  ßé?óç'ýüÿŠ£ý'þ|äÿ¿‘ÿñUg}&ú¯þ“ÿ>rßiÿÅQþ“ÿ>rßiÿÅUôo  ÿé?óç'ýüÿŠ£ý'þ|äÿ¿‰ÿÅUôo  ù¹ÿŸ9?ïäüU¹ÿŸ9?ïäüUXßïFú¯›ùó“þþGÿÅQ›ùó“þþGÿÅUôo  ù¸ÿŸ9?ïâñTfãþ|äÿ¿‰ÿÅUôo  ù¸ÿŸ9?ïâñTfãþ|äÿ¿‰ÿÅTûèß@fãþ|äÿ¿‰ÿÅQ›ùó“þþGÿÅTûèß@fãþ}$ÿ¿‘ÿñTfãþ|äÿ¿‰ÿÅTûèß@fãþ|äÿ¾ÓÿŠ£7óé'ýüOþ*§ßFúƒ7óé'ýöŸüU®?çÒOûøŸüUO¾“uAºãþ}$ÿ¾ÓÿŠ¥ u@ñ†8²‘ŸÀšWžE¸DXÝýæ H:C–þº-qZ×üIþûèFŠ5¯øþ“ýöÿÐ¥án²cêÏ^V·D.Jȉ’>D,\d~µaxWï?ýs?Ík£ ’ßcDwŒ"€ÀóÈüÀ"l’¶Ç#'ž:T´P"Ü…q½~ueè{œÔ»™‡Ç—õçŒRÑ@‹s€¬ëµwÀ9%³×óüp(kw*ʯΊ¬Nxǧþ•5 [2ò¤9fRY² öéSÙÁ`T¯ÿªŠ(î7Ò£‰Äh›ÁÁ0@Ï@Ƥ# ZYT(` “ÿ¯@ i£*B†$Ž>SMh]ÖDeŒ#rr1ŸÏ­KóÏAÿ|õèÃÏEÿ¾?úô ·}¹SÊOßùcÓô§ˆÎdW`ñ³nÆH$àŸ‡­? ýõÿ¾?úôa¿¾¿÷Çÿ^€!6Ĥƒzüê뎈æ–Hd23$€##%rã¨.ûëÿ|õèÃ}ïþ½V6ò®"ŒR±«¹ãqO6£2d#©fe Ì9>ÃÆ¥Ã}ïþ½.ûëÿ|õè]SI½³êN¦OZu&ûëÿ|õèÃ}ïþ½-˜oï¯ýñÿ×£ ýõÿ¾?úô´Ra¿¾¿÷Çÿ^Œ7÷×þøÿëÐÑI†þúÿßýz0ßß_ûãÿ¯@ E&ûëÿ|õèÃ}ïþ½-˜oï¯ýñÿ×£ ýõÿ¾?úô´Ra¿¾¿÷Çÿ^Œ7÷×þøÿëÐÑI†þúÿßýz0ßß_ûãÿ¯@ E&ûëÿ|õèÃ}ïþ½-˜oï¯ýñÿ×£ ýõÿ¾?úô´Ra¿¾¿÷Çÿ^Œ7÷×þøÿëÐÑI†þúÿßýz0ßß_ûãÿ¯@ E&ûëÿ|õèÃ}ïþ½-˜oï¯ýñÿ×£ ýõÿ¾?úô´Ra¿¾¿÷Çÿ^Œ7÷×þøÿëÐÑI†þúÿßýz0ßß_ûãÿ¯@ E&ûëÿ|õèÃ}ïþ½-˜oï¯ýñÿ×£ ýõÿ¾?úô´Ra¿¾¿÷Çÿ^Œ7÷×þøÿëÐÑI†þúÿßýz0ßß_ûãÿ¯@ E&ûëÿ|õèÃ}ïþ½Fí0¸EP¾YûÄŽGëOo½ûâ— ÿ=þøÿëу¸ààçqýhŠÖ¿ãúO÷ÛÿB4Q­ÇôŸï·þ„h  / ýçÿ®gù­tuÎxWï?ýs?Íi¾)kÛ9¡º‚îxàqå²£`+uñþ”ÒÑY>K£¦ý¦îâYZá·F$9Úƒùò*KMtÜß%±†<ÒDsï‘vçæeÚ0=OQ@ôVzëV¯H©; ËÔÜZS­Xª2¿»çiçy!P~˜  ôU(õ[inͬBG‘I µ'Ó=éÖºµä¦8‹çie,„à•=ÆhÝ“i¬»ÆÓ\ÆÀ<¥ Ž8³`œàçæéžÅZ‹T¶žXc‡ÌÊ›ÁT$(Î>oNx  ”UGÕ-’ïìľàë8C±Yº)n€œÌU!®;-«‹IBË;FÀ!b@ ÊúýÚØ¢¨>³d‘Ç&çt’?3(„í\ã-è3SAÉ›ÊY ÂJ—(B’:€{К+"ËZ-e÷hþeÀ2GP6B =N@Èù¸úTÃV‰d¸‘ØtHš6@I}ý1ëž1NÁsFŠË·Ö•’fš) –Š8–#¼€ªNWñ4ó®YmwS#Fˆ®Ò,d¨Ü8õ>”€Ñ¢™žlK&ÇMßÂë‚>¢Ÿ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@VµÿÒ¾ßú¢kþ?¤ÿ}¿ô#EixWï?ýs?ÍkröÎ ûI-ntr ßÔøÖ…~óÿ×3üÖº:@T*¨UQ€@+:-#™®Ò9štO-A I?{©Ö•@i*–öÑÃs$R[)T”($ƒÔQÉ YÈ!¤ÛM3÷óÜû‚IZÓ¢€3±bŪ™Ø­¶;öläÝFNr;ÓôýÛMvhV,B‘+œà¸?_¢‹…ŠÙJ@‘\I;:J7g Niöšl6R‰#wb"1ßÄK,}É&®Q@_JîZS<‚'•fxY×9ëü+ǵ$RÃ,Mö—t†V’4*܆ÈϽWè  £áëB ûŽÐ©LÍI¸-ч'¨«Öö‰m‘#²HïÓ¦ãœTôPyÒUa¶H.¥…íá0‰A,‡ 4‡D·R)dBD©Œ†3•`}kFŠ.2¤Ð ™?}(š_9¦ß,(ã%B‘´ñÐ °šdqE:Dê¾xPG’»Ñަ¥]¢€ ²´KD¶GgU$‚xês€;AÚ§¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šâµ¯øþ“ýöÿÐk_ñý'ûíÿ¡(CÃM±&aÚ&?ª×nº<FngÎ9Æßð®ÃÜ[Üú`ßÍk½Y -òd($dåGo­4ßþ~n?5ÿ ÏÔ-–ÊXR9]„¹Îüq‚£·ûÕ6­pa²–XKŽ6mÈïò OµA­Iþ“oìÿBJm Øöù#í7{¯øP4kùù¸ü×ü+7Q×%Óõm²Û-»Ë'” ”Ø䌌v5+øŠÞ;ƒŽg‰YK…_Ý£> ‚sžr:ŒŒâ€/bÛÿÏÍÇæ¿áAÑ­ÿçæãó_ð¬¶ñTbB‹§Þ¾ ›YU0â3‡#æíï‚{N_ÙÉv–Ñ ÌdA.@ì¡•O9ÉvÇ=h šG·ÿŸ›Í©Al³jsZ4Î HaÇîÿñ_¥.©]ÜÜÝAr°Ÿ³ìýä•ÉÎWžãó¤˜×nOª·þÓ¤ˆÑ­Ïü¼Ü~kþ¿Ø¶ÿóóqù¯øVtþ$H.ÞÙlnæ)*ú0›LŒ¡‚Œ°=Sǽ18ÀÏaK/ˆâ…ÊËkr‚0¦vÚ¤A¸ñ¸‚sÿÎ;Ôzü„™ìÿã´€Ò:4Š›™Éù£[ÿÏÍÇæ¿áUµ]Utù¢y‚4¸*nÈ ÍëÇJ«Šc.[ÈW1ïwT!ð„á=³Žø¦5?±mÿçæãó_ð£ûßþ~n?5ÿ  Þ&¶ŠKˆæŠhä€ ÆL¶Ñ·i<’@ÁÁæšþ'†8‰’Öá&yg;7–Û»®í¸Ç9ÍhcÛÿÏÍÇæ¿áXÚ¸{+…·‚fùöì+’ÙöþÖ­ÙxŠßQ¸H­b•Õ£Õ œðA;‰È#€pjŽ¸Ûµ>‰ó’“CåÝÏóÿß þ¾U×üÿ?ýð¿áYòkŪ®žèûž=êáK¸Ç©â‘_fmÙëÚšÞO=æ{—¸[8Ær¸Æìð? éþÇ÷¥ÿ¾‡øQö8½/ýô?Â@ä­¼;$°\¥ì®†Q÷‚FM9À銰þf–Âð!]¤XbOqÏÞº_±Ãýéï¡þ}ŽïKÿ}ð¢ì,3O]©0É8òÆOS€Õj›I •Mß1–9éÓùšuQEQEQEQEQEQEQEQEQEQEQEQE?Oæòð±þÔ¨¿°-„l·W‹jÊT[‰bé•ÏÐdMòåYZX.u ØPÀã8ëõ?;uïüÿ·ýúOð¦³èö³ß­éiP[hB€îSêz`ÕtðÍ‚y IpD¨É‚È6ÁŽPIȱ4ý׿óþß÷é?Â׿óþß÷é?€°õÑ-ÅÚÝ™çy†7»ˆÏ›Ž›¾N?à;jÚZÆ—²Þ2XÖ6ùp #ñäÕ׿óþß÷é?Â׿óþß÷é?‹…‡.ƒf Ü÷$Lãd[ó»nyÉêN3Å6]ÖU nnÕJ"H×û»²½}Æ(Ý{ÿ?íÿ~“ü(Ý{ÿ?íÿ~“ü(¸ ú“µÑ*-Ðq".Ìã A+¸}qíSj@%¤J: cóëßùÿoûôŸáMdžR¾}ÓJªÁ‚ìUäté@X㵿øþ“ýöÿÐk_ñý'ûíÿ¡(CÃ#ó³è3Ýk¢óé”ß÷åÿ¹¯C1ÿ¦gÿBZÒ¼ÖþË<ëöwxàA$’Q€sØžzROÍÿ¦Sß—ÿ <Ïúe7ýùð¬èµ¨þÏ$󂈓4`ª–àw8TÇVµ¬^p,Êm€BHà­[ó?é”ß÷åÿÂ3þ™Mÿ~_ü*‚ëÖ ›–}Ü€F$ç¦2zuqnC(aÐŒŽ(þgý2Ÿþü¿øQæÓ)ÿïËÿ…7í} zмÏúe?ýùð£Ìÿ¦Sÿß—ÿ O´Z>Ð=h|Ïúe?ýùð£Ìÿ¦Sÿß—ÿ O´ZO´Zw™ÿL¦ÿ¿/þyŸôÊoûòÿáMûEh yŸôÊoûòÿáG›ÿL¦ÿ¿/þÏ>>€æÿÓ)¿ïËÿ…2K¨â]Ò Pz´L?¥'ŸU¯äß=ÿ¡¤Ý•ÊJîÅçp›r–8T±€æÓ)¿ïËÿ…gý2›þü¿øS>ÑKöŠw™ÿL¦ÿ¿/þyŸôÊûòÿáMûEhï3þ™Oÿ~_ü(ó?é”ÿ÷åÿ›öëKöë@ æÓ)ÿïËÿ…gý2Ÿþü¿øR} zÑöë@ æÓ)ÿïËÿ…gý2Ÿþü¿øR} zÑöë@ æÓ)ÿïËÿ…gý2›þü¿øS~Ð=hûE;Ìÿ¦Sß—ÿ <Ïúe7ýùð¦ý QöŠw™ÿL¦ÿ¿/þyŸôÊoûòÿáLûE}?Íÿ¦Sß—ÿ <ßúe7ýùð¦yôž}IæÿÓ)¿ïËÿ…!˜IŽ`Sä¿øUÝbA*ÈwçW#Š™.ÖâÐJ¡‚È™†(Ï›ÿLæÿ¿/þyŸôÊoûòÿáTnõCm<0$-,³gj† Ó¯'ùS_[†ßÎk“±b 1UgÛòƒó`qÖ€4<Ïúe?ýùð£Ìÿ¦Sÿß—ÿ ªšÅ£Ü‹u˜y§¢àúgõÇ8ëV~Ð=h|Ïúe?ýùð£Ìÿ¦Sß—ÿ oÚ­h y¿ôÊoûòÿáH&#˜ãƒû—ãô¦ùõ —Bf™¹ –?‚ŠYóé”ß÷åÿÂ3þ™Mÿ~_ü+(x†mg0GÍÛ„ ŽP÷Ýôþ¢­.¯h×-l³)‘I`ã#’3Ó#Ò„[ó?é”ß÷åÿÂ3þ™Mÿ~_ü+$øŠÒEær‚wãŽG=E:ß]içe1¤iöƒ –, `OÝÇn€þTX O3þ™Oÿ~_ü(ó?é”ÿ÷åÿ© vÀ‰ÚW ± ãǼñÅ-†¬·ßhe]«¾Z’'€rAisÌÿ¦Sÿß—ÿ <Ïúe?ýùð¤û@õ¤ûG½;Ìÿ¦Sß—ÿ <Ïúe7ýùð¦ý¢“Ï ù¿ôÊoûòÿáHÓ¢]ePHh˜ þTß> ¹“tj?Û_æ(—ÖÿãúO÷ÛÿB4Q­ÿÇüŸï·þ„h  ¾ÿQ7ýs?úÖ‰Ó }JKÙbŽW*ª›â¦ äõª>UrÈêYpAnZé5=OK‡V}/Jð;¡qúß.Õ_QÐ>½xõ«„ž‚m# m"iÕ.Ê«LÒíÚØ;‡Cµ<óÖˆ´w†#\~æH’9TÇËm]¹†ºË;@µ’Þ9´Ë%k™<¨‡ÙTîm¥±ÓŽõ©¿°´úÙà:…¡sÚ} O¡®Ëû Gÿ M—þ§øQý…£ÿÐ&ËÿÓü(å œnÓèhÚ} v_ØZ?ýl¿ð?Âì-þ6_øŸáG(\ãvŸCI´úìÿ°´úÙà:…ØZ?ýl¿ð?ÂŽP¹Æm>†§Ð×gý…£ÿÐ&ËÿÓü(þÂÑÿèeÿ€éþr…Î3iô5Ø"óé]×öÿ@›/üOð¬?iÖ6ZtOieoní.ÒÑDªHÚÜdj‰¯t¸?y×?òÇýãÿ µe]hëuâ´¬¦åƒ+æ2oãÿ׭Ć+‹»h¦‰%Œ±Ê:‚ÈÇ¡®rëÃ×¶ö:›Åc-ÃåL(±ìw»Žƒ”ì"C£È×PÊn˜¤EB­ÆÑŽ>lsî ¥1¢´-M¾vzœç¯éSx G¸Mäëºa[†¸Ê ¨0Û6Ž›‡Læ´ÛÃÊ–6<ß6 ‘NýÛX÷^«N*¬É1íteµºóC‡@ÅÕX6Uˆç6={V†ÓèjÌ^ˆH“J-™Ìí$¨°á6•ÚGlc?\Ô+á,Û˜¥–ܘàòbt‡ò÷õl.3î}h³ ŒÚ} O¡­;ýÊæÕ’ÚÚÚÞl«+ùCVÇ>ÄÕ%ðœÚ?k’WUš<ʪ„ aT0R¼gzÑÊ"Ú} O¡§GáS)³óâQš†§ÐÖßöV›ÿ@ëOûð¿áGöV›ÿ@ëOûð¿áG(\ÄÚ}åFÓè*ÛþÊÓèiÿ~ü(þÊÓèiÿ~ü(å ˜›O¡£iô5·ý•¦ÿÐ:Óþü/øQý•¦ÿÐ:Óþü/øQÊ9Ë˯¡LÐÁ¸ö©œÆ8ô­ßì­7þÖŸ÷á›&•¦ˆœ:ÓîŸùb¿áG(\ç5 9/b0‡„F~ò˘¡Œ©ý‰2àGvw£²ËmåT(Îg‘šë¯ü7m;Á5•½”`Èöࣆäã¨5øNÙ൴ l¶ñód:bHÝØýèH9¸t*øÜ´‚@Òy¥Y[‡Æ2>l~„ûÖ†ÓèkSþX?´<Í–Ÿeóüÿ/ÈóŒlÏM™ç<~µ7vÓÏmbDQ2¼qÛ…WrF€þ´X.bm>†§ÐÖÅÿ…4ëë”&+x–'B° C¸U¸àã®zÕ)|!,ÂUwÓÇŸ+º[•1‘œ²p ëG(\©´ú‚æÜÜÚ\[†ÙæMØÎ2 g× J öe™ÀÆL “úUyô .êÞæßì6Ñy€ ’8T2eG ãƒCˆÓ9Ña-#ÆÌ’I³$Œ´ƒÀ÷ÀÏÐP4ƒæiÉ·I^Tˆ&fÎrÙä|ǵu>·‡Ï’ö)å•UGlÔÜ““QAá¨bŸN†K;i!´€™¦ò×÷òchu#’yö¢Â¹ËÿbÌÑì–ì0XVñPÀóÏ'åÇj°4Ì$(e$ErÓýÞ¹,q×ý®¾ÕÒÛøríuyo§´hŒ‘ðU9#ælõ >¦¡ŸÃ1y^Dv–î./D’J#U0ÃÁ*;ÿ8þõas–Ãë{ܦ .U‹! g,A zÎÒ[9¥”K$ÒyŒU ÀÆO¥t áÈÆ³-ÙµÓZÕöªB`Á@ç '¹íL²ð­½½Ú½ÂÚÏ!ÄIä ͸ç2÷¶Ž ™[O¡£iô5¿káÛäIii)šft&ýÚ0£éÖcáý:Ö y¬­'–4 ò´ KŸ^E¡sžÚ} O¡®£ûJÿ ]Ÿþ¯øQý¥Ð.Ïÿ×ü(å œ¾Óèi“ß_ç]_ö>•ÿ@»?ü_𪺞™§A§Ë,:}¬r(]!PAÈèqG(\óoþ?äÿ}¿ô#EßüÉþûèFŠ‘š^ÿYøý +vHõo x—P¼·ÒfÔìõ2+@ d$– €r V…Ö~ÿBJõIî!¶]ÓJ‘¯«VŸ-ï±2W<óÂ:±ƒÆ—pê¶òY^_’b…†0H¡ìB Pk¥¾‚öq§Ò­®RYÞ1;8Co*Ž 9;ƒÓ‘­…ôñÝ žh2#” f=pzŒÕª©K™ÜIY-®•®Û[]c{‰Ù<¹cx›d¹q—Ï›ó2@3ÓŠ»¤è÷ï&Ÿöèä)n—%w’¡Ȇ<®âz€IÇ­u´TŒãmôInmô»{½:ãΆé^þY%È•„Ràî鸎˜ê+¡Ð!º·Ñ`†ô8š2ëó¶NÐçnO—£F{PEPEPEPEP\ïäýwÿÙº*ç|kÿ ¸?ë¿þÈÕøYpø‘BÑ•5 gq•Räþ=&—ãmY%‚\JIÇú‚æi!®¡2$3ÿ,ž¼ëGÓfÐÞÞ;«ÖqÁ[w9þ*¨«õë–ú…­ÍëY¬N²¬fBxÀ uÿ ¹å§÷å\7€¥¿›VŸí–3Á²Ùñ$¸ÃeÓŽµiIm¨{Å0ê-zפ‘¶=¿šØŽv†òøã œÒ‹mjIltRKmðÀûD“’#ûÄ ŸÒ¥òÓûƒò®rÒÒü]ZÌ ºéy)n2ÒE‹¶I8ß»¯ §–²tùQ#Ô’o±lº2ÈÄÉq¹y‹ž7ò¸#½Q'[!‚Ý)!rÇ$àÄ)ÞZp~U‡­i)á‚Iî-Ñáqj¹gÂȬØ|î'㟥Rû¤úà‘d¿·¶Ý[þêWÄA~el¾œïò0h§slŠæ5ijpXàœS€OáQÅsc=Ä–ÑO“Eþ²4pY>£¨®Z+ £kf.lõ à´½Ò2Ï*˜Km-¸a˜goÒµ,÷M®Is6Ÿs¶Gl‚Õ€`pYÙñ‚XŽ}Ï&ÐI$‘ ¢ 8Úx$d~”ÿ-?¸?*ãg¾7š©gþÐ’ÖKÕ_&pãù+„=›¨ê-NKëKÓS’÷ÎkF«Ä:ɼíó6IÛ´dädô íü´þàü¨òÓûƒò¥@Dhïmúâ–€å§÷åG–ŸÜ•:Šo–ŸÜ•Zp~Tê(¾Zp~TyiýÁùS¨ ùiýÁùQå§÷åN¢€å§÷åG–ŸÜ•:Šo–ŸÜ•6XÓÉ}ÓÚ¤¦Ëþ¥ÿÝ4jW··€Ë;Gj]ÈP?M–âÊ ¢‚i ŽYŽ#Gpϰ= ÎñFœ5d[Qq:.èWnHoQïY¾"Ónî5 åŠÍçkûXa·@"GbKáûÊÙï\QÔ:+½´sG ¼K$¹òÐñÉÀïŠWkxäŽ7hÕå$F¬@.@Éwàf¹ÉtÝ[þë]B[[ic¸Y–v->[¥v`rsÔäãð¹uh/umTKIRWóDãCŒNHý)®Ín’¬LѬŒ¥‚2@êqè2*ªêº;M+¨Yf£A:îpz3Ícø›G½Õ5{6µÿW¼¢E|ˆæÉOݱ€Ø==++R¶¿¾ž÷ɱ¼…o"ƒe©µK.r¬ýŒƒî)ÝyiýÁùTqÆ›åùGßÿÙEJ¹Ø79Ö~­k5ö©Ú[6Ù¦‰ÑqÉ@4=jH5,Ú=ུ6Èpóy«±O¡làRÍ}aœú‰–6µTßæ¡ÜöÇZIJ ¿¿þͼ´·–(!Hb„y¡”X(ÏLŸn8ªú}¬Æ 3E–&>Ó-ã«€IJMøãqb¤ý ÐêUíÞW…Z3,`@Få¦GlàþTØç³”Ê#–0œJ(}¥b¶•q¡¯¶·{»8ü©@ÚoÞäçוçéY Ë]ôÈ£¹‚ ¯&ÒÖ;„Utr›Œ@PN{àòin5¦©¥Þ´iÌ ,¨$XK!SÐí늞+‹)ç–f‚IaÇ™8,ŸQÚ±4ÁnÖ3CmbÊ`t¶b%¦ÝÅÀÀUSŽO'Øs[GÓ.WP³ŠK‡ìKr·30fóÿzŸLzÓ¦I-¥WhÞ'±W*Àí#¨>„RÄ`ž%–‘¸ÊºCPkJÑá‹MÔì%±Dµ’îCFL.8ôÈ«¾‚K_X[ËŠHàUd#H(@_òÓûƒò£ËOîÊE7ËOîʨkˆ£F¹!@;Gó£YúïünÝÌP’ëñÿ'ûíÿ¡(ÖÿãþO÷ÛÿB4Ve^ÿYøý +·¼wžîöÛæ{°BΏùzŒñÜ‘ü«ˆð¯úÏÀèI^•¨iV×î²;É ª0%‰€lzsYÕ¢ªÇ•» K•ÜÃÓZòßR³Ž{e¶™¾G‰%” Ôã¦pxíz§®Ü_¦³¨É —( p³­Û¬vÛ³–1}×¹ÓXivz{´«#Ë3 fp[œ`ÀU¦û)ß»Ê>`Ãç0÷õ­Ò±(Þ'ÖCßÜ%œr[Úý¡ve/–Ö?9c»ÆÑ€Ã“Ö¤Ô5Í^ÔÚÛZ\Z^ËÕîµq$ˆ©*‘0 AóÀ>hëÐe@ük"ËU¹—NðôPÞ™oWÌ7(òœ’È›ßöç=ñ]5¢ØXÛ¬òƨ <É’Iä’IÉ&” 4<’jQ‰åËZËx›Tû5¼ åµãÌÑÎÆ  f@­œõ Ó¶x¨¯µ]JýWoofÐÏk¾Ô|Ï!fRX0lmÎ@Æzê|+ì¿eòìþÏœù[WgåÒ•—LwÝmáˆRSéé@(¨¾Õoÿ?ßbµ[ÿÏx¿ï±@ÑQ‹ˆI£ÿ¾…(–3ÒDÿ¾…>¹ßÿÈ.úïÿ²5tÔôaù×=ãB—ü¶ÿÙ¢ .(Ú?—¨Ú7£7þ‹jÚ=%Sÿ®¦‰@É!Æ?í›×xVô žMR·Û’¾zŒõ÷ªŠoaÍöÒç ß³Kö“ýÑù×á-bßXÖ§–9!i–Ú@ë8dxÎ+Aµ›ß±ÏxÑP\›hâelÄ|ÑùwOâÀŒsJ.êâ’±Ò}¤ÿt~t¿i?Ýré¨O>§j“²;Û]Ë x2\E»€IÁù±ŒžED¾#¾ûžE¤5—Úã†ýÏÌ£kóÏÞê1Ê‘Š¡oÚO÷GçGÚO÷Gç\î¯s©ÛéÛ XäYalU6̪Ù¼°89>¼Ó?¶5C«Éi¼SÇo"G+,ewn.â ôç8<ÐKö“ýÑùÑö“ýÑù×$5=Já¬"’ê[¿¶>ÎÛ‚‘¿çÐqWìÌ­Í$SÉke¸2¾PÉÁ ƒ¶Þÿ—&€7DáFH0sÀ¤3ÁŒHXt$dŠç'Ö¸1½«ÛA<1¶Ÿ2A 0mØïÓã­6=rú9<ÉÒ a‘®–4‰]LDã$’!OaŠéþÒßÝi?ÝaiÝÝÛÃs%¬€ÛGp¦ÝHÛ¸Ÿ”’Ç=:ñô­z›í'û£ó£í'û£ó¨h  ¾Òº?:>Òº?:†Š›í'û£ó£í'û£ó¨h  ¾Òº?:>Òº?:†Š›í'û£ó£í'û£ó¨h  ¾Òº?:d·Ê”}ÓÞ™L—ýSÿºhX\”tõ£í'û£ó®wÄú„ö¶" wš•µÄq3ùJ£<`18=9=ª¶¥u:Xiz”Wr(9|âƒ## NHälеui?Ýi?Ýax’I“Nim/šÊE‚[æi=ºýi¾(»¾²ŠÉôä2L׊¢ ÛDƒk|¤úq@ÿi?Ýi?Ýq3\ÜO%‚Û]ÞÞ žI|¹ÄH ŒÇå Iyük¢Ðîž÷A±¹’Q,’@¥Ü.ÝÍМ}A W5>Òº?:dw|¿(ûþ¾Â™T5[‰í4FæØfh£wŒc<„qCÐhÕûIþèüé>у¸¢çk™²/)¿²R–憊w¸Úw°$à€xf«Áq>¡ Yi’ÌòOuu%¼ònÏîÑÉ|0ê6¡»ç± Wêuÿi?Ý|JGOjã¬îõ ™"×ì×WÐ\—I)nèp„áà{æ’ÓT¼‚ÏV\ÊþG— &Y–bgn :òWŽÙí@ÎÈ\’2~t}¤ÿt~uÍ[Z½¶¯kecwrëdŠ.þb ³…ûÄüÞ¿¥A£Þ]Mg›é%’ñ.MÄLC,% @þt÷ÍuŸi?Ýi?ÝsÚX¼—LÔa}FVš;¹#[†E, xSOz¹ Ë$ú„³HÒHð)gc’ÇÔЯÚO÷GçGÚO÷GçPÑ@}¤ÿt~uÏxªêbÖq¬Žˆå·ª±¹^£½m×=âŸõÖ?VþkQ?„¸npšßüÉþûèFŠ5¿øÿ“ýöÿЄixWýgà?ô$®Ò_ÔdµK/—+!Ù!.v’ Û·zâü+þ³ðúVµÌ‘µÕÌre•n¦Ò&våÈçHlqš/a3²‡Z²žt…|õiÕßnê ú‘ŠÐǵpzD jÖQ'˜J¥QÔäpÙÁ=TãÖ´õ_Í©]ܵ§šZko)Ì€~ìÞ½1œŽõQwÒù©öÖÜWvv¸Î:ôϵ?ÐW&«¨ž(aqn"Çœ ðùêþX9ã(LãŠ~¡£^NXÚi2Ä­l#²Q2'ØeÜűÎTädü¸ïTaè(Àô €2rqÉ¥ Àô`z Z(0=‚–ŠLAF ¥¢€ÐRÑEÎø×þAp×oý‘«¢®wÆ¿ò ƒþ»ÿìQ?…—‰öÑù·öёţËj”x?EPÒ¢ÿ¦ÿÅT03%Ü.§ ¢B¡òž¸ßxÛ^ÕfoíJWDÉ; ‰rõÛUÞÈŸ™èvz¦Ÿ#Iih».Ö`äädrO ©—nÒÉ3Y[e]’HbBξ„ã${ÌÐ5™µ=]Ô\É%·ìÂpÁÐg!G©«í¯Û,sÍä\´Éå –<¬²nÙ±9É;Ž:c9æ„ÓWA$ÓÔ™4裎8ÒÒŽ#˜ÑcP¨}Tv?JEÓ A(K+e˶%aõn9üj¸Ö¼ûë8¢V„4òEsɇŒ¬{±×ÁÏ<Eñ=‹[¼æ+”AÚ"ß<øòäçžJõÁäSvKO:6ŽX’HØa‘ÀeaèAàÔ?Ù6»£ìûMЮØÛÉLÆ=ãô¨/¼E µ®c@תñ±iSÎPò*ä¨'6G8éOZEx-¥Šâ6 ±ÈÅX†B1óŒtÈäsÍ»qŒÐš5œsãÓlÒcœÈ° cž¼žj±ñ– >â×O¸–;Ùüµ`f_-ŸrØþ„ƒVbÔ.ÿ¶Å„ÐC±ãiÇ!fŒ1¼c9í@ ‡C³·»{¸ì ¶0û(Úœ|£ «`PØ#B»Š•UKu#МóëTnuÙb—QŒÛ¼qÙÉ €¡×æ pFàsóvâ¦Ñ/¯u /%¸Ë'x¡+•ÎíÄžŸÝ7NÐ-´£+Zǘ1ÎÐ[þùw«ÞDžƒó«4Po"OAùÑäIè?:³EVò$ôDžƒó«4Po"OAùÑäIè?:³EVò$ôDžƒó«4Po"OAùÑäIè?:³EVò$ô2X$òŸ÷Oz¹M—ýKÿºh_³»Gµ2°ÁS‚÷¨N•l×1Ü›cQŽp99  3è–7MºãL³˜î/™ F;¸ò:ð9öh@à ÏÖ|D4NÎÈÁç=äoå(l3È €£°w$ôÅgßx²çN¿’Òátÿ6ˆ´à‰fgê#R9ÇùÅtDžŸ­28dß/Çëì*íS½½M6ÂúúE,–êÒ:PF³6­htëO³³nh|”ØO©\`šTÒ¢Žæ;ˆáÐÄbWI€£ÐU{m_Pe¼‚{Íí´I(Š)¾V œ|Ä `ƒšdÚÍ̾²»R+ÝDD¯Þp£'è(òé°«Ìëi´ã0A—ýãü_FÚD ¶È Xã´IqáP0g?\TVºÅËë·:dÖéû¨Œ±²îRüãpºòW t'‘M¶×emþúòÙmÞÎIƯ¿îŽ}Nh¸¶‹dׂõ´ëFº0œÂ†LŽ݌楎Â8e’h­¡ŽY±æHˆ¡Ÿ7Éüj„–©mw§Z_Eo)º\9G"E;73ƃÇ_OZ4ÿ\]]@²Ú"Áx²›R’e–z0##‘JÑ[M‚DŠ–m  ǹ>¦„µ1"Çjˆ£ ª{U,ukÛ½:övÓÕnm§x„ 09Æ1–éßš·¤^¾£¤ZÞÉÆóĮȧ!I3@ò$ôýhò$ôýjÕWÈ“Óõ®sÅhÉ5ŽáŒ–þk]ms^/†YÊD‰Ù#.]•I Êõ=ª'ð— Ï:ÖÿãþO÷ÛÿB4Q­ÿÇüŸï·þ„h¤#K¿ë?ÿ¡%zÍׇd½u¹KGœ6Æi!äq‚ÄvéÖ¼ÿ¿ë?ÿ¡%mOiÚn.ÙcµÔ˶c•ÏeÎ1ŒÆ‹ØLí Óì­dó-ìà…ÈÆèâU?˜b¸­68—Q²™!¶Mò¨\J¬8läÓŠ›TšÝuaîu;›i`†#j±Ý:኷Hóµ²qÔ¤î#¯¤$¤ ä'×õèïímEº,¿gäÌJ%vûã,àŒcøCsU¯õ‹émÙEíí­ô.ð#Ìk‚sœtlŽœŠ ;š+MVäê1Ý.¦& §y‹]«q vʪ“•aÀ=ýiâKøì%u¿¶Ÿ÷PHn,-»<ª¥HÏ8‘žxæ\쨬­ þ{Ô»Y¦Žà[Ü’â5ÂÊ6ƒœtà’8ô­ZQEQEQEÎø×þAp×ý‘«¢®wÆ¿ò ƒþ»ÿìQ?…—‰-ÌÔ-“8ݼgÇf7×q­,Y>Eˆ?“ÕøØ¥Ý» d<ÿ×6¬)¼gvtÇxZ!qÝÄÇòu9#œž I [Ù†|¾¾šéu)n¼ØŒ{ …Ë‘óîÖƒx~ÜÇ,"êé`’O9"V\E&ýû”íÈ;¹Á$sÒ³¼;yo#Þ´E€B<µÇPsúŠÔ7d3FYw ¨õ4âÓWB’iÙ‰…mÇ)šy&YÚw•ÊæV+°†ãÚÀ¥Bž³X¸º‘g‹{©òcÈ;WöW““Å+ß³ÚħÌûS0GB ð <þ(¸€‡"hÈïÃåúúUµ¨YG¨Ùµ¬¯")*Áã 2²ÊFA*’xvÕ5·ù²4íƒ#¼Q1v²S*z}Ò—ö–Ö‚êY”@YTH9f :{š”\@Ψ&Œ³Œ¨ 2ÃÔzÐ á›hÆä¼ºYüñ8DjÁ•û¡vòçŽsSÚhÿc¹¸5 §ûK—‘\GÉ#¹Àì3PK©ØÂbßuIå) ‘»ilÐp§­/ö…¯öŠéâPnZ3.À ùGrz Y<;¾p{Û²³„ó—)‰1†?.sÀéǵ_³´ŽÆ†"ÅZG–<娱ü2j‰¼…U•„"6 ºFP‘ž9þx©$¸‚ ¦I£@ßt³Ÿ¥hÑTihíJŠ»ER¢€.ÑT¨  ´U*(íJŠ»M—ýKÿºj¥2_õOþé  Kûµ=:[)™Ö9—k ôÍVÔ|;¦ê’ù×0·›º2]©`·_ÌÔ:†§g¥[ ïf!!G’}€äÓo5‹ ¥¶¹˜¤Œ8F`€œÄ ('ŒœPÖÒ£“R[éçžf‹&݆ȉ$N ä穪²ønÚyUæ»»“!Ê]qq±·.ÿ—±ôÆ{ÓF«iý¢, ‘gbUwBê¬@ɈÁ8çÒÚj–··2ÛÅæ¬±.æIaxÎÜã#pâ€-_hÖz•ÊMv†@°¼>YÆÒ¬T“럔`ƒT_°ʒÇ&¥~ñÏG:³F|à¹qÙœàõT‹ªZ¶¡öÞ¤ä¡áuWÇ]¬F=6}bÆÞYb–R$„¢²bIºæ'šÚU ¡T`PKmäVÓ¦ø¦Ê:ú‚ ȇ]Ó缪ò‰ ­ —ÕEÎT1'ƒÐö«†HáIå•ÂF‡s3Œš!ú~€˜ý¢ââYÕQåmª0£€=»Ô0h¿gºÓ‚Iº×N€¤JÇ.\€»û¹üê¼ÝÍ´“ÂgqÝÈ-äó0ÝÌn ö8¢MfÔhçS‡tÑ•)Vwݳn îãš½o¤,:‡Û¦¼¹º™Q’?8®"V ¨ôœž* :!“÷3_ «‘!É`9Ú¸ *õíšK}NÎîêêÚ •å´Ûç€9Ç=Ý=(ƒRµ¹µ’ê&c`“!•XuÊ’0ÃÜPË£ÖfÔÒþä<ÛCňÊmQ÷FWpÎSIe ZØÞ ”–y<°â¤`Rç-·<‘ÜŸj£k¯Z\½´N“A5ÈH›nJî ¿sŽqš–ÛY°»¹{xf%Ð1Ë#*°S†*Äa°zã8  +]>+E¹³Ÿ´ÊÒ¾â8$qíÅ:ÆÎ=>Æ8Yš8"—9$Z˃YÓ®,&¿ŽåM´.Èò@uëרäU›K¨om!»·bÐÌÑŠ‘zpy§EQ¢€/V~»ÿ [Ÿ÷GóꥬÈ* þb€<Ã[ÿù?ßoýÑF·ÿò¾ßú¢³(Òð¯úÏÀèI]Ôþ´–ò[˜¯o-Ì®ÎV&LÇ-ÊO$“Œ÷®¿ë?ÿ¡%z Ôÿé3 p²`¹' 6©ÆÖšW#²ðµ­ò^5ÝÕĈr¢b˜Î1Ÿ•Fq“×̴ֵ¢V‰ ƒ£•aYO(×!OR@Ü0ÚHàûŠYµ›³âY´Ôº¶‚8„EUí$•äÝœüÁÀ^ÅRÐFëÅŒ¬ñ£2©e¥"A `„†5î;T}kš´ñ@†ÞâúîYÙ- t ¨Ž]Ýל £®]!{íâÿJ¶ó§†Cˆø`FOÈH`Ïš`l˜b%I‰ RYNÑÁ=MCq§Ú][µ¼ÖèÑ3¬Œ£€X0`N=À¬˜|K 0uP­þ53Ö,¨i# ²Äqœ8ÿ¶O\†–’êšLË,J够ºÁ$ç'þǿֻk-§R´Ý÷w1ÿÈmW¤ñŒ¶MA÷cRâ¥fúì¬`øA#‚mJÞ3&ahÕ‘ù)ÃqþI©D»6·ßg¶r×q;?30?–ügù}0nØkF­)†Æö;—DÞUœ.qŸÎ¯y1ÿwõ«I-„Ý÷9‹mî+ˆ®6Ãnžf†6ùbVŒ'ËÇ'#?SO Þ}ˆÀbµˆ¥—Ù²ÿ ¹Nöãý“×',k³òcþïëG“÷Zb9ýSF[‹W‹ûÍѲÂò°„ìullû£;zã½R:ĺ»^L„G#¤¡"–5\mû…ˆÿu€äñ]o“÷Z<˜ÿ»úÐ!o¢_Aol¢ÚÝ£´¹Em#©;<¶B …ãvA#è®óÉÐþty1ú΀)¢•õUþTêµäÇýßÖ&?îþ´VеäÇýßÖ&?îþ´VеäÇýßÖ&?îþ´VеäÇýßÖ&?îþ´VеäÇýßÖ&?îþ´VеäÇýßÖ&?îþ´V™/ú§ÿtÕß&?îþ´ÉaÉ—øOz¯­YK¨h×móej–8§z£¬h÷—·w¢ÜÅäj0G Î톈#1Èòþ"ºa {G½hò#ôýhmõ u÷»º·I Œ•µ"aˆ”Ž[n9cÓ=‡N¦¢µ±¿‡Q»ÔVÒÞ–¾JÍ‘3ç!˜ãOƺO"?OÖ"?OÖ€9á§ÝËâu·†Ùa ¯*K¹§R0Œp3ÏáUî4+¿íëjÕã*@®ÙG\êÃøIã 9LŠê|ˆý?Z<ˆý?Zã­|?©åDa5ºó Ó:ìbIQà67 ù­­BËûGM¿²ß³íÑîôÊš×ò#ôýi‘Ãùxþ?_öE,nsÐÙjY¼»¹´¶–{˜ã‡ìÂoªç$¶;îQ\…Ö~ÿBJô™ï$[‡rhQbx=G­R*Xh÷Ñj+w{{ ÛʱBS'd’DZ5¥”0Þ\]¦ï2ä(|ž>P@ÇçT-µY¤ÕÕö2¾GT‚}O¥h=í¬eÃ܆2ªá¤ioº¦{zÕÏ_ iÉn`Q(CEĘ#cF³r [þÏ?ÙæÐß]’N|ýàH9õ¥Gc«ÛÞ+ïd…Öi£î70Š–ÓŒûfŸýµ¥6½ŸÙU¶´þzì è[8ÍgMáheh#iwÀ·êg—-,²ód1ÁéÅ[¹Ð-/nåžîI§Fñ݆ÔW]¬_Íœ‘ÏN+Dø˜7ÚCõqGü$Ãû4˜íŠjp]AÂO¡Bõ Ç‚ïî…«ÝȱÝ*(yc‚ Êãò3œUX.õ“mh}tZòÞÞYËPÑ3JÂü¸¾q['ĪzÛIÏûbøI‡üûIÿ}Нkâös2^ç]µ†G·¹¸»˜µÜI±®?wŸ-¸QÉÇãéN°›U¼{hNªí×y¶ä4Šd•bѨ6;wÅjÂJ¿óë'ýö(>&­´‡þ){Hwg>ÆE½ÍÃÜÛÞÞ^Ëgq6š_gÉ$ŠíÃØàb´´}j(ôÂ××»+°óØoI0,¥T|¼÷#œT¿ð“ÒÚNÛ¿ð“ çìÒßbŸµ‡pörìb=›jOnÉmÐÜêÒÊ‚îñ²yX WÓ â¦“N¶Òî`ƒ[&ïOHÃæ!hRù*Wœax]Ý8­OøITç6ÒsþØ x•W¥¬ƒèâ—´‡pörì^Ò¥óô‹I…¿ÙäCýÁØUºÆ>$Brmdÿ¾Å'ü$‰ÿ>ÿ}Š~ÖÃÙ˱µEbÿÂHŸóèÿ÷Ø£þDÿŸGÿ¾Å/iáìåØÚ¢±á$OùôûìQÿ "Ï£ÿßbiáìåØÚ¢±á$OùôûìQÿ "Ï£ÿßbiáìåØÚ¢±á$OùôûìQÿ "Ï£ÿßbiáìåØÚ¢±á$OùôûìQÿ "Ï£ÿßbiáìåØÚ¦Ëþ¥ÿÝ5ÿ "Ï£ÿßb›'ˆÐÄãì÷OñŠ=¤;‡³—b÷‹­׆î?Ö–CªFìŒd¾¸Ñ»'“Ôœû»ÿ dóå'ýöµž&µ•ãy4æv‰·FY”•8##Ðà‘øÒöî?g>Åe‡JÅVֶ묶¥RßkGü%‘ÿÏ”Ÿ÷ÚÑí!Ü=œ»gë¿ò¹ÿt1Yÿð–Gÿ>RßkUµ¥åŒ–âÕÐɸ°8äQí#Ü=œ»}­ÿÇüŸï·þ„h£[ÿù?ßoýÑ@/ ÿ¬üþ„•ÚßÉsýÈ:eÝÊ<›‘¡‰XQRéⸯ ÿ¬üþ„•ê]¬nËå»m8$8¹¢© ˜Zb\\k1Ký›skJIiÑTta†$œš“RÐïî5 ÚÝ­µÜ<¦FexÌl w#õ«§ ·BÛc£°$d©BjÑ‘ìºüƒ-ÏO­PŽ]|%p¿Úˆ.cÙªý JNIŒ;1M¼µó/C×4Û½Wßöá™»’âØ!f*Ä[æ-·<îôà9®ž+˜'yR)QÚ S¤€@?ñ©h’:&­k}m-¼rÉ/Úžufe†3&Ï”¤ž™è3ÏJè´»/ìÝ*ÖÇÌó>ÏǿΧj²]U•KÍÐÉ£zïÙ¸nÆvçœPE0ËDdPì2žOáK½wìÜ7ã;sÎ=hÔS^DÝWqÀÜq“Au° Ý<šuQ@Q@VÔäuÿ\_ÿA5f«j?ò ºÿ®/ÿ šáµòí£îœÿ㦹øM¡ œ2®Üí‘Ê{úŒWUw ÜG QÆefll œü§µgÿÂ)пðŽÃ´ta\üv¹¥&žˆÚ1ºÞÅ;Ç­ÝÉ6q[¤i¼r\òÇ>µ¼,ÓÍXZá„‚?6OÝåUvîà瓎Øüjœ>šÝ‹Á£˜XŒŽ×i#Ó t«¢iD`[Ü~ïîŸ#‘íœdcÅdõwhÙh­qSNóJùS–ªë”ÁÚX©'ž0E;û5C”{ƒ»æ(ª€³€@d޹ÏáÞ£û>²ei~Ït“a"">_@ÀJQ²®ìוB)k}ئ28úõ¢Ë°îûŽû<"ÛaFó~ÎÓù„ô ‘·‡æi–öË5šÊòlPd$ªnl(Sê3ÖÛk&·º1“È1yÏ\gç*Â]Ó¥+ÆrXN1Ž€qE¼‚þc#Ó–cqˆ°…[hÉÝœd1ÐçŸÎ˜Ö*‘¾ëŒÊ±<¡U2¥T‘÷³ßµ hHïök†.`Ðn>R1ÇÓŠ‘WU[µ|øe*\ÄIœ8ãóÅ]…wÜÌó a«Ùz‡üøÜߣGö^¡ÿ>7÷èÔYö.ë¹_Ì4y†¬eêóãqÿ~Ùz‡üøÜߣEŸ`ºîWó a«Ùz‡üøÜߣGö^¡ÿ>7÷èÑgØ.»•üÃG˜jÇö^¡ÿ>7÷èÑý—¨ÏÇýú4Yö ®å0Ñæ±ý—¨ÏÇýú4eêóãqÿ~}‚ë¹_Ì4y†¬eêóãqÿ~Ùz‡üøÜߣEŸ`ºîWó a«Ùz‡üøÜߣGö^¡ÿ>7÷èÑgØ.»•üÃMyÆúµý—¨ÏÇýú4×Òõ Üt?òÈÑgØ.»’Xl–]²BË1r¡¹¢ØBò\9 $q#:©8-ϧÃg«Û«,vs|n ntá¥K]b2 Zθ$àAÇ=xÆ1íÒªÞDßÌQoÕa„«yRr¹ä2FjG²Š;{™KÊo¶÷^ 'ð8úæ¡û¯çùÿe¹óOñyGü)«a« !mn°P¦ dü§¨ö§ò™jöÖíæ1¢†‰P’ncœgpíÖ²¼ÃWåƒZš3Û\8-Ž™ dþ5öV£ÿ>7÷ìÒ’»Ñ.ËVWó Ib‚æõ bTI(R}3Š“û+QÿŸûöi#Òõ%ve²¹6AœŽ$ök¹d BÖó¼~LR3«#1#ŽœõïH‘ù7rË,H#†/4*’ÊÙ/'±$~´5¾´ó,¯m;:‚mÁ=xÆ?J$¶Õ¥‰ÒK+†i39Œäà`œ «yóÈŠh¬D!•ç‘£vsœ‘·œvêiïkÝ@ *`veÞ ÏË×9zT?Ùú®ÄO²\…Œ–LFFÒq“ÓØTÆ-e¼Ã%œîÎ…òˆÛž¤:Ÿ_z>A1®ðMk5Á€E–ýÓûÇ=1è-ÔGÁQ•­Ú0[vwîñÛÚšmusÀlå1¨!A¶€Nx;r?:Im5‰¢X¤¶¹d^ƒÊ?†xçñ£ä1.´wPb9/±]ÃqÎ{Ô7¡a¾ž$"9 3œ •ôýRB¥ìî E ¿º<Óµ$šn§,$–w ìrO”y?•&Ÿa¦»•|ÃG˜jÇöV£ÿ>7÷ìÑý•¨ÿÏÇýû56}‡uܯæ7’Ê?Úάej?óãqÿ~Í5ôëØ@’KI‘‚Y£ i¤î&ÕŽk[ÿù?ßoýÑF·ÿò¾ßú¢»3K¿ë?ÿ¡%v÷w–ë¨] ®¡ˆÅ6šêÊFz=ëˆð¯úÏÀèI^™ug¥Ï6û»kI%Æ7K–ÇãT„Ì;mäñ¸‚ê9ÌÌEoánp¥&ª“ÛÝëQ‹™Ž¥l‰C u,”†#…ê:àVõ¾›ö(mcr>o%T=ñVéØGoi}g­L¶é~· wmÑ_ìÍŠ5’F·\ä U» µ‰ní-su°¥ÈšKˆ¢-¸ydžñœa«©¢˜’±ƒy§JuÝòHÄ÷1Ë"Í\ÐÄž(³[O2À‹©L©M®>ñ8l$¯•8«ëVR\Gh÷ .˜P+FväÎ9Úp}ª…—…–ÓìùºGky#)'–ûÊ&~RYÈü€Õ9ÐY®‰kÓö3uö³oå|ÆO÷óÓ#8Æ}èÕ¦³§ß\µµµÇ™ ¸F À¬FŽ ¨Ä6åÅÔêŒ$‘@ð-…ãíïYÚV‘«Áq—qV–mh]Ÿ’$+ØuÛô¦ÛhšÇÛåfŠÈÈ.L…”JSÌdÀÀ`3…' =èb}oM¶ ’èop¤lV`}ÒH öÏZ¾F+—ŸÃ×°ÍŽ•°o³ù¯.ÃÄXvìáGH÷Ô±Ëêi€”QE (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ l¿ê_ýÓN¦Ëþ¥ÿÝ4ÝkW]Ä]É’1Ã*Ç@7IìZ¯{âX¬åÚm'hã†9î_ä#’ òO tÅ\Ô­//-¼›[¸mÑÔ¬¾e¿›¸Ž>aÇ5›qáU‘DÞ´vÒ[EmsG¹¥HÉ# ‘´òAàðhGWÔ¥ÒíÂÙ=ÄH¬ò²º®ÅSÉö¦ê:ݶ™mksq•†æUMìB„IÉÏÒ Ôô‹ýFXOöŒ¦2y2Ú—Wàm ‡Úr}ò8â¦ÕtdÖ`´†í£u‚e–E1ådÀ#ÏsßVOÌÝcÒ¦f¸ŽIU^EŒˆÓoÌrxÎîŸjX^E¨éö÷°†ÜF² aƒ‚23XW^’êKs-å­ÒÛ %¾²óð´€Iq’6ýïCùíé¶_ÙÚl^t“ù(Ì嚪­ÅÜV6·ws¶Ø G g€ šµU.¬âÔ,ïl¦Ï—p mޏ*'°ÑJ-}žÚ饱{yíQ$xf•ݶp:úb˜Þ!ó|9§kïn\Eo‡†rû‘ÕIç#·4ûm#P¶ÿiÅ%ôÂ4óšÛä™ÀØ©ÉÉÏ~• žƒ5­åš;‰`·y®ð4îOEÏjaгi®-Ϋu§r$µMìѺÈ1œBœ« qKi®Ås¦]ßÉo-²Z;«¤Ø òŒô3éE¾•r5q©^ÞG;ÇÅÅ—…b ÜwÇ僯ZëDœÛ½¤n$†òÿϸb6ì‚W¯9*þ@[ëwK-„7ú{Do0¢DpT9MØÛœàF}E-—ˆb»ºX¬ÑÇ0ÛÊpDÛr=³Öý“yý¾ú‘½ã`"’Ù‹D˜ù‚¶ð'œíô©š‡ÚÊö^óΆÔH-bòö”Þrw6~lt½è[Mqnôë«Áct¦ÚVŒÀTŒvŒä}*Ö›zº–›oz±´bxÄlesØâ™e§}o›¿íS¼ßww1מ”ý2Ëû7L¶²ó<Ï"0›öãv;K(¢€ Ï×ä sþèþb´+?]ÿ-Ïû£ùŠò]oþ?äÿ}¿ô#EßüÉþûèFŠÌ£K¿ë?ÿ¡%zó9¼œ,¤¤n?"3õ¯?ð¯úÏÀèI^ƒ{á建–tÔïí|ÒÒ@¹ÀåIè~ÕHL§jÒ~ßñnã9#å<Ê—Pº¿²ÖüÛ›™ã°f òDf0çŒJ/ÉÇ+Ç®*í†غ{ûÛ·U‹‡RÜQÎ üê̺E„×kkXþÓÚm ²žÄgŒŠ¡Éâ[û«Y^ÒÁdšÞ%ûDcq1ËæuÀå¶…fÀäñ޵ñ к¹½Iḱ·ÓRåãE ³n”6ÌòÊ Ó±o¡ÙCg5´¡®¾Ñ'›<“ct¯Ç'h €:T£IÓƒÂâÊÐ)HÈAò©íô  «¶9>Õ5ÃÀÖmà„Mß7Ê~yÁ gc½ÿ¾ßßûíù×'ua¬Oy¨È–¦6Þá‹ 9FGQL·ÔmîÞD¶¼Iš#‡ &JŸ|U 6Úk >H«.û©6ª`Fn銧¤ÙÞÙ˜$’ÁÓì6e*¥s;î¯=8''z€7>ßPË9u2²™`u1ŽsM²ÔbÔ!󭤕£Î²:÷]Ànã"°#Ó.£˜ªXÈ’A¦’pÃl‘±$wí‘‘ŠÖЬF¢Ú[˜D2—Í\ççÆ ÔÑÞÿßoÎïýöüé( bïï·çF÷þû~t”Pïï·çM•ßʾéïKL—ýSÿºhåÅìVpy×7+ c¼´~f™q©ÚÚ\Goq{SK÷ä›·©x†Àê$ñEn³O³÷@Þ£= fø‡K¿¼Õå–Ú ]$†$]…|¹JÈX‰sÈQÆ6àòzô£¨=Ž‚ïQ¶°UkËÄ·Wmªe“nO Í>kÈ­‘{•]•»à31ÀÜÖ6¯äÚ»N’áíB¹%öã'îü¤üÓoôInô#L™L© Æ.c#wýõŠÙ—P‚ Z)nÑ$HŒ¬­&AÕˆô÷¦Yj¶šŠ³Y_ErŒR†Æzt®nM TýýÅÀ[›Û«+ˆ%‘t”g×ýXÕ½ÊþMînR䡲HK݈Ö@ÊFB`mëÉéÍ1÷þû~uHÊe%ȲI?ìŠuPÔí$¿Òu HX,“ÆÑ©'%©cD©­XIh÷i¨ÂÖñœ<¢`UO¹Í,Úµ´:kj?ió-•w·n펧æÛ+n!‚ž`xòC åp žÃ¥2ÆÂå$±Ó/¼’]I¨Ü‚AÚe•gvÒpÈ5Bètú¥­ÜÒÃo{²Ãþ±@J}Gj|WðÏ Í ÒÉlUÙ!Hê;ŠÊÓ£¸¹Õgº¿°šØÐB ("Ý“È<³·×4äµ–ÏJ¸Ócˆ@ÚŽ Ñ@ª6,è«ÂÍ›MvÆñâŽ+Ôó¦@é >$*FAÛ×§5,Z¬óË7±É,?ëd§Ôv¬Ç†iuè£}>d²²+ögk¹\ocœ€ ãþ•šº¡qn¶gû9·¶º‹Ï,11—îãûœúPKoªÚ]@óÛßE,Qœ;¤ ªýMM ÊÜÀ“Á8’)r:6CPkÂÂ[‰o&»Ó…¼S[Å ÛÉ´î(8cÒ¯è¶òÚhvVó¦Éb…U—û§Ò÷¿÷Ûó£{ÿ}¿:m v÷þû~uKXf:Tà±<þâ­Õ-cþASýóæßüÉþûèFŠ5¿øÿ“ýöÿЙF—…Ö~ÿBJôK›¶[™HÀ‡ÇÞÚª6©çó¯;ð¯úÏÀèI]Ýåž°·×i ¬±Jû×͘®>URØs÷Z¤&z„ͬG•Ú7Üc‘ÐGåVfÖ¼—ÕWìùþΉdÎÿõ™RØéÇOz­§éú¡Õ#º¾ŽÚ(â)™É8#*09©u ÞÜÏ,WÒÛ%Üb;¨ÕU¼ÅÆ û§ŒÓ ‰â›PžÚî6„ ¢Ž±L¼HáKãË:v«Ñëšt‚çíYÖFFu*0‡ I=9=ê¡ðÚ›ç“íŽ-x® °AËÆªæë‘N=©lü:¶·©+Ý „J!£(‚Àžý8☕ɦւj¶‘[ ½,ÒÈ»Íݾéö÷íPÚø®uá6e-gšX ŸÌÉw;²¸àe['8è*õÆ÷V3ƒå‹)Ñ £&=¾öjœX/þзr£’I`€¨ÄRIÇ=ù,@=2iu<ú«Ã®ZéßcÇpý ° ÀOèTµñ žñkQ¤Ï2ApÒƒ¸ÄNíË”|¬AÉàsмtÓ%Å…Ä× $¶a²Û@ó .ÒN:zñUm|; ½ð®X"i^ vQ¶6åÎ{õ8ÏLš}@m׉í"Ô ±·x%2…v•¦Û«6цå‰Û¨©_\Q¯Ã¥EnÒ+î\n£…ÜçŸN=j;ÿC{pì“´OGq ÄŠ¬X‡©äv?;þ»Õ¡Ôbk„’9^RŸh£3 ´¶à(^Š( Š( «j?ò ºÿ®/ÿ š³Uµù]×ÿÐMrö*Q³àe¿ô[VöÅþûÖ ‘Åý©ôßÿ¢ž±5ÍR+y/n?´âÁ&M œy®8áS9'=k7>TU®ÎãÊFlnlã<Òý=McøfçÏ„)rîªåÈ%1‚zô<÷Åf-ÓE ·6÷÷©QâŽÙ®ÖTóq³Ë$€ç1œÕÅóô:¿³ ä±£ìéêk“Ôõ}Rò-^Ý`_²¢\ÂË” Pá¾þâO¦Þ‡­ZþÔ{K½FwÔBÁ˜¡Ùæ”á—ægÿ×O¥Ã­Ž‹ìéêiÂ2£GÐã¤Ôïo岎çvRêxðÚ‰Ƭ¤´lGº"ºûP¢Ò Ÿt ÇïLŸøñ徦€³§©£ìéêkކòêK»¿2æWŽho@rû¶Ÿ—1ô‹huã=jhõK•Ó#µym¯U"³pë2Ò"ío›“ŽAöéBÔMØëV-ŸvG\ú<¬‚<ÇÁëÍeøjYæÓXÜ^‹—8ÚGÍÎà rsútªz®·ym:E=¼+nð(†DËÌ€$Œô=(½ötõ4}=MsW~%»ŠçPû1Y ŠÞåâi" µâíÖ#9êÚ¤]SW·¼‘g¹·š8n …‚ÀP¸‘AÎwŸÆ€:³§©£ìéêk•‹[ÖÍ’Ý5Í«ìñzSìägæÁLîýJ³¾×”ðË;&œÐÌLÁDmϽƒ¸ž9ä¨éÆh¡û:zš>Ξ¦²ôvRK-Óˆn&Ú;‰Ì’F¤f$䜜‘œT:$ðù·—±ßJtý !¹¹2 Ò ÇåSÐt€6¾Îž¦³§©®b+Ë-ÜwêÒF±H¤¼#s`ƒ»ÓãÓð•§Ù¼;k#4n÷1¬ÎËÒÄ’Ç'q÷£¥Å}lj}=MgOSRÑ@ȾΞ¦³§©©h ¾Îž¦™-ºy/Éû¦¬SeÿRÿîš´-Óhäô¥û:zšÉñ_ÚóÏoy5³B¡ó [‘ÆzôÁ¬_]A­·“u,qÛÛÂä$å6)ªt˜1´ôÀÇ&޶µÎ·ìéêhû:zšç¼Cz¨C êOkj–÷ ÏþYó×fÕ$zÇo|r)5YõKDX®ÖþêXK°ù~`…È#ЕÁÑ}=MgOS\lú®§s%Ö ïqgÚmÊÛÛT£Æ™1븰ÑG­[ð­ÔãV{Y%”ÆöQʱµã]ÙÃ1v9Rr>^‡ö¢Â¹Óý=MGºï—“÷ÿöQVk;WšæßFÔç³ÜG´X;‚ qÞ“ÐkRçÙÓÔÒQP–rrrxÊFfš ë}?W’[8–Ú_>k¶ù³“"ù¼•ÜéÓÏ{ÿ?P߃ÿÅQv7¿á%óá7ýöŸãGü$£þ|&ÿ¾Óüko-à’vž©r¢"¤€3Œî5b_Ý–³`gëŠ.ÂÆ×ü$£þ|&ÿ¾Óühÿ„”Ï„ß÷ÚSþÆ}µxÿ¦?ý•/ö3ÿÏêÿߟþÊØ´-ÿÂJ?çÂoûí?ÆøIGüøMÿ}§øÕOìY?çõïÏÿeKý‰'üÿ/ýùÿ쨻 _ð’ùð›þûOñ£þQÿ>ßiþ5WûOùý_ûóÿÙRbÉÿ?«ÿ~û*.ÃBßü$£þ|&ÿ¾Óüj+­í“B¶2ƒ$l —\ ŒzÔ?ØÏÿ?«ÿ~û*†ëO{[gŸí+ A’¾^Üþ94]†„V{F£h‘—þý½k}šÐcn?顬x/í£7þ‹jQ×.¬æ™Ö¾Í›K²Ÿ—ܜ⧙Ej;6ô:µ¬e!M ±cÜ’{“Þ•¤r´ÑÁJßzEŒ?SÖ³tÛ×½¶ŠgP¥÷‘Œ³ÿ¬á¬ßE ·ó%»YÅxÖìˆHª$Ø$á¹ ‘ÅZwØ—¦çF~ÊfóŒ1™q·Ì1ØôÏ\R³$m *»1/ è8éí\Þ£â‹x’öÞßxž$•c”í(dE$Œgwn¤`ã­[‡VœÝÝÄönñ[F棠)»sŸN1êi®`ÓÚ%„ÙÛ˜Ôä!vƒì1Š…ì,žMá‡=H°gñ0“ì¦Ùâ¶Ye’)ZåwìePqò6r9ŠÞ™íãfuve²û€hÐ6«#ȰƯ'Â0 }OzD‘GåÇo!;Ь@}pZÇMNt¿Ô"»†8 µ…fB¹™Il“Ø}Þ•žþ ¹}.K•eÀxm¼¦Ü¯€Ä‚yg½ÐÜYÙ\Iæ:<±·‘¢.}[n7~5éZ\×\M³Io,Ë#60r'“Y7þ!òmÞHáš¡iUà•á–2à1 xÆTš×´šK‹d–[w·v”vRzuùI­ZÛgæ<Ÿg‹|ƒþRåÇ¡8æž^I1©$‚~AÉ bÅ®E5ê[¥­Ç—$\¢6tp6î0FqŒŽµ ø–ÝÖP¶— 4RÇ’­3$)>ßá=H#¿ºÛ|¤ÆÝ¸Ø1O§µ7e–÷³C¾A‡o)rÃМr+x¢ÜDòKcyªÈWz§Îc8ucÈ>¸±©!ñIv-åÓï-Ïœ°3IåíWeÜ ísÔÈÈç­mG”*V+Xc†!!Uއ֑!°ˆ±ŽÎÞ0ÛaQ¸zk-lÞÃx¶v§í6¡IŽiSi œÈXcåœÔ:Ž»-¾a¨ZZùÍxÑ<ía¹±î8 …Þ ]ÊçƒÔS-ÒÎÕJÛA*NHŽ0 þUÍMâr×wbÎ$–Ö )&ŽbOï$P¯Ð\ûŸj—AÖåÔ‘íæÙMæÀ¬ ê¤1ÏÐH0ÜdääçŒ~”*HZ$cÕ‘Iú)wS ¡G@è)i°!¿9Ó®ë‹ÿ#O½8Gþµïüx\×&þF¨œE1ÿkúÒq¦;ÛëXúψLº¶‡Í´…&ŽG2]HQFݼs»ô­7;}MUžÂ ‹¨î%ŠDñl8ÚÊøÎGüSZ/Û”·óàž'‘#i~^!/÷CwçéõÅð—@¿Ø¯vym.ï-pcS†o½Ðzuö¦EáÛ8gŠe’VxÕT™7.îä•'ÆF ]ÀŸfǵ2oÚÎ^{½²Æ±Ê¡×mV?/ÞØ Öö¯ke Ó’I­aižÝdfÐ3Óµ"kzyº–ÕîãŠx‘dt‘Â¥wdg¨©¦bøzÊŸ*Wîu›K{U»Y’kr¼Ø¤VU$㟛§lÕ›[Ë{ëu¸µž9ân†LŠç"ðëPÜKp~Ê­#¥²´3‚ò23’z‘“Ú§µð啨^áðÑ]“v•G1ë’}kkíök6k‡í dÃæ àuÎÞ´Á«iÆÙîF¡j`FÚòù˵O¡9À4•/‡ì¦ŒFþvÐenuå»~U$º5¤ï#H%&I’f±ó*…º`VŒz¶(s¡lâ4ÞûfSµ}O<z Õ´ë™;}BÖgpJ¬s+©h3OÑ-´Ô•ayßÍ#>a_•W;@Ú£ûÇ““ïO:E³YCdÆco @ ¸ã’1Áâ¯VÕíšâÖO¶ª¶Â-q)ÝéÅ,”:wÛ¡”ÙAòŸá5¡šd§÷/þé  ÷ºÛãT7wVê@Ê»Áƒ•?¦ W¸ðí…ÁA¶h£X–Š7ÂKœª¶A$ž„O5©¨jQé–Ây¡žHÀ%ŒQîØÉ'ÐRI«[,–ñ§™4—$,B|ÇÐsÞ€3¯4H/œÉ,÷k&æùÒPV2>éÀã¯V$ӭ䋱•,œ4(§…*õ5cRÖ-t³Î%w3Š2íµ~ó; Ž}Å%öµa§XÁ{q6-çtD‘FAßÐý=è=¼?§–àhbXåŒ$G}þ¹æŸc£Åcqöƒ=ÍÔâ! ÉpÊJGv€ª£¨ã#Ó¦–Dó5Ä’!TuC‡*{ã½Po Z5Œö¦âñ¼ýæi¤Ú‡å\•ÆÞ܃œœæ´m {xDoq5Áýd¡}>UQ›ˆ-nm¥š(n‹E´˜|ƒæßt…ô5nÂþJÑnm÷l,ÊC®ÖVRAv ƒ@àúQƒéWh  X>•KXû*~;æ+j³õßùÜÿº?˜ %ÖÿãþO÷ÛÿB4Q­ÿÇüŸï·þ„h¬Ê4|.¡üÅac ^Vº,ÀÛÇøV…~óÿ×3üÖº:g’?ç¬ÿ÷Øÿ <‘ÿ=gÿ¾ÇøSè y#þzÏÿ}ð£ÉóÖûì…>Šg’?ç¬ÿ÷Øÿ <‘ÿ=gÿ¾ÇøSè ͺ0*ï+)ê¥ÆéN•de“ÝiÔP~\ÿóÿuÿ}/ÿG—?üÿÝ~kÿÄÔ”P~\ÿóÿuù¯ÿG—?üÿÝ~kÿÄÔ”P~\ÿóÿuù¯ÿG—?üÿÝ~kÿÄÔ”P~\ÿóÿuù¯ÿHÐ4ƒl·W¦rQ™p~¸¥¢€ ºÈ’Fû ã=Aô&ªÜØ­Ôr¤²°iq‘TSêjµE&“ÜiØKC5Š*[͵P@zã?_º*'·i,%±iÛÈšc;£%‹ïëé‘SQMi°ž¦|º:O,²Iw;y¯#²á@Ý !Lô>¾ž•} Äf᣺dk€¡Ø"çåϵ-îÂÅ¥(Ûºêá™ey·‡(ÅØbJmìj%õìh¨·<(ÀÊdþdäÔ4Qv/Ÿ4—2=ÁÝs†L û£==>ñª©¦A- ;b‰ü½ÑǪ±F ¤Ær9=êå]…гØ-ɘ¼¤yÎò8UndØÄÙ_ךÑ[ûåEQr0 û¡ÐTQvD1[˜)#—ÒN`ÉwÎâO~ Ò¢KIžg»–Y$’9¤Uë%zÀÜjÝ2YžVû¨¥Ž=¨¸X¬údO–_jþ÷î ë\}3ÓÒ¥6ßé p$ #\%ÉeGΪ¦>µ}t]”²D23Ìÿýj_ì}_þ}aÿ¿ÿýj5†}¼Ïu"_Îe»UY$*»€\ãÜjÕ½ÅÍ¥´vÖó,qF»TÇçžç¹=Í5£–))Ð$±¶ÖPÙëô"’FÍqilÐEpvÈÌÒ3 ,ìz’{ŸèU–ÄM¼3¶€Áp„©çßäZµEabÁÔoÉɹ÷èRh_ÿÏÈÿ¿B ¢‹°±?ö…ÿüüûô(þпÿŸ‘ÿ~…AE`Oý¡ÿ?#þý þù”©¹#ê…AE`I{qq¨ÚµµãC<'ø^8=ˆô#±ª3Ø%Ô¾uÄžlâá[†@eŒ!%J·PÙc’:Õª(¸X|×SÞ ·¸jÂð#ØÅIã×å ‰$Ö6¶2JÞÓo–†1ÙJŒúðiôRªXìIí1–'ŠG` 2²ªO°EÒ¦Óã“Kæµ¹;Ʊ·šL¹ Ó–$Àãž•%îÂÈ·ý¯©ÿÏÒÿß¡P^]^_YÜZOr W*R@±€H#·®¾Ñx.'¸[¶In#XÝ•À\ã‡æ5ù©¬ (ZIæF»/ÏÌÞ§$Ÿ¯4ê)Ý…†À&¶6†)ÏúqPnëŸZÏ{K«V¸>U܆I€A’N3ÏaÅ:ŠWò\]Ëy ÓÜnxˆ—ËS<®8Ï¥T’ÐËi«ÌÞTQË€£;dn±EÂ{±q5Â]”–h–&eA®qCɧÚ^^XÚ¥µ´ê‘ àÁ$õ$žäœ’}ê*)Ý…‹ÚúŸüý/ýúkêóô¿÷èUJ(»ßö¾§ÿ?Kÿ~…Gq¨_]@ÐMp7ûÀFj (¸V·ÿÒ¾ßú¢kþ?¤ÿ}¿ô#E 4¼+÷Ÿþ¹ŸæµÑ,Ouwmf’Ä› €r )c|)Ü×;á_¼ÿõÌÿ5®‰—qS–VV ¬§HèE_Ôô(4ÛUºµžsµÑ]%¸pÄ/~‡œñXÚܶvÉ$1‰¦DÚN2€=Ç<Ö…ÅÕÕØQsrÒª…ÚgÔã­TºµŽò»€È`Pà‚AëM•>¡y-ø´·«yÅdP#Ü€F­€IÁò*—NÔ%}Ò^4€M+$+´áˆão#·Þ«‘i¶ðÜ €dirX³6rv…Éü©mí㶃Ɉ™'ç©Éþt›£jÓê3:J#D$Â)R‡qy??O¼0+^ªZi¶öN#+ÊO1÷Ó9Ú¾ÜÊ­Ð'IM^K™.f•aÄkO³qÚ±#Ÿâc×´wv_Ù×òZ¬¯,{D.rÊ #÷éúÓmæšÒV–Úf‰œü Ž™¿½5™ä‘¥–F’GûÎÝý°£K•y©O÷ш›É·µù©·r±<ýÑ֩˨ê%ne~ß=`‹€b‡E‘J¶p}¡Úà¶4u?Á§isÞÛ\\´¶Ñ™XK&á Q’è2lVN§/Øí'“s/øzã¡â®Owws†âéåˆc(T Øþñj•ý«_Z=¿™³Ì#sž3“øÐÀ¬šÌm.Ù-åŠ#$‘,­‚¬ÉœŽGÝ=j ÚܰÄï#mòãVV/¸ñÐà}1V-´h •¤–I'&Y$Tfùy9ÀõÁÆi%ÒÙýž ‰Wk+FdbÞV:mÆçš4 K6WböÜËå´E]‘‘ˆ$pzqUäÕ•.Ì+m+¢Î4À®ÕvÆ''¨è;Ôú}ŸØ,ÄV•·3»·Vbrj")®’á%’&Ç3 l£•#¨õÀ4ubÕb›ÈÛ=$a’6óUcÖEì¶¢¯*Q¹\å³pT‘ØUŸìK"_p•‘ÕÓËi>U÷±éštzM´e[|Îë*ÊÜg mL(Q·Öæ1É!¶’x"·Y™ÆÕq’ÙÈÏû=ªì—Iwe{åR SgùsÇçH4˜ PlÝ¢uËÎäa’~aß©ô¥ŠÆ; ÙÖ sýâhЇ_×otwÞÆ-¢ƒÍ.ñ;ù­žP2ð‡äç¯JW×ï¤åb‡ì1ÞÅdÊAóK:©Üp.£瓞Õvê 7QòZæìËq$BÎiDeJ€ œ(äç­jK,³ÌóO!’G ¥¶Âçýæüꤚ}¼¯#¸lÊÈ͆î‡+GP)ͯÁol³Í ÑȬè œ3ó~¤¶ÖMÅŸì’;HÀ Dƒ¦}Ï8©¦Ðì¦i™”Ê[ÌØøÞäƒÇJéVm+Jc%œ¹›ï†ê§Ô{PV:ݵôSÈÏ!C¸Ü­ò‘œåIºSáÔÌÉi,_h£,WsÁ⧆Í! 2K4l1‰Ÿv1Ž•öE¿–‰ç\þìæ6ó~hÆ1€qÓ¹£@"]m¥¬¬‚ßír£bä^OÊzTw"‚ÑcûD¼~iF‘2±ûÜý5m4»HâhÕ\+@-ÏÍü?¯'š{éð¼‘ȯ4OÃFø%GcÇ4h•¢Öi¶ yÞ8ålmfQ“À9O¥ÝM{¦Ás<>KÊŠØr3‘‚p>¼Ó—O¶VV ÙI^a–þ&ÎiÖ–‘Ù[ˆ"i5û¡ÛvÑè=¨ÐGZÿé?ßoýÑFµÿÒ¾ßú¢^ûÏÿ\ÏóZèëœð¯Þúæš×G@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@÷Wþù˜_î¯ýò)h Š( Š( Š( Š( Š( Š)XˆïŽ»Pœ~T´Q¶Oùá7ýúoð¥Û'üð›þý7øPQK¶Oùá7ýúoð£l¿óÂoûôßá@ E.Ù?ç„ß÷é¿Â²Ï ¿ïÓ…%»dÿžߦÿ iܼ¼r 'd ~´´RRIÀdš]²Ï ¿ïÓ…Rí“þxMÿ~›ü(Û'üð›þý7øPQK¶_ùá7ýúoð£lŸóÂoûôßá@ E.Ù?ç„ß÷é¿Â²Ï ¿ïÓ…%m“þxMÿ~›ü)§n{P­ÇôŸï·þ„h£Zÿé?ßoýÑ@^ûÏÿ\ÏóZèëœð¯Þúæš×G@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@]Ò&Ùo8Î?Òÿ@J¥Ré‡1Üû\Ÿý”°.O÷Aw¬[Ø"5Ĭ7¶ÔUVvsèOáQsT/í.ZòÖúÑQå¶Þ nÛC+ ÆÄkCªÁ2ÆVR†Oº’Žà-ƒúT‰¨E#²$êÌ¿yCd­r×ún«¨^Á4‰iFÀ+¡(UòÙb¥ŽF1´ŽùÍ  N¥<¨d&èK*}â$É_®>˜¦Oý§o´·ÚcÚ Þ0¥2 U.n.aMÀÛ:«ÐåCqøå§Ðîç·µQk Øh¡xñ.W¾daŸ¨Ï=kKHÓ¥ÓžáLRÊ}Íò RÓ­7MÉþñüê–«9m=ÆO/þ†´¼ÕMO‹ÿ]bùi ŽÙ}lé¯ô5´.O÷`“‹»_úì?‘­>hp\ÿ´:‚óY·°ùï&é[j$q´ŒÇáTÒ¢æ¨j¶¯ub;A;#d0œÄÑœuV\FÊjp¾ÌLw*1ÚØúE;íÑã>rà®ìîíëô®Dèú¼×VOy,Sy 4«°giùóòî$Ž8 zŠ×oeu™P±Zàõ!÷àä áz…i×%âÈã:ž…NA Üÿ´:ÅÒ,M…£ÆÊêÒHdewFÁ8é±TÇ@*÷4oí'ûưݷÝ\·ý6?ÈV5–‡3\ÿ×vþ”†qº×üIþûèFŠ5¯øþ“ýöÿЀÒð¯Þúæš×G^yàÁ:J'†A,q€û ’G#Ÿjëá$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5¨¬ŸøI,ÿç”ÿ÷Èÿ?á$³ÿžSÿß#ühZŠÉÿ„’ÏþyOÿ|ñ£þK?ùå?ýò?Æ€5ª4ûT 'Ùå„,¼‰",C`aÙEfÿÂIgÿ<§ÿ¾GøÑÿ %ŸüòŸþùã@¿hÔçµ§ýøoþ.´j?óÚÓþü7ÿY_ð’YÿÏ)ÿï‘þ4ÂIgÿ<§ÿ¾GøÐ¯Ú5ùíiÿ~ÿ‹£íüö´ÿ¿ ÿÅÖWü$–óÊûäð’YÿÏ)ÿï‘þ4«öGþ{Z߆ÿâèûF£ÿ=­?ïÃñu•ÿ %ŸüòŸþùãGü$–óÊûäjý£QÿžÖŸ÷á¿øºd¦îáV9æƒË¬Dp•'irX÷³á$³ÿžSÿß#ühÿ„’ÏþyOÿ|ñ  9QØ£Æá7¤®F}Å;íüö´ÿ¿ ÿÅÖWü$–óÊûäð’YÿÏ)ÿï‘þ4«öGþ{Z߆ÿâèûF£ÿ=­?ïÃñu•ÿ %ŸüòŸþùãGü$–óÊûäjý£QÿžÖŸ÷á¿øº>ѨÿÏkOûðßü]eÂIgÿ<§ÿ¾GøÑÿ %ŸüòŸþùã@¿hÔçµ§ýøoþ.´j?óÚÓþü7ÿY_ð’YÿÏ)ÿï‘þ4ÂIgÿ<§ÿ¾GøÐ¯Ú5ùíiÿ~ÿ‹¦Ã mîÝ˳ÀÉô…fÂIgÿ<§ÿ¾GøÑÿ %—üòŸòã@þ³ÿ¯þûèFŠå¼Wâæ]NX,b*É!ÜÒŒõäϽVÏÿÙfotoxx-12.01.2/doc/images/edit-tags.jpg0000644000175000017500000015117111701011016016233 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿíBPhotoshop 3.08BIM&resize sharp resize sharp ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 403 552 1 2 2 ÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀ“("ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?óÏ øsÁ×_ —ž6]nâî}M¬ÓÙ2ç`+ò‘×®N}*Oìß„¿ô ñçýûJ]þMïGëÿ#Rèè |iâ-2-KSµ]J[µiá·¿wY§ ¹<úâ¹q˜¸á`¥%vöK©µ.«²v<ïû7á/ý|yÿ~ÒìÏ„¿ô ñçýûJé>%øY| ¶ª¶Ð»…žÒ) FŽ>ëg·q]¿€£°¶øc¨j7ŸØp\Ç©ˆ–ïU±7JªU>L»’N9ÆrkL."8š~Ñ+yZ”¹YäÙŸ èãÏûö”¿Ù¿ èãÏûö•ê>•£­™ñ&¨óݽֶ¶V£IO&=Dœ}޸ǭkø­d{ŸŠ“5ÝÚCµß Eq2œðÅ”?Ý+ל×CV3¹ãÙŸ èãÏûö”f|%ÿ O?ïÚW¤üaMÕôHt­2kK©lbŸÌFUŒÆsê€ZLã-œb®|=ÕVçÂ~%{@žMMyíd—Oîà1a-ót”[FÄå±å_ÙŸ èãÏûö”f|%ÿ O?ïÚW²jÞÓµ=#U¿¸ƒû3[‡L‹[Û΂!µH”S´ã$œœóQéþ ðã]A¥ÜbM@èÿÚop“(„’>èêhµ†ÏþÍøKÿ@Ÿߤ£û3á/ý|yÿ~Ò½CðΩø*»!s¨kÚYn"Šù#hsÝ7ÌËŒdƒÓ§Zó¤w* fɧüiòëa_¨ßìß„¿ô ñçýûJ?³~ÿÐ'ÇŸ÷é)û›Õ¿6ÿ77«~mþ4ùs1ŸÙ¿ èãÏûô”fü%ÿ O?ïÒS÷7«~mþ4noVüÛühäAÌÆfü%ÿ O?ïÒQý›ð—þ><ÿ¿IOÜÞ­ù·øÑ¹½[óoñ£‘3ý›ð—þ><ÿ¿IGöoÂ_úøóþý%?sz·æßãFæõoͿƎDÌgöoÂ_úøóþý%Ù¿ èãÏûô”ýÍêß››Õ¿6ÿ9s1ŸÙ¿ èãÏûô”fü%ÿ O?ïÒS÷7«~mþ4noVüÛühäAÌÆfü%ÿ O?ïÒQý›ð—þ><ÿ¿IOÜÞ­ù·øÑ¹½[óoñ£‘3ý›ð—þ><ÿ¿IGöoÂ_úøóþý%?sz·æßãFæõoͿƎDÌgöoÂ_úøóþý%Ù¿ èãÏûô”ýÍêß››Õ¿6ÿ9s1ŸÙ¿ èãÏûô”fü%ÿ O?ïÒS÷7«~mþ4noVüÛühäAÌÆfü%ÿ O?ïÒQý›ð—þ><ÿ¿IOÜÞ­ù·øÑ¹½[óoñ£‘3ý›ð—þ><ÿ¿IGöoÂ_úøóþý%?sz·æßãFæõoͿƎDÌgöoÂ_úøóþý%Ù¿ èãÏûô”ýÍêß››Õ¿6ÿ9s1ŸÙ¿ èãÏûô”fü%ÿ O?ïÒS÷7«~mþ4noVüÛühäAÌÆfü%ÿ O?ïÒQý›ð—þ><ÿ¿IOÜÞ­ù·øÑ¹½[óoñ£‘3ý›ð—þ><ÿ¿IGöoÂ_úøóþý%?sz·æßãFæõoͿƎDÌgöoÂ_úøóþý%Ù¿ èãÏûô”ýÍêß››Õ¿6ÿ9s1ŸÙ¿ èãÏûô”fü%ÿ O?ïÒS÷7«~mþ4noVüÛühäAÌÆfü%ÿ O?ïÒQý›ð—þ><ÿ¿IOÜÞ­ù·øÑ¹½[óoñ£‘3ý›ð—þ><ÿ¿IGöoÂ_úøóþý%?sz·æßãFæõoͿƎDÌgöoÂ_úøóþý%Ù¿ èãÏûô”ýÍêß››Õ¿6ÿ9s1ŸÙ¿ èãÏûô”fü%ÿ O?ïÒS÷7«~mþ4noVüÛühäAÌÆfü%ÿ O?ïÒQý›ð—þ><ÿ¿IOÜÞ­ù·øÑ¹½[óoñ£‘3ý›ð—þ><ÿ¿IGöoÂ_úøóþý%?sz·æßãFæõoͿƎDÌgöoÂ_úøóþý%Ù¿ èãÏûô”ýÍêß››Õ¿6ÿ9s1ŸÙ¿ èãÏûô”fü%ÿ O?ïÒS÷7«~mþ4noVüÛühäAÌÆfü%ÿ O?ïÒQý›ð—þ><ÿ¿IOÜÞ­ù·øÑ¹½[óoñ£‘3ý›ð—þ><ÿ¿IGöoÂ_úøóþý%?sz·æßãFæõoͿƎDÌç¾$h~Ó¼9áýÁ+«B—WW¿öƒ®õh|¾€tåýMxçþI'…ì1ª8h¬Ê;Ÿ‡þÕ¼WðÊÓAŠ ®àñº)4Ë•DùÇøW_àÞx4Ñõëd·Ö,-þÍHàÄGðȬ8q·‚? »û,É+?öŸÿA޽KUÒ4Íb%‹XÓ,uÓ•K¨@§Û=+†X„µ³Z£j5}üÏñÕæ£ñ;]û„´Øå¹ÂMvÞhX†Ã’Ìçœ?khZÆ?ÛIm¡6co$†V/m\#ËÆOaÅ{6›ae¥Úý—J±´±¶Î|«h„jO©¬Õá©{ò®»“V~ÑÜñ=ã5”·²ÚÍe—²ù÷_Û#ÿ{<)ãøqþ®|)ñjéuaq›'ö®Ï·fþØ}£oÝÎ#à8Ïz÷z+£˜‹©xSâΩ¥Ú麄zuÍ…©_P·00Mç‘‚Hü…Aaà‰ú}¥õµ…¦™oôF ¤]BæÆAId$pOL÷ú(çbåG‰>ñ™¬ÈË`m^ÜÚ´föÔ-åî<I#'¥uzjøçLðšé¶ÚUåÅòÚDK½^Ïìpä`º•VÇecÓµzs\-cÃm¼=ñ†×EM&Ù´ø´åˆÀ"Kë`BJïò÷ã$÷¬5ø_ãõ 'HÀôü+èê(çacçøV?ÿ N“ÿƒH¿ÂøV?ÿ N“ÿƒH¿Â¾Ž¢Žy)óü+ÿÐ'IÿÁ¤_áGü+ÿÐ'IÿÁ¤_á_GQG<ƒ”ùÇþ‡ÿè¤ÿàÒ/ð£þ‡ÿè¤ÿàÒ/楂£‡)óü+ÿÐ'IÿÁ¤_áGü+ÿÐ'IÿÁ¤_á_GQG;SçøV?ÿ N“ÿƒH¿ÂøV?ÿ N“ÿƒH¿Â¾Ž¢Žy)óü+ÿÐ'IÿÁ¤_áGü+ÿÐ'IÿÁ¤_á_GQG;SçøV?ÿ N“ÿƒH¿ÂøV?ÿ N“ÿƒH¿Â¾Ž¢Žy)óü+ÿÐ'IÿÁ¤_áGü+ÿÐ'IÿÁ¤_á_GQG<ƒ”ùÇþ‡ÿè¤ÿàÒ/ð£þ‡ÿè¤ÿàÒ/楂£žAÊ|ãÿ ÃÇÿô ÒðiøQÿ ÃÇÿô ÒðiøWÑÔQÎÔùÇþ‡ÿè¤ÿàÒ/ð£þ‡ÿè¤ÿàÒ/楂£žAÊ|ãÿ ÃÇÿô ÒðiøQÿ ÃÇÿô ÒðiøWÑÔQÏ å>qÿ…aãÿúé?ø4‹ü(ÿ…aãÿúé?ø4‹ü+èê(çrŸ8ÿ°ñÿýtŸüEþ°ñÿýtŸüEþôusÈ9OœáXxÿþ:Oþ "ÿ ?áXxÿþ:Oþ "ÿ ú:Š9ä§Î?ð¬<ÿ@'ÿ‘…ð¬<ÿ@'ÿ‘…}EòSçøV?ÿ N“ÿƒH¿ÂøV?ÿ N“ÿƒH¿Â¾Ž¢Žy)óü+ÿÐ'IÿÁ¤_áGü+ÿÐ'IÿÁ¤_á_GQG<ƒ”ùÇþ‡ÿè¤ÿàÒ/ð£þ‡ÿè¤ÿàÒ/楂£žAÊ|ãÿ ÃÇÿô ÒðiøQÿ ÃÇÿô ÒðiøWÑÔQÏ å>qÿ…aãÿúé?ø4‹ü(ÿ…aãÿúé?ø4‹ü+èê(çrŸ8ÿ°ñÿýtŸüEþ°ñÿýtŸüEþôusÈ9OœáXxÿþ:Oþ "ÿ ?áXxÿþ:Oþ "ÿ ú:Š9ä§Î?ð¬<ÿ@'ÿ‘…ð¬<ÿ@'ÿ‘…}EòSçøV?ÿ N“ÿƒH¿ÂøV?ÿ N“ÿƒH¿Â¾Ž¢Žy)óü+ÿÐ'IÿÁ¤_áGü+ÿÐ'IÿÁ¤_á_GQG<ƒ”ùÇþ‡ÿè¤ÿàÒ/ð£þ‡ÿè¤ÿàÒ/楂£žAÊ|ãÿ ÃÇÿô ÒðiøQÿ ÃÇÿô ÒðiøWÑÔQÎÂÇÈ_|;¨øWáׄô½m!Kïí û–Xe(Y<’>aô4Wcû`ÿǧ†?ë¥ÇòŽŠ7­ý•ÿä•ûÏÿ Ç]GÄVÕæÔ<7§irFÞÞ›òÚ<›Q˜&øãrªqÉöÆ9®_öWÿ’Vì#?þƒz†¡¥[ßê]äï*ɧNn" €ŠÃgœ|ÄñƒšOq£€Ò¼K%®¡e{-ÔvPZë2Ý[ý¨Üh.6ðÅSrŒ ¨!pzÐðÇÄ#­Ü4)¦Çq+Y5ìQi—bíþR3€ª*K† ²œ»Žv­¼¥Bêdk™Ð%ìm…vºÝÉæHx<n¹<ÔÖ¹³°–Ìø›]žÜÛ›xW‹6ëØ©Ú 0ì[>ù£BRfälÏ3#FÌ¡Š?ÞLàí8ã<ã©çÖ¹ˆrêv>©iâI4Ć YÇcÿiœŸ•Io™·p¡T)êséׯ¾\Q¦ærŠ{ã-ÔöÏû×9¯xIuYkZÔì®l£)n$/LÙ@$ÁÆzÓÖ‘G/­kž%h|IìzcørÆ ¥ÓÄ *\ÎÑyÒ¤Œ~`˜ÒyÉÇ;±Þê#â.‘öœ’i¦›5ÚØ5¼kä•ùþóœú ›Xð=Ž«qp÷ާwÇo¨C "­ú'Ì;r¤Œƒ°©ÁÇ¥XÔ<-öÏ[kÿÛš¼¶Èb†Ö‡ÉHÛnäå7`…ç tÅRjä´Êš=ƧÄ]SM¼Õ^òÄØ È!6這6í|Ì1Üž´Ï\jÚ‡‹í´'T:Dka%ô· n“;ʪ€8+·''Œ‘ÀÇZ»…¼¯KâíÍM¦‘<–´+“ågvϹ»óœæ£¼ð|W)bã[ÕáÔmb–íÚ34±ÈÄ”l©R:`ã#ƒœ“=]YÏ[xƒXÔ´ßk‰¨ýšVx­¯4ô¶B’6]]ƒœ°NɪÄÀ2 +1u$·'=Žry­h–ºî’ÖÒN(ë4d,ˆèr²/mÙé›·â%Àæ|Uâ›ÝÅ^ Tív:~‚—ñÙåS|¦á“>f (nôšŸï´„½‹TÒ-a¾‚+K€±ßažCùd1‚ ’ØVäZ?ð„ÙËi¬&¡©jZ…î« [O{?–$X’¨ŠªFKÁ'¿j»áÔ¹Ôîu ]NÿO½žÖ3%¸¶¤NÌ>WR ;È9È#ó§t-¯‘Ïë?d:Lr¦Šo54‹'ö¦,Ò(Èù¼ï+q$²€¢>¤çšM7ÇwšµÅ¢iÚ4"ÓßP¹šêôưªHQ‚íŒ2§€Àö­_XØÁht­KRÓõ yg”jþX‘ÌØ2«&ß/iÚ§nÐPx<Ö¥®:Ûîo//îšÈØ;Ý2Ÿ1 —,ØrqŽ)h=NkÁâñ6­ej––ÑÇ}Ü@`¼óä‰W· ´˜®8HÇ3OâÉtïêÚmÜZ•Õ”v0MV:t·%™÷1¡ ` gŽ8­Ïø}ô%Š5Í^çM‚?&ÞÂáÐÅ  ä.æ 8'­Zi0Zë÷ÚÄrLn¯ ŽÝБ±U G|Ç<š4Ó|}ygà-SÔdÒg¾¼†âWûuð²y Lꪈ±°-´rdry5¿’æËR»µ±f·µÐàÖ¢ó$ÚÒ VB#` G—×-ÉãÝm<eckeªê¶mmi-‘š#’Xe”ÊÊIS´î<Á¤¹ð„š|VVúž©gÒãÑæòZ2×0F]å—åa–åqÔŽ”¯¨47IñŒÚž¾4Եӭ¬EÖâü¥Ë,‘,›â‹ËèߴÃ%[Ž+Â~3Ô4ß h·^#³fÓ®åžÝ5wæNÒ+H˾2£j¥Cn' dA®®_Û\_éóÞjz…Í®žñKme"Ų'B©·líÜ>ÜU=3áî™d,ážÿS¿°³ye·²¹t1G$›·>B†'ÛA$r)‚¿S ÏâªÜi×wK§ZLɦ˨íÿœp€.lFNCd`¸$ž1[ â|\Ík‡¬¥»¶°]Jâ5Õ ä$`˜°Ó¯òðƒçç‹ËàðtK­ëÄÝÖ—-«YÇm3ÆDœ\±`n'ZÍñÞut'Ð-uFºšÄØÍ%¥å´Éû‹/šwËÑ‚Ã$Ro°Yÿ_#"_‹P#’;L¥•½íÄ2ßì˜ù©¿Ë65Âúù`œÍwÞ!ŠêëD”éz”št¥©p¶ë#Æï¸üdð9‹¥x(évv)§ëÚž™p–Vö—`dòîLH6ISÔn8®ƒ[±}SOšÖ+û«&žÝU¤¸ùÁ= äúQ%£°Fú\¥áÛ­CÀÚ¡pV{û½2 ‰  $xÁ$àaFIè03Ås“üA'D´¼´ÓwÏ&•u¨ÝDò‘öC*ñŸ—æ>hÙŸ—=}«BðØÑ´ý*ÆgSžÛMÂIJùcÌŒ&Åö¨ÊŽ õ'©=*=+ÁºF›y¯Ü"Í1Ö‰ûDR¶R5l—D#žy⇻¢F‹q¯Å¬iÚN£®‹©u&KÔ¸ûkö9“a!ÀhöÉ€-•É<â¶>^ÞßøWÍÕoöî+ëËf¸hÖ2ëìŠJ¨ 8š/ƒ­ô—ycÕµK›´³6· 5œ9l`.üª70$…÷¦hþmE¹±´×µ«…’ct¥¼…q!s#í!@ÉäxÅS°’סÈk^,Ô¡¶cu¯e[Ÿ¾–÷k DÅkäîçR¹ Îâ ©ü?¯x‹^};FƒRòÌ·“®´ÖŠ%žÎZ8ˆÙ½šM¹Æ0¤€zV÷†|-3À—ÚôOc{ý¿.»¤R¤ž^WËDw€IÚOnkwÄš:ôö—R]ÞYêVlÍo}jëæÇ¸a—æJ‘€T‚¢é%ýtÕèRðV£öÄÔ­_S¿Ôn,¦í}§}ŽXà €Ë€¬ (ãzž’²<= Á¢éVòòúòúE–æêé—s•]ª¨  Ž­z–(¢ŠQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|çû`ÿǧ†?ë¥ÇòŽŠ?løôðÇýt¸þQÑV„u¿²¿ü’£ÿaÿôë×ëÈ?eù%GþÂ3ÿè1ׯԱ…QHŠ( Š( Š( Š( Š( Š( Š( Š( ŠÈñ~£6‘ámWQµg´¶’hÃô%Fyö¨,ô\ZA0×<><ÈÕð4ùxÈÿ®Ÿ­ \ ê+þ¯ÐwÃÿø/—ÿŽQÿ׎¿è;áÿüËÿÇ(°\Ø¢±ÿáñ×ý|?ÿ‚ùøåðxëþƒ¾ÿÁ|¿ür‹ÍŠ+þ¯ÐwÃÿø/—ÿŽQÿ׎¿è;áÿüËÿÇ(°\Ø¢±ÿáñ×ý|?ÿ‚ùøåðxëþƒ¾ÿÁ|¿ür‹ÍŠ+þ¯ÐwÃÿø/—ÿŽQÿ׎¿è;áÿüËÿÇ(°Um;OÕ¬-¤õíÝÉ„64H¨A$ç$Õû|™Š«LÝ9`3Š,4TÞý1ƒþù?ãGŸÿL`ÿ¾OøÐ4TÞý1ƒþù?ãGŸÿL`ÿ¾OøÐ4TÞý1ƒþù?ãGŸÿL`ÿ¾OøÐ4V›¨ÜÝxóÄ6r²‹[[Š%\iãqõ$…_l­oÐEPEPEPEPEPEPEPEPEPEPEPEPEPζüzxcþº\(è£öÁÿO ×KåhG[û+ÿÉ+?öŸÿAŽ»ŸÍåø³ÂQýžÚO2ê`$• §œô®öXÿ’Vì#?þƒzµÅ­ÍÝ¥ÍÄ %Å£·rÌ<²ÊA8Ž9T½ÇÐó_ë~1Ôí|)$Ú¦’âœqdÇì¾Xv>Ÿ*Ÿwåž ©›ÅzÝæ…¤-Œÿñ;‘o ñZéâàH¶óŒ˜iF™žIËÍw–z—e˜––)é…˜9òw‚$œ†o½ž¼b©ÜxK@žÞ$Óq&RžUÌÑœJûåVepÌŒÇ%NWÛ¦ß@8ø¼S¯ëš|—šUņš¶z:¤Éq —Ï’_30Ãj(óÉËïU,ü[âýe¥} Okƒeoj^(íQ’æY!Y[t*˜— …oSé[þ,ðZ­½ž“g£ZÚ[Ú5yä¹WŠA 6TÎÉ \àúÖÌÞ ðüâÓϱid¶·Ž×ÍK™`i’<ÝCŽ:0n¸¦¬MÆøºÿQ†ãBÓt‰`´¼Õ®Å¿Ú.#2­º¬O+| ÍˆÊ 9®DÔµ;õ]:Âï~¹u­Ý;‹-8NfTŽ,¾Ö‘̹%Ž ÀÍz–­¦YjöËo¨Û‰¢WYcÛ#DѺœ«£¡Œà©·Lƒ–ž ðävÑÁ˜aD’IƒÃyq¥ÜäȲ!€HóÍ îzg†µ}c^ñ‰ª¾¢Ö‘¾4×) ‘$h®LnÏ€ÇiÃ`‘Ó‘Z>× kÉ¡[í;C§“z,³HÀ¶>‘…=³¡ñ†¯¯i×ú‡‡D;J†æâ9".Ívä³@<Hܤ_Ƕ¹ÒÃjë«ZHPŽÚK`¯Är«À9€‘“Û½fx{Ã÷~ðÅ嵌š{ëW·3ßÜJÊël×¶z»`]«Ó'õ¥Ð-©‡7Œ/ï,uohíž°¸µŒ…šdÀ{’F6¬ˆ óó+SÇ‹oRÕ°mlÁ˜òÄû³ÓÎù¿Ü­X<-6—ðò èrج‹ Dó\#˜ÈÄÊû@'ø‰ ôºï…ëÁ6¾Ò¥µƒNXRÎi.±Ã«“ŒgœÓ~BF¾¹âVëÃpÚÝØØioîƒÉjd1[Å·ÉÀÜ71'‘}¹<9â?Ï'‡.µK‹ -µswlmà”Äð¤¬$O!ŒM•ÀÆF ®ù´Û¶Y\­ª‰¬ak{GÜߺ•U€ÁÈUë’;b«Ã¡iP%‚CbŠ–,–£{þé¤ý윉sž´JÝ_©ÀxwXñŽªžIu]*&×tùo ­‹²ù{O~và%qÎ3V4xƒÄ±éÐY\éú|˦Mww$4‹4‘ÎðlA¸mRP’rH×sg¢é–GOû%’DtèÚÓçɰ Œž~èääñÆ*œþÐ'µ¶¶“LQ °‘bXî&Œ…‘‹:W‘‰$£¾Ô=vNÚžS ö±¨|(º±°¹²´Ót¿ Á$ÑÏvº2Ã! 6à‡$×{á¥K?5½²„†ûÃö×S*€›XÕ¸îRLä(«RóÁ^¼µ‚ÖãISm²Ù,Is4jÐ/Hßk1Aäo݃Ï­ "ÞËU¾Ô#fiØ),0ÄÔ^§©bNyàvÍ;­Y<¯Oë±™ñ#þIÿˆ¿ëÂoýÑñÎ)4(Xßë â{ÛXí´«k;ùaEuŒÍ¥W ¹pä|Hÿ’â/úð›ÿ@5¹?ƒ|7®Ia«êåu1§ÇiçÛjwÌaûÛ1ŠÜsÏ^=$[<ïÆú–µ¯âÝ@]êFçBû*[Ë á†Þ܈R\¼ľs»Gʶ1·ßKÙüeÓLW—æ;ý*òi­äº‘¡Ü’[*팪@fä œÖµ÷„ü3«[jw–±Myn±…v¸|?–IŒÈ»¶ÈTœ©pÅO#£»ð‡‡.üMˆ&7'Vˆ‚’®©pŠ `í$ ´í\®Ür >·&ÚXÅÓÖ]3â‰"¶º¿ž6Òc¼Ü]I*,­$£äRv Â¨À®OáUÞ©&©á£sw«Hºî%ÕÜ—7æežB±?›dˆv´Œ›@^ƒƒŒ×£ÛxGÖÞ(“ÄPý jÒ¾c©ÎÊÀçå1™6m‰ ·¨¤Ðü+á òòçIµ†Ú{ Êì³±Ú¬ÅŠÆ –%¶¦ÑžzÐïsžøo`fÓgD²Œiåã¼oõá°¯¿~¨àqœ×G­øWC×%y5m<\4‘yââXıõ "£…p ÈÝœE:? èÑë ª-‰kÕq"4—3•ÔiÞÑ4ÝDßXX}žã.ÊâS?1HwùjN…G_­O{¡iwòÞI{cïyn¶³³³|ñ+UëÆ ‘‚z.„ÕÎÛÄ^/–Ó]°ŽÒgÕ4ù,¤Ib©0·œ¾öû:ÊAe’ðXj[KíKYñg„‡ˆßcA¨¥À:{Dâ1‚²BÏÀØèFG^:Äðg‡£ŠíO•Zí¢’âo·Ü™åh·yle2y„ä¸`rÄßðŠhBÚÆÓÌIc#ËnÐÜͨïäÈ®$rÙù·1ÝÆsDZ[ƒW(è¸?ü[´`?NÀÎqóÝWS\¶ŠK|Kñks§éÇ㺮¦‘AEPEPEPEPEPEPEPEPEPEPEPEPEPζüzxcþº\(è£öÁÿO ×KåhG[û+ÿÉ*?öŸÿA޽~¼ƒöWÿ’Tì#?þƒzýKQE€(¢Š@QE0 (¢€ (¢€ *¼W¶“]Km Ô\D?yHд½GQÚ¬PEW¸½µ·š(®.aŠY›lI$€$ôQÔœö«QQÏ4Vð¼×$Q Ë;°G¹è6ÒêÞò5¤ñO 'Dá”ã¶G5UHõoÒ;Ëg»\î…eRã«ÔP¢ 2†p@#j›í3“þ¾_ûìÔTÉ¥ŽšYÝ#æw;BÜ“Æ=èÇÚn?缿÷Ù£í7óÞ_ûìÔé$k$l®Ž+)0?N1D²$Q¼’º¢(%™Ž€3ÎxÞ‹Ø7'ûMÇü÷—þû4}¦ãþ{Ëÿ}š¡c¨Ùj æÂòÚè'Þ0J²c>¸éV¨_´ÜÏyï³GÚn?缿÷Ù¨¨¢àKö›ùï/ýöhûMÇü÷—þû5\ ~Óqÿ=åÿ¾Íi¸ÿžòÿßf¢¢‹€ç’I1æ;¾:nlÖ~¯¥ZkeÔVá­÷+ÜÖä‘êbe$g¤‘œp*õËÿÂáŸùóÔðuÿÇèÿ„Ã?óç¨ÿàêÿÿ×QE—ÿ„Ã?óç¨ÿàêÿÿÑÿ†çÏQÿÁÕÿÿ®¢Š./ÿ†çÏQÿÁÕÿÿ£þ ÿÏž£ÿƒ«ÿþ?]E\ ÚN%ÜšE¬±Kt¨“<·sÜ3,TfWb on:ÖµPEPEPEPEPEPEPEPEPEPEPEPEPEPζüzxcþº\(è£öÁÿO ×KåhG[û+ÿÉ+?öŸÿA޽q¤DeGu Ä…ýâo¼öWÿ’Tì#?þƒw^"¸x¼Yá(•a"k™”³Æ—±Ê·U<~\T½ÇÐéh¯)ðæ¥âÍN×ÂOâ(U¼Aâ]¶1Ÿ³òºz± ‚+Ï·3¯‰5CAÒaµ½½þÛ)zÓ}†Ö؉ÞcšæwTE$.@9Ëq€)=4 £Óè¯,‹Äúæ»§=妭m£ý‹@‡TtòQs,¦AÉbqù_ÃÎ_­V³ñ7Œ5¡<šÐ²ùþq‘¸¦3Ævâ½–«@ÖKw3[­šÞJÊñ¢ dÇ@Ì>fÄš³Nâ±Á|Um&áû‹ï±%úk)fÚ$XÅÌeö“È\uöëÅw¢E” "uxßæVSÀóÁER¿ƒL•£mNÛO™€*†îÜ€z¸gmª*Ĩ±…Â*.ØÐcð©H}ndø¶ïF°ðõå߉…¹ÒaPó …܇ 1‘ÜîÀžxæ°þZÀ°k:”1ÙÚNá&m«)h«µC…áeo¼Àt8A5×Üǰ²ÝŰue'ԃǡö<Ô:t:|1¸ÒíìaŽ_ì‘">§hÆi§aX·^]⥷|=6Ÿ.‰; T,–Ö1¿ópÁ™äî@yeÂñžkÔjœ §A}#Á „WÒ <‘Ä‹3gÕ€Ü}ýh[Üok[ïœf¸/Š–Ú•öŸödÒ®¯´5·š{Ï³Ë —u_ÝÆþdˆ|¼å˜®âB…Æk¼¨®%‚4ÿIx• ù„`ûx¤ÀÆð’MàO¼ÖÒ[?Øb_-Ê“€¼0ÚHà:ÔE[ñ=½¥ß‡5KmFámlæ¶’9§lb4e ±Ï“éZ1”1§•³ËÀ °  Àý)$XÞ7YU2eu ¤zxǨéNO™°»c€øhÐÙk𦅥ßYêºU¥•¼‹{oi ä§“#D¹Â†Ç_Zô*­aö(à0i©g*wíQr{½ýúÕšmÜH(¢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€>sý°ãÓÃõÒãùGE¶üzxcþº\(è«B:ßÙ_þIQÿ°Œÿú uëZ[Osmq< $öÌ^9ˆ ‘Ï\w¯'ý•ÿä•ûÏÿ Ç^¿RÆQ¶ÒtëU°[kb[ÂÐ.q¸Ûsê ¯Z«sá ê!¸Òmž(Grë´ÈŤåNHbI*r3øVżÀã<[àK}r K(ô‹+;kvµA%£ÈñFØâ2®>ë†^‡¯?„|?qö#u¥Ãq%œ o²WhÐ`*Fà89æ·(¡;+º™úΧkpÇ­f—1ÆÞbì…NÈ(Ag¾1Q·‡´Vm9¿²í”éÀ O,²yC à`ò2!² æµ(  ;oør×Í6ú-¢a’Ù¾ùýÓŒ4c-ò¡†K©xgCÕ&·—RÒà¹ktG½œAÑp ¼G¯E uŽI'—O`=+ÅÏ+YYÚE4–ë}{ ¤³FÛZ8ݰÄÄŒŒö'5»Uµ+mJÆk;èĶò®rG¾Aƒ9ìy£¨lY¿øáq¥I¾—i§Ëf;èGbG_˜œ÷Ífx^ö}KÃ:MõØââÙ$“nF¿WŸE¿½µû©â]JóJ +ÛyQÅ$«ýÉ&_™$zVÐ ª«*F€*"  Æ)°2¼á­#]З[×tû]OQ¾wg7‘,®Ê#Ea„9'“LÓí"ÑüW¬è¶ ÇMŠÞÞî(‹ï!‘Z0OðñÛwbœºEÕ¥ÍÌÚµs¥%Ó™'`Iâg?yÕ[÷ÆA<ã¹µ¤ééqN"’{‹‹™<Û›«† ,ïŒeˆàp;š@QþηñâÓ5PeÓml…àµcò\Hd+óâU;O¸Ïj›ÆZ—áÈôÝW@²·Ón…ý½«CiÄ—1Ë*£+ ùIËç:â¤Õ4¤¿–Úâ+‰ì¯íXµ½Ý¹Óv7)†C•#ŒŽ*yu+{ýoU¹Õ®­‰kexR`b6ï¹Ëà“€N1Ö„ÐøÒæ{/ݽ¤ÞD¬ñÀ'ã÷"I3&(bÞœzWïgÆeø|¾ô¯³«mßí˜Ã™üügÎÌçï3Øzeݼ7–Ó[]Ä“[̱¸Êº° ‚;ŒY#EÔ~Æ4ÿøJua¥³É Ÿg÷~Ð~nœd‚ØïžhVþ¸šëÖÒ\ÎndŽ[‹o´<õ†y"Yl² lô9Èâx{KñÕ5ZÛêw?nžÒ+{¨ÖXícŠBŠT æÆNð3ŒV¥­¼v–ö–p¤¶ñ¬PÄœ*"Œ=¿ZΗI¸‡QžÿDÕ®4››¿i OÌ£hrÀ} .àF@ç’i0Úu¶ã–Ó4 #Óïté/žÑs²ÖXæ‰ èªâVùx‹Žõ©gµâ½C¾®—oÊ0=I½Zÿ„Åÿô=Aÿ‚Uÿã´X š+þÐõoÿ‚Tÿã´Âãú­ÿðJŸüv‹±EcÿÂãú­ÿðJŸüvøAüaÿCÕ¿þ SÿŽÑ`6(¬øAüaÿCÕ¿þ SÿŽÑÿ?Œ?èz·ÿÁ*ñÚ,Åÿ?Œ?èz·ÿÁ*ñÚ?áñ‡ýVÿø%Oþ;E€Ø¢±ÿáñ‡ýVÿø%Oþ;Gü þ0ÿ¡êßÿ©ÿÇh°V?ü þ0ÿ¡êßÿ©ÿÇhÿ„Æô=[ÿà•?øíbŠÇÿ„Æô=[ÿà•?øíðƒøÃþ‡«ü§ÿ¢ÀlQXÿðƒøÃþ‡«ü§ÿ£þÐõoÿ‚Tÿã´X Š+þÐõoÿ‚Tÿã´Âãú­ÿðJŸüv‹±EcÿÂãú­ÿðJŸüvøAüaÿCÕ¿þ SÿŽÑ`6(¬øAüaÿCÕ¿þ SÿŽÑÿ?Œ?èz·ÿÁ*ñÚ,Åÿ?Œ?èz·ÿÁ*ñÚ?áñ‡ýVÿø%Oþ;E€Ø¢±ÿáñ‡ýVÿø%Oþ;Gü þ0ÿ¡êßÿ©ÿÇh°V?ü þ0ÿ¡êßÿ©ÿÇhÿ„Æô=[ÿà•?øíbŠÇÿ„Æô=[ÿà•?øíðƒøÃþ‡«ü§ÿ¢ÀlQXÿðƒøÃþ‡«ü§ÿ£þÐõoÿ‚Tÿã´X Š+þÐõoÿ‚Tÿã´Âãú­ÿðJŸüv‹±EcÿÂãú­ÿðJŸüvøAüaÿCÕ¿þ SÿŽÑ`6(¬øAüaÿCÕ¿þ SÿŽÑÿ?Œ?èz·ÿÁ*ñÚ,Åÿ?Œ?èz·ÿÁ*ñÚ?áñ‡ýVÿø%Oþ;E€Ø¢±ÿáñ‡ýVÿø%Oþ;L“Á~.†6‘üs Tˆ*rýµ¢Àxwíƒÿžÿ®—Ê:)ÿ¶"âðäc$$×+“ÔãËã½h«öWÿ’Vì#?þƒtÿmà“QÐ%Öí&¼ðÔSHo HÚD/³÷M"¯,»téšæ?eù%gþÂ3ÿè1×°#2QŠ·¨5/p[M¬Íi¦ÿoµ……Ôz~§áÄ·Òâ‚ÚC¹‘ç&0ÊœH¤Ž:zVuç…ã¸Ðošå «V@1´ä¸ûÖn¹¥ßßê«?ˆn嵺¸Ól¿³®¤Ò..î!“Ê_0Ûɪ!˜K’r¤ž3‘Å{‡ö»zÿäþÎí‡õÿÈ?ý ’xWOÕþ*ë·šÞ˜·‘Åef-Þâ2Ñ£ƒ!fLü¡Á óGb2k#CÓ.[âŒþ•$:Fw&½ '*Zà6Ôÿ€ÈÓ¾=Ç¥z'öÃúŸûò?øºËÒa±Ò.oîl!‘no¥ó®e”¼¯#s¹å$(Ï 0@h¸X×Ò5û=WWÖ4ëO8Ï¥J\Œ„ÞÈn„á†qê+/â„÷ñxT‹H‰åÔ®ÐYÛ„åyHMÇ Ù'¶*Í­Ü6;[A&â_:S°S#æÃòØP2yÀÕcûa¿Ì#ÿ‹¥¸Ï }/WЬµ*ûK†ÞÖÞóLÖ¢Min"X•’)•X¢’ÃìâB¡sûÂy©µk}cÃþ)º¾y­,fñJ][ý³N–x.Õm  %…pÍ =ñ=1^³ý®Þ¿ùÿ³£ûa½òÿgNâG˜xI´Õ¾x^ÿVð¥”&ÃPµy-’ÌÌ µKæV]â6Œ+»ÁV׊43\ñ?ÃÈ`ÓRoF·„À°·aÓ œ|¤Ojí¶üÂ?øº?¶×ÿ ÿöt]^àp^/—Ãú'Ä_5½¤vòiÆhç– 6>M»[ȱ¡uS„ÜÀÎ3Ú¹ßÇw/ÄT¼ƒM·µÔâ׬âG·Óg’î[Mч•®D­"”ØF<œ_þ×o_üƒÿÙÑý°Þ¿ùÿ³¥æ>–$¶×ìî|M{¡EçÛ;xîe;ÅW$(ÝÓ'iãҵ뜆òng¸Š£ž}¾l«lI·¦â'9þµcûa½Oýùü];ŠÆÝ‰ý°Þ§þüþ.í†õ?÷äñt\f݉ý°Þ§þüþ.í†õ?÷äñt\ º+ûa½Oýùü]Û êïÈÿâè¸tV'öÃzŸûò?øº?¶Ôÿß‘ÿÅÑp6è¬Oí†õ?÷äñtl7©ÿ¿#ÿ‹¢àmÑXŸÛ êïÈÿâèþØoSÿ~GÿEÀÛ¢±?¶Ôÿß‘ÿÅÑý°Þ§þüþ.‹·Ebl7©ÿ¿#ÿ‹£ûa½Oýùü]nŠÄþØoSÿ~GÿGöÃzŸûò?øº.݉ý°Þ§þüþ.í†õ?÷äñt\ º+ûa½Oýùü]Û êïÈÿâè¸tV'öÃzŸûò?øº?¶Ôÿß‘ÿÅÑp6è¬Oí†õ?÷äñtl7©ÿ¿#ÿ‹¢àmÑXŸÛ êïÈÿâèþØoSÿ~GÿEÀÛ¢±?¶Ôÿß‘ÿÅÑý°Þ§þüþ.‹·Ebl7©ÿ¿#ÿ‹£ûa½Oýùü]nŠÄþØoSÿ~GÿGöÃzŸûò?øº.݉ý°Þ§þüþ.í†õ?÷äñt\ º+ûa½Oýùü]Û êïÈÿâè¸u¡ÿ7?õÉ¿‘¬¿í†õ?÷äñuº¡–'‹me*q:ÿÀè¸3~Ù}túøºþiE7öÅ2?8nšé€=Fv)¡Wì¯ÿ$¨ÿØFý:õúòÙ_þIQÿ°Œÿú ué÷ˆ´Ý K(õ)'Yod1[Ǭ·+œIÎ?>Õ,f½ÏÁã }Al’âq+N-w½¤ÉŸù&F]‚LuBÁà€x¦ÛøÏB¸Šæx®æ6vâF{Æ´™mˆŒáÂÌWËb<)9#½-BçEEs2xë@ŠÂêòâêâÞc•g²ž)JqylÊ±È ŒƒïUuØ[M§%µ¦¥sö@X\ ÓîV[Så4™h¼½äí…À, #!N˜®ŽÂŠç¼QâhôÑ –7× ©]­¹òmfw…Y‹T,[å»áùëýõÿףχþzÇÿ}õëŸo |>³Ð´›ëïÇ;_BއO°º¸ÞJ$"+:¯ûÀc€y­]À?µ2ÛQÒôm>æÊá‘J›°ÃóàñÈ<ƒhå –üøç¬÷×ÿ^>ùëýõÿ×§®ðWý ¶ø÷øÖ ¾øgˆßCK©Gåù©Ä©™‚IJG270â‹ÍÏ>ùëýõÿףχþzÇÿ}õë xká“kÒhñèi5ìr¥òlî$†'`G•ApÌ#ÔUKM/á5ÝÛ[A¦Û3âb’k…Šo+>`†B6JW …Ðà°?ŸüõþúÿëÑçÃÿ=cÿ¾¿úõÊhö?õky®-tûT‚+O·™.­n-•­úy©æÞ€õ+ 2*k-#áU晩_ǤE¾oö»¡qes ‰ RÂO-Ô;) Ø p@ɢ¹ÒùðÿÏXÿï¯þ½|?óÖ?ûëÿ¯\Ο¤|,¿ŠÊhtM^ÍÓ\i÷PG3È¥“kH @8 ã3’×Ò< ðóV7£OÐí&ûÃZÌ|¹ T€ÝG##¶x4X._óáÿž±ÿß_ýz<øç¬÷×ÿ^ÿ ·Á_ô.Ùÿãßã\·ŠtÏ„þ¸– kL‚!„\ÍåZ\N!Œ¡¤1†  ØÉéE†tþ|?óÖ?ûëÿ¯GŸüõþúÿëÖ¡áï†:~¨–ºÃ3:G浕ÏÀÚ¦m¾Z±Èà°9 Tsh ãñ΄ºª[…ÄPi÷R¬^`ÊtRФgæ'œ‘Š9Ett~|?óÖ?ûëÿ¯GŸüõþúÿë×Ö¿ï<]¡iZ.‡a=Ô—kus,Æ›`‰hdl$€8Ã2–Û"´­¬þ\Z^ÜǦÀ¶ö–|òIgs{tûÒŹGšƒ#æMÑê2XgYçÃÿ=cÿ¾¿úôyðÿÏXÿï¯þ½rÐiß eÑõPé–ðYéñ$÷ siq$oŽÔ3ÁÁPA< šÛѼà^ÐÜÚxh$aö»´žÙò1ü…lr9Æ(åËÞ|?óÖ?ûëÿ¯GŸüõþúÿëÓ¿áWx+þ…Û?ü{ükƒñ¾ák‡N°ð>z#Ó¤Ô¥’ëR6ƒb0Rª °fç<•¤R°ÎëχþzÇÿ}õèóáÿž±ÿß_ýzãžÛá=½¦5þ£ÞXŨžÖwkhdÆÖœ eˆdã.@È<ñZ“xoá”~!: Ñ#›QAJ–öw$"Lìó$@R<í$naëÒŸ(®nùðÿÏXÿï¯þ½|?óÖ?ûëÿ¯\õ¿„<qã™t8ô%Ù´í¶w1»°u]É#¦´““ìk£ÿ…]à¯úlÿñïñ¢ÃçÃÿ=cÿ¾¿úôyðÿÏXÿï¯þ½;þo‚¿è]³ÿÇ¿ÆøU¾ ÿ¡vÏÿÿ9@oŸüõþúÿëÑçÃÿ=cÿ¾¿úôïøU¾ ÿ¡vÏÿÿ?áVø+þ…Û?ü{ühå¾|?óÖ?ûëÿ¯GŸüõþúÿëÓ¿áVø+þ…Û?ü{ühÿ…[à¯úlÿñïñ£”ùðÿÏXÿï¯þ½|?óÖ?ûëÿ¯Nÿ…[à¯úlÿñïñ£þo‚¿è]³ÿǿƎPçÃÿ=cÿ¾¿úôyðÿÏXÿï¯þ½;þo‚¿è]³ÿÇ¿ÆøU¾ ÿ¡vÏÿÿ9@oŸüõþúÿëÑçÃÿ=cÿ¾¿úôïøU¾ ÿ¡vÏÿÿ?áVø+þ…Û?ü{ühå¾|?óÖ?ûëÿ¯GŸüõþúÿëÓ¿áVø+þ…Û?ü{ühÿ…[à¯úlÿñïñ£”ùðÿÏXÿï¯þ½|?óÖ?ûëÿ¯Nÿ…[à¯úlÿñïñ£þo‚¿è]³ÿǿƎPçÃÿ=cÿ¾¿úôyðÿÏXÿï¯þ½;þo‚¿è]³ÿÇ¿ÆøU¾ ÿ¡vÏÿÿ9@oŸüõþúÿëÑçÃÿ=cÿ¾¿úôïøU¾ ÿ¡vÏÿÿ?áVø+þ…Û?ü{ühå¾|?óÖ?ûëÿ¯GŸüõþúÿëÓ¿áVø+þ…Û?ü{ühÿ…[à¯úlÿñïñ£”ùðÿÏXÿï¯þ½|?óÖ?ûëÿ¯Nÿ…[à¯úlÿñïñ£þo‚¿è]³ÿǿƎPçÃÿ=cÿ¾¿úôyðÿÏXÿï¯þ½;þo‚¿è]³ÿÇ¿ÆøU¾ ÿ¡vÏÿÿ9@oŸüõþúÿëÑçÃÿ=cÿ¾¿úôïøU¾ ÿ¡vÏÿÿŠëáƒ"¶–DðõžäFa÷ºõ£”žÿl §†b÷ü£¢¥ý²¸ÿ„|ùøºúH£öWÿ’Vì#?þƒz6­¤Ïyâ?jj¾»M9\ÚÍkgs˸”>üÆ6}á ÷üv|C¦jÏàfÒ4‹{ï%´û}¢å Œ©`V7' ÀϨ§}¶_öï§ÿ>Û/û?÷ÓÿNè]nsžñæƒá‹K•²eÒá6÷6j³Ã ÆQ%óR0ù\°®9ë‘V|?aâø7ÂÚ¥µ­ýûj>U䱉mÞI$’@O# ÀÝÕˆõ;ßm—ýŸûéÿƶÍíù·øÓæ Eyö»ámfóÆñjšRÙéÑyÐ4÷ÐßJ²Ïg1Éo³Ë~¤- lý¶_öï§ÿ>Û/û?÷Óÿ úƒ­h:î³’i³èz¦ ú„“I;¥Ä&EPè!VårpÀ8ÇÎx[áÅîŠ"³{-*X-#ž;mA¯î^_Tù q¶†!ÀÅvm—ýŸûéÿƶËþÏýôÿãK@9 Ká¥ö©¦ÙX]]ÚÇ ~›D•³3< FS÷G<ƒÈãÒÕ—‚uð牭ntí"ÇQÔ´ö²Žhu ‹­ä«Œ³J ¢nl…ºžMt¿m—ýŸûéÿƶËþÏýôÿãBÒáØÃø¾™ð¢Kk»¤·Ô`‚!§ùy/¢ÃÀ±.2Ìdp dŒñÖ¥0ëžøczŠ^ø’FŒ´L£73Ì ®Åy¦Glô µ®/¦0?àMþ4}¶ooÍ¿Æú…¬týëÄ>1Åqc¨øŠ 6ûI{¿iÐZ‹+‰X]3Æîª`Tù¹FWiºf½#í²ÿ³ÿ}?øÒ‹ùÇB?ï§ÿâ©^ãZ‹|®kZíÝÂ=¤°Éykq÷:…Âýš(„{á[uY%‘Ûq<ïÁ]†‰áû‹x«T™á6ú±¶ò„dïQ[î1Ôñ‚x¤ûl¿ìÿßOþ4}¶_öï§ÿ|ÚXJ68Û?‡ÚëIáÝ:ò]14m ÛUž)œÏ:OF° T*‘¹²yÏj‡KøoªAáÍGL’ËGŠäèòév÷˨\ÌϹUA)"‘£pRÜŽ•Ü}¶_öï§ÿ>Û/û?÷Óÿ+Üv25ÞÏ.½#Ûé·ñ_é––)ks+¢;DÒÜʤ¨ÃŒ0‚3Æ(Óm¼Eá/xŠê}ú–£Íua`“Kzc!>HDŒ¢I2Ãû¹çõ¯öÙÙÿ¾ŸühûlÞß›V7t³xÚm¡ÔÖ%¿0¡¸XI($Ú7Ï;sœWâÏZx«Å¿mÖml®´ßì©,”J›¥ŠV‘H‘2¸R8`rçZŸm—ýŸûéÿƶËþÏýôÿãCÔ8«¯xÂâÆò9n´yîõ'S¹–Y2†#"ùñ€Ÿ9d’‡h БZú¿„5y(Ͱ—PŽúUšh¢ë–û<¹2 ‹ö­ï¶ËþÏýôÿãGÛeÿgþúñ¢ác4é>$o‰Ë¯5Ž’4´²}8§Èf(Ò«ù›<¹Âãnïølèwú½ç‰|Cí’Ûé’CŒÌ¬¯;÷JÜðTUw éP}¶_öï§ÿ>Û7·æßãBc:Š+—ûl¿ìÿßOþ4}¶_öï§ÿw EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EËý¶_öï§ÿ>Û/û?÷Óÿ EA¨ÇÏýroäkžûl¿ìÿßOþ4†òR!H#Ý=1žh¸XùÃöËë ×Å×óJ)Ÿ¶·ðÛ7V–䟩­ÐޝöWÿ’Tì#?þƒz?ˆ5û}¬â’ÞîòòòC½­¤^d² $€çŠóÙ_þIQÿ°Œÿú uèZþ‘yuªiz¦“=¬z†žÒK­â)#‘v°%A`zsƒÏq­ŒÇbëH‚Y¬ï¯oî®ïD6–VÄʶðÌP3©#nÐIç'³ußÏ­Æ48nŽŒšIÕâ;%˜Ê7mèdRª¼ç«dzxøop‘Ù\Î|;«jQKxÓũٙ-dr «2:ž:A#½m7ƒå/të.›l&ЛHYÀb†9BåÕ@ÀNOsÎ*´%_úõ<}§B'ŽX5ÅŒ6Ò^ÝÅmˆbF]²s·žƒ$wãš»7Œ´øµ7¶h/¬wKbúˆƒ6©;¡ s¹‚“‚8ÍgŸÜ`øOöûõh-aGÚØÉ€FK r2:ñPZxluÙç†Ç·vsÝý¬Ü_iÁïa$‚Ê­´ƒÈʱ`FqÎ++†¶%>7Þ"ðýŽ•kx,ïu7´{¹íˆ†dŽ)KùOž¡ÑFN;ã<‘¥qâ;¨¼y‘w=´–bäÝE´„&@Ÿ0'„IäCT4ß j¶·¾ŠMFÁ´múK¸T+ý¢Uu”n6‚ §œÝx­=KD¿“ÅVú¶sk5«XܤŃˆÙÃoŒ€Aqƒ€p3ŽE[úìÝÿ]FCã-ÊjVº†•ä[Évþ,I }“äヌUøXºby‹y§ës-²Ý,7›^DwTM£',ÌÀmÈ#¾+ÏáqŠÙ£Ô%Ñá„i7lÓéÖ­ö«³"¨ûD®Ê ?ˤ‘’pNj= wź֡}|šMìK¤­žo,'ŽÒgiˆe‘Cî!I8!Ç'°’v=+J¼{û3<¶¶¡‚ò0’ s€HÇ¡æ®V‚´)ü=¤ÏmqîM1g,6nûVC ¼††3X|ÕŽ—{²é*ò‹ól<³‹c<–“q+åH à°8ä³â?‡^&×uŸ´–¾‡MÖM¢¾.%g o#8fO$+3îŒñŽ­M­¬"ÉÓõ±N~(xh$®cÿ²“ãQþ“Éäp=j¦‹‰5kíjÎ?ÚÛO£²­Ø»ðÓBp,¬ \`®9éÓ¶+Ÿ¾ø¯>“-„zS[H²„g–Ý!‘á·O;)2s f3€r¤ž¢»™ü ¬ CÅhcÒu +Ä|0L—72Âé,PÂüˆrŒvå ¹$Ò„•®Âähž$žÖ¨>$hÛM Š)SGR’98 ¬.pIôÕɼ#ã8!yfñÖ•H¥™ÛBÀP$“qÒŸáßkºg…ô­>étùmµxîÄw¨f[[u?òÉÂ!yÔr²2޼ç=¯Š¬o5/ ê–Z]ÊÚ_\[!×í–ïFŽž¸½šo)w \± NYWnÊF Q'¨x×Å·GC/ªèÚcCâyt[ÉÒC ÛcvV!¥!wgv`8®§@ñÆ«sñVÐus¦ÁG3Øb.&Xö~ñæYX/Þ;‘‘HÊàšß¸ñ‚.tÄ’ãUðìº}Ñ’áL“BÑJc#{òpÅN2{Túf­á 5IÆ™{¡¶£1xåû<‘y¯å¨. ®Aè¦+¼©\êþÓïïnt»»™£Ý$Ú[³Û9ŒÆ[’8ïß5‘§øƒR½×5µiôË{M>Y K‰Ì¥c %/¼§' °ð>÷aÒè—Zuæ•o>‰-¬Ús¯îdµ*Ñ0Ïð•ãÏJ̹Õ|/ˆfŠâóG]n vyäŒ\$ n$ÿLdúb¥”ŽJׯšå§‡´]OX›Ha©éê_º·’%‰ÖG–•· ³sÀúÕ7ÄڕƱ1ó¬%¸“@ŽúMí ¤ÄUÉr0I6ÐBžsÖµ®|EáëÛMYÛÛk:]ÕÒÚCqh`š y1òç-žœ|¡ˆö«‹?„ßÄW*ú#k«e€y_h ´˜}ìmÀçµ08i¾ xˆiÖP[Ci>­%Ô];Y,1Û•‰dî¹;‡Î³ŒðpEz.“¬Átl­.ä·‡YšÉ/$²I„…àûÊãwCTôW𞻥½žý‹¨iÑf‚ØE,J[J”É©,:vš×œÉomåÛ„–á°¡!L ì£,}hÌ|D½Õ­u? &‰{ ¤’Ý\ <øÚH¤U´™ÀdVRܨ?xr3íTt¿ß^ø§IÝ=žËÍkÔ´ ɲPð}â\†yÁØòrk ›Æ}959µí¬Vo%.šê3ÈÉ¡³ÅI8ô5_ø9õÕ·IôÖBŒF#8^ñþÖ6a¿Ýç¥M†q·*ñ ïƒæœjv6µž§eØsyqG$±¡…Ã+Œ1%Õ°W# y·^1Õ­|S‘:dÖ©{k`öé ­ÅÁ™7ä,kœí*ß*7Ì:WMáÙü1«é7xuô{Í3qŽhì¼·‡qê/Åj&d—0Ü%²ÜC•¢% ‰ýÕ8ȨGoãnÏÃøŸ]“KþÇÔvö²‡·€M$BMæBF[彫ªðîµ,ö:L:ó[Yë·Öæëì pÊ ‚W’J†UcÓ9Æ[Ö4+ZÁ,não±‰ m±$ÁÎת“ÕO®}ŽÜß­á… ÒÆbãæNHϦ@4Ë4QE0 (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ óÏé:v±â¯ampÍ*Åp»Ô7™ îÇ® üëÐë‰Ô?äfúöŸÿG[ÒcFž ð’ÆÄx[E)Çú?ÿ^—á¯ü“/à*’áT`(ó_íü…nÍþ©þ‡ùVÃOù&>ÿr_ýô€ñ?Ûþ=<1ÿ].?”tQû`ÿǧ†?ë¥ÇòŽŠhG[û+ÿÉ*?öŸÿAŽ»zÈê^>Ñ,VO(Ü麄"LgnèÔgúôâ¸ïÙ_þIYÿ°Œÿú uâÖ½{á{EÕ4¹a†ê[²M•P1Œ´rpqž¿•L¼ÊGO­ü#—QÒô[8u¨âÚh%Ÿ™ç@6ñ凖ä§_˜`û »¯ü3ŸS»ñZ¦­z~¾¶ÎÑ=¶÷†hQíÀ2ŠJ‘Ϩ¯8ŸâÇŒì¢ÎÿC‹O77‰o«ÞÆaƒTHž5Pp~g.rTã¡©µŸŠþ.³m`¤ö+< x×FÉ·i)aiŸœJ¤‘Àê1Ókmg[uðŠòòÞq®Û µÕ%×]ÓO6½eE Xâ% r¹Ës[Ú€¯´ßjž*“U´šëU¡ºˆYPTBîÎWiÝ’wdp0 yü~,šôøwÄš¾®~Ãiâi4ßíXžKKK›?!Ø;Æ[f<Ü&ãžSê+_Áÿ¡á]bÎÑ<Ë‹‹9b2æd œÍy¾»ñm𿛝i ¥[]@‰:´LÓ+[ïd‡{„‘÷cŒŽkÒ­5Ë)õ84Ï5Æ£%˜½ò^&V –ãçŒg=})µÐIìÑïÃý^æ´]k1Å4pC×SIÔ¼-£ê^%ŠiEÖ«lÐÞ]~þM—S¤r\Í GsI;žÙEx>…ã_Xx:Ú+©í­.·ò¥½“Ì hÒ{Ç•ºá¾B§îe p½7Ã$Š]7A‡UÔ,nu=SÎòX,3ˆòK+(Æ6€OA“€OÀêè®#âñ¸ÿ„RÞ;_4¼Ú¥„%#¹{rê÷Q©_1~e=kŽ:·‰ü+©ZèSêšE˜Ú.m“R¼fûO™3£$²|òP£ ËŒŽ”“¸yžÑEx{|C× Íäk«éÃnßµl3¤z°³Kó d¶§ Z^5ñÅ–ž–·V×Òj÷Séö7qZ-^9ˆóX‚¾HwÆpvuäPµv=‚ŠÏ²Õ쯵BÆÖb÷Vá6°Ø]w’0N9ã5‡â«ÍY|G iºMì6qÞyæy5ˆDÉs֘βŠò ={XñÞ Óoï´åÛägJ‚å¡¿·òÝ–' „?Ì[9‡8ÅWñÄ)tß xv] V³=¦‘æu‘./)Zäî2åŽT ÝsÓ•p=žŠó=/Yš×ÄÞ1‹XñM½°HÒêÞÞåQ>Ï ?z¹nP6A< ƒ’+&ÓÇwvž ðÝö›yi©%ü2éªbo7þ&$fÜHSµÁðYi½Ïb¢¼Žø‡ûsZ³›XðݼÖQÝ'Ùo&J¢(²—,¿xFXn9ùBƒ]„fI"rŒ¬à†­yáñ£áiu-:mR- éåÅüÏz°'¦$Id ¸•–B9JJúØ,{æ?/¥ñRÙëZ…‘šÆ;†±‹Ëw±?gY$79mñá‰Á+´¼ŒÕ¿‡þ1ÒϾÝ{­[^yW÷òO™K3]H±)b7 ¤ ㌠Së`=Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¸CþFgÿ¯iÿôu½vÕÄêò3?ý{Oÿ£­é1¡Óª¡þU…ðÓþI‡?Ü—ÿF½nÍþ©þ‡ùVÃOù&>ÿr_ýõ(ý°ãÓÃõÒãùGE¶üzxcþº\(è«B:ßÙ_þIYÿ°Œÿú uÐøæãBµñ§‡§ñSÇ‘µÓÊòn‘åí?/<W=û+ÿÉ+?öŸÿA޵~'èW¾$ñ>ƒ¦i’¬WRÁpRF mÚb9àž8ãûTËq£¿Oˆö7Zîƒk¥[µö›«O5˜¾Y~EÄJÌѼLƒ„=‡QíSk¾(ðn¬º¦‡­ÞÇåÛÆòÝEp’Â¥b ¹W  q¤â²"øa5½µÅ·ˆ$ô:¼ºÌ—ÒZ+$²Ê†7S`ùxQ†ÎFk*Oú|úõÍÞ¦d[•¼S"ÚræãË1cæl#ä@ŒI­ξO‰ž‡O´½›Vòí‹ÛL ‚ÌWfUåù˜ù‡<Ö–™ã TÔïl4ûï´\Y†3”‰Ìk€¤3 — y®7^øYs¯I¦^ëzÝ–£«ÙÇ%»O{£C42BåN,p®¥r?ÄÀ‚®‡ðý´ŸÝk°j‰ Ë D-¬ìź¹!@y€b’2íùNÅ<òO!v‡«ØëÚM¶§¤\-Í…ÊïŠe#8  Ö"x½gñN­¡ZXI-Í•·"¢Nø£ô#rdŸïVÖ‡kye¤[[êz‹êw‘®$»xV#)Ï]ŠN=+šÓ¼icâu´¾¼}H]Ïq34Ò¥IU”Çåò×»ù‚‚|±ïGQô/ÚøËOÿ„[L×5¹´‚ú0E…ç1¹;Œjpîp)úŒt»XuclÒÞM¦Ú½Ì« NS?0/›,1RÎ5Íê? þe¥\êvÓÁe¶ÖââÀJ‹Œ)ØÏ´Ì q!ëòòjÃü<ß4àêQÅnúqÓÈ··hä”[§o3lØÁ* ‚¼x£¸•ô6ÿá2цœodžc 8ŽV†ÞY„o´3)(¤|£ï€ðHu,c†I·¢î$“±v '’O5:Œ–Ïâ'…¯"•íµ6, ¨¶˜;d¨WnY¿xœ('§£ ‘|_á‰õ;R.£{ƉR›gÌi4…—ÛònxH*Är€+»øQip"i/cšhIxEÕ¢Íý¶«óÆNÑç8#:Px( ¹Auo O¤,–vk+ä\K6V0NÝÆb1žÙÉ&¨FÍ¿ŠleƒV¸e¸i×_d“e¼¯!m¨Õ…ßüc 9ô­]/QµÕlc¼°”Km'Ýlx8 ƒÈ ‚#"¸ËÏßêëjͤðêÑßù?`aèü°#‘|ÓæFV0¥N3ÉÏjÑðß…ï4t[+MN´’â[¨£¶HÅÁ“%Tpˆ¥‰ùHûª;šCâ{ #þñ±pš”§ìï,¥5=À%„Q>ýÑå°¡Q“Ò²t­gÖڅâ]¨E¨][ΰ&'¸[g ûàäeL›÷üÜœzŸøv/é‘i÷73Áh.aža ”yn(u!“æU;Ïc­dXx!ô¹,[IÕ$ŒYÞOë\Ö4°·‘Ë¥…3Êö²,x+¸ûqÓßžÙªÏã Ýivš³´óXäOÉÓ§ePPŸ4/…ÚÇçé‚FzÕ£áé×ZÕ.¢¾dÔmÖ)áxw8uR¡Õ÷:§'¸¬/ü:‹XÐt-¯!1ØXö«5¸B *ùª„…YFÏ•ˆ8Éàæ€: ;ÄjÕõk)mZ8ìcŽt$‰ãpÄ0Uç?)ã¿ÍV¶ñ¦–þ·Ön ñÚO$¨¥-å—hÙI`ªJ}ÒNà1È4Û/ ]i·ÿiÓ5(5„vn³Û2ñ©ÈuÀ9^sê+Ÿá”÷z¾›¨êÖwžL·2)—Mßgffo)¤*]YÎÆ=<Ðüyž©<)4.7•Ôä0=ö®wÇúý§‡4‹{»Ë¨sÅ …Ü9Þ3ýÐ g¯6…£ßiWvÑM¥Òmtè¬âµòÔn‘O2±Æs€ q׎•‹<%gâ‹ËÔ纖‚Sä[Ï$ îë·%ãel.1Ðîæ›òó-¿‰´tg })p¶ŒH8´K(\ã¼l­ž˜5›¨xóG³Ñ-õT[ùí..¢´B–3‚ZFP™+†ÎÉÀ¬½?áìÖSZíŸ:Ö¡ºxäµ¥š;qn 6ï¸QSåÆr:à⦲ð$Öþ¼°¬i<·PÝÁä[2ZÛoÊ6°Àçg'¥3OðÞ±¤hºV•­D,MšM ZäœbH“ãå9ÏZuÎv¡lt¯8ðÇÅm3XyÙÁm‘ž+…º*LÞRÆëYdfÆÔÁfíȯA‚)#µŽfi¤T Ò°¹– `dõàb¼æßá”éç\I&°i¯–Á)p «¼™~xÐc)òîÆ ÈZÜ:e¿‹ôK‰¬¢¶º’io?Õ¤VÒ¹\6Â\ýØ Á/·öª–ž;ѧMfYšîÚ*ãìÓI=¬ª¬Çhr¿1%À 2IÆ"³O€%ó4ùS‰&ŠäÝÜÝ%©[™$i°ŽEyqœ(C‚½ry«ºƒ¦»mXG©ˆ¡»»‡Q€}Íou!V'pÞ™r˜¯Ì;,Ÿøp4 ue$™@²Ï™òþì‡!Hl`žk¨®~+Ûj"ãSwºÔc”\Ì $’+–UÜpEP¹<I9'ªÓ­5u}VâöüÏgpÑ‹KPŠºªÇ8³1$äÇ4ÆQ×Î–ÐÆ-V)ÊÀÈÞK¸:¸0äk£±ñìW·‚(­3 êƒO†ui9âBV2Ÿ3X€p~nÕr÷Ǻ•ýõä·p\Z#»µy¡Ëã÷‡æ^=j“¸.Õ5Ÿj>º´Õ/ïã¶_GÖö«#_H¦&6&Êòò‰`½x$õ×õäñä6× x4VŽtšÚáU¾Íå¨*à¬Pn–LƒÐüFУ°[Ù?´£·Éo!{ …Ð.á Û•päñÖ¯?‹ôÏíBÊ8õ 䱸x¬¤’5ýД áv’P®y'hZ êjhZ¤Ök¨Ù¬¢Úå<ÈüÔ(Å{#=k…ðü6vÞ&ñêV¤ø­®g{[™-˿ٶ $ €FÜõÎFMv~×´ÿØ=ΖÒyqHat–&‰ãa••€ àƒøÔ~5×Ã>Õu¥µû[XÛ´â3g™´g°qõÁ¤ôÔhó«›ÿXø[Ã×7þ"Ö¢’ûOûUÄé§Û»¥×’… !ùU˜¹Á² ;Ë¥ë~-¾ñ…µ•ä·¶ p‚¨cqm!µWi"͹ڢB@/,€œü¾›¶ÿ4ß6énín£X‚[xÞâR6n—z"‚6Ê“’2? Ò»ñö‡mvðy—“ˆÒ džÞÒIaD›ý[3¨*ã®x§Ô[£ƒµ»›OøY¢%Þ±«M} Ý´sÁsk¬®Ž¾dL<Œí»ïd˜ÖÈñ»7Ĩ ´{Ïìg¹X ¼ª¥#nÎ@-Ã*î niŽ[pÛÓ>±ã­JyÖing"¼¯km$ÊŠÌê eb|úcš±mâíêxá·¸y$’å-QV&;™á)}͇;ºpyàÑ~¡ÒÅýV¶×t¸ïì<ß³Hò"™¡;l©Áî0{וÇf¿ð±¯ŸM³’=|ø†9d¹XYI°‘‰ÉŒòÎ7@ÈÈöEPª€p¯9½øs¿ªéú,r]ZjöP4·žZ\¬¡78!  ˆÁûëÈÍOÚCècÞ_xÂÇÂz5ôºÝûIrVúi`‚/° YJì låC0It“¶6“‘nßZñ$^!Ò¡—S—QyìÆ-¬áHâó<§>dÁáÞT¼¤‰ƒ“oZüF¹ÔÖÐhú"K-íа¶7f7 ’Ü+‘XÄewÅŸ€ù«¿³{‡µ‰¯cŠ’£ÌŽ) ˆ­Ü*¤| ¦Öâ<"ËSñDF[èu;÷’å,“QÔn-’¶o.Ré-Ým^crÁ9ù‡S¥ê^,kû9îu[‹˜VKš8lÑ`%gY–ˆI6AA¸gµÖxçÅ¿ðŠI¢,ͽýè¶š_7gÙ£ØÌÒœƒ•P¤‘Ç=«ÃÆúÍíÆŠ°hZo—©\KéÉçF±Jé$›E¾Ò¨<²ä½pH3¯Ñ5‹]d_5—›¶ÒêK7gB¡¤†Ûž ŒŽàŽÕÄ_xjMWâýƤöºT[XÙâKý0ܾD³’!“zˆØpIà í^ŽŠa@“ǹÍqzßæÓ¼Kua™º}‹Z-åÓ\”‘áÊ HöøÀ',¼2F(ê…ºfÕï‰mü3u©Ë«êææãRžÒ(–+hc´‰nRBÆÚFÆÄPIWÈlüUŸ¤kž2»¶ŽòâîùÚÚžζh#ºw»¸ŽRå¢þ®8˜íòñœàŠëõ?ƺV§y¢XÉxtù$IMÊËm ä1È_-ƒ0e#sŽ£­jë>,Ó4mJÎËQ71=ÖÝ’ˆ¡›h àmSŸR:М ö¹âHô ù­µ{ÖÖ–íòÕícH´è øgˆˆ‰ô-æŒ|ØÇ×x[_’;- ÏY¼7ÚŽ¦Ó&Š#†HÁmÎv à7lPXŒ‘Lâ?‡äµ’à=ø #)XÊ}òùKå.Ü¿ÏÆzƒÐÕ]3âNsmm>¡ ö“Hì¬2H¶Éç4JÓ>À"ÜÈxlr\SCe‹Öêž¹³†%™æ»²B û\YÝ#r’FFFrGZ¢º.¯a¡hšn£faºšéô-.x™ÃG³ (”'»œâ½¸øú ê²ÛE§Y]C¾“Í¿0Í"ï*Rü¶?²ä8ë@¬`hºßˆ®%×Oˆµ™,’5¹[C»Û)Ã[c”Ç.ÒîÝJe¶½ªÁáŸÉgywfÊ®ôû+hâšYBÄmxY®X_,ÐñŠíçñÖ‰m>±Ô·P>•·7[i1G÷Ù8ùÀÇlõùí4ÆÓÒiÝïØ_ΆXÌ WùÆÁ´õ©tÝSKoK¤ÂºÐÔ"¦?h>I@qÎv0Éãœt *‰|Yá­gU³ŽüÙÅu}%ÍÆ¢#;'º6ö˜Qº wÌ¿( I\yìlµqüC¨Çªê7–ÚA1¶ºŽÅA–P€È2Èp±Æ<®_Kl;½3ÆhÞ3›P×5{I,­ †ÀÊ<¥»y/_aÀo³ˆ¾ëAÄäqÏì#”Òõ«ã០¢ê·ÚVšßh[ëë{üá*°1FU¢(f$GÉP3ZÚ±¯Ë㿳\^^Knn&I¬ä´D†Qh¦W»>Ëó6c#X|@ÒáÒ4ëÛôºF½·žíc¶¶šm‘B@vo2ãrçrŽIã5:ø÷C“U{žòi@«Çg#E!<ÆT.Ö!Hàzu¦3kúŮ¿£[êšx—ì—´fXʈÎ88È=Á´«Š‹â?‡Œ0ùPgf‘<ˆôùŒ‘ùh¬Û.TmaÉö«Ö>7ÐïõAais,¬ø :ÀþDŒb…Yq°¶Æ €sŠW°=ÅÂÊðÿö]ž N¢-ï=®l%Ýp¥7îEÛ–P¼’W[awý½å¤‹-µÄk,r/FV‚?L.X®'Pÿ‘™ÿëÚýo]µq:‡üŒÏÿ^ÓÿèëzLhtßêŸè•a|4ÿ’cáÏ÷%ÿѯ[³ª¡þU…ðÓþI‡?Ü—ÿF½JÄÿløôðÇýt¸þQÑGíƒÿžÿ®—Ê:*ÐŽ·öWÿ’Vì#?þƒuúîŸo¨üJð¤w’4pÅ Ôå•‚ãg–Üç·ûW!û+ÿÉ*?öŸÿAŽºYÛ_øÃC·¾7bݬï pù2?t‹Œã+‚LTËq£°Ó¾éÛD4mkS‚Ôjrjª h$S#`£lF€mPN 8‹Qøg§Ÿµ]YÍu-Þ.Zå–8•d™÷³Lü0È-¿ŒÅqm©ë‘Meem«fÿc½þ΃NÓäµK‡Y Í4I„Ò¿jà;w[VWÞ '½}IuØôù!¼[»x¬îdX •4R`‡f D§ÁÉ/Ð^¥í7á”zŽ–eñ¥q&¡p×M,–ÒE2•£$h@Î"L2¢¸®®óÂ6zV·§Ë-ЃV+çp í‰#xÇH×®yÏn+Ïí^¼ðö‚¶ â O²h7~j YmXÞ#[yJÊÈ7 ˜ã †ÇC^—£ë?oÔ/,Úå'²ŠšfLDÏ"–ا9, F8ܽsOÈ^f øjËDŠh †É<ñó}+´º¶‚òÞK{¸cž ׎E ®=<Oa-Q•á(ÒÛI[c¬ÿlNŽï-ÉpÄ—vl`…Úx j˽ð•y¬A©É-âÝC©ÿj)WP ùiŒü¿êÏ•×rƒž1\"躖‹á]-t»[Þ]Røê2iÚk¼þ_›9·>\8‘“%1€pþÖ€‡ÅÈÍwk}«]] ø ˆO C Àl—s˜Ýi9ÉÈa‚zŠ”ï¨ßc²ŸÁ–oc6÷—Ö××Òj÷q²a–Mû±¹J•+#® ž® ^·Ó'‡]µ¹—Xºš8¬šk!P%rêLÌ` Ü}xó?Íáqö¶¿=Ü·új\ 4ùíd€“í;ZBw¦ÒrWäP885д‹§üJÓm”kÓÂ4Ùm^w³¸š‘¤„¦fØTäîÇvúÑkºN•®Kj$‘éí#IõØD¼l²M’7§jÂð×€m´GÓçÒ¶¼ñÿ‡õÑ,î%XîL·Oh¬CÀsã#‘ÇéG`7ÿá³>½ÑZKƒkw%Ä®å†õi¥i[c†sŽ:œÖ>¥ðòÃR¾KËíKQ–äGo²eH΄þïå9s›r:×¥Iã ÝlÔu¹üHc‰M´údðÁß™ÉóŸ1´?x/å*í©¯ïbŠ)UG/Ì„£dr;úœ¿j³†g†H|ØÃ˜frdd«‘‘œ{‘¢=¼Úœ¯¯%û]Î$Ž5vÛ®„P ïÉ=É«ø~Âo&¹4bKÔ·ɽTª(rù\Œ†Ï|ךꞎ9îzÐ3¾ÂQíê:Ä:…ÐÔ. ’fHÕ!Aj*— ¨ÁrÇdf¶4Ko±i6–Fò[é-£Xd¸•·<Œ Ì}OSõ¯0½‹Å±A$ÐO­–¸¸Ô…ÀÃ1Š»>Qˆc†1}Ügp#ñZ¯°l$Š[fC«kÓÇln`)3# Âií`»P’HÝ€8͆oè‹¢jö¦ Ô¥–k™Û`“2H\üØèŒg<já-5·¥Þ«qq:ÙÝY»""#œÄ\•Ž5\)0qüG9ã>'ØO©øVµ´·k™Ìa–gÚÁˆ¹ã^Q¨xoWÕ¼[¨k–:eéÓ®êé­fµhP‰^Èx )ð ÛFFÒjzØ®—=Rié³[^]©…§–)ðe‹Ë'H @ ŒõÈâ°µo‡Öïc¥èñM–Q:•ì×3ä*4Š4QÆQ‡Ê±8$×_¢ëP_ßO§ÚØÝÀ–¶ðH^H|´b’# NàêÊ1‘\§Ä˜f‡Y¶¿}íÜ/¥_X/Ù-^ᄲùe„ªŒ7(=Hã.]Ä»0Ótù¼I=ìZƒ4·6Ë öjñ´s ÎÖ`An„žs\í·Ã= ü=c§[jÒÃl&Uº/²HBÅ©*ª¨€QÏ\ñv6:§„–H¼;¤ÜßjãNX®ºK¨‚eµHÐÅvT+¦õ@TÀÜF5Ò|?[¿è¯¡jD« WvÖö1Ø9ž2³*«#¬y!ÖYŽ7÷¢Â¹ÑÚx+MÓ"F†öö/"tºYÓädµK`y\cdjÞÉéÅgŸ‡šlšt:|úÞ£pm§šá_³3+\/•ò¶à™Œ©#Ò·¼§Ïªø']°´‹Î¸¸²–(ããçb„Ï©¯2¿Ó'Õ®5]z;-zÖÄÞiDyVÓÛܺÀÍ"-¾k(ó?»Éű­MÒt¤ßÚJšÑÓ¬´Ô°ŠÑÈ • ™œ÷l*ÀÇÍ×w5­ Ç]¸Òn/A•tûƒuaYš)"ù#l„Œc{Wšxž_Þx’æ8uŸ°Ê~ÌmšÖy"šÙ­IóK·îÑ·»1¼“€kcÃ7—ÞÒ/†¥±}gzÚÄëºV–E´i£‚ü¹ã&žú‹Èìî4K3{©ÞË,¨om#´˜ ©y„ÆAýëdçÓ¥q2ü:K·Ž_ ^I.±„Ã$÷1[ùQ¤rG‘²ÝÔå]܇=Af½Q´ŠþÂæÎááž6‰Õ†AVƼRÏNñ¾ì‘j:s-ÔZ]ܰYË5À³¶ŽDÑ#"FW”¡%2pÙ5pѱ™$|ÉŸ&1¸ºŒuÔVþ´±Ñ/´ÛMZþÖÊx|…Ù°0EžB±‹'##/¸ã¾y®>ËJ×ômSI±7ú•…ªÛ[ËÙ4ù®cžêId{¯4Çò¡%—™>\6G!¨)¯Zørî=VOÜ%Öˆ$|C,ò¥ßš@ETBA!€+º<h³¬øúâóOM¿éí¬w×\ ’t·”Éò– 7R2¯sÈlbºàøm­åþË¿º¶½û öPÎØ+Í}ûðåƒtäp?æâ¾¾›SÐ¥»!¶ÒÛO…-’ÖÊtì1 „ ¹=»ÀL9¨¼¨kWöÎ¥âCT™ím§šîÉôÙ’%erTÃ3-þA€#89àŠ`¿Èô» ±Ø[[4ÒÌa‰c2ÌÛð1¹rz“\Ï‚´ýJæK­GW¿¾žxÊZÊÍ 5ºù‹*˜Š ,U‘-»îûœõVSí6 ¤·–´D®ÐÎx÷ •` &¼FÒ|[§¤l²ÔÍ­„ÛÙ”óe™-ÁEA½”¦M«Ëæ•õ=n÷Á–ú„SKRÔnçšÐÙÉ;˜•Šœ"#Ó§cÖ²Sáw‡$žöæ9.ÝFo1$/™•qò0` äXs\Õ•ç‰c‡E’æMzòXïfŠ;_²\Û›˜¼åÙ,’ma ’b7 䃚ÜðªéšÒ‡‚ÙÜÝêï42ƒä¦o¤hYF>]Êųü@ƒéNÚ¡\Õ¾ðµ»&“g7‰/ šÖãíQ…[HÚwÆWÉÆ#å¯98«:fŸ¬ëSZë×RêŽé$Ž%ÌGh ¨bº¥±Éîs\Å=.Kïu{uq£Ikeq›H°Ü©2ˆ±Ën%x¸©àxít)õ8õ.çþ纹ŸR6.ËŽºÕ÷†ô«k&ñ—Ù¢ÔÌ£ì²ÚÈï¼›rÛÐ$Œu9Ï9c@Ô|@Þ9Ò“W›ZŠâæ]òÀвYù?cCÆFÝþnü€wœ€0in7¡Ù]xO›HЬ¢¹»…ôXVÞÖä,2I° BHŒ„•ü½zbµ-4‰à×Rùµ+‡µŽÅ-ÏSxbZSŒÄõâ_jé¯hÖúœ÷6ðϸƗʆ*Ÿ•€Ü=AÚµ)€W¨ÈÌÿõí?þŽ·®Ú¸CþFgÿ¯iÿôu½&4:oõOô?ʰ¾É1ðçû’ÿè×­Ù¿Õ?Ðÿ*Âøiÿ$ÇßîKÿ£^¥â¶üzxcþº\(è£öÁÿO ×KåhG[û+ÿÉ*?öŸÿAŽºŸëÖžñ¶‰¬êK3ZYØÞÉ …w1'NÙíΩ&¹oÙ_þIQÿ°Œÿú uÙk–ÑÝüBÐ šêkHžÆø4ðÈ#hÆÔËdð09ô©{|@ÓšmH4=VïSÕ"•á‚Ú8e–(ÀiÖBžY;qµÎr03Y<' ö«h‹q-€˜âÌæ"„]û‡^ „ ƒ´š½ià [ÇNÔ®m5q=ݼ–·Â;‰ã•”ÌH\Œ¶Ìà8Æ(_xf÷R×t(5 SËeZJ\¸·‡Ïf;ÕqŒ³#œd€rp2*´'RާñÇÂú]¬RjjV×yàšÖU…%·0•\?yHT,Çœƒ;¯Š66¶öú½wc£®ë»Ø!‹ÊQä‰A¤ ~B8 ‘‘œdfÔß ´o¶½í•Ω§ß½Ä÷sgtc‘¼ížbƒòv# ŽkF -ž™âК4¾ÕØË#Þ––?3ËXòFA#j3ɤöµ,5(ãKÓõkûQ©Ç¦ ímĈŀ&l†ÿR»°ÎqŒ+_Õ­t-ûUÔ–ÒΞB‹¹°£8¹ôÏøsÀ–:'„4  «ÈâÒeŽàIm+Bg‘I'~:£3Tä+Ä:d:Î…¨i·1¤°ÝÀð²9 ÊGQÈúŽiËÈkÌäµ?‰Ún•¦ÜÞjºuý‰µ¸û<ðÝMi£yaø-8WùHÀBǶ8«×^>ÓíæÔ²Ôe±°´Žöæõ#AFèΤ`ìp‡…RrG­fißmáµ™µ­Zíõ;Ù$]E8G‘dEFŒ6:€ðñÆ1]^Ò’ÎþÐÂò[ßZÇg2;œ4H…{pO"“ØHå.>*Ûi—:„zöq§ÉÊA¤ÒÛÇ9+33J"àÎsÓ®EkÚüCÒîg*ÏQ6Ö5¼ò—Ëgkd¹U »ÌÉG_áÆr=(oiv×|ë:Œ:Íäþr]›¤•Œ! í#bŒ€½³×šÒO éé3ÌèÜ=ÚßL¹c(` Ïû¿ŽM6³á=~èé©[[Moo!ýØ–H\ºàÀÄî1Î0H<ZÒù†&òЉ1ò–÷¾‹áÛM*Ksâ3êÚŠ4—†ö8¦»ž6U1M ·îöîsÍv×7VöÆq'е £Ù´–’xÓi24¬»G9ÆÑ÷±¼ª{Rê6t”V^™¥-Ž¥ª_}ªæg¿‘¤’‘P¡QzrI’yéZ”À(¢Š(¢Š(¢£’Xâd:©vÚ»Ž7Aêp(J(¢€ (¢€ (¢€ (¢€)2Áµ1¨µ©Ôybè¾h_îïÆqíš»HH$€?•T‘Ò†¤/-ŽœaûGÚ¼Õò¼­»·ïÎÝ»yÎqйE5X2‚¤zi³K1—–EDYŽühJ(¢€ *6–5™biHà•BÃ$ gÛ#ó%TêxÖ¢xÊ ”üoIŠõÁ Œûž€ *”º„Z”:t·Ö©¨NŒñ[4ª%‘GVTÎHÈ«´QETv°^ZËmw sÛÊ»dŠU ®b{TôP#EŽ5DP¨ ª0ôú( ©E¥ØC¨Í¨CeküÊK•‰D®£ g$tàÕÚ(¢Š(®'Pÿ‘™ÿëÚýo]µq:‡üŒÏÿ^ÓÿèëzLhtßêŸè•a|4ÿ’cáÏ÷%ÿѯ[³ª¡þU…ðÓþI‡?Ü—ÿF½JÄÿløôðÇýt¸þQÑGíƒÿžÿ®—Ê:*ÐŽ·öWÿ’Vì#?þƒoüAÑ›Ä#±Òã4×:N¥J“4[œÆ¡A*FW'guqX²¿ü’£ÿaÿôë£ñ¿ˆcð·4^kY®Ò K¿ÜÂ@w-娞;úԽƌ+Ÿø•ô}mN×´ëý3B–ÝCjdJ·{­ÆÀÞiÌD+™Ùòôçˆl¼_swã›]Oñ4ê@¶6£òÇ:<3ÄLÄÄ­¹ ÀÆjÜ|g³†è:“Íhnާ}å믔å#Äq •Œ†ÃlGäœàÕO‹×ú¢x~}ÃsÉÞ°úMâ\LŠÑºÆ_je†I_˜˜H­Í'â„:—‹-thtKõŽî[¸-ïãÙ+Û.ewg¾POSíši6„ΣÀÐOmá-6+Èu.3¾=Fä\Ü“÷ä†>õÆE§x üBšðE}Ÿ#\¤näxZ?+÷Læ*­¸¹Ï>¾…¡ÞÜj:M½Ýå„útò®ZÖvRñû¤Ö¸ýKâ‡k¨O&¹.œ4û”¶†Ù%ûd‡äfbG– 嘒yÆG­sÚljï[¶¶ÓÌqC© …ОæQ"oÊ0q·àÖ¦•¨ßÉã-kM»šÞK8a‚{qï3o;þæs…êG=hîa|OÒ.µ GÃ÷Xê—ZµÁ”i·fÚT- w«£cv:®k/L±ñu½í­¾¬º•ÖÛÈ.§¹†ä,m°Ž9Àó:9Û€2Á»×©‚#–½O0±´Ödø~-dÓ5aug©}¥a»œK4° ³*€í#"=¼3gŒT:–‰¬^xÞÓPžÓV™SUK¨Ûíx¶†Ïì¥vy[öù‚]Ü…Ýógv8¯U¢šÑÜMQ¦iZÝþŸ¤XÍk¯ÙÚE¬\Ëp&ÔdYZÕ ¸1*Êd 9‹Ù†F¯öÍ·‹<7aªÞêÏ­µÕ±hãÕ mV&޲²aŽW%Šœäe»WºÒдw hy§„¥Öü3á^{/WÔ¤‰£û*ÜÜÉ%Õãœ)ʼ’,|‘’¤/S…½,ô¢Šytº°ðŠílmï ÍÕô“A×ÒNeŒ:°#Ìr$‚{Ô~)Ò¼E­ø…å³åœwpZ­¤‘^´ÙÏö64p •+ƒ†í‚Íz­­{Ðñ;­+â«mo&¦÷v±Úąಹey‘¤Ed%%RÒ*ÂÍ»zœO…9=6“áÍJãPðêj:ëi¶Ú}לÒ_IùÆxL"M’–bH,ܘä×£Q@ZÇ›øXk:ñ5ÝÕŽ±n‘ùð½ÕÄ=Ĥ&4ˆÈè£@(—Šô9%šÒ '… •ÑYâ, Œ‘’¹t©è¦™OáGK_ÞijKq6¯ivªºŒ®g%æ ¯!PJ¬‹—#åéŠË›@ñ]ÐÔ¯ó­Ãt¾dÖ0ÿiº…o´îPȲl#`û­•ÇËí^ÃE% ¬y©¦k:FŸªjWz•ýЍÔ. ÅÖ§'’¬·…íirJmRr­´öÔøVïU²Ò´‰/ìu ›ýråî®U¤bºr8.îáB(Hð1–ã$×mE A³›ñîŸy©èÛOk¥•ç‹qµ¸kwØnùÕ•€Æzó|5ã xsÌZ„ÕäÝËAi‰$c.Z1"Üü§r‚OÊAîTQ`<†óÃ^*K{‰mnµv¾º¸?ÚRlå÷[˜Ô¾#û .Фƒ€j½÷‡üQ¬ëWw²¦¿mi%Ú<0®­$b2Â+ å‰xíÉó^ÍE ]Ü6V<6ßÃþ6:f¨nï5æ×LQ¢¸+ »[m3mW‚cVÜ9b 's^ð•ä’DòÛë7–vÒÜAj³™|†‡k2±”1!Û ànƒŠõj)õ¸ŽL±Õmþ$]\ˆµ9ôÙî–êêEŠ‘6¬q‰Ln $ `I99®£ÃZ”ú¾‰m}u§ÜiÒϹ…µÇúÅ]Çi`:¸8<ŒàóZ”P Xñ­kÂÞ,¸Ö5K› õˆÚy®<¦´«« ˆüͪ6–Æc¯Sjú‰u }JçìÚüJÓÚ›[E¼tó6Û²¸cÊѦó’Cr@$0¯_¢Ž–[žI>…â«ÞËsq«@ò(6¿e¸smgU113Ï™æþY~A é¨h^/Õå‘Ìzý´)m " Uá-*@À·É/w=Ï=M{e<»ÃúN¿eâÝ&[ˆõ{˜UZ)ÍÕü¦xÂȆ%++ >b3sùwÚ¡>§g$÷Ø•žHÒ9ðÑ[ñØdÚ´è 6Öt¯KãÑqnu3¹¶hfK¶‘Û(ýú<;¶³°È¡<©b¸ë]:ÿà ï¢ÕåÔôhàÐa·Ž+­Uþ¢‘ ÊJ®B¨E![¦ÞµïTR°=]Ï2Õ4Íñ ·ºÕ“MÛlm¾Êìbˆ®ï9e_9TîÈÉd~>î g·…¯õjš~§g¯\k…QîdŸT—ɺ•_q0(‡’*ã]¢˜’±æ÷šv¦zä“—€à’Ÿ˜žO±iš„Óêú–žtû˜­lVŽîS•¸fRX.y;FÜžå±Ô×¢î$‚Š( aEPEPEP^_ã6ÏUÖRÛPŽimü¹˜¤wSA’dÄêHpN3ƒØW¨W «Gž&cp -çc‡Ûÿ- Ï=3IŒá¿áð×ý®¿ðoÿÇë¿Óì­´ßi–vˆ-aB±ÆŸh<õbXœœä’IÎkÇWðΣ9·Óu KˬÞM¾¡¹ 2~P Ç­Xðv§>±à}P»XÖiÄ…–1€‘”c¾pOsÏÑàß¶üzxcþº\(è£öÁÿO ×KåHG[û+ÿÉ*?öŸÿAŽ» wI²×>#xjÃS‡Ï´–Öìºo)œydr¤Íqÿ²¿ü’£ÿaÿôëÖÖö;Ã-u2G+ f[ïOLŒê8©{Œ}ïÃOÞɾëHYÜÍvÙžPIœ<›†ì23(;WŽ”ûχ>½¹Ô§ŸKËj$µÊ-Ì«±Ú ‚0ÁVO•~u¸ÎjOµIÿLÿïGÚ¤ÿ¦÷À§Ì+¯Ã¯ ®œlVÊäEöó©ù¿o¸ó¾ÔWi”K¿ÌÜG{Ö±4Ÿ…–v_æñ;Ý)LOäÙȦP®ÌZF°:¢¡$ääÖÿÚ¤ÿ¦÷À£íRÓ?ûàQÍm‚ÆÖƒ¤XèE¶—¥B`±¶]‘FdgÚ2OÞbIêzš¥uá-ée[›‘fy¤‘ZGÃ4ÉåÉ‘œa“Œt¹ª_j“þ™ÿßµIÿLÿïJèd«à­ tùì„F9¦K‡ßNgóT®&/æ@ÈjÒþıþÙUT™o’#zÜH Î®í®FN FN+#íRÓ?ûàQö©?éŸýð)ÜV5ü3¢ZøwD·Òì o fÝ+nwwrîì{’ÌÄð<Z•Ê}ªOúgÿ| >Õ'ý3ÿ¾+¡Øêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸Xêè®SíRÓ?ûàQö©?éŸýð(¸]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]Ê}ªOúgÿ| >Õ'ý3ÿ¾ ]yÏ‹5{MX7z”@ñË1ÂÒ–s$-Œ(=•ÐÛûTŸôÏþø佞2|¶UÏ]¨¢†ÀòÍQð‡õ WPÑtë›[ýK™å|ÜêŸ'Ȥò@ê}€®øw ¶ÿ ¼;ñ¼Rä;$R¤#yèsÓ½uÚWŸóØþCü* ç’r<Ö?t äž:ð+óíƒÿžÿ®—Ê:(ý°ãÓÃõÒãùGEZÕþ˱¬¿ ¤ŽL”{ùÔàã‚©Ür+×M½®ãÎ×þý×’~ÊÿòJý„gÿÐc¯_©c#û=¯üùÚÿߺ>Ïkÿ>v¿÷ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RQ@ýž×þ|íïÝgµÿŸ;_û÷RU«»‰RæeY0ªÄ´t€(ýž×þ|íïÝgµÿŸ;_û÷VòWPÉ0e=À—íSÿÏCÿ|­Vû=¯üùÚÿߺ>Ïkÿ>v¿÷îŸ&¬‘^[ÚKy]\0ÂÅ˰ÅTò@gƒÇ&¦ûTÿóÐÿß+@¾Ïkÿ>v¿÷î³Úÿϯýû®oÀÍqoâI.%’WõÊ‚äœ(H@QØ v^õØG#ÇhLgi2c¦r1@þÏkÿ>v¿÷î³Úÿϯýû©[Pd#Ü¢¹è§h?€©~Õ?üôÿÇV€*ýž×þ|íïÝgµÿŸ;_û÷V~Õ?üô?÷ÊÑö©ÿç¡ÿ¾V€+}ž×þ|íïÝ `r,í³ÿ\é÷:ªÚ½²\ÞE ÜJ!…d* ’«êØ“\Ö›s<ÿüB“Lî‘éV{Ÿ•s,Ù éž3Ú€¹ã¶·ðÓ·%¥¹cÇr#¢›û`ÿǧ†?ë¥ÇòŽŠ´[û+ÿÉ*?öŸÿA޽~¼ƒöWÿ’Tì#?þƒzýK¢Š)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW9ñ[RŸOðýüvË.¡}0±µŠ,oy$m  2'Û­tu_S¼Ó¤æâkžÞbÑ™Y Dã##<«`‘‘‚(ÕõMsWH/n&  Ú5ž¢6í7…ö†„w¡á]F]@E¢ B\»ò¡óœ®0Kãq#äv¢û ǜ麞·a xcX­ö£{©Iy ¶Óí10Xçhö¨ IÎNy©µ NçNø{mªi¾(ŸP½ÔVÓí3Ï^•ÔhÿòSüKÿ`«/ý5hد‡4øc‡OƒC´†9<èã·†ÕoP£†ÁÆx8â²ô£ŸâW‰ D:U–p8–nãŠméa(»ÜòÛþ=<1ÿ].?”tQû`ÿǧ†?ë¥ÇòŽŠ¤3­ý•ÿä•ûÏÿ Ç^¿^Cû+~Ωÿ¹cᎽ‡bÏÌ÷ÝKZ ¢Ÿ±?çæûî‰ÿ?0ßtµ”Sö'üüÁÿ}ѱ?çæûî@eý‰ÿ?0ßtlOùùƒþû£PE?bÏÌ÷Ýþ~`ÿ¾èÔQOØŸóóý÷FÄÿŸ˜?ïº5”Sö'üüÁÿ}ѱ?çæûî@eý‰ÿ?0ßtlOùùƒþû£PE?bÏÌ÷Ýþ~`ÿ¾èÔQOØŸóóý÷FÄÿŸ˜?ïº5”Sö'üüÁÿ}ѱ?çæûî@eý‰ÿ?0ßtlOùùƒþû£PE?bÏÌ÷Ýþ~`ÿ¾èÔQOØŸóóý÷FÄÿŸ˜?ïº5”Sö'üüÁÿ}ѱ?çæûî@eý‰ÿ?0ßtlOùùƒþû£PE?bÏÌ÷Ýþ~`ÿ¾èÔQOØŸóóý÷FÄÿŸ˜?ïº5”Sö'üüÁÿ}ѱ?çæûî@eý‰ÿ?0ßtlOùùƒþû£PE?bÏÌ÷Ýþ~`ÿ¾èÔQOØŸóóý÷FÄÿŸ˜?ïº5”Sö'üüÁÿ}ѱ?çæûî@eý‰ÿ?0ßtlOùùƒþû£PE?bÏÌ÷Ýþ~`ÿ¾èÔQOØŸóóý÷FÄÿŸ˜?ïº5”Sö'üüÁÿ}ѱ?çæûî@e`ÿÂá?úü5ÿ‚›þ"º‰ÿ?0ßtlOùùƒþû§¨÷ü!žÿ¡OÃø)·ÿâ(ÿ„3Âô)økÿ6ÿüEt;þ~`ÿ¾èØŸóóý÷KPÐç¿á ðŸý ~ÿÁM¿ÿGü!žÿ¡OÃ_ø)·ÿâ+¡ØŸóóý÷FÄÿŸ˜?ïº5 z}ž›h-tË+KU%„,1‚q“µ@éÛ?•WÕ4-V’95}KÔ^0UòÎ9ʃØR@öéZ›þ~`ÿ¾èØŸóóý÷OP9ïøC<'ÿBŸ†¿ðSoÿÄQÿg„ÿèSð×þ mÿøŠèv'üüÁÿ}ѱ?çæûî–¡¡ÏÂá?úü5ÿ‚›þ"øC<'ÿBŸ†¿ðSoÿÄWC±?çæûî‰ÿ?0ßtj÷ü!žÿ¡OÃ_ø)·ÿâ+CJÑ´­ÎþÇÒtÝ;ÎÇ™ö+Hàߌà6À3ŒŸÌúÖŽÄÿŸ˜?ïº6'üüÁÿ}Ѩ8~Ø?ñéáúéqü£¢—öÂ[xd+«÷©Èéhžõø’ÏW¹·¶ÜÆä*†'gyýöü袘ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPæ?÷Ûó£Ìï·çEyýöüèóûíùÑEcÿ}¿:<Çþû~tQ@˜ÿßoÎ1ÿ¾ßPŸ‡ ŽûÄZU­Ð2A5ÔqÈ¥ˆÊ–ŒŽGQE ?ÿÙfotoxx-12.01.2/doc/images/navigation.jpeg0000644000175000017500000021110411701011016016647 0ustar micomicoÿØÿàJFIFÿávExifMM*JR(2Z2010:05:07 05:18:46ÿí:Photoshop 3.08BIMresize trim sharp ÿá ýhttp://ns.adobe.com/xap/1.0/ 8 516 622 1 2 2 ÿÛC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;ÿÛC  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ÿÀn"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?õ;û¶„ȨÅqï…€9Æã'içž9¬¼a¦[Ï$3k-‘»FêÓÛ‚¬:öëÁ­Mc{Iv‰Ë=º??úÕÁ^ø"KÍZâîK„h&äò‘\1RÄ…$®;ý(Ð`žYà‹»•‘‚"ãú-I¾oùþ¸ü£ÿâ*±x DvRéQÆI'Ûš“Î?Þö¤2Öù¿çúãòÿˆ£|ßóýqùGÿÄUo8ÿz8ÿz€,ï›þ®?(ÿøŠ7Íÿ?×”üEUóº|Ô¾qþõYß7üÿ\~Qÿño›þ®?(ÿøŠ­çï{QçïPóÏõÇåÿFù¿çúãòÿˆªÞqþõ'œ}hÖù¿çúãòÿˆ£|ßóýqùGÿÄUo8ÿz8ÿz€,ï›þ®?(ÿøŠ7Íÿ?×”üEVó÷¨ó÷¨Îù¿çúãòÿˆ£|ßóýqùGÿÄUo8ÿz8ÿz€,ï›þ®?(ÿøŠ7Íÿ?×”üEVó÷¨ó÷¨Îù¿çúãòÿˆ£|ßóýqùGÿÄUo8ÿz8ÿz€,ï›þ®?(ÿøŠ7Íÿ?×”üEVó÷¨ó÷¨Îù¿çúãòÿˆ£|ßóýqùGÿÄUo8ÿz8ÿz€,ï›þ®?(ÿøŠ7Íÿ?×”üEVó÷¨ó÷¨Îù¿çúãòÿˆ£|ßóýqùGÿÄUo8ÿz8ÿz€,ï›þ®?(ÿøŠ7Íÿ?×”üEVó÷¨ó÷¨Îù¿çúãòÿˆ£|ßóýqùGÿÄUo8ÿz8ÿz€±g|ßóýqùGÿÄQ¾oùþ¸ü£ÿâ*·œ½Gœ½@wÍÿ?×”üEæÿŸëÊ?þ"«yÇûÔyÇûÔg|ßóýqùGÿÄQ¾oùþ¸ü£ÿâ*·œ½Gœ½@wÍÿ?×”üEæÿŸëÊ?þ"«yÇûÔyÇûÔg|ßóýqùGÿÄQ¾oùþ¸ü£ÿâ*·œ½Gœ½@wÍÿ?×”üE.ù¿çúãòÿˆª¾qþõ5§`¤òzбݬ·[Ç©ÌÒÆ¡WË8ŒýμTÛ¦Ïü~Üçéÿ\Áѧy–çÍE”,M˰*á˱ãŒüØäéM—D»vŸQ)9a#åó l0è0:c8ö §tßóýsùGÿÄTSÞ¥¦ß´êÏþÌxWwÓ)\êh·ùÞMЋÌI“rÈÄ…b6Ž{Óµ'öUúéæÍd·häre#}ÒUHN3ÜcµtÂWgd„å”Tyyô?r’I^7E’úç26Õcäã8?'·ë\íÞ•=î\²DÇÌ|Æ¡PŒzuÏ^½èM&ê5XÒì"¬â@UÛ<ÆUN»¹ëÇŠéwMÇúuÇåÿQœN-Σ?šÃ;qã¨ÏÉÆpk›}í¬â„=¸d yÒa˜¨LõÝÆpr9ëOŸL¼¸‰¿~¢FIP³’ e+{Œàr2{ñ@>é¿çöçòÿˆ¤Ý7?é·?”~ŸîzW55½À–)a›»´Æ1ÓïsïU$Ó/mm²î³5\ØT¬ €AɸÏ\h±Ý7üÿ\~QÿñÇ™¢Mòj3"g˜ÆïS\´Më žä§• a—Ì!£Á9ÀÁ޼~*{M:îÚM®ñœ%!½n³jÎ'="/óøl¬&Êk‘æx²ÑGXº€®NG$ç>• Η<ú¿ÛxnV >ú`€¸Á<ýÀ  èî–c T•ü£¶M­Ø}ÉÁªÑêÖò*²ê—X… Q@bÍ´cäõã5›§i²ÙEy “Ç4wÚ‘üIaïíœõ5VßCš‰RXP ·,¶ #ä·OOÇ× ¡Ôî˜u½¸ü£ÿâ(Ý7éלtÿˆ®Q4+ņd{ í!<€Ä1Áa°ŽG9ïÆ1·hd‚Î(d`dHÕ (àñÛÐ~´ Ðß7üÿ\~Qÿño›þ®?(ÿøŠ­çïQçïPóÏõÇåÿFù¿çúãòÿˆªÞqþõqþõYß7üÿ\~Qÿño›þ®?(ÿøŠ­çïQçïPóÏõÇåÿFù¿çúãòÿˆªÞqþõqþõYß7üÿ\~Qÿño›þ®?(ÿøŠ­çïQçïPóÏõÇåÿFù¿çúãòÿˆªÞqþõqþõ[šfÕ%E€E7¨8æO_¥;ìvóéoÿ~ÇøR¿ü…%ÿ®Qÿ9*LÕ-ÄÎiü_àµ'}åÁêaàã·N•,%ðÈÝÖ®½ -¹Æ;äãÏZá­4{ëË}&ÇÍÓ‚¬a¢Äº6$±Ï<)ì=zqSK£][ÛêÉi@<;X,¥¢SÂôèxÈ8êxâº'J1[™F¢{îzy²´þ<íÿïУìvŸóéoÿ~ÇøT­÷ÏÔÒgÞ¹MLSTðöŒë mmÝÁe <ÔàUDñ?„¤‰¥IíYï0¶$/×qX¾:Œ>¥Öç-h€P®[‡È=Àî:V§§42Ì ‡PeUZhGË“ÈaŽøp>µ× 1qNûœÓ¯ÈÚ=L¸Ñ5ˆ{µž4càŽ ägŠ»ö;?ùô·ÿ¿cü+—ð fMIHp~Ôω³å¯Uòz×Y‘XT,šFð—2L‹ìv`Ç¥¿ýúáUî“l¡¦ŠÕã”\cߎ½[•±4n>VR§žØé\T1¬–ȳ†&2èv²2ðJžÝøÁÝë2›;%´²u ¶¶ìD`æ—ìvóéoÿ~ÇøW¥k¯c©Á¦Å:ÝBî&FX©Ç÷H är=vÿ÷ì…c³ÿŸ;ûö?Â¹Í â$ñ ÛAªMyÚî_6ïÍùƒ àôõì+§Ï½Gö;?ùô·ÿ¿cü)>Çgøô·õÿV?¥ϽeëÚ¤ÚVžÒÁk,òœí 2§rÏ´p;Ÿ^ÝÈi]ØMÙ\ÐûŸüú[ÿß¡þŸc³éöKûô?¼çÃþ#Ô­5‰Ž{ô·Mj]ýÜßÔtÇéJÛ0 €Ù½;UΛƒ³&3RWC>Çiÿ>–ÿ÷ì…c´ÿŸKûö?¤Ͻ÷¬Ë"û˜ÿ—Kûö?£x´Ø›lÚ!ë†U`œGõ#!û5€pŸf¶ÜFBùkœR›;1ÿ.–ÿ÷ì…szåàÓüUç’ó´V.Á#cÉïÛòk—_ê1êrjdFVCGFdEÎp 0èTsÔ÷öÚ4œ•Ñ›ª¢ìÏMû§üùÛÿß¡þ}ŽÏþ}-ÿïØÿ Ïðî¥6­¢Ayq³Ì”¸"0B¬GBIíêkS>õ“Vvf‰Ý\ìvóéoÿ~ÇøQö;Oùô·ÿ¿cü*LûÑŸz@Eö;?ùô·ÿ¿Cü(vg¥¥¿ýúáYÞ"ÖdÑ4ÖºŽ3– §*“Ý\{u$㎵ÂYxÃP³šâD’)¤¹`eiã.xÈìÀÛkR’º3•Efzgجóÿvÿ÷ì…/ØìÿçÎßþýð¨´Û‡»ÓmndÌžÝö • ù~ug"²jÌÑ;«‘ýŽÓþ}-ÿïØÿ >Çiÿ>–ÿ÷ì…IŸz3ï@}ŽÏþ|íÿïÐÿ >Çgœ}’ß?õÌ…cx³\¹Ðìmç¶’q2¡a‚¤ðÐWÍ…|(“ƒÁþœÖÑ¥)+£9TIØô¯±Yä±ÛñÿL‡øR}ŽÏþ|íÿïØÿ X$ó ŽA&å ±×k( pGb=I‘XµfhÈþÇgÿ>vÿ÷ì…c³ÿŸ;ûö?¤Ͻ÷ ¾Çgÿ>–ÿ÷è… kdªY­m”’Lc\g‰¼[cªÝ鱋qЀ¼LÎA@O;ÀêÞgéÞ#žçB¿Ò¦I."û»$ÆLjðÙì}y#¿¨ÙQ“1“¨“±èbÒÈ€E¥¹¡ŽJ_±ÙÿÏ¿ýûáU´_ùéã°´‹Ð|ƒð«¹¬š³4Nêä_c³ÿŸ;ûö?±ÙÿÏ¿ýúáRçÞ¹KÛûýU¸nÄâlÈ«# ’qü$tÇN¡ éþÇiÿ>vÿ÷ì…c³ÿŸ;ûö?³<>·O73]4ÿh;×sîÚ\úöxÆp1ÍkçÞ€#ûŸüùÛÿß±þ}ŽÏþ|íÿïØÿ “>ôgÞ€"ûŸüùÛÿß±þ¿c³ÿŸ;ûö?¤Ͻ÷ þÇgÿ>vÿ÷ì…'ØìÿçÎßþýð©sïF}è?±ÙÿÏ¿ýûáGØìÿçÎßþýð©3ïF}è?±ÙÿÏ¿ýûáIö;?ùó·ÿ¿cü*\ûÑŸzìvŸóéoÿ~ÇøQö;Oùô·ÿ¿cü*LûÑŸzìvŸóéoÿ~ÇøQö;Oùô·ÿ¿cü*LûÑŸzìvŸóéoÿ~ÇøQö;Oùô·ÿ¿cü*LûÑŸzìvŸóéoÿ~ÇøQö;Oùô·ÿ¿cü*LûÑŸzìvŸóéoÿ~ÇøQö;Oùô·ÿ¿cü*LûÑŸzìvŸóéoÿ~ÇøQö;Oùô·ÿ¿cü*LûÑŸzŠSJoh¢þrQæ Á?ˆŒž´“ÿÈBúãózçŸÁ‘-n»|ÆhʇÝü'iÈè{Ð#…µRÖ!£ËlbfH}ä& |à·8sùTöÞºM>âÞ}2k«–'ʹu€A$Ÿ\Žsë[W—­•æ$’x|Û°-’X5ÇϼH(W߃Ÿ›&¢[­vi¯-íç¹{ˆ‘uÊ0φòÈé”®x÷­]Y4“2$®ÎáŸ.Øõ?çõ¤ÝÏݬ--Me’MFâwQ,Jà(Î[$޹hëïÁ'µ¡rÚ\‹fò¤Û“$ÜHÜ21î8&²fÈç|m¢jzž¥ ö)3¨„)`†;³†Éºu¬ùôe^]–Z‘·rŒÁæ]Í´Œ¸õüy­¤¶×î$ó%¸¼¶ø1¬ˆv/ÙÇC·¯š1ž§žÕ^þ/Þ»FÖÓyRÛ…• RŒÞZœØïÊã'¹<[F­•ŒeI7sS¶·ÑßÉ4³Üî‰gui6ª*œ‘ÇU?‡¿»Œâ¸¡mâH EnÒÃW0*(e$™Ðò¤Ü8Áë-chmbå’W ¼‡.ÇÜÿú«9>gsH«YwûV6«£¼Î÷zyHîrKÆÄ„”÷9âïßR{IüO,VÍrÉ·;Fß(!ÜdÜO9 s×ïU´Ôñ÷qý©®`ƒÌCÈ Ï–r¥° Âó“ÈãŠÆõÐç´ÍÅpxÒ+Ëm5 µ3y’KvAP¤rªç<ž}y¯NÞ3Àâ¸ë(Y±@F2²2äc?ÜéÇBH÷­-gíf·Ÿåù£ÏØóm9Ûœ½·=ð0+ÎoÍ=Â,“µäGk—(!RmÔã rÞaSèyþ(µÆjiF£k¨ý¦öX@G,I>¹\v÷ë[ûý«Ž´Ä÷’ Y‚†2Å$˜d9sŽAã¬Ï¿loÏðÔ±5Ý”ÖÈʾllƒpÈ\O¹s.¹vui%á"K„Á6.çÙõÏçµIqoâí;¨àº˜Bª~ÌÌ•ÔG• qÃyO\cð"í¨5}Ãþ¹Ñua-äRM¡Hÿ<Šê÷ñXEuYô5bÓ[Þ\\#²&ÐðÆe\¨=8@sœäÖuÈñ$R\Ikö™žìB¾\ª|µC×,$÷$㊹IÉêDb£±×oö¤ßíÍcx~=V']Zf•ãG6˜ª?ÖqÓ9#ìöÍI«Å{;[Çg4Ñ&é ­QŸ‘¶çŽ›ÈÀöô¨e£[vkYð;µyÄ¿»t HSƒ"Ž_Ǩ¬öÿ„‘®¥yZåA„XUHÏ”8Éà7™¸äçÓ§5kG·ÕUŠçT7 )¶häd#ÈÞº¡H ®{qÖª2qwD´š³: t°ª*$k´* *ŽÀ˜Ëš“xô®^î-iRI[æßs1ÛBʘo,(#nÇ''¹¨íÓÅ?Ú°¥Ë“mæ¬rºíÚT#0ü 4µnìv²²:Íþß­1'ŽLùn®AÁÚÙÁ¤c¸Î2$p:ä´½#S²‚ÚÝZâØ[ùì¥7õ›Æ}9Lõ>œäÒCv{ ‰f.®ß0®ÖÛŒŽ™ÛïXò[ëp^ÍöUK†’ .¹2çœÏL±I ÜÑô¯ì˜åŒ\<«#n¸Ç§Nþ¤céZ[ý«Œ#ÄÆ4E{¥]Çœ@Þïµv±NÊìŽA<Ž+® Ï$àœ f0%Ü»FãýÚp£p  7îѸÿv£Ü(Ü(MÇû´n?ݨ÷ 7 “qþí÷j=€$Ü»FãýÚp£p  7îѸÿv£Ü(Ü(MÇû´n?ݨ÷ 7 “qþí÷j=€$Ü»FãýÚp£p  7îѸÿv£Ü(Ü(MÇû´n?ݨ÷ 7 [Œý¾|.O“LzÉL&Oùäï¡RÍÿ!ÿëŒÍëŸVÔ£Ön¡‰ãËݲÕW¢„FY3×ï³ÿtãMm‘e6ÀÈœ+|»— À=}=8ëBF>]°L¶âShÜØÁëpyâ¬ÜøšX>׺8?ѧ±óCeNîž®v”a†zt  ÜÉÿ<›þúfCÝ7ýô+~ðjie%²óJžcȱ–W\(<¹  œg9w9©4næöò{¨!…§µYÂE&ò¹PH=×àgÒ…Ü/Ð×̇¤Mÿ} PdÿžMÿ} ÅÑu¶½¼žÒàHn ’ERbF}CcS’0OTÓÄúœ:u«\ÙBóÈ‘³ÊÒˆãù£É} 19ä*é@`I‘“þÏáýis'üòoûèVü$wP]­´°ÆÅî|¥ å^EiÞ< Ç;UFzu¶þ#žçC–òH¡·”cdk2»g ¬£±•ÔÝÌ<£ÿ} LÈå“sÓæΟÜet´…ÂÊœM„‡æuÖÀ'qê3rÓ]žãZ[ -áBêX¨”´ƒ£Æ0T—Û»<ãë´@ÍlÉÿXŠŽ¼Ç­“ò›Ž~ð¬KWɧŠúÁs,оL¡ž›ya‘…#`䊎×S»û&°Zä\Oh®é,n¯¿j C £*IÆG<‘FÀÂdýÓßB“2 ~é¿ï¡\ìZõôlËjWV€Fg˜FÌÈ»V# 8°sS[ø’y ™x-ÂÜÊÉû«…•›x ­œòs×Éêp¹™?ç“ßB”?ç“ßB¹tñUøV”Û[H$d÷Ácˆ˜Ëgl|ùùO\~•³gª]Ü^É ¶È‹‰Œl¬r|¹ÙõÉ#Ó4{2Ï&ÿ¾….dÿžGþúÌA¯]5.n/Ò0.-UÙÕr¾tX?ÜÉéóùÅ_ÔüCö-@D”v)’i6Ç&L’@ÏðtøÏJ,œÉÿ<[þúfOùâß÷Щ¨ s'üñoûèRÃ$BFzò9ÇJ›9éEWxÄ  -ƒí9žp~aè}úŠwïQǶÞÔÛùeƒO¸šÝ“E4kŽ `1õíé\ëkzšÛÂÖí%Üm âÂI1^8—u'lõɣȑ·‘óBN{sÞÞãˆÛŸö…cßj¹ÖVÖÏT„?”í$R0 Ÿ¼NáÈÉCf¢]Zsá“tפQÇ®áF_þyûèW?o¬J÷– MI§p»Â*Ü@®@|ã$ž…<žqKqâw‚öH¢X¦Œ»³!]© ˜,L§=³ì ÀßÌŸóÉ¿ï¡I†'>I8Ï?/sÏëÛÚ°G‰îYg/kon±Nc 4àÆ\ +£¨êÀ{ÖÞro´ËK¶]†æ” 'åʃŒž{õÆh@9ÐÈ…ܺ7 ­´ƒøR€êª¢(B‚¸Ðzcªz(Éÿ<[þúfOùâß÷Щ©(Éÿ<›Ÿ¼(‡Ê!#©àõü³Uõ‹‰­tó,Oåþö ÒmÉBê¬ø#($‚r^œVM¶³©í5&‰ÖÒ_0K8‡ 0B¸tÀEnƒ;³Àâ„ç—™D¿fýàCü»½ÆzãÚ™3þ©¿ï¡X´Ó\j+e¬[„‚4Ü×›rž ·9$7ÌF -Ö¨ÃOÒg{é4ø®eÛ,Ò„Ý„vÛÉUÁŒfu6ó'üòonEùâß÷Юi|KªÅa×î2¬LÒ?’ ùA÷6üœ`’•Z“Äs‰na[£E"¡s1hÑX]‡ÝèÒç=9 fßïü²n¸ûí“þyûèW5mâ{ö´;ìc2G`';äTiŸ{a'nqƦ*ýæ§r¶åqg‹ÃÓŒ2Æ€‘¼nÀƒŒÐÖýçüñoûèQûÏùâߘ¬+MZåµ /´ÜÆ¢K!-Ü.mßfwÆäí1n~\´Äñ<âííÖÙ'u-ˆÕ¿zÀÉ2üªýÐç9ÁÇ'€FþdÿžGþú¹“þy7ýô+›oÜ®š·omj„ï<ÜV#gÈ çç;ñ·¯ËŸ§TFÏ4dÿž-ÿ} 3'üñoûèTÔP9“þx·ýô(ÌŸóÅ¿ï¡SQ@æLãÊoûèQ—Çú¦ÿ¾…føŠúâÆÚ ÞB¼Œ®ûCc±Eñó0Qøã¯"-^ùµÉb¿­ [ee˜÷*ç¹b1Ðc=Íkæ@y‰¿ï¡FdÿžMÿ} æZ¬e¹¶Ö"’®ö ÏM"„o‘@R2\.Ð@$ê ¹­ê—·j!¼0Iö35½»"³\J„˜äq… ŒÐædÿžMÿ} 3'?ºn8û°—Ä7ÿo¶·–Â(Äó:i‚áV_,¨'ï6qPGÖ«\x¢ñ´É%†+xæUßæMê„CÈfù‰àãå#®vs¦Ìœþé¿ï¡I™?ç‘ÿ¾…bÃâ éî&‚;(U’ëÉEyÆWÊ•~aä¸éÍ&¥¬Þ ¨OnmŒÈ›wfÂì‡=yÜÝ0~_­ ¼Éÿ<›þú¹“þyûèV4ÅàÔ5Uº‰íã…Û,‰Œ1iï;AǾ>µÅ—TÅm#•£@HIy_õct™ùÉ΄þàty|ãÊlŽÛ….dÿž-ÿ} Ä‹ÄS½í«Ãn‚䦟ymÅòÑàm l÷×çÐPY“þx·ýô(ÌŸóÅ¿ï¡SRzP7ü„gÿ®1ÿ7¬ù¼C¥Á4I|«$d‡Sž hMÿ!ÿëŒÍëÉ5Íe£ñ>§lšl÷ ðÍÓÔÐÓHMØô¯øI4‘È¿\ûdO”x‹Lè/WÓ¡ÿ<þuå‰â+T8šÊúþÔ9þU~ËXÓµ üˆ%f”‚v4l§Âç¢ÂE¦ù_~§úz~tÂG¥Ž~Þ¼qÀ=³ÓþµpbîÍähÖêÊpTH2)HSÑÏ¡¥aÞçqÿ >’?åýxïÇᎨÿ„—G<h&sþ×QÆz~µÃùy=) J%N1’GOóéJÌ4;Ñâ 1ÔâõH÷ùòh> ÓAÿÔRzõÿ>ÿθ—†’IŸlh7Iâ¨ÙëUåÊZÁ2K+@#½=Ms@i’i.-žX²cr›™ Tã=8íÇ)ÒkÚ-Êm’æ9ƒµÑ˜dŽ£=½º×“ÝxÆÖÑÊ4AJ’9çvJOÃÑcÏý³Ïõ¡v&ç´&½£Å¬w‘¢/EU ¼NµÖ´p×{q; 4ž_Î@ì[¯(·ñ;Káë½XÃ»É Vwtç©õõ¬'ñýÛRÒŸRÆ€÷øHôùÿOÉ©‡Å*õÔ#üš¸2eÓa¹˜òF¬UG>ßFâ7` 7>Ôì=R 㺆;ˆ\Iƒ*Ã<ÇšÃ><ðÉÿlDzßÖ¯x{Øÿ×ýkÀ~QÍmF´lÊ­NK⨻‡·g¸ÿÂ{ᮣY‡?Fí§ZŽü2æ1ã»üÿž+ñKùQõEÜ>°Ïpÿ„÷ÃYÏöÌYÆ3†ééÒ¡ÿ„ËÂ>qŸûFÐÌÄ'–K3Œœg€[\ ñ\QŒSú¤{‡·g·?Ž<-,mš´ ÁVV ƒÛ)#ñ¯… ‰b‡TµŠ4ȈT(ô¯Åæ—ÕpúÃ=¿þ¯ Ðbûå¿ÂøN¼1ÿAˆ?ï–ÿ ðüQŠSpúÃ=ëNñ>‹«Üý’ÃPŽyŠ–Ø öö5­^?ðÄÅ^¿õï'òëâ¸ëC’VGE9ó+‘]\Ãek-ÍÈáKÈçøTwÍbÿÂuáŸú ÅŸ_œýñô«,ÿ‘OVÿ¯9?ô^ƒZРª\έ^K#Û?á;ðßO툆=›óéÛµðxg?ò‹>¸lþxÿ?Zñ< 1]?Rs¬³Ûá:ð×ý"ü›ëéGü'~?óŽŸ{óé^$¡à⺂Ä3Û|1¼!ÖbÜݰÝ;öÿjøóÃ0šÌ$Žq†ïŸÇšò HŽ÷Uò]ÕáÞwE»å< zuýj&·Ó®á½{`ö µÃ¼ÆìwŒñ‚:kÏ´yùN»¾Nc׿á:ð× ë1s׆緦?Bž0ðœR´±ê«#ç.†lã98ÿesëœñ"ŒWzÁ­îr}eö=¢xRæ#ú•´Ñà‘ )ôàZpñ¿†€º´ @lc +ÅqFßzkäýež×ÿ džè1äßáGü'ÿ Ä?“…xž3F(ú”{ë,öÏøN|5ÿAˆ¿&ÿ ’ÛÆ¼ºŠÖßT‰å™Â"€rIãŒgÞ¼<ŠÔð¸ÿŠ«Jÿ¯È¿ô1S<"Œ\®Tq »áy{o¦ÚIww0†ÆçsØ~Õ;é7N© ’3€ÁTœ€FA>œsõ5OÆÄ ßoFeØ2«Žyqúµ"ÛpëþGå^DE&>µ×õ÷9þ».ǯÂe tþÕ‹ð/Ï¥GŠ|/Û å¬@¨R2¹Î0O™½¹>õäØ¤ÇµPpú컳7Š|1pÈ×¶ÓÎä2G»iëÁ#õâ¥ÿ„ËÃÿôòoð¯!(g “ŠÀéSõ*wµõÖçkÛC׿á2ðÿý"ü›ü(ÿ„ËÃßô‹òoð¯!Å_Pq}v]^ÿ„ËÃßô‹òoð«>"Ò5;…µ´¾I¥ ¶Å·±¯®—Àþ*¨¿ë”Ÿú ¬êàã9_béâå)%mÏK»Ômtï,ÝL±yÒyiœüÍéÿëªçÄ:Tw+möäYXnUçœO ü«Ç0I46-eÊHÍ•l#ÅrorÓ ^/Î$3ïô¯U,ìzÑ…ÕÏJoé©+D×ꬃv2x§8翵G‰´yK,z„l@ÝŒ±÷ÏN{zל*H»¦1$›ÀRÒHHon¿ç± äe¥ª¬lS*Ü©áBªƒô¸u½>â–ÅhÔ•fÆGôüøïM¶ñ—y¸Ûߤ›NÖë×>¤sÇá^kµüA–(ƒó`\0?Jd0\¯š°CüþTíŸÄÓUé§ÄZ^ÉY¯ÓlD«ç<gû~tÈüK¤HJ¥ú’SvnWñ¦kÌ#I’y$‚Bíµ•ä'qî*ÊCt«óéÑn# ‘üúÕs¢yYè£^Ñ®íåI.á–3˜äVRTõz÷ƒÇ¨¦ÚøCeuµ½„Ù`ªTgü÷ë^p¶—qU·‘’JùœŸ¯Ö«¢In]£†H‡RË'_lúÕ)'°4Öç§ s@žàÜ}¦Ýæ‹åóZ?™:wǿ㚒?hò¡xïã`¼8¯0Š9co,žo$ ÏƒŠ‘KÆ6‹ ˆr¸È=½OÊ«NäëØôCã€ö¤]»ý;RIã/F7I©Ä9À%\ÿJòÉ,Ô&.N6õ`ôɦOb.P ó;†è¹éìjí³"ò¹î2ÿÈFúãózò»¸ ñö´ dØùîzé^©7ü„gÿ®1ÿ7¯*ñÇöŒon7ßjÿ1ç_ÿ²¨èY›¬\ÜZjÇ é唣` îÉÝõ­<^^±§K‚ιñ±ïô®GQ¸ƒP‰n!Ù•ï¼üÄú¸ã'­khš¨¸û£³4–× oâVVýML[zØçµÕó59íÖÊ]3Û–;¶àg¯Lþuѽ–lÙµM’Ç"çc°ç#¯8?ýjÇ×&†ÏÄGÌnòÜ »S¸õäÿ“–iÓ\]^¨Jg“Ó8ãµ »“Øï€6a€§Ñüø¡€F'=ë2]]¥šh-¬æŸË´C°æ›’Z²Òo`ñ&¡í Åø5Éñ,*S#çðS]N­ªÚ^éWÆÙ.Z/²–y0Š8QÉþ•Êø#z ’ ¸Î:0M4ÉznP׿֓êÌSX`“Ò·üBЙvß!f)»Óð¬DOœ.AÎG luÿ»øetÝÞèÕ¹ح^E ±#€µÐcÿ…z–Èêe7yexsXºMä–š‚4hdÝò„þõ&ôШêìÎÓÚ¦¤naÓµC‚Q™”Ú¤~?•tVöñÀQ.¹aëÅrrëQY^yÄ2Ü@Ûvã‘Ç*O§nµÔiZ¬z¾›-Ê;`.79ÚÜõÏ_¯½8»¡Î*/FzFƒÇ‡ìëä­x ”}+è- mÑí¤*?Jùü”Wvvqâ^ˆLQŠ~)1Íz8î7`Ó¶Š¢Áq¸§2€ŠÁÁ$œ¯qAV?uw7ZÚÓü!¨ÞÚÇtn-âI;d, FG ÇŒª(»F «˜tbºsà{Áÿ/Ö÷Óÿ…;þKÿùý´üßü*”âö+9`(ÅuÀ·ßóûiÿÿ…ð‚ßÿÏí§æÿáO™ Ç1F+¨ÿ„ûþm?7ÿ ?á¿ÿŸÛ_ûéÿŸ2 |2ÿ‘¹ëÞOä+׫Ìü- ÝøwXï%¬àFÑìW`yï÷}«²þÞ›þ}#ÿ¿Çÿ‰¯?)Ý#®Œ”cf?Å|øKVÿ¯9?ô^{¯¨\jz=倆(ÍÌ-ó3–Éy®þ{ïùü´ÿ¾Ÿü+|/¸Ì«¾f¬sQŠéÿá¾ÿŸËOûéÿÂøB/¿çòÓþúð®ÏhŽnVs WMÿE÷üþZ~oþÂ}ÿ?–¿›ÿ…'$5]Ò¯4õŠÅ÷ šÞI\ñ÷¶¹ôãžÂ°í,þÅi¬åÕžå—a$ýýÇôüÍtÚ~‡s¦Å寶S|Ù/39cøcË¿Ý^¼†O±&è¶'–î6’[§&¼eNj£•ºž‹œy-s…Å(\WMÿE÷üþZ~oþŸð„_Ï坿ÿá^š±çò³™ÛF+¦ÿ„"ûþ~í?7ÿâhÿ„"ûþ~í?7ÿ |èžVs;h"ºoøB/±ÿvŸ›ÿ…ð„_ÏݧýôÿáMM+9‚+SÃþ*­+þ¿"ÿÐ…iÿÂ}ÿ?–Ÿ÷Óÿ…ZÒ¼){§jÖ—­sk ·™%*²pAÀùxúÔT’piµ$ÙÜxäíð•é÷AWàrÃÓ¯ç\¶‘):Ü 4,„Æ™e9R|±œçœ~uÒê”·Ö¦ÜÛD«¸õÇ·¶ÊÇRCqçÛ$8 $ þ[qÛÐW*rÕXôy££¹e£Vy°zÊÇò¡X²°#8¦tw[}ʼn%elsÿ¡RáIù`äÏVÿâkBvØÑUÌŸ\\ÚX-ͼRJPà¬rl%O\õãÛ½qö÷çÌ(ŇÀBI+Æ1ùûW¡­&¶¶Š{€¸”Fn0ÍJΪw9äõíôª)©Íܼ¨;Z]›Cc9ç¦yÏá[  _‹U‹í6ûÖ0›üÇÇO÷8éøUKŸ _KÇyn†bL…™ŽAòð~´C .Á*Ñę̀µ4…àó~U3,@Æ;·óÿëVع'Q1 Saˆ?ûYϯ­f_•ĺ…°NÒã=qž:þµrÓÂ7Ð_Cs5弦8öc{óŒÿ³î!Nxi=…Ñ]HdÕ°‘|»°¸|’yÇcž>”,±ºËf6ÆŠ8f<ô«ÒxnížW‰ìãYÝ,ä)s÷}½ª£ø6ñÛ&îØ–…¢bYÿˆó·åãñÎj¡‡•´Bu•÷(]¢F¤Ë,q•}£kAàÿõÿ´`ÕaØD®A ¼08Á>ôûŸ Þ\@‘µÍ ‘(l·÷ÛŸlzS.<'=·”·v±HØÞÊ[ Ž}8éWì$÷#Ú¤Ê×7±¼-" ÞnP«·PR=: ¤5Pbç+Øy~éu?ç­kEáØãE{2®ã$ž¹ÆsøôãÞ —Á:‹ì }j *î“8ë×m\h4Kª™ìÈFúãózòºÚøŽÚ岉¾hØžô¯X›þB3ÿ×ÿ›×¨…þй'‘Î;ÖIžA-›I!M>ÚæX˜†…=üþ¹¢XÞÅ4ÓnQ¼ågwTÄõïÛ½ik~1K{i§²JÜ«ÊÜ¢Ÿoóеáí^Kµ’ ©¼É 9à·^¸ãŠ9–ÈÑÓ’Wf>½ _ßj·O¡xå*VQ"¯eÈçÜÕ-ž©ÚYýž;X|Ì ]æ,[Ž 𮹀üôª×Çlìp“íC±šZÈÀ¾F9õ˜úlRÍsäÜùfGÖ ¼}Þ;Us©ÃªNÉi'˜#88Ï$÷æ¡Ñ­Ýn%t pÎçšÊmÁ7±wÄi"ø~ñb µbPws…ö¯?³yacäÊU™v‚ ç#§ÔêÚÍÐy¥£šÎÝöK ˆH~¼}ZÒo-/b’Þ á…pÛ@<ž€tŸ2²dÝÙÀ<3ÜHUT’ Ô"’l“ž vŸÙvVºG“ ÈLƒ œ·ŸH|3§_·ÚÒI@“’3׿•5$ô%ÓiýÝŸ•¡[Î[çyH8äsÆ}8ýk6ç‚â9|¶S Ëú×m{áÈ^Ø%¼ò±¶ì;P}@è>µCUH-å{mFgó£f,l òHíßžx¦´bQÜÁ%¹¹ ¤•ÏÕ‰®×Áúuͽ® “!C#¢'êO#Ú°¬'ÒmçYc3Jùù ¯@Ó ’ T2¡Id‘œ†2ñ€ä*”íaÊ)F÷Ôô4ƒ¥Û0‘öeÔà7ƒu¾x1ž=«·Š9χ^ÚÃÎ󅦨|£‡àŽ=`iÚ–°Ý\²þôí‰GRqןð5ßi¾·ŸL¶’{‹+Æ P.ì’qÇ­y•*ÆSg}8IE–‰i®YÞ<ú¬·±ÄaxÖ+‰\—,¤ è'…mùþÕªú‘nNíFH±Ô#yþ詇†,ÙC-ÝÉ Ð‚œþ”R©­Âp“1<ÿj<ÿjÛo Ù"–kË•P2Idãô¦ÇáË ¹Šúáû|®‡úV¿XÊF7ŸíGŸí[GÃv *Äo®Ž¥•K&X @ÇNGçNÿ„^Óþ~®¿5ÿ =¼ÙHÃóý¨óý«eü9§ÆÁ^úáKtÐgô¥ÿ„jÇþn?ï´õúQíàÊF/ŸíGŸí[+áË,úáŠýà8ý>¿•9¼5dŠYï.UGRY8çéïG·€{)žµµm'†ì%\Ç{pãÕ]ô§Â/iÇúU×>ëþ{x²‘‡çûQçûVçü"öŸó÷uÿ}/øRÂ3d\§Û.wJîLÒoöR1<ÿj<ÿjÜÿ„^Ïþ~®¿5ÿ ?á´Çü}]zu_ð£ëe#Ïö£Ïö­©<7a %íÂz³ çò¥>²?l¹Æq÷“¯åG·€{)žµµnÂ/iÿ?w^½Wü(´<}®ëó_ð£ÛÀ^ÊFŸíGŸí[1xnÂhÖX¯®$G••‚CÓ¥+øjÆ5,÷—*=YJ>±û)¾µµmGá» Ahﮥ]ô§ ÙÿÏÝ׿¿áG·€{)~µµl?‡ôÔž;wÔfYeÎÈÚD ØëŽqRÂ/iÿ?w_šÿ…Þì¤aùþÔyþÕ¹ÿµ¦ãîëó_ð£þ{LãíwYú¯_ʬ@=”Œ??Ú?ڶdž,˜.îH?”xbÍ€"îä‚3Ã/øQõˆ²‘‡çûQçûVÓxjÆ5,÷·*$³ þ”£ÃeC »’ †Oð£ÛÀ=”Œ6˜íluÁÇÖ¯I&œ Ÿ2¢Bc®ì¦Á€øçïg9É<úÕÙ|7a m$·×¢Œ³3 ~T X föà;‚BîL‘ß{ÔJ¬Üjœ—C.áák÷Ky­„&b³(EÎHé·ßO¥YlÚêh˜Z¤d(YƒD@œ•\ž§øG"´á´ÿŸ»¾™ûËôþíðŒZÏÝ׿ŸüMG<{•É.ÆU¤±I±‰|Èñö­¼/Í»œç§#šz¾žÓÄ¢VXÞi79“7ÉŸO©çšÑÿ„jËŸôËœç2uü©Ö *Ä××Fª\:œméÈüÅ>x^÷IZÖ3[ìdLp¬¨¥B7a²£ “Û}<ÔÏýŸ˜cûDa ×ÌâUwd1œ“ýÜžz~µ{þ{N?Ò)ÿÄÑÿ½§_µ]~iÿÄÑí#Ü=œ»Á¬À4¹V’5Ïž¿(!·¶yùA£²–ɜۇýÞ>Ð@\nñž3·õ«ÿ½§Oµ]~iÿÄÑÿ½ ÿ—«¬{ÿâhU#g¨8K±f€[º „³\ ñÄà–ÆF~QÎx$1$–âF ‘ ÎJ2®Š>oNN iÿÂ/iÇúU×ëÿÄÓ¿á·Æ>Ý{·i@7©ùIÉ_»ÓIÔ´`¡+êŒÇ:xK†EŠ»¾uåB‚ÏÞÉÈÈç€8<Ò]G 6©-»îS8@Â@À™åz)Ï8­/øEí9ÿKºç¯)Ïþ;N“ÃJIzá3)éòôü… ¤SÜ=œ»ö2[›’n|ÃÌ¥AÉÿ€‘R3Z5²¯V6™”®ùR\×?^+Hx^Ðgý*è~+ÿÄÑÿ½™ëuuõÊ÷çû¿…7R Þà©É-Œæ–Á­-ÚCo¯–dh@2µ· ¸c“}Ey<éþÌb1Sû¡…¨ÏöË­kÂ/h?åêïþú_þ&øE­;ÝÝ`û¯ÿDgïpp“[°Ëhb¹Ú¬d‹-¼+(!·{¸ØRBÖ >mÀ]Û7‘0ø#g`æßý8­1á{1Àººê£ô @ð½§Suuù§?øí.xêÓIv2¤’ÄÂLLQ‚îÌÌÚFßuùºÓ®V×í,î­ÊüÄ´ïÆFF8ÉÃr¦9­Aá‹N¿jºüÓÿ‰¤ÿ„bÐËÝßæŸüM>x÷Iv6åÿŒÿõÊ?æõÀø†Ò-ZKËc;ªù¬»¢r ãã#¥w²ÿÈFoúåózó¯êñXkRÛ¤m,òJÅQxÀÏRä^gR½Õ:¿Ñ'Ó§•.J4q0ùÇp{þ}©nþÌâ¹!ï–È'ñ­=STûUá߉X®ß"ßôËu¨ì4«C5Ê?˜äŒ7NŸ½(¤Ù´ç+j[Óõ+–µ;.æeS‚ÎÙ`}Ïÿ^¤½¾¸šÎÞÉ »Ï&ÖsŸ•r*ïö]• gˆã’§ÿ®™zRÚ4D’¥) ûÊ}G¾3MÆÌÊ3WØÄÓníl5[¥•$,‡Ëß îFÛ­hêzîmã·°‹Å£<ªŽ¤gŠ¡<0X,î®ïò%aœ Àúf¹¿¸?qöõå@žù¥dÆÛFì’C-»"ÎY\~Ÿ®Mkøiaýò‡MÙQ&þ9äœrk“±¼»Å³g0ÌN}¹®£NuÓ¯n>Ñ#ˆ¿„1ÈàôÇAŒþ”¹SØÚë¡ÐÛhöóNÒÁq½·b]£€=õÇz’îÒ:5òcÂà ÎsšË‹ÄÑÛHÏ ±“#œ¶ÜãÔõǵøŠãU¾+,ÅÆXê§§4r5¨ý¢fŠÃçK?ßaŸ§zÇ× ‚;èáF@@Ç ê}=xëÅlÚJ‰tŒîª$qíýkžÖ§-­\±µ0}\ÕD†S$¡O,m`ÃÏ­zÛì,íŒ$er´ú˜wH˜Wß=+ ×§1éÒ¾^>¤cùš²NÛÁÎeðf“+ukecõ95ãx‡ó¯cðb2x+FVÆE¢^DåJëÁîÎ<[µˆ¶Ò©ŠPR½„€'5kL·i¯â1 s+ f¡t;w‚€)Ëo=>•nÆx­ff•Ê©8ê܃n{×5j–ƒKszPnI½™Ðê· ‹Dv*ÁPzŽœ×y¢36§–?1·þµÁYùwqç÷¨Ó|ÄI×sÏ·Šï4UÙáÍ7xgqª€Ø9ÉïïÏZñ¡vÝÏ]èŒY¼?|òHJù—Wr¹@G–ÊØË}ã’FT“ô«:-†¯i©»ÞÍ+B”`ce!v¨g`ŽG¹­ÂA&u&oþÆ£ó—Ò/üüMl Ìî™;ªKŽEWB0CCùÿÕ\m¾­Y—ŽÄ VwfI#˜£]ò1÷‰ ¤=°uªûÎ#'Úàñ4æ%ébÂYw~8#ô¥ÊÇs•:F²ìe {¬l±¡ºY&\ùỸ‚Q¼dqœžÃí aܪ¤â5*ÈÎ3Ž›ŽIüÉ÷înýš<Ÿ™øÿkÿ­A·ˆ 0'¶ïþµ G7©i·3x’Úý-dš$ƒËÜ‚ÚwƒÏ˜A¾Wš¤úù¹ºŸìѺ$Š0ë‹P³+¶2Î1ÈÇ<ì~Í«õþ÷ÿZ³Gýæÿ¾¿úÔ¯`ÜÃÐt§Ó"¥À’yå|* ‡Ì'¯Ò´æ'‰¢š4•$]Ê~ ð{v«?gûÏÿ}õ¨û4Þoûëÿ­@Î\Ól£[tŽÆ(­vHcœ*œEŒ“¼¨m㪠àgq$г§®¥{7Vk’Ü^ÈcIo §—”Ágàa±ã“ÔœŽÓìéC0'¾îIõúÒ˜ýæŸ÷³œóM1“ÏÉ]hÚôšö¡Hä¼ImÇ—>Ù#‹`@C Üþðû×fmâîÍë÷¿^”}š?Wÿ¾¿úÔº¡ÉÜéºäzËÚË4°m?gS;m#ËÀFf— ïËnÚO?x © Cm§õæa+ì,Û˜GŸ—î7ozØû4~­ÿ}õ¨û4yÆ_þúÿëP#Ä:<šÈ²‰ ¢Å3»¹®ceÎ9Éa“×ùÖ Zºö¢Ï´2Ä#"Þ+œ#"2ŠÞo ðv®{·§{öhý_þúÿëQöhý[þúÿëP€ää±×EëMÚ‚¬¾c»Kt)®ï•€ 8ž[mØÆ8 FvfÕ¿ï¯þµfûÏÿ}õ¨C9 ÝTk[è`šâU.bDšñ˜ymÚ0Äàù™9äÿÀx§6™­ÈRK¨b2± ×¥¤D-óÉ;e=NǨoÙ£ÇÞoûëÿ­GÙ£þóß_ýjiê%6›¯}²ßeÕÀ·ŽW)²Ríï2¬Û¤]ãgî vï]9<œt©¾Í÷›þúÿëQöhñ÷›þúÿëQä%>…ª5Ì“CpS:“\Çl*£ËÚ?xÇ×8¬ù4ÝrÒÎ;‰¤ºgLG;k†gˆæ9°{®2x\â»ß³Gêß÷×ÿZ“ìÉž g×v8ô¥°37IŽæ&[­êÆWdId.è„ªÌ ÉÜýOZ»š›ìÑú·ýõÿÖ ÛGÇÌß÷×ÿZ€!Í©þÌž¯ÿ}õ©>Í«ß_ýj‡4f¦û4Þoûëÿ­GÙ£þóÿß_ýj‡4f¦û4~¯ÿ}õ¨û4Þoûëÿ­@\‡4f¦û4~­ÿ}õ¨û4~­ÿ}õ¨Ñš›ìÑú·ýõÿÖ£ìÑú·ýõÿÖ sFjo³Gêß÷×ÿZ³Gêß÷×ÿZ€!Í©¾Í«ß_ýj>Í«ß_ýjlßòŸþ¸ÇüÞ¼'Æš¤‘ø¾òhFà,,HèCŸþ±¯u—þB3ÿ׿›×‚ø¶öÚêÈÎÒ1º}Ê£¶zúô¥~…Òi;²¼kjUp_!˜ô'òúÝs6í3 …RÄ{\jSÛJeµ5Ï×ÐsÏÿ®´®ÃV’k •:w+»#¿¥né6:zÛ¤v±C0%€ I÷=k‡(V¢½+Ã~µ±Óö­Â¤Ó§Ï8P{gúf•õ)¥b¾¡q™ Ø‘‰Üp`êqÔW8‘Ís8H÷<®xÁçêk²Kgiî&Blìã’}I©tí i6+œ‚Im£ÐwjQKÌÅÅ»v9¨|=¨pdxרœŸð«všwö~÷y; |¹®–uÆ[#¥sö©”‡?5ÌŸr>àzš‡&ô.1EmFòXç#}¤HzVcJÒI+»îglîõã­SUIIóCÜ’9úâ¯][Á!ŠúÞàÈ|¦ÉõTFüÚšÊÊ&¿†u {¸kŒ‚á@ tæ´oukäšÖRë>C ÏN~•ÍZœ†>â´-åŽ ¾j+gûÔ¥6¥`P\·=—ÃÂ1áͰ(6©py*QXd~uèáÔóqkb=´…sÚ¦)L•–šGÎÔ;×{••Ù“nÄæÃv5ʈËá†_žáÒ¯èÚ³ÙǨÝ1K‚¡y€N®r]Nk¤Y-XâŒyŠy]¤÷¼Šµ÷·¤$nBÞdˆÇ#ásŽßOZñ+M¶õÜö)A$´Øè¥Õ#šã>\dÏ\óÖ»Ý8ÑôÀ8ÆÏ$põçO§Z¼àÒ”€ìß>@ëÉÇùÆ1^ƒ¦üš–¹ÈU^£ý–ÿ>•5©¬ÊÞ2‰®O¼7ç8ç÷s^â‡#ÃÓïW…‹F9Aæ)Ü>yÍpKw© §:>¦ê £y— ÜÛØƒópI<‚yŠô)Ír´Î)ÊÓ6|+§]ÙêdòX$vò°ò§_/$yO‘Ãn98ê0+ºº?è²} pž?´´‰þââ@ø]ÃÌmÛôæ»k—ÿF~üV×Sh·»-êG±¸X˜¬†6W‚;zs\”¬úŒ +\¸só¡nA•:`¾> Žk±-’yï\Χ¦Í§1¸´‰çµÎJ'߈OUöûØ»–îK¤ø†Ay•|ªÒ¶ÕGR < ìÆ®—&¼ƒÂW× ã¡ Zt÷ˆ’¶eL…ÝcžØfã©ë^·¸P†ŠzƳm¢Ùý¦à’IÄh>ôÜÓñ®JËÇsG4Ïu›Ìq媾1ÈÇ ûs×ùW_¨YÛjVrZÝB%†J÷Ô{Žyë\žŸàkx¦oã’dÞ¦ÞE|¸=~™÷ý+¢Ÿ³å|Û™MNêÇiit.ì­îv•į´öÜÛïPjú’é:d·¯‘bÛòƒŒäýJ–Þ4¶·ŽÞ%*Ʊª“ÑG>½*FÊßS°–ÒåY¢—‚§†Ï·5еõØ·{yœ„ž<˜êQÏX·Úá2gw'æp}3×¾:×ia}m©ZGuhûâ~øÁÐ×/­ßV„őآæP_s»g =†?NvPǽºCKH¸DUàãéZÔä²å"šÝË9¬[Ë©§¸Hv:FªÎe+¿†8 žyÅkoú×.³­e­¤ðÅû¤LU&I08ãp! ÷8Ï\s\•#'DÒWhé4‹Ùd_"T%VGUrå‹s‘Ï^œg®Aô­|×'£ê:…Î¥ hwVVêd‘¾TÚTdž™æº‚⪠¨¤÷šD™¬­FêVt¶çDiB¥pUˆí—ŒƒÖ´wŠäõm[V¶Ô.-bðåÕõ¹!¼ä|+ƒí´‘É+œçŽÔM6š@Ó¶†¦{*]K+:oSæ<…öç ŽOãzÜÍq6ºž¨òÅn¾¾‰@Y[„ÉåÛ+Ï®3ÎveÁcJœeÙîNÚÍE<­LÂ6|ßç?×Ò—u#9#å8àzÓ’m4·)Zú”RøE+!”0^˜Á=`{}+EX:† à ֲ®,æ¶¢¤jÄ $‘ן¥h¦ØãXÔ|¨»GÐ`W&Ú©5=‹—+JÄÙ¬+í\I(Š'xÕï©ù› 8ýkgxÞ²–É3.Ä’Û`É ÁÈ`dÿœçjÊnÊ&2MìhX]=ݸ‘ÓnìØõÿQ‚mæ¡ÛeÛØNÞ+X¦’Ljö³$Ír³]Ë{4Œ%@QM²È(OQŒ~§Œ 鷊þҔÌZfVÉ 20:ÇQÏLcðâ´–â’} Zé¸IS~ð9 NO\c=ñõ?ZÖÍsVRê~¨±›I$µºÚ»ÄgtG=ý¹<óÔþ= qIÚú ^Ú’f±õÛÖƒËy_øƒàžÝ}~G¿©¼ŸÊ©êV‰yÎw©À g9íþO½5kê ;hcZßýžåLr)êYRUpÃЀØö=+©'ŒôÿõW)=•üqµ…ŒÑá•vä7=?N‡8$Vý…ãÞYGq-¼HÝQÆG íDšoAE5¹s5ƒ¯Þná‚{óe °1W.æp[®0}GçŒínW3âÍ>öú{)­­ŒñD: Ë ÅNìt#åíÉ©)ì`Új?Ù—B;=Zîn&T†ÞÛ˜ä$áC†Î ÇcÍzA<ðxí^_oáÝYµëk˜4Ù HîÖ}ҮЪÄàW¥‡ùyëÀ>ÜP¯¨ê¶ZL)=ôë ;„RAäã8㿚óÍFÿFÔ´½@ÆZ+Í÷[2òÒlaŽ£•ëÓàs]·ˆ|?kâK8í®¥š1‚@b#9Á9#×®‡.•%êG¦ßÝÎí<17ÙŸdqüÉ»8ùŽ9ãŽqëYNROÈì„h{&äýî†× 'm/QûLÒJþdD¶8o_¥z&k‰øugqao|.-g€3DTË&î "»-´NéKbLÑšxô£p¦Q&hÍG¸Q¸P™£5áFá@fŒÔ{……6oùÏÿ\cþo_8øÅ¼g¬ÿ7ÚäíÏ_Zú:_ùÏÿ\cþo_:ø¹Ñð„žwƒ´™yÃÚ©äך„Ã^à“Ÿè¿õæ•ær^ùSK@Æ0yc¶{WU‘§{œU©Ê£Ð”¥RÕáWÓ¤-» 26¶?ò*Ѻ*ž~öô¬ûé/.b—l{bŒe¹ã¹õ5µLL]™”0ÓRM¢F¸|ÌAò¥PŒK‚Xd|¤ãñô®¶ÏKHoíeÓs \tC‚­ 6<>9êþüó[¯Ú!\É^2ž•åJWg£d7—SŒ•T‘r@ÇCßÙÇë]M TÒ4à¿(S…öÀjæÑ3©Ã'ɸ&³âOº{t5Ó[#ɤY…ûÊ»€ç’0qWOFDÎyµ¹­µó®¦3‹‰Ú!Ž0§l›6î`@É õüª¯ü$ü‘?˜ãË›n`l, ÉÎÜgk:ýãÇr+®ÿJÛ€€xÞØíÛÏZÚ‰åí’ÄþwüþxèÐÆ×w±Îi¾#Ö5I­áÛk› ¸o1|ŒÛ ¬œ0 vžO¯éšÎ§is$ФB"-ÎYWýn?Ùö­i‘tÃÀù›ôÆ? †  m"(²rw;±ÉÉç©çœœÑq‰®Ý=³Ù¬—mefò°¸¹]£`ÅA$ r}‡^k#Oñ. o"´™à•· Š7Œ‰®#i$_0rÚª{ž™Õy¸$àŸEô¦(&–eGJª®À7 r=¸ôõ¬Ë9‹?kZ‚F-"wÎàÃyˆˆÝÌl«!9È“´œô\ õs›«.J™aY» 9¦$r\ûOáÓsíG™Ó†ë×iã蘿º×aÔµK»YÁ·² ¬S«fv„ »;ˆ;·ƒŽ*KwY‡T¹±Hm¤’.6›ïó|ÍÄnÊýÒ8'?Ã]™Ž›±þéíþG§4 06€Àg?tŒ“Éíúâ€+iϨéË{°,SHÍÆ—œ+RqžÜV‰õMKM»šâÚWÐØ;È¡Cfm¢AÆNÖ žØÏ\WJeÎN'ÕHéëÞ—Í#¦üg¦ø~´09iǼc¾(Aàþ¾¢¹)uëèâe†e–êÐ^Iq®vª—ò·Œd.6`ðO^k©~ÿýòhð0\c§¿áÅFrÚÆ¹©Acynf¶‚HÖáDâ7Q#*!UŒg*í¼ó–û‡M?Yº¹ÖÚÉÄ;FðÑÞdAvì‘ÉìÙãc¶yÆÀ”ÆñìÿÎ7åÇÌG¦ ìGÓµCÄ3]A¢ÊöNñÌÒFªÊ@?4Ч’'’ â¹ëoë6÷oa%ºM42²ÊÈ$“æsµ[rî!–ÝÚ»&9ÃgÎÓŸ¦zúÂ4ã6:}ÓŽsÛ¸4ÈÅâèþÑ1¾³d’h×Ï(æ³ >лøbß/QÏ¿ÖZN÷PM,M’D®Ñ“Ê+ør? œsœ¿Lt===i<Áèþ¿tóLZïZê÷Ïgª „rdò!3L;BíÞUÎz“Àà¯ü$÷þpUk9—ÌÛ¢6/þe‹æÀ#'û܃Ðd×Sç™01Øã×ü(ó çŽî=qþ4œÝž·¬<–­:ÚæÎÂ8[ÈP®KcåûŰwt iØ^êsê×\ÚEØÉ>HÈ=¶÷úñÚ´<Üÿ{qƒùôôëíIæ¿ôÚýThzÄ6šmÅÅÄÒAQ3´‘Ÿ™T÷ü r°ë÷VÖ>tzœ~h’Qç2Ê€»-ŒÞ0$äç•8k¯cœ0#Ž÷î;ÒùìO;úzï×Þ…¸Ä^"Õn/¬ih­$Þ[«DÌm{°+ܳ/ÍÆÑõ5\Òµ}JçoÚmc˜ÉoÁm”.̳)ݽ†@+œ‚ȵ·æœmù±ÐesÇå­!—8?9ç=õœg­°$¸àädzz×'m©Yßj^eô³ÛÚ¤ò´D$bn…ÙÜœœœò8×S½ºïƒJ%ÿ®q‚9ìzu§Ô:ŠøªödD‘­ÓÌy"PV’Cü, Kò¯ÍÊ_xµáÛËÛ‹o&õ‘ä†H€Œ«Æ99$yÎz Ôó<¿¯Fü}é ™ë¸õê„ý?Ö„.¦f½vöËg›—³µ’ãmÍÂ…Ìk±ˆ$œ€ RO=GfXx’è\RÇnTùŠ¥ʼneÝž óßµtÔ~nFâ:à‚?¦9ç­Ç£ß€D™>ôdûÔ{Ç÷[þø4oÝoûàЙ>ôdûÔ{Ç÷[þø4oÝoûàЙ>ôdûÔ{Ç÷[þø4oÝoûàЙ>ôdûÔ{Ç÷[þø4oÝoûàÐÓÈBúãóz…¬lÝ˵¹brXĤŸcÅM7ü„'ÿ®1ÿ7£½ 5 þϲÿŸ+cõ…?°XÿÏ•·ýø_ð©ñF(ßr°ÙÏ•·ýù_ð¥û ŸüùÛãþ¸¯øTô”hd`²ÿŸ;oûò¿áGØ,º}ŠÛþü¯øTø¥ .×R¿Ø,çÊÛ?õŰYôû¿ýù_𫘣Aó>äa³=l­±ÿ\Wü(û—üù[ß•ÿ ±E¿[•þÁeÿ>VØÿ®+þ}‚Çþ|m‡ý±_𫘠.ï¹Ø,¿çÆÛþü¯øPtûùñ¶ÿ¿+þbŠAvƪª*¢ª¿Â£}+ËLJlíXçPr¬wžHõ¯R¯‹Æp™É{dqeb Ç'{RWAÜÚƒGµ÷^Vö,­— <~k]ÓcµÓå'välGä‚N:ÿ“Z^$†Úe{[E¸²%ÚpåU®õoµY$b+€ÈÞfÿ˜6ãôô¨±Wfe¾ºXÛÁnÌbª¬CýÓŒqùÖô¤—wíe¼û£Pà ØÃåú¯ZÂ3#jŠí&<¼äž¹äà“Î9é]U…Í»jÍ{¸(„!¸np{òz~|Ô´4ƲÌ׫ ‚T@8V]ÝùÇùÍvšv¡ee¤Y¥Ýä6îðƒ¶yUI9<÷ÏS\‚\Ù·ˆ>Ð,›LeÈPsÏÎzwéQx¥ÃǤ¿@mr÷c[áiº“åzâ**pº;¯íÝþ‚Ö_øŸãGöö‘ÿAk/üOñ¯&üMz¿P]Ï;믱ë?ÛºGýl¿ð!?ÆíÝþ‚Ö_øŸã^MÎ)½³Kê+¸}uö=oû{Gÿ µ—þ§øÒÿohÿô²ÿÀ„ÿò¿J={>¢»‡×_cÖÿ·´ú YàBÛº?ý¬¿ð!?Ƽ gŠSÉ⨮áõרõ¿íÝþ‚Ö_øŸãIý»£ÿÐZËÿükÉ  Oô£ê+¸}uö=oûwGÿ µ—þ'øÒÿnéô²ÿÀ„ÿò> ü¨# »‡×_c×?·´oú ÙàB/ööÿAk/ü Oñ¯!ü(Æ4}Ew®¾Ç®ÿohÿô²ÿÀ„ÿ?·´ú ÙàJy:QÔô£ê+¸}uö=wû{Gÿ µ—þ§øÑý½£ÿÐZËÿSükÈ€˜£ê+¸}uö={û{Gÿ µ—þ§øÑý½£ÿÐ^ËÿSükȱëH@#Š>¢»‡×_c׿·´ú YàJ!ñŠ¿{X±[”ÿò0(ÀùQõÜ>ºû·ÿ ‰ÿA›ü Oñ£þ-þƒ6øŸã^G´½3GÔ<ÃëÞG®ÂE¡ÿÐjÃÿSühÿ„‹Cÿ Õ‡þ'ø×‘çÞ‚yöúÓú‡˜}{ÈõÏøH´Oú ØàJð‘hŸô°ÿÀ¤ÿò1ŸZ@N3“úÒú‡˜þ»äzïü$Z'ýl?ð%?ÆøH´Oú XsÿO)þ5ä|úÒœþ^ô}GÌ>»äzßü$Z'ý¬?ð%?ÆøH´Oú ØàRyy>“>ô}Ew®ù»ÿ ‰ÿA›ü Oñ£þ-þƒVøŸã^IØsúÒ~?©£êaõçØõÏøH´?ú ØàJ'ü$zýl?ð)?Ƽ“žj9Æ(úŠî]ò=sþ-þƒVøŸãGü$Zýl?ð)?Ƽˆÿžhí×õ£êaõרõßøH´?ú ØàR'ü$Zý¬?ð)?Ƽ'I?LÒäãÿ®hú‡˜}wÈõÏøH´?ú iÿøŸãGü$Zýtÿü Oñ¯#ü)r=OëGÔ<Ãë¾G¶Mÿ!ÿëŒÍéi&ÿŒÿõÆ?æô+Ë=!h£úR‘@ E&xö¥ ŠJZ(¢Š(¢Š(¢Š(¢Š+À^Ê'EÚY ’s’O>ÿ{íyøOÄA.à°õ'Ÿ\ÓDÊý íE0 ò÷µ'8ÿùÔæ\ M¸QÑqßùu­øE|Aÿ@»nøÒÿÂ)¯Ÿù…Oë÷E= WF|·-q¹¤Ë–%°Nòì*( ‘Cåù’ ijNI#kõäqŽã¯¥jÂ)¯ã#JŸaN×ñÿ ©ùúPRlËß(™%Jwôõã×<{WC®†þÎÐ÷1cöÉèX“ëTÿá×ÇM*|zàUÿ#Åm£Æà«¥VÁÓ„þ*9±?Ãw0À£ô¥Ç4cî8€sHéN#ŠLu äÑŠ^”¤P!½ÿâŽEP1 `f“m?&€CvñÔÒm§íñFÜ‘ë@ Æ(ãôìu €JÃzñëÍ èiÛqš1Û½7œt÷ãŠsœÓ±×ŠCÍ!è)j\f“µ&Hà 'µ/&Œq@„îE.2zRr~½)xÅ ý)¸=zÒãëKœcÓ4ÜOµ/j;sß­ñš!zQŽxüéÝOãIëŰ˜Ïÿ®Ž S‡#4žÔÜ{ÑŽ*qHF(9Æ;fŒsJy£Ÿq@ Å¥ÇÿZŒPœæ“ÐbÔõ£hœÒE8u¤#=¨c­!Ô½sÚŒP ÅúÒ‘ùúÑÏþ”‡>¼QžœzÑœRã¥'QéGn´â¥éïŠL©¿*\w¤©ØÏ=h`4.¥=8 (Æ;P¶Mÿ!ÿëŒÍ긿´7’Y‰—ωrñû`íÐŽ;qV&ÿŒÿõÆ?æõ?‡#º¼¸’[§ò%feŠ4 ÊΊ‡æç#>]¸äƒ‘Å|Áôeßíkìøµ¸ m %U,èHÇ w© ¿´¹¸–eóæ·ÿX¨¬O\ƒœøw©`½·¹‚¡”Æ®ÿ:çåðœsZÏ·óé²#°ìg!ˆg'?/AÜf€6.5 [F‰g—ËóˆT$x‘Ó“MS³šçY³2;)c#©ê85VçJ»¸kDûzýšÝÔì`šQN g¥4 ?JP9¥˜Ð´Kÿ!ÿë”ÍëƒÕ|[¬Zê·vðÉ—¥T4yaù×w/ü„gÿ®Q7¯1ÖÓþ'—§fc^.œ¬ÕÏ_9F)¦Xÿ„Ï]ÿžÐߪCãMtõ°ÿß‘YE1ØÓþÌínò`mV N{}=8¯KØR]=V©ÜÑÿ„×]ÿžÐÿߪ?á6×ç¬?÷ädZo—×ÚŸÕéö·©Ü×>6×ç´÷äQÿ ¾»ÿ= ÿ¿"±Ìd{Ry~Ô}^Ÿ`öõ;›?ð›kØÿ[ýùÅñÞ´ÎÑ-ÄÓ¨òzJÈÙŒ’pµ„k]8ßr²ž ÉôëÓ½sÖ…(5¦æô¥RwÔèGußùëýù£Æšæ?×Aÿ~…bùf »š+kWy[ p?>+IR¤•ìfªTrJçD¾4×½„dÏ*pñ޶å¬?÷äW3e, 9"4–ïʯFDVB\dÞ¢¥5±sH½Y¶<_­ÏhïȧëGþZÃÿ~…bªäñúTªµn…>ĪÓ}OJÒî$ºÒ­®&`^XÃ1^†¸1ã-pŒ™`ÿ¿#­w: Ƈf="μÙmò Åa…¥ ÎJH×RqŠiš?ð™k¿óÖûò(ÿ„Ï]ÏúèïÕg›s×Ó8ÅwýZ—c…b*w4¿á2×ç¬÷äRÂe®ÿ~ûõYþN{Ri}Z—b–"§sGþMwþzÁÿ~¨ñ¯<L²ròZïo©lÿZÍò½«K^´Ò=­ó¬gN©cERSƒRf(ùæ“§`ú u!¸¥ÆiJÑŒPw£iÀi?Æ€:qHFi}©qŠLqšAÔzS‚ÑŠh£ô½ñJï@ #µ¤{΂9û¼L}))OjÄVžmŒ÷j+hÚ{äâ¥É-ÊQob®=»PG)Ýi¼zSD‰HGçN9Å`f˜ þ!F3šv9¤Ó¦kˆÚ Öæ0_oPjL†x d^«àTëéÖ´¾Ó<÷Gdq$b ¹Âõçÿ×^|±•/¦Çlp°¶¥hÈwekŽÙçô§˜½©Ör$„#Æ#“ab:.3ÇNÙ©Å*ÆU¹‘X€zñ‘þéP®¥}δydÒØÏ¾‡u”ãæFä}+'Mµy„‹ª£`7ÌGó­Ý^m*à8à/÷ˆî=+ššóìê¾\1/O•Pø?L¢¹1³÷•ެ$tgCrÂÖÂI‰$G9#9>þµÅË}uög´¸o3q ?6ÆÈçÓ¥k꺑¹ÿ@GE껲@ù±œþ¼Ö5ÊíÇŠEÌŒ9¾½Åg:îI$i ¶iéÖ²L°ƒ)XY¶Ë´d]žñˆÚå°A æíÇÎFzb³ô«;§†(ìç挞©ëœgõ«úõÍÅ­ÅÕÔÑ„JÆ«• þ+W”%¡´¨ÆkRÌwvÓ]Çg ‚IœðÉâ®FÐ:ò­Ðƒ\<7By²ˆVs–@yã¨ÝרϥurGek¦[Ks=ÎdLì‡gÁôÿ8®®Ïª0xX5£=7FçF³Ç#Êåßjv¥Hb•¸_§=?Jõ}%‹D³2PB¸,rH÷õ¯,™¢†âßj’ÜF &ryç×>ø¬yF\Ñ{šº1”m.†½›¥Ý±¸Ûå¨b¿9ÏÿZ•|‰$dYS(2psÆ=«ý˜hA'¹•šp?ÃŽ=ºVˆ7ÈHÜ8N Fk©ãªY¿S‹nÇg[ÌP$ÈÏ!Û<>œóŠq¶#±®. m­µK{…BËŽNP6ð>•ÒÚøŽ)·ˆ­.fd]ÇlÓ¥Ž|ÞöÄÏ­îî\òj—ÄÚPì-@ýj›êW·v–Vi¼Ò#â5ë·Ÿð«þ#Œ¬Zb·%m˜zðǽt,DjÔŠFRÃÊœ‘‡ñ£ŸJ^‚ŒcÞ½ˆ;Òv§zõ¤ÇÒ€AŒâƒøÐhíÒ€ã@pM.:Ñ@ íùQߨü©Ø¤ì;Pqß44â(ãÒ€øP4c=iqϵ†ž™ÍZ¶º†=2êÝ viŠŸ0>à÷ê±rÊ)d³¼ÇǼI®zÛ#Zn×(žÔzÒŽ†‚3Ú¶ŽÆlB8¤Àǵ:“©öª˜çîÒcìJ\P1Ȥüiä Lr}¨4Ž):ÓñÍ&:ÐúRqéNÇëGO΀½¥#¶(Å'ãšN_Zv:âŒ`Po¯qKÁâŒvæ€(¥“é@ëÖ€Š1NëÞƒ@ ïHiÝè  fƒœÐG$ö¥€RbœOzN3Ò€ÜhÇ¿j\QŒÐ oçKÒ‚9è(¸÷£šw~´˜Î(¢žÝéØçןãN=i0ŽiØ>´cŸéJô¥p=Ž_ùÏÿ\¢þo\n¢»µ;Ÿ_9«³›þB3ÿ×ÿ›×¨F5›èÎTBìdf\(î{×…B|­³Û­d’9]KTº–öâÑ®Sh1¥°‚á’ñÕœK,D+î ‘Ï¸Çæ0)å’âG¸BÊ’ÊX`~=:TÂ4ÒM®ÊË¿\$ëž+ Órnæ´ ¢¬ƒM¶ŠM:b¢¨Så“‘î}z ±gi†Q+I»|„óÇ9ö©4­h‘nA/”ªC õäg­Y¶…ÈÛ€ÆòxÂmn}ùç=y®vÍÒ¹P[[}©×c ‡ž£ß=}jO°…e…¶Ê#;¼ÃÑ;óLˆH÷s=£y­± Ç÷yçëF³˜ôЃqY$DŒ†çå'ðéÓ“B”“M Æ:Ý^§¨Ü¾¡, 3˜ˆÊ+|­Ž•g”3Í&1þ=»ô«:þ—›«^ZÛÜ´‘'ìåÎw†pÝìr=ÀÍd´’Ĺ£Œ• žAâº9œ’fIY²äáT7–èv«7óÛõ¢e.¬…Ž úö⩵ô¥K.ݧ¯Àç–YäÆIàŽ=(³ÏHð¦›nc±¸21‘¡fár­Ð÷ïX>-h¥×e—ç“çl#ŸõGqéÿ.™nb¶³¶H‘ˆ™ÝÀ^GO~µ›¬½ÔÝ¡ÚÅX¢ŒõžG¿œbùµ)¿t‰da"8a”$`­n I­tȸI Dxd¢·^=ëØ„‰ÄØŒsòç×üþµ`.Žš’„2! ˆˆtÏ^~õiQh¬L^§¯øe·xgM9å­”æ¼ÖG»ñO´Yr§ NÕéÚ?á°Û¾Jàý8¯9]Ä2Ù­ÕêK8hÕ_îߟLÖR²µÍ#ïb-E&½Ñ±$Q«´ËßîŸè*„ö 2[‚¶Ñ,{Á̇-’¼€:tõ«shúô“â@ÁnÂIù›iòè7‚'1$¢Laó“õÎjeQiaÆ›êb:?ØÖo"<‘K©8ÇcíÇnÕ¡áëK’²Þ(XðÁv犕4MDÚ2˜]dó·Í‚Wn3‘ÇáÍ]²Ð$Rd¹•ÒPÃ@äzÖrÑj›Lt±Nä3vÇÊ[“Ÿ¯_֮뻞‘»ï}Û$ÓœÁØý¢R¥xrÏZ›_]¶ÚJä¶„ Üçæ®ì½Þª91ѵ39âŒRŽ”w¯£<4„:f—»R‘šiâ”RãšÍ7ž¹ Š^Ôvé@1½Í)¸8 Ð{­qN«~”˜éé@G4 u§v4„PJè49[×M&KÏ‘oº ¬«‚+•žãcF„’¬q¸€N+·K˜ ÓÙš1ËüÜÏà=+ƒVÖFЉ磀}¨ƒõ®Äšƒ+ 'û>ÿZÉK™E”rœ4’Ï–ÆI=O¿øW"¿.ˆê¡CŸV} /ü„gÿ®1ÿ7¯9ÖÒ9u{äeàÌÁ°:óÞ½oùÏÿ\cþoU_KÓäÉ%•»»–1ƒ’}ëÇô=…cÎ6@Fñ×¥ lh¶Œ 22}zõä×¢ÿdi¿óámÿ~ÇøQý“¦ÿÏ„÷À©³êRhó¦Kg9{tsŒe‰üÓ1B@ÙæÍ¤[9ÎH*A yÁûcùUIü5m3o)„ÿ98¯Uþ̰ä}Š ¿»¿Ù–>Çýð?«T¬CW܈¤ÜîbÒÉï€1Vb²¸ŽÝ¡33Fç• •vçÛÒ½þÍþ÷è…ðŽè£ì›Oûô?†î¬Á&µáxü¯ é‘ñò[® 棻;Wåí]¼QG)1¬qÆ "(À\z”ýÇÔÇÿ¯YJ F±“‰Åý­Hû†£kœžWq½¿¼:]íýãùÔ{ý«8Cps÷M0ÎOðäW{½¿¼:]íýãKÙÛ3ÏZW$íùŸçI¯óm¥ûZÿìÆ½sxþýzà¼S̶GÒ'ÁïçšîÁG–ª8q“r¦Ì1Í(Å.1Í}áÇ4„qÚŸŽiÈR ÄÅ'õ¥ÇëA)€iâž)1Å&OJ9¥Æ9£‡#ŒŽhÅ.:0sÔÐ}/%¶ŽMã­9VD,ΠÌc&¢NÊãJîÂ-¼ÓL©Œ¾qåÊÛCuÿ"—OÑ5»«7Š9dˆÛu„Ü,px߃T¦¹?Û‘ÄÎÞC«l–Q€ÏŽà:w©Æ›yg¥‹Ä¸’á£ÆbË$á‰ê:W‹‰¨œÏN…ËrEÔõˆ …Á󨯯ÚYÇ^;uúRÉFP8ÆFåÉê*«OsG¾ÞFY›pn¤É'ñïWÛ º²ð ??_é]øj‰Å$sV¦Ô›##4Ÿ…;¯~¢“Úr‰Ži1ȧŽ:ŠÍŠ6Ó±HWÛšcÚŒJv2x˜¤Ni½3ìiÛ{bŒc8¦xâŽ)æ~t®p(ÇÔìt¥#ò4\C1È Ž ;˜ö¢ãGµ(â—ÝèÆ(lâ—}©qš0yæ•Æ&8£ýiÀRw4Ä&'_ζ“( 3‚´¸ qŠLqjL`õ§cµâÇ4ÀȧmöcŒí¥°†ŽâƒùS±ùÐF)!¸÷4àçÒŒr*;é<:æ\ò±œ}{TIÙ68«´ŽkU‘ntñ&½ÔÙ^z('~e¬%XÒµ ¨-Žƒƒ¸² ü¼.8'¿^¸÷«VÞbÇ,‘ªFß•x-ëÎOÿª¼:’r‘ìÓ,O¥fÿŒÿõÆ?æô´“ÈFúãózZÀÜ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠNÕÂø ~òÏþ¹?þ†ÕÝW âo½h?é“ÿèm]X_â#—ü6`ã­.ÜJyw¯pñ¬7£·ÖŠÀãŠf)ÏÿZ¤Úi `7­éÅ;¾1F9¥p­â3Gz.n9ƒô§cŠNÞÔÀÁÅ2o)b-6Ý£ïbãëô©ÁúÖWˆà´·™ÞL ÆÕcµ¹éŽÕ[ò;Rø•̹5u~ÐY"a‰ŒNÙb~™è¥hÂC©E§-¼ÖÒÆÏûÂcŒà6sü³õ®sJ’)ud`›YˆbT°Ç#üûÕ«ýFçL»µ—y1䬪1ÇàM6õÜ÷"’Z=†©cy†éÙ[9ܨPg8ùíï’iÖrC$8ËgU;Ù;òzúV®´º¥­Ã=‡Ì‘ŒÈ fÈIúsƒš½áØ!04?„î “œœ{þuÕƒæç]Ž|R\Œ×ŧc“IŽ+Ú´:‘­ˆoR5u¶±$ ÷éíõ­[;wgÀ# ñ?Ʊ5]:æM`ÝA™c!7„eú÷é]1­¢LmØŠ¸ü;W-·Q¦ô:*B*š}@:1Ò—Åçµv£qÉ£O4¬vŒã8ÍAkr.?Õ <äôIíÇz‰ME¤ú– Úml‰ñô¤íÚ´þ4b©6“ö§tïK‚i€Ïø€§cš:÷Å7ù¨éNÇAHFh˜Ïµ4 r8 š&:ñ@”œb€}¨½}èÆ})ØçÚŽþÔÅdøŒ\ýŒ|æP9$v^{V¸=H£±Ø=¿*Τy¢Ñp—,“85xáxž`Y_ŸcŽÀvqZöÁ<òÉtñ¡  îP; `œàwõªz¥¼2ërÛ?É l\à䌀~4–ÒÙÛÉwÀàª3xôÚ¿ž}ëÄšåv=˜>d™ôTßòŸþ¸ÇüÞ–’oùÏÿ\cþoKXš…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ \?‰~ý§ýr“ÿCjî+ˆñ(ùìÿë›ÿèfº°¿ÅG.'à0ù#  õ>Ôì~cÞ½»ž@Üu£¸¥Ç4\õì(Ç&œ4˜æ˜ ü9£ñý)Ø£P!¸Éã­Þ—õ£Ô˜àÑíšR£š1Jáa1À¨5N•r2clz;ÕŒqPji·ýœqÉçëÅEO—‰¼xñ3*ásÀ3õÍOª[[¿‡MÛ¢™T Fzdäsÿê¨$5×,~T„äg99ôükBà´ž‘&BÓ)9`N¯½xÊÜͳ×וX|Y<Eb—¨É`Ù<1êHÇëÅli  y6ãVè1Xöº<šU¼p±lÈb—æl`ñoζ4Áþ‹)fÝûæÎ[8çµoƒv“1Å]ıMl…Èž£4J“¡ue#=˜6Aè~¦(>Kq¸Ÿá=ø×¡*‹‘É3Aó$ÇJ?zÜ`œzT7ÞD`pG8«·Å"XdiHO(1.@ÛÏLö®SWס–T¶²žN Þéò‚¼ôïŒý+žU£ìµfѤý¦‡M<1YY[Ÿ;ÅYˆÀPp?a_ø’ÚÛ)n†g‚r\qì+#[šV‚â”íVe,ò ô<áYqZ‡dVf(ǶœgŸ×Þ¸aˆ”adv<:”®Îƒ@kkµ[›‹V¥¹œ¨*rG¿¨ëÚ­Â-…£3ÛF1j쬩‚>ª6–"Ú5ŠŠ6sÉ8öÅ^M1æ„ÀÒ¢6U “ž¡³ž•Âçï7sµArÚÅHͼvÿ9Ë0ÁçnåôöÏWŠÁ„H7Y™Áà ôÇ|Õa¢¥V¥DE<Œýê•4dx f5*X`–]ܘ݌Vνìd¨ër¤66ÃWKsLÂm‡l‡i g8ÿ{ŸóŠuÝ•©qŽË7nÛ[=}~µ¦4Hc*îŒÆ3¤¡ààåúf²¦Šid¼P W ò7oLçõŸµl¾D·Cl´¸܆Srx6ÞO­iˆ§Òm 7•Hdmعõö9¬u”^.-á‘Wd‚äsÎüÍ_Eó&'—”EpY³ÆSzúÓIE§qJ JÖ-ÿi´J¦{VØÃïDwþ¿CV"¾´‚¤ÃwM­•?—SP›O1­íB¤r™|ŒÅô“Uu}>{k“ÄjI÷·w]çЃ^„1~g°ÈÒ¼Þ¶s 6Ãn)–L%ÌI"¶9$s×^ u›J‰ÖæâöóHÁ[p@ìúß…<›™„öÐÎb,ɵ†%ÿ3ÏÔýn2¨®?«J4Ý‹ dý çÞ›‚6`¹ /+øfŸ·= zɦ®1«; ŽM&=©ÝñA=©ˆn8"‚´â2(Çç@ ÇCG8§bÒÅ­8 qF1Ú˜ ÛŧÆ}i1ÇÒ ·¥§c‘KŒŠŒzýïÆƒýiÃï~4›Ž3S¸xuýE‘"™>ø—µQÁ’á™Á2I¿v3œŠ½©ªÂMtÈÙÈ=gÁ4j’3H@2zñšñ+-[=Š? >˜›þB3ÿ×ÿ›ÒÒMÿ!ÿëŒÍékœè (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€µq>$=Ÿýrý ×mÚ¸¯ýû?úæÿú®¬/ñ͉þ18£§`ûQÍ{gŽ4­)ÔÅ7>ÔcéNǵ Ðc­&84þÝi1Œó@ 8£Ô¤fŒ{ n()Ävç­&94Äék’Nð÷¬Bþâ_ù‰ ³<»Í®ãÎ=x«šò;èÒ¬{KpÑ“†3Uìî´»hÄÊn#yŽX·¨rGÍ”ã×µpâkrÞ'f—2æ9È&x5œªNâ20ÍÁÉÿUlÅhŒ© jg!U—+‚yÆj·°—Q•¼Û‰'hÉ*°íä¶NrrrkBÎÒxí÷"••\®2Å—Åè yZÜõЩqæ* &ÜnaËï\óëÏO­hè¢àÚÈ%t‘v†ÊŒmÉèjÀê–y ½¾þ>LAç¾1š|þ&°Ó´Ûå-}4¬Q£ØsNxObkJ5\‘ióGÌÛ$qá5+ž€ƒÿ×®sY×SΆÞÎà†gF\ Ê{g#ô¬­AïgÑ­ØÝLå‰ó¿Ê3¼{V]ª}šãϘ)ç°8>Üš×Û¾NS`œÔ™§¬=óKÍr]pFéîR çëÓ§5VÃJšy„èIRrÑÏ¿·ó«0ÉÜ>jźBÌ»{àóÐqÓ×Ó½hY4—ÑHì‡' 1*O‘޼ôÀ¹›v±Ò’LŠ{c4Ë-Æ2¿>AÉòN3ëî8â–8¢’2’~è¨,Áfã¡ÇAý+fæX Ì× ,2¦@Æ$0zÿ,U ѧ¼[˜Úb®"EO%ºT§ ÙsFÔ_MÑY¼ÇV-–câN{Žk¢µñW¬±,Vò™edU6ÅAà`wüx¬Î(´‡-‡]d;»y?Ò¶¬ìl¢ºjĬ ݰ•÷ü}ë nkt;í¹d–³‰I c@N:nsü«#Qñ>›a¨v»»Iò¾Ò@õ?†kcPµhg·žå#ÞˆNC1ííҸˈ¯5ÉÌVï¾y7l# ú÷ç­T{°“¶Çmew«ê-ä2ÁŽK¨$§r{øšçü`­#}Š[( wócc¸Û€žO5ÐiZzivñ@ìZh퀜,žXQsÇ&³5û]2î57`ǘäD}ÜŸ2àö½qš•£ l®sVW‚É¥¦ò±ù0r@ùGºV†—c§ ¿2E/€Ûä7=²¤uÇ)ö:^"ÜDÖñ¨vˆ˜“÷GSŒw­]'Âvj&û&¢¶ò“åC•Þ$ñžƒ˜rhIcÔ¢KV›íRÄ€ ,¬9íÓ×¶*¥ÍÌ󱺅DˈöĘ>˜ÿâ«ú¨¹±Óî#‰âŽT˜!•bàòÀŒ¹ô¬› 뫤šÞ詸ݲ)V<‚sÆîäsøGºKª¶eczÊLrÄà<2ªª.Bärxú{T“\Ïs…VFûLw,¥‡Ê…B¶{“ޏíÅYÖãU‘ZêHÌÑÛ–óY@µHç§œŒûTòy4W’tL¦iîycæûïÏLUEY¦)=']¥Wa1òãÐ 8>Õˆ eN7 “êÞ¿\óS=+é);Á3çê+I¿ôuÏìuúQ´f´"Ã@àRcò§‘IŽ´\6Fh=zS»Ññ¦@Æ{ÐzÓˆçð¤Æ !˜ô©ØúRíæ€n8¤ÚŽž”¸È¤+ Åô²ÛÅý“´ÛòqžžµÉËÔêæè[Òj—†áÕã…1²ž#'Óðæ²^ÍMì‰4ÅBe€ qÎ?ÏçW šÚÞY<››ˆâ‘ŽíȧqàŒž=3Þ‰,å’C ·‹FJ?½ë‘ùдØ[‘šæ6X]ˆ*•#œûzTÑÚË«´h p²€(ÇðU‰×M¶T’ÔIæ”hWÊü¤‡ëô¨mËÆ¢ãÌibû@_)ÆCƒŸ© :–¬-”·–®QŒ¡]àƒÎG·Ž)ú!’ôÆóåG¾L0ùHî‘ß }8¤·±Ì—)x˜Œ22œ‘À8ÇéïV´¿±Á–É6çX\ãO$céÍk‚ÞÆÞ³cY[Çj`ØnÏP+ÆØÃ$ÎÛ™ ¯‘“‚:[º¸ŽM!2Ÿ1Ѝè@9ǰÅsè°Ç Ëp &ŽqÈDÇ5fjé¬%ë‰TIö ïäŒøþ5µ^éwþí|ÛœúÇjÉÑ-`“E»s ;}¨*¹o›ør3íÌÖÅ£¤Òß„&r78îÀcô¬§»5‚Ñý¶Tk[[hÈÑç{ Ä{µ!½ÔÑšyRáÀ8ý?­AqsŸmÝb;KrYO+!<•L`c¿5Ìÿmk€³Ç¦ÛÅá£bÄíÏ|qÉ=0iÆ-ì)I-ΧNk¯íX’ö#‡mžln­Ï?8öéXž-²†æn#Eó¦sãiÇÿ«z¹¤j sqcwòÉ‚I^2¥‡Lq׎œU_ [Ë¡pÈò–þrÏ)£žCgwhÅå8[„›z©Ï|súš·¡[hëÒ;-Ì¡XˆIo”Žä÷8+>î Xþ]¼{%;Á™YXýâ§OJ±iÜ“²iT…,A!•T»i9'üæ©7b]®RºÓ"ÖaA¶UxíE‡È8l{çæ>ã½UƒÃ3[ÇusçâÝ.™eVsóü?×ß½Z¾‚ ¬†R"¨RÃwÞœtí×­ojPE¥øZK›xI’Pý _o-íŸÀNî麹¦[Mlis*ã’|ž@öäÕÜt¨´ùå¹ÓášXŒnËœgõ«{WÑQV‚0ðúru»Eÿ¶Àc¶3ߦ3ïëŠgü&¾< z˧O4~ŸãKmÃs:ÓÄ—„ÅåËo~Ó9I#FòþÎþzÄ»™sÔ7LdíúâAâùEœ×RiðCS,guê£-Ê °?(ùB’síWGŒü9‚«­Ùã°Œßç?ýz•|] ·+¬Úœt"QùúRC3.üU=½ÔÊ-¢hâ <¿´ípDÉi AÉ#;²1ô«Özì÷7¶ðÉci1@X\y…XÄïÆk ƒÐŠx·@°Öm€9ózóþsPx]xm~Ë99Ì£ü÷æ«  &·2]j¶ðJ—RÛ4^\PÆ]â 9Ü«ó=°qÅBþ&k}O¿dŽYe´ó§F>WHóÎA*:ž{{TßðžxTàÂCcøÍéßÒ¡ŸÆ> ¹eyõ­:F @-(8Éþ _Ê’Ø]GÃâ™f½·…,#a!9”]¨ ‰3pdû äŒ5oAÖ¿¶¢šC1ˆ‚gÊ›Í2î*NÑ‚3‚:TÇžcóx†ËþÿsþqÞ¡ƒÆ^µC­éé¸î$M’O©?JÎ’ŠÀÿ„ïŸô0Xßáþ4ÂwáOú,?ï÷ÿ^€7é;Vü'~ÿ¡‚ÇþÿõêÖâ}Wºû.›ªÛ]O³w—ƒv=hV¹ |K©.Ÿ¨ÍY¦†0AŽqjû¤\/'Ó;‡@I®¾¢ûT'þ[!ÇNztÆ?Ȣ½Œ}CZXe°ŠÞþ®n¤Uû<ª¿Ü,InT„9ÁË ƒÒ«Ùk÷W:¼²YìÑÝc 1 …;¾@pqÁAѬÁÚûí×?®:óAq7cƒž™¦4rñx–â&tˆCªÂ±‡ó¡`€â7v@C”p8ù¹©íüO$¿bó,àŒ]JS1ß,ØÆ0`%ÍŽpÏ9®y$ÜýOùãšMù8ÜOë×úžô„r+ã+¢­ ²¶—{&Õª¨™BÄ4ÆüñŒuïÞ£×ùk<ð|·ï’>v®Ïq<î9úúõðk׺Ú`Ë7ÿÐÍua¿ˆŽ|OÀÌŒzÑŠR:÷¥Å{“a¤qA¸¥Ç­a¿…&>”â4cë@Xn(ÇëNÿ 0? Ã@£m;Š1í@Xn?:LcÐSñF1@XÊñ"nÒpsÄŠ~_LÖZJ‰­+K*•òP[Ï¿_åZ¾%ÒWýþ=¸5‚Ò®åÞ©0T N6cçßëƒ^N7Yžá3¥·K‹Ù¢ˆé†|c‘¡¦X}¢7šEDÙ— p™<“Ž üIt·De#®b9;Bœò=úq[^†;‹Õ´š&†HÕfcN -ž@ï\—ÐêZ»°˜n,/üÙ$É€GÈ=}{þ5WìSI©.òÑÇÈld9úÕû1ö»-ÞTÆgÁã lgžz~œSRôCm±<°\°VÏÌø8ê:~T“@ô ó<«¸ï„2´sÄ«µŸ'9éôçô«1ê.gHšÖXâg ðÀã?çךr»ˆ­Ú!"ÄŽ²d<ü˜Èœu©´[íz;w²vîIý*dôÐksWPI [xB"C*†<–8Ï=G~zâ¨é¯Ä~dМImŸ/<ã?×úUjéí¥2˜ÐÛ–ÚØnF0Lût«66ïk§¨î’,L¯Sß®8¬”½ÝMnî^½»³ŽÞ+!›2ÎªÑÆ2W/“Éã¥q÷šr'ˆµ´™U±G'o'§AÀõ®óRŠÞ{$v‰EhØ2ޤM·Ÿ^+Œ¸VUÔd –y'ÞÀ‘Ù»téUO{ zjt>†i4dGpŸl òàó)<N•µoknîßi.#O:UR½0ãšç¼=ªÙYèßg—Í'í!¸è9¼úÖî—«ÚÝ1‹yF’90ÎF .IþGŸzÎkÞeÁû¦<îÐkZŒ ²Û1< D£nHïԊɆw»†à[ÅÃJUY¤àÐãÔséÔúÖ® cÿ„šå<ä!tÔ\—o˜týkÚm%šÚ7ÛiT9`‘¦ ¤]•Ñ )=K¶ò:é_g†ê2#gf 3è¥.½o»M…ޤ¼Íˆû©Ô×­>.ÈFòܾÎÓ+t sÅ>òÅ¥³DÄ/•½0¤uU8É8 žsMÉ7rTZÐe¥†ž Ã~þ0Œ ¬hsñ’{òE^½¼š ê.ï)…U#XÀ§ŸéÆ+ÖÙ%ºó_œ]ðìè@ýpEt:Ⱦ‰.b(ZÍ"uÉ ®ü1ý1S»/deß[Ùê‘@n!|%¸1ï8hóØÁúñPøVQiwu Ë!Ž)l«‘°tÇ<œ~?…[º’;{Kye`´9õã§± M¦ÝÌénóÆc*pØç9­$’Š"7m›zŒ)©ZÆñe]©¸Œl†Áè5=FFðÝ•µ¬2ó™$V\n]¿1ãëXóÀŒaÙ–UÊÛ¹é^ãô¥ÕõË{ Ö‡í&Yc]xV'ïËšW’Ñ2ê±@\(Fîiq‘Š«¥j^D°—v™#ùò¿x~H«xÍ}7î+$Õ¤ÆcôïGãNÇO–¢»º‚ÂÝ®.$Ùœg“ÏÒ­»+²»±=¤—˩¶V‰;fa!ÀÆG?Z[±"^J²D!mÜÆBû}* TŠñnnБFbÇzðNGo­hjMm#ù°£FŰÊsÓ¯ó®8U½O#WM¤PÇéF:qOÇÔÑŠí¹†c§­)äv¤ÛÛµ;Q·¾)ØíF)Üc1F)à^Ô€Qq ·üæ²üD °‰W©ü íÓµkc¥ex?d·Ã`ý¡O¯¯ùük¯Üf´¾4`BÓ>¶c#bK';±ù{qN±2Ĭ|±·s³Îãžâ£$:œ“ª ‚3,G?‡¥5³%«DZ@ÞnåI~nïJç­ØúoùÏÿ\cþo^+¯®<[©œpn$Ççÿׯj›þB3ÿ×ÿ›×këêO×ý)¿SZQÜš»ö 6€€ ³óùÕ«m Ytñtm¦1»`:Œ®3þzÔœÝ =¹¯@Ñ.´ÄÑ,mÓU%PL‘>N“ÐÔ“JÑswØ5PV<Ý­ü©š=û‚žëV`ó"9Éǹ­o°¶§¬ÝHÌ©—,Ê8ú~:ûŠÝ‹DÓ„a|¥'rsù×3¼ìô4RÑ\å`½z Ö°´O³“ ù~ažŸ_SYw“[[_Km.©&Ñ‘ƒz}oØ„žÅ$ÈQ·§½Sº@™J}I¹É’Æ=ßÞO”Ö]Ç‚¬d9‚æXŽx óóø×Hçn2zö¦„ Nà÷\ü£ëê}ªnÐîp×>¿V"Ù£ºö_½úÿeÝiz†žÚmeˆ2Àãó¯Li¶FY†#g;@úÏëUQ•ˆt·GV耕í‚zzúPê$4›<Ð?¨¡Áþ*ô)¬ôL…šÖ=Ùç å°ÿ?sZ¿‡­-.Þ+K¼… OLõ¤d˜Œ:î¾ø­‰ÿ§IöZã[L½L« :ƒè7Wgð{?ðšŸúô—úU!žãX±·O–¶{Vj@»@"„ìL–¥ˆ@Ú©8$Ž5Ø1OÎ=èlih<ôî3ž• $×'ãEh­§Fžcíß#*pqǯ'­KvW:éïì튬÷1Ä\áD‚ßJåuÓÍ¡ÿ¦oÿ¡šãoÕ±ðþ&ŸO–êHFÒÏÁŒAvàñžÕ[Æ"ÎËþ]æÉD«¹T‚Ì:îsÆz Éðε¬Å¾; THÀ LÏ·ÎìAšÆöZ𥫱RòyüE¨eMÓ•'~ uw¬yV4ÕÖÒßk’Û ê3À?^õÓO¢J.nu ¢·gc$‹ÀrÁ8ŸçX:……çÚRí¢Íe%hÎ8þc=M’bq}M6pY4Û^(£ÃM±Žìm?7^8ãÖFƒ{öé'SµZ\‡‘ö¶:žäƒV®524ÖŽDŽ8î~V‘†9èÜ}=*T½l:Ì¢=ĺr9ÆqJú1Û]—RjvðÄúŒ1²Ë™ŒA˜œq´/NØü*ËêzjBÿñ0I2»Qáòî݃Æ8ÇÓ½X¼Ñ­OanÑZËs|Ùð7Qõ Õ„Æ[(îÌ—‘]Â)\§w¡ã¥B³Eê™®¾!¶¹Ž8Š9Þ5'x 1&ò3Ö²$¶ŽòòúI®’‘£òÙY›stçØõëVíÞ C|3A6–¦àȪHzàñïéÚ´ZEÙ¿+l“’ØÈÎxçTUµ"MlÌÍ*=?M–ÈOv’È‘µ¸Á9 ôŽjüRèkzm®W%¿Ö”;‰Îjœ‰mäŽmKG”¡ˆëëJúmŒwϰ¶É.Ò ±°_”±öëÓžµZ=Y édËWz·†íµXÌ7–«“,6ü£¶=¸íÓéXé‰ÎÏ­Û DÏ#e[£vázgœzÔšž•g§ªÅmhb·…ÃoQ»Ê$?AÇ_CÅM&™r%Øš¨œ¬F0ú RÚZBí 6•qjbŠö6Ù‹]¼ôüxéüé·–¶–ÚĈ²ÅTã] òÏJ­§Ù[ÜÚ\ÞG¦yëo;Fó.#t#‘´ŽzœúóN&öÞí…¬²I¬¨L1'``>lûóR¬7sgJдÍGJ,öí&÷Ê–ù‰xÁéSÞøʵxÝÐG.d »ARcõö¬5ˆŸM‰·¨‘š6*p~P}úc®7ˆlá Ö3”_”çæ žÜôëVÒv±ºnæn«¦M›#´lËM³?2€íù—ƒéŽ•‹hûM‚ÊKaæNÕÈärA?JèµnÂûG“EÓî>Çö¹>dtàð½-¤‘ØjvÒC5¢âH³ghO¯4k³+E©²Cj‹°1!˜îèÁ€çëÇó¬V¼¯´Å:±y$AGƒ 1aÛýkPÔà·’IÚîÕ•Ê Ç0;O±uËí?S½y’ò>woâbÛ¸ì;QÓwGA D‘hèB0Ÿˆçê}jñ§‡a¯éVVÞT×pØØÎ1ßžÕq|I£±ÂÞÃî°æ½ª5#È®Ï&­9s»#C¡—â‰c‹Ãóî@ìøD_|õþµv=WO“ýUäN}ª!´]^;[Kh’ævqµXô\œ~•U*G•ÙŠœ2¹Gšs^Ã$’HØ‹ˆø2rOnµØj¤ITPr:uÇL×;¢hÚöšVÙSì™R R¥dç#>˜ÇJغþÙ´ˆ‰¢YˆP»XtÄלz×›Nv’:ªÁëb¥õâÙ[y¬‰ù@'ðzþ])šeÄ×·ž§Íë¿tq‘ùg­SñPF¨+¹FíÏùü*ŒWëk©XÙÂ|«XönêÅs“ê1Ž+ºU¹f—CÒæ¦ÚÜ鈤Ç5#®Ö"›a]iÜå°Ücš1ÿ×§×½'aNà3¨§ N ¥Æ;ö¢áa‚²|JJÙÛár~Ð;ôë[8é\÷Šçhͺ3a4˜ÈÀÌÖ5šPf´•挅bgÀ8lŸ¯çNµäsW(€ c+¡'$Ÿ—¡ôúU+{É]D{0¥·»O­Yûy†Émå„L›·ˆÑvóÏÌNFOjñäÏRú oùÏÿ\cþo^9â!j*߸cú×±Íÿ!ÿëŒÍëÆüKÿ#¤Ãï}¡±ùÖ”·dTÙíµæ1¿\õÏOoþ½Kuiud«(ÚÑ•, }y¬Ù$—í2:ƒ÷ŽÞ}­Á¨[ßé[M•–ónÈvééXÎͲãt‘wK´7:L;“agóà†?áS‹Ém¤?i]¥äaàsZúM„†ÎÄ©À@Ç='úյУÖ,mž4ܼ‡1·Þ8cY¸»\9“v89.íÆ¬ÄNe<ŒõÍjÚ‘£„ÛµÛríôÀÏò5†–iý¨Ñàb9sÀÜ2qÓéZ¢C^RBÏòŽ€‚{ÐÛv´4€'ž£qëP]ζö¬îv¨R?ô©-e3&ÆFIrƒ¶2xüÏä*ž±Ém¹²ñõ‹¹¬äÚ**æ=ÄZ…ù- D!Û È>Äߥ %Ô­æ—{1ïúÖ„ª¦ímÄ>\QÝ÷'ƒƒ“íùUHÐEh;.ú‚jæzš6¶¶óÈ×­róM+TláA?Ÿ~)5ù®.Ö„ôPÜò+Ñ<9:\Û†E G¹2ÜóÅh·'¡·TA«Õš«@Jâ—v:õ¨ƒb°{ûÖˆTµ‚#{ Ž9FåH›‘ž¼tü«†µU+w:éSqo±Õøsź~™m4p$÷Hì\|”sÓƒÛžµËÞêëÒ`-˜º¸`Î÷Æ 9í]7…R8tkCåã|jr0í íú ãÄE5BÂ0"†å¥bl½yÂ’»;B_ZCac´úóTu­B×Sò# Ó qމää‘Û>Ÿ•O¥]Û[C‹²·˜„c sœdsŒ}jšºìîtz ™5RmÁXÉ!€êpyÈï]w‰cóü©™QHOÞ*¯H Óœg9®)-¦ÚÖ“@á”néâæ’â{Ë+iíæ–öñ¥FvU…Pç=ñY(ë¡nZjPñM².†’ù0—JѦ:æ5ÝøûÖ&‹©›If“ì~|³¢Ä€ô_JŸX¾šæøG*lXä;c \.G¿åE¬·V%§ ’ "È›ƒíïþEj¶³3ëtu:ûj›î|œ¤¢/(g¡QÉÃ~ïNG½VH- ðõÍàŽÝäóV/# €ÁÏÞíéMŠæökhÛí:LLÁFÃo‚¾ßZYEùL-ÆåÎ0…#<žsš„ì^åë+eŠhå˜%œW6þTáf ±s œý{Õ{™–áfx¯,!òÚpXF‡§OÿV*‹ErgÙ%µ„±ª€¸“ >˜j ÜÇ1Øiª»±´ÌAÉzÓæ%Âú–¤¸4ƒ{BóÜ(ÜYW(½¿EK¥xn\Ãd ïÞH˜grŽòÉÇAY‰mtÛ•tÝ3sð[Ìûx¨'†[ie”-´{âet÷(ùJäU)'¡ +›¶73èÞ »¸ˆG9pX°c¿9çüò+-bæêxc‘„BFUÉf rHÎ+[AšæãÂz»ÉsÉû„è6Œ3êzc×5IíµäG:\¹9cäçòü(—™QºØ¿ý´šU­î’m¢š)å,e²zœñžÙ¡¶Hn]ª¸„ÈÍ¿åà¨÷<µR4Ôƒ«B–W΄>Ý9üêıYÜ1¹–óJ¾\ÞDO©ÏN}¿:„ÑvlÕ³ž%·¼Ä¨°Ȭ§Ãrƒ·OΩ¼qÉ,ù.ÂHø] Ç}÷ß©¬«˜nn®öwpIwVUsõÅ,–·r–t³*Q1“0?/¶ê¤Ñ›‹CÌéu~ux¾ÎL¨Ð`Œ©ÉÈõÇ¥X[»™­ä¶»swo'®ƒ•Ç@ÝAëÎGZ§$º¸‚8Ô¶Œî[æÇ|w9ô¥·kÃ4MyhË“:Bs³Œóùö¤÷иì®z^‘)ŽØiè«5Ù‡wVPS=zñÚ¨ø{IÔo¡»m>$aáù‚£±œf´§Õl-¯ÂÛè×2,W&UfgÉÀlt§\Õ:ëR³i—OÑ2!“2D\’zœ“×&Æìjê×V–¶wûeX¥hæO¿Œ(e‡AÚ¡³e”ïeÜ`mзpIëéôÇ+Þë÷v")ôiÖ ȱ¢*°#åÃ<ôâ©Go©Å$š øQÉòPäúúú÷¤&㡜¡Ì^°´Y^îa $¶I%uùzŸ½ž¤ÖUæØµË˜­0¾T¨ª{.[io|ƒ×¸«M$»Ú4»Ó”ÚGÙðH9ÉÈþ]ë:â@JÍ ‹BL€eƒ <ã×§æ=iʧ0($oCö›‡…5&XŠ“º& ÿ§¿=9ô¦E5¢–ûcÊeŠ/Ý3ü­¹ˆcó8ªVzË5Õ²\Å *º«0©Æs֬˧ožÝ#i6ª‰DeÀmÄžs߯'…ä¥snX¸êRžKí]£†hâ7*¨É à|Ü;õ¨,¥/®‹µŽ[w¸`6¸Â9Ènþ¸?ŽkF I!hRå"ò‹nFÝÃwÇZ’ÆÐjzM®öCi-ÃIœ¤žøîzÖê£rMêcì×+KCiˆ$ŸÂ º¹ŽÊØÏ %©^ß…K¹µ!i ùK·qçÅPñ#˜ô9ÈäõQýì àûw¯gžÐ¹ä¨^v)Eâ –Ò´ˆe”»‘@û¹Øþ•º!K.;q\lk:ZiÄ$q°c““–ì6ôöÏjî7æRñ ÷Åc‡¬ç{›W¤¢ÕŽ3^Öç±ñ_+*Gƒ°ùXØüÇá]legdŒ‚Ž t Œ×œx®ánµë•FvØ6àóÈœtªVwSq¶ySŒ¥¬?:]RR…ˆ ’iÇc\^ê(ÛiÄ.NyèV¹¨u}BÕG—{:N<Ãøž”´×w2ßÜNZG_/$g×¶qŠÊxŽtÕ‹XnFÈ’æI¢”çd`cÂ[=>«§Gˆ­ãfx”–*£°ã'ñã­`Ãk•Ur]v’Ç®=GJ55 шO/B…õQù×#Fèú2_ùÏÿ\cþo^9â|G©{]={ßòŸþ¸ÇüÞ¼gÄåø‡SsÑg‘¿&´§¥ÉŸCÙ™[Œ–ïÚ®¤r¬{¸eüÇåPØ]Fá#}¥›åòIçZÝÖü!&™wÚî’ÞVP̹É)ö¬½›nåó¥£;}>I,&´„Ç›tµf—åUF1ôÁµ—6‰¨C¸…¼±Ó‚1úT15¡ž[)†ÖXÃ’x]¤ãô«GO[h$t?(·1…ö5«²V2м®xô°ˆuÛ¸£$ªÈÊbàü}i×wN³È©lÄFTuêh“k×’ùï!;³óc’jíÂ#]ʆÀàwÍ-Í×cOÃÑ}¾O0(K¨@ ²¹àõÏ^½=ã½HßíP YIû¡À8úsZ¾´[ežh“&h”àƒŸºx?çÔM&{³&[ýÞ¿^)U²HqÕ˜‹­íÜF$•²ã1¶Þ õçß­e¥”“Ê€£[8àãó?•t×vñE.¤—B8¶nËã;øÈÈþ5Ë<<Œ¾{!<ŒŒçõŠ•¶.×ÜÛÒlî.-o ŠB…™_ ’Yz;™¬ÍJÙímàF‰ÑË2ß)Ç\þµ·á¦6¢òÞà‚ÒFÞ¼ŸóïU|P’ ’|¬…œ2·ey­!+»X–¬TÓNc„ú>^8Çÿ^½7DÕ¶ Ï\ðGoJòý/sB{çòêšH+eòQUGrE_Q-‹õ‰‘ɽkkÉ5«¸§ž}©·å mÇ\uïŽOÚ­iqÇe¦êVÒ£¤o²&ùI²2=ñŒTl0ÛÚÜÉ4’©¶ˆ•>X|®Ç· ùq\ó¨å3xÁ!ºe±Óü^bÔ¶Œ¾,+Ôê׋®¢Õ6ˆÿ¼ŠV‘Ž~èÚ\ƒÅgÁw#Ï=í¬¿Œ3ïÇn=©6¤×NÐ'9âøè9>ŸNõÏk³{ébíÔíkiC*DcÂM¸Ÿ”Бøvª6ªñ«Ìà°½I8ä` Ó}A¥ ù$òREÏ ÔŽß­D¾ZáàC=ÆnsÂgóÒ©!6P´d‹[ËpÍ÷Ž0€ûæº ØM-ÕIJܰ JÄ `N1ƒÇ~µžº¬¦uETc7o+Èì?Æ®[2Ç ì3\Úq‘“œàŽ€àÉ<Ñ%dwgKw¦Z5ËE$6’¨E Éo‚w`í=sþ'ðÖ¥e$¶‹öMì˜I~^½Gùï[w–bÖ1ynmn)$‡ }9ÅG¬ë2d¯Ùo^ðŒ¬àäg8æ±W¹¤­cŠ‚ÝÚÞòapÛy#<ãÒ¬iÓÛi®äo%H6îã=*•´±O9ßæ1 ºM ƒÎr:÷íÞ¬Ã:–¶Ûùì£å8'žüÿ*Ù­ Ó;ke±[ˈ´Û_Ý£à³&<žüÓ-õ ›MBõ®,ÚD+ò.Õm ž>ŸN:V-”×&[›V|¾wHÌ1÷±Óñö§Kyyôå¤HÂÆÂ@ñ‡Æî}Ž=MdÕÍ4 Ì÷Y{}5`9„ ÌOõïV#·ÜavÓ‘›$¸òW‘ӡѧ»—Lˆ=ÒÚ‚ìË'æ<Aõ©ÅØŠèÉý¡<ˆ»K,»¿Î9é×éS¢)2ð™DÒIq¥”0¥m~ïô®cÄ2YIl/.â®»8#ëù×_ ö“Æb"lÞkœq‘…Îk–ñ~•gv‡Q²yäÊ‘Ÿz#kŠW°ûh¢Õ’Ò2ª÷6â5œçœÓ‘¨¡ »K]Ã;ºŸ™I¯\õüé-ƒÍá«Ï.å]MÔ,oñ`àgéÀíXm¦ÝéFâyFFÍÁrÛ€ ûÖ²D#³MBßÏHn¬UïÞÓ[•àÀÈçÍ_“Á°jpÇ<›¬[¼Ô‰¾hÐà6Ð`µrp¾£ õºº HVRC;›¿^˜‡¿§ê’´…‰£`œ|ÇÝs»§\XµmM¹Tø>Úe2ÄtÉ”¾ÀØh\Ÿ¨¨n|%$0þê~|-¯ ?Ý­¶"·¸dÌ÷‘n Êìãå9Ç|úÑ`êMonà¯jaIõÆúõ:FsšN‘}%ô‘õ7  ‚0FáÁÜŽƒ?…oÊúÖ“j[ûJåc‹«M`§ˆæ‘5kÉ5!©Ek©&Þ2NqÓׯõ¥¥¨ZF‚DIã ·kqŸnzU;¢RGyâ}FG’V»¥á³Un=N3Þ–ÒãY¾"h//Ür¡‚†ãmË$–ól-„sK1Á}»p§¦=1šÌÒåÕåÓÚhTÅæ± Ï#4Ö¨„Àx¢%Ìz–§V<÷dŽ1SÃ7Š„þYÕ/Õ‚î ¶¨sëOtÕ–Òš;$¨v\’}46š±a'’! B»Ûw^ÃÒMAωc$ɪ^qŒïÓ”þ|sYqë!´¿6Ì`ÄäÈÊÖ,Ç’qïŒÖœ2] ÄÞ2ïà.p{`vçšn¡{vööö‹uf—p“ºá®{R»¸YnA/‰¯"nmô©”ž|È^?Ó ïPÇsûI$þ†KmÄ4–Ò‚~ f­éÿm¶™ÞM<¶ÊÌ[±ü hÇ>Ÿï–Q³êÿ^‡qœìøx]¢¹¸ÓmdB Ü[0Û&xù¹Û++ˆ­OÙuË}Eb•¼¸#œnðz=«~K2ñ^+k™í‹yƒauÚ6·jËÔ¼$°h×6ð¥ÔåÂm’Ývõ›š¥"yL”›U²v¶¾¸N€°W9f ýM?W¶ÔîD8HdÛÜŸŸhؤäžÇ×Z­hˆ­uYçIRÐöl6UKKz÷ý=Î4öµ6¾‚öpZÛRœÅ5ÚÉ ‚Ó/Ë’¡p2HWã·éZPÞ]K$ÒÆ,ÊÌ3ß®8éTšxÙäò¬®ñ²íe$œ©çŒU{­NÐé—0Ç:y‰lG%OOÒ²”çuÊìtÑ„nHçDñ¬“<¨-0`Ç‘‡sÐtè>µ“jÛf‘?„çç¡«1Ææ0£•¢C«€xÉ랟WhBÝ GG ·.yç¦{ô®Þš³Šþö„²mÊrG]½þµ£XôµÈ'qÇ¿éYŠT|¬7eÆ3Ô÷&µ.Šy/„n‘Ï Çj²ØÛYÖC#m9_SœƒÜŸ^ŸXºs$áÕvž¬k?LeÙ+’Ab3Ž0;ÒÞO:[+F¤À(݃ŒO¤VÐúZoùÏÿ\cþo^%ãÛ«ë¯ïÜ {œZöÙ¿ä#?ýqù½x—ŠÐÍâ VåGÚ™³é†ÿëUÁèÉ—C™·‚BH÷Î88Ç#ÿ¯^ƒ£øšãR·µÑïãÎfM€w€ßÅø½{šá§³¹v¹Q€ÈpHõöüêywm"J³J’FrŒðzñP§m qR=ò]<^ÇrÊèãþ£¿øzþ­!û6–ªË¸¢*í8ç úW†h5]6IÅýÊÜ2™%é Ûœr:õÏæ+Ö$ñn‘ªx}î¬îcŸ˜ÃE'ÊA,ÊûgéM¾aF§—Y3É{;ïÎç%”óÎîµ§;ÆòÉTî9ëÒ²tÍrÎ_ HÂý[½_’d2¹êÁŽ1Ô`ŸéXKFZGImm{ybÕ Š#MÃÌÚy±ëôª3iúÄSHg·¸‰æBë÷€àr+sÃÓ¿‘+F$ "NQ7Èà¯SŸZÌ™Éû[vïñ{Ý:Ò«¢L#½Š:¸2”¸™ò±¶HÏ$ã©Ç>•VS+:4an$}÷•?ˆµ›—¼Šá·ù3팆$`ã¯Nµµ4ù‘Úå=2CåmÞÀ®÷æ½cC¹I졉UƒCß»¾sÆ ñxÑÄd€ä^ÕØü9Õn/¼PÑMw4È-Ü…bv tã§s[¸¾b•R¯œ‘#B¤°6pp§ÿÕ_Fׇ Œ?Í'ïx`ÜuºwÍMWbéÞút{Qg©óË‚¹;xã~õ¥m¤ZZ-¢ù²k ‘¡f*r[>µ™¤X½•ôá¦ÌÑ…;HSÁéê*Å®‰4 fX‰·±’Æyf'ÜR§µÇSrÜ ago´ ; qk¹™¸ sÏlÕT¹áŠ-¿egP#')’çž¹ã¥Oc¦-•¨’|(Þ,ªœ6TÓùTu •Þ1jcPîÁÎF磫'thGve-l¨RCkæ–U Ž:çŸÎ¶.$gÑ4©~{5cÜrsøþUÑ ¹@ò2ÛÀ8ÎÌp9àVŧö.’c ²R¹Á8Ïõâ·Ã[˜Æº÷Hb!øÿ3KÞˆÿÕ/åøæ—ë§¢<¶µbcš_^”´¥UÅa(ŸÆ—¹¨®Råíe[WTœƒå³t†ì†‘Äøµø‰U uÀǧåYâX’âI!s™Ê®ïÅ>âÚçí÷¿ngûBrÌÝ;|Ùý>”¢Þ?ì´¹™” ©Ïóž Ïò¯&nòlôi«E1Ýa™±;À ÎwIÇLš‘-ìR9(Ò0Ï&9“‘ÿëçž´·Ú‹XiÊF͵²ï'ƒž¼~ßÜ.“"EgŒdËÁr8pfÑ¥ËÄóÄÒ7žˆu,GmßSùÓ_PXï'd0Ř22Ä€}=ñëTô¶ß½¼„±iNVGŸëQÁ–æåá <µ.BŽAÆ'ž£Þ˜jljW³¾˜Ñàkkr[,Å‹6Tn¯áTãÔm­¬­Þky%Rã÷{@T^¸ãŒýA«vš—¶2FghÙ]ˆ?1lO¿­G¢M®[ÚÈ '“œg9#û›ô*Öcî§µ »Mð1ЪႂÃå±ÏéK¥E<Êdóg ¤È¸ç±«ÚöŸ%¦ž°@¢(cš"§©V}­œõëžµfÞ .4ÝÑían’+dá€ó6ÿ?çS}·4f²³¿HŠJ’\º…÷R:¨ÛÎ03õª×05Ù£2&é& î«×n@öãð©4|A|«‘¾ÌÀÝ·ŠØžòÞö |6n>Ò¬ÊǧAþEg{ÕÑç÷v¿bÛ=é')€0 ¦AéÇn¾ãÖ’Æîn|ÿ´BˆŽ£Cž½ñô÷­/]]=ýÑ1À‘Àî!,pF㜌{ÖG‡•ZÈÌÁKI'š@îAøÚÝW#“×#“Û·­<Ì·qÜK Èc·ÿy““žøÏP:ýk=âwÕ'/2†ù˜¶Ü “þ>µ£v±Ûß%½Â"}r¬~öw|£ôö¬[ÔÕ-  ¸UÓÑäFÓ¦âØNTv÷ü«[fò&†[·‘挠ƒÏ?…m®•ÿ„Ê]ÂA2*RNÐ>ž¦³nt¶´Ñ>ÏJ±yË#+3)+Ïê@8©ÝØ{´«±¤V×*–Ì7|ì¹ÇÓR\é1=¤¶‹ªC$¾b°88$c×ÍÁfÏv‰m¡r7…'ORyä×Ag èöþ|ë4Ë(ÈËHÞ8õçÖ›VwîA`¿ÙÞ¸DAMV5a'!þtñ¬!ŽÖÁvŒà+F¸둎}ê8ŠÉá¹OÍ mhó`° x'®)‰kn%L„÷«Œ>í¿7¥Tõ³&=M·Èúœ‚ú(c+L…8ÆAÿÕµdKGÉÐIh¤]Å›<}?.•Î[#Ç©c ²ÊO­X´Ó/&™®­¦Ž(¾t—“Ãg>ÇœtÍNåZÅýZÞÀ'™ ¥¤”´gÊ—h<æ¬Z[A&Ÿö‰Œ’,´eMÛ¸ÍrwZµ«M#Oc+Ûäƒ!¸c&3ŽÓ¥kHú­”Ai ·6ŒªèÅFᜟþ3I¡Ü£ga=î¥rcÇm¶Æ#žÕ@4Öúš¼k“"30ò±†8þÿQŠßÓ®¦º’_*ÕTÊ„M§#éŠoBQƒªëm¥­–7r/%H˜FÐxÎ~µ^(¾ÓrÁmHŠ©ØýxÖ¯[·Wӽ،–[ƒÊ® psŒž ÎðÕÃG"YAy+oP%ºóÆqMl'¹{LÒµtQÓI³7™–C‘ù õç5e%šØ˜üöc´çw¯áP}¨Ì±iæ(Öá]žUY (ã¢à~u%Ü:n’Â;¦p†5g;Iá‰Èãږ㽋vA¢Xn ùl혤'9#€}¹?Ÿ5™|ÚïŠ ·Ißìë—vòpFA9ê03Vtûý&ã|¡ þ¬‡R¬xÝù)—wKgkfò¤pºÜ_peØÛ½³Û#Ú‹YŽú –Û]´€5µÌ’É#† ˨{úöõ®—MÕ.Öºéæ$8#;sžO~µ©$žmÈ‚…‡˜wr8#Ž˜9éM¶²dw·¸ÝaµxÈð{õëRÕÆGVxm¯MŤ¿º™ƒ l3þyªšf«χàKh14B-§; ðXnlqÍ:+/$‡G À?4Ò¦ö–Ò r&ÈP¬N:üßýzž+øuo¼üäzÕ}>9×Í`£<ó×ÖÖ¥C»Í ܃óýiΚv%I£¸ðÌÖ—"â%xåšÕJù¦)ŽÇ¿Ó5KQ•ãŠûXï\çäõ¬í2&Y¦‚h'ŽuÁS¬V×ÌgìÒü fl¿CéYÖí}4¾u±mª2|ç*Nr?¥[XpîŽG¾Ñv“ÃMf„…‚B¤‘Æ7H¤âÖ£Næ­­¼É~“4,ì-Ç9Ü3žzÖíü2 AJùñ’ àœ\¯ÚVvò3*0ƒz·œÇô_È×a)- h®Ä–61–brI>çžµ¦âÔζÄ6ÞwÙ”ÜÏ–Æáwp?Ï¥?µ"6!RT޽>¦œ$Œb½dôGœÕÛ Ò 29äÒŒ{S¹6 R¯ZLS—¨¤ØXóÍ{R ¬êB¢u(‘„ÎÆF?ý+(Å=ÖŠåÇ< ä}}³]«alž-hÙÂC&3€¹'ÜŸÒ£Ò~Ïokq‚²E ã$¦àTsÍy“~ó= kÝE_ì©ïlT¤)M¡B7|§ñ«V6o=̶ÆM‡b©!s´€NG~:â®XÝÉi!E8w xìõÍT†u†ææGÈû¨qÔe5›l´„Óc‚ÃP¶g)µc›çn烚»âYìç³­Ö3.ÇyBç ëÀ"³­#h¤p2,vr6æ’A­]~ÊÖ](Ío„2E²m«Á çž'±©ê™Kb] K…&‰GXŠå°n1éÅeÜeâ›RÇhkÐãžÿ†Em}Žáæ´HåòÝmãô<ÆÃ·5Gì±Ûê†án¥ ’³ŒpÃ=°qž)ucè KS³¹µ6ï02M-±-ÇÈyéíT´ëØâ¶ºƒŸ´î#³"óùcóª÷PÚÇ|¶¢y6yªIÀPFzã®1ÛëŠ.â’îFØG°€>qsÿÖ¡ÅXjWfÖ”¨uUF@FÖ${¿ÈŒQª‹Ì|ää‚àr:kÒT.THîÀY£c§o¥kC eAä´ê1݇˜?JÎÅ\­â:&°‹jbI¦”aŽ+M·{_"¶¹·‘e`;’y<þ^µ«®j7WÑ:ÖÜ„ˆ²»—˹'hè+'H–q$°•ÁK”BÌ åqÀÇéZ­"GSyÔד1üÒ¶Þ}ÏNÀóÖª²“%Ú°Rb‰YÉlã–毴KÔ¸ŸËbä½ù=i¦ÎF›TxDRªB…‰ç­ÿÖ¬[5HÜŽæ´kI–y]„KØFÓ€8ç·5êšmݼ0În«¬Fç¹íøõúUû–³Ðmdˆª´c,€Á^¿_Ÿ¦hz–¹j³ÄþdD’q çò Iu\XGw:E5ÍÄÈwI¸(P·Z¯>“nÓ=ʼé.:±’sÛž¸¢ãFÕô•–æ;g(~gfÄ€Ó<=s‚jˆÕn§³'¿ 6žx8÷ªµÅ¥ŠÖ®ÑøBгdÖ[¨ã…=…ßíp€A é·nFã»ô©láÒLŸ0:¼¬yôCRùvïv‹y mÆI ƒÔÕMÛAEir)e»Lìó€ùûWA¥y6âFyŽ‹œd÷>½zt¬HwÚ^A2;Ë(züýjü“F!ºŽ;È¢e8aI,OsÚ£¡^¥y4 ÷Šéc'•$Ù]“(FO9tÅoß^L"…v<@7” úã'õ±Ö÷U–Ê(ã-G+™B`ÿ{‘øÑmr¢ÛÊig'y_0wŽ 'pVeKe[}mRGpÆßpßÈ8ãÛÚµ`0A àY^R±®¯2AÇ=~+6T˜jÐÊ&gä£wC޵3°k{ÆŽêû”l9ù†îzñj5`ˆ-tËX[<¼Åpæ089¹m ÂÑ ’íË–8Î}½;bº!x±Š@Ð\o7_­sÚ;±Ñ–3媶ã’î¤uôö«JÉ’÷Ðê,ožÎÚÙÓN.²’\‚¿9ì1éV¯Ä†õ®Ù ?vX¡aÁξ½v¡©Å£Á§B`“͉Ê*ƒ¼ç===j+{L]2<³¡Q½÷®C°þ;úgŽõ*éÜm&ˆôû×çT¸·v ‹{¦ÂyÊò:ô«:˜µÖïìÞâ'šÀ'9 FyÏ?Ö™o¨kR¶Aw12…Ü rFW§±éÁ¨5››ÆÖ¬üÇòT³v„ù¶{}zÐÛli$‹qZÚFn#ƒ‹![9¡úT:ÝŠêg¶2¨›¼·lrË÷‡lûõ©,.dŽë34s«F« ŽXT×—¶·ºÝGˆñµH WèÝz{Ô«¡±.4X­|/äI~LBÍÉ,¾á±ÃÍ$oÛ4è<‹Ñ媉'ùJ†PôxàSõv°O ÞMåFÙcãï¼wÇzmµÊKá{‹åµ¼G™0r6°?at¿éóéÖHYš9nK ä*œñúö®kÅ–2[I$Ñþû „üÅJãz‹áü3ÝN`k†]¡ƒ£ Ù<Çp;qŽ8¨>%\gYû2ɉAK`’Ž•q½b[Ð~™¦ùëj–ïöy‘æ-Î6“×ë”Ôå’ëX¸xd bŠyÉì{ÕÏ OýŸ¬­ËꑳRÃߥ@·lÖ×C+¼É9$sùg­oÙ™9&¬UOR¡²_Üü£ôæ¬G`·*v‘L{÷5—{9ÞIò¨yã¨éNcrªòñÜMh@%Ș¬PÛíFÎ[«¬«¼!ù†~îOò¬<ÿ¤¦q„幫woêûòwùG?RB¹-‹m+•^§’~µ,›X®H'’GòÁªQ^Š5PÌOLݾ¦›-ä³"”Œ×žµ.ÃW>œ›þB3ÿ×ÿ›×Îþ:‘ÓÆZ’£•ÿH“¡>µôDßòŸþ¸ÇüÞ¾tñÀó|uª*ÇÎ êI©ÖÚ¥ÕÌ_µ].˜øõÝOŒä`»¨tøkXe¶¤lì·OåÃ&W6q€:õý+?ÊtœÇ"•t}¤’jUîV…Ø£ÕeLÇk# àa:Ÿ¡§%Äíp¨ùUPA 9È·³µæGÚ3ç?x3Âç×Þ°·–¾™‰ ´®yëÔÿœÖ‰4ÑZNŽ@y7p2¹ýj;¢ÑÃ2›xäÄa€eÇ~Aõ⛤7Í ô ûå©×¤~ûf1ö@:vï[M]&b›%±+Óʩ壸PCr\éÛŠnµ+Ëd›,Àg8üj>müœ±>nqæzôéøÕ­RH“Kš5r7ÇŒsóšÁÅ´Z•™k6æ„ol£–ŽþµëÁ âO:ù¤¨Þ±áI$“ÏçíôªÉ´J‘ƒd8Ç®)¯_܆U%¸$ð•—.¦©ÜÒ´•.U¤iÄ`*NðOSÜçëÖ‡Ÿ|“®ÞY÷†Ï8ííúV–°D¯> ÎOoëOR38êAý* µ%²âp<üÀóô®§áãSŽÖ’öúW'vÜ¿üþ•Ö|"?ñZ·ôI?öZ¹-F¶=¶¼ øÊÉ%¬.1†cÆOñ¯|¯/þÀÖ°1iwèsnN?:†ì;\áîµ JM¥'„÷!K.<ß©ý)úeíÕôowtܩފYŽ0zÿÖ®ßûZÁÿB¼ÿÀsŠiе€?äxíßÿ­K™öTs“ëlÖ®¶¿ž¤ó+ŒõëÖ±ÄZ¤­)tBÒr>\“ôük¸¯ÎtËÃÇh1ý)‡AÖüÂosÿ²Ô·&TtG?¦¼ÑM×6òË:Gå’O€ ê{sí]õÇɢ諂Ù©éÈî;û×<þÕÿè vð0“ý+¡¿ŽUÓ´XÊ22—ù°EkCâÔÊ®ÄHG”£>´ Œõ¨‘ÎÅç¡#¯Ö”?\zúW¤ž‡ Z’àŽæ”{Tn|ã4;Àv۷ך´Xç€=¹¦˜[BN:✠jÞ gëJ®®Î{R¸XåutK\Æñ– ±÷6 ¯Êi¶6‰e ‘dÊŒåŠã¢”4ÝdO&¿¨ˆ§)˜ÑTàðyäwÏjŽÑvBåË3±Žnp¾½ó^uG«;iì‹–âÞÝó ŠÊ'™rr0½úô¨ ž;©fx2bfÎöêÙFëùH<³¦Ã±&‹8#î’·OÃ¥Ke¸{añìj’P÷úV]M;~×,÷>H„yQÛ´dŒÄ.wg×=ª]PJq§Z"¤82NŠØÎTm$Ÿ|ãó4Œ¿Ù¢ G£6nÝ{㑎Ÿþª–÷rèW×ë$°€…aëCÜQ©$–òËy'ïLqmÁÎp­Óñ§hº[AªÚâ\±w‘— •$œõÏ"µí£InQ%HÙV(ùAÿ–léΫ”x¢ÚXƒ/™b¤¨è‚ }~ZJJí̧ugÕnú(`V"CÀÈî{UkkEG‘$€ tù7È>`· ÏÖº_ÙÇp·¼ÑÝÛü¤ d§?ʰf—kÌ`[Ú¨ §flö¥{ JÛ–tät¸d[s!+Æ×ÉÇ×­l<ë;Pȱȳ„ʾùϰí$Î%IÒ6 y ®OÅ^x/§µ´ud“ͼVq“Ï®i[©LÊ{I´öÕuX÷…`ú‹G1!7] êzÕ^蔵;;I¢j剛 p:ç;Õ7{yn5Ù@¨öêYHço_®y«°Úµ×œÑ; ÇÌsÑTnç½`Ä pß¡™¤c÷‹)ö¥b·55æ»H4¨o&>b$Aà±b~\g¯'¥tµDðôRéñof_6MœqÇsì1X[¬., ±.H>Ô8àtÏ×éÒµ4=Pi–ÓÙÅ%•·‚N8Ú1×ôî¶2?á!Õ‘d‚å‰V%@b~^{~½sPYÞh\_\˜öËæ|ä8T÷ïúUÝlH¯g{p¼²l˜)áŽIè}EH!µ‚;‘Ðä®7çÆW¹Æ §rUÌ»F‰<= ›’¡U¸c»žŠÕ$qÙ¬ÃÊx¦QÁo~Õ]¡šmÃɪÈ÷×¹³Œàú…YþɹпÙäueYP0VëÈ¢eCa°ùŸÛ‘ùJD%ÛåÎàqãÓ¶+Ym,#·ÒÞöÑâç2ùƒp}½Ç¬»;ø› ‰¿…åAf?×ô­]jÄ]iBõ®DkidêYpvòy#©ê8ÅJc±q<}á¹/–ÁV7¶+c‚}³Á¬ßXZ›õ{wòæðмÙÇþ™®éÖ„°û|@Ç€3 dgÎNHÎk¾Ôm§xt‹³²ÇŒ—î$uÁã§LFxÔŽ«4Sù¨Ÿfór9ýz{T·–ê’Ìí!ÃõÚ3÷†sŽqUV#q­\3lFêÀmàäâ¤Y®g.ïkn"yv.ÅÆX°äÔìÆ¶(["ŽuÞÌVÆ~«Ó-×õ¬­.öì«xÖveŽ3ò0Èv0?ýU´Ëj4ˆ(<ßìù™Â“Œï>õ¦DSIµc´î‹æRƒûÄÿ…ZwD´iyÿû9—Sx#‡‰>\’sÏOñ®®ÛTÐí4‹w¿Œ6ðT?)íž?+úÄ]ϧm½»Â'—h-¸;ý}ª¦£µÖ©u4þCˆÜÆŠç;QIyÇ@8äóBW¡ÑJþ¼„6›/Ù°Ï–r¯ðô¬ONž_ZD¬­™eÃ7S…Ï$òxõ¬k{8¬õ„ŠÔ Žê&Z¶T0Á݃õýkr']Ò!™G—&XõÿÓØ MXiÜì‘‚´d!Àe\²œ¯9ÿ늟CÑa»Ó¤:®¥¼#‘òà'åÐ~T—ÖBËL»hS2`(fää°ŸÿUszž™qµ!ùÕQCF"p g ϧÐ{Ô¥u¹M7ˆ´‰­ô{—·–9,Ź!ÆÕÁÇúsOÕ-¡ƒL¶µ²N'‹3:·@9>§úÕIíä¸ð—q&KÂÆCŒå—~?kÞÚÍoe¡¸'ËÓäv#ƒÈäÿß< -°®qºKIî…¢FJrÅAvL :¯Zæ/õI®/5)ã s¹HÁ'Ð~žõ×x#ûê-R(l‹îØpI¯ç‘ïXVÖ¯¬j‚,0M,m6àÇ¿6qØàVɨ¶Ù“½´0"i"Žá÷`´EG>àJ®.¤XU ñ…ËcÓJõŸx B¼±£{©”¯šò’¡xÉçœ×'ªø*ÉtûýOIÕk{G!ã{v]¤“òƒÜô5+ì/fìrfæS©˜Èu vž˜Tö—>a’3œÅ·g³ØóØéÒ¦±‘¢ºó‡E,¹®›«hfÑ«-¼6©ˆ»£RvI¿^:â¨ÌæGûÉ´7è:Ôº¿V±·³òY¢FLó\Ö,%žMÌÇwô'æªNàO O‰Q.Hõÿ8¥]£cŒ‚i-—䈼¨­ów9o¡²>ЀL½B­&3éÙ¿ä#?ýqù½|ëã)ñưûö‘tÝúb¾Š›þB3ÿ×ÿ›×Íž4p§w"þð£ò€3… ÿ,R0óg #Ï+œžIÛßÖ³ïõ¢uGŽÚÆ(¡}€†6æP <ã9ÏçWd›ìט`#"eòË äm‚?*ä©nt¨òèLWýÌÊ–›l›Ž8=)·ífý<ÆGÞ¹Ùì‡óéVïtófçÌ/¾Rù äã¦z*=)Øëº‡Úmònd0¨'œ…'?qÇèªÆpר¢C1 ©=Ãß… 4+¦ìI`·{¤¿'p'8#®~µ³§6ѧ¤Ê‰˜ñü<5eKzñÚ¬²BP(1§ÌÃŽ _±)4#d“Œ9Î<þ7 ìTñÄðÂ/WH9>ìÕ™á8‹Clë’Âï>¤ã¤×§†O ´ls  üÇäãÓüj·…/Ú[Tò°ÁíÛ°íÇO¥5ð‰hΣNi¡YDfGó¢Œ íñÜ ÁKxú½ÜRÆÛw18 Ž:ÕÍÄÉçDä3°ãî­RÓåytÝnç,­<Ňã~š45î¡™"™L`.F[Ê9÷ük6ïÉŸû6M¹™d]¬£§#>Ÿ¡íZSËpó‹[˜ÄQ0Wó]Õ—ÿÕÒ¨G 'Q¬ÑÈ ¶²ô;±Óé‚ ¥mBèÅ)5¾©kfÚXãóSqd, téþ{ÕË7ˆÚ1Ÿk ÚYÆU ÃÇö‡MŒLÀ"ȼ„ÝÉž¿oÇ3iþŸteÁ,ǵ¶¶Ügùþ”÷²¦§=i¸Øø]S3\6@ÇP{õ§[=Üšš«M•gû­ßýz†|Ý?‘y­ ´2±uëô÷­Éo­íî-ó¶Æ›CžÞ”ç½…L»MFê;Ðì±ä¨Übê{Öö°|¯ ß W%­˜„ާ¥P°‘.dŸq>\A@ •ÎáÛ<Õ¿ý²Ç×QÈUòÏï ü n;sQr´<ò]†I¾I×2(?*ž‡ù5é²"Ia4›|Œ‘çpUÿóY®Qål€ÿ¤Ÿ›ïeùëÖ½6ÒÕucæ‡à]€¸%pQ~oÒœ¶%j̰Àjòylˆ!@áˆ^zdúúTò£Neu—bÅÎÖ9äþzÕX’/í«ø¤…FQ·Í+ŽzûñVâð<ª Xœ÷œ1ÇoéÇN*ovRØÂóâ6—ݘ 0³~.+.ÎôK¢ÙÆí0UŒ2€ÃƒZwQDšUÜ…”¤.¹=ù¬»b‰¤Yì1¶"N²cŒzV‹b^çIq;Z6—l’K²XÔòÜ •ã+ÞË{•,Zv\²¶üVõüjí¤¡%bG“µr9aøŠçÒMÏvÛrŒÌŃ‚ÜÞ¿_Òœ –ƒWañŠn!±´üìk¨ÖÒF׬£ÒHÿgf _Ü?ã\œãÄ˵~EÈË8dëéÒº¶{{ïY\3•O±»QÆ70^”¦š,\í÷rG<Ž0 ‡žOQÏÌø…b:¥Î÷fsœž~P9ükª¸…šÒì·”c1܇$Ý¥rZû·öµ× µIèý@`©‰r7d9ðŠÌHÓÍ-èÝ9ëÚ¶µÇ#Á÷÷m!2}€”íÊx qߨ¬—x¼).Èßä&áü<ÖLjçðƒë*Ä@r“ÏëBÝ #ɼ'©M¦Ý\Ë BB l¬´O?t^ 1nÜ·Ÿnå¬dmŠ>u;z߯­qºS˜¡¼~HsŽñO­tžÉñöÐ0¶2í#¯ÝÇnkJ©(6b›½QðX?c½Âóçs좰õ¾µø©Áy¦KnÑ«¨ ן0Ÿ_S[ÞTKk° \ž3ÁùE7ÆwL¾ÔÕæþ=Øcc^R·:^féŸ<ªÇžÙãŠè<RklYT¸‹1†’9ü«•~l‚I÷õ®Ëá¶Ÿ¦Þj“¾£š#@Ñæm‡w¨5íÇTsMzœa´‰Öᢠ).W‡nyïÅy­¼mç#•8ïÏl׬ÝiÚMæ*ÜmR«#"4Äpöð;Šò´‰¦–ÎëzžkM·!k¢$Ž˜ð¼,§;{ RÆŒ¡FÂÍцzã©«hw‚™â cÉç§4×Ñ® L­ÔK“ÔdçóúŸi¹>–›þB3ÿ×ÿ›×€x¯Â#¼ñ†«qo¡_Í—.ÈénÅYsÁkßæÿ„ÿõÆ?æõ½´7oh·ùñŒ¼{†à¿OÇõ©Ü´Ïž×Á^#1´gÃú¦1þŽÜsŸOÆ ÿ„Å#xR$wäJúµ]9,b¿7}–^c›xØÃÔ†žš”—¿cK¨šçnÿ(?Í·ƒýGçïE˜î|ì< âœçþýG?õîÙ£þo‚?âÔ¿ð«è‹]JÆúGŽÖî)™ ܨù#ƒú‚?JµÛ=©X|ÇÍÿð…x§§ü#úž=<‡¤ñ9bO‡už3övÿ ú8Í”B]D…LIä¨ Ë#ó§Q`æ>l>ñNA_j#Óý¿Â¥ñF9ðþ¢3ž–íÅ}ú¥Š-Ã5ÜX·`³|ÿpž½ Moq Ý´wò¤ÐÈWC•lôŸsXùÜx'ÄçþeýOñ¨ ñHûº¢8ç÷ _E£«©e`yÛǯù¥;ãK”|ìùÊ/x‘œîÐ5ÆOÙØçðÅHÞñÎÃCÔí›f?Ò¾ˆ¥§as6·ƒ|THLJõ =>Êä~[k²ø]áÝoKñi¸Ô4›ËX>Ìë¾X?.Hö¯`¢‹XNW JZ§ý­§n&ût]§úöóF"ÿ{Ó¡ü©ˆ·üý)j´÷ö¶ÍMsM9ýÚ³ãÒ›«§Ên|»ÈIµœÇ”9å½:ËÚ€-g=)j½¥ý¥üfKKˆçPpJ6qÆ{Ôô¸¯8ñLr7Šü:á¬e³Žß;õ«ÐÖhžGdRñczŽ«‘‘Ÿç\v¶!¦šÍ$é GT ÷\ñŽ™>¸éÅRÑ‚Wv<á-¼?˜Î¯¸>ÐÇŸ™²xúŠ‚í ;Ö ª0Û– IÁ€xôã§»ª¬7—w²[ï‘äþöBWÌ9ëL󎪿ï"‹Ëm6)$l“ äþ}¥tÆQ¶§3OšÉ—ü?k¬ê:·Úµk˜¦TÌó ä®Òº+{ FßO¼¶·kK¨þg‰•Õ¼µÎ2;gô­2ÚÞœY¶X Hy%ÆæÎï—ŒŽ£¿jÌ×g‘[d²\+0ÚK"+#±N½1×8®iÅ5¡Õk’kz•´ö–Ýl-ŽJ@‘о0½È®1^8'–{e+,r3«€1ØwíëD·.×wZ1&v>£ô©Rs¥Ã".Ñ).WËb 2x÷Ïn\U’¸àâÛeö²¶¿Š -bUî&g9Œù‡õÈÍOsmq¨ø‰#†DÊÉ eÃ0@ üê­¥ÕÄQ\[[ !iòÊ àýã‚wuì:ð]ÐWV[¸înÌQpw…UÉÿ‡áS=vµË’ÛkrJ÷h€å7($ü¤RqéXñj7í­\}’íaÀåFíÀã=?»+»æÓ-MžŸGÄbI|ÄÈOÍÏ\ñœtŠå+缺ºžR´™ächãü«9"Ô›ÄV÷¶¼ ó6ñ"ÊFNxÏ ¤½i›ÃëmÓÞΛð79Ïâj vâ OP½Ôb{Ç`FÀ~FÂŽÝëÇJuÍíÕ¾•m`ÌEH];+ú®}1ÍCM$iwb+95[™RÚæñO”:3÷°{z ì4mw©]Ë$jÛÙ¦wŒìùLý+”¶Ô&¶¾cgiC¯»1çÿ¯Shþ/Mòçe´l·r•0È* àOZq]D×CGâ:ÇÚ:Y‚9¥ @à3rü« DÒu[©.bHRYaÞ.àNGçãRø£Ä«®jÚky?g~VÜ r}ÏNœWAð¸Ëzu;—”nvùÙTÜ÷ÿõR“²m +S*kmVÛýþÝdB,nÊFñzg5Dj„¦ËużnØ 0Uäþ•Òk÷ð>¹s0’UvŽ6 Œqƒü«Y-¢»¾biµ* ž0FOéúÖJM¢š³p ÓtÓö˜í–fÚÃ/ƒØgôýj–©kPÈZP<Ê>p\ƒœôì*?…Ôna·2…Á\þï`8úv­™4ج¯M´w5©\•çhä÷­/hŠ×fÛ5ë@dµx‘ÎK<<\ûRÚ륭«¬vð–]ì»1–=AÏa]Œí$ŸÃ0yÌ¡b™q°tê3^ 4sm`äÄdñÚ¦.èÓ±ßA©G{yjfŽÝ›ÊOÝgvÞs€?JÝ7ZLnâk$Pyâ1Û§ò¯3‘m"žvóÄ„3Fà#ð¨žöy.ZâÑ’œy 2o'ƒÛúzúÐãq¦G3èó1ˆYDÎOËû¯qíYÚþ·c ZK ”cÍuv‘ó09$w®+NÔþîÁy¨$M™µö&ÓøŽŸ–µnø§ÄÚf­ ik ïŠî9|Ò dg±íR¢ÓE]XeƦºe‡‡'k!tßf‘¶³0Æ[¯ö4Æñ$z°KVÑ<”¶yÈìvgŒóõ­Ý2('´ÒÒâËíÙ+zÎÙü}ê´¶Žú”AdÛÊÈRAP>`8ëõ§7©1NÆ1Ö›AÔ§Óç‹`®â$Éà‡ðû×cªëÚ1š7¸g’;ˆA &2s‘Ò±u=kG“Äq´3™_ D¤:çðªmâXt™¡‚-8]ïù”ºãè;Ž”ã&‡¯C †×@Ôå‘-¢Ž)$‰mÆ9ú÷ë[:œ#u’rÞX*ª HÝp+ŽƒZ{;ÿí6´p«!£NŒ È`àtã­_ÖuÛñ-ÇölÈ-åØÉ†Ã/ËÏûqÓš™FÎÅÉXÄ×µ[i|Kqwoæy¿u Çz–ÂèêK%³€Ç bdB¤ãÜýG˜lþۧ‘](ŸíEˆdÎxþ÷áS]£‰‘㕾ÎFãêü=*ÔUŒTÍ-SEt[›o6xä‚ÀDûá!Fzõë\ͥƜ--¡¸ˆ*³¤-¸œ§©ý)÷×ÚíÙµ½ÔÝãw\ïû¬=@úóUþ˪2IœpÜBµr÷Ï\ÂŽ[+çq¸žÎÒëG»}­ ÷‰´úTãÂzIn”«M.H{ ×üsT-¯n4O雇—$—K’)Pn9¦FÞ*LjµÂ²µÆ™0x¬Aópâ¹ÊûcÔé¡^Mq¥OimM°xÂà`çp}9Åpª/w¹Óž§-âcà«‹3>ƒ%Ì ¼E"­ê3Ÿç‘ï\Œ}sÊûŽ?•zWü#šü#kxÑo˜1„q€€F}z“É8®é~[y‰q÷€ºsÖ½ êȵ–åÏi»F3d§îIéôÍdXî…» æ‡Þ·¼YSc.±ˆ¸9>Õ‘§[=ÅìjˆÇf\ãÚ¶’oC(&c´‚H=éfáÚyùý?úôAe,’>È®YˆÂ•$qïQXÙ_^Ë$³\<|²m\;W?±•Í\Õ¡eÿŒÿõÆ?æõ‰qáÁsypïvÉ åÜ”VdTl±È+„mÕ~ ÷Ú‹‚‚Õv¬@rÛyã'gýóŠ»Å\¬žts¿ð‹¼ÂÚ;˘¦ŠÕ³0óVBœº2ëÈàB<©i,)<>l’ ¯s‘»æef*OÏú~]>QÈìÈæî|$.fžO´Æ<ÒÄ“ Ý&eWć9`í0¸…Z³ðìv—°\£¨hŠ„?uctÛ¸’q– Îzb¶ š_œSPvtP:uá¸Ô¥KÔŒÞÆ©,g|$'<œn•]¼>cÖmõ Yâ‰mbòb¡$ªl*°<®HlsÈíÔi™Îx~ÓròÑìØ{DaÁáË§Ô Äï ¾ðÊ»¤_ßÉ&‡Ýá—' *­×ƒ¥FV¾DîwdŒ”$¦ß0†s‡ï‘Ïó®“ímž‹OK†nÂfÅ΋'¿¶G¨Æj8Î1MkŽÃ£Ù±ó­‹QEfXW7'„ÌösÁ.¡$aãòâ0ƪƒ# àîA|äwŽy®’©}®\žƒéM+‰»î´ËË“m½­aui"’Í6иÜC0Àœt'éƒ,ºcMo©+Ü%þåÞZíÚ€sÛ“ÔrI§ý®_Eü¨û\¾‹ùUr²yŒ¹¼.÷³‹Ûµiš!b‡h@ªêÉÎà\zð1Ž´xYmÍ™‰àˆÚÈÏ”›ƒ·!“!zŒ’{œê›¹=ò¤ûdž‚ŽVÈà O%b{ˆ «!Ø!dF*›w>wäîÝ‘ÏçYþ'·ŽYlYå‘JDàŒ‡nk¬ûlž‹ùW1¯[Ír,6‘ä¶yîXÒi­ÆÎ{ìqÅ䀟úf?ƃeoϯ1“ýjа¸êBr½Iö Žr«ÇûU<ÎÃäW¹Jî·µ+ö£,rB<È€qÒ™¦[Í.‹næ%DŒ¬0ÙAƒÛó§Þùb8íä•A‘ªœüÙýzšÒ6’Æ)UEBOÍ‚¿çüjù´%-Zè`\Û›+ˆ4ës 1œÆ<äzýy­„ÑZ„P¼*‰ØËžO9檈dÖ‹+«y Œã“òÿ>Û{É8EÁúUJz!B+]Lã¤]cƒÿvP1ŠŽM*ôc÷.ãmt=ù5©ýŸrsò/âE9tÙ°ÅŽ SY¹²¹lf=þÈŒi8Àlá°zŸzfÍZ2Fn‚ãë[ dD¤|ûJõßÏÓéJ`(çÀÇ \ýï•ïÐ-æb¬úŒXÚe¯ú¼ÿ1Å0É9%š(Ùˆù‹B3ë×=+ DB388ìßýz,`ÞIèOô£Ôv{¦svwC rŒƒÁÇOçBN±çl)’s“Ï=;×PîNßð#Ne!¿ihÕ„¯{œÍÝäWPÇ Åœ r¡ÎqÖ¦Òµ‘¢¤‘ØZ,jüœ¶áßò­ï(gîGÿ|/øRxÉɆ2qÙ“е‡vÎlÝ[Ëq$óZ‡g;†qò““š…ÒÎYÝÈtÔ)EQøóÿ뮤ÛÂG0Eø¢Ò÷­¢#<å.T‡wÔãî¬læÔ ô-,rü¿s€0?Ï5{íq½ûEÍÍÉmxˆàzõö®„ÙZ¶±ø¦>̶~Μzþ4ìš°“i•uoéŇØfÔ'|Íù0Ž£>õšºvˆ±“¦Ùä0oÒ¶Ž—`ÿzÙO=y¦aé]¢ ëò³ J)l6Ûw1O²™ Ïs A§iw7Ì0@Ÿ­>M6ÅH1ßÄB (ãÿ¯ÏZ×&ž¿Àê:ŸÞ”béüü’ßTíp½Œ_øG¬f1ïÕíÕcmáYÈÏåÒ©jÚT"Ù~Í";ïW+nÈ×Lt+Æ_oŸÿ­MmÄ«.é ½ÇåŠ ŽÔfÔ-¬4µ±¼ÁôøÃ@ ótþuNßÏW3µÔN®p[v ‚sZZ\‹l%2¢Ä"ŒŒ(É mØýÙæ_Æ¥Å6ØÔšV(¾<úœ×ïyh­)ÉQ(ã#§J†+g·¹2Ýù7eH•.>èU¿…iÂ9n9ûLœã°§`B1‹©@Îxª— ›{¢¶§Ü>øå"9§Y89d]Üäõ'ŠQ¥K˜©«Û8*TgŽ=:w©O‡ãéÇõb˜t+t¿ˆ"¦Úܧ6÷)Gau„p™#“cùîHÇéOÒ´ûË{(÷MNŠW OùÇáVNƒ6[´=²:SF‰uÐ\ÆyîM;}J3è—3Î’ «\D¡y“Œ€:zj§=µå„rq!(xŒdp þu´tk±ÏœŒOa!Ïì»õÏÊ­‘‚<ÏZ,Ç-­kúµå‚éwã‰ÌªÿqÁ'©äô­K-3TšI—íÈL°DŒp ¹\ú€0HãÒ´ÚÂüˆ]ݾ”Ãk|£fp?1íÅ_M'Ü©ªÁ(ÖšÁ,çK[PSÌŠ2Cebàäóϯ4ËKÝKI1¨¼–¦VB¤#£~aØ“ÉúÕÖ·¾l“Äž­œ‘Å É<ÛÈHèGlP›Cr¹vÂþ¾xg¶˜X5¾Ýq #k s3QI²Öñ þa|¸‰ç Ol £¥Uòf “¸ëÀÅ3.¿1Y<•›‹{•Ïn…}"ÏS´Õ a^1‘ :)ÏæG¦j½ÝޝsªÌˆ³¾dʳ9:çõ­1—qêp}±M%VnyÎr?#ZÝÚÆO}ÉØË£=•ÊJ·(êFÔÈu<·¨úÖdÚU寣qº#„HÎ&Qæg‘õy˜tÜr3ÎzÒ佸Ÿ­%t2„:ŠÛ7‘‹ û±+¨ÉÿëUÛ;R»¼·7ÍÁ½RUv qŽHù²iáPàüǶi ÆÃ9>½iI6îiÙYi¬Û£À–K:¼™ùä,8à?\V"·¿I7.Œ’u\>AätÅYÂãï÷õ¤!NNî>•Jëm äï¹C[Ò/¯.`)fì ¢.#qµ[ŒÙ¬ý3FÕt{Ÿ:]6i· ¸UÎ êk§¹•6±ÊNþÀÔ?:±ýã/®*®Ø¶,YøŽæØ«O ß2dˆ˜æ©KxbÔ.ïtôšÐ]Éæyf6Êç“‘‚:ûÿ:”<äïéÃ:y¸»ÁÿHó×Ì?ãJì§nDzMÿ!ÿëŒÍèÏÔÏSHFh¢ºæGGÉ«QŽ”QTÈÈ«iÐÑE&ZZ(®S¡k$žOÖŠ+Z}Læ&y¥¢ŠØzSh¢ZÚyz½¼¨Ì­äÝÏP¼ùÖué+¡è'$ÿĵŸ\g4Q\SøÙÓ‘MNXƒéFryö¢Š î¨Å'˜ÜsÖŠ) PìG,iKŸz(¤‰''ÚšÇôÿ(¦;ñÚ”1fÁçZG1à¾xõÁþ´QHbFyíüéˆÆ P3ÿÙfotoxx-12.01.2/doc/images/watermark.jpg0000644000175000017500000006605211701011016016352 0ustar micomicoÿØÿàJFIF´´ÿáˆExifII*ntŠ’(2ši‡®( CanonCanon PowerShot SD600´´2010:09:21 06:39:13!š‚@‚H'ˆ0220Pd‘’ x’€’ ˆ’’ ’Y ’˜|’R †’ò  0100    @¢ ¢ ¢¢£¤¤¤¤ ¤¤ ¤ ¤<2010:09:21 06:39:132010:09:21 06:39:13m]Ñ)_ )_ .¢þ"R^x¶H  Ž h®— N`˜  EÀ"ÐJ\ÿÿ@ÿÿÿøC¨è_Ÿÿÿ ÿÿ ÿÿÿÿ¨æ­D/ j_½Ø`ÀúôIMG:PowerShot SD600 JPEGFirmware Version 1.00+((ÿÿÿÿL+":êÿÿÿ ("DZb ÀÀ ¿î³¿î:ÿÿÿ¡X*@$¯»E¥»@"?[Èÿÿÿÿw«ÿ(C ksrursvtsiת•/ @€ý0ÿýÿýÿýÏÿÏÿÏÿ111 'Š €àÐþÿ0æ€    ""  ))'$ -,(# %*.//.*% %*.//.*% #(,--,(# $'))'$  "        II* ASCIIthis is an annotation¸ : ©v ~ († ùHHÿØÿÛ„    !#"! $)4,$'1'-=-167:::"*?D>8B3796    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀx !ÿÄ¢  }!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?Ô•ö0ÌnFz…ÍIŽÿ|šf,Âûþ"¡%}E #b¿ÞVŸîœ=é2‘JuÊç­K¤Ëä^Æþ„]J{v•r±øÖÜÈr„±#®~STu¬6¿zWî—8ÕÏZKšßjÛ›ÐO–ý.aÎäI1ŸÖ½#í Ž’9àDé[ÒøQË_ãg5á${ª%¯°?V¦kZ:Äæ7PÈßqˆý½tCc;êsÍiöBcÇEFãŠæ—ÆýNØ|+Ðê´Í+ÿBûAs»·¹¬™c:*]Dmas2Þë’¾ãÐÕÚèÁJÒ~§sl«1%GåUž%þèüªK=Fh_Ë>^ÜŽ~jqŠÔÀ†Dã¥TuÁ¤À…×5Zhƒ)‘h§,XL`¥A )(æ¡–uZB}¯TÓ§NdBQ‡¯/ˆ´ù-uVg?ë—p·5ÍY>~nœ§E¹-טȷÓÍÂçnìq’ØÅl]É9³‚åtX×ÓÔ×E/•¾7êc®»>stÐC¾~3¼‘ŒgÓëN´ñ]î­y …Ìâ)›iaœ¯¸æ»# Úÿ#'¸kïo{åÈC£ ?ˆzÖkŠã—ÆýNÚ ô:ë_eE›å½+~òÆßV¶%H$ŠÑlsOI?S€×n;ŠÕ3šJí¿3fëVÓg´‘¦‘ »€öÆI½Oc^}¨^éWÑ›6dRqó²×7gô¡µaÂ2æQêÝ’õ=(¥E³åéÓŠÐį*U9’¤eG\TN)ˆx5NhóÚ³e”/c/as@ÝŽNC[Út+o¦éÈ‹´}Š2F1ó ýs\õ^ÇEÙöæ"YØzßš‚æôHÀd…Î ô­©´ ŽzŠõœÖÒÎNéc„°ÊïaϽGa¦ÜéºÒ_Ú\ÙË{·ÁT}õý*Þ%Fwq[Ž4y¥enil©5)5)š[¹!ió±ŒHUr8Ç$óÇ­s~2±ším#€ w,Ÿ;9ÇøVq—4¯Ò[5hÛ¬taáÈo<5¤ËnÖ]y²y›…Á\p1·ÛÖâ³j·òÛåL™7}0*ê6¢í¹X(Ó•xª¶öw÷“ØÑ»Ô-®ëØ$PA!d·dÔdzc&²%žÖpâÆÎÙÕ2K€6õÆ=yþUÃi½î¯sì\$"”#JQN*Úê{#Ç´ÿ#UöýáèkÔgçä2¥T•)1”fL®Â‘H…ÇZ¯ ›4FeÕõ”3g¸‰KåJ±¯µhͨ Ú­³(Xâ ŒÁ_ò+ ÁÊK¢7„¹bßR»²* c•šEV;ºÙã¯nµJïÈ“cÉw+¾pÙã cžkN[|¶3m5Öï©Ìj’ ¤… –ÁÚ²‚@lvçð§Ã,©v²9#iÜU¬ìÓZ“vÖëf^ñS1µ°µ·•’áWÌ—rÄñÓÚ®µôÚƒY$Ñ/™˰?ìóDRVèiß­÷c–Y.x¨µÉxðJ¥‡Ù‡˜ãÛéNo•_p£yrísŸÕío.‚¹–d$)È ÒŸ ^M£¬Ò,’݅päý3QíZhÎÕ„œZSmA½OzµºIâã§u=TÒÈ›\÷œ×YãHµVU©`Q¸Àµ›þ‘¨YiЋ„Ž$PÌØÜFz× ÚÚjHïfŠ­(’FƒhÇLŒÔzT9ò»¶—™¢WVÜÌÕ¯¯uS÷±¤n¨•ØÁˆ9þ+/TÓŠÀ²ÌfÈU|²ËrÝG¯éWÌŸg}ˆå×]1F—kpÏnò¤fÜ)T,À³·Œ³-Á–õ¯”… ‘ОÿÊ®\–"1 …õ$v¬äõ4­§Ìè4û@ õÐß‘c¥’ï2=¤5)ô]–Žë¡Áj³–*vqÇzÉwž*ébäãg÷ž×s –3y‘Ÿ¡ì}Kkª$ò”(TËd޵už!Ÿ¬ø¿FѲ.o¢ÝŒìC¹¿!Íqz‡ÄùnØÇ¢éÏ'ý4›ùñ©e(÷ÑWWÞ¯ÿ! ö‰ü²‡å¥Dš4VM–·uÝ æ‘ªò.ZÚÏw0ŠÚ%‘º")b]v‘ðÇT¿!¯¤Kû†ùßþùÔŠç«V0ÑîöE¥×¡Üè¿ôm$¬†»yó.û(ãó®‘‘UvçvQ\§®õ} M·e·b¥Ì6Ò®'Ž)¤Šù×3¯bCˆ²ÛÚ\•!2ãèPu…yð«SžÔï5z=,v(.[ËÝìÏ)ñ“pg:„6·0|æ1ìç×ô¬»EžúC1¼Þbì;Nqøö¯¡…XN׋QøŸc©EÚÎïddÝ#-ó¢8uC·ºHþ•¤âêÀÀ×h©8þ¨íZÊkDô”öFqNîÛ-ηMº2ÜDà‘]gÄXRÒÆÉPõˆ+)k%ämOá~g—_Î$#ž‚¨3U¥¡-Ž«ñu®Q­ô=åÏI%íø åÚë]×.?Ò¯ÝðÇòñéÇõ­70IG}YjßövÄ3¡™û—9çéW‚*¨ À P+Ü›M»µµÕ­ÞvÊ$Š\yúÖÞ¯{¤ÂI%½œi|%UŽ;‚NT½û};R­JvJ/•Ëyv4¥8´ïªOcb×ÄÖú ÛZÚiÉ _•öêOqç©=«^ûâÖȦËJyWhb@Èõ¯6X9NWæ·6ýN†Õ¼‘~ý²ÔKke<„çqR:üÄ€ ÉÔ9ÔN¡¾ ÂÆ3[?‰>yåÊÇ­Râ´3:o ­¾Ø£TÏ ¥·Œ(zæ¬À‘äÏz§{sö{Yr§“»Ù®¬ŠÚ|ͨ¹ÀX|¤ùäe wÆqÜô«úñ5ó±‘3{ŸÖ·œÔ Úé¸F-M_¯CJ&fŽry?Z·¯êrOáý3O¸ÀxðÌÊHo,óôéüëŠí8Åk)lu6¬ÛÙj‚(%gx”¶È‹œ ÉÀÿõU6ÕTœ2?ïWLp¼±Ý&÷Vês§~U¥juTŸü»NË͙֕¡eöž¬Ä»¼ß2ÅcI+à*¯Ìsj¡¨iú®Ÿ¶K覅_¡#ƒíÿÖ­+bš‚v}r)ÒÓ™¡‘Ï\6;®G?k·ˆµIì|‡¼Ÿ`}§„÷5)ªR’RqÕ\q” ÚM«îbÜjDq2Hz³óU'º}çcÑ@É52—ü’ûÍ5ð¶¥$BA9þÃ4‘Ås§Üù4r)å[¨¬ÔÔ´] qi]›öǦx«.çÉ(ÜÌFy5—<¹=hV&æžïTA~*ìhˆ®pzƒèi;JñÚ-¤¶wVËqlçpG8ÚÞ ÿJï~øÑⲸUÔm,Äl<»kÉ~VìIÏ\×<“£z‘¼Ôž´‘²jv‹²²ø¿|E·¼ðµÅ¬¢¦qÝ\¬¾sõçÒ¼f%[‰%±Ú[§­oó+««½.¬G.¶=áï‡m“J›Y¹PV)Ç!<sƒøb´¼iocyðæööSœõÞÄWVr–!5ðƤcsª1J»‹i+mx¶èÀ¡bNE6[¹î¾\íOAÒ½×--Øâ¶·6t? ÜêN¬ÃÈ„òdqÉ»K]#OÑ ýÊ ØæGäµqÔ›“å_3¦²»ùúŸˆîŽÌä÷~ÃéXQHÓ\—‘‹6rI=kXÇ—N½YœÿCZ)„kêÞýªU/1*¬›€É Á™æ¨ƒ>âpzþ•Ÿ;2{ÓªA’¨…ê7|´Š3&´Jr2;T[6?Ê2)\» c)^sǽ:Ú}°2ƒÎi‹cÚ< :êþ ¶·¶aòEạ̊סëüs¼Ik“má%¬N^äÆÙPÙ8P}²Iü+Æ£,K‹½©ÍÊG\Ý©ßù•‘ÀÚhòÞ¾bŠçA]›¤ÚXL¦XþÑ&ßðõ'-,¾fSjëSKÝ#þê/S\Þ§ªÜ_g'l}Z˜G—W»Ø©;éÑne³1=8¢6Ús“šÔÍ–’æ@9Ã}h{ž9} ’™IåŽlU;‰Ë¶{zUÙAzd/QÈICô¤QL €äÔY9È©,Q“Ö xÙ\²/°¦„Ðûsuá ¯nkŸÊµ´{+T¸-|¬ÊGúûÔÉ®š7Ô¨®ú¥Ð꡵¶š2c•`dHúcʳnumY–Ë÷’²¿5 5ñl‹~FD¬ò9’F,ǹ¨$;zÑ~f+Y–ÏZnàO½Z%ŠÔ­5Ÿ=iÈ$5]ºõª²—}v !9 ­"’ÜSÚÙ‰9|‘PÝ‘qWKbXªŒU™pØþt"š&¶ˆ’XŽ*×¶­g-_£)h½JË|øeÝpqŸ­ 5.8 - 17.4 mm 1 2 3 0 5/1 8 6 212 384 1 2 2 ÿÛC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;ÿÛC  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ÿÀÔ€"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?¸Ç£ó4ôÇLf€#¾? ;{ ãšLgëë@Ä‚€sŠ=úR¨9¤; œúûÖÖ›yu¤ÖpK±fûÄO3éY(9kcDM×°§bàt¨lÑl–1¢ŠÙ¼Ø­ŒhûË29#>õŸk¤_ÍÄqÀ©Ài·ÐUÝoPÕe»·Ó´°Y’,¹DËd±îx¨í¼©ê %Õ/°:ír\Ã¥*•©ÅÙ“.„.t˜ÆÛa VÉþµ¼ðÔ'*³Éß>Yþ¢ºKoi1.&ši¦vÒ¯'„4ébÝõ¬~·ð qWÕœ´~ Ò²©³E9ÄDøVãÔt[™vËqÄ=Õ€F|r2p¾ÞЙp4õ_ufùÖ}×€ôÉAò&žþöáúÔ¼Tz¡¤žÌÊÕì ¿€Àý)zp8¤"5Š8×S‰ñKž2>´„dýh»·0ïïKíý*¼Õ(úÒO?ÅKšLž¨¤“‘ŽôgŽ¿ÇáIŽ1Ž) \ä篽ðúÒrOø@ÚŽÏ“øzRsšpR;T…µ¶zÐ})ÛqÛ­="iRÌOMK•бLöÍ*¯>µÓi~Öu ¬Ð h¿¿7ü:×c¥ü<Ò¬‚µÛ5܃ûÜ/åXʲ[jU’Üók 2óP“˳¶’féò¯ñ®×Bð5ô3Çsy2DPä"üÇóé]ÜÖö±íáHtU\Rt¬\ªKÈ9ÒÙ-ì"€€ƒ˜“Éúš—Ê@~î~¦¦¤$’@¹¬%Mn.vÈÂ.q¶—ʨ¥h¬ngîÂ¥ÏéA“P—ˆ­£€zgÉÿ¾GøÓT´» ²`˜8ÏåUî/­­&»Ecü9Ë~]i§NyŽnï%”r3å§éÉüMM•½ Å½²GêUy?`âöE&º•´.¤lZÙI"ÿÏIqþ¼þ•b3xdGšH‚€sc‚{r}*brzb˜zT]ÇBôcË‚>d#õªóYX\ñ5´2½§³äñF C“)#2è7¾Ÿ?ì?‘ªrxA~V)“ýÙMo=i¸èÄýhö²[2¬Îb_‡zqɼ¸ŒúY—?¯mÜËcwל£~u݉¿¼)ûÁŸZ¸â&¶båg™K>·¢š„ cää~ *{;Ûieól'k ®ê>ëqÐÿ:ô)$R’ u#0È5Ìjþ ²»V{ ZË×oT'ú~ÑO¥îÔDº]c£"Mi$O²kvñ¨n¸Ý}»Y·¾ÓaÕ-¥²$˘G̾įòªRK¤Hmu(×ù8ö=ÅEq¨Aah²XË’Nå'<žœÿ#]thÅINœ´ìD¤íË%ó4¯t«’XuWŽØË—ò›ø¸Î ìAþuå÷6¾V²UCŒœdçŸòk¶º‘µkK{l´»îf ƒ´ú¢ŠÇñN…s¤] “i¶r|—S¸mëÃ8æ»T”d¢ÞæoUt¶1¯Úmž>ýTûН¤ÊJ3uhÈ?‡5fÝ„’(c´çœÕ-1Õ5 ”¯ÈA8€æ´d'Ô¿ çÍ"’Im ý8þt¶²²Jí8v+œöéý(´.É\¯<¹?­2!åY ä þ8ÿ’Ë‘ÚÃ(ƒëŠ—ŽœbÐSqŒqÓ¾)˜ˆO¿ZB9éKœtè)½;ô¦ƒôÍ&@ÿõÑíH:ð)àpzâŽã×Òò}ètí@ÅÆÇZA¨£H4¸Æ) _oJ1ÏÖŒsÜJ>”®0Ãr(xúR…ÝÏó§…ÈÎ1SqØfÞ)Bdzš·kaqy(ŠÞ™Ïð ÍuzgíFç{"ZGýÓó?åY:‰c‹ç€+SMðÖ©ª°û-¤Ž§øÈÂÄ×§é¾Ñ´Ð[ý¢Aüs|ßé[ƒP¬Üäö ¤pšgÃU\I©Ýä÷ŽýMuºv‰¦iHšF¾FXþ&¯UiuH[a˜3ÿqvü…CåêÅvö-M%S7s¨³1ïÎÛA“ü©~Éq/ü|^>?»Ø?>OëGLø}JåbSÖ8¹oÏ ®ÃLðî•¥`ÛZ¦ñÿ-æoÌ×$ñQ[(w<ÛJðv±©élbˆÿËI¾Qþ5Øé´ûPþVºqÎÕùSük¤¸Ôì­'¹÷s“ùu¨´®'ÿM>W¤—÷kúóúW4«·¸Yô-ÛZ[YF"µ·ŽôEÅI,©–EEÄǨmJãý}ò@¿Ý¶Nï¦þ‚Ÿ“c‰3<Ÿß‹ŸÖ§Ú>„Û»«Àç±ËvßôÅ2¿÷ÑÀýi3ªÜ}Ô‚Í}Xùù ¼€‚“9£õbôE?ì¨äù®î'¹>ŒûSþùj(a6CF¾ˆ SúÒqœf„ìbæŠgš»Šõ#šj¼Ò‚P_SÞŸ:êÅbGmŠXö¥Þ0;ñš‡ýjÇ¡çÐGÙ˜¨ÁèMK­Ñ!ò3‚HU$zCÊ|½È:j<žR¬Iòã©ïHÕ™Kp+'R娎ØLlìü°à H‚ù!±–=IíDmºÉäqMŒí½â³s¹J#¡8‡B8¦¡Á‘{õ(ÚìxÁ¤Èß»¾1Y¶ZˆÔ)·Ì”å³Ðö¡‰o—†éÅ)(9*) ¼õ¨l´‡ (˜>¼SFÕÜsÖ˜dLC’èZƒ& àSK`õªÍqU.µ+{PZæxáí°”e-"‹QKsAåÇz…¤÷®fóÆÚTÊ÷ éñùœV ïÄ)زÁC³HÛô®ˆ`+O jq=Ê=j•Þ«cf ¹ºŠ?÷œùW˜K¯kš»ŠK©·q¶Àý*kk×ÌXÒÔó7?•t¬¾œ5©4G·“øQ×ÝøãM‚'6âKœ0(Ú:_§¥s‡ï¦ÊÀ#¶Sè7·æx«¶¾UZúþIwJÅònkbDÒ£ó–Ö ÖY¹?™­°´ôŠ»%ª²ÝØà k:Ü»’ ›¢z3dýhÛø#X¹ÝMªú¹‡à+½I‘ã#!é·§éM'4K5¤Uaã»w9x|§ ÿHºžfÿg )—†ÊG¹Ó“s,dG®IÜ‹>Þë©Æâ8©‡zܱ-޽‡ojÆ8º×æ¹£¥ ZÇ‘Ü%Å´ïÈÉ ?2µIo8iU\…ωàW¤jzMž«K˜²Ýxaø×-uà[…rÖ—QÈpã ^µ,u9¯{Fq΄–Ç£^˜-£Xí¤>Rqˆ¥ï“ÅeRâÞÚâÚÎâ!öC–qо÷3¤\.šeV D¥r¤g*œúmµåª ìšÞâ ˜Ï+Ïó­c̵-[cœžÎúÞÆ+Éáu·œí Ø×+«Y´Z¥Ê(Yɀќ¡àt"½ë@˜iñ¤×ްÄG‘ ­Ãcƒ´zÕË]K¾toá²Ûa*s‚:lΪr5Ï&fÓ“²8ëK Ž€-¬”3’$–P?Õç9ú?ÓÓà¸Ôàš±4©•óâ\n`·bx>•ÛZhºf™ EC*“óy§;‰=ÇCÖ©ëzõ´6ŸlUFÓæ”àDƒ©ü¸çËÏ.Zjå¬=µ‘ægÈb¸=r+gHðÆ¥«°0C¶/ùêü/ÿ_ð«úF™ ¾ÝBîËír\ÈÒ¥¯˜’FAäœv¯H7°ÅioäCûÛ‘ˆ Æ 8Î=±ZT¯+¨Ãq*j:³Kð.›dªÓ§Ú¥îdû¿þµ§w«iº,!7Æ;D(-Ÿ ¬¯ϨŧMsýª–ò‰Î<òÉëÓ&™à=:5µº½’ Îó·•#òvûg¥rÕ¥8ëQš&šÐ»ößêŸñéfº|'¤·'/ÿ|Š’/ÜÈþeþ³wpßÜCå§ä+w­9ÂmO=ëž1ºlŠVöÑYÝZD?ÛŒ|ÇëžZ´’‰*s޾Ôt¦ºö?Þk4ÃrLÐ D®ÈB¿#³IMH—Ù ž)´fŸ8¹F‡a)V?)éLS‰ú€piÒ ¯GJlGrÉžø©æî>Qéþ½ÿݤRÒåS‹Æi±eKéŠM¹Î®})s”rI0r1œŸZ@á ©‘Š@FÏ©=MLtâ¥È¥G˜«µÇ¡¥vn,À³~•qÜÓ Àt©æ/‘²pUFÖ¾8ÏY§>µ —*ŠYÜ*ú±À¢íìŠPî[2Þ˜Ó(ïXž)Òm3¾ñ‡ðÇóӊļø ‚--±üS6ä+hakOd'*qêv­=A5Üp)idH×Õ˜^euãm^ô”†m„ðÝ9üúÔ1èþ"Õ˜9¶›þZ\>ë] £­I$O¶þUsº¼ñ~‘lûOšÃ´K»õéX߈薪 ôi›ú ‚ÛÀ1Ý©*ƒÕ`^3[6žÑ-clnÍ»ôéUþÇK͇ï¥är3x§ZÕd3NÄÿ²cùRÁáß¶ç·òþ;—çòë^‰Q[¦ÈaŽ%ôE ü©KqɤñÖÒœR¡}dÎ>Ûáðë©3ÿ³ÀüÍlYø[D²ÁŽÅ]‡ñLwð«7:ÎjÅ%»BãøæoÈdÓìu5 Ö嶆+ó Ö5+b$¯&ìitÓ²E”ÛíV5ô@¤bX`X퉣8¡N·÷Àþ¿•q¶Þ¦º!çoÝè>•ËxâöH­m,ap²\˸çû£ÿ®Jê+‰»#[ñéƒnè¬ð³Óƒ»úþUÕ…K›™ô3¨ô·s§Ó Útch$±ÖœÇ$šf °[€}=Oà+KšW*ÖV*º/ÌóF»ÿ×?ÈT'¥K$†WÝȃ؂¢jº Ô¹¨Ûê*C×ôªBgmáôÿA(ù~[Hwcw®!¬r¬g÷§ï?‡ÓÓ×ó®Y7(òîÍU“¹ÝëÂídKgäÈÜÙúW5u=˜Ýa 3;®&'™qÉΉof_9AÿËGq»õ5wJ¦¿µ…¶Ÿ{aáyç8l¦›b©YɤŽçN¶}»¥#í3°flgäìXךêÅ,ïRæHg‡ÌhDJˆ$îã¦0G5R9„l¯’ sšÒ€Xɪyw&I-t«@ÂV;Fæù‰#¾F8ªœj]‡º±…¦]ݼ{¬²ÛiÎÛŒ×c2ËþÊ1žøÕÏøYö6²l4w6±ç¾Þ=€éÖ¹MOP¸ñN¦÷“ï[aòÁ@£8úz“J©\" ¬r@ärsì:IRs÷¦&ÒÑ|JÖ ¡²í“€ìõÇ'>µ¡gñ>ÉœG©Y=±?ÆŒƹßqÉöÎ n¤Sž(ž&ŽTŠ1Ó¦åÔÔ¼-6Ìõ­?U°ÕaXÜÇ2²yQÚ§’DŠ3$ŒTd³px²Au£Ü5î—pñ?tÏ cÐòOå]Eγ{«ZÇ=Ô×G· ²ãqîÄä}=+•थ¦Ås#®#³šõ,`I%–CµK «ùžJÌÔ¼C©ÛL`mƒÇ»ÍL4;ñÛŶ¨-/btß##ä dlÔPÞ_O>£$’§•$Ù`8Á®¨áiEmv+¶nÉñX¦îØÉ AŸÆ¥´ø“3ŸßÇnW uà×(öO¨Å,b)EÎq’£Ö¹t;_ ¸ÁÆ)ý^œ¾É-´{­‹ôÛéeŒ,NoºO×·^õ°% ¹ žâ¼™…Âfù }Ÿ½,R6)Ë~}ýk¥ðήÂ6·’7å2(ÎT€pØÏL+ƒä4K¥5'fvF@;ÓLßeÝkzm Ý5äCŒí “ù ûñå„y[heœŽÿuk†z³øQÐåîθÌj7—hË0w5æ×¾=Ôf;a1À=w5PSâiXon3Ýòõ®¸åíkRIûeöUÏE»ñ—i‘-älÃøPî?¥aÞøúÚ0~ËlïèÒÒ±í< «Î»¹‚Ù{—jضð&“åî.ÛÑÛò\˜J[»°½il¬`ÝøãU¸%b‘"ÏE…rMSK/êí»ì×Rgøç$Ö½×MÓìÛK(!ªƒ?X,OzOéN~Á¿‰œ-·€u qöÛØ¡Ö!¹¿Âµí|£[œÌ²Ý7¬­Çä+ ’XâRò¸EYŽe]ø›J¶ý$LG_(nŸOÖ²xŒE]¿Õ:p/Ágif¡m­a„î ó©KÔ×+qã YI³³½)Ïòãõ¬‰õÝVíK5Û*úB8ˆÿâ©ÇZzÈhGcºžîÚÙI¸¸Ž!êìdÝx¯M¶i’cØ"ã?‰Æ ã$ráÞFîÙ,ñßêÔ+?»Ç=BÿPœþm]PËà¾'s']ô7n¼]|üAo²ž/_×ÈÖMÍýåØÍÕܬ§¶v¯ë´~† B >X;»„8?øîOæE5IB(ßþÈÃ~››õÙ á²1u$÷bíÚ£ <¿R8üÎÕý wš-¯Øô¨#+µŠînäóÛðÆé–‚ïS†Üð]²Ûˆ ´rzînžâ½>µÁ˜MYA#Ô>”"Ïüô9üúŸÆ†Én7ÔÐûCa8QÀú òN’½íÒXÙMy' ç¹ì?:å¼ jÏo>§)ýåÓÔäÿõ¿ZŸÇ·¦=&:&ýíì `tõëkL³M?K·¶A÷PïšíK’…ú³-çèX'šk+_ìÇùΕ‰2ÙÀ¹ì)¯´6Åmʃh>¾§ñ95ÊXÃÅ0ûâžzÔdàÐ!ùTOéRžqQ75HLåô_jb°µ“lLFåc€zà×SŒ,æc%ÜK0L${†Ã|ç?Zàˆd9àâ›yy˜ÒEƹÀPrö¦žç“¬Ô×5IõK餞6c ˆÎvŒtã¥c‘;²±ã,{?>õ]Ý[>vHW€­‚Aàä}(–ææÖá®’oß³d²ŸQžÕ”`–Ź_qÍ+cqlàÁ»ád2\\\?ü²@€ŸRrA\Ì××wÍ)$‡,qŽk³ðÔB- $Æ ÎXçÛŠ¹¿tˆ/xÚc媗gùp=Î*_ë6Sxi?²a1ɪK±ñ0^¿ÐUO¶Me›¨e´ Ïœã±ëÉ‹¨\H5="ÙJæÖÜJÊÝ79Þsø\²’v‰Ò—R$­¢XxýÚàg¦@÷ÿhÐà’Gª©?‚÷ü{SÔC?ÞÈ'OV>§Ò–y<ãó!sõûÌ*‰@r pLñÁ>þÃÒ–3òåÏ''¿ñ¾ÃÒœê2QÜ2lð{ž¤Ò…FS³¶p: Ú:{þz”ŒGçå×zä¨åºýk®º¿·6ŠÐiŠŠã)æ~«Œºwx]£ùXòí–Ï={-t±7ö€†>BþPةМüÀíÊ•›ÐzndjPÜÇ#ǪJèÇpÉ8ÏCÚ¨Z\ÝXÝCq&—H HˆükÒ_±ù—7WF6vÎO#ØÈk & VGÕD…È;H$ ¤`zö§Êâ W1gÔ¯eñ0žÒÛìxØÈŒcðàÖwü"‰lʾ\— Ÿ02¡ày"´Æ»l/--渂T†"þr¦>lr2pOüMQÔuí³²ZåP’X‘´ê8ç5¿*åºz˜ÎM»¬ ZéÆ7xÇœ0ìG;yA?‡·Jȶ¼Ø×ÍN–LTe\«‘ÆMeÚÏ)‚5¸i&l°ÜyZ>¶}JQbƒË>òEE&¹kÉ(¶Í)ÇUcM|ª\ÎÅ."†ÜŸ‘ä;™‡n+R×áý„x7—“Ü·p§bÿudà8` §wªØYgí7qFº\nüº×ŠñUçîÄìT µc,´M*À³XB¤]Íùš¼\ÀÏ]xÆÊ!ŠYObøŒ~¼þ•“uâ­J@vùV‹Øãó|~‹Ia«ÔÕþ#ç„v;RàrHæ³î5Ý6Û*÷‘³áŒïoÈW =Ô÷8{›™e_W$¯æø_ÈTãô °žÔ®˜eÿÌÌå_±ÕÜøÊÅ,íd•‡÷Ž?A“ùâ²®|Kª\¶Õ–8?ØŒ|ÿ—Ì•dnw_—-§Þ_Ój:hbA_E9_Ép¿™5× %(ô2udúžI'9žg–Cÿ=çòù›ùSX*0Þ»[ðVü3¹¿ALP[å‹%{„ä~Iùµ*( „Qü‰üi gk4õ¦1ãޜƘÝ8 C DßJÕUàòÄ~½MA,"U* ô«pÀ×_ºs(ä/sì*£¯¶Ñèx:­JÎώ•,²-Ü!QPU‘ÜÓ¥d˜0Èæ«D¬$Ø n'Œc=k&’5M±J¸ÜG\+Ð-!û-…µ¸ÿ–q€~½MrÃK‘.,¼åÝÞ׋ Fyàw׿ß8v5…FmMu(j-æÄÖëËJR!ÿlÿ$¬ë©~ÑâRtä+˜Óžl? ¿æ…×-YËI;ý#LÔ‘YV¼°yòà´‡s¶:žN}; æZͳo²LÀ9!1ßîqÈÃÖœ‡s.ÕIÉÜçqÐõÈ ÜÔ }:šxÁùG+È”uãÖµ$z¹wÆ3¡cíÔŠPHÿtuàa}°:šC‚}U»ç¦[ߨS³“óc’?Rxϰ¨9¤X#bNG*1뀣۹®Óó^@¿Ù–Ñþã웎~nÜ×xYL[ò3–ÏP7æ+OÃ^$Ô4‹ß²Y|ÂDË)è2zý D êz¶§¥¾©gä<²,ˆ'£g¯×¥p:Þ™wa1‚HØ•Á,™çÒºíQ¾Ö¦†PÅaEÌŽW@?ƪxÒýnb[~X7Ìߦ?Ï¥KÕ\¥tìy\Ð!•dMˆbW!Y°#>µs|î¬rU˜ã€9ÿ9­/ÍRÇ`°n‡,{ýpeØi“ÝÈVÇPq’}p?­RšŒu3i·`¶Y.&UÉò“—cÔz­túV¥><Ð[ÕrÌ»Œc® wç&¤ÒôˆíQdq–ªõÚ}O©¬I¦êï1Á +r@#÷¸í\éªÒiì_Á±µqªßÞ_I(?Á’?$ÀüÍTP»ØFpOðç-ùF3ùš@Í Á_1G\æ@?ô¨„®÷/÷G#ò]«úÖŠŽÈ.Ø—n‰è0‡ò\·ëCm ½‚ý™J¶,0‘SÙò«ù(üMLÚTÖð†4jz–4?‘þuWB³(±`ß9 ÇÌ6“ô-–?•#;ðOF~¿›äþB®%ª¨,%R_)‘æ'ó¦- F% \÷TQÿ'õ¢è Η“wû,ü~¯ýàÞ¡~AúãòZ±ö;„þò†OÌã?­WxæVʦÓÝ—ÿ­–?UЄ$”Ôã³?#ð-ù-#/ 7Ì ÿãÿÀü¦y_Ž$cî“ø ·æi$ìáýôË~¢€$ʬ?á¿ únÀü–šçrq”ìÝÿǰ?%¤?{žw¿MÍù‘MRA;>Wà¼7é–ýE0Ÿ#æÀ^Äôÿǰ¿4mp˜|•í»îþ°? h ÙÈÁ=È7é–üȦ§Þ;z÷+÷¿1“ù°¤!XaFâ6ö ÓõÀü”Ö†‰jouX"u-|ì09ï×…¬åÀËÆ{²ž?«W]áK?.ÎK¶tç @åÛÔûž•͉©ÉMšÒW‘¾3ë@°™Án?Çôͦ“Ž}8üÿÈüëçýNàfÜ屨zSI¥ã­4škÓ$b‘³ d@÷íN=ht±¯c"çéœÿJGAyk÷cà1Qµ<’I=úÓƒL’j3OcúS­4It¨ÛƒRjR€;‚¼Î})§;IÏ5¥©Ø‹+·„ºåOðóŠÏlM}¬]õ<&šb&(VšÀìáÇw©×®ßZ 7\ñCWVrç† —:œ{Ü”¶Fe^ÊH®´ØòkÂðª­Üà`’©üÍlÌì;¡I\W÷:᱓u9êW;³åY¬Kõ–Lÿè5 #¶©ú_§juîÅ‘yû]þÁî± _ëNoŒ8ãƒÓó<µa¬Ò]¸äðIŸÅ»óéOL'$rë× dûžM0É ÁÉy8íÏAR­ÇMÇ=Î{{ ЕˆÎX {ð1îzšR[nwrþ‚=ýhRN¸<¬xãHNÔ Î ǰÏÓ© dщ¡ùOFý ëëÐTÞa.¡w3F Å×8þ¦œáv7¢©íÓù©<%Û©ÈÇ›0Uã¨POõ¬k;@qÜéF£} ·¶¹ò£›FkQÖ.--ˆ+¹Ú<£ž;ãóúÖ…Ó·bOéHå@´ sé\ªí®¥ú~“Is4ŒÍºB îïžùÍ[ÑõkÈ&m’«a¹1è0?›«.5ÙÒŠ8Èû¹Àô÷­ þËLӤř÷nä·§Ò½«ÓºW¹‚~öçLÌÑÀòºídŠƒž•ÄÄ¡e ä1—“úð*忥{¨·Îÿg„çä^3õ5Vq…öêhÃaœSrêMJ©½ ÂîF›fI±p?_åNþÓ¼lù2yXêÈÇõ­­F÷A [ÇeEz˜8#šå@#yÅuª1¾ÆSœ—Rì7˾mÄpØÈWn‡±ª·Í;î•ÞNx Ű?€€{ ÷âš@ô­T1rd¦êHÔª€õÇZŒÜœ »ƒ{qùÔG¶iƒ$€:ö£‘3.Gu<Œn$ Û“ÍX7…W’8ÚÙÏ^¢³ÑÒ5`È çµ"3)ùF{ô¨t×b”¤^MYHÙt¬@à‚€ËŠyšÎD)J®s°ýÓõƒøUH¢€»yÄ’ ©á½J–Í˜ŠˆÇlòµ’/Ú4\ó%呞r£#þùà:T•/¡™Üà~@Öa`ŒÆ)v‘ýÖÍKú4n# Ã8š2U¿úõ”¡m#Rû—›!B6ìúgÉiYA;[–ônOáE§ÁJ%³‰ÑF_jáÀ÷Áüéû˳hþ ÜÇ üɬ®l,=ÕÚ@€\…]Ç‘ùäÈW¢AÛ‘&vÆ¡FkÃ[FŸn`0Ä 7èNÛó®„“^.6¯<¹VÈì£UqI,z“HxÀ={ýÏò¦1ËÿéúÒç5ÀlÓÏ4¹Å4š`!4‰£>HME1%ÙY0àzsÒ”ÃÍ<2KÉnWTdàb‹†˜Ç•ŸµC$¨Ÿy†OAԟª(b1×0ÆYÂV8JÿW¶±Í*Æq÷OÌÿ÷Ïø×/¨x®iX­¢yc´Ëÿ€ü+²–sèe*±‰÷/;³9åÎI¨œ©àŒS2AÎqJ9Šú•¡ä=GGlò d‘ ÷ Á48,G{w§ÂÈ2’G¹è> Ô÷›Ç uÛŸFÿ{ÐØÒ6ôH¼­&?Y±üð?•Z¹G r3†C“ú ’s¼Q b4 ŒûT:­´ë¥ÀKl\0åˆÆ1ô&¸f÷gdU‘•:ú]³š+v•³ýéŸåŠq}ÌIââÝ¿¦§˜§öƧ„Ü T‚2z  .J—  1Ó×ôè Dº9n0‹Ó…êln&¥d+•îä¯ =½i‰‚ÊÇN}@É'¿°ô§‚˜‘Áö'ÜúUˆ{.T‘‚9Ús‘ÉÛôìi8|6~VÇê}ý‡¥ õoϯóêi¤ÆÐyñО‹õ=éË™6A#±É 'דßðí]F“¦}ŸÁz|¡~uÝ#ãÑÿª¹-T‘iå ùä3Éçå^,Mg¢µ¼1ù ¶ÄOR¥yØéÙE#z1½ÎBþêg ›†IöçúW%ªkóß±HQü±ü#§ãëZ6ºmþºÄê†H|‘ò IçŸéN¼´Ó´ÚÝdºn…þb¾õµ´­vcRýv1´5ïæ7$¤KÉ`9ÇNåVn-ìà/$0ï7-þE?%ù=OÖª3bzW±¾§¦¶E‰.PÚ¬3ƒä ý>•FF)»!ÇåZ¨ØÉÊã÷=©„LRÅ!=ê¬-D'µ4æAÅ8 ìΤ8þB‹ˆGOSOòI_™×'£¨¦™@ûv¨™Û¾~€qHa½•‘C\t5#nû¸úSŒAbPÿÀÆIhxž?âLBΫ'Ü ø x¤O¼‡ê)°:ã›î;Úà’Çož¥9eYKe@^¸ ÐwçÐqTÃäu#Š@Ø;ÅCC, ¼Þd´ŒGÒ™ouo}–ÚU‘HϸúÓˆÞ¼ÖšvgHÒqÇZM!"š_Ðf€S­)8ö üƒ'†?¥dßxƒM²KrÇðGóðp§)»$K”Vå¯&hY¬‹°òb“îçØŽ”מâ4-*@Š:–”à~•ÊßxæI2–PÇ÷Üäþ]?swš­åãn¹¸yzÇà+ѧ€›ÖZÒ¯±ÙÞøžÎWÏó˜ #ñcý+œ¿ñMäû’ÛÑž»>ñú·ZÃ-–=þ”m`yãÚ½ xJpésžU¥!$w‘‹1,O94mãÛÞž¨I!W'¹«)j nýrq]##sIÑnµ{Ñkl™vû ð=ù¦jš]Æ‘zö—I¶HÎëúÔv¦¡¤k¡bŽ)ô«ÚÐÕ&®oÕüÉNwä};WUââµ3”Zf8#UË-ÓÝÅn@m§&ª”b>ç¾;Ö¦ƒ“R2uòã'‘О*g%aÆ/˜è É'±5Qˆ“Yµ‰É1«‡aèoÓpÕ•$¥[P»í ³(ú»Çè+Ï©±ÙÊÖžq'ÞšBäûç'¯Ò¦1íQÁ/ÉÉ>ƒßž¦–ŠAyÁúà}}iê?ÍÁ‘Žy$ãצ*–ÂÜ`FAÏ÷ì¿­9U\ß.Iày>Üô+‡‚çØ{}GSODP1ŽœqÈÏNÜzÐ!ŠI㌂ ÀõÉè=‡zD9Q’'ÿB=>µ#ª‘ wñôõ¦íΪ“ŒžœžÙã ô¦líþÛâ-.Ó¨óT°íÀÏNÝëÔIËù5ÀøF!qâ¶ŸªÁ7Оþ…[þ$ñ éQýšÝ•®Ügž‘S^622«UB']&¡ ²·‰õ+KI$;ØÝ¨Š:žJâä]²;n2;œ³š–k‚øvB÷ IffÎ3ëïU u2ØçhàW³ƒÂªQ×sί[Ù\>dÙ×~µ#8¡dýàm¹9Î+O\Ô¬õ¡{K$µXã Á?ˆúפ‘˹™ïIQS[ÁçÌ‘â8­xbçÃÆ¸xÛÍ]À¡Ï_¸Ô[WG>Iô¤'9ép=x§ ©“œ’pïT@TT$³yÎ8¶IfùG­R¹½ÆQáž)NJ+R¢¯±;´qœ³dzgUäÔDý8ª.í#eÎ¥7O¹eU½ãM-ÉžîW'îŒöêi¿i”ž£ò¨Kb—9ã¥eÎËåDéy ì¸â¬-ÂKž~ozÏ [¡v¥’'@¬Ê@nAÇZµ6'_#osj3§­CùmŽ~‡Ö¦#¾p+DîCV!@n0Ã9ý)ãå4 ƒŸZbó!È;×ÓÔå™å$+Žv“PŽ0sŒÓ²3ùÔ´;šöšô–ó†ˆwSÁú×]¦x®Úìî×Ëï×ë^tÊrqƒŠrJñckAž•Å[ 5:)×”OI¿ñ.båÛóøž+çÇŒ™û%¢«vy'ðþºÃ·Õ±y %Cü 9Oþµ2ïGÞ‚âÑÁWÏîØò;uÿÂZPø‘¤ªÎ_ }¯jZƒâk– ÿ8_Ë¥gÈËšVãb’¤v#ƒjãŽÕ߯+ÝG3m½DË6vç𥠃‚síOŠ9&ùbŒœzv«QØqºgÛì¿ãM´‚Ì©<­²5ù½» ²¶kÁ˜zçÿ¯S3Ål¥c@>µ$²ÎÙh=©ÿëÑ« ¦hÕvÄ»±ß¢“œ[9ì;~Ç”"†8Eõ=Tå¼bHˆm¹ëOH‹Vw¾°—ŒtèC/Þ?†Mz6¡ig«Ì®ëµî7ê!KuÂŽµÌ|9¶Ýuw~:Ûõ»p+fÖæ8§ibKken-ãmœ»´˜b=zTMl¢ÌkïÏlþu¸E_P¹_ñ_Ç#ÜUy"ž+‡(S´BŒ¡k¿ygW²³K.Y¦# NúŸåYÏu§Ë¬>qe$d›c˜(1ÈØä3ÏQY(»—tŽK*¨Ò0ùPn?…b‹w:\Àä››µBÙyýZ½6óÁÐOÇ˜Ë ey‘?Ö³/|#*i‹ q §G%J¶ß¼Ù?)ëÀMØGñ`{ŽÃŽzÿ3ÜÒKÈìXî$Ÿ|ôãÖµ.´ë˜Ù¡hÎyV^ÙÏÓµ@-_ËßÇËßó?Nýª˜BƒÛå?– üº 9ˆHÙ=óŸ©?Ò´EŸ Ÿ—ý¦ãÛ¿ãV¢ÓEÁ!¦q– v$õïÀïMŒ& ]oÇžüõ>”#"ùlͱrvœÿwõïW'³ØÍo˜‘y#Ö¨Üea“<àdïÏAøw  º£ƒ jš¹¥gXbVÎ rqúƒ\ìÉ«´Îä³¶érO?ýjƒ[¹dÓ¬ôüýÂòÈvcÿŽùÕIÈ<ï ç·ëJ…%Îæ÷"´ýÛ"i[¸<Õ [û–ýKs>2;g­R$õ'­zQG È=Àô¥Ï_äi¹ÇΗ'?wúV¶$‘%1È2òH«WúµÖ¤TÜÜ4¥05R8{ŠUCŽ{óÏ¥!©47ý£Éì)ŽÛù8ô\αf9cÀ›4Ï;Äã°¬§QD¸ÁÈuÍÛÉ•^žµWpN8ñÇzL{×$¤å¹Ò¢–Ãx¥Ç4£¸úÐA>ãéQr†•ÏÓLMÔ`š“@h^£úÐc*Ø<zµ=Ô×Ip¸v¢£t ˜#¯¥2Ù„7q»Œ„pÇ=Å4ì+ ‘¶Žœûж…¤…ýá×úTúÞ¥g©OÙ`€NIœuÇÒ­ÝÝèB!²He /™ÈQêH4F£ºÐN:¸¹É© ”%X`ƒ‚ }ñ]F"ãàÐILJ÷ö£4†”˜ÇqŒýÓíV`Ôî­­åXfy½ý¥ËwÛȤ³àm'®+ þܘÊpŒÇ6qÔ ã5ê>%òÎŽåÔÜ6C^}u)KYܳ ‘’>rjhµf<ÔI–öLœ€v‚=Çô©l/~̲@Ãä~G±¥·±’òG'ib€ÀΨÎ6Î3Òºa¢1–ºÌGô¨ú9¬Ø®fˆ6å£U¨®&’'–€ÝŠÞ5b`龄àü¸ä‘Vôý:çP¸òm£26ÒÄ@2k0\̬s&9ÆsH—÷0ñÊccÆPã"«ÛAì¤Ë2¼Q»…^Þµ^}LV ?¼y?…S$±é–=éHàrÓÖ°fö5$µbX—s’{“Í5ŽëSˆÉ䖬Ƕðdž,¼Úœ½Èo.?Ãÿ×ZMÑ6íÿ„n¾¢F-üêÚ&x8#”}¢áãÕ{WªMîÙ²·cóÁú.¢§ì;ìgÉt'ñäW ªi7z=Û[]ÆQÇ õv ÷¯Wt1 ãâTê=}ª WK‹Ä:A·pÄ`´.zƒéô5­L¢í't)SRZFW®=ªæõãnHZš&M®§HäUäN‘^ºwG+Du†q‘MÏ4ùÏÜäL'Ú¬“I›ÌŽ9zoAŸ¨àÿ*iëÏjm»n²ã’Œ^ŸÈÓ¹ÎI®ˆìe-À䛞”ॉ*¹©}ãÓšb"UbØEÍH°€2üûTª qŒ õ¥ž9"¤`§§ÒŸ·#šhÓð"Œ’;{T”†ËS$‘b;`ã ¨înãƒ*¿4ŸÊ³%‘å;˜æ¥±Ø·6¢Ì¥"\´zÕ#ÎI9¤íÅ/§©nå ŒŠ\)qƒÅ*«1ùF}iÞÜþTàŒãÛµH"QÔn?¥Iœ§Þ¥MÇc´×a†=*gŽã*T«ŽõËÄì0Aä÷¢ŠÊ‡ÂT·:ÿO,©ŽFV]ÅYNû¾ŸZõ jwWÂH®\I° >0ÇëŠ(®‘=‹Zä²[Y‹˜d)"0x=•Z³'û=$$–e,IîMQÐ’Æ0;)£ï7áE EŒ×)ècò©¨¢€0üXÄXB ðX“ùW®’šMÀ^3€1E/sXü' ’¼© óȪ—1dúÑEoöLz•qµ ø«2´„ÀØÚ™ÚqÈïEÄf$–èI=>¸¨ÛÆLQE!‚±É>‚­YB’ ìQIìeÑÜêLgløM¶ÔüOmÚy‘ç%sןéE_á²ãñ#¾yêᥗ’ªÑ@à@”Q^*7{Š:ÔðHRcA„¾‘!Jd~?ƧµP·@à¶?:(¬Y¤O5ñݼpx¢àF¸lb=Èþu͸<ÿw¥WÐQþô9'ñ2´¿}Gû5Q[™tþ`Ÿê§ô54q«uàÑEo ŒžãÙÊ£ ö žh¢¨CäQNU'QIŒïØÕ]JâHCÚ¤rGZ(¨{ŒÚQÆ9ëE‘`9ãÖó ( ¢†` XdUÀQŠ(©cBcƒÉëBò=úÑE!ŸÿÙfotoxx-12.01.2/doc/images/manage-collections.jpg0000644000175000017500000004122411701011016020113 0ustar micomicoÿØÿàJFIFÿátExifMM*JR(1Zgnome-screenshotÿí8Photoshop 3.08BIMresize sharpen ÿá 4http://ns.adobe.com/xap/1.0/ 274 273 ÿÛC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROÿÛC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÿÀ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?êtm'K}OwÓl™šÖ"ÌÖèI%I8ªz–£àí*ñ­/à°ŠuŠý‡w§!­þ@:wýzEÿ  ­ogis«jMqkÌ0 ‘+6Q\íêÍm¡¦ê^Õ/RΠgpJ§Ø6ç'’€tµý¤ÿÐ.Ãÿ“ü*­Ý¥¶§¤=µ¬±ºpZ8•Ig›Ž°­zM¾€‘KûIÿ ]‡þ'øQý¤ÿÐ.Ãÿ“ü*âM±bëûõÿµe¨Øê íawÈBœ6ÜôÎ>”^C² ¸Ót[hyôÝ="A–cl˜Qêx§6•£¬fFÓtð€d±·õÎ*ó²¢r@É' Ì"`,ÒFÿðoÜ‘žÃ³×ÉÏoÇîЛî&‘¯™£O M™`ѸܭöTäzô¬{·Óà»–ÑtÒ° ·Oð®¤0`AäÞ¸­Uñª]úhk:“’Z3z4ã'f‰¾Óaÿ@=3ÿÓü)>Óaÿ@=3ÿ×ü+;}ëm>çO°‡bô—údd 4}% éºý)ŸÚšGýôoûôŸáV´ h.ä¸ó£U9#ûV­Î—f¶W-öqÄ/Õ›û§Þ»)EN ¹3Ь”&⢌_´Øóÿ-3úw_ð£íV8Ïö™ú÷_ð«š,°®‘8¹ÿUq2ÂÇÓ óø³4QOcmg– µˆ³}×;I?­b¹Úº‘»TÓ·)“ö»úéø¿áIöËúéø¿á[XÚ Û2m‚‡ïB…mš¬–\]XM š‘â °ù}rzÒýçp^ËùJl±ÿ —ÿ€ëþ}¶Çþ€Z_þ¯øVœÖ«{#Ci½þȲ¥»¹bHï§áGï-tÅj]bgÿhÙÐ KÿÀuÿ ?´l¿è¥à:ÿ…_¹¶³6ƶ¨’Eb—E'qlsš¯¬ZÅÄ«‚ªþb2È[ü0úTÉÔWÔ¥-¥ÊWþѲÿ •ÿ€ëþiYÐJÿÀuÿ ÈßI¾²öóîoõj}ŽÓE¶Óu+&žMNB$)…¶O@}=êäú>”°HF—bSÿ.Ééôª^9Ñßþ¾OòZÚ¸ÿyÝ?ʺc)8ÞçH¨Í¤|빿¼h¤¢ºÎcÞtûû; JwÂd´‹fóØEÎ?:‚{Ÿ ÜNÓM=»HØÜÂV\ã§CK¥’ƒø–Ÿý*ÝÜßÞ?s½ÍÆ >·'†{q"gk¶äq“èHüjçöî“ÿ?ðßU¥¹¿¼:77÷çHg,m|I& 8’rM]°»ðÞš®¶ÙÛ¬„œn#¥nnoïÎÍýãùÑp±•.³¢ÍG5å³£pÊÇ ýiç]ÒNsÏûU¥¹¿¼:77÷çF©—µ£EÇíº"Œ*ƒ€s·Éks}<éªØ‘÷ÎÙ¥vÛ›ûÇó£sxþu2Š–åÂrƒº8²ÛÿÐ[Oÿ¿ÿÄÑö[ú iÿ÷ñ¿øšï·7÷çFæþñüê}” >±PàÒ‹>V·d™ë¶gÿÇiÅK_µ ðAùý+ºÜßÞ?›ûÇ󦢖×%Õ“Õ¥÷ÙbÙ³ûfÃns·Í|~[h±Ú5›¹Î¯ŒúýÚï÷7÷çFóýãùÒöq+ë :í™aÀ&wÈý)¿f@TnÄû¿¾—éòñ]þâz1üèÜßÞ?Î"öóò8{_.Þc+êZ]ÃßK!ÇÐã4Û°nïêMgNYl‘×h–»­Íýãùѹ¿¼:|‘µ…í§{ž|Öq³}gOf=KJäŸüv²®Íƒ[±Ùýß9ñùm¯AÜßÞ?›ûÇó¥ì¢WÖ*zlРC­X…óŸðÛGØÔF·b Œç?Ûå¯BÜßÞ?›ûÇó£ÙÄ>±SÈóÑf¡ .·bõQ3€ ´ŸbPžXÖìáóŸ–Úô=ÍýãùѼççG²ˆ}b§‘ç¦Ó'']²'ÉžNžŸw¥4Ø®Ï/ûjÃfs·Î|~[kÑ 2XÆÍýãùÑì¢X©äyÙ²9×,NFÓû÷äz}ÞžÔb$I®X8LçO–½sxþtnoïÎeúÅO#Î?³bÿ Æ›ÿÿ‰¤þÌ‹þƒoýüoþ&½#sxþtnoïΗ±€þµTæ|?y§éz{ÛÜjVŽæS 1¹#QÜJ×MJÆö9£µºŠWXËS’­_ÜßÞ?eÝu³’OúŸúUÙ%dbäå+³À袊ë0=ËKÿ˜ýƒOþƒnÖ—ÿ0ûŸý*Ý®ynj‚¨kžpÑî^ÙÝ%w©SƒÇ8ý*ý! ‚z‘œÆ·yp&1K¶ßPÄZ{ ÃRûåˆÿr§Òn®í&³Å-¬÷÷1…ØÞbÌs»q§L 襲¤(¶Ð…€æ%1õ_O›*Z[F%xbEG.£1å¸I=}ꮉ³9¸¼C«Ë§ÁkÇ*+FÍ ˆ³…ÚNÔmäVÝ…åË è®ü©%³}»¡B¡ÆÜ”“ƒøš°4ëil­ƒJs!.\ç<ñÏ<ÔëhÎÈŠ­!Ë0XûúÐÚ°$îröþ!Õ^À]Ik Ç:Äb•£dH™Ü.’w9èzTm=ÌN²¼3LÚ‰_1”/ú;Tn8¼ÒÉ ¬0ïx¢Hâ&\ì#rK~O>ô®·žÇ1uª_]éK<–».4·ºA 0h)mÇw_AÈ©ï/µ¶šÕî!Iàš×lñFÊ¥]‡ ¥³ØçæçÚ®ZéºFm>¢íæÅqß$± œaTœŽ šÖ’ÒÚA"Ëm ‰@Y ;Àè®*›HV¹›}¨ßZ@Áv‘"[—À‰‹7m XèOãY×óMow¨´íÄ«cpŒ¨ß½}ÝÄκ3mnm¾Ì`ˆÁ¾VÁ·˜éQ®Ÿb¨l­‚…؉p9ÇN™æ’`ÕÌ NúîïD¾¹g…`Žc[¢7) \–ÝŽqœmèG5·¤^Ib.eòÃ;·îÐŃ“Ëý?©‘ôû™¦{+v•øg1)fúœ{ ™"Ž6vŽ4F‘·9U±é“êi_@³¸ú(¢‘AEPYw?ò?õá'þ†•©Yw?ò?õá'þ†”tÁ(¢Šê1=ËKÿ˜ýƒOþƒnÖ—ÿ0ûŸý*Ý®ynj‚ªjÒI™;à “8^6*ÇèWŸËš·EHÎNÆ ë•‚ †Ô¿ÛŸ‘$ñŸ/ÊeŽnüõïWâb|"€ý«í¶än%À'ýÐ>µ¿EUɱËŧÜÏ{O&¦[»‘(2¢„ Þ^0~QŒcϽV†m^I4¿2ä G&lH¥°û” ƒåÎK`÷®ÆŠ9ƒ”ämå»Å´FKï·9¹2¬ŽþINÍ£îcîôçÖ®xf=@HE0”þ÷?xÇQ…ã¥mÁgio,’ÛÚÁ ’ÿ¬xâUgú9©è¸ìr° H0)ý£ö¡ßk21ô;<¼ü¹ÎÜlíœÕ»»?áhn¥™ãG‘^Wy |¥°X’:t…oÑJác’¹´‘¥¼½ÓÓSFŽÒ/³–yƒ3rC9£gƒVî$¾]NK`·§~¡ˆÊ®SÉÚ»†áÀ ú×EE>arœ´:}Ô×0´òješçÍæe>_CòŽ˜Æ÷ªPŨ$­¦ºœÁ䲉 ‚_ø>»«¶¢Ž`å9Õ†ö;ñt¦ô¹ÔŒl¦G1˜þá;@÷ñªõYù¡ŠþöÎL{¦b² n p p‡®ÆŠ.;VÖÓ¶‰«[d¼×C)·r=óš –ÞÕU5”´X§óø\g'vÞ¸þ×YE+ŠÆ%óß&d·0Í-ˬkpмŠQ¶üÇ÷_7_JÉt¿—L…u!©²Y>hc&æ ¼/Ì~\}áZìh¢ã±Æê·odmî"ÔO³Û­´pùžP Á‚ñœçï~µ¯ Mí¹·-’oûpþg3³æÆ7{g­Š)¹\IXÁÒíï¥Ôa}I®³ œd1Õ ›Ÿ;‚¬ØÛsQ^Ûê,ÚÍų]ùêè¶ÃÍp›6.í«¤çw8Îk£¢‹‡)ÊZZ^O%¼RÜ_›G‰U’â6Œúl9¹8ÍC:¼Væ'ÔšI­\îwf gnïºÛw` WcEÁÊs¾‚)olÓQ’ÖÚá^(%2%ŒŒ8Ã|Ìr7wT¶Ú¼fÖ)..”|ù‘´­¶bÙ9Ùœo—ºê)\v"¶”Ë ®Æ,…w9#=ªZ(¤0¬»Ÿù Ÿúð“ÿCJÔ¬»Ÿù Ÿúð“ÿCJ:à”QEužå¥ÿÌþÁ§ÿAеäi^å-à(¬ÈÎY†F§ãY_üÀ?ìô«T¶ÝR#ÿLÿBJæžæ±$û5÷üüÁÿ~øÑökïùùƒþýñª^ ¾ºµÒÌ–‹9–4Rã#æp: |Nc¹¹y”¬v¶›åƒË(}¤gÓ§áÍRŒ›’7>Í}ÿ?0ߣþ4}šûþ~`ÿ¿Gük†ÏlŠ¨Ì¬ñͽ3°²í8Îí‚;æ®éZßö› X cìë,™l˜Ü±:u[ò§ËsH²ÿi·x¼é"‘d}Ÿ* àŸSéV*½ëî{QÿMÇò5b³Òú­µ +Wº¼µ½VyäµÓÄy3ÇÏGøÇ¸¦ÁªÝ¬7÷ /"Ù!’Kƒyä O9'Ú…srŠÃµ×¥½6kii=À”¹ið¨#`§)ÝÜp? “KÔoÃí¨_G+H¦9 2ž£h xìM`šzVx…­íf–úÍbt‚9Ñc›zº¹À䃞¼Tqx¡v»Olª±‡ËÇ6ôfUÜœ ägÓ‘E˜] ™§kùüƒGÉ)-’Žs”éÔ`Ô)¬]½µ¬£OM÷Ì¢ŽX-—;~_”ÆïJ,ÂèÙ¢¹×Õ&¹»„¦ø ÛÝ,±È&À{ã'Þ˜Þ$Vö¼biE¤sL^P¬CqòŒÍÁ8ãëÍ¢æGKE`^k¯¦Ý]ØÛÆÄæ8å’O™˜0Sòm8ÈÎsíO—V¸¶ÔÞK`÷n‘*D—s3÷*árN?RÌwFå‹ý·s$‘ÛAc»3<2F÷QJ¨l† r#|VŽxº†Ÿâ#"Ì»¶·U=üÁ¢ÝBåš(¢ÂŠ( Š( Š( Š( ²îä6ëÂOý +R²îä6ëÂOý (è‚QEÔb{–—ÿ0ûŸý*кaôLÄ(òœdœ å³ô¿ù€Ø4ÿè1V½Ä p=nïÒ¹j+ÜÚÅ+Ÿ³]D#Ñ2¾7ãr?QPËk§Ës=Ä‹–â1§ÞPr?ýusαÿž#þüð£Î±ÿž#þüð¬y_ó]v(½Œ¶¢ÚyhÄ‚AæÎ\‚:rNqÇJšÚ;;F­ü´7dùú±þ_þº±çXÿÏÿ~øQçXÿÏÿ~øQÊÿ˜.»¼«$öÊ®¬D àñƒZ5Z­Lb@Œz~ïnJ³We¹2w)Þiv·ÏºçÎ ®ÖE••Xz E&‰a#ÈÆ9{ÂJÊ0ðxŠÑ¢´¹;m2ÒÚH¤‰|B@¬ÎXüäÎzäD:]¤Ó[Ʋy3 Œ@9 éÔô«”Qp±Mô»)‡!¡XXýÀr×=úÒ>•i,Ãp%#”J¾l¬ä0éÉ9ǵ]¢‹°²+ÚÙ[Z …¼ADò4’sÌzÕa¢X,HY„aƒ ó›÷DtÙÏËÔô­) ¤šMŠBBG’)ÜrwýìúçÞ‘t›DòL^tf«G3)*B’ {Õê)ÝŠÈ ú=Œ9häÛ>L‘‰!'©ÛœgÞè¶,¬%veU.Ò±”’ìç ±æ´(¢ábœe»BÑDCBÌÊÅÉ%›†$ž¤ûÔö¶ÑYÛ%½ºíŠ0BŒççúÔ´Qp°QE†QEQEQEQE—sÿ!³ÿ^èiZ•—sÿ!³ÿ^èiG@<Š(®£Ü´¿ù€Ø4ÿè1V²º´Gþ˜?þ„•“¥ÿÌþÁ§ÿAŠ´¦mºŒGþ˜¿þ„µÍ7gësX«è_–áb‰ä|í@XãÐUK ^;è¼ä·¹†"›Ä“&Å#ëšŽåŒ¶ÒÆ§—B£>â¹û].èh²iïFÍ ¡w½y•ˆì“´jjºLß‹_¶žæx­ŠL´JdIT©ßž‡=¶ô«v­i©Û ìæYŽ@#+ìGc\àÓ¯&¸šw‚ÞßÌšÝÄhà€#Ý“À÷ý+CEK‹=>;Kˆã_ lWFϘ2yÇnÔýº°½›¹¥¨>ãj?é¸þF¥ªWº[aÿM‡ò5v³Ræm•ËË¡FëSŽÚñm½ÌÓüÌCì.q“øÒjZµ¶y|Ö¬%ÀvÉ€~µKTÓnfÖRò(^XÅ¿—ˆï܃»<í##ëPßé³ËuåÛÛ¸¼11‘ßæ‡n2:r8㦭% ›4ÛW´Šñ-n%Hd‘¤TÜë†ØTs׿u«R][E:A-ÄI4Ÿr6p¾ƒ©¬h´ËÛmQocŠAšã*_,…nFΞôkzn¥}|¾S©µYP .ÖVËÊ–÷ˆÞ2â0Ä0<„¯o¯<ÕHµ[¹4ÛK†ÔbY.Ý_Ý®,óœ\‚6üÝ룊`A qrB \þTŸg·Ì‡È‹÷Ÿä?×ÖÕÂÌæáº’ëQ²iÝ$òÚê™F (ÁýG•VNþ ;Lµ°ÁNbߦÒ]—Žväó]€Ž0Dh}Á´a~ž”Ö··uU{xYTåA@@>¢‹ŠÇ5}{wu¦ê%à·–%t¨åÀûÛºŸ^8¥¸Ô&¶½Au¡ €¶~PÒ0$ã‚í])†—Íhc2cÊ ãÓ4‹o!D‚%R0T LQpiœüz…ýÄ‘ZÅz ×€]$J|ÅîÈ3“ƒJÖÑn¥½Ò`¸ŸošÛ•ÊŒUŠçñÆjâÅ**FŠ©÷@Pý=)UUT*(P;Jú !h¢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ ˹ÿÙÿ¯ ?ô4­J˹ÿÙÿ¯ ?ô4£  EWQ‰îZ_üÀ?ìô«bY%X¡‰¤‘m ÀÆNOÔV>—ÿ0ûŸý*ÕÝ·UˆÿÓÿÐ’¹å¹¬væ^ÿÏ‹ÿßÕÿ<Ëßùñûú¿ãYø†ì[¥åÕ¤+dó˜wÇ)gOŸh,¥Gô&¬]ø†Þ?>(·ù‰½FŒùfERvç׊|‘îÅÌûüËßùñûú¿ãG™{ÿ>/ÿWüj˜ñ ¼[ý«Ì2¼ ,¦8ÉXÃp z çò¤·ñ<Iqo2l¸xjîåFßRqœv§Éâæ}‹ž|êè·Í»m¸<þJž¨›èµm&„¶ÎÖVe`GcW«7£±k`¢³.ï¯WUVVÐHDse)üXÀšbkö¦Òš)¼ÉwæMì»8ì=}Å; æµ·ké¥`Öñ¼K–¤³ï@@ÇrI¥Mu%¾·‚ ieY7¸h™ ‚{}î´Y…ѯEP²Õíogò¡óe/:²(8%OqRG¨D÷æÉ£š9pJ—L+Ô©ïE‚åº*ƒêö©5Â0—e°&i‚.< [×Vë\ShÍjë, ɆÓG1º¿yndòÀ›Ë ´FÁ—åïÈçúVÅ^ÀÕÌk¿ÃtŽUbnMÊ !YX®Ò žŸLThÆÖT–Êâ;rcXæHí”$€F”üÍëÖµh¢ác|>†­§»im¡/åÇå…!YXNyûÝqÚ•´4n.¯¤šCÄå…ØŠÁº¤àdþ•³EadW·´X.îî–7L¬AwbŠ) (¢Š(¢Š(¢Š(¢Š(¢Š+.çþCgþ¼$ÿÐÒµ+.çþCgþ¼$ÿÐÒŽ€x%Q]F'¹ióÿ°iÿÐb­Üö¿:ÂÒÿæÿ`Óÿ ÅK>¯2ë²Ø » p‚=‹2±y za…`ÕÙ¢ØÜÀÿkó£ý¯Î±/5—7CgþWÛRÞK‚«åž~eç>øÇ½Cm®Ï+ʋҖ¾qUC¹ÇÌ¥¹'ϽM´¸ît8í~t`µùÖ4ü,ÈotPÑî  @î¡€ 6{Žƒõ2kPÉz%µÉåhRã å³®wónà‚3Œdu¢Ì.<ö¿:0?Úüê(¦ó-–gŠH·.ãƒæ_by¬Øõøå±‚ê;¶2,p 1îH?üDj,5ð?ÚüèÀÿkó¬ ïí¼ûeH°ÎÆ  <`玽²­Z›X’¶I´«Õk– <'æú 3Ðg#8Y…Ñ«þ×çFû_aizöëX¿´bš&q!YÙWË“a$ã‘ÀîpqNOÚº¶·~iØc‹ º@ç GÍÏ©wY…Ñ·þ×çFû_e>»\ÞD†W6Å#€BŸ›“ÈÎÜžµø–Æ9& þ\^h…]²ÁÞœä`õph³ ›8í~t`µùÕ-?R[Ù$ˆÛÏm4j®c˜.v·B ’?Z»Cи`µùÑþ×çE†í~t`µùÑEí~t`µùÑEí~t`µùÑEí~t`µùÑEí~t`µùÑEí~t`µùÑEí~t`µùÑEí~u—sÿ!³ÿ^èiZ•—sÿ!³ÿ^èiG@<Š(®£Ü´¿ù€Ø4ÿè1U×Óíó]ÁsnÓ¨©ÛÓª“Þ©ióÿ°iÿÐb­+½JÖÎæÚÞâM²]>ÈÆ3“ïéÉêEsËsE±\è°›µ™n.18¸ò]†Aߦ Ó@‚ 7W1ƒ†@ Ÿ1I'œŽÅLu­ ‹»{n&™¶– Xn zõ ¶¥muäµ³¬‘K00ÂãœçæÿZBÐíRˆI6×’)#9TßìŒÕH4[µÖv™#²Šgž8–Mçsg<y$ýã[kµò ÿi‡ÊMãn~´åžRTa'Ü!Ýôõ§v[1­Ò#4’2®ß1ñ¸ûžÙ¬Y|:CDö÷²,¿iI¥”…S…V( ·<÷ÖõT±Ô­5?ì²ïû<†921‚?˜÷ö¤›ÜÒÅFðý›ÄI&’Uv,2æ@Ç^1Jš3­äwGT¼ycÊ–3òç'øxÎHô«j–³ÝÜAˆËo»ÊçÔ¶zµã̱:â)| Û¡¾\x?¥…‘V Ú-«,ÓÏÅ!]±ïÎì` œ9ÏZ-ô h"HÖW*’#¦#HÚrUA#ëV%Õ¬á½û#»ïU˜!(Œßtè ¢=ZÒKß²+>ýæ0ÅÂàd¨n„Š5 û­ê}`ÍÉ “Η(’î »³Ž€}îÝ*sáÛ?ô°®éÐ2„L©|î!¶îî{â®\j6¶×–ö’ÈD÷ ˆÔ)9úút¦kZ}¸Ún}âA}‡`r3·wL㵆„°ÙE ÛÜ«9w‰" ã^Ÿ5f£’xb‘#’hÑÜá˜ÇØw¦­Ý»™)£‘ã²+‚G×Ò†î XšŠ¡±e+é¦&ºÓžÏLi$†9oÞá£Æ|ä.HèAçÒºZ(æaÊŽB*öîÊ+”ákžan `í~Ô¯oNõ`øvd±¹ŠÁs nÒº—FC“ó1jé裘9LÝRÚìßÁ}cLÉ´lûx|r±QøVmׇå“O¶±‰“ÉMv&ds’6ƒóõ8Šé(¤‡cU²½¸‰ ŒqÇ=£³;?ßR»[>œù «s¢\Ä²ÚØ¤mosi³»6 [ |ØïçñÑQEÂÅ­$mVÆtÊ\9'žWªj°êZ£ØýŽ8ã™°ÓÚ¡úã©$žõ³E ðè‘I¨_\Þ£ºËr%‰<æÙÀ%ÚNGqPÃi«ZF–6èžHºý¤HòÌ›™JžsŒŽ+zŠ. (¢Â²îä6ëÂOý +R²îä6ëÂOý (è‚QEÔb{–—ÿ0ûŸý*ÝÀôýOøÖ—ÿ0ûŸý*Ý®ynhƒÓõ?ãF§êÆŠ*J OÔÿŸ©ÿ( Óõ?ãF§êÆŠ(ÀôýOøÑéúŸñ¢Š0=?Sþ4`z~§üh¢€ OÔÿŸ©ÿ( Óõ?ãF§êÆŠ(ÀôýOøÑéúŸñ¢Š0=?Sþ4`z~§üh¢€ OÔÿŸ©ÿ( Óõ?ãF§êÆŠ(ÀôýOøÑéúŸñ¢Š0=?Sþ4`z~§üh¢€ OÔÿŸ©ÿ«goö«q<—3«37 Ø G§µOýžŸóõsÿ}ð¦¢ÚºBm!øŸ©ÿ0=?Sþ4ÏìôÿŸ«Ÿûì…Ùéÿ?W?÷Øÿ |’ì.d?Óõ?ãYw?ò?õá'þ†•p!·¾HVY$G‰˜ï9ÁGõªw?ò?õá'þ†•/ª+±à”QEužå¥ÿÌþÁ§ÿAŠ·k Kÿ˜ýƒOþƒn×<·5AETŒ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šçu'S§é‘K#$O~M²Êî~ qPJk8µap^Ò9aŽ)¥c"ÂY€s“Ô(9­ˆ û=ճȘ•0S–$v#½H$ŒGå-¼¢½ª5½”pàK ›|Š#š6 ÎÊs“ƒž8­ux‘QRÚET9P¶Ìý8â‘ü‰#òä´wLçkZ±õÆÚ~Ùö³'·–Y®máJm˜º‚ ”ÈÈëPÜÿÈlÿׄŸúTÖ ½Úȱº¢FËó!^I\`¥Csÿ!³ÿ^èiN/™6 ZÈðJ(¢» rÒÿæÿ`Óÿ Å[µ‡eÛiÚ-Õ’Û»Eb¨Ë3²BŸîþµs~µÿ>ÚwþIÿÆëžKSDhQYûõ¯ùöÓ¿ð*Oþ7Fýkþ}´ïü “ÿÒ°îhQYûõ¯ùöÓ¿ð*Oþ7Fýkþ}´ïü “ÿÑ`¹¡EgïÖ¿çÛNÿÀ©?øÝõ¯ùöÓ¿ð*Oþ7E‚æ…Ÿ¿ZÿŸm;ÿ¤ÿãtoÖ¿çÛNÿÀ©?øÝ šV~ýkþ}´ïü “ÿÑ¿ZÿŸm;ÿ¤ÿãtX.hQYûõ¯ùöÓ¿ð*Oþ7Fýkþ}´ïü “ÿÑ`¹¡EgïÖ¿çÛNÿÀ©?øÝõ¯ùöÓ¿ð*Oþ7E‚æ…Ÿ¿ZÿŸm;ÿ¤ÿãtoÖ¿çÛNÿÀ©?øÝ šV~ýkþ}´ïü “ÿÑ¿ZÿŸm;ÿ¤ÿãtX.hQYûõ¯ùöÓ¿ð*Oþ7Fýkþ}´ïü “ÿÑ`¹¡EgïÖ¿çÛNÿÀ©?øÝõ¯ùöÓ¿ð*Oþ7E‚æ…Ÿ¿ZÿŸm;ÿ¤ÿãtoÖ¿çÛNÿÀ©?øÝ šV~ýkþ}´ïü “ÿÑ¿ZÿŸm;ÿ¤ÿãtX.hQYûõ¯ùöÓ¿ð*Oþ7Fýkþ}´ïü “ÿÑ`¹¡EgïÖ¿çÛNÿÀ©?øÝõ¯ùöÓð&Oþ7E‚åÙdÙ…QºFè?©ö¬“ƒ¬» ¶ë3!þ3½zÀv§ùzÉh4öÜs!ûL™Aþ¯íI¥÷Ú¦¼¾û2Ÿ³4Aa‘›©ºŒ~µ-1žEWY‰{û_TL"jWŠª6ª‰Ø@9£ûgVÿ ïþ?øÑEr³dÛ:·ýïð!ÿÆí[þ‚w¿øÿãE€?¶uoú ÞÿàCÿÛ:·ýïð!ÿÆŠ(þÙÕ¿è'{ÿþ4lêßô½ÿÀ‡ÿ( ûgVÿ ïþ?øÑý³«ÐN÷ÿüh¢€í[þ‚w¿øÿãGöέÿA;ßüñ¢Š?¶uoú ÞÿàCÿÛ:·ýïð!ÿÆŠ(þÙÕ¿è'{ÿþ4lêßô½ÿÀ‡ÿ( ûgVÿ ïþ?øÑý³«ÐN÷ÿüh¢€í[þ‚w¿øÿãGöέÿA;ßüñ¢Š?¶uoú ÞÿàCÿÛ:·ýïð!ÿÆŠ(þÙÕ¿è'{ÿþ4lêßô½ÿÀ‡ÿ( ûgVÿ ïþ?øÑý³«ÐN÷ÿüh¢€í[þ‚w¿øÿãGöέÿA;ßüñ¢Š?¶uoú ÞÿàCÿÛ:·ýïð!ÿÆŠ(þÙÕ¿è'{ÿþ4lêßô½ÿÀ‡ÿ( ûgVÿ ïþ?øÑý³ªÿÐN÷þÿ¿øÑE*QEÖ`ÿÙfotoxx-12.01.2/doc/images/gammachart.png0000644000175000017500000010567611701011016016473 0ustar micomico‰PNG  IHDR²$\ÌEsBITÛáOà IDATxœì}]l×uÿ]I$eî(N¡]=4.´«>4wÕ‡ITjŠî° \Åtó ¢¼DT¹jІ ¨E˜|hEAdb"þ&Ñ NÂ%ZnDºqú!®ü¢]Í‹vƒ6_Þµù!rþ׺¹ºgν3ûAyÎÃáòœsÏ=3;;¿ßܹs'B!„œŸÏç+•Š ?‰DâÂ… „ååe•Ú‹ç6^½z•2™Vö÷÷çr¹F£qûöí”j!ñxüÕW_e?_|4f' àOÓù|¾½„Æ3 §õõuä5k§I___:^\\ä¨ÎN^”'ç\.gÇæ;aÙÁ?;;« h-(—Ë©T*‘Hð;÷…^( ìßÓ§OBîÝ»G:Œ0‰F£×®]#„ŒÉðOï|W«U| ðÒ××7>>N¯¹É㧤h4šL&M9 FáTΜ9“ÍfWVVè¡ÌôõõÃßz™œœL&“ÓÓÓ<÷¥rüøqÒÙõ³ƒ¿P(ððOS'H*•Êår+++ÓÓÓm0 >˜!äÌ™3ôˆÚ‹Ì ‰ŒB …‚À5;vØ€ßùÑht||¼\. Ê ö9H¥RÃÃÃÅbQyð·ôE÷ÑdZ×uÇá/»ßÿ}ÂþQ„— p7‘HŒŽŽNMM]¾|ùÚµklš˜ëºL˜d³Yzy1555>>θ—iýH P¹páB¹\^ZZJ&“Ùl–NÍ 4xAnf4}ñÅÇÆÆ¦¦¦fff‰y´óŸxJ¡PX__Ç„]¹r%•J çþú°©uê³ÊeW®\‰Åb¦Õ6u3ýü­ «««•J%‘HÐí¯T*årÙqŠOµZýÙl–úD{àÇ­pjjêù矟œœL¥R®ëV*•ÕÕUÇqø#Û³Ú¶딡‹År¹<99Iåb±X­Vì(pN@éíí½víÚØØØôôôúúú… (3£O°õ7C‰­ÿܹsçÏŸÏår®ë6ÅÅEBÈàà`» „$‰d2BÈÔÔÔÈÈ;Óƒ?zü­ÇqÒé4æj¬^¯7µ;fÇ‘õw3$™L"/…!¤^¯Çb1ú¹CÈÅ#L¤|ð«iA°X{úôéÕÕÕ±±±|>ìØ±ÌÍÍÅãñl6;??¿²²BÃr¹\,3šT`‘xaÌ P($ Çqèd7Џ€´k@Æ FFFR©T½^¯T*Žãäóù ºh' ÙèhöØØØÊÊÊÚÚZ"‘¨ÕjÕj5™L ÙWl+¦[ʘÁÜÜÜââb<¯T*õz=“ÉwÙ:Pxf@þC‡ÑËÁK—.µ»:B¤ƒ£G^½zµÝE}$Ì “ÉоGåüùó>30È$íX¹ÁÏÁ㓵UÊÑ£GgffìÚŠ´€ÖD×X__§¿yÇq’Éd&“ŒF£¦_O*•Ÿ››£Çq®\¹’H$âñx±Xtg`` “É Ó¶ž9³ÙìñãÇoÞ¼IGA’ÉäÙ³gOœ8¡ëºí„@èw|||hhè7ÞX]]%„ äóù `©Iœ€I4½qã}´¯T*9Ž“ÍfGGGùaíN–D"ñú믿ñÆÅb±T*Åãñáááf/”PfÀü‰DâìÙ³ýýýX§•dÊ <ëoû‰– ªj×=ÿרÖäÀ¢­2•e[ú‡½¡^¯ÏÏÏ‹Åd2yìØ1pçÎr¹¼¾¾~æÌ™\.gÑ+k]­VéyÜî$Þ–Š=GõYp[~ºF£\.ÇãñÇ· ?ç)å—ûË_þ²Z­&‰D}ÌÆÒÁ€¾¾¾N+)¥R) ”Qþ¦:jë:,áiÑÖÙ:scƒ•¶ŸNa žÚõ労 P(d³Ùå²kFã7Þ¨×ëçÏŸoñF¶ë–ùXýbIøý>‰ÒÞ9_vÒáßËí’ßÞ'àûiA£Ñèíí¥‹ÆPf WCcìX:ód ›Üö·5üÚg/˜Ûmß“‚ ¿âÎ9>VÒỽyÈa×|/J‡Å$èo¹•_±¸nª­T*tAb:™Î}$| &;m577G—(0}ÄmkÙÑpñâEݲ²ð7À:áx½ÿþÅ‹›º¶nS9ÁÊÊÊŋۻ¶®,øbæææ.^¼ØÔbš*…BáúõëµóñrÿþýB¡°¼¼Üiõ#©$]Ø»\.{Ößâi—ÌÎÎ …&ÕÃN°0Rø‘B¡0;;k†Ó²#Ù¶R© »5-ÔO"¤R©ÉÉÉÛ·oOLLD£Ñl6;44„.SÀ‰r¹l´0m'Œð‚yô–t*a¯×ëëëëÊ÷ ">9»çw]­V×××›ýü˜µxn5‘Óšbš!M}k@ó„Nî£?ò1­ fú¡ÑÁßÞIûJiÁÁiæCŒÏ/²X”|fÁÏÁ/ÞD„.‰@èïï§çéJi6HXält&!h4o2]ÎÖÈÇêëÞ‹s ¨Xgnžríé;˜­œì`w×ß €Óég‡ ?~饗~ô£ ,--=÷Üstõ¡?ƒçÂM Y:d@^)ü·Ò±ERq5b~h'ð_s°‚Ùp¸àÎÙtþQ­¾ìŽÝLa¦_ nû¡Å{·¦/ú9¨ ¼~ÌmÓâ…; ÙÕ]å°··7N—Ëeú°2³ã±Áâ«êœsÛ`>…Ö_©TîÜ¹ÃÆ$ãñø‘#GèBÄö!ÝVŽ\¼xÑuÝ .Ðå2Ûrx˜ +++Žãô÷÷+ ®ÕjŽãèæö†”tÈ ºRà» äQñ¥RéÎ;ÌxìØ±x<®{jº©CëB_ræ8ÎøøxSŸ4Ø}v4???88¨ÛÉ•JÅî©uOúb}g´íZZÀU‹‹‹+++t}ÜÉÉÉ£GsBP*•nß¾-Ì3ˆÅbñx|```hhˆ}nRàâºn¥R¹yó&}ÉM"‘Èårôf ý­:ŽÃêï¨Ê©¸®[,”+¤:Ž3<<|úôiäϵ]œ€<ºÕwîܹK—.ñïDh‹ »¦Ë‚%‰_|Q^0Š®’ÉdØBÎ)t+Êår¹\fFºÙÀÀ@6›íÀÞø`yy™þxùó:ŽÇãCCCÊ%UÔs \×¥«­¬¬Ð kÙl–þx,j­×ëlú?ý­Z­ÒZé‹d:s­4ú2Œz½žL&Ç)—ËtåB[·‘.ÊÛë׺®KßkÇóùü‘#Gîܹ³¸¸Øßß?44DßœD× Þ£ËF?ø¼ ¦8íÉ“'c±X£Ñ «3(mÙ>· Dìm1Ê#„®ÕH_1:33Ói!¤R©\¾|™ýH“É$ï¢X¥#= ôÅ`„:÷Š^“ܸqc~~ž.ñII&“333m_/Kùë¸xñ"8vúôiÇq–——WVVΟ?OÈ+++õz=›Í^ºtIW¼Ïßl Bç¨% :Ò<:::<<Üšzül>{U’ò¹~ýúÚÚZµZÍçóÖÌ@®S'ù‹Åâìì,ý‘Ò+pæbçJÒ£¦•Jåë_ÿ:}mA6›e/°«ïæÍ› Édr||œ¾8ŽJgæçç]×}ýõ×ÛþãÄuÝ^x¡Z­ÎÌÌÐ3Ë|ðòË/ß»w¯Ñh¤ÓéÓ§Oß¹sg~~>‹½öÚk¤Ã ªÕêÈȈpXÓ_é•+W(›šš*‹gΜ—àm/' „œ#CY&C#ë’ŒÄn˜„Ò‚™™™‰‰ ÝNcnܸÑÈJkËd2gϞ΄Z­¶¸¸¸¸¸Ø™´¦V«=ÿüó±XìÚµk´øZ­V((¹?sæÌñãÇWWWadm™¿‘•••©©©L&ÿoe~~~ii鯔"Ó'éÙ©c™=áœ9sfpppbb‚<7û†/v{€žpæææÒéôÕ«Wå‹ç‘‘BÈ›o¾Ô†ÅÆóÏ?O¯`…Áx*ôÎN©T’izÊ¡ã8“““ßûÞ÷Μ9ÃÎvó\×]ZZr‡½LVh4šËår¹\£ÑX^^6JÞ¹ÿ>=ˆé¯.‰D£Ñ .лÂ/½ôR*•ÊçóÙl¶V«ñ³.:Dè%Ñðð0ÿ L¥RÉdòæÍ›ôßññqÇq€µ „™,eÈ…£ÑèÌÌL>Ÿ¯T*cccôÎN+'XìT*5::Úh4ÆÆÆèÛÙyïéÓ§ !·o߬¤R©ÐKÕññqú3Ab±ØùóçÓét©Tê´µ%È£]JßÁF-±X,ŸÏ—ËåL&“ÏçS©ÔK/½ÇÙÈA{E8´hUgÏžå§OŸ®×ëtÞw4eo>ämû×D"qãÆ úh[¡PhÙ1ÃËbär¹L&³¾¾>==-\D£ÑL&S¯×K¥R°óä&,//×ëuú²å¨j"‘˜œœtG~†@M >|âÄ ¾J 6Àª¯×ëtM{>@HKï,tÚãé®ë²aRÞ~øðaBñDÇg:­~ò¨¤#GŽvÇqx“L&kµš2ƒÏÉÄ'p9ágΜ™œœŒD"t±©¦žòügÎf³”ʼüòËBBÇq|&o’Ѓ‡þ6•ßý wæ—<*‰½Ø… ý-Ð,­?wNñü~fÿ|=‘Þ»wÓSÓƒðiÛË ¢ÑèK/½tæÌzsvee¥eõX“ƒñññt:],—––„óá¡C‡‚/»òYQzð?~œp.¤¥·½_¬L»¹ÿþõë×…1¤È…Ò!»F£¡ä,4žN²•Ñ«]¶‚ž²é½U:sÇu]Š ÌHý,;ðüNO÷îÝ£O°_E¹\¦ÕÒúÙ¿‚ø~ô9N LÀ®V«óóóìßþþþ•••¥¥¥r¹<99Ù‚Y{~† óù|µZ-‹/¾ø"«–^Ôòwþ:Dè!Ṩ èØú F"‘§Ÿ~š¾÷øñãô»o4÷w×ÝÝ]«ÕÊåòg>óÊ"“ɤÿ‰'Ë‘#G~ðƒ¬¯¯îsŸcÇîôôô{ï½÷çþçµZmzzº\.ÓùñF–¤yƒž™é3¥R‰Î‘i4%NØ€G­Vëêê2:bñâgWÐ3#›´100P­Voݺõ¯ÿú¯Žã4•••ï~÷»Žãüíßþm{~Y>ýéOÓý\­V;&ß ®Õj³³³«««©T*—ËuTñ„§Ÿ~zqq±R© Ò³äýû÷ÿþïÿžn!$‰ÌÎξ÷Þ{Ï=÷Üç?ÿùΩŸþ4è­½÷Þ{ï _ø­ÿƒ>¸|ùò¯~õ«¿ú«¿J&“wïÞý‡øö/ဃ•ÙÙYö !„.ÚÈ„ O¾÷Þ{ǧw©šWŒ òÉGî}~~žN°‹D"]]]_úÒ—~þóŸ¿õÖ[¥RéСC¿þõ¯ggg)îÚ½UØ´Z£ï÷³Ÿýì~ðƒŸÿüç‡úìg?ÛÕÕ%4g³‰s¹ÿÀï»Ñ­rè)˜S£Ñxùå—ÙÝ;ž¼Ôj5J$ÇyñÅOœ8Ñ®_&pê§÷°é­:ö^¯×ÇÇÇù+W6y¢sÎ,LØdl¾~6 ñÔ©SDšjÛöA&ì!„ÐÉÌ.\P¶ÅbÍ8³ø¤GtÊžðûšŸŸ_\\dcw|ðлô´î8_$}$‡tð“®ë‹ÅééiòèVÈúú:}$„žÐiò1œÖ‹ëºÓÓÓtÞ«ŸB'!Þ½{wllŒýK ÏÌCdGȽ{÷æææ2™ÌÐÐ22™L¶qÿë~ãtÊ!›KKç^¿~}ee…Å´ëàÁÜY[[›šš¢_A<ç‡4ØÁßßßOG.ù3¿%-ÀÔ$$,•JËËË”02c<O&“ôÈv˜ó>]·€2›d2yöìYÊ`غm¬#´~º¾z<O§Ó£££´àÙÙYʈé¿þ HÓ6>yò¤<¸Ùâóì9;;[.—åšéÀô¹yúóÎpNßÛå9éŒy-6‡OnÙËžyr•\|nŽrN ˆÇâÇLjµÚòò²<d=#¡©{Ö3¿ÏÞÛ^àùéŽ?4¬¿½ÏSuN Í–<Ù5C"´*0^"^¯N >6g #L{ëÒ“`6GM è -úh,•jµJçY8ŽãÖå©S§Þ}÷]ëÛìAA]†/|á ?ûÙÏx¯õi]x\žæüâ¿øÎ;ïõ[tG?š³¿¿uuÞ?v[D[ þô§?eç¶3å]jÔ >yòäÛo¿ÝŒú©œ:uê­·Þ’ó#sz†}éK_úÉO~‚,Æó2ŽîX>,“ɬ¬¬íj–SÌÐÐÐüc»ýƒéâÙgŸÕ-놹¨õt}ùË_þþ÷¿üýZ¸¾ò•¯,..ÕodÿêW¿úÚk¯ùϯ3~ík_ûçþgÏýcmáhºg+d$²w![»† „z<ƒuaAí ë‘Øå™2ƒŽµ]2?8 û!F#¿òÊ+Ìâg#»C‘…‚vò$Kx6iRzàiÛuÆçG×É)×a¶+¨«#asd@à ³ù<)´®G°X¨,f¯œ';ç„Ã*Q/~Ü××÷½ï}·=zôêÕ«äÑXw3¶Ä3mÛ¿æ'£åNnû¦ù—Îùu5CöÜÔŒÉ+ -ØvɺMóSÏÝ¥¼‘Á×㙿-ži§ÖªI¢ž[@Çx Oß’É$}­p â¹/:á„ÒÞš7 KÚ½iOªø•íÑ/H¸ðmÒ†´þLÚÔ;Ý 3P‰çŽ5ÚóžÌ€ÿNƒ÷Ky|^$á3ìn";ï)ȹh~i»ïZîñ€Dq‡_ ±^¯‹ÅT*E_:ÔúÏŒ ìÝó&F‚:µà×ÛF 1¸“%¨½ÚŒÉ4ve´ 'liŠrçXßÐiË¥œÀ¡+£yÓÈ„’ø‰n´€¾~”· ^¾|™_%±yb”¿ÓÎãÁBKó BÑI§Q{NžìØš‰lü°A€3Ë,N­ÊùníýŠåÂìNqsb¦yU$2í]=·À•¤¯¯¯^¯óKŸ.‘G‡uÎwÉK€ó-Ü@eUOÒY»3÷9ð$íÿK3n~w¬c¼Ê0ëÏæòÕ¤ç 3a´ˆñ9qG å´`ó›w3((‘w~kuõh}ß"oY^^&Íy}¤ÝìŒÎ‘À¹ó“=BÐöK @:¶°ÖK'Mí•ï–ˆ~~++Ʊ=‡µÛ5ÑOÎ'àHf{»©ÓtxQÓ‚J¥R(x‹ã8ãããÁ¾¡n¯[ÁŽï’HÕö{–OÀïÓ¿à÷@{wWÇ~Sðü²`:ÝÇaº ÈÌÁÎí÷?Þg§®ëzv×a[Äo¾ÛyËÿúÚ[ /í*s¬2ÁÎ-`H‰ÿýßÿýðáÃèôöö¶R?|ø°««‹i]«ÿú¯ÿÚò­„ º¾”=RýŸÿùŸÈ:1Ûµÿ~ÖŠêwß}Y›§f‘û÷ïgöÿ÷ZÑH¹*ÏxfY[[ƒã-êçõíÛ·‘‘v1ÿöoÿÆŽÏãó] ÇÏ[o½åƒ<þ•ÇùO~ò£Ãææ&ífëéé¡ZˆQê……¾Ç ÏVBÙÂzßØØ¸qㆰE¼—YhÍB[楟•Þú§â3󑼿½ì3`gúêÕ«J{Púå—_¶¡wïÞ=¥’@8!D*Lïìì(µ„€Vºü|£x¹w`+0°”†©T°¡Ô@<'p+ ’$ft1´xÆðõÀ1˜•^…^” ƒ(ß#&^3¨”‘J;º‚Eò°ÍGÊytÞÎ[tvDuO-Ç PŠ÷µª=õiz5 IDAT¦êúØ3›®ºœB̦tÅ/@¸²¹/ùú˜Ï\%+‰Ÿß3³Ž èrbÈiÔIðT€¿–®n™]¶x’]NáªÝ'!¼Âu3@”­x¨€\™ I,üS–-`ZFS©o9qâÄ©S§J¥’`·;ø¤$€×vyäl¦`,ÃPfÁFbàÞž=*û•ÎcJ`è…«•á¨EemžŒ4÷Œ@×”.è ½K —¡]™G ápEðÌ#@ @2øäó^¶umª´wãÛ•ì¦O2aJ”£B`D&xÀ–ûÅ¥ ºx uÐyƒ¥ºV6´€H3#jµZ6›M&“~ØËÉŸ‚e°×iÆÔùl:ˆõZL#¸õ$Ê MÎæ ½@NL[e m d@V¥Ü8§ìÅØ•^{FÙt+´ Ú4^ÙJÈ€!BýJí'‰¡ÈHªuø-b`Š ˜F ½äë¼Ì{7ÄÈcÚÊ‚^xÚ‘786ƒoÀP%Õ ZP«ÕJ¥Òääd&“q'‹MNN®­­Õj5$ ÿ l€ Õv0liêT…f»l ‘àgPV+ƒ>¿2³'l³“2Ó³-SÈlê@%FÙX¹USíH°4”½ áS'\!³Æž^]Uþ!ЬÇ@ÃF­t0¬´c Ó.¿À#3cØn«írÚ‹J€<0´ë,ºñk:·RŽ(`â1uzÒ ¦Š dÖ xÏ^t$ðnªà_¦ ɰð"ÉïÝâžp ü3#0@kŸD˜œœ|ã7b±X2™¬V«ù|>“ÉP—ÿåŒ`€´€O$h½À^L̦!ÐyÞ´ #µE À°Àf=nll(·Ý'`·ÑN-21ÍDê€Ç('«Óþ™E×Ö.°g,òèÈM€t„ÿ¬!à¡IȘד"(³Á#@¼g_:·&"@N>R°o¡ŸdÙâ^Zu«–êbŸe¨îR=«ó tvOmI z{{³Ù,!äüùó¼=—arÍE¡-ƒ¥n×?pzöHí°h ÚÕ ×MfL=0@ú´ó•èö¿'¬ÚE Ј¬ß‹¨ÃÙ”äÉ”4ø¡yð„ _‰²*SJÁ*©ÌfDG6A¢ ¼…§x!rKz$èˆd5ȯ´À‘ ªux8×µe^a¹6™0;ßnõØM~ºÀüüüÈÈH¥R©T*/¼ðÂsÏ=W,ý%-ðœþ3è@…ý„ïÀ¦^ÏVÖ°gÑ—Q+¥]8Ñ[j°U)÷¤®N£Ê•=ò¥½ÙT@×»záæñnD0¤ÇŽŽl<~õ´¶Âšˆ3’!ä4Í Ô¬­nNoϹÈÙ”°­Œ>Ë,DÊ™-Çë"Y¼.R¹«ÒË>+ÉÁöã Éw?z‹ yüµœÂ{O ø§ ÆÂÂÂèèh"‘¸yó¦ã8ù|~zzºÑhòÅ¡>¡+½‘H„×›››L+½>ûõYm€9e»lšÑWk¶H¹-·®6íE§ÝçVÈ{ÏOU~êd–fÓyø$žS ÇküHƒuN%0 ­”8&§¤arÀÚê2^¼a­ƒs¦åà•.Çw©ÞÌ"/¿-½MFÐ,†a=?5ñƒßÓ>¢R©B†‡‡ÆÚÚÚÀÀÀðð0!¤\.ûç´/ opPÝ$/ ÑÍèÑ¢•çžtS÷Ikö¼‘æ$Àúýo—)½5žñ5ø¤MÖp.DzöëY)0µ•Z ÆAÕ k$„›Zd`ölµ>;ÿ®•RãA}¿jÝböžÖ»¼š­§E{Xw©^•®{u;O dô§@ý$‚ã8„F£±¾¾N $P»Ù·o߇~œ†:Í+ØýðȵóÞ ¿uvû™­Ù½0»Ñþ”÷UPÚnoøÑFDDI†üнI‘ž0¹¡þ}*ÒÓ8üº a 4Ð×–æ©+LfŸä@èÑþ1Ѓ=©„y†m¡-lÁƒ:}“0ß–Yøæe ŸMÉkø¢]íN$ñxüå—_®Õjñx<‘H¼ð Éd2‘H2åPyÊæu§y;;ÝË'ý ¼-hì>ñ$+Áfó´{³ŸýÙ ðÏ´dD†üˆ˜’ÿôB ÞFÁ”x -¼ Òà­ëˆÜ’ÿ–ÁöÀú°B/ÛÛÛ: ÕHWj|¤ í:;ƒm@(_/ÛÍòììì( ÁÎÎÎþýûa€VB&''#‘H<Ÿœœ$„\¸paffÆ?!`´€ž¼>øà%u²w¯hÌ3½OOL½Á¶ÒÑx»šAkZCw|Ò#?”¢©Ú”FxÚÙ¶ojæáíÌÒ˜×Á°©xÎÐ`Þ§–!ÜÔŽxOÍ2côÇ•f€ÙÔ.h¡¯úYˆ¤pNµÎŽô£D÷€¢ëºG}饗˜åĉÌÅ Ý-¡—ZxÝ¯Ó Þf÷,ajÍb­”ÔÁŽÖ­”5ÀÔª•%´«eÆØ•Ю¤{+ßì…­¦šÚe/oç½x{3À^w5/{ñv?Zy].0Lx¯lÇh ð æu^$œó1J/˹»»+ô.{mhÁýû÷¯_¿.…È#L&…Å ø0þaZÐh4˜–ÁÛ—½þ34ë#4émè!äÃ?4µÃ^ÙμÊýh?”±ðCüÐÌÛ‘üÕ¿r ÀÈk§up{•à €±¯Èñ0{Ú#‘ˆ©~øð!Ó°WŽ‘½r$³ðŒvO€"u1¦š‚:¯ezAµÉkZà8N:fÿÖëõb±˜J¥Ž;F3‚@J¥Ò;whÌñãÇébÉ9¨×ë„F£!hj×yùØë'>Ʀ@å'†B?^9Föò1v^Œ–^é´{|ÈÏ(H°ÄC 0D¡ytÁ”:`(†( ðx˜÷¼R7Š¡À{y‰á#ñ°„vø ÐøërÈ…ÈH$Âk#ýëÝÝ]¥6·ÖÓ‚X,–ÏçyËàààåË—_|ñÅh4‘`ÞuÝJ¥211Q­V)ŸXYY™žžåG¨D"‘÷ßßZ×ëuO/>F)ÇÈ‘º˜`5WÀÄè"y¯.ÒO ^Ëã4º]¤Ÿ±Ì8 fÔCDüŽ` †(E`àÇ<æM© ü€Ç@¸©†©Ô„Œ~øð¡R›ÆËzggÇ(žo¥Ó¦ñLGüAu3À›"ÕÁfÃkZ ¯YÔ××W¯×Ëår*•’ãkµZ¡Pe¼¡T*]¾|¹^¯Ë¥üæ7¿Qêßþö·€WŽ”5&ÆþÝï~Ç4>RÖ˜^¿ÿþûLã#e¤š}ÁGÊ©ïÁG5©`ÆWLGDtñ°ÆGòzccC©ñ‘:½¹¹)hÓxXomm Ú®FóÐh×ÊTã¡ZÙ6â5´kÓkâÖ\~%í\ÛÕoPš€¢¦FCX¹hyy™hnBnÞ¼™L&/]ºÄ÷—J¥&''ÇÆÆÎž=Kï&]>QúiÔÉÚîDì§-þ4í§­ÝéÛOÛfƒ`€O÷Aå HLáÄîº0¨kAŒnv~ŒÞÝÝm‹¦×i~t'×¶õ“-jZP©T …oqg||<‹)‰ÆÚÚ›„È?ªJ¥’ÉäíÛ·s¹œÐäþà!ŸùÌgŒôÓO?m‰×Ÿþô§"ñúSŸúÓ¦ñýÉO~RÐøHXâŸ@jÓxª:d¤éjZ¼¶këh4j¤íZQÝÛÛk¡Ÿzê)¤¶kÅëƒZkúZw;MßæÂkÿì4]ο¦O…¥é£çxݼÌ~4½ÉÝ^MíIÒþEM R©ÔÛo¿|¬€R¯×9B?ÏÏÏ ±áÇqèE¼ ¦pBOñAEÊà-?À†.Sx³‹tÇu]ÿ:2‰ÑÅëbìtoo/Ó˜]¼.†×O=õ”Q$¯11~ôÁƒ™ÆÄÈÉëžždŒNã#yÝÝÝÍ4>Ö¦ñ]]]Jm¯Ó°n…Ѧñ²Þ¿?Rûi«Óûöí3ÒAåÁèÖÜ#Àô¥ƒr*Úe \×­Õj·oß®×ëŽã 8ŽóàÁ:í`aa=ƒàºnµZ•—Lv‡„C‡¹^ðƒ‰Á c r4i6ˆ2ð#^W±˜k\̰iŒî*s…-_%›Æè®¶u×Üø«y?Wíüµ;þúsõÀÄÐ+uÌø~Œ?‰±# xb§0]БÿÄÂ?íÀ Sz¡# ¦ÔÁ?Õ€é‚aÝVù@&†×˜9Žá5ÏÈH×ɰ Ú)‡sss¹\îüùótx`vvvnn.›ÍºªyŒ§OŸs‡˜žž.‹º ø;©mÔîã` ƒœ`½­‡OxpÛÎT+ÿ`¬öÞ0¨ã½AÁ¼Q+·:ÍC2^ëZÉ0Ø]ýmø&…i+S2'~Z)iÁîî®îêêì/#Ûýhª™ÝES OŠ`J,ìÈžp^ÜPéÕ­kÓõhA¥R©×ëüR†çÏŸ¯×ë¥RIß××—Ëå*•J©TJ§Óôîu:¾víZ&“‘9ò¤ß¼k8¥www—êÞÞ^öYЭ¯ª©=v>èÚq+AÚ¼…ãŠ9÷6Ïn¤]=½°'ÀÛ1s<í»š‘¥½õš‡Ø@ìnsH†FèÆS Á¾³³ƒÑôý@:’$»*à×ÙÙ›ŠMa[gWzwc:r h˜hW9$„4 :àL=û§›u¸¶¶–ËåØ4C–Ífu½º3ÚR³O­ÌŒ„œfxíà§•ÖÉð‰× ì>ÁX¹í­· ZY³†¯ø1vxlÀ`$ŸAii½!_gg»³³ÓÓÓô΂!2üëìFš¯Á6ÆÎÃ<¿Í#Jbáiç!\iZa„’F<|ôRÄýª'ôC Ô£ôÅÊ—/_®Õj„Z­611Çûúú”Ì€NDøÖ·¾µ¶¶FQßç:§Kø¤fç…3·ÞkÑ BvÐÕÊV¦ðÙ v+ö¶k ¢€¿M` çøHL¹³³sðàA¦•!òu‘>é‚áz÷qðF’ Ù®#ÖȪ¡keD`2[L#™~øð¡R[P >ÿ‚¦¥÷) ¦Ú'&''/_¾<22BÿeoXVÊ•+W*•ÊòòòÔÔ!$“Éœ>}Z<às5ƒ‹q§¦‘õØ]š¶jãkã÷ÒÔ+éÖk¼a˜24æHÎ;¿E€‡+Ú ½ÀV¶õ¬6êhê»^!ËÇ©îé顟hR³œ€Ææ‹Ž@([yj˜jš' ]]]ÛÛÛ‚EI/lhëºGýÞ÷¾G'8Ž“H$˜K ö‰Dbtt´\.Ó… Î;LJ‡‡ése|¼ÝIMþÙ'ô«ù̼W ˜ªL½ºÓ“ÿœÖ­”iÚ\CP[äÓ@NkêiFåÊm€Ç´Z£H¸wS˜GÖ#üŽ|ök ÞÐ…6jÏ‚öÿð ŒaÁ·,ºœº #F­ØÞÞ,0É ñÛÛÛô³'!à#™V9†.fjL jµ]í˜ÉíÛ·Ùçx<ÌH$ù|þÒ¥KÅbquuunnnff†± F øŸ–ògxu1z]ÕÝÇ`ûÕjM½>[§r»¾‚­°›‚b‹_T¸` –:JaÔ—i$üÍú¡x‹pTËÙ0d œð­õð™¶Ø.ä+áИ<ÂÕ?ŸA¦=*º $Fñ)ˆO Ôi¤ƒ¥Y0Ã^ÏV¦”®S{ ½ûlÓñð)Øk\ÿ}éÀÆ>å~ålÖ[!×X‚Ê£Ûðvér"¡]é`Ï“ Èp‹ßj¡З ç0⊠h8RI„ÏøHªuÞžžö=Ó ÖV& ¬•ì•íÌkC !FãúõëkkktnAÿ… ØK“¡Ë$¯¬¬”Ëå¡¡¡'N(g*iA·4U>©Á^Øëƒ¯ÁÔkG†ü÷ k u3ÍT%ž¬öO;æÚÎ"³îlJ;äjñPêçª Ï0†÷¾•.i+ŠL¡}{{íBOxâi˜z” ­$|fÓHOìééa mÃÃ9ÐVð $@& ¼' ²ÝNÓ×ÉÓ×u/_¾Üh4FGG9òàÁƒÅÅű±±7n¸ªU§¦¦ªÕj.—Ëf³õ.î‰Xþ”S¸Ge ’"`z3Þ‡?~Ó#A ^8M3+í,s÷ãÓ‚”m‘} 9…úÙ~“³ÎfDby”ûAÞF#-Ó?yÐ`$ò XÙJ ÏJ _+óÃ×Ü@=p/0šÂ9Lð^ ¨"ÈÔya g‘Bmr~¾­2¿lW~¶Ö¦p®xØNGz8*ÀÇØÐ*tª Åxù!CžÔëõjµªË“L&…»J¨Ö­xe§åõ°ìzì±%J°8ýP9³ rÖôE—S€g$äë„ENe+ að:Ò80#õ¶×Ä.¸­i+Ò€HžáªšÏ€Öm£ç•4ƒo%|*ίiÁ«ë €jØÛcó@+$ÌËCØçÍÍM¤A²§~æ_¦¼E©ù̲îîîÖÍÔÒ‚£Gf2™ëׯŸ={6‹Õjµ›7of2™£GÕ`Àìì,}ƒ¢Rfffè;—™°«rIKæáH!F†7 D²Ìüƒ%r_¤G Ìpþ 2÷  œ­G‚U¾f ?ÜVöêH êHºƒoeaç½2ŒY÷¢„IÏÞ=!¨Óže P9R× ž-âa0ÆÄkñö: UÂ9yEnçõ„yà³OØæAZŽÔÙ^ˆAB8¦œíàÁƒ¼·»»[‡×ZZp÷î]ú4ÕLè¿étúêÕ«<ט™™èÂÚÚÚ;wÖÖÖªÕªÌJ˜Ô-0©Œ|¨Z BGŒˆ….'OüÓ]ýx‚¢ÌfA&0D“Í.ŸÍ”ë€Oº¥ç•1­xØ3¢0›¶‚ã‘p.göŒWF*áä¥å!k]Œ.ö*c`* Äè[wõ¬óê²y^£Á¼ ÌÌîÿzo?Ào#ë/ @~OOoQzéë Q´€áz2™¼víš®¼mHŸG(•J«««„\.788(?£ˆÿ‡àOžÀ¯Ë gÆP Ìch ¦6d6eN#ò¡Ë'†vxÆxjë JPG¶2mË·RB,@”T )ʾ”­ˆõl¥fe¼ø•„FΣ‹— Ž(Àö­ÇëRFZ€´2§5+¯ƒå<Ì#\É:xöÌüÃ0/´Å $ TÀÏ•½Åg%HÃñBµ¼E†Á+DRËÆÆ§þžðA½½½}}}D¿P ‹‹‹KKKÕj5§ÓéÉÉÉt:ÝÛÛ«kî ù0Ìë Ÿ“0Oò©ÐÔuP'dÃD9-úåchDR“‡/ÆiAMØ)CJ„j°ñ¤ÊVFñp+]¼®•g¼ ä2èÊùuä@h¥„|]<ò1ö-éÙk9^W8ž(3``^îK†X¸­Õ@ƒj€·†y;&xÌ@=ö³Ÿ¶‚—·nÝ‚`q]—¾™7Öëõ;w®Öj5ùŃׯ²V2S»Vžmo´5mx¼Ð x¤Qüæ£:‰d¬<¨HÝþ„XaôË×"ƒ¸—ÅØe¶ÈI÷¿©þµÌîyDá#u¿¬ÀÛú·È¿,Ø"ÿýÄó^e¤Òkiý¹‡{Ê@÷Ù3ÏÆÆÆ_üÅ_ˆ¿Ï‚BLŒ=ä IDAT™-<.KKKµZ¨.€ä!}öóVjÝ-‹Vº÷O­àÓ™ò„+køTˆlå¹Õ¦ñvZøî”{lÿþýžßéÏgöŒÁF1žÇ†ò[ð<~DÉZ€W£#[ÊÞñ^¡/Oª§‹av%Ùò̬£h›››Ê¶@¼O;;íòvþtìiבNxøapO»Ò¢ !-J͘ÎHÒˆ^ð”E7Ò Æì¨Ãæã7 äHå!Z€6¾B‰R©T(X__w'Nçóùd2©¤<¨{°.Þ†0†{Ç$PŸs‹£;H¸…óÔExÚ±E%¤ù¯„f2A>Ò+À­@J”`¬k%€·Q+%QðŒZ ½Å#IœÙ4RIG‰Äh½ b™@×OŒóBŒ «rfO¯0® ô : ½˜ÑÀ+Œ`H<§x2!Ç4ï³LàQ aJ ø2µ´€'ÂRˆž¤¡T*-//—J%ºþñÀÀÀéÓ§Oœ8¡#x¨–#10¬¼zÆ­iŒ'Á÷e¦ÙXN‚^e@~¹­²6]¥W® ÓJö*·H×°ÓJL[yÚ75`,ØXE摯Αñr:­£ÈH¸>^†dÞ‚ÏÙ ’á©•àmcD2<)H ^f÷$¬2RøŒ«0²cHƒ™Ð^(?or`¿éEøxÄÕ´€—Z­¶¼¼¬#ñx<›Íò–ùùùr¹Üßß?33Ã?¬aØb[¯ñp¨ƒ[#0æaÉOþM¸Âmu^ Ø#3oš°MÞŸJˆÒÙuÙì@Ø"‹<Èøµ'9@WT8IJ<{ëÔ]ͳV2uÆøª0™!'Ü/œ!¡o°ðÂã:{Z™~n|ð½l>ئ‘ä›’ 8Ûæã´@'ZZ°°°N§é¿årÙqœxª777Ùg¦ƒí †C¾» ž^ÿ¬½üÉheá…!Í(§`¨óZd“óZ™SÎf¤ƒÊ#gÃz°‘`Ë9}¶…Ç ‚j…!Bà“ˆÀñìúÛ½Àxuä@ISdï¦ Éеò$r+A+½AÑ Ÿ´Oìi•«W¯R8/ ©TŠ.÷<¾:`gð¯´ÓÏö´/t`àðáÙL&“ÉBÖÖÖîܹ3???==-? ¨¼¦÷xoj€ÜÔË÷"÷Ž÷ÊdÙ»²Œ¶®Ùº;ø´ÅVëà°£ìp.Û‘™ùÓ½]ÍpNÏúålºœò>ÑeƒÁ™ÍŽ"ì7§#üã-JJáo=ÎáŸ^xf–ãa2¡ì·IÚ“‚èb”Þ¥yðUI#¶¤5<ŒìºÏ~G ˆj!$å<Ä‹/ëÈ“ 0à­ózÆØÁŒ=+ôíž×vÔÏë Ú× ÀŒ]…Íìvõ+|ƒ êtˆ¤žvOŠ`×̘¶º^0À‰Ïï Ò<Å $®BSBÀç±£~â•”Ð0ð+ã•©¤ž‘<+?ËZÙ ®ŸÁe†-p±¯Mà·¸§~„V€w›[°|{{Û†8ŽC©Õjtüÿý÷߯V«”T«Uêåett´^¯ëæÊ(ʧ`S ŒüÁ­]ïÔ{­{€Ç-êD¶²ƒ1ݳw¤=¨zd;¾ž@zôŒTn;¾/Ÿ¤!À¶Ña ç÷´`F ð™ñ`ŒÌƒÌ‰Ìà™Ó³­i0¢²˜Ù#ƒ®®­þùx9R ظyK@¤.ÆBËðÏôöã¯M×ymhA"‘ˆÇãׯ_?}úô;wjµZ£Ñ˜¥ó '''…øÕÕUa"¼æh±óeˆD"›››T üxízT¶2‚Ÿ}YØ={éJØùu†NÓ=©Œ´ ÈúáÞý?žF( ÿù‹Š`GG€V€ÆÓ‹<›z¨öÌ6ÿ™µEÆ^]¼à•ˆW³£ŒÜÖ,/{·¥7³^Á¢ô´@ûÅÉÉÉF£Q(( ÿÖjµÉÉIå‚sssÏ=÷Üììl¥R!^´¨Kn Jo$áõæ# ìrŒ§7ƒ[ùñ6©•¼O<[Uƒ]/>µÞ˜¤—À÷ƒ5½ð³Ïý£:‘Ô °XÃ3²6ùW!€-Jð¶³ O>”Ù`¨¦‘ò _ÞC²¤2ZhËÀcáÁ[ˆ2t©€WfÐÿi¥]!†½S¦Ú¹‰Dbff†·Œë‚óù|>Ÿ_[[»~ýúÒÒR2™ŒF£4@ `6Ò­@øá‡ÍËi´g>üðC‹ýlýÍØMÒ{âèòO›tð,h /$96Ò”FŽé—·–ÀáŸïËS{B2 ´H˾GÓÀ1­Æ[x¨ö“GÈ °XL©€MG<5k«{<`ézü•÷|Œ`iz´À}$pcAúûûãñ8}XqmmíÙgŸšš*•JDš¨¨ƒ.jߋަæàVº°½•­,²YìÛ@ìm‡|?{ÕZëÆÏ,²5ØÁ¹‰fÏœ2<ã#1Z®¯e8×é-Í#ֲŞ€|Ÿæ!sÌÃàm©ƒpÀ‚ÔÌ󯹇-:àÞý+ëú·ûîììØÓ‚»wïž:uʈ0‰F£™L楗^zíµ×!…BáîÝ»B 2`´Ì+oñï휜2@¶¾•g6à[ƒ‰…©Ý޾XÛè`Ë´5Øû×xr`G” -ìÍÇo8ê ÚÈî'R†g< v`Z& þûÕA¸o+s¶Rä§•Ê?ÝáCPZCw¬í ÊT£5vO€×Ù~<Ì›‚½9`;‰PM÷oav$!@=»ë4¼å¶x+í¼W¶^OP—¡ÚÎ÷íÛ·³³#h¾_¾•œA°ÛЂh4*,@„!F£^¯/---,,d³Ù .èÞ–ôÁ´Løá‡v^PeÝi^eiž·•T©•t§%pÂaäÅÛíFš1B`äà(ï•í°æÖ+¼WÚ¯’ýÀ6Ô- ] ̰Wˆ‰D">4µ3¯äc´¤‘@Ž×JÈßÝÝeZ³oß¾ÝÝ]YÀÌ*‡kkkÅbquu5™Læóù¡¡¡ÞÞÞˆþÅF£‰Dðšžúa/&Æ.Þ+ǘzù˜fx›­›M†‚¢&Í (Í£#vÄÂŽøñê®õíF`P¼ûÐ×ôÊœxøÇÀ<ì1Ñö`¯.†÷Ê1²¯e`ÖÅè"e˜—㙀d<¨ã¡]× ÉóQ|$‘õÎÎÓʘvÒ‚b±è8Ϋ¯¾zôèѸbºöQë5…L?12-0ÑQ|Œ)©RjJΔšŽ—À^|Œ©¹½øXãG|Œ.’÷Ê1²—Ñyñ1ž^|Œ){ù¯777™†½ºH] RG¼€¾šÇ9ìaPÇ€7Âñ0C5¶ñÐÎk l¦ñ²ÆGê´ ·øVm×Jð®ëºY´x "/W®\ó9ûÛßB~÷»ßBøÏþõûï¿Ï4&F)ÇèâáH¼®×ëÈ^cbäø`)L’ü“!»±%üøÝˆŽÝ8ŠnÜ?>„GàëÛ Ü "˜a||$ÎñÐîçjä~®Ë1°mÏÊkq#‡Rÿîžaø7̓×ô}ÍÖž}Á­¥´e¥R©×ëŽã$ j‰x `kü¿ÿû?BÈÿþïÿ²Ïý«_ýÊ"£ýë_[Äãõo~ó¦ñ‘MI•¬MãuCÅLãý*˜™’$†GS‚Ò~F;ðÚ®füÀtlÀTomm1í?ƒÞÞÞD?|ø0pM'Žató2ûÑôšµ½š¢Õ“§}Š–T*•‰‰ ú*BH<¿rå #HÑqºÌ¬{{{•Ú®UóôSO=e¤ý´¥úàÁƒžÚO[îééQjÿ0º»»[Ðþ3Øé®®.A•ÇN8pÐÍÈi§÷ïßo­›—ÙTïÛ·¯-šžKít'×¶wõ,¿_·À}\._¾œN§_ýõ[·n½þúëétzllLhñ]¯ŸúÔ§ýÉO~#k|¤þÄ'>!h|¤®-&’êC‡!ctÉkúr,|¤Nã#©æ >R§ñ‘vÄÔ”JE:툦)­ôO"ƒ¥Œ¦±•°$ÙÖu]?zÿþý:¨<°ö¼•n­íÆêÛÕo šHˆO…B€åŒjµÚèèèáÇ#‘H,m4ta"OÔ÷”C‡¹®+kÇq”v»8’‘#e/>†„c0:2TŒ.RŽá#u^¼îííe:¨9RöÊ‘p F?õÔS‚ÆÄÈ‘º>Ž9xð Ó˜]¤#ÇÃ1T÷ôô cx‰‘ã᪻»»‘1²ÆGÚé®®.Aã#•m}RVŽ™Ž÷X´rqô¢•Ô$XbaM/t8뺿§üU~<'î³Ò8ú9‹‘ î^è®Û0×ø?׎¦W–vsõ‰¹6Å\¹šÆ˜zù;/òêÙõ‚j ›Â¼´c@ù~¼rŒà·#¦$Cðä (Ò€! ÁÒSº€'xÂk6N°»»KuWW— y¯¬11¼¦ë{ƸíÛ°£ …èFàáXæ×.g”Éd._¾œËåŽ9òàÁƒÅÅÅL&S­V«Õ*èg´s…çÿsÙØ¨ÓÊy Ò¾kB#»Ÿ‡p÷zÚw%ê l%™( é… -h4årY¶§R©Z­V¯×}ÞDÀœÄ;Ü«„1ätv?Þ@Zù¼ÖÀ¤u/ÊýðäÙ™VîC Írê༢ٔB¹³³£ƒp]Îf#½³³Ãk ~‹Ž:ÀdC„^Ñ Úw§Jª¡l«# øHS SÀþPõd™ðÔ粜yÿ£7'ÙЂJ¥R(dû­[·ŠÅâúúºÏ›ðinOx}^íùñZ´²ÞvÓ«É&Ážiï~ög€•t¾fÉ`ˆDÚ›©´óõ  ¨³à{±#|mºJ,´²÷æ‘ %½lL+ÿÔááÇJ2áiH…d¦™Å“Ùø¶°Ö‘ !Rgáí<9ЦmhA*•b7Øú9ŸÏû!Tz¬¦ ù÷§~ø É×ú”T+Ï}¢Üo-®¼ÙûÍÓî V¹2R€Éƒ )-~ú²«_Yg:˜7ªÇ¼*QÖdž@ÈD°9yÍ ~öO>X!3ýÌ,ž´Cnå©e âÙ  pŒNooo{’ !þÀ´k  ´vêA­V›ššj4®ë‹ÅÅÅEúÙ?' „èNðiÅ¿—Åp¨#­©ÊìÀÊf'&ë ƒÝÞ@¶BÍ®†+$LzÂ'¦/£ªð‰¬yl̘÷ìÑ4¿§…[°™y@´5äËZ&°âå 2üË`Çë,JâÄû×ÛÛÛL T@¶Pæ[d‚~ñºHžpÀ­-p]wllìСCFã7ÞXXXˆÇãÅbñÆî£Åüˆª•”Wx•PHf¤7ðmQþh1Tß—)Zyž =íT«´ÛÕƒ'L%F`iÙ‚Þ¶>© ¦6l~>³¥F™uyä^àœž$ È<’á©áxæÝÞÞ¦Z†þ3O¡—ÿ P  ²ÆÄ0P÷ônmm)©ï¥hõhA¥R©Õj“““‡.‹¹\îÕW_­T*•JÅ'!ÐÑ‚nÍ<ÛÀ5†#  Ò.-Ÿá“àõ$°×“"`²~Ô-j ª»`cò[Tìÿ&Qð¬ë, ´xè²ÎÀ3œßsÛuyðÀÀ¼Òl2Ϙ x¯2žÂ'>›·º¶2 `ZG äHþ•^e=:r û¬ônmmyÒ8†zåF”tÁ†Ð7¼>|˜òƒd2I—‚¡ö hA·æY^^wK³^eÝ-Ý£’½,è%@/²6¤n=%j^…Èœ¦d®ÇššØÙj‚Ƀ?fW‚QOÐê1<<*!Ö¢BOà‡k3H9n[<‰ˆQ¿žd<ƒ4$`0&C»²w9^ ê‚W êÈH>ˆá! ´ÚÚÚZQ/ƒj!R鈂ÃÿL<íB Õ7’É$!¤T*ݹs‡2888??ÏìþE–ÝÒ¤Á»«l¦G¢:8ïæfÌb*±ðšÒ%™¼6¸* 'Æ‹l…¤Ð)þäT6¸B‚Ê©ý!3ã"M%1Mõ vv:0jåéíÖßq4­¨ÐÖï3'˜™™9P¬„v] §9À“nñ­` ¤•Q< –pNÎa¼J  ý@5Ay -Ø{TP \¯ã¯ËA ýê>cÆàí †BΟ?ŸÍf !‰D‚233C8 dÊ¡n…'Mu° @~°º$<¨ø‰é‘àÍgŒ÷¡þ±¢À3?ä&àxf–A‹Ï,󛿲É{†ÏišMi÷C`ê÷‹fFÒ¼V˜gïÂ} má­ó¼ÚfÏ+cÏ̶`àI‚i¢dÐUBuìuPäÙÖòëöƒçhüykkËÚN?ÓíÚÜÜdŸ©}ss° m™ÆXtÚ†¸®KW3$„”J%BȽ{÷æææfffü¿'II ä¥'”1=êé?F fê‡ÒœUϾzÈ,À’ùP§5½€ „if]+]NÀ ïÕe³îΆHd"ëZ™ökÚJ>‰{Fb®¹uð ìüp ¦P ènéJW ™º;ÜpfkøÄC²u8Ê¢ô"í²€Üày;ýÌ?ÎùVÈÏ‚ÞØØè±£µZíë_ÿº<ÁÞV¸víZ__Ÿf [%J†7áÙMà=³É1|Zd€Y~zÕšÊ5[L6Lf£< `”yxøÚ*këy|ÄO,¼Jû¶4«ŸÍ˜…V¬_dï2Àýê Â4^ ê0É™‰äãïnÍ ±¬•ß…rïá¡Z ¥ÂžÇcJ¨†½ä€­ôÊWÏÌŽ„mÎùoll„@°°Ï–´ ÑhüèG?b“ J¥ÒØØØ­[·‚š[ ~yaHþuPªË©9»œJaDztÙ"ˆ‘ie6 íð¤8FA™ÇO®Œˆ…][%0ã[éÚš¶RR\É@À³)ðËÄê<#…ÌH`nxcâö§ç؆'ëb˜æáJçžWÒ€E— ÓVù9pB @²LLÁˆ±€ðƒÒëx¾*^ ^!ƒ2›àå3ØÐ‚D"ñÚk¯Ñ‡éʆìŠüBÈÖ´@~äË Iz’ Oȇ“SÈì ðÒ£‹ÄdÓª5]hWÌöãëvá©xÈ ò Ýg++¡EG`@’[Á°„¡<à ' e6%qA¶§}K?‹?Fv%=’·NIŒ”C\ä!kÿ^Ý0¸àÅ€½i¼¶•ðÌìJ çï‘ë2Ñøkq¹•ÏÏ€f ­@B¾2 ÿr¤¯›ׯ_—íW¯^]YY)—ËçÏŸ·æ<-x¨Z½Y¢€×Áªg6L ºÌž0Tƈ XDzưjÔ#]@ᔤ0#{H€<ÊÄ#‰….^G”ðŒÌì™SG<[éìž@®ƒmᨾ5%¥PÆäcëñùç2áµÁÈu910o¡øÄØaà×¼ ÛJêÀƒ{B¾)lö20Ë0@¾’.è¼ Ô•ãºH¶¡Žã¤Ói¥ëÈ‘#~ÁG½JïzÂhùQH6íÅBoã^nÀ32ƒ²•ZHа­Y+ÛþuÀ ô«f˜.ÈêHP•®üÀ И²È€ð‰÷2ç-Õ#[r öò·,kJÄjúâ!œ÷ ñJ0VÚ•P-S¥]¨È ´(í›››ºÈf¤]€m Û*Éò³±ðI‚º÷ùºÏ=ܨ€µ†ú£÷.çóyþ¦@4M«$‰Äãñd2és†AWW×þýû]×Ý·oŸ¬www•ZO_ð(´ÝÙÙÙ¿?Њo‰D<{ôÎÎŽQ<« SÉë[±ýƒŒgûdz•¼ÿùHÌ·Ì"ù ‚¦ùY6¡Ý·)׌Ü?{ÞW€Ÿgÿþýì8”íLc¾;LÌŽêåîŒyË^AóUé¼p[àó¦^À®Ü"þš΃„3È{ÀgNa»‹îÌÔ¢´³«8À‚¬¹uÀU¢‘w{{Ù–dŸÙKýö¬Öóóööö±cÇÿÈ!Ì%¬T*ÂM ŸW¯^ dÊáÉ“'ß}÷]‹TÈW8~á _øÙÏ~Æç·~÷£²á¿øÅwÞy¨ß¢;¾Iÿêêªçþ±îeppð§?ý)fÿuÁ‚ÿìÏþìí·ß†óã3Ë‘§Nzë­·äüÈœža_úÒ—~ò“ŸX—çó—ù—+++BýytCCC?þñ•ûß3Ãîî.£ËJMyöÙgß|óMòè­ë‚n«óòý~ùË_þþ÷¿ÏçªBæäõW¾ò•ÅÅE£úì_ýêW_ýuÿy”õB¾öµ¯ý¿ÿ÷ÿ0‘øœ¼åÌ™3óóó˜¶v–sçνòÊ+@Œ\¹§…ÏðÍo~snnŸßÔ{ñâÅ«W¯Â‘@NÝgÖj|||jjJ—Íó³g_ßþö·á§P7êõz±XL¥Rð %”PBÙëBO€vŸt,{á¶_›m˜ IDATžùñ•åDæ×e3²nÙ7Ÿùuûo”Y Ú3¿ìÅXüä7ò’DZÜtë>µÿ=ûò5-ˆÅbù|ž· ýõ_ÿu£ÑˆF£ÈÔ¡„J(¡„ÊÞõ]IŽ=Úh4‚z±r(¡„J(¡„ÒòÑh0Ðh4è˜,//BâñxPCÍró‡ù}æw7ûýäo^ò0˜?Ì¿×ó·ñüs€ròäIÞäºn¥R¡ë3qgtt4‹ù/Èzk‘ å°`{ôÌfÑßÄz3‘Mð º`Á˜V~jе j¿í%‹µ;¨01ž•û?t騡]sdC£ß¯…+À&¦_¥ÿ<ÊýoÔÜÓˆ/²IŸMLó›þ«;Ñ5è\Ê0ùWlôÙ(@)®ë*æD"‘T*õöÛo íÃ)¡„J(¡„òd‹öÅÊ®ëÖjµÛ·o×ëuÇqc±XÈ B %”PB å í”Ãb±822²´´T*•–––FFFŠÅbSïv„J(¡„J(íÅhëºFcvvvtt4—ËQËÒÒÒìììàà ã8-/2”PB %”PBi…¨o"”ËåF£1<<Ì,ÃÃ󳳕J%¨E쬧ª>ÏÑzv²I°÷ä&͘Øh4qÒçÌGë‰{m ³›ŠeÑ—ç÷ do†J(„!ääÉ“ßþö·™ÉuÝ»wïŽýð‡?¤‹Ñy###¯¾új"‘ð٥뺧Nò™$”PB %”PB±·ß~[çr]W1· ‰ôõõÅãñ‰‰‰Z­æºî/ùËB¡L&ýs‚PB %”PB ¥cE=å299IY__'^‘033ÓººB %”PB %”–‹öÅ£G^½z•~îííÍf³Ï>ûì­[·¨%¼ J(¡„J(OžhŸD“߀pêÔ)Çq^}õÕ@–; %”PB %”P:JÔ£•J¥R©LNN²ÇïÝ»7;;{íÚµÖJ(¡„J(¡´TDZ@Ÿ_ŠÇããããýýý̘L&;–J¥ÂB %”PB åI•Ǧº®»°°@9|øp&“aöH$Fûúúèý…¥¥¥V—J(¡„J(¡4_Ä'âñø7¾ñùùyúh"/•Jenn®P(?~¼-µ†J(¡„J(M•Çn"D"‘L&süøñ›7ož;wŽ’L&©k}}=g³Ùk×®E£Ñ6TJ(¡„J(¡4YĹ‘H$‹]ºtéÂ… årùÎ;„ÇqΞ=Բǡ„J(¡„JgŠúI:™ •J…T ”PB %”P>>¢]å0”PB %”PBù¸IH B %”PB %”$¤¡„J(¡„ÊGÒ‚PB %”PB å#Ѿ* /˜uÃW+…J(¡„JçK´€R(J¥’Î{íÚµð‰†PB %”PBé| †D"‘l6;44D¤—*ÒE(¡„J(¡„Òlùˆ7,Æüãñ8}‘ME‡Â÷*…J(¡„JÇŠ ÓÑ‚H$ÂûpÎ%”PB %”½%:ˆ§Làÿ¿i:á³±%”PB %”PZ)0Ü? ‘„’L&WWWi}Âââ"!d~~žzù71šoB(¡„J(¡„Ò fÊáéÓ§‹Åâ /¼à8N¹\žœœ|ùå—çææ!ãããÂCfJ(¡„J()ЂH$røðá×_}yy¹^¯ONNÆb±7ß|óîÝ»ñx<‹ÉMþèþH— OšÙ¼à©{Þ3j^ÁMMÞÔJZßÞ&˜T¶P:A>Vãf¡„J(¡-à‡”C`ø8K8!”PB åc%Šu \×½{÷î7¾ñb±Øh4ÂÅ‚÷qiK l© ;i{ý¡„J(¡4UÔË%“Ét:½°°022255U*•B0\\IZÖµ¼ •…„!”PB åÉÅM„H$FGGGÏŸ?¿²²255µ¶¶æ8Îðððàà ]‡@À’L&säÈ‘ðV´OiãBÛk%”PB ¥ÄcÊa<'„¼ùæ›ï¼óÎíÛ·çææúûûOŸ>-<<<<00póæÍ………?ýÓ?M¥RÁÕüdŠ/n;ƒ¦e{NDùA(¡+{… „<`ωz´ Ñh¤Óiú.Dd"úÝ»®ûþûï‹ÅµµµÕÕÕl6{íÚµXÈ^=ÃŒUî•m %”Δ=ÁB*°§Eý€b"‘E¦`GÀÚÚZ­V+•JÉd2—˽øâ‹Fc {TZðX¦çí†N»ïä{™¡„²¥óÙðcï´RCå#ZOTñ”ùùù¥¥%BH6›ú¸½/±Å÷û„N›îòƒPBñ)0ÈS:Ÿµ„"‹î´ =‰€ç ‘Hdtt4›ÍÚ÷„I+±™ÞÑg7øÛU†§Èü ÓF8B ¥“eOüLöD‘¡¯ë4ã7(*Ya>Ÿ×=fú1?PZ¼¤±®ßιX— ýü1?NB E'{â§±'Š )¼X™žÖ]Û`}}â8N:Îår©TêÉ>b:s)ÀΟ±(Œ„ƒ¡„J( Ñå¹'Fcll¬Ñhd³Ù³gÏBÙÐÖ¥óª‡ç6ø¸¯–ôÁýyyÁ‰AˆW²@„££#º»îÂkµZÍfÓòi%BÈ¿ÿýoOâEAÄCº^Dh‹,Ëûûûªª²ã]×××× !î¿Ï‹ ‚ ÈyñJœe‘›ã¸¹¹¹x<žÍfwvvèõB¡Ðl6·¶¶.ÂÈ‚ 2ˆXÀk/(Z6SNâs·¸¸833c½8??ïþKK‚ ‚ô‡³­/(Ú»ÿ¶B¡Ókú###ìßwß}_3CA áÐ)Ÿ²å°­P° F£AX<ÎÏÏ_´'!‚ H0q¨wý&BÛ©Qyž'„†Q.—#‘ÈÄÄu·A 8g}ATýv¢iš¢(ær¹d2I/â ‚ ‚ Þœ[°3äD.àAu‚ 2x&  ï/—Ë;;;Édæ !²,öœ]AAX¼ü°òúúºªªkkk±X .ær¹ÑÑÑH$BO?$(A$¨x3[Ðl6———yž¿{÷.œUÀq\"‘ „d³Ù½½=A<‰AAÿðF …x<žÉdØ‹T躎²AA‚7² ÓÉÇÑ÷A 8|*‰ã8<­AAÞ¼ù‚"‚ ‚ o( Ay…g/(:ƒ"‚ HðñìM„f³Ùé.~* AAÏÎ- „H’Ôö.~* AAÏ?–$)•Jy‚ ‚ ý·"‚ ò ”‚ ‚¼e‚ ‚ ¯ðfo,ËÃÃÃîÝÿâ¿ ¿íï.ºyã±Ïn<ùê£'ö0s‚ã&PÆ ¢Iì­>'н³ÐØ{pÜ÷½yéÙ×ÙýžÝ»çáø¦…SÏ ðFÀ'‘Òã`ëËóã LÓ|óŽLx#…Z¯\Ö17Î< *hºoÁ@÷s·ml·mEmKoÍQ§„xR²§–‹'í§íp@ÚvodA6›UUµÓÝ­­­h4ê&¿ÅWÏ9Î6—õ­DÁŒ T ¹˜x¢ öý@.xÿäßvÂNQ\ð ÷‰6²ÀM—ãPž—SŸW¼²ßW³ýV‚tËEî¢ü¨úÉ+Y`Ét]×+•J'?‚ ÀKzœÇqÑhôÑ£GôV>Ÿ÷ê«Ê¾®Ø{q?ô·3§.[àà }à‚?hþõÙmCÆáçX²ô•,°d·¦i¥R‰~(¹Ñhðøz‚ >M€gbÞúŠsö:ÉKÿÊö7l¿UU­T*õz]Y–'&&Âá°KË|ÒOk8s€ ¾‚‘W  íelÐuºöÿþ÷¿Ïž=ƒÂÓ4çyËùÊÊJ£ÑˆÅb°Á°ÛrõûDàãÓš…³8@¤7°ëò\/&mdÇq‘HD„B¡L&ŽŽt]oµZ…BÁ0Œƒƒƒµµ5òzO&Š¢¢(ªª ‚ ¬ôVÌøR¾çàö]ñìÀ<¡Ï'Ä#îù?BÈ{ï½wýúuË>ø V«‹E]×ÿú׿NMM)Š¢ëúüü|,c]ÂK‰Ÿ|ò Ïó>üÛßþÖl6ÿ÷¿ÿ‰¢HX¯V«~%éÇqøø!ÈÁ‡ÈC°Q:/æææîr„ëׯñÅžDfš¦®ëår¹V«†Çãñx,³,´ý¬"ëÀMDÓ‡œº73P wã&PƼñ&õ?¨A ÐØ{pÜ÷ý‰ÂÛ¼š7õcþµosº_ýµƒ oyÇq‚ d2™{÷î}öÙg†a,//›'xÒ~‰ ˆçøú´ö¡}†(p† øxðM„N•i|||||\×uØ¢HúRó÷°ûFñAE ã_ËÙ‡6ÕÀ`áͧ’ªÕª¦iîNMMÁ« ¸÷-høtv‚ ^‚é3žÉ]×átdÃ0=8YQ”>øn!ÁÅ‚“ÁÕ(od|NGVU5›ÍæóyBˆiš“““žDø +ðaFsǧž»m°Nå¢ è– Í {# ºeà¶”ÊM"¢·•p7neÌ`™„íxpè§ Þ=N7v[Za?Yð¯ýë\âEAÄ_PDAdpAY€ ‚ È+¼—‚ ¤R)úW’$x;AA€ãÁáÇnvIX?Æ×Aä\xôèQ§[¦i¾Meûh³Ù4 £Ó]QqÂAA‚ òß¶üº•ÛÛÛªªvº»µµF»·AA±Ï÷·A‘ºs©8ŽK¥Rì–AA‚‰Ãêÿ)çt«A 2Î;_É‚SXB}€ ‚ o*T¼m¿JP ‚ ÈÀÞ•·_Dp¯P ‚ È`áÐwŸ²·àT}×777Q ‚ Hðqî¯Ý~*É¥>85>AAK×_PÄ͉‚ ò¦òê›Ý~æ™;ÁÁišùz4‚ ‚ δ?å°Û!>.. ‚ È@Ãöà¯[@ÎЋ»×‚ ‚œ;ößzna¶œQ @Aâü ¤ÓÏ-èM¸9ùAAþã͹gÑ(A$xnA›qòAA‚Ï[Ýz ï%š'të½ÛAé]gœqòAAÒ£, ôðæÇq=b¯œ:ådÍqaf8K±ă ®ñ!rVYø½ó ÈÇyA6Ò=–"pH›p7©fó‡úupL§=p6(»ÁÎÝvÛ»./Zâr™p»ÍbìË©mƒ^{Yœ_Á ~èã7X¶:ðwofûQÜ]ï-pæì;ÒØÓ”Y³k¤ÀrUUK¥Òþþ¾®ë.ë±Ë$«ªÊúe˺Ùl¶Z-‹1¦iZ.Ò¸ž>}ê`ðóçÏÛz„UUm6›&\¤Þ᢮몪¶Z-¶2«ªÊ¦Â%Dêäþ`šæññ±Å6ÈÏþ[Ò6h¹·­¡AÑ@Šž?×·“h+ˆ«_ 4„®ë~Ǧ: ·ãÜ/ô`6Û(yžjeÀ~1ኃó5¦Àæ\.W(!F#N7›Mz×.õ,¿;¥šÞ*‹–ÐhŽ eccÃ~ÂÑ4ÍÁ`Ó4s¹œÝžz½>;;[,——— Ë¡Óét©T¢¦¦Óéb±8;;[¯× !º®ß¸q£P( …7nЈNË×WT*•l6Ë6‘l’ÛÊh{n³ªÅîÒÍEàöíÛÔM³ÙÌf³.Sá9ÛÛÛFƒ½b𿯯F£ÑÛÖ××Ý„Ž···;4NÕnѲ³(Mø]V×ûYoñEPÎ2y0èâ °:P,[­ÖÞÞ^*•Z\\L¥RÐãBBÚŽžéEí·(0'„lnnR7tÈNc7Oèô ôý7Z,ëd0ÇqápXû¸ªP(¬­­åóù{÷îBjµ\ÜÚÚÚÜܼÿ~¹\†ñÍÁÁÁW_}µ¹¹¹ºº ™P,eYÞÛÛÛÝÝ•e¹\.w›½<ÏÛÅ ›Eöé vVãøøèº~||lq©ªêÓ§O-Ù~||üüùóNõºÒåååµµµH$W ÃKXgš¦Q¤i[â|u„Éþ…†a†ÁFÕ¦m µZM’$ú;?;HÈ=ÖìN™Ól6!ghFƒ§OŸZ&iž>} Eæ¦ÝÃ0¨GÚþ@ý!Ì“å¾Ôì^:¹‡B¡5ÓòÐÑ‚ðKïèGgÄ[AÀ¶º~'Ù›½Μeçóø;€ê°(ƒ ™×‰z½þÙgŸÁoŽã¦§§GGG! …Báàà@ÅF£qëÖ-Y–‹Å¢¢(º® ‚Ðh4òù<Ïóétúïÿ;!ú›{÷îÍÎÎrÇóüôôôÆÆÆÃ‡[­ O Ãàyžçy _~ù%´Aš¦íííU*EQ²ÙìÖÖÛ²T*•x<î`0ü i?¤R)T4Õ4 Ú8èC¡P<?::"„H’ …À!D×õ©©)AÀ¯$Iì̇›òå8.‘H¨ªzppH$Ø[ÕjuggòV–å[·n©ªº½½ ¹177W.—9Ž …BÍfsnnnŸçyBÈîî.!$—Ë©ª‡›Í&x/‹FC×õP(¤ªêÚÚ¨(–¶š,‰D"4(Ö’|>_©Tö÷÷#‘ˆ®ë©T*‘H¸‰Ë™/¿üú~¶Üoß¾Ï硞d³ÙÍÍÍÉÉÉx<®iša’$---™¦999I÷/×jµùùyÓ4ëõº$IÕjUÓ´L&cšæÂ‚(ŠðûÆ„ùùùX,!¬­­ëºžN§ !_}õÕÐЪªÙlöŸÿüçÐÐPµZ­×ë«««4ë&''eYÖ4MÓ4žç÷ööLÓÜÙÙ©V«PŽ™L&‘H”J%ž„x<®( U9’$Áßx<~ëÖ-úPð<¯( ˜´°°dÎÝ»wß}÷]r"Ž³Ù¬(Š‹‹‹mëO¡P€¸òù|µZ-—Ë¢(jš¥V*•ѱ¥Æ¦EQ”¥¥¥D"Ñ)°¹Ñh¤R©r¹ 52äñãÇô9òÀ6û€óhp 6‹ôCPÎÒYR¿mï³÷åm7b£Ñ€à8.BÿQ¯×¡¹„9gY– !º®ß½{whhh¿X,Þ¹sG„ÇÓÎ[×uè×MÓÜØØ „T*AVWWMÓ\YY¡ ååË—óùÿÍ7ß‹Eº²ÎqUtúÄB.—[]]­Õj°SÁ¢(ŽŒŒ€%‰D‚Z244D9<<¡\.—J¥ÃÃCžçUUu—3333“l¹³9ý y¶²×áá¡$Ið·V«…ÃaI’êõºªª03ÔjµªÕª,˲,+ŠÒjµE‰ÅbŠ¢BªÕêÔÔÔÌÌLµZ…r‰ÅbGGGàŒvÒ”D"Æ‚`š&}F !ô¡VBè,— ccc„ZıX,“É<~ü¸T*±ëS´š‰¢H/f³YÃ0@Xêä aêO­V£¥V«Õxž‡‡Â¡ÔØ´D£ÑÝÝÝN±Ðš)M)ÔLZîjÁé°}dÐ4Áà®´åd`é//ˆ8 m,t¬L©×닚ðü³)’$©V«Á˜Œ†Zè!Úzikð÷ßï ˜’É$ …yž‡q$¸¡ë¬.‹0$]YY!„,--uk?Àq\2™4 ¶1ÚS×mÎèºû%9޳¬˜8S8«««Ÿþ9›cìäŠý"{E–e:§âIËuj ´µ»TU5›¦ õê^,;<ƳCç~E±ØF÷²ÓŠ¢(Šä¸u IDAT266Fa±¦ˆ`VFÓ´p8F‹Åb2™_‰D¢P(H’u£^¯³sZ€ZMNV4è3Bq®!åryiiéÎ;©TêÔ\]ZZÊd2ëëëßÿ½½Ô,ñ²¥–J¥t]?5|š0ûæÍ›°{À! 0}ÂΔô†¥›þøcBH«Õ’$ ö6rç—3l¹CPl¹ÿüç?çw gJ¥ÒÞÞ^³Ù„¨!«A ~÷ÝwW¯^ýñLùî»ï~ýë__ºt‰±(Š£££?üá9Ž“eùÒ¥Kà6j@Ž ‚ðË_þÌP(ÄóüÄÄÏóW®\‘$é§?ý)¤ZÓ4šlŽŽŽ†B!¨{­V+™LBFÑY~S/4(I’ ¾‰¢øÇ?þÞ¶ „ˆ¢H3GÈg¸5::úí·ßÒRÓ4-Òú …FGG!¥Ô°h4 5œ ‹¢Èn¶e½¤R)BÔÒ¶±XÛ^¼xÁDWa"½-§ ‚ngzóè7!äúõë_|ñÅy[b¥g å­”ó•êD—À@M½HYYY‘$‰Î»ZÒhšæþþ¾¦iðRV.—c[¢èûÍ›7www;e5c~~Þ¾©Ð·íØË‹¼ž.=LεõÞ¶è'''Ὃû¶Xw8Û‘Øv¿öõ ê«­y–p,fwJE'kÓÒÖÚ¶^ì)%¯'öÔ¬°_t¾b °mh]̧éŸ! ˜¦yÎ{  ªÛ•xgå¨uýžÓXnܸ{µè{Û/|ONN~ôÑG<ÏÛ_ý²x´óé§Ÿ‚(é¼xÖM@zÝaL¸Ø¿.ô0èië³áµ%ÒNü¶õÂújT'Çm9¤½S’‚rðbOi'ÃìIètÑùŠsB’oDz¾Þ•_ÿðuöù@pg XìBµU$AžàÇÜO òê/ÁóåÔyˆ`濇µ7˜ ô`&Ыì¹ ë?¦ieË¡3Üë;õˆëœe=ZÔnDjg ¬ò®ËÏ-Ú=Ú àžMT«ç, æ$ j—3uPP‚»ˆ`‡uéjÖÝaº&P³÷lêÎ×?è9unƈçΠ<ðo6Á)Ô. `ê:…®fþÙp‚¼d`çÕlApš×®ðÊì&?€&yˆ‡© `FÐ$7 P³pü¨Þo^é0i(æ€Á³AŸÈ‹Ê‚œ#ÿO4ŽîtEXtAuthor©®ÌHtEXtCommentöÌ–¿ tEXtCopyright¬Ì:tEXtCreation Timeô6 tEXtDescription !# tEXtDisclaimer·À´ tEXtSoftware]pÿ:tEXtSourceõÿƒëtEXtTitle¨îÒ'tEXtWarningÀæ‡tIMEÓ2( czTXtRaw profile type iptcxœãò qV((ÊOËÌIåRc3.c #K“ „C Ãd#s ÓÜÜÈ,ÍÜÄ̈M @âæÆ`5  "M¸’©k±t%DiTXtXML:com.adobe.xmp 690 292 úw¿ëIEND®B`‚fotoxx-12.01.2/doc/freecode0000664000175000017500000000107111701011016014075 0ustar micomico A new capability was added to search for and report any image metadata (EXIF/IPTC/etc.). The report shows thumbnail images and metadata text. Processing new photos is 2x faster (up to 1000/minute). The main window can be more easily zoomed and panned during a dialog which is using the mouse. The mouse wheel can be used to zoom in/out. The mouse pointer tracks the zoom center to the middle of the window. The zoom ratio is configurable: 1-4 zooms for each 2x increase. Print color adjustments can be saved to a file for re-use. Three minor bugs were fixed. fotoxx-12.01.2/doc/changelog0000644000175000017500000005023211701011016014251 0ustar micomicoFotoxx change log ================= 2012.01.04 v.12.01.2 + Italian user guide was updated. + Swedish translation was updated. 2012.01.04 v.12.01.1 + Bugfix: zoom causes infinite loop after new installation. 2012.01.01 v.12.01 + New function Search Metadata: search and report image metadata (EXIF/IPTC/etc.), using a combined image and text display format. + Synchronize Files is 2x faster for an initial installation or after importing a large number of new photos (>1000/min. on a fast PC). + "my mouse" was removed from all edit and selection dialogs. The mouse belongs to the last widget clicked. The main window can be zoomed and scrolled during such dialogs by using CTRL + mouse click or drag. + Mouse wheel can do zoom-in and zoom-out. + Zooming an image re-centers it on the mouse position, and the mouse position follows the zoom center to the middle of the window. + Zoom ratio configurable: choose 1-4 zooms for each 2x increase in size. + DRGB (print color adjust) can save corrections to a file for re-use. + Some user settings in various menus were collected together in the new menu function Tools > User Settings. + Bugfix: Search Image was finding false matches for images with very large caption or comments. + Bugfix: cannot escape file open dialog if open previous or open recent is attempted when there are no previous files (initial installation). + Bugfix: interactive GUI translation function failed to initialize. 2011.12.03 v.11.12.2 + Italian translation was updated. + Locale of lc_RC will prefer a .po file named "lc_RC", fallback to "lc". 2011.12.02 v.11.12.1 + Bugfix: crash at startup - top image directory not correctly initialized from previous fotoxx installation. 2011.12.01 v.11.12 + New function Auto-Trim: automatically trim unused edge areas left over from panorama, HDR, HDF, stack, warp and unbend functions. + New function: Find bright or dark "stuck" pixels (camera sensor defect) (1x1/2x2/3x3 blocks) and fix them by interpolating neighboring pixels. Pixel locations can be saved and applied later to other images. + Select Area was extended to both select and unselect by matching colors, and the pixel search range was made adjustable 1-20x mouse radius. + Batch Resize/Export function now supports output of JPEG, PNG, TIFF. This can be used to select and convert files to a different format. + Convert RAW Files now supports output of JPEG, PNG, TIFF-8, TIFF-16. + Warp Area algorithm was made a bit more intuitive and controllable. + GUI language translation procedure was simplified. + Bugfix: restored some lost translations of dialog buttons. + Bugfix: Trim dialog mouse ownership was sometimes misleading. + Bugfix: WarpArea did not reset itself if selected area was changed. + Bugfix: crash if parallel instances of fotoxx are simultaneously editing images and using undo/redo. 2011.11.05 v.11.11.1 Fix problems in v.11.11 released a few days ago: + Bugfix: crash in vertical panorama. + Bugfix: crash in Open Recent File if trashed image is attempted. + Restore lost BUSY indicator for functions needing significant time. 2011.11.01 v.11.11 + Creating and editing collections was made easier and more intuitive. + Synchronize Files always works incrementally and runs automatically at startup. Image navigation/viewing is immediately possible but editing is blocked until the synchronize is finished (normally a few seconds). + Straighten Image: fix less than optimal results for images needing a large correction. Menu was renamed to Keystone Correction. + New menu: Help > User Guide Changes: summary of changes in the user guide for recent releases (minimize effort to keep up with changes). + New menu: Help > Edit Functions Summary: a one-page "quick reference" summary of all the image editing functions. + New topic added to the user guide: How to organize a large image collection to minimize effort and to optimize image searching. + The status bar now shows if a dialog is waiting for input (and possibly hidden under another window). + New keyboard shortcut: N = Rename Image File. + Transform and Retouch menus were rearranged to follow typical workflow. + Rotate and warp dialogs have convenience buttons to grid line setup. + Grid setup: the x and y grids can be moved around over the image. + New utility: update collections if the top image directory is moved. + The package build method was updated to improve Debian packaging and include dependencies on non-library programs. The RPM packages do not include this because the package names are not compatible. 2011.10.01 v.11.10 + New function: classic gamma curve edit for brightness and individual RGB colors. Applicable to the whole image or a selected object/area. + Printing was revised to work better with recent changes in HPLIP that made printing on small paper sizes more difficult. The paper size must be specified in the Printer Properties dialog (printer admin function) and not in the application program - otherwise the print fails with a "paper mismatch" error. This changed between Ubuntu 10.10 and 11.04. + New function: convert "tetragon" image into a rectangle. Useful for gallery paintings photographed from the side to avoid reflections, buildings photographed at an angle, etc. + At startup, check for new files, advise if synchronization is needed. + New option: warn if overwriting original (non-versioned) image file. + Slide Show: stop strange behavior when multiple monitors are used. + Slide Show: option to show only the most recent version of each image. + Slide Show: use spacebar to pause and resume slide show. + Pixel Edit: transparency adjustment steps were made finer. + Code cleanup for new compiler warnings from GCC 4.6 (Ubuntu 11.10). 2011.09.26 v.11.09.1 + Bufgix: crash in Slide Show if the last transition type (jaws) is not included in the user preferences. 2011.09.01 v.11.09 + Print Image File now has margin inputs and tiny margins also work. + The Portuguese translation was brought up to date. + Minor source code changes were made for better BSD compatibility. + Show RGB: labels on monitored image points were made optional. + Gallery: larger font for file names is used when thumbnails are large. + Edit Captions and Edit User Comments were combined into one function. + File Open will discard a preceding search result or named collection, and the user is notified and may proceed or cancel. + File > Open (menu and toolbar) can now be used to open a single RAW file (as tiff-16). A batch conversion function is also available. + CPU load monitor on status bar now includes spawned subprocesses. + Smart Erase: improved algorithm gives better results in some cases. + Panorama: image overlap requirement was relaxed. + Bugfix: Flatten: fix uneven conversion of pixels with max. brightness. + Bugfix: crash if Tools > Add Menu is started and then canceled. + Bugfix: minor memory leak. 2011.08.01 v.11.08 + An Italian user guide has been added. + New function DRGB: change brightness and color balance using OD units. + Revise_RGB: added delta mode (show +/- changes from original image). + Show RGB: added EV and OD units, delta mode, and pixel labels on image. + Slide Show: two image transitions were added, "radar" and "jaws". + Slide Show: preferred transition modes can be selected and remembered. + Delete Area was renamed to Unselect Area (to reduce ambiguity). + F1 help topic is now determined by the last dialog opened OR USED. + Bugfix: disable a select-area if Undo/Redo changes the image size. + Bugfix: Create Blank Image got leftover EXIF data from a prior image. + Bugfix: buffer overflow crash in Russian locale. Several other risky places from long translation strings were identified and fixed. + Bug workaround: crash from GCC 4.5 optimization removing necessary code. Do-nothing variable references were added to prevent this. + Annoyance fix: rapid repetition of prev/next buttons or arrow keys was sometimes causing a "function still active" popup message. + Current bug: On Ubuntu 11.04 Fotoxx refuses to print with small paper formats (A5, A6). Ubuntu 10.10 works OK. I cannot fix this. 2011.07.01 v.11.07 + The main retouch functions can now be used in parallel (i.e. multiple edit dialogs can be active at the same time). + The last position of the main window and most dialog windows is saved and restored within a session and across sessions. + New function Match Colors: take a spot color sample from two images. The colors of the 2nd image are changed to match the first. + New function Revise RGB: select up to 9 control pixels on an image and adjust their RGB values. All image pixels are adjusted to match, using weights based on distances from the control pixels. Use this function to make complex color adjustments that vary across the image. + Brightness Ramp was revised to handle RGB colors. This is an alternative method to remove a color caste that varies across an image or image area. + Tools > Show RGB: EV and OD units are output in addition to RGB values. Up to five points are shown, updated live as the image is edited. + The Brightness/Color curves now have a range of +/-2 EV (F-stops) and the step-adjust buttons ([+++] etc.) are calibrated in 0.1 EV steps. Steps 1/3 this size can also be used. Use this function in conjunction with Show RGB to make calibrated color adjustments. + Numeric feedback was added to the sliders in retouch edit functions. + Missing gallery thumbnails are generated 2-3x faster (on multi-core processors) using multiple threads working ahead of need (usually). + Clone (new window) now has two variants: share desktop 50/50 or open a new window of the same size, slightly offset for visibility. + Open File now has two variants: use the same window or open a new window in a parallel instance of Fotoxx. + New toolbar button: save file as a new version (immediate, no dialog). The current image and its edit history remain unchanged. + Save-As menu and toolbar: new checkbox option to switch the current file to the saved file. The edit trail (undo/redo) is also retained. + New command line parameters: -prev open the last file viewed in the previous session. -recent start with a gallery of recent files (most recent at top). (-prev used to be default but this is no longer the case). + If the [undo] or [redo] button is pressed with the shift-key, they become "undo all" and "redo all". This makes it easier to compare an image having multiple edits with the original image. + Select Area [Unfinish] button: put a finished area back in edit mode. + Pixel Edit was moved from the Art menu to the Retouch menu. + Hourglass cursor was replaced with a BUSY sign at bottom of the window. + Toolbar help is a topic help like F1. Menu help opens the user guide. + Bugfix: warp functions were infrequently putting artifacts in the image. + Bugfix: Edit Collection could crash if adds and deletes were mixed. + Bugfix: Select Area Edge Calculation: if killed by user, the area was left in a half finished condition. 2011.06.13 v.11.06.2 Bugfix: Ubuntu 11.04 32-bit: libtiff.so was moved to a really different location: /usr/lib/i386-linux-gnu/libtiff.so. This caused a misleading diagnostic when building from source, so the check and diagnostic was simply eliminated. The packages are not affected. 2011.06.09 v.11.06.1 Bugfix: A hole was closed that could cause a crash if a select area is deleted while an edit function is open and active. 2011.06.01 v.11.06 + Smart Erase and Remove Dust were made slightly more effective. + Brightness/Color retouching and Tone Mapping were made 25-40% faster. + Retouching brightness/color by "painting" with the mouse (dodge and burn) was made much faster (instant response on a fast computer). + If at startup the previous image file is no longer present then a gallery of the 100 most recent files viewed is shown. + New function: Tools > Toolbar Style: set to text, icons, or both. + New function: Tools > Edit Translation: edit translations interactively as Fotoxx is being used, and the changes are immediately effective. + Several other small usability improvements were made. + Minor bugfix: paste area edge blending lost 1 pixel around the edge. 2011.05.15 v.11.05.2 + Fix an error in the .desktop file causing the desktop menu not to work (the command "fotoxx" in a terminal or launcher still works OK). 2011.05.02 v.11.05.1 + The new version of alien replaces text files /usr/share/doc/appname/* with compressed (.gz) versions, making the menus Help > README etc. to fail. Program now accepts either normal or compressed files. + Context help (F1) for Remove Dust was not working. 2011.05.01 v.11.05 + New function Erase Dust: erase dust spots on images from scanned slides. + Named image collections were made easier to create and revise. Images can be added, removed and rearranged using a thumbnail gallery. + The trim (crop) function better handles zoom and scroll. The desired image size can be input directly, in addition to the mouse drag method. + Smart Erase was made faster (noticeable on slow processors). + Create Blank Image: simplify UI and create new file automatically. + Minor UI improvement: inform user if the current search results or named collection must be abandoned to open a non-member image file. + Select Area: edge distance calculation for hairy edges is >2x faster. + Image tags with embedded blanks are allowed. + Bugfix: Smart Erase was sometimes missing a few pixels. + The supplied .deb and .rpm packages are now built using Ubuntu 10.04 instead of Ubuntu 8.10. These packages (using newer libraries) may not be installable on less current Linux releases. 2011.04.01 v.11.04 + Vertical panorama was implemented (previously possible but clumsy). + Slide Show can optionally play a music file or play list. + A pre-planned slide show can be started from the command line. + Initialization for new installs was simplified and the user warning was strengthened (need fewer frustrated users who don't read user guides). + Smart Erase was made easier by combining the select and erase functions. + Select ellipse: keep the ellipse centered at the drag origin. + Select by color: the search range for matching pixels was limited to 3x the mouse radius. This works better, allowing edges with varying color to be more easily followed and selected. The remaining interior areas can be selected with an extra click in the finish dialog. + Paste Area was made easier to use by automating the finish step. + Unbend was extended to fix more types of perspective problems. + Toolbar buttons were rearranged to reduce the risk of accidentally overwriting the original image. + The total image file limit of 100,000 was removed. The practical limit depends on how much main memory is available for the image search index. 1 GB is enough for >1 million files, and only needed when searching. + Bugfix: possible crash in slide show with "ellipse" transitions. + Bugfix: HDF: first manual tweak caused an annoying random jump. + Bugfix: crash if initial warning message ignored and then open a file. 2011.03.13 v.11.03.1 + Bugfix: possible crash if area select along bottom edge of image. + Bugfix: possible crash following a revision of lens parameters. + Bugfix: select area: edge of image can also be edge of area. 2011.03.01 v.11.03 + Composite functions Pano, HDR, HDF and Stack run 2-3 times faster. + Printing: intermediate file was changed from .jpeg to .tiff to correct slight blurring of some color edges in high-resolution images. + New art function: create color outline drawings. + New function: adjust monitor gamma with live feedback. + Plugins: add external image editors to Fotoxx menu: Fotoxx edits may precede and follow, [undo] / [redo] buttons work, etc. + Smart Erase: can use a tighter area around the object to be erased. + Panorama: the math was simplified to a pure cylindrical projection. + Select Area: added select for rectangular and elliptical areas. + Notify user of delay for thumbnail creation when new images are found. + New slide show transition: ellipse expanding from the center. + Select Area: brighter outlines for freehand draw and follow edge. + Unbend: panorama curve is more accurately flattened. + bugfix: crash reading 4-channel tiff file in strip format. + bugfix: panorama crash if image overlap reaches zero during alignment. + bugfix: crash if trying to save to a .gif file (converts to .jpg). + bugfix: fixed small memory leak in metadata viewer. 2011.02.01 v.11.02 + Retouch functions can be incrementally "painted" with the mouse, with variable radius and strength. + Area cut and paste: edge effects are more effectively suppressed and the pasted area/object can be rotated as well as resized. + Curve edit (used in image retouch functions): curve data can be saved to a file or loaded from a file as part of the curve edit dialog. + New function: Smart Erase: erase power lines and other small defects by replacing them with pixels from the neighborhood. + New functions: Make Image Collection and Open Image Collection. Images may be assigned to named collections. A collection can be recalled and used for a slide-show, export, etc. + New function: Combine photos of the same subject taken at different moments, remove tourists, cars, etc. that come and go. + Panorama pre-align was made a little easier (check the user guide). + Tag Edit and Tag Management were separated to simplify operation. + New 1-time function: Tools > Fix Tag Delimiters: make tags (keywords) compatible with Photoshop. Other photo managers may not be compatible. This is optional and can be done at any time without affecting Fotoxx. + Art > Dots: dot rows are offset by 1/2 dot pitch, which looks better. + Expand Brightness Range: use sliders and show brightness histogram. + 1-time function to rebuild thumbnails now has a fast incremental mode. + Obsolete functions removed: convert old tag and parameter formats. (if you have startup problems, delete /home//.fotoxx). + Bugfix: Edit Info function could not be canceled before using it. + Bugfix: Edit Info (metadata) limit raised from 100 to 1000 characters. + Bugfix: Stop meaningless EXIF diagnostic when a blank image is created. + Bugfix: Annotate crash if font set to tiny and then increased. + tags_index file was renamed to search_index 2011.01.07 v.11.01.2 + Bugfix: select whole image was not working. What went wrong between testing and release is a mystery, but now it is fixed. 2011.01.06 v.11.01.1 + Revise startup warnings about thumbnails and tag index file to make them less intrusive and perhaps easier to understand. + French translation was updated. 2011.01.01 v.11.01 + Select Area: Select the whole image and use overall brightness or a single RGB color brightness to control the application of a retouch function. This allows tone mapping, noise reduction, etc. to apply in darker image areas but not brighter areas (or the inverse). + New art function: make a dot matrix image (à la Roy Lichtenstein). + Slide Show was given a few dubiously useful but cute image transition modes (fade-out/fade-in and various kinetic image replacement methods). + Open Recent File: the 100 most recent image files are presented in a gallery window to make it easier to go back to a desired image. + If grid lines are active when an image is printed, the grid lines will also appear on the printed image. + The status bar shows if a select-area is active or a function is busy. + A new blank image can be created and used as a basis for mashups using cutouts from other images plus annotation text. + After a first-time install, the user is now advised to run the 1-time indexing program so that image searches will function correctly. + Batch add and delete tags have a popup window to monitor progress. + Search Images output (gallery window) is sorted to follow the physical organization of the underlying files. Groupings and sequences implied by the file organization (directories and file names) are preserved in the generated window of thumbnail images. This was always a claimed fotoxx capability, but was not always working as advertised. + Bugfix: image was sometimes not being resized to fit window after a size change (trim, resize), possibly giving a false impression. + Bugfix: inverting a select area did not work with some edit functions. fotoxx-12.01.2/doc/userguide-en.html0000644000175000017500000105347111701011016015672 0ustar micomico fotoxx user guide Fotoxx User Guide  v.12.01

License and Warranty

Fotoxx is licensed under the GNU General Public License v3 (Free Software Foundation).
Fotoxx is not warranted for any purpose, but if you find a bug, I will try to fix it.

Origin and Contact
Fotoxx originates from the author's web site 
http://kornelix.squarespace.com/fotoxx. Other web sites may offer it for download. Modifications may have been made. If you have questions, suggestions, or a bug to report, you may contact me.

User Guide changes for this version can be found here.



Getting Started

When you see the word
directory, substitute folder if this is your way of thinking. The terms file and image and image file mean a single computer file of type  .jpg  .png  .tif  etc. containing a single image (photograph).

Installation
To install Fotoxx, try the appropriate package file first: packages. It may install OK with one click. If not, you must install from source code. Instructions are here: downloads. Fotoxx should show up in the system menu after installation (or maybe after a new login). If not, use the command "fotoxx" in a terminal window or launcher.

Initialization
Fotoxx needs to know where all your image files are located (directory and file names) and their imbedded metadata (if any): tags, captions, comments, ratings and dates. These must be indexed for fast searching. Fotoxx also needs to create thumbnail images so that the gallery windows (thumbnail pages) will work fast. When Fotoxx starts, it checks for a top image directory and index file. These will be missing the first time Fotoxx is started, and a popup dialog (Synchronize Files) will ask you to supply a top image directory so that your image files can be found and indexed, and thumbnail files created. The top image directory is simply a directory containing all your image files (or subdirectories with image files). This is typically named "/home/<user>/Pictures" or similar. Use the [browse] button to locate this directory and press [proceed]. A popup window will list the image files as they are indexed. If you have many thousands of images, this will need some time to finish (a fast computer will do over 1000 images per minute). Fotoxx does not change or copy the image files - it only reads them to get data for the search index and to make thumbnails. After this function has finished, the gallery windows will be fast and the Search Images function will be very fast.

If you start Fotoxx after new image files have been added to your collection, the synchronize function starts automatically. A popup window will list the new image files found. You can use Fotoxx normally to navigate and view images, but editing images will be blocked until the synchronize function is finished. This normally needs a few seconds unless there are hundreds of new images to process. The popup window is left open for your inspection. You can close it at any time, but synchronize will always continue to completion. For more details, see  the topic
Synchronize Files.

Test Run
After Fotoxx finishes initialization, use the [open] button on the toolbar to select an image file to view in the main window. Choose the menu Retouch > Brightness/Color, and in the dialog use the [+++] button to brighten the image. Use the [cancel] button to leave the dialog without changing the image file on disk. Use the [gallery] toolbar button to see all the images in the current directory as thumbnails in a new window. Use the navigation buttons on the gallery window to navigate within the directory. Use the [parent] button to leave this directory and choose another. Click on a thumbnail image to view the image in the main window.


Essential Information for those who hate big user manuals:

  o  Menu functions and dialogs have live help activated by keyboard F1.
  o  Mouse left click: zoom image bigger and move center to mouse position. 
  o  Mouse drag across a zoomed image: scroll and pan the image.
  o  Mouse right click: un-zoom image to fit in the window.
  o  Gallery button: thumbnail browser: view all images in current directory.
  o  Click image in thumbnail browser: show image in main window.
  o  The status bar at the bottom of the main window contains status information.

Fotoxx Startup: To start Fotoxx, use the command "fotoxx" in a launcher or terminal window. Command line options are listed in the Technical Notes section.

This User Guide is available in the menu Help > User Guide. The F1 key will bring up a help topic for the current menu or dialog. This appears in your chosen web browser (and can get hidden under the Fotoxx window).

Mouse Actions on Main Window
To zoom the image in the main window, left-click a position on the image. The image will grow with each click and the clicked position will move toward the center. A right-click will restore the image to fit within the window. To scroll a zoomed image, left-drag the mouse across the image. This works like invisible scroll bars: the image moves in the opposite direction of the mouse. Diagonal scrolls work. The mouse wheel may also be used to zoom the image in or out. The middle mouse button (wheel) will make a zoomed image re-center at the mouse position.

Mouse Ownership
Some dialogs use the mouse to reference or alter the image in the main window. There may be more than one such dialog active at the same time. The mouse is also used to zoom and scroll the image, and you may need to do this while using a dialog. Therefore it is important to understand who owns the mouse (dialog or main window) and how to change the ownership:
1. The mouse is owned by the dialog that was last clicked or modified. Mouse cllicks and drags on the main window are inputs to this dialog and DO NOT zoom or scroll the image.
2. To zoom or scroll the image while a mouse-using dialog is active, press the CTRL key before clicking or dragging the mouse. The mouse acts on the main window and the dialog is not affected. The mouse wheel can always be used for zooming the image - the CRTL key is not needed.


Dialog buttons
mostly work as follows:
   Proceed - close dialog, proceed with lengthy task.
   Apply - apply settings from dialog, leave dialog active.
   Done - keep dialog changes and close dialog.
   Cancel - discard changes and close dialog.

General Editing Procedure
The image in the main window (the current image) can be operated on with the edit functions (in the menus Transform, Retouch, Art, Combine). These functions modify the current image in memory. You can use these functions in any order, and the changes are accumulated for the current image and shown in the main window. The Toolbar [undo] and [redo] buttons can be used to review the before/after results for the current active edit function. After the function is closed (dialog [done] or [cancel]), these buttons can be used to review all the edits done to the current image (up to 99). When finished editing an image, use [Save] to replace the original image file with the modified one. Use [Save+V] to save the modified image with the original file name appended with a version number (both are kept). Use [Save+F] to save the modified image to a new file.

Many image edit dialogs have sliders, spin buttons, or editable curves that update the image in the main window. The reaction time depends on the size of the image, the complexity of the function and the speed of your computer. This is typically <1 second for a fast computer.

Curve Editing:

Several image edit functions use editable curves. You can manipulate the curves to change some property of the image (e.g. color saturation) depending on some other property (e.g. brightness). To illustrate, you could increase color saturation in the darker areas of an image without changing it in brighter areas. Generally, the X-axis of the curve represents the input property (brightness in the prior example) and the Y-axis the output property (color saturation). The curves can be moved (pulled) with the mouse. "Up" increases the effect of the current edit function and "down" decreases the effect. An anchor point (black dot) is added to the curve wherever it is pulled, and this becomes a constraint for subsequent pulls: the curve will continue to go through this point as other parts of the curve are pulled. Anchor points can also be dragged. Delete by right-clicking them. The curve edit windows have buttons [open] and [save] which can be used to load a curve previously saved to a file. This may reduce the time to edit the curves for a series of images receiving the same treatment.

Simple Workflow
Most of the time you can just edit the JPEG file that comes out of the camera. Use the following more complex procedure only if you see "color bands" after editing the image.

Complex Workflow
Convert the camera RAW file to TIFF, which will produce an image with 16 bits/color. The high color depth reduces the risk of visible "color bands" from functions that can radically shift the brightness distribution (especially Flatten and Tone Mapping). When finished, convert the final TIFF to JPEG (quality level 70+) to reduce the file size (from typically 50 MB to 2 MB). You will almost never be able to see any difference between the final TIFF and JPEG images. To preserve the possibility of re-editing the image later, keep the RAW file, which is much smaller than the TIFF file.

Suggestions for how to organize a large image collection can be found here.


Selecting Images from an Image Gallery Window

This procedure is used in several functions which use or modify multiple image files (batch add or delete tags, batch convert images, others). It is explained once here, and this paragraph is linked from each of the functions using this procedure.

When image files are selected, a dialog box appears with an empty list for the selected image files. Behind it is a gallery window which permits the selection of multiple images. To select an image, click its thumbnail and the image file will be added to the list. You can navigate the gallery window to other directories and choose images in any order. The list of image files can also be manipulated to change the sequence or remove images added by mistake. Click on a file in the list to show its thumbnail in the dialog and also set the current list position. The next image file added will be inserted at this position. If the [delete] button is pressed, the current list position will be deleted, and if the [insert] button is pressed, the last deleted image file will be inserted at the current position. To move an image to a new position in the list: click the image file (its thumbnail will be shown), press [delete], click another image file and press [insert]. The deleted image will be inserted before the selected image. The list can also be edited directly: you can use cut and paste to get the sequence you wish, but be careful to always cut and paste entire lines (files) only. The [add_all] button will add all the image files in the current image gallery. After using Search Images to establish a set of images, the gallery window will contain this set. You can select individual images from the gallery, or use [add all] and then delete unwanted images.


Fotoxx Menus and Toolbar Buttons

File Menu File Management
Image Gallery
Show thumbnail images - image files in the current directory (more).
Clone 50/50
Clone Fotoxx and share the desktop 50/50 with the old instance (more).
Clone Overlay
Clone Fotoxx and open a new window slightly offset from the old one (more).
Open Image File
File open dialog - open an image file to view or edit (more).
Open in New Window
File open dialog - open new file in a new window (more).
Open Previous File
Go back to the last image file opened (more).
Open Recent File
Choose from a list of the most recent image files opened (more).
Save to Same File
Save modified image to the same file (overwrite) (more).
Save to New Version
Save modified image to the same file with a new version number appended (more).
Save to New File
Save modified image to a new file (more).
Create Blank Image
Create a new blank image file (more).
Trash Image File
Move an image file into the trash bin (more).
Rename Image File
Rename image files, optionally add sequence numbers (more).
Batch Rename Files
Rename many image files using a base name and sequence number (more).
Print Image File Select printer / paper format / orientation and print image (more).
Quit Fotoxx
Exit from Fotoxx.

Tools Menu
Utilities and setup functions.
Manage Collections
Make image collections, arrange the sequence, etc. (more).
Move Collections
Update collections when image top directory is changed (more).
Batch Convert
Convert / resize / export images (for upload to the web, e-mail, etc.) (more).
Convert RAW Files Convert RAW image files to tiff (more).
Slide Show Show a series of images full screen (no menu or toolbar) (more).
Synchronize Files Rebuild the image search index and refresh thumbnails (more).
Show RGB Show RGB values at position of mouse click (more).
Grid Lines Add or remove grid lines for image alignment (warp, rotate) (more).
Burn Images to CD/DVD Select images and write them on a CD or DVD (more).
E-mail Images Select images, downsize, send to your E-mail program (more).
Check Monitor
Display a color palette for tuning your monitor (more).
Monitor Gamma
Adjust monitor gamma for better image editing (more).
Brightness Distribution
Show brightness distribution graph of current image (more).
Change Language
Change the GUI language (more).
Edit Translations
Revise a translation interactively (more).
Menu and Launcher
Add a system menu entry and desktop launcher (more).
User Settings
A collection of user preferences and settings (more).
Memory Usage
Dump a memory usage table to the log file (more).

Info Menu
View and edit image data and attributes
Edit Caption/Comments
Add or change descriptive text for an image (more).
Tags Overview
Explanation of tags and how they are used (more).
Edit Tags
Add or change image tags (keywords), stars rating, or date (more).
Manage Tags
Create tags and tag categories (more).
Batch Add Tags
Add many tags to many images at once (more).
Batch Delete Tag
Delete or replace one tag for many images at once (more).
View Info (short)
View most important image data (more).
View Info (long)
View all available image data (more).
Edit Info
Add or change the data for a specific key (more).
Delete Info
Delete a specific key or all image data (more).
Search Images Find images with desired tags / stars / dates / comments / captions (more).
Search Metadata
Search and report any desired metadata (EXIF/IPTC/etc.) (more).

Select Menu
Selected areas within images where edits are confined
Overview
Explanation of area selection and editing (more).
Select
Select an area for subsequent editing (more).
Show / Hide
Show or hide an area outline (more).
Enable / Disable
Enable or disable an area for subsequent editing (more).
Invert
Invert an area (more).
Unselect
Unselect an area (more).
Copy / Paste
Copy an area to memory and paste it somewhere else (more).
Open / Save
Save an area to a file and load it later to use in other images (more).
Select Whole Image
Select the whole image as a mask for retouch edit functions (more).
Select and Edit
Mouse over an image area to apply an edit function incrementally (more).

Transform Menu Functions that change image size, shape, content
Rotate Image Rotate an image (level an image or turn in 90° steps) (more).
Trim Image Cut out a rectangular portion of an image (more).
Auto-Trim Image
Auto-select trim margins to remove after rotate, unbend, or warp functions (more).
Resize Image
Scale an image up or down (more).
Annotate Image
Write text annotations on an image (more).
Flip Image
Mirror an image horizontally or vertically (more).
Make Negative Make a black-white or color negative, or a positive from a negative (more).
Unbend Image Fix perspective problems (more).
Keystone Correction
Straighten a photo made from an offset angle (more).
Warp Image (area)
Distort image within an area by pulling with the mouse (more).
Warp Image (curved)
Distort entire image by pulling with the mouse (more).
Warp Image (linear)
Distort entire image by pulling with the mouse (more).
Warp Image (affine)
Distort entire image by pulling with the mouse (more).

Retouch Menu
Functions that change image qualities
Brightness / Color Edit brightness, contrast, color saturation, color balance (more).
Gamma Curve Edit brightness and color using the classic gamma curve (more).
Expand Brightness Clip low / high brightness levels and expand the rest (more).
Flatten Brightness Flatten the brightness distribution to enhance detail (more).
Brightness Ramp Horizontal / Vertical variation of brightness (more).
Tone Mapping Increase local contrast to to enhance details (more).
White Balance
Remove false color from an image (more).
Match Colors Match the colors in one image to those in another image (more).
DRGB Change brightness or RGB colors using OD units (more).
Revise RGB Make complex color corrections that vary over the image (more).
Red Eyes Remove red eyes from flash photos (more).
Blur Image
Blur an image (e.g. smoothen skin) (more).
Sharpen Image
Sharpen a blurred image (more).
Reduce Noise
Reduce noise (speckles) in low-light images (more).
Smart Erase
Remove power lines and other spoilers by substituting neighboring pixels (more).
Remove Dust
Remove dust spots on images made from scanned slides (more).
Fix Stuck Pixels
Fix stuck pixels (always bright or dark) from defective camera sensor (more).
Edit Pixels Edit pixels and paint lines or areas using the mouse (more).

Art Menu Functions that make artful transformations
Color Depth
Reduce color depth (posterize) (more).
Drawing
Transform a photo into a simulated pencil or chalk drawing (more).
Outlines
Transform a photo into a colorized line drawing (more).
Embossing
Transform a photo into a simulated embossing (more).
Tiles
Transform a photo into tiles (pixelate image) (more).
Dots
Transform a photo into an array of dots (more).
Painting
Transform a photo into a simulated painting (more).

Combine Menu Functions that combine multiple images
High Dynamic Range
Make a high dynamic range image from multiple images (more).
High Depth of Field
Make a high depth of field image from multiple images (more).
Stack / Paint
Combine multiple images to remove tourists and cars (more).
Stack / Noise
Combine multiple images to reduce noise (more).
Panorama / Vertical Panorama Join 2-4 overlapping images to make an ultra-wide image (more).
 
Plugins Menu
Other image edit programs can be used as edit functions in foloxx (more).
 
Help Menu User guide, README, change log  (more).
  
Toolbar Buttons

Gallery
Show thumbnails of image flles in the current directory (more).
Open
File open dialog - open an image file to view or edit (more).
Prev / Next
Go to previous or next image in the current directory or search set.
Zoom+ Magnify the image. A left mouse click also magnifies.
Zoom- Reduce the image to fit window. A right mouse click also reduces.
Undo / Redo Undo one edit / Redo one edit - up to 99 edits of the current image.
Shift-key + Redo / Redo Changes the buttons to [undo all] and [redo all].
Save / Save+V / Save+F
Save image to the same file, to a new version, or to a new file (more).
Trash Move an image file into the trash bin (more).
Quit
Exit from Fotoxx.
Help
Show online user guide (more).
 
Keyboard Shortcuts

Main Window
shows current image file to view oe edit
left / right arrow keys
previous / next image
plus(+) / minus(-)  keys
zoom image bigger / smaller
Z  key
toggle: zoom image to 100% / fit image in window
R / L  keys
rotate image 90° right / left (change is permanent)
G  key
toggle grid lines on or off
T  key
shortcut for menu Transform > Trim
B  key
shortcut for menu Retouch > Brightness/Color
A key
change toolbar undo/redo buttons to undo/redo ALL edits
N key
shortcut for menu File > Rename Image File
Delete key
move image to trash bin
Escape key
Exit slide show mode
Spacebar
pause and resume slide show timer
Control + s
Save to original file (no questions asked)
Control + S
Save+F: dialog to choose a target file
Control + v or V
Save+V: save to new version (no questions asked)
Control + q or Q
Quit Fotoxx
Control + z or Z undo one edit level
Control + Shift + z or Z redo one edit level
Image Gallery window
thumbnail images of current directory
Home / End keys
move to first / last page of image gallery
Page Up / Down keys
move to previous / next page of image gallery
up / down arrow keys
move up / down by one row of image gallery
left / right arrow keys
move to previous / next page of image gallery
plus(+) / minus(-)  keys
bigger / smaller thumbnail size
Escape key
close image gallery window
Dialogs for User Input
 
F1 function key
display user guide section for current function
Escape key
cancel dialog

Mouse Functions

left click
Zoom-in: magnify image, center at click position.
right click
Zoom-out: restore image to window size.
drag on image
Scroll a zoomed image in the opposite direction, like a scroll bar.


Some supplimentary
technical notes can be found here.


File Menu

Navigation


Use the Image Gallery menu or the [gallery] toolbar button to open an image gallery window (thumbnails) showing image files in the current directory, the latest search results, or the current named collection. Use this window to scroll around the directory and select image files by clicking thumbnails. The buttons at the top allow scrolling forward or back by rows or pages. Use the [parent] and [open] buttons to jump to other locations. Use the [bigger] and [smaller] buttons to change the thumbnail size and the number of visible thumbnails. Pressing the [gallery] button in the Fotoxx main window will bring the gallery window forward with the current image file in the top row. Clicking on a thumbnail will bring the Fotoxx main window forward with the selected image. The windows seem to replace each-other, but one is only on top of the other, and they can be dragged apart if you want to view both.

There are three types of image gallery windows: (1) the image files in a single directory (plus subfolders at the top of the list), (2) the results of using the image search function to find images that may be in many different directories, (3) the images in a named collection. The title bar of the window will show the directory path, "Search Results", or the collection file name.


Clone Fotoxx

Start a new instance of Fotoxx in a new window. There are two variations: split the screen 50/50 between the two windows, or open the new window over the old window, slightly offset for visibility. Clone is useful to compare images or to work with more than one image at a time. Both windows can be used to edit images. The new window will initially have an unmodified version of the current image file. The original window keeps whatever edits have been done. If the same file is edited in both windows, the result will depend on whichever window saved it last. Use the toolbar button [Save+F] if you want to keep both image files.


Open Image File

This function starts a standard file open dialog, allowing you to select an image file or navigate to another directory and select an image file. The selected file is opened in the Fotoxx main window where you can view or edit the image file using the menus and toolbar buttons. The main window title bar always shows the file name and directory of the current image file. Drag and drop can also be used to open a file: drag an image file from Nautilus (or other source) to the Fotoxx window or desktop launcher, and Fotoxx will open the file. If text is dragged from gedit (or other program with drag sourcing), Fotoxx will assume the text is a filespec and try to open it. Thus you can make a list of filespecs in a text file and use this list with Fotoxx. Effectively, you can use Nautilus or text files to navigate a collection of images as an alternative to the Fotoxx navigation system. Add Fotoxx to the "open with" list for jpeg, tiff, etc. in Nautilus or other file browser. If the current image gallery list is from an image search function or a named collection, and you open a new file with Open Image File, the gallery will be replaced with image files from the same directory as the opened file. A message informs you and gives the option to proceed or cancel.

Camera RAW files can also be opened. This may need a few seconds depending on file size and processor speed. The RAW file is converted to tiff-16 and this file is opened. It remains on the disk unless you delete it or move it to Trash. RAW files are not included in gallery lists because the processing time is too much. If you want them in the galleries, I suggest the following: save the converted tiff file in a smaller size and format so that less disk space is required. A 1/4 size jpeg file will use less than 1% of a full-size tiff. Of course you can always get the full size image back from the RAW file.

Open in New Window
This is the same function, but the new file is opened in a new instance of Fotoxx. The current file remains in the old instance. This function is a combination of open file and clone.


Open Previous File
Go back to the previously opened image file, also if this is in a different directory. This differs from the toolbar button [Prev] which goes to the previous image file in the same directory as the current image file, or the previous image in the last search results.


Open Recent File
The 99 previously opened image files are presented in a list, from which you can select a file to open.


Save Image File

Menu File >
Save to Same File  or toolbar button [Save]
Save the current image file back to itself. If the file is a JPEG file, the default quality (90) is used. If this is an original file (not a versioned file), you will be warned that you are overwriting the original file. You can override the warning and continue. You can also elect to permanently supress this warning if wanted. If you have disabled the warning and wish to reinstate it, you must edit the file /home/<user>/.fotoxx/parameters  and change the value of "warn overwrite" from "0" to "1".

Menu File > Save to New Version  or toolbar button [Save+V]
Save the current image file with a new version number. File names with version numbers are formatted "filename.vNN.ext" where NN is a version number 01 to 99.  The 4 characters .vNN are inserted between the file name and extension. If the file name has no versions, version .v01 will be created. If file versions are already present on disk, then the next higher version number is used. There is no dialog or confirmation. If the file is a JPEG file, the default quality (90) is used.

Menu File >
Save to New File  or toolbar button [Save+F]

A dialog opens to save the current image file to a selected file, which can be the original file, another existing file, or a new file. An edited image file can be saved in three formats, JPEG, PNG, and TIFF. JPEG is normally the best option, since these are compressed to reduce space. You can choose a JPEG quality value in the range 1-100. Lower values give smaller files and less image quality. Values above 70 are generally hard to distinguish from 100 (highest quality, largest file size). PNG files are compressed without any loss of quality and are usually larger than JPEG files of the highest quality. TIFF files are uncompressed and larger than JPEG or PNG. TIFF files may be saved with 8 or 16 bits per color. The 16-bit TIFF format only makes sense for files converted from a RAW format supporting more than 8 bits per color (camera RAW files are typically 12 bits per color with noise in the lowest 1-2 bits). It is rare that the difference between 8 and 16 bits per color can be seen with the eye. However, an image with higher bits has more latitude when the brightness is altered with a program like Fotoxx. If "make current" is checked, the newly saved file will become the current file. In either case, the edit history is retained (i.e. undo and redo still work).

File sizes for a 10 megapixel image are roughly as follows (depending on amount of detail):
 tiff-16
 tiff-8
 png
 jpeg-100
 jpeg-90
 jpeg-80
 jpeg-70
 58 MB
 19 MB
 14 MB
 7 MB
 2 MB
 1 MB
 0.6 MB

There is a technical note about JPEG files and loss of image quality.
 

Create Blank Image

Create a blank image with specified pixel dimensions and color. This can be used as a background for a mashup using cutouts taken from other images (via Select Area) and annotation text (via Annotate Image). Input a file name, choose a background color, and set the desired pixel dimensions.


Trash Image File
Fotoxx uses the Linux desktop standard for trash. If this works, trashed image files go into the standard trash location and can be recovered later if wanted. Otherwise, Fotoxx puts trashed images into a desktop directory named "fotoxx-trash". You can delete it or move it to your Linux-specific trash. If standard trash does not work, you may be able to fix this yourself. See the technical note about this.


Rename Image File


This function can help automate the process of renaming a series of image files using a root name (e.g. an event or place name) and a sequence number. It is good for renaming a series of image files from a digital camera. Open the first image file in the series, input a new name, and press the [rename to] button. Use the [next] button to move to the next file if wanted. You can use the same name again by pressing the [previous] button and then add a suffix or sequence number. If you are using sequence numbers, press the [ +1 ] button after the [previous] button to get the next sequence number added to the name.


Batch Rename Files

This function is helpful if you want many image files (perhaps with the same date or from the same event) to have the same names with an added sequence number. In the dialog, specify a base name, a starting sequence number, and an increment. For example, a base name of "arctic cruise-", a starting sequence number of 100, and an increment of 1 will produce a series of file names like this: arctic cruise-100, arctic cruise-101, arctic cruise-102, etc. (file extensions will not be changed). Use the button [select files] to open a file chooser dialog to select as many image files as you want. When done, press [proceed] to rename all the image files at once. Don't use this function to rename non-image files, since Fotoxx will also try to update file name and tag associations in the search index file.



Print Image File

The print menu brings up a standard Page Setup dialog where you can select a printer, a paper size (letter, A4 ...), and orientation (portrait or landscape). Select your printer (do not use a default setting). The paper size shown will be the one last set in the Printer Properties dialog (a separate admin function in the System menu). If the paper size is wrong, fix it using the Printer Properties dialog. Changing the paper in the Page Setup dialog may be ignored or lead to a "paper mismatch" failure. After using the [apply] button, another dialog starts for entering the print margins. Use these to shrink the image size on the paper or shift the image position. When done, a Print dialog starts for the actual printing. Use the Print Preview button to check that the image has the right orientation and position and cancel the print if not.


Tools Menu

Manage Collections - Concepts
An image collection is an arbitrary collection of images that is manually assembled from other images. This is one method to make groups of associated images (other methods are tags, captions and comments, directory and file names). An image collection is simply a list of the member image files. The image files themselves are not copied or changed. A given image can be a member of multiple collections. Collections can be used to group images with some shared characteristics, such as photos from a vacation trip, photos of a given person taken at different times or events, a "best photos" collection, etc. Once a collection is made, you can call it up by name and use it for other purposes, e.g. view as a slide show or burn to a CD. You can add and remove images in a collection and rearrange the order of the images. An image may also be present multiple times in a collection.

Manage Collections Dialog


New: Supply a new collection name. This will be named in the dialog as the "Editing" collection.
Edit: Select an existing collection for editing. This will become the "Editing" collection.
View: Select a collection for viewing. The gallery window will show its thumbnails. This can be the collection being edited or any other.
Delete: Select an existing collection to delete. The collection is deleted, not the images.

After a collection for editing is created or selected, you can add or remove images by right clicking on a gallery thumbnail or main window image. A popup menu appears with the following entries:
    + add image to collection: <collection name>
    + remove image from collection
    + remove and save image
    + insert saved images here

Procedures
(1) Add images: use [New] or [Edit] to establish an edit collection. Use [Open] or [Gallery] to navigate to the images to add. Right-click each image to add and select the "add" menu. You can also use [View] to add images from an existing collection.
(2) Remove images: use [View] to view a thumbnail gallery of images in the collection. Right-click each image to remove and select the "remove" menu.
(3) Rearrange images: use [View] to view a thumbnail gallery of images in the collection. Right-click each image to be moved and select the "remove and save" menu. The thumbnails are immediately removed from the gallery and the images are saved in a separate list. Right-click the thumbnail where the saved images are to be inserted (after) and select the "insert" menu.


Move Collections
An image database can be moved by renaming or moving its top directory. The image files will follow automatically.  The function Synchronize Files can fix the Fotoxx search index. The named collections, however, will become useless because the stored file paths are invalid. The function Move Collections can be used to replace the top directory in all the existing named collections. Enter the old and new top directory names in the dialog and press [apply].


Batch Convert / Resize / Export

This function is used to convert, resize and export many image files at once (for planned uploads to a web site, to save disk space, etc.). The menu opens a dialog to select image files and specify options. Use the button [select files] to select image files from a gallery window (link). Select a maximum width and height for the output files (use huge values if no size reduction is wanted). Select the output file type. "same" means the file type will not be changed, otherwise all files will be converted to the specified type. Select the option: "replace originals" or "export to location". For the latter, input a directory where the resized and converted image files will be written, or use the [browse] button to locate the directory. Use the checkbox to remove EXIF/IPTC data from the output files, if desired. Finally, use the [proceed] button to start the resize process. A popup window shows the progress.


Convert RAW Files
This function converts selected RAW image files to JPEG, PNG, TIFF-8 or TIFF-16 format, using the program ufraw-batch. The two TIFF formats have respectively 8 and 16 bits per color. RAW files generally have 10-12 bits, therefore use TIFF-16 to keep all of the data available in a RAW file (the difference between 8 and 16 bit color is rarely visible). A file chooser dialog is opened. Choose one or more RAW image files (hold down the CTRL key to select multiple files). Then you will be asked to choose one of the above output formats. The image files are converted one at a time and displayed in the main window. Depending on the number of files, this can take a long time (my fast PC does about 24 image files per minute using a mix of raw file types and TIFF-16 output).


Slide Show

The images in the current directory, from a named collection, or from a previous search function are shown one by one. The image window is enlarged to the whole screen, and the menu and toolbar are removed. A dialog pops up to ask for some initial inputs. Enter a time duration to show each image, select the option to show only the latest image versions, and select the transition mode(s) to use when the image changes. Transition modes include arrow-keys (manual transition), instant replacement, fade-out / fade-in, and several kinetic methods of image replacement (e.g. the new image expands from the center to replace the old image). If "arrow-keys" is selected, then the time duration is irrelevant and the keyboard left and right arrow keys are used to move to the next or previous image. The arrow keys can still be used even if one of the other modes is selected. Use the escape key to get out of slide show mode. The spacebar can be used to pause and resume the timer between slides. If an image search is done before a slide show, these images are shown. Before starting the slide show, you can use the function Info > Edit Comments or Edit Caption to show relevant text for each image in a small window which you can push to the side. The text is updated for each image viewed in the slide show. The other Info menu displays will also update with each image. The slide show dialog also has an input for a music file or playlist. If not blank, the music will be started with the slide show.

It is also possible to start a slide show with or without music from the command line:
   $ fotoxx -slideshow /.../imagefile1.jpg  -music /.../musicfile.ogg
The slide show begins with the given image file and proceeds to following files in the same directory. The -music parameter is optional. If present, the following file is a music file (.mp3 .ogg ...) or a playlist. xdg-open is used to open the file with the preferred music player.


Synchronize Files

This is needed when Fotoxx is started for the first time, if you add new image files to your collection, or if you move or rename image files or their directories. Nothing is lost when image files are moved, but the image gallery (thumbnail) windows will be slow if a large number of files were added or moved, and the Search Images function will not find the new or moved files. The Synchronize Files function will create missing thumbnails, replace outdated ones, and refresh the search index file using current data from your image files. On a fast computer, new files are processed at 1000+ per minute and old files at 1000+ per second.

Images created (i.e. edited and saved) or moved within Fotoxx are taken care of automatically. Synchronize Files is only needed when new image files are created from outside Fotoxx (e.g. a new batch of files from a camera), or if files are moved or renamed from outside Fotoxx.

If you have used directory and/or file names to classify your images, you can make immediate use of these in the Search Images function. If you have saved captions, tags, titles, or ratings in your images (using Photoshop, Fotoxx, or other tools), these will also be searchable.

Synchronize Files starts automatically at Fotoxx startup if image files are detected with a date/time newer than the last Fotoxx session. It can also be started manually from the Tools menu. A dialog will ask for the topmost directory of your image files (e.g. /home/<user>/Pictures). That directory and any subdirectories containing images will be processed. It does not matter if other files are mixed. A popup window shows the new image files as they are found and processed. This window is left open for your inspection after the synchronize function is finished. After the images have been indexed, searching them (by captions/comments, file names, tags, date, rating) is almost instantaneous.


When Synchronize runs, you can use Fotoxx normally to navigate and view images, but editing images and metadata (tags, comments, etc.) is blocked until Synchronize is finished. You can see in the status bar if Synchronize is running. Unless there are hundreds of new images to process, this will be done in a few seconds.


Show RGB


When a point on the image is clicked, the RGB values are shown in a dialog window. The values have the format xxx.dd, where xxx is the upper 8 bits of the color value and .dd is the lower 8 bits. The range is 0.00 to 255.99. The lower 8 bits are zero unless the image is being edited or the image is a 16-bit tiff file. EV (exposure value) and OD (optical density) units are alternative units, useful for precise color adjustment. EV is zero for mid-brightness (128). OD (optical density or reflectivity) is 2.0 - Log(100 * RGB / 256). The outputs are updated immediately if the image is being edited. The last five points clicked are shown. The points are labeled on the image corresponding to the letters A-E in the dialog window.

  RGB
0
1
2
4
8
16
32
64
128
256
  EV
nan
-7
-6
-5
-4
-3
-2
-1
0
1
  OD
nan
2.41
2.11
1.81
1.51
1.20
0.90
0.60
0.30
0.0


Grid Lines

This function adds or removes horizontal and vertical lines across the image. The lines are useful when an image must be rotated for horizon alignment, or when an image is unbent or warped to straighten walls or other objects in the image. The settings for x- and y-spacing control the spacing (pixels) between the lines. If the controls for x- and y-count are NOT zero, then the x- and y-spacing values are ignored and the number of lines will be set to these counts. Example: set x- and y-count to 2 lines each in order to divide the image into thirds horizontally and vertically. The x- and y-grid checkboxes can be used to enable and disable the veritcal and horizontal lines separately. The keyboard key G can be used to toggle the grid lines on and off. This works also during an edit function. If an image is printed with grid lines enabled, the grid lines are also printed.


Burn Images to CD/DVD

This function enables you to choose image files and burn them into a CD or DVD. When the function starts, an image gallery window is displayed from which you can select the image files to burn (link). When done, the list of image files is sent to Brasero to burn a CD or DVD.


E-mail Images
This function enables you to choose up to about 40 image files and send them to your preferred e-mail program. In the dialog, press the [select files] button to display an image gallery window from which you can select the image files (
link). After selecting the images, set the desired maximum width and height in the dialog. The [proceed] button will do the image reductions and send them to the e-mail program. The reduced images are put into a temporary directory (/tmp/<user>/fotoxx/) and do not affect the original images. The e-mail program is started with the selected image files as attachments. You must then add the subject, text and recipients, and finally send the e-mail.

This function uses xdg-email (Linux Standards Base) which must be installed and work correctly. It works for some Linux flavors with some e-mail programs and not for others. If it does not work for you, then the next best appproach is to use Transform > Batch Convert to select, optionally reduce, and export the image files to your Desktop. Then you can conveniently attach them from within your e-mail program.


Check Monitor

Eight color bands are written across the screen with brightness from zero (black) to 100%. You can use this to adjust the brightness of your monitor. The left end of each stripe should be as black as possible, but you should start to see some color within a few mm from the left edge. If the completely black portion is wider than this, adjust the monitor. There are 255 brightness steps from black to 100% (8 bits per color). The steps are too small to distinguish with the eye. This evaluation should be done in a darkened room (with little external light falling on the monitor).


Monitor Gamma

Gamma determines how RGB brightness values (0-255) are converted into brightness as perceived by the eye. The standard value is 2.2 and this should normally be used for image editing. An adjustment chart is provided, courtesy of Norman Koren. Adjust the dialog slider until the shaded bands disappear at scale location 2.2. The chart only works at 100% size, so do not zoom the chart.


Brightness Distribution

This function opens a small window that shows a brightness distribution graph of the current image in the main window. This graph updates immediately for new images or as edit functions change the image.


Lens Parameters

This is a dialog for setting and saving the two lens parameters, lens_mm and lens_bow, which must be set for each camera/lens used for panoramas. These parameters govern how Fotoxx warps the panorama input images so that they can fit together accurately. Enter a name for the lens/camera and the two parameters. Up to four lens/cameras may be entered. Lens_mm is roughly the focal length of the lens (35mm equivalent), and lens_bow is a factor to compensate for edge-curving distortion (barrel and pincushion distortion). How to set these parameters is described here, but you should read the section on making panoramas first, in order to better understand the following instructions.



Change Language

This function allows you to change the GUI to one of the available languages. If your language is not available or has missing translations, consider making a translation, which is not difficult (more).


Edit Translations

This function is used to revise the GUI translations interactively, as Fotoxx is being used. Traditionally, translation files (.po files) are edited separately. These are then installed and Fotoxx is exercised to see how the translations look. The advantage with this new method is that the application context is experienced as the translation is made, which should result in easier and better translations. Also, the new translations are immediately used by Fotoxx. For details about how to do translations, see the menu Help > Translations. This describes how .po files work and the procedures for editing them. The section "Interactive Translations" describes how to use this interactive method to update .po files. You can also start Fotoxx with the command line parameter "-translate" to make it start up in translation mode. This will capture the main window menu and toolbar translations which would be missed if the menu function is used.


Menu and Launcher

This function puts a Fotoxx icon / launcher on the desktop and adds Fotoxx to the desktop menu system under the category "Graphics". Your system must be LSB compliant (Linux Standards Base). The effectiveness of this has been sporadic. You may need to log off and back on to see the new menu entry. A dialog allows you to customize the startup options.


User Settings

Various user preferences and settings are collected in this dialog.
 Startup Display 
The initial window content when Fotoxx is started. Directory can be the top image directory or any sub-subdirectory underneath. Image File is any valid image file.
 Toolbar Style
The desired toolbar style for the main window and gallery window.
 Warn Overwrite 
Whether attempts to save a modified image replacing the original image is warned or not. Saving to a new version is never warned. Saving to a new file name is warned only if the file already exists.
 Panorama
The two lens parameters used for Panoramas. Normally EXIF data is used for lens mm (35mm focal length equivalent), and the value here is used only if there is no EXIF (e.g. a scanned print from a film camera). Lens bow is for compensation of barrel/pincushion distortion. There is no EXIF for this, but fortunately it can usually be left at zero. There is a way to measure this described in the Panorama topic.
 Zoom Ratio
The image size increase with each zoom-in. The choices are 4/3/2/1 zooms for each 2x increase in size.


Memory Usage
This is a diagnostic tool to detect memory leaks. A table is dumped to the log file (stdout) which shows total memory usage and usage by category. If any of these numbers increase consistently with Fotoxx usage, then there could be a memory leak bug.


 

Info Menu

Note: the program exiftool must be installed for the following functions to work. Fotoxx uses this program to read and write text information stored within an image file (metadata: EXIF, IPTC, etc.). If exiftool is not installed, then modifying an image with Fotoxx will lose all metadata. For recent Ubuntu, the package name is: libimage-exiftool-perl. Other distros may be different.

I have provided a short analysis of the alternatives for organizing a large image collection so that it can be easily searched. If you are interested, you can find it here.


Edit Caption/Comments

This is a special function for editing image text saved in IPTC "Captions" and EXIF "User Comments". Enter any text you want to associate with the current image. Multiple text lines of any length can be entered, up to an overall limit of 1000 characters. Press the [Apply] button to save the text in the IPTC and EXIF data for the current image. The dialog can be left open while navigating to different images, and the current text for each image is shown, if any. Enter or modify the text and press [Apply] to make the change permanent. If you need to enter (nearly) the same text for multiple images, you can use cut and paste. You can leave this window open in a corner of the monitor to show the comments as new images are viewed (also in Slide Show mode). You can search for images based on captions and comments (see topic Search Images).


Tags Overview

Image files can have classification tags (categories, keywords) assigned to them. These can be used to search a large image collection for those images having desired tags. Typical tags: the main subject of a photo, the associated event, the location, the person(s), etc. Tags reside inside the image metadata (IPTC:keywords). Tags are normally one word, but a short phrase with imbedded blanks or other delimiters can be used. Commas and semicolons are recognized internally as delimiters (separators) between tags, and therefore cannot be used within a tag. A compound tag like "Arizona scenery" is allowed, but you should use two tags instead for more flexibility: you can search for images having either tag or both tags.

You can use a directory hierarchy to make a physical organization of your images, e.g. directory names corresponding to year or location or other scheme. You can use file names for the main subject of the image. Such physical organizations are useful but optional: you can also put all your images in one giant directory and keep the numeric file names that come out of the camera. Regardless of the physical organization, tags can be used to create other organizations, e.g. to label all the images of one person over all years, events, locations, etc. All images having a desired tag or tags can be found quickly and displayed in an image gallery window (thumbnails), where you can further review the images and choose those for viewing, editing, or changing their tags.

If you have used directory and file names in a meaningful way, you can keep using these, and you can also search for images using these names as well as tags. There is no need to duplicate information already available. See "Search Images" below.

Images may have a date (date of photo) which is pulled from the image EXIF data, if present, or manually set. Images may have a "star rating" for the importance or quality of an image. Dates and star ratings can also be used as search criteria.

Limitations and Practical Tips
The following are the default limits for tags. These are compile time constants which can be easily increased if needed, although I believe they are large enough to exceed practical limits:
     o   max. tag length: 50 characters per tag
     o   max. tags for one image file: 1000 characters
     o   max. tags in a tag category: 50000 characters
     o   max. tags overall: 50000 characters
     o   max. tags in a search: 200 characters
     o   max. tags for Batch Add Tags: 200 characters

The practical limit for the overall number of tags is in the range 200-500. Exceeding this range is possible but will lead to some practical problems: The window showing available tags will be large and tags will become harder to find (although sorted by category and within category), and the point and click method of adding tags will become more cumbersome. If tags are broadly defined and fewer in number, the search results will be larger, but using the search results (image gallery window) to find a smaller set of images is also quite fast. Physical file organization is also preserved in the gallery window (image files located together in their directories will also appear together in the gallery window). All in all, my recommendation for the casual photographer is to use fewer and broader tags.


Edit Tags


To assign tags to the current image, select the menu Info > Edit Tags. Existing tags are shown in "current tags". Available tags are shown in the "defined tags" window below. One of these tags can be added to the image by pointing and clicking with the mouse. A tag can be deleted by pointing and clicking within "current tags". Tags recently added are shown in "recently added". This is a convenience to make adding tags to a new batch of images easier, assuming that many of the same tags will be used repeatedly. Point and click the same way. The date of the image, if available, is shown as "image date". This may be entered if missing, or changed. You can enter a full date in the format yyyymmdd or a shorter format yyyy or yyyymm. A missing month/day is logically equivalent to 01/01 when used as a low limit for searching, or 12/31 when used as a high limit. The [use-last] button fills-in the date from the last date entered or shown. This is to allow easy dating of a series of images. You may enter an optional "stars" rating for the image. The dialog remains open if you navigate to a new image, and the current tags are filled-in from that image. The [Apply] button writes the tag information to the image file and to the search index file used for searching images.


Manage Tags

To create new tags, use the menu Info > Manage Tags. You can also assign categories to tags to help organize them and locate them more quickly when adding tags to images. They are optional and they play no role in tag assignment or searching: only the tag is stored in an image, not its category. Typical categories are people, places, things, events, scenery, buildings, art, etc. To add a new tag with a new category, enter the caterory and tag and click [create]. The category can be left blank and the tag will be assigned to "nocatg". To assign a tag to a different category, click a category (bold text) or enter a new one, click the tag, and press [create]. The tag will move from the old to the new category. To delete a tag, click the tag and press [delete]. The window of defined tags is updated to reflect changes. If the Edit Tags dialog is open, its window of defined tags will also be updated. You can keep both the Edit Tags and Manage Tags dialogs open if you need to create or change tags for immediate application to images. Tags used in images but not assigned to a category will appear under "nocatg".

Note:
 a newly created tag is appended to the end of the tag list for its category. The next time fotoxx is started, all categories and their tag lists are sorted alphabetically, except that "nocatg" is always last. A tag will also disappear from the list if it is no longer assigned to any image.


Batch Add Tags
When adding tags to a large number of images having many of the same tags (i.e. the same event or subject), use this function to speed up the process. In the dialog, use the [select files] button to open a gallery window with thumbnail images from which you can select the image files (link). After selecting files, specify tags to add to the images by clicking tags in the "defined tags" list. If you need a new tag, input the tag and press [create tag] to add it to the list. When done specifying image files and tags, press [proceed] to add the tags to the image files.


Batch Delete/Replace Tag
This function is used to delete a single tag from many images at once, or replace a tag with another one. In the dialog, input a tag to delete and an optional replacement tag. Use the [select files] button to open a gallery window with thumbnail images from which you can select the image files (link). Alternatively, use the "search all files" checkbox to specify that the tag will be removed/replaced for all image files in the image database (all image files having the tag, as found with the Search Images function).


View Info (short)
View Info (long)

The View Info functions will display metadata for the current image file, if available. EXIF metadata contains the date and time of a photo, shutter speed, focal length, pixel dimensions, etc. Digital cameras store this data inside the image. IPTC metadata contains tags (from Fotoxx, Photoshop ...) and captions (often for published images). If an image is edited and then saved, the metadata is updated and stored with the new image.

The View Info short report outputs the most commonly needed data, including the photo date and time, exposure data, focal length (real and 35mm equivalent), user-assigned tags and star rating, comments, caption, and a history of Fotoxx edit functions that have been applied to the image. The long report reports all the data available.

Fotoxx uses the following EXIF / IPTC data items:
    Key Name
Fotoxx Usage
    Date/Time Original
Edit Tags function - image date
    Keywords
Edit Tags function - image tags
    Rating
Edit Tags function - image stars
    User Comments
Edit Comments function
    Caption-Abstract Edit Caption function
    Edit Status
History of Fotoxx edits applied to the image
    any key
Edit Info, Delete Info


Edit Info
A specific metadata ID (key) can be added (if legitimate) or revised. Enter the key name and press [fetch] to retrieve existing data, if any. Enter the new data and press [save] to save the new or revised data. You may enter the key name in lower case and without blanks, e.g. the EXIF key "User Comment" may be more easily entered as "usercomment". The dialog is live: the current key name will be fetched automatically for each new image file opened, and it can then be revised and saved if wanted.


Delete Info
This function allows deletion of a specified metadata key, or all metadata at once. Input a key name in lower case and without blanks, e.g. the EXIF key "User Comment" is entered as "usercomment".


Search Images


Example: select images in 2005 or later, with 4 stars or more, having tags buildings or monuments, and containing dresden in the directory or file name.

A search index file is used for searching, which makes it very fast (thousands of images per second are searched). The index is generated from the tags, comments, captions, dates and star ratings saved inside the image file itself (EXIF and IPTC metadata). Thus you can rearrange your image directories and image files without losing anything - you must only regenerate the search index file, which is simple and fast. See Tools > Synchronize Files.

Use the Search Images function to find images having desired tags, dates, stars, comments, captions, or file names. Available tags are shown and can be chosen with point and click. Use the radio buttons "all" or "any" to indicate if all tags or any tag must be present for an image to be selected. Press the [search] button to perform the search. Matching images are displayed in a pageable image gallery window (thumbnails). Choose images to view or edit by clicking the thumbnails. The set of matching images are used for the buttons [prev] and [next]. If an image file is selected with the File > Open function or toolbar button [Open], then the current image set (gallery window list) is replaced by the directory of the newly opened image file.

A date range may be optionally entered, to further restrict the search to images within the date range. The format is yyyymmdd. Images are selected which have a date on or after the first date, if present, and on or before the second date, if present. Missing month/day default to 01/01 for the low date limit and to 12/31 for the hight date limit.

A pair of star ratings may be optionally entered to restrict the results to images having a star rating within the given range. A missing low value implies zero, and a missing high value means unlimited.

Image directory and file names may also be searched. In the input field "file names", enter any number of names used for your image directories and file names, separated by blanks. An input of [ egypt cairo ] would match all image directory/file names containing either of these strings. Name matching is not sensitive to case.

Image comments and captions may also be searched (see Edit Comments, Edit Captions). Enter the words to search for in the dialog "search text" field, separated by blanks. These will be matched to every word in the comments and captions of all images, and matching images are selected.

The radio buttons "all" and "any" apply to all matching options: tags, text, and file names. You can select images having ALL the entered strings, or ANY of the entered strings. Example: if the search file field contains [egypt cairo] and "any" is selected, then image files with either of these names within the directory or file name would be selected.

You can use comments, captions and directory/file names as an alternative to using tags. Effective use of tags can require high organization and attention to detail, and therefore lots of time. Also revising your tag organization can be very hard if hundreds of images are affected. User comments and file names are much easier, if less exacting. Simply name your image files with the key topic or content, and add comments or captions with adequate descriptive words. You do not have to have an elaborate tag system, and revisions are easier. The tags system has the advantage that a complete list of defined tags is automatically maintained and presented when you search images, and adding tags to new images is a point and click operation.


Search Metadata

Report any desired metadata using a combined image and text layout. The starting point is always the current image gallery list, which can be an image directory (the normal case) or the results from an immediately preceeding Search Images. The selection criteria available in Search Images is always shown first: file name, date, star rating, caption, comments, and tags. When Search Metadata is started, you can enter up to five more metadata items to report. The items available in any given image file can be shown using View Info (long). These include camera make and model, exposure time, F-number, ISO, metering mode, focal length, shooting mode, etc. etc. You can enter shortcut names like "exposuretime" instead of "Exposure Time". You may also enter match criteria, if wanted, so that only the images with matching metadata are reported. For example, if you enter "camera model name" with the match value "DMC-FZ28" (my Panasonic) then only the images taken with this camera will be reported. You can also enter multiple match values for one key, separated by blanks.

Performance: If no extra metadata to report is entered, then 1000+ images/second are searched and reported. If extra metadata is entered, the search performance slows down to something like 100 images/second. This is because the image files are being read to extract the metadata, instead of using the search index file. For good performance, always use Search Images first to reduce the images being searched as much as possible. Use dates, tags, file names, etc. to reduce the image count. Then use Search Metadata to search for and report additional metadata.




Select Menu

Overview
Edit functions normally apply to the entire image, but it is possible to edit part of an image (an "area") and leave the rest unchanged. If an image area has been selected, then the Retouch and Art edit functions will work only within this area. Other functions ignore a selected area. An area may be selected before starting an edit function, or while an edit function is active. The selected area is immediately active, prior edits are retained, and future edits will apply only within the area. If another edit function is started, the selected area remains active, so it is possible to carry out a series of edits on one area.

"Layers" in Photoshop and Gimp are "areas" in Fotoxx. Instead of selecting something from the image, making a separate layer from the selection, performing edit functions on the layer and finally merging the layers, you select something in the image and perform edit functions on the selection, with WYSIWYG feedback during the edit. Areas can also be saved, pasted into other images, and edited there.


Select Area


If an area is already present, its outline will be shown. You can continue to edit this area or use [Unselect] to discard it and start a new area. Select one of the methods (explained below) and proceed to define the area. The [Hide] button removes the area outline (for better visibility of image edits and edge blending). Use the [Show] button to show the outline. The select area dialog can be exited and re-started later to modify a selected area or start a new one.

Methods to enclose one or more spaces that will belong to the final area:
  Rectangle drag the mouse to enclose a rectangular area
  Ellipse
drag the mouse to enclose an elliptical area
  Freehand Draw  
drag and click the mouse to draw lines that outline an enclosed space
  Follow Edge 
click along the edge of an object in the image to draw lines that follow the edge, or drag the mouse to draw freehand
  Select by Mouse   
select a small area of pixels around the mouse and aggregate adjacent areas with pixels matching in color and brightness
Methods may be used in any sequence to define spaces that are either joined or detached. The following paragraphs explain the details of each method.

Rectangle: Drag the mouse from one corner to the opposite corner of the desired rectangular area to select. A rectangle is drawn to enclose the area. Right-click to delete and start over. Repeat the process to select more rectangular areas.

Ellipse: This works the same as rectangle selection, except that the area enclosed is an ellipse that fits within the rectangle.

Freehand draw: Drag the mouse (left button down) to draw a freehand (curvey) line, or left-click to connect a straight line from the last point drawn to the point clicked. Continue around the target area until it is surrounded with connected curves and lines. Right click to remove previous lines (mistakes). A right click will remove the previous clicked or dragged line, up to 50 pixels. Right click repeatedly to remove more. A new clicked line will always connect to the end of the previous line. A new dragged line will connect to the previous line if it is started close to the end of that line. If it is started elsewhere, a disconnected line will be drawn. You can start a new drag from far away and draw back to meet the previous line. If a clicked line connects to an undesired point (i.e. you don't want to connect to the last line drawn), right click to erase it and then use drag to start a new sequence of lines. A right-button drag can be used to erase small segments: right-drag closely along a line to erase it, then left-drag to re-draw the line. At the end, an area must be fully enclosed, with no gaps. Lines that overlap a little at the ends are OK. Gaps can be difficult to find and correct, so work at 100% image size or greater and be careful. A series of lines automatically connected with left clicks will not leave gaps, but deviation from this sequence is likely to create gaps. To reduce the possibility of gaps, use deliberate overlaps when manually connecting lines.

Follow edge: High-contrast pixels (likely object edges) between the last point drawn and a newly clicked position are found and connected. This is effective for clear edges that are not too irregular. Fuzzy and ragged edges may not work well and freehand draw will be needed if high precision is necessary. The rules for connecting lines are the same as explained above. Dragging the mouse instead of clicking works like freehand draw, so you can switch back and forth.

Select by mouse:
  The radius control will define a circle around the mouse pointer. Click the left mouse button somewhere on the image to define a group of pixels to match. The group is all pixels inside the circle, and the degree of match is defined by the match control: 100 means a perfect match is required. Adjacent areas (within search range) with pixels matching any of the selected pixels will be selected. A bigger radius or a lesser match value will select more pixels. If the mouse is dragged or clicked within the selected area, the selection will be expanded to match new pixels enclosed by the mouse and within the search range. Drag the mouse over new areas you want to include, or over "islands" of non-matching pixels you want to include. Watch the selected area expand accordingly. If you go too far, right click to remove the last selection. Repeat if needed to remove more previous selections. Reduce the radius or increase the match level to gain finer control - the selection will expand more slowly and stay closer to the mouse position. The radius of selection is limited by search range which is a multiplyer of the mouse radius. A small radius and search range can be used to follow along an edge and select pixels up to the edge with good precision. Change to a larger radius and/or search range to select larger areas after the fine work is complete. If the "firewall" is enabled, then already-selected pixels will act as a barrier to stop the search for new pixels. This is sometimes useful, e.g. an existing selection boundary should remain fixed and you want to extend the selection in the interior. Right drag acts as an un-select: pixels matching pixels inside the mouse radius and within the search range are un-selected. You may need some practice to get a feeling for this and be able to work efficiently.

Summary
  left click or drag
select pixels inside radius and those with matching colors inside search range
  right click
undo previous selection, repeat to unselect more
  right drag
unselect pixels inside radius and those with matching colors inside search range
  match mouse color  
uncheck to turn color matching off: only pixels within the mouse radius are selected or unselected

Blend Width: Edits made within an area can be blended with the surrounding image over a distance called "blend width". At the edge of the selected area, the image is the original (unedited) image. At a distance of "blend width" from any edge inside the area, the image is the edited image. For distances in-between, the pixels are a mix of original and edited pixels with a gradual transition. Use the Blend Width control to set the blend width for the current or subsequent edit functions. Zero blend width gives a hard edge to the area edit. Increasing blend width makes the edges of the edit more gradual and harder to distinguish from the original image. Changing the value for the first time after editing an area will cause the edge distance to be calculated for each pixel in the area. This is normally fast (a few seconds), but it may take minutes if the area is large and has a complex geometry (a very long edge). Whenever an area is re-edited or inverted, the edge calculation is discarded and must be repeated if blending is wanted. If the edge of a selected area is within 4 pixels of the image edge, it is no longer considered an edge for blending. If a selected area includes a portion of the image edge, and you do not want blending along this edge (the normal case), be sure the edge of the area is within 4 pixels of the image edge.

Show / Hide: Use [Hide] to hide the area outlines. This is useful when editing the image/area, to better see the effects of the edit without interference from the area outlines. Use [Show] to show the outlines and resume editing the area.

Color: Alternates the color used to show the area outline (red, green, black).

Finish: When you are finished selecting the enclosed spaces, use the [Finish] button to complete the process. A popup dialog will ask you to click the mouse inside each enclosed space in sequence. This action launches a search for all pixels within the enclosed space, and these are mapped and saved. The enclosed space is temporarily colored so you can see exactly what part of the image is being selected. The dialog will show the status of the search, "success" or "outline has a gap". If there is a gap in the outline, an attempt is made to show where the gap is: you will see a line coming out of the colored space to meet the edge of an imaginary rectangle enclosing the space. You may be able to follow this line back to the gap, but if the area is convoluted finding the gap can be difficult. Each use of [finish] will produce a different picture that may lead you to the gap. Carefully inspect the outline of the area, close the hole, and use [Finish] again. An area is not effective for edits until it is successfully finished. Any enclosed area can be selected, even those not explicitely outlined (e.g. if you use select by mouse to select a donut with a hole, you can still click the hole to include it in the area).

Unfinish:
To re-edit a finished area, it is sometimes necessary to un-finish it to make the edit functions work normally.

Disable / Enable: Disable the current area and keep the data so that it can be re-activated later. This allows you to alternate edits within a selected area and edits for the entire image.

Invert: This function inverts an existing area: the entire image is selected except for the existing area. Using the function two times returns the original selected area. Inverting a selected area invalidates the edge calculation which will be repeated if edge blending is selected.

Unselect: Discard the current area permanently.


Area Show / Hide
Show or hide the outline of the current area. Hiding the area is useful when the area is being modified with one of the edit functions. This makes it easier to judge the effects of the edit. These are also available as buttons in the Select Area dialog.


Area Enable / Disable
Disable the current area and keep the data so that it can be re-activated later (Enable menu). This allows you to alternate edits within a selected area and edits for the entire image. These are also available as buttons in the Select Area dialog.


Area Invert
Invert an existing area: the entire image is selected except for the existing area. Using the function two times returns the original selected area. Inverting a selected area invalidates the edge calculation which must be repeated if edge blending is desired. This is also available as a button in the Select Area dialog.


Area Unselect
Permenently discard the current area. This is also available as a button in the Select Area dialog.


Area Copy / Paste

Copy:
The current selected area is copied and saved in memory.

Paste:
The saved area is pasted into the current image. It can be moved around by dragging with the mouse. Use the resize and angle buttons to resize or rotate the pasted object. Use the edge blend slider to make a blended edge if desired. Press the [done] button in the popup dialog. The pasted area now behaves like a Select Area. You can edit within the area and use the [blend width] control in the Select Area dialog.


Area Open and Save

If a selected area is active or has been saved with the menu Select > Copy, it can be saved to an image file using the menu Select > Save. You are asked to supply a name. Two files are saved: the image is saved to filename.tiff and the transparency data is saved to filename.info. These files reside at /home/<user>/.fotoxx/saved_areas/. Use Select > Open to choose a saved area (choose the tiff file), which will be dumped into the image where it can be moved around, resized, etc. as with the copy and paste functions.


Select Whole Image

It is sometimes effective to apply a retouching function controlled by image brightness, e.g. apply noise reduction to darker areas of the image while leaving brighter areas alone. To do this, use the menu Select > Select Whole Image. Choose brightness or one of the RGB colors as the controller. The editable graph controls how subsequent edit functions are applied to the image. The x-axis is pixel brightness from dark to bright, or the selected RGB color from 0 to 100% of the pixel brightness. The y-axis value governs how strongly the edit function affects a corresponding pixel. A low value minimizes the effect, and a high value maximizes it. Example: apply tone mapping primarily to dark pixels: Use Select > Select Whole Image and drag the curve so that high values are on the left (dark pixels) and low values are in the middle and on the right (bright pixels). Now use Retouch > Tone Mapping to apply tone mapping to the darker areas of the image. You can edit either curve (whole image curve, tone mapping curve) while watching the resulting image.


Select and Edit

Use this function in combination with a retouch edit function. Specify a mouse radius and power factors for the mouse center and radius edge. Then start a retouch edit function if not already active. The mouse pointer will be surrounded by a circle with the specified radius. When the mouse is dragged over an area of the image, the current retouch function is applied within the circle. The "strength" of the function is regulated by the power factors. Typically you will use a high value at the center and zero at the edge, meaning that the strength of the edit will be maximum at the center, changing gradually to zero at the edge of the circle. As you drag the mouse over the same area repeatedly, the edits are slowly accumulated. For example, if the edit function is Brightness/Color, and the brightness curve is set to a high level, then the image will be slowly brightened in the area where the mouse is dragged. This is called dodge and burn in other image editors, but other retouch functions can also be used, e.g. tone mapping or blur. Use the [undo] and [redo] toolbar buttons to monitor the change, which may be hard to notice at first. Set the center power to 100 to make faster changes (with less fine control). Use a left-button drag to weaken the edit or ultimately erase it. When done using one edit function in one or more image areas, use the [done] button on the edit dialog to complete the edit. Use the [reset area] button to erase the active area that is now left over from the mouse dragging. If you leave the area active and start a new edit function, the results are unpredictable. A suggested approach is: (1) start the Select and Edit dialog, (2) start the edit function with its initial settings (the effect on the image will be zero since no mouse dragging has been done), (3) drag the mouse over the desired areas and watch the effect, (4) adjust the edit function settings, (5) alternate between the previous two steps. This method to "paint" a retouch function incrementally can improve selected areas of an image quickly and easily. It works with any edit function that can use selected areas. The most useful are Brightness/Color and Tone Mapping.



Transform Menu


Rotate Image

The rotate menu function starts a dialog to rotate the image clockwise (+) or counterclockwise (-) in steps of 0.1, 1, 10, or 90 degrees. For a tilted image, use the mouse to drag the right edge up or down until the image looks level. Use the 90 degree steps to convert an image taken in vertical format to horizontal. No resolution is lost with 90 degree rotation. For other angles, the loss of resolution is about 1/2 pixel. The output image is increased to accommodate the rotated input image without size reduction - e.g. a 100 x 100 image rotated 45 degrees will be inside a new image box of 141 x 141 pixels, and the unused areas will be black. Use the [trim] button to remove these expanded margins.


Trim Image
(aka crop)
The HDR, HDF and panorama functions will leave some black margins around the edges where the images did not overlap. Use the trim function to remove these areas, or any other unwanted margins. An initial selection rectangle is drawn (using previous trim dimensions if they fit within the current image size). Click or drag near any corner of the rectangle to move that corner. When done, press the [Done] button in the dialog box to cut-off parts of the image outside the selection rectangle. The dialog box shows the current width/height ratio of the selection rectangle. If the box "lock ratio" is checked, then moving one corner of the rectangle will also move the opposite corner to keep the same ratio. You can also drag from the middle of the rectangle to shift the whole rectangle without changing its dimensions. You can use the width and height spin buttons to input desired pixel dimensions directly, and the selection rectangle will adjust to these.

The six ratio buttons allow you to choose a preset width/height ratio. The button [invert] exchanges the width/height ratio (2:1 becomes 1:2 etc). You can change the ratio button names and the corresponding ratios with the button [customize] which starts the second dialog shown above. Enter desired button names in the first row of six text entry areas, and enter the corresponding width/height ratios in the second row (the default names are the same as the ratios, except for "gold"). Use the ratio 16:9 for the HDTV format. The default [gold] button uses the golden ratio, about 1.618:1. You do not have to keep it.


Auto-Trim Image

The functions panorama, HDR/HDF, stack, unbend, and warp can leave black margins where images did not overlay or were bent away from the edge. Auto-Trim automatically sets trim margins to omit these areas and then starts the Trim function (previous topic) with the margins pre-set. If these are correct, press the [done] button to finish. If not, change the margins as described above. Auto-Trim tries to find a maximum rectangle that does not overlap any of the black margin areas. This may or may not be the desired margins, so you can keep them or move them with the mouse before comitting with the [done] button.


Resize Image
(aka rescale)

This function sets a new image width and height. You can input the new pixel width and height directly or choose a percent change for width and height. Buttons are present for setting the new size to 3/4, 2/3, 1/2, 1/3, or 1/4 of the original size. Using one of these ratios will minimize loss of resolution. If the lock ratio box is checked, the original width / height ratio will be preserved, meaning that if one dimension is changed, the other dimension will be changed to match. The change is made immediately, but the image will look the same unless it becomes smaller than the window, causing a visible shrinkage. Leave the dialog with [done] to save the changes or [cancel] to keep the original size. The image file size (status bar) is not updated until the modified image is saved.



Annotate Image

With this function you can edit descriptive text and write directly on the image. Enter the text into the dialog. Multiple lines can be used. After editing the text in the window, left-click the mouse where you want the text on the image. Click or drag to move the text elsewhere. Right click to remove the text. Use the [Font] button to select a different font and size. Use the [Size] control to increase or decrease the text size. Use the [Angle] control to change the angle of the text. The foreground (text) and background colors and transparency can be adjusted. The example shows green text on a blue background, with the background being 77% transparent, meaning that the image shows through the background. The 3rd color option is to supply an optional outline around the text, in this case red. [Width] controls how wide the outline is. The [Open] and [Save] buttons start a file chooser dialog with which you can load or save all annotation data from or to a file. All the items in the dialog are loaded or saved (text, font, etc.), so you can keep a collection of often-used annotations.

Making a Watermark: use a foreground transparency of 70% or more and a background transparency of 100%. The text should be faint but readable. To add a "relief" effect, use Select Area to put a box around the text and use the function Art > Simulate Embossing to raise the text (if brighter than the image) or recess the text (if darker).


Flip Image
Choose either horizontal or vertical flip from the dialog. The image is reversed (mirrored) vertically or horizontally. Repeating the flip restores the original image. Doing both a horizontal and vertical flip is the same as a 180 degree rotation.


Make Negative
Use this function to make a black and white or color negative, or convert a negative image into a positive image.
Select one of the four buttons:
    black/white positive - convert a color image to black and white

    black/white negative - convert to black and white and reverse brightness
    color positive - do nothing at all, or undo one of the others
    color negative - replace each RGB color with its compliment
Color negative: Each RGB color is replaced with the maximum value - the color value. For example, if the RGB colors (% of maximum) are 20/40/60, then the negative color is 80/60/40. Doing this twice brings back the original colors. This produces complimentary colors as follows: red becomes cyan, green becomes magneta, and blue becomes yellow.


Unbend Image


Panoramas of nearby subjects (typically buildings or interior rooms) may show straight lines that are curved, or buildings that are slanted. Bending of the images is necessary in the panorama process in order for the images to fit together. For remote subjects (esp. landscapes) this is not noticeable. The unbend function can be used to straighten curved lines and remove the slant from vertical lines. Vertical and horizontal dotted lines are drawn over the image, showing the unbend axes. Click or drag the mouse near the end of a line to move it. Input values for horizontal and vertical unbend and watch the effect on the image. Increase or decrease the values and repeat until satisfied. Move the axes to change the centers of unbending. The linear values will slant the image left/right or top/bottom edges to remove slant. The curved values will straighten the image curving that comes from making a panorama. See also "Warp Image" for another method of correcting image curving and perspective problems.


Keystone Correction

This function can be used to straighten a photo made from an offset angle. The painting on the left is the original photo, taken from below and left of center, to reduce reflections. The painting on the right is the straightened version. This function can also be used to straighten a building photographed from an angle, or a book page or document, etc.

Click on the four corners of the tetragon shape that you want to make into a rectangle (in the above case, the four corners of the painting or frame), then select [apply]. Use [reset] to go back and try again if needed. The clicked corners are labeled with small letters A, B, C, D. The upper left corner of the square enclosing the letter precisely marks the corner position. Clicking near a corner will move it to the new position. After the 4th corner is defined, a new click replaces the closest corner.


Warp Image (area)

This function can be used to make distortions within an image. You can select an image area and drag the mouse to stretch this area with respect to the rest of the image. The image reacts as if made of rubber. The movement is maximum at the mouse pointer and declines to zero at the edges of the selected area. Many mouse drags of different lengths and directions can be combined to achieve the desired results. The [undo last] button will remove the most recent stretch (up to the last 100). When finished, you can select another area and do some more warping, or select [done] to exit the function. The method used limits loss of resolution from repeated warps: for each warp step, the total movement of each pixel is accumulated and the original image is warped to the latest pixel positions. The pixels are interpolated to reduce jaggies and improve sharpness.


Warp Image (curved)

This function is useful to correct perspective problems (see also "Unbend"). Drag the image from any position, using the mouse. The entire image will be pulled or pushed in the direction of the mouse, but areas near the mouse are moved more than more distant areas. You can straighten curved lines or deliberately curve the image.


Warp Image (linear)

This function is useful to correct perspective problems (see also "Unbend"). Drag the image from any position, using the mouse. The entire image will be pulled or pushed in the direction of the mouse, but areas near the mouse are moved more than more distant areas. You can straighten curved lines or deliberately curve the image. This function works over a broader area than the curved warp and causes less image curvature. To minimize the addition of curvature, pull only on the image corners.


Warp Image (affine)
This function can be used to warp an image in interesting ways. Drag the image from a corner or edge using the mouse. The changes are purely linear so straight lines remain straight. This transform is called "affine". Technical details can be found with Google.



Retouch Menu


Brightness/Color

This function is used to change brightness, contrast, color saturation, and color balance (relative RGB levels). You can adjust all of these items as a function of the original image pixel brightness. To illustrate, you could increase color saturation in darker image areas and leave it unchanged in brighter image areas.

There are 5 response curves for the 5 image attributes of brightness, color saturation, and color balance (levels of red, green, and blue). The radio buttons select which curve is active and displayed. The curve represents a value (Y-axis) for each level of image brightness (X-axis). The middle Y-value is neutral (no change from the initial value). Higher and lower Y-values represent corresponding higher and lower settings for the 5 attributes. The initial curves are flat at the middle value.

The curves can be dragged up or down with the mouse. An anchor point (black dot) is added to the curve wherever it is pulled, and this becomes a constraint for subsequent pulls: the curve will continue to go through this point as other parts of the curve are pulled. Anchor points can also be dragged, or deleted by right-clicking them.

The image changes in real-time as the curves are moved. Simply move the curves and observe the image until you are satisfied. For example, to increase overall contrast, make the Brightness curve lower on the left and/or higher on the right. To brighten areas that are too dark, raise the left side of the Brightness curve. The buttons [+++] etc. can be used to shift the whole curve rapidly in various ways.

Brightness changes all RGB values for a pixel by the same factor. Color saturation changes the dominant RGB color(s) within each pixel and moves other colors in the opposite direction, so that overall brightness does not change. The curves for the three colors change one color at a time. For example, if dark image areas have a red hue, lower the left side of the Red curve.

The scale range is +/- 2.0 EV (F-stops) for a total brightness range of 1/4 to 4x. The step size for the buttons [+++] etc. is 0.1 EV or about 7% brightness change. The alternative small step size is 1/3 as big.


Gamma Curve

This is the classic gamma curve edit found in Photoshop and many other image edit programs. The x-axis maps the input pixel brightness and the y-axis the output or adjusted pixel brightness. The straight line at 45 degrees is the neutral curve, mapping input brightness values to the same values for output brightness. The edited curve shown here will cause darker pixels to become darker, mid-range pixels to have an increased brightness range (more contrast), and the brightest pixels to become brighter. In effect, contrast is being removed from the darker and brighter image areas so that the mid-range areas can have more contrast. Moving the low end of the curve to the right will cause dark pixels to be clipped (made black), and moving the top end of the curve to the left will cause bright pixels to be clipped (made white).

Edit the ALL curve while watching the image for instant feedback. You can also select and modify individual RGB colors after finishing the ALL color. Editing the ALL curve forces the RGB curves to match the ALL curve, so do RGB curve adjustments after adjusting the ALL curve.


Expand Brightness

This function expands the brightness range of an image that does not utilize the full brightness range available, possibly making it look contrast-poor. You can see this in the brightness distribution graph. If the distribution shows little or no area at the extreme low and high ends of the horizontal scale, the image may benefit from expanding the brightness range. This means that the darkest pixels are made darker and/or the brightest pixels are made brighter. Move the sliders to extend the brightness range and observe the image.


Flatten Brightness

This is a fast and easy way to compensate for a common limitation in photos: there is not enough range in the brightness to show good detail in all areas. This function finds where there are too many pixels with nearly the same brightness and spreads them apart, compressing other areas to make room. Technically, the brightness distribution is made more uniform (flatter). Move the slider and watch the image, which may lag a moment. Some images will show good results, others may not be helped or even become worse. Using this function within a selected area is often very effective. Edge blending may be needed to make the boundary invisible.


Brightness Ramp

This function varies the brightness across an image, with the direction and magnitude of the brightness slope determined by editable curves. You can use this to compensate for uneven lighting or vignetting (darker image corners). The function dialog displays two editable curves, horizontal and vertical. The horizontal curve adjusts brightness horizontally, and the vertical curve adjusts brightness vertically. Move the curves in the directions labeled "+" and "‒" to increase or decrease the image brightness in the corresponding image area. To remove vignetting in the image corners, move both ends of both curves in the "+" direction while fixing the middle areas or even moving them in the "‒" direction. To brighten the upper right corner, move the right end of the horizontal curve and the upper end of the vertical curve in the "+" direction, as in the example above. If used with a selected area, the scales refer to the enclosing rectangle of the area instead of the whole image. Thus you can select an area of an image and apply a brightness ramp across the area. If the button "all" is selected (default) then all colors are adjusted equally (i.e. brightness is adjusted). If one of the colors is selected, the image is adjusted for that color only, and the "all" curve is ignored. Any or all three RGB colors may be adjusted in this manner. You can use this to remove a color-caste that varies across an image or image area.


Tone Mapping

Tone mapping increases the apparent brightness range of an image by increasing local contrast. It is especially useful to improve HDR images, but can also be applied to any image. HDR images often seem "flat" because the contrast between nearby pixels has been reduced to make the overall contrast fit within the available range. Tone Mapping increases the contrast between nearby pixels without increasing the overall contrast. It relies on the nature of human vision: contrast within a small angle is perceived more strongly than contrast over a large angle. Tone mapping also brings out subtle details (low contrast) that would otherwise be hard to notice.

Other methods can also be used: adjusting the brightness curve can increase contrast for a selected brightness range (possibly at the expense of others). Flattening the brightness distribution can spread the available contrast (brightness range) more evenly. Increasing color saturation can also bring out more detail. These methods operate globally: all pixels of a given color and brightness are processed the same. Tone mapping processes pixels differently depending on the brightness of surrounding pixels and is more effective at enhancing detail and the perceived brightness range.

In the dialog, the graphic curve determines how much local contrast is increased depending on initial local contrast. The left end of the x-axis corresponds to low-contrast pixels and the right end high-contrast pixels. Raise the left side of the curve to increase the contrast of low-contrast pixels (but this will also enhance low-level noise). The Amplify slider below the curve regulates the internal algorithmic calculation, from no contrast amplification on the left to full amplification on the right. If moved too far to the right, the image may show artifacts (bright or dark "rays"), so push it back until these disappear.

The curve can be dragged with the mouse and its effect on the image will show up in a few seconds (depending on image size and CPU speed). The amplify slider also needs a few seconds to show up in the image. If more contrast is wanted, raise the curve. If uniform areas (e.g. sky) become mottled, pull the left end of the curve down to reduce amplification for low-contrast pixels. In some cases it will be best to select different areas of the image and process them separately, e.g. more conservative for sky, more aggressive for textured surfaces like stone walls.


White Balance


This function is an easy way to remove a false color-cast, e.g. the whole image has an overall blue or red tinge. After strarting the function, click somewhere on the image that should have no color - a white or gray area. If that location has any color other than white or gray, it will be used as a measure of overall false color, and this amount of color will be removed from the whole image. You can click around on various areas and see the impact instantly. Press the [done] button when you are satisfied, or [cancel] if not.


Match Colors

This function matches the colors in one image to those in another. A small spot, determined from a mouse click, is sampled from each image. The spot on the 2nd image will be made to have the same average color (RGB values) as the spot from the 1st image. The factors used to make the RGB values the same are then applied to all the pixels in the 2nd image. The most common use is to remove a color-cast from an image by marking a spot on the image that should have a given color which is taken from another image.

Procedure: The dialog lists 5 steps to take in sequence. (1) Set a radius for the spot sample. The mouse cursor will have a circle of this radius which is the spot area that will be sampled. (2) Open the 1st image (press the [open] button for a file open dialog). If the current image is already the one you want, this step can be skipped. (3) Click on the image to take a color sample from the spot area enclosed by the mouse circle. You can change the radius and click again if wanted. (4) Open the 2nd image by pressing the [open] button. (5) Click on the image at the spot you want to match the spot color from the 1st image. The image colors will change within a second or two. You can change the radius and click on another spot if wanted, and the colors will change accordingly. Click the dialog [done] or [cancel] button to finish.


DRGB

This function is used to change overall brightness or selected colors using OD (optical density) units. The input values range from -99 to +99 which represent -0.99 to +0.99 OD.  OD is a logarithmic scale where -1 is a 10x increase and +1 is a 10x decrease in brightness. The input steps (0.01 OD) make a 2.3% change in brightness, which is barely visible with undo/redo and not visible with a side-by-side comparison. The contrast buttons change contrast by 0.01 OD per step, meaning that the brightest and darkest pixels are changed by 0.01 OD in opposite directions, with intermediate pixels changed proportionally.

DRGB is the tool for converting color space between monitor and printer. Print a standard color chart, use DRGB to adjust the Fotoxx image and print again until the printout is good. Save the settings (color offsets) and use them to print subsequent images with correct color the first time. The settings will be different for different printers and paper types. Use [save] to save the settings to a file, and use [open] to load the settings from a saved file.


Revise RGB

This function can be used to make complex color corrections, whereby different parts of the image need different corrections. Select up to 9 control points on the image by clicking them with the mouse. The points are added to the list in the dialog window, with the most recent point at the top. The points are labeled A-I in the list and on the image window. The current RGB values are shown (or EV or OD units if selected). Change the RGB/EV/OD values in the dialog, and the image will be changed to match. Each pixel in the image is influenced by all the control points in the dialog, with the closer control points having more influence than those farther away. The slider Soften Peaks determines how widely the control points spread their influence. If "delta" is checked, the values shown are the deltas (differences) from the original image.


Remove Red Eye

This function reduces the red-eye effect from electronic flash photos. Two methods are provided. The first is faster but will not handle difficult cases (e.g. the eyelids are almost as red as the eye). The second method is more robust but also needs more time and care.

To use the first function, left-click on a red-eye one or more times until satisfied. If the darkened area is too small or off-center, do a right-click to undo the change and then left-click more precisely on the center of the red-eye. If a red-eye cannot be fixed correctly, right-click to undo the change and then use the second method.

The second method can better handle difficult cases where the red-eye is only slightly red and the color difference with the eyelids is too little for the automatic algorithm to distinguish. Place the cursor over the center of the red eye. Hold the left mouse button and drag the cursor down and to the right. A dotted ellipse will appear enclosing the red eye. Repeat if needed to get the red eye centered in the ellipse (roughly). Note that the shape of the ellipse depends on the direction of the drag, which can allow more precise enclosure of only the red-eye. Left-click inside the ellipse repeatedly while watching the red eye darken, and stop when it is dark enough. If you go too far, the eyelids may start to darken. Right-click to undo and repeat if necessary.


Blur image

This function can be used to blur or un-sharpen an image. Each pixel is mixed with neighboring pixels to reduce the differences, making edges fuzzy. Enter a value for blur radius and press [apply] to see the results. A small value mixes each pixel with its nearest neighbors and larger values mix more distant pixels. The contribution from each pixel decreases with distance, so the nearest pixels have the greatest contribution. This function is useful to smooth mottled skin tones. You can use "select area" to limit the blur to a face or part of a face. This is also a way to cure "banding" in sky areas (this can happen if the flatten, brightness, or tone mapping functions cause the distribution to spread out, making the brightness steps perceptible).


Sharpen Image


This function sharpens a blurry image. Three methods are implemented: edge detection, unsharp mask, and gradient. Edge detection: find adjacent pixels with the largest brightness difference (contrast) and increase the difference. This is repeated for several cycles, with the threshold for brightness difference decreased each cycle. Unsharp mask: a fast and effective method also found in Gimp and other tools. A technical description can be found via Google. Gradient: pixels are processed left to right and top to bottom. The brightness difference (contrast) between each pixel and its prior neighbors (left and above) is increased, and the pixel brightness is modified to match. This brightness change is propagated to the next pixel where the process is repeated.

The edge detection method gives sharper edges where the contrast is high and softer edges elsewhere, making it good for portraits (sharp eyes, smooth skin). For images that are partly sharp and partly blurred (e.g. depth of field or motion problem), the edge detection method primarily affects the blurry areas, whereas unsharp mask may put "halos" around edges that are already sharp. The gradient method works about as well as unsharp mask for slightly blurry images. The radius value limits the distance over which pixels around an edge are changed. It should be small for images that are slightly fuzzy and larger for poorer images. Threshold suppresses changes to low-contrast pixels: a higher values reduces the amplification of low-level irregularities.

For the edge detection method, enter the following parameters:
   cycles         number of iterations
   reduce        brightness reduction threshold per cycle, 80 means 0.80
   threshold    brightness change low cutoff threshold

For the unsharp mask method, enter the following parameters:
   radius          distance pixels around an edge are changed
   amount        amount of correction, 100 = normal
   threshold     brightness change low cutoff threshold

For the gradient method, enter the following parameters:
   amount        amount of correction, 100 = normal
   threshold     brightness change low cutoff threshold

Press the button for the method selected and wait a few seconds to see the result. The default values are suggested starting points. Make changes and repeat the process until satisfied. You can go back and forth among the methods to compare which is best for a given image. Use Select Area to operate on different parts of the image with different methods and parameters.


Reduce Noise

This function reduces the noise present in photos taken under poor lighting conditions, making uniform surfaces appear speckled. Choose one of the methods described below. Press the [reduce] button repeatedly while watching the image. If you go too far, sharpness and detail will be lost. The radius input determines the area around each pixel that is compared. A default radius is set when a method is selected, but other values may work better. For a large image, these algorithms may run a long time. To save time, select a small area and experiment with the different methods and radius settings until you make a decision, then clear the selected area and apply the chosen method to the whole image. There are four different methods, and each method applies to each RGB color independently.
  Flatten outliers (1) The highest and lowest pixel values within a radius are moderated slightly.
  Flatten outliers (2) Pixels are compared to the mean and sigma of pixels within a radius. Those outside one sigma are moved back toward the mean.
  Median brightness
Pixels are set to the median value of their neighbors within a radius.
  Top hat Detect outliers by comparison with a band of pixels at a distance. The distance is increased in steps from 1 pixel to the radius limit.


Smart Erase

This function can be used to erase small objects that can spoil a good photo, such as power lines, trash on the ground, a sign, etc. The unwanted object is replaced with pixels taken from the surrounding area. This is sometimes very effective (side-effects almost invisible), and sometimes not. It works best for small or narrow objects in the photo (e.g. <20 pixels wide). Radius controls the size of a circle around the mouse pointer, defining the area to select and erase. Drag the mouse to enclose all or part of the object to be removed. Left-drag selects and right-drag un-selects. Press [Erase] to erase the selected area, replacing the pixels with the nearest pixels from outside the selection. If the selection was not precise enough, use [Undo], adjust the selected area, and [Erase] again. Repeated selections and erasures will accumulate until you use [New_Area] to start a new selection. The prior erased areas are now fixed and [Undo] will only work for the current selection. As with all edit functions, the toolbar buttons [Undo] and [Redo] can be used to review all changes. It is likely best to work with an image zoomed to 200% or more. The Blur control adds blur to the replacement pixels. This can reduce visible side-effects, since the replacement pixels may be sharper or have more contrast than the surroundings. Change the Blur setting and repeat the [Erase] button. A blur of 0.5 or 1 pixel is usually effective.


Remove Dust

Images made from dusty scanned slides can have many small dark spots - shadows of the dust on the slides. This function can be used to remove the majority of such spots. Move the three sliders until the maximum number of dust spots are painted red, then press the [erase] button to erase them. Press [red] to bring back the red view, then you can adjust the sliders again and press [erase]. The "spot size limit" slider limits the size of the spots that will be erased. The "max. brightness" slider sets a theshhold for ignoring spots that are not dark enough. The "min. contrast" slider screens out spots having low contrast with their surroundings. This process is usually a compromise. If the settings are not optimal, small features like tree leaves can be erased, or large spots may be left in place. Different parts of the image may need different settings, e.g. sky can be treated more aggressively than a building wall. You can simply use Erase Dust multiple times with different settings as needed to get all the dust spots. Or you can use select area to process the image in sections. If some spots are persistent, you can treat them manually with Smart Erase: set a small mouse radius and click on each spot to remove it. Spots from fibers (long and thin) are usually not removed automatically, but Smart Erase can be effective here.


Fix Stuck Pixels (always bright or dark)

Camera sensors may have defects causing isolated pixels to be always bright or always dark. This may be one RGB color or all of them. I have seen a case where a group of 3x3 pixels was always too red. This function can find such pixels in an image and repair them by substituting neighboring pixels.

Select the defect sizes to search for: 1 pixel, 4 pixels in a 2x2 block, or 9 pixels in a 3x3 block. The defects found are surrounded by small circles which you can toggle between write, black and red. Zoom-in to inspect these and determine if they are real defects. Use the contrast control to precisely select the defects. If set too low, small high-contrast spots in the image may be erroneously selected. If set too high, real defects may be missed. Use the [apply] button to erase the defects in the current image. You can apply the function many times using different settings if needed. The currently shown (encircled) defective pixels can be saved to a file by using the [save] button. This file can be used later to fix the defects in any image made by the same camera: use the [open] button, select the saved defects file, then use the [apply] button to fix the current image. Using a saved defects file from one image to fix the defects in another image will only work if the two images have never been trimmed, or if exactly the same trim was applied to both images. This is necessary because the defective pixels in the two images must have the same locations. If more than one contrast setting or pixel group selection is needed to accurately find all the defects in one image, you can save the respective defect files and combine them manually into one file. Use any text editor for this. I suggest you make a test images to find defects: Make a photo of a paper sheet or blank wall that is underexpsed to come out gray. This image can be used to find both bright and dark stuck pixels.



Edit Pixels

This function changes individual pixels. There are three modes of operation: pick, paint, and erase. Pick mode: click anywhere on the image to set the current color. Paint mode: click or drag anywhere on the image to paint with the current color. Erase mode: click or drag anywhere on the image to restore modified pixels to their original color. The button [color] allows you to pick a color using a color wheel, and it always shows the current color. The "brush radius" control sets how large an area of pixels will be changed with each mouse click or drag. The "transparency" controls determine how intensely the color is applied at the center and edges of the brush. Zero transparency applies the full color immediately whereas a high transparency (90-99) applies a little color and allows you to gradually change the color using many clicks or drags (analogous to spray painting from a distance). Erase also works this way: use zero transparency to immediately erase, and high transparency to erase gradually. The [undo-last] button removes the last edit (modifications from the last click or drag operation), and this can be repeated to remove many recent edits. The memory for undo operations is limited to 200 megabytes, which can be reached if you make many edits using a large brush (every change to every pixel is saved). It is useful to save the image after each satisfactory change to free this memory. The amount of memory available is displayed in the dialog, so you can see when the limit is approaching. If a selected area is enabled, the painting is confined within the area. You can select an area by color and then change the color without taking care about the edges. NOTE: zoom the image to 100% or more when using this function. If the mouse steps are larger than the image pixels and a small brush is being used, some pixels may be skipped by the mouse and cannot be painted.



Art Menu


Color Depth

This function changes the normal 16 bits per RGB color (red, green, blue) to any value between 1 and 16 bits per color. At 8 bits per color, there are 16.8 million total color combinations. At 4 bits per color there are only 4096 total colors. Use 1-4 bits for an interesting "poster" effect.


Drawing

This function transforms a photo into a black and white high-contrast image or into a line drawing where only the edges of objects are shown as black lines on white background or white lines on black background. The sliding control "contrast" will deepen dark areas to black. The sliding control "threshold" will convert the image from gray-scale to black and white. The sliding control "outlines" will highlight high-contrast pixels (edges of objects) and suppress low-contrast pixels. This can be black on white or white on black, depending on the selection of the radio buttons "pencil" and "chalk". Manipulate both "threshold" and "outlines" to find the best balance.


Outlines
This function transforms a photo into a colorized line drawing showing outlines of objects within the image. Edges (sharp transitions in brightness or color) in the image are brightened, and the rest of the image is darkened. There are three sliding controls. Outline threshold: regulates how bright an edge must be in order to get enhanced, from "show no edges" at the low end to "show all edges" (even faint ones) at the high end. Outline width: the width of the enhanced edges, from 1-pixel to about 5 pixels. Image brightness: the brightness of the image itself, from dark (show only the outlines) to full brightness.


Embossing

This function transforms a photo into a simulated relief or embossed image. The "radius" setting determines the feature size or level of detail. The "depth" setting determines how deep the features go into the surface.


Tiles

This function transforms a photo into an array of large monocolor tiles. You can control the tile size and the thickness of the space between tiles (caulk, grout). This is also called "pixelate" or "pixelize". Use Select Area to confine the transform to a limited area, such as a face.


Dots
This function transforms a photo into a array of dots, like old-fashioned comic book pictures or Roy Lichtenstein paintings. The only control is the dot size. Also experiment with using color saturation, color depth, or other functions before using Dots.


Painting
This function transform a photo into something looking more like a painting. It reduces the number of colors, maps each contiguous pixel area having the same color, and then consolidates smaller areas into adjacent larger areas having the best color match. Four user settings control this process: "color depth" sets the number of colors to be used (bits per RGB color). 1 = 8 colors, 2 = 64 colors ... 5 = 32768 colors;  "target group area" sets a lower limit for areas that will have their own color: areas smaller than this number of pixels will be absorbed into an adjacent area with the nearest color match; "req. color match" sets the minimum color match required for a smaller area to be consolidated into an adjacent larger area: 0 = don't care (maximum consolidation), 100 = perfect match required (no consolidation); "borders" determines whether the colored areas will be delineated with a thin black border, like irregular tiles in a mosaic. After using this function, using the Embossing function can add interesting texture to the image.



Combine Menu


Make a High Dynamic Range Image
(HDR)
Combine (overlay) multiple images of the same subject with different exposure levels. The combined image can show improved visibility of detail in both the darker and brighter areas, in effect using pixels from the brighter images for the darker areas, and from the darker images for the brighter areas. Many digital cameras do exposure bracketing: take multiple shots in quick succession with different exposure levels. You can combine such images to make a better one. If the camera is adjusted manually between shots, take care to keep it level and aim at the same distant point. Some misalignment of the two images can be tolerated. If things move between shots, fuzziness and ghosting cannot be avoided.

Select the HDR menu function. A file open dialog is started to select up to 9 image files, which must all have nearly the same pixel dimensions. The images are aligned and combined automatically, which may need a minute or more. When done, the combined image is shown, along with a dialog for manual adjustments. The contributions from the input images are shown as a series of editable curves. The horizontal scale represents pixel brightness, from dark to bright white. Each curve represents an image which contributes to the pixels. The image contribution at a given brightness level is proportional to the height of its curve at that level. The initial curve for the brightest image will be high on the left and low on the right, meaning a high contribution to dark pixels and a low contribution to bright pixels. The darkest image will be low on the left and high on the right, and the remaining images will be in-between. The curves can be edited by dragging them with the mouse. The anchor points (small squares on a curve) can be pulled around while others remain fixed. The corresponding image contributions are changed accordingly, and you can see the results in quasi-real-time in the output image. Right-click on an anchor point to remove it. In general, the brightest image should have a higher contribution to the darker pixels, and the darkest image a higher contribution to the brighter pixels. You will likely need practice to become effective at working the curves.

A faster and easier alternative may work as well: after the images are combined, ignore the curves and exit from HDR. Use various edit functions to refine the image: Flatten, Expand Brightness, Brightness/Color, and Tone Mapping. Select Area can be used to enclose any area in the image which needs more brightness, color, or local contrast, so you can apply different methods and parameters to different areas.


Make a High Depth of Field Image (HDF)
Combine (overlay) multiple photos of the same subject with different focus settings from near to far. Different parts of the subject are in sharp focus in each image. Combine the images so that all parts of the subject are sharp. This technique is most useful for extreme close-ups.

Making the photos: choose a point for the center of the image. Aim the camera at a near object and depress the shutter button 1/2 way to set the focus on this object. Hold the button at the 1/2 position, aim the camera at the chosen center, and snap the photo. Now choose a farther object and do the same. Repeat with increasing focus distance. Hopefully each part of the subject is sharp in at least one photo. The camera position should be very nearly the same for all photos, which can be a challenge when the subject is very close. Camera movement can cause scaling and parallax problems (nearer objects shifted against farther objects). Such problems may be fixable later in Fotoxx, but this may require considerable time. It is better to avoid the problems.

Processing the photos: in Fotoxx, choose the HDF menu function and select up to 9 images. The images will now be aligned as well as possible. This may take a minute or more per image, depending on image size and CPU speed. The output image is an even mix of the aligned input images. A small amount of camera movement between the photos is compensated, but this is limited, and parallax shifts are not compensated at all. When the alignment is complete, a dialog opens. You can select any input image and "paint" with the mouse on any area of the output image. This converts the original image mix to the selected image for the area being painted. For each area or object in the image, choose an input image that is sharp in that area. The radius of the paintbrush can set larger or smaller, so you can paint large areas quickly and control fine detail when needed. If you have overlapping near and far objects, time and patience will be needed to make all of them sharp.

Misalignments can be corrected by selecting the "warp" option in the dialog. The underlying images can then be dragged and warped with the mouse, and the composite output image is changed accordingly. The warp is limited to the area around the mouse. When a painted area is dragged, the corresponding image is automatically selected and dragged, while areas painted with other images remain fixed. Areas that have not been painted cannot be dragged. Move around to different areas and make incremental drags until all areas are aligned.
 
Suggested Workflow:
Using paint mode, choose each image in sequence and paint all areas that look sharp with that image. Any boundaries that are not well-aligned will show up clearly as shifts in the edges of objects in the image. Some of these can be made unimportant by changing the image used for painting (if more than one image is sharp enough). Using warp mode, make fine adjustments as needed to eliminate visible shifts.


Stack / Paint

Combine (overlay) multiple photos of the same subject taken at different times. Remove tourists and cars that come and go between shots by painting them away with the mouse.

Making the photos: aim the camera at the same distant point and take multiple photos as tourists or cars move in front of the subject. Try to get at least one photo with each part of the subject not obscured by the moving objects.

Processing the photos: in Fotoxx, choose the Stack / Paint menu function and select up to 9 images. The images will now be aligned as well as possible. This may take a minute or more per image, depending on image size and CPU speed. The output image is an even mix of the aligned input images. When the alignment is complete, a dialog opens. You can select any input image and "paint" with the mouse on any area of the output image. This converts the original image mix to the selected image for the area being painted. For each area in the image, choose an input image that is free from the moving objects. The radius of the paintbrush can set larger or smaller, so you can paint large areas quickly and control fine detail when needed.


Stack / Noise
This function combines 2-9 images (photos) of the same subject. The photos should be nearly the same, except for small offsets caused by a hand-held camera. If the photos were made with a very high ISO setting (low light conditions), the pixels will have considerable noise. By making many photos and averaging them, the noise can be mostly eliminated.

Making the photos: choose a point for the center of the image. Take several photos using the same center and being careful not to shift or rotate the camera too much. The more photos the better. Up to nine can be used with Fotoxx, but you can take more in order to have some to discard if they are not sharp, a common problem with low light conditions and long exposure times. In Fotoxx, chose the Stack / Noise function and select up to nine image files. They will be combined automatically and shown, and then a dialog will open. The initial output image is a combination of all the selected input images, averaged together. This means that the RGB values for each output pixel are the average of the RGB values for the corresponding input pixels. A few alternative tools can be used to possibly reduce the remaining noise a little more. The "use median" button will change the output pixels from an average of the input pixels to the median of the input pixels (1-3 "middle" RGB values are averaged, depending on the number of images). This may or may not be better, so switch back and forth to compare (the screen update may need several seconds). The checkboxes for "omit low pixel" and "omit high pixel" will cause the lowest and highest RGB input values to be discarded before the average is calculated. This may help to get noise spikes removed from the mix. This has no effect if the median method is selected.


Make a Panorama Image

This function stitches 2-4 images together to make a wide image or panorama. The images must overlap by 15% or more, so that the program can find where they coincide and put them together.

Using the panorama menu function, select 2-4 image files. The images are initially joined and shown with a small transparent overlap. A pre-align dialog asks you to drag the images into rough alignment. Drag the images into the correct left to right order. The image to drag may overlap other images. To be clear about which image is being dragged, drag from near the center of the image. After the images are in the correct order, align each image to its left neighbor. It works best to proceed from left to right. Move an image horizontally and vertically into rough alignment with its neighbor to the left, then rotate the image if needed by dragging its bottom edge left or right. The image pivots around the mid-point of its overlap with the image to the left. The fastest method is to align the overlap middle region first, then rotate the right image if needed to bring the upper and lower overlap regions into alignment. Extreme accuracy is not needed. Use the [resize] button to get a bigger combined image after moving them closer together.

The images should be correctly curved and fit together well. If they do not, then the lens mm parameter (focal length, 35mm equivalent) needs adjustment. The curvature of the images changes as lens mm is adjusted. The initial value is obtained from the EXIF data if available, and this is normally good enough. The lens bow parameter (barrel or pincushion distortion) is not available in EXIF and must be adjusted manually, but this is often insignificant and can be left at zero. You can measure and set the lens parameters manually as described below.

If an image was trimmed so that the greater dimension (width or height) was reduced, then the EXIF focal length is no longer valid, and the EXIF initial value may not work well. A section of an image taken from the middle has an effective focal length greater than the original. Use the pre-align dialog to increase the lens mm parameter until the images fit together reasonably well.

Press [proceed] when pre-alignment is finished, and the program will do fine alignment and join the images. Internally, the images are shifted and rotated and the degree of match is evaluated. This is done with increasing image sizes until the best match is found within a fraction of a pixel. This may take from 10 seconds to a minute or more per image, depending on CPU speed and image size.


When fine alignment is complete, the combined image is displayed. A dialog pops up for fine adjustment of brightness and color match. You may see a sharp border between images if the images do not have the same brightness and color balance. The [auto color] button can be used to perform an automatic color match, which is often satisfactory by itself. The other controls allow you to make additional changes to better match the images. Select one of the images with the radio buttons at the top, change the values for brightness and color, and press the [apply] button to see the results. Use [auto color] to match the other images to the one changed. Use [file color] to restore the original values from the input images. The "blend width" input governs how the images are blended together: at the image joints, the color balance is gradually shifted over this many pixels, to mask imbalances that cannot be fully corrected. The default is 1 pixel, which makes any brightness or color differences look obvious.

When done, you can use unbend, warp, rotate, trim, and other functions for final adjustments. Use the auto-trim function at the end to automatically get rid of any leftover black margins.


Vertical Panorama
This function works the same as horizontal panorama, except that the images are arranged vertically. To change the order of the images, drag them from near their centers. To rotate an image, drag the right edge up or down. It is best to align from the top down.

Scanned Images
Scanned images can be combined if there is enough overlap. Set the lens mm parameter to the maximum value (999 mm), since there is no curvature in scanned images.

Panorama Limitations
Panoramas including nearby objects can be tricky: when the photos are made, be careful to turn the camera on an axis through the lens, with minimum lateral movement, otherwise the images may align poorly due to shifting foreground objects (parallax). This is not an issue when the subject is 50+ meters away, since a small lateral movement has little impact on the image.

Setting Lens Parameters Automatically

The [search] button in the panorama pre-alignment dialog initiates an automated search for optimum lens parameters. Use a suitable image pair: the subject is 50+ meters away, the images have a low horizon difference and little relative rotation, and there is plenty of high-contrast detail in the overlap area. Input your nominal lens focal length for lens_mm. Use zero for lens_bow. After doing a decent pre-align, press the [search] button and wait a while for the results. Do this a second time and observe the changes. If the values remain consistent, you can use them for your panoramas. The search function steps through a range of values for lens_mm, lens_bow, and the image alignment offsets for x, y, and theta. It searches for the lens values that give the best alignment results for the given images. The process needs a minute or more, but you only need to do this once to characterize a given camera lens. Be sure to save the results using the Tools > Settings menu.

Setting Lens Parameters Manually
Make a panorama image of a brick wall (or any wall with lots of detail) with about 40% image overlap. The wall should be 5+ meters away. Within the panorama pre-align process, adjust lens_mm and lens_bow until the overlapping bricks coincide. When making the two images, be sure to turn the camera on a vertical axis through the lens, minimizing lateral movement and rotation in other axes - otherwise the images may fit poorly and your lens parameters may not be optimal. The result should roughly correspond to the nominal focal length of your lens (35mm equivalent). It may be off somewhat (my 27mm lens works best with a lens_mm setting of 29-30mm). I speculate that this is because wide-field camera lenses are not ideal lenses (pinhole equivalent). Most panoramas will still work OK even if the lens_mm setting is off by 10%.




Plugins Menu

Other image edit programs (e.g. Gimp) can be added to this menu. They will then work like any other edit function in Fotoxx. After using one of these external programs to modify an image, you can use the Fotoxx [Undo] and [Redo] buttons to check the results, perform additional edits with Fotoxx, or use [Save] or [Save+F] to save the edited image. The image passed by Fotoxx to the external program is a TIFF file with 16 bits per color. Most programs can read this but may use only 8 bits. When finished using the external editor, save the image back to itself ("save" menu) and exit the program. Fotoxx will then pick up the revised file and use it as though the edit had been done in Fotoxx.

To add a new plugin, use the function Plugins > Edit Plugins. Input a menu name (e.g. "Gimp"), a command to start the program (e.g. "gimp") and press the [Add] button. You can also remove a plugin by selecting it from the list and pressing the [Remove] button. The Plugins menu will not be updated until the next time Fotoxx is started.

The plugins are saved in a file: /home/<user>/.fotoxx/plugins which you can manipulate with a text editor if desired. This is the only way to change the sequence of the menu entries. Be careful not to screw up the format: menu = command (with exactly one space before and after the '=' character).




Help Menu


About

This displays a short message about the Fotoxx version number, license, credits, and contact address.

User Guide
The user guide (this document) is displayed (created using the WYSIWYG HTML editor KompoZer).

User Guide Changes
This is a summary of changes in the User Guide for the most recent versions. The intent is to enable you to survey the changes without reading the whole document.

Edit Functions Summary
A one-page "quick reference" summary of the image edit functions is displayed.

README
Displays the README file distributed with Fotoxx, which may contain new information about installation or dependencies. When you install a new release of Fotoxx, you should look at README and the Change Log to check if there is anything special you need to be aware of.

Change Log
Displays the change log file distributed with Fotoxx, containing details about functional changes, additions, or bug fixes for the current and previous releases.

Translate
Displays a short text file which explains how to make a new translation or change an existing one. This involves editing a text file that contains English text messages with their corresponding translations (see technical notes, below).

Home Page
Shows the Fotoxx home page from the Internet. Look here for program updates (the page named "recent changes"). This page is published via RSS and you can subscribe to get timely notification of changes.




Organizing a Large Image Collection for Searching

Fotoxx can edit and search for the following image attributes: photo date, "star" rating, tags, file names, and words appearing in captions or comments. These are explained in the Info section of the user guide. The image search function is also explained there. The following is an attempt to give an overview of the options and tradeoffs.

Physical organization - directory and file names: these names can be used as a basic organization that will enable you to find images even if more elaborate organizations (tags, collections, captions) are not used. The physical organization should be by time (not event or place or person ...). I suggest using one directory per year named 2001, 2002, etc. This will also help to keep any one directory from becoming excessively large. The image files may further be organized in time sequence by using MM.DD as the start of the file name. The rest of the file name can be an event or place name, and a sequence number.
    Example: /top-directory/2011/08.20 Spitzbergen 23
This very basic organization allows Fotoxx to find files by searching file names. In the above example, a search for "spitzbergen" or even "spitz" will produce all the images of Spitzbergen. The batch rename function in Fotoxx (File > Batch rename Files) lets you rename a whole batch of camera files taken on one day at one location or event by selecting the files and inputting a template name like "08.20 Spitzbergen". The sequence numbers are automatic.

Captions: A simple method of organization is to use captions and comments (Info > Edit Captions/Comments). These are arbitrary text strings that can be added to images in rapid sequence:
   input some text, press [next], input some text, press [next] ... 
Captions and comments are two separate inputs but treated logically the same. They are searchable: words appearing in captions and comments can be searched for. You can add the names of persons or other information to each image, and then find them again quickly. With this method, you can search images using a combination of dates, file names, and any words appearing in captions or comments. Dates are taken from the EXIF data in the camera file. This presumes the camera clock was set correctly when the photos were made. If not, dates can be edited using the Info > Edit Tags function.

Collections: Another simple method of organization is to use named collections. Choose a name for each collection and assign any desired images to the collection, using basically two clicks per image (plus the time to find the images to add). This method is independent of tags, captions, file names, etc. See Tools > Manage Collections. Callections can be selected by name and viewed directly as a gallery of thumbnails or sequentially in the main window.

Tags: The most powerful tool is tags, but this is also the most demanding of organizational care. You can go through your images sequentially and add tags by clicking on a list of defined tags. New tags can be defined as needed. Images can have many tags, and can be searched for AND/OR combinations of tags (along with date, star rating, file name, caption, comments). Tagging is the fastest way to classify a large collection, needing a few seconds per image. The hitch is the tagging system. You need to lay this out in advance and stick to it, otherwise things can get chaotic. If you end up with 1000 tags they will not be very useful. If the images are physically organized by time, then groups of images will tend to have the same tags, which makes the process of adding tags faster.




User Guide Changes

This section is provided to help you quickly review the changes without reading the whole manual. This also helps translators to find the topics needing revision.

v.12.01
  • The introductory sections were rearranged and revised for functionality changes.
  • The paragraph about "my mouse" was replaced with "mouse ownership" and references to "my mouse" elsewhere were removed. My mouse is dead.
  • Select Area introduction - new paragraph about "layers" and "areas".
  • New topic: Search Metadata
  • Revised topic: Search Images
  • New Technical Notes: Preview Mode, File Size, Search Image Benchmarks.
  • Technical Note deleted: Missing Toolbar Button Text (see Tools > User Settings).
  • Technical Note deleted: How to get a traceback dump. This is now automatic.
  • Technical Note: Translations: file name for language xx changed to fotoxx-xx.po.
  • Lens Parameters topic was removed from Tools menu and added to Panorama topic. 
  • Toolbar Style topic was removed from Tools menu and added to the User Settings topic.
  • User Settings menu and topic was added to the Tools menu.
  • New Technical Note: Ubuntu Unity Launcher (drop-down menu with options).
  • Technical Note revised: The option -blank was added to Command Line Options.
v.11.12
v.11.11
v.11.10
  • Getting Started: Installation and Initialization changes for Synchronize Files.
  • Save Image File: new functionality to warn about overwriting an original file.
  • Print Image File: revised to match revised functionality.
  • Slide Show: new option to show only the latest version of each image file.
  • Gamma Curve: new topic, added after Brightness/Color.
  • Straighten Image: new topic, added after Unbend Image.
  • Slide Show: a sentence was added to explain pause/resume via spacebar.
v.11.09
  • The two menus Edit Caption and Edit Comments were combined.
  • The menu and topic Open RAW File was eliminated and Open Image File was revised.
    (open Image File can be used to open a single RAW file).
  • A paragraph about scanned images was added to the panorama topic.
  • The topic Print Image File was revised for the addition of print margins.
v.11.08
  • Getting Started: the paragraph Fotoxx Startup was added.
  • General Editing Procedure: expanded for clarity.
  • Select Area: "Delete" was changed to "Unselect" in several places
    (some people thought it meant deleting a part of the image).
  • "Whole Image" was changed to "Select Whole Image" in several places.
  • The new topic DRGB was added after Expand Brightness.
  • Revise RGB: A sentence was added for the new "delta" mode.
  • Show RGB: minor errors corrected.
v.11.07
  • Brightness/Color: explain the graph range and the step size for the buttons.
  • Match Colors: new topic for new function.
  • Save Image File: A new paragraph was added for Save to New Version.
  • Show RGB: expanded to explain the EV and OD units.
  • The Clone topic was expanded to cover the new function Clone Overlay.
  • Open Image File topic was expanded to cover "Open in New Window".
  • Toolbar Buttons (table): updated to: Save / Save+V / Save+F.
  • The Brightness Ramp topic was expanded to explain the new RGB buttons.
  • Keyboard Shortcuts (table): added entry "Control + v or V".
  • Toolbar Buttons (table): Undo and Redo text revised for shift key.
  • Replaced "Tools > Rebuild Search Index" with "Tools > Synchronize Files".
  • The Select Area topic was revised to improve clarity.
  • Select Area topic: an explanation for the unfinish button was added.
  • The new topic Revise RGB was added.
  • The topic Save to New File was revised to reflect changed functionality.
  • Technical Notes: command line options: add entry for -recent



Technical Notes

Translations

See the menu  Help > Translations  or the text file translations for guidance on how to modify an existing translation or make a new one. This is a fairly simple process: edit a text file with English text strings followed by their corresponding translations. See one of the existing translations as an example, e.g. /usr/share/fotoxx/locales/fotoxx-de.po (the German translation). A new translation for language code xx would be saved at /usr/share/fotoxx/locales/fotoxx-xx.po. After making such a file, you can test it by starting Fotoxx on the command line: $ fotoxx -lang xx.

Hardware and Software Requirements
Fotoxx works best on a fast computer with at least a gigabyte of memory. Multiple CPU cores are utilized for compute intensive functions (e.g. sharpen, rotate, warp, tone mapping, HDR, panorama). Slower computers (notebooks) will work, but will be quite slow for some functions. Monitors smaller than 1200x800 will feel confining for some functions. The typical notebook screen with limited brightness and color should NOT be used for image retouching.

Programs Required by Fotoxx

Fotoxx requires the following libraries and programs to function at run time:
   libtiff4 read and write tiff files, 8 and 16 bits per color
   xdg-utils open text or html files with user's preferred application
   exiftool
read and write image metadata (tags, comments, etc.)
   ufraw-batch 
import raw image files from a digital camera
   brasero burn a CD or DVD with selected images

Packages Required for Fotoxx Source Build

See the README file for instructions on compiling Fotoxx from source.
In addition to the programs listed above, the following are also needed:
   g++
GNU C++ compiler
   libgtk2.0-dev 
Gnome GTK/GDK/Pixbuf/etc. development files
   libtiff4-dev tiff library development files
Note: package names and exactly which files are included in each package are decisions made by each Linux distro. The above names are valid for Debian-based distros (including Ubuntu). For other distros you may have to dig to find the right packages to install.

Command Line Options

   -v
output version and build date and exit
    /.../imagefile.jpg
initial image directory or image file to open
   -recent  (or -r)
show a gallery of recent files, most recent at the top
   -prev  (or -p)
show the last file viewed in the previous session
   -blank (or -b)
show a blank window
   -lang lc_RC language code (+ opt. region code) to use for GUI (de, de_AT, fr ...)
   -slideshow /.../image1.jpg
    [ -music /.../playlist.pls ]
start a slide show using image1 and following images
optional music playlist for slide show

   -translate (or -t)
start in online translation mode (to capture the initial menus)

Status Bar Information

Example:  CPU 123%  1234x987x8  0.45MB  56%  edits: 3   menu locked   area active   dialog open
   CPU 123%
current Fotoxx process CPU loading for all threads
   1234x987x8 
image width x height x depth (bits per color)
   0.45MB image file size (updated when a modified image is saved)
   56% zoom status, image % size
   edits: 3
3 edits have been made and can be reversed with the [undo] button
   menu locked  
an edit function is active; other edit functions are blocked
   file sync busy
synchronize files operation is running; image edit functions are blocked
   area active  
a select area is present and enabled - edits are confined within the area
   dialog open
a dialog for user input is open and waiting

Ubuntu Unity Launcher
The following launcher will have a right-click dropdown menu with three different startup options: blank window, last image viewed, and a gallery of up to 100 recent images that can be selected. Save the following text as a file named fotoxx.desktop, make it executable, and drag the file to the Unity left side launcher list.
[Desktop Entry]
Name=fotoxx
GenericName=Photo Editor
Comment=Edit photos and manage collections
Categories=Photography;
Type=Application
Terminal=false
MimeType=image/bmp;image/gif;image/tiff;image/jpeg;image/png;
Exec=/usr/bin/fotoxx
Icon=/usr/share/fotoxx/icons/fotoxx.png
X-Ayatana-Desktop-Shortcuts=blank window;last image;recent images

[blank window Shortcut Group]
Name=blank window
Exec=fotoxx -blank
TargetEnvironment=Unity

[last image Shortcut Group]
Name=last image
Exec=fotoxx -prev
TargetEnvironment=Unity

[recent images Shortcut Group]
Name=recent images
Exec=fotoxx -recent
TargetEnvironment=Unity

File Types Supported
Fotoxx uses two libraries to support reading and writing of image files: the GDK pixbuf library and libtiff. Pixbuf supports JPEG, PNG, ICO and BMP files, with 3 RGB colors and 8 bits per color. Libtiff supports TIFF files with 1-bit depth (black/white), 8-bit and 16-bit grayscale, and 3 RGB colors with 8 or 16 bits per color. Other TIFF formats are not supported by Fotoxx, although they could be added if there is a need. Black/white and grayscale images are treated as RGB inside Fotoxx, with all RGB colors having the same value (shades of gray). Fotoxx converts camera RAW files to TIFF RGB with 16 bits per color, using the program ufraw-batch.

Color Depth
8-bit color (256 brightness levels), as supported by JPEG files, is the norm for image files and is usually adequate. LCD monitors are limited to 8-bits, and the effective brightness range for photo paper is less than 8 bits. One brightness step (averaging 1/256 or 0.4% over the gamma range) is very hard to see. 16-bit color can be useful if a narrow brightness range within an image has been greatly expanded (via various retouching functions). This expansion can lead to visible "banding" or "picket fence distribution". If the image was converted from RAW to 16-bit tiff before editing, this problem can be reduced, even when the image is converted back to 8 bits for storage.

Alignment Algorithm (HDR, HDF, Stack, Panorama)
Relatively few high-contrast or "edge" pixels are selected to control alignment in HDR, HDF, Stack and Panorama. The actual pixels used are shown in red during the alignment process, which is also entertaining. Each image in succession is systematically warped various small amounts and the fit with the previous or adjoining image is tested. This is done because two photos made with slightly different horizons or rotations will not fit perfectly with simple translation and rotation. Also the cylindrical image projection used for panoramas is only an approximation of what the camera lens actually does.

Tone Mapping Algorithm
The method used by Fotoxx is home-made, but inspired by Fattal and other gradient-based methods. It is not as effective as fattal in some cases, but close. On the other hand, Fotoxx is both fast and simple.

Alpha Channels
Images having alpha channels (transparency information) can be edited, but the alpha channel is lost when the edited image file is saved.

Image Deterioration From Repeated Editing
If you save an edited image file and then use this file later to perform additional edits, pixel resolution may be lost. It is better if you do all edits when the image files are first processed, to minimize image deterioration (or go back to the originals if you still have them). The following edit functions reduce resolution about 1/2 pixel, and this error can accumulate if multiple functions are applied in series: rotate (other than 90 degrees), HDR, HDF, stack, panorama, unbend, keystone, warp. Resize to a smaller size will of course reduce resolution, but using the fraction 1/2, 1/3, or 1/4 gives the best results. Other functions do not reduce resolution (except for those that do it deliberately).

Image Deterioration From Repeated Saving of JPEG files
Reading a compressed JPEG image and saving it again can lead to loss of detail and increased JPEG artifacts. The effect seems to be negligible if the JPEG-quality is set to a high value. I read and saved a JPEG image 30 times using a quality of 90 (the Fotoxx default). A rapid A:B comparison with the original image showed no visually detectable loss of quality. The TIFF and PNG formats are lossless and therefore have no deterioration. They are only disk space hogs.

EXIF Errors
Cameras (esp. older ones) do not always produce structurally correct EXIF data, and the program exiftool (used by Fotoxx to manipulate EXIF data) may produce error messages. I have been able to fix these cases by saving the image file on top of itself, which will replace the EXIF data with whatever exiftool was able to read correctly. If desired tags get lost, you must restore them manually.

Newline characters in User Comments or Captions
When editing User Comments or Captions, if you need to align text in columns, you can use the [enter] key to force new lines. These are converted into the string "\n" before being stored in image EXIF/IPTC data, since newline characters are not allowed (exiftool converts them into periods). If the text is viewed or edited again, the "\n" strings are converted back to new lines, so that the original text alignments are restored. This is not standard, so don't expect the text to remain aligned if viewed in Photoshop, etc. If this is a requirement, then do not use the enter key to make new lines when entering long text - just let the text overflow to the next line by itself.

Standard Trash Directory
If the Fotoxx [trash] menu and toolbar button does not put trashed image files into the standard wastebasket (where they are also recoverable using the GUI wastebasket browser), you may be able to fix this yourself. If your image files are not on the /home disk, there may be no wastbasket directory by default. You can add one yourself following this example: if the disk containing image files is mounted at /images and your UID is 1000, there should be a directory named /images/.Trash-1000, owned by UID 1000, with full permissions for UID 1000. The standard trash function will put trashed files there. Add this directory manually if it is not there. This may fix the problem.

Special Fotoxx Files
The following files reside in /home/<user>/.fotoxx/. The search_index file duplicates data contained in the EXIF and IPTC metadata within the image files. It is there because it can be read 1000 times faster than reading the image files.
   /annotations/
annotations saved from Transform > Annotate Image
   /collections/
image collections from Tools > Manage Collections
   /saved_areas/
"cutout" files saved from the Select > Save dialog
   /saved_curves
curve data saved from Retouch curve edit dialogs
   fotoxx.log
Fotoxx outputs that may be relevant for diagnosing problems
   parameters
setup parameters that are saved across Fotoxx sessions
   printfile.png
the last file printed with Fotoxx
   recent_files
a list of the last 100 files opened by Fotoxx, saved when Fotoxx exits
   search_results
a list of the last image files found with Info > Search Images
   tags_defined
a list of all categories and tags currently used in all images
   search_index
a large text file containing searchable data for all image files
   zdialog_positions
saved dialog window positions (relative to main window)

Preview Mode
Some edit functions use a reduced image size for a faster interactive response time. This reduced size is shown on the status bar as "preview". When [done] is pressed, the full-size image is then processed. This is why [done] sometimes takes noticeable time. A monitor-size image (2 megapixels) is 5 times faster to process than a 10 megapixel image. This method is used whenever the preview edits can be applied to the full-size image without visible impact (Rotate, Unbend, Warp and all brightness, contrast and color related functions). It cannot be used for things like sharpen and tone mapping because the results for a small image cannot be converted for a larger image. Thus Tone Mapping is not as responsive as Gamma Curve, for example.

File Size in Status Bar
The file size shown on the status bar while an image is being edited is the original (unedited) file size. The file size for an edited image is not known until the image is compressed and saved on disk. In memory the size is length x width x 3 colors x 2 bytes. A 10 megapixel image uses 60 megabytes in memory and typically < 2 megabytes on disk (if jpeg). When the edited image is saved, the correct file size is updated on the status bar.

Image Search Benchmarks

Here are a few benchmark numbers for a test image collection of 29892 images and a total size of 25.6 GB. The first benchmark is for a new install of Fotoxx on a computer having nearly 30 thousand images. The next two represent subsequent startups with no new image files and 15 new image files present. The Search Image benchmarks show the fast search speed using data that is in the search index file. The Search Metadata benchmark shows the slower search speed when non-indexed metadata is searched: the 4140 files from a prior Search Image were searched for specific EXIF data.
  Synchronize Files from initial status (no index file, no thumbnails)
 28 minutes
  Synchronize Files at startup, no new files present
 < 1 second
  Synchronize Files at startup, 15 new files present
 3 seconds
  Search Images by date range, find 2178 from 29892 with a date in 2006
 < 1 second
  Search Images by file name, find 4140 from 29892 with "gallery" in directory/file name
 < 1 second
  Search Images by tags, find 258 from 29892 having both tags "alaska" and "scenery"
 < 1 second
  Search Metadata, find 228 of 4140 files having "2011" in EXIF: Modifiy Date
 30 seconds

Source Code

The C++ source code is heavily commented in the hope that others can understand and use the code for their own projects. If you have a technical question about how something works, or a better idea to pass along, you can  contact me.

Questions and Problems
If you have a question or run into a problem, you may contact me. If you send me any images that work poorly, I can use these to try to improve Fotoxx. If there is a traceback dump on the screen, or error messages in the log file /home/<user>/.fotoxx/fotoxx.log, please send these also. Please explain exactly how to produce the error, and what version of Fotoxx and what Linux flavor you are using.

Technical Reference Book
I recommend the book "Introduction to Image Processing and Analysis" by Russ and Russ, CRC Press. It is clear and concise. The following algorithms were adapted from this book: flatten brightness distribution, unsharp mask, noise reduction (median smoothing, top hat), simulated embossing. The affine transform method for image warping and rotation was found via Google.

Acknowledgements
The programs  libtiff, ufraw, exiftool have helped Fotoxx evolve much faster than otherwise possible. Of course this also applies to GTK, GDK, the pixbuf library, the GNU tools and libraries, and the entire GNU/Linux ecosystem. Thanks to those who have donated their work for translations (see Fotoxx Help > About), and those who have donated their ideas for development and their time for testing.


fotoxx-12.01.2/doc/edit-menus0000644000175000017500000000603611701011016014377 0ustar micomico Image Transform =============== Rotate Image Rotate an image any amount. Trim Image Trim unwanted margins from an image. Auto-Trim Image Trim leftover margins from panorama, warp, etc. Resize Image Scale an image up or down. Annotate Image Write text annotations on an image. Flip Image Mirror an image horizontally or vertically. Make Negative Make a black-white or color negative or positive. Unbend Image Fix perspective problems (esp. panoramas). Keystone Correction Straighten an object photographed from an angle. Warp Image (area) Distort "rubber" image by pulling with the mouse. Warp Image (curved) Distort entire image by pulling with the mouse. Warp Image (linear) Distort entire image by pulling with the mouse. Warp Image (affine) Distort entire image by pulling with the mouse. Image Retouch ============= Brightness/Color Edit brightness, contrast, color, saturation. Gamma Curve Edit brightness and color using gamma curves. Expand Brightness Clip low/high brightness and expand the middle. Flatten Brightness Even brightness distribution to enhance detail. Brightness Ramp Horizontal/Vertical variation of brightness. Tone Mapping Increase local contrast to to enhance details. White Balance Remove false color from an image. Match Colors Match the colors in one image to another image. DRGB Change brightness or RGB colors using OD units. Revise RGB Make color corrections that vary over the image. Red Eyes Remove red eyes from flash photos. Blur Image Blur an image (e.g. smoothen skin). Sharpen Image Sharpen a blurred image. Reduce Noise Reduce noise (speckles) in low-light images. Smart Erase Remove power lines and other spoilers. Remove Dust Remove spots on images made from dusty slides. Fix Stuck Pixels Fix bright/dark pixels from camera sensor defects. Edit Pixels Edit pixels and paint areas using the mouse. Apply Art Effects ================= Color Depth Reduce the number of colors (aka "posterize"). Drawing Convert to a simulated pencil or chalk drawing. Outlines Convert into a colorful line drawing. Embossing Convert into a simulated embossing (3D effect). Tiles Convert into square tiles. Dots Convert into dots (Roy Lichtenstein effect). Painting Convert into a simulated painting. Combine Images ============== High Dynamic Range Make an image with extended brightness range. High Depth of Field Make an image with extended depth of sharp focus. Stack / Paint Remove transient objects (cars, tourists). Stack / Noise Reduce noise by averaging multiple images. Panorama Make an image with extended horizontal field of view. Veritcal Panorama Make an image with extended vertical field of view. fotoxx-12.01.2/doc/fotoxx.man0000644000175000017500000000626211701011016014427 0ustar micomico.TH FOTOXX 1 2011-08-01 "Linux" "Fotoxx man page" .SH NAME Fotoxx - digital photo editor and collection manager .SH SYNOPSIS \fBFotoxx\fR [ \fB-v\fR ] [ \fB-lang\fR \fIcode\fR ] [ \fIfile\fR | \fIdirectory\fR ] [ \fB-recent\fR ] [ \fB-prev\fR ] [ \fB-blank\fR ] [ \fB-slideshow\fR [ \fB-music\fR ] ] [ \fB-translate\fR ] .SH DESCRIPTION Fotoxx is a graphical menu-driven program which operates in its own window. Organize and administer a collection of images, edit images, search images, perform image utility functions. .SH OVERVIEW Edit functions include: - View and edit most image file types and RAW file types - Adjust brightness/color/contrast using movable curves - Fix vignetting and other brightness uniformity problems - Expand and/or flatten the brightness distribution - Trim (crop), Resize, Flip, Rotate (any angle) - Sharpen, Blur, Reduce noise, Remove red-eyes - Tone Mapping (enhance local contrast and faint details) - Auto adjust white balance, Match colors to a standard - Remove a color caste even if it varies across the image - Warp (stretch/distort image by dragging the mouse) - Panorama, HDR, and Stack composites (hand-held photos OK) - Combine photos with differing focus depths - Artful transforms (simulate drawing, embossing, painting) - Pixel edit with variable brush transparency and blending - Edit selected objects or areas within an image - Copy and paste selected objects or areas (cutouts) - Smart erase: get rid of ground litter, power lines, etc. - Erase dust: remove dust spots on images from scanned slides - Write text on the image (vary font, color, transparency, angle) - Use Gimp or other editor as a plug-in function Utility functions include: - Thumbnail image browser and navigator - Add comments, tags, dates, and star-ratings to images - Search images by comments, tags, dates, star-ratings, file names - Rename images from camera using a base name and sequence number - Slide-show mode: automatic or keyboard control, optional music - Batch convert multiple RAW files to tiff-8/16, jpeg, png - Print image using any format, make color adjustments - Select images, convert format, resize, export, burn CD/DVD - Assign images to named collection, edit and view collection - Edit image metadata, search and report any metadata - Tune monitor for color and gamma - Context aware help available via the F1 key .SH OPTIONS Command line options \fB-v\fR print version and exit \fB-lang\fR \fIcode\fR specify language (de, fr, zh_CN ...) \fIfile\fR initial image file to view or edit \fIdirectory\fR initial directory of image files \fB-prev\fR open last file from the previous session \fB-recent\fR show a gallery of most recent files opened \fB-slideshow\fR is first image in a slide show \fB-music\fR is a music file or a playlist \fB-translate\fR start in interactive translation mode .SH SEE ALSO The online user manual is available using the help menu. This manual explains Fotoxx operation in great detail. .SH AUTHORS Written by Mike Cornelison fotoxx-12.01.2/doc/userguide-it.html0000664000175000017500000102022211701011016015672 0ustar micomico fotoxx - Guida utente Fotoxx - Manuale utente v.11.12

Licenza e garanzia

Fotoxx ha la licenza GNU General Public License v3 (Free software foundation).
Fotoxx non è garantito per alcuno scopo ma, se trovate un difetto, proverò a correggerlo.

Origine e contatti
Fotoxx ha origine dal sito web dell'autore http://kornelix.squarespace.com/fotoxx. Altri siti web possono offrirne il download. Possono esservi modifiche. In caso di domande, suggerimenti, segnalazione errori, potete contattarlo.

La cronistoria delle versioni della guida utente possono essere viste qui (inglese).

Alcune note tecniche addizionali possono essere trovate qui.


Informazioni di base

Installazione
Per installare Fotoxx, provare prima il pacchetto appropriato: pacchetti: potrebbe installarsi bene con un singolo clic. Altrimenti, occorre installare usando i sorgenti: le istruzioni sono qui: downloads. Fotoxx dovrebbe mostrarsi nel menù sotto la voce Grafica, dopo l'installazione (oppure dopo riavviata la sessione). Diversamente usare il comando "fotoxx" in una finestra di terminale o un lanciatore. Per provare Fotoxx, usare il pulsante della barra [Apri] per trovare un file immagine (.JPG  .TIF  .PNG ...) e controllare che venga mostrato correttamente. Usare il menù Ritocco->Luminosità e colore e premere il pulsante [+++] alcune volte: l'immagine dovrebbe schiarirsi. Usare il pulsante [Annulla] per uscire dalla funzione senza alterare l'immagine. Premere il pulsante della barra [Galleria] per mostrare tutte i file immagine nella stessa cartella come una schiera di miniature. Ciò può essere lento, perché le miniature devono essere create, ma sarà più veloce la volta successiva che si aprirà la stessa cartella. Cliccare su una miniatura per mostrare l'immagine in dimensione reale. Se tutto questo funziona bene, allora Fotoxx sta funzionando normalmente.

Iniziazione
Fotoxx deve sapere dove si trovano le vostre immagini (cartelle e nomi file), e le informazioni al loro interno (se presenti): etichette, commenti, punteggi, date. Fotoxx ha bisogno anche di creare le miniature così che la galleria (pagine di miniature) possa funzionare velocemente. Dovreste eseguire la funzione del menù Strumenti->Sincronizza file prima di eseguire qualsiasi lavoro significativo. Dopo eseguita questa funzione, la galleria funzionerà molto più velocemente, e la funzione di Ricerca immagini potrà analizzare migliaia di immagini al secondo. Per maggiori dettagli, riferirsi all'argomento Sincronizza file.

Informazioni essenziali per chi odia i manuali corposi:

  o  Le funzioni del menù hanno l'aiuto contestuale attivato dal tasto F1.
  o  Clic sinistro del mouse: ingrandisce l'immagine, centrandola sulla posizione del mouse.
  o  Trascinamento del mouse sull'immagine: fa scorrere l'immagine dentro la finestra.
  o  Clic destro del mouse: ripristina l'immagine in modo che stia dentro la finestra.
  o  Pulsante della Galleria: mostra miniature di tutte le immagini nella cartella corrente.
  o  Clic di un'immagine nella Galleria: mostra l'immagine nella finestra principale.
  o  Menu: Strumenti -> Cambia lingua del programma: cambia da Inglese alla vostra lingua.

Le parole directory e cartella possono essere usate intercambiabilmente.

Molte finestre di dialogo hanno una casella "Abilita mouse". Se spuntata, le operazioni con il mouse riguardano la funzione corrente (della finestra di dialogo); se non spuntata, il mouse varierà ingrandimento e scorrimento dell'immagine nella finestra principale. Si possono usare alternativamente entrambi i modi.

I pulsanti delle finestre di dialogo normalmente funzionano come segue:
Prosegui - chiude il dialogo e continua con la funzione (se articolata o complessa).
Applica - applica le impostazioni del dialogo, lasciandolo aperto.
Fatto - mantiene le modifiche appena fatte e chiude il dialogo.
Annulla - elimina l'ultima modifica e chiude il dialogo.

Procedure generali di editing
L'immagine nella finestra principale (l'immagine corrente) può essere manipolata con le funzioni del menù Ritocco, Trasforma, Arte, Combina. Queste funzioni modificano l'immagine corrente (solo in memoria); si possono usare più volte in qualsiasi ordine, e i loro effetti vengono accumulati e mostrati nella finestra principale. I pulsanti [Annulla] e [Ripeti] della barra principale possono essere usati per vedere i risultati "prima e dopo" delle ultime 99 modifiche. Essi possono essere usati pure per vedere gli stessi risultati "prima e dopo" mentre una funzione di modifica è in corso. Dopo aver modificato un'immagine, usare [Salva] o [Salva nuovo...] per memorizzare l'immagine su disco (rispettivamente con sostituzione del vecchio file o creazione di uno nuovo).

Molte finestre di dialogo hanno cursori, regolazioni o curve modificabili che aggiornano l'immagine nella finestra principale. Il tempo di reazione dipende dalle dimensioni dell'immagine, la complessità della funzione e la velocità del computer; di solito questo tempo è inferiore a un secondo, usando un computer con due processori a 2GHz o più.

Modifica di curve:

Molte funzioni usano curve modificabili. Si possono manipolare tali curve per cambiare alcune proprietà dell'immagine (es. la saturazione del colore) in dipendenza di qualche altra proprietà (es. la luminosità). Come esempio, si potrebbe aumentare la saturazione nelle aree scure di un'immagine senza toccare le aree chiare. In genere, l'asse X della curva (direzione da sinistra a destra) rappresenta la proprietà "d'ingresso" (luminosità nell'esempio precedente), e l'asse Y (dal basso verso l'alto) la proprietà che viene modificata (saturazione, nell'esempio di prima). Le curve possono essere trascinate con il mouse: verso l'alto per aumentare l'effetto della funzione, e verso il basso per diminuirne l'effetto. Un punto di ancoraggio (quadratino nero) verrà aggiunto alla curva nella posizione in cui la si sta trascinando, e la curva passerà sempre attraverso il quadratino appena immesso, anche questa viene modificata in altri tratti. Anche i punti di ancoraggio possono essere trascinati, e si può eliminarli con un clic destro del mouse sopra di essi. Le finestre contenenti curve modificabili contengono anche i pulsanti [Carica da un file] e [Salva in un file], che permettono di memorizzare le curve in un file e riutilizzarle in seguito. Questo può far risparmiare il tempo necessario a modificare una curva quando più immagini devono ricevere lo stesso trattamento.

Procedura semplice
Quasi sempre si possono modificare le immagini JPEG così come prodotte dalla macchina fotografica. Si può usare la procedura descritta qui sotto, più complessa, nel caso che si producano bande colorate dopo aver ritoccato la fotografia.

Procedura complessa
Convertire l'immagine RAW della macchina in formato TIFF, producendo un'immagine con 16 bit per colore. La grande profondità (precisione) di colore riduce il rischio di creare bande colorate da parte di quelle funzioni che possono spostare pesantemente la distribuzione della luminosità (specialmente normalizzazione e mappatura di tonalità). Quando terminato, convertire il TIFF risultante in JPEG, con qualità 70 o più, per ridurre la dimensione del file (tipicamente da 50 Mib a 2 Mib). Difficilmente sarà visibile qualche differenza tra il TIFF elaborato e il JPEG risultante. Per preservare la possibilità di ritoccare nuovamente l'immagine in futuro, conviene tenere il file RAW, che è molto più piccolo del TIFF.


Selezione di immagini da una Galleria di miniature

Questa procedura si usa in diverse funzioni che usano o ritoccano file multipli (creazione di una collezione, aggiunta/rimozione in blocco di etichette, ridimensionamento in blocco e simili). Viene spiegata una volta sola qui, ma questo paragrafo è collegato (raggiungibile) da ogni funzione che usa questa procedura.

Quando la procedura parte, appare una lista vuota per le immagini selezionate. Dietro la lista si trova la galleria che permette selezioni multiple. Per selezionare un'immagine, cliccarne la miniatura, e il file relativo verrà aggiunto alla lista. Si può navigare nella galleria verso altre cartelle e selezionare immagini in qualsiasi ordine. La lista dei file può essere manipolata anch'essa per variarne l'ordine o togliere le immagini inserite per sbaglio: cliccare un elemento della lista per mostrarne la miniatura e segnare, contemporaneamente, la posizione corrente di inserimento di nuovi elementi. L'immagine successiva che verrà aggiunta finirà in questa posizione. Premendo [Elimina], l'elemento corrente verrà tolto; premendo [Inserisci], l'ultimo elemento tolto verrà reimmesso nella posizione indicata. Quindi, per spostare un'immagine in una nuova posizione: cliccare l'elemento (la sua miniatura verrà mostrata); premere [Elimina]; cliccare su una nuova posizione e premere [Inserisci] (l'elemento tolto sarà reinserito prima della posizione selezionata). La lista può essere manipolata direttamente tramite "taglia e incolla" per ottenere l'ordine desiderato, ma fare attenzione a tagliare e incollare solo intere linee di testo (che sono nomi di file). Il pulsante [Aggiungi tutti] aggiunge tutte le immagini presenti in quel momento nella galleria. Dopo una ricerca immagini, per esempio, la galleria conterrà i risultati della ricerca: si possono aggiungere le immagini volute una per volta, oppure usare [Aggiungi tutti] e poi eliminare le immagini non volute.


Menù e barra dei pulsanti di Fotoxx

Menù File
Gestione di file
Galleria immagini
Mostra la galleria di miniature corrispondenti alla directory corrente (dettagli).
Clona (50/50)
Apre un'ulteriore istanza di fotoxx: le due finestre sono grandi metà dello schermo
Clona (sovrapposta)
Apre un'ulteriore istanza, sovrapponendola alla finestra originaria
Apri un'immagine
Dialogo di apertura file: carica un'immagine da vedere o modificare (dettagli).
Apri in nuova finestra
Apre un'immagine, ma usando un'ulteriore finestra
Apri l'immagine precedente
Torna all'ultimo file utilizzato (prima di quello corrente) (dettagli).
Apri un file recente
Sceglie da una lista delle immagini usate più di recente (dettagli).
Salva (sovrascrivi)
Salva l'immagine corrente (modificata) nello stesso file originario (sovrascrivendolo) (dettagli).
Salva nuovo...
Salva l'immagine in un file nuovo (dettagli).
Crea immagine vuota
Crea un nuovo file di immagine (dettagli).
Cestina l'immagine
Sposta un file immagine nel cestino (dettagli).
Rinomina l'immagine
Cambia nome, opzionalmente usando un numero di sequenza (dettagli).
Rinomina più immagini
Rinomina più immagini usando una radice e un numero incrementale (dettagli).
Stampa immagine Seleziona stampante, carta, orientamento, e stampa l'immagine (dettagli).
Termina Fotoxx
Esce dal progamma Fotoxx.

Menù Strumenti
Funzioni di utilità e di impostazione
Gestione collezioni Riorganizza collezioni di foto (dettagli).
Verifica luminosità schermo
Mostra delle barre di colore per regolare lo schermo (dettagli).
Verifica gamma dello schermo
Mostra un'immagine speciale per regolare la "gamma" dello schermo (dettagli).
Diagramma della luminosità
Mostra il grafico della distribuzione di luminosità dell'immagine corrente (dettagli).
Duplica Fotoxx (nuova finestra)
Apre una nuova finestra (es. per confrontare due immagini) (dettagli).
Slideshow
Mostra diverse immagini a schermo pieno (senza menù e barre) (dettagli).
Esplora i colori RGB dei pixel
Mostra i valori RGB alle posizioni cliccate (dettagli).
Linee griglia
Mostra/nasconde linee di griglia di riferimento (per Svolgi/Ruota) (dettagli).
Parametri dell'obbiettivo
Modifica i parametri delle macchine e degli obbiettivi (dettagli).
Cambia lingua del programma
Cambia la lingua utilizzata dal programma (dettagli).
Edit Translations
Permette di eseguire la traduzione della lingua interattivamente (dettagli).
Crea menù e lanciatore
Crea una voce per il menù del desktop e un'icona sul desktop (scrivania) (dettagli).
Conversione di più immagini RAW
Converte una o più immagini da RAW a TIFF (dettagli).
Masterizza immagini su CD/DVD
Seleziona più immagini e le scrive su un CD o DVD (dettagli).
Spedire immagini via e-mail
Seleziona immagini, le ridimensiona, e le invia al programma di posta (dettagli).
Sincronizza file
Ricostruisce miniature e indici (per la ricerca) delle immagini  (dettagli).
Toolbar Style
Imposta il tipo di barra degli strumenti (Solo testo, solo icone, o entrambi)
Mostra uso memoria (in console)
Mostra, nel terminale usato per lanciare Fotoxx, un sommario sull'uso della RAM

Menù Info
Mostra e modifica i dati delle immagini e i loro attributi
Modifica commenti
Add or change descriptive text for an image (dettagli).
Modifica titolo
Add or change an image caption (dettagli).
(Introduzione)
Spiegazione delle etichette e come vengono utilizzate (dettagli).
Modifica etichette
Aggiunge/modifica etichette, parole chiave, punteggio e data (dettagli).
Gestione etichette
Crea etichette e categorie di etichette (dettagli).
Aggiungi etichette a più immagini
Aggiunge diverse etichette a più immagini contemporaneamente (dettagli).
Cancellazione in blocco di etichette
Elimina o modifica una etichetta per più immagini insieme (dettagli).
Ricerca immagini
Cerca immagini con etichette/punteggio/data/commenti/titolo desiderati (dettagli).
Vedere informazioni (breve)
Visualizza le informazioni basilari dell'immagine (dettagli).
Vedere informazioni (lungo)
Mostra tutte le informazioni disponibili sull'immagine (dettagli).
Modifica informazioni
Aggiunge o modifica i dati di una chiave (o campo) specifica (dettagli).
Elimina informazioni
Elimina una chiave specifica o tutte le informazioni (dettagli).

Menù Seleziona
Seleziona aree dell'immagine dove confinare le operazioni di modifica
(Introduzione)
Spiegazione su selezione e modifica di aree (dettagli).
Seleziona
Seleziona un'area per le successive funzioni di editing (dettagli).
Mostra / Nascondi
Mostra o nasconde il perimetro dell'area (dettagli).
Abilita / Disabilita
Attiva o disattiva il confinamento nell'area per le successive operazioni (dettagli).
Inverti
Inverte un'area (dettagli).
Cancella
Elimina un'area (dettagli).
Copia / Incolla
Copia un'area in memoria e la incolla (utilizza) in qualche altro punto (dettagli).
Carica / Salva file
Salva un'area in un file / la ricarica per usarla su altre immagini (o sulla stessa) (dettagli).
Immagine intera
Seleziona l'intera immagine come maschera per le manipolazioni successive (dettagli).
Seleziona a modifica
Usare il mouse sopra l'immagine per fare modifiche incrementali (dettagli).

Menù Ritocco
Funzioni che cambiano alcune proprietà dell'iimagine
Bilanciamento del bianco
Rimuove la sfasatura di colore (dettagli).
Trasforma in negativo
Produce il negativo (bianco e nero o a colori), o il positivo (da un negativo) (dettagli).
Normalizza la luminosità
Appiattisce la luminosità per migliorare i dettagli (dettagli).
Luminosità e colore
Modifica luminosità, contrasto, saturazione e bilanciamento dei colori (dettagli).
Mappatura della luce
Variazione della luminosità in senso orizzontale e verticale (dettagli).
Espandi luminosità
Taglia le luminosità estreme ed espande le altre (dettagli).
Mappa tonalità
Aumenta il contrasto locale per migliorare i dettagli (dettagli).
Correzione occhi rossi
Rimuove gli "occhi rossi" dalle fotografie fatte col flash (dettagli).
Sfocatura immagine
Sfuoca l'immagine (es. liscia la pelle) (dettagli).
Contrasta immagine
Acutizza un'immagine sfuocata (dettagli).
Riduci disturbo
Riduce il rumore (puntini/pallini) in immagini con luce scarsa (dettagli).
Cancellazione intelligente
Rimuove pieghe e altri disturbi sostituendoli con particolari adiacenti (dettagli).
Rimozione polvere
Rimuove macchioline da immagini acquisite tramite scanner (dettagli).

Menù Trasforma
Funzioni che cambiano dimensione, forma o contenuti di un'immagine
Ritaglia immagine
Ritaglia una porzione rettangolare dell'immagine (dettagli).
Ridimensiona immagine
Riscala un'immagine (con più o meno pixel) (dettagli).
Ritaglia automaticamente Sceglie margini automatici dopo ruota, raddrizza o deforma (dettagli).
Ridimensiona/esporta in blocco
Riscala molte immagini (per pubblicazione su web, email ecc.) (dettagli).
Testo sulll'immagine
Imprime testi/annotazioni sull'immagine (dettagli).
Ruota immagine
Ruota l'immagine con diversi passi di rotazione (non solo 90°) (dettagli).
Rifletti immagine
Riflette l'immagine in orizzontale o in verticale (dettagli).
Svolgi (raddrizza deformazioni obbiettivo)
Corregge problemi di prospettiva (dettagli).
Deforma immagine (area)
Distorce un'area trascinando con il mouse (dettagli).
Deforma immagine (curve)
Distorce l'intera immagine trascinando con il mouse (dettagli).
Deforma immagine (lineare)
Distorce l'intera immagine trascinando con il mouse (dettagli).
Deforma immagine (speculare)
Come sopra, in modo simmetrico (dettagli).

Menù Arte
Funzioni che effettuano trasformazioni artistiche
Profondità di colore
Riduce la profondità di colore (come un poster) (dettagli).
Disegno
Trasforma una foto in un disegno simulato a matita o gessetto (dettagli).
Contorni
Trasforma una foto in un disegno di linee colorate (dettagli).
Bassorilievo
Trasforma una foto in un bassorilievo simulato (dettagli).
Mosaico
Trasforma una foto in un mosaico di tessere (dettagli).
Puntinismo
Trasforma una foto in un insieme di molti puntini (dettagli).
Pittura
Trasforma una foto in un disegno a olio (dettagli).
Modifca dei pixel
Modifica dei pixel e disegno di linee o aree con il mouse (dettagli).

Menù Combina Funzioni che combinano/uniscono più immagini in una
Combina immagini (alta dinamica - HDR)
Crea un'immagine con alta dinamica miscelando altre immagini (dettagli).
Combina immagini (grande profondità - HDF)
Crea un'immagine con grande profondità miscelandone altre (dettagli).
Sovrapponi (interattivo con mouse)
Miscela più immagini per rimuovere elementi come turisti o veicoli (dettagli).
Sovrapponi (rimozione disturbo)
Miscela più immagini per ridurre i disturbi (dettagli).
Crea un panorama / Panorama verticale Affianca 2..4 foto per produrne una larga o alta (dettagli).
 
Menù Plugins
Altri programmi di fotoritocco possono essere usati come funzioni di manipolazione in Fotoxx (dettagli).
 
Menù Aiuto
Guida utente, file README, change log (dettagli).
  
Pulsanti della barra

Miniature
Mostra la galleria di miniature delle immagini nella cartella (directory) corrente (dettagli).
Carica da file
Richiama un dialogo di selezione file per aprire o vedere un'immagine da disco (dettagli).
Prec / Prossima
Carica l'immagine precedente/successiva dalla directory corrente o del risultato della ricerca.
Salva / Salva come
Salva l'immagine corrente sullo stesso file (sovrascrivi) o un file nuovo (dettagli).
Annulla
Annulla l'effetto dell'ultima manipolazione eseguita.
Ripeti
Annulla l'ultimo annullamento. La memoria per gli annullamenti ha 99 passi.
Zoom+
Ingrandisce l'immagine. Anche un clic sinistro sull'immagine ha lo stesso effetto.
Zoom-
Riduce l'immagine fino ad adattarla alla finestra. Un clic destro ha lo stesso effetto.
Cestina Cestina (sposta nel cestino) il file corrispondente all'immagine corrente (dettagli).
Uscita
Esce dal programma.
Aiuto
Mostra la guida utente (questo documento) (dettagli).
 
Scorciatoie da tastiera

Finestra principale

Frecce sinistra e destra
Immagine precedente e prossima
Tasti "+" e "-"
Zoom più o meno
Tasto "Z"
Ingrandimento ottimale (immagine completa nella finestra)
Tasti "R" / "L"
Rotazione di 90° a destra o sinistra
Tasto "G"
Mostra o nasconde la griglia
Tasto "T"
Richiama la funzione Trasforma -> Ritaglia immagine
Tasto "B"
Richiama la funzione Ritocco -> Luminosità e colore
Tasto "Del" o "Canc"
Cestina l'immagine
Tasto "Esc" (Escape)
Termina lo slide show
Control + "s" (minuscolo)
Salva l'immagine (riscrittura - senza chiedere conferma)
Control + "S" (maiuscolo)
Salva con nome (richiama un dialogo per inserire il nome)
Control + "q" o Control + "Q"
Uscita da Fotoxx
Galleria di immagini

Home / Fine
Salta alla prima o ultima pagina della galleria
Pagina Su/Giù (PgSu/PgGiù)
Passa alla pagina precedente/successiva
Frecce su/giù
Scorre la galleria una riga per volta
Frecce sinistra/destra
Passa alla pagina precedente/successiva
Tasti "+" e "-"
Dimensione delle miniature maggiore/minore
Tasto "Esc" (Escape)
Chiude la galleria
Dialoghi per l'inserimento di dati
 
Tasto "F1"  (Tasto funzione F1)
Mostra l'aiuto (la guida utente) sull'argomento corrente

Funzioni del mouse

Clic sinistro
Aumenta l'ingrandimento, centrando l'immagine sulla posizione del clic
Clic destro
Adatta l'ingrandimento alla finestra in modo da vedere tutta l'immagine
Trascinamento sull'immagine
Fa scorrere l'immagine nella direzione opposta, come le barre di scorrimento



Menù File

Navigazione


Usare la funzione del menù File -> Galleria immagini oppure il pulsante [Miniature] per aprire una finestra di miniature dei file d'immagine nella directory corrente, o l'ultimo risultato della ricerca, o la collezione corrente. Usare questa finestra per navigare nelle directory e selezionare file di immagini cliccando sulle miniature. I pulsanti in alto permettono di scorrere avanti e indietro per righe o per pagine. Usare [Cartella superiore] e [Apri un file] per usare altre cartelle/directory. Usare i pulsanti [Aumenta] e [Riduci] per modificare la dimensione delle miniature. Il richiamo di questa funzione dalla finestra principale mostrerà la galleria con l'immagine corrente nella fila superiore; cliccando una delle miniature riattiverà la finestra principale, che conterrà l'immagine appena cliccata. Le due finestre sembrano escludersi a vicenda, ma in realtà ognuna è semplicemente davanti all'altra, ed entrambe possono essere ridimensionate e spostate per vederle insieme, se si desidera.

Ci sono tre tipi di galleria: (1) lista di immagini in una directory (con eventuali sottocartelle alla cima); (2) lista di immagini ottenuta tramite la funzione di ricerca, dove le immagini possono risiedere in molte cartelle differenti; (3) lista di immagini appartenenti a una collezione precisa (dotata di nome). La barra del titolo della finestra mostra il nome della cartella/directory corrente, la scritta "Risultati della ricerca", or il nome di file della collezione scelta.



Apri un'immagine

Questo comando mostra una finestra di dialogo standard, che permette di selezionare un file o spostarsi in un'altra directory per selezionare. Il file scelto viene aperto nella finestra principale dove potrà essere manipolato usando il menù e i pulsanti. La barra del titolo della finestra principale mostra il nome del file e la directory di appartenenza dell'immagine corrente. Il trascinamento di file da altre applicazioni (es. file manager come Nautilus o Konqueror) è anche possibile: Fotoxx aprirà il file trascinato. Se si trascina del testo (per esempio il testo selezionato all'interno di un editor di testi), Fotoxx assumerà che il testo indica un nome di file, e proverà ad aprire tale file; quindi è possibile creare una lista di nomi di file e usarla con Fotoxx. Praticamente è possibile usare file manager o file di testo per navigare un insieme di immagini in modo alternativo al sistema di navigazione interno di Fotoxx. Si aggiunga l'applicazione all'elenco di "Apri con..." del file manager. Se la galleria mostra il risultato di una ricerca o una collezione, e si apre un file che non appartiene all'elenco mostrato in quel momento dalla galleria, allora la galleria verrà ricaricata con le immagini della directory che contiene il file appena aperto; una conferma viene richiesta per dare modo di proseguire o interrompere l'operazione.


Apri l'immagine precedente
Torna all'immagine precedente, anche se questa appartiene a una directory diversa. Ciò è diverso dal pulsante della barra [Prec.], che carica l'immagine precedente della galleria.


Apri file recente
Le ultime 99 immagini usate sono mostrate in una lista, dalla quale se ne può scegliere una per aprirla.


Salva immagine
Il menù [File > Salva (sovrascrivi)] o il pulsante della barra [Salva] eseguono la stessa funzione: salvano l'immagine corrente con lo stesso nome, riscrivendo quindi il file. Se il file è un JPEG, il fattore di qualità di default, cioé 90, viene utilizzato. Se il file è originale (senza "versione"), il programma avvertirà che lo si sta riscrivendo - si può confermare e proseguire. Si può anche decidere di sopprimere questo avviso in modo permanente. Se l'avvertimento è stato disabilitato e lo si vuole riabilitare, occorre editare il file /home/<utente>/.fotoxx/parameters e cambiare il valore di "warn overwrite" da 0 a 1.

Salva con versione
Menù [File > Salva con una nuova versione] o pulsante [Salva+V]
Salva l'immagine con un nuovo numero di versione. I nomi di file sono preparati come "nome_del_file.vNN.ext", dove NN è il numero di versione da 01 a 99. I quattro caratteri .vNN vengono inseriti fra il nome_del_file e l'estensione. Se il file non ha ancora un numero di versione, viene creata la ".v01". Se esistono già nomi dello stesso file con un numero di versione, allora viene usato il numero successivo al più alto. Il programma non chiede conferme in questa operazione. Se il file è un JPEG, viene usata la qualità di default: 90.

La funzione del menù File > Salva nuovo... o il pulsante [Salva come] mostrano questo dialogo:

Questo dialogo permette di scegliere un nome di file su cui salvare, che può essere il file originale, un altro file esistente, o uno nuovo. Un'immagine può essere salvata in tre formati diversi: JPEG, PNG e TIFF. Il JPEG è di solito la scelta migliore, perché è compresso in modo da risparmiare spazio. Si può scegliere un fattore di qualità da 1 a 100; valori bassi producono file piccoli e minore qualità. Valori superiori a 70 danno risultati difficilmente distinguibili da quelli ottenuti con 100 (che indica la migliore qualità e il più grosso file).
I file di tipo PNG vengono compressi senza perdita di qualità, ma normalmente producono file più grossi di un equivalente JPEG a qualità massima.
I TIFF non sono compressi, e più grandi sia dei PNG che dei JPEG. I TIFF possono essere salvati con 8 o 16 bit per colore. 16 bit per colore hanno senso solo per immagini convertite da un formato RAW con più di 8 bit per colore (i RAW prodotti da una macchina fotografica hanno solitamente 12 bit, dei quali l'ultimo o gli utimi due contengono rumore). E' raro che differenze tra 8 bit e più di otto bit per colore possano essere apprezzate a occhio; tuttavia un'immagine con più bit ha più "latitudine" quando viene usata da un programma di fotoritocco come Fotoxx (sopporta meglio le manipolazioni).

Se la casella "Creare nuova versione" è spuntata, allora il nome di file conterrà un numero di versione suffisso: ".v01" se non esistono altre versioni di questo file, o il prossimo numero più alto se una o più versioni già esistono. Questo rende facile salvare una modifica senza perdere l'originale, o mantenere una serie di modifiche. L'immagine corrente si riferirà al nuovo file se è stato usato [Salva nuovo...] e la directory NON è stata cambiata. Se, invece, nel dialogo si è fatto un cambio di directory, l'immagine corrente continuerà a rifersi al vecchio file. Si può usare il menù [File -> Apri l'immagine precedente] per tornare all'immagine della versione precedente (e quindi all'immagine di prima delle ultime modifiche), se si desidera. Nome file e directory corrente vengono mostrati nella barra del titolo: controllarli sempre in caso di dubbio.

Dimensioni di file indicative per un'immagine a 10 megapixel (dipendono dalla quantità di dettagli):
 tiff-16
 tiff-8
 png
 jpeg-100
 jpeg-90
 jpeg-80
 jpeg-70
 58 MB
 19 MB
 14 MB
 7 MB
 2 MB
 1 MB
 0.6 MB


Crea immagine vuota
Crea una nuova immagine, vuota, con le dimensioni e il colore specificato. Si può usare come sfondo per incollarci pezzi tratti da altre immagini (usando Selezione area) e annotazioni (usando testo sull'immagine).
Inserire un nome di file, scegliere un colore per lo sfondo, e impostare la dimensione in pixel.



Cestina immagine
Fotoxx usa per il cestino il "Linux desktop standard". Se ciò funziona, le immagini cestinate finiscono nel cestino standard e possono essere recuperate. Altrimenti, Fotoxx sposta i file dentro una directory della scrivania nominata "fotoxx-trash". A sua volta questa directory può essere eliminata o spostata nel cestino specifico del tuo computer. Se il cestino standard non funziona, potreste forse provare a correggere il problema: fare riferimento a note tecniche a questo riguardo.


Rinomina l'immagine


Questa funzione può aiutare ad automatizzare il processo di rinomina di una serie di immagini usando una base (es. un accadimento o un nome di luogo) e un numero di sequenza. Va bene per rinominare una serie di immagini prelevate da una macchina fotografica. Aprire il primo file della serie, immettere un nuovo nome, e premere [Rinominare in]. Il prossimo file viene quindi caricato. A questo punto si può usare lo stesso nome premendo il tasto [Prec.] e poi aggiungendo un numero di sequenza. Se si usano numeri di sequenza, premere [+1] dopo [Prec.] per aggiungere la sequenza successiva al nome di base.


Rinomina più immagini
Questa funzione è utile se si vogliono rinominare in blocco molte immagini (probabilmente con la stessa data o riferite allo stesso evento), per dargli lo stesso nome e un numero di sequenza diverso. Nel dialogo, specificare una radice (nome), un numero di sequenza iniziale, e un incremento. Per esempio, usare una radice come "crociera artica-", un numero iniziale di 100 e un incremento di 1 produrrà una serie di file nominati così: "crociera artica-100", "crociera artica-101", "crociera artica-102" eccetera (le estensioni .JPG, .TIF e simili non verranno modificate). Usare il pulsante [Seleziona i file] per aprire un dialogo di scelta file e selezionare quante immagini si vuole. Quando pronti, cliccare [Prosegui] per rinominare i file tutti insieme. Non usare questa funzione per rinominare file che non siano fotografie, perché Fotoxx cercherà di aggiornare il suo catalogo interno di etichette e file relativi per la ricerca immagini.


Collezioni di immagini - Concetti
Una collezione è un insieme arbitrario di immagini composta manualmente da immagini prelevate dal database di Fotoxx. Questo è uno dei metodi per creare gruppi di immagini (altri due sono etichette/titoli/commenti, e directory/nomi di file). Una collezione è semplicemente la lista dei suoi membri (file); i file stessi non vengono mai copiati o modificati. Una data immagine può fare parte di diverse collezioni. Le collezioni possono essere usate per raggruppare immagini che condividono qualche caratteristica, come "foto di una vacanza", "foto di una certa persona" prese in momenti e occasioni diverse, "foto notevoli" e via dicendo. Quando una collezione viene creata gli viene assegnato un nome, e può essere utilizzata per diversi scopi, come vedere uno slide show o inciderla su un CD. Si possono aggiungere e rimuovere foto da una collezione, o variare il loro ordine. Una certa singola immagine può essere presente più volte nella stessa collezione.

Dialogo di gestione collezioni

Nuovo: specificare un nome per la nuova collezione; ulteriori operazioni verranno svolte sulla nuova collezione.
Modifica: selezionare una collezione esistente per le modifiche.
Vista: selezionare una collezione da visualizzare; la galleria mostrerà le miniature.
Elimina: selezionare una collezione (esistente) da eliminare. Viene cancellata la collezione, non le immagini che la formano.

Dopo che una collezione è stata creata o aperta, si possono aggiungere o rimuovere immagini cliccando il tasto destro su una miniatura della galleria o nella finestra principale: un menù a comparsa mostra le seguenti voci:

    + aggiungi immagine alla collezione <nome della collezione>
    + rimuovi immagine dalla collezione
    + rimuovi immagine e ricordala
    + inserisci qui le immagini ricordate

Procedure
(1) Aggiungere immagini: usare [Nuovo] o [Modifica] per stabilire la collezione da creare o modificare. Usare [Apri] or [Miniature] per navigare verso le immagini da aggiungere. Cliccare col destro ogni immagine da aggiungere e selezionare la voce per aggiungere. Si può anche usare [Vista] per aggiungere immagini da un'altra collezione.

(2) Rimuovere immagini: usare [Modifica] per vedere una galleria, cliccare le immagini da eliminare con il destro, e selezionare [Rimuovi immagine dalla collezione].

(3) Riorganizzare immagini: usare [Modifica] per aprire una galleria di foto; cliccare il destro su ogni immagine da spostare, e selezionare [Rimuovi immagine e ricordala]. La miniatura viene immediatamente rimossa dalla galleria, ma ricordata in una lista interna. Cliccare infine col destro su un'immagine dopo la quale collocare quelle ricordate, e scegliere [Inserisci qui le immagini ricordate] dal menù.

Sposta collezioni
Un database di foto può essere mosso rinominando o spostando la sua cartella principale - le immagini lo seguiranno automaticamente. La funzione [Sincronizza file] può riparare l'indice di ricerca, ma le collezioni diventano invalide perché le directory memorizzate saranno differenti. la funzione [Sposta collezioni] può essere usata per spostare la cartella principale in tutte le collezioni salvate. Immettere i nomi della cartella vecchia e nuova e cliccare [Applica].



Stampa immagine

Questa funzione apre un dialogo dove si seleziona una stampante, un formato di carta (es. Lettera o A4), e un orientamento della carta (verticale o orizzontale). Usare il pulsante [Stampa] per stampare l'immagine corrente con le impostazioni scelte.
Tra i formati di carta si può anche scegliere
"custom N.N x N.N cm" - senza modificare questa scritta, ma rimpiazzando i due "N.N" con con i valori desiderati in centimetri. A seconda del software di stampa installato, potrebbe apparire un'anteprima di stampa, e potrebbe essere possibile impostare ulteriori opzioni su carta, qualità e stampante. Alcuni dei formati predefiniti potrebbero non funzionare con alcune stampanti. Anche i margini sembrano a volte essere casuali; a volte si può correggere il problema cambiando le dimensioni del foglio: usare il formato custom (speciale) aumentando gradualmente le dimensioni per ottenere margini più piccoli. Io ho potuto sperimentare solo CUPS (software di stampa) con una stampante HP Officejet. Suggerisco di fare alcune prove con carta normale prima di usare la dispendiosa carta speciale fotografica.


Menù strumenti

Verifica luminosità schermo

Otto bande colorate vengono generate orizzontalmente sullo schermo, con luminosità crescente da 0% (nero) al 100% (bianco). Si può usare questa immagine per regolare luminosità e contrasto dello schermo. L'estremo sinistro di ogni banda dovrebbe essere più nero possibile, ma il colore dovrebbe cominciare a essere visibile entro pochi mm dal lato sinistro. Se la porzione nera è più ampia, occorre regolare lo schermo. Ci sono 255 passi di luminosità dal nero al bianco (si usano 8 bit per colore), e queste gradazioni sono più sottili di quanto l'occhio umano possa cogliere. Questa regolazione va eseguita in una stanza abbastanza scura, con poca luce che cade sul video.


Gamma del monitor
Il fattore gamma determina come i valori 0..255 dei colori vengono convertiti in luminosità percepita dall'occhio. Il valore standard è 2,2 e dovrebbe essere utilizzato normalmente durante le operazioni di editing. La funzione Verifica gamma dello schermo mostra un'immagine speciale fornita cortesemente da Norman Koren. Occorre regolare il cursore fino a che le  sfumature della bande scompaiano in corrispondenza del valore 2.2. Questa immagine speciale funziona solo se ingrandita al 100%, quindi non cambiare ingrandimento.


Grafico di luminosità

Questa funzione apre una piccola finestra che mostra un grafico riguardo alla distribuzione della luminosità dell'immagine corrente. Il grafico si aggiorna immediatamente se si cambia immagine o si esegue qualche modifica.


Duplica Fotoxx

Esegue una nuova istanza di Fotoxx in una nuova finestra, contenente l'immagine corrente. Lo schermo sarà diviso a metà fra le due istanze. Questo torna utile per comparare immagini, o per usare due foto alla volta. Entrambe le istanze possono essere usate per fare modifiche. L'istanza copia (a sinistra) avrà all'inizio una versione non modificata dell'immagine, mentre l'istanza originale (a destra) manterrà le ultime modifiche. Se lo stesso file viene modificato nelle due istanze, il file conterrà l'immagine che verrà salvata per ultima. Usare [Salva come] / Salva nuovo specificando [Creare nuova versione] se si desidera mantenere i due differenti file.


Slide show

Le immagini nella directory corrente, o quelle risultanti da una ricerca o una collezione, vengono mostrate una per volta. La finestra viene allargata all'intero schermo, e menù e barra dei pulsanti vengono rimossi. Un dialogo chiede la durata per ogni immagine e il tipo di transizione per cambiarla. I modi di transizione includono i tasti freccia (transizioni manuali), rimpiazzamento istantaneo, dissolvenza in ingresso e uscita, e diversi altri metodi dinamici (la nuova immagine si espande dal centro per rimpiazzare la vecchia). Se il modo "Manuale: tasti freccia" è selezionato, la durata è irrilevante e i tasti freccia a sinistra o destra sono usati per passare all'immagine precedente o successiva. Questi tasti possono essere usati anche se uno degli altri modi è attivo. Usare il tasto Esc per uscire dallo slide show. Se una ricerca immagini è stata eseguita prima dello slide show, vengono mostrate queste immagini. Prima di richiamare questa funzione è possibile usare Info->Modifica commenti o Info->Modifica titolo per mostrare il rispettivo testo di ogni immagine in una piccola finestra che si può spostare di lato; il testo viene aggiornato a ogni immagine presentata. Gli altri tipi di informazione del menù Info avranno lo stesso comportamento. Il dialogo di avviamento della funzione permette anche di specificare un file musicale o una playlist. Se questo campo non è vuoto, la musica verrà avviata insieme allo slide show.

E' anche possibile avviare uno slide show con o senza musica dalla riga di comando:

   $ fotoxx -slideshow /.../imagefile1.jpg  -music /.../musicfile.ogg

Lo slide show inizia con il file specificato e continua con i file seguenti nella stessa directory. Il parametro "-music" è opzionale; se presente, deve specificare un file musicale (.mp3, .ogg ...) o una playlist. Il comando xdg-open(1) viene usato per aprire il file musicale (che sarà suonato con il lettore predefinito).



Esplora i colori RGB

Quando un punto dell'immagine è cliccato con il pulsante sinistro, i valori RGB vengono mostrati in una finestra di dialogo. I numeri hanno il formato xxx.ddd, dove xxx sono gli 8 bit superiori del valore del colore, da 0..255, e .ddd sono gli 8 bit inferiori, da 0..999. Gli otto bit inferiori sono a zero a meno che l'immagine mostrata non sia una TIFF a 16 bit. Soltanto le funzioni di modifica di colori e luminosità cambiano gli 8 bit bassi, e questi vengono preservati solo se l'immagine viene salvata nel formato TIFF a 16 bit.


Linee griglia
Questa operazione mostra o nasconde linee orizzontali e verticali lungo l'immagine. Le linee sono utili quando un'immagine deve essere ruotata per allineare l'orizzonte, o quando viene deformata o svolta per raddrizzare i muri o altri oggetti. Le impostazioni per la spaziatura x-spacing e y-spacing controllano lo spazio in pixel fra le linee. Se le impostazioni di x-count e y-count (conteggio x e y) sono diverse da zero, allora le distanze specificate vengono ignorate e il numero richiesto di linee verrà generato. Per esempio, impostare x- e y-count a 2 per dividere l'immagine in nove quadrati uguali. Le caselle di spunta x-grid e y-grid abilitano le linee orizzontali e verticali separatamente. Il tasto G della tastiera può essere usato per invertire le linee: le caselle x-grid e y-grid vengono invertite. Se un'immagine viene stampata quando le linee sono visibili, anch'esse verranno stampate.


Parametri dell'obbiettivo

Questo è un dialogo per impostare e salvare i due parametri, focale e curvatura, che devono essere impostati per ogni macchina o lente usata per i panorami. Questi valori governano il modo con cui Fotoxx "svolge" le foto panoramiche in modo che possano collimare accuratamente. Immettere un nome per la lente o macchina e i due parametri. Fino a quattro lenti o macchine possono essere specificate. mm_focale è grosso modo la lunghezza focale della lente (equivalente a 35 mm), e curvatura è un fattore per compensare la bombatura ai lati. Qui si descrive come impostare i parametri, ma occorrerebbe prima leggere la sezione sulla creazione di panorami, per capire meglio le istruzioni seguenti.

Impostazione automatica dei parametri

Il pulsante [Ricerca], nel dialogo di pre-allineamento nella funzione Panorama, inizia una ricerca automatica dei parametri ottimali della lente. Usare una coppia di immagini adatta: il soggetto deve trovarsi a più di 50 metri di distanza, le immagini devono avere poche differenze nell'orizzonte e poca rotazione relativa, con molte dettagli ben contrastati nella zona di sovrapposizione. Inserire la lunghezza focale nominale; usare zero per la curvatura. Dopo aver fatto un preallineamento soddisfacente, premere [Ricerca] e attendere il risultato. Eseguire il tutto ancora una volta e osservare i cambiamenti. Se i valori rimangono uguali, possono essere usati per i successivi panorama. La funzione di ricerca scandisce un intervallo di valori per lunghezza e curvatura focale, e scostamenti dell'immagine per x, y e theta, cercando quei valori che forniscono i migliori risultati per le immagini analizzate. Il processo è lento (un minuto o più), ma va eseguito una volta sola per regolare le caratteristiche di un determinato obbiettivo. Assicurarsi di salvare il risultato tramite la funzione Parametri dell'obbiettivo nel menù Strumenti.

Impostazione manuale dei parametri delle lenti
Creare un panorama di un muro di mattoni (o qualsiasi muro con molti dettagli), con due immagini che si sovrappongono del 40%. Il muro deve distare almeno 5 metri. Durante il pre-allineamento, regolare diametro e curvatura dell'obbiettivo fino a che le parti sovrapposte coincidano. Durante la ripresa delle due immagini, assicurarsi di ruotare la macchina lungo l'asse verticale passante per le lenti, minimizzando movimento laterale e rotazione degli altri assi, diversamente le immagini corrisponderanno poco e i parametri non saranno ottimali. Il risultato dovrebbe corrispondere all'incirca alla lunghezza focale nominale della lente (equivalente a 35 mm). Potrebbe discostarsi un poco (le mie lenti da 27 mm funzionano meglio con un'impostazione di lunghezza di 29-30 mm). Ritengo che ciò accada perché le lenti grandangolari non sono lenti ideali. La maggior parte dei panorami saranno corretti anche se l'impostazione della lunghezza focale è impostata con un errore del 10%.


Cambio lingua

Questa funzione permette di scegliere una lingua (tra quelle disponibili) per l'interfaccia grafica del programma. Se la lingua desiderata non è disponibile, o ha una traduzione imperfetta, si consideri la possibilità di creare o correggere la traduzione: non è un compito difficile (informazioni qui).


Edit Translations (correggi traduzione / lingua del programma)

Questa procedura si usa per correggere le traduzioni interattivamente, durante l'uso di Fotoxx. Tradizionalmente i file delle traduzioni vengono modificati a parte; poi questi file vengono installati e Fotoxx viene eseguito per vedere il risultato finale. Il vantaggio di questo metodo nuovo è che il contesto d'utilizzo del programma è vissuto nello stesso momento di modifica della traduzione, e questo dovrebbe portare a una traduzione migliore e più agevole. Inoltre, la traduzione viene usata immediatamente da Fotoxx. Per maggiori dettagli su come fare una traduzione (incluso questo metodo interattivo), vedere il menù Aiuto -> Come tradurre il programma.


Crea menù e lanciatore

Questa funzione crea un'icona (lanciatore) sulla scrivania (desktop) e aggiunge una voce nel menù di sistema nella categoria "Grafica". Il sistema operativo deve essere conforme con LSB (Linux Standards Base, un insieme di regole per la standardizzazione di Linux). Il successo di tutto ciò è sporadico - può essere necessario riavviare la sessione per vedere la nuova voce del menù.


Convertire file RAW
Questa funzione converte una o più immagini RAW in file TIFF a 16 bit per colore, usando il programma ufraw-batch. Un dialogo di scelta file si apre: selezionare uno o più file RAW (tenere premuto il tasto Ctrl per eseguire selezioni multiple). Le immagini sono convertite una per volta e mostrate nella finestra principale. Secondo il numero di file, può servire molto tempo (un processore da 2,67 GHz converte circa 18 file (misti) al minuto. Il programma ufraw usa in effetti core multipli, ma la funzione di Fotoxx non usa questa possibilità.

Questa funzione converte i file RAW selezionati in JPEG, PNG, TIFF-8 o TIFF-16, usando il programma ufraw-batch. I due formati TIFF hanno rispettivamente 8 e 16 bit per colore. I file RAW usano generalmente 10-12 bit, quindi usare TIFF-16 per mantenere la precisione disponibile in un file RAW (tuttavia la differenza tra colore a 8 e 16 bit è raramente precettibile).
Un dialogo di scelta file si apre: selezionare uno o più file RAW (tenere premuto il tasto Ctrl per eseguire selezioni multiple). Verrà poi chiesto di scegliere uno dei formati elencati prima. Le immagini verranno convertite una alla volta e mostrate nella finestra principale. Secondo il numero di file, ciò può richiedere molto tempo (il mio veloce PC elabora circa 24 foto al minuto usando un misto di foto RAW e uscita con TIFF-16).



Masterizza immagini su CD/DVD

Questa funzione permette di scegliere file d'immagini e scriverle su un CD o DVD. Quando la procedura inizia, una galleria viene mostrata dalla quale scegliere le immagini da incidere (dettaglio). Quando finito, la lista di immagini viene inviata al programma Brasero per eseguire la scrittura reale.


Spedire immagini via e-mail
Questa funzione permette di scegliere fino a circa 40 immagini per inviarle al programma di posta predefinito. Si apre un dialogo: cliccare [Seleziona i file] per aprire una galleria di immagini dalla quale selezionare (
dettaglio). Finita la selezione, impostare le dimensioni massime di larghezza e altezza. Il pulsante [Prosegui] ridurrà le immagini e le manderà al programma di posta. Le nuove immagini, ridotte, sono salvate in una directory/cartella temporanea "/tmp/<nome_utente>/fotoxx/" senza intaccare quelle originali. Questa funzione usa il comando xdg-email (da LSB, Linux Standards Base), che deve essere installato e funzionante sulla vostra distribuzione (nel gennaio 2011 funzionava su Ubuntu 10.04 e falliva nel 10.10). Il programma di posta viene avviato con le immagini ridotte allegate. Occorre poi specificare il destinatario, l'oggetto e il testo, e infine inviare il messaggio.


Sincronizza file
Occorre eseguire questa procedura: dopo la prima installazione di Fotoxx, quando si aggiungono immagini alla propria collezione, o dopo un'operazione di rinomina di file o cartelle. Niente viene perso quando i file vengono spostati, ma la galleria di miniature diventa lenta se un grande numero di file è stato spostato, e la funzione di ricerca immagini non troverà file nuovi o spostati altrove. La funzione Sincronizza file crea le miniature mancanti, aggiorna quelle vecchie, e aggiorna l'indice di ricerca  usando i dati correnti delle fotografie. Se si sono usate cartelle e/o nomi di file per classificare le foto, si possono usare immediatamente questi termini nella funzione di ricerca. Se sono stati salvati titoli, etichette o punteggi dentro alle foto, anche questi dati possono essere ricercati.
Una finestra di dialogo chiederà la directory superiore contenente le vostre foto (es. /home/<nomeutente>/Immagini). Quella directory, e tutte quelle di ordine inferiore contenenti immagini verranno processate. Non importa se vi sono file di altro tipo mischiati con le immagini, tali file saranno ignorati. Ci sono due opzioni per eseguire la sincronizzazione: completa e incrementale. La "ricostruzione completa" azzera tutti i dati memorizzati e li ricostruisce; può impiegare parecchio tempo (il mio computer, relativamente potente, analizza 4500 immagini in 10 minuti). Il modo "Incrementale" salterà le immagini già conosciute (che possiedono già miniatura e dati per la ricerca); è molto più rapido se solo relativamente poche immagini sono state aggiunte (secondi invece di minuti). Lo svantaggio (non grave) è che miniature e dati obsoleti vengono lasciati al loro posto invece di essere cancellati.
Dopo che le immagini sono state indicizzate, la loro ricerca diventa praticamente istantanea.
Immagini create o spostate da Fotoxx medesimo sono gestite automaticamente. La funzione Sincronizza file è necessaria solo quando l'archivio delle immagini viene modificato dall'esterno (senza usare Fotoxx).


 
Menu Info

Nota: il programma/pacchetto exiftool deve essere installato affinché le funzioni seguenti funzionino. Fotoxx usa tale programma per leggere e scrivere le informazioni contenute dentro a un file di immagine (metadata: EXIF, IPTC, ecc.). Se exiftool non è installato, allora la riscrittura di un file (conseguente a una modifica) cancellerà questi metadati. Nelle versioni recenti di Ubuntu, il pacchetto contenente exiftool è libimage-exiftool-perl.


Modifica commenti
Questa è una funzione speciale per editare la chiave EXIF "User Comments". Immettere un qualsiasi testo da associare con l'immagine corrente. Linee di testo multiple di qualsiasi lunghezza possono essere immesse, fino a un limite generale di 1000 caratteri. Premere [Applica] per salvare il testo nei dati EXIF dell'immagine. La finestra di dialogo può essere lasciata aperta mentre si naviga su altre immagini, e il testo corrente di ogni immagine viene mostrato, se presente. Scrivere un nuovo testo e premere [Applica] per rendere la modifica permanente. Se occorre scrivere lo stesso testo (o quasi) in diverse immagini, si può usare copia/incolla. Si può lasciare aperta questa finestra, in un angolo dello schermo, anche nel modo Slide show. I commenti associati a un'immagine possono essere usati (ricercati) dalla funzione di Ricerca immagini.


Modifica titolo
Funziona esattamente come "Modifica commenti", ma il testo riguarda la chiave IPTC "Caption-Abstract".


Etichette

I file immagine possono avere etichette di classificazione (categorie, parole chiave) associate. Queste possono essere usate per ricercare in una grande collezione quelle immagini con le etichette desiderate. Etichette tipiche sono: il soggetto principale della foto, l'evento, il luogo, le persone, e così via. Queste etichette risiedono nel campo "keywords" dei metadati IPTC. Le etichette sono solitamente composti di una sola parola, ma una breve frase contenente spazi o altri delimitatori può essere usata. Virgole e punti e virgola sono riconosciuti internamente come separatori di etichette, e quindi non devono essere usati. Un'etichetta composta come "Panorama d'America" è permessa, ma sarebbe meglio usare due etichette distinte per avere maggiore flessibilità, perché così sarebbe possibile cercare immagini aventi una sola delle due etichette o entrambe.

Si può usare un albero o gerarchia di directory per organizzare fisicamente le immagini, per esempio nomi di directory descriventi l'anno, o il luogo, o altri schemi. Si può usare il nome di file come soggetto principale della foto. Tali schemi organizzativi sono utili ma non indispensabili: è anche possibile buttare tutte le foto in una directory gigantesca e usare la numerazione progressiva generata dalla macchina fotografica. A prescindere dall'organizzazione fisica, le etichette permettono di organizzare le stesse immagini in viste multiple: tutte le foto di una persona attraverso tutti gli anni, tutti i luoghi, tutte le occasioni, eccetera. Tutte le immagini aventi la stessa etichetta possono essere trovate velocemente e mostrate in una galleria di miniature, dove è possibile sceglierene un insieme più ristretto per vederle, modificarle, cambiare loro le etichette.

Se i nomi di file e directory sono stati scelti accuratamente, si può continuare a usarli in modo produttivo: si possono eseguire ricerche usando quei nomi, da soli o in aggiunta alle etichette. Non c'è bisogno di duplicare informazioni già presenti. Riferirsi a "Ricerca immagini" più sotto.

Le immagini possono avere una data (data della foto) che viene estratta dai dati EXIF o impostata manualmente. Le immagini possono avere un punteggio (a stellette) per l'importanza del contenuto o per la loro qualità. Anche le date e il punteggio possono essere usati come criterio di ricerca.

Limitazioni e consigli pratici
I seguenti sono i limiti imposti per le etichette; sono fissati durante la compilazione di Fotoxx e potrebbero essere facilmente innalzati, ma ritengo che siano abbastanza grandi da soddisfare le applicazioni pratiche:

     o   lunghezza massima di una singola etichetta: 50 caratteri
     o   lunghezza massima complessiva di etichette per un file: 1000 caratteri
     o   numero massimo di etichette per una singola categoria: 50.000 caratteri
     o   limite massimo interno per le etichette: 50.000 caratteri
     o   numero massimo di etichette per una ricerca: 200 caratteri
     o   numero massimo durante l'aggiunta in blocco di etichette: 200 caratteri

Il limite pratico per il numero totale di etichette è 200..500. Oltrepassare questo intervallo è possibile, ma porta a qualche problema pratico: la finestra che mostra le etichette disponibili sarà grande e tali etichette saranno difficili da individuare, anche se sono ordinate per categoria e all'interno di ogni categoria, e l'operazione di "punta e clicca" per aggiungere etichette diventerà più impegnativa. Se le etichette sono definite grossolanamente e in numero inferiore, i risultati di una ricerca saranno più numerosi, ma una ulteriore raffinazione della ricerca all'interno delle miniature è comunque piuttosto veloce. L'organizzazione fisica dei file viene preservata nella galleria (file che risiedono nella stessa directory appariranno affiancati nella galleria). Insomma, il mio consiglio per il fotografo non professionista è di usare poche, generiche etichette.


Modifica etichette


Per assegnare etichette all'immagine corrente, usare il menù Info->Modifica etichette.
Le etichette correnti sono mostrate in "Etichette attuali". Le etichette disponibili sono mostrate nel riquadro inferiore in "Etichette definite". Tali etichette possono essere aggiunte all'immagine cliccandole. Un'etichetta assegnata si può togliere cliccandola, dentro il riquadro "Etichette attuali". Le etichette aggiunte recentemente sono mostrate in "Etichette recenti"; questa è una comodità per aggiungere le stesse etichette a molte immagini, in previsione che molte etichette possano essere usate ripetutamente: anche queste si aggiungono cliccandole. La data dell'immagine, se disponibile, viene mostrata nel campo apposito; può essere immessa se mancante, o modificata. Si può usare il formato completo AAAAMMGG (anno/mese/giorno) o le forme più brevi AAAAMM e AAAA. Durante una ricerca il mese e il giorno, se non presenti, sono assunti come 01/01 in un confronto verso il limite inferiore, e 31/12 verso il limite superiore. Il pulsante [Utilizza ultima] riempie il campo data con l'ultima data immessa o mostrata: serve a datare facilmente una serie di immagini.
Si può assegnare un punteggio opzionale per la foto. Questa finestra di dialogo rimane aperta se si passa a un'altra fotografia, e i campi vengono aggiornati con i dati della nuova foto. Il pulsante [Applica] scrive le informazioni nel file dell'immagine e nel database usato per la ricerca.


Gestione etichette

Per creare etichette nuove, usare il menù Info->Gestione etichette. Si possono anche usare categorie per organizzare le etichette e trovarle più facilmente; le categorie sono opzionali e non hanno alcun ruolo nell'assegnamento o la ricerca: solo le etichette vengono memorizzate nell'immagine, non la categoria corrispondente. Categorie tipiche sono Persone, Luoghi, Cose, Eventi, Scenari, Palazzi, Arte e simili. Per creare un'etichetta e una categoria, immettere i rispettivi nomi e cliccare [Crea]. La categoria può essere omessa, e in tal caso l'etichetta apparterrà alla categoria "nocatg". Per assegnare un'etichetta a una categoria differente, cliccare prima la categoria (le scritte in grassetto) o scriverne il nome, poi cliccare l'etichetta e quindi premere [Crea]. l'etichetta verrà spostata dalla vecchia alla nuova categoria. Per eliminare un'etichetta, cliccarla e premere [Elimina]. La finestra viene aggiornata per riflettere i cambiamenti; se anche la finestra di modifica etichette è aperta, pure quella verrà aggiornata: si possono quindi tenere aperte entrambe, se occorre creare o cambiare etichette in vista di un loro uso immediato. Etichette presenti nelle immagini ma non assegnate ad alcuna categoria appariranno nella sezione "nocatg".

Nota:
appena creata, un'etichetta sarà aggiunta al fondo della propria categoria. Al riavvio successivo di Fotoxx, tutte le categorie e i loro contenuti saranno ordinati alfabeticamente, eccetto "nocatg" che è sempre ultima. Inoltre, un'etichetta scompare dalla lista se nessuna immagine la utilizza.


Aggiungi etichette a più immagini
Quando si aggiungono etichette a un gran numero di immagini aventi in comune molte delle loro etichette, usare questa procedura può velocizzare l'operazione. Usare, nella finestra di dialogo, il pulsante [Seleziona i file] per aprire una galleria dalla quale selezionare i file (spiegazione). Dopo aver selezionato i file, specificare le etichette da aggiungere alle immagini scegliendole con un clic dal riquadro "Etichette definite". Se occorre un'etichetta non ancora definita, scriverla nel riquadro e cliccare [Crea etichetta] per aggiungerla alla lista. Infine, cliccare [Procedi] per aggiungere le etichette alle immagini.


Cancellazione in blocco di etichette
Questa funzione si usa per eliminare una singola etichetta dal molte immagini, o rimpiazzare un'etichetta con un'altra. Nel dialogo, immettere l'etichetta da eliminare e, opzionalmente, l'etichetta di rimpiazzo. Usare il pulsante [Seleziona i file] per aprire una galleria da cui selezionare le immagini (spiegazione). In alternativa, selezionare [cerca tutti i file] per specificare che la cancellazione o sostituzione interesserà tutti i file trovati nel database del programma, che abbiano l'etichetta specificata (similarmente alla funzione di ricerca).


Ricerca immagini


Esempio:selezione di immagini del 2005 o successive, con 4 stelle o più, con etichetta "buildings" o "monuments" (costruzioni e monumenti), e contenenti "dresden" nel nome di file o di directory.

Un apposito indice viene usato per la ricerca, che la rende molto veloce (migliaia di immagini al secondo vengono analizzate). L'indice viene generato da etichette, titoli, date e punteggi salvate nell'immagine stessa (metadati EXIF e IPTC). Quindi si può spostare file e directory senza perdere informazioni - occorre solo rigenerare l'indice per la ricerca, che è semplice e rapido. Vedere il menù Strumenti->Sincronizza file.

Usare la funzione di ricerca immagini per trovare immagini recanti le etichette desiderate, data, punteggio, commenti, titoli o nomi di file/percorsi. Le etichette definite vengono mostrate e possono essere selezionate cliccandole. Usare le caselle "all" o "any" di ogni campo per indicare se tutte (all) o una qualunque (any) delle parole specificate deve essere presente in un'immagine affinché questa sia selezionata. Premere poi [Prosegui] per iniziare la ricerca. Le immagini corrispondenti vengono mostrate in una galleria di miniature. Scegliere le immagini da vedere o modificare cliccando sulle miniature. L'insieme dei risultati della ricerca viene usato dai pulsanti [Prec.] e [Prossima]. Se un'immagine viene caricata usando la funzione File->Apri un'immagine (o il pulsante [Carica da file]), allora l'insieme corrente di immagini (la galleria) viene sostituito dall'elenco delle immagini della directory da cui si è prelevata la nuova foto.


Un intervallo di date può essere usato, per restringere ulteriormente la ricerca alle immagini all'interno del periodo richiesto. Il formato è AAAAMMGG (yyyymmdd). Le immagini rientrano nell'intervallo se hanno una data corrispondente o successiva alla prima data, se specificata, e uguale o precedente alla seconda data, se specificata. Se la data di una foto omette mese e giorno, allora si assume 01/01 per la data d'inizio periodo, e 31/12 per la data di fine periodo.

Una coppia di punteggi può essere specificata per restringere la ricerca alle immagini aventi un punteggio compreso nei due limiti specificati. Se si omette il primo limite, si assume zero; se si omette il secondo, si assume infinito.

Nomi di cartelle e file possono essere usati come termini di ricerca. Immettere nel campo "nomi dei file" un qualsiasi numero di nomi separati da spazi. I caratteri jolly ("*") sono impliciti prima e dopo ogni parola, e possono comunque essere scritti anche nel mezzo di ognuna. Quindi, una specifica come "egitto cairo" troverebbe tutte le foto ove il nome di file o di directory contenesse una o l'altra di queste parole, perché ogni nome di file o di cartella viene comparato con ognuno dei due termini (prima con "*egitto*" e poi con "*cairo*"). Usando come specifica "egitto*cairo" il risultato è diverso, perché ogni nome di directory e file viene comparato una volta sola con la singola parola immessa, e solo le immagini che contengono entrambe le parole "egitto" e "cairo", in quell'ordine, soddisfano il la richiesta. Il metodo di confronto è semplice: un asterisco ("*") corrisponde a qualsiasi sequenza di caratteri, ovunque nel nome completo di percorso del file di immagine. Il confronto è insensibile alla differenza fra maiuscole e minuscole. Se il termine da cercare contiene spazi, usare due virgolette intorno a esso (altrimenti verrebbe inteso come due parole separate): per esempio una ricerca su [città del capo] troverebbe qualsiasi file che contiene uno dei tre termini, mentre ["città del capo"] trova solo i file che contengono esattamente quella scritta.

La ricerca può basarsi anche su titoli e commenti (vedere Modifica titolo e Modifica commenti). Immettere i termini da cercare nel campo "Ricerca testo", separati da spazi. Questi termini verranno comparati con ogni parola del titolo e del commento di ogni immagine, e le corrispondenze verranno selezionate. Anche qui si può usare il carattere jolly "*".

Le scelte "all" (tutti) ed "any" (qualsiasi) si applicano a ogni campo di ricerca: etichette, testo, e nomi di file. Si può specificare, per ogni campo di ricerca, se i termini all'interno devono corrispondere tutti (ALL) o almeno uno (ANY). Per esempio, se il campo etichette contiene [egitto cairo] ed "any" è selezionato, le immagini corrispondono se contengono almeno una delle due etichette; se "all" è selezionato, devono contenerle entrambe.

Si possono usare commenti, titoli e nomi di file e directory come alternativa alle etichette. L'uso produttivo di etichette può richiedere pianificazione, organizzazione e grande attenzione ai dettagli, e di conseguenza molto tempo. Anche la manutenzione può risultare difficile se si tratta di centinaia di immagini. Commenti e nomi di file sono molto più semplici, anche se meno precisi: basta nominare il file con il soggetto chiave, e aggiungere commenti o titolo con parole descrittive e adeguate. Non serve in questo caso avere un sistema elaborato di etichette, e le revisioni sono più semplici. Il sistema delle etichette ha il vantaggio che una lista completa di quelle disponibili è mantenuta automaticamente e mostrata quando si esegue una ricerca, e aggiungere etichette a una nuova immagine è un'operazione semplice con il clic del mouse.

Se sono state aggiunge, rimosse o spostate immagini con metodi estranei a Fotoxx, assicurarsi di eseguire la procedura Strumenti->Sincronizza file per aggiornare l'indice di ricerca. La procedura è veloce se si usa il modo incrementale e meno di 1000 immagini sono coinvolte.


Vedere informazioni (breve)
Vedere informazioni (lungo)
Queste due funzioni mostrano i metadati (dati aggiuntivi) dell'immagine corrente, se disponibili. I metadati EXIF contengono data e ora della foto, velocità dell'otturatore, lunghezza focale, dimensione dei pixel eccetera. Le macchine digitali memorizzano questi dati dentro l'immagine. I metadati IPTC contengono etichette (aggiunte con Fotoxx, Photoshop o altri programmi) e titoli (spesso per immagini pubblicate). Se un'immagine viene modificata e poi salvata, i metadati vengono aggiornati e salvati nella nuova immagine.

La funzione Vedere informazioni (breve) mostra i dati più importanti, inclusi data e ora, esposizione, lunghezza focale (reale ed equivalente a 35 mm), etichette aggiunte dall'utente e punteggio, commenti, titolo, e una cronistoria delle manipolazioni che Fotoxx ha applicato all'immagine. La funzione Vedere informazioni (lungo) mostra tutti i dati disponibili.

Fotoxx usa i seguenti metadati EXIF / IPTC:
    Nome chiave (Key Name)
Uso di / con Fotoxx
    Date/Time Original
Modifica etichette - Data immagine
    Keywords
Modifica etichette - Etichette attuali
    Rating
Modifica etichette - Valutazione (punteggio)
    User Comments
Modifica commenti
    Caption-Abstract Modifica titolo
    Edit Status
Cronistoria delle manipolazioni eseguite con Fotoxx
    (altro)
Modifica informazioni / Elimina informazioni


Modifica informazioni
Un valore specifico dei metadati (metadata ID / key) può essere aggiunto (se legittimo) o modificato. Immettere il nome del metadato (chiave / key) e cliccare [Prendi] per prelevare il valore corrente, se esiste. Immettere il nuovo valore e cliccare [Salva] per aggiornare il dato. Si può immettere la chiave in minuscolo e senza spazi, cioé il dato EXIF "User Comment" può essere scritto più facilmente come "usercomment". Questa finestra può essere lasciata aperta: il valore della chiave specificata sarà aggiornato automaticamente ogni volta che una nuova immagine viene caricata, e può essere modificato e salvato, se desiderato.


Elimina informazioni
Questa funzione permette di eliminare un valore (chiave) specifico dei metadati, oppure tutti i metadati insieme. Immettere un nome di chiave in minuscolo, senza spazi, cioé "usercomment" per indicare la chiave EXIF "User Comment".


Menù Seleziona

Introduzione
Le funzioni di editing si applicano di solito all'intera immagine, ma è possibile modificare solo una parte dell'immagine e lasciare il resto invariato. Se un'area più piccola è stata selezionata, le funzioni di Ritocco e Arte riguarderanno solo quell'area. Altre funzioni ignorano la selezione. Un'area può essere selezionata prima di cominciare una funzione di modifica, oppure anche durante. L'area selezionata è attiva immediatamente; i ritocchi precedenti sono mantenuti, e i ritocchi successivi si applicheranno solo entro l'area. Se un'altra funzione di manipolazione viene richiamata, l'area selezionata rimane attiva, così è possibile eseguire una serie di modifiche sull'area.



Seleziona


Con la finestra di dialogo, se c'è già un'area selezionata, il suo contorno verrà mostrato. Si può continuare a modificare tale area o usare [Elimina] per scartarla e iniziare una nuova area. Selezionare uno dei sei metodi (spiegati dopo) e procedere alla definizione. Togliere la spunta da "Abilita mouse" per sospendere l'operazione e rendere disponibile il mouse per ingrandire o spostare l'immagine su schermo. Rimettere la spunta per riprendere l'operazione. Il pulsante [Nascondi] rimuove il contorno (per migliorare la visibilità dell'immagine e la dissolvenza dei margini). Usare il pulsante [Visualizza] per mostrare di nuovo il contorno. La finestra può essere chiusa e riaperta successivamente per riprendere a modificare la stessa area o definirne una nuova.

Ci sono cinque metodi (descritti sotto) per racchiudere uno o più zone che apparterranno all'area finale. Questi spazi chiusi saranno soggetti a modifiche future (luminosità, colore, ecc.). Questi metodi possono essere usati in qualunque ordine per definire zone da includere o eslcudere. Sceglierli con gli appositi bottoni:

    Rettangolo: trascinare il mouse per disegnare una zona rettangolare.
    Ellisse: trascinare il mouse per racchiudere una zona ellittica.
    Mano libera: cliccare per disegnare linee, o trascinare per disegnare curve, in modo da racchiudere uno spazio.
    Segui bordi: cliccare lungo il bordo di un oggetto per disegnare linee che seguano un contorno, o trascinare per disegnare a mano libera.
    Selezione col mouse: seleziona una piccola zona intorno al mouse, e si espande alle aree adiacenti aventi colori simili.

I paragrafi successivi spiegano in dettaglio ogni metodo.

Rettangolo: trascinare il mouse da un angolo a quello opposto dell'area da selezionare. Un rettangolo viene disegnato per racchiudere l'area. Cliccare col destro per cancellare e riprovare. Ripetere il processo per selezionare più aree rettangolari.

Ellisse: è identico al rettangolo, ma disegna un ellisse inscritto nel rettangolo.

Disegno a mano libera: trascinare il mouse (pulsante sinistro) per disegnare a mano libera una curva, oppure cliccare per creare una linea dall'ultimo punto a quello cliccato. Continuare intorno al bersaglio fino a circondarla di curve e linee interconnesse. Cliccare con il destro per rimuovere linee precedenti (errate) e ridisegnarle. Un clic col destro rimuove linee precedenti fino a 50 pixel; cliccare col destro ripetutamente per rimuovere ancora di più. Una nuova linea creata cliccando si connette sempre all'estremo della linea precedente. Una nuova linea creata trascinando si connette a quella precedente se iniziata vicino all'estremo; se iniziata più distante, una linea sconnessa verrà creata. Si può iniziare una curva da distante, e dirigerla all'indietro per incontrare la vecchia linea. Se una linea creata cliccando si connette automaticamente a un punto non desiderato (cioé, non si vuole connetterla all'ultima linea), cliccare col destro e usare il trascinamento per iniziare una nuova sequenze di linee. Un trascinamento col bottone destro può essere usato per cancellare piccoli segmenti: puntare col destro vicino a una linea da aggiustare, poi trascinare.
Alla fine dell'operazione, un'area deve essere chiusa interamente, senza crepe. Queste interruzioni possono essere difficili da trovare e correggere, perciò lavorare a ingrandimento 100% e prestare attenzione. Una serie di linee connesse automaticamente non lasceranno interruzioni, ma una deviazione da questa sequenza probabilmente sì. Per ridurre l'eventualità, usare sormonti o incroci in modo deliberato quando si connettono le linee.

Segui bordi: pixel molto contrastati (probabilmente bordi di oggetti) tra l'ultimo punto immesso e la posizione cliccata vengono trovati e connessi. Funziona bene su contorni puliti non troppo irregolari. Contorni frastagliati e confusi non funzionano bene e il disegno a mano libera può essere richiesto per avere maggiore precisione. Le regole per connettere le linee sono le stesse viste prima. Il trascinamento del mouse invece dei clic funziona come il disegno a mano libera, così si possono usare i due metodi insieme.


Selezione col mouse:il campo [Raggio del mouse] definisce un cerchio intorno al puntatore del mouse. Cliccare il bottone sinistro nell'immagine per indicare un gruppo di pixel come riferimento. Entro la [Distanza di ricerca] dal mouse, qualsiasi pixel che abbia un colore simile a un pixel contenuto nel cerchio verrà selezionato. Il valore [Distanza di ricerca] viene moltiplicato per il [Raggio del mouse] per definire un cerchio entro il quale cercare pixel simili. La similitudine richiesta è impostata da [Corrispondenza colore], dove 100 indica similitudine perfetta. Un raggio maggiore o una similarità inferiore selezioneranno più pixel. Se il mouse è trascinato o cliccato dentro l'area selezionata, questa verrà espansa per includere i pixel residenti dentro il raggio. Trascinare su nuove aree da includere, o sopra isole escluse da includere. Notare che l'area si espande. Se si seleziona troppo, cliccare col destro per rimuovere l'ultima selezione; ripetere per rimuovere ulteriori selezioni. Ridurre o aumentare la similarità per avere un controllo più fine: la selezione si espanderà più lentamente e rimarrà più vicina alla posizione del mouse. Il raggio della selezione è limitato a 3 volte il raggio del mouse; questo significa che un raggio piccolo può essere usato per inseguire un bordo e selezionare pixel vicini al bordo con buona precisione. Passare a un raggio più ampio per selezionare aree più grandi dopo che il lavoro fine è stato completato. Se l'opzione "confinamento" è abilitata, allora i pixel già selezionati agiranno come una barriera alla propagazione della nuova selezione. Questo talvolta è utile, per esempio se una selezione esistente è corretta e si vuole estenderla all'interno o da un'altra direzione. Il pulsante destro del mouse funziona come quelli sinistro ma de-seleziona, sempre basandosi sulla similarità di pixel vicini. Probabilmente serve un po' di esercizio per usare efficientemente questa modalità.

Abilita mouse: se contrassegnata, questa casella impone che il mouse sia gestito dall'operazione in corso (in questo caso, operazioni di selezione). Se la casella non è contrassegnata il mouse può essere usato per variare l'ingrandimento o lo scorrimento dell'immagine. Lavorando con aree più grosse della loro porzione visibile, si può alternare tra la selezione e la variazione della vista.

Larghezza di sfumatura: modifiche fatte entro un'area definita possono essere miscelate con la parte d'immagine all'esterno su una distanza chiamata "larghezza di sfumatura". All'esterno del bordo della selezione, l'immagine rimane invariata. Alla distanza impostata, verso l'interno dell'area, l'immagine viene manipolata. A distanze intermedie, i pixel vengono modificati parzialmente: risultano in una miscela tra l'immagine originale e il risultato teorico della manipolazione, con una gradazione relativa alla distanza. L'effetto è una sfumatura di transizione tra l'immagine originale e la parte modificata. Usare questo campo per selezionare la larghezza di questa striscia per l'operazione corrente e quelle successive. Una larghezza di zero imposta un margine assoluto per l'area di selezione. Incrementando la larghezza si ottengono modifiche più dolci e transizioni meno distinguibili. Cambiare questo valore per la prima volta dopo aver impostato un'area di selezione comporta il ricalcolo della distanza per ogni pixel entro l'area. Ciò è normalmente veloce (pochi secondi), ma può richiedere diversi minuti se l'area è grande e ha una geometria complessa (un contorno molto lungo). Quando un'area viene modificata o invertita, il calcolo eseguito diventa inutile e deve essere ripetuto, se si vuole la sfumatura. Se il bordo di un'area sta entro i 4 pixel dal bordo dell'immagine, non viene più considerato come bordo per la sfumatura. Se un'area contiene una porzione del bordo dell'immagine, e non si vuole sfumare lungo questo bordo (questo è il caso normale), assicurarsi che il bordo della selezione sia strettamente vicino (coincidente) con il bordo dell'immagine.

Visualizza / Nascondi: usare [Nascondi] per nascondere il contorno della selezione. Ciò è utile quando si usa una funzione di modifica, per vederne meglio gli effetti senza l'interferenza delle linee di selezione. Usare [Visualizza] per mostrare di nuovo il contorno della selezione e riprendere a variare l'area.

Colore: alterna il colore usato per disegnare i bordi dell'area, tra rosso, verde e nero.

Termina: quando si ha finito di selezionare gli spazi chiusi, usare questo pulsante per completare il processo. Una finestrella chiederà di cliccare dentro ogni spazio chiuso, in sequenza. Questa azione esegue una ricerca di tutti i pixel all'interno dello spazio chiuso; tali pixel vengono riconosciuti e ricordati. Lo spazio chiuso viene temporaneamente colorato di modo che si possa vedere esattamente quali parti dell'immagine sono selezionate. La finestra di dialogo mostrerà lo stato dell'elaborazione: "successo" o "il contorno è discontinuo". Se c'è un'interruzione nel contorno, viene fatto un tentativo per mostrare dove essa si trova: si vedrà un linea che parte dallo spazio colorato per incontrare il lato di un rettangolo immaginario che racchiude la porzione. Può essere possibile seguire questa linea fino all'interruzione, ma se l'area è complessa trovare la crepa può essere difficile. Ogni uso di [Termina] produrrà un risultato differente che può condurre alla crepa. Ispezionare attentamente il contorno dell'area, vicino al buco, e usare [Termina] di nuovo. Un'area non è funzionante fino a che non è terminata con successo. Qualsiasi area chiusa può essere selezionata, anche se non disegnata direttamente: per esempio, selezionando un'area a forma di ciambella con un buco al centro, sarà poi possibile includere anche il buco, fin tanto che esso è delimitato da pixel inclusi in una selezione.

Invert: questa funzione inverte l'area esistente: l'immagine intera viene selezionata, eccetto la parte che era selezionata in precedenza. Usando la funzione due volte di file si ritorna alla selezione precedente. L'inversione dell'area comporta il ricalcolo della sfumatura, se questa è richiesta.

Abilita / Disabilita: disabilita l'area corrente senza cancellare però i suoi dati, di modo che possa essere riattivata in seguito. Questo permette di alternare modifiche entro la selezione e sull'immagine intera.

Elimina: rimuove la selezione in modo permanente.


Seleziona -> Visualizza / Nascondi
Mostra o nasconde il contorno della selezione corrente. Nasconderlo è utile durante il ritocco, poiché è più facile giudicare l'effetto delle modifiche. Questa scelta di visualizza/nascondi è disponibile anche nella finestra di dialogo Seleziona.


Seleziona -> Abilita / Disabilita
Abilita e Disabilita l'area (selezione) corrente (mantenendo i dati per poterla riattivare in seguito). Permettono di alternare modifiche entro la selezione e sull'immagine intera. Le funzioni sono disponibili pure nella finestra di dialogo della Seleziona.


Inverti
Inverte la selezione corrente: l'immagine intera è selezionata, tranne l'area/selezione corrente. Usando la funzione due volte di fila si torna alla situazione di partenza. Se è stata richiesta una larghezza di sfumatura, il calcolo va ripetuto. La funzione è disponibile anche nella finestra di dialogo Sleziona.


Elimina
Elimina permanentemente l'area/selezione. E' disponibile anche nella finestra Seleziona.


Copia / Incolla

Copia:
la selezione corrente viene copiata (ricordata) in memoria.

Incolla:
l'area salvata precedentemente (i pixel copiati con la funzione Copia) viene incollata nell'immagine. Può essere spostata trascinandola con il mouse; Usare i pulsanti [Resize] e [Angolo] per variare dimensione e angolo di rotazione. Impostare il cursore [Edge blend] se si desidera una sfumatura lungo il bordo dell'oggetto incollato. Quando finito cliccare il pulsante [Fatto]. L'area appena incollata diventa la nuova selezione: le successive modifiche saranno confinate entro quest'area, che può essere cancellata, disabilitata o modifcata (in particolare la Larghezza di sfumatura).


Carica da file / Salva
Se un'area di selezione è attiva o è stata copiata tramite Seleziona->Copia, può essere salvata in un file immagine usando Seleziona->Salva (occorrerà inserire un nome di file <nomefile>). Due file sono salvati: l'immagine (i contenuti dell'area) nel file <nomefile>.tiff mentre le informazioni di trasparenza nel file <nomefile>.info. Questi file si troveranno nella directory /home/<utente>/.fotoxx/saved_areas/. Usare Seleziona->Carica da file per scegliere un'area salvata (scegliere il file TIFF), che sarà immessa nell'immagine dove potrà essere spostata e variata nell stesso modo visto per Copia/Incolla.



Immagine intera

E' talvolta utile applicare un ritocco in modo controllato dalla luminosità, per esempio applicare la riduzione del disturbo su aree scure senza toccare quelle chiare. Per fare questo, usare il menù Seleziona->Immagine intera. Scegliere [Luminosità] o uno deicolori RGB come controllore. Il grafico editabile controlla come i ritocchi successivi verranno applicati all'immagine. L'asse orizzontale segue la luminosità di un pixel da scuro a chiaro (o uno dei colori RGB) da 0 a 100%. L'asse verticale governa quanto forte un ritocco viene applicato al pixel corrispondente. Un valore piccolo (curva bassa) minimizza l'effetto, e un valore grande lo massimizza. Per esempio: applicare la mappatura di tonalità soprattutto sui pixel scuri: usare Seleziona->Immagine intera e trascinare la curva in modo che sia alta verso sinistra (pixel scuri) e bassa nel centro e a destra. Poi, usare Ritocco->Mappa tonalità per applicare l'effetto alle aree scure. Si possono modificare entrambe le curve mentre si osserva il risultato.



Seleziona e modifica

Usare questa funzione in combinazione con una di ritocco. Specificare un raggio per il mouse e i fattori di potenza per il centro e il bordo distante dal centro. Poi, richiamare una funzione di ritocco se non già attiva. Il puntatore sarà circondato da un cerchio dal raggio specificato. Quando il mouse (puntatore) viene trascinato sopra un'area dell'immagine, la funzione di ritocco viene applicata all'interno del cerchio. L'intensità del ritocco è regolata dai fattori di forza (centro e bordo). Di solito si usa un valore grande al centro e zero al bordo, indicando che l'intensità del ritocco sarà massimo al centro e sfumerà gradualmente fino a zero al bordo. Trascinando il mouse sulla stessa area ripetutamente, le modifiche vengono lentamente accumulate. Per esempio, se la funzione è Luminosità e colore, e la curva è impostata a un valore alto, l'immagine verrà lentamente illuminata nella zona dove il mouse viene trascinato. Questo si chiama "Dodge and burn" in altri programmi, ma in Fotoxx anche altre funzioni possono essere usate, per esempio mappatura del tono o sfocatura. Usare [Annulla] e [Ripeti] per controllare i cambiamenti, i quali possono essere difficili da vedere a prima vista. Impostare [Forza/Centro] a 100 per produrre cambiamenti veloci (con controllo poco preciso). Trascinare il bottone destro del mouse per ridurre il ritocco o, insistendo, per cancellarlo del tutto. Quando finito con una funzione di ritocco in una o più zone, usare il pulsante [Fatto] per completare la modifica. Usare il pulsante [Azzera area] per escludere l'area attiva che è stata lasciata fuori dal trascinamento.  Se si lascia l'area attiva e s'inizia una nuova funzione di ritocco, i risultati saranno impredicibili. Una procedura suggerita è: 1 - richiamare [Seleziona e modifica]; 2 - richiamare la funzione di ritocco con i suoi parametri iniziare (l'effetto sull'immagine sarà nullo poiché nessun trascinamento è stato eseguito); 3 - trascinare il mouse sulle zone d'interesse e osservare il risultato; 4 - regolare le impostazioni della funzione di ritocco; 5 - alternare i due passi precedenti. Questo metodo di "disegnare" un ritocco in modo incrementale può migliorare le aree desiderate in fretta e facilmente. Funziona con qualsiasi ritocco che può usare la selezione; le più utili sono Luminosità e colore, e Mappa tonalità.


Menù Ritocco


Bilanciamento del bianco

Questa funzione è un modo facile per rimuovere una predominanza di colore, quando l'immagine ha una sfumatura generale verso il blu o il rosso. Avviata la funzione, cliccare un punto dell'immagine che non dovrebbe essere colorato: un punto bianco o grigio. Se il punto cliccato ha un colore diverso da bianco o grigio, sarà considerato come misura del falso colore generale, e tale quantità di colore sarà sottratta dall'immagine intera. Si può cliccare diverse aree e vedere l'impatto istantaneamente. Cliccare [Fatto] quando soddisfatti, o [Annulla] per rinunciare.



Trasforma in negativo
Usare questa funzione per generare un negativo in bianco e nero o a colori, o convertire un negativo in un positivo.
Selezionare unodei quattro bottoni:
    black/white positive - converte una foto a colori in una in bianco e nero
    black/white negative - converte in bianco e nero e poi inverte
    color positive - non ha effetto: annulla le altre trasformazioni
    color negative - genera il negativo a colori (rimpiazza ogni colore RGB con il suo complementare)
Color negative: ogni colore RGB color viene rimpiazzato dal "massimo meno il valore attuale". Se i colori RGB (in % sul massimo) sono 20/40/60, il negativo avrà 80/60/40. Eseguire l'operazione due volte riporta ai colori originali. L'operazione genera i colori complementari: il rosso diventa ciano, il verde magenta, e il blu giallo.



Normalizza la luminosità

Questo è un metodo facile e veloce per compensare una limitazione comune in fotografia: non c'è abbastanza escursione di luminosità per mostrare bene i dettagli in ogni area. Questa funzione cerca dove ci sono troppi pixel con luminosità abbastanza simile e la distanzia, compremendo i valori di altre aree per fare posto. Tecnicamente, la distribuzione di luminosità viene fatta più uniforme (appiattita). Muovere il cursore osservando l'immagine, che può ritardare un momento. Alcune immagini mostreranno buoni risultati, altre forse no, o anche peggiorare. Usare questa funzione entro una selezione è spesso molto efficace; una sfumatura ([Larghezza di sfumatura] in Seleziona) può essere necessaria per nascondere il contorno dell'area modificata.



Luminosità e colore

Si usa per cambiare luminosità, contrasto, saturazione e bilanciamento fra i colori (relativo ai livelli RGB).
Si possono variare i livelli in funzione della luminosità dei pixel dell'immagine originale; per esempio, si può aumentare la saturazione nelle aree più scure lasciando intatte quelle più chiare.
Vi sono cinque curve per i cinque attributi di luminosità, saturazione, e bilanciamento (livelli di rosso, verde e blu). I bottoni selezionano quale curva si vuole vedere e variare. La curva rappresenta un valore (in verticale sull'asse Y) per ogni livello di luminosità (in orizzontale sull'asse X). La posizione verticale centrale è neutra - non modifica nessun valore, mentre una curva spostata più in alto amplifica l'attributo, e più in basso lo riduce. Inizialmente la curva è piatta, e centrata verticalmente: il risultato è che l'immagine non viene alterata.
Le curve possono essere trascinate con il mouse. Un punto di ancoraggio (quadratino nero) viene aggiunto alla curva quando viene tirata, e diventa un vincolo per i trascinamenti successivi: la curva continuerà a passare attraverso questo punto anche se altre zone della curva si spostano. Anche i punti di ancoraggio possono essere trascinati, o cancellati con un click del pulsante destro.
L'immagine si aggiorna immediatamente quando si ritocca la curva: semplicemente trascinare la curva e osservare il risultato fino al raggiungimento del risultato. Per esempio, per aumentare il contrasto, abbassare la curva sulla sinistra e/o alzarla sulla destra. Per schiarire le zone scure, sollevare la parte sinistra della curva. I pulsanti [+++], [+-] eccetera possono essere usati per traslare la curva in diversi modi.
La curva di luminosità modifica tutti i livelli RGB con uno stesso fattore (proporzionale). La saturazione cambia il livello (R, G o B) dominante in una direzione, e gli altri due nella direzione opposta, cosicché la luminosità non cambia ma la tinta sì. Le curve dei tre colori cambiano un colore per volta. Per esempio, se le aree scure hanno una tendenza al rosso, abbassare la parte sinistra della curva del rosso.



Mappatura della luce

Questa funzione varia la luminosità lungo l'immagine, con direzione e ampiezza determinabili da curve modificabili. Si può usare ciò per compensare illuminazioni diseguali o vignette (angoli bui).
La finestra di dialogo mostra due curve modificabili, orizzontale e verticale. La curva orizzontale regola la luminosità orizzontalmente, e quella verticale verticalmente. Trascinare le curve nelle direzioni segnate con "+" e "-" per aumentare o diminuire la luminosità nelle zone corrispondenti. Per rimuovere l'effetto vignetta dagli angoli, spostare le quattro estremità delle curve verso i segni "+", o anche spostando il centro delle curve verso il "-". Per illuminare l'angolo in alto a destra, trascinare l'estremo destro della curva orizzontale verso l'alto, e l'estremo superiore della curva verticale verso destra, come mostrato nell'immagine qui sopra. Se l'effetto viene applicato a una selezione invece che all'intera immagine, le scale si riferiscono al rettangolo che racchiude la selezione. E' quindi possibile selezionare solo una parte, e applicare l'effetto lungo quella selezione.



Expand Brightness

Questa funzione allarga l'intervallo di luminosità di una foto che non utilizza tutta l'ampiezza disponibile, eventualmente rendendola meno contrastata. Si può vedere questo nella finestra di distribuzione della luminosità. Se la distribuzione mostra scarse o assenti barre agli estremi sinistro e destro, l'immagine potrebbe beneficiare di un'espansione della luminosità. Questo si ottiene scurendo ancora le zone già scure, e schiarendo quelle chiare. Spostare i cursori per aumentare rispettivamente la quantità di scuro e di chiaro mentre si osserva l'immagine.



Mappa tonalità

La mappatura di tonalità aumenta l'intervallo di luminosità innalzando il contrasto locale. E' utile specialmente per migliorare immagini HDR, ma può essere usata anche su altri immagini. Le immagini HDR spesso sembrano "piatte" perché il contrasto tra pixel adiacenti è stato ridotto per accomodare il contrasto generale nell'intervallo disponibile. La mappatura di tonalità accresce il contrasto locale senza aumentare quello generale; si affida alla natura della visione umana: il contrasto entro un angolo piccolo viene percepito maggiormente del contrasto su una visuale più ampia. Inoltre questa funzione rivela piccoli dettagli (a basso contrasto) che sarebbero altrimenti difficili da notare.

Si possono pure usare altri metodi: regolando la curva di luminosità può aumentare il contrasto per un determinato intervallo di luminosità, eventualmente a spesa di altri. Appiattire la distribuzione della luminosità può distribuire il contrasto in modo più omogeneo. Anche un aumento di saturazione può aumentare i dettagli. Tutti questi metodi operano globalmente: tutti i pixel di un dato colore sono processati nello stesso modo. Mappa tonalità invece processa ogni pixel in modo diverso, in dipendenza della luminosità dei pixel intorno, ed è più efficace nell'aumentare i dettagli e la luminosità percepita.

Nella finestra di dialogo la curva determina quanto il contrasto locale viene aumentato, in dipendenza del contrasto locale corrente. La parte sinistra corrisponde ai pixel aventi poco contrasto, e la parte destra a quelli con molto contrasto. Sollevare la curva a sinistra per aumentare il contrasto dei pixel attualmente poco contrastati (ma questo aumenterà anche il rumore). Il cursore di [Amplificazione] regola il calcolo interno, da nessuna amplificazione del contrasto al massimo possibile; se spostato troppo a destra, l'immagine può rivelare artifatti (raggi chiari o scuri) - se ciò accade, spostare il cursore indietro fino a farli sparire.
La curva può essere trascinata con il mouse, e l'effetto sull'immagine si vede in pochi secondi, in dipendenza della sua grandezza e della potenza della CPU. Anche il cursore di amplificazione abbisogna di alcuni secondi. Se si desidera più contrasto, innalzare la curva. Se aree uniformi (come il cielo) diventano disturbate, abbassare il lato sinistro della curva per ridurre il contrasto nelle zone uniformi. In alcuni casi il metodo migliore è selezionare aree differenti e processarle separatamente, essere cioé più moderati per il cielo, e più aggressivi sui particolari come muri di pietra.



Correzione occhi rossi

Questa funzione riduce l'effetto "occhi rossi" generato dal flash. Sono disponibili due metodi. Il primo è più rapido ma non è adatto a casi difficili (quando la pupilla è rossa quanto l'intero occhio). Il secondo metodo è più versatile però richiede più cura e più tempo.

Per usare il primo metodo, cliccare col sinistro sull'occhio rosso una o più volte fino a quando si è soddisfatti. Se l'area scurita è troppo piccola o scentrata, usare un click col destro per annullare e poi riprovare. Se un occhio rosso è impossibile da correggere, cliccare col destro per annullare e passare al secondo metodo.

Il secondo metodo funziona meglio nei casi difficili, quando la differenza di colore tra la pupilla e l'iride è troppo piccola per essere rilevata automaticamente dall'algoritmo. Piazzare il puntatore sul centro dell'occhio rosso; mantenere pigiato il pulsante sinistro del mouse e trascinare in basso e a destra: un ellisse puntinato circonderà l'occhio rosso. Ripetere se necessario per avere l'occhio rosso abbastanza centrato nell'ellisse. Notare che la forma dell'ellisse dipende dalla direzione del trascinamento, che permette un più preciso contenimento del solo occhio rosso. Cliccare col sinistro, ripetutamente, mentre si osserva lo scurimento dell'occhio rosso, e smettere quando è abbastanza. Se si esagera, la pupilla può cominciare a scurirsi: cliccare il pulsante destro per annullare e ripetere se necessario.



Sfocatura immagine

Si usa per sfumare o ammorbidire un'immagine. Ogni pixel viene miscelato con i vicini per ridurre le differenze, facendo i contorni confusi. Immettere un valore per il raggio e cliccare [Applica] per osservare i risultati. Un valore piccolo miscela i pixel con gl'immediati vicini, e valori più grandi miscelano pixel più distanti. Il contributo di ogni pixel decresce con la distanza, sicché i pixel più vicini danno il maggiore contributo. Questa funzione è utile per appianare zone ruvide (specialmente la pelle). Si può anche usare una selezione per limitare l'effetto al viso o una parte di esso. Con questo metodo si possono anche ridurre effetti a bande in zone come il cielo (questo può succedere se altre funzioni di manipolazione della luminosità fanno allargare troppo la distribuzione, rendendo le transizioni di luminosità visibili).



Contrasta immagine


Questa funzione acuisce un'immagine sfuocata. Tre metodi sono implementati: riconoscimento dei bordi, maschera di contrasto, e gradiente.
Riconoscimento dei bordi: cerca i pixel adiacenti con la maggiore differenza di luminosità (contrasto) e aumenta la differenza. Ciò è ripetuto per diversi cicli, con la soglia di differenza di luminosità decrementata a ogni ciclo.
Maschera di contrasto: un metodo veloce ed efficace presente
anche in Gimp e altri programmi. Una descrizione tecnica può essere trovata con Google.
Gradiente: i pixel sono processati da sinistra a destra e dall'alto in basso. La differenza di luminosità (contrasto) tra ogni pixel e i suoi vicini precedenti (sinistra e sopra) viene accresciuta, e la luminosità viene modificata per corrispondere. Questo cambiamento di luminosità viene propagato al pixel successivo dove il processo è ripetuto.

Il metodo di riconoscimento dei bordi genera contorni più aspri dove il contrasto è alto e contorni più morbidi altrove, rendendolo buono per i ritratti (occhi evidenti, pelle liscia). Per immagini in parte contrastate e in parte sfumate (per esempio a causa di movimenti o problemi nella lunghezza di campo), il riconoscimento dei bordi agisce principalmente sulle aree confuse, laddove Maschera di contrasto può generare aloni intorno a bordi già contrastati. Il metodo del gradiente lavora più o meno bene come Maschera di contrasto per immagini leggermente sfuocate. Il valore del raggio limita la distanza massima dei pixel che sono modificati intorno a un bordo. Dovrebbe essere piccolo per immagini leggermente sfuocate e più grande per immagini più povere. La soglia sopprime i cambiamenti per i pixel a basso contrasto: un valore più alto riduce l'amplificazione delle irregolarità di basso livello.


Per il metodo di Riconoscimento dei bordi immettere i seguenti parametri:
   Cicli            numero di iterazioni
   Riduzione   riduzione della soglia di luminosità per ciclo; 80 vale 0,8
   Soglia         soglia inferiore del cambiamento di luminosità

Per il metodo di maschera di contrasto immettere i seguenti parametri:
   Raggio        distanza massima di modifica per i pixel intorno a un bordo
   Quantità     quantità di correzione: 100 = normale
   Soglia        
soglia inferiore del cambiamento di luminosità

FPer il metodo Gradiente di luminosità immettere i seguenti parametri:
   Quantità     quantità di correzione: 100 = normale
   Soglia         soglia inferiore del cambiamento di luminosità

Premere il pulsante del metodo voluto e attendere alcuni secondi il risultato. I valori d'ufficio sono quelli suggeriti come punto di partenza; regolarli e ripetere il processo fino al risultato voluto. Si può andare avanti e indietro fra i metodi per vedere quale funziona meglio per una data immagine. Si può anche usare una selezione per operare differentemente su aree diverse.



Riduci disturbi

Serve per ridurre il disturbo in fotografie prese in condizioni di luce scarsa, che mostrano disturbate le superfici uniformi. Scegliere uno dei metodi descritti di seguito. Premere il pulsante [Ridurre] ripetutamente osservando l'immagine; se si va oltre, fuoco e dettagli vengono persi. Il [Raggio] determina l'area intorno a ogni pixel che viene esaminata; un valore d'ufficio viene selezionato quanto si sceglie un metodo, ma altri valori possono funzionare meglio. Per immagini grandi, questi algoritmi possono prendere molto tempo; per risparmiare tempo, selezionare un'area adeguata e sperimentare i diversi metodi e raggi per decidere, quindi riselezionare l'intera immagine e applicare il metodo trovato. Ci sono quattro metodi diversi, e ognuno lavora con i colori RGB indipendenti.


Appiattire livelli di colore (1) I valori maggiori e minori dei pixel entro il raggio vengono moderati leggermente.
Appiattire livelli di colore (2) PI valori dei pixel entro il raggio vengono comparati con i valori Media e Sigma. Quelli scostati oltre un Sigma vengono corretti verso la Media.
Imposta luminosità media per colore
I pixel vengono impostati al valore medio dei vicini entro il raggio.
Filtro superiore per colore
Rileva gli eccessi mediante la comparazione con una banda di pixel a una certa distanza. La distanza viene incrementata a passi partendo da 1 pixel fino al limite del raggio.


Cancellazione intelligente

Questa funzione può essere usata per cancellare particolari che possono rovinare una bella foto, come elettrodotti, spazzatura per terra, cartelli e simili. L'oggetto da cancellare viene coperto con pixel presi dall'area circostante. A volte questo è molto efficace (effetti collaterali quasi invisibili), a volte no. Funziona al meglio con oggetti piccoli o stretti, cioé inferiori ai venti pixel. Il controllo [Raggio] imposta la dimensione del cerchio intorno al puntatore che definisce l'area da cancellare. Trascinare il mouse per racchiudere tutto o una parte dell'oggetto da rimuovere; col pulsante sinistro si seleziona e col destro si de-seleziona. Cliccare [Esegui cancellatura] per cancellare l'area, ricoprendola con dati presi dall'esterno della selezione. Se la selezione non era abbastanza precisa, usare [Annulla], correggere l'area e ripetere la cancellazione. Selezioni e cancellazioni ripetute si accumulano fino a che si clicca [Nuova area] per fare una nuova selezione. Le cancellazioni precedenti diventano confermate e [Annulla] agisce solo sulla selezione corrente. Come per tutte le funzioni di editing, i pulsanti della barra [Annulla] e [Ripeti] possono essere usati per controllare le modifiche. Probabilmente si lavora meglio con ingrandimenti del 200% o più. Togliere la spunta ad [Abilita mouse] per scorrere un'immagine ingrandita. Il controllo [Sfuoca] aggiunge una sfumatura per i pixel di rimpiazzo; questo può ridurre gli effetti collaterali, dato che i nuovi pixel possono essere più evidenti o avere più contrasto. Cambiare l'impostazione di [Sfuoca] e ripetere [Esegui cancellatura]. Una sfumatura di 0,5 o 1 pixel è solitamente sufficiente.



Rimozione polvere

Le immagini ricavate da scansioni possono avere molte macchioline scure: ombre della polvere sull'originale. Questa funzione può essere usata per rimuovere molte di esse. Spostare i tre cursori fino a che il massimo numero di macchioline sia colorato in rosso, e poi premere [Esegui cancellatura] per eliminarle. Cliccare [Rosso] per ripristinare la vista del rosso, per regolare ancora i cursori e premere [Esegui cancellatura]. Il cursore [Limite dimensione raggio] limita la dimensione dei possibili candidati (più è a destra, più si possono eliminare grosse macchie). il cursore [Luminosità max] imposta una soglia per ignorare macchie non abbastanza scure. Il cursore [Contrasto min] ignora le macchie che non hanno abbastanza contrasto con le loro vicinanze. Il processo è usualmente un compromesso; se le impostazioni non sono ottimali, dettagli come foglie di alberi possono essere eliminati, oppure grosse macchie possono essere lasciate dove sono. Differenti parti dell'immagine possono richiedere impostazioni diverse, per esempio il cielo può essere trattato più aggressivamente del muro di una casa. Si può semplicemente invocare la funzione più volte con diversi parametri per eliminare tutte le macchie. Oppure si possono eseguire selezioni e trattarle differentemente. Se alcune macchie sono persistenti, possono essere eliminate con la cancellazione intelligente.



Correggi pixel difettosi (fissi al bianco o al nero)

I sensori delle fotocamere possono avere difetti che mostrano singoli pixel sempre luminosi o sempre scuri; questo può affliggere on dei colori RGB o tutti e tre. Ho visto un caso dove un gruppo di 3x3 pixel erano sempre troppo rossi. Questa funzione può trovare tali pixel in una foto e ripararli sostituendoli con pixel vicini.

Selezionare la dimensione dei difetti da cercare: blocchi di 1 pixel, 4 pixel (2x2), o 9 pixel (3x3). I difetti rilevati vengono marcati con piccoli cerchi dal colore selezionabile bianco, nero o rosso. Ingrandire per ispezionare i difetti e determinare se sono veri difetti. Usare il cursore [Contrasto] per selezionarli con precisione: se impostato troppo basso (troppo a destra), piccole macchie con grande contrasto possono essere selezionate erroneamente; se impostato troppo alto, veri difetti possono essere ignorati. Usare il pulsante [Applica] per cancellare i difetti sull'immagine; se necessario si può eseguire la funzione molte volte con impostazioni differenti. I pixel correntemente cerchiati possono essere salvati su un file usando [Salva]; questo file può essere usato in seguito per correggere i difetti in altre immagini prese dalla stessa macchina: usare il pulsante [Apri], selezionare il file, quindi cliccare [Applica] per eseguire la correzione. Questa procedura (correggere un'immagine caricando le posizioni difettose da un file) funziona solo se le due immagini non sono state ritagliate o, se invece sì, solo se sono state ritagliate in modo identico. Se, per trovare tutti i difetti, diverse impostazioni devono essere usate, è possibile salvare i difetti in più file differenti, e poi combinarli manualmente con un editore di testi. Suggerisco quanto segue, per trovare tutti i difetti facilmente: fotografare un foglio di carta o un muro bianchi sottoesposti, di modo che il risultato sia un grigio uniforme. La foto risultante può essere usata come immagine campione per trovare i pixel difettosi sia scuri che luminosi o con colori falsati.



Modifica pixel

Questa funzione ritocca puntini individuali. Ci sono tre modi di operare: Seleziona (il colore), Dipingi, e Cancella.
Modo [Seleziona]: cliccare in un punto per prelevarne il colore, che sarà usato per dipingere (colore corrente).
Modo [Dipingi]: cliccare o trascinare nella foto per dipingere usando il colore corrente (prelevato prima).
Modo [Cancella]: cliccare o trascinare per ripristinare il colore originale.
Il pulsante [Colore] permette di scegliere un colore con un selettore, e mostra sempre il colore corrente. Il controllo Raggio del pennello imposta in pixel la dimensione dell'area interessata dai clic/trascinamenti. I controlli di trasparenza impostano quanto intensamente il nuovo colore viene trasferito ai pixel, al centro e ai bordi del mouse. La trasparenza zero applica il colore subito e completamente; trasparenze alte (90-99) applicano poco colore e permettono di cambiare il colore gradualmente attraverso clic o trascinamenti ripetuti (un po' come spruzzare colore da una certa distanza). Anche il modo Cancellazione lavora in questo modo: con trasparenza zero si ripristinano i pixel immediatamente, con trasparenze alte i pixel riprendono il colore originario gradualmente. [Annulla ultimo] annulla l'effetto dell'ultimo clic o trascinamento, e può essere usato più volte in successione per annullare l'ultimo, il penultimo e così via. La memoria per questi annullamenti è limitata a 200 Mib, che può essere raggiunta se si usa un pennello grosso (ogni cambiamento di ogni pixel viene registrato). E' utile salvare l'immagine dopo ogni modifica soddisfacente per liberare questa memoria. La quantità di memoria disponibile viene mostrata nella finestra di dialogo, per vedere quando il limite si avvicina. Se un'area di selezione è attiva, le modifiche vengono confinate in quell'area; si può selezionare un'area "per colore" e poi cambiare tale colore senza curarsi dei bordi. NOTA: ingrandire l'immagine al 100% o più per usare questa funzione; se i passi del mouse sono maggiori della dimensione dei pixel e si usa un pennello piccolo, alcuni pixel possono essere saltati.


Menù trasforma


Ruota immagine
rotate.jpg
Questa funzione mostra un dialogo per ruotare l'immagine in senso orario (+) o antiorario (-) in passi di 0,1, 1, 10 o 90 gradi. Se l'immagine è inclinata, usare il mouse per trascinare il lato destro su o giù per livellarla. Usare passi di 90 gradi per convertire una foto da verticale a orizzontale o viceversa. Non c'è perdita d'informazioni per rotazioni di 90 gradi; per altri angoli, la perdita è di circa 1/2 pixel. La nuova immagine risulta espansa per accomodare quella originale, ruotata, senza ridurre le dimensioni; per esempio: una foto 100 x 100 ruotata di 45 gradi avrà dimensioni di 141 x 141, e le aree inutilizzate saranno nere. Usare la funzione [Ritaglia] per rimuovere questi margini estesi.


Ritaglia immagine
(crop)
Le funzioni per creare panorami lasciano margini neri intorno ai lati dove le immagini non si sovrappongono bene. Usare questa funzione per rimuovere tali margini (o qualsiasi altro margine). Un rettangolo di selezione iniziale viene mostrato, grande come l'ultimo usato se la dimensione rientra nell'immagine. Cliccare o trascinare vicino agli angoli per spostarli. Quando terminato, cliccare [Fatto] per tagliare via le parti esterne al rettangolo. La finestra di dialogo mostra le dimensioni e la proporzione correnti del rettangolo di ritaglio. Se la casella [Blocca proporzioni] è marcata, muovendo un angolo del rettangolo sposterà anche quello opposto per mantenere la proporzione. Si può anche trascinare dal centro del rettangolo per spostarlo interamente senza modificarne le dimensioni. Se [Abilita mouse] non è marcato, il mouse può essere usato per variare ingrandimento e posizione dell'immagine. Quando si spunta nuovamente [Abilita mouse], il rettangolo può essere disegnato nuovamente nelle nuove parti visibili. Si possono usare i pulsanti di regolazione di [Larghezza] e [Altezza] per impostare la dimensione in pixel: il rettangolo di selezione si adatterà ai valori.



I sei pulsanti permettono di selezionare un rapporto larghezza/altezza preconfigurato. Il pulsante [Inverti] inverte il rapporto (2:1 diventa 1:2 e così via). Si può cambiare il nome del pulsante e il rapporto corrispondente usando [Personalizza], che aprirà la finestrella mostrata sopra a destra. Immettere i nomi desiderati nella prima riga di caselle, e il rapporto corrispondente nella linea sottostante; usare 16:9 per il formato HDTV.
Il pulsante [gold] usa di default il rapporto aureo (circa 1,618:1) - si può modificare esattamente come gli altri.


Ritaglia automaticamente
autotrim.jpg

Le funzioni per creare panorami possono lasciano margini, e altre trasformazioni possono lasciare aree nere. Il ritaglio automatico imposta automaticamente i margini per eliminare queste aree, e poi invoca la funzione di ritaglio (capitolo precedente). Se i margini sono corretti, premere [Fatto]; se non sono corretti, modificarli come descritto prima. La funzione automatica cerca il massimo rettangolo che non attraversi i margini neri; il risultato può essere quello desiderato oppure no, e in questo caso essi possono essere variati.



Ridimensiona immagine
(riscalare)
Questa funzione imposta nuovi valori di larghezza e altezza. Si possono immettere direttamente larghezza e altezza in pixel, oppure usare una variazione percentuale. Sono presenti pulsanti per reimpostare direttamente (in percentuale) a 3/4, 2/3, 1/2, 1/3, o 1/4 della dimensione originale. Usando uno di questi pulsanti si minimizzerà la perdita di risoluzione. Se la casella [Blocca proporzioni] è marcata, le proporzioni originali di larghezza e altezza saranno preservate, cioé se una dimensione viene modificata, l'altra verrà modificata di conseguenza per mantenere il rapporto. Il cambio di dimensioni viene fatto immediatamente, ma l'immagine sembrerà la stessa a meno che non diventi più piccola della finestra, causando un restringimento visibile. Uscire dalla finestra di dialogo con [Fatto] per mantenere le modifiche, o [Annulla] per mantenere le dimensioni immutate. La barra di stato in basso viene aggiornata solo salvando l'immagine.



Ridimensiona/esporta in blocco

Si usa per scalare molte immagini insieme (per caricarle su un sito web,  o per guadagnare spazio sul disco). L'invocazione apre una finestra di dialogo per selezionare le immagini e impostare le opzioni. Usare il pulsante [Seleziona i file] per scegliere le immagini da una galleria (dettagli). Selezionare larghezza e altezza massime per i file di uscita (usare valori enormi se non si vuole ridurre). Selezionare il [Nuovo tipo di file]: [Uguale] significa che il tipo di file non verrà cambiato, le altre scelte impostano invece il tipo di file che sarà usato per la nuova copia.
Importante è la scelta [Sostituzione originali] o [Esporta su una posizione]; nel secondo caso, occorre specificare una directory dove le immagini scalate saranno salvate (scrivere direttamente nella casella sotto, o usare [Sfoglia]). Infine, usare [Prosegui] per cominciare l'elaborazione; una finestrella mostrerà il progresso. Se l'opzione di sostituzione originali è attiva, i dati EXIF verranno preservati (incluse le etichette). Se invece si è scelta l'opzione di esportazione, usare la casella [Copia EXIF] per scegliere se tali dati devono essere esportati od omessi.



Testo sull'immagine

Con questa operazione si possono immettere testi descrittivi e imprimerli direttamente sull'immagine. Immettere il testo nella casella apposita (si possono usare linee multiple). Dopo immesso il testo, cliccare o trascinare con il tasto sinistro del mouse per indicare la posizione del testo; usare il pulsante destro per rimuovere la scritta.
Usare il pulsante [Font] per selezionare un diverso tipo di carattere e una diversa dimensione; la dimensione può essere variata anche con il controllo apposito senza cliccare [Font]. Il controllo [Angolo] permette di ruotare la scritta. Si possono scegliere il colore del testo (text) e dello sfondo (backing), e la trasparenza. L'esempio qui sopra mostra testo verde su sfondo blu, con trasparenza al 77%, cioé l'immagine è visibile attraverso la scritta. La terza casella del colore [Outline] permette di specificare il colore del contorno del testo (rosso nell'esempio). Il controllo [Spessore] imposta la larghezza del contorno. I pulsanti [Carica da file] e [Salva] richiamano una finestra di dialogo per scegliere un file, dal quale si leggono o scrivono i dati della finestra corrente (font, colori, dimensione...), così è possibile mantenere una collezione di annotazioni usate frequentemente.


Per creare un watermark: usare una trasparenza del testo del 70% o più, e una dello sfondo del 100%. Il testo dovrebbe essere leggero ma leggibile. Per aggiungere un effetto di bassorilievo usare [Seleziona area] per circondare il testo e poi [Arte -> Bassorilievo] per sbalzare il testo (se più chiaro dell'immagine) o scavarlo (se più scuro).



Rifletti immagine
Scegliere [orizzontale] o [verticale]; l'immagine viene specchiata (ribaltata) di conseguenza. Ripetendo la stessa operazione, l'immagine torna come prima. Eseguire entrambe le riflessioni da lo stesso risultato di una rotazione di 180 gradi.



Svolgi immagine


Fotografie di  soggetti vicini (solitamente edifici o interni di stanze) possono mostrare come curve linee che in realtà sono diritte. Raddrizzare queste curve è necessario per far collimare le immagini nella creazione di un panorama (menù [Combina]). Per soggetti lontani (specialmente paesaggi) il problema non è avvertibile. Questa funzione può essere usata per raddrizzare le linee curve e togliere l'inclinazione a quelle storte. Linee puntinate orizzontali e verticali vengono mostrate sull'immagine, come assi di riferimento: cliccare o trascinare vicino all'estremità di una linea per spostarla. Immettere i valori di correzione orizzontale e verticale e osservare il risultato; aumentare o diminuire i valori e ripetere. Spostare gli assi per cambiare il centro dello svolgimento. I valori sotto [Lineare] inclinano l'immagine (rettangolo -> parallelogramma) per rimuovere le inclinazioni errate. I valori sotto [Curvato] raddrizzano le curve generate riprendendo un panorama. Vedere anche [Trasforma -> Deforma immagine] per altri metodi di correzione della curvatura o della prospettiva.



Deforma immagine (area)

Questa funzione si può usare per generare distorsioni dentro un'area. Si può selezionare un'area e trascinare il mouse per deformarla rispetto al resto dell'immagine; l'immagine reagisce come se fosse fatta di gomma. Il movimento è massimo in corrispondenza del puntatore e decresce a zero ai bordi della selezione. Diversi trascinamenti con lunghezze e direzioni diverse possono essere combinati per arrivare al risultato. Il pulsante [Annulla ultimo] cancella l'ultimo trascinamento (fino agli ultimi 100). Quando finito, si può selezionare un'altra area e deformare ancora, o scegliere [Fatto] per terminare. Il metodo usato da Fotoxx limita la perdita di risoluzione per deformazioni ripetute: per ogni trascinamento, il movimento totale di ogni pixel viene accumulato e l'immagine originale viene usata per calcolare la disposizione finale. I pixel vengono interpolati per ridurre spigolosità e migliorare la nitidezza.



Deforma immagine (curve)

Questa funzione è utile per correggere problemi di prospettiva (vedi anche [Svolgi immagine]). Trascinare col mouse un punto qualsiasi dell'immagine: l'intera immagine verrà tirata o spinta nella direzione indicata, ma le zone vicino al puntatore si spostano maggiormente di quelle distanti. Si possono raddrizzare linee curve, o deformare deliberatamente l'immagine.



Deforma immagine (lineare)

TQuesta funzione lavora come la precedente, ma su un'area più ampia e causa una curvatura minore. Per minimizzare la creazione di curvature indesiderate, trascinare gli angoli dell'immagine piuttosto che altri punti.



Deforma immagine (speculare)
Questa funzione deforma l'immagine in modi interessanti. Trascinare gli angoli o i lati con il mouse; i cambiamenti sono puramente lineari così le linee dritte rimangono tali. Questa trasformazione è chiamata "affine"; ulteriori dettagli possono essere trovati su Internet con Google.


Menù Arte


Profondità di colore

Questa funzione cambia i normali 16 bit per colore RGB a qualsiasi quantità tra 1 e 16. Con 8 bit per colore ci sono 16,8 milioni di combinazioni di colori; con 4 bit i colori possibili sono solo più 4096. Usare da 1 a 4 bit per ottenere interessanti effetti di tipo poster.



Disegno

Trasforma una fotografia in un'immagine in bianco e nero molto contrastata, oppure in un disegno dove solo i contorni degli oggetti vengono mostrati in nero su sfondo bianco o viceversa. Il cursore [Contrasto] porta le aree scure verso il nero. Il cursore [Soglia] converte l'immagine da scala di grigio a bianco e nero. Il cursore [Contorni] evidenzia i pixel con grande contrasto (bordi degli oggetti) e sopprime quelli poco contrastati. Il risultato può essere nero su bianco o bianco su nero, secondo la selezione di [Matita] o [Gessetto]. Manipolare sia [Soglia] che [Contorni] per ottenere il miglior bilanciamento.



Contorni
Questa funzione trasforma una fotografia in un disegno di linee colorate corrispondenti ai contorni dei soggetti nella fotografia. I bordi (transizioni marcate di luminosità o colore) nell'immagine vengono illuminati, e il resto scurito. Ci sono tre cursori per controllare il processo. [Soglia del contorno] regola quanto luminoso deve essere un bordo per essere illuminato, da "nessun bordo" a "tutti" (anche quelli deboli). [Spessore contorno] regola la larghezza dell'illuminazione, da 1 pixel a circa 5. [Luminosità immagine] regola la luminosità del resto dell'immagine, da scuro (si vedono solo i contorni) a piena luminosità.



Bassorilievo

Trasforma la foto in un bassorilievo simulato. Il [Raggio] determina la grossolanità (inverso del dettaglio). La [Profondità] quanto è profonda l'incisione.



Mosaico

Questa funzione trasforma una foto in una schiera di grosse tessere monocolori. Si può impostare la grandezza delle tessere e la distanza fra esse. Questo processo viene anche chiamato "pixelaze" o "pixelate". Usare una selezione per confinare l'effetto a una parte dell'immagine, per esempio un volto.



Puntinismo
Genera una schiera di puntini dalla foto, rendendola simile ai vecchi fumetti o ai quadri di Roy Lichtenstein. L'unico parametro impostabile è la dimensione dei puntini. Prima di questa funzione, si può provare a modificare saturazione, profondità di colore o altri effetti per arrivare a risultati interessanti.



Pittura
Questa funzione trasforma una foto rendendola simile a un dipinto. Riduce il numero di colori, considera i pixel vicini con colori simili, e poi li aggrega in aree più grandi. Quattro parametri controllano il processo: [Profondità dei colori] imposta il numero di colori da usare (numero di bit per colore): 1=8 colori, 2=64... 5=32768; [Fattore artistico] imposta un limite inferiore per aree che avranno un proprio colore: aree più piccole di questo numero saranno assorbite da aree adiacenti simili; [Precisione colori] imposta una similarità minima per includere una piccola area in una adiacente: 0=qualunque (massimo raggruppamento), 100=similarità completa (nessun raggruppamento) ; [Contorni] determina se le aree colorate devono essere bordate con una sottile linea scura, come tessere irregolari in un mosaico. Dopo questa funzione, l'applicazione del Bassorilievo può aggiungere trame interessanti.



Modifica dei pixel

Questa funzione cambia pixel singoli. Ci sono tre modi d'operazione: Selezione, Pittura e Cancellare. Il modo Selezione serve per cliccare nell'immagine per prelevare il colore corrente. Nel modo Pittura si clicca o si disegna nell'immagine per dipingere con il colore corrente. Il modo Cancellare serve per cliccare o trascinare nell'immagine per ripristinare i pixel al loro colore originale.
Il pulsante [Colore] permette di scegliere un colore attraverso una finestra di selezione, e mostra sempre il colore corrente.
Il controllo [Raggio del pennello] imposta la grandezza dell'area ritoccata dal puntatore con ogni clic o trascinamento.
I controlli di trasparenza impostano l'intensità di applicazione del colore al centro e ai bordi del pennello. Con trasparenza zero il nuovo colore viene impresso completamente subito, mentre una grande trasparenza (90..99) applica poco colore e permette di regolare la sua quantità usando molti successivi clic (è analogo a spruzzare il colore da una certa distanza).
[Cancellare] funziona nello stesso modo di [Pittura]: usare zero trasparenza per per cancellare al primo clic, e alta trasparenza per cancellare gradualmente. Togliere la spunta ad [Abilita mouse] per poter ingrandire o spostare l'immagine, e rimettere la spunta per tornare a disegnare.
Il pulsante [Annulla ultimo] annulla l'ultima operazione (un singolo clic o trascinamento), e si può usare più volte per annullare all'indietro molte operazioni. La memoria per le operazioni di annullamento è limitata a 200 Mib (megabyte), e può essere consumata se si fanno molte modifiche con un pennello grosso (ogni cambiamento a ogni pixel viene salvato). E' utile salvare l'immagine dopo ogni modifica soddisfacente per riacquistare questa memoria. La quantità utilizzata di memoria viene mostrata, così si può vedere quando si arriva vicino al limite. Se una selezione è abilitata, le operazioni vengono confinate entro quell'area. Si può selezionare un'area per colore e poi cambiare il colore senza preoccuparsi dei bordi.
NOTA: ingrandire l'immagine al 100% o più quando si usa questa funzione: se i movimenti del mouse sono più ampi dei pixel dell'immagine e un pennello piccolo è in uso, alcuni pixel potrebbero venire saltati.


Menù [Combina]


Combina immagini (alta dinamica - HDR)

Combina (sovrappone) immagini multiple con lo stesso soggetto a livelli di esposizione diversi. L'immagine combinata può mostrare migliori dettagli sia in parti chiare che scure dell'immagine prelevando pixel dall'immagine chiara per le zone scure e pixel dall'immagine scura per le zone chiare. Molte macchine digitali possono prendere scatti multipli in rapida successione con livelli d'esposizione differenti. Si possono combinare queste immagini per produrne una migliore. Se la macchina viene regolata manualmente tra gli scatti, curare di mantenerla allineata e mirare allo stesso punto distante. Una lieve quantità di disallineamento può essere tollerato. Se il soggetto si muove tra due scatti successivi, confusione e sdoppiamenti non possono essere evitati.



Selezionare la funzione HDR. Una finestra di dialogo permette di selezionare fino a 9 immagini, che devono avere dimensioni molto simili in pixel. Le immagini vengono allineate e combinate automaticamente, e questo può richiedere un minuto o anche più. Finito l'allineamento, l'immagine combinata viene mostrata, insieme a una finestra di dialogo per la regolazione manuale. Le contribuzioni delle immagini in ingresso sono mostrate come una serie di curve modificabili. La scala orizzontale rappresenta la luminosità, da scuro a chiaro. Ogni curva è associata a un'immagine che contribuisce ai pixel finali; il contributo di un'immagine a una certa luminosità è proporzionale all'altezza della sua curva a quella luminosità. La curva inziale dell'immagine più luminosa sarà alta verso sinistra e bassa verso destra, dando così un gran contributo aipixel scuri e poco contributo a quelli chiari. L'immagine più scura avra la curva bassa a sinistra e alta a destra, e le ulteriori immagini avranno curve mediane fra queste. Le curve possono essere manipolate trascinandole con il mouse. I punti d'ancoraggio (quadratini sulla curva) possono essere spostati mantenendo fissi gli altri. I contributi dell'immagine corrispondente vengono variati conformemente, e i risultati si possono vedere quasi in tempo reale. Cliccare col pulsante destro su un punto d'ancoraggio per rimuoverlo. In genere, l'immagine più luminosa dovrebbe contribuire maggiormente ai pixel scuri, e quella più scura dovrebbe contribuire maggiormente; occorre un po' di pratica per lavorare efficacemente con le curve.

Un sistema alternativo più rapido e facile può funzionare ugualmente bene: dopo aver combinato le immagini, ignorare le curve e uscire dalla funzione e usarne invece altre per rifinire l'immagine: Normalizza/Espandi luminosità, Luminosità e contrasto, Mappatura della luce. Una selezione di area può essere usata per racchiudere una zona che ha bisogno di più luminosità, colore o contrasto locale, così si possono applicare metodi e parametri diversi ad aree differenti.



Combina immagini (grnade profondità - HDF)
Combina (sovrappone) diverse immagini dello stesso soggetto riprese con messa a fuoco differente -- da vicino a lontano. Parti differenti dell'immagine sono messe ben a fuoco in ogni immagine: qusta funzione combina le immagini in modo che tutte le parti diventano ben definite. Questa tecnica efficace specialmente per le riprese molto ravvicinate.

Per prendere le foto , scegliere un punto come centro dell'immagine; mirare all'oggetto vicino e far scattare l'otturatore a metà per impostare il fuoco sull'oggetto; mantenere l'otturatore a metà, mirare al centro scelto, e scattare la foto. Poi, scegliere un oggetto più distante e ripetere. Ripetere con distanze di fuoco maggiori: probabilmente ogni parte della scena sarà a fuoco in almeno una foto. La posizione della macchina dovrebbe essere grosso modo sempre la stessa, che può essere difficile se il soggetto è molto vicino. I movimenti della macchina possono causare problemi di scalatura e parallasse (oggetti vicini spostati  a rispetto di quelli distanti); questi problemi possono essere corretti in Fotoxx, ma ciò può richiedere parecchio tempo: è meglio cercare di evitarli.




Riprese le foto, si possono processare con Fotoxx. Invocare la funzione HDF e selezionare fino a 9 immagini; queste verranno automaticamente allineate il meglio possibile. Questo può richiedere un minuto o più per immagine, in dipendenza della dimensione delle immagini e della potenza della CPU. L'immagine risultante è una miscela uniforme delle immagini in ingresso allineate. Piccoli movimenti della macchina tra le foto vengono corretti, ma in modo limitato, e gli errori di parallasse non vengono compensati. Quando l'allineamento è completo, si apre una finestra di dialogo. Si può selezionare una delle immagini in ingresso e "pitturare" con il mouse su ogni area dell'immagine in uscita. Questo trasporta la miscela originale verso l'immagine selezionata, nella zona "pitturata". Per ogni area o oggetto nella foto, scegliere l'immagine d'ingresso che è migliore in quell'area. Il raggio del pennello può essere ingrandito o rimpicciolito, per pitturare velocemente aree ampie o controllare piccoli dettagli quando serve. Se ci sono oggetti vicini e lontani che si sovrappongono, occorrono tempo e pazienza per rendere tutta la foto nitida. Togliere la spunta ad [Abilita mouse] per ingrandire/spostare l'immagine, e rimetterla per tornare al ritocco.

I disallineamenti possono essere corretti selezionando [deformazione] nella finestra di dialogo. Le immagini sottostanti possono essere trascinate e deformate con il mouse, e l'immagine composta risultante cambia conformemente. La deformazione è limitata all'area intorno al mouse. Quando un'area già "pitturata" viene trascinata, l'immagine corrispondente viene selezionata e deformata, mentre aree "pitturate" con altre immagini rimangono ferme. Aree che non sono state pitturate non possono essere trascinate. Manipolare le diverse aree ed eseguire trascinamento incrementali fino a che tutte le aree siano allineate.

Procedura suggerita:
con il modo [Pittura] selezionare ogni immagine in sequenza e pitturare tutte le aree con aspetto nitido in quell'immagine. Tutti i confini che non sono allineati si mostreranno chiaramente come scostamenti nei bordi degli oggetti. Alcuni di questi possono essere ridotti selezionando un'altra immagine come sorgente per quella zona (se più di un'immagine è abbastanza nitida in quella zona). Usando il modo [deformazione] eseguire i ritocchi fini per eliminare i disallineamenti visibili.



Sovrapponi (interattivo con mouse)
Combina (sovrappone) diverse foto dello stesso soggetto prese in tempi differenti. Serve per rimuovere turisti o automobili che vanno e vengono tra le riprese, pitturandoli via con il mouse.

Per fare le foto, mirare allo stesso punto distante e riprendere diversi fotogrammi mentre gli altri oggetti (turisti, automobili...) si muovono davanti. Cercare di prendere almeno un'istantanea libera da ostacoli per ogni parte del soggetto.

Per processare le foto con Fotoxx, richiamare [Combina->Sovrapponi (interattivo con mouse)] e selezionare fino a nove immagini. Le immagini verranno allineate il meglio possibile, richiedendo un certo tempo (anche un minuto o più per ogni immagine, in dipendenza della potenza della CPU). L'immagine in uscita è una miscela omogenea delle immagini in ingresso allineate. Quando l'allineamento è completo si apre un dialogo. Si può selezionare una delle immagini in ingresso e "pitturare" con il mouse su un'area dell'immagine risultante. Questo converte la miscela delle immagini verso l'immagine scelta, nell'area sotto pittura. Per ogni area dell'immagine, scegliere l'originale che sia libero da oggetti in movimento davanti al soggetto reale. Il raggio del pennello/mouse può essere variato per pitturare velocemente grandi aree o controllare finemente piccoli dettagli. Deselezionare [Abilita mouse] per ingrandire o spostare l'immagine, e riselezionare per tornare a pitturare.




Sovrapponi (rimozione disturbo)
Questa funzione combina da 2..9 immagini dello stesso soggetto. Le foto dovrebbero essere praticamente identiche, eccetto piccoli scostamenti dovuti a riprese fatto a mano libera. Se le foto sono state riprese con livelli ISO molto alti (condizioni di luce scarsa), i pixel avranno parecchio disturbo; riprendendo molte foto e facendone una media, questo disturbo può essere praticamente eliminato.



Per prendere le foto, scegliere un punto come centro dell'immagine. Eseguire poi diversi scatti riferiti allo stesso centro e facendo attenzione a non ruotare o spostare troppo la macchina. Maggiori sono gli scatti, meglio è; fino a nove immagini possono essere usate da Fotoxx, ma se ne possono prendere di più per scartare quelle meno definite - un problema ricorrente in condizione di poca luce e lunghi tempi d'esposizione. In Fotoxx richiamare [Combina->Sovrapponi (rimozione disturbo)] e selezionare fino a nove immagini. Queste vengono combinate, e infine viene mostrato un dialogo. L'immagine risultante iniziale è una miscela di quelle in ingresso: i valori RGB di ogni pixel in uscita è la media matematica dei corrispondenti valori in ingresso. Alcuni strumenti aggiuntivi possono essere usati per ridurre eventualmente il disturbo rimanente ancora un po'. Il bottone [use median] cambia l'algoritmo da media matematica a valore mediano (si esegue la media dei valori mediani 1-3, in dipendenza del numero di immagini). Il risultato può essere migliore oppure no, quindi alternare fra i due metodi per fare una comparazione (l'aggiornamento dello schermo può richiedere parecchi secondi).
Le caselle [omit low pixel] e [omit high pixel] causano l'esclusione dei valori RGB estremi prima del calcolo della media. Questo può aiutare a rimuovere picchi di rumore; non ha effetto quando il metodo [use median] è selezionato.



Crea un panorama

Questa funzione affianca da 2..4 immagini insieme per formare un'immagine larga o panoramica. Le immagini devono sovrapporsi del 15% o più affinché Fotoxx possa trovare i punti concidenti e combinarli.


Richiamare [Combina->Crea un panorama] e selezionare da 2 a 4 file d'immagine. Le immagini vengono unite e mostrate con una piccola sovrapposizione trasparente. Un dialogo di pre-allineamento chiede di trascinare le immagini in una posizione grossolanamente allineata: trascinare le immagini nell'ordine corretto da sinistra a destra, se richiesto. Le immagini da trascinare possono essere sovrapposte ad altre: per essere chiari riguardo a quale immagine si vuole spostare, trascinare il centro di un'immagine. Quando le foto sono disposte nell'ordine corretto, allineare ognuna alla vicina di sinistra - funziona meglio lavorare da sinistra verso destra. Spostare l'immagine orizzontalmente e verticalmente in un allineamento approssimativo col vicino di sinistra, e poi ruotarla trascinando il lato inferiore a destra o sinistra. L'immagine si inclina intorno al punto centrale della sua sovrapposizione di sinistra. Il metodo più veloce è allineare la sovrapposizione nel centro verticale, poi ruotare l'immagine, se richiesto, per portare le regioni di sovrapposizione alta e bassa all'allineamento. Non serve un'accuratezza estrema. Usare il pulsante [Ridimensiona] per ottenere un'immagine combinata più grande dopo averle disposte vicine.

Le immagini dovrebbero essere curvate correttamente e combaciare bene. Se non combaciano, occorre impostare i parametri delle lenti come descritto in [Strumenti->Parametri dell'obbiettivo] (dettagli). Si possono regolare questi parametri da dentro il dialogo di preallineamento fino a che le immagini combacino ragionevolmente bene, e ciò potrebbe essere sufficiente. Il parametro [mm focale] (lunghezza focale, equivalente a 35 mm) è ottenuto dai dati EXIF se disponibili. Il parametro [curvatura] (barrel distortion) non è disponibile nelle informazioni EXIF: deve essere regolato manualmente, ma spesso è insignificante e può essere lasciato a zero.

Se una foto era stata ritagliata di modo che la maggiore delle dimensioni (larghezza o altezza) era stata ridotta, allora la lunghezza focale descritta in EXIF non è più valida, e il valore iniziale prelevato da EXIF potrebbe non funzionare bene. Una sezione (parte) di un'immagine presa dal centro ha una lunghezza focale effettiva maggiore dell'immagine intera. Usare il dialogo di pre-allineamento per aumentare il valore di lunghezza focale fino a che le immagini combacino ragionevolmente bene.

Cliccare [Procedi] quando il pre-allineamento è terminato: il programma eseguirà l'allineamento fine e unirà le immagini. Internamente, le immagini vengono spostate e ruotate e il grado di corrispondenza viene valutato. Questo viene fatto con dimensioni d'immagine sempre maggiori, fino a che la corrispondenza migliore viene trovata entro una frazione di pixel. Questa procedura può richiedere da 10 secondi a un minuto o più per immagine, in dipendenza della dimensione delle immagini e della velocità della CPU.



Quando l'elaborazione dell'allineamento fine è completata, l'immagine combinata viene mostrata. Una finestra di dialogo si apre per regolare in modo fine la luminosità e la corrispondenza del colore. Può essere visibile un bordo spigoloso perché le immagini non hanno la stessa luminosità e bilanciamento di colori. Il pulsante [colori automatici] può essere usato per ricercare una corrispondenza automatica, che è usualmente il miglior punto di partenza. Gli altri controlli permettono di fare cambi addizionali per far combaciare meglio le immagini. Cambiare i valori per [luminosità] e i tre colori e cliccare [Applica] per vedere il risultato. Usare [colori automatici] per far convergere le altre immagini verso quella modificata. Usare [file colore] per ripristinare i valori originali dell'immagine d'ingresso. La [Larghezza di sfumatura] governa come le immagini vengono miscelate: ai bordi affiancati, il bilanciamento di colore viene gradualmente spostato lungo la quantità di pixel specificata, per nascondere sbilanciamenti che non possono essere corretti pienamente. Il valore iniziale è 1 pixel, che rende evidente qualsiasi differenza di colore o luminosità.

Al termine, si possono ancora usare [Svolgi], [Deforma], [Ruota], [Ritaglia] e altre funzioni per le correzioni finali. Usare magari la funzione [Ritaglia automaticamente] per eliminare i bordi neri superflui.


Panorama verticale
Funziona esattamente come il panorama orizzontale, eccetto che le immagini sono impilate verticalmente. Per cambiare l'ordine delle immagini, trascinarle dal centro. Per ruotare un'immagine trascinarne il lato destro su o giù. E' meglio allineare dall'alto verso il basso.

Limitazioni delle funzioni "Panorama"
Panorami che includono oggetti vicini possono essere complicati: quando le foto devono essere prese, fare attenzione a girare la macchina intorno all'asse della lente (non del corpo della macchina!), con il minimo spostamento laterale possibile, altrimenti le immagini si allineano malamente a causa dello spostamento di oggetti vicini (parallasse). Questo non è un problema quando il soggetto si trova a 50 metri o più, dato che un piccolo movimento laterale ha poco impatto sull'immagine.




Menù Plugins

Altri programmi di fotoritocco (es. Gimp) possono essere aggiunti a questo menù. Essi funzioneranno come qualsiasi altra funzione interna di Fotoxx. Dopo aver usato uno di questi programmi esterni per manipolare un'immagine, si potranno usare [Annulla] e [Ripeti] per controllare il risultato, eseguire ulteriori ritocchi con Fotoxx, o usare [Salva] e [Salva come] per memorizzare l'immagine modificata. L'immagine passata da Fotoxx al programma esterno è un TIFF con 16 bit per colore. Quasi tutti i programmi possono leggere questo formato, ma eventualmente usare solo 8 bit. Quando finito di usare l'editor esterno, prima di uscire salvare l'immagine di nuovo su sè stessa (usare "salva" invece di cambiare nome), poi uscire. Fotoxx preleverà il file manipolato e lo userà come se la modifica fosse stata effettuata da Fotoxx.

Per aggiungere un nuovo plugin, usare la funzione del menù [Plugins->Gestione plug-in]. Immettere un nome per il menù (es. "Gimp"), un comando per far partire il programma (es. "gimp") e cliccare il pulsante [Aggiungere]. Si può anche rimuovere un plugin selezionandolo dalla lista e cliccando il pulsante [Taglia].

Il menù dei plugin non viene aggiornato fino al successivo avvio di Fotoxx.

I dati dei plugin sono salvati nel file "/home/<utente>/.fotoxx/plugins", che può essere manipolato con un editore di testi se desiderato. Questo metodo è la sola via per cambiare la sequenza delle voci nel menù. Attenzione a non rovinare il formato delle righe: "menu = comando" con esattamente uno spazio prima e dopo il segno uguale.



Menù Aiuto


Info

Mostra un breve messaggio sulla versione di Fotoxx, licenza, crediti e indirizzi di contatto.

Guida utente
La guida per l'utente (questo documento) viene aperta in un browser. Questa guida è stata scritta usando il programma KompoZer.

README
Mostra il file README distribuito con Fotoxx, che può contenere nuove informazioni sull'installazione o le dipendenze. Quando s'installa un nuovo rilascio di Fotoxx, si dovrebbe controllare il README e la Cronistoria delle modifiche per controllare se c'è qualche cosa importante da sapere.

Cronistoria delle modifiche
Mostra il file "change log" distribuito con Fotoxx, contenente il dettaglio dei cambiamenti, aggiunte o correzioni apportate nel tempo al programma Fotoxx.

Come tradurre il programma
Visualizza un breve flie di testo che spiega come fare una nuova traduzione, o correggerne una esistente. La procedura consiste nel manipolare un file di testo contenente i messaggi in inglese e la relativa traduzione in un'altra lingua (vedere le note tecniche qui sotto).

Sito WEB
Carica la home page di Fotoxx da Internet. Controllare lì alla ricerca di aggiornamenti, nella pagina Recent changes. Questa pagina consente di usare RSS e ci si può sottoscrivere per ricevere notifiche di aggiornamenti.


Organizzare una grossa quantità di immagini per la ricerca

Fotoxx può modificare e ricercare i seguenti attributi: data, punteggio, etichette, nomi di file, parole contenute in titoli o commenti. Tutto ciò è spiegato nella sezione Info di questa guida. Quello che segue è un sommario delle opzioni e dei compromessi.

Organizzazione fisica - usare nomi di directory e di file: questi nomi possono essere usati come organizzazione base che permette di trovare le foto anche se sistemi più elaborati (etichette, collezioni...) non sono usati. L'organizzazione dovrebbe essere per date e non per eventi, luoghi o persone. Suggerisco di usare una directory per ogni anno nominata 2005, 2006, 2007 eccetera. Questo sistema aiuta anche a impedire che una qualsiasi directory diventi troppo grossa. I file con le foto possono ancora essere organizzati in sequenza temporale usando MM.GG (mese-giorno) come parte iniziale del nome; la parte restante del nome può essere costituita dal nome dell'evento o del luogo, seguita da un numero di sequenza.

  Per esempio:
/directory-principale/2011/08.20 Spitzbergen 23

Questa organizzazione basilare permette a Fotoxx di trovare file cercando nei nomi di file. Con l'esempio sopra, una ricerca per "spitzbergen" o anche solo "spitz" produrrà tutte le immagini di Spitzbergen. La funzione [File/Rinomina più immagini] permette di rinominare d'un colpo un'intera partita di fotografie prese un in un giorno in un certo luogo selezionando i file e immettendo un nome modello com "08.20 Spitzbergen". I numeri di sequenza sono automatici.

Titoli: un metodo semplice è usare titoli e commenti [Info -> Modifica titoli/commenti]. Questi sono testi arbitrari che possono essere associati alle immagini rapidamente: scrivere del testo, cliccare [Prossima], scrivere del testo, cliccare [Prossima] e così via. Titoli e commenti sono campi separati ma trattati nello stesso modo; essi sono ricercabili: le parole in essi contenute possono essere ricercate. Si possono aggiungere nomi di persona o altre informazioni a ogni immagine, e poi ritrovarle velocemente. Con questo metodo si possono cercare immagini usando una combinazione di date. nomi di file, e parole arbitrarie che appaiono in titoli o commenti. Le date sono prelevate dai dati EXIF del file; questo presume che l'orologio della macchina fotografica fosse impostato correttamente al momento di prendere la foto; comunque, le date possono essere variate usando [Info -> Modifica etichette].

Collezioni: un altro metodo semplice è usare le collezioni. Scegliere un nome per ogni collezione e assegnare immagini alla stessa usando praticamente due clic (più il tempo per trovare le immagini da aggiungere). Questo metodo è indipendente da quelli descritti prima. Riferirsi a [Strumenti -> Gestione collezioni]. Le collezioni si scelgono dal nome e vengono visualizzate direttamente come gallerie di miniature o sequenzialmente nella finestra principale.

Etichette: lo strumento più completo sono le etichette, ma queste sono anche quelle che richiedono maggiore cura organizzativa. Si può scorrere le immagini sequenzialmente e aggiungere etichette cliccando su una lista di etichette predefinite. Nuove etichette possono essere create all'occorrenza. Le immagini possono avere molte etichette, e possono essere ricercate usando una combinazione AND/OR (e/oppure: tutte/almeno una) insieme a data, punteggio, nome del file, commenti. Le etichette sono il sistema più rapido per attraversare una grande quantità di foto. Lo scoglio è l'organizzazione delle etichette: occorre pianificarlo in partenza e aderire a esso, altrimenti la situazione può diventare caotica. Se si finisce per avere mille etichette, esse non saranno molto utili. Se le immagini sono ordinate per data, tenderanno ad avere le stesse etichette, e quindi l'aggiunta di etichette sarà più rapida.



Note tecniche

Traduzioni

Vedere il menù [Aiuto -> Come tradurre il programma]  oppure il file di testo TRANSLATIONS per informazioni su come modificare una traduzione esistente o crearne una nuova. Questo è un processo abbastanza semplice: si tratta di editare un file che contiene messaggi in inglese seguiti dalla loro traduzione. Vederne uno esistente come esempio, magari /usr/share/fotoxx/locales/de/fotoxx.po (è la traduzione in tedesco). Una nuova traduzione per la lingua con codice ZZ dovrebbe essere salvata in /usr/share/fotoxx/locales/ZZ. Dopo aver creato o ritoccato un simile file, esso può essere provato eseguendo fotoxx dalla riga di comando "fotoxx -l ZZ".


Requisiti hardware e software
Fotoxx lavora al meglio con un computer veloce e almeno un gigabyte di memoria. I core multipli di una CPU sono usati in funzioni intensive di calcolo (cioé Contrasta, Sfocatura, Ruota, Deforma, Panorama...). I computer più lenti funzioneranno, ma saranno abbastanza lenti in alcune funzioni. Monitor più piccoli di 1200x800 sembreranno un po' limitati in alcune funzioni. Lo schermo tipico di un notebook, con luminosità e colore limitati, non dovrebbe essere usato per fare fotoritocco.


Programmi richiesti da Fotoxx
Fotoxx richiede, al momento dell'esecuzione, i seguenti programmi o librerie:

   libtiff4 legge e scrive file TIFF, con 8 e 16 bit per colore
   xdg-utils apre file di testo o HTML con l'applicazione preferita dall'utente
   exiftool
legge e scrive i metadati in un file (EXIF: etichette, commenti ecc.)
   ufraw-batch 
importa e converte immagini RAW dalle macchine digitali
   brasero scrive CD o DVD (per creare supporti con fotografie e immagini)

Pacchetti necessari per compilare Fotoxx dai sorgenti
Vedere il file README per sapere come compilare Fotoxx.
In aggiunta a quanto elencato prima, serve anche quanto segue:

   g++
Il compilatore C++ GNU
   libgtk2.0-dev 
librerie di sviluppo Gnome (GTK/GDK/Pixbuf/ecc.)
   libtiff4-dev libreria di sviluppo TIFF

Nota: i nomi dei pacchetti e il loro contenuto preciso dipendono da ogni distribuzione di Linux. I pacchetti elencati prima sono validi per le distribuzioni basate su Debian (quindi Ubuntu è inclusa). Per le altre distribuzioni è possibile che servano pacchetti leggermente diversi.

Opzioni della linea di comando
-v
mostra versione e data compilazione, ed esce
/.../imagefile.jpg directory o file iniziali da aprire
-recent  (o -r) mostra una galleria di immagini recenti (il più recente in cima)
-prev (o -p) apre l'ultima immagine usata
-lang lc_RC codice di lingua per l'interfaccia, più codice regione opzionale: it_IT, de_AT, fr, es...
-slideshow /.../image1.jpg
[-music /.../playlist.pls]
inizia uno slide show con image1 e seguenti, e una musica di sottofondo opzionale
-translate (o -t)
inizia subito il modo traduzione interattivo (per tradurre i menù)

Informazioni della barra di stato

Esempio:  CPU 123%  1234x987x24  0.45MB  56%   edits: 3   menu locked   area active
   CPU 123%
impegno di CPU del processo Fotoxxper tutte i thread
   1234x987x8 
dimensioni immagine: larghezza x altezza x profondità (bit per colori)
   0.45MB dimensioni del file (aggiornato al salvataggio del file)
   56% quantità di zoom, in % sulle dimensioni dell'immagine
   edits: 3
funzioni di ritocco applicate e annullabili col pulsante [Annulla]
   menu locked  
una funzione di modifica è attiva, e le altre funzioni sono indisponibili
   area active  
una selezione di area è attiva, e le modifiche sono confinate entro la selezione

Tipi di file supportati
Fotoxx usa due librerie per leggere e scrivere i file grafici: la GDK pixbuf e libtiff. Pixbuf supporta JPEG, PNG, ICO e BMP, tutti con tre colori RGB e 8 bit per colore. Libtiff supporta file TIFF con 1 bit di colore (bianco e nero), scala di grigi con 8 e 16 bit, e colore RGB con 8 o 16 bit. Altri formati TIFF non sono supportati da Fotoxx, anche se potrebbero essere aggiunti in caso di necessità. Immagini in bianco e nero o a scala di grigi sono trattati come RGB a colori, con tutti i canali RGB allo stesso livello (toni di grigio). Fotoxx converte immagini RAW in TIFF con 16 bit per colore usando il programma ufraw-batch.

Testo mancante nei pulsanti della barra
Questo è un problema di configurazione di Gnome. L'impostazione predefinita varia con la fase lunare. Aprire un terminale e richiamare il comando "gconf-editor". Selezionare nel dialogo "desktop > gnome > interface". Impostare "toolbar_style" a "both", che sceglie icona + testo.

Profondità di colore
8 bit per colore (256 livelli di luminosità), come supportato dai file JPEG, è la norma per i file grafici e solitamente è adeguato. I monitor LCD sono limitati a 8 bit, e l'intervallo effettivo di luminosità per la carta fotografica è inferiore a 8 bit. Un passo di luminosità (1/256esimo o 0,4% sulla gamma) è modlto difficile da distinguere. 16 bit per colore possono essere utili se un piccolo intervallo di luminosità è stato molto amplificato (usando alcune funzioni di fotoritocco). Questa amplificazione può portare a bande visibili o "picket fence distribution". Se l'immagine era stata convertita da RAW a TIFF a 16 bit prima della modifica, questa problema può essere ridotto, anche se l'immagine viene convertita a soli 8 bit in salvataggio (JPEG) o visualizzata su un monitor.


Algoritmo di allineamento (HDR, HDF, Stack, Panorama)
Relativamente pochi pixel "di confine" con alto contrasto vengono selezionati per controllare l'allineamento nella combinazione di immagini HDR, HDF, Stack and Panorama. I pixel scelti sono mostrati in rosso durante il processo, il che è pure divertente. Ogni immagine della sequenza è deformata variamente in piccole quantità e poi la corrispondenza con l'immagine di riferimento viene controllata. Ciò viene fatto perché due foto fatte con piccole differenze di angolo o di orizzonte non possono corrispondere perfettamente con semplici traslazioni e rotazioni. Anche la proiezione cilindrica usata per i panorami è solo un'approssimazione di quello che la lente della macchina fotografica fa realmente.


Algoritmo di Mappatura del tono
Il metodo usato da Fotoxx è "fatto in casa", ma ispirato da Fattal e altri metodi basati sul gradiente. Non è efficace come Fattal in alcuni casi, ma si avvicina. D'altra parte, Fotoxx è semplice e rapido.

Canali alpa
Immagini che hanno canali alfa (informazioni sulla trasparenza) possono essere processate, ma il canale alfa viene perso quando l'immagine viene salvata.

Deterioramento dell'immagine per manipolazioni ripetute
Se si salva un'immagine modificata e il relativo file viene usato in seguito per ulteriori modifiche, la risoluzione del pixel può andare persa. E' meglio eseguire tutte le modifiche nella prima sessione per minimizzare questo deterioramento, o usare di nuovo gli originali. Le seguenti funzioni di modifica riducono la risoluzione di circa 1/2 pixel, e l'errore può accumularsi se si salva e si riapre l'immagine tra una modifica e l'altra: Ruota immagine (angoli diversi da 90 gradi); HDR, HDF, Sovrapponi, Panorama, Svolgi, Deforma. Ridurre le dimensioni di un'immagine riduce naturalmente la risoluzione, ma usare le frazioni 1/2, 1/3, o 1/4 conduce ai risultati migliori. Le seguenti funzioni non riducono la risoluzione: Bilanciamento del bianco, Normalizza luminosità, Luminosità e colore, Mappatura della luce, Espandi luminosità, Mappa tonalità, Correzione occhi rossi, Contrasta immagine, Riduci disturbo, Ritaglia, Rifletti, e tutte le funzioni "artistiche".

Deterioramento dell'immagine per ripetuti salvataggi
Aprire un JPEG compresso e risalvarlo porta a qualche deterioramento, ma l'effetto è trascurabile - per lo meno con l'algoritmo usato da Fotoxx (libreria Pixbuf GTK) e la qualità JPEG impostata a un valore alto. Ho letto e salvato un JPEG 20 volte usando una qualità di 90: una comparazione rapida con l'originale ha mostrato una leggera riduzione della luminosità dei colori più brillanti, ma nessuna perdita visibile di risoluzione. I formati TIFF e PNG sono lossless (senza perdite) e quindi non hanno deterioramento - consumano però un sacco di spazio.


Errori EXIF
Le macchine digitali (specialmente quelle più vecchie) non sempre producono dati EXIF strutturalmente corretti, e il programma exiftool (usato da Fotoxx per manipolare quei dati) può produrre messaggi di errore. Sono riuscito a correggere quei casi salvando l'immagine sopra sé stessa, il che rimpiazza i dati EXIF con ciò che exiftool era riuscito a leggere correttamente. Se le etichette vanno perse, devono essere ripristinate a mano.


Caratteri di "a capo" (newline) in Commenti o Titoli
Quando si introducono Commenti o Titoli, se occorre allineare il testo in colonne, si può usare il tasto Invio per creare nuove linee. Questi "a capo" vengono convertiti in stringhe "\n" prima di salvarli nei dati EXIF/IPTC perché non sono consentiti (exiftool li converte in punti). Quando il testo viene ricaricato, i vari "\n" vengono convertiti in "a capo", cosicchè l'allineamento originale del testo viene ripristinato. Tutto questo non è standard, quindi non ci si può aspettare di vedere il testo ancora allineato in altri programmi come Photoshop. Se invece questo è richiesto, non usare il tasto Invio per generare nuove linee durante l'immissione di un lungo testo - lasciare invece che il testo sbordi da solo sulle righe seguenti.


Directory standard per il Cestino
Se il menù [File->Cestina immagine] e l'analogo pulsante della barra non spostano i file nel Cestino standard (dove possono essere recuperati usando gli strumenti normali del desktop/scrivania), può essere possibile rimediare al problema da soli. Se i file d'immagini non sono nel disco "/home" potrebbe, d'ufficio, non essere disponibile. Si può aggiungere il cestino seguendo questo esempio: se il disco con le immagini è montato come "/immagini" e il vostro UID (ID utente) è 1000, dovrebbe esserci una directory chiamata "/immagini/.Trash-1000", con proprietario UID=1000, e con pieni permessi per l'UID 1000. La funzione standard di cestinamento metterà là i file cancellati. Aggiungere questa directory manualmente se essa non esiste - questo potrebbe risolvere il problema.

File speciali di Fotoxx
I seguenti file risiedono in "/home/<utente>/.fotoxx/". Il file search_index duplica i dati EXIF e IPTC delle immagini; esso è usato perché incrementa lettura e ricerca di tali dati di un fattore 1000.
   /annotations/
annotazioni raccolte dalla funzione Trasforma->testo sull'immagine
   /collections/
collezioni d'immagini create con le funzioni per le collezioni
   /saved_areas/
dati di aree salvate dalle funzioni di selezione aree (menù [Seleziona])
   /saved_curves
dati delle curve salvate dalle funzioni del menù [Ritocco]
   fotoxx.log
giornale di Fotoxx che può servire a fini diagnostici
   parameters
parametri d'impostazione che Fotoxx salva tra una sessione e l'altra
   printfile.jpg
l'ultimo file stampato da Fotoxx
   recent_files
una lista degli ultimi 100 file aperti da Fotoxx, salvati all'uscita
   search_results
una lista degli ultimi file trovati con [Info -> Ricerca immagini]
   tags_defined
la lista di tutte le etichette e categorie usate in tutte le immagini
   search_index
un grosso file di testo contenente dati ricercabili per tutte le immagini

Codice sorgente

Il codice sorgente C++ è fortemente commentato nella speranza che altre persone possano capire e usare il codice per i loro progetti. Se qualcuno ha qualche domanda tecnica su come qualche funzione lavora, o qualche suggerimento da dare,  contattare l'autore.

Domande e problemi
Se qualcuno ha qualche domanda o incappa in un problema, può contattare l'autore. Se mi mandate qualsiasi immagine che dà scarsi risultati, posso usarla per cercare di migliorare Fotoxx. Se si trova un listato di traceback sullo schermo, o messaggi di errore nel file /home/<utente>/.fotoxx/fotoxx.log, si è pregati d'inviare pure quelli. Si prega di spiegare esattamente come riprodurre l'errore, e quale versione di Fotoxx e quale distribuzione di Linux è stata utilizzata.

Come ottenere un traceback con i numeri di linea del sorgente
Se s'incontra un crash, mi è molto più facile cercarlo e correggerlo se posso avere il traceback con i numeri di linea del sorgente. Questo è un metodo per produrre il backtrace: in un terminale, eseguire il comando "gdb fotoxx". Fotoxx partirà sotto il controllo del debugger GNU "gdb". In Fotoxx, eseguire l'operazione che genera il crash; il programma gdb dirà che fotoxx è andato in crash. Dentro gdb, immettere il comando "backtrace" (senza virgolette); dopodiché, immettere "q" (quit, per terminare) e "y" (yes, conferma al comando). Copiare tutto il testo di gdb dalla finestra del terminale, incollare dentro un messaggio e-mail, e inviarmelo (e-mail), insieme con la descrizione di ciò che ha provocato il crash.

Libro di riferimenti tecnici
Raccomando il libro "Introduction to Image Processing and Analysis" di Russ and Russ, edizioni CRC Press. E' chiaro e conciso. I seguenti algoritmi sono stati adattati da tale libro: Normalizza la luminosità, Maschera di contrasto, Riduzione del disturbo (valore mediano e "top hat"), Bassorilievo. Le trasformazioni affini per la deformazione e la rotazione sono state trovate usando Google.

Ringraziamenti
I programmi libtiff, ufraw, exiftool e brasero hanno aiutato Fotoxx a evolvere molto più velocemente di quanto sarebbe stato possibile senza. Naturalmente questo riguarda anche GTK, GDK, la libreria pixbuf, gli strumenti e librerie GNU, e l'intero ecosistema GNU/Linux. Grazie a coloro che hanno donato il loro tempo per le traduzioni e le prove (vedere [Aiuto->Info], e a coloro che hanno contribuito con le loro idee allo sviluppo del programma.

fotoxx-12.01.2/doc/copyright0000644000175000017500000000077711701011016014343 0ustar micomicoAuthor: Michael Cornelison Copyright: Copyright 2007, 2008, 2009, 2010, 2011, 2012 Michael Cornelison The source program code can be found here: http://kornelix.squarespace.com/downloads License: You are free to distribute this software under the terms of the GNU General Public Licensel, either version 3 of the License, or (at your option) any later version. The complete text of the license can be found here: http://www.gnu.org/licenses/gpl-3.0.html fotoxx-12.01.2/doc/README0000644000175000017500000000311211701011016013252 0ustar micomicoInstallation of fotoxx from source tarball Building fotoxx requires the following packages: g++ the Gnu C++ compiler and linker libgtk2.0-dev GTK graphics library (GUI base) libtiff4 read/write tiff-8/16 image files At run time the following packages are also needed: exiftool read/write EXIF and tags data ufraw-batch convert camera RAW files to TIFF xdg-utils LSB standard Linux utilities Build and install fotoxx as follows: 1. Download the tar file (fotoxx-N.N.tar.gz) to Desktop 2. Open a terminal window 3. $ cd Desktop # go to Desktop 4. $ tar -xzf fotoxx-N.N.tar.gz # unpack to ./fotoxx 5. $ cd fotoxx # go there 6. $ make # build program 7. $ sudo make install # install program Missing dependencies will cause error messages in step 6. Install these from your repository and repeat step 6. Step 7 moves all files to the following locations: /usr/bin/fotoxx binary executable /usr/share/fotoxx/ icons, translations ... /usr/share/doc/fotoxx/ user guide, README ... For step 7, use "sudo" or "su -c" to get root privileges. Please review the user guide (Help menu) before trying fotoxx. NOTES FOR PACKAGE BUILDERS: If $PREFIX is defined, files go there instead of /usr. If $DESTDIR is also defined, files go to $DESTDIR$PREFIX. The file .../doc/userguide-en.html is used for interactive help. Please do not split into a separate documentation package.