egg/0000755000176200001440000000000013512271573011022 5ustar liggesusersegg/inst/0000755000176200001440000000000013512266054011775 5ustar liggesusersegg/inst/NEWS.md0000644000176200001440000000222113512262111013056 0ustar liggesusers# egg 0.5 (2019-07-13) ## NEW FEATURES * added `theme_presentation` * improved the settings in `theme_article` * added `tag_facet_outside` to tag facet rows and columns ## BUG FIX * corrected logic in `ggarrange` which was failing for non-trivial layouts with more than 4 plots * News file was referring to gridExtra * `symmetrise_scale` no longer worked (again) due to internal changes in ggplot2; this functionality is not achieved through `symmetric_range` passed as limits in the scale # egg 0.4.2 (2018-11-02) ## NEW FEATURES * added theme_article # egg 0.4.1 (2018-07-23) ## NEW FEATURES * added tag_facet ## BUG FIX * fixed aspect ratio for facetted plots was causing a problem in ggarrange; it now works again but the aspect ratio is not fully respected, as space between panels is ignored in the calculation # egg 0.4.0 (2018-06-18) ## NEW FEATURES * added geom_custom * ggarrange gains labels ## CLEANUP * improved vignettes ## BUG FIX * fixed aspect ratio somewhat better respected for facetted plots in ggarrange (not perfect, as space between panels is ignored in the calculation) # egg 0.2.0 (2017-09-12) * initial CRAN release egg/inst/doc/0000755000176200001440000000000013512266054012542 5ustar liggesusersegg/inst/doc/Ecosystem.R0000644000176200001440000001470113512266043014641 0ustar liggesusers## ----setup, echo=FALSE, results='hide', message=FALSE-------------------- library(knitr) library(gridExtra) library(egg) library(gtable) library(grid) opts_chunk$set( message = FALSE, fig.width = 6, fig.height = 3, cache = FALSE ) ## ----basic, echo=2:6, fig.height=5, fig.cap="A few plots that we want to organise on a page."---- set.seed(123) library(ggplot2) p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- qplot(mpg, data = mtcars) + ggtitle("title") p3 <- qplot(mpg, data = mtcars, geom = "dotplot") p4 <- p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") + ggtitle("facetted plot") library(gridExtra) grid.arrange(p1, p2, p3, p4, layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)), widths = c(1.2, 1, 1)) ## ----arrange1, echo=TRUE, fig.height=3, fig.cap="Basic usage of `grid.arrange()`"---- grid.arrange(p1, p2, nrow = 1) ## ----arrange2, echo=-c(1:2), fig.width=4, fig.height=3, fig.cap="Illustrating further arguments of `grid.arrange()`, namely `layout_matrix` and relative widths."---- cols <- c( "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC" ) gl <- lapply(1:4, function(x) grobTree(rectGrob(gp = gpar(fill = cols[x])), textGrob(paste("plot", x)))) grid.arrange( grobs = gl, widths = c(2, 1, 1), layout_matrix = rbind(c(1, 2, NA), c(3, 3, 4)) ) ## ----inset, fig.width=4, fig.height=3, fig.cap="Plot inset."------------- g <- ggplotGrob(qplot(1, 1) + theme(plot.background = element_rect(colour = "black"))) qplot(1:10, 1:10) + annotation_custom( grob = g, xmin = 1, xmax = 5, ymin = 5, ymax = 10 ) + annotation_custom( grob = rectGrob(gp = gpar(fill = "white")), xmin = 7.5, xmax = Inf, ymin = -Inf, ymax = 5 ) ## ----plotstructure, echo=FALSE, fig.width=6, fig.height=3, fig.cap="Colour-coded structure of examplar ggplot layouts. Note how the panels (red) vary in size from plot to plot, as they accommodate the other graphical components."---- pl <- lapply(list(p1, p2, p3, p4), expose_layout, FALSE, FALSE) layouts <- arrangeGrob( grobs = pl, widths = c(1.2, 1, 1), layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)) ) ids <- c("background", "panel", "axis", "lab", "guide", "strip", "title") cols <- c( "grey95", "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC" ) leg <- lapply(ids, textGrob, hjust = 0, x = 0.1) legend <- gtable_matrix( "legend", matrix(leg, ncol = 1), widths = 1.2 * grobWidth(leg[[1]]), heights = unit(rep(1, length(leg)), "line") ) legend <- gtable_add_cols(legend, unit(1, "line"), 0) legend <- gtable_add_grob(legend, t = seq_along(leg), l = 1, lapply(cols[seq_along(ids)], function(x) rectGrob(gp = gpar(fill = x, col = NA)))) grid.arrange(layouts, legend, widths = unit.c(unit(1, "null"), 1.2 * sum(legend$widths))) ## ----rbind, fig.height=4, fig.width=4, fig.cap="Aligning plot panels. Note that the two y axes have different widths."---- library(gtable) g2 <- ggplotGrob(p2) g3 <- ggplotGrob(p3) g <- rbind(g2, g3, size = "first") g$widths <- unit.pmax(g2$widths, g3$widths) grid.newpage() grid.draw(g) ## ----egg, fig.height=3, fig.width=6-------------------------------------- p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point()+ theme_article() + theme(legend.position = 'top') p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme_article() ggarrange(p1, p2, widths = c(1.5,2)) ## ----titles-------------------------------------------------------------- grid.arrange( p3, p3, p3, nrow = 1, top = "Title of the page", bottom = textGrob( "this footnote is right-justified", gp = gpar(fontface = 3, fontsize = 9), hjust = 1, x = 1 ) ) ## ----legend, echo=TRUE, fig.height=4------------------------------------- grid_arrange_shared_legend <- function(..., ncol = length(list(...)), nrow = 1, position = c("bottom", "right")) { plots <- list(...) position <- match.arg(position) g <- ggplotGrob(plots[[1]] + theme(legend.position = position))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) lwidth <- sum(legend$width) gl <- lapply(plots, function(x) x + theme(legend.position = "none")) gl <- c(gl, ncol = ncol, nrow = nrow) combined <- switch( position, "bottom" = arrangeGrob( do.call(arrangeGrob, gl), legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight) ), "right" = arrangeGrob( do.call(arrangeGrob, gl), legend, ncol = 2, widths = unit.c(unit(1, "npc") - lwidth, lwidth) ) ) grid.newpage() grid.draw(combined) # return gtable invisibly invisible(combined) } grid_arrange_shared_legend(p1, p2) ## ----tables-------------------------------------------------------------- grid.arrange( tableGrob(mtcars[1:4, 1:4]), p2, ncol = 2, widths = c(1.5, 1), clip = FALSE ) ## ----comparison, echo=FALSE, message=FALSE, warnings=FALSE, results='asis'---- tabl <- " | Package | Function(s) | ggsave compat. | alignment | |-------------------|:-------------:|:------:|:----------:| | grid | `viewport`, `grid.layout` | no | no | | [gridExtra][1] | `grid.arrange` | yes | no | | [(r cookbook)][2] | `multiplot` | no | no | | [gtable][3] | `rbind`, `cbind`| yes | yes | | [cowplot][4] | `plot_grid` | yes* | yes* | | [multipanelfigure][5] | `multi_panel_figure` | yes | yes | | [egg][6] | `ggarrange` | yes | yes | | [patchwork][7] | `plot_layout` | yes | yes | " cat(tabl) ## ----comp---------------------------------------------------------------- pushViewport(viewport(layout = grid.layout(2, 2))) vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y) print(p1, vp = vplayout(1, 1:2)) print(p2, vp = vplayout(2, 1)) print(p3, vp = vplayout(2, 2)) egg/inst/doc/Overview.R0000644000176200001440000001307413512266054014500 0ustar liggesusers## ----setup, echo=FALSE, results='hide', message=FALSE-------------------- library(egg) library(grid) library(gridExtra) library(gtable) library(knitr) opts_chunk$set(message = FALSE, fig.width = 7, fig.height = 3) ## ----layout-------------------------------------------------------------- p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- qplot(mpg, data = mtcars) + ggtitle("title") p3 <- qplot(mpg, data = mtcars, geom = "dotplot") p4 <- p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") + ggtitle("facetted plot") pl <- lapply(list(p1, p2, p3, p4), expose_layout, FALSE, FALSE) grid.arrange( grobs = pl, widths = c(1.2, 1, 1), layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)) ) ## ----panel, fig.height=3.5----------------------------------------------- p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- p1 + facet_wrap( ~ carb, nrow = 1) grid.arrange(grobs = lapply( list(p1, p2), set_panel_size, width = unit(2, "cm"), height = unit(1, "in") )) ## ----frame--------------------------------------------------------------- p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme() p3 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_grid(. ~ cyl, scales = "free") g1 <- ggplotGrob(p1) g2 <- ggplotGrob(p2) g3 <- ggplotGrob(p3) fg1 <- gtable_frame(g1, debug = TRUE) fg2 <- gtable_frame(g2, debug = TRUE) fg12 <- gtable_frame(gtable_rbind(fg1, fg2), width = unit(2, "null"), height = unit(1, "null")) fg3 <- gtable_frame( g3, width = unit(1, "null"), height = unit(1, "null"), debug = TRUE ) grid.newpage() combined <- gtable_cbind(fg12, fg3) grid.draw(combined) ## ----ggarrange----------------------------------------------------------- p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point()+ theme_article() + theme(legend.position = 'top') p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme_article() ggarrange(p1, p2, widths = c(1.5,2)) ## ----ggarrangelayout----------------------------------------------------- p <- ggplot() ggarrange(p, p, p, widths = c(3, 1), heights = c(5, 1)) ## ----ggarrangelabels----------------------------------------------------- ggarrange(p1, p2, p3, ncol=2, labels = c("A", "b)", "iii."), label.args = list(gp=gpar(font=4), x=unit(1,"line"), hjust=0)) ## ----tagfacet------------------------------------------------------------ d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) tag_facet(p) tag_facet_outside(p) ## ----themes-------------------------------------------------------------- d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) p + theme_article() ## ----symmetrise---------------------------------------------------------- df = data.frame(x = c(1, 2), y = c(5, 0.2), group = c(1, 2)) p <- ggplot(df, aes(x = x, y = y)) + geom_point() + facet_wrap( ~ group, scale = "free") p + scale_y_continuous(limits = symmetric_range) ## ----custompics---------------------------------------------------------- codes <- data.frame(country = c("nz","ca","ar","fr","gb","es")) codes$y <- runif(nrow(codes)) gl <- lapply(codes$country, function(.x) png::readPNG(system.file("flags", paste0(.x,".png"), package="egg"))) codes$raster <- I(gl) ggplot(codes, aes(x = country, y = y)) + geom_point() + geom_custom(data = codes, aes(data=raster), grob_fun = rasterGrob, fun_params = list(height=unit(1,"cm"))) + scale_y_continuous(breaks=NULL, "") + theme(panel.grid = element_blank()) ## ----customgrobs--------------------------------------------------------- codes$raster <- I(lapply(codes$raster, function(x) rasterGrob(x, height=unit(1,"cm")))) ggplot(codes, aes(x = country, y = y)) + geom_point() + geom_custom(data = codes, aes(data=raster), grob_fun = identity) ## ----customgrobcoord----------------------------------------------------- custom_grob <- function(data, x=0.5,y=0.5){ grob(data=data,x=x,y=y, cl="custom") } preDrawDetails.custom <- function(x){ pushViewport(viewport(x=x$x,y=x$y)) } postDrawDetails.custom <- function(x){ upViewport() } drawDetails.custom <- function(x, recording=FALSE, ...){ grid.rect(mean(x$data$x), mean(x$data$y), width=diff(range(x$data$x)), height=diff(range(x$data$y))) grid.lines(x$data$x, x$data$y, gp=gpar(col=x$data$col,lwd=2), default.units = "native") } d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3)) gl <- lapply(1:4, function(ii){ data.frame(x=seq(0.4,0.6,length=10), y = runif(10,0.45,0.55), col = hcl(h = seq(0,300,length=nrow(d)))[ii], stringsAsFactors = FALSE) }) subplots <- data.frame(f=letters[1:4], data = I(gl)) str(subplots) ggplot(d, aes(f,x)) + facet_wrap(~f, nrow=1)+ coord_polar() + geom_point()+ geom_custom(data = subplots, aes(data = data, x = f, y = 2), grob_fun = custom_grob) egg/inst/doc/Ecosystem.html0000644000176200001440000161147013512266044015414 0ustar liggesusers Laying out multiple plots on a page

Laying out multiple plots on a page

Baptiste Auguié

2019-07-13

An individual ggplot object contains multiple pieces – axes, plot panel(s), titles, legends –, and their layout is defined and enforced via the gtable package, itself built around the lower-level grid package. Plots themselves become graphical objects, which can be arranged on a page using e.g. the gridExtra or egg packages, which provide helper functions for such multi-object layouts. The following schematic illustrates the main relations between these packages.

Schematic illustration of the links between packages ggplot2, gtable, grid, egg and gridExtra.

Schematic illustration of the links between packages ggplot2, gtable, grid, egg and gridExtra.

Arranging multiple plots on a page

To begin, we’ll create four example plots that we can experiment with.

library(ggplot2)
p1 <- qplot(mpg, wt, data = mtcars, colour = cyl)
p2 <- qplot(mpg, data = mtcars) + ggtitle("title")
p3 <- qplot(mpg, data = mtcars, geom = "dotplot")
p4 <-
  p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") +
  ggtitle("facetted plot")
A few plots that we want to organise on a page.

A few plots that we want to organise on a page.

Basic strategy

The easiest approach to assemble multiple plots on a page is to use the grid.arrange() function from the gridExtra package; in fact, that’s what we used for the previous figure. With grid.arrange(), one can reproduce the behaviour of the base functions par(mfrow=c(r,c)), specifying either the number of rows or columns,

Basic usage of grid.arrange()

Basic usage of grid.arrange()

If layout parameters are ommitted altogether, grid.arrange() will calculate a default number of rows and columns to organise the plots.

More complex layouts can be achieved by passing specific dimensions (widths or heights), or a layout matrix defining the position of each plot in a rectangular grid. For the sake of clarity, we’ll use a list gl of dummy rectangles, but the process is identical for plots.

Illustrating further arguments of grid.arrange(), namely layout_matrix and relative widths.

Illustrating further arguments of grid.arrange(), namely layout_matrix and relative widths.

Further examples are available in a dedicated gridExtra vignette.

Plot insets

A special case of layouts is where one of the plots is to be placed within another, typically as an inset of the plot panel. In this case, grid.arrange() cannot help, as it only provides rectangular layouts with non-overlapping cells. Instead, a simple solution is to convert the plot into a grob, and place it using annotation_custom() within the plot panel. Note the related geom_custom() function, suitable when different facets should display different annotations.

Plot inset.

Plot inset.

In the second annotation, we used the convenient shorthand +/-Inf to signify the edge of the plot, irrespective of the data range.

An alternative way to place custom annotations within the plots is to use raw grid commands, which we will present at the end of this document. However, note that an advantage of using annotation_custom is that the inset plot is embedded in the main plot, therefore the whole layout can be saved with ggsave(), which will not be the case for plot modifications at the grid level.

Aligning plot panels

A common request for presenting multiple plots on a single page is to align the plot panels. Often, facetting the plot solves this issue, with a flexible syntax, and in the true spirit of the Grammar of Graphics that inspired the ggplot2 design. However, in some situations, the various plot panels cannot easily be combined in a unique plot; for instance when using different geoms, or different colour scales.

grid.arrange() makes no attempt at aligning the plot panels; instead, it merely places the objects into a rectangular grid, where they fit each cell according to the varying size of plot elements. The following figure illustrates the typical structure of ggplots.

Colour-coded structure of examplar ggplot layouts. Note how the panels (red) vary in size from plot to plot, as they accommodate the other graphical components.

Colour-coded structure of examplar ggplot layouts. Note how the panels (red) vary in size from plot to plot, as they accommodate the other graphical components.

As we can readily appreciate, each plot panel stretches or shrinks according to the other plot elements, e.g. guides, axes, titles, etc. This often results in misaligned plot panels.

In this situation, instead of using grid.arrange(), we recommend to switch to the more powerful gtable package. In particular, the rbind(), cbind(), and join functions can provide a better alignment. The plots must first be converted to grobs (more specifically, gtables), using the ggplotGrob() function. The second step is to bind the two gtables, using the sizes from the first object, then assigning them to the maximum. Finally, the resulting object, a gtable, can be displayed using grid.draw() (it is no longer a ggplot, so print() no longer renders it on a device).

Aligning plot panels. Note that the two y axes have different widths.

Aligning plot panels. Note that the two y axes have different widths.

Aligning complex plots

One possible strategy, implemented in egg with the low-level gtable_frame and high-level ggarrange functions, is to take the following steps:

Aligning plots is achieved simply as follows,

where many parameters are common to the grid.arrange() function from gridExtra.

Multiple pages?

Plots produced by ggplot2, including those with facets, and those combined with grid.arrange(), are always displayed on a single page. Sometimes, however, there isn’t enough room to display all the information, and it becomes necessary to split the output on multiple pages. A convenient approach consists in storing all the plots in a list, and plotting subsets of them on subsequent pages. The gridExtra package can simplify this process with the helper function marrangeGrob(), sharing a common syntax with grid.arrange(), but outputting as many pages as required by the total number of plots and per-page layout.

Mixed graphical components

Titles and subtitles

Adding a global title and/or subtitle to a page with multiple plots is easy with grid.arrange(): use the top, bottom, left, or right parameters to pass either a text string, or a grob for finer control.

Recent versions of ggplot2 have added built-in options to add a subtitle and a caption; the two stategies are somewhat complementary (grid.arrange aligns elements with respect to the entire plot, whereas ggplot2 places them with respect to the plot panel area).

Legends

When arranging multiple plots, one may wish to share a legend between some of them (although in general this is a clear hint that facetting might be a better option). The procedure involves extracting the legend from one graph, creating a custom layout, and inserting the plots and legend in their corresponding cell.

Tables and other grobs

As we’ve seen in the previous examples, ggplots are grobs, which can be placed and manipulated. Likewise, other grobs can be added to the mix. For instance, one may wish to add a small table next to the plot, as produced by the tableGrob function in gridExtra.

Alternative options

We’ve focused on grid.arrange() and ggarrange for simplicity, but there are numerous alternatives to achieve similar arrangements of plots (all of which ultimately based on grid). We list below a few alternatives, in chronological order.

Package Function(s) ggsave compat. alignment
grid viewport, grid.layout no no
gridExtra grid.arrange yes no
(r cookbook) multiplot no no
gtable rbind, cbind yes yes
cowplot plot_grid yes* yes*
multipanelfigure multi_panel_figure yes yes
egg ggarrange yes yes
patchwork plot_layout yes yes

grid viewports and layouts

Underlying all these other packages is the grid package, included in the core R distribution. This package provides the low-level functions used for drawing and placing objects on a device.

Acknowledgements

Parts of this document were originally written by Hadley Wickham as a draft vignette for the ggplot2 package; the contents have since been shuffled around quite a bit and I have lost track of the exact history of edits.

egg/inst/doc/Overview.html0000644000176200001440000211200413512266054015236 0ustar liggesusers Overview of the egg package

Overview of the egg package

Baptiste Auguié

2019-07-13

This document provides a brief overview of the main utiilty functions included in the egg package.

Exposing ggplot2 layouts

The function expose_layout can be useful to illustrate the structure of ggplot2 plots, e.g. when ying to customise and/or post-process the gtable layout.

p1 <- qplot(mpg, wt, data = mtcars, colour = cyl)
p2 <- qplot(mpg, data = mtcars) + ggtitle("title")
p3 <- qplot(mpg, data = mtcars, geom = "dotplot")
p4 <-
p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") +
ggtitle("facetted plot")
pl <- lapply(list(p1, p2, p3, p4), expose_layout, FALSE, FALSE)
grid.arrange(
grobs = pl,
widths = c(1.2, 1, 1),
layout_matrix = rbind(c(1, 2, 3),
c(4, 4, 4))
)

Setting panel size

In some cases, having ggplot2 expand the plot panel to best fit the available space isn’t ideal: for instance, we may want to produce multiple plots to appear on different slides of a presentation, and the successive pages should have the exact same layout for smooth visual transition. Another use-case is to embed multiple separate graphics in a drawing/page layout software. In this situation the plot alignement will be made manually, but the plots should not be rescaled (otherwise the fonts would be distorted). For such situations, the easiest solution is to set fixed dimensions to the gtable produced by ggplot2.

The function set_panel_size helps set the panel size (width, height) to absolute measurements in the form of grid units. In the case of a facetted plot, all panels are set to the same value.

  p1 <- qplot(mpg, wt, data = mtcars, colour = cyl)
p2 <- p1 + facet_wrap( ~ carb, nrow = 1)
grid.arrange(grobs = lapply(
list(p1, p2),
set_panel_size,
width = unit(2, "cm"),
height = unit(1, "in")
))

Note that the total size is now fixed, therefore when exporting the plot on a device it can be useful to query the size and set the width and height accordingly, to avoid clipping or white margins. This extra step is enabled by default when saving the results to a file.

Aligning complex ggplots

gridExtra::grid.arrange provides no way to align the panels of individual plots. While this is achievable with low-level gtable functions, it often requires substantial effort on a case-by-case basis. The egg package introduces a general strategy for such layout manipulations, with the following steps:

p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point()

p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") +
  guides(colour = "none") +
  theme()

p3 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() + facet_grid(. ~ cyl, scales = "free")

g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(p2)
g3 <- ggplotGrob(p3)

fg1 <- gtable_frame(g1, debug = TRUE)
fg2 <- gtable_frame(g2, debug = TRUE)
fg12 <-
  gtable_frame(gtable_rbind(fg1, fg2),
               width = unit(2, "null"),
               height = unit(1, "null"))
fg3 <-
  gtable_frame(
    g3,
    width = unit(1, "null"),
    height = unit(1, "null"),
    debug = TRUE
  )
grid.newpage()
combined <- gtable_cbind(fg12, fg3)
grid.draw(combined)

Arranging and aligning multiple plots

Using this generic strategy, we can easily align arbitrary plots (facetted or single-panel), with the convenience function ggarrange,

p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point()+ theme_article() + theme(legend.position = 'top') 
p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") +
  guides(colour = "none") +
  theme_article()
  
ggarrange(p1, p2, widths = c(1.5,2))

Note that custom widths and heights may be provided for the layout.

p <- ggplot()
ggarrange(p, p, p, widths = c(3, 1), heights = c(5, 1))

For convenience, labels can be added to refer to the subfigures. All parameters of textGrob can be used for the formatting of the labels, including the positioning (x, hjust, etc.).

ggarrange(p1, p2, p3, ncol=2,
          labels = c("A", "b)", "iii."), 
          label.args = list(gp=gpar(font=4), x=unit(1,"line"), hjust=0))

The package provides two functions for labelling facetted plots in a more compact manner, removing panel strips and using in-panel tags instead:

d = data.frame(
  x = 1:90,
  y = rnorm(90),
  red = rep(letters[1:3], 30),
  blue = c(rep(1, 30), rep(2, 30), rep(3, 30)))

p <- ggplot(d) +
  geom_point(aes(x = x, y = y)) +
  facet_grid(red ~ blue)
  
tag_facet(p)

tag_facet_outside(p)

Custom themes

egg provides theme_article and theme_presentation,

d = data.frame(
  x = 1:90,
  y = rnorm(90),
  red = rep(letters[1:3], 30),
  blue = c(rep(1, 30), rep(2, 30), rep(3, 30)))

p <- ggplot(d) +
  geom_point(aes(x = x, y = y)) +
  facet_grid(red ~ blue)

p + theme_article()

Symmetric axis scale

The function symmetric_range helps align the 0 value of adjacent panels in facetted plots with asymmetric range of data in each group.

df = data.frame(x = c(1, 2),
                y = c(5, 0.2),
                group = c(1, 2))
p <- ggplot(df, aes(x = x, y = y)) + 
  geom_point() + 
  facet_wrap( ~ group, scale =
                "free")
p + scale_y_continuous(limits = symmetric_range)

Custom geom

The function geom_custom extends the ggplot2 function annotation_custom to cases where multiple grobs are to be placed, e.g. on different panels, or at different positions in a plot. This geom is a bit special in that it does not truly respect a grammar of graphics – arbitrary grobs can be plotted, with no explicit mapping to variables. Its typical use would be to place annotations (images, tables, …). The data used to create the annotation is passed as a list-column.

codes <- data.frame(country = c("nz","ca","ar","fr","gb","es"))
codes$y <- runif(nrow(codes))

gl <- lapply(codes$country, 
                    function(.x) png::readPNG(system.file("flags", 
                                             paste0(.x,".png"),
                                             package="egg")))

codes$raster <- I(gl)


ggplot(codes, aes(x = country, y = y)) + 
  geom_point() + 
  geom_custom(data = codes, aes(data=raster), 
              grob_fun = rasterGrob, 
              fun_params = list(height=unit(1,"cm"))) +
  scale_y_continuous(breaks=NULL, "") +
  theme(panel.grid = element_blank())

The list-column format allows passing grobs directly, in which case the grob_fun function should be identity,

codes$raster <- I(lapply(codes$raster, function(x) rasterGrob(x, height=unit(1,"cm"))))

ggplot(codes, aes(x = country, y = y)) + 
  geom_point() +
  geom_custom(data = codes, aes(data=raster), 
              grob_fun = identity)

Note that such grobs need to have x and y slots, which will be mapped to the appropriate location. It is therefore often necessary to create a wrapper with such fields, as illustrated below.

Because the grobs are manually “mapped”, independently of the main ggplot, this geom also allows the placing of arbitrary annotations without interference from transformed coordinate systems, etc.

custom_grob <- function(data, x=0.5,y=0.5){
  grob(data=data,x=x,y=y, cl="custom")
}
preDrawDetails.custom <- function(x){
  pushViewport(viewport(x=x$x,y=x$y))
}
postDrawDetails.custom <- function(x){
  upViewport()
}
drawDetails.custom <- function(x, recording=FALSE, ...){
  grid.rect(mean(x$data$x), mean(x$data$y), 
            width=diff(range(x$data$x)), 
            height=diff(range(x$data$y)))
  grid.lines(x$data$x, x$data$y, gp=gpar(col=x$data$col,lwd=2), default.units = "native")
}

d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3))
gl <- lapply(1:4, function(ii){
  data.frame(x=seq(0.4,0.6,length=10),
             y = runif(10,0.45,0.55),
             col = hcl(h = seq(0,300,length=nrow(d)))[ii],
             stringsAsFactors = FALSE)
})
subplots <- data.frame(f=letters[1:4], data = I(gl))
str(subplots)
## 'data.frame':    4 obs. of  2 variables:
##  $ f   : Factor w/ 4 levels "a","b","c","d": 1 2 3 4
##  $ data:List of 4
##   ..$ :'data.frame': 10 obs. of  3 variables:
##   .. ..$ x  : num  0.4 0.422 0.444 0.467 0.489 ...
##   .. ..$ y  : num  0.469 0.452 0.491 0.498 0.492 ...
##   .. ..$ col: chr  "#FFC5D0" "#FFC5D0" "#FFC5D0" "#FFC5D0" ...
##   ..$ :'data.frame': 10 obs. of  3 variables:
##   .. ..$ x  : num  0.4 0.422 0.444 0.467 0.489 ...
##   .. ..$ y  : num  0.527 0.471 0.481 0.547 0.508 ...
##   .. ..$ col: chr  "#FACABC" "#FACABC" "#FACABC" "#FACABC" ...
##   ..$ :'data.frame': 10 obs. of  3 variables:
##   .. ..$ x  : num  0.4 0.422 0.444 0.467 0.489 ...
##   .. ..$ y  : num  0.469 0.478 0.459 0.471 0.548 ...
##   .. ..$ col: chr  "#EDD0AD" "#EDD0AD" "#EDD0AD" "#EDD0AD" ...
##   ..$ :'data.frame': 10 obs. of  3 variables:
##   .. ..$ x  : num  0.4 0.422 0.444 0.467 0.489 ...
##   .. ..$ y  : num  0.477 0.46 0.462 0.549 0.549 ...
##   .. ..$ col: chr  "#DAD6A7" "#DAD6A7" "#DAD6A7" "#DAD6A7" ...
##   ..- attr(*, "class")= chr "AsIs"
ggplot(d, aes(f,x)) +
  facet_wrap(~f, nrow=1)+
  coord_polar() +
  geom_point()+
  geom_custom(data = subplots, aes(data = data, x = f, y = 2), 
              grob_fun = custom_grob) 

egg/inst/doc/Ecosystem.Rmd0000644000176200001440000003366413512266011015166 0ustar liggesusers--- title: "Laying out multiple plots on a page" author: "Baptiste Auguié" date: '`r Sys.Date()`' vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Laying out multiple plots on a page} %\VignetteEncoding{UTF-8} output: rmarkdown::html_vignette: toc: true toc_depth: 3 --- ```{r setup, echo=FALSE, results='hide', message=FALSE} library(knitr) library(gridExtra) library(egg) library(gtable) library(grid) opts_chunk$set( message = FALSE, fig.width = 6, fig.height = 3, cache = FALSE ) ``` An individual ggplot object contains multiple pieces -- axes, plot panel(s), titles, legends --, and their layout is defined and enforced via the `gtable` package, itself built around the lower-level `grid` package. Plots themselves become _graphical objects_, which can be arranged on a page using e.g. the `gridExtra` or `egg` packages, which provide helper functions for such multi-object layouts. The following schematic illustrates the main relations between these packages. ![Schematic illustration of the links between packages `ggplot2`, `gtable`, `grid`, `egg` and `gridExtra`.](ecosystem.png) ## Arranging multiple plots on a page To begin, we'll create four example plots that we can experiment with. ```{r basic, echo=2:6, fig.height=5, fig.cap="A few plots that we want to organise on a page."} set.seed(123) library(ggplot2) p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- qplot(mpg, data = mtcars) + ggtitle("title") p3 <- qplot(mpg, data = mtcars, geom = "dotplot") p4 <- p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") + ggtitle("facetted plot") library(gridExtra) grid.arrange(p1, p2, p3, p4, layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)), widths = c(1.2, 1, 1)) ``` ### Basic strategy The easiest approach to assemble multiple plots on a page is to use the `grid.arrange()` function from the `gridExtra` package; in fact, that's what we used for the previous figure. With `grid.arrange()`, one can reproduce the behaviour of the base functions `par(mfrow=c(r,c))`, specifying either the number of rows or columns, ```{r arrange1, echo=TRUE, fig.height=3, fig.cap="Basic usage of `grid.arrange()`"} grid.arrange(p1, p2, nrow = 1) ``` If layout parameters are ommitted altogether, `grid.arrange()` will calculate a default number of rows and columns to organise the plots. More complex layouts can be achieved by passing specific dimensions (widths or heights), or a layout matrix defining the position of each plot in a rectangular grid. For the sake of clarity, we'll use a list `gl` of dummy rectangles, but the process is identical for plots. ```{r arrange2, echo=-c(1:2), fig.width=4, fig.height=3, fig.cap="Illustrating further arguments of `grid.arrange()`, namely `layout_matrix` and relative widths."} cols <- c( "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC" ) gl <- lapply(1:4, function(x) grobTree(rectGrob(gp = gpar(fill = cols[x])), textGrob(paste("plot", x)))) grid.arrange( grobs = gl, widths = c(2, 1, 1), layout_matrix = rbind(c(1, 2, NA), c(3, 3, 4)) ) ``` Further examples are available in a dedicated `gridExtra` [vignette](https://CRAN.R-project.org/package=gridExtra/vignettes/arrangeGrob.html). ### Plot insets A special case of layouts is where one of the plots is to be placed within another, typically as an inset of the plot panel. In this case, `grid.arrange()` cannot help, as it only provides rectangular layouts with non-overlapping cells. Instead, a simple solution is to convert the plot into a *grob*, and place it using `annotation_custom()` within the plot panel. Note the related `geom_custom()` function, suitable when different facets should display different annotations. ```{r inset, fig.width=4, fig.height=3, fig.cap="Plot inset."} g <- ggplotGrob(qplot(1, 1) + theme(plot.background = element_rect(colour = "black"))) qplot(1:10, 1:10) + annotation_custom( grob = g, xmin = 1, xmax = 5, ymin = 5, ymax = 10 ) + annotation_custom( grob = rectGrob(gp = gpar(fill = "white")), xmin = 7.5, xmax = Inf, ymin = -Inf, ymax = 5 ) ``` In the second annotation, we used the convenient shorthand `+/-Inf` to signify the edge of the plot, irrespective of the data range. An alternative way to place custom annotations within the plots is to use raw grid commands, which we will present at the end of this document. However, note that an advantage of using `annotation_custom` is that the inset plot is embedded in the main plot, therefore the whole layout can be saved with `ggsave()`, which will not be the case for plot modifications at the `grid` level. ### Aligning plot panels A common request for presenting multiple plots on a single page is to align the plot panels. Often, *facetting* the plot solves this issue, with a flexible syntax, and in the true spirit of the Grammar of Graphics that inspired the ggplot2 design. However, in some situations, the various plot panels cannot easily be combined in a unique plot; for instance when using different geoms, or different colour scales. `grid.arrange()` makes no attempt at aligning the plot panels; instead, it merely places the objects into a rectangular grid, where they fit each cell according to the varying size of plot elements. The following figure illustrates the typical structure of ggplots. ```{r plotstructure, echo=FALSE, fig.width=6, fig.height=3, fig.cap="Colour-coded structure of examplar ggplot layouts. Note how the panels (red) vary in size from plot to plot, as they accommodate the other graphical components."} pl <- lapply(list(p1, p2, p3, p4), expose_layout, FALSE, FALSE) layouts <- arrangeGrob( grobs = pl, widths = c(1.2, 1, 1), layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)) ) ids <- c("background", "panel", "axis", "lab", "guide", "strip", "title") cols <- c( "grey95", "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC" ) leg <- lapply(ids, textGrob, hjust = 0, x = 0.1) legend <- gtable_matrix( "legend", matrix(leg, ncol = 1), widths = 1.2 * grobWidth(leg[[1]]), heights = unit(rep(1, length(leg)), "line") ) legend <- gtable_add_cols(legend, unit(1, "line"), 0) legend <- gtable_add_grob(legend, t = seq_along(leg), l = 1, lapply(cols[seq_along(ids)], function(x) rectGrob(gp = gpar(fill = x, col = NA)))) grid.arrange(layouts, legend, widths = unit.c(unit(1, "null"), 1.2 * sum(legend$widths))) ``` As we can readily appreciate, each plot panel stretches or shrinks according to the other plot elements, e.g. guides, axes, titles, etc. This often results in misaligned plot panels. In this situation, instead of using `grid.arrange()`, we recommend to switch to the more powerful `gtable` package. In particular, the `rbind()`, `cbind()`, and `join` functions can provide a better alignment. The plots must first be converted to grobs (more specifically, gtables), using the `ggplotGrob()` function. The second step is to `bind` the two gtables, using the sizes from the first object, then assigning them to the maximum. Finally, the resulting object, a gtable, can be displayed using `grid.draw()` (it is no longer a `ggplot`, so `print()` no longer renders it on a device). ```{r rbind, fig.height=4, fig.width=4, fig.cap="Aligning plot panels. Note that the two y axes have different widths."} library(gtable) g2 <- ggplotGrob(p2) g3 <- ggplotGrob(p3) g <- rbind(g2, g3, size = "first") g$widths <- unit.pmax(g2$widths, g3$widths) grid.newpage() grid.draw(g) ``` ### Aligning complex plots One possible strategy, implemented in `egg` with the low-level `gtable_frame` and high-level `ggarrange` functions, is to take the following steps: - decompose each plot into a 3x3 layout, where the central cell corresponds to the core panels, surrounded by axes, legends, etc. - set the core width and height to a fixed dimension - bind the individual 3x3 gtables Aligning plots is achieved simply as follows, ```{r egg, fig.height=3, fig.width=6} p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point()+ theme_article() + theme(legend.position = 'top') p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme_article() ggarrange(p1, p2, widths = c(1.5,2)) ``` where many parameters are common to the `grid.arrange()` function from `gridExtra`. ### Multiple pages? Plots produced by `ggplot2`, including those with facets, and those combined with `grid.arrange()`, are always displayed on a single page. Sometimes, however, there isn't enough room to display all the information, and it becomes necessary to split the output on multiple pages. A convenient approach consists in storing all the plots in a list, and plotting subsets of them on subsequent pages. The `gridExtra` package can simplify this process with the helper function `marrangeGrob()`, sharing a common syntax with `grid.arrange()`, but outputting as many pages as required by the total number of plots and per-page layout. ## Mixed graphical components ### Titles and subtitles Adding a global title and/or subtitle to a page with multiple plots is easy with `grid.arrange()`: use the `top`, `bottom`, `left`, or `right` parameters to pass either a text string, or a grob for finer control. ```{r titles} grid.arrange( p3, p3, p3, nrow = 1, top = "Title of the page", bottom = textGrob( "this footnote is right-justified", gp = gpar(fontface = 3, fontsize = 9), hjust = 1, x = 1 ) ) ``` Recent versions of ggplot2 have added built-in options to add a subtitle and a caption; the two stategies are somewhat complementary (`grid.arrange` aligns elements with respect to the entire plot, whereas ggplot2 places them with respect to the plot panel area). ### Legends When arranging multiple plots, one may wish to share a legend between some of them (although in general this is a clear hint that facetting might be a better option). The procedure involves extracting the legend from one graph, creating a custom layout, and inserting the plots and legend in their corresponding cell. ```{r legend, echo=TRUE, fig.height=4} grid_arrange_shared_legend <- function(..., ncol = length(list(...)), nrow = 1, position = c("bottom", "right")) { plots <- list(...) position <- match.arg(position) g <- ggplotGrob(plots[[1]] + theme(legend.position = position))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) lwidth <- sum(legend$width) gl <- lapply(plots, function(x) x + theme(legend.position = "none")) gl <- c(gl, ncol = ncol, nrow = nrow) combined <- switch( position, "bottom" = arrangeGrob( do.call(arrangeGrob, gl), legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight) ), "right" = arrangeGrob( do.call(arrangeGrob, gl), legend, ncol = 2, widths = unit.c(unit(1, "npc") - lwidth, lwidth) ) ) grid.newpage() grid.draw(combined) # return gtable invisibly invisible(combined) } grid_arrange_shared_legend(p1, p2) ``` ### Tables and other grobs As we've seen in the previous examples, `ggplots` are grobs, which can be placed and manipulated. Likewise, other grobs can be added to the mix. For instance, one may wish to add a small table next to the plot, as produced by the `tableGrob` function in `gridExtra`. ```{r tables} grid.arrange( tableGrob(mtcars[1:4, 1:4]), p2, ncol = 2, widths = c(1.5, 1), clip = FALSE ) ``` ## Alternative options We've focused on `grid.arrange()` and `ggarrange` for simplicity, but there are numerous alternatives to achieve similar arrangements of plots (all of which ultimately based on `grid`). We list below a few alternatives, in chronological order. ```{r comparison, echo=FALSE, message=FALSE, warnings=FALSE, results='asis'} tabl <- " | Package | Function(s) | ggsave compat. | alignment | |-------------------|:-------------:|:------:|:----------:| | grid | `viewport`, `grid.layout` | no | no | | [gridExtra][1] | `grid.arrange` | yes | no | | [(r cookbook)][2] | `multiplot` | no | no | | [gtable][3] | `rbind`, `cbind`| yes | yes | | [cowplot][4] | `plot_grid` | yes* | yes* | | [multipanelfigure][5] | `multi_panel_figure` | yes | yes | | [egg][6] | `ggarrange` | yes | yes | | [patchwork][7] | `plot_layout` | yes | yes | " cat(tabl) ``` [1]: https://CRAN.R-project.org/package=gridExtra [2]: http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2) [3]: https://CRAN.R-project.org/package=gtable [4]: https://CRAN.R-project.org/package=cowplot [5]: https://CRAN.R-project.org/package=multipanelfigure [6]: https://CRAN.R-project.org/package=egg [7]: https://github.com/thomasp85/patchwork ### grid viewports and layouts Underlying all these other packages is the `grid` package, included in the core R distribution. This package provides the low-level functions used for drawing and placing objects on a device. ```{r comp} pushViewport(viewport(layout = grid.layout(2, 2))) vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y) print(p1, vp = vplayout(1, 1:2)) print(p2, vp = vplayout(2, 1)) print(p3, vp = vplayout(2, 2)) ``` ## Acknowledgements Parts of this document were [originally written by Hadley Wickham as a draft vignette](https://github.com/tidyverse/ggplot2/issues/1239) for the `ggplot2` package; the contents have since been shuffled around quite a bit and I have lost track of the exact history of edits. egg/inst/doc/Overview.Rmd0000644000176200001440000002167713512226504015025 0ustar liggesusers--- title: "Overview of the egg package" author: "Baptiste Auguié" date: '`r Sys.Date()`' vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Overview of the egg package} %\VignetteEncoding{UTF-8} output: rmarkdown::html_vignette: toc: true toc_depth: 3 --- ```{r setup, echo=FALSE, results='hide', message=FALSE} library(egg) library(grid) library(gridExtra) library(gtable) library(knitr) opts_chunk$set(message = FALSE, fig.width = 7, fig.height = 3) ``` This document provides a brief overview of the main utiilty functions included in the `egg` package. ## Exposing ggplot2 layouts The function `expose_layout` can be useful to illustrate the structure of ggplot2 plots, e.g. when ying to customise and/or post-process the gtable layout. ```{r layout} p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- qplot(mpg, data = mtcars) + ggtitle("title") p3 <- qplot(mpg, data = mtcars, geom = "dotplot") p4 <- p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") + ggtitle("facetted plot") pl <- lapply(list(p1, p2, p3, p4), expose_layout, FALSE, FALSE) grid.arrange( grobs = pl, widths = c(1.2, 1, 1), layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)) ) ``` ## Setting panel size In some cases, having ggplot2 expand the plot panel to best fit the available space isn't ideal: for instance, we may want to produce multiple plots to appear on different slides of a presentation, and the successive pages should have the exact same layout for smooth visual transition. Another use-case is to embed multiple separate graphics in a drawing/page layout software. In this situation the plot alignement will be made manually, but the plots should not be rescaled (otherwise the fonts would be distorted). For such situations, the easiest solution is to set fixed dimensions to the gtable produced by ggplot2. The function `set_panel_size` helps set the panel size (width, height) to absolute measurements in the form of grid units. In the case of a facetted plot, all panels are set to the same value. ```{r panel, fig.height=3.5} p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- p1 + facet_wrap( ~ carb, nrow = 1) grid.arrange(grobs = lapply( list(p1, p2), set_panel_size, width = unit(2, "cm"), height = unit(1, "in") )) ``` Note that the total size is now fixed, therefore when exporting the plot on a device it can be useful to query the size and set the width and height accordingly, to avoid clipping or white margins. This extra step is enabled by default when saving the results to a file. ## Aligning complex ggplots `gridExtra::grid.arrange` provides no way to align the panels of individual plots. While this is achievable with low-level `gtable` functions, it often requires substantial effort on a case-by-case basis. The `egg` package introduces a general strategy for such layout manipulations, with the following steps: - decompose each plot into a 3x3 layout, where the central cell corresponds to the core panels, surrounded by axes, legends, etc. - set the core width and height to a fixed dimension - align the individual 3x3 gtables using `rbind`/`cbind` ```{r frame} p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme() p3 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_grid(. ~ cyl, scales = "free") g1 <- ggplotGrob(p1) g2 <- ggplotGrob(p2) g3 <- ggplotGrob(p3) fg1 <- gtable_frame(g1, debug = TRUE) fg2 <- gtable_frame(g2, debug = TRUE) fg12 <- gtable_frame(gtable_rbind(fg1, fg2), width = unit(2, "null"), height = unit(1, "null")) fg3 <- gtable_frame( g3, width = unit(1, "null"), height = unit(1, "null"), debug = TRUE ) grid.newpage() combined <- gtable_cbind(fg12, fg3) grid.draw(combined) ``` ## Arranging and aligning multiple plots Using this generic strategy, we can easily align arbitrary plots (facetted or single-panel), with the convenience function `ggarrange`, ```{r ggarrange} p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point()+ theme_article() + theme(legend.position = 'top') p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme_article() ggarrange(p1, p2, widths = c(1.5,2)) ``` Note that custom widths and heights may be provided for the layout. ```{r ggarrangelayout} p <- ggplot() ggarrange(p, p, p, widths = c(3, 1), heights = c(5, 1)) ``` For convenience, labels can be added to refer to the subfigures. All parameters of `textGrob` can be used for the formatting of the labels, including the positioning (`x`, `hjust`, etc.). ```{r ggarrangelabels} ggarrange(p1, p2, p3, ncol=2, labels = c("A", "b)", "iii."), label.args = list(gp=gpar(font=4), x=unit(1,"line"), hjust=0)) ``` The package provides two functions for labelling facetted plots in a more compact manner, removing panel strips and using in-panel tags instead: ```{r tagfacet} d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) tag_facet(p) tag_facet_outside(p) ``` ## Custom themes `egg` provides `theme_article` and `theme_presentation`, ```{r themes} d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) p + theme_article() ``` ## Symmetric axis scale The function `symmetric_range` helps align the 0 value of adjacent panels in facetted plots with asymmetric range of data in each group. ```{r symmetrise} df = data.frame(x = c(1, 2), y = c(5, 0.2), group = c(1, 2)) p <- ggplot(df, aes(x = x, y = y)) + geom_point() + facet_wrap( ~ group, scale = "free") p + scale_y_continuous(limits = symmetric_range) ``` ## Custom geom The function `geom_custom` extends the ggplot2 function `annotation_custom` to cases where multiple grobs are to be placed, e.g. on different panels, or at different positions in a plot. This geom is a bit special in that it does not truly respect a *grammar of graphics* -- arbitrary grobs can be plotted, with no explicit mapping to variables. Its typical use would be to place annotations (images, tables, ...). The data used to create the annotation is passed as a list-column. ```{r custompics} codes <- data.frame(country = c("nz","ca","ar","fr","gb","es")) codes$y <- runif(nrow(codes)) gl <- lapply(codes$country, function(.x) png::readPNG(system.file("flags", paste0(.x,".png"), package="egg"))) codes$raster <- I(gl) ggplot(codes, aes(x = country, y = y)) + geom_point() + geom_custom(data = codes, aes(data=raster), grob_fun = rasterGrob, fun_params = list(height=unit(1,"cm"))) + scale_y_continuous(breaks=NULL, "") + theme(panel.grid = element_blank()) ``` The list-column format allows passing grobs directly, in which case the `grob_fun` function should be identity, ```{r customgrobs} codes$raster <- I(lapply(codes$raster, function(x) rasterGrob(x, height=unit(1,"cm")))) ggplot(codes, aes(x = country, y = y)) + geom_point() + geom_custom(data = codes, aes(data=raster), grob_fun = identity) ``` Note that such grobs need to have `x` and `y` slots, which will be mapped to the appropriate location. It is therefore often necessary to create a wrapper with such fields, as illustrated below. Because the grobs are manually "mapped", independently of the main ggplot, this geom also allows the placing of arbitrary annotations without interference from transformed coordinate systems, etc. ```{r customgrobcoord} custom_grob <- function(data, x=0.5,y=0.5){ grob(data=data,x=x,y=y, cl="custom") } preDrawDetails.custom <- function(x){ pushViewport(viewport(x=x$x,y=x$y)) } postDrawDetails.custom <- function(x){ upViewport() } drawDetails.custom <- function(x, recording=FALSE, ...){ grid.rect(mean(x$data$x), mean(x$data$y), width=diff(range(x$data$x)), height=diff(range(x$data$y))) grid.lines(x$data$x, x$data$y, gp=gpar(col=x$data$col,lwd=2), default.units = "native") } d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3)) gl <- lapply(1:4, function(ii){ data.frame(x=seq(0.4,0.6,length=10), y = runif(10,0.45,0.55), col = hcl(h = seq(0,300,length=nrow(d)))[ii], stringsAsFactors = FALSE) }) subplots <- data.frame(f=letters[1:4], data = I(gl)) str(subplots) ggplot(d, aes(f,x)) + facet_wrap(~f, nrow=1)+ coord_polar() + geom_point()+ geom_custom(data = subplots, aes(data = data, x = f, y = 2), grob_fun = custom_grob) ``` egg/inst/flags/0000755000176200001440000000000013206376451013074 5ustar liggesusersegg/inst/flags/fr.png0000644000176200001440000000035213206360575014211 0ustar liggesusersPNG  IHDR\'PLTE)9ξMV#)9>~tRNSnIjvIDATx!êBB ٦ff?Revnvnvnvnvnvnvnvnvnv>RKJ]0JQIFIENDB`egg/inst/flags/ca.png0000644000176200001440000000363713206376410014171 0ustar liggesusersPNG  IHDR}oXPLTE  ""##$$&&''((**,,--..1122334455667788;;<<==>>??@@AACCDDEEFFGGHHIIJJLLOOQQRRSSTTVVWWYYZZ\\]]^^__``aaeeffhhiijjllmmnnooppssttuuvvwwyyzz{{}}~2ݳIDATx_SUǟ]SP,@1R+ #[8TeABeRjJ0K h6-we۝{7s?}Ϲ)Xy]Gut]Gut/0ZCnƉ~ `(Lj5p!'B1>?9Q {/D5~EŅ iĄ'`[|+r}4V囈V}q}xO߳he*geYL $Q]=+n+௾`)f&{esru|Fѝz[E?z7ELT`}-5lfgn3V;?K*~8orrSV!(G_ ܩhmkQFVҍ g[#Տ>8^Q~nl)puڞߍLcݫDo,s#RkVx*zFYQ,)"^G8F?+6WKWdD7#ܧ/z=n>{|yl!ɤɔ]Zi W3^}7٦(Ov3\ m*%( [Ķ .r}˺xaal~"j8P;/g3Ҕ]#KĖֵģWmQVV0 >M$cEDzK6S~^H(@4G| --bb>})@MKdkkqs\&lMĢw.6ڂNr_xo^`APA[D|~}4 i?N{ntPXgJgSM;[F&tȽC$=)L-* 5tfUbS53ř\A{*Aӈ<1T)ϖcaHKt}76M$rYP8nb}q !?k߱:g#N8>2zZ$/Q~,R3#E? Ѐ>){n:5_#E|`Dw"E%ROv"ET"E_)R'5vAn(B>>N8BϿh.D̥Ztt]Gut=ny Jk}íuIENDB`egg/inst/flags/gb.png0000644000176200001440000000202613206360576014173 0ustar liggesusersPNG  IHDR}oPLTE$}6R8T9U;WTlUmyzz|ٷڹۻ+,122N_O`aqbrfvgvhvvxy{扔爔牔犕줬줭>cIDATxIw@;a 6 {@<"xf4/t|Gu4Eez8awKՙ_nf3 ^O?L`Mk't>^IρEgu<):t&^Cχyx2xJklz)<%KI+ϤSMt<^O]-3CwMgp Ox4t(Gp.Gx1t*GpOx/]}t)p,> OQp /7Mzsp>$܃?ʥjۅ{Yt JU??'^ݝuKd>tAzЃ?NЃ=AzЃ=AzЃ=|:E)AzЃsD\3?z<3 dv_|>x԰ 灟_ >ҏ6);4K'sn&~xLxvyR<^?>L}]r<m(p/ #ڈ$x<AE31*,8eݒp<np|, φ3ڃ!x>+ଦp^;8s+@-4p.:i 5x{_+Mx*ÛU7 \-or_.4p04E64 nl p쀂7í=ߦRv\+3xNN9$(S4.37Td6,on0 $E[6=.:;VSRπ88h?T N3ZQFGlbi6JOZ<T[0.z /VuCɇFNa ywNl7² 9 ?6$h blzz҇8%UXւyI1\ Jy5}pcL+(0hHPJ{}>i:r!Bli ㍵_<K%9ڰgf>,K88(’Udl.M(A)N+`YfDgN;V2Q1f/Blv'"O-P)p!@~ƈÌ3N8]+tׇoPfky!qlpl(塯|"īF#On)T '89ϥ>lGoOwTm,@=zkISyT>ĎL2xZ4nh+S>+zF vAS'wFb#hJJÉ}:[)N1^mT8[y= c%C͋4bo$'L18] K_d]M c&6`!^-6`k8p_wR-&}@}"W.暵R1aWh1tEfI>~l;>IZJ^M(|R:A{˨lЪ]uDt'خm)]%.*Ma8z± (wGKRf' :9y?1 6Őc9jt}[>2Cg |>1Qi4ubEԆ0&VQn\ ځN=|>W}ٜqŞ{L f"Nn^jUnzCm#EdU0<\UH16=Æ6mp){ȌXMq6y֔Ph[Ԑ)` aW B li3V,P)MM,l!.J2jb >`|!5W+0Ux&W 'ls^ϏTf4S-тƎ 'VE>h`|nr RtOJ?$ C*@kr9Qdf;+<="#%)C5`I)f4Hߑ2mX]c G).ƀ@j`\_B] (ZR\TS{0ۆC'mM1Q(ՓPU9qQ6 Y™!gIwQI(@qHG\ĉ'=h9lz)&$i <!.&>T|s}X3ek PJQ9==W(\ߎ#lsSqЎ9GOqI6Q]0G@OvqI CBRh爌G)ΧlҮ7xd7o{#ӏ>74DarttH^=W4 =HB9,='V$Ja xB\Mu,]z39Ĥ)tuaS[Kaa}zg{f4 [-ZAq by};p~UXXr`u]Z9y%JqZ}0q)6:z\.)DQD)uM )}S>Ҝ&p '|U31 e216Bq~5ԏv]k@bqJ)RB)h*kݐr ~0UIؼNڋ,4:g\^o:•C<]Zk\ϥM8٥/A`daNqG 6\Hlfs1&V989i 42tPmC[)4E)0>C$IB!"FWEרO3d*WCFrs.c!/$c[zȕ zXUwqcEXo"M6#i=Jut@3ޑ+r!QĹRxdיiގž/w6~)X~M~-+=SN0c'B?'ˋZ!>dӪiEqrRQZ6>B\ j`)^U:L?cO/"m,|'qg 6M+(("\\$Ka) l۱,Sj`큘g2]7-yc,QyʵE2ms ~ >U{m@coU \6Fx.B\MLyce ZS9ZsVWX $#9Vch 6>yQ5MhC |/WogR,ˢhP}r/-WL稇M+q+E8- `RS68t踾 P `'s!jXuc6aۊkXJa}M! Qq\vAR AS _[TݏS!JE3w/ -VP3qn >1.9%"ul`N#"\r|DS*V8Kb:nkڕгk^`[q .B|~kߏ"Ixfuy$$Q]㔔ﺢMi8@92p5qX_Q;bӫ-z|e , 1P?aG?ƳxíL<۟k[,&M(8Ӓ[צH , {7.}1q́G#9t3AMZ Mnl2$749M)Ҫ iJSxȊ<|º-c;yI;KA>#Ս,eb$0Yws|w2Y: W,<n`p DQDY9~GŶ8ӆk#{^h&A 5R^t2?K JFd̊bpfir89zx;6c}O(~:+Mވr NߨܵOpʀm}O ݁dqE֜8k8*av._|o/$MSΔ$ z>. X9B ɘ^m"Zk^.6pS5* 38\0wi!W6)ü833~@yl0 <u{x Qq!i phu8,"]Py;B\M-Y?\cˋ(38 (NhJIc. GY&Fi XJ0ơ,kr=^JRqQ68 ߻~C8Ja7Kco0`ɏXvs#,a?S܎҃UL0}):-_O>n~ד.]aHR` a=(<PuCu]\BKɰă~;XGw)E:b8MۊJ >ZQ\ \M245E)ssگ_ye!Ih?rGS>V`]L"S_v` 4˂}GwS}t75itdAi͓L?4>{bfUM})Y>y6V-vQ'\ "BH6i *L ;+"twcgr?Tkoz9x>̮{;ܱ?&_0q!6#.|{Z`6m$:*WocI\Fq._S?7VoOscdY#9f$ A`Gqµ-ڏģɄ ^Ұt['7|GS fN~qγtmc1SGlrmobS^(|W¶ammo>ɛjt&mrJq Ym;Q':r)m[Imtg^øŅC︋y?Sj33Y!&cWGJ75|gK.g7ښ %Er(e&J龱Ŷ[">щӓ` Q*䷆JJx!wEH9R X\y֭ټ+_O$OY ąh2gUL=@@7A dL__'$.\Z-`WtѠ=UQafΒw].cx ;_G dЪ+#j )K)Υ8 (@ip vJu5!EԫW\G-MHަҝYJp Jbl2(Ƅՙ;sXB?Jk(,4OY'm,ـڸ5AKш4 8N PM)t>%%:/)LԾT$w}E wѥ{y) !^}6j0pJ""Rr|bs9ibLL%`94&QX V!!iS0JE^.RZ&ZkNiZ$I>B\ .33oQӌ,֠ י}CajC{H{ҭMZOPŔ)y_u',o1u ^YDKdT Ϗ% tef882YV Y8U' _ߢx{IC,XX=10)"Qy[ ,)^{tlF- tf:C3a1c$qI6up K&SS%+iT ts9 gKͷ]7^EVw2'9wz ׷b>W&|ڧi nSq0j`bu#Ei2(8T (HSMjڱK;,kc(^zKf1z3s]y]_'mh W8C״zI"h|@R4Z›r35$IIS"I5Ԛ6qe1I ]G[Y]S:tW]zxοu8\HJ2υ(;,+`G|+GV PB""`Sua^,mxQ o`"M}'][)};[D1|lM 4# yr^kו܌EhzB6Yz:'?Տz$Ǝ+F >c4ŒT1A@?}{b0O3Qr~ʙR7 y|x7ݥks=kzq16Ycيz͍kK8&ی-4ЧvHb4mN΄UJN.d*.3TǨ ) AJֿk ݳXﺕ}͕<09Lym ;zC bQަcu7>#\eЅ!kLUEu^;ppMBH-bl2h8XSM %2>3&F\N [We{ŶžM/n&cb6mȗQډ1{rJ<%l $byYVUR.1>Q9<;G9 vvaTwNbى!c2PEe {'̵-h68R\z۝4!j I?a'%0P4&ku=B٫Rsْg}9pQx+NR[ yevb?c !NA)a#~`J ď$"4B!2O#<"4B!2O#< 4"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<,BL-KIENDB`egg/inst/flags/nz.png0000644000176200001440000000573713206360572014242 0ustar liggesusersPNG  IHDR}Y~] IDATxytSUqYϜ9PёQhRq@A6F\,#ʨ32"E@]vRvYYZ@kWRJ)4i$]~{9-@9ߓIi-i07r7gSp[4UnAiۚ4Dnvb|ݓ}Z}^Xo]A. yw KߦcYk0W}['l`zG- z'- =z\קoI5z,ЫmvmW'C}R]fY.B/UjGN'ȵ|{"o^]/ f^ i2UΔ xwB'pZt ]] !twtWu @zwCzLn'nEEE<'twtW{cQ~1- ]>W<0FXbo <.+zqz0F]  0h@itH._q~ebx)/~:k8|*2Ld "|^w @9^\ONya5"&uqb噳2x]|Qm <ǐZ ytόUaM`Kc7r^wF誷x,[/wc}:k>"cA+}WpU'Kt9U}Gi76;kj:PUU{=1}Jڕˁ([;|j#[f/;y=7tĔb`u-rVY-76CƝr=f#&@0\ςJ5-- ]f [w4"Ҧy*K0]?75>p!?Z/K=0嬱e/yk\YK4{^>HÝ~ ԇN:"L)W ݳLswSa qO"g}]q鰘-yߺkL7xZUUۧ3o}lצn%'"2>-U{]K] oY| [zN_V##V <^o9U_Y] ƋOEPQnǟ-Pz>צXVOɯGL_(:7/6hBT[?:u[np9 Ő{ 3#]TZ^ԁp@'k)nA~1O$6:VX˓B8Kjbex{Q,".E{iL 8}*tO?j.dd4zRM?C/TWV58s?=i}Ƭ*fuםCh SX>xE#0D㋨6׷iy`z8?wiÒ*X|^k ]>hVM@mAW֡{*ɳb*5y/ {v.Vn ۍ~/~qL?F]U\\Q7ZR }7utW ;־RTYb҈X ? dpŇަ> U:tWwǓwHOD㋂!*`Flވc0ڴAW ^;vZs(O/-O^\;'n%JWBWޠ;(6ZRޯ#c6 '{v$+ \Нշ=.)YFtMf"0]B& ˧ىu- ޵obǁ_sS2ia:&ÿF{/cЩ4⃥|۵ۃϾ񳸜T1F1Bg:cc31F1Bg:cc#t1F1Bg:cc#t3F1Bg:c@OΘ{'(3p7>H? 2N#t|@\DLM"q\y=3PwŪgcD.~nʕx~ǘ>5 BZN&SwTUY3🀷:pdxmY`MZ ҄v5^^3[zz\K茩ڒ g1o)Eݸig#on?:cN0!޶_;S|Ā;!`,/-!tT NVEn5I3j.]E茩֖Wj:\8gV 1}'tׄ6{WT?5a#t31F1Bg:c#t31F1Bg:cc CfM;-o՟IENDB`egg/inst/flags/ar.png0000644000176200001440000001040713206360574014205 0ustar liggesusersPNG  IHDR#!-IDATxyTVlދ}նz۾VoWj7zE[oUjպ kXdAd_gd$ PjW=yfB9'O~3&ˏmtٚea tf%殴)-~FFob8(:<)f$7bj+#}-+n3ֽ=JxH{S t;$0}J1ok.yu2ёUTg"'}'׭P9a'rYZ}Q*a( ݧh%]\Ne&6m2wkoS>JƮs:LxìbWHzڬ\}{# ݧP,d*WrD*|M;rsN@pf~M^Nn&>ҤQ~/lgRֻ?*M *+C)f({ѡz eneC]4u%rs٤X4W'jgnmJlLm,>mos5GDs& ,v*_v~YwY 1M>!y]_jIaÀC@W\D_B"=McW"ޔ ZdeҰŝMqՙ_.~ 4Ez0d7ZMs>(ȸWv;Gc Nm`c3~Vyi o 'n^;B</?6VDѼ?IG͵iGZ`&L>6:~C>YU";ǮQg56E)ӷQ!5!RK/U\թV(d8YZYFh?>&c51bdfǥ+qZ klMڬMɏʣE*鰙L1vUtGߜ˫pߢ=3|5QrhqnӘugdh(4ei*>11gA_ʿ8t3 _77xȊZ;Cj"'[+)Xz0򉶋D_ ~ѽ( ק,s)oy}q].~jR:l\ (e[>{P.ZN/\a(8@{&tӘw\:o &7TU$O|;'ߺ2'kN%?ʌmtcqJk.:0}re3S9]&à0ky-BRVrn\quE{[=4'q~-DAtOl'dY!NxUףz!srUeqWΧfic1/Se~c_[jO/Vjvן!}rn\JT v{9qĵ2?/.%d{oY&zE{ĮeR!dM#2THˇ{錯)[%qg_+[bK$*zc Kc6tG1܈$n6J Q U$=SoWʖ4F>V8P^:3e*:a YZq'vÍ }rv[Gn :.kàW$K^sDe.-DӒ1'+(ET,D'TЪ :GotܰrU?)k5ik/JCJN'U^~2F}"\Ca ը?%.i8N?p:, 'g q;wOo8!-&s\nJjni%uۛ*@{ቶ@+3by lMy*,ޗ>]gT0tIߕ! WP c$ZY;g(p4rӨe˜ͥ~^{{&,ҩ$3iڋf$Cr >)a̡MY.z_}I}FD3gQ) 'o ,.2]Ayɿ{.⃼]^ vy~;ʗ?=Q6S3 eQۆI%Gu%pxhoG[ц<˳?3hF)X*m{Y#/|E{ԼK-=tɧԅQ}/;8ӊm8s"ƫG [lLo׋w!$k4^?\|Y"lJUggۚK{ӘܰSe/=_{v8%I u'gٕ TToYkJtpF>|<<؃цWQ}g* bۍ%a \>$97YV! zZ(uYۚ@qKM^pjq [Wp1i.}g"S>ƘCI [cNb^X[eu_%/n"y"3vbQW7Y“ ~WMK;٧Jٮm2naS#N3E-7$Vu|u8ɊT<T.?G4QIk-FYVRȋ:]#̯70U%WS@ͨ}EYԧIY724Hoէa6R)z6`wCLZeSͥ51qoq0>bͶʊEcΔqr|E[lIccќy-wRodR6b?UIg8 ݧzlZ2^Fkr_J^gxVM]Eg'uS%_Ҿ뒘5菜V3Ou;ϳ:)Q+}N۶Er;&s߭wT%3פn#^uo~ aʸy&rW^:Yo( n~ s˸Ztc3>iu,uˢǸA;QĢ:\}ӶnኾA;@wrAZ_?@w;t@w;@w;t@w;@w;t@w;@w;t@w;@w@w;GaE[IENDB`egg/NAMESPACE0000644000176200001440000000320713512255104012233 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(print,egg) export(.dummy_ggplot) export(.dummy_gtable) export(expose_layout) export(geom_custom) export(ggarrange) export(gtable_frame) export(set_panel_size) export(symmetric_range) export(tag_facet) export(tag_facet_outside) export(theme_article) export(theme_presentation) importFrom(ggplot2,aes_string) importFrom(ggplot2,element_blank) importFrom(ggplot2,element_line) importFrom(ggplot2,element_rect) importFrom(ggplot2,element_text) importFrom(ggplot2,geom_text) importFrom(ggplot2,ggplot) importFrom(ggplot2,ggplotGrob) importFrom(ggplot2,ggplot_build) importFrom(ggplot2,ggplot_gtable) importFrom(ggplot2,ggproto) importFrom(ggplot2,ggproto_parent) importFrom(ggplot2,ggsave) importFrom(ggplot2,layer) importFrom(ggplot2,scale_x_continuous) importFrom(ggplot2,theme) importFrom(ggplot2,theme_bw) importFrom(ggplot2,theme_void) importFrom(grDevices,dev.interactive) importFrom(grDevices,dev.new) importFrom(grDevices,n2mfrow) importFrom(grid,convertHeight) importFrom(grid,convertWidth) importFrom(grid,editGrob) importFrom(grid,gpar) importFrom(grid,grid.draw) importFrom(grid,grid.newpage) importFrom(grid,grobHeight) importFrom(grid,grobName) importFrom(grid,grobTree) importFrom(grid,grobWidth) importFrom(grid,is.grob) importFrom(grid,is.unit) importFrom(grid,nullGrob) importFrom(grid,rectGrob) importFrom(grid,textGrob) importFrom(grid,unit) importFrom(grid,unit.c) importFrom(gridExtra,gtable_cbind) importFrom(gridExtra,gtable_rbind) importFrom(gtable,gtable_add_cols) importFrom(gtable,gtable_add_grob) importFrom(gtable,gtable_add_rows) importFrom(gtable,gtable_matrix) importFrom(utils,as.roman) egg/R/0000755000176200001440000000000013512266054011221 5ustar liggesusersegg/R/expose_layout.r0000644000176200001440000000316713367157565014331 0ustar liggesusers#' expose_layout #' #' @description Schematic view of a ggplot object's layout. #' @param p ggplot #' @param draw logical, draw the gtable #' @param newpage logical #' #' @return gtable #' @export #' #' @examples #' p1 <- qplot(mpg, wt, data=mtcars, colour=cyl) #' p2 <- qplot(mpg, data = mtcars) + ggtitle('title') #' p3 <- qplot(mpg, data = mtcars, geom = 'dotplot') #' p4 <- p1 + facet_wrap(~carb, nrow=1) + theme(legend.position='none') + #' ggtitle('facetted plot') #' pl <- lapply(list(p1,p2, p3, p4), expose_layout, FALSE, FALSE) #' grid.arrange(grobs=pl, widths=c(1.2,1,1), #' layout_matrix = rbind(c(1, 2, 3), #' c(4, 4, 4))) expose_layout <- function(p, draw = TRUE, newpage = TRUE) { g <- ggplotGrob(p) lay <- g[["layout"]] gt <- g ids <- c("background", "panel", "axis", "lab", "guide", "strip", "title") replace_grob <- function(idname, col) { id <- grepl(idname, lay$name) pos <- lay[id, ] newgrob <- rectGrob(gp = gpar(col = "white", lwd = 1.2, fill = col)) gt$grobs[id] <- replicate(nrow(pos), newgrob, simplify = FALSE) } cols <- c("grey95", "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC") for (ii in seq_along(ids)) { id <- grepl(ids[ii], lay$name) pos <- lay[id, ] newgrob <- rectGrob(gp = gpar(col = "white", lwd = 1.2, fill = cols[ii])) gt$grobs[id] <- replicate(nrow(pos), newgrob, simplify = FALSE) } if (draw) { if (newpage) grid.newpage() grid.draw(gt) } gt } egg/R/geom_custom.r0000644000176200001440000000364113367157565013747 0ustar liggesusers #' geom_custom #' #' @description Draw user-defined grobs, typically annotations, at specific locations. #' @param mapping mapping #' @param data data #' @param inherit.aes inherit.aes #' @param ... arguments passed to the geom's draw_group method #' @importFrom gtable gtable_matrix gtable_add_grob gtable_add_cols gtable_add_rows #' @importFrom grid nullGrob unit grobTree editGrob grobName #' @importFrom ggplot2 ggproto ggproto_parent layer #' @return layer #' @export #' @examples #' library(grid) #' d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3)) #' gl <- replicate(4, matrix(sample(palette(), 9, TRUE), 3, 3), FALSE) #' dummy <- data.frame(f=letters[1:4], data = I(gl)) #' ggplot(d, aes(f,x)) + #' facet_wrap(~f)+ #' theme_bw() + #' geom_point()+ #' geom_custom(data = dummy, aes(data = data, y = 2), #' grob_fun = function(x) rasterGrob(x, interpolate = FALSE, #' width=unit(1,'cm'), #' height=unit(1,'cm'))) geom_custom <- function(mapping = NULL, data = NULL, inherit.aes = TRUE, ...) { layer(geom = GeomCustom, mapping = mapping, data = data, stat = "identity", position = "identity", show.legend = FALSE, inherit.aes = inherit.aes, params = list(...)) } GeomCustom <- ggproto("GeomCustom", Geom, handle_na = function(self, data, params) { data }, setup_data = function(self, data, params) { data <- ggproto_parent(Geom, self)$setup_data(data, params) data }, draw_group = function(data, panel_scales, coord, grob_fun, fun_params = list()) { coords <- coord$transform(data, panel_scales) gl <- lapply(seq_along(data$data), function(i) { .g <- do.call(grob_fun, c(list(data$data[[i]]), fun_params)) grid::editGrob(.g, x = unit(coords$x[i], "native"), y = unit(coords$y[i], "native")) }) do.call(grobTree, gl) }, required_aes = c("data", "x", "y")) egg/R/set_panel_size.r0000644000176200001440000000255113367157565014431 0ustar liggesusers #' set_panel_size #' #' @description Set the panel width/height of a ggplot to a fixed value. #' @param p ggplot2 #' @param g gtable #' @param file optional output filename #' @param margin grid unit #' @param width grid unit, requested panel width #' @param height grid unit, requested panel height #' #' @importFrom grid unit convertWidth convertHeight grobWidth grobHeight textGrob gpar #' @importFrom ggplot2 ggplotGrob ggsave #' @return gtable with fixed panel sizes #' @export #' @examples #' p1 <- qplot(mpg, wt, data=mtcars, colour=cyl) #' p2 <- p1 + facet_wrap(~carb, nrow=1) #' grid.arrange(grobs=lapply(list(p1,p2), set_panel_size)) set_panel_size <- function(p = NULL, g = ggplot2::ggplotGrob(p), file = NULL, margin = unit(1, "mm"), width = unit(4, "cm"), height = unit(4, "cm")) { panels <- grep("panel", g$layout$name) panel_index_w <- unique(g$layout$l[panels]) panel_index_h <- unique(g$layout$t[panels]) nw <- length(panel_index_w) nh <- length(panel_index_h) g$widths[panel_index_w] <- rep(width, nw) g$heights[panel_index_h] <- rep(height, nh) if (!is.null(file)) { ggplot2::ggsave(file, g, width = grid::convertWidth(sum(g$widths) + margin, unitTo = "in", valueOnly = TRUE), height = grid::convertHeight(sum(g$heights) + margin, unitTo = "in", valueOnly = TRUE)) } g } egg/R/gtable_frame.r0000644000176200001440000003067213427400577014031 0ustar liggesusers #' gtable_frame #' #' @description Reformat the gtable associated with a ggplot object into a 3x3 gtable where the central cell corresponds to the plot panel(s). #' @param g gtable #' @param width requested width #' @param height requested height #' @param debug logical draw gtable cells #' #' @importFrom gtable gtable_matrix gtable_add_grob gtable_add_cols gtable_add_rows #' @importFrom grid unit unit.c nullGrob rectGrob grid.newpage grid.draw #' @importFrom gridExtra gtable_rbind gtable_cbind #' @return 3x3 gtable wrapping the plot #' @export #' @examples #' library(grid) #' library(gridExtra) #' p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + #' geom_point() #' #' p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + #' geom_point() + facet_wrap( ~ cyl, ncol=2, scales = 'free') + #' guides(colour='none') + #' theme() #' #' p3 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + #' geom_point() + facet_grid(. ~ cyl, scales = 'free') #' #' g1 <- ggplotGrob(p1); #' g2 <- ggplotGrob(p2); #' g3 <- ggplotGrob(p3); #' fg1 <- gtable_frame(g1) #' fg2 <- gtable_frame(g2) #' fg12 <- gtable_frame(gtable_rbind(fg1,fg2), width=unit(2,'null'), height=unit(1,'null')) #' fg3 <- gtable_frame(g3, width=unit(1,'null'), height=unit(1,'null')) #' grid.newpage() #' combined <- gtable_cbind(fg12, fg3) #' grid.draw(combined) gtable_frame <- function(g, width = unit(1, "null"), height = unit(1, "null"), debug = FALSE) { panels <- g[["layout"]][grepl("panel", g[["layout"]][["name"]]), ] pargins <- g[["layout"]][grepl("panel", g[["layout"]][["name"]]), ] ll <- unique(panels$l) margins <- if (length(ll) == 1) unit(0, "pt") else g$widths[ll[-length(ll)] + 2] tt <- unique(panels$t) fixed_ar <- g$respect if (fixed_ar) { # there lies madness, we want to align with aspect ratio constraints ar <- as.numeric(g$heights[tt[1]])/as.numeric(g$widths[ll[1]]) # a*(b-c) != ab - ac in grid... height <- width * (ar/length(ll)) # - sum(margins)* (ar / length(ll)) g$respect <- FALSE } core <- g[seq(min(tt), max(tt)), seq(min(ll), max(ll))] top <- g[seq(1, min(tt) - 1), seq(min(ll), max(ll))] bottom <- g[seq(max(tt) + 1, nrow(g)), seq(min(ll), max(ll))] left <- g[seq(min(tt), max(tt)), seq(1, min(ll) - 1)] right <- g[seq(min(tt), max(tt)), seq(max(ll) + 1, ncol(g))] fg <- nullGrob() if (length(left)) { # add a dummy grob to make sure things stick to the panel lg <- gtable::gtable_add_cols(left, unit(1, "null"), 0) lg <- gtable::gtable_add_grob(lg, fg, 1, l = 1) } else { lg <- fg } if (length(right)) { # add a dummy grob to make sure things stick to the panel rg <- gtable::gtable_add_cols(right, unit(1, "null")) rg <- gtable::gtable_add_grob(rg, fg, 1, l = ncol(rg)) } else { rg <- fg } if (length(top)) { # add a dummy grob to make sure things stick to the panel tg <- gtable::gtable_add_rows(top, unit(1, "null"), 0) tg <- gtable::gtable_add_grob(tg, fg, t = 1, l = 1) } else { tg <- fg } if (length(bottom)) { # add a dummy grob to make sure things stick to the panel bg <- gtable::gtable_add_rows(bottom, unit(1, "null"), -1) bg <- gtable::gtable_add_grob(bg, fg, t = nrow(bg), l = 1) } else { bg <- fg } ## 3x3 cells (corners contain nullGrob) grobs <- list(fg, tg, fg, lg, core, rg, fg, bg, fg) widths <- unit.c(sum(left$widths), width, sum(right$widths)) heights <- unit.c(sum(top$heights), height, sum(bottom$heights)) all <- gtable::gtable_matrix("all", grobs = matrix(grobs, ncol = 3, nrow = 3, byrow = TRUE), widths = widths, heights = heights) if (debug) { hints <- grid::rectGrob(gp = gpar(fill = NA, lty = 2, lwd = 0.2)) tl <- expand.grid(t = 1:3, l = 1:3) all <- gtable::gtable_add_grob(all, replicate(9, hints, simplify = FALSE), t = tl$t, l = tl$l, z = Inf, name = "debug") } all[["layout"]][5, "name"] <- "panel" # make sure knows where the panel is if (fixed_ar) all$respect <- TRUE all } .tmp <- gtable::gtable_matrix("placeholder", matrix(replicate(9, grid::nullGrob(), simplify = FALSE), 3, 3), widths = rep(unit(1, "null"), 3), heights = rep(unit(1, "null"), 3)) .tmp$layout$name[5] <- "panel" #' @export .dummy_gtable <- .tmp #' @importFrom ggplot2 ggplot theme_void #' @export .dummy_ggplot <- ggplot() + theme_void() # stolen from grid (because unexported) as.unit.list <- function(unit) { if (inherits(unit, "unit.list")) { unit } else { l <- length(unit) result <- vector("list", l) for (i in seq_len(l)) result[[i]] <- unit[i] class(result) <- c("unit.list", "unit") result } } label_grid <- function(labels, x = 0, hjust = 0, y = 1, vjust = 1, ..., .fun = grid::textGrob) { lapply(labels, .fun, x = x, hjust = hjust, y = y, vjust = vjust, ...) } #' ggarrange #' #' @description Arrange multiple ggplot objects on a page, aligning the plot panels. #' @param ... ggplot objects #' @param plots list of ggplots #' @param nrow number of rows #' @param ncol number of columns #' @param heights list of requested heights #' @param widths list of requested widths #' @param byrow logical, fill by rows #' @param top optional string, or grob #' @param bottom optional string, or grob #' @param left optional string, or grob #' @param right optional string, or grob #' @param padding unit of length one, margin around annotations #' @param clip argument of gtable #' @param newpage logical: draw on a new page #' @param draw logical: draw or return a grob #' @param debug logical, show layout with thin lines #' @param labels character labels used for annotation of subfigures #' @param label.args label list of parameters for the formatting of labels #' @importFrom grid is.unit is.grob #' @importFrom grDevices n2mfrow #' @importFrom gridExtra gtable_cbind gtable_rbind #' @return gtable of aligned plots #' @export #' @examples #' p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + #' geom_point() #' p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + #' geom_point() + facet_wrap( ~ cyl, ncol=2, scales = 'free') + #' guides(colour='none') + #' theme() #' ggarrange(p1, p2, widths = c(2,1), labels = c('a', 'b')) ggarrange <- function(..., plots = list(...), nrow = NULL, ncol = NULL, widths = NULL, heights = NULL, byrow = TRUE, top = NULL, bottom = NULL, left = NULL, right = NULL, padding = unit(0.5, "line"), clip = "on", draw = TRUE, newpage = TRUE, debug = FALSE, labels = NULL, label.args = list(gp = grid::gpar(font = 4, cex = 1.2))) { n <- length(plots) grobs <- lapply(plots, ggplot2::ggplotGrob) ## logic for the layout if nrow/ncol supplied, honour this if not, use length of ## widths/heights, if supplied if nothing supplied, work out sensible defaults ## nothing to be done but check inconsistency if (!is.null(ncol) && !is.null(widths)) { stopifnot(length(widths) == ncol) } if (!is.null(nrow) && !is.null(heights)) { stopifnot(length(heights) == nrow) } ## use widths/heights if supplied if (is.null(ncol) && !is.null(widths)) { ncol <- length(widths) } if (is.null(nrow) && !is.null(heights)) { nrow <- length(heights) } ## work out the missing one if (is.null(nrow) && !is.null(ncol)) { nrow <- ceiling(n/ncol) } if (is.null(ncol) && !is.null(nrow)) { ncol <- ceiling(n/nrow) } ## it may happen that sufficient info was passed, but incompatible with number of grobs ## (fewer cells) stopifnot(nrow * ncol >= n) ## last case: nothing exists if (is.null(nrow) && is.null(ncol) && is.null(widths) && is.null(heights)) { nm <- grDevices::n2mfrow(n) nrow <- nm[1] ncol <- nm[2] } is_full <- ((nrow*ncol) %% n) > 0 if (is_full) { message('adding dummy grobs') # trouble, we need to add dummy grobs to fill the layout grobs <- c(grobs, rep(list(.dummy_gtable), nrow * ncol - n)) n <- length(grobs) # add dummy labels if needed if ((!is.null(labels)) && (length(labels) != nrow * ncol)) { labels <- c(labels, rep("", nrow * ncol - length(labels))) } } ## case numeric if (is.numeric(widths) && !inherits(widths, "unit")) { widths <- lapply(widths, unit, "null") } if (is.numeric(heights) && !inherits(heights, "unit")) { heights <- lapply(heights, unit, "null") } ## sizes if (is.null(widths)) widths <- lapply(rep(1, n), unit, "null") if (is.null(heights)) heights <- lapply(rep(1, n), unit, "null") # user may naively have passed grid units, but only unit.list units work well with `[` # so convert to this class if (grid::is.unit(widths)) widths <- as.unit.list(widths) if (grid::is.unit(heights)) widths <- as.unit.list(heights) # indexing is problematic, wrap in list if (grid::is.unit(widths) && length(widths) == 1) { widths <- list(widths) } if (grid::is.unit(heights) && length(heights) == 1) { heights <- list(heights) } ## split the list into rows/cols nrc <- if (byrow) nrow else ncol if (nrc == 1) { splits <- rep(1, n) } else { seqgrobs <- seq_along(grobs) splits <- cut(seqgrobs, nrc, labels = seq_len(nrc)) ## widths and heights refer to the layout repeat for corresponding grobs repw <- rep_len(seq_along(widths), length.out=n) reph <- rep_len(seq_along(heights), length.out=n) widths <- c(matrix(widths[repw], ncol = nrc, byrow = !byrow)) heights <- c(matrix(heights[reph], ncol = nrc, byrow = byrow)) } fg <- mapply(gtable_frame, g = grobs, width = widths, height = heights, MoreArgs = list(debug = debug), SIMPLIFY = FALSE) if (!is.null(labels)) { stopifnot(length(labels) == length(fg)) # make grobs labels <- do.call(label_grid, c(list(labels), label.args)) # add each grob to the whole gtable fg <- mapply(function(g, l) { gtable::gtable_add_grob(g, l, t = 1, l = 1, b = nrow(g), r = ncol(g), z = Inf, clip = "off", name = "label") }, g = fg, l = labels, SIMPLIFY = FALSE) } spl <- split(fg, splits) if (byrow) { rows <- lapply(spl, function(.r) do.call(gridExtra::gtable_cbind, .r)) gt <- do.call(gridExtra::gtable_rbind, rows) } else { # fill colwise cols <- lapply(spl, function(.c) do.call(gridExtra::gtable_rbind, .c)) gt <- do.call(gridExtra::gtable_cbind, cols) } ## titles given as strings are converted to text grobs if (is.character(top)) { top <- textGrob(top) } if (is.grob(top)) { h <- grobHeight(top) + padding gt <- gtable_add_rows(gt, heights = h, 0) gt <- gtable_add_grob(gt, top, t = 1, l = 1, r = ncol(gt), z = Inf, clip = clip) } if (is.character(bottom)) { bottom <- textGrob(bottom) } if (is.grob(bottom)) { h <- grobHeight(bottom) + padding gt <- gtable_add_rows(gt, heights = h, -1) gt <- gtable_add_grob(gt, bottom, t = nrow(gt), l = 1, r = ncol(gt), z = Inf, clip = clip) } if (is.character(left)) { left <- textGrob(left, rot = 90) } if (is.grob(left)) { w <- grobWidth(left) + padding gt <- gtable_add_cols(gt, widths = w, 0) gt <- gtable_add_grob(gt, left, t = 1, b = nrow(gt), l = 1, r = 1, z = Inf, clip = clip) } if (is.character(right)) { right <- textGrob(right, rot = -90) } if (is.grob(right)) { w <- grobWidth(right) + padding gt <- gtable_add_cols(gt, widths = w, -1) gt <- gtable_add_grob(gt, right, t = 1, b = nrow(gt), l = ncol(gt), r = ncol(gt), z = Inf, clip = clip) } if (draw) { if (newpage) grid.newpage() grid.draw(gt) } class(gt) <- c("egg", class(gt)) invisible(gt) # return the full gtable } ##' @noRd ##' @importFrom grDevices dev.interactive dev.new ##' @export print.egg <- function(x, ...) { grid.newpage() grid.draw(x) } egg/R/theme.r0000644000176200001440000000454113510016536012506 0ustar liggesusers #' Theme with minimalistic (and opinionated) defaults suitable for publication #' #' @inheritParams ggplot2::theme_bw #' @importFrom ggplot2 theme_bw element_line element_rect element_text #' @importFrom grid unit #' @export #' @examples #' library(ggplot2) #' #' d = data.frame( #' x = 1:90, #' y = rnorm(90), #' red = rep(letters[1:3], 30), #' blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) #' #' p <- ggplot(d) + #' geom_point(aes(x = x, y = y)) + #' facet_grid(red ~ blue) #' tag_facet(p + theme_article()) #' p + theme_presentation() #' #' # example of use with cairo device #' # ggsave("fig_talk.pdf", p + theme_presentation("Source Sans Pro"), #' # width=14, height=7, device = cairo_pdf, bg='transparent') theme_article <- function(base_size = 11, base_family = "") { gray <- "#464646" fg <- "#000000" theme_bw(base_size = base_size, base_family = base_family) + theme(line = element_line(colour = gray), rect = element_rect(fill = NA, colour = NA), text = element_text(colour = fg), axis.ticks = element_line(colour = gray), legend.key = element_rect(colour = NA, fill = NA), legend.key.height = unit(3,"mm"), panel.border = element_rect(colour = gray, fill = NA), panel.grid = element_blank(), plot.background = element_blank(), panel.background=element_blank(), strip.background = element_blank()) } #' Theme with minimalistic (and opinionated) defaults suitable for presentation #' #' @inheritParams ggplot2::theme_bw #' @importFrom ggplot2 theme_bw element_line element_rect element_text #' @importFrom grid unit #' @describeIn theme #' @export theme_presentation <- function(base_size = 24, base_family = "") { gray <- "#464646" bg = 'grey98' fg <- "#000000" theme_bw(base_size = base_size, base_family = base_family) + theme(line = element_line(colour = gray), rect = element_rect(fill = NA, colour = NA), text = element_text(colour = fg), axis.ticks = element_line(colour = gray), legend.key = element_rect(colour = NA, fill = bg), legend.key.height = unit(3,"mm"), panel.border = element_rect(colour = gray, fill = NA), panel.grid = element_blank(), panel.background=element_rect(fill=bg), strip.background = element_blank()) } egg/R/tag_facet.r0000644000176200001440000001115213512254273013321 0ustar liggesusers #' tag_facet #' #' @description Adds a dummy text layer to a ggplot to label facets and sets facet strips to blank. #' This is the typical formatting for some journals that consider facets as subfigures #' and want to minimise margins around figures. #' @param p ggplot #' @param open opening character, default: ( #' @param close closing character, default: ) #' @param tag_pool character vector to pick tags from #' @param x x position within panel, default: -Inf #' @param y y position within panel, default: Inf #' @param hjust hjust #' @param vjust vjust #' @param fontface fontface #' @param family font family #' @param ... further arguments passed to geom_text layer #' #' @return plot with facet strips removed and replaced by in-panel tags #' @importFrom ggplot2 geom_text ggplot_build theme element_blank aes_string #' @export #' @examples #' library(ggplot2) #' mydf = data.frame( #' x = 1:90, #' y = rnorm(90), #' red = rep(letters[1:3], 30), #' blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) #' #' p <- ggplot(mydf) + #' geom_point(aes(x = x, y = y)) + #' facet_wrap( #' ~ red + blue) #' tag_facet(p) tag_facet <- function(p, open = "(", close = ")", tag_pool = letters, x = -Inf, y = Inf, hjust = -0.5, vjust = 1.5, fontface = 2, family = "", ...) { gb <- ggplot_build(p) lay <- gb$layout$layout tags <- cbind(lay, label = paste0(open, tag_pool[lay$PANEL], close), x = x, y = y) p + geom_text(data = tags, aes_string(x = "x", y = "y", label = "label"), ..., hjust = hjust, vjust = vjust, fontface = fontface, family = family, inherit.aes = FALSE) + theme(strip.text = element_blank(), strip.background = element_blank()) } #' tag_facet_outside #' #' @description Adds a dummy text layer to a ggplot to label facets and sets facet strips to blank. #' This is the typical formatting for some journals that consider facets as subfigures #' and want to minimise margins around figures. #' @param p ggplot #' @param open opening character, default: ( #' @param close closing character, default: ) #' @param tag_fun_top labelling function #' @param tag_fun_right labelling function #' @param x x position within cell #' @param y y position within cell #' @param hjust hjust #' @param vjust vjust #' @param fontface fontface #' @param family font family #' @param draw logical: draw the resulting gtable #' @param ... further arguments passed to geom_text layer #' @return plot with facet strips removed and replaced by in-panel tags #' @importFrom ggplot2 ggplot_gtable geom_text ggplot_build theme element_blank #' @importFrom utils as.roman #' @export #' @examples #' library(ggplot2) #' d = data.frame( #' x = 1:90, #' y = rnorm(90), #' red = rep(letters[1:3], 30), #' blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) #' #' p <- ggplot(d) + #' geom_point(aes(x = x, y = y)) + #' facet_grid(red ~ blue) #' #' tag_facet_outside(p) #' tag_facet_outside <- function(p, open=c("(",""), close = c(")","."), tag_fun_top = function(i) letters[i], tag_fun_right = utils::as.roman, x = c(0,0), y = c(0.5, 1), hjust = c(0,0), vjust = c(0.5,1), fontface = c(2,2), family="", draw = TRUE, ...){ gb <- ggplot_build(p + theme(strip.text = element_blank(), strip.background = element_blank())) lay <- gb$layout$layout tags_top <- paste0(open[1],tag_fun_top(unique(lay$COL)),close[1]) tags_right <- paste0(open[2],tag_fun_right(unique(lay$ROW)),close[2]) tl <- lapply(tags_top, grid::textGrob, x=x[1], y=y[1], hjust=hjust[1], vjust=vjust[1], gp=grid::gpar(fontface=fontface[1], fontfamily = family, ...)) rl <- lapply(tags_right, grid::textGrob, x=x[2], y=y[2], hjust=hjust[2], vjust=vjust[2], gp=grid::gpar(fontface=fontface[2], fontfamily = family, ...)) g <- ggplot_gtable(gb) g <- gtable::gtable_add_rows(g, grid::unit(1,"line"), pos = 0) l <- unique(g$layout[grepl("panel",g$layout$name), "l"]) g <- gtable::gtable_add_grob(g, grobs = tl, t=1, l=l) wm <- do.call(grid::unit.pmax, lapply(rl, grid::grobWidth)) g <- gtable::gtable_add_cols(g, wm, pos = max(l)) t <- unique(g$layout[grepl("panel",g$layout$name), "t"]) g <- gtable::gtable_add_grob(g, grobs = rl, t=t, l=max(l) + 1) g <- gtable::gtable_add_cols(g, unit(2,"mm"), pos = max(l)) if(draw){ grid::grid.newpage() grid::grid.draw(g) } invisible(g) } egg/R/symmetric_scale.r0000644000176200001440000000115413512260404014561 0ustar liggesusers#' symmetric_range #' #' @description Function to ensure that a position scale is symmetric about 0 #' @param range range of the data #' #' @return symmetric range #' @importFrom ggplot2 scale_x_continuous #' @export #' @examples #' library(ggplot2) #' df = data.frame(x = c(1, 2), #' y = c(5, 0.2), #' group = c(1, 2)) #' p <- ggplot(df, aes(x = x, y = y)) + #' geom_point() + #' facet_wrap( ~ group, scale = #' "free") #' p + scale_y_continuous(limits = symmetric_range) symmetric_range <- function(range) { max_abs <- max(abs(range)) c(-max_abs, max_abs) } egg/vignettes/0000755000176200001440000000000013512266054013030 5ustar liggesusersegg/vignettes/fr.png0000644000176200001440000000035213206357004014141 0ustar liggesusersPNG  IHDR\'PLTE)9ξMV#)9>~tRNSnIjvIDATx!êBB ٦ff?Revnvnvnvnvnvnvnvnvnv>RKJ]0JQIFIENDB`egg/vignettes/ca.png0000644000176200001440000000363713206376410014130 0ustar liggesusersPNG  IHDR}oXPLTE  ""##$$&&''((**,,--..1122334455667788;;<<==>>??@@AACCDDEEFFGGHHIIJJLLOOQQRRSSTTVVWWYYZZ\\]]^^__``aaeeffhhiijjllmmnnooppssttuuvvwwyyzz{{}}~2ݳIDATx_SUǟ]SP,@1R+ #[8TeABeRjJ0K h6-we۝{7s?}Ϲ)Xy]Gut]Gut/0ZCnƉ~ `(Lj5p!'B1>?9Q {/D5~EŅ iĄ'`[|+r}4V囈V}q}xO߳he*geYL $Q]=+n+௾`)f&{esru|Fѝz[E?z7ELT`}-5lfgn3V;?K*~8orrSV!(G_ ܩhmkQFVҍ g[#Տ>8^Q~nl)puڞߍLcݫDo,s#RkVx*zFYQ,)"^G8F?+6WKWdD7#ܧ/z=n>{|yl!ɤɔ]Zi W3^}7٦(Ov3\ m*%( [Ķ .r}˺xaal~"j8P;/g3Ҕ]#KĖֵģWmQVV0 >M$cEDzK6S~^H(@4G| --bb>})@MKdkkqs\&lMĢw.6ڂNr_xo^`APA[D|~}4 i?N{ntPXgJgSM;[F&tȽC$=)L-* 5tfUbS53ř\A{*Aӈ<1T)ϖcaHKt}76M$rYP8nb}q !?k߱:g#N8>2zZ$/Q~,R3#E? Ѐ>){n:5_#E|`Dw"E%ROv"ET"E_)R'5vAn(B>>N8BϿh.D̥Ztt]Gut=ny Jk}íuIENDB`egg/vignettes/gb.png0000644000176200001440000000202613206357005014123 0ustar liggesusersPNG  IHDR}oPLTE$}6R8T9U;WTlUmyzz|ٷڹۻ+,122N_O`aqbrfvgvhvvxy{扔爔牔犕줬줭>cIDATxIw@;a 6 {@<"xf4/t|Gu4Eez8awKՙ_nf3 ^O?L`Mk't>^IρEgu<):t&^Cχyx2xJklz)<%KI+ϤSMt<^O]-3CwMgp Ox4t(Gp.Gx1t*GpOx/]}t)p,> OQp /7Mzsp>$܃?ʥjۅ{Yt JU??'^ݝuKd>tAzЃ?NЃ=AzЃ=AzЃ=|:E)AzЃsD\3?z<3 dv_|>x԰ 灟_ >ҏ6);4K'sn&~xLxvyR<^?>L}]r<m(p/ #ڈ$x<AE31*,8eݒp<np|, φ3ڃ!x>+ଦp^;8s+@-4p.:i 5x{_+Mx*ÛU7 \-or_.4p04E64 nl p쀂7í=ߦRv\+3xNN9$(S4.37Td6,on0 $E[6=.:;VSRπ88h?T N3ZQFGlbi6JOZ<T[0.z /VuCɇFNa ywNl7² 9 ?6$h blzz҇8%UXւyI1\ Jy5}pcL+(0hHPJ{}>i:r!Bli ㍵_<K%9ڰgf>,K88(’Udl.M(A)N+`YfDgN;V2Q1f/Blv'"O-P)p!@~ƈÌ3N8]+tׇoPfky!qlpl(塯|"īF#On)T '89ϥ>lGoOwTm,@=zkISyT>ĎL2xZ4nh+S>+zF vAS'wFb#hJJÉ}:[)N1^mT8[y= c%C͋4bo$'L18] K_d]M c&6`!^-6`k8p_wR-&}@}"W.暵R1aWh1tEfI>~l;>IZJ^M(|R:A{˨lЪ]uDt'خm)]%.*Ma8z± (wGKRf' :9y?1 6Őc9jt}[>2Cg |>1Qi4ubEԆ0&VQn\ ځN=|>W}ٜqŞ{L f"Nn^jUnzCm#EdU0<\UH16=Æ6mp){ȌXMq6y֔Ph[Ԑ)` aW B li3V,P)MM,l!.J2jb >`|!5W+0Ux&W 'ls^ϏTf4S-тƎ 'VE>h`|nr RtOJ?$ C*@kr9Qdf;+<="#%)C5`I)f4Hߑ2mX]c G).ƀ@j`\_B] (ZR\TS{0ۆC'mM1Q(ՓPU9qQ6 Y™!gIwQI(@qHG\ĉ'=h9lz)&$i <!.&>T|s}X3ek PJQ9==W(\ߎ#lsSqЎ9GOqI6Q]0G@OvqI CBRh爌G)ΧlҮ7xd7o{#ӏ>74DarttH^=W4 =HB9,='V$Ja xB\Mu,]z39Ĥ)tuaS[Kaa}zg{f4 [-ZAq by};p~UXXr`u]Z9y%JqZ}0q)6:z\.)DQD)uM )}S>Ҝ&p '|U31 e216Bq~5ԏv]k@bqJ)RB)h*kݐr ~0UIؼNڋ,4:g\^o:•C<]Zk\ϥM8٥/A`daNqG 6\Hlfs1&V989i 42tPmC[)4E)0>C$IB!"FWEרO3d*WCFrs.c!/$c[zȕ zXUwqcEXo"M6#i=Jut@3ޑ+r!QĹRxdיiގž/w6~)X~M~-+=SN0c'B?'ˋZ!>dӪiEqrRQZ6>B\ j`)^U:L?cO/"m,|'qg 6M+(("\\$Ka) l۱,Sj`큘g2]7-yc,QyʵE2ms ~ >U{m@coU \6Fx.B\MLyce ZS9ZsVWX $#9Vch 6>yQ5MhC |/WogR,ˢhP}r/-WL稇M+q+E8- `RS68t踾 P `'s!jXuc6aۊkXJa}M! Qq\vAR AS _[TݏS!JE3w/ -VP3qn >1.9%"ul`N#"\r|DS*V8Kb:nkڕгk^`[q .B|~kߏ"Ixfuy$$Q]㔔ﺢMi8@92p5qX_Q;bӫ-z|e , 1P?aG?ƳxíL<۟k[,&M(8Ӓ[צH , {7.}1q́G#9t3AMZ Mnl2$749M)Ҫ iJSxȊ<|º-c;yI;KA>#Ս,eb$0Yws|w2Y: W,<n`p DQDY9~GŶ8ӆk#{^h&A 5R^t2?K JFd̊bpfir89zx;6c}O(~:+Mވr NߨܵOpʀm}O ݁dqE֜8k8*av._|o/$MSΔ$ z>. X9B ɘ^m"Zk^.6pS5* 38\0wi!W6)ü833~@yl0 <u{x Qq!i phu8,"]Py;B\M-Y?\cˋ(38 (NhJIc. GY&Fi XJ0ơ,kr=^JRqQ68 ߻~C8Ja7Kco0`ɏXvs#,a?S܎҃UL0}):-_O>n~ד.]aHR` a=(<PuCu]\BKɰă~;XGw)E:b8MۊJ >ZQ\ \M245E)ssگ_ye!Ih?rGS>V`]L"S_v` 4˂}GwS}t75itdAi͓L?4>{bfUM})Y>y6V-vQ'\ "BH6i *L ;+"twcgr?Tkoz9x>̮{;ܱ?&_0q!6#.|{Z`6m$:*WocI\Fq._S?7VoOscdY#9f$ A`Gqµ-ڏģɄ ^Ұt['7|GS fN~qγtmc1SGlrmobS^(|W¶ammo>ɛjt&mrJq Ym;Q':r)m[Imtg^øŅC︋y?Sj33Y!&cWGJ75|gK.g7ښ %Er(e&J龱Ŷ[">щӓ` Q*䷆JJx!wEH9R X\y֭ټ+_O$OY ąh2gUL=@@7A dL__'$.\Z-`WtѠ=UQafΒw].cx ;_G dЪ+#j )K)Υ8 (@ip vJu5!EԫW\G-MHަҝYJp Jbl2(Ƅՙ;sXB?Jk(,4OY'm,ـڸ5AKш4 8N PM)t>%%:/)LԾT$w}E wѥ{y) !^}6j0pJ""Rr|bs9ibLL%`94&QX V!!iS0JE^.RZ&ZkNiZ$I>B\ .33oQӌ,֠ י}CajC{H{ҭMZOPŔ)y_u',o1u ^YDKdT Ϗ% tef882YV Y8U' _ߢx{IC,XX=10)"Qy[ ,)^{tlF- tf:C3a1c$qI6up K&SS%+iT ts9 gKͷ]7^EVw2'9wz ׷b>W&|ڧi nSq0j`bu#Ei2(8T (HSMjڱK;,kc(^zKf1z3s]y]_'mh W8C״zI"h|@R4Z›r35$IIS"I5Ԛ6qe1I ]G[Y]S:tW]zxοu8\HJ2υ(;,+`G|+GV PB""`Sua^,mxQ o`"M}'][)};[D1|lM 4# yr^kו܌EhzB6Yz:'?Տz$Ǝ+F >c4ŒT1A@?}{b0O3Qr~ʙR7 y|x7ݥks=kzq16Ycيz͍kK8&ی-4ЧvHb4mN΄UJN.d*.3TǨ ) AJֿk ݳXﺕ}͕<09Lym ;zC bQަcu7>#\eЅ!kLUEu^;ppMBH-bl2h8XSM %2>3&F\N [We{ŶžM/n&cb6mȗQډ1{rJ<%l $byYVUR.1>Q9<;G9 vvaTwNbى!c2PEe {'̵-h68R\z۝4!j I?a'%0P4&ku=B٫Rsْg}9pQx+NR[ yevb?c !NA)a#~`J ď$"4B!2O#<"4B!2O#< 4"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<"4B!2O#<,BL-KIENDB`egg/vignettes/ecosystem.png0000644000176200001440000003573413512264254015565 0ustar liggesusersPNG  IHDRT?tEXtSoftwareAdobe ImageReadyqe<;~IDATx[lUם$ۨSU*)PQV!aVɘIѼ%e4 |ZۀQ_[QX@VƂh ʚ5\|Y{セew EXn&0 cU`0V5 cU`0 `0+FGG hjժ_+~￟Y;^fU bnnx뭷6md֨.vmjL޾}{ڵ_|Ya,_|aa'0kƪh({5; 7nܠ#vξV"g}Fovh֭[z7o#!^ZWxZF ୷2#Pᄏm۶ZܹsǏ׮]" /p-ߺu,A6js١ݱ5k*:}>.]*M=z46V5D>,C+1/^[~篾jY {޼yT~#@9-x.Hss![ng_e3찵VZ=7to}Ѹ%=M6ڵK=i8$%u̙;wFV^K-|g0|PDƩQ+곰"i $KyHpR #&*kV5DsΝ?^*z:R;v'NCg}67BI:VȲݯk0#k_|94&?IS!a 8r(3³ǏڦU р7/SE~iJTS1ҤP17sʺu"1d1?/C-rCw礪C~5iL7$AD6V5V͹.?ԩSMu-re&tfGITZZ5BUϿ[;gy40r||\_9ϙ4\0VҪ QPb8 X&3g~˗/SϑEF48+{~:fR]r%/s6uZ 頍.^"K>#9EŐR#ԪlZ`Z5JM BӪkUjpJ|nj39fYDE',=4==-IƯR<?fmZ5SSSBT!bQ5J!%SOfmӪoxx7Li)3۳g8~2@-~^͘;imӪ!#[yQ~PVu>qWj҅'ӪYЪƪ}g!P0RO<͔VEV=%g0??906 L:55/u~3(911;::=3y1%]]]]ЄiqJP`*x^#EV ­~zbn\,y +wԷhK +2T^~̞={S-p]^qpSB_JzTdgP(j*Evuww*@bxxG؆rv,+WRo__|7"uAah˖-;u4}w8J.A>?Ϲ"8=de=͛7'? ĉwB{.ML~3nzW^yEe#7q m(o*vc,TڳDV^ӟ=l+SD_>8䞑{}7l@$TVʁGPEBֶ8uԜ>*F㪲dڵ"5@8!uhIҐQO@u( GIڪӓU()T%nŨ9'Dk. Q")|sW [&v|Dqp[fɓ_1b= j' a|7wR%t\fVu-M7?Tu@gP*Ŕ :DiD̨Z+ &F^p?@U`Vt/DB :WfA7Gm=ұqJ.[H=2gϞǁmۦh& B&z YL'B܄/\ ؖd%4`pɓ'U xkWYҩ%C戬z*ϔͽ"2~ĐF3(D"BzNR (1%"]ڱ 8Y"Pѱ"5U=8_ 4zy~>2"G]bI#@z70Z|Ucմ=*_C$تlJ ZJ Նt-ɟW6}^Bp (\D']]TPk)9vxSaQgـ# e&\vEmeڵji!ŢV`L z/z"@iXB "$ǥIsjZ5МM^єnwP*zSَvuJUDp?JKbCCCe˥lGUN)@__ ^zK ~յb2ETVv1$Drvb5C!'UC~)PZIuO %!]1VҪ_5.%Ǟn]vPe04ZzUԓ;Cmv=AM_VuC^lB +_] 5VbQH{ysI*dp>\U@nU}ЉV_F J!kFIAPGUz"ާfC"b>lր#6IVm-)c=OP}#lWm- RsUMCaO@EҞժQOfmӪ1kwO ;}kՌ'iQ6WLV5j6Z+jh6s8m0 XnE,T5N ΠV>x`|z_&E=ھ}Ç]p(y'v{ZÀW jղ5d|Oy@5Y:M_ljU"H;W׽4.CVZ&tIW)֪XZU˪n>7ed.H̵*Ev4W я!g qRus-Iާ8D\5C ]JVj&QyՉOPdl-Tܚ,#4J G#E<[):Jy$u؞eTiƤ\XUHn8\UtNH]X::UH\5{յ]t(l_ @kv9%G.G@\bd{DkmZq9? ZV-V<#1;wV:o\\"nvR}e3;p!]EX>'9p‡8e_7`';ܜsνj<J,˸oi)GCnUϪ7FFF;~lUYnĚ,GF?:Sr+qG$@XMU7%@us @~E^0^wT'aJӄ-ӵ \Ô]hMAR|7}L*E݆L%\ ^ }֘O1*fV%! LGiykFFnmYC! 4C[+V7EZ5ri㧉cpfqcMp챚ΙUA 1ԪA47rk im͈riۺ9B$HQj&:2]:㱡kUZ?<P5XƕcXX,NKz74ku`hɪn/!>(ww)CYZ5Usޡ8SôIfNZ;wyIy#f"=sb`˟w5DkhU !\ `hbf8X;g;&Wڝ 84"WZ;,[lvv~k}7V^bzfY>?!lM0*=eQjg =oܸn:$bctt_\.߀L9b۷o牸}9sfΝ5_fMOOO}x/Ӵ{@ <(^`78T8cҋ:CIujlRkչs4%hIVݸq^xСCׯ_'rq\Ϧ(y-trr6iqw4X moPTWݲeKok׮CJD.]D>vo79}b:ٖ4TӁmlXVP($RIZQ*va)Ԫ/BܵkצMܺukǎ&/߭["BaLUO:5<< ;v2tzϟ?q_f~~XCh]^k틩; i喵7ݫQ^t}N%zF97ZCysx[5!/ӡFښcVW:_#K/;w.0˗9#v'f|IY~>ovqmK= F2_,hkGKû!TnPJq/ƳJG2 b:,f|s(˃6558u4k֬$~+5h5D( 늍ȥ MunгpqT㖬ۼd?ƳRnxW\Jf秦gQM7 vs;Ec:M̚Vxy!'DQJsk\0C=$J &"񐮑UWW=JQmj NSӱKfy=z8[U}W=qGq1333#|xӥ$Q ^3 >}[ ,th @M"3~=uYԇTP%h3BB><ĺ%zTZuʕwc=pK/qFIB*'=zhT Ϣj9KV@w@bڵ/Ta P7E-R0ۊMfjn hO5$箧 ԙYn044݋ !L /F{XH%h_𗄴yZbL']kj`vj18E$߲rD )7Fw*t*>Jtӝp'tcLmfпuY`b;vZ7*4ovvV}dҼ?? 6h-ҕ+W+/ ˖- eXJ+]]]ׯw7oLb4Ҭ۷o{%޽{˿ `.??.(;l|ֵOZ*ww9z Y5 b1wHTuV5YҪ #4Vɖ}}}ߊ>r-piV9f[tr]g`F,}Uo_Sp?vƱH&fWB M?*ubbBaq(U5R4FQڦ0F'UZ"9l%En ^fKL֩7tu:£fG.2pjg+_Kʽ](UUk!Ƅwey] 3>qx#f^V OmbU4V]xD *u@VbU%?UUuX)5&ɯsL uGs+kWGu~a~jرcpRwcllLrR47oތ}ԿP= NȩYo޼Or9֤B rr P([;6+C;r7<;MA*#gCQJ0+_!9rbP@([tSrt[BK3U}A&rlƀtӣ4$ ][~pTӱ 58l֩uUij93][ձ51wcUt!2~T4>4Y)QU3n̟b}VhZ[ gBCCCVTiD9̠fYeZBƓ'O6՞={ Ju#yLOh3(Ϳijٳ۷o/r E3<<|agt8AJM@wۯO ZB%[' Ri= (՘zZMMVu ߀bQS5JMƌUwJ6 7ZoLU{*~n^b坙PZ0hԓ4{qHpchN; J 4[PNO~!EbJsnR@ӕ[p7ÜlקW%HS:' r{E]*L9V;ArXrwpJ]r}'r9}% $7b`ղ9HQs&jڵk_Q47m]yK]+։![.Dɝ=BZ[vf2:zF/(288Q~}sj|DLEsx0Rpp ElC9F_4޺m6!Rt~Eq$Cb+[EUJ}.0/I,ܤ*s0̐nfvo@'] ަUCWl7RsmBwd0ڄG+A'Z]6yQ*bD npႩUX"i1z166ˆétJΞ=kM|'ZRJ)xXܲeK o޽֯__ﹷo߮whwŊ¯(wL+#Ĥ$+[GtҪPBItzzZ_(@³.Jx_.,_W_;լю*oo`U:ݹF=_ȚD}BA:o8]=Lu˙S탪x@_Mmʫتnts^@3l5vBiN@㼚PՎ2~W&A|e CKj_v3UV)Z?99 5А֛jR$ZU3g>q/VaŊwn/T jUX (^h߆5yhmjolhkTR~0Jm9}3Bjb\ S֮m?q>55F;f ^]WwhoP$Bѣ*rJh܊.%6R\ UVmʒڑ =fQO333/B_XokcY%3EݢVIfZ>(;x"gӦM]^tܺu+񔐿HҪG(CH٥׋Bkf1djÇplk׮C۷SN==~* #z˖-:1VmŢfU RC *7^"_ cǎ7wx7wIP3tw8tPɴjj~h1|t?,_ekc=V(k B;wԄW F| s"#/IڴؾPňUN>>ѡ0+Wɼ7MK7R31/|Z7hUwؑ f3gR۸j-KCXMs&''pc'F;ӃPǥ'Oϩ.j]Kkm۶ %NUS*ﭭImWF㪩VwojfEP}|/}Ɍ&Wzꩧj;h:PqV [Vj011ܾ ,N3)c E"týfjk@C)'Toܸ1ڷhKKM@Xު|wwwF:n颖[8 UU-XXǴjWWW *@>'K6 ]BnZU jw*&6 8 wTFr4Zܸ;pmb R.cՇ$KVa1EE㳄uH:NX6!ܿs:}RUE].׮Ҫdĩ'*s]T6Z h#@ƪG*ɴ ZFvg AM׭[HO 2!=FtҕQf}}}*pȉӪEIL5sj0a프nr :ObQsshZɓFme]Jdվ-sGA:;o qCۄ! jE`gRB[P"Y_#eyt r㽰$ Ms:"r OkWqmB[kx~ef*PR|hVm(Hd8q``X]s Q]uLԨ#M<$ϩCd4kPz_r!%([L]x8uawNXȬV356 *JxYW8B9_EP$gH ~*%t @@tU`J/G (5t* ׅ ؼKeh-8Y8 $zjJX?=ZI+SKd`HUjP2?!i&#]L\V6er^ePL( C/TzU+7c0b]eDjcWb%6)vi>@]* CiHת7!^OL4^>*Jb",FhQjThV͔jD5WuU U'nիW[҄4uӪa~~ ѪȮz? YVUM6|>O5 4kUء7BLK>j痖kf$ +FXWh(aZjooQj&X^hx)hǞ-Z*Chr^Tb-aX\n3ĪP㤐T"^~tA-6Y?&h*a*~yW0dU$V7T7oھ}{__z` ptͮ_ 8JݤWh@U9..w\UQ|ǬSUrҐye@ttI7Ѫnc8"&Z[hJ.T}ɶ\Fi:Z2$nGeփsbhttԝ+U(MQ>b=(rᒙei*sesMah7:1ZP)tgTܙiU!CiėsH^%Ji\EDdGA 声R:r*)Q*[2!$[/ $ӇGt@UȒr%D#ȉ֪HR̍vrzֱBǺZU=U`r2jULzYosS /:JGhWTF䎏>ro^$<&r*#(Y9W'[/u!7CJJH2!+_;V 5gKj6ܩC>Q)B[Z_:4gt4o=LMCBgUloynK]*Zu}Y湅 } MMl0J5Z4vHZkJ^M0+X!JŦW5;;/Y_{UV5H8ƥhc9W"#o>,ϥ(USOT8;6_BUncn޼I̦Mj̡csܹ^nƍ5ôjZQ,'&&c7X^E֛F:UB6ԴjⰸȓOӪIl;88hjhvxmUִ!W^E)C[FjWק=Ӫ͛L-u YFZWMVq8tԃ7(CjiӪAX}s(ehl\5jF|gxx2$Iҥ{ꚻMV2>Qk׮5>5$O"{_Y0jh- }7ąU띯 3"Ts$xscŴa,.. iS088o1h^zڵ_kd u֚5kfffaΝF Zվ4ޟW/mƾ!֬ZjO*/'Nؿcò{Jm˖-*7={(ƺw0+|W3R9[!pSNjU[2G j^2(s%RM,655EKo_ fՆ7M?#xSھU PZKc{tw"i5WoGf*TnQ!)h* ׯw16ìP(ҜM7UѪO>$_ߦתWu#nVL.kO [fkZ(iզt+ӪI":ի<ΫM/EAjbЪKcUsR7C f@櫺 vFҡ jU nU)kF睰6-.k  ic cBtRj (Rɓ6dyHCjWW|оv/zTUk p}ٰlz`ȊV*{왛K ֪j0Wu䂕3```C߾7o֖P С!NW44u9Qa.Jȍk)[(䬔#sxxB %a%Gmw_~/{Ui%s>KQ:]Ki0$w*S'nÇGGG 8 h iKE):m/+r.7NMMU ]W0Vp\o||\clߗQl (e% Zh4b';RwX-CtP ,CGG‡$$JbU^T$݅ߗ_rUHSˏ08A%#:Йc-qGoxu89$ HV0;qO@bC"OjSPҒ+&N< f\`q՚"Qk@gplQN! 5./*0/H!w"GBnS~$+'@%t%sUx5j0Vu5:uTEx2:Ȱʇ&9i~8;7tܑwN9ED)-p\ihUߩ"U*#U U4L$wCxB0R)$Q%1}wj+lZ`Z'ׁ"o4j0dU#Q[L iEVj0Ȫ P `0V5V5 5۷o[fv`fff޽f![ZʂKCغu`ԟҥKf`0jZ`0Vm333sQӪj#o߾s/rXմ`Z5عs3g8rV5RҪ/^aqT;㊤Jb YxcX\bݽ{,Rgy{\X͛7}]{ io}[/y䑸ӝ;w_g}P*\*f#ć~ iEŽo]h$*o߾}'N8s ܚ,O=yCFƧ׮]t&' Y~wR jUѹ 6Ĥ/^|s$ᣏ>ziVU_/@d4>`tuu\rŊd?}(`V֒_ꗾUV\0Dh-[v֭|;7nW``0a`0 ƪ`j0 ƪ`0V5 vbIENDB`egg/vignettes/Ecosystem.Rmd0000644000176200001440000003366413512266011015454 0ustar liggesusers--- title: "Laying out multiple plots on a page" author: "Baptiste Auguié" date: '`r Sys.Date()`' vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Laying out multiple plots on a page} %\VignetteEncoding{UTF-8} output: rmarkdown::html_vignette: toc: true toc_depth: 3 --- ```{r setup, echo=FALSE, results='hide', message=FALSE} library(knitr) library(gridExtra) library(egg) library(gtable) library(grid) opts_chunk$set( message = FALSE, fig.width = 6, fig.height = 3, cache = FALSE ) ``` An individual ggplot object contains multiple pieces -- axes, plot panel(s), titles, legends --, and their layout is defined and enforced via the `gtable` package, itself built around the lower-level `grid` package. Plots themselves become _graphical objects_, which can be arranged on a page using e.g. the `gridExtra` or `egg` packages, which provide helper functions for such multi-object layouts. The following schematic illustrates the main relations between these packages. ![Schematic illustration of the links between packages `ggplot2`, `gtable`, `grid`, `egg` and `gridExtra`.](ecosystem.png) ## Arranging multiple plots on a page To begin, we'll create four example plots that we can experiment with. ```{r basic, echo=2:6, fig.height=5, fig.cap="A few plots that we want to organise on a page."} set.seed(123) library(ggplot2) p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- qplot(mpg, data = mtcars) + ggtitle("title") p3 <- qplot(mpg, data = mtcars, geom = "dotplot") p4 <- p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") + ggtitle("facetted plot") library(gridExtra) grid.arrange(p1, p2, p3, p4, layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)), widths = c(1.2, 1, 1)) ``` ### Basic strategy The easiest approach to assemble multiple plots on a page is to use the `grid.arrange()` function from the `gridExtra` package; in fact, that's what we used for the previous figure. With `grid.arrange()`, one can reproduce the behaviour of the base functions `par(mfrow=c(r,c))`, specifying either the number of rows or columns, ```{r arrange1, echo=TRUE, fig.height=3, fig.cap="Basic usage of `grid.arrange()`"} grid.arrange(p1, p2, nrow = 1) ``` If layout parameters are ommitted altogether, `grid.arrange()` will calculate a default number of rows and columns to organise the plots. More complex layouts can be achieved by passing specific dimensions (widths or heights), or a layout matrix defining the position of each plot in a rectangular grid. For the sake of clarity, we'll use a list `gl` of dummy rectangles, but the process is identical for plots. ```{r arrange2, echo=-c(1:2), fig.width=4, fig.height=3, fig.cap="Illustrating further arguments of `grid.arrange()`, namely `layout_matrix` and relative widths."} cols <- c( "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC" ) gl <- lapply(1:4, function(x) grobTree(rectGrob(gp = gpar(fill = cols[x])), textGrob(paste("plot", x)))) grid.arrange( grobs = gl, widths = c(2, 1, 1), layout_matrix = rbind(c(1, 2, NA), c(3, 3, 4)) ) ``` Further examples are available in a dedicated `gridExtra` [vignette](https://CRAN.R-project.org/package=gridExtra/vignettes/arrangeGrob.html). ### Plot insets A special case of layouts is where one of the plots is to be placed within another, typically as an inset of the plot panel. In this case, `grid.arrange()` cannot help, as it only provides rectangular layouts with non-overlapping cells. Instead, a simple solution is to convert the plot into a *grob*, and place it using `annotation_custom()` within the plot panel. Note the related `geom_custom()` function, suitable when different facets should display different annotations. ```{r inset, fig.width=4, fig.height=3, fig.cap="Plot inset."} g <- ggplotGrob(qplot(1, 1) + theme(plot.background = element_rect(colour = "black"))) qplot(1:10, 1:10) + annotation_custom( grob = g, xmin = 1, xmax = 5, ymin = 5, ymax = 10 ) + annotation_custom( grob = rectGrob(gp = gpar(fill = "white")), xmin = 7.5, xmax = Inf, ymin = -Inf, ymax = 5 ) ``` In the second annotation, we used the convenient shorthand `+/-Inf` to signify the edge of the plot, irrespective of the data range. An alternative way to place custom annotations within the plots is to use raw grid commands, which we will present at the end of this document. However, note that an advantage of using `annotation_custom` is that the inset plot is embedded in the main plot, therefore the whole layout can be saved with `ggsave()`, which will not be the case for plot modifications at the `grid` level. ### Aligning plot panels A common request for presenting multiple plots on a single page is to align the plot panels. Often, *facetting* the plot solves this issue, with a flexible syntax, and in the true spirit of the Grammar of Graphics that inspired the ggplot2 design. However, in some situations, the various plot panels cannot easily be combined in a unique plot; for instance when using different geoms, or different colour scales. `grid.arrange()` makes no attempt at aligning the plot panels; instead, it merely places the objects into a rectangular grid, where they fit each cell according to the varying size of plot elements. The following figure illustrates the typical structure of ggplots. ```{r plotstructure, echo=FALSE, fig.width=6, fig.height=3, fig.cap="Colour-coded structure of examplar ggplot layouts. Note how the panels (red) vary in size from plot to plot, as they accommodate the other graphical components."} pl <- lapply(list(p1, p2, p3, p4), expose_layout, FALSE, FALSE) layouts <- arrangeGrob( grobs = pl, widths = c(1.2, 1, 1), layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)) ) ids <- c("background", "panel", "axis", "lab", "guide", "strip", "title") cols <- c( "grey95", "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC" ) leg <- lapply(ids, textGrob, hjust = 0, x = 0.1) legend <- gtable_matrix( "legend", matrix(leg, ncol = 1), widths = 1.2 * grobWidth(leg[[1]]), heights = unit(rep(1, length(leg)), "line") ) legend <- gtable_add_cols(legend, unit(1, "line"), 0) legend <- gtable_add_grob(legend, t = seq_along(leg), l = 1, lapply(cols[seq_along(ids)], function(x) rectGrob(gp = gpar(fill = x, col = NA)))) grid.arrange(layouts, legend, widths = unit.c(unit(1, "null"), 1.2 * sum(legend$widths))) ``` As we can readily appreciate, each plot panel stretches or shrinks according to the other plot elements, e.g. guides, axes, titles, etc. This often results in misaligned plot panels. In this situation, instead of using `grid.arrange()`, we recommend to switch to the more powerful `gtable` package. In particular, the `rbind()`, `cbind()`, and `join` functions can provide a better alignment. The plots must first be converted to grobs (more specifically, gtables), using the `ggplotGrob()` function. The second step is to `bind` the two gtables, using the sizes from the first object, then assigning them to the maximum. Finally, the resulting object, a gtable, can be displayed using `grid.draw()` (it is no longer a `ggplot`, so `print()` no longer renders it on a device). ```{r rbind, fig.height=4, fig.width=4, fig.cap="Aligning plot panels. Note that the two y axes have different widths."} library(gtable) g2 <- ggplotGrob(p2) g3 <- ggplotGrob(p3) g <- rbind(g2, g3, size = "first") g$widths <- unit.pmax(g2$widths, g3$widths) grid.newpage() grid.draw(g) ``` ### Aligning complex plots One possible strategy, implemented in `egg` with the low-level `gtable_frame` and high-level `ggarrange` functions, is to take the following steps: - decompose each plot into a 3x3 layout, where the central cell corresponds to the core panels, surrounded by axes, legends, etc. - set the core width and height to a fixed dimension - bind the individual 3x3 gtables Aligning plots is achieved simply as follows, ```{r egg, fig.height=3, fig.width=6} p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point()+ theme_article() + theme(legend.position = 'top') p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme_article() ggarrange(p1, p2, widths = c(1.5,2)) ``` where many parameters are common to the `grid.arrange()` function from `gridExtra`. ### Multiple pages? Plots produced by `ggplot2`, including those with facets, and those combined with `grid.arrange()`, are always displayed on a single page. Sometimes, however, there isn't enough room to display all the information, and it becomes necessary to split the output on multiple pages. A convenient approach consists in storing all the plots in a list, and plotting subsets of them on subsequent pages. The `gridExtra` package can simplify this process with the helper function `marrangeGrob()`, sharing a common syntax with `grid.arrange()`, but outputting as many pages as required by the total number of plots and per-page layout. ## Mixed graphical components ### Titles and subtitles Adding a global title and/or subtitle to a page with multiple plots is easy with `grid.arrange()`: use the `top`, `bottom`, `left`, or `right` parameters to pass either a text string, or a grob for finer control. ```{r titles} grid.arrange( p3, p3, p3, nrow = 1, top = "Title of the page", bottom = textGrob( "this footnote is right-justified", gp = gpar(fontface = 3, fontsize = 9), hjust = 1, x = 1 ) ) ``` Recent versions of ggplot2 have added built-in options to add a subtitle and a caption; the two stategies are somewhat complementary (`grid.arrange` aligns elements with respect to the entire plot, whereas ggplot2 places them with respect to the plot panel area). ### Legends When arranging multiple plots, one may wish to share a legend between some of them (although in general this is a clear hint that facetting might be a better option). The procedure involves extracting the legend from one graph, creating a custom layout, and inserting the plots and legend in their corresponding cell. ```{r legend, echo=TRUE, fig.height=4} grid_arrange_shared_legend <- function(..., ncol = length(list(...)), nrow = 1, position = c("bottom", "right")) { plots <- list(...) position <- match.arg(position) g <- ggplotGrob(plots[[1]] + theme(legend.position = position))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) lwidth <- sum(legend$width) gl <- lapply(plots, function(x) x + theme(legend.position = "none")) gl <- c(gl, ncol = ncol, nrow = nrow) combined <- switch( position, "bottom" = arrangeGrob( do.call(arrangeGrob, gl), legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight) ), "right" = arrangeGrob( do.call(arrangeGrob, gl), legend, ncol = 2, widths = unit.c(unit(1, "npc") - lwidth, lwidth) ) ) grid.newpage() grid.draw(combined) # return gtable invisibly invisible(combined) } grid_arrange_shared_legend(p1, p2) ``` ### Tables and other grobs As we've seen in the previous examples, `ggplots` are grobs, which can be placed and manipulated. Likewise, other grobs can be added to the mix. For instance, one may wish to add a small table next to the plot, as produced by the `tableGrob` function in `gridExtra`. ```{r tables} grid.arrange( tableGrob(mtcars[1:4, 1:4]), p2, ncol = 2, widths = c(1.5, 1), clip = FALSE ) ``` ## Alternative options We've focused on `grid.arrange()` and `ggarrange` for simplicity, but there are numerous alternatives to achieve similar arrangements of plots (all of which ultimately based on `grid`). We list below a few alternatives, in chronological order. ```{r comparison, echo=FALSE, message=FALSE, warnings=FALSE, results='asis'} tabl <- " | Package | Function(s) | ggsave compat. | alignment | |-------------------|:-------------:|:------:|:----------:| | grid | `viewport`, `grid.layout` | no | no | | [gridExtra][1] | `grid.arrange` | yes | no | | [(r cookbook)][2] | `multiplot` | no | no | | [gtable][3] | `rbind`, `cbind`| yes | yes | | [cowplot][4] | `plot_grid` | yes* | yes* | | [multipanelfigure][5] | `multi_panel_figure` | yes | yes | | [egg][6] | `ggarrange` | yes | yes | | [patchwork][7] | `plot_layout` | yes | yes | " cat(tabl) ``` [1]: https://CRAN.R-project.org/package=gridExtra [2]: http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2) [3]: https://CRAN.R-project.org/package=gtable [4]: https://CRAN.R-project.org/package=cowplot [5]: https://CRAN.R-project.org/package=multipanelfigure [6]: https://CRAN.R-project.org/package=egg [7]: https://github.com/thomasp85/patchwork ### grid viewports and layouts Underlying all these other packages is the `grid` package, included in the core R distribution. This package provides the low-level functions used for drawing and placing objects on a device. ```{r comp} pushViewport(viewport(layout = grid.layout(2, 2))) vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y) print(p1, vp = vplayout(1, 1:2)) print(p2, vp = vplayout(2, 1)) print(p3, vp = vplayout(2, 2)) ``` ## Acknowledgements Parts of this document were [originally written by Hadley Wickham as a draft vignette](https://github.com/tidyverse/ggplot2/issues/1239) for the `ggplot2` package; the contents have since been shuffled around quite a bit and I have lost track of the exact history of edits. egg/vignettes/nz.png0000644000176200001440000000573713206357001014172 0ustar liggesusersPNG  IHDR}Y~] IDATxytSUqYϜ9PёQhRq@A6F\,#ʨ32"E@]vRvYYZ@kWRJ)4i$]~{9-@9ߓIi-i07r7gSp[4UnAiۚ4Dnvb|ݓ}Z}^Xo]A. yw KߦcYk0W}['l`zG- z'- =z\קoI5z,ЫmvmW'C}R]fY.B/UjGN'ȵ|{"o^]/ f^ i2UΔ xwB'pZt ]] !twtWu @zwCzLn'nEEE<'twtW{cQ~1- ]>W<0FXbo <.+zqz0F]  0h@itH._q~ebx)/~:k8|*2Ld "|^w @9^\ONya5"&uqb噳2x]|Qm <ǐZ ytόUaM`Kc7r^wF誷x,[/wc}:k>"cA+}WpU'Kt9U}Gi76;kj:PUU{=1}Jڕˁ([;|j#[f/;y=7tĔb`u-rVY-76CƝr=f#&@0\ςJ5-- ]f [w4"Ҧy*K0]?75>p!?Z/K=0嬱e/yk\YK4{^>HÝ~ ԇN:"L)W ݳLswSa qO"g}]q鰘-yߺkL7xZUUۧ3o}lצn%'"2>-U{]K] oY| [zN_V##V <^o9U_Y] ƋOEPQnǟ-Pz>צXVOɯGL_(:7/6hBT[?:u[np9 Ő{ 3#]TZ^ԁp@'k)nA~1O$6:VX˓B8Kjbex{Q,".E{iL 8}*tO?j.dd4zRM?C/TWV58s?=i}Ƭ*fuםCh SX>xE#0D㋨6׷iy`z8?wiÒ*X|^k ]>hVM@mAW֡{*ɳb*5y/ {v.Vn ۍ~/~qL?F]U\\Q7ZR }7utW ;־RTYb҈X ? dpŇަ> U:tWwǓwHOD㋂!*`Flވc0ڴAW ^;vZs(O/-O^\;'n%JWBWޠ;(6ZRޯ#c6 '{v$+ \Нշ=.)YFtMf"0]B& ˧ىu- ޵obǁ_sS2ia:&ÿF{/cЩ4⃥|۵ۃϾ񳸜T1F1Bg:cc31F1Bg:cc#t1F1Bg:cc#t3F1Bg:c@OΘ{'(3p7>H? 2N#t|@\DLM"q\y=3PwŪgcD.~nʕx~ǘ>5 BZN&SwTUY3🀷:pdxmY`MZ ҄v5^^3[zz\K茩ڒ g1o)Eݸig#on?:cN0!޶_;S|Ā;!`,/-!tT NVEn5I3j.]E茩֖Wj:\8gV 1}'tׄ6{WT?5a#t31F1Bg:c#t31F1Bg:cc CfM;-o՟IENDB`egg/vignettes/ar.png0000644000176200001440000001040713206357003014135 0ustar liggesusersPNG  IHDR#!-IDATxyTVlދ}նz۾VoWj7zE[oUjպ kXdAd_gd$ PjW=yfB9'O~3&ˏmtٚea tf%殴)-~FFob8(:<)f$7bj+#}-+n3ֽ=JxH{S t;$0}J1ok.yu2ёUTg"'}'׭P9a'rYZ}Q*a( ݧh%]\Ne&6m2wkoS>JƮs:LxìbWHzڬ\}{# ݧP,d*WrD*|M;rsN@pf~M^Nn&>ҤQ~/lgRֻ?*M *+C)f({ѡz eneC]4u%rs٤X4W'jgnmJlLm,>mos5GDs& ,v*_v~YwY 1M>!y]_jIaÀC@W\D_B"=McW"ޔ ZdeҰŝMqՙ_.~ 4Ez0d7ZMs>(ȸWv;Gc Nm`c3~Vyi o 'n^;B</?6VDѼ?IG͵iGZ`&L>6:~C>YU";ǮQg56E)ӷQ!5!RK/U\թV(d8YZYFh?>&c51bdfǥ+qZ klMڬMɏʣE*鰙L1vUtGߜ˫pߢ=3|5QrhqnӘugdh(4ei*>11gA_ʿ8t3 _77xȊZ;Cj"'[+)Xz0򉶋D_ ~ѽ( ק,s)oy}q].~jR:l\ (e[>{P.ZN/\a(8@{&tӘw\:o &7TU$O|;'ߺ2'kN%?ʌmtcqJk.:0}re3S9]&à0ky-BRVrn\quE{[=4'q~-DAtOl'dY!NxUףz!srUeqWΧfic1/Se~c_[jO/Vjvן!}rn\JT v{9qĵ2?/.%d{oY&zE{ĮeR!dM#2THˇ{錯)[%qg_+[bK$*zc Kc6tG1܈$n6J Q U$=SoWʖ4F>V8P^:3e*:a YZq'vÍ }rv[Gn :.kàW$K^sDe.-DӒ1'+(ET,D'TЪ :GotܰrU?)k5ik/JCJN'U^~2F}"\Ca ը?%.i8N?p:, 'g q;wOo8!-&s\nJjni%uۛ*@{ቶ@+3by lMy*,ޗ>]gT0tIߕ! WP c$ZY;g(p4rӨe˜ͥ~^{{&,ҩ$3iڋf$Cr >)a̡MY.z_}I}FD3gQ) 'o ,.2]Ayɿ{.⃼]^ vy~;ʗ?=Q6S3 eQۆI%Gu%pxhoG[ц<˳?3hF)X*m{Y#/|E{ԼK-=tɧԅQ}/;8ӊm8s"ƫG [lLo׋w!$k4^?\|Y"lJUggۚK{ӘܰSe/=_{v8%I u'gٕ TToYkJtpF>|<<؃цWQ}g* bۍ%a \>$97YV! zZ(uYۚ@qKM^pjq [Wp1i.}g"S>ƘCI [cNb^X[eu_%/n"y"3vbQW7Y“ ~WMK;٧Jٮm2naS#N3E-7$Vu|u8ɊT<T.?G4QIk-FYVRȋ:]#̯70U%WS@ͨ}EYԧIY724Hoէa6R)z6`wCLZeSͥ51qoq0>bͶʊEcΔqr|E[lIccќy-wRodR6b?UIg8 ݧzlZ2^Fkr_J^gxVM]Eg'uS%_Ҿ뒘5菜V3Ou;ϳ:)Q+}N۶Er;&s߭wT%3פn#^uo~ aʸy&rW^:Yo( n~ s˸Ztc3>iu,uˢǸA;QĢ:\}ӶnኾA;@wrAZ_?@w;t@w;@w;t@w;@w;t@w;@w;t@w;@w@w;GaE[IENDB`egg/vignettes/Overview.Rmd0000644000176200001440000002167713512226504015313 0ustar liggesusers--- title: "Overview of the egg package" author: "Baptiste Auguié" date: '`r Sys.Date()`' vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Overview of the egg package} %\VignetteEncoding{UTF-8} output: rmarkdown::html_vignette: toc: true toc_depth: 3 --- ```{r setup, echo=FALSE, results='hide', message=FALSE} library(egg) library(grid) library(gridExtra) library(gtable) library(knitr) opts_chunk$set(message = FALSE, fig.width = 7, fig.height = 3) ``` This document provides a brief overview of the main utiilty functions included in the `egg` package. ## Exposing ggplot2 layouts The function `expose_layout` can be useful to illustrate the structure of ggplot2 plots, e.g. when ying to customise and/or post-process the gtable layout. ```{r layout} p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- qplot(mpg, data = mtcars) + ggtitle("title") p3 <- qplot(mpg, data = mtcars, geom = "dotplot") p4 <- p1 + facet_wrap( ~ carb, nrow = 1) + theme(legend.position = "none") + ggtitle("facetted plot") pl <- lapply(list(p1, p2, p3, p4), expose_layout, FALSE, FALSE) grid.arrange( grobs = pl, widths = c(1.2, 1, 1), layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4)) ) ``` ## Setting panel size In some cases, having ggplot2 expand the plot panel to best fit the available space isn't ideal: for instance, we may want to produce multiple plots to appear on different slides of a presentation, and the successive pages should have the exact same layout for smooth visual transition. Another use-case is to embed multiple separate graphics in a drawing/page layout software. In this situation the plot alignement will be made manually, but the plots should not be rescaled (otherwise the fonts would be distorted). For such situations, the easiest solution is to set fixed dimensions to the gtable produced by ggplot2. The function `set_panel_size` helps set the panel size (width, height) to absolute measurements in the form of grid units. In the case of a facetted plot, all panels are set to the same value. ```{r panel, fig.height=3.5} p1 <- qplot(mpg, wt, data = mtcars, colour = cyl) p2 <- p1 + facet_wrap( ~ carb, nrow = 1) grid.arrange(grobs = lapply( list(p1, p2), set_panel_size, width = unit(2, "cm"), height = unit(1, "in") )) ``` Note that the total size is now fixed, therefore when exporting the plot on a device it can be useful to query the size and set the width and height accordingly, to avoid clipping or white margins. This extra step is enabled by default when saving the results to a file. ## Aligning complex ggplots `gridExtra::grid.arrange` provides no way to align the panels of individual plots. While this is achievable with low-level `gtable` functions, it often requires substantial effort on a case-by-case basis. The `egg` package introduces a general strategy for such layout manipulations, with the following steps: - decompose each plot into a 3x3 layout, where the central cell corresponds to the core panels, surrounded by axes, legends, etc. - set the core width and height to a fixed dimension - align the individual 3x3 gtables using `rbind`/`cbind` ```{r frame} p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme() p3 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_grid(. ~ cyl, scales = "free") g1 <- ggplotGrob(p1) g2 <- ggplotGrob(p2) g3 <- ggplotGrob(p3) fg1 <- gtable_frame(g1, debug = TRUE) fg2 <- gtable_frame(g2, debug = TRUE) fg12 <- gtable_frame(gtable_rbind(fg1, fg2), width = unit(2, "null"), height = unit(1, "null")) fg3 <- gtable_frame( g3, width = unit(1, "null"), height = unit(1, "null"), debug = TRUE ) grid.newpage() combined <- gtable_cbind(fg12, fg3) grid.draw(combined) ``` ## Arranging and aligning multiple plots Using this generic strategy, we can easily align arbitrary plots (facetted or single-panel), with the convenience function `ggarrange`, ```{r ggarrange} p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point()+ theme_article() + theme(legend.position = 'top') p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap(~ cyl, ncol = 2, scales = "free") + guides(colour = "none") + theme_article() ggarrange(p1, p2, widths = c(1.5,2)) ``` Note that custom widths and heights may be provided for the layout. ```{r ggarrangelayout} p <- ggplot() ggarrange(p, p, p, widths = c(3, 1), heights = c(5, 1)) ``` For convenience, labels can be added to refer to the subfigures. All parameters of `textGrob` can be used for the formatting of the labels, including the positioning (`x`, `hjust`, etc.). ```{r ggarrangelabels} ggarrange(p1, p2, p3, ncol=2, labels = c("A", "b)", "iii."), label.args = list(gp=gpar(font=4), x=unit(1,"line"), hjust=0)) ``` The package provides two functions for labelling facetted plots in a more compact manner, removing panel strips and using in-panel tags instead: ```{r tagfacet} d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) tag_facet(p) tag_facet_outside(p) ``` ## Custom themes `egg` provides `theme_article` and `theme_presentation`, ```{r themes} d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) p + theme_article() ``` ## Symmetric axis scale The function `symmetric_range` helps align the 0 value of adjacent panels in facetted plots with asymmetric range of data in each group. ```{r symmetrise} df = data.frame(x = c(1, 2), y = c(5, 0.2), group = c(1, 2)) p <- ggplot(df, aes(x = x, y = y)) + geom_point() + facet_wrap( ~ group, scale = "free") p + scale_y_continuous(limits = symmetric_range) ``` ## Custom geom The function `geom_custom` extends the ggplot2 function `annotation_custom` to cases where multiple grobs are to be placed, e.g. on different panels, or at different positions in a plot. This geom is a bit special in that it does not truly respect a *grammar of graphics* -- arbitrary grobs can be plotted, with no explicit mapping to variables. Its typical use would be to place annotations (images, tables, ...). The data used to create the annotation is passed as a list-column. ```{r custompics} codes <- data.frame(country = c("nz","ca","ar","fr","gb","es")) codes$y <- runif(nrow(codes)) gl <- lapply(codes$country, function(.x) png::readPNG(system.file("flags", paste0(.x,".png"), package="egg"))) codes$raster <- I(gl) ggplot(codes, aes(x = country, y = y)) + geom_point() + geom_custom(data = codes, aes(data=raster), grob_fun = rasterGrob, fun_params = list(height=unit(1,"cm"))) + scale_y_continuous(breaks=NULL, "") + theme(panel.grid = element_blank()) ``` The list-column format allows passing grobs directly, in which case the `grob_fun` function should be identity, ```{r customgrobs} codes$raster <- I(lapply(codes$raster, function(x) rasterGrob(x, height=unit(1,"cm")))) ggplot(codes, aes(x = country, y = y)) + geom_point() + geom_custom(data = codes, aes(data=raster), grob_fun = identity) ``` Note that such grobs need to have `x` and `y` slots, which will be mapped to the appropriate location. It is therefore often necessary to create a wrapper with such fields, as illustrated below. Because the grobs are manually "mapped", independently of the main ggplot, this geom also allows the placing of arbitrary annotations without interference from transformed coordinate systems, etc. ```{r customgrobcoord} custom_grob <- function(data, x=0.5,y=0.5){ grob(data=data,x=x,y=y, cl="custom") } preDrawDetails.custom <- function(x){ pushViewport(viewport(x=x$x,y=x$y)) } postDrawDetails.custom <- function(x){ upViewport() } drawDetails.custom <- function(x, recording=FALSE, ...){ grid.rect(mean(x$data$x), mean(x$data$y), width=diff(range(x$data$x)), height=diff(range(x$data$y))) grid.lines(x$data$x, x$data$y, gp=gpar(col=x$data$col,lwd=2), default.units = "native") } d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3)) gl <- lapply(1:4, function(ii){ data.frame(x=seq(0.4,0.6,length=10), y = runif(10,0.45,0.55), col = hcl(h = seq(0,300,length=nrow(d)))[ii], stringsAsFactors = FALSE) }) subplots <- data.frame(f=letters[1:4], data = I(gl)) str(subplots) ggplot(d, aes(f,x)) + facet_wrap(~f, nrow=1)+ coord_polar() + geom_point()+ geom_custom(data = subplots, aes(data = data, x = f, y = 2), grob_fun = custom_grob) ``` egg/MD50000644000176200001440000000525013512271573011334 0ustar liggesusers8d930ad26d516b4b1e0c576ebb805e8c *DESCRIPTION bea5f684c3c5051cc64a677caf60c9bd *NAMESPACE e86387b59689a972b96b57d34ef2132a *R/expose_layout.r 9c2383ea02ebe574e526ca0bf688b44c *R/geom_custom.r f649dc44189e5ac1a2dad484d4a5e016 *R/gtable_frame.r 60b17bfaced3343145a9f6917a590b3c *R/set_panel_size.r f337d1369c535ae056a5d9ca5fcd126d *R/symmetric_scale.r b5b0f2d1c7ae229ad9c44651cbd46f51 *R/tag_facet.r 13c65c7937d6a769426f26896a7dd4b3 *R/theme.r 953daa174cf70627deb5d7f278c822bb *build/vignette.rds c47c848a03f56fb7ba1be6cae876df0b *inst/NEWS.md afba648f16eb111981a10145a591eaec *inst/doc/Ecosystem.R 565dd59f5084851bcaac76dd9fc4a2d2 *inst/doc/Ecosystem.Rmd ce5a617e2038c3a5ddbce09d98145a68 *inst/doc/Ecosystem.html 314cd9f1f965365b29007cfbdf3f1047 *inst/doc/Overview.R f59bfc5701976a8a4793840eb31ab3bb *inst/doc/Overview.Rmd e1d08b8a18c5f8881a44ac209bc3ba04 *inst/doc/Overview.html 4231d3fafc3bfe2cdcb5519873750e1f *inst/flags/ar.png 4c4f4bb44108764ba4ef0724c0d61c2b *inst/flags/ca.png aef2df92c4907db9ad283873760252e5 *inst/flags/es.png 7efb3db3ba3f3f472069639f9ea96fa8 *inst/flags/fr.png f9d92da7bee019cad446d79239b93de9 *inst/flags/gb.png 635abf946d83e954fc7e8cd65e671b2e *inst/flags/nz.png 52a8ba5d972665afbeeb49b433b5a8c1 *man/expose_layout.Rd da9ca2d6c0456e4405542ecfd9c7812f *man/geom_custom.Rd ec241c4a9be3b51f3bc68182b9a04906 *man/ggarrange.Rd 9c1a16716e22b036e5532dfbbe6f5ac0 *man/gtable_frame.Rd 07e4bd0e7ca96965f9df1b03a3669434 *man/set_panel_size.Rd cd90f35539ad142780eb09d549456e09 *man/symmetric_range.Rd ee54f390e10268633af94db95f388042 *man/tag_facet.Rd f296161f96955d4f5c0ce7426bf44803 *man/tag_facet_outside.Rd 3d0af9d58b6f99fad0dad0569e2bbbe7 *man/theme_article.Rd 4df1233e0d9c3304aea12e2764f519b1 *man/theme_presentation.Rd f560b17924ae4d4120f8e8cc436a409b *tools/README/customgrob-1.png 79e3e43fa427630ae8d16f626f478140 *tools/README/custompics-1.png 1b86845ab7f6ea53df90d8299dce1261 *tools/README/frame-1.png efcbf274735e880bc9322ffeea99a51a *tools/README/ggarrange-1.png fd2e757897dd2c3a23a1d3d074d187cf *tools/README/ggarrangelabels-1.png a2b24e453c68314e5bef08ff47584103 *tools/README/ggarrangelayout-1.png 3e79eeeaf090823dded2224fb98e0856 *tools/README/layout-1.png 22bde57af89a72ef868b6c43365d04d7 *tools/README/panel-1.png 565dd59f5084851bcaac76dd9fc4a2d2 *vignettes/Ecosystem.Rmd f59bfc5701976a8a4793840eb31ab3bb *vignettes/Overview.Rmd 4231d3fafc3bfe2cdcb5519873750e1f *vignettes/ar.png 4c4f4bb44108764ba4ef0724c0d61c2b *vignettes/ca.png 02dd3307b895eb766815ebc04f96f12b *vignettes/ecosystem.png aef2df92c4907db9ad283873760252e5 *vignettes/es.png 7efb3db3ba3f3f472069639f9ea96fa8 *vignettes/fr.png f9d92da7bee019cad446d79239b93de9 *vignettes/gb.png 635abf946d83e954fc7e8cd65e671b2e *vignettes/nz.png egg/build/0000755000176200001440000000000013512266054012117 5ustar liggesusersegg/build/vignette.rds0000644000176200001440000000040513512266054014455 0ustar liggesusersun0M MU)ciFJujX1N[= 2.3), ggplot2 Imports: gtable, grid, grDevices, utils Suggests: knitr, png RoxygenNote: 6.1.1 NeedsCompilation: no Packaged: 2019-07-13 05:29:16 UTC; baptiste Author: Baptiste Auguie [aut, cre] Maintainer: Baptiste Auguie Repository: CRAN Date/Publication: 2019-07-13 06:00:27 UTC egg/man/0000755000176200001440000000000013512266054011573 5ustar liggesusersegg/man/geom_custom.Rd0000644000176200001440000000177513367157647014434 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/geom_custom.r \name{geom_custom} \alias{geom_custom} \title{geom_custom} \usage{ geom_custom(mapping = NULL, data = NULL, inherit.aes = TRUE, ...) } \arguments{ \item{mapping}{mapping} \item{data}{data} \item{inherit.aes}{inherit.aes} \item{...}{arguments passed to the geom's draw_group method} } \value{ layer } \description{ Draw user-defined grobs, typically annotations, at specific locations. } \examples{ library(grid) d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3)) gl <- replicate(4, matrix(sample(palette(), 9, TRUE), 3, 3), FALSE) dummy <- data.frame(f=letters[1:4], data = I(gl)) ggplot(d, aes(f,x)) + facet_wrap(~f)+ theme_bw() + geom_point()+ geom_custom(data = dummy, aes(data = data, y = 2), grob_fun = function(x) rasterGrob(x, interpolate = FALSE, width=unit(1,'cm'), height=unit(1,'cm'))) } egg/man/set_panel_size.Rd0000644000176200001440000000143013367160637015074 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/set_panel_size.r \name{set_panel_size} \alias{set_panel_size} \title{set_panel_size} \usage{ set_panel_size(p = NULL, g = ggplot2::ggplotGrob(p), file = NULL, margin = unit(1, "mm"), width = unit(4, "cm"), height = unit(4, "cm")) } \arguments{ \item{p}{ggplot2} \item{g}{gtable} \item{file}{optional output filename} \item{margin}{grid unit} \item{width}{grid unit, requested panel width} \item{height}{grid unit, requested panel height} } \value{ gtable with fixed panel sizes } \description{ Set the panel width/height of a ggplot to a fixed value. } \examples{ p1 <- qplot(mpg, wt, data=mtcars, colour=cyl) p2 <- p1 + facet_wrap(~carb, nrow=1) grid.arrange(grobs=lapply(list(p1,p2), set_panel_size)) } egg/man/tag_facet_outside.Rd0000644000176200001440000000266713463701212015541 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tag_facet.r \name{tag_facet_outside} \alias{tag_facet_outside} \title{tag_facet_outside} \usage{ tag_facet_outside(p, open = c("(", ""), close = c(")", "."), tag_fun_top = function(i) letters[i], tag_fun_right = utils::as.roman, x = c(0, 0), y = c(0.5, 1), hjust = c(0, 0), vjust = c(0.5, 1), fontface = c(2, 2), family = "", draw = TRUE, ...) } \arguments{ \item{p}{ggplot} \item{open}{opening character, default: (} \item{close}{closing character, default: )} \item{tag_fun_top}{labelling function} \item{tag_fun_right}{labelling function} \item{x}{x position within cell} \item{y}{y position within cell} \item{hjust}{hjust} \item{vjust}{vjust} \item{fontface}{fontface} \item{family}{font family} \item{draw}{logical: draw the resulting gtable} \item{...}{further arguments passed to geom_text layer} } \value{ plot with facet strips removed and replaced by in-panel tags } \description{ Adds a dummy text layer to a ggplot to label facets and sets facet strips to blank. This is the typical formatting for some journals that consider facets as subfigures and want to minimise margins around figures. } \examples{ library(ggplot2) d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) tag_facet_outside(p) } egg/man/symmetric_range.Rd0000644000176200001440000000073013512226552015251 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/symmetric_scale.r \name{symmetric_range} \alias{symmetric_range} \title{symmetric_range} \usage{ symmetric_range(range) } \arguments{ \item{range}{range of the data} } \value{ symmetric range } \description{ Function to ensure that a position scale is symmetric about 0 } \examples{ library(ggplot2) ggplot(mpg, aes(cty, hwy)) + geom_point() + scale_x_continuous(limits = symmetric_range) } egg/man/tag_facet.Rd0000644000176200001440000000237613367161114014006 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tag_facet.r \name{tag_facet} \alias{tag_facet} \title{tag_facet} \usage{ tag_facet(p, open = "(", close = ")", tag_pool = letters, x = -Inf, y = Inf, hjust = -0.5, vjust = 1.5, fontface = 2, family = "", ...) } \arguments{ \item{p}{ggplot} \item{open}{opening character, default: (} \item{close}{closing character, default: )} \item{tag_pool}{character vector to pick tags from} \item{x}{x position within panel, default: -Inf} \item{y}{y position within panel, default: Inf} \item{hjust}{hjust} \item{vjust}{vjust} \item{fontface}{fontface} \item{family}{font family} \item{...}{further arguments passed to geom_text layer} } \value{ plot with facet strips removed and replaced by in-panel tags } \description{ Adds a dummy text layer to a ggplot to label facets and sets facet strips to blank. This is the typical formatting for some journals that consider facets as subfigures and want to minimise margins around figures. } \examples{ library(ggplot2) mydf = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(mydf) + geom_point(aes(x = x, y = y)) + facet_wrap( ~ red + blue) tag_facet(p) } egg/man/theme_presentation.Rd0000644000176200001440000000072113510016416015750 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/theme.r \name{theme_presentation} \alias{theme_presentation} \title{Theme with minimalistic (and opinionated) defaults suitable for presentation} \usage{ theme_presentation(base_size = 24, base_family = "") } \arguments{ \item{base_size}{base font size} \item{base_family}{base font family} } \description{ Theme with minimalistic (and opinionated) defaults suitable for presentation } egg/man/theme_article.Rd0000644000176200001440000000161613510016663014670 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/theme.r \name{theme_article} \alias{theme_article} \title{Theme with minimalistic (and opinionated) defaults suitable for publication} \usage{ theme_article(base_size = 11, base_family = "") } \arguments{ \item{base_size}{base font size} \item{base_family}{base font family} } \description{ Theme with minimalistic (and opinionated) defaults suitable for publication } \examples{ library(ggplot2) d = data.frame( x = 1:90, y = rnorm(90), red = rep(letters[1:3], 30), blue = c(rep(1, 30), rep(2, 30), rep(3, 30))) p <- ggplot(d) + geom_point(aes(x = x, y = y)) + facet_grid(red ~ blue) tag_facet(p + theme_article()) p + theme_presentation() # example of use with cairo device # ggsave("fig_talk.pdf", p + theme_presentation("Source Sans Pro"), # width=14, height=7, device = cairo_pdf, bg='transparent') } egg/man/ggarrange.Rd0000644000176200001440000000323713367160637014034 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gtable_frame.r \name{ggarrange} \alias{ggarrange} \title{ggarrange} \usage{ ggarrange(..., plots = list(...), nrow = NULL, ncol = NULL, widths = NULL, heights = NULL, byrow = TRUE, top = NULL, bottom = NULL, left = NULL, right = NULL, padding = unit(0.5, "line"), clip = "on", draw = TRUE, newpage = TRUE, debug = FALSE, labels = NULL, label.args = list(gp = grid::gpar(font = 4, cex = 1.2))) } \arguments{ \item{...}{ggplot objects} \item{plots}{list of ggplots} \item{nrow}{number of rows} \item{ncol}{number of columns} \item{widths}{list of requested widths} \item{heights}{list of requested heights} \item{byrow}{logical, fill by rows} \item{top}{optional string, or grob} \item{bottom}{optional string, or grob} \item{left}{optional string, or grob} \item{right}{optional string, or grob} \item{padding}{unit of length one, margin around annotations} \item{clip}{argument of gtable} \item{draw}{logical: draw or return a grob} \item{newpage}{logical: draw on a new page} \item{debug}{logical, show layout with thin lines} \item{labels}{character labels used for annotation of subfigures} \item{label.args}{label list of parameters for the formatting of labels} } \value{ gtable of aligned plots } \description{ Arrange multiple ggplot objects on a page, aligning the plot panels. } \examples{ p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap( ~ cyl, ncol=2, scales = 'free') + guides(colour='none') + theme() ggarrange(p1, p2, widths = c(2,1), labels = c('a', 'b')) } egg/man/expose_layout.Rd0000644000176200001440000000151513367157647015003 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/expose_layout.r \name{expose_layout} \alias{expose_layout} \title{expose_layout} \usage{ expose_layout(p, draw = TRUE, newpage = TRUE) } \arguments{ \item{p}{ggplot} \item{draw}{logical, draw the gtable} \item{newpage}{logical} } \value{ gtable } \description{ Schematic view of a ggplot object's layout. } \examples{ p1 <- qplot(mpg, wt, data=mtcars, colour=cyl) p2 <- qplot(mpg, data = mtcars) + ggtitle('title') p3 <- qplot(mpg, data = mtcars, geom = 'dotplot') p4 <- p1 + facet_wrap(~carb, nrow=1) + theme(legend.position='none') + ggtitle('facetted plot') pl <- lapply(list(p1,p2, p3, p4), expose_layout, FALSE, FALSE) grid.arrange(grobs=pl, widths=c(1.2,1,1), layout_matrix = rbind(c(1, 2, 3), c(4, 4, 4))) } egg/man/gtable_frame.Rd0000644000176200001440000000243013367157647014510 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gtable_frame.r \name{gtable_frame} \alias{gtable_frame} \title{gtable_frame} \usage{ gtable_frame(g, width = unit(1, "null"), height = unit(1, "null"), debug = FALSE) } \arguments{ \item{g}{gtable} \item{width}{requested width} \item{height}{requested height} \item{debug}{logical draw gtable cells} } \value{ 3x3 gtable wrapping the plot } \description{ Reformat the gtable associated with a ggplot object into a 3x3 gtable where the central cell corresponds to the plot panel(s). } \examples{ library(grid) library(gridExtra) p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap( ~ cyl, ncol=2, scales = 'free') + guides(colour='none') + theme() p3 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_grid(. ~ cyl, scales = 'free') g1 <- ggplotGrob(p1); g2 <- ggplotGrob(p2); g3 <- ggplotGrob(p3); fg1 <- gtable_frame(g1) fg2 <- gtable_frame(g2) fg12 <- gtable_frame(gtable_rbind(fg1,fg2), width=unit(2,'null'), height=unit(1,'null')) fg3 <- gtable_frame(g3, width=unit(1,'null'), height=unit(1,'null')) grid.newpage() combined <- gtable_cbind(fg12, fg3) grid.draw(combined) } egg/tools/0000755000176200001440000000000013512266054012160 5ustar liggesusersegg/tools/README/0000755000176200001440000000000013367162121013113 5ustar liggesusersegg/tools/README/ggarrangelayout-1.png0000644000176200001440000001756413367162116017173 0ustar liggesusersPNG  IHDRz4 iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o"IDATxٱN%gFQ~D$wq_b:zGH5~ @_ю @P@ Д @u @M @P7@ <[x_w @7 'Y?H  0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ uO  @t: @`]> 0+ @g @ <{ @׏?S~ @A #@8& @) @ #@8& @) @ #@8& @) @v'׿IENDB`egg/tools/README/customgrob-1.png0000644000176200001440000007463513311301707016154 0ustar liggesusersPNG  IHDRz4 iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o@IDATx %U}O*y%&Yb_iBP#DB hAT * 3꫞]]]U޺[Y;:Wszb2  H@$ ,j)$  H@@J@!H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@ڀ$  H@@63 H@$ 6  H@$*hL$  H@ H@$  J@*n3$  H@Pj$  H@P$  H@VuW^y_"Ò%KJK@ [ hFM@{Έ5t7=5E$  H>h}vƔ$  H@A@ZQ$  H@PggL H@$ 5E$  H>h}vƔ$  H@A@ZQ$ x}oH@3wyg^^TziC@@ }6qk C$nO$*rm菀?~CkIo=-? n ";}A~h ZaҥK.IxMLL m-~e]~_/]tE{1CRr%TDxS9C w mC'a<1KHk pQGSO=5j]zנ0= nW"m[nd$0 W̌_|D+#ۑJ߂3йZ%KJOJ:ͭڳ16I=[wԴ8U"0kT汄@'{D!*y.Q hoc^Ctyx !p4 H@$ . (@i$  H@! GS$  H@蒀KP& H@$0#ovLe@'{t\@'{t7^3?6om~l#5/u0$K= O#-(:3J`Qpf)I ʒM!w3/7K#e(gU!MIbNf~>A{/{kUc=>pG2Dy" FަXjo7>}L{O{kEs=?GUzUx{;FZ b92k["x!$ O|>͹f JYfƲDv+Fa@iZm.?m.A2ԞA؟VN+a/9[mUz/5s= 75s/p1 J[Hl{JF# ЫqP$oor#~v |8Quz|qƃVͫQVͧף[5q>tꩧ"bx)xGdM??O%7#?Oy{~WY 209 C=ʂ<D]&A=/6 xEf_tƠϣG3LۣȂ6;8=M{+fjo Z)Qec.b0 ۙ߈!uv OxLp8$9xn)?^[@0 3޴6M{#VhU8!"ۡdb߈NnDk&kFx5xGqX+ f[Exf3gK{MoF[W}/Mڻ]12TxzҡNIdð3 ;qkBcGO/uE0 ݾϿamZ==g{[$_i[??Ԁ-"I\1GruMAਖ਼F"ZJD#,B|0b}>R沠۾ufuf[gRlo:_gd 'D`>⊏wzq9lA*Z!>;7ʿ~H=J84WW뭷^S~L{뾆Y_{ˤ=[ZM>T_.6 ":U\y3Eu3?muek#Z(#B ;sa1~MjozgchoDk{V3:f{RoSp 'a]v`x=o|cgqOlof~F>-*79ʓB-"4d%a^b{glꫯ;s˿ˢf6޺㨽uǩY['BSǵ8u:k\w=~K_JN?9[n mY;U@[~&(ũ*VU|7<ȼ·a|[;.0/~?m5UުzT{&U[+tm 'x4۲g?K7k>~3j{:آf6{pXjosS 8Dt.Y!ҟ&@tH{]hSwqGt7O;{G`cЁN X= h[4Q7 7 ^d y<Y荂. 7 iȃ6Mw]8b3zaeanne$t<A{kܿO<1w{]wlޤhog?i |WUguVxK_: qOGZKHxzyaveP#BI'g)蠃 rHifn4!@2t" :-k!SVtx: KIΙQ8 Zh~\,?as(^P0j6n?ML۴7JKCOa xClߚk૽:9yN%y9Z?׿>E)})}tIAoP]x@Ggt<|ɩ #BcM*oROM'8 vNⓤ1И kpp.O x !M-;  72pƷq~ы^~^ܘ^،xlTioܷ?M(޿Gr/,4B8a=ꨣO.qe!n:JSƃn;yԵ7۷;ؾioS/`ͦ3Eg<#nPĩpi}XžQ|:SYm: G+Bt܈x_ =]vMu){Pfhf=ݤY.Lh2ƈ"tB3,DhKƲkoZ}p+ δGzlߦv]ioS$)_a)w|Fb:(o wF7g`8DI eCtz(|O;ϰf [n?AUt<ϝ-{kUxte\_egf""auDLQ@P!e+Q'ª(Q؇`DTQF3=6hCZ Mи1/(`SL_ `9{>56_Mjo{m GM{;M{^yG';LJ'{x,X}'?Iک?Sb-¦n:+KDG!B, ^DF< ѳIg_K09C> =0_`}0:IJs22_{m.A2ԞKơ?m-D/}Ki}O?=.3H?G }K/td%LcFF!FZ4މC4^IA}(| m)b5_ cmES ~27N!eG >I4KKx v[!^;CɃv a=EMJ^<<<]ko[& iϬZ\{$Bگٟ6ӟFMi;)MoyE@kǰ+_ʸYkQeΆtrY!x0?BA/Ec᮶V=$ zA[moa7*ċ W|/ڍ1`OY'3tDitHbf7ma}m-u&kN>az4mXS۷vӯV(>pGvaV8F@|FF8)c9fnpIyDvtjnHnDPuE(7;5@KEBNW_}uzYw|f\=e2v.ht{?.{NaNdzzM ,ًڢhZT=gX3Bho\> Q_,  kꊺF,VȀ@c[ƽ1 -EAS6S7Et}gcp>6ϻFhKx ">c~/}t>޺4uN+3L=y{K⬳J`4߂Kj{’%KR41FZYEp 0Sâ׽f:O|2Gg&0ֿHO~{zџ:MVppX 0> dUm6U^PDJת*AdofHSxpz>6ΆngC|.joo.H޺`wX+]yzz'= ۅW;)^5C=e"Ne\RFgԼ,‰a|v8GDM~Sa{?s"R_tiɕt+ aUn}l¥DDsX@}!`Vff):}צգXdN0})P80Ik}0o-O 7'2KX'L|}v@lOްI>y~+n;7dvh"1??}zpV 7/a3}|?) F"Bebce;7e9YLY ܩE'!L'K^{ja>x碿h!lQw&>L'sfw!L6NlQX u ䷾Va2zf!.x80Q'm6?m @ǨE]Iiް۷lN{_'{é0>+었eK~Q2N+F'ذFX7,\~IgErp]r:pxRdׅ_/jFjo!N/ `WQ@ V9!_F)\x2MSyˎGzyHа謯xHNmwQLcâ#6z _ȉYXGMgF^{Zc[C)T|_rw>nDHQki3~NqG{r ˟.O^$JDD2)LleO^t3eab] d1/|âe#>A@rS_6?|'G-1޺nߺ̴)6|o=*^g7EBsq_ U LD 5 vHݦe_M=Ook(S2{rX|ϲχD(~'6< |_F\wfrw!Y8ݧM([7l;5Τ)F}:ƨo0i"g66Cc>ڷG=KV -îӅyJ;o6N^KzcRx2Otd*V;2 _n ?L>#*Zz?99A{M5;sػ_~p>p)F/FpypN. CgS'ǣ(~>D5=y"];/*/7i"\<돿ɋaG>|OHn$=UW[5mMO{7E@Z^> F [%^~ ?7ɬ|MbtWq5ڱ$ p@Op }8 ~;@pD?7z nee E)_N"Fz#D(渙Opm/K(せn|~&-2U|,ZďX>mPVmo̒Xھbߞ|KV6> iNalߢCgXLOzjzxK[׼&R~DLdblV8 4ڈ@2l>6ȓZ*>ir 6Ia|IZ0E` 0 E=7N&{ߪT[koF{5ؾt:N}1]F_oں#eE|3<_w 3dꈐkh2Oyl:E8]tj_XCӅ Z]!ӋFJ#Q!%u|"/Y>cǜ75^[>v7V7_Woy,۠퍺[X&-޺guϪL bO:йURWxtr hI%6 H`ȏLw*G|=x.8d?E'2Ob|Eqtݼ<ݤskoյCfݲ}Ҙoe ]ce@*8uD͢PD"#BQB5eA"^ܱnq)޲{::3 3)3n::3ʞ1'2̈́ );Q"D&"*;A-Yb@guB^%VG(RUq9^'nhoՔj>ުio|z=Uު{X+ LeNJC#nADgC"f!]$"D':ȦPqaUcEʦuʣ_{#NyeSf-Kdȵ̦hoedfko3,Eb6I~+0Žt FpÂq~+(}UU8T=߭$>c9ȇN.C:4NU!wۂ`\Q7Q{[}fl*la^-ܒg4~Et+@w>({?Iv+>I3Ug2¾x%o:d,nt;xٱmjoy*s᫽Mq:Ǹ =8H(jo] 7M_5|s^{moy[۠Ї*0;!e SWL7SȊPT}3| b7uԶ _l"|!槽ioY޲4m^׆-UXh?m?zn o}8қ?=|; gZ|t38#CM8å^vm4Y&[u*mFݸ:!GN*Ǹi;CvmG?Q*_]uFa֩㔷P[+ۮJXYzU{[e].®=[%=VeSU4g><Ѿio cUѾџmf[BP>:蠰ۦ/TXx㍳ k~pgN/QW,l1:qI :M&ϘG~*̧쪀5NP#j(밗<1Ĺl2{';u鼲ul&Y'n)}/gO{Xeu~uKbupuOg 7pC8 _[oKw#esw@'1o=nky7JQYt,++G<^&ueLȟ6wK:FuC7ew7inlZY{˒ tSu&ՍM2򗿜ؾ5Df9nueޘHcꖻ.5?IDAT|-SP< 2կ~5iԧ>ՓWLSIvh$9UW]5uMTHU97zǨ#/;UF1 [Pإu~lL{˲}{?zë^.·X#9núk8,]4~~!pS'02íJ3 S.˗k*;VUnVNJ{+gSVMM{Q8[~ӱ* h8q_FQ(ݬ2\\:#/J1+:is}X\c+eޡl7c}Zn=<ˎWA{3uL{([@fުpt-N|Mٓ6r![s@{3LOdy !n!fT7넇z(E u!h\aGZ\CsnÌB1mdb:﫲xTe9ؾO2[lkjo|AaK:/,SQ~{+vnCFEhEqh;A=?'4`uƳ8d&sre(-$\g:žQ7sUũj䴷(PW1`,{=7W<.\Ъ5qٴ'.[,%/ REu5Ă[jzalߴvqhߴu[g(ࠣ(Ću+ fC!HXwE3V,x}Oפ:2YH4$;༇8E‚)K5 -#N=R'u]{#\nүp|:~#-â}?L$H . $9Hf(7ړO~ou~~,3@n׿ԤsE0߄??}2QoO3\ P?J ) @Ue<~̗dȲP%>qYhFGD4MD\8iF!؍%}#NNL?sPĪze[|Y˶j{+x%Sˮ&x{<\k=aUW{d֎?>y晉}x3L"zsEӾ {s2lk^9 }l[L'GQ?ݷ?"Pӱ0Us5 ˩a5aoi6I "t+B*!ݩ<"1ϟ[MPu3_J6->6|a2y(Ȇɟ ݜx+Bx^GC 9} u_+.L _0yL°ݗGV,+|amEIsed4YL&[wRd9=Y𦝖,Y?,Nb6U'oۦ6p(7M9:cB( w&o1 )i:"ќS7 n'ҩ2 K:u+7]VnxjɻETUİܣsV|l0ŷDl|w+y&otVnX)Nލꏟ>G{FQ};}&Yd"Yx`WY%$x0YOa#,k'˷di7To˶oSa6ަ82r"@"EaRW#~ټHHb尉XMC9ii~v|R?_' &ǺoCR~s-Nw+K`WG=&Wxababw&'/}a'_ Ixaa+⫇MLk! }SMe"N~,QK͒dyam2rM-]1?w{amjmۂRa&:LD~)#_?MoכFz 6H]RNe hPu@KA{zYXt aoJߎxᇓQBaq6oi7F;ް6۷<-CgyZ'&dy”7ŝ+H{K;0B:OO#٦ʹݕm$ϊLҀ#3tLE#{Cqc`&Luh"@fNwH>tppJ՗' ^l^9Yt~,'' ?<ߝ}?m?-ʰ"Lr3oKP>^nCf A >}e6~Σ\/Q>> /BvT/PD,seSaW2SAڴ^s"EyCˆh/;ީ5{I{[uُRDHlXXIg1vI>:?eS;wbe=Oo[o]B{f7m/3|^I`s=p/^|Wv~۷ZHmoaAMoݐfSZPy+$KQG#X'7& b'Af8ExCɃƸ,57 fU$cP<= &-8N~:km6çL|mWK#ކߧ{>k `l{ 7xce>ӊwDCr̩-giCڛ-bN:;lP-ڂiSg%@*4lT^"ႰÃY -X#>0\ϧ[ݹNQvj>-zhydv!yeMFИp.T7kyӡ4{ݦ|[7o[MyBWy'4q/|s+O!lѤu,ݴoc/ý7 O{j۷ؾO/}1!Od^PDk@G/1,1.kd _gӢG"YM' n ;F,Ywf#o˗wl6{}]w޲}!j:â_ NQ!PXBNdž $~gN%A:bB q㹜XC%F fE(y1%ITe)?9 (M9{p oHn7|1<;N3 Ѓυ Sr[v]l8iߴ>gi {[ph+1 -vm"< EǀH͒;vQ>O< 6Yb|15K\x~u,OBÐ>eHc^YPFK0 F1 A{lo֓6CP{f_ RFǐ!"!pd%bu#׮'N刢ym60F|R~bD>"u|[$Z{⫽5kg1uM{zm5!#!B^A󘇄Gn`(A@Z(kgsbgY@#P˩EͭioSsa5G`&e۷Mm 8t0|v:k<P x y &E MN+B9x"ru)̋Yoe]OUmʙjol 1m¸ۂ*3 "r<'  U3C8C!iGa4ADvPEXfl "x=A{L`og[9SM/GhͷKڷ/@77EPF|HCqWEF@ěT݊Px`@V;|9j"ufufTuVEg1m.^,${[$geI%âHǗ_/3v|ci2Pa w &@$"˼ksm@w>@]7,hoed߆q#j˂Gmߪ۷noSBl+{TD 3vr5>iWQ9bZG$픙ue"kG|F 1@S<.e҆[5Մ1=yO8M7^W4Z[o tPԼE/v{ oEh}[?k?6{HwUvwuW!*J"œC㧖k/!7$BcֳOoۼEXSx> Gz0E|"YʮO1TyH{-F}q7l[u>OLm oR xӟ>\a]w {ڷdo }T{ThFirDd~X8E&x!>c䋰%pP~wk4<2qkId;%-KHddߖ`ox>6^Vt۫^Vba OySR;ڷdooS#zٟjoپ-?Yx23Byt~GQZv/h7Ff*2K^sc&"Р3MyWU>x0*{Z?asSQXhVPGP*V|B7nب Ђfxy1}b"M:G q##|,}4Dqq!]q5&N<) 5wyavR`I6!Q7z>ޞ.lּa 3+ho[g{K.X}E{}T{>'1$S;x ovr$6&8쎑2|bh@'XaSpDǀ |l f!WxV;75e1I}ꩧsѢ ` g:W]=B #Hm{I׾+HG?eZ&| _i?%G}tc=lz4F۷)`-oo=Vfo Вd7^6D(˲eΉٛD4Ԉ&T 2)d#o S܋435™@J1dJl1D8ZbO{ofmK^7yA ߾!O9 {kRϰ[67۷ޢ3XQ7߂`oD׿aɒ%cX}̟GA!ub/sx fpo+a}͟66߂/*VD}[1CK{b[1~͌K`L_s5G8O:x饗^-CE>?0Y'/T1gH| op 'N:)DS-muUުzT{&s9SGGP?¶nz>pO)#Ghe^(bj!f&e\gtOΛoypmp5ufufu Bj߶n;nq7hEs^̕[cG峯( 6X4,Q>nwřk/G^]ϐrg?<:A{Ljoq޺~-~bo-Yk6} ! ~R b*y"  j!!L.F|rsoWrK*Zs:Ƨm۷O{덗[ogg퍗uO}60r!a 7L>Gm>LQIb.ujo䴷j>ު)@ѼQu^#An>i"7fi H"' BQg6N'ˀd(RGt\ G{kҺ榭پ͵ho[s57Nl`{oxr6hш8B5HQDi\H,U4.ݸn\8F|.7 :p0B^\8̧7:0wuWUy=M1CM{kҦr-Ax`>o=GDc6 "s'+f,|l~`pݬu<QE[hciomYC{{CѪ\#:Q|وm("׀X#ɒ Shnu~G(kp?B3>ø #|Z5C@{ڱ\7M{LR,Aho>#s!EDd|1.)X<H"v8x@ei q7@ǭ}hl߆>}_duB7=-KxAXxr“pT(2k7>kuʩաf7YlR4^nI y y(8yC< aarGB^"$Yhģ،uS+7fѣu0 ho 몱(bl" ׃& h E,n"CQc_mx.P{hoW4G H@$ L@kk$  H@@@:R$  ,d Ѕ\^$  H@ yn$  H`! [J@{땘C@{뇞q{%&Oǻ{$  H@ 8_%  H@P֡f H@$ Q$  HhjƑ$  H@M@Z%  H@P֡f H@$ Q$  HhjƑ$  H@M@Z%  H@P֡f H@$ Q$  HhjƑ$  H@M@Z%  H@P֡f H@&#c=6Mo g}S79 H@E@:\ai$ J# sLXwueb% B`b2 ZL H@CK/}ip -$0(z@Et$  $+]vY8£>Z3%I@  Ѩ'K) 1.a7KXx_& H  H@C@/xAXtiԧ>5%Y. H@$#qS$  HY f$  H@@4M H@$ f (@k$  H@9$  H@@6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@$ h$  H@P6%  H@r9 nJ@$  4K@,_S$  H@P怸) H@$,h|M]$  H G@$  H@@5u H@ud0Yp2Ѐ @_N  @+ @  @" @b @|; @@h@L @z'@ I __ @1  @ @ 4 & @W@~} @D@$@ Яw @Ѐ @_N  @+ @  @" @b @|; @@h@L @z'@ I __ @1  @ @ 4 & @W@~} @D@$@ Яw @Ѐ @_N  @+ @  @" @b @|VsiIENDB`egg/tools/README/ggarrangelabels-1.png0000644000176200001440000014661013367162120017106 0ustar liggesusersPNG  IHDRz4 iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o@IDATx]EӮL$s0~$$ (|&') AH9I.܆*efz:T37SS]"|HW^2eЅ (**bcc)""‡#r׌#jբ͛7{GC I3$ʓ'uؑ>4繀`D LM0A '>>>!F`ڹsKڵ])<<իG AebF z "EH<@ydF 0Q[~%=0?!StԨQrgf͚yݻןϼ0#`t]woMŊB QE ۷oWEeFo>1c̙S>8n k@~`FP#G믿ٳӹsĉt){0#L>|8%&&믿N HP7F'ZZ5ݻw,Ι3k> vHx`ׯ~J.MK`hF-Wl6uI;qℽɓ'~ܹe0?#xHsdd$=r_}#ŋ)_| 0@"k.uyv^Tpa{@+T`/fCi˖-4uTzפA5=pڵ4sL1b-ZTU-#0Ѕ ҟ);(~΄e :1#0m;>dbeƍrRJ2؈ʗ//O{< t!6mK ֶk׎7nL0ُ:gT"1SdEuFmڴю%LxpaPh` nɒ%MhAju ᗠm̖-լYӡX:~Cu86!ŋqЪU+}r7n.4`*Ξ=[M;<4͛'ŕ"F`4(K۷mҊ+^ aowg (x#3ǎ\|Y %KqҥKRxVUYfuG#[7|S6hР4'NevD {'0sǎ+WR*Uc'7 ,o޼rX,;^bFC+7#זg0#0_"K~yY)F`F`@F`FKXL1#0#זg0#0_"_^f`F`Eྲྀ<3F`F`@0S#0#/,1#0#ꗗbF`F x`4x-ό`3g-\xW^߹s'?#͛7[hԨQtqyaBພ<F`2P>7<|2UV;&!9P;Z,51#wڵbcc|u҅Ν;'_ڻw0@#h_c!#0ꫯ~ F.]nܸA{9q,(99&NH=.TTh<ׯ_OB)d՝믿N:#g.f 0/bfF ͛7m۶Im_%=֡xBTv%JSP!4o`|,CSfA8R&\0k@"1#rAcǎ[J{Mtu;GZZx1aIe}wi\UYڵ(OJJ"8LU]2@ V)#0>Cݻw%3gHO2eP,YN׮]Cј1c)NӧO-[Ћ/(͛N>Mt`9͛?Ql 護ޢݻw`ꫯRΜ9Q`@1ˌ#K/$5חPxO4I:&aO?.]JyeCMBǎ+W.biʔ)ԢE YI&.IgPRߵkW=zCg(xK>xc`Xcs`F`LB(=!2К&2S)RWҥ ~3cIIIm6]u 3#B*U}qL͛7݄bC߿#<|`F`FlX5Q`F`F#,zO2#0# f#1#0#xDPIF`F``lD?F`G`#`D0o<:,eb&F`BŋK,1Kpѣi~jٲ%ZmP:q@Cj\F`hРAT`AF9G~VXA9s&MȘ7> ~?F`5k(Pnw\ԩCNEQ֭QFT9/2#:t ’(#`O}рhƍҥK` _"f`F  5`~h„ -[v]$''ӹs[xx8իWO~hBW`h0_]#0D`޽eС<'FgΜ{Qb|@"EzTZ5z7|2Vuh]1`FkT"Mpȑ={v:t*-#`:ZӉ'x4|ij@! xјeF`F-JiӦ ʕ"##iΜ9ϸj<#0!N:Qʕ+7o^+ 1 > .30#0l@Ytz,:G#0#0>F} 0w0#7oޤ0U{/ED_NvrB )BdQϟ_H@ڻ+M.`F``FsOǎNLu3GTlY)%~ᇴ{n*W}4e뮻x" gF`Bd灣L.]())y,YzP~ZjFsΥo P 2#sv8jң@|M))) ^iȄkפʂ˱psec?1md'/Y4:H˫F݆έ[$nh}\J D]-)$(}[&ʕ+#hٲeS֬YӴ _˥zdBsĹT3gNx:[hH UQ ͩ:NHIa liǾp<&qFIMUWpQjK)ɔ5<7hE O/t9wH`.Yx%K/U@G/_/9rz(~ +BX\vMQQQ>xH[ڪ{ƂBB\;\ mZBU ݶm.6FE}!CwI};wnOvG|*e=%KO?4u^ַo_={<^xzip RF ێwŎ|yhvOʝd?8suLAqO+괶7 $sM[^` 9Xӌ Y5rZ˗Oӣ] AK/ylYIF` @ OxӏOIrQ™ӔEhn)MH>A 2ӝA`K~5aZ.@qFV00X8.\ t+V5kF6m" <ܕ2|*TH8G;CrV`yզ}3M]Wv3h`>|!MjCwڅT 5NFm#hå-t+9>S^-R,i?jl{e;juz{TvmR/y:\bJ|r(_d^B3YĄ YtZ (sEXnAM_7g_4SM|DW /;uK +an&5XFNO[`֜4|MV݃o K86w^VJOV9sj֬)\} ,Ź7M]TcQ /SV.KYb?С?z%_7n,AǍGիWҴiKį4i9}Y!<,wTN{*+PM觳 |c+vD梓7N; /w 5Z&p/-hh~D|ל4[? /{MRـZ1ۀ؀¶+m@al6F':t '/˶$TB7o\b{#`A1ϧo3(i#لX]),vgCf&|Pow>|L:U_CSm۶֭[ˏj(0StRR)p0r߻]We)x?SeQ5صpJ|X:a?={c׭[WjPgdQU=37(O(QeF=w>6 ׉JvoaP}h/*/}xh*5Me]̢jѯ^jQ1b' iMb[-~ET;V-,"ý"rI w F (]Sfػw48px{9b2~+֠]0@ޒ2lj41ЗLoy+`XL0{0_ f[IP;ͨPZ xxKjF9\[-/wQQZV;qWb)R셷w?)\;|+&ۙ7wk쮮s9ک1suhcH݆py86h^(ChB&x(F/^,*VH 6LC<'NPr of %x?+ϡb:x_:U:>AFx43"й?v/0<9{YoU\0L!5m3j{ܹsrF6 !p3VaԵnCZ*BL4X0cv9Fg~x,Wpr8Tu`h75j$Ȍ3F0!<GdVUw $#1KS(a0LgϞkO|=*{{6io>E PVPhFojFWj;!(G ̀SD QLI`9H*T A?8 t;~f*8cDE`+ HVrH ͛6cǤӛZᨺ =C:huzL":AG;G>`9RK9F`)K ˗c5^p!/, M#*_BZ͝M pb}R7Y'#>+zIy' ;S!}86EI"{VW[džƏTjk-ѧ/HfS۴W#hٲe2{L%΀I$ܹSBJO|@OS6wb~R{8T!!^~F)#!әFFrPz|'ԨG'oäеX^=NE_iHED}os…Uwy`P@xх,HaBjs s3O!;e!ܘ.I|T!yVT}B FP}U=oʕ+go۪]'Rj2`Լy4p݇.Cgqʖ-K8(#(…!"^ qͽ ^pMqo{1@%kvh(%~m6mz|qTdx7,n Ґ@V7x>;":z%kӻ<#0@!}G]T ?QVny: h\nЗa0 {n*\[X1iӦ4(W_}PfJDu` T0tOъ+rT]ѸGT}§8Gq>ŸW!p;P>^!㺥k8%A_ww< `UHFl/)Ŕ"DMCe!;O,C`p ڵkx9rD D0`s Zܹse._6m yr+<_ONÅW 鸚\`B<~LN;Gh_/_ޫ&Q-EPdAC҃W^Ҍ ziܸqRn:￷cGQj'B G8E`\7˺(Q؂mT40SSפFE|1|!7;u#2aٳL2gI[:u8Gkּ"Y僀F 0bNlI!UV4[c޽\:6!`\4)P4C}6 xzhkzZ #r|17WF dصk sX ,bYŒiqtF)EhON)bi5b%YhW.p \Y[=wZ7Nx!/FmxxpBc}y xqsXY1Y1œ ߗR/磧ʕ+ӴiUaw{=g;EeVZ ۄ+ꙉOɞ"_AƒB-/F)3CI \o6Mdvj 4' OhF9 voCȸix)}w{Kߌ=!"e刟d~6fռI|bЄj+G{իR&N>fΜ)5:cǎ%KCW=gSd\,S2"]TʔUE[_ݨ!fwTFuBFHU^zxM}'y;-0V}gdF۪V(!/֤I2e}~s̱ۋ o_1`$.sC} )C#y8/^l1#FT|.]жmF%{̎S±>{l Gǎm1;uD5jԐ?XE٦Ipյ;e}c)X1BDb^B測υytk׮H ͓ZvW",+c7}2;<3L;b s|1wF Tx?WuF4,l˾1=v5CY/l.4NBl让6wN"tRj߾=A;>?z(,Yҁ'Ҙ1c>n}YԩS?\Gxoƭ )$#㋅}ʓf(PM7tD.Bnq֔a̦uk(\:'vA Ν;Bhe'd"¸`s 8$Qк/Xf{¬No4D@9;ձ r ˧3;96cio`3_9ŜaJ4>0#`t-%-GݶL9={O~@nyJϝW7j!Vrs˯}3Z}pMWߋ^T'^ a30Z\rɰkprþ"(.^ZRT0%>l zڨ:jLoTmULϾ'VzE^iL@=FH#_N)ypJɑd9%0)Y+OG)"V)Mj֦%HjgF%=B`_,yAR&lԨQ2!CH"k0PE Q/ϡ9BZVuy{)3?c:zӹDV͜y:!팄aBH1će 'b:|`A@vll~6X_in_b)";ӍW8M޼Jяظq#͘1Cv [˵kג{i qݺup_y䑿ڵkKǏK[_~p rF`|riR^) r! =k\4"[t eyTބdm=ˈ>Kիۗ7n,=1(AUODa;MfrRq>}W|2,0KIݷ;^)SxsF`E`r)lzΚ&xCR q?sJe%i$0}GHa»$6Z~>22! >mۖZn-jLAcoS|rߖhgip|oh̝2# H8Ϛ5KPBBEgJ]捗?bYG(A(!|vD zEҡ\/XHXNڄhDj`釃;(OUN/8(oouBiC{j|{34hۛjH|AKvyι;Pz(g:|`?BrrSX{s&,?id[N֫W^uʔ)?[`6^Î ق%3I aGЭa3΋ʍ)NlB;|M,q_ϟ^Ōͳی>SNYF'~nq W%`kOH[%,(߈Pd;=Mhw!OPx}&.s w8}@h>#0~^&*$ B@̀XG6i@\KGՁP5z_V~ԋH[m?JoOHcG&EO"d&g }*3"x /n^?)os% XI[5CgϞ0P4akXQ%-b =Uv;07'T(kXFqqOOoa q}F`2={HAQӦM]r_,/+_D uPxKODa`S}f'׆žl璲~0¼&͛7ˏt֜cc˖-iW|y?رcMU@rʩC 'ؿ?ƃT9gyu+nK Jd-J^O2m@(]51T&Q̱Y10Oiձ= KU;qrn%X.W4pe˖2O>)?:wLKVMBjռB~Ex:0HvăKxc9:wCզM z-Zd !"rmKU OH݉dAS Cf͚QQU!VLCX𦾶OmVLE?h=)ԕJ5ΏǞQj\sF{+h[gmުQP z:#+p>KF_8xm7 R/oOu9~/>\|<=km)mQQ!&=a Jcl25ᡇr;$ώ;ʕDT:x\Ch/|@OK &C(A =@((yçmŧ8]U,Ks[loO:vǓeq+T`CB)aLTFxZOh.n)fAee0tisJߐ3Lc@U>{l9˝|>[RZf-zmh )cF`9B>&C Bz*0la4SO-\.]Jp,r>yi3n!XժUƇ(BA_a”P9}/ӭ*4T4ϓ` G>/UymݺUj"Ij4E[&}&ؚ{ng\%<o^&(xe/|~Qѣ&eʔ'x#M#S!O%KtoF`|2! 2GP,_+f͚ѻu 6p],ASy?9! w\,mSOU&4ud!l8{c}Ȉg2QpB OxV#@cbOwBә7aFڢQ^/x=&,b ͖=S|_O@>fF ݻ7ҼBm(@3|My -g%i@FO?3 ! 0Yvh0`W<6OJܹФ" xKJ ~ŏkԨmS}/O)R4nJK\}&%. #ONߌb AɔsG!dg*]驯kSNQ&M]އ̙3뫊h=UZ4aTO[#̓Ԕ =;PJR2U:U]I5R)M6Q=͋D׾C<7_N47 :!j_ Aċܹs4l0A˻nӳgO3իƗ;,`[J%0C]v*Z'NFY~ʬN5e6zZnmBxZT0`L kdV>idp wGĩDa MN`F E4]C.N:I-ٚDcG 4/&e2؛i( iOr #Frq?lرRFlT_eFp!s̑L ,BN]q5:n&S2$I3ArB I{6ⳲK4Af5=sr%qGy+ʊ !|8yd0uA*WW$ë.jJXPt=~6o6+^@bΌUsѻUʌUQRAu02w#̪6Vm$ +B`?Է=s>$d}arLmpmx#cǎ08rM&ݻB͚5I Ԃڵk,U?7n( ³y԰aC:D'NZjC9TB>?~\&* Ba7g2Sø\F!~79B:n8ꫯesF$XTslHDU8Qf2twpmFxLdEl+Ќ3dP%!.bf CQBOZӫW/)D#v$Lߢ5DׯG=z!L\B&Ms-=rH_+kr<ܛ~ o!Vʔ)C}{:upz-BO>zpi?YJE= :5x@fM9(BM79+*fsK8:ύ0$m ef1"-Yh„ 2x׮]e(>Ǐ' + I B!֭k+3 )~AbvpDS}<2YZAh8_u9vlh&%JG}Dp1v%Wyw|ΝK@Y˪W..}YjӦ)tf}\Pz3!hL4*@W^$pu]Dq"m;;'|xkF{#H@g:܀(^ bb3 |*R%bd԰!TVg67>n AT` t Ç[-UyWT|yjA&]4;y5640D33ww}j3 sis;?M[L4KQ\Q&T ogbB@A݃>(SBJA k~Ro^ @j&ؿx_HL`YykOD$Y@ 65TZ5MHc fJ]dIԶiyQwe fЄbn߆Vfef=:56 f!e?ёbv;#h,2|ܭŸm?l?V'sf|ֻ*b5-h;uȵF omÁ5|B,F,4~Q,/X,Q,%X2GZQ85>FVZeC- .,a N%zݤ[ yp 2;򇫿t5 &h ڤm96h!'NtGҎmbkRGoSp~QpªU[θ>#:Xc"NE+N`̌J+Yr(Bʟ?v Es_'c=&bŊQVf2=Cn60iٲ%a|3 zm۶kh")w{j<_nK*D[h3D ӒBp@jRsfIN=2`,EY(^ذ!_DCD]рvFz6#1B:^ZEKX_iӦCYձz6hTlsƍ~:g͚5t}YbЎS-[A /\BrhԬY3pƽ+p+B(;8E+W&fڽSczfqVi>&h;qmy8G0pC?`{Ȭ+S@FH&(=q׏M|UBV :{W/'xU[*s+ҴAU5ga-݅иMpz#!YPhP"ZaAC+RRY23Ɓm ,3^㛑 239O_ 8*Z/@dBnpPU,\szUN9BicM*U"JK 3W[F('W'Y *턣GeM6ـ3ՅA]aW"zi:Rik=/lHO_/מ1g5Y^¤n to;ޞ½0?  F }|z*M#>/E#).]"A=B "ߦO?-HIdJ, Sa8(I!Rf7NYE&|!2 ,p|BX_>EYl,!,=[NJ~:#Z#;A( KЄ$E:Bk겼'fhq/}sn TN;x0U^Ԙ/,HӖC\r%Әq?荽dI7T.݊U2tvp?`^4iQc:JqFtV !%KB8敐`B_^`XE6KʴeJm޼9l}s0S 2=!DN\컏T +&;h=%pS"}aSmЧU"&T$_B]?ﶧp[8+{<p}zꩠO(pL߿?M>]ڀ"MԩSJ*r^|"m?.RBJ7[@]ސaYֲZ|t TT].ám|J=VvQ3|,_ٲeeAgشim޼Y ,@;uDC?h?h>[hAŋ 0h`V!2DKff-7_O9([DVz`| Eˁ=BtD%=w(JhC %˰黓o+;F˶*S7r B?#d* 6֭[i4{lze*ν{f*2SPYTgwHRxR+)MشIj !ƽ1}E!np0-&\0eK ")"8Lh??h&'h cJN?j+x%.YL7N {b>R,ߢ;+3 ɒ%K=so# ,zV=|(9ѷ 6ASUw1@Y0u7\N YaGeb4nB3NbY:ɤ#QT6{iBi$ӐhiD6?q~ȇ0f͚Ҍ3ԩS}LeBl@C̜]񾻉6BgpD:3tqo4La.KWlAt(,w.2GQ(qJwd, 'gbA஻;wɓ't*P }Ge@wMgΜ_s+c>F4W<$45A;h;$#@=&Rz}LgRDf[BdsY?0CI&TF /B9٘FrF:t(-RBhڴis O/n\΋!\5ݔPH"Rd&^!D3Ԏ1 +Wۮ]wM=q#@>,3&{r2qqq2|Ϟ==NO2F˗b0ڜ1"rJ4h͛W:t XË,=!.]&M$/ƿF{v8.ˢ}@2 8,LS])鶇cCu+5л/@V "M,[Aʽ!}MV݃'@CB=7|}!кuk믿UVR/F-!*!db bŊ԰aCU,Eŋ O^>qp^^VB+RZ1 ⾰$A{$^Vahߖ ?_ н{w1bmۖ^J͚5¨_0L0!@@ H٨Q#%f D2 Ãaz<F`F  (ڷoO}8@7QΈt5y8EɧO4Pa+#;vLfQʕ+ۭ[:8 /_^z~+#0@@[nԥKLc|M1ot.Be cg=ڂݛ~ ^%n ɽe ([D6pա8;h^"^[IQ"໏C9Gڻw/U^In4sLʟ?ٳiɒ%_\ ks G>!ݮ>_ʛ=5ݲѡ&&vwx )bСC2܈,X{j罏ECQH$]ٴ9%XF"݉AXulX{%aJ*O /H#"S~JІT|@av-ZGQ"JLfK)`c= 8 qlZeH<щDfQLdq}GD̈?++<|sF@{Ľ5Bdczn޼cb @j8/c캟k^PZ>.d^;H/lm]QvzFRDTO]p%F_@L؍31 @,bSBMu~o}]bKA7oQ-^wP`@L2OȘKm6ѣڗ_~Iuؑ_.C;uD5jԐ?y2u>QJâSk8L0 ׊`|k@}.wm [.HYxFB pv] 9s洏P>vX m[{rnsnQ|‘K5<p =֊6f%!x>Y?M( a[L#a;k a/nAP=(qF oj1{e^Q+|Fـ;\G"g %%߱!6jQ'$D#NH>='M*HmjPY U<-V;_wF b9r@ q#nGPXqM?EBjʴv6Ŀo}3[qPi&iRvmLwP)]h.I'O~ a-Qh NHY3NͲD[o{Rhی#Xb BP̋a zgDZtz9McRHѹm+w Ѡ!E?1!#Iʼn^zQ*Udy.Brg#j]&"Q"4?<0 wD,0;^[Rb,[gXz7֠R} ?EVRP%3%nO*iʎLfˌ!$ C_ ?_śnݺ2P=۷/_իk,igDg]U#0jT;#ʱUu>b5ښ=mCv^)3:XSrVd+T#5'orٙB5bŜ: _ v7'r?P[&xW_}E;w5fNHztUj>Q-{ƨc|o m:3ovBrFC@ugTv@aۛwxۗx[5b^۱C]*RƈY]B e% x;/#[u_qї (C+S d(%,/qx{K5FQ#ycz"ҥK7o^W)kЁW LbL>K 9#(MK.9\7th`\Hũ9Mũ,!A8QEC2#4/3+lj|%mL)BK^*̕p"vQBÑh!E4"kJ-W`|T7~њ5khܸqdfF+X .h؄bD^84o}>"*V"e4q#`m*N,cSS"'H-[իWӓO>):wLK68*7cF|X5S1A»q©-,:GTp`,=8AÚ/x0 ,W8yK/#bר?>W`>glNi]nkX5! SݑorXwlGB Ixo'J.c˪~!$q\1*^3 Sl ɪNG/,E }qcd3١#>Жx2%+)$ 뚡1ZHټysnݺAW|y].;BF`LFP2e))~/2MRx6`N5(IWuQ7M&W"C\ X}嗩f͚ &֭ v4x`2~e6<"% M>N@E,Pxu&IܾA(FIR}52zYŋѣn;r/^Ə`F 3`43$9M7'8ι1fe}?V{ʖ%+BpiϞ=Ks̡~є)SPtѢErUVi>VX!ilٲtERi9U_zZG"=uT[8F0g@*#(#L mc !!v61Az<#`,Z2@ i[ لVRҞ ֌ia1l"g=UC`رce%OiG{իÇi4sLBzE׷éiǎ Ȉ@7! #c$}++xC'6~3O#S'lw\]eYj#`6I.B dxa*EoH)B*^)67KCRŊ{={ zMԘ m۪]8 nDh*NrM mlڜWtN8QT&^[iC 駟~!X>?; pRdS HىL#  ~4uTԳgOڰa`|0>A \y~Ծؤ9rR˯QX 9oɓev#%|^p\>3e\z #0@@h@w%g͚%!P͝;ԩ 񐌀uDo@b76v1}֡#iSqvQz? '5ҏ`4#0alAAT9`l#}i4Zx 2^o[u}|y!V\{.Es%IF  \@u]wY׸"""(JA$G__];ӓN|yfCuUgΜ:5R:*v ]mΜ92aDJǬp?> ocrTHsxxQK TrB/Wp9P˃_rLx-6y-[On{/aΝ)gh /:btFɿ/Ji$aTv ]ݏxc06!;D(Ǯ}j[$cU `o͵hxڦPyH(3oӦMO<>R#XR.җygp"mn]( :yi//CՌQxܴ4*#⹒&2~^J1]QQ"DijC}/T]m%$X ТE Wj(W-IH$~|P-,%G_E}N()fYp37ׂWՓH _'r} 0._|eo߾RZ5+V3A;Ժ+WؓHzǞc+sqw ^0ď:Edq0)Zw>ٷRx;oʡbŵ9ʠVnxh~ x KU`|7RJ\WZ=){sZ ]>}qƲn:7n  bGM͑~ȓCG;j?-2Z)6u'M7rdrm=|ۑH @%9$װ`tØttߞmYwTNY,Y[RJ ȱ\iwcaBx݌wPdegVh̑QPv$$7wxI@X dL6)UE6XP+!a$3ycvڿjA>ag)Nxfak"(7<6֪xRHd%击6{Kחw̓=ʎnvȭENk?rw)%V!GMRKsKl5zw|>ٿϓPh0=E GrϿ@<%Yci`bSO=e5]0>۶m+'O֟5kNk fc]>gM%dĔ0J~y׸ϭZ̍`?>پ[I=NssU4;*#S1qpTvsHG4@ӱUX' 5I=%G/5h^e*%z}%:̙3GCؽ{wlIZQ~l*gRUR](@!YVdj꘣'r+Ea*2JDu"AU,…}گ&BOI @&~")b稸~0דz0NrR<Ѕoftz-!ʎ7&^5`E6\ -R;< fJpݔ=lB)oqs{Peuwq8G;]DޭKJj~j$'9bx Д`e$@ lUtZ^]Qx&3A0T]*^\_|n_fƒ!Ӓ x}!O$9ŋ/viU+wiZ@b_aÆ1fsԩҫWV\ҡCφj肷 fa J4u:ETS`ߔAHwط1"YԼD*R1gP/%s& "nOI0Ӕa&d)R^zs=1_`tMJ[l6@L;vX(?YJY2J0y=V104V1c0 Ɍ%\JFUL,*O摃XH givCA1)i6lM~Dm6eE>gv*ʸj̪Wn\o# ϥ [: (b4@X< d"bXy8vr/`v>waÆҺuBOtR93^S1B{| xԲe˘ )N蒔v2mQY5#IDvN~ʱ"TsB0Fj殝;#;\U5+ ƓbKmUh8<\dhzLK KEv*/bpR'ЩS'iӦ<OȐ!C2W/#&qFpPr6Pͬjs'Gx?Myn1iܴiTRK;uk%"5bFj.-0 yf'8~)4iNMDԮi?aTiŊ sszCg,F~U)Dja(%5kIvZ 5@e_A׉3%.ɼ^^v^e{ʂnK2./}\2yV`9oƀgo,@'<_ymܸQ~)hc+ S_PL>p"xEL¸Λ_R?0]ׯ/_h< fڴirwxQEߕq]U q"O^~`R5!99)zQw5@ٌԭa~ʖ-*~[ "%ѼcyQʁo% vڥ CL0={Α>+Ϩ@=CY{hL`T}cǎh|z䪫~ c)ľgn޽{͛5kIVH䙞䟟jS[e]yZ8K+ԬuEu[/VqQUKbW<몲<p$J,Arʖ}X)/7 8kV{4]q?(_0TJǵ0dz♄O6୍UDzʕ#.}`ZC{߮ ;S䱪R@#OM/?w۶mDzn`fdL :P;_ S, xGwY dRd^( #n|F*M*Tva0$c-0d$kRcl,'^FEP&`Xɘ9k 0y9 IW÷rʶ#7D($N~QNb]HHH ПzE M& PՈOKCu’ dlq'}CĠ%w"Gy^t`,^ƤE/txXAݻwKʕS1HR,OL^aB8t9+AI* ]̘\ 6H߾}uPXL>Nl9ܯԘP,"_^c (%rb-&<Ʋq۲!($VÛuV |Ɂ3fd׿*>`FenF4p -[|%ږFQiE.]XazóѱcGs:g>s?g?Obw}Y⦎pF + Pt b$D9ПAס1Hqݾ0 qӵkB]VꟷO/kb0i$?6瞓 /PhA[ni ac}V]][t?z>铷GyDGW?q~KC*;C? ~}K-Õ X~,z.ٳuH/j(obyHeyNӡ"ULpi1u3yW E|0e-E<8=sxVJި7fcU-3bƾSMz~ dm<0@5 4tIzDѥDx ^yCzB0ѤMO]weUrʢfJnt-tcµ'[Y t?  'M1L Bl}[ozJ/.\nk=3A*~Fe-xS3mhBo6L{Nu $W\S3$$ Oc?J7~bܙOG1v:L{ܶt3F3Wzc,x= EAe @,n N$@$@$@Fh(!   4'@4#   L#@4Z @ @i-J}HHHH MbHHHH ʹ>$@$@$@$?$ꑀ+X7ԫ$=C[oU<)&ׯ0c5C-ܢrXzӦMriIɒ%u/O?TN>dӟ$͛7ϸU\Af" !eԩSeȐ!z SO=Uԃ>(^ ŒXz &XȊ+g~Z~'}kyg4z@y#d e˖3/l8!l/N==j(>} @F$@>%PlY?~T֮][J>| 8PkB|{sNmp^|zxrwJ=qYfINNajܸ|#;z@4{rgj=J(!BiZj.v6m*H3|7oTPAڴicKmn ߛ W~gnذA[^^:u-[ȯ3} H.]&?I ;Gn_d1cu5bŊ{nٶmT^rF" @RJ!Uߙ'L2ʕ+m|g L; n vV6mիЅUViC$) d+5kH?7SNߙ= 34m'@NYI7ސZ6n(=_~}9scN9II~X%@40:ͪGתUKy2e@U%} l ?v\~ ^*r}'6 h@.`QHHwftFٞhԟHHH<&.x8   v4@$@$@$@$1gq$@$@$@$hf@IHHHc4@=HHHH ݶm "^Xr} F @FH:o< lٲҨQ#j|>u!iA d<bŊIr4ĝ;wOx4O HJ}ϷNpHHHH $ݲe^ZCk֬4?7oåhTHHHH"tt:sL@jذc McՆ$@$@$@$@O 73=gt1&u@~;vÇκt:=&GRJ,'`!2@*@XS)S >cYti!`8'PHHHHI lnf{@z,iOcVEZ[~'^U}2M/$<̂H|I c PX%kb-3/u,/0@B.~{U儲ˆ6 d25@>,rv˗\o>ē^ȑ#G5Z%KSѭPBsAO@+z>~+ }0z]?LH$@>'1>o@VHHHFZ%   dIHHHohX_   9>o@VHHHFZ%   dIHHHohX_   9>o@VHHHFZ%   dIHHHo<[ ϛ7Or-kϟo?O>dR^Z֭[gDZ X    O }I>}qڈ7n >\efW< ^xAlܸQ*VӜq4@-Z    3flR |2giժEB 2tPkW^цg&Me˖uԱpHHHH<|ri֬Eۋ/C7-Z$ӧOS{m۶͛孷ޒ5kք^"k )^    $tÆ R|y&ѣ[nRlY};w.]Z{R{-\rD}]2dUVls1Wr=U)S&UYiWūJ|x!9rċbY dO ŋڐ G<{yGӍ5_*Uկ__Fd;9to~ `* T ~ .lT4Ɣ>f K,LF$@$'(>Ci׮e|% @ZڡC9sCݻwzi0 !j*ٳg4x6JׯR»gnJ    &R;8̦]^t޽xU%VW.{&t0QNXT ƚ]S_F ]N&a%7JAT?5kTZD9EqRHH'%g0xOp    d $@$@$@$@&@4D #xxHHHH h&(#   p$@O $ de~$@$@$@$@h:I    dl̏HHHH PG<rR-'>™>%JC#J*IS૲t1PaR  H[hrH釷zk`Rʗ//{I }ۧJ>*T]vI~~~*5jd>{R)h;wJg֬YSj}*V(;v(}rrrhfe$@YE]YTHHH ТoրHHH Ьjn*K$@$@$@EOhѷk@$@$@$@YEhV57%   '@ۀ5    "@4ʒ @Zm @VUMeIHHH -6` HHHH ͪ榲$@$@$@$Ph}$@$@$@$Ur2o<ɑ-ZH% {nYpaVZYK.UVIfͤjժqn '}O>ҸqcYn7NQ;sʋ/(׷gEI 䥗^^xAԩc ?xb3FZl) Tnf3gҠZltUziϕ+Wʌ3?+VLo-<@P: ?O ˗KN,B_xqXF;C=guXB8 m|"\?i$+?l|ڳj>#RbECJ*%Eŋ@ N$>K;!|C>*TH>(7)Yd(Ҥ}~3j}Qä6>3# 4&Zk6l[fkl o<Æ k#Ǥ[n5[l4XGZS?fXKzSZAZܟir^pC9!nRN$@A#GXD>YցF \zreiC;vݶmٍYzuP{ ⑊޽{uY ]$??Jg52NhT gΝ)7j֬uI>~رHAB$@$8\qvc۵j zZ FժU+t=~($@$@$@$@#ڶm[Yc     C2sLѣս{wW?zhm|b<^#Gԯ͛7߯'ۺ_~r7JʕnݺrײHHHH|H G OtlLh31 F'\СCʕ *һtcL^&.)P?fz̤c@ܦZ/ǀ1&a$@Fz1ǘMOhtE!   /OƀkN$@$@$@$l4@M 8ꈇ'IHHHMh2?    G4@$ @ M6QG$@$@$@$H#$   H6&HHHH uÓ$@$@$@$@&@4D #OtIOI2e\uqM]_OB,%ZX1 \ST)Mm,YRʗ/r}W]2ucDHXt/-k'Bz }~BBI3N,H҅@j"ra5qkxsݒ宯4}` ߿_A< jPڵ+gϋR} ^Flٲf$@$@ XLXsM,M3kcM22Ix> r)HjƫHH8ړ ]$@$@$@$o4@~= P5+L$@$@$@&@ړ ]$@$@$@$o4@~= P5+L$@$@$@&@ړ dJHk V8)|Ydz @h&ΐ9K.]drA͕{M*$@$@$<3@8 ͓iѢ(Q",۷7|#75kZiV^-֭T" 4A۶m͛}yg7hР!  '(D飍JƍÇk| s՟ 6$lܸQ*V8 vxܖ#FhÇx妛n *=σ$@$@$@3fl2&of3gjȑ#oO?-Փ??Az)*Ue˖СCN:5 ;DM''&H}L4DqumqIDŊ)DQIH c xbnذAʗ/oA6 P)[>{N.BZ|sΕҥKkOj޽K.eȐ!>˴N8l)SFJ*U*EɠK9sc#Ժuk\c+Ia @rxb c d8 C|P'iԨ+ׯ/F 2@/r9,1cFJjմuϞ=n/+1˱+(Aq*F> HF_>cu9N`H9ODEb8}vڥ.9ieΝީE9s܇  xb‹.t#خ]ٵ>a\w}rq90\!XPƁˆу.9Hb˖-1EQK!eHu9`b6xaE bZpuG 4]ʕXhR%Z}1>S-Tc( }`RHHCzKN^si۶L ;S߿u<yi QxhoBQ|*O$@$@%C2sLѣ6wgѣuLΝ;ٳkر_|Q{쮼Jׯj[p#2xbbbb0LgnF& ⡞^zqݺu] @(o(!EOxf&:t(Z2<|a$O('c@<ŗ]vYDu'NSO=5bh'0&jE.5j8ElY5]e`q1{2:i <^ĢH>rRNt> $N.xSMLDl1>MyaN`O6-c0d|BI{~mKEHHH<5@ ɯ-'Oq}sf A$@$@NhPlHᮐ-O>JHK1I0ANIxHHH4@=\TE\qABo &e`HCpVZ\5Sz P_7_A1+XB2*0a޵*Q>񘤒.V+W4ᾆjvO<O0V2qc    Pϑ'>@5kWҥOZ4lPjS0PE^uN:i=Ur5v]ab%-cxǚ'ӓ $ 4I&ɭ*7ooB q; #Gᘐ&= /xZHӟ`X?1{E((,_j=8EK!  (z4@ Mc# baI7E)˖-Ft:^`AAʆ "XB`AsHHH34@=C܂f̘!IE|7'!zԩ8ˋX2eJX) >.\~ IHH ""ҝd۶mKW(\'$&&_U;ZW1 @Bh&.[O8)YdJ"''P~2e"XՋNZ:V'IHH Kķ(+5N[,yEJ20HC ;t' ?k띺Q}ի^j3ҊH0fi9XqZA*bec=\mh +rUWrpYu?4S$0Ι=ڵk˘1cK/Ǎg^d:ѭ[75k=: ]X!Ĕnx%0囲~*>өߞ8lv'yuo $@~/ =HcoTcרQ#ܼI&nrL4Qԯ__0tnб?14H\2c-裏jo`$oa$!UJ>};.EGyD~mؼ{al%R͛7'xB˄P^[֡ʗ/'Z}ƌ~co6F^{51b]VgyA:-ӑ @:Q_e*"1I'z:l]wpd ax;EcǎaK駵 o¦y7Zs֭:h<<^Sl 袋 tCHM>݊[JɭQ6IA.+qW6mTǠΝ;Sn`B9~k֬)>`"v(ڢE +Vzώ;(ڍB$@$8GnܸѸ𫯾jժ%D=Y(z>sA^hb,O f,?08 m}xHrǎ=k֬>;RR,mڴj>PNA*x n$A͝;1UkCg? B$a DIH_^1x/x>쳘M0•_hl^蠫:.HnXx]ꆡXaFx2?H;A;KO?qH&!Np+Q#$@$hmѰX0kKA]pwitZzuL*\'CE퉺-_\͸p ׍@_'6D9N]`tSٙ~Ϗ;ܫ'Q?  =Np] /],]տ#NƬ:cu4MN(>2v*UrQaB;LGwI,1IPo4A]w*;qss$@$}hm󫯾Ѡ??m_rnKtViS$E;]~9FІN,mܸqĬ ApHֳgOːìz(bZLfr2"_U0 kܡC+Ymc*A 8zkqRHHHh߿x׿J.]l)j*m,"&&b"  KtP 믿^k0 /C n7bhs9rii}:'`itOsOOB;ˣ7A/ "(V*2"(í)SR?~`h:Ð{˕+'?e˖.Տ|;n{!!1FMpz[ 5>q1\}LX)ܲ^4c`'fɒ%agǧ]I'T C0nViPvǠ[,ў7xcDcG&D`SXX0- dG[m\IjB[5T:wk]0hPN8AF6 AhO2趎$[G3r`кW_}5b2 1@h$jW0l" 6uG0#7|2•3{PP~T /I`|: w]+ 'hg}h+c$@$@#6yeBwYǤ#o.]Z8'h] ґV&[t/f7i=T. ŋ*/Z@xx¢ ヒ:nS4u3^<Ѥ-!䀉-rEWSt0$=//89E7->),֘m'>vb.v'wkB$@$P4<1@aDR!0c3ߊEZ`7G}&13]Ic洺O҂ BcM`,)f; 8yf&;]DJ.hF k;Wi$Sh`L&$H;a:'aؙ y˩HD[:9W w:W8qSV*pu1  <1@݊Y!#uǡ;j(9kx+q&eLF4&$[0S:Ү]6s +7:01~&9HPF< A#vFFco۴ipc($(3^5\&01k=G/'}冻+թ QŇ1`ubo;X't9L2 'G Ez# H-O PtaFlv+`lp`V:8?`N]|cvw!G2Ļbs^XWԞ!/ ,T81)"Sf!T|ϟP]MP8 [5"Z(V^zIͮT7cm|4 !S]ˤ rTz\ sW#O*-;X}TeM5AP?#8)TD=lD+xq"[`z6._<a.P]zNʈ z>:uPl>vx)$@$@!IPxmCIf#dF0'Md{GQ6d^p:\䃶ASxyt& ^kx1qA >]fP$TD hbi"N$W3-rLnzEhp"v(FXؙB*L7]hW0I`|){1aVrN qe ϜA[,\P0 סiv}pB$@$8ȃʡjժGThPjXb9~}AZj̲5肶 ~K6€~= xt0K>H0h`h('0R. e#5ycl?c`PDp#!кEƮ Mݑ]Hyߌ==`p{me|9^:43}zsΤ'c, }4/agn>gCoGZAUF1G:FsV?IH 1m۶`EaPL8>^D &h?xa <5oĉ퉩ϫIHHH&|3zi]G 6ᗐkCu@>V>A23íXHHHH x2@WӬV*"GW&W HV0 ]'J1r"u'l]T't.xtCW6$}"(+hk=7Nws]i킏p 5?' &qon$01Enb    o xR5xQcb&7&:c7fu=RCR)^Ad>h^ cu͛7bF ބ>n&Śohz胞{   d+B ziZ$/FLO?]0Nm hf::C=NByGu @:d|:*:  EÝ @(Zm#)><4`_u>)g~zB%V~+r֋H|, IDATMc@}|< f1 q@Ӎԏ?>!ypSp|A렟|z5)K4X|^zUVAp>k,ZH6lؠ}"Iǚ" @֎_tXO={ʎ;)^X$}2|ϗ#FW;8яIϠA_s9G/'>~mt~Y7 0֠2v3fxxМ3g I+W/CMm… o>~)ȿo=aǏ㤏tðatݻWN*T~l;$@$r (V7y״]FMڬY3/^lF$}-[ )ST .>rHb%I?<=n6`k8 7 4@;u$UTc_cʗ/o5dK$}~'YtڵK,RX1kM'nUc81'|"W]uTTIZnqc' +삏e` }-hs/7teOxCW]wk@}6m?/O< 2DN?O? @JhVZl۶:m?_vm :u-ucɒ%2p@ۤK.V5>clܸQ{(csWc8A;PHHhZm۶2yd=]ճf͒MRk/9m49Z pqQ~}N~l'}>A wHH 8:t_ѣ`^u"[_mvMπG",رc$tTfر-wuUʕ+ŏ㤏v0_~0H!~l'}>C  Hs\3La~b}Lxy0~2///ѓ>E۔ъf|6~|~ɴV& "@ȳ\   R OIHHH-*,HHH ,mxM$@$@$@EEhQg$@$@$@$hfiSm   (*4@<%   ,%@4Kj @QZTY. d)Yٳ|WҫW/eĉra}K/gyFmۦ?ttM?.8?bٽ{/_.}%Kk֮]k @lhƋӘe˴uʛ4i"%J_xwIΝ矗Cj-9"tQ']v_|Qz)@@߿ 2DZj%%Kkoߞ$X5  Hoyz3f<$uVOYf| X{ԩ0,4F(@}͛ ^/_^F%ӧO׆'ԨQC}Q@HHH &Ƅӝ@nny智֮][ժUכ]yEYM6?̛7O*T mڴ_r%67HHH#@h|xUXxqv999ړi`?T֭k+qի Z#8G!  H=@`ڴiW%E~ƍeժU֤%$㏭   ﮝU${otA }衇~rJٲeO+R{1Yn >R  (ju "'ТE =EdҤI]t10L?ׄ .] _ YfMqؿ6$ߺukٱcdۼy,\Pf3]v0LoJ!  =3H1>1.Æ ~M{sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o@IDATx]|?` "*OP@.T{yO{^,(H⇝"* v Ζ=ߒݙ;wf=_11#0Gnԋ*,, :ziAcǎxQMMM1AY-UVVRsssaRG=j[lZ咟h3%H߹=gF`FHAjkku{ ]x$#0Sˎ>vH_*** 8}{0@j!PUUeٕdD_5-XB̛7^o (]H,\;#0#( 3ĉ>^{z0ċ鮻xH뀇ޢsF`![oў{I&M]xᅴpBk,sdk z뭴i&[,氰n" cF`?iȐ!z}ɒ%hp|衇$uAЅO2#8NȻd!۪m8k.Saa!DqGPFFF WqQ y0# ]te_0IX'.Zp& dvN>2#$l!eee #"|C3#01fϞM0@>6ƕ1i@^^) q5a-Y!!{Z]]]PѬ,*..:6l1nw&F1cW_}E~|wwqԳg+#O{K a##<2V_uίLlٲEg+&AT?11"{} Y}B"Fׇ9ˇ@]dݾ}{+ݎ@AAA{`A~8` #0@kMk!F ^DbF`F`| G_`;`F`F`!`$>/,ϒA8!Z-8)PN|BB%)inn&DRKO}w{#g( :r㙎gZ»Br$$Rzmx@MMMmE }_q_ 7xjyY_pKጣ&$F7nT߻vBt0㩥Xگ <a8>Թsgu5TUBeǃ}UGYԉ㡀[>(/po/`ł \q22Ѷ9rǎM8]$%j}ܿK4 Y2HKж B=, p,֋ngr+qy2Գ6/~Y&{j)s8Ey) ckVWW%K低)T˕+W=JMx~_CP@ݻYX/t#Fq)m_9ޣGիTĩ'_>/36ԫ_۾m&Ny( WF"Q8j1CKq?'n<{<Qw;#,:@]pui%#g>F[xbGzrPB*{ s8BɈzBLj;K_K.dl V)lqf`F1DZ|x>vFڌ(C׿Mbg'v1_EwHK[4;%V-VVgUUcmavcm8Ŕ=`Fic([i%l `mK+"?|mr2o'Q&@[\TCy.;H0$jOi2L6oV˗![m-Č~#Rۦbdռ 7+Z|wx%svV-Cn`.jkpP (E=Իcp;⪍ztvr5eЀ. t-\g`h>v(hC[\&F`삀 cўfgĢ ?;|T RV7罎1C klov`@ 0i9w,Zt'cvv~ֻ:>}[\.2*tqfDf;jSl#0@\ PpT%>6o,w #PgF`Ag[;!xI8"yR"uMԛOBd"\KDڔ>id)`|e_؁7G?}Dߣ!e7wa ܏؅0"R:G/0ڌ :XXSmq}0|xmv=,F` Z\Ȋ,d#Sx6`8T9vjٓm۶NYMM!n0 >L@L[XHS>ف~)ϡ *BmcFA~zrJZfM``;N;~L8;R@BGڱNj'_+Hfd[7]q~oCb_ Tpl3M}t۱]^U10@ _:w ۙM2Eo^2=x`@mm-DAV>F)Nb@^H5v-[TG" jD&F`@lX|9s=ԣG05@Tr!F`!OۑI] epL#Xvm@lm۰a}g4zh֭[ 2nPʤ=˼?"Ұ)N+h {kDK =h\o`U0v'D3xMm}><PaYMX{a}ʈj LP 9cY3)m"ԭya*!y;Q"ѴdzgRv޽&kjjh#}?>j }tYg~M< D?i( 9%4#vfAhf=-[M-"t#j00d6 4@ wy~+}K/ .@qFB&㊊aAmŮ-lcb .c'H`,&17'iJ&WMxyҴ6,Ϝ9ꫯeG^_=͚5P=Lq-رcN; sdr]ܭ؁u&I"dT,Devy`hsF}>:M0!\hZ~!7 N0 Pj#XJYxzhċߧQFP$%->0Ha;< O>I>eǽKǏ' \tEs/zR>m4O?%|_z5M8Q(C$rw!O:`.]y0I F^x!=ԩS'H^rޣ}WF{R )>xI@!P7|#u? > f<@,'ag,(% i׌뀣Oi 43O{ >ƿFn_Z)h`ڣM 3^HfbF gAuQ1x ¢ԯ_?:d4Hvmm~mքT){e4p S޽nW_}U ~&d+nc=&.]*7`1bYx1r)?Ջ~W1b4L?]}D%4f'|woIg fF`lcG-:# Õ0##̈́U0?O˖- @;N+tq>ZBЄ뮠SGqDs/2dH su$"h,; pxv(`P?IRU]A.gnzSҚLGGȶ #D|jNٚ\`"_SؖC9DjaϓO>94Lgȁsr$R"u5(R(IP;pr,%a+vr_~eY/vG.;.sF ]z)=:Xj\ ULe[lb3ZB9$ cbFJHeV9}t;wԎGt7T NAَBtEYE =9|?|*((fI؍P`H p6.B¡XP@lsVK8BG(BkiUɢ*E/#0 E~Z^`b9C;M?݁}ه(Mm  ׉ :l 43 ~,X # JC_ >w͞=[ X{,x(AAP׃x#ûs=oEhHT5k[r3aޱqW˭KV`0@Z"w휀c س21#=ZfE 0?B8MCA>arA#RwAp Ft8G&NF:X(@x׋{>X`gd瞓<*Lz(tv!925 wXVmbg`P U:FH$JRDΨiʔ)D\N8!P2&"A EBރ )>_<|nݔ/v|Ԅ=C;\1yGMF f@VͻXxldxZ!]r;L#Xdg?vZPA Q^ܡΛy Um)U)}B G@AxroVM4%c^*YHtKHu\uURfK/BpISH<'<®YC-&F`FfG/ cc !Bp޳邰eU{в-+rMo|A Ky#UY9/1Oపo`coּփ{ΎD E#h8ѴE(!;k]&Z,0މ '"G/]j@#8,Ibƪ]Ϝ3#:@(6ǮSB1FH6x&rG1{ y8MP1F`E!Nߚ#0V! =01" +E1Y$cg aY[P|FT08ڑ0i@UUxi:mF`XoG 6olG'FHcPWWC]gFP":eF 02#7kAǷ4huj:z ڃĽ%jdSbFH 7GM6#^#|^|W6U{i4fikr @hނW,ZH6:tPF`LG RE۪kkki)--X "j63o~SDKdo#J"OsC N|zpquu%llٲ,XkFFjm"xO3fLX\+2ņea'K.Ɇj\ߥI}3Mȸjr57_d][I`'RΝcn*gۅ c=F} 0|wD'Zv0fF ir0{l#$f֭X "D(s)t@u2p͛C";/ }cbuʔ)]ԝv)X&YV%:[|97N?t;B<1# #WV8sU- п4i$zG O# w%| (F0R u&b cw v%xu`{Xyҋ70Dpc'` wI\rIXAstG$;8"R%~bYY m!UhL;'W(Cx4PAJE]ƒ L|Lz`iK'h.2Kᄶjyy,c$c'hǪ /* _1TR pD D /"t}cF 6xƑsK_^7kv^{5߿? 2,YQF> ABUVp`EΦ7iGOi#3۔+G< WAGO :2x ZCS@⦫^%AH,ОQM@C@{] YVЛfXe|`8=nuXl`^&Sq?`,ч~P`1 '1Zv^x1}tA2P&YF. ^hF4~tg˅GIGu^u&(c'OT"; &ԋq4[{GωM0mû?uCÝ1TEc}♋|d_xcci;g ܏؍15U*ݯ`̙3 [ӧODƃuƌa& X^EOہmbxb0DzkPNf,FւwR?]7$Y8 !xx\sfk:u!cJxx1cXZm |Ԋe(YQQXhq)//H1oF`GZ+b^x!pLŪv̧?oiMu i$c3=Nvn8ju'K~[=>}w$a=8&T h qD U7n;06 W'gF@J$\[-18XBb>$54 ! |S}\x[t)?N@u^x0Gk ob7KC 5''#XkA+L |k}5F 0'LFՆAF3"a&L@QQQT?\as&"{oEO\GKdQЮC#4GYԲ%FYgnGPktWe-ǍP .> s}10 _ċ'!nϞ=mf.] E$]!Fp42┙=@X.(dwLd?K Q&r mw94V|EĶetI"4].ԽA:ɯ0.oFH_x%lF_]aJIp]1:xf'*E NŇl>4]8G6~BU-մk~?T0@(cD@D5![(/?#D@,Dڶ,ңcQpmKs1hR &> 5 ler ?|`<(gƗf+ަF_#5xHQKFXv2 _%r13j@<7UM+?+Hю%0%:k³R+_<fͻhCМ'/'% L4vfV޿}͚5Աcm,sYF`DV ͤ ?>^yiڴioMjNXd#F ^V=~!WNp ECۮ܅DLzxvac!74o.~?Yԇ|Ǥ[Zs0Q9t݂V"9otCKE^\\,$"1!H"4ڶ :0'17 3e|bц `/I4afTLl(ǃ0E+=% ŋӼyO>!9rL& ^ Ɔ_v(S~VO0|3,1Gtܳ]"?~*tDgI&6H9 UPvl$30#@!ك)ВAs̡c'NH&M#Fv[֌>']}`VQOḛiIDvۑ~[*}tyD _v^MؙPv'TT?-* Qڪ7#`[2'-#0dv5؝D`0o@X{~aZhQBZD3ef)g ft?_fӅSKTю=iiNGg#/:J\9T磧s"µ<:q4 !^!0#` `SMv*~tpժUv|Aƒ~G6xZa#n*&U#_f+5s~#4t--|0GWlsVS$)Dz\{=0evwiۃI=9@󫿤'C{8fŗYR֗ lj]Fϊ4@*ާ kO^O:T#&{\\r%/X1-Fv#2ȮB6E>.0&#P[3umf͚E' :ƍGr 2Ab*͢fuZwHC4uA9~퐿-f|q}?C*?uW_#X rruў~r 1sB[>W[3q!p㩪im5Y*;ŘH6jBVF`lz!s9{ܚ5jc%577N Y\"*Odj]2GD'\o"BQk"~\GVN/MbAK|FW"M2 }lYoYSw#(j%a5&*㢂 13_-!ج~WB6@( sBL&\h>\/;!ʜ4ΠgK(AKK+N2pWj;E|+Hfe\ n9sP _ON첋 ԠĿp#a0]+^{Ps%p{p2fj@qa6J]E{AΠ I6W.@ҿem5?;_xhss'tpz |L~ 5D[!Dr>[mޚ{wo6mW#lGڼybF 6"VX!ؖ!ˆq?Db [} },<~:tSjϗca?,MBk}Fwɯ 7sĨUuW]K.f?,?|lvM?~} g]'%!s1Rr'3 LF`!LB <Тh;G??(~KC>:G?Q>sLc9WFJ4j׆UߘӛL,=+^huyW mse!|m$fÝ4S pU{y ,0+ pĊrӥ+gM| !#GqM9bC\`Fr"% nrYYlٳeqՄ>ͦHbSTT.Up$~rf=s9D U =hPрHUꞗ IN-T`ybu{Vcw 8'^x1cFp H)GI<q ]y2Z~oܸQ&9Xvr_,n`U>U*  g+$l~B+..ufzeqէֻN-=.{}.;+3UflVKV9c"5ՊǎsS褓Nbc30B!өBo *ykۮiTa4K.HF?:hQδ7mp!"hVF`"~za8$qHɩ&S-r*vA?J2itkhoF\7eMMsD*N!<.!HKL#L `@,٫,4,j/6 Y;kyO({ѵ=/~K,\s^*&S9<\cPGZ &F3@5Nyy9E8^#Ďvݮ.=IrJhuAǵ?n_ ͪOnWtGЙԓBHО]3EN[G EI8[PۂcP!չJa&c5uHޘJ:wzP/(N֨DU70NϨ7RP}Rm_=,12FF0^GPۏHpn`r>c9Oңx堈q]933bjQnCr§0#  )MVS7Ld"N9ڶk7Tݱ‡X0g;`>`/0[wTu0=S]\+7G?ՁPD@X/ED8D )oPh(mgSS,&f# kFMhG2J\o$Q,0&w`w 7ر.lx+֭“F,d2"O"S8("#`&x 9#-F,.T*))!/8s[C.һEPRM:xyE&J m#_t4 Jr*!tI*/k׮={{.] i#m f`R;{L4/bXH =eEeg[݅>kono}k:rm {5Â;0Ucgeߒ1/1OYJ l#, /[#v0F;;/zz[!zz궬n8cJ<VPJ2:a˲?UYq ýl B"L,cф{X _Isi 4hy䑴NUܹsc/`F555R3&A@h[vCſv 0ϣY 71%ʺ/#_Y;b7 h}M5H~Ėmvԩ{#<"yiѢE4tF`l@ !Tlvlذ!\2-h8TPL~+ mm]+"} ʝ&`V=zPksukDZ!sɢU=?2X*vb^zOV,ԩS 5دh2E 01#`*** Nfd#>IHבf#|E!לYmE]_~#ۜ@2YZEћpr`vT{/u-]2M <ˎfێ|3O#A}ݴieV-G o|$޷4fἚ-LBd<&^/w{v0+2G}^y1DQ*gaEzvmlɋ40WTXh]*GW~77I3U௯D"K4S>_TjA2P㐨PJ~NX-R\`B&@;2R]b]}tg4tPO,"C ̝A* q[VI r&z!Zj@y^6E9ﺝH(CPc^$ґ&zd6Va dŸ:Ňbvh׌fө֎dkvNdG'FH<UUU[,YZKiԨQmP1b&nҥe˖6XUBr0GˌkbU{~Ж9,,DhG+;gЪ,?)f341v[E,6Tj^z5wwZ~wZ1D6DzSjjjd~; 0gz73ǚ0@ee%]uUtmGMdRH.vE mby(٨uצ*{X 8!pX mI ; I&V(&"F 0S&yڮ;:oUWW_(R\\LӧO/#@ 'R_haPW KKdKw@] 'JT't#0@"z6mDeeeO01@J;Ӗnޕ- ƒD)v%퐠́"Ls?&F`FD jb+x*N<5@ߗONVoE ReƢףWTÁ*R*B"N:Zq(3P:F,ojԬ-01# ㎖BUn$}xPx_\ 2ڑȎX1O#` @uY0#H$tƣ!n)z̾ѺoYאlyk$B^(@&hF)////RWzE@uVTr\d;zL#`OUaD ;A@ 8ّd,íI9#X@0 h87X5 gH9̡V׾}XX2i# Ύ2CeYe +%eъ>ʋpƂ \ &F@A`4l0tG)ѷf\ ~R7F@ѓid&`D TWW'p []v,1HjxMM%&mqq1ag)j^ 8`NbnZAVK,8Dy^]ȫs϶ ;0I4ay>n&zy 7t ʤ9vy^* /XF s&Nv h01K A9O|Bc X8STYYI%%%Nńg}U:5hM-}J ӿ aԸ*%l8|`# zꔩ`nvwӤI{iSwUU=#F^zIS5, aڈEbf *((h-7Q7>zJ(&X'b Qhb›WQsgO#؀P}T7FMl퀅2wx 0~>$0L"9a୷ޢݻKP~ >|a:A/pq_al_E@QF]D 5:6̱H:Wwcxuct c ϰ =r@O?>pA_oV/sO9?17/Y#mO>$δ{:µ$r˗K=)W?'ht{-r/A Rc:wˀz<S#h"|q dr+'+?'x"l3M:f{HHZ0 DԍwE"|p?C9_Mq́xhF7̳ij㮼(.2<1N,PO(r~ ԋEVʂaE\AGK։•Wx4h~tLJ^S,*W'·*P]xRx饗 U' > ūϞ=пO?T>B?_j2_L'NT7#FCoF_[i4?gq=3>'o'-Eo\mX(:S}֭vL=ezf+2h;i ۖzٔ-N Zq,x@e (% ̇w1P G[.bN\pǵE[.c)7r)KT7}oڈX#:c)*C m-1l"pOsیg}6@i2# H_}"vHMP̑RHF`@EE?Rvr$`8m4ҥKN?xUWlR"m`R5믿.}_>Cm>;I᫯J{[v`>`5\f _`; EEc|]w Q(RaM8p`]y*tvֻKTOD&F`< G WD/Ωps#0IB~70@R@"D G2[tЫW)xwұ%f T/peByBպN;)?/ꈐ`?s~)UVCr!:jB: Q-Z$Fkl2BCY:i~o "x>矃eb&-3>E(BX- .zmA\{M-JF dvq܂N$x:͗\r }(wg_~%!~$d:Fn&hر~/诿",~`!)g:KǯJO=qR؂D|dbuN.2=駟N¸ܜB/}Y9>XĀ|A>} YE^{v9g:蠃Dx{QN}OڽoҰkNV`IْGxJ ucG\ RMӉgӒ54WHb5%a M"LuGyn1 -mXKWhf6dЦ FlO"zb[]9(qͮG7( h-p Ꜷ F]mVsǘg>+=`d&V(y# Q?xcI%:_=\Ђp Rs=Wj?뮓} QHt=zsp;åޱ"wA{( x$\ :ubcH[o^bwc裏A>sBTD_ykչsұK't|7NfSfyo,dFX'"qT~NGQScS^v;SebGc[~}~z: 7 ,60qAh&$0 BLN"z:q${/ի;dzjUhġQv3& ~Bp#UwkP?#@Z­U iAN`A@r4=7 9lA"@u-YDjýkP)o;hΝBpQ6QӞ5臲SѣGHb`⤘` iidbB!_b9kF _8ةNQMb,5 ͿK h6[H<ɢ+ 7nN+.#`[ T5=m J}X|WGaSl f 9s&'|8oC ;n0# y'! eoV s&X!.{'7 )SHQÆ~éYY`~#L(Sr>\QRڷEWU yZ?RSK0ٙ~uuNAL{i:7Y278(m!ھ?԰xA܇p@}0Q,nvGu #k6[B/?|)@ cAN"j@c(?~y8q#Y])o׿8:#e-GIDmB(@4'q'@I"9n"km0њZ*5}auF&tÏ-|4_:aJYM #\Bk֛5ULvX,L~k:b!CۆM?l!@;0B_Dt ̡92M,@A&!ឳcCOr9{  ^=g&*"8B&>]V'TPt&:vr,&x6M؅NDXW{`Qנ0%³C)/1Ν;K,#%X~%<7,B?07v7[w&2@8رbDY{邱bQk Qٲ=?}$wbS@$ЃUlMĆbF fs1W0@aDCUMhoߕYA¿Rj/0/#`xLp5v5)`l̵o;1 ڑ4v-Z+-\.lEy )m߹#j *_tթUA9e-NWh*am6vNdFbca ,<"@#~X粌#Њ}&Z1#y0銏]ߴ[4G 6/uJPp~x^^jMV #0" x:@b˹ϬE[cbC;nF!&F`@N ¥F`!);+&V`l~ _ɮ vĊyb# wNDBC-0[2V^^nK)FHOG 717 ,?_gAw{ ǏHZQ IE೩ƍi4tP1cA 3g2 4"@xg=؃O 鳟}Y?Qst-|h#*_G3fKvjK=QⰍ"BO25E7N$:A.zHݕbz4fWQ#Ek׮;G !w.|y$C=T9M;̢E#9rd_h&Y[X1!&7*ijA{/T)lЙn=k+ƍqFQzQTE_|<@N7H}Owt1ЭJk֬x 3G;~555a9Aod$09?T>~Z^Ek=姜L].l35ҁO~T@BYt?7STD}*kBXESL"kSBCz6ڛq>jnqKx2&}1\QBs=/wuWfCp>seв2.. {#%Q` #BEE!l0v6ldʅ:?,#n!+YDPB'/" b}6ePv:(CkF͛)?sk26mzQ<Ɔ,ńJiҥt 'ȏYg%m޼Y:+ ,[}]GaFar e`X'bu*x9ԂoUv[oEmk b$xaZ"7 x4ZHLvg83ں$"X,y( ^|(TbJyKv:OyK($k BA"޻{PkV_0?:;(j!Cc츚S4[~[OS=@JW݊W%a.`za|1Ԥ\xGhp)ZuB xT:ƿTU[nuZTF(C"vSOIW`ɡ4D@/Ja.G .@t}ɭre10fS?"D^OxRs  =,ѨO~@jYu7eMY2!jГK 蓥x~B&/4 Yd<):Gav[o06D @ZCFCX'tM7Ʉ6mM0hH2C_,&jAQd 6JkׇV(b Lc\Tk[-x]2@I+LF[NymÇBןΣz\F5۴#}@E0)e=0A[+gs0TUUY%|{j?uT {_wޙ3UWW@7!QUBW0P ,W&=^tlt֨jyiӱT^|2(ǝMY"dO?F,.9 `FH>0ŧVF6h,9vD[pB߱)hQ ڲwG]飍0rc45Νcg`> e+tb/ں7#`ϸpEڵk)ACI*5ڇ eroŁ &tT}H~߸qc0ZآEG58Ej=}Ɵ_CESSg:u:5dYSfϞ-Ν+#}aGӧOΝ;kFڃ艳6bTAvh 'zaAw:27``l EZ»V ڸ^+WWWŃ,6>|/V$k!޴vu6v+~ZBZ{`n_ݥXL+2'+xFsALNdoT28*J U?; LW0>COX!A}>0|/(LDg & ("FD1d@PPD DrD v]cRTWW\ң+9#PDH"z[xX-EK/'w8pv[N[mq%F+ ?)6`ސ{>/#RG̥W,2J†9\YȤsX} #0E(ڨMAh;qK(k[J ?(~^3NGSZ3_@,~NNOO _fFXR5[Ve@VVV:7 LD⟢ _O7Ʋ7C !e~1\zy,MiJ&̯Dʠ|/O#!?zmP2# ,>|8Z1T^wcǎ腸DRwKI 4 s_kLI47kUeE޿($ }愈#{=ʤiC ͍ =ډp*Th<< F u`I+/p g<&o"P9"}z.ۜdե+M_eeDd8i#0&ߨ)žՅ`ŊDv1!TĽ$MGvW@Aˎ $b 4݄S;x ilQǒʕ+s)JⱤO?QzQF)5Y]IkQLziiˍ?8tλ6m)XrvNmI/dO>}s?>!鏖<@{(B`޽EEָqh<pUVѓO>Iw͞=4h@wuýps@l@mObÍK@ZUa%)CfagϞ4mڴ";fP&6n('▹)N.]ZF*Nc2# (r ͗"ݴH_%<L&F Q-[Vj,X@]v-[7n(F`F@ ~(NKQˌ#ѣ飏>D\bTJ^FysGZVMA+"Rf73L#xqkSyP\m>a'x"+fx7'|aB ^}4eݻ7u-b;wr F`c)m1p0DM+E[Z-q駟C=DՓ&qǏ7\x#-233M#FKLQiQ$AᅲԪ>bW@X_bc`V=7 +^="77k 7|3t xX!oƪ;F:`$w0ysmp&n(`nk%UFFFg\"? ۥxDž}pwg5hmbo]m\r!=CN8igڵkêѰaE}L |A ^}RU12@DkV11NҚ'iW<_4>yqo&٭{&30)afi;.Ń ڈH3ajlvQyn ,@[F@"i&VLjS⵴yf9)3fgKW]u|!]|!wBE҅ĭ9kp_hz4s̐_HZ 5c;Mh1scc޽ :($tm8ijuU ؿXר"/DrawǓ|/^,{Dl Ktc2d"d `0RGU4M^;~khAAm01c\ђDZ?~Z;vxZnB?,_|.t"xn*Z;ܫx޾KOO襪ѿ2ziX.8=wL {nf?7?~.vؑ&L@0;l۶hh7P0@ @]6dA SAkc%<#"5CY:Ġ)μFQܱcGXXGCmf7Zq۶mS۷QrU1xsϣ= ə0fRu9~j$"EϤXzChtZ&:vd?'q̞!jIԄ ~buh_?TcB+sLq_~9 &rz:t`Hw~hZ`-^ķ aSTM W@1%1^(_Ve5{ ZEٸŋL{huc5F@8qΊc&ygR*2bYՔӈ|g?,T'xiD:҅n|qM GتP8w-xnWɔm;.4fV/=w T H 1|!BKTihRծtQ8VZ&ߗNέxVl\ze`iW} ~&zfZ-ݷw5շsVIV[ʩq,[կZ|p7 /\6jJN mrܑr#`5hY'-K1wy1SO0Yx2|pU:uXq\ FBf Ё,5"U/VRt:o{o.]ysJ豓N:Bnп=Z_]k}..v"c gÿ>W|:.1,p&$tJpc&́,KX6;/t)Ku(kq^"+'t={sNZ)08{?jKE"F;vh1; ~f͚a>?g +OJ@}CP-!i4inB/ *l:FB?mס3ƩW̢٧N u}02?8ٵ7{S ;n@IDATB"; 91 5; F#bgr(@2W?Bɹ`12EXG(WZBA $&%A[6KSc.ܳ#2!ۮCS  c dhvPn h,Yq8Gho]3),ar?|wED㉯,㏉`F 2'jB¬TKb =.! f\Sl3a vI_i֬Y8˖H}vd96,uąr8 xڴi2/B||AK.ue]F7pʼh͑u2|ŕ I(&l wF(@YizٓtϷPd<&TZphթū 0m6f+p޼e0L `mF} J߰B{Ә N<0]ów8G&`=z!\I2Q~[fƊ2BYLh}]Jj޼y(I:i 3hP0!І1H^7>">t#bXع\ydZj7g5*Nz"аd=J m)WLAơdOXYqD9h`/B=3* L P@l~aMܜNfNz+Amfچ9MiyS˷pzε!(uUv 7|S:)رc+ +XG4fcbgV.5}ўohʎߛ^27M-Q>pJz*/"WlJwJ'̍︛ó{$l! '{ XErLغu+ġCs`F҆_,#Dm:sZɈ  Q*`5>!prtpvǤ-mGs8Wc魷ޒjwҤI23&Z^z)]~r2WE$lQ+ Xbe pa :U%2OH(GDHZ+SP'+K\ qeF@N H;wA:!R*ַ (]?vԋӑPvab&lf/ڵko߾wB:qD9}t_r* wd| -vP8jM9\V((`Bg  2/_pSL_fVy) ” m7&Fpf*TK"WBsC9FH`ۑt@D9_8btLS׋fyộdq)>p(tͬ&n;c(Жٳ p6m*m|a~,uԑec/XTbd$ 5.m:#N/ԨQADJ‰B[ߪUt)xXzT}b Z x  H_$po#=vf|OKG#yf$"A0y A\ Yꄘ|Ʉ` 4EQNH]0OQΚ8ceR=,\4^*h::xO˅Hiz ]j[+?8XXͶ.;pUs`[7 Bロ(W|p)üBO'tWb5j$}_WΈSΥiB[&4>,5i(_82R:*xJSL((Y~ b1CPPN hBA8VvVgbmK_a'q 2c`(>Z?+VPzZ4fV,V:ca?=[uq#wew'M.Q>vLRG[r}}ucU.Li2)R]idO y-EPM( eRf86zF'l[#FРAcǎF$^OMA X i5kR)ONƔc`r)B-| V B(?G7>@xۉ"? AU9B1[1ÈmD⢑L" )"N!1l!~21" W8Ù`F`#pY  ]x( GR3ifiM{hȑb&8ٳgJWf-v,(@Y9^nX58sFAJ|{frʜ; ۨ{ ;3ڴiCޣ:/|h[>K>`r@Ld֮ #0#$3`wB+m >,UTf̘A L 6=zlDc69zhUp5@3΢z)}V uީ- ɓHzkK4_Nt;sm;i4]& Nc )99JLf+eDtC!k J&\LV^M`-Zlx6D`Ggq?5 0PkO` x3v aX}t'sS ++5"`3F5c<7`ŸAB2&EȪzuI!ʇB,T†H;;r#*@8_ m$OLL%$$)>h7_h_Ydv*p@8d$'D"On)_|It;VMeF\}pRp,>":`5oQ t;w:Z-rF[lS_Q'b4|0Hȧrz35y*VF*TH@ ZhQ` 38Ѥ'L9ϣ̅ҳ/r?^4p) š| <8)j9 8s E XBf3Z&`̌ 8yҟ>`իyiX3cE̮r0ck '3p^|Y9XD+&X oFuNo[Q,p΢Um2tO3!+@!\祗^!CQ"gyF5nܘs4#~nnsZ[JYRe MJ_PЌ 'i+B=z"(>xilBs $8C88¯DOXj`xrנcJM蓿lEfORz4g.s0gl"ghe8Ai 4T9þgqF @?#Jts*O>Iv{w 5yfZxL„pzS*`/"-`C0jma ͹)mZ+s۟.&%FI1ɹ,™o… dAZ>[jQNK,֭[8pVfiHHL*ܸ+ܶv8Ϲt8ÿ +7vVolwFHA+̥`6TtGRp42jKnL7nΗN&@s c۰Vͬ*gE?0)hԞ:UcQׂ]D,a0q@Gx%JۼI 4G 26VM:?_CvLbU f;}d߿|.p Hp~_-'5\ VM>]޿|0*j ZA”KlD?ڰڟM6GݎL2`Eұ*/v@ν3k1#Pxt O/K&Z}1︇LV(!&@XL""چ&O !aavۈTⅩ @GKRKDe \*M"UUvC{bco{qQ7)]$!$Ա 3D M5iC?p"DPY +ViGlѶ]M.Nߨ]sV)cO wHK$?fAbjN@nu\}RUF&F!P9axLO@-0>F>_=uZ`F-$45Ж_LhU䘈[n xX8 ;бv's2J (ݷEDŽf2n8Y*'r':biE{$3sG̚q]KFazd00=cF yvdG];}Y4h(uԙս]߭;M<;ߦWwN`'&`F#̴ jU7aT Ax^+[0{ &%Ь??h@Ԭt_(:u2P ZfA0h׮L-YfF /DR/ 0V8 o,AIςVC (Io$Ȕ)SdYDù>R7v7t0]v!'SdrDD ;^+pL]HC5J8o֙t:% RG AU4-F#/ ?"Hf*?F-֬fƲ:7of9 &{vh7Pp|cCzO ce2(V<0ђO\ pڂO>J::0ߖ&AHVVuPo4tPՄ\9 vTFY+ueP(vmX nB64?eɤeü%{Մ(7+k>7}xk#0&d L\r ]x2;l&/ZhA[Wێ~_9;mG qQh?S9MhFʟ* cxS&Cu xZ:\KIb+-dgL 1s8WÉIB 7|S:?S oA4UhI2d_KQRS`d]v*Zxْwp4B2@AXB&Z~W)d֫WO{:l8L)BF]8f63B#>El6+6i2oFɼ{F'd{WC4iĥ^J_~9i><7*&H50;+>..xr"{\cϞ=Q~:T:A.{Ktho;h$Ry XMm|ٳ(}Z0M!!wA&'N$dsU[hq2^; + X4g,r:pg/Z8k`cԩSUhl"MpN825!B;eehEOhUКDanhLʟA7f%~{@1`wbkG]aiRNxV;7t]cmmB>MUڮ>ڵB{UVїw\xy+6D]<;R̜9^&703f թS6%3ӊ|12B[s#a.#7+V V5k +cǎ%8  DjժUbu˵,HC?!>%6gz*RQ9)` 4m9Lh>8CcėEH9-]|x kopvv91)3Wuc<ۥxDž'v}0F;v ,+="ϋo.[g ^{5z Ш-FO,.Z: ͬ^vZڼys:"?tEhG5}xbMrmov~3a?!K&wQrz"cx=F">ai>vL xꢍxx&{N~.L _H v4(M+ X,&F*xf@fN(j8(\0C;Y*43 c9餓hh15¾vӌo1 1@f Iw0S'QC&}&\Tmz рp(fN> SV4J6-L Ęo;fj`[za1;Tf;&.~*⿿*bF"ǂ;$4|.2p"Aċc+ <K }cqӊx @!`m } .?UT*[xe駟 ݭ⋩O>t焗\M7WOrUT| 1r `.ٵ|r"qMWcwM6u/T)jum ĂI3mjY6FہImD8 ܠevRDg!kBG>v,TC@N"Ж# /AI-hgϞM;v z6aO_F`vVy"?GL` f'GXni$ CaТ5Eh,5j!{Æ G20l&a=zX㲌#4,l 17$8 ;dB27ٮ YÑ=Caڶm+un뮻NzGc^eF%5"a0r ـH2gϞ~>WZ;bO9-yeH^> z&Q>:$ ߃A9e@OGOd2,p$J @A%]3g͚E^{m(==2+4tPB8Ff[i5De… 魷ޢ{'lRS?P:kr@ GXJ\4iЗng￧nIuD?C뮻yBwφ  B+cE3#ė)}lJKYND% !YBm 'M&3d> A{%кu.#86{ `VSOI{G:tYqoN?t/ !%x_ >9@N:/#`990L.i!n!w4?L-[J@?c5e9_j h1wLHjK\`O|+}~O|GK̛M_y>a*W%Q$B'xEkhܸqGtnݺ¡6IJ;D1q0aB5ENF EL>իWX?#h"tI&r%"tH LڤGT$n#SSLٓ'O&< hA`V`^ƍ !VA: im6:<L#`O{PLX Z[T,X ]0%7ߤaÆņv+Z3`#X D4KGT' }0>Lv/"Rٚ/PpLʝ{qm .&NXm܈[_h+nXO};rZB;.9 O39 oZO_.^,{lRG3(swr',6B5bmFދJ*Eg K.?7D83& :k?0vF?-[2%Kǰ7и<ƅ۷޳f/{:S+U'Ό[ad|2}K>1Ƀ*3;|KS 'G@W_}E?xXD1c4!_$5lpw#0#0@\d,|Zk6E9 1Բ9s4,XW6j8cF!iM!F<F`:= _(Wo4}_Ai̙6nWaF`bFH viO7Oћ#\r2|$D6yN) Ų=*eT.Lq1#][ݑg^/peb ;xJ ;wROߺJ?0dk~XϫeէC&5 U)U:S?9"2ӄNNHl22d̶|rssa֯_J8.7#<31#EaH'3@t|.Dl"uHf,Oc,X x#&W^ye@C$"1^QBa/Ǽ1#HNmA۷4`c׸:,[D4SwKM4!xуFE{.UVHƃbF YYY.yF`!{vGS@ĄQVmq,;UV5m }G:k,ZnΣs9'iL12$bbF p&Dm/-y[oْLH5F 58zmytkԢT ,;:T! #<"n^BÇ' GN4cF`<_jZjy'f(䋈:y,??V-O;H vD8U$񰓥7a-#0@GZvLHl6Ż<1EL"Zf$<x3$$;d{&L?R7snpcn`FX#(t'11#5 H䷚8eܹԹsgzgm۶LA`ӦMڵkrP^ */3gΤ>@a۬Y38p`G0C? 3G`եŋ{np`(Wdr+NzpS5jDXq͚5=yo)F("*X e*`Y}ʔ)ORknPㄕYQ3D,l:Vi0b{-6&bӦM@!2-b\`EgWO-޻'OE;v:t(, ?ѦM3UIiRjTϼmM7j3ڍ4[Axs}W1x(h`bqċa,@vN ^ʼnʔ)#? +VO>V^-5um!>3D,Ҙ #KNˉ6"D%҉q8ц],0 1>|llEf x@~`ԭ["7N#0"Mph屄W+^ڵ~5e 1q{5v.xY!XumX1qN8F0$i #"0۷/kx5s dpʕ+'y߳gAN7 9=իWՂl0@kԌ L&zxUvG[a~vA`4vXzWd^zIڡ1™FZZ Y ! L V\AMWd1X+1Ca%ؙ'&4f2B|bBfFinb:kCԠAxWҲe75F f`&4f&BR9r$5mڔ 3^[;g@) !pjw*)N4=yY#lڵkC!!cB0EKLC@ok֬K{'}9&qԨHyF]M>6Db }ЩSFv2R8A $&?(a #E6tI2[,TłeL}?@Qv b'ٳ'-z'x#P=BL#Ċ@n֔7Jqd9R5֦-MdPn9׃͹#NfX"B(f1*]4ae*χU`Š*U{lرRܲelѬQj)4#1(TT-O9}ge6c@;jG}PN/gF ˓RH_I~|NF(Jo@y[$'daÆtu]'0뮻$ 5>#B=zP߾}FK=@sm0=HD#:t‡!AOx601#R8̏t?=2- ҥm~8FnmX&F`F`r,חG/1u*UDeʔ6ׯ:P۶mG i޼9-_^xᅰ<LҮ];;v,͚5KڄO6M5~4@{>Y4ve?ھ00o.Z_BL@7p#0hfV}/QU|2۲6l1yꩧz8 P20m5F on 6 l,k8q)F(!͡oj ϡnybP&dp TzuRj$<_uu+(XL#0ٳw#(ժU+ 6s#x H#O4oe$]rEwεݻw;Cwy'?ް.K,1 ?o&gϞRS;LxF>< fHQ?^Qa֮S!8;f?sJ3fȈ7\~4s̰1#\(y5)ц UKȮ`X`ʕce9?<⇀Ku;UQ^t캾 ,j"㒴,M:5+G?P&MUBG-ϡpt;pR%K?ܮ|0!;<ÀvGy~vc9 MX:Jd j2f4ַeeF ^ iǎNE'F +S>VN6pJ@{31_6 (…"RРAdlxhyUVi! Tj[I'IEyA }4R~5afjkax6'F c(-bsx@1C b32) )XgHO?ڵChÀn޼Y }'@0㏩u֡ d@{>> _;0X޵k 4v[&nCT\)O ̜R{(+#JLѵ?0Zqs#]]Dxd#Lr̢RN,@\u&-$  αr00`U7nH-Z&5H$`W+a ნ<\ F ӆ/VHO*X`% (^2bO0#$}S??PRVwĻh3# IVÀT|+`^YUPL⋸|fIV̒M^@4w $IDAT{1r"Qxz,\B{?QDLRuX#iԠNUbUR1!yq"1昈@b\ +%F ~ J01#0/ PX ;x0Dh4Y  gP2Lk]v1@g@Xf\C*abfWY̦`#${'W4q D,]uј ~Bx촣Խx7t,A>G Z#0ݰ;S٬ۢ6v DqAQ-3Qy#@:H%ٓ#/pWq/\0/SY _MDB !F$R; ͬ6HݘLm6tZ߿H︠ĮLq`o"=e0-,Vd} JׄL2*GVi9 pU//Lد}آ,ZSN#̒tsGw҉$΢j| }$U)}6Щ5en:y4M]|qU'?9ߗ| \L8&I r`ppPv{563>bxnbDXPoռ'v̲L!Pն<4xN8A6\7!bBpq/|0xVxV!#@ew-a߰ZX9U`_͐ k ||tmU{/\FQh-߃=>5rc%S@~v*\`F`+N1 *3,n{noڴLRѽ{w4hPՇM~ ]YLRB?PAP2#.*7iPf<Iz<\&]E&B08!71R '`{Jc"P91>MNʴiᱍ wČ2׋"W`F`0X՜?l^BF`/\i wߕfϞM;v41:xl311 /HbU_U0<{,Z4A6;RפӋd 8ߎw0V} Z8&ИsײD eukΥNDdF.hd ̟IUTIFg "ޓ):0)o*d΄ &1!i4lPG9.`>zhSFN8c0€"c]0̋ Xk# kTHtH s\JҧW*BFzZC|D <ٍR&L&́B kNF=&F }$7֭[sCYf\=7 f`R(m2J}޽{KA]Jn뮻N 4JkݮmwTm>Smڷ<}fh!Y8G.|N ڑ[K1@QE@tj7#0^Aq 4&z{hZLeoM32'lB-܄ ]vM<|@`( + :Jq@Q^hiױ&$(뭷dƍڏJ*I3ܹr/]:JeP [8Q~~r @Ъo~vj4cɉ'j!4o u_}(g[< Q/c3 -FNYT; &Z>nY\V^!$̵>V"8 >8P:껆wG=3U$ ~ߺu+믴|rҥ)I[.| <_93ihAA]>|-NWaQ61!2xƘ#ڏUxǯ?)"Ǯ:~=xFMڏuh_J>K6+giBE iaс<7ߕWorQNᚺnuׯ_/=z~; ;xV8 x¿(T lq4vX)*p~0z2* HC?=uԉ.B>|xQFw} :uԤkI1 P+?qq_=0hEzw[}cd4=h_W^yVX!'F6(u?ŗM}xٓMF-[ +a$^u7H "&@x~嗄>:%~77첒A۶mJ4'讹?F ) Ń+O ܩ!EvVHIh xg"e| 6l@ 4 :S~ϡXvds!Yw|jժK/0Yf^gܫ`0;v7Z;0gF-xEZhQt#c!m&@CbF`F`V%;cS<ˤYg}ćP!VD[@ݦMj/Yr֪U3 r#|5i$:Ψ9iΝX4ZrCr1ƒev> m\P3 .ZS-# hCcXd4T!Fs[l6mN6>xc ᧽Bz1N@@R2XvDߣHc |}@!D@ݪUP8Dciv_A^ߴi!,l {~X_5}t饗!|.#&]>;Zk׮]2~ļEۗ\rIO@R3ĝƏӏWOo޼Yz.\(ÕF]#i̘129>^ꫯƄɓ' 9h hTyLx>򻡞gyf̘!# Lc3BFG|o1|o.s)G6 SA72sL-}wBPYvGGf't|{r?~Ο?.$ srk$8y1x{IBf>QX7,r7{l.P*zԆڬb 3#!ffᘴ~q0Dbӈ83=NF9d6کH,m"V,TO0#`ղYjwR}ۤnvOm{Z籏o235ErtHd6Œ+*zų |;#GGf'6φQ޽cGDJ$>x'yveS}a_VDl**gm޼9zꩅ z M[O0 Rc{UWJG`ӈx`4gΜBMXP% LMvEfzʧ3#PоCq!kyjҥ2o&q}[eo)SHXH^9 ݄^tEʷ3|{D>f>XdȑR!JDbxn!+g5y X8f|Aۯ~Ꜿ Σ>*ogGI رcVD߆0M"),J}ј0}P|FѤIH, 1 -#X3n8#0)fw>uw'LtvnuS܂.}-ױ\0j(WxGF's{h,pz!4dԝ ,"A)y bPEZc&H@X9*NEFԵX04~xldTFxi߾}2jBAKVpҖus=p򃶬k\H6X#`a0vtJVaZ h͚5Rzˠ';[CJH%~;}"' C+K8wIF`L4P-R )78i޼ya> url[:DZСAKZhԘWXQpH?^|B}@^\s8`{D7iٳcǎR+s+0t xWuӛHi7S[F UК%"N:v!NSe}A$}Nvx[ b&@ ! a {`~oju"<+ogQ$|G&'N2(":#XG5NA.M9?_#s.^xaȑ7=ԲeK0`|)\ ²4ZOw}7&{)g"d)v.Ml R=2z`? ;P0?}_eнpIȘ"2SBEMCL/c"cR݋%uw߽9 {{Ϲ{X{^w=kx`D |윰IEo80ЀSXO=N$@"_3ZfLJŅJP_c'Aa-~qnM/V1k%J)7փy~?1` ?ȿjAM>|GTzAי3g\b'P&(Nu%Fflʩ9l?:Xrq4 [ K0B%ƩB L~5K4lU#ͦgRޘ3 `Js\³N ̅O>ӄwdJtV!~aJ'L#n. M5`:H/[N~l'M^K$@Q'bDM`.ѝ&#Sw,{a`k9\x KA7mO$@$@ S8/@*$ϑ @B~e'H ^V$PJyY @!\-QVI$`> An3e ([ D +&d^HHHHH lLn' e6u!ŀ@$$=h |y.^( ,gѣ֭[2e6mX$լY*~޼yr ={}Z}fZatٓ)`f?h@KKKr5ARQQ!X,uHHH&MȩSL}eeL>]v!˖-S@AAA~!oVϙ3Gt"7oݻw˶m۔s玔=zȯ_Խl@+ɮ)=*z޽Uy܅|-X~ 0a>-}U˪>e!CO4)_M)$@$ 3U]W>,V 88v t:Z&O3`.%B֑.Dk6XWՀbׯ_V4n.L_Hl8`4񭄓-Z{UWOvСΡT*%7&B]en&E~дiS8 xzjׯ{ `B%Tl@@ l1)$@ff~M|+ȓUO!pJ=ªU4ݍI Ç˽{d=C'JNm&1?l43$@$DYfNy2x/j>"['@1\uiau>TҥKٳgje@g2 yFZl;N"Or dE8k7(b ʕ+U<vЯ{_q G=UpKM6u:A)8@0ĸA, 4(oSH6YcǎɅ aC`WCג@k`UB~ k"#&~09b e.4| #sM,1AsXb&YXNҵ&LثWL< L*gt`ڵs4B\ȯͱ`F`߈L xSr\OB$@$kM$@$@$Pd^<"&O$/idiHH N[yVZY$@$@ %]&J&Elb' {+Eo cHH @ph-H 4h xKWAyyycFt0}%JKK~R܌b6B'ֿi8Gh=p[QQQ/"c6n1d%J hl8ۼyz[pU` 7vWgGOU],<|%QIENDB`egg/tools/README/custompics-1.png0000644000176200001440000006617013367162121016162 0ustar liggesusersPNG  IHDRz4 iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o@IDATxTաߔewEbA HIb`Ib?$&/ƗļR^I#`K"BTP@Ф)sfuve3;:3{qns @@p;V  @H@@Qܬ @@w@@Qܬ @@w@@Qk녕UTTBWVzzrwjl4JVd,tmaۡH~˱%xm>Ï<:xCHYh6=0A1R7l{{{{ 0|CYQfW:ndۼ55 3C?v}UWpًm\S@Hj.BJe)r+pw,/k齜l0]R4xuig_8s>sB(lKߘ=de07_;u%ϺW/) 4M #jts7OӦ<1 !X[%A]lܞF# @ @SN?/7K:E)@>$@CEUc/W=i ;"s^k8s{&{Qq罧m̓4%yfk! QQTpkz| t v==5$=]/! t$A# qhhl>f uh_oA:s륖" }~=A@[s@0fr}T' 4۟R=(d1@ HxSNV਑1[ ㏴4s|<YQѝ y)Ǽ?¡u GX# 7f G(P_a ,^QqXTTdtWUU/|z@"mZ6 @HLhb B@VMˆ! )@MvV  @ @i0@@ 1. @HZh6- $41ۅZ! I+@Mڦe@@p,677_on5/y  w k|r=zl6xڲe'# qG 4m4?֝wީX E 7ܠG1  $׉ٴifϞݾ)ShÆ :S7Cʕ+5uP@8p`߮q颋.:hdxBeq2ns"omۭDfJͶ7^owFۣ_Ax9@߹sA_?/˥yV^A OHOOMWaξq=O|]7u7=GC H---V+9榛nҕW^ /Poohŝ]pax={:}N*,,Teee'dD߮P;TUU%zU~mhj{|oĿ=lEqqq-] }# ~Wŷ&ά斜nW9vh}owURZ1c!7v  }\j%KBnڐio4y]8xڐ:|p}ᇡј0aB'  9?k֬=@͛pcܹ=ztw_ƛoY7u.Mm.\@@pNmNmmm|C]__񼁎Ms@KJJ8 N94N]6|(F8q9q@fs@KKK9 98:Hhxyyy_#qA&" $#&D@pL5+B@P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  P   @fe  ޾Nr&V63wpotQvK* &$@]6Espnw[gunnkfU] x<6I_W2}#QZ}#'' ,^7wGT:&Č effVjdDގP;/"==}#P@@oоQWW' x a;Re߰%9t  shI)@@ 4@@b.@9)" D Fa  @1'@@@HH:LC@4  IIi  1 Ɯ@@" @#0 @@ ИR   @$oLC@@k/S%K[wTRk٬@ y=]oR0L=[_W%_Plݺesug5`YS70}kͪ թ 8?cu|PY! ?t Wu z_Ϭ]wݪ/LmiU (j[ Miޒڃߔe4r.>D˭T/]TkԷWkTYYPt^m ?@  g_S)t6̺N_V1At-]ўnf8x木˳+}_K&xS zѕjnhIJ  7:.8k.S~ L׈^k/bPishbz94CF 1]UgUqPcCo/ukgJrXZJ~&d $@9%CezjX.yΩS􈮟=_y z|]~$-{=;7g6&6v.s.(S3q^e7Ct2'W7],zGw?[| xlMt房gW}% T*[~ش[h(9;_s?(?sS5_O&P.~~ZB=@ÆkjeSո?ޮQisP~gwK&/*-[|c.v8mV=;.2@k-F}@@ 9N S>K~sQi/UQSj+rɓtEu ˚7n%U|Nנ\̱HWϥϮvkGG?vSܢ[-K{ۥCkzHӛܚ&sqTCh=.,f$&@#P@H z& .=LCovvYf\2寬M}ƠY1}e2.}梢+~Q.}eX7~ڧH*|;j4P;~q#uz |r7puOj{e'':ͺ@@6~j޸I;t qmSr$l¯/׹Oz9LN7#ZnݼmVIMoJ uϫ;o, 2 @Ҿ:{XHibДiOfpSه<;ϛUQt]WkUl-8KyO3MEE@@'sж0F]~,{dɜ*p9ϴQ+{e.jJл?Qo\ @@c@H\W]`94`#9}lfx0=Pɚ{&Oe^U&3t J+i3t')LгOUrLa rRr} &GYlJj "^y骶&%p%[W@H Ms.2WwmZL M5O`2c8Lyq?uQxX!  c /1W+_~/gDoVO9_ Ͽ/5߿4&j{otԪ4utƏhMj]Gs:0πWg7OV:v`͙qhntolӸ=zUTj]&|&fԣ-|  7llkquõgjէܴULe#WސtgC=z&|WƦf-~5-]Zϙ[n:[~R 2?%?' te|Aw+/ScMdzMLoq5<ֺ[kv3g>si-#].q9}Ԫ iQ1j駆Oz|e9 *@@^8vH]wuU -x~?{ ߹A C/+*C7oxh?|orUuW>sUZ͞U/4E՚X^u*^[{D* @x_6]OS뇛Ѿǖ(wXw c>ZlTs$ͭ&yLcۏ 悞OoDoѦV=M-]V,~*6?5O>O~yF#YqrV )-*{` ϨU_ w ^'λ6feɿDU!Q.,D̹>^X2A_N'%GokBa)^I ZTטsP4ubLjSԦfxB!:ٳpf URR"=Q!EEEvk=X9*=]=7`O7X9)4\pậr<>=M4AsD2ӎi٫=#ҤJǬ,4fYs.g!{QSNiO?r}5vB8t<=0@@yeMil6PmqݽbM'looOk|p@v~>m/  Cfz7۷OK.ٳ}Z2 n1'6'xmV bۂ{oĿ 5e5nONݑ0͘1CK,QSSSϞi{9`{AGh֭[CW̏?>  $#=f t޼y 7ΝѣG>nZ{-ܢ'zCn}MV  %2=ĩ6t硺e- yDjC rޞorPߊޟnO"PUU+c Ѷ=7"296 o8Fl=s@UrnB݆)[v4uլ]0@HGM*@@ X(R  @=bF@@X@cH  = @@b!@"e  Xc*fD@4  ch@@ X(R  @=bF@@X@cH  = @@b!@"e  Xc*fD@4  ch@@ X(R  @=bF@@X@cH  = @@b!@"e  Xc*fD@4  ch@@ X(R  @=bF@@X@cH  = @@b!@"e  Xc*fD@4  ch@@ X(R  @=bF@@X@cH  = @@b!@"e  Xc*fD@4  ch@@ X(R  @=bF@@X8b}  =Ǐ_{N~?|@@hz@.\|͛7OÇ-ܢG^C@HQ3f޽{F7nI'S;Puuu  # pϻrJ=t\.x㍺ە_z}rnnnVM4uyIM}uC77=匌 w#1$RSnnnnt1aӦMz#h֭3gqwyztW?ϻXwFUVVN V%RXXi7NQQQ\說W&k`m{}#_{*}#maa/"a!v߰["8Μ9S˗/qnA\s ^=Eo@@q2eJi,-egg    8W:pك>1q@@@@@@V! D%@@@ F+r  Q @bc!@@hʱ  @TШX@@ Zhr,  4*6B@V! D%@@@ F+r  Q @bc!@@hʱ  @TШX@@ Zhr,  4*6B@V! D%@@@ F+r  Q @bc!@@hʱ  @TШX@@ Zhr,  4*6B@V! D%@@@ F+r  Q @bc!@@hʱ  @TШX@@ Zhr,  4*6B@V! D%@@@ F+r  Q @bc!@@h.r /r>_qE=.Ι5Vs/nz߿y{KTh'h~\ۓ ]/ݓYD A5@()kK<¢3fɊ^efv@+x<A(zL # Hl'vP;@@ Iפl  nj $4隔 B@[C@@*kR6@iߦO{{.'z` mpAsLEE“5qzu.|r*PssҊ 4oiz鵏u#oEra쭴y\n;vzi]g_PaoPZQ^EiXsrbD8@oe%7uTET^|N>dE [e5JT1lpjsYyՖ%GDM>H=cTLTνfݟ 9b\gNͷܞkh[z==z?othlب<T6s 0OpUUԋ*/ly:}(Ssg^Xg O>QG5> cL҈ 4+H&xa4]5o=u ֿN+ר *} ~^}2nj_^AGM4{v)ShÆ Р/nI>?o@Hd=\YkqBծPU*{yBgs5v9?ӥܜt3ve: z쉕ڰqZ*t<'L+<]2B֨'ku&x٢AU|, ڕ<Os]\׶֫mҲW>qGGf$rR^p$ݻW_?~Ν-҈#B~rvܻH7}Dǖ&Du :fF~t zZ|&uXmpꄓW/Cٓ;[nՒ%K?07bjmmA$׫P= maP;X|kk_rrrT__@>W@*|G̹q[P]S{*UF+WmԓFh f[;&_ެ'Ly&m.Dwq=@#U=AKL\ CnD_ۿ14N:F\uL<x]TT(:uyg u  uzɕZVSvuMm[ߍCeO%a^x-..VކǎË/O>Dw^h9|?)>5\޾ٳgO!Üm֥cOM = HOOPB7n {d̕qMLj =%UZ{Z#z?M mA-*[Tŗw njiFkUu)ꩿֶ-%&b<34qX]}i&xU;oֻc9 a4sLϣfwsk੷{O mChLfm(Kv{# P{nW{7i+f/: '<\veկ~J. }ItQ7h SYS̹WCso:4_=lxO UO,S%&cǶѓNcKϟ3AkuOh,h3ϓkfcnX?i#iznm i6x~z鹽CګjLG&lϭ  f믿ySBܚ;wgP=AWȇ++ }W-#ZZ z4J̡9wFR;9UoSm*[s30Be7֜VLM9aX}gh˦=mA4ڳl4A93+]:N_ ͞PlYy*_Nf3ȡz]G{@j0s[Rkך3Ӕo3'~{P{~O9ӢV՜~rx?힦~ā|MU{=U"22/j9E {hya:xzcOTQUoB7=};L?M9*@C J{=YYK4I__hhσUkT[T *2[ 4a]ltVi!d[U;*M,+olhz<l2G KWQj ~[MgUuZvSvzT{ed_k2ԝmnnNxq[A3H߻s s=C @Sr@ dfxտ\X{TNL!!k92[ZtmӼQNk4,uˇ V{  ƪ{R$NΝ)' s97|򧗪 65{yCT^0[Q#bUFU.y<-iZB Æ<>ϬOjzLz=r]/&/Y3)/Q3ѝ3Oјi4hw*{ET|鋪YJ&~'^X?>0A·^ -@Mg@z[ <<:Qu58_if\{Vs<=W5|\$ov>D=v=Z~j4ddep[:lcM6N_=]gyLGeNpeg))ʝ|ϟgzDWbD+Tjh&O]+U=6z %hIRn6h59)%`-ۊu8D%m6 yyӛf73sѺ icuէigۂ9'@k(IDATl-r&M P勖^R+կեw}E_٪?|ۜi`6>t; @jQo@&<=*sF){!JInJ9=!|1/)U ]-q+;3t'ws¤1  ,2;x&>ٹ?x>Ml63M'js3׶ꉛh㆝7 B yd*ô@Em^x]ZN: z1g|m2Atj[bBt *}eU>E_.~zo࣯hGJI44)BN;uy#9%=~f(((09TSS&s5T۾m.1ic1 gbӄʌ48x=M܃*yhJ|;np ZUߤ۫6ictݕYuSNPjWzD,SS^>^\~3 e]蒍zW;McUxn_@F/g 焮jgmI[dChNɝS&*x֙w 7QPAt ϗ7IիNyWACGtep sjPْT s&~MϙƏV}Wwێ#$QŚ4hyM/h,iVsϧTbgӶ!Cgpi>{n^YzD_ymYE>2Z^yΟ=AuLcTl/\e˖bϝˮPiy ֘}DGj"$C(xnb΍ڟW&xȧgx4s;t=z'msh;њfFD9hVw'\4I9ѯ_}w?j.V2AѥUM yW>CI,@Me@7{w޸ݜ c 摙*>rY)\5sqWjO+oA~ *A}Ye֧/E۳gO_q32ꅅ*))1w.̙ҌEEEvg@]fh_=eoÔr} b:ًƒɝmSTEUZ[cz| ye+7ܟ~8ݪe;xmxDۺ7 wG'TPw}>tmI5~qE M_]C91#k7Ўp aReȈ9y  khE)@@ 4"@@b-@(! D Fa"  @<@@Ј@X:k֬=@͛pcܹ=zt=Lp9護 <4qϼA@P{~3ֆ _ fꫯ  а  @j 8r#&f@@: @;j@@N @@: @;j@@N @@: @;j@@ SoC+ Tc8,}g~Z0gx<ڗ)(_S1v̟w5ev@4,qҕpuI.CA.Nz'ú^ےaS܆3N!v)H@gО9uƙ#E=7-wgۛޛ;lk@@ hjyny՗nf|&ed˝?XEG)-+?"MMn@9@@ v kT{K7LFg*=|2Q R[ L3'.ǚ蝹C5٠&*=/WUAs^'sY׏"  @kJXMM%Tey+ȧt}\"9 -_мxT/׆@@ pys,cZ=hV;rRVz|hijJWWֆ@@,?hnSJ˥~溣j>|0r ,@ [&cZ5%#q Pf˛_yEŪ(VEn{r5@ʝ+oVCt(SzZa5A &hf UC@cz;kwGy7 FkƏRF![@RY`뚒_ܢƤ:6 }hG<s{9&sЬe6ѱ{F,9C̩#1:oӿp-A衐D F$KYG.\CTf8t̀@ ؓ$=QrW:`3ޭj q^-7DPXne! @?չ>3Msld.HjǛ)WFܞ4=x2omqVKƥt{y__n7Z"@4755խ[8A݃ek߸w])/Fyn3<uk+My -@=l2iU6X87~è)"pmv)7hצ ij1cFZ}wɽ]Pf =!sӘ@`&01܅% v{5ӹ^U!V:yBPǝTuuVl3k43|ZtL*hOC:r #<[((Hh-r>X*mkj$lc0--.gl%]zr *ĭ g)}`eg$ץֿZZ`(_$) JؗJͶ"3;/CO sU_CZjpQTz 8  MĭN =Ĥ'`ls)Q>U[UT14W6摴eEzB>PZ'Kid@TD A}(g|r+ֿ=C,WHf>supR}I9@Chj@ x.>%ݫmdֶp_^ʛ2s//РYnl4|_IN oc0lt)}P9%Co+ټ'J?Vî]߿\o>thHy{ @ghg>!@}܊)({.)[#U+_/yzI}z9n1nPvSYgZU"G&9G pVJn6ovV4o.Jj+k&9]*wga*k##];#A8J `~mLWל澠TQgZP9m1ϋ yߜIEe3@ ^B8Sg32<*쟮V,6C]+3I[n8 @uU jeyռ9-i7;^π 4:7BH>sI!hg@^cו%@@@&  3)mCEQj+elM}FDľ/ 3`;! =%% c_f^[L;(_K~u=l{9yyc%4@ZHHHl@ * RkQV   ΂A#R0sκDyHI=ەZW  KJ䟔CݻwCBu m KL*VѣGV?ŲyF^x!@@[O^f ,~7wc$!!ZyV^Jp&FW#\ϟ?k#((rMI#GI~V t}pT;Ybv%z}Ii۶ɴi,'>ztUv%EzӧSNQ3gd'Oٺu,YnYNnݺ  XNvOl$@$@$@$@$@ԒFIHHH~I*w$G!?+W,3fM)påH"&wBLbpm&RJIbL*k#[lzm& B/^ܤ+c@HHHH p@$@$@$@j,oF$@$/6m+WR?++w^yU6$@ԆJHHh0<٣F>O`>Ž$`,NumO>W^ѓŋݻ_R}R~"sWڵkc\,\ƍccc?^<+ 'ݼyS֭x62Sb,۷ok{k> 8tW]={a;y^:s`Lm0uT}8p4iD&N(۷o?~z RzRX_8tڴigu-uՐNFԕ_V u ópbs}3:uJƏ/۷VZ#G (<D8JLLziGJ*ұcGm'1 zwx\knN0+Ve e 줪0;+0^CC\G,%e=o}yOxp04k֬U,:C $`3&yUz0QpC'0u' M>@r R \{@׸+%c$a43ht1rZ>u͸e0=Ff=$@$@$AFEٳgRlY), _R# x"zTHT|H_J$@i&rJ6mlٲE!#ѣGe2|ߥtH(1k,^;e3f$&&jnǏ5/\PbbbJ*iРA }J|N82 rֱi&ٱcԨQù $@$Mz>&Y=}+V䜟7o}vY nVȑ#RL~ߵk;vMuɅ tە+WF*y#=(5J&L˕+H[YdKǑ3ꠟ WHL@8MH߿/Ǐ(U ?~ټyz1رCҧOo#zj?c޽+2vXi߾ڵx]t[I&2<0~>}*rttI =fh@$` HsO#_g޼yS6mإ͚5'OmJ@@qaaaNCS|jx³b iܸ;' x Po'  o@L.G2E uۗ'OIHHpnCkk\K``Ɩ~VrCVzyҥs?HH h( %-ZT=>t h%W\!Cٽ{s#˗m:ͱݻwrݗK) NL.c! 3j֠,$@&Pzu)UvbbѣGCBB3{%U cʕeȐ!7 ×HDZ 7n(oI@ŋWP0aÆq̑#NX;wG04Y 4HvHX1zwU_wW*\&0 tI=o$HF9HHsg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o@IDATxEFvv9# HTPPQQS0bˆ<8Pqܪ_|[o)t!Çy@$@&!P< 0]Vod۶mjD4h`$@$PU4@JIH tA֬Y>+=vqI׮]>?PJnM U tM$@"@4\d)H"@Ϟ=eҤIdzaÆryɭުVk/2VMNNͅ$@!@WK$@$iy<[lz:=۵knZ/_.]t1 А#@ l~ /Ȏ;d̙ѣ<5%Zgڦ$@$PuvׯtQf̘Qu@$@`hHb@~~rY7 #@4 @*Xoa֏HHH" kC$@$@$@NbY?A9995j>\ATILLC jՒLٻw` !ߐ%Xm uUyLlN:|tJ+,,t).. q*(,b1/n:(b N$Py4@+ό9H$ſ|*I]i$K BD]dX˧Dz)/tEKJJ2! Ǿq%~ѻ P5ex$!1-[H=n9s\2 7= 9וI?'V,ܑ*9qY0`ԥ]q944mţ0̎!x\ N%óÐo7l7JóPFlo|pip.: D_`1~ˡ<  @I1 E:i$yd̘1n200CH,))Q.,݉8A[lc.Nvvyq>ˡ/>yBBʭl(uEa  V % 1' ^{MF֐!Cŭ[JVf͚c=rA9pwN`W8C*4JKKScq_)O7h@AțP7yyyF_Ʌi_Ne0B'}SSSW_]Cr^ËBR !)>TX i&iӦcǎBQ `MۿpK$@Oh1kH!!ag}V.\ZJ+=z| #Rg{>aTIbcmY3) [~2~xٽ{{j9QX 沆J$ S@ݻ+j$VmLܓ%kP@Y$@$PY4@+KIb"\EEUI >vf-I 1 @$IA]HH I$P4@YIH \*x  4@#1 ,RFl^{;aw8Ei#z|ȃ81Ʌ^vyqz!`2qݮLęz(Biqa(P А  mǞp)io 0L2VtxtB]T)T*_)H h(ő @$\lb&4Do!2S\qfddÇ=k W_QHpˆFWky!$%; ڀշ\Tu@$J4@CIHH  "7ʕ+?쳽H 6gI⌀ilu X|L0]Ԇ dϞ=c5 '5 @<!OHC|W^ꫯy֕H P0L$@B*ؠ{@u&e:Id%ɉ.iP;Yԩ+Rcs{kGym@^|]G\+qz(Bi k֬VZUTP  ~,b|a)dggoJOOW+qƙhӉH}]Ҿ~4O|@-L 'l_T~[*ud`20d 0B]0i:pW 3 '4xL$`K6MNd…Ν;Yf+yyy8}/.I%;, .+N+SZ)#~rnK^[.'J9_F/Gjk ̸bHHƟ Wث[_1=M6Uqp`\ڹD'QgS@]7V=Cq^SчBw M4@c]Y+9Z6msZy6$ϲ^7VK#I~H 3VrNO{XlVV,u HH Ơ*$`lðad̘1Ҷm[})n<;.ːRf:%ȼmR+e|wR U*֒:.IzO=,!4@˱H" Јi *BIZ3|$ y gm.36?ZގiuCVqټP?V߻S4>Ä/r mrH$WLV"&?ȭ} /Pyc)S w-Vt󄱙nv|tx]oZ*)xKn[nԪ88S6 @ 6߶m[N;iҤژ__Wq2% *GMIuKV2iuV^Dk5ԞSEFކ% ϛﶧjkzJ[*]qSuT+pE>THh 8 ōUw?ثX}e9uNY;%99GtϵG8-74ZFseڲvǧG!k|:rI| ꤩ}@YwH4@#Y gg{O?B$õ=)^CZ$yrgCr7Yf '[EKHOȵuJ~ D:BԏBH{MwyRZZV;h6L73Ȋɲzl~N4hP[R Jzd) tv5H" j B&}v93$++K^A9z N3y^>N<ϿY _͚+/\&m& I)9?_*Sᎏu$hFbP'~޽{gr7*<VCC nxS4Dx&Gkn(?o2>=S7[w?_$W{g4njq>Ⱦq\2 |ۊ$@5Khg$P`T 2D}JJJ_|PN*`Pip= WXioۡC㓬Fr !dy6j/sWRh i℁ סs .#f= $@5Khg$PV\)gVoFerI'TچsRPa9mk-VJJJR#Rԭ؃[^|;t)֒H :$NfRs@ի'#GQFIw8˭i.9i#E m $%價+%琵)M@ߣ#Kia)t~6)zdR23j.k $4@#5 @׮]'3f}A/_.~ZԣG Q>,)Ih526(#Q_ dZ+Ut:Qvm\+wHۆugK]k/M[ȧIeZVi^~yRn]V.˯'|1[0OgmZy@$@$Z ֋c3eJi$l"3gΙ3G <ЁLl|ywod_ylyB*zCr'(Ns*4h )z~k$ךwzQY|ul~HNW%E֢ X;wFs'}1499} qF}BqGYm;W7)H m˴X7!00`$82R*oIg )cAa?D {voK,lXzѲR\.ȃOo>y}-Ju$@1ACbY ֭[妛n#8B:v('N={ʼydӦMr'k.7~Æ ~V5 gr~a}!F=BΦn}Oc }0 … 孷; $@$4@y@dr]w  $|rw x@%H`dXvf]e6sVj\?5UWqطdk[V͛vCp>~j{V^-}Q/h 8 ӷ5fI r)O0űxiҮ];޽ r9#.<}['%Rl|"Rǁwހ.ڎi§UvZS;Cm$߰A}VMw,A/{'˖-SᅲN;-: T *cV'ؼ}رX3|ez2C~ au"lBoU/&̑ى꒫J̲aud SzvPι\4+>IޝY]ZD.b͍3.4THBjj)}W &@4۟'G qe`+iI쵉 6T+7`=zMqכzL!++KzK6o;:9)Q9N-Ly pmj u%o>(u/8g5ԡT]xź|z8x衇d„ j16ydyw!ꛖ$@ECެ- Mؒ%K_~j(sIǍ'+VPK Xh o2)Nd3//P, -PEyْc,y q>ȄlW'uϤg>7]e˖~Hh ˪㏗5k֨ɶm:e2gJ%{ͷe-%fow?"_9:T2@ ,l޼Yڴi$aN( =@$,A˖:~x?s'R¥NU~LOzWϫޘ_ $q}WsEZj%< 0@իܜ~gլ#D4@#U D( 477W͡45vRnye>dٗ}@7(bf/K.D߯&_֊HhVӓ DfHKy.:Τt))jri㆖].*]%r/>P,Dc  M=o Jw ;KDI_x{٘ύ:^iceX7 `hR2 @58G;y?Ym-%Mz+v]Ҡy;Яw5kVlhMמ D&ԈH :l V3O/?~W@NFXZ-'o0*&$4@3K!'G<U߳](|9G.\N[Dٛm^4$⢐ȡ "I9$'erGKͣ];wS'n4U\\"sPiGʜᄋz\ =gvPF.4lh)H 8\7"$0m4[eÆ 2zhycC GSl#mؠ׵@N6e|֪jmğ,ւvk"!IH@$@`h0ԘL3HK/.HF!`=-].2Q)^tΥj{Fq|fڲ|G2/"=)tTZY _ 6  ¾}ϗ>@5jo2rHu ˔#xE2n>&ז>D|H 9fNn\sɦ-ۥe2*7CV \ɝ'}QOu(tt}źmU.$@1I=1٬ 6>aO)gym*#.,} /f87,tCS< =4DM !^uk{w?L? }Y\SH_ɢ+YF2j䥊]8 P[Zb6@$@5AhMPg$`=#7I&M{˷*:x-77{z*-_󦐒oWn]oa@ݻ77ʮ{d<5 Z߫n_Z 1^Hݬ B tYFh֬CH N ӆgI {GZl)w} FN8h {N8l~tj#zQ '=?֗Cr=yfiܸJ}I' @-@ ٳwR R͖g%Ǣ&Ukiktٲe駟JΝC_/J$Z4@8 T/UV… w/ʱ>Ń$7 ]Q[O,b*>t؍ w><}yeқt1mZ4& S'v)[n?P.BرcH v ݶeH v*~mHeFAbT57?#xzmڪ.M"g_&=F ﬐6T|4ZTZ|s+IO?$1c jРACW_픍q$@q@h42H$~0"{ <_m6!y ӾZ'>+~,ZB7m,7\WB]!n'p˶mShb n\VH~%( Ƨȴ/fгOӗ''WEHJڼ]~ҥZm @ ~۞5'!mאּ!k+{ Ea=\+gq~ N&Lt(f5IK _zno}9 6)S!(H *f$;6G&س6ظ3g ! COI& yL(./P>V= ]BBdrLeyʯʱ]UU&< w߿_4hPLK$hpj$@GIQ YR-:+>rjB 4>k<$%@4rۆ@@ϛ/BسbHn1ԋn *L6֪U˘YҮ8Յ?mJq%rw(\m^8 w9Nff '"$O:<& pR`H lT͞*}{wmZɢDjou)\G*$ 3* T@u+? 5;ƊQ4 @MGI dee >'pr-r%*]n q_~<2gSdhsl34ydm{y駟.vmޠ#H" j BJyȋ+*EGY(<+04''TzM?l@4<\)H X4@%|$@$---E=I nfEIxҪUJ+иqc߿C9=7dau<Ħ mڴ~U6JߧOСCPy3Y% $@$IM86I-B]HH E!-j/3"cZ<#pz$@$Pug:CJ %IY$@$hFdP)c4@Yu'իW9ڵsB-R~ϱ̙3SOu _~+\lYx}Q e[Nl٢oꭙ)޿{=zk֬M6I^QF^dŊcݻԫWtR:w\u7?|y@$842ځZ@Lذa5J}>lU7l1tW+q>QO:Uy5kJ8/JǎIz)i>Pvҥ~j[#eyGʹ뮻[ݻnN;M6oެ{>sԩ^xA@Io8oڴ|wjQ,҂+Tˤ[nߘڼh]+phHM=n< wc{O Cs׫Cݓ 롇{VPcڵGQ!D|M|K/.H.NeW$#y*ԩLf\p\:@?xb]~ b~[93f:?t2Jٸq-ӸV_VH' 'Dq$@&!' z1̍hprJ}*0`7}M'wyG~Ge鸤$y7'1|y<ꨣdZ8p@2?|pg' D/rƟfk:0 "C[zmnF<@İ=#W]u{#@D!G뮻N0w-dرc)G)E@y $@$KKɺ@@}EsJ;CXؓ)>J@\jsU")un˖-ej?}*Νw_|۶m^+p =UR4Lt,c  HZtI_9V={-<`0öG:` ^+zW觜rΦW&N0A U^ zyO5i0' `^?oÆ S21<3nT 2 &}@5 ~ T ,Om@VPRǢgLKKsO`%}S)i )fU5`&UUmPG* _jO?c 8%8mxVji| TN84 S<=!sZ]G`=]m2^99أIȾ ]pp&$j$@$L&{@1Eu~i5\#un/ƒ@/-z %4@v” k&MB?.[&!@4vڒ5! #.2^$4 TLDqAs@㢙YI x&όXw %HHHH p#HHH HHHH ph@Kޏ~_y͕#Fg-su~/wurhQV Qc$9z,{z8M&pe9k,U]/uĉwނܹsUO*zG]иqT'9uV~ {@C"Hj|w])֭[PQƍ+l|!zz)HdΖ~M`tpQGIv)IHB@h R @$𺓕u>m۶KH_^=5t߾}:XP~}S T *dv #0{lқ7o%> ڵkP`Νj>>7 @ phR @4i 4H>tQN>dpm&wOڭ[7y TH" Јm*F$.wZpTZZ*s|gaGyD=˕W^)7npC$@$w3&%2==]0-8 yy,Ljذ #sBabu< @  )H V0>QG}T2226L~ԶNgyf֒* @d"ljE$X-`|څ VWڷo/ϗJu  |x15 @;<'aoQ  ZF$@$@$@$b4 @h -OJ#   C@&   -Ii$@$@$@$@~$@$@$@$@%@4<)HHHH~1HHHH h' !@ F 4    ?hh    ZF$@$@$@$ P?M$@$@$@$Z4@C˓HHHHIHHHBKhhyR 4@b4 @h -OJ#   C@&   -Ii$@$@$@$@~$@$@$@$@%@4<)HHHHd?رC ")))ҢE ۔۶mbxFHOO&M_9ڴiS4l.ZMuJz*\Rݶm[Dd+K<4@h9tP)$--1 #8' $&&:d H+YZ#HFYzr<13#kk; %   %@4~۞5'   !@FP   _4@Ys   0XdܹSf͚%֭O! dRXXB!7ߔ/\ :uzٲeruI^^W%~u'$:.|OpS*4ק~*wy /bw/B>ѣG FモGyDW5Aq{r]wɖ-[=v8Q3FȊ++۷WM`~[o͛K>}[nqG!oXիW?Oi׮o܈L^F'~ೳ#UŨ yƇK/T.2G//QQjVrx@[nϮfMb{ʤI^'ꫯ*W~i{8 "~L2E.))I>39rdsΕO>Y>#uo]x[oDE (\1+[YƢ+Wtfז.]tI*D'} #L c`Fn=܈)Z]RT qҨQhN}AꪫK/TDYiժ;ZzٳGt"'O=zӈP0wqۀرs9QTUaƦ) 8Pڴi# ?#aLyv dee| {|jZC3'p͘1CZc ("{TO(uU2pa?ǫ8^~g*/( s`'ڵ˭=zE;<9t2LG}xD14@3b%%,z!0WZ*HoM6!CanI-ZPyƍUN~"ddd_^ Oҷo_С ?. SxrQG 7ܠpO!#8f 81U xojR} VZaO_UR #cA`ӴiS5+o*G 33Sw.خ=tԩrZ;Xf{T' xɪ;)`>1[9ӡ `bH!0'1*v`O70̄U @'8'L 'NTC3dGO>DQ0r0'yjӕ+5%XabOLLk('+kՖ+nڵjGֿ2ƪ#<6 VOƐ]0ri=4h [U#Y*[m֬sBʄ9=N!X\uzI2\`3zƂ@IDAT0j(n< `h`H h|68If:h|VfK@''+4>+h%19 … +P9$V9^LM$@$@$@HeWǍHHHH$@4HpF$@$@$@$ +Y@$آ)` Εq"T%,tͭyxGbWmT.,++ScYf)-Z* 9¿i!l:p^k חlS$''G*@`4C;FSزI'D}o>h 6u`c~}V8pVo&ݐ[ǠNU`̡ |:}X➁  0q_}}SsۦO7`p_vzc@gzqqqXU'ܷ&b Nb{ldz``ݳo.=OtkҤ*=Mz7ia{lϿswSGܓhxnHۼysuOڵ%0[ozw1dQO<)v}Q1&ݠ7v5e7Mnc^=on{w{NLzڦֳP*[M ⮻SgX 4@c%Y *rٟ%uSK~?U*Is+ջ+v,BJcτ|'?_.%p5`/7%i_.Dm q( LšԋL`sZ`&tC ԛvvqh_S/?'dGۡ\8kжsUtg.lsXn#1A$˚M9 lX} 3sEjJtm[YuzN+Cz^t,θwE n`VY@|WϡPG< N پ2o,qlDzhzmq_, G3@Θ1cdܸqW_ɜ9sQiV#Dfx  L/ 7 iN6p:*<R27S!xOF@XGhK]N,9}|^6 7o,2N{pY7 _T*_*ʆV}ŵe!'N<(> F3 m`2,KMx@l3CGWV7<G;ڵ%0eVumdC<}4Bg*O$  X*uR`dV ɉ.ILWH",^!h& Ok}Gi?8[2rcǎxbfӦMjW~扶G[Q_ h]kKv%ɭ;SYZh #XFM${ D1 #!U =Pk9^bر1g1 ЪA@$La!6.Mջ!y:%Vjs@CaO>Y}0߾a/B$^̭+ ;uOM$gNk]$kWM*~j4X>\5IRZqcM$0L0T^uE0aK-;=X#$p|"..wWZIK%^y^~(,\rOơ $@G/Fqi]Vz)iӦM9  5 =:U6W*3B+O$`E|Pln ߸7;o<8pj̞Fc[lM7Lnәg'שL]Mѣ\FmG85_Zg;:=dv*3>:Mzj 뤏m2|q7𭏕TgΔ/8S^25#- HU+A+LekyoD73\I$iLy_@>:&:I78-OkYNqHgu6kǞ9qr={< So};L 8roʫbuvʫu wir2\0B~ˈ;W?r-2|plrUW9n+xxo xaO8_w x|D7מ,ΐm;*z E h QQ)#v*}r>[g?ANB÷XzzrwfK .&yM.<{\=`*Ι\ƞ)Fڹt*`ܘt!|0BI7Tz7t{9S%7*. }MLq4qvCN(h;yN},eC!dzeq mF'L."|Y@y?t&פhK'p=+F;عEۢ B,.p+E{0@yvtv ` GL%t=iזxM#7,{ް{N`@ܚ{;Ͽxy<='N{7'IR$1?K@wܩnjm8mVaϞ=^|3*<&d:.xA#)2F˩Lx I.^j)u)x{7t0ru^_BwGO|< ה?v'?N&n33Xy'C@MP>!No<8Hgρ]a2@p jR"H;ܽ ~ߪ~X#HUB$@$@$Pǘ .9CjEDqzG/]w+ =>hD4     Wh|w*x#F/\@$@$@$@\E**ssPriHHHpV(,.ĭ_ڒ E \CA);hN[&$@$@$@!$P)L5ܰHHHb0)  >WITt^ǷaK4Ho$ذش)4`a}6ŦvY]daC`ᱧl\ætzl l Ne" 1AL\ȏx9鍼qN7!|qٕuqZ_2XP)n;S%{ӂQUt|;^.Ne, 8=':KF%Hn`{G נHx1tsP}!YĹY{Nezzo팺>2!N_j,8Y0N(S|wz k 고@oߠb]@=!K=W{RLu(O\ C}xgLL`! E`bC& h[+Ltbvc ]80($ytC[^6n8DP7ߠ9='> (cr@gs_==QOmw KfθwY3e,@WěȟL9C)ٽЖY@]db@'Sgq/잓@XB`Z7{ ,QnFNqk#:,~3F7xw 񨓊&#S_78D]S}4`tl;ݜ4Ki*Ws4:D]vV?QyG_ݐN7)vqZ7x-WqTn?2qNIOpY@8;毝+!vqe9L:!_,XiNNqͤ7z7 N.kvqxNsSmL 8kpVHHH2PiEٳ+$ի4k֬h@4[: z|R])bJ̙3eܹ4@Tx@$@$@$@H#J{ aÆ2}tws2dh?`h '   S9uܲJdݎ\yY)ҦQWrk׹… eʔ)l2$QyhT6&eodhpn0)H@jRdoU-Si+krm9ĵ#-SO=5@x ݒ"*=)rrnK$@$6ʕ_6ﯲr ^rFtyf?訾VnGu5Sg_=E1@వZ8 kzp|vҤIrEIݺuH]I1clڴ)Zڒ@ ֧'Wh k}@q$@$.c4\@ҿpUF&X`+ԨJ/|ΝeF^xAx BKv}QG<-à l.<àxwly}dꍈ}/<` SC u۠qzCa%?x|N7'UM{1q1sbzmlKݶ>)^HcI7TV({U,-O[bP`9X< `eUtsjg,8g\wYnvpi-ML7=N`u ` Xu9yUyc)/M;w,owqAn(^?~Fh(^nٲ M,^vqxu[ǁ e"y./5š:GL2pN>@sEEZ9G-KF~tQ/2I.*q,tK⁓Dn)fZh:2vUu^d (Sߗv9Az0,Q]^ȅ^&:η皥{obnzs^tH-7nS;vLuBςS2d#)v4s;-2ݽzڵ~~vςSnC':]¥t+өBMy/YcX.|ia2W_R̜ǝ:ydҥCVZel>:ٳGrssn|zo233ZӃܿ<~qx&?4/؜lРc/\ .s ,/z9 L\E\na67ӪeXZVժ="v}H1~Ѿve:lԨD]}^}p|/{m79JŒ^zPqgYa&ER/!bQ[W M=kA۴iS',{)@1a;+~*SM'ҤIUg|tC{ ,ؽ;d^w0"FoGS?#v,t\ܮ-> xoI_0ƽ7 hw(SL dp ϔI7 pٽנxx@_kܸ*9Aٽ;PCte,̡CʴiӢ娭#2ƧN~_,ݙ(]co.b߳6ǿ zf·veCݙ `oT*W~Jgd @tPᚩ.с<~b0B>x~G/V(z>=޻`xF1|{uW}5]dH %4A'ES? S qv'I^ ; V~8`#Il8T ̸3@2#@z%5WUnb[vYq[Ma?|5U(ی^ab$7JUu\BS*&$brQ?i2ߥuy`&r]ve L \ae|&'.KM*X1PUV".H"y_G {hᒋ)~jWߊs>SH Y w6jz@cر^|^~g{Cvz+ObV)O<ޒ*K9ƒzm֎n[ZoMW޸XJH?SC[(ur)nkI\ 3S" A`dٱPj'$ɠVJ q5=*ڄJ;v… XHuVdJߎ{Թ3 j |%wJR92^ڔMPFQK?1W1SGKcKeHM ?֨XyZ2tK*Z/Wdj?ԖMIɫA8e$6"`'ޗ/\hyr9ThHt0@ Q ގѠwuxRYo \T&䶞]ԫ[(+5 6?pWx rwR6L/ >rsrCsCKxD5AG~ṽO| ?&+&V_e>M@hEH}J#D[soʦXO{b̨Uu1&k̊ݺRe=+ E5[+<^*R^HC_0L'X=%Vde֖v<vvqy,Nw\Ox 62xAo5 F_Ȳk?WU^tkYq/T7Edkf.ZI-u}wn,-S4v,q. }ҩ|8tjKěu3!S'md Sk ʰkeոN5!R1pEs-2!BCNJ/U7!߾7M &A׵3FO7,0D?S3f6FO=Ԑbͭ|nv\aX8(azs@~ݺOw,gC;!zˇtC0뺮8 ȧz^<^Z77MnK`hhQv FOeuyiiLh_ 嚂x,M\e. CIoOڷ^gl߼{Nt^<%ZӬ'DºލCp[~jQ?rMtAwLmK:zpZ|{4@q#Wu]>p9zhy饗Jy Zk23Uq&7adrŗbXb\d 7 Ly :C5'ES~)n&Ev 4?/#DNntP'Ekϔ49l,O!*vFJrlߝmmUqsbF(Į>Xԉ{Υ%ğ+NT =nhgvz,NxM=ɥ%tgsx8}lg?ۧՒ-%+@ikށ3@vuûwo d7mk@o,%XςtXDǻШ4@@/X@fϞ>?>| 4(th#eKt/Z, njVVB- ӆo^bᇁBIY-=+#URS,÷usKzJvEҴi-ٷ*-~c:|wɻ(O?tiq7CW!ל]0^y+(^j߭/_'o>0L:ҧʼ]ue eos`L5IϕeGyjB7y5 j]pr?HAaXê',Gm际$Ew)ҔiRP [=jk,SD^^ uڳdkz:Hӭr%'$@$0;>3f[o%7xrŹf͚k6(Y̍zo޹m|"k\l(` +y|<>{hu7ӵsYz$2d[/Jm@`ˁRsfuag |XjW(Mԑg_x5oJHjpp2r^Ä䨉1+;WjWgϤqUPNUue|d_װOgᐁ*"Ƨ[^.?M$M1xV'0Aר4@yG ]d\s5e3N+VZHMӲqۋ(?k=xk$N @O&㐀L/Wl6 Lf. Dzjͅz\ݼy]l8ʷܹsnݺ޽{e2rHi [dɲrJ|])7̒Qw.9ھZ=~eb$,1,&J.ze"ڜ[5L+_8GT$@QH6b93p@B,5js(9{vEqI!*(,( 1,|FH 1&,(FT *^E+(Jopxo9yݩgsfvv9[0YGy=93vaRTi\=5c>wR-xe'~ԗ_/';w=ix%稶!ЮC[QvV 3`}uZM]Td P C5h2NA eh1ڮ];u饗$X~>}=yU1 Hn% /=mw&m*_?ϛha|ңG5vXǗFJ'Z4S#[i6S_|q[n1-]wիill^a;[c-{tSvş25F#OiݰhybctuޘG,>X;Ǩk7+}1Wn,᭘\L QrY o!W IX5w?mT$.J4>n~+5f o۵jHOo^[M,l 8;3YGss2q\<)ϖ-[:mϟo y9f[h-Z.\hlp%7%eKKDft5'ڧ~ㄼ`5sbΝ;Pܻ(7ddg)||jiB9=ʄ.X yjS]5*Nk ̜:>Qx[guL'x>]|ONAfZ-W^ȇkYڂ_h'> ||$,I=.FXVI_]¿o0)-o]}#vBSNIKڂ'i"ʒӦ\7m8ѯ}|OP7X4dN_AciN^MA9Vc:Dټ33f.])S( 7P9ZV %IY>F}ձ'Ww_uq?s R AOx?]roRh:Gm].#.%A{|b:|l1 +VU~u7zذaٯ{;tPU&_Ͻw9@=̋Z3K`S OTb E ?'^v25=OU=[jڛ1WN -.@ ,3Kl XwTݫ CH=ꨣn <%^|M} 8Bav]68^+k&LUMPxX~r(ϦꫯVٳ`4iF8=WY>X <̂kHYDF`bm?~, ;WgV'NS+]UVi v*yJ(}|⨓ E"PƊL,=nǎ yknVeiѨ}{obNRҊCW聧Vצ_05Ꮚczj%e nd$A@ϮgKjmIv%\m!jԍ#3B|UN?*j'k-z@S;t]ϩYOWMYbUrֺ`R<j.%z@ ^-Ole%x/Qtb3̃ok:wChuQZI'&zY`V|wS֪S w@IbI t$"P(t=+U}buj?**rT_ I/6)Bx#L ~]|ӧViT:ilK F݂Ηh[𙴤 }K|y#]LqRߴB,'u('eIC8+dׯ}| XS9& ޱIm<$!!% E~XE%*m0v~_xϽj~娷  @1V_lDTVI5ӦXa/RK  OW5 Y|''^ޛh j_6K}8 - ϻZuշz%3/8Yr-i  @}/VoݧܫۖjQ?q 4OU)SK9OgϜg/'Sgcd]檡g_h<ؓuUv) /rQ[jZ$躆s'Qٲ+('Jo/IE:BAćm Vݧ|𗿫+  >T/u[o9s樾}&?M=rf@-{ IӪeYT![* Os {g_s2s̸ j۫kYHA@?rܥTju9=7X]}OT{:n՟~wS]7Rkh:ozײ&OU5KJZμb( T zkHB%G3gT ,P7tcǎjܸqU9-T\a\] kɦW Z.=':vhgT^EX?[p5UN) ݟ?]hΝըQ;p .̆AUg#I$_\/>~pgMd?}mW׊'OAme+s =sfVi^mYǍ/ҷyEZ,q?7nm\l6^-KQP]NI$'?K[Ogyp]4 ߸ۺqkݸg yA|}W)PW. {gYޢY&W-}We(_oBe+Òx!?bɳq%}oP!?wi Ž~CyWYȪ`*Kh]?:c'lZQ`vtĈQ3֣nգ?b,갂~U7yEb@B'#nU_}=V}b.T]$Й %#>$G@,CIzsK]_rںfeIP[):t:s;Sj۶ ڴicZܙfs<$L2"̰a.>KKXr |~L.a:;N@|}zWmֳ gqĀ`?oNپje#-[c -|&,Q?A.p'"|%\f3buK6>tP!3sadp)FA }אyWFBXկe!ޟ?C˒~ Q3< 0!W<-lj2%O~t*4}r{o>rҵyR wKr/ϗ.mB?vZog+]+E8ֈG=ɺ%nm>,{VfDᇲNm:>,K_ q(/;ad\ڶj'VޢI|)Wgwoxq+Bm?K|x▃2RJײ!_Z&MRuj]KPZ*wg0y)3<93V ف$^ɁX% Tzl DK K/>Z{w=#To @o6W 2Dm{WYL75Vkzt\=и8_Qb0H!A@A&=W_@/ٖp+fC܄]wK{WrѸk/T Z M ?2`mf5SgA{nE=B+eA@Avٶڡϖْ-XHtף7ۯv߱W B R{ߟ6ˊ.}ų/ 8`&[M~9K3afzwjqGNZaЏ\t?nV]v:Cl]1  TxQMVl/J}w>O6Mj=#z뭧ءC j ytZgj3C*` RwM|D}ګ} >  T>}, ml4ou]8shm6R~ @nhxzuCG Џ|;[?;A|1#Pr'@# xkPѠvx{G}TSe D`ҌcL-L4 t.jFA@r@z @K_wv}w5z=Or%.aZhuE[+L+A@~8NF= 0 H)jV96P'S(ʃ#~%`5 ͗7@SfeMbODmSKH*]~.7Fp}a4O/Fܢt}GF]ygӎcCD{{y٫ujBiimѼ|۸> Oܓ}i<ٸq-2(P-RlV5se%DݱZc?V;wv"O>,InO2Iduf= ٳL$ȗv)'};iڅeo:vg5 %){XG|}?CXQ @6޸Pvo+מե$iUe" @x饗2z`yWB/{_.p$Ԅ  zqMw{衇ft##D\soz!Nw6 .GuT7MB\o=7yw} .^{mf-L8p`欳r{\ 6ox&\ )^{6l믛<^:_#2<'sUW8\vmi$9nm&/)X)S zЕpqe,_<$n)|ə/)=5;6/a&hJ d?$wyO&O+osZOW^.Dw1sy%xg ^υ[b:nYne=4,lOF ӂ  Y/56=Z$* @cHo(&zy[[_}>={t! +lB~ݻw3vd?wޘ|c[lj߾}>̾+:^: \{}l86|yڏ˺#Xt:x3n%m6'ϗ}|^Zxs E[dMP8mGfVػ o~D=#Ͼ=o l!} {!{i =7%` o|yX>셆7d4m{i ɡ[cFG/%u|c0m4!Wq>^`a^kڰziب0r&U % "0?^l2wpڦwĪQ૰҄eA@A@Xs,AlT.%zKM>,3FQsϙ뭷^β:@K,cǴiӲyo\j`(˾a{׺^=ijJw_:F?kN:5Hug(NB.Y /Piu3z{lN83@7%\baz'Ovu Z5ys/LxҢcI%2 <'S%IN:$aJUј}P<)W X&_ˤ+KQ}{gVc `&-Zȑ#Gm&gK.A9Ѯ]}rVުxQה+ Kl%e>XVLN`~}r Vc`gxQ/v[E`T>L?'IXLeܓKW}2 K_ߐeHJ%|D߱P7{@. (jb̩A$z;Cɠ _Y~;N9⢛,Jx`F4Ez1sg{챬^ t d^veѣGgO?̽k`4s 7d7zѝq~3zmDz-oYiX&_PeCafvmHI%>dBi׿{Yfe3裐\DN tO0< 2_& m!-><`ttA?K!j ,CyR$,/$I`$hL82 PߐeHJe>2-7ݾ,'V([5/U 0%X¶_T,u\ KXR:+Xko6D`fԨQY',0c1s [KܿkQ}f:/fHw-bǴ`fTw>,='d^z  <6ЧO2ML?<~)P`? x( hd.t|rIlx3CO.d;ǘ1cr!,R$,C$i|iN`vgf>VʘOˤ<)xˤL272I\ O. OJ%Ґ~gfW6:L{gvaeKEP᢭Uk%2ĉ ;G4,DU|p^OK̰E̩4xh Fŋ<*Xꇒ~agQ}hƍ3KQ2M>,ϖ,p%D_~+ʦ4XV 𱢭BMitVZLW8v_Y. Kl5iıo2M>L?[\722ڇ>L7SZ,UJ,X[y_Kz>"4XJ]-qRe)*Orse앏Rc`6Oi/.it PJ,Ӽ\27VZ,Ŭj>:,Xˏ|~x-32,,1F4Ԝd^Y<3`th"I,+OfL9mf—,YbN73e_̎B V9'3s1x{ԩSMi"?f7itaT` vFCg;C^X\!Dd#J.L%ˋ9ctq2_,%J%[e<}X/: e<}r|reoHeGe8za]rKW@IXdXF߱]82ͣFYFf?#_3.%ǾLͤfvSNQ,I%fxpO?tK$ zGUW]2̆A&$W_#̀r&I'>lذ>UN3-Wc`&OIW l˸ 4$|>Xbf̙jΜ9fY@3ֳ,֡+2 @)[8y4X"X&ANMO$bi<[ʉO4y_tkx6ieR[e!-Iro7~M2 K_IXdXwl}_eB~=})ꈆZk&=Pl-Lޅ#2HeCB#>*}2RLZ,U0 O6p̦ }C Qp8`$} @ȃ2rx%2z!a|찝W\aL%a铭$KEŒ d~$,CXBXꏃeBr'IXYLeܓ\>$!,C}CR[VX[|| +ն}<`=i 2-X:*N 4>EX$ŗ6yF8띔'a! X3BdĮ/4X2b9Ukߕ-_8{ V\ k*eRLۗ5\3b iL)M0Ʋrb-rNbt˾/gzWhWY7Dˇ32B#7  &wMfڴi>SoltYm>UA J x4o\Em*c]d526F5oѢ?pB 6JkfQA@D@E(AxDzLϞ=[%|͚536y~R,WA@=c()@!p7駟:t蠶~{cyȐ!N3IrKuf(UY1]A@*Vlc P.ze-]TmjĉeÇ#7|;0{UVY\H b\ ,/ (6mXGҢE("`R˖-3T20t @ hJ PJ9Oq9UW]ըazN R ˂ T&r2E2 xT.1ѨQڵkz)CYP_qA@Y/ -uKXNB @ihiA@A@%[A@AxJj   4 A@A@(-2--  @WIENDB`egg/tools/README/layout-1.png0000644000176200001440000002634513367162113015307 0ustar liggesusersPNG  IHDRz4 iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o(IDATxۏ$]ٍٞk'k;ɃC"#(yx@ Q"qN:1en}+7{LO9սӟVSߩgҙNU/x p t_uvueGe}u }_J;,0^} \c Paqu9 @hS@mS\ @>=@ ЮO@6 @`~g _Cyn7t`yev?7Y-I+Ž~߂oQ:5t´,~gUj#Bϕx&0x<>_ͦ!iޛاW;~7Mk{a0X<lМkG||\^GGGK[6ދÏz遫n|[넿;Ka_|w[`O,T:G?|Ρ[wW߾ut uNz/U@+U'Ɂ<=k/q[9Cif>jlQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @Q@mQ @(! PՓ @QXQ @@kz?/tV5@ׯNg!p^?w*hA`q0N[vS@uwXY5 ?>ןz#ܽ ޯV>wL5aV>ƎJ U$jԷPҘW0uݣ}N&'0W>Ǝ ԋ @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  ! @@Y @ @@N  tNNNhs~?{jٰ?LV>A*TqQǗ޵pzx.5I;_{h4z{pzzǨ¶GNF~^})cG&⍪0i5 zufaVu>OEQm&2WO;?>W\_yv+ҟ5p X$؊o\{MGk'PuwgG~ @mm( @L@= @@h @8@(|A Іچ9 @3 _ @! l @3 @mm( @L@= @@h @8@(|A Іچ9 @3 _ @!oct<^ H8J:a7;ް~͞ٯEV&nh Aue… \ tAoz-W_򭧽вԋ <ܙ|nQͯ_s1;v%['rza}KN¿|]lZPh~+5 @jjN"@$ fԆ @`5t5'{ @d@3AjC  @2  !@XM@]^ @L @& d/ @Lh&Hm @V@Ws @@&46 @ 9ً @ R @^//^nb3>'gA8 MF_[}yMx5.2޸w5WU8.fYޚp9N/|d2 O8m>ZU|%~oK<hia  @@0 @(- ֟ @ @+x\Y7ͯ3xrGO9XG[WCL\ꬥ+ٜhsfZt||| @lh4 ~t+I @zu֕ @R@eqR @+ ^ݵue @ʿt:m%"@X t4ũ/:{ @l@?4t:֐o!@H&y  @r E#@H IE @hnQ @hG @ [T? @Q$@- Տ @ ) &y  @r E#@H IE @hnQ @hG @ [T? @Q$@- Տ @ ) &y  @r E#@H IE @hnQ @duN= @Uj/~*q @ԟ!0N^V{ &:mlI`p#τy|A  av|[[>W{s {}ƺB;x_uFPa2x.yz}irs4sX?5J {UIc]8 | ߎY ܸ j wzB8h"P{a}qa4Вk q~ƺB ׿Ͼ&ϼНG[8S4 0XǞy:-g^ϼ4 @N ;. ytk  @;% rX @ͯ3 @씀Sb  @@7΀ SN-%@l^@8 @N ;. ytk  @;% rX @ͯ3 @씀Sb  @@7΀ SN-%@l^@8 @N ;. ytk  @;% rX @Mt^X㼺n῕+m<[1n~/LO'KB7C.ؒCo ܄;~\͆v:uh<_~}~V ^4=37BxVOd/iT3{3M{ 8S7&^{˓_,=pՍ7υɸ=]ӣ1@~Ixo?7gc@Ƶ0p|||nEK`6wk?&GK4=6.A^g`̻_?a}|]Vwc/ ",~ʮ*{,֩ _c]4Uν2O>oz+||~Ν}wBx: m\2nQ[o73}'^rŲ?^sErRbfՑg^+ og{?'3bYQI<<{}99M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$$" @@n4~ @I4ɣH [@- @@R@M( @@sG @< @ܢ @$:'''~888&.ap=L!<8|؍ 6&uC>{sxꩧl2 ռZZޠfy8<<<7p8 (LOj6+0xv;]ϼq[?3eKN׭רsGwN gisKs[?0" iOio!$o+Mj,7޽sOD*\7tCzV_Z=o7e3.''wο.߶2;מؼ^/?D4]{^{e7_7^Uٜbx3t{pIxg?y[1­ N/?(n5F oM=|ӣd]⇄Ds4O7Z#ŬF _}39!( @X_@]Α @kk9 @`}t};G @!  @I C @@׷s$ @h!@X_@]Α @kk9 @`}t};G @!  @I C @h#;NxكpcW·hgƫd:k+uZ?J.[^nx˟^ Za^bY♷^t|fO<>޼WGߛ>g&V9N>~dBՙtӧbZjP^[$l-'boM3ZF}OfmvM>;AFXxFa+?bwϝ  @-s <:߂ @@4 @ [ٓ @ Q  @խI A@̀ @V$@ f@Ԃ @`utu+{ @d@3 jA =  @2 @X]@]ʞ @ Z @. neO @  =xivxqrޚ @w4'zr|z^I+ @l"|NZUUF @`/$@\-j!@lK  @WK@Zj @[/ЩBJ_$@xb~cYIENDB`egg/tools/README/ggarrange-1.png0000644000176200001440000013465413367162116015735 0ustar liggesusersPNG  IHDRrxn iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o@IDATx] MsϽלyBH!zKR!Wi RIETȫ(J+)$*C1_u[s {s>k᷾{ i˗//UiRJTT)meggʰe8q*]4UX16vܩ6+WF*U(33SǏӡC|>ըQ# ;3'''lٲTBBڵkWPvx|o֭t~VNYYYAǫWNAeG#GߪUag޽T^|y*W\Pn(E:~ZZҒ ܠbL٣- }kرctam3|}.'/xBӒvQBVmF7n&Mo8{n A`F "ʑPT#hF`#:_bhDcɟ`3)>[#0{tgt0>C֎,0#0V̕(VTD6fTPP`vB],30#` 8ycW f̍#ᮝɓ'Kxqk}>1#P)S&>(#`B%+! wvz6zhzxu]6Xц6lz7F`n@%A,O&F(Fl){={v۷o}8U {ի@g͚E{E:c jݺ5 A#0Gf͚L |pfê=Cs@eG$@ZBҋmҼyroPPE$%*r#0Me~Wk׮哷A 4W2MsL0xb駟[n)Q F`O'`^o`c=s~3f uUڏ^x4h Z`Fy`F9%r$C8&F(B`ǎWYfijڵKnZ."U̿#0"}#9eW rp%fc]vD`j۶m2+R38`0# z+P6{Md@SN1!Dyހ h`[.mڴ-[DӄF`B+R7"@2B N5OQ —4lddO6G~a0SNFw}T;#0CQ&Fpz5,\@89vXK0t}2o4rHZn4p@j޼9wy%p#03dddvs]鼞vu>Ā@2牏R&'|DHꫯÇB!CoI&#0!`e ҄gmaZ JSq7IjQvF^nΝ;Ɏg 6;7nQSc1#V\i§[/iT q2`QWmev`&|bI&,|"`~F e8zLb4aWz1@#`7BW8`n'ϼ1##K+Q%o1@^TƊcFp]i 6q'o!`i8lGi5Y裏͛ _ &x92 Ξ=:uh O? #0}8q̔*@>x 3/wkUN~mzeɲիWx`bFH<*U$ `$ǏOj$6l]y^y啀P_Gѣʐ]cԹsgĎl3<#3gΤzou_|A|m۶Mis<^upTG:3G!”yTޣG߿,b-)˗/+BGw`^4Dz}zT12#DVg&`\"f^iym~07nFiӦ[3Ϥ!C'P p̂eh{}7`y½8C7O.cF-Gn9G#Pr夅ЩSUW]%}' |=z4hʕ+'q_&MÆf7yɰMJÌ~,YBժU30#Ćn#(Km1?@0[HOь _x7<ҽ{J!{_]O'|Rb'R^p.еkJ{Іaa!=~wȥv6n9[56#0nCfMFg+!rx(婊׵!FR@#ǒk2# ?#⋺X@syuf2`Qh`~eQ6m.,]ԕ\wuԬY3WL1 D2;eemW jniuC9H^6!p#0ɂT<&4t§.,\0@J"3 HDeHyl7"F'F`Ff> pweP޷o_p#߿?sgF!@])HE`F:p\&$3'g0KG1kcpTΜYfѡC{e{=Bb&{|[|lki/#`5k6ǽj^%/{Իwoڳgd!0b6lmܸ /]c23rwZy<7F33=fɮ8̄زe }Gh"E]D˗/ /Cp7fܕ6PVX2w@SNG܌4s=c|77"xb:djw}:,y?Wd&BJ'/yc L@$L<5jD_|q$չ#hعs'mذA ˖- hjUcLH5os{"@Fv(4JifeeyMOn:z L#=`7rJ(Ӿ}{2e ]~w-t*F-Wj@ug…@ `Bўk4oޜ4h@tXp=p/@#%s9'}g?v|lܤ6f#R!Cжmh^z4|Kx` ر#XBGJP\fof$x5AA 1A*U&#0Ev裏R.])w2c 2A*[JPXdԃWYu ^OwK>}|֭]2CʕEj+m@9|j^9#*9 aDW @2GÇ? ~?4FH5PrأT;<_"_ɭWe5k2Rn0 ]1~O? +~hM6 e<n# `0[([#/xz뭷;#Q?// $i۷*Lo6Rk-o3^FL W:!AP^w'v̫Љ1OFG`ӦMKcǎpo"VϞ= TVݺuiA7n9RƣCL>}W[Ӕ0&)Pי2CS 6ˈ- sѣ־'7n(PdBՊ㸾!":FQIǵz1駟q*jժ x߻wos|n?A >B=?51\NZN:3m$܌4B)`m{l׎[o ^@J%ЂWůVU/"/aAhZT8dpQ}9!6Pu}Hכ?N"ų( ?Pu:U-W}?BǗh R:E5 ~0G?Сu,^N73^JZ}GU:% ?P xCmHǹh˖-\r}O]+ s娃Lq)U{<'BP+\7x*Ń{^(8é;O*pI&QFhwjE'OLcƌ.\kc++yrH+rOJ ~~PX\7Š(M< y:t(? 0m[{s*D1/n TZCC/:/^XB_ʑ< rG7hګ/ժUSE1'aViɒ%4{lz'vXl۶-l6\k40.ЏX Ƽ W^,c=iԩT&L#Fj>ӫW/fT1n-d>}~^{1;+ṇEouR/x~җjs ~+VRcUZ%M}i9->ҭϵ⺂6^.[|kbĉ>ȴIڞx`,#~"ºGi5~ 27Bɣ+:R?nQ_hSd"`@b w1m^xy.aͮ>1 p:뮻]BĒ@O=TڹsT\ב,b^Z4VAAbޔw/~NO >J%f}̬cXڧW};~\ƟSsg [+גZlq) E.gpTZgiHKfԹ͍O<0}:Q^..r>xQ;/#!CR9pBjܸB+*/^zI.!k׎f͚%4Rzf2?+u?GttWѼ`Rfq/mu7cg%/'9//x=֬%_e ޮג/Fa;[Uةjr`)(ML4Hطo_>Ra1p@<-.K{׿Rp >\G@yES5bOOSCmCṱ;A7LstN.s+̗PUǝA}F u*sv'ͥoN+R,-\@IˈYiR7 q >{@oZPSL,yv;uTm=wZ֑ 63>9O,A}ΰM(SN7n=]jl1c. n/iVxߝr tڛٝ1W# f1SC'~aBUAJ!NetJ(X )UHW> 8V^!x§cޯ˽ߪ8o%Ngӕ5/)QƂ_J' NJS¯S闣.z׮%)rK V/4$K}*C^xZ]^T!|%[!4Vd'sC?V Џ1TիW'Q|ϋ)]}D/j/ F~2|v3qyGL@#.?Єi_ZW$a*RzWDbU%qrş.-K酔&l&0@ `>$ֈY4ـvy<Ԝm\2r~Rl"Fn OiӦM ܹsekӊUpqF` _ +P#քGvɣN/Y%0sf#ʀOdm۶C=Z;֊+7l= Uc}>#0;(8v:IWɣYEuice"⋈Uw C˖-kzC뵋 ͣ{4h@s=ԥK }ܸq4rHY[nԧOYHL#;?)#Q:0FcҎ}UDun #.Ui",2!-GȠ{* >EX-rB/șh|ʌ[nDN qxNP%KHA4A<\!=5j`۷o'$!f| h@C1|># THUcb7/Dqz"5\==Xۇ_v^@We Oa q]g2QD#i5obcѱ}'8[nE&}<_`>@m$B+qnx8@aL9%2ă# Ak$W5k-^9sfPhB5x*U*0l:uhڵ~ZX3x&"@?Ebjժ~0y>" ҏE$rZjMlH`ƔĬcq鉬a*ֺL[*0\l 216 ί`q -]Tx_|1!O5k#V/4J ,`F,u'Ph")8k#gDg/꺜P/U(Q%g:2ԝVI' ؗ^z;9 ]7ovkNjIQRgfOl~N΋fF/f8淚W݉iyMg>)B?!̾]GfNpc ڼH[Ix#t8pB_~eqx,3':߿@%ܳÇ7eύ6u AF`G2ŏ53{tBzWgUW]E7n]R=# n N 1u0:*zq@s^{5xZ.PyK .=Fe4lؐƏ/B(+W6hYE*[o5P*; PD1cAʉ0F gs_M͕P26eQ͵zo 'sJs#F͛GXVo֬\fQkӶmۨsβPݧM&**׭[G_=6%jJf ^ol%TRo>+ z4Ɩ p♏wQ#@*#H`m%H"8¯m6&$QM,5qSCCNgh16/DT c'"?F"px9=<(+ . &ȑ#iĈbUf͢7x}@L)SH%ë)*;իL]°|(_%t)S&v*gU (p#9s ~+"1^1#a+9q[ܿx[D~6<|Y3%Zl1uVjUW\Yo -3c:@`Ë6erŕ~ZI*$C6Ò%zA}U NxaDJHļiM^Xzoڴ|^wut*~ONsΥT?A[l!തP} NI0&(FB6a9J^ܰhp_/G9Uh,n?;eЉˠU ؂o31ߍ6gy F y/SMTxXx;|*Ev4LsI ̾}ʏC !́١-'"{qo^1_F SP^qTjDv}iq@WX!Q~z`A/#fA4oϟH4ݻwo֚ 4(@I&<+Tv(@:J)56r[[W|EV7$n6Eq*_F 0.<(_P+V$L2''L<X 3&F 8܊-g2rjfaFǗӶ47oFU0!/ gS*܊`F Lk7nYڏ; ~hUNʼnXgO2|ǎK|1"!5cO78'3;yuN~ aF HOKaZ~=s9e'O^{!ѯZfqr#]ߠ ]ev4vo|4EvdG?J(knnl9m2?#0"o');h "U֭[e ^kM3UZ=3X~ƶV1͚K9a_kU AcUR%\հ2F:۱̇/X F` $#(.(!L*SOtUu “i< aH[(h쎰VPlܔY*=f5,*F8꺰~Їڌp9#0@r `BYHo$x" s5D؎Z#"0sLB‹.H6kLml28qb y`F uvx 5 'Ե\%16pZCԕXnk5Fx@]pT~FGSg `* I44lU51FACp+VqT'?~P 'wcugg7 D<Ѝ9#@ #PӦMiȐ!%͛7p|giҥk岖-[eILH,eNT;#0Ƀ@dVq/(f3<#` z{m8N HB='0UV'8p M:zEهQd ŗRZr$:};B#0`P17AszYy_@s kݺ5M4I<҄Yfs35߸|v4G/J+]& #0 \P$fP~6=Qޤ4_,ճۦ0#Ĉ6䎅oW猎s9#0@j e?4$oZ&FH.,'zr^"3D M.$y6#xW.CS¡q -Nm<1*ؼI:/a̓oN:(Ӳی#0.A^.`3ET鷀)[ O(;@Y,X@dDdem}ܹset m9o3^G"3'fa`J."B*9%˸xz-;BpϞ=i…oȐeoŊtmц d~ڜ"QzVtr ޳h3㌀l߾ܖ,} GOjSZT(Kʕ؍M6sرk͟?_ ڱS]v2n.!~Ծ}{vȑt9PnݨO>ԥKSof܌يݻɏҵjr8*~Fp1"+Sa!*#b"^jlfּ@Æ irX~_r%~%/ЕW^(?sƴM6Rczgcp-#_|hoжm'?d UB^ A#??5СC?:SؚwH-bg3rsVV|`<#GdP}%3+Uғ^_6ʌJ&Sx;)Rvj,~1oYހ2m3ccHh޼y4zhj֬uСD]vE{#eBA0R(x:⽈Hy+(^OYIO՟TzcZQ;yUͯOGRsFvqed1lXѰҮSk%rԘ 1e4|'J& /;ϥZ|[ L@ChD|C si](id5_K۬cp phڴ\:{-1fժU{q@ Aבıڵk /"׷Q#YeSj{YR"P&F Zr&>6MVQ[ʶ BE޸qc?B+tҜ9sd=!SVG f͚%-^X # f+|V1b31@0v.C{@P,_+'т҄S+t?B`v_=Wj4uTl+|6 KZXabAϚx[ V{0(cԉTf :@`^«X5hPݻ7,ZɠA<' c)RkQ~}B&,1-v`8+a .&F HT@ E(%g>q]g& HQx/3j e;Dؕՠ FNY+|jESvBJ3`C;ϥL 0gpfBT.! 4_ޠ?NELH@0EFHP;,0.<(OjKm6d=ii<~$vgmnJ#8RGÉ>3ODMcVmʟ]`|;/9)^ԯ3Լw[? '_ X۫v=db'oqe'ln# d\KɊ;ϋ`܋Uq[*Nd@eH7MPǢ)jgZ*fv^bU{DF]V~ cn8w:7Sצytn7QZS(HGSFNyɥN 2#z\ˌQxf6 /CAB*dffZJ$# Eiʬ 9 z#H' iz -UA';V͖cħSdvLcbF |+ڰ:e.L+@$2v˩E+$z D8dabFp/ݾX)SZ680}PŰve&GN `f0FH99sLiӦMcѸqt[bvmaÆ@0m݊"%#0@bxsx7t,8e=?ݵf*FP@.'Gh|N>ƌ#r-ԭ[7ѣG (#Gs9Gӧuu2۸:qιOF@OF)=3X -xӄHXYŪ9o< _; 8-Vv޶/JLdI|bTǢ-b x^:怄 WR%ys}F|hKv3a˶m쳋qa/}@A,w}Bs2=3ͱ1ګFcY='aln繌OChs.1 'X B"316jW{bFKz•♆vS 떯E2(070 [- pw=Ro0qE@9A?~Wew}*ljՎ~5@oh+yOKao)Jv7~}3VH&Og|1Bj V lCQ|jc #2ĉmV;/ 660?70.nV#Egb')f=I ]\sjBcZo;e4|w_ϝog _#A5Hu)#̼ࡑXByN:4h ]f2!LN/tS*s&D7/^HjvU33#*JgZ&,XٲӼ!txޫC1*\;w:M< 4dȐ͛e"hڵkGf͒,^Xj̴Rjii5kO9Ga~]2N0I 6>;2؍l@v1n@ k׮K;C]tQoժU~QPߧo^~e:t,@@/iF2-UʁKF`E3 aNTE`͛ӗ_~i89sկ__ Dpd5nxVRQD C&a ޲U2O0I+a7`f 烧8iL!?6:F8rr܊ _(wT(B11@`'c#2؈y@ q*;drDEW:1b8 8W̳3I[CiT-c[9xtҺݸR)2)-7U8 W ^f꼘o P]$|ehg+b#i06#p,8]UretŢ(X)`Iם)$D"a7*|،@";sG2{\PK"[ "LHZFI Ծ}{]Mիȑ#A"M&MdFaJ Mf?5}?>B}"1 %P#ߊ'H0ɅX&lSEToۨQ#z饗;//n(駟cǎtҲedƍ"#<_';ѳvW" M bTs@b@h&F DvNܙ!bf D\h˽B:}t٬iӦo@ v:|pݻ,( tڕzA62#F'9'9CĕCsn#LGL#Y|uRgs)-32J2-q2jwH8C'|RfS@1c\oӦMgSCHcĪQscm`$dC9عʡ21_;}bPNwy1̴LJ;9>21 7w^|hhԗ7`C, ϫDH4Cg EZ#?>[D!tڴi2رvE?p֭[KQVj{=zTk۶^bN{ArRȏީP ^ԍt2^(>`GYC"}v҅EK9"<ڌON٘c2h㱍s 鱕0_6mZnM Fn:x vlO:;%8İ,{0{_N!)SƮ"[ 69lENOPBl];ϤCS.Yb /6gׯ'auWz *"j #rYr'h8EZ"[̙P7L#!%xlko1Gp!*NM fgJo3cB >aQAz!f`tObtE'ٝF"!i2N&TyB6!.P4wcieuLrjۤ#FٍйާA:e`7BW (//Y T/'NX^I#} 3Q7* h|B=җY5jO(B|~3ҶpЏչ'\vkz2jwA9o>"!hy';YwQOM3u4a0K ɟg-R^xAGӛ͢Eoդ^z)ŒԱhU_V;U?UY!4`d-OV憶 !V X}/QXS鍣Xr%uAիʐڈ~E *5l8LJ"qu.O,S<:#"PPX@ӷGFgf7 6rЪ8Ocmot hUBZ] e;Wմ*^v7h_~*QɋFrlM8nsvؘq})~01q,+2<˞={"e?IH< &g6(43f̠&MP6m4z'H5[i;xȩ^`8m`\^ǜ` ҏO<~ 5JB3VGq:c1SM< XF^oO;U}ƍ fNvp_էCﺣO]Mmb ~q(h, qF U0F#G;MgyB7&PiӦ;Ccǎ TyZ"hAac79=Vh]/|:sYTi <ײЁsuƯPjaF;m%>?-%Ov~k 0jh~?17E (kw|iNo-ƹïõw(wn4eRڵkjSL!xxW5\Cp8T.uRzǤt͚5m^R>!2q!d#U;о#هv#u`C -d*U(_wS5ͼ'a.k3V?|Mng6H: )˗)tiZZs~*~'t95&s6&+I5+jݏ|0> aT*_hedk׮&/_h@WX}?]E\#'rlMQayrG ^,]t1[iѣ57`b L~JyZFjY,> b5/x. ?%Z"rlr5!z:"K?S_Ypd/D\ \fT &V}Y0`\!"Blph֭[gx</_"!#ЖaA564ANj*:E4!IB *89+15kΉk55fI?\NŠ>Z7;|/==ڌNI?V,_-jv8r CH7H~7QT/D/%*qDT_yEN9nJ/`ӫJ?05k1m96G:t*#d !]8:)"%Vm&B|钦~q˕rzd?ܹS.%DNDe/ڞF`Ld&x3bF[BEh˜ڮ,ڜZh6!p9HN)CT*LrljxWDDd5SMdE\J Y ;<1;5".簘=,#]rqm=39A=}ٮ֕6X3jrCEZԃE+owB v}ёkA G~!\FB=\khypc<P<59VW%3_^ l])&! ԚQ ͈OX, e+Otƛ)F>< q9#0#o`NWG)J$exNZ)k"4MDyOB,ҼLڰ=\K>Bzssz8U5fsj\EK%y?tK?{O?6mZ~=͛7OzŇ] sɒ%ACo9 ;}Lߨfy'8bM'x~oD3 dR]#ꘕ_"3$S+Zm-?/ɧgJ X~ Q#‘$0K%qI*"ۃxfn&R[n $X&3>O!˟| !Ҭ>C/P瞓sGȜ޽{֭[x# V룏>J3g 0?oߦ{.>@5>+f͚E~;mذ,?.R 7Nm1v7ސj?Vٳ ]#?x+tU㊬mV֣U|xC$#cu҅z%>|8ASsUWƍk׮ԣGsM?xyBl d^bX_~%4̛oIC z#op~.X8 HLBiӦ YSJ D7oޜ˿K/4dhvC8>}jذ֭!k.w!BT}=PٕKPLzYL"SAuKL@2"PjUN /[o5?@ 3f E MV=\W.JfS?C &Lkժ%ݻwdȊh2uhY%,sOp)_iP@OV-g{3.nJ3?sx\ܹ 1m4\ߋwKaԔXD`լaIMOY{sK fЀBs3p`!4"cd[h<0طo_mAUl< 'L a/Yn]/O5wH1ŋ4*XjJkeT7Mwd FD24w>Vgލmĉ/>FH 3hAn']NcH.s;0 e'0M\/ȓe׻K_ >lX6Є$a~pKa{͚52@8"(6&w#|rkWNر#}weUVɓ'Kg Dxi|Ђf޳+c;vp@q=FHg&8oRT|@c m֮]+[lx{饗 Um۶zjwwЁ~&>h{iVK6j#<" r -9s](L t"ٕHخ\lBD+ECljZ8۴;~VQznya܇޽{=V/=h`OxE_ a3p@<%B/P[6kzb~B1?<#B8ӧ!қokSL9~a&g4T8] X↷|" */VDL+B2kamYIՋٳ+޼cǎB-;\t`/lk KʐXak<㡥zmZɶԳ?}{8cN}[CA<ۭ>߭qyk/W<)^)d`T^=]YWj@#~hV g2'**$juQąRezeEnDv|r/ۯF#"3:F&͜b9Ueܕ+Y3%pd*B4#aa`/Pzגz'Nj !-E5Cq}F*FҀCt 7 Us 19r#0E notT]ꫯhԨQA/@,cGԤI1b*wl9>!B*a'\G^VT[Xe:u Ќ`ȸ_W43DF`D!٧qt}I 0 ڬzb)-u oJEDY"xɼBс>hr!Ӊ^|؇¹pǡ`ܽ{ Gq4?#0 (ԧp!KR%#ğsJB93 gNEBo#tXz mP؅21"` 8=ӑz:Ņ`F  ZzW-,k2 ݍ>П\C+ziJ/ޘ'M_&rr|!C O<j[Rc078'|h9LT?}xuΛUOc{D;y2;cvA x7wxYx2F`F   ?.re Ύ:FV R xjˍڛ;Q iҔ_$ /,qR| PQVZԭoQFOц"LSF!yj;vzjSrjVFVuFT_ѵ,Y[N+2DgW?F. & $bA+t80qVϛ-#0@@>U&G,H^LȀ |L z&y §/-+VP ([(8K'~#w4ٿdu8Y@!`TTsKcUa-SdږS|8@ 67o˴pzO*VW.30# I]p!}^>lN )wbɽ375D(kgTȧ\^_v2B0Db1ZDTP&?s^]hM|ȴW0 Fdjs=wF"@O?tpFA]vY86.tfɠbZؗF?rb@%DiTdcrJy,=$@RFZU(vdf"͟?_ڀVo_ԡC ~k6m,ΐ3#L#;0Q kh 6."e@zx3gYUW}Cӗc&P/#( rYC[!dNPݽw # o^T4fǠ9vy2tr 6I- q |#0#GX#+D|)d%OD}z1Eo2`\0#D@ЧzJڑA8M{z("Ku5+e32d#m۶¤5jԈNW_VZŋe,߿/;qF ]2#fϞM^z)7N:+:W,ө V0t+o #!. ꂓ,0#'omD _~Q\06!`<"x ctFx92?#2P:ETF;w,W.d-":@)TWwЩ2)#΄dԉp`b`Xܹss2M7DSLtwFH!>CmzgbA/;ydziС /0#br vbfp)v?~W~{>#s!`1"K-܅>7ח=*Ӯ"+#0^AՌ^9S69i(=- Uϝ dpUe@0cO(LHrӻ+ `ebF-ĉdޕP|th-=i:YK'eϜ4bX-I _BGu'rցYJ*Ryl~^WFKܚ4itFpgDpJIFQe-)B1Y**:tjt/-ZHt4YX~NM.SN9%fi<&F^zltpF+laF9LU(jԨ2"c'7g@tD_mjUʬ(K*d-%_QKFn-:D$bU(?rޜFn;s5k֤N;V\)Y !OZn6VF`tp (4%^ g$l QJegv#RvAϕd~yaRHRPgWf9Bz!Bj U-T~i:$>|' m{cF:@O+1=#X.rr!M4w1apQ=qPU%B=PQ0"Vtbh*3j JoX֟AC!x7d:bb"A/ 0y)_|$M#0qCPJe+7֒oӄb0#=x^vHhѥ;L5,EᱣTY*<,C(\9*5E¸ʔ!_TzАkY&ERWhYLF@|#aՆ5zXvD~C.|a )m*B4,-Cbٽ mhZ%QgDBƆ ^%3|3#=aڽ{7_VZ` 7"e!E—"`iKSUP'34w44r.;B#0# VnvpYYYnd-,O"V8].l5oTrz*XFv{w2f̿z۷NTC,01#0@(31!?hnW|x-[&NH7\O6?Xvٺu*_Fzeb̸BV}ܒ.fQ} e>sD(( ^| x h"AD<EA?@P#FEPQazpròտzz{zϙ}2կ^Wa!״qFBaÆY6ebY9sXTuE%ՖS2MeaŸ]vn_T9N3Kx_Đ| 闺uFQ]*wUÌ@Wj|LCbNG]zO9cƌD;_~եKD["'<32 [.ϋ/0WC7{SU#`@&!6mJƍ[!d~Gs~;w.=æk[,r1=09' b :{l:i$Y/U}"b¢EϓO>9Q"ڴso5 ~vvyoV|ĸmQR3Up@ec'2im(3P zdLU#|**a=*_F`\CT?-[F#F`;v$GAYS)q:Ӿk%S,q}SXW-y'l2AT_qM0@PWSp_=>lUTVVFwqGR}( Ⴉ0UTXXE@aXu|8UY5 s:fd4 T)F6%|Շ >o+QFCX@1c$>'L@EEEHݎ!_~OTxE&|2꺫ee{!^F"[]m1#dkZ< BQ(cNIE֭V0}> h 0솢[{4}t*viŋ'j[KTl)!ZGG͉@a%vƆoy$#0A";3%V gΜ){%ַ3&F,*fحY= &X$Z:+ш~$=\߼i Wi6#0D).&NH^{>묳Jx3Ds{EY[U6;+~> .hKJp_El]TX=\.\-}x`0" ߯OtT\%V=/W]/VQh\fũ/q6Dj}Sӄ;x#kl+2+ j%B7oV-ު.ž0#f1&+Zr&㻩1BN=#_<ŕnۺ-/dcH F)S٩uF2V (a#a5iߐD»J֊ 3 #3`VCrƮhP|gO#PH x(l xY)Ƽgҍw3wG//H1b V>0s)^gD4H0X6aDMF`D~F}՛PZ@pk60.u;_{ۏI?}g9Xd9RfPDdb Uj (zRk#)%H-DZ Z#0#}J (eqnyCt 0ƴG?_OW,9>bį$^9| |TJVذxog^[`=HlFHcK&$3dq&IS>;D݈*7§-…%N1#xgyH6*++fJ@4}-eMH̃&3F8͒xp0>k\"cFbdOΫvoӼ-$aLn*ލ(zIT/S5wQu.~Uk&'ի۷o?ڵkG;w6 9BF`BeEޣ~T+&̬VnUhԩԱcĩF 5khرtSO=EW_}5]|ʼnsx`F"wJ[0 H h" JPin…UFRyM7nҰa"M2~***éxYϢ)>0#eXeâԨfd??/.jxd ݋&g4h 9gԩѣR$XjKJJk׮R͛@~-o^awܑYeenm |!g,n/uA./cAn+;Xԙ01%aCx/d#+VmgϦo [nفq= (CO[CJqӳMf19@(r2WF3Rhb?QXlUBY0` 4HZ;۴iA"XߐRQQ&Mh̙j&L ~7N V1L3oWW&| u(x{C$aKʼn10!JԻV]΃N~@r [L2u۶žc3HBlhU@\bjS*+ m3#>f8#}Z}T>!@L Va"D'O, ݺun޼Y!NoϞ=i…|ER3T#`F LfY;kRhJ}OdEb*LQgkFMcƌI$1bmذA65rH?> 2f̘Hk 1#X-ܲe EԲeP^!Te0KHѩh$Z@x;@iO?ɰO)ŋ'mۖΝK;w>0#@ P)aAgq#d]v0լV#3f|g|~F`"}=E# j$,9CMz‹Us|O$albF*xSf[0sF)ό6mJQ/5hvۭjb"mgL(z("=2lV>P@VFzº_ȁWnx¿m0fVF`a*#Y4>gXeee Nu~N|1FBrS[,\@}$ұPD(t;$VI-vKQ{=-[BDzo7L6ƹe,=5!6aMrG>Zrpvzn߾f͚E 64=qƍ4p@6li(VNں0#X.(((KM\'2NBkwS㝹*7(&Ln&NhPX<̙C:uS0K[l+2q~֭uD[X_ȇbnD\c`F&.-^`>H> cbj[TNU3@f s-OevA:K*"iBcb;WCO@f>"0|*,, $P@APBgϞMsΥI&%NA6 . [mB89/Bh Ii 2Xx1P cJAa eA (Jś n+2O~| V>޴uӦMxb6mZ=5EhРATRRBmڴ4h@cƌI *.MVy (:u* ,ps[QN/cb'vNRqgfU|YG  ;]J>?z^I^+I URzf`ҥT\\,JX/a>|8\2PQO=\ we<2հMF`,@,5#V@͐r ߙ!b֤hTO02!>ExHP6.YDhтfΜIvlǘXLN}:!/|SMY¿#0")xȬ|[c*#w}tp\1R#B \~۫yM,6J|dFP*~1 p Ts"(b9#6ubBS~ OBF`F $j+!PUU kb$[({ gJvU*K@6:^1jˋ27O;k"=Lug3qllz,;#0!cJ*׳{M rX1:|DjljO!&M#SH8+S,Gyk֘B,uP,Zr SHVEs/+K/ ,XYā1IcFͫ2ʥCC"$n WS+8ǩTmD*_ !E&SPBz |B e@JHȧ , (n!J Zy&b!FB/fvS|*Q(k݆?(Pf۪/Pl6<^UPpeb@a-3ǖt@Ȭ#VzʿJ[a*,\JF/`F2v2xL7+1k֌j}O%(Spկ]~Cķ~/Hd:꧌#0;ٳǔі-[(-[4āŔ&S#Pc'3cX"uRG{}DY+&/LZ6mn`r |@JG]Z.ҙr>CL0e/;Dhs$9?=MqWum}bF 8|+w}СCSs?8eF>az7Jqܾ};kaÆS"p"dp݆4_DU`=aE7oߟn6ӟD;v_]/+3U(Bh4vX2sYf ]s5_ѣ饗^*ZM , #;͗)n!iAMKZMC@=/򰻭x(v3Sx8Ii۬xճ[%6S Ld*T}M8,f"DSL￟h4|pi؈SqsWvKM҆Ox`|GHbFM6h{k_H˖-/9^^!G駟NW|XM-۵7Y[҄ g&Bb[LnQ^f}K"Ɣ esM۫W/$'j6[q=NDx?sU}:T; C󮔕D2"δ4yb'xBZK'QoN)PlBzP|/ϩR ?(P7 (l`T*c⼽beb~B`Lzd >^A6mD/iӦ黙EڨQ#?~|>@ng!`dG5f['zW~pb,wɖJ}Lqԡ1(gPD*q n}G/i/O<0+tRRse?b۶iRtxQ6qos]Oe [kutܧ4`3pyD#($x+ VZ*Bz饗&7n(ewCYO0=G/P|\z!3®o;}|` yX)^` P>LOV@E3Mmr[{XW_ {&=c#*=5ʧ,Q"Y);vp ;(PB,Y"ZhA3gL(7o~xٓVŠyXeFpp})cb2A " c D{vWɬI;wT0hgĈrV92~ "lbQq7_OT,|,C|MjDNȧ1`Œ0U%l8p7Í@kGVиYL(:Վ=Vu 9"bj ڶmKs%(VT}Ϩ*ϥ"ĭ̏W *hKhGԢ!:2be >n` t#=$u'HVt֖८,AL5._Y^bGDw'_lt͂k~!dS$9t$*_F_!yT+#X^gD[YPa4-<P`Gёit7be{<'5P%XO|awdTx m.L# Jn[wNW|Ϸ_9DX$~0glۦԴTZZτdYS߷M|b!zxk΍O[eXf ڵ7;̟YsmTG+#$B+_)F@ `1"Ig%y.I'JNӈWT(G n"A,_D-DWm\KFP*A3A!`5 N~֭[iԹsgj߾avڤczLX_"Rhn8A3"-n  3#j#״h"7ouYӐ!C]jM::v8fadտ*QjSi5ͨ`!9!'ヰ}  k.?#0n"}f Q3$?n#.L\&SLJ4\qɒ%4n8j׮O`R#)x<8S5 P.?d%}'QvJǪR"Q :T/1:PٳgܹsiҤI#{ۈy"Gt&jY:+AujĨo=,FJEѡzc]:p(B'9@_mͧfբ5+hY;یNVvС?Rip A^aEF)3mT, >Gl-麾r!WRE;JQ0@R͠| #Y"@"]dL, J1 鑅 n Tr$5kaРAڴi#PPP }IU^|Q jDt0{ qU !U3Lg6,/WTf{D,6;Q@W=Lmੇ1jVF?iI[TV}PזԤy hd?'}T)Ì@ pO[@@>DE*+P> Va0]uz&c;xpӇ|IZnbW ^qqq":) +e]T/5yv]M7VϫF ՋS[F]vY#tkRERqk=Ch#~b50"Dҷ~+ O?M+WlذALϖR۶m͛ &OL+VׯuZ l4S1^`^"'ΩєKRXE }Fp+-[P[lnaJXBd:"0aEv8fCVQFI%tƌTF "Y31bM0AG=r33ӴX펄c ǵ&ZW G<3er ?8Oػ?(*$WO'?FyMDL*Lb @ŋ'޽;M>~'j1L#PP0"-w^}A>}VuX "4I^x># 5ޕ78j"b> Ӈ^4n|R0@_xfx>'!0}A6"KۂjT~ٹ!E$' ( \X!rԻݘXM+N-žm[KG+}댮!k]d@RYL,#07Xkڴ)E7yBFHlPj ӂfڴn 5ĞsBEˆ?t/VarsN!R|?̔Oup \H&ѣ7gڥ%dro٪_٬|(WfFi>L 2X/(?<#. }.U&40>k3# L[ k'LTݗ/务^nAbNu|S=_UBvڇx>A?:ɱ~H桥LxO ?:0ƾk/ef͚%E\/B8i D_=kqvr6?yoCokذ!ny>1U/cK '&3 "ޔ(?KF+{!_ /?&OL/q$<|i 7pQU7 wO>.25kxt}4kFwuZJL%6Q(?m49s&[o}i?n8/h_2}QҶ/!RSoСRI&/=0.EHK8}1\2Q(^ZL7:'c ~;B-Qpdeb()ӒL'(PD=z1DZY{^{ϕ۾o'Mh߆N):jߌQ9^z'rjUotl6/^%~>nf`?\=Z>m;d6 W&I=NCxɦ?ߨ}(vx)6LPJO!/gf2{ݾ|\>3FπL1շoVFc蘶iZ^mnߞoh4cNK$,Rfbp C*`FHjK ` X`m:l[~zI~^k_]NZws> m ѱK'pS<dDLgvGepԩu=H1jG:/ʸ׎9֭[P".gϞ\`B@IItԻtB۷SD({GWN+P>EJ[T)FZ֭[g-X!υ0#lܸQ~kXzt* "0#`iB57pVt ,^L#0|?Ov)?$u9Q믿Ng}vb+֮]|^*R` ݵkפ]*]tM_|&NHo ;CSLⅆ?/kJ'nBTpGyf*(^ӢEiԨ 裏ҿ/iY|'30 嶌f2tذa2 KP჈e17a ~ : ުb5~U?=o*,ϛ7} >?BIB#d>4͢)jlΜ9AŮ+磌}Gr_,bB኉P^mH;]1.&|TM /s%xco\0#XT@v .H[R CR@CPl&8801m+VHgٳg߮=6|Uxe˖I_~Ad&R⅃ Mxb_ =cuK ak O ^iiTd*0uKJ메eτʀٽ_1V ]7zX0{_ co!Be#9@gr "$By,A!'|R 0Ta.\(HS K,R^&!E 0A;v"iaL˗/V.X c 1 ^&rBzk"=vXC_ˏ ᗌN ~:Q?~uTpuĕdb>@Dx==1&L@EEEX/#3=lFX#TR0)3zeL`†>. 8Mh>zx(GFu˄E%Q'0+T*gAaoXyc#)"ZUIEaS>!/VILa V O`a`b"LZet6!j#)aWqWctXfJLX.gr,1#X`Vʦي10@ +l`HDQ`bF`5g֏PZ@N'u\D὘F`l@qƦbbO(PL{B~fdKcv3#0A 1R>gT@Z@I3ү7rebFJJj\%#PܰfTfrdZdz>0#;dU&܁{#k.\0#͇CxsW`4cDF`@3BLPN#GhYY\n 9jα GyTVĘoK~)tM)Sd"$> z)կ~E]w_^c5Թ 'g3NgS|F gT@96;CtƍRDnݺ<EG}D^x!=4qD 3g8p M: XɆݫW/Bʾ}svUKӦM-0[QhyRHfs@b?S|V!8Vs$eU7YX3JKKiɒ%t),: ,)x y X4B(<<޽{w[o%ShΚ5|MxB-{I($/cB-!E-r-j:Jř?SB6R=2.izB)**'!/kaaT0['Lzjd3<3qmp@.*~&F gj_A?,)r@ H6ΪJ۶mB8,nwPVl%:%ZܳDd9s;M41Y(}@V7`XlYo)N8P^K oe먷1wF X,z0XB (+ ٳ#XBnر#ݛɦCt%иqᆪɓ'j^z.pb#+r-`FJ F28S"#(֭_~YNc* ! }'5A/%]fF/Y9[Y׸iӗ;gP}4bZliv˫$8 Zk޶m]V*wߦ>}07ڥKgLBz-[@~TDp~ '32v*t+YvE}1>'E?&MD;wO>F-㉲΅##Lͽk=Fĭ(SMY_.7`Մ҉jՊ̙C ?Ӽyslݺe̎`D^˼ÎU۷SD({u 10uMΪ,֨Q*CIshFt[6:e< ~<7s1 ?J (0V>>76e\QQATQZE/|wu(5F2#&ܻwЗ[=B/< 0#*yXL0@@*#0@KJ)&ZG[ds ܺF`TXY@\PN#n[R]Z>^{]q/#0 *QDY&5jԨR/qLOZ=F1F1寷oѢE=}$pA/`B^yڐrkvڕs{1fa6@Su ZRmT #)f%Im=S2}Ny4lذRv.S~Ɵ}6ZH`di}iEIENDB`